diff --git a/hyper-v.changes b/hyper-v.changes index 962eadd..b5a9bdf 100644 --- a/hyper-v.changes +++ b/hyper-v.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Wed Nov 27 09:08:07 UTC 2019 - ohering@suse.de + +- async name resolution in kvp_daemon (bsc#1100758) +- kvp: eliminate 'may be used uninitialized' warning (89eb4d8d) +- fix typos in toolchain (2d35c660) +- fixed Python pep8/flake8 warnings for lsvmbus (5912e791) +- Replace GPLv2 boilerplate/reference with SPDX (43aa3132) +- Fix a warning of buffer overflow with gcc 8.0.1 (4fcba780) + ------------------------------------------------------------------- Tue Oct 9 09:27:45 UTC 2018 - ohering@suse.de diff --git a/hyper-v.lsvmbus.py b/hyper-v.lsvmbus.py index b29bb81..ac02003 100644 --- a/hyper-v.lsvmbus.py +++ b/hyper-v.lsvmbus.py @@ -4,10 +4,10 @@ import os from optparse import OptionParser +help_msg = "print verbose messages. Try -vv, -vvv for more verbose messages" parser = OptionParser() -parser.add_option("-v", "--verbose", dest="verbose", - help="print verbose messages. Try -vv, -vvv for \ - more verbose messages", action="count") +parser.add_option( + "-v", "--verbose", dest="verbose", help=help_msg, action="count") (options, args) = parser.parse_args() @@ -21,27 +21,28 @@ if not os.path.isdir(vmbus_sys_path): exit(-1) vmbus_dev_dict = { - '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]', - '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]', - '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]', - '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]', - '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]', - '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]', - '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]', - '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse', - '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard', - '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter', - '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter', - '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller', - '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller', - '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter', - '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter', - '{44c4f61d-4444-4400-9d52-802e27ede19f}' : 'PCI Express pass-through', - '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]', - '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]', - '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]', + '{0e0b6031-5213-4934-818b-38d90ced39db}': '[Operating system shutdown]', + '{9527e630-d0ae-497b-adce-e80ab0175caf}': '[Time Synchronization]', + '{57164f39-9115-4e78-ab55-382f3bd5422d}': '[Heartbeat]', + '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}': '[Data Exchange]', + '{35fa2e29-ea23-4236-96ae-3a6ebacba440}': '[Backup (volume checkpoint)]', + '{34d14be3-dee4-41c8-9ae7-6b174977c192}': '[Guest services]', + '{525074dc-8985-46e2-8057-a307dc18a502}': '[Dynamic Memory]', + '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}': 'Synthetic mouse', + '{f912ad6d-2b17-48ea-bd65-f927a61c7684}': 'Synthetic keyboard', + '{da0a7802-e377-4aac-8e77-0558eb1073f8}': 'Synthetic framebuffer adapter', + '{f8615163-df3e-46c5-913f-f2d2f965ed0e}': 'Synthetic network adapter', + '{32412632-86cb-44a2-9b5c-50d1417354f5}': 'Synthetic IDE Controller', + '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}': 'Synthetic SCSI Controller', + '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}': 'Synthetic fiber channel adapter', + '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}': 'Synthetic RDMA adapter', + '{44c4f61d-4444-4400-9d52-802e27ede19f}': 'PCI Express pass-through', + '{276aacf4-ac15-426c-98dd-7521ad3f01fe}': '[Reserved system device]', + '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}': '[Reserved system device]', + '{3375baf4-9e15-4b30-b765-67acb10d607b}': '[Reserved system device]', } + def get_vmbus_dev_attr(dev_name, attr): try: f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r') @@ -52,6 +53,7 @@ def get_vmbus_dev_attr(dev_name, attr): return lines + class VMBus_Dev: pass @@ -66,12 +68,13 @@ for f in os.listdir(vmbus_sys_path): chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping') chn_vp_mapping = [c.strip() for c in chn_vp_mapping] - chn_vp_mapping = sorted(chn_vp_mapping, - key = lambda c : int(c.split(':')[0])) + chn_vp_mapping = sorted( + chn_vp_mapping, key=lambda c: int(c.split(':')[0])) - chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' % - (c.split(':')[0], c.split(':')[1]) - for c in chn_vp_mapping] + chn_vp_mapping = [ + '\tRel_ID=%s, target_cpu=%s' % + (c.split(':')[0], c.split(':')[1]) for c in chn_vp_mapping + ] d = VMBus_Dev() d.sysfs_path = '%s/%s' % (vmbus_sys_path, f) d.vmbus_id = vmbus_id @@ -85,7 +88,7 @@ for f in os.listdir(vmbus_sys_path): vmbus_dev_list.append(d) -vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id)) +vmbus_dev_list = sorted(vmbus_dev_list, key=lambda d: int(d.vmbus_id)) format0 = '%2s: %s' format1 = '%2s: Class_ID = %s - %s\n%s' @@ -95,9 +98,15 @@ for d in vmbus_dev_list: if verbose == 0: print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)) elif verbose == 1: - print (('VMBUS ID ' + format1) % \ - (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)) + print( + ('VMBUS ID ' + format1) % + (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) + ) else: - print (('VMBUS ID ' + format2) % \ - (d.vmbus_id, d.class_id, d.dev_desc, \ - d.device_id, d.sysfs_path, d.chn_vp_mapping)) + print( + ('VMBUS ID ' + format2) % + ( + d.vmbus_id, d.class_id, d.dev_desc, + d.device_id, d.sysfs_path, d.chn_vp_mapping + ) + ) diff --git a/hyper-v.spec b/hyper-v.spec index d2974b1..7b65855 100644 --- a/hyper-v.spec +++ b/hyper-v.spec @@ -89,6 +89,7 @@ gcc \ -DCN_KVP_IDX=0x9 \ -DCN_KVP_VAL=0x1 \ -DKVP_SCRIPTS_PATH= \ + -pthread \ -o %{hv_kvp_daemon} gcc \ $RPM_OPT_FLAGS \ diff --git a/hyper-v.tools.hv.hv_fcopy_daemon.c b/hyper-v.tools.hv.hv_fcopy_daemon.c index 454311f..5d64e20 100644 --- a/hyper-v.tools.hv.hv_fcopy_daemon.c +++ b/hyper-v.tools.hv.hv_fcopy_daemon.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * An implementation of host to guest copy functionality for Linux. * * Copyright (C) 2014, Microsoft, Inc. * * Author : K. Y. Srinivasan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ diff --git a/hyper-v.tools.hv.hv_get_dhcp_info.sh b/hyper-v.tools.hv.hv_get_dhcp_info.sh index f16e8fc..a6d81e9 100644 --- a/hyper-v.tools.hv.hv_get_dhcp_info.sh +++ b/hyper-v.tools.hv.hv_get_dhcp_info.sh @@ -12,7 +12,7 @@ # the script prints the string "Disabled" to stdout. # # Each Distro is expected to implement this script in a distro specific -# fashion. For instance on Distros that ship with Network Manager enabled, +# fashion. For instance, on Distros that ship with Network Manager enabled, # this script can be based on the Network Manager APIs for retrieving DHCP # information. diff --git a/hyper-v.tools.hv.hv_kvp_daemon.c b/hyper-v.tools.hv.hv_kvp_daemon.c index 546403f..01ebbab 100644 --- a/hyper-v.tools.hv.hv_kvp_daemon.c +++ b/hyper-v.tools.hv.hv_kvp_daemon.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * KVP protocol: The user mode component first registers with the @@ -85,7 +86,7 @@ static char *processor_arch; static char *os_build; static char *os_version; static char *lic_version = "Unknown version"; -static char full_domain_name[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; +static char *full_domain_name; static struct utsname uts_buf; /* @@ -700,7 +701,7 @@ static void kvp_get_ipconfig_info(char *if_name, /* - * Gather the DNS state. + * Gather the DNS state. * Since there is no standard way to get this information * across various distributions of interest; we just invoke * an external script that needs to be ported across distros @@ -809,7 +810,7 @@ kvp_get_ip_info(int family, char *if_name, int op, int sn_offset = 0; int error = 0; char *buffer; - struct hv_kvp_ipaddr_value *ip_buffer; + struct hv_kvp_ipaddr_value *ip_buffer = NULL; char cidr_mask[5]; /* /xyz */ int weight; int i; @@ -1051,7 +1052,7 @@ static int parse_ip_val_buffer(char *in_buf, int *offset, char *start; /* - * in_buf has sequence of characters that are seperated by + * in_buf has sequence of characters that are separated by * the character ';'. The last sequence does not have the * terminating ";" character. */ @@ -1178,6 +1179,7 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val) FILE *file; char cmd[PATH_MAX]; char *mac_addr; + int str_len; /* * Set the configuration for the specified interface with @@ -1301,8 +1303,18 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val) * invoke the external script to do its magic. */ - snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s", - "hv_set_ifconfig", if_file); + str_len = snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s", + "hv_set_ifconfig", if_file); + /* + * This is a little overcautious, but it's necessary to suppress some + * false warnings from gcc 8.0.1. + */ + if (str_len <= 0 || (unsigned int)str_len >= sizeof(cmd)) { + syslog(LOG_ERR, "Cmd '%s' (len=%d) may be too long", + cmd, str_len); + return HV_E_FAIL; + } + if (system(cmd)) { syslog(LOG_ERR, "Failed to execute cmd '%s'; error: %d %s", cmd, errno, strerror(errno)); @@ -1317,27 +1329,76 @@ setval_error: return error; } - -static void -kvp_get_domain_name(char *buffer, int length) +/* + * Async retrival of Fully Qualified Domain Name because getaddrinfo takes an + * unpredictable amount of time to finish. + */ +static void *kvp_getaddrinfo(void *p) { - struct addrinfo hints, *info ; - int error = 0; + char *tmp, **str_ptr = (char **)p; + char hostname[HOST_NAME_MAX + 1]; + struct addrinfo *info, hints = { + .ai_family = AF_INET, /* Get only ipv4 addrinfo. */ + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_CANONNAME, + }; + int ret; + int prev_ret = 0, cnt = 5; - gethostname(buffer, length); - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; + do { + if (gethostname(hostname, sizeof(hostname) - 1) < 0) + goto out; - error = getaddrinfo(buffer, NULL, &hints, &info); - if (error != 0) { - snprintf(buffer, length, "getaddrinfo failed: 0x%x %s", - error, gai_strerror(error)); + ret = getaddrinfo(hostname, NULL, &hints, &info); + switch (ret) { + case 0: + break; + case EAI_BADFLAGS: + case EAI_MEMORY: + case EAI_OVERFLOW: + case EAI_SOCKTYPE: + case EAI_SYSTEM: + /* Permanent failure */ + syslog(LOG_ERR, "getaddrinfo failed: %d %s", + ret, gai_strerror(ret)); + goto out; + default: + /* runtime debug */ + if (cnt) { + if (prev_ret != ret) { + prev_ret = ret; + syslog(LOG_ERR, "getaddrinfo warning: %d %s", ret, gai_strerror(ret)); + cnt--; + } + } + /* Temporary failure, aim for success. */ + sleep(5); + } + } while (ret); + + ret = asprintf(&tmp, "%s", info->ai_canonname); + freeaddrinfo(info); + if (ret <= 0) + goto out; + + if (ret > HV_KVP_EXCHANGE_MAX_VALUE_SIZE) + tmp[HV_KVP_EXCHANGE_MAX_VALUE_SIZE - 1] = '\0'; + *str_ptr = tmp; + +out: + pthread_exit(NULL); +} + +static void kvp_obtain_domain_name(char **str_ptr) +{ + pthread_t t; + + if (pthread_create(&t, NULL, kvp_getaddrinfo, str_ptr)) { + syslog(LOG_ERR, "pthread_create failed; error: %d %s", + errno, strerror(errno)); return; } - snprintf(buffer, length, "%s", info->ai_canonname); - freeaddrinfo(info); + pthread_detach(t); } void print_usage(char *argv[]) @@ -1376,6 +1437,8 @@ int main(int argc, char *argv[]) daemonize = 0; break; case 'h': + print_usage(argv); + exit(0); default: print_usage(argv); exit(EXIT_FAILURE); @@ -1400,11 +1463,7 @@ int main(int argc, char *argv[]) * Retrieve OS release information. */ kvp_get_os_info(); - /* - * Cache Fully Qualified Domain Name because getaddrinfo takes an - * unpredictable amount of time to finish. - */ - kvp_get_domain_name(full_domain_name, sizeof(full_domain_name)); + kvp_obtain_domain_name(&full_domain_name); if (kvp_file_init()) { syslog(LOG_ERR, "Failed to initialize the pools"); @@ -1480,7 +1539,7 @@ int main(int argc, char *argv[]) case KVP_OP_GET_IP_INFO: kvp_ip_val = &hv_msg->body.kvp_ip_val; - error = kvp_mac_to_ip(kvp_ip_val); + error = kvp_mac_to_ip(kvp_ip_val); if (error) hv_msg->error = error; @@ -1559,7 +1618,7 @@ int main(int argc, char *argv[]) switch (hv_msg->body.kvp_enum_data.index) { case FullyQualifiedDomainName: - strcpy(key_value, full_domain_name); + strcpy(key_value, full_domain_name ? : ""); strcpy(key_name, "FullyQualifiedDomainName"); break; case IntegrationServicesVersion: diff --git a/hyper-v.tools.hv.hv_vss_daemon.c b/hyper-v.tools.hv.hv_vss_daemon.c index 0f28129..76ea8fa 100644 --- a/hyper-v.tools.hv.hv_vss_daemon.c +++ b/hyper-v.tools.hv.hv_vss_daemon.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * An implementation of the host initiated guest snapshot for Hyper-V. * - * * Copyright (C) 2013, Microsoft, Inc. * Author : K. Y. Srinivasan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * */ @@ -53,7 +42,7 @@ static int vss_do_freeze(char *dir, unsigned int cmd) * If a partition is mounted more than once, only the first * FREEZE/THAW can succeed and the later ones will get * EBUSY/EINVAL respectively: there could be 2 cases: - * 1) a user may mount the same partition to differnt directories + * 1) a user may mount the same partition to different directories * by mistake or on purpose; * 2) The subvolume of btrfs appears to have the same partition * mounted more than once. @@ -229,6 +218,8 @@ int main(int argc, char *argv[]) daemonize = 0; break; case 'h': + print_usage(argv); + exit(0); default: print_usage(argv); exit(EXIT_FAILURE);