Bir dosya inode tarafından alınabilir mi?


27

Belirtilen sıraya göre aşağıdaki komutları koştum:

$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b

Bu testten komutun rmgerçekte a, inode hala var olduğu ve başka bir dosya adı ( b) üzerinden alınabileceği için dosya yerine sadece dosya adını ( bu testte) kaldırdığı sonucuna vardım .

Sorum şu ki, bir dosya sadece bir dosya adına bağlıysa, dosyaya ne zaman yapılırsa rmgerçek dosya (inode) tamamen kaldırılır mı? Olmazsa, bir dosya inode'u dosya adı olmadan ve sadece inode üzerinden alınabilir mi?


Bana işletim sistemine özgü geliyor.
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams. Versiyona bağlı mı demek istiyorsun?
user43312 29:13

Hayır, işletim sistemine bağlı demek istiyorum. Her (eğer farklı olması herhangi VFS'nin içine dokunarak) yollarını.
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams RHL veya RHEL hakkında bir fikriniz var mı?
user43312 29:13

1
@ BruceEdiger Os X sıralama böyle yapar. Bir dosya sistemi nesnesine, temelde dosya sistemi numarası ve düğüm numarasından oluşturulan bir "dosya referans URL'si" kullanarak erişebilirsiniz. Ancak bunları kendiniz inşa etmek resmen desteklenmiyor. Bunun yerine, bir dosya için bir "dosya referans URL'si" alırsınız ve daha sonra aynı çalışma oturumu sırasında sonraki erişimler için yol adı yerine onu kullanırsınız, böylece uygulamanız aynı birimde başka bir yere taşınan dosyaya kayıtsız kalır.
Analog Dosya

Yanıtlar:


29

Bir dosyayı inode üzerinden açmaya çalışırsanız, bu herhangi bir dizinde gezinmeyi atlar. Dizin geçişi, dosyanın ve kendisine giden dizinlerin izinlerini belirlemek için gereklidir. Dizin geçişi olmadan, çekirdeğin arama işleminin dosyaya erişmesine izin verilip verilmediğini belirleme yolu yoktur.

Bir yoktu dosya tanıtıcıyı bir dosyaya bir bağlantı oluşturarak izin Linux çekirdeği için önerilen yama . O edildi güvenli bu uygulamaya son derece zor olurdu çünkü reddedildi .

Linux altında (ve muhtemelen aynı nedenden dolayı diğer unix varyantlarında), silinen bir dosyaya bağlantı oluşturamazsınız, bu nedenle bir dosyanın adı artık olmazsa, bir tane daha ekleyemezsiniz. altındaki sihirli bağlantıları açarak dosyalayın /proc/$pid/fd/.

Bir dosyanın artık bağlantısı yoksa ve artık açık değilse, artık mevcut değildir ve önceden verileri tarafından kullanılan alan herhangi bir zamanda geri kazanılabilir.

¹ Sen ile örneğin bir dosya sistemi bağımlı bir şekilde dosya sisteminde doğrudan bayt twiddling bunu mümkün olabilir debugfsext2 / ext3 / ext4 için. Bu, dosya sisteminin monte edildiği cihaza erişim gerektirir (yani, genellikle sadece root bunu deneyebilir). Ancak, debugfs bir dosyaya inode ile erişebilse de, bu dosya silinirse yardımcı olmaz: uygulama kapatılırsa dosya gerçekten silinir ve hata ayıklamaların monte edilmiş bir dosya sisteminde okuma-yazma modunda çalıştırılması bir reçetedir. felaket.


11

Linux'ta, debugfsetkileşimli ext2 / ext3 / ext4 dosya sistemi hata ayıklayıcısı, lnbir inode numarasını alabilen filespecve karşılık gelen dosyaya yeni bir sabit bağlantı oluşturabilen bir komut sağlar . Uygulamada, bu , bağlantısız dosyanın açık bir dosya tanımlayıcısını koruyarak bir işlem tarafından açık tutulmasını gerektirir /proc/[pid]/fd/[n]. Bunun silinmiş bir dosyada olduğunu denemek büyük olasılıkla dosya sisteminin bozulmasına neden olacaktır.

Bunun nedeni, ext3'ün (ve ext4 uzantısında) bir çökmeden sonra bir bağlantıyı güvenli bir şekilde devam ettirebilmesini sağlamak için, aslında inode içindeki blok işaretleyicileri sıfırlar , ext2 ise bu blokları blok bitmaplerinde kullanılmamış olarak işaretler ve işaretler. "silindi" olarak inode edin ve blok işaretleyicileri yalnız bırakın. Buna rağmen, hard link oluşturmak için dosya sisteminin okuma-yazma sisteminin monte edilmesi gerektiğinden, silinen dosya için ayrılan bloklar önceden tahsis edilmiş olabilir.

Çekirdek 2.6.39 sürümünden önce , GNU coreutils v8.0'da sunulan seçeneğin , bağlantısız bir dosyayı hem bir tmpfs dosya sisteminde bulunması durumunda , açık bir dosya tanıtıcısı aracılığıyla bir bağlantısız dosyayı kurtarmak için kullanılabileceği için kullanılır . Bu özellik, Gilles'un belirttiği gibi , doğrudan bir dosya tanımlayıcısından sabit bağlantı oluşturulmasına izin vermeyle ilgili güvenlik hususları nedeniyle devre dışı bırakılmıştır .ln -L|--logical/proc/[pid]/fd/[n]


ln -LSilinen bir dosyayı / proc dizininden kurtarmayı denedim ve şu hatayı aldım: "Böyle bir dosya veya dizin yok", bu yüzden aslında bunu desteklediğini sanmıyorum. Çekirdeklerim 8.21 var.
wingedsubmariner

1
ln -Lsöylediklerini yapmaz. lnKaynağın sembolik bir bağ olması halinde hedefi zor bağlaması gerektiğini söyler . İçindeki sembolik linkler /proc/$pid/fdözeldir ve bir (deleted)linkin zorla bağlanması işe yaramaz.
Gilles 'SO- kötülük yapmayı bırak'

Ayrıca debugfs, dosya silinmişse de yardım etmeyecektir - dosya sisteminin tamamının tamamen karışması muhtemel olan takılı bir dosya sisteminde okuma-yazma modunda çalıştırma riskini almak istemiyorsanız.
Gilles 'SO- kötülük olmayı'

İle ilgili cevap güncellendi ln -L. /proc/[pid]/fd/[n]Belirli özel durumlarda kullanmaktan zor bağlantılar oluşturmak mümkün olmuştu, ancak bu o zamandan beri düzeltildi.
Thomas Nyman

1
debugfs's lngerçekten düşük seviye ve sadece bir isim oluşturur, sayımı güncelleme veya blokları kullanılmamış olarak işaretlemediğinden çok tehlikelidir . Tercih debugfs'ın undelhangi des bütün bunlar. Uyarı: debugfsedilir çalıştırılacak değil sen küle sizin FS yanan bir şans almak istemediğiniz sürece bir dosya sistemini monte üzerinde.
Lloeki

9

'Ln' ve 'rm' komutları 1970'lerin başından beri her UNIX dosya sisteminde tam olarak böyle çalıştı. Mac OSX, BSD ve Linux, bu özgün tasarıma miras alıyor.

Kendi başına, bir UNIX dosyasının adı yoktur, yalnızca inode numarası veya inum vardır. Ancak, ona yalnızca bir adı, söz konusu inum ile ilişkilendiren özel bir "dizin" dosyasına giriş yoluyla erişebilirsiniz; doğrudan inum değerini belirleyemezsiniz.

Bir dizindir kendisi de erişmesi gereken böylece, bir dosya bunu bir "yol adı" olarak bilinen ileri eğik çizgiler ile sınırlanmış dizin adlarının (/) bir dizi, vb (başka) dizini aracılığıyla ve. Bir "/" harfiyle başlamadığı sürece, işlemin "geçerli çalışma dizini" nde yol başlar, bu durumda dosya sistemi kök dizini ile başlar. Örneğin, yol adı "/" karakteri içermiyorsa, geçerli dizine bir giriş olması bekleniyor.

Dizin olmayan bir dosya "sabit bağlantı" olarak bilinen herhangi bir sayıda yol adına sahip olabilir ve tüm yol adları kaldırılana ve son işlem dosyayı kapatana kadar devam eder . Sonra dosya aslında silinir ve alanı yeniden kullanıma uygun olarak işaretlenir. Yani, tek başına bağlı bir dosyayı creat () veya open () ve ardından unlink () 'ı açarak dosya sistem adı alanında artık görünmeyecektir, ancak dosya siz kapatana kadar var olmaya devam edecektir. Bu, başka bir program tarafından okunamayacak geçici kazı kazan dosyaları için kullanışlıdır.

Dizinler inode numaralarına sahip olsalar da, çoğu dosya sistemi bunlara katı bağlantılara izin vermez; sadece bir başka dizinde görünebilirler. (Sıra dışı istisnalardan biri Mac OSX HFS + dosya sistemidir; Time Machine yedeklemelerinin çalışmasına izin verir.) Dizinlere (veya başka bir dosyaya) "yumuşak bağlantılar" oluşturabilirsiniz. Yazılım bağlantısı, bir inum yerine başka bir yol adı içermesi dışında bir dizin girişine benzer.

Her UNIX dosyasının sahibi, grubu ve erişim izinleri vardır. Dosyayı açmanıza izin vermeleri zorunlu ama yeterli değil; Ayrıca, başvurmak için kullandığınız yol adındaki her dizin için en azından yürütme iznine sahip olmalısınız. Bu yüzden UNIX dosyasını inode numarasına göre açmanın standart bir yolu yoktur; bu, yaygın olarak kullanılan önemli bir güvenlik mekanizmasını atlar.

Ancak bu, neden bir kök (ayrıcalıklı) kullanıcının inode numarasına göre bir dosyayı açmasının standart bir yolu olamayacağını açıklamıyor , çünkü izinler denetimi yine de atlanıyor. Bu, yedekleme gibi bazı sistem yönetimi işlevleri için çok yararlı olacaktır. Bildiğim kadarıyla, bu tür mekanizmalar var, ama hepsi dosya sistemine özgü; Herhangi bir UNIX dosya sistemi için bunu yapmanın genel bir yolu yoktur.


1
Ileri /sessiz, bu yüzden "eğik çizgi" olarak telaffuz edilir.
ctrl-alt-delor,

4

Bu soru teorik (bununla başarılabilir debugfs) veya pratik olarak (acil durum) ele alınabilir . İkinci durumda niyetimin günü kurtardığını ve dosyanın içeriğini (acilen acilen geri yükleyeceğini farz ediyorum).

Çekirdek API debugfsolmadığı için, canlı bir dosya sisteminde çalıştırılmamalıdır, çünkü FS yapısını doğrudan yönetir. Bu nedenle, bunu canlı yapmak için başka bir dosya adına sahip olmalısınız. Dosyanın hala bir işlemle (herhangi bir işlemle) açık olduğunu varsayarak, şu ana kadar uygun olan dosya tanıtıcılarına erişebilir /proc:

$ lsof -F pf "$PWD/a" | sed 's/^p//' # find pid and file descriptor number of any process having the file open
$ pid=1234
$ ls -l /proc/$pid/fd/* | grep "$PWD/a" # find file descriptor number
$ fd=42
$ cat /proc/$pid/fd/$fd > "$PWD/a.restored" # read contents to a new filename

İpuçları:

  • Eğer doğru fd hakkında şüpheniz varsa file, bunun gibi komutları çalıştırabilirsiniz .
  • Dosyaya yazma işlemi varsa, işlemi en kısa sürede durdurduğunuzdan emin olun yoksa en son verileri alamazsınız. (Denenmemiş) bir numara, sadece fd yoluyla okunan dosyayı başka bir işlemle açmak olabilir (deneyin tail -f < /proc/$pid/fd/$fd > /dev/null, yazma işleminden temiz bir şekilde çıkması için çıkın ve yeni işlemin fd'sini kullanın).

2
tail -f < /proc/...İkinci ipucunda olmalı .
Murray Jensen,

Veya , yazma işlemi yalnızca ekleniyorsa (geri arama ve yeniden yazma değil) , ilk etapta kopyalamak için kullanın . Diğer işlemden önce çıkın , ardından dosyanın sonuna kadar bekleyin . tail -c +0 -fcattailtail
Peter Cordes,
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.