]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
shutdown: Rework API and lxc-stop
authorStéphane Graber <stgraber@ubuntu.com>
Fri, 31 Jan 2014 13:56:55 +0000 (13:56 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 31 Jan 2014 18:08:33 +0000 (18:08 +0000)
With this change, shutdown() will no longer call stop() after the
timeout, instead it'll just return false and it's up to the caller to
then call stop() if appropriate.

This also updates the bindings, tests and other scripts.

lxc-stop is then updated to do proper option checking and use shutdown,
stop or reboot as appropriate.

Signed-off-by: Stéphane Graber <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/lxc-start-ephemeral.in
src/lxc/lxc_stop.c
src/lxc/lxccontainer.c
src/lxc/lxccontainer.h
src/python-lxc/examples/api_test.py
src/python-lxc/lxc.c
src/tests/shutdowntest.c

index d40ce4eaafe7b4bf03205e2e9cc04c844797f100..62a6194e884e7e4fd595c523631d5a70ca43cbe7 100644 (file)
@@ -270,7 +270,8 @@ if not dest.start() or not dest.wait("RUNNING", timeout=5):
 # Deal with the case where we just attach to the container's console
 if not args.command and not args.daemon:
     dest.console()
-    dest.shutdown(timeout=5)
+    if not dest.shutdown(timeout=5):
+        dest.stop()
     sys.exit(0)
 
 # Try to get the IP addresses
@@ -318,6 +319,7 @@ for ip in ips:
     break
 
 # Shutdown the container
-dest.shutdown(timeout=5)
+if not dest.shutdown(timeout=5):
+    dest.stop()
 
 sys.exit(retval)
index d8de2b01ee7bae32da9c0847e159b1861d09deee..99621a23deae33b8c32d671672332e578528085a 100644 (file)
@@ -77,7 +77,7 @@ Options :\n\
        .options  = my_longopts,
        .parser   = my_parser,
        .checker  = NULL,
-       .timeout = 60,
+       .timeout  = -2,
 };
 
 /* returns -1 on failure, 0 on success */
@@ -95,7 +95,7 @@ static int do_reboot_and_check(struct lxc_arguments *a, struct lxc_container *c)
                return -1;
        if (a->nowait)
                return 0;
-       if (timeout <= 0)
+       if (timeout == 0)
                goto out;
 
        for (;;) {
@@ -118,7 +118,7 @@ static int do_reboot_and_check(struct lxc_arguments *a, struct lxc_container *c)
                if (ret)
                        break;
                elapsed_time = tv.tv_sec - curtime;
-               if (timeout - elapsed_time <= 0)
+               if (timeout != -1 && timeout - elapsed_time <= 0)
                        break;
                timeout -= elapsed_time;
        }
@@ -145,6 +145,46 @@ int main(int argc, char *argv[])
                         my_args.progname, my_args.quiet, my_args.lxcpath[0]))
                return 1;
 
+       /* Set default timeout */
+       if (my_args.timeout == -2) {
+               if (my_args.hardstop) {
+                       my_args.timeout = 0;
+               }
+               else {
+                       my_args.timeout = 60;
+               }
+       }
+
+       if (my_args.nowait) {
+               my_args.timeout = 0;
+       }
+
+       /* some checks */
+       if (!my_args.hardstop && my_args.timeout < -1) {
+               fprintf(stderr, "invalid timeout\n");
+               return 1;
+       }
+
+       if (my_args.hardstop && my_args.nokill) {
+               fprintf(stderr, "-k can't be used with --nokill\n");
+               return 1;
+       }
+
+       if (my_args.hardstop && my_args.reboot) {
+               fprintf(stderr, "-k can't be used with -r\n");
+               return 1;
+       }
+
+       if (my_args.hardstop && my_args.timeout) {
+               fprintf(stderr, "-k doesn't allow timeouts\n");
+               return 1;
+       }
+
+       if (my_args.nolock && !my_args.hardstop) {
+               fprintf(stderr, "--nolock may only be used with -k\n");
+               return 1;
+       }
+
        /* shortcut - if locking is bogus, we should be able to kill
         * containers at least */
        if (my_args.nolock)
@@ -167,24 +207,27 @@ int main(int argc, char *argv[])
                goto out;
        }
 
+       /* kill */
        if (my_args.hardstop) {
                ret = c->stop(c) ? 0 : 1;
                goto out;
        }
+
+       /* reboot */
        if (my_args.reboot) {
                ret = do_reboot_and_check(&my_args, c);
                goto out;
        }
 
-       if (my_args.nokill)
-               my_args.timeout = 0;
-
+       /* shutdown */
        s = c->shutdown(c, my_args.timeout);
        if (!s) {
-               if (!my_args.shutdown)
-                       ret = c->wait(c, "STOPPED", -1) ? 0 : 1;
+               if (my_args.timeout == 0)
+                       ret = 0;
+               else if (my_args.nokill)
+                       ret = 1;
                else
-                       ret = 1; // fail
+                       ret = c->stop(c) ? 0 : 1;
        } else
                ret = 0;
 
index a0a5af579d17e3cc63d94061e15a4f86040d1043..85c644afb1f14aa35723690b171bf1faddc11fcb 100644 (file)
@@ -1348,10 +1348,6 @@ static bool lxcapi_shutdown(struct lxc_container *c, int timeout)
                haltsignal = c->lxc_conf->haltsignal;
        kill(pid, haltsignal);
        retv = c->wait(c, "STOPPED", timeout);
-       if (!retv && timeout > 0) {
-               c->stop(c);
-               retv = c->wait(c, "STOPPED", 0); // 0 means don't wait
-       }
        return retv;
 }
 
index 5f5d9b22a2d3518b020df90bad3a0eeae786add8..92c76b45b68e70b26e1de5af66ef19987e00e235 100644 (file)
@@ -362,12 +362,10 @@ struct lxc_container {
         * SIGPWR.
         *
         * \param c Container.
-        * \param timeout Seconds to wait before forcing a hard stop
-        *  (value must be >0).
+        * \param timeout Seconds to wait before returning false.
+        *  (-1 to wait forever, 0 to avoid waiting).
         *
-        * \return \c true if configuration was loaded successfully, else \c false.
-        *
-        * \note A \p timeout of \c 0 means do not wait.
+        * \return \c true if the container was shutdown successfully, else \c false.
         */
        bool (*shutdown)(struct lxc_container *c, int timeout);
 
index f72cc568a2ac874180541b5b432b5634f9ea72c7..a1fe6f9a211edb5c314c7d65d73f8a04eba272b2 100755 (executable)
@@ -144,7 +144,8 @@ if len(sys.argv) > 1 and sys.argv[1] == "--with-console":
 
 ## Shutting down the container
 print("Shutting down the container")
-container.shutdown(3)
+if not container.shutdown(3):
+    container.stop()
 
 if container.running:
     print("Stopping the container")
index 05727bf00419348e7a4aab11768def7f07549495..9fdc27f492837ba17bd09646df0b4a7af499a40f 100644 (file)
@@ -1591,9 +1591,8 @@ static PyMethodDef Container_methods[] = {
      METH_VARARGS|METH_KEYWORDS,
      "shutdown(timeout = -1) -> boolean\n"
      "\n"
-     "Sends SIGPWR to the container and wait for it to shutdown "
-     "unless timeout is set to a positive value, in which case "
-     "the container will be killed when the timeout is reached."
+     "Sends SIGPWR to the container and wait for it to shutdown."
+     "-1 means wait forever, 0 means skip waiting."
     },
     {"snapshot", (PyCFunction)Container_snapshot,
      METH_VARARGS|METH_KEYWORDS,
index 6e4bb3175812bfe0470beba632c4662ab34154ab..c5d609d893186d8a1391c47c991e06f12cb4704e 100644 (file)
@@ -69,6 +69,9 @@ int main(int argc, char *argv[])
                goto out;
        }
 
+       /* Wait for init to be ready for SIGPWR */
+       sleep(10);
+
        if (!c->shutdown(c, 60)) {
                fprintf(stderr, "%d: failed to shut down %s\n", __LINE__, MYNAME);
                goto out;