2
0
mirror of git://github.com/lxc/lxc synced 2025-08-31 15:09:28 +00:00

lxc-monitor multiple paths

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
Dwight Engen
2013-05-07 16:40:49 -04:00
committed by Serge Hallyn
parent 566c0d6dce
commit 8d06bd135a
19 changed files with 165 additions and 69 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -28,6 +28,7 @@ extern "C" {
#endif
#include <stddef.h>
#include <sys/types.h>
#include <lxc/state.h>
struct lxc_msg;
@@ -77,16 +78,36 @@ 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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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]);
}

View File

@@ -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]);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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]);
}

View File

@@ -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]);
}

View File

@@ -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]);
}

View File

@@ -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)