Существующий каталог необходим в качестве точки монтирования .
$ ls
$ sudo mount /dev/sdb2 ./datadisk
mount: mount point ./datadisk does not exist
$ mkdir datadisk
$ sudo mount /dev/sdb2 ./datadisk
$
Я нахожу это сбивающим с толку, поскольку он перекрывает существующее содержимое каталога. Существует два возможных содержимого каталога точек монтирования, которые могут неожиданно переключиться (для пользователя, который не выполняет монтирование).
Почему не mount
попадает во вновь созданный каталог? Именно так графические операционные системы отображают сменные носители. Было бы ясно, если каталог смонтирован (существует) или не смонтирован (не существует). Я уверен, что есть веская причина, но я пока не смог ее обнаружить.
udisksctl
. Зачем использоватьmount
?better design than Unix!
[необходима цитата]Ответы:
Это случай утечки деталей реализации.
В системе UNIX каждый каталог состоит из списка имен, сопоставленных с номерами inode . Inode содержит метаданные, которые сообщают системе, является ли это файл, каталог, специальное устройство, именованный канал и т. Д. Если это файл или каталог, он также сообщает системе, где найти содержимое файла или каталога на диске. Большинство инодов являются файлами или каталогами.
-i
Вариантls
список будет номера индексных дескрипторов.Монтирование файловой системы берет индексный каталог и устанавливает флаг в копии ядра в памяти, чтобы сказать «на самом деле, при поиске содержимого этого каталога вместо этого смотрите на эту другую файловую систему» (см. Слайд 10 этой презентации ). Это относительно просто, так как это изменение одного элемента данных.
Почему он не создает запись каталога для вас, указывая вместо этого на новый индекс? Это можно реализовать двумя способами, оба из которых имеют свои недостатки. Один из них - физически записать новый каталог в файловую систему, но это не даст результатов, если файловая система доступна только для чтения! Другой - добавить в каждый процесс листинга каталога список «лишних» вещей, которых на самом деле нет. Это неудобно и может привести к небольшому снижению производительности при каждой файловой операции.
Если вам нужны динамически созданные точки монтирования,
automount
система может сделать это. Специальные файловые системы без диска могут также создавать каталоги по желанию, напримерproc
,sys
,devfs
и так далее.Изменить: см. Также ответ на вопрос « Что происходит, когда вы« монтируете »существующую папку с содержимым?
источник
sudo mount --bind / /mnt ; ls /mnt/proc
-> пусто. Интересно, как это работает.fs/namespace.c
, я думаю; Я не знаком с источником и не хотел тратить слишком много времени на детализацию. «Флаг на иноде» я получил из связанной презентации./var/cache
какое-то время, когда/var
не удалось смонтировать.) Смотрите такжеpath_resolution(7)
. (У старых linux-manpages эта страница руководства была в разделе 2, как die.net) IDK, как Linux на самом деле работает внутри, чтобы оптимизировать проверку каждого компонента каталога как возможного монтирования. Может быть, прикрепить эту запись VFS в кэш?fs/namei.c
(путь -> поиск по индоду) вызывает в namespace.c хотяlookup_mnt()
. На dentry есть флаг (запись в кэше каталога). Но это всего лишь оптимизация, известная как реализация. Он не говорит вам, какая файловая система там смонтирована; Вы должны посмотреть в таблице монтирования. (См. M_hash (), для более подробной информации о реализации. Linux, по крайней мере, избегает дополнительных сравнений строк, и AFAICS в то же время удается повторно использовать dentry, например, для bind mounts, потому что он написан мастерами).man 8 mount
::mount --bind foo foo
.mount
Вызов bind присоединяет (частично) только одну файловую систему, а не возможные дополнительные монтирования. Вся файловая иерархия, включаяmount --rbind olddir newdir
Если в качестве точки монтирования
mount(2)
требовалось создать новый каталог, вы не могли монтировать что-либо в файловой системе только для чтения. Это было бы глупо, поэтому мы можем исключить это.Если mount при необходимости создает новый каталог для точки монтирования, это будет странно. Это не так, как монтирование / размонтирование происходит постоянно, поэтому добавление дополнительной логики в ядро для выполнения этих двух шагов с помощью одного системного вызова не будет важным ускорением. Просто оставьте это в пользовательском пространстве, чтобы сделать
mkdir(2)
системный вызов, если он этого хочет. В ответе Дмитрия указывается, чтоmount(2)
выполнение обоих этих действий сделает его неатомарным. И вы хотите дополнительный аргументmount(2)
с режимом флагов , какopen(2)
требуется, дляO_CREAT
,O_EXCL
и т.д. Это будет просто глупо по сравнению с позволяя пользовательское пространства сделать это.Или, может быть, вы спрашивали о том, чтобы
mount(8)
(традиционная программа,mount(2)
выполняющая системные вызовы) это делала? Это было бы возможно, но это уже идеально подходитmkdir(1)
для этой работы, а дизайн Unix - это хорошие небольшие инструменты, которые можно комбинировать. Если вам нужен инструмент, который выполняет обе функции, то легко написать сценарий оболочки, чтобы построить этот инструмент из двух более простых инструментов. (Или, как прокомментировал muru, этоudisksctl
уже сделано , поэтому вам не нужно его писать.) Кроме того, обычный Linuxmount(8)
из util-linux поддерживаетmount -o x-mount.mkdir[=mode]
использование своегоx-
синтаксиса для параметров для пользовательского пространства, а не для параметров, передаваемых в файловую систему.Теперь более интересный вопрос: почему в родительской файловой системе вообще должен быть каталог?
Как указывает ответ pjc50 (никакого отношения, даже если у него есть мои инициалы!), Отображение точек монтирования в списках каталогов потребует дополнительной проверки для каждого
readdir()
.Наличие точек монтирования существует в виде каталогов в директории, содержащей их (на родительской FS), это хороший трюк.
readdir()
не должен заметить, что это точка монтирования вообще. Это происходит только в том случае, если точка монтирования используется в качестве компонента пути. Разумеется, разрешение пути должно проверять таблицу монтирования для каждого компонента каталога пути.источник
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 dumb
- Я бы сказал, что это умнее: с точки зрения пользователя, файловая система,ro
. Существует много вариантов использования файловых систем только для чтения, где ваш аргумент не имеет смысла.man 8 mount
:x-mount.mkdir[=mode]
Позвольте сделать целевой каталог (MOUNTPOINT). Необязательный аргумент mode определяет режим доступа к файловой системе, используемыйmkdir(2)
в восьмеричной записи. Режим по умолчанию - 0755. Эта функция поддерживается только для пользователей root./tmp
и записи и/home
. Или только для чтения NFS-монтируется/usr
с локальным/usr/local
монтируется на нем. Или, в более общем смысле, любое общее изображение только для чтения с изменяемой частью, установленной поверх него. (Локальные моды для образа только для чтения также можно создавать для каждого файла с помощью пользовательских файловых систем, таких как overlayfs или другие объединенные файловые системы для Linux, используемые в загрузочных образах LiveCD.) Сначала я думал о корневой FS, изначально смонтированной RO, в загрузиться, но сделать это можно раньше других монтировок.Монтирование в существующий каталог делает вызов
mount
практически атомарным: он либо успешно, либо неудачно, по крайней мере, с точки зрения пользователя. Если быmount
пришлось создавать саму точку монтирования, у него было бы две точки отказа, что делало невозможным гарантированный чистый откат. Представьте себе следующий сценарий:mount
успешно создает точку монтированияmount
пытается смонтировать новую файловую систему в этот каталог, но не удаетсяmount
пытается удалить точку монтирования, но не удаетсяСистема заканчивается побочным эффектом отказа
mount
.Вот еще один:
umount
успешно размонтирует файловую системуumount
пытается удалить точку монтирования, но не удаетсяТеперь должен
umount
вернуть успех или неудачу?источник
mount
имеет 8 различных кодов возврата для ошибок, которые также могут быть объединены. Он может просто добавить еще один, когда удалить каталог не удается. man7.org/linux/man-pages/man8/mount.8.html#RETURN_CODESmount
системный вызов не создает его. Хотя, возможно, это была только моя интерпретация / ожидание того, что я думал, что ОП хотел спросить, или то, что я бы спросил, если бы я спрашивал.Еще один случай, который может произойти:
При загрузке базовый образ только для чтения загружается в корневой каталог. Таким образом, вы хотели бы переопределить его, когда вы хотите найти настоящий корень. Таким образом, вы можете себе представить, что системный вызов mount просто меняет точку
ro
монтирования наrw
.Давайте представим, что у вас проблема с файловой системой в корневой точке монтирования, и вы хотели бы попытаться исправить ее. С помощью mount overlap вы можете размонтировать файловую систему и использовать
fsck
предоставленный базовый образ для ее решения.Эта функция также может быть полезна в системах, которые нуждаются в строгой защите, чтобы отслеживать изменения между
ro
разделами и разделамиrw
.источник
mount
необходимости создания нового каталога в месте точки монтирования вы не можете ничего монтировать поверх файловой системы только для чтения? Первый абзац сбивает с толку: Linux initrd работает не так. Он используетpivot_root
системный вызов для изменения корневого fs, а не только для монтирования поверх него большего количества вещей. Это затрудняло следование вашей логике в следующих параграфах, потому что я думал, что вы говоритеpivot_root(2)
.pivot_root
а затемumount
и виртуальный диск. Но initramfs - это rootfs: вы не можете ниpivot_root
rootfs, ни размонтировать его . Вместо этого удалите все из rootfs, чтобы освободить пространство (find -xdev / -exec rm {} \;
), перемонтируйте rootfs с новым root (cd /newmount; mount --move . /; chroot .
), присоедините stdin / stdout / stderr к новой / dev / console иexec
новойinit
Я тоже всегда удивлялся этому.
Простая обертка, такая как:
сохраненный как исполняемый скрипт, названный
mount
в директории, переопределяющей/bin
в вашем PATH, должен позаботиться об этом, если это слишком беспокоит вас(Перед запуском фактического
mount
двоичного файла он создает каталог с именем после последнего аргументаmount
, если такой каталог еще не существует.)В качестве альтернативы, если вы не хотите, чтобы неудачные вызовы
mount
оболочки создавали каталоги, вы можете сделать:источник
mount
команда не должна использовать созданный каталог?mount /dev/foo /some/path
? Я предполагал, что это будет работать так, какudisksctl
работает, поэтому вы будете бежатьmount /dev/foo
.eval
расширения$#
, используя"${@:-1}"
. Я протестировал это с DASH, так как я думаю, что он не поддерживает ничего, кроме того, что требуется для поддержки POSIX sh./bin/dash -c 'echo ${@:-1}' foo bar
отпечаткиbar
.man -o x-mount.mkdir
...