Magic numbers of the Linux reboot() system call
Just a guess, but those numbers look more interesting in hex:
672274793 = 0x28121969
85072278 = 0x05121996
369367448 = 0x16041998
537993216 = 0x20112000
Developers' or developers' children's birthdays?
Regarding finding the syscall implementation, I did a git grep -n LINUX_REBOOT_MAGIC2
and found the definition in kernel/sys.c. The symbol sys_reboot
is generated by the SYSCALL_DEFINE4(reboot, ...
gubbins, I suspect.
system call reboot and magic numbers
The significance of the allowed set of magic2 numbers is that, when expressed in hexadecimal, they represent dates-of-birth (specifically, of Linus Torvalds and his three children).
This really lowers the bar on silly interview questions!
Linux reboot system call returns error despite correct arguments
I got this code from this link : Reboot with and without glibc
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#ifdef NO_GLIBC
#include <linux/reboot.h>
#else
#include <sys/reboot.h>
#endif
#ifdef NO_GLIBC
#ifndef LINUX_REBOOT_MAGIC1
#define LINUX_REBOOT_MAGIC1 0xfee1dead
#endif
#ifndef LINUX_REBOOT_MAGIC2
#define LINUX_REBOOT_MAGIC2 0x28121969
#endif
#ifndef LINUX_REBOOT_MAGIC2A
#define LINUX_REBOOT_MAGIC2A 0x05121996
#endif
#ifndef LINUX_REBOOT_MAGIC2B
#define LINUX_REBOOT_MAGIC2B 0x16041998
#endif
#ifndef LINUX_REBOOT_MAGIC2C
#define LINUX_REBOOT_MAGIC2C 0x20112000
#endif
#endif /* NO_GLIBC */
#ifndef LINUX_REBOOT_CMD_RESTART
#define LINUX_REBOOT_CMD_RESTART 0x1234567
#endif
#ifndef LINUX_REBOOT_CMD_HALT
#define LINUX_REBOOT_CMD_HALT 0xcdef0123
#endif
#ifndef LINUX_REBOOT_CMD_POWER_OFF
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc
#endif
#ifndef LINUX_REBOOT_CMD_RESTART2
#define LINUX_REBOOT_CMD_RESTART2 0xa1b3c3d4
#endif
#ifndef LINUX_REBOOT_CMD_CAD_ON
#define LINUX_REBOOT_CMD_CAD_ON 0x89abcdef
#endif
#ifndef LINUX_REBOOT_CMD_CAD_OFF
#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
#endif
static void do_reboot(int command);
int
main(int argc, char *argv[]) {
int reboot_command;
if(argc == 1) {
fprintf(stderr, "No command given.\n");
fprintf(stderr, "Commands: RESTART, HALT, POWER_OFF, CAD_ON,
CAD_OFF.\n");
return(2);
} else if(strcasecmp(argv[1], "RESTART") == 0) {
reboot_command = LINUX_REBOOT_CMD_RESTART;
} else if(strcasecmp(argv[1], "HALT") == 0) {
reboot_command = LINUX_REBOOT_CMD_HALT;
} else if(strcasecmp(argv[1], "POWER_OFF") == 0) {
reboot_command = LINUX_REBOOT_CMD_POWER_OFF;
} else if(strcasecmp(argv[1], "RESTART2") == 0) {
fprintf(stderr, "RESTART2 not supported. Try RESTART.\n");
return(1);
} else if(strcasecmp(argv[1], "CAD_ON") == 0) {
reboot_command = LINUX_REBOOT_CMD_CAD_ON;
} else if(strcasecmp(argv[1], "CAD_OFF") == 0) {
reboot_command = LINUX_REBOOT_CMD_CAD_OFF;
} else {
fprintf(stderr, "%s not supported.\n", argv[1]);
fprintf(stderr, "Commands: RESTART, HALT, POWER_OFF, CAD_ON,
CAD_OFF.\n");
return(2);
}
do_reboot(reboot_command);
// Not reached, unless command was CAD_ON or CAD_OFF.
return(0);
}
static void
do_reboot(int cmd) {
int reboot_status = 0;
// Flush filesystem buffers before rebooting.
sync();
#ifdef NO_GLIBC
// Old libc.
reboot_status = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd,
NULL);
#else
// glibc uses a wrapper around the system call.
reboot_status = reboot(cmd);
#endif
if(reboot_status == -1) {
if(errno == EPERM) {
fprintf(stderr, "Permission denied. Are you root?\n");
}
}
}
From this code, we can understand that the format for reboot
in oldlibc
is :int reboot(int magic, int magic2, unsigned int cmd, void *arg);
and the format for reboot
in glibc
is : int reboot(int cmd);
Reason for Error 22: This error implies "Invalid argument" (EINVAL). glibc
expects single argument in reboot(int cmd)
function call ( glibc uses a wrapper around the system call), but we are giving multiple arguments. That's the reason for the error.
Please see the function call in the above code :
#ifdef NO_GLIBC
// Old libc.
reboot_status = reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd,
NULL);
#else
// glibc uses a wrapper around the system call.
reboot_status = reboot(cmd);
#endif
What do the numbers after command and system call names mean in *nix?
These numbers refer to Unix man sections.
1 Commands available to users
2 Unix and C system calls
3 C library routines for C programs
4 Special file names
5 File formats and conventions for files used by Unix
6 Games
7 Word processing packages
8 System administration commands and procedures
You can specify a section number with the man
command by just listing the section number:
man 1 somecommand
would look for somecommand
in section 1 of the man pages.
Wikipedia has some additional information on this as does this page on how to use man pages.
How to define a system call in Linux with non-default return type?
Returning long
is the only proper way for a system call in Linux.
There is no way for a system call to return a value, which size differs from the size of long
.
Do you expect ssize_t
to have the same size as long
on all platforms? If yes (this is a correct expectation), then there is no reason to prefer ssize_t
over long
. If you are not sure that your return type will fit to long
on every platform, then you simply cannot use this return type.
For example, from the C standard you knows, that read function returns ssize_t
. But read
system call has long
as return type (it is defined using DEFINE_SYSCALL
macro):
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
struct fd f = fdget(fd);
ssize_t ret = -EBADF;
if (f.file) {
loff_t pos = file_pos_read(f.file);
ret = vfs_read(f.file, buf, count, &pos);
file_pos_write(f.file, pos);
fdput(f);
}
return ret;
}
Note, that despite on long
being return type of the system call, the above implementation returns a value of type ssize_t
.
Related Topics
Using Linux, How to Specify Which Ethernet Interface Data Is Transmitted On
Subtract Days from a Date in Bash
Opening a .Tar.Gz File with a Single Command
How to Find the Processor/Chip Architecture on Linux
How to Automate the Installation of Eclipse Plugins with Command Line
How to Export Database Schema in Oracle to a Dump File
How to Divide in the Linux Console
Genymotion Throws Libssl_Conf.So: Cannot Open Shared Object File: No Such File or Directory
Can't Remove a Directory in Unix
How to Change(Hide) the Nginx Server Signature
What Is the Pid in the Host, of a Process Running Inside a Docker Container
Ssh Error When Executing a Remote Command: "Stdin: Is Not a Tty"
Isolate Kernel Module to a Specific Core Using Cpuset
Will Adding the -Rdynamic Linker Option to Gcc/G++ Impact Performance
Command to Get Time in Milliseconds