[DRBD-cvs] r1597 - trunk/user
svn at svn.drbd.org
svn at svn.drbd.org
Tue Oct 19 00:13:50 CEST 2004
Author: phil
Date: 2004-10-19 00:13:46 +0200 (Tue, 19 Oct 2004)
New Revision: 1597
Modified:
trunk/user/drbdmeta.c
Log:
drbdmeta is now nearly complete. [Only two small TODOs left]
Now it knows about meta-data formats v06 and v07
and these commands are implementd:
show-gc, get-gc, create-md, dump-md, convert-md and set-gc
Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c 2004-10-18 16:14:11 UTC (rev 1596)
+++ trunk/user/drbdmeta.c 2004-10-18 22:13:46 UTC (rev 1597)
@@ -41,7 +41,6 @@
#if G_MAXLONG == 0x7FFFFFFF
#define LN2_BPL 5
#define hweight_long hweight32
-#define WW UL
#elif G_MAXLONG == 0x7FFFFFFFFFFFFFFF
#define LN2_BPL 6
#define hweight_long hweight64
@@ -53,7 +52,11 @@
#define MD_AL_MAX_SIZE_07 64
#define MD_BM_OFFSET_07 (MD_AL_OFFSET_07 + MD_AL_MAX_SIZE_07)
#define DRBD_MD_MAGIC_07 (DRBD_MAGIC+3)
+#define MD_RESERVED_SIZE_07 ( (typeof(guint64))128 * (1<<20) )
+#define MD_BM_MAX_SIZE_07 ( MD_RESERVED_SIZE_07 - MD_BM_OFFSET_07*512 )
+#define DRBD_MD_MAGIC_06 (DRBD_MAGIC+2)
+
char* progname = 0;
enum MetaDataFlags {
@@ -67,6 +70,9 @@
#define MDF_ConnectedInd (1<<__MDF_ConnectedInd)
#define MDF_FullSync (1<<__MDF_FullSync)
+#define OR_EXIT(OBJ,OP,args...) \
+({ if(! OBJ->ops-> OP(OBJ, ##args) ) format_op_failed(OBJ, #OP ); })
+
enum MetaDataIndex {
Flags, /* Consistency flag,connected-ind,primary-ind */
HumanCnt, /* human-intervention-count */
@@ -83,21 +89,11 @@
int bm_size; // v07
unsigned long *bitmap; // v07
int al_size; // v07
- unsigned int *act_log; // v07
+ unsigned int *act_log; // not yet implemented...
unsigned long bits_set; // additional info, set by fopts->read()
};
-struct meta_data_on_disk_07 {
- guint64 la_size; // last agreed size.
- guint32 gc[GEN_CNT_SIZE]; // generation counter
- guint32 magic;
- guint32 md_size;
- guint32 al_offset; // offset to this block
- guint32 al_nr_extents; // important for restoring the AL
- guint32 bm_offset; // offset to the bitmap, from here
-};
-
struct format_06 {
int fd;
int minor;
@@ -125,32 +121,14 @@
const char* name;
char** args;
int conf_size;
- int (* parse)(struct format *, char **argv, int argc, int*);
+ int (* parse)(struct format *, char **, int, int*);
int (* open) (struct format *);
int (* close)(struct format *);
+ struct meta_data * (* md_alloc)(void);
int (* read) (struct format *, struct meta_data *);
- int (* write)(struct format *, struct meta_data *);
+ int (* write)(struct format *, struct meta_data *, int);
};
-int v07_parse(struct format * config, char **argv, int argc, int *ai);
-int v07_open(struct format * config);
-int v07_close(struct format * config);
-int v07_read(struct format * config, struct meta_data *);
-int v07_write(struct format * config, struct meta_data *);
-
-struct format_ops formats[] = {
- { "v07",
- (char *[]) { "device","index",0 },
- sizeof(struct format_07),
- v07_parse,
- v07_open,
- v07_close,
- v07_read,
- v07_write
- }
-};
-
-
static inline guint32 hweight32(guint32 w)
{
guint32 res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
@@ -176,6 +154,12 @@
#endif
}
+void format_op_failed(struct format * fcfg, char* op)
+{
+ fprintf(stderr,"%s_%s() failed\n",fcfg->ops->name,op);
+ exit(20);
+}
+
/* capacity in units of 512 byte (AKA sectors)
*/
int bm_words(unsigned long capacity)
@@ -190,6 +174,100 @@
return words;
}
+void to_lel(unsigned long* buffer, int words)
+{
+ int i;
+ unsigned long w;
+
+ for (i=0;i<words;i++) {
+ w = GULONG_TO_LE(buffer[i]);
+ buffer[i] = w;
+ }
+}
+
+
+unsigned long from_lel(unsigned long* buffer, int words)
+{
+ int i;
+ unsigned long w;
+ unsigned long bits=0;
+
+ for (i=0;i<words;i++) {
+ w = GULONG_FROM_LE(buffer[i]);
+ bits += hweight_long(w);
+ buffer[i] = w;
+ }
+
+ return bits;
+}
+
+guint64 bdev_size(int fd)
+{
+ guint64 size64; // size in byte.
+ long size; // size in sectors.
+ int err;
+
+ err=ioctl(fd,BLKGETSIZE64,&size64);
+ if(err) {
+ if (errno == EINVAL) {
+ printf("INFO: falling back to BLKGETSIZE\n");
+ err=ioctl(fd,BLKGETSIZE,&size);
+ if(err) {
+ perror("ioctl(,BLKGETSIZE,) failed");
+ exit(20);
+ }
+ size64 = (typeof(guint64))512 * size;
+ } else {
+ perror("ioctl(,BLKGETSIZE64,) failed");
+ exit(20);
+ }
+ }
+
+ return size64;
+}
+
+void md_free(struct meta_data * m)
+{
+
+ if(m->bitmap) free(m->bitmap);
+ if(m->act_log) free(m->act_log);
+
+ free(m);
+}
+
+/******************************************
+ begin of v07
+ ******************************************/
+struct __attribute__((packed)) meta_data_on_disk_07 {
+ guint64 la_size; // last agreed size.
+ guint32 gc[GEN_CNT_SIZE]; // generation counter
+ guint32 magic;
+ guint32 md_size;
+ guint32 al_offset; // offset to this block
+ guint32 al_nr_extents; // important for restoring the AL
+ guint32 bm_offset; // offset to the bitmap, from here
+};
+
+guint64 v07_offset(struct format_07* cfg)
+{
+ guint64 offset;
+
+ if(cfg->index == -1) {
+ offset = ( bdev_size(cfg->fd) & ~((1<<12)-1) )
+ - MD_RESERVED_SIZE_07;
+ } else {
+ offset = MD_RESERVED_SIZE_07 * cfg->index;
+ }
+ return offset;
+}
+
+int v07_parse(struct format * config, char **argv, int argc, int *ai);
+int v07_open(struct format * config);
+int v07_close(struct format * config);
+struct meta_data * v07_md_alloc(void);
+int v07_read(struct format * config, struct meta_data *);
+int v07_write(struct format * config, struct meta_data *, int init_al);
+
int v07_parse(struct format * config, char **argv, int argc, int *ai)
{
struct format_07* cfg = &config->d.f07;
@@ -246,146 +324,286 @@
return close(cfg->fd) == 0;
}
-struct meta_data * md_alloc()
+struct meta_data * v07_md_alloc(void)
{
struct meta_data *m;
m = malloc(sizeof(struct meta_data ));
memset(m,0,sizeof(struct meta_data ));
+
+ m->bitmap = malloc(MD_BM_MAX_SIZE_07);
+ if( ! m->bitmap) {
+ PERROR("Can not allocate memory for bitmap.");
+ return 0;
+ }
+
+ m->bm_size = MD_BM_MAX_SIZE_07;
return m;
}
-void md_free(struct meta_data * m)
+int v07_read(struct format * config, struct meta_data * m)
{
+ struct format_07* cfg = &config->d.f07;
+ struct meta_data_on_disk_07 buffer;
+ int rr,i,bmw;
+ guint64 offset = v07_offset(cfg);
- if(m->bitmap) free(m->bitmap);
- if(m->act_log) free(m->act_log);
+ if(lseek64(cfg->fd,offset,SEEK_SET) == -1) {
+ PERROR("lseek() failed");
+ return 0;
+ }
- free(m);
-}
+ rr = read(cfg->fd, &buffer, sizeof(struct meta_data_on_disk_07));
+ if( rr != sizeof(struct meta_data_on_disk_07)) {
+ PERROR("read failed");
+ return 0;
+ }
+
+ if( GUINT32_FROM_BE(buffer.magic) != DRBD_MD_MAGIC_07 ) {
+ fprintf(stderr,"Magic number not found\n");
+ return 0;
+ }
-#define MD_RESERVED_SIZE_07 ( (typeof(guint64))128 * (1<<20) )
+ if( GUINT32_FROM_BE(buffer.al_offset) != MD_AL_OFFSET_07 ) {
+ fprintf(stderr,"Magic number (al_offset) not found\n");
+ return 0;
+ }
+ if( GUINT32_FROM_BE(buffer.bm_offset) != MD_BM_OFFSET_07 ) {
+ fprintf(stderr,"Magic number (bm_offset) not found\n");
+ return 0;
+ }
-guint64 bdev_size(int fd)
-{
- guint64 size64; // size in byte.
- long size; // size in sectors.
- int err;
+ for (i = Flags; i < GEN_CNT_SIZE; i++)
+ m->gc[i] = GUINT32_FROM_BE(buffer.gc[i]);
- err=ioctl(fd,BLKGETSIZE64,&size64);
- if(err) {
- if (errno == EINVAL) {
- printf("INFO: falling back to BLKGETSIZE\n");
- err=ioctl(fd,BLKGETSIZE,&size);
- if(err) {
- perror("ioctl(,BLKGETSIZE,) failed");
- exit(20);
- }
- size64 = (typeof(guint64))512 * size;
- } else {
- perror("ioctl(,BLKGETSIZE64,) failed");
- exit(20);
+ m->la_size = GUINT64_FROM_BE(buffer.la_size);
+
+ if(m->bitmap) {
+ bmw = bm_words(m->la_size);
+
+ offset = offset + 512 * MD_BM_OFFSET_07;
+ if(lseek64(cfg->fd, offset, SEEK_SET) == -1) {
+ PERROR("lseek() failed");
+ return 0;
}
- }
- return size64;
-}
+ rr = read(cfg->fd, m->bitmap, bmw*sizeof(long));
+ if( rr != bmw*sizeof(long) ) {
+ PERROR("read failed");
+ return 0;
+ }
-unsigned long from_lel(unsigned long* buffer, int words)
-{
- int i;
- unsigned long w;
- unsigned long bits=0;
-
- for (i=0;i<words;i++) {
- w = GULONG_FROM_LE(buffer[i]);
- bits += hweight_long(w);
- buffer[i] = w;
+ m->bm_size = bmw*sizeof(long);
+ m->bits_set = from_lel(m->bitmap,bmw);
}
- return bits;
+ return 1;
}
-int v07_read(struct format * config, struct meta_data * m)
+int v07_write(struct format * config, struct meta_data * m, int init_al)
{
struct format_07* cfg = &config->d.f07;
- struct meta_data_on_disk_07 * buffer;
- int rr,i,bmw;
- guint64 offset;
+ struct meta_data_on_disk_07 buffer;
+ int rr,i;
+ guint64 offset = v07_offset(cfg);
- buffer = malloc(sizeof(struct meta_data_on_disk_07));
+ buffer.magic = GUINT32_TO_BE( DRBD_MD_MAGIC_07 );
+ buffer.al_offset = GUINT32_TO_BE( MD_AL_OFFSET_07 );
+ buffer.bm_offset = GUINT32_TO_BE( MD_BM_OFFSET_07 );
- if(cfg->index == -1) {
- offset = ( bdev_size(cfg->fd) & ~((1<<12)-1) )
- - MD_RESERVED_SIZE_07;
- } else {
- offset = MD_RESERVED_SIZE_07 * cfg->index;
- }
-
+ for (i = Flags; i < GEN_CNT_SIZE; i++)
+ buffer.gc[i] = GUINT32_TO_BE(m->gc[i]);
+
+ buffer.la_size = GUINT64_TO_BE(m->la_size);
+
if(lseek64(cfg->fd,offset,SEEK_SET) == -1) {
PERROR("lseek() failed");
return 0;
}
- rr = read(cfg->fd, buffer, sizeof(struct meta_data_on_disk_07));
+ rr = write(cfg->fd, &buffer, sizeof(struct meta_data_on_disk_07));
if( rr != sizeof(struct meta_data_on_disk_07)) {
- PERROR("read failed");
+ PERROR("write failed");
return 0;
}
-
- if( GUINT32_FROM_BE(buffer->magic) != DRBD_MD_MAGIC_07 ) {
- fprintf(stderr,"Magic number not found");
+
+ if(lseek64(cfg->fd,offset + 512 * MD_BM_OFFSET_07 ,SEEK_SET) == -1) {
+ PERROR("lseek() failed");
return 0;
}
- if( GUINT32_FROM_BE(buffer->al_offset) != MD_AL_OFFSET_07 ) {
- fprintf(stderr,"Magic number (al_offset) not found");
+ to_lel(m->bitmap, m->bm_size/sizeof(long) );
+
+ rr = write(cfg->fd, m->bitmap, m->bm_size);
+ if( rr != m->bm_size) {
+ PERROR("write failed");
return 0;
}
- if( GUINT32_FROM_BE(buffer->bm_offset) != MD_BM_OFFSET_07 ) {
- fprintf(stderr,"Magic number (bm_offset) not found");
+ from_lel(m->bitmap, m->bm_size/sizeof(long) );
+
+ if( init_al ) {
+ // TODO;
+ }
+
+ return 1;
+}
+/******************************************
+ end of v07
+ ******************************************/
+
+/******************************************
+ begin of v06
+ ******************************************/
+struct __attribute__((packed)) meta_data_on_disk_06 {
+ guint32 gc[GEN_CNT_SIZE]; // generation counter
+ guint32 magic;
+};
+
+int v06_parse(struct format * config, char **argv, int argc, int *ai);
+int v06_open(struct format * config);
+int v06_close(struct format * config);
+struct meta_data * v06_md_alloc(void);
+int v06_read(struct format * config, struct meta_data *);
+int v06_write(struct format * config, struct meta_data *, int init_al);
+
+int v06_parse(struct format * config, char **argv, int argc, int *ai)
+{
+ struct format_06* cfg = &config->d.f06;
+ char *e;
+
+ if(argc < 1) {
+ fprintf(stderr,"Too few arguments for format\n");
return 0;
}
- for (i = Flags; i < GEN_CNT_SIZE; i++)
- m->gc[i] = GUINT32_FROM_BE(buffer->gc[Flags]);
+ e = argv[0];
+ cfg->minor = strtol(argv[0],&e,0);
+ if(*e != 0) {
+ fprintf(stderr,"'%s' is not a valid index number.\n",argv[1]);
+ return 0;
+ }
- m->la_size = GUINT64_FROM_BE(buffer->la_size);
- bmw = bm_words(m->la_size);
+ *ai+=1;
- m->bitmap = malloc(sizeof(long) * bmw);
- if( ! m->bitmap) {
- PERROR("Can not allocate memory for bitmap.");
+ return 1;
+}
+
+int v06_open(struct format * config)
+{
+ struct format_06* cfg = &config->d.f06;
+ char fn[100];
+
+ snprintf(fn,99,"/var/lib/drbd/drbd%d",cfg->minor);
+
+ cfg->fd = open(fn,O_RDWR);
+
+ if(cfg->fd == -1) {
+ PERROR("open() failed");
return 0;
}
- m->bm_size = bmw*sizeof(long);
- if(lseek64(cfg->fd,offset + 512 * MD_BM_OFFSET_07 ,SEEK_SET) == -1) {
+ return 1;
+}
+
+int v06_close(struct format * config)
+{
+ struct format_06* cfg = &config->d.f06;
+
+ return close(cfg->fd) == 0;
+}
+
+struct meta_data * v06_md_alloc(void)
+{
+ struct meta_data *m;
+
+ m = malloc(sizeof(struct meta_data ));
+ memset(m,0,sizeof(struct meta_data ));
+
+ return m;
+}
+
+int v06_read(struct format * config, struct meta_data * m)
+{
+ struct format_06* cfg = &config->d.f06;
+ struct meta_data_on_disk_06 buffer;
+ int rr,i;
+
+ if(lseek64(cfg->fd,0,SEEK_SET) == -1) {
PERROR("lseek() failed");
return 0;
}
- rr = read(cfg->fd, m->bitmap, bmw*sizeof(long));
- if( rr != bmw*sizeof(long) ) {
+ rr = read(cfg->fd, &buffer, sizeof(struct meta_data_on_disk_06));
+ if( rr != sizeof(struct meta_data_on_disk_06)) {
PERROR("read failed");
return 0;
}
+
+ if( GUINT32_FROM_BE(buffer.magic) != DRBD_MD_MAGIC_06 ) {
+ fprintf(stderr,"Magic number not found\n");
+ return 0;
+ }
- m->bits_set = from_lel(m->bitmap,bmw);
+ for (i = Flags; i < GEN_CNT_SIZE; i++)
+ m->gc[i] = GUINT32_FROM_BE(buffer.gc[i]);
return 1;
}
-int v07_write(struct format * config, struct meta_data * m)
+int v06_write(struct format * config, struct meta_data * m, int init_al)
{
- //struct format_07* cfg = &config->d.f07;
+ struct format_06* cfg = &config->d.f06;
+ struct meta_data_on_disk_06 buffer;
+ int rr,i;
- return 0;
+ buffer.magic = GUINT32_TO_BE( DRBD_MD_MAGIC_06 );
+
+ for (i = Flags; i < GEN_CNT_SIZE; i++)
+ buffer.gc[i] = GUINT32_TO_BE(m->gc[i]);
+
+ if(lseek64(cfg->fd,0,SEEK_SET) == -1) {
+ PERROR("lseek() failed");
+ return 0;
+ }
+
+ rr = write(cfg->fd, &buffer, sizeof(struct meta_data_on_disk_06));
+ if( rr != sizeof(struct meta_data_on_disk_06)) {
+ PERROR("write failed");
+ return 0;
+ }
+
+ return 1;
}
+/******************************************
+ end of v06
+ ******************************************/
+struct format_ops formats[] = {
+ { "v06",
+ (char *[]) { "minor", 0 },
+ sizeof(struct format_06),
+ v06_parse,
+ v06_open,
+ v06_close,
+ v06_md_alloc,
+ v06_read,
+ v06_write
+ },
+ { "v07",
+ (char *[]) { "device","index",0 },
+ sizeof(struct format_07),
+ v07_parse,
+ v07_open,
+ v07_close,
+ v07_md_alloc,
+ v07_read,
+ v07_write
+ }
+};
+
struct meta_cmd {
const char* name;
const char* args;
@@ -393,15 +611,6 @@
int show_in_usage;
};
-void format_op_failed(struct format * fcfg, char* op)
-{
- fprintf(stderr,"%s_%s() failed\n",fcfg->ops->name,op);
- exit(20);
-}
-
-#define F_OP_OR_EXIT(OP,args...) \
-({ if(! fcfg->ops-> OP(fcfg, ##args) ) format_op_failed(fcfg, #OP ); })
-
int meta_show_gc(struct format * fcfg, char** argv, int argc )
{
struct meta_data* md;
@@ -410,12 +619,11 @@
if(argc > 0) {
fprintf(stderr,"Ignoring additional arguments\n");
}
+ md = fcfg->ops->md_alloc();
- md = md_alloc();
-
- F_OP_OR_EXIT(open);
- F_OP_OR_EXIT(read,md);
- printf(
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,read,md);
+ printf( "\n"
" WantFullSync |\n"
" ConnectedInd | |\n"
" lastState | | |\n"
@@ -423,9 +631,10 @@
" ConnectedCnt | | | | |\n"
" TimeoutCnt | | | | | |\n"
" HumanCnt | | | | | | |\n"
- "Consistent | | | | | | | | Size\n"
- " --------+-----+-----+-----+-----+-----+-----+-----+------------------+\n"
- " %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s | %s\n",
+ "Consistent | | | | | | | |\n"
+ " --------+-----+-----+-----+-----+-----+-----+-----+\n"
+ " %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s \n"
+ "\n",
md->gc[Flags] & MDF_Consistent ? "1/c" : "0/i",
md->gc[HumanCnt],
md->gc[TimeoutCnt],
@@ -433,27 +642,231 @@
md->gc[ArbitraryCnt],
md->gc[Flags] & MDF_PrimaryInd ? "1/p" : "0/s",
md->gc[Flags] & MDF_ConnectedInd ? "1/c" : "0/n",
- md->gc[Flags] & MDF_FullSync ? "1/y" : "0/n",
- ppsize(ppb,md->la_size));
+ md->gc[Flags] & MDF_FullSync ? "1/y" : "0/n");
- fcfg->ops->close(fcfg);
+ if(md->la_size) {
+ printf("last agreed size: %s\n", ppsize(ppb,md->la_size));
+ }
+
+ if(md->bitmap) {
+ printf("%lu bits set in the bitmap [ %s out of sync ]\n",
+ md->bits_set, ppsize(ppb,md->bits_set));
+ }
+
+ OR_EXIT(fcfg,close);
+
md_free(md);
- return 1;
+ return 0;
}
-int meta_create_md(struct format * fcfg, char** argv, int argc ) { return 0; }
-int meta_dump_md(struct format * fcfg, char** argv, int argc ) { return 0; }
-int meta_convert_md(struct format * fcfg, char** argv, int argc ) { return 0; }
-int meta_modify_gc(struct format * fcfg, char** argv, int argc ) { return 0; }
+int meta_get_gc(struct format * fcfg, char** argv, int argc )
+{
+ struct meta_data* md;
+ if(argc > 0) {
+ fprintf(stderr,"Ignoring additional arguments\n");
+ }
+
+ md = fcfg->ops->md_alloc();
+
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,read,md);
+ printf("%d:%d:%d:%d:%d:%d:%d:%d\n",
+ md->gc[Flags] & MDF_Consistent ? 1 : 0,
+ md->gc[HumanCnt],
+ md->gc[TimeoutCnt],
+ md->gc[ConnectedCnt],
+ md->gc[ArbitraryCnt],
+ md->gc[Flags] & MDF_PrimaryInd ? 1 : 0,
+ md->gc[Flags] & MDF_ConnectedInd ? 1 : 0,
+ md->gc[Flags] & MDF_FullSync ? 1 : 0);
+
+ OR_EXIT(fcfg,close);
+
+ md_free(md);
+
+ return 0;
+}
+
+int meta_create_md(struct format * fcfg, char** argv, int argc )
+{
+ struct meta_data* md;
+
+ if(argc > 0) {
+ fprintf(stderr,"Ignoring additional arguments\n");
+ }
+
+ md = fcfg->ops->md_alloc();
+
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,write,md,1);
+ OR_EXIT(fcfg,close);
+
+ md_free(md);
+
+ return 0;
+}
+
+struct format* parse_format(char** argv, int argc, int* ai);
+
+int meta_convert_md(struct format * fcfg, char** argv, int argc )
+{
+ struct format * target;
+ struct meta_data* md;
+ int unused;
+
+ target = parse_format(argv, argc, &unused );
+
+ md = target->ops->md_alloc();
+
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,read,md);
+ OR_EXIT(fcfg,close);
+
+ OR_EXIT(target,open);
+ OR_EXIT(target,write,md,1); // init_al = 1 ?!?
+ OR_EXIT(target,close);
+
+ md_free(md);
+
+ return 0;
+}
+
+int meta_dump_md(struct format * fcfg, char** argv, int argc )
+{
+ struct meta_data* md;
+ guint64 *b;
+ int words;
+ int i;
+
+ if(argc > 0) {
+ fprintf(stderr,"Ignoring additional arguments\n");
+ }
+
+ md = fcfg->ops->md_alloc();
+
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,read,md);
+ printf("gc {");
+ for(i=0;i<GEN_CNT_SIZE;i++) {
+ printf(" 0x%X;",md->gc[i]);
+ }
+ printf(" }\n");
+
+ // if(md->la_size) TODO.
+
+ if(md->bitmap) {
+ words = md->bm_size/sizeof(guint64);
+ b = (guint64*) md->bitmap;
+ printf("bm {");
+ for (i=0;i<words;i++) {
+#if G_MAXLONG == 0x7FFFFFFF
+ printf(" 0x%016llX;",b[i]);
+#elif G_MAXLONG == 0x7FFFFFFFFFFFFFFF
+ printf(" 0x%016lX;",b[i]);
+#endif
+ if(i%4 == 3) printf("\n ");
+ }
+ printf(" }\n");
+ }
+
+ OR_EXIT(fcfg,close);
+
+ md_free(md);
+
+ return 0;
+}
+
+int m_strsep(char **s,int *val)
+{
+ char *t, *e;
+ int v;
+
+ if( (t = strsep(s,":")) ) {
+ if(strlen(t)) {
+ e = t;
+ v = strtol(t,&e,0);
+ if(*e != 0) {
+ fprintf(stderr,"'%s' is not a number.\n",*s);
+ exit(10);
+ }
+ if(v < 0 ) {
+ fprintf(stderr,"'%s' is negative.\n",*s);
+ exit(10);
+ }
+ *val = v;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+int m_strsep_b(char **s,int *val, int mask)
+{
+ int d;
+ int rv;
+
+ d = *val & mask;
+
+ rv = m_strsep(s,&d);
+
+ if(d > 1) {
+ fprintf(stderr,"'%d' is not 0 or 1.\n",d);
+ exit(10);
+ }
+
+ if(d) *val |= mask;
+ else *val &= ~mask;
+
+ return rv;
+}
+
+// "::14" sets the TimeoutCnt to 14
+int meta_set_gc(struct format * fcfg, char** argv, int argc )
+{
+ struct meta_data* md;
+ char **str;
+
+ if(argc < 1) {
+ fprintf(stderr,"Required Argument missing\n");
+ exit(10);
+ }
+ str = &argv[0];
+
+ md = fcfg->ops->md_alloc();
+
+ OR_EXIT(fcfg,open);
+ OR_EXIT(fcfg,read,md);
+
+ do {
+ if(!m_strsep_b(str,&md->gc[Flags],MDF_Consistent)) break;
+ if(!m_strsep(str,&md->gc[HumanCnt])) break;
+ if(!m_strsep(str,&md->gc[TimeoutCnt])) break;
+ if(!m_strsep(str,&md->gc[ConnectedCnt])) break;
+ if(!m_strsep(str,&md->gc[ArbitraryCnt])) break;
+ if(!m_strsep_b(str,&md->gc[Flags],MDF_PrimaryInd)) break;
+ if(!m_strsep_b(str,&md->gc[Flags],MDF_ConnectedInd)) break;
+ if(!m_strsep_b(str,&md->gc[Flags],MDF_FullSync)) break;
+ } while(0);
+
+ OR_EXIT(fcfg,write,md,0);
+ OR_EXIT(fcfg,close);
+
+ md_free(md);
+
+ return 0;
+}
+
struct meta_cmd cmds[] = {
- { "create-md", 0, meta_create_md, 1 },
{ "show-gc", 0, meta_show_gc, 1 },
+ { "get-gc", 0, meta_get_gc, 1 },
+ { "create-md", 0, meta_create_md, 1 },
{ "dump-md", 0, meta_dump_md, 1 },
{ "convert-md", "FORMAT [FORMAT ARGS...]", meta_convert_md, 1 },
- { "modify-gc", "ID=VAL ...", meta_modify_gc, 0 }
+ //{ "restore-md", 0, meta_restore_md, 0 },
+ { "set-gc", ":::VAL:VAL:...", meta_set_gc, 0 }
};
void print_usage()
@@ -572,7 +985,5 @@
}
ai++;
- command->function(fcfg, argv+ai, argc-ai);
-
- return 0;
+ return command->function(fcfg, argv+ai, argc-ai);
}
More information about the drbd-cvs
mailing list