Работа оптического привода подобна работе по набору на компьютере книги на английском языке: вам не обязательно понимать, о чем эта книга, чтобы выполнить работу. Не надо даже понимать английский язык. Задача для жесткого диска напоминает чтение немецкой книги и ее набор на компьютере в виде перевода на английский язык. В этом случае вам необходимо знать оба языка и понимать содержание книги.
Библиотека libata справляется с задачей и дает возможность подключить подсистему SCSI для устройств с интерфейсами ATA/SATA. Как правило, оказывается вовлеченным большее количество драйверов, а не всего лишь один ведущий драйвер SATA, как показано на рис. 3.2. Остальные драйверы не показаны в целях упрощения схемы.
3.6.3. Обобщенные устройства SCSI
Процесс из пространства пользователя взаимодействует с подсистемой SCSI с помощью слоя блочных устройств и/или другой службы ядра, расположенной над драйвером класса устройств SCSI (например, sd или sr). Другими словами, большинству пользовательских процессов нет нужды знать что-либо об устройствах SCSI или об их командах.
Тем не менее пользовательские процессы могут обходить драйверы классов устройств и отправлять команды протокола SCSI напрямую устройствам с помощью
$ lsscsi — g
[0:0:0:0] disk ATA WDC WD3200AAJS-2 01.0 /dev/sda
[1:0:0:0] cd/dvd Slimtype DVD A DS8A5SH XA15 /dev/sr0 /dev/sg1
[2:0:0:0] disk USB2.0 CardReader CF 0100 /dev/sdb /dev/sg2
[2:0:0:1] disk USB2.0 CardReader SM XD 0100 /dev/sdc /dev/sg3
[2:0:0:2] disk USB2.0 CardReader MS 0100 /dev/sdd /dev/sg4
[2:0:0:3] disk USB2.0 CardReader SD 0100 /dev/sde /dev/sg5
[3:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdf /dev/sg6
В дополнение к обычному файлу блочного устройства в каждой строке указан файл обобщенного SCSI-устройства (отмечен символом
Зачем может понадобиться обобщенное SCSI-устройство? Ответ обусловлен сложностью кода ядра. Когда задачи становятся более тяжелыми, лучше их вывести за пределы ядра. Представьте запись и чтение CD/DVD. Чтение происходит существенно проще записи, при нем не затрагиваются важные службы ядра. Программа в пространстве пользователя выполнила бы запись чуть менее эффективно, чем служба ядра, однако такую программу гораздо проще создать и поддерживать, чем службу ядра, а ошибки в ней не затронут пространство ядра. Следовательно, чтобы записать оптический диск в системе Linux, мы запускаем программу, которая «разговаривает» с обобщенным SCSI-устройством, таким как /dev/sg1. Однако благодаря простоте чтения, по сравнению с записью, считывание с устройства происходит с помощью специального драйвера sr в ядре.
3.6.4. Методы коллективного доступа к одному устройству
На рис. 3.3 для SCSI-подсистемы Linux показаны две точки доступа (sr и sg) к оптическому приводу из пространства пользователя (опущены все драйверы, которые расположены под самым нижним уровнем SCSI). Процесс А осуществляет чтение с помощью драйвера sr, а процесс Б производит запись с помощью драйвера sg. Однако такие процессы не могут одновременно получать доступ к одному устройству.
Рис. 3.3. Схема драйверов оптического привода
На рис. 3.3 процесс А осуществляет чтение с блочного устройства. Однако действительно ли пользовательские процессы считывают данные подобным образом? Ответ, как правило, отрицательный: нет, напрямую не считывают. Над блочными устройствами есть дополнительные слои, а для жестких дисков — также и дополнительные точки доступа, как вы узнаете из следующей главы.
4. Диски и файловые системы
В главе 3 мы рассмотрели дисковые устройства верхнего уровня, которые делают ядро доступным. В данной главе мы детально расскажем о работе с дисками в Linux. Вы узнаете о том, как создавать разделы дисков, настраивать и поддерживать файловые системы в этих разделах, а также работать с областью подкачки.
Вспомните о том, что у дисковых устройств есть имена вроде /dev/sda, первого диска подсистемы SCSI. Такой тип блочного устройства представляет диск целиком, однако внутри диска присутствуют различные компоненты и слои.
На рис. 4.1 приведена схема типичного диска в Linux (масштаб не соблюден). По мере изучения этой главы вы узнаете, где находится каждый его фрагмент.
Рис. 4.1. Схема типичного диска Linux
Разделы являются более мелкими частями всего диска. В Linux они обозначаются с помощью цифры после названия блочного устройства и, следовательно, получают такие имена, как, например, /dev/sda1 и /dev/sdb3. Ядро представляет каждый раздел в виде блочного устройства, как если бы это был целый диск. Разделы определяются в небольшой области диска, которая называется
примечание
Многочисленные разделы были когда-то распространены в системах с большими дисками, поскольку старые ПК могли загружаться только из определенных частей диска. К тому же администраторы использовали разделы, чтобы зарезервировать некоторое пространство для областей операционной системы. Например, они исключали возможность того, чтобы пользователи заполнили все свободное пространство системы и нарушили работу важных служб. Такая практика не является исключительной для Unix; вы по-прежнему сможете найти во многих новых системах Windows несколько разделов на одном диске. Кроме того, большинство систем располагает отдельным разделом подкачки.
Хотя ядро и позволяет вам иметь одновременный доступ ко всему диску и к одному из его разделов, вам не придется это делать, если только вы не копируете весь диск.
Следующий за разделом слой является
Как можно заметить на рис. 4.1, если вам необходим доступ к данным в файле, вам потребуется выяснить из таблицы разделов расположение соответствующего раздела, а затем отыскать в базе данных файловой системы этого раздела желаемый файл с данными.
Чтобы обращаться к данным на диске, ядро Linux использует систему слоев, показанную на рис. 4.2. Подсистема SCSI и все остальное, описанное в разделе 3.6, представлены в виде одного контейнера. Обратите внимание на то, что с дисками можно работать как с помощью файловой системы, так и непосредственно через дисковые устройства. В этой главе вы попробуете оба способа.
Чтобы уяснить, как все устроено, начнем снизу, с разделов.
4.1. Разделы дисковых устройств
Существуют различные типы таблиц разделов. Традиционная таблица — та, которая расположена внутри
Приведу перечень доступных в Linux инструментов для работы с разделами:
• parted — инструмент командной строки, который поддерживает как таблицу MBR, так и таблицу GPT;
• gparted — версия инструмента parted с графическим интерфейсом;
• fdisk — традиционный инструмент командной строки Linux для работы с разделами. Не поддерживает таблицу GPT;
Рис. 4.2. Схема доступа ядра к диску
• gdisk — версия инструмента fdisk, которая поддерживает таблицу GPT, но не работает с MBR.
Поскольку инструмент parted поддерживает обе таблицы (MBR и GPT), в данной книге мы будем пользоваться им. Однако многие пользователи предпочитают интерфейс fdisk, и в этом нет ничего плохого.
примечание
Хотя команда parted способна создавать и изменять файловые системы, не следует использовать ее для манипуляций с файловой системой, поскольку вы можете легко запутаться. Имеется существенное отличие работы с разделами от работы с файловой системой. Таблица разделов устанавливает границы диска, в то время как файловая система гораздо сильнее вовлечена в структуру данных. Исходя из этого, мы будем применять команду parted для работы с разделами, а для создания файловых систем используем другие утилиты (см. подраздел 4.2.2). Даже документация к команде parted призывает вас создавать файловые системы отдельно.
4.1.1. Просмотр таблицы разделов
Можно просмотреть таблицу разделов вашей системы с помощью команды parted — l. Приведу пример результатов работы для двух дисковых устройств с различными типами таблиц разделов:
# parted — l
Modename = "note" ATA WDC WD3200AAJS-2 (scsi)
Disk /dev/sda: 320GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 316GB 316GB primary ext4 boot
2 316GB 320GB 4235MB extended
5 316GB 320GB 4235MB logical linux-swap(v1)
Modename = "note" FLASH Drive UT_USB20 (scsi)
Disk /dev/sdf: 4041MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
1 17.4kB 1000MB 1000MB myfirst
2 1000MB 4040MB 3040MB mysecond
Первое устройство, /dev/sda, использует традиционную таблицу разделов MBR (которую команда parted назвала msdos), а второе устройство содержит таблицу GPT.
Обратите внимание на различающиеся параметры в этих таблицах разделов, поскольку сами таблицы различны. В частности, в таблице MBR нет столбца Name (Имя), поскольку в этой схеме имена отсутствуют. (Я произвольно указал имена myfirst и mysecond в таблице GPT.)
Таблица MBR в данном примере содержит основной, расширенный и логический разделы.
В данном примере раздел 2 является расширенным разделом, который содержит логический раздел 5.
примечание
Файловая система, которую выводит команда parted, это не обязательно та система, что определена в поле идентификатора в большинстве записей таблицы MBR. Этот идентификатор является числом; например, 83 — это раздел Linux, а 82 — область подкачки Linux. Таким образом, команда parted пытается самостоятельно определить файловую систему. Если вам необходимо абсолютно точно узнать идентификатор системы для таблицы MBR, используйте команду fdisk — l.
Первичное чтение ядром
При первичном чтении таблицы MBR ядро Linux выдает следующий отладочный результат (вспомните, что увидеть его можно с помощью команды dmesg):
sda: sda1 sda2 < sda5 >
Фрагмент sda2 < sda5 > означает, что устройство /dev/sda2 является расширенным разделом, который содержит один логический раздел, /dev/sda5. Как правило, вы будете игнорировать расширенные разделы, поскольку вам будет нужен доступ только к внутренним логическим разделам.
4.1.2. Изменение таблиц разделов
Просмотр таблиц разделов — операция сравнительно простая и безвредная. Изменение таблиц разделов также осуществляется довольно просто, однако при таком типе изменений диска могут возникнуть опасности. Имейте в виду следующее.
• Изменение таблицы разделов сильно усложняет восстановление любых данных в удаляемых разделах, поскольку при этом меняется начальная точка привязки файловой системы. Обязательно создавайте резервную копию диска, на котором вы меняете разделы, если он содержит важную информацию.
• Убедитесь в том, что на целевом диске ни один из разделов в данный момент не используется. Это важно, поскольку в большинстве версий Linux автоматически монтируется любая обнаруженная файловая система (подробности о монтировании и демонтировании см. в подразделе 4.2.3).
Когда вы будете готовы, выберите для себя команду для работы с разделами. Если вы предпочитаете применять команду parted, то можете воспользоваться утилитой командной строки или таким графическим интерфейсом, как gparted. Для интерфейса в стиле команды fdisk воспользуйтесь командой gdisk, если вы работаете с разделами GPT. Все эти утилиты обладают интерактивной справкой и просты в освоении. Попробуйте применить их для флеш-накопителя или какого-либо подобного устройства, если у вас нет свободных дисков.
Существуют различия в том, как работают команды fdisk и parted. С помощью команды fdisk вы создаете новую таблицу разделов до выполнения реальных изменений на диске; команда fdisk только осуществляет их, когда вы выходите из нее. При использовании команды parted разделы создаются, изменяются и удаляются,
Эти различия важны также для понимания того, как данные утилиты взаимодействуют с ядром. Команды fdisk и parted изменяют разделы полностью в пространстве пользователя; нет необходимости, чтобы ядро обеспечивало поддержку перезаписи таблицы разделов, поскольку пространство пользователя способно считывать и изменять все данные на блочном устройстве.
Однако в конечном счете ядро все же должно считывать таблицу разделов, чтобы представить разделы как блочные устройства. Утилита fdisk использует сравнительно простой метод: после изменения таблицы разделов эта команда осуществляет единичный системный вызов к диску, чтобы сообщить ядру о необходимости повторного считывания таблицы разделов. После этого ядро генерирует отладочный вывод, который можно просмотреть с помощью команды dmesg. Например, если вы создаете два раздела на устройстве /dev/sdf, вы увидите следующее:
sdf: sdf1 sdf2
В сравнении с этой командой инструменты parted не используют системный вызов для всего диска. Вместо него они сигнализируют ядру об изменении отдельных разделов. После обработки изменения одного раздела ядро не производит приведенного выше отладочного вывода.
Есть несколько способов увидеть изменения разделов.
• Используйте команду udevadm, чтобы отследить изменения событий ядра. Например, команда udevadm monitor — kernel покажет удаленные устройства-разделы и добавленные новые.
• Посмотрите полную информацию о разделах в файле /proc/partitions.
• Поищите в каталоге /sys/block/device/ измененные системные интерфейсы разделов или в каталоге /dev — измененные устройства-разделы.
Если вы хотите быть абсолютно уверенными в том, что таблица разделов изменена, можно выполнить «старомодный» системный вызов, который применяет команда fdisk, использовав команду blockdev. Например, чтобы ядро принудительно перезагрузило таблицу разделов на устройстве /dev/sdf, запустите следующую команду:
# blockdev — rereadpt /dev/sdf
На данный момент вы знаете все необходимое о работе с разделами дисков. Если вам интересно изучить некоторые дополнительные подробности о дисках, продолжайте чтение. В противном случае переходите к разделу 4.2, чтобы узнать о размещении файловой системы на диске.