douhui3330 2017-10-04 07:00
浏览 119
已采纳

如何正确获取块设备的大小?

EDITED: as @abhink pointed out, was not invoking Size().

I tried two different go methods, and then compared to df. Of course, all 3 give different results:

package main

import (
    "os"
    "syscall"
    "fmt"
)

func main() {
    disk := "/dev/sda1"
    statout, err := os.Stat(disk)
    if err != nil {
        fmt.Errorf("Error %x", err)
        os.Exit(1)
    }
    println("os.Stat Size   : ", statout.Size())

    var stat syscall.Statfs_t
    syscall.Statfs(disk, &stat)
    println("syscall.Statfs_t Type: ",  stat.Type)
    println("syscall.Statfs_t Bsize: ",  stat.Bsize)
    println("syscall.Statfs_t Blocks: ",  stat.Blocks)
}

Running the programs:

$ main
os.Stat Size   :  0
syscall.Statfs_t Type: 16914836
syscall.Statfs_t Bsize: 4096
syscall.Statfs_t Blocks: 2560

And df:

$ df /dev/sda1
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             65792556  43694068  18726712  70% /var

Net:

  • os.Stat() gives 0 which it is not, but might be an OS issue.
  • syscall.Statfs() gives 2560 blocks * 4096 block size = 10,485,760. More realistic, but still incorrect
  • df gives 65792556 1K-blocks * 1024 bytes / K = 67,371,577,344

How do I reliably get the size of a block device without mounting it?

Essentially, I am looking for the equivalent of the ioctl call on the device.

ioctl(fd,BLKGETSIZE64,&size)
  • 写回答

2条回答 默认 最新

  • douzhi7070 2019-09-06 13:04
    关注

    The OP asked how to get the size of a block device. To get the size of a block device (or any file), you can File.Seek to the end of the file using io.SeekEnd and read the position returned. Credit to others for python and C.

    Running the example getsize.go below shows:

    $ sudo go run getsize.go /dev/sda
    /dev/sda is 256060514304 bytes.
    

    lsblk --bytes /dev/device will give you the same information. That is how much data the block device can store.

    The Statfs_t path, and df /path/to/mounted/filesystem will give you information about how much data you can store in the filesystem mounted at provided path. Filesystems have overhead, probably in the 2-5% range depending on details of the filesystem, and also keep track of how much space is Free or Used.

    There is no api that I am aware of that can provide information about unmounted filesystems on a block device. dumpe2fs can give you that information for the ext{2,3,4} filesystems. There likely exist tools for other filesystems. Such tools are filesystem specific. When you mount the filesystem, then the linux kernel's filesystem driver exposes that information that is returned by df.

    Code:

    // getsize.go: get the size of a block device or file
    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    
    func main() {
        var path string
        if len(os.Args) < 2 {
            fmt.Println("Give path to file/disk")
            os.Exit(1)
        }
        path = os.Args[1]
        file, err := os.Open(path)
        if err != nil {
            fmt.Printf("error opening %s: %s
    ", path, err)
            os.Exit(1)
        }
        pos, err := file.Seek(0, io.SeekEnd)
        if err != nil {
            fmt.Printf("error seeking to end of %s: %s
    ", path, err)
            os.Exit(1)
        }
        fmt.Printf("%s is %d bytes.
    ", path, pos)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 运筹学中在线排序的时间在线排序的在线LPT算法
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试,帮帮忙吧