[DRBD-cvs] r1636 - in trunk: drbd drbd/linux user
svn at svn.drbd.org
svn at svn.drbd.org
Fri Nov 12 12:51:58 CET 2004
Author: phil
Date: 2004-11-12 12:51:55 +0100 (Fri, 12 Nov 2004)
New Revision: 1636
Modified:
trunk/drbd/drbd_fs.c
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
trunk/drbd/drbd_receiver.c
trunk/drbd/drbd_req.c
trunk/drbd/drbd_strings.c
trunk/drbd/drbd_worker.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
Log:
Implemented "drbdadm outdate" and the implications on DRBD's
state switching mechanisms.
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_fs.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -222,6 +222,7 @@
struct file *filp2 = 0;
struct inode *inode, *inode2;
struct block_device *bdev, *bdev2;
+ drbd_disks_t nds;
minor=(int)(mdev-drbd_conf);
@@ -434,9 +435,22 @@
drbd_set_blocksize(mdev,INITIAL_BLOCK_SIZE);
- if(drbd_request_state(mdev,NS(disk,
- drbd_md_test_flag(mdev,MDF_Consistent)
- ? Consistent : Inconsistent )) > 0) {
+ /* If MDF_Consistent is not set go into inconsistent state, otherwise
+ investige MDF_UpToDate...
+ If MDF_UpToDate 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_UpToDate)) {
+ nds = Consistent;
+ } else {
+ nds = Outdated;
+ }
+ } else {
+ nds = Inconsistent;
+ }
+
+ if(drbd_request_state(mdev,NS(disk,nds)) > 0) {
drbd_thread_start(&mdev->worker);
}
@@ -615,10 +629,10 @@
}
/* --do-what-I-say*/
- if (mdev->state.s.disk < Consistent) {
- WARN("Forcefully set consistent!");
+ if (mdev->state.s.disk < UpToDate) {
+ WARN("Forcefully set to UpToDate!");
r = drbd_request_state(mdev,NS2(role,newstate & 0x3,
- disk,Consistent));
+ disk,UpToDate));
if(r<=0) return -EIO;
forced = 1;
@@ -1032,7 +1046,6 @@
drbd_bm_lock(mdev); // racy...
drbd_md_set_flag(mdev,MDF_FullSync);
- drbd_md_clear_flag(mdev,MDF_Consistent);
drbd_md_write(mdev);
drbd_bm_set_all(mdev);
@@ -1086,6 +1099,18 @@
break;
+ case DRBD_IOCTL_OUTDATE_DISK:
+ r = drbd_request_state(mdev,NS(disk,Outdated));
+ if( r == 2 ) break;
+ if( r <= 0 ) {
+ err = -EISCONN;
+ break;
+ }
+
+ drbd_md_write(mdev);
+
+ break;
+
default:
err = -EINVAL;
}
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_int.h 2004-11-12 11:51:55 UTC (rev 1636)
@@ -246,11 +246,13 @@
__MDF_PrimaryInd,
__MDF_ConnectedInd,
__MDF_FullSync,
+ __MDF_UpToDate,
};
#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_UpToDate (1<<__MDF_UpToDate)
/* drbd_meta-data.c (still in drbd_main.c) */
enum MetaDataIndex {
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_main.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -431,10 +431,14 @@
ns.s.conn < Connected ) rv=-3;
if( ns.s.conn > Connected &&
- ns.s.disk < Consistent && ns.s.pdsk < Consistent ) rv=-4;
+ ns.s.disk < UpToDate && ns.s.pdsk < UpToDate ) rv=-4;
if( ns.s.conn > Connected &&
(ns.s.disk == Diskless || ns.s.pdsk == Diskless ) ) rv=-5;
+
+ if( (ns.s.conn >= Connected && ns.s.conn != PausedSyncT) &&
+ ns.s.disk == Outdated ) rv=-6;
+
}
/* State sanitising */
@@ -446,6 +450,48 @@
ns.s.conn = Connected;
}
+ if( ns.s.conn >= Connected && ns.s.disk == Consistent ) {
+ switch(ns.s.conn) {
+ case SkippedSyncT:
+ case WFBitMapT:
+ case PausedSyncT:
+ ns.s.disk = Outdated;
+ break;
+ case Connected:
+ case SkippedSyncS:
+ case WFBitMapS:
+ case SyncSource:
+ case PausedSyncS:
+ ns.s.disk = UpToDate;
+ break;
+ case SyncTarget:
+ ns.s.disk = Inconsistent;
+ WARN("Implicit set disk state Inconsistent!\n");
+ break;
+ }
+ }
+
+ if( ns.s.conn >= Connected && ns.s.pdsk == Consistent ) {
+ switch(ns.s.conn) {
+ case Connected:
+ case SkippedSyncT:
+ case WFBitMapT:
+ case PausedSyncT:
+ case SyncTarget:
+ ns.s.pdsk = UpToDate;
+ break;
+ case SkippedSyncS:
+ case WFBitMapS:
+ case PausedSyncS:
+ ns.s.pdsk = Outdated;
+ break;
+ case SyncSource:
+ ns.s.disk = Inconsistent;
+ WARN("Implicit set pdsk Inconsistent!\n");
+ break;
+ }
+ }
+
if(rv <= 0) {
if( flags & ChgStateVerbose ) print_st_err(mdev,os,ns,rv);
return rv;
@@ -483,7 +529,7 @@
}
if ( ns.s.role == Primary && ns.s.conn < Connected &&
- ns.s.disk < Consistent ) {
+ ns.s.disk < UpToDate ) {
drbd_panic("No access to good data anymore.\n");
}
@@ -506,18 +552,6 @@
ns.s.conn >= Connected ) {
drbd_send_param(mdev,0);
}
-
- /* Update MDF_Consistent in the meta-data */
- if ( os.s.disk != ns.s.disk && ns.s.disk > Failed ) {
- if(ns.s.disk >= Outdated ) {
- drbd_md_set_flag(mdev,MDF_Consistent);
- } else {
- drbd_md_clear_flag(mdev,MDF_Consistent);
- }
- /* TODO metadata, to support everything that
- drbd_disk_t can express... */
- }
-
}
@@ -1964,9 +1998,12 @@
buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
memset(buffer,0,512);
- flags = mdev->gen_cnt[Flags] & ~(MDF_PrimaryInd|MDF_ConnectedInd);
+ flags = mdev->gen_cnt[Flags] & ~(MDF_Consistent|MDF_PrimaryInd|
+ MDF_ConnectedInd|MDF_UpToDate);
if (mdev->state.s.role == Primary) flags |= MDF_PrimaryInd;
if (mdev->state.s.conn >= WFReportParams) flags |= MDF_ConnectedInd;
+ if (mdev->state.s.disk >= Consistent) flags |= MDF_Consistent;
+ if (mdev->state.s.disk >= UpToDate) flags |= MDF_UpToDate;
mdev->gen_cnt[Flags] = flags;
for (i = Flags; i < GEN_CNT_SIZE; i++)
@@ -2127,15 +2164,7 @@
u32 me,other;
/* FIXME
- * we should not only rely on the consistent bit, but at least check
- * whether the rest of the gencounts is plausible, to detect a previous
- * split brain situation, and refuse anything until we are told
- * otherwise!
- *
- * And we should refuse to become SyncSource if we are not consistent!
- *
- * though DRBD is not to blame for it,
- * someone eventually will try to blame it ...
+ * Take the UpToDate flag into account.
*/
me=mdev->gen_cnt[Flags] & MDF_Consistent;
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_receiver.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -1102,7 +1102,7 @@
list_add(&e->w.list,&mdev->read_ee);
spin_unlock_irq(&mdev->ee_lock);
- if(!inc_local(mdev) || (mdev->gen_cnt[Flags] & MDF_Consistent) == 0) {
+ if(!inc_local(mdev) || mdev->state.s.disk < UpToDate ) {
if (DRBD_ratelimit(5*HZ,5))
ERR("Can not satisfy peer's read request, no local data.\n");
drbd_send_ack(mdev,NegDReply,e);
@@ -1206,7 +1206,7 @@
drbd_dump_md(mdev,p,0);
// INFO("have_good=%d sync=%d\n", have_good, sync);
- if (have_good > 0 && !drbd_md_test_flag(mdev,MDF_Consistent)) {
+ if (have_good > 0 && mdev->state.s.disk < Consistent ) {
/* doh. I cannot become SyncSource when I am inconsistent!
*/
ERR("I shall become SyncSource, but I am inconsistent!\n");
@@ -1290,8 +1290,7 @@
{
Drbd_Parameter_Packet *p = (Drbd_Parameter_Packet*)h;
drbd_conns_t nconn;
- drbd_disks_t npdsk;
- drbd_state_t ns;
+ drbd_state_t ns,peer_state;
int consider_sync,rv;
sector_t p_size;
@@ -1388,16 +1387,6 @@
(unsigned long)mdev->lo_usize);
}
-
- if(p_size ) {
- npdsk = Inconsistent;
- if (be32_to_cpu(p->gen_cnt[Flags]) & MDF_Consistent) {
- npdsk = Consistent;
- }
- } else {
- npdsk = Diskless;
- }
-
if (mdev->state.s.conn == WFReportParams) {
INFO("Connection established.\n");
}
@@ -1408,11 +1397,13 @@
return FALSE;
}
+ peer_state.i = be32_to_cpu(p->state);
+
spin_lock_irq(&mdev->req_lock);
ns.i = mdev->state.i;
ns.s.conn = nconn;
- ns.s.peer = be32_to_cpu(p->state);
- ns.s.pdsk = npdsk;
+ ns.s.peer = peer_state.s.role;
+ ns.s.pdsk = peer_state.s.disk;
rv = _drbd_set_state(mdev,ns,ChgStateVerbose);
spin_unlock_irq(&mdev->req_lock);
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_req.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -144,7 +144,7 @@
unsigned long sbnr,ebnr,bnr;
sector_t esector, nr_sectors;
- if (drbd_md_test_flag(mdev,MDF_Consistent)) return 1;
+ if (mdev->state.s.disk == UpToDate) return 1;
nr_sectors = drbd_get_capacity(mdev->this_bdev);
esector = sector + (size>>9) -1;
@@ -255,7 +255,7 @@
dec_local(mdev);
}
}
- remote = !local && mdev->state.s.pdsk >= Consistent;
+ remote = !local && mdev->state.s.pdsk >= UpToDate;//Consistent;
} else {
remote = 1;
}
Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_strings.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -64,6 +64,7 @@
[3] = "Refusing to make peer Primary without data",
[4] = "Refusing to be inconsistent on both nodes",
[5] = "Refusing to be syncing and diskless",
+ [6] = "Refusing to be Outdated while Connected",
};
const char* conns_to_name(drbd_conns_t s) {
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/drbd_worker.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -401,8 +401,8 @@
mdev->rs_paused = 0;
drbd_request_state(mdev,NS3(conn,Connected,
- disk,Consistent,
- pdsk,Consistent));
+ disk,UpToDate,
+ pdsk,UpToDate));
drbd_md_write(mdev);
@@ -711,14 +711,7 @@
} else if (side == SyncSource) {
r = drbd_request_state(mdev,NS2(conn,SyncSource,
pdsk,Inconsistent));
- /* If we are SyncSource we must be consistent.
- * FIXME this should be an assertion only,
- * otherwise it masks a logic bug somewhere else...
- */
- ERR_IF (!drbd_md_test_flag(mdev,MDF_Consistent)) {
- // FIXME this is actually a BUG()!
- drbd_md_set_flag(mdev,MDF_Consistent);
- }
+ D_ASSERT(mdev->state.s.disk == UpToDate);
}
if(r != 1) return;
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/linux/drbd.h 2004-11-12 11:51:55 UTC (rev 1636)
@@ -204,8 +204,8 @@
Diskless,
Failed, /* Becomes Diskless as soon as we told it the peer */
Inconsistent,
+ Consistent, /* Might be Outdated, might be UpToDate ... */
Outdated,
- Consistent, /* Might be outdated, might be UpToDate ... */
UpToDate,
disk_mask=7
} drbd_disks_t;
@@ -270,6 +270,7 @@
#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 _IO ( DRBD_IOCTL_LETTER, 0x15 )
#endif
Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/drbd/linux/drbd_config.h 2004-11-12 11:51:55 UTC (rev 1636)
@@ -23,7 +23,7 @@
extern const char * drbd_buildtag(void);
#define REL_VERSION "0.8-pre1"
-#define API_VERSION 77
+#define API_VERSION 80
#define PRO_VERSION 74
//#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces
Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/user/drbdadm_main.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -126,6 +126,7 @@
{ "secondary", adm_generic_s,"secondary" ,1,1 },
{ "invalidate", adm_generic_l,"invalidate" ,1,1 },
{ "invalidate_remote", adm_generic_l,"invalidate_remote",1,1 },
+ { "outdate", adm_generic_s,"outdate" ,1,1 },
{ "resize", adm_resize, 0 ,1,1 },
{ "syncer", adm_syncer, 0 ,1,1 },
{ "adjust", adm_adjust, 0 ,1,1 },
Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/user/drbdmeta.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -84,11 +84,13 @@
__MDF_PrimaryInd,
__MDF_ConnectedInd,
__MDF_FullSync,
+ __MDF_UpToDate,
};
#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_UpToDate (1<<__MDF_UpToDate)
enum MetaDataIndex {
Flags, /* Consistency flag,connected-ind,primary-ind */
@@ -180,14 +182,32 @@
void md_disk_06_to_cpu(struct md_cpu *cpu, const struct md_on_disk_06 *disk)
{
int i;
+ u32 flags;
+
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);
+
+ /* 06 does not have the UpToDate flag, set it according to
+ the Consistent Flag */
+ flags = cpu->gc[Flags];
+ if( flags & MDF_Consistent) flags = flags | MDF_UpToDate;
+ cpu->gc[Flags]=flags;
}
-void md_cpu_to_disk_06(struct md_on_disk_06 *disk, const struct md_cpu *cpu)
+void md_cpu_to_disk_06(struct md_on_disk_06 *disk, struct md_cpu *cpu)
{
int i;
+ u32 flags;
+
+ /* Commulate the UpToDate flag into the consistent flag. */
+ flags = cpu->gc[Flags];
+ if(!((flags & MDF_Consistent) && (flags & MDF_UpToDate))) {
+ flags &= ~MDF_Consistent;
+ }
+ flags &= ~MDF_UpToDate;
+ cpu->gc[Flags]=flags;
+
for (i = 0; i < GEN_CNT_SIZE; i++)
disk->gc[i].be = cpu_to_be32(cpu->gc[i]);
disk->magic.be = cpu_to_be32(cpu->magic);
@@ -220,6 +240,7 @@
void md_disk_07_to_cpu(struct md_cpu *cpu, const struct md_on_disk_07 *disk)
{
int i;
+ u32 flags;
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);
@@ -228,11 +249,27 @@
cpu->al_offset = be32_to_cpu(disk->al_offset.be);
cpu->al_nr_extents = be32_to_cpu(disk->al_nr_extents.be);
cpu->bm_offset = be32_to_cpu(disk->bm_offset.be);
+
+ /* 07 does not have the UpToDate flag, set it according to
+ the Consistent Flag */
+ flags = cpu->gc[Flags];
+ if( flags & MDF_Consistent) flags = flags | MDF_UpToDate;
+ cpu->gc[Flags]=flags;
}
-void md_cpu_to_disk_07(struct md_on_disk_07 *disk, const struct md_cpu *cpu)
+void md_cpu_to_disk_07(struct md_on_disk_07 *disk, struct md_cpu *cpu)
{
int i;
+ u32 flags;
+
+ /* Commulate the UpToDate flag into the consistent flag. */
+ flags = cpu->gc[Flags];
+ if(!((flags & MDF_Consistent) && (flags & MDF_UpToDate))) {
+ flags &= ~MDF_Consistent;
+ }
+ flags &= ~MDF_UpToDate;
+ cpu->gc[Flags]=flags;
+
disk->la_kb.be = cpu_to_be64(cpu->la_sect >> 1);
for (i = 0; i < GEN_CNT_SIZE; i++)
disk->gc[i].be = cpu_to_be32(cpu->gc[i]);
@@ -596,7 +633,7 @@
void printf_gc(const struct md_cpu *md)
{
- printf("%d:%d:%d:%d:%d:%d:%d:%d\n",
+ printf("%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
md->gc[Flags] & MDF_Consistent ? 1 : 0,
md->gc[HumanCnt],
md->gc[TimeoutCnt],
@@ -604,7 +641,8 @@
md->gc[ArbitraryCnt],
md->gc[Flags] & MDF_PrimaryInd ? 1 : 0,
md->gc[Flags] & MDF_ConnectedInd ? 1 : 0,
- md->gc[Flags] & MDF_FullSync ? 1 : 0);
+ md->gc[Flags] & MDF_FullSync ? 1 : 0,
+ md->gc[Flags] & MDF_UpToDate ? 1 : 0);
}
/******************************************
@@ -1053,16 +1091,17 @@
return -1;
printf("\n"
- " WantFullSync |\n"
- " ConnectedInd | |\n"
- " lastState | | |\n"
- " ArbitraryCnt | | | |\n"
- " ConnectedCnt | | | | |\n"
- " TimeoutCnt | | | | | |\n"
- " HumanCnt | | | | | | |\n"
- "Consistent | | | | | | | |\n"
- " --------+-----+-----+-----+-----+-----+-----+-----+\n"
- " %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s \n"
+ " UpToDate |\n"
+ " WantFullSync | |\n"
+ " ConnectedInd | | |\n"
+ " lastState | | | |\n"
+ " ArbitraryCnt | | | | |\n"
+ " ConnectedCnt | | | | | |\n"
+ " TimeoutCnt | | | | | | |\n"
+ " HumanCnt | | | | | | | |\n"
+ "Consistent | | | | | | | | |\n"
+ " --------+-----+-----+-----+-----+-----+-----+-----+-----+\n"
+ " %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s | %3s \n"
"\n",
cfg->md.gc[Flags] & MDF_Consistent ? "1/c" : "0/i",
cfg->md.gc[HumanCnt],
@@ -1071,8 +1110,10 @@
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");
+ cfg->md.gc[Flags] & MDF_FullSync ? "1/y" : "0/n",
+ cfg->md.gc[Flags] & MDF_UpToDate ? "1/y" : "0/n");
+
if (cfg->md.la_sect) {
printf("last agreed size: %s\n",
ppsize(ppb, cfg->md.la_sect >> 1));
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2004-11-12 08:42:23 UTC (rev 1635)
+++ trunk/user/drbdsetup.c 2004-11-12 11:51:55 UTC (rev 1636)
@@ -105,6 +105,7 @@
int cmd_net_conf(int drbd_fd,char** argv,int argc,struct option *options);
int cmd_disk_conf(int drbd_fd,char** argv,int argc,struct option *options);
int cmd_disk_size(int drbd_fd,char** argv,int argc,struct option *options);
+int cmd_outdate(int drbd_fd,char** argv,int argc,struct option *options);
int cmd_disconnect(int drbd_fd,char** argv,int argc,struct option *options);
int cmd_show(int drbd_fd,char** argv,int argc,struct option *options);
int cmd_syncer(int drbd_fd,char** argv,int argc,struct option *options);
@@ -168,6 +169,7 @@
(struct option[]) {
{ "size", required_argument, 0, 'd' },
{ 0, 0, 0, 0 } } },
+ {"outdate", cmd_outdate, 0, 0, },
{"disconnect", cmd_disconnect, 0, 0, },
{"state", cmd_state, 0, 0, },
{"cstate", cmd_cstate, 0, 0, },
@@ -960,6 +962,22 @@
return 0;
}
+int cmd_outdate(int drbd_fd,char** argv,int argc,struct option *options)
+{
+ int err;
+
+ err=ioctl(drbd_fd,DRBD_IOCTL_OUTDATE_DISK);
+ if(err)
+ {
+ err=errno;
+ PERROR("ioctl(,OUTDATE_DISK,) failed");
+ if(err==EISCONN)
+ fprintf(stderr,"Only possible when not connected to the peer.\n");
+ return 20;
+ }
+ return 0;
+}
+
int cmd_down(int drbd_fd,char** argv,int argc,struct option *options)
{
int err;
More information about the drbd-cvs
mailing list