diff options
author | Manuel Bentele | 2019-08-21 14:58:42 +0200 |
---|---|---|
committer | Manuel Bentele | 2019-08-21 14:58:42 +0200 |
commit | 0692b963aa3cb846d8abab5ef5247c4dbb3fec96 (patch) | |
tree | f13776d25da3e1adc1445aef22e7566ac98cbe84 /libfdisk | |
parent | losetup: added file format option to the man page (diff) | |
parent | partx: document -d vs. --nr and fix test (diff) | |
download | kernel-qcow2-util-linux-0692b963aa3cb846d8abab5ef5247c4dbb3fec96.tar.gz kernel-qcow2-util-linux-0692b963aa3cb846d8abab5ef5247c4dbb3fec96.tar.xz kernel-qcow2-util-linux-0692b963aa3cb846d8abab5ef5247c4dbb3fec96.zip |
lib/losetup: merge remote-tracking branch 'util-linux/master'kernel-qcow2
Signed-off-by: Manuel Bentele <development@manuel-bentele.de>
Diffstat (limited to 'libfdisk')
-rw-r--r-- | libfdisk/docs/libfdisk-sections.txt | 2 | ||||
-rw-r--r-- | libfdisk/src/alignment.c | 2 | ||||
-rw-r--r-- | libfdisk/src/context.c | 163 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 6 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 1 | ||||
-rw-r--r-- | libfdisk/src/label.c | 9 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 3 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 5 | ||||
-rw-r--r-- | libfdisk/src/partition.c | 10 | ||||
-rw-r--r-- | libfdisk/src/script.c | 117 | ||||
-rw-r--r-- | libfdisk/src/table.c | 2 |
11 files changed, 237 insertions, 83 deletions
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt index f6675fe46..f148da527 100644 --- a/libfdisk/docs/libfdisk-sections.txt +++ b/libfdisk/docs/libfdisk-sections.txt @@ -132,6 +132,7 @@ fdisk_ref_script fdisk_script_enable_json fdisk_script_get_header fdisk_script_get_nlines +fdisk_script_set_table fdisk_script_get_table fdisk_script_has_force_label fdisk_script_read_context @@ -290,6 +291,7 @@ fdisk_unref_table <FILE>context</FILE> fdisk_context fdisk_assign_device +fdisk_assign_device_by_fd fdisk_deassign_device fdisk_reassign_device fdisk_device_is_used diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c index 426fa938c..4ae5ff08f 100644 --- a/libfdisk/src/alignment.c +++ b/libfdisk/src/alignment.c @@ -324,7 +324,7 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt, * * The smallest possible granularity for partitioning is physical sector size * (or minimal I/O size; the bigger number win). If the user's @grain size is - * too small than the smallest possible granularity is used. It means + * too small then the smallest possible granularity is used. It means * fdisk_save_user_grain(cxt, 512) forces libfdisk to use grain as small as * possible. * diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 56ebb6c1e..f97f0a612 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -17,13 +17,13 @@ * * The library distinguish between three types of partitioning objects. * - * on-disk data + * on-disk label data * - disk label specific * - probed and read by disklabel drivers when assign device to the context * or when switch to another disk label type * - only fdisk_write_disklabel() modify on-disk data * - * in-memory data + * in-memory label data * - generic data and disklabel specific data stored in struct fdisk_label * - all partitioning operations are based on in-memory data only * @@ -31,8 +31,12 @@ * - provides abstraction to present partitions to users * - fdisk_partition is possible to gather to fdisk_table container * - used as unified template for new partitions + * - used (with fdisk_table) in fdisk scripts * - the struct fdisk_partition is always completely independent object and * any change to the object has no effect to in-memory (or on-disk) label data + * + * Don't forget to inform kernel about changes by fdisk_reread_partition_table() + * or more smart fdisk_reread_changes(). */ /** @@ -483,7 +487,7 @@ int fdisk_is_ptcollision(struct fdisk_context *cxt) * </informalexample> * * Note that the recommended way to list partitions is to use - * fdisk_get_partitions() and struct fdisk_table than ask disk driver for each + * fdisk_get_partitions() and struct fdisk_table then ask disk driver for each * individual partitions. * * Returns: maximal number of partitions for the current label. @@ -537,7 +541,7 @@ static void reset_context(struct fdisk_context *cxt) free(cxt->firstsector); } else { /* we close device only in primary context */ - if (cxt->dev_fd > -1) + if (cxt->dev_fd > -1 && cxt->private_fd) close(cxt->dev_fd); free(cxt->firstsector); } @@ -555,6 +559,7 @@ static void reset_context(struct fdisk_context *cxt) memset(&cxt->dev_st, 0, sizeof(cxt->dev_st)); cxt->dev_fd = -1; + cxt->private_fd = 0; cxt->firstsector = NULL; cxt->firstsector_bufsz = 0; @@ -568,30 +573,12 @@ static void reset_context(struct fdisk_context *cxt) fdisk_free_wipe_areas(cxt); } -/** - * fdisk_assign_device: - * @cxt: context - * @fname: path to the device to be handled - * @readonly: how to open the device - * - * Open the device, discovery topology, geometry, detect disklabel and switch - * the current label driver to reflect the probing result. - * - * Note that this function resets all generic setting in context. If the @cxt - * is nested context then the device is assigned to the parental context and - * necessary properties are copied to the @cxt. The change is propagated in - * child->parent direction only. It's impossible to use a different device for - * primary and nested contexts. - * - * Returns: 0 on success, < 0 on error. - */ -int fdisk_assign_device(struct fdisk_context *cxt, - const char *fname, int readonly) +/* fdisk_assign_device() body */ +static int fdisk_assign_fd(struct fdisk_context *cxt, int fd, + const char *fname, int readonly, int privfd) { - int fd; - - DBG(CXT, ul_debugobj(cxt, "assigning device %s", fname)); assert(cxt); + assert(fd >= 0); /* redirect request to parent */ if (cxt->parent) { @@ -602,7 +589,7 @@ int fdisk_assign_device(struct fdisk_context *cxt, * unwanted extra warnings. */ fdisk_enable_listonly(cxt->parent, fdisk_is_listonly(cxt)); - rc = fdisk_assign_device(cxt->parent, fname, readonly); + rc = fdisk_assign_fd(cxt->parent, fd, fname, readonly, privfd); fdisk_enable_listonly(cxt->parent, org); if (!rc) @@ -614,16 +601,13 @@ int fdisk_assign_device(struct fdisk_context *cxt, reset_context(cxt); - fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC); - if (fd < 0) - goto fail; - if (fstat(fd, &cxt->dev_st) != 0) goto fail; cxt->readonly = readonly; cxt->dev_fd = fd; - cxt->dev_path = strdup(fname); + cxt->private_fd = privfd; + cxt->dev_path = fname ? strdup(fname) : NULL; if (!cxt->dev_path) goto fail; @@ -635,15 +619,20 @@ int fdisk_assign_device(struct fdisk_context *cxt, if (fdisk_read_firstsector(cxt) < 0) goto fail; - fdisk_probe_labels(cxt); + /* warn about obsolete stuff on the device if we aren't in list-only */ + if (!fdisk_is_listonly(cxt) && fdisk_check_collisions(cxt) < 0) + goto fail; + fdisk_probe_labels(cxt); fdisk_apply_label_device_properties(cxt); - /* warn about obsolete stuff on the device if we aren't in - * list-only mode and there is not PT yet */ - if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt) - && fdisk_check_collisions(cxt) < 0) - goto fail; + /* Don't report collision if there is already a valid partition table. + * The bootbits are wiped when we create a *new* partition table only. */ + if (fdisk_is_ptcollision(cxt) && fdisk_has_label(cxt)) { + cxt->pt_collision = 0; + free(cxt->collision); + cxt->collision = NULL; + } DBG(CXT, ul_debugobj(cxt, "initialized for %s [%s]", fname, readonly ? "READ-ONLY" : "READ-WRITE")); @@ -651,19 +640,84 @@ int fdisk_assign_device(struct fdisk_context *cxt, fail: { int rc = -errno; - if (fd >= 0) - close(fd); DBG(CXT, ul_debugobj(cxt, "failed to assign device [rc=%d]", rc)); return rc; } } /** + * fdisk_assign_device: + * @cxt: context + * @fname: path to the device to be handled + * @readonly: how to open the device + * + * Open the device, discovery topology, geometry, detect disklabel, check for + * collisions and switch the current label driver to reflect the probing + * result. + * + * If in standard mode (!= non-listonly mode) then also detects for collisions. + * The result is accessible by fdisk_get_collision() and + * fdisk_is_ptcollision(). The collision (e.g. old obsolete PT) may be removed + * by fdisk_enable_wipe(). Note that new PT and old PT may be on different + * locations. + * + * Note that this function resets all generic setting in context. + * + * If the @cxt is nested context (necessary for example to edit BSD or PMBR) + * then the device is assigned to the parental context and necessary properties + * are copied to the @cxt. The change is propagated in child->parent direction + * only. It's impossible to use a different device for primary and nested + * contexts. + * + * Returns: 0 on success, < 0 on error. + */ +int fdisk_assign_device(struct fdisk_context *cxt, + const char *fname, int readonly) +{ + int fd, rc; + + DBG(CXT, ul_debugobj(cxt, "assigning device %s", fname)); + assert(cxt); + + fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC); + if (fd < 0) { + rc = -errno; + DBG(CXT, ul_debugobj(cxt, "failed to assign device [rc=%d]", rc)); + return rc; + } + + rc = fdisk_assign_fd(cxt, fd, fname, readonly, 1); + if (rc) + close(fd); + return rc; +} + +/** + * fdisk_assign_device_by_fd: + * @cxt: context + * @fd: device file descriptor + * @fname: path to the device (used for dialogs, debugging, partition names, ...) + * @readonly: how to use the device + * + * Like fdisk_assign_device(), but caller is responsible to open and close the + * device. The library only fsync() the device on fdisk_deassign_device(). + * + * The device has to be open O_RDWR on @readonly=0. + * + * Returns: 0 on success, < 0 on error. + */ +int fdisk_assign_device_by_fd(struct fdisk_context *cxt, int fd, + const char *fname, int readonly) +{ + return fdisk_assign_fd(cxt, fd, fname, readonly, 0); +} + +/** * fdisk_deassign_device: * @cxt: context * @nosync: disable fsync() * - * Close device and call fsync(). If the @cxt is nested context than the + * Close device and call fsync(). If the @cxt is nested context then the * request is redirected to the parent. * * Returns: 0 on success, < 0 on error. @@ -683,15 +737,19 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync) DBG(CXT, ul_debugobj(cxt, "de-assigning device %s", cxt->dev_path)); - if (cxt->readonly) + if (cxt->readonly && cxt->private_fd) close(cxt->dev_fd); else { - if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) { + if (fsync(cxt->dev_fd)) { + fdisk_warn(cxt, _("%s: fsync device failed"), + cxt->dev_path); + return -errno; + } + if (cxt->private_fd && close(cxt->dev_fd)) { fdisk_warn(cxt, _("%s: close device failed"), cxt->dev_path); return -errno; } - if (!nosync) { fdisk_info(cxt, _("Syncing disks.")); sync(); @@ -700,7 +758,6 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync) free(cxt->dev_path); cxt->dev_path = NULL; - cxt->dev_fd = -1; return 0; @@ -720,7 +777,7 @@ int fdisk_deassign_device(struct fdisk_context *cxt, int nosync) int fdisk_reassign_device(struct fdisk_context *cxt) { char *devname; - int rdonly, rc; + int rdonly, rc, fd, privfd; assert(cxt); assert(cxt->dev_fd >= 0); @@ -732,11 +789,19 @@ int fdisk_reassign_device(struct fdisk_context *cxt) return -ENOMEM; rdonly = cxt->readonly; + fd = cxt->dev_fd; + privfd = cxt->private_fd; fdisk_deassign_device(cxt, 1); - rc = fdisk_assign_device(cxt, devname, rdonly); - free(devname); + if (privfd) + /* reopen and assign */ + rc = fdisk_assign_device(cxt, devname, rdonly); + else + /* assign only */ + rc = fdisk_assign_fd(cxt, fd, devname, rdonly, privfd); + + free(devname); return rc; } @@ -774,7 +839,7 @@ int fdisk_reread_partition_table(struct fdisk_context *cxt) fdisk_info(cxt, _( "The kernel still uses the old table. The " "new table will be used at the next reboot " - "or after you run partprobe(8) or kpartx(8).")); + "or after you run partprobe(8) or partx(8).")); return -errno; } diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 6dc276e8a..fc5bcc651 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -814,6 +814,12 @@ static int dos_probe_label(struct fdisk_context *cxt) if (!mbr_is_valid_magic(cxt->firstsector)) return 0; + /* ignore disks with FAT */ + if (cxt->collision && + (strcmp(cxt->collision, "vfat") == 0 || + strcmp(cxt->collision, "ntfs") == 0)) + return 0; + dos_init(cxt); get_partition_table_geometry(cxt, &h, &s); diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 19c1c7953..fefebae2a 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -389,6 +389,7 @@ struct fdisk_context { pt_collision : 1, /* another PT detected by libblkid */ no_disalogs : 1, /* disable dialog-driven partititoning */ dev_model_probed : 1, /* tried to read from sys */ + private_fd : 1, /* open by libfdisk */ listonly : 1; /* list partition, nothing else */ char *collision; /* name of already existing FS/PT */ diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index 2a11acad6..a18cdeaff 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -247,7 +247,8 @@ const struct fdisk_field *fdisk_label_get_field_by_name( * fdisk_write_disklabel: * @cxt: fdisk context * - * Write in-memory changes to disk. Be careful! + * This function wipes the device (if enabled by fdisk_enable_wipe()) and then + * it writes in-memory changes to disk. Be careful! * * Returns: 0 on success, otherwise, a corresponding error. */ @@ -636,7 +637,7 @@ int fdisk_label_is_disabled(const struct fdisk_label *lb) * @ma: maximal number * * The function provides minimal and maximal geometry supported for the label, - * if no range defined by library than returns -ENOSYS. + * if no range defined by library then returns -ENOSYS. * * Since: 2.32 * @@ -661,7 +662,7 @@ int fdisk_label_get_geomrange_sectors(const struct fdisk_label *lb, * @ma: maximal number * * The function provides minimal and maximal geometry supported for the label, - * if no range defined by library than returns -ENOSYS. + * if no range defined by library then returns -ENOSYS. * * Since: 2.32 * @@ -686,7 +687,7 @@ int fdisk_label_get_geomrange_heads(const struct fdisk_label *lb, * @ma: maximal number * * The function provides minimal and maximal geometry supported for the label, - * if no range defined by library than returns -ENOSYS. + * if no range defined by library then returns -ENOSYS. * * Since: 2.32 * diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 47e778a67..0669c0a7c 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -195,6 +195,8 @@ int fdisk_is_labeltype(struct fdisk_context *cxt, enum fdisk_labeltype id); int fdisk_assign_device(struct fdisk_context *cxt, const char *fname, int readonly); +int fdisk_assign_device_by_fd(struct fdisk_context *cxt, int fd, + const char *fname, int readonly); int fdisk_deassign_device(struct fdisk_context *cxt, int nosync); int fdisk_reassign_device(struct fdisk_context *cxt); @@ -757,6 +759,7 @@ void fdisk_unref_script(struct fdisk_script *dp); const char *fdisk_script_get_header(struct fdisk_script *dp, const char *name); int fdisk_script_set_header(struct fdisk_script *dp, const char *name, const char *data); struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp); +int fdisk_script_set_table(struct fdisk_script *dp, struct fdisk_table *tb); int fdisk_script_get_nlines(struct fdisk_script *dp); int fdisk_script_has_force_label(struct fdisk_script *dp); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index 8f80d7964..96fcadd71 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -303,3 +303,8 @@ FDISK_2.33 { fdisk_get_devmodel; fdisk_get_devno; } FDISK_2.32; + +FDISK_2.35 { + fdisk_script_set_table; + fdisk_assign_device_by_fd; +} FDISK_2.33; diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c index 05474a041..80a43ffde 100644 --- a/libfdisk/src/partition.c +++ b/libfdisk/src/partition.c @@ -85,7 +85,13 @@ static struct fdisk_partition *__copy_partition(struct fdisk_partition *o) if (!n) return NULL; + memcpy(n, o, sizeof(*n)); + + /* do not copy reference to lists, etc.*/ + n->refcount = 1; + INIT_LIST_HEAD(&n->parts); + if (n->type) fdisk_ref_parttype(n->type); if (o->name) @@ -100,6 +106,10 @@ static struct fdisk_partition *__copy_partition(struct fdisk_partition *o) n->fsuuid = strdup(o->fsuuid); if (o->fslabel) n->fslabel = strdup(o->fslabel); + if (o->start_chs) + n->start_chs = strdup(o->start_chs); + if (o->end_chs) + n->end_chs = strdup(o->end_chs); return n; } diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index 66be4f08c..a28983dba 100644 --- a/libfdisk/src/script.c +++ b/libfdisk/src/script.c @@ -7,13 +7,33 @@ /** * SECTION: script * @title: Script - * @short_description: text based sfdisk compatible description of partition table + * @short_description: complex way to create and dump partition table * - * The libfdisk scripts are based on original sfdisk script (dumps). Each + * This interface allows to compose in-memory partition table with all details, + * write all partition table description to human readable text file, read it + * from the file, and apply the script to on-disk label. + * + * The libfdisk scripts are based on original sfdisk script (dumps). Each * script has two parts: script headers and partition table entries - * (partitions). + * (partitions). The script is possible to dump in JSON too (read JSON is not + * implemented yet). * * For more details about script format see sfdisk man page. + * + * There are four ways how to build the script: + * + * - read the current on-disk partition table by fdisk_script_read_context()) + * - read it from text file by fdisk_script_read_file() + * - read it interactively from user by fdisk_script_read_line() and fdisk_script_set_fgets() + * - manually in code by fdisk_script_set_header() and fdisk_script_set_table() + * + * The read functions fdisk_script_read_context() and fdisk_script_read_file() + * creates always a new script partition table. The table (see + * fdisk_script_get_table()) is possible to modify by standard + * fdisk_table_...() functions and then apply by fdisk_apply_script(). + * + * Note that script API is fully non-interactive and forces libfdisk to not use + * standard dialog driven partitioning as we have in fdisk(8). */ /* script header (e.g. unit: sectors) */ @@ -41,6 +61,8 @@ struct fdisk_script { force_label : 1; /* label: <name> specified */ }; +static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str); + static void fdisk_script_free_header(struct fdisk_scriptheader *fi) { @@ -76,12 +98,6 @@ struct fdisk_script *fdisk_new_script(struct fdisk_context *cxt) dp->cxt = cxt; fdisk_ref_context(cxt); - dp->table = fdisk_new_table(); - if (!dp->table) { - fdisk_unref_script(dp); - return NULL; - } - INIT_LIST_HEAD(&dp->headers); return dp; } @@ -148,8 +164,9 @@ static void fdisk_reset_script(struct fdisk_script *dp) assert(dp); DBG(SCRIPT, ul_debugobj(dp, "reset")); - fdisk_unref_table(dp->table); - dp->table = NULL; + + if (dp->table) + fdisk_reset_table(dp->table); while (!list_empty(&dp->headers)) { struct fdisk_scriptheader *fi = list_entry(dp->headers.next, @@ -317,16 +334,58 @@ int fdisk_script_set_header(struct fdisk_script *dp, * fdisk_script_get_table: * @dp: script * - * The table (container with partitions) is possible to create by - * fdisk_script_read_context() or fdisk_script_read_file(), otherwise - * this function returns NULL. + * The table represents partitions holded by the script. The table is possible to + * fill by fdisk_script_read_context() or fdisk_script_read_file(). All the "read" + * functions remove old partitions from the table. See also fdisk_script_set_table(). * - * Returns: NULL or script. + * Returns: NULL or script table. */ struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp) { assert(dp); - return dp ? dp->table : NULL; + + if (!dp->table) + /* + * Make sure user has access to the same table as script. If + * there is no table then create a new one and reuse it later. + */ + dp->table = fdisk_new_table(); + + return dp->table; +} + +/** + * fdisk_script_set_table: + * @dp: script + * @tb: table + * + * Replaces table used by script and creates a new reference to @tb. This + * function allows to generate a new script table independently on the current + * context and without any file reading. + * + * This is useful for example to create partition table with the same basic + * settings (e.g. label-id, ...) but with different partitions -- just call + * fdisk_script_read_context() to get current settings and then + * fdisk_script_set_table() to set a different layout. + * + * If @tb is NULL then the current script table is unreferenced. + * + * Note that script read_ functions (e.g. fdisk_script_read_context()) create + * always a new script table. + * + * Returns: 0 on success, <0 on error + */ +int fdisk_script_set_table(struct fdisk_script *dp, struct fdisk_table *tb) +{ + if (!dp) + return -EINVAL; + + fdisk_ref_table(tb); + fdisk_unref_table(dp->table); + dp->table = tb; + + DBG(SCRIPT, ul_debugobj(dp, "table replaced")); + return 0; } static struct fdisk_label *script_get_label(struct fdisk_script *dp) @@ -377,7 +436,7 @@ int fdisk_script_has_force_label(struct fdisk_script *dp) * @cxt: context * * Reads data from the @cxt context (on disk partition table) into the script. - * If the context is no specified than defaults to context used for fdisk_new_script(). + * If the context is not specified then defaults to context used for fdisk_new_script(). * * Return: 0 on success, <0 on error. */ @@ -400,7 +459,7 @@ int fdisk_script_read_context(struct fdisk_script *dp, struct fdisk_context *cxt if (!lb) return -EINVAL; - /* allocate and fill new table */ + /* allocate (if not yet) and fill table */ rc = fdisk_get_partitions(cxt, &dp->table); if (rc) return rc; @@ -542,7 +601,7 @@ static int write_file_json(struct fdisk_script *dp, FILE *f) } - if (!dp->table) { + if (!dp->table || fdisk_table_is_empty(dp->table)) { DBG(SCRIPT, ul_debugobj(dp, "script table empty")); goto done; } @@ -651,7 +710,7 @@ static int write_file_sfdisk(struct fdisk_script *dp, FILE *f) devname = fi->data; } - if (!dp->table) { + if (!dp->table || fdisk_table_is_empty(dp->table)) { DBG(SCRIPT, ul_debugobj(dp, "script table empty")); return 0; } @@ -911,6 +970,7 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) assert(dp); assert(s); + assert(dp->table); DBG(SCRIPT, ul_debugobj(dp, " parse script line: '%s'", s)); @@ -996,8 +1056,11 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) rc = next_string(&p, &type); if (rc) break; - pa->type = fdisk_label_parse_parttype( - script_get_label(dp), type); + + pa->type = translate_type_shortcuts(dp, type); + if (!pa->type) + pa->type = fdisk_label_parse_parttype( + script_get_label(dp), type); free(type); if (!pa->type) { @@ -1106,6 +1169,7 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) assert(dp); assert(s); + assert(dp->table); pa = fdisk_new_partition(); if (!pa) @@ -1240,11 +1304,8 @@ static int fdisk_script_read_buffer(struct fdisk_script *dp, char *s) if (!s || !*s) return 0; /* nothing baby, ignore */ - if (!dp->table) { - dp->table = fdisk_new_table(); - if (!dp->table) - return -ENOMEM; - } + if (!dp->table && fdisk_script_get_table(dp) == NULL) + return -ENOMEM; /* parse header lines only if no partition specified yet */ if (fdisk_table_is_empty(dp->table) && is_header_line(s)) @@ -1569,7 +1630,7 @@ static int test_stdin(struct fdisk_test *ts, int argc, char *argv[]) printf("<start>, <size>, <type>, <bootable: *|->\n"); do { struct fdisk_partition *pa; - size_t n = fdisk_table_get_nents(dp->table); + size_t n = dp->table ? fdisk_table_get_nents(dp->table) : 0; printf(" #%zu :\n", n + 1); rc = fdisk_script_read_line(dp, stdin, buf, sizeof(buf)); diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c index 1f9d5a28a..8a3a935af 100644 --- a/libfdisk/src/table.c +++ b/libfdisk/src/table.c @@ -303,7 +303,7 @@ int fdisk_table_remove_partition(struct fdisk_table *tb, struct fdisk_partition * @tb: returns table * * This function adds partitions from disklabel to @table, it allocates a new - * table if if @table points to NULL. + * table if @table points to NULL. * * Returns: 0 on success, otherwise, a corresponding error. */ |