[gelöst] systemd-Service-Units: Conflicts=

Welches Modul/Treiber für welche Hardware, Kernel compilieren...
Antworten
TomL

[gelöst] systemd-Service-Units: Conflicts=

Beitrag von TomL » 24.05.2016 20:06:54

Moin

An anderer Stelle hatte ich einen Text-Schnippsel aus der Man-Page zu service-units zitiert... hier ist der ganze Absatz:
"Conflicts=
A space-separated list of unit names. Configures negative requirement dependencies. If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa. Note that this setting is independent of and orthogonal to the After= and Before= ordering dependencies.

If a unit A that conflicts with a unit B is scheduled to be started at the same time as B, the transaction will either fail (in case both are required part of the transaction) or be modified to be fixed (in case one or both jobs are not a required part of the transaction). In the latter case, the job that is not the required will be removed, or in case both are not required, the unit that conflicts will be started and the unit that is conflicted is stopped.


...worauf niemand erklärt hat:
niemand hat geschrieben:
Wann und wodurch besteht oder ensteht ein Conflict?
Conflicts=… ist eine Option in der Konfiguration, die man halt setzen kann, wenn man weiß, dass die Unit nicht zeitgleich mit einer Anderen laufen kann (welche eben angegeben wird). Damit wird auch der Rest verständlich, und es zeigt auch gut das häufig beobachtbare Problem: speziellere Sachen ohne
Grundlagen zu verstehen, ist schwierig.
Ich habe darauf auch noch mal geantwortet und mich anschließend mit meiner eigenen Antwort beschäftigt.... ich wollte das doch noch mal verifizieren. Und shit... am liebsten würde ich meine dortige Antwort jetzt ungeschehen machen. Denn offensichtlich bin ich da wieder einer Fehlinterpretation aufgesessen. Ich konnte diesen async-Sachverhalt mit zwei neuen Test-Units nicht bestätigen :-( und bin anscheinend wieder am Anfang meiner fehlenden Grundlagen.

Das mit Conflicts und zwei Units ist einfach reproduzierbar.... die im Conflict stehende Unit wird einfach nicht gestartet. Aber ich habe dennoch Fragen, für die ich selber keine Antwort oder plausible Erklärung finden kann. Was bedeutet dieser spezielle Satz im obigen Zitar: "If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa." Der"former" stoppt die letztere und umgekehrt. Was "umgekehrt"...?... . genau dieses "umgekehrt" hat mich anscheinend auf die falsche Fährte mit dem async-Rückschlus geführt.... was aber offensichtlich quatsch ist.

Und warum funktioniert meine Unit nur mit dem Conflicts-Statement, obwohl der Unit-Start und die beiden Targets umount und shutdown weit auseinander liegen:

Code: Alles auswählen

[Unit]
Description=thlu:varlog.service:  Redirect /var/log to mountpoint
DefaultDependencies=no
Before=systemd-journald-dev-log.socket local-fs.target umount.target shutdown.target
Conflicts=umount.target shutdown.target

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/local/bin/varlog start
ExecStop=/usr/local/bin/varlog stop
TimeoutSec=30

[Install]
WantedBy=local-fs.target
Zuletzt geändert von TomL am 29.05.2016 16:16:48, insgesamt 1-mal geändert.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: systemd-Service-Units: Conflicts=

Beitrag von smutbert » 24.05.2016 20:30:42

Sagen wir, wir haben
- unit A in der steht conflicts=B und
- unit B
Wird also unit A gestartet, dann wird unit B gestoppt und umgekehrt wird auch unit A gestoppt, wenn unit B gestartet wird. Es müsste afaik gleichwertig sein, wenn man stattdessen
- unit A
- unit B mit conflicts=A
schreibt.

____

Mir scheinen umount.target und shutdown.target in Before=… kontraproduktiv, denn das sagt ja eigentlich : varlog darf erst gestoppt werden nachdem umount.target und shutdown.target aktiv sind. (Before bezieht sich auf den Start, beim Beenden wird before zu nachher und after zu vorher)
Das ist denke ich das Gegenteil von dem was du erreichen willst.

Auch das conflicts bezieht sich nicht nur auf den Start der unit sondern auf das Laufen derselben und deine varlog-Unit „läuft“ vom Ausführen von "varlog start" bis zum Ausführen von "varlog stop".
Ich vermute also, dass die conflicts=…-Zeile sicherstellt, dass varlog beendet wird noch bevor das Unmounten oder der Shutdown richtig losgehen.

Im Endeffekt habe ich den Eindruck mit der conflicts-Zeile korrigierst du das Mißverständnis in der before-Zeile.

(Es ist aber durchaus möglich, dass ich alles ganz falsch verstehe und etwas ganz anderes vor sich geht.)

TomL

Re: systemd-Service-Units: Conflicts=

Beitrag von TomL » 24.05.2016 20:53:33

Das Ziel dieser Unit resp. des Scripts ist es, das Journal zum frühestmöglichen Zeitpunkt "abzufangen" und das ganze Verzeichnis "/var/log" nach tmpfs zu mounten. Das passiert hiermit....

... und mit Hilfe dieser Verzeichnisse (bzw. eines davon):

Code: Alles auswählen

 TmpVarLogDir="/run/$HOSTNAME/log"               # ->tmpfs
#SikVarLogDir="/var/log_sik"                     # ->SDCard
 SikVarLogDir="/media/var/$HOSTNAME/log"         # ->local HardDisk
#SikVarLogDir="/media/USB/var_log_save"          # ->local USB-Stick
Bei Systemstart die letzte Sicherung restoren und dann /var/log nach /tmpfs->/var/log mounten

Code: Alles auswählen

    start)
        if [ -z "$(grep /var/log /proc/mounts)" ]; then
           cp -Rpu $SikVarLogDir/* $TmpVarLogDir >/dev/null 2>&1

           mount -t tmpfs tmpfs /var/log -o defaults,size="70M"
           chmod 755 /var/log
           cp -Rpu $TmpVarLogDir/* /var/log >/dev/null 2>&1
           rm -r $TmpVarLogDir
        fi
    ;;
Und am Ende, beim Shutdown, soll natürlich das ganze tmpfs->/var/log so gesichert werden, dass die neuen Journal-Einträge beim nächsten Systemstart einfach angehängt werden können..... also es sollen keine Einträge verloren gehen.

Code: Alles auswählen

    stop)
       [ -d $SikVarLogDir ] &&  rm -r $SikVarLogDir/* || mkdir -p $SikVarLogDir
       cp -Rpu /var/log/* $SikVarLogDir >/dev/null 2>&1
       sync
       umount -f /var/log/
    ;;
Und genau das funktioniert eigentlich perfekt... ich habe alle Betriebs-Log-Einträge beginnend vom Systemstart drin und auch fast bis zum Ende des Shutdowns alle Shutdown-Einträge. Und obwohl das alles in tmpfs abläuft, ist auch alles Systemstart-übergreifend verfügbar. Darüber hinaus macht das Script im 6h-Zyklus (8,14,20,2) ein Backup nach $SikVarLogDir. Im Endergebnis habe ich damit für dieses ganze Thema keine Schreibvorgänge auf die SDC.... wie ich das eigentlich auch beabsichtigt habe.

Nur... ich verstehe halt nicht, warum das jetzt funktioniert. Mit Deinen Erklärungen hats gerade etwas "geleuchtet".... aber es war noch nicht hell genug, das ich das wirklich alles sehe und verstehe :roll:

TomL

Re: systemd-Service-Units: Conflicts=

Beitrag von TomL » 25.05.2016 15:26:54

smutbert hat geschrieben:Wird also unit A gestartet, dann wird unit B gestoppt und umgekehrt wird auch unit A gestoppt, wenn unit B gestartet wird. Es müsste afaik gleichwertig sein, wenn man stattdessen
- unit A
- unit B mit conflicts=A
schreibt.
Ja, das ist so... ich habe das gerade mehrfach mit 2 Test-Units durchgespielt. Und jetzt habe ich das auch mit latter and vice versa kapiert. Deine Erklärung hats gebracht. :THX:
Mir scheinen umount.target und shutdown.target in Before=… kontraproduktiv,...
Kontraproduktiv sind sie für den Start wohl nicht, aber anscheinend absolut unnötig. Ohne diese "Before's" geschieht der Start von varlog ebenso zum frühest möglichen Zeitpunkt wie zuvor. Diese Einträge haben dafür keine Auswirkung.....
varlog darf erst gestoppt werden nachdem umount.target und shutdown.target aktiv sind. (Before bezieht sich auf den Start, beim Beenden wird before zu nachher und after zu vorher). Das ist denke ich das Gegenteil von dem was du erreichen willst.
...aber auch beim Beenden haben sie wohl keinen Einfluss. Obwohl es genau das ist, was ich ja eigentlich erreichen müsste. Varlog wird ja quasi vor dem Filesystem gestartet und würde dementsprechend dann beim Shutdown auch erst nach dem Filesystem gestoppt werden. Und damit könnte ich dann die tmpfs-Logs nicht mehr sichern. Varlog muss also auf jeden Fall vor umount beendet werden,

Ich habe die beiden Before's shutdown und umount also auch mal entfernt.... und es funktioniert trotzdem. Aber warum funktioniert das jetzt noch? Eigentlich müsste Varlog ja analog zur umgekehrten Startreihenfole erst dann gestoppt werden, wenn das Filesystem schon nicht mehr erreichbar ist. Und jetzt vermute ich mal, das regelt das Statement "conflicts=umount shutdown". Das bedeutet anscheinend, dass varlog nicht gleichzeitig mit umount und shutdown laufen kann, sondern beim Start von einem der beiden beendet wird. So wie ich das jetzt interpretiere habe ich mit dem Conflicts-Statement eine asynchrone Reihenfolge erzwungen, bei der entweder umount.target oder shutdown.target als Event verwendet wird, um varlog zu beenden.... denn eigentlich wäre varlog ja erst später zum Stop an der Reihe.... nur... das darf eben nicht sein, weil sonst die Sicherung fehlschlagen würden. Kann diese Interpretation richtig sein?

Und hier... die letzten Einträge vom vorherigen boot:

Code: Alles auswählen

Mai 25 14:54:49 raspi5 systemd[1]: var-log.mount mount process exited, code=exited status=32
Mai 25 14:54:49 raspi5 systemd[1]: Failed unmounting /var/log.
Mai 25 14:54:50 raspi5 systemd[1]: Unmounted thlu: Mount Local /tmp to tmpfs.
Mai 25 14:54:50 raspi5 systemd[1]: Unmounted /boot.
Mai 25 14:54:50 raspi5 systemd[1]: Starting Unmount All Filesystems.
Mai 25 14:54:50 raspi5 systemd[1]: Reached target Unmount All Filesystems.
Mai 25 14:54:50 raspi5 systemd[1]: Stopping Local File Systems (Pre).
Mai 25 14:54:50 raspi5 systemd[1]: Stopped target Local File Systems (Pre).
Mai 25 14:54:50 raspi5 systemd[1]: Stopping Create Static Device Nodes in /dev...
Mai 25 14:54:50 raspi5 systemd[1]: Stopped Create Static Device Nodes in /dev.
Mai 25 14:54:50 raspi5 systemd[1]: Stopping Remount Root and Kernel File Systems...
Mai 25 14:54:50 raspi5 systemd[1]: Stopped Remount Root and Kernel File Systems.
Mai 25 14:54:50 raspi5 systemd[1]: Starting Shutdown.
Mai 25 14:54:50 raspi5 systemd[1]: Reached target Shutdown.
Mai 25 14:54:50 raspi5 systemd[1]: Starting Final Step.
Mai 25 14:54:50 raspi5 systemd[1]: Reached target Final Step.
Mai 25 14:54:50 raspi5 systemd[1]: Starting Reboot...
Mai 25 14:54:50 raspi5 systemd[1]: Shutting down.
Und die ersten Einträge des neuen boots:

Code: Alles auswählen

-- Logs begin at Mi 2016-05-25 14:51:09 CEST, end at Mi 2016-05-25 15:10:06 CEST. --
Mai 25 14:54:48 raspi5 systemd-journal[94]: Runtime journal is using 4.0M (max allowed 21.7M, trying to leave 32.5M free of 209.4M available → current limit 21.7M).
Mai 25 14:54:48 raspi5 systemd-journal[94]: Runtime journal is using 4.0M (max allowed 21.7M, trying to leave 32.5M free of 209.2M available → current limit 21.7M).
Mai 25 14:54:48 raspi5 kernel: Booting Linux on physical CPU 0x0
Mai 25 14:54:48 raspi5 kernel: Initializing cgroup subsys cpuset
Mai 25 14:54:48 raspi5 kernel: Initializing cgroup subsys cpu
Mai 25 14:54:48 raspi5 kernel: Initializing cgroup subsys cpuacct
Mai 25 14:54:48 raspi5 kernel: Linux version 4.1.13+ 
Alles ist da, nix geht verloren, obwohl zur Laufzeit alles in tmpfs gespeichert wurde und die Daten sogar 2 mal umgeschaufelt wurden.

:?

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: systemd-Service-Units: Conflicts=

Beitrag von smutbert » 27.05.2016 00:05:18

TomL hat geschrieben:[…]Kann diese Interpretation richtig sein?
[…]
Glaub schon, aber ich sag lieber nichts mehr, ich bin selbst schon zu oft mit Before= und After= durcheinandergekommen.

Antworten