Nie można ponownie zamontować / wrócić do wersji tylko do odczytu po aktualizacji pakietu

13

Używam Debian Stretch. Moja partycja root jest zamontowana read-only. Tylko wtedy, gdy instaluję lub aktualizuję pakiety, jest /ponownie instalowany read-write(za pomocą apt hook), a następnie ponownie instalowany ro.

Czasami po uaktualnieniu pakietu nie mogę ponownie podłączyć /się do wersji tylko do odczytu

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

W starszych wersjach Debiana (Wheezy) mogłem wyświetlić listę otwartych plików, które zostały odłączone za pomocą lsof:

 lsof +L1

lub dokładniej, pliki, które uniemożliwiają /ponowne podłączenie z powrotem do ro:

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

Jednak w Debian Stretch lsof +L1nie wyświetla żadnych plików.

Nie widzę żadnych zmian +|-Lw man lsofktóre mogłyby wyjaśnić, dlaczego przestał działać.

Dlaczego lsof + L1 nie wyświetla już listy otwartych plików, które zostały rozłączone?

Jak mogę wyświetlić listę plików, które uniemożliwiają / nie są ponownie montowane w trybie tylko do odczytu?

AKTUALIZACJA

Mam zatrzymał wszystkie procesy, które mogą być zatrzymane, a tylko initi gettynadal działa, ale nadal nie mogę Remount /do ro.

Martin Vegter
źródło
Niepowiązane otwarte pliki nie są jedyną przeszkodą. Poszukaj wlub uw FDkolumnie lsofwyników lub na przykład Fw danych wyjściowych fuser -vm /. Nie mogę ci jednak podać wyczerpującej listy. Możesz także zainstalować pakiet needrestart .
Ferenc Wágner
głupie pytanie, ale czy wykonujesz lsof as root?
Kiwy
1
Kiwy - tak, wykonuję lsof jako root.
Martin Vegter,
1
nie fuser -m / mówi, co używa root?
Rui F Ribeiro
1
@Marcus Linsner - Nie używam systemd. Używam init.
Martin Vegter,

Odpowiedzi:

2

Jak mogę wyświetlić listę plików, które uniemożliwiają / nie są ponownie montowane w trybie tylko do odczytu?

A) fusermożna znaleźć w psmiscpaczce; jest to przypadek użycia, w którym uważam, że fuserświeci i jest bardziej przydatny niż lsof.

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

To pokaże wszystkie procesy, w których pliki są otwarte na / do odczytu (f) i pisania (F). Pliki, które uniemożliwią / zostaną ponownie zamontowane tylko do odczytu, to te, które są otwarte do zapisu (F).

Zabij procesy uruchamiane z plikami katalogu głównego otwartymi do zapisu , tj

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

To jest ponad systemdkomentarzami z zastrzeżeniem. Jeśli systemdtak, initto fuserzobaczymy i istnieją inne względy. Po systemduruchomieniu może (ponownie) rozpocząć procesy za twoimi plecami, nawet jeśli zostały właśnie zidentyfikowane i zabite fuser. systemdjest znacznie bardziej zaawansowany niż tradycyjny sysvinit.

B) AKTUALIZACJA w opisie stwierdza, że ​​system ma tylko ... initi gettynadal działa ...

Widzę komentarz, który mówi, że system nie używa systemd, używa init. Na odcinku systemd jest init . Komentarz nie wyraźnie powiedzieć sysvinit, więc jestem przy założeniu, że dany system może być używany domyślny odcinek systemddla init. Lub że inni ludzie, którzy natkną się na ten post, używający odcinków systemd, uważają tę część za przydatną.

Na Wiki Debiana ,

Proces inicjalizacji systemu jest obsługiwany przez demona init. W wersjach squeeze i wcześniejszych ten demon jest dostarczany przez pakiet sysvinit i nie są obsługiwane żadne alternatywy. W wheezy domyślny demon init jest nadalsysvinit , ale dostępny jest „podgląd technologii” systemd. W jessie i stretch domyślnym systemem init jestsystemd , ale obsługiwane jest przełączanie na sysvinit.

Od czasu jessie tylko systemd jest w pełni obsługiwany; sysvinit jest w większości obsługiwany, ale pakiety Debiana nie są wymagane do dostarczania skryptów startowych sysvinit. runit jest również spakowany, ale nie otrzymał tego samego poziomu testowania i wsparcia jak inne, i nie jest obecnie obsługiwany jako PID 1.

Podczas systemduruchamiania jest kilka dodatkowych kroków, które należy podjąć, aby zwolnić /, aby można go było ponownie zamontować bez problemu.

Prawdopodobnie system.sliceprzechowuje otwarte pliki dla ( systemd-journald.servicelub systemd-udevd.serviceoba mają zależności gniazd). Lub, jeśli NetworkManagerjest uruchomiony, może odrodzić się, dhclientco zapisuje dzierżawę do / var / ... (& / var / nie zawsze jest jego własnym urządzeniem), itp. fuserMoże znaleźć i zabijesz, dhclientale NetworkManageruruchomi się od razu.

Morał polega na tym, że wiele rzeczy jest zautomatyzowanych, które mogłyby „chcieć” / (a ​​nawet bardziej systemd).

Dla pewności, jeśli jest to wykonalne, systemdodpowiednik poziomu uruchomienia 1 jest dopasowany przez rescue.target(i runlevel1.targetjest dowiązaniem symbolicznym rescue.target).

1) Zacznij od izolacji systemu rescue.target

# systemctl isolate rescue.target

Powinien zostać wyświetlony monit o podanie hasła roota; postępuj zgodnie z instrukcjami na ekranie.

2) W muszli ratunkowej dowiedz się, czego chce /.

# systemctl show -p Wants /

Zazwyczaj jest system.slice; zatrzymać wszystko, co chce /. na przykład

# systemctl stop system.slice

3) W tym momencie remont nie powinien się zgłaszać mount: / is busyi mount -o remount,ro / powinien działać. Jeśli nie, sprawdź ponownie za pomocą fuser.

4) FWIW; Widziałem także czasy, kiedy umountzawodzi, gdy / jeśli inne urządzenie jest zamontowane w podkatalogu innego montowania, tj. Zagnieżdżonych montowań. Na przykład umount /nie powiedzie się, jeśli / var / lub / boot / znajduje się na innym urządzeniu (i jest zamontowane). Chociaż mount -o remount,ro /powinno nadal działać w tym przypadku.

lsblk może być pomocny w wizualizacji zagnieżdżonych mocowań.

Dlaczego lsof + L1 nie wyświetla już listy otwartych plików, które zostały rozłączone?

Ponieważ nie są one dostępne (gniazda lub większość FIFO i potoków), nie są już otwartymi plikami (proces nadrzędny zamknął deskryptor pliku) lub (nadal) mają liczbę linków większą niż 1.

man lsof (8) szczegóły ...

+ | -L [l]

Ta opcja włącza („+”) lub wyłącza („-”) listę zliczeń linków do plików, tam gdzie są one dostępne - np. Nie są one dostępne dla gniazd lub większości FIFO i potoków.

Gdy podano + L bez następującego numeru, wszystkie liczby linków zostaną wyświetlone. Gdy podano -L (domyślnie), liczba podanych łączy nie będzie wyświetlana.

Gdy po + L następuje liczba, wyświetlane będą tylko pliki z liczbą łączy mniejszą niż ten numer . (Żaden numer nie może występować po -L.) Specyfikacja postaci „+ L1” wybierze otwarte pliki, które zostały rozłączone. Specyfikacja formularza +aL1 <file_system>wybierze niepowiązane otwarte pliki w określonym systemie plików.

Joseph Tingiris
źródło
0

Czy masz /proczamontowane?

Jako osoba, która przez /większość czasu dba o to, aby montować tylko do odczytu, mogę sobie wyobrazić, że możesz zdecydować się nie montować procfs. Ale procfs jest potrzebny lsofdo znalezienia otwartych plików.

Pliki utrzymywane przez procesy są ujawniane przez jądro poprzez dowiązania symboliczne w procfs. Katalogi /proc/<pid>/fdzawierają dowiązanie symboliczne dla każdego otwartego pliku. Nazwa dowiązań symbolicznych to numery deskryptorów plików, a ścieżka wskazywana przez dowiązanie symboliczne to ścieżka do pliku.

Wciąż pozostają wiszące dowiązania symboliczne /procdla otwartych plików, które zostały już usunięte. Nazwa ścieżki, do której następuje odwołanie, zostaje zmieniona na „(usunięte)”.

Co w lsof +L1zasadzie nie różni się od szybkiego jednego linijki, takiego jak:

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

Możesz więc użyć podobnej jednowierszowej, aby wyświetlić listę wszystkich otwartych plików, co może uniemożliwić ponowne zamontowanie głównego systemu plików (pod warunkiem, że działa /proc).

Jednak jeśli już to zrobiłeś / zrobiłeś /proc, jedynymi innymi przyczynami, o których myślę, są błędy ... W każdym razie, FYI, na moim obecnym systemie Debian Stretch. lsof +L1działa zgodnie z oczekiwaniami.

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
źródło
tak, /proczamontowałem. Nie rozumiem twojego rozumowania, dlaczego mógłbym tego nie mieć. W każdym razie stat -c%N /proc/[0-9]*/fd/* | grep deletednic mi nie pokazuje.
Martin Vegter,
0

Mogę odtworzyć ten problem tylko raz, i rozwiązać go tylko przy użyciu mountz -n opcja.

Cytując wierzchowca :

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

Sam mountprogram otwierający pliki do zapisu w systemie plików root brzmiał dla mnie jak wiarygodne wytłumaczenie. W końcu mountpisze, /etc/mtaba /etcczęsto jest częścią głównego systemu plików. Nie mogłem jednak odtworzyć go ponownie na tym samym komputerze po tym, jak to zrobiłem raz ...

Czy to może rozwiązać Twój problem?

Hkoof
źródło
nie, używanie -nz mountem nie robi różnicy.
Martin Vegter,
0

Bez wglądu w Twój system bardzo trudno jest dokładnie powiedzieć, na czym polega problem. Komentarze i poprzednie odpowiedzi to dobry początek.

Powiedziałbym, że wrócę całą drogę przez wiki debian, która opisuje wymagania wstępne do montowania / tylko do odczytu.

Link do dokumentacji znajduje się tutaj: https://wiki.debian.org/ReadonlyRoot

Ten duży poprowadzę cię tutaj:

1 - istnieją określone lokalizacje w obszarze /, które należy przeczytać. Na podstawie dokumentacji wygląda to tak:

root debian ro

Twoje urządzenia blokowe prawdopodobnie będą się różnić, w zależności od konfiguracji stosu pamięci (partycje, bezdzielny lvm itp.), ale główną ideą jest to, że potrzebujesz tych 4 punktów montowania, aby ich później zamontowany system plików miał opcję montowania RW.

2 - w / etc znajduje się wiele specjalnych plików, które musisz utworzyć symboliczne łącze lub wdrożyć jakąś inną zmianę (szczegółowo opisaną w linkowanym artykule). Mogą one, ale nie muszą mieć zastosowania, w zależności od aplikacji, na których działa Twój serwer Linux. niektóre pliki mogą nawet nie istnieć na twoim komputerze, ale załączyłem wszystko do dokumentacji. Pamiętaj, zdecydowanie zalecam wprowadzanie tych zmian NAWET JEŚLI zabiłeś pid procesu. Oto ścieżki bezpośrednio z wiki debian:

  • przerwa
  • init.d / alsa-utils
  • / etc / courier / shared / index
  • dowolne pliki stanu pucharów, klas.conf, cupsd.conf, printers.conf subscriptions.conf
  • /etc/lvm/lvm.conf
  • mtab (wygląda na to, że próbowałeś rozwiązać, podając mount -n flagę)
  • sieć / uruchomienie (używane przez ifup i ifdown, w squeeze. może nie dotyczyć stretch, ymmv)
  • nologin
  • resolv.conf
  • pliki passwd i shadow
  • samba / dhcp.conf
  • ssać
  • udev

Po sprawdzeniu wszystkich powyższych i potwierdzeniu, że są zgodne ze specyfikacją na wiki, następną rzeczą do sprawdzenia jest /etc/apt/apt.conf

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"; };
}; 

na podstawie Twojego błędu ostatnia rzecz, którą możesz sprawdzić na podstawie dokumentacji, pochodzi z poniższego:

„Po aktualizacji pakietów może pojawić się problem polegający na tym, że mount odmawia ponownego zamontowania systemu plików, mówiąc tylko„ / jest zajęty ”. Jest to spowodowane usuniętymi plikami, które są nadal używane przez proces. Aby dowiedzieć się, które procesy wykorzystują usunięte pliki, użyj narzędzia checkrestart (1) z pakietu debian-goodies lub użyj następującego polecenia. Często są to demony korzystające z ulepszonych bibliotek. trzeba je ponownie uruchomić, aby pliki zostały zwolnione. ”

polecenie dostarczone w dokumencie:

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

Nie znając dokładnej konfiguracji systemu plików, podziału na partycje i konfiguracji urządzenia pamięci masowej, trudno dać ci wiele innych do naśladowania. Zacznę od powrotu i ponownego sprawdzenia twoich wymagań wstępnych w dokumentacji (i opisanych powyżej).

przód autobusu
źródło