[DRBD-cvs] svn commit by phil - r2390 - in trunk: drbd drbd/linux
user - Implemented the state, cstate, dstate as well the get-u
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Mon Aug 28 17:18:29 CEST 2006
Author: phil
Date: 2006-08-28 17:18:27 +0200 (Mon, 28 Aug 2006)
New Revision: 2390
Modified:
trunk/drbd/drbd_nl.c
trunk/drbd/linux/drbd.h
trunk/drbd/linux/drbd_nl.h
trunk/user/drbdsetup.c
Log:
Implemented the state, cstate, dstate as well the get-uuid and
show-uuid commands
Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c 2006-08-28 12:16:33 UTC (rev 2389)
+++ trunk/drbd/drbd_nl.c 2006-08-28 15:18:27 UTC (rev 2390)
@@ -1538,11 +1538,107 @@
rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
+ kfree(cn_reply);
return;
fail:
drbd_nl_send_reply(req, retcode);
}
+STATIC void drbd_nl_get_state (void *data)
+{
+ struct cn_msg *req = data;
+ struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
+ drbd_dev *mdev;
+ int retcode=NoError,rr;
+ struct drbd_nl_cfg_reply* reply;
+ struct cn_msg *cn_reply;
+ unsigned short *tl;
+ int size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply) +
+ get_state_tag_size;
+
+ if( !(mdev = ensure_mdev(nlp)) ) {
+ retcode=MinorNotKnown;
+ goto fail;
+ }
+
+ if( !(cn_reply = kmalloc(size,GFP_KERNEL)) ) {
+ retcode=KMallocFailed;
+ goto fail;
+ }
+ reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
+ tl = reply->tag_list;
+
+ tl = get_state_to_tags(mdev,(struct get_state*)&mdev->state,tl);
+ *tl++ = TT_END; /* Close the tag list */
+
+ cn_reply->id = req->id;
+ cn_reply->seq = req->seq;
+ cn_reply->ack = req->ack + 1;
+ cn_reply->len = (char*)tl - (char *)reply;
+ cn_reply->flags = 0;
+
+ reply->minor = nlp->drbd_minor;
+ reply->ret_code = retcode;
+
+ rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
+ if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
+ kfree(cn_reply);
+ return;
+ fail:
+ drbd_nl_send_reply(req, retcode);
+}
+
+STATIC void drbd_nl_get_uuids (void *data)
+{
+ struct cn_msg *req = data;
+ struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
+ drbd_dev *mdev;
+ int retcode=NoError,rr;
+ struct drbd_nl_cfg_reply* reply;
+ struct cn_msg *cn_reply;
+ unsigned short *tl;
+ int size = sizeof(struct cn_msg) + sizeof(struct drbd_nl_cfg_reply) +
+ get_uuids_tag_size;
+
+ if( !(mdev = ensure_mdev(nlp)) ) {
+ retcode=MinorNotKnown;
+ goto fail;
+ }
+
+ if( !(cn_reply = kmalloc(size,GFP_KERNEL)) ) {
+ retcode=KMallocFailed;
+ goto fail;
+ }
+ reply = (struct drbd_nl_cfg_reply*) cn_reply->data;
+ tl = reply->tag_list;
+
+ if(inc_local(mdev)) {
+ // This is a hand crafted add tag ;)
+ *tl++ = T_uuids;
+ *tl++ = UUID_SIZE*sizeof(u64);
+ memcpy(tl,mdev->bc->md.uuid,UUID_SIZE*sizeof(u64));
+ tl= (unsigned short*)((char*)tl + UUID_SIZE*sizeof(u64));
+ dec_local(mdev);
+ }
+ *tl++ = TT_END; /* Close the tag list */
+
+ cn_reply->id = req->id;
+ cn_reply->seq = req->seq;
+ cn_reply->ack = req->ack + 1;
+ cn_reply->len = (char*)tl - (char *)reply;
+ cn_reply->flags = 0;
+
+ reply->minor = nlp->drbd_minor;
+ reply->ret_code = retcode;
+
+ rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
+ if(rr) printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
+ kfree(cn_reply);
+ return;
+ fail:
+ drbd_nl_send_reply(req, retcode);
+}
+
// Generate the packet_number to callback table...
typedef void (*cn_handler)(void*);
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2006-08-28 12:16:33 UTC (rev 2389)
+++ trunk/drbd/linux/drbd.h 2006-08-28 15:18:27 UTC (rev 2390)
@@ -257,7 +257,7 @@
struct drbd_nl_cfg_reply {
int minor;
int ret_code; // enum ret_code or set_st_err_t
- unsigned short tag_list[]; // only used with get_config()...
+ unsigned short tag_list[]; // only used with get_* calls
};
#endif
Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h 2006-08-28 12:16:33 UTC (rev 2389)
+++ trunk/drbd/linux/drbd_nl.h 2006-08-28 15:18:27 UTC (rev 2390)
@@ -69,7 +69,15 @@
PACKET(resume_io, )
PACKET(outdate, )
PACKET(get_config, )
+PACKET(get_state,
+ INTEGER( 33, T_MAY_IGNORE, state_i)
+)
+PACKET(get_uuids,
+ STRING( 34, T_MAY_IGNORE, uuids, (UUID_SIZE*sizeof(__u64)))
+ INTEGER( 35, T_MAY_IGNORE, uuids_flags)
+)
+
#undef PACKET
#undef INTEGER
#undef INT64
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2006-08-28 12:16:33 UTC (rev 2389)
+++ trunk/user/drbdsetup.c 2006-08-28 15:18:27 UTC (rev 2390)
@@ -104,8 +104,16 @@
const char* cmd;
const int packet_id;
int (*function)(struct drbd_cmd *, int, int, char **);
- struct drbd_argument *args;
- struct drbd_option *options;
+ union {
+ struct {
+ struct drbd_argument *args;
+ struct drbd_option *options;
+ } cp;
+ struct {
+ int (*show_function)(struct drbd_cmd *, int,
+ unsigned short* );
+ } gp;
+ };
};
@@ -121,18 +129,28 @@
// command functions
int generic_config_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv);
-int show_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv);
int down_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv);
+int generic_get_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv);
+
+// sub commands for generic_get_cmd
+int show_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl);
+int state_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl);
+int cstate_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl);
+int dstate_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl);
+int uuids_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl);
+
// convert functions for arguments
int conv_block_dev(struct drbd_argument *ad, struct drbd_tag_list *tl, char* arg);
int conv_md_idx(struct drbd_argument *ad, struct drbd_tag_list *tl, char* arg);
int conv_address(struct drbd_argument *ad, struct drbd_tag_list *tl, char* arg);
int conv_protocol(struct drbd_argument *ad, struct drbd_tag_list *tl, char* arg);
+
// convert functions for options
int conv_numeric(struct drbd_option *od, struct drbd_tag_list *tl, char* arg);
int conv_handler(struct drbd_option *od, struct drbd_tag_list *tl, char* arg);
int conv_bit(struct drbd_option *od, struct drbd_tag_list *tl, char* arg);
int conv_string(struct drbd_option *od, struct drbd_tag_list *tl, char* arg);
+
// show functions for options
void show_numeric(struct drbd_option *od, unsigned short* tp);
void show_handler(struct drbd_option *od, unsigned short* tp);
@@ -184,14 +202,14 @@
#define ES conv_string, show_string, { }
struct drbd_cmd commands[] = {
- {"primary", P_primary, generic_config_cmd, NULL,
+ {"primary", P_primary, generic_config_cmd, {{ NULL,
(struct drbd_option[]) {
{ "overwrite-data-of-peer",'o',T_overwrite_peer, EB },
- { NULL,0,0,NULL,NULL, { } }, }, },
+ { NULL,0,0,NULL,NULL, { } }, }} }, },
- {"secondary", P_secondary, generic_config_cmd, NULL, NULL },
+ {"secondary", P_secondary, generic_config_cmd, {{NULL, NULL}} },
- {"disk", P_disk_conf, generic_config_cmd,
+ {"disk", P_disk_conf, generic_config_cmd, {{
(struct drbd_argument[]) {
{ "lower_dev", T_backing_dev, conv_block_dev },
{ "meta_data_dev", T_meta_dev, conv_block_dev },
@@ -201,11 +219,11 @@
{ "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) },
- { NULL,0,0,NULL,NULL, { } }, }, },
+ { NULL,0,0,NULL,NULL, { } }, }, }} },
- {"detach", P_detach, generic_config_cmd, NULL, NULL },
+ {"detach", P_detach, generic_config_cmd, {{NULL, NULL}} },
- {"net", P_net_conf, generic_config_cmd,
+ {"net", P_net_conf, generic_config_cmd, {{
(struct drbd_argument[]) {
{ "local_addr", T_my_addr, conv_address },
{ "remote_addr", T_peer_addr, conv_address },
@@ -227,38 +245,36 @@
{ "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 },
- { NULL,0,0,NULL,NULL, { } }, }, },
+ { NULL,0,0,NULL,NULL, { } }, }, }} },
- {"disconnect", P_disconnect, generic_config_cmd, NULL, NULL },
+ {"disconnect", P_disconnect, generic_config_cmd, {{NULL, NULL}} },
- {"resize", P_resize, generic_config_cmd, NULL,
+ {"resize", P_resize, generic_config_cmd, {{ NULL,
(struct drbd_option[]) {
{ "size",'s',T_resize_size, EN(DISK_SIZE_SECT,'s') },
- { NULL,0,0,NULL,NULL, { } }, }, },
+ { NULL,0,0,NULL,NULL, { } }, }, }} },
- {"syncer", P_syncer_conf, generic_config_cmd, NULL,
+ {"syncer", P_syncer_conf, generic_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) },
- { NULL,0,0,NULL,NULL, { } }, }, },
+ { NULL,0,0,NULL,NULL, { } }, }, }} },
- {"invalidate", P_invalidate, generic_config_cmd, NULL, NULL },
- {"invalidate-remote", P_invalidate_peer, generic_config_cmd, NULL, NULL },
- {"pause-sync", P_pause_sync, generic_config_cmd, NULL, NULL },
- {"resume-sync", P_resume_sync, generic_config_cmd, NULL, NULL },
- {"suspend-io", P_suspend_io, generic_config_cmd, NULL, NULL },
- {"resume-io", P_resume_io, generic_config_cmd, NULL, NULL },
- {"outdate", P_outdate, generic_config_cmd, NULL, NULL },
- {"down", 0, down_cmd, NULL, NULL },
-
- /*
- {"state", cmd_state, 0, 0, },
- {"cstate", cmd_cstate, 0, 0, },
- {"dstate", cmd_dstate, 0, 0, },
- {"show-gi", cmd_show_gi, 0, 0, },
- {"get-gi", cmd_get_gi, 0, 0, }, */
- {"show", P_get_config, show_cmd, NULL, NULL },
+ {"invalidate", P_invalidate, generic_config_cmd, {{ NULL, NULL }} },
+ {"invalidate-remote", P_invalidate_peer, generic_config_cmd, {{NULL, NULL}} },
+ {"pause-sync", P_pause_sync, generic_config_cmd, {{ NULL, NULL }} },
+ {"resume-sync", P_resume_sync, generic_config_cmd, {{ NULL, NULL }} },
+ {"suspend-io", P_suspend_io, generic_config_cmd, {{ NULL, NULL }} },
+ {"resume-io", P_resume_io, generic_config_cmd, {{ NULL, NULL }} },
+ {"outdate", P_outdate, generic_config_cmd, {{ NULL, NULL }} },
+ {"down", 0, down_cmd, { {NULL, NULL }} },
+ {"state", P_get_state, generic_get_cmd, { .gp={ state_scmd} } },
+ {"cstate", P_get_state, generic_get_cmd, {.gp={ cstate_scmd} } },
+ {"dstate", P_get_state, generic_get_cmd, {.gp={ dstate_scmd} } },
+ {"show-gi", P_get_uuids, generic_get_cmd, {.gp={ uuids_scmd} }},
+ {"get-gi", P_get_uuids, generic_get_cmd, {.gp={ uuids_scmd} } },
+ {"show", P_get_config, generic_get_cmd, {.gp={ show_scmd} } },
};
#define EM(C) [ C - RetCodeBase ]
@@ -653,7 +669,7 @@
{
char buffer[ RCV_SIZE ];
struct drbd_nl_cfg_reply *reply;
- struct drbd_argument *ad = cm->args;
+ struct drbd_argument *ad = cm->cp.args;
struct drbd_option *od;
static struct option *lo;
struct drbd_tag_list *tl;
@@ -674,10 +690,10 @@
ad++;
}
- lo = make_longoptions(cm->options);
+ lo = make_longoptions(cm->cp.options);
opterr=0;
while( (c=getopt_long(argc,argv,make_optstring(lo,0),lo,0)) != -1 ) {
- od = find_opt_by_short_name(cm->options,c);
+ od = find_opt_by_short_name(cm->cp.options,c);
if(od) rv |= od->convert_function(od,tl,optarg);
else {
if(c=='(') flags |= DRBD_NL_SET_DEFAULTS;
@@ -802,6 +818,20 @@
}
}
+
+const char* consume_tag_blob(enum drbd_tags tag, unsigned short *tlc,
+ unsigned int* len)
+{
+ unsigned short *tp;
+ tp = look_for_tag(tlc,tag);
+ if(tp) {
+ *tp++ = TT_REMOVED;
+ *len = *tp++;
+ return (char*)tp;
+ }
+ return NULL;
+}
+
const char* consume_tag_string(enum drbd_tags tag, unsigned short *tlc)
{
unsigned short *tp;
@@ -825,20 +855,14 @@
return 0;
}
-int show_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv __attribute((unused)))
+int generic_get_cmd(struct drbd_cmd *cm, int minor, int argc,
+ char **argv __attribute((unused)))
{
char buffer[ 4096 ];
struct drbd_tag_list *tl;
struct drbd_nl_cfg_reply *reply;
- struct sockaddr_in *addr;
- int sk_nl;
- unsigned short *rtl;
+ int sk_nl,rv;
- int idx;
- const char* str;
-
- ASSERT(cm->packet_id == P_get_config);
-
if(argc > 1) {
fprintf(stderr,"Ignoring excess arguments\n");
}
@@ -856,12 +880,26 @@
reply = (struct drbd_nl_cfg_reply *)
((struct cn_msg *)NLMSG_DATA(buffer))->data;
- rtl = reply->tag_list;
+ rv = cm->gp.show_function(cm,minor,reply->tag_list);
+ if(dump_tag_list(reply->tag_list)) {
+ printf("# Found unknown tags, you should update your\n"
+ "# userland tools\n");
+ }
+
+ return rv;
+}
+
+int show_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl)
+{
+ int idx;
+ const char* str;
+ struct sockaddr_in *addr;
+
// find all commands that have options and print those...
for ( cm = commands ; cm < commands + ARRY_SIZE(commands) ; cm++ ) {
- if(cm->options)
- print_options(cm->options, rtl, cm->cmd);
+ if(cm->cp.options)
+ print_options(cm->cp.options, rtl, cm->cmd);
}
// start of spagethi code...
@@ -907,14 +945,64 @@
printf("}\n");
}
- if(dump_tag_list(reply->tag_list)) {
- printf("# Found unknown tags, you should update your\n"
- "# userland tools\n");
- }
+ return 0;
+}
+int state_scmd(struct drbd_cmd *cm __attribute((unused)),
+ int minor __attribute((unused)),
+ unsigned short *rtl)
+{
+ drbd_state_t state;
+ state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+ printf("%s\n",roles_to_name(state.role));
return 0;
}
+int cstate_scmd(struct drbd_cmd *cm __attribute((unused)),
+ int minor __attribute((unused)),
+ unsigned short *rtl)
+{
+ drbd_state_t state;
+ state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+ printf("%s\n",conns_to_name(state.conn));
+ return 0;
+}
+
+int dstate_scmd(struct drbd_cmd *cm __attribute((unused)),
+ int minor __attribute((unused)),
+ unsigned short *rtl)
+{
+ drbd_state_t state;
+ state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+ printf("%s\n",disks_to_name(state.disk));
+ return 0;
+}
+
+int uuids_scmd(struct drbd_cmd *cm,
+ int minor __attribute((unused)),
+ unsigned short *rtl)
+{
+ __u64 *uuids;
+ int flags;
+ unsigned int len ;
+
+ uuids = (__u64 *)consume_tag_blob(T_uuids,rtl,&len);
+ flags = consume_tag_int(T_uuids_flags,rtl);
+ if( len == UUID_SIZE * sizeof(__u64)) {
+ if(!strcmp(cm->cmd,"show-gi")) {
+ dt_pretty_print_uuids(uuids,flags);
+ } else if(!strcmp(cm->cmd,"get-gi")) {
+ dt_print_uuids(uuids,flags);
+ } else {
+ ASSERT( 0 );
+ }
+ } else {
+ printf("Unexpected length of T_uuids tag. You should upgrade your\n"
+ "userland tools\n");
+ }
+ return 0;
+}
+
static struct drbd_cmd *find_cmd_by_name(const char* name)
{
unsigned int i;
@@ -927,19 +1015,18 @@
return NULL;
}
-int down_cmd(struct drbd_cmd *cm __attribute((unused)), int minor, int argc, char **argv)
+int down_cmd(struct drbd_cmd *cm, int minor, int argc, char **argv)
{
- struct drbd_cmd *cmd;
int rv = 0;
if(argc > 1) {
fprintf(stderr,"Ignoring excess arguments\n");
}
- cmd = find_cmd_by_name("disconnect");
- rv |= cmd->function(cmd,minor,argc,argv);
- cmd = find_cmd_by_name("detach");
- rv |= cmd->function(cmd,minor,argc,argv);
+ cm = find_cmd_by_name("disconnect");
+ rv |= cm->function(cm,minor,argc,argv);
+ cm = find_cmd_by_name("detach");
+ rv |= cm->function(cm,minor,argc,argv);
return rv;
}
@@ -956,7 +1043,7 @@
prevcol=col=0;
col += snprintf(line+col, maxcol-col, " %s", commands[i].cmd);
- if ((args = commands[i].args)) {
+ if ((args = commands[i].cp.args)) {
while (args->name) {
col += snprintf(line+col, maxcol-col, " %s", args->name);
args++;
@@ -968,7 +1055,7 @@
col=0;
}
prevcol=col;
- if ((options = commands[i].options)) {
+ if ((options = commands[i].cp.options)) {
while (options->name) {
if (tag_type(options->tag) == TT_BIT) {
col += snprintf(line+col, maxcol-col,
More information about the drbd-cvs
mailing list