From: Felix Fietkau Date: Sun, 9 Oct 2011 15:54:40 +0000 (+0200) Subject: rename interface-hotplug.c to interface-event.c X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=commitdiff_plain;h=13cc3e23d947b0d1a19c08cd031becd2ed866264 rename interface-hotplug.c to interface-event.c --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 47a3509..461c07c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ ENDIF() SET(SOURCES main.c utils.c - interface.c interface-ip.c interface-hotplug.c + interface.c interface-ip.c interface-event.c proto.c proto-static.c proto-shell.c config.c device.c bridge.c vlan.c ubus.c) diff --git a/interface-event.c b/interface-event.c new file mode 100644 index 0000000..ba7405a --- /dev/null +++ b/interface-event.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include + +#include + +#include "netifd.h" +#include "interface.h" + +char *hotplug_cmd_path = DEFAULT_HOTPLUG_PATH; +static struct interface *current; +static enum interface_event current_ev; +static struct list_head pending = LIST_HEAD_INIT(pending); + +static void task_complete(struct uloop_process *proc, int ret); +static struct uloop_process task = { + .cb = task_complete, +}; + +static void +run_cmd(const char *ifname, bool up) +{ + char *argv[3]; + int pid; + + pid = fork(); + if (pid < 0) + return task_complete(NULL, -1); + + if (pid > 0) { + task.pid = pid; + uloop_process_add(&task); + return; + } + + setenv("ACTION", up ? "ifup" : "ifdown", 1); + setenv("INTERFACE", ifname, 1); + argv[0] = hotplug_cmd_path; + argv[1] = "network"; + argv[2] = NULL; + execvp(argv[0], argv); + exit(127); +} + +static void +call_hotplug(void) +{ + if (list_empty(&pending)) + return; + + current = list_first_entry(&pending, struct interface, hotplug_list); + current_ev = current->hotplug_ev; + list_del_init(¤t->hotplug_list); + + D(SYSTEM, "Call hotplug handler for interface '%s'\n", current->name); + run_cmd(current->name, current_ev == IFEV_UP); +} + +static void +task_complete(struct uloop_process *proc, int ret) +{ + if (current) + D(SYSTEM, "Complete hotplug handler for interface '%s'\n", current->name); + current = NULL; + call_hotplug(); +} + +/* + * Queue an interface for an up/down event. + * An interface can only have one event in the queue and one + * event waiting for completion. + * When queueing an event that is the same as the one waiting for + * completion, remove the interface from the queue + */ +void +interface_queue_event(struct interface *iface, enum interface_event ev) +{ + enum interface_event last_ev; + + D(SYSTEM, "Queue hotplug handler for interface '%s'\n", iface->name); + if (current == iface) + last_ev = current_ev; + else + last_ev = iface->hotplug_ev; + + iface->hotplug_ev = ev; + if (last_ev == ev && !list_empty(&iface->hotplug_list)) + list_del(&iface->hotplug_list); + else if (last_ev != ev && list_empty(&iface->hotplug_list)) + list_add(&iface->hotplug_list, &pending); + + if (!task.pending && !current) + call_hotplug(); +} + +void +interface_dequeue_event(struct interface *iface) +{ + if (iface == current) + current = NULL; + + if (!list_empty(&iface->hotplug_list)) + list_del_init(&iface->hotplug_list); +} diff --git a/interface-hotplug.c b/interface-hotplug.c deleted file mode 100644 index ba7405a..0000000 --- a/interface-hotplug.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "netifd.h" -#include "interface.h" - -char *hotplug_cmd_path = DEFAULT_HOTPLUG_PATH; -static struct interface *current; -static enum interface_event current_ev; -static struct list_head pending = LIST_HEAD_INIT(pending); - -static void task_complete(struct uloop_process *proc, int ret); -static struct uloop_process task = { - .cb = task_complete, -}; - -static void -run_cmd(const char *ifname, bool up) -{ - char *argv[3]; - int pid; - - pid = fork(); - if (pid < 0) - return task_complete(NULL, -1); - - if (pid > 0) { - task.pid = pid; - uloop_process_add(&task); - return; - } - - setenv("ACTION", up ? "ifup" : "ifdown", 1); - setenv("INTERFACE", ifname, 1); - argv[0] = hotplug_cmd_path; - argv[1] = "network"; - argv[2] = NULL; - execvp(argv[0], argv); - exit(127); -} - -static void -call_hotplug(void) -{ - if (list_empty(&pending)) - return; - - current = list_first_entry(&pending, struct interface, hotplug_list); - current_ev = current->hotplug_ev; - list_del_init(¤t->hotplug_list); - - D(SYSTEM, "Call hotplug handler for interface '%s'\n", current->name); - run_cmd(current->name, current_ev == IFEV_UP); -} - -static void -task_complete(struct uloop_process *proc, int ret) -{ - if (current) - D(SYSTEM, "Complete hotplug handler for interface '%s'\n", current->name); - current = NULL; - call_hotplug(); -} - -/* - * Queue an interface for an up/down event. - * An interface can only have one event in the queue and one - * event waiting for completion. - * When queueing an event that is the same as the one waiting for - * completion, remove the interface from the queue - */ -void -interface_queue_event(struct interface *iface, enum interface_event ev) -{ - enum interface_event last_ev; - - D(SYSTEM, "Queue hotplug handler for interface '%s'\n", iface->name); - if (current == iface) - last_ev = current_ev; - else - last_ev = iface->hotplug_ev; - - iface->hotplug_ev = ev; - if (last_ev == ev && !list_empty(&iface->hotplug_list)) - list_del(&iface->hotplug_list); - else if (last_ev != ev && list_empty(&iface->hotplug_list)) - list_add(&iface->hotplug_list, &pending); - - if (!task.pending && !current) - call_hotplug(); -} - -void -interface_dequeue_event(struct interface *iface) -{ - if (iface == current) - current = NULL; - - if (!list_empty(&iface->hotplug_list)) - list_del_init(&iface->hotplug_list); -}