summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2013-02-07 13:53:28 +0100
committerLuca Barbato <lu_zero@gentoo.org>2013-02-07 13:53:28 +0100
commit96da532526fec9bbfc9f53f2c5819520b971710c (patch)
tree9b23bd0f28bd285b1bb8355187c43c0325019f4a /src
parent94d7639cf2435a92672c6043e8e0333452c24c80 (diff)
udevadm: support updating hwdb from an offset root
Introduce `--root` option to make users run udevadm on rootfs not mounted as / Ease the life of distribution packagers.
Diffstat (limited to 'src')
-rw-r--r--src/libudev/conf-files.c34
-rw-r--r--src/libudev/conf-files.h10
-rw-r--r--src/udev/udev-rules.c2
-rw-r--r--src/udev/udevadm-hwdb.c32
4 files changed, 62 insertions, 16 deletions
diff --git a/src/libudev/conf-files.c b/src/libudev/conf-files.c
index 34b86293d3..8e8edd0b9c 100644
--- a/src/libudev/conf-files.c
+++ b/src/libudev/conf-files.c
@@ -37,11 +37,27 @@
#include "hashmap.h"
#include "conf-files.h"
-static int files_add(Hashmap *h, const char *path, const char *suffix) {
+static int files_add(Hashmap *h,
+ const char *prefix,
+ const char *path,
+ const char *suffix) {
DIR *dir;
int r = 0;
- dir = opendir(path);
+ if (prefix) {
+ char *p = NULL;
+
+ if (asprintf(&p, "%s/%s", prefix, path) < 0) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ dir = opendir(p);
+ free(p);
+ } else {
+ dir = opendir(path);
+ }
+
if (!dir) {
if (errno == ENOENT)
return 0;
@@ -90,7 +106,10 @@ static int base_cmp(const void *a, const void *b) {
return strcmp(path_get_file_name(s1), path_get_file_name(s2));
}
-int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
+int conf_files_list_strv(char ***strv,
+ const char *prefix,
+ const char *suffix,
+ const char **dirs) {
Hashmap *fh = NULL;
char **files = NULL;
const char **p;
@@ -105,7 +124,7 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs) {
}
STRV_FOREACH(p, dirs) {
- r = files_add(fh, *p, suffix);
+ r = files_add(fh, prefix, *p, suffix);
if (r < 0)
log_warning("Failed to search for files in %s: %s",
*p, strerror(-r));
@@ -126,7 +145,10 @@ finish:
return r;
}
-int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
+int conf_files_list(char ***strv,
+ const char *prefix,
+ const char *suffix,
+ const char *dir, ...) {
char **dirs = NULL;
va_list ap;
int r;
@@ -145,7 +167,7 @@ int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) {
}
strv_uniq(dirs);
- r = conf_files_list_strv(strv, suffix, (const char **)dirs);
+ r = conf_files_list_strv(strv, prefix, suffix, (const char **)dirs);
finish:
strv_free(dirs);
diff --git a/src/libudev/conf-files.h b/src/libudev/conf-files.h
index f37ee1f3db..c2c59dc972 100644
--- a/src/libudev/conf-files.h
+++ b/src/libudev/conf-files.h
@@ -25,7 +25,13 @@
#include "macro.h"
-int conf_files_list(char ***strv, const char *suffix, const char *dir, ...);
-int conf_files_list_strv(char ***strv, const char *suffix, const char **dirs);
+int conf_files_list(char ***strv,
+ const char *prefix,
+ const char *suffix,
+ const char *dir, ...);
+int conf_files_list_strv(char ***strv,
+ const char *prefix,
+ const char *suffix,
+ const char **dirs);
#endif
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index ab755210ba..0fcad5d7e9 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1639,7 +1639,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
return udev_rules_unref(rules);
udev_rules_check_timestamp(rules);
- r = conf_files_list_strv(&files, ".rules", (const char **)rules->dirs);
+ r = conf_files_list_strv(&files, NULL, ".rules", (const char **)rules->dirs);
if (r < 0) {
log_error("failed to enumerate rules files: %s\n", strerror(-r));
return udev_rules_unref(rules);
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 279e9255f0..917d1e0eaf 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -474,7 +474,7 @@ static int import_file(struct trie *trie, const char *filename) {
}
static void help(void) {
- printf("Usage: udevadm hwdb [--create] [--help]\n"
+ printf("Usage: udevadm hwdb [--create] [--help] [--root <root_path>]\n"
" --update update the hardware database\n"
" --test <modalias> query database and print result\n"
" --help\n\n");
@@ -483,11 +483,13 @@ static void help(void) {
static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
static const struct option options[] = {
{ "update", no_argument, NULL, 'u' },
+ { "root", required_argument, NULL, 'r' },
{ "test", required_argument, NULL, 't' },
{ "help", no_argument, NULL, 'h' },
{}
};
- const char *test = NULL;
+ const char *test = NULL, *root_path = NULL;
+ char *udev_hwdb_path = UDEV_HWDB_BIN;
bool update = false;
struct trie *trie = NULL;
int err;
@@ -496,7 +498,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
for (;;) {
int option;
- option = getopt_long(argc, argv, "ut:h", options, NULL);
+ option = getopt_long(argc, argv, "ut:r:h", options, NULL);
if (option == -1)
break;
@@ -507,6 +509,9 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
case 't':
test = optarg;
break;
+ case 'r':
+ root_path = optarg;
+ break;
case 'h':
help();
return EXIT_SUCCESS;
@@ -542,7 +547,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
}
trie->nodes_count++;
- err = conf_files_list_strv(&files, ".hwdb", (const char **)conf_file_dirs);
+ err = conf_files_list_strv(&files, root_path, ".hwdb", (const char **)conf_file_dirs);
if (err < 0) {
log_error("failed to enumerate hwdb files: %s\n", strerror(-err));
rc = EXIT_FAILURE;
@@ -570,11 +575,24 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
log_debug("strings dedup'ed: %8zu bytes (%8zu)\n",
trie->strings->dedup_len, trie->strings->dedup_count);
- mkdir_parents(UDEV_HWDB_BIN, 0755);
- err = trie_store(trie, UDEV_HWDB_BIN);
+ if (root_path) {
+ if (asprintf(&udev_hwdb_path,
+ "%s/%s", root_path, udev_hwdb_path) < 0) {
+ rc = EXIT_FAILURE;
+ goto out;
+ }
+ }
+
+ mkdir_parents(udev_hwdb_path, 0755);
+ err = trie_store(trie, udev_hwdb_path);
+
+ if (root_path) {
+ free(udev_hwdb_path);
+ }
+
if (err < 0) {
log_error("Failure writing hardware database '%s': %s",
- UDEV_HWDB_BIN, strerror(-err));
+ udev_hwdb_path, strerror(-err));
rc = EXIT_FAILURE;
}
}