diff options
-rw-r--r-- | fdisks/fdisk.c | 32 | ||||
-rw-r--r-- | fdisks/gpt.c | 51 | ||||
-rw-r--r-- | libfdisk/src/alignment.c | 2 | ||||
-rw-r--r-- | libfdisk/src/context.c | 71 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 3 | ||||
-rw-r--r-- | libfdisk/src/label.c | 31 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 6 | ||||
-rw-r--r-- | libfdisk/src/utils.c | 1 |
8 files changed, 128 insertions, 69 deletions
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 866d8fe21..c771f6e6d 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -1387,12 +1387,10 @@ static int is_ide_cdrom_or_tape(char *device) } /* Print disk geometry and partition table of a specified device (-l option) */ -static void print_partition_table_from_option(char *device, unsigned long sector_size) +static void print_partition_table_from_option(struct fdisk_context *cxt, + char *device, unsigned long sector_size) { - struct fdisk_context *cxt; - - cxt = fdisk_new_context_from_filename(device, 1); /* read-only */ - if (!cxt) + if (fdisk_context_assign_device(cxt, device, 1) != 0) /* read-only */ err(EXIT_FAILURE, _("cannot open %s"), device); if (sector_size) /* passed -b option, override autodiscovery */ @@ -1413,9 +1411,6 @@ static void print_partition_table_from_option(char *device, unsigned long sector btrydev(cxt); } else list_table(cxt, 0); - - fdisk_free_context(cxt); - cxt = NULL; } /* @@ -1423,7 +1418,8 @@ static void print_partition_table_from_option(char *device, unsigned long sector * try all things in /proc/partitions that look like a full disk */ static void -print_all_partition_table_from_option(unsigned long sector_size) +print_all_partition_table_from_option(struct fdisk_context *cxt, + unsigned long sector_size) { FILE *procpt; char line[128 + 1], ptname[128 + 1], devname[256]; @@ -1445,7 +1441,7 @@ print_all_partition_table_from_option(unsigned long sector_size) char *cn = canonicalize_path(devname); if (cn) { if (!is_ide_cdrom_or_tape(cn)) - print_partition_table_from_option(cn, sector_size); + print_partition_table_from_option(cxt, cn, sector_size); free(cn); } } @@ -1593,13 +1589,18 @@ int main(int argc, char **argv) { int c, optl = 0, opts = 0; unsigned long sector_size = 0; - struct fdisk_context *cxt = NULL; + struct fdisk_context *cxt; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); + fdisk_init_debug(0); + cxt = fdisk_new_context(); + if (!cxt) + err(EXIT_FAILURE, _("failed to allocate libfdisk context")); + while ((c = getopt(argc, argv, "b:c::C:hH:lsS:u::vV")) != -1) { switch (c) { case 'b': @@ -1657,7 +1658,6 @@ int main(int argc, char **argv) } } - fdisk_init_debug(0); if (sector_size && argc-optind != 1) printf(_("Warning: the -b (set sector size) option should" @@ -1668,9 +1668,9 @@ int main(int argc, char **argv) if (argc > optind) { int k; for (k = optind; k < argc; k++) - print_partition_table_from_option(argv[k], sector_size); + print_partition_table_from_option(cxt, argv[k], sector_size); } else - print_all_partition_table_from_option(sector_size); + print_all_partition_table_from_option(cxt, sector_size); exit(EXIT_SUCCESS); } @@ -1692,8 +1692,7 @@ int main(int argc, char **argv) if (argc-optind != 1) usage(stderr); - cxt = fdisk_new_context_from_filename(argv[optind], 0); - if (!cxt) + if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0) err(EXIT_FAILURE, _("cannot open %s"), argv[optind]); if (sector_size) /* passed -b option, override autodiscovery */ @@ -1714,5 +1713,6 @@ int main(int argc, char **argv) command_prompt(cxt); + fdisk_free_context(cxt); return 0; } diff --git a/fdisks/gpt.c b/fdisks/gpt.c index 4f70f962d..f9ba9f072 100644 --- a/fdisks/gpt.c +++ b/fdisks/gpt.c @@ -248,6 +248,8 @@ static struct fdisk_parttype gpt_parttypes[] = DEF_GUID("85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD Vinum")), }; +/* FIXME: move these global variables to fdisk_gpt_label */ + /* primary GPT header */ static struct gpt_header *pheader = NULL; /* backup GPT header */ @@ -1009,21 +1011,6 @@ static void gpt_init(struct fdisk_context *cxt) partitions = le32_to_cpu(pheader->npartition_entries); } -/* - * Deinitialize fdisk-specific variables - */ -static void gpt_deinit(struct fdisk_context *cxt) -{ - free(ents); - free(pheader); - free(bheader); - ents = NULL; - pheader = NULL; - bheader = NULL; - - cxt->disklabel = FDISK_DISKLABEL_ANY; - partitions = 0; -} static int gpt_probe_label(struct fdisk_context *cxt) { @@ -1062,6 +1049,7 @@ static int gpt_probe_label(struct fdisk_context *cxt) return 1; failed: + DBG(LABEL, dbgprint("GPT probe failed")); return 0; } @@ -1580,17 +1568,15 @@ static int gpt_create_disklabel(struct fdisk_context *cxt) int rc = 0; ssize_t entry_sz = 0; + /* labe private stuff has to be empty, see gpt_deinit() */ + assert(pheader == NULL); + assert(bheader == NULL); + /* - * Reset space or clear data from headers, pt entries and - * protective MBR. Big fat warning: any previous content is - * overwritten, so ask users to be sure!. - * * When no header, entries or pmbr is set, we're probably * dealing with a new, empty disk - so always allocate memory * to deal with the data structures whatever the case is. */ - gpt_deinit(cxt); - rc = gpt_mknew_pmbr(cxt); if (rc < 0) goto done; @@ -1663,6 +1649,25 @@ static int gpt_set_partition_type(struct fdisk_context *cxt, int i, return 0; } +/* + * Deinitialize fdisk-specific variables + */ +static void gpt_deinit(struct fdisk_label *lb) +{ + free(ents); + free(pheader); + free(bheader); + + ents = NULL; + pheader = NULL; + bheader = NULL; + + if (lb->cxt && lb->cxt->disklabel == FDISK_DISKLABEL_GPT) + lb->cxt->disklabel = FDISK_DISKLABEL_ANY; + + partitions = 0; +} + static const struct fdisk_label_operations gpt_operations = { .probe = gpt_probe_label, @@ -1672,7 +1677,9 @@ static const struct fdisk_label_operations gpt_operations = .part_add = gpt_add_partition, .part_delete = gpt_delete_partition, .part_get_type = gpt_get_partition_type, - .part_set_type = gpt_set_partition_type + .part_set_type = gpt_set_partition_type, + + .deinit = gpt_deinit }; /* diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c index 1ef5796a4..25323d1b5 100644 --- a/libfdisk/src/alignment.c +++ b/libfdisk/src/alignment.c @@ -185,7 +185,7 @@ int fdisk_discover_geometry(struct fdisk_context *cxt) unsigned int h = 0, s = 0; assert(cxt); - assert(!cxt->geom.heads); + assert(cxt->geom.heads == 0); /* get number of 512-byte sectors, and convert it the real sectors */ if (!blkdev_get_sectors(cxt->dev_fd, &nsects)) diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 83420a977..b2929f351 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -1,7 +1,7 @@ #include "fdiskP.h" -static struct fdisk_context *fdisk_new_context(void) +struct fdisk_context *fdisk_new_context(void) { struct fdisk_context *cxt; size_t i; @@ -10,6 +10,9 @@ static struct fdisk_context *fdisk_new_context(void) if (!cxt) return NULL; + DBG(LABEL, dbgprint("new context %p allocated", cxt)); + cxt->dev_fd = -1; + /* * Allocate label specific structs. * @@ -47,8 +50,37 @@ struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const cha return NULL; } +static void reset_context(struct fdisk_context *cxt) +{ + size_t nlbs; + struct fdisk_label *lbs[ ARRAY_SIZE(cxt->labels) ]; + + DBG(CONTEXT, dbgprint("\n-----\nresetting context %p", cxt)); + fdisk_deinit_label(cxt); /* reset the current label */ + + /* remember permanent setting */ + memcpy(lbs, cxt->labels, sizeof(lbs)); + nlbs = cxt->nlabels; + + /* free device specific stuff */ + if (cxt->dev_fd > -1) + close(cxt->dev_fd); + free(cxt->dev_path); + free(cxt->firstsector); + + /* the reset */ + memset(cxt, 0, sizeof(*cxt)); + + /* initialize */ + cxt->dev_fd = -1; + + /* set permanent setting */ + memcpy(cxt->labels, lbs, sizeof(lbs)); + cxt->nlabels = nlbs; +} + /** - * fdisk_new_context_from_filename: + * fdisk_context_assign_device: * @fname: path to the device to be handled * @readonly: how to open the device * @@ -56,25 +88,24 @@ struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const cha * the device with read-write mode and will fallback to read-only if * unsuccessful. * - * Returns: newly allocated fdisk context or NULL upon failure. + * Returns: 0 on sucess, < 0 on error. */ -struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly) +int fdisk_context_assign_device(struct fdisk_context *cxt, + const char *fname, int readonly) { - int fd, errsv = 0; - struct fdisk_context *cxt = NULL; + int fd; - DBG(CONTEXT, dbgprint("initializing context for %s", fname)); + DBG(CONTEXT, dbgprint("assigning device %s", fname)); + assert(cxt); + + reset_context(cxt); if (readonly == 1 || (fd = open(fname, O_RDWR)) < 0) { if ((fd = open(fname, O_RDONLY)) < 0) - return NULL; + return -errno; readonly = 1; } - cxt = fdisk_new_context(); - if (!cxt) - goto fail; - cxt->dev_fd = fd; cxt->dev_path = strdup(fname); if (!cxt->dev_path) @@ -89,20 +120,15 @@ struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int rea /* detect labels and apply labes specific stuff (e.g geomery) * to the context */ fdisk_probe_labels(cxt); - fdisk_reset_alignment(cxt); DBG(CONTEXT, dbgprint("context %p initialized for %s [%s]", cxt, fname, readonly ? "READ-ONLY" : "READ-WRITE")); - return cxt; + return 0; fail: - errsv = errno; - fdisk_free_context(cxt); - errno = errsv; - - DBG(CONTEXT, dbgprint("failed to initialize context for %s: %m", fname)); - return NULL; + DBG(CONTEXT, dbgprint("failed to assign device")); + return -errno; } /** @@ -119,10 +145,7 @@ void fdisk_free_context(struct fdisk_context *cxt) return; DBG(CONTEXT, dbgprint("freeing context %p for %s", cxt, cxt->dev_path)); - if (cxt->dev_fd > -1) - close(cxt->dev_fd); - free(cxt->dev_path); - free(cxt->firstsector); + reset_context(cxt); /* deallocate label's private stuff */ for (i = 0; i < cxt->nlabels; i++) { diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 01dd71f51..4d352b5d4 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -143,6 +143,8 @@ struct fdisk_label_operations { /* free in-memory label stuff */ void (*free)(struct fdisk_label *lb); + /* deinit in-memory label stuff */ + void (*deinit)(struct fdisk_label *lb); }; /* @@ -231,5 +233,6 @@ extern int fdisk_read_firstsector(struct fdisk_context *cxt); /* label.c */ extern int fdisk_probe_labels(struct fdisk_context *cxt); +extern void fdisk_deinit_label(struct fdisk_context *cxt); #endif /* _LIBFDISK_PRIVATE_H */ diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index 8f9934835..5fb40adc7 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -9,15 +9,23 @@ int fdisk_probe_labels(struct fdisk_context *cxt) size_t i; cxt->disklabel = FDISK_DISKLABEL_ANY; + cxt->label = NULL; for (i = 0; i < cxt->nlabels; i++) { - if (!cxt->labels[i]->op->probe || - cxt->labels[i]->op->probe(cxt) != 1) + struct fdisk_label *lb = cxt->labels[i]; + + if (!lb->op->probe) continue; - cxt->label = cxt->labels[i]; + DBG(LABEL, dbgprint("probing for %s", lb->name)); + if (lb->op->probe(cxt) != 1) { + if (lb->op->deinit) + lb->op->deinit(lb); /* for sure */ + continue; + } - DBG(LABEL, dbgprint("detected a %s label", cxt->label->name)); + cxt->label = lb; + DBG(LABEL, dbgprint("detected a %s label", lb->name)); return 0; } @@ -151,6 +159,8 @@ int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name) #endif } + fdisk_deinit_label(cxt); /* deinitialize the current label */ + cxt->label = fdisk_context_get_label(cxt, name); if (!cxt->label) return -EINVAL; @@ -210,3 +220,16 @@ size_t fdisk_get_nparttypes(struct fdisk_context *cxt) return cxt->label->nparttypes; } + +/* + * Resets the current used label driver to initial state + */ +void fdisk_deinit_label(struct fdisk_context *cxt) +{ + assert(cxt); + + if (!cxt->label || !cxt->label->op->deinit) + return; + + cxt->label->op->deinit(cxt->label); +} diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index d72a60889..d803fc2dc 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -47,10 +47,12 @@ enum fdisk_labeltype { extern void fdisk_init_debug(int mask); /* context.h */ -extern struct fdisk_context *fdisk_new_context_from_filename( - const char *fname, int readonly); +extern struct fdisk_context *fdisk_new_context(void); extern void fdisk_free_context(struct fdisk_context *cxt); +extern int fdisk_context_assign_device(struct fdisk_context *cxt, + const char *fname, int readonly); + extern struct fdisk_label *fdisk_context_get_label(struct fdisk_context *cxt, const char *name); diff --git a/libfdisk/src/utils.c b/libfdisk/src/utils.c index 6668e23e3..1360e8467 100644 --- a/libfdisk/src/utils.c +++ b/libfdisk/src/utils.c @@ -35,6 +35,7 @@ int fdisk_read_firstsector(struct fdisk_context *cxt) if (r != cxt->sector_size) { if (!errno) errno = EINVAL; /* probably too small file/device */ + DBG(TOPOLOGY, dbgprint("failed to read first sector %m")); return -errno; } |