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;
59 result = event_parse_ad_message(event, buf, len);
64 udev_print_event(event);
65 device_handler_event(udev->handler, event);
71 static int udev_process(void *arg)
73 struct udev *udev = arg;
77 len = recvfrom(udev->socket, buf, sizeof(buf), 0, NULL, NULL);
80 pb_log("udev socket read failed: %s", strerror(errno));
87 udev_handle_message(udev, buf, len);
92 static int udev_destructor(void *p)
94 struct udev *udev = p;
96 if (udev->socket >= 0)
102 struct udev *udev_init(struct device_handler *handler)
104 struct sockaddr_un addr;
107 unlink(PBOOT_DEVICE_SOCKET);
109 udev = talloc(NULL, struct udev);
111 udev->handler = handler;
113 udev->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
114 if (udev->socket < 0) {
115 pb_log("Error creating udev socket: %s\n", strerror(errno));
119 talloc_set_destructor(udev, udev_destructor);
121 addr.sun_family = AF_UNIX;
122 strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET);
124 if (bind(udev->socket, (struct sockaddr *)&addr, sizeof(addr))) {
125 pb_log("Error binding udev socket: %s\n", strerror(errno));
129 waiter_register(udev->socket, WAIT_IN, udev_process, udev);
131 pb_log("%s: waiting on %s\n", __func__, PBOOT_DEVICE_SOCKET);
140 int udev_trigger(struct udev __attribute__((unused)) *udev)
142 int rc = system("/sbin/udevadm trigger --subsystem-match=block --action=add");
145 pb_log("udev trigger failed: %d (%d)\n", rc, WEXITSTATUS(rc));
147 return WEXITSTATUS(rc);
150 void udev_destroy(struct udev *udev)