Что может сделать передачу init =/path/to/program к ядру не, запускают программу как init?

find . -type d -exec chmod 755 {} + -or -type f -exec chmod 644 {} +

find ... -exec ... + похож find ... -exec ... \; за исключением того, что команда выполняется только однажды на большой набор соответствия файлам.

Давным-давно, find OPTIONS... -exec COMMAND... \; должен был действовать на один файл за один раз. Так xargs был изобретен к действиям группы для эффективности. Но xargs представленный его собственная доля проблемы: это ожидает вход, который заключается в кавычки способом это find не может произвести. Так find OPTIONS... | xargs COMMAND... бесполезно, если Вы не знаете, что Ваши имена файлов не содержат ни одного из '"\ или пробел.

Затем GNU изобретен find OPTIONS... -print0 | xargs -0 COMMAND..., который позволяет любому символу появляться в имени файла. Но требовалось много времени, чтобы кто-либо еще принял его, и тем временем Sun (я думаю), изобретенный find OPTIONS... -exec COMMAND... +, который делает то же задание группировки как xargs, без добавленных сложностей (более длительная командная строка, ограничьте одной на find команда). Теперь find ... -exec ... + является стандартным (это находится в Единственном Unix v3), и более широко доступный, чем xargs -0. Если Вы не должны поддерживать совместимость со старой системой Linux, просто забудьте о xargs.

13
30.01.2012, 23:14
4 ответа

Смотря на источник ядра Linux, я вижу, что, если файл/init существует, ядро будет всегда пытаться выполнить его при условии, что он делает начальную загрузку электронного диска. Проверьте свою систему, чтобы видеть, существует ли/init, если это делает, затем это - вероятно, Ваша проблема.

3
27.01.2020, 19:53
  • 1
    На самом деле это проверяет execute_command во-первых, который прибывает из командной строки ядра init= параметр. Если это не может выполнить его, это печатает предупреждение и попытки работать init в различных местоположениях. Это находится в init/main.c в функции init_post(). Я просмотрел ядро printk сообщения и нашел предупреждение в выводе моего ядра, поэтому теперь я должен выяснить, почему это не может запустить/bin/sh или что-либо еще, что я пытаюсь запустить. –  Shawn J. Goff 31.01.2012, 06:00
  • 2
    Код, на который я смотрел (v3.2.2 я думаю) проверенный установил ramdisk_execute_command, если его сбросили и затем попробовали для выполнения его, таким образом, Вы не должны быть то, что текущие. Слишком плохо, потому что я не видел ничто больше, что объяснит это. –  Kyle Jones 31.01.2012, 07:21
  • 3
    Необходимо использовать rdinit при начальной загрузке от электронного диска, по-видимому: unix.stackexchange.com/a/430614/32558 –  Ciro Santilli 新疆改造中心法轮功六四事件 16.03.2018, 14:37

На

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

Я нашел:

При отладке нормальной корневой файловой системы хорошо смочь загрузиться с "init =/bin/sh". initramfs эквивалент "rdinit =/bin/sh", и это столь же полезно.

Так, вероятно, пробуют ridinit =/bin/sh

4
27.01.2020, 19:53

Вы можете настроить ядро ​​Linux и перекомпилировать его. Для ядра 4.9 отредактируйте функцию "kernel_init" в файле init/main.c и попробуйте сначала выполнить следующую строку:

try_to_run_init_process("/bin/sh")

Кроме того, это может быть вызвано параметрами ядра, переданными BootLoader.

0
27.01.2020, 19:53

второстепенные махинации

Если вы используете initrd или initramfs, имейте в виду следующее:

  • rdinit=используется вместоinit=

  • если rdinit=не задано, пробные пути по умолчанию: :/sbin/init, /etc/init, /bin/initи /bin/sh, но не/init

    Если initrd не используется, /initявляется первым пробным путем, за которым следуют остальные.

v4.15 RTFS :все содержится внутри файла https://github.com/torvalds/linux/blob/v4.15/init/main.c.

Сначала мы узнаем, что:

  • execute_comandэто то, что передается:init=
  • ramdisk_execute_commandэто то, что передается:rdinit=

как видно из:

static int __init init_setup(char *str)
{
    unsigned int i;

    execute_command = str;
    /*
    * In case LILO is going to boot us with default command line,
    * it prepends "auto" before the whole cmdline which makes
    * the shell think it should execute a script with such name.
    * So we ignore all arguments entered _before_ init=... [MJ]
    */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("init=", init_setup);

static int __init rdinit_setup(char *str)
{
    unsigned int i;

    ramdisk_execute_command = str;
    /* See "auto" comment in init_setup */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("rdinit=", rdinit_setup);

, где __setup— волшебный способ обработки параметров командной строки.

start_kernel, ядро ​​"точка входа", вызывает rest_init, который "вызывает" kernel_initпоток:

pid = kernel_thread(kernel_init, NULL, CLONE_FS);

Тогда kernel_initделает:

static int __ref kernel_init(void *unused)
{
    int ret;

    kernel_init_freeable();

    [...]

    if (ramdisk_execute_command) {
        ret = run_init_process(ramdisk_execute_command);
        if (!ret)
            return 0;
        pr_err("Failed to execute %s (error %d)\n",
            ramdisk_execute_command, ret);
    }

    [...]

    if (execute_command) {
        ret = run_init_process(execute_command);
        if (!ret)
            return 0;
        panic("Requested init %s failed (error %d).",
            execute_command, ret);
    }
    if (!try_to_run_init_process("/sbin/init") ||
        !try_to_run_init_process("/etc/init") ||
        !try_to_run_init_process("/bin/init") ||
        !try_to_run_init_process("/bin/sh"))
        return 0;

    panic("No working init found.  Try passing init= option to kernel. "
        "See Linux Documentation/admin-guide/init.rst for guidance.");
}

и kernel_init_freeableделает:

static noinline void __init kernel_init_freeable(void)
{

    [...]

    if (!ramdisk_execute_command)
        ramdisk_execute_command = "/init";

    if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
        ramdisk_execute_command = NULL;
        prepare_namespace();
    }

TODO :понять sys_access.

Также обратите внимание, что существуют дополнительные различия между ram-инициалами и не -ram-инициалами, например. работа с консолью:Разница в выполнении init со встроенными и внешними initramfs?

13
27.01.2020, 19:53

Теги

Похожие вопросы