ฉันจะรันสคริปต์ก่อนทุกอย่างอื่นเมื่อปิดระบบด้วย systemd ได้อย่างไร


17

หมายเหตุ: คำถามที่กำหนดสูตรสั้น ๆ สามารถพบได้ที่ด้านล่าง

ฉันมีสคริปต์ที่ทำให้การสำรองไฟล์ของฉันไปยังไดรฟ์ USB ภายนอก การดำเนินการอาจใช้เวลาสักครู่ขึ้นอยู่กับปริมาณข้อมูลใหม่ที่ฉันสร้างขึ้น ฉันต้องการเรียกใช้โดยอัตโนมัติทุกครั้งที่ปิดระบบ

ฉันใช้ fedora 23 พร้อมอัปเดตล่าสุด (systemd)

ฉันพยายามทำสิ่งนี้ให้สำเร็จในหลาย ๆ ทาง แต่ฉันไม่สามารถทำงานได้

กระบวนการทำงานที่ยาวนานด้วย StopExec

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

ฉันเปิดใช้งานด้วยและเริ่มด้วยsystemctl enable autobackup.servicesystemctl start autobackup.service

ส่วนหนึ่งของบันทึกการบูตของฉัน ( journalctl -b-1):

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

โปรดทราบว่าฉันไม่ได้ตัดทอนสิ่งใดระหว่างนั้นจริง ๆ ก็ไม่ได้เมานท์ / mnt / BACKUP ก่อนที่สคริปต์จะเริ่ม

ก่อนปิดเครื่องเป้าหมาย

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

เอาต์พุตนั้นเป็นพื้นเดียวกัน

ปัญหา

ฉันคิดว่าปัญหาคือ systemd เริ่มต้นสคริปต์ของฉันควบคู่ไปกับสคริปต์การปิดระบบอื่น ๆ ทั้งสองกรณีซึ่งยกเลิกการต่อเชื่อม BACKUP และปิดการใช้งานโครงสร้างพื้นฐานของท่อ (ข้อผิดพลาดอื่นที่ฉันได้รับในบางครั้ง

คำถาม

ฉันจะสอน systemd ให้เริ่มสคริปต์ของฉันก่อนที่จะปิดเครื่องรอจนกว่าจะออกจากนั้นเริ่มสคริปต์การปิดระบบ / เป้าหมาย / หน่วยอื่น ๆ ที่เหลือได้อย่างไร

คำตอบ:


12

ไม่จำเป็นต้องสร้างหรือแก้ไขไฟล์บริการ เพียงวางสคริปต์ของคุณใน

/usr/lib/systemd/system-shutdown/

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

ทันทีก่อนที่จะดำเนินการระบบที่แท้จริงหยุด / poweroff / รีบูต / kexec systemd-shutdown จะเรียกใช้ไฟล์ปฏิบัติการทั้งหมดใน / usr / lib / systemd / system-shutdown / และส่งผ่านอาร์กิวเมนต์หนึ่งไปยังพวกเขา: ทั้ง "หยุด", "poweroff", "poweroff" "หรือ" kexec "ขึ้นอยู่กับการกระทำที่เลือก ไฟล์เรียกทำงานทั้งหมดในไดเร็กทอรีนี้ถูกเรียกใช้งานแบบขนานและการดำเนินการของแอ็คชันจะไม่ดำเนินต่อไปก่อนที่ไฟล์ปฏิบัติการทั้งหมดจะเสร็จสิ้น

ฉันใช้มันเพื่อส่งเสียงบี๊บลำโพง PC


2
คุณต้องสร้างไดเรกทอรีนี้หรือไม่? ฉันไม่ได้มีทั้ง Ubuntu 16.04 และ Raspbian (เจสซี) - ทั้งคู่เป็น systemd
WoJ

2
ระบบ Debian /lib/systemd/system-shutdown/ใช้เส้นทางที่แตกต่างกัน และนอกจากนี้โปรดทราบว่าสคริปต์เหล่านี้จะถูกเรียกใช้งานช้ามากเมื่อปิดระบบไฟล์หลังจากที่เมาท์แบบอ่านอย่างเดียวแล้ว ดังนั้นการเข้าถึงเพื่อเขียนใด ๆ ในระบบไฟล์จะล้มเหลวเว้นแต่ได้รับการนับใหม่ว่าอ่าน - เขียน ( mount -oremount,rw /) ดูวิธีเรียกใช้งานสคริปต์ใน / usr / lib / systemd / system-shutdown / เมื่อรีบูตหรือปิดเครื่อง?
Frank Breitling

9
OP ขอให้สคริปต์ทำงาน "ก่อนทุกอย่างอื่น" เมื่อปิดเครื่อง สคริปต์การปิดระบบจะดำเนินการหลังจากทุกอย่างทันทีก่อนที่จะฆ่าเคอร์เนล
เกร็กอเล็กซานเดอร์

11

ฉันเข้าใจแล้ว!

ใช้เวลานานในการแก้ปัญหาด้วย StopExecและแก้ไขดังนี้:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

หมายเหตุบรรทัด:

RequiresMountsFor=/mnt/BACKUP /home

มันทำงานได้ตามที่คาดไว้ด้วยวิธีนี้


2
systemctl editคุณไม่ควรต้องทำ systemctl enable autobackupมีเอฟเฟกต์เดียวกันและมีสำนวนมากกว่าและควรจะทำงานได้เนื่องจากคุณมี[Install]ส่วนในหน่วยของคุณอยู่แล้ว คุณจะต้องแก้ไขการพิมพ์ผิดในชื่อเป้าหมาย ;)
Stefan Majewsky

OMG ฉันค้นหาวิธีแก้ปัญหาในการโทรหาสคริปต์สำรองก่อนที่จะยกเลิกการต่อเชื่อมไดรฟ์ใด ๆ ขอขอบคุณ!
deanresin

2
สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันไม่มีที่เมาท์ฉันเพียงต้องการให้แน่ใจว่าสคริปต์ของฉันทำงานก่อนที่หน่วยอื่นจะปิดตัวลง
2rs2ts
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.