[PATCH] Re: ipvsadm trees

Horms horms at verge.net.au
Thu Jan 27 04:44:16 GMT 2005


On Mon, Jan 17, 2005 at 01:27:23PM +0800, Wensong Zhang wrote:
> 
> 
> On Thu, 13 Jan 2005, Horms wrote:
> 
> >On Wed, Jan 12, 2005 at 10:43:06AM -0500, Joseph Mack wrote:
> >>Alejandro Mery wrote:
> >>>
> >>>Hi, i have a machine which boot both, linux2.4 and linux2.6. i want to
> >>>use ipvs on both, what should i do with ipvsadm? can i use ipvsadm-1.24
> >>>to admin lx2.4 or ipvsadm-1.21 for lx2.4 and 1.24 for lx2.6?
> >>
> >>The way they were written you have to use a version of ipvsadm for each
> >>kernel. I would rather one giant ipvsadm that detects the kernel and does
> >>the right thing. However Horms is the one who's doing most of the 
> >>maintenance
> >>and he's happy with the way he's doing it.
> >
> >I am not sure that either of those stathements are true.
> >I would definately rather ipvsadm had the same kind of
> >semantics as modutils. That is something like this:
> >
> >You always invoke ipvsadm regardless of your kernel.
> >If you only have ipvsadm-1.21 or ipvsadm-1.24 installed,
> >then that is always run and it complains if there is a kernel
> >version missmatch. If you have both installed then ipvsadm-1.24
> >is always run, but if it detects a 2.4 kernel, then it execs
> >ipvsadm 1.21.
> >
> >Also, the current version numbers are quite aquard, especually
> >as 1.24 is used for a 2.6 kernel, nota  2.4 kernel, which one
> >may be tempted to think in error. But we are probably stuck with them.
> >
> >As for who maintains the code. I have made modifications to it over
> >time, as have others. But I always assumed that as with the kernel code
> >the maintainer was Wensong.
> >
> >I would be more than happy to make patches to implement what I describe
> >above, but I would like some feedback from Wensong first.
> >
> 
> If we merge the code of current ipvsadm-1.21 and ipvsadm-1.24 together, we 
> probably need copy all the ipvs interface between kernel and user (ip_vs.h) 
> into ipvsadm source code, so that no matter which version the default 
> kernel source is, ipvsadm can be compiled. Then, there is two places to 
> maintain for the ipvs interface, the ipvsadm source code would be 
> complicated and hard to read and maintain. In my past experience, 
> maintaining the code of using getopt and popt parsing option together in 
> one ipvsadm.c is time consuming. As long as the ipvs interface between 
> kernel 2.4 and 2.6 is different, it is hard to do it in the way.

Hi Wensong,

I think you missunderstand my suggestion. My suggestion is not to merge
the code. I think keeping ipvsadm-1.21 and ipvsadm-1.24 is fine.
Its a clean split. What I am talking about is allowing ipvsadm-1.24 to
exec ipvsadm-1.21 if it detects that is the right thing to do.

This is how modprobe and friends work, so you can have both the 2.6 and
2.4 generation tools installed. This is very useful for systems
that want to be able to run both a 2.4 and a 2.6 kernel. And is
simmilarly useful for packagers of distributions that have that
requirement.

Attached is a first cut at implementing this. I borrowed some code
from modprobe. And by default this new feature is not compiled in,
so you get the existing behaviour.

If it is compiled in, and you run ipvsadm on an a system running 2.4, 
then it will try and exec PATH/ipvsadm-1.21, else gracefully fail. It
is up to the packager or sysadmin to install ipvsadm-1.21 into
PATH/ipvsadm-1.21 and compile ipvsadm-1.24 with this new feature
if they want this functionality. Again, I am thinking of package
maintainers.

-- 
Horms
-------------- next part --------------
diff -ruN ipvsadm-1.24/Makefile ipvsadm-1.24.backwards_compat/Makefile
--- ipvsadm-1.24/Makefile	2004-10-28 00:53:07.000000000 +0900
+++ ipvsadm-1.24.backwards_compat/Makefile	2005-01-27 13:24:45.000000000 +0900
@@ -74,10 +75,15 @@
 POPT_DEFINE = -DHAVE_POPT
 endif
 
+# If defined then if the version of ipvs in the kernel is too old
+# for ipvsadm 1.24, then instead of trying to execute ipvsadm.1.21,
+# print a warning and soldier on
+BACKWARDS_COMPET_DEFINE= -DNO_BACKWARDS_COMPAT
+
 OBJS		= ipvsadm.o config_stream.o dynamic_array.o
 LIBS		= $(POPT_LIB)
 DEFINES		= -DVERSION=\"$(VERSION)\" -DSCHEDULERS=\"$(SCHEDULERS)\" \
-		  $(POPT_DEFINE)
+		  $(POPT_DEFINE) $(BACKWARDS_COMPET_DEFINE)
 DEFINES		+= $(shell if [ ! -f ../ip_vs.h ]; then	\
 		     echo "-DHAVE_NET_IP_VS_H"; fi;)
 
diff -ruN ipvsadm-1.24/ipvsadm.c ipvsadm-1.24.backwards_compat/ipvsadm.c
--- ipvsadm-1.24/ipvsadm.c	2004-01-10 18:39:03.000000000 +0900
+++ ipvsadm-1.24.backwards_compat/ipvsadm.c	2005-01-27 13:32:46.000000000 +0900
@@ -54,6 +54,7 @@
  *                                processing options.
  *        Alexandre Cassen    :   added ipvs_syncd SyncdID support to filter
  *                                incoming sync messages.
+ *        Horms		      :   Added backwards compatibility code
  *
  *
  *      ippfvsadm - Port Fowarding & Virtual Server ADMinistration program
@@ -301,9 +302,11 @@
 static void list_daemon(void);
 
 static int modprobe_ipvs(void);
-static void check_ipvs_version(void);
+static void check_ipvs_version(char **argv);
 static int process_options(int argc, char **argv, int reading_stdin);
 
+static void exec_old(char **argv);
+
 
 int main(int argc, char **argv)
 {
@@ -319,7 +322,7 @@
 	}
 
 	/* warn the user if the IPVS version is out of date */
-	check_ipvs_version();
+	check_ipvs_version(argv);
 
 	/* list the table if there is no other arguement */
 	if (argc == 1){
@@ -1393,13 +1396,14 @@
 }
 
 
-static void check_ipvs_version(void)
+static void check_ipvs_version(char *argv[])
 {
 	/* verify the IPVS version */
 	if (ipvs_info.version <
 	    IPVS_VERSION(MINIMUM_IPVS_VERSION_MAJOR,
 			 MINIMUM_IPVS_VERSION_MINOR,
 			 MINIMUM_IPVS_VERSION_PATCH)) {
+		exec_old(argv);
 		fprintf(stderr,
 			"Warning: IPVS version missmatch: \n"
 			"  Kernel compiled with IPVS version %d.%d.%d\n"
@@ -1896,3 +1900,46 @@
 
 	return (offset<top)?0:1;
 }
+
+
+/* Simple backwards compat code to exec old version */
+/* Based on code form module-init-tools 3.1 */
+
+#ifndef NO_BACKWARDS_COMPAT
+
+static void exec_old(char **argv)
+{
+	char *sep;
+	pid_t pid;
+	char ascii_pid[32];
+	char pathname[strlen(argv[0])+1];
+	char oldname[strlen(argv[0])+strlen("ipvsadm-1.21")+1];
+
+	memset(pathname, 0, strlen(argv[0])+1);
+	sep = strrchr(argv[0], '/');
+	if (sep)
+		memcpy(pathname, argv[0], sep - argv[0]+1);
+	sprintf(oldname, "%sipvsadm-1.21", pathname);
+
+	/* Use an environment variable for recursion detection */
+	pid = getpid();
+	snprintf(ascii_pid, sizeof(ascii_pid), "%lu", (unsigned long)pid);
+	if (strcmp(getenv("IPVSADM_RECURSE") ?: "", ascii_pid) == 0) {
+		fprintf(stderr, "WARNING: %s: I am not the old version!\n",
+			oldname);
+		return;
+	}
+	setenv("IPVSADM_RECURSE", ascii_pid, 1);
+
+	execvp(oldname, argv);
+	fprintf(stderr,
+		"Kernel requires old ipvsadm, but couldn't run %s: %s\n",
+		oldname, strerror(errno));
+	exit(2);
+}
+
+#else /* NO_BACKWARDS_COMPAT */
+static void exec_old(char **argv)
+{
+}
+#endif /* !NO_BACKWARDS_COMPAT */


More information about the lvs-users mailing list