mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
libudev: enumerate - allow to filter-out not-already-initialized devices
This commit is contained in:
parent
ff0e1f4e5d
commit
48a0170b11
@ -34,9 +34,9 @@ DISTCHECK_HOOKS =
|
||||
# ------------------------------------------------------------------------------
|
||||
# libudev
|
||||
# ------------------------------------------------------------------------------
|
||||
LIBUDEV_CURRENT=9
|
||||
LIBUDEV_REVISION=4
|
||||
LIBUDEV_AGE=9
|
||||
LIBUDEV_CURRENT=10
|
||||
LIBUDEV_REVISION=0
|
||||
LIBUDEV_AGE=10
|
||||
|
||||
SUBDIRS += libudev/docs
|
||||
|
||||
|
@ -45,6 +45,7 @@ udev_device_get_syspath
|
||||
udev_device_get_sysname
|
||||
udev_device_get_sysnum
|
||||
udev_device_get_devnode
|
||||
udev_device_get_is_initialized
|
||||
udev_device_get_devlinks_list_entry
|
||||
udev_device_get_properties_list_entry
|
||||
udev_device_get_tags_list_entry
|
||||
@ -89,6 +90,7 @@ udev_enumerate_add_match_sysattr
|
||||
udev_enumerate_add_nomatch_sysattr
|
||||
udev_enumerate_add_match_property
|
||||
udev_enumerate_add_match_tag
|
||||
udev_enumerate_add_match_is_initialized
|
||||
udev_enumerate_add_match_sysname
|
||||
udev_enumerate_add_syspath
|
||||
udev_enumerate_scan_devices
|
||||
|
@ -28,6 +28,7 @@ udev_device_get_sysname
|
||||
udev_device_get_sysnum
|
||||
udev_device_get_subsystem
|
||||
udev_device_get_devtype
|
||||
udev_device_get_is_initialized
|
||||
udev_device_get_devlinks_list_entry
|
||||
udev_device_get_properties_list_entry
|
||||
udev_device_get_tags_list_entry
|
||||
@ -48,6 +49,7 @@ udev_enumerate_add_match_sysattr
|
||||
udev_enumerate_add_nomatch_sysattr
|
||||
udev_enumerate_add_match_property
|
||||
udev_enumerate_add_match_tag
|
||||
udev_enumerate_add_match_is_initialized
|
||||
udev_enumerate_add_match_sysname
|
||||
udev_enumerate_scan_devices
|
||||
udev_enumerate_scan_subsystems
|
||||
|
@ -114,7 +114,9 @@ int udev_device_update_db(struct udev_device *udev_device)
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db/", id, NULL);
|
||||
|
||||
/* do not store anything for otherwise empty devices */
|
||||
if (!has_info && udev_device_get_devnode(udev_device) == NULL) {
|
||||
if (!has_info &&
|
||||
major(udev_device_get_devnum(udev_device)) == 0 &&
|
||||
udev_device_get_ifindex(udev_device) == 0) {
|
||||
unlink(filename);
|
||||
return 0;
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ struct udev_device {
|
||||
bool info_loaded;
|
||||
bool db_loaded;
|
||||
bool uevent_loaded;
|
||||
bool is_initialized;
|
||||
};
|
||||
|
||||
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
|
||||
@ -249,6 +250,7 @@ int udev_device_read_db(struct udev_device *udev_device)
|
||||
info(udev_device->udev, "no db file to read %s: %m\n", filename);
|
||||
return -1;
|
||||
}
|
||||
udev_device->is_initialized = true;
|
||||
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
ssize_t len;
|
||||
@ -1308,6 +1310,31 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device)
|
||||
return udev_device->id_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_device_get_is_initialized:
|
||||
* @udev_device: udev device
|
||||
*
|
||||
* Check if udev has already handled the device and has set up
|
||||
* device node permissions and context, or has renamed a network
|
||||
* device.
|
||||
*
|
||||
* For now, this is only implemented for devices with a device node
|
||||
* or network interfaces. All other devices return 1 here.
|
||||
*
|
||||
* Returns: 1 if the device is set up. 0 otherwise.
|
||||
**/
|
||||
int udev_device_get_is_initialized(struct udev_device *udev_device)
|
||||
{
|
||||
if (!udev_device->info_loaded)
|
||||
udev_device_read_db(udev_device);
|
||||
return udev_device->is_initialized;
|
||||
}
|
||||
|
||||
void udev_device_set_is_initialized(struct udev_device *udev_device)
|
||||
{
|
||||
udev_device->is_initialized = true;
|
||||
}
|
||||
|
||||
int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
|
||||
{
|
||||
if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
|
||||
|
@ -57,6 +57,7 @@ struct udev_enumerate {
|
||||
unsigned int devices_cur;
|
||||
unsigned int devices_max;
|
||||
bool devices_uptodate:1;
|
||||
bool match_is_initialized;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -456,6 +457,32 @@ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const ch
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_enumerate_add_match_is_initialized:
|
||||
* @udev_enumerate: context
|
||||
*
|
||||
* Match only devices which udev has set up already. This makes
|
||||
* sure, that the device node permissions and context are properly set
|
||||
* and that network devices are fully renamed.
|
||||
*
|
||||
* Usually, devices which are found in the kernel but not already
|
||||
* handled by udev, have still pending events. Services should subscribe
|
||||
* to monitor events and wait for these devices to become ready, instead
|
||||
* of using uninitialized devices.
|
||||
*
|
||||
* For now, this will not affect devices which do not have a device node
|
||||
* and are not network interfaces.
|
||||
*
|
||||
* Returns: 0 on success, otherwise a negative error value.
|
||||
*/
|
||||
int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate)
|
||||
{
|
||||
if (udev_enumerate == NULL)
|
||||
return -EINVAL;
|
||||
udev_enumerate->match_is_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_enumerate_add_match_sysname:
|
||||
* @udev_enumerate: context
|
||||
@ -601,6 +628,21 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
|
||||
if (udev_enumerate->match_is_initialized) {
|
||||
/*
|
||||
* All devices with a device node or network interfaces
|
||||
* possibly need udev to adjust the device node permission
|
||||
* or context, or rename the interface before it can be
|
||||
* reliably used from other processes.
|
||||
*
|
||||
* For now, we can only check these types of devices, we
|
||||
* might not store a database, and have no way to find out
|
||||
* for all other types of devices.
|
||||
*/
|
||||
if (!udev_device_get_is_initialized(dev) &&
|
||||
(major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0))
|
||||
goto nomatch;
|
||||
}
|
||||
if (!match_tag(udev_enumerate, dev))
|
||||
goto nomatch;
|
||||
if (!match_property(udev_enumerate, dev))
|
||||
|
@ -87,6 +87,7 @@ const char *udev_device_get_sysname_old(struct udev_device *udev_device);
|
||||
int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old);
|
||||
const char *udev_device_get_knodename(struct udev_device *udev_device);
|
||||
const char *udev_device_get_id_filename(struct udev_device *udev_device);
|
||||
void udev_device_set_is_initialized(struct udev_device *udev_device);
|
||||
int udev_device_add_tag(struct udev_device *udev_device, const char *tag);
|
||||
void udev_device_cleanup_tags_list(struct udev_device *udev_device);
|
||||
int udev_device_has_tag(struct udev_device *udev_device, const char *tag);
|
||||
|
@ -88,6 +88,7 @@ const char *udev_device_get_syspath(struct udev_device *udev_device);
|
||||
const char *udev_device_get_sysname(struct udev_device *udev_device);
|
||||
const char *udev_device_get_sysnum(struct udev_device *udev_device);
|
||||
const char *udev_device_get_devnode(struct udev_device *udev_device);
|
||||
int udev_device_get_is_initialized(struct udev_device *udev_device);
|
||||
struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
|
||||
struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
|
||||
struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device);
|
||||
@ -141,6 +142,7 @@ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, co
|
||||
int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
|
||||
int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname);
|
||||
int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag);
|
||||
int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate);
|
||||
int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath);
|
||||
/* run enumeration with active filters */
|
||||
int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
|
||||
|
@ -354,6 +354,7 @@ static int test_enumerate(struct udev *udev, const char *subsystem)
|
||||
if (udev_enumerate == NULL)
|
||||
return -1;
|
||||
udev_enumerate_add_match_subsystem(udev_enumerate,"block");
|
||||
udev_enumerate_add_match_is_initialized(udev_enumerate);
|
||||
udev_enumerate_scan_devices(udev_enumerate);
|
||||
test_enumerate_print_list(udev_enumerate);
|
||||
udev_enumerate_unref(udev_enumerate);
|
||||
|
@ -631,12 +631,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
|
||||
/* set device node name */
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", event->name, NULL);
|
||||
udev_device_set_devnode(dev, filename);
|
||||
}
|
||||
|
||||
udev_device_update_db(dev);
|
||||
udev_device_tag_index(dev, event->dev_db, true);
|
||||
|
||||
if (major(udev_device_get_devnum(dev)) != 0) {
|
||||
/* remove/update possible left-over symlinks from old database entry */
|
||||
if (event->dev_db != NULL)
|
||||
udev_node_update_old_links(dev, event->dev_db);
|
||||
@ -648,6 +643,10 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
|
||||
err = udev_node_add(dev, event->mode, event->uid, event->gid);
|
||||
}
|
||||
|
||||
udev_device_update_db(dev);
|
||||
udev_device_tag_index(dev, event->dev_db, true);
|
||||
udev_device_set_is_initialized(dev);
|
||||
|
||||
udev_device_unref(event->dev_db);
|
||||
event->dev_db = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user