Re: Piranha and radius

Sébastien BONNET <[email protected]> Wed, 12 Oct 2005 10:29:41 +0200
Newsgroups gmane.linux.redhat.piranha
Message-ID <[email protected]>
Hi Tony,

> So I created a script that was run from the “send” line for the virtual 
> service:

You have to use send_program instead of send. Your piranha might be 
buggy regarding this feature and you might need the attached patch.

-- 
Sébastien BONNET     --    Ingénieur système
Tel: 04.42.25.15.40      GSM: 06.64.44.58.98

_______________________________________________
Piranha-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/piranha-list
piranha-0.7.0.diff (text/plain, 26 KB)
diff -Naur piranha.old/fos.c piranha.new/fos.c
--- piranha.old/fos.c	2001-12-13 21:30:26.000000000 +0100
+++ piranha.new/fos.c	2005-07-05 11:05:56.032938357 +0200
@@ -282,10 +282,10 @@
 	*arg++ = (char *) "-c";
 
 	*arg++ = (char *) "-h";
-	*arg++ = virtAddress;
+	*arg++ = realAddress;
 
 	*arg++ = (char *) "-V";
-	*arg++ = realAddress;
+	*arg++ = virtAddress;
 
 	*arg++ = (char *) "-p";
 	*arg++ = portNum;
@@ -300,7 +300,7 @@
 	if (FOserver->send_program) {
 		send_str = strdup (FOserver->send_program);
 		*arg++ = (char *) "-e";
-		*arg++ = strip_quotes (send_program);
+		*arg++ = strip_quotes (send_str);
 	}
 
 	if (FOserver->send_str) {
@@ -652,7 +652,7 @@
 	}
 
 	if (flags & LVS_FLAG_ASDAEMON)
-		unlink ("/var/run/fos.pid");
+		removePidFile ();
 
 	piranha_log (flags, (char *) "will now exit to notify pulse...");
 
diff -Naur piranha.old/lvs.c piranha.new/lvs.c
--- piranha.old/lvs.c	2002-01-31 11:08:37.000000000 +0100
+++ piranha.new/lvs.c	2005-07-05 11:05:56.033938215 +0200
@@ -412,6 +412,12 @@
   
   *arg++ = (char *) "--lvs";
   	          
+  /* pass along the real server hostname which might be used */
+  /* by the loadMonitor command */
+
+  *arg++ = (char *) "--servername";
+  *arg++ = service->name;
+
   /* Terminate the command line call */
   
   *arg++ = NULL;
@@ -452,6 +458,38 @@
 
 
 int
+zeroClientMonitor (struct lvsConfig *config,
+		   struct lvsVirtualServer *vserver,
+		   struct lvsService *service,
+		   struct clientInfo *clients,
+		   int *numClientsPtr, int flags)
+{
+
+  int which;
+  struct clientInfo clientInfo;
+
+  clientInfo.vip = vserver->virtualAddress;
+  clientInfo.address = service->address;
+  clientInfo.protocol = vserver->protocol;
+  clientInfo.port = service->port;
+
+  which = findClientInList (clients, *numClientsPtr, &clientInfo);
+
+  if (which == -1)
+    return 0;
+
+  if (clients->clientMonitor != -1)
+    {
+      kill (clients[which].clientMonitor, SIGTSTP);
+    }
+
+  return 0;
+}
+
+
+
+
+int
 shutdownClientMonitor (struct lvsConfig *config,
 		       struct lvsVirtualServer *vserver,
 		       struct lvsService *service,
@@ -699,7 +737,7 @@
 
   int old, new;
   enum
-  { WHAT_UNKNOWN, WHAT_START, WHAT_STOP, WHAT_SKIP }
+  { WHAT_UNKNOWN, WHAT_START, WHAT_STOP, WHAT_SKIP, WHAT_ZERO }
   what;
 
 
@@ -760,7 +798,15 @@
 	       vserver->servers[new].isActive)
 	{
 	  /* old active, new active */
-	  what = WHAT_SKIP;
+	  if (oldVserver->servers[old].weight &&
+	      !vserver->servers[new].weight)
+	    {
+	      what = WHAT_ZERO;
+	    }
+	  else
+	    {
+	      what = WHAT_SKIP;
+	    }
 
 	}
       else if (!oldVserver->servers[old].isActive &&
@@ -791,6 +837,10 @@
       else if (what == WHAT_STOP)
 	shutdownClientMonitor (config, vserver, vserver->servers + new,
 			       clients, numClientsPtr, flags);
+
+      else if (what == WHAT_ZERO)
+	zeroClientMonitor (config, vserver, vserver->servers + new,
+			   clients, numClientsPtr, flags);
     }
 
   return 0;
@@ -1044,7 +1094,7 @@
     }
 
   if (flags & LVS_FLAG_ASDAEMON)
-    unlink ("/var/run/lvs.pid");
+    removePidFile ();
 
   return 0;
 }
diff -Naur piranha.old/lvsconfig.c piranha.new/lvsconfig.c
--- piranha.old/lvsconfig.c	2002-01-31 11:08:37.000000000 +0100
+++ piranha.new/lvsconfig.c	2005-07-05 14:58:59.831225159 +0200
@@ -121,6 +121,11 @@
 #define LVS_SAW_BACKUPSHARED        (1 << 21)
 #define LVS_SAW_RCA		    (1 << 22)
 #define LVS_SAW_SERIAL_NO	    (1 << 23)
+#define LVS_SAW_USESYNCDAEMON	    (1 << 24)
+#define LVS_SAW_ACTIVE_CMD          (1 << 25)
+#define LVS_SAW_INACTIVE_CMD        (1 << 26)
+#define LVS_SAW_MCASTINTERFACE      (1 << 27)
+#define LVS_SAW_SYNCID              (1 << 28)
 
 #define LVS_SAW_VS_CLIENTMONITOR    (1 << 1)
 #define LVS_SAW_VS_VIRTUALADDRESS   (1 << 2)
@@ -1398,6 +1403,8 @@
   char *current_ptr;
   int saw = 0;
 
+  config->syncId = 255;
+
   if (eConfig)
     sectionMarkers = alloca (eConfig->numVirtServers *
 			     sizeof (*sectionMarkers));
@@ -1526,6 +1533,18 @@
 		}
 
 	    }
+          else if (TOKEN ("active_cmd"))
+            {
+              CHECK_ARGS (1) free (config->activeCommand);
+                config->activeCommand = strdup (toks.argv[2]);
+              OUTPUT_STR (eConfig, activeCommand, 2, LVS_SAW_ACTIVE_CMD);
+            }
+          else if (TOKEN ("inactive_cmd"))
+            {
+              CHECK_ARGS (1) free (config->inactiveCommand);
+                config->inactiveCommand = strdup (toks.argv[2]);
+              OUTPUT_STR (eConfig, inactiveCommand, 2, LVS_SAW_ACTIVE_CMD);
+            }
 	  else if (TOKEN ("debug_level"))
 	    {
 	      CHECK_ARGS (1) free (config->debug_level);
@@ -1555,6 +1574,24 @@
 	      config->rshCommand = strdup (toks.argv[2]);
 
 	    OUTPUT_STR (eConfig, rshCommand, 2, LVS_SAW_RSHCOMMAND)}
+	  else if (TOKEN ("syncdaemon"))
+	    {
+	      CHECK_ARGS (1)
+		if ((rc = getBoolean (&config->useSyncDaemon, toks.argv[2])))
+		return rc;
+	    OUTPUT_NUM (eConfig, useSyncDaemon, 2, LVS_SAW_USESYNCDAEMON)}
+	  else if (TOKEN ("mcast_interface"))
+	    {
+	      CHECK_ARGS (1) free (config->mcastInterface);
+	      config->mcastInterface = strdup (toks.argv[2]);
+
+	    OUTPUT_STR (eConfig, mcastInterface, 2, LVS_SAW_MCASTINTERFACE)}
+	  else if (TOKEN ("syncid"))
+	    {
+	      CHECK_ARGS (1)
+		if ((rc = getNum (&config->syncId, toks.argv[2])))
+		return rc;
+	    OUTPUT_NUM (eConfig, syncId, 2, LVS_SAW_SYNCID)}
 	  else if (TOKEN ("heartbeat"))
 	    {
 	      CHECK_ARGS (1)
@@ -1769,6 +1806,14 @@
 			  inet_ntoa (eConfig->natRouter),
 			  eConfig->natRouterDevice);
 
+	  OUTPUT_MISSING_STR (LVS_SAW_ACTIVE_CMD,
+			      eConfig->activeCommand, "",
+			      "active_cmd = %s\n");
+
+	  OUTPUT_MISSING_STR (LVS_SAW_INACTIVE_CMD,
+			      eConfig->inactiveCommand, "",
+			      "inactive_cmd = %s\n");
+
 	  OUTPUT_MISSING_STR (LVS_SAW_RSHCOMMAND, eConfig->rshCommand,
 			      (char *) "rsh", (char *) "rsh_command = %s\n")
 	    OUTPUT_MISSING_STR (LVS_SAW_DEBUG_LEVEL, eConfig->debug_level,
@@ -1777,6 +1822,15 @@
 	    OUTPUT_MISSING_STR (LVS_SAW_VSADM, eConfig->vsadm,
 				(char *) IPVSADM,
 				(char *) "ipvsadm = %s\n")
+	    OUTPUT_MISSING_NUM (LVS_SAW_USESYNCDAEMON, eConfig->useSyncDaemon,
+				0,
+				(char *) "syncdaemon = %d\n")
+	    OUTPUT_MISSING_STR (LVS_SAW_MCASTINTERFACE, eConfig->mcastInterface,
+				(char *) "mcast_interface",
+				(char *) "mcast_interface = %s\n")
+	    OUTPUT_MISSING_NUM (LVS_SAW_SYNCID, eConfig->syncId,
+				255,
+				(char *) "syncid = %d\n")
 	    OUTPUT_MISSING_NUM (LVS_SAW_USEHEARTBEAT, eConfig->useHeartbeat,
 				0,
 				(char *) "heatbeart = %d\n")
@@ -1946,6 +2000,7 @@
     configFile.lineEnd = NULL;
 
     /* Set default values */
+    config->useSyncDaemon = 0;
     config->useHeartbeat = 0;
     config->heartbeatPort = 539;
     config->keepAliveTime = 2;
@@ -2079,6 +2134,9 @@
 	FREE(config->vsadm);
 	FREE(config->reserve);
 	FREE(config->reservation_conflict_action);
+	FREE(config->activeCommand);
+	FREE(config->inactiveCommand);
+	FREE(config->mcastInterface);
 
 	for (i = 0; i < config->numVirtServers; i++)
 		lvsFreeVirtServer(config->virtServers + i);
diff -Naur piranha.old/lvsconfig.h piranha.new/lvsconfig.h
--- piranha.old/lvsconfig.h	2002-01-31 11:08:37.000000000 +0100
+++ piranha.new/lvsconfig.h	2005-07-05 11:24:54.401192648 +0200
@@ -180,6 +180,11 @@
   struct lvsVirtualServer *virtServers;
   struct lvsVirtualServer *failoverServices;
   char *reservation_conflict_action;	/* "preempt" or "nothing" */
+  int useSyncDaemon;
+  char *mcastInterface;
+  char *activeCommand;
+  char *inactiveCommand;
+  int syncId;
 };
 
 int lvsParseConfig (int fd, struct lvsConfig *config, int *badLineNum);
diff -Naur piranha.old/Makefile piranha.new/Makefile
--- piranha.old/Makefile	2002-04-26 22:08:36.000000000 +0200
+++ piranha.new/Makefile	2005-07-05 11:05:56.032938357 +0200
@@ -44,10 +44,12 @@
 
 COPTS   	=
 
+XTRA_CFLAGS	= -DUSE_REGEX
+
 ifeq ($(CC),ccc)
-		CFLAGS	= -Wall -g -DVERSION=\"$(VERSION)\" -DRELEASE=\"$(RELEASE)\" -DDATE=\"$(DATE)\" $(COPTS)
+		CFLAGS	= -Wall -g -DVERSION=\"$(VERSION)\" -DRELEASE=\"$(RELEASE)\" -DDATE=\"$(DATE)\" $(XTRA_CFLAGS) $(COPTS)
 else
-		CFLAGS	= -Wall -g -DVERSION=\"$(VERSION)\" -DRELEASE=\"$(RELEASE)\" -DDATE=\"$(DATE)\" $(RPM_OPT_FLAGS) $(COPTS)
+		CFLAGS	= -Wall -g -DVERSION=\"$(VERSION)\" -DRELEASE=\"$(RELEASE)\" -DDATE=\"$(DATE)\" $(XTRA_CFLAGS) $(RPM_OPT_FLAGS) $(COPTS)
 endif
 
 LDFLAGS   	= -ggdb # -lefence
diff -Naur piranha.old/nanny.c piranha.new/nanny.c
--- piranha.old/nanny.c	2001-12-13 21:30:26.000000000 +0100
+++ piranha.new/nanny.c	2005-07-05 11:05:56.037937651 +0200
@@ -139,6 +139,11 @@
 #include <math.h>		/* for pow() */
 #include <time.h>
 
+#if defined(USE_REGEX)
+	#include <sys/types.h>
+	#include <regex.h>
+#endif
+
 #include "globals.h"
 #include "util.h"
 #include "nanny.h"
@@ -158,13 +163,14 @@
 
 static int childDead = 0;
 static int gotAlarm = 0;
+static int gotStop  = 0;
 sigjmp_buf killYourself;
 static int nextState = 0;
 pid_t needsKilling = 0;
 int use_udp = 0;
 unsigned int fwmark = 0;
 
-static const char *http_send_str = "GET / HTTP/1.0\r\n\r\n";
+/* static const char *http_send_str = "GET / HTTP/1.0\r\n\r\n"; */
 /* static const char *http_recv_str = "HTTP"; */
 /* Default send/expect for port 80 */
 
@@ -189,6 +195,12 @@
 }
 
 static void
+handleStop (int signal)
+{
+	gotStop = 1;
+}
+
+static void
 changeState (int signal)
 {
 	if (signal == SIGHUP)
@@ -269,6 +281,25 @@
 	struct iphdr *ip;
 #endif
 
+#if defined(USE_REGEX)
+	static regex_t regExpr;
+	static char regCompiled = 0;
+	char regError[255];
+#endif
+
+#if defined(USE_REGEX)
+	if (!regCompiled) {
+		if ((i = regcomp (&regExpr, expect_str, REG_EXTENDED)) == 0) {
+			regCompiled = 1;
+		} else {
+			regerror (i, &regExpr, regError, sizeof (regError));
+			piranha_log (flags, (char *)
+				     "Error '%s' processing expected regular expression",
+				     regError);
+		}
+	}
+#endif
+
 	if (pingTimeout < 500)
 		pingTimeout = 500;
 
@@ -502,7 +533,11 @@
 			*/
 
 			if (expect_str)
+#if defined(USE_REGEX)
+				read_len = sizeof (read_buf) - 1;
+#else
 				read_len = strlen (expect_str);
+#endif
 			else
 				read_len = 1;	/* for UDP */
 
@@ -555,11 +590,15 @@
 				}
 
 				if ((read_len == 1) && (*expect_str == '*')) {
+					/* Wildcard */
 					read_buf[0] = '*';
 					read_buf[1] = 0;
 					i = 1;
 				}
-				/* Wildcard */
+#if defined(USE_REGEX)
+				if (!regCompiled || regexec (&regExpr, read_buf, 0, NULL, 0))
+					return_status = 1;
+#else
 				if (i >= read_len) {
 					if (strncmp ((const char *) expect_str,
 						     (const char *) read_buf,
@@ -572,6 +611,7 @@
 						     port);
 					return_status = 1;
 				}
+#endif
 			}
 		}
 	}
@@ -896,29 +936,20 @@
 
 float
 getRemoteLoad (int flags, struct in_addr *remoteAddr, int timeout,
-	       char *loadCommand)
+	       char *loadCommandArgv[])
 {
 
-	char *argv[40];
-	char **argp = argv;
 	char *output;
 	char *start, *chptr;
 	float avg;
 
-	*argp++ = loadCommand;
-	*argp++ = inet_ntoa (*remoteAddr);
-
-	if (strcmp (loadCommand, (char *) "none") == 0)
+	if (strcmp (loadCommandArgv[0], (char *) "none") == 0)
 		/* == 0 per bugzilla #24843 */
 		return -1.0;	/* nothing to see here, go home silently */
 
-	if (strcmp (loadCommand, (char *) "rup"))
-		*argp++ = (char *) "uptime";
-	*argp++ = NULL;
-
-	logArgv (flags, argv);
+	logArgv (flags, loadCommandArgv);
 
-	output = getExecOutput (flags, argv, timeout);
+	output = getExecOutput (flags, loadCommandArgv, timeout);
 
 	if (!output) {
 		piranha_log (flags, (char *) "failed to read remote load");
@@ -965,7 +996,7 @@
 int
 adjustWeight (int flags, char *ipvsadm, char *virtualAddress, int port,
 	      struct in_addr *remoteAddr, char *routingMethod, int weight,
-	      int interval, int scale, char *loadCommand, int lastWeight)
+	      int interval, int scale, char *loadCommandArgv[], int lastWeight)
 {
 	int newWeight;
 
@@ -994,7 +1025,7 @@
 
 		load = getRemoteLoad (flags, remoteAddr,
 				      interval,
-				      loadCommand);
+				      loadCommandArgv);
 
 		if ((load >= 0.0) && (load != 1.0)) {
 			if (load < 1.0) {
@@ -1105,7 +1136,7 @@
 int
 run (int flags, char *ipvsadm, char *virtualAddress, int port,
      struct in_addr *remoteAddr, char *routingMethod, int weight,
-     int interval, int countThresh, int scale, char *loadCommand,
+     int interval, int countThresh, int scale, char *loadCommandArgv[],
      char *send_program, char *send_str, char *expect_str,
      int quiesce_srv, int service_type)
 {
@@ -1129,6 +1160,7 @@
 	sigaddset (&sigs, SIGHUP);
 	sigaddset (&sigs, SIGUSR1);
 	sigaddset (&sigs, SIGUSR2);
+	sigaddset (&sigs, SIGTSTP);
 	sigprocmask (SIG_BLOCK, &sigs, NULL);
 
 	if (flags & NANNY_FLAG_VERBOSE) {
@@ -1187,6 +1219,7 @@
 	signal (SIGUSR1, changeState);
 	signal (SIGUSR2, changeState);
 	signal (SIGHUP, changeState);
+	signal (SIGTSTP, handleStop);
 
 	sigfillset (&sigs);
 	sigdelset (&sigs, SIGTERM);
@@ -1195,6 +1228,7 @@
 	sigdelset (&sigs, SIGHUP);
 	sigdelset (&sigs, SIGUSR1);
 	sigdelset (&sigs, SIGUSR2);
+	sigdelset (&sigs, SIGTSTP);
 
 	/* we keep a single socket for pings */
 	pingSocket = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
@@ -1366,12 +1400,27 @@
 					   virtualAddress, port,
 					   remoteAddr, routingMethod,
 					   weight, interval, scale,
-					   loadCommand, lastWeight);
+					   loadCommandArgv, lastWeight);
 			if (rc < 0)
 				return rc;
 			lastWeight = rc;
 		}
 
+		if (gotStop && (service_type == SERV_LVS) && isActive && isSrvUp) {
+			gotStop = 0;
+			piranha_log (flags, (char *)
+				     "de-activating %s:%d without shutting it down",
+				     inet_ntoa (*remoteAddr), port);
+
+			if (adjustDevice
+			    (flags, ipvsadm,
+			     virtualAddress, port,
+			     remoteAddr, routingMethod, 0))
+				return -1;
+
+			lastWeight = 0;
+		}
+
 		/*
 		**  Monitor loop
 		*/
@@ -1499,15 +1548,20 @@
 	int service_type = SERV_UNK;
 
 	char *server = NULL;
+	char *servername = NULL;
 	char *virtualAddress = NULL;
 	char *routingMethod = (char *) "-m";
 	char *specifiedRM;
 	char *vsadmPath = (char *) IPVSADM;
-	char *loadCommand = (char *) "rup";
+	char *loadCommand = NULL;
 	char *send_program = NULL;
 	char *send_str = NULL;
 	char *expect_str = NULL;
 
+	char *loadCommandArgv[40];
+	char **argp = loadCommandArgv;
+	char *token;
+
 	/* Letters taken: DIMRSTUV acnpstuvwx */
 
 	struct poptOption options[] = {
@@ -1542,6 +1596,9 @@
 		{"server", 'h', POPT_ARG_STRING, &server, 0,
 		 N_("IP address of remote server")},
 
+		{"servername", '\0', POPT_ARG_STRING, &servername, 0,
+		 N_("Hostname of remote server")},
+
 		{"send_program", 'e', POPT_ARG_STRING, &send_program, 0,
 		 N_("Use an external program to test a service")},
 
@@ -1715,8 +1772,24 @@
 			     "starting LVS client monitor for %s:%d",
 			     virtualAddress, port);
 
+	if (loadCommand == NULL)
+		loadCommand = strdup ("none");
+
+	token = strtok (loadCommand, " ");
+	while (token != NULL)
+	{
+		if (!strcmp (token, "%a"))
+			*argp++ = strdup (server);
+		else if (!strcmp (token, "%h") && (servername != NULL))
+			*argp++ = strdup (servername);
+		else
+			*argp++ = strdup (token);
+		token = strtok (NULL, " ");
+	}
+	*argp++ = NULL;
+
 	return run (flags, vsadmPath, virtualAddress, port, &remoteAddr,
 		    routingMethod, weight, interval, countThresh, scale,
-		    loadCommand, send_program, send_str, expect_str,
+		    loadCommandArgv, send_program, send_str, expect_str,
 		    quiesce_srv, service_type);
 }
diff -Naur piranha.old/pulse.c piranha.new/pulse.c
--- piranha.old/pulse.c	2002-01-17 21:43:23.000000000 +0100
+++ piranha.new/pulse.c	2005-07-05 15:01:32.279710168 +0200
@@ -388,7 +388,8 @@
 }
 
 static void handleHupSignal(int signal) {
-  kill(HA_Process, SIGHUP);
+  if (HA_Process)
+    kill(HA_Process, SIGHUP);
 }
 
 #if 0
@@ -649,6 +650,59 @@
 
 
 /*
+**  executeCommand() -- 
+*/
+
+static void
+executeCommand (struct lvsConfig *config, int flags, char *cmd)
+{
+
+  pid_t child = 0;
+  char *argv[40];
+  char **argp;
+  char *token;
+  char *command;
+
+
+  if (!cmd)
+    return;
+
+  command = strdup (cmd);
+
+  if (!(flags & PULSE_FLAG_NORUN))
+    {
+      if (pulse_debug)
+        piranha_log (flags,
+		     (char *)
+		     "DEBUG -- Executing '%s'", command);
+
+      if (!(child = fork ()))
+	{
+          argp = argv;
+          token = strtok (command, " ");
+          while (token != NULL)
+            {
+              *argp++ = strdup (token);
+              token = strtok (NULL, " ");
+            }
+          *argp++ = NULL;
+
+          logArgv (flags, argv);
+	  execv (argv[0], argv);
+	  exit (-1);
+	}
+
+      waitpid (child, NULL, 0);
+    }
+
+  free (command);
+}
+
+
+
+
+
+/*
 **  deactivateFos() --  stop fos process and shut down all VIP interfaces
 */
 
@@ -662,14 +716,6 @@
   if (flags & PULSE_FLAG_NORUN)
     return;
 
-  if (HA_Process > 0)
-    {
-      kill (HA_Process, SIGTERM);
-      waitpid (HA_Process, NULL, 0);
-      HA_Process = 0;
-    }
-
-
   if (cleanup)
     {
       /* deactivate the interfaces */
@@ -692,6 +738,13 @@
 			      flags);
 	}
     }
+
+  if (HA_Process > 0)
+    {
+      kill (HA_Process, SIGTERM);
+      waitpid (HA_Process, NULL, 0);
+      HA_Process = 0;
+    }
 }
 
 
@@ -717,6 +770,9 @@
   int numFakes;
   char *argv[7];
 
+
+  executeCommand (config, flags, config->activeCommand);
+
   argv[0] = fosBinary;
   argv[1] = (char *) "--active";
   argv[2] = (char *) "-c";
@@ -819,6 +875,9 @@
 
   char *argv[7];
 
+
+  executeCommand (config, flags, config->inactiveCommand);
+
   argv[0] = fosBinary;
   argv[1] = (char *) "--monitor";
   argv[2] = (char *) "-c";
@@ -924,7 +983,7 @@
       unblock_signals ();
       execv (argv[0], argv);
       piranha_log (flags, "Couldn't execute \"%s\": %s", argv[0],
-		   sys_errlist[errno]);
+		   strerror (errno));
       exit (-1);
     }
 
@@ -997,7 +1056,7 @@
       unblock_signals ();
       execv (argv[0], argv);
       piranha_log (flags, "Couldn't execute \"%s\": %s", argv[0],
-		   sys_errlist[errno]);
+		   strerror (errno));
       exit (-1);
     }
 
@@ -1048,7 +1107,7 @@
       unblock_signals ();
       execv (argv[0], argv);
       piranha_log (flags, "Couldn't execute \"%s\": %s", argv[0],
-		   sys_errlist[errno]);
+		   strerror (errno));
       exit (-1);
     }
 
@@ -1102,7 +1161,7 @@
       unblock_signals ();
       execv (argv[0], argv);
       piranha_log (flags, "Couldn't execute \"%s\": %s", argv[0],
-		   sys_errlist[errno]);
+		   strerror (errno));
       exit (-1);
     }
 
@@ -1128,7 +1187,7 @@
       execv (argv[0], argv);
       if (confidence)
 	piranha_log (flags, "Couldn't execute \"%s\": %s", argv[0],
-		     sys_errlist[errno]);
+		     strerror (errno));
       confidence = 0;
     }
 }
@@ -1137,45 +1196,90 @@
    SHARED SCSI ROUTINES END HERE
 */
 
+
+
+
+
 /*
-**  activateLvs() -- Start LVS program, then send arps for all VIPs
+** syncDaemon() -- (re)start IPVS synchronisation daemon
 */
 
-static pid_t
-activateLvs (struct lvsConfig *config, int flags)
+static void
+syncDaemon (struct lvsConfig *config, int flags, int master)
 {
 
-  pid_t child = 0;
-  pid_t fake1;
-  pid_t *fake = alloca (sizeof (*fake) * (config->numVirtServers + 1));
-  int i;
-  int j;
-  int numFakes;
+  pid_t child;
+  char *ipvsadmArgs[8];
+  char szSyncId[10];
 
-  char *argv[5];
+  if (config->useSyncDaemon == 0)
+    return;
 
-  argv[0] = lvsBinary;
-  argv[1] = (char *) "--nodaemon";
-  argv[2] = (char *) "-c";
-  argv[3] = configFile;
-  argv[4] = NULL;
+  ipvsadmArgs[0] = (char *) config->vsadm;
+  ipvsadmArgs[1] = (char *) "--stop-daemon";
+  ipvsadmArgs[2] = (char *) ((master) ? "backup" : "master");
+  ipvsadmArgs[3] = NULL;
 
+  if (pulse_debug)
+    piranha_log (flags,
+		 (char *)
+		 "DEBUG -- Executing 'ipvsadm --stop-daemon %s'", ipvsadmArgs[2]);
 
-  if (flags & PULSE_FLAG_ASDAEMON)
-    argv[1] = (char *) "--nofork";
+  if (!(child = fork ()))
+    {
+      logArgv (flags, ipvsadmArgs);
+      execv (ipvsadmArgs[0], ipvsadmArgs);
+      exit (-1);
+    }
+
+  waitpid (child, NULL, 0);
+
+  sprintf (szSyncId, "%d", config->syncId);
+  ipvsadmArgs[0] = (char *) config->vsadm;
+  ipvsadmArgs[1] = (char *) "--start-daemon";
+  ipvsadmArgs[2] = (char *) ((master) ? "master" : "backup");
+  ipvsadmArgs[3] = (char *) "--syncid";
+  ipvsadmArgs[4] = szSyncId;
+  ipvsadmArgs[5] = NULL;
+  if (config->mcastInterface)
+    {
+      ipvsadmArgs[5] = (char *) "--mcast-interface";
+      ipvsadmArgs[6] = (char *) config->mcastInterface;
+      ipvsadmArgs[7] = NULL;
+    }
 
   if (pulse_debug)
-    logArgv (flags, argv);
+    piranha_log (flags,
+                 (char *)
+                  "DEBUG -- Executing 'ipvsadm --start-daemon %s --syncid %s ...'",
+                  ipvsadmArgs[2], ipvsadmArgs[4]);
 
-  if (!(flags & PULSE_FLAG_NORUN))
+  if (!(child = fork ()))
     {
-      if (!(child = fork ()))
-	{
-	  execv (lvsBinary, argv);
-	  exit (-1);
-	}
+      logArgv (flags, ipvsadmArgs);
+      execv (ipvsadmArgs[0], ipvsadmArgs);
+      exit (-1);
     }
 
+  waitpid (child, NULL, 0);
+}
+
+
+
+
+
+/*
+**  sendLvsArps() -- send arps for all VIPs
+*/
+
+static void
+sendLvsArps (struct lvsConfig *config, int flags)
+{
+  pid_t fake1;
+  pid_t *fake = alloca (sizeof (*fake) * (config->numVirtServers + 1));
+  int i;
+  int j;
+  int numFakes;
 
   /* Run fake for 5 seconds on each interface */
   if (!(fake1 = fork ()))
@@ -1240,6 +1344,54 @@
     }
 
   waitpid (fake1, NULL, 0);
+}
+
+
+
+
+
+/*
+**  activateLvs() -- Start LVS program, then send arps for all VIPs
+*/
+
+static pid_t
+activateLvs (struct lvsConfig *config, int flags)
+{
+
+  pid_t child = 0;
+  char *argv[6];
+
+
+  executeCommand (config, flags, config->activeCommand);
+
+  argv[0] = lvsBinary;
+  argv[1] = (char *) "--nodaemon";
+  argv[2] = (char *) "-c";
+  argv[3] = configFile;
+  argv[4] = NULL;
+  argv[5] = NULL;
+
+  if (flags & PULSE_FLAG_ASDAEMON)
+    argv[1] = (char *) "--nofork";
+
+  if (pulse_debug)
+    argv[4] = (char *) "-v";
+
+  if (pulse_debug)
+    logArgv (flags, argv);
+
+  if (!(flags & PULSE_FLAG_NORUN))
+    {
+      if (!(child = fork ()))
+	{
+	  execv (lvsBinary, argv);
+	  exit (-1);
+	}
+    }
+
+  syncDaemon (config, flags, 1);
+  sendLvsArps (config, flags);
+
   return child;
 }
 
@@ -1258,6 +1410,10 @@
   int i, j;
 
 
+  executeCommand (config, flags, config->inactiveCommand);
+
+  syncDaemon (config, flags, 0);
+
   if ((flags & PULSE_FLAG_NORUN) || !(flags & PULSE_FLAG_AMACTIVE))
     return;
 
@@ -1653,7 +1809,11 @@
     }
 
   if (use_fos == 0)
-    sigprocmask (SIG_UNBLOCK, &sigs, NULL);
+    {
+      sigprocmask (SIG_UNBLOCK, &sigs, NULL);
+      executeCommand (config, flags, config->inactiveCommand);
+      syncDaemon (config, flags, 0);
+    }
 
   flags |= PULSE_FLAG_SUPPRESS_ERRORS;	/* Suppress useless start errs */
 
@@ -2085,16 +2245,13 @@
 
 			  /* Both are running & we are master */
 
-			  if ((config->redirectType == LVS_REDIRECT_NAT) &&
-			      (config->natRouterDevice != NULL) &&
-			      (use_fos == 0))
+			  if (use_fos == 0)
 			    {
 			      piranha_log (flags,
 					   (char *)
 					   "partner active: resending arps");
-			      sendArps (config->natRouterDevice,
-					&config->natRouter,
-					&config->nat_nmask, 5, flags);
+                              executeCommand (config, flags, config->activeCommand);
+			      sendLvsArps (config, flags);
 			    }
 			  else
 			    piranha_log (flags, (char *) "partner active");
@@ -2429,7 +2586,7 @@
     }
 
   poptFreeContext (optCon);
-  logName ((char *) "pulse");
+  logName ((char *) argv[0]);
 
   if (display_ver)
     {
@@ -2582,10 +2739,8 @@
   if (!rc)
     rc = run (&config, fd, fd_priv, flags);
 
-
   if (flags & PULSE_FLAG_ASDAEMON)
-    unlink ("/var/run/pulse.pid");
-
+    removePidFile ();
 
   if (rc == 2)
     rc = 0;
diff -Naur piranha.old/pulse.init piranha.new/pulse.init
--- piranha.old/pulse.init	2001-06-07 22:09:35.000000000 +0200
+++ piranha.new/pulse.init	2005-07-05 11:05:56.040937227 +0200
@@ -11,6 +11,8 @@
 # pidfile: /var/run/pulse.pid
 # config: /etc/sysconfig/ha/lvs.cf
 
+pulse=`basename $0`
+
 # Source function library.
 . /etc/rc.d/init.d/functions
 
@@ -20,32 +22,32 @@
 # Check that networking is up.
 [ ${NETWORKING} = "no" ] && exit 0
 
-[ -f /usr/sbin/pulse ] || exit 0
+[ -f /usr/sbin/$pulse ] || exit 0
 
-[ -f /etc/sysconfig/ha/lvs.cf ] || exit 0
+[ -f /etc/sysconfig/ha/$pulse.cf ] || exit 0
 
 RETVAL=0
 
 # See how we were called.
 case "$1" in
   start)
-        echo -n "Starting pulse: "
-        daemon pulse
+        echo -n "Starting $pulse: "
+        daemon $pulse -c /etc/sysconfig/ha/$pulse.cf
 	RETVAL=$?
         echo
-        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/pulse
+        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$pulse
         ;;
 
   stop)
-        echo -n "Shutting down pulse: "
-	killproc pulse
+        echo -n "Shutting down $pulse: "
+	killproc $pulse
 	RETVAL=$?
         echo
-        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/pulse
+        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$pulse
         ;;
 
   status)
-	status pulse
+	status $pulse
 	RETVAL=$?
 	;;
 
@@ -56,13 +58,13 @@
 	;;
 
   reload)
-	echo -n "Reloading pulse: "
-	killproc pulse -HUP
+	echo -n "Reloading $pulse: "
+	killproc $pulse -HUP
 	RETVAL=$?
 	;;
 
   *)
-        echo "Usage: pulse {start|stop|status|restart|reload}"
+        echo "Usage: $pulse {start|stop|status|restart|reload}"
         exit 1
 esac
 
diff -Naur piranha.old/util.c piranha.new/util.c
--- piranha.old/util.c	2001-10-08 20:55:46.000000000 +0200
+++ piranha.new/util.c	2005-07-05 11:05:56.040937227 +0200
@@ -29,6 +29,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <libgen.h>
 
 #include "util.h"
 
@@ -37,7 +38,11 @@
 void
 logName (char *newName)
 {
-  name = newName;
+  char *path;
+
+  path = strdup (newName);
+  name = strdup (basename (path));
+  free (path);
 }
 
 static void
@@ -150,6 +155,15 @@
 }
 
 void
+removePidFile ()
+{
+  char pidFile[80];
+
+  sprintf (pidFile, "/var/run/%s.pid", name);
+  unlink (pidFile);
+}
+
+void
 logArgv (int flags, char **argv)
 {
   char *argList;
diff -Naur piranha.old/util.h piranha.new/util.h
--- piranha.old/util.h	2001-08-28 21:07:55.000000000 +0200
+++ piranha.new/util.h	2005-07-05 11:05:56.040937227 +0200
@@ -36,6 +36,7 @@
 void piranha_log (int flags, char *format, ...);
 void logArgv (int flags, char **argv);
 void logName (char *name);
+void removePidFile ();
 
 #define LVS_FLAG_TESTSTARTS     (1 << 26)
 #define LVS_FLAG_ASDAEMON       (1 << 27)