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

Erik Rossen rossen at rossen.ch
Tue Mar 13 15:26:46 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.


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.

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 */
+
+	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"...

-- 
Erik Rossen
rossen at rossen.ch
http://www.rtfm-sarl.ch
OpenPGP key: 2935D0B9



More information about the drbd-user mailing list