[DRBD-cvs] svn commit by phil - r2011 - in trunk: drbd drbd/linux user - This fine patch makes **online attach** work !! Done al

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Sun Nov 27 22:47:04 CET 2005


Author: phil
Date: 2005-11-27 22:47:02 +0100 (Sun, 27 Nov 2005)
New Revision: 2011

Modified:
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd_config.h
   trunk/user/drbdmeta.c
Log:
This fine patch makes **online attach** work !!

Done already a bit of testing, looks good so far.
Since this change was rather intrusive, might broke 
something.


Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_actlog.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -713,7 +713,7 @@
 	unsigned long sbnr,ebnr,lbnr,bnr;
 	sector_t esector, nr_sectors;
 
-	if (size <= 0 || (size & 0x1ff) != 0 || size > PAGE_SIZE) {
+	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
 		ERR("sector: %lu, size: %d\n",(unsigned long)sector,size);
 		return;
 	}

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_fs.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -265,7 +265,7 @@
 STATIC
 int drbd_ioctl_set_disk(drbd_dev *mdev, struct ioctl_disk_config * arg)
 {
-	int i, md_gc_valid, minor;
+	int minor;
 	enum ret_codes retcode;
 	struct disk_config new_conf;  // local copy of ioctl() args.
 	struct drbd_backing_dev* nbc; // new_backing_conf
@@ -344,8 +344,6 @@
 	}
 
 	if ((drbd_get_capacity(nbc->backing_bdev)>>1) < new_conf.disk_size) {
-		/* FIXME maybe still allow,
-		 * but leave only DRBD_MAX_SECTORS usable */
 		retcode = LDDeviceTooSmall;
 		goto release_bdev2_fail_ioctl;
 	}
@@ -379,6 +377,13 @@
 #endif
 // -- up to here
 
+	// Make sure the new disk is big enough
+	if (drbd_get_capacity(nbc->backing_bdev) < 
+	    drbd_get_capacity(mdev->this_bdev) ) {
+		retcode = LDDeviceTooSmall;
+		goto release_bdev2_fail_ioctl;
+	}
+
 	if(drbd_request_state(mdev,NS(disk,Attaching)) <= 0 ) {
 		retcode = StateNotAllowed;
 		goto release_bdev2_fail_ioctl;
@@ -389,9 +394,8 @@
 	nbc->on_io_error = new_conf.on_io_error;
 	drbd_md_set_sector_offsets(mdev,nbc);
 
-	md_gc_valid = drbd_md_read(mdev,nbc);
-	if ( md_gc_valid != NoError ) {
-		retcode = md_gc_valid;
+	retcode = drbd_md_read(mdev,nbc);
+	if ( retcode != NoError ) {
 		goto release_bdev3_fail_ioctl;
 	}
 
@@ -422,10 +426,6 @@
 
 	drbd_bm_lock(mdev); // racy...
 	drbd_determin_dev_size(mdev);
-	/* FIXME
-	 * what if we now have la_size == 0 ?? eh?
-	 * BOOM?
-	 */
 
 	if (drbd_md_test_flag(mdev,MDF_FullSync)) {
 		INFO("Assuming that all blocks are out of sync (aka FullSync)\n");
@@ -438,51 +438,45 @@
 		drbd_bm_read(mdev);
 	}
 
-	i = drbd_check_al_size(mdev);
-	if (i) {
-// FATAL!
-		/* FIXME see the comment above.
-		 * if this fails I need to undo all changes,
-		 * go back into Unconfigured,
-		 * and fail the ioctl with ENOMEM...
-		 */
-		// return i;
-		drbd_panic("Cannot allocate act_log\n");
-		drbd_suicide();
+	drbd_al_read_log(mdev);
+	if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
+		drbd_al_apply_to_bm(mdev);
+		drbd_al_to_on_disk_bm(mdev);
 	}
-
-	if (md_gc_valid > 0) {
-		drbd_al_read_log(mdev);
-		if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
-			drbd_al_apply_to_bm(mdev);
-			drbd_al_to_on_disk_bm(mdev);
-		}
-	} /* else {
+	/* else {
 	     FIXME wipe out on disk al!
 	} */
 
-	/* If MDF_Consistent is not set go into inconsistent state, otherwise
-	   investige MDF_WasUpToDate...
-	   If MDF_WasUpToDate is not set go into Outdated disk state, otherwise
-	   into Consistent state.
-	*/
-	if(drbd_md_test_flag(mdev,MDF_Consistent)) {
-		if(drbd_md_test_flag(mdev,MDF_WasUpToDate)) {
-			nds = Consistent;
+
+	if(mdev->state.conn == Connected) {
+		drbd_send_sizes(mdev);  // to start sync...
+		drbd_send_uuids(mdev);
+		drbd_send_state(mdev);
+		drbd_thread_start(&mdev->worker);
+	} else {
+		/* If MDF_Consistent is not set go into inconsistent state, 
+		   otherwise investige MDF_WasUpToDate...
+		   If MDF_WasUpToDate is not set go into Outdated disk state, 
+		   otherwise into Consistent state.
+		*/
+		if(drbd_md_test_flag(mdev,MDF_Consistent)) {
+			if(drbd_md_test_flag(mdev,MDF_WasUpToDate)) {
+				nds = Consistent;
+			} else {
+				nds = Outdated;
+			}
 		} else {
-			nds = Outdated;
+			nds = Inconsistent;
 		}
-	} else {
-		nds = Inconsistent;
+		
+		if(drbd_request_state(mdev,NS(disk,nds)) > 0) {
+			drbd_thread_start(&mdev->worker);
+		}
 	}
 
-	if(drbd_request_state(mdev,NS(disk,nds)) > 0) {
-		drbd_thread_start(&mdev->worker);
-	}
-
 	drbd_bm_unlock(mdev);
-
 	return 0;
+
  release_bdev3_fail_ioctl:
 	drbd_force_state(mdev,NS(disk,Diskless));
  release_bdev2_fail_ioctl:
@@ -984,15 +978,11 @@
 		return -EINTR;
 	}
 
+	drbd_free_bc(mdev->bc);
+	mdev->bc=0;
+
 	after_state_ch(mdev, os, ns);
 
-/* FIXME
-* if you detach while connected, you are *at least* inconsistent now,
-* and should clear MDF_Consistent in metadata, and maybe even set the bitmap
-* out of sync.
-* since if you reattach, this might be a different lo dev, and then it needs
-* to receive a sync!
-*/
 	return 0;
 }
 

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_main.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -720,7 +720,7 @@
 	}
 
 	/* it feels better to have the module_put last ... */
-	if ( (os.disk > Diskless || ns.conn > StandAlone) &&
+	if ( (os.disk > Diskless || os.conn > StandAlone) &&
 	     ns.disk == Diskless && ns.conn == StandAlone ) {
 		drbd_mdev_cleanup(mdev);
 		module_put(THIS_MODULE);
@@ -745,13 +745,23 @@
 	/* Here we have the actions that are performed after a
 	   state change. This function might sleep */
 
-	/*  Added disk, tell peer.  */
-	if ( os.disk == Diskless && ns.disk >= Inconsistent &&
-	     ns.conn >= Connected ) {
-		drbd_send_sizes(mdev);
-		drbd_send_state(mdev);
+	if (os.conn != WFBitMapS && ns.conn == WFBitMapS) {
+		wait_event(mdev->cstate_wait,!atomic_read(&mdev->ap_bio_cnt));
+		drbd_bm_lock(mdev);   // {
+		drbd_send_bitmap(mdev);
+		drbd_bm_unlock(mdev); // }
 	}
 
+	/*  Lost contact to peer's copy of the data  */
+	if (ns.role == Primary &&
+	    os.pdsk > DUnknown && ns.pdsk <= DUnknown ) {
+		/* Only do it if we have not yet done it... */
+		if ( mdev->bc->md.uuid[Bitmap] == 0 ) {
+			INFO("Creating new current UUID\n");
+			drbd_uuid_new_current(mdev);
+		}
+	}
+
 	/*  Removed disk, tell peer.  */
 	if ( os.disk >= Inconsistent && ns.disk == Diskless &&
 	     ns.conn >= Connected ) {
@@ -769,8 +779,6 @@
 	        ns.aftr_isp == 0 && ns.user_isp == 0   ) {
 		drbd_send_short_cmd(mdev,ResumeResync);
 	}
-
-
 }
 
 
@@ -1056,7 +1064,7 @@
 	sector_t d_size;
 	int ok;
 
-	if(inc_local(mdev)) {
+	if(inc_md_only(mdev,Attaching)) {
 		D_ASSERT(mdev->bc->backing_bdev);
 		d_size = drbd_get_max_capacity(mdev);
 		p.u_size = cpu_to_be64(mdev->bc->u_size);
@@ -1147,6 +1155,7 @@
 int drbd_send_bitmap(drbd_dev *mdev)
 {
 	int ok;
+
 	down(&mdev->data.mutex);
 	ok=_drbd_send_bitmap(mdev);
 	up(&mdev->data.mutex);

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_receiver.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -1680,11 +1680,6 @@
 	if (hg > 0) { // become sync source.
 		D_ASSERT(drbd_md_test_flag(mdev,MDF_Consistent));
 		rv = WFBitMapS;
-		wait_event(mdev->cstate_wait,
-			   atomic_read(&mdev->ap_bio_cnt)==0);
-		drbd_bm_lock(mdev);   // {
-		drbd_send_bitmap(mdev);
-		drbd_bm_unlock(mdev); // }
 	} else if (hg < 0) { // become sync target
 		drbd_md_clear_flag(mdev,MDF_Consistent);
 		drbd_uuid_set(mdev,Current,mdev->p_uuid[Bitmap]);
@@ -1905,7 +1900,7 @@
 {
 	Drbd_State_Packet *p = (Drbd_State_Packet*)h;
 	drbd_conns_t nconn;
-	drbd_state_t ns,peer_state;
+	drbd_state_t os,ns,peer_state;
 	int rv;
 
 	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
@@ -1928,17 +1923,24 @@
 			// we want resync, peer has not yet decided to sync...
 			drbd_send_uuids(mdev);
 			drbd_send_state(mdev);
+		} else if ( peer_state.disk == Attaching ) {
+			// Peer should promote from Attaching to UpToDate.
+			drbd_send_state(mdev);
+			peer_state.disk = UpToDate;
 		}
 	}
 
 	spin_lock_irq(&mdev->req_lock);
+	os = mdev->state;
 	ns.i = mdev->state.i;
 	ns.conn = nconn;
 	ns.peer = peer_state.role;
 	ns.pdsk = peer_state.disk;
 	ns.peer_isp = ( peer_state.aftr_isp | peer_state.user_isp );
+	if(nconn == Connected && ns.disk == Attaching) ns.disk = UpToDate;
 	rv = _drbd_set_state(mdev,ns,ChgStateVerbose);
 	spin_unlock_irq(&mdev->req_lock);
+	after_state_ch(mdev,os,ns);
 
 	if(rv <= 0) {
 		drbd_force_state(mdev,NS(conn,StandAlone));
@@ -2025,12 +2027,6 @@
 	/* no, actually we can't. failures happen asynchronously, anytime.
 	 * we can never be sure. disk may have failed while we where busy shaking hands...
 	 */
-/*
- *  FIXME this should only be D_ASSERT here.
- *        *doing* it here masks a logic bug elsewhere, I think.
- */
-	D_ASSERT(mdev->state.disk >= Inconsistent);
-	D_ASSERT(mdev->state.pdsk >= Inconsistent);
 
 	ok=TRUE;
  out:
@@ -2172,12 +2168,10 @@
 {
 	int r;
 
-	drbd_uuid_new_current(mdev);
-	drbd_md_write(mdev);
-
 	r = drbd_request_state(mdev,NS2(pdsk,Outdated,conn,TearDown));
 	WARN("r=%d\n",r);
 	D_ASSERT(r >= 0);
+	drbd_md_write(mdev); // because drbd_request_state created a new UUID.
 
 	return TRUE;
 }
@@ -2379,16 +2373,6 @@
 	}
 
 	if ( mdev->state.role == Primary ) {
-		if ( mdev->state.pdsk >= DUnknown &&
-		     mdev->bc->md.uuid[Bitmap] == 0 ) {
-			/* We only create a new UUID if the peer might
-			   possibly be UpToDate. Since the connection is
-			   already gone it is DUnknown by now.
-			   In case we already created a BitMap there is
-			   no need to create a new UUID.
-			*/
-			drbd_uuid_new_current(mdev);
-		}
 		if ( test_bit(SPLIT_BRAIN_FIX,&mdev->flags) &&
 		     mdev->state.pdsk >= DUnknown ) {
 			drbd_disks_t nps = drbd_try_outdate_peer(mdev);

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_req.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -177,7 +177,8 @@
 	sector_t esector, nr_sectors;
 
 	if (mdev->state.disk == UpToDate) return 1;
-
+	if (mdev->state.disk <  Inconsistent) return 0;
+	// We will have a look at the BitMap
 	nr_sectors = drbd_get_capacity(mdev->this_bdev);
 	esector = sector + (size>>9) -1;
 

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/drbd_strings.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -36,10 +36,11 @@
 	[SkippedSyncT]   = "SkippedSyncT",
 	[WFBitMapS]      = "WFBitMapS",
 	[WFBitMapT]      = "WFBitMapT",
+	[WFSyncUUID]     = "WFSyncUUID",
 	[SyncSource]     = "SyncSource",
 	[SyncTarget]     = "SyncTarget",
 	[PausedSyncS]    = "PausedSyncS",
-	[PausedSyncT]    = "PausedSyncT",
+	[PausedSyncT]    = "PausedSyncT"
 };
 
 static const char *drbd_role_s_names[] = {

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/drbd/linux/drbd_config.h	2005-11-27 21:47:02 UTC (rev 2011)
@@ -30,7 +30,7 @@
 
 //#define DBG_SPINLOCKS   // enables MUST_HOLD macro (assertions for spinlocks)
 //#define DBG_ASSERTS     // drbd_assert_breakpoint() function
-
+#define DUMP_MD 2       // Dump even all cstate changes (I like it!)
 //#define PARANOIA // some extra checks
 
 // don't enable this, unless you can cope with gigabyte syslogs :)

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2005-11-22 10:24:36 UTC (rev 2010)
+++ trunk/user/drbdmeta.c	2005-11-27 21:47:02 UTC (rev 2011)
@@ -1643,17 +1643,17 @@
 
 	printf("version \"%s\";\n\n", cfg->ops->name);
 	if (format_version(cfg) < Drbd_08) {
-		printf("gc {");
+		printf("gc {\n   ");
 		for (i = 0; i < GEN_CNT_SIZE; i++) {
 			printf(" 0x%X;", cfg->md.gc[i]);
 		}
 	} else { // >= 08
-		printf("uuid {");
+		printf("uuid {\n   ");
 		for ( i=Current ; i<UUID_SIZE ; i++ ) {
 			printf(" 0x"X64(016)";", cfg->md.uuid[i]);
 		}
 	}
-	printf(" }\n");
+	printf("\n}\n");
 
 	if (format_version(cfg) >= Drbd_07) {
 		printf("la-size-sect "U64";\n", cfg->md.la_sect);
@@ -2220,19 +2220,20 @@
 	return cfg->ops->parse(cfg, argv + 1, argc - 1, ai);
 }
 
-int is_configured(int minor)
+int is_attached(int minor)
 {
 	FILE *pr;
-	char line[120], tok[40];
+	char line[120], cs[40],st[40],ds[40];
 	int m,rv=0;
 
 	pr = fopen("/proc/drbd","r");
 	if(!pr) return rv;
 
 	while(fgets(line,120,pr)) {
-		if(sscanf(line,"%2d: %s",&m,tok)) {
+		if(sscanf(line,"%2d: %s %s %s",&m,cs,st,ds)) {
 			if( m == minor ) {
-				rv = strcmp(tok,"Unconfigured");
+				rv = strcmp(cs,"Unconfigured");
+				if(rv) rv = strncmp(ds,"ds:Diskless/",11);
 				break;
 			}
 		}
@@ -2319,7 +2320,7 @@
 
 	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))) {
+		if (is_attached(dt_minor_of_dev(cfg->drbd_dev_name))) {
 			fprintf(stderr, "Device '%s' is configured!\n",
 				cfg->drbd_dev_name);
 			exit(20);



More information about the drbd-cvs mailing list