mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
libvirt_nss: Report newer addresses first
Ideally, a software that's translating domain names would iterate over all addresses the NSS returned, but some software does not bother (e.g. ping). What happens is that for instance when installing a guest, it's assigned one IP address but once it's installed and rebooted it gets a different IP address (because client ID used for the first DHCP traffic when installing the guest was generated dynamically and never saved so after reboot the guest generated new ID which resulted in different IP address to be assigned). This results in 'ping $domain' not working properly as it still pings the old IP address. Well, it might - NSS plugin does not guarantee any order of addresses. To resolve this problem, we can sort the array just before returning it to the caller (ping) so that the newer IP addresses come before older ones. Reported-by: Andrea Bolognani <abologna@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
757b94c682
commit
a7cbfabc2f
@ -3,13 +3,13 @@
|
||||
"ip-address": "192.168.122.197",
|
||||
"mac-address": "52:54:00:a4:6f:91",
|
||||
"hostname": "fedora",
|
||||
"expiry-time": 1900000000
|
||||
"expiry-time": 1900000002
|
||||
},
|
||||
{
|
||||
"ip-address": "192.168.122.198",
|
||||
"mac-address": "52:54:00:a4:6f:92",
|
||||
"hostname": "fedora",
|
||||
"expiry-time": 1900000000
|
||||
"expiry-time": 1900000001
|
||||
},
|
||||
{
|
||||
"ip-address": "192.168.122.254",
|
||||
|
@ -46,7 +46,7 @@ testGetHostByName(const void *opaque)
|
||||
char buf[BUF_SIZE] = { 0 };
|
||||
char **addrList;
|
||||
int rv, tmp_errno = 0, tmp_herrno = 0;
|
||||
size_t i = 0, j = 0;
|
||||
size_t i = 0;
|
||||
|
||||
memset(&resolved, 0, sizeof(resolved));
|
||||
|
||||
@ -117,6 +117,7 @@ testGetHostByName(const void *opaque)
|
||||
}
|
||||
|
||||
addrList = resolved.h_addr_list;
|
||||
i = 0;
|
||||
while (*addrList) {
|
||||
virSocketAddr sa;
|
||||
char *ipAddr;
|
||||
@ -135,14 +136,10 @@ testGetHostByName(const void *opaque)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (j = 0; data->ipAddr[j]; j++) {
|
||||
if (STREQ(data->ipAddr[j], ipAddr))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!data->ipAddr[j]) {
|
||||
if (STRNEQ_NULLABLE(data->ipAddr[i], ipAddr)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"Unexpected address %s", ipAddr);
|
||||
"Unexpected address %s, expecting %s",
|
||||
ipAddr, NULLSTR(data->ipAddr[i]));
|
||||
VIR_FREE(ipAddr);
|
||||
goto cleanup;
|
||||
}
|
||||
@ -152,12 +149,10 @@ testGetHostByName(const void *opaque)
|
||||
i++;
|
||||
}
|
||||
|
||||
for (j = 0; data->ipAddr[j]; j++)
|
||||
;
|
||||
|
||||
if (i != j) {
|
||||
if (data->ipAddr[i]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"Expected %zu addresses, got %zu", j, i);
|
||||
"Expected %s address, got NULL",
|
||||
data->ipAddr[i]);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -76,9 +76,29 @@ do { \
|
||||
typedef struct {
|
||||
unsigned char addr[16];
|
||||
int af;
|
||||
long long expirytime;
|
||||
} leaseAddress;
|
||||
|
||||
|
||||
static int
|
||||
leaseAddressSorter(const void *a,
|
||||
const void *b)
|
||||
{
|
||||
const leaseAddress *la = a;
|
||||
const leaseAddress *lb = b;
|
||||
|
||||
return lb->expirytime - la->expirytime;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sortAddr(leaseAddress *tmpAddress,
|
||||
size_t ntmpAddress)
|
||||
{
|
||||
qsort(tmpAddress, ntmpAddress, sizeof(*tmpAddress), leaseAddressSorter);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
appendAddr(const char *name ATTRIBUTE_UNUSED,
|
||||
leaseAddress **tmpAddress,
|
||||
@ -89,6 +109,7 @@ appendAddr(const char *name ATTRIBUTE_UNUSED,
|
||||
const char *ipAddr;
|
||||
virSocketAddr sa;
|
||||
int family;
|
||||
long long expirytime;
|
||||
size_t i;
|
||||
|
||||
if (!(ipAddr = virJSONValueObjectGetString(lease, "ip-address"))) {
|
||||
@ -109,6 +130,12 @@ appendAddr(const char *name ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberLong(lease, "expiry-time", &expirytime) < 0) {
|
||||
/* A lease cannot be present without expiry-time */
|
||||
ERROR("expiry-time field missing for %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < *ntmpAddress; i++) {
|
||||
if (memcmp((*tmpAddress)[i].addr,
|
||||
(family == AF_INET ?
|
||||
@ -125,6 +152,7 @@ appendAddr(const char *name ATTRIBUTE_UNUSED,
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*tmpAddress)[*ntmpAddress].expirytime = expirytime;
|
||||
(*tmpAddress)[*ntmpAddress].af = family;
|
||||
memcpy((*tmpAddress)[*ntmpAddress].addr,
|
||||
(family == AF_INET ?
|
||||
@ -325,6 +353,8 @@ findLease(const char *name,
|
||||
|
||||
#endif /* defined(LIBVIRT_NSS_GUEST) */
|
||||
|
||||
sortAddr(tmpAddress, ntmpAddress);
|
||||
|
||||
VIR_STEAL_PTR(*address, tmpAddress);
|
||||
*naddress = ntmpAddress;
|
||||
ntmpAddress = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user