четверг, 18 марта 2010 г.

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

Утилита gpart служит для управления GEOM классом PART. На самом деле это хардлинк на утилиту geom(8), которая является универсальной утилитой управления для многих GEOM классов.

Как я уже упоминал в предыдущей заметке, класс PART служит для работы с таблицами партиций и предоставляет доступ к провайдерам этих партиций. С появлением этой утилиты можно уже забыть такие утилиты как fdisk и bsdlabel, они морально устарели. Большинство их действий можно выполнять при помощи утилиты gpart. Нужно только понять и запомнить основные понятия - схема и партиция. Прежде чем создавать партиции, необходимо выбрать тип таблицы - схему. Например, для привычной разметки с использованием MBR необходимо выполнить команду 'gpart create' с указанием имени схемы в опции "-s mbr":
# gpart create -f x -s mbr md0
md0 created
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17  1023978       - free -  (500M)

# gpart commit md0
Опция "-f x" указывает классу не вносить изменения на провайдер носителя сразу. Т.е. если вы не уверены в своих действиях, вы можете с каждой командой указывать эту опцию и после того как будете уверены, выполнить команду `gpart commit`, либо отменить изменения командой `gpart undo`. Не имеет значения, какой флаг вы укажете после опции "-f", т. к. класс отслеживает только наличие опции и её отличие от значения, принятого по-умолчанию. Если не указывать опцию "-f", то её значение по-умолчанию будет установлено в "-f C", что приведёт к автоматическому выполнению команды `gpart commit`.

Таблица MBR может содержать максимум 4 записи, т.е. не более 4 партиций. После того как схема создана можно создавать партиции при помощи команды `gpart add`. Каждая партиция обладает несколькими обязательными свойствами - смещение начала, смещение конца, индекс в таблице и тип партиции. А так же одно дополнительное свойство, которым обладают партиции некоторых схем - символьная метка.  Все эти параметры видны пользователю, за исключением смещения конца. Смещение заменяется на вычисляемый из него размер.
К тому же, для создания партиции при помощи утилиты gpart нужен только один обязательный параметр - это тип партиции, остальные параметры могут быть вычеслены автоматически.

Тип партиции может быть задан символьным именем либо специальным номером, в зависимости от используемой схемы. Поддерживаемые символьные имена можно увидеть в мануале gpart(8). При необходимости задать какой-то специфический для схемы тип партиции, он указывается после знака восклицания. Например, для схемы MBR тип партиции FreeBSD представлен номером 165, который можно указать как "-t !165" (не забываем экранировать знак восклицания, если выполняем команду из shell - "\!165"), либо символьным именем "-t freebsd".

Размер и смещение начала партиции по-умолчанию задаются в блоках, размер которых обычно соответствует размеру физического сектора, т.е. 512 байт. Для того чтобы не вычислять количество блоков, эти параметры можно указывать с суффиксом размера: b, k, m, g, t, p, e - т.е. от байт до экзабайт. Но есть одна особенность реализации - парсер при разборе этих параметров ещё не знает какой размер сектора имеет носитель, поэтому если он отличается от 512 байт, то лучше указывать размер в секторах, иначе размер будет вычислен неправильно.  Размер партиции указывается после опции "-s", а смещение начала - после "-b". При опускании любого из этих параметров они выбираются автоматически: смещение начала - на первый доступный блок, размер - на максимально возможный из доступного свободного пространства.

Вычисление индекса партиции обычно можно оставить утилите gpart. Только если вам не нужна какая-нибудь особенная конфигурация, например, чтобы система устанавливалась на ad0s3 нужно указать параметр "-i 3".

Итак, схема создана, создадим партицию:
# gpart add -s 400m -t freebsd md0
md0s1 added
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  (400M)
   819213   204782       - free -  (100M)

Как видно, партиция была создана с типом "freebsd" и размером в 400 Мбайт, индекс и смещение начала были выбраны автоматически.

Теперь на созданной партиции можно сделать дополнительную разметку для BSD схемы:
# gpart create -s bsd md0s1
md0s1 created
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  (400M)
   819213   204782       - free -  (100M)

# gpart show md0s1
=>     0  819196  md0s1  BSD  (400M)
       0  819196         - free -  (400M)

Теперь добавим партиции, только вместо bsdlabel используем тот же gpart:
# gpart add -s 100m -t freebsd-ufs md0s1
md0s1a added
# gpart add -s 100m -t freebsd-swap md0s1
md0s1b added
# gpart add -t freebsd-ufs md0s1
md0s1d added
# gpart show md0s1
=>     0  819196  md0s1  BSD  (400M)
       0  204800      1  freebsd-ufs  (100M)
  204800  204800      2  freebsd-swap  (100M)
  409600  409596      4  freebsd-ufs  (200M)

Всё достаточно легко и просто. Для записи загрузочного кода можно использовать всю ту же утилиту. Для этого предназначена команда `gpart bootcode`. Например, аналогом команды `bsdlabel -B` будет:
# gpart bootcode -b /boot/boot md0s1
md0s1 has bootcode
Аналогично можно записать загрузочный код для схемы MBR:
# gpart bootcode -b /boot/mbr md0
md0 has bootcode
Если же необходимо установить менеджер загрузки, то нужно всего лишь выбрать другой образ загрузочного кода - /boot/boot0. Так же, не стоит забывать, что у схемы MBR есть аттрибут активного раздела, чтобы его установить нужно использовать команду `gpart set`:
# gpart set -a active -i 1 md0
md0s1 has active set
# gpart show md0
=>     17  1023978  md0  MBR  (500M)
       17   819196    1  freebsd  [active]  (400M)
   819213   204782       - free -  (100M)

В принципе, этого набора команд достаточно для работы. Если иметь понятие, что и для чего нужно сделать - то сложностей в использовании вообще не вижу. Даже если такая необходимость возникает нечасто, все команды утилиты gpart имеют описание:
# gpart 
usage: gpart add [-b start] [-s size] -t type [-i index] [-l label] [-f flags] geom
       gpart bootcode [-b bootcode] [-p partcode] [-i index] [-f flags] geom
       gpart commit geom
       gpart create -s scheme [-n entries] [-f flags] provider
       gpart delete -i index [-f flags] geom
       gpart destroy [-f flags] geom
       gpart modify -i index [-l label] [-t type] [-f flags] geom
       gpart set -a attrib -i index [-f flags] geom
       gpart show [-lr] [geom ...]
       gpart undo geom
       gpart unset -a attrib -i index [-f flags] geom
       gpart help
       gpart list [name ...]
       gpart status [-s] [name ...]
       gpart load [-v]
       gpart unload [-v]

23 комментария:

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

    ОтветитьУдалить
  2. Вместе с SSD и HDD от WD пришла новая проблема - сектора размером 4K. Хорошо бы автоматически (либо по специальной опции)выравнивать начало партициий по границе сектора. При наличии опции с параметром, я бы всегда задавал выравнивание по границе 1М (удобно и для SSD и для RAID).

    ОтветитьУдалить
  3. Скажите пожалуйста, а как метку раздела снести?

    # gpart modify -i 2 -l "" ad10
    ad10p2 modified

    # gpart show -l ad10
    => 34 234441581 ad10 GPT (112G)
    34 256 1 boot (128K)
    290 8388608 2 sysswap (4.0G)
    8388898 4194304 3 sysroot (2.0G)
    12583202 62914560 4 sysvar (30G)
    75497762 158943853 5 sysusr (76G)

    Таким образом чото не получается.

    ОтветитьУдалить
  4. у меня работает. Какая версия системы? Что выводит команда:
    # ident /sys/geom/part/g_part_gpt.c

    ОтветитьУдалить
  5. # uname -mrs
    FreeBSD 8.2-RELEASE-p2 amd64

    # ident /sys/geom/part/g_part_gpt.c
    /sys/geom/part/g_part_gpt.c:
    $FreeBSD: src/sys/geom/part/g_part_gpt.c,v 1.16.2.13.2.1 2010/12/21 17:09:25 kensmith Exp $

    ОтветитьУдалить
  6. Добрый день!
    А можно по подробнее рассказать про bootcode?
    Я немного ни понимаю различай между -p и -b опциями, и что применять для моего случая со sparc64 =(

    ОтветитьУдалить
  7. Лично у меня не было возможности поработать с FreeBSD на спарках,
    поэтому ничего конкретного тут посоветовать не могу. Видимо, тут всё зависит от того,
    какая таблица разделов у вас используется. Некоторое время назад я добавил главу
    "BOOTSTRAPPING" в мануал gpart(8). Там есть объяснение с примерами, какой загрузочный код
    где должен находиться: gpart(8)

    Разница между -p и -b в том, что первый - partcode, располагается на специально выделенном
    для него разделе, а второй - bootcode, находится в области метаданных таблицы разделов.

    ОтветитьУдалить
  8. Анонимный29 июня 2012 г., 16:09

    root@jw:~# mdconfig -s 2048m
    md0
    root@jw:~# gpart create -s mbr md0
    md0 created
    root@jw:~# gpart show md0
    => 63 4194241 md0 MBR (2.0G)
    63 4194241 - free - (2G)

    root@jw:~# gpart add -a 4k -t freebsd -s 100m md0
    md0s1 added
    root@jw:~# gpart add -a 4k -t freebsd md0
    md0s2 added
    root@jw:~# gpart show md0
    => 63 4194241 md0 MBR (2.0G)
    63 63 - free - (31k)
    126 204687 1 freebsd (100M)
    204813 63 - free - (31k)
    204876 3989412 2 freebsd (1.9G)
    4194288 16 - free - (8.0k)

    Хм, а разделы-то получились ни разу не выровнены по 4к...

    ОтветитьУдалить
    Ответы
    1. Вот тут я уже отвечал на такой вопрос.

      Удалить
  9. Анонимный18 июля 2012 г., 12:57

    Простите, а не подскажете - есть nanobsd с рабочей системой, подключили доп.диск 1Тбайт из виндовой машины - следовательно, он NTFS. Как убить все на нём, форматнуть в UFS и подключить как партицию? Нужен он чисто как диск под бэкапы.

    Какие команды gpart нужно применить? Система видит его как ada0.

    Заранее большое спасибо!

    ОтветитьУдалить
  10. file# gpart show
    => 34 976773100 mirror/gm1 GPT (465G)
    34 6 - free - (3.0k)
    40 256 1 freebsd-boot (128k)
    296 4194304 2 freebsd-swap (2.0G)
    4194600 972578528 3 freebsd-ufs (463G)
    976773128 6 - free - (3.0k)

    => 34 1953546173 stripe/gs1 GPT (931G)
    34 94 - free - (47k)
    128 1953545984 1 freebsd-ufs (931G)
    1953546112 95 - free - (47k)


    stripe/gs1-raid10

    ls
    .cshrc COPYRIGHT dev home media rescue sys var
    .profile bin etc lib mnt root tmp
    .snap boot file libexec proc sbin usr
    Хочу примонтировать stripe/gs1p1 к /home
    mount /dev/stripe/gs1p1 /home
    mount: /dev/stripe/gs1p1 : Invalid argument
    Что не так???

    ОтветитьУдалить
    Ответы
    1. EINVAL при mount означает что у вас на /dev/stripe/gs1p1 нет файловой системы.

      Удалить
  11. Добрый день, Андрей, помогите пожалуйста с решение следующего вопроса. Есть домашний комп на котором поднята виртуализация на XCP (аналог XenServer). На материнке два контроллера и один из этих контроллеров с тремя подключенными винтами я полностью прокинул внутрь VM. Хост их не видит, а виртуалка напрямую "видит железо". Загрузился с FreeBSD 9.0 DVD и настроил zfs и три винта в raidz (ada0, ada1, ada2). Проблема в том, что у VM нет полноценного биоса и теперь я не могу сказать загрузиться с этих винтов. Есть только опции: грузится с DVD, HDD, network. Под HDD он понимает только vhd диски подключенные к машине. Ок, создал диск 100 мб. подключил, он стал ada0 (как изменить его на ada4 я не знаю), и как сделать, чтобы загрузчик указывал на ada1 не пойму. пробовал вариант:
    gpart create gpt ada0
    gpart add -b 40 -s 128k freebsd-boot -l vmboot ada0
    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
    машина грузится, и получаю:
    gptzfsboot: No ZFS ppols located, can't load
    Как сказать чтобы он загружался с другого винта?
    ведь нумерация винтов изменилась. Заранее спасибо за помощь.

    ОтветитьУдалить
    Ответы
    1. Последовательность дисков в общем-то не так важна в случае с ZFS.
      Покажите как вы сделали raidz? Из целых дисков, или там есть таблицы разделов?

      Удалить
  12. Я написал скрипт и запускал его, ниже его часть

    gpart create -s gpt $mydisk0
    gpart create -s gpt $mydisk1
    gpart create -s gpt $mydisk2
    gpart create -s gpt $mydisk3

    gpart add -b 40 -s 128k -t freebsd-boot -l boot0 $mydisk0
    gpart add -b 40 -s 128k -t freebsd-boot -l boot1 $mydisk1
    gpart add -b 40 -s 128k -t freebsd-boot -l boot2 $mydisk2
    gpart add -b 40 -s 128k -t freebsd-boot -l boot3 $mydisk3

    gpart add -t freebsd-zfs -l disk1 -b 2048 -a 4k $mydisk1
    gpart add -t freebsd-zfs -l disk2 -b 2048 -a 4k $mydisk2
    gpart add -t freebsd-zfs -l disk3 -b 2048 -a 4k $mydisk3


    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $mydisk0
    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $mydisk1
    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $mydisk2
    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $mydisk3

    #This is for 4k sectors disks
    gnop create -S 4096 /dev/gpt/disk1
    gnop create -S 4096 /dev/gpt/disk2
    gnop create -S 4096 /dev/gpt/disk3

    echo "creating zpool (RAID 3 disks)"
    zpool create -f -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache $poolname raidz /dev/gpt/disk1.nop /dev/gpt/disk2.nop /dev/gpt/disk3.nop

    echo creating partitions
    zpool export $poolname
    gnop destroy /dev/gpt/disk1.nop
    gnop destroy /dev/gpt/disk2.nop
    gnop destroy /dev/gpt/disk3.nop
    zpool import -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache $poolname
    zpool set bootfs=$poolname $poolname
    zfs set checksum=fletcher4 $poolname
    ... создаю партиции...
    ...потом swap...
    echo "creating swap tmp and link to home directory"
    zfs create -V 4G $poolname/swap
    zfs set org.freebsd:swap=on $poolname/swap
    zfs set checksum=off $poolname/swap
    # tmp and home folders
    chmod 1777 /mnt/tmp
    chmod 1777 /mnt/var/tmp
    cd /mnt ; ln -s usr/home home
    ...потом возвращаю файл назад
    cp /var/tmp/zpool.cache /mnt/boot/zfs/zpool.cache

    echo configuring fstab, rc.conf, loader.conf, periodic.conf
    echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf
    echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
    echo 'vfs.root.mountfrom="zfs:raidpool"' >> /mnt/boot/loader.conf
    echo 'daily_status_zfs_enable="YES"' >> /mnt/etc/periodic.conf
    touch /mnt/etc/fstab

    ОтветитьУдалить
    Ответы
    1. Понятно. Предлагаю выяснить, видит ли загрузчик диски вообще. Второй этап - умеет ли биос грузиться с GPT без использования UEFI?

      Удалить
    2. А как можно выяснить видит ли загрузчик диски?

      Удалить
    3. Если взять и отключить диск, который не используется с пулом ZFS, вообще хоть какой-то загрузчик отрабатывает?
      В вашем случае есть три стадии загрузчиков:
      1. PMBR - находит freebsd-boot раздел в GPT и запускает его загрузочный код
      2. gptzfsboot - находит ZFS пул и запускает из него zfsloader
      3. zfsloader - находит ZFS пул ещё раз и запускает ядро.

      Какое последнее сообщение выводится в вашем случае?
      Кстати, мне тут вспомнилось. У меня один знакомый не так давно эксперементировал с QEMU и VirtIO. У него тоже была проблема с загрузкой. Так вот, если есть желание, можете попробовать положить в /boot вашего пула вот этот zfsloader http://people.freebsd.org/~ae/zfsloader . Он от 10-ки, но собран с опцией -DVIRTUALBOX, которая игнорирует информацию о количестве дисков, сообщаемую загрузчику. Т.е. он будет принудительно опрашивать диски.

      Удалить
    4. Если отключить диск (виртуальный), то никакой загрузчик не отрабатывает. BIOS у виртуалки обрезанный и он просто "не знает", что есть другие устройства с которых можно грузится. Т.е. загрузчик VM дествует "в лоб", пробую DVD, если не смонтирован, перехожу к следующему шагу, пробую HDD, если HDD, в формате который он понимает нет, то пишу "No boot device". Как я понял, чтобы увидить эти диски кто-то должен запустить kernel, когда проходит загрузка ядра он этот пул увидит. Сегодня попробую.

      Удалить
    5. Тогда надо пробовать другой вариант, создайте виртуальный диск, можно с MBR. Там freebsd слайс, на нём одну партицию c UFS, куда положить /boot/zfsloader, можно и остальные файлы кроме ядра. Тогда ваша загрузка остановится и в консоли лоадера можно будет ввести команду lsdev, которая покажет, какие диски загрузчик увидел.

      Удалить
    6. У меня заработало. Сделал так:
      Увеличил размер виртуального диска до 500М. Затем
      destroy -F /dev/ada0
      create -s gpt /dev/ada0
      Затем загрузчик и буткод
      add -b 40 -s 128k -t freebsd-boot -l boot0 /dev/ada0
      bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/ada0
      Добавил раздел
      gpart add -t freebsd-zfs -l disk0 -b 2048 -a 4k /dev/ada0
      Смонтировал ранее созданный пул из трех дисков в /mnt
      zpool import -o altroot=/mnt/ -f raidpool
      Создаю каталог куда буду монтировать новый пул и сам пул
      mkdir /tmp/tmpp
      zpool create -f -o altroot=/tmp/tmpp -o cachefile=/var/tmp localpool.cache localpool /dev/ada0p2
      потом скопировал в /tmp/tmpp каталог /boot и два файла с кешами
      cp -R /mnt/boot /tmp/tmpp/
      cp /mnt/boot/zfs/zpool.cache /tmp/tmpp/boot/zfs/
      cp /var/tmp/localpool.cache /tmp/tmpp/boot/zfs/
      Почему заработало я не понял. Видимо догадка, что нужно загрузить kernel - верная

      Удалить
  13. который день сексуюсь с загрузочной флешкой.

    типичная последовательность

    dd if=/dev/zero of=/dev/da5 bs=1m count=5
    gpart create -s mbr da5
    gpart bootcode -b /boot/mbr da5
    gpart add -t freebsd da5
    gpart create -s bsd da5s1
    gpart add -t freebsd-ufs da5s1
    gpart set -a active -i 1 da5
    newfs -U -L RootOnUSB /dev/da5s1a
    gpart bootcode -b /boot/boot da5s1

    ну и далее при желании installworld, kernel...

    На более-менее свежих компах заводится и взлетает. Но есть толпа HP Compaq d230m, для которых, собственно эти флешки и предназначены на случай подыхания винтов. Так вот - при вставлении такой флешки в этот самый d230m он тупо виснет на первой странице POST (точнее, на картинке HP), не грузится вообще, не даёт выбрать диск для загрузки и выводится из этого состояния только путём 4-х секундного удержания кнопки питания. Дело во втором boot - до его записи исправно прогружается, если выбрать USB для загрузки - ругается, что Misssing operating system, но не виснет. Эта же флешка в более свежем компе - например, HP Compaq dx2200 - исправно грузится. Винда на этом же старье (d230m) с флешки грузится исправно, но этого не нужно. Что делать, куда копать, на что менять boot ?

    А, да - загрузчик записывался на FreeBSD 8.2x86 или 9.1amd64 - но, как я полагаю, boot всё равно 32-битный ? в случае 8.2 boot тот же самый, который грузится на этой же машине с винта. И ещё - FreeBSD-8.2-RELEASE-i386-memstick.img тоже вешает комп при загрузке

    ОтветитьУдалить
    Ответы
    1. После долгих плясок с бубном, выяснилось, что это старое УГ прекрасно грузится с GPT дисков. Сделал флешку с GPT вместо MBR - и всё заработало и для указанной модели d230m и для более старых и более унылых :)

      Удалить