сценарий с `чтением `в цикле bash while, вызывающем высокую загрузку ЦП при запуске в качестве службы systemd

Как указано в комментариях, у вас есть несколько вариантов уровня файловой системы -для резервного копирования Pi. Если вы сделаете это, вам нужно будет исключить виртуальные файловые системы /procи /sys. Вы также должны знать, что он не будет включать загрузочный образ файловой системы, отличный от -, или вашу таблицу разделов; В конце этого ответа я дам предложение по резервному копированию отдельно.

  1. Вы можете использовать rsync. Это даст вам копию файловой системы на вашем резервном носителе, а не один файл изображения.

    rsync -avzHP --exclude '/proc/' --exclude '/sys/' root@pi:/ /backup/pi.$(date +'%Y%m%d')
    

    Если ваша локальная учетная запись не является root, вы, вероятно, захотите включить параметр --fake-superдля резервного копирования и восстановления. (Он сохраняет сведения об удаленном владении, хотя не может фактически применить их к локальной резервной копии.)

    Если вы решите пойти по этому пути, я настоятельно рекомендую вам также просмотреть rsnapshot, чтобы получить резервные копии GFS без использования большого количества дополнительного дискового пространства.

  2. Вы можете использовать tar, paxили любой другой инструмент архивации. Это даст вам сжатое изображение

    .
    ssh root@pi 'cd / && tar --exclude '/proc/' --exclude '/sys/' -czvf -.' > /path/to/backup.pi.$(date +'%Y%m%d').tgz
    
  3. Вы можете использовать другие параметры, такие как duplicity. Я не использовал это серьезно, поэтому я не думаю, что лучше всего могу привести пример того, как это будет использоваться.


Получив резервную копию файловой системы, вы также, вероятно, захотите восстановить минимальный загрузочный образ.

На моем Pi у нас есть такая структура (Я проигнорировал третий раздел; он может быть у вас, но он, вероятно, был зарезервирован как часть вашей файловой системы):

fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x42913321

Device         Boot   Start      End  Sectors  Size Id Type
/dev/mmcblk0p1         8192   137215   129024   63M  c W95 FAT32 (LBA)
/dev/mmcblk0p2       137216  8388607  8251392    4G 83 Linux

Вам нужно все от начала диска до начала раздела 1(/boot). В этом конкретном отображении сектора находятся в блоках по 512 байт, но нам нужно прочитать блоки по 4 КБ (размер блока SSD ), поэтому мы делим все числа на восемь:

# Copy the boot segment from the beginning of the disk
dd bs=4k count=$((8192/8)) if=/dev/mmcblk0 | gzip >img0.gz

Вы можете восстановить этот сохраненный сегмент на карту SSD в /dev/mmbclk0с помощью такой команды. Обратите внимание, что это безвозвратно перезапишет целевое устройство,поэтому проверьте его несколько раз, прежде чем использовать, и не копируйте слепо этот пример:

zcat img0.gz | dd bs=4k iflag=fullblock of=/dev/mmcblk0
partprobe /dev/mmcblk0
2
23.06.2021, 23:50
1 ответ

Это ваша event_monitorпрограмма зацикливается, используя весь ЦП, а не ваш bash-скрипт.

При запуске под systemd к STDIN подключен /dev/null (или, возможно, он даже закрыт ). Когда цикл монитора событий в main выполняет read(2), он получает EOF и снова проходит цикл.

При интерактивном запуске монитор события _имеет терминал, подключенный к стандартному вводу, поэтому read(2)блокируется до поступления ввода.

монитор событий _должен зацикливаться на чтении стандартного ввода, только если он открыт. Если он получает EOF, он должен либо выйти (, что, вероятно, нежелательно в данном случае ), либо просто заснуть на долгое время.

Если вы не можете изменить event_monitor, вы можете успешно подключить именованный канал FIFO ()к стандартному вводу службы. systemd имеет параметр StandardInput(, задокументированный на справочной странице systemd.exec (5 )), где вы можете указать StandardInput=file:/run/event_monitor_ctl. Затем вам просто нужно создать именованный канал /run/event_monitor_ctl. Для этого вы можете использовать systemd -tmpfiles, создав файл конфигурации (см. tmpfiles.d (5 )), чтобы создать этот именованный канал.

1
28.07.2021, 11:23

Теги

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