Kelahiran kosong di ext4

83

Saya baru saja membaca di Birthbagian statdan tampaknya ext4 harus mendukungnya, tetapi bahkan file yang saya buat membiarkannya kosong.

 ~  % touch test                                                       slave-iv
 ~  % stat test.pl                                                     slave-iv
  File: ‘test.pl’
  Size: 173             Blocks: 8          IO Block: 4096   regular file
Device: 903h/2307d      Inode: 41943086    Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/xenoterracide)   Gid: (  100/   users)
Access: 2012-09-22 18:22:16.924634497 -0500
Modify: 2012-09-22 18:22:16.924634497 -0500
Change: 2012-09-22 18:22:16.947967935 -0500
 Birth: -

 ~  % sudo tune2fs -l /dev/md3 | psp4                                  slave-iv
tune2fs 1.42.5 (29-Jul-2012)
Filesystem volume name:   home
Last mounted on:          /home
Filesystem UUID:          ab2e39fb-acdd-416a-9e10-b501498056de
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    journal_data
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              59736064
Block count:              238920960
Reserved block count:     11946048
Free blocks:              34486248
Free inodes:              59610013
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      967
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
RAID stride:              128
RAID stripe width:        256
Flex block group size:    16
Filesystem created:       Mon May 31 20:36:30 2010
Last mount time:          Sat Oct  6 11:01:01 2012
Last write time:          Sat Oct  6 11:01:01 2012
Mount count:              14
Maximum mount count:      34
Last checked:             Tue Jul 10 08:26:37 2012
Check interval:           15552000 (6 months)
Next check after:         Sun Jan  6 07:26:37 2013
Lifetime writes:          7255 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
First orphan inode:       55313243
Default directory hash:   half_md4
Directory Hash Seed:      442c66e8-8b67-4a8c-92a6-2e2d0c220044
Journal backup:           inode blocks

Mengapa ext4partisi saya tidak mengisi bidang ini?

xenoterracide
sumber

Jawaban:

93

Kolom akan diisi (lihat di bawah) hanya coreutils stattidak menampilkannya. Rupanya mereka sedang menunggu 1 untuk xstat()antarmuka .

coreutils patch - Agustus. 2012 - TODO

stat (1) dan ls (1) mendukung waktu kelahiran. Bergantung pada xstat () yang disediakan oleh kernel

Anda bisa mendapatkan waktu pembuatan melalui debugfs:

debugfs -R 'stat <inode_number>' DEVICE

mis. untuk perangkat saya /etc/profileyang aktif /dev/sda2(lihat Cara mengetahui perangkat apa yang digunakan oleh file ):

stat -c% i / etc / profile
398264
debugfs -R 'stat <398264>' /dev/sda2
debugfs 1.42.5 (29-Jul-2012)
Inode: 398264   Type: regular    Mode:  0644   Flags: 0x80000
Generation: 2058737571    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 562
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x506b860b:19fa3c34 -- Wed Oct  3 02:25:47 2012
 atime: 0x50476677:dcd84978 -- Wed Sep  5 16:49:27 2012
 mtime: 0x506b860b:19fa3c34 -- Wed Oct  3 02:25:47 2012
crtime: 0x50476677:dcd84978 -- Wed Sep  5 16:49:27 2012
Size of extra inode fields: 28
EXTENTS:
(0):3308774

1 balasan Linus pada utas LKML

don_crissti
sumber
7
@Sparhawk: Saya punya masalah ini juga dengan file /home/user/path/to/filekarena /homeberada di partisi yang terpisah. Dalam hal itu, jalur yang disediakan statharus relatif terhadap /home. Contoh: sudo debugfs -R 'stat user/path/to/file' /dev/sda2. Untuk menghilangkan penanganan jalur, kami dapat memberikan statnomor inode alih-alih jalur:sudo debugfs -R "stat <$(stat -c %i /home/user/path/to/file)>" /dev/sda5
jpfleury
3
Bisakah ini digunakan untuk mendapatkan waktu pembuatan file dari sistem file yang dipasang di jaringan?
taranaki
1
Jadi ini bukan cap waktu yang melampaui penciptaan sistem file. Ini berarti bahwa jika file dibuat 25 tahun yang lalu dan disalin melalui banyak sistem fisik atau sistem yang berbeda, tidak ada cara sama sekali untuk menemukan informasi tanggal pembuatan di salah satu metadata? Jadi satu-satunya cara untuk mengetahui kapan suatu file dibuat adalah dengan mengetikkannya ke dalam nama file? Atau di dalam konten? Apakah ada alasan untuk penerapan yang tampaknya aneh ini?
sinekonata
2
Metadata file @sinekonata sangat tergantung pada sistem (seperti yang ditunjukkan oleh jawaban ini, setiap lapisan OS harus dapat memprosesnya) dan menjaganya di seluruh salinan di antara mesin bergantung pada dukungan untuk format metadata oleh kedua sistem dan alat penyalinan. Artinya adalah: Anda beruntung jika Anda mendapatkan nama file yang tidak rusak. Atau, beberapa format file memungkinkan Anda untuk memasukkan metadata ke dalam file (misalnya ID3 ), dan yang umumnya berjalan dengan baik, tetapi banyak format tidak memiliki fitur seperti itu. Akhirnya, Anda dapat meletakkan file di dalam file arsip seperti
André Paramés
1
Perhatikan bahwa <dan di >sekitar nomor inode diperlukan. Mereka sering digunakan dalam contoh untuk mengelilingi variabel yang harus disesuaikan, tetapi dalam kasus ini mereka harus dimasukkan secara harfiah. Tanpa mereka, nomor inode diperlakukan sebagai jalur, dan Anda mendapatkan File not found by ext2_lookupkesalahan.
mivk
31

Saya menggabungkan ini ke dalam fungsi shell sederhana:

get_crtime() {
  for target in "${@}"; do
    inode=$(stat -c %i "${target}")
    fs=$(df  --output=source "${target}"  | tail -1)
    crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | 
    grep -oP 'crtime.*--\s*\K.*')
    printf "%s\t%s\n" "${target}" "${crtime}"
  done
    }

Anda kemudian dapat menjalankannya

$ get_crtime foo foo/file /etc/
foo Wed May 21 17:11:08 2014
foo/file    Wed May 21 17:11:27 2014
/etc/   Wed Aug  1 20:42:03 2012
terdon
sumber
22

The xstatfungsi tidak pernah mendapat digabung menjadi arus utama. Namun, statxpanggilan baru diusulkan kemudian , dan digabungkan dalam Linux 4.11 . statx(2)Panggilan sistem baru tidak termasuk waktu pembuatan dalam struct kembali. Wrapper untuk statx(2)ditambahkan ke glibc hanya pada 2,28 (rilis Agustus 2018) . Dan dukungan untuk menggunakan pembungkus ini ditambahkan dalam GNU coreutils 8.31 (dirilis Maret 2019):

stat sekarang mencetak waktu pembuatan file ketika didukung oleh sistem file, pada sistem GNU Linux dengan glibc> = 2.28 dan kernel> = 4.11.

% stat --version
stat (GNU coreutils) 8.31
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Michael Meskes.
% stat /
  File: /
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d    Inode: 2           Links: 17
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-06-06 20:03:12.898725626 +0900
Modify: 2019-05-28 05:15:44.452651395 +0900
Change: 2019-05-28 05:15:44.452651395 +0900
 Birth: 2018-06-07 20:35:54.000000000 +0900

Berikut ini adalah demo di statxmana userland belum menyusul (glibc atau coreutils lama). Tidak mudah untuk memanggil panggilan sistem secara langsung dalam program C. Biasanya glibc menyediakan pembungkus yang memudahkan pekerjaan, tetapi Untungnya, @whotwagner menulis contoh program C yang menunjukkan cara menggunakan statx(2)pemanggilan sistem pada sistem x86 dan x86-64. Outputnya adalah format yang sama dengan statdefault, tanpa opsi format apa pun, tetapi mudah untuk memodifikasinya untuk mencetak waktu kelahiran saja. (Jika Anda memiliki glibc yang cukup baru, Anda tidak memerlukan ini - Anda dapat menggunakan statxsecara langsung seperti yang dijelaskan dalam man 2 statx).

Pertama, klon:

git clone https://github.com/whotwagner/statx-fun

Anda dapat mengkompilasi statx.ckode, atau, jika Anda hanya ingin waktu kelahiran, buat birth.cdi direktori kloning dengan kode berikut (yang merupakan versi minimal dari statx.cpencetakan hanya cap waktu pembuatan termasuk ketepatan nanosecond):

#define _GNU_SOURCE
#define _ATFILE_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include "statx.h"
#include <time.h>
#include <getopt.h>
#include <string.h>

// does not (yet) provide a wrapper for the statx() system call
#include <sys/syscall.h>

/* this code works ony with x86 and x86_64 */
#if __x86_64__
#define __NR_statx 332
#else
#define __NR_statx 383
#endif

#define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

int main(int argc, char *argv[])
{
    int dirfd = AT_FDCWD;
    int flags = AT_SYMLINK_NOFOLLOW;
    unsigned int mask = STATX_ALL;
    struct statx stxbuf;
    long ret = 0;

    int opt = 0;

    while(( opt = getopt(argc, argv, "alfd")) != -1)
    {
        switch(opt) {
            case 'a':
                flags |= AT_NO_AUTOMOUNT;
                break;
            case 'l':
                flags &= ~AT_SYMLINK_NOFOLLOW;
                break;
            case 'f':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags |= AT_STATX_FORCE_SYNC;
                break;
            case 'd':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags |= AT_STATX_DONT_SYNC;
                break;
            default:
                exit(EXIT_SUCCESS);
                break;
        }
    }

    if (optind >= argc) {
        exit(EXIT_FAILURE);
    }

    for (; optind < argc; optind++) {
        memset(&stxbuf, 0xbf, sizeof(stxbuf));
        ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
        if( ret < 0)
        {
            perror("statx");
            return EXIT_FAILURE;
        }
        printf("%lld.%u\n", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);
    }
    return EXIT_SUCCESS;
}

Kemudian:

$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017

Secara teori ini harus membuat waktu pembuatan dapat diakses pada lebih banyak filesystem daripada hanya ext * ( debugfsmerupakan alat untuk filesystem ext2 / 3/4, dan tidak dapat digunakan pada yang lain). Itu berhasil untuk sistem XFS, tetapi tidak untuk NTFS dan exfat. Saya kira sistem file FUSE untuk mereka yang tidak termasuk waktu pembuatan.

muru
sumber
5

Ada kasus lain di mana waktu Lahir akan kosong / nol / putus: ukuran Inode Ext4 harus setidaknya 256bytes untuk disimpan crtime. Masalah terjadi jika Anda awalnya membuat sistem file lebih kecil dari 512MB (ukuran Inode default akan menjadi 128 byte, lihat /etc/mke2fs.confdan mkfs.ext4manpage).

stat -c '%n: %w' testfile
testfile: -  

dan / atau

stat -c '%n: %W' testfile
testfile: 0

Sekarang periksa inode sistem file (apakah cukup besar untuk menyimpan crtime?):

tune2fs -l $(df . --output=source | grep ^/) | grep "Inode size:"
Inode size:           128

Informasi teknis: Pada halaman Layout Disk Ext4 , perhatikan bahwa beberapa atribut dari tabel inode melebihi 0x80 (128).

Franklin Piat
sumber
Benar (saya ingat pernah membaca tentang ini di vger ). Batas 512MB didefinisikan mke2fs.cpada baris 1275
don_crissti
2

Untuk apa nilainya saya merasa sangat bertele-tele jadi menulis bash wrapper sekitar stat untuk diam-diam mendukung crtime menggunakan debugfs untuk mengambilnya dari sistem file ext4 yang mendasarinya jika tersedia. Saya harap ini kuat. Temukan di sini .

Perhatikan bahwa perbaikan tampaknya ada di daftar todo untuk Linux seperti yang didokumentasikan dalam skrip itu. Jadi bungkus ini memiliki umur nominal hanya sampai itu selesai dan lebih merupakan latihan dalam apa yang bisa dilakukan.

Bernd Wechner
sumber
3
Catatan yang xstat()akhirnya telah ditambahkan ke Linux, jadi tinggal menunggu waktu sebelum libc GNU dan findtambahkan dukungan untuk itu.
Stéphane Chazelas
1
Luar biasa! Kabar baik memang.
Bernd Wechner
6
Dengan permintaan maaf karena menjadi orang yang bertele-tele, Anda sepertinya tidak mengerti arti "orang yang bertele-tele".
Nick
"terlalu mementingkan detail kecil atau formalisme" - seperti dalam, jawaban yang diterima baik-baik saja, tapi ... mari kita formalisasikan. ;-)
Bernd Wechner