parent
1eec4407ab
commit
dac12d8a4c
@ -1,2 +1,3 @@ |
||||
usr/bin/vitastor-osd |
||||
usr/bin/vitastor-dump-journal |
||||
usr/bin/vitastor-dump-meta |
||||
|
@ -0,0 +1,173 @@ |
||||
// Copyright (c) Vitaliy Filippov, 2019+
|
||||
// License: VNPL-1.1 (see README.md for details)
|
||||
|
||||
#define _LARGEFILE64_SOURCE |
||||
#include <sys/types.h> |
||||
#include <sys/ioctl.h> |
||||
#include <sys/stat.h> |
||||
#include <sys/time.h> |
||||
#include <fcntl.h> |
||||
#include <unistd.h> |
||||
#include <stdint.h> |
||||
#include <malloc.h> |
||||
#include <linux/fs.h> |
||||
#include <string.h> |
||||
#include <errno.h> |
||||
#include <assert.h> |
||||
#include <stdio.h> |
||||
|
||||
#include "object_id.h" |
||||
#include "osd_id.h" |
||||
|
||||
// "VITAstor"
|
||||
#define BLOCKSTORE_META_MAGIC_V1 0x726F747341544956l |
||||
#define BLOCKSTORE_META_VERSION_V1 1 |
||||
|
||||
#define DIRECT_IO_ALIGNMENT 512 |
||||
#define MEM_ALIGNMENT 4096 |
||||
|
||||
struct __attribute__((__packed__)) clean_disk_entry_v0_t |
||||
{ |
||||
object_id oid; |
||||
uint64_t version; |
||||
uint8_t bitmap[]; |
||||
}; |
||||
|
||||
struct __attribute__((__packed__)) blockstore_meta_header_v1_t |
||||
{ |
||||
uint64_t zero; |
||||
uint64_t magic; |
||||
uint64_t version; |
||||
uint32_t meta_block_size; |
||||
uint32_t data_block_size; |
||||
uint32_t bitmap_granularity; |
||||
}; |
||||
|
||||
struct meta_dumper_t |
||||
{ |
||||
char *meta_device; |
||||
uint32_t meta_block_size; |
||||
uint64_t meta_offset; |
||||
uint64_t meta_len; |
||||
uint64_t meta_pos; |
||||
int fd; |
||||
}; |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
meta_dumper_t self = { 0 }; |
||||
int b = 1; |
||||
if (argc < b+4) |
||||
{ |
||||
printf("USAGE: %s <meta_file> <meta_block_size> <offset> <size>\n", argv[0]); |
||||
return 1; |
||||
} |
||||
self.meta_device = argv[b]; |
||||
self.meta_block_size = strtoul(argv[b+1], NULL, 10); |
||||
self.meta_offset = strtoull(argv[b+2], NULL, 10); |
||||
self.meta_len = strtoull(argv[b+3], NULL, 10); |
||||
if (self.meta_block_size % DIRECT_IO_ALIGNMENT) |
||||
{ |
||||
printf("Invalid metadata block size\n"); |
||||
return 1; |
||||
} |
||||
self.fd = open(self.meta_device, O_DIRECT|O_RDONLY); |
||||
if (self.fd == -1) |
||||
{ |
||||
printf("Failed to open metadata device\n"); |
||||
return 1; |
||||
} |
||||
// Read all metadata into memory
|
||||
void *data = memalign(MEM_ALIGNMENT, self.meta_len); |
||||
if (!data) |
||||
{ |
||||
printf("Failed to allocate %lu MB of memory\n", self.meta_len/1024/1024); |
||||
close(self.fd); |
||||
return 1; |
||||
} |
||||
while (self.meta_pos < self.meta_len) |
||||
{ |
||||
int r = pread(self.fd, data+self.meta_pos, self.meta_len-self.meta_pos, self.meta_offset+self.meta_pos); |
||||
assert(r > 0); |
||||
self.meta_pos += r; |
||||
} |
||||
close(self.fd); |
||||
// Check superblock
|
||||
blockstore_meta_header_v1_t *hdr = (blockstore_meta_header_v1_t *)data; |
||||
if (hdr->zero == 0 && |
||||
hdr->magic == BLOCKSTORE_META_MAGIC_V1 && |
||||
hdr->version == BLOCKSTORE_META_VERSION_V1) |
||||
{ |
||||
// Vitastor 0.6-0.7 - static array of clean_disk_entry_v0_t with bitmaps
|
||||
if (hdr->meta_block_size != self.meta_block_size) |
||||
{ |
||||
printf("Using block size %u bytes based on information from the superblock\n", hdr->meta_block_size); |
||||
self.meta_block_size = hdr->meta_block_size; |
||||
} |
||||
uint64_t clean_entry_bitmap_size = hdr->data_block_size / hdr->bitmap_granularity / 8; |
||||
uint64_t clean_entry_size = sizeof(clean_disk_entry_v0_t) + 2*clean_entry_bitmap_size; |
||||
uint64_t block_num = 0; |
||||
printf( |
||||
"{\"version\":\"0.6\",\"meta_block_size\":%u,\"data_block_size\":%u,\"bitmap_granularity\":%u,\"entries\":[\n", |
||||
hdr->meta_block_size, hdr->data_block_size, hdr->bitmap_granularity |
||||
); |
||||
bool first = true; |
||||
for (uint64_t meta_pos = self.meta_block_size; meta_pos < self.meta_len; meta_pos += self.meta_block_size) |
||||
{ |
||||
for (uint64_t ioff = 0; ioff < self.meta_block_size-clean_entry_size; ioff += clean_entry_size, block_num++) |
||||
{ |
||||
clean_disk_entry_v0_t *entry = (clean_disk_entry_v0_t*)(data + meta_pos + ioff); |
||||
if (entry->oid.inode) |
||||
{ |
||||
printf( |
||||
#define ENTRY_FMT "{\"block\":%lu,\"pool\":%u,\"inode\":%lu,\"stripe\":%lu,\"version\":%lu,\"bitmap\":\"" |
||||
(first ? (",\n" ENTRY_FMT) : ENTRY_FMT), |
||||
#undef ENTRY_FMT |
||||
block_num, INODE_POOL(entry->oid.inode), INODE_NO_POOL(entry->oid.inode), |
||||
entry->oid.stripe, entry->version |
||||
); |
||||
first = false; |
||||
for (uint64_t i = 0; i < clean_entry_bitmap_size; i++) |
||||
{ |
||||
printf("%02x", entry->bitmap[i]); |
||||
} |
||||
printf("\",\"ext_bitmap\":\""); |
||||
for (uint64_t i = 0; i < clean_entry_bitmap_size; i++) |
||||
{ |
||||
printf("%02x", entry->bitmap[clean_entry_bitmap_size + i]); |
||||
} |
||||
printf("\"}"); |
||||
} |
||||
} |
||||
} |
||||
printf("]}\n"); |
||||
} |
||||
else |
||||
{ |
||||
// Vitastor 0.4-0.5 - static array of clean_disk_entry_v0_t
|
||||
uint64_t clean_entry_size = sizeof(clean_disk_entry_v0_t); |
||||
uint64_t block_num = 0; |
||||
printf("{\"version\":\"0.5\",\"meta_block_size\":%u,\"entries\":[\n", self.meta_block_size); |
||||
bool first = true; |
||||
for (uint64_t meta_pos = 0; meta_pos < self.meta_len; meta_pos += self.meta_block_size) |
||||
{ |
||||
for (uint64_t ioff = 0; ioff < self.meta_block_size-clean_entry_size; ioff += clean_entry_size, block_num++) |
||||
{ |
||||
clean_disk_entry_v0_t *entry = (clean_disk_entry_v0_t*)(data + meta_pos + ioff); |
||||
if (entry->oid.inode) |
||||
{ |
||||
printf( |
||||
#define ENTRY_FMT "{\"block\":%lu,\"pool\":%u,\"inode\":%lu,\"stripe\":%lu,\"version\":%lu}" |
||||
(first ? (",\n" ENTRY_FMT) : ENTRY_FMT), |
||||
#undef ENTRY_FMT |
||||
block_num, INODE_POOL(entry->oid.inode), INODE_NO_POOL(entry->oid.inode), |
||||
entry->oid.stripe, entry->version |
||||
); |
||||
first = false; |
||||
} |
||||
} |
||||
} |
||||
printf("]}\n"); |
||||
} |
||||
free(data); |
||||
} |
Loading…
Reference in new issue