github.com/yasker/longhorn-engine@v0.0.0-20160621014712-6ed6cfca0729/frontend/tcmu/cfunc.go (about) 1 package tcmu 2 3 /* 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stdarg.h> 7 #include <poll.h> 8 #include <scsi/scsi.h> 9 #include <scsi_defs.h> 10 #include <libtcmu.h> 11 12 13 void errp(const char *fmt, ...) 14 { 15 va_list va; 16 17 va_start(va, fmt); 18 vfprintf(stderr, fmt, va); 19 va_end(va); 20 } 21 22 extern bool devCheckConfig(const char *cfgString, char **reason); 23 extern int devOpen(struct tcmu_device *dev); 24 extern void devClose(struct tcmu_device *dev); 25 26 int dev_open_cgo(struct tcmu_device *dev) { 27 return devOpen(dev); 28 } 29 30 void dev_close_cgo(struct tcmu_device *dev) { 31 devClose(dev); 32 } 33 34 bool dev_check_config_cgo(const char *cfgString, char **reason) { 35 return devCheckConfig(cfgString, reason); 36 } 37 38 static struct tcmulib_handler lh_handler = { 39 .name = "Longhorn TCMU handler", 40 .subtype = "longhorn", 41 .cfg_desc = "dev_config=longhorn//<id>", 42 .added = dev_open_cgo, 43 .removed = dev_close_cgo, 44 .check_config = dev_check_config_cgo, 45 }; 46 47 struct tcmulib_context *tcmu_init() { 48 return tcmulib_initialize(&lh_handler, 1, errp); 49 } 50 51 uint8_t tcmucmd_get_cdb_at(struct tcmulib_cmd *cmd, int index) { 52 return cmd->cdb[index]; 53 } 54 55 void *allocate_buffer(int length) { 56 return calloc(1, length); 57 } 58 59 */ 60 import "C" 61 62 import ( 63 "unsafe" 64 ) 65 66 type ( 67 Command *C.struct_tcmulib_cmd 68 Device *C.struct_tcmu_device 69 70 Cbuffer *C.void 71 ) 72 73 func CmdGetScsiCmd(cmd Command) byte { 74 return byte(C.tcmucmd_get_cdb_at(cmd, 0)) 75 } 76 77 func CmdMemcpyIntoIovec(cmd Command, buf []byte, length int) int { 78 if len(buf) != length { 79 log.Errorln("read buffer length %v is not %v: ", len(buf), length) 80 return 0 81 } 82 return int(C.tcmu_memcpy_into_iovec(cmd.iovec, cmd.iov_cnt, unsafe.Pointer(&buf[0]), C.size_t(length))) 83 } 84 85 func CmdMemcpyFromIovec(cmd Command, buf []byte, length int) int { 86 if len(buf) != length { 87 log.Errorln("write buffer length %v is not %v: ", len(buf), length) 88 return 0 89 } 90 return int(C.tcmu_memcpy_from_iovec(unsafe.Pointer(&buf[0]), C.size_t(length), cmd.iovec, cmd.iov_cnt)) 91 } 92 93 func CmdSetMediumError(cmd Command) int { 94 return int(C.tcmu_set_sense_data(&cmd.sense_buf[0], C.MEDIUM_ERROR, C.ASC_READ_ERROR, nil)) 95 } 96 97 func CmdGetLba(cmd Command) int64 { 98 return int64(C.tcmu_get_lba(cmd.cdb)) 99 } 100 101 func CmdGetXferLength(cmd Command) int { 102 return int(C.tcmu_get_xfer_length(cmd.cdb)) 103 } 104 105 func CmdEmulateInquiry(cmd Command, dev Device) int { 106 return int(C.tcmu_emulate_inquiry(dev, cmd.cdb, cmd.iovec, cmd.iov_cnt, &cmd.sense_buf[0])) 107 } 108 109 func CmdEmulateTestUnitReady(cmd Command) int { 110 return int(C.tcmu_emulate_test_unit_ready(cmd.cdb, cmd.iovec, cmd.iov_cnt, &cmd.sense_buf[0])) 111 } 112 113 func CmdEmulateModeSense(cmd Command) int { 114 return int(C.tcmu_emulate_mode_sense(cmd.cdb, cmd.iovec, cmd.iov_cnt, &cmd.sense_buf[0])) 115 } 116 117 func CmdEmulateModeSelect(cmd Command) int { 118 return int(C.tcmu_emulate_mode_select(cmd.cdb, cmd.iovec, cmd.iov_cnt, &cmd.sense_buf[0])) 119 } 120 121 func CmdEmulateServiceActionIn(cmd Command, numLbas int64, blockSize int) int { 122 if C.tcmucmd_get_cdb_at(cmd, 1) == C.READ_CAPACITY_16 { 123 return int(C.tcmu_emulate_read_capacity_16(C.uint64_t(numLbas), 124 C.uint32_t(blockSize), 125 cmd.cdb, cmd.iovec, cmd.iov_cnt, &cmd.sense_buf[0])) 126 } 127 return C.TCMU_NOT_HANDLED 128 }