{"record":{"id":"689e520d2cd4498f","repo":"containerd/containerd","slug":"failed-to-get-block-device-size-s-w","errorCode":null,"errorMessage":"failed to get block device size: %s: %w","messagePattern":"failed to get block device size: (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/snapshots/devmapper/dmsetup/dmsetup.go","lineNumber":103,"sourceCode":"\tthinPool, err := makeThinPoolMapping(dataFile, metaFile, blockSizeSectors)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = dmsetup(\"reload\", deviceName, \"--table\", thinPool)\n\treturn err\n}\n\nconst (\n\tlowWaterMark = 32768                // Picked arbitrary, might need tuning\n\tskipZeroing  = \"skip_block_zeroing\" // Skipping zeroing to reduce latency for device creation\n)\n\n// makeThinPoolMapping makes thin-pool table entry\nfunc makeThinPoolMapping(dataFile, metaFile string, blockSizeSectors uint32) (string, error) {\n\tdataDeviceSizeBytes, err := BlockDeviceSize(dataFile)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get block device size: %s: %w\", dataFile, err)\n\t}\n\n\t// Thin-pool mapping target has the following format:\n\t// start - starting block in virtual device\n\t// length - length of this segment\n\t// metadata_dev - the metadata device\n\t// data_dev - the data device\n\t// data_block_size - the data block size in sectors\n\t// low_water_mark - the low water mark, expressed in blocks of size data_block_size\n\t// feature_args - the number of feature arguments\n\t// args\n\tlengthSectors := dataDeviceSizeBytes / SectorSize\n\ttarget := fmt.Sprintf(\"0 %d thin-pool %s %s %d %d 1 %s\",\n\t\tlengthSectors,\n\t\tmetaFile,\n\t\tdataFile,\n\t\tblockSizeSectors,\n\t\tlowWaterMark,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/plugins/snapshots/devmapper/dmsetup/dmsetup.go#L85-L121","documentation":"makeThinPoolMapping builds the thin-pool table and must know the data device's byte size, which it obtains via BlockDeviceSize (an lseek to end of file). This error wraps whatever failure occurred while sizing the data file/device, aborting pool creation or reload.","triggerScenarios":"CreatePool or ReloadPool -> makeThinPoolMapping -> BlockDeviceSize fails: the data file/device path is wrong, cannot be opened, or the seek to SEEK_END fails.","commonSituations":"The loopback data file was not created before pool setup; permission problems on /dev or the data dir; the underlying block device disappeared (VM disk detach); filesystem errors on the host.","solutions":["Check the wrapped cause (%w) in the error — it names the underlying open/seek failure.","Verify the data file/device path exists and is readable/writable by the process.","Recreate the pool: ensure the sparse data file is created with correct size before makeThinPoolMapping runs.","Check host disk health/space and that the loopback device is attached (losetup)."],"exampleFix":"// before\nerr := pool.CreatePool() // data file never created\n// after\nif err := createSparseFile(dataFile, sizeBytes); err != nil { return err }\nif err := pool.CreatePool(); err != nil { return fmt.Errorf(\"pool create: %w\", err) }","handlingStrategy":"try-catch","validationCode":"func checkDataDevice(path string) error {\n    fi, err := os.Stat(path)\n    if err != nil { return fmt.Errorf(\"data device missing: %w\", err) }\n    if !fi.Mode().IsRegular() && fi.Mode()&os.ModeDevice == 0 {\n        return fmt.Errorf(\"%s is not a seekable file/device\", path)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"table, err := CreatePool(...)\nif err != nil {\n    var sizeErr error\n    if strings.Contains(err.Error(), \"failed to get block device size\") {\n        sizeErr = checkDataDevice(dataFile)\n    }\n    return fmt.Errorf(\"pool create failed: %w (device check: %v)\", err, sizeErr)\n}","preventionTips":["Create and verify the sparse data file before CreatePool","Check disk space and permissions on the pool directory","Monitor host storage health (dmesg, smartctl)","Log the wrapped cause (%w) to distinguish open vs seek failures"],"tags":["devmapper","dmsetup","block-device","io"],"backgroundTag":"block-device-size-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}