Yet another pulse enhancement
Sébastien Bonnet <[email protected]>
| Newsgroups | gmane.linux.redhat.piranha |
|---|---|
| Message-ID | <[email protected]> |
Hi all, As I wanted to be able to use both directors as realservers, which was until a few hours ago impossible, I decided to finally code what I suggested earlier. lvs.cf now accepts two new global variables, active_cmd and inactive_cmd. If set, they should point to a valid executable. Arguments are allowed. active_cmd is launched when lvs becomes active (when starting first director or when failing over). inactive_cmd is launched when pulse starts and also when lvs becomes inactive (when pulse is shutdown, when both directors where active or when primary director is forced to be the master). This way, it's very easy to send an email when a director fails over, and also to set appropriate hidden flags when using DR or TUN. And whatever else ! My lvs.cf now contains : active_cmd = /tmp/cluster-active.sh inactive_cmd = "/tmp/cluster-inactive.sh arg testing" See attached files for scripts and diff file against 0.6.1-3 Still awaiting comments :) Lothar, will you hack piranha-gui ? Regards, -- Sébastien Bonnet Centre de contacts - Experian France
piranha-0.6.1-3-uptime+arp+sync+active.diff
(text/plain, 11.5 KB)
diff -Naur piranha/lvsconfig.c piranha-0.6.1-3/lvsconfig.c
--- piranha/lvsconfig.c Wed Jan 30 16:08:12 2002
+++ piranha-0.6.1-3/lvsconfig.c Wed Jun 26 16:46:00 2002
@@ -121,6 +121,9 @@
#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_VS_CLIENTMONITOR (1 << 1)
#define LVS_SAW_VS_VIRTUALADDRESS (1 << 2)
@@ -1526,6 +1529,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 +1570,12 @@
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 ("heartbeat"))
{
CHECK_ARGS (1)
@@ -1769,6 +1790,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 +1806,9 @@
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_NUM (LVS_SAW_USEHEARTBEAT, eConfig->useHeartbeat,
0,
(char *) "heatbeart = %d\n")
@@ -1946,6 +1978,7 @@
configFile.lineEnd = NULL;
/* Set default values */
+ config->useSyncDaemon = 0;
config->useHeartbeat = 0;
config->heartbeatPort = 539;
config->keepAliveTime = 2;
@@ -2079,6 +2112,8 @@
FREE(config->vsadm);
FREE(config->reserve);
FREE(config->reservation_conflict_action);
+ FREE(config->activeCommand);
+ FREE(config->inactiveCommand);
for (i = 0; i < config->numVirtServers; i++)
lvsFreeVirtServer(config->virtServers + i);
diff -Naur piranha/lvsconfig.h piranha-0.6.1-3/lvsconfig.h
--- piranha/lvsconfig.h Mon Mar 11 20:10:39 2002
+++ piranha-0.6.1-3/lvsconfig.h Wed Jun 26 12:02:26 2002
@@ -179,6 +179,9 @@
struct lvsVirtualServer *virtServers;
struct lvsVirtualServer *failoverServices;
char *reservation_conflict_action; /* "preempt" or "nothing" */
+ int useSyncDaemon;
+ char *activeCommand;
+ char *inactiveCommand;
};
int lvsParseConfig (int fd, struct lvsConfig *config, int *badLineNum);
diff -Naur piranha/nanny.c piranha-0.6.1-3/nanny.c
--- piranha/nanny.c Mon Mar 11 20:10:39 2002
+++ piranha-0.6.1-3/nanny.c Mon Jun 3 17:07:45 2002
@@ -233,11 +233,13 @@
static char *send_str = NULL;
static char *expect_str = NULL;
static int quiesce_srv;
-static char *loadCommand = NULL;
-
+static char *loadCommandArgv[40];
static int loadConfigFile(void)
{
+ char **argp;
+ char *token;
+
int fd;
struct lvsConfig config;
struct lvsVirtualServer *vserver;
@@ -322,10 +324,24 @@
quiesce_srv = vserver->quiesceServer;
- if (vserver->loadMonitor && strcmp (vserver->loadMonitor, "uptime"))
- ASSIGNSTRING(loadCommand, vserver->loadMonitor);
- else
- ASSIGNSTRING(loadCommand, config.rshCommand);
+ argp = loadCommandArgv;
+ if (vserver->loadMonitor)
+ {
+ token = strtok (vserver->loadMonitor, " ");
+ while (token != NULL)
+ {
+ if (!strcmp (token, "%a"))
+ *argp++ = strdup (inet_ntoa (remoteAddr));
+ else if (!strcmp (token, "%h"))
+ *argp++ = strdup (serverName);
+ else
+ *argp++ = strdup (token);
+
+ token = strtok (NULL, " ");
+ }
+ }
+ *argp++ = NULL;
+
out:
lvsFreeConfig(&config);
@@ -1029,30 +1045,20 @@
}
float
-getRemoteLoad (int flags, struct in_addr *remoteAddr, int timeout,
- char *loadCommand)
+getRemoteLoad (int flags, struct in_addr *remoteAddr, int timeout)
{
- 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 ((*loadCommandArgv == NULL) || (strcmp (*loadCommandArgv, "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");
@@ -1099,7 +1105,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, int lastWeight)
{
int newWeight;
@@ -1127,8 +1133,7 @@
float diffThresh = (float) weight / 4;
load = getRemoteLoad (flags, remoteAddr,
- interval,
- loadCommand);
+ interval);
if ((load >= 0.0) && (load != 1.0)) {
if (load < 1.0) {
@@ -1513,7 +1518,7 @@
virtualAddress, port,
&remoteAddr, routingMethod,
weight, interval, scale,
- loadCommand, lastWeight);
+ lastWeight);
if (rc < 0)
return rc;
lastWeight = rc;
diff -Naur piranha/pulse.c piranha-0.6.1-3/pulse.c
--- piranha/pulse.c Fri Jan 18 00:35:12 2002
+++ piranha-0.6.1-3/pulse.c Wed Jun 26 15:14:06 2002
@@ -1137,45 +1137,78 @@
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[4];
- 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] = NULL;
+ if (pulse_debug)
+ piranha_log (flags,
+ (char *)
+ "DEBUG -- Executing 'ipvsadm --stop-daemon'");
- 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);
+
+ ipvsadmArgs[0] = (char *) config->vsadm;
+ ipvsadmArgs[1] = (char *) "--start-daemon";
+ ipvsadmArgs[2] = (char *) ((master) ? "master" : "backup");
+ ipvsadmArgs[3] = NULL;
if (pulse_debug)
- logArgv (flags, argv);
+ piranha_log (flags,
+ (char *)
+ "DEBUG -- Executing 'ipvsadm --start-daemon %s'", ipvsadmArgs[2]);
- 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 +1273,107 @@
}
waitpid (fake1, NULL, 0);
+}
+
+
+
+
+
+/*
+** 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);
+}
+
+
+
+
+
+/*
+** 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 +1392,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 +1791,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 +2227,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");
@@ -2582,7 +2721,6 @@
if (!rc)
rc = run (&config, fd, fd_priv, flags);
-
if (flags & PULSE_FLAG_ASDAEMON)
unlink ("/var/run/pulse.pid");
cluster-active.sh
(application/x-sh, 175 B)
#! /bin/sh echo 0 > /proc/sys/net/ipv4/conf/all/hidden echo 0 > /proc/sys/net/ipv4/conf/lo/hidden cat <<EOT | mail -s "$HOSTNAME becoming active" [email protected] `date` EOT
cluster-inactive.sh
(application/x-sh, 99 B)
#! /bin/sh echo 1 > /proc/sys/net/ipv4/conf/all/hidden echo 1 > /proc/sys/net/ipv4/conf/lo/hidden