[lvm-devel] LVM2/tools lvm2cmdline.h lvmcmdline.c polldaemon.c

snitzer at sourceware.org snitzer at sourceware.org
Mon Jan 11 19:19:17 UTC 2010


CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	snitzer at sourceware.org	2010-01-11 19:19:17

Modified files:
	tools          : lvm2cmdline.h lvmcmdline.c polldaemon.c 

Log message:
	Only allow one return from poll_daemon().  If a child polldaemon was
	successfully created it must _exit() once it completes.
	
	Update _become_daemon() to differentiate between a failed fork() and a
	successful fork().
	
	Added lvm_return_code() to lvmcmdline.[ch]

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvm2cmdline.h.diff?cvsroot=lvm2&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.110&r2=1.111
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/polldaemon.c.diff?cvsroot=lvm2&r1=1.30&r2=1.31

--- LVM2/tools/lvm2cmdline.h	2008/12/19 18:51:02	1.8
+++ LVM2/tools/lvm2cmdline.h	2010/01/11 19:19:17	1.9
@@ -35,6 +35,7 @@
 void lvm_register_commands(void);
 int lvm_split(char *str, int *argc, char **argv, int max);
 int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
+int lvm_return_code(int ret);
 int lvm_shell(struct cmd_context *cmd, struct cmdline_context *cmdline);
 
 #endif
--- LVM2/tools/lvmcmdline.c	2010/01/11 15:40:04	1.110
+++ LVM2/tools/lvmcmdline.c	2010/01/11 19:19:17	1.111
@@ -1070,6 +1070,11 @@
 	return ret;
 }
 
+int lvm_return_code(int ret)
+{
+	return (ret == ECMD_PROCESSED ? 0 : ret);
+}
+
 int lvm_split(char *str, int *argc, char **argv, int max)
 {
 	char *b = str, *e;
@@ -1389,7 +1394,5 @@
 
       out:
 	lvm_fin(cmd);
-	if (ret == ECMD_PROCESSED)
-		ret = 0;
-	return ret;
+	return lvm_return_code(ret);
 }
--- LVM2/tools/polldaemon.c	2010/01/08 21:53:08	1.30
+++ LVM2/tools/polldaemon.c	2010/01/11 19:19:17	1.31
@@ -15,6 +15,7 @@
 
 #include "tools.h"
 #include "polldaemon.h"
+#include "lvm2cmdline.h"
 #include <signal.h>
 #include <sys/wait.h>
 
@@ -23,6 +24,12 @@
 	while (wait4(-1, NULL, WNOHANG | WUNTRACED, NULL) > 0) ;
 }
 
+/*
+ * returns:
+ * -1 if the fork failed
+ *  0 if the parent
+ *  1 if the child
+ */
 static int _become_daemon(struct cmd_context *cmd)
 {
 	pid_t pid;
@@ -37,7 +44,7 @@
 
 	if ((pid = fork()) == -1) {
 		log_error("fork failed: %s", strerror(errno));
-		return 1;
+		return -1;
 	}
 
 	/* Parent */
@@ -232,12 +239,20 @@
 	}
 }
 
+/*
+ * Only allow *one* return from poll_daemon() (the parent).
+ * If there is a child it must exit (ignoring the memory leak messages).
+ * - 'background' is advisory so a child polldaemon may not be used even
+ *   if it was requested.
+ */
 int poll_daemon(struct cmd_context *cmd, const char *name, const char *uuid,
 		unsigned background,
 		uint32_t lv_type, struct poll_functions *poll_fns,
 		const char *progress_title)
 {
 	struct daemon_parms parms;
+	int daemon_mode = 0;
+	int ret = ECMD_PROCESSED;
 
 	parms.aborting = arg_is_set(cmd, abort_ARG);
 	parms.background = background;
@@ -260,9 +275,11 @@
 	}
 
 	if (parms.background) {
-		if (!_become_daemon(cmd))
-			return ECMD_PROCESSED;	/* Parent */
-		parms.progress_display = 0;
+		daemon_mode = _become_daemon(cmd);
+		if (daemon_mode == 0)
+			return ECMD_PROCESSED;	    /* Parent */
+		else if (daemon_mode == 1)
+			parms.progress_display = 0; /* Child */
 		/* FIXME Use wait_event (i.e. interval = 0) and */
 		/*       fork one daemon per copy? */
 	}
@@ -273,10 +290,21 @@
 	if (name) {
 		if (!_wait_for_single_lv(cmd, name, uuid, &parms)) {
 			stack;
-			return ECMD_FAILED;
+			ret = ECMD_FAILED;
 		}
 	} else
 		_poll_for_all_vgs(cmd, &parms);
 
-	return ECMD_PROCESSED;
+	if (parms.background && daemon_mode == 1) {
+		/*
+		 * child was successfully forked:
+		 * background polldaemon must not return to the caller
+		 * because it will redundantly continue performing the
+		 * caller's task (that the parent already performed)
+		 */
+		/* FIXME Attempt proper cleanup */
+		_exit(lvm_return_code(ret));
+	}
+
+	return ret;
 }




More information about the lvm-devel mailing list