From: Kay Sievers Date: Fri, 26 Sep 2008 17:43:32 +0000 (+0200) Subject: libudev: device - read database only when needed X-Git-Tag: 174~1528 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=9921484458e0233e1aae868bfa8cc1481aa460a8;p=elogind.git libudev: device - read database only when needed --- diff --git a/TODO b/TODO index b61b75240..5c8cdc379 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,6 @@ o enumerate() - add buses and drivers o increase ressize buffer - o lazy loading of "uevent" and db - o lazy init of selinux - o add DVB variables to kernel, and drop shell script rule o add watershed extra o replace list.h with ccan list.h which is gpl-v2-or-later version diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index 6c6b1d387..de4bd48e1 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -37,11 +37,12 @@ struct udev_device { char *syspath; const char *devpath; const char *sysname; - char *devname; + char *devnode; char *subsystem; - struct list_head link_list; + struct list_head devlink_list; struct list_head properties_list; char *action; + int event_timeout; char *driver; char *devpath_old; char *physdevpath; @@ -52,6 +53,7 @@ struct udev_device { int devlink_priority; int ignore_remove; struct list_head attr_list; + int info_loaded; }; static size_t syspath_to_db_path(struct udev_device *udev_device, char *filename, size_t len) @@ -65,42 +67,6 @@ static size_t syspath_to_db_path(struct udev_device *udev_device, char *filename return util_path_encode(&filename[start], len - start); } -static int device_read_uevent_file(struct udev_device *udev_device) -{ - char filename[UTIL_PATH_SIZE]; - FILE *f; - char line[UTIL_LINE_SIZE]; - int maj = 0; - int min = 0; - - util_strlcpy(filename, udev_device->syspath, sizeof(filename)); - util_strlcat(filename, "/uevent", sizeof(filename)); - f = fopen(filename, "r"); - if (f == NULL) - return -1; - - while (fgets(line, sizeof(line), f)) { - char *pos; - - pos = strchr(line, '\n'); - if (pos == NULL) - continue; - pos[0] = '\0'; - - if (strncmp(line, "MAJOR=", 6) == 0) - maj = strtoull(&line[6], NULL, 10); - else if (strncmp(line, "MINOR=", 6) == 0) - min = strtoull(&line[6], NULL, 10); - - device_add_property_from_string(udev_device, line); - } - - udev_device->devnum = makedev(maj, min); - - fclose(f); - return 0; -} - static int device_read_db(struct udev_device *udev_device) { struct stat stats; @@ -125,9 +91,9 @@ static int device_read_db(struct udev_device *udev_device) info(udev_device->udev, "error reading db link %s: %s\n", filename, strerror(errno)); return -1; } - if (asprintf(&udev_device->devname, "%s/%s", udev_get_dev_path(udev_device->udev), target) < 0) + if (asprintf(&udev_device->devnode, "%s/%s", udev_get_dev_path(udev_device->udev), target) < 0) return -ENOMEM; - info(udev_device->udev, "device %p filled with db symlink data '%s'\n", udev_device, udev_device->devname); + info(udev_device->udev, "device %p filled with db symlink data '%s'\n", udev_device, udev_device->devnode); return 0; } @@ -148,7 +114,7 @@ static int device_read_db(struct udev_device *udev_device) switch(line[0]) { case 'N': - asprintf(&udev_device->devname, "%s/%s", udev_get_dev_path(udev_device->udev), val); + asprintf(&udev_device->devnode, "%s/%s", udev_get_dev_path(udev_device->udev), val); break; case 'S': util_strlcpy(filename, udev_get_dev_path(udev_device->udev), sizeof(filename)); @@ -160,7 +126,7 @@ static int device_read_db(struct udev_device *udev_device) device_set_devlink_priority(udev_device, atoi(val)); break; case 'T': - device_set_timeout(udev_device, atoi(val)); + device_set_event_timeout(udev_device, atoi(val)); break; case 'A': device_set_num_fake_partitions(udev_device, atoi(val)); @@ -179,6 +145,54 @@ static int device_read_db(struct udev_device *udev_device) return 0; } +static int device_read_uevent_file(struct udev_device *udev_device) +{ + char filename[UTIL_PATH_SIZE]; + FILE *f; + char line[UTIL_LINE_SIZE]; + int maj = 0; + int min = 0; + + util_strlcpy(filename, udev_device->syspath, sizeof(filename)); + util_strlcat(filename, "/uevent", sizeof(filename)); + f = fopen(filename, "r"); + if (f == NULL) + return -1; + + while (fgets(line, sizeof(line), f)) { + char *pos; + + pos = strchr(line, '\n'); + if (pos == NULL) + continue; + pos[0] = '\0'; + + if (strncmp(line, "MAJOR=", 6) == 0) + maj = strtoull(&line[6], NULL, 10); + else if (strncmp(line, "MINOR=", 6) == 0) + min = strtoull(&line[6], NULL, 10); + + device_add_property_from_string(udev_device, line); + } + + udev_device->devnum = makedev(maj, min); + + fclose(f); + return 0; +} + +static void device_load_info(struct udev_device *device) +{ + device_read_uevent_file(device); + device_read_db(device); + device->info_loaded = 1; +} + +void device_set_info_loaded(struct udev_device *device) +{ + device->info_loaded = 1; +} + struct udev_device *device_init(struct udev *udev) { struct udev_device *udev_device; @@ -192,7 +206,7 @@ struct udev_device *device_init(struct udev *udev) memset(udev_device, 0x00, sizeof(struct udev_device)); udev_device->refcount = 1; udev_device->udev = udev; - INIT_LIST_HEAD(&udev_device->link_list); + INIT_LIST_HEAD(&udev_device->devlink_list); INIT_LIST_HEAD(&udev_device->properties_list); INIT_LIST_HEAD(&udev_device->attr_list); info(udev_device->udev, "udev_device: %p created\n", udev_device); @@ -241,8 +255,6 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * device_set_syspath(udev_device, path); info(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device)); - device_read_uevent_file(udev_device); - device_read_db(udev_device); return udev_device; } @@ -381,9 +393,9 @@ void udev_device_unref(struct udev_device *udev_device) if (udev_device->parent_device != NULL) udev_device_unref(udev_device->parent_device); free(udev_device->syspath); - free(udev_device->devname); + free(udev_device->devnode); free(udev_device->subsystem); - list_cleanup(udev_device->udev, &udev_device->link_list); + list_cleanup(udev_device->udev, &udev_device->devlink_list); list_cleanup(udev_device->udev, &udev_device->properties_list); free(udev_device->action); free(udev_device->driver); @@ -446,7 +458,9 @@ const char *udev_device_get_devnode(struct udev_device *udev_device) { if (udev_device == NULL) return NULL; - return udev_device->devname; + if (!udev_device->info_loaded) + device_load_info(udev_device); + return udev_device->devnode; } /** @@ -506,7 +520,11 @@ const char *udev_device_get_subsystem(struct udev_device *udev_device) **/ struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device) { - return list_get_entry(&udev_device->link_list); + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + device_load_info(udev_device); + return list_get_entry(&udev_device->devlink_list); } /** @@ -523,6 +541,10 @@ struct udev_list *udev_device_get_devlinks_list(struct udev_device *udev_device) **/ struct udev_list *udev_device_get_properties_list(struct udev_device *udev_device) { + if (udev_device == NULL) + return NULL; + if (!udev_device->info_loaded) + device_load_info(udev_device); return list_get_entry(&udev_device->properties_list); } @@ -544,6 +566,8 @@ dev_t udev_device_get_devnum(struct udev_device *udev_device) { if (udev_device == NULL) return makedev(0, 0); + if (!udev_device->info_loaded) + device_load_info(udev_device); return udev_device->devnum; } @@ -576,7 +600,7 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch while (list != NULL) { if (strcmp(udev_list_get_name(list), attr) == 0) { info(udev_device->udev, "got '%s' (%s) from cache\n", attr, udev_list_get_value(list)); - return udev_list_get_name(list); + return udev_list_get_value(list); } list = udev_list_get_next(list); } @@ -663,17 +687,17 @@ int device_set_subsystem(struct udev_device *udev_device, const char *subsystem) return 0; } -int device_set_devname(struct udev_device *udev_device, const char *devname) +int device_set_devnode(struct udev_device *udev_device, const char *devnode) { - udev_device->devname = strdup(devname); - if (udev_device->devname == NULL) + udev_device->devnode = strdup(devnode); + if (udev_device->devnode == NULL) return -ENOMEM; return 0; } int device_add_devlink(struct udev_device *udev_device, const char *devlink) { - if (list_insert(udev_device->udev, &udev_device->link_list, devlink, NULL, 0) == NULL) + if (list_insert(udev_device->udev, &udev_device->devlink_list, devlink, NULL, 0) == NULL) return -ENOMEM; return 0; } @@ -720,8 +744,6 @@ int device_set_driver(struct udev_device *udev_device, const char *driver) const char *device_get_devpath_old(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; return udev_device->devpath_old; } @@ -735,8 +757,6 @@ int device_set_devpath_old(struct udev_device *udev_device, const char *devpath_ const char *device_get_physdevpath(struct udev_device *udev_device) { - if (udev_device == NULL) - return NULL; return udev_device->physdevpath; } @@ -750,8 +770,6 @@ int device_set_physdevpath(struct udev_device *udev_device, const char *physdevp int device_get_timeout(struct udev_device *udev_device) { - if (udev_device == NULL) - return -1; return udev_device->timeout; } @@ -760,6 +778,18 @@ int device_set_timeout(struct udev_device *udev_device, int timeout) udev_device->timeout = timeout; return 0; } +int device_get_event_timeout(struct udev_device *udev_device) +{ + if (!udev_device->info_loaded) + device_load_info(udev_device); + return udev_device->event_timeout; +} + +int device_set_event_timeout(struct udev_device *udev_device, int event_timeout) +{ + udev_device->event_timeout = event_timeout; + return 0; +} int device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum) { @@ -775,8 +805,8 @@ int device_set_devnum(struct udev_device *udev_device, dev_t devnum) int device_get_num_fake_partitions(struct udev_device *udev_device) { - if (udev_device == NULL) - return -1; + if (!udev_device->info_loaded) + device_load_info(udev_device); return udev_device->num_fake_partitions; } @@ -788,8 +818,8 @@ int device_set_num_fake_partitions(struct udev_device *udev_device, int num) int device_get_devlink_priority(struct udev_device *udev_device) { - if (udev_device == NULL) - return -1; + if (!udev_device->info_loaded) + device_load_info(udev_device); return udev_device->devlink_priority; } @@ -801,8 +831,8 @@ int device_set_devlink_priority(struct udev_device *udev_device, int prio) int device_get_ignore_remove(struct udev_device *udev_device) { - if (udev_device == NULL) - return -1; + if (!udev_device->info_loaded) + device_load_info(udev_device); return udev_device->ignore_remove; } diff --git a/udev/lib/libudev-monitor.c b/udev/lib/libudev-monitor.c index 0dc8e10cb..8a1bdaed0 100644 --- a/udev/lib/libudev-monitor.c +++ b/udev/lib/libudev-monitor.c @@ -308,7 +308,7 @@ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monito } else if (strncmp(key, "SUBSYSTEM=", 10) == 0) { device_set_subsystem(udev_device, &key[10]); } else if (strncmp(key, "DEVNAME=", 8) == 0) { - device_set_devname(udev_device, &key[8]); + device_set_devnode(udev_device, &key[8]); } else if (strncmp(key, "DEVLINKS=", 9) == 0) { char *slink = &key[9]; char *next = strchr(slink, ' '); @@ -344,5 +344,6 @@ struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monito } device_set_devnum(udev_device, makedev(maj, min)); + device_set_info_loaded(udev_device); return udev_device; } diff --git a/udev/lib/libudev-private.h b/udev/lib/libudev-private.h index c80c940b1..5be798317 100644 --- a/udev/lib/libudev-private.h +++ b/udev/lib/libudev-private.h @@ -55,7 +55,7 @@ extern int udev_get_run(struct udev *udev); /* libudev-device */ extern int device_set_syspath(struct udev_device *udev_device, const char *syspath); extern int device_set_subsystem(struct udev_device *udev_device, const char *subsystem); -extern int device_set_devname(struct udev_device *udev_device, const char *devname); +extern int device_set_devnode(struct udev_device *udev_device, const char *devnode); extern int device_add_devlink(struct udev_device *udev_device, const char *devlink); extern int device_add_property(struct udev_device *udev_device, const char *key, const char *value); extern int device_add_property_from_string(struct udev_device *udev_device, const char *property); @@ -67,6 +67,8 @@ extern const char *device_get_physdevpath(struct udev_device *udev_device); extern int device_set_physdevpath(struct udev_device *udev_device, const char *physdevpath); extern int device_get_timeout(struct udev_device *udev_device); extern int device_set_timeout(struct udev_device *udev_device, int timeout); +extern int device_get_event_timeout(struct udev_device *udev_device); +extern int device_set_event_timeout(struct udev_device *udev_device, int event_timeout); extern int device_set_devnum(struct udev_device *udev_device, dev_t devnum); extern int device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum); extern int device_get_num_fake_partitions(struct udev_device *udev_device); @@ -75,6 +77,7 @@ extern int device_get_devlink_priority(struct udev_device *udev_device); extern int device_set_devlink_priority(struct udev_device *udev_device, int prio); extern int device_get_ignore_remove(struct udev_device *udev_device); extern int device_set_ignore_remove(struct udev_device *udev_device, int ignore); +extern void device_set_info_loaded(struct udev_device *device); /* libudev-ctrl - daemon runtime setup */ struct udev_ctrl;