Bagaimana saya bisa membuat layanan pengguna saya menunggu sampai jaringan online?

14

Saya telah menulis beberapa file layanan pengguna systemd yang saya ingin pengguna aktifkan dan yang membutuhkan koneksi jaringan yang berfungsi. Saya pikir itu akan semudah:

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

Namun, layanan tampaknya mulai terlalu dini, dan dalam journalctlsaya melihat:

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

Kemudian saya mencari lebih banyak dan mencoba

Wants=network.target
After=network.target

dan lakukan sudo systemctl enable systemd-networkd-wait-online.service.

Sekarang saya miliki di journalctl:

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

Dan sekali lagi layanan dimulai terlalu dini.

Apakah pesan itu seharusnya ada di sana? Bagaimana saya bisa men-debug masalah saya?


EDIT : alasannya sederhana dan secara khusus dinyatakan dalam Arch Wiki :

systemd --userberjalan sebagai proses terpisah dari systemd --systemproses. Unit pengguna tidak dapat merujuk atau bergantung pada unit sistem.

Posting forum ini sepertinya menyarankan solusi sederhana: Saya harus linkmenggunakan unit sistem yang diperlukan sebagai pengguna, sehingga membuat symlink tersedia di jalur pencarian unit.

Setelah melakukan itu, saya tidak melihat No such file or directorypesan apa pun , namun, saya masih tidak dapat membuat layanan benar-benar berjalan setelah jaringan online. Saya telah mencoba menghubungkan network.target, network-online.targetdan systemd-networkd-wait-online.service, mengatur unit saya untuk bergantung pada masing-masing, tanpa hasil. Ketika saya memeriksa status unit yang ditautkan dalam mode pengguna, mereka semua ada yang mati, misalnya:

$ 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.

Namun, saya dapat melihat network-online.targetaktif dalam mode pengguna setelah menautkannya:

$ 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.
Lev Levitsky
sumber
Saya harap Anda punya jawaban.
@Deleteme Terima kasih, saya pikir saya menemukan penyebabnya (lihat pembaruan), tetapi tidak bagaimana menyelesaikan masalah.
Lev Levitsky
Apakah Anda setiap menemukan solusi untuk masalah ini? Juga, saya perhatikan Anda menekankan bahwa hanya beberapa unit terkait yang mati. Yang mana yang berhasil, dan apa bedanya?
Sparhawk
@Sparhawk sayangnya tidak. Sebagai solusinya, saya hanya menggunakan timer yang disetel ke beberapa detik setelah boot. Pertanyaannya memiliki contoh: target jaringan-online aktif setelah menautkan, dan target jaringan tidak.
Lev Levitsky
Mungkin saya salah paham, tetapi saya mencari sesuatu untuk dinyalakan setiap kali jaringan kembali, untuk memeriksa email saya setelah melanjutkan dari penangguhan. Saya pikir ini akan menjadi cara untuk melakukannya. Saya melihat contohnya sekarang. Saya pikir maksud Anda beberapa layanan khusus dipecat dan beberapa tidak. Namun, saya melihat sekarang Anda berbicara tentang versi pengguna target jaringan.
Sparhawk

Jawaban:

3

Karena Anda tidak dapat bergantung pada layanan sistem, satu-satunya solusi Anda adalah menyediakan layanan pengguna yang mendeteksi apakah jaringan sedang online. (Atau buat layanan sistem layanan Anda.) Detail untuk layanan pengguna "deteksi-online" akan bergantung pada definisi "online" Anda. Misalnya, menunggu ping ke 8.8.8.8 untuk berhasil. Atau agar resolusi nama DNS berhasil. Sebagai contoh, dalam situasi yang sama dengan vpnc, saya menunggu ping ke vpn IP untuk berhasil.

Kemudian Anda dapat membuat layanan pengguna Anda bergantung pada (Setelah =) layanan pengguna deteksi-online Anda.

#!/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
Stuart Gathman
sumber
Terima kasih, ini tampaknya masuk akal dan cukup sederhana. Tetapi jika 10 pengguna mengaktifkan layanan pengguna saya, akan ada 10 contoh ping server yang sama secara bersamaan, yang tampaknya agak berlebihan. Dalam praktiknya ini mungkin tidak dipermasalahkan, tetapi saya menanyakan ini dengan harapan mendapatkan satu "bendera online" yang tersedia untuk semua layanan pengguna. Namun, belum ada solusi yang lebih baik yang disarankan.
Lev Levitsky
1

Saya akan merekomendasikan untuk menguji sesuatu seperti ini:

# /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

Diikuti oleh:

# systemctl daemon-reload && systemctl enable foo.service
Marius Karnauskas
sumber
4
Tetapi ini adalah layanan sistem, dan saya mencoba mengatur layanan pengguna.
Lev Levitsky