[DRBD-user] ARM (armel) users please test "drbdsetup 0 show"

Lars Ellenberg lars.ellenberg at linbit.com
Tue Mar 20 16:35:16 CET 2012

Note: "permalinks" may not be as permanent as we would like,
direct links of old sources may well be a few messages off.


On Tue, Mar 13, 2012 at 03:26:46PM +0100, Erik Rossen wrote:
> After hacking show_address() in user/drbdsetup.c, I managed to get "drbdsetup 0
> show" to produce correct results:
> 
> 	...snip...
> 	protocol C;
> 	_this_host {
> 		device			minor 0;
> 		disk			"/dev/sda1";
> 		meta-disk		internal;
> 		address			ipv4 172.16.3.1:7788;
> 	}
> 	_remote_host {
> 		address			ipv4 172.16.3.2:7788;
> 	}
> 
> The trick was to reserve a guaranteed-to-be-aligned buffer for the
> sockaddr/sockaddr_in/sockaddr_in6 data and memcpy() to the buffer before
> parsing it.

WTF.
Not that again.

> Here is the diff:
> 
> ------------------------------------------------------------------------
> --- user/drbdsetup.c.ORIG	2012-02-21 16:15:30.000000000 +0100
> +++ user/drbdsetup.c	2012-03-13 15:09:06.000000000 +0100
> @@ -1452,28 +1452,29 @@
>  
>  static void show_address(void* address, int addr_len)
>  {
> -	struct sockaddr     *addr;
>  	struct sockaddr_in  *addr4;
>  	struct sockaddr_in6 *addr6;
>  	char buffer[INET6_ADDRSTRLEN];
>  
> -	addr = (struct sockaddr *)address;
> -	if (addr->sa_family == AF_INET
> -	|| addr->sa_family == get_af_ssocks(0)
> -	|| addr->sa_family == AF_INET_SDP) {
> -		addr4 = (struct sockaddr_in *)address;
> +	struct sockaddr addrbuf; /* reserve a perfectly-aligned sockaddr */
> +	memcpy(&addrbuf, address, addr_len); /* ...and fill it with bytes */

Yeah, well, something like that.

> +
> +	if (addrbuf.sa_family == AF_INET
> +	|| addrbuf.sa_family == get_af_ssocks(0)
> +	|| addrbuf.sa_family == AF_INET_SDP) {
> +		addr4 = (struct sockaddr_in *)(&addrbuf);
>  		printf("\taddress\t\t\t%s %s:%d;\n",
>  		       af_to_str(addr4->sin_family),
>  		       inet_ntoa(addr4->sin_addr),
>  		       ntohs(addr4->sin_port));
> -	} else if (addr->sa_family == AF_INET6) {
> -		addr6 = (struct sockaddr_in6 *)address;
> +	} else if (addrbuf.sa_family == AF_INET6) {
> +		addr6 = (struct sockaddr_in6 *)(&addrbuf);
>  		printf("\taddress\t\t\t%s [%s]:%d;\n",
>  		       af_to_str(addr6->sin6_family),
>  		       inet_ntop(addr6->sin6_family, &addr6->sin6_addr, buffer, INET6_ADDRSTRLEN),
>  		       ntohs(addr6->sin6_port));
>  	} else {
> -		printf("\taddress\t\t\t[unknown af=%d, len=%d]\n", addr->sa_family, addr_len);
> +		printf("\taddress\t\t\t[unknown af=%d, len=%d]\n", addrbuf.sa_family, addr_len);
>  	}
>  }
> ------------------------------------------------------------------------
>  
> 
> gcc whines a bit:
> 
> 	drbdsetup.c: In function ‘show_address’:
> 	drbdsetup.c:1466: warning: dereferencing pointer ‘addr4’ does break strict-aliasing rules
> 	drbdsetup.c:1465: note: initialized from here
> 	drbdsetup.c:1475: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	drbdsetup.c:1474: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	drbdsetup.c:1473: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	drbdsetup.c:1471: note: initialized from here
> 	cc1: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	cc1: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	cc1: warning: dereferencing pointer ‘addr6’ does break strict-aliasing rules
> 	drbdsetup.c:1471: note: initialized from here
> 
> so it would be nice if some more-experienced C programmers found a cleaner
> solution for aligning and conditionally-parsing the sockaddr structures.
> Perhaps a union?
> 
> I am still interested to know if I am the only armel user having problems with
> "drbdsetup 0 show"...

As you probably know, behaviour for misaligned access is different for different ARM versions,
*and* can additionally be changed at runtime in /proc/cpu/alignment
(or /proc/sys/debug/alignment, or something like that).

Whether or not things will be misaligned also depends on what exactly
comes back from the kernel, so it may well be aligned "good enough"
sometimes, or even most of the time.

Anyways, probably best to use a union { struct sockaddr_* } on stack,
and memcpy there, before using it.

Will do, thanks for reporting.


-- 
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com

DRBD® and LINBIT® are registered trademarks of LINBIT, Austria.
__
please don't Cc me, but send to list   --   I'm subscribed



More information about the drbd-user mailing list