Szef kuchni poleca: Beefy Miracle t-shirts O mnie Planeta !apcoh Social
Szef kuchni poleca: Beefy Miracle t-shirts O mnie Planeta !apcoh Social
Kotek:
![[dachowiec]](http://dżogstaff.pipebreaker.pl/2010.08.13-kotek.jpg)
* dzięki, Doom :)
RTFM: sd_notify
Na początku należy mieć świadomość, że aktywacji jednostek nie podlegają tylko
usługi, a wszystkie możliwe typy. Można więc stworzyć gniazdko, z którym
połączenie zaktywuje inne gniazdo. Albo licznik czasu wyzwalany pojawieniem
się pliku w katalogu. Efektem nawiązania połączenia może być zamontowanie urządzenia.
I to wszystko wyrażone naturalnie zmienną konfiguracyjną Unit=.
Przy konfigurowaniu jednostek działających w podobny sposób można skorzystać
z dyrektywy .include. Usługi mogą korzystać z instancji generowanych
dodaniem znaku @ do nazwy.
Pisząc skrypty działające jako usługi warto je wzbogacić wywołaniami
polecenia systemd-notify przekazującymi konkretniejsze informacji
o stanie działania. Dla demonów w C do poznania jest strona manuala funkcji
sd_notify(). Pełniejszy status może wyglądać następująco:
# systemctl status avahi-daemon.service … Status: "Server startup complete. Host name is dhartha.local. Local service cookie is 3239089184."
Wpisanie zależności jako OnFailure= pozwala zaregować na błędy
przy uruchamianiu/restartowaniu usługi. Efektem może być np. aktywowanie zadania
wysyłającego do administratora maila/SMSa, że kluczowa usługa przestała działać.
Aktywacja usług na żądanie może trwać długo. Zawsze możemy taką długostartującą
usługę przypisać do .wants/ któregoś z celi aktywowanych przy bootowaniu.
Wtedy uruchomienie usługi nastąpi przy starcie systemu.
Zdarza się czasami popsuć system w sposób uniemożliwiający prawidłowy
start. Niechcący można chociażby wyłączyć getty dające
logowanie na konsolach i nie wystartować sieci z ssh.
Uruchomienie awaryjne systemu realizujemy przez linię poleceń
jądra, w ktorej przekazujemy nazwę jednostki do aktywowania zamiast
default.target. Przykładowo systemd.unit=emergency.target.
Jest o tyle lepsze od podania single lub init=/bin/bash, że
po naprawieniu możemy przejść do normalnego uruchomienia systemu: systemctl default.
W czasie pracy można przejść do awaryjnej linii poleceń domyślnie
konfigurowaną usługą kbrequest, startowaną skrótem klawiaturowym
Alt+↑.
Poprzednio: Kontrola startu; Następnie: Spis treści.
RTFM: systemctl, systemd.unit
Do śmieci: chkconfig
W SysV zarządzanie usługami polega na ogarnięciu stada
symlinków z /etc/rcX.d/, odpowiadających runlevelom.
W systemd start usług w większości wynika z zależności,
czasem jednak trzeba dodać coś swojego. Albo wskazać, że
naszserver.target oznacza uruchomienie Tomcata.
Zarządzanie takimi explicit zależnościami również realizuje
się przez łącza symboliczne. Przy analizie każdej jednostki
sprawdzana jest zawartość katalogu o takiej samej nazwie z
doklejonym .wants (np. touchme.service.wants/).
Jednostki, do których symlinki znajdują się wewnątrz traktowane
są jakby były wyszczególnione słowem kluczowym Wants=
w definicji touchme.service.
W drugą stronę: jednostki mogą zasugerować, że są potrzebne do
czegoś, np. przez WantedBy=multi-user.target. W takim przypadku
systemctl enable <UNIT> doda symlinki w katalogach
.wants/ wyszczególnionych jednostek. Analogicznie
disable łącza usunie.
chkconfig SERVICE [on|off] przechodzi w systemctl
[enable|disable] UNIT
Do dyspozycji jest też słówko Also=, które rządzi włączaniem
usług stowarzyszonym. Jednym ruchem można aktywować usługę, jej gniazdko,
timery itp.
Poprzednio: Zależności; Następnie: Użyteczne drobiazgi.
RTFM: systemd.unit
Ważna sprawa, jednak najnudniejsza. Większość zależności nie musi być podawana.
Nie trzeba przykładowo podawać, że usługa wymaga MySQL. Jeśli program połączy
się z /var/lib/mysql/mysql.sock, MySQL zostanie
automatycznie wystartowany.
Zależności explicite między jednostkami mogą
być typu słabego (co jest zalecane). WantedBy= i Wants=
pozwala definiować w obie strony, co jest potrzebne i czemu jest potrzebna
jednostka. Problem w aktywowaniu jednostek chcianych nie powoduje problemu
z aktywacją jednostki rozpatrywanej.
Mocne zależności to requires. Tutaj brak spełnienia zależności
uniemożliwia aktywację jednostki. Podobnie oznaczenie jednostek jako konfliktujących
będzie powodować ich wzajemne wyłączanie przy starcie drugiej.
Słabe zależności mogą być przez systemd zignorowane, jeśli
powodują konflikty. Mocne nie. Obydwa typy nie określają kolejności, wszystkie
wymagane jednostki są startowane jednocześnie z główną. W celu wymuszenia
kolejności można stosować Before= i After=.
Poprzednio: Urządzenia i swap; Następnie: Kontrola startu.
RTFM: systemd.device, systemd.swap
Do śmieci: swapon
Dzięki informacjom pobieranym z udev swoje
odpowiednik wśród jednostek mają urządzenia. Wszystkie, które
w regułkach udev otagowane są znacznikem systemd
mają automatycznie tworzoną jednostkę. W Fedorze dotyczy to urządzeń
blokowych, sieciowych i kilku specjalnych typów.
Skojarzenie z urządzeniem zmiennej SYSTEMD_WANTS pozwala na automatyczne
wystartowanie programów umożliwiających korzystanie ze sprzętu.
Przykłady z /lib/udev/rules.d/99-systemd.rules:
SUBSYSTEM=="bluetooth", TAG="systemd", ENV{SYSTEMD_WANTS}="bluetooth.target"
SUBSYSTEM=="printer", TAG="systemd", ENV{SYSTEMD_WANTS}="printer.target"
ENV{ID_SMARTCARD_READER}=="*?", TAG="systemd", ENV{SYSTEMD_WANTS}="smartcard.target"
Bardzo prostą jednostką jest odzwierciedlenie swapu. Wymaga
tylko podania urządzenie i opcjonalnie priorytetu. Interpretowane są
linijki definiujące swap z /etc/fstab.
Poprzednio: Punkty (auto)mountowania; Następnie: Zależności
RTFM: systemd.mount, systemd.automount
Do śmieci: fstab, mount ;)
Punkty mountowania po części są tworzone automatycznie (dla
systemówych katalogów typu /sys/, /proc/,
/selinux/ itd.), a po części z interpretacji
pliku /etc/fstab. W tym drugim przypadku możemy zarządać
montowania przy starcie systemu wpisując odpowiedni ciąg komentarza.
Zauważylem pewną niekonsekwencję przy zapamiętywaniu urządzenia
do montowania. Przy podaniu UUIDu czasem systemd operuje
na odnośniku do /dev/disk/by-[id,uuid]/, a czasem na urządzeniu:
# grep /boot /etc/fstab UUID=6e958881-903e-4211-a686-4ca8083eaaac /boot ext4 defaults 1 2 # systemctl show -p What boot.mount What=/dev/vda1
Przykład odmontowania:
# findmnt /boot TARGET SOURCE FSTYPE OPTIONS /boot /dev/vda1 ext4 rw,relatime,barrier=1,data=orde # systemctl stop boot.mount # findmnt /boot #
Przy definiowaniu punktu montowania można od razu podać uprawnienia, jakie
mają być nadane katalogowi. Każdy punkt mountowania może być aktywowany dopiero
w momencie dostępu. Używany jest autofs, a punkty automatycznego
mountowania definiuje się w plikach z rozszerzeniem .automount.
W domyślnej konfiguracji pod nadzorem systemd jest kilkanaście
systemów plików:
# findmnt TARGET SOURCE FSTYPE OPTIONS / /dev/mapper/vg_dhartha-lv_root ext4 rw,relatime,barrier=1,data=orde ├─/proc /proc proc rw,relatime │ ├─/proc/sys/fs/binfmt_misc systemd-1 autofs rw,relatime,fd=19,pgrp=1,timeout=300,minproto=5,maxproto=5,dir │ │ └─/proc/sys/fs/binfmt_misc none binfmt_misc rw,relatime │ └─/proc/bus/usb /proc/bus/usb usbfs rw,relatime ├─/sys /sys sysfs rw,relatime │ ├─/sys/kernel/debug systemd-1 autofs rw,relatime,fd=17,pgrp=1,timeout=300,minproto=5,maxproto=5,dir │ │ └─/sys/kernel/debug debugfs debugfs rw,relatime │ └─/sys/kernel/security systemd-1 autofs rw,relatime,fd=18,pgrp=1,timeout=300,minproto=5,maxproto=5,dir ├─/dev udev devtmpfs rw,relatime,size=171468k,nr_inodes=42867,mode= │ ├─/dev/pts devpts devpts rw,relatime,gid=5,mode=620,ptmxmode= │ ├─/dev/shm tmpfs tmpfs rw,relatime │ ├─/dev/hugepages systemd-1 autofs rw,relatime,fd=15,pgrp=1,timeout=300,minproto=5,maxproto=5,dir │ │ └─/dev/hugepages hugetlbfs hugetlbfs rw,relatime │ └─/dev/mqueue systemd-1 autofs rw,relatime,fd=16,pgrp=1,timeout=300,minproto=5,maxproto=5,dir ├─/cgroup tmpfs tmpfs rw,nosuid,nodev,noexec,relatime,mode= │ ├─/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib/systemd/systemd-cgro │ ├─/cgroup/cpuset cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpu │ ├─/cgroup/ns cgroup cgroup rw,nosuid,nodev,noexec,relatime │ ├─/cgroup/cpu cgroup cgroup rw,nosuid,nodev,noexec,relatime │ ├─/cgroup/cpuacct cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpua │ ├─/cgroup/memory cgroup cgroup rw,nosuid,nodev,noexec,relatime,mem │ ├─/cgroup/devices cgroup cgroup rw,nosuid,nodev,noexec,relatime,devi │ ├─/cgroup/freezer cgroup cgroup rw,nosuid,nodev,noexec,relatime,free │ ├─/cgroup/net_cls cgroup cgroup rw,nosuid,nodev,noexec,relatime,net_ │ └─/cgroup/blkio cgroup cgroup rw,nosuid,nodev,noexec,relatime,bl └─/boot /dev/vda1 ext4 rw,relatime,barrier=1,data=orde
Poprzednio: Ścieżki; Następnie: Urządzenia i swap.
RTFM: systemd.path
Do śmieci: inotify-tools
Wbudowana obsługa inotify pozwala reagować na zmiany w
systemie plików. Demon drukarki może być startowany dopiero, gdy w
katalogu z kolejką wydruków pojawi się zadanie. Wrzucenie
pliku przez FTP może uruchamiać program, który przeskanuje go
antywirusowo i przeniesie we właściwe miejsce.
Stwórzmy więc kolejną prostą usługę, która zareaguje na pojawienie
się pliku jego usunięciem. Najpierw usługa (untouchme.service):
[Service] ExecStart=/bin/rm /tmp/hey
I aktywator do niej (untouchme.path):
[Path] PathExists=/tmp/hey
Po systemctl start untouchme.path najlepiej obserować
działanie używając systemctl monitor. Konfiguracji specyficznej
dla jednostki Path nie ma wiele. Poza pojawianiem się plików, także
ich zmiana bądź pojawienie się plików w uprzednio pustym katalogu.
Poprzednio: Timery; Następnie: Punkty (auto)mountowania
RTFM: systemd.timer
Do śmieci: cron (prawie)
Kolejnym udogodnieniem dostępnym w systemd (a zaplanowanym również
dla upstart) jest możliwość wyzwalania czasowego jednostek.
Niestety, nie jak w cronie podawanie dni i godzin, do dyspozycji
jest aktywacja po upłynięciu okresu od konkretnego wydarzenia. Powtarzalność
można uzyskać przez skonfigurowanie licznika do wyzwalania np. „5m” po
starcie systemu i „1w” po zakończeniu działania przez jednostkę. W ten
sposób jednostka będzie aktywowana co tydzień.
Wracając do przykładu, stworzenie pliku touchme.timer
o zawartości:
[Timer] OnUnitInactiveSec=30Spowoduje aktywowanie
touchme.service po upływie pół minuty
od ostatniej aktywacji.
Na tę chwilę nie widzę sposobu na pełną emulację działania crona i at. Zmieni się to, gdy startowanie o konkretnej godzinie (podanej w formacie RFC2445) zostanie dopisane:
133003 <kay> ah, i guess that can all end up in timer. it just has no date-spec parser now
RTFM: systemd.socket
Do śmieci: inetd, xinetd
Przerobienie naszej usługi na sieciową? Banalnie proste (touchme.socket):
Aktywacja:[Socket] ListenStream=1234
# systemctl load touchme.socket Unit touchme.socket added. # netstat -apn | grep 1234 # systemctl start touchme.socket Unit touchme.socket removed. Job 67350 added. Job 67350 removed. Unit touchme.socket added. # netstat -apn | grep 1234 tcp 0 0 :::1234 :::* LISTEN 1/init
Do wyboru obsługa TCP, UDP, SOCK_SEQPACKET i plików FIFO. Od razu możliwość skonfigurowania:
systemd nasłuchuje na wszystkich aktywowanych gniazdach, również
tych w systemie plików. Dzięki temu może startować na żądanie nie tylko demony
sieciowe, ale również te, do których dostęp realizowany jest przez gniazdka
typu /tmp/.s.PGSQL czy /var/lib/mysql/mysql.sock.
Przy usługach, które tworzą nową instancję dla każdego połączenia, warto polecenie
w ExecStart= poprzedzić minusem. Wtedy zniknięcie procesu z
każdego powodu spowoduje usunięcie instancji. Inaczej instancje usług kończących
pracę błędem będą wisiały w systemie, co teoretycznie może doprowadzić do DoSa.
Poprzednio: Cele i migawki; Następnie: Timery.
RTFM: systemd.target, systemd.snapshot
Do śmieci: runlevele
Cele są stosunkowo bezmięsnym typem jednostki. Ich głównym
zadaniem jest zbieranie zależności dla jednostek reprezentujących konkretny
poziom funkcjonalności systemu. Przykładowo, multi-user.target
pozwala na pracę wielu użytkowników — dostępne są konsole tekstowe
i możliwość logowania się po sieci. graphical.target zbiera
usługi potrzebne do pracy graficznej i wymaga uruchomienia graficznego
zarządcy logowania.
Domyślnie, przy starciesystemd aktywuje default.target.
Jest to w założeniu link symboliczny do odpowiedniego celu, np. graphical.target.
W bardzo dużym przybliżeniu odpowiada staremu ustawieniu inittdefault
z pliku /etc/inittab.
Cele mają zapewniać pewien zestaw funkcji i obsługi sprzętu. Przykładowo, urządzenie typu
czytnik smartcard żąda aktywacji smartcard.target. Ten z kolei
w zależnościach demona pcscd i inne usługi przydatne w tej
sytuacji. Jednocześnie może być aktywnych kilka celi, o ile mają
niewykluczające się zależności.
W każdej chwili działania systemu można zrobić migawkę aktualnie aktywnych
jednostek. Powrót to tego punktu działania systemu uzyskujemy poleceniem
systemctl isolate [UNIT]. Aktywowane zostaną jednostki działające
w momencie zrobienia migawki, pozostałe zostaną wyłączone. Odkrycie praktycznego
zastosowania tego mechanizmu czeka jeszcze na uwagę badaczy.