diff options
Diffstat (limited to 'libfdisk/src/context.c')
| -rw-r--r-- | libfdisk/src/context.c | 152 |
1 files changed, 128 insertions, 24 deletions
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 7569e5b52..0de2d2a59 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -21,7 +21,6 @@ struct fdisk_context *fdisk_new_context(void) cxt->labels[ cxt->nlabels++ ] = fdisk_new_gpt_label(cxt); cxt->labels[ cxt->nlabels++ ] = fdisk_new_dos_label(cxt); cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt); - cxt->labels[ cxt->nlabels++ ] = fdisk_new_mac_label(cxt); cxt->labels[ cxt->nlabels++ ] = fdisk_new_sgi_label(cxt); cxt->labels[ cxt->nlabels++ ] = fdisk_new_sun_label(cxt); @@ -33,9 +32,9 @@ struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent, const char *name) { struct fdisk_context *cxt; + struct fdisk_label *lb = NULL; assert(parent); - assert(name); cxt = calloc(1, sizeof(*cxt)); if (!cxt) @@ -55,10 +54,28 @@ struct fdisk_context *fdisk_new_nested_context(struct fdisk_context *parent, cxt->first_lba = parent->first_lba; cxt->total_sectors = parent->total_sectors; + cxt->ask_cb = parent->ask_cb; + cxt->ask_data = parent->ask_data; + cxt->geom = parent->geom; - if (strcmp(name, "bsd") == 0) - cxt->label = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt); + if (name && strcmp(name, "bsd") == 0) + lb = cxt->labels[ cxt->nlabels++ ] = fdisk_new_bsd_label(cxt); + + if (lb) { + DBG(LABEL, dbgprint("probing for nested %s", lb->name)); + + cxt->label = lb; + + if (lb->op->probe(cxt) == 1) + __fdisk_context_switch_label(cxt, lb); + else { + DBG(LABEL, dbgprint("not found %s label", lb->name)); + if (lb->op->deinit) + lb->op->deinit(lb); + cxt->label = NULL; + } + } return cxt; } @@ -77,18 +94,46 @@ struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const cha return cxt->label; for (i = 0; i < cxt->nlabels; i++) - if (strcmp(cxt->labels[i]->name, name) == 0) + if (cxt->labels[i] + && strcmp(cxt->labels[i]->name, name) == 0) return cxt->labels[i]; DBG(LABEL, dbgprint("failed to found %s label driver\n", name)); return NULL; } +int fdisk_context_next_label(struct fdisk_context *cxt, struct fdisk_label **lb) +{ + size_t i; + struct fdisk_label *res = NULL; + + if (!lb || !cxt) + return -EINVAL; + + if (!*lb) + res = cxt->labels[0]; + else { + for (i = 1; i < cxt->nlabels; i++) { + if (*lb == cxt->labels[i - 1]) { + res = cxt->labels[i]; + break; + } + } + } + + *lb = res; + return res ? 0 : 1; +} + int __fdisk_context_switch_label(struct fdisk_context *cxt, struct fdisk_label *lb) { - if (!lb) + if (!lb || !cxt) return -EINVAL; + if (lb->disabled) { + DBG(LABEL, dbgprint("*** attempt to switch to disabled label %s -- ignore!", lb->name)); + return -EINVAL; + } cxt->label = lb; DBG(LABEL, dbgprint("--> switching context to %s!", lb->name)); return 0; @@ -105,7 +150,7 @@ static void reset_context(struct fdisk_context *cxt) { size_t i; - DBG(CONTEXT, dbgprint("\n-----\nresetting context %p", cxt)); + DBG(CONTEXT, dbgprint("*** resetting context %p", cxt)); /* reset drives' private data */ for (i = 0; i < cxt->nlabels; i++) @@ -122,17 +167,7 @@ static void reset_context(struct fdisk_context *cxt) cxt->dev_path = NULL; cxt->firstsector = NULL; - cxt->io_size = 0; - cxt->optimal_io_size = 0; - cxt->min_io_size = 0; - cxt->phy_sector_size = 0; - cxt->sector_size = 0; - cxt->alignment_offset = 0; - cxt->grain = 0; - cxt->first_lba = 0; - cxt->total_sectors = 0; - - memset(&cxt->geom, 0, sizeof(struct fdisk_geometry)); + fdisk_zeroize_device_properties(cxt); cxt->label = NULL; } @@ -158,12 +193,11 @@ int fdisk_context_assign_device(struct fdisk_context *cxt, reset_context(cxt); - if (readonly == 1 || (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) { - if ((fd = open(fname, O_RDONLY|O_CLOEXEC)) < 0) - return -errno; - readonly = 1; - } + fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC); + if (fd < 0) + return -errno; + cxt->readonly = readonly; cxt->dev_fd = fd; cxt->dev_path = strdup(fname); if (!cxt->dev_path) @@ -178,7 +212,10 @@ int fdisk_context_assign_device(struct fdisk_context *cxt, /* detect labels and apply labes specific stuff (e.g geomery) * to the context */ fdisk_probe_labels(cxt); - fdisk_reset_alignment(cxt); + + /* let's apply user geometry *after* label prober + * to make it possible to override in-label setting */ + fdisk_apply_user_device_properties(cxt); DBG(CONTEXT, dbgprint("context %p initialized for %s [%s]", cxt, fname, @@ -189,6 +226,29 @@ fail: return -errno; } +int fdisk_context_deassign_device(struct fdisk_context *cxt) +{ + assert(cxt); + assert(cxt->dev_fd >= 0); + + if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) { + fdisk_warn(cxt, _("%s: close device failed"), cxt->dev_path); + return -errno; + } + + fdisk_info(cxt, _("Syncing disks.")); + sync(); + + cxt->dev_fd = -1; + return 0; +} + +int fdisk_context_is_readonly(struct fdisk_context *cxt) +{ + assert(cxt); + return cxt->readonly; +} + /** * fdisk_free_context: * @cxt: fdisk context @@ -237,6 +297,50 @@ int fdisk_context_set_ask(struct fdisk_context *cxt, return 0; } +/** + * fdisk_context_enable_details: + * cxt: context + * enable: true/flase + * + * Enables or disables "details" display mode. + * + * Returns: 0 on success, < 0 on error. + */ +int fdisk_context_enable_details(struct fdisk_context *cxt, int enable) +{ + assert(cxt); + cxt->display_details = enable ? 1 : 0; + return 0; +} + +int fdisk_context_display_details(struct fdisk_context *cxt) +{ + assert(cxt); + return cxt->display_details == 1; +} + +/** + * fdisk_context_enable_listonly: + * cxt: context + * enable: true/flase + * + * Just list partition only, don't care about another details, mistakes, ... + * + * Returns: 0 on success, < 0 on error. + */ +int fdisk_context_enable_listonly(struct fdisk_context *cxt, int enable) +{ + assert(cxt); + cxt->listonly = enable ? 1 : 0; + return 0; +} + +int fdisk_context_listonly(struct fdisk_context *cxt) +{ + assert(cxt); + return cxt->listonly == 1; +} + /* * @str: "cylinder" or "sector". |
