diff options
-rw-r--r-- | include/closestream.h | 7 | ||||
-rw-r--r-- | libfdisk/docs/libfdisk-sections.txt | 1 | ||||
-rw-r--r-- | libfdisk/src/context.c | 31 | ||||
-rw-r--r-- | libfdisk/src/label.c | 3 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h.in | 1 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.sym | 4 | ||||
-rw-r--r-- | libfdisk/src/script.c | 106 | ||||
-rw-r--r-- | libfdisk/src/table.c | 2 | ||||
-rw-r--r-- | sys-utils/fsfreeze.c | 2 | ||||
-rw-r--r-- | sys-utils/ldattach.c | 2 | ||||
-rw-r--r-- | sys-utils/losetup.c | 2 | ||||
-rw-r--r-- | sys-utils/lscpu.c | 56 | ||||
-rw-r--r-- | sys-utils/lscpu.h | 9 | ||||
-rw-r--r-- | sys-utils/lsipc.c | 2 | ||||
-rw-r--r-- | text-utils/colrm.c | 2 |
15 files changed, 180 insertions, 50 deletions
diff --git a/include/closestream.h b/include/closestream.h index 6a62e48e8..83df1ee7d 100644 --- a/include/closestream.h +++ b/include/closestream.h @@ -39,7 +39,7 @@ close_stream(FILE * stream) static inline void close_stdout(void) { - if (close_stream(stdout) != 0 && !(errno == EPIPE)) { + if (stdout && close_stream(stdout) != 0 && !(errno == EPIPE)) { if (errno) warn(_("write error")); else @@ -47,8 +47,11 @@ close_stdout(void) _exit(CLOSE_EXIT_CODE); } - if (close_stream(stderr) != 0) + if (stderr && close_stream(stderr) != 0) _exit(CLOSE_EXIT_CODE); + + stdout = NULL; + stderr = NULL; } static inline void diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt index f6675fe46..d0d362f60 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 diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 56ebb6c1e..1171f28a8 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 lebel 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(). */ /** @@ -574,14 +578,23 @@ static void reset_context(struct fdisk_context *cxt) * @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. + * 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) than 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. * - * 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. + * 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. */ diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index 2a11acad6..68f73f143 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 eanbled by fdisk_enable_wipe() and than + * it writes in-memory changes to disk. Be careful! * * Returns: 0 on success, otherwise, a corresponding error. */ diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 47e778a67..69c6fd820 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -757,6 +757,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..8ce943acc 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -303,3 +303,7 @@ FDISK_2.33 { fdisk_get_devmodel; fdisk_get_devno; } FDISK_2.32; + +FDISK_2.35 { + fdisk_script_set_table; +} FDISK_2.33; diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index 66be4f08c..dbbd53eaf 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 than 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) */ @@ -76,12 +96,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 +162,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 +332,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 than create a new 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 than + * fdisk_script_set_table() to set a different layout. + * + * If @tb is NULL than 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) @@ -400,7 +457,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 +599,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 +708,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 +968,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)); @@ -1106,6 +1164,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 +1299,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 +1625,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. */ diff --git a/sys-utils/fsfreeze.c b/sys-utils/fsfreeze.c index 4da1a6fa3..6035a1010 100644 --- a/sys-utils/fsfreeze.c +++ b/sys-utils/fsfreeze.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) { diff --git a/sys-utils/ldattach.c b/sys-utils/ldattach.c index 3019e5a9f..c2d2f8397 100644 --- a/sys-utils/ldattach.c +++ b/sys-utils/ldattach.c @@ -314,7 +314,7 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); /* parse options */ if (argc == 0) diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c index d862fd8e7..27884df73 100644 --- a/sys-utils/losetup.c +++ b/sys-utils/losetup.c @@ -642,7 +642,7 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); if (loopcxt_init(&lc, 0)) err(EXIT_FAILURE, _("failed to initialize loopcxt")); diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 0e775805e..4f1ab47e9 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -178,6 +178,11 @@ enum { COL_CACHE_ONESIZE, COL_CACHE_TYPE, COL_CACHE_WAYS, + COL_CACHE_ALLOCPOL, + COL_CACHE_WRITEPOL, + COL_CACHE_PHYLINE, + COL_CACHE_SETS, + COL_CACHE_COHERENCYSIZE }; @@ -215,7 +220,12 @@ static struct lscpu_coldesc coldescs_cache[] = [COL_CACHE_NAME] = { "NAME", N_("cache name") }, [COL_CACHE_ONESIZE] = { "ONE-SIZE", N_("size of one cache"), SCOLS_FL_RIGHT }, [COL_CACHE_TYPE] = { "TYPE", N_("cache type") }, - [COL_CACHE_WAYS] = { "WAYS", N_("ways of associativity"), SCOLS_FL_RIGHT } + [COL_CACHE_WAYS] = { "WAYS", N_("ways of associativity"), SCOLS_FL_RIGHT }, + [COL_CACHE_ALLOCPOL] = { "ALLOC-POLICY", N_("allocation policy") }, + [COL_CACHE_WRITEPOL] = { "WRITE-POLICY", N_("write policy") }, + [COL_CACHE_PHYLINE] = { "PHY-LINE", N_("number of physical cache line per cache t"), SCOLS_FL_RIGHT }, + [COL_CACHE_SETS] = { "SETS", N_("number of sets in the cache; set lines has the same cache index"), SCOLS_FL_RIGHT }, + [COL_CACHE_COHERENCYSIZE] = { "COHERENCY-SIZE", N_("minimum amount of data in bytes transferred from memory to cache"), SCOLS_FL_RIGHT } }; @@ -1354,9 +1364,19 @@ read_cache(struct lscpu_desc *desc, int idx) ca->name = xstrdup(buf); - /* cache ways */ - ul_path_readf_s32(desc->syscpu, &ca->ways, + ul_path_readf_u32(desc->syscpu, &ca->ways_of_associativity, "cpu%d/cache/index%d/ways_of_associativity", num, i); + ul_path_readf_u32(desc->syscpu, &ca->physical_line_partition, + "cpu%d/cache/index%d/physical_line_partition", num, i); + ul_path_readf_u32(desc->syscpu, &ca->number_of_sets, + "cpu%d/cache/index%d/number_of_sets", num, i); + ul_path_readf_u32(desc->syscpu, &ca->coherency_line_size, + "cpu%d/cache/index%d/coherency_line_size", num, i); + + ul_path_readf_string(desc->syscpu, &ca->allocation_policy, + "cpu%d/cache/index%d/allocation_policy", num, i); + ul_path_readf_string(desc->syscpu, &ca->write_policy, + "cpu%d/cache/index%d/write_policy", num, i); /* cache size */ if (ul_path_readf_buffer(desc->syscpu, buf, sizeof(buf), @@ -1682,9 +1702,10 @@ print_caches_readable(struct lscpu_desc *desc, int cols[], int ncols, break; } case COL_CACHE_WAYS: - if (ca->ways) - xasprintf(&data, "%d", ca->ways); + if (ca->ways_of_associativity) + xasprintf(&data, "%u", ca->ways_of_associativity); break; + case COL_CACHE_TYPE: if (ca->type) data = xstrdup(ca->type); @@ -1693,6 +1714,26 @@ print_caches_readable(struct lscpu_desc *desc, int cols[], int ncols, if (ca->level) xasprintf(&data, "%d", ca->level); break; + case COL_CACHE_ALLOCPOL: + if (ca->allocation_policy) + data = xstrdup(ca->allocation_policy); + break; + case COL_CACHE_WRITEPOL: + if (ca->write_policy) + data = xstrdup(ca->write_policy); + break; + case COL_CACHE_PHYLINE: + if (ca->physical_line_partition) + xasprintf(&data, "%u", ca->physical_line_partition); + break; + case COL_CACHE_SETS: + if (ca->number_of_sets) + xasprintf(&data, "%u", ca->number_of_sets); + break; + case COL_CACHE_COHERENCYSIZE: + if (ca->coherency_line_size) + xasprintf(&data, "%u", ca->coherency_line_size); + break; } if (data && scols_line_refer_data(line, c, data)) @@ -2255,7 +2296,7 @@ int main(int argc, char *argv[]) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); while ((c = getopt_long(argc, argv, "aBbC::ce::hJp::s:xyV", longopts, NULL)) != -1) { @@ -2414,6 +2455,9 @@ int main(int argc, char *argv[]) columns[ncolumns++] = COL_CACHE_WAYS; columns[ncolumns++] = COL_CACHE_TYPE; columns[ncolumns++] = COL_CACHE_LEVEL; + columns[ncolumns++] = COL_CACHE_SETS; + columns[ncolumns++] = COL_CACHE_PHYLINE; + columns[ncolumns++] = COL_CACHE_COHERENCYSIZE; } print_caches_readable(desc, columns, ncolumns, mod); break; diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index 56c97e2e8..5bbdb348e 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -49,10 +49,17 @@ enum { struct cpu_cache { char *name; char *type; + char *allocation_policy; + char *write_policy; + int level; - int ways; uint64_t size; + unsigned int ways_of_associativity; + unsigned int physical_line_partition; + unsigned int number_of_sets; + unsigned int coherency_line_size; + int nsharedmaps; cpu_set_t **sharedmaps; }; diff --git a/sys-utils/lsipc.c b/sys-utils/lsipc.c index 5ba9cd7bf..5a1a3d7ac 100644 --- a/sys-utils/lsipc.c +++ b/sys-utils/lsipc.c @@ -1137,7 +1137,7 @@ int main(int argc, char *argv[]) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); ctl->time_mode = 0; diff --git a/text-utils/colrm.c b/text-utils/colrm.c index d0ef2eb66..f9dfd5938 100644 --- a/text-utils/colrm.c +++ b/text-utils/colrm.c @@ -166,7 +166,7 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - atexit(close_stdout); + close_stdout_atexit(); while ((opt = getopt_long(argc, argv, "bfhl:pxVH", longopts, |