From: Kay Sievers Date: Sat, 17 Mar 2007 09:08:25 +0000 (+0100) Subject: read list of devices from index, make index private to database X-Git-Tag: 174~2030 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=31de3a2ba18ffa011f5054016ccc4a500cbe0cc3 read list of devices from index, make index private to database --- diff --git a/test-udev.c b/test-udev.c index e40a44843..ba3601591 100644 --- a/test-udev.c +++ b/test-udev.c @@ -136,7 +136,7 @@ int main(int argc, char *argv[], char *envp[]) goto fail; } - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) goto fail; diff --git a/udev.h b/udev.h index 31542243e..16a107a33 100644 --- a/udev.h +++ b/udev.h @@ -99,7 +99,7 @@ extern int udev_run; extern void udev_config_init(void); /* udev_device.c */ -extern struct udevice *udev_device_init(void); +extern struct udevice *udev_device_init(struct udevice *udev); extern void udev_device_cleanup(struct udevice *udev); extern int udev_device_event(struct udev_rules *rules, struct udevice *udev); extern dev_t udev_device_get_devt(struct udevice *udev); @@ -127,6 +127,7 @@ extern int udev_db_add_device(struct udevice *dev); extern int udev_db_delete_device(struct udevice *dev); extern int udev_db_get_device(struct udevice *udev, const char *devpath); extern int udev_db_lookup_name(const char *name, char *devpath, size_t len); +extern int udev_db_get_devices_by_name(const char *name, struct list_head *name_list); extern int udev_db_get_all_entries(struct list_head *name_list); /* udev_utils.c */ diff --git a/udev_db.c b/udev_db.c index 40082abf0..8c9e474ad 100644 --- a/udev_db.c +++ b/udev_db.c @@ -77,6 +77,46 @@ static int name_index(const char *devpath, const char *name, int add) return 0; } +int udev_db_get_devices_by_name(const char *name, struct list_head *name_list) +{ + char dirname[PATH_MAX]; + size_t start; + DIR *dir; + int rc = 0; + + strlcpy(dirname, udev_root, sizeof(dirname)); + start = strlcat(dirname, "/"DB_NAME_INDEX_DIR"/", sizeof(dirname)); + strlcat(dirname, name, sizeof(dirname)); + path_encode(&dirname[start], sizeof(dirname) - start); + + dir = opendir(dirname); + if (dir == NULL) { + info("no index directory '%s': %s", dirname, strerror(errno)); + rc = -1; + goto out; + } + + info("found index directory '%s'", dirname); + while (1) { + struct dirent *ent; + char device[PATH_SIZE]; + + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + if (ent->d_name[0] == '.') + continue; + + strlcpy(device, ent->d_name, sizeof(device)); + path_decode(device); + name_list_add(name_list, device, 0); + rc++; + } + closedir(dir); +out: + return rc; +} + int udev_db_add_device(struct udevice *udev) { char filename[PATH_SIZE]; @@ -288,7 +328,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) strlcpy(device, ent->d_name, sizeof(device)); path_decode(device); - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) break; if (udev_db_get_device(udev, device) == 0) { diff --git a/udev_device.c b/udev_device.c index daf94a577..4cd5526de 100644 --- a/udev_device.c +++ b/udev_device.c @@ -33,11 +33,10 @@ #include "udev_rules.h" -struct udevice *udev_device_init(void) +struct udevice *udev_device_init(struct udevice *udev) { - struct udevice *udev; - - udev = malloc(sizeof(struct udevice)); + if (udev == NULL) + udev = malloc(sizeof(struct udevice)); if (udev == NULL) return NULL; memset(udev, 0x00, sizeof(struct udevice)); @@ -162,8 +161,8 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) goto exit; } - /* read current database entry, we may need to cleanup */ - udev_old = udev_device_init(); + /* read current database entry; cleanup, if it is known device */ + udev_old = udev_device_init(NULL); if (udev_old != NULL) { if (udev_db_get_device(udev_old, udev->dev->devpath) == 0) { info("device '%s' already in database, cleanup", udev->dev->devpath); @@ -241,7 +240,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) if (major(udev->devt) != 0 && strcmp(udev->action, "remove") == 0) { struct name_entry *name_loop; - /* import and delete database entry */ + /* import database entry, and delete it */ if (udev_db_get_device(udev, udev->dev->devpath) == 0) { udev_db_delete_device(udev); if (udev->ignore_remove) { diff --git a/udev_node.c b/udev_node.c index ed323e944..1558df849 100644 --- a/udev_node.c +++ b/udev_node.c @@ -275,7 +275,7 @@ void udev_node_remove_symlinks(struct udevice *udev) struct udevice *old; info("found overwritten symlink '%s' of '%s'", name_loop->name, devpath); - old = udev_device_init(); + old = udev_device_init(NULL); if (old != NULL) { if (udev_db_get_device(old, devpath) == 0) { char slink[PATH_SIZE]; diff --git a/udev_rules.c b/udev_rules.c index c0f4cd207..ea02b8e94 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -236,7 +236,7 @@ static int import_parent_into_env(struct udevice *udev, const char *filter) struct name_entry *name_loop; dbg("found parent '%s', get the node name", dev_parent->devpath); - udev_parent = udev_device_init(); + udev_parent = udev_device_init(NULL); if (udev_parent == NULL) return -1; /* import the udev_db of the parent */ @@ -518,7 +518,7 @@ found: struct udevice *udev_parent; dbg("found parent '%s', get the node name", dev_parent->devpath); - udev_parent = udev_device_init(); + udev_parent = udev_device_init(NULL); if (udev_parent != NULL) { /* lookup the name in the udev_db with the DEVPATH of the parent */ if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) { diff --git a/udevd.c b/udevd.c index 4aad165d8..8f3329ea6 100644 --- a/udevd.c +++ b/udevd.c @@ -124,7 +124,7 @@ static int udev_event_process(struct udevd_uevent_msg *msg) for (i = 0; msg->envp[i]; i++) putenv(msg->envp[i]); - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) return -1; strlcpy(udev->action, msg->action, sizeof(udev->action)); diff --git a/udevinfo.c b/udevinfo.c index 3f47add87..e892b1092 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -167,7 +167,7 @@ static void export_db(void fnct(struct udevice *udev)) { list_for_each_entry(name_loop, &name_list, node) { struct udevice *udev_db; - udev_db = udev_device_init(); + udev_db = udev_device_init(NULL); if (udev_db == NULL) continue; if (udev_db_get_device(udev_db, name_loop->name) == 0) @@ -177,6 +177,41 @@ static void export_db(void fnct(struct udevice *udev)) { name_list_cleanup(&name_list); } +static int lookup_device_by_name(struct udevice *udev, const char *name) +{ + LIST_HEAD(name_list); + struct name_entry *device; + int rc = -1; + + if (udev_db_get_devices_by_name(name, &name_list) <= 0) + goto out; + + /* select the device that matches the dev_t of name */ + list_for_each_entry(device, &name_list, node) { + char filename[PATH_SIZE]; + struct stat statbuf; + + udev_device_init(udev); + if (udev_db_get_device(udev, device->name) != 0) + continue; + info("found db entry '%s'", device->name); + + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + strlcat(filename, name, sizeof(filename)); + if (stat(filename, &statbuf) != 0) + continue; + if (statbuf.st_rdev == udev->devt) { + info("found '%s', dev_t matches", udev->name); + rc = 0; + break; + } + } +out: + name_list_cleanup(&name_list); + return rc; +} + int main(int argc, char *argv[], char *envp[]) { int option; @@ -220,7 +255,7 @@ int main(int argc, char *argv[], char *envp[]) udev_config_init(); sysfs_init(); - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) { rc = 1; goto exit; @@ -330,14 +365,11 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } } else if (name[0] != '\0') { - char devpath[PATH_SIZE]; - - if (udev_db_lookup_name(name, devpath, sizeof(devpath)) != 0) { + if (lookup_device_by_name(udev, name) != 0) { fprintf(stderr, "node name not found\n"); rc = 4; goto exit; } - udev_db_get_device(udev, devpath); } else { fprintf(stderr, "query needs --path or node --name specified\n"); rc = 4; @@ -385,14 +417,12 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } } else if (name[0] != '\0') { - char devpath[PATH_SIZE]; - - if (udev_db_lookup_name(name, devpath, sizeof(devpath)) != 0) { + if (lookup_device_by_name(udev, name) != 0) { fprintf(stderr, "node name not found\n"); rc = 4; goto exit; } - if (print_device_chain(devpath) != 0) { + if (print_device_chain(udev->dev->devpath) != 0) { fprintf(stderr, "device not found\n"); rc = 4; goto exit; diff --git a/udevstart.c b/udevstart.c index 6ea18272e..a381c411a 100644 --- a/udevstart.c +++ b/udevstart.c @@ -120,7 +120,7 @@ static int add_device(const char *devpath) if (dev == NULL) return -1; - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) return -1; diff --git a/udevtest.c b/udevtest.c index 73bf7dd1f..bb889a70f 100644 --- a/udevtest.c +++ b/udevtest.c @@ -97,7 +97,7 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - udev = udev_device_init(); + udev = udev_device_init(NULL); if (udev == NULL) { fprintf(stderr, "error initializing device\n"); rc = 3;