地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Linux】linux 削除したファイルを復活させることができるかもしれない話

かもしれない

Linuxファイルシステム上にあるように見えるファイル(lsとか)は、実際はinodeへのリンク。

inodeには、ファイルのあらゆるプロパティ(アクセス権や所有権など)のほか、ファイルの中味が実際に存在するディスク上のデータブロックのアドレスも記録される。

rmコマンドでファイルを削除すると、ファイルのinodeを指すリンクは削除されるが、inodeそのものは削除されない。

削除した時点で、他のプロセス(オーディオ・プレーヤーなど)でファイルがまだ開かれている場合もある。

このようなプロセスがすべて終了し、すべてのリンクが削除されるまで、 inodeとそれに関連付けられたデータブロックが書き込みの対象となることはない。

このように実際のファイルが削除されるまでタイムラグがある。

この特性を生かしてファイルを開いているプロセスを立ち上げて別プロセスからファイルを削除し、その状態からファイルを復活させてみる。

簡単に言うと「/proc/PID/fd/」

open用のプログラム。openしてsleepするだけ。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
  FILE *fp;
  char s[256];

  if ((fp = fopen("smpl.txt", "r")) == NULL) {
    printf("file open error!!\n");
    exit(EXIT_FAILURE);
  }

  sleep(60);

  fclose(fp);
  return 0;
}

事前に削除対象のファイルを作成しておく(空ファイルではなくデータも用意) 用意したら実行しsleepに入ったら別コンソールでファイルを削除

$ gcc open.c
$ echo "test test test test" >> smpl.txt
$ ./a.out

PIDを確認して

# ファイルを削除
$ rm -f smpl.txt

# 先ほどのコンパイルして実行したプロセスのPIDを取得
$ ps aux | grep a.out

# 取得したプロセスが開いているfdのうち該当するfdをreadしてみると内容が見れる
$ cat /proc/149417/fd/3
test test test test

ファイル自体はcloes(2)された時点でプロセスとしてのfdの紐付けはなくなるので復旧は困難となる。