Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Tools: hv: cache FQDN in kvp_daemon to avoid timeouts

kvp_daemon does some operations which take an unpredicable amount of
time. In addition the kernel driver gives the kvp_daemon a 5 second
timeout to respond to message from the host. If an operation such as
getaddrinfo takes a long time and the timeout triggers then netlink
errors occour. As a result of such errors the daemon just terminates and
the service becomes unavailable.

Idendifying and fixing these shortcomings in the kernel-userland
communication protocol will be done in separate patches. This change
fixes just one obvious timeout bug.

Update kvp_get_domain_name to not return a value, better diagnostic for
the consumer of the hostname string, remove trailing newline in error
case, use snprintf to not overrun output buffer, get hostname only once
and return the cached result.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Olaf Hering and committed by
Greg Kroah-Hartman
58125210 d6675667

+12 -7
+12 -7
tools/hv/hv_kvp_daemon.c
··· 89 89 static char *os_build; 90 90 static char *os_version; 91 91 static char *lic_version = "Unknown version"; 92 + static char full_domain_name[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; 92 93 static struct utsname uts_buf; 93 94 94 95 /* ··· 1368 1367 } 1369 1368 1370 1369 1371 - static int 1370 + static void 1372 1371 kvp_get_domain_name(char *buffer, int length) 1373 1372 { 1374 1373 struct addrinfo hints, *info ; ··· 1382 1381 1383 1382 error = getaddrinfo(buffer, NULL, &hints, &info); 1384 1383 if (error != 0) { 1385 - strcpy(buffer, "getaddrinfo failed\n"); 1386 - return error; 1384 + snprintf(buffer, length, "getaddrinfo failed: 0x%x %s", 1385 + error, gai_strerror(error)); 1386 + return; 1387 1387 } 1388 - strcpy(buffer, info->ai_canonname); 1388 + snprintf(buffer, length, "%s", info->ai_canonname); 1389 1389 freeaddrinfo(info); 1390 - return error; 1391 1390 } 1392 1391 1393 1392 static int ··· 1454 1453 * Retrieve OS release information. 1455 1454 */ 1456 1455 kvp_get_os_info(); 1456 + /* 1457 + * Cache Fully Qualified Domain Name because getaddrinfo takes an 1458 + * unpredictable amount of time to finish. 1459 + */ 1460 + kvp_get_domain_name(full_domain_name, sizeof(full_domain_name)); 1457 1461 1458 1462 if (kvp_file_init()) { 1459 1463 syslog(LOG_ERR, "Failed to initialize the pools"); ··· 1677 1671 1678 1672 switch (hv_msg->body.kvp_enum_data.index) { 1679 1673 case FullyQualifiedDomainName: 1680 - kvp_get_domain_name(key_value, 1681 - HV_KVP_EXCHANGE_MAX_VALUE_SIZE); 1674 + strcpy(key_value, full_domain_name); 1682 1675 strcpy(key_name, "FullyQualifiedDomainName"); 1683 1676 break; 1684 1677 case IntegrationServicesVersion: