Kann nach dem Paket-Upgrade nicht erneut bereitgestellt / wieder schreibgeschützt werden

13

Ich benutze Debian Stretch. Meine Root-Partition ist gemountet read-only. Nur wenn ich Pakete installiere oder aktualisiere, wird sie erneut /bereitgestellt read-write(mithilfe von apt hook) und anschließend erneut bereitgestellt ro.

Manchmal kann ich nach einem Paket-Upgrade nicht /wieder schreibgeschützt einbinden :

mount -o remount,ro /
mount: / is busy

In älteren Debian-Versionen (Wheezy) konnte ich offene Dateien auflisten, mit denen keine Verknüpfung bestand lsof:

 lsof +L1

oder genauer gesagt, Dateien, die /ein erneutes Einhängen in ro verhindern:

{ lsof +L1 ; lsof|sed -n '/SYSV/d; /DEL|(path /p;' ; } | grep -Ev '/(dev|home|tmp|var)'

Unter Debian Stretch werden lsof +L1jedoch keine Dateien aufgelistet.

Ich sehe keine Änderungen +|-Lin man lsofdas würde erklären , warum es funktioniert nicht mehr.

Warum listet lsof + L1 keine offenen Dateien mehr auf, deren Verknüpfung aufgehoben wurde?

Wie kann ich die Dateien auflisten, die verhindern, dass sie erneut schreibgeschützt bereitgestellt werden?

AKTUALISIEREN

Ich habe alle Prozesse gestoppt , die gestoppt werden kann und nur haben initund gettyimmer noch laufen, aber ich kann immer noch nicht remount /zu ro.

Martin Vegter
quelle
Nicht verknüpfte offene Dateien sind nicht das einzige Hindernis. Suchen Sie nach woder uin der FDSpalte der lsofAusgabe oder beispielsweise nach Fin der Ausgabe von fuser -vm /. Ich kann Ihnen jedoch keine vollständige Liste geben. Möglicherweise möchten Sie auch das Needrestart- Paket installieren .
Ferenc Wágner
Dumme Frage, aber führen Sie lsof as aus root?
Kiwy
1
Kiwy - ja, ich führe lsof als root aus.
Martin Vegter
1
sagt nicht fuser -m / , was ist mit root?
Rui F Ribeiro
1
@Marcus Linsner - Ich benutze nicht systemd. Ich benutze init.
Martin Vegter

Antworten:

2

Wie kann ich die Dateien auflisten, die verhindern, dass sie erneut schreibgeschützt bereitgestellt werden?

A) fuserfinden Sie in der psmiscPackung; Dies ist ein Anwendungsfall, in dem ich fuserShines & als nützlicher empfinde lsof.

# fuser -v -m / 2>&1 | grep '[Ff]r.e'

Daraufhin werden alle Prozesse angezeigt, bei denen Dateien zum Lesen (f) und Schreiben (F) geöffnet sind. Die Dateien, die verhindern würden, dass sie wieder in den schreibgeschützten Zustand versetzt werden, sind solche, die zum Schreiben geöffnet werden (F).

Tötet die Prozesse , die ein sind ausführbar ist , laufen mit Root - Verzeichnis - Dateien zum Schreiben geöffnet ., Dh

# for fupid in $(fuser -v -m / 2>&1 | grep Fr.e | awk '{print $2}'); do kill $fupid; done

Das steht über den systemdKommentaren mit einer Einschränkung. Wennsystemd es initdann ist, fuserwird es sehen und es gibt andere Überlegungen. Beim systemdLaufen können Prozesse hinter Ihrem Rücken (neu) gestartet werden, auch wenn sie gerade identifiziert und getötet wurden fuser. systemdist viel weiter fortgeschritten als die traditionelle sysvinit.

B) Das UPDATE in der Beschreibung gibt an, dass das System nur ... initund gettynoch läuft ...

Ich sehe den Kommentar, der besagt, dass das System nicht verwendet systemd, sondern verwendet init. Auf der Strecke systemd ist init . In dem Kommentar wurde nicht ausdrücklich darauf hingewiesen sysvinit, daher gehe ich davon aus, dass das betreffende System möglicherweise die Standardausdehnung systemdfür verwendet init. Oder dass andere Leute, die über diesen Beitrag stolpern und Stretch verwenden systemd, diesen Teil nützlich finden.

Per dem Debian - Wiki ,

Der Systeminitialisierungsprozess wird vom init-Daemon ausgeführt. In Squeeze und früheren Versionen wird dieser Dämon vom sysvinit-Paket bereitgestellt, und es werden keine Alternativen unterstützt. In Wheezy ist der Standard-Init-Daemon immer nochsysvinit , aber eine "Technologie-Vorschau" von systemd ist verfügbar. In Jessie und stretch ist das Standard-Init-Systemsystemd , der Wechsel zu sysvinit wird jedoch unterstützt.

Seit Jessie wird nur systemd vollständig unterstützt. sysvinit wird meistens unterstützt, aber Debian-Pakete sind nicht erforderlich, um sysvinit-Startskripte bereitzustellen. runit ist ebenfalls im Paket enthalten, hat jedoch nicht die gleiche Test- und Unterstützungsstufe wie die anderen erhalten und wird derzeit nicht als PID 1 unterstützt.

Mit systemd Laufen müssen einige zusätzliche Schritte unternommen werden, um das Programm freizugeben, damit es problemlos erneut bereitgestellt werden kann.

Es ist wahrscheinlich system.slice, dass Dateien für systemd-journald.serviceoder geöffnet sind systemd-udevd.service(beide haben Socket-Abhängigkeiten). Oder, wenn NetworkManageres läuft, kann es erneut erscheinen, dhclientwas Leases in / var / ... schreibt (& / var / ist nicht immer sein eigenes Gerät), etc. findet fusermöglicherweise & Sie töten dhclientaberNetworkManager es beginnt gleich wieder nach oben.

Die Moral ist, dass viele Dinge automatisiert sind, die "wollen" (und noch mehr mit "wollen") systemd ).

Um sicherzugehen, wenn es machbar ist, wird das systemdÄquivalent von Laufstufe 1 mit rescue.target(und) abgeglichenrunlevel1.target ist ein symbolischer Link zu rescue.target) .

1) Beginnen Sie, indem Sie das System von isolieren rescue.target

# systemctl isolate rescue.target

Es sollte Sie auffordern, das root-Passwort einzugeben. Folgen Sie den Anweisungen auf dem Bildschirm.

2) Finde in der Rettungshülle heraus, was du willst.

# systemctl show -p Wants /

Normalerweise ist es system.slice; alles aufhalten, was will. z.B

# systemctl stop system.slice

3) An diesem Punkt sollte die Remount nicht berichten mount: / is busyund mount -o remount,ro / soll funktionieren. Wenn nicht, überprüfen Sie erneut mit fuser.

4) FWIW; Ich habe auch mal gesehen, wann ein umountFehler auftritt, wenn / wenn ein anderes Gerät in einem Unterverzeichnis eines anderen Mounts gemountet ist, dh verschachtelte Mounts. Zum Beispiel umount /würde fehlschlagen, wenn / var / oder / boot / auf einem anderen Gerät (und gemountet) ist. Sollte mount -o remount,ro /aber in diesem Fall noch funktionieren.

lsblk kann hilfreich sein, um verschachtelte Reittiere zu visualisieren.

Warum listet lsof + L1 keine offenen Dateien mehr auf, deren Verknüpfung aufgehoben wurde?

Da sie nicht verfügbar sind (Sockets oder die meisten FIFOs und Pipes), sind sie nicht mehr geöffnet (der übergeordnete Prozess hat den Dateideskriptor geschlossen) oder sie haben (immer noch) eine Linkanzahl größer als 1.

man lsof (8) details ...

+ | -L [l]

Diese Option aktiviert ('+') oder deaktiviert ('-') die Auflistung der Dateiverknüpfungszahlen, sofern diese verfügbar sind - z. B. sind sie nicht für Sockets oder die meisten FIFOs und Pipes verfügbar.

Wenn + L ohne folgende Nummer angegeben wird, werden alle Verbindungszählungen aufgelistet. Wenn -L angegeben ist (Standardeinstellung), werden keine Verbindungszählungen aufgelistet.

Wenn auf + L eine Zahl folgt, werden nur Dateien aufgelistet, deren Linkanzahl unter dieser Zahl liegt . (Auf -L darf keine Nummer folgen.) Eine Angabe der Form '' + L1 '' wählt offene Dateien aus, die nicht verknüpft wurden. Eine Spezifikation des Formulars +aL1 <file_system>wählt nicht verknüpfte geöffnete Dateien im angegebenen Dateisystem aus.

Joseph Tingiris
quelle
0

Hast du /procbestiegen?

Anscheinend jemand zu sein, der sich darum kümmert / meiste Zeit nur lesbar gemountet wird, und ich kann mir vorstellen, dass Sie sich auch dafür entschieden haben, procfs nicht zu mounten. Aber procfs wird benötigt lsof, um offene Dateien zu finden.

Von Prozessen geöffnete Dateien werden vom Kernel über symbolische Links in procfs verfügbar gemacht. Die Verzeichnisse/proc/<pid>/fd enthalten für jede geöffnete Datei einen Symlink. Der Name der Symlinks ist die Nummer des Dateideskriptors, und der Pfad, auf den der Symlink verweist, ist der Dateipfad.

Dangling-Symlinks bleiben weiterhin erhalten /procBei geöffneten Dateien, die bereits gelöscht wurden, . Der referenzierte Pfad der Datei wird umbenannt und endet mit "(gelöscht)".

Was lsof +L1macht, unterscheidet sich im Wesentlichen nicht von einem schnellen Einzeiler wie:

stat -c%N /proc/[0-9]*/fd/* | grep deleted

Sie können also einen ähnlichen Einzeiler verwenden, um alle offenen Dateien aufzulisten, die möglicherweise verhindern, dass das Root-Dateisystem erneut bereitgestellt wird (sofern dies funktioniert /proc).

Wenn Sie jedoch /procgemountet haben, sind die einzigen anderen Ursachen, an die ich denken kann, Fehler ... Wie auch immer, zu Ihrer Information, auf meinem aktuellen Debian-Stretch-System. lsof +L1funktioniert wie erwartet.

bash# lsb_release -d
Description:    Debian GNU/Linux 9.5 (stretch)

bash# uname -a
Linux bwp-249-8 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u4 (2018-08-21) x86_64 GNU/Linux

bash# lsof -v
lsof version information:
    revision: 4.89
    [...]
Hkoof
quelle
ja, ich habe /procbestiegen. Ich folge Ihrer Argumentation nicht, warum ich es vielleicht nicht getan habe. Sowieso stat -c%N /proc/[0-9]*/fd/* | grep deletedzeigt mir nichts.
Martin Vegter
0

Ich konnte dieses Problem nur einmal reproduzieren und löste es mountmit der Option -n .

Zitat von man mount :

-n, --no-mtab
      Mount without writing in /etc/mtab.  This is necessary for example when /etc is on a read-only filesystem.

Das mountProgramm selbst, das Dateien zum Schreiben in das Root-Dateisystem öffnete , klang für mich nach einer plausiblen Erklärung. Speziell mountschreibt /etc/mtabimmerhin und/etc oft Teil des Root-Dateisystems. Ich konnte es jedoch nicht mehr auf demselben Computer reproduzieren, nachdem ich es einmal gemacht hatte ...

Könnte dies Ihr Problem lösen?

Hkoof
quelle
Nein, die Verwendung -nmit mount macht keinen Unterschied.
Martin Vegter
0

Ohne Einblick in Ihr System ist es sehr schwierig, das genaue Problem zu ermitteln. Die Kommentare und vorherigen Antworten sind gute Starts.

Das heißt, ich würde den ganzen Weg durch das Debian-Wiki zurückgehen, das die Voraussetzungen für das Mounten / Nur-Lesen beschreibt.

Der Link zur Dokumentation ist hier: https://wiki.debian.org/ReadonlyRoot

Die Große werde ich dir hier zeigen:

1 - Es gibt bestimmte Stellen unter /, die gelesen und geschrieben werden müssen. Basierend auf der Dokumentation sieht es ungefähr so ​​aus:

debian ro root

Ihre Block-Geräte unterscheiden sich wahrscheinlich in Abhängigkeit von Ihrer Storage-Stack-Konfiguration (Partitionen, Partitionless Lvm usw.). Die Hauptidee ist jedoch, dass Sie diese 4 Mount-Punkte benötigen, um das nachfolgende gemountete Dateisystem für die RW-Mount-Option zu haben.

2 - Es gibt eine Reihe von speziellen Dateien in / etc, für die Sie entweder einen symbolischen Link erstellen oder eine andere Änderung vornehmen müssen (speziell im verlinkten Artikel beschrieben). Diese können auf der Grundlage der auf Ihrem Linux-Server ausgeführten Anwendungen angewendet werden oder nicht. Einige der Dateien sind möglicherweise noch nicht einmal auf Ihrem Computer vorhanden, aber ich habe alles in die Dokumentation aufgenommen. Denken Sie daran, ich empfehle dringend, diese Änderungen vorzunehmen, AUCH WENN Sie die PID des Prozesses getötet haben. Hier sind die Pfade direkt aus dem Debian-Wiki:

  • Adjtime
  • init.d / alsa-utils
  • / etc / courier / shared / index
  • Alle Cups geben die Dateien classes.conf, cupsd.conf und printers.conf subscriptions.conf an
  • /etc/lvm/lvm.conf
  • mtab (wie es aussieht, haben Sie versucht, mit mount das Flag -n zu adressieren)
  • network / run (wird von ifup und ifdown in squeeze verwendet. gilt möglicherweise nicht für stretch, ymmv)
  • Nologin
  • resolv.conf
  • Passwd- und Shadow-Dateien
  • samba / dhcp.conf
  • saugen
  • udev

Nachdem Sie alle oben genannten Punkte überprüft und bestätigt haben, dass sie den Spezifikationen im Wiki entsprechen, müssen Sie als Nächstes /etc/apt/apt.conf überprüfen

DPkg {
// Auto re-mounting of a readonly /
Pre-Invoke { "mount -o remount,rw /"; };
Post-Invoke { "test ${NO_APT_REMOUNT:-no} = yes || mount -o remount,ro / || true"; };
}; 

Anhand Ihres Fehlers können Sie Folgendes abschließend anhand der Dokumentation überprüfen:

"Nach einem Upgrade von Paketen könnten Sie mit dem Problem konfrontiert werden, dass mount die erneute Bereitstellung des Dateisystems verweigert und Ihnen nur mitteilt, dass / ausgelastet ist. Dies wird durch gelöschte Dateien verursacht, die noch von einem Prozess verwendet werden. Um herauszufinden, welche Prozesse verwendet werden, verwenden Sie Deleted Dateien verwenden das Tool checkrestart (1) aus dem Paket debian-goodies oder den folgenden Befehl. Oft sind dies Daemons, die aktualisierte Bibliotheken verwenden. Sie müssen sie neu starten, damit die Dateien freigegeben werden. "

Befehl im Dokument bereitgestellt:

{lsof +L1; lsof|sed -n '/SYSV/d; /DEL\|(path /p;'} |grep -Ev '/(dev|home|tmp|var)'

Ohne Ihre genaue Dateisystemkonfiguration, Partitionierung und Speichergerätekonfiguration zu kennen, ist es schwierig, Ihnen noch viel zu folgen. Ich würde damit beginnen, Ihre Voraussetzungen in der Dokumentation noch einmal zu überprüfen (und oben umrissen).

Frontseitenbus
quelle