Ext4'te doğum boş


83

Sadece Birthbölümünü okuyordum statve ext4'ün onu desteklemesi gerekiyor, fakat yeni oluşturduğum bir dosya bile boş bırakıyor.

 ~  % 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

Neden ext4bölümüm bu alanı doldurmuyor?

Yanıtlar:


93

Alan doldurulur (aşağıya bakınız) yalnızca coreutils statgöstermez. Görünüşe göre arayüz için 1 bekliyorlar .xstat()

coreutils yamalar - ağustos 2012 - TODO

stat (1) ve ls (1) doğum zamanı için destek. Xstat () 'a çekirdek tarafından sağlanan

Yaratma zamanını şu yoldan alabilirsiniz debugfs:

debugfs -R 'stat <inode_number>' DEVICE

örneğin, /etc/profilehangisinin açık olduğu için /dev/sda2(bkz. Bir dosyanın hangi cihazda olduğunu bulma ):

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

LKML iş parçacığına 1 Linus 'cevap


7
@Sparhawk: Bu problemi de bir dosya ile yaşadım /home/user/path/to/fileçünkü /homeayrı bir bölümdeydi . Bu durumda, sağlanan yolun statgöreceli olması gerekir /home. Örnek: sudo debugfs -R 'stat user/path/to/file' /dev/sda2. Yol kullanımından kurtulmak için yol statyerine inode numarasını sağlayabiliriz :sudo debugfs -R "stat <$(stat -c %i /home/user/path/to/file)>" /dev/sda5
jpfleury

3
Ağa bağlı bir dosya sisteminden dosyaların oluşturulma zamanını almak için kullanılabilir mi?
taranaki

1
Dolayısıyla bu, dosya sisteminin oluşturulmasının ötesine geçen bir zaman damgası değildir. Bunun anlamı, bir dosya 25 yıl önce oluşturulmuş ve çok sayıda farklı fiziksel veya monte edilmiş sistem üzerinden kopyalanmışsa, herhangi bir meta verinin yaratılış tarihine ilişkin bilgiyi bulmanın hiçbir yolu yok demektir. Yani bir dosyanın ne zaman yapıldığını bilmenin tek yolu onu dosya adına mı yazmaktır? Veya içeriğin içinde? Bunun garip görünmemesi için herhangi bir sebep var mı?
Sinekonata

2
@sinekonata dosyası meta çok sistem bağımlı (Bu cevap gösterdiği gibi, işletim sisteminin her katman işlemesini olmalıdır) ve makineler arasında kopya genelinde tutarak sistemleri hem o meta veri biçimi için destek dayanır ve kopyalama aracı. Bunun anlamı şudur: karışmamış dosya adını bile alırsanız şanslısınız. Alternatif olarak, bazı dosya biçimleri sen meta eklemek için izin içindeki dosya (örn ID3 ), ve genellikle de taşır, ancak birçok biçimleri böyle bir özelliği yoktur. Sonunda, dosyayı aşağıdaki gibi bir arşiv dosyasının içine koyabilirsiniz
André Paramés

1
Not <ve >inode numarası etrafında gereklidir. Genellikle ayarlanması gereken bir değişkeni kuşatmak için örneklerde kullanılırlar, ancak bu durumda tam anlamıyla girilmeleri gerekir. Bunlar olmadan, inode numarası bir yol olarak kabul edilir ve bir File not found by ext2_lookuphata ile karşılaşırsınız.
mivk

31

Bunu basit bir kabuk fonksiyonunda birleştirdim:

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
    }

Daha sonra ile çalıştırabilirsiniz

$ 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

22

xstatFonksiyon ana hat birleştirilecek oldu da hiç. Ancak, statxdaha sonra yeni bir çağrı önerildi ve Linux 4.11'de birleştirildi . Yeni statx(2)sistem çağrısı, dönüş yapısında bir oluşturma süresi içerir. statx(2)Glibc'ye yalnızca 2.28'de bir sarıcı eklendi (Ağustos 2018'de yayımlandı) . Bu sarıcıyı kullanma desteği, GNU coreutils 8.31'e (Mart 2019'da yayımlandı) eklendi:

stat, dosya sistemi tarafından desteklendiğinde, glibc> = 2.28 ve kernel> = 4.11 bulunan GNU Linux sistemlerinde dosya oluşturma süresini yazdırır.

% 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

Aşağıda, statxkullanıcının henüz yakalayamadığı bir demo (daha eski glibc veya coreutils) var. Doğrudan bir C programında sistem çağrılarını aramak kolay değildir. Tipik olarak glibc, işi kolaylaştıran bir sarıcı sağlar, ancak Neyse ki, @whotwagner , x86 ve x86-64 sistemlerinde sistem çağrısının nasıl kullanılacağını gösteren örnek bir C programı yazdı statx(2). Çıktı stat, herhangi bir biçimlendirme seçeneği olmadan varsayılanla aynıdır , ancak yalnızca doğum zamanını yazdırmak için değiştirmek kolaydır. (Yeterince yeni bir glibc'niz varsa, buna ihtiyacınız olmayacak - statxdoğrudan açıklandığı şekilde kullanabilirsiniz man 2 statx).

İlk önce, onu kopyalayın:

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

statx.cKodu derleyebilir veya yalnızca doğum saatini istiyorsanız birth.c, aşağıdaki kodla klonlanmış bir dizinde bir dizin oluşturabilirsiniz (bu, statx.cnanosaniye kesinliği dahil yalnızca oluşturma zaman damgasının yazdırılmasının minimal bir sürümüdür ):

#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;
}

Sonra:

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

Teorik olarak bu, yaratma zamanını yalnızca ext * olanlardan daha fazla dosya sisteminde erişilebilir kılmalıdır ( debugfsext2 / 3/4 dosya sistemleri için bir araçtır ve diğerleri için kullanılamaz). XFS sistemi için çalıştı, ancak NTFS ve exfat için çalışmadı. Sanırım bunun için FUSE dosya sistemleri oluşturma zamanını içermiyordu.


5

Doğum zamanının boş / sıfır / kısa olacağı başka bir durum daha var: Ext4'ün Inode büyüklüğünün saklamak için en az 256 byte olması gerekir crtime. Sorun başlangıçta 512 MB'tan küçük dosya sistemi oluşturduysanız ortaya çıkar (varsayılan Inode boyutu 128 byte, see /etc/mke2fs.confand mkfs.ext4manpage).

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

ve / veya

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

Şimdi dosya sistemi inode'unu kontrol edin (saklamak için yeterince büyük crtimemü?):

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

Teknik bilgi: Ext4 Disk Düzeni sayfasında, inode tablolarının bazı niteliklerinin 0x80 (128) ötesinde olduğuna dikkat edin.


Doğru (bunu vger'da okuduğumu hatırlıyorum ). 512MB sınırı 1275mke2fs.c satırında tanımlanmıştır
don_crissti

2

Ne pahasına olursa olsun kendimi aşağılık hissediyordum, bu yüzden eğer mümkünse altta yatan bir ext4 dosya sisteminden almak için debugfs kullanarak crtime işlevini sessizce desteklemek için stat etrafına bir bash sarıcı yazdım. Umarım sağlamdır. Burada bulun .

Bir düzeltmenin görünüşte o betikte belgelendiği Linux için yapılacaklar listesinde olduğunu unutmayın. Dolayısıyla, bu ambalajın, yalnızca yapılana kadar nominal bir ömrü vardır ve yapılabilecekler için daha fazla bir egzersizdir.


3
Not xstat()o GNU C önce sadece bir zaman meselesi ve böylece en sonunda, Linux eklenmiştir findbunun için destek ekleyin.
Stéphane Chazelas

1
Korku veren! Gerçekten iyi haber.
Bernd Wechner

6
Pedantik olduğun için özür dileyerek, "pedantik" in anlamını anlamış görünmüyorsun.
Nick

"Aşırı ayrıntı veya formalitelerle aşırı ilgilenme" - olduğu gibi, kabul edilen cevap iyi, ama ... resmileştirelim. ;-)
Bernd Wechner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.