9 #include <sys/socket.h>
10 #include <sys/types.h>
14 #include <talloc/talloc.h>
15 #include <waiter/waiter.h>
19 #include "pb-discover.h"
20 #include "device-handler.h"
22 #define PBOOT_DEVICE_SOCKET "/tmp/petitboot.udev"
24 #define max(a, b) ((a) > (b) ? (a) : (b))
27 struct device_handler *handler;
31 static void udev_print_event(struct event *event)
33 const char *action, *params[] = {
44 action = event->action == EVENT_ACTION_ADD ? "add" : "remove";
46 pb_log("udev %s event:\n", action);
47 pb_log("\tdevice: %s\n", event->device);
49 for (i = 0; params[i]; i++)
50 pb_log("\t%-12s => %s\n",
51 params[i], event_get_param(event, params[i]));
54 static void udev_handle_message(struct udev *udev, char *buf, int len)
60 event = talloc(udev, struct event);
61 event->type = EVENT_TYPE_UDEV;
65 result = event_parse_ad_message(event, buf, len);
70 udev_print_event(event);
72 /* Ignore ram, loop, and devices with no DEVNAME. */
74 devpath = event_get_param(event, "DEVPATH");
76 if (event_get_param(event, "DEVNAME")
77 && !strstr(devpath, "virtual/block/loop")
78 && !strstr(devpath, "virtual/block/ram")) {
79 device_handler_event(udev->handler, event);
87 static int udev_process(void *arg)
89 struct udev *udev = arg;
93 len = recvfrom(udev->socket, buf, sizeof(buf), 0, NULL, NULL);
96 pb_log("udev socket read failed: %s", strerror(errno));
103 udev_handle_message(udev, buf, len);
108 static int udev_destructor(void *p)
110 struct udev *udev = p;
112 if (udev->socket >= 0)
118 struct udev *udev_init(struct device_handler *handler)
120 struct sockaddr_un addr;
123 unlink(PBOOT_DEVICE_SOCKET);
125 udev = talloc(NULL, struct udev);
127 udev->handler = handler;
129 udev->socket = socket(PF_UNIX, SOCK_DGRAM, 0);
130 if (udev->socket < 0) {
131 pb_log("Error creating udev socket: %s\n", strerror(errno));
135 talloc_set_destructor(udev, udev_destructor);
137 memset(&addr, 0, sizeof addr);
138 addr.sun_family = AF_UNIX;
139 strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET);
141 if (bind(udev->socket, (struct sockaddr *)&addr, sizeof(addr))) {
142 pb_log("Error binding udev socket: %s\n", strerror(errno));
146 waiter_register(udev->socket, WAIT_IN, udev_process, udev);
148 pb_log("%s: waiting on %s\n", __func__, PBOOT_DEVICE_SOCKET);
157 int udev_trigger(struct udev __attribute__((unused)) *udev)
159 int rc = system("/sbin/udevadm trigger --subsystem-match=block --action=add");
162 pb_log("udev trigger failed: %d (%d)\n", rc, WEXITSTATUS(rc));
164 return WEXITSTATUS(rc);
167 void udev_destroy(struct udev *udev)