github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/spdk/spdk.go (about) 1 /* 2 Copyright 2020 The OpenEBS Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // +build linux, cgo 18 19 package spdk 20 21 /* 22 #include "stdlib.h" 23 #include "stdint.h" 24 25 #define SPDK_BLOBSTORE_TYPE_LENGTH 16 26 27 typedef uint64_t spdk_blob_id; 28 29 typedef struct { 30 char bstype[SPDK_BLOBSTORE_TYPE_LENGTH]; 31 }spdk_bs_type; 32 33 struct spdk_bs_super_block { 34 uint8_t signature[8]; 35 uint32_t version; 36 uint32_t length; 37 uint32_t clean; 38 spdk_blob_id super_blob; 39 uint32_t cluster_size; 40 uint32_t used_page_mask_start; 41 uint32_t used_page_mask_len; 42 uint32_t used_cluster_mask_start; 43 uint32_t used_cluster_mask_len; 44 uint32_t md_start; 45 uint32_t md_len; 46 spdk_bs_type bstype; 47 uint32_t used_blobid_mask_start; 48 uint32_t used_blobid_mask_len; 49 uint64_t size; 50 uint32_t io_unit_size; 51 uint8_t reserved[4000]; 52 uint32_t crc; 53 }; 54 55 char *get_signature(struct spdk_bs_super_block *spdk) 56 { 57 return spdk->signature; 58 } 59 */ 60 import "C" 61 import ( 62 "encoding/binary" 63 "fmt" 64 "io" 65 "os" 66 "unsafe" 67 ) 68 69 const spdkSignature = "SPDKBLOB" 70 71 type DeviceIdentifier struct { 72 DevPath string 73 } 74 75 // IsSPDKSignatureExist check is the signature matches the spdk super block signature 76 func IsSPDKSignatureExist(signature string) bool { 77 // need to compare only the first 8 characters of signature 78 if len(signature) > 8 { 79 signature = signature[0:8] 80 } 81 return signature == spdkSignature 82 } 83 84 // GetSPDKSuperBlockSignature tries to read spdk super block from a disk and returns the signature 85 func (di *DeviceIdentifier) GetSPDKSuperBlockSignature() (string, error) { 86 var spdk *C.struct_spdk_bs_super_block 87 buf := make([]byte, C.sizeof_struct_spdk_bs_super_block) 88 f, err := os.Open(di.DevPath) 89 defer f.Close() 90 if err != nil { 91 return "", err 92 } 93 _, err = f.Seek(0, io.SeekStart) 94 if err != nil { 95 return "", err 96 } 97 err = binary.Read(f, binary.BigEndian, buf) 98 if err != nil { 99 return "", fmt.Errorf("error reading from %s: %v", di.DevPath, err) 100 } 101 102 // converting the read bytes to spdk super block struct 103 spdk = (*C.struct_spdk_bs_super_block)(C.CBytes(buf)) 104 defer C.free(unsafe.Pointer(spdk)) 105 106 ptr := (*C.char)(C.get_signature(spdk)) 107 return C.GoString(ptr), nil 108 }