<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7226.0">
<TITLE>Problems at boot time with drbd-8</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">I’ve been working on getting the pre-release version of DRBD8 up on my system and have run into a couple of</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">minor</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">problems… first of all, I found that drbdadm dies with a segfault when running ‘drbdadm adjust all’ at boot time – turns out this is because the underlying ‘drbdsetup /dev/drbd0 show’ command returns “# not configured” at that time – the parsing of this into a resource structure</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> by drbdadm</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> leaves the running->me field NULL and we then trip over an attempt to strcmp the name of the device with the configured name – after some checking, I found that this problem is actually fixed in the trunk so I moved forward to there, BUT there are still a couple of issues with startup, namely:</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">1. </FONT></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">The routine convert_after_option</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">(in drbdadm_main.c)</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">ends up being called twice when the ‘drbdadm adjust all’ command is issued – once when comparing with the current running config and then again if a sync operation is actually kicked off – unforturnately, this routine actually crashes if the name stored in the after option is not a valid resource name (which of course it isn’t after it’s been converted the first time). I fixed this simply by not doing the conversion if the name does not represent a valid resource – if it truly is a bad resource name then the later attempt to use it will fail.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">2. </FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">The new code added to check IP addresses (</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">verify_ips in drbdadm_main.c) is not properly</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">initializing</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> the sin_addr local variable which should have the IP address of the local system</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"></FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">–</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> thus this routine always fails and you get the</FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">‘</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">OOPS: the IP address x.y.z.a isn</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">’</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">t configure/up on your system!</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">’</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> error message.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">3. </FONT></SPAN><SPAN LANG="en-us"> <FONT SIZE=2 FACE="Tahoma">The definition & use of INVALID_IP_IS_INVALID_CONF</FONT></SPAN><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma"> are inconsistent; the definition defines it as zero and implies this means the option is disabled whereas the .c file uses #ifdef to check if it is enabled. I think this should be #if instead.</FONT></SPAN><SPAN LANG="en-us"> </SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">Attached is a patch that fixes these.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT SIZE=2 FACE="Tahoma">Simon</FONT></SPAN><SPAN LANG="en-us"></SPAN></P>
<BR>
<P DIR=LTR><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"><FONT FACE="Courier New">Index: user/drbdadm_main.c</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">===================================================================</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">--- user/drbdadm_main.c (revision 2739)</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+++ user/drbdadm_main.c (working copy)</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">@@ -794,6 +794,12 @@</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> struct d_resource* res_by_name(const char *name);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> // Need to convert after from resourcename to minor_number.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// NOTE: this _may_ already have been done (for example, adjust</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// processing will call this, then may start a syncer op</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// which will call it again for the same resource). This is</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// detected by attempting to locate the resource structure</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// for the resource -- if this fails, we assume the tx has</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+// already been done.</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> void convert_after_option(struct d_resource* res)</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> {</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> struct d_option* opt;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">@@ -802,9 +808,13 @@</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> if ( (opt = find_opt(res->sync_options, "after")) ) {</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> char *ptr;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">- ssprintf(ptr,"%d",dt_minor_of_dev(res_by_name(opt->value)->me->device));</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">- free(opt->value);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">- opt->value=strdup(ptr);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ struct d_resource *ares = res_by_name(opt->value);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ if (ares) {</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ ssprintf(ptr,"%d",dt_minor_of_dev(ares->me->device));</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ free(opt->value);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ opt->value=strdup(ptr);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ }</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> }</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> }</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">@@ -1293,6 +1303,7 @@</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> const char *my_ip;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> my_ip = res->me->address;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+ sin_addr.s_addr = inet_addr(my_ip);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> /* does DRBD support inet6? */</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> family = AF_INET;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">@@ -1316,7 +1327,7 @@</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> </FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> if (valid == 0) {</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> fprintf(stderr, "OOPS, the IP address %s isn't configure/up on your system!\n", my_ip);</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">-#ifdef INVALID_IP_IS_INVALID_CONF</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New">+#if INVALID_IP_IS_INVALID_CONF</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> config_valid = 0;</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> #endif</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"><FONT FACE="Courier New"> }</FONT></SPAN></P>
<P DIR=LTR><SPAN LANG="en-us"></SPAN><SPAN LANG="en-us"></SPAN></P>
</BODY>
</HTML>