
Как мы все знаем, когда мы перезагружаем, выключаем или запускаем систему, на экране появляется некоторое сообщение, вот фрагмент:
Моя система — Ubuntu 16.04, я знаю, что эти сообщения журнала, указанные выше, исходят от systemd.
Насколько я понимаю, обычный пользовательский процесс может печатать что-то на экране, потому что система дает ему три файловых дескриптора: 0, 1 и 2. Мы можем найти их в /proc/<PID>/fd/
. Вот пример:
root@X86-Xenial-6:~# ls /proc/3467/fd
0 1 2 255
Это 3467
программа Hello World, я не знаю, что 225
это, но я знаю, что это 0
, 1
и 2
есть стандартный ввод, стандартный вывод и стандартная ошибка.
Итак, у меня возник вопрос: когда система начинает завершать работу, перезагружаться или запускаться, пользовательский процесс не создается или уничтожается, что означает, что он /proc/
больше не существует, в данном случае 0
, 1
и 2
не существует.
Так почему сообщение, приходящее от systemd, может быть выведено на экран? Ядро может печатать, потому что оно управляет экраном немедленно, но я не думаю, что systemd принадлежит ядру, так как же оно может печатать что-то на экране? Какая функция или API используется?
решение1
Запуск и завершение работы в основном выполняются в пользовательском пространстве, а не ядром. Как только ядро завершает инициализацию, оно ищет init
и запускает его как обычный процесс со стандартными файловыми дескрипторами, указывающими на консоль. Таким образом init
(в вашем случае скрипт initramfs, а затем systemd) может писать в свой стандартный вывод, и все, что он пишет, будет отображаться на экране (или там, где настроен вывод консоли). Это продолжается до тех пор, пока ядро не выключится или не перезагрузится, что происходит после выключения пользовательского пространства (и после того, как все журналы выключения будут записаны на консоль).
Кстати, отметим, что /proc
это всего лишь средство доступа к определенным фрагментам информации, поддерживаемым ядром; эти фрагменты информации существуют независимо от того, /proc
смонтировано оно или нет.
Обратите внимание также, что
Как мы все знаем, когда мы перезагружаем, выключаем или запускаем систему, на экране появляется какое-то сообщение.
не обязательно так — многие системы теперь загружаются и выключаются, не отображая журналы, поэтому мы не можем предполагать, что «мы все знаем».
решение2
Короткий ответ, чтобы прояснить некоторые недопонимания.
- Процесс выполняется в пользовательском пространстве: конкретно,
init
первый пользовательский процесс. - Вам не нужен /proc для существования файловых дескрипторов. Если бы единственный способ доступа к файловым дескрипторам был через файл, то как бы вы получили доступ к файловому дескриптору? (вы бы открыли файл в и
/proc
получили бы файловый дескриптор, попытались бы найти его в и/proc
получили бы файловый дескриптор…)./proc
это всего лишь представление, оно нужно только процессам, которые сообщают о других процессах. - Файловый дескриптор 255
ls
в вашем примере принадлежит каталогу/proc/3467/fd
:ls
должен открыть каталог, поэтому мы ожидаем один дополнительный файловый дескриптор. У нас есть один дополнительный, так что вот что это такое. /proc/fd/1
и т.д. указывают на другие устройства. например1 -> /dev/pts/3
. Сделайтеls -l /proc/self/fd
- При запуске ядра
init
оно подключает свои stdin, stdout, stderr к экрану (устройству tty, которое выводится на экран) или к другому месту. init
это процесс1
(в вашей системеsystemd
).