diff options
-rw-r--r-- | disk-utils/fdisk-list.c | 2 | ||||
-rw-r--r-- | libfdisk/src/bsd.c | 133 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 46 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 19 | ||||
-rw-r--r-- | libfdisk/src/gpt.c | 116 | ||||
-rw-r--r-- | libfdisk/src/label.c | 78 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 70 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 1 | ||||
-rw-r--r-- | libfdisk/src/sgi.c | 52 | ||||
-rw-r--r-- | libfdisk/src/sun.c | 62 |
10 files changed, 428 insertions, 151 deletions
diff --git a/disk-utils/fdisk-list.c b/disk-utils/fdisk-list.c index b2b528e97..5ef92b13c 100644 --- a/disk-utils/fdisk-list.c +++ b/disk-utils/fdisk-list.c @@ -75,7 +75,7 @@ void list_disk_geometry(struct fdisk_context *cxt) fdisk_info(cxt, _("Disklabel type: %s"), fdisk_label_get_name(lb)); - if (fdisk_get_disklabel_id(cxt, &id) == 0 && id) + if (!fdisk_is_details(cxt) && fdisk_get_disklabel_id(cxt, &id) == 0 && id) fdisk_info(cxt, _("Disk identifier: %s"), id); } diff --git a/libfdisk/src/bsd.c b/libfdisk/src/bsd.c index 618a3eef9..9d4135d60 100644 --- a/libfdisk/src/bsd.c +++ b/libfdisk/src/bsd.c @@ -89,7 +89,6 @@ struct fdisk_bsd_label { #endif }; -static int bsd_list_disklabel(struct fdisk_context *cxt); static int bsd_initlabel(struct fdisk_context *cxt); static int bsd_readlabel(struct fdisk_context *cxt); static void sync_disks(struct fdisk_context *cxt); @@ -398,14 +397,8 @@ static int bsd_create_disklabel(struct fdisk_context *cxt) rc = bsd_initlabel(cxt); if (!rc) { - int org = fdisk_is_details(cxt); - cxt->label->nparts_cur = d->d_npartitions; cxt->label->nparts_max = BSD_MAXPARTITIONS; - - fdisk_enable_details(cxt, 1); - bsd_list_disklabel(cxt); - fdisk_enable_details(cxt, org); } return rc; @@ -430,48 +423,114 @@ static int bsd_delete_part( return 0; } -static int bsd_list_disklabel(struct fdisk_context *cxt) +static int bsd_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item) { - struct bsd_disklabel *d = self_disklabel(cxt); + struct bsd_disklabel *d; + int rc = 0; assert(cxt); assert(cxt->label); assert(fdisk_is_label(cxt, BSD)); - if (fdisk_is_details(cxt)) { - fdisk_info(cxt, "# %s:", cxt->dev_path); - - if ((unsigned) d->d_type < BSD_DKMAXTYPES) - fdisk_info(cxt, _("type: %s"), bsd_dktypenames[d->d_type]); - else - fdisk_info(cxt, _("type: %d"), d->d_type); - - fdisk_info(cxt, _("disk: %.*s"), (int) sizeof(d->d_typename), d->d_typename); - fdisk_info(cxt, _("label: %.*s"), (int) sizeof(d->d_packname), d->d_packname); + d = self_disklabel(cxt); - fdisk_info(cxt, _("flags: %s"), + switch (item->id) { + case BSD_LABELITEM_TYPE: + item->name = _("Type"); + item->type = 's'; + if ((unsigned) d->d_type < BSD_DKMAXTYPES) { + item->data.str = strdup(bsd_dktypenames[d->d_type]); + if (!item->data.str) + rc = -ENOMEM; + } else if (asprintf(&item->data.str, "%d", d->d_type) < 0) + rc = -ENOMEM; + break; + case BSD_LABELITEM_DISK: + item->name = _("Disk"); + item->type = 's'; + item->data.str = strndup(d->d_typename, sizeof(d->d_typename)); + if (!item->data.str) + rc = -ENOMEM; + break; + case BSD_LABELITEM_PACKNAME: + item->name = _("Packname"); + item->type = 's'; + item->data.str = strndup(d->d_packname, sizeof(d->d_packname)); + if (!item->data.str) + rc = -ENOMEM; + break; + case BSD_LABELITEM_FLAGS: + item->name = _("Flags"); + item->type = 's'; + item->data.str = strdup( d->d_flags & BSD_D_REMOVABLE ? _(" removable") : d->d_flags & BSD_D_ECC ? _(" ecc") : d->d_flags & BSD_D_BADSECT ? _(" badsect") : ""); + if (!item->data.str) + rc = -ENOMEM; + break; - /* On various machines the fields of *lp are short/int/long */ - /* In order to avoid problems, we cast them all to long. */ - fdisk_info(cxt, _("bytes/sector: %ld"), (long) d->d_secsize); - fdisk_info(cxt, _("sectors/track: %ld"), (long) d->d_nsectors); - fdisk_info(cxt, _("tracks/cylinder: %ld"), (long) d->d_ntracks); - fdisk_info(cxt, _("sectors/cylinder: %ld"), (long) d->d_secpercyl); - fdisk_info(cxt, _("cylinders: %ld"), (long) d->d_ncylinders); - fdisk_info(cxt, _("rpm: %d"), d->d_rpm); - fdisk_info(cxt, _("interleave: %d"), d->d_interleave); - fdisk_info(cxt, _("trackskew: %d"), d->d_trackskew); - fdisk_info(cxt, _("cylinderskew: %d"), d->d_cylskew); - fdisk_info(cxt, _("headswitch: %ld (milliseconds)"), (long) d->d_headswitch); - fdisk_info(cxt, _("track-to-track seek: %ld (milliseconds)"), (long) d->d_trkseek); + /* On various machines the fields of *lp are short/int/long */ + /* In order to avoid problems, we cast them all uint64. */ + case BSD_LABELITEM_SECSIZE: + item->name = _("Bytes/Sector"); + item->type = 'j'; + item->data.num64 = (uint64_t) d->d_secsize; + break; + case BSD_LABELITEM_NTRACKS: + item->name = _("Tracks/Cylinder"); + item->type = 'j'; + item->data.num64 = (uint64_t) d->d_ntracks; + break; + case BSD_LABELITEM_SECPERCYL: + item->name = _("Sectors/Cylinder"); + item->data.num64 = (uint64_t) d->d_secpercyl; + item->type = 'j'; + break; + case BSD_LABELITEM_CYLINDERS: + item->name = _("Cylinders"); + item->data.num64 = (uint64_t) d->d_ncylinders; + item->type = 'j'; + break; + case BSD_LABELITEM_RPM: + item->name = _("Rpm"); + item->data.num64 = (uint64_t) d->d_rpm; + item->type = 'j'; + break; + case BSD_LABELITEM_INTERLEAVE: + item->name = _("Interleave"); + item->data.num64 = (uint64_t) d->d_interleave; + item->type = 'j'; + break; + case BSD_LABELITEM_TRACKSKEW: + item->name = _("Trackskew"); + item->data.num64 = (uint64_t) d->d_trackskew; + item->type = 'j'; + break; + case BSD_LABELITEM_CYLINDERSKEW: + item->name = _("Cylinderskew"); + item->data.num64 = (uint64_t) d->d_cylskew; + item->type = 'j'; + break; + case BSD_LABELITEM_HEADSWITCH: + item->name = _("Headswitch"); + item->data.num64 = (uint64_t) d->d_headswitch; + item->type = 'j'; + break; + case BSD_LABELITEM_TRKSEEK: + item->name = _("Track-to-track seek"); + item->data.num64 = (uint64_t) d->d_trkseek; + item->type = 'j'; + break; + default: + if (item->id < __FDISK_NLABELITEMS) + rc = 1; /* unssupported generic item */ + else + rc = 2; /* out of range */ + break; } - fdisk_info(cxt, _("partitions: %d"), d->d_npartitions); - - return 0; + return rc; } static int bsd_get_partition(struct fdisk_context *cxt, size_t n, @@ -934,7 +993,7 @@ static int bsd_partition_is_used( static const struct fdisk_label_operations bsd_operations = { .probe = bsd_probe_label, - .list = bsd_list_disklabel, + .get_item = bsd_get_disklabel_item, .write = bsd_write_disklabel, .create = bsd_create_disklabel, diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index de70728c2..b9fb77cb7 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -615,22 +615,6 @@ static void read_extended(struct fdisk_context *cxt, size_t ext) DBG(LABEL, ul_debug("DOS: nparts_max: %zu", cxt->label->nparts_max)); } -static int dos_get_disklabel_id(struct fdisk_context *cxt, char **id) -{ - unsigned int num; - - assert(cxt); - assert(id); - assert(cxt->label); - assert(fdisk_is_label(cxt, DOS)); - - num = mbr_get_id(cxt->firstsector); - if (asprintf(id, "0x%08x", num) > 0) - return 0; - - return -ENOMEM; -} - static int dos_create_disklabel(struct fdisk_context *cxt) { unsigned int id = 0; @@ -1852,13 +1836,34 @@ static int wrong_p_order(struct fdisk_context *cxt, size_t *prev) return 0; } -static int dos_list_disklabel(struct fdisk_context *cxt) +static int dos_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item) { + int rc = 0; + assert(cxt); assert(cxt->label); assert(fdisk_is_label(cxt, DOS)); - return 0; + switch (item->id) { + case FDISK_LABELITEM_ID: + { + unsigned int num = mbr_get_id(cxt->firstsector); + item->name = _("Disk identifier"); + item->type = 's'; + if (asprintf(&item->data.str, "0x%08x", num) < 0) + rc = -ENOMEM; + break; + } + default: + if (item->id < __FDISK_NLABELITEMS) + rc = 1; /* unssupported generic item */ + else + rc = 2; /* out of range */ + break; + } + + return rc; + } static int dos_get_partition(struct fdisk_context *cxt, size_t n, @@ -2273,15 +2278,14 @@ static const struct fdisk_label_operations dos_operations = .verify = dos_verify_disklabel, .create = dos_create_disklabel, .locate = dos_locate_disklabel, - .list = dos_list_disklabel, - .reorder = dos_reorder, - .get_id = dos_get_disklabel_id, + .get_item = dos_get_disklabel_item, .set_id = dos_set_disklabel_id, .get_part = dos_get_partition, .set_part = dos_set_partition, .add_part = dos_add_partition, .del_part = dos_delete_partition, + .reorder = dos_reorder, .part_toggle_flag = dos_toggle_partition_flag, .part_is_used = dos_partition_is_used, diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 5e8ed9c35..10380e15b 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -197,16 +197,13 @@ struct fdisk_label_operations { int (*verify)(struct fdisk_context *cxt); /* create new disk label */ int (*create)(struct fdisk_context *cxt); - /* list disklabel details */ - int (*list)(struct fdisk_context *cxt); /* returns offset and size of the 'n' part of the PT */ int (*locate)(struct fdisk_context *cxt, int n, const char **name, uint64_t *offset, size_t *size); /* reorder partitions */ int (*reorder)(struct fdisk_context *cxt); - - /* get disk label ID */ - int (*get_id)(struct fdisk_context *cxt, char **id); + /* get details from label */ + int (*get_item)(struct fdisk_context *cxt, struct fdisk_labelitem *item); /* set disk label ID */ int (*set_id)(struct fdisk_context *cxt); @@ -427,6 +424,18 @@ extern char *fdisk_partname(const char *dev, size_t partno); extern int fdisk_probe_labels(struct fdisk_context *cxt); extern void fdisk_deinit_label(struct fdisk_label *lb); +struct fdisk_labelitem { + int id; /* <label>_ITEM_* */ + char type; /* s = string, j = uint64 */ + const char *name; + + union { + char *str; + uint64_t num64; + } data; +}; + + /* ask.c */ struct fdisk_ask *fdisk_new_ask(void); void fdisk_reset_ask(struct fdisk_ask *ask); diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 007840f60..33526190f 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -395,6 +395,16 @@ static inline int partition_unused(const struct gpt_entry *e) sizeof(struct gpt_guid)); } +static char *gpt_get_header_id(struct gpt_header *header) +{ + char str[37]; + + guid_to_string(&header->disk_guid, str); + + return strdup(str); +} + + /* * Builds a clean new valid protective MBR - will wipe out any existing data. * Returns 0 on success, otherwise < 0 on error. @@ -1034,7 +1044,62 @@ static int gpt_locate_disklabel(struct fdisk_context *cxt, int n, return 0; } +static int gpt_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item) +{ + struct gpt_header *h; + int rc = 0; + + assert(cxt); + assert(cxt->label); + assert(fdisk_is_label(cxt, GPT)); + + h = self_label(cxt)->pheader; + switch (item->id) { + case GPT_LABELITEM_ID: + item->name = _("Disk identifier"); + item->type = 's'; + item->data.str = gpt_get_header_id(h); + if (!item->data.str) + rc = -ENOMEM; + break; + case GPT_LABELITEM_FIRSTLBA: + item->name = _("First LBA"); + item->type = 'j'; + item->data.num64 = le64_to_cpu(h->first_usable_lba); + break; + case GPT_LABELITEM_LASTLBA: + item->name = _("Last LBA"); + item->type = 'j'; + item->data.num64 = le64_to_cpu(h->last_usable_lba); + break; + case GPT_LABELITEM_ALTLBA: + /* TRANSLATORS: The LBA (Logical Block Address) of the backup GPT header. */ + item->name = _("Alternative LBA"); + item->type = 'j'; + item->data.num64 = le64_to_cpu(h->alternative_lba); + break; + case GPT_LABELITEM_ENTRIESLBA: + /* TRANSLATORS: The start of the array of partition entries. */ + item->name = _("Partition entries LBA"); + item->type = 'j'; + item->data.num64 = le64_to_cpu(h->partition_entry_lba); + break; + case GPT_LABELITEM_ENTRIESALLOC: + item->name = _("Allocated partition entries"); + item->type = 'j'; + item->data.num64 = le32_to_cpu(h->npartition_entries); + break; + default: + if (item->id < __FDISK_NLABELITEMS) + rc = 1; /* unssupported generic item */ + else + rc = 2; /* out of range */ + break; + } + + return rc; +} /* * Returns the number of partitions that are in use. @@ -1662,29 +1727,6 @@ static int gpt_set_partition(struct fdisk_context *cxt, size_t n, } -/* - * List label partitions. - */ -static int gpt_list_disklabel(struct fdisk_context *cxt) -{ - assert(cxt); - assert(cxt->label); - assert(fdisk_is_label(cxt, GPT)); - - if (fdisk_is_details(cxt)) { - struct gpt_header *h = self_label(cxt)->pheader; - - fdisk_info(cxt, _("First LBA: %ju"), le64_to_cpu(h->first_usable_lba)); - fdisk_info(cxt, _("Last LBA: %ju"), le64_to_cpu(h->last_usable_lba)); - /* TRANSLATORS: The LBA (Logical Block Address) of the backup GPT header. */ - fdisk_info(cxt, _("Alternative LBA: %ju"), le64_to_cpu(h->alternative_lba)); - /* TRANSLATORS: The start of the array of partition entries. */ - fdisk_info(cxt, _("Partition entries LBA: %ju"), le64_to_cpu(h->partition_entry_lba)); - fdisk_info(cxt, _("Allocated partition entries: %u"), le32_to_cpu(h->npartition_entries)); - } - - return 0; -} /* * Write partitions. @@ -2329,25 +2371,6 @@ done: return rc; } -static int gpt_get_disklabel_id(struct fdisk_context *cxt, char **id) -{ - struct fdisk_gpt_label *gpt; - char str[37]; - - assert(cxt); - assert(id); - assert(cxt->label); - assert(fdisk_is_label(cxt, GPT)); - - gpt = self_label(cxt); - guid_to_string(&gpt->pheader->disk_guid, str); - - *id = strdup(str); - if (!*id) - return -ENOMEM; - return 0; -} - static int gpt_set_disklabel_id(struct fdisk_context *cxt) { struct fdisk_gpt_label *gpt; @@ -2372,7 +2395,7 @@ static int gpt_set_disklabel_id(struct fdisk_context *cxt) return rc; } - gpt_get_disklabel_id(cxt, &old); + old = gpt_get_header_id(gpt->pheader); gpt->pheader->disk_guid = uuid; gpt->bheader->disk_guid = uuid; @@ -2380,7 +2403,7 @@ static int gpt_set_disklabel_id(struct fdisk_context *cxt) gpt_recompute_crc(gpt->pheader, gpt->ents); gpt_recompute_crc(gpt->bheader, gpt->ents); - gpt_get_disklabel_id(cxt, &new); + new = gpt_get_header_id(gpt->pheader); fdisk_info(cxt, _("Disk identifier changed from %s to %s."), old, new); @@ -2674,16 +2697,15 @@ static const struct fdisk_label_operations gpt_operations = .write = gpt_write_disklabel, .verify = gpt_verify_disklabel, .create = gpt_create_disklabel, - .list = gpt_list_disklabel, .locate = gpt_locate_disklabel, - .reorder = gpt_reorder, - .get_id = gpt_get_disklabel_id, + .get_item = gpt_get_disklabel_item, .set_id = gpt_set_disklabel_id, .get_part = gpt_get_partition, .set_part = gpt_set_partition, .add_part = gpt_add_partition, .del_part = gpt_delete_partition, + .reorder = gpt_reorder, .part_is_used = gpt_part_is_used, .part_toggle_flag = gpt_toggle_partition_flag, diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index dd9fef040..92b82cc18 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -336,19 +336,46 @@ int fdisk_verify_disklabel(struct fdisk_context *cxt) * * Lists details about disklabel, but no partitions. * - * This function uses libfdisk ASK interface to print data. The details about - * partitions table are printed by FDISK_ASKTYPE_INFO. + * This function is based on fdisk_get_disklabel_item() and prints all label + * specific information by ASK interface (FDISK_ASKTYPE_INFO, aka fdisk_info()). + * The function requires enabled "details" by fdisk_enable_details(). + * + * It's recommended to use fdisk_get_disklabel_item() if you need better + * control on output and formmatting. * * Returns: 0 on success, otherwise, a corresponding error. */ int fdisk_list_disklabel(struct fdisk_context *cxt) { + int id = 0, rc = 0; + struct fdisk_labelitem item = { .id = id }; + if (!cxt || !cxt->label) return -EINVAL; - if (!cxt->label->op->list) - return -ENOSYS; - return cxt->label->op->list(cxt); + if (!cxt->display_details) + return 0; + + /* List all label items */ + do { + /* rc: < 0 error, 0 success, 1 unknown item, 2 out of range */ + rc = fdisk_get_disklabel_item(cxt, id++, &item); + if (rc != 0) + continue; + switch (item.type) { + case 'j': + fdisk_info(cxt, "%s: %ju", item.name, item.data.num64); + break; + case 's': + if (item.data.str && item.name) + fdisk_info(cxt, "%s: %s", item.name, item.data.str); + free(item.data.str); + item.data.str = NULL; + break; + } + } while (rc == 0 || rc == 1); + + return rc < 0 ? rc : 0; } /** @@ -437,13 +464,46 @@ int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, const char **name, */ int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id) { - if (!cxt || !cxt->label) + struct fdisk_labelitem item; + int rc; + + if (!cxt || !cxt->label || !id) return -EINVAL; - if (!cxt->label->op->get_id) - return -ENOSYS; DBG(CXT, ul_debugobj(cxt, "asking for disk %s ID", cxt->label->name)); - return cxt->label->op->get_id(cxt, id); + + rc = fdisk_get_disklabel_item(cxt, FDISK_LABELITEM_ID, &item); + if (rc == 0) + *id = item.data.str; + if (rc > 0) + rc = 0; + return rc; +} + +/** + * fdisk_get_disklabel_item: + * @cxt: fdisk context + * @id: item ID (FDISK_LABELITEM_* or {GPT,MBR,...}_LABELITEM_*) + * @item: specifies and returns the item + * + * Note that @id is always in range 0..N. It's fine to use the function in loop + * until it returns error or 2, the result in @item should be ignored when + * function returns 1. + * + * Returns: 0 on success, < 0 on error, 1 on unssupported item, 2 @id out of range + */ +int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item) +{ + if (!cxt || !cxt->label || !item) + return -EINVAL; + + item->id = id; + DBG(CXT, ul_debugobj(cxt, "asking for disk %s item %d", cxt->label->name, item->id)); + + if (!cxt->label->op->get_item) + return -ENOSYS; + + return cxt->label->op->get_item(cxt, item); } /** diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index bfb22a2f7..ba6539e23 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -99,7 +99,7 @@ struct fdisk_field; /** * fdisk_script * - * library handler for sfdisk compatible scripts + * library handler for sfdisk compatible scripts and dumps */ struct fdisk_script; @@ -124,6 +124,14 @@ enum fdisk_labeltype { }; /** + * fdisk_labelitem + * + * library handler for label specific information. See + * generic FDISK_LABELITEM_* and label specific {GPT,MBR,..}_LABELITEM_*. + */ +struct fdisk_labelitem; + +/** * fdisk_asktype: * * Ask API dialog types @@ -140,6 +148,7 @@ enum fdisk_asktype { FDISK_ASKTYPE_MENU }; + /* init.c */ extern void fdisk_init_debug(int mask); @@ -246,7 +255,7 @@ int fdisk_parttype_is_unknown(const struct fdisk_parttype *t); /** * fdisk_fieldtype * - * Types of fdisk_field + * Types of fdisk_field. The fields describe a partition. */ enum fdisk_fieldtype { FDISK_FIELD_NONE = 0, @@ -289,6 +298,18 @@ extern int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, uint64_t *offset, size_t *size); +/** + * fdisk_labelitem_gen + * + * Generic disklabel items + */ +enum fdisk_labelitem_gen { + FDISK_LABELITEM_ID = 0, /* Unique disk identifier */ + + __FDISK_NLABELITEMS = 8 /* Specifies reserved range for generic items (0..7) */ +}; + +extern int fdisk_get_disklabel_item(struct fdisk_context *cxt, int id, struct fdisk_labelitem *item); extern int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id); extern int fdisk_set_disklabel_id(struct fdisk_context *cxt); @@ -477,17 +498,52 @@ extern int fdisk_sun_set_ilfact(struct fdisk_context *cxt); extern int fdisk_sun_set_rspeed(struct fdisk_context *cxt); extern int fdisk_sun_set_pcylcount(struct fdisk_context *cxt); +enum fdisk_labelitem_sun { + SUN_LABELITEM_LABELID = __FDISK_NLABELITEMS, + SUN_LABELITEM_VTOCID, + SUN_LABELITEM_RPM, + SUN_LABELITEM_ACYL, + SUN_LABELITEM_PCYL, + SUN_LABELITEM_APC, + SUN_LABELITEM_INTRLV +}; + /* bsd.c */ extern int fdisk_bsd_edit_disklabel(struct fdisk_context *cxt); extern int fdisk_bsd_write_bootstrap(struct fdisk_context *cxt); extern int fdisk_bsd_link_partition(struct fdisk_context *cxt); +enum fdisk_labelitem_bsd { + /* specific */ + BSD_LABELITEM_TYPE = __FDISK_NLABELITEMS, + BSD_LABELITEM_DISK, + BSD_LABELITEM_PACKNAME, + BSD_LABELITEM_FLAGS, + BSD_LABELITEM_SECSIZE, + BSD_LABELITEM_NTRACKS, + BSD_LABELITEM_SECPERCYL, + BSD_LABELITEM_CYLINDERS, + BSD_LABELITEM_RPM, + BSD_LABELITEM_INTERLEAVE, + BSD_LABELITEM_TRACKSKEW, + BSD_LABELITEM_CYLINDERSKEW, + BSD_LABELITEM_HEADSWITCH, + BSD_LABELITEM_TRKSEEK +}; + /* sgi.h */ #define SGI_FLAG_BOOT 1 #define SGI_FLAG_SWAP 2 extern int fdisk_sgi_set_bootfile(struct fdisk_context *cxt); extern int fdisk_sgi_create_info(struct fdisk_context *cxt); +enum fdisk_labelitem_sgi { + SGI_LABELITEM_PCYLCOUNT = __FDISK_NLABELITEMS, + SGI_LABELITEM_SPARECYL, + SGI_LABELITEM_ILFACT, + SGI_LABELITEM_BOOTFILE +}; + /* gpt */ /* @@ -539,6 +595,16 @@ extern int fdisk_gpt_is_hybrid(struct fdisk_context *cxt); extern int fdisk_gpt_get_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t *attrs); extern int fdisk_gpt_set_partition_attrs(struct fdisk_context *cxt, size_t partnum, uint64_t attrs); +enum fdisk_labelitem_gpt { + /* generic */ + GPT_LABELITEM_ID = FDISK_LABELITEM_ID, /* GPT disklabel UUID (!= partition UUID) */ + /* specific */ + GPT_LABELITEM_FIRSTLBA = __FDISK_NLABELITEMS, /* First Usable LBA */ + GPT_LABELITEM_LASTLBA, /* Last Usable LBA */ + GPT_LABELITEM_ALTLBA, /* Alternative LBA (backup header LBA) */ + GPT_LABELITEM_ENTRIESLBA, /* Partitions entires array LBA */ + GPT_LABELITEM_ENTRIESALLOC /* Number of allocated entries in entries array */ +}; /* script.c */ struct fdisk_script *fdisk_new_script(struct fdisk_context *cxt); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 15c268ee3..7cf5d2f0c 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -250,4 +250,5 @@ FDISK_2.27 { fdisk_script_set_fgets; fdisk_script_set_userdata; fdisk_table_get_partition_by_partno; + fdisk_get_disklabel_item; } FDISK_2.26; diff --git a/libfdisk/src/sgi.c b/libfdisk/src/sgi.c index 7cc68b501..8e0c0e72b 100644 --- a/libfdisk/src/sgi.c +++ b/libfdisk/src/sgi.c @@ -264,22 +264,48 @@ static int sgi_probe_label(struct fdisk_context *cxt) return 1; } -static int sgi_list_table(struct fdisk_context *cxt) +static int sgi_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item) { - struct sgi_disklabel *sgilabel = self_disklabel(cxt); - struct sgi_device_parameter *sgiparam = &sgilabel->devparam; + struct sgi_disklabel *sgilabel; + struct sgi_device_parameter *sgiparam; int rc = 0; - if (fdisk_is_details(cxt)) - fdisk_info(cxt, _( - "Label geometry: %d heads, %llu sectors\n" - " %llu cylinders, %d physical cylinders\n" - " %d extra sects/cyl, interleave %d:1\n"), - cxt->geom.heads, cxt->geom.sectors, - cxt->geom.cylinders, be16_to_cpu(sgiparam->pcylcount), - (int) sgiparam->sparecyl, be16_to_cpu(sgiparam->ilfact)); + assert(cxt); + assert(cxt->label); + assert(fdisk_is_label(cxt, SGI)); + + sgilabel = self_disklabel(cxt); + sgiparam = &sgilabel->devparam; + + switch (item->id) { + case SGI_LABELITEM_PCYLCOUNT: + item->name = _("Physical cylinders"); + item->type = 'j'; + item->data.num64 = (uint64_t) be16_to_cpu(sgiparam->pcylcount); + break; + case SGI_LABELITEM_SPARECYL: + item->name = _("Extra sects/cyl"); + item->type = 'j'; + item->data.num64 = (uint64_t) sgiparam->sparecyl; + break; + case SGI_LABELITEM_ILFACT: + item->name = _("Interleave"); + item->type = 'j'; + item->data.num64 = (uint64_t) be16_to_cpu(sgiparam->ilfact); + break; + case SGI_LABELITEM_BOOTFILE: + item->name = _("Bootfile"); + item->type = 's'; + item->data.str = *sgilabel->boot_file ? strdup((char *) sgilabel->boot_file) : NULL; + break; + default: + if (item->id < __FDISK_NLABELITEMS) + rc = 1; /* unssupported generic item */ + else + rc = 2; /* out of range */ + break; + } - fdisk_info(cxt, _("Bootfile: %s"), sgilabel->boot_file); return rc; } @@ -1145,8 +1171,8 @@ static const struct fdisk_label_operations sgi_operations = .probe = sgi_probe_label, .write = sgi_write_disklabel, .verify = sgi_verify_disklabel, + .get_item = sgi_get_disklabel_item, .create = sgi_create_disklabel, - .list = sgi_list_table, .get_part = sgi_get_partition, .set_part = sgi_set_partition, diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c index 27e3bdd00..d5c76ae80 100644 --- a/libfdisk/src/sun.c +++ b/libfdisk/src/sun.c @@ -731,10 +731,10 @@ static int sun_delete_partition(struct fdisk_context *cxt, return 0; } - -static int sun_list_disklabel(struct fdisk_context *cxt) +static int sun_get_disklabel_item(struct fdisk_context *cxt, struct fdisk_labelitem *item) { struct sun_disklabel *sunlabel; + int rc = 0; assert(cxt); assert(cxt->label); @@ -742,21 +742,51 @@ static int sun_list_disklabel(struct fdisk_context *cxt) sunlabel = self_disklabel(cxt); - if (fdisk_is_details(cxt)) { - fdisk_info(cxt, - _("Label geometry: %d rpm, %d alternate and %d physical cylinders,\n" - " %d extra sects/cyl, interleave %d:1"), - be16_to_cpu(sunlabel->rpm), - be16_to_cpu(sunlabel->acyl), - be16_to_cpu(sunlabel->pcyl), - be16_to_cpu(sunlabel->apc), - be16_to_cpu(sunlabel->intrlv)); - fdisk_info(cxt, _("Label ID: %s"), sunlabel->label_id); - fdisk_info(cxt, _("Volume ID: %s"), - *sunlabel->vtoc.volume_id ? sunlabel->vtoc.volume_id : _("<none>")); + switch (item->id) { + case SUN_LABELITEM_LABELID: + item->name =_("Label ID"); + item->type = 's'; + item->data.str = *sunlabel->label_id ? strndup((char *)sunlabel->label_id, sizeof(sunlabel->label_id)) : NULL; + break; + case SUN_LABELITEM_VTOCID: + item->name =_("Volume ID"); + item->type = 's'; + item->data.str = *sunlabel->vtoc.volume_id ? strndup((char *)sunlabel->vtoc.volume_id, sizeof(sunlabel->vtoc.volume_id)) : NULL; + break; + case SUN_LABELITEM_RPM: + item->name =_("Rpm"); + item->type = 'j'; + item->data.num64 = be16_to_cpu(sunlabel->rpm); + break; + case SUN_LABELITEM_ACYL: + item->name =_("Alternate cylinders"); + item->type = 'j'; + item->data.num64 = be16_to_cpu(sunlabel->acyl); + break; + case SUN_LABELITEM_PCYL: + item->name =_("Physical cylinders"); + item->type = 'j'; + item->data.num64 = be16_to_cpu(sunlabel->pcyl); + break; + case SUN_LABELITEM_APC: + item->name =_("Extra sects/cyl"); + item->type = 'j'; + item->data.num64 = be16_to_cpu(sunlabel->apc); + break; + case SUN_LABELITEM_INTRLV: + item->name =_("Interleave"); + item->type = 'j'; + item->data.num64 = be16_to_cpu(sunlabel->intrlv); + break; + default: + if (item->id < __FDISK_NLABELITEMS) + rc = 1; /* unssupported generic item */ + else + rc = 2; /* out of range */ + break; } - return 0; + return rc; } static struct fdisk_parttype *sun_get_parttype( @@ -1090,7 +1120,7 @@ const struct fdisk_label_operations sun_operations = .write = sun_write_disklabel, .verify = sun_verify_disklabel, .create = sun_create_disklabel, - .list = sun_list_disklabel, + .get_item = sun_get_disklabel_item, .get_part = sun_get_partition, .set_part = sun_set_partition, |