mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Add support for btrfs resize
Mount utils support resizing of btrfs volume, however it lacks btrfs device block size and total size detection needed to determine if resize is needed. Adding btrfs support is useful for certain CSI drivers (e.g. Azure) which now have to implement custom solution for btrfs resize. With this patch it should be easy for such drivers to use mount-utils module instead and help unify (and correct) the resize flows.
This commit is contained in:
parent
ad46b4f921
commit
c1f41ceab3
@ -129,6 +129,9 @@ func (resizefs *ResizeFs) NeedResize(devicePath string, deviceMountPath string)
|
||||
case "xfs":
|
||||
blockSize, fsSize, err = resizefs.getXFSSize(deviceMountPath)
|
||||
klog.V(5).Infof("Xfs size: filesystem size=%d, block size=%d, err=%v", fsSize, blockSize, err)
|
||||
case "btrfs":
|
||||
blockSize, fsSize, err = resizefs.getBtrfsSize(devicePath)
|
||||
klog.V(5).Infof("Btrfs size: filesystem size=%d, block size=%d, err=%v", fsSize, blockSize, err)
|
||||
default:
|
||||
klog.Errorf("Not able to parse given filesystem info. fsType: %s, will not resize", format)
|
||||
return false, fmt.Errorf("Could not parse fs info on given filesystem format: %s. Supported fs types are: xfs, ext3, ext4", format)
|
||||
@ -190,6 +193,51 @@ func (resizefs *ResizeFs) getXFSSize(devicePath string) (uint64, uint64, error)
|
||||
return blockSize, blockSize * blockCount, nil
|
||||
}
|
||||
|
||||
func (resizefs *ResizeFs) getBtrfsSize(devicePath string) (uint64, uint64, error) {
|
||||
output, err := resizefs.exec.Command("btrfs", "inspect-internal", "dump-super", "-f", devicePath).CombinedOutput()
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to read size of filesystem on %s: %s: %s", devicePath, err, string(output))
|
||||
}
|
||||
|
||||
blockSize, totalBytes, _ := resizefs.parseBtrfsInfoOutput(string(output), "sectorsize", "total_bytes")
|
||||
|
||||
if blockSize == 0 {
|
||||
return 0, 0, fmt.Errorf("could not find block size of device %s", devicePath)
|
||||
}
|
||||
if totalBytes == 0 {
|
||||
return 0, 0, fmt.Errorf("could not find total size of device %s", devicePath)
|
||||
}
|
||||
return blockSize, totalBytes, nil
|
||||
}
|
||||
|
||||
func (resizefs *ResizeFs) parseBtrfsInfoOutput(cmdOutput string, blockSizeKey string, totalBytesKey string) (uint64, uint64, error) {
|
||||
lines := strings.Split(cmdOutput, "\n")
|
||||
var blockSize, blockCount uint64
|
||||
var err error
|
||||
|
||||
for _, line := range lines {
|
||||
tokens := strings.Fields(line)
|
||||
if len(tokens) != 2 {
|
||||
continue
|
||||
}
|
||||
key, value := strings.ToLower(strings.TrimSpace(tokens[0])), strings.ToLower(strings.TrimSpace(tokens[1]))
|
||||
|
||||
if key == blockSizeKey {
|
||||
blockSize, err = strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to parse block size %s: %s", value, err)
|
||||
}
|
||||
}
|
||||
if key == totalBytesKey {
|
||||
blockCount, err = strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to parse total size %s: %s", value, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return blockSize, blockCount, err
|
||||
}
|
||||
|
||||
func (resizefs *ResizeFs) parseFsInfoOutput(cmdOutput string, spliter string, blockSizeKey string, blockCountKey string) (uint64, uint64, error) {
|
||||
lines := strings.Split(cmdOutput, "\n")
|
||||
var blockSize, blockCount uint64
|
||||
|
@ -166,6 +166,224 @@ Journal sequence: 0x00037109
|
||||
Journal start: 1
|
||||
Journal checksum type: crc32c
|
||||
Journal checksum: 0xb7df3c6e
|
||||
`
|
||||
cmdOutputSuccessBtrfs :=
|
||||
`superblock: bytenr=65536, device=/dev/loop0
|
||||
---------------------------------------------------------
|
||||
csum_type 0 (crc32c)
|
||||
csum_size 4
|
||||
csum 0x31693b11 [match]
|
||||
bytenr 65536
|
||||
flags 0x1
|
||||
( WRITTEN )
|
||||
magic _BHRfS_M [match]
|
||||
fsid 3f53c8f7-3c57-4185-bf1d-b305b42cce97
|
||||
metadata_uuid 3f53c8f7-3c57-4185-bf1d-b305b42cce97
|
||||
label
|
||||
generation 7
|
||||
root 30441472
|
||||
sys_array_size 129
|
||||
chunk_root_generation 6
|
||||
root_level 0
|
||||
chunk_root 22036480
|
||||
chunk_root_level 0
|
||||
log_root 0
|
||||
log_root_transid 0
|
||||
log_root_level 0
|
||||
total_bytes 1048576000
|
||||
bytes_used 147456
|
||||
sectorsize 4096
|
||||
nodesize 16384
|
||||
leafsize (deprecated) 16384
|
||||
stripesize 4096
|
||||
root_dir 6
|
||||
num_devices 1
|
||||
compat_flags 0x0
|
||||
compat_ro_flags 0x3
|
||||
( FREE_SPACE_TREE |
|
||||
FREE_SPACE_TREE_VALID )
|
||||
incompat_flags 0x341
|
||||
( MIXED_BACKREF |
|
||||
EXTENDED_IREF |
|
||||
SKINNY_METADATA |
|
||||
NO_HOLES )
|
||||
cache_generation 0
|
||||
uuid_tree_generation 7
|
||||
dev_item.uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
dev_item.fsid 3f53c8f7-3c57-4185-bf1d-b305b42cce97 [match]
|
||||
dev_item.type 0
|
||||
dev_item.total_bytes 1048576000
|
||||
dev_item.bytes_used 130023424
|
||||
dev_item.io_align 4096
|
||||
dev_item.io_width 4096
|
||||
dev_item.sector_size 4096
|
||||
dev_item.devid 1
|
||||
dev_item.dev_group 0
|
||||
dev_item.seek_speed 0
|
||||
dev_item.bandwidth 0
|
||||
dev_item.generation 0
|
||||
sys_chunk_array[2048]:
|
||||
item 0 key (FIRST_CHUNK_TREE CHUNK_ITEM 22020096)
|
||||
length 8388608 owner 2 stripe_len 65536 type SYSTEM|DUP
|
||||
io_align 65536 io_width 65536 sector_size 4096
|
||||
num_stripes 2 sub_stripes 1
|
||||
stripe 0 devid 1 offset 22020096
|
||||
dev_uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
stripe 1 devid 1 offset 30408704
|
||||
dev_uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
backup_roots[4]:
|
||||
backup 0:
|
||||
backup_tree_root: 30441472 gen: 5 level: 0
|
||||
backup_chunk_root: 22020096 gen: 5 level: 0
|
||||
backup_extent_root: 30474240 gen: 5 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30457856 gen: 5 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 1:
|
||||
backup_tree_root: 30588928 gen: 6 level: 0
|
||||
backup_chunk_root: 22036480 gen: 6 level: 0
|
||||
backup_extent_root: 30408704 gen: 6 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30556160 gen: 6 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 2:
|
||||
backup_tree_root: 30441472 gen: 7 level: 0
|
||||
backup_chunk_root: 22036480 gen: 6 level: 0
|
||||
backup_extent_root: 30474240 gen: 7 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30457856 gen: 7 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 3:
|
||||
backup_tree_root: 30408704 gen: 4 level: 0
|
||||
backup_chunk_root: 1064960 gen: 4 level: 0
|
||||
backup_extent_root: 5341184 gen: 4 level: 0
|
||||
backup_fs_root: 5324800 gen: 3 level: 0
|
||||
backup_dev_root: 5242880 gen: 4 level: 0
|
||||
backup_csum_root: 1130496 gen: 1 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 114688
|
||||
backup_num_devices: 1
|
||||
|
||||
`
|
||||
cmdOutputNoDataBtrfs :=
|
||||
`superblock: bytenr=65536, device=/dev/loop0
|
||||
---------------------------------------------------------
|
||||
csum_type 0 (crc32c)
|
||||
csum_size 4
|
||||
csum 0x31693b11 [match]
|
||||
bytenr 65536
|
||||
flags 0x1
|
||||
( WRITTEN )
|
||||
magic _BHRfS_M [match]
|
||||
fsid 3f53c8f7-3c57-4185-bf1d-b305b42cce97
|
||||
metadata_uuid 3f53c8f7-3c57-4185-bf1d-b305b42cce97
|
||||
label
|
||||
generation 7
|
||||
root 30441472
|
||||
sys_array_size 129
|
||||
chunk_root_generation 6
|
||||
root_level 0
|
||||
chunk_root 22036480
|
||||
chunk_root_level 0
|
||||
log_root 0
|
||||
log_root_transid 0
|
||||
log_root_level 0
|
||||
bytes_used 147456
|
||||
nodesize 16384
|
||||
leafsize (deprecated) 16384
|
||||
stripesize 4096
|
||||
root_dir 6
|
||||
num_devices 1
|
||||
compat_flags 0x0
|
||||
compat_ro_flags 0x3
|
||||
( FREE_SPACE_TREE |
|
||||
FREE_SPACE_TREE_VALID )
|
||||
incompat_flags 0x341
|
||||
( MIXED_BACKREF |
|
||||
EXTENDED_IREF |
|
||||
SKINNY_METADATA |
|
||||
NO_HOLES )
|
||||
cache_generation 0
|
||||
uuid_tree_generation 7
|
||||
dev_item.uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
dev_item.fsid 3f53c8f7-3c57-4185-bf1d-b305b42cce97 [match]
|
||||
dev_item.type 0
|
||||
dev_item.total_bytes 1048576000
|
||||
dev_item.bytes_used 130023424
|
||||
dev_item.io_align 4096
|
||||
dev_item.io_width 4096
|
||||
dev_item.sector_size 4096
|
||||
dev_item.devid 1
|
||||
dev_item.dev_group 0
|
||||
dev_item.seek_speed 0
|
||||
dev_item.bandwidth 0
|
||||
dev_item.generation 0
|
||||
sys_chunk_array[2048]:
|
||||
item 0 key (FIRST_CHUNK_TREE CHUNK_ITEM 22020096)
|
||||
length 8388608 owner 2 stripe_len 65536 type SYSTEM|DUP
|
||||
io_align 65536 io_width 65536 sector_size 4096
|
||||
num_stripes 2 sub_stripes 1
|
||||
stripe 0 devid 1 offset 22020096
|
||||
dev_uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
stripe 1 devid 1 offset 30408704
|
||||
dev_uuid 987c8423-fba3-4168-9892-560a116feb81
|
||||
backup_roots[4]:
|
||||
backup 0:
|
||||
backup_tree_root: 30441472 gen: 5 level: 0
|
||||
backup_chunk_root: 22020096 gen: 5 level: 0
|
||||
backup_extent_root: 30474240 gen: 5 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30457856 gen: 5 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 1:
|
||||
backup_tree_root: 30588928 gen: 6 level: 0
|
||||
backup_chunk_root: 22036480 gen: 6 level: 0
|
||||
backup_extent_root: 30408704 gen: 6 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30556160 gen: 6 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 2:
|
||||
backup_tree_root: 30441472 gen: 7 level: 0
|
||||
backup_chunk_root: 22036480 gen: 6 level: 0
|
||||
backup_extent_root: 30474240 gen: 7 level: 0
|
||||
backup_fs_root: 30425088 gen: 5 level: 0
|
||||
backup_dev_root: 30457856 gen: 7 level: 0
|
||||
backup_csum_root: 30490624 gen: 5 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 147456
|
||||
backup_num_devices: 1
|
||||
|
||||
backup 3:
|
||||
backup_tree_root: 30408704 gen: 4 level: 0
|
||||
backup_chunk_root: 1064960 gen: 4 level: 0
|
||||
backup_extent_root: 5341184 gen: 4 level: 0
|
||||
backup_fs_root: 5324800 gen: 3 level: 0
|
||||
backup_dev_root: 5242880 gen: 4 level: 0
|
||||
backup_csum_root: 1130496 gen: 1 level: 0
|
||||
backup_total_bytes: 1048576000
|
||||
backup_bytes_used: 114688
|
||||
backup_num_devices: 1
|
||||
|
||||
`
|
||||
testcases := []struct {
|
||||
name string
|
||||
@ -212,6 +430,24 @@ Journal checksum: 0xb7df3c6e
|
||||
expectError: true,
|
||||
fsType: "ext4",
|
||||
},
|
||||
{
|
||||
name: "success parse btrfs info",
|
||||
devicePath: "/dev/test1",
|
||||
blocksize: 4096,
|
||||
blockCount: 256000,
|
||||
cmdOutput: cmdOutputSuccessBtrfs,
|
||||
expectError: false,
|
||||
fsType: "btrfs",
|
||||
},
|
||||
{
|
||||
name: "block size not present - btrfs",
|
||||
devicePath: "/dev/test1",
|
||||
blocksize: 0,
|
||||
blockCount: 0,
|
||||
cmdOutput: cmdOutputNoDataBtrfs,
|
||||
expectError: true,
|
||||
fsType: "btrfs",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testcases {
|
||||
@ -238,6 +474,8 @@ Journal checksum: 0xb7df3c6e
|
||||
blockSize, fsSize, err = resizefs.getXFSSize(test.devicePath)
|
||||
case "ext4":
|
||||
blockSize, fsSize, err = resizefs.getExtSize(test.devicePath)
|
||||
case "btrfs":
|
||||
blockSize, fsSize, err = resizefs.getBtrfsSize(test.devicePath)
|
||||
}
|
||||
|
||||
if blockSize != test.blocksize {
|
||||
|
Loading…
Reference in New Issue
Block a user