служба systemd при завершении работы с доступом к диску [резервная копия]

Если вы использовали LVM во время установки, вы можете проверить дату создания логического тома в день установки, например:

$ sudo lvdisplay /dev/mapper/KUbuntu_VG-rootFS | grep Creation
  LV Creation host, time kubuntu, 2014-12-28 20:52:15 +0100
1
15.11.2019, 16:10
1 ответ

Хорошо, я нашел проблему и смог создать правильно работающее решение, которое по большей части следует рабочему процессу systemd().

Выпуск

Следующая служба, хотя на первый взгляд выглядит корректно, никогда не будет выполняться:

# poweroff-backup.service
[Unit]
Description=Backup on poweroff to external encrypted USB disk.
DefaultDependencies=no
Before=shutdown.target

# This causes the service to be discarded/skipped due to
# a dependency cycle conflict. See below... 
Requires=systemd-cryptsetup@ext.service
After=systemd-cryptsetup@ext.service
Before=umount.target

[Service]
Type=oneshot
# Note:  The script executed here needs access to '/', '/tmp' 
# (or Systemd's PrivateTemp) and '/dev/mapper/ext' which is the 
# decrypted USB partition managed by /etc/crypttab and 
# systemd-cryptsetup-generator (as systemd-cryptsetup@ext.service)
ExecStart=/usr/bin/sleep 30
TimeoutSec=infinity
# Note: This does not make any difference
RemainAfterExit=yes

[Install]
WantedBy=poweroff.target

Причина, по которой эта служба никогда не будет запущена, заключается в том, что существует проблема/конфликт цикла зависимостей между poweroff.target -[require]-> shutdown.target -[conflicts]-> cryptsetup.target <-[require]- systemd-cryptsetup@ext.service <-[require]- poweroff-backup.service <-[wants]- poweroff.target, где shutdown.target конфликтует с cryptsetup.target, чтобы гарантировать отсоединение всех зашифрованных дисков перед завершением работы (выключение питания/перезагрузка )и poweroff -backup.service, который необходимо активировать с помощью poweroff.target.

Решение

Зная это, очевидная проблема заключается в моем ошибочном предположении, что systemd каким-то образом может избежать этого конфликта цикла зависимостей, зная, что poweroff -backup.service — это « one -shot « сервис, который может быть решена сначала с помощью systemd, продолжая нормальный переход к выключению после того, как poweroff -backup.service был активирован и перешел в состояние неактивно/сделано.

Итак, вот служба, которая использует ExecStop= вместо ExecStart=, что позволяет нам избежать циклов зависимостей -, но имеет некоторые небольшие оговорки:

# poweroff-backup.service
[Unit]
Description=Backup external encrypted USB disk on poweroff.
Requires=systemd-cryptsetup@ext.service
After=multi-user.target
After=systemd-cryptsetup@ext.service

[Service]
Type=oneshot
ExecStart=/usr/bin/echo "Waiting for poweroff..."
# Note: We need this, since there is no other way to detect poweroff vs reboot now.
ExecStop=/usr/bin/systemctl list-jobs | /usr/bin/egrep -q 'poweroff.target.*start'
# Note: This should be replaced with your script
ExecStart=/usr/bin/sleep 30
TimeoutSec=infinity
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

Это работает, потому что:

  • Это предотвращает проблему цикла зависимости, вызванную shutdown.target, cryptsetup.target и poweroff -backup.service
  • Правильный рабочий порядок по-прежнему сохраняется, так как systemd гарантирует, что порядок выключения является обратным порядку запуска (, заданному After= и Before=)

У меня есть только две незначительные претензии к этому решению:

  • Поскольку служба запускается при входе в систему, она также расшифровывает внешний USB-диск при входе в систему. Я бы предпочел, чтобы это происходило только после выполнения фактического сценария резервного копирования -с использованием обычного порядка systemd After= и Require= и механики зависимостей. Это можно решить, добавив следующее, но это будет означать, что я не использую службу cryptsetup для расшифровки/отсоединения USB-диска:

    ExecStop=/usr/lib/systemd/systemd-cryptsetup attach ext
    [...]
    ExecStop=/usr/lib/systemd/systemd-cryptsetup detach ext
    
  • У меня нет способа условно выполнить ExecStop= только при выключении, ссылаясь на shutdown.target, и мне приходится полагаться на небольшую вспомогательную команду с помощью systemctl list-jobs.

Вопрос:Кто-нибудь знает, как улучшить эти моменты?

Полный служебный файл

Это мой текущий файл службы, который запускает службу только после подключения USB-диска путем присоединения (WantedBy= )к USB-устройству (по его UUID )вместо множественного -пользователь.цель:

# poweroff-backup.service
[Unit]
Description=Backup external encrypted USB disk on poweroff.
Requires=systemd-cryptsetup@ext.service
Requires=-.mount
Requires=tmp.mount
After=dev-disk-by\<uuid here>.device
After=systemd-cryptsetup@ext.service
After=-.mount
After=tmp.mount

[Service]
Type=oneshot
ExecStart=/usr/bin/echo "Waiting for poweroff to trigger snapshot and archive transfer..."
ExecStop=/usr/bin/systemctl list-jobs | /usr/bin/egrep -q 'poweroff.target.*start'
ExecStop=-/usr/local/bin/btrfs-snapshots.sh --device='UUID=<uuid>' @ @boot @home
ExecStop=/usr/local/bin/btrfs-archive.sh --source='UUID=<uuid>' --target=/dev/mapper/ext
TimeoutSec=infinity
RemainAfterExit=true

[Install]
WantedBy=dev-disk-by\<uuid here>.device
1
27.01.2020, 23:40

Теги

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