#include "libudev-private.h"
static int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode);
+static struct udev_list_entry *udev_device_add_property_internal(struct udev_device *udev_device, const char *key, const char *value);
/**
* SECTION:libudev-device
udev_device->seqnum = seqnum;
snprintf(num, sizeof(num), "%llu", seqnum);
- udev_device_add_property(udev_device, "SEQNUM", num);
+ udev_device_add_property_internal(udev_device, "SEQNUM", num);
return 0;
}
udev_device->ifindex = ifindex;
snprintf(num, sizeof(num), "%d", ifindex);
- udev_device_add_property(udev_device, "IFINDEX", num);
+ udev_device_add_property_internal(udev_device, "IFINDEX", num);
return 0;
}
udev_device->devnum = devnum;
snprintf(num, sizeof(num), "%u", major(devnum));
- udev_device_add_property(udev_device, "MAJOR", num);
+ udev_device_add_property_internal(udev_device, "MAJOR", num);
snprintf(num, sizeof(num), "%u", minor(devnum));
- udev_device_add_property(udev_device, "MINOR", num);
+ udev_device_add_property_internal(udev_device, "MINOR", num);
return 0;
}
udev_device->devpath_old = strdup(devpath_old);
if (udev_device->devpath_old == NULL)
return -ENOMEM;
- udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
+ udev_device_add_property_internal(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
pos = strrchr(udev_device->devpath_old, '/');
if (pos == NULL)
if (udev_device->driver == NULL)
return -ENOMEM;
udev_device->driver_set = true;
- udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
+ udev_device_add_property_internal(udev_device, "DRIVER", udev_device->driver);
return 0;
}
if (udev_device->devtype == NULL)
return -ENOMEM;
udev_device->devtype_set = true;
- udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
+ udev_device_add_property_internal(udev_device, "DEVTYPE", udev_device->devtype);
return 0;
}
if (udev_device->subsystem == NULL)
return -ENOMEM;
udev_device->subsystem_set = true;
- udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
+ udev_device_add_property_internal(udev_device, "SUBSYSTEM", udev_device->subsystem);
return 0;
}
udev_device->devnode_mode = mode;
snprintf(num, sizeof(num), "%#o", mode);
- udev_device_add_property(udev_device, "DEVMODE", num);
+ udev_device_add_property_internal(udev_device, "DEVMODE", num);
return 0;
}
udev_device->devnode_uid = uid;
snprintf(num, sizeof(num), "%u", uid);
- udev_device_add_property(udev_device, "DEVUID", num);
+ udev_device_add_property_internal(udev_device, "DEVUID", num);
return 0;
}
udev_device->devnode_gid = gid;
snprintf(num, sizeof(num), "%u", gid);
- udev_device_add_property(udev_device, "DEVGID", num);
+ udev_device_add_property_internal(udev_device, "DEVGID", num);
return 0;
}
-struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
+static struct udev_list_entry *udev_device_add_property_internal(struct udev_device *udev_device, const char *key, const char *value)
{
udev_device->envp_uptodate = false;
if (value == NULL) {
return udev_list_entry_add(&udev_device->properties_list, key, value);
}
+
+int udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
+{
+ struct udev_list_entry *property;
+
+ property = udev_device_add_property_internal(udev_device, key, value);
+
+ /* store in db, skip private keys */
+ if (key[0] != '.')
+ udev_list_entry_set_num(property, true);
+
+ return 0;
+}
+
static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
{
char name[UTIL_LINE_SIZE];
val = &val[1];
if (val[0] == '\0')
val = NULL;
- return udev_device_add_property(udev_device, name, val);
+ return udev_device_add_property_internal(udev_device, name, val);
}
static int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
if (udev_device->syspath == NULL)
return -ENOMEM;
udev_device->devpath = udev_device->syspath + strlen("/sys");
- udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
+ udev_device_add_property_internal(udev_device, "DEVPATH", udev_device->devpath);
pos = strrchr(udev_device->syspath, '/');
if (pos == NULL)
return udev_list_entry_get_value(list_entry);
}
-int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
+int udev_device_read_db(struct udev_device *udev_device)
{
char filename[UTIL_PATH_SIZE];
char line[UTIL_LINE_SIZE];
+ const char *id;
FILE *f;
- /* providing a database file will always force-load it */
- if (dbfile == NULL) {
- const char *id;
+ if (udev_device->db_loaded)
+ return 0;
- if (udev_device->db_loaded)
- return 0;
- udev_device->db_loaded = true;
+ udev_device->db_loaded = true;
- id = udev_device_get_id_filename(udev_device);
- if (id == NULL)
- return -1;
- strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
- dbfile = filename;
- }
+ id = udev_device_get_id_filename(udev_device);
+ if (id == NULL)
+ return -1;
- f = fopen(dbfile, "re");
+ strscpyl(filename, sizeof(filename), "/run/udev/data/", id, NULL);
+
+ f = fopen(filename, "re");
if (f == NULL)
- return log_debug_errno(errno, "no db file to read %s: %m", dbfile);
+ return log_debug_errno(errno, "no db file to read %s: %m", filename);
/* devices with a database entry are initialized */
udev_device->is_initialized = true;
if (udev_device == NULL)
return NULL;
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
return udev_list_get_entry(&udev_device->devlinks_list);
}
return NULL;
if (!udev_device->info_loaded) {
udev_device_read_uevent_file(udev_device);
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
}
if (!udev_device->devlinks_uptodate) {
char symlinks[UTIL_PATH_SIZE];
l = strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
l = strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
- udev_device_add_property(udev_device, "DEVLINKS", symlinks);
+ udev_device_add_property_internal(udev_device, "DEVLINKS", symlinks);
}
}
if (!udev_device->tags_uptodate) {
l = strpcpyl(&s, sizeof(tags), ":", NULL);
udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
l = strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
- udev_device_add_property(udev_device, "TAGS", tags);
+ udev_device_add_property_internal(udev_device, "TAGS", tags);
}
}
return udev_list_get_entry(&udev_device->properties_list);
if (udev_device == NULL)
return 0;
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
if (udev_device->usec_initialized == 0)
return 0;
now_ts = now(CLOCK_MONOTONIC);
udev_device->usec_initialized = usec_initialized;
snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
- udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
+ udev_device_add_property_internal(udev_device, "USEC_INITIALIZED", num);
}
/**
}
if (udev_device->devnode == NULL)
return -ENOMEM;
- udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
+ udev_device_add_property_internal(udev_device, "DEVNAME", udev_device->devnode);
return 0;
}
_public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
return udev_device->is_initialized;
}
if (udev_device == NULL)
return NULL;
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
return udev_list_get_entry(&udev_device->tags_list);
}
if (udev_device == NULL)
return false;
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
list_entry = udev_device_get_tags_list_entry(udev_device);
if (udev_list_entry_get_by_name(list_entry, tag) != NULL)
return true;
udev_device->action = strdup(action);
if (udev_device->action == NULL)
return -ENOMEM;
- udev_device_add_property(udev_device, "ACTION", udev_device->action);
+ udev_device_add_property_internal(udev_device, "ACTION", udev_device->action);
return 0;
}
int udev_device_get_devlink_priority(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
return udev_device->devlink_priority;
}
int udev_device_get_watch_handle(struct udev_device *udev_device)
{
if (!udev_device->info_loaded)
- udev_device_read_db(udev_device, NULL);
+ udev_device_read_db(udev_device);
return udev_device->watch_handle;
}
int udev_device_rename(struct udev_device *udev_device, const char *name)
{
_cleanup_free_ char *dirname = NULL;
+ const char *interface;
char *new_syspath;
int r;
if (r < 0)
return r;
+ interface = udev_device_get_property_value(udev_device, "INTERFACE");
+ if (interface) {
+ /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
+ udev_device_add_property_internal(udev_device, "INTERFACE_OLD", interface);
+ udev_device_add_property_internal(udev_device, "INTERFACE", name);
+ }
+
return 0;
}
return device;
}
+struct udev_device *udev_device_clone_with_db(struct udev_device *old_device)
+{
+ struct udev_device *device;
+
+ device = udev_device_shallow_clone(old_device);
+ if (!device)
+ return NULL;
+
+ udev_device_read_db(device);
+ udev_device_set_info_loaded(device);
+
+ return device;
+}
+
struct udev_device *udev_device_new_from_nulstr(struct udev *udev, char *nulstr, ssize_t buflen) {
struct udev_device *device;
ssize_t bufpos = 0;
return device;
}
+
+int udev_device_copy_properties(struct udev_device *dst, struct udev_device *src) {
+ struct udev_list_entry *entry;
+
+ for ((entry = udev_device_get_properties_list_entry(src)); entry; entry = udev_list_entry_get_next(entry)) {
+ const char *key, *value;
+
+ key = udev_list_entry_get_name(entry);
+ value = udev_list_entry_get_value(entry);
+
+ udev_device_add_property(dst, key, value);
+ }
+
+ return 0;
+}