СЕРГЕЙ ЯРЕМЧУК, фрилансер. Автор более 800 статей и шести книг. С «СА» с первого номера. Интересы: сетевые технологии, защита информации, свободные ОС
Использование LVM
Рано или поздно, но это произойдёт. В один прекрасный солнечный день, когда хочется поваляться на пляже, введя команду df, обнаруживаешь, что места на сервере осталось всего ничего. Причём как ни стараешься правильно разбить диск при установке системы, но предугадать, какой из разделов потребует больше места, а какой меньше, удаётся очень редко. Если корневой раздел, /usr и /opt в большинстве своём сюрпризов не приносят, т.к. устанавливаемый софт контролируется самим сисадмином и обычно здесь применяется стандартный набор приложений. Каталог /tmp сейчас обычно отдают на откуп tmpfs – файловую систему в оперативной памяти. То с /var и /home обычно возни больше. Выходов в этой систуации может быть несколько.
Первый. Простой
Плюнуть на всё требования и поступить ещё при установке просто:
# parted /dev/hda mkpartfs primary linux-swap 0 256 && parted /dev/hda mkpartfs primary ext2 256 ###
т.е. использовать всего два раздела swap и всё оставшееся место отвести под корневой. Что тут сказать, пока диск не заполнится полностью, можно будет совсем не думать о наличии свободного/занятого места в разделах. Но это положительная сторона. А с другой стороны – производительность диска в таком случае будет не на высоте, особенно при большом заполнении. Плюс обязательно найдется кто-то, у кого дома много фильмов на дисках, и в один прекрасный день он решит их все принести на работу для демонстрации. Или кто-то «добрый» запишет большой файл в /tmp. После этого остановится всё, что требует места, например, почтовый сервер или syslog, которым просто некуда будет писать на диске данные.
Второй. Фашистский
Если места мало, его нужно расчистить:
# find /home ( -atime +365 -o -name "*.avi") -exec rm {};
т.е. если пользователь не удосужился заглянуть в файл в течение года, то он явно лишний (а будет кричать, то файл всегда найдется в бэкапе), плюс туда улетают и фильмы, работать надо на работе (здесь начальство даже похвалить может).
# find /home -size 200 > trash ; cat trash | less
Или просто посмотреть на те файлы, которые занимают много места.
Третий. Радикальный
Все данные резервируются, и диск переразбивается заново с учётом текущих обстоятельств, до возникновения новых. Должно помочь.
Четвертый. Софтварный
При помощи утилиты parted, гарантирующей сохранение данных, размеры разделов изменяются. Но, к великому сожалению, parted не работает с современными журналируемыми файловыми системами RaiserFS и XFS.
Пятый. Естественно, хардварный
Идём к шефу и говорим, что свободного места нет, и требуем новый жёсткий диск для сервера и повышения зарплаты для себя (чтобы два раза не бегать). Далее вставляем его в корпус, форматируем и монтируем, например, в /home/newhome и часть данных переносим на новый диск. Чтобы при этом некоторые старые файлы были доступны, из нового месторасположения необходимо воспользоваться символическими ссылками. К слову, в таком случае очень неплохо бы и на втором диске создать swap-раздел, а в файле /etc/fstab сделать запись о равенстве их приоритетов.
/dev/hda1 swap swap defaults,pri=1 0 0
/dev/hdc1 swap swap defaults,pri=1 0 0
Теперь всё пользовательское пространство будет состоять из двух файловых систем и придётся всё время помнить о том, на каком диске находятся данные и следить за их наполнением, но дополнительно ко всему отпадает возможность создания жёстких ссылок на данные, расположенные в другой файловой системе. Согласитесь, это несколько неудобно, гораздо лучше, чтобы оно выглядело как единое целое, пусть даже и не является таковым. И поэтому...
Вариант шестой
Предусмотреть возможное несоответствие размеров и возможное перепланирование рабочего пространства в будущем еще на стадии разбиения диска или, если уж произошло такое, то воспользоваться удобными современными технологиями. Для решения этой задачи в самый раз придется популярная технология LVM (Logical Volume Manager, или менеджер логических томов), которая полностью поддерживается Linux-ядром версии 2.4.
По понятиям
Давайте сначала немного разберёмся в терминологии и в том, что собственно происходит. Недавний ремонт вызывает у меня только строительные ассоциации, поэтому давайте представим жесткий диск в виде стены. Но стена неоднородная, она состоит из отдельных кирпичиков, т.е. физических разделов жёткого диска (physical media), все равно каких, первичных или логических разделов на расширенном. В терминологии LVM каждый кирпичик будет называться физическим томом PV (Physical Volume). Этому разделу при образовании присваивается определенный идентификатор типа файловой системы – 8e (например, программой fdisk). Сам Physical Volume образуется из неких элементарных единиц, называемых PE (physical extents). Будем считать, это тот песок, из которого состоят кирпичи. Это минимальный размер, с которым умеет обращаться VG и по умолчанию равен 4 Мб. Далее, чтобы на голый кирпич прицепить что-то более привлекательное для глаза, его сначала заштукатуривают, и теперь наша стена выглядит как одно большое целое. В терминологии LVM это называется группой томов VG (volume group), это главная часть, представляющая собой логическую надстройку над физическими разделами, некий банк дисковых ресурсов. Операционная система видит VG как единое целое, хотя фактически она состоит из нескольких реальных разделов жёсткого диска. Это можно представить (но только представить) как создание расширенного раздела при обычном разбиении. И теперь кладём плитку, т.е. нарезаем в получившемся VG разделы требуемых размеров (или не нарезаем, если в этом нет необходимости, т.е. сплошная стена вас вполне устраивает). Эти разделы называются логическими томами LV (logical volume). Такой раздел форматируется затем обычным образом под выбранную файловую систему, и драйвер ФС работает именно на этом уровне. Также, именно эти разделы монтирует пользователь и прописывает данные в /etc/fstab. В LVM (HOWTO), которое находится по адресу http://tldp.org/HOWTO/LVM-HOWTO, все это схематически отображено так:
Рисунок 1
Сам логический том также состоит из песчинок, называемых LE (logical extent), которые сопоставляются реальным физическим physical extents. Если в дальнейшем понадобится изменить размер logical volume, то это можно будет проделать как раз на величину, кратную physical extents. Такая взаимосвязь физических и логических extent обозначается термином mapping. И ещё, так как фактически нет разницы, какому PE противопоставить LE, то это можно сделать двумя вариантами – линейным (linear mapping) и чередующимся (striped mapping). В первом случае всё просто: непрерывной последовательности физических extent ставится в соответствие столь же непрерывная последовательность логических extent. Во втором – непрерывная последовательность логических extent связывается с чередующимися между различными физическими носителями extent. Эта схема напоминает нулевой (полосатый) RAID-массив. При этом если разместить два диска на различных IDE-каналах, можно добиться некоторого повышения производительности дисковых операций. Но надёжность в таком случае ниже, т.к. в случае вылета одного диска можно потерять всё. Поэтому бэкап в последнем случае играет не последнюю роль. И ещё не стоит смешивать в одной VG оба метода, если есть в этом необходимость, то для striped mapping создайте отдельную volume group. Как говорил один из моих преподавателей: «Природу не обманешь, за всё надо платить». Естественно, за удобства приходится расплачиваться, в нашем случае это 10-15% процессорной мощности. Причем перенос файловых систем с физического на логический уровень на скорости дисковых операций не отразился в linear случае.
От теории к практике
Теперь попробуем создать logical volume и подключить его как обычную файловую систему. Для начала давайте определимся, что не надо класть в LV. Так, нет особого смысла помещать туда каталог /boot, в котором содержится ядро и Grub. Его стоит вынести в отдельный раздел размером 50 Мб (с запасом) и в файле /etc/fstab прописать такие строки, чтобы он не автоматически монтировался при загрузке.
/dev/hda1 /boot ext2 noauto 1 2
Применять журналируемые файловые системы в этом случае смысла особого нет, а при смене ядра (довольно редкое занятие) данный каталог всегда можно примонтировать вручную. Также, наверное, не стоит помещать туда и следующие каталоги /etc, /proc, /lib, /mnt, /bin, /sbin, /dev, /root, swap и /tmp (хотя это всё относительно). Обычно состав их более-менее статичен и много места не занимает, так, корневой раздел в CRUX такого состава получился у меня всего навсего 300 Мб, остальное находится в /usr, /var и /home. При большом количестве внесистемного софта также следует вынести в отдельный каталог и /usr/local с /opt (я обычно делаю символическую ссылку ln -s /usr/local /opt, чтобы голову меньше ломать). Дополнительно ко всему у вас всегда будет возможность зайти в систему из-под root в случае аварийных обстоятельств. LVM можно использовать при наличии в системе и одного жёсткого диска, но наибольшую гибкость данная технология даёт при использовании двух и более дисков в системе. Для эксперимента возьмем два раздела /dev/hda4 и /dev/hdс2.
Рисунок 2
Общее распределение разделов на дисках будет таким:
- /dev/hda1 – /boot
- /dev/hda2 – swap (содержит и /tmp)
- /dev/hda3 – корневой (/etc, /proc, /lib, /mnt, /bin, /sbin, /dev, /root)
- /dev/hda4 – будет использован с LVM
- /dev/hdс1 – swap
- /dev/hdс2 – будет использован с LVM
Необходимый софт
В большинстве современных дистрибутивов, за исключением разве ориентированных на power user, всё необходимое для работы уже имеется. Так, например, программа установки Red Hat 9 позволяет создать LVM (и софт-RAID) в графическом режиме (рис. 2), но, если честно, мне она не показалась интуитивно понятной. Для поддержки технологии ядром при компиляции должны быть включены следующие опции. В секции Multi-device support (RAID and LVM) нужно включить поддержку самих Multiple devices и далее собственно менеджера логических томов (Logical volume manager (LVM) support).
Файл /usr/src/linux/.config должен содержать следующие строки:
#
# Multi-device support (RAID and LVM)
#
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_MULTIPATH is not set
CONFIG_BLK_DEV_LVM=y
Следующим шагом необходимо установить софт для работы с LVM (если его нет, конечно). В виде исходников его можно взять с сайта http://www.sistina.com. Установка заключается в стандартной компиляции (./configure && make; su; make install) и обычно проходит без сюрпризов. В результате получите три группы утилит, предназначенные для работы на «своём» уровне: pv* работает с физическими томами, lg* – с логическими группами и lv* – с логическими томами. Все их можно найти при помощи табуляции.
Так команды вида *create создают том или группу в зависимости от первых двух букв, *display выводит полную информацию и т. д.
Для начала создаём физические разделы с идентификатором 8е. Для примера взят второй диск.
# /sbin/fdisk /dev/hdс
Command (m for help): p
Disk /dev/hdс: 3243 MB, 3243663360 bytes
128 heads, 63 sectors/track, 785 cylinders
Units = cylinders of 8064 * 512 = 4128768 bytes
Device Boot Start End Blocks Id System
/dev/hdb1 1 20 168682+ 82 Linux swap
/dev/hdb2 21 785 3165088+ b Win95 FAT32
Command (m for help): t
Selected partition 2
Hex code (type L to list codes): 8e
Changed system type of partition 2 to 8e (Linux LVM)
Command (m for help): p
Disk /dev/hdс: 3243 MB, 3243663360 bytes
128 heads, 63 sectors/track, 785 cylinders
Units = cylinders of 8064 * 512 = 4128768 bytes
Device Boot Start End Blocks Id System
/dev/hdb1 1 20 168682+ 82 Linux swap
/dev/hdb2 21 785 3165088+ 8e Linux LVM
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
|
Теперь дисковые разделы превращаем в физический том, это своего рода форматирование, чтобы программы высшего уровня могли работать с ними. Причем если используется файловая система устройств devfs, то необходимо задавать полное имя в соответствии с принятым обозначением, т.е. что-то типа /dev/ide/host0/bus0/target0/lun0/part4, программы не распознают символических ссылок.
# /sbin/pvcreate /dev/hda4
pvcreate -- physical volume "/dev/hda4" successfully created |
# /sbin/pvcreate /dev/hdb2
pvcreate -- physical volume "/dev/hdb2" successfully created |
Теперь запускаем программу vgscan, которая отыщет всё разделы с идентификатором 8е и создаст конфигурационные файлы /etc/lvmtab и /etc/lvmtab.d.
# /sbin/vgscan
vgscan -- reading all physical volumes (this may take a while...)
vgscan -- "/etc/lvmtab" and "/etc/lvmtab.d" successfully created
vgscan -- WARNING: This program does not do a VGDA backup of your volume group
|
Дополнительно можно проверить, что думает о созданных физических томах система.
# /sbin/pvscan
pvscan -- reading all physical volumes (this may take a while...)
pvscan -- inactive PV "/dev/hda4" is in no VG [1.27 GB]
pvscan -- inactive PV "/dev/hdb2" is in no VG [3.02 GB]
pvscan -- total: 2 [4.29 GB] / in use: 0 [0] / in no VG: 2 [4.29 GB]
|
И теперь объединяем все в группу томов. Для этого вызывается команда vgcreate, в качестве аргументов принимающая условное имя будущей группы, которое может быть любым (кроме lvm), и разделы, которые будут включены в эту группу. Дополнительно при помощи опции -s ##m можно задать размер physical extent (в большинстве рекомендуют 32 Мб). По умолчанию создаётся линейный режим чередования. Если есть необходимость, в полосатом режиме используйте опцию -i, a -l # при этом задаст размер чередующихся блоков.
# /sbin/vgcreate -s 32 test /dev/hda4 /dev/hdb2
vgcreate -- INFO: maximum logical volume size is 2 Terabyte
vgcreate -- doing automatic backup of volume group "test"
vgcreate -- volume group "my" successfully created and activated
|
Обратите внимание на максимальный размер volume group, который в нашем случае равен 2 Тб, в варианте по умолчанию его значение равнялось бы 256 Гб.
Теперь pvscan сообщит, что тома активированы.
# /sbin/pvscan
pvscan -- reading all physical volumes (this may take a while...)
pvscan -- ACTIVE PV "/dev/hda4" of VG "test" [1.22 GB / 1.22 GB free]
pvscan -- ACTIVE PV "/dev/hdb2" of VG "test" [2.97 GB / 2.97 GB free]
pvscan -- total: 2 [4.29 GB] / in use: 2 [4.29 GB] / in no VG: 0 [0]
|
И теперь нарезаем большую VG на логические тома требуемых размеров. При этом нужно учитывать, что урезание файловой системы и затем логического тома (вот именно в два этапа) – немного более трудоёмкий процесс, чем увеличение. Дополнительно файловая система XFS пока не урезается. Поэтому лучше создать минимально требуемый размер логического тома (с запасом), а затем при необходимости его просто увеличить до нужного. Создаем. При этом при помощи -L указывается нужный размер, а при помощи -n имя и в конце следует имя VG. Если значение в килобайтах после него ставится K, в мегабайтах M и в гигабайтах G.
# /sbin/lvcreate -L 1G -n lvm_usr test && /sbin/lvcreate -L 1G -n lvm_home test
lvcreate -- doing automatic backup of "test"
lvcreate -- logical volume "/dev/test/lvm_usr" successfully created
lvcreate -- doing automatic backup of "test"
lvcreate -- logical volume "/dev/test/lvm_home" successfully created
|
Или для полосатости.
# lvcreate -n stripedlv -i 2 -I 64 mygroup -L 20M
Проверяем.
# /sbin/lvscan
lvscan -- ACTIVE "/dev/test/lvm_usr" [1 GB]
lvscan -- ACTIVE "/dev/test/lvm_home" [1 GB]
lvscan -- 2 logical volumes with 2 GB total in 1 volume group
lvscan -- 2 active logical volumes
|
Команда lvdisplay выдаст более подробную информацию. Обратите внимание на новое месторасположение вроде /dev/test/lvm_usr, именно с ними придется работать в дальнейшем.
Следующим шагом будет создание файловых систем на логических томах. Это делается обычным образом, как и для обычного дискового раздела, при этом может быть выбрана любая из поддерживаемых современным ядром файловых систем. Например, создадим ReiserFS:
# /sbin/mkfs.reiserfs /dev/test/lvm_home
И монтируем в выбранное место.
# mkdir /home/test
# mount -t reiserfs /dev/test/lvm_home /home/test
# df
/dev/hda3 4032124 2789108 1038188 73% /
...
/dev/test/lvm_home 1048540 32840 1015700 4% /home/test
|
Для автоматического монтирования раздела при загрузке системы в /etc/fstab добавляем следующие строки:
/dev/test/lvm_home /home/test reiserfs defaults 0 0
Чтобы система при загрузке могла обнаружить LVM, необходимо, чтобы в стартовых скриптах присутствовали две команды (для различных дистрибутивов примеры смотрите в HOWTO).
/sbin/vgscan
/sbin/vgchange -ay
В RedHat 9 в /etc/rc.d/rc.sysinit все это прописано такими строками:
# LVM initialization
if [ -f /etc/lvmtab -a ! -e /proc/lvm ] ; then
modprobe lvm-mod >/dev/null 2>&1
fi
if [ -e /proc/lvm -a -x /sbin/vgchange -a -f /etc/lvmtab ]; then
action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -ay
fi
И для размонтирования при остановке системы должна выполниться команда (/etc/rc.d/init.d/halt):
/sbin/vgchange -an
Изменение размеров раздела
Теперь давайте попробуем изменить размер раздела. ReiserFS можно при этом не размонтировать. Для изменения размера логического тома используется команда lvextend, в качестве параметров принимающая новый размер или число (положительное или отрицательное), на которое необходимо изменить раздел:
# /sbin/lvextend -L +1G /dev/test/lvm_home
lvextend -- extending logical volume "/dev/test/lvm_home" to 2 GB
lvextend -- doing automatic backup of volume group "test"
lvextend -- logical volume "/dev/test/lvm_home" successfully extended
|
Теперь при помощи resize_reiserfs изменяем раздел самой файловой системы:
# /sbin/resize_reiserfs -f /dev/test/lvm_home
Проверяем:
# df
dev/hda3 4032124 2789108 1038188 73% /
...
/dev/test/lvm_home 2097084 32840 2064244 2% /home/test
|
Как видите, размер получился в два раза больший.
Уменьшение раздела производится в таком порядке:
- размонтируем файловую систему;
- уменьшаем файловую систему с запасом;
- уменьшаем размер логического тома при помощи lvreduce;
- расширяем файловую систему до заполнения всего тома.
В командах это выглядит так:
# umount /dev/test/lvm_home
# resize_reiserfs -s -1.5G /dev/test/lvm_home
# lvreduce -L -1G /dev/test/lvm_home
# resize_reiserfs -f /dev/test/lvm_home
При работе с ext2 используется – resize2fs, XFS – xfs_growfs (но пока она урезаться не может).
И хотелось бы сказать ещё об одной возможности LVM, названной snapshots, которая позволяет администратору создавать новое блочное устройство, в которое копируется логический том в «замороженном» на этот момент состоянии. Этот режим позволяет производить резервное копирование без закрытия приложений. Фактически теперь можно производить резервное копирование при любой нагрузке. По окончании процесса копирования администратор должен удалить snapshots.
Создается snapshots командой lvcreate с ключом -s и с указанием размера, имени и логического тома, состояние которого необходимо заморозить.
# lvcreate -L592M -s -n home_backup /dev/test/lvm_home
lvcreate -- WARNING: the snapshot must be disabled if it gets full
lvcreate -- INFO: using default snapshot chunk size of 64 KB for "/dev/test/home_backup "
lvcreate -- doing automatic backup of "test "
lvcreate -- logical volume "/dev/test/home_backup" successfully created
|
В результате образуется ещё один логический том с именем /dev/test/home_backup.
Его можно смонтировать и посмотреть, что там есть.
# mkdir /mnt/snapshots
# mount /dev/test/home_backup /mnt/snapshots
mount: block device /dev/ops/dbbackup is write-protected, mounting read-only |
Всё, теперь архивируем данные и удаляем snapshots.
# umount /dev/test/home_backup
# lvremove /dev/test/home_backup
Теперь при подключении к системе новых дисков на них можно создавать свои логические тома или присоединять их к существующим, копировать, перемещать импортировать имеющиеся на другой диск, в общем, полная свобода действий. Вот такая технология LVM, удобная, простая и в то же время позволяющая гибко управлять своими файловыми системами.
Дополнительную информацию, кроме вышеназванного HOWTO, можно получить в статьях Дэниеля Роббинсона (Daniel Robbins) – одного из создателей дистрибутива Gentoo Linux в Learning Linux LWM, Part 1 и Part 2: http://www-106.ibm.com/developerworks/linux/library/l-lvm.
Как разместить корневую файловую систему на LVM, можно узнать по адресу: http://www.the-infinite.org/archive/docs/lvm/howto-boot-off-root-lv.txt
И в man-страницах, конечно же.