42 lines
1011 B
Go
42 lines
1011 B
Go
//go:build linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"unsafe"
|
|
|
|
"syscall"
|
|
)
|
|
|
|
// BLKGETSIZE64 = _IOR(0x12, 114, sizeof(uint64)) on Linux.
|
|
const blkGetSize64 = 0x80081272
|
|
|
|
func blockDeviceSize(path string) (int64, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer f.Close()
|
|
|
|
var size uint64
|
|
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), blkGetSize64, uintptr(unsafe.Pointer(&size)))
|
|
if errno != 0 {
|
|
return 0, errno
|
|
}
|
|
return int64(size), nil
|
|
}
|
|
|
|
// isRawDevice reports paths that must be sized via ioctl rather than os.Stat.
|
|
// On Linux block devices are recognized through os.ModeDevice instead, so this
|
|
// is always false.
|
|
func isRawDevice(string) bool { return false }
|
|
|
|
// deviceAlignment is 1 on Linux: buffered pread/pwrite on a block device accept
|
|
// any alignment.
|
|
func deviceAlignment(string) int64 { return 1 }
|
|
|
|
// canElevate reports whether a permission failure opening a device is worth
|
|
// retrying under sudo (see --sudo).
|
|
func canElevate() bool { return true }
|