9 #include <sys/socket.h>
12 #include <talloc/talloc.h>
13 #include <waiter/waiter.h>
18 #include "pb-discover.h"
19 #include "device-handler.h"
21 #define PBOOT_DEVICE_SOCKET "/tmp/petitboot.udev"
23 #define max(a, b) ((a) > (b) ? (a) : (b))
26 struct device_handler *handler;
30 static void udev_print_event(struct event *event)
32 const char *action, *params[] = {
43 action = event->action == EVENT_ACTION_ADD ? "add" : "remove";
45 pb_log("udev %s event:\n", action);
46 pb_log("\tdevice: %s\n", event->device);
48 for (i = 0; params[i]; i++)
49 pb_log("\t%-12s => %s\n",
50 params[i], event_get_param(event, params[i]));
53 static void udev_handle_message(struct udev *udev, char *buf, int len)
58 event = talloc(udev, struct event);
59 event->type = EVENT_TYPE_UDEV;
63 result = event_parse_ad_message(event, buf, len);
68 udev_print_event(event);
69 device_handler_event(udev->handler, event);
75 static int udev_process(void *arg)
77 struct udev *udev = arg;
81 len = recvfrom(udev->socket, buf, sizeof(buf), 0, NULL, NULL);
84 pb_log("udev socket read failed: %s", strerror(errno));
91 udev_handle_message(udev, buf, len);
96 static int udev_destructor(void *p)
98 struct udev *udev = p;
100 if (udev->socket >= 0)
106 struct udev *udev_init(struct device_handler *handler)
108 struct sockaddr_un addr;
111 unlink(PBOOT_DEVICE_SOCKET);
113 udev = talloc(NULL, struct udev);
115 udev->handler = handler;
117 udev->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
118 if (udev->socket < 0) {
119 pb_log("Error creating udev socket: %s\n", strerror(errno));
123 talloc_set_destructor(udev, udev_destructor);
125 addr.sun_family = AF_UNIX;
126 strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET);
128 if (bind(udev->socket, (struct sockaddr *)&addr, sizeof(addr))) {
129 pb_log("Error binding udev socket: %s\n", strerror(errno));
133 waiter_register(udev->socket, WAIT_IN, udev_process, udev);
135 pb_log("%s: waiting on %s\n", __func__, PBOOT_DEVICE_SOCKET);
144 int udev_trigger(struct udev __attribute__((unused)) *udev)
146 int rc = system("/sbin/udevadm trigger --subsystem-match=block --action=add");
149 pb_log("udev trigger failed: %d (%d)\n", rc, WEXITSTATUS(rc));
151 return WEXITSTATUS(rc);
154 void udev_destroy(struct udev *udev)