Что происходит, когда вы «монтируете» существующую папку с содержимым?

80

Прямо сейчас /tmpесть некоторые временные файлы в нем. Когда я креплю свой жесткий диск ( /dev/sdc1) сверху /tmp, я вижу файлы на жестком диске. Что происходит с фактическим содержимым /tmpмоего жесткого диска? Можно ли выполнять операции чтения / записи с фактическим содержимым, /tmpпока жесткий диск установлен?

python@lanix / $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       286G   43G  229G  16% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            3.8G  4.0K  3.8G   1% /dev
tmpfs           766M  1.4M  765M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            3.8G   38M  3.8G   1% /run/shm
none            100M   24K  100M   1% /run/user
/dev/sdb1       7.5G  2.7G  4.9G  35% /mnt
/dev/sdc1       932G  242G  691G  26% /tmp
пользователь
источник

Ответы:

117

Что происходит с фактическим содержимым / tmp, когда мой жесткий диск смонтирован?

Почти ничего. Они просто скрыты от глаз, недоступны при обычном обходе файловой системы.

Можно ли выполнять операции чтения / записи с фактическим содержимым / tmp во время монтирования жесткого диска?

Да. Процессы с открытыми файловыми дескрипторами внутри вашего «оригинала» /tmpбудут продолжать использовать их. Вы также можете сделать «вновь появиться» где-то еще, прикрепив привязку в /другом месте.

# mount -o bind / /somewhere/else
# ls /somewhere/else/tmp  

Вот небольшой эксперимент, который вы можете провести, чтобы лучше (надеюсь) почувствовать происходящее.

Примечание: это не попытка быть совершенно правильной или исчерпывающее описание того, что на самом деле происходит. Должно быть достаточно точным, чтобы дать вам общую картину.

Я создал пользователя с именем meна моей машине и случайный каталог в его доме с файлом в нем:

me@home $ pwd
/home/me/tmp
me@home $ echo hello > some_file
me@home $ ls  
some_file
me@home $ cat some_file 
hello

На данный момент ничего необычного - это просто каталог с простым файлом. Я оставляю эту сессию открытой прямо как есть, cwdвнутри этой тестовой директории.

В качестве пользователя root я создаю небольшую файловую систему и монтирую ее поверх /home/me/tmp.

root@home # dd if=/dev/zero of=./fs bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00467318 s, 2.2 GB/s

root@home # mkfs -t ext2 ./fs 
mke2fs 1.42.12 (29-Aug-2014)
[... snip ...]
Writing superblocks and filesystem accounting information: done

root@home # mount ./fs /home/me/tmp

Затем я открываю новый терминал meи смотрю вокруг:

me@home #2 $ cd tmp
me@home #2 $ ls
lost+found
me@home #2 $ cat some_file
cat: some_file: No such file or directory
me@home #2 $ echo bye bye > some_file
-su: some_file: Permission denied

Итак, тот файл, который мы создали, явно не там. lost+foundКаталог является показателем корня из внутр файловой системы. И я потерял разрешение на запись, так что это явно не оригинальная директория.

Вернемся к первой meсессии, давайте посмотрим, как она видит мир:

me@home $ echo something else > other_file

Нет проблем с написанием.

me@home $ cat some_file other_file 
hello
something else

Оригинальный файл все еще там, новый файл создан без проблем.

А? В чем дело?

Первый сеанс вошел в каталог до того, как он был наложен корневым подключением другой файловой системы. Это действие монтирования никак не влияет на исходную файловую систему. Процесс оболочки имеет совершенно правильный дескриптор каталога в исходной файловой системе и может продолжать взаимодействовать с ним. Это своего рода бегают под на ковер точки монтирования.

Второй сеанс вошел в каталог после установки монтирования. Таким образом, он видит новую, пустую файловую систему. И системный администратор заблокировал разрешения, поэтому он не может использовать запрошенное пространство ... давайте исправим это.

root@home # chown me:users /home/me/tmp
me@home #2 $ echo bye bye > some_file
me@home #2 $ ls 
lost+found  some_file
me@home #2 $ cat some_file 
bye bye

Может ли сессия 1 сбежать из-под коврика? (Становится затхлым.)

Конечно! Если сеанс 1 перемещается обратно вверх по дереву файловой системы из монтирования, он потеряет этот дескриптор во внутренней части и будет следовать за монтированием, как и все остальные.

me@home $ cd
me@home $ pwd
/home/me
me@home $ cd tmp
me@home $ cat some_file other_file
bye bye
cat: other_file: No such file or directory

То же, что и в сеансе №2, мы вернулись к нормальной жизни.

Но как вы узнали, что файлы не исчезли? Никто не смотрит больше!

Это один из моментов, когда привязные крепления становятся удобными. Они позволяют вам монтировать уже смонтированную файловую систему где-то еще.

me@home $ mkdir ~/bind
root@home # mount -o bind /home/me /home/me/bind

(Да, вы можете связать и смонтировать файловую систему «внутри себя». Прикольный трюк, а?)

me@home $ ls bind/tmp
other_file  some_file
me@home $ cat bind/tmp/*
something else
hello

Так что они действительно там, готовы к действиям. Просто они не видны / недоступны в исходном местоположении, монтирование скрывает их от обычного обхода каталога.


Я призываю вас поиграть с этим, это действительно не сложно, если вы поняли «трюк», который разыгрывается. И как только вы получили это, загляните в объединенные файловые системы для еще большего увеличения ковра :-)

Одно замечание: монтирование поверх /tmpили /var(или любого из основных каталогов ОС) действительно не очень хорошая идея после завершения процесса загрузки. Многие приложения оставляют состояние в этих каталогах и могут серьезно запутаться, если вы играете в игры с ними.

Мат
источник
4
Это отличный ответ - вы вышли за пределы того, что я от вас просил. Идея bind-mount тоже очень крутая! Спасибо за подробный ответ. Приветствия.
пользователь
11
Это очень распространенный способ загадочно потерять место на диске. Если монтирование завершается неудачно по какой-либо причине в скрипте запуска, данные могут быть записаны в каталог в корневой файловой системе. Если затем попытаться перезапустить, монтирование может быть успешным, и, возможно, никто не заметит (например, если файловая система содержит файлы или журналы tmp), за исключением того, что она будет занимать место, может быть, много.
Дэн Шеппард
2
@DanSheppard Это одна из причин, по которой мне нравятся мои точки монтирования, установленные chmod 000. Кроме того, почему systemd не запускается при загрузке критических монтирований.
Зан Рысь
Не могли бы вы также -bind смонтировать /home/meна /home/meвместо папки «привязки»? Т.е. положить другой ковер поверх ковра. Или вам придется fsсначала размонтировать ?
jiggunjer
@jiggunjer Кажется, unionвариант может помочь.
hliu