2 * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
3 * Copyright © 2012 Canonical Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <sys/reboot.h>
25 #include <sys/types.h>
28 #include "lxc/namespace.h"
31 #include <linux/sched.h>
32 #include <linux/reboot.h>
34 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...);
36 static int do_reboot(void *arg
)
41 printf("failed to reboot(%d): %m\n", *cmd
);
45 static int test_reboot(int cmd
, int sig
)
47 long stack_size
= 4096;
48 void *stack
= alloca(stack_size
) + stack_size
;
52 ret
= clone(do_reboot
, stack
, CLONE_NEWPID
| SIGCHLD
, &cmd
);
54 printf("failed to clone: %m\n");
58 if (wait(&status
) < 0) {
59 printf("unexpected wait error: %m\n");
63 if (!WIFSIGNALED(status
)) {
65 printf("child process exited but was not signaled\n");
69 if (WTERMSIG(status
) != sig
) {
70 printf("signal termination is not the one expected\n");
77 static int have_reboot_patch(void)
79 FILE *f
= fopen("/proc/sys/kernel/ctrl-alt-del", "r");
86 ret
= fscanf(f
, "%d", &v
);
90 ret
= reboot(v
? LINUX_REBOOT_CMD_CAD_ON
: LINUX_REBOOT_CMD_CAD_OFF
);
96 int main(int argc
, char *argv
[])
101 printf("Must run as root.\n");
105 status
= have_reboot_patch();
107 printf("Your kernel does not have the container reboot patch\n");
111 status
= test_reboot(LINUX_REBOOT_CMD_CAD_ON
, -1);
113 printf("reboot(LINUX_REBOOT_CMD_CAD_ON) should have failed\n");
116 printf("reboot(LINUX_REBOOT_CMD_CAD_ON) has failed as expected\n");
118 status
= test_reboot(LINUX_REBOOT_CMD_RESTART
, SIGHUP
);
121 printf("reboot(LINUX_REBOOT_CMD_RESTART) succeed\n");
123 status
= test_reboot(LINUX_REBOOT_CMD_RESTART2
, SIGHUP
);
126 printf("reboot(LINUX_REBOOT_CMD_RESTART2) succeed\n");
128 status
= test_reboot(LINUX_REBOOT_CMD_HALT
, SIGINT
);
131 printf("reboot(LINUX_REBOOT_CMD_HALT) succeed\n");
133 status
= test_reboot(LINUX_REBOOT_CMD_POWER_OFF
, SIGINT
);
136 printf("reboot(LINUX_REBOOT_CMD_POWERR_OFF) succeed\n");
138 printf("All tests passed\n");