[DRBD-cvs] svn commit by phil - r2395 - in trunk: . drbd drbd/linux
user - * Implemented the last two missing options in the netli
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Sun Sep 10 14:02:55 CEST 2006
Author: phil
Date: 2006-09-10 14:02:54 +0200 (Sun, 10 Sep 2006)
New Revision: 2395
Modified:
trunk/ROADMAP
trunk/drbd/drbd_nl.c
trunk/drbd/linux/drbd_nl.h
trunk/user/drbdsetup.c
Log:
* Implemented the last two missing options in the netlink based
drbdsetup. --wfc-timeout and --degr-wfc-timeout for the wait-*
commands
* Fixed a bug in drbdsetup, where it assumed that the enum's of
handler-names are continous.
I guess drbdsetup(netlink) is not usable.
Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP 2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/ROADMAP 2006-09-10 12:02:54 UTC (rev 2395)
@@ -442,7 +442,7 @@
Things to do:
* Locking in userspace, to prevent multiple instances of drbdsetup
- * The timeout options of wait-connect and wait-sync are still missing.
+ * Think about locking in kernel space ( device_mutex? )
80% DONE
Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c 2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/drbd/drbd_nl.c 2006-09-10 12:02:54 UTC (rev 2395)
@@ -1368,6 +1368,24 @@
return (int)((char*)tl - (char*)reply->tag_list);
}
+
+STATIC int drbd_nl_get_timeout_flag(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+ struct drbd_nl_cfg_reply *reply)
+{
+ unsigned short *tl;
+
+ tl = reply->tag_list;
+
+ // This is a hand crafted add tag ;)
+ *tl++ = T_use_degraded;
+ *tl++ = sizeof(char);
+ *((char*)tl) = test_bit(USE_DEGR_WFC_T,&mdev->flags) ? 1 : 0 ;
+ tl=(unsigned short*)((char*)tl + sizeof(char));
+ *tl++ = TT_END;
+
+ return (int)((char*)tl - (char*)reply->tag_list);
+}
+
STATIC drbd_dev *ensure_mdev(struct drbd_nl_cfg_req *nlp)
{
drbd_dev *mdev;
@@ -1428,6 +1446,9 @@
sizeof(struct get_state_tag_len_struct) },
[ P_get_uuids ] = { &drbd_nl_get_uuids,
sizeof(struct get_uuids_tag_len_struct) },
+ [ P_get_timeout_flag ] = { &drbd_nl_get_timeout_flag,
+ sizeof(struct get_timeout_flag_tag_len_struct)},
+
};
void drbd_connector_callback(void *data)
@@ -1497,7 +1518,7 @@
unsigned short *tl = reply->tag_list;
static atomic_t seq = ATOMIC_INIT(2); // two.
- WARN("drbd_bcast_state() got called\n");
+ // WARN("drbd_bcast_state() got called\n");
tl = get_state_to_tags(mdev,(struct get_state*)&mdev->state,tl);
*tl++ = TT_END; /* Close the tag list */
Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h 2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/drbd/linux/drbd_nl.h 2006-09-10 12:02:54 UTC (rev 2395)
@@ -78,6 +78,10 @@
INTEGER( 35, T_MAY_IGNORE, uuids_flags)
)
+PACKET(get_timeout_flag,
+ BIT( 36, T_MAY_IGNORE, use_degraded)
+)
+
#undef PACKET
#undef INTEGER
#undef INT64
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/user/drbdsetup.c 2006-09-10 12:02:54 UTC (rev 2395)
@@ -45,6 +45,7 @@
#include <string.h>
#include <getopt.h>
#include <stdlib.h>
+#include <sys/time.h>
#include <time.h>
#include <linux/netlink.h>
@@ -224,7 +225,7 @@
DRBD_ ## D ## _DEF } }
#define EB conv_bit, show_bit, bit_opt_usage, { }
#define ES conv_string, show_string, string_opt_usage, { }
-#define CLOSE_OPTIONS { NULL,0,0,NULL,NULL,NULL, { } }, }} }, },
+#define CLOSE_OPTIONS { NULL,0,0,NULL,NULL,NULL, { } }
#define F_CONFIG_CMD generic_config_cmd, config_usage
#define F_GET_CMD generic_get_cmd, get_usage
@@ -234,7 +235,7 @@
{"primary", P_primary, F_CONFIG_CMD, {{ NULL,
(struct drbd_option[]) {
{ "overwrite-data-of-peer",'o',T_overwrite_peer, EB },
- CLOSE_OPTIONS
+ CLOSE_OPTIONS }} }, },
{"secondary", P_secondary, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -248,7 +249,7 @@
{ "size",'d', T_disk_size, EN(DISK_SIZE_SECT,'s') },
{ "on-io-error",'e', T_on_io_error, EH(on_error,ON_IO_ERROR) },
{ "fencing",'f', T_fencing, EH(fencing_n,FENCING) },
- CLOSE_OPTIONS
+ CLOSE_OPTIONS }} }, },
{"detach", P_detach, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -274,21 +275,21 @@
{ "after-sb-1pri",'B', T_after_sb_1p,EH(asb1p_n,AFTER_SB_1P) },
{ "after-sb-2pri",'C', T_after_sb_2p,EH(asb2p_n,AFTER_SB_2P) },
{ "discard-my-data",'D', T_want_lose, EB },
- CLOSE_OPTIONS
+ CLOSE_OPTIONS }} }, },
{"disconnect", P_disconnect, F_CONFIG_CMD, {{NULL, NULL}} },
{"resize", P_resize, F_CONFIG_CMD, {{ NULL,
(struct drbd_option[]) {
{ "size",'s',T_resize_size, EN(DISK_SIZE_SECT,'s') },
- CLOSE_OPTIONS
+ CLOSE_OPTIONS }} }, },
{"syncer", P_syncer_conf, F_CONFIG_CMD, {{ NULL,
(struct drbd_option[]) {
{ "rate",'r',T_rate, EN(RATE,'k') },
{ "after",'a',T_after, EN(AFTER,1) },
{ "al-extents",'e',T_al_extents, EN(AL_EXTENTS,1) },
- CLOSE_OPTIONS
+ CLOSE_OPTIONS }} }, },
{"invalidate", P_invalidate, F_CONFIG_CMD, {{ NULL, NULL }} },
{"invalidate-remote", P_invalidate_peer, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -307,11 +308,21 @@
{"events", 0, F_EVENTS_CMD, { .ep = {
(struct option[]) {
{ "unfiltered", no_argument, 0, 'u' },
- { "all-devices",no_argument, 0, 'd' },
+ { "all-devices",no_argument, 0, 'a' },
{ 0, 0, 0, 0 } },
print_state } } },
- {"wait-connect", 0, F_EVENTS_CMD, {.ep = {NULL,w_connected_state} } },
- {"wait-sync", 0, F_EVENTS_CMD, {.ep = {NULL,w_synced_state} } },
+ {"wait-connect", 0, F_EVENTS_CMD, {.ep = {
+ (struct option[]) {
+ { "wfc-timeout",required_argument, 0, 't' },
+ { "degr-wfc-timeout",required_argument,0,'d'},
+ { 0, 0, 0, 0 } },
+ w_connected_state} } },
+ {"wait-sync", 0, F_EVENTS_CMD, {.ep = {
+ (struct option[]) {
+ { "wfc-timeout",required_argument, 0, 't' },
+ { "degr-wfc-timeout",required_argument,0,'d'},
+ { 0, 0, 0, 0 } },
+ w_synced_state} } },
};
#define EM(C) [ C - RetCodeBase ]
@@ -609,18 +620,18 @@
{
const char** handler_names = od->handler_param.handler_names;
const int number_of_handlers = od->handler_param.number_of_handlers;
- int i,nr;
+ int i,nr=-1;
for(i=0;i<number_of_handlers;i++) {
+ if(handler_names[i]==NULL) continue;
if(strcmp(arg,handler_names[i])==0) {
- nr = i;
- break;
+ add_tag(tl,od->tag,&nr,sizeof(i));
+ return 0;
}
}
-
- add_tag(tl,od->tag,&nr,sizeof(nr));
-
- return 0;
+
+ fprintf(stderr, "Handler not known\n");
+ return 20;
}
int conv_string(struct drbd_option *od, struct drbd_tag_list *tl, char* arg)
@@ -753,7 +764,7 @@
add_tag(tl,TT_END,NULL,0); // close the tag list
if(rv == 0) {
- // dump_tag_list(tl->tag_list_start);
+ //dump_tag_list(tl->tag_list_start);
sk_nl = open_cn();
if(sk_nl < 0) return 20;
@@ -897,6 +908,18 @@
return 0;
}
+char consume_tag_bit(enum drbd_tags tag, unsigned short *tlc)
+{
+ unsigned short *tp;
+ tp = look_for_tag(tlc,tag);
+ if(tp) {
+ *tp++ = TT_REMOVED;
+ tp++;
+ return *(char *)tp;
+ }
+ return 0;
+}
+
int generic_get_cmd(struct drbd_cmd *cm, int minor, int argc,
char **argv __attribute((unused)))
{
@@ -1080,12 +1103,10 @@
int print_state(unsigned int seq, int minor, drbd_state_t ns)
{
- /*
- char stime[20];
- time_t now;
- time(&now);
- strftime(stime,20,"%a %e %T",gmtime(&now));
- */
+ /*char stime[20];
+ time_t now;
+ time(&now);
+ strftime(stime,20,"%a %e %T",gmtime(&now)); */
printf("%u ST %d { cs:%s st:%s/%s ds:%s/%s %c%c%c%c }\n",
seq,
@@ -1127,18 +1148,41 @@
struct drbd_tag_list *tl;
struct option *lo;
unsigned int seq=0;
- int sk_nl,c,cont=1;
+ int sk_nl,c,cont=1,rr;
drbd_state_t state;
int unfiltered=0, all_devices=0;
+ int wfc_timeout=0, degr_wfc_timeout=0,timeout_ms;
+ struct pollfd pfd;
+ struct timeval before,after;
lo = cm->ep.options;
while( (c=getopt_long(argc,argv,make_optstring(lo,0),lo,0)) != -1 ) {
- // This code block is actually only relevant for the "events"
- // command. not for wait-connect, or wait-sync.
switch(c) {
case 'u': unfiltered=1; break;
- case 'd': all_devices=1; break;
+ case 'a': all_devices=1; break;
+ case 't':
+ wfc_timeout=m_strtoll(optarg,1);
+ if(DRBD_WFC_TIMEOUT_MIN > wfc_timeout ||
+ wfc_timeout > DRBD_WFC_TIMEOUT_MAX) {
+ fprintf(stderr, "wfc_timeout => %d"
+ " out of range [%d..%d]\n",
+ wfc_timeout, DRBD_WFC_TIMEOUT_MIN,
+ DRBD_WFC_TIMEOUT_MAX);
+ return 20;
+ }
+ break;
+ case 'd':
+ degr_wfc_timeout=m_strtoll(optarg,1);
+ if(DRBD_DEGR_WFC_TIMEOUT_MIN > degr_wfc_timeout ||
+ degr_wfc_timeout > DRBD_DEGR_WFC_TIMEOUT_MAX) {
+ fprintf(stderr, "degr_wfc_timeout => %d"
+ " out of range [%d..%d]\n",
+ degr_wfc_timeout, DRBD_DEGR_WFC_TIMEOUT_MIN,
+ DRBD_DEGR_WFC_TIMEOUT_MAX);
+ return 20;
+ }
+ break;
}
}
@@ -1146,15 +1190,37 @@
fprintf(stderr,"Ignoring excess arguments\n");
}
+ tl = create_tag_list(2);
+ add_tag(tl,TT_END,NULL,0); // close the tag list
+
sk_nl = open_cn();
if(sk_nl < 0) return 20;
+ // Find out which timeout value to use.
+ send_tag_list_cn(sk_nl,tl,P_get_timeout_flag,minor,0);
+ receive_cn(sk_nl, (struct nlmsghdr*)buffer, 4096 );
+ cn_reply = (struct cn_msg *)NLMSG_DATA(buffer);
+ reply = (struct drbd_nl_cfg_reply *)cn_reply->data;
+ rr = consume_tag_bit(T_use_degraded,reply->tag_list);
+ timeout_ms= 1000 * ( rr ? degr_wfc_timeout : wfc_timeout) - 1;
+
// ask for the current state before waiting for state updates...
- tl = create_tag_list(2);
- add_tag(tl,TT_END,NULL,0); // close the tag list
send_tag_list_cn(sk_nl,tl,P_get_state,minor,0);
do {
+ pfd.fd = sk_nl;
+ pfd.events = POLLIN;
+
+ // printf("calling poll(,,%d)\n",timeout_ms);
+ gettimeofday(&before,NULL);
+ rr = poll(&pfd,1,timeout_ms);
+ if(rr == 0) return 5; // timeout expired.
+ gettimeofday(&after,NULL);
+
+ if(timeout_ms > 0 ) {
+ timeout_ms -= ( (after.tv_sec - before.tv_sec) * 1000 +
+ (after.tv_usec - before.tv_usec) / 1000 );
+ }
receive_cn(sk_nl, (struct nlmsghdr*)buffer, 4096 );
cn_reply = (struct cn_msg *)NLMSG_DATA(buffer);
More information about the drbd-cvs
mailing list