日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

简单理解Busybox下halt/poweroff/reboot实现及区别

發(fā)布時(shí)間:2023/12/13 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 简单理解Busybox下halt/poweroff/reboot实现及区别 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)鍵詞:halt/poweroff/reboot、reboot()、SIGUSR1/SIGTERM/SIGUSR2等。

1. busybox下的halt/poweroff/reboot實(shí)現(xiàn)

通過(guò)applets.h下的halt/poweroff/reboot可知,實(shí)現(xiàn)都在halt_main()中。

IF_HALT(APPLET(halt, BB_DIR_SBIN, BB_SUID_DROP))
IF_POWEROFF(APPLET_ODDNAME(poweroff, halt, BB_DIR_SBIN, BB_SUID_DROP, poweroff))
IF_REBOOT(  APPLET_ODDNAME(reboot,   halt, BB_DIR_SBIN, BB_SUID_DROP, reboot))

下面就看看halt_main(),-d表示延遲多久執(zhí)行操作;-n表示在執(zhí)行操作之前是否執(zhí)行sync();-f表示強(qiáng)制整個(gè)系統(tǒng)直接系統(tǒng)調(diào)用reboot重啟操作,不定義的情況下通過(guò)init。

int halt_main(int argc UNUSED_PARAM, char **argv)
{
    static const int magic[] = {
        RB_HALT_SYSTEM,
        RB_POWER_OFF,
        RB_AUTOBOOT
    };
    static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };------------SIGUSR1表示halt操作;SIGUSR2表示poweroff操作;SIGTERM表示reboot操作。

    int delay = 0;
    int which, flags, rc;

    /* Figure out which applet we're running */
    if (ENABLE_HALT && !ENABLE_POWEROFF && !ENABLE_REBOOT)
        which = 0;
    else
    if (!ENABLE_HALT && ENABLE_POWEROFF && !ENABLE_REBOOT)
        which = 1;
    else
    if (!ENABLE_HALT && !ENABLE_POWEROFF && ENABLE_REBOOT)
        which = 2;
    else
    for (which = 0; "hpr"[which] != applet_name[0]; which++)
        continue;---------------------------------------------------------------根據(jù)applet_name[]來(lái)確定which的值,小技巧實(shí)現(xiàn)了下面kill()和reboot參數(shù)which。

    /* Parse and handle arguments */
    /* We support -w even if !ENABLE_FEATURE_WTMP,
     * in order to not break scripts.
     * -i (shut down network interfaces) is ignored.
     */
    flags = getopt32(argv, "d:+nfwi", &delay);

    sleep(delay);------------------------------------------------延時(shí)多久執(zhí)行操作。
...
if (!(flags & 2)) /* no -n */
        sync();--------------------------------------------------sync()同步操作。

    /* Perform action. */
    rc = 1;
    if (!(flags & 4)) { /* no -f */------------------------------重要區(qū)別是-f是否定義,對(duì)reboot命令影響較大。
...
        if (rc) {
            /* talk to init */
            if (!ENABLE_FEATURE_CALL_TELINIT) {
                /* bbox init assumed */
                rc = kill(1, signals[which]);--------------------對(duì)init進(jìn)程發(fā)送信號(hào),信號(hào)值是由which決定的。
            } else {
...
            }
        }
    } else {
        rc = reboot(magic[which]);------------------------------在定義-f的情況下,執(zhí)行真正的內(nèi)核reboot命令。具體的哪種reboot,也是通過(guò)which決定的。
    }

    if (rc)
        bb_perror_nomsg_and_die();
    return rc;
}

1.1 reboot -f和reboot的區(qū)別

在沒(méi)有-f選項(xiàng)情況下,直接調(diào)用reboot系統(tǒng)調(diào)用;反之,則向init進(jìn)程發(fā)送SIGUSR1/SIGTERM/SIGUSR2信號(hào),經(jīng)由init處理這幾個(gè)信號(hào)來(lái)實(shí)現(xiàn)halt/poweroff/reboot。

check_delayed_sigs()接收SIGUSR[12]/SIGTERM信號(hào),調(diào)用halt_reboot_pwoff()進(jìn)行處理。

halt_reboot_pwoff()執(zhí)行inittab中SHUTDOWN操作,kill所有非init進(jìn)程之后,調(diào)用reboot系統(tǒng)調(diào)用。

static int check_delayed_sigs(void)
{
    int sigs_seen = 0;

    while (1) {
...
        if ((1 << sig) & (0
#ifdef SIGPWR
            + (1 << SIGPWR)
#endif
            + (1 << SIGUSR1)
            + (1 << SIGUSR2)
            + (1 << SIGTERM)
        )) {
            halt_reboot_pwoff(sig);
        }
    }
}

static void halt_reboot_pwoff(int sig) { const char *m; unsigned rb; reset_sighandlers_and_unblock_sigs(); run_shutdown_and_kill_processes();---------------執(zhí)行inittab中的SHUTDOWN action。 m = "halt"; rb = RB_HALT_SYSTEM;-----------------------------默認(rèn)是halt magic。 if (sig == SIGTERM) {----------------------------對(duì)應(yīng)reboot magic。 m = "reboot"; rb = RB_AUTOBOOT; } else if (sig == SIGUSR2) {---------------------對(duì)應(yīng)poweroff magic。 m = "poweroff"; rb = RB_POWER_OFF; } message(L_CONSOLE, "Requesting system %s", m); pause_and_low_level_reboot(rb); /* not reached */ }
static void pause_and_low_level_reboot(unsigned magic) { pid_t pid; sleep(1); pid = vfork(); if (pid == 0) { /* child */ reboot(magic);-------------------------------在子進(jìn)程中執(zhí)行reboot()系統(tǒng)調(diào)用。 _exit(EXIT_SUCCESS); } while (1) sleep(1);------------------------------------init進(jìn)程本身進(jìn)入了while(1)。 }

2. reboot系統(tǒng)調(diào)用

halt/poweroff/reboot三個(gè)busybox命令,分別對(duì)應(yīng)RB_HALT_SYSTEM(0xcdef0123)/RB_POWER_OFF(0x4321fedc)/RB_AUTOBOOT(0x01234567)。

這三個(gè)命令的區(qū),詳細(xì)可以參考kernel_halt()、kernel_power_off()、kernel_restart()。

/*
 * 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)
{
...
    if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
        cmd = LINUX_REBOOT_CMD_HALT;

    mutex_lock(&reboot_mutex);
    switch (cmd) {
    case LINUX_REBOOT_CMD_RESTART:-----------------------對(duì)應(yīng)busybox中的reboot命令。
        kernel_restart(NULL);
        break;
...
    case LINUX_REBOOT_CMD_HALT:--------------------------對(duì)應(yīng)busybox中的halt命令。
        kernel_halt();
        do_exit(0);
        panic("cannot halt");

    case LINUX_REBOOT_CMD_POWER_OFF:---------------------對(duì)應(yīng)busybox中的poweroff命令。
        kernel_power_off();
        do_exit(0);
        break;

    case LINUX_REBOOT_CMD_RESTART2:
        ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
        if (ret < 0) {
            ret = -EFAULT;
            break;
        }
        buffer[sizeof(buffer) - 1] = '';

        kernel_restart(buffer);
        break;
...
    default:
        ret = -EINVAL;
        break;
    }
    mutex_unlock(&reboot_mutex);
    return ret;
}

3. 小結(jié)

halt/poweroff/reboot三個(gè)命令最終都通過(guò)內(nèi)核reboot()系統(tǒng)調(diào)用實(shí)現(xiàn),但是-f選項(xiàng)多了一些操作。

reboot相對(duì)于reboot -f區(qū)別是,可以通過(guò)init對(duì)halt/poweroff/reboot附加一些操作,比如做一些備份操作、同步操作。

不同reboot() magic區(qū)別是,調(diào)用不同kernel_restart()/kernel_halt()/kernel_power_off()。

總結(jié)

以上是生活随笔為你收集整理的简单理解Busybox下halt/poweroff/reboot实现及区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。