窥探 kernel,just for fun --- 分析sys_reboot

本系列文章由张同浩编写,转载请注明出处:http://blog.csdn.net/muge0913/article/details/7518576

邮箱:muge0913@sina.com



系统调用的内容到这里已经讲述了很多,该到去kernel中窥看一个服务例程具体实现的时候了。在linux中关机和重启命令有shutdown,reboot,init,poweroff,halt,telinit。它们都是通过sys_reboot来实现的。在kernel/sys.c中。

  1. /* 
  2.  *kernel/sys.c文件中定义 
  3.  * Reboot system call: for obvious reasons only root may call it, 
  4.  * and even root needs to set up some magic numbers in the registers 
  5.  * so that some mistake won't make this reboot the whole machine. 
  6.  * You can also set the meaning of the ctrl-alt-del-key here. 
  7.  * 
  8.  * reboot doesn't sync: do that yourself before calling this. 
  9.  */  
  10. SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,  
  11.         void __user *, arg)  
  12. {  
  13.     char buffer[256];  
  14.     int ret = 0;  
  15.   
  16.     /* We only trust the superuser with rebooting the system. */  
  17.     /* 
  18.     *检查调用者是否有合法权限。capable函数用于检查是否有操作指定资源的权限, 
  19.     *如果它返回非零值,则调用者有权进行操作,否则无权操作. 
  20.     *capable(CAP_SYS_BOOT)即检查调用者是否有权限使用reboot系统调用 
  21.     */  
  22.     if (!capable(CAP_SYS_BOOT))  
  23.         return -EPERM;  
  24.   
  25.     /* For safety, we require "magic" arguments. */  
  26.     /* 
  27.     *通过对两个参数magic1和magic2的检测,判断reboot系统调用是不是被偶然调用到的。 
  28.     *如果reboot系统调用是被偶然调用的, 
  29.     *那么参数magic1和magic2几乎不可能同时满足预定义的这几个数字的集合。 
  30.     */  
  31.     if (magic1 != LINUX_REBOOT_MAGIC1 ||  
  32.         (magic2 != LINUX_REBOOT_MAGIC2 &&  
  33.                     magic2 != LINUX_REBOOT_MAGIC2A &&  
  34.             magic2 != LINUX_REBOOT_MAGIC2B &&  
  35.                     magic2 != LINUX_REBOOT_MAGIC2C))  
  36.         return -EINVAL;  
  37.   
  38.     /* Instead of trying to make the power_off code look like 
  39.      * halt when pm_power_off is not set do it the easy way. 
  40.      */  
  41.     if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)  
  42.         cmd = LINUX_REBOOT_CMD_HALT;  
  43.   
  44.     mutex_lock(&reboot_mutex);  
  45.     /*sys_reboot()对调用者的各种使用情况进行区分。 
  46.     *为LINUX_REBOOT_CMD_RESTART时,kernel_restart()将打印出"Restarting system."消息, 
  47.     *然后调用machine_restart函数重新启动系统。 
  48.     *为LINUX_REBOOT_CMD_CAD_ON或LINUX_REBOOT_CMD_CAD_OFF时, 
  49.     *分别允许或禁止Ctrl+Alt+Del组合键。 
  50.     *我们还可以在/etc/inittab文件指定是否可以使用Ctrl+Alt+Del组合键来关闭并重启系统。 
  51.     *如果希望完全禁止这个功能,需要将/etc/inittab文件中的相应一行注释掉。 
  52.     *为LINUX_REBOOT_CMD_HALT时,打印出"System halted."消息,和LINUX_REBOOT_CMD_RESTART情况下类似, 
  53.     *但只是暂停系统而不是将其重新启动。为LINUX_REBOOT_CMD_POWER_OFF时,打印出"Power down."消息,然后关闭机器电源。 
  54.     *为LINUX_REBOOT_CMD_RESTART2时,接收命令字符串,该字符串说明了系统应该如何关闭。 
  55.     *LINUX_REBOOT_CMD_SW_SUSPEND用于使系统休眠。 
  56.     */  
  57.     switch (cmd) {  
  58.     case LINUX_REBOOT_CMD_RESTART:  
  59.         kernel_restart(NULL);  
  60.         break;  
  61.   
  62.     case LINUX_REBOOT_CMD_CAD_ON:  
  63.         C_A_D = 1;  
  64.         break;  
  65.   
  66.     case LINUX_REBOOT_CMD_CAD_OFF:  
  67.         C_A_D = 0;  
  68.         break;  
  69.   
  70.     case LINUX_REBOOT_CMD_HALT:  
  71.         kernel_halt();  
  72.         do_exit(0);  
  73.         panic("cannot halt");  
  74.   
  75.     case LINUX_REBOOT_CMD_POWER_OFF:  
  76.         kernel_power_off();  
  77.         do_exit(0);  
  78.         break;  
  79.   
  80.     case LINUX_REBOOT_CMD_RESTART2:  
  81.         if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {  
  82.             ret = -EFAULT;  
  83.             break;  
  84.         }  
  85.         buffer[sizeof(buffer) - 1] = '\0';  
  86.   
  87.         kernel_restart(buffer);  
  88.         break;  
  89.   
  90. #ifdef CONFIG_KEXEC  
  91.     case LINUX_REBOOT_CMD_KEXEC:  
  92.         ret = kernel_kexec();  
  93.         break;  
  94. #endif  
  95.   
  96. #ifdef CONFIG_HIBERNATION  
  97.     case LINUX_REBOOT_CMD_SW_SUSPEND:  
  98.         ret = hibernate();  
  99.         break;  
  100. #endif  
  101.   
  102.     default:  
  103.         ret = -EINVAL;  
  104.         break;  
  105.     }  
  106.     mutex_unlock(&reboot_mutex);  
  107.     return ret;  
  108. }  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值