There is a minor formatting problem in the first hunk from a bad cut and paste. This should correct it.
Russell Mosemann, Ph.D. Associate Profesor of Computer Science Concordia University, Nebraska diff -Naur ucarp-1.1/README ucarp-1.1-3/README --- ucarp-1.1/README 2004-09-02 17:07:42.000000000 -0500 +++ ucarp-1.1-3/README 2006-01-13 20:21:02.000000000 -0600 @@ -126,10 +126,23 @@ Please note that by default, and if everything's ok, a master will stay a master as long as possible. If you want a "preferred" master to immediately -become a master even if the other host is: +become a master even if another host is already the master, - add the --preempt (or -P) switch to *all* hosts - use a lower skew or a lower base for the "preferred" one. +When ucarp first runs, it starts as a backup and listens to the network +to determine if it should become the master. When it enters the backup +state, it normally runs the downscript. That can be useful to remove +old temporary files or clean up an interface that is in an unknown +state. In some circumstances, however, it is undesirable to run the +downscript if the service was not already up. In that case, use the +--neutral (-n) switch for ucarp to not run the downscript when it +enters the backup state the first time. All changes from the master +state to the backup state after that will run the downscript. + +--shutdown (-z) will run the downscript at exit, unless ucarp is +already in the backup state. + The "dead ratio" (--deadratio=...) knob basically changes how long a backup server will wait for an unresponsive master before considering it as dead, and becoming the new master. In the original protocol, the ratio is 3. This is diff -Naur ucarp-1.1/src/carp.c ucarp-1.1-3/src/carp.c --- ucarp-1.1/src/carp.c 2004-08-28 11:30:02.000000000 -0500 +++ ucarp-1.1-3/src/carp.c 2006-01-13 20:27:03.000000000 -0600 @@ -59,7 +59,8 @@ break; case BACKUP: logfile(LOG_WARNING, _("Switching to state: BACKUP")); - (void) spawn_handler(dev_desc_fd, downscript); + if ((sc->sc_state != INIT) || (neutral != 1)) + (void) spawn_handler(dev_desc_fd, downscript); gratuitous_arp(dev_desc_fd, 0); break; case MASTER: @@ -313,17 +314,8 @@ #endif switch (sc->sc_state) { case INIT: - if (preempt != 0 && carp_suppress_preempt == 0) { - carp_send_ad(sc); - gratuitous_arp(dev_desc_fd, 1); -#ifdef INET6 - carp_send_na(sc); -#endif /* INET6 */ - carp_set_state(sc, MASTER); - } else { - carp_set_state(sc, BACKUP); - carp_setrun(sc, 0); - } + carp_set_state(sc, BACKUP); + carp_setrun(sc, 0); break; case BACKUP: sc->sc_ad_tmo.tv_sec = 0; @@ -607,7 +599,8 @@ logfile(LOG_DEBUG, "sighandler_exit(): Calling [%s] and exiting", downscript); #endif - (void) spawn_handler(dev_desc_fd, downscript); + if (sc->sc_state != BACKUP) + (void) spawn_handler(dev_desc_fd, downscript); _exit(EXIT_SUCCESS); } @@ -687,14 +680,18 @@ pfds[0].fd = dev_desc_fd; pfds[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; - carp_setrun(&sc, 0); - if (shutdown_at_exit != 0) { (void) signal(SIGINT, sighandler_exit); (void) signal(SIGQUIT, sighandler_exit); (void) signal(SIGTERM, sighandler_exit); } + if (gettimeofday(&now, NULL) != 0) { + logfile(LOG_WARNING, "initializing now to gettimeofday() failed: %s", + strerror(errno)); + } + carp_setrun(&sc, 0); + for (;;) { nfds = poll(pfds, (nfds_t) 1, sc.sc_advbase * 1000); if (nfds == -1 || diff -Naur ucarp-1.1/src/globals.h ucarp-1.1-3/src/globals.h --- ucarp-1.1/src/globals.h 2004-06-20 14:35:22.000000000 -0500 +++ ucarp-1.1-3/src/globals.h 2006-01-13 19:05:29.000000000 -0600 @@ -20,6 +20,7 @@ GLOBAL0(char *upscript); GLOBAL0(char *downscript); GLOBAL0(signed char preempt); +GLOBAL0(signed char neutral); GLOBAL0(signed char shutdown_at_exit); GLOBAL0(unsigned char hwaddr[6]); GLOBAL0(signed char no_syslog); diff -Naur ucarp-1.1/src/ucarp.c ucarp-1.1-3/src/ucarp.c --- ucarp-1.1/src/ucarp.c 2004-08-28 11:04:05.000000000 -0500 +++ ucarp-1.1-3/src/ucarp.c 2006-01-13 19:03:06.000000000 -0600 @@ -28,6 +28,7 @@ "--vhid=<id> (-v <id>): virtual IP identifier (1-255)\n" "--pass=<pass> (-p <pass>): password\n" "--preempt (-P): becomes a master as soon as possible\n" + "--neutral (-n): do not run downscript at start if backup\n" "--addr=<ip> (-a <ip>): virtual shared IP address\n" "--help (-h): summary of command-line options\n" "--advbase=<seconds> (-b <seconds>): advertisement frequency\n" @@ -127,6 +128,10 @@ preempt = 1; break; } + case 'n': { + neutral = 1; + break; + } case 'a': { if (inet_pton(AF_INET, optarg, &vaddr) == 0) { logfile(LOG_ERR, _("Invalid address: [%s]"), optarg); diff -Naur ucarp-1.1/src/ucarp_p.h ucarp-1.1-3/src/ucarp_p.h --- ucarp-1.1/src/ucarp_p.h 2004-08-28 11:02:51.000000000 -0500 +++ ucarp-1.1-3/src/ucarp_p.h 2006-01-13 19:03:33.000000000 -0600 @@ -1,7 +1,7 @@ #ifndef __CARP_P_H__ #define __CARP_P_H__ 1 -static const char *GETOPT_OPTIONS = "i:s:v:p:Pa:hb:k:u:d:r:zf:B"; +static const char *GETOPT_OPTIONS = "i:s:v:p:Pna:hb:k:u:d:r:zf:B"; static struct option long_options[] = { { "interface", 1, NULL, 'i' }, @@ -9,6 +9,7 @@ { "vhid", 1, NULL, 'v' }, { "pass", 1, NULL, 'p' }, { "preempt", 0, NULL, 'P' }, + { "neutral", 0, NULL, 'n' }, { "addr", 1, NULL, 'a' }, { "help", 0, NULL, 'h' }, { "advbase", 1, NULL, 'b' },