]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
handle the stop command
authorDaniel Lezcano <dlezcano@fr.ibm.com>
Wed, 7 Oct 2009 14:06:08 +0000 (16:06 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Wed, 7 Oct 2009 14:06:08 +0000 (16:06 +0200)
Handle the stop command. The stop command waits for the peer to
disconnect, that means the peer has exited, so it is safe to
return to the user control. By this way, we ensure a stop command
followed by a start or a destroy won't fail with a race condition
because the start command is not yet finised.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Michel Normand <normand@fr.ibm.com>
src/lxc/commands.c
src/lxc/commands.h
src/lxc/stop.c

index 662ad9e15489749a5655f17aef9e0e2a8dc6213c..4b7f81041099135d764093a992fc1d360a1d0738 100644 (file)
@@ -95,6 +95,8 @@ out_close:
 extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info);
 extern int lxc_console_callback(int fd, struct lxc_request *request,
                        struct lxc_handler *handler);
+extern int lxc_stop_callback(int fd, struct lxc_request *request,
+                       struct lxc_handler *handler);
 
 static int trigger_command(int fd, struct lxc_request *request,
                        struct lxc_handler *handler)
@@ -104,6 +106,7 @@ static int trigger_command(int fd, struct lxc_request *request,
 
        callback cb[LXC_COMMAND_MAX] = {
                [LXC_COMMAND_TTY] = lxc_console_callback,
+               [LXC_COMMAND_STOP] = lxc_stop_callback,
        };
 
        if (request->type < 0 || request->type >= LXC_COMMAND_MAX)
index b6c76c1f44c9bed6dd0f672e12503f837b4870e8..0e72e326fefd081a6fbb318dd6f44f14b9112cff 100644 (file)
@@ -25,6 +25,7 @@
 
 enum {
        LXC_COMMAND_TTY,
+       LXC_COMMAND_STOP,
        LXC_COMMAND_MAX,
 };
 
index 72e2f87ef6c04cdca15252a7aca70e957ad33880..896ab3b20bbfb2f08db4a9335cbc008955446d9a 100644 (file)
 
 #include <lxc/lxc.h>
 #include <lxc/log.h>
+#include "commands.h"
 
 lxc_log_define(lxc_stop, lxc);
 
 #define MAXPIDLEN 20
 
-int lxc_stop(const char *name)
+int __lxc_stop(const char *name)
 {
        char init[MAXPATHLEN];
        char val[MAXPIDLEN];
@@ -73,3 +74,61 @@ out_close:
        close(fd);
        return ret;
 }
+
+int lxc_stop(const char *name)
+{
+       struct lxc_command command = {
+               .request = { .type = LXC_COMMAND_STOP },
+       };
+
+       int ret;
+
+       ret = lxc_command(name, &command);
+       if (ret < 0) {
+               ERROR("failed to send command");
+               return -1;
+       }
+
+       /* we do not expect any answer, because we wait for the connection to be
+        * closed
+        */
+       if (ret > 0) {
+               ERROR("stop request rejected for '%s': %s",
+                       name, strerror(-command.answer.ret));
+               return -1;
+       }
+
+       INFO("'%s' has stopped", name);
+
+       return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * functions used by lxc-start mainloop
+ * to handle above command request.
+ *--------------------------------------------------------------------------*/
+extern int lxc_stop_callback(int fd, struct lxc_request *request,
+                       struct lxc_handler *handler)
+{
+       struct lxc_answer answer;
+       int ret;
+
+       answer.ret = kill(handler->pid, SIGKILL);
+       if (!answer.ret)
+               return 0;
+
+       ret = send(fd, &answer, sizeof(answer), 0);
+       if (ret < 0) {
+               WARN("failed to send answer to the peer");
+               goto out;
+       }
+
+       if (ret != sizeof(answer)) {
+               ERROR("partial answer sent");
+               goto out;
+       }
+
+out:
+       return -1;
+}
+