summaryrefslogtreecommitdiffstats
path: root/libmount
diff options
context:
space:
mode:
authorKarel Zak2012-08-01 17:51:43 +0200
committerKarel Zak2012-08-01 17:51:43 +0200
commit6870636c7f144038de8262a66d658abaafd51eaf (patch)
tree62046bfa1c26db95a83c8f7a97fc5fc1ee0ec670 /libmount
parenttests: standardize fdisk headers in MBR tests (diff)
downloadkernel-qcow2-util-linux-6870636c7f144038de8262a66d658abaafd51eaf.tar.gz
kernel-qcow2-util-linux-6870636c7f144038de8262a66d658abaafd51eaf.tar.xz
kernel-qcow2-util-linux-6870636c7f144038de8262a66d658abaafd51eaf.zip
libmount: add mnt_optstr_deduplicate_option()
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount')
-rw-r--r--libmount/docs/libmount-sections.txt1
-rw-r--r--libmount/src/libmount.h.in2
-rw-r--r--libmount/src/libmount.sym19
-rw-r--r--libmount/src/optstr.c61
4 files changed, 74 insertions, 9 deletions
diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt
index dc6aeabf5..e0f899471 100644
--- a/libmount/docs/libmount-sections.txt
+++ b/libmount/docs/libmount-sections.txt
@@ -250,6 +250,7 @@ MNT_NOHLPS
<FILE>optstr</FILE>
mnt_optstr_append_option
mnt_optstr_apply_flags
+mnt_optstr_deduplicate_option
mnt_optstr_get_flags
mnt_optstr_get_option
mnt_optstr_get_options
diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in
index 326588fec..43646ac8a 100644
--- a/libmount/src/libmount.h.in
+++ b/libmount/src/libmount.h.in
@@ -183,6 +183,7 @@ extern int mnt_optstr_get_option(const char *optstr, const char *name,
extern int mnt_optstr_set_option(char **optstr, const char *name,
const char *value);
extern int mnt_optstr_remove_option(char **optstr, const char *name);
+extern int mnt_optstr_deduplicate_option(char **optstr, const char *name);
extern int mnt_split_optstr(const char *optstr,
char **user, char **vfs, char **fs,
@@ -196,6 +197,7 @@ extern int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
extern int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
const struct libmnt_optmap *map);
+
/* iter.c */
enum {
diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym
index 260642d4d..9e0f2c45d 100644
--- a/libmount/src/libmount.sym
+++ b/libmount/src/libmount.sym
@@ -228,22 +228,23 @@ global:
MOUNT_2.22 {
global:
- mnt_fs_streq_target;
- mnt_fs_streq_srcpath;
- mnt_context_tab_applied;
+ mnt_context_disable_swapmatch;
mnt_context_get_options;
mnt_context_is_loopdel;
mnt_context_is_nocanonicalize;
mnt_context_is_nohelpers;
- mnt_table_find_devno;
- mnt_table_parse_swaps;
- mnt_get_mountpoint;
- mnt_get_swaps_path;
+ mnt_context_is_swapmatch;
+ mnt_context_tab_applied;
mnt_fs_get_priority;
mnt_fs_get_size;
mnt_fs_get_swaptype;
mnt_fs_get_tid;
mnt_fs_get_usedsize;
- mnt_context_is_swapmatch;
- mnt_context_disable_swapmatch;
+ mnt_fs_streq_srcpath;
+ mnt_fs_streq_target;
+ mnt_get_mountpoint;
+ mnt_get_swaps_path;
+ mnt_optstr_deduplicate_option;
+ mnt_table_find_devno;
+ mnt_table_parse_swaps;
} MOUNT_2.21;
diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c
index 08c12150e..16d6d13a2 100644
--- a/libmount/src/optstr.c
+++ b/libmount/src/optstr.c
@@ -290,6 +290,48 @@ int mnt_optstr_get_option(const char *optstr, const char *name,
return rc;
}
+/**
+ * mnt_optstr_deduplicate_option:
+ * @optstr: string with comma separated list of options
+ * @name: requested option name
+ *
+ * Removes all instances of @name except the last one.
+ *
+ * Returns: 0 on success, 1 when not found the @name or negative number in case
+ * of error.
+ */
+int mnt_optstr_deduplicate_option(char **optstr, const char *name)
+{
+ int rc;
+ char *begin = NULL, *end = NULL, *opt = *optstr;
+
+ do {
+ struct libmnt_optloc ol;
+
+ mnt_init_optloc(&ol);
+
+ rc = mnt_optstr_locate_option(opt, name, &ol);
+ if (!rc) {
+ if (begin) {
+ /* remove previous instance */
+ size_t shift = strlen(*optstr);
+
+ mnt_optstr_remove_option_at(optstr, begin, end);
+
+ /* now all offset are not valied anymore - recount */
+ shift -= strlen(*optstr);
+ ol.begin -= shift;
+ ol.end -= shift;
+ }
+ begin = ol.begin;
+ end = ol.end;
+ opt = end && *end ? end + 1 : NULL;
+ }
+ } while (rc == 0 && opt && *opt);
+
+ return rc < 0 ? rc : begin ? 0 : 1;
+}
+
/*
* The result never starts or ends with comma or contains two commas
* (e.g. ",aaa,bbb" or "aaa,,bbb" or "aaa,")
@@ -1187,6 +1229,24 @@ int test_remove(struct libmnt_test *ts, int argc, char *argv[])
return rc;
}
+int test_dedup(struct libmnt_test *ts, int argc, char *argv[])
+{
+ const char *name;
+ char *optstr;
+ int rc;
+
+ if (argc < 3)
+ return -EINVAL;
+ optstr = strdup(argv[1]);
+ name = argv[2];
+
+ rc = mnt_optstr_deduplicate_option(&optstr, name);
+ if (!rc)
+ printf("result: >%s<\n", optstr);
+ free(optstr);
+ return rc;
+}
+
int test_fix(struct libmnt_test *ts, int argc, char *argv[])
{
char *optstr;
@@ -1230,6 +1290,7 @@ int main(int argc, char *argv[])
{ "--set", test_set, "<optstr> <name> [<value>] (un)set value" },
{ "--get", test_get, "<optstr> <name> search name in optstr" },
{ "--remove", test_remove, "<optstr> <name> remove name in optstr" },
+ { "--dedup", test_dedup, "<optstr> <name> deduplicate name in optstr" },
{ "--split", test_split, "<optstr> split into FS, VFS and userspace" },
{ "--flags", test_flags, "<optstr> convert options to MS_* flags" },
{ "--apply", test_apply, "--{linux,user} <optstr> <mask> apply mask to optstr" },