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
29 #include <sys/reboot.h>
30 #include <sys/types.h>
33 #include "namespace.h"
36 #include <linux/sched.h>
37 #include <linux/reboot.h>
39 int clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
, ...);
41 static int do_reboot(void *arg
)
46 printf("failed to reboot(%d): %s\n", *cmd
, strerror(errno
));
51 static int test_reboot(int cmd
, int sig
)
53 long stack_size
= 4096;
54 void *stack
= alloca(stack_size
) + stack_size
;
58 ret
= clone(do_reboot
, stack
, CLONE_NEWPID
| SIGCHLD
, &cmd
);
60 printf("failed to clone: %s\n", strerror(errno
));
64 if (wait(&status
) < 0) {
65 printf("unexpected wait error: %s\n", strerror(errno
));
69 if (!WIFSIGNALED(status
)) {
71 printf("child process exited but was not signaled\n");
76 if (WTERMSIG(status
) != sig
) {
77 printf("signal termination is not the one expected\n");
84 static int have_reboot_patch(void)
86 FILE *f
= fopen("/proc/sys/kernel/ctrl-alt-del", "r");
93 ret
= fscanf(f
, "%d", &v
);
98 ret
= reboot(v
? LINUX_REBOOT_CMD_CAD_ON
: LINUX_REBOOT_CMD_CAD_OFF
);
105 int main(int argc
, char *argv
[])
110 printf("Must run as root.\n");
114 status
= have_reboot_patch();
116 printf("Your kernel does not have the container reboot patch\n");
120 status
= test_reboot(LINUX_REBOOT_CMD_CAD_ON
, -1);
122 printf("reboot(LINUX_REBOOT_CMD_CAD_ON) should have failed\n");
125 printf("reboot(LINUX_REBOOT_CMD_CAD_ON) has failed as expected\n");
127 status
= test_reboot(LINUX_REBOOT_CMD_RESTART
, SIGHUP
);
130 printf("reboot(LINUX_REBOOT_CMD_RESTART) succeed\n");
132 status
= test_reboot(LINUX_REBOOT_CMD_RESTART2
, SIGHUP
);
135 printf("reboot(LINUX_REBOOT_CMD_RESTART2) succeed\n");
137 status
= test_reboot(LINUX_REBOOT_CMD_HALT
, SIGINT
);
140 printf("reboot(LINUX_REBOOT_CMD_HALT) succeed\n");
142 status
= test_reboot(LINUX_REBOOT_CMD_POWER_OFF
, SIGINT
);
145 printf("reboot(LINUX_REBOOT_CMD_POWERR_OFF) succeed\n");
147 printf("All tests passed\n");