Автоматическое монтирование fstab и systemd

Пользовательские пространства имен

В листинге 1 приведена часть кода модуля PAM (pluggable authentication module, подключаемого модуля авторизации), который предоставляет каждому пользователю, кроме root, обособленное пространство имен. Если директория /tmp/priv/USER существует, то она будет смонтирована с помощью bind на директорию /tmp в пользовательском пространстве имен.

Листинг 1. Часть кода PAM с настройкой пространства имен для сеанса пользователя
#define DIRNAMSZ 200
int handle_login(const char *user)
{
        int ret = 0;
        struct stat statbuf;
        char dirnam;

        if (strcmp(user, "root") == 0)
                return PAM_SUCCESS;

        ret = unshare(CLONE_NEWNS);
        if (ret) {
                mysyslog(LOG_ERR, "failed to unshare mounts for %s\n", user);
                return PAM_SESSION_ERR;
        }

        snprintf(dirnam, DIRNAMSZ, "/tmp/priv/%s", user);
        ret = stat(dirnam, &statbuf);
        if (ret == 0 && S_ISDIR(statbuf.st_mode)) {
                ret = mount(dirnam, "/tmp", "none", MS_BIND, NULL);
                if (ret) {
                        mysyslog(LOG_ERR, "failed to mount tmp for %s\n", user);
                        return PAM_SESSION_ERR;
                }
        } else
                mysyslog(LOG_INFO, "No private /tmp for user %s\n", user);
        return PAM_SUCCESS;
}

int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
                const char **argv)
{
        const char *PAM_user = NULL;
        char *fnam;
        int ret;

        ret = pam_get_user(pamh, &PAM_user, NULL);
        if (ret != PAM_SUCCESS) {
                mysyslog(LOG_ERR, "PAM-NS: couldn't get user\n");
                return PAM_SESSION_ERR;
        }

        return handle_login(PAM_user);
}
session   required   pam_ns.so

в /etc/pam.d/login и /etc/pam.d/sshd. После этого для какого-нибудь пользователя
создайте частный каталог tmp.

mkdir /tmp/priv
chmod 000 /tmp/priv
mkdir /tmp/priv/USER
chown -R USER /tmp/priv/USER

Теперь войдите на одном терминале как пользователь root, а на другом — как . Из сеанса работы пользователя попробуйте выполнить следующие команды:

touch /tmp/ab
ls /tmp

Вы можете заметить, что директория /tmp пользователя содержит единственный — только что созданный — файл.

Затем выведите список содержимого /tmp в терминале root; вы увидите, что в каталоге есть какие-то другие файлы, но нет /tmp/ab. Фактически существует два разных каталога /tmp. Чтобы найти каталог /tmp пользователя из терминала root, введите

ls /tmp/priv/USER

Вы увидите искомый файл ab. Теперь в терминале root, смонтируйте что-нибудь в /mnt:

mount --bind /dev /mnt
mount(8) и unshare(2)

Из страниц man Linux: Команда служит для присоединения файловой системы какого-либо устройства к основному дереву файловой системы. Системный вызов
позволяет вызывающему процессу заменять пространства имен для выбранных ресурсов копиями оригинального пространства имен. Подробнее: см. .

Заметим, что содержимое директории /dev появляется под /mnt в терминале root, но не в терминале . Деревья монтирования для этих двух терминалов полностью изолированы друг от друга. С помощью команды
вы можете управлять распространением монтирования. По умолчанию все объекты монтирования являются частными. Поэтому до входа в систему пользователя попробуйте следующую команду:

mount --make-rshared /

После этого объекты монтирования будут распространяться между пространствами имен, которые иначе были бы обособленными. Однако после входа в систему пользователя монтирование /tmp/priv/USER на /tmp не будет распространяться на родительское пространство имен. Чтобы изменить это, в pam_ns.so можно сделать файловую систему пользователя подчиненной, как показано в листинге 2.

Листинг 2. Модуль PAM с подчиненным пользовательским пространством имен
#define DIRNAMSZ 200
#ifndef MS_SLAVE
#define MS_SLAVE 1<<19
#endif
#ifndef MS_REC
#define MS_REC 0x4000
#endif
int handle_login(const char *user)
{
        int ret = 0;
        struct stat statbuf;
        char dirnam;

        if (strcmp(user, "root") == 0)
                return PAM_SUCCESS;

        ret = unshare(CLONE_NEWNS);
        if (ret) {
                mysyslog(LOG_ERR, "failed to unshare mounts for %s\n", user);
                return PAM_SESSION_ERR;
        }

        ret = mount("", "/", "dontcare", MS_REC|MS_SLAVE, ""));
        if (ret) {
                mysyslog(LOG_ERR, "failed to mark / rslave for %s\n", user);
                return PAM_SESSION_ERR;
        }

        snprintf(dirnam, DIRNAMSZ, "/tmp/priv/%s", user);
        ret = stat(dirnam, &statbuf);
        if (ret == 0 && S_ISDIR(statbuf.st_mode)) {
                ret = mount(dirnam, "/tmp", "none", MS_BIND, NULL);
                if (ret) {
                        mysyslog(LOG_ERR, "failed to mount tmp for %s\n", user);
                        return PAM_SESSION_ERR;
                }
        } else
                mysyslog(LOG_INFO, "No private /tmp for user %s\n", user);
        return PAM_SUCCESS;
}

Что такое /etc/fstab и зачем он нужен?

fstab — это текстовый файл, содержащий список механизмов хранения информации и параметры монтирования. Различные накопители, которые необходимо автоматически примкнуть во время загрузки операционной системы, по порядку перечисляются в файле fstab. Также в данном файле содержатся информация об устройствах, которые не присоединяются автоматически, но при выполнении монтирования приборы стандартной командой mount происходит присоединение устройства с заданными параметрами Это необходимо, к образцу, для CD/DVD-приводов, которые не примонтированы постоянно, а монтируются при наличии диска в приводе. fstab состоит из строчек. Каждая строка это устройство.

Символ решетки (#) в начале строки, как и во абсолютно всех Unix системах, обозначает комментарий и поэтому значимой строкой не считается. А теперь фактически к практике. Осталось только рассказать, как же устроен файл /etc/fstab и что в него надо строчить. Начну с того, что этот файл является системным, поэтому для его редактирования нужны преимущества root. Если вы забыли, как редактировать конфигурационные файлы системы, прочитайте снова заметку про права доступа. Каждому разделу винчестера отводится одна строка. Строчки, начинающиеся с знака решётки (#), являются комментариями и системой (множество элементов, находящихся в отношениях и связях друг с другом, которое образует определённую целостность, единство) игнорируются. Формат каждой записи весьма простой:

Помните, в статье про разметку диска я рассказывал, что разделы винчестера в Linux кликаются как sdaX (или sdbX, sdcX и т.д. если у вас несколько винчестеров). Так вот, в fstab используется несколько иной механизм идентификации винчестеров6). Для этой цели используются так называемые uuid, довольно длинные строчки из произвольных букв латинского алфавита и цифр7). Для того, дабы узнать uuid для нужного вам раздела выполните в терминале команду8)

Использование

Устройство /dev/cdrom монтируется в каталог /mnt/cdrom, если он существует.
Начиная от момента монтирования и пока пользователь не отмонтирует файловую систему (или туда не будет смонтировано что-то иное) в каталоге /mnt/cdrom будет содержаться дерево каталогов устройства /dev/cdrom; те файлы, и подкаталоги, которые раньше находились в /mnt/cdrom, сохранятся, но будут недоступны до размонтирования устройства /dev/cdrom.

Монтирование USB-дисков

Для распространённого случая, когда USB-диск имеет файловую систему FAT32, команда монтирования выглядит так:

Параметр codepage необходим, чтобы имена созданных файлов корректно отображались в старых ОС (например, DOS). Если дистрибутив использует в качестве кодировки системной локали не UTF-8, то её необходимо указать в параметре iocharset так:

Реально используемую кодировку можно определить, выполнив команду .

Полезными опциями при монтировании Flash-дисков являются и . Первая приводит к постоянному сбросу на диск буфера записи, так что данные не теряются при отсоединении flash-диска без размонтирования. Побочный эффект такого монтирования — значительное уменьшение в скорости записи. Вторая опция (доступна только в новых ядрах Linux) ведёт к сбросу буфера на диск после записи последнего файла. Это также способствует сохранению данных в случае удаления диска без размонтирования, но не приводит к падению скорости записи.

Монтирование образов дисков

Если имеется образ диска в виде iso-файла, то для его монтирования нужно указать параметр и, обычно, тип файловой системы (необязательно) ( — это имя файла образа, а  — точка монтирования):

Образы bin/cue

Для преобразования образа bin/cue в iso-образ можно воспользоваться конвертером bchunk:

Монтирование сетевых дисков SMB

Пример монтирования сетевых SMB-ресурсов :

(Утилита smbfs заменилась в ядре linux на совместимую с ней cifs.)
примечания:

«-t cifs» можно иногда не указывать, если имя монтируемого устойства вида «//server/dir»

если для авторизации необходимо указать доменное имя пользователя, то в параметрах команды mount оно указывается как «-o username=domain\\user», однако при указании монтируемого ресурса в /etc/fstab имя пользователя указывается как «domain/user»:

Модуль ядра Fuse (был принят в официальную ветку ядра начиная с 2.6) позволяет непривилегированным пользователям монтировать различные файловые системы.

Для работы необходимо добавить пользователя в группу fuse, сделать это можно вот так:

или

или вручную отредактировав файл /etc/group. Ещё необходимо, чтобы загружен был модуль ядра fuse:

После этого, можно смонтировать каталог другого компьютера с помощью sshfs:

Для отмонтирования нужно ввести команду:

Файл конфигурации

Основная статья: fstab

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

 # <fs>                  <mountpoint>    <type>          <opts>          <dump/pass>
 
 # NOTE: If your BOOT partition is ReiserFS, add the notail option to opts.
 #/dev/BOOT              /boot           ext2            noauto,noatime  1 2
 /dev/sda5               /               reiserfs        noatime         0 1
 /dev/sda1               none            swap            sw              0 0
 /dev/cdrom              /mnt/cdrom      iso9660         noauto,ro       0 0
 #/dev/fd0               /mnt/floppy     auto            noauto          0 0
 
 # NOTE: The next line is critical for boot!
 proc                    /proc           proc            defaults        0 0
 
 # glibc 2.2 and above expects tmpfs to be mounted at /dev/shm for
 # POSIX shared memory (shm_open, shm_unlink).
 # (tmpfs is a dynamically expandable/shrinkable ramdisk, and will
 #  use almost no memory if not populated with files)
 shm                     /dev/shm        tmpfs           nodev,nosuid,noexec     0 0

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

Другое назначения файла конфигурации — автоматическое монтирование файловых систем при загрузке системы. Если не требуется монтировать определённые файловые системы, то для них в файле конфигурации нужно указать параметр .

Создание массива RAID 10

Массив RAID 10 традиционно реализуется путем создания чередующегося массива RAID 0, состоящего из наборов массивов RAID 1. Вложение массивов дает как избыточность, так и высокую производительность за счет больших объемов дискового пространства. У утилиты mdadm есть собственный тип RAID 10, который обеспечивает те же преимущества с повышенной гибкостью. Он не создается путем создания вложенных массивов, но предлагает много тех же характеристик и гарантий. Здесь мы будем использовать mdadm RAID 10.

  • Требования: минимум 3 устройства хранения данных.
  • Главное преимущество: повышенная производительность и избыточность данных.
  • Следует иметь в виду: Объем уменьшения емкости массива определяется количеством копий данных, которые вы хотите сохранить. Количество копий, которые хранятся в массиве mdadm  RAID 10, можно настраивать.

По умолчанию две копии каждого блока данных будут храниться в так называемом макете «near». Здесь доступны следующие топологии, которые определяют, как хранится каждый блок данных:

  • near: топология по умолчанию. Копии каждого фрагмента записываются последовательно при чередовании; это означает, что копии блоков данных будут записаны примерно в одной и той же части нескольких дисков.
  • far: Первая и последующие копии записываются в разные части устройств в массиве. Например, первый фрагмент может быть записан рядом с началом диска, а второй фрагмент будет записан в середине на другом диске. Это может дать прирост производительности для традиционных дисков.
  • offset: Каждый фрагмент смещается на последующем диске. Это означает, что копии смещены, но все еще близко расположены. Это помогает минимизировать поиск во время обработки некоторых рабочих нагрузок.

Больше информации об этом типе RAID10 можно найти в справке:

Эту страницу можно также прочитать онлайн.

Определение устройств массива

Для начала нужно определить идентификаторы для неформатированных дисков, которые вы будете использовать:

Как вы можете видеть выше, у нас есть четыре диска без файловой системы, каждый размером 100G. В этом примере этим устройствам были присвоены идентификаторы /dev/sda, /dev/sdb, /dev/sdc и /dev/sdd для текущего сеанса. Это неформатированные компоненты, которые мы будем использовать для построения массива.

Создание массива

Чтобы создать массив RAID 10 из этих компонентов, передайте их команде mdadm —create. Вам нужно указать имя устройства, которое вы хотите создать (например, /dev/md0), уровень RAID и количество устройств:

Если вы хотите использовать другую топологию или изменить количество копий, вам нужно использовать параметр —layout =. Опция n определяет топологию near, f – far, а o – offset. После этого нужно указать количество копий.

Например, чтобы создать массив, который хранит 3 копии в топологии offset, нужно использовать команду:

Инструмент mdadm начнет настраивать массив (фактически по соображениям производительности он использует процесс восстановления для построения массива). Это может занять некоторое время, но в течение этого времени массив можно использовать. Вы можете отслеживать ход зеркалирования, проверяя файл /proc/mdstat:

В первой выделенной строке указано, что с помощью устройств /dev/sda, /dev/sdb, /dev/sdc и /dev/sdd было создано устройство /dev/md0 в конфигурации RAID 10. Вторая выделенная строка показывает топологию текущего массива (в данном случае это 2 копии и near). Третья строка отображает прогресс сборки. Вы можете продолжить работу в системе во время выполнения этого процесса.

Создание и монтирование файловой системы

Создайте в массиве файловую систему:

Создайте точку монтирования:

А затем смонтируйте файловую систему:

Убедитесь, что новое пространство доступно:

Сохранение топологии массива

Чтобы убедиться, что при загрузке сервера массив загружается автоматически, нужно отредактировать файл /etc/mdadm/mdadm.conf. Вы можете автоматически сканировать активный массив и добавить данные в файл:

После этого вы можете обновить initramfs, чтобы массив был доступен во время загрузки:

Добавьте новые параметры монтирования файловой системы в файл /etc/fstab для поддержки автоматического монтирования при загрузке:

Теперь массив RAID 10 будет автоматически смонтирован при загрузке системы.

Файл конфигурации

Основная статья: fstab

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

 # <fs>                  <mountpoint>    <type>          <opts>          <dump/pass>
 
 # NOTE: If your BOOT partition is ReiserFS, add the notail option to opts.
 #/dev/BOOT              /boot           ext2            noauto,noatime  1 2
 /dev/sda5               /               reiserfs        noatime         0 1
 /dev/sda1               none            swap            sw              0 0
 /dev/cdrom              /mnt/cdrom      iso9660         noauto,ro       0 0
 #/dev/fd0               /mnt/floppy     auto            noauto          0 0
 
 # NOTE: The next line is critical for boot!
 proc                    /proc           proc            defaults        0 0
 
 # glibc 2.2 and above expects tmpfs to be mounted at /dev/shm for
 # POSIX shared memory (shm_open, shm_unlink).
 # (tmpfs is a dynamically expandable/shrinkable ramdisk, and will
 #  use almost no memory if not populated with files)
 shm                     /dev/shm        tmpfs           nodev,nosuid,noexec     0 0

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

Другое назначения файла конфигурации — автоматическое монтирование файловых систем при загрузке системы. Если не требуется монтировать определённые файловые системы, то для них в файле конфигурации нужно указать параметр .

Заключение

Монтирование с использованием bind позволяет монтировать любой файл или каталог в любой другой. Поддержка пространств имен позволяет процессам получать собственные изолированные копии родительских деревьев монтирования. Распространение монтирования позволяет прежде изолированным копиям файловых систем обмениваться объектами монтирования в одном или обоих направлениях. Эти функции дают пользователям «квазичастные» копии деревьев монтирования, открывая при этом доступ к системным событиям вроде монтирования CD-ROM и допуская избирательное совместное использование с другими пользователями.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *