[DRBD-cvs] svn commit by phil - r2144 - trunk/user - Finally a
_sane_ implementation of the "drbdadm adjust"
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Tue Apr 11 18:18:18 CEST 2006
Author: phil
Date: 2006-04-11 18:18:17 +0200 (Tue, 11 Apr 2006)
New Revision: 2144
Modified:
trunk/user/drbdadm.h
trunk/user/drbdadm_adjust.c
trunk/user/drbdadm_main.c
trunk/user/drbdadm_parser.c
trunk/user/drbdadm_parser.h
trunk/user/drbdadm_scanner.fl
trunk/user/drbdsetup.c
Log:
Finally a _sane_ implementation of the "drbdadm adjust" command.
Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm.h 2006-04-11 16:18:17 UTC (rev 2144)
@@ -53,9 +53,13 @@
char* name;
char* device;
char* disk;
+ int disk_major;
+ int disk_minor;
char* address;
char* port;
char* meta_disk;
+ int meta_major;
+ int meta_minor;
char* meta_index;
};
@@ -64,7 +68,8 @@
char* name;
char* value;
struct d_option* next;
- int mentioned; // for the adjust command.
+ unsigned int mentioned :1 ; // for the adjust command.
+ unsigned int is_default :1 ; // for the adjust command.
};
struct d_resource
@@ -97,6 +102,8 @@
extern void uc_node(enum usage_count_type type);
extern int adm_create_md(struct d_resource* res ,const char* cmd);
+extern void convert_discard_opt(struct d_resource* res);
+extern void convert_after_option(struct d_resource* res);
extern char* config_file;
extern int config_valid;
Modified: trunk/user/drbdadm_adjust.c
===================================================================
--- trunk/user/drbdadm_adjust.c 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm_adjust.c 2006-04-11 16:18:17 UTC (rev 2144)
@@ -28,6 +28,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -36,312 +37,176 @@
#include "drbdadm.h"
#include "drbdtool_common.h"
-/******
- This is a bit uggly.
- If you think you are clever, then consider to contribute a nicer
- implementation of adm_adjust()
+extern FILE* yyin;
+extern struct d_resource* parse_resource(char*);
-*/
-
-FILE *m_popen(int *pid,char** argv)
+static FILE *m_popen(int *pid,char** argv)
{
- int mpid;
- int pipes[2];
+ int mpid;
+ int pipes[2];
- if(pipe(pipes)) {
- perror("Creation of pipes failed");
- exit(E_exec_error);
- }
+ if(pipe(pipes)) {
+ perror("Creation of pipes failed");
+ exit(E_exec_error);
+ }
- mpid = fork();
- if(mpid == -1) {
- fprintf(stderr,"Can not fork");
- exit(E_exec_error);
- }
- if(mpid == 0) {
- close(pipes[0]); // close reading end
- dup2(pipes[1],1); // 1 = stdout
- close(pipes[1]);
- execvp(argv[0],argv);
- fprintf(stderr,"Can not exec");
- exit(E_exec_error);
- }
+ mpid = fork();
+ if(mpid == -1) {
+ fprintf(stderr,"Can not fork");
+ exit(E_exec_error);
+ }
+ if(mpid == 0) {
+ close(pipes[0]); // close reading end
+ dup2(pipes[1],1); // 1 = stdout
+ close(pipes[1]);
+ execvp(argv[0],argv);
+ fprintf(stderr,"Can not exec");
+ exit(E_exec_error);
+ }
- close(pipes[1]); // close writing end
- *pid=mpid;
- return fdopen(pipes[0],"r");
+ close(pipes[1]); // close writing end
+ *pid=mpid;
+ return fdopen(pipes[0],"r");
}
-int check_opt_b(FILE *in,char* name,struct d_option* base)
+/* option value equal? */
+static int ov_eq(char* val1, char* val2)
{
- struct d_option* o;
- char uu[2],scs[200],sn[50];
- int l,rv=0;
+ unsigned long long v1,v2;
- strcpy(sn,name);
- l=strlen(sn)-1;
- sn[l]=0;
- sprintf(scs," %*s%%[%c]\n",l,sn,name[l]);
+ if(val1 == NULL && val2 == NULL) return 1;
+ if(val1 == NULL || val2 == NULL) return 0;
- if(fscanf(in,scs,uu)>0) {
- o=find_opt(base,name);
- if(o) o->mentioned=1;
- else rv=1;
- } // else { unexpected input... }
+ if(isdigit(val1[0])) {
+ v1 = m_strtoll(val1,0);
+ v2 = m_strtoll(val2,0);
- //printf("check_opt_b(%s)=%d\n",name,rv);
- return rv;
+ return v1 == v2;
+ }
+
+ return !strcmp(val1,val2);
}
-int check_opt_d(FILE *in,char* name,char du, char* unit,struct d_option* base)
+static int opts_equal(struct d_option* conf, struct d_option* running)
{
- unsigned long ul;
- struct d_option* o;
- char uu[2];
- char scs[200];
- int rv=0;
+ struct d_option* opt;
- sprintf(scs," %s = %%lu %s (%%[d]efault)\n",name,unit);
- if(fscanf(in,scs,&ul,uu)>0) {
- o=find_opt(base,name);
- if(o) {
- o->mentioned=1;
- if(m_strtoll(o->value,du) != ul) rv=1;
- } else {
- if( uu[0] != 'd' ) rv=1;
- }
- }
- //printf("check_opt_d(%s)=%d\n",name,rv);
+ while(running) {
+ if((opt=find_opt(conf,running->name))) {
+ if(!ov_eq(running->value,opt->value)) {
+ /*printf("Value of '%s' differs: r=%s c=%s\n",
+ opt->name,running->value,opt->value);*/
+ return 0;
+ }
+ opt->mentioned=1;
+ } else {
+ if(!running->is_default) {
+ /*printf("Only in running config %s: %s\n",
+ running->name,running->value);*/
+ return 0;
+ }
+ }
+ running=running->next;
+ }
- return rv;
+ while(conf) {
+ if(conf->mentioned==0) {
+ /*printf("Only in config file %s: %s\n",
+ conf->name,conf->value);*/
+ return 0;
+ }
+ conf=conf->next;
+ }
+ return 1;
}
-int check_opt_s(FILE *in,char* name,struct d_option* base)
+static int addr_equal(struct d_resource* conf, struct d_resource* running)
{
- struct d_option* o;
- char scs[200];
- char value[200];
- int rv=0;
+ if (conf->peer == NULL && running->peer == NULL) return 1;
+ if (conf->peer == NULL || running->peer == NULL) return 0;
- sprintf(scs," %s = %%s\n",name);
- if(fscanf(in,scs,value)>0) {
- o=find_opt(base,name);
- if(o) {
- o->mentioned=1;
- if(strcmp(o->value,value)) rv=1;
- } else {
- rv=1;
- }
- }
+ return !strcmp(conf->me->address, running->me->address) &&
+ !strcmp(conf->me->port, running->me->port) &&
+ !strcmp(conf->peer->address,running->peer->address) &&
+ !strcmp(conf->peer->port, running->peer->port) ;
+}
- //printf("check_opt_s(%s)=%d [value=%s]\n",name,rv,value);
+static int proto_equal(struct d_resource* conf, struct d_resource* running)
+{
+ if (conf->protocol == NULL && running->protocol == NULL) return 1;
+ if (conf->protocol == NULL || running->protocol == NULL) return 0;
- return rv;
+ return !strcmp(conf->protocol, running->protocol);
}
-int complete(struct d_option* base)
+static int dev_eq(char* device_name, int g_major, int g_minor)
{
- int rv=0;
+ struct stat sb;
+
+ if(stat(device_name,&sb)) return 0;
- while(base) {
- if(base->mentioned == 0) {
- //printf("complete(): '%s'\n",base->name);
- rv=1;
- break;
- }
- base=base->next;
- }
+ return major(sb.st_rdev) == g_major && minor(sb.st_rdev) == g_minor;
+}
- //printf("complete()=%d\n",rv);
-
- return rv;
+/* Are both internal, or are both not internal. */
+static int int_eq(char* m_conf, char* m_running)
+{
+ return !strcmp(m_conf,"internal") == !strcmp(m_running,"internal");
}
-int m_fscanf(FILE *stream,const char *fmt, ...)
+static int disk_equal(struct d_host_info* conf, struct d_host_info* running)
{
- va_list ap;
- int rv;
+ int eq = 1;
- va_start(ap, fmt);
- rv=vfscanf(stream,fmt,ap);
- va_end(ap);
+ eq &= dev_eq(conf->disk,running->disk_major,running->disk_minor);
+ eq &= int_eq(conf->meta_disk,running->meta_disk);
+ if(!strcmp(conf->meta_disk,"internal")) return eq;
+ eq &= dev_eq(conf->meta_disk,running->meta_major,running->meta_minor);
- if(rv==0) {
- fprintf(stderr,"fscanf() faild for fmt string: %s\n",fmt);
- }
-
- return rv;
+ return eq;
}
-
-/* NOTE
- * return before waitpit is a BUG. "goto out;" instead!
- *
+/*
* calling drbdsetup again before waitpid("drbdsetup show") has a race with
* the next ioctl failing because of the zombie still holding an open_cnt on
* the drbd device. so don't do that.
*/
int adm_adjust(struct d_resource* res,char* unused __attribute((unused)))
{
- char* argv[20];
- int rv,pid,argc=0;
- FILE *in;
- char str1[255],str2[255];
- unsigned long ul1,ul2;
- struct d_option* o;
- char uu[2];
- int do_attach=0;
- int do_resize=0;
- int do_connect=0;
- int do_syncer=0;
+ char* argv[20];
+ int pid,argc=0;
+ struct d_resource* running;
+ int do_attach=0;
+ int do_connect=0;
+ int do_syncer=0;
- struct stat sb;
- int c_major, c_minor;
- int err = 10;
+ argv[argc++]=drbdsetup;
+ argv[argc++]=res->me->device;
+ argv[argc++]="show";
+ argv[argc++]=0;
- argv[argc++]=drbdsetup;
- argv[argc++]=res->me->device;
- argv[argc++]="show";
- argv[argc++]=0;
+ yyin = m_popen(&pid,argv);
+ line = 1;
+ running = parse_resource("drbdsetup/show");
+ fclose(yyin);
+ waitpid(pid,0,0);
- in=m_popen(&pid,argv);
+ convert_discard_opt(res);
+ convert_after_option(res);
- rv=fscanf(in,"%[Not] configured",str1);
- if(rv==1 && !strcmp("Not",str1) ) {
- do_attach=1;
- do_connect=1;
- do_syncer=1;
- goto do_up;
- }
+ do_attach = !opts_equal(res->disk_options, running->disk_options);
+ do_attach |= strcmp(res->me->device, running->me->device);
+ do_attach |= !disk_equal(res->me, running->me);
- if (stat(res->me->disk, &sb)) {
- PERROR("stat '%s' failed:", res->me->device);
- goto out;
- }
- if (!S_ISBLK(sb.st_mode)) {
- fprintf(stderr, "'%s' not a block device!\n", res->me->disk);
- goto out;
- }
- rv=m_fscanf(in,"Lower device: %d:%d (%*[^)])\n",&c_major,&c_minor);
- if( (rv!=2) || makedev(c_major,c_minor) != sb.st_rdev) do_attach=1;
+ do_connect = !opts_equal(res->net_options, running->net_options);
+ do_connect |= !addr_equal(res,running);
+ do_connect |= !proto_equal(res,running);
- if (strcmp("internal", res->me->meta_disk)) {
- if (stat(res->me->meta_disk, &sb)) {
- PERROR("stat '%s' failed:", res->me->meta_disk);
- goto out;
- }
- if (!S_ISBLK(sb.st_mode)) {
- fprintf(stderr, "'%s' not a block device!\n", res->me->disk);
- goto out;
- }
- } else {
- sb.st_rdev = 0;
- }
+ do_syncer = !opts_equal(res->sync_options, running->sync_options);
- rv = m_fscanf(in, "Meta device: %s (%[^)])\n", str1, str2);
- if (rv == 1) {
- if (!strcmp("internal", str1)) {
- if (strcmp("internal", res->me->meta_disk))
- do_attach = 1;
- } else {
- fprintf(stderr, "parse error, '%s' read, 'internal' expected\n", str1);
- goto out;
- }
- }
- if (rv == 2) {
- sscanf(str1, "%d:%d", &c_major, &c_minor);
- if ((rv != 2) || makedev(c_major,c_minor) != sb.st_rdev)
- do_attach = 1;
- rv = m_fscanf(in, "Meta index: %[0-9]\n", str1);
- if (rv == 1) {
- if (strcmp(str1, res->me->meta_index))
- do_attach = 1;
- } else {
- fprintf(stderr, "parse error\n");
- goto out;
- }
- }
+ if(do_attach) schedule_dcmd(adm_attach,res,0);
+ if(do_syncer) schedule_dcmd(adm_syncer,res,1);
+ if(do_connect) schedule_dcmd(adm_connect,res,2);
- rv=m_fscanf(in,"Disk options%[:]\n",uu);
- if(rv==1) {
- do_resize |= check_opt_d(in,"size",'K',"KB",res->disk_options);
- do_attach |= check_opt_s(in,"on-io-error",res->disk_options);
-
- // Check if every options is also present in drbdsetup show's output.
- o=res->disk_options;
- while(o) {
- if(o->mentioned == 0) {
- if(!strcmp(o->name,"size")) do_resize=1;
- else do_attach=1;
- }
- o=o->next;
- }
- }
-
- rv=m_fscanf(in,"Local address: %[0-9.]:%s\n",str1,str2);
- if(rv!=2 || strcmp(str1,res->me->address) || strcmp(str2,res->me->port) ) {
- do_connect=1;
- }
-
- rv=m_fscanf(in,"Remote address: %[0-9.]:%s\n",str1,str2);
- if(rv!=2 || strcmp(str1,res->peer->address) ||
- strcmp(str2,res->peer->port) ) {
- do_connect=1;
- }
-
- rv=m_fscanf(in,"Wire protocol: %1[ABC]\n",str1);
- if(rv!=1 || strcmp(str1,res->protocol) ) {
- do_connect=1;
- }
-
- rv=m_fscanf(in,"Net options%[:]\n",uu);
- if(rv==1) {
- rv=m_fscanf(in," timeout = %lu.%lu sec (%[d]efault)\n",&ul1,&ul2,uu);
- o=find_opt(res->net_options,"timeout");
- if(o) {
- o->mentioned=1;
- if(m_strtoll(o->value,1) != ul1*10 + ul2) do_connect=1;
- } else {
- if( uu[0] != 'd' ) do_connect=1;
- }
-
- do_connect |= check_opt_d(in,"connect-int",1,"sec",res->net_options);
- do_connect |= check_opt_d(in,"ping-int",1,"sec",res->net_options);
- do_connect |= check_opt_d(in,"max-epoch-size",1,"",res->net_options);
- do_connect |= check_opt_d(in,"max-buffers",1,"",res->net_options);
- do_connect |= check_opt_d(in,"sndbuf-size",1,"",res->net_options);
- do_connect |= check_opt_d(in,"ko-count",1,"",res->net_options);
- do_connect |= check_opt_s(in,"on-disconnect",res->net_options);
- do_connect |= check_opt_b(in,"allow-two-primaries",res->net_options);
- do_connect |= complete(res->net_options);
- }
-
- rv=m_fscanf(in,"Syncer options%[:]\n",uu);
- if(rv==1) {
- do_syncer |= check_opt_d(in,"rate",'K',"KB/sec",res->sync_options);
- do_syncer |= check_opt_d(in,"group",1,"",res->sync_options);
- do_syncer |= check_opt_d(in,"al-extents",1,"",res->sync_options);
- do_syncer |= check_opt_b(in,"skip-sync",res->sync_options);
- do_syncer |= check_opt_b(in,"use-csums",res->sync_options);
- do_syncer |= complete(res->sync_options);
- } else do_syncer=1;
-
- do_up:
- err = 0;
- out:
- // drain, close, wait for drbdsetup to "officially die".
- { static char drain[1024]; while (fgets(drain,1024,in)); }
- fclose(in);
- waitpid(pid,0,0);
- if (err) return err;
-
- if(do_attach) {
- schedule_dcmd(adm_attach,res,0);
- do_resize=0;
- }
- if(do_resize) schedule_dcmd(adm_resize,res,0);
- if(do_syncer) schedule_dcmd(adm_syncer,res,1);
- if(do_connect) schedule_dcmd(adm_connect,res,2);
-
- return 0;
+ return 0;
}
Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm_main.c 2006-04-11 16:18:17 UTC (rev 2144)
@@ -728,6 +728,24 @@
return rv;
}
+// need to convert discard-node-nodename to discard-local or discard-remote.
+void convert_discard_opt(struct d_resource* res)
+{
+ struct d_option* opt;
+
+ if ( (opt = find_opt(res->net_options, "after-sb-0pri")) ) {
+ if(!strncmp(opt->value,"discard-node-",13)) {
+ if(!strcmp(nodeinfo.nodename,opt->value+13)) {
+ free(opt->value);
+ opt->value=strdup("discard-local");
+ } else {
+ free(opt->value);
+ opt->value=strdup("discard-remote");
+ }
+ }
+ }
+}
+
int adm_connect(struct d_resource* res,const char* unused __attribute((unused)))
{
char* argv[20];
@@ -742,16 +760,7 @@
ssprintf(argv[argc++],"%s:%s",res->peer->address,res->peer->port);
argv[argc++]=res->protocol;
- // need to convert discard-node-nodename to discard-local or discard-remote.
- if ( (opt = find_opt(res->net_options, "after-sb-0pri")) ) {
- if(!strncmp(opt->value,"discard-node-",13)) {
- if(!strcmp(nodeinfo.nodename,opt->value+13)) {
- opt->value=strdup("discard-local");
- } else {
- opt->value=strdup("discard-remote");
- }
- }
- }
+ convert_discard_opt(res);
opt=res->net_options;
make_options(opt);
@@ -767,6 +776,19 @@
struct d_resource* res_by_name(const char *name);
+// Need to convert after from resourcename to minor_number.
+void convert_after_option(struct d_resource* res)
+{
+ struct d_option* opt;
+
+ if ( (opt = find_opt(res->sync_options, "after")) ) {
+ char *ptr;
+ ssprintf(ptr,"%d",dt_minor_of_dev(res_by_name(opt->value)->me->device));
+ free(opt->value);
+ opt->value=strdup(ptr);
+ }
+}
+
int adm_syncer(struct d_resource* res,const char* unused __attribute((unused)))
{
char* argv[20];
@@ -777,13 +799,7 @@
argv[argc++]=res->me->device;
argv[argc++]="syncer";
- // Need to convert after from resourcename to minor_number.
- if ( (opt = find_opt(res->sync_options, "after")) ) {
- char *ptr;
- ssprintf(ptr,"%d",dt_minor_of_dev(res_by_name(opt->value)->me->device));
- free(opt->value);
- opt->value=strdup(ptr);
- }
+ convert_after_option(res);
opt=res->sync_options;
make_options(opt);
Modified: trunk/user/drbdadm_parser.c
===================================================================
--- trunk/user/drbdadm_parser.c 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm_parser.c 2006-04-11 16:18:17 UTC (rev 2144)
@@ -157,6 +157,7 @@
cn->name=name;
cn->value=value;
cn->mentioned=0;
+ cn->is_default=0;
return cn;
}
@@ -271,7 +272,7 @@
int token;
enum range_checks rc;
- struct d_option* options = NULL;
+ struct d_option* options = NULL, *ro = NULL;
EXP('{');
while(1) {
@@ -283,40 +284,30 @@
rc = yylval.rc;
EXP2(TK_STRING,TK_INTEGER);
range_check(rc,opt_name,yylval.txt);
- options = APPEND(options,new_opt(opt_name,yylval.txt));
+ ro = new_opt(opt_name,yylval.txt);
+ options = APPEND(options,ro);
} else if ( token == '}' ) {
return options;
} else {
pe_expected("An option keyword");
}
- EXP(';');
+ switch(yylex()) {
+ case TK__IS_DEFAULT:
+ ro->is_default=1;
+ EXP(';');
+ break;
+ case ';':
+ break;
+ default:
+ pe_expected("_is_default | ;");
+ }
}
}
-static void parse_host_section(struct d_resource* res)
+static void parse_host_body(struct d_host_info *host,
+ struct d_resource* res,
+ int require_all)
{
- struct d_host_info *host;
-
- c_section_start = line;
-
- host=calloc(1,sizeof(struct d_host_info));
- EXP(TK_STRING);
- host->name = yylval.txt;
- if(strcmp(host->name, nodeinfo.nodename) == 0) {
- res->me = host;
- } else {
- if (res->peer) {
- config_valid = 0;
- fprintf(stderr,
- "%s:%d: in resource %s, on %s { ... } ... on %s { ... }:\n"
- "\tThere are multiple host sections for the peer.\n"
- "\tMaybe misspelled local host name '%s'?\n",
- config_file, c_section_start, res->name,
- res->peer->name, host->name, nodeinfo.nodename);
- }
- res->peer = host;
- }
-
EXP('{');
while(1) {
switch(yylex()) {
@@ -325,12 +316,26 @@
host->disk = yylval.txt;
check_uniq("disk", "%s:%s:%s","disk",
host->name,yylval.txt);
+ switch(yylex()) {
+ case TK__MAJOR:
+ EXP(TK_INTEGER);
+ host->disk_major = atoi(yylval.txt);
+ EXP(TK__MINOR);
+ EXP(TK_INTEGER);
+ host->disk_minor = atoi(yylval.txt);
+ EXP(';');
+ case ';':
+ break;
+ default:
+ pe_expected("_major | ;");
+ }
break;
case TK_DEVICE:
EXP(TK_STRING);
host->device = yylval.txt;
check_uniq("device", "%s:%s:%s","device",
host->name,yylval.txt);
+ EXP(';');
break;
case TK_ADDRESS:
EXP(TK_IPADDR);
@@ -339,6 +344,7 @@
EXP(TK_INTEGER);
host->port = yylval.txt;
range_check(R_PORT, "port", yylval.txt);
+ EXP(';');
break;
case TK_META_DISK:
EXP(TK_STRING);
@@ -348,6 +354,21 @@
EXP(TK_INTEGER);
host->meta_index = yylval.txt;
EXP(']');
+ EXP(';');
+ } else {
+ switch(yylex()) {
+ case TK__MAJOR:
+ EXP(TK_INTEGER);
+ host->meta_major = atoi(yylval.txt);
+ EXP(TK__MINOR);
+ EXP(TK_INTEGER);
+ host->meta_minor = atoi(yylval.txt);
+ EXP(';');
+ case ';':
+ break;
+ default:
+ pe_expected("_major | ;");
+ }
}
check_meta_disk(host);
break;
@@ -356,6 +377,7 @@
host->meta_disk = yylval.txt;
host->meta_index = strdup("flexible");
check_meta_disk(host);
+ EXP(';');
break;
case '}':
goto break_loop;
@@ -363,26 +385,69 @@
pe_expected("disk | device | address | meta-disk "
"| flex-meta-disk");
}
- EXP(';');
}
break_loop:
+ if (!require_all) return;
if (!host->device) derror(host,res,"device");
if (!host->disk) derror(host,res,"disk");
if (!host->address) derror(host,res,"address");
if (!host->meta_disk) derror(host,res,"meta-disk");
}
+static void parse_host_section(struct d_resource* res)
+{
+ struct d_host_info *host;
+
+ c_section_start = line;
+
+ host=calloc(1,sizeof(struct d_host_info));
+ EXP(TK_STRING);
+ host->name = yylval.txt;
+ if(strcmp(host->name, nodeinfo.nodename) == 0) {
+ res->me = host;
+ } else {
+ if (res->peer) {
+ config_valid = 0;
+ fprintf(stderr,
+ "%s:%d: in resource %s, on %s { ... } ... on %s { ... }:\n"
+ "\tThere are multiple host sections for the peer.\n"
+ "\tMaybe misspelled local host name '%s'?\n",
+ config_file, c_section_start, res->name,
+ res->peer->name, host->name, nodeinfo.nodename);
+ }
+ res->peer = host;
+ }
+ parse_host_body(host,res,1);
+}
+
+static void parse_drbdsetup_host_dump(struct d_resource* res, int local)
+{
+ struct d_host_info *host;
+
+ c_section_start = line;
+
+ host=calloc(1,sizeof(struct d_host_info));
+
+ if(local) {
+ res->me = host;
+ } else {
+ res->peer = host;
+ }
+
+ parse_host_body(host,res,0);
+}
+
struct d_resource* parse_resource(char* res_name)
{
struct d_resource* res;
+ int token;
res=calloc(1,sizeof(struct d_resource));
res->name = res_name;
res->next = NULL;
- EXP('{');
while(1) {
- switch(yylex()) {
+ switch((token=yylex())) {
case TK_PROTOCOL:
EXP(TK_STRING);
res->protocol=yylval.txt;
@@ -391,6 +456,12 @@
case TK_ON:
parse_host_section(res);
break;
+ case TK__THIS_HOST:
+ parse_drbdsetup_host_dump(res, 1);
+ break;
+ case TK__REMOTE_HOST:
+ parse_drbdsetup_host_dump(res, 0);
+ break;
case TK_DISK:
res->disk_options = parse_options(TK_DISK_SWITCH,
TK_DISK_OPTION);
@@ -411,10 +482,12 @@
res->handlers = parse_options(0,
TK_HANDLER_OPTION);
break;
- case '}': return res;
+ case '}':
+ case 0:
+ return res;
default:
- pe_expected("protocol | on | disk | net | syncer |"
- " startup | handler");
+ pe_expected_got("protocol | on | disk | net | syncer |"
+ " startup | handler",token);
}
}
}
@@ -442,9 +515,13 @@
while(1) {
switch(yylex()) {
case TK_GLOBAL: parse_global(); break;
- case TK_COMMON: common = parse_resource("common"); break;
+ case TK_COMMON:
+ EXP('{');
+ common = parse_resource("common");
+ break;
case TK_RESOURCE:
EXP(TK_STRING);
+ EXP('{');
config = APPEND( config , parse_resource(yylval.txt) );
break;
case TK_SKIP: parse_skip(); break;
Modified: trunk/user/drbdadm_parser.h
===================================================================
--- trunk/user/drbdadm_parser.h 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm_parser.h 2006-04-11 16:18:17 UTC (rev 2144)
@@ -83,7 +83,12 @@
TK_USAGE_COUNT,
TK_ASK,
TK_YES,
- TK_NO
+ TK_NO,
+ TK__IS_DEFAULT,
+ TK__MAJOR,
+ TK__MINOR,
+ TK__THIS_HOST,
+ TK__REMOTE_HOST
};
typedef struct YYSTYPE {
Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdadm_scanner.fl 2006-04-11 16:18:17 UTC (rev 2144)
@@ -31,7 +31,7 @@
IPV4ADDR ({SNUMB}"."){3}{SNUMB}
WS [ \t]
OPCHAR [{};\[\]:]
-DQSTRING \"[^\"\\\n]{1,255}\"
+DQSTRING \"[^\"\\\n]{0,255}\"
STRING [a-zA-Z0-9/._-]{1,80}
LONG_STRING [a-zA-Z0-9/._-]{81}
@@ -66,6 +66,11 @@
meta-disk { DP; return TK_META_DISK; }
flexible-meta-disk { DP; return TK_FLEX_META_DISK; }
usage-count { DP; return TK_USAGE_COUNT; }
+_is_default { DP; return TK__IS_DEFAULT; }
+_major { DP; return TK__MAJOR; }
+_minor { DP; return TK__MINOR; }
+_this_host { DP; return TK__THIS_HOST; }
+_remote_host { DP; return TK__REMOTE_HOST; }
size { DP; CP; RC(DISK_SIZE); return TK_DISK_OPTION; }
on-io-error { DP; CP; return TK_DISK_OPTION; }
fencing { DP; CP; return TK_DISK_OPTION; }
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2006-04-07 16:21:02 UTC (rev 2143)
+++ trunk/user/drbdsetup.c 2006-04-11 16:18:17 UTC (rev 2144)
@@ -1322,13 +1322,28 @@
#define SHOW_I(T,U,M,D) \
printf("\t" T "\t%d",M); \
if(M==D) printf(" _is_default"); \
-printf("; # " U "\n")
+printf("; \t# " U "\n")
+#define SHOW_IU(T,U1,U2,M,D) \
+printf("\t" T "\t%d",M); \
+if(M==D) printf(" _is_default"); \
+printf(U1"; \t# " U2 "\n")
+
#define SHOW_H(T,M,D,H) \
printf("\t" T "\t%s",H[M]); \
if(M==D) printf(" _is_default"); \
printf(";\n")
+#define SHOW_S(T,M,D) \
+printf("\t" T "\t\"%s\"",M); \
+if(!strcmp(M,D)) printf(" _is_default"); \
+printf(";\n")
+
+ if( cn.state.disk == Diskless && cn.state.conn == StandAlone)
+ {
+ printf("# not configured.\n");
+ }
+
if( cn.state.disk > Diskless)
{
printf("disk {\n");
@@ -1350,10 +1365,12 @@
SHOW_I("max-buffers","pages", cn.nconf.max_buffers, DEF_MAX_BUFFERS);
SHOW_I("sndbuf-size","byte", cn.nconf.sndbuf_size, DEF_SNDBUF_SIZE);
SHOW_I("ko-count","1", cn.nconf.ko_count, DEF_KO_COUNT);
- SHOW_H("on-disconnect",cn.nconf.on_disconnect,DEF_ON_DISCONNECT,dh_names);
+ // SHOW_H("on-disconnect",cn.nconf.on_disconnect,DEF_ON_DISCONNECT,dh_names);
SHOW_H("after-sb-0pri",cn.nconf.after_sb_0p,DEF_AFTER_SB_0P,asb0p_names);
SHOW_H("after-sb-1pri",cn.nconf.after_sb_1p,DEF_AFTER_SB_0P,asb1p_names);
SHOW_H("after-sb-2pri",cn.nconf.after_sb_2p,DEF_AFTER_SB_0P,asb2p_names);
+ SHOW_S("cram-hmac-alg",cn.nconf.cram_hmac_alg,"");
+ SHOW_S("shared-secret",cn.nconf.shared_secret,"");
if( cn.nconf.two_primaries ) printf("\tallow-two-primaries;\n");
if( cn.nconf.want_lose ) printf("\tdiscard-my-data;\n");
printf("}\n");
@@ -1362,7 +1379,7 @@
if( cn.state.conn > StandAlone)
{
printf("syncer {\n");
- SHOW_I("rate\t","KByte/second", cn.sconf.rate, DEF_SYNC_RATE);
+ SHOW_IU("rate\t","K","(K)Byte/second", cn.sconf.rate, DEF_SYNC_RATE);
SHOW_I("after\t","minor", cn.sconf.after, DEF_SYNC_AFTER);
SHOW_I("al-extents","4MByte", cn.sconf.al_extents, DEF_SYNC_AL_EXTENTS);
if( cn.sconf.skip ) printf("\tskip-sync;\n");
More information about the drbd-cvs
mailing list