github.com/torfuzx/docker@v1.8.1/pkg/devicemapper/devmapper_wrapper.go (about) 1 // +build linux 2 3 package devicemapper 4 5 /* 6 #cgo LDFLAGS: -L. -ldevmapper 7 #include <libdevmapper.h> 8 #include <linux/loop.h> // FIXME: present only for defines, maybe we can remove it? 9 #include <linux/fs.h> // FIXME: present only for BLKGETSIZE64, maybe we can remove it? 10 11 #ifndef LOOP_CTL_GET_FREE 12 #define LOOP_CTL_GET_FREE 0x4C82 13 #endif 14 15 #ifndef LO_FLAGS_PARTSCAN 16 #define LO_FLAGS_PARTSCAN 8 17 #endif 18 19 // FIXME: Can't we find a way to do the logging in pure Go? 20 extern void DevmapperLogCallback(int level, char *file, int line, int dm_errno_or_class, char *str); 21 22 static void log_cb(int level, const char *file, int line, int dm_errno_or_class, const char *f, ...) 23 { 24 char buffer[256]; 25 va_list ap; 26 27 va_start(ap, f); 28 vsnprintf(buffer, 256, f, ap); 29 va_end(ap); 30 31 DevmapperLogCallback(level, (char *)file, line, dm_errno_or_class, buffer); 32 } 33 34 static void log_with_errno_init() 35 { 36 dm_log_with_errno_init(log_cb); 37 } 38 */ 39 import "C" 40 41 import "unsafe" 42 43 type ( 44 CDmTask C.struct_dm_task 45 46 CLoopInfo64 C.struct_loop_info64 47 LoopInfo64 struct { 48 loDevice uint64 /* ioctl r/o */ 49 loInode uint64 /* ioctl r/o */ 50 loRdevice uint64 /* ioctl r/o */ 51 loOffset uint64 52 loSizelimit uint64 /* bytes, 0 == max available */ 53 loNumber uint32 /* ioctl r/o */ 54 loEncrypt_type uint32 55 loEncrypt_key_size uint32 /* ioctl w/o */ 56 loFlags uint32 /* ioctl r/o */ 57 loFileName [LoNameSize]uint8 58 loCryptName [LoNameSize]uint8 59 loEncryptKey [LoKeySize]uint8 /* ioctl w/o */ 60 loInit [2]uint64 61 } 62 ) 63 64 // IOCTL consts 65 const ( 66 BlkGetSize64 = C.BLKGETSIZE64 67 BlkDiscard = C.BLKDISCARD 68 69 LoopSetFd = C.LOOP_SET_FD 70 LoopCtlGetFree = C.LOOP_CTL_GET_FREE 71 LoopGetStatus64 = C.LOOP_GET_STATUS64 72 LoopSetStatus64 = C.LOOP_SET_STATUS64 73 LoopClrFd = C.LOOP_CLR_FD 74 LoopSetCapacity = C.LOOP_SET_CAPACITY 75 ) 76 77 const ( 78 LoFlagsAutoClear = C.LO_FLAGS_AUTOCLEAR 79 LoFlagsReadOnly = C.LO_FLAGS_READ_ONLY 80 LoFlagsPartScan = C.LO_FLAGS_PARTSCAN 81 LoKeySize = C.LO_KEY_SIZE 82 LoNameSize = C.LO_NAME_SIZE 83 ) 84 85 const ( 86 DmUdevDisableSubsystemRulesFlag = C.DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG 87 DmUdevDisableDiskRulesFlag = C.DM_UDEV_DISABLE_DISK_RULES_FLAG 88 DmUdevDisableOtherRulesFlag = C.DM_UDEV_DISABLE_OTHER_RULES_FLAG 89 DmUdevDisableLibraryFallback = C.DM_UDEV_DISABLE_LIBRARY_FALLBACK 90 ) 91 92 var ( 93 DmGetLibraryVersion = dmGetLibraryVersionFct 94 DmGetNextTarget = dmGetNextTargetFct 95 DmLogInitVerbose = dmLogInitVerboseFct 96 DmSetDevDir = dmSetDevDirFct 97 DmTaskAddTarget = dmTaskAddTargetFct 98 DmTaskCreate = dmTaskCreateFct 99 DmTaskDestroy = dmTaskDestroyFct 100 DmTaskGetDeps = dmTaskGetDepsFct 101 DmTaskGetInfo = dmTaskGetInfoFct 102 DmTaskGetDriverVersion = dmTaskGetDriverVersionFct 103 DmTaskRun = dmTaskRunFct 104 DmTaskSetAddNode = dmTaskSetAddNodeFct 105 DmTaskSetCookie = dmTaskSetCookieFct 106 DmTaskSetMessage = dmTaskSetMessageFct 107 DmTaskSetName = dmTaskSetNameFct 108 DmTaskSetRo = dmTaskSetRoFct 109 DmTaskSetSector = dmTaskSetSectorFct 110 DmUdevWait = dmUdevWaitFct 111 DmUdevSetSyncSupport = dmUdevSetSyncSupportFct 112 DmUdevGetSyncSupport = dmUdevGetSyncSupportFct 113 DmCookieSupported = dmCookieSupportedFct 114 LogWithErrnoInit = logWithErrnoInitFct 115 DmTaskDeferredRemove = dmTaskDeferredRemoveFct 116 DmTaskGetInfoWithDeferred = dmTaskGetInfoWithDeferredFct 117 ) 118 119 func free(p *C.char) { 120 C.free(unsafe.Pointer(p)) 121 } 122 123 func dmTaskDestroyFct(task *CDmTask) { 124 C.dm_task_destroy((*C.struct_dm_task)(task)) 125 } 126 127 func dmTaskCreateFct(taskType int) *CDmTask { 128 return (*CDmTask)(C.dm_task_create(C.int(taskType))) 129 } 130 131 func dmTaskRunFct(task *CDmTask) int { 132 ret, _ := C.dm_task_run((*C.struct_dm_task)(task)) 133 return int(ret) 134 } 135 136 func dmTaskSetNameFct(task *CDmTask, name string) int { 137 Cname := C.CString(name) 138 defer free(Cname) 139 140 return int(C.dm_task_set_name((*C.struct_dm_task)(task), Cname)) 141 } 142 143 func dmTaskSetMessageFct(task *CDmTask, message string) int { 144 Cmessage := C.CString(message) 145 defer free(Cmessage) 146 147 return int(C.dm_task_set_message((*C.struct_dm_task)(task), Cmessage)) 148 } 149 150 func dmTaskSetSectorFct(task *CDmTask, sector uint64) int { 151 return int(C.dm_task_set_sector((*C.struct_dm_task)(task), C.uint64_t(sector))) 152 } 153 154 func dmTaskSetCookieFct(task *CDmTask, cookie *uint, flags uint16) int { 155 cCookie := C.uint32_t(*cookie) 156 defer func() { 157 *cookie = uint(cCookie) 158 }() 159 return int(C.dm_task_set_cookie((*C.struct_dm_task)(task), &cCookie, C.uint16_t(flags))) 160 } 161 162 func dmTaskSetAddNodeFct(task *CDmTask, addNode AddNodeType) int { 163 return int(C.dm_task_set_add_node((*C.struct_dm_task)(task), C.dm_add_node_t(addNode))) 164 } 165 166 func dmTaskSetRoFct(task *CDmTask) int { 167 return int(C.dm_task_set_ro((*C.struct_dm_task)(task))) 168 } 169 170 func dmTaskAddTargetFct(task *CDmTask, 171 start, size uint64, ttype, params string) int { 172 173 Cttype := C.CString(ttype) 174 defer free(Cttype) 175 176 Cparams := C.CString(params) 177 defer free(Cparams) 178 179 return int(C.dm_task_add_target((*C.struct_dm_task)(task), C.uint64_t(start), C.uint64_t(size), Cttype, Cparams)) 180 } 181 182 func dmTaskGetDepsFct(task *CDmTask) *Deps { 183 Cdeps := C.dm_task_get_deps((*C.struct_dm_task)(task)) 184 if Cdeps == nil { 185 return nil 186 } 187 deps := &Deps{ 188 Count: uint32(Cdeps.count), 189 Filler: uint32(Cdeps.filler), 190 } 191 for _, device := range Cdeps.device { 192 deps.Device = append(deps.Device, (uint64)(device)) 193 } 194 return deps 195 } 196 197 func dmTaskGetInfoFct(task *CDmTask, info *Info) int { 198 Cinfo := C.struct_dm_info{} 199 defer func() { 200 info.Exists = int(Cinfo.exists) 201 info.Suspended = int(Cinfo.suspended) 202 info.LiveTable = int(Cinfo.live_table) 203 info.InactiveTable = int(Cinfo.inactive_table) 204 info.OpenCount = int32(Cinfo.open_count) 205 info.EventNr = uint32(Cinfo.event_nr) 206 info.Major = uint32(Cinfo.major) 207 info.Minor = uint32(Cinfo.minor) 208 info.ReadOnly = int(Cinfo.read_only) 209 info.TargetCount = int32(Cinfo.target_count) 210 }() 211 return int(C.dm_task_get_info((*C.struct_dm_task)(task), &Cinfo)) 212 } 213 214 func dmTaskGetDriverVersionFct(task *CDmTask) string { 215 buffer := C.malloc(128) 216 defer C.free(buffer) 217 res := C.dm_task_get_driver_version((*C.struct_dm_task)(task), (*C.char)(buffer), 128) 218 if res == 0 { 219 return "" 220 } 221 return C.GoString((*C.char)(buffer)) 222 } 223 224 func dmGetNextTargetFct(task *CDmTask, next unsafe.Pointer, start, length *uint64, target, params *string) unsafe.Pointer { 225 var ( 226 Cstart, Clength C.uint64_t 227 CtargetType, Cparams *C.char 228 ) 229 defer func() { 230 *start = uint64(Cstart) 231 *length = uint64(Clength) 232 *target = C.GoString(CtargetType) 233 *params = C.GoString(Cparams) 234 }() 235 236 nextp := C.dm_get_next_target((*C.struct_dm_task)(task), next, &Cstart, &Clength, &CtargetType, &Cparams) 237 return nextp 238 } 239 240 func dmUdevSetSyncSupportFct(syncWithUdev int) { 241 (C.dm_udev_set_sync_support(C.int(syncWithUdev))) 242 } 243 244 func dmUdevGetSyncSupportFct() int { 245 return int(C.dm_udev_get_sync_support()) 246 } 247 248 func dmUdevWaitFct(cookie uint) int { 249 return int(C.dm_udev_wait(C.uint32_t(cookie))) 250 } 251 252 func dmCookieSupportedFct() int { 253 return int(C.dm_cookie_supported()) 254 } 255 256 func dmLogInitVerboseFct(level int) { 257 C.dm_log_init_verbose(C.int(level)) 258 } 259 260 func logWithErrnoInitFct() { 261 C.log_with_errno_init() 262 } 263 264 func dmSetDevDirFct(dir string) int { 265 Cdir := C.CString(dir) 266 defer free(Cdir) 267 268 return int(C.dm_set_dev_dir(Cdir)) 269 } 270 271 func dmGetLibraryVersionFct(version *string) int { 272 buffer := C.CString(string(make([]byte, 128))) 273 defer free(buffer) 274 defer func() { 275 *version = C.GoString(buffer) 276 }() 277 return int(C.dm_get_library_version(buffer, 128)) 278 }