mirror of
https://github.com/systemd/systemd.git
synced 2025-02-24 17:57:34 +03:00
Merge pull request #23817 from yuwata/sd-device-send-udev-database-version
sd-device: send udev database version
This commit is contained in:
commit
44571ce98e
@ -55,7 +55,7 @@ struct sd_device {
|
||||
dev_t devnum;
|
||||
|
||||
char **properties_strv; /* the properties hashmap as a strv */
|
||||
uint8_t *properties_nulstr; /* the same as a nulstr */
|
||||
char *properties_nulstr; /* the same as a nulstr */
|
||||
size_t properties_nulstr_len;
|
||||
|
||||
char *syspath;
|
||||
|
@ -508,7 +508,7 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
|
||||
"sd-device-monitor: Invalid message header");
|
||||
}
|
||||
|
||||
r = device_new_from_nulstr(&device, (uint8_t*) &buf.raw[bufpos], buflen - bufpos);
|
||||
r = device_new_from_nulstr(&device, &buf.raw[bufpos], buflen - bufpos);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "sd-device-monitor: Failed to create device from received message: %m");
|
||||
|
||||
@ -574,7 +574,7 @@ int device_monitor_send_device(
|
||||
assert(m);
|
||||
assert(device);
|
||||
|
||||
r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen);
|
||||
r = device_get_properties_nulstr(device, &buf, &blen);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device properties: %m");
|
||||
if (blen < 32)
|
||||
|
@ -356,6 +356,10 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "sd-device: Failed to add tag '%s': %m", word);
|
||||
}
|
||||
} else if (streq(key, "UDEV_DATABASE_VERSION")) {
|
||||
r = safe_atou(value, &device->database_version);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "sd-device: Failed to parse udev database version '%s': %m", value);
|
||||
} else {
|
||||
r = device_add_property_internal(device, key, value);
|
||||
if (r < 0)
|
||||
@ -467,7 +471,7 @@ int device_new_from_strv(sd_device **ret, char **strv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
|
||||
int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
const char *major = NULL, *minor = NULL;
|
||||
int r;
|
||||
@ -484,7 +488,7 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
|
||||
char *key;
|
||||
const char *end;
|
||||
|
||||
key = (char*) &nulstr[i];
|
||||
key = nulstr + i;
|
||||
end = memchr(key, '\0', len - i);
|
||||
if (!end)
|
||||
return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
|
||||
@ -517,16 +521,24 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
|
||||
}
|
||||
|
||||
static int device_update_properties_bufs(sd_device *device) {
|
||||
_cleanup_free_ char **buf_strv = NULL, *buf_nulstr = NULL;
|
||||
size_t nulstr_len = 0, num = 0;
|
||||
const char *val, *prop;
|
||||
_cleanup_free_ char **buf_strv = NULL;
|
||||
_cleanup_free_ uint8_t *buf_nulstr = NULL;
|
||||
size_t nulstr_len = 0, num = 0, i = 0;
|
||||
|
||||
assert(device);
|
||||
|
||||
if (!device->properties_buf_outdated)
|
||||
return 0;
|
||||
|
||||
/* append udev database version */
|
||||
buf_nulstr = newdup(char, "UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION) "\0",
|
||||
STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION)) + 2);
|
||||
if (!buf_nulstr)
|
||||
return -ENOMEM;
|
||||
|
||||
nulstr_len += STRLEN("UDEV_DATABASE_VERSION=" STRINGIFY(LATEST_UDEV_DATABASE_VERSION)) + 1;
|
||||
num++;
|
||||
|
||||
FOREACH_DEVICE_PROPERTY(device, prop, val) {
|
||||
size_t len = 0;
|
||||
|
||||
@ -536,59 +548,58 @@ static int device_update_properties_bufs(sd_device *device) {
|
||||
if (!buf_nulstr)
|
||||
return -ENOMEM;
|
||||
|
||||
strscpyl((char *)buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
|
||||
strscpyl(buf_nulstr + nulstr_len, len + 1, prop, "=", val, NULL);
|
||||
nulstr_len += len + 1;
|
||||
++num;
|
||||
num++;
|
||||
}
|
||||
|
||||
/* build buf_strv from buf_nulstr */
|
||||
buf_strv = new0(char *, num + 1);
|
||||
buf_strv = new0(char*, num + 1);
|
||||
if (!buf_strv)
|
||||
return -ENOMEM;
|
||||
|
||||
NULSTR_FOREACH(val, (char*) buf_nulstr) {
|
||||
buf_strv[i] = (char *) val;
|
||||
assert(i < num);
|
||||
i++;
|
||||
}
|
||||
size_t i = 0;
|
||||
char *p;
|
||||
NULSTR_FOREACH(p, buf_nulstr)
|
||||
buf_strv[i++] = p;
|
||||
assert(i == num);
|
||||
|
||||
free_and_replace(device->properties_nulstr, buf_nulstr);
|
||||
device->properties_nulstr_len = nulstr_len;
|
||||
free_and_replace(device->properties_strv, buf_strv);
|
||||
|
||||
device->properties_buf_outdated = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len) {
|
||||
int device_get_properties_nulstr(sd_device *device, const char **ret_nulstr, size_t *ret_len) {
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(nulstr);
|
||||
assert(len);
|
||||
|
||||
r = device_update_properties_bufs(device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*nulstr = device->properties_nulstr;
|
||||
*len = device->properties_nulstr_len;
|
||||
if (ret_nulstr)
|
||||
*ret_nulstr = device->properties_nulstr;
|
||||
if (ret_len)
|
||||
*ret_len = device->properties_nulstr_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_get_properties_strv(sd_device *device, char ***strv) {
|
||||
int device_get_properties_strv(sd_device *device, char ***ret) {
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(strv);
|
||||
|
||||
r = device_update_properties_bufs(device);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*strv = device->properties_strv;
|
||||
if (ret)
|
||||
*ret = device->properties_strv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len);
|
||||
int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len);
|
||||
int device_new_from_strv(sd_device **ret, char **strv);
|
||||
int device_new_from_watch_handle_at(sd_device **ret, int dirfd, int wd);
|
||||
static inline int device_new_from_watch_handle(sd_device **ret, int wd) {
|
||||
@ -48,8 +48,8 @@ uint64_t device_get_tags_generation(sd_device *device);
|
||||
uint64_t device_get_devlinks_generation(sd_device *device);
|
||||
|
||||
int device_properties_prepare(sd_device *device);
|
||||
int device_get_properties_nulstr(sd_device *device, const uint8_t **nulstr, size_t *len);
|
||||
int device_get_properties_strv(sd_device *device, char ***strv);
|
||||
int device_get_properties_nulstr(sd_device *device, const char **ret_nulstr, size_t *ret_len);
|
||||
int device_get_properties_strv(sd_device *device, char ***ret);
|
||||
|
||||
int device_rename(sd_device *device, const char *name);
|
||||
int device_shallow_clone(sd_device *device, sd_device **ret);
|
||||
|
@ -320,9 +320,8 @@ TEST(sd_device_new_from_nulstr) {
|
||||
"\0";
|
||||
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL, *from_nulstr = NULL;
|
||||
_cleanup_free_ uint8_t *nulstr_copy = NULL;
|
||||
const char *devlink;
|
||||
const uint8_t *nulstr;
|
||||
_cleanup_free_ char *nulstr_copy = NULL;
|
||||
const char *devlink, *nulstr;
|
||||
size_t len;
|
||||
|
||||
assert_se(sd_device_new_from_syspath(&device, "/sys/class/net/lo") >= 0);
|
||||
@ -335,14 +334,29 @@ TEST(sd_device_new_from_nulstr) {
|
||||
assert_se(set_contains(device->devlinks, devlink));
|
||||
}
|
||||
|
||||
/* For issue #23799 */
|
||||
assert_se(device_add_tag(device, "tag1", false) >= 0);
|
||||
assert_se(device_add_tag(device, "tag2", false) >= 0);
|
||||
assert_se(device_add_tag(device, "current-tag1", true) >= 0);
|
||||
assert_se(device_add_tag(device, "current-tag2", true) >= 0);
|
||||
|
||||
/* These properties are necessary for device_new_from_nulstr(). See device_verify(). */
|
||||
assert_se(device_add_property_internal(device, "SEQNUM", "1") >= 0);
|
||||
assert_se(device_add_property_internal(device, "ACTION", "change") >= 0);
|
||||
|
||||
assert_se(device_get_properties_nulstr(device, &nulstr, &len) >= 0);
|
||||
assert_se(nulstr_copy = newdup(uint8_t, nulstr, len));
|
||||
assert_se(nulstr_copy = newdup(char, nulstr, len));
|
||||
assert_se(device_new_from_nulstr(&from_nulstr, nulstr_copy, len) >= 0);
|
||||
|
||||
assert_se(sd_device_has_tag(from_nulstr, "tag1") == 1);
|
||||
assert_se(sd_device_has_tag(from_nulstr, "tag2") == 1);
|
||||
assert_se(sd_device_has_tag(from_nulstr, "current-tag1") == 1);
|
||||
assert_se(sd_device_has_tag(from_nulstr, "current-tag2") == 1);
|
||||
assert_se(sd_device_has_current_tag(from_nulstr, "tag1") == 0);
|
||||
assert_se(sd_device_has_current_tag(from_nulstr, "tag2") == 0);
|
||||
assert_se(sd_device_has_current_tag(from_nulstr, "current-tag1") == 1);
|
||||
assert_se(sd_device_has_current_tag(from_nulstr, "current-tag2") == 1);
|
||||
|
||||
NULSTR_FOREACH(devlink, devlinks) {
|
||||
log_device_info(from_nulstr, "checking devlink: %s", devlink);
|
||||
assert_se(set_contains(from_nulstr->devlinks, devlink));
|
||||
|
Loading…
x
Reference in New Issue
Block a user