Mount neden mevcut bir dizinin üstüne geliyor?


52

Var olan bir dizini bağlama noktası olarak gereklidir .

$ ls
$ sudo mount /dev/sdb2 ./datadisk
mount: mount point ./datadisk does not exist
$ mkdir datadisk
$ sudo mount /dev/sdb2 ./datadisk
$

Dizinin mevcut içeriğini kapladığından kafa karıştırıcı buluyorum. Beklenmedik bir şekilde değiştirilebilecek bağlama noktası dizininin iki olası içeriği vardır (montajı gerçekleştirmeyen bir kullanıcı için).

mountYeni oluşturulan bir dizine neden gelmiyor ? Grafiksel işletim sistemlerinin çıkarılabilir medyayı gösterme şekli budur. Dizinin monte edilmiş (var) veya monte edilmemişse (mevcut değilse) açık olacaktır. İyi bir sebep olduğuna eminim ama henüz bulamadım.


1
Bu davranışı istiyorsanız, kullanın udisksctl. Neden kullanmak mount?
muru

1
Çünkü bu Unix'in yolu. Çünkü bu şekilde daha esnektir ve daha sonra istediğiniz yere monte edebilirsiniz. Bunları herhangi bir yere monte etmek, sunucularınızı ihtiyaç duyduğunuz şekilde genişletmenize olanak sağlar; örneğin, veritabanı bölümü için yeni bir disk almak, DB bölümündeki verileri yeni diske taşımak ve DB verilerine izin vermek için doğru yere monte etmek daha fazla büyümek için.
Rui F Ribeiro

8
Tarihsel bir not olarak, Windows ve LInux diğer tüm işletim sistemlerini esasen ezmeden önce Apollo adında bir şirket vardı. Unix benzeri bir sistem (Unix'ten daha iyi bir tasarım!) İşletim sistemi yazdılar. NFS ihracatının otomatik olarak eklendiği dizinleri yarattı. Aslında, önceden var olan bir dizine bağlanamıyordunuz. HP, Apollo'yu aldı, işletim sistemini çöpe attı ve Apollo'nun 64-bit işlemcisini HP-PA olarak kullandı. Apollo'nun uzaktan prosedür çağrıları sistemi, görünüşe göre Windows'un içinde yaşayan OSF'nin DCE'si oldu. Bilmek savaşın yarısıdır!
Bruce Ediger

Bir şekilde bu benim ubuntu 14.04,3 ​​sistemimde olur. Henüz araştırma yapmadım. SD kartım takıldığında, altında hiçbir şey bulunmayan bir yolla bitiyor. eğer onu tutar ve el ile geri takmaya çalışırsam, aldığım hata bağlama noktasında bir dizin yok.
Skaperen

2
@BruceEdiger better design than Unix![kaynak belirtilmeli]
Ruslan

Yanıtlar:


51

Bu, sızdırılmış bir uygulama detayı durumudur.

Bir UNIX sisteminde, her dizin inode numaralarıyla eşlenmiş bir ad listesinden oluşur . Bir inode, sisteme bir dosya, dizin, özel aygıt, adlandırılmış yöneltme vb. Olup olmadığını bildiren meta verileri tutar. Bir dosya veya dizin ise sisteme diskte dosyanın veya dizin içeriğinin nerede bulunacağını da söyler. Çoğu inode dosya veya dizindir. -iSeçeneği için lsliste inode'a irâde.

Bir dosya sistemi kurmak bir dizin inode alır ve "aslında, bu dizinin içeriğini ararken bunun yerine bu diğer dosya sistemine bakın" (" bu sunumun 10. slaytına bakınız") için çekirdeğin bellekteki kopyasına bir bayrak koyar . Bu, tek bir veri öğesini değiştirdiği için nispeten kolaydır.

Neden sizin için yeni inode'u işaret eden bir dizin girişi oluşturmuyor? Her ikisi dezavantajları olan, uygulayabileceğiniz iki yol vardır. Biri fiziksel olarak dosya sistemine yeni bir dizin yazmaktır - ancak dosya sistemi salt okunursa başarısız olur! Diğer her dizin listeleme işlemi gerçekten orada olmayan "ekstra" şeylerin bir listesini eklemek için. Bu oldukça karmaşıktır ve her dosya işleminde potansiyel olarak küçük bir performans darbesine neden olur.

Dinamik olarak oluşturulmuş bağlama noktaları istiyorsanız, automountsistem bunu yapabilir. Özel olmayan bir disk dosya sistemleri de örneğin iradesiyle dizinleri oluşturabilir proc, sys, devfsvb.

Düzenleme: ayrıca, içeriği bulunan mevcut bir klasörü 'taktığınızda' ne olur?


Bunun dışında inode üzerine bir bayrak koymaz. sudo mount --bind / /mnt ; ls /mnt/proc-> boş. Nasıl çalıştığını merak ediyorum.
sourcejedi

Tam operasyon içinde fs/namespace.csanırım; Kaynağa aşina değilim ve ayrıntılara sondaj için çok uzun zaman harcamak istemedim. "İnode'daki bayrak" bağlantılı sunumdan aldım.
pjc50

2
@sourcejedi: bağlama bağlaçları yalnızca gerçekten bahsettiğiniz dosya sistemini bağlar. Altına monte edilmiş diğer dosya sistemlerini tekrar tekrar bağlamazlar. Bu, montajlarla gizlenmiş çöpleri bulmanın kullanışlı bir yoludur. (örneğin, bazı şeyler montajı başarısız /var/cacheolduğunda bir süre sonra kök FS'de sona /varerdiyse.) Ayrıca bakınız path_resolution(7). (Eski linux-manpages, die.net gibi, 2. bölümde bu adam sayfasını içeriyordu) IDK, Linux'un dahili olarak nasıl çalıştığını, her bir dizin bileşenini mümkün bir montaj olarak kontrol etmeyi optimize etti. Belki bu VFS girişini önbellekte sabitleyebilirsin?
Peter Cordes

2
Tamam, bu benim açımdan… Yani fs/namei.c(yol -> inode araması) namespace.c'yi çağırıyor lookup_mnt(). Dentry'de bir bayrak var (dizin önbelleği girişi). Ama bu sadece bir optimizasyon aka uygulama detayı. Size hangi dosya sisteminin monte edildiğini söylemez ; montaj tablosuna bakmak zorundasın. (Daha fazla uygulama bilgisi için m_hash () 'a bakınız. Linux, en azından ek dizi karşılaştırmalarından kaçınır ve AFAICS, aynı zamanda sihirbazlar tarafından yazılmış olduğu için, dişçi dişlisinin örneğin cilt takma bağlantılarında tekrar kullanılmasını da sağlar).
sourcejedi

1
@PeterCordes man 8 mount:: mount --bind foo foo. Bağlama mountarama yalnızca (bir kısmını) tek bir dosya sistemi değil, olası submounts ekler. Alt montajlar da dahil olmak üzere tüm dosya hiyerarşisi, aşağıdakiler kullanılarak ikinci bir yere eklenir :mount --rbind olddir newdir
mikeserv

19

Eğer mount(2) gerekli bağlama noktası olmaya yeni dizinin oluşturulmasını, bir salt okunur dosya sistemi altında bir şey bağlanamadı. Bu aptalca olur, bu yüzden bunu ekarte edebiliriz.

Mount isteğe bağlı olarak mountpoint olarak yeni bir dizin oluşturduysa, bu garip olurdu. Her zaman mount / unmount olaylarının gerçekleşmesi gibi bir şey değildir, bu yüzden çekirdeğe bu iki adımı tek bir sistem çağrısı ile yapmak için fazladan bir mantık koymak önemli bir hızlanma olmaz. mkdir(2)İsterseniz bir sistem çağrısı yapmak için onu sadece kullanıcı alanına bırakın . Dmitry'in cevabı, mount(2)her iki şeyi de yapmanın onu atomik olmayan yapacağı görüşüne işaret ediyor. Ve ekstra argüman isterdim mount(2)mod bayrakları gibi olan open(2)için, sürer O_CREAT, O_EXCLvb Sadece kullanıcı alanı icar kıyasla aptalca olurdu bunu.

Veya belki de mount(8)( mount(2)sistem çağrılarını yapan geleneksel program ) bunu yapmayı mı soruyordunuz ? Bu mümkün olurdu, ama zaten mkdir(1)iş için mükemmel bir iyilik var ve Unix'in tasarımı tamamen bir araya getirilebilecek küçük araçlarla ilgili. Her ikisini de yapan bir araç istiyorsanız, bu aracı iki basit araçtan oluşturmak için bir kabuk betiği yazmak kolaydır. (Veya, muru yorumunda olduğu gibi, udisksctlzaten bunu yapar, bu yüzden onu yazmak zorunda değilsiniz.) Ayrıca, Linux'un mount(8)util- linux'dan normal olması, dosya sistemine aktarılacak seçeneklerden ziyade, kullanıcı alanı seçenekleri için sözdizimini mount -o x-mount.mkdir[=mode]kullanmayı destekler x-.


Şimdi daha ilginç olan soru: neden ana dosya sisteminde bir dizin olması gerekiyor?

Pjc50'nin cevabının işaret ettiği gibi (baş harfleriim olmasına rağmen hiçbir ilişki yok!), Dizin listelerinde bağlantı noktalarının gösterilmesi daha sonra her birinin ekstra kontrolünü gerektirir readdir().

Bağlantı noktalarına sahip olmak, dizinde onları içeren dizinde bulunur (ana FS'de). readdir()bunun bir bağlantı noktası olduğunu farketmek zorunda değil. Bu sadece olur eğer bağlama noktası bir yol bileşeni olarak kullanılır. Elbette yol çözünürlüğü, bir yolun her dizin bileşeni için bağlama tablosunu kontrol etmek zorundadır.


1
If mount(2) required the creation of a new directory to be the mount point, you couldn't mount anything under a read-only filesystem. That would be dumbKullanıcı açısından bakıldığında, bir salt okunur dosya sistemi değiştirmek gerekir ama bağlar sağlayan elinden gelir: - Ben akıllı it iddia ediyorum
Izkata

2
@Izkata: Bir dosya sistemini salt okunur yapmak, VFS'nin tüm alt ağacının donmuş olduğu anlamına gelmez. Üst yazmaç dizinlerini işaret eden sembolik bağlantılara sahip olabilir veya ana fs yeniden monte edildiğinde altında okuma yazma bağlantı noktalarına sahip olabilir ro. Argümanınızın bir anlam ifade etmediği salt okunur dosya sistemleri için birçok kullanım durumu vardır.
Peter Cordes

2
man 8 mount: x-mount.mkdir[=mode] Hedef dizini oluşturmaya izin ver (bağlama noktası). İsteğe bağlı argüman modu mkdir(2), sekizli gösterimde kullanılan dosya sistemi erişim modunu belirtir . Varsayılan mod 0755'tir. Bu işlev yalnızca kök kullanıcılar için desteklenir.
mikeserv

Takılı okuma-yazma dosya sistemine sahip, salt okunur dosya sistemlerinin önemli kullanım durumlarını görmüyorum, özellikle de Unix'te değil. @PeterCordes
kubanczyk

@kubanczyk: salt okunur kök dosya sistemi, okuma-yazma /tmpve /home. Veya üzerine /usryerel olarak /usr/localmonte edilmiş salt okunur NFS montajı . Veya daha genel olarak, üzerine monteli değiştirilebilen kısmı olan paylaşılan salt okunur bir görüntü. (salt okunur bir görüntünün yerel modları , LiveCD önyüklenebilir görüntülerinde kullanılan, Linux için bindirmeler veya diğer birleşik dosya sistemleri gibi özel dosya sistemleriyle dosya bazında da yapılabilir .) Başlangıçta başlangıçta RO adlı kök FS'yi düşünüyordum. Önyükleme, ancak bunu yapma işlemi diğer bağlardan önce gerçekleşebilir.
Peter Cordes

12

Var olan dizine bağlanmak mountpratik olarak atomik bir çağrı yapar : en azından kullanıcının bakış açısına göre başarılı veya başarısız. Eğer mountmountpoint kendisini oluşturmak için vardı, imkansız geri temiz bir rulo garanti hale başarısızlık iki puan olurdu. Aşağıdaki senaryoyu hayal edin:

  1. mount başarıyla mountpoint'i oluşturur
  2. mount bu dizine yeni bir dosya sistemi bağlamaya çalışır, ancak başarısız olur
  3. mount mountpoint'i kaldırmaya çalışır, ancak başarısız olur

Sistem başarısız bir yan etkisi ile sona erer mount.

İşte burada bir başkası:

  1. umount bir dosya sistemini başarıyla kaldırır
  2. umount mountpoint'i kaldırmaya çalışır, ancak başarısız olur

Şimdi, umountbaşarı mı yoksa başarısızlık mı geri dönmeli?


5
mountbirleştirilebilecek hatalar için 8 farklı dönüş koduna sahiptir. Dizin silme işlemi başarısız olduğunda başka bir tane ekleyebilir. man7.org/linux/man-pages/man8/mount.8.html#RETURN_CODES
kaos

8
OP'nin neden bağlama noktasının neden mevcut bir dizin olması gerektiğini sorduğunu düşünüyorum, mountsistem çağrısının neden oluşturduğu değil. Her ne kadar belki de bu OP'nin sormak istediğini düşündüğüm şey ya da sormak isteyip istemediğim ile ilgili yorumum / beklentimdi.
Peter Cordes

3

Oluşabilecek başka bir dava:

Önyüklerken, salt okunur bir görüntü kök dizine yüklenir. Bu yüzden, gerçek kökleri hizalamak istediğinizde geçersiz kılmak istiyorsunuz. Böylece, mount syscall'in romountpoint'i değiştirdiğini hayal edebilirsiniz rw.

Burada, kök bağlama noktasında bir dosya sistemi sorunu olduğunu hayal edelim, onu düzeltmeyi denemek istersiniz. Mount overlap ile dosya sistemini fsckçözebilir ve çözmek için temel görüntüyü kullanabilirsiniz.

Bu özellik, bir robölüm ile bir bölüm arasındaki değişimin izini sürmek için güçlü güvenlik gerektiren sistemlerde de faydalı olabilir rw.


1
Bunun soruyu nasıl cevapladığından emin değilim. Bağlama noktasının bulunduğu yerde, salt okunur bir dosya sisteminin üzerine hiçbir şey bağlayamayacağınız yeni bir dizin oluşturmak mount gerektiğine işaret ediyor musunuz? Açılış paragrafı kafa karıştırıcı: Linux initrd böyle değil. pivot_rootRoot fs'yi değiştirmek için sistem çağrısını kullanır, sadece üzerine daha fazla şey monte etmekle kalmaz. Bu, sonraki paragraflarda mantığınızı izlemenizi zorlaştırdı, çünkü hakkında konuştuğunuzu sanıyordum pivot_root(2).
Peter Cordes

2
@PeterCordes - linux yıllardır bir initrd kullanmadı : Başka bir root cihazını değiştirirken, initrd pivot_rootsonra umountramdisk kullanıyor. Ancak initramfs rootfs: ne pivot_rootrootfs, ne de demonte edebilirsiniz . Bunun yerine, space ( find -xdev / -exec rm {} \;) alanını boşaltmak için rootfs dışındaki her şeyi silin , rootfs'ı yeni root ( cd /newmount; mount --move . /; chroot .) ile üst üste getirin , stdin / stdout / stderr öğesini new / dev / konsoluna ve execnewinit
mikeserv

@mikeserv: Temiz! İnitrd yerine initramfs kullanmaya başladığımızda kök değiştirme mekanizmasının değiştiğini farketmemiştim. Bir "doğru çekirdek modüllerinin içinde olduğundan emin olun" admin perspektifinden, özdeş>. <. Yine de bunun soruyu gerçekten iyi cevaplamadığını düşünüyorum . “Bir rofs altına monte etmek imkansız” yorumunu kabul ediyor gibi görünüyor ve çok özel bir problem durumu ortaya koyuyor (initramfs önyüklemede salt okunur olarak monte edilmediği için pek mümkün değil gibi görünüyor. - cpio.gz imajını etkilemeden yaz.)
Peter Cordes

@PeterCordes - Bu cevabı gerçekten anlamıyorum. Sadece yorumunuzu gördüm - initramfs bir dosya sistemidir - gerçekten salt okunur olamaz - fs önbelleği enkarnasyonu.
mikeserv

2

Bunu her zaman merak etmişimdir.

Gibi basit bir sarıcı:

#!/bin/sh
eval "mkdir -p \"\$$#\"" 
/bin/mount "$@"  

mountPATH'nizi geçersiz kılan bir dizinde adı verilen yürütülebilir bir komut dosyası olarak kaydedilmişse, /binsizi çok fazla rahatsız ediyorsa

(Gerçek mountikiliyi çalıştırmadan önce mount, eğer böyle bir dizin yoksa, son argümandan sonra adlandırılmış bir dizin oluşturur .)


Alternatif olarak, mountdizin oluşturmak için sargının başarısız çağrılarını istemiyorsanız , şunları yapabilirsiniz:

#!/bin/sh
set -e
eval "lastArg=\"\$$#\""
test -d "$lastArg" || { mkdir "$lastArg"; madeDir=1; }
/bin/mount "$@"  ||  {  test -z "$madeDir" || rmdir "$lastArg"; }

Olmamalı mountkomut sonra dizini böylece yaratılan kullanılır?
muru

1
@muru Son satırın yaptığı bu.
PSkocik

Yani bunu bu şekilde kullanılması gerektiğini anlamına gelir: mount /dev/foo /some/path? İşe yarayacağını düşündüm udisksctl, sen koşarsın mount /dev/foo.
Aralık'ta

4
Kullanarak eval, genişletmeden son cmdline argümanını alabilirsiniz . Bunu DASH ile test ettim, çünkü POSIX sh’in desteklemesi gereken şeyin ötesinde hiçbir şeyi desteklemediğini düşünüyorum. yazdırır . $#"${@:-1}"/bin/dash -c 'echo ${@:-1}' foo barbar
Peter Cordes

1
kullanabilirsiniz man -o x-mount.mkdir...
mikeserv
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.