summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2009-04-12 15:11:54 +0000
committerJeremy Kerr <jk@ozlabs.org>2009-06-30 15:29:22 +0800
commitfbb2f7a20e5ac7b6d9f578fdb3538fad4310c472 (patch)
tree5ae45fc83b13c1143439636d3661361a04eac2a7
parentd7ce19907ff585e7fb6b950a40bd638d49c96a27 (diff)
downloadtalos-petitboot-fbb2f7a20e5ac7b6d9f578fdb3538fad4310c472.tar.gz
talos-petitboot-fbb2f7a20e5ac7b6d9f578fdb3538fad4310c472.zip
Add discover user event
Add a gereric event interface to pb-discover. Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
-rw-r--r--discover/device-handler.c58
-rw-r--r--discover/event-parser.c55
-rw-r--r--discover/parser.h1
-rw-r--r--discover/pb-discover.c7
-rw-r--r--discover/user-event.c175
-rw-r--r--discover/user-event.h33
-rw-r--r--rules.mk7
7 files changed, 333 insertions, 3 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c
index 908409c..c72390b 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -335,6 +335,52 @@ static int handle_remove_udev_event(struct device_handler *handler,
return 0;
}
+static int handle_add_user_event(struct device_handler *handler,
+ struct event *event)
+{
+ struct device *device;
+
+ assert(event->device);
+
+ device = talloc_zero(handler, struct device);
+
+ if (!device)
+ goto fail;
+
+ device->id = talloc_strdup(device, event->device);
+ list_init(&device->boot_options);
+
+ parse_user_event(device, event);
+
+ discover_server_notify_add(handler->server, device);
+
+ /* add device to handler device array */
+ device_handler_add(handler, device);
+
+ return 0;
+
+fail:
+ talloc_free(device);
+ return 0;
+}
+
+static int handle_remove_user_event(struct device_handler *handler,
+ struct event *event)
+{
+ struct device *device = device_handler_find(handler, event->device);
+
+ if (!device)
+ return 0;
+
+ discover_server_notify_remove(handler->server, device);
+
+ /* remove device from handler device array */
+ device_handler_remove(handler, device);
+
+ talloc_free(device);
+ return 0;
+}
+
int device_handler_event(struct device_handler *handler,
struct event *event)
{
@@ -356,6 +402,18 @@ int device_handler_event(struct device_handler *handler,
}
break;
case EVENT_TYPE_USER:
+ switch (event->action) {
+ case EVENT_ACTION_ADD:
+ rc = handle_add_user_event(handler, event);
+ break;
+ case EVENT_ACTION_REMOVE:
+ rc = handle_remove_user_event(handler, event);
+ break;
+ default:
+ pb_log("%s unknown action: %d\n", __func__,
+ event->action);
+ break;
+ }
break;
default:
pb_log("%s unknown type: %d\n", __func__, event->type);
diff --git a/discover/event-parser.c b/discover/event-parser.c
new file mode 100644
index 0000000..0cfda9a
--- /dev/null
+++ b/discover/event-parser.c
@@ -0,0 +1,55 @@
+#define _GNU_SOURCE
+
+#include <assert.h>
+
+#include "log/log.h"
+#include "talloc/talloc.h"
+#include "event.h"
+#include "parser-utils.h"
+
+int parse_user_event(struct device *device, struct event *event)
+{
+ struct boot_option *opt;
+ const char *p;
+
+ opt = talloc_zero(device, struct boot_option);
+
+ if (!opt)
+ goto fail;
+
+ p = event_get_param(event, "name");
+
+ if (!p) {
+ pb_log("%s: no name found\n", __func__);
+ goto fail;
+ }
+
+ opt->id = talloc_asprintf(opt, "%s#%s", device->id, p);
+ opt->name = talloc_strdup(opt, p);
+
+ p = event_get_param(event, "image");
+ assert(p);
+
+ if (!p) {
+ pb_log("%s: no image found\n", __func__);
+ goto fail;
+ }
+
+ opt->boot_image_file = talloc_strdup(opt, p);
+
+ p = event_get_param(event, "args");
+ assert(p);
+
+ opt->boot_args = talloc_strdup(opt, p);
+
+ opt->description = talloc_asprintf(opt, "%s %s", opt->boot_image_file,
+ opt->boot_args);
+
+ device_add_boot_option(device, opt);
+
+ return 0;
+
+fail:
+ talloc_free(opt);
+ return -1;
+}
diff --git a/discover/parser.h b/discover/parser.h
index ff86578..1b88831 100644
--- a/discover/parser.h
+++ b/discover/parser.h
@@ -23,5 +23,6 @@ enum generic_icon_type {
void parser_init(void);
void iterate_parsers(struct discover_context *ctx);
+int parse_user_event(struct device *device, struct event *event);
#endif /* _PARSER_H */
diff --git a/discover/pb-discover.c b/discover/pb-discover.c
index 4d61814..d7ea0ca 100644
--- a/discover/pb-discover.c
+++ b/discover/pb-discover.c
@@ -7,6 +7,7 @@
#include <log/log.h>
#include "udev.h"
+#include "user-event.h"
#include "discover-server.h"
#include "device-handler.h"
@@ -22,6 +23,7 @@ int main(void)
struct device_handler *handler;
struct discover_server *server;
struct udev *udev;
+ struct user_event *uev;
FILE *log;
log = fopen("pb-discover.log", "a");
@@ -52,7 +54,12 @@ int main(void)
if (!udev)
return EXIT_FAILURE;
+ uev = user_event_init(handler);
+ if (!uev)
+ return EXIT_FAILURE;
+
udev_trigger(udev);
+ user_event_trigger(uev);
for (running = 1; running;) {
if (waiter_poll())
diff --git a/discover/user-event.c b/discover/user-event.c
new file mode 100644
index 0000000..afc4c43
--- /dev/null
+++ b/discover/user-event.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009 Sony Computer Entertainment Inc.
+ * Copyright 2009 Sony Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include <log/log.h>
+#include <talloc/talloc.h>
+#include <waiter/waiter.h>
+
+#include "device-handler.h"
+#include "event.h"
+#include "user-event.h"
+
+
+struct user_event {
+ struct device_handler *handler;
+ int socket;
+};
+
+static void user_event_print_event(struct event __attribute__((unused)) *event)
+{
+ const char *action, *params[] = {
+ "name", "image", "args",
+ NULL,
+ };
+ int i;
+
+ action = event->action == EVENT_ACTION_ADD ? "add" : "remove";
+
+ pb_log("user_event %s event:\n", action);
+ pb_log("\tdevice: %s\n", event->device);
+
+ for (i = 0; params[i]; i++)
+ pb_log("\t%-12s => %s\n",
+ params[i], event_get_param(event, params[i]));
+}
+
+static void user_event_handle_message(struct user_event *uev, char *buf,
+ int len)
+{
+ int result;
+ struct event *event;
+
+ event = talloc(uev, struct event);
+ event->type = EVENT_TYPE_USER;
+
+ result = event_parse_ad_message(event, buf, len);
+
+ if (result)
+ return;
+
+ user_event_print_event(event);
+ device_handler_event(uev->handler, event);
+ talloc_free(event);
+
+ return;
+}
+
+static int user_event_process(void *arg)
+{
+ struct user_event *uev = arg;
+ char buf[PBOOT_USER_EVENT_SIZE];
+ int len;
+
+ len = recvfrom(uev->socket, buf, sizeof(buf), 0, NULL, NULL);
+
+ if (len < 0) {
+ pb_log("%s: socket read failed: %s", __func__, strerror(errno));
+ return 0;
+ }
+
+ if (len == 0) {
+ pb_log("%s: empty", __func__);
+ return 0;
+ }
+
+ pb_log("%s: %u bytes\n", __func__, len);
+
+ user_event_handle_message(uev, buf, len);
+
+ return 0;
+}
+
+static int user_event_destructor(void *arg)
+{
+ struct user_event *uev = arg;
+
+ pb_log("%s\n", __func__);
+
+ if (uev->socket >= 0)
+ close(uev->socket);
+
+ return 0;
+}
+
+struct user_event *user_event_init(struct device_handler *handler)
+{
+ struct sockaddr_un addr;
+ struct user_event *uev;
+
+ unlink(PBOOT_USER_EVENT_SOCKET);
+
+ uev = talloc(NULL, struct user_event);
+
+ uev->handler = handler;
+
+ uev->socket = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (uev->socket < 0) {
+ pb_log("%s: Error creating event handler socket: %s\n",
+ __func__, strerror(errno));
+ goto out_err;
+ }
+
+ talloc_set_destructor(uev, user_event_destructor);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, PBOOT_USER_EVENT_SOCKET);
+
+ if (bind(uev->socket, (struct sockaddr *)&addr, sizeof(addr))) {
+ pb_log("Error binding event handler socket: %s\n",
+ strerror(errno));
+ }
+
+ waiter_register(uev->socket, WAIT_IN, user_event_process, uev);
+
+ pb_log("%s: waiting on %s\n", __func__, PBOOT_USER_EVENT_SOCKET);
+
+ return uev;
+
+out_err:
+ talloc_free(uev);
+ return NULL;
+}
+
+/**
+ * user_event_trigger - Trigger known user events
+ *
+ * SIGUSR1 causes udhcpc to renew the current lease or obtain a new lease.
+ */
+
+void user_event_trigger(struct user_event __attribute__((unused)) *uev)
+{
+ /* FIXME: todo */
+}
+
+void user_event_destroy(struct user_event *uev)
+{
+ talloc_free(uev);
+}
diff --git a/discover/user-event.h b/discover/user-event.h
new file mode 100644
index 0000000..e134d0c
--- /dev/null
+++ b/discover/user-event.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2009 Sony Computer Entertainment Inc.
+ * Copyright 2009 Sony Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#if !defined(_PB_DISCOVER_USER_EVENT_H)
+#define _PB_DISCOVER_USER_EVENT_H
+
+#include "device-handler.h"
+
+#define PBOOT_USER_EVENT_SOCKET "/tmp/petitboot.ev"
+#define PBOOT_USER_EVENT_SIZE (1 * 1024)
+
+struct user_event;
+
+struct user_event *user_event_init(struct device_handler *handler);
+void user_event_trigger(struct user_event *uev);
+void user_event_destroy(struct user_event *uev);
+
+#endif
diff --git a/rules.mk b/rules.mk
index 1c91661..ff807e4 100644
--- a/rules.mk
+++ b/rules.mk
@@ -17,7 +17,7 @@ parser_test = test/parser-test
# install targets and components
daemons = $(pb_discover)
-parsers = kboot yaboot
+parsers = event kboot yaboot
uis = $(pb_test)
tests = $(parser_test)
@@ -40,8 +40,9 @@ waiter_objs = lib/waiter/waiter.o
# daemon objs
parser_objs = discover/parser.o discover/parser-conf.o discover/paths.o \
$(foreach p, $(parsers), discover/$(p)-parser.o)
-discover_objs = discover/event.o discover/udev.o discover/discover-server.o \
- discover/device-handler.o discover/paths.o discover/parser-utils.o
+discover_objs = discover/event.o discover/user-event.o discover/udev.o \
+ discover/discover-server.o discover/device-handler.o discover/paths.o \
+ discover/parser-utils.o
# client objs
ui_common_objs = ui/common/discover-client.o ui/common/loader.o \
OpenPOWER on IntegriCloud