1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
| ---
categories: system sysadmin
title: Howto systemd
...
* Documentation : <https://www.freedesktop.org/software/systemd/man/systemd.service.html>
* Manpages : <https://www.freedesktop.org/software/systemd/man/>
[systemd](https://www.freedesktop.org/wiki/Software/systemd/) est un gestionnaire de services (le fameux démon avec le PID 1) en alternative au System V. Il est installé par défaut depuis Debian 8. Son utilisation a suscitée des débats au sein de l'équipe, mais nous l'utilisons sur tous nos serveurs en Debian 8.
## Utilisation de base
### Statut systemd
Afficher le statut :
~~~
# systemctl status
~~~
Lister les unités qui tournent :
~~~
# systemctl
# systemctl list-units
~~~
Lister les unités en échecs :
~~~
# systemctl --failed
~~~
Lister les unités installées :
~~~
# systemctl list-unit-files
~~~
> *Note* : Les unités sont par défaut dans `/usr/lib/systemd/system/` et `/etc/systemd/system/` (gestion manuelle)
### Gestion des unités
<https://www.freedesktop.org/software/systemd/man/systemd.unit.html>
Démarrer/arrêter/redémarrer une unité :
~~~
# systemctl start <unité>
# systemctl stop <unité>
# systemctl restart <unité>
~~~
Recharger la configuration d'une unité :
~~~
# systemctl reload <unité>
~~~
Afficher le statut d'une unité :
~~~
# systemctl status <unité>
# systemctl status <unité> -l
~~~
Savoir si une unité est activée ou non :
~~~
# systemctl is-enabled <unité>
~~~
> *Note* : Attention, pour les pseudo-unités (qui sont en fait des scripts dans `/etc/init.d/`), `is-enabled` ne fonctionne pas.
Activer/désactiver une unité au boot :
~~~
# systemctl enable <unité>
# systemctl disable <unité>
~~~
Masquer/démasquer une unité (_mask_ rend impossible tout stop/start/…) :
~~~
# systemctl mask <unité>
# systemctl unmask <unité>
~~~
Afficher la man page correspondante au service de l'unité :
~~~
# systemctl help <unité>
~~~
Recharger systemd pour prendre en compte les unités modifiées :
~~~
# systemctl daemon-reload
~~~
Lister les unités en état « failed » :
~~~
# systemctl --failed --all
~~~
Oublier l'état « failed » pour une unité ou l'ensemble des unités :
~~~
# systemctl reset-failed
# systemctl reset-failed <unité>
~~~
### Gestion des timers
Systemd permet aussi la gestion de tâches planifiées.
Elles se décrivent via des unité de type `timers` et vont déclancger une unité de type `service` pour effectuer une action.
Lister les timers :
~~~
# systemctl list-timers --all
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2022-03-11 11:39:00 CET 23min left Fri 2022-03-11 11:09:01 CET 6min ago phpsessionclean.timer phpsessionclean.service
Fri 2022-03-11 11:54:22 CET 38min left Thu 2022-03-10 11:54:22 CET 23h ago etckeeper.timer etckeeper.service
Fri 2022-03-11 11:54:22 CET 38min left Thu 2022-03-10 11:54:22 CET 23h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Fri 2022-03-11 16:16:09 CET 5h 0min left Thu 2022-03-10 18:57:22 CET 16h ago apt-daily.timer apt-daily.service
Sat 2022-03-12 00:00:00 CET 12h left Fri 2022-03-11 00:00:01 CET 11h ago logrotate.timer logrotate.service
Sat 2022-03-12 00:00:00 CET 12h left Fri 2022-03-11 00:00:01 CET 11h ago man-db.timer man-db.service
Sat 2022-03-12 06:53:28 CET 19h left Fri 2022-03-11 06:08:38 CET 5h 6min ago apt-daily-upgrade.timer apt-daily-upgrade.service
7 timers listed.
~~~
> On ajoutera l’option `--user` pour lister les _timers_ de son utilisateur.
>
> $ systemctl --user list-timers --all
Les commandes usuelles (start, stop, disable, enable...) sont donc valide aussi sur des timers. Ainsi :
* Démarrer un timer : `systemctl start <timer>`
* Démarrer un timer au démarrage du système : `systemctl enable <timer>`
* Arréter un timer : `systemctl stop <timer>`
* Désactiver le démarrage d'un timer au démarrage du système : `systemctl disable <timer>`
### Redémarrer ou éteindre un serveur
Avec systemd, les commandes halt/poweroff/shutdown/reboot n'existent plus !
Ce sont des désormais des liens symboliques vers **systemctl**.
On conseille donc d'utiliser directement les commandes « natives ».
Redémarrer le serveur :
~~~
# systemctl reboot
~~~
Éteindre et couper l'alimentation du serveur :
~~~
# systemctl poweroff
~~~
> *Note* : l'option `--force` permet de killer tous les process sans attendre leur extinction propre (à éviter bien sûr)
## Rédaction des unités
<https://www.freedesktop.org/software/systemd/man/systemd.service.html>
### Modifier une unité
~~~
# cp -a /lib/systemd/system/<service>.service /etc/systemd/system/
# vim /etc/systemd/system/<service>.service
# systemctl daemon-reload
~~~
Exemple avec `ssh.service` sous Debian 8 :
~~~
[Unit]
Description=OpenBSD Secure Shell server
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
Alias=sshd.service
~~~
> **Note** : Chaque fois qu'une unité est modifiée, il est nécessaire de recharger systemd avec `systemctl daemon-reload`.
> **N.B.** : La commande donnée dans la variable `ExecStart` n’est pas exécutée dans un shell. Les symboles tels que `>>` ou `&&` ne seront donc par pris en compte comme de la syntaxe shell, mais comme des arguments pour le programme qu’on souhaite exécuter. Si on veut quand même utiliser `>>` par exemple, on fera :
> ```
> ExecStart=/bin/sh -c '/path/to/program >> /path/to/log'
> ```
### Modifier partiellement une unité
Au lieu de tout ré-écrire, on peut surcharger une partie de l'unité en créant un fichier dans `/etc/systemd/system/NOM_UNITÉ.service.d/` qui précisera les modifications à faire. Exemple avec l'unité de _varnish_ on crée le fichier `/etc/systemd/system/varnish.service.d/override.conf` :
~~~
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd -a 0.0.0.0:80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,16G -p thread_pools=8 -p thread_pool_add_delay=2 -p thread_pool_min=500 -p thread_pool_max=5000
ExecReload=
ExecReload=/etc/varnish/reload-vcl.sh
~~~
A noter que les premières directives "ExecStart" et"ExecReload" sont vides : ce ne sont pas des erreurs mais permettent d'effacer les valeurs présentes dans l'unité par défaut avant de les réassigner !
On peut directement utiliser la commande suivante pour surcharger une unité :
~~~
# systemctl edit varnish
~~~
On pourra ensuite lister l'unité complète vue par _systemd_ :
~~~
# systemctl cat varnish
~~~
A noter que cela fonctionne aussi pour les services qui n'ont pas d'unité systemd mais encore une unité sysvinit dans `/etc/init.d/`, on pourra par exemple mettre en place un redémarrage automatique d'un service :
~~~
[Service]
PIDFile=/run/service.pid
Restart=always
RemainAfterExit=no
~~~
### Créer une unité systemd
Modèle simple :
~~~
# /etc/systemd/system/<unit_name>.service
[Unit]
Description=<Unit description>
After=network.target
[Service]
ExecStart=<Start command>
#ExecStop=<Stop command>
#Restart=on-failure
Type=exec
# If main process exits after being run.
#Type=oneshot
#RemainAfterExit=yes
#User=<user>
#Group=<group>
#UMask=027
[Install]
WantedBy=multi-user.target
~~~
Puis :
~~~
systemctl daemon-reload
systemctl enable --now <unit_name>
~~~
### Créer et utiliser un template d'unité
On peut créer et utiliser des template d'unité. Cela permet de gérer à la volée des instances de services.
Par exemple pour _redis_ via `/etc/systemd/system/redis@.service`.
~~~
[Unit]
Description=Advanced key-value store instance %i
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/%i.conf
ExecStartPost=/bin/chgrp %i /var/run/redis/%i.sock
ExecStop=/usr/bin/redis-cli shutdown
Restart=always
User=redis
Group=%i
[Install]
WantedBy=multi-user.target
~~~
`%i` correspond au nom d'instance après le `@`.
On pourra ensuite démarrer l'instance foo et bar avec :
~~~
# systemctl start redis@foo redis@bar
~~~
## systemd par utilisateur
systemd fonctionne avec le PID 1. Mais il est aussi possible de lancer des instances par utilisateur avec le paramètre `--user`. C'est très pratique pour donner les droits à un utilisateur de gérer lui-même ses services (instances _Tomcat_ par exemple).
Il faut avoir le paquet `libpam-systemd` installé : une session systemd est lancée quand on est connecté à la machine :
~~~
$ systemctl --user status
● bar
State: running
Jobs: 0 queued
Failed: 0 units
Since: ven. 2016-12-23 21:15:33 CET; 1 weeks 6 days ago
CGroup: /user.slice/user-1001.slice/user@1001.service
├─1758 /lib/systemd/systemd --user
└─1760 (sd-pam)
~~~
Attention, si l'on veut une session persistante pour un utilisateur, il faut l'activer avec `loginctl` (si l'on ne fait pas cela, les services lancés via `systemctl --user` seront coupés à la déconnexion). Par exemple pour l'utilisateur _foo_ :
~~~
# loginctl enable-linger foo
~~~
On peut aussi désactiver cela :
~~~
# loginctl disable-linger foo
~~~
Attention, si l'on renomme l'utilisateur foo ou que l'on change son UID, il faut supprimer son "linger" :
~~~
# rm /var/lib/systemd/linger/foo
~~~
L'utilisateur peut créer son unité systemd dans son */home* dans le dossier suivant :
~~~
~/.config/systemd/user/
~~~
A créer si les dossier n'existe pas.
Exemple d'unité utilisateur pour _Tomcat_ :
`/etc/systemd/user/tomcat.service`
~~~
[Unit]
Description=Tomcat %u.
After=network.target
[Service]
WorkingDirectory=/home/%u
Environment="CATALINA_BASE=/home/%u/tomcat"
EnvironmentFile=/home/%u/tomcat/conf/env
UMask=0002
ExecStart=/usr/share/tomcat7/bin/startup.sh
ExecStop=/usr/share/tomcat7/bin/shutdown.sh
ExecStopPost=/bin/sh -c date | /usr/bin/mail -s "%H/%u : Shutdown instance" foo@bar.com
Type=forking
[Install]
WantedBy=default.target
~~~
*Note* : il est important que `WantedBy` soit `default.target` car en mode utilisateur `multi-user.target` n'existe pas et donc le service n'est jamais démarré automatiquement.
L'utilisateur pourra ainsi gérer lui-même le service :
~~~
$ systemctl --user enable tomcat
$ systemctl --user start tomcat
$ systemctl --user status -l tomcat
$ systemctl --user restart tomcat
$ systemctl --user stop tomcat
$ systemctl --user daemon-reload
~~~
Si l'on rencontre l'erreur `Failed to connect to bus: No such file or directory` ou que l'on veut pouvoir gérer `systemctl --user` via `sudo -iu foo`, on conseille de mettre dans `/etc/profile.d/systemd.sh` :
~~~
export XDG_RUNTIME_DIR="/run/user/$UID"
~~~
*Attention*, le fichier `/etc/profile.d/systemd.sh` doit avoir les droits 644.
## systemd slice
Documentation: <https://www.freedesktop.org/software/systemd/man/latest/systemd.slice.html>
Resource control: <https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html#>
Les unitées systemd et les process sont lancé dans différentes `slices` qui sont organisé de manière hierarchique.
Chaque slice permet de limiter les ressources (notamment cpu et mémoire via cgroup) accéssibles au services qui y sont lancé.
Il y a 3 slice pricipaux :
- system.slice qui contient les service par défaut
- user.slice qui contient les slices pour chacun des utilisateurs
- machine.slice utilisé pour les conteneurs et machines virtuelles
On peut voir l'ensemble des slices avec `systemctl status`
### Limiter les ressources d'un utilisateur
On peut limiter les ressource d'un utilisateur en éditant son slice :
~~~{.bash}
# systemctl edit --force user-1002.slice
[Slice]
MemoryHigh=80%
MemoryMax=90G
CPUQuota=360%
# systemctl cat user-1002.slice
[Unit]
Description=User Slice of UID %j
Documentation=man:user@.service(5)
StopWhenUnneeded=yes
[Slice]
TasksMax=33%
# /etc/systemd/system/user-1002.slice.d/override.conf
[Slice]
MemoryHigh=80%
MemoryMax=90%
CPUQuota=360%
~~~
- `MemoryHigh` rend plus difficile à un process d'utiliser plus de mémoire
- `MemoryMax` est la mémoire maximale avant que le process se fasse oom kill
> On peut spécifier un pourcentage de la mémoire totale, ou bien directement la valeur, `4G` par exemple
- `CPUQuota` est le pourcentage de temps cpu max, il faut adapter selon le nombre de cpu !
## Utilisation avancée
Afficher plein d'informations sur l'unité :
~~~
# systemctl show <service>
~~~
_Debug_ au démarrage accessible sur _tty9_ :
~~~
# systemctl enable debug-shell
~~~
Débug d'une unité :
~~~
# systemctl stop unit
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/unit
~~~
Analyser ce qui prend du temps au démarrage :
~~~
# systemd-analyze
Startup finished in 5.019s (firmware) + 6.128s (loader) + 5min 35.864s (kernel) + 20min 3.148s (userspace) = 25min 50.160s
# systemd-analyze blame | head -3
2.029s systemd-udev-settle.service
1.400s docker.service
1.215s uml-utilities.service
~~~
## journald/journalctl
Voir la page dédiée à `systemd-journald` et `journalctl` : <https://wiki.evolix.org/HowtoJournald>
## FAQ
### systemd et Debian 8
Sous Debian 8, l'adoption de systemd est récente et de nombreuses services ont des unités mal écrites. Notamment elles ne gèrent souvent pas les options dans `/etc/default/` alors qu'un fichier est créé par défaut.
On conseille alors de corriger l'unité. En général, les corrections sont intégrées en Debian 9.
Exemple avec [Bind](HowtoBind) qui ne gère par les options dans `/etc/default/bind9` en Debian 8.
Pour corriger il faut copier l'unité :
~~~
# cp -a /lib/systemd/system/bind9.service /etc/systemd/system/
~~~
et ajuster la section _[Service]_ :
~~~
EnvironmentFile=-/etc/default/bind9
ExecStart=/usr/sbin/named -f $OPTIONS
~~~
puis :
~~~
# systemctl daemon-reload
~~~
### Limiter les accès disque
Ces directives ajouté dans la section Service seront appliqué au processus parent mais aussi au processus enfant. Prenons le cas de Dovecot où l'on a besoin de réduire sa priorité d'accès en lecture :
~~~
cat /etc/systemd/system/dovecot.service.d/override.conf
[Service]
IOSchedulingClass=best-effort
IOSchedulingPriority=5
~~~
### strace d'un process
Avant _systemd_, une astuce efficace pour stracer un démon multi-process était de faire `strace -ff /etc/init.d/<démon> start` …mais ça n'est plus possible avec systemd : il faut désormais détecter le PID du processus père du démon pour faire un `strace -ff -p<PID>`.
Exemple pour Apache, on récupère le PID, on lance le _strace_ puis on fait un _graceful_ :
~~~
# pstree -pan | grep -v grep | grep apache | head -1
# strace -ff -s65535 -p<PID>
# apache2ctl graceful
~~~
Autre astuce pour récupérer les logs "strace" dans `/tmp/strace.log` :
~~~
# strace -f -o /tmp/strace.log -s 2048 -p 1 & systemctl restart <SERVICE>
~~~
### networking
Sous Debian 8, le démarrage du système se bloque complètement (dead lock) si l'initialisation de process dépendant du réseau (comme NFS, NTP, firewalling…) se fait avant que le réseau soit démarré.
Notamment quand ils sont démarrés via des hooks dans `/etc/network/if-*/`… Cela n'était pas bloquant avec SysV, cf <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754218#30>
Contournement « bourrin » : ajouter `exit 0` dans `/etc/init.d/networking` et voir le souci via `systemctl status networking -l` ; modifier `JobTimeoutUSer` => `systemctl show networking -p JobTimeoutUSer`
### Failed to get D-Bus connection: Unknown error -1
Si en utilisant `systemctl` vous obtenez une erreur "Failed to get D-Bus connection: Unknown error -1" vérifiez si vous êtes bien passé à systemd et n'êtes resté à sysvinit !
Si cela se produit dans un conteneur LXC, voir la section [LXC et cgroupv2](/HowtoDebian/MigrationBusterBullseye#lxc-et-cgroupv2) de la page [HowtoDebian/MigrationBusterBullseye](/HowtoDebian/MigrationBusterBullseye).
### Failed to get D-Bus connection: No such file or directory
Si en tant qu'utilisateur, on obtient l'erreur :
~~~
$ systemctl --user status
Failed to get D-Bus connection: No such file or directory
# ou bien
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)
~~~
S'assurer que l'on a bien une variable d'environnement du type :
~~~
XDG_RUNTIME_DIR=/run/user/1042
~~~
Avec un _strace_ on devrait voir quelque chose comme :
~~~
$ strace systemctl --user status
connect(3, {sa_family=AF_LOCAL, sun_path="/run/user/1042/systemd/private"}, 32) = -1 ECONNREFUSED (Connection refused)
connect(3, {sa_family=AF_LOCAL, sun_path="/run/user/1042/bus"}, 20) = -1 ENOENT (No such file or directory)
~~~
C'est surtout le premier élément qui est intéressant. _systemd_ doit maintenir des sockets Unix fonctionnelles quand un utilisateur est logué :
~~~
$ lsof | grep /run/user/1042
systemd 844 foo 11u unix 0xffff88082dbb9480 0t0 69531078 /run/user/1042/systemd/notify
systemd 844 foo 12u unix 0xffff88082dbb9c00 0t0 69531080 /run/user/1042/systemd/private
~~~
Pour le forcer à les récréer on pourra tester dans l'ordre :
* la commande `loginctl enable-linger foo` pour les rendre persistantes et voir l'effet (quitte à désactiver après)
* `mv /var/lib/systemd/linger/foo /tmp` puis `loginctl enable-linger foo`
* `mv /run/user/1042` puis `loginctl enable-linger foo`
* redémarrer dbus : `systemctl restart dbus`
* redémarrer systemd-logind : `systemctl restart systemd-logind`
* stopper tous les process de l'utilisateur (voir avec lsof) puis se loguer "proprement" avec ssh ou login (et non pas sudo ou su)
Cas d'une installation non standard, tel un container, vérifiez que vous avez bien accès à `/dev`. On peut le vérifier avec dbus-launch.
~~~
foo@bar:~$ dbus-launch
Failed to open /dev/null: Permission denied
~~~
Parfois avec OpenVZ, les containers sont démarrés avec `/dev` en 700.
### Please remove executable permission bits
Contrairement à SysVinit, les unités systemd sont des fichiers de configurations et non des éxécutables, les droits doivent donc etre en **644** pour éviter le warning suivant:
~~~
Configuration file /etc/systemd/XXXX/XXXX.service is marked executable. Please remove executable permission bits. Proceeding anyway.
~~~
### systemd-fsck : Dependency failed
Vous obtenez _systemd-fsck : Dependency failed for File System Check on /dev/disk/foo_ ?
Par défaut, `systemd-fsck` attend 1m30 l'accès à chaque device disque. Pour diverses raisons (accès à un SAN externe, etc.) cela peut échouer, vous aurez alors :
~~~
systemd[1]: Job dev-disk-by\x2dlabel-foo.device/start timed out.
systemd[1]: Timed out waiting for device dev-disk-by\x2dlabel-foo.device.
systemd[1]: Dependency failed for /backup.
systemd[1]: Dependency failed for Local File Systems.
systemd[1]: Triggering OnFailure= dependencies of local-fs.target.
systemd[1]: Dependency failed for File System Check on /dev/disk/by-label/foo.
~~~
Vous pouvez alors ajouter différentes options via le fstab, du type :
~~~
LABEL=foo /foo ext4 defaults,nofail,x-systemd.device-timeout=120 0 0
~~~
Notamment `nofail` pour éviter que cela fasse échouer votre séquence de boot !
### systemd VS systemD VS SystemD
**systemd** ne prend aucune majuscule. Ce n'est pas SystemD ou systemD.
### Migrer de sysvinit à systemd
Cette action peut être nécessaire lorsque l'on migre de Debian Wheezy à Jessie.
~~~
# apt install systemd-sysv
The following packages will be REMOVED:
sysvinit-core
# reboot
~~~
et vérifier que GRUB ne se lance pas avec l'option `init=/lib/sysvinit/init`.
### Et les scripts dans /etc/init.d/ ?
Avec systemd, pourquoi reste-t-il des scripts dans `/etc/init.d/` ?
systemd prend en compte les scripts dans `/etc/init.d/` :
* les scripts « classiques » sont pris en compte si il n'existe pas d'unité systemd avec le même nom (sa description commence alors par **LSB:**)
* certains scripts sont juste là par compatibilité afin de pouvoir faire `/etc/init.d/foo start/stop/restart/status` mais c'est en fait l'unité systemd qui est prise en compte
### Boot bloqué pour partition inaccessible
Si on modifie le partitionnement et qu'on oublie de mettre à jour le fstab, ou qu'un disque n'est plus détecté, il arrive que le démarrage soit bloqué.
Au démarrage du serveur, à l'écran de boot, on choisira `e` pour "éditer" les options de démarrage. À la fin de la ligne `linux` on ajoutera `init=/bin/bash` puis on demande la suite du boot (probablement `F10`).
On a alors la possibilité de remonter la partition `/` en écriture avec `mount -o remount,rw /` puis d'éditer le fstab avec `vi /etc/fstab`.
Au prochain démarrage les paramètres spécifiques de grub sont oubliés et le démarrage devrait se faire sans encombre.
NB : l'édition des paramètres de grub et le shell tmeporaire sont habituellement en keymap qwerty !
## Exemples d'unités
### Process Node.js géré via forever
*forever* est lui-même un gestionnaire de process, mais dans certains cas c'est pertinent d'empiler les 2 gestionnaires. Voici un exemple fonctionnel (qu'on pourrait vouloir transformer en unité "user", d'ailleurs) :
~~~
# /etc/systemd/system/foo_chat.service
[Unit]
Description=Node.js process for Foo chat
After=network.target
[Service]
ExecStart=/usr/local/bin/forever start --pidFile /home/foo/www/foo.pid -o /home/foo/www/log/out.log -e /home/foo/www/log/err.log /home/foo/www/bin/www
ExecStop=/usr/local/bin/forever stop /home/foo/www/bin/www
PIDFile=/home/foo/www/foo.pid
Type=forking
LimitNOFILE=4096
User=nod
Restart=always
[Install]
WantedBy=default.target
~~~
### Process Java / JBoss (exemple avec wildfly)
Il faut mettre les variables d’environnement java dans un fichier que l'on appelle avec la variable *EnvironmentFile=* dans l'unité systemd, voici un exemple Environment File :
~~~
JBOSS_HOME=/home/wildfly/wildfly-10.1.0.Final/
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
JAVA=/usr/lib/jvm/java-8-openjdk-amd64/bin/java
JBOSS_LOG_DIR=/home/wildfly/wildfly-10.1.0.Final/analysis/log/
JBOSS_CONFIG_DIR=/home/wildfly/wildfly-10.1.0.Final/analysis/configuration/
JBOSS_CONFIG=standalone.xml
MODULE_OPTS=
JBOSS_MODULEPATH="/home/wildfly/wildfly-10.1.0.Final/modules"
instance_name=analysis
JAVA_OPTS="-server -Xms256m -Xmx2048M -XX:MetaspaceSize=192M -XX:MaxMetaspaceSize=2048m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.server.base.dir=/home/wildfly/wildfly-10.1.0.Final/analysis -Djboss.node.name=analysis -Djboss.as.management.blocking.timeout=701"
~~~
Voici un exemple d'unité systemd :
~~~
[Unit]
Description=Jboss Application Server
After=network.target
[Service]
Type=exec
EnvironmentFile=/home/wildfly/prod_wildfly_analyses_env
User=wildfly
Group=wildfly
ExecStart=/home/wildfly/wildfly-10.1.0.Final/bin/standalone.sh
#TimeoutStartSec=600
#TimeoutStopSec=600
[Install]
WantedBy=multi-user.target
~~~
|