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