Khởi động lại dịch vụ Đơn vị Systemd nếu dịch vụ khác bắt đầu hoặc tải lại


16

Tôi muốn biết liệu có cách nào Systemdđể khởi động lại A.service( After) khi B.servicebắt đầu hoặc tải lại (chỉ tải lại cấu hình), nếu có thể mà không cần chỉnh sửa B.serviceđược hệ thống cài đặt và nâng cấp.

A.servicenên bắt đầu ngay cả khi B.servicekhông được cài đặt, vô hiệu hóa hoặc dừng lại.

A.service:

[Unit]
After = B.service network-online.target
Wants = B.service

[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes

[Install]
WantedBy = network-online.target

B.service:

[Unit]
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid

[Install]
WantedBy=multi-user.target

Câu trả lời:


12

Bạn có thể sử dụng PartOftrong [Unit]phần.

Thí dụ: PartOf=B.service

Từ trang người đàn ông,

PartOf =

Định cấu hình các phụ thuộc tương tự như Yêu cầu =, nhưng giới hạn ở việc dừng và khởi động lại các đơn vị. Khi systemd dừng hoặc khởi động lại các đơn vị được liệt kê ở đây, hành động được truyền đến đơn vị này. Lưu ý rằng đây là phụ thuộc một chiều - các thay đổi đối với đơn vị này không ảnh hưởng đến các đơn vị được liệt kê.


Cảm ơn, tôi đã nhìn vào Overriding vendor settingsnhưng có vẻ điều này thậm chí dễ dàng hơn và hứa hẹn, chỉ excpetion là tôi không muốn Adừng lại nếu Bngừng, chỉ A.restartnếu B.start, dù sao, tôi sẽ làm một số xét nghiệm sớm và xem nếu có một số cách để quản lý nó, sau đó sẽ cho bạn biết
Alex

@Alex: Nếu bạn sử dụng PartOfRestart=alwayscùng nhau thì sao?
Do đó,

Tôi đang xem Restart=tài liệu, tôi không chắc hành vi của các oneshotdịch vụ là gì, nhưng bất kể : When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restarted, nếu tôi hiểu chính xác thì việc dừng B sẽ dừng A
Alex

Giờ đây, tiền thưởng tự động được chỉ định hết hạn, @Thushi tôi đánh giá cao nỗ lực của bạn và đề xuất nhưng PartOfkhông phải là giải pháp cho câu hỏi, dù sao hãy tận hưởng.
Alex

@Alex: Chà, Điểm không quan trọng với tôi. Có rất nhiều cách khác tôi có thể kiếm được điểm. Tôi chỉ muốn biết liệu giải pháp được cung cấp có giải quyết được vấn đề của bạn không. Nếu không, chúng tôi sẽ làm việc về nó hơn nữa. Làm thế nào về việc sử dụng PartOfvới Restart=always? Bạn đã thử điều đó?
Do đó,

3

Tôi không có quyền kiểm soát stopvới PartOf=, và Akhông phải chỉ dừng lại ở B, vì vậy tôi đã kết thúc bằng Trọng thiết lập nhà cung cấp , dường như làm việc.

/etc/systemd/system/B.service.d/override.conf

[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'

/cmdviệc thực hiện không đồng bộ và truy cập vào một tài nguyên cũng /script.shcần truy cập, tôi thấy không có gì tốt hơn (hiện tại) để ngủ vài giây.

Tôi đã thử sử dụng systemctl [--no-block] try-restarttrước khi sử dụng /script.shtrực tiếp nhưng không hiệu quả.


Tôi cũng đang tìm kiếm một giải pháp cho kịch bản này. Bạn có thể vui lòng giải thích giải pháp này thêm một chút? hoặc cung cấp một liên kết đến một số tài liệu để đọc và hiểu những gì bạn đã làm.
zappy

Xin chào @zappy, hãy tìm hướng dẫn sử dụng man systemd.unit(hoặc tìm kiếm trực tuyến nếu chưa được cài đặt) và tìm chương "Cài đặt nhà cung cấp ghi đè".
Alex

Cảm ơn về thông tin bạn vừa nhập. Tôi hiểu rằng bạn chỉ chọn phương pháp trên vì dịch vụ B là nhà cung cấp cụ thể và bạn không muốn chỉnh sửa tệp dịch vụ đó. Nhưng trong trường hợp của tôi, cả dịch vụ A và B đều không được cung cấp. Tôi cảm thấy ghi đè nó có thể thêm phức tạp cho hệ thống. Chúng ta có lựa chọn nào khác không?
zappy

Câu hỏi là một vài năm tuổi, bạn đã kiểm tra tài liệu? Có lẽ kịch bản này đã được bảo hiểm kể từ đó. Lúc đó tôi đang rất vội nhưng có thời gian tôi sẽ tìm danh sách gửi thư chính thức của hệ thống và hỏi ở đó, cuối cùng sẽ mở một vấn đề
Alex

1

Tại thời điểm systemd không bao gồm senario này. Bạn không thể đạt được chức năng này thông qua các tệp dịch vụ một mình. Một khả năng là chiếm quyền điều khiển systemctl thông qua tập lệnh shell có cùng tên và trong kiểm tra đó để xem B.service sắp được khởi động lại hoặc tải lại, hãy thực hiện hành động thích hợp với A.service và nếu cần cập nhật RC.local để có được trạng thái thích hợp khi khởi động là tốt. Tôi gặp vấn đề này với docker.service và network.service, nhưng tôi chỉ luôn khởi động lại chúng cùng nhau:

systemctl khởi động lại docker.serviceetwork.service

Rõ ràng, điều này sẽ không hiệu quả nếu chính systemd thao túng B.service bên trong (ví dụ: thông qua các tệp dịch vụ khác.).

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.