Linux.systemd: Unterschied zwischen den Versionen

Aus OrgaMon Wiki
Zur Navigation springen Zur Suche springen
 
(20 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
"systemd" ist ein Linux-Programm das den ganzen Boot- und Start-Prozess des Linux-Betriebssystem durchführt. Wenn man Server-Dienste betreibt kommt man systemd in Berührung. Zu startende Dienste sind von anderen abhängig so dass dieser Boot-Prozess nicht ganz einfach ist.
"systemd" (https://systemd.io/) ist ein Linux-Programm das den ganzen Boot- und Start-Prozess des Linux-Betriebssystem durchführt. Wenn man Server-Dienste betreibt kommt man systemd in Berührung. Zu startende Dienste sind von anderen abhängig so dass dieser Boot-Prozess nicht ganz einfach ist, systemd bietet hier umfassende Hilfe.


== Bedienung ==
== Bedienung ==


* starten: systemctl start <dienst>
* starten:  
 
** <code>systemctl start <dienst></code>
* Info ob er läuft, und Diagsnose: systemctl status <dienst>
* Info ob er läuft, und Diagsnose:  
 
** <code>systemctl status <dienst></code>
* stoppen: systemctl start <dienst>
* stoppen:  
 
** <code>systemctl stop <dienst></code>
* Stop+Start: systemctl restart <dienst>
* Stop+Start:  
** <code>systemctl restart <dienst></code>
* Autostart AN
** <code>systemctl enable <dienst></code>
* Autostart AUS
** <code>systemctl disable <dienst></code>


== Dokumentation ==
== Dokumentation ==
Zeile 34: Zeile 39:


=== Mounten ===
=== Mounten ===
* Mounts mit systemd sind eine echte Herausforderung, insbesondere weil sie bei booten schiefgehen
* Von Mounts sind oft andere Dienste abhängig, die sollten nicht starten, wenn verschiedene Mounts fehlen
* Es gibt im Moment (meiner Meinung nach) keine ordentliche Lösung
** https://github.com/systemd/systemd/issues/4468


==== eines RAID Arrays ====
==== eines RAID Arrays ====
* verwende immer den "by-id", dieser Funktioniert auch auf einem neuen System, wenn du das RAID umziehen musst


  #
  #
Zeile 44: Zeile 56:
   
   
  [Mount]
  [Mount]
  What=/dev/md/Tokio:0
  What=/dev/disk/by-id/md-uuid-2ca7d214:9c6bfab4:b2ecf28b:72df44ca
  Where=/srv/smb/ra6
  Where=/srv/smb/ra6
   
   
  [Install]
  [Install]
  WantedBy=local-fs.target
  WantedBy=local-fs.target


==== eines remote Samba-Shares ====
==== eines remote Samba-Shares ====
Zeile 66: Zeile 77:
  Type=cifs
  Type=cifs
  Options=guest
  Options=guest
[Install]
WantedBy=remote-fs.target


==== eines lokalen Samba-Shares ====
==== eines lokalen Samba-Shares ====
Zeile 84: Zeile 98:
  Type=cifs
  Type=cifs
  Options=guest
  Options=guest
==== Automount ====
* man kann das Mounten verzögern (also nicht direkt beim boot) indem man das .mount nicht enabled
* anstelle dessen enabled man eine automount unit:
#
# /etc/systemd/system/srv-ftp.automount
#
[Unit]
Description=srv-ftp
[Automount]
Where=/srv/ftp
[Install]
WantedBy=remote-fs.target


=== cOrgaMon ===
=== cOrgaMon ===
Zeile 161: Zeile 192:
  [Install]
  [Install]
  WantedBy=multi-user.target
  WantedBy=multi-user.target
=== fb ===
#
# /etc/systemd/system/fb.service
#
# (c) Andreas Filsinger, OrgaMon.org
#
[Unit]
Description=route like a gateway
Requires=network-online.target
After=network-online.target
[Service]
WorkingDirectory=/root
ExecStart=/root/fb.sh
[Install]
WantedBy=multi-user.target
=== einzelne Festplatten in den Standby ===
#
# (c) Andreas Filsinger, OrgaMon.org
#
# /etc/systemd/system/hdstandby@.service
#
[Unit]
Description=Send "spare" Drives of an RAID-Array to standby
After=multi-user.target
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 120
ExecStart=/sbin/hdparm -y /dev/disk/by-id/%i
[Install]
WantedBy=multi-user.target
#
# "So" bekommst Du die Device Namen raus
#
l /dev/disk/by-id/ata*
#
# "So" legst du Platten nach dem Start schlafen
#
systemctl enable hdstandby@ata-WDC_WD20PURX-64P6ZY0_WD-WCC4M0XEZ7CH


== Diagnose ==
== Diagnose ==
Zeile 170: Zeile 251:


[[Datei:Systemd-cOrgaMon.png]]
[[Datei:Systemd-cOrgaMon.png]]
* journalctl --unit=sshd
=== Sind alle Units gestartet ===
systemctl status
systemctl list-units --failed
== Programmierung ==
* Ziele
**  Ich will mit freepascal einen Header Haben mit libsystemd.so
*** #include "systemd/sd-daemon.h"
*** sd_notify(0, "READY=1");
*** auto r = sd_notify(0, "READY=1\nSTATUS=Polyzalos woke up");
** Ich will einen ordentlichen cOrgaMon (Linux) haben der sich mit systemd unterhält
** So soll er in einem ersten Step melden, sobald er die Konfiguration geladen hat
** In einem 2. Step soll er über einen Watchdog kontrolliert werden
** Ein weiter Schritt soll sein, dass das Logging über die Lib-Funktionen läuft
** Ein weiterer Schritt soll ein, dass der Dienst ordentlich auf einen Shut-Down reagiert
*** Keine Annahme mehr von Aufgaben
*** Kontrollierter Abbruch oder Beendigung von aktuellen Aufgaben
*** Meldung an systemd wenn es save ist den PID zu killen oder freiwilliger exit
program daemond;
uses
  cthreads,
  BaseUnix,
  SomeOtherUnit;
var
  bTerm: boolean;
  aTerm: pSigActionRec;
  aThread: TThreadDefinedInSomeOtherUnit;
 
  procedure ProcessSig(sig: longint); cdecl;
  begin
    bTerm := (bTerm) or (sig = SIGTERM);
  end;
 
begin
  bTerm := False;
  New(aTerm);
  aTerm^.sa_handler := SigActionHandler(@ProcessSig);
  FillChar(aTerm^.sa_mask, SizeOf(aTerm^.sa_mask), #0);
  aTerm^.sa_flags := 0;
  {$IFDEF LINUX}
  aTerm^.sa_restorer := nil;
  {$ENDIF}
  fpSigAction(SIGTERM, aTerm, nil);
  if fpFork = 0 then
  begin
    Close(input);
    Close(output);
    Assign(output, '/dev/null');
    ReWrite(output);
    Close(stderr);
    Assign(stderr, '/dev/null');
    ReWrite(stderr);
    aThread := TThreadDefinedInSomeOtherUnit.Create;
    try
      repeat
        fpSleep(1);
      until bTerm;
    finally
      aThread.Terminate;
      aThread.WaitFor;
      aThread.Free;
    end;
  end;
  Dispose(aTerm);
end.


== Alternativen ==
== Alternativen ==

Aktuelle Version vom 10. September 2021, 16:58 Uhr

"systemd" (https://systemd.io/) ist ein Linux-Programm das den ganzen Boot- und Start-Prozess des Linux-Betriebssystem durchführt. Wenn man Server-Dienste betreibt kommt man systemd in Berührung. Zu startende Dienste sind von anderen abhängig so dass dieser Boot-Prozess nicht ganz einfach ist, systemd bietet hier umfassende Hilfe.

Bedienung

  • starten:
    • systemctl start <dienst>
  • Info ob er läuft, und Diagsnose:
    • systemctl status <dienst>
  • stoppen:
    • systemctl stop <dienst>
  • Stop+Start:
    • systemctl restart <dienst>
  • Autostart AN
    • systemctl enable <dienst>
  • Autostart AUS
    • systemctl disable <dienst>

Dokumentation

Aufgaben und Anwendungen

Login

  • der "automatische Login" soll bei Servern selbstverständlich verhindert werden
    • Q: How To Disable Auto Login?
    • A: Yast - Security and Users - User/Group Management - Expert Options >Login Settings
  • der resourcenfressende grafische Anmeldeschirm soll unterdrückt werden
    • systemctl set-default multi-user.target

Apache2 Webserver

systemctl enable apache2
systemctl start apache2

Mounten

  • Mounts mit systemd sind eine echte Herausforderung, insbesondere weil sie bei booten schiefgehen
  • Von Mounts sind oft andere Dienste abhängig, die sollten nicht starten, wenn verschiedene Mounts fehlen
  • Es gibt im Moment (meiner Meinung nach) keine ordentliche Lösung

eines RAID Arrays

  • verwende immer den "by-id", dieser Funktioniert auch auf einem neuen System, wenn du das RAID umziehen musst
#
# srv-smb-ra6.mount
#
[Unit]
Description=srv-smb-ra6

[Mount]
What=/dev/disk/by-id/md-uuid-2ca7d214:9c6bfab4:b2ecf28b:72df44ca
Where=/srv/smb/ra6

[Install]
WantedBy=local-fs.target

eines remote Samba-Shares

#
# /etc/systemd/system/srv-nas-user1.mount
#
[Unit]
Description=srv-nas-user1
Requires=network-online.target
After=network-online.target

[Mount]
What=//newyork/user1
Where=/srv/nas/user1
Type=cifs
Options=guest

[Install]
WantedBy=remote-fs.target

eines lokalen Samba-Shares

#
# /etc/systemd/system/root-.wine-drive_w.mount
#
# Mount für den cOrgaMon Server
# 
[Unit]
Description=root-.wine-drive_w
Requires=network-online.target smb.service
After=network-online.target smb.service

[Mount]
What=//tokio.pcworld/app
Where=/root/.wine/drive_w
Type=cifs
Options=guest

Automount

  • man kann das Mounten verzögern (also nicht direkt beim boot) indem man das .mount nicht enabled
  • anstelle dessen enabled man eine automount unit:
#
# /etc/systemd/system/srv-ftp.automount
#
[Unit]
Description=srv-ftp

[Automount]
Where=/srv/ftp

[Install]
WantedBy=remote-fs.target

cOrgaMon

als XMLRPC-Server

#
# /etc/systemd/system/cOrgaMon-XMLRPC@.service
#
# systemd Rulez for the cOrgaMon Service als XMLRPC
#
# (c) 2016 Andreas Filsinger
#
[Unit]
Description=cOrgaMon-XMLRPC Server
Requires=root-.wine-drive_h.mount multi-user.target
After=root-.wine-drive_h.mount multi-user.target

[Service]
UMask=000
Environment="WINEDEBUG=-all" "LANG=de_DE.UTF-8"
ExecStart=/usr/bin/wine "C:\\Program Files (x86)\\OrgaMon\\cOrgaMon.exe" "--Port=%i"

als App-Server

#
# systemd Rulez for the cOrgaMon Service
#
# (c) 2016 Andreas Filsinger
#
[Unit]
Description=cOrgaMon App-Server
After=root-.wine-drive_w.mount
Requires=root-.wine-drive_w.mount

[Service]
UMask=000
Environment="WINEDEBUG=-all" "LANG=de_DE.UTF-8"
ExecStart=/usr/bin/wine "C:\\Program Files (x86)\\OrgaMon\\cOrgaMon.exe" "--app" "--Id=%i"

als Foto-Server

#
# systemd Rulez for the cOrgaMon Service
#
# (c) 2016 Andreas Filsinger
#
[Unit]
Description=cOrgaMon Foto-Server
Requires=root-.wine-drive_w.mount
After=root-.wine-drive_w.mount

[Service]
UMask=000
Environment="WINEDEBUG=-all" "LANG=de_DE.UTF-8"
ExecStart=/usr/bin/wine "C:\\Program Files (x86)\\OrgaMon\\cOrgaMon.exe" "--foto" "--Id=%i"

aqbd

#
# /etc/systemd/system/aqbd.service
#
# (c) Andreas Filsinger, OrgaMon.org
#

[Unit]
Description=AqBanking Daemon
After=multi-user.target

[Service]
StandardOutput=null
StandardError=null

ExecStartPre=/srv/aqb/aqbd.sh
ExecStart=/srv/aqb/aqb -D

[Install]
WantedBy=multi-user.target

fb

#
# /etc/systemd/system/fb.service
#
# (c) Andreas Filsinger, OrgaMon.org
#

[Unit]
Description=route like a gateway
Requires=network-online.target
After=network-online.target

[Service]
WorkingDirectory=/root
ExecStart=/root/fb.sh

[Install]
WantedBy=multi-user.target

einzelne Festplatten in den Standby

#
# (c) Andreas Filsinger, OrgaMon.org
#
# /etc/systemd/system/hdstandby@.service
#
[Unit]
Description=Send "spare" Drives of an RAID-Array to standby
After=multi-user.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 120
ExecStart=/sbin/hdparm -y /dev/disk/by-id/%i

[Install]
WantedBy=multi-user.target


# 
# "So" bekommst Du die Device Namen raus
#
l /dev/disk/by-id/ata*
#
# "So" legst du Platten nach dem Start schlafen
#
systemctl enable hdstandby@ata-WDC_WD20PURX-64P6ZY0_WD-WCC4M0XEZ7CH

Diagnose

  • sehr hilfreich ist die Grafik, die systemd erstellen kann.
  • Es ist dann immer gut zu Erkennen, wenn Dienste nicht starten können weil Abhängigkeiten nicht funktionieren
systemd-analyze plot > /srv/www/web/systemd.svg

  • journalctl --unit=sshd

Sind alle Units gestartet

systemctl status
systemctl list-units --failed

Programmierung

  • Ziele
    • Ich will mit freepascal einen Header Haben mit libsystemd.so
      • #include "systemd/sd-daemon.h"
      • sd_notify(0, "READY=1");
      • auto r = sd_notify(0, "READY=1\nSTATUS=Polyzalos woke up");
    • Ich will einen ordentlichen cOrgaMon (Linux) haben der sich mit systemd unterhält
    • So soll er in einem ersten Step melden, sobald er die Konfiguration geladen hat
    • In einem 2. Step soll er über einen Watchdog kontrolliert werden
    • Ein weiter Schritt soll sein, dass das Logging über die Lib-Funktionen läuft
    • Ein weiterer Schritt soll ein, dass der Dienst ordentlich auf einen Shut-Down reagiert
      • Keine Annahme mehr von Aufgaben
      • Kontrollierter Abbruch oder Beendigung von aktuellen Aufgaben
      • Meldung an systemd wenn es save ist den PID zu killen oder freiwilliger exit
program daemond;

uses
 cthreads,
 BaseUnix,
 SomeOtherUnit;

var
 bTerm: boolean;
 aTerm: pSigActionRec;
 aThread: TThreadDefinedInSomeOtherUnit;
 
 procedure ProcessSig(sig: longint); cdecl;
 begin
   bTerm := (bTerm) or (sig = SIGTERM);
 end;
 
begin
 bTerm := False;
 New(aTerm);
 aTerm^.sa_handler := SigActionHandler(@ProcessSig);
 FillChar(aTerm^.sa_mask, SizeOf(aTerm^.sa_mask), #0);
 aTerm^.sa_flags := 0;
 {$IFDEF LINUX}
 aTerm^.sa_restorer := nil;
 {$ENDIF}
 fpSigAction(SIGTERM, aTerm, nil);
 if fpFork = 0 then
 begin
   Close(input);
   Close(output);
   Assign(output, '/dev/null');
   ReWrite(output);
   Close(stderr);
   Assign(stderr, '/dev/null');
   ReWrite(stderr);
   aThread := TThreadDefinedInSomeOtherUnit.Create;
   try
     repeat
       fpSleep(1);
     until bTerm;
   finally
     aThread.Terminate;
     aThread.WaitFor;
     aThread.Free;
   end;
 end;
 Dispose(aTerm);
end.

Alternativen

vor openSuSe 12.1

Nehmen wir an, Du hast ein Skript deindienst.sh das deinen Dienst startet, dies soll ab sofort auch nach einem Neustart des Server erfolgen. Das geht so:

  • in /etc/init.d
cp skeleton deindienst
ln -s deindienst /usr/sbin/rcdeindienst
  • nun deinen Dienst anpassen
joe deindienst
# Provides:          deindienst
# Required-Start:    $ALL
  • den ganzen Vorcheck wegmachen
-- snip

# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
FOO_BIN=/usr/sbin/FOO
test -x $FOO_BIN || { echo "$FOO_BIN not installed";
        if [ "$1" = "stop" ]; then exit 0;
        else exit 5; fi; } 

# Check for existence of needed config file and read it
FOO_CONFIG=/etc/sysconfig/FOO
test -r $FOO_CONFIG || { echo "$FOO_CONFIG not existing";
       if [ "$1" = "stop" ]; then exit 0;
       else exit 6; fi; }

# Read config
. $FOO_CONFIG

-- snap --


  • im Startbereich einfach Dein Skript eintragen
       ## Start daemon with startproc(8). If this fails
       ## the return value is set appropriately by startproc.
       /sbin/startproc /etc/deindienst.sh
  • nun den Autostart sicherstellen
chkconfig --add deindienst
  • willst du jetzt schon starten?
rcdeindienst start