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  }