As per the previous commit, modify `ipconfig` to participate in the new `daemonize` protocol: use pthreads for the ipv6 router advertisement/solitication and ipv6 DHCP loop maintenance threads. Send an event to our parent when we exit or go into the background.
Change `ifconfig` to use daemonize and the new ipconfig facility. Change-Id: I60735d0427c5ad580522cd7e5ac210f8d2d5ae4b Signed-off-by: Dan Cross <[email protected]> --- kern/kfs/ifconfig | 2 +- tools/apps/ipconfig/Makefile | 2 +- tools/apps/ipconfig/ipconfig.h | 1 + tools/apps/ipconfig/ipv6.c | 67 ++++++++++++++------------ tools/apps/ipconfig/main.c | 105 +++++++++++++++++++++++++++-------------- 5 files changed, 109 insertions(+), 68 deletions(-) diff --git a/kern/kfs/ifconfig b/kern/kfs/ifconfig index 39734db..f99ca1f 100755 --- a/kern/kfs/ifconfig +++ b/kern/kfs/ifconfig @@ -58,7 +58,7 @@ then ipconfig -g $route ether /net/ether$NIC $me $mask else # No explicit configuration; use DHCP. - ipconfig ether /net/ether$NIC + daemonize /bin/ipconfig -S ether /net/ether$NIC fi ipconfig loopback /dev/null 127.0.0.1 else diff --git a/tools/apps/ipconfig/Makefile b/tools/apps/ipconfig/Makefile index e6aa54e..ffeabfb 100644 --- a/tools/apps/ipconfig/Makefile +++ b/tools/apps/ipconfig/Makefile @@ -4,7 +4,7 @@ SOURCES:= main.c ipv6.c XCC:= $(CROSS_COMPILE)gcc -LIBS:= -lndblib -liplib -lbenchutil +LIBS:= -lndblib -liplib -lbenchutil -lpthread PHONY:= all all: ipconfig diff --git a/tools/apps/ipconfig/ipconfig.h b/tools/apps/ipconfig/ipconfig.h index 12c3a75..996f246 100644 --- a/tools/apps/ipconfig/ipconfig.h +++ b/tools/apps/ipconfig/ipconfig.h @@ -112,6 +112,7 @@ void doadd(int); void doremove(void); void dounbind(void); void ea2lla(uint8_t *lla, uint8_t *ea); +void evexit(int rc); int getndb(void); void getoptions(uint8_t *p); int ip4cfg(void); diff --git a/tools/apps/ipconfig/ipv6.c b/tools/apps/ipconfig/ipv6.c index 237f884..b48d505 100644 --- a/tools/apps/ipconfig/ipv6.c +++ b/tools/apps/ipconfig/ipv6.c @@ -21,6 +21,7 @@ #include <ctype.h> #include <fcntl.h> +#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -314,14 +315,14 @@ int dialicmp(uint8_t *dst, int dport, int *ctlfd) cfd = open(name, O_RDWR); if (cfd < 0) { fprintf(stderr, "dialicmp: can't open %s: %r", name); - exit(-1); + evexit(-1); } n = snprintf(cmsg, sizeof(cmsg), "connect %R!%d!r %d", dst, dport, dport); m = write(cfd, cmsg, n); if (m < n) { fprintf(stderr, "dialicmp: can't write %s to %s: %r", cmsg, name); - exit(-1); + evexit(-1); } lseek(cfd, 0, 0); @@ -337,13 +338,13 @@ int dialicmp(uint8_t *dst, int dport, int *ctlfd) fd = open(name, O_RDWR); if (fd < 0) { fprintf(stderr, "dialicmp: can't open %s: %r", name); - exit(-1); + evexit(-1); } n = sizeof(hdrs) - 1; if (write(cfd, hdrs, n) < n) { fprintf(stderr, "dialicmp: can't write `%s' to %s: %r", hdrs, name); - exit(-1); + evexit(-1); } *ctlfd = cfd; return fd; @@ -362,7 +363,7 @@ int ip6cfg(int autoconf) // create link-local addr if (myetheraddr(ethaddr, conf.dev) < 0) { fprintf(stderr, "myetheraddr w/ %s failed: %r", conf.dev); - exit(-1); + evexit(-1); } ea2lla(conf.laddr, ethaddr); } @@ -626,30 +627,31 @@ recvrahost(uint8_t buf[], int pktlen) /* * daemon to receive router advertisements from routers */ +static void *recvra6thr(void *unused_arg); + void recvra6(void) { + pthread_t tid; + + pthread_create(&tid, NULL, recvra6thr, NULL); +} + +static void *recvra6thr(void *unused_arg) +{ int fd, cfd, n, sendrscnt, sleepfor; uint8_t buf[4096]; + (void)unused_arg; + /* TODO: why not v6allroutersL? */ fd = dialicmp(v6allnodesL, ICMP6_RA, &cfd); if (fd < 0) { fprintf(stderr, "can't open icmp_ra connection: %r"); - exit(-1); + evexit(-1); } sendrscnt = Maxv6rss; - switch (fork()) { - case -1: - fprintf(stderr, "can't fork: %r"); - exit(-1); - default: - return; - case 0: - break; - } - ralog("recvra6 on %s", conf.dev); sleepfor = jitter(); for (;;) { @@ -695,12 +697,14 @@ void recvra6(void) case IsHostNoRecv: ralog("recvra6: recvra off, quitting on %s", conf.dev); close(fd); - exit(0); + evexit(0); default: ralog("recvra6: unable to read router status on %s", conf.dev); break; } } + + return NULL; } /* @@ -831,32 +835,33 @@ void sendra(int fd, uint8_t *dst, int rlt) /* * daemon to send router advertisements to hosts */ +static void *sendra6thr(void *unused_arg); + void sendra6(void) { + pthread_t tid; + + pthread_create(&tid, NULL, sendra6thr, NULL); +} + +void *sendra6thr(void *unused_arg) +{ int fd, cfd, n, dstknown = 0, sendracnt, sleepfor, nquitmsgs; long lastra, now; uint8_t buf[4096], dst[IPaddrlen]; struct ipifc *ifc = NULL; + (void)unused_arg; + fd = dialicmp(v6allnodesL, ICMP6_RS, &cfd); if (fd < 0) { fprintf(stderr, "can't open icmp_rs connection: %r"); - exit(-1); + evexit(-1); } sendracnt = Maxv6initras; nquitmsgs = Maxv6finalras; - switch (fork()) { - case -1: - fprintf(stderr, "can't fork: %r"); - exit(-1); - default: - return; - case 0: - break; - } - ralog("sendra6 on %s", conf.dev); sleepfor = jitter(); for (;;) { @@ -883,7 +888,7 @@ void sendra6(void) continue; } else { ralog("sendra6: sendra off, quitting on %s", conf.dev); - exit(0); + evexit(0); } } @@ -909,6 +914,8 @@ void sendra6(void) else sendra(fd, v6allnodesL, 1); } + + return NULL; } void startra6(void) @@ -941,7 +948,7 @@ void doipv6(int what) switch (what) { default: fprintf(stderr, "unknown IPv6 verb\n"); - exit(-1); + evexit(-1); case Vaddpref6: issueadd6(&conf); break; diff --git a/tools/apps/ipconfig/main.c b/tools/apps/ipconfig/main.c index 172bd6b..db353bd 100644 --- a/tools/apps/ipconfig/main.c +++ b/tools/apps/ipconfig/main.c @@ -23,6 +23,7 @@ #include <errno.h> #include <fcntl.h> +#include <pthread.h> #include <stdlib.h> #include <string.h> #include <time.h> @@ -171,6 +172,7 @@ int nodhcpwatch; char optmagic[4] = {0x63, 0x82, 0x53, 0x63}; int plan9 = 1; int sendhostname; +int server; char *verbs[] = { [Vadd] "add", @@ -186,6 +188,22 @@ char *verbs[] = { [Vpkt] "pkt", }; +void evnotify(int rc) +{ + struct event_msg msg = { 0 }; + + msg.ev_type = EV_USER_IPI; + msg.ev_arg1 = rc; + sys_notify(getppid(), EV_USER_IPI, &msg); +} + +void evexit(int rc) +{ + if (server) + evnotify(rc); + exit(rc); +} + void usage(void) { fprintf(stderr, @@ -193,7 +211,7 @@ void usage(void) argv0, "[-6dDGnNOpPruX][-b baud][-c ctl]* [-g gw] [-h host][-m mtu]", "[-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask [raddr [fs [auth]]]]]"); - exit(1); + evexit(1); } void warning(char *fmt, ...) @@ -271,7 +289,7 @@ void parse6pref(int argc, char **argv) case 1: if (parseip(conf.v6pref, argv[0]) == -1) { fprintf(stderr, "bad address %s\n", argv[0]); - exit(-1); + evexit(-1); } break; } @@ -324,12 +342,13 @@ void parse6ra(int argc, char *argv[]) if (conf.maxraint < conf.minraint) { fprintf(stderr, "maxraint %d < minraint %d\n", conf.maxraint, conf.minraint); - exit(-1); + evexit(-1); } } void init(void) { + parlib_wants_to_be_mcp = FALSE; srand(lrand48()); if (register_printf_specifier('E', printf_ethaddr, printf_ethaddr_info) != 0) @@ -402,7 +421,7 @@ int parseargs(int argc, char *argv[]) case Vtree: case Vpkt: fprintf(stderr, "medium %s already specified\n", conf.type); - exit(-1); + evexit(-1); case Vadd: case Vremove: case Vunbind: @@ -439,7 +458,7 @@ int main(int argc, char *argv[]) init(); retry = 0; - while ((ch = getopt(argc, argv, "6b:c:dDg:h:m:nNo:OpPrux:X")) != -1) { + while ((ch = getopt(argc, argv, "6b:c:dDg:h:m:nNo:OpPrSux:X")) != -1) { switch (ch) { case '6': /* IPv6 auto config */ ipv6auto = 1; @@ -451,7 +470,7 @@ int main(int argc, char *argv[]) cp = malloc(sizeof(*cp)); if (cp == NULL) { fprintf(stderr, "%r\n"); - exit(1); + evexit(1); } *ctll = cp; ctll = &cp->next; @@ -501,6 +520,9 @@ int main(int argc, char *argv[]) case 'r': retry = 1; break; + case 'S': + server = 1; + break; case 'u': /* IPv6: duplicate neighbour disc. off */ dupl_disc = 0; break; @@ -535,7 +557,12 @@ int main(int argc, char *argv[]) break; } - return 0; + if (server) { + evnotify(0); + uthread_sleep_forever(); + } + + evexit(0); } int havendb(char *net) @@ -569,13 +596,13 @@ void doadd(int retry) if (ip6cfg(ipv6auto) < 0) { fprintf(stderr, "can't automatically start IPv6 on %s\n", conf.dev); - exit(-1); + evexit(-1); } } else if (validip(conf.laddr) && !isv4(conf.laddr)) { if (ip6cfg(0) < 0) fprintf(stderr, "can't start IPv6 on %s, address %R\n", conf.dev, conf.laddr); - exit(-1); + evexit(-1); } if (!validip(conf.laddr)) { @@ -598,14 +625,14 @@ void doadd(int retry) return; } fprintf(stderr, "no success with DHCP\n"); - exit(-1); + evexit(-1); } if (!noconfig) { if (ip4cfg() < 0) { fprintf(stderr, "can't start ip\n"); - exit(-1); + evexit(-1); } if (dodhcp && conf.lease != Lforever) dhcpwatch(0); @@ -628,7 +655,7 @@ void doremove(void) if (!validip(conf.laddr)) { fprintf(stderr, "remove requires an address\n"); - exit(-1); + evexit(-1); } ifc = readipifc(conf.mpoint, ifc, -1); for (nifc = ifc; nifc != NULL; nifc = nifc->next) { @@ -729,7 +756,7 @@ void lookforip(char *net) snprintf(proto, sizeof(proto), "%s/ipifc", net); if (stat(proto, &s) < 0) { fprintf(stderr, "no ip stack bound onto %s\n", net); - exit(-1); + evexit(-1); } } @@ -748,13 +775,13 @@ void controldevice(void) fd = open(ctlfile, O_RDWR); if (fd < 0) { fprintf(stderr, "can't open %s\n", ctlfile); - exit(-1); + evexit(-1); } for (cp = firstctl; cp != NULL; cp = cp->next) { if (write(fd, cp->ctl, strlen(cp->ctl)) < 0) { fprintf(stderr, "ctl message %s: %r\n", cp->ctl); - exit(-1); + evexit(-1); } lseek(fd, 0, 0); } @@ -771,14 +798,14 @@ void binddevice(void) conf.cfd = open(buf, O_RDWR); if (conf.cfd < 0) { fprintf(stderr, "opening %s/ipifc/clone: %r\n", conf.mpoint); - exit(-1); + evexit(-1); } /* specify medium as ethernet, bind the interface to it */ snprintf(buf, sizeof(buf), "bind %s %s", conf.type, conf.dev); if (write(conf.cfd, buf, strlen(buf)) != strlen(buf)) { fprintf(stderr, "%s: bind %s %s: %r\n", buf, conf.type, conf.dev); - exit(-1); + evexit(-1); } } else { /* open the old interface */ @@ -786,7 +813,7 @@ void binddevice(void) conf.cfd = open(buf, O_RDWR); if (conf.cfd < 0) { fprintf(stderr, "open %s: %r\n", buf); - exit(-1); + evexit(-1); } } } @@ -880,7 +907,7 @@ void dhcpquery(int needconfig, int startstate) break; default: fprintf(stderr, "internal error 0\n"); - exit(-1); + evexit(-1); } conf.resend = 0; conf.timeout = time(0) + 4; @@ -906,20 +933,24 @@ enum { Maxsleep = 450, }; +static void *dhcpwatchthr(void *arg); + void dhcpwatch(int needconfig) { - int secs, s; - uint32_t t; + pthread_t tid; + intptr_t nc = needconfig; if (nodhcpwatch) return; - switch (fork()) { - default: - return; - case 0: - break; - } + pthread_create(&tid, NULL, dhcpwatchthr, (void *)nc); +} + +static void *dhcpwatchthr(void *arg) +{ + int secs, s; + uint32_t t; + int needconfig = (arg == NULL); // procsetname("dhcpwatch"); /* keep trying to renew the lease */ @@ -960,7 +991,7 @@ void dhcpwatch(int needconfig) if (needconfig && conf.state == Sbound) { if (ip4cfg() < 0) { fprintf(stderr, "can't start ip: %r\n"); - exit(-1); + evexit(-1); } needconfig = 0; /* @@ -973,6 +1004,8 @@ void dhcpwatch(int needconfig) } } } + + return NULL; } int dhcptimer(void) @@ -986,7 +1019,7 @@ int dhcptimer(void) switch (conf.state) { default: fprintf(stderr, "dhcptimer: unknown state %d\n", conf.state); - exit(-1); + evexit(-1); case Sinit: case Sbound: break; @@ -1039,7 +1072,7 @@ void dhcpsend(int type) switch (type) { default: fprintf(stderr, "dhcpsend: unknown message type: %d\n", type); - exit(-1); + evexit(-1); case Discover: ipmove(up->raddr, IPv4bcast); /* broadcast */ if (*conf.hostname && sendhostname) @@ -1316,7 +1349,7 @@ int openlisten(void) for (n = 0; (cfd = announce9(data, devdir, 0)) < 0; n++) { if (!noconfig) { fprintf(stderr, "can't announce for dhcp: %r\n"); - exit(-1); + evexit(-1); } /* might be another client - wait and try again */ @@ -1328,14 +1361,14 @@ int openlisten(void) if (write(cfd, "headers", strlen("headers")) < 0) { fprintf(stderr, "can't set header mode: %r\n"); - exit(-1); + evexit(-1); } sprintf(data, "%s/data", devdir); fd = open(data, O_RDWR); if (fd < 0) { fprintf(stderr, "open %s: %r\n", data); - exit(-1); + evexit(-1); } close(cfd); return fd; @@ -1786,12 +1819,12 @@ void ndbconfig(void) db = ndbopen(0); if (db == NULL) { fprintf(stderr, "can't open ndb: %r\n"); - exit(-1); + evexit(-1); } if ((strcmp(conf.type, "ether") != 0 && strcmp(conf.type, "gbe") != 0) || myetheraddr(conf.hwa, conf.dev) != 0) { fprintf(stderr, "can't read hardware address\n"); - exit(-1); + evexit(-1); } snprintf(etheraddr, sizeof(etheraddr), "%E", conf.hwa); nattr = 0; @@ -1828,7 +1861,7 @@ void ndbconfig(void) ndbfree(t); if (!validip(conf.laddr)) { fprintf(stderr, "address not found in ndb\n"); - exit(-1); + evexit(-1); } } -- 2.8.0.rc3.226.g39d4020 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
