summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--disk-utils/fdisk-list.c2
-rw-r--r--libfdisk/src/bsd.c133
-rw-r--r--libfdisk/src/dos.c46
-rw-r--r--libfdisk/src/fdiskP.h19
-rw-r--r--libfdisk/src/gpt.c116
-rw-r--r--libfdisk/src/label.c78
-rw-r--r--libfdisk/src/libfdisk.h.in70
-rw-r--r--libfdisk/src/libfdisk.sym1
-rw-r--r--libfdisk/src/sgi.c52
-rw-r--r--libfdisk/src/sun.c62
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,