Ağ başladıktan sonra bir komut dosyasının yürütülmesine neden olur mu?


102

Sistemd için nispeten yeniyim ve mimarisini öğreniyorum.

Şu anda, özel bir kabuk betiğinin nasıl çalışacağına karar vermeye çalışıyorum. Bu komut dosyasının ağ katmanı başladıktan sonra çalışması gerekir .

Arch ile çalışıyorum, netdl ve sistemd kullanarak.

Test etmek için basitçe çalışan basit bir senaryo yazdım ip addr list > /tmp/ip.txt. Bu komut dosyası için aşağıdaki servis dosyasını oluşturdum.

(/etc/systemd/system/test.service)
[Unit]
Description=test service

[Service]
ExecStart=/root/test.script

[Install]
WantedBy=multi-user.target

Sonra betiği etkinleştirdim,

systemctl enable test

Yeniden başlatmanın ardından komut dosyası gerçekten çalışır, ancak ağ başlatılmadan önce çalışır. Başka bir deyişle, çıktı ip.txt, birincil arabirime atanmış hiçbir IPv4 adresi görüntüler. Giriş yaptığımda, IPv4 adresi gerçekten atandı ve ağ bağlantısı kuruldu.

WantedByParametre ile uğraşarak betiğin çalıştığı noktayı değiştirebileceğimi tahmin ediyorum , ancak bunun nasıl yapılacağından emin değilim.

Birisi beni doğru yöne işaret edebilir mi?

Yanıtlar:


126

Sistemd ağ yapılandırması bağımlılıklarında

Sistemin birim siparişini etkilemek çok kolaydır. Öte yandan, tamamlanmış bir birimin ne garanti ettiği konusunda dikkatli olmanız gerekir.

Hizmetinizi yapılandırın

Mevcut sistemlerde, sipariş verme, network.targetyalnızca gerçek bir yapılandırma olmadığı için şebeke servisinin başlatıldığını garanti eder. Bunun için sipariş vermeniz network-online.targetve çekmeniz gerekir.

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

Eski sistemlerle uyumluluk için network.target'den sonra da sipariş vermeniz gerekebilir.

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

Bu, servisin birim dosyası ve systemd için.

Yazılımın güncel sürümlerinde uygulama

Şimdi network-online.target, beklendiği gibi çalıştığından (veya en azından kullanabildiğinizden network.target) emin olmalısınız .

NetworkManager'ın şu anki sürümü , NetworkManager-wait-online.servicehangilerinin network-online.targetservisinize tarafından hangilerinin tarafından alındığını sunmaktadır. Bu özel servis, servisinizin başlatılması için yapılandırılan tüm bağlantıların otomatik olarak başarılı, başarısız veya zaman aşımına uğramasını beklemesini sağlar.

Geçerli systemd-networkd sürümü, tüm cihazlar istenen şekilde yapılandırılana kadar hizmetinizi engeller. Şu anda yalnızca önyükleme sırasında uygulanan yapılandırmaları desteklemesi daha kolaydır (daha özel olarak `systemd-networkd.service başlangıç ​​zamanı).

Tamamlanması adına, /etc/init.d/networkFedora'daki servis, sistemin geçerli sürümleri tarafından yorumlandığı gibi, blokları network.targetve dolaylı olarak network-online.targethizmetinizi ve hizmetinizi bloke eder . Komut dosyası tabanlı bir uygulama örneği.

Uygulamanız, ister servise dayalı isterse komut dosyası tabanlı olsun, yukarıdaki ağ yönetim hizmetlerinden biri olarak davranırsa, ağ yapılandırması başarılı bir şekilde tamamlanıncaya, iyi bir sebepten başarısız oluncaya ya da makul bir süreden sonra zaman aşımına uğrayana kadar hizmetinizin başlamasını geciktirir tamamlamak için çerçeve.

Netctl'in aynı şekilde çalışıp çalışmadığını kontrol etmek isteyebilirsiniz ve bu bilgi bu cevaba değerli bir katkı olacaktır.

Yazılımın eski sürümlerinde uygulamalar

Bunun işe yaramayacağı, yeterince eski bir sistem sürümü göreceğinizi sanmıyorum. Ancak en azından network-online.targetvar olup olmadığını ve sonra sipariş edildiğini kontrol edebilirsiniz network.target.

Önceden NetworkManager yalnızca en az bir bağlantının uygulanacağını garanti ediyordu. Ve bunun çalışması için bile, NetworkManager-wait-online.serviceaçıkça etkinleştirmeniz gerekir . Bu, Fedora'da uzun süre önce düzeltildi, ancak yalnızca son zamanlarda yukarı yönde uygulandı.

systemctl enable NetworkManager-wait-online.service

Network.target ve network-online.target uygulamalarına ilişkin notlar

Yazılımınızı hiçbir zaman belirli bir hizmete NetworkManager.serviceveya NetworkManager-wait-online.servicebaşka bir hizmete bağımlı hale getirmeniz gerekmez . Bunun yerine, tüm ağ yönetimi hizmetleri önceden network.targetve isteğe bağlı olarak kendilerini sipariş etmelidir network-online.target.

Basit bir komut dosyası tabanlı ağ yönetimi hizmeti çıkmadan önce ağ yapılandırmasını bitirmeli ve daha önce network.targetve böylece dolaylı olarak kendisini sipariş etmelidir network-online.target.

[Unit]
Before=network.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

Daemon tabanlı bir ağ yönetimi hizmeti, network.targetçok kullanışlı olmasa da, daha önce de sipariş vermelidir .

[Unit]
Before=network.target

[Service]
Type=simple
ExecStart=...

Artalanın bitmesini bekleyen bir servis, belirli bir hizmetten sonra ve daha önce kendisini sipariş etmelidir network-online.target. RequisiteServis sağlayıcısı servisini kullanmalıdır , böylece ilgili ağ yönetimi servisi kullanılmıyorsa derhal başarısız olur.

[Unit]
Requisite=...
After=...
Before=network-online.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

Paket, yapılandırılmış ağı beklemek isteyen servisler tarafından çekilmesi için wantsdizindeki bekleme servisine bir bağlantı kurmalıdır network-online.target.

ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/

İlgili belgeler

Final notları

Umarım sorunuzu sorduğunuzda yanıtlamanıza yardım etmekle kalmayıp, aynı zamanda yukarı akış ve Linux dağıtımlarındaki durumu iyileştirmeye de katkıda bulundum, böylece orijinalini yazarken mümkün olandan daha iyi bir cevap verebilirim. .


"Otomatik bağlantı başlatılacak şekilde yapılandırılmış tüm bağlantılar otomatik olarak başarılı olana kadar bekle" anlamına gelen otomatik bağlantı seçeneğini mi kastediyorsunuz? No-auto-default = * olarak ayarladığımda bunu kaldırabilir miyim, ancak bağlantılarımdan birinde autoconnect = yes var mı? Ve son soru - anlamıyorum - nm-online ve manuel sayfanın başlangıç ​​için bekle seçeneği pek yardımcı olmuyor. Bu yazı için teşekkürler, çok beğendim!
Kasım'da

Bildiğim kadarıyla, nm-online no-auto-defaultsadece umursamıyor auto. Özel bir sorunuz var mı? Bence nm-online manpage açıkça -sonunla bütün otomatik bağlantıların denenmesini, yani bağlı veya başarısız olmasını beklediğini belirtir .
Pavel Šimerda

Bu saçmalığı bir saat boyunca karıştırdıktan sonra, çözümü buldum: apt-get install sysv-init. :-) Karmaşıklık sistemi bir kaç kabuk betiğinin yerine ekliyor zihniyet verici.
Birisi

@Birisi korkarım initscripts bu durumda bir cevap değildir. NetworkManager veya başka bir dinamik yapılandırma aracı kullanıyorsanız, initscripts tamamen yapılandırılmış bir ağdan sonra kendilerini sipariş edemez. Kullanarak /etc/init.d/networkveya benzer şekilde sınırlı bir dinamik yapılandırma elde edebilirsiniz ancak bu evrensel olarak çalışmaz.
Pavel Šimerda

@Pavel Šimerda Init seri olarak çalıştırılır ve uygun bir init betiği, sonraki komut dosyalarının dayanması gerekenleri tamamlayana kadar geri dönmez. Ağ oluşturma için tüm uygun adaptörlerin hazır ve hazır olması anlamına gelir. Sadece şanslı zamanlama olmadıkça, NM bu bağlamda iyi davranır. Tabii ki asıl sorun NM, mevcut basit ve denenmiş ve test edilmiş yapılar üzerine inşa etmek yerine ağ kullanımını yeniden icat etmektir. Masaüstü insanlarının karmaşıklık tehlikeleri hakkında hiçbir fikri yoktur. ;-)
Birisi

9

Sen kullanabilirsiniz Afteriçinde [Unit]servis başlamadan önce başlatılmalıdır bir hizmeti tanımlamak için bölüm. Örneğin, NetworkManager kullanıyorsanız, NetworkManager başlatıldıktan sonra servisinizi başlatabilirsiniz.

[Unit]
Description=test service
After=NetworkManager.service

BindsTohizmet bir kereye mahsus bir olay olduğundan ve kalıcı bir hizmet olmadığı için uygun değildir ( ExecStopağ bağlantısı kesildiğinde başlatılacak bir özellik içermiyorsa).
goldilocks

kaldırıldıBindsTo
phoops

Değiştirmek için bir şey ekleyebilirsiniz BindsTo, örneğin, Requiresyalnızca eğer servisin NetworkManager çalıştırması durumunda çalışmasını istiyorsanız . AfterAslında bunu yapmaz - bunun anlamı eğer NM da çalışıyorsa, o zaman sonradan bu çalıştırın. NM çalıştırılmayacaksa, servis isteğe bağlı olarak çalıştırılacaktır.
goldilocks

4
After = network.target daha genel olduğundan After = NetworkManager.service öğesinden daha iyidir.
Pavel Šimerda

7
O belirten edin After=fooedecek değil neden foobirimi zaten başlamış değilse, o olacak başlatmak için sadece birimlerini nasıl sipariş systemd anlatmak ikisi de aynı anda başlamış ise . Kullanılması hem After=foode Wants=fooveya Requires=fooçekerek etkisine sahiptir foobirimler doğru systemd sipariş verme de başlamış değilse, vb.
Emil Lundberg

8

Hizmetiniz, birisinin bağlantı kurmasını pasif olarak bekleyebilecek bir sunucu sağlıyorsa, bunu kullanın:

[Unit]
After=network.target

Hizmetiniz joker karakter arabirimine bağlanmalıdır. Soket etkinleştirme kullanıyorsa (önerilir) veya yalnızca yerelse, ağ hedeflerini tamamen yok sayabilirsiniz.

Hizmetiniz bir müşteri olarak hareket ediyorsa veya eşler arası ise, bu daha uygundur:

[Unit]
After=network-online.target
Requires=network-online.target

Systemd 213'ten önce network- online.target'ın bahsedilen Pavel geçici çözümüne ihtiyacı vardır (ağın kurulmasını bekleyecek bir servisi manuel olarak etkinleştirmeniz gerekir). Bu sistem 213'ten itibaren varsayılan olarak yapılır. systemd-networkd-wait-onlinegeridöngü olmayan bir arabirimde yapılandırılmış en az bir adres (yönlendirilebilir veya yerel bağlantı) bekler.

Systemd-networkd, NetworkManager veya eşdeğeri yapılandırmak bağımsız bir iştir. DHCP (IPv4 için) ve NDP (IPv6 için) kutudan çıkma eğilimindedir, ancak bunları “ağ kurulur” un tam tanımı sizin tetikleyeceğiniz şekilde yapılandırmalısınız network-online.target.

Belgeler:


Sadece yeni bir cevabın neden var olduğunu ve mevcut ve (umarım) iyi yapılandırılmış bir cevabın küçük iyileştirmelerinin nedenini merak ediyorum.
Pavel Šimerda

İlk iki Belge bağlantısı şu anda geçersiz durumda.
Peter Hansen,

Neden istemek yerine neden kullanmalısınız?
Karl Morrison

4

WantedBy parametresiyle uğraşarak betiğin çalıştığı noktayı değiştirebileceğimi tahmin ediyorum

İstediğinin tam tersi bir etkisi olacak. Kimden man systemd.unit:

WantedBy =, RequiredBy =

[...] Bu sistem systemctl enable tarafından yüklendiğinde, listelenen her birimin .wants / veya .requires / dizininde sembolik bir bağlantı oluşturulur. Bu tür bir bağımlılığı istiyor = ya da ilave edilir = gerektirir etkiye sahiptir gelen listelenen birimi için mevcut birimin .

Buna dayanarak, uygun ünite seçeneğinin "İsteyenler" veya "Gerekenler" olduğunu görebiliriz; Bu açıklamalara dayanarak, "Gerektiği", muhtemelen yalnızca ağ servisinin çalışmasını sağlamak için değil, bu birimden önce çalışmasını sağlamak için "Sonra" eklenmesiyle de doğrudur.

Birim seçeneklerden hiçbiri, AFAIK, bir başladı perquisite tamamlamış veya yalnızca o, (ağ muhtemelen cin hizmetidir) belli noktaya olması gerektiğini şartı da içerebilir başlatmak ilk. Bunu göz önünde bulundurarak, Type=forkingönce bir DHCP kirası aldığınızdan emin olmak için betiğinizi yapmak ve sağlıklı bir gecikme (örneğin, 30 saniye) veya bir gecikme içeren bir tür başarılı çıkış döngüsü atmak isteyebilirsiniz .


1
Ne WantedBy ne de RequiredBy sıralamayı etkilemez.
Pavel Šimerda

1
@ PavelŠimerda: Burada kimse yaptıklarını iddia etmedi. Sipariş, "yalnızca ağ hizmetinin çalıştırılmasını değil, bu üniteden önce çalıştırılmasını sağlamak" Afterile birlikte açıkça belirtilmemin nedenidir Requires.
goldilocks

1
Evet, Afterbirlikte Wantsya da Requiresbu şekilde çalışır . Öte yandan, açık gecikmeler bağımlılık temelli araçlarda kötü bir alışkanlıktır, özellikle de ağ sistemd dokümantasyonu tarafından belirtilen şekilde yapılandırılana kadar beklemenin açık bir yolu olduğunda, bu yüzden aşağı oyda ısrar etmek zorundayım.
Pavel Šimerda

3

Kendi servisinizden önce nelerin başlaması gerektiğini belirlemek Afteriçin [Unit]bölümü kullanın . (Önceki cevabın bu kadarı doğru.)

Ağınızı açtıktan sonra servisinizi başlatmak için, NetworkManager'ı, Arch'taki conf.d / netctl sistemini veya sistemin farkında olduğu başka bir hizmeti kullanmanız durumunda uygulanacak olan ağ hedefini kullanın.

[Unit]
#.....
After=network.target

Kısa bir bakış, sisteminizde ağ bağlantısına dayanan diğer tüm servislerin bu yönergeyi içerdiğini doğrular.

Ayrıca systemd kullanan tüm dağıtımlara taşınabilir. Birim dosyanız, Debian'ın Arch, Fedora, RHEL 7, gelecekteki sürümleri için aynı olacaktır ...


Arch komut dosyaları veya sizinki gibi bir ağ bağlantısı başlatan servislerin kendi birim dosyalarında belirtmesi gerekir .

[Unit]
Wants=network.target
Before=network.target

Parçayı tamamen sevmiyorum Wantsçünkü diğer paketler üzerinde yan etkileri var. Cevaplarıma bak lütfen.
Pavel Šimerda

Sadece fark Wantsüzerinde network.targetburada iyi bir fikirdir.
Pavel Šimerda

Gerçekten network-online.target kullanmak istiyor. ref
Edward Torvalds

1

Bu yazıya bir nokta eklemek istedim. Şu anda (2015 yazında) RHEL7 / CentOS 7’de, network-online.target IPv6 ağları kurulmadan önce yanlış ayarlanmış

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

IPv6 adreslerine açıkça bağlanan hizmet tanımlarında muhtemelen IPv6 çalıştırılmadan ve çalıştırılmadan önce başlatılacak ve bunların başarısız olmasına neden olacaktır.


Sanırım bu, sadece zaten kusurlu olan çekirdek bazlı IPv6 otomatik konfigürasyonunda böyledir. IPv6'dan sonra doğru bir şekilde sipariş vermek istiyorsanız, kesinlikle yerine NetworkManager kullanmalısınız /etc/init.d/network. NM ile bile aynı sorunu yaşarsanız, bir özellik isteği için iyi bir sebep olabilir. RHEL / CentOS'u kontrol etmedim, ilgileniyorsanız detaylarda size yardımcı olabilirim.
Pavel Šimerda

0
[Unit]
After=systemd-networkd.service

benim için çalışıyor.


Bazı özel durumlarda işe yarayıp yaramadığından emin değilim, ancak birkaç nedenden dolayı yanlış. Bunlardan biri networkd, kendi / online bekle / servisini sağlamasıdır. İçeri network-online.targetçekmek ve sonra sipariş vermek , onu destekleyen herhangi bir servise gitmenin doğru yoludur.
Pavel Šimerda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.