Назад | Перейти на главную страницу

Как запретить квоте Linux дважды подсчитывать bind-mounts

Если вы работаете на компьютере с Linux и у вас есть файловая система с активированной пользовательской квотой, вы можете проверить следующие команды: quotacheck подсчитывает файлы несколько раз, если к ним можно получить доступ через привязку (если источник и цель этих привязок находятся в файловой системе, которая quotacheck посещений):

# we assume /home has active user-quota
repquota /home # check used quota before changes
mkdir /home/test_user/dir
mkdir /home/other_dir
mount -o bind /home/test_user/dir /home/other_dir
head -c1000000 /dev/urandom > /home/test_user/dir/test
chown test_user /home/test_user/dir/test
repquota /home # repquota now reports 1000000 bytes more for test_user
# umount /home/test_user/dir # possible solution
quotaoff -a
quotacheck -vuam
quotaon -a
# mount -o bind /home/test_user/dir /home/other_dir # possible solution
repquota /home # repquota now reports 2000000 bytes more for test_user

Единственное решение, которое я могу придумать, - это umount все подключаемые к привязке каталоги перед выполнением quotacheck и потом снова смонтировать их. Есть ли другие решения? Удаление usrquota-option из подключенных к связыванию каталогов, похоже, не работает (не удивлен, не беспокойтесь об этом). И исключая некоторые каталоги из посещения quotacheck кажется невозможным (справочная страница не упоминает ни одной соответствующей опции). Кстати, я тестировал это на Debian 8 (ядро 3.16.0, квота 4.01).

Разъяснение: Кроме креплений, все, что находится под /home принадлежит одной файловой системе.

Оказывается, в quotacheck была ошибка. Я отправил патч, чтобы исправить это, но понятия не имею, когда (и даже если) будет опубликована новая версия квоты, включая этот патч. Непосредственно прикрепить файлы к моему ответу не представляется возможным, поэтому я не буду размещать здесь патч. Но если кому-то интересно, оставьте комментарий, и я выложу патч в виде блока кода.

РЕДАКТИРОВАТЬ: Мой патч не был принят, потому что он не имел никакого отношения к делу. quotacheck уже может правильно работать при наличии bind-mounts при компиляции с EXT2_DIRECT вариант и используется в файловых системах ext. К сожалению, ошибка помешала этому работать с файловыми системами ext4, которые автор исправил (зафиксируйте 2b3795805c8d1bd8873b046508777fa6e9a5c83d в git: //git.code.sf.net/p/linuxquota/code).

У вас очень интересная проблема. Похоже, для quotacheck игнорировать каталоги. Вероятно, вам нужно будет изменить задание quotacheck и запустить его для каждого тома, игнорируя привязанные. Вы можете получить список связанных томов с помощью findmnt с чем-то вроде:

findmnt | awk '$2 ~ /\[.*\]$/'

Так что, вероятно, ваша работа cron могла бы быть чем-то вроде

findmnt --noheadings --raw | awk '$2 !~ /\[.*\]$/ {print$1}'  | while read FS ; do quotacheck -vum $FS ; done

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

Оказывается, текущий стабильный Debian (stretch) тоже страдает от этой ошибки. К счастью, пакет quota легко перекомпилировать и исправить:

# follow this tutorial: https://wiki.debian.org/BuildingTutorial#Rebuild_without_changes

apt-get source quota
apt-get build-dep quota
apt-get install devscripts
cd quota-4.03/

# this package uses "quilt" for patches, follow a different tutorial for "quilt":
#   https://wiki.debian.org/UsingQuilt#Using_quilt_with_Debian_source_packages

export QUILT_PATCHES=debian/patches
export QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
quilt push -a
quilt new quotacheck_ext4_direct.diff
quilt add quotacheck.c
vi quotacheck.c
    # https://marc.info/?l=fedora-extras-commits&m=147878735423631&w=2
    # add "!strcmp(mnt->me_type, MNTTYPE_EXT4)"
quilt refresh
quilt pop -a

# return to the original tutorial: https://wiki.debian.org/BuildingTutorial#Rebuild_without_changes

dch -n # enter something in the changelog
debuild -b -uc -us

Файл diff должен выглядеть так:

$ cat debian/patches/quotacheck_ext4_direct.diff

Index: quota-4.03/quotacheck.c
===================================================================
--- quota-4.03.orig/quotacheck.c
+++ quota-4.03/quotacheck.c
@@ -959,7 +959,7 @@ Please stop all programs writing to file
 start_scan:
        debug(FL_VERBOSE | FL_DEBUG, _("Scanning %s [%s] "), mnt->me_devname, mnt->me_dir);
 #if defined(EXT2_DIRECT)
-       if (!strcmp(mnt->me_type, MNTTYPE_EXT2) || !strcmp(mnt->me_type, MNTTYPE_EXT3) || !strcmp(mnt->me_type, MNTTYPE_NEXT3)) {
+       if (!strcmp(mnt->me_type, MNTTYPE_EXT2) || !strcmp(mnt->me_type, MNTTYPE_EXT3) || !strcmp(mnt->me_type, MNTTYPE_NEXT3) || !strcmp(mnt->me_type, MNTTYPE_EXT4)) {
                if ((failed = ext2_direct_scan(mnt->me_devname)) < 0)
                        goto out;
        }

Наконец, вы устанавливаете новый пакет, используя dpkg -i и принудительный пересчет квоты.