Handbuch · Kapitel 4

Backup-Server einrichten (bkp_target)

Zum Inhaltsverzeichnis

bkp_target nimmt Sicherungen von beliebig vielen Agents entgegen und legt sie in Stores unter <storage>/<verzeichnis>/<store>.cbs ab. Alles läuft über TLS. Die Einrichtung besteht aus vier Schritten.

4.1 Schritt 1: Zertifikat und Schlüssel erzeugen#

Auf dem Server:

bkp_maintenance tls-init --cert /etc/bkp/target.crt --key /etc/bkp/target.key --cn backup.example.org

Ausgabe:

wrote certificate to /etc/bkp/target.crt and private key to /etc/bkp/target.key

Das Kommando erzeugt ein selbstsigniertes ECDSA-Zertifikat (P-256, mit subjectAltName aus --cn, ohne externen openssl-Aufruf; Windows und Browser können kein Ed25519). Bereits vorhandene Dateien werden nicht überschrieben, außer mit --force; --days <n> legt die Gültigkeit fest.

target.crt wird zusätzlich auf jedem Client gebraucht: der Agent prüft den Server gegen genau dieses Zertifikat (--tls-ca). Der private Schlüssel target.key bleibt auf dem Server und ist nur für root lesbar.

4.2 Schritt 2: API-Key anlegen#

bkp_maintenance acl-add --acl-file /etc/bkp/acl --dir vm1,vm2

Ausgabe:

added to acl: key=6df1922d599969e0d2c8c10ad723335a95d3cab8f4678e77ba209992aa330b1c dirs=vm1,vm2

Der Key wird einmalig ausgegeben (ohne --key ein zufälliger 256-Bit-Wert). Auf dem Client legst du ihn in eine Datei, die nur der ausführende Benutzer lesen darf:

printf '%s' 6df1922d...330b1c > /etc/bkp/vm1.key
chmod 600 /etc/bkp/vm1.key

Die ACL-Datei hat pro Zeile <api_key> <verz1>[,<verz2>,...]; # oder ; beginnt einen Kommentar (am Zeilenanfang oder nach einem Leerzeichen/Tab, siehe „Kommentare“ unten). Statt des Keys darf dort sein SHA-256 als sha256:<64 Hexziffern> stehen; acl-add schreibt nur diese Prüfsumme, der Key selbst steht nirgends auf dem Server. Geht er verloren, legst du einen neuen an.

Jedes Verzeichnis ist ein Muster relativ zu --storage; * und ? gelten nur innerhalb einer Ebene: vm1 erlaubt genau dieses Verzeichnis, vm* alle Verzeichnisse, deren Name mit vm beginnt, vm1/* eine Ebene darunter, vm1/** jede Tiefe darunter (aber nicht vm1 selbst) und vm1/*** vm1 selbst und jede Tiefe darunter. .. und \ sind nie erlaubt.

Inhalt der ACL

cat /etc/bkp/acl

Ausgabe:

6df1922d599969e0d2c8c10ad723335a95d3cab8f4678e77ba209992aa330b1c vm1,vm2

Tipp: Vergib pro Client einen eigenen Key und binde ihn nur an dessen Verzeichnis. Wird ein Rechner kompromittiert, streichst du eine Zeile in der ACL, ohne die anderen Clients anzufassen. Der Server liest die ACL beim Start (Log: loaded N ACL entry); nach Änderungen bkp_target neu starten.

4.3 Schritt 3: Server starten#

bkp_target --storage /srv/backups --tls-cert /etc/bkp/target.crt --tls-key /etc/bkp/target.key \
           --acl-file /etc/bkp/acl [--bind 0.0.0.0] [--port 9990]

Ausgabe:

[bkp_target] INFO  loaded 1 ACL entry from /etc/bkp/acl
[bkp_target] INFO  bkp_target listening on 0.0.0.0:9990 (storage_root=/srv/backups, TLS enabled)

Einfacher ist die Parameterdatei /etc/bkp/bkp_target.cfg (Vorlage packaging/bkp_target.cfg.example): jede Option hat dort einen gleichnamigen Schlüssel, und der Server startet mit einem schlichten bkp_target. Eine Option auf der Kommandozeile hat Vorrang vor der Datei. bkp_target --config-validate prüft sie; Änderungen wirken nach einem Neustart. bkp_setup --configure-server schreibt sie selbst und lässt dabei alle Zeilen stehen, die es nicht betreffen.

/etc/bkp/bkp_target.cfg

storage=/srv/backups
acl-file=/etc/bkp/acl
tls-cert=/etc/bkp/target.crt
tls-key=/etc/bkp/target.key
port=9990

Pro Verbindung läuft ein eigener Thread. Ein nicht vorhandenes Verzeichnis, das die ACL erlaubt, legt der Server bei der ersten Sicherung an.

Jeder Store hat einen Index (index.lmdb), der standardmäßig im Store liegt. Mit --index-dir <dir> liegen die Indizes stattdessen unter <dir>/<store-uuid>.lmdb, zum Beispiel auf einer SSD; das Verzeichnis muss für das Konto aegisgrid beschreibbar sein. Liegt --storage auf NFS/SMB, ist ein lokales --index-dir Pflicht.

Wichtig: Die Netzwerkseite von bkp_target läuft nie als root: startest du es als root (der Normalfall unter systemd, oder von Hand per sudo), teilt es sich in zwei Prozesse. Ein Arbeitsprozess läuft als der Systembenutzer aegisgrid und erledigt alles, was mit dem Netz zu tun hat (TLS, ACL, Sitzungen, Speichern der Daten in den Stores). Der Elternprozess bleibt root, nimmt selbst keine Verbindungen an und führt für den Arbeitsprozess nur eine kleine, fest vorgegebene Liste privilegierter Aktionen aus (derzeit LVM), über einen lokalen Socket unter /run/bkp_target.

Voraussetzung ist, dass der Benutzer aegisgrid existiert und --storage, --tls-cert, --tls-key und --acl-file ihm gehören (siehe unten) -- fehlt der Benutzer, bricht der Start mit einer Fehlermeldung ab, statt stillschweigend als root weiterzulaufen. Wird bkp_target direkt als normaler Benutzer gestartet, läuft es als ein einziger Prozess unter diesem Benutzer, ohne den root-Teil. bkp_setups Server-Rolle legt den Benutzer automatisch an; bei einer Einrichtung von Hand die folgenden Schritte einmalig ausführen:

groupadd --system aegisgrid
useradd --system --no-create-home --shell /usr/sbin/nologin --gid aegisgrid aegisgrid
chown aegisgrid:aegisgrid /etc/bkp/target.crt /etc/bkp/target.key /etc/bkp/acl
chmod 640 /etc/bkp/target.key
chown -R aegisgrid:aegisgrid /srv/backups

Hinweis: Ältere Versionen liefen unter einem eigenen Benutzer bkp_target. Ein Update über bkp_updater stellt den Dienst einmalig um: es hält bkp_target an und übergibt Speicher, Zertifikat, Schlüssel, ACL und Logdatei per chown -R --from=bkp_target:bkp_target aegisgrid:aegisgrid an aegisgrid. Der alte Benutzer bleibt bestehen. Bei einer Einrichtung von Hand denselben chown selbst ausführen.

4.3.1 Verwaltung über die Target-API#

Der Server lässt sich auch von einem anderen Rechner aus verwalten, zum Beispiel mit der Target-Konsole: laufende Sitzungen beobachten und abbrechen, Einstellungen und Zugänge ändern, den Target-Scheduler steuern, Stores ansehen, prüfen und bereinigen. Die API hört auf Port 9991 (HTTPS) und ist zunächst aus. bkp_setup --configure-server --enable-target-api erledigt die folgenden Schritte bei der Einrichtung; von Hand auf dem Server:

bkp_target --api-init
bkp_target --api-enable
bkp_target --api-token-add konsole --role admin
systemctl reload bkp_target
bkp_target --api-info

Das Token erscheint nur einmal; zusammen mit dem Fingerprint aus --api-info richtest du damit die Konsole ein. Port 9991 nur für die Verwaltungsrechner in der Firewall öffnen. Löschen von Läufen und Jobs, die beliebige Programme starten, sind über die API zunächst gesperrt (allow-delete=yes bzw. allow-exec=yes im Abschnitt [api] von /etc/bkp/bkp_target.cfg). Wie die Target-Konsole damit arbeitet, beschreibt Kapitel 15; die vollständige Beschreibung für Programmierer steht in docs/target-api.txt.

4.3.2 Als systemd-Dienst#

Im Repository liegt packaging/systemd/bkp_target.service:

/etc/systemd/system/bkp_target.service

[Unit]
Description=Backup target server (bkp_target)
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/bkp_target
KillSignal=SIGTERM
TimeoutStopSec=330
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now bkp_target

Die Unit enthält bewusst kein User=/Group=: der Dienst muss als root starten, damit der root-Teil (siehe oben) LVM-Aktionen ausführen kann; den Wechsel zu aegisgrid übernimmt bkp_target selbst. Mit User=aegisgrid läuft es zwar auch, dann aber ohne den root-Teil. systemctl reload bkp_target (SIGHUP) liest Zertifikat, Schlüssel und ACL neu ein, ohne Verbindungen zu trennen. Stirbt der Arbeitsprozess unerwartet, beendet sich auch der root-Teil mit Fehler, und Restart=on-failure startet den ganzen Dienst neu.

Sanftes Beenden: SIGTERM (und SIGINT) nimmt keine neuen Verbindungen mehr an und lässt laufende Sitzungen bis zu --drain-timeout Sekunden (Standard 300) zu Ende laufen. TimeoutStopSec=330 in der Unit liegt bewusst darüber, damit systemd den Dienst nicht vorzeitig beendet. Ein Neustart mitten in der Nacht bricht so keine laufende Sicherung ab.

4.4 Schritt 4: Erste Sicherung über das Netzwerk#

bkp_agent --source data.img --target backup.example.org:9990 --target-dir vm1 \
          --tls-ca /etc/bkp/target.crt --api-key file:/etc/bkp/vm1.key --name data

Ausgabe:

[bkp_agent] INFO  source is not an LVM logical volume: backing it up directly (no snapshot)
[bkp_agent] INFO  created the store backup.example.org:9990/vm1/default.cbs (id hash blake3, encryption none,
                  chunks 65536/262144/1048576, segments of 1073741824 bytes)
[bkp_agent] INFO  done: full run 20261015T121825Z-6aa5d6f2-... in backup.example.org:9990/vm1/default.cbs:
                  source 16777216 bytes, data 13631488, holes 3145728 (fs-free 0); chunks 44, new 44 (0.0% deduplicated);
                  12587566 bytes sent, 12587566 newly stored

Der Server legt den Store beim ersten Lauf unter /srv/backups/vm1/default.cbs an (ein anderer Name mit --store). Für jeden Chunk fragt der Agent in Stapeln, ob der Store ihn schon hat, und sendet nur die fehlenden. Mehrere Rechner, die in denselben Store sichern, deduplizieren so auch über das Netz gegeneinander. Ein Run entsteht erst, wenn der Server alle Daten sicher gespeichert hat. --verify wirkt im Netzwerkmodus nicht (der Restore prüft ohnehin jeden Chunk).

Jede weitere Sicherung ist wieder derselbe Befehl; übertragen wird nur, was dem Store fehlt. --out und --target dürfen zusammen angegeben werden: dann wird die Quelle einmal gelesen und jeder Store bekommt seinen eigenen, vollständigen Run (lokale Kopie plus Server). Mehr Ziele, eigene Verschlüsselung je Ziel und optionale Ziele gehen über Sinks (unten).

4.4.1 Konfigurationsdatei statt langer Kommandozeile#

Für Cron/systemd-Timer und mehrere Sicherungen auf einem Host liest bkp_agent beim Start /etc/bkp/bkp_agent.cfg (Windows: %ProgramData%\AegisGrid\bkp_agent.cfg, überschreibbar mit --config-path). packaging/bkp_agent.cfg.example nach /etc/bkp/bkp_agent.cfg kopieren und anpassen:

/etc/bkp/bkp_agent.cfg

[targets]
srv1:backup.example.org:9990:/etc/bkp/target.crt

[data]
source=data.img
target=srv1
target-dir=vm1
api-key=file:/etc/bkp/vm1.key

Danach genügt bkp_agent --name data. Jeder zusätzlich auf der Kommandozeile angegebene Parameter überschreibt den gleichnamigen aus der Konfiguration; bkp_agent --help listet alle dafür nutzbaren key=value-Namen. api-key= akzeptiert drei Formen: den Schlüssel direkt als Klartext, file:<pfad> (wie hier, äquivalent zu --api-key file:<pfad> auf der Kommandozeile) und das reservierte, noch nicht implementierte kms:<url>. Nur in der Konfigurationsdatei ist Klartext erlaubt -- dort landet er nie auf der Kommandozeile oder in der beim ausfallsicheren Fortsetzen gespeicherten Job-Beschreibung (siehe unten); auf der Kommandozeile verlangt --api-key immer file:/kms:, da argv über /proc/ps einsehbar ist.

Kommentare: # oder ; am Zeilenanfang oder nach einem Leerzeichen/Tab leitet einen Kommentar bis zum Zeilenende ein, z. B. timeout-seconds=259200 # 3 Tage. Das gilt für alle .cfg-Dateien (Agent, bkp_xenV, bkp_proxmox, bkp_sched, Updater, Setup-Antwortdatei, ACL). Beginnt ein Wert mit " oder ', reicht er bis zum passenden schließenden Anführungszeichen; die Anführungszeichen werden entfernt, # und ; darin gehören zum Wert, z. B. smtp-password='geheim #1' # Kommentar. In "..." stehen \" und \\ für " und \, '...' gilt wörtlich. Nach dem schließenden Anführungszeichen darf nur noch ein Kommentar folgen. Anführungszeichen mitten im Wert sind normale Zeichen (args=--x "a b" reicht sie an das Programm weiter).

4.5 Mehrere Ziele: Sinks#

Ein Sink ist ein Store, in den ein Lauf schreibt. --out und --target erzeugen unverschlüsselte Sinks direkt auf der Kommandozeile. Alles Weitere (Verschlüsselung, mehrere Server, eigener Store-Name je Ziel, optionale Ziele) steht in benannten Abschnitten [sink:<name>], die ein Profil mit sinks= auswählt (auf der Kommandozeile --sink <name>):

/etc/bkp/bkp_agent.cfg (Sink-Abschnitte dürfen auch in /etc/bkp/sinks.cfg stehen)

[targets]
rz1:backup.example.org:9990:/etc/bkp/rz1-ca.pem

[sink:lokal]
type=out                       # out | target (Pflicht)
path=/srv/local-copy           # out: der Store liegt unter <path>/<store>.cbs
encryption=aes-256-gcm         # none (Standard) | aes-256-gcm | chacha20-poly1305
key=file:/etc/bkp/local.key    # Pflicht genau dann, wenn verschlüsselt
retention=7d                   # überschreibt --retention des Jobs
required=no                    # yes (Standard) | no: ein Ausfall macht den Lauf nur „teilweise“ (Exit 3)

[sink:rz1]
type=target
target=rz1                     # Eintrag aus [targets]
target-dir=kunde-mueller
api-key=file:/etc/bkp/rz1.key
encryption=chacha20-poly1305
key=file:/etc/bkp/rz1-daten.key

[srv01]
source=/dev/vg0/root
sinks=lokal,rz1                # Reihenfolge = späterer Restore-Vorzug

[targets] und die [sink:…]-Abschnitte dürfen auch in einer eigenen Datei sinks.cfg neben bkp_agent.cfg stehen (Linux /etc/bkp/sinks.cfg, Windows C:\ProgramData\AegisGrid\sinks.cfg); andere Abschnitte gehören nicht hinein. bkp_agent liest beide zusammen. Diese Datei pflegt auch die Verwaltungskonsole („Ziele (Sinks)“, Kapitel 14): Was sie anlegt, landet dort, Schlüssel als Dateien unter keys/, hochgeladene CA-Zertifikate unter ca/.

  • Die Quelle wird einmal gelesen und gechunkt; jeder Sink bekommt seinen eigenen, vollständigen Run. Die Runs eines Laufs tragen dieselbe run_group (Zwillinge). Jeder Store meldet selbst, welche Chunks ihm fehlen; komprimiert wird einmal, verschlüsselt je Schlüssel.
  • Höchstens 8 Sinks. Alle Stores eines Laufs müssen gleich chunken (gleiche Chunk-Größe); ein neu hinzukommender Store übernimmt sie.
  • Ausfall eines Sinks (Verbindung länger weg als --net-retry, Datenträger voll, Schlüssel abgewiesen): Er wird abgehängt, die anderen schließen ihren Run ab. Exit-Code 0 alle Sinks ok, 3 teilweise (ein Sink mit required=no fehlgeschlagen; bkp_sched zeigt PARTIAL), 1 ein Sink mit required=yes fehlgeschlagen. Der nächste Lauf füllt den fehlenden Sink automatisch auf.
  • Gibt die Kommandozeile --out, --target oder --sink an, ersetzt sie die Sinks des Profils als Ganzes.
  • Der Restore liest aus den Sinks des Profils (Kapitel 7): aus dem ersten, der die Sicherung hat, und holt Fehlendes aus den Zwillingen.

4.6 Firewall und Netzwerk#

  • Der Server braucht eingehend nur einen TCP-Port (Standard 9990); die Clients brauchen nur ausgehenden Zugriff auf diesen Port.
  • Beispiel mit ufw: ufw allow from 192.0.2.0/24 to any port 9990 proto tcp.
  • Mit --bind <adresse> lauscht der Server nur auf einer Schnittstelle, zum Beispiel im Verwaltungsnetz.

4.7 Ausfallsichere Netzwerk-Sicherung#

Fällt während einer Netzwerk-Sicherung der Server, das Netz oder der Arbeitsplatz aus (Stromausfall, Herunterfahren, Absturz), geht die bisherige Arbeit nicht verloren. Das ergibt sich aus dem Store: Was einmal sicher im Store liegt, muss kein späterer Lauf noch einmal senden. Ein Run entsteht erst beim Abschluss; ein abgebrochener Lauf hinterlässt also nie eine halbe Sicherung. Das ist immer aktiv, kein Parameter nötig zum Einschalten.

4.7.1 Server-Absturz oder Netzausfall im laufenden Lauf#

Der Agent lässt sich seine Daten regelmäßig vom Server bestätigen (spätestens alle 60 s oder nach 256 MiB) und hält bis dahin alles Unbestätigte im Speicher. Bricht die Verbindung ab, verbindet er sich automatisch neu (--net-retry <Minuten>, Standard 30, 0 = sofort aufgeben), fragt nach, was der Server noch hat, sendet den Rest erneut und macht weiter. Der Lauf bleibt derselbe, auch für das Target: Es zählt ihn als eine Sicherung, selbst wenn es dazwischen neu gestartet ist (Kapitel Target-Scheduler, „Ereignisse und Ketten“), und die Target-Konsole zeigt die Sitzung als „Fortgesetzt“ ab dem Beginn der Sicherung.

4.7.2 Absturz oder Neustart des Arbeitsplatzes#

Der Agent merkt sich einen laufenden Auftrag in einer Zustandsdatei (--resume-dir, Standard /var/lib/bkp_agent/resume bzw. unter Windows %ProgramData%\AegisGrid\resume; auch über die Umgebungsvariable BKP_AGENT_RESUME_DIR). Liegt die Zustandsdatei in einem eigenen Verzeichnis, hinterlegt der Agent im Standardverzeichnis einen Verweis darauf (elsewhere/<hash>.dir); so finden --resume-pending und das tägliche Aufräumen auch diese Aufträge. Der Verweis verschwindet, sobald sein Verzeichnis keinen abgebrochenen Auftrag mehr enthält. Der nächste Lauf desselben Befehls (Cronjob, Scheduler, von Hand oder --resume-pending) ist ein neuer Lauf, sendet aber nur, was der Store noch nicht hat, im Wesentlichen also den Rest:

WertVerhalten
--resume auto (Standard)Der abgebrochene Auftrag wird gemerkt und sein Snapshot aufbewahrt; der nächste Lauf sichert vom selben Snapshot (derselbe Zeitpunkt). Ist der Snapshot weg, nimmt er einen neuen; das Ergebnis ist dann die Quelle zum neuen Zeitpunkt.
--resume offKein Merken, kein aufbewahrter Snapshot. Was schon im Store angekommen ist, nutzt der nächste Lauf trotzdem.

--resume-max-age <Stunden> (Standard 24) legt fest, wie lange nach ihrer letzten Aktivität (also ab dem Abbruch, nicht ab dem Start) eine angefangene Sicherung noch fortgesetzt wird. Die früheren Modi verify und trust gibt es nicht mehr: ein neuer Lauf ist immer vollständig und konsistent, und der Store sorgt dafür, dass nichts doppelt übertragen wird.

4.7.3 Wiederanlauf ohne eigenen Daemon#

bkp_agent --resume-pending [--resume-dir <dir>] [--resume-max-age <stunden>]

startet alle abgebrochenen Aufträge erneut und beendet sich danach. bkp_setup richtet das bei der Installation der Komponente agent beim Systemstart ein: unter Linux die systemd-Unit bkp_agent-resume.service (ohne systemd /etc/cron.d/bkp_agent-resume, beide auch unter packaging/), unter Windows die geplante Aufgabe „AegisGrid resume“ (2 Minuten nach dem Start). --no-resume-service schaltet das bei der Installation ab. Ein zweiter, gleichzeitiger Lauf desselben Auftrags beendet sich sofort mit Exit-Code 75 (wie der Updater), statt zu warten oder die Sicherung zu stören.

Dabei räumt --resume-pending auch auf: Eine abgebrochene Sicherung, die länger untätig ist als ihr eigenes --resume-max-age, würde ohnehin nicht mehr fortgesetzt. Ihre Zustandsdatei und ihr aufbewahrter Snapshot (LVM-Snapshot bzw. persistente Schattenkopie) werden entfernt. So bleibt nichts liegen, wenn ein Auftrag gelöscht oder geändert wurde und nie mehr läuft. Eine Sicherung, die ihr eigenes Limit noch erlaubt, bleibt stehen, auch wenn --resume-pending sie mit einem kürzeren Limit nicht mehr startet; ihr nächster regulärer Lauf setzt sie fort. Aufgeräumt wird beim Systemstart und, wo bkp_sched läuft, zusätzlich einmal am Tag (erstmals eine Stunde nach dem Start des Dienstes) mit bkp_agent --resume-cleanup. Dieser Aufruf entfernt nur und startet nichts neu; was er entfernt, steht im Protokoll von bkp_sched. Von Hand entfernt --discard-interrupted eine abgebrochene Sicherung sofort.

4.7.4 Unterbrechen oder verwerfen#

Ein Absturz, ein Zeitlimit oder SIGTERM unterbricht eine Sicherung: sie wird wie oben beschrieben wieder aufgenommen. Soll sie stattdessen verworfen werden, räumt --discard-interrupted mit sonst denselben Optionen auf: keine Sicherung, die Quelle wird nicht gelesen; gelöscht werden der aufbewahrte Snapshot bzw. die Schattenkopien und die Zustandsdatei. Was der Lauf schon gespeichert hatte, bleibt bis zum nächsten prune im Store. Exit 0 (auch wenn nichts zu verwerfen ist), 75 solange die Sicherung noch läuft. bkp_proxmox und bkp_xenV kennen dieselbe Option (entfernt die zurückgelassenen Snapshots, bei bkp_proxmox auch ZFS-, RBD- und qcow2-Snapshots). Wurde eine VM-Sicherung hart beendet (etwa kill -9 oder Stromausfall), entfernt der nächste Lauf von bkp_proxmox die zurückgelassenen Snapshots selbst, wenn keine andere Sicherung der VM mehr läuft und kein angehaltener Lauf sie noch braucht; das Protokoll vermerkt es als Warnung.

Laufenden Job endgültig beenden, danach --discard-interrupted

bkp_sched stop <job> [--no-wait]

Der Stopp geht zuerst über den Laufkanal des Jobs (Kapitel 13): bkp_agent, bkp_restore, bkp_m365 und die VM-Programme beenden den Lauf dann selbst, meist nach wenigen Sekunden. Steckt der Lauf nach 60 Sekunden noch fest (etwa in einem Snapshot oder Hook) oder folgt das Programm dem Kanal nicht, bekommt er SIGTERM bzw. unter Windows Strg+Unterbrechen.

bkp_sched stop erreicht den Job, egal ob ihn der Daemon, bkp_sched run oder bkp_sched start ausführt, und ruft danach automatisch --discard-interrupted auf; dessen Ausgabe steht im Job-Protokoll. Der Lauf gilt als FAILED, das Protokoll endet mit cancelled: 1 und wer abgebrochen hat. stop wartet, bis alles erledigt ist (--no-wait: kehrt sofort zurück). Der API-Abbruch (POST /jobs/{name}/cancel) wirkt genauso. Für den Scheduler von bkp_target gibt es bkp_target --sched-stop <job>: der Lauf kommt nicht wieder in die Warteschlange.

4.7.5 Pausieren und drosseln: bkp_sched pause, resume, throttle#

Ein laufender Job lässt sich von der Befehlszeile aus pausieren, egal ob ihn der Dienst, bkp_sched run oder start ausführt: das Programm hört sofort auf zu lesen und zu senden und wartet; Verbindungen und Snapshot bleiben erhalten. Die Pausenzeit zählt nicht zum Zeitlimit des Jobs.

Laufende Jobs pausieren, fortsetzen und drosseln

bkp_sched pause <job>... | --all [--for 30m|4h|2d] [--reason "<text>"]
bkp_sched resume <job>... | --all
bkp_sched throttle <job>... | --all [--bw 20M|500K|1G|off] [--background on|off|default]
  • --for pausiert für die angegebene Zeit (höchstens hold-max); danach geht der Lauf von selbst weiter.
  • Ohne --for bleibt der Job pausiert, bis resume ihn fortsetzt. Eine Sicherung (agent, proxmox, xenv, hyperv), die länger als pause-max pausiert (Standard 4h, 10m bis 7d, Abschnitt [sched]), wird dann angehalten (siehe unten) und gibt Snapshot und Target-Sitzung frei; andere Jobs laufen nach pause-max weiter.
  • --reason hält einen Grund fest (eine Zeile, höchstens 200 Zeichen). Wird ein pausierter Job erneut pausiert, gelten die neue Zeit und der neue Grund.
  • resume setzt pausierte Jobs sofort fort, egal wer pausiert hat (Befehlszeile, API, Fortschrittsfenster oder Zeitfenster; dann läuft der Job außerhalb seines Fensters weiter, was protokolliert wird). Angehaltene Jobs (HELD) setzt resume sofort im Hintergrund fort, wie start.
  • throttle begrenzt die Bandbreite eines laufenden Jobs (--bw, Bytes pro Sekunde, binäre Einheiten; off hebt die Grenze auf) oder schaltet den Hintergrundmodus um, der Prozessor und Platte anderen Programmen überlässt (default: wie beim Start). Der nächste Lauf startet wieder wie konfiguriert.
  • --all wirkt auf alle laufenden (bei resume: alle pausierten oder angehaltenen) Jobs; Jobs, deren Programm das nicht kann, werden genannt.

bkp_sched list zeigt das an: in der Spalte STATUS etwa RUNNING 42 % (paused), darunter paused since … mit Urheber und Grund sowie limited to …; die Zusammenfassung nennt Jobs, die länger als eine Stunde pausiert sind. Exit-Code 0, wenn alles erledigt ist, 1, wenn ein Job nicht läuft, nicht pausieren kann, weder pausiert noch angehalten ist oder nicht binnen 35 Sekunden antwortet, 2 bei falschem Aufruf.

4.7.6 Anhalten statt beenden: bkp_sched hold#

Muss ein Rechner oder die Leitung kurz frei sein (Wartung, Umzug, Videokonferenz), wird eine laufende Sicherung besser angehalten als beendet: der Lauf hört sauber auf, behält seinen Snapshot und setzt später fort, ohne Fehlermail und ohne die Arbeit zu verlieren.

Laufende Sicherungen anhalten bzw. sofort fortsetzen

bkp_sched hold <job>... | --all [--for 30m|4h|2d|1w | --until "2026-11-03 08:00"] [--reason "<text>"] [--no-wait]
bkp_sched resume <job>... | --all
  • Mit Zeitangabe (--for oder --until, Ortszeit) setzt der Planer den Lauf zur angegebenen Zeit fort, im Zeitfenster des Jobs; Termine dazwischen werden ausgelassen.
  • Ohne Zeitangabe setzt der nächste reguläre Lauf fort.
  • --all hält alle laufenden Sicherungen an. Anhalten lassen sich agent-, proxmox-, xenv- und hyperv-Jobs; andere laufende Jobs (etwa Restore oder M365) nennt --all, lässt sie aber weiterlaufen.
  • --reason hält einen Grund fest (eine Zeile, höchstens 200 Zeichen); er erscheint in bkp_sched list, in den Konsolen und im Job-Protokoll.
  • Ist ein Job schon angehalten, bekommt er mit hold die neue Zeit und den neuen Grund; hold ohne Zeitangabe überlässt die Fortsetzung dem nächsten regulären Lauf.
  • bkp_sched resume setzt einen angehaltenen Job sofort im Hintergrund fort; bkp_sched run oder start setzt ebenfalls sofort fort.
  • Ein Halt dauert höchstens hold-max (Standard 7d, höchstens 30d, im Abschnitt [sched] von bkp_sched.cfg); danach setzt der Planer fort.
  • Folgejobs mit after= warten: angehalten ist nicht fertig.

hold wartet, bis die Programme den Lauf beendet haben (--no-wait: kehrt sofort zurück). Ein Programm, das nach 120 Sekunden noch läuft, wird hart beendet; der Lauf wird trotzdem später fortgesetzt. Exit-Code 0, wenn alles angehalten ist, 1 bei einem Fehler, 2 bei falschem Aufruf. Wird ein mit bkp_sched run gestarteter Job angehalten, endet run mit Exit-Code 78.

Die Fortsetzung ist ein neuer Lauf, der dort weitermacht, wo der angehaltene aufgehört hat. Eine Disk- oder Volume-Sicherung verwendet denselben Snapshot und liest nur die Teile, die noch fehlen; den freien Platz der Dateisysteme, den der angehaltene Lauf gefunden hat, übernimmt sie, statt die Belegungstabelle erneut zu lesen (das spart bei großen Volumes Minuten). Eine VM-Sicherung mit proxmox oder xenv behält ihre Snapshots und sichert nur die offenen Disks und den Rest der angefangenen. Eine Datei-Sicherung liest aus ihren behaltenen Snapshots, übernimmt jede schon erledigte Datei ungelesen und liest eine angefangene große Datei ab der Stelle weiter, an der sie stehen blieb; alle Dateien stammen so aus demselben Zeitpunkt. Ist der Snapshot nicht mehr da, nimmt sie einen neuen, übernimmt nur Dateien, die sich seit dem Halt nicht geändert haben (Größe, Zeiten, Inode), und liest eine angefangene Datei von vorn. Wurden Pfade oder Ausschlüsse inzwischen geändert, vergleicht sie wie üblich mit der letzten Sicherung. Das Protokoll nennt, was übernommen wurde. bkp_agent meldet einen Halt mit Exit-Code 78 und den Zeilen held_until= und hold_kind=; --resume-pending überspringt angehaltene Sicherungen, deren Zeit noch nicht gekommen ist.

Automatisch angehalten wird ein Lauf, wenn sein Zeitfenster mit window-end=hold endet, wenn sein Zeitlimit abläuft, wenn der Dienst bkp_sched beendet wird und wenn das Target neu startet oder der Target-Administrator anhält (Kapitel 15). Ist ein Job länger als remind-held-days Tage angehalten (Abschnitt [mail], Standard 3), erinnert eine Mail daran, danach wöchentlich.

Hinweis: Pausieren, anhalten, ausschalten, beenden: Pausieren (bkp_sched pause, Strg+P) unterbricht einen Lauf, der Prozess bleibt aktiv und der Snapshot belegt weiter Platz. Anhalten beendet den Prozess und setzt später fort. bkp_sched deactivate schaltet einen Job für künftige Termine aus, ohne einen Lauf anzuhalten. bkp_sched stop beendet einen Lauf endgültig und verwirft ihn.

Achtung: Ein langer Halt hält den Snapshot fest: ein LVM-Snapshot füllt sich mit jeder Änderung des Volumes. Bei langen Halten genug Platz in der Volume Group vorsehen. Was der angehaltene Lauf schon gespeichert hat, schützt eine Markierung im Store bis zum Ende des Halts vor prune und Speicherbereinigung; ein Target vor Version 2.0.0-alpha.052 kennt diesen Schutz nicht, dann liest die Fortsetzung alles erneut.

4.7.7 Snapshots über den Neustart hinweg#

  • LVM: Der Snapshot bleibt bei einem Abbruch oder SIGTERM bestehen (getaggt mit dem Auftrag), solange die Sicherung fortgesetzt werden kann, und wird beim nächsten Lauf desselben Auftrags wiederverwendet: derselbe Zeitpunkt. Fertige Sicherungen, --resume off und Aufträge ohne Zustandsdatei räumen den Snapshot sofort auf.
  • Windows: --vss-persistent auto|off (Standard auto) versucht bei einer fortsetzbaren Netzwerk-Sicherung eine persistente Schattenkopie (überlebt einen Neustart); scheitert das, fällt es automatisch auf die normale, nicht-persistente Kopie zurück (dann sichert der nächste Lauf vom neuen Zeitpunkt).

Hinweis: Prune während einer Unterbrechung: Hat ein prune in der Zwischenzeit Daten entfernt, die der Server dem Agent vorher als vorhanden gemeldet hatte, merkt der Agent das beim Wiederverbinden und bricht ab, statt eine unvollständige Sicherung zu schreiben; der nächste Lauf sendet dann neu. --gc-min-age (Standard 24 h) hält frisch geschriebene Daten ohnehin vom Löschen fern.

Tests: scripts/resume_test.sh (Serverabsturz mitten im Lauf), scripts/resume_agent_test.sh (Agent-Absturz, --resume off, --resume-pending, --discard-interrupted), scripts/lvm_resume_test.sh (LVM-Snapshot übersteht Absturz), scripts/resume_agent_test_wine.sh (Windows-Agent unter Wine), scripts/resume_test.ps1 (echtes Windows, persistente Schattenkopie).