incapaz de remontar o sistema de arquivos de volta para somente leitura após a atualização do pacote

10

No meu sistema Debian, tenho minha /partição separada e montada read-only. Apenas /home/, /var/e /tmp/são graváveis. Também criei um Pre-Invokee Post-Invoke apt hook, para que aptpossa remontar automaticamente o sistema para gravação, quando os pacotes forem instalados ou atualizados e remontá-lo novamente read-onlyquando terminar:

DPkg::Pre-Invoke  {"mount -o remount,rw / ;};
DPkg::Post-Invoke {"mount -o remount    / ;};

Toda essa configuração funciona bem com uma exceção. Às vezes, durante o processo de instalação / atualização, alguns serviços precisam ser reiniciados ou novos arquivos abertos durante a janela curta quando meu /é montado read-write, esses arquivos são abertos com writepermissões. Após a conclusão da instalação / atualização, meu Post-Invokegancho retorna um erro porque não pode /voltar a remontar read-only.

Existe alguma maneira de resolver esse problema? Isso é muito chato, porque nessa situação geralmente devo reiniciar o servidor, o que é impraticável.

EDITAR

Abaixo está um log da minha atualização mais recente do pacote, que resultou no erro descrito:

root@alpha# apt-get upgrade 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
  base-files curl libc-bin libc6 libcurl3 libcurl3-gnutls libmysqlclient18 libssl1.0.0 locales multiarch-support mysql-client mysql-client-5.5 mysql-common
  nscd openssl tzdata wget whois
18 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Need to get 18.7 MB of archives.
After this operation, 264 kB of additional disk space will be used.
Do you want to continue [Y/n]? 
Fetched 18.7 MB in 0s (33.2 MB/s) 
Preconfiguring packages ...
(Reading database ... 20532 files and directories currently installed.)
Preparing to replace base-files 7.1wheezy3 (using .../base-files_7.1wheezy4_amd64.deb) ...
Unpacking replacement base-files ...
Processing triggers for man-db ...
Processing triggers for install-info ...
Setting up base-files (7.1wheezy4) ...
Installing new version of config file /etc/debian_version ...
(Reading database ... 20532 files and directories currently installed.)
Preparing to replace libc-bin 2.13-38 (using .../libc-bin_2.13-38+deb7u1_amd64.deb) ...
Unpacking replacement libc-bin ...
Processing triggers for man-db ...
Setting up libc-bin (2.13-38+deb7u1) ...
(Reading database ... 20532 files and directories currently installed.)
Preparing to replace libc6:amd64 2.13-38 (using .../libc6_2.13-38+deb7u1_amd64.deb) ...
Unpacking replacement libc6:amd64 ...
Setting up libc6:amd64 (2.13-38+deb7u1) ...
(Reading database ... 20532 files and directories currently installed.)
Preparing to replace libssl1.0.0:amd64 1.0.1e-2+deb7u1 (using .../libssl1.0.0_1.0.1e-2+deb7u4_amd64.deb) ...
Unpacking replacement libssl1.0.0:amd64 ...
Preparing to replace curl 7.26.0-1+wheezy7 (using .../curl_7.26.0-1+wheezy8_amd64.deb) ...
Unpacking replacement curl ...
Preparing to replace libcurl3:amd64 7.26.0-1+wheezy7 (using .../libcurl3_7.26.0-1+wheezy8_amd64.deb) ...
Unpacking replacement libcurl3:amd64 ...
Preparing to replace libcurl3-gnutls:amd64 7.26.0-1+wheezy7 (using .../libcurl3-gnutls_7.26.0-1+wheezy8_amd64.deb) ...
Unpacking replacement libcurl3-gnutls:amd64 ...
Preparing to replace mysql-common 5.5.33+dfsg-0+wheezy1 (using .../mysql-common_5.5.35+dfsg-0+wheezy1_all.deb) ...
Unpacking replacement mysql-common ...
Preparing to replace libmysqlclient18:amd64 5.5.33+dfsg-0+wheezy1 (using .../libmysqlclient18_5.5.35+dfsg-0+wheezy1_amd64.deb) ...
Unpacking replacement libmysqlclient18:amd64 ...
Preparing to replace multiarch-support 2.13-38 (using .../multiarch-support_2.13-38+deb7u1_amd64.deb) ...
Unpacking replacement multiarch-support ...
Processing triggers for man-db ...
Setting up multiarch-support (2.13-38+deb7u1) ...
(Reading database ... 20532 files and directories currently installed.)
Preparing to replace tzdata 2013h-0wheezy1 (using .../tzdata_2013i-0wheezy1_all.deb) ...
Unpacking replacement tzdata ...
Setting up tzdata (2013i-0wheezy1) ...

Current default time zone: 'Europe/London'
Local time is now:      Sat Feb 15 11:35:41 CET 2014.
Universal Time is now:  Sat Feb 15 11:35:41 UTC 2014.
Run 'dpkg-reconfigure tzdata' if you wish to change it.

(Reading database ... 20511 files and directories currently installed.)
Preparing to replace wget 1.13.4-3 (using .../wget_1.13.4-3+deb7u1_amd64.deb) ...
Unpacking replacement wget ...
Preparing to replace locales 2.13-38 (using .../locales_2.13-38+deb7u1_all.deb) ...
Unpacking replacement locales ...
Preparing to replace whois 5.0.23 (using .../whois_5.1.1~deb7u1_amd64.deb) ...
Unpacking replacement whois ...
Preparing to replace mysql-client 5.5.33+dfsg-0+wheezy1 (using .../mysql-client_5.5.35+dfsg-0+wheezy1_all.deb) ...
Unpacking replacement mysql-client ...
Preparing to replace mysql-client-5.5 5.5.33+dfsg-0+wheezy1 (using .../mysql-client-5.5_5.5.35+dfsg-0+wheezy1_amd64.deb) ...
Unpacking replacement mysql-client-5.5 ...
Preparing to replace nscd 2.13-38 (using .../nscd_2.13-38+deb7u1_amd64.deb) ...
[ ok ] Stopping Name Service Cache Daemon: nscd.
Unpacking replacement nscd ...
Preparing to replace openssl 1.0.1e-2+deb7u1 (using .../openssl_1.0.1e-2+deb7u4_amd64.deb) ...
Unpacking replacement openssl ...
Processing triggers for install-info ...
Processing triggers for man-db ...
Setting up libssl1.0.0:amd64 (1.0.1e-2+deb7u4) ...
Setting up libcurl3:amd64 (7.26.0-1+wheezy8) ...
Setting up curl (7.26.0-1+wheezy8) ...
Setting up libcurl3-gnutls:amd64 (7.26.0-1+wheezy8) ...
Setting up mysql-common (5.5.35+dfsg-0+wheezy1) ...
Setting up libmysqlclient18:amd64 (5.5.35+dfsg-0+wheezy1) ...
Setting up wget (1.13.4-3+deb7u1) ...
Setting up locales (2.13-38+deb7u1) ...
Generating locales (this might take a while)...
  en_DK.UTF-8... done
  en_US.UTF-8... done
Generation complete.
Setting up whois (5.1.1~deb7u1) ...
Setting up mysql-client-5.5 (5.5.35+dfsg-0+wheezy1) ...
Setting up mysql-client (5.5.35+dfsg-0+wheezy1) ...
Setting up nscd (2.13-38+deb7u1) ...
[ ok ] Starting Name Service Cache Daemon: nscd.
Setting up openssl (1.0.1e-2+deb7u4) ...
mount: / is busy

A última linha ( mount: / is busy) é o erro retornado pelo apt, ao tentar remontar de /volta para read-only.

ATUALIZAR:

o comando sugerido por Graemenão mostra nenhum arquivo:

# lsof / | awk 'NR==1 || $4~/[0-9][uw]/'
COMMAND     PID       USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
Martin Vegter
fonte
Você está procurando uma maneira de impedir que os arquivos sejam abertos read-writeou de ter que reiniciar o servidor enquanto pode remontar roou localizar e alterar os pacotes de bloqueio? Ou seria aceitável como solução?
Anthon
Idealmente, eu gostaria de impedir que os arquivos sejam abertos rwem primeiro lugar. Mas qualquer solução que me permita remontar rosem reiniciar também é boa.
Martin Vegter 15/02
Pare os serviços ofensivos, remonte, inicie-os novamente?
Frostschutz
@martin você já tem uma visão geral dos serviços ofensivos? Gosto da configuração que você apresentou e tentará isso em uma VM, mas seria bom saber que você não está executando algo não padrão no seu sistema que tornaria minhas experiências apenas parcialmente relevantes.
Anthon
@ Anton Não sei quais são os serviços incorretos. Mas veja meu EDIT acima para esclarecimentos. Meu servidor também é uma VM. É uma instalação mínima com apenas alguns serviços em execução.
Martin Vegter 15/02

Respostas:

2

Meu palpite é que não são apenas serviços, é o fato de você ter outros sistemas de arquivos, como / home e / var, montados dentro do sistema de arquivos raiz. Além disso, a melhor solução que eu poderia encontrar está descrita aqui:

https://sites.google.com/site/linuxpendrive/rorootfs

Procure a seção intitulada Como instalar / desinstalar pacotes em um sistema de arquivos somente leitura? Em poucas palavras, envolve remontar o sistema de arquivos de destino e depois fazer o chroot na nova montagem, antes de usar o gerenciador de pacotes.

A sugestão, descrita em uma das outras respostas, faz suposições sobre o que acontece quando o sistema de arquivos raiz é remontado rw para atualizações de pacotes, portanto esta solução pode não funcionar realmente com o Debian, se o Debian exibir um comportamento diferente do que é assumido. Mas ei, vale a pena tentar, eu acho ...

Rouben Tchakhmakhtchian
fonte
1

Para chegar mais perto de uma resposta definitiva, precisamos ver quais arquivos estão causando o mount: / is busyerro. Você poderia fazer isso com:

lsof / | awk 'NR==1 || $4~/[0-9][uw]/'

Veja minha resposta à outra pergunta do OP - lsof: show files open as read-write - para as ressalvas. Pode ser que você precise colocar isso em um script separado e colocá-lo no gancho do apt para ver algo.

Minha suspeita é que os arquivos em /etcpermanecem abertos quando os serviços são iniciados. Alguns programas / daemons atualizam sua configuração dinamicamente. NetworkManagere cupsdsão dois exemplos. As atualizações cupsque causam cupsda verificação de novas impressoras (em oposição a um dpkgscript de configuração) podem muito bem estar causando o problema. Eu recomendo que você /etcinstale um sistema de arquivos gravável, mesmo que não seja a fonte do seu problema.

Outra possibilidade é que o buffer do sistema de arquivos ainda esteja sendo liberado para o disco quando você tenta fazer a remontagem. Não sei ao certo qual é o comportamento mountaqui, seja para bloquear até a conclusão do IO ou para falhar e relatar o disco como ocupado. O primeiro parece mais provável, mas não vejo syncchamadas na saída de strace(embora possivelmente a mountchamada do sistema faça isso). De qualquer forma, pode funcionar para fazer um syncantes da remontagem se o lsofacima não mostrar nada, por exemplo:

DPkg::Post-Invoke { "sync; mount -o remount /"; };
Graeme
fonte
isto é estranho. Seu lsofcomando não lista nenhum arquivo
Martin Vegter
1
Interessante, outra coisa é que os arquivos mapeados na memória podem ser copiados na gravação. Não sei como isso afeta a montagem, mais não tenho certeza lsofe até mostro isso. Você tentou correr lsofcom seu gancho? E as synccoisas?
Graeme