spoustet/ukoncovat/povolovat/zakazovat/upravovat sluzby vcetne reseni poradi/zavislosti i paralelniho provadeni 1k sh radku jiste svladne, a nejspis ani pri nedosupnem oddilu pri startu kterej neni pro samotnej start systemu potreba nezkonci v "zachranem rezimu" kterej nebude dostupnej pres ssh a bude se muset k serveru osobne (zdravime sYsTeMd ;-)
no nevrátí. Ono dneska málo lidí umí napsat servicu. A proto vznikl systemd.
Samozřejmě - já jako vývojář mám v C++ třídu napsanou pro servicy, kdy přesně tak jak říkáte, servica vrátí exit code, když vlákno service oznámí, že je ready a že čeká na požadavky. Takový program se pak s cmdline dá ovládat přímo příkazy start/stop/restart/status bez skriptu. SystemD mi v tomhle jen háže klacky pod nohy.
Máte nějaký example? Já jen že všechny init service mají stejné ovládání
start, stop, restart, reload, status
nikdy jsem s tím neměl problém
Stejně tak s instalací service. init akorát neuměl závislosti, ale určitě se to dalo řešit líp, než tak, že starou baterii v autě nahradím jaderným generátorem.
Jestli je ta ovládací utilita zakompilovaná do hlavní binárky nebo je zvlášť je víceméně jedno – akorát ta společná binárka odporuje unixovému principu, že každý nástroj dělá jen jednu věc. Problém je ale hlavně v tom, že si to každý program řeší sám, a každý trochu jinak. Jeden umí komunikovat jenom se svou první instancí, jiný s libovolnou. Normální ve smyslu „běžné“ to možná je, ale to neznamená, že je to správné. Holt když máte neschopné správce služeb, nezbývá, než jejich práci dělat někde jinde, a čekat, až se objeví nějaký lepší správce služeb.
Jo? A jak mám svou službu napsat aby dostávala zprávy od systémd? Možná je to jen dokumentační problém. Ale jediný co jsem se naučil ze všech dokumentaci je jen start a stop tím že to pustí nějaký skript. A to ještě se s tím blbě pracuje a může to dělat jen root.
Něco jako registrace služby uživatelem asi ne (třeba v rámci jeho session, tedy to co dělá gedit nebo firefox nebo chrome)
O psaní služeb, které budou dobře spolupracovat se systemd, se dozvíte např. v man daemon. Konkrétně ta notifikace o aktivaci služby (zpráva od služby pro systemd, ne opačně) se posílá pomocí sd_notify.
Pro obecnou komunikaci se dá použít D-Bus, se kterým systemd také spolupracuje.
Ondřej Novák: Ono je potřeba se nějak popasovat s tím, že tu máte spoustu služeb, které fungují postaru. I tak spousta lidí kveruluje, že systemd přináší novoty. A pořád je tenhle mix nesrovnatelně lepší, než „správce služeb“, který neví ani to, zda vůbec běží proces, který by tu službu měl zajišťovat.
Asi by to chtělo něco vědět o service žejo?
Tak například Windows SCM to nemá špatně udělaný. Service se inicializuje, service běží, service se ukončuje. Všechny stavy ten control manager zná.
Netuším, jak to dělá systemd, ale pokud to nedělá, tak je k ničemu. Chápu starej init, který prostě pustil proces, ten se forknul a jakmile se rodič ukončil, tak se to považovalo za hotové. Jenže některé "služby" se ani neumí forknout, jsou to standalone obyčejné procesy a s nima se prostě nedá nic dělat, než fork-exec a jako service manager si mohu udělat čárku. Případě pak umím nahlásit, že ten proces umřel, aniž by po sobě nechal děti.
Vzhledem k tomu, že systemd považuje za službu i obyčejný proces, který se spustí a skončí a on to vede jako běžící servicu, tak pak to samozřejmě vůbec k ničemu není. Prostě bez toho aby process spolupracoval se service managerem se neobejdeme.
Asi by to chtělo něco vědět o service žejo?
Tak proč si o tom něco nezjistíte?
Service se inicializuje, service běží, service se ukončuje.
Přičemž pro ostatní služby je podstatný ten stav „služba běží“, který neznamená jenom to, že je spuštěný příslušný proces, ale hlavně to, že poskytuje své služby. Některé služby mají prodlevu mezi spuštěním procesu a začátkem poskytování služeb desítky sekund i minuty. Okamžik, kdy služba začala poskytovat služby, nemůže správce služeb obecně z venku zjistit, musí mu to nějak signalizovat samotná služba. Windows SCM tuhle signalizaci má. Shell skripty ji nemají.
Chápu starej init, který prostě pustil proces, ten se forknul a jakmile se rodič ukončil, tak se to považovalo za hotové.
Proces se forknul, aby na něj init nedosáhl. Což vypovídá o kvalitě initu. Jak může správce služeb spravovat nějakou službu, když ji nemá pod kontrolou, když ani neví, zda ten proces ještě běží nebo neběží?
Jenže některé "služby" se ani neumí forknout, jsou to standalone obyčejné procesy a s nima se prostě nedá nic dělat, než fork-exec a jako service manager si mohu udělat čárku.
Je to přesně opačně. Když máte pořádného správce služeb, služba se nebude forkovat a poběží pod správou toho správce. Který pak tu službu opravdu může spravovat.
Vzhledem k tomu, že systemd považuje za službu i obyčejný proces, který se spustí a skončí a on to vede jako běžící servicu, tak pak to samozřejmě vůbec k ničemu není.
Služba ale má být obyčejný proces, který se spustí a ukončí. Pak ho může správce služeb spravovat, můžete službu ladit jako administrátor tak, že ji normálně spustíte z konzole, programátor ji může debugovat.
Prostě bez toho aby process spolupracoval se service managerem se neobejdeme.
No právě. Jenže to pomocí shellu nezařídíte. Shell by se službou mohl komunikovat, pokud by služba běžela jako dceřiný proces. Ale jakmile se služba odforkuje, dostane se z dosahu shellu a veškerá spolupráce tím končí – vždyť ten shellovský init pak neví ani tak základní věc, jako jestli vůbec ještě běží proces té služby.
A on aplikační server se neumí pustit bez databáze? A co dělá, když databáze spadne během činnosti - nebo ji někdo restartuje? To spadne taky?
Co kdyby aplikační server který nevidí databázi prostě počkal dokud databáze nenaběhne, stejně tak musí činit, když ji někdo restartuje? Jako závislosti jsou fajn, ale robustní aplikace si poradí bez nich.
S odpojením od databáze si aplikační server poradí.
Jinak samozřejmě, že si každá aplikace může své závislosti řešit sama. Ale jaká je výhoda v tom, že to bude každá aplikace implementovat znovu a jinak? Mně připadá lepší, když se principiálně stejné věci řeší jednou a stejně. Je to známý unixový princip, kdy každá aplikace dělá jenom jednu věc.
@Filip Jirsak Zvládne ten shell skript také nastartovat databázi, počkat, až je schopná vyřizovat požadavky, a pak nastartovat aplikační server?
nejsem databazista, ale aspon podle mysql myslim neni problem aby "service" pro "shell init system" obsahovala neco jako:
start="mysqld"
check="mysql -u mujuser -e 'use mojedb;'"
tedy polozka check by byla zpracovana pro zjisteni dostupnosti, kdy mysql ma klienta mysql kterej vraci navratovej kod pri uspechu a lze pouzit treba jen "pouzij tuto db", pokud nepujde pouzit je problem a vrati navratovej kod erroru kterej "shell init system" jednoduse zpracuje...
21. 8. 2019, 21:18 editováno autorem komentáře
Takže ten skript pro zjištění dostupnosti by se volal třeba každou sekundu, dokud by nevrátil úspěch? Ano, jde to, ale že by to bylo elegantní řešení, to se říct nedá… Polling bych bral vždy až jako poslední možnost, když není možné se o změně stavu dozvědět pomocí nějaké události. Navíc to, že služba běží, nemusí být ani z venku detekovatelné – např. služba, která bude zpracovávat frontu příchozích souborů v nějakém adresáři.
Podstatné je to, že služby mohou záviset na tom, až jiná služba začne poskytovat své služby. Začátek poskytování služby může mít prodlevu od startu služby – a správci služeb má být úplně jedno, jestli ta prodleva je jedna sekunda nebo jedna hodina. Databáze byla jen příklad. Pokud chcete jiný příklad, tak třeba DNSSEC resolver závisí na tom, aby byl správně synchronizován čas. Nebo webserver, pokud je pro danou doménu spuštěn poprvé, může před začátkem poskytování služby žádat o vystavení HTTPS certifikátu – a to lusknutím prstu opravdu nezařídíte.