diff -ruN -x .svn ucarp-1.5.2.orig/install-sh ucarp-1.5.2/install-sh --- ucarp-1.5.2.orig/install-sh 2009-03-11 14:29:35.000000000 -0700 +++ ucarp-1.5.2/install-sh 2010-02-03 10:42:15.231647097 -0800 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/bash # install - install a program, script, or datafile scriptversion=2005-05-14.22 diff -ruN -x .svn ucarp-1.5.2.orig/src/carp.c ucarp-1.5.2/src/carp.c --- ucarp-1.5.2.orig/src/carp.c 2010-01-31 13:59:12.000000000 -0800 +++ ucarp-1.5.2/src/carp.c 2010-02-03 10:42:14.377471307 -0800 @@ -48,6 +48,24 @@ # include #endif +#if defined __sun || defined __sun__ /* MARCO */ +#include "check_zone.h" + +#if ! defined timersub +/* from the linux /usr/include/sys/time.h */ +# define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) + +#endif +#endif + static void carp_set_state(struct carp_softc *sc, int state) { if ((int) sc->sc_state == state) { @@ -197,6 +215,7 @@ #ifdef DEBUG logfile(LOG_DEBUG, "-> carp_send_ad()"); #endif + advbase = sc->sc_advbase; if (carp_suppress_preempt == 0 || sc->sc_advskew > CARP_BULK_UPDATE_MIN_DELAY) { @@ -246,7 +265,7 @@ ch.carp_cksum = 0; sum = cksum(&ch, sizeof ch); ch.carp_cksum = htons(sum); - + eh.ether_shost[0] = 0x00; eh.ether_shost[1] = 0x00; eh.ether_shost[2] = 0x5e; @@ -705,6 +724,9 @@ int fd; int nfds; int iface_running = 1; +#if defined __sun || defined __sun__ /* MARCO, my zone support;-) */ + int zone_running = 1; +#endif int poll_sleep_time; struct timeval time_until_advert; @@ -804,18 +826,18 @@ break; } if ((iface.ifr_flags & IFF_RUNNING) == 0) { - if (ignoreifstate == 0) { - carp_set_state(&sc, BACKUP); - sc.sc_ad_tmo.tv_sec = 0; - sc.sc_ad_tmo.tv_usec = 0; - sc.sc_md_tmo.tv_sec = 0; - sc.sc_md6_tmo.tv_usec = 0; - if (iface_running) { - iface_running = 0; - } - sleep(SECONDS_TO_WAIT_AFTER_INTERFACE_IS_DOWN); - continue; - } + if (ignoreifstate == 0) { + carp_set_state(&sc, BACKUP); + sc.sc_ad_tmo.tv_sec = 0; + sc.sc_ad_tmo.tv_usec = 0; + sc.sc_md_tmo.tv_sec = 0; + sc.sc_md6_tmo.tv_usec = 0; + if (iface_running) { + iface_running = 0; + } + sleep(SECONDS_TO_WAIT_AFTER_INTERFACE_IS_DOWN); + continue; + } } else { if (!iface_running) { iface_running = 1; @@ -823,6 +845,34 @@ } } #endif +#if defined __sun || defined __sun__ /* MARCO, my zone support;-) */ + if (zonename != NULL) { + int z_stat = check_zone(zonename); + + logfile(LOG_DEBUG, "check_zone(%s) -> z_stat= %d", zonename, z_stat); + + if (z_stat != 0) { + carp_set_state(&sc, BACKUP); + sc.sc_ad_tmo.tv_sec = 0; + sc.sc_ad_tmo.tv_usec = 0; + sc.sc_md_tmo.tv_sec = 0; + sc.sc_md6_tmo.tv_usec = 0; + + if (zone_running) { + zone_running = 0; + } + + sleep(SECONDS_TO_WAIT_AFTER_INTERFACE_IS_DOWN); + continue; + } + else { + if (!zone_running) { + zone_running = 1; + carp_setrun(&sc, 0); + } + } + } +#endif if (received_signal != 0) { int flag = received_signal; diff -ruN -x .svn ucarp-1.5.2.orig/src/check_zone.c ucarp-1.5.2/src/check_zone.c --- ucarp-1.5.2.orig/src/check_zone.c 1969-12-31 16:00:00.000000000 -0800 +++ ucarp-1.5.2/src/check_zone.c 2010-02-03 10:42:14.374595592 -0800 @@ -0,0 +1,86 @@ +#include +#include "ucarp.h" + +#include +#include +#include +#include +#include + +#if defined __sun || defined __sun__ + +int check_zone(const char *zonename) { + int new_fds[2]; + int pid; + + if (pipe(new_fds) < 0) { + logfile(LOG_ERR, "Can't open pipe for zone check: %s", strerror(errno)); + return -1; + } + + pid = fork(); + + if (pid == 0) { + if (dup2(new_fds[1], 1) < 0) { + exit(-1); + } + + if (close(2) < 0) { + exit(-1); + } + + if (execl("/usr/sbin/zoneadm", "/usr/sbin/zoneadm", "-z", zonename, + "list", "-p", NULL) < 0) { + exit(-1); + } + } + else if (pid < 0) { + logfile(LOG_ERR, "fork failed: %s", strerror(errno)); + return -1; + } + else { + char buf[4096]; + int len, new_len; + int stat_loc = 0; + int ret = -1; + + if (close(new_fds[1]) < 0) { + logfile(LOG_ERR, "Can't close `write-side' of pipe: %s", strerror(errno)); + } + + len = 0; + while (len < 25 && (new_len = read(new_fds[0], buf + len, 4096 - len)) > 0) { + len += new_len; + } + + if (close(new_fds[0]) < 0) { + logfile(LOG_ERR, "Can't close `read-side' of pipe: %s", strerror(errno)); + } + + if (len > 0) { + char *z_id, *z_name, *z_state; + + if ((z_id = strtok(buf, ":")) != NULL) { + if ((z_name = strtok(NULL, ":")) != NULL && strcmp(z_name, zonename) == 0) { + if ((z_state = strtok(NULL, ":")) != NULL && strcmp(z_state, "running") == 0) { + ret = 0; + } + } + } + } + + if (waitpid(pid, &stat_loc, 0) < 0) { + logfile(LOG_ERR, "waitpid failed: %s", strerror(errno)); + ret = -1; + } + + if (WEXITSTATUS(stat_loc) != 0) { + logfile(LOG_ERR, "zone check fork/exec failed with exit %d", WEXITSTATUS(stat_loc)); + ret = -1; + } + + return ret; + } +} + +#endif diff -ruN -x .svn ucarp-1.5.2.orig/src/check_zone.h ucarp-1.5.2/src/check_zone.h --- ucarp-1.5.2.orig/src/check_zone.h 1969-12-31 16:00:00.000000000 -0800 +++ ucarp-1.5.2/src/check_zone.h 2010-02-03 10:42:14.376029895 -0800 @@ -0,0 +1,8 @@ +#ifndef __CHECK_ZONE_H__ +#define __CHECK_ZONE_H__ 1 + +#if defined __sun || defined __sun__ +int check_zone(const char *zonename); +#endif + +#endif diff -ruN -x .svn ucarp-1.5.2.orig/src/daemonize.c ucarp-1.5.2/src/daemonize.c --- ucarp-1.5.2.orig/src/daemonize.c 2007-07-04 06:34:59.000000000 -0700 +++ ucarp-1.5.2/src/daemonize.c 2010-02-03 17:54:34.521458828 -0800 @@ -74,6 +74,29 @@ _("Unable to detach: /dev/null can't be duplicated")); _exit(EXIT_FAILURE); } +#if defined __sun || defined __sun__ /* MARCO */ + if (pidfile != NULL) { + int pid_fd; + char pid_buf[36]; + + if ((pid_fd = open(pidfile, O_WRONLY | O_CREAT)) < 0) { + logfile(LOG_ERR, "Unable to open pidfile %.256s: %s", pidfile, strerror(errno)); + _exit(EXIT_FAILURE); + } + + snprintf(pid_buf, 32, "%d\n", (int)getpid()); + + if (write(pid_fd, pid_buf, strlen(pid_buf)) != strlen(pid_buf)) { + logfile(LOG_ERR, "Unable to write to pidfile %.256s: %s", pidfile, strerror(errno)); + _exit(EXIT_FAILURE); + } + + if (close(pid_fd) != 0) { + logfile(LOG_ERR, "Unable to close pidfile %.256s: %s", pidfile, strerror(errno)); + _exit(EXIT_FAILURE); + } + } +#endif } } diff -ruN -x .svn ucarp-1.5.2.orig/src/fillmac.c ucarp-1.5.2/src/fillmac.c --- ucarp-1.5.2.orig/src/fillmac.c 2007-07-04 06:34:59.000000000 -0700 +++ ucarp-1.5.2/src/fillmac.c 2010-02-03 10:42:14.379259103 -0800 @@ -109,7 +109,7 @@ struct lifreq *lifr; caddr_t *lifrspace; struct arpreq arpreq; - + lifn.lifn_flags = 0; lifn.lifn_family = AF_INET; if (ioctl(s, SIOCGLIFNUM, &lifn) < 0) { @@ -121,6 +121,7 @@ return -1; } lifc.lifc_family = lifn.lifn_family; + lifc.lifc_flags = lifn.lifn_flags; lifc.lifc_len = lifn.lifn_count * sizeof *lifr; lifrspace = ALLOCA(lifc.lifc_len); lifc.lifc_buf = (caddr_t) lifrspace; diff -ruN -x .svn ucarp-1.5.2.orig/src/globals.h ucarp-1.5.2/src/globals.h --- ucarp-1.5.2.orig/src/globals.h 2009-05-27 14:39:23.000000000 -0700 +++ ucarp-1.5.2/src/globals.h 2010-02-03 17:54:34.521733878 -0800 @@ -32,4 +32,9 @@ GLOBAL0(char *xparam); GLOBAL(unsigned char inaddr_carp_group[4], { 224 _COMA_ 0 _COMA_ 0 _COMA_ 18 }); GLOBAL0(sig_atomic_t received_signal); + +#if defined __sun || defined __sun__ /* MARCO */ +GLOBAL0(char *zonename); +GLOBAL0(char *pidfile); +#endif #endif diff -ruN -x .svn ucarp-1.5.2.orig/src/Makefile.am ucarp-1.5.2/src/Makefile.am --- ucarp-1.5.2.orig/src/Makefile.am 2004-08-28 09:05:25.000000000 -0700 +++ ucarp-1.5.2/src/Makefile.am 2010-02-03 10:42:14.380883033 -0800 @@ -33,7 +33,9 @@ log.h \ daemonize.c \ daemonize.h \ - syslognames.h + syslognames.h \ + check_zone.h \ + check_zone.c ucarp_LDADD = \ $(LTLIBINTL) diff -ruN -x .svn ucarp-1.5.2.orig/src/Makefile.in ucarp-1.5.2/src/Makefile.in --- ucarp-1.5.2.orig/src/Makefile.in 2010-01-31 14:05:39.000000000 -0800 +++ ucarp-1.5.2/src/Makefile.in 2010-02-03 11:35:49.675164599 -0800 @@ -58,7 +58,8 @@ crypto-sha1.$(OBJEXT) fillmac.$(OBJEXT) \ bsd-getopt_long.$(OBJEXT) garp.$(OBJEXT) spawn.$(OBJEXT) \ fakesnprintf.$(OBJEXT) mysnprintf.$(OBJEXT) log.$(OBJEXT) \ - daemonize.$(OBJEXT) + daemonize.$(OBJEXT) \ + check_zone.$(OBJEXT) ucarp_OBJECTS = $(am_ucarp_OBJECTS) am__DEPENDENCIES_1 = ucarp_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -230,7 +231,9 @@ log.h \ daemonize.c \ daemonize.h \ - syslognames.h + syslognames.h \ + check_zone.h \ + check_zone.c ucarp_LDADD = \ $(LTLIBINTL) @@ -317,6 +320,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysnprintf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spawn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ucarp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_zone.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ diff -ruN -x .svn ucarp-1.5.2.orig/src/ucarp.c ucarp-1.5.2/src/ucarp.c --- ucarp-1.5.2.orig/src/ucarp.c 2009-05-27 14:42:44.000000000 -0700 +++ ucarp-1.5.2/src/ucarp.c 2010-02-03 17:54:34.521176445 -0800 @@ -43,6 +43,10 @@ "--nomcast (-M): use broadcast (instead of multicast) advertisements\n" "--facility= (-f): set syslog facility (default=daemon)\n" "--xparam= (-x): extra parameter to send to up/down scripts\n" +#if defined __sun || defined __sun__ /* MARCO */ + "--zone= (-Z): zone to check before sending the package\n" + "--pidfile= (-F): file where to store the PID of the daemon\n" +#endif "\n" "Sample usage:\n" "\n" @@ -197,6 +201,44 @@ dead_ratio = (unsigned int) strtoul(optarg, NULL, 0); break; } +#if defined __sun || defined __sun__ /* MARCO */ + case 'Z': { + free(zonename); + if ((zonename = strdup(optarg)) == NULL) { + die_mem(); + } + break; + } + case 'F': { + char *pid_d; + char *pid_p; + struct stat status[1]; + + free(pidfile); + if ((pidfile = strdup(optarg)) == NULL) { + die_mem(); + } + if ((pid_d = strdup(pidfile)) == NULL) { + die_mem(); + } + if ((pid_p = strrchr(pid_d, '/')) != NULL && pid_p > pid_d) { + *pid_p = '\0'; + } + if (stat(pid_d, status) == -1 || !S_ISDIR(status->st_mode)) { + logfile(LOG_ERR, "Invalid --pidfile argument: '%s' (Parent directory does not exist)", pidfile); + free(pidfile); + pidfile = NULL; + } + if (access(pid_d, W_OK) == -1) { + logfile(LOG_ERR, "Invalid --pidfile argument: '%s' (Parent directory is not writable)", pidfile); + free(pidfile); + pidfile = NULL; + } + + free(pid_d); + break; + } +#endif case 'z': { shutdown_at_exit = 1; break; diff -ruN -x .svn ucarp-1.5.2.orig/src/ucarp.h ucarp-1.5.2/src/ucarp.h --- ucarp-1.5.2.orig/src/ucarp.h 2010-01-31 13:13:42.000000000 -0800 +++ ucarp-1.5.2/src/ucarp.h 2010-02-03 10:42:14.376505760 -0800 @@ -62,7 +62,7 @@ #include #include -#ifdef __sun__ +#if defined __sun || defined __sun__ # define u_int8_t uint8_t # define u_int16_t uint16_t # define u_int32_t uint32_t diff -ruN -x .svn ucarp-1.5.2.orig/src/ucarp_p.h ucarp-1.5.2/src/ucarp_p.h --- ucarp-1.5.2.orig/src/ucarp_p.h 2009-05-27 14:39:23.000000000 -0700 +++ ucarp-1.5.2/src/ucarp_p.h 2010-02-03 17:54:34.520826721 -0800 @@ -24,6 +24,10 @@ { "nomcast", 0, NULL, 'M' }, { "passfile", 1, NULL, 'o' }, { "xparam", 1, NULL, 'x' }, +#if defined __sun || defined __sun__ /* MARCO */ + { "pidfile", 1, NULL, 'F' }, + { "zone", 1, NULL, 'Z' }, +#endif { NULL, 0, NULL, 0 } };