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[] = {
33 "DEVNAME", "ID_TYPE", "ID_BUS", "ID_FS_UUID", "ID_FS_LABEL",
38 action = event->action == EVENT_ACTION_ADD ? "add" : "remove";
40 pb_log("udev %s event:\n", action);
41 pb_log("\tdevice: %s\n", event->device);
43 for (i = 0; params[i]; i++)
44 pb_log("\t%-12s => %s\n",
45 params[i], event_get_param(event, params[i]));
49 static void udev_handle_message(struct udev *udev, char *buf, int len)
54 event = talloc(udev, struct event);
55 event->type = EVENT_TYPE_UDEV;
57 result = event_parse_ad_message(event, buf, len);
62 udev_print_event(event);
63 device_handler_event(udev->handler, event);
69 static int udev_process(void *arg)
71 struct udev *udev = arg;
75 len = recvfrom(udev->socket, buf, sizeof(buf), 0, NULL, NULL);
78 pb_log("udev socket read failed: %s", strerror(errno));
85 udev_handle_message(udev, buf, len);
90 static int udev_destructor(void *p)
92 struct udev *udev = p;
94 if (udev->socket >= 0)
100 struct udev *udev_init(struct device_handler *handler)
102 struct sockaddr_un addr;
105 unlink(PBOOT_DEVICE_SOCKET);
107 udev = talloc(NULL, struct udev);
109 udev->handler = handler;
111 udev->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
112 if (udev->socket < 0) {
113 pb_log("Error creating udev socket: %s\n", strerror(errno));
117 talloc_set_destructor(udev, udev_destructor);
119 addr.sun_family = AF_UNIX;
120 strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET);
122 if (bind(udev->socket, (struct sockaddr *)&addr, sizeof(addr))) {
123 pb_log("Error binding udev socket: %s\n", strerror(errno));
127 waiter_register(udev->socket, WAIT_IN, udev_process, udev);
129 pb_log("%s: waiting on %s\n", __func__, PBOOT_DEVICE_SOCKET);
138 int udev_trigger(struct udev __attribute__((unused)) *udev)
140 int rc = system("/sbin/udevadm trigger --subsystem-match=block");
143 pb_log("udev trigger failed: %d (%d)\n", rc, WEXITSTATUS(rc));
145 return WEXITSTATUS(rc);
148 void udev_destroy(struct udev *udev)