Oramai praticamente tutte le nuove release delle distribuzioni Linux hanno abbandonando il denome init ( SystemV init o SysV init ) per passare al demone systemd come controllore dei servizi e del sistema.
Uno dei principali vantaggi di systemd è la capacità di avviare i processi in parallelo (aggressive parallelization capabilities). Con init infatti i processi vengono avviati in modo seriale e un task può essere avviato solo quando il precedente si è concluso correttamente. Come per avviene per init systemd è il primo processo che sia avvia ed è il padre di tutti i processi nati dopo successivamente, tipicamente ha assegnato pid=1.
A differenza di SysV init, systemd init è responsabile del mount point, della crittografia, di syslog, etc superando così le funzionalità di un init system di base. La gran parte delle azioni di systemd si svolge agendo su risorse denominate “units”. Le units sono definite da files noti come unit files. Il tipo di unit files è in genere riconoscibile a partire dall’estensione del file. Conseguentemente lo unit file di un servizio avrà l’estensione .service: il servizio di dbase postgresql avrà come target uno unit files del tipo postgresql.service.
Il comando utilizzato per controllare systemd è systemctl.
Conseguentemente la situazione abbastanza frequente di verificare che un servizio o demone (service o daemon) sia in esecuzione ad esempio: apache ,mysqld, postrgresql, samba, ssh, nfs, rsync, cron, syslogd, etc. in un sistema Linux con systemd init sarà diversa da quella con SysV init.
Controllare che un servizio sia attivo: comparazione tra SysV init e systemd init
SysV init
per controllare che il servizio postgresql sia in esecuzione con SysV init utilizziamo il comando
service nome-del-servizio status per postgresql service postgresql status
ubuntu 12
$ service postgresql status 9.1/main (port 5432): online
per dettagli sul controllo dello stato di un servizio in SysV init fare riferimento al post:
Come controllare che un servizio (service) sia in esecuzione in linux
Systemd init
per controllare che un servizio con systemd sia in esecuzione è necessario conoscere lo unit file di riferimento e utilizzare il comando systemctl
systemctl status nome-unit-file.estensione per postgresql systemctl status postgresql@9.6-main.service
debian 9
# systemctl status postgresql@9.6-main.service ● postgresql@9.6-main.service - PostgreSQL Cluster 9.6-main Loaded: loaded (/lib/systemd/system/postgresql@.service; disabled; vendor preset: enabled) Active: active (running) since Sat 2018-04-28 16:23:29 CEST; 4min 36s ago Process: 19786 ExecStop=/usr/bin/pg_ctlcluster --skip-systemctl-redirect -m fast 9.6-main stop (code=exited, status=0/SUCCESS) Process: 19792 ExecStart=postgresql@9.6-main --skip-systemctl-redirect 9.6-main start (code=exited, status=0/SUCCESS) Main PID: 19799 (postgres) Tasks: 6 (limit: 4915) CGroup: /system.slice/system-postgresql.slice/postgresql@9.6-main.service ├─19799 /usr/lib/postgresql/9.6/bin/postgres -D /var/lib/postgresql/9.6/main -c config_file=/etc/postgresql/9.6/main/postgresql.conf ├─19801 postgres: 9.6/main: checkpointer process ├─19802 postgres: 9.6/main: writer process ├─19803 postgres: 9.6/main: wal writer process ├─19804 postgres: 9.6/main: autovacuum launcher process └─19805 postgres: 9.6/main: stats collector process Apr 28 16:23:27 deb9 systemd[1]: Starting PostgreSQL Cluster 9.6-main... Apr 28 16:23:29 deb9 systemd[1]: Started PostgreSQL Cluster 9.6-main.
come si può osservare l’outup è decisamente più articolato di sysV.
Unit file
Per visualizzare il contenuto dello unit file responsabile dell’avvio del servizio postgresql si può utilizzare il comando: systemctl cat nome-unit
systemctl cat postgresql@9.6-main.service # /lib/systemd/system/postgresql@.service # systemd service template for PostgreSQL clusters. The actual instances will # be called "postgresql@version-cluster", e.g. "postgresql@9.3-main". The # variable %i expands to "version-cluster", %I expands to "version/cluster". # (%I breaks for cluster names containing dashes.) [Unit] Description=PostgreSQL Cluster %i ConditionPathExists=/etc/postgresql/%I/postgresql.conf PartOf=postgresql.service ReloadPropagatedFrom=postgresql.service Before=postgresql.service [Service] Type=forking # @: use "postgresql@%i" as process name ExecStart=@/usr/bin/pg_ctlcluster postgresql@%i --skip-systemctl-redirect %i start ExecStop=/usr/bin/pg_ctlcluster --skip-systemctl-redirect -m fast %i stop ExecReload=/usr/bin/pg_ctlcluster --skip-systemctl-redirect %i reload PIDFile=/var/run/postgresql/%i.pid SyslogIdentifier=postgresql@%i # prevent OOM killer from choosing the postmaster (individual backends will # reset the score to 0) OOMScoreAdjust=-900 # restarting automatically will prevent "pg_ctlcluster ... stop" from working, # so we disable it here. Also, the postmaster will restart by itself on most # problems anyway, so it is questionable if one wants to enable external # automatic restarts. #Restart=on-failure # (This should make pg_ctlcluster stop work, but doesn't:) #RestartPreventExitStatus=SIGINT SIGTERM [Install] WantedBy=multi-user.target
Visualizzare le dipendenze di una unit
In systemd init è possibile visualizzare anche tutte le dipendenze di un servizio quale postgresql con il comando systemctl list-dependecies postgresql@96-main.service.
systemctl cat systemctl list-dependencies postgresql@9.6-main.service postgresql@9.6-main.service ● ├─system-postgresql.slice ● └─sysinit.target ● ├─apparmor.service ● ├─dev-hugepages.mount ● ├─dev-mqueue.mount ● ├─keyboard-setup.service ● ├─kmod-static-nodes.service ● ├─lvm2-lvmetad.socket ● ├─lvm2-lvmpolld.socket ● ├─lvm2-monitor.service ● ├─proc-sys-fs-binfmt_misc.automount ● ├─sys-fs-fuse-connections.mount ● ├─sys-kernel-config.mount ● ├─sys-kernel-debug.mount ● ├─systemd-ask-password-console.path ● ├─systemd-binfmt.service ● ├─systemd-hwdb-update.service ● ├─systemd-journal-flush.service ● ├─systemd-journald.service ● ├─systemd-machine-id-commit.service ● ├─systemd-modules-load.service ● ├─systemd-random-seed.service ● ├─systemd-sysctl.service ● ├─systemd-timesyncd.service ● ├─systemd-tmpfiles-setup-dev.service ● ├─systemd-tmpfiles-setup.service ● ├─systemd-udev-trigger.service ● ├─systemd-udevd.service ● ├─systemd-update-utmp.service ● ├─cryptsetup.target ● ├─local-fs.target ● │ ├─-.mount ● │ ├─media-ArchivioR.mount ● │ ├─media-Home_Dati.mount ● │ ├─systemd-fsck-root.service ● │ └─systemd-remount-fs.service ● └─swap.target ● └─dev-sda15.swap
Verificare lo stato di tutti i servizi in systemd init – linux
SysV init
Per verificare lo stato di tutti i servizi presenti un sistema sysV init basta usare l’opzione –status-all
$ service --status-all
In pratica –status-all consente di vedere i servizi installati.
systemd
Come già affermato systemd gestisce un numero più elevato di funzionalità rispetto a sysV quindi la visualizzazione di tutte le unit diventa una schermata piuttosto estesa.
In questo caso conviene filtrare le units chiedendo di visualizzare sono le unit di tipo servizio. Per visualizzare tutte le units che systemd può gestire si usa il comando
# systemctl list-units
per restringere il campo a quelle di tipo service aggiungere l’opzione –type=service
# systemctl list-units --type=service
systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
alsa-restore.service loaded active exited Save/Restore Sound Card State
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
binfmt-support.service loaded active exited Enable support for additional executable binary formats
colord.service loaded active running Manage, Install and Generate Color Profiles
console-setup.service loaded active exited Set console font and keymap
cron.service loaded active running Regular background program processing daemon
cups-browsed.service loaded active running Make remote CUPS printers available locally
cups.service loaded active running CUPS Scheduler
dbus.service loaded active running D-Bus System Message Bus
ebtables.service loaded
... loaded active exited Set the console keyboard layout
kmod-static-nodes.service loaded active exited Create list of required static device nodes for the current kernel
libvirt-guests.service loaded active exited Suspend/Resume Running libvirt Guests
libvirtd.service loaded active running Virtualization daemon
lightdm.service loaded active running Light Display Manager
... loaded active exited Raise
● nginx.service loaded failed failed A high performance web server and a reverse proxy server
polkit.service loaded active running Authorization Manager
postgresql.service loaded active exited PostgreSQL RDBMS
postgresql@9.6-main.service loaded active running PostgreSQL Cluster 9.6-main
rpcbind.service
.....
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
runlevel e System state
SysV init runlevel
In SysV init il modo più semplice per visualizzare i servizi attivi in un dato runlevel è digitare un comando del tipo:
sudo ls -l /etc/rc(num-run-level).d/
systemd init System state ( runlevel )
In systemd il concetto di runlevel è sostituito dal concetto di System State o punto di sincronizzazione. Per definire un determinato System State vengono utilizzati degli unit file particolari con estensione .target. Uno unit.target garantirà di avere disponibile tutti gli units che definiscono uno specifico System State senza doversi preoccupare dei singoli elementi. Se si utilizza lo unit sound.target questo starà ad indicare che servizi per l’audio sono pronti all’audio.
In systemd i System State sono più numerosi dei runlevel quelli comparabili con i runlevel possono essere elencati con il comando:
systemctl list-units --type=target
systemctl list-units --type=target UNIT LOAD ACTIVE SUB DESCRIPTION basic.target loaded active active Basic System cryptsetup.target loaded active active Encrypted Volumes getty.target loaded active active Login Prompts graphical.target loaded active active Graphical Interface local-fs-pre.target loaded active active Local File Systems (Pre) local-fs.target loaded active active Local File Systems multi-user.target loaded active active Multi-User System network-online.target loaded active active Network is Online network-pre.target loaded active active Network (Pre) network.target loaded active active Network paths.target loaded active active Paths remote-fs-pre.target loaded active active Remote File Systems (Pre) remote-fs.target loaded active active Remote File Systems rpcbind.target loaded active active RPC Port Mapper slices.target loaded active active Slices sockets.target loaded active active Sockets sound.target loaded active active Sound Card swap.target loaded active active Swap sysinit.target loaded active active System Initialization time-sync.target loaded active active System Time Synchronized timers.target loaded active active Timers virt-guest-shutdown.target loaded active active Libvirt guests shutdown LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 22 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
Benchè il concetto di System State conseguito con gli unit.target sia decisamente più flessibile del concetto di runlevel è possibile evidenziare alcuni target che sono in relazione proprio i principali runlevel di SysV. A questo proposito si può precisare sono diponibili anche unit dal nome evocativo:
systemctl list-units-files --type=target UNIT FILE STATE ... runlevel0.target disabled runlevel1.target disabled runlevel2.target static runlevel3.target static runlevel4.target static runlevel5.target static runlevel6.target disabled ... 59 unit files listed.
Elencare i servizi abilitati in Systemctl
Per elencare tutti i servizi abilitati, enabled, si può far ricorso al solito greo
systemctl list-unit-files | grep enabled
es:
# systemctl list-unit-files | grep enabled
acpid.path enabled
cups.path enabled
apache2.service enabled
atd.service enabled
autovt@.service enabled
avahi-daemon.service enabled
clamav-freshclam.service enabled
console-setup.service enabled
cron.service enabled
...
...
per elencare i servizi in esecuzioni utilizzare il filtro running
systemctl | grep running
es:
# systemctl | grep running
proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File System Automount Point
acpid.path loaded active running ACPI Events Check
cups.path loaded active running CUPS Scheduler
init.scope loaded active running System and Service Manager
session-877.scope loaded active running Session 877 of user maurizio
...
...
Comparazione tra runlevel e target ( System state) :
- Run level 3 è emulato dal target multi-user.target;
- Run level 5 è emulato da target graphycal.target;
- runlevel3.target è un link simbolico a multi-user.target;
- runlevel5.target è un link simbolico a graphycal.target.
Comparazione tra alcuni comandi SysV init (service) e systemd init (systemctl)
systemctl start sshd.service | service sshd start | start |
systemctl status sshd.service | service sshd status | status |
systemctl stop sshd.service | service sshd stop | stop |
systemctl reload sshd.service | service sshd reload | reload |
ls /lib/systemd/system/*.service /etc/systemd/system/*.service | ls /etc/rc.d/init.d/ | lista tutti i servizi avviabili |
systemctl enabled sshd.service | service sshd enabled | attivare un servizio al prossimo boot |
Avviare e abilitare un servizio al prossimo boot
Per avviare un servizio come il webserver apache2 e come abilitarlo al riavvio al successvio boot
systemctl start apache2 systemctl enable apache2