no se puede volver a montar el sistema de archivos a solo lectura después de la actualización del paquete

10

En mi sistema Debian, tengo mi /partición separada y montada read-only. Solo /home/, /var/y /tmp/son de escritura. También he creado un Pre-Invokey Post-Invoke apt hook, para que aptpueda volver a montar automáticamente el sistema para escritura, cuando los paquetes estén instalados o actualizados, y volver a montarlo read-onlycuando haya terminado:

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

Toda esta configuración funciona bien con una excepción. A veces, durante el proceso de instalación / actualización, es necesario reiniciar algunos servicios o abrir nuevos archivos durante la ventana corta cuando /se monta my read-write, estos archivos se abren con writepermisos. Una vez completada la instalación / actualización, mi Post-Invokegancho devuelve un error porque no puede /volver a montarse read-only.

¿Hay alguna forma de resolver este problema? Esto es muy molesto, porque en esta situación generalmente debo reiniciar el servidor, lo que no es práctico.

EDITAR

A continuación se muestra un registro de mi última actualización de paquete, que resultó en el error 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

La última línea ( mount: / is busy) es el error que devuelve apt cuando intenta /volver a montar read-only.

ACTUALIZAR:

el comando sugerido por Graemeno muestra ningún archivo:

# lsof / | awk 'NR==1 || $4~/[0-9][uw]/'
COMMAND     PID       USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
Martin Vegter
fuente
¿Está buscando una manera de evitar que se abran los archivos read-write, o de tener que reiniciar el servidor mientras se puede volver a montar ro, o encontrar y cambiar los paquetes de bloqueo? ¿O sería aceptable como solución?
Anthon
Idealmente, me gustaría evitar que los archivos se abran rwen primer lugar. Pero cualquier solución que me permita rovolver a montar sin reiniciar también es buena.
Martin Vegter
¿Detener los servicios ofensivos, volver a montarlos y comenzarlos de nuevo?
frostschutz
@martin ¿ya tiene una visión general de los servicios ofensivos? Me gusta la configuración que presentó y probaré eso en una máquina virtual, pero sería bueno saber que no está ejecutando algo no predeterminado en su sistema que haría que mis experimentos solo sean parcialmente relevantes.
Anthon
@Anthon No sé cuáles son los servicios ofensivos. Pero vea mi EDIT arriba para aclaraciones. Mi servidor también es una VM. Es una instalación mínima con solo unos pocos servicios en ejecución.
Martin Vegter

Respuestas:

2

Supongo que no son solo servicios, es el hecho de que tienes otros sistemas de archivos, como / home y / var, montados dentro del sistema de archivos raíz. Aparte de eso, la mejor solución que podría desenterrar se describe aquí:

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

Busque la sección titulada ¿Cómo instalo / desinstalo paquetes en un sistema de archivos de solo lectura? En pocas palabras, implica volver a montar el sistema de archivos de destino y luego pasar al nuevo montaje, antes de usar el administrador de paquetes.

La sugerencia, descrita en una de las otras respuestas, hace suposiciones sobre lo que sucede cuando el sistema de archivos raíz se vuelve a montar rw para las actualizaciones de paquetes, por lo que esta solución puede no funcionar realmente Debian, si Debian exhibe un comportamiento diferente de lo que se supone. Pero bueno, creo que vale la pena intentarlo ...

Rouben Tchakhmakhtchian
fuente
1

Para acercarnos a una respuesta definitiva para esto, necesitamos ver qué archivos están causando el mount: / is busyerror. Podrías hacer esto con:

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

Vea mi respuesta a la otra pregunta del OP - lsof: mostrar archivos abiertos como lectura-escritura - para las advertencias de esto. Puede ser que necesite poner esto en un guión separado y luego poner el guión en el gancho apto para ver algo.

Mi sospecha es que los archivos debajo /etcpermanecen abiertos una vez que se inician los servicios. Algunos programas / demonios actualizan su configuración dinámicamente. NetworkManagery cupsdson dos ejemplos. Las actualizaciones a las cupsque se cupsddebe buscar nuevas impresoras (en lugar de una dpkgsecuencia de comandos de configuración) pueden ser la causa del problema. Le recomiendo que ponga /etcun sistema de archivos grabable, incluso si no es la fuente de su problema.

Otra posibilidad es que el búfer del sistema de archivos todavía esté en proceso de ser vaciado al disco cuando intente hacer el montaje. No estoy seguro de cuál es el comportamiento mountaquí, ya sea para bloquear hasta que IO esté completo o para fallar e informar que el disco está ocupado. El primero parece más probable, pero no veo syncllamadas en la salida de strace(aunque posiblemente la mountllamada al sistema haga esto). De todos modos, puede funcionar hacer un syncantes del montaje si lo lsofanterior no muestra nada, por ejemplo:

DPkg::Post-Invoke { "sync; mount -o remount /"; };
Graeme
fuente
esto es extraño. Su lsofcomando no muestra ningún archivo
Martin Vegter
1
Interesante, otra cosa es que los archivos mapeados en memoria pueden ser copiados en escritura. No sé cómo afecta esto al montaje, además, no estoy seguro lsofe incluso lo muestro. ¿Intentaste correr lsofcon tu gancho? ¿Qué tal las synccosas?
Graeme