[OpenWrt-Devel] [PATCH v2] procd: delay inittab workers until the tty exists.
John Crispin
blogic at openwrt.org
Tue Jan 20 01:34:47 EST 2015
On 20/01/2015 01:21, Owen Kirby wrote:
> Add hotplug support for tty devices in /etc/inittab that are specified
> by the askfirst
> keyword so that terminals attached after boot time get console processes
> started.
>
> This was tested on an AT91 target using the gadget serial subsystem and
> on an WNDR3800
> with a USB serial adapter. One possible weirdness I encountered was that
> the baud rates
> and control modes sometimes need adjusting with a hotplug script after
> reconnecting
> the adapter. This is also only implemented for askfirst, but it might
> also make sense
> to do the same thing for respawn and askconsole.
>
i think it would be a lot simpler if you ...
* add a new cmd_handler inside hotplug/json_script called console or
spawn_console
* add a 2nd parameter to procd_inittab_run called char *tty that can be
NULL or act as a filter
* call procd_inittab_run with the 2nd parameter set from the new
json_script handler
* add a new if clause to package/system/procd/files/hotplug.json
> Signed-off-by: Owen Kirby <osk at exegin.com>
> ---
> inittab.c | 35 ++++++++++++++++++++++++++++++++---
> plug/hotplug.c | 40 +++++++++++++++++++++++++++++++++++-----
> plug/hotplug.h | 15 +++++++++++++++
> 3 files changed, 82 insertions(+), 8 deletions(-)
>
> diff --git a/inittab.c b/inittab.c
> index 623103d..c9310e5 100644
> --- a/inittab.c
> +++ b/inittab.c
> @@ -26,6 +26,7 @@
> #include <libubox/utils.h>
> #include <libubox/list.h>
>
> +#include "plug/hotplug.h"
> #include "utils/utils.h"
> #include "procd.h"
> #include "rcS.h"
> @@ -55,6 +56,7 @@ struct init_action {
>
> struct init_handler *handler;
> struct uloop_process proc;
> + struct hotplug_event event;
>
> int respawn;
> struct uloop_timeout tout;
> @@ -90,6 +92,29 @@ static int dev_exist(const char *dev)
> return (res != -1);
> }
>
> +static void dev_hotplug(struct hotplug_event *event, struct blob_attr
> *msg)
> +{
> + struct init_action *a = container_of(event, struct init_action,
> event);
> + char *action = hotplug_msg_find_var(msg, "ACTION");
> + char *subsystem = hotplug_msg_find_var(msg, "SUBSYSTEM");
> + char *devname = hotplug_msg_find_var(msg, "DEVNAME");
> +
> + if (!action || !subsystem || !devname)
> + return;
> + if (strcmp(subsystem, "tty") || strcmp(devname, a->id))
> + return;
> +
> + DEBUG(4, "inittab hotplug: ACTION=\"%s\", SUBSYSTEM=\"%s\",
> DEVNAME=\"%s\"\n",
> + action, subsystem, devname);
> + if (!strcmp(action, "add")) {
> + uloop_timeout_set(&a->tout, a->respawn);
> + }
> + else if (!strcmp(action, "remove")) {
> + uloop_process_delete(&a->proc);
> + uloop_timeout_cancel(&a->tout);
> + }
> +}
> +
> static void fork_worker(struct init_action *a)
> {
> int fd;
> @@ -130,7 +155,7 @@ static void child_exit(struct uloop_process *proc,
> int ret)
> struct init_action *a = container_of(proc, struct init_action, proc);
>
> DEBUG(4, "pid:%d\n", proc->pid);
> - uloop_timeout_set(&a->tout, a->respawn);
> + uloop_timeout_set(&a->tout, a->respawn);
> }
>
> static void respawn(struct uloop_timeout *tout)
> @@ -157,7 +182,7 @@ static void askfirst(struct init_action *a)
> {
> int i;
>
> - if (!dev_exist(a->id) || (console && !strcmp(console, a->id))) {
> + if (console && !strcmp(console, a->id)) {
> DEBUG(4, "Skipping %s\n", a->id);
> return;
> }
> @@ -168,8 +193,12 @@ static void askfirst(struct init_action *a)
> a->argv[0] = ask;
> a->respawn = 500;
>
> + a->event.cb = dev_hotplug;
> + hotplug_event_add(&a->event);
> +
> a->proc.cb = child_exit;
> - fork_worker(a);
> + if (dev_exist(a->id))
> + fork_worker(a);
> }
>
> static void askconsole(struct init_action *a)
> diff --git a/plug/hotplug.c b/plug/hotplug.c
> index 061833a..3aa87c0 100644
> --- a/plug/hotplug.c
> +++ b/plug/hotplug.c
> @@ -44,13 +44,14 @@ struct cmd_queue {
> };
>
> static LIST_HEAD(cmd_queue);
> +static LIST_HEAD(events);
> static struct uloop_process queue_proc;
> static struct uloop_timeout last_event;
> static struct blob_buf b;
> static char *rule_file;
> static struct blob_buf script;
>
> -static char *hotplug_msg_find_var(struct blob_attr *msg, const char *name)
> +char *hotplug_msg_find_var(struct blob_attr *msg, const char *name)
> {
> struct blob_attr *cur;
> int rem;
> @@ -393,24 +394,30 @@ static struct json_script_ctx jctx = {
> .handle_file = rule_handle_file,
> };
>
> -static void hotplug_handler_debug(struct blob_attr *data)
> +static void hotplug_handler_debug(struct hotplug_event *e, struct
> blob_attr *msg)
> {
> char *str;
>
> if (debug < 3)
> return;
>
> - str = blobmsg_format_json(data, true);
> + str = blobmsg_format_json(msg, true);
> DEBUG(3, "%s\n", str);
> free(str);
> }
>
> +static void hotplug_handler_script(struct hotplug_event *e, struct
> blob_attr *msg)
> +{
> + json_script_run(&jctx, rule_file, msg);
> +}
> +
> static void hotplug_handler(struct uloop_fd *u, unsigned int ev)
> {
> int i = 0;
> static char buf[4096];
> int len = recv(u->fd, buf, sizeof(buf), MSG_DONTWAIT);
> void *index;
> + struct hotplug_event *e, *tmp;
> if (len < 1)
> return;
>
> @@ -427,10 +434,16 @@ static void hotplug_handler(struct uloop_fd *u,
> unsigned int ev)
> i += l;
> }
> blobmsg_close_table(&b, index);
> - hotplug_handler_debug(b.head);
> - json_script_run(&jctx, rule_file, blob_data(b.head));
> + list_for_each_entry_safe(e, tmp, &events, list)
> + e->cb(e, blob_data(b.head));
> }
>
> +static struct hotplug_event script_event = {
> + .cb = hotplug_handler_script,
> +};
> +static struct hotplug_event debug_event = {
> + .cb = hotplug_handler_debug,
> +};
> static struct uloop_fd hotplug_fd = {
> .cb = hotplug_handler,
> };
> @@ -470,6 +483,8 @@ void hotplug(char *rules)
> json_script_init(&jctx);
> queue_proc.cb = queue_proc_cb;
> uloop_fd_add(&hotplug_fd, ULOOP_READ);
> + hotplug_event_add(&debug_event);
> + hotplug_event_add(&script_event);
> }
>
> int hotplug_run(char *rules)
> @@ -486,3 +501,18 @@ void hotplug_shutdown(void)
> uloop_fd_delete(&hotplug_fd);
> close(hotplug_fd.fd);
> }
> +
> +int hotplug_event_add(struct hotplug_event *e)
> +{
> + list_add_tail(&e->list, &events);
> +
> + return 0;
> +}
> +
> +int hotplug_event_delete(struct hotplug_event *e)
> +{
> + list_del(&e->list);
> +
> + return 0;
> +}
> +
> diff --git a/plug/hotplug.h b/plug/hotplug.h
> index 2a44442..4870476 100644
> --- a/plug/hotplug.h
> +++ b/plug/hotplug.h
> @@ -16,10 +16,25 @@
> #define __PROCD_HOTPLUG_H
>
> #include <libubox/uloop.h>
> +#include <libubox/list.h>
> +#include "../utils/utils.h"
> +
> +struct hotplug_event;
> +
> +typedef void (*hotplug_event_handler)(struct hotplug_event *event,
> struct blob_attr *msg);
> +
> +struct hotplug_event {
> + struct list_head list;
> +
> + hotplug_event_handler cb;
> +};
>
> void hotplug(char *rules);
> int hotplug_run(char *rules);
> void hotplug_shutdown(void);
> void hotplug_last_event(uloop_timeout_handler handler);
> +char *hotplug_msg_find_var(struct blob_attr *msg, const char *name);
> +int hotplug_event_add(struct hotplug_event *event);
> +int hotplug_event_delete(struct hotplug_event *event);
>
> #endif
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list