Skip to content

resizeFilesystem: invoke resize2fs against the partition device, not the whole disk#10

Open
eriknordmark wants to merge 1 commit into
diskfs:mainfrom
eriknordmark:fix-block-device-resize2fs-path
Open

resizeFilesystem: invoke resize2fs against the partition device, not the whole disk#10
eriknordmark wants to merge 1 commit into
diskfs:mainfrom
eriknordmark:fix-block-device-resize2fs-path

Conversation

@eriknordmark
Copy link
Copy Markdown

Summary

Fixes #9.

When resizeFilesystem is invoked against a real block device (DeviceTypeBlockDevice branch), it was handing the whole-disk path to resize2fs rather than the partition device path. resize2fs /dev/sda finds no filesystem at offset 0 and errors out; what was needed was resize2fs /dev/sda9 (or /dev/nvme0n1p9, /dev/mmcblk0p9, …).

Approach

Resolve the partition device path by sysfs lookup rather than hardcoding the naming convention:

func partitionDevicePath(diskPath string, partNumber int, syspath string) (string, error) {
    diskBase := filepath.Base(diskPath)
    diskSysDir := filepath.Join(syspath, "class", "block", diskBase)
    entries, _ := os.ReadDir(diskSysDir)
    for _, e := range entries {
        raw, err := os.ReadFile(filepath.Join(diskSysDir, e.Name(), "partition"))
        if err != nil { continue }
        if n, _ := strconv.Atoi(strings.TrimSpace(string(raw))); n == partNumber {
            return filepath.Join("/dev", e.Name()), nil
        }
    }
    ...
}

The kernel-named partition directory under sysfs always matches the device node under /dev, so the lookup gives us back sda9, nvme0n1p9, mmcblk0p9, etc. correctly without us having to maintain a naming-convention table.

The disk-image (DeviceTypeFile) branch is unchanged — it continues to copy the partition's bytes out to a temp file, resize that, and copy back.

Tests

New TestPartitionDevicePath covers:

  • sdasda9 (traditional convention).
  • nvme0n1nvme0n1p9 (the "p"-prefix convention used by NVMe / eMMC / virtio-blk).
  • partition number not found under sysfs (returns error).
  • disk not found under sysfs (returns error).

Uses a fake-sysfs tree under t.TempDir(), same pattern as the existing TestFindDisks.

Test plan

$ go test -run '^TestShrinkFilesystem$|^TestPartitionDevicePath$' .
ok      github.com/diskfs/partitionresizer  0.816s

End-to-end against a real block device isn't unit-testable here, but the load-bearing piece is the partition-name resolution, which is now under test.

Signed-off-by: eriknordmark erik@zededa.com

When running against a real block device, resizeFilesystem was
calling resize2fs (via execResize2fs) with the whole-disk path that
the disk.Disk was opened with — e.g. "/dev/sda" — instead of the
partition device path "/dev/sda9". resize2fs on the whole disk fails
because there is no filesystem at offset 0.

Resolve the partition device path by walking
/sys/class/block/<disk>/<part>/partition under sysfs and matching on
the partition number. This handles the different naming conventions
(sda9, nvme0n1p9, mmcblk0p9, …) without having to hardcode them.

The disk-image (DeviceTypeFile) branch is unaffected; it continues
to copy the partition's bytes out to a temp file, resize that, and
copy back.

Tests cover the sda-style and nvme-style naming, plus the
not-found cases (partition number absent, disk absent).

Closes diskfs#9.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

block-device shrink calls resize2fs against the whole-disk path, not the partition device

1 participant