mirror of
https://github.com/systemd/systemd
synced 2024-10-15 20:45:09 +00:00
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
This commit is contained in:
commit
18c4e13457
|
@ -8,9 +8,19 @@
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
|
#define LATEST_UDEV_DATABASE_VERSION 1
|
||||||
|
|
||||||
struct sd_device {
|
struct sd_device {
|
||||||
unsigned n_ref;
|
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;
|
int watch_handle;
|
||||||
|
|
||||||
sd_device *parent;
|
sd_device *parent;
|
||||||
|
@ -88,7 +98,9 @@ struct sd_device {
|
||||||
|
|
||||||
int device_new_aux(sd_device **ret);
|
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_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_read_uevent_file(sd_device *device);
|
||||||
|
|
||||||
int device_set_syspath(sd_device *device, const char *_syspath, bool verify);
|
int device_set_syspath(sd_device *device, const char *_syspath, bool verify);
|
||||||
|
|
|
@ -948,6 +948,10 @@ int device_update_db(sd_device *device) {
|
||||||
|
|
||||||
SET_FOREACH(tag, device->current_tags)
|
SET_FOREACH(tag, device->current_tags)
|
||||||
fprintf(f, "Q:%s\n", tag); /* Current tag */
|
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);
|
r = fflush_and_check(f);
|
||||||
|
|
|
@ -128,10 +128,6 @@ int device_add_property_aux(sd_device *device, const char *_key, const char *_va
|
||||||
return 0;
|
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) {
|
int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
|
||||||
_cleanup_free_ char *syspath = NULL;
|
_cleanup_free_ char *syspath = NULL;
|
||||||
const char *devpath;
|
const char *devpath;
|
||||||
|
@ -1208,6 +1204,12 @@ static int handle_db_line(sd_device *device, char key, const char *value) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
r = safe_atou(value, &device->database_version);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_device_debug(device, "sd-device: Unknown key '%c' in device db, ignoring", key);
|
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;
|
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) {
|
_public_ const char *sd_device_get_current_tag_first(sd_device *device) {
|
||||||
void *v;
|
void *v;
|
||||||
|
|
||||||
assert_return(device, NULL);
|
assert_return(device, NULL);
|
||||||
|
|
||||||
|
if (!device_database_supports_current_tags(device))
|
||||||
|
return sd_device_get_tag_first(device);
|
||||||
|
|
||||||
(void) device_read_db(device);
|
(void) device_read_db(device);
|
||||||
|
|
||||||
device->current_tags_iterator_generation = device->tags_generation;
|
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);
|
assert_return(device, NULL);
|
||||||
|
|
||||||
|
if (!device_database_supports_current_tags(device))
|
||||||
|
return sd_device_get_tag_next(device);
|
||||||
|
|
||||||
(void) device_read_db(device);
|
(void) device_read_db(device);
|
||||||
|
|
||||||
if (device->current_tags_iterator_generation != device->tags_generation)
|
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(device, -EINVAL);
|
||||||
assert_return(tag, -EINVAL);
|
assert_return(tag, -EINVAL);
|
||||||
|
|
||||||
|
if (!device_database_supports_current_tags(device))
|
||||||
|
return sd_device_has_tag(device, tag);
|
||||||
|
|
||||||
(void) device_read_db(device);
|
(void) device_read_db(device);
|
||||||
|
|
||||||
return set_contains(device->current_tags, tag);
|
return set_contains(device->current_tags, tag);
|
||||||
|
|
Loading…
Reference in a new issue