return 0;
}
+static const char hwdb_bin_paths[] =
+ "/etc/udev/hwdb.bin\0"
+ UDEVLIBEXECDIR "/hwdb.bin\0";
+
+
/**
* udev_hwdb_new:
* @udev: udev library context
**/
_public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
struct udev_hwdb *hwdb;
+ const char *hwdb_bin_path;
const char sig[] = HWDB_SIG;
hwdb = new0(struct udev_hwdb, 1);
hwdb->refcount = 1;
udev_list_init(udev, &hwdb->properties_list, true);
- hwdb->f = fopen("/etc/udev/hwdb.bin", "re");
+ /* find hwdb.bin in hwdb_bin_paths */
+ NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) {
+ hwdb->f = fopen(hwdb_bin_path, "re");
+ if (hwdb->f)
+ break;
+ else if (errno == ENOENT)
+ continue;
+ else {
+ log_debug_errno(errno, "error reading %s: %m", hwdb_bin_path);
+ udev_hwdb_unref(hwdb);
+ return NULL;
+ }
+ }
+
if (!hwdb->f) {
- udev_dbg(udev, "error reading /etc/udev/hwdb.bin: %m");
+ log_debug("hwdb.bin does not exist, please run udevadm hwdb --update");
udev_hwdb_unref(hwdb);
return NULL;
}
if (fstat(fileno(hwdb->f), &hwdb->st) < 0 ||
(size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8) {
- udev_dbg(udev, "error reading /etc/udev/hwdb.bin: %m");
+ log_debug_errno(errno, "error reading %s: %m", hwdb_bin_path);
udev_hwdb_unref(hwdb);
return NULL;
}
hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
if (hwdb->map == MAP_FAILED) {
- udev_dbg(udev, "error mapping /etc/udev/hwdb.bin: %m");
+ log_debug_errno(errno, "error mapping %s: %m", hwdb_bin_path);
udev_hwdb_unref(hwdb);
return NULL;
}
if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
(size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
- udev_dbg(udev, "error recognizing the format of /etc/udev/hwdb.bin");
+ log_debug("error recognizing the format of %s", hwdb_bin_path);
udev_hwdb_unref(hwdb);
return NULL;
}
- udev_dbg(udev, "=== trie on-disk ===\n");
- udev_dbg(udev, "tool version: %"PRIu64, le64toh(hwdb->head->tool_version));
- udev_dbg(udev, "file size: %8"PRIu64" bytes\n", hwdb->st.st_size);
- udev_dbg(udev, "header size %8"PRIu64" bytes\n", le64toh(hwdb->head->header_size));
- udev_dbg(udev, "strings %8"PRIu64" bytes\n", le64toh(hwdb->head->strings_len));
- udev_dbg(udev, "nodes %8"PRIu64" bytes\n", le64toh(hwdb->head->nodes_len));
+ log_debug("=== trie on-disk ===");
+ log_debug("tool version: %"PRIu64, le64toh(hwdb->head->tool_version));
+ log_debug("file size: %8"PRIu64" bytes", hwdb->st.st_size);
+ log_debug("header size %8"PRIu64" bytes", le64toh(hwdb->head->header_size));
+ log_debug("strings %8"PRIu64" bytes", le64toh(hwdb->head->strings_len));
+ log_debug("nodes %8"PRIu64" bytes", le64toh(hwdb->head->nodes_len));
return hwdb;
}
}
bool udev_hwdb_validate(struct udev_hwdb *hwdb) {
+ bool found = false;
+ const char* p;
struct stat st;
if (!hwdb)
return false;
if (!hwdb->f)
return false;
- if (stat("/etc/udev/hwdb.bin", &st) < 0)
+
+ /* if hwdb.bin doesn't exist anywhere, we need to update */
+ NULSTR_FOREACH(p, hwdb_bin_paths) {
+ if (stat(p, &st) >= 0) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
return true;
+
if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim))
return true;
return false;