[DRBD-cvs] r1726 - in trunk: . drbd drbd/linux user

svn at svn.drbd.org svn at svn.drbd.org
Tue Jan 18 21:57:53 CET 2005


Author: phil
Date: 2005-01-18 21:57:51 +0100 (Tue, 18 Jan 2005)
New Revision: 1726

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_config.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdmeta.c
   trunk/user/drbdsetup.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
* Tested the changed protocol, and fixed some minimal glitches,
  all sizes in the protocol are in sectors now, as they should be.
* The module no longer creates the meta-data by it self, it 
  asks the user to use drbdmeta to do so...
* show-gc and get-gc implemented in drbdsetup. 


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/ROADMAP	2005-01-18 20:57:51 UTC (rev 1726)
@@ -352,7 +352,7 @@
   defined in a resource section.
   0% DONE
 
-13 Introduce a UUID (universally unique identifier) in the
+13 Introduce an UUID (universally unique identifier) in the
   meta data. One purpose is to tag the bitmap with this UUID. 
   If the peer's UUID is different to what we expect we know that 
   we have to do a full sync....

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/drbd_fs.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -96,11 +96,10 @@
  */
 STATIC int do_determin_dev_size(struct Drbd_Conf* mdev)
 {
-#warning "these ._size <<1 shifts have to go"
-	sector_t p_size = mdev->p_size <<1;  // partner's disk size.
+	sector_t p_size = mdev->p_size;   // partner's disk size.
 	sector_t la_size = mdev->la_size; // last agreed size.
 	sector_t m_size; // my size
-	sector_t u_size = mdev->lo_usize <<1; // size requested by user.
+	sector_t u_size = mdev->lo_usize; // size requested by user.
 	sector_t size=0;
 	int rv;
 	char ppb[10];
@@ -384,14 +383,18 @@
 
 	set_bit(MD_IO_ALLOWED,&mdev->flags);
 
-/* FIXME I think inc_local_md_only within drbd_md_read is misplaced.
- * should go here, and the corresponding dec_local, too.
- */
-
 	md_gc_valid = drbd_md_read(mdev);
 
-/* FIXME if (md_gc_valid < 0) META DATA IO NOT POSSIBLE! */
+	if (md_gc_valid == -1 ) {
+		retcode = MDIOError;
+		goto unset_fail_ioctl;
+	}
 
+	if (md_gc_valid == -2 ) {
+		retcode = MDInvalid;
+		goto unset_fail_ioctl;
+	}
+
 	drbd_bm_lock(mdev); // racy...
 	drbd_determin_dev_size(mdev);
 	/* FIXME
@@ -460,6 +463,15 @@
 
 	return 0;
 
+ unset_fail_ioctl:
+	mdev->md_bdev  = 0;
+	mdev->md_file  = 0;
+	mdev->md_index = 0;
+
+	mdev->backing_bdev = 0;
+	mdev->lo_file  = 0;
+	mdev->lo_usize = 0;
+	mdev->on_io_error = 0;
  release_bdev2_fail_ioctl:
 	bd_release(bdev2);
  release_bdev_fail_ioctl:
@@ -910,7 +922,28 @@
 	return 0;
 }
 
+STATIC int drbd_ioctl_get_gen_cnt(struct Drbd_Conf *mdev, 
+				  struct ioctl_get_gen_cnt* arg)
+{
+	struct ioctl_get_gen_cnt cn;
+	int i;
 
+	memset(&cn,0,sizeof(cn));
+
+	for(i=Flags;i<=ArbitraryCnt;i++)
+		cn.gen_cnt[i]=mdev->gen_cnt[i];
+	cn.uuid = mdev->uuid;
+	cn.peer_uuid = mdev->peer_uuid;
+	cn.bits_set = drbd_bm_total_weight(mdev);
+	cn.current_size = drbd_get_capacity(mdev->this_bdev);
+
+	if (copy_to_user(arg,&cn,sizeof(cn)))
+		return -EFAULT;
+
+	return 0;
+}
+
+
 int drbd_ioctl(struct inode *inode, struct file *file,
 			   unsigned int cmd, unsigned long arg)
 {
@@ -1008,7 +1041,7 @@
 			break;
 		}
 		err=0;
-		mdev->lo_usize = (unsigned long)arg;
+		mdev->lo_usize = (sector_t)(u64)arg;
 		drbd_bm_lock(mdev);
 		drbd_determin_dev_size(mdev);
 		drbd_md_write(mdev); // Write mdev->la_size to disk.
@@ -1205,6 +1238,10 @@
 		err = drbd_outdate_ioctl(mdev,(int *) arg);
 		break;
 
+	case DRBD_IOCTL_GET_GEN_CNT:
+		err=drbd_ioctl_get_gen_cnt(mdev,(void *)arg);
+		break;
+
 	default:
 		err = -EINVAL;
 	}

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/drbd_int.h	2005-01-18 20:57:51 UTC (rev 1726)
@@ -241,29 +241,7 @@
 #define RQ_DRBD_DONE      0x0030
 #define RQ_DRBD_IN_TL     0x0040
 
-enum MetaDataFlags {
-	__MDF_Consistent,
-	__MDF_PrimaryInd,
-	__MDF_ConnectedInd,
-	__MDF_FullSync,
-	__MDF_WasUpToDate,
-};
-#define MDF_Consistent      (1<<__MDF_Consistent)
-#define MDF_PrimaryInd      (1<<__MDF_PrimaryInd)
-#define MDF_ConnectedInd    (1<<__MDF_ConnectedInd)
-#define MDF_FullSync        (1<<__MDF_FullSync)
-#define MDF_WasUpToDate     (1<<__MDF_WasUpToDate)
-
 /* drbd_meta-data.c (still in drbd_main.c) */
-enum MetaDataIndex {
-	Flags,          /* Consistency flag,connected-ind,primary-ind */
-	HumanCnt,       /* human-intervention-count */
-	TimeoutCnt,     /* timout-count */
-	ConnectedCnt,   /* connected-count */
-	ArbitraryCnt,   /* arbitrary-count */
-	GEN_CNT_SIZE	// MUST BE LAST! (and Flags must stay first...)
-};
-
 #define DRBD_MD_MAGIC (DRBD_MAGIC+4) // 4th incarnation of the disk layout.
 
 #define DRBD_PANIC 3

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/drbd_main.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -852,8 +852,8 @@
 	have_disk=inc_local(mdev);
 	if(have_disk) {
 		D_ASSERT(mdev->backing_bdev);
-		if (mdev->md_index == -1 ) d_size = drbd_md_ss(mdev)>>1;
-		else d_size = drbd_get_capacity(mdev->backing_bdev)>>1;
+		if (mdev->md_index == -1 ) d_size = drbd_md_ss(mdev);
+		else d_size = drbd_get_capacity(mdev->backing_bdev);
 	} else d_size = 0;
 
 	p.u_size = cpu_to_be64(mdev->lo_usize);
@@ -2125,7 +2125,9 @@
 
 /*
  * return:
- *   < 0 if we had an error (currently never ...)
+ *   < 0 if we had an error 
+ *       -1  no meta data IO allowed
+ *       -2  magic number not present
  *   = 0 if we need a FullSync because either the flag is set,
  *       or the gen counts are invalid
  *   > 0 if we could read valid gen counts,
@@ -2135,7 +2137,7 @@
 {
 	struct meta_data_on_disk * buffer;
 	sector_t sector;
-	int i;
+	int i,rv;
 
 	if(!inc_local_md_only(mdev)) return -1;
 
@@ -2144,12 +2146,16 @@
 
 	sector = drbd_md_ss(mdev) + MD_GC_OFFSET;
 
-/* FIXME different failure cases: IO error or invalid magic */
+	if ( ! drbd_md_sync_page_io(mdev,sector,READ) ) {
+		rv = MDIOError;
+		goto err;
+	}
 
-	ERR_IF( ! drbd_md_sync_page_io(mdev,sector,READ) ) goto err;
+	if(be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) {
+		rv = MDInvalid;
+		goto err;
+	}
 
-	if(be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) goto err;
-
 	for(i=Flags;i<=ArbitraryCnt;i++)
 		mdev->gen_cnt[i]=be32_to_cpu(buffer->gc[i]);
 	mdev->la_size = be64_to_cpu(buffer->la_size);
@@ -2168,23 +2174,7 @@
 	up(&mdev->md_io_mutex);
 	dec_local(mdev);
 
-	INFO("Creating state block\n");
-
-	/* if we need to create a state block, we are
-	 * not consistent, and need a sync of the full device!
-	 * if one knows what he is doing, he can manipulate gcs by hand,
-	 * and avoid the initial full sync...
-	 * otherwise, one of us will have to be forced (--do-what-I-say)
-	 * to be primary, before anything is usable.
-	 */
-	set_bit(MD_DIRTY,&mdev->flags);
-	mdev->gen_cnt[Flags] = MDF_FullSync;
-	for(i = HumanCnt; i < GEN_CNT_SIZE; i++) mdev->gen_cnt[i]=1;
-
-/* FIXME might have IO errors! */
-	drbd_md_write(mdev);
-
-	return 0;
+	return rv;
 }
 
 #if DUMP_MD >= 1

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/drbd_receiver.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -1334,8 +1334,6 @@
 	if (drbd_recv(mdev, h->payload, h->length) != h->length)
 		return FALSE;
 
-	// TODO also take o->c_size into account!
-
 	p_size=be64_to_cpu(p->d_size);
 
 	if(p_size == 0 && mdev->state.s.disk == Diskless ) {
@@ -1368,6 +1366,15 @@
 		}
 	}
 
+	if (mdev->state.s.conn > WFReportParams ) {
+		if( be64_to_cpu(p->c_size) != 
+		    drbd_get_capacity(mdev->this_bdev) ) {
+			// we have different sizes, probabely peer
+			// needs to know my new size...
+			drbd_send_sizes(mdev);
+		}
+	}
+
 	return TRUE;
 }
 
@@ -1417,6 +1424,14 @@
 
 	peer_state.i = be32_to_cpu(p->state);
 
+	if (mdev->state.s.conn > WFReportParams ) {
+		if( nconn > Connected && peer_state.s.conn == Connected) {
+			// we want resync, peer has not yet decided to sync...
+			drbd_send_gen_cnt(mdev);
+			drbd_send_state(mdev);
+		}
+	}
+
 	spin_lock_irq(&mdev->req_lock);
 	ns.i = mdev->state.i;
 	ns.s.conn = nconn;

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/linux/drbd.h	2005-01-18 20:57:51 UTC (rev 1726)
@@ -128,6 +128,8 @@
 	MDMounted,
 	LDMDInvalid,
 	LDDeviceTooLarge,
+	MDIOError,
+	MDInvalid,
 };
 
 struct ioctl_disk_config {
@@ -249,6 +251,37 @@
 	int                   _pad;
 };
 
+enum MetaDataFlags {
+	__MDF_Consistent,
+	__MDF_PrimaryInd,
+	__MDF_ConnectedInd,
+	__MDF_FullSync,
+	__MDF_WasUpToDate,
+};
+#define MDF_Consistent      (1<<__MDF_Consistent)
+#define MDF_PrimaryInd      (1<<__MDF_PrimaryInd)
+#define MDF_ConnectedInd    (1<<__MDF_ConnectedInd)
+#define MDF_FullSync        (1<<__MDF_FullSync)
+#define MDF_WasUpToDate     (1<<__MDF_WasUpToDate)
+
+enum MetaDataIndex {
+	Flags,			/* Consistency flag,connected-ind,primary-ind */
+	HumanCnt,		/* human-intervention-count */
+	TimeoutCnt,		/* timout-count */
+	ConnectedCnt,		/* connected-count */
+	ArbitraryCnt,		/* arbitrary-count */
+	GEN_CNT_SIZE		/* MUST BE LAST! (and Flags must stay first...) */
+};
+
+struct ioctl_get_gen_cnt {
+	OUT __u64        uuid;
+	OUT __u64        peer_uuid;
+	OUT __u64        current_size;
+	OUT __u32        gen_cnt[GEN_CNT_SIZE];	/* generation counter */
+	OUT unsigned int bits_set;
+	int              _pad;
+};
+
 #define DRBD_MAGIC 0x83740267
 #define BE_DRBD_MAGIC __constant_cpu_to_be32(DRBD_MAGIC)
 
@@ -265,12 +298,13 @@
 #define DRBD_IOCTL_INVALIDATE       _IO ( DRBD_IOCTL_LETTER, 0x0D )
 #define DRBD_IOCTL_INVALIDATE_REM   _IO ( DRBD_IOCTL_LETTER, 0x0E )
 #define DRBD_IOCTL_SET_SYNC_CONFIG  _IOW( DRBD_IOCTL_LETTER, 0x0F, struct ioctl_syncer_config )
-#define DRBD_IOCTL_SET_DISK_SIZE    _IOW( DRBD_IOCTL_LETTER, 0x10, unsigned int )
+#define DRBD_IOCTL_SET_DISK_SIZE    _IOW( DRBD_IOCTL_LETTER, 0x10, __u64 )
 #define DRBD_IOCTL_WAIT_CONNECT     _IOR( DRBD_IOCTL_LETTER, 0x11, struct ioctl_wait )
 #define DRBD_IOCTL_WAIT_SYNC        _IOR( DRBD_IOCTL_LETTER, 0x12, struct ioctl_wait )
 #define DRBD_IOCTL_UNCONFIG_DISK    _IO ( DRBD_IOCTL_LETTER, 0x13 )
 #define DRBD_IOCTL_SET_STATE_FLAGS  _IOW( DRBD_IOCTL_LETTER, 0x14, drbd_role_t )
 #define DRBD_IOCTL_OUTDATE_DISK     _IOW( DRBD_IOCTL_LETTER, 0x15, int )
+#define DRBD_IOCTL_GET_GEN_CNT      _IOR( DRBD_IOCTL_LETTER, 0x15, struct ioctl_get_gen_cnt )
 
 
 #endif

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/drbd/linux/drbd_config.h	2005-01-18 20:57:51 UTC (rev 1726)
@@ -24,7 +24,7 @@
 
 #define REL_VERSION "0.8-pre1"
 #define API_VERSION 80
-#define PRO_VERSION 74
+#define PRO_VERSION 80
 
 //#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces
 

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/user/drbdadm_main.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -189,8 +189,8 @@
   { "cstate",            adm_generic_s,         1, 1 },
   { "dump",              adm_dump,              1, 1 },
   { "create-md",         admm_generic,          1, 1 },
-  { "show-gc",           admm_generic,          1, 1 },
-  { "get-gc",            admm_generic,          1, 1 },
+  { "show-gc",           adm_generic_b,         1, 1 },
+  { "get-gc",            adm_generic_b,         1, 1 },
   { "dump-md",           admm_generic,          1, 1 },
   { "set-gc",            admm_generic,          0, 1 },
   { "set-uuid",          admm_generic,          0, 1 },
@@ -616,7 +616,8 @@
   int rv;
 
   rv=adm_generic(res,cmd,SLEEPS_SHORT|SUPRESS_STDERR);
-  if(rv == 17) return rv;
+  if(rv == 17) return rv; 
+  // 17 returned by drbdsetup outdate, if it is already primary.
 
   if( rv ) {
     rv = admm_generic(res,cmd);

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/user/drbdmeta.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -79,28 +79,6 @@
 #define DRBD_MD_MAGIC_07   (DRBD_MAGIC+3)
 #define DRBD_MD_MAGIC_08   (DRBD_MAGIC+4)
 
-enum MetaDataFlags {
-	__MDF_Consistent,
-	__MDF_PrimaryInd,
-	__MDF_ConnectedInd,
-	__MDF_FullSync,
-	__MDF_WasUpToDate,
-};
-#define MDF_Consistent      (1<<__MDF_Consistent)
-#define MDF_PrimaryInd      (1<<__MDF_PrimaryInd)
-#define MDF_ConnectedInd    (1<<__MDF_ConnectedInd)
-#define MDF_FullSync        (1<<__MDF_FullSync)
-#define MDF_WasUpToDate     (1<<__MDF_WasUpToDate)
-
-enum MetaDataIndex {
-	Flags,			/* Consistency flag,connected-ind,primary-ind */
-	HumanCnt,		/* human-intervention-count */
-	TimeoutCnt,		/* timout-count */
-	ConnectedCnt,		/* connected-count */
-	ArbitraryCnt,		/* arbitrary-count */
-	GEN_CNT_SIZE		/* MUST BE LAST! (and Flags must stay first...) */
-};
-
 /*
  * }
  * end of should-be-shared
@@ -644,19 +622,6 @@
 
 #undef FMT
 
-void printf_gc(const struct md_cpu *md)
-{
-	printf("%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
-	       md->gc[Flags] & MDF_Consistent ? 1 : 0,
-	       md->gc[Flags] & MDF_WasUpToDate ? 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);
-}
 
 int get_real_random(void * p, int size)
 {
@@ -1114,7 +1079,7 @@
 
 	if (cfg->ops->open(cfg))
 		return -1;
-	printf_gc(&cfg->md);
+	dt_print_gc(cfg->md.gc);
 	return cfg->ops->close(cfg);
 }
 
@@ -1129,28 +1094,7 @@
 	if (cfg->ops->open(cfg))
 		return -1;
 
-	printf("\n"
-	       "                                              WantFullSync |\n"
-	       "                                        ConnectedInd |     |\n"
-	       "                                     lastState |     |     |\n"
-	       "                            ArbitraryCnt |     |     |     |\n"
-	       "                      ConnectedCnt |     |     |     |     |\n"
-	       "                  TimeoutCnt |     |     |     |     |     |\n"
-	       "              HumanCnt |     |     |     |     |     |     |\n"
-	       "     WasUpToDate |     |     |     |     |     |     |     |\n"
-	       "Consistent |     |     |     |     |     |     |     |     |\n"
-	       "   --------+-----+-----+-----+-----+-----+-----+-----+-----+\n"
-	       "       %3s | %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s  \n"
-	       "\n",
-	       cfg->md.gc[Flags] & MDF_Consistent ? "1/c" : "0/i",
-	       cfg->md.gc[Flags] & MDF_WasUpToDate ? "1/y" : "0/n",
-	       cfg->md.gc[HumanCnt],
-	       cfg->md.gc[TimeoutCnt],
-	       cfg->md.gc[ConnectedCnt],
-	       cfg->md.gc[ArbitraryCnt],
-	       cfg->md.gc[Flags] & MDF_PrimaryInd ? "1/p" : "0/s",
-	       cfg->md.gc[Flags] & MDF_ConnectedInd ? "1/c" : "0/n",
-	       cfg->md.gc[Flags] & MDF_FullSync ? "1/y" : "0/n");
+	dt_pretty_print_gc(cfg->md.gc);
 
 	if (cfg->md.la_sect) {
 		printf("last agreed size: %s\n",
@@ -1383,9 +1327,9 @@
 
 	printf("  consistent:H:T:C:A:p:c:f\n");
 	printf("previously ");
-	printf_gc(&cfg->md);
+	dt_print_gc(cfg->md.gc);
 	printf("GCs set to ");
-	printf_gc(&tmp);
+	dt_print_gc(tmp.gc);
 
 	if (!confirmed("Write new GCs to disk?")) {
 		printf("Operation cancelled.\n");

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/user/drbdsetup.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -114,6 +114,8 @@
 int cmd_detach(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_state(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_cstate(int drbd_fd,char** argv,int argc,struct option *options);
+int cmd_show_gc(int drbd_fd,char** argv,int argc,struct option *options);
+int cmd_get_gc(int drbd_fd,char** argv,int argc,struct option *options);
 
 struct drbd_cmd commands[] = {
   {"primary", cmd_primary,           0,
@@ -175,8 +177,10 @@
   {"outdate", cmd_outdate,           0, 0, },
   {"disconnect", cmd_disconnect,     0, 0, },
   {"state", cmd_state,               0, 0, },
-  {"cstate", cmd_cstate,              0, 0, },
-  {"show", cmd_show,                 0, 0, }
+  {"cstate", cmd_cstate,             0, 0, },
+  {"show-gc", cmd_show_gc,           0, 0, },
+  {"get-gc", cmd_get_gc,             0, 0, },
+  {"show", cmd_show,                 0, 0, },
 };
 
 const char *eh_names[] = {
@@ -413,7 +417,7 @@
 	case 'd':
 	  cn->config.disk_size = m_strtoll_range(optarg,'K', "disk-size",
 			      DRBD_DISK_SIZE_SECT_MIN>>1,
-			      DRBD_DISK_SIZE_SECT_MAX>>1 );
+			      DRBD_DISK_SIZE_SECT_MAX>>1 ) << 1;
 	  break;
 	case 'e':
 	  for(i=0;i<ARRY_SIZE(eh_names);i++) {
@@ -543,6 +547,9 @@
     [LDDeviceTooLarge]="Currently we only support devices up to 3.998TB.\n"
                        "(up to 2TB in case you do not have CONFIG_LBD set)",
                        "Contact office at linbit.com, if you need more.",
+    [MDIOError]="IO error(s) orruced during initial access to meta-data.\n",
+    [MDInvalid]="No valid meta-data signature found.\n"
+                "Use 'drbdadm create-md res' to initialize meta-data area.\n",
   };
 
   if (err_no>ARRY_SIZE(etext) || err_no<0) err_no=0;
@@ -1071,7 +1078,7 @@
 
 int cmd_disk_size(int drbd_fd,char** argv,int argc,struct option *options)
 {
-  unsigned long u_size=0;
+  __u64 u_size=0; // unit: sectors.
   int err;
 
   if(argc > 0)
@@ -1088,7 +1095,7 @@
 	    case 'd':
 	      u_size=m_strtoll_range(optarg,'K', "disk-size",
 			      DRBD_DISK_SIZE_SECT_MIN>>1,
-			      DRBD_DISK_SIZE_SECT_MAX>>1 );
+			      DRBD_DISK_SIZE_SECT_MAX>>1 ) << 1;
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
 	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",cmdname,optarg);
@@ -1323,6 +1330,48 @@
   return 0;
 }
 
+int cmd_get_gc(int drbd_fd,char** argv,int argc,struct option *options)
+{
+  struct ioctl_get_gen_cnt cn;
+  int err;
+
+  err=ioctl(drbd_fd,DRBD_IOCTL_GET_GEN_CNT,&cn);
+  if(err)
+    {
+      PERROR("ioctl(,GET_GEN_CNT,) failed");
+      return 20;
+    }
+  
+  dt_print_gc(cn.gen_cnt);
+
+  return 0;
+}
+
+int cmd_show_gc(int drbd_fd,char** argv,int argc,struct option *options)
+{
+  struct ioctl_get_gen_cnt cn;
+  char ppb[10];
+  int err;
+
+  err=ioctl(drbd_fd,DRBD_IOCTL_GET_GEN_CNT,&cn);
+  if(err)
+    {
+      PERROR("ioctl(,GET_GEN_CNT,) failed");
+      return 20;
+    }
+  
+  dt_pretty_print_gc(cn.gen_cnt);
+
+  printf("current agreed size: %s\n", ppsize(ppb, cn.current_size >> 1));
+  printf("%u bits set in the bitmap [ %s out of sync ]\n",
+	 cn.bits_set, ppsize(ppb, cn.bits_set * 4));
+
+  printf("local  uuid: %llX\n",cn.uuid);
+  printf("peer's uuid: %llX\n",cn.peer_uuid);
+
+  return 0;
+}
+
 int main(int argc, char** argv)
 {
   int drbd_fd,i;

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/user/drbdtool_common.c	2005-01-18 20:57:51 UTC (rev 1726)
@@ -1,6 +1,7 @@
 #define _GNU_SOURCE
 
 #include <sys/types.h>
+#include <asm/types.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
 #include <fcntl.h>
@@ -11,6 +12,7 @@
 #include <getopt.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <linux/drbd.h>
 
 #include "drbdtool_common.h"
 
@@ -276,3 +278,43 @@
 	if (lock_fd >= 0) unlock_fd(lock_fd); /* ignore errors */
 	return err;
 }
+
+void dt_print_gc(const __u32* gen_cnt)
+{
+	printf("%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+	       gen_cnt[Flags] & MDF_Consistent ? 1 : 0,
+	       gen_cnt[Flags] & MDF_WasUpToDate ? 1 : 0,
+	       gen_cnt[HumanCnt],
+	       gen_cnt[TimeoutCnt],
+	       gen_cnt[ConnectedCnt],
+	       gen_cnt[ArbitraryCnt],
+	       gen_cnt[Flags] & MDF_PrimaryInd ? 1 : 0,
+	       gen_cnt[Flags] & MDF_ConnectedInd ? 1 : 0,
+	       gen_cnt[Flags] & MDF_FullSync ? 1 : 0);
+}
+
+void dt_pretty_print_gc(const __u32* gen_cnt)
+{
+	printf("\n"
+	       "                                              WantFullSync |\n"
+	       "                                        ConnectedInd |     |\n"
+	       "                                     lastState |     |     |\n"
+	       "                            ArbitraryCnt |     |     |     |\n"
+	       "                      ConnectedCnt |     |     |     |     |\n"
+	       "                  TimeoutCnt |     |     |     |     |     |\n"
+	       "              HumanCnt |     |     |     |     |     |     |\n"
+	       "     WasUpToDate |     |     |     |     |     |     |     |\n"
+	       "Consistent |     |     |     |     |     |     |     |     |\n"
+	       "   --------+-----+-----+-----+-----+-----+-----+-----+-----+\n"
+	       "       %3s | %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s  \n"
+	       "\n",
+	       gen_cnt[Flags] & MDF_Consistent ? "1/c" : "0/i",
+	       gen_cnt[Flags] & MDF_WasUpToDate ? "1/y" : "0/n",
+	       gen_cnt[HumanCnt],
+	       gen_cnt[TimeoutCnt],
+	       gen_cnt[ConnectedCnt],
+	       gen_cnt[ArbitraryCnt],
+	       gen_cnt[Flags] & MDF_PrimaryInd ? "1/p" : "0/s",
+	       gen_cnt[Flags] & MDF_ConnectedInd ? "1/c" : "0/n",
+	       gen_cnt[Flags] & MDF_FullSync ? "1/y" : "0/n");
+}

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2005-01-17 12:05:27 UTC (rev 1725)
+++ trunk/user/drbdtool_common.h	2005-01-18 20:57:51 UTC (rev 1726)
@@ -1,6 +1,8 @@
 #ifndef DRBDTOOL_COMMON_H
 #define DRBDTOOL_COMMON_H
 
+#include <asm/types.h>
+
 #define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
 
 /*
@@ -14,10 +16,12 @@
 extern int dt_lock_open_drbd(const char* device, int *lock_fd, int open_may_fail);
 extern int dt_close_drbd_unlock(int drbd_fd, int lock_fd);
 extern void dt_release_lockfile(int drbd_fd);
-int dt_minor_of_dev(const char *device);
+extern int dt_minor_of_dev(const char *device);
 extern unsigned long long m_strtoll(const char* s,const char def_unit);
-const char* make_optstring(struct option *options, char startc);
-char* ppsize(char* buf, size_t size);
+extern const char* make_optstring(struct option *options, char startc);
+extern char* ppsize(char* buf, size_t size);
+extern void dt_print_gc(const __u32* gen_cnt);
+extern void dt_pretty_print_gc(const __u32* gen_cnt);
 
 #endif
 



More information about the drbd-cvs mailing list