Làm cách nào tôi có thể làm cho dịch vụ người dùng của mình đợi cho đến khi mạng trực tuyến?


14

Tôi đã viết một vài tệp dịch vụ người dùng systemd mà tôi muốn người dùng kích hoạt và cần kết nối mạng hoạt động. Tôi nghĩ rằng nó sẽ dễ dàng như:

Wants=network-online.target
After=network-online.target

Tuy nhiên, các dịch vụ dường như bắt đầu quá sớm và trong journalctltôi thấy:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

Sau đó tôi tìm kiếm thêm và thử

Wants=network.target
After=network.target

và đã làm sudo systemctl enable systemd-networkd-wait-online.service.

Bây giờ tôi có journalctl:

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.

Và một lần nữa dịch vụ bắt đầu quá sớm.

Có phải tin nhắn đó là ở đó? Làm thế nào tôi có thể gỡ lỗi vấn đề của tôi?


EDIT : lý do rất đơn giản và được nêu cụ thể trong Arch Wiki :

systemd --userchạy như một quy trình riêng biệt từ systemd --systemquy trình. Đơn vị người dùng không thể tham chiếu hoặc phụ thuộc vào đơn vị hệ thống.

Bài đăng trên diễn đàn này dường như đề xuất một giải pháp đơn giản: Tôi nên linkđơn vị hệ thống cần thiết với tư cách là người dùng, do đó tạo ra một liên kết tượng trưng đến nó có sẵn trên đường dẫn tìm kiếm đơn vị.

Sau khi làm điều đó, tôi không thấy bất kỳ No such file or directorytin nhắn nào , tuy nhiên, tôi vẫn không thể làm cho các dịch vụ thực sự chạy sau khi mạng trực tuyến. Tôi đã thử liên kết network.target, network-online.targetsystemd-networkd-wait-online.service, đặt các đơn vị của mình phụ thuộc vào từng đơn vị, nhưng không thành công. Khi tôi kiểm tra trạng thái của đơn vị được liên kết trong chế độ người dùng, tất cả họ đều đã chết, ví dụ:

$ systemctl --user status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.

Tuy nhiên, tôi có thể thấy network-online.targethoạt động trong chế độ người dùng sau khi liên kết nó:

$ systemctl --user status network-online.target
● network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.

Tôi hy vọng bạn sẽ có câu trả lời.

@Deleteme Cảm ơn, tôi nghĩ rằng tôi đã tìm thấy nguyên nhân của việc này (xem cập nhật), nhưng không phải làm thế nào để giải quyết vấn đề.
Lev Levitsky

Bạn đã từng tìm một giải pháp cho vấn đề này? Ngoài ra, tôi nhận thấy bạn nhấn mạnh rằng chỉ một số đơn vị được liên kết là chết. Đó là những cái đã làm việc, và chúng khác nhau như thế nào?
Sparhawk

@Sparhawk tiếc là không. Như một giải pháp thay thế, tôi chỉ sử dụng bộ hẹn giờ được đặt thành vài giây sau khi khởi động. Câu hỏi có một ví dụ: mục tiêu mạng trực tuyến đang hoạt động sau khi liên kết và mục tiêu mạng thì không.
Lev Levitsky 2/11/2015

Có lẽ tôi hiểu nhầm, nhưng tôi đang tìm kiếm thứ gì đó để kích hoạt mỗi khi mạng hoạt động trở lại, để kiểm tra email của tôi sau khi tiếp tục bị đình chỉ. Tôi nghĩ rằng đây sẽ là cách để làm điều đó. Tôi thấy các ví dụ bây giờ. Tôi nghĩ bạn có nghĩa là một số dịch vụ tùy chỉnh bị sa thải và một số thì không. Tuy nhiên, tôi thấy bây giờ bạn đang nói về các phiên bản người dùng của các mục tiêu mạng.
Sparhawk

Câu trả lời:


3

Vì bạn không thể phụ thuộc vào dịch vụ hệ thống, giải pháp duy nhất của bạn là cung cấp dịch vụ người dùng phát hiện xem mạng có trực tuyến hay không. (Hoặc tạo dịch vụ hệ thống dịch vụ của bạn.) Chi tiết cho dịch vụ người dùng "phát hiện trực tuyến" sẽ phụ thuộc vào định nghĩa "trực tuyến" của bạn. Chẳng hạn, nó có thể chờ ping đến 8.8.8.8. Hoặc để phân giải tên DNS thành công. Chẳng hạn, trong một tình huống tương tự với vpnc, tôi chờ ping đến IP vpn để thành công.

Sau đó, bạn có thể làm cho dịch vụ người dùng của mình phụ thuộc vào (Sau =) dịch vụ người dùng phát hiện trực tuyến của bạn.

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done

Cảm ơn bạn, điều này có vẻ hợp lý và đủ đơn giản. Nhưng nếu 10 người dùng kích hoạt dịch vụ người dùng của tôi, sẽ có 10 trường hợp ping cùng một máy chủ, điều này có vẻ hơi dư thừa. Trong thực tế, điều này có lẽ không thành vấn đề, nhưng tôi đã hỏi điều này với hy vọng có được một "cờ trực tuyến" duy nhất có sẵn cho tất cả các dịch vụ người dùng. Không có giải pháp tốt hơn đã được đề xuất, mặc dù.
Lev Levitsky

1

Tôi muốn giới thiệu để kiểm tra một cái gì đó như thế này:

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target

Theo dõi bởi:

# systemctl daemon-reload && systemctl enable foo.service

4
Nhưng đây là một dịch vụ hệ thống và tôi đang cố gắng thiết lập một dịch vụ người dùng.
Lev Levitsky
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.