diff --git a/hyper-v.changes b/hyper-v.changes index 765c85d..be08625 100644 --- a/hyper-v.changes +++ b/hyper-v.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Sep 25 08:33:36 UTC 2018 - ohering@suse.de + +- vss: fix loop device detection (07136793) +- Fix IP reporting by KVP daemon with SRIOV (4ba63412) +- Fix a bug in the key delete code (86503bd3) +- fix compiler warnings about major/target_fname (1330fc35) + ------------------------------------------------------------------- Thu Aug 2 08:46:52 UTC 2018 - schwab@suse.de diff --git a/hyper-v.lsvmbus.py b/hyper-v.lsvmbus.py index 9307c85..59239ec 100644 --- a/hyper-v.lsvmbus.py +++ b/hyper-v.lsvmbus.py @@ -1,4 +1,5 @@ #!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0 import os from optparse import OptionParser diff --git a/hyper-v.tools.hv.hv_fcopy_daemon.c b/hyper-v.tools.hv.hv_fcopy_daemon.c index 45030a6..623a607 100644 --- a/hyper-v.tools.hv.hv_fcopy_daemon.c +++ b/hyper-v.tools.hv.hv_fcopy_daemon.c @@ -24,13 +24,14 @@ #include #include #include +#include #include #include #include #include static int target_fd; -static char target_fname[W_MAX_PATH]; +static char target_fname[PATH_MAX]; static unsigned long long filesize; static int hv_start_fcopy(struct hv_start_fcopy *smsg) diff --git a/hyper-v.tools.hv.hv_kvp_daemon.c b/hyper-v.tools.hv.hv_kvp_daemon.c index 7c62c86..546403f 100644 --- a/hyper-v.tools.hv.hv_kvp_daemon.c +++ b/hyper-v.tools.hv.hv_kvp_daemon.c @@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size) * Found a match; just move the remaining * entries up. */ - if (i == num_records) { + if (i == (num_records - 1)) { kvp_file_info[pool].num_records--; kvp_update_file(pool); return 0; @@ -634,64 +634,6 @@ static char *kvp_if_name_to_mac(char *if_name) return mac_addr; } - -/* - * Retrieve the interface name given tha MAC address. - */ - -static char *kvp_mac_to_if_name(char *mac) -{ - DIR *dir; - struct dirent *entry; - FILE *file; - char *p, *x; - char *if_name = NULL; - char buf[256]; - char dev_id[PATH_MAX]; - unsigned int i; - - dir = opendir(KVP_NET_DIR); - if (dir == NULL) - return NULL; - - while ((entry = readdir(dir)) != NULL) { - /* - * Set the state for the next pass. - */ - snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR, - entry->d_name); - - file = fopen(dev_id, "r"); - if (file == NULL) - continue; - - p = fgets(buf, sizeof(buf), file); - if (p) { - x = strchr(p, '\n'); - if (x) - *x = '\0'; - - for (i = 0; i < strlen(p); i++) - p[i] = toupper(p[i]); - - if (!strcmp(p, mac)) { - /* - * Found the MAC match; return the interface - * name. The caller will free the memory. - */ - if_name = strdup(entry->d_name); - fclose(file); - break; - } - } - fclose(file); - } - - closedir(dir); - return if_name; -} - - static void kvp_process_ipconfig_file(char *cmd, char *config_buf, unsigned int len, int element_size, int offset) @@ -997,6 +939,70 @@ getaddr_done: return error; } +/* + * Retrieve the IP given the MAC address. + */ +static int kvp_mac_to_ip(struct hv_kvp_ipaddr_value *kvp_ip_val) +{ + char *mac = (char *)kvp_ip_val->adapter_id; + DIR *dir; + struct dirent *entry; + FILE *file; + char *p, *x; + char *if_name = NULL; + char buf[256]; + char dev_id[PATH_MAX]; + unsigned int i; + int error = HV_E_FAIL; + + dir = opendir(KVP_NET_DIR); + if (dir == NULL) + return HV_E_FAIL; + + while ((entry = readdir(dir)) != NULL) { + /* + * Set the state for the next pass. + */ + snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR, + entry->d_name); + + file = fopen(dev_id, "r"); + if (file == NULL) + continue; + + p = fgets(buf, sizeof(buf), file); + fclose(file); + if (!p) + continue; + + x = strchr(p, '\n'); + if (x) + *x = '\0'; + + for (i = 0; i < strlen(p); i++) + p[i] = toupper(p[i]); + + if (strcmp(p, mac)) + continue; + + /* + * Found the MAC match. + * A NIC (e.g. VF) matching the MAC, but without IP, is skipped. + */ + if_name = entry->d_name; + if (!if_name) + continue; + + error = kvp_get_ip_info(0, if_name, KVP_OP_GET_IP_INFO, + kvp_ip_val, MAX_IP_ADDR_SIZE * 2); + + if (!error && strlen((char *)kvp_ip_val->ip_addr)) + break; + } + + closedir(dir); + return error; +} static int expand_ipv6(char *addr, int type) { @@ -1473,26 +1479,12 @@ int main(int argc, char *argv[]) switch (op) { case KVP_OP_GET_IP_INFO: kvp_ip_val = &hv_msg->body.kvp_ip_val; - if_name = - kvp_mac_to_if_name((char *)kvp_ip_val->adapter_id); - if (if_name == NULL) { - /* - * We could not map the mac address to an - * interface name; return error. - */ - hv_msg->error = HV_E_FAIL; - break; - } - error = kvp_get_ip_info( - 0, if_name, KVP_OP_GET_IP_INFO, - kvp_ip_val, - (MAX_IP_ADDR_SIZE * 2)); + error = kvp_mac_to_ip(kvp_ip_val); if (error) hv_msg->error = error; - free(if_name); break; case KVP_OP_SET_IP_INFO: diff --git a/hyper-v.tools.hv.hv_vss_daemon.c b/hyper-v.tools.hv.hv_vss_daemon.c index bda82cb..0f28129 100644 --- a/hyper-v.tools.hv.hv_vss_daemon.c +++ b/hyper-v.tools.hv.hv_vss_daemon.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include /* Don't use syslog() in the function since that can cause write to disk */ static int vss_do_freeze(char *dir, unsigned int cmd) @@ -68,6 +70,55 @@ static int vss_do_freeze(char *dir, unsigned int cmd) return !!ret; } +static bool is_dev_loop(const char *blkname) +{ + char *buffer; + DIR *dir; + struct dirent *entry; + bool ret = false; + + buffer = malloc(PATH_MAX); + if (!buffer) { + syslog(LOG_ERR, "Can't allocate memory!"); + exit(1); + } + + snprintf(buffer, PATH_MAX, "%s/loop", blkname); + if (!access(buffer, R_OK | X_OK)) { + ret = true; + goto free_buffer; + } else if (errno != ENOENT) { + syslog(LOG_ERR, "Can't access: %s; error:%d %s!", + buffer, errno, strerror(errno)); + } + + snprintf(buffer, PATH_MAX, "%s/slaves", blkname); + dir = opendir(buffer); + if (!dir) { + if (errno != ENOENT) + syslog(LOG_ERR, "Can't opendir: %s; error:%d %s!", + buffer, errno, strerror(errno)); + goto free_buffer; + } + + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + + snprintf(buffer, PATH_MAX, "%s/slaves/%s", blkname, + entry->d_name); + if (is_dev_loop(buffer)) { + ret = true; + break; + } + } + closedir(dir); +free_buffer: + free(buffer); + return ret; +} + static int vss_operate(int operation) { char match[] = "/dev/"; @@ -75,6 +126,7 @@ static int vss_operate(int operation) struct mntent *ent; struct stat sb; char errdir[1024] = {0}; + char blkdir[23]; /* /sys/dev/block/XXX:XXX */ unsigned int cmd; int error = 0, root_seen = 0, save_errno = 0; @@ -96,10 +148,15 @@ static int vss_operate(int operation) while ((ent = getmntent(mounts))) { if (strncmp(ent->mnt_fsname, match, strlen(match))) continue; - if (stat(ent->mnt_fsname, &sb) == -1) - continue; - if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR) - continue; + if (stat(ent->mnt_fsname, &sb)) { + syslog(LOG_ERR, "Can't stat: %s; error:%d %s!", + ent->mnt_fsname, errno, strerror(errno)); + } else { + sprintf(blkdir, "/sys/dev/block/%d:%d", + major(sb.st_rdev), minor(sb.st_rdev)); + if (is_dev_loop(blkdir)) + continue; + } if (hasmntopt(ent, MNTOPT_RO) != NULL) continue; if (strcmp(ent->mnt_type, "vfat") == 0)