Category Archives: file systems

внутренности ufs

Так как про fsdb для файловой системы vxfs я уже писал, то решил описать и fsdb для ufs, ведь вопросы иногда возникают, несмотря на возраст файловой системы и относительно полный man.
При работе с fsdb надо быть очень аккуратным. Одно неверное движение и данных как не бывало.
Запускаем fsdb c возможностью записи :

fsdb -o w /dev/rdsk/_your_file_system_

У fsdb своеобразный синтаксис, похожий на adb. Все команды начинаются с :
Так например есть команда :ls
Также будет работать :ls /
Не стоит забывать, что / это именно корень файловой системы и если вы открыли с помощью fsdb var то это будет именно корень файловой системы
var а ни в коем случае не корневой файловой системы.
Тут у :ls есть всего 2 опции -l выводит список вместе с номером inod’а и -R делает рекурсивный листинг.
Так как есть :ls то есть и :cd
Также есть очень полезная команда :base . С помощью ее можно поменять шестнадцатеричную систему (по умолчанию) на десятеричную. Делается это так :

:base=0t10

В fsdb есть понятие “точка”. То есть вы сначала выбираете объект, с которым хотите работать, тем самым присваиваете точке его адрес. Все же последующие команды будут выполняться относительно значения “точки”
Так если вы хотите что-то сделать с 5 inode’ом, то сначала вы его выбираете.
Делается так

 5:inode

Далее вы можете вывести информацию об этом inode :

?i

Эти две команды можно объединить в одну :

5:inode?i

/dev/rdsk/c1t3d0s0 > 5:inode?i
i#: 5 md: d---rwxr-xr-x uid: 0 gid: 3
ln: 4 bs: 2 sz : c_flags : 0 200

db#0: 2fc
accessed: Wed Apr 29 16:24:50 2009
modified: Wed Feb 25 13:40:05 2009
created : Wed Feb 25 13:40:05 2009

Думаю вывод всем понятен. Возможно лишь стоит уточнить значение поля db. DB расшифровывается как direct block. Именно в db и записываются сами данные. Как я надеюсь все помнят inode ufs имеет 12 direct block’ов и 3 indirect block’ов. IB это блок, в котором содержаться не данные, а до 2048 адресов других блоков. Причем только первый ib будет содержать ссылки на db. Если же этого не хватает, то будет использован второй, так называемый double indirect block, который содержит 2048 ссылок на ib, которые уже содержат ссылки непосредственно на db. Вот Соответственно третий ib это triple indirect block и что там содержится думаю понятно.
Если вернуться к нашему случаю, то мы видим что inode состоят из одного db ( нулевого ) в блоке 2fc.
Но мы отвлеклись.
Файл это или директория можно понять по полю md (mode). Если флаг d есть, значит директория, если нет, то файл 😉
Если оказывается что это директория :ls покажет вам в ней есть.

Я надеюсь все помнят что такое директория в ufs. Это ни что иное как массив, где перечислены соответствие inode определенному имени файла.
Так после того, как вы выбрали inode , который является директорией, вы можете посмотреть и изменить эти поля.
:ls собственно эти записи вам и показывает, но вот только немного не в том порядке. В “том” порядке это можно сделать вот так :

0:dir?d
1:dir?d
2:dir?d

Чтобы все время это не вводить достаточно лишь просто нажимать Enter и
будет выполняться :dir?d к следующему элементу.

Ну или чтобы вывести 20 записей, хранящиеся в 0 блоке 2 inode’а :

2:ino; 0:db:block,20?d

Или же

 308:fragment,20?d

Если вы вдруг захотите, чтобы какая-то из записей (допустим пятая) указывала не на 22 inode а к примеру на 66 то все в ваших руках 😉
Делается это так :

5:dir?d=42

так как 42 – 66 в hex

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

 5:dir:nm="test"

вуаля и имя и записи меняется.

С директориями разобрались. Теперь к файлам.
В общем-то все тоже самое.

/dev/rdsk/c1t3d0s0 > :ls -l /etc/passwd
/etc:
i#: a317 passwd
/dev/rdsk/c1t3d0s0 > 0xa317:inode?i
i#: a317 md: ----rw-r--r-- uid: 0 gid: 3
ln: 1 bs: 2 sz : c_flags : 0 395

db#0: 6a8db
accessed: Wed Apr 29 16:20:06 2009
modified: Mon Apr 27 11:59:48 2009
created : Mon Apr 27 11:59:48 2009

/dev/rdsk/c1t3d0s0 > 0:db:block,100/c

И мы видим содержание /etc/passwd, Можем ли мы что-то поменять? Безусловно!
Это можно сделать несколькими способами.
Заполнить часть файла нулями :

6a889:fragment,4=fill=0x0

Или же просто записать в определенный адрес :

1aa22400=0xffff

А если нужно записать текст, то можно сделать вот так :

1aa36c00="root"

Итак, какой же самый простой способ удалить inode на незамонтированной файловой системе? Конечно же используя команду clri 🙂