[lxc-devel] [PATCH v2] lxc-monitor multiple paths

Dwight Engen dwight.engen at oracle.com
Tue May 7 20:40:49 UTC 2013


Signed-off-by: Dwight Engen <dwight.engen at oracle.com>
---
 doc/lxc-monitor.sgml.in  |  7 ++++++
 src/lxc/arguments.c      | 34 +++++++++++++++++++++++++++--
 src/lxc/arguments.h      |  5 ++++-
 src/lxc/lxc.h            | 31 +++++++++++++++++++++-----
 src/lxc/lxc_attach.c     |  8 +++----
 src/lxc/lxc_cgroup.c     |  6 ++---
 src/lxc/lxc_checkpoint.c |  2 +-
 src/lxc/lxc_console.c    |  4 ++--
 src/lxc/lxc_execute.c    |  6 ++---
 src/lxc/lxc_freeze.c     |  4 ++--
 src/lxc/lxc_info.c       |  6 ++---
 src/lxc/lxc_kill.c       |  4 ++--
 src/lxc/lxc_monitor.c    | 35 +++++++++++++++++++++--------
 src/lxc/lxc_restart.c    |  6 ++---
 src/lxc/lxc_start.c      |  6 ++---
 src/lxc/lxc_stop.c       |  4 ++--
 src/lxc/lxc_unfreeze.c   |  4 ++--
 src/lxc/lxc_wait.c       |  5 +++--
 src/lxc/monitor.c        | 57 +++++++++++++++++++++++++++++++-----------------
 19 files changed, 165 insertions(+), 69 deletions(-)

diff --git a/doc/lxc-monitor.sgml.in b/doc/lxc-monitor.sgml.in
index 336061d..b460843 100644
--- a/doc/lxc-monitor.sgml.in
+++ b/doc/lxc-monitor.sgml.in
@@ -63,6 +63,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
       to monitor all the containers, several of them or just one.
     </para>
 
+    <para>
+      The <option>-P, --lxcpath</option>=PATH option may be specified multiple
+      times to monitor more than one container path. Note however that
+      containers with the same name in multiple paths will be
+      indistinguishable in the output.
+    </para>
+
   </refsect1>
 
   &commonoptions;
diff --git a/src/lxc/arguments.c b/src/lxc/arguments.c
index f61c6eb..5f1c1af 100644
--- a/src/lxc/arguments.c
+++ b/src/lxc/arguments.c
@@ -150,13 +150,32 @@ See the %s man page for further information.\n\n",
 	exit(code);
 }
 
+static int lxc_arguments_lxcpath_add(struct lxc_arguments *args,
+				     const char *lxcpath)
+{
+	if (args->lxcpath_additional != -1 &&
+	    args->lxcpath_cnt > args->lxcpath_additional) {
+		fprintf(stderr, "This command only accepts %d -P,--lxcpath arguments\n",
+			args->lxcpath_additional + 1);
+		exit(EXIT_FAILURE);
+	}
+
+	args->lxcpath = realloc(args->lxcpath, (args->lxcpath_cnt + 1) *
+				 sizeof(args->lxcpath[0]));
+	if (args->lxcpath == NULL) {
+		lxc_error(args, "no memory");
+		return ENOMEM;
+	}
+	args->lxcpath[args->lxcpath_cnt++] = lxcpath;
+	return 0;
+}
+
 extern int lxc_arguments_parse(struct lxc_arguments *args,
 			       int argc, char * const argv[])
 {
 	char shortopts[256];
 	int  ret = 0;
 
-	args->lxcpath = default_lxc_path();
 	ret = build_shortopts(args->options, shortopts, sizeof(shortopts));
 	if (ret < 0) {
 		lxc_error(args, "build_shortopts() failed : %s",
@@ -176,7 +195,11 @@ extern int lxc_arguments_parse(struct lxc_arguments *args,
 		case 'l':	args->log_priority = optarg; break;
 		case 'c':	args->console = optarg; break;
 		case 'q':	args->quiet = 1; break;
-		case 'P':	args->lxcpath = optarg; break;
+		case 'P':
+			ret = lxc_arguments_lxcpath_add(args, optarg);
+			if (ret < 0)
+				return ret;
+			break;
 		case OPT_USAGE: print_usage(args->options, args);
 		case '?':	print_help(args, 1);
 		case 'h': 	print_help(args, 0);
@@ -195,6 +218,13 @@ extern int lxc_arguments_parse(struct lxc_arguments *args,
 	args->argv = &argv[optind];
 	args->argc = argc - optind;
 
+	/* If no lxcpaths were given, use default */
+	if (!args->lxcpath_cnt) {
+		ret = lxc_arguments_lxcpath_add(args, default_lxc_path());
+		if (ret < 0)
+			return ret;
+	}
+
 	/* Check the command options */
 
 	if (!args->name) {
diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h
index 6f6826b..002a919 100644
--- a/src/lxc/arguments.h
+++ b/src/lxc/arguments.h
@@ -47,7 +47,10 @@ struct lxc_arguments {
 	const char *console;
 	const char *console_log;
 	const char *pidfile;
-	const char *lxcpath;
+	const char **lxcpath;
+	int lxcpath_cnt;
+	/* set to 0 to accept only 1 lxcpath, -1 for unlimited */
+	int lxcpath_additional;
 
 	/* for lxc-checkpoint/restart */
 	const char *statefile;
diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h
index db921f0..9057757 100644
--- a/src/lxc/lxc.h
+++ b/src/lxc/lxc.h
@@ -28,6 +28,7 @@ extern "C" {
 #endif
 
 #include <stddef.h>
+#include <sys/types.h>
 #include <lxc/state.h>
 
 struct lxc_msg;
@@ -77,17 +78,37 @@ extern int lxc_execute(const char *name, char *const argv[], int quiet,
 extern int lxc_monitor_open(const char *lxcpath);
 
 /*
- * Read the state of the container if this one has changed
- * The function will block until there is an event available
- * @fd : the file descriptor provided by lxc_monitor_open
- * @state : the variable which will be filled with the state
+ * Blocking read for the next container state change
+ * @fd  : the file descriptor provided by lxc_monitor_open
+ * @msg : the variable which will be filled with the state
  * Returns 0 if the monitored container has exited, > 0 if
- * data was readen, < 0 otherwise
+ * data was read, < 0 otherwise
  */
 extern int lxc_monitor_read(int fd, struct lxc_msg *msg);
+
+/*
+ * Blocking read for the next container state change with timeout
+ * @fd      : the file descriptor provided by lxc_monitor_open
+ * @msg     : the variable which will be filled with the state
+ * @timeout : the timeout in seconds to wait for a state change
+ * Returns 0 if the monitored container has exited, > 0 if
+ * data was read, < 0 otherwise
+ */
 extern int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout);
 
 /*
+ * Blocking read from multiple monitors for the next container state
+ * change with timeout
+ * @rfds    : an fd_set of file descriptors provided by lxc_monitor_open
+ * @nfds    : the maximum fd number in rfds + 1
+ * @msg     : the variable which will be filled with the state
+ * @timeout : the timeout in seconds to wait for a state change
+ * Returns 0 if the monitored container has exited, > 0 if
+ * data was read, < 0 otherwise
+ */
+extern int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg, int timeout);
+
+/*
  * Close the fd associated with the monitoring
  * @fd : the file descriptor provided by lxc_monitor_open
  * Returns 0 on success, < 0 otherwise
diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
index 300bc92..e0c253b 100644
--- a/src/lxc/lxc_attach.c
+++ b/src/lxc/lxc_attach.c
@@ -292,11 +292,11 @@ int main(int argc, char *argv[])
 		return ret;
 
 	ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			   my_args.progname, my_args.quiet, my_args.lxcpath);
+			   my_args.progname, my_args.quiet, my_args.lxcpath[0]);
 	if (ret)
 		return ret;
 
-	init_pid = get_init_pid(my_args.name, my_args.lxcpath);
+	init_pid = get_init_pid(my_args.name, my_args.lxcpath[0]);
 	if (init_pid < 0) {
 		ERROR("failed to get the init pid");
 		return -1;
@@ -314,7 +314,7 @@ int main(int argc, char *argv[])
 	 * by asking lxc-start
 	 */
 	if (namespace_flags == -1) {
-		namespace_flags = lxc_get_clone_flags(my_args.name, my_args.lxcpath);
+		namespace_flags = lxc_get_clone_flags(my_args.name, my_args.lxcpath[0]);
 		/* call failed */
 		if (namespace_flags == -1) {
 			ERROR("failed to automatically determine the "
@@ -387,7 +387,7 @@ int main(int argc, char *argv[])
 		}
 
 		if (!elevated_privileges) {
-			ret = lxc_cgroup_attach(grandchild, my_args.name, my_args.lxcpath);
+			ret = lxc_cgroup_attach(grandchild, my_args.name, my_args.lxcpath[0]);
 			if (ret < 0) {
 				ERROR("failed to attach process to cgroup");
 				return -1;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 7684f1b..094686d 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -69,7 +69,7 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
 	state_object = my_args.argv[0];
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
 		value = my_args.argv[1];
 
 	if (value) {
-		if (lxc_cgroup_set(my_args.name, state_object, value, my_args.lxcpath)) {
+		if (lxc_cgroup_set(my_args.name, state_object, value, my_args.lxcpath[0])) {
 			ERROR("failed to assign '%s' value to '%s' for '%s'",
 				value, state_object, my_args.name);
 			return -1;
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
 		int ret;
 		char buffer[len];
 
-		ret = lxc_cgroup_get(my_args.name, state_object, buffer, len, my_args.lxcpath);
+		ret = lxc_cgroup_get(my_args.name, state_object, buffer, len, my_args.lxcpath[0]);
 		if (ret < 0) {
 			ERROR("failed to retrieve value of '%s' for '%s'",
 			      state_object, my_args.name);
diff --git a/src/lxc/lxc_checkpoint.c b/src/lxc/lxc_checkpoint.c
index 8b3a02a..ee41ba1 100644
--- a/src/lxc/lxc_checkpoint.c
+++ b/src/lxc/lxc_checkpoint.c
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
 		return ret;
 
 	ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			   my_args.progname, my_args.quiet, my_args.lxcpath);
+			   my_args.progname, my_args.quiet, my_args.lxcpath[0]);
 	if (ret)
 		return ret;
 
diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c
index 1d779a1..795b54c 100644
--- a/src/lxc/lxc_console.c
+++ b/src/lxc/lxc_console.c
@@ -192,7 +192,7 @@ int main(int argc, char *argv[])
 		return -1;
 
 	err = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			   my_args.progname, my_args.quiet, my_args.lxcpath);
+			   my_args.progname, my_args.quiet, my_args.lxcpath[0]);
 	if (err)
 		return -1;
 
@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	err = lxc_console(my_args.name, my_args.ttynum, &master, my_args.lxcpath);
+	err = lxc_console(my_args.name, my_args.ttynum, &master, my_args.lxcpath[0]);
 	if (err)
 		goto out;
 
diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c
index 0fa2d25..3c070cf 100644
--- a/src/lxc/lxc_execute.c
+++ b/src/lxc/lxc_execute.c
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
 	/* rcfile is specified in the cli option */
@@ -110,7 +110,7 @@ int main(int argc, char *argv[])
 	else {
 		int rc;
 
-		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name);
+		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
 		if (rc == -1) {
 			SYSERROR("failed to allocate memory");
 			return -1;
@@ -137,5 +137,5 @@ int main(int argc, char *argv[])
 	if (lxc_config_define_load(&defines, conf))
 		return -1;
 
-	return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath);
+	return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath[0]);
 }
diff --git a/src/lxc/lxc_freeze.c b/src/lxc/lxc_freeze.c
index ff3cdd5..3bd5e28 100644
--- a/src/lxc/lxc_freeze.c
+++ b/src/lxc/lxc_freeze.c
@@ -55,9 +55,9 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
-	return lxc_freeze(my_args.name, my_args.lxcpath);
+	return lxc_freeze(my_args.name, my_args.lxcpath[0]);
 }
 
diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c
index b19b1d0..f815b0f 100644
--- a/src/lxc/lxc_info.c
+++ b/src/lxc/lxc_info.c
@@ -80,14 +80,14 @@ int main(int argc, char *argv[])
 		return 1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return 1;
 
 	if (!state && !pid)
 		state = pid = true;
 
 	if (state || test_state) {
-		ret = lxc_getstate(my_args.name, my_args.lxcpath);
+		ret = lxc_getstate(my_args.name, my_args.lxcpath[0]);
 		if (ret < 0)
 			return 1;
 		if (test_state)
@@ -97,7 +97,7 @@ int main(int argc, char *argv[])
 	}
 
 	if (pid)
-		printf("pid:%10d\n", get_init_pid(my_args.name, my_args.lxcpath));
+		printf("pid:%10d\n", get_init_pid(my_args.name, my_args.lxcpath[0]));
 
 	return 0;
 }
diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c
index e089931..9a24209 100644
--- a/src/lxc/lxc_kill.c
+++ b/src/lxc/lxc_kill.c
@@ -62,7 +62,7 @@ int main(int argc, char *argv[], char *envp[])
 		return ret;
 
 	ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			   my_args.progname, my_args.quiet, my_args.lxcpath);
+			   my_args.progname, my_args.quiet, my_args.lxcpath[0]);
 	if (ret)
 		return ret;
 
@@ -76,7 +76,7 @@ int main(int argc, char *argv[], char *envp[])
 	} else
 		sig=SIGKILL;
 
-	pid = get_init_pid(my_args.name, my_args.lxcpath);
+	pid = get_init_pid(my_args.name, my_args.lxcpath[0]);
 	if (pid < 0) {
 		ERROR("failed to get the init pid");
 		return -1;
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
index 5ddb291..e41686f 100644
--- a/src/lxc/lxc_monitor.c
+++ b/src/lxc/lxc_monitor.c
@@ -52,6 +52,7 @@ Options :\n\
 	.options  = my_longopts,
 	.parser   = NULL,
 	.checker  = NULL,
+	.lxcpath_additional = -1,
 };
 
 int main(int argc, char *argv[])
@@ -59,14 +60,14 @@ int main(int argc, char *argv[])
 	char *regexp;
 	struct lxc_msg msg;
 	regex_t preg;
-	int fd;
-	int len, rc;
+	fd_set rfds, rfds_save;
+	int len, rc, i, nfds = -1;
 
 	if (lxc_arguments_parse(&my_args, argc, argv))
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
 	len = strlen(my_args.name) + 3;
@@ -87,16 +88,33 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	lxc_monitord_spawn(my_args.lxcpath);
+	if (my_args.lxcpath_cnt > FD_SETSIZE) {
+		ERROR("too many paths requested, only the first %d will be monitored", FD_SETSIZE);
+		my_args.lxcpath_cnt = FD_SETSIZE;
+	}
 
-	fd = lxc_monitor_open(my_args.lxcpath);
-	if (fd < 0)
-		return -1;
+	FD_ZERO(&rfds);
+	for (i = 0; i < my_args.lxcpath_cnt; i++) {
+		int fd;
+
+		lxc_monitord_spawn(my_args.lxcpath[i]);
+
+		fd = lxc_monitor_open(my_args.lxcpath[i]);
+		if (fd < 0)
+			return -1;
+		FD_SET(fd, &rfds);
+		if (fd > nfds)
+			nfds = fd;
+	}
+	memcpy(&rfds_save, &rfds, sizeof(rfds_save));
+	nfds++;
 
 	setlinebuf(stdout);
 
 	for (;;) {
-		if (lxc_monitor_read(fd, &msg) < 0)
+		memcpy(&rfds, &rfds_save, sizeof(rfds));
+
+		if (lxc_monitor_read_fdset(&rfds, nfds, &msg, -1) < 0)
 			return -1;
 
 		msg.name[sizeof(msg.name)-1] = '\0';
@@ -118,4 +136,3 @@ int main(int argc, char *argv[])
 
 	return 0;
 }
-
diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c
index 77099b1..3b8eedc 100644
--- a/src/lxc/lxc_restart.c
+++ b/src/lxc/lxc_restart.c
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
 	/* rcfile is specified in the cli option */
@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
 	else {
 		int rc;
 
-		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name);
+		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
 		if (rc == -1) {
 			SYSERROR("failed to allocate memory");
 			return -1;
@@ -172,7 +172,7 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath);
+	ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath[0]);
 
 	if (my_args.statefile)
 		close(sfd);
diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
index 12aacb8..490dbad 100644
--- a/src/lxc/lxc_start.c
+++ b/src/lxc/lxc_start.c
@@ -165,7 +165,7 @@ int main(int argc, char *argv[])
 		args = my_args.argv;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return err;
 
 	/* rcfile is specified in the cli option */
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
 	else {
 		int rc;
 
-		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name);
+		rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
 		if (rc == -1) {
 			SYSERROR("failed to allocate memory");
 			return err;
@@ -252,7 +252,7 @@ int main(int argc, char *argv[])
 	if (my_args.close_all_fds)
 		conf->close_all_fds = 1;
 
-	err = lxc_start(my_args.name, args, conf, my_args.lxcpath);
+	err = lxc_start(my_args.name, args, conf, my_args.lxcpath[0]);
 
 	/*
 	 * exec ourself, that requires to have all opened fd
diff --git a/src/lxc/lxc_stop.c b/src/lxc/lxc_stop.c
index 0967a15..d7c7283 100644
--- a/src/lxc/lxc_stop.c
+++ b/src/lxc/lxc_stop.c
@@ -55,8 +55,8 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
-	return lxc_stop(my_args.name, my_args.lxcpath);
+	return lxc_stop(my_args.name, my_args.lxcpath[0]);
 }
diff --git a/src/lxc/lxc_unfreeze.c b/src/lxc/lxc_unfreeze.c
index 44d3cc0..095f290 100644
--- a/src/lxc/lxc_unfreeze.c
+++ b/src/lxc/lxc_unfreeze.c
@@ -54,9 +54,9 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
-	return lxc_unfreeze(my_args.name, my_args.lxcpath);
+	return lxc_unfreeze(my_args.name, my_args.lxcpath[0]);
 }
 
diff --git a/src/lxc/lxc_wait.c b/src/lxc/lxc_wait.c
index d21578b..f1a065c 100644
--- a/src/lxc/lxc_wait.c
+++ b/src/lxc/lxc_wait.c
@@ -84,8 +84,9 @@ int main(int argc, char *argv[])
 		return -1;
 
 	if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
-			 my_args.progname, my_args.quiet, my_args.lxcpath))
+			 my_args.progname, my_args.quiet, my_args.lxcpath[0]))
 		return -1;
 
-	return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout, my_args.lxcpath);
+	return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout,
+			my_args.lxcpath[0]);
 }
diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
index 5648b86..c04bb73 100644
--- a/src/lxc/monitor.c
+++ b/src/lxc/monitor.c
@@ -147,33 +147,50 @@ err1:
 	return ret;
 }
 
-int lxc_monitor_read_timeout(int fd, struct lxc_msg *msglxc, int timeout)
+int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg,
+			   int timeout)
 {
-	fd_set rfds;
-	struct timeval tv;
-	int ret;
+	struct timeval tval,*tv = NULL;
+	int ret,i;
 
 	if (timeout != -1) {
-		FD_ZERO(&rfds);
-		FD_SET(fd, &rfds);
-
-		tv.tv_sec = timeout;
-		tv.tv_usec = 0;
-
-		ret = select(fd+1, &rfds, NULL, NULL, &tv);
-		if (ret == -1)
-			return -1;
-		else if (!ret)
-			return -2;  // timed out
+		tv = &tval;
+		tv->tv_sec = timeout;
+		tv->tv_usec = 0;
 	}
 
-	ret = recv(fd, msglxc, sizeof(*msglxc), 0);
-	if (ret <= 0) {
-		SYSERROR("client failed to recv (monitord died?) %s",
-			 strerror(errno));
+	ret = select(nfds, rfds, NULL, NULL, tv);
+	if (ret == -1)
 		return -1;
+	else if (ret == 0)
+		return -2;  // timed out
+
+	/* only read from the first ready fd, the others will remain ready
+	 * for when this routine is called again
+	 */
+	for (i = 0; i < nfds; i++) {
+		if (FD_ISSET(i, rfds)) {
+			ret = recv(i, msg, sizeof(*msg), 0);
+			if (ret <= 0) {
+				SYSERROR("client failed to recv (monitord died?) %s",
+					 strerror(errno));
+				return -1;
+			}
+			return ret;
+		}
 	}
-	return ret;
+	SYSERROR("no ready fd found?");
+	return -1;
+}
+
+int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout)
+{
+	fd_set rfds;
+
+	FD_ZERO(&rfds);
+	FD_SET(fd, &rfds);
+
+	return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout);
 }
 
 int lxc_monitor_read(int fd, struct lxc_msg *msg)
-- 
1.8.1.4





More information about the lxc-devel mailing list