[libvirt] [PATCH] LXC containers don't stopped under some conditions

Maxim Kozin posted 1 patch 5 years, 1 month ago
Test syntax-check passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/1551897551-3122-1-git-send-email-kolomaxes@gmail.com
src/lxc/lxc_driver.c | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
[libvirt] [PATCH] LXC containers don't stopped under some conditions
Posted by Maxim Kozin 5 years, 1 month ago
LXC containers can be started, but time to time  can't be stopped.
1) virsh shutdown with option "--mode initctl" always stop container, but
  virsh report error:
    "Container does not provide an initctl pipe"
  In container present /dev/initctl

2) virsh shutdown with option "--mode signal" never stop lxc container, at
  least for centos 7.5/7.6
  In container log:
    systemd: Received SIGTERM.
    systemd: Reexecuting.
    systemd: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX  +IMA
      -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS
      +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
    systemd: Detected virtualization lxc-libvirt.
    systemd: Detected architecture x86-64.

3) virsh shutdown without option "--mode" can stop lxc container, but in 2 cases:
   - cointainer not under heavy load
   - in gdb when perform step-by-setp debug
   But most often not, with simptoms as with --mode signal.

Patch tested only with host centos 7.6 and guests centos 7.5/7.6

Short comments to patch.
lxcDomainShutdownFlags() return rc=0 and container begin stopped.
We not go to endjob label, but later we pass check:
  if (rc == 0 &&
          (flags == 0 ||
                   (flags & VIR_DOMAIN_SHUTDOWN_SIGNAL))) {
And trying next shutdown method with sigterm to PID 1.
If container heavy loaded, it not stopped. IF not or if you wait in gdb, then
first method succefully perform shutdown.

Signed-off-by: Maxim Kozin <kolomaxes@gmail.com>
---
 src/lxc/lxc_driver.c | 40 ++++++++++++++++++----------------------
 1 file changed, 18 insertions(+), 22 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index b1ef221..760f9f8 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3269,7 +3269,7 @@ lxcDomainShutdownFlags(virDomainPtr dom,
     virLXCDomainObjPrivatePtr priv;
     virDomainObjPtr vm;
     int ret = -1;
-    int rc;
+    int rc = -1;
 
     virCheckFlags(VIR_DOMAIN_SHUTDOWN_INITCTL |
                   VIR_DOMAIN_SHUTDOWN_SIGNAL, -1);
@@ -3298,19 +3298,17 @@ lxcDomainShutdownFlags(virDomainPtr dom,
         (flags & VIR_DOMAIN_SHUTDOWN_INITCTL)) {
         int command = VIR_INITCTL_RUNLEVEL_POWEROFF;
 
-        if ((rc = virLXCDomainSetRunlevel(vm, command)) < 0)
-            goto endjob;
-        if (rc == 0 && flags != 0 &&
-            ((flags & ~VIR_DOMAIN_SHUTDOWN_INITCTL) == 0)) {
-            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                           _("Container does not provide an initctl pipe"));
-            goto endjob;
+        if ((rc = virLXCDomainSetRunlevel(vm, command)) < 0) {
+            if (flags != 0 &&
+                (flags & VIR_DOMAIN_SHUTDOWN_INITCTL)) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                               _("Container does not provide an initctl pipe"));
+                goto endjob;
+            }
         }
-    } else {
-        rc = 0;
     }
 
-    if (rc == 0 &&
+    if (rc < 0 &&
         (flags == 0 ||
          (flags & VIR_DOMAIN_SHUTDOWN_SIGNAL))) {
         if (kill(priv->initpid, SIGTERM) < 0 &&
@@ -3347,7 +3345,7 @@ lxcDomainReboot(virDomainPtr dom,
     virLXCDomainObjPrivatePtr priv;
     virDomainObjPtr vm;
     int ret = -1;
-    int rc;
+    int rc = -1;
 
     virCheckFlags(VIR_DOMAIN_REBOOT_INITCTL |
                   VIR_DOMAIN_REBOOT_SIGNAL, -1);
@@ -3376,19 +3374,17 @@ lxcDomainReboot(virDomainPtr dom,
         (flags & VIR_DOMAIN_REBOOT_INITCTL)) {
         int command = VIR_INITCTL_RUNLEVEL_REBOOT;
 
-        if ((rc = virLXCDomainSetRunlevel(vm, command)) < 0)
-            goto endjob;
-        if (rc == 0 && flags != 0 &&
-            ((flags & ~VIR_DOMAIN_SHUTDOWN_INITCTL) == 0)) {
-            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                           _("Container does not provide an initctl pipe"));
-            goto endjob;
+        if ((rc = virLXCDomainSetRunlevel(vm, command)) < 0) {
+            if (flags != 0 &&
+                (flags & VIR_DOMAIN_REBOOT_INITCTL)) {
+                virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                               _("Container does not provide an initctl pipe"));
+                goto endjob;
+            }
         }
-    } else {
-        rc = 0;
     }
 
-    if (rc == 0 &&
+    if (rc < 0 &&
         (flags == 0 ||
          (flags & VIR_DOMAIN_REBOOT_SIGNAL))) {
         if (kill(priv->initpid, SIGHUP) < 0 &&
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] LXC containers don't stopped under some conditions
Posted by Michal Privoznik 5 years, 1 month ago
On 3/6/19 7:39 PM, Maxim Kozin wrote:
> LXC containers can be started, but time to time  can't be stopped.
> 1) virsh shutdown with option "--mode initctl" always stop container, but
>    virsh report error:
>      "Container does not provide an initctl pipe"
>    In container present /dev/initctl
> 
> 2) virsh shutdown with option "--mode signal" never stop lxc container, at
>    least for centos 7.5/7.6
>    In container log:
>      systemd: Received SIGTERM.
>      systemd: Reexecuting.
>      systemd: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX  +IMA
>        -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS
>        +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
>      systemd: Detected virtualization lxc-libvirt.
>      systemd: Detected architecture x86-64.
> 
> 3) virsh shutdown without option "--mode" can stop lxc container, but in 2 cases:
>     - cointainer not under heavy load
>     - in gdb when perform step-by-setp debug
>     But most often not, with simptoms as with --mode signal.
> 
> Patch tested only with host centos 7.6 and guests centos 7.5/7.6
> 
> Short comments to patch.
> lxcDomainShutdownFlags() return rc=0 and container begin stopped.
> We not go to endjob label, but later we pass check:
>    if (rc == 0 &&
>            (flags == 0 ||
>                     (flags & VIR_DOMAIN_SHUTDOWN_SIGNAL))) {
> And trying next shutdown method with sigterm to PID 1.
> If container heavy loaded, it not stopped. IF not or if you wait in gdb, then
> first method succefully perform shutdown.
> 
> Signed-off-by: Maxim Kozin <kolomaxes@gmail.com>
> ---
>   src/lxc/lxc_driver.c | 40 ++++++++++++++++++----------------------
>   1 file changed, 18 insertions(+), 22 deletions(-)

I've reworeded the commit message, ACKed and pushed.

Congratulations on your first libvirt contribution!

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list