sys_reboot
http://blog.csdn.net/muge0913/article/details/7518576系统调用的内容到这里已经讲述了很多,该到去kernel中窥看一个服务例程具体实现的时候了。在linux中关机和重启命令有shutdown,reboot,init,poweroff,halt,telinit。它们都是通过sys_reboot来实现的。在kernel/sys.c中。
·
http://blog.csdn.net/muge0913/article/details/7518576
系统调用的内容到这里已经讲述了很多,该到去kernel中窥看一个服务例程具体实现的时候了。在linux中关机和重启命令有shutdown,reboot,init,poweroff,halt,telinit。它们都是通过sys_reboot来实现的。在kernel/sys.c中。
- /*
- *kernel/sys.c文件中定义
- * Reboot system call: for obvious reasons only root may call it,
- * and even root needs to set up some magic numbers in the registers
- * so that some mistake won't make this reboot the whole machine.
- * You can also set the meaning of the ctrl-alt-del-key here.
- *
- * reboot doesn't sync: do that yourself before calling this.
- */
- SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
- void __user *, arg)
- {
- char buffer[256];
- int ret = 0;
- /* We only trust the superuser with rebooting the system. */
- /*
- *检查调用者是否有合法权限。capable函数用于检查是否有操作指定资源的权限,
- *如果它返回非零值,则调用者有权进行操作,否则无权操作.
- *capable(CAP_SYS_BOOT)即检查调用者是否有权限使用reboot系统调用
- */
- if (!capable(CAP_SYS_BOOT))
- return -EPERM;
- /* For safety, we require "magic" arguments. */
- /*
- *通过对两个参数magic1和magic2的检测,判断reboot系统调用是不是被偶然调用到的。
- *如果reboot系统调用是被偶然调用的,
- *那么参数magic1和magic2几乎不可能同时满足预定义的这几个数字的集合。
- */
- if (magic1 != LINUX_REBOOT_MAGIC1 ||
- (magic2 != LINUX_REBOOT_MAGIC2 &&
- magic2 != LINUX_REBOOT_MAGIC2A &&
- magic2 != LINUX_REBOOT_MAGIC2B &&
- magic2 != LINUX_REBOOT_MAGIC2C))
- return -EINVAL;
- /* Instead of trying to make the power_off code look like
- * halt when pm_power_off is not set do it the easy way.
- */
- if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
- cmd = LINUX_REBOOT_CMD_HALT;
- mutex_lock(&reboot_mutex);
- /*sys_reboot()对调用者的各种使用情况进行区分。
- *为LINUX_REBOOT_CMD_RESTART时,kernel_restart()将打印出"Restarting system."消息,
- *然后调用machine_restart函数重新启动系统。
- *为LINUX_REBOOT_CMD_CAD_ON或LINUX_REBOOT_CMD_CAD_OFF时,
- *分别允许或禁止Ctrl+Alt+Del组合键。
- *我们还可以在/etc/inittab文件指定是否可以使用Ctrl+Alt+Del组合键来关闭并重启系统。
- *如果希望完全禁止这个功能,需要将/etc/inittab文件中的相应一行注释掉。
- *为LINUX_REBOOT_CMD_HALT时,打印出"System halted."消息,和LINUX_REBOOT_CMD_RESTART情况下类似,
- *但只是暂停系统而不是将其重新启动。为LINUX_REBOOT_CMD_POWER_OFF时,打印出"Power down."消息,然后关闭机器电源。
- *为LINUX_REBOOT_CMD_RESTART2时,接收命令字符串,该字符串说明了系统应该如何关闭。
- *LINUX_REBOOT_CMD_SW_SUSPEND用于使系统休眠。
- */
- switch (cmd) {
- case LINUX_REBOOT_CMD_RESTART:
- kernel_restart(NULL);
- break;
- case LINUX_REBOOT_CMD_CAD_ON:
- C_A_D = 1;
- break;
- case LINUX_REBOOT_CMD_CAD_OFF:
- C_A_D = 0;
- break;
- case LINUX_REBOOT_CMD_HALT:
- kernel_halt();
- do_exit(0);
- panic("cannot halt");
- case LINUX_REBOOT_CMD_POWER_OFF:
- kernel_power_off();
- do_exit(0);
- break;
- case LINUX_REBOOT_CMD_RESTART2:
- if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
- ret = -EFAULT;
- break;
- }
- buffer[sizeof(buffer) - 1] = '\0';
- kernel_restart(buffer);
- break;
- #ifdef CONFIG_KEXEC
- case LINUX_REBOOT_CMD_KEXEC:
- ret = kernel_kexec();
- break;
- #endif
- #ifdef CONFIG_HIBERNATION
- case LINUX_REBOOT_CMD_SW_SUSPEND:
- ret = hibernate();
- break;
- #endif
- default:
- ret = -EINVAL;
- break;
- }
- mutex_unlock(&reboot_mutex);
- return ret;
- }
/*
*kernel/sys.c文件中定义
* Reboot system call: for obvious reasons only root may call it,
* and even root needs to set up some magic numbers in the registers
* so that some mistake won't make this reboot the whole machine.
* You can also set the meaning of the ctrl-alt-del-key here.
*
* reboot doesn't sync: do that yourself before calling this.
*/
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
{
char buffer[256];
int ret = 0;
/* We only trust the superuser with rebooting the system. */
/*
*检查调用者是否有合法权限。capable函数用于检查是否有操作指定资源的权限,
*如果它返回非零值,则调用者有权进行操作,否则无权操作.
*capable(CAP_SYS_BOOT)即检查调用者是否有权限使用reboot系统调用
*/
if (!capable(CAP_SYS_BOOT))
return -EPERM;
/* For safety, we require "magic" arguments. */
/*
*通过对两个参数magic1和magic2的检测,判断reboot系统调用是不是被偶然调用到的。
*如果reboot系统调用是被偶然调用的,
*那么参数magic1和magic2几乎不可能同时满足预定义的这几个数字的集合。
*/
if (magic1 != LINUX_REBOOT_MAGIC1 ||
(magic2 != LINUX_REBOOT_MAGIC2 &&
magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2B &&
magic2 != LINUX_REBOOT_MAGIC2C))
return -EINVAL;
/* Instead of trying to make the power_off code look like
* halt when pm_power_off is not set do it the easy way.
*/
if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
cmd = LINUX_REBOOT_CMD_HALT;
mutex_lock(&reboot_mutex);
/*sys_reboot()对调用者的各种使用情况进行区分。
*为LINUX_REBOOT_CMD_RESTART时,kernel_restart()将打印出"Restarting system."消息,
*然后调用machine_restart函数重新启动系统。
*为LINUX_REBOOT_CMD_CAD_ON或LINUX_REBOOT_CMD_CAD_OFF时,
*分别允许或禁止Ctrl+Alt+Del组合键。
*我们还可以在/etc/inittab文件指定是否可以使用Ctrl+Alt+Del组合键来关闭并重启系统。
*如果希望完全禁止这个功能,需要将/etc/inittab文件中的相应一行注释掉。
*为LINUX_REBOOT_CMD_HALT时,打印出"System halted."消息,和LINUX_REBOOT_CMD_RESTART情况下类似,
*但只是暂停系统而不是将其重新启动。为LINUX_REBOOT_CMD_POWER_OFF时,打印出"Power down."消息,然后关闭机器电源。
*为LINUX_REBOOT_CMD_RESTART2时,接收命令字符串,该字符串说明了系统应该如何关闭。
*LINUX_REBOOT_CMD_SW_SUSPEND用于使系统休眠。
*/
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
kernel_restart(NULL);
break;
case LINUX_REBOOT_CMD_CAD_ON:
C_A_D = 1;
break;
case LINUX_REBOOT_CMD_CAD_OFF:
C_A_D = 0;
break;
case LINUX_REBOOT_CMD_HALT:
kernel_halt();
do_exit(0);
panic("cannot halt");
case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
do_exit(0);
break;
case LINUX_REBOOT_CMD_RESTART2:
if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
ret = -EFAULT;
break;
}
buffer[sizeof(buffer) - 1] = '\0';
kernel_restart(buffer);
break;
#ifdef CONFIG_KEXEC
case LINUX_REBOOT_CMD_KEXEC:
ret = kernel_kexec();
break;
#endif
#ifdef CONFIG_HIBERNATION
case LINUX_REBOOT_CMD_SW_SUSPEND:
ret = hibernate();
break;
#endif
default:
ret = -EINVAL;
break;
}
mutex_unlock(&reboot_mutex);
return ret;
}
更多推荐
已为社区贡献7条内容
所有评论(0)