Лабораторная работа "Управление файловыми системами" - efanov/mephi GitHub Wiki

Цель

Изучить свойства файловой системы и командный интерфейс управления файловыми системами.

Команды, изучаемые в лабораторной работе: partprobe, blkid, lsblk, dd, truncate, df, du, losetup, mkfs, tune2fs, dumpe2fs, debugfs, mount, umount, wipefs, cryptsetup.

Для исследования файловой системы будет использоваться механизм loop device.

Задание

1. Изучение свойств блочных устройств

Вывести разными способами информацию о блочных устройствах. Определить тип таблицы разделов (GPT), количество и номера разделов, мажорные и минорные номера блочных устройств.

$ ls -l /dev/sda{,[123]}
brw-rw----. 1 root disk 8, 0 фев 15 23:46 /dev/sda
brw-rw----. 1 root disk 8, 1 фев 15 23:46 /dev/sda1
brw-rw----. 1 root disk 8, 2 фев 15 23:46 /dev/sda2
brw-rw----. 1 root disk 8, 3 фев 15 23:46 /dev/sda3
$ lsblk --list
NAME      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   128M  0 loop 
sda         8:0    0  1024G  0 disk
sda1        8:1    0   512G  0 part / 
...
nvme0n1   259:0    0   256G  0 disk 
nvme0n1p1 259:1    0   128M  0 part /boot/efi
nvme0n1p2 259:2    0     1G  0 part /boot
...
$ cat /proc/diskstats 
   8       0 sda 554 0 32719 5640 18 0 0 541 0 3557 6724 0 0 0 0 18 541
   8       1 sda1 182 0 15128 1822 0 0 0 0 0 1790 1822 0 0 0 0 0 0
...
 259       0 nvme0n1 239227 203994 15764226 124220 813706 734932 21514061 839863 0 280666 1000494 0 0 0 0 28241 36410
 259       1 nvme0n1p1 234 249 13796 50 19 0 21 12 0 66 63 0 0 0 0 0 0
...
   7       0 loop0 1382 0 48421 60 427 0 118640 161 0 507 520 6 0 3141632 179 65 119
# partprobe -s
/dev/sda: gpt partitions 1 2
/dev/nvme0n1: gpt partitions 1 2 3 4 5

Вывести статистику использования файловых систем.

$ df -Th -x tmpfs -x devtmpfs
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/nvme0n1p6 ext4   49G   42G  5.4G  89% /
/dev/nvme0n1p5 ext4  974M  291M  616M  33% /boot
/dev/nvme0n1p4 vfat  599M   27M  573M   5% /boot/efi
/dev/nvme0n1p7 ext4  412G  319G   73G  82% /home

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

$ cat /proc/devices 
Character devices:
  1 mem
  5 /dev/tty
  5 /dev/console
...
Block devices:
  7 loop
  8 sd
...
259 blkext

2. Создание и монтирование файловой системы

Для эксперимента создадим новую файловую систему, но не на блочном устройстве (разделе диска), а в обычном файле. В результате в файле будет храниться образ файловой системы. Чтобы начать работать с файловой системой, нужно связать файла-образ со специальным loop-устройством, а затем выполнить монтирование loop-устройства, как для обычной файловой системы на блочном устройстве.

Для создания файла-образа выполним команду truncate, затем проверим размер созданного файла.

Создать файл размером 100 Мегабайт.

# truncate -s 100M fs-2024.img
# ls -l fs-2024.img
-rw-r--r--. 1 root root 104857600 Feb 17 02:33 fs-2024.img
# du -s fs-2024.img
0	fs-2024.img

Связать созданный файл с блочным устройством loop.

# losetup --find --show fs-2024.img
/dev/loop0
# losetup --list
NAME   SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                               DIO LOG-SEC
/dev/loop0
               0      0         0  0 /root/fs-2024.img                         0     512

Создать файловую систему, определить: размер блока, количество индексных дескрипторов и блоков данных, номера блоков с резервной копией суперблока:

# mkfs -t ext4 /dev/loop0
mke2fs 1.45.5 (07-Jan-2020)
Discarding device blocks: done                            
Creating filesystem with 102400 1k blocks and 25688 inodes
Filesystem UUID: 03cf1643-3243-4284-b6d7-97310b74a015
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

Определить UUID файловой системы.

# blkid /dev/loop0
/dev/loop0: UUID="03cf1643-3243-4284-b6d7-97310b74a015" BLOCK_SIZE="1024" TYPE="ext4"

Выполнить монтирование файловой системы, определить опции монтирования.

# mount /dev/loop0 /mnt
# mount | grep /mnt
/dev/loop0 on /mnt type ext4 (rw,relatime,seclabel)

Выполнить мониторинг файловой системы. Вывести информацию о количестве блоков и индексных дескрипторов.

# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0       93M  1.6M   85M   2% /mnt
# df -hi /mnt
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/loop0        26K    11   26K    1% /mnt

Создайте тестовый файл с читаемыми данными.

# echo Hello > /mnt/mephi

Выполнить размонтирование файловой системы.

# umount /dev/loop0

Исследование свойств файловой системы

Содержимое суперблока можно вывести командой tune2fs -l <блочное_устройство> или командой dumpe2fs -h <блочное_устройство>. В качестве аргумента <блочное_устройство> можно указать имя файла блочного устройства, содержащего файловую систему, (/dev/sda1), или метку файловой системы (LABEL=<метка>), или идентификатор файловой системы (UUID=<идентификатор>).

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

# dumpe2fs -h /dev/loop0
dumpe2fs 1.45.5 (07-Jan-2020)
Filesystem volume name:   <none>
Last mounted on:          /mnt
Filesystem UUID:          03cf1643-3243-4284-b6d7-97310b74a015
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              25688
Block count:              102400
Reserved block count:     5120
Free blocks:              93502
Free inodes:              25676
First block:              1
Block size:               1024
Fragment size:            1024
Group descriptor size:    64
Reserved GDT blocks:      256
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1976
Inode blocks per group:   247
Flex block group size:    16
Filesystem created:       Sat Feb 17 02:34:59 2024
Last mount time:          Sat Feb 17 02:51:39 2024
Last write time:          Sat Feb 17 02:51:39 2024
Mount count:              2
Maximum mount count:      -1
Last checked:             Sat Feb 17 02:34:59 2024
Check interval:           0 (<none>)
Lifetime writes:          3522 kB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:	          128
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      78438a20-5d73-41a6-8347-484a027557e0
Journal backup:           inode blocks
Checksum type:            crc32c
Checksum:                 0xea15650c
Journal features:         journal_64bit journal_checksum_v3
Journal size:             4096k
Journal length:           4096
Journal sequence:         0x00000006
Journal start:            0
Journal checksum type:    crc32c
Journal checksum:         0xbf3f5129

Как связаны следующие величины?

Block size: 1024

Inode size: 128

Inodes per group: 1976

Inode blocks per group: 247

Освободить блочное устройство.

# losetup --detach /dev/loop0
# losetup --list

Произведите поиск данных в образе файловой системы.

# grep Hello fs-2024.img 
Binary file fs-2024.img matches
# grep mephi fs-2024.img 
Binary file fs-2024.img matches

О чём говорит вывод команды grep?

Особенности алгоритма создания файловой системы

Сравните характеристики файловых систем разного размера (500 Мегабайт и 1 Гигабайт). Обратите внимание на выбранный размер блока и количество созданных индексных дескрипторов (инодов).

Сначала изучите характеристики файловой системы размером 500 Мбайт.

$ dd if=/dev/zero of=./fs-2024.img bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 0.296697 s, 1.8 GB/s
$ sudo losetup --find --show fs-2024.img 
/dev/loop0
$ sudo mkfs -t ext4 /dev/loop0
mke2fs 1.45.5 (07-Jan-2020)
Discarding device blocks: done                            
Creating filesystem with 512000 1k blocks and 128016 inodes
Filesystem UUID: d9979c30-b24c-480b-9187-158569cac725
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done 

$ sudo losetup --detach /dev/loop0 
$ rm fs-2024.img

Теперь изучите характеристики файловой системы размером 1 Гбайт.

$ dd if=/dev/zero of=./fs-2024.img bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.43769 s, 747 MB/s
$ sudo losetup --find --show fs-2024.img 
/dev/loop0
$ sudo mkfs -t ext4 /dev/loop0
mke2fs 1.45.5 (07-Jan-2020)
Discarding device blocks: done                            
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 1d15f690-c714-442a-96ae-360f5952d478
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

$ sudo losetup --detach /dev/loop0 
$ rm fs-2024.img

Какой размер блока выбрал алгоритм создания файловой системы в каждом случае? Какие ещё есть отличия?

Изучение сигнатур (magic strings) файловой системы

С помощью команды wipefs изучите магические строки файловой системы.

Создайте файловую систему.

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

# wipefs -O DEVICE,OFFSET,TYPE,UUID /dev/loop0
DEVICE OFFSET TYPE UUID
loop0  0x438  ext4 d9979c30-b24c-480b-9187-158569cac725
# wipefs --all --backup /dev/loop0
/dev/loop0: 2 bytes were erased at offset 0x00000438 (ext4): 53 ef

Восстановите магические строки из бэкапа.

# dd if=/root/wipefs-loop0-0x00000438.bak of=/dev/loop0 seek=$((0x00000438)) bs=1 conv=notrunc
2+0 records in
2+0 records out
2 bytes copied, 0.0129952 s, 0.2 kB/s
# wipefs -O DEVICE,OFFSET,TYPE,UUID /dev/loop0
DEVICE OFFSET TYPE UUID
loop0  0x438  ext4 d9979c30-b24c-480b-9187-158569cac725

Изучение механизма автоматического монтирования файловых систем /etc/fstab

  1. Вывести содержимое файла /etc/fstab
$ cat /etc/fstab

UUID=32d6eee9-ba8d-defa-8bf4-ccefd34bf14e /                       ext4    defaults        1 1
UUID=ac78c18c-5060-defa-8dc0-91145963689e /boot                   ext4    defaults        1 2
UUID=BEEA-630E                            /boot/efi               vfat    umask=0077,shortname=winnt 0 2
UUID=b1d6d09c-f4e6-defa-9b5e-b2bb8eb4d328 /home                   ext4    defaults        1 2
UUID=dfcfb4ba-3fad-defa-b507-ca5ca54c51d8 none                    swap    defaults        0 0

3. Изучение бита Set-Group-ID для директории

Создать файл размером 10 Мегабайт.

# dd if=/dev/zero of=loop-fs.img bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.0101878 s, 1.0 GB/s

Связать созданный файл с первым свободным loop-устройством и вывести информацию о всех loop-устройствах.

# losetup -fP loop-fs.img 
# losetup -a
/dev/loop1: [66309]:1846788 (/root/loop-fs.img)
# ls -l /dev/loop1
brw-rw----. 1 root disk 7, 1 Feb  6 05:04 /dev/loop1

Создадим файловую систему в файле-образе и новую точку монтирования.

# mkfs -t ext4 loop-fs.img 
# mkdir /mnt/loop-fs

Выполним монтирование файловой системы с опциями по умолчанию (т.е. с опцией -o nogrpid).

# mount -o loop /dev/loop1 /mnt/loop-fs/
# mount | grep loop-fs
/dev/loop1 on /mnt/loop-fs type ext4 (rw,relatime,seclabel)

Видно, что файловая система успешно смонтирована в директории /mnt/loop-fs/.

Теперь перейдём к изучению вопроса принадлежности файла после его создания.

Создадим в новой файловой системе тестовую директорию и файл в ней.

Создадим двух новых пользователей, новую группу, и включим этих пользователей в эту группу. Сделаем владельцем тестовой директории новую группу и дадим для неё все права на директорию.

# cd /mnt/loop-fs/
# mkdir project-2022
# useradd student1
# useradd student2
# groupadd project-2022
# usermod -aG project-2022 student1
# usermod -aG project-2022 student2
# chown :project-2022 project-2022
# chmod g+w project-2022/
# ls -ld project-2022/
drwxrwxr-x. 2 root project-2022 1024 Feb  6 05:15 project-2022/

Теперь с помощью команды su создадим в тестовой директории файлы от имени новых пользователей.

# su student1
$ touch project-2022/report1
$ exit
# su student2
$ touch project-2022/report2
$ exit
# ls -l project-2022/
total 2
-rw-rw-r--. 1 student1 student1 0 Feb  6 05:24 report1
-rw-rw-r--. 1 student2 student2 0 Feb  6 05:24 report2

Видно, что владельцем и группой-владельцем каждого файла назначается UID и GID пользователя, создавшего файл.

Теперь установим для тестовой директории бит set-group-ID и повторно создадим в тестовой директории файлы от имени новых пользователей.

# chmod g+s project-2022/
# ls -ld project-2022/
drwxrwsr-x. 2 root project-2022 1024 Feb  6 05:24 project-2022/
# su student1
$ touch project-2022/report12
$ exit
# su student2
$ touch project-2022/report22
$ exit
# ls -l project-2022/
total 4
-rw-rw-r--. 1 student1 student1     0 Feb  6 05:24 report1
-rw-rw-r--. 1 student1 project-2022 0 Feb  6 05:25 report12
-rw-rw-r--. 1 student2 student2     0 Feb  6 05:24 report2
-rw-rw-r--. 1 student2 project-2022 0 Feb  6 05:26 report22

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

Теперь сбросим для тестовой директории бит set-group-ID и выполним монтирование файловой системы, указав явно опцию -o grpid.

# chmod g-s project-2022/
# ls -ld project-2022/
drwxrwxr-x. 2 root project-2022 1024 Feb  6 05:26 project-2022/
# cd
# umount /mnt/loop-fs/
# mount -o grpid,loop /dev/loop1 /mnt/loop-fs/

Повторно создадим в тестовой директории файлы от имени новых пользователей.

# cd /mnt/loop-fs/
# su student1
$ touch project-2022/report1-grpid
$ exit
# su student2
$ touch project-2022/report2-grpid
$ exit
# ls -l project-2022/
total 6
-rw-rw-r--. 1 student1 student1     0 Feb  6 05:24 report1
-rw-rw-r--. 1 student1 project-2022 0 Feb  6 05:25 report12
-rw-rw-r--. 1 student1 project-2022 0 Feb  6 05:31 report1-grpid
-rw-rw-r--. 1 student2 student2     0 Feb  6 05:24 report2
-rw-rw-r--. 1 student2 project-2022 0 Feb  6 05:26 report22
-rw-rw-r--. 1 student2 project-2022 0 Feb  6 05:31 report2-grpid

Видно, что, как и в предыдущих двух случаях, владельцем каждого файла назначается UID пользователя, создавшего файл. А группа-владельца для обоих файлов наследуется от группы-владельца директории, не смотря на то, что у директории не установлен бит set-group-ID.

Вернём систему в исходное состояние: удалим директорию монтирования, loop-устройство и файл с образом файловой системы.

# cd
# umount /mnt/loop-fs/
# rmdir /mnt/loop-fs/
# losetup -d /dev/loop1
# rm loop-fs.img

В рассмотренном примере было показано влияние опций монтирования и наличия бита set-group-ID у родительской директории на то, какая группа будет у новых файлов, создаваемых в директории.

4. Изучение LUKS

Вывести криптопровайдеры.

$ cat /proc/crypto

Создать файл размером 100 Мегабайт, заполненный случайными данными. Обратите внимание на скорость создания файла.

# dd if=/dev/random of=./fs-LUKS.img bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.628301 s, 167 MB/s
# ls -l fs-LUKS.img 
-rw-r--r--. 1 root root 104857600 Feb 19 01:06 fs-LUKS.img
# du -sh fs-LUKS.img 
101M	fs-LUKS.img

Создать LUKS-контейнер, используя созданный файл в качестве устройства хранения.

ВСЕ ДАННЫЕ НА УСТРОЙСТВЕ ХРАНЕНИЯ БУДУТ УНИЧТОЖЕНЫ!

Для подтверждения операции введите большими буквами YES. Затем введите два раза парольную фразу для доступа к LUKS-контейнеру (опция -y).

# cryptsetup luksFormat fs-LUKS.img 

WARNING!
========
This will overwrite data on fs-LUKS.img irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for fs-LUKS.img: 
Verify passphrase: 

Откройте LUKS-контейнер, используя парольную фразу, и свяжите с новым устройством fs-LUKS (имя можно выбрать другое). Убедитесь, что отображение устройства выполнено.

# cryptsetup luksOpen fs-LUKS.img fs-LUKS
Enter passphrase for fs-LUKS.img: 
# ls -l /dev/mapper/
total 0
crw-------. 1 root root 10, 236 Feb 19 00:54 control
lrwxrwxrwx. 1 root root       7 Feb 19 01:56 fs-LUKS -> ../dm-0

Выведите статус устройства. Какой тип контейнера используется? Обратите внимание, что неявно было выполнено loop-связывание.

# cryptsetup status fs-LUKS 
/dev/mapper/fs-LUKS is active.
  type:    LUKS2
  cipher:  aes-xts-plain64
  keysize: 512 bits
  key location: keyring
  device:  /dev/loop0
  loop:    /root/fs-LUKS.img
  sector size:  512
  offset:  32768 sectors
  size:    172032 sectors
  mode:    read/write

Убедитесь, что в ядро загружен модуль отображения устройств.

# lsmod | grep dm_crypt
dm_crypt               53248  1

Создайте файловую систему и выполните её монтирование. Выведите информацию о блочных устройствах.

# mkfs.ext4 /dev/mapper/fs-LUKS 
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 86016 1k blocks and 21560 inodes
Filesystem UUID: 3a6081f5-ce3c-4485-b5d3-2a2868952bf5
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done 

# mount /dev/mapper/fs-LUKS /mnt/
# mount | grep /mnt
/dev/mapper/fs-LUKS on /mnt type ext4 (rw,relatime,seclabel)
# lsblk 
NAME        MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
loop0         7:0    0   100M  0 loop  
└─fs-LUKS   253:0    0    84M  0 crypt /mnt
...

Создайте тестовый файл с читаемыми данными. Выполните размонтирование файловой системы. Закройте LUKS-контейнер.

# echo Hello > /mnt/mephi
# umount /mnt 
# cryptsetup luksClose fs-LUKS 

Произведите поиск данных в образе файловой системы.

# grep Hello fs-LUKS.img 
# grep mephi fs-LUKS.img 

О чём говорит вывод команды grep?

Добавление ключа

Можно cryptsetup luksDump fs-LUKS.img или cryptsetup luksDump /dev/loop0.

# cryptsetup luksDump /dev/loop0 
LUKS header information
Version:       	2
Epoch:         	3
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	7fd7ca5d-5678-4ba8-9a2c-de5cd60d0c0f
Label:         	(no label)
Subsystem:     	(no subsystem)
Flags:       	(no flags)

Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]

Keyslots:
  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      argon2i
	Time cost:  6
	Memory:     1048576
	Threads:    4
	Salt:       06 a4 52 70 d4 29 cb 52 13 e4 f2 8b c6 3c 8a bb 
	            94 88 5d ca df df f7 e4 2d d0 21 fa 05 94 83 b8 
	AF stripes: 4000
	AF hash:    sha256
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
	Hash:       sha256
	Iterations: 129774
	Salt:       2e ce 26 95 e7 16 45 e9 c8 f6 10 30 70 05 a4 53 
	            55 10 62 fe 9d 9e 3a 29 b9 cf ee 3c aa f7 58 07 
	Digest:     2c 57 26 31 84 4a eb a4 23 14 44 dd 5d a7 a3 3f 
	            d1 04 f2 61 39 7b 04 96 04 3e 03 54 b5 0b a3 4e 

Сколько занято слотов?

Добавить новый ключ в свободный слот. Проверить, что теперь занято два слота.

# cryptsetup luksAddKey /dev/loop0
# cryptsetup luksDump /dev/loop0

Порядок защиты работы

Для защиты работы необходимо ответить на вопросы по теме работы.

Ссылки

  1. Index Nodes
  2. struct ext4_inode
  3. http://man7.org/linux/man-pages/man4/loop.4.html
  4. http://man7.org/linux/man-pages/man8/losetup.8.html
  5. http://man7.org/linux/man-pages/man8/lsblk.8.html
  6. https://man7.org/linux/man-pages/man8/blkid.8.html
  7. https://man7.org/linux/man-pages/man8/findfs.8.html
  8. http://man7.org/linux/man-pages/man8/mount.8.html
  9. https://man7.org/linux/man-pages/man5/fstab.5.html
  10. https://man7.org/linux/man-pages/man5/ext4.5.html
  11. https://man7.org/linux/man-pages/man8/dumpe2fs.8.html
  12. https://man7.org/linux/man-pages/man8/tune2fs.8.html
⚠️ **GitHub.com Fallback** ⚠️