From 75d0aba49be010bb18b514171fcf2672b47cc855 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 25 Apr 2018 22:05:00 +0900 Subject: [PATCH] device: fix serialization and deserialization of DeviceFound DeviceFound is a bit flag. So, it is necessary to support the case that multiple bits are set. Follow-up for 918e6f1c0151429f5095355f4f3f74f16e79724a. --- src/core/device.c | 88 +++++++++++++++++++++++++++++++++++++---------- src/core/device.h | 3 -- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/core/device.c b/src/core/device.c index 1441d08b97..294e79f9b5 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -17,7 +17,6 @@ #include "parse-util.h" #include "path-util.h" #include "stat-util.h" -#include "string-table.h" #include "string-util.h" #include "swap.h" #include "udev-util.h" @@ -152,7 +151,71 @@ static int device_coldplug(Unit *u) { return 0; } +static const struct { + DeviceFound flag; + const char *name; +} device_found_map[] = { + { DEVICE_FOUND_UDEV, "found-udev" }, + { DEVICE_FOUND_UDEV_DB, "found-udev-db" }, + { DEVICE_FOUND_MOUNT, "found-mount" }, + { DEVICE_FOUND_SWAP, "found-swap" }, + {} +}; + +static int device_found_to_string_many(DeviceFound flags, char **ret) { + _cleanup_free_ char *s = NULL; + unsigned i; + + assert(ret); + + for (i = 0; device_found_map[i].name; i++) { + if ((flags & device_found_map[i].flag) != device_found_map[i].flag) + continue; + + if (!strextend_with_separator(&s, ",", device_found_map[i].name, NULL)) + return -ENOMEM; + } + + *ret = TAKE_PTR(s); + + return 0; +} + +static int device_found_from_string_many(const char *name, DeviceFound *ret) { + DeviceFound flags = 0; + int r; + + assert(ret); + + for (;;) { + _cleanup_free_ char *word = NULL; + DeviceFound f = 0; + unsigned i; + + r = extract_first_word(&name, &word, ",", 0); + if (r < 0) + return r; + if (r == 0) + break; + + for (i = 0; device_found_map[i].name; i++) + if (streq(word, device_found_map[i].name)) { + f = device_found_map[i].flag; + break; + } + + if (f == 0) + return -EINVAL; + + flags |= f; + } + + *ret = flags; + return 0; +} + static int device_serialize(Unit *u, FILE *f, FDSet *fds) { + _cleanup_free_ char *s = NULL; Device *d = DEVICE(u); assert(u); @@ -160,13 +223,16 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) { assert(fds); unit_serialize_item(u, f, "state", device_state_to_string(d->state)); - unit_serialize_item(u, f, "found", device_found_to_string(d->found)); + + (void) device_found_to_string_many(d->found, &s); + unit_serialize_item(u, f, "found", s); return 0; } static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { Device *d = DEVICE(u); + int r; assert(u); assert(key); @@ -195,13 +261,9 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value, d->deserialized_state = state; } else if (streq(key, "found")) { - DeviceFound found; - - found = device_found_from_string(value); - if (found < 0) + r = device_found_from_string_many(value, &d->found); + if (r < 0) log_unit_debug(u, "Failed to parse found value: %s", value); - else - d->found = found; } else log_unit_debug(u, "Unknown serialization key: %s", key); @@ -934,16 +996,6 @@ bool device_shall_be_bound_by(Unit *device, Unit *u) { return DEVICE(device)->bind_mounts; } -static const char* const device_found_table[] = { - [DEVICE_NOT_FOUND] = "not-found", - [DEVICE_FOUND_UDEV] = "found-udev", - [DEVICE_FOUND_UDEV_DB] = "found-udev-db", - [DEVICE_FOUND_MOUNT] = "found-mount", - [DEVICE_FOUND_SWAP] = "found-swap", -}; - -DEFINE_STRING_TABLE_LOOKUP(device_found, DeviceFound); - const UnitVTable device_vtable = { .object_size = sizeof(Device), .sections = diff --git a/src/core/device.h b/src/core/device.h index a96aa6d24d..d52700b66f 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -37,6 +37,3 @@ extern const UnitVTable device_vtable; int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now); bool device_shall_be_bound_by(Unit *device, Unit *u); - -const char *device_found_to_string(DeviceFound f) _const_; -DeviceFound device_found_from_string(const char *s) _pure_;