Hello, I'm trying to call Linux SCSI generic ioctls from Go, ideally without resorting to cgo, and have hit a few snags.
I have ported the sg_io_hdr_t struct (<scsi/sg.h>) to Go, and according to http://golang-sizeof.tips, it is the same size as sizeof(sg_io_hdr_t) in C, and does not contain any unexpected padding or weird alignment. Using "unsafe", I have some working code that is able to send a SCSI INQUIRY to a device and get a sane response (on x64). I _assume_ that this code should be portable to i386 or arm64, but am open to being corrected. Where things start to get ugly is when one has to work with packed structs, such as the megasas_iocpacket struct in the Linux megaraid_sas driver. This struct is for sending ioctls to the megaraid_sas driver, which can include e.g. SCSI pass-through commands for interfacing with disks attached to MegaRAID controllers. Porting this struct to Go and checking it on http://golang-sizeof.tips reveals several instances of undesired padding, which leads to incorrect alignment of the members when the ioctl reads them. I do have some working code however that is able to send INQUIRY or ATA IDENTIFY commands, wrapped in SCSI pass-through commands, via the MegaRAID ioctls (aka MegaRAID Firmware Interface or MFI). I am achieving this by using encoding/binary to write the struct to a buffer in packed format, and then calling the ioctl with an unsafe pointer to that buffer. This at least results in the correct packing, as would be achieved in C. But it is quite tedious if the ioctl has to write some response into that buffer, since I then have to read that buffer back into the struct before I can continuing to work with the values written to that struct. The impasse that I have currently reached is how to make such a packed struct be platform independent. Encoding/binary will not work if the struct contains non fixed-size members, such as int, uint or especially uintptr. Many ioctls pass structs that contain void* pointers to buffers which are expected to be written to by the ioctl. Is there a way to deal with this, without rewriting most of encoding/binary? I get that the size of uintptr is not fixed, but it can be determined at runtime or presumably compile time, since the target arch is known. Will I have to resort to using cgo, and will that even deal with the packed struct issue? Any help or advice appreciated. Daniel -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.