[DRBD-cvs] r1777 - in trunk: . drbd drbd/linux
www-data
www-data at garcon.linbit.com
Mon Apr 4 17:19:43 CEST 2005
Author: phil
Date: 2005-04-04 17:19:41 +0200 (Mon, 04 Apr 2005)
New Revision: 1777
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/drbd_sizeof_sanity_check.c
trunk/drbd/drbd_worker.c
trunk/drbd/linux/drbd.h
trunk/drbd/linux/drbd_config.h
Log:
Implemented the kernel part of item 16 (generation UUIDs)
Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/ROADMAP 2005-04-04 15:19:41 UTC (rev 1777)
@@ -468,6 +468,10 @@
NB: If they are needed, I think they can be implemented
as special UUID values.
+ 50% DONE. Kernel part is implemented, not tested. But testing
+ will only be possible after drbdmeta was updated.
+ Drbdmeta still has no clue of gen-UUIDs, not drbdsetup.
+
17 Something like
drbdx: WARNING disk sizes more than 10% different
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_fs.c 2005-04-04 15:19:41 UTC (rev 1777)
@@ -703,7 +703,7 @@
nps = Outdated;
break;
case 5: /* peer was down, increase GENCNT ... */
- drbd_md_inc(mdev,ConnectedCnt);
+ drbd_uuid_new_current(mdev);
nps = Outdated;
break;
case 6: /* Peer is primary, voluntarily outdate myself */
@@ -712,7 +712,7 @@
break;
default:
/* The script is broken ... */
- drbd_md_inc(mdev,ConnectedCnt);
+ drbd_uuid_new_current(mdev);
nps = DUnknown;
ERR("outdate-peer helper returned %d (%d)\n",(r>>8)&0xff,r);
}
@@ -824,14 +824,9 @@
clear_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
}
- if(newstate & Human) {
- drbd_md_inc(mdev,HumanCnt);
- } else if(newstate & TimeoutExpired ) {
- drbd_md_inc(mdev,TimeoutCnt);
- } else {
- drbd_md_inc(mdev,
- mdev->state.s.conn >= Connected ?
- ConnectedCnt : ArbitraryCnt);
+ if ( (mdev->state.s.conn < WFReportParams &&
+ mdev->uuid[Bitmap] == 0) || forced ) {
+ drbd_uuid_new_current(mdev);
}
}
@@ -982,10 +977,10 @@
return 0;
}
-STATIC int drbd_ioctl_get_gen_cnt(struct Drbd_Conf *mdev,
- struct ioctl_get_gen_cnt* arg)
+STATIC int drbd_ioctl_get_uuids(struct Drbd_Conf *mdev,
+ struct ioctl_get_uuids* arg)
{
- struct ioctl_get_gen_cnt cn;
+ struct ioctl_get_uuids cn;
int i;
if( mdev->state.s.disk <= Failed ) {
@@ -994,10 +989,9 @@
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;
+ for (i = Current; i < UUID_SIZE; i++) {
+ cn.uuid[i]=mdev->uuid[i];
+ }
cn.bits_set = drbd_bm_total_weight(mdev);
cn.current_size = drbd_get_capacity(mdev->this_bdev);
@@ -1307,8 +1301,8 @@
err = drbd_outdate_ioctl(mdev,(int *) arg);
break;
- case DRBD_IOCTL_GET_GEN_CNT:
- err=drbd_ioctl_get_gen_cnt(mdev,(void *)arg);
+ case DRBD_IOCTL_GET_UUIDS:
+ err=drbd_ioctl_get_uuids(mdev,(void *)arg);
break;
default:
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_int.h 2005-04-04 15:19:41 UTC (rev 1777)
@@ -293,7 +293,7 @@
RSDataRequest, // Used to ask for a data block
SyncParam,
ReportProtocol,
- ReportGenCnt,
+ ReportUUIDs,
ReportSizes,
ReportState,
AuthChallenge,
@@ -334,7 +334,7 @@
[RSDataRequest] = "RSDataRequest",
[SyncParam] = "SyncParam",
[ReportProtocol] = "ReportProtocol",
- [ReportGenCnt] = "ReportGenCnt",
+ [ReportUUIDs] = "ReportUUIDs",
[ReportSizes] = "ReportSizes",
[ReportState] = "ReportState",
[AuthChallenge] = "AuthChallenge",
@@ -461,13 +461,12 @@
typedef struct {
Drbd_Header head;
- u64 uuid;
u32 protocol;
} __attribute((packed)) Drbd_Protocol_Packet;
typedef struct {
Drbd_Header head;
- u32 gen_cnt[GEN_CNT_SIZE];
+ u64 uuid[UUID_SIZE];
} __attribute((packed)) Drbd_GenCnt_Packet;
typedef struct {
@@ -636,7 +635,6 @@
MD_IO_ALLOWED, // EXPLAIN
MD_DIRTY, // current gen counts and flags not yet on disk
SYNC_STARTED, // Needed to agree on the exact point in time..
- UUID_CHANGED, // UUID changed. Need fullsync.
UNIQUE, // Set on one node, cleared on the peer!
SPLIT_BRAIN_FIX, // Set if split-brain-fix is configured
};
@@ -706,8 +704,6 @@
/* volatile */ drbd_state_t state;
wait_queue_head_t cstate_wait; // TODO Rename into "misc_wait".
sector_t la_size; // last agreed disk size in sectors.
- u64 uuid;
- u64 peer_uuid;
unsigned int send_cnt;
unsigned int recv_cnt;
unsigned int read_cnt;
@@ -742,8 +738,9 @@
struct lru_cache* resync; // Used to track operations of resync...
atomic_t resync_locked; // Number of locked elements in resync LRU
int open_cnt;
- u32 gen_cnt[GEN_CNT_SIZE];
- u32 *p_gen_cnt;
+ unsigned int md_flags;
+ u64 uuid[UUID_SIZE];
+ u64 *p_uuid;
atomic_t epoch_size;
spinlock_t ee_lock;
struct list_head active_ee; // IO in progress
@@ -836,10 +833,10 @@
// drbd_meta-data.c (still in drbd_main.c)
extern void drbd_md_write(drbd_dev *mdev);
extern int drbd_md_read(drbd_dev *mdev);
-extern int drbd_md_compare(drbd_dev *mdev);
-extern void drbd_dump_md(drbd_dev *, int );
// maybe define them below as inline?
-extern void drbd_md_inc(drbd_dev *mdev, enum MetaDataIndex order);
+extern void drbd_uuid_set_current(drbd_dev *mdev, u64 val);
+extern void drbd_uuid_new_current(drbd_dev *mdev);
+extern void drbd_uuid_reset_bm(drbd_dev *mdev);
extern void drbd_md_set_flag(drbd_dev *mdev, int flags);
extern void drbd_md_clear_flag(drbd_dev *mdev, int flags);
extern int drbd_md_test_flag(drbd_dev *mdev, int flag);
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_main.c 2005-04-04 15:19:41 UTC (rev 1777)
@@ -50,6 +50,7 @@
#include <linux/mm_inline.h>
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/random.h>
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
@@ -542,7 +543,6 @@
int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns,enum chg_state_flags flags)
{
drbd_state_t os;
- char pb[160], *pbp;
int rv=1,warn_sync_abort=0;
os = mdev->state;
@@ -667,10 +667,6 @@
mod_timer(&mdev->resync_timer,jiffies);
}
- if ( os.s.peer == Secondary && ns.s.peer == Primary ) {
- drbd_md_inc(mdev,ConnectedCnt);
- }
-
if ( os.s.disk == Diskless && os.s.peer == StandAlone &&
(ns.s.disk >= Inconsistent || ns.s.peer > StandAlone) ) {
__module_get(THIS_MODULE);
@@ -681,6 +677,12 @@
drbd_panic("No access to good data anymore.\n");
}
+ if ( os.s.conn != Connected && ns.s.conn == Connected &&
+ mdev->p_uuid ) {
+ kfree(mdev->p_uuid);
+ mdev->p_uuid = 0;
+ }
+
return rv;
}
@@ -948,7 +950,6 @@
{
Drbd_Protocol_Packet p;
- p.uuid = cpu_to_be64(mdev->uuid);
p.protocol = cpu_to_be32(mdev->conf.wire_protocol);
return drbd_send_cmd(mdev,mdev->data.socket,ReportProtocol,
@@ -960,11 +961,11 @@
Drbd_GenCnt_Packet p;
int i;
- for (i = Flags; i < GEN_CNT_SIZE; i++) {
- p.gen_cnt[i] = cpu_to_be32(mdev->gen_cnt[i]);
+ for (i = Current; i < UUID_SIZE; i++) {
+ p.uuid[i] = cpu_to_be64(mdev->uuid[i]);
}
- return drbd_send_cmd(mdev,mdev->data.socket,ReportGenCnt,
+ return drbd_send_cmd(mdev,mdev->data.socket,ReportUUIDs,
(Drbd_Header*)&p,sizeof(p));
}
@@ -1722,7 +1723,7 @@
ZAP(mdev->sync_conf);
// ZAP(mdev->data); Not yet!
// ZAP(mdev->meta); Not yet!
- ZAP(mdev->gen_cnt);
+ ZAP(mdev->uuid);
#undef ZAP
mdev->al_writ_cnt =
mdev->bm_writ_cnt =
@@ -2212,9 +2213,8 @@
struct meta_data_on_disk {
u64 la_size; // last agreed size.
- u64 uuid; // universally unique identifier
- u64 peer_uuid; // universally unique identifier
- u32 gc[GEN_CNT_SIZE]; // generation counter
+ u64 uuid[UUID_SIZE]; // UUIDs.
+ u32 flags; // MDF
u32 magic;
u32 md_size;
u32 al_offset; // offset to this block
@@ -2240,19 +2240,17 @@
buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
memset(buffer,0,512);
- flags = mdev->gen_cnt[Flags] & ~(MDF_Consistent|MDF_PrimaryInd|
- MDF_ConnectedInd|MDF_WasUpToDate);
+ flags = mdev->md_flags & ~(MDF_Consistent|MDF_PrimaryInd|
+ MDF_ConnectedInd|MDF_WasUpToDate);
if (mdev->state.s.role == Primary) flags |= MDF_PrimaryInd;
if (mdev->state.s.conn >= WFReportParams) flags |= MDF_ConnectedInd;
if (mdev->state.s.disk > Inconsistent) flags |= MDF_Consistent;
if (mdev->state.s.disk > Outdated) flags |= MDF_WasUpToDate;
- mdev->gen_cnt[Flags] = flags;
+ mdev->md_flags = flags;
- for (i = Flags; i < GEN_CNT_SIZE; i++)
- buffer->gc[i]=cpu_to_be32(mdev->gen_cnt[i]);
+ for (i = Current; i < UUID_SIZE; i++)
+ buffer->uuid[i]=cpu_to_be64(mdev->uuid[i]);
buffer->la_size=cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
- buffer->uuid=cpu_to_be64(mdev->uuid);
- buffer->peer_uuid=cpu_to_be64(mdev->peer_uuid);
buffer->magic=cpu_to_be32(DRBD_MD_MAGIC);
@@ -2328,11 +2326,9 @@
goto err;
}
- for(i=Flags;i<=ArbitraryCnt;i++)
- mdev->gen_cnt[i]=be32_to_cpu(buffer->gc[i]);
+ for (i = Current; i < UUID_SIZE; i++)
+ mdev->uuid[i]=be64_to_cpu(buffer->uuid[i]);
mdev->la_size = be64_to_cpu(buffer->la_size);
- mdev->uuid = be64_to_cpu(buffer->uuid);
- mdev->peer_uuid = be64_to_cpu(buffer->peer_uuid);
mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents);
if (mdev->sync_conf.al_extents < 7)
mdev->sync_conf.al_extents = 127;
@@ -2349,105 +2345,60 @@
return rv;
}
-#if DUMP_MD >= 1
-#define MeGC(x) mdev->gen_cnt[x]
-#define PeGC(x) mdev->p_gen_cnt[x]
-void drbd_dump_md(drbd_dev *mdev, int verbose)
+void drbd_uuid_set_current(drbd_dev *mdev, u64 val)
{
- INFO("I am(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
- mdev->state.s.role == Primary ? 'P':'S',
- MeGC(Flags) & MDF_Consistent ? '1' : '0',
- MeGC(HumanCnt),
- MeGC(TimeoutCnt),
- MeGC(ConnectedCnt),
- MeGC(ArbitraryCnt),
- MeGC(Flags) & MDF_PrimaryInd ? '1' : '0',
- MeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
- if (mdev->p_gen_cnt) {
- INFO("Peer(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
- mdev->state.s.peer == Primary ? 'P':'S',
- PeGC(Flags) & MDF_Consistent ? '1' : '0',
- PeGC(HumanCnt),
- PeGC(TimeoutCnt),
- PeGC(ConnectedCnt),
- PeGC(ArbitraryCnt),
- PeGC(Flags) & MDF_PrimaryInd ? '1' : '0',
- PeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
+ mdev->uuid[Current] = val;
+ if (mdev->state.s.role == Primary) {
+ mdev->uuid[Current] |= 1;
} else {
- INFO("Peer Unknown.\n");
+ mdev->uuid[Current] &= ~((u64)1);
}
- if (verbose) {
- /* TODO
- * dump activity log and bitmap summary,
- * and maybe other statistics
- */
+}
+
+void drbd_uuid_new_current(drbd_dev *mdev)
+{
+ D_ASSERT(mdev->uuid[Bitmap] = 0);
+ mdev->uuid[Bitmap] = mdev->uuid[Current];
+ get_random_bytes(&mdev->uuid[Current], sizeof(u64));
+ if (mdev->state.s.role == Primary) {
+ mdev->uuid[Current] |= 1;
+ } else {
+ mdev->uuid[Current] &= ~((u64)1);
}
}
-#undef MeGC
-#undef PeGC
-#else
-void drbd_dump_md(drbd_dev *mdev, Drbd_Parameter_Packet *peer, int verbose)
-{ /* do nothing */ }
-#endif
-
-// Returns 1 if I have the good bits,
-// 0 if both are nice
-// -1 if the partner has the good bits.
-int drbd_md_compare(drbd_dev *mdev)
+void drbd_uuid_reset_bm(drbd_dev *mdev)
{
int i;
- u32 self,peer;
- self = mdev->gen_cnt[Flags] & MDF_Consistent;
- peer = mdev->p_gen_cnt[Flags] & MDF_Consistent;
- if( self > peer ) return 1;
- if( self < peer ) return -1;
+ if (mdev->uuid[Bitmap] == 0) return;
- self = mdev->gen_cnt[Flags] & MDF_WasUpToDate;
- peer = mdev->p_gen_cnt[Flags] & MDF_WasUpToDate;
- if( self > peer ) return 1;
- if( self < peer ) return -1;
-
- for(i=HumanCnt;i<=ArbitraryCnt;i++) {
- self = mdev->gen_cnt[i];
- peer = mdev->p_gen_cnt[i];
- if( self > peer ) return 1;
- if( self < peer ) return -1;
+ for ( i=History_start ; i<History_end ; i++ ) {
+ mdev->uuid[i+1] = mdev->uuid[i];
}
- self = mdev->gen_cnt[Flags] & MDF_PrimaryInd;
- peer = mdev->p_gen_cnt[Flags] & MDF_PrimaryInd;
- if( self > peer ) return 1;
- if( self < peer ) return -1;
-
- return 0;
+ mdev->uuid[History_start]=mdev->uuid[Bitmap];
+ mdev->uuid[Bitmap]=0;
}
-/* THINK do these have to be protected by some lock ? */
-void drbd_md_inc(drbd_dev *mdev, enum MetaDataIndex order)
-{
- set_bit(MD_DIRTY,&mdev->flags);
- mdev->gen_cnt[order]++;
-}
void drbd_md_set_flag(drbd_dev *mdev, int flag)
{
- if ( (mdev->gen_cnt[Flags] & flag) != flag) {
+ if ( (mdev->md_flags & flag) != flag) {
set_bit(MD_DIRTY,&mdev->flags);
- mdev->gen_cnt[Flags] |= flag;
+ mdev->md_flags |= flag;
}
}
void drbd_md_clear_flag(drbd_dev *mdev, int flag)
{
- if ( (mdev->gen_cnt[Flags] & flag) != 0 ) {
+ if ( (mdev->md_flags & flag) != 0 ) {
set_bit(MD_DIRTY,&mdev->flags);
- mdev->gen_cnt[Flags] &= ~flag;
+ mdev->md_flags &= ~flag;
}
}
int drbd_md_test_flag(drbd_dev *mdev, int flag)
{
- return ((mdev->gen_cnt[Flags] & flag) != 0);
+ return ((mdev->md_flags & flag) != 0);
}
module_init(drbd_init)
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_receiver.c 2005-04-04 15:19:41 UTC (rev 1777)
@@ -1257,123 +1257,133 @@
return TRUE;
}
+/*
+ 100 after split brain try auto recover
+ 2 SyncSource set BitMap
+ 1 SyncSource use BitMap
+ 0 no Sync
+ -1 SyncTarget use BitMap
+ -2 SyncTarget set BitMap
+ -100 after split brain, disconnect
+-1000 unrelated data
+ */
+static int drbd_uuid_compare(drbd_dev *mdev)
+{
+ u64 self, peer;
+ int i,j;
+
+ self = mdev->uuid[Current] & ~((u64)1);
+ peer = mdev->p_uuid[Current] & ~((u64)1);
+
+ if (self == UUID_JUST_CREATED &&
+ peer == UUID_JUST_CREATED) return 0;
+
+ if (self == UUID_JUST_CREATED &&
+ peer != UUID_JUST_CREATED) return -2;
+
+ if (self != UUID_JUST_CREATED &&
+ peer == UUID_JUST_CREATED) return 2;
+
+ if (self == peer) return 0;
+
+ peer = mdev->p_uuid[Bitmap] & ~((u64)1);
+ if (self == peer) return -1;
+
+ for ( i=History_start ; i<=History_end ; i++ ) {
+ peer = mdev->p_uuid[i];
+ if (self == peer) return -2;
+ }
+
+ self = mdev->uuid[Bitmap] & ~((u64)1);
+ peer = mdev->p_uuid[Current] & ~((u64)1);
+
+ if (self == peer) return 1;
+
+ for ( i=History_start ; i<=History_end ; i++ ) {
+ self = mdev->uuid[i] & ~((u64)1);
+ if (self == peer) return 2;
+ }
+
+ self = mdev->uuid[Bitmap] & ~((u64)1);
+ peer = mdev->p_uuid[Bitmap] & ~((u64)1);
+
+ if (self == peer) return 100;
+
+ for ( i=History_start ; i<=History_end ; i++ ) {
+ self = mdev->p_uuid[i] & ~((u64)1);
+ for ( j=History_start ; j<=History_end ; j++ ) {
+ peer = mdev->p_uuid[j] & ~((u64)1);
+ if (self == peer) return -100;
+ }
+ }
+
+ return -1000;
+}
+
/* drbd_sync_handshake() returns the new conn state on success, or
conn_mask (-1) on failure.
*/
STATIC drbd_conns_t drbd_sync_handshake(drbd_dev *mdev)
{
- int have_good,sync;
+ int hg;
drbd_conns_t rv = conn_mask;
- have_good = drbd_md_compare(mdev);
+ hg = drbd_uuid_compare(mdev);
- if(have_good==0) {
- if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
- /* gen counts compare the same, but I have the
- * PrimaryIndicator set. so the peer has, too
- * (otherwise this would not compare the same).
- * so we had a split brain!
- *
- * FIXME maybe log MDF_SplitBran into metadata,
- * and refuse to do anything until told otherwise!
- *
- * for now: just go StandAlone.
- */
- ALERT("Split-Brain detected, dropping connection!\n");
- drbd_force_state(mdev,NS(conn,StandAlone));
- drbd_thread_stop_nowait(&mdev->receiver);
- return conn_mask;
- }
- sync=0;
- } else {
- sync=1;
+ if (abs(hg) >= 100) {
+ ALERT("Split-Brain detected, dropping connection!\n");
+ drbd_force_state(mdev,NS(conn,StandAlone));
+ drbd_thread_stop_nowait(&mdev->receiver);
+ return conn_mask;
}
- drbd_dump_md(mdev,0);
- // INFO("have_good=%d sync=%d\n", have_good, sync);
-
- if (have_good > 0 && mdev->state.s.disk <= Inconsistent ) {
- /* doh. I cannot become SyncSource when I am inconsistent!
- */
+ if (hg > 0 && mdev->state.s.disk <= Inconsistent ) {
ERR("I shall become SyncSource, but I am inconsistent!\n");
drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return conn_mask;
}
- if (have_good < 0 && !(mdev->p_gen_cnt[Flags] & MDF_Consistent) ) {
- /* doh. Peer cannot become SyncSource when inconsistent
- */
- ERR("I shall become SyncTarget, but Peer is inconsistent!\n");
+ if (hg < 0 && mdev->state.s.role == Primary ) {
+ ERR("I shall become SyncTarget, but I am primary!\n");
drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return conn_mask;
}
- if ( mdev->sync_conf.skip && sync ) {
- return have_good == 1 ? SkippedSyncS : SkippedSyncT ;
+ if (abs(hg) >= 2) {
+ drbd_md_set_flag(mdev,MDF_FullSync);
+ drbd_md_write(mdev);
+
+ drbd_bm_set_all(mdev);
+ drbd_bm_write(mdev);
+
+ drbd_md_clear_flag(mdev,MDF_FullSync);
+ drbd_md_write(mdev);
}
- if( sync ) {
- if( test_bit(UUID_CHANGED,&mdev->flags) ) {
- WARN("Peer presented a new UUID -> full sync.\n");
- drbd_bm_set_all(mdev);
- clear_bit(UUID_CHANGED, &mdev->flags);
- }
-
- if(have_good == 1) {
- 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 { // have_good == -1
- if ( (mdev->state.s.role == Primary) &&
- drbd_md_test_flag(mdev,MDF_Consistent) ) {
- /* FIXME
- * allow Primary become SyncTarget if it was
- * diskless, and now had a storage reattached.
- * only somewhere the MDF_Consistent flag is
- * set where it should not... I think.
- */
- ERR("Current Primary shall become sync TARGET!"
- " Aborting to prevent data corruption.\n");
- drbd_force_state(mdev,NS(conn,StandAlone));
- drbd_thread_stop_nowait(&mdev->receiver);
- return conn_mask;
- }
- drbd_md_clear_flag(mdev,MDF_Consistent);
- rv = WFBitMapT;
- }
+ 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_current(mdev,mdev->p_uuid[Bitmap]);
+ rv = WFBitMapT;
} else {
rv = Connected;
drbd_bm_lock(mdev); // {
if(drbd_bm_total_weight(mdev)) {
- if (drbd_md_test_flag(mdev,MDF_Consistent)) {
- /* We are not going to do a resync but there
- are marks in the bitmap.
- (Could be from the AL, or someone used
- the write_gc.pl program)
- Clean the bitmap...
- */
- INFO("No resync -> clearing bit map.\n");
- drbd_bm_clear_all(mdev);
- drbd_bm_write(mdev);
- } else {
- WARN("I am inconsistent, but there is no sync? BOTH nodes inconsistent!\n");
- }
+ INFO("No resync -> clearing bit map.\n");
+ drbd_bm_clear_all(mdev);
+ drbd_bm_write(mdev);
}
drbd_bm_unlock(mdev); // }
}
- if (have_good == -1) {
- /* Sync-Target has to adopt source's gen_cnt. */
- int i;
- for(i=HumanCnt;i<GEN_CNT_SIZE;i++) {
- mdev->gen_cnt[i]=mdev->p_gen_cnt[i];
- }
- }
return rv;
}
@@ -1403,11 +1413,6 @@
return FALSE;
}
- if( mdev->peer_uuid != be64_to_cpu(p->uuid) ) {
- mdev->peer_uuid = be64_to_cpu(p->uuid);
- set_bit(UUID_CHANGED, &mdev->flags);
- }
-
return TRUE;
}
@@ -1459,10 +1464,8 @@
drbd_determin_dev_size(mdev);
drbd_bm_unlock(mdev); // }
- if (mdev->p_gen_cnt) {
+ if (mdev->p_uuid) {
nconn=drbd_sync_handshake(mdev);
- kfree(mdev->p_gen_cnt);
- mdev->p_gen_cnt = 0;
if(nconn == conn_mask) return FALSE;
if(drbd_request_state(mdev,NS(conn,nconn)) <= 0) {
@@ -1489,24 +1492,24 @@
return TRUE;
}
-STATIC int receive_gen_cnt(drbd_dev *mdev, Drbd_Header *h)
+STATIC int receive_uuids(drbd_dev *mdev, Drbd_Header *h)
{
Drbd_GenCnt_Packet *p = (Drbd_GenCnt_Packet*)h;
- u32 *p_gen_cnt;
+ u64 *p_uuid;
int i;
ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
if (drbd_recv(mdev, h->payload, h->length) != h->length)
return FALSE;
- p_gen_cnt = kmalloc(sizeof(u32)*GEN_CNT_SIZE, GFP_KERNEL);
+ p_uuid = kmalloc(sizeof(u64)*UUID_SIZE, GFP_KERNEL);
- for (i = Flags; i < GEN_CNT_SIZE; i++) {
- p_gen_cnt[i] = be32_to_cpu(p->gen_cnt[i]);
+ for (i = Current; i < UUID_SIZE; i++) {
+ p_uuid[i] = be64_to_cpu(p->uuid[i]);
}
- if ( mdev->p_gen_cnt ) kfree(mdev->p_gen_cnt);
- mdev->p_gen_cnt = p_gen_cnt;
+ if ( mdev->p_uuid ) kfree(mdev->p_uuid);
+ mdev->p_uuid = p_uuid;
return TRUE;
}
@@ -1526,10 +1529,10 @@
nconn = mdev->state.s.conn;
if (nconn == WFReportParams ) nconn = Connected;
- if (mdev->p_gen_cnt) {
+ if (mdev->p_uuid && mdev->state.s.conn == Connected) {
nconn=drbd_sync_handshake(mdev);
- kfree(mdev->p_gen_cnt);
- mdev->p_gen_cnt = 0;
+ kfree(mdev->p_uuid);
+ mdev->p_uuid = 0;
if(nconn == conn_mask) return FALSE;
}
@@ -1730,7 +1733,7 @@
[RSDataRequest] = receive_DataRequest, //receive_RSDataRequest,
[SyncParam] = receive_SyncParam,
[ReportProtocol] = receive_protocol,
- [ReportGenCnt] = receive_gen_cnt,
+ [ReportUUIDs] = receive_uuids,
[ReportSizes] = receive_sizes,
[ReportState] = receive_state,
};
@@ -1876,10 +1879,13 @@
drbd_thread_start(&mdev->worker);
}
- if ( test_bit(SPLIT_BRAIN_FIX,&mdev->flags) &&
- mdev->state.s.role == Primary) {
- drbd_disks_t nps = drbd_try_outdate_peer(mdev);
- drbd_request_state(mdev,NS(pdsk,nps));
+ if ( mdev->state.s.role == Primary ) {
+ if ( test_bit(SPLIT_BRAIN_FIX,&mdev->flags) ) {
+ drbd_disks_t nps = drbd_try_outdate_peer(mdev);
+ drbd_request_state(mdev,NS(pdsk,nps));
+ } else {
+ drbd_uuid_new_current(mdev);
+ }
drbd_md_write(mdev);
}
Modified: trunk/drbd/drbd_sizeof_sanity_check.c
===================================================================
--- trunk/drbd/drbd_sizeof_sanity_check.c 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_sizeof_sanity_check.c 2005-04-04 15:19:41 UTC (rev 1777)
@@ -23,7 +23,7 @@
SZO(struct ioctl_syncer_config, 32)
SZO(struct ioctl_wait, 16)
SZO(struct ioctl_get_config, 560)
- SZO(struct ioctl_get_gen_cnt, 48)
+ SZO(struct ioctl_get_uuids, 48)
if (err) printk("<3>ioctls won't work, aborting\n");
return err;
}
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_worker.c 2005-04-04 15:19:41 UTC (rev 1777)
@@ -390,6 +390,9 @@
mdev->rs_total = 0;
mdev->rs_paused = 0;
+ drbd_uuid_set_current(mdev,mdev->p_uuid[Current]);
+ drbd_uuid_reset_bm(mdev);
+
drbd_request_state(mdev,NS3(conn,Connected,
disk,UpToDate,
pdsk,UpToDate));
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/linux/drbd.h 2005-04-04 15:19:41 UTC (rev 1777)
@@ -273,6 +273,7 @@
#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 */
@@ -282,11 +283,19 @@
GEN_CNT_SIZE /* MUST BE LAST! (and Flags must stay first...) */
};
-struct ioctl_get_gen_cnt {
- OUT __u64 uuid;
- OUT __u64 peer_uuid;
+enum UuidIndex {
+ Current,
+ Bitmap,
+ History_start,
+ History_end,
+ UUID_SIZE
+};
+
+#define UUID_JUST_CREATED ((__u64)4)
+
+struct ioctl_get_uuids {
+ OUT __u64 uuid[UUID_SIZE];
OUT __u64 current_size;
- OUT __u32 gen_cnt[GEN_CNT_SIZE]; /* generation counter */
OUT unsigned int bits_set;
};
@@ -312,7 +321,7 @@
#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 )
+#define DRBD_IOCTL_GET_UUIDS _IOR( DRBD_IOCTL_LETTER, 0x16, struct ioctl_get_uuids )
#endif
Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h 2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/linux/drbd_config.h 2005-04-04 15:19:41 UTC (rev 1777)
@@ -30,10 +30,6 @@
//#define DBG_SPINLOCKS // enables MUST_HOLD macro (assertions for spinlocks)
//#define DBG_ASSERTS // drbd_assert_breakpoint() function
-//#define DUMP_MD 1 // Dump metadata to syslog upon connect
-#define DUMP_MD 2 // Dump even all cstate changes (I like it!)
-//#define DUMP_MD 3 // Dump even all meta data access
- // (don't! unless we track down a bug...)
//#define PARANOIA // some extra checks
More information about the drbd-cvs
mailing list