Make vip6-autod a daemon
Daniel Hokka Zakrisson [Mon, 30 Jul 2007 14:59:11 +0000 (14:59 +0000)]
src/vip6-autod.c
sysv/vip6-autod [new file with mode: 0755]

index 63e9368..8f9b2d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: vip6-autod.c,v 1.2 2007/07/26 19:00:23 dhozac Exp $
+ * $Id: vip6-autod.c,v 1.3 2007/07/26 23:08:00 dhozac Exp $
  * Copyright (c) 2007 The Trustees of Princeton University
  * Author: Daniel Hokka Zakrisson <daniel@hozac.com>
  *
@@ -7,6 +7,10 @@
  * version 2 or later.
  */
 
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -21,6 +25,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <signal.h>
+#include <syslog.h>
 
 #include <asm/types.h>
 /* not defined for gcc -ansi */
@@ -29,9 +34,8 @@ typedef int64_t __s64;
 #include <netlink/netlink.h>
 #include <netlink/route/addr.h>
 
-typedef unsigned int nid_t;
-typedef unsigned int xid_t;
 #include <vserver.h>
+#include "pathconfig.h"
 
 #define HAS_ADDRESS    0x01
 #define HAS_PREFIX     0x02
@@ -157,7 +161,7 @@ static void do_slices_autoconf(struct prefix_list *head)
                addr.type = vcNET_IPV6A;
                addr.count = 0;
                if (vc_net_remove(nid, &addr) == -1) {
-                       perror("vc_net_remove");
+                       syslog(LOG_ERR, "vc_net_remove: %s", strerror(errno));
                        continue;
                }
 
@@ -168,7 +172,7 @@ static void do_slices_autoconf(struct prefix_list *head)
                                char buf[64];
 
                                inet_ntop(AF_INET6, &i->address.addr, buf, sizeof(buf));
-                               printf("Address %s timed out.\n", buf);
+                               syslog(LOG_NOTICE, "Address %s timed out", buf);
 
                                if (i->next)
                                        i->next->prev = i->prev;
@@ -191,15 +195,15 @@ static void do_slices_autoconf(struct prefix_list *head)
                        addr.ip[2] = htonl((ntohl(addr.ip[2]) & 0xffffff00) | ((nid & 0x7f00) >> 7));
                        addr.ip[3] = htonl((ntohl(addr.ip[3]) & 0x00ffffff) | ((nid & 0xff) << 25));
                        if (vc_net_add(nid, &addr) == -1) {
-                               perror("vc_net_add");
+                               syslog(LOG_ERR, "vc_net_add: %s", strerror(errno));
                                exit(1);
                        }
                        if (add_address_to_interface(i->ifindex, (struct in6_addr *) addr.ip, i->prefix.prefix_len) == -1) {
-                               perror("add_address_to_interface");
+                               syslog(LOG_ERR, "add_address_to_interface: %s", strerror(errno));
                                exit(1);
                        }
                        if (add_nid_to_list(i, nid) == -1) {
-                               perror("add_nid_to_list");
+                               syslog(LOG_ERR, "add_nid_to_list: %s", strerror(errno));
                                exit(1);
                        }
 next:
@@ -307,7 +311,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg)
                struct nlattr *tb[PREFIX_MAX+1];
 
                if (nlmsg_parse(nlh, sizeof(struct prefixmsg), tb, PREFIX_MAX, prefix_policy) < 0) {
-                       printf("Failed to parse prefixmsg.\n");
+                       syslog(LOG_ERR, "Failed to parse prefixmsg");
                        return -1;
                }
 
@@ -325,7 +329,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg)
                struct nlattr *tb[IFA_MAX+1];
 
                if (nlmsg_parse(nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, addr_policy) < 0) {
-                       printf("Failed to parse ifaddrmsg.\n");
+                       syslog(LOG_ERR, "Failed to parse ifaddrmsg");
                        return -1;
                }
 
@@ -345,7 +349,7 @@ int handle_valid_msg(struct nl_msg *msg, void *arg)
 int handle_error_msg(struct sockaddr_nl *source, struct nlmsgerr *err,
                     void *arg)
 {
-       perror("Got an error");
+       syslog(LOG_ERR, "%s", strerror(err->error));
        return 0;
 }
 
@@ -365,12 +369,23 @@ void signal_handler(int signal)
        }
 }
 
+static int write_pidfile(const char *filename)
+{
+       FILE *fp;
+       fp = fopen(filename, "w");
+       if (!fp)
+               return -1;
+       fprintf(fp, "%d\n", getpid());
+       fclose(fp);
+       return 0;
+}
+
 int main(int argc, char *argv[])
 {
        struct nl_cb *cbs;
-
        head.prev = head.next = NULL;
-       signal(SIGUSR1, signal_handler);
+
+       openlog("vip6-autod", LOG_PERROR, LOG_DAEMON);
 
        handle = nl_handle_alloc_nondefault(NL_CB_VERBOSE);
        cbs = nl_handle_get_cb(handle);
@@ -381,12 +396,21 @@ int main(int argc, char *argv[])
 
        nl_join_groups(handle, RTMGRP_IPV6_PREFIX|RTMGRP_IPV6_IFADDR);
        if (nl_connect(handle, NETLINK_ROUTE) == -1) {
-               perror("nl_connect");
+               syslog(LOG_CRIT, "nl_connect: %s", strerror(errno));
                exit(1);
        }
 
+       if (daemon(0, 0) == -1)
+               return -1;
+
+       /* XXX .. here is a hack */
+       write_pidfile(DEFAULT_PKGSTATEDIR "/../vip6-autod.pid");
+
+       signal(SIGUSR1, signal_handler);
+
        while (nl_recvmsgs(handle, cbs) > 0);
 
        nl_close(handle);
+       closelog();
        return 0;
 }
diff --git a/sysv/vip6-autod b/sysv/vip6-autod
new file mode 100755 (executable)
index 0000000..b3dfe69
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/bash
+#
+# vip6-autod   assigns auto-discovered IPv6 addresses to guests
+#
+# chkconfig: 2345 99 01
+# description: starts vip6-autod
+
+: ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
+test -e "$UTIL_VSERVER_VARS" || {
+    echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2
+    exit 1
+}
+. "$UTIL_VSERVER_VARS"
+
+LOCKFILE=vip6-autod
+. "$_LIB_VSERVER_INIT_FUNCTIONS"
+
+prog="vip6-autod"
+
+function start()
+{
+    _beginResult $"Starting $prog"
+    $__SBINDIR/$prog
+    _endResult $?
+    local retval=$?
+    test "$retval" -ne 0 || touch "$lockfile"
+    return $retval
+}
+
+function stop()
+{
+    _beginResult $"Stopping $prog"
+    killall $prog
+    $_RM -f "$lockfile"
+}
+
+function restart()
+{
+    stop
+    start
+}
+
+case "$1" in
+    start|stop|restart)        $1;;
+    reload)            ;;
+    condrestart)
+       test -f $lockfile && restart || :
+       ;;
+    status)
+       status $prog
+       ;;
+    *)
+        echo "Usage: $0 {start|stop|reload|restart|condrestart|status}"
+       exit 2
+       ;;
+esac