--- Begin Message ---
Package: klibc-utils
Version: 2.0.4-8ubuntu3
Severity: normal
Tags: patch
Dear Maintainer,
klibc "reboot" command does not support the reboot syscall argument, so we
cannot do things like "reboot recovery" in devices that follow the Android
partitions conventions.
This bug has been reported in Ubuntu at
<https://bugs.launchpad.net/ubuntu/+source/klibc/+bug/1692494>
It has also been sent upstream at
<http://www.zytor.com/pipermail/klibc/2017-May/003957.html>
The attached patch resolves the issue.
-- System Information:
Debian Release: stretch/sid
APT prefers yakkety-updates
APT policy: (500, 'yakkety-updates'), (500, 'yakkety-security'), (500,
'yakkety-proposed'), (500, 'yakkety'), (100, 'yakkety-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.8.0-53-generic (SMP w/8 CPU cores)
Locale: LANG=es_ES.UTF-8, LC_CTYPE=es_ES.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages klibc-utils depends on:
ii libklibc 2.0.4-8ubuntu3
klibc-utils recommends no packages.
klibc-utils suggests no packages.
-- no debconf information
Description: Add support for reboot syscall argument
Add support to the reboot command so an argument for the 4th parameter
of the syscall can be passed around. This can be useful in, say, devices
that follow Android partitions conventions, so we can do things like
rebootinig to the kernel in recovery partition with "reboot recovery".
Author: Alfonso Sanchez-beato <[email protected]>
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/klibc/+bug/1692494
Forwarded: http://www.zytor.com/pipermail/klibc/2017-May/003957.html
Last-Update: 2017-05-22
--- klibc-2.0.4.orig/usr/include/sys/reboot.h
+++ klibc-2.0.4/usr/include/sys/reboot.h
@@ -16,8 +16,8 @@
#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF
#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
-/* glibc-ish one-argument version */
-__extern int reboot(int);
+/* two-arguments version of reboot */
+__extern int reboot(int, void *);
/* Native four-argument system call */
__extern int __reboot(int, int, int, void *);
--- klibc-2.0.4.orig/usr/klibc/reboot.c
+++ klibc-2.0.4/usr/klibc/reboot.c
@@ -6,10 +6,10 @@
#include <sys/reboot.h>
#include <sys/syscall.h>
-/* This provides the one-argument glibc-ish version of reboot.
+/* This provides two-argument reboot function (glibc flag plus reboot argument).
The full four-argument system call is available as __reboot(). */
-int reboot(int flag)
+int reboot(int flag, void *arg)
{
- return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, NULL);
+ return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, arg);
}
--- klibc-2.0.4.orig/usr/utils/halt.c
+++ klibc-2.0.4/usr/utils/halt.c
@@ -6,7 +6,7 @@
static __noreturn usage(void)
{
- static char mesg[] = "Usage: {halt|reboot|poweroff} [-n]\n";
+ static char mesg[] = "Usage: {halt|reboot|poweroff} [-n] [reboot-arg]\n";
write(2, mesg, sizeof(mesg) - 1);
exit(1);
}
@@ -16,6 +16,7 @@ int main(int argc, char *argv[])
int cmd = 0; /* initalize to shut gcc up */
int do_sync = 1;
char *ptr, *ptr2;
+ char *reboot_arg = NULL;
/* Which action (program name)? */
ptr2 = ptr = argv[0];
@@ -32,23 +33,28 @@ int main(int argc, char *argv[])
usage();
/* Walk options */
- while (*++argv && **argv == '-')
- switch (*++*argv) {
- case 'f':
- break; /* -f assumed */
- case 'n':
- do_sync = 0;
- break;
- default:
- usage();
+ while (*++argv)
+ if (**argv == '-') {
+ switch (*++*argv) {
+ case 'f':
+ break; /* -f assumed */
+ case 'n':
+ do_sync = 0;
+ break;
+ default:
+ usage();
+ }
+ } else if (cmd == LINUX_REBOOT_CMD_RESTART) {
+ reboot_arg = *argv;
+ cmd = LINUX_REBOOT_CMD_RESTART2;
+ } else {
+ usage(); /* args, not reboot == error */
}
- if (*argv)
- usage(); /* any args == error */
if (do_sync)
sync();
- reboot(LINUX_REBOOT_CMD_CAD_OFF); /* Enable CTRL+ALT+DEL */
- if (!reboot(cmd)) {
+ reboot(LINUX_REBOOT_CMD_CAD_OFF, NULL); /* Enable CTRL+ALT+DEL */
+ if (!reboot(cmd, reboot_arg)) {
/* Success. Currently, CMD_HALT returns, so stop the world */
/* kill(-1, SIGSTOP); */
kill(getpid(), SIGSTOP);
Description: Add support for reboot syscall argument
Add support to the reboot command so an argument for the 4th parameter
of the syscall can be passed around. This can be useful in, say, devices
that follow Android partitions conventions, so we can do things like
rebootinig to the kernel in recovery partition with "reboot recovery".
Author: Alfonso Sanchez-beato <[email protected]>
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/klibc/+bug/1692494
Forwarded: http://www.zytor.com/pipermail/klibc/2017-May/003957.html
Last-Update: 2017-05-22
--- klibc-2.0.4.orig/usr/include/sys/reboot.h
+++ klibc-2.0.4/usr/include/sys/reboot.h
@@ -16,8 +16,8 @@
#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF
#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF
-/* glibc-ish one-argument version */
-__extern int reboot(int);
+/* two-arguments version of reboot */
+__extern int reboot(int, void *);
/* Native four-argument system call */
__extern int __reboot(int, int, int, void *);
--- klibc-2.0.4.orig/usr/klibc/reboot.c
+++ klibc-2.0.4/usr/klibc/reboot.c
@@ -6,10 +6,10 @@
#include <sys/reboot.h>
#include <sys/syscall.h>
-/* This provides the one-argument glibc-ish version of reboot.
+/* This provides two-argument reboot function (glibc flag plus reboot argument).
The full four-argument system call is available as __reboot(). */
-int reboot(int flag)
+int reboot(int flag, void *arg)
{
- return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, NULL);
+ return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, arg);
}
--- klibc-2.0.4.orig/usr/utils/halt.c
+++ klibc-2.0.4/usr/utils/halt.c
@@ -6,7 +6,7 @@
static __noreturn usage(void)
{
- static char mesg[] = "Usage: {halt|reboot|poweroff} [-n]\n";
+ static char mesg[] = "Usage: {halt|reboot|poweroff} [-n] [reboot-arg]\n";
write(2, mesg, sizeof(mesg) - 1);
exit(1);
}
@@ -16,6 +16,7 @@ int main(int argc, char *argv[])
int cmd = 0; /* initalize to shut gcc up */
int do_sync = 1;
char *ptr, *ptr2;
+ char *reboot_arg = NULL;
/* Which action (program name)? */
ptr2 = ptr = argv[0];
@@ -32,23 +33,28 @@ int main(int argc, char *argv[])
usage();
/* Walk options */
- while (*++argv && **argv == '-')
- switch (*++*argv) {
- case 'f':
- break; /* -f assumed */
- case 'n':
- do_sync = 0;
- break;
- default:
- usage();
+ while (*++argv)
+ if (**argv == '-') {
+ switch (*++*argv) {
+ case 'f':
+ break; /* -f assumed */
+ case 'n':
+ do_sync = 0;
+ break;
+ default:
+ usage();
+ }
+ } else if (cmd == LINUX_REBOOT_CMD_RESTART) {
+ reboot_arg = *argv;
+ cmd = LINUX_REBOOT_CMD_RESTART2;
+ } else {
+ usage(); /* args, not reboot == error */
}
- if (*argv)
- usage(); /* any args == error */
if (do_sync)
sync();
- reboot(LINUX_REBOOT_CMD_CAD_OFF); /* Enable CTRL+ALT+DEL */
- if (!reboot(cmd)) {
+ reboot(LINUX_REBOOT_CMD_CAD_OFF, NULL); /* Enable CTRL+ALT+DEL */
+ if (!reboot(cmd, reboot_arg)) {
/* Success. Currently, CMD_HALT returns, so stop the world */
/* kill(-1, SIGSTOP); */
kill(getpid(), SIGSTOP);
--- End Message ---