Ricolbind un file anonimo (scollegato ma aperto)

In Unix, è ansible creare un handle per un file anonimo, ad esempio, creando e aprendolo con creat () e quindi rimuovendo il collegamento alla directory con unlink () – lasciandoti un file con inode e storage ma nessun modo ansible per riaprirlo. Tali file sono spesso usati come file temporanei (e in genere questo è ciò che tmpfile () restituisce).

La mia domanda: c’è un modo per ricolbind un file come questo nella struttura delle directory? Se si potesse fare ciò, si potrebbe ad esempio implementare le scritture di file in modo che il file appaia atomicamente e pienamente formato. Questo fa appello alla mia pulizia compulsiva. 😉

Quando mi sono imbattuto nelle funzioni di chiamata di sistema rilevanti, mi aspettavo di trovare una versione di link () chiamata flink () (confronta con chmod () / fchmod ()) ma, almeno su Linux, questo non esiste.

Punti bonus per dirmi come creare il file anonimo senza esporre brevemente un nome file nella struttura di directory del disco.

    Una patch per una proposta di chiamata di sistema Linux flink() è stata inviata diversi anni fa, ma quando Linus ha dichiarato “non c’è modo in HELL di poterlo fare in modo sicuro senza grosse altre incursioni” , questo ha praticamente chiuso il dibattito sull’aggiunta di questo .

    Aggiornamento: A partire da Linux 3.11, ora è ansible creare un file senza voce di directory usando open() con il nuovo flag O_TMPFILE e collegarlo al filesystem una volta che è completamente formato usando linkat() su /proc/self/fd/ fd con il flag AT_SYMLINK_FOLLOW .

    Il seguente esempio è fornito sulla pagina di manuale open() :

      char path[PATH_MAX]; fd = open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); /* File I/O on 'fd'... */ snprintf(path, PATH_MAX, "/proc/self/fd/%d", fd); linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file", AT_SYMLINK_FOLLOW); 

    Nota che linkat() non permetterà di riapplicare i file aperti dopo che l’ultimo link è stato rimosso con unlink() .

    La mia domanda: c’è un modo per ricolbind un file come questo nella struttura delle directory? Se si potesse fare ciò, si potrebbe ad esempio implementare le scritture di file in modo che il file appaia atomicamente e pienamente formato. Questo fa appello alla mia pulizia compulsiva. 😉

    Se questo è il tuo unico objective, puoi ottenerlo in un modo molto più semplice e ampiamente utilizzato. Se stai a.dat a a.dat :

    1. Aprire a.dat.part per scrivere.
    2. Scrivi i tuoi dati.
    3. Rinominare a.dat.part in a.dat .

    Posso capire che voglio essere pulito, ma scolbind un file e ricollegarlo solo per essere “pulito” è una specie di sciocco.

    Questa domanda su serverfault sembra indicare che questo tipo di ricollegamento non è sicuro e non è supportato.

    Grazie al post @ mark4o su linkat(2) , vedi la sua risposta per i dettagli.

    Volevo fare un tentativo per vedere cosa effettivamente è successo quando si cerca di colbind effettivamente un file anonimo nel file system su cui è stato salvato. (spesso /tmp , ad es. per i dati video che sta giocando firefox).


    A partire da Linux 3.16, sembra che non ci sia ancora modo di ripristinare un file cancellato che è ancora aperto. Né AT_SYMLINK_FOLLOWAT_EMPTY_PATH per linkat(2) fanno il trucco per i file eliminati che avevano un nome, anche come root.

    L’unica alternativa è tail -c +1 -f /proc/19044/fd/1 > data.recov , che crea una copia separata, e devi ucciderla manualmente quando viene eseguita.


    Ecco il wrapper perl che ho preparato per i test. Usa strace -eopen,linkat linkat.pl - per verificare che il tuo sistema non sia ancora in grado di ripristinare i file aperti. (Lo stesso vale anche per sudo ). Ovviamente dovresti leggere il codice che trovi su Internet prima di eseguirlo o utilizzare un account sandbox.

     #!/usr/bin/perl -w # 2015 Peter Cordes  # public domain. If it breaks, you get to keep both pieces. Share and enjoy # Linux-only linkat(2) wrapper (opens "." to get a directory FD for relative paths) if ($#ARGV != 1) { print "wrong number of args. Usage:\n"; print "linkat old new \t# will use AT_SYMLINK_FOLLOW\n"; print "linkat -  

    Chiaramente, questo è ansible – fsck fa, per esempio. Tuttavia, fsck fa con il mojo principale del file system localizzato e chiaramente non sarà portatile, né eseguibile come utente non privilegiato. È simile al commento di debugfs sopra.

    Scrivere quella chiamata di flink(2) sarebbe un esercizio interessante. Come sottolinea Ijw, offrirebbe alcuni vantaggi rispetto alla pratica corrente di rinominazione file temporanea (rinomina, nota, è garantita atomica).

    Un po ‘tardi per il gioco, ma ho appena trovato http://computer-forensics.sans.org/blog/2009/01/27/recovering-open-but-unlinked-file-data che potrebbe rispondere alla domanda. Non l’ho ancora testato, quindi, YMMV. Sembra sano.