All of lore.kernel.org
 help / color / mirror / Atom feed
From: Serge Hallyn <serge.hallyn@canonical.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Daniel Lezcano <daniel.lezcano@free.fr>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] pidns: reboot_pid_ns: use SEND_SIG_FORCED instead of force_sig()
Date: Mon, 16 Apr 2012 11:24:02 -0500	[thread overview]
Message-ID: <20120416162402.GA7995@sergelap> (raw)
In-Reply-To: <20120416153843.GA9302@redhat.com>

Quoting Oleg Nesterov (oleg@redhat.com):
> On 04/16, Serge Hallyn wrote:
> >
> > Quoting Oleg Nesterov (oleg@redhat.com):
> > >
> > > Strange... I even tested this change, but only in the root namespace.
> > > OK, thanks, I'll investigate. I hope you verified your kernel has
> > > 629d362b commit ;)
> >
> > I took friday's HEAD of Linus tree.  All went fine.  Added this patch.
> > The container can shutdown, but reboot causes shutdown.  Don't undersrtand
> > why.
> 
> Heh. This looks "impossible". I'd like to understand the reason.
> So, LINUX_REBOOT_CMD_RESTART results in WIFSIGNALED() == SIGINT?
> 
> OK, I'll try to test this patch in the non-root namespace.

Playing with the test case below (based on the one Daniel submitted
alongside his container reboot patches), it looks like
WIFSIGNALED(status) and WTERMSIG(status) are 0 with this kernel, not
1 and sig.

-serge

#include <alloca.h>
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <signal.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <linux/sched.h>
#include <linux/reboot.h>

static int do_reboot(void *arg)
{
        int *cmd = arg;

        if (reboot(*cmd))
                printf("failed to reboot(%d): %m\n", *cmd);
}

int test_reboot(int cmd, int sig)
{
        long stack_size = 4096;
        void *stack = alloca(stack_size) + stack_size;
        int status;
        pid_t ret;

        ret = clone(do_reboot, stack, CLONE_NEWPID | SIGCHLD, &cmd);
        if (ret < 0) {
                printf("failed to clone: %m\n");
                return -1;
        }

        if (wait(&status) < 0) {
                printf("unexpected wait error: %m\n");
                return -1;
        }

	printf("WIFSIGNALED is %d\n", WIFSIGNALED(status));

	printf("signal termination is %d, expected %d)\n", WTERMSIG(status), sig);

        if (!WIFSIGNALED(status)) {
		if (sig != -1)
			printf("child process exited but was not signaled\n");
                return -1;
        }

        if (WTERMSIG(status) != sig) {
                printf("signal termination is not the one expected\n");
                return -1;
        }

        return 0;
}

static int have_reboot_patch(void)
{
	FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
	int ret;
	int v;

	if (!f)
		return 0;

	ret = fscanf(f, "%d", &v);
	fclose(f);
	if (ret != 1)
		return 0;
	ret = reboot(v ? LINUX_REBOOT_CMD_CAD_ON : LINUX_REBOOT_CMD_CAD_OFF);
	if (ret != -1)
		return 0;
	return 1;
}

int main(int argc, char *argv[])
{
        int status;

	if (getuid() != 0) {
                printf("Must run as root.\n");
                return 1;
	}

	status = have_reboot_patch();
	if (status != 0) {
                printf("Your kernel does not have the container reboot patch\n");
                return 1;
	}

#if 0
        status = test_reboot(LINUX_REBOOT_CMD_CAD_ON, -1);
        if (status >= 0) {
                printf("reboot(LINUX_REBOOT_CMD_CAD_ON) should have failed\n");
                return 1;
        }
        printf("reboot(LINUX_REBOOT_CMD_CAD_ON) has failed as expected\n");
#endif

        status = test_reboot(LINUX_REBOOT_CMD_RESTART, SIGHUP);
        if (status < 0)
                return 1;
        printf("reboot(LINUX_REBOOT_CMD_RESTART) succeed\n");

        status = test_reboot(LINUX_REBOOT_CMD_RESTART2, SIGHUP);
        if (status < 0)
                return 1;
        printf("reboot(LINUX_REBOOT_CMD_RESTART2) succeed\n");

        status = test_reboot(LINUX_REBOOT_CMD_HALT, SIGINT);
        if (status < 0)
                return 1;
        printf("reboot(LINUX_REBOOT_CMD_HALT) succeed\n");

        status = test_reboot(LINUX_REBOOT_CMD_POWER_OFF, SIGINT);
        if (status < 0)
                return 1;
        printf("reboot(LINUX_REBOOT_CMD_POWERR_OFF) succeed\n");

        printf("All tests passed\n");
        return 0;
}

  reply	other threads:[~2012-04-16 16:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-13  0:44 [PATCH] pidns: reboot_pid_ns: use SEND_SIG_FORCED instead of force_sig() Oleg Nesterov
2012-04-13 18:20 ` Serge Hallyn
2012-04-13 19:24   ` Oleg Nesterov
2012-04-13 19:34     ` Serge Hallyn
2012-04-16 13:59     ` Serge Hallyn
2012-04-16 15:38       ` Oleg Nesterov
2012-04-16 16:24         ` Serge Hallyn [this message]
2012-04-16 21:26           ` Oleg Nesterov
2012-04-17 18:35             ` Oleg Nesterov
2012-04-18  2:29               ` Serge E. Hallyn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120416162402.GA7995@sergelap \
    --to=serge.hallyn@canonical.com \
    --cc=akpm@linux-foundation.org \
    --cc=daniel.lezcano@free.fr \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.