summaryrefslogtreecommitdiffstats
path: root/discover/user-event.c
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-09-05 14:21:23 +1000
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-09-08 14:26:27 +1000
commit1def8f21aecc41ac22652e7b8bd1f5bf7a4dae98 (patch)
tree34ce7ff6feff3181c4312b80aad4af391ba94277 /discover/user-event.c
parent4da0965a861bedd4332217c131abf399bc2b5a18 (diff)
downloadtalos-petitboot-1def8f21aecc41ac22652e7b8bd1f5bf7a4dae98.tar.gz
talos-petitboot-1def8f21aecc41ac22652e7b8bd1f5bf7a4dae98.zip
discover: Pass UUID to discover_device_create()
Currently discover_device_create() will search for existing discover devices by id to determine if a new device is required. However it is possible under some circumstances for distinct devices to have the same name. This is especially troublesome if the following network events are seen in network_handle_nlmsg(): - New interface, 'foo' with uuid x:x:x:x:x:x -> new discover device created with dev->device->id = 'foo' dev->uuid = x:x:x:x:x:x - New interface, 'foo' with uuid y:y:y:y:y:y -> existing device 'foo' found dev->uuid = y:y:y:y:y:y This can occur if an interface rename event arrives *after* an old name is reused, where temporarily Petitboot will see two distinct network interfaces with the same name. Now the two interfaces point to the same discover device, which can quickly result in a segfault if a 'remove' event occurs for one of the interfaces and the discover device is freed. To generally avoid this a 'uuid' parameter is added to discover_device_create(), which if present allows existing devices to be looked up by UUID rather than just their name. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Diffstat (limited to 'discover/user-event.c')
-rw-r--r--discover/user-event.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/discover/user-event.c b/discover/user-event.c
index 7ceddb1..20b2bea 100644
--- a/discover/user-event.c
+++ b/discover/user-event.c
@@ -385,7 +385,8 @@ static int user_event_dhcp(struct user_event *uev, struct event *event)
struct device_handler *handler = uev->handler;
struct discover_device *dev;
- dev = discover_device_create(handler, event->device);
+ dev = discover_device_create(handler, event_get_param(event, "mac"),
+ event->device);
device_handler_dhcp(handler, dev, event);
@@ -398,7 +399,10 @@ static int user_event_add(struct user_event *uev, struct event *event)
struct discover_context *ctx;
struct discover_device *dev;
- dev = discover_device_create(handler, event->device);
+ /* In case this is a network interface, try to refer to it by UUID */
+ dev = discover_device_create(handler, event_get_param(event, "mac"),
+ event->device);
+ dev->device->id = talloc_strdup(dev, event->device);
ctx = device_handler_discover_context_create(handler, dev);
parse_user_event(ctx, event);
@@ -414,8 +418,13 @@ static int user_event_remove(struct user_event *uev, struct event *event)
{
struct device_handler *handler = uev->handler;
struct discover_device *dev;
+ const char *mac = event_get_param(event, "mac");
+
+ if (mac)
+ dev = device_lookup_by_uuid(handler, event_get_param(event, "mac"));
+ else
+ dev = device_lookup_by_id(handler, event->device);
- dev = device_lookup_by_id(handler, event->device);
if (!dev)
return 0;
OpenPOWER on IntegriCloud