7

Wondering if there has been anyone experimenting with low-level disk I/O, such as reading raw sectors, MBR, etc. I've done some digging around myself, but haven't been able to find anything mentioned about it. Most of it is dead ends where someone is talking about Go's native io package.

Any leads would be appreciated.

Sly
  • 1,145
  • 7
  • 19
  • On *nix you'd read/write the raw device files in /dev/ – nos Jan 09 '14 at 22:26
  • Yeah, but it would be nice if there were a cross-platform way of doing it since Go is cross-platform... without having to code everything in C, though possible if required. The `/dev/` files would be fine with me, since I run *NIX on everything. I know they don't exist in Windows, though. – Sly Jan 09 '14 at 22:28
  • 4
    no such cross platform API exists, at least not for Go. btw windows have special files in the \\.\ namespace, e.g. \\.\PhysicalDisk0, or \Device\XXX\ – nos Jan 09 '14 at 22:36
  • 1
    Most likely you will find such universal API in nearest future. Anyway accessing disk on Windows is similar to *NIX. `\\.\PhysicalDriveN` or `\\.\X:` http://support.microsoft.com/kb/100027 (You posted before me) – Tema Jan 09 '14 at 22:38
  • I haven't used Windows in years, so thanks for that. I suppose I'll have to make one or wait for one. :P – Sly Jan 09 '14 at 22:39
  • 1
    @FUZxxl Yeah, I'm aware it's all platform dependent. I wanted to know if someone has _experimented_ with Go having a native ability to do low-level disk I/O without depending on anything external. I figured, being a compiled language, that it may have something helpful hidden that I haven't had a chance to see yet. From the comments here, it doesn't seem like there's a way to do it without depending on something external. – Sly Jan 10 '14 at 10:05
  • Also, something else that would be a helpful hint is if there is anything in Go that maps to the physical disk per platform. This would keep someone from having to repeat code for different platforms if it is already available natively. – Sly Jan 10 '14 at 11:56
  • You even admit that there is no portable way. Why do you keep asking for one? Some platforms, such as Plan 9, don't even have the notion of physical disks. Why don't you simply io.Open() the device file you want to deal with? – fuz Jan 10 '14 at 17:29
  • @FUZxxl As mentioned in my last comment, it would be nice to know things such as if Go has something in it that maps the physical device to its file when it's compiling. As mentioned in the comment before my last one, I haven't had a chance to go through the entire source of Go yet... so I don't know if this exists. Obviously it's not hard to tell which platform it's running on, but why repeat code if it's already provided natively? – Sly Jan 10 '14 at 17:58
  • @Sly Such a thing is impossible and I don't think Go does it. Each platform has countless ways of addressing disks. (For instance, under Linux there are at least four: By incrementing number, by physical location, by UUID, by SCSI-triple). Even then your platform might have options to customize the names of device files. Why not pass the name of the device file to your program from a parameter? This makes it easil possible to test your program on a file as well. – fuz Jan 10 '14 at 18:33

2 Answers2

9

I am still new to go so my example is not particularly elegant, but I think this is what you want:

package main

import (
    "syscall"
    "fmt"
)

func main() {
    disk := "/dev/sda"
    var fd, numread int
    var err error

    fd, err = syscall.Open(disk, syscall.O_RDONLY, 0777)

    if err != nil {
        fmt.Print(err.Error(), "\n")
        return
    }

    buffer := make([]byte, 10, 100)

    numread, err = syscall.Read(fd, buffer)

    if err != nil {
        fmt.Print(err.Error(), "\n")
    }

    fmt.Printf("Numbytes read: %d\n", numread)
    fmt.Printf("Buffer: %b\n", buffer)

    err = syscall.Close(fd)

    if err != nil {
        fmt.Print(err.Error(), "\n")
    }
}

Here is a link to the syscall package documentation: http://golang.org/pkg/syscall/

According to this page, this package attempts to be compatible with as many different platforms as possible but it kinda seems to my novice eye like the main target is the Linux API with, of course, go idioms to simplify things. I hope this answers your question!

waynr
  • 133
  • 1
  • 5
  • Haven't had a chance to check this out yet, but +1 anyway for the effort. :D – Sly Jan 15 '14 at 17:07
  • I gave it some more thought, and I actually don't think this is particularly following the Linux API except in the sense that these system call functions are named similarly--I really don't know enough about other OSes to comment on whether or not the names match up. For example, the `syscall.Open` function always requires `mode` argument even if the call is not actually creating a file. – waynr Jan 16 '14 at 17:36
0

It seems it is already late, but it might be interesting for somebody else. There is an interesting example of how to work with MBR on Windows: GoogleCloudPlatform/compute-image-tools

and they use package golang.org/x/sys/windows

photon
  • 1
  • 1