Свойство устойчивости к сбоям питания (power-fault tolerance) является одной из важных характеристик файловой системы. Строго говоря, имеется в виду устойчивость не только к сбоям питания, но и к любой ситуации, при которой работа с ФС прекращается без выполнения операции размонтирования. Поэтому правильнее было бы говорить об устойчивости к любым сбоям системы, а не только питания.
С другой стороны, если говорить просто об ``устойчивости к сбоям'', возникает неприятная двусмысленность. Под устойчивостью к сбоям можно понимать устойчивость к сбоям всей системы, например, к тем же сбоям питания, а можно понимать устойчивость к дефектам физического носителя, которые могут привести к потере части данных на диске. Вторая проблема также довольно сложна, но она обсуждается в разделе 8.4.4, а сейчас мы будем говорить только о первой проблеме, называя ее просто ``устойчивостью'' для краткости.
На самом деле, неожиданное прекращение работы с ФС может произойти не только при сбое питания, но и при:
RESET
нетерпеливым пользователем;
В системах класса ДОС последняя причина возникает очень часто, поэтому в таких системах можно использовать только устойчивые к сбоям ФС.
В системах класса ОС ``спонтанные'' зависания происходят намного реже. Система, зависающая по непонятным или неустранимым причинам раз в несколько дней считается малопригодной для серьезного использования, а делающая это раз в месяц - подозрительно ненадежной. Поэтому в таких системах можно позволить себе роскошь использовать неустойчивые к сбоям ФС. Тем более, что такие системы, как правило, обладают более высокой производительностью, чем устойчивые ФС.
К тому же перед выключением системы, интегрированной в сеть, необходимо уведомить всех клиентов и все сервера о разъединении. Только чисто клиентская машина может быть выключена из сети без проблем. Поэтому на сетевых серверах в любом случае необходима процедура закрытия системы (shutdown). Так почему бы не возложить на эту процедуру еще и функцию размонтирования ФС?
Напротив, в системах реального времени, которые по роду работы могут часто и неожиданно перезапускаться, например, при отладке драйверов или программ, осуществляющих доступ к аппаратуре, стараются использовать устойчивые к сбоям ФС.
Хотя первая из перечисленных выше причин - извлечение носителя из дисковода - не является ``сбоем'' даже в самом широком смысле этого слова, с точки зрения ФС это мало чем отличается от сбоя. Поэтому на удаляемых носителях, таких, как дискеты, можно использовать только устойчивые ФС.
Интересный альтернативный подход используется в компьютерах Macintosh и некоторых рабочих станциях. У этих машин дисковод не имеет кнопки для извлечения дискеты. Выталкивание дискеты осуществляется программно, подачей соответствующей команды дисководу. Перед подачей такой команды ОС может выполнить нормальное размонтирование ФС на удаляемом диске.
В узком смысле слова ``устойчивость'' означает лишь то, что такая ФС после аварийной перезагрузки необязательно нуждается в починке. Такие ФС обеспечивают целостность собственных структур данных в случае сбоя, но, вообще говоря, не гарантируют целостности пользовательских данных в файлах.
*
Нужно отметить, что даже если ФС считается в этом смысле устойчивой,
некоторые сбои для нее могут быть опасны. Например, если запустить команду
DISKOPT
на ``устойчивой'' файловой системе FAT и в
подходящий момент нажать RESET, то значительная часть данных на диске может быть
навсегда потеряна.
*
Напротив, можно говорить об устойчивости в том смысле, что в ФС после сбоя гарантирована целостность пользовательских данных. Хотя после простого анализа можно убедиться, что такую гарантию нельзя обеспечить на уровне ФС; обеспечение такой целостности накладывает серьезные ограничения и на программы, работающие с данными, а иногда оказывается просто невозможным.
Характерный и очень простой пример: архиватор InfoZip работает над созданием архива. Программа сформировала заголовок файла, упаковала и записала на диск около 50 % данных, и в этот момент произошел сбой. В zip-архивах каталог находится в конце архивного файла и записывается туда после завершения упаковки всех данных. Обрезанный в случайном месте zip-файл не содержит каталога и поэтому, безусловно, является безнадежно испорченным.
Поэтому при серьезном обсуждении проблемы устойчивости к сбоям говорят не о гарантии целостности пользовательских данных, а об уменьшении вероятности их порчи.
Поддержание целостности структур ФС обычно гораздо важнее, чем целостность недописанных в момент сбоя пользовательских данных. Дело в том, что если при сбое оказывается испорчен создававшийся файл, это достаточно неприятно; если же окажется испорчена файловая система, в худшем случае это может привести к потере всех данных на диске, то есть к катастрофе. Поэтому обычно обеспечению целостности ФС при сбоях уделяется гораздо больше внимания.
Упоминавшаяся выше ``врожденная'' устойчивость к сбоям файловой системы
FAT объясняется тем, что в этой ФС удаление блока из списка свободных и
выделение его файлу производится одним действием - модификацией элемента
FAT
. Поэтому если во время этой процедуры произойдет сбой или
дискета будет вынута из дисковода, то ничего страшного не случится: просто
получится файл, которому выделено на один блок больше, чем его длина, записанная
в каталоге. При стирании этого файла все его блоки будут помечены как свободные,
поэтому вреда практически нет.
*
Нужно отметить, что при использовании отложенной записи FAT и
родственные ФС теряют это преимущество. При этом отложенная запись
FAT
является единственным способом добиться хоть сколько-нибудь
приемлемой производительности от ФС с 32-битовым FAT
. Поэтому,
например, хотя Novell NetWare и использует ФС, основанную на 32-битной
FAT
, после аварийной перезагрузки эта система вынуждена запускать
программу аварийной починки дисковых томов. Аналогичным образом ведет себя и
32-битная версия ДОСовской ФС FAT32.
*
Если же система хранит отдельно список или карту свободных блоков, а отдельно списки блоков, выделенных каждому файлу, как это делают HPFS или ФС систем семейства Unix, то при прерывании операции выделения места в неподходящий момент могут либо теряться блоки (если мы сначала удаляем блок из списка свободных), либо получаться блоки, которые одновременно считаются и свободными, и занятыми (если мы сначала выделяем блок файлу).
Первая ситуация достаточно неприятна, вторая же просто недопустима: первый же файл, созданный после перевызова системы, будет ``перекрещиваться'' с испорченным. Поэтому все ОС, использующие файловые системы такого типа (системы семейства Unix, OS/2, Windows NT и т.д.), после аварийной перезагрузки первым делом проверяют свои ФС соответствующей программой починки.
Задача обеспечения целостности файловых систем при сбоях усложнияется тем, что дисковые подсистемы практически всех современных ОС активно используют отложенную запись, в том числе и при работе с системными структурами данных. Отложенная запись, особенно в сочетании с сортировкой запросов по номеру блока на диске, может приводить к тому, что изменения инода или ф-нода файла могут все-таки записываться на диск раньше, чем изменения списка свободных блоков, что может приводить к возникновению ``скрещенных" файлов.
Чаще всего суперблок неустойчивых ФС содержит флаг dirty (``грязный''), сигнализирующий о том, что ФС, возможно, нуждается в починке. Этот флаг сбрасывается при нормальном размонтировании ФС и устанавливается при ее монтировании или при первой модификации после монтирования. Таким образом, если ОС погибла, не успев размонтировать свои дисковые тома, после перезагрузки на этих томах dirty-флаг будет установлен, что и будет сигнализировать о необходимости починки.
Починка состоит в том, что система прослеживает пространство, выделенное всем файлам. При этом должны выполняться следующие требования:
Чаще всего программа починки в этой ситуации требует вмешательства пользователя, с тем чтобы решить, какие из файлов следует удалить или обрезать по месту пересечения. Иногда для каждого из файлов создается копия ``общего'' блока, но и в этом случае пользователю все равно нужно определить, какие из файлов испорчены.
Практически все ФС при выделении блока сначала удаляют его из списка свободных и лишь потом отдают файлу, поэтому при ``обычных'' сбоях перекрещивание файлов возникнуть может только как следствие отложенной записи в сочетании с сортировкой запросов. Возникновение таких ошибок обычно сигнализирует либо об ошибке в самом файловом менеджере, либо об аппаратных сбоях на диске, либо о том, что структуры ФС были модифицированы в обход файлового менеджера. Например, в ДОС это может быть признаком вирусной активности.
Обычно программа починки не помечает потерянные блоки как свободные, а
выделяет из них непрерывные цепочки и создает из этих цепочек файлы. Например,
в OS/2 программа починки пытается найти в потерянных блоках файловые
записи, а потом создает ссылки на найденные таким образом файлы в каталоге
FOUND.XXX
. В DOS эти файлы помещаются в корневой каталог
ФС под именами FILEXXXX.CHK
(вместо XXXX
подставляется номер). Предполагается, что пользователь просматривает все такие
файлы и определяет, не содержит ли какой-то из них ценной информации, например
конца насильственно укороченного файла.
lost+found
;
В некоторых особенно тяжелых случаях, программа починки оказывается не в состоянии справиться с происшедшей аварией и администратору системы приходится браться за дисковый редактор.
В процессе эксплуатации системы SCO Open Desktop 4.0, у одного из авторов неоднократно возникала необходимость выполнять холодную перезагрузку без нормального размонтирования файловых систем. Одна из таких перезагрузок привела к катастрофе.
Дисковая подсистема машины состояла из кэширующего контроллера дискового
массива. Контроллер активно использовал отложенную запись, что, по-видимому и
послужило причиной катастрофы. Во время планового резервного копирования драйвер
лентопротяжки впал в ступор и заблокировал процесс копирования. Из-за наличия зависшего процесса оказалось
невозможно размонтировать файловую систему и машина была перезагружена нажатием
кнопки RESET
без выполнения нормального закрытия, в том числе и без
выполнения операции закрытия драйвера дискового массива, которая должна была
сбросить на диски содержимое буферов контроллера.
После перезагрузки система автоматически запустила программу починки файловой
системы fsck
(File System ChecK), которая выдала радостное
сообщение: DUP in inode 2
. Для незнакомых с системными утилитами
Unix необходимо сказать, что DUP означает ошибку перекрещивания файлов, а
инод 2 - это инод корневого каталога ФС. Таким образом, корневая директория
дискового тома объемом около 2 гигабайт оказалась испорчена. При этом
подавляющее большинство каталогов и файлов были не затронуты катаклизмом, но
оказались недоступны. Программа починки не могла перенести ссылки на
соответствующие иноды в каталог lost+found
, так как ссылка на него
также идет из корневого каталога.
Ситуация представлялась безвыходной. Катастрофа усугублялась тем, что произошла она во время резервного копирования, а последняя ``хорошая" копия была сделана неделю назад. Большую часть пользовательских данных можно было бы восстановить, но среди потерянных файлов оказался журнальный файл сервера СУБД ORACLE (сама база данных находилась в другом разделе диска). Пришлось заняться восстановлением ФС с использованием дискового редактора, мотивируя это тем, что ``терять все равно уже нечего". Собственно, в восстановлении ФС участвовало два человека - автор и штатный администратор системы. Автор ни в коем случае не хочет создать у читателя впечатление, что план восстановления был разработан лично им - это был плод совместных усилий, проб и ошибок.
Редактирование системных данных ``сложных" ФС с использованием простого
шестнадцатиричного дискового редактора является крайне неблагодарным занятием.
Есть основания утверждать, что это вообще невозможно. Во всяком случае, ни
одному из авторов не доводилось слышать об успехе такого предприятия. К счастью,
системы семейства Unix предоставляют для редактирования ФС специальную
программу fsdb
(File System DeBugger - отладчик
файловой системы). По пользовательскому интерфейсу эта программа напоминает
программу DEBUG.COM
, поставляемую с MS DOS; основным ее
преимуществом является то, что она ``знакома" с основными понятиями файловой
системы. Так, например, fsdb
позволяет просмотреть содержимое 10-го
логического блока файла с инодом 23456, выделить физический блок 567345 файлу с
инодом 2 или пометить инод 1245 как свободный.
Первая попытка восстановления состояла в том, что мы удалили тот инод, с
которым перекрещивался корневой каталог, смонтировали том командой
``безусловного" монтирования (которая позволяла монтировать поврежденные тома),
создали командой mkdir
каталог lost+found
и вновь
запустили fsck
. Попытка завершилась крахом. Беда была в том, что,
как оказалось, корневой каталог пересекался также и со списком свободных блоков,
то есть создание каталога, а потом его расширение командой fsck
снова приводило к порче корневого каталога и задача сводилась к предыдущей.
Таким образом, нам необходимо было либо починить вручную список свободных
блоков, либо найти способ создать директорию lost+found
без
обращений к этому списку. Дополнительная сложность состояла в том, что с
каталогом lost+found
не связано фиксированного инода, а определить
инод старого lost+found
не представлялось возможным.
Мы решили не связываться с починкой списка свободны блоков. Вместо этого мы
просмотрели листинг последней ``правильной" резервной копии, нашли там ненужный
пустой каталог и присоединили его к корневому под названием
lost+found
. После этого нам оставалось лишь уповать на то, что
вновь создаваемые fsck
ссылки на файлы не приведут к необходимости
удлинить наш lost+found
. К счастью, этого не произошло: все потомки
корневого каталога благополучно получили имена в lost+found
. По
существу, ФС пришла в пригодное для чтения состояние, оставалось лишь правильно
определить имена найденных каталогов. Это также оказалось относительно несложной
задачей: большая часть каталогов на томе была домашними каталогами пользователей
и их имена можно было восстановить на основании того, кому эти каталоги
принадлежали. Для остальных каталогов имя достаточно легко определялось после
сопоставления их содержимого с листингом резервной копии.
Во многих современных ОС реализованы устойчивые к сбоям файловые системы: jfs в AIX(версия Unix, поставляемая IBM), Merlin), Veritas в UnixWare, NTFS в Windows NT. Практически все такие ФС основаны на механизме, который по-английски называется intention logging (регистрация намерений).
*
Термин, вынесенный в заголовок этого подпункта, является дословной
калькой (возможно, не очень удачной) англоязычного термина intention
logging. В русском языке, к сожалению, еще нет общепринятого термина для
этого понятия.
*
Идея журналов регистрации намерений пришла из систем управления базами данных. В СУБД часто возникает задача внесения согласованных изменений в несколько разных структур данных. Например, банковская система переводит миллион долларов с одного счета на другой. СУБД вычитает 1.000.000 из суммы на первом счету, затем пытается добавить ту же величину ко второму счету... и в этот момент происходит сбой.
Для СУБД этот пример выглядит очень тривиально, но мы выбрали его потому, что он похож на ситуацию в файловой системе: в каком бы порядке ни производились действия по переносу объекта из одной структуры в другую, сбой в неудачный момент приводит к крайне неприятной ситуации. В СУБД эта проблема была осознана очень давно и была очень острой - ведь миллион долларов всегда был намного дороже одного сектора на диске...
Удовлетворительное решение проблемы заключается в следующем:
Во-первых, все согласованные изменения в СУБД организуются в блоки, называемые транзакциями (transaction). Каждая транзакция осуществляется как неделимая (атомарная) операция, во время которой никакие другие операции над изменяемыми данными не разрешены.
Во-вторых, каждая транзакция осуществляется в три этапа.
Журнал часто называют журналом регистрации намерений (intention log), что очень хорошо отражает суть дела, потому что в этот журнал записываются именно намерения (intentions).
При использовании отложенной записи транзакция считается полностью завершенной, только когда последний блок измененных данных будет физически записан на диск. При этом в системе обычно будет одновременно существовать несколько недовыполненных транзакций. Легко понять, что при операциях с самим журналом отложенную запись вообще нельзя использовать.
Если произошел сбой системы, после перезагрузки запускается программа починки базы данных. Эта программа просматривает конец журнала.
Нужно отметить, что данные, необходимые для выполнения отката, могут иметь большой объем. Фактически это копия всех данных, подвергающихся изменению в ходе транзакции. Многие СУБД, такие как ORACLE, хранят эти данные не в самом журнале, а в специальной области данных, называемой сегмент отката (rollback segment).
Более подробная информация о работе журналов намерений в базах данных может быть найдена в соответствующей литературе ([16] и др.). Необходимо только отметить, что книги и даже фирменная документация по простым СУБД типа dBase или FoxPro здесь не помогут, поскольку эти пакеты не содержат средств журналирования.
Легко понять, что идея журнала намерений достаточно естественно переносится в программу управления файловой системой. Но здесь возникает интересный вопрос - что же считать транзакцией: только операции по распределению пространства на диске или также все операции по изменению данных?
Первый вариант проще в реализации и оказывает меньшее влияние на производительность; зато он гарантирует только целостность самой ФС, но не может гарантировать целостности пользовательских данных, если сбой произойдет в момент записи в файл.
Второй вариант требует выделения сегмента отката и сильно замедляет работу. Действительно, ведь теперь данные пишутся на диск два раза: сначала в сегмент отката, а потом в сам файл. Зато он существенно снижает вероятность порчи пользовательских данных.
Ряд современных ФС с регистрацией намерений поддерживают оба режима работы и
предоставляют выбор между этими вариантами администратору системы. Например, у
файловой системы vxfs
или Veritas, входящей в пакет
UnixWare (версия Unix SVR4, поставляемая фирмой Novell),
существует две версии. Одна версия, поставляемая вместе с системой по умолчанию,
включает в транзакцию только системные данные. Другая, ``advanced'', версия,
которая поставляется за отдельные деньги, осуществляет регистрацию намерений как
для системных, так и для пользовательских данных.
В Veritas 2 дисковый том разбит на области, называемые группами цилиндров (термин, унаследованный из UFS - файловой системы BSD Unix). Каждая группа цилиндров имеет свою карту свободных блоков, участок динамической таблицы инодов и журнал намерений. Журнал намерений организован в виде кольцевого буфера записей о транзакциях. В журнал пишутся данные только о транзакциях над инодами, принадлежащими к этой группе цилиндров. При этом в каждой группе может исполняться одновременно несколько транзакций и окончанием транзакции считается физическое завершение записи модифицированны данных. Количество одновременно исполняющихся транзакций ограничено объемом журнала, но поскольку каждая группа цилиндров имеет свой журнал, это ограничение не играет большой роли.
Кроме общесистемных сбоев, ФС должна обеспечивать средства восстановления при физических сбоях диска. Наиболее распространенным видом таких сбоев являются нечитаемые - ``плохие'' (bad) - блоки, появление которых обычно связано с физическими дефектами магнитного носителя.
Быстрее всего плохие блоки возникают на гибких магнитных дисках, которые соприкасаются с головкой чтения/записи и из-за этого подвержены физическому износу и повреждениям. Кроме того, гибкие диски подвергаются опасным воздействиям и вне дисковода. Например, при вносе дискеты с улицы в теплое помещение на поверхности диска будет конденсироваться влага, а соприкосновение головки дисковода с влажным диском практически наверняка повредит магнитный слой.
Жесткие магнитные диски помещены в герметичный корпус и не соприкасаются с головками дисковода, поэтому срок службы таких дисков намного больше. Появление одиночных плохих блоков на жестком диске скорее всего свидетельствует о заводском дефекте поверхности или же о том, что магнитный слой от старости начал деградировать.
Еще одной причиной порчи жестких дисков является соприкосновение головок чтения/записи с поверхностью вращающегося диска (head crash). Обычно это приводит к повреждению целой дорожки или нескольких дорожек диска, а зачастую и самой головки. Для несъемных жестких дисков в герметичных корпусах (т.наз. винчестерских дисков) это означает потерю целой рабочей поверхности.
Обычно ошибки данных обнаруживаются при чтении. Дисковые контроллеры используют при записи кодировку с исправлением ошибок, чаще всего, коды типа CRC (Cyclic Redundancy Code - циклический избыточный код), которые позволяют обнаруживать и исправлять множественные ошибки. Тем не менее, если при чтении была обнаружена ошибка, большинство ОС отмечают такой блок как плохой, даже если данные удалось восстановить на основании избыточного кода.
В файловой системе FAT плохой блок или кластер, содержащий такой блок,
отмечается кодом 0xFFB
или 0xFFFB
для дисков с
16-разрядной FAT
. Эта файловая система не способна компенсировать
плохие блоки в самой FAT
или в корневом каталоге диска. Такие диски
просто считаются непригодными для использования.
В ``сложных'' файловых системах обычно используется более сложный, но зато и более удобный способ обхода плохих блоков, называемый горячей заменой (hotfixing). При создании файловой системы отводится небольшой пул блоков, предназначенных для горячей замены. В файловой системе хранится список всех обнаруженных плохих блоков, и каждому такому блоку поставлен в соответствие блок из пула горячей замены. При этом плохие блоки, на которые оказались отображены системные структуры данных, например участок таблицы инодов, также подвергаются горячей замене. Таблица горячей замены может быть как статической, так и динамической.
На первый взгляд, динамическая таблица горячей замены предпочтительна, однако не нужно забывать о двух немаловажных факторах.
С учетом обоих факторов кажется целесообразным установить предел количества плохих блоков, после достижения которого диск нуждается в замене. Нужно отметить также, что этот предел не может превышать нескольких процентов общей емкости диска. В свете этого небольшая статическая таблица блоков горячей замены представляется вовсе не такой уж плохой идеей.
При эксплуатации ОС может возникнуть необходимость монтировать файловые системы, отличающиеся от ``родной'' ФС. Особенно часто она возникает в организациях, где используются ОС нескольких разных типов. Да и в организациях, работающих с монокультурой MS DOS/MS Windows, такая потребность возникает все чаще. Во-первых, доступ к файлам на файловом сервере осуществляется существенно иными способами, чем к файлам на локальном диске, даже если на сервере стоит та же ДОС с той же ФС типа FAT. Во-вторых, дисководы для CD-ROM становятся все дешевле и распространяются все шире. При этом стандартная ФС на CD-ROM - вовсе не FAT.
Решение этой проблемы приходит в голову сразу - необходим драйвер файловой системы со стандартным интерфейсом, подобный драйверу внешнего устройства. Естественно, набор функций такого драйвера должен быть существенно иным:
Кроме собственно драйвера ФС, для ее полноценной поддержки нужны следующие программы:
mkfs
или FORMAT
;
fsck
или
CHKDSK
;
Например, дистрибутив ОС UnxiWare 2.0 фирмы SCO, основанной на UNIX System V R4.2, содержит драйверы следующих файловых систем:
SQEESE
в RT-11. Используется для
хранения ядра системы, и нескольких конфигурационных файлов, используемых при
загрузке. Все эти данные считываются только при загрузке системы и
перезаписываются только при изменениях конфигурации ядра, поэтому высокая
производительность от этой ФС не требуется.
Любопытно, что даже MS/DR DOS версий выше 3.30 имеют возможность
устанавливать драйвер файловой системы. Такой драйвер может быть реализован
путем перехвата недокументированных функций прерывания 0x2F
-
группы функций ``Network Redirector'' и ``IFS''. Таким образом реализован ряд
сетевых клиентов для MS/DR DOS. К сожалению, авторы не смогли найти
полноценного описания этих функций.
Next: Безопасность Up: Contents
Т.Б.Большаков: tbolsh@inp.nsk.su