cooper_volume.db文件读写
字节序格式图:
数据结构:
1 typedef struct { 2 char device_id[8]; // Without prefix "/dev/mapper/lv" 3 char subvol_id[16]; // volume_id + subvol_order 4 char src_subvol[16]; // volume_id + src_subvol_order 5 char member_ip[16]; 6 char client_ip[16]; 7 } SubVolType; 8 class VolumeType 9 { 10 public: 11 VolumeType() { 12 memset(volume_id, 0, 16); 13 memset(srcvol_id, 0, 16); 14 } 15 16 ~VolumeType() { 17 foreach (SubVolType* p, subvol_vec) 18 delete p; 19 } 20 21 public: 22 char role; 23 unsigned int timestamp; 24 char volume_id[16]; // The last 10 bytes of cinder-ID 25 char srcvol_id[16]; // The last 10 bytes of cinder-ID 26 vector<SubVolType*> subvol_vec; 27 }; 28 class CooperVolumeType 29 { 30 public: 31 ~CooperVolumeType() { 32 foreach (VolumeType* p, cooper_volume_vec) 33 delete p; 34 } 35 36 public: 37 vector<VolumeType*> cooper_volume_vec; 38 };
读写代码:
1 const int kVolumeIDLenth = 10; 2 const int kSubvolDevIDLenth = 4; 3 const char kRoleData = '0'; 4 const char kRoleCloneSrc = '1'; 5 const char kRoleClone = '2'; 6 const char kRoleSnapshotSrc = '3'; 7 const char kRoleSnapshot = '4'; 8 const char kRoleCloneSnapshotSrc = '5'; 9 const string kVolumeDevicePrefix = "/dev/mapper/lv"; 10 11 bool GetCooperVolumes(CooperVolumeType& cp_volumes) 12 { 13 cp_volumes.cooper_volume_vec.clear(); 14 BinaryFile bfile(kCooperVolumeDBFile); 15 16 if (ReadBinaryFile(bfile) < 0) { 17 return false; 18 } 19 20 char* cursor = bfile.file_buf_; 21 unsigned int volume_count = *(unsigned int*)cursor; 22 // printf("GetCooperVolumes: volume_count=%u\n", volume_count); 23 cursor += sizeof(int); 24 25 for (int i = 0; i != volume_count; ++i) { 26 unsigned int subvol_count = *(unsigned int*)cursor; 27 cursor += sizeof(int); 28 // printf("GetCooperVolumes: subvol_count=%u\n", subvol_count); 29 30 VolumeType* volume = new VolumeType; 31 volume->role = cursor[0]; 32 cursor += 1; 33 34 volume->timestamp = *(unsigned int*)cursor; 35 cursor += sizeof(int); 36 37 strncpy(volume->volume_id, cursor, kVolumeIDLenth); 38 cursor += kVolumeIDLenth; 39 40 strncpy(volume->srcvol_id, cursor, kVolumeIDLenth); 41 cursor += kVolumeIDLenth; 42 43 for (int j = 0; j != subvol_count; ++j) { 44 SubVolType* subvol = new SubVolType; 45 memset(subvol, 0, sizeof(SubVolType)); 46 unsigned int order = *(unsigned int*)cursor; 47 cursor += sizeof(int); 48 snprintf(subvol->subvol_id, 49 sizeof(subvol->subvol_id), "%s%u", volume->volume_id, order); 50 51 order = *(unsigned int*)cursor; 52 cursor += sizeof(int); 53 54 if (order != 0) { 55 snprintf(subvol->src_subvol, 56 sizeof(subvol->src_subvol), "%s%u", volume->volume_id, order); 57 } else { 58 sprintf(subvol->src_subvol, "none"); 59 } 60 61 char id[kMemberIDLenth + 1]; 62 string ip(""); 63 memset(id, 0, sizeof(id)); 64 strncpy(id, cursor, kMemberIDLenth); 65 cursor += kMemberIDLenth; 66 67 ConvertIDtoIP(string(id), ip); 68 strncpy(subvol->member_ip, ip.c_str(), ip.length()); 69 70 strncpy(id, cursor, kMemberIDLenth); 71 cursor += kMemberIDLenth; 72 73 ConvertIDtoIP(string(id), ip); 74 strncpy(subvol->client_ip, ip.c_str(), ip.length()); 75 76 strncpy(subvol->device_id, cursor, kSubvolDevIDLenth); 77 cursor += kSubvolDevIDLenth; 78 79 volume->subvol_vec.push_back(subvol); 80 // printf("GetCooperVolumes: Get subvolume: %s\n", subvol->subvol_id); 81 // printf("GetCooperVolumes: Get subvolume: %s\n", subvol->device_id); 82 } 83 84 cp_volumes.cooper_volume_vec.push_back(volume); 85 } 86 87 return true; 88 } 89 90 bool SetCooperVolumes(const CooperVolumeType& cp_volumes) 91 { 92 unsigned int volume_count = cp_volumes.cooper_volume_vec.size(); 93 unsigned int total_buf_size = sizeof(int); 94 95 for (int i = 0; i != volume_count; ++i) { 96 unsigned int subvol_count = cp_volumes.cooper_volume_vec[i]->subvol_vec.size(); 97 unsigned int subvol_bufsize = subvol_count * (2 * sizeof(int) + 2 * kMemberIDLenth + kSubvolDevIDLenth); 98 unsigned int volume_bufsize = 2 * sizeof(int) + 1 + 2 * kVolumeIDLenth + subvol_bufsize; 99 total_buf_size += volume_bufsize; 100 } 101 102 // printf("SetCooperVolumes: volume_count=%u, new_buf_size=%d\n", volume_count, total_buf_size); 103 104 BinaryFile bfile(kCooperVolumeDBFile); 105 bfile.InitBuf(total_buf_size); 106 char* cursor = bfile.file_buf_; 107 108 memcpy(cursor, (char*)&volume_count, sizeof(int)); 109 cursor += sizeof(int); 110 111 for (int i = 0; i != volume_count; ++i) { 112 unsigned int subvol_count = cp_volumes.cooper_volume_vec[i]->subvol_vec.size(); 113 memcpy(cursor, (char*)&subvol_count, sizeof(int)); 114 cursor += sizeof(int); 115 116 cursor[0] = cp_volumes.cooper_volume_vec[i]->role; 117 cursor += 1; 118 119 memcpy(cursor, (char*)&(cp_volumes.cooper_volume_vec[i]->timestamp), sizeof(int)); 120 cursor += sizeof(int); 121 122 strncpy(cursor, cp_volumes.cooper_volume_vec[i]->volume_id, kVolumeIDLenth); 123 cursor += kVolumeIDLenth; 124 125 strncpy(cursor, cp_volumes.cooper_volume_vec[i]->srcvol_id, kVolumeIDLenth); 126 cursor += kVolumeIDLenth; 127 128 for (int j = 0; j != subvol_count; ++j) { 129 unsigned int order = atoi(cp_volumes.cooper_volume_vec[i]->subvol_vec[j]->subvol_id + kVolumeIDLenth); 130 memcpy(cursor, (char*)&order, sizeof(int)); 131 cursor += sizeof(int); 132 // printf("SetCooperVolumes: Set subvolume order %d\n", order); 133 134 order = atoi(cp_volumes.cooper_volume_vec[i]->subvol_vec[j]->src_subvol + kVolumeIDLenth); 135 memcpy(cursor, (char*)&order, sizeof(int)); 136 cursor += sizeof(int); 137 // printf("SetCooperVolumes: Set src_subvol order %d\n", order); 138 139 string id(""); 140 ConvertIPtoID(string(cp_volumes.cooper_volume_vec[i]->subvol_vec[j]->member_ip), id); 141 strncpy(cursor, id.c_str(), kMemberIDLenth); 142 cursor += kMemberIDLenth; 143 144 ConvertIPtoID(string(cp_volumes.cooper_volume_vec[i]->subvol_vec[j]->client_ip), id); 145 strncpy(cursor, id.c_str(), kMemberIDLenth); 146 cursor += kMemberIDLenth; 147 148 strncpy(cursor, cp_volumes.cooper_volume_vec[i]->subvol_vec[j]->device_id, kSubvolDevIDLenth); 149 cursor += kSubvolDevIDLenth; 150 } 151 } 152 153 if (WriteBinaryFile(bfile) < 0) { 154 return false; 155 } 156 157 return true; 158 }
测试代码:
1 void TestInitCooperVolumes(CooperVolumeType& cp_volumes, unsigned int volume_count) 2 { 3 cp_volumes.cooper_volume_vec.clear(); 4 char roles[] = "012345"; 5 6 for (int i = 0; i != volume_count; ++i) { 7 int subvol_cnt = i % 32 + 1; 8 VolumeType* volume = new VolumeType; 9 10 volume->role = roles[i % 6]; 11 volume->timestamp = time(NULL); 12 snprintf(volume->volume_id, kVolumeIDLenth + 1, "%dabbccddee", i); 13 14 if (volume->role == kRoleData || volume->role == kRoleCloneSrc || volume->role == kRoleSnapshotSrc) { 15 sprintf(volume->srcvol_id, "none"); 16 } else { 17 snprintf(volume->srcvol_id, kVolumeIDLenth + 1, "ff%dbbccdde", i); 18 } 19 20 // printf("Init volume: Role=%c, timestamp=%u, subvol_cnt=%u, volume_id=%s, srcvol_id=%s\n", 21 // volume->role, volume->timestamp, subvol_cnt, volume->volume_id, volume->srcvol_id); 22 23 for (int j = 0; j != subvol_cnt; ++j) { 24 SubVolType* subvol = new SubVolType; 25 memset(subvol, 0, sizeof(SubVolType)); 26 snprintf(subvol->device_id, kSubvolDevIDLenth + 1, "%d%d", i, j); 27 snprintf(subvol->subvol_id, kVolumeIDLenth + sizeof(int) + 1, "%s%d%d", volume->volume_id, i, j); 28 snprintf(subvol->member_ip, 16, "%d.%d.%d.12%d", i%256, i%256, i%256, j%10); 29 snprintf(subvol->client_ip, 16, "12%d.%d.%d.%d", j%10, i%256, i%256, i%256); 30 31 if (volume->role != kRoleData && volume->role != kRoleCloneSrc && volume->role != kRoleSnapshotSrc) { 32 snprintf(subvol->src_subvol, kVolumeIDLenth + sizeof(int) + 1, "%s%d%d", volume->volume_id, j, i); 33 } else { 34 sprintf(subvol->src_subvol, "none"); 35 } 36 37 volume->subvol_vec.push_back(subvol); 38 // printf("Init subvolume: device_id=%s, subvol_id=%s, member_ip=%s, client_ip=%s, src_subvol=%s\n", 39 // subvol->device_id, subvol->subvol_id, 40 // subvol->member_ip, subvol->client_ip, subvol->src_subvol); 41 } 42 43 cp_volumes.cooper_volume_vec.push_back(volume); 44 } 45 } 46 47 void PrintCooperVolumes(const CooperVolumeType& cp_volumes) 48 { 49 map<char, string> role_dict; 50 role_dict.insert(make_pair('0', "data")); 51 role_dict.insert(make_pair('1', "clone source")); 52 role_dict.insert(make_pair('2', "clone")); 53 role_dict.insert(make_pair('3', "snapshot source")); 54 role_dict.insert(make_pair('4', "snapshot")); 55 role_dict.insert(make_pair('5', "clone snapshot source")); 56 57 foreach (VolumeType* vp, cp_volumes.cooper_volume_vec) { 58 cout << "Volume ID: " << vp->volume_id << endl; 59 60 if (role_dict.find(vp->role) != role_dict.end()) { 61 cout << "Volume Role: " << role_dict[vp->role] << endl; 62 } else { 63 cout << "Volume Role: unknown" << endl; 64 } 65 66 cout << "Source ID: " << vp->srcvol_id << endl; 67 string timestr(""); 68 ConvertTimestampToString(vp->timestamp, timestr); 69 cout << "Update Time: " << timestr << endl; 70 cout << "[" << endl; 71 int si = 0; 72 73 foreach (SubVolType* svp, vp->subvol_vec) { 74 cout << " SubVolume ID: " << svp->subvol_id << endl; 75 cout << " Source ID: " << svp->src_subvol << endl; 76 cout << " Device Path: " << kVolumeDevicePrefix << svp->device_id << endl; 77 cout << " Home Cluster: " << svp->member_ip << endl; 78 cout << " Attached To: " << svp->client_ip << endl; 79 80 if (++si < vp->subvol_vec.size()) 81 cout << " ------" << endl; 82 } 83 84 cout << "]" << endl << endl; 85 } 86 }