Представьте, что размер физического тома изменился:
pvresize /dev/sda2
Размер логического тома был изменен:
lvresize -l +100%FREE system/home
Но эта команда не была выполнена:
resize2fs /dev/mapper/system-home
Поскольку последняя команда была забыта, осталось неиспользуемое пространство.
Как посчитать неиспользованные байты?
Предыстория: я хочу написать сценарий проверки, который проверяет, не было ли забыто изменение размера файловой системы на сервере.
Кстати: я не доверяю сценариям оболочки.
Размер всего блочного устройства по умолчанию, плюс онлайн-рост, делают ненужную проверку размера. Бегать resize2fs
во всех ваших файловых системах.
(Если у вас есть вариант использования, который требует размера, отредактируйте свой вопрос.)
Предотвратите повторное забывание файловой системы, добавив lvresize --resizefs
к вашим скриптам или псевдонимам оболочки.
В идеале нехватка места будет продолжать появляться в отчетах о планировании мощностей. Надеюсь, он не станет настолько полным, чтобы вызывать предупреждения о почти заполнении.
Шаг 1 : определить границы файловой системы
dumpe2fs -h /dev/mapper/system-home | grep -E "^Block count|^Block size"
вы получите общий размер файловой системы с этими двумя числами, пример ниже:
Block count: 98304
Block size: 1024 (which is 1k)
FS size = 98304 = **96MB**
Шаг 2 : определить границы блочного устройства
а) определите dm, связанный с вашим логическим томом readlink -f /dev/mapper/system-home
что дает вам / dev / dm-XX
б) определить границы / dev / dm-XX cat /sys/block/dm-XX/size
что дает вам общий размер в блоках (512 байт). Если размер 300000 блоков, то у вас немного меньше 150 МБ на блочном устройстве
150-96 марок ~ 54 МБ свободного места в файловой системе
Я решаю проблему изменения размера с помощью сценария, который находит все задействованные блочные устройства и соответственно распечатывает им команды изменения размера.
https://github.com/mircea-vutcovici/scripts/blob/master/vol_resize.sh
Аналогичным образом вы можете изменить его, чтобы запускать команды, которые показывают размеры блочных устройств и размер файловой системы. Просто взглянув на сценарий, вы поймете, что ответ немного сложнее.
Например. Представьте себе такой макет:
Как узнать размер:
blockdev --getsz sdX
, grep . /sys/block/*/size
pvs
dumpe2fs /dev/sdX|egrep '^Block (count|size):'
zpool status
, zpool list
, zfs list
xfs_info
dmsetup table
df
Другие перечислили инструменты, которые можно использовать для ответа на ваш вопрос, но я хотел создать реальную рабочую реализацию, которую вы могли бы использовать. Итак, я написал сценарий bash, который делает именно то, что вы просите: сообщать, сколько свободного места в конце LV еще не занято FS (например, когда кто-то забывает вырастить сам FS).
Я должен отметить, что, поскольку определение размера файловой системы зависит от инструментов этой файловой системы, вы должны персонализировать ее для того, какие файловые системы вы используете для своих дисков LVM. Я лично использую и XFS, и EXT4, поэтому приведенный ниже сценарий реализует их оба. В частности, мне пришлось использовать tune2fs
для EXT4 и xfs_info
для XFS.
#!/bin/bash
# Header
printf '%-20s %-7s %8s %8s %8s\n' Mountpoint FS_Type LV_Size FS_Size LV_Free
lsblk -nlbo TYPE,FSTYPE,MOUNTPOINT,PATH,SIZE | grep -E '^lvm +(ext4|xfs)' | while read TYPE FSTYPE MOUNTPOINT PAATH SIZE; do
if [[ $FSTYPE == 'ext4' ]] ; then
FSSIZE=$(tune2fs -l $PAATH | grep -E '(Block count|Block size)' | awk 'BEGIN{x=1}{x=x*$NF}END{print x}')
elif [[ $FSTYPE == 'xfs' ]] ; then
FSSIZE=$(xfs_info $MOUNTPOINT | grep ^data | /bin/tr = ' ' | awk '{print $3*$5}')
fi
LVFREE=$((SIZE - FSSIZE))
printf '%-20s %-7s %8d %8d %8d\n' $MOUNTPOINT $FSTYPE $((SIZE/1024/1024)) $((FSSIZE/1024/1024)) $((LVFREE/1024/1024))
done
[root@xps joshua]# lvextend -L +1G /dev/vg1/home
Size of logical volume vg1/home changed from 90.00 GiB (23040 extents) to 91.00 GiB (23296 extents).
Logical volume vg1/home successfully resized.
[root@xps ~]# lvextend -L +256M /dev/vg1/usr
Size of logical volume vg1/usr changed from 25.00 GiB (6400 extents) to 25.25 GiB (6464 extents).
Logical volume vg1/usr successfully resized.
[root@xps ~]# ./lvfree.sh
Mountpoint FS_Type LV_Size FS_Size LV_Free
/ ext4 5120 5120 0
/var ext4 24576 24576 0
/var/log ext4 20480 20480 0
/usr ext4 25856 25600 256
/home xfs 93184 92160 1024
/tmp ext4 10240 10240 0
/opt ext4 5120 5120 0
[root@xps ~]# xfs_growfs /home
meta-data=/dev/mapper/vg1-home isize=256 agcount=8, agsize=3276800 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0, sparse=0, rmapbt=0
= reflink=0
data = bsize=4096 blocks=23592960, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=65536 ascii-ci=0, ftype=0
log =internal log bsize=4096 blocks=6400, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 23592960 to 23855104
[root@xps ~]# resize2fs /dev/mapper/vg1-usr
resize2fs 1.45.3 (14-Jul-2019)
Filesystem at /dev/mapper/vg1-usr is mounted on /usr; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/mapper/vg1-usr is now 6619136 (4k) blocks long.
[root@xps ~]# ./lvfree.sh
Mountpoint FS_Type LV_Size FS_Size LV_Free
/ ext4 5120 5120 0
/var ext4 24576 24576 0
/var/log ext4 20480 20480 0
/usr ext4 25856 25856 0
/home xfs 93184 93184 0
/tmp ext4 10240 10240 0
/opt ext4 5120 5120 0
Сноска: PAATH в моем сценарии не опечатка. Мне пришлось не использовать имя переменной PATH, поскольку оно имеет зарезервированное значение в сценариях оболочки.
crtdev=/dev/sda9
crtdev=/dev/Vol-1/Root
{ read devsz;read devss;}< <(blockdev --getsz --getss $crtdev)
devsize=$((devsz*devss))
Примечание: Вы могли бы использовать lsblk
чтобы перечислить устройства с размерами:
lsblk -no KNAME,NAME,SIZE
Это может быть полезно в скрипте ... Смотрите дальше!
ext2|ext3|ext4
:while IFS=$':\t\r\n' read fld val;do
case $fld in
Block\ size) fsbs=$val;;
Block\ count) fssz=$val;;
esac
done < <(dumpe2fs 2>&1 -h $crtdev)
fssize=$((fssz*fsbs))
xfs
:Информация XFS не будет выполняться на подключенных устройствах, вместо этого вы должны использовать mont-point:
mntpnt=/mnt
while IFS=$' =,\t\r\n' read -a lne;do
[ "$lne" = "data" ] &&
fsbs=${lne[2]} fssz=${lne[4]}
done < <( xfs_info $mntpnt )
fssize=$((fssz*fsbs))
ntfs
:Кажется, с этим все не так просто ... Так как я ими не часто пользуюсь, даже если уже использовал ntfsresize
в прошлом. Есть что-то:
read fsinfo < <(file -bs $1)
fssz=${fsinfo#*, sectors } fssz=${fssz%%,*}
fssize=$(( 512 * ( fssz + 1 ) ))
Примечание: ненавижу это: я не мог объяснить + 1
и некоторые из моих тестовых работ с + 8
вместо...
printf "Dev: %d - FS: %d = Unused: %d\n" $devsize $fssize $(( devsize - fssize ))
lsblk
для сканирования всех устройств:Этот сценарий, запущенный без аргументов, будет печатать одну строку по устройству, у которого diff не null. Запуск с любым (фиктивным) аргументом, будет печатать по одной строке для каждого xfs
или ext[234]
устройство.
Как это использовать трепать с эффективным башизм и ограниченные вилки до lshw
, dumpe2fs
и / или xfs_info
только этот сценарий требует очень мало ресурсов.
!! Чтобы работать как root
или с sudo
!!
#!/bin/bash
shopt -s extglob
declare -A KNAMES='()' # Prevent double check
infolog() {
# Entering this with $kname, $size, $fs, $name, $fsbs and $fssz.
fssize=$((fssz*fsbs))
(( $# | size-fssize ))&& # Only if diffsize > 0 or if argument was submited
printf "%-25s %-6s %15u %15u %14u\n" \
${NAME##*/} $FSTYPE $SIZE $fssize $((SIZE-fssize))
}
while read line; do eval "$line"
[ "${KNAMES[${KNAME##*/}]}" ] || case $FSTYPE in
ext* ) while IFS=$':\t\r\n' read fld val;do
case $fld in
Block\ size) fsbs=$val;;
Block\ count) fssz=$val;;
esac
done < <(dumpe2fs 2>&1 -h $KNAME)
infolog $@ ;;
xfs ) check=$KNAME
[ "$MOUNTPOINT" ] && check="$MOUNTPOINT"
while IFS=$' =,\t\r\n' read -a lne;do
[ "$lne" = "data" ] &&
fsbs=${lne[2]} fssz=${lne[4]}
done < <( xfs_info "$check" )
infolog $@ ;;
ntfs )
read fsinfo < <(file -Lbs $KNAME)
fssz=${fsinfo#*, sectors } fssz=${fssz%%,*}
(( fssz += 1, fsbs=512 ))
infolog $@ ;;
esac
KNAMES[${KNAME##*/}]="done"
done < <(lsblk -bnpPo KNAME,NAME,MOUNTPOINT,FSTYPE,SIZE)
(Это немного уменьшено, чтобы предотвратить полосы прокрутки SO;)
Пример выполнения (без аргументов):
./unused_bytes_by_dev.sh
Vol--I-XDATAS xfs 48318382080 42949672960 5368709120
sdd1 ext4 1010774016 175472640 835301376
С одним аргументом:
./unused_bytes_by_dev.sh dummy
md0 ext4 246349824 246349824 0
Vol--I-ROOT ext4 1610612736 1610612736 0
Vol--V-USR ext4 31138512896 31138512896 0
Vol--I-VAR ext4 22548578304 22548578304 0
Vol--I-HOME ext4 34359738368 34359738368 0
Vol--I-XDATAS xfs 48318382080 42949672960 5368709120
Vol--I-Win ntfs 42949672960 42949672960 0
sdd1 ext4 1010774016 175472640 835301376
df
дает вам общий размер, как видно из FS, с -k
- в КБ.
sudo blockdev --getsize64
дает вам чистый размер блочного устройства - в байтах.
Довольно просто преобразовать байты в килобайты и сравнить, есть ли между ними какая-либо значительная разница.
Чтобы получить неиспользуемые байты, вы должны получить таблицу разделов и взглянуть на границы разделов и границы файловой системы.
Есть несколько способов сделать это, поэтому я назову несколько из них.
Это требует некоторого расчета. Вы можете видеть, сколько секторов на диске, и вы можете видеть количество секторов в начале и в конце каждого раздела, чтобы вы могли вычислить, осталось ли свободное место.
# fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 477 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: THNSN5512GPUK NVMe TOSHIBA 512GB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: B9E14CDC-1817-4552-9AD0-967A6FC9C4CE
Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 411647 409600 200M EFI System
/dev/nvme0n1p2 411648 2508799 2097152 1G Linux filesystem
/dev/nvme0n1p3 2508800 18782207 16273408 7.8G Linux filesystem
/dev/nvme0n1p4 18782208 1000214527 981432320 468G Linux filesystem
Вы можете вызвать parted, чтобы распечатать свободное место в таблице разделов
# parted /dev/nvme0n1 print free
Model: THNSN5512GPUK NVMe TOSHIBA 512GB (nvme)
Disk /dev/nvme0n1: 512GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
17.4kB 1049kB 1031kB Free Space
1 1049kB 211MB 210MB fat16 EFI System Partition boot, esp
2 211MB 1285MB 1074MB ext4
3 1285MB 9616MB 8332MB
4 9616MB 512GB 502GB
512GB 512GB 335kB Free Space