Pourquoi la mise hors tension de ma machine après un mauvais "rm" a-t-elle enregistré mes fichiers?

31

Situation classique: j'ai rmmal tourné et j'ai réalisé immédiatement après que j'avais supprimé les mauvais fichiers. (Rien de critique et j'avais des sauvegardes assez récentes, mais toujours ennuyeuses.)

Sachant que l'activité du disque était mon ennemi si je voulais récupérer les fichiers avec extundeleteou de tels outils, j'ai immédiatement mis la machine hors tension physiquement (c'est-à-dire avec le bouton d'alimentation, pas avec haltou une telle commande). C'était un ordinateur portable sans tâches importantes en cours d'exécution ou quoi que ce soit ouvert, donc c'était une opération acceptable. (Au fait, j'ai appris depuis lors que la première chose à faire dans une telle situation serait d'estimer d'abord si les fichiers manquants peuvent toujours être ouverts par un processus https://unix.stackexchange.com/a/101247 - s'ils le sont, vous devez les récupérer de cette façon plutôt que d'éteindre la machine.)

Pourtant, une fois que la machine a été mise hors tension, j'ai réfléchi un moment et j'ai décidé que les fichiers ne valaient pas l'investissement en temps de démarrage d'un système live pour une criminalistique appropriée. J'ai donc rallumé la machine. Et puis j'ai découvert que mes fichiers se trouvaient toujours sur le disque: ils rmn'avaient pas été propagés sur le disque avant la mise hors tension. J'ai fait une petite danse et j'ai remercié le dieu des administrateurs système pour son pardon inattendu.

Ma question est maintenant de comprendre comment cela a été possible et quel est le délai typique avant qu’un rmne se propage réellement sur le disque. Je sais que le disque IO n'est pas vidé immédiatement mais qu'il reste en mémoire pendant un certain temps, mais je pensais que le journal du disque garantirait rapidement que les opérations en attente ne soient pas entièrement perdues. https://unix.stackexchange.com/a/78766 semble faire allusion à un mécanisme distinct pour vider les pages sales et pour vider les opérations de journal, mais ne donne pas suffisamment de détails sur la façon dont le journal serait impliqué pour un rmet le délai prévu avant les opérations sont vidées.

Quelques détails supplémentaires: les données étaient dans une partition ext4 à l'intérieur d'un volume LUKS, et lors du démarrage de la sauvegarde de la machine, j'ai vu ce qui suit dans syslog:

Sep 24 10:24:58 gamma kernel: [   11.457007] EXT4-fs (dm-0): 1 orphan inode deleted
Sep 24 10:24:58 gamma kernel: [   11.458393] EXT4-fs (dm-0): recovery complete
Sep 24 10:24:58 gamma kernel: [   11.482475] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)

mais je ne suis pas sûr que ce soit lié à la rm.

Une autre question serait de savoir s'il existe un moyen de dire au noyau de n'effectuer aucune des opérations de disque en attente (mais plutôt, disons, de les vider quelque part), plutôt que de mettre la machine hors tension. (Bien sûr, il semble dangereux de ne pas effectuer les opérations en attente, mais c'est ce qui se passerait quand vous éteignez la machine de toute façon, et dans certains cas, cela pourrait vous sauver.) Ce serait "plus propre", bien sûr, et aussi intéressant par exemple des serveurs distants où la mise hors tension physique n'est pas une option facile.

a3nm
la source

Réponses:

22

Il semble que vous ayez une bonne compréhension de ce qui s'est passé.

Oui, car vous avez mis hors tension le système avant que vos modifications ne soient enregistrées sur le disque, elles étaient là lorsque vous avez démarré la sauvegarde.

Le système met en cache toutes les écritures avant de les vider sur le disque. Il existe plusieurs options qui contrôlent ce comportement, toutes situées dans /proc/sys/vm/dirty_* [ kernel doc ] . Sauf si un vidage est explicitement effectué par une application via fsync() [ man 2 fsync ] , les données sont validées lorsqu'elles sont soit assez anciennes, soit le cache d'écriture est rempli.
La définition de «données» telle qu'utilisée ci-dessus inclut la modification de l'entrée de répertoire pour supprimer le fichier.

Maintenant, en ce qui concerne le journal, c'est l'une des idées fausses les plus courantes sur ce à quoi sert le journal. Le but d'un journal n'est pas de s'assurer que les modifications sont relues ou que les données ne sont pas perdues. Le but d'un journal est d'empêcher la corruption du système de fichiers lui-même, et non des fichiers qu'il contient. Le journal contient simplement des informations sur les modifications apportées, et non (généralement) les données complètes de la modification elle-même. Les détails exacts dépendent du système de fichiers et du mode journal. Pour ext3 / 4, voir l' dataoption de montage dans man 8 mount.


Pour répondre à votre question supplémentaire de savoir s'il existe un moyen d'empêcher les écritures en attente sans redémarrage:

En faisant une lecture rapide du code source du noyau, il semble que vous pouvez utiliser la ucommande magic sysrq ([ wikipedia ], [ kernel doc ]) pour effectuer une opération de remontage d'urgence en lecture seule. Il semble que cela remonte immédiatement tous les volumes en lecture seule sans opération de synchronisation.

Pour l'utiliser, appuyez simplement sur Alt+ SysRq+ u.

Patrick
la source
1
Merci pour cette réponse! Je suis encore un peu confus au sujet du journal: dois-je le considérer comme quelque chose qui ne s'implique que lorsque les modifications sont vidées sur le disque, de sorte que la mise en cache d'écriture est le seul mécanisme pertinent pour estimer le temps de grâce avant l' rmécriture? En d'autres termes, les choses ne sont engagées dans le journal que lorsqu'une écriture est sur le point d'être effectuée? Ou l'image est-elle plus complexe que cela? Quant à alt-sysrq-u, c'est une bonne idée. Avez-vous une référence à donner pour la réclamation "Il semble"? (Cela ne semble pas découler des liens que vous avez donnés.) Merci! :)
a3nm
De plus, magic sysrq a également la limitation que vous ne pouvez toujours pas le faire sur une machine distante.
a3nm
3
@ a3nm Vous pouvez utiliser sysrq sur une machine distante. echo u > /proc/sysrq-trigger(vous devrez peut-être l'activer en premier).
Paulo Almeida du
Le journal ne traite pas du contenu du fichier (par défaut, il peut être modifié entièrement journalisé), uniquement des métadonnées du système de fichiers, mais dans ce cas, il aurait pu supprimer le fichier , car nous avons affaire à la suppression de l'entrée de répertoire. Ainsi, le journal doit s'assurer que le fichier existe (avec son contenu précédent, en supposant qu'il n'y ait eu aucune autre modification) ou qu'il n'existe pas.
Ángel
@ a3nm En ce qui concerne votre commentaire de journal. Le cache d'écriture se situe entre le journal et le disque. Lorsque vous écrivez sur le système de fichiers, le journal est mis à jour, puis le système de fichiers, mais aucun n'est encore validé sur le disque.
Patrick
2

De: https://www.kernel.org/doc/Documentation/filesystems/ext4.txt

commit = nrsec (*) Ext4 peut être invité à synchroniser toutes ses données et métadonnées toutes les 'nrsec' secondes. La valeur par défaut est 5 secondes. Cela signifie que si vous perdez votre puissance, vous perdrez autant que les 5 dernières secondes de travail (votre système de fichiers ne sera cependant pas endommagé, grâce à la journalisation). Cette valeur par défaut (ou toute valeur faible) nuira aux performances, mais elle est bonne pour la sécurité des données. Le mettre à 0 aura le même effet que de le laisser par défaut (5 secondes). La définition de valeurs très élevées améliorera les performances.

Voir également ici comment les vider: Comment vider les tampons et le cache sur un système Linux?

Cité du lien ci-dessus:

REMARQUE: nettoyez la mémoire des choses inutiles (Kernerl 2.6.16 ou plus récent). Assurez-vous toujours d'exécuter la synchronisation en premier pour vider les éléments utiles sur le disque !!!

To free pagecache:

$ echo 1 > /proc/sys/vm/drop_caches

To free dentries and inodes:

$ echo 2 > /proc/sys/vm/drop_caches

To free pagecache, dentries and inodes:

$ echo 3 > /proc/sys/vm/drop_caches
David
la source
Merci pour cette réponse! Cependant, je ne comprends pas ceci: quant à cette "synchronisation" mentionnée dans commit=nrsec, est-ce quelque chose qui aurait lieu après que le noyau a décidé de vider les modifications de la mémoire sur le disque? Ou le réglage commit=1garantit-il que toutes les modifications seront effacées après 1 seconde, quels que soient les paramètres dirty_expire_centisecset dirty_writeback_centisecs?
a3nm le
Le noyau videra (synchronisera) tout cache / tampon sur le disque toutes les 1 seconde pendant commit=1. Pour autant que je le comprends, syncforce tout à se produire indépendamment des paramètres de mémoire virtuelle bien que cela puisse arriver plus tôt.
David
De plus, pour des raisons de performances, (et la longévité du stockage), le paramètre de validation sur une valeur inférieure à la valeur par défaut n'est pas recommandé.
David