diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2020-11-26 12:48:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-26 12:48:05 +0100 |
commit | 18c4e13457a0535186418851c41b2f1657b7cca0 (patch) | |
tree | 9cfa5503b976f2489b898c272ec350b7985ca26c | |
parent | 362ddd775690684ce32246395550a48149304b99 (diff) | |
parent | 6ece7cd2b7d5a9a916958a93f108a2fc1c9a0c0c (diff) | |
download | systemd-18c4e13457a0535186418851c41b2f1657b7cca0.tar.gz |
Merge pull request #17622 from yuwata/udev-database-set-udev-version
sd-device: make sd_device_has_current_tag() compatible with udev database generated by older udevd
-rw-r--r-- | src/libsystemd/sd-device/device-internal.h | 14 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-private.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 31 |
3 files changed, 44 insertions, 5 deletions
diff --git a/src/libsystemd/sd-device/device-internal.h b/src/libsystemd/sd-device/device-internal.h index 3f81cef796..3321c8e2dc 100644 --- a/src/libsystemd/sd-device/device-internal.h +++ b/src/libsystemd/sd-device/device-internal.h @@ -8,9 +8,19 @@ #include "set.h" #include "time-util.h" +#define LATEST_UDEV_DATABASE_VERSION 1 + struct sd_device { unsigned n_ref; + /* The database version indicates the supported features by the udev database. + * This is saved and parsed in V field. + * + * 0: None of the following features are supported (systemd version <= 246). + * 1: The current tags (Q) and the database version (V) features are implemented (>= 247). + */ + unsigned database_version; + int watch_handle; sd_device *parent; @@ -88,7 +98,9 @@ struct sd_device { int device_new_aux(sd_device **ret); int device_add_property_aux(sd_device *device, const char *key, const char *value, bool db); -int device_add_property_internal(sd_device *device, const char *key, const char *value); +static inline int device_add_property_internal(sd_device *device, const char *key, const char *value) { + return device_add_property_aux(device, key, value, false); +} int device_read_uevent_file(sd_device *device); int device_set_syspath(sd_device *device, const char *_syspath, bool verify); diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index 1c7bb033d3..2801ebdcbe 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -948,6 +948,10 @@ int device_update_db(sd_device *device) { SET_FOREACH(tag, device->current_tags) fprintf(f, "Q:%s\n", tag); /* Current tag */ + + /* Always write the latest database version here, instead of the value stored in + * device->database_version, as which may be 0. */ + fputs("V:" STRINGIFY(LATEST_UDEV_DATABASE_VERSION) "\n", f); } r = fflush_and_check(f); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index bfa0781773..d06f90ce1d 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -128,10 +128,6 @@ int device_add_property_aux(sd_device *device, const char *_key, const char *_va return 0; } -int device_add_property_internal(sd_device *device, const char *key, const char *value) { - return device_add_property_aux(device, key, value, false); -} - int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { _cleanup_free_ char *syspath = NULL; const char *devpath; @@ -1209,6 +1205,12 @@ static int handle_db_line(sd_device *device, char key, const char *value) { return r; break; + case 'V': + r = safe_atou(value, &device->database_version); + if (r < 0) + return r; + + break; default: log_device_debug(device, "sd-device: Unknown key '%c' in device db, ignoring", key); } @@ -1442,11 +1444,26 @@ _public_ const char *sd_device_get_tag_next(sd_device *device) { return v; } +static bool device_database_supports_current_tags(sd_device *device) { + assert(device); + + (void) device_read_db(device); + + /* The current tags (saved in Q field) feature is implemented in database version 1. + * If the database version is 0, then the tags (NOT current tags, saved in G field) are not + * sticky. Thus, we can safely bypass the operations for the current tags (Q) to tags (G). */ + + return device->database_version >= 1; +} + _public_ const char *sd_device_get_current_tag_first(sd_device *device) { void *v; assert_return(device, NULL); + if (!device_database_supports_current_tags(device)) + return sd_device_get_tag_first(device); + (void) device_read_db(device); device->current_tags_iterator_generation = device->tags_generation; @@ -1461,6 +1478,9 @@ _public_ const char *sd_device_get_current_tag_next(sd_device *device) { assert_return(device, NULL); + if (!device_database_supports_current_tags(device)) + return sd_device_get_tag_next(device); + (void) device_read_db(device); if (device->current_tags_iterator_generation != device->tags_generation) @@ -1763,6 +1783,9 @@ _public_ int sd_device_has_current_tag(sd_device *device, const char *tag) { assert_return(device, -EINVAL); assert_return(tag, -EINVAL); + if (!device_database_supports_current_tags(device)) + return sd_device_has_tag(device, tag); + (void) device_read_db(device); return set_contains(device->current_tags, tag); |