LINUX.ORG.RU

RFC HOWTO: автологин в иксовую сессию с помощью systemd

 , ,


16

1

Добрый вечер, господа. Это тред-howto о том, как сделать корректный автологин в иксы «на чистом systemd». В вики мне писать влом, да и никто её не читает, а тут и теги указать можно, и людей скастовать. Собственно, да: border-radius, ecko.

В чём вообще проблема? Проблема в том, что значительное количество людей делают это через банальнейшие костыли, настраивая автологин в текстовую консоль и запуская иксы из bashrc (или, чего хуже, из bash_profile). Это плохо по трём причинам:

  • не залогиниться в другую физическую консоль в текстовом режиме
  • оверхед на проделывание цепочки такого вида:
    systemd
    /bin/agetty
    /bin/login
    PAM
    /bin/bash
    ~/.bashrc
    /bin/startx
    
  • в конце концов, это само по себе костыль.

Я предлагаю написать getty-подобный юнит, который будет запускать иксы от фиксированного пользователя с фиксированным номером дисплея на произвольном VT. (Почему так много хардкода? Потому что systemd — не дисплейный менеджер.)

Это тоже неидеальное решение. Например, нафиг идёт мультисит и возникают гонки между запуском иксов и обнаружением видеоустройств. Но этими недостатками мы пренебрежём.

Параграф один. logind, autovt и getty-подобные юниты. Getty могут запускаться двумя способами.

  • Первый — по требованию, через logind. При переключении на ttyN logind запускает юнит autovt@ttyN.service, который засимлинкен на getty@.service. Эта логика работает для tty2-tty6.
  • Второй — статически. Юнит getty@tty1.service включен по умолчанию и втягивается через getty.target. Это даёт нам всегда запущенный getty на tty1.

Соответственно, допустим, у нас есть юнит xorg@.service, который запускает иксы на указанном VT.
Его нужно либо симлинкнуть под именем autovt@ttyN.service, переопределив шаблонный юнит (тогда при переключении на выбранный VT иксы будут запускаться вместо getty — первый способ), либо отключить getty@tty1.service и включить вместо него xorg@tty1.service (тогда мы вместо всегда запущенного getty будем иметь всегда запущенные иксы — второй способ).

Параграф два. Xorg вместо getty. Итак, имеем юнит для иксов, написанный по аналогии с getty@.service: /etc/systemd/system/xorg@.service.

User=<впишитеюзера>
PAMName=login

-- это аналог su.

Conflicts=getty@%i.service
After=getty@%i.service

-- это некоторая защита от одновременного запуска getty на том же терминале.

StandardOutput=tty
StandardInput=tty-fail

-- это указание systemd запускать иксы подсоединёнными напрямую к терминалу, а не к логгеру (нужно для того, чтобы иксы можно было запускать не от рута... ах да, работает только с 1.16 и выше).

ExecStart=/etc/systemd/scripts/startx -D :0

-- это мой велосипед вместо startx с нескучным синтаксисом и exec xinit в конце, что важнее.

Дело в том, что systemd из-за вероятного бага при остановке юнита отправляет SIGTERM/SIGKILL не всем процессам в дереве, начиная с startx, а только самому startx. А поскольку он написан на шелле, то он радостно игнорирует SIGTERM и ждёт завершения xinit, которому никакого сигнала не приходит. Следовательно, проблему решаем переписыванием startx так, чтобы он в конце не запускал xinit подпроцессом, а делал exec xinit, заменяя им собственный процесс. Тогда сигнал приходит xinit'у, а он его корректно ловит и убивает иксы.

Всё остальное скопипащено из getty@.service.

Да, дисплей захардкожен в :0. Пара слов о назначении VT: процесс startx получает номер VT в переменной $XDG_VTNR (её устанавливает pam_systemd), а из startx запускается /etc/X11/xinit/xserverrc, который об этой переменной знает и передаёт X-серверу параметр vt$XDG_VTNR.

Параграф три. Запускаем. Итак, помещаем юнит в /etc/systemd/system/xorg@.service, startx в /etc/systemd/scripts/startx (можно куда угодно) и делаем:

systemctl daemon-reload
systemctl disable getty@tty1
systemctl enable xorg@tty1

После этого можно ребутиться и надеяться, что запустится. Ах да, дисплейный менеджер тоже стоит отключить, потому что он запустит свой X-сервер и произойдёт адъ и израиль.

Как-то так. Сейчас три часа семнадцать минут по московскому времени, поэтому прошу меня извинить за упрт стиль изложения, краткость, неконсистентное использование форматирования и так далее.

★★★★★

Последнее исправление: intelfx (всего исправлений: 4)

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.