diff options
Diffstat (limited to 'libfdisk/src/label.c')
| -rw-r--r-- | libfdisk/src/label.c | 143 |
1 files changed, 132 insertions, 11 deletions
diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index cc21f759e..a923a898f 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -17,7 +17,10 @@ int fdisk_probe_labels(struct fdisk_context *cxt) if (!lb->op->probe) continue; - + if (lb->disabled) { + DBG(LABEL, dbgprint("%s disabled -- ignore", lb->name)); + continue; + } DBG(LABEL, dbgprint("probing for %s", lb->name)); cxt->label = lb; @@ -72,14 +75,37 @@ int fdisk_dev_is_disklabel(struct fdisk_context *cxt, enum fdisk_labeltype l) */ int fdisk_write_disklabel(struct fdisk_context *cxt) { - if (!cxt || !cxt->label) + if (!cxt || !cxt->label || cxt->readonly) return -EINVAL; if (!cxt->label->op->write) return -ENOSYS; - return cxt->label->op->write(cxt); } +int fdisk_require_geometry(struct fdisk_context *cxt) +{ + assert(cxt); + + return cxt->label + && cxt->label->flags & FDISK_LABEL_FL_REQUIRE_GEOMETRY ? 1 : 0; +} + +int fdisk_missing_geometry(struct fdisk_context *cxt) +{ + int rc; + + assert(cxt); + + rc = (fdisk_require_geometry(cxt) && + (!cxt->geom.heads || !cxt->geom.sectors + || !cxt->geom.cylinders)); + + if (rc && !fdisk_context_listonly(cxt)) + fdisk_warnx(cxt, _("Incomplete geometry setting.")); + + return rc; +} + /** * fdisk_verify_disklabel: * @cxt: fdisk context @@ -94,16 +120,36 @@ int fdisk_verify_disklabel(struct fdisk_context *cxt) return -EINVAL; if (!cxt->label->op->verify) return -ENOSYS; + if (fdisk_missing_geometry(cxt)) + return -EINVAL; return cxt->label->op->verify(cxt); } /** + * fdisk_list_disklabel: + * @cxt: fdisk context + * + * Lists in-memory partition table + * + * Returns 0 on success, otherwise, a corresponding error. + */ +int fdisk_list_disklabel(struct fdisk_context *cxt) +{ + if (!cxt || !cxt->label) + return -EINVAL; + if (!cxt->label->op->list) + return -ENOSYS; + + return cxt->label->op->list(cxt); +} + +/** * fdisk_add_partition: * @cxt: fdisk context * @t: partition type to create or NULL for label-specific default * - * Creates a new partition, with number @partnum and type @parttype. + * Creates a new partition with type @parttype. * * Returns 0. */ @@ -119,6 +165,8 @@ int fdisk_add_partition(struct fdisk_context *cxt, return -EINVAL; if (!cxt->label->op->part_add) return -ENOSYS; + if (fdisk_missing_geometry(cxt)) + return -EINVAL; if (!(cxt->label->flags & FDISK_LABEL_FL_ADDPART_NOPARTNO)) { int rc = fdisk_ask_partnum(cxt, &partnum, 1); @@ -164,6 +212,9 @@ int fdisk_delete_partition(struct fdisk_context *cxt, size_t partnum) */ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name) { + int haslabel = 0; + struct fdisk_label *lb; + if (!cxt) return -EINVAL; @@ -175,21 +226,75 @@ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name) #endif } - if (cxt->label) + if (cxt->label) { fdisk_deinit_label(cxt->label); + haslabel = 1; + } - cxt->label = fdisk_context_get_label(cxt, name); - if (!cxt->label) + lb = fdisk_context_get_label(cxt, name); + if (!lb || lb->disabled) return -EINVAL; - - DBG(LABEL, dbgprint("changing to %s label\n", cxt->label->name)); - if (!cxt->label->op->create) + if (!lb->op->create) return -ENOSYS; - fdisk_reset_alignment(cxt); + __fdisk_context_switch_label(cxt, lb); + + if (haslabel && !cxt->parent) + fdisk_reset_device_properties(cxt); + + DBG(LABEL, dbgprint("create a new %s label", lb->name)); return cxt->label->op->create(cxt); } + +int fdisk_locate_disklabel(struct fdisk_context *cxt, int n, const char **name, + off_t *offset, size_t *size) +{ + if (!cxt || !cxt->label) + return -EINVAL; + if (!cxt->label->op->locate) + return -ENOSYS; + + DBG(LABEL, dbgprint("locating %d chunk of %s.", n, cxt->label->name)); + return cxt->label->op->locate(cxt, n, name, offset, size); +} + + +/** + * fdisk_get_disklabel_id: + * @cxt: fdisk context + * @id: returns pointer to allocated string + * + * Returns 0 on success, otherwise, a corresponding error. + */ +int fdisk_get_disklabel_id(struct fdisk_context *cxt, char **id) +{ + if (!cxt || !cxt->label) + return -EINVAL; + if (!cxt->label->op->get_id) + return -ENOSYS; + + DBG(LABEL, dbgprint("asking for disk %s ID", cxt->label->name)); + return cxt->label->op->get_id(cxt, id); +} + +/** + * fdisk_get_disklabel_id: + * @cxt: fdisk context + * + * Returns 0 on success, otherwise, a corresponding error. + */ +int fdisk_set_disklabel_id(struct fdisk_context *cxt) +{ + if (!cxt || !cxt->label) + return -EINVAL; + if (!cxt->label->op->set_id) + return -ENOSYS; + + DBG(LABEL, dbgprint("setting %s disk ID", cxt->label->name)); + return cxt->label->op->set_id(cxt); +} + /** * fdisk_get_partition_type: * @cxt: fdisk context @@ -333,3 +438,19 @@ int fdisk_label_is_changed(struct fdisk_label *lb) assert(lb); return lb ? lb->changed : 0; } + +void fdisk_label_set_disabled(struct fdisk_label *lb, int disabled) +{ + assert(lb); + + DBG(LABEL, dbgprint("%s label %s", + lb->name, + disabled ? "DISABLED" : "ENABLED")); + lb->disabled = disabled ? 1 : 0; +} + +int fdisk_label_is_disabled(struct fdisk_label *lb) +{ + assert(lb); + return lb ? lb->disabled : 0; +} |
