* [PATCH v2 2/2] gpt: create empty disklabels
@ 2012-10-27 17:23 Davidlohr Bueso
2012-11-01 9:06 ` Petr Uzel
2012-11-02 11:35 ` Karel Zak
0 siblings, 2 replies; 3+ messages in thread
From: Davidlohr Bueso @ 2012-10-27 17:23 UTC (permalink / raw)
To: Karel Zak, Petr Uzel; +Cc: util-linux
This patch enables creating a new, empty, GPT disklabel from either
an empty disk or one that already has a disklabel. For this
purpose, a 'g' option is added to the main menu and is visible to all
labels. Here's an example for a scsi_debug device (/dev/sdb):
...
Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x20a614c8.
3696: fdisk: CONTEXT: zeroize in-memory first sector buffer
Command (m for help): g
3696: fdisk: LABEL: changing to gpt label
3696: fdisk: CONTEXT: zeroize in-memory first sector buffer
3696: fdisk: LABEL: created new empty GPT disklabel (GUID: D4EA0706-F011-46DC-B7DE-6A72C7090AF8)
Command (m for help): w
The partition table has been altered!
...
Signed-off-by: Davidlohr Bueso <dave@gnu.org>
---
fdisks/fdisk.c | 4 ++
fdisks/gpt.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 200 insertions(+), 6 deletions(-)
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c
index e271ea1..a3ac087 100644
--- a/fdisks/fdisk.c
+++ b/fdisks/fdisk.c
@@ -90,6 +90,7 @@ static const struct menulist_descr menulist[] = {
{'e', N_("edit drive data"), {OSF_LABEL, 0}},
{'f', N_("fix partition order"), {0, DOS_LABEL}},
{'g', N_("create an IRIX (SGI) partition table"), {0, ANY_LABEL}},
+ {'g', N_("create a new empty GPT partition table"), {ANY_LABEL, 0}},
{'h', N_("change number of heads"), {0, DOS_LABEL | SUN_LABEL}},
{'i', N_("change interleave factor"), {0, SUN_LABEL}},
{'i', N_("change the disk identifier"), {0, DOS_LABEL}},
@@ -1694,6 +1695,9 @@ static void command_prompt(struct fdisk_context *cxt)
case 'd':
delete_partition(cxt, get_existing_partition(cxt, 1, partitions));
break;
+ case 'g':
+ fdisk_create_disklabel(cxt, "gpt");
+ break;
case 'i':
if (disklabel == SGI_LABEL)
create_sgiinfo(cxt);
diff --git a/fdisks/gpt.c b/fdisks/gpt.c
index 48397f3..843dc44 100644
--- a/fdisks/gpt.c
+++ b/fdisks/gpt.c
@@ -19,7 +19,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
*/
#include <stdio.h>
@@ -59,7 +58,8 @@
#define EFI_PMBR_OSTYPE 0xEE
#define MSDOS_MBR_SIGNATURE 0xAA55
-#define GPT_PART_NAME_LEN 72 / sizeof(uint16_t)
+#define GPT_PART_NAME_LEN 72 / sizeof(uint16_t)
+#define GPT_NPARTITIONS 128
/* Globally unique identifier */
struct gpt_guid {
@@ -96,8 +96,8 @@ struct gpt_attr {
/* The GPT Partition entry array contains an array of GPT entries. */
struct gpt_entry {
- struct gpt_guid partition_type_guid; /* purpose and type of the partition */
- struct gpt_guid unique_partition_guid;
+ struct gpt_guid partition_type_guid; /* purpose and type of the partition */
+ struct gpt_guid unique_partition_guid;
uint64_t lba_start;
uint64_t lba_end;
struct gpt_attr attr;
@@ -115,7 +115,7 @@ struct gpt_header {
uint64_t alternative_lba; /* backup GPT header */
uint64_t first_usable_lba; /* first usable logical block for partitions */
uint64_t last_usable_lba; /* last usable logical block for partitions */
- struct gpt_guid disk_guid; /* unique disk identifier */
+ struct gpt_guid disk_guid; /* unique disk identifier */
uint64_t partition_entry_lba; /* stat LBA of the partition entry array */
uint32_t npartition_entries; /* total partition entries - normally 128 */
uint32_t sizeof_partition_entry; /* bytes for each GUID pt */
@@ -298,6 +298,125 @@ static inline int partition_unused(struct gpt_entry e)
}
/*
+ * Builds a clean new valid protective MBR - will wipe out any existing data.
+ * Returns 0 on success, otherwise < 0 on error.
+ */
+static int gpt_mknew_pmbr(struct fdisk_context *cxt)
+{
+ struct gpt_legacy_mbr *pmbr = NULL;
+
+ if (!cxt || !cxt->firstsector)
+ return -ENOSYS;
+
+ fdisk_zeroize_firstsector(cxt);
+
+ pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
+
+ pmbr->signature = cpu_to_le16(MSDOS_MBR_SIGNATURE);
+ pmbr->partition_record[0].os_type = EFI_PMBR_OSTYPE;
+ pmbr->partition_record[0].start_sector = 1;
+ pmbr->partition_record[0].end_head = 0xFE;
+ pmbr->partition_record[0].end_sector = 0xFF;
+ pmbr->partition_record[0].end_track = 0xFF;
+ pmbr->partition_record[0].starting_lba = cpu_to_le32(1);
+ pmbr->partition_record[0].size_in_lba =
+ cpu_to_le32(min((uint32_t) cxt->total_sectors - 1, 0xFFFFFFFF));
+
+ return 0;
+}
+
+/* some universal differences between the headers */
+static void gpt_mknew_header_common(struct fdisk_context *cxt,
+ struct gpt_header *header, uint64_t lba)
+{
+ if (!cxt || !header)
+ return;
+
+ header->my_lba = cpu_to_le64(lba);
+
+ if (lba == GPT_PRIMARY_PARTITION_TABLE_LBA) { /* primary */
+ header->alternative_lba = cpu_to_le64(cxt->total_sectors - 1);
+ header->partition_entry_lba = cpu_to_le64(2);
+ } else { /* backup */
+ uint64_t esz = le32_to_cpu(header->npartition_entries) * sizeof(struct gpt_entry);
+ uint64_t esects = (esz + cxt->sector_size - 1) / cxt->sector_size;
+
+ header->alternative_lba = cpu_to_le64(GPT_PRIMARY_PARTITION_TABLE_LBA);
+ header->partition_entry_lba = cpu_to_le64(cxt->total_sectors - 1 - esects);
+ }
+}
+
+/*
+ * Builds a new GPT header (at sector lba) from a backup header2.
+ * If building a primary header, then backup is the secondary, and vice versa.
+ *
+ * Always pass a new (zeroized) header to build upon as we don't
+ * explicitly zero-set some values such as CRCs and reserved.
+ *
+ * Returns 0 on success, otherwise < 0 on error.
+ */
+static int gpt_mknew_header_from_bkp(struct fdisk_context *cxt,
+ struct gpt_header *header,
+ uint64_t lba,
+ struct gpt_header *header2)
+{
+ if (!cxt || !header || !header2)
+ return -ENOSYS;
+
+ header->signature = header2->signature;
+ header->revision = header2->revision;
+ header->size = header2->size;
+ header->npartition_entries = header2->npartition_entries;
+ header->sizeof_partition_entry = header2->sizeof_partition_entry;
+ header->first_usable_lba = header2->first_usable_lba;
+ header->last_usable_lba = header2->last_usable_lba;
+
+ memcpy(&header->disk_guid,
+ &header2->disk_guid, sizeof(header2->disk_guid));
+ gpt_mknew_header_common(cxt, header, lba);
+
+ return 0;
+}
+
+/*
+ * Builds a clean new GPT header (currently under revision 1.0).
+ *
+ * Always pass a new (zeroized) header to build upon as we don't
+ * explicitly zero-set some values such as CRCs and reserved.
+ *
+ * Returns 0 on success, otherwise < 0 on error.
+ */
+static int gpt_mknew_header(struct fdisk_context *cxt,
+ struct gpt_header *header, uint64_t lba)
+{
+ uint64_t esz = 0;
+
+ if (!cxt || !header)
+ return -ENOSYS;
+
+ esz = sizeof(struct gpt_entry) * GPT_NPARTITIONS / cxt->sector_size;
+
+ header->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
+ header->revision = cpu_to_le32(GPT_HEADER_REVISION_V1_00);
+ header->size = cpu_to_le32(sizeof(struct gpt_header));
+
+ /*
+ * 128 partitions is the default. It can go behond this, however,
+ * we're creating a de facto header here, so no funny business.
+ */
+ header->npartition_entries = cpu_to_le32(GPT_NPARTITIONS);
+ header->sizeof_partition_entry = cpu_to_le32(sizeof(struct gpt_entry));
+ header->first_usable_lba = cpu_to_le64(esz + 2);
+ header->last_usable_lba = cpu_to_le64(cxt->total_sectors - 2 - esz);
+
+ gpt_mknew_header_common(cxt, header, lba);
+ uuid_generate_random((unsigned char *) &header->disk_guid);
+ swap_efi_guid(&header->disk_guid);
+
+ return 0;
+}
+
+/*
* Checks if there is a valid protective MBR partition table.
* Returns 0 if it is invalid or failure. Otherwise, return
* GPT_MBR_PROTECTIVE or GPT_MBR_HYBRID, depeding on the detection.
@@ -850,6 +969,22 @@ static void gpt_init(void)
partitions = le32_to_cpu(pheader->npartition_entries);
}
+/*
+ * Deinitialize fdisk-specific variables
+ */
+static void gpt_deinit(void)
+{
+ free(ents);
+ free(pheader);
+ free(bheader);
+ ents = NULL;
+ pheader = NULL;
+ bheader = NULL;
+
+ disklabel = ANY_LABEL;
+ partitions = 0;
+}
+
static int gpt_probe_label(struct fdisk_context *cxt)
{
int mbr_type;
@@ -899,6 +1034,7 @@ static char *encode_to_utf8(unsigned char *src, size_t count)
uint16_t c;
char *dest = xmalloc(count * sizeof(char));
size_t i, j, len = count;
+
memset(dest, 0, sizeof(char) * count);
for (j = i = 0; i + 2 <= count; i += 2) {
@@ -1363,6 +1499,60 @@ static void gpt_add_partition(struct fdisk_context *cxt, int partnum,
printf(_("Created partition %d\n"), partnum + 1);
}
+/*
+ * Create a new GPT disklabel - destroys any previous data.
+ */
+static int gpt_create_disklabel(struct fdisk_context *cxt)
+{
+ int rc = 0;
+ ssize_t entry_sz = 0;
+
+ /*
+ * Reset space or clear data from headers, pt entries and
+ * protective MBR. Big fat warning: any previous content is
+ * overwritten, so ask users to be sure!.
+ *
+ * When no header, entries or pmbr is set, we're probably
+ * dealing with a new, empty disk - so always allocate memory
+ * to deal with the data structures whatever the case is.
+ */
+ gpt_deinit();
+
+ rc = gpt_mknew_pmbr(cxt);
+ if (rc < 0)
+ goto done;
+
+ pheader = xcalloc(1, sizeof(*pheader));
+ rc = gpt_mknew_header(cxt, pheader, GPT_PRIMARY_PARTITION_TABLE_LBA);
+ if (rc < 0)
+ goto done;
+
+ bheader = xcalloc(1, sizeof(*bheader));
+ rc = gpt_mknew_header_from_bkp(cxt, bheader, last_lba(cxt), pheader);
+ if (rc < 0)
+ goto done;
+
+ entry_sz = le32_to_cpu(pheader->npartition_entries) *
+ le32_to_cpu(pheader->sizeof_partition_entry);
+ ents = xcalloc(1, sizeof(*ents) * entry_sz);
+
+ gpt_recompute_crc(pheader, ents);
+ gpt_recompute_crc(bheader, ents);
+
+ gpt_init();
+ DBG(LABEL, dbgprint("created new empty GPT disklabel "
+ "(GUID: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X)",
+ pheader->disk_guid.time_low, pheader->disk_guid.time_mid,
+ pheader->disk_guid.time_hi_and_version,
+ pheader->disk_guid.clock_seq_hi,
+ pheader->disk_guid.clock_seq_low,
+ pheader->disk_guid.node[0], pheader->disk_guid.node[1],
+ pheader->disk_guid.node[2], pheader->disk_guid.node[3],
+ pheader->disk_guid.node[4], pheader->disk_guid.node[5]));
+done:
+ return rc;
+}
+
static struct fdisk_parttype *gpt_get_partition_type(struct fdisk_context *cxt,
int i)
{
@@ -1409,7 +1599,7 @@ const struct fdisk_label gpt_label =
.probe = gpt_probe_label,
.write = gpt_write_disklabel,
.verify = gpt_verify_disklabel,
- .create = NULL,
+ .create = gpt_create_disklabel,
.part_add = gpt_add_partition,
.part_delete = gpt_delete_partition,
.part_get_type = gpt_get_partition_type,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 2/2] gpt: create empty disklabels
2012-10-27 17:23 [PATCH v2 2/2] gpt: create empty disklabels Davidlohr Bueso
@ 2012-11-01 9:06 ` Petr Uzel
2012-11-02 11:35 ` Karel Zak
1 sibling, 0 replies; 3+ messages in thread
From: Petr Uzel @ 2012-11-01 9:06 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: util-linux
[-- Attachment #1: Type: text/plain, Size: 12339 bytes --]
On Sat, Oct 27, 2012 at 07:23:47PM +0200, Davidlohr Bueso wrote:
> This patch enables creating a new, empty, GPT disklabel from either
> an empty disk or one that already has a disklabel. For this
> purpose, a 'g' option is added to the main menu and is visible to all
> labels. Here's an example for a scsi_debug device (/dev/sdb):
>
> ...
> Device does not contain a recognized partition table
> Building a new DOS disklabel with disk identifier 0x20a614c8.
> 3696: fdisk: CONTEXT: zeroize in-memory first sector buffer
>
> Command (m for help): g
> 3696: fdisk: LABEL: changing to gpt label
>
> 3696: fdisk: CONTEXT: zeroize in-memory first sector buffer
> 3696: fdisk: LABEL: created new empty GPT disklabel (GUID: D4EA0706-F011-46DC-B7DE-6A72C7090AF8)
>
> Command (m for help): w
> The partition table has been altered!
> ...
>
> Signed-off-by: Davidlohr Bueso <dave@gnu.org>
Looks good to me and it also survived my testing.
Reviewed-and-tested-by: Petr Uzel <petr.uzel@suse.cz>
> ---
> fdisks/fdisk.c | 4 ++
> fdisks/gpt.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 200 insertions(+), 6 deletions(-)
>
> diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c
> index e271ea1..a3ac087 100644
> --- a/fdisks/fdisk.c
> +++ b/fdisks/fdisk.c
> @@ -90,6 +90,7 @@ static const struct menulist_descr menulist[] = {
> {'e', N_("edit drive data"), {OSF_LABEL, 0}},
> {'f', N_("fix partition order"), {0, DOS_LABEL}},
> {'g', N_("create an IRIX (SGI) partition table"), {0, ANY_LABEL}},
> + {'g', N_("create a new empty GPT partition table"), {ANY_LABEL, 0}},
> {'h', N_("change number of heads"), {0, DOS_LABEL | SUN_LABEL}},
> {'i', N_("change interleave factor"), {0, SUN_LABEL}},
> {'i', N_("change the disk identifier"), {0, DOS_LABEL}},
> @@ -1694,6 +1695,9 @@ static void command_prompt(struct fdisk_context *cxt)
> case 'd':
> delete_partition(cxt, get_existing_partition(cxt, 1, partitions));
> break;
> + case 'g':
> + fdisk_create_disklabel(cxt, "gpt");
> + break;
> case 'i':
> if (disklabel == SGI_LABEL)
> create_sgiinfo(cxt);
> diff --git a/fdisks/gpt.c b/fdisks/gpt.c
> index 48397f3..843dc44 100644
> --- a/fdisks/gpt.c
> +++ b/fdisks/gpt.c
> @@ -19,7 +19,6 @@
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
> - *
> */
>
> #include <stdio.h>
> @@ -59,7 +58,8 @@
>
> #define EFI_PMBR_OSTYPE 0xEE
> #define MSDOS_MBR_SIGNATURE 0xAA55
> -#define GPT_PART_NAME_LEN 72 / sizeof(uint16_t)
> +#define GPT_PART_NAME_LEN 72 / sizeof(uint16_t)
> +#define GPT_NPARTITIONS 128
>
> /* Globally unique identifier */
> struct gpt_guid {
> @@ -96,8 +96,8 @@ struct gpt_attr {
>
> /* The GPT Partition entry array contains an array of GPT entries. */
> struct gpt_entry {
> - struct gpt_guid partition_type_guid; /* purpose and type of the partition */
> - struct gpt_guid unique_partition_guid;
> + struct gpt_guid partition_type_guid; /* purpose and type of the partition */
> + struct gpt_guid unique_partition_guid;
> uint64_t lba_start;
> uint64_t lba_end;
> struct gpt_attr attr;
> @@ -115,7 +115,7 @@ struct gpt_header {
> uint64_t alternative_lba; /* backup GPT header */
> uint64_t first_usable_lba; /* first usable logical block for partitions */
> uint64_t last_usable_lba; /* last usable logical block for partitions */
> - struct gpt_guid disk_guid; /* unique disk identifier */
> + struct gpt_guid disk_guid; /* unique disk identifier */
> uint64_t partition_entry_lba; /* stat LBA of the partition entry array */
> uint32_t npartition_entries; /* total partition entries - normally 128 */
> uint32_t sizeof_partition_entry; /* bytes for each GUID pt */
> @@ -298,6 +298,125 @@ static inline int partition_unused(struct gpt_entry e)
> }
>
> /*
> + * Builds a clean new valid protective MBR - will wipe out any existing data.
> + * Returns 0 on success, otherwise < 0 on error.
> + */
> +static int gpt_mknew_pmbr(struct fdisk_context *cxt)
> +{
> + struct gpt_legacy_mbr *pmbr = NULL;
> +
> + if (!cxt || !cxt->firstsector)
> + return -ENOSYS;
> +
> + fdisk_zeroize_firstsector(cxt);
> +
> + pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
> +
> + pmbr->signature = cpu_to_le16(MSDOS_MBR_SIGNATURE);
> + pmbr->partition_record[0].os_type = EFI_PMBR_OSTYPE;
> + pmbr->partition_record[0].start_sector = 1;
> + pmbr->partition_record[0].end_head = 0xFE;
> + pmbr->partition_record[0].end_sector = 0xFF;
> + pmbr->partition_record[0].end_track = 0xFF;
> + pmbr->partition_record[0].starting_lba = cpu_to_le32(1);
> + pmbr->partition_record[0].size_in_lba =
> + cpu_to_le32(min((uint32_t) cxt->total_sectors - 1, 0xFFFFFFFF));
> +
> + return 0;
> +}
> +
> +/* some universal differences between the headers */
> +static void gpt_mknew_header_common(struct fdisk_context *cxt,
> + struct gpt_header *header, uint64_t lba)
> +{
> + if (!cxt || !header)
> + return;
> +
> + header->my_lba = cpu_to_le64(lba);
> +
> + if (lba == GPT_PRIMARY_PARTITION_TABLE_LBA) { /* primary */
> + header->alternative_lba = cpu_to_le64(cxt->total_sectors - 1);
> + header->partition_entry_lba = cpu_to_le64(2);
> + } else { /* backup */
> + uint64_t esz = le32_to_cpu(header->npartition_entries) * sizeof(struct gpt_entry);
> + uint64_t esects = (esz + cxt->sector_size - 1) / cxt->sector_size;
> +
> + header->alternative_lba = cpu_to_le64(GPT_PRIMARY_PARTITION_TABLE_LBA);
> + header->partition_entry_lba = cpu_to_le64(cxt->total_sectors - 1 - esects);
> + }
> +}
> +
> +/*
> + * Builds a new GPT header (at sector lba) from a backup header2.
> + * If building a primary header, then backup is the secondary, and vice versa.
> + *
> + * Always pass a new (zeroized) header to build upon as we don't
> + * explicitly zero-set some values such as CRCs and reserved.
> + *
> + * Returns 0 on success, otherwise < 0 on error.
> + */
> +static int gpt_mknew_header_from_bkp(struct fdisk_context *cxt,
> + struct gpt_header *header,
> + uint64_t lba,
> + struct gpt_header *header2)
> +{
> + if (!cxt || !header || !header2)
> + return -ENOSYS;
> +
> + header->signature = header2->signature;
> + header->revision = header2->revision;
> + header->size = header2->size;
> + header->npartition_entries = header2->npartition_entries;
> + header->sizeof_partition_entry = header2->sizeof_partition_entry;
> + header->first_usable_lba = header2->first_usable_lba;
> + header->last_usable_lba = header2->last_usable_lba;
> +
> + memcpy(&header->disk_guid,
> + &header2->disk_guid, sizeof(header2->disk_guid));
> + gpt_mknew_header_common(cxt, header, lba);
> +
> + return 0;
> +}
> +
> +/*
> + * Builds a clean new GPT header (currently under revision 1.0).
> + *
> + * Always pass a new (zeroized) header to build upon as we don't
> + * explicitly zero-set some values such as CRCs and reserved.
> + *
> + * Returns 0 on success, otherwise < 0 on error.
> + */
> +static int gpt_mknew_header(struct fdisk_context *cxt,
> + struct gpt_header *header, uint64_t lba)
> +{
> + uint64_t esz = 0;
> +
> + if (!cxt || !header)
> + return -ENOSYS;
> +
> + esz = sizeof(struct gpt_entry) * GPT_NPARTITIONS / cxt->sector_size;
> +
> + header->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
> + header->revision = cpu_to_le32(GPT_HEADER_REVISION_V1_00);
> + header->size = cpu_to_le32(sizeof(struct gpt_header));
> +
> + /*
> + * 128 partitions is the default. It can go behond this, however,
> + * we're creating a de facto header here, so no funny business.
> + */
> + header->npartition_entries = cpu_to_le32(GPT_NPARTITIONS);
> + header->sizeof_partition_entry = cpu_to_le32(sizeof(struct gpt_entry));
> + header->first_usable_lba = cpu_to_le64(esz + 2);
> + header->last_usable_lba = cpu_to_le64(cxt->total_sectors - 2 - esz);
> +
> + gpt_mknew_header_common(cxt, header, lba);
> + uuid_generate_random((unsigned char *) &header->disk_guid);
> + swap_efi_guid(&header->disk_guid);
> +
> + return 0;
> +}
> +
> +/*
> * Checks if there is a valid protective MBR partition table.
> * Returns 0 if it is invalid or failure. Otherwise, return
> * GPT_MBR_PROTECTIVE or GPT_MBR_HYBRID, depeding on the detection.
> @@ -850,6 +969,22 @@ static void gpt_init(void)
> partitions = le32_to_cpu(pheader->npartition_entries);
> }
>
> +/*
> + * Deinitialize fdisk-specific variables
> + */
> +static void gpt_deinit(void)
> +{
> + free(ents);
> + free(pheader);
> + free(bheader);
> + ents = NULL;
> + pheader = NULL;
> + bheader = NULL;
> +
> + disklabel = ANY_LABEL;
> + partitions = 0;
> +}
> +
> static int gpt_probe_label(struct fdisk_context *cxt)
> {
> int mbr_type;
> @@ -899,6 +1034,7 @@ static char *encode_to_utf8(unsigned char *src, size_t count)
> uint16_t c;
> char *dest = xmalloc(count * sizeof(char));
> size_t i, j, len = count;
> +
> memset(dest, 0, sizeof(char) * count);
>
> for (j = i = 0; i + 2 <= count; i += 2) {
> @@ -1363,6 +1499,60 @@ static void gpt_add_partition(struct fdisk_context *cxt, int partnum,
> printf(_("Created partition %d\n"), partnum + 1);
> }
>
> +/*
> + * Create a new GPT disklabel - destroys any previous data.
> + */
> +static int gpt_create_disklabel(struct fdisk_context *cxt)
> +{
> + int rc = 0;
> + ssize_t entry_sz = 0;
> +
> + /*
> + * Reset space or clear data from headers, pt entries and
> + * protective MBR. Big fat warning: any previous content is
> + * overwritten, so ask users to be sure!.
> + *
> + * When no header, entries or pmbr is set, we're probably
> + * dealing with a new, empty disk - so always allocate memory
> + * to deal with the data structures whatever the case is.
> + */
> + gpt_deinit();
> +
> + rc = gpt_mknew_pmbr(cxt);
> + if (rc < 0)
> + goto done;
> +
> + pheader = xcalloc(1, sizeof(*pheader));
> + rc = gpt_mknew_header(cxt, pheader, GPT_PRIMARY_PARTITION_TABLE_LBA);
> + if (rc < 0)
> + goto done;
> +
> + bheader = xcalloc(1, sizeof(*bheader));
> + rc = gpt_mknew_header_from_bkp(cxt, bheader, last_lba(cxt), pheader);
> + if (rc < 0)
> + goto done;
> +
> + entry_sz = le32_to_cpu(pheader->npartition_entries) *
> + le32_to_cpu(pheader->sizeof_partition_entry);
> + ents = xcalloc(1, sizeof(*ents) * entry_sz);
> +
> + gpt_recompute_crc(pheader, ents);
> + gpt_recompute_crc(bheader, ents);
> +
> + gpt_init();
> + DBG(LABEL, dbgprint("created new empty GPT disklabel "
> + "(GUID: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X)",
> + pheader->disk_guid.time_low, pheader->disk_guid.time_mid,
> + pheader->disk_guid.time_hi_and_version,
> + pheader->disk_guid.clock_seq_hi,
> + pheader->disk_guid.clock_seq_low,
> + pheader->disk_guid.node[0], pheader->disk_guid.node[1],
> + pheader->disk_guid.node[2], pheader->disk_guid.node[3],
> + pheader->disk_guid.node[4], pheader->disk_guid.node[5]));
> +done:
> + return rc;
> +}
> +
> static struct fdisk_parttype *gpt_get_partition_type(struct fdisk_context *cxt,
> int i)
> {
> @@ -1409,7 +1599,7 @@ const struct fdisk_label gpt_label =
> .probe = gpt_probe_label,
> .write = gpt_write_disklabel,
> .verify = gpt_verify_disklabel,
> - .create = NULL,
> + .create = gpt_create_disklabel,
> .part_add = gpt_add_partition,
> .part_delete = gpt_delete_partition,
> .part_get_type = gpt_get_partition_type,
> --
> 1.7.9.5
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe util-linux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Petr
--
Petr Uzel
IRC: ptr_uzl @ freenode
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 2/2] gpt: create empty disklabels
2012-10-27 17:23 [PATCH v2 2/2] gpt: create empty disklabels Davidlohr Bueso
2012-11-01 9:06 ` Petr Uzel
@ 2012-11-02 11:35 ` Karel Zak
1 sibling, 0 replies; 3+ messages in thread
From: Karel Zak @ 2012-11-02 11:35 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: Petr Uzel, util-linux
On Sat, Oct 27, 2012 at 07:23:47PM +0200, Davidlohr Bueso wrote:
> This patch enables creating a new, empty, GPT disklabel from either
> an empty disk or one that already has a disklabel. For this
> purpose, a 'g' option is added to the main menu and is visible to all
> labels. Here's an example for a scsi_debug device (/dev/sdb):
>
> ...
> Device does not contain a recognized partition table
> Building a new DOS disklabel with disk identifier 0x20a614c8.
> 3696: fdisk: CONTEXT: zeroize in-memory first sector buffer
>
> Command (m for help): g
It would be be really nice to print a message, something like
GPT disk label created.
and it would be also nice to print label type in the 'p'(print)
command output and maybe also PT uuid.
> fdisks/fdisk.c | 4 ++
> fdisks/gpt.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 200 insertions(+), 6 deletions(-)
Applied, excellent, thanks!
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-11-02 11:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-27 17:23 [PATCH v2 2/2] gpt: create empty disklabels Davidlohr Bueso
2012-11-01 9:06 ` Petr Uzel
2012-11-02 11:35 ` Karel Zak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).