ЦЕЛОСТНОСТЬ ФАЙЛОВОЙ СИСТЕМЫ

Уже упоминалось, что файловая система - это раздел операционной системы. В обязанности операционной системы входит обеспечение целостности данных файловой системы. Действительная потеря данных - большая редкость; файловые системы UNIX очень устойчивы к порче данных. Это вызвано наличием некоторой избыточности в специальных структурах, невидимых пользователю. Именно эти структуры обеспечивают целостность файловой системы. Например, если при работе системы выходит из строя питание, теряется очень мало информации. Любое нарушение обычно затрагивает один или два файла, делая их недоступными. Почти во всех случаях операционная система может исправить любое повреждение файлов. Очень редко повреждение делает недоступной всю файловую систему.

Для исправления поврежденных файловых систем операционная система пользуется программой fsck ("filesystem check" - "проверка файловой системы"). Эта программа проверяет совместимость файловой системы. В случаях потери содержимого файла (что бывает редко) единственный способ восстановить потерянные данные - воспользоваться резервной копией файловой системы. Программа fsck выполняется автоматически для корневой файловой системы при начальной загрузке. Сообщения состояния программы fsck имеют следующий вид:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  ** Phase 1 - Check Blocks and Sizes
Ё                         (Фаза 1 - Проверка блоков и размеров)
Ё  ** Phase 2 - Pathnames          (Имена путей)
Ё  ** Phase 3 - Connectivity       (Связность)
Ё  ** Phase 4 - Reference Counts   (Счетчики обращений)
Ё  ** Phase 5 - Check Free List    (Проверка свободного списка)
Ё
Если система прекращена аварийно (выход из строя питания), появятся другие сообщения, на первый взгляд тревожные:

FREE INODE COUNT WRONG IN SUPERBLK (FIX?)

(Ошибка в счетчике свободных индексных дескрипторов файлов в суперблоке - исправить?)

На самом деле сообщения такого рода являются обычными в случае, если система не была остановлена нормально; здесь следует лишь ввести y, и fsck продолжит работу. Это можно сделать без вмешательства администратора системы, но, как правило, лучше все же знать, что происходит с файловой системой при возникновении проблемы.

В целях рассмотрения понятия целостности системы и принципов функционирования fsck следует описать структуру, лежащую в основе простого понятия файлов, каталогов и файловых систем. Хотя вникать в принципы файловой памяти не обязательно, полезно знать, к чему относятся сообщения, подобные приведенному выше; после этого они не будут выглядеть столь загадочно. После изучения данного раздела вам станут понятны некоторые основные принципы операционных систем UNIX. В разделе "Восстановление файловой системы с помощью fsck" описана простая механика использования команды fsck. Последующие подразделы описывают структуры файловой системы, с которыми работает fsck.

Файлы в системах UNIX

Каждая файловая система содержит специальные структуры, позволяющие операционной системе осуществлять доступ и сопровождать файлы и данные, хранящиеся в файловой системе. Нас интересует разрушение и восстановление именно этих структур.

Структура файловой системы базируется на принципе хранения данных на жестких дисках. Хотя жесткий диск и содержит все данные, используемые системой, они отнюдь не хранятся там маленькими аккуратными островками, соответствующими отдельным файлам. Вы вряд ли сможете, указав какое-либо место на жестком диске, с уверенностью сказать: "Мой файл записан именно в этой части диска". На самом деле данные, скорее всего, будут разбросаны по диску, и операционная система использует сложную схему адресации, чтобы иметь доступ к каждому из фрагментов, на которые разбивается файл, и представить их всех пользователю как единое целое.

Разброс данных связан с тем, что операционная система на самом деле работает не с файлами, а с элементами данных. Чтобы понять, что это означает, предположим, что файл создан и записан в одну область на диске. Теперь допустим, что вы редактируете этот файл и удаляете из него несколько предложений вразброс. Значит, вы теперь используете немного меньше пространства на диске, чем вначале. Это пространство имеет ряд разрывов в области, которую занимал файл. Пространство на диске ценится дорого и не тратится зря. Эти освободившиеся маленькие участки памяти выделяются другим файлам. Представьте себе этот процесс с участием сотен файлов и дюжины пользователей, и вам станет яснее принцип сопровождения файлов. Благодаря эффективности алгоритмов (формул), используемых операционной системой, этот процесс является очень эффективным и надежным.

Файловые системы в системах UNIX

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

Блоки не записываются сразу на жесткий диск. Чтобы свести к минимуму время поиска данных на жестком диске, недавно использовавшиеся блоки данных хранятся в кэше в специальных структурах памяти - буферах. Именно использование этих структур повышает эффективность операционной системы. Когда скопится достаточное количество данных для записи в один или несколько полных блоков на диске, буфер "сбрасывается" - содержавшаяся в нем информация записывается на диск. При сбое какая-то информация всегда теряется, так как недавно изменившиеся данные еще не записаны на диск, но это несущественно.

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

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

Информация из версии суперблока на диске считывается, когда файловая система смонтирована; эта информация поддерживается и модифицируется в памяти по мере развития активности в системе. Информация записывается обратно на диск с регулярными интервалами по команде update, которая обычно выполняется сценариями /etc/rc2, когда система запущена. Команда update вызывает команду sync(C) каждые 30 секунд, в результате чего происходит запись на диск версии суперблока в памяти и буферов. При аварии системы, если записанная на диск информация недостаточно актуальна, файловая система может быть запорчена.

Причины порчи файловой системы

Любая из структур, упомянутых в данном разделе, может оказаться запорченной. Это означает разрушение данных или структур, используемых для поиска данных. Это может случиться по нескольким причинам:

Аппаратный сбой
Аппаратные сбои происходят редко. Лучший способ решения такой проблемы - обеспечить неукоснительное следование рекомендованным процедурам диагностики и обслуживания.
Программные прерывания
Ошибки, вызывающие сбой программы, могут быть результатом потери некоторых данных. Здесь трудно дать общие рекомендации, так как очень велик диапазон возможных причин.
Ошибка по вине человека
Это основная причина очень многих случаев порчи файловой системы, как ни горько это признать. Существуют правила работы с файловыми системами, которые следует соблюдать.

Правила проверки файловых систем

1. ВСЕГДА проверяйте файловую систему командой fsck, прежде чем ее монтировать. Ничто так не усложняет проблему очистки запорченной файловой системы, как использование ее в поврежденном состоянии.

2. НИКОГДА не удаляйте файловую систему физически без предварительного демонтирования.

3. ВСЕГДА применяйте команду sync перед остановом системы и перед демонтированием файловой системы. (Команда sync записывает данные из буферного кэша обратно на диск.)

Регулярное дублирование файловой системы дает наилучшие гарантии постоянной целостности файловой системы.

Восстановление файловой системы командой fsck

Файловую систему можно исправить командой fsck. Перед выполнением fsck файловую систему нужно демонтировать. (Корневую файловую систему демонтировать нельзя, так что в этом случае следует сначала остановить систему, а затем вновь ее запустить в однопользовательском режиме (режиме технического обслуживания).) Команда fsck проверяет различные структуры на диске и пытается согласовать их. Она по возможности восстанавливает соединения, разрешает ссылки - "чистит" файловую систему.

Формат команды:

        fsck specialfile
@ Пользователи sysadmsh выбирают: Filesystems->Checks

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

Замечание

Программа fsck на самом деле является фронтальной - она выполняет лишь предварительную обработку, запуская для каждого типа файловой системы свою версию fsck. Для исправления файловых систем DOS программа fsck вызывает специальную версию.

Предположим, например, что вы запустили систему после сбоя питания и находитесь в однопользовательском режиме. Чтобы проверить файловую систему /u, представленную устройством /dev/u, введите

fsck /dev/u и нажмите <Return>. Программа проверит файловую систему и выдаст следующие сообщения о ходе своей работы:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  ** Phase 1 - Check Blocks and Sizes
Ё  ** Phase 2 - Pathnames
Ё  ** Phase 3 - Connectivity
Ё  ** Phase 4 - Reference Counts
Ё  ** Phase 5 - Check Free List
Ё

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

Заметим, что команда fsck удалит любой файл, который она сочтет слишком сильно запорченным и не подлежащим восстановлению. Можно задать возможность выбора для fsck - выполнять восстановление или нет. Вы можете заставить fsck проигнорировать нарушение целостности, если вы сочтете проблему настолько серьезной, что либо пожелаете разобраться с ней самостоятельно с помощью утилиты fsdb(ADM), либо решите восстановить систему с резервных копий. Если вы не можете использовать fsdb, вам следует дать fsck возможность исправлять нарушения целостности, в противном случае файловая система может оказаться непригодной к использованию.

Заметьте, что вам может понадобиться несколько раз выполнить команду fsck, прежде чем вся файловая система будет очищена. Полный список сообщений об ошибках можно найти в странице Руководства, соответствующей fsck(ADM).

Краткое описание этапов fsck

Команда fsck просматривает и проверяет каждую из вышеупомянутых структур. На каждом этапе выполняется сравнение компонентов и проверка согласованности этих компонентов друг с другом.

На этапе 1 проверяются блоки и размеры. Команда fsck читает список индексных дескрипторов файлов, чтобы определить размеры и отыскать блоки, используемые каждым из файлов. Эти дескрипторы файлов проверяются на действительность (проверка типа и размера дескриптора, проверка на равенство нулю счетчика связей) и на наличие дефектных или дублированных блоков. (Дефектными являются блоки, значения которых выходят за границы файловой системы.) Когда fsck спрашивает, следует ли чистить дескриптор файла, это означает обнуление в нем дефектной информации. В итоге файл или каталог, соответствующий этому дескриптору, будет удален. Дублированный блок означает, что два дескриптора указывают один и тот же блок на диске. Команда fsck пытается определить оригинальный дескриптор, чтобы скорректировать дубликат на этапе 2.

На этапе 2 проверяются имена путей. Должны быть удалены элементы каталога для файлов, удаленных на этапе 1. На этапе 2 исправляются ошибки, вызванные неправильным состоянием индексных дескрипторов файлов, выходом указателей этих дескрипторов за пределы диапазона; исправляются каталоги, указывающие на дефектные дескрипторы файлов, как описано выше. В случае файлов с дублированными блоками, обнаруженными на этапе 1, fsck попытается удалить оба файла (это одна из немногих ситуаций, требующих вмешательства администратора системы).

На этапе 3 проверяются связи. На этапе 2 удалены каталоги, не указывающие на действительные файлы. На этапе 3 восстанавливаются связи с файлами, которые выпали из структуры каталога. Все действительные файлы, на которые нет ссылки, помещаются в специальный каталог под названием lost+found. Поскольку каталог был отсоединен, имя файла теряется; в каталоге lost+found файлу присваивается номер.

На этапе 4 проверяются счетчики обращений. Команда fsck проверяет счетчик связей для каждого элемента, благополучно прошедшего этапы 2 и 3. В некоторых случаях файлы, на которые не было указателя в структуре каталога, но которые все же обладают индексными дескрипторами, могут быть вновь связаны с файловой системой по каталогу lost+found.

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

На этапе 6 восстанавливается свободный список. Система реконструирует список свободных блоков в соответствии с измененной файловой системой, если это было определено на этапе 5.

Автоматическая проверка файловой системы

Иногда операционная система во время старта выдает запрос на проверку файловой системы. Обычно это имеет место после ненормального останова (например, в результате потери мощности в питании). После проверки файловой системы все файлы, разрушенные в процессе останова, восстанавливаются.

Исправление файловой системы с помощью команды fsdb

Если после фатального сбоя суперблок файловой системы оказывается настолько поврежден, что fsck не в состоянии его восстановить, можно с помощью команды fsdb ("filesystem debugger" "отладчик файловой системы") вручную исправить суперблок, наставив "заплат". С большой вероятностью команда fsdb понадобится, если fsck аварийно прекращается или выдает слишком много ошибок.

Так как fsdb - очень мощное средство, позволяющее непосредственно изменять суперблок (который содержит важную информацию о файловой системе), использовать его следует с величайшей осторожностью. Почти во всех случаях, когда требуется применить fsdb, приходится менять только одну или две ячейки суперблока, представляющие fsize и isize; им возвращаются значения, обычные для вашей файловой системы. fsize - общее число блоков в файловой системе; isize - количество индексных дескрипторов файлов, назначенных файловой системе.

Далее приводятся порядок использования fsdb в целях изменения значений fsize и isize.

1. Получите нормальные значения fsize и isize в вашей файловой системе. Вы должны были записать их согласно инструкции в конце процедуры установки, описанной в документе Installation Guide. Если вы этого не сделали, можно получить размер файловой системы с помощью divvy и оценить число индексных дескрипторов файлов. Для определения размера файловой системы воспользуйтесь командой

divvy -b 1 -c 1 Размеры файловых систем выводятся на экран в виде диапазона номеров блоков. Нужно вычесть номер начального блока из номера последнего, и получится размер файловой системы. Приблизительное число индексных дескрипторов файлов равно размеру, умноженному на .125.

2. Убедитесь в том, что fsize и isize вашей файловой системы запорчены.

3. Найдите fsize и isize в суперблоке.

4. Установите fsize и isize равными их нормальным значениям.

Все эти шаги подробно описаны в последующих разделах. В странице Руководства, соответствующей fsdb(ADM), приведено несколько других способов применения fsdb для просмотра и обработки суперблока; однако эти возможности рекомендуется использовать только опытным администраторам системы.

Проверка нарушения значений fsize и isize

При проверке файловой системы после фатального сбоя команда fsck считывает из суперблока размер файловой системы. Если значения fsize и isize, хранящиеся в этот момент в суперблоке, не являются нормальными значениями для файловой системы, fsck выдает на экран результаты проверки размера и заканчивает работу, как показано в следующем примере:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  # fsck /dev/root
Ё  /dev/root
Ё  /dev/root   File System: /  Volume: root
Ё  Size check: fsize 0 isize 0
Ё  #
Ё

Сравните значения fsize и isize, выданные командой fsck (в нашем примере - 0), с нормальными значениями вашей файловой системы. Если они отличаются, придется выполнить fsdb, чтобы заменить значения в суперблоке на нормальные значения файловой системы.

Иногда неправильной оказывается только одна из этих величин, хотя информация, выданная fsck, показывает нарушение обоих значений. При выполнении fsdb вы увидите фактические значения fsize и isize, записанные в суперблоке, и поймете, сколько значений вам придется менять - одно или оба. Для выполнения fsdb введите следующую команду, задав в качестве filesystem имя файловой системы:

fsdb /dev/filesystem

Полученный в результате вывод будет аналогичен приведенному в следующем примере:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  # fsdb /dev/root
Ё  /dev/root(/): 1K byte Block File System
Ё  FSIZE =  1895959976, ISIZE = 7216
Ё

В данном примере fsdb показывает, что некорректно только значение fsize (хотя fsck выдала некорректность обоих). fsdb всегда работает аккуратнее.

Поиск fsize и isize в суперблоке

Чтобы заново установить значения fsize и/или isize, нужно уметь отыскивать эти значения в суперблоке. Это можно сделать, перейдя к первому адресу суперблока и проверив первые два значения, которые и есть суть fsize и isize. В файловых системах UNIX суперблок начинается по адресу 512, а в файловых системах XENIX - по адресу 1024. Вот пример для файловой системы UNIX:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  # fsdb /dev/root
Ё  /dev/root(/): 1K byte Block File System
Ё  FSIZE = 28890, ISIZE = 7216
Ё  512
Ё  001000:      000705 (453)
Ё  
Ё  001002:      000000 (0)
Ё  
Ё  001004:      070332 (28890)
Ё
(Клавиша <Return> используется для перехода от одного значения в суперблоке к другому.) Выводятся следующие величины: адрес (в восьмеричном виде), записанное по этому адресу значение (также в восьмеричном виде) и его десятичный эквивалент (в скобках). Убедиться в том, что вы находитесь в нужном месте суперблока, можно следующим образом: третья выведенная на экран величина (после второго нажатия клавиши <Return>) - fsize - должна совпадать со значением, выведенным командой fsdb при ее запуске (FSIZE). Заметим, что fsdb выдает значения в блоках по 1К. Если вы возьмете размер файловой системы у команды df, то он окажется ровно вдвое больше размера, сообщаемого командой fsdb. Это связано с тем, что df выдает ответы в 512-байтных блоках. Если вам нужно изменить значение FSIZE, имея размер, выданный командой df, его следует разделить на два. Если же вы использовали номер из команды divvy, его преобразовывать не надо, так как divvy, как и fsdb, пользуется блоками 1К.

Со значением ISIZE дело обстоит иначе. Это значение, выданное командой fsdb, нужно преобразовать, прежде чем сравнивать со значением первой величины в суперблоке (isize).

Значение isize, записанное в суперблоке, является адресом первого блока, расположенного после блоков, которые выделены для индексных дескрипторов файлов. Чтобы сделать значение isize более выразительным, fsdb преобразует этот адрес в число назначенных индексный дескрипторов файлов (ISIZE). Это число нужно преобразовать обратно в адрес блока путем деления ISIZE на 16 (число дескрипторов в блоке) и сложения с 2 (для учета первых блоков файловой системы, которые используются для других целей: блок начальной загрузки и суперблок). Результат (isize) должен равняться числу, выведенному на экран в качестве первого адреса в суперблоке.

Установка нормальных значений для fsize и isize

Теперь, когда вы знаете точное местоположение fsize и isize в суперблоке, вы можете использовать fsdb, чтобы перейти непосредственно к соответствующему адресу, пройти суперблок по словам и присвоить адресу новое значение.

Замечание

Прежде чем пользоваться командой fsdb, убедитесь в том, что файловая система демонтирована.

Чтобы перейти к первому адресу суперблока, введите команду абсолютного адреса, который фиксирован для файловой системы (512 для файловых систем UNIX и 1024 для файловых систем XENIX). В следующем примере проверяется файловая система UNIX:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  512
Ё  001000:      000173 (123)
Ё
По умолчанию fsdb считывает адреса, вводимые вами в виде десятичных слов (512), а выводит адреса восьмеричными байтами (001000). Значение, хранящееся по заданному адресу, также выводится в восьмеричном виде (в скобках дается десятичный эквивалент).

Введя адрес в виде слова, можете нажимать <Return>, чтобы продвигаться в суперблоке каждый раз на одно слово.

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  002000:      000173 (123)
Ё  
Ё  002002:      000000 (0)
Ё  
Ё  002004:      007461 (3889)
Ё

В файловых системах UNIX для достижения значения fsize нужно дважды нажать <Return>, а в файловых системах XENIX - только один раз. (Это связано со способом хранения значений в суперблоке для файловых систем UNIX.)

Замечание

Если при вводе начального адреса на экране появится следующее сообщение об ошибке:

         block out of range          (блок вне диапазона)
то это значит, что запорченное значение fsize настолько мало, что программа fsdb решила, что вы не сможете продвинуться в суперблоке так далеко. Чтобы отключить регистрацию ошибок, введите заглавную букву O. Теперь можно беспрепятственно вводить адрес.

В любой момент можно нажать клавишу INTERRUPT (DEL) или <CTL>d, чтобы прекратить вывод адресов на экран.

Предположим, что при переходе ко второму значению в суперблоке на экран выдано значение fsize, равное 0 (вместо нормального значения 3889):

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  002000:      000173 (123)
Ё  
Ё  002002:      000000 (0)
Ё  
Ё  002004:      000000 (0)
Ё

Вы можете присвоить новое значение адресу, который вы видите в данный момент, с помощью команды присваивания fsdb. (Перед тем, как вносить какие-либо изменения, убедитесь, что вы знаете, что вы собираетесь сделать. fsdb сразу пишет прямо на диск, не ожидая sync.) Введите знак равенства, и за ним - новое значение:

здддддддддддддддддддддддддддддддддддддддддддддддддддддддддддддд
Ё  002002:      000000 (0)
Ё  <Return>
Ё  002004:      000000 (0)
Ё  =3889
Ё  002004:      007461 (3889)
Ё  q
Ё

Когда fsdb выдаст подтверждение на запрошенное вами изменение, выйдите из fsdb. Теперь снова можно попробовать выполнить fsck.

Замечание

Перед изменением isize не забудьте выполнить вычисления (деление на 16 и прибавление 2) для величины ISIZE, выданной командой fsdb во время нормальной работы системы. В случае fsize используйте значение FSIZE, выданное fsdb при нормальной работе системы, без каких-либо вычислений.