X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fudev.c;h=40b9f638c5b9d51b0c2c432cbe4a223e1873dd96;hp=16d050e7702aae28de901f7ed969494804c3d129;hb=5e7c90eddd7ac2e4a3b05a7a5f6e29166edfa161;hpb=1a44c3bf2503b12c78c205676d903fbb05fb7ef0 diff --git a/discover/udev.c b/discover/udev.c index 16d050e..40b9f63 100644 --- a/discover/udev.c +++ b/discover/udev.c @@ -1,19 +1,22 @@ #define _GNU_SOURCE -#include +#include #include +#include +#include #include -#include -#include #include +#include #include +#include #include +#include +#include +#include "event.h" #include "udev.h" -#include "log.h" -#include "waiter.h" #include "pb-discover.h" #include "device-handler.h" @@ -26,115 +29,56 @@ struct udev { int socket; }; -static void parse_event_params(struct udev_event *event, char *buf, int len) -{ - int param_len, name_len, value_len; - struct param *param; - char *sep; - - for (; len > 0; len -= param_len + 1, buf += param_len + 1) { - - /* find the length of the whole parameter */ - param_len = strnlen(buf, len); - if (!param_len) { - /* multiple NULs? skip over */ - param_len = 1; - continue; - } - - /* find the separator */ - sep = memchr(buf, '=', param_len); - if (!sep) - continue; - - name_len = sep - buf; - value_len = param_len - name_len - 1; - - /* update the params array */ - event->params = talloc_realloc(event, event->params, - struct param, ++event->n_params); - param = &event->params[event->n_params - 1]; - - param->name = talloc_strndup(event, buf, name_len); - param->value = talloc_strndup(event, sep + 1, value_len); - } -} - -static const char *event_param(struct udev_event *event, const char *name) -{ - int i; - - for (i = 0; i < event->n_params; i++) - if (!strcasecmp(event->params[i].name, name)) - return event->params[i].value; - - return NULL; -} - -static void print_event(struct udev_event *event) +static void udev_print_event(struct event *event) { const char *action, *params[] = { - "DEVNAME", "ID_TYPE", "ID_BUS", "ID_FS_UUID", "ID_FS_LABEL", + "DEVNAME", + "DEVPATH", + "ID_TYPE", + "ID_BUS", + "ID_FS_UUID", + "ID_FS_LABEL", NULL, }; int i; - action = event->action == UDEV_ACTION_ADD ? "add" : "remove"; + action = event->action == EVENT_ACTION_ADD ? "add" : "remove"; pb_log("udev %s event:\n", action); - printf("\tdevice: %s\n", event->device); + pb_log("\tdevice: %s\n", event->device); for (i = 0; params[i]; i++) - printf("\t%-12s => %s\n", - params[i], event_param(event, params[i])); - + pb_log("\t%-12s => %s\n", + params[i], event_get_param(event, params[i])); } -static void handle_udev_message(struct udev *udev, char *buf, int len) +static void udev_handle_message(struct udev *udev, char *buf, int len) { - char *sep, *device; - enum udev_action action; - struct udev_event *event; - int device_len; - - /* we should see an @\0 at the head of the buffer */ - sep = strchr(buf, '@'); - if (!sep) - return; - - /* terminate the action string */ - *sep = '\0'; - len -= sep - buf + 1; + int result; + struct event *event; + const char *devpath; - if (!strcmp(buf, "add")) { - action = UDEV_ACTION_ADD; + event = talloc(udev, struct event); + event->type = EVENT_TYPE_UDEV; - } else if (!strcmp(buf, "remove")) { - action = UDEV_ACTION_REMOVE; + pb_log("%s\n", buf); - } else { - return; - } + result = event_parse_ad_message(event, buf, len); - /* initialise the device string */ - device = sep + 1; - device_len = strnlen(device, len); - if (!device_len) + if (result) return; - /* now we have an action and a device, we can construct an event */ - event = talloc(udev, struct udev_event); - event->action = action; - event->device = talloc_strndup(event, device, device_len); - event->n_params = 0; - event->params = NULL; + udev_print_event(event); - len -= device_len + 1; - parse_event_params(event, device + device_len + 1, len); + /* Ignore ram, loop, and devices with no DEVNAME. */ - print_event(event); + devpath = event_get_param(event, "DEVPATH"); - device_handler_event(udev->handler, event); + if (event_get_param(event, "DEVNAME") + && !strstr(devpath, "virtual/block/loop") + && !strstr(devpath, "virtual/block/ram")) { + device_handler_event(udev->handler, event); + } talloc_free(event); @@ -157,7 +101,7 @@ static int udev_process(void *arg) if (len == 0) return 0; - handle_udev_message(udev, buf, len); + udev_handle_message(udev, buf, len); return 0; } @@ -172,7 +116,7 @@ static int udev_destructor(void *p) return 0; } -struct udev *udev_init(struct device_handler *handler) +struct udev *udev_init(struct waitset *waitset, struct device_handler *handler) { struct sockaddr_un addr; struct udev *udev; @@ -191,6 +135,7 @@ struct udev *udev_init(struct device_handler *handler) talloc_set_destructor(udev, udev_destructor); + memset(&addr, 0, sizeof addr); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET); @@ -199,7 +144,9 @@ struct udev *udev_init(struct device_handler *handler) goto out_err; } - waiter_register(udev->socket, WAIT_IN, udev_process, udev); + waiter_register(waitset, udev->socket, WAIT_IN, udev_process, udev); + + pb_log("%s: waiting on %s\n", __func__, PBOOT_DEVICE_SOCKET); return udev; @@ -208,6 +155,25 @@ out_err: return NULL; } +int udev_trigger(struct udev __attribute__((unused)) *udev) +{ + const char *cmd[] = { + pb_system_apps.udevadm, + "trigger", + "--subsystem-match=block", + "--action=add", + NULL, + }; + int rc; + + rc = pb_run_cmd(cmd, 1, 0); + + if (rc) + pb_log("udev trigger failed: %d (%d)\n", rc, WEXITSTATUS(rc)); + + return WEXITSTATUS(rc); +} + void udev_destroy(struct udev *udev) { talloc_free(udev);