summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/closestream.h7
-rw-r--r--libfdisk/docs/libfdisk-sections.txt1
-rw-r--r--libfdisk/src/context.c31
-rw-r--r--libfdisk/src/label.c3
-rw-r--r--libfdisk/src/libfdisk.h.in1
-rw-r--r--libfdisk/src/libfdisk.sym4
-rw-r--r--libfdisk/src/script.c106
-rw-r--r--libfdisk/src/table.c2
-rw-r--r--sys-utils/fsfreeze.c2
-rw-r--r--sys-utils/ldattach.c2
-rw-r--r--sys-utils/losetup.c2
-rw-r--r--sys-utils/lscpu.c56
-rw-r--r--sys-utils/lscpu.h9
-rw-r--r--sys-utils/lsipc.c2
-rw-r--r--text-utils/colrm.c2
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,