Neden aynı dosya sistemindeki “mount --bind” dizininden bir dosyaya “hardlink” oluşturamıyorum?


9

Orijinal Sorun

Bir dosya sisteminde bir dosya var: /data/src/file

ve bunu zor bir şekilde bağlamak istiyorum: /home/user/proj/src/file

ama /homebir disk üzerinde ve /databaşka bir üzerinde yani bir hata alıyorum:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Tamam, bu yüzden cihazlar arasında sabit bağlantı kuramayacağımı öğrendim. Mantıklı.

Eldeki sorun

Bu yüzden fantezi olsun ve dosya sistemi srcüzerinde bir klasör bağlamak bağlamak düşündüm /data:

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Neden hala çalışmıyor?

Geçici çözüm

Ben bu kurulum doğru biliyorum çünkü /databağlı yerine "gerçek" dizininde olduğum sürece sabit bağlantı yapabilirsiniz .

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

Bazı Sistem Bilgileri

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

Not : Durumu daha net hale getirmek için dosya ve dizin adlarını elle değiştirdim, bu nedenle komut okumalarında bir veya iki yazım hatası olabilir.


2
Klasörü nereye bağladığınız önemli değildir. Farklı bölümlerde fiziksel olarak bulunurlar. Her bölümün kendi dosya tablosu vardır ve hardlink sadece bu tabloya kaydedilir.
user996142

2
Buradaki nokta, dosyaların fiziksel olarak farklı bölümlerde DEĞİLDİR. Aynı bölümdeki aynı dosya sistemi. Fark bağlama bağlamasıdır.
roaima

Bağlama bağlantısı sadece bir kurgu. Disklerdeki veri yapılarını değiştirmez. Dosya sistemleri hala fiziksel olarak ayrıdır.
Bob Eager

Ancak sabit bağlantıyı oluşturduğumda, /databağlama bağlanma dizininden inode'a erişebiliyorum, bu yüzden bağlama bağlamasıyla aynı bölümde olmalı /dataveya sabit bağlantı yasadışı olması gereken, ancak yine de çalışan cihazlar arasında çalışıyor. Neyi kaçırıyorum?
jdk1.0

Yanıtlar:


6

Yorumlardan bir hayal kırıklığı eksikliği var kodu . Zaman bağlama bağları v2.4'te uygulandığından, hiç kimse yararlı olduğunu düşünmemiş gibi. Elbette yapmanız gereken tek şey .mnt->mnt_sbsöylediği yerlerin yerine geçmektir .mnt...

Çünkü size bir alt ağacın etrafında bir güvenlik sınırı verir.

Not: bu birkaç kez tartışıldı, ancak aramalardan kaçınmak için: örneğin mount --bind / tmp / tmp; artık kullanıcıların / tmp yazılabilir olmalarına rağmen kök fs olmayan başka yerlere bağlantılar oluşturamadıkları bir durum var. Benzer teknikler diğer izolasyon ihtiyaçları için çalışır - temel olarak, yeniden adlandırmayı / bağlantıyı verilen alt ağaçla sınırlayabilirsiniz. IOW, kasıtlı bir özellik. Bir grup ağacı kroze bağlayabileceğinizi ve bir yıl sonra ana ağaçta nasıl yeniden düzenlenebileceğinden bağımsız olarak öngörülebilir kısıtlamalar alabileceğinizi unutmayın.

- Al Viro

İpliğin altında daha somut bir örnek var

Mount -r --bind düzgün çalıştığımızda (sayfa önbellek paylaşımına izin verirken gerekli paylaşılan kitaplıkların kopyalarını chroot haplarının içine yerleştirmek için kullanırım), bu özellik güvenliği bozar.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

Her ne kadar korumalar yeterli olsa da, mahkumun / jail / usr / log dosyasına / jail / usr / log dosyasına potansiyel olarak yazılabilir olmasını istemiyorum.


-1

Cihazlar arası bağlantı yapamamanızın nedeni, belirsizlikler getirmenizdir. Dosyanın dizin girdisi (basit sistemlerde) ilgili dosyanın i-düğüm numarasını içerir. Sabit bir bağlantı (yalnızca başka bir dizin girişi) aynı i-düğüm numarasını içermelidir. Bu iyidir, ancak i-düğüm numaraları yalnızca tek bir dosya sisteminde benzersizdir (genellikle 1'den başlayan yoğun bir kümedir).

Bağlama bağlantınız bu sorunu çözmez. Evet, yapının bir tür 'kurgusu' inşa eder, ancak yapamayacağı şey, tüm ilgili dosya sistemlerinde benzersiz olduklarından emin olmak için tüm i-düğümlerini tek bir dosya sisteminde yeniden numaralandırmaktır! Aptalca olurdu.

Bu kısıtlama her zaman UNIX sistemlerinde olmuştur. Sembolik bağlantı kısmen bunu çözmek için icat edildi. İşlevsel olarak aynı olmadıklarını biliyorum, ama genellikle sorun yok.

Sembolik bir bağlantı mı denemek istiyorsunuz? ( ln -s)


Burada yeniden numaralandırılan herhangi bir düğüm için isim olmazdı. İki görünüme sahip yalnızca bir temel dosya sistemi vardır.
Gilles 'SO- kötü olmayı bırak

Sembolik bir bağlantı istemememin bir nedeni, yollarımın uzun olması ve bir dağınıklık yapmasıydı ls -l. İlk başta biraz aptalca akıl yürütme, ama sonra bir tavşan deliğine yol açtı ve zor bağlantılar ile neler olup bittiğini merak ettim ...
jdk1.0

@Gilles, ben de öyle diyordum. Belirttiğim nokta, inode yeniden numaralandırmasının saçma olacağıydı. Doğru cevabın neden reddedildiğine dair bir fikrim yok.
Bob Eager

Sonucu doğru buluyorsunuz, ancak birçok yerde açıklamanız yanlış, bir bütün olarak cevabınız çok yanıltıcı. İyi bir açıklama için sourcejedi'nin cevabına bakınız.
Gilles 'SO- kötü olmayı bırak'

Daha net olabileceğimi itiraf etsem de hiç hata görmüyorum.
Bob Eager
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.