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

www-data www-data at garcon.linbit.com
Thu Apr 21 23:54:02 CEST 2005


Author: lars
Date: 2005-04-21 23:53:53 +0200 (Thu, 21 Apr 2005)
New Revision: 1785

Modified:
   trunk/drbd/drbd_bitmap.c
   trunk/drbd/drbd_compat_wrappers.h
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/linux/drbd.h
   trunk/user/drbd_endian.h
   trunk/user/drbdmeta.c
   trunk/user/drbdmeta_parser.h
   trunk/user/drbdtool_common.h
Log:
* fix drbd_md_read error return codes
  make it fail if there is no valid meta data block
  (you _have_ to use drbdmeta now)

* move enum MetaDataIndex into user/drbdtool_common.h,
  it is only needed to read/convert v06 and v07 meta data blocks in user space

* remove stale comment blocks

* added 16bit endian conversion (needed for xfs size detection)

* v08 al/bm offsets are signed (we may want to place the meta data block last,
  so it is easier to find when we have variable size meta data.
  al/bm byte offsets are part of the cfg struct now

* drbdmeta can refuse to operate now,
  if it detects existing data on the lower level device.
  see check_for_exiting_data and meta_create_md

* fix order of memset arguments in drbdmeta

* quieten bitmap code in case of out of memory condition

  * cannot allocate bitmap => la_size = 0
    still to do: should probably stay diskless in case it was connected.

  * cannot REallocate bitmap => la_size keeps the same as before.
     still a problem: actual size may now be smaller!
     what now??

  behaviour was tested with an explicit
     nmb = NULL; /* vmalloc(bytes); */,
  so it would fail always, and it turned out to be of size 0.  (single machine
  only).  behaviour NOT tested with connected devices (no test cluster available)

  it still does not fail the ioctl, so it might go unnoticed at first.
  anyways, it is a slight improvement to the existing code.

  but maybe we really want to fix the device setup procedure
  and do the right thing: fail the ioctl.


Modified: trunk/drbd/drbd_bitmap.c
===================================================================
--- trunk/drbd/drbd_bitmap.c	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/drbd_bitmap.c	2005-04-21 21:53:53 UTC (rev 1785)
@@ -235,6 +235,12 @@
 	return 0;
 }
 
+sector_t drbd_bm_capacity(drbd_dev *mdev)
+{
+	ERR_IF(!mdev->bitmap) return 0;
+	return mdev->bitmap->bm_dev_capacity;
+}
+
 /* called on driver unload. TODO: call when a device is destroyed.
  */
 void drbd_bm_cleanup(drbd_dev *mdev)
@@ -270,7 +276,7 @@
 		cleared += hweight_long(b->bm[w]);
 		b->bm[w++]=0;
 	}
-	
+
 	return cleared;
 }
 
@@ -368,6 +374,7 @@
 			bytes = (words+1)*sizeof(long);
 			nbm = vmalloc(bytes);
 			if (!nbm) {
+				ERR("bitmap: failed to vmalloc %lu bytes\n",bytes);
 				err = -ENOMEM;
 				goto out;
 			}
@@ -375,6 +382,7 @@
 		spin_lock_irq(&b->bm_lock);
 		obm = b->bm;
 		// brgs. move several MB within spinlock...
+		// FIXME this should go into userspace!
 		if (obm) {
 			bm_set_surplus(b);
 			D_ASSERT(b->bm[b->bm_words] == DRBD_MAGIC);
@@ -382,8 +390,9 @@
 		}
 		growing = words > b->bm_words;
 		if (growing) { // set all newly allocated bits
-			memset( nbm+b->bm_words, -1,
-				(words - b->bm_words) * sizeof(long) );
+			// start at -1, just to be sure.
+			memset( nbm + (b->bm_words?:1)-1 , 0xff,
+				(words - ((b->bm_words?:1)-1)) * sizeof(long) );
 			b->bm_set  += bits - b->bm_bits;
 		}
 		nbm[words] = DRBD_MAGIC;
@@ -418,7 +427,9 @@
 	unsigned long s;
 	unsigned long flags;
 
-	D_BUG_ON(!(b && b->bm));
+	D_BUG_ON(!b);
+	if (b->bm_bits == 0) return 0;
+	D_BUG_ON(!b->bm);
 	// MUST_BE_LOCKED(); well. yes. but ...
 
 	spin_lock_irqsave(&b->bm_lock,flags);
@@ -431,7 +442,9 @@
 size_t drbd_bm_words(drbd_dev *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	D_BUG_ON(!(b && b->bm));
+	D_BUG_ON(!b);
+	if (b->bm_words == 0) return 0;
+	D_BUG_ON(!b->bm);
 
 	/* FIXME
 	 * actually yes. really. otherwise it could just change its size ...
@@ -453,6 +466,7 @@
 	unsigned long word, bits;
 	size_t n = number;
 
+	if (number == 0) return;
 	D_BUG_ON(!(b && b->bm));
 	D_BUG_ON(offset        >= b->bm_words);
 	D_BUG_ON(offset+number >  b->bm_words);
@@ -492,6 +506,7 @@
 	unsigned long word, bits;
 	size_t n = number;
 
+	if (number == 0) return;
 	D_BUG_ON(!(b && b->bm));
 	D_BUG_ON(offset        >= b->bm_words);
 	D_BUG_ON(offset+number >  b->bm_words);
@@ -529,6 +544,7 @@
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long *bm;
 
+	if (number == 0) return;
 	D_BUG_ON(!(b && b->bm));
 	if ( (offset        >= b->bm_words) ||
 	     (offset+number >  b->bm_words) ||
@@ -555,13 +571,16 @@
 void drbd_bm_set_all(drbd_dev *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	D_BUG_ON(!(b && b->bm));
 
+	D_BUG_ON(!b);
+	if (b->bm_bits == 0) return;
+	D_BUG_ON(!b->bm);
+
 	MUST_BE_LOCKED();
 
 	spin_lock_irq(&b->bm_lock);
 	BM_PARANOIA_CHECK();
-	memset(b->bm,-1,b->bm_words*sizeof(long));
+	memset(b->bm,0xff,b->bm_words*sizeof(long));
 	bm_clear_surplus(b);
 	b->bm_set = b->bm_bits;
 	spin_unlock_irq(&b->bm_lock);
@@ -699,8 +718,11 @@
 void drbd_bm_clear_all(drbd_dev *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	D_BUG_ON(!(b && b->bm));
 
+	D_BUG_ON(!b);
+	if (b->bm_bits == 0) return;
+	D_BUG_ON(!b->bm);
+
 	MUST_BE_LOCKED();						\
 
 	spin_lock_irq(&b->bm_lock);
@@ -713,8 +735,9 @@
 void drbd_bm_reset_find(drbd_dev *mdev)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
-	D_BUG_ON(!(b && b->bm));
 
+	D_BUG_ON(!b);
+
 	MUST_BE_LOCKED();
 
 	spin_lock_irq(&b->bm_lock);
@@ -733,8 +756,12 @@
 {
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long i = -1UL;
-	D_BUG_ON(!(b && b->bm));
 
+
+	D_BUG_ON(!b);
+	if (b->bm_bits == 0) return i;
+	D_BUG_ON(!b->bm);
+
 	spin_lock_irq(&b->bm_lock);
 	BM_PARANOIA_CHECK();
 	if (b->bm_fo < b->bm_bits) {

Modified: trunk/drbd/drbd_compat_wrappers.h
===================================================================
--- trunk/drbd/drbd_compat_wrappers.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/drbd_compat_wrappers.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -28,7 +28,10 @@
 /* Returns the number of 512 byte sectors of the device */
 static inline sector_t drbd_get_capacity(struct block_device *bdev)
 {
-	return bdev ? bdev->bd_inode->i_size >> 9 : 0;
+	loff_t capacity = bdev ? bdev->bd_inode->i_size >> 9 : 0;
+	if ((sector_t)capacity != capacity)
+		printk(KERN_ERR "drbd: overflow in drbd_get_capacity\n");
+	return (sector_t)capacity;
 }
 
 /* sets the number of 512 byte sectors of our virtual device */

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/drbd_fs.c	2005-04-21 21:53:53 UTC (rev 1785)
@@ -71,7 +71,7 @@
 char* ppsize(char* buf, size_t size) 
 {
 	// Needs 9 bytes at max.
-	static char units[] = { 'K','M','G','T' };
+	static char units[] = { 'K','M','G','T','P','E' };
 	int base = 0;
 	while (size >= 10000 ) {
 		size = size >> 10;
@@ -144,16 +144,23 @@
 		int err;
 		err = drbd_bm_resize(mdev,size);
 		if (unlikely(err)) {
-			ERR("BM resizing failed. "
-			    "Size unchanged = %s (%lu sect)\n", 
-			    ppsize(ppb,size>>1),(unsigned long)size);
-		} else {
-			// racy, see comments above.
-			drbd_set_my_capacity(mdev,size);
-			mdev->la_size = size;
-			INFO("size = %s (%lu sect)\n",ppsize(ppb,size>>1),
-			     (unsigned long)size);
+			/* currently there is only one error: ENOMEM! */
+			size = drbd_bm_capacity(mdev)>>1;
+			if (size == 0) {
+				ERR("Could not allocate bitmap! Set device size => 0\n");
+			} else {
+				/* FIXME this is problematic,
+				 * if we in fact are smaller now! */
+				ERR("BM resizing failed. "
+				    "Leaving size unchanged at size = %lu KB\n", 
+				    (unsigned long)size);
+			}
 		}
+		// racy, see comments above.
+		drbd_set_my_capacity(mdev,size<<1);
+		mdev->la_size = size;
+		INFO("size = %s (%lu KB)\n",ppsize(ppb,size),
+		     (unsigned long)size);
 	}
 
 	return rv;
@@ -345,6 +352,8 @@
 	}
 
 	if ((drbd_get_capacity(bdev)>>1) < new_conf.disk_size) {
+		/* FIXME maybe still allow,
+		 * but leave only DRBD_MAX_SECTORS usable */
 		retcode = LDDeviceTooSmall;
 		goto release_bdev2_fail_ioctl;
 	}
@@ -398,15 +407,16 @@
 
 	md_gc_valid = drbd_md_read(mdev);
 
-	if (md_gc_valid == -1 ) {
-		retcode = MDIOError;
+	if (md_gc_valid != NoError) {
+		retcode = md_gc_valid;
 		goto unset_fail_ioctl;
 	}
 
-	if (md_gc_valid == -2 ) {
-		retcode = MDInvalid;
-		goto unset_fail_ioctl;
-	}
+	/* We reach this only if we have a valid meta data block,
+	 * so we no longer create one here, if we don't find one.
+	 * That means that initially, you HAVE to use the drbdmeta
+	 * command to create one in user space.
+	 */
 
 	drbd_bm_lock(mdev); // racy...
 	drbd_determin_dev_size(mdev);
@@ -414,13 +424,13 @@
 	 * what if we now have la_size == 0 ?? eh?
 	 */
 
-	if (md_gc_valid <= 0) {
+	if (drbd_md_test_flag(mdev,MDF_FullSync)) {
 		INFO("Assuming that all blocks are out of sync (aka FullSync)\n");
 		drbd_bm_set_all(mdev);
 		drbd_bm_write(mdev);
 		drbd_md_clear_flag(mdev,MDF_FullSync);
 		drbd_md_write(mdev);
-	} else { // md_gc_valid > 0
+	} else {
 		/* FIXME this still does not propagate io errors! */
 		drbd_bm_read(mdev);
 	}

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/drbd_int.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -556,16 +556,6 @@
 	drbd_work_cb cb;
 };
 
-/*
- * since we eventually don't want to "remap" any bhs, but allways need a
- * private bh, it may as well be part of the struct so we do not need to
- * allocate it separately.  it is only used as a clone, and since we own it, we
- * can abuse certain fields of if for our own needs.  and, since it is part of
- * the struct, we can use b_private for other things than the req, e.g. mdev,
- * since we get the request struct by means of the "container_of()" macro.
- *	-lge
- */
-
 struct drbd_barrier;
 struct drbd_request {
 	struct drbd_work w;
@@ -968,6 +958,7 @@
 extern void drbd_bm_write     (drbd_dev *mdev);
 extern unsigned long drbd_bm_ALe_set_all (drbd_dev *mdev, unsigned long al_enr);
 extern size_t        drbd_bm_words       (drbd_dev *mdev);
+extern sector_t      drbd_bm_capacity    (drbd_dev *mdev);
 extern unsigned long drbd_bm_find_next   (drbd_dev *mdev);
 extern unsigned long drbd_bm_total_weight(drbd_dev *mdev);
 extern int drbd_bm_rs_done(drbd_dev *mdev);
@@ -1485,7 +1476,7 @@
 
 static inline void drbd_suicide(void)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+#ifdef TASK_ZOMBIE
 	set_current_state(TASK_ZOMBIE);
 #else
 	current->exit_state = EXIT_ZOMBIE;

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/drbd_main.c	2005-04-21 21:53:53 UTC (rev 1785)
@@ -1105,7 +1105,16 @@
 	p.sector   = cpu_to_be64(drbd_ee_get_sector(e));
 	p.block_id = e->block_id;
 	p.blksize  = cpu_to_be32(drbd_ee_get_size(e));
+/*
+ * FIXME kernel source <= 2.6.8 don't have atomic_add_return!
+ */
+#if 0
+#warning "YES I KNOW. JUST SO IT COMPILES NOW."
+	atomic_inc(&mdev->packet_seq);
+	p.seq_num = atomic_read(&mdev->packet_seq);
+#else
 	p.seq_num  = cpu_to_be32(atomic_add_return(1,&mdev->packet_seq));
+#endif
 
 	if (!mdev->meta.socket || mdev->state.s.conn < Connected) return FALSE;
 	ok=drbd_send_cmd(mdev,mdev->meta.socket,cmd,(Drbd_Header*)&p,sizeof(p));
@@ -1335,8 +1344,14 @@
 
 		p.sector   = cpu_to_be64(drbd_req_get_sector(req));
 		p.block_id = (unsigned long)req;
+#if 0
+#warning "YES I KNOW. JUST SO IT COMPILES NOW."
+		atomic_inc(&mdev->packet_seq);
+		p.seq_num = atomic_read(&mdev->packet_seq);
+#else
 		p.seq_num  = cpu_to_be32( req->seq_num =
 				     atomic_add_return(1,&mdev->packet_seq) );
+#endif
 
 		dump_packet(mdev,mdev->data.socket,0,(void*)&p, __FILE__, __LINE__);
 		set_bit(UNPLUG_REMOTE,&mdev->flags);
@@ -2289,21 +2304,20 @@
 
 /*
  * return:
- *   < 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,
+ *   = 0 if we could read valid gen counts,
  *       and reading the bitmap and act log does make sense.
+ *  != 0 if we had an error
+ *       MDIOError no meta data IO allowed
+ *       MDIOError IO not possible
+ *       MDInvalid no correct magic present
  */
 int drbd_md_read(drbd_dev *mdev)
 {
 	struct meta_data_on_disk * buffer;
 	sector_t sector;
-	int i,rv;
+	int i,rv = NoError;
 
-	if(!inc_local_md_only(mdev)) return -1;
+	if(!inc_local_md_only(mdev)) return MDIOError;
 
 	down(&mdev->md_io_mutex);
 	buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
@@ -2327,11 +2341,6 @@
 	if (mdev->sync_conf.al_extents < 7)
 		mdev->sync_conf.al_extents = 127;
 
-	up(&mdev->md_io_mutex);
-	dec_local(mdev);
-
-	return !drbd_md_test_flag(mdev,MDF_FullSync);
-
  err:
 	up(&mdev->md_io_mutex);
 	dec_local(mdev);
@@ -2341,7 +2350,6 @@
 
 
 
-
 static void drbd_uuid_move_history(drbd_dev *mdev)
 {
 	int i;

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/drbd/linux/drbd.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -273,16 +273,6 @@
 #define MDF_FullSync        (1<<__MDF_FullSync)
 #define MDF_WasUpToDate     (1<<__MDF_WasUpToDate)
 
-/* MetaDataIndex is scheduled for removal! */
-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...) */
-};
-
 enum UuidIndex {
 	Current,
 	Bitmap,

Modified: trunk/user/drbd_endian.h
===================================================================
--- trunk/user/drbd_endian.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/user/drbd_endian.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -20,8 +20,11 @@
 
 #define u64 uint64_t
 #define u32 uint32_t
+#define s32 int32_t
+#define u16 uint16_t
 #define __u64 uint64_t
 #define __u32 uint32_t
+#define __u16 uint16_t
 
 /* linux/byteorder/swab.h */
 
@@ -34,6 +37,14 @@
  * oh, well...
  */
 
+#define __swab16(x) \
+({ \
+	__u16 __x = (x); \
+	((__u16)( \
+		(((__u16)(__x) & (__u16)0x00ffUL) << 8) | \
+		(((__u16)(__x) & (__u16)0xff00UL) >> 8) )); \
+})
+
 #define __swab32(x) \
 ({ \
 	__u32 __x = (x); \
@@ -74,19 +85,27 @@
 #define le64_to_cpu(x) ((__u64)(x))
 #define cpu_to_le32(x) ((__u32)(x))
 #define le32_to_cpu(x) ((__u32)(x))
+#define cpu_to_le16(x) ((__u16)(x))
+#define le16_to_cpu(x) ((__u16)(x))
 #define cpu_to_be64(x) __swab64((x))
 #define be64_to_cpu(x) __swab64((x))
 #define cpu_to_be32(x) __swab32((x))
 #define be32_to_cpu(x) __swab32((x))
+#define cpu_to_be16(x) __swab16((x))
+#define be16_to_cpu(x) __swab16((x))
 #elif __BYTE_ORDER == __BIG_ENDIAN
 # define cpu_to_le64(x) __swab64((x))
 # define le64_to_cpu(x) __swab64((x))
 # define cpu_to_le32(x) __swab32((x))
 # define le32_to_cpu(x) __swab32((x))
+# define cpu_to_le16(x) __swab16((x))
+# define le16_to_cpu(x) __swab16((x))
 # define cpu_to_be64(x) ((__u64)(x))
 # define be64_to_cpu(x) ((__u64)(x))
 # define cpu_to_be32(x) ((__u32)(x))
 # define be32_to_cpu(x) ((__u32)(x))
+# define cpu_to_be16(x) ((__u16)(x))
+# define be16_to_cpu(x) ((__u16)(x))
 #else
 # error "sorry, weird endianness on this box"
 #endif

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/user/drbdmeta.c	2005-04-21 21:53:53 UTC (rev 1785)
@@ -64,6 +64,46 @@
  */
 
 /*
+ * FIXME
+ *
+ * when configuring a drbd device:
+ *
+ * Require valid drbd meta data at the respective location.  A meta data
+ * block would only be created by the drbdmeta command.
+ *
+ * (How) do we want to implement this: A meta data block contains some
+ * reference to the physical device it belongs. Refuse to attach not
+ * corresponding meta data.
+ *
+ * THINK: put a checksum within the on-disk meta data block, too?
+ *
+ * When asked to create a new meta data block, the drbdmeta command
+ * warns loudly if either the data device or the meta data device seem
+ * to contain some data, and requires explicit confirmation anyways.
+ *
+ * See current implementation in check_for_exiting_data below.
+ *
+ * XXX should also be done for meta-data != internal, i.e.  refuse to
+ * create meta data blocks on a device that seems to be in use for
+ * something else.
+ *
+ * Maybe with an external meta data device, we want to require a "meta
+ * data device super block", which could also serve as TOC to the meta
+ * data, once we have variable size meta data.  Other option could be a
+ * /var/lib/drbd/md-toc plain file, and some magic block on every device
+ * that serves as md storage.
+ *
+ * For certain content on the lower level device, we should refuse
+ * allways.  e.g. refuse to be created on top of a LVM2 physical volume,
+ * or on top of swap space. This would require people to do an dd
+ * if=/dev/zero of=device.  Protects them from shooting themselves,
+ * and blaming us...
+ */
+
+/* reiserfs sb offset is 64k plus */
+#define HOW_MUCH (65*1024)
+
+/*
  * I think this block of declarations and definitions should be
  * in some common.h, too.
  * {
@@ -76,8 +116,8 @@
 #define MD_AL_OFFSET_07    8
 #define MD_AL_MAX_SIZE_07  64
 #define MD_BM_OFFSET_07    (MD_AL_OFFSET_07 + MD_AL_MAX_SIZE_07)
-#define MD_RESERVED_SIZE_07 ( (u64)128 * (1<<20) )
-#define MD_BM_MAX_SIZE_07  ( MD_RESERVED_SIZE_07 - MD_BM_OFFSET_07*512 )
+#define MD_RESERVED_SIZE_07 ( (u64)(128 * (1<<20)) )
+#define MD_BM_MAX_SIZE_07  ( (u64)(MD_RESERVED_SIZE_07 - MD_BM_OFFSET_07*512) )
 
 #define DRBD_MD_MAGIC_06   (DRBD_MAGIC+2)
 #define DRBD_MD_MAGIC_07   (DRBD_MAGIC+3)
@@ -127,6 +167,7 @@
 typedef struct { u64 be; } be_u64;
 typedef struct { u32 le; } le_u32;
 typedef struct { u32 be; } be_u32;
+typedef struct { s32 be; } be_s32;
 typedef struct { unsigned long le; } le_ulong;
 typedef struct { unsigned long be; } be_ulong;
 
@@ -142,9 +183,9 @@
 	 * we use sectors in our general working structure here */
 	u64 la_sect;		/* last agreed size. */
 	u32 md_size;
-	u32 al_offset;		/* offset to this block */
+	s32 al_offset;		/* signed sector offset to this block */
 	u32 al_nr_extents;	/* important for restoring the AL */
-	u32 bm_offset;		/* offset to the bitmap, from here */
+	s32 bm_offset;		/* signed sector offset to the bitmap, from here */
 	/* Since DRBD 0.8 we have uuid instead of gc */
 	u64 uuid[UUID_SIZE];
 	u32 flags;
@@ -168,6 +209,7 @@
 	int i;
 	u32 flags;
 
+	memset(cpu, 0, sizeof(*cpu));
 	for (i = 0; i < GEN_CNT_SIZE; i++)
 		cpu->gc[i] = be32_to_cpu(disk->gc[i].be);
 	cpu->magic = be32_to_cpu(disk->magic.be);
@@ -184,7 +226,7 @@
 	int i;
 	u32 flags;
 
-	/* Commulate the UpToDate flag into the consistent flag. */
+	/* clear Consistent flag if UpToDate is not set*/
 	flags = cpu->gc[Flags];
 	if(!((flags & MDF_Consistent) && (flags & MDF_WasUpToDate))) {
 		flags &= ~MDF_Consistent;
@@ -215,9 +257,9 @@
 	be_u32 gc[GEN_CNT_SIZE];	/* generation counter */
 	be_u32 magic;
 	be_u32 md_size;
-	be_u32 al_offset;	/* offset to this block */
+	be_s32 al_offset;	/* signed sector offset to this block */
 	be_u32 al_nr_extents;	/* important for restoring the AL */
-	be_u32 bm_offset;	/* offset to the bitmap, from here */
+	be_s32 bm_offset;	/* signed sector offset to the bitmap, from here */
 	char reserved[8 * 512 - 48];
 };
 
@@ -225,6 +267,8 @@
 {
 	int i;
 	u32 flags;
+
+	memset(cpu, 0, sizeof(*cpu));
 	cpu->la_sect = be64_to_cpu(disk->la_kb.be) << 1;
 	for (i = 0; i < GEN_CNT_SIZE; i++)
 		cpu->gc[i] = be32_to_cpu(disk->gc[i].be);
@@ -246,7 +290,7 @@
 	int i;
 	u32 flags;
 
-	/* Commulate the UpToDate flag into the consistent flag. */
+	/* clear Consistent flag if UpToDate is not set*/
 	flags = cpu->gc[Flags];
 	if(!((flags & MDF_Consistent) && (flags & MDF_WasUpToDate))) {
 		flags &= ~MDF_Consistent;
@@ -262,7 +306,7 @@
 	disk->al_offset.be = cpu_to_be32(cpu->al_offset);
 	disk->al_nr_extents.be = cpu_to_be32(cpu->al_nr_extents);
 	disk->bm_offset.be = cpu_to_be32(cpu->bm_offset);
-	memset(disk->reserved, sizeof(disk->reserved), 0);
+	memset(disk->reserved, 0, sizeof(disk->reserved));
 }
 
 int v07_validate_md(struct md_cpu *md)
@@ -317,8 +361,6 @@
 
 /*
  * -- DRBD 0.8 --------------------------------------
- *  even though they now differ only by la-size being kb or sectors,
- *  I expect them to diverge, so lets have different structures.
  */
 
 struct __attribute__ ((packed)) md_on_disk_08 {
@@ -327,15 +369,17 @@
 	be_u32 flags;
 	be_u32 magic;
 	be_u32 md_size;
-	be_u32 al_offset;	/* offset to this block */
+	be_s32 al_offset;	/* signed sector offset to this block */
 	be_u32 al_nr_extents;	/* important for restoring the AL */
-	be_u32 bm_offset;	/* offset to the bitmap, from here */
-	char reserved[8 * 512 - 56];
+	be_s32 bm_offset;	/* signed sector offset to the bitmap, from here */
+	char reserved[8 * 512 - (8*(UUID_SIZE+1)+4*6)];
 };
 
 void md_disk_08_to_cpu(struct md_cpu *cpu, const struct md_on_disk_08 *disk)
 {
 	int i;
+
+	memset(cpu, 0, sizeof(*cpu));
 	cpu->la_sect = be64_to_cpu(disk->la_sect.be);
 	for ( i=Current ; i<UUID_SIZE ; i++ )
 		cpu->uuid[i] = be64_to_cpu(disk->uuid[i].be);
@@ -351,15 +395,16 @@
 {
 	int i;
 	disk->la_sect.be = cpu_to_be64(cpu->la_sect);
-	for ( i=Current ; i<UUID_SIZE ; i++ )
+	for ( i=Current ; i<UUID_SIZE ; i++ ) {
 		disk->uuid[i].be = cpu_to_be64(cpu->uuid[i]);
+	}
 	disk->flags.be = cpu_to_be32(cpu->flags);
 	disk->magic.be = cpu_to_be32(cpu->magic);
 	disk->md_size.be = cpu_to_be32(cpu->md_size);
 	disk->al_offset.be = cpu_to_be32(cpu->al_offset);
 	disk->al_nr_extents.be = cpu_to_be32(cpu->al_nr_extents);
 	disk->bm_offset.be = cpu_to_be32(cpu->bm_offset);
-	memset(disk->reserved, sizeof(disk->reserved), 0);
+	memset(disk->reserved, 0, sizeof(disk->reserved));
 }
 
 int v08_validate_md(struct md_cpu *md)
@@ -400,11 +445,13 @@
 	char *drbd_dev_name;
 	int lock_fd;
 	int drbd_fd;
-	int ll_fd;
+	int ll_fd;		/* not yet used here */
 	int md_fd;
 
-	/* byte offset of our "super block", within fd */
+	/* byte offsets of our "super block" and other data, within fd */
 	u64 md_offset;
+	u64 al_offset;
+	u64 bm_offset;
 
 	/* unused in 06 */
 	int md_index;
@@ -429,6 +476,9 @@
 		 * which may be partially unused
 		 * use le_long for now. */
 		le_ulong *bm;
+
+		/* to check for existing data on physical devices */
+		void *ll_data;
 	} on_disk;
 };
 
@@ -572,14 +622,18 @@
 
 int confirmed(const char *text)
 {
-	char answer[16];
-	int rr;
+	const char yes[] = "yes";
+	const ssize_t N = sizeof(yes);
+	char *answer = NULL;
+	size_t n = 0;
+	int ok;
 
-	do {
-		printf("%s [yes/no] ", text);
-		rr = scanf("%15s", answer);
-	} while (rr != 1);
-	return !strcmp(answer, "yes");
+	printf("\n%s\n[need to type '%s' to confirm] ", text, yes);
+	ok = getline(&answer,&n,stdin) == N &&
+	     strncmp(answer,yes,N-1) == 0;
+	if (answer) free(answer);
+	printf("\n");
+	return ok;
 }
 
 unsigned long bm_words(u64 sectors)
@@ -642,7 +696,7 @@
 	u64 offset;
 
 	if (cfg->md_index == -1) {
-		offset = (bdev_size(cfg->md_fd) & ~((1 << 12) - 1))
+		offset = (bdev_size(cfg->md_fd) & ~((1LLU << 12) - 1))
 		    - MD_RESERVED_SIZE_07;
 	} else {
 		offset = MD_RESERVED_SIZE_07 * cfg->md_index;
@@ -654,7 +708,7 @@
 {
 	struct stat sb;
 	unsigned long words;
-	u64 offset, al_offset, bm_offset;
+	u64 offset;
 
 	cfg->md_fd = open(cfg->md_device_name, O_RDWR);
 
@@ -689,23 +743,37 @@
 	}
 	cfg->md_offset = offset;
 
+	/* in case this is internal meta data, mmap first <some>KB of device,
+	 * so we can try and detect existing file systems on the physical
+	 * device, and warn about that.
+	 */
+	if (cfg->md_index == -1) {
+		cfg->on_disk.ll_data =
+		    mmap(NULL, HOW_MUCH, PROT_READ | PROT_WRITE, MAP_SHARED,
+			 cfg->md_fd, 0);
+		if (cfg->on_disk.ll_data == NULL) {
+			PERROR("mmap(ll_data) failed");
+			exit(20);
+		}
+	}
+
 	if (cfg->ops->md_disk_to_cpu(cfg)) {
 		return -1;
 	}
 
-	al_offset = offset + cfg->md.al_offset * 512;
-	bm_offset = offset + cfg->md.bm_offset * 512;
+	cfg->al_offset = offset + cfg->md.al_offset * 512;
+	cfg->bm_offset = offset + cfg->md.bm_offset * 512;
 
 	cfg->on_disk.al =
 	    mmap(NULL, MD_AL_MAX_SIZE_07 * 512, PROT_READ | PROT_WRITE,
-		 MAP_SHARED, cfg->md_fd, al_offset);
+		 MAP_SHARED, cfg->md_fd, cfg->al_offset);
 	if (cfg->on_disk.al == NULL) {
 		PERROR("mmap(al_on_disk) failed");
 		exit(20);
 	}
 
 	cfg->on_disk.bm = mmap(NULL, MD_BM_MAX_SIZE_07, PROT_READ | PROT_WRITE,
-			       MAP_SHARED, cfg->md_fd, bm_offset);
+			       MAP_SHARED, cfg->md_fd, cfg->bm_offset);
 	if (cfg->on_disk.bm == NULL) {
 		PERROR("mmap(bm_on_disk) failed");
 		exit(20);
@@ -845,7 +913,7 @@
 
 	do {
 		for ( i=Current ; i<UUID_SIZE ; i++ ) {
-			if (!m_strsep_u64(str, &md->uuid[i])) goto done;
+			if (!m_strsep_u64(str, &md->uuid[i])) return;
 		}
 		if (!m_strsep_bit(str, &md->flags, MDF_Consistent)) break;
 		if (!m_strsep_bit(str, &md->flags, MDF_WasUpToDate)) break;
@@ -853,7 +921,6 @@
 		if (!m_strsep_bit(str, &md->flags, MDF_ConnectedInd)) break;
 		if (!m_strsep_bit(str, &md->flags, MDF_FullSync)) break;
 	} while (0);
-	done:
 }
 
 
@@ -1043,37 +1110,40 @@
 
 int v07_md_close(struct format *cfg)
 {
+	int err = 0;
+	if (cfg->on_disk.ll_data && munmap(cfg->on_disk.ll_data, HOW_MUCH)) {
+		PERROR("munmap(ll_data) failed");
+		err = -1;
+	}
 	if (munmap(cfg->on_disk.bm, MD_BM_MAX_SIZE_07)) {
 		PERROR("munmap(bm_on_disk) failed");
-		return -1;
+		err = -1;
 	}
 	if (munmap(cfg->on_disk.al, MD_AL_MAX_SIZE_07 * 512)) {
 		PERROR("munmap(al_on_disk) failed");
-		return -1;
+		err = -1;
 	}
 	if (munmap(cfg->on_disk.md7, 8 * 512)) {
 		PERROR("munmap(md_on_disk) failed");
-		return -1;
+		err = -1;
 	}
 	if (fsync(cfg->md_fd) == -1) {
 		PERROR("fsync() failed");
-		return -1;
+		err = -1;
 	}
 	if (ioctl(cfg->md_fd, BLKFLSBUF) == -1) {
 		PERROR("ioctl(,BLKFLSBUF,) failed");
-		return -1;
+		err = -1;
 	}
 	if (close(cfg->md_fd)) {
 		PERROR("close() failed");
-		return -1;
+		err = -1;
 	}
-	return 0;
+	return err;
 }
 
 int v07_md_initialize(struct format *cfg)
 {
-	u64 al_offset, bm_offset;
-
 	cfg->md.la_sect = 0;
 	cfg->md.gc[Flags] = 0;
 	cfg->md.gc[HumanCnt] = 1;	/* THINK 0? 1? */
@@ -1090,12 +1160,12 @@
 	cfg->md.al_nr_extents = 257;	/* arbitrary. */
 	cfg->md.bm_offset = MD_BM_OFFSET_07;
 
-	al_offset = cfg->md_offset + cfg->md.al_offset * 512;
-	bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
+	cfg->al_offset = cfg->md_offset + cfg->md.al_offset * 512;
+	cfg->bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
 	if (cfg->on_disk.al == NULL) {
 		cfg->on_disk.al =
 		    mmap(NULL, MD_AL_MAX_SIZE_07 * 512, PROT_READ | PROT_WRITE,
-			 MAP_SHARED, cfg->md_fd, al_offset);
+			 MAP_SHARED, cfg->md_fd, cfg->al_offset);
 		if (cfg->on_disk.al == NULL) {
 			PERROR("mmap(al_on_disk) failed");
 			exit(20);
@@ -1105,15 +1175,15 @@
 	if (cfg->on_disk.bm == NULL) {
 		cfg->on_disk.bm =
 		    mmap(NULL, MD_BM_MAX_SIZE_07, PROT_READ | PROT_WRITE,
-			 MAP_SHARED, cfg->md_fd, bm_offset);
+			 MAP_SHARED, cfg->md_fd, cfg->bm_offset);
 		if (cfg->on_disk.bm == NULL) {
 			PERROR("mmap(bm_on_disk) failed");
 			exit(20);
 		}
 	}
 
-	memset(cfg->on_disk.al, MD_AL_MAX_SIZE_07, 0);
-	memset(cfg->on_disk.bm, MD_BM_MAX_SIZE_07, 0xff);
+	memset(cfg->on_disk.al, 0x00, MD_AL_MAX_SIZE_07);
+	memset(cfg->on_disk.bm, 0xff, MD_BM_MAX_SIZE_07);
 	return 0;
 }
 
@@ -1140,6 +1210,7 @@
 		return -1;
 	}
 	md_cpu_to_disk_08(cfg->on_disk.md8, &cfg->md);
+	fprintf(stderr,"msync\n");
 	err = msync(cfg->on_disk.md8, sizeof(*cfg->on_disk.md8),
 		    MS_SYNC | MS_INVALIDATE);
 	if (err) {
@@ -1156,7 +1227,6 @@
 
 int v08_md_initialize(struct format *cfg)
 {
-	u64 al_offset, bm_offset;
 	int i;
 
 	cfg->md.la_sect = 0;
@@ -1177,12 +1247,12 @@
 	cfg->md.al_nr_extents = 257;	/* arbitrary. */
 	cfg->md.bm_offset = MD_BM_OFFSET_07;
 
-	al_offset = cfg->md_offset + cfg->md.al_offset * 512;
-	bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
+	cfg->al_offset = cfg->md_offset + cfg->md.al_offset * 512;
+	cfg->bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
 	if (cfg->on_disk.al == NULL) {
 		cfg->on_disk.al =
 		    mmap(NULL, MD_AL_MAX_SIZE_07 * 512, PROT_READ | PROT_WRITE,
-			 MAP_SHARED, cfg->md_fd, al_offset);
+			 MAP_SHARED, cfg->md_fd, cfg->al_offset);
 		if (cfg->on_disk.al == NULL) {
 			PERROR("mmap(al_on_disk) failed");
 			exit(20);
@@ -1192,7 +1262,7 @@
 	if (cfg->on_disk.bm == NULL) {
 		cfg->on_disk.bm =
 		    mmap(NULL, MD_BM_MAX_SIZE_07, PROT_READ | PROT_WRITE,
-			 MAP_SHARED, cfg->md_fd, bm_offset);
+			 MAP_SHARED, cfg->md_fd, cfg->bm_offset);
 		if (cfg->on_disk.bm == NULL) {
 			PERROR("mmap(bm_on_disk) failed");
 			exit(20);
@@ -1200,8 +1270,10 @@
 	}
 
 	/* do you want to initilize al to something more usefull? */
-	memset(cfg->on_disk.al, MD_AL_MAX_SIZE_07, 0);
-	memset(cfg->on_disk.bm, MD_BM_MAX_SIZE_07, 0xff);
+	//fprintf(stderr,"memset al\n");
+	memset(cfg->on_disk.al, 0x00, MD_AL_MAX_SIZE_07);
+	//fprintf(stderr,"memset bm\n");
+	memset(cfg->on_disk.bm, 0xff, MD_BM_MAX_SIZE_07);
 	return 0;
 }
 
@@ -1437,6 +1509,207 @@
 	return 0;
 }
 
+int md_convert_08_to_07(struct format *cfg)
+{
+	/* Note that al and bm are not touched!
+	 * (they are currently not even mmaped)
+	 *
+	 * KB <-> sectors is done in the md disk<->cpu functions.
+	 * We only need to adjust the magic here. */
+	printf("Converting meta data...\n");
+	cfg->md.magic = DRBD_MD_MAGIC_07;
+	// somehow generate GCs in a sane way
+	if (cfg->ops->md_cpu_to_disk(cfg)
+	    || cfg->ops->close(cfg)) {
+		fprintf(stderr, "conversion failed\n");
+		return -1;
+	}
+	printf("Conversion Currently BROKEN!\n");
+	//printf("Successfully converted v08 meta data to v07 format.\n");
+	return 0;
+}
+
+/* if on the physical device we find some data we can interpret,
+ * print some informational message about what we found,
+ * and what we think how much room it needs.
+ *
+ * look into /usr/share/misc/magic for inspiration
+ * also consider e.g. xfsprogs/libdisk/fstype.c,
+ * and of course the linux kernel headers...
+ */
+struct fstype_s {
+	const char * type;
+	unsigned long long bnum, bsize;
+};
+
+int may_be_extX(char *data, struct fstype_s *f)
+{
+	unsigned int size;
+	if (le16_to_cpu(*(u16*)(data+0x438)) == 0xEF53) {
+		if ( (le32_to_cpu(*(data+0x45c)) & 4) == 4 )
+			f->type = "ext3 filesystem";
+		else
+			f->type = "ext2 filesystem";
+		f->bnum  = le32_to_cpu(*(u32*)(data+0x404));
+		size     = le32_to_cpu(*(u32*)(data+0x418));
+		f->bsize = size == 0 ? 1024 :
+			size == 1 ? 2048 :
+			size == 2 ? 4096 :
+			4096; /* DEFAULT */
+		return 1;
+	}
+	return 0;
+}
+
+int may_be_xfs(char *data, struct fstype_s *f)
+{
+	if (be32_to_cpu(*(u32*)(data+0)) == 0x58465342) {
+		f->type = "xfs filesystem";
+		f->bsize = be32_to_cpu(*(u32*)(data+4));
+		f->bnum  = be64_to_cpu(*(u64*)(data+8));
+		return 1;
+	}
+	return 0;
+}
+
+int may_be_reiserfs(char *data, struct fstype_s *f)
+{
+	if (strncmp("ReIsErFs",data+0x10034,8) == 0 ||
+	    strncmp("ReIsEr2Fs",data+0x10034,9) == 0) {
+		f->type = "reiser filesystem";
+		f->bnum  = le32_to_cpu(*(u32*)(data+0x10000));
+		f->bsize = le16_to_cpu(*(u16*)(data+0x1002c));
+		return 1;
+	}
+	return 0;
+}
+
+int may_be_jfs(char *data, struct fstype_s *f)
+{
+	if (strncmp("JFS1",data+0x8000,4) == 0) {
+		f->type = "JFS filesystem";
+		f->bnum = le64_to_cpu(*(u64*)(data+0x8008));
+		f->bsize = le32_to_cpu(*(u32*)(data+0x8018));
+		return 1;
+	}
+	return 0;
+}
+
+/* really large block size,
+ * will always refuse */
+#define REFUSE_BSIZE 0xFFFFffffFFFF0000LLU
+#define REFUSE_IT    f->bnum = 1; f->bsize = REFUSE_BSIZE;
+int may_be_swap(char *data, struct fstype_s *f)
+{
+	int looks_like_swap =
+		strncmp(data+(1<<12)-10, "SWAP-SPACE", 10) == 0 ||
+		strncmp(data+(1<<12)-10, "SWAPSPACE2", 10) == 0 ||
+		strncmp(data+(1<<13)-10, "SWAP-SPACE", 10) == 0 ||
+		strncmp(data+(1<<13)-10, "SWAPSPACE2", 10) == 0;
+	if (looks_like_swap) {
+		f->type = "swap space signature";
+		REFUSE_IT
+		return 1;
+	}
+	return 0;
+}
+
+int may_be_LVM(char *data, struct fstype_s *f)
+{
+	if (strncmp("LVM2",data+0x218,4) == 0) {
+		f->type = "LVM2 physical volume signature";
+		REFUSE_IT
+		return 1;
+	}
+	return 0;
+}
+
+void check_for_exiting_data(struct format *cfg)
+{
+	char *data = cfg->on_disk.ll_data;
+	struct fstype_s f;
+	int i;
+	if (data == NULL)
+		return;
+
+	for (i = 0; i < HOW_MUCH/sizeof(long); i++) {
+		if (((long*)(data))[i] != 0LU) break;
+	}
+	/* all zeros? no message */
+	if (i == HOW_MUCH/sizeof(long)) return;
+
+	f.type = "some data";
+	f.bnum = 0;
+	f.bsize = 0;
+
+/* FIXME add more detection magic
+ */
+
+	may_be_swap     (data,&f) ||
+	may_be_LVM      (data,&f) ||
+
+	may_be_extX     (data,&f) ||
+	may_be_xfs      (data,&f) ||
+	may_be_jfs      (data,&f) ||
+	may_be_reiserfs (data,&f);
+
+	printf("\nFound %s ", f.type);
+	if (f.bnum) {
+		/* FIXME overflow check missing!
+		 * relevant for ln2(bsize) + ln2(bnum) >= 64, thus only for
+		 * device sizes of more than several exa byte.
+		 * seems irrelevant to me for now.
+		 */
+		u64 fs_kB = ((f.bsize * f.bnum) + (1<<10)-1) >> 10;
+		u64 max_usable_kB;
+
+		if (f.bsize == REFUSE_BSIZE) {
+			printf(
+"\nDevice size would be truncated, which\n"
+"would corrupt data and result in\n"
+"'access beyond end of device' errors.\n"
+"If you want me to do this, you need to zero out the first part\n"
+"of the device (destroy the content).\n"
+"You should be very sure that you mean it.\n"
+"Operation refused.\n\n");
+			exit(40); /* FIXME sane exit code! */
+		}
+
+#if 0
+#define min(x,y) ((x) < (y) ? (x) : (y))
+		max_usable_kB =
+			min( cfg->md_offset,
+			min( cfg->al_offset,
+			     cfg->bm_offset )) >> 10;
+#undef min
+
+		printf("md_offset %llu\n", cfg->md_offset);
+		printf("al_offset %llu\n", cfg->al_offset);
+		printf("bm_offset %llu\n", cfg->bm_offset);
+#else
+		/* for now (we still have no flexible size meta data) */
+		max_usable_kB = cfg->md_offset >> 10;
+#endif
+
+		/* looks like file system data */
+		printf("which uses %llu kB\n", fs_kB);
+		printf("current configuration leaves usable %llu kB\n", max_usable_kB);
+		if (fs_kB > max_usable_kB) {
+			printf(
+"\nDevice size would be truncated, which\n"
+"would corrupt data and result in\n"
+"'access beyond end of device' errors.\n"
+"You need to either\n"
+"   * use external meta data (recommended)\n"
+"   * shrink that filesystem first\n"
+"   * zero out the device (destroy the filesystem)\n"
+"Operation refused.\n\n");
+			exit(40); /* FIXME sane exit code! */
+		}
+	}
+}
+
+
 /* FIXME create v07 replaces a valid v08 block without confirmation!
  * we need better format auto-detection */
 int meta_create_md(struct format *cfg, char **argv, int argc)
@@ -1454,23 +1727,44 @@
 		 */
 		virgin = v07_md_disk_to_cpu(cfg);
 		if (!virgin) {
-			if (confirmed("Valid v07 meta-data found, convert?"))
+			if (confirmed("Valid v07 meta-data found, convert to v08?"))
 				return md_convert_07_to_08(cfg);
 		}
 	}
+	if (virgin && cfg->ops == f_ops + Drbd_07) {
+		/* don't just overwrite existing v08 with v07
+		 */
+		virgin = v08_md_disk_to_cpu(cfg);
+		if (!virgin) {
+			if (confirmed("Valid v08 meta-data found, convert back to v07?"))
+				return md_convert_08_to_07(cfg);
+		}
+	}
+
 	if (!virgin) {
-		if (!confirmed("Valid meta-data already in place, create new?")) {
+		if (!confirmed("Valid meta-data already in place, recreate new?")) {
 			printf("Operation cancelled.\n");
 			exit(0);
 		}
+	} else {
+		printf("About to create a new drbd meta data block\non %s.\n",
+				cfg->md_device_name);
+		check_for_exiting_data(cfg);
+
+		if (!confirmed(" ==> This might destroy existing data! <==\n\n"
+				"Do you want to proceed?")) {
+			printf("Operation cancelled.\n");
+			exit(0);
+		}
 	}
 
 	printf("Creating meta data...\n");
+	memset(&cfg->md, 0, sizeof(cfg->md));
 	err = cfg->ops->md_initialize(cfg)
 	    || cfg->ops->md_cpu_to_disk(cfg)
 	    || cfg->ops->close(cfg);
 	if (err)
-		fprintf(stderr, "conversion failed\n");
+		fprintf(stderr, "operation failed\n");
 
 	return err;
 }
@@ -1577,7 +1871,7 @@
 #endif
 
 char *progname = NULL;
-void print_usage()
+void print_usage_and_exit()
 {
 	char **args;
 	int i;
@@ -1640,13 +1934,13 @@
 
 	pr = fopen("/proc/drbd","r");
 	if(!pr) return rv;
-	
+
 	while(fgets(line,120,pr)) {
 		if(sscanf(line,"%2d: %s",&m,tok)) {
 			if( m == minor ) {
 				rv = strcmp(tok,"Unconfigured");
 				break;
-			}			
+			}
 		}
 	}
 	fclose(pr);
@@ -1660,6 +1954,21 @@
 	struct format *cfg;
 	int i, ai;
 
+#if 1
+	if (sizeof(struct md_on_disk_07) != 4096) {
+		fprintf(stderr, "Where did you get this broken build!?\n"
+			        "sizeof(md_on_disk_07) == %u, should be 4096\n",
+				sizeof(struct md_on_disk_07));
+		exit(111);
+	}
+	if (sizeof(struct md_on_disk_08) != 4096) {
+		fprintf(stderr, "Where did you get this broken build!?\n"
+			        "sizeof(md_on_disk_08) == %u, should be 4096\n",
+				sizeof(struct md_on_disk_08));
+		exit(111);
+	}
+#endif
+
 	if ((progname = strrchr(argv[0], '/'))) {
 		argv[0] = ++progname;
 	} else {
@@ -1667,21 +1976,13 @@
 	}
 
 	if (argc < 4)
-		print_usage();
+		print_usage_and_exit();
 
 	/* FIXME should have a "drbd_cfg_new" and a "drbd_cfg_free"
 	 * function, maybe even a "get" and "put" ?
 	 */
 	cfg = calloc(1, sizeof(struct format));
 	cfg->drbd_dev_name = argv[1];
-	cfg->drbd_fd = dt_lock_open_drbd(cfg->drbd_dev_name, &cfg->lock_fd, 1);
-	if (cfg->drbd_fd > -1) {
-		if (is_configured(dt_minor_of_dev(cfg->drbd_dev_name))) {
-			fprintf(stderr, "Device '%s' is configured!\n",
-				cfg->drbd_dev_name);
-			exit(20);
-		}
-	}
 
 	/* argv[0] is progname, argv[1] was drbd_dev_name. */
 	ai = 2;
@@ -1695,6 +1996,16 @@
 		exit(20);
 	}
 
+	cfg->drbd_fd = dt_lock_open_drbd(cfg->drbd_dev_name, &cfg->lock_fd, 1);
+	if (cfg->drbd_fd > -1) {
+		if (is_configured(dt_minor_of_dev(cfg->drbd_dev_name))) {
+			fprintf(stderr, "Device '%s' is configured!\n",
+				cfg->drbd_dev_name);
+			exit(20);
+		}
+	}
+
+
 	for (i = 0; i < ARRY_SIZE(cmds); i++) {
 		if (!strcmp(cmds[i].name, argv[ai])) {
 			command = cmds + i;

Modified: trunk/user/drbdmeta_parser.h
===================================================================
--- trunk/user/drbdmeta_parser.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/user/drbdmeta_parser.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -5,6 +5,7 @@
 
 #define YYSTYPE_IS_DECLARED 1
 #define YYSTYPE_IS_TRIVIAL 1
+#define YY_NO_UNPUT 1
 
 extern YYSTYPE yylval;
 
@@ -19,3 +20,5 @@
 	TK_LA_SIZE
 };
 
+/* avoid compiler warnings about implicit declaration */
+int yylex(void);

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2005-04-21 15:46:52 UTC (rev 1784)
+++ trunk/user/drbdtool_common.h	2005-04-21 21:53:53 UTC (rev 1785)
@@ -5,6 +5,17 @@
 
 #define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
 
+
+/* MetaDataIndex for v06 / v07 style meta data blocks */
+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 PERROR(fmt, args...) \
 do { fprintf(stderr,fmt ": " , ##args); perror(0); } while (0)



More information about the drbd-cvs mailing list