Sử dụng systemd để thực thi tập lệnh trước khi tắt hệ thống?


7

Tôi đã viết một tập lệnh đình chỉ tất cả các máy VirtualBox của mình và đặt một dòng vào /etc/rc.local.shutdown, nhưng nó dường như không hoạt động,

su - XX -c /XX

Khi tôi khởi động lần sau, VirtualBox sẽ cho tôi biết máy đó Aborted, vì vậy tập lệnh không được thực thi. (Khởi chạy kịch bản đó theo cách thủ công cho tôi)

PS tôi đã kích hoạt shutdown.target

BIÊN TẬP

Vấn đề có vẻ phức tạp hơn tôi nghĩ, .bashrcnếu tôi đang chạy tty3, nó sẽ thực thi startx, vì vậy khi systemd quyết định tắt / khởi động lại, nó sẽ giết VBoxSVCquá trình và những thứ khác khi X session chết.

Tôi cũng đã cố gắng hack mã nguồn của xfsm-shutdown-helper, tạo một bản giả systemctlthực thi tập lệnh của tôi trước, không có tác dụng nào ở trên.


Vì tò mò, có bao nhiêu máy ảo bạn đang tắt song song? .. Không liên quan đến câu hỏi của bạn, nhưng tôi tin rằng tôi đã tìm thấy một vấn đề trong VirtualBox 4.2.6 khi tắt quá nhiều cùng một lúc (5 đến 10) (tất cả đều là các bản sao được liên kết từ một máy ảo được chia sẻ) dẫn đến các máy ảo nhân bản bị hỏng.
adamrmcd

@adamrmcd Tôi đang tắt từng cái một ...
daisy

Bạn có muốn đình chỉ các máy ảo hơn là tắt chúng không? Trong một hệ thống dựa trên init cổ điển (SysV?), Bạn sẽ có thể làm điều đó từ inittab / bằng cách sửa đổi các tập lệnh cho runlevel được sử dụng để tắt ... (đọc trang init man, nó khác nhau giữa các unix, có thể là giữa Linux phân phối là tốt)
Gert van den Berg

Bạn cũng có thể muốn lặp lại một cái gì đó cho một logfile từ tập lệnh, để chắc chắn rằng nó thực sự không chạy, thay vì thất bại do kết quả của một thứ khác ...
Gert van den Berg

1
Nếu ti hỗ trợ các tập lệnh init kiểu SysV, bạn sẽ thêm một tập lệnh như thế /etc/init.d/stopvmsdừng các VM khi truyền tham số "dừng". Sau đó, bạn tạo các liên kết (tượng trưng hoặc cứng) đến tập lệnh đó như nói /etc/rc5.d/K01stopvms/etc/rc3.s/K01stopvms. . ))
Gert van den Berg

Câu trả lời:


1

Nếu tôi hiểu bạn một cách chính xác, bạn muốn tạm dừng các máy VB của bạn trước khi phiên bash của bạn trên tty3 kết thúc hoặc trước khi Xserver của bạn kết thúc.

Tôi tin rằng systemd không biết về Xsession đang chạy của bạn, bởi vì bạn khởi động nó từ .bashrc của bạn, vì vậy sẽ rất khó để nói systemd tạm dừng VB của bạn trước khi nó chấm dứt shell của bạn hoặc Xsession của bạn. Bạn sẽ phải tìm một vị trí trong chuỗi tắt máy "đủ sớm", có thể khó tìm và nghi ngờ về mặt ngữ nghĩa, bởi vì nó sẽ trộn "công cụ người dùng" với "công cụ hệ thống"

Các giải pháp có thể phần nào phụ thuộc vào cách systemd chấm dứt các quy trình của bạn, nhưng ít nhất những điều sau đây phải theo hướng tốt:

Trước khi vỏ kết thúc

suspendVB() {
        echo "suspending VBs"
        # put real code here
        exit
}

trap suspendVB EXIT

Nếu bạn thực hiện điều này là RCfile của bash của bạn (hoặc thêm nó vào .bashrc), thì mã trong suspendVB()sẽ được thực thi trước khi shell kết thúc. Bạn có thể kiểm tra điều này bằng cách chạy

bash --rcfile xxx

nơi tập tin xxxchứa mã từ trên. Điều này bắt đầu một shell khác bên trong shell hiện tại của bạn, chỉ để thử nghiệm. Khi bạn chạy một lối thoát đơn giản, bạn sẽ thấy:

martin@beaureve:~$ exit
exit
suspending VBs
/home/martin >

và bạn đã trở lại trong vỏ (đăng nhập) ban đầu của bạn.

Bạn có thể phải tìm hiểu làm thế nào systemd thực sự chấm dứt shell đăng nhập của bạn và bạn có thể phải thay thế EXITbằng một số tín hiệu khác. Tra cứu traplệnh để tìm hiểu thêm.

Lưu ý rằng khi systemd giết chết các tiến trình của bạn bằng "-9" (SIGKILL) thì bạn sẽ không thể bẫy được việc chấm dứt, tức là bạn đã hết may mắn.

Trước khi Xsession chấm dứt

Ngoài ra, bạn có thể thử một điều tương tự với Xsession của bạn. Điều này rất cần thiết trong trường hợp systemd chấm dứt Xsession của bạn trước khi nó kết thúc shell của bạn. Bạn có thể muốn chèn một cái bẫy vào một trong các tệp khởi động X (ví dụ: .xinitrc) - tra cứu các trang hướng dẫn startxxinittìm hiểu thêm.

Nếu startxtệp của bạn trông giống như của tôi, thì xserver được khởi động ở nền trước và bạn có thể chỉ cần đặt các lệnh tạm ngưng của mình sau dòng X thực sự bắt đầu (và hoàn toàn không sử dụng bẫy):

xinit "$client" $clientargs -- "$server" $display $serverargs
retval=$?
echo " --- suspending VBs ---"

Tôi đặt dòng "đình chỉ VB" và khi tôi chạy, startx -- vt8tôi nhận được phiên fullblows (kde) trên vt8 và chỉ khi tôi đăng xuất, dòng "đình chỉ VB" mới xuất hiện trên màn hình.

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.