diff --git a/0002-Do-not-set-NM_CONTROLLED-no.patch b/0002-Do-not-set-NM_CONTROLLED-no.patch new file mode 100644 index 0000000..563c9f1 --- /dev/null +++ b/0002-Do-not-set-NM_CONTROLLED-no.patch @@ -0,0 +1,24 @@ +From 88be69d62a01b9ac233de7f68118c948623c6f0a Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 14 Nov 2019 09:45:44 +0100 +Subject: Do not set NM_CONTROLLED=no + +--- + hv_set_ifconfig.sh | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh +index 7ed9f85..18b27cc 100644 +--- a/hv_set_ifconfig.sh ++++ b/hv_set_ifconfig.sh +@@ -51,7 +51,6 @@ + + + echo "IPV6INIT=yes" >> $1 +-echo "NM_CONTROLLED=no" >> $1 + echo "PEERDNS=yes" >> $1 + echo "ONBOOT=yes" >> $1 + +-- +2.27.0 + diff --git a/0004-Update-C-files-and-scripts-to-kernel-version-5.7-rc1.patch b/0004-Update-C-files-and-scripts-to-kernel-version-5.7-rc1.patch new file mode 100644 index 0000000..f706a1f --- /dev/null +++ b/0004-Update-C-files-and-scripts-to-kernel-version-5.7-rc1.patch @@ -0,0 +1,345 @@ +From f20c2a3298ceae7536c06bd08a5c571ebfa8cce4 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 6 May 2021 12:50:43 +0200 +Subject: Update C files and scripts to kernel version 5.7-rc1 + +(cherry-picked from RHEL 8.4.0 commit b0a20fac0e74b0b3eecc20ffe74006e7877da352) +Signed-off-by: Miroslav Rezanina +--- + hv_fcopy_daemon.c | 37 +++++++++++++++++++++++++++++++----- + hv_get_dhcp_info.sh | 2 +- + hv_kvp_daemon.c | 35 ++++++++++++++++++++-------------- + hv_set_ifconfig.sh | 2 +- + hv_vss_daemon.c | 46 ++++++++++++++++++++++++++++++++++----------- + 5 files changed, 90 insertions(+), 32 deletions(-) + +diff --git a/hv_fcopy_daemon.c b/hv_fcopy_daemon.c +index aea2d91..16d629b 100644 +--- a/hv_fcopy_daemon.c ++++ b/hv_fcopy_daemon.c +@@ -80,6 +80,8 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg) + + error = 0; + done: ++ if (error) ++ target_fname[0] = '\0'; + return error; + } + +@@ -108,15 +110,29 @@ static int hv_copy_data(struct hv_do_fcopy *cpmsg) + return ret; + } + ++/* ++ * Reset target_fname to "" in the two below functions for hibernation: if ++ * the fcopy operation is aborted by hibernation, the daemon should remove the ++ * partially-copied file; to achieve this, the hv_utils driver always fakes a ++ * CANCEL_FCOPY message upon suspend, and later when the VM resumes back, ++ * the daemon calls hv_copy_cancel() to remove the file; if a file is copied ++ * successfully before suspend, hv_copy_finished() must reset target_fname to ++ * avoid that the file can be incorrectly removed upon resume, since the faked ++ * CANCEL_FCOPY message is spurious in this case. ++ */ + static int hv_copy_finished(void) + { + close(target_fd); ++ target_fname[0] = '\0'; + return 0; + } + static int hv_copy_cancel(void) + { + close(target_fd); +- unlink(target_fname); ++ if (strlen(target_fname) > 0) { ++ unlink(target_fname); ++ target_fname[0] = '\0'; ++ } + return 0; + + } +@@ -131,7 +147,7 @@ void print_usage(char *argv[]) + + int main(int argc, char *argv[]) + { +- int fcopy_fd; ++ int fcopy_fd = -1; + int error; + int daemonize = 1, long_index = 0, opt; + int version = FCOPY_CURRENT_VERSION; +@@ -141,7 +157,7 @@ int main(int argc, char *argv[]) + struct hv_do_fcopy copy; + __u32 kernel_modver; + } buffer = { }; +- int in_handshake = 1; ++ int in_handshake; + + static struct option long_options[] = { + {"help", no_argument, 0, 'h' }, +@@ -170,6 +186,12 @@ int main(int argc, char *argv[]) + openlog("HV_FCOPY", 0, LOG_USER); + syslog(LOG_INFO, "starting; pid is:%d", getpid()); + ++reopen_fcopy_fd: ++ if (fcopy_fd != -1) ++ close(fcopy_fd); ++ /* Remove any possible partially-copied file on error */ ++ hv_copy_cancel(); ++ in_handshake = 1; + fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR); + + if (fcopy_fd < 0) { +@@ -196,7 +218,7 @@ int main(int argc, char *argv[]) + len = pread(fcopy_fd, &buffer, sizeof(buffer), 0); + if (len < 0) { + syslog(LOG_ERR, "pread failed: %s", strerror(errno)); +- exit(EXIT_FAILURE); ++ goto reopen_fcopy_fd; + } + + if (in_handshake) { +@@ -231,9 +253,14 @@ int main(int argc, char *argv[]) + + } + ++ /* ++ * pwrite() may return an error due to the faked CANCEL_FCOPY ++ * message upon hibernation. Ignore the error by resetting the ++ * dev file, i.e. closing and re-opening it. ++ */ + if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) { + syslog(LOG_ERR, "pwrite failed: %s", strerror(errno)); +- exit(EXIT_FAILURE); ++ goto reopen_fcopy_fd; + } + } + } +diff --git a/hv_get_dhcp_info.sh b/hv_get_dhcp_info.sh +index c38686c..2f2a3c7 100644 +--- a/hv_get_dhcp_info.sh ++++ b/hv_get_dhcp_info.sh +@@ -13,7 +13,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/hv_kvp_daemon.c b/hv_kvp_daemon.c +index e9ef4ca..0e5f14a 100644 +--- a/hv_kvp_daemon.c ++++ b/hv_kvp_daemon.c +@@ -76,7 +76,7 @@ enum { + DNS + }; + +-static int in_hand_shake = 1; ++static int in_hand_shake; + + static char *os_name = ""; + static char *os_major = ""; +@@ -1360,7 +1360,7 @@ void print_usage(char *argv[]) + + int main(int argc, char *argv[]) + { +- int kvp_fd, len; ++ int kvp_fd = -1, len; + int error; + struct pollfd pfd; + char *p; +@@ -1400,14 +1400,6 @@ int main(int argc, char *argv[]) + openlog("KVP", 0, LOG_USER); + syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); + +- kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC); +- +- if (kvp_fd < 0) { +- syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s", +- errno, strerror(errno)); +- exit(EXIT_FAILURE); +- } +- + /* + * Retrieve OS release information. + */ +@@ -1423,6 +1415,18 @@ int main(int argc, char *argv[]) + exit(EXIT_FAILURE); + } + ++reopen_kvp_fd: ++ if (kvp_fd != -1) ++ close(kvp_fd); ++ in_hand_shake = 1; ++ kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC); ++ ++ if (kvp_fd < 0) { ++ syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s", ++ errno, strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++ + /* + * Register ourselves with the kernel. + */ +@@ -1457,8 +1461,7 @@ int main(int argc, char *argv[]) + syslog(LOG_ERR, "read failed; error:%d %s", + errno, strerror(errno)); + +- close(kvp_fd); +- return EXIT_FAILURE; ++ goto reopen_kvp_fd; + } + + /* +@@ -1617,13 +1620,17 @@ int main(int argc, char *argv[]) + break; + } + +- /* Send the value back to the kernel. */ ++ /* ++ * Send the value back to the kernel. Note: the write() may ++ * return an error due to hibernation; we can ignore the error ++ * by resetting the dev file, i.e. closing and re-opening it. ++ */ + kvp_done: + len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg)); + if (len != sizeof(struct hv_kvp_msg)) { + syslog(LOG_ERR, "write failed; error: %d %s", errno, + strerror(errno)); +- exit(EXIT_FAILURE); ++ goto reopen_kvp_fd; + } + } + +diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh +index 18b27cc..3dd064c 100644 +--- a/hv_set_ifconfig.sh ++++ b/hv_set_ifconfig.sh +@@ -12,7 +12,7 @@ + # be used to configure the interface. + # + # 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 configuring the + # interface. + # +diff --git a/hv_vss_daemon.c b/hv_vss_daemon.c +index 92902a8..29a1e48 100644 +--- a/hv_vss_daemon.c ++++ b/hv_vss_daemon.c +@@ -28,6 +28,8 @@ + #include + #include + ++static bool fs_frozen; ++ + /* Don't use syslog() in the function since that can cause write to disk */ + static int vss_do_freeze(char *dir, unsigned int cmd) + { +@@ -155,16 +157,22 @@ static int vss_operate(int operation) + continue; + } + error |= vss_do_freeze(ent->mnt_dir, cmd); +- if (error && operation == VSS_OP_FREEZE) +- goto err; ++ if (operation == VSS_OP_FREEZE) { ++ if (error) ++ goto err; ++ fs_frozen = true; ++ } + } + + endmntent(mounts); + + if (root_seen) { + error |= vss_do_freeze("/", cmd); +- if (error && operation == VSS_OP_FREEZE) +- goto err; ++ if (operation == VSS_OP_FREEZE) { ++ if (error) ++ goto err; ++ fs_frozen = true; ++ } + } + + goto out; +@@ -175,6 +183,7 @@ err: + endmntent(mounts); + } + vss_operate(VSS_OP_THAW); ++ fs_frozen = false; + /* Call syslog after we thaw all filesystems */ + if (ent) + syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s", +@@ -196,13 +205,13 @@ void print_usage(char *argv[]) + + int main(int argc, char *argv[]) + { +- int vss_fd, len; ++ int vss_fd = -1, len; + int error; + struct pollfd pfd; + int op; + struct hv_vss_msg vss_msg[1]; + int daemonize = 1, long_index = 0, opt; +- int in_handshake = 1; ++ int in_handshake; + __u32 kernel_modver; + + static struct option long_options[] = { +@@ -232,6 +241,18 @@ int main(int argc, char *argv[]) + openlog("Hyper-V VSS", 0, LOG_USER); + syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); + ++reopen_vss_fd: ++ if (vss_fd != -1) ++ close(vss_fd); ++ if (fs_frozen) { ++ if (vss_operate(VSS_OP_THAW) || fs_frozen) { ++ syslog(LOG_ERR, "failed to thaw file system: err=%d", ++ errno); ++ exit(EXIT_FAILURE); ++ } ++ } ++ ++ in_handshake = 1; + vss_fd = open("/dev/vmbus/hv_vss", O_RDWR); + if (vss_fd < 0) { + syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s", +@@ -247,8 +268,7 @@ int main(int argc, char *argv[]) + if (len < 0) { + syslog(LOG_ERR, "registration to kernel failed; error: %d %s", + errno, strerror(errno)); +- close(vss_fd); +- exit(EXIT_FAILURE); ++ goto reopen_vss_fd; + } + + pfd.fd = vss_fd; +@@ -312,14 +332,18 @@ int main(int argc, char *argv[]) + default: + syslog(LOG_ERR, "Illegal op:%d\n", op); + } ++ ++ /* ++ * The write() may return an error due to the faked VSS_OP_THAW ++ * message upon hibernation. Ignore the error by resetting the ++ * dev file, i.e. closing and re-opening it. ++ */ + vss_msg->error = error; + len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg)); + if (len != sizeof(struct hv_vss_msg)) { + syslog(LOG_ERR, "write failed; error: %d %s", errno, + strerror(errno)); +- +- if (op == VSS_OP_FREEZE) +- vss_operate(VSS_OP_THAW); ++ goto reopen_vss_fd; + } + } + +-- +2.27.0 + diff --git a/0005-Add-vmbus_testing-tool-build-files.patch b/0005-Add-vmbus_testing-tool-build-files.patch new file mode 100644 index 0000000..92f2717 --- /dev/null +++ b/0005-Add-vmbus_testing-tool-build-files.patch @@ -0,0 +1,401 @@ +From a13aa83d1b5bb4b6ce4396aef3457b48695b7c41 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 6 May 2021 12:53:31 +0200 +Subject: Add vmbus_testing tool build files + +Add the vmbus_testing tool to redhat build dirs + +(cherry-pick from rhel 8.4.0 commit d8ca5e0) +Signed-off-by: Mohammed Gamal +Signed-off-by: Miroslav Rezanina +--- + .distro/hyperv-daemons.spec.template | 2 + + vmbus_testing | 376 +++++++++++++++++++++++++++ + 2 files changed, 378 insertions(+) + create mode 100755 vmbus_testing + +diff --git a/vmbus_testing b/vmbus_testing +new file mode 100755 +index 0000000..e721290 +--- /dev/null ++++ b/vmbus_testing +@@ -0,0 +1,376 @@ ++#!/usr/bin/env python3 ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Program to allow users to fuzz test Hyper-V drivers ++# by interfacing with Hyper-V debugfs attributes. ++# Current test methods available: ++# 1. delay testing ++# ++# Current file/directory structure of hyper-V debugfs: ++# /sys/kernel/debug/hyperv/UUID ++# /sys/kernel/debug/hyperv/UUID/ ++# /sys/kernel/debug/hyperv/UUID/ ++# ++# author: Branden Bonaby ++ ++import os ++import cmd ++import argparse ++import glob ++from argparse import RawDescriptionHelpFormatter ++from argparse import RawTextHelpFormatter ++from enum import Enum ++ ++# Do not change unless, you change the debugfs attributes ++# in /drivers/hv/debugfs.c. All fuzz testing ++# attributes will start with "fuzz_test". ++ ++# debugfs path for hyperv must exist before proceeding ++debugfs_hyperv_path = "/sys/kernel/debug/hyperv" ++if not os.path.isdir(debugfs_hyperv_path): ++ print("{} doesn't exist/check permissions".format(debugfs_hyperv_path)) ++ exit(-1) ++ ++class dev_state(Enum): ++ off = 0 ++ on = 1 ++ ++# File names, that correspond to the files created in ++# /drivers/hv/debugfs.c ++class f_names(Enum): ++ state_f = "fuzz_test_state" ++ buff_f = "fuzz_test_buffer_interrupt_delay" ++ mess_f = "fuzz_test_message_delay" ++ ++# Both single_actions and all_actions are used ++# for error checking and to allow for some subparser ++# names to be abbreviated. Do not abbreviate the ++# test method names, as it will become less intuitive ++# as to what the user can do. If you do decide to ++# abbreviate the test method name, make sure the main ++# function reflects this change. ++ ++all_actions = [ ++ "disable_all", ++ "D", ++ "enable_all", ++ "view_all", ++ "V" ++] ++ ++single_actions = [ ++ "disable_single", ++ "d", ++ "enable_single", ++ "view_single", ++ "v" ++] ++ ++def main(): ++ ++ file_map = recursive_file_lookup(debugfs_hyperv_path, dict()) ++ args = parse_args() ++ if (not args.action): ++ print ("Error, no options selected...exiting") ++ exit(-1) ++ arg_set = { k for (k,v) in vars(args).items() if v and k != "action" } ++ arg_set.add(args.action) ++ path = args.path if "path" in arg_set else None ++ if (path and path[-1] == "/"): ++ path = path[:-1] ++ validate_args_path(path, arg_set, file_map) ++ if (path and "enable_single" in arg_set): ++ state_path = locate_state(path, file_map) ++ set_test_state(state_path, dev_state.on.value, args.quiet) ++ ++ # Use subparsers as the key for different actions ++ if ("delay" in arg_set): ++ validate_delay_values(args.delay_time) ++ if (args.enable_all): ++ set_delay_all_devices(file_map, args.delay_time, ++ args.quiet) ++ else: ++ set_delay_values(path, file_map, args.delay_time, ++ args.quiet) ++ elif ("disable_all" in arg_set or "D" in arg_set): ++ disable_all_testing(file_map) ++ elif ("disable_single" in arg_set or "d" in arg_set): ++ disable_testing_single_device(path, file_map) ++ elif ("view_all" in arg_set or "V" in arg_set): ++ get_all_devices_test_status(file_map) ++ elif ("view_single" in arg_set or "v" in arg_set): ++ get_device_test_values(path, file_map) ++ ++# Get the state location ++def locate_state(device, file_map): ++ return file_map[device][f_names.state_f.value] ++ ++# Validate delay values to make sure they are acceptable to ++# enable delays on a device ++def validate_delay_values(delay): ++ ++ if (delay[0] == -1 and delay[1] == -1): ++ print("\nError, At least 1 value must be greater than 0") ++ exit(-1) ++ for i in delay: ++ if (i < -1 or i == 0 or i > 1000): ++ print("\nError, Values must be equal to -1 " ++ "or be > 0 and <= 1000") ++ exit(-1) ++ ++# Validate argument path ++def validate_args_path(path, arg_set, file_map): ++ ++ if (not path and any(element in arg_set for element in single_actions)): ++ print("Error, path (-p) REQUIRED for the specified option. " ++ "Use (-h) to check usage.") ++ exit(-1) ++ elif (path and any(item in arg_set for item in all_actions)): ++ print("Error, path (-p) NOT REQUIRED for the specified option. " ++ "Use (-h) to check usage." ) ++ exit(-1) ++ elif (path not in file_map and any(item in arg_set ++ for item in single_actions)): ++ print("Error, path '{}' not a valid vmbus device".format(path)) ++ exit(-1) ++ ++# display Testing status of single device ++def get_device_test_values(path, file_map): ++ ++ for name in file_map[path]: ++ file_location = file_map[path][name] ++ print( name + " = " + str(read_test_files(file_location))) ++ ++# Create a map of the vmbus devices and their associated files ++# [key=device, value = [key = filename, value = file path]] ++def recursive_file_lookup(path, file_map): ++ ++ for f_path in glob.iglob(path + '**/*'): ++ if (os.path.isfile(f_path)): ++ if (f_path.rsplit("/",2)[0] == debugfs_hyperv_path): ++ directory = f_path.rsplit("/",1)[0] ++ else: ++ directory = f_path.rsplit("/",2)[0] ++ f_name = f_path.split("/")[-1] ++ if (file_map.get(directory)): ++ file_map[directory].update({f_name:f_path}) ++ else: ++ file_map[directory] = {f_name:f_path} ++ elif (os.path.isdir(f_path)): ++ recursive_file_lookup(f_path,file_map) ++ return file_map ++ ++# display Testing state of devices ++def get_all_devices_test_status(file_map): ++ ++ for device in file_map: ++ if (get_test_state(locate_state(device, file_map)) is 1): ++ print("Testing = ON for: {}" ++ .format(device.split("/")[5])) ++ else: ++ print("Testing = OFF for: {}" ++ .format(device.split("/")[5])) ++ ++# read the vmbus device files, path must be absolute path before calling ++def read_test_files(path): ++ try: ++ with open(path,"r") as f: ++ file_value = f.readline().strip() ++ return int(file_value) ++ ++ except IOError as e: ++ errno, strerror = e.args ++ print("I/O error({0}): {1} on file {2}" ++ .format(errno, strerror, path)) ++ exit(-1) ++ except ValueError: ++ print ("Element to int conversion error in: \n{}".format(path)) ++ exit(-1) ++ ++# writing to vmbus device files, path must be absolute path before calling ++def write_test_files(path, value): ++ ++ try: ++ with open(path,"w") as f: ++ f.write("{}".format(value)) ++ except IOError as e: ++ errno, strerror = e.args ++ print("I/O error({0}): {1} on file {2}" ++ .format(errno, strerror, path)) ++ exit(-1) ++ ++# set testing state of device ++def set_test_state(state_path, state_value, quiet): ++ ++ write_test_files(state_path, state_value) ++ if (get_test_state(state_path) is 1): ++ if (not quiet): ++ print("Testing = ON for device: {}" ++ .format(state_path.split("/")[5])) ++ else: ++ if (not quiet): ++ print("Testing = OFF for device: {}" ++ .format(state_path.split("/")[5])) ++ ++# get testing state of device ++def get_test_state(state_path): ++ #state == 1 - test = ON ++ #state == 0 - test = OFF ++ return read_test_files(state_path) ++ ++# write 1 - 1000 microseconds, into a single device using the ++# fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay ++# debugfs attributes ++def set_delay_values(device, file_map, delay_length, quiet): ++ ++ try: ++ interrupt = file_map[device][f_names.buff_f.value] ++ message = file_map[device][f_names.mess_f.value] ++ ++ # delay[0]- buffer interrupt delay, delay[1]- message delay ++ if (delay_length[0] >= 0 and delay_length[0] <= 1000): ++ write_test_files(interrupt, delay_length[0]) ++ if (delay_length[1] >= 0 and delay_length[1] <= 1000): ++ write_test_files(message, delay_length[1]) ++ if (not quiet): ++ print("Buffer delay testing = {} for: {}" ++ .format(read_test_files(interrupt), ++ interrupt.split("/")[5])) ++ print("Message delay testing = {} for: {}" ++ .format(read_test_files(message), ++ message.split("/")[5])) ++ except IOError as e: ++ errno, strerror = e.args ++ print("I/O error({0}): {1} on files {2}{3}" ++ .format(errno, strerror, interrupt, message)) ++ exit(-1) ++ ++# enabling delay testing on all devices ++def set_delay_all_devices(file_map, delay, quiet): ++ ++ for device in (file_map): ++ set_test_state(locate_state(device, file_map), ++ dev_state.on.value, ++ quiet) ++ set_delay_values(device, file_map, delay, quiet) ++ ++# disable all testing on a SINGLE device. ++def disable_testing_single_device(device, file_map): ++ ++ for name in file_map[device]: ++ file_location = file_map[device][name] ++ write_test_files(file_location, dev_state.off.value) ++ print("ALL testing now OFF for {}".format(device.split("/")[-1])) ++ ++# disable all testing on ALL devices ++def disable_all_testing(file_map): ++ ++ for device in file_map: ++ disable_testing_single_device(device, file_map) ++ ++def parse_args(): ++ parser = argparse.ArgumentParser(prog = "vmbus_testing",usage ="\n" ++ "%(prog)s [delay] [-h] [-e|-E] -t [-p]\n" ++ "%(prog)s [view_all | V] [-h]\n" ++ "%(prog)s [disable_all | D] [-h]\n" ++ "%(prog)s [disable_single | d] [-h|-p]\n" ++ "%(prog)s [view_single | v] [-h|-p]\n" ++ "%(prog)s --version\n", ++ description = "\nUse lsvmbus to get vmbus device type " ++ "information.\n" "\nThe debugfs root path is " ++ "/sys/kernel/debug/hyperv", ++ formatter_class = RawDescriptionHelpFormatter) ++ subparsers = parser.add_subparsers(dest = "action") ++ parser.add_argument("--version", action = "version", ++ version = '%(prog)s 0.1.0') ++ parser.add_argument("-q","--quiet", action = "store_true", ++ help = "silence none important test messages." ++ " This will only work when enabling testing" ++ " on a device.") ++ # Use the path parser to hold the --path attribute so it can ++ # be shared between subparsers. Also do the same for the state ++ # parser, as all testing methods will use --enable_all and ++ # enable_single. ++ path_parser = argparse.ArgumentParser(add_help=False) ++ path_parser.add_argument("-p","--path", metavar = "", ++ help = "Debugfs path to a vmbus device. The path " ++ "must be the absolute path to the device.") ++ state_parser = argparse.ArgumentParser(add_help=False) ++ state_group = state_parser.add_mutually_exclusive_group(required = True) ++ state_group.add_argument("-E", "--enable_all", action = "store_const", ++ const = "enable_all", ++ help = "Enable the specified test type " ++ "on ALL vmbus devices.") ++ state_group.add_argument("-e", "--enable_single", ++ action = "store_const", ++ const = "enable_single", ++ help = "Enable the specified test type on a " ++ "SINGLE vmbus device.") ++ parser_delay = subparsers.add_parser("delay", ++ parents = [state_parser, path_parser], ++ help = "Delay the ring buffer interrupt or the " ++ "ring buffer message reads in microseconds.", ++ prog = "vmbus_testing", ++ usage = "%(prog)s [-h]\n" ++ "%(prog)s -E -t [value] [value]\n" ++ "%(prog)s -e -t [value] [value] -p", ++ description = "Delay the ring buffer interrupt for " ++ "vmbus devices, or delay the ring buffer message " ++ "reads for vmbus devices (both in microseconds). This " ++ "is only on the host to guest channel.") ++ parser_delay.add_argument("-t", "--delay_time", metavar = "", nargs = 2, ++ type = check_range, default =[0,0], required = (True), ++ help = "Set [buffer] & [message] delay time. " ++ "Value constraints: -1 == value " ++ "or 0 < value <= 1000.\n" ++ "Use -1 to keep the previous value for that delay " ++ "type, or a value > 0 <= 1000 to change the delay " ++ "time.") ++ parser_dis_all = subparsers.add_parser("disable_all", ++ aliases = ['D'], prog = "vmbus_testing", ++ usage = "%(prog)s [disable_all | D] -h\n" ++ "%(prog)s [disable_all | D]\n", ++ help = "Disable ALL testing on ALL vmbus devices.", ++ description = "Disable ALL testing on ALL vmbus " ++ "devices.") ++ parser_dis_single = subparsers.add_parser("disable_single", ++ aliases = ['d'], ++ parents = [path_parser], prog = "vmbus_testing", ++ usage = "%(prog)s [disable_single | d] -h\n" ++ "%(prog)s [disable_single | d] -p\n", ++ help = "Disable ALL testing on a SINGLE vmbus device.", ++ description = "Disable ALL testing on a SINGLE vmbus " ++ "device.") ++ parser_view_all = subparsers.add_parser("view_all", aliases = ['V'], ++ help = "View the test state for ALL vmbus devices.", ++ prog = "vmbus_testing", ++ usage = "%(prog)s [view_all | V] -h\n" ++ "%(prog)s [view_all | V]\n", ++ description = "This shows the test state for ALL the " ++ "vmbus devices.") ++ parser_view_single = subparsers.add_parser("view_single", ++ aliases = ['v'],parents = [path_parser], ++ help = "View the test values for a SINGLE vmbus " ++ "device.", ++ description = "This shows the test values for a SINGLE " ++ "vmbus device.", prog = "vmbus_testing", ++ usage = "%(prog)s [view_single | v] -h\n" ++ "%(prog)s [view_single | v] -p") ++ ++ return parser.parse_args() ++ ++# value checking for range checking input in parser ++def check_range(arg1): ++ ++ try: ++ val = int(arg1) ++ except ValueError as err: ++ raise argparse.ArgumentTypeError(str(err)) ++ if val < -1 or val > 1000: ++ message = ("\n\nvalue must be -1 or 0 < value <= 1000. " ++ "Value program received: {}\n").format(val) ++ raise argparse.ArgumentTypeError(message) ++ return val ++ ++if __name__ == "__main__": ++ main() +-- +2.27.0 + diff --git a/0006-tools-hv-change-http-to-https-in-hv_kvp_daemon.c.patch b/0006-tools-hv-change-http-to-https-in-hv_kvp_daemon.c.patch new file mode 100644 index 0000000..a6c7947 --- /dev/null +++ b/0006-tools-hv-change-http-to-https-in-hv_kvp_daemon.c.patch @@ -0,0 +1,56 @@ +From 6ed9946f9a4f1a01846add2279e8d0640c1c2f1c Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 6 May 2021 12:53:58 +0200 +Subject: tools: hv: change http to https in hv_kvp_daemon.c + +The patch has no functional change. Only changes the URL pointed to +in one of the comments + +commit fa52a4b2d0ab416508538bb47a95167d4c94caac +Author: Alexander A. Klimov +Date: Sun Jul 5 23:44:57 2020 +0200 + + tools: hv: change http to https in hv_kvp_daemon.c + + Rationale: + Reduces attack surface on kernel devs opening the links for MITM + as HTTPS traffic is much harder to manipulate. + + Deterministic algorithm: + For each file: + If not .svg: + For each line: + If doesn't contain `\bxmlns\b`: + For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: + If both the HTTP and HTTPS versions + return 200 OK and serve the same content: + Replace HTTP with HTTPS. + + Signed-off-by: Alexander A. Klimov + Link: https://lore.kernel.org/r/20200705214457.28433-1-grandmaster@al2klimov.de + [ wei: change subject line to be more specific ] + Signed-off-by: Wei Liu + +Signed-off-by: Mohammed Gamal +(cherry-picked from rhel 8.4.0 commit e956573) +Signed-off-by: Miroslav Rezanina +--- + hv_kvp_daemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c +index 0e5f14a..c06c94d 100644 +--- a/hv_kvp_daemon.c ++++ b/hv_kvp_daemon.c +@@ -437,7 +437,7 @@ void kvp_get_os_info(void) + + /* + * Parse the /etc/os-release file if present: +- * http://www.freedesktop.org/software/systemd/man/os-release.html ++ * https://www.freedesktop.org/software/systemd/man/os-release.html + */ + file = fopen("/etc/os-release", "r"); + if (file != NULL) { +-- +2.27.0 + diff --git a/hyperv-daemons.spec b/hyperv-daemons.spec index 69a49a5..f0258af 100644 --- a/hyperv-daemons.spec +++ b/hyperv-daemons.spec @@ -13,7 +13,7 @@ Name: hyperv-daemons Version: 0 -Release: 0.35%{?snapver}%{?dist} +Release: 0.36%{?snapver}%{?dist} Summary: Hyper-V daemons suite License: GPLv2 @@ -44,6 +44,10 @@ Source202: hypervfcopy.rules # HYPERV TOOLS Source301: lsvmbus +Patch0002: 0002-Do-not-set-NM_CONTROLLED-no.patch +Patch0004: 0004-Update-C-files-and-scripts-to-kernel-version-5.7-rc1.patch +Patch0005: 0005-Add-vmbus_testing-tool-build-files.patch +Patch0006: 0006-tools-hv-change-http-to-https-in-hv_kvp_daemon.c.patch # Hyper-V is available only on x86 architectures # The base empty (a.k.a. virtual) package can not be noarch # due to http://www.rpm.org/ticket/78 @@ -54,6 +58,7 @@ Requires: hypervvssd = %{version}-%{release} Requires: hypervfcopyd = %{version}-%{release} BuildRequires: gcc + %description Suite of daemons that are needed when Linux guest is running on Windows Host with Hyper-V. @@ -127,11 +132,25 @@ Contains tools and scripts useful for Hyper-V guests. cp -pvL %{SOURCE0} COPYING cp -pvL %{SOURCE1} hv_kvp_daemon.c +cp -pvL %{SOURCE2} hv_get_dhcp_info.sh +cp -pvL %{SOURCE3} hv_get_dns_info.sh +cp -pvL %{SOURCE4} hv_set_ifconfig.sh +cp -pvL %{SOURCE5} hypervkvpd.service +cp -pvL %{SOURCE6} hypervkvp.rules cp -pvL %{SOURCE100} hv_vss_daemon.c +cp -pvL %{SOURCE101} hypervvssd.service +cp -pvL %{SOURCE102} hypervvss.rules cp -pvL %{SOURCE200} hv_fcopy_daemon.c +cp -pvL %{SOURCE201} hypervfcopyd.service +cp -pvL %{SOURCE202} hypervfcopy.rules cp -pvL %{SOURCE301} lsvmbus +%patch0002 -p1 +%patch0004 -p1 +%patch0005 -p1 +%patch0006 -p1 + %build # HYPERV KVP DAEMON %{__cc} $RPM_OPT_FLAGS -c hv_kvp_daemon.c @@ -154,25 +173,26 @@ install -p -m 0755 %{hv_vss_daemon} %{buildroot}%{_sbindir} install -p -m 0755 %{hv_fcopy_daemon} %{buildroot}%{_sbindir} # Systemd unit file mkdir -p %{buildroot}%{_unitdir} -install -p -m 0644 %{SOURCE5} %{buildroot}%{_unitdir} -install -p -m 0644 %{SOURCE101} %{buildroot}%{_unitdir} -install -p -m 0644 %{SOURCE201} %{buildroot}%{_unitdir} +install -p -m 0644 hypervkvpd.service %{buildroot}%{_unitdir} +install -p -m 0644 hypervvssd.service %{buildroot}%{_unitdir} +install -p -m 0644 hypervfcopyd.service %{buildroot}%{_unitdir} # Udev rules mkdir -p %{buildroot}%{_udevrulesdir} -install -p -m 0644 %{SOURCE6} %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervkvp.rules -install -p -m 0644 %{SOURCE102} %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervvss.rules -install -p -m 0644 %{SOURCE202} %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervfcopy.rules +install -p -m 0644 hypervkvp.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervkvp.rules +install -p -m 0644 hypervvss.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervvss.rules +install -p -m 0644 hypervfcopy.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervfcopy.rules # Shell scripts for the KVP daemon mkdir -p %{buildroot}%{_libexecdir}/%{hv_kvp_daemon} -install -p -m 0755 %{SOURCE2} %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_get_dhcp_info -install -p -m 0755 %{SOURCE3} %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_get_dns_info -install -p -m 0755 %{SOURCE4} %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_set_ifconfig +install -p -m 0755 hv_get_dhcp_info.sh %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_get_dhcp_info +install -p -m 0755 hv_get_dns_info.sh %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_get_dns_info +install -p -m 0755 hv_set_ifconfig.sh %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_set_ifconfig # Directory for pool files mkdir -p %{buildroot}%{_sharedstatedir}/hyperv # Tools install -p -m 0755 lsvmbus %{buildroot}%{_sbindir}/ -sed -i 's,#!/usr/bin/env python,#!/usr/bin/python3,' %{buildroot}%{_sbindir}/lsvmbus +sed -i 's,#!/usr/bin/env python,#!%{__python3},' %{buildroot}%{_sbindir}/lsvmbus +install -p -m 0755 vmbus_testing %{buildroot}%{_sbindir}/ %post -n hypervkvpd if [ $1 -gt 1 ] ; then @@ -244,8 +264,14 @@ fi %files -n hyperv-tools %{_sbindir}/lsvmbus +%{_sbindir}/vmbus_testing %changelog +* Mon May 10 2021 Miroslav Rezanina - 0-0.36.20190303git +- Synchronize RHEL 8 changes [rhbz#1957651] +- Resolves: rhbz#1957651 + ([Hyper-V][RHEL-9] Update build to rhel format and syncup RHEL 8 content for hyperv-daemons.) + * Fri Apr 16 2021 Mohan Boddu - 0-0.35.20190303git - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937