Làm cách nào để chạy tập lệnh trước khi mọi thứ khác tắt máy với systemd?


17

Lưu ý: Câu hỏi được xây dựng ngắn gọn có thể được tìm thấy ở phía dưới.

Tôi có một tập lệnh tạo bản sao lưu các tệp của mình vào ổ USB ngoài. Việc thực hiện có thể mất một lúc, tùy thuộc vào lượng dữ liệu mới tôi đã tạo. Tôi muốn chạy nó tự động sau mỗi lần tắt hệ thống.

Tôi đang sử dụng fedora 23 với các bản cập nhật mới nhất (systemd).

Tôi đã cố gắng để đạt được điều này theo nhiều cách, nhưng tôi không thể làm cho nó hoạt động được.

Quá trình chạy dài với StopExec

dịch vụ tự động:

[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

Tôi kích hoạt nó systemctl enable autobackup.servicevà bắt đầu với systemctl start autobackup.service.

Một phần của nhật ký khởi động của tôi ( 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.

Lưu ý rằng tôi đã không rút ngắn bất cứ điều gì ở giữa, nó thực sự chưa được kết thúc / mnt / BACKUP ngay trước khi kịch bản bắt đầu, sự trùng hợp hài hước ..

Trước khi tắt máy.

dịch vụ tự động:

[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

Đầu ra về cơ bản là giống nhau.

Vấn đề

Tôi nghĩ vấn đề là systemd khởi động tập lệnh của tôi song song với tất cả các tập lệnh tắt máy khác trong cả hai trường hợp, điều đó làm mất BACKUP và hủy kích hoạt cơ sở hạ tầng đường ống (một lỗi khác đôi khi tôi gặp phải, khi việc ngắt kết nối không đủ nhanh).

Câu hỏi

Làm cách nào tôi có thể dạy systemd khởi động tập lệnh của mình trước khi tắt máy, đợi cho đến khi nó thoát và sau đó bắt đầu phần còn lại của tập lệnh / mục tiêu / đơn vị / bất cứ điều gì?

Câu trả lời:


12

Không cần phải tạo hoặc chỉnh sửa các tập tin dịch vụ. Đơn giản chỉ cần thả tập lệnh của bạn vào

/usr/lib/systemd/system-shutdown/

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

Ngay lập tức trước khi thực hiện việc dừng hệ thống thực tế / poweroff / restart / kexec systemd-shutdown sẽ chạy tất cả các thực thi trong / usr / lib / systemd / system-shutdown / và truyền một đối số cho chúng: hoặc "tạm dừng", "poweroff", "khởi động lại "Hoặc" kexec ", tùy thuộc vào hành động đã chọn. Tất cả các tệp thực thi trong thư mục này được thực thi song song và việc thực thi hành động không được tiếp tục trước khi tất cả các tệp thực thi kết thúc.

Tôi sử dụng nó để đơn giản là tiếng bíp loa PC.


2
Bạn đã phải làm thư mục này? Tôi không có nó trên Ubuntu 16.04 cũng như Raspbian (jessie) - cả hai đều dựa trên systemd.
WoJ

2
Các hệ thống Debian sử dụng đường dẫn khác nhau /lib/systemd/system-shutdown/. Và ngoài ra, hãy lưu ý rằng các tập lệnh này được thực thi rất muộn khi tắt máy, sau khi các hệ thống tệp đã được gắn ở chế độ chỉ đọc. Vì vậy, mọi quyền truy cập ghi vào hệ thống tệp sẽ không thành công trừ khi được ghi lại là read-write ( mount -oremount,rw /). Xem Làm thế nào để thực thi các tập lệnh trong / usr / lib / systemd / system-shutdown / lúc khởi động lại hoặc tắt máy?
Frank Breitling

9
OP đã yêu cầu kịch bản thực thi "trước mọi thứ khác" khi tắt máy. Các kịch bản tắt hệ thống được thực thi sau mọi thứ khác, ngay lập tức trước khi giết kernel.
Greg Alexander

11

Tôi hiểu rồi!

Thực hiện giải pháp Quá trình chạy dài với StopExec và sửa đổi nó như sau:

dịch vụ tự động:

[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

Lưu ý dòng:

RequiresMountsFor=/mnt/BACKUP /home

Nó hoạt động như mong đợi theo cách này.


2
Bạn không cần phải làm systemctl edit. systemctl enable autobackupcó tác dụng tương tự và có nhiều thành ngữ hơn, và sẽ hoạt động vì bạn đã có [Install]phần trong đơn vị của mình. Bạn sẽ phải sửa lỗi đánh máy trong tên mục tiêu. ;)
Stefan Majewsky

OMG Tôi đã tìm kiếm rất lâu để có giải pháp gọi tập lệnh sao lưu của mình TRƯỚC bất kỳ ổ đĩa nào không được đếm. Cảm ơn bạn!
Deanresin

2
Điều này không làm việc cho tôi. Tôi không có bất kỳ gắn kết nào, tôi chỉ muốn đảm bảo tập lệnh của tôi chạy trước khi các đơn vị khác đóng cửa.
2rs2ts
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.