summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-device
diff options
context:
space:
mode:
authorFelipe Sateler <fsateler@debian.org>2019-02-20 21:24:33 -0300
committerFelipe Sateler <fsateler@debian.org>2019-02-20 21:24:33 -0300
commit7c20daf69c4411979b7f8902f3601d1cdc56cc07 (patch)
treed59b9989ce55ed23693e80974d94c856f1c2c8b1 /src/libsystemd/sd-device
parent6e866b331d7cd4a5e0759dd160dea6edabd3678e (diff)
downloadsystemd-7c20daf69c4411979b7f8902f3601d1cdc56cc07.tar.gz
New upstream version 241upstream/241
Diffstat (limited to 'src/libsystemd/sd-device')
-rw-r--r--src/libsystemd/sd-device/device-monitor.c12
-rw-r--r--src/libsystemd/sd-device/device-private.c24
-rw-r--r--src/libsystemd/sd-device/device-private.h1
-rw-r--r--src/libsystemd/sd-device/sd-device.c76
-rw-r--r--src/libsystemd/sd-device/test-sd-device-monitor.c127
5 files changed, 136 insertions, 104 deletions
diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c
index b86932663e..27d0af5918 100644
--- a/src/libsystemd/sd-device/device-monitor.c
+++ b/src/libsystemd/sd-device/device-monitor.c
@@ -93,14 +93,8 @@ _public_ int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, siz
assert_return(m, -EINVAL);
assert_return((size_t) n == size, -EINVAL);
- if (m->bound)
- return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
- "sd-device-monitor: Socket fd is already bound. "
- "It may be dangerous to change buffer size. "
- "Refusing to change buffer size.");
-
- if (setsockopt_int(m->sock, SOL_SOCKET, SO_RCVBUF, n) < 0) {
- r = setsockopt_int(m->sock, SOL_SOCKET, SO_RCVBUFFORCE, n);
+ if (setsockopt_int(m->sock, SOL_SOCKET, SO_RCVBUFFORCE, n) < 0) {
+ r = setsockopt_int(m->sock, SOL_SOCKET, SO_RCVBUF, n);
if (r < 0)
return r;
}
@@ -754,7 +748,7 @@ _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) {
m->subsystem_filter = hashmap_free_free_free(m->subsystem_filter);
m->tag_filter = set_free_free(m->tag_filter);
- if (setsockopt(m->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0)
+ if (setsockopt(m->sock, SOL_SOCKET, SO_DETACH_FILTER, &filter, sizeof(filter)) < 0)
return -errno;
m->filter_uptodate = true;
diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c
index 01a5aa3d3f..76267a1e74 100644
--- a/src/libsystemd/sd-device/device-private.c
+++ b/src/libsystemd/sd-device/device-private.c
@@ -326,15 +326,6 @@ static int device_append(sd_device *device, char *key, const char **_major, cons
action = device_action_from_string(value);
if (action == _DEVICE_ACTION_INVALID)
return -EINVAL;
- /* FIXME: remove once we no longer flush previuos state for each action */
- if (action == DEVICE_ACTION_BIND || action == DEVICE_ACTION_UNBIND) {
- static bool warned;
- if (!warned) {
- log_device_debug(device, "sd-device: ignoring actions 'bind' and 'unbind'");
- warned = true;
- }
- return -EINVAL;
- }
} else if (streq(key, "SEQNUM")) {
r = safe_atou64(value, &seqnum);
if (r < 0)
@@ -711,13 +702,24 @@ int device_new_from_stat_rdev(sd_device **ret, const struct stat *st) {
int device_copy_properties(sd_device *device_dst, sd_device *device_src) {
const char *property, *value;
+ Iterator i;
int r;
assert(device_dst);
assert(device_src);
- FOREACH_DEVICE_PROPERTY(device_src, property, value) {
- r = device_add_property(device_dst, property, value);
+ r = device_properties_prepare(device_src);
+ if (r < 0)
+ return r;
+
+ ORDERED_HASHMAP_FOREACH_KEY(value, property, device_src->properties_db, i) {
+ r = device_add_property_aux(device_dst, property, value, true);
+ if (r < 0)
+ return r;
+ }
+
+ ORDERED_HASHMAP_FOREACH_KEY(value, property, device_src->properties, i) {
+ r = device_add_property_aux(device_dst, property, value, false);
if (r < 0)
return r;
}
diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h
index 56558b38c6..062bfd651c 100644
--- a/src/libsystemd/sd-device/device-private.h
+++ b/src/libsystemd/sd-device/device-private.h
@@ -37,6 +37,7 @@ uint64_t device_get_properties_generation(sd_device *device);
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);
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index db58615df5..2a69f2e94b 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -29,7 +29,7 @@
#include "util.h"
int device_new_aux(sd_device **ret) {
- sd_device *device = NULL;
+ sd_device *device;
assert(ret);
@@ -205,9 +205,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
return r;
free_and_replace(device->syspath, syspath);
-
device->devpath = devpath;
-
return 0;
}
@@ -227,7 +225,6 @@ _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) {
return r;
*ret = TAKE_PTR(device);
-
return 0;
}
@@ -610,8 +607,8 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
return sd_device_new_from_devnum(ret, id[0], devt);
}
- case 'n':
- {
+
+ case 'n': {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
_cleanup_close_ int sk = -1;
struct ifreq ifr = {};
@@ -642,11 +639,10 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
return -ENODEV;
*ret = TAKE_PTR(device);
-
return 0;
}
- case '+':
- {
+
+ case '+': {
char subsys[PATH_MAX];
char *sysname;
@@ -660,6 +656,7 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
return sd_device_new_from_subsystem_sysname(ret, subsys, sysname);
}
+
default:
return -EINVAL;
}
@@ -727,7 +724,6 @@ _public_ int sd_device_get_parent(sd_device *child, sd_device **ret) {
return -ENOENT;
*ret = child->parent;
-
return 0;
}
@@ -746,11 +742,8 @@ int device_set_subsystem(sd_device *device, const char *_subsystem) {
if (r < 0)
return r;
- free_and_replace(device->subsystem, subsystem);
-
device->subsystem_set = true;
-
- return 0;
+ return free_and_replace(device->subsystem, subsystem);
}
static int device_set_drivers_subsystem(sd_device *device, const char *_subsystem) {
@@ -769,9 +762,7 @@ static int device_set_drivers_subsystem(sd_device *device, const char *_subsyste
if (r < 0)
return r;
- free_and_replace(device->driver_subsystem, subsystem);
-
- return 0;
+ return free_and_replace(device->driver_subsystem, subsystem);
}
_public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
@@ -836,7 +827,6 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
return -ENOENT;
*ret = device->subsystem;
-
return 0;
}
@@ -886,7 +876,6 @@ _public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const
return r;
*ret = parent;
-
return 0;
}
@@ -923,11 +912,8 @@ int device_set_driver(sd_device *device, const char *_driver) {
if (r < 0)
return r;
- free_and_replace(device->driver, driver);
-
device->driver_set = true;
-
- return 0;
+ return free_and_replace(device->driver, driver);
}
_public_ int sd_device_get_driver(sd_device *device, const char **ret) {
@@ -960,7 +946,6 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
return -ENOENT;
*ret = device->driver;
-
return 0;
}
@@ -972,7 +957,6 @@ _public_ int sd_device_get_devpath(sd_device *device, const char **devpath) {
assert(device->devpath[0] == '/');
*devpath = device->devpath;
-
return 0;
}
@@ -992,7 +976,6 @@ _public_ int sd_device_get_devname(sd_device *device, const char **devname) {
assert(path_startswith(device->devname, "/dev/"));
*devname = device->devname;
-
return 0;
}
@@ -1002,6 +985,9 @@ static int device_set_sysname(sd_device *device) {
const char *pos;
size_t len = 0;
+ if (!device->devpath)
+ return -EINVAL;
+
pos = strrchr(device->devpath, '/');
if (!pos)
return -EINVAL;
@@ -1030,13 +1016,9 @@ static int device_set_sysname(sd_device *device) {
if (len == 0)
sysnum = NULL;
- free_and_replace(device->sysname, sysname);
-
- device->sysnum = sysnum;
-
device->sysname_set = true;
-
- return 0;
+ device->sysnum = sysnum;
+ return free_and_replace(device->sysname, sysname);
}
_public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
@@ -1054,7 +1036,6 @@ _public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
assert_return(device->sysname, -ENOENT);
*ret = device->sysname;
-
return 0;
}
@@ -1074,7 +1055,6 @@ _public_ int sd_device_get_sysnum(sd_device *device, const char **ret) {
return -ENOENT;
*ret = device->sysnum;
-
return 0;
}
@@ -1283,7 +1263,6 @@ int device_get_id_filename(sd_device *device, const char **ret) {
}
*ret = device->id_filename;
-
return 0;
}
@@ -1415,7 +1394,6 @@ _public_ int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *u
return -EIO;
*usec = now_ts - device->usec_initialized;
-
return 0;
}
@@ -1475,7 +1453,7 @@ _public_ const char *sd_device_get_devlink_next(sd_device *device) {
return v;
}
-static int device_properties_prepare(sd_device *device) {
+int device_properties_prepare(sd_device *device) {
int r;
assert(device);
@@ -1558,7 +1536,6 @@ _public_ const char *sd_device_get_property_first(sd_device *device, const char
if (_value)
*_value = value;
-
return key;
}
@@ -1580,7 +1557,6 @@ _public_ const char *sd_device_get_property_next(sd_device *device, const char *
if (_value)
*_value = value;
-
return key;
}
@@ -1691,7 +1667,6 @@ _public_ int sd_device_get_property_value(sd_device *device, const char *key, co
if (_value)
*_value = value;
-
return 0;
}
@@ -1718,8 +1693,7 @@ static int device_add_sysattr_value(sd_device *device, const char *_key, char *v
r = hashmap_put(device->sysattr_values, key, value);
if (r < 0)
return r;
-
- key = NULL;
+ TAKE_PTR(key);
return 0;
}
@@ -1736,7 +1710,6 @@ static int device_get_sysattr_value(sd_device *device, const char *_key, const c
if (_value)
*_value = value;
-
return 0;
}
@@ -1820,14 +1793,11 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr,
static void device_remove_sysattr_value(sd_device *device, const char *_key) {
_cleanup_free_ char *key = NULL;
- _cleanup_free_ char *value = NULL;
assert(device);
assert(_key);
- value = hashmap_remove2(device->sysattr_values, _key, (void **) &key);
-
- return;
+ free(hashmap_remove2(device->sysattr_values, _key, (void **) &key));
}
/* set the attribute and save it in the cache. If a NULL value is passed the
@@ -1843,7 +1813,6 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
if (!_value) {
device_remove_sysattr_value(device, sysattr);
-
return 0;
}
@@ -1874,23 +1843,22 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
if (r == -EISDIR)
return r;
- free(value);
- value = strdup("");
- if (!value)
- return -ENOMEM;
+ r = free_and_strdup(&value, "");
+ if (r < 0)
+ return r;
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
+ TAKE_PTR(value);
- value = NULL;
return -ENXIO;
}
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
+ TAKE_PTR(value);
- value = NULL;
return 0;
}
diff --git a/src/libsystemd/sd-device/test-sd-device-monitor.c b/src/libsystemd/sd-device/test-sd-device-monitor.c
index 9e5ca11fe9..aa1edaaf3c 100644
--- a/src/libsystemd/sd-device/test-sd-device-monitor.c
+++ b/src/libsystemd/sd-device/test-sd-device-monitor.c
@@ -21,14 +21,46 @@ static int monitor_handler(sd_device_monitor *m, sd_device *d, void *userdata) {
assert_se(sd_device_get_syspath(d, &s) >= 0);
assert_se(streq(s, syspath));
- return sd_event_exit(sd_device_monitor_get_event(m), 0);
+ return sd_event_exit(sd_device_monitor_get_event(m), 100);
}
-static int test_send_receive_one(sd_device *device, bool subsystem_filter, bool tag_filter, bool use_bpf) {
+static int test_receive_device_fail(void) {
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
- const char *syspath, *subsystem, *tag, *devtype = NULL;
+ _cleanup_(sd_device_unrefp) sd_device *loopback = NULL;
+ const char *syspath;
int r;
+ log_info("/* %s */", __func__);
+
+ /* Try to send device with invalid action and without seqnum. */
+ assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
+ assert_se(device_add_property(loopback, "ACTION", "hoge") >= 0);
+
+ assert_se(sd_device_get_syspath(loopback, &syspath) >= 0);
+
+ assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
+ assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
+ assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
+
+ assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
+ assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
+ assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
+ assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
+
+ /* Do not use assert_se() here. */
+ r = device_monitor_send_device(monitor_server, monitor_client, loopback);
+ if (r < 0)
+ return log_error_errno(r, "Failed to send loopback device: %m");
+
+ assert_se(sd_event_run(sd_device_monitor_get_event(monitor_client), 0) >= 0);
+
+ return 0;
+}
+
+static void test_send_receive_one(sd_device *device, bool subsystem_filter, bool tag_filter, bool use_bpf) {
+ _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
+ const char *syspath, *subsystem, *tag, *devtype = NULL;
+
log_device_info(device, "/* %s(subsystem_filter=%s, tag_filter=%s, use_bpf=%s) */", __func__,
true_false(subsystem_filter), true_false(tag_filter), true_false(use_bpf));
@@ -56,14 +88,8 @@ static int test_send_receive_one(sd_device *device, bool subsystem_filter, bool
if ((subsystem_filter || tag_filter) && use_bpf)
assert_se(sd_device_monitor_filter_update(monitor_client) >= 0);
- /* Do not use assert_se() here. */
- r = device_monitor_send_device(monitor_server, monitor_client, device);
- if (r < 0)
- return log_error_errno(r, "Failed to send loopback device: %m");
-
- assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 0);
-
- return 0;
+ assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
+ assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
}
static void test_subsystem_filter(sd_device *device) {
@@ -99,7 +125,45 @@ static void test_subsystem_filter(sd_device *device) {
log_info("Sending device subsystem:%s syspath:%s", subsystem, syspath);
assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
- assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 0);
+ assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
+}
+
+static void test_sd_device_monitor_filter_remove(sd_device *device) {
+ _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
+ const char *syspath;
+
+ log_device_info(device, "/* %s */", __func__);
+
+ assert_se(sd_device_get_syspath(device, &syspath) >= 0);
+
+ assert_se(device_monitor_new_full(&monitor_server, MONITOR_GROUP_NONE, -1) >= 0);
+ assert_se(sd_device_monitor_start(monitor_server, NULL, NULL) >= 0);
+ assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_server), "sender") >= 0);
+
+ assert_se(device_monitor_new_full(&monitor_client, MONITOR_GROUP_NONE, -1) >= 0);
+ assert_se(device_monitor_allow_unicast_sender(monitor_client, monitor_server) >= 0);
+ assert_se(sd_device_monitor_start(monitor_client, monitor_handler, (void *) syspath) >= 0);
+ assert_se(sd_event_source_set_description(sd_device_monitor_get_event_source(monitor_client), "receiver") >= 0);
+
+ assert_se(sd_device_monitor_filter_add_match_subsystem_devtype(monitor_client, "hoge", NULL) >= 0);
+ assert_se(sd_device_monitor_filter_update(monitor_client) >= 0);
+
+ assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
+ assert_se(sd_event_run(sd_device_monitor_get_event(monitor_client), 0) >= 0);
+
+ assert_se(sd_device_monitor_filter_remove(monitor_client) >= 0);
+
+ assert_se(device_monitor_send_device(monitor_server, monitor_client, device) >= 0);
+ assert_se(sd_event_loop(sd_device_monitor_get_event(monitor_client)) == 100);
+}
+
+static void test_device_copy_properties(sd_device *device) {
+ _cleanup_(sd_device_unrefp) sd_device *copy = NULL;
+
+ assert_se(device_shallow_clone(device, &copy) >= 0);
+ assert_se(device_copy_properties(copy, device) >= 0);
+
+ test_send_receive_one(copy, false, false, false);
}
int main(int argc, char *argv[]) {
@@ -111,24 +175,27 @@ int main(int argc, char *argv[]) {
if (getuid() != 0)
return log_tests_skipped("not root");
- assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
- assert_se(device_add_property(loopback, "ACTION", "add") >= 0);
- assert_se(device_add_property(loopback, "SEQNUM", "10") >= 0);
-
- r = test_send_receive_one(loopback, false, false, false);
+ r = test_receive_device_fail();
if (r < 0) {
assert_se(r == -EPERM && detect_container() > 0);
return log_tests_skipped("Running in container? Skipping remaining tests");
}
- assert_se(test_send_receive_one(loopback, true, false, false) >= 0);
- assert_se(test_send_receive_one(loopback, false, true, false) >= 0);
- assert_se(test_send_receive_one(loopback, true, true, false) >= 0);
- assert_se(test_send_receive_one(loopback, true, false, true) >= 0);
- assert_se(test_send_receive_one(loopback, false, true, true) >= 0);
- assert_se(test_send_receive_one(loopback, true, true, true) >= 0);
+ assert_se(sd_device_new_from_syspath(&loopback, "/sys/class/net/lo") >= 0);
+ assert_se(device_add_property(loopback, "ACTION", "add") >= 0);
+ assert_se(device_add_property(loopback, "SEQNUM", "10") >= 0);
+
+ test_send_receive_one(loopback, false, false, false);
+ test_send_receive_one(loopback, true, false, false);
+ test_send_receive_one(loopback, false, true, false);
+ test_send_receive_one(loopback, true, true, false);
+ test_send_receive_one(loopback, true, false, true);
+ test_send_receive_one(loopback, false, true, true);
+ test_send_receive_one(loopback, true, true, true);
test_subsystem_filter(loopback);
+ test_sd_device_monitor_filter_remove(loopback);
+ test_device_copy_properties(loopback);
r = sd_device_new_from_subsystem_sysname(&sda, "block", "sda");
if (r < 0) {
@@ -139,13 +206,13 @@ int main(int argc, char *argv[]) {
assert_se(device_add_property(sda, "ACTION", "change") >= 0);
assert_se(device_add_property(sda, "SEQNUM", "11") >= 0);
- assert_se(test_send_receive_one(sda, false, false, false) >= 0);
- assert_se(test_send_receive_one(sda, true, false, false) >= 0);
- assert_se(test_send_receive_one(sda, false, true, false) >= 0);
- assert_se(test_send_receive_one(sda, true, true, false) >= 0);
- assert_se(test_send_receive_one(sda, true, false, true) >= 0);
- assert_se(test_send_receive_one(sda, false, true, true) >= 0);
- assert_se(test_send_receive_one(sda, true, true, true) >= 0);
+ test_send_receive_one(sda, false, false, false);
+ test_send_receive_one(sda, true, false, false);
+ test_send_receive_one(sda, false, true, false);
+ test_send_receive_one(sda, true, true, false);
+ test_send_receive_one(sda, true, false, true);
+ test_send_receive_one(sda, false, true, true);
+ test_send_receive_one(sda, true, true, true);
return 0;
}