From: Karel Zak Date: Thu, 11 Jun 2015 12:19:47 +0000 (+0200) Subject: libfdisk: add new API to read label specific data X-Git-Tag: v2.27-rc1~150 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5989556ad3dca8246f245eaf0867e89fb6fc9362;p=thirdparty%2Futil-linux.git libfdisk: add new API to read label specific data * removes list() label operation from internal API The list() has been based on fdisk_info() it was useless for anything else than print on stdout... * add a new get_item() label operation and fdisk_get_disklabel_item() public API The new API provides abstract and pretty simple way how to get label specific disk label information, for example fdisk_get_disklabel_item(cxt, GPT_LABELITEM_ENTRIESLBA, &iterm); return LBA of the array with GPT entries. Note that this patch does not implement public functions to get data from the @item object. * removes get_id() label operation -- it's subset of the new get_item() * the new internal API is also used to implement backwardly compatible fdisk_list_disklabel() and fdisk_get_disklabel_id() Signed-off-by: Karel Zak --- diff --git a/disk-utils/fdisk-list.c b/disk-utils/fdisk-list.c index b2b528e97c..5ef92b13c6 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 618a3eef98..9d4135d606 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 de70728c2a..b9fb77cb78 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 5e8ed9c355..10380e15b4 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; /*