माउंट माउंट के लिए रीड ओनली ऑप्शन को माउंट क्यों नहीं करता है?


35

मेरे आर्क लिनक्स सिस्टम पर (लिनक्स कर्नेल 3.14.2) बाइंड माउंट्स केवल पढ़ने के विकल्प का सम्मान नहीं करते हैं

# mkdir test
# mount --bind -o ro test/ /mnt
# touch /mnt/foo

फ़ाइल बनाता है /mnt/foo। में प्रासंगिक प्रविष्टि /proc/mountsहै

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

विकल्प माउंट मेरी अनुरोध किया विकल्पों से मेल नहीं है, लेकिन बाँध के व्यवहार पढ़ें / लिखें दोनों से मेल माउंट करते हैं और विकल्प के लिए इस्तेमाल किया मूल रूप से माउंट /dev/sda2पर/

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

यदि, हालांकि, मैं माउंट को रिमूव करता हूं तो यह रीड ओनली ऑप्शन का सम्मान करता है

# mount --bind -o remount,ro test/ /mnt
# touch /mnt/bar
touch: cannot touch ‘/mnt/bar’: Read-only file system

और संबंधित प्रविष्टि /proc/mounts/

/dev/sda2 /mnt ext4 ro,relatime,data=ordered 0 0

लगता है कि मैं क्या उम्मीद कर सकता हूं (हालांकि सच में मैं testनिर्देशिका का पूरा रास्ता देखने की उम्मीद करूंगा )। /proc/mounts/ऑर्निगल माउंट /dev/sda2/ऑन की प्रविष्टि /भी अपरिवर्तित है और पढ़ने / लिखने के लिए बनी हुई है

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

इस व्यवहार और आस-पास के काम को कम से कम 2008 के बाद से जाना जाता है और इसे मैन पेज के दस्तावेज में दर्ज किया गया हैmount

ध्यान दें कि फाइल सिस्टम माउंट विकल्प मूल आरोह बिंदु पर ही बने रहेंगे, और -bind / - rbind के साथ -o विकल्प पास करके नहीं बदले जा सकते हैं। माउंट विकल्पों को एक अलग रिमाउंट कमांड द्वारा बदला जा सकता है

सभी वितरण समान नहीं हैं। आर्क चुपचाप विकल्पों का सम्मान करने में विफल रहता है, जबकि डेबियन एक चेतावनी उत्पन्न करता है जब बाइंड माउंट को केवल पढ़ने के लिए माउंट नहीं मिलता है

mount: warning: /mnt seems to be mounted read-write.

ऐसी खबरें हैं कि यह व्यवहार डेबियन लेनी और स्क्वीज़ में "निश्चित" था, हालांकि यह एक सार्वभौमिक सुधार प्रतीत नहीं होता है और न ही यह अभी भी डेबियन व्हीज़ी में काम करता है। बाइंड माउंट बनाने के साथ मुश्किल से जुड़ा क्या है शुरुआती माउंट पर रीड ऑप्शन का सम्मान?


क्या आपके पास / etc / mtab है?
eyoung100

यह भी देखें thread.gmane.org/gmane.linux.utilities.util-linux-ng/2979 और का उपयोग करके एक समाधान mount -t bindऔर एक सहायक स्क्रिप्ट bugs.launchpad.net/ubuntu/+source/mountall/+bug/519380
स्टीफन चेलजस

@ECarterYoung हाँ मेरे पास ए है /etc/mtab। प्रारंभिक माउंट के बाद प्रविष्टि का कहना है कि माउंट आरडब्ल्यू है और रिमाउंट के बाद यह आरओ कहता है, इसलिए यह माउंट की स्थिति को सही ढंग से रिपोर्ट कर रहा है। यह केवल माउंट कमांड है जो विफल रहता है।
स्ट्रॉन्गबैड

3
मैंने दो डेबियन परीक्षण / अस्थिर मशीनों पर परीक्षण किया, एक डेबियन कर्नेल को चलाने वाला और एक कर्नेल को चालू करने वाला। कर्नेल, mount --bind -o roदोनों के साथ काम नहीं कर रहा है , वे दोनों एक संदेश को थूकते हैं, mount: warning: «mountpoint» seems to be mounted read-write.इसलिए ऐसा लगता है कि डेबियन गिरा या किसी बिंदु पर पैच खो गया ... रिमाउंट हालांकि काम करता है।
derobert

2
@StrongBad ने अनुरोध किया है कि परीक्षण किया है, और यह भी काम नहीं करता है।
derobert

जवाबों:


21

बिंद माउंट है ... अच्छी तरह से ... एक बांध माउंट। यानी यह एक नया माउंट नहीं है। यह सिर्फ "लिंक" / "एक्सपोज़" / "को" एक नए माउंट बिंदु के रूप में एक उपनिर्देशिका मानता है। इस तरह यह माउंट मापदंडों में बदलाव नहीं कर सकता है। इसलिए आपको शिकायतें मिल रही हैं:

# mount /mnt/1/lala /mnt/2 -o bind,ro
mount: warning: /mnt/2 seems to be mounted read-write.

लेकिन जैसा कि आपने कहा कि एक सामान्य बाइंड माउंट काम करता है:

# mount /mnt/1/lala /mnt/2 -o bind

और फिर एक आरओ रिमाउंट भी काम करता है:

# mount /mnt/1/lala /mnt/2 -o bind,remount,ro 

हालाँकि क्या होता है कि आप पूरे माउंट को बदल रहे हैं, न कि केवल इस बाइंड माउंट को। यदि आप / proc / mounts पर एक नज़र डालते हैं, तो आप देखेंगे कि दोनों माउंट और मूल माउंट को केवल-पढ़ने के लिए बदलते हैं:

/dev/loop0 /mnt/1 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0
/dev/loop0 /mnt/2 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0

तो आप जो कर रहे हैं वह शुरुआती माउंट को रीड-ओनली माउंट में बदलने और फिर बाइंड माउंट करने जैसा है, जो निश्चित रूप से केवल रीड-ओनली होगा।

अद्यतन 2016-07-20:

निम्नलिखित 4.5 गुठली के लिए सही हैं, लेकिन 4.3 गुठली के लिए सच नहीं है (यह गलत है। नीचे # 2 अद्यतन देखें)

कर्नेल में दो ध्वज होते हैं जो केवल पढ़ने के लिए नियंत्रित करते हैं:

  • MS_READONLYचाहे पर्वत का संकेत देती है केवल पढ़ने के लिए:
  • MNT_READONLYकेवल पढ़ने के लिए संकेत "उपयोगकर्ता" चाहता है कि क्या यह:

4.5 कर्नेल पर, mount -o bind,roवास्तव में एक चाल चलेगी। उदाहरण के लिए, यह:

# mkdir /tmp/test
# mkdir /tmp/test/a /tmp/test/b
# mount -t tmpfs none /tmp/test/a
# mkdir /tmp/test/a/d
# mount -o bind,ro /tmp/test/a/d /tmp/test/b

रीड-ओनली बाँध के माउंट पैदा करेगा /tmp/test/a/dकरने के लिए /tmp/test/bहै, जो में दिखाई नहीं देंगे /proc/mountsके रूप में:

none /tmp/test/a tmpfs rw,relatime 0 0
none /tmp/test/b tmpfs ro,relatime 0 0

एक अधिक विस्तृत दृश्य दिखाई देता है /proc/self/mountinfo, जो उपयोगकर्ता दृश्य (नाम स्थान) को ध्यान में रखता है। प्रासंगिक लाइनें ये होंगी:

363 74 0:49 / /tmp/test/a rw,relatime shared:273 - tmpfs none rw
368 74 0:49 /d /tmp/test/b ro,relatime shared:273 - tmpfs none rw

दूसरी पंक्ति पर, आप देख सकते हैं कि यह दोनों ro( MNT_READONLY) और rw( !MS_READONLY) कहता है ।

अंतिम परिणाम यह है:

# echo a > /tmp/test/a/d/f
# echo a > /tmp/test/b/f
-su: /tmp/test/b/f: Read-only file system

अपडेट 2016-07-20 # 2:

इसमें थोड़ी और खुदाई से पता चलता है कि वास्तव में व्यवहार लिबामाउंट के संस्करण पर निर्भर करता है जो कि उपयोग-लिनेक्स का हिस्सा है। इसके लिए समर्थन इस प्रतिबद्धता के साथ जोड़ा गया था और संस्करण 2.27 के साथ जारी किया गया था:

प्रतिबद्ध 9ac77b8a78452eab0612523d27fee52159f5016a
लेखक: करेल ज़क 
दिनांक: सोम अगस्त १: 11:54:26 2015 +0200

    libmount: "बाइंड, आरओ" के लिए समर्थन जोड़ें

    अब केवल रीड-ओनली बनाने के लिए दो माउंट (8) कॉल का उपयोग करना आवश्यक है
    माउंट:

      माउंट / फू / बार-बाइ बाँध
      माउंट / बार-रिम रिमाउंट, आरओ, बाइंड

    यह पैच "बाइंड, आरओ" को निर्दिष्ट करने की अनुमति देता है और रिमाउंट किया जाता है
    अतिरिक्त माउंट (2) syscall द्वारा स्वचालित रूप से libmount द्वारा। यह
    निश्चित रूप से परमाणु।

    साइन-ऑफ-बाय: करेल ज़क 

जो वर्कअराउंड भी प्रदान करता है। व्यवहार को पुराने और नए माउंट पर स्ट्रेस का उपयोग करके देखा जा सकता है:

पुराना:

mount("/tmp/test/a/d", "/tmp/test/b", 0x222e240, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.000681>

नया:

mount("/tmp/test/a/d", "/tmp/test/b", 0x1a8ee90, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.011492>
mount("none", "/tmp/test/b", NULL, MS_RDONLY|MS_REMOUNT|MS_BIND, NULL) = 0 <0.006281>

निष्कर्ष:

वांछित परिणाम प्राप्त करने के लिए दो कमांड चलाने की जरूरत है (जैसा कि @ थोमस ने पहले ही कहा था):

mount SRC DST -o bind
mount DST -o remount,ro,bind

माउंट के नए संस्करण (उपयोग-लिनेक्स> = 2.27) स्वचालित रूप से ऐसा करते हैं जब कोई चलाता है

mount SRC DST -o bind,ro

3
हां लेकिन नहीं। IIRC में अलग-अलग विकल्प रखने के लिए अलग-अलग आरोह बिंदु (फाइलसिस्टम नहीं) के लिए कर्नेल में कुछ समर्थन है । डेबियन के पास एक पैच हुआ करता था mount -o bind,roजो एक रीड-राइट फाइलसिस्टम का केवल-पढ़ने का दृश्य बनाता था (लेकिन यह अब मट्ठे में नहीं लगता है)।
गिल्स एसओ- बुराई को रोकें '

मैं यह नहीं देखता कि यह उपरोक्त कैसे विरोधाभासी है। भाड़े सभी प्रकार के सामान की अनुमति दे सकते हैं, जिसमें ऐसी चीजें शामिल हैं जो बहुत अधिक समझ में नहीं आती हैं। वर्तमान में केवल 3.14 कर्नेल पर रीड-ओनली रिमाउंट को अंततः इस कॉल द्वारा नियंत्रित किया जाता है: mnt_make_readonly (real_mount (mnt)), जिसे आप real_mount () का उपयोग करते हुए देख सकते हैं, इसलिए यह वास्तविक माउंट को प्रभावित कर सकता है और जिसके कारण बाइंड mounts नए को प्रतिबिंबित करता है। (रीड-ओनली) माउंट फ्लैग। कम से कम मेरी समझ तो यही है।
V13

तो यह "स्प्रेड स्ट्रक्चर माउंट" पैच (विशेषकर यह कमिट ) का परिणाम होगा, जो पहले कर्नेल 3.3 में दिखाई दे रहा है। क्या आप जानते हैं कि इस पैच के परिणामों की चर्चा lkml या lwn पर की गई थी?
गिल्स एसओ- बुराई पर रोक '

7
mount --bind /tmp/ /mnt/tmp/; mount -o remount,bind,ro /mnt/tmp/... तो touch /tmp/aठीक है, लेकिन touch /mnt/tmp/bदेता है touch: cannot touch ‘/mnt/tmp/b’: Read-only file system। यह डेबियन 3.13 और kernel.org 3.14.2 दोनों पर काम करता है। तो यह सिर्फ पूरे माउंट को नहीं बदलता है। कम से कम हाल की गुठली के साथ तो नहीं।
derobert

1
संभवत: यह कथन कि "बिंद माउंट है ... ठीक है ... बाइंड माउंट।" वास्तव में महत्वपूर्ण है, लेकिन मेरे लिए कुछ भी नहीं है। मुझे यह भी समझ में नहीं आता कि यह दूसरी बार रिमाउंट विकल्प के साथ क्यों काम करता है।
स्ट्रांगबैड

9

उचित समाधान वास्तव में इसे दो बार माउंट करने के लिए है। कमांड लाइन पर:

mount -t none -o bind /source/dir /destination/dir
mount -t none -o bind,remount,ro /source/dir /destination/dir

इन /etc/fstab:

/source/dir            /destination/dir    none  bind            0 0
/source/dir            /destination/dir    none  remount,bind,ro 0 0

मैनुअल ( man mount) इसे इस तरह बताता है:

   The bind mounts.
          Since Linux 2.4.0 it is possible to remount part of the file hierarchy somewhere else. The call is
                 mount --bind olddir newdir
   [...]
          Note that the filesystem mount options will remain the same as those on the original mount point, and cannot be changed  by  passing  the  -o  option
          along with --bind/--rbind. The mount options can be changed by a separate remount command, for example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro newdir
          .
          Note  that  behavior  of  the remount operation depends on the /etc/mtab file. The first command stores the 'bind' flag to the /etc/mtab file and the
          second command reads the flag from the file.  If you have a system without the /etc/mtab file or if you explicitly define source and target  for  the
          remount command (then mount(8) does not read /etc/mtab), then you have to use bind flag (or option) for the remount command too. For example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro,bind olddir newdir

यह कम से कम Ubuntu 14.04 LTS और कर्नेल 3.19.0-51-न्यूनता के साथ काम करने लगता है। अच्छा!
मिकको रेंटालिनेन

0

आप mount(8)कमांड लाइन के दृष्टिकोण से पूछ रहे हैं (जो इस साइट पर स्वीकार्य है)। उस आदेश पर अन्य उत्तरों में चर्चा की गई है और कुछ मामलों में, एब्सट्रैक्ट आवश्यक दूसरी mount(2)प्रणाली कॉल को दूर करता है ।

लेकिन दूसरी प्रणाली कॉल की आवश्यकता क्यों है? mount(2)केवल एकल कॉल रीड-ओनली बाइंड माउंट क्यों नहीं बना सकता है?

mount(2)आदमी पेज बताते हैं, हैं कि के रूप में अन्य लोगों ने बताया है, दो सेट झंडे सेट होने का:

  • अंतर्निहित फ़ाइल सिस्टम झंडे
  • VFS माउंट-पॉइंट फ्लैग

इसे कहते हैं:

चूंकि लिनक्स 2.6.16, MS_RDONLYप्रति-माउंट-बिंदु के साथ-साथ अंतर्निहित फाइल सिस्टम पर सेट या क्लियर किया जा सकता है। माउंटेड फाइल सिस्टम केवल लिखने योग्य होगा, न तो फाइलसिस्टम और न ही माउंटपॉइंट को केवल-पढ़ने के लिए चिह्नित किया गया हो।

और के बारे में MS_REMOUNT:

लिनक्स 2.6.26 के बाद से, इस ध्वज का उपयोग MS_BINDकेवल प्रति-माउंट-पॉइंट झंडे को संशोधित करने के लिए किया जा सकता है । यह अंतर्निहित फ़ाइल सिस्टम को बदलने के बिना माउंट बिंदु पर "रीड-ओनली" झंडे को स्थापित करने या साफ़ करने के लिए विशेष रूप से उपयोगी है। माउंटफ्लैग को इस प्रकार निर्दिष्ट करना:

      MS_REMOUNT | MS_BIND | MS_RDONLY

अन्य आरोह बिंदुओं को प्रभावित किए बिना, केवल इस आरोह-अवरोह के माध्यम से पहुँच बनाएगा।

मुझे लगता है कि समस्या के बारे में आया था जब बाइंड माउंटों को पहली बार पेश किया गया था:

यदि माउंटफ्लैग्स में MS_BIND(लिनक्स 2.4 के बाद से उपलब्ध) शामिल है, तो एक बाइंड माउंट करें। ... माउंटफ्लैग तर्क में शेष बिट्स को भी अनदेखा किया जाता है, इसके अपवाद के साथ MS_REC। (बाइंड माउंट में अंतर्निहित माउंट बिंदु के समान माउंट विकल्प हैं।)

ऐसा लगता है कि, MS_BIND | MS_REMOUNTकेवल VFS झंडे को सेट करने के लिए सिग्नल के रूप में उपयोग करने के बजाय , वे MS_RDONLYप्रारंभिक के साथ (और स्वीकार) को छोड़कर MS_BINDमाउंट बिंदु पर लागू कर सकते थे।

तो mount(2)सिस्टम कॉल के कुछ अजीब शब्दार्थों के कारण :

  • पहला कॉल बाइंड माउंट बनाता है और अन्य सभी झंडों को अनदेखा किया जाता है
  • दूसरा कॉल (रिमाउंट के साथ) माउंट-पॉइंट फ्लैग को केवल पढ़ने के लिए सेट करता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.