summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/pathnames.h3
-rw-r--r--libmount/src/mountP.h2
-rw-r--r--libmount/src/utils.c91
-rw-r--r--tests/expected/libmount/utils-kernel-cmdline5
-rw-r--r--tests/ts/libmount/files/kernel_cmdline1
-rwxr-xr-xtests/ts/libmount/utils9
6 files changed, 111 insertions, 0 deletions
diff --git a/include/pathnames.h b/include/pathnames.h
index 58bba519a..a7f33fed5 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -152,5 +152,8 @@
/* wdctl path */
#define _PATH_WATCHDOG_DEV "/dev/watchdog"
+/* kernel command line */
+#define _PATH_PROC_CMDLINE "/proc/cmdline"
+
#endif /* PATHNAMES_H */
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
index bbaa2c6c4..f28935d0d 100644
--- a/libmount/src/mountP.h
+++ b/libmount/src/mountP.h
@@ -147,6 +147,8 @@ extern const char *mnt_get_utab_path(void);
extern int mnt_get_filesystems(char ***filesystems, const char *pattern);
extern void mnt_free_filesystems(char **filesystems);
+extern char *mnt_get_kernel_cmdline_option(const char *name);
+
/* tab.c */
extern int mnt_table_set_parser_fltrcb( struct libmnt_table *tb,
int (*cb)(struct libmnt_fs *, void *),
diff --git a/libmount/src/utils.c b/libmount/src/utils.c
index 0cfefb347..624633dd8 100644
--- a/libmount/src/utils.c
+++ b/libmount/src/utils.c
@@ -881,6 +881,78 @@ char *mnt_get_fs_root(const char *path, const char *mnt)
return res;
}
+/*
+ * Search for @name kernel command parametr.
+ *
+ * Returns newly allocated string with parameter argument if the @name is
+ * specified as "name=" or returns pointer to @name or returns NULL if not
+ * found.
+ *
+ * For example cmdline: "aaa bbb=BBB ccc"
+ *
+ * @name is "aaa" --returns--> "aaa" (pointer to @name)
+ * @name is "bbb=" --returns--> "BBB" (allocated)
+ * @name is "foo" --returns--> NULL
+ */
+char *mnt_get_kernel_cmdline_option(const char *name)
+{
+ FILE *f;
+ size_t len;
+ int val = 0;
+ char *p, *res = NULL;
+ char buf[BUFSIZ]; /* see kernel include/asm-generic/setup.h: COMMAND_LINE_SIZE */
+ const char *path = _PATH_PROC_CMDLINE;
+
+ assert(name);
+ assert(*name);
+
+#ifdef TEST_PROGRAM
+ path = safe_getenv("LIBMOUNT_KERNEL_CMDLINE");
+ if (!path)
+ path = _PATH_PROC_CMDLINE;
+#endif
+ f = fopen(path, "r");
+ if (!f)
+ return NULL;
+
+ p = fgets(buf, sizeof(buf), f);
+ fclose(f);
+
+ if (!p || !*p || *p == '\n')
+ return NULL;
+
+ len = strlen(buf);
+ *(buf + len - 1) = '\0'; /* remove last '\n' */
+
+ len = strlen(name);
+ if (len && *(name + len - 1) == '=')
+ val = 1;
+
+ while (p && *p) {
+ if (p != buf)
+ p++;
+ if (!(p = strstr(p, name)))
+ break; /* not found the option */
+ if (p != buf && !isblank(*(p - 1)))
+ continue; /* no space before the option */
+ if (!val && *(p + len) != '\0' && !isblank(*(p + len)))
+ continue; /* no space behind the option */
+ if (val) {
+ char *v = p + len;
+
+ while (*p && !isblank(*p)) /* jump to the end of the argument */
+ p++;
+ *p = '\0';
+ res = strdup(v);
+ break;
+ } else
+ res = (char *) name; /* option without '=' */
+ break;
+ }
+
+ return res;
+}
+
#ifdef TEST_PROGRAM
int test_match_fstype(struct libmnt_test *ts, int argc, char *argv[])
{
@@ -974,6 +1046,24 @@ int test_chdir(struct libmnt_test *ts, int argc, char *argv[])
return rc;
}
+int test_kernel_cmdline(struct libmnt_test *ts, int argc, char *argv[])
+{
+ char *name = argv[1];
+ char *res;
+
+ res = mnt_get_kernel_cmdline_option(name);
+ if (!res)
+ printf("'%s' not found\n", name);
+ else if (res == name)
+ printf("'%s' found\n", name);
+ else {
+ printf("'%s' found, argument: '%s'\n", name, res);
+ free(res);
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
@@ -986,6 +1076,7 @@ int main(int argc, char *argv[])
{ "--mountpoint", test_mountpoint, "<path>" },
{ "--fs-root", test_fsroot, "<path>" },
{ "--cd-parent", test_chdir, "<path>" },
+ { "--kernel-cmdline",test_kernel_cmdline, "<option> | <option>=" },
{ NULL }
};
diff --git a/tests/expected/libmount/utils-kernel-cmdline b/tests/expected/libmount/utils-kernel-cmdline
new file mode 100644
index 000000000..2a6316583
--- /dev/null
+++ b/tests/expected/libmount/utils-kernel-cmdline
@@ -0,0 +1,5 @@
+'selinux=' found, argument: '0'
+'selinux' not found
+'ro' found
+'ro=' not found
+'root=' found, argument: 'UUID=33230ae2-1093-4353-824c-f7ca09a2a882'
diff --git a/tests/ts/libmount/files/kernel_cmdline b/tests/ts/libmount/files/kernel_cmdline
new file mode 100644
index 000000000..37a0c89e9
--- /dev/null
+++ b/tests/ts/libmount/files/kernel_cmdline
@@ -0,0 +1 @@
+rd.md=0 rd.lvm=0 rd.dm=0 KEYTABLE=us root=UUID=33230ae2-1093-4353-824c-f7ca09a2a882 rd.luks=0 SYSFONT=latarcyrheb-sun16 ro LANG=en_US.UTF-8 selinux=0
diff --git a/tests/ts/libmount/utils b/tests/ts/libmount/utils
index d425400ad..6facaad10 100755
--- a/tests/ts/libmount/utils
+++ b/tests/ts/libmount/utils
@@ -76,4 +76,13 @@ ts_init_subtest "fs-root-subdir2"
ts_valgrind $TESTPROG --fs-root /etc &> $TS_OUTPUT
ts_finalize_subtest
+ts_init_subtest "kernel-cmdline"
+export LIBMOUNT_KERNEL_CMDLINE="$TS_SELF/files/kernel_cmdline"
+ts_valgrind $TESTPROG --kernel-cmdline selinux= &>> $TS_OUTPUT
+ts_valgrind $TESTPROG --kernel-cmdline selinux &>> $TS_OUTPUT
+ts_valgrind $TESTPROG --kernel-cmdline ro &>> $TS_OUTPUT
+ts_valgrind $TESTPROG --kernel-cmdline ro= &>> $TS_OUTPUT
+ts_valgrind $TESTPROG --kernel-cmdline root= &>> $TS_OUTPUT
+ts_finalize_subtest
+
ts_finalize