Re: [lxc-devel] [Lxc-users] Request for inclusion into mainline LXC utils

2010-02-04 Thread Guido Trotter
On Wed, Feb 3, 2010 at 7:34 PM,   wrote:
> It seems that we did not the same kind of utils.
> You have made init.d, start, stop and status scripts (for debian-like
> distro).
> It could proposed to the debian package maintainer.

Sure, I'd be happy to have contributions to the debian package! :)
(but let's make sure what can fit in mainline, even as examples,
because that's the best place to make sure we're not drifted apart).
Feel free to send patches my way, on the debian bts, and later to
request alioth git commit access, if you feel you have bigger
contributions to make, over a longer period of time.

Thanks,

Guido

--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 00/10] new enhancements

2010-02-04 Thread Daniel Lezcano
 * console improvements
 * shutdown / poweroff / reboot support


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 01/10] fix compilation warning

2010-02-04 Thread Daniel Lezcano
Add missing include

Signed-off-by: Daniel Lezcano 
---
 src/lxc/state.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: lxc/src/lxc/state.c
===
--- lxc.orig/src/lxc/state.c
+++ lxc/src/lxc/state.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 03/10] use a mainloop for the console

2010-02-04 Thread Daniel Lezcano
Use the mainloop to manage io of the console.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/lxc_console.c |  163 ++
 1 file changed, 88 insertions(+), 75 deletions(-)

Index: lxc/src/lxc/lxc_console.c
===
--- lxc.orig/src/lxc/lxc_console.c
+++ lxc/src/lxc/lxc_console.c
@@ -38,10 +38,10 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-
+#include "error.h"
+#include "lxc.h"
+#include "log.h"
+#include "mainloop.h"
 #include "arguments.h"
 
 lxc_log_define(lxc_console_ui, lxc_console);
@@ -102,7 +102,7 @@ static void sigwinch(int sig)
 
 static int setup_tios(int fd, struct termios *newtios, struct termios *oldtios)
 {
-   if (isatty(fd)) {
+   if (!isatty(fd)) {
ERROR("'%d' is not a tty", fd);
return -1;
}
@@ -132,21 +132,68 @@ static int setup_tios(int fd, struct ter
return 0;
 }
 
+static int stdin_handler(int fd, void *data, struct lxc_epoll_descr *descr)
+{
+   static int wait4q = 0;
+   int *peer = (int *)data;
+   char c;
+
+   if (read(0, &c, 1) < 0) {
+   SYSERROR("failed to read");
+   return 1;
+   }
+
+   /* we want to exit the console with Ctrl+a q */
+   if (c == my_args.escape) {
+   wait4q = !wait4q;
+   return 0;
+   }
+
+   if (c == 'q' && wait4q)
+   return 1;
+
+   wait4q = 0;
+   if (write(*peer, &c, 1) < 0) {
+   SYSERROR("failed to write");
+   return 1;
+   }
+
+   return 0;
+}
+
+static int master_handler(int fd, void *data, struct lxc_epoll_descr *descr)
+{
+   char buf[1024];
+   int *peer = (int *)data;
+   int r;
+
+   r = read(fd, buf, sizeof(buf));
+   if (r < 0) {
+   SYSERROR("failed to read");
+   return 1;
+   }
+   write(*peer, buf, r);
+
+   return 0;
+}
+
 int main(int argc, char *argv[])
 {
-   int wait4q = 0;
-   int err;
+   int err, std_in = 1;
+   struct lxc_epoll_descr descr;
struct termios newtios, oldtios;
 
err = lxc_arguments_parse(&my_args, argc, argv);
if (err)
return -1;
 
-   if (lxc_log_init(my_args.log_file, my_args.log_priority,
-my_args.progname, my_args.quiet))
+   err = lxc_log_init(my_args.log_file, my_args.log_priority,
+  my_args.progname, my_args.quiet);
+   if (err)
return -1;
 
-   if (setup_tios(0, &newtios, &oldtios)) {
+   err = setup_tios(0, &newtios, &oldtios);
+   if (err) {
ERROR("failed to setup tios");
return -1;
}
@@ -158,77 +205,47 @@ int main(int argc, char *argv[])
fprintf(stderr, "\nType  to exit the console\n",
 'a' + my_args.escape - 1);
 
-   if (setsid())
+   err = setsid();
+   if (err)
INFO("already group leader");
 
if (signal(SIGWINCH, sigwinch) == SIG_ERR) {
SYSERROR("failed to set SIGWINCH handler");
-   return -1;
+   err = -1;
+   goto out;
}
 
winsz();
 
-   err = 0;
+   err = lxc_mainloop_open(&descr);
+   if (err) {
+   ERROR("failed to create mainloop");
+   goto out;
+   }
+
+   err = lxc_mainloop_add_handler(&descr, 0, stdin_handler, &master);
+   if (err) {
+   ERROR("failed to add handler for the stdin");
+   goto out_mainloop_open;
+   }
+
+   err = lxc_mainloop_add_handler(&descr, master, master_handler, &std_in);
+   if (err) {
+   ERROR("failed to add handler for the master");
+   goto out_mainloop_open;
+   }
 
-   /* let's proxy the tty */
-   for (;;) {
-   struct pollfd pfd[2] = {
-   { .fd = 0,
- .events = POLLIN|POLLPRI,
- .revents = 0 },
-   { .fd = master,
- .events = POLLIN|POLLPRI,
- .revents = 0 },
-   };
-
-   if (poll(pfd, 2, -1) < 0) {
-   if (errno == EINTR)
-   continue;
-   SYSERROR("failed to poll");
-   goto out_err;
-   }
-   
-   /* read the "stdin" and write that to the master
-*/
-   if (pfd[0].revents & POLLIN) {
-   char c;
-   if (read(0, &c, 1) < 0) {
-   SYSERROR("failed to read");
-   goto out_err;
-   }
-
-   /* we want to exit the console with Ctrl+a q */
-   if (c == my_args.escape) {
-   wai

[lxc-devel] [patch 04/10] Fix header inclusion

2010-02-04 Thread Daniel Lezcano
No need to include the lxc_conf structure definition, a forward
declaration is enough.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/start.h |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Index: lxc/src/lxc/start.h
===
--- lxc.orig/src/lxc/start.h
+++ lxc/src/lxc/start.h
@@ -23,14 +23,14 @@
 #ifndef __lxc_state_h
 #define __lxc_state_h
 
-#include 
 #include 
+#include 
 
-struct lxc_handler {
+struct lxc_conf;
 
+struct lxc_handler {
pid_t pid;
lxc_state_t state;
-
int sigfd;
char nsgroup[MAXPATHLEN];
sigset_t oldmask;


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 02/10] factor-out-console code

2010-02-04 Thread Daniel Lezcano
Factore out the console code and encapsulate the code in
functions.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/lxc_console.c |   67 --
 1 file changed, 43 insertions(+), 24 deletions(-)

Index: lxc/src/lxc/lxc_console.c
===
--- lxc.orig/src/lxc/lxc_console.c
+++ lxc/src/lxc/lxc_console.c
@@ -100,11 +100,43 @@ static void sigwinch(int sig)
winsz();
 }
 
+static int setup_tios(int fd, struct termios *newtios, struct termios *oldtios)
+{
+   if (isatty(fd)) {
+   ERROR("'%d' is not a tty", fd);
+   return -1;
+   }
+
+   /* Get current termios */
+   if (tcgetattr(0, oldtios)) {
+   SYSERROR("failed to get current terminal settings");
+   return -1;
+   }
+
+   *newtios = *oldtios;
+
+   /* Remove the echo characters and signal reception, the echo
+* will be done below with master proxying */
+   newtios->c_iflag &= ~IGNBRK;
+   newtios->c_iflag &= BRKINT;
+   newtios->c_lflag &= ~(ECHO|ICANON|ISIG);
+   newtios->c_cc[VMIN] = 1;
+   newtios->c_cc[VTIME] = 0;
+
+   /* Set new attributes */
+   if (tcsetattr(0, TCSAFLUSH, newtios)) {
+   ERROR("failed to set new terminal settings");
+   return -1;
+   }
+
+   return 0;
+}
+
 int main(int argc, char *argv[])
 {
int wait4q = 0;
int err;
-   struct termios tios, oldtios;
+   struct termios newtios, oldtios;
 
err = lxc_arguments_parse(&my_args, argc, argv);
if (err)
@@ -114,27 +146,8 @@ int main(int argc, char *argv[])
 my_args.progname, my_args.quiet))
return -1;
 
-   /* Get current termios */
-   if (tcgetattr(0, &tios)) {
-   ERROR("failed to get current terminal settings : %s",
- strerror(errno));
-   return -1;
-   }
-
-   oldtios = tios;
-
-   /* Remove the echo characters and signal reception, the echo
-* will be done below with master proxying */
-   tios.c_iflag &= ~IGNBRK;
-   tios.c_iflag &= BRKINT;
-   tios.c_lflag &= ~(ECHO|ICANON|ISIG);
-   tios.c_cc[VMIN] = 1;
-   tios.c_cc[VTIME] = 0;
-
-   /* Set new attributes */
-   if (tcsetattr(0, TCSAFLUSH, &tios)) {
-   ERROR("failed to set new terminal settings : %s",
- strerror(errno));
+   if (setup_tios(0, &newtios, &oldtios)) {
+   ERROR("failed to setup tios");
return -1;
}
 
@@ -145,8 +158,14 @@ int main(int argc, char *argv[])
fprintf(stderr, "\nType  to exit the console\n",
 'a' + my_args.escape - 1);
 
-   setsid();
-   signal(SIGWINCH, sigwinch);
+   if (setsid())
+   INFO("already group leader");
+
+   if (signal(SIGWINCH, sigwinch) == SIG_ERR) {
+   SYSERROR("failed to set SIGWINCH handler");
+   return -1;
+   }
+
winsz();
 
err = 0;


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 07/10] count the number of tasks in the container

2010-02-04 Thread Daniel Lezcano
This patch adds a function to count the number of tasks in the
container.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/cgroup.c |   27 +++
 src/lxc/cgroup.h |2 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

Index: lxc/src/lxc/cgroup.c
===
--- lxc.orig/src/lxc/cgroup.c
+++ lxc/src/lxc/cgroup.c
@@ -219,3 +219,30 @@ int lxc_cgroup_get(const char *name, con
close(fd);
return ret;
 }
+
+int lxc_cgroup_nrtasks(const char *name)
+{
+   char *nsgroup;
+   char path[MAXPATHLEN];
+   int pid, ret, count = 0;
+   FILE *file;
+
+   ret = lxc_cgroup_path_get(&nsgroup, name);
+   if (ret)
+   return -1;
+
+snprintf(path, MAXPATHLEN, "%s/tasks", nsgroup);
+
+   file = fopen(path, "r");
+   if (!file) {
+   SYSERROR("fopen '%s' failed", path);
+   return -1;
+   }
+
+   while (fscanf(file, "%d", &pid) != EOF)
+   count++;
+
+   fclose(file);
+
+   return count;
+}
Index: lxc/src/lxc/cgroup.h
===
--- lxc.orig/src/lxc/cgroup.h
+++ lxc/src/lxc/cgroup.h
@@ -29,5 +29,5 @@ struct lxc_handler;
 int lxc_rename_nsgroup(const char *name, struct lxc_handler *handler);
 int lxc_unlink_nsgroup(const char *name);
 int lxc_cgroup_path_get(char **path, const char *name);
-
+int lxc_cgroup_nrtasks(const char *name);
 #endif


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 05/10] rename network type enum

2010-02-04 Thread Daniel Lezcano
Use a prefixed enum to avoid conflict later.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/conf.c|   14 +++---
 src/lxc/conf.h|   12 ++--
 src/lxc/confile.c |   10 +-
 3 files changed, 18 insertions(+), 18 deletions(-)

Index: lxc/src/lxc/conf.c
===
--- lxc.orig/src/lxc/conf.c
+++ lxc/src/lxc/conf.c
@@ -104,12 +104,12 @@ static int instanciate_vlan(struct lxc_n
 static int instanciate_phys(struct lxc_netdev *);
 static int instanciate_empty(struct lxc_netdev *);
 
-static  instanciate_cb netdev_conf[MAXCONFTYPE + 1] = {
-   [VETH]= instanciate_veth,
-   [MACVLAN] = instanciate_macvlan,
-   [VLAN]= instanciate_vlan,
-   [PHYS]= instanciate_phys,
-   [EMPTY]   = instanciate_empty,
+static  instanciate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
+   [LXC_NET_VETH]= instanciate_veth,
+   [LXC_NET_MACVLAN] = instanciate_macvlan,
+   [LXC_NET_VLAN]= instanciate_vlan,
+   [LXC_NET_PHYS]= instanciate_phys,
+   [LXC_NET_EMPTY]   = instanciate_empty,
 };
 
 static struct mount_opt mount_opt[] = {
@@ -1241,7 +1241,7 @@ int lxc_create_network(struct lxc_list *
 
netdev = iterator->elem;
 
-   if (netdev->type < 0 || netdev->type > MAXCONFTYPE) {
+   if (netdev->type < 0 || netdev->type > LXC_NET_MAXCONFTYPE) {
ERROR("invalid network configuration type '%d'",
  netdev->type);
return -1;
Index: lxc/src/lxc/conf.h
===
--- lxc.orig/src/lxc/conf.h
+++ lxc/src/lxc/conf.h
@@ -29,12 +29,12 @@
 #include 
 
 enum {
-   EMPTY,
-   VETH,
-   MACVLAN,
-   PHYS,
-   VLAN,
-   MAXCONFTYPE,
+   LXC_NET_EMPTY,
+   LXC_NET_VETH,
+   LXC_NET_MACVLAN,
+   LXC_NET_PHYS,
+   LXC_NET_VLAN,
+   LXC_NET_MAXCONFTYPE,
 };
 
 /*
Index: lxc/src/lxc/confile.c
===
--- lxc.orig/src/lxc/confile.c
+++ lxc/src/lxc/confile.c
@@ -132,15 +132,15 @@ static int config_network_type(const cha
lxc_list_add(network, list);
 
if (!strcmp(value, "veth"))
-   netdev->type = VETH;
+   netdev->type = LXC_NET_VETH;
else if (!strcmp(value, "macvlan"))
-   netdev->type = MACVLAN;
+   netdev->type = LXC_NET_MACVLAN;
else if (!strcmp(value, "vlan"))
-   netdev->type = VLAN;
+   netdev->type = LXC_NET_VLAN;
else if (!strcmp(value, "phys"))
-   netdev->type = PHYS;
+   netdev->type = LXC_NET_PHYS;
else if (!strcmp(value, "empty"))
-   netdev->type = EMPTY;
+   netdev->type = LXC_NET_EMPTY;
else {
ERROR("invalid network type %s", value);
return -1;


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 06/10] allocate a console to be proxied

2010-02-04 Thread Daniel Lezcano
The actual behaviour of the console is messy as:
 * it relies on a heuristic (tty or not, rootfs or not, etc ...)
 * the container init stole the tty and we lose the control

The following patch:
 * allocates a tty
 * maps this tty to the container console
 * proxy the io from the console to the file specified in the configuration
 lxc.console=

That allows to specify a file, a fifo, a $(tty), and can be extended with an
uri like file://mypath, net://1.2.3.4:1234, etc ...
That solves the problem with the heuristic and the container does no longer 
stole
our current tty.

Note by default, the console output will go to a blackhole if no configuration 
is
specified making the container showing nothing.

In order to access the console from the tty, use

 lxc-start -n foo -s lxc.console=$(tty)

I propose the make the container to daemonize by default now.

I tried the following:

 in a shell:
  tail --retry -f /var/lib/lxc/foo/console
 in another shell:
  lxc-start -n foo -s lxc.console=$(tty)

Signed-off-by: Daniel Lezcano 
---
 src/lxc/conf.c  |   56 +++-
 src/lxc/conf.h  |   30 ---
 src/lxc/confile.c   |   20 +
 src/lxc/console.c   |   80 +++-
 src/lxc/console.h   |   26 
 src/lxc/lxc_start.c |   45 -
 src/lxc/start.c |   78 --
 7 files changed, 200 insertions(+), 135 deletions(-)

Index: lxc/src/lxc/conf.c
===
--- lxc.orig/src/lxc/conf.c
+++ lxc/src/lxc/conf.c
@@ -641,41 +641,42 @@ out:
return 0;
 }
 
-static int setup_console(const char *rootfs, const char *tty)
+static int setup_console(const char *rootfs, const struct lxc_console *console)
 {
-   char console[MAXPATHLEN];
+   char path[MAXPATHLEN];
+   struct stat s;
 
-   snprintf(console, sizeof(console), "%s/dev/console",
-rootfs ? rootfs : "");
-
-   /* we have the rootfs with /dev/console but no tty
-* to be used as console, let's remap /dev/console
-* to /dev/null to avoid to log to the system console
-*/
-   if (rootfs && !tty[0]) {
+   /* We don't have a rootfs, /dev/console will be shared */
+   if (!rootfs)
+   return 0;
 
-   if (!access(console, F_OK)) {
+   snprintf(path, sizeof(path), "%s/dev/console", rootfs);
 
-   if (mount("/dev/null", console, "none", MS_BIND, 0)) {
-   SYSERROR("failed to mount '/dev/null'->'%s'",
-console);
-   return -1;
-   }
-   }
+   if (access(path, F_OK)) {
+   WARN("rootfs specified but no console found");
+   return 0;
}
 
-   if (!tty[0])
-   return 0;
+   if (console->peer == -1)
+   INFO("no console output required");
 
-   if (access(console, R_OK|W_OK))
-   return 0;
+   if (stat(path, &s)) {
+   SYSERROR("failed to stat '%s'", path);
+   return -1;
+   }
+
+   if (chmod(console->name, s.st_mode)) {
+   SYSERROR("failed to set mode '0%o' to '%s'",
+s.st_mode, console->name);
+   return -1;
+   }
 
-   if (mount(tty, console, "none", MS_BIND, 0)) {
-   ERROR("failed to mount the console");
+   if (mount(console->name, path, "none", MS_BIND, 0)) {
+   ERROR("failed to mount '%s' on '%s'", console->name, path);
return -1;
}
 
-   INFO("console '%s' mounted to '%s'", tty, console);
+   INFO("console has been setup");
 
return 0;
 }
@@ -1073,7 +1074,10 @@ struct lxc_conf *lxc_conf_init(void)
new->utsname = NULL;
new->tty = 0;
new->pts = 0;
-   new->console[0] = '\0';
+   new->console.peer = -1;
+   new->console.master = -1;
+   new->console.slave = -1;
+   new->console.name[0] = '\0';
lxc_list_init(&new->cgroup);
lxc_list_init(&new->network);
lxc_list_init(&new->mount_list);
@@ -1361,7 +1365,7 @@ int lxc_setup(const char *name, struct l
return -1;
}
 
-   if (setup_console(lxc_conf->rootfs, lxc_conf->console)) {
+   if (setup_console(lxc_conf->rootfs, &lxc_conf->console)) {
ERROR("failed to setup the console for '%s'", name);
return -1;
}
Index: lxc/src/lxc/conf.h
===
--- lxc.orig/src/lxc/conf.h
+++ lxc/src/lxc/conf.h
@@ -149,11 +149,31 @@ struct lxc_tty_info {
 };
 
 /*
+ * Defines the structure to store the console information
+ * @peer   : the file descriptor put/get console traffic
+ * @name   : the file name of the slave pty
+ */
+struct lxc_c

[lxc-devel] [patch 08/10] Store the container name in the handler

2010-02-04 Thread Daniel Lezcano
Store the container in the handler, so it is accessible
everywhere.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/start.c |   12 +++-
 src/lxc/start.h |1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

Index: lxc/src/lxc/start.c
===
--- lxc.orig/src/lxc/start.c
+++ lxc/src/lxc/start.c
@@ -196,10 +196,16 @@ struct lxc_handler *lxc_init(const char
 
handler->conf = conf;
 
+   handler->name = strdup(name);
+   if (!handler->name) {
+   ERROR("failed to allocate memory");
+   goto out_free;
+   }
+
/* Begin the set the state to STARTING*/
if (lxc_set_state(name, handler, STARTING)) {
ERROR("failed to set state '%s'", lxc_state2str(STARTING));
-   goto out_free;
+   goto out_free_name;
}
 
if (lxc_create_tty(name, conf)) {
@@ -234,6 +240,9 @@ out_delete_tty:
lxc_delete_tty(&conf->tty_info);
 out_aborting:
lxc_set_state(name, handler, ABORTING);
+out_free_name:
+   free(handler->name);
+   handler->name = NULL;
 out_free:
free(handler);
return NULL;
@@ -249,6 +258,7 @@ void lxc_fini(const char *name, struct l
lxc_unlink_nsgroup(name);
 
lxc_delete_tty(&handler->conf->tty_info);
+   free(handler->name);
free(handler);
 
LXC_TTY_DEL_HANDLER(SIGQUIT);
Index: lxc/src/lxc/start.h
===
--- lxc.orig/src/lxc/start.h
+++ lxc/src/lxc/start.h
@@ -30,6 +30,7 @@ struct lxc_conf;
 
 struct lxc_handler {
pid_t pid;
+   char *name;
lxc_state_t state;
int sigfd;
char nsgroup[MAXPATHLEN];


--
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [patch 10/10] reboot the container at reboot

2010-02-04 Thread Daniel Lezcano
When the reboot is detected, reboot the container.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/commands.c  |7 +++
 src/lxc/conf.c  |6 --
 src/lxc/conf.h  |1 +
 src/lxc/confile.c   |   30 +++---
 src/lxc/lxc.h   |3 ++-
 src/lxc/lxc_start.c |   19 ++-
 src/lxc/start.c |3 +++
 src/lxc/utmp.c  |3 ++-
 8 files changed, 52 insertions(+), 20 deletions(-)

Index: lxc/src/lxc/commands.c
===
--- lxc.orig/src/lxc/commands.c
+++ lxc/src/lxc/commands.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -228,6 +229,12 @@ extern int lxc_command_mainloop_add(cons
return -1;
}
 
+   if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
+   SYSERROR("failed to set sigfd to close-on-exec");
+   close(fd);
+   return -1;
+   }
+
ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler, 
handler);
if (ret) {
ERROR("failed to add handler for command socket");
Index: lxc/src/lxc/lxc.h
===
--- lxc.orig/src/lxc/lxc.h
+++ lxc/src/lxc/lxc.h
@@ -43,9 +43,10 @@ struct lxc_conf;
  * Start the specified command inside a container
  * @name : the name of the container
  * @argv : an array of char * corresponding to the commande line
+ * @conf : configuration
  * Returns 0 on sucess, < 0 otherwise
  */
-extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *);
+extern int lxc_start(const char *name, char *const argv[], struct lxc_conf 
*conf);
 
 /*
  * Stop the container previously started with lxc_start, all
Index: lxc/src/lxc/lxc_start.c
===
--- lxc.orig/src/lxc/lxc_start.c
+++ lxc/src/lxc/lxc_start.c
@@ -90,17 +90,15 @@ Options :\n\
 
 int main(int argc, char *argv[])
 {
-   char *const *args;
int err = -1;
-
+   struct lxc_conf *conf;
+   char *const *args;
+   char *rcfile = NULL;
char *const default_args[] = {
"/sbin/init",
'\0',
};
 
-   char *rcfile = NULL;
-   struct lxc_conf *conf;
-
lxc_list_init(&defines);
 
if (lxc_arguments_parse(&my_args, argc, argv))
@@ -176,6 +174,17 @@ int main(int argc, char *argv[])
 
err = lxc_start(my_args.name, args, conf);
 
+   /*
+* exec ourself, that requires to have all opened fd
+* with the close-on-exec flag set
+*/
+   if (conf->reboot) {
+   INFO("rebooting container");
+   execvp(argv[0], argv);
+   SYSERROR("failed to exec");
+   err = -1;
+   }
+
return err;
 }
 
Index: lxc/src/lxc/start.c
===
--- lxc.orig/src/lxc/start.c
+++ lxc/src/lxc/start.c
@@ -471,6 +471,9 @@ int lxc_start(const char *name, char *co
while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
continue;
 
+   if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
+   WARN("failed to restore sigprocmask");
+
err =  lxc_error_set_and_log(handler->pid, status);
 out_fini:
lxc_fini(name, handler);
Index: lxc/src/lxc/utmp.c
===
--- lxc.orig/src/lxc/utmp.c
+++ lxc/src/lxc/utmp.c
@@ -94,7 +94,8 @@ static int utmp_handler(int fd, void *da
}
 
if (currun_level == '6') {
-   INFO("container has reboot");
+   INFO("container has rebooted");
+   conf->reboot = 1;
kill(handler->pid, SIGKILL);
}
}
Index: lxc/src/lxc/conf.c
===
--- lxc.orig/src/lxc/conf.c
+++ lxc/src/lxc/conf.c
@@ -1068,12 +1068,6 @@ struct lxc_conf *lxc_conf_init(void)
}
memset(new, 0, sizeof(*new));
 
-   new->rootfs = NULL;
-   new->pivotdir = NULL;
-   new->fstab = NULL;
-   new->utsname = NULL;
-   new->tty = 0;
-   new->pts = 0;
new->console.peer = -1;
new->console.master = -1;
new->console.slave = -1;
Index: lxc/src/lxc/conf.h
===
--- lxc.orig/src/lxc/conf.h
+++ lxc/src/lxc/conf.h
@@ -181,6 +181,7 @@ struct lxc_conf {
char *fstab;
int tty;
int pts;
+   int reboot;
struct utsname *utsname;
struct lxc_list cgroup;
struct lxc_list network;
Index: lxc/src/lxc/confile.c
===
--- lxc.orig/src/lxc/confile.c
+++ lxc/src/lxc/confile.c
@@ -692,22 +692,34 @@ static int config_utsname(const char *ke
 sta

[lxc-devel] [patch 09/10] shutdown container when powering off the container

2010-02-04 Thread Daniel Lezcano
This patch allows to shutdown the container when the system
is powered off in the container.

Signed-off-by: Daniel Lezcano 
---
 src/lxc/Makefile.am |6 +-
 src/lxc/start.c |   11 +++
 src/lxc/utmp.c  |  156 
 src/lxc/utmp.h  |   28 +
 4 files changed, 198 insertions(+), 3 deletions(-)

Index: lxc/src/lxc/Makefile.am
===
--- lxc.orig/src/lxc/Makefile.am
+++ lxc/src/lxc/Makefile.am
@@ -18,7 +18,7 @@ so_PROGRAMS = liblxc.so
 liblxc_so_SOURCES = \
arguments.c arguments.h \
commands.c commands.h \
-   start.c \
+   start.c start.h \
stop.c \
monitor.c monitor.h \
console.c \
@@ -43,7 +43,9 @@ liblxc_so_SOURCES = \
 genl.c genl.h \
\
mainloop.c mainloop.h \
-   af_unix.c af_unix.h
+   af_unix.c af_unix.h \
+   \
+   utmp.c utmp.h
 
 AM_CFLAGS=-I$(top_srcdir)/src
 
Index: lxc/src/lxc/start.c
===
--- lxc.orig/src/lxc/start.c
+++ lxc/src/lxc/start.c
@@ -91,10 +91,12 @@ int signalfd(int fd, const sigset_t *mas
 #include "start.h"
 #include "conf.h"
 #include "log.h"
+#include "cgroup.h"
 #include "error.h"
 #include "af_unix.h"
 #include "mainloop.h"
 #include "utils.h"
+#include "utmp.h"
 #include "monitor.h"
 #include "commands.h"
 #include "console.h"
@@ -172,8 +174,15 @@ int lxc_poll(const char *name, struct lx
goto out_mainloop_open;
}
 
-   if (lxc_command_mainloop_add(name, &descr, handler))
+   if (lxc_command_mainloop_add(name, &descr, handler)) {
+   ERROR("failed to add command handler to mainloop");
goto out_mainloop_open;
+   }
+
+   if (lxc_utmp_mainloop_add(&descr, handler)) {
+   ERROR("failed to add utmp handler to mainloop");
+   goto out_mainloop_open;
+   }
 
return lxc_mainloop(&descr);
 
Index: lxc/src/lxc/utmp.c
===
--- /dev/null
+++ lxc/src/lxc/utmp.c
@@ -0,0 +1,156 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "conf.h"
+#include "cgroup.h"
+#include "start.h"
+#include "mainloop.h"
+#include "lxc.h"
+#include "log.h"
+#define __USE_GNU
+#include 
+#undef __USE_GNU
+
+lxc_log_define(lxc_utmp, lxc);
+
+static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
+{
+   struct inotify_event ie;
+   struct utmpx *utmpx;
+   struct lxc_handler *handler = (struct lxc_handler *)data;
+   struct lxc_conf *conf = handler->conf;
+   char prevrun_level = 'N', currun_level = 'N';
+   int ntasks, ret;
+   char path[MAXPATHLEN];
+
+   if (read(fd, &ie, sizeof(ie)) < 0) {
+   SYSERROR("failed to read utmp notification");
+   return -1;
+   }
+
+   if (snprintf(path, MAXPATHLEN, "%s/var/run/utmp", conf->rootfs) >
+   MAXPATHLEN) {
+   ERROR("path is too long");
+   return -1;
+   }
+
+   if (utmpxname(path)) {
+   SYSERROR("failed to 'utmpxname'");
+   return -1;
+   }
+
+   setutxent();
+
+   while ((utmpx = getutxent())) {
+
+   if (utmpx->ut_type == RUN_LVL) {
+   prevrun_level = utmpx->ut_pid / 256;
+   currun_level = utmpx->ut_pid % 256;
+   }
+   }
+
+   ntasks = lxc_cgroup_nrtasks(handler->name);
+   if (ntasks < 0) {
+   ERROR("failed to get the number of tasks");
+   goto out;
+   }
+
+   if (ntasks == 1 && prevrun_level == '3') {
+
+   DEBUG("run level is %c/%c", prevrun_level, currun_level);
+   DEBUG("there is %d tasks remaining", ntasks);
+
+   if (currun_level == '0') {
+   INFO("container has shutdown");
+   kill(handler->pid, SIGKILL);
+   }
+
+   if (currun_level == '6') {
+