* [PATCH v2 1/3] drivers: hv: vmbus: Introduce latency testing
2019-08-20 2:44 [PATCH v2 0/3] hv: vmbus: add fuzz testing to hv device Branden Bonaby
@ 2019-08-20 2:44 ` Branden Bonaby
2019-08-21 22:52 ` Michael Kelley
2019-08-20 2:44 ` [PATCH v2 2/3] drivers: hv: vmbus: add test attributes to debugfs Branden Bonaby
2019-08-20 2:45 ` [PATCH v2 3/3] tools: hv: add vmbus testing tool Branden Bonaby
2 siblings, 1 reply; 9+ messages in thread
From: Branden Bonaby @ 2019-08-20 2:44 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, sashal
Cc: Branden Bonaby, linux-hyperv, linux-kernel
Introduce user specified latency in the packet reception path.
Signed-off-by: Branden Bonaby <brandonbonaby94@gmail.com>
---
Changes in v2:
- Add #ifdef in Kconfig file so test code will not interfere
with non-test code.
- Move test code functions for delay to hyperv_vmbus header
file.
- Wrap test code under #ifdef statement.
drivers/hv/Kconfig | 7 +++++++
drivers/hv/connection.c | 3 +++
drivers/hv/hyperv_vmbus.h | 20 ++++++++++++++++++++
drivers/hv/ring_buffer.c | 7 +++++++
include/linux/hyperv.h | 21 +++++++++++++++++++++
5 files changed, 58 insertions(+)
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 9a59957922d4..d97437ba0626 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -29,4 +29,11 @@ config HYPERV_BALLOON
help
Select this option to enable Hyper-V Balloon driver.
+config HYPERV_TESTING
+ bool "Hyper-V testing"
+ default n
+ depends on HYPERV && DEBUG_FS
+ help
+ Select this option to enable Hyper-V vmbus testing.
+
endmenu
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 09829e15d4a0..c9c63a4033cd 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -357,6 +357,9 @@ void vmbus_on_event(unsigned long data)
trace_vmbus_on_event(channel);
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_delay_test(channel, INTERRUPT_DELAY);
+#endif /* CONFIG_HYPERV_TESTING */
do {
void (*callback_fn)(void *);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 362e70e9d145..edf14f596d8c 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -357,4 +357,24 @@ enum hvutil_device_state {
HVUTIL_DEVICE_DYING, /* driver unload is in progress */
};
+#ifdef CONFIG_HYPERV_TESTING
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#define TESTING "hyperv"
+
+enum delay {
+ INTERRUPT_DELAY = 0,
+ MESSAGE_DELAY = 1,
+};
+
+int hv_debug_delay_files(struct hv_device *dev, struct dentry *root);
+int hv_debug_add_dev_dir(struct hv_device *dev);
+void hv_debug_rm_dev_dir(struct hv_device *dev);
+void hv_debug_rm_all_dir(void);
+void hv_debug_set_dir_dentry(struct hv_device *dev, struct dentry *root);
+void hv_debug_delay_test(struct vmbus_channel *channel, enum delay delay_type);
+
+#endif /* CONFIG_HYPERV_TESTING */
+
#endif /* _HYPERV_VMBUS_H */
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 9a03b163cbbd..51adda23b398 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -396,6 +396,10 @@ struct vmpacket_descriptor *hv_pkt_iter_first(struct vmbus_channel *channel)
struct hv_ring_buffer_info *rbi = &channel->inbound;
struct vmpacket_descriptor *desc;
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_delay_test(channel, MESSAGE_DELAY);
+#endif /* CONFIG_HYPERV_TESTING */
+
if (hv_pkt_iter_avail(rbi) < sizeof(struct vmpacket_descriptor))
return NULL;
@@ -421,6 +425,9 @@ __hv_pkt_iter_next(struct vmbus_channel *channel,
u32 packetlen = desc->len8 << 3;
u32 dsize = rbi->ring_datasize;
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_delay_test(channel, MESSAGE_DELAY);
+#endif /* CONFIG_HYPERV_TESTING */
/* bump offset to next potential packet */
rbi->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
if (rbi->priv_read_index >= dsize)
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 6256cc34c4a6..6bf8ef5c780c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -926,6 +926,21 @@ struct vmbus_channel {
* full outbound ring buffer.
*/
u64 out_full_first;
+
+#ifdef CONFIG_HYPERV_TESTING
+ /* enabling/disabling fuzz testing on the channel (default is false)*/
+ bool fuzz_testing_state;
+
+ /* Interrupt delay will delay the guest from emptying the ring buffer
+ * for a specific amount of time. The delay is in microseconds and will
+ * be between 1 to a maximum of 1000, its default is 0 (no delay).
+ * The Message delay will delay guest reading on a per message basis
+ * in microseconds between 1 to 1000 with the default being 0
+ * (no delay).
+ */
+ u32 fuzz_testing_interrupt_delay;
+ u32 fuzz_testing_message_delay;
+#endif /* CONFIG_HYPERV_TESTING */
};
static inline bool is_hvsock_channel(const struct vmbus_channel *c)
@@ -1166,6 +1181,12 @@ struct hv_device {
struct vmbus_channel *channel;
struct kset *channels_kset;
+
+#ifdef CONFIG_HYPERV_TESTING
+ /* place holder to keep track of the dir for hv device in debugfs */
+ struct dentry *debug_dir;
+#endif /* CONFIG_HYPERV_TESTING */
+
};
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] drivers: hv: vmbus: add test attributes to debugfs
2019-08-20 2:44 [PATCH v2 0/3] hv: vmbus: add fuzz testing to hv device Branden Bonaby
2019-08-20 2:44 ` [PATCH v2 1/3] drivers: hv: vmbus: Introduce latency testing Branden Bonaby
@ 2019-08-20 2:44 ` Branden Bonaby
2019-08-20 18:17 ` Branden Bonaby
2019-08-20 2:45 ` [PATCH v2 3/3] tools: hv: add vmbus testing tool Branden Bonaby
2 siblings, 1 reply; 9+ messages in thread
From: Branden Bonaby @ 2019-08-20 2:44 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, sashal
Cc: Branden Bonaby, linux-hyperv, linux-kernel
Expose the test parameters as part of the debugfs channel attributes.
We will control the testing state via these attributes.
Signed-off-by: Branden Bonaby <brandonbonaby94@gmail.com>
---
Changes in v2:
- Move test attributes to debugfs.
- Wrap test code under #ifdef statements.
- Add new documentation file under Documentation/ABI/testing.
- Make commit message reflect the change from from sysfs to debugfs.
Documentation/ABI/testing/debugfs-hyperv | 21 +++
MAINTAINERS | 1 +
drivers/hv/vmbus_drv.c | 167 +++++++++++++++++++++++
3 files changed, 189 insertions(+)
create mode 100644 Documentation/ABI/testing/debugfs-hyperv
diff --git a/Documentation/ABI/testing/debugfs-hyperv b/Documentation/ABI/testing/debugfs-hyperv
new file mode 100644
index 000000000000..b25f751fafa8
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-hyperv
@@ -0,0 +1,21 @@
+What: /sys/kernel/debug/hyperv/<UUID>/fuzz_test_state
+Date: August 2019
+KernelVersion: 5.3
+Contact: Branden Bonaby <brandonbonaby94@gmail.com>
+Description: Fuzz testing status of a vmbus device, whether its in an ON
+ state or a OFF state
+Users: Debugging tools
+
+What: /sys/kernel/debug/hyperv/<UUID>/delay/fuzz_test_buffer_interrupt_delay
+Date: August 2019
+KernelVersion: 5.3
+Contact: Branden Bonaby <brandonbonaby94@gmail.com>
+Description: Fuzz testing buffer delay value between 0 - 1000
+Users: Debugging tools
+
+What: /sys/kernel/debug/hyperv/<UUID>/delay/fuzz_test_message_delay
+Date: August 2019
+KernelVersion: 5.3
+Contact: Branden Bonaby <brandonbonaby94@gmail.com>
+Description: Fuzz testing message delay value between 0 - 1000
+Users: Debugging tools
diff --git a/MAINTAINERS b/MAINTAINERS
index e81e60bd7c26..120284a8185f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7460,6 +7460,7 @@ F: include/uapi/linux/hyperv.h
F: include/asm-generic/mshyperv.h
F: tools/hv/
F: Documentation/ABI/stable/sysfs-bus-vmbus
+F: Documentation/ABI/testing/debugfs-hyperv
HYPERBUS SUPPORT
M: Vignesh Raghavendra <vigneshr@ti.com>
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index ebd35fc35290..b6d023ae9664 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -919,6 +919,10 @@ static void vmbus_device_release(struct device *device)
struct hv_device *hv_dev = device_to_hv_device(device);
struct vmbus_channel *channel = hv_dev->channel;
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_rm_dev_dir(hv_dev);
+#endif /* CONFIG_HYPERV_TESTING */
+
mutex_lock(&vmbus_connection.channel_mutex);
hv_process_channel_removal(channel);
mutex_unlock(&vmbus_connection.channel_mutex);
@@ -1727,6 +1731,9 @@ int vmbus_device_register(struct hv_device *child_device_obj)
pr_err("Unable to register primary channeln");
goto err_kset_unregister;
}
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_add_dev_dir(child_device_obj);
+#endif /* CONFIG_HYPERV_TESTING */
return 0;
@@ -2086,6 +2093,159 @@ static void hv_crash_handler(struct pt_regs *regs)
hyperv_cleanup();
};
+#ifdef CONFIG_HYPERV_TESTING
+
+struct dentry *hv_root;
+
+static int hv_debugfs_delay_get(void *data, u64 *val)
+{
+ *val = *(u32 *)data;
+ return 0;
+}
+
+static int hv_debugfs_delay_set(void *data, u64 val)
+{
+ if (val >= 1 && val <= 1000)
+ *(u32 *)data = val;
+ /*Best to not use else statement here since we want
+ * the delay to remain the same if val > 1000
+ */
+ else if (val <= 0)
+ *(u32 *)data = 0;
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(hv_debugfs_delay_fops, hv_debugfs_delay_get,
+ hv_debugfs_delay_set, "%llu\n");
+
+/* Setup delay files to store test values */
+int hv_debug_delay_files(struct hv_device *dev, struct dentry *root)
+{
+ struct vmbus_channel *channel = dev->channel;
+ char *buffer = "fuzz_test_buffer_interrupt_delay";
+ char *message = "fuzz_test_message_delay";
+ int *buffer_val = &channel->fuzz_testing_interrupt_delay;
+ int *message_val = &channel->fuzz_testing_message_delay;
+ struct dentry *buffer_file, *message_file;
+
+ buffer_file = debugfs_create_file(buffer, 0644, root,
+ buffer_val,
+ &hv_debugfs_delay_fops);
+ if (IS_ERR(buffer_file)) {
+ pr_debug("debugfs_hyperv: file %s not created\n", buffer);
+ return PTR_ERR(buffer_file);
+ }
+
+ message_file = debugfs_create_file(message, 0644, root,
+ message_val,
+ &hv_debugfs_delay_fops);
+ if (IS_ERR(message_file)) {
+ pr_debug("debugfs_hyperv: file %s not created\n", message);
+ return PTR_ERR(message_file);
+ }
+
+ return 0;
+}
+
+/* Setup test state value for vmbus device */
+int hv_debug_set_test_state(struct hv_device *dev, struct dentry *root)
+{
+ struct vmbus_channel *channel = dev->channel;
+ bool *state = &channel->fuzz_testing_state;
+ char *status = "fuzz_test_state";
+ struct dentry *test_state;
+
+ test_state = debugfs_create_bool(status, 0644, root, state);
+ if (IS_ERR(test_state)) {
+ pr_debug("debugfs_hyperv: file %s not created\n", status);
+ return PTR_ERR(test_state);
+ }
+
+ return 0;
+}
+
+/* Bind hv device to a dentry for debugfs */
+void hv_debug_set_dir_dentry(struct hv_device *dev, struct dentry *root)
+{
+ if (hv_root)
+ dev->debug_dir = root;
+}
+
+/* Create all test dentry's and names for fuzz testing */
+int hv_debug_add_dev_dir(struct hv_device *dev)
+{
+ const char *device = dev_name(&dev->device);
+ char *delay_name = "delay";
+ struct dentry *delay, *dev_root;
+ int ret;
+
+ if (!IS_ERR(hv_root)) {
+ dev_root = debugfs_create_dir(device, hv_root);
+ if (IS_ERR_OR_NULL(dev_root)) {
+ pr_debug("debugfs_hyperv: %s/%s/ not created\n",
+ TESTING, device);
+ return PTR_ERR(dev_root);
+ }
+
+ hv_debug_set_test_state(dev, dev_root);
+ hv_debug_set_dir_dentry(dev, dev_root);
+ delay = debugfs_create_dir(delay_name, dev_root);
+
+ if (IS_ERR(delay)) {
+ pr_debug("debugfs_hyperv: %s/%s/%s/ not created\n",
+ TESTING, device, delay_name);
+ return PTR_ERR(delay);
+ }
+ ret = hv_debug_delay_files(dev, delay);
+
+ return ret;
+ }
+ pr_debug("debugfs_hyperv: %s/ not in root debugfs path\n", TESTING);
+ return PTR_ERR(hv_root);
+}
+
+/* Remove dentry associated with released hv device */
+void hv_debug_rm_dev_dir(struct hv_device *dev)
+{
+ if (!IS_ERR(hv_root))
+ debugfs_remove_recursive(dev->debug_dir);
+}
+
+/* Remove all dentrys associated with vmbus testing */
+void hv_debug_rm_all_dir(void)
+{
+ debugfs_remove_recursive(hv_root);
+}
+
+/* Delay buffer/message reads on a vmbus channel */
+void hv_debug_delay_test(struct vmbus_channel *channel, enum delay delay_type)
+{
+ struct vmbus_channel *test_channel = channel->primary_channel ?
+ channel->primary_channel :
+ channel;
+ bool state = test_channel->fuzz_testing_state;
+
+ if (state) {
+ if (delay_type == 0)
+ udelay(test_channel->fuzz_testing_interrupt_delay);
+ else
+ udelay(test_channel->fuzz_testing_message_delay);
+ }
+}
+
+/* Initialize top dentry for vmbus testing */
+int hv_debug_init(void)
+{
+ hv_root = debugfs_create_dir(TESTING, NULL);
+ if (IS_ERR(hv_root)) {
+ pr_debug("debugfs_hyperv: %s/ not created\n", TESTING);
+ return PTR_ERR(hv_root);
+ }
+
+ return 0;
+}
+#endif /* CONFIG_HYPERV_TESTING */
+
static int __init hv_acpi_init(void)
{
int ret, t;
@@ -2108,6 +2268,9 @@ static int __init hv_acpi_init(void)
ret = -ETIMEDOUT;
goto cleanup;
}
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_init();
+#endif /* CONFIG_HYPERV_TESTING */
ret = vmbus_bus_init();
if (ret)
@@ -2140,6 +2303,10 @@ static void __exit vmbus_exit(void)
tasklet_kill(&hv_cpu->msg_dpc);
}
+#ifdef CONFIG_HYPERV_TESTING
+ hv_debug_rm_all_dir();
+#endif /* CONFIG_HYPERV_TESTING */
+
vmbus_free_channels();
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/3] tools: hv: add vmbus testing tool
2019-08-20 2:44 [PATCH v2 0/3] hv: vmbus: add fuzz testing to hv device Branden Bonaby
2019-08-20 2:44 ` [PATCH v2 1/3] drivers: hv: vmbus: Introduce latency testing Branden Bonaby
2019-08-20 2:44 ` [PATCH v2 2/3] drivers: hv: vmbus: add test attributes to debugfs Branden Bonaby
@ 2019-08-20 2:45 ` Branden Bonaby
2 siblings, 0 replies; 9+ messages in thread
From: Branden Bonaby @ 2019-08-20 2:45 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, sashal
Cc: Branden Bonaby, linux-hyperv, linux-kernel
This is a userspace tool to drive the testing. Currently it supports
introducing user specified delay in the host to guest communication
path on a per-channel basis.
Signed-off-by: Branden Bonaby <brandonbonaby94@gmail.com>
---
Changes in v2:
- Move testing location to new location in debugfs.
tools/hv/vmbus_testing | 334 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 334 insertions(+)
create mode 100644 tools/hv/vmbus_testing
diff --git a/tools/hv/vmbus_testing b/tools/hv/vmbus_testing
new file mode 100644
index 000000000000..f615009b7393
--- /dev/null
+++ b/tools/hv/vmbus_testing
@@ -0,0 +1,334 @@
+#!/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 directories
+#author: Branden Bonaby
+
+import os
+import cmd
+import argparse
+from collections import defaultdict
+from argparse import RawDescriptionHelpFormatter
+
+#debugfs paths for vmbus must exist (same as in lsvmbus)
+debugfs_sys_path = '/sys/kernel/debug/hyperv'
+if not os.path.isdir(debugfs_sys_path):
+ print("{} doesn't exist/check permissions".format(debugfs_sys_path))
+ exit(-1)
+#Do not change unless, you change the debugfs attributes
+#in "/sys/kernel/debug/hyperv/<UUID>/". All fuzz testing
+#attributes will start with "fuzz_test".
+pathlen = len(debugfs_sys_path)
+fuzz_state_location = "fuzz_test_state"
+fuzz_states = {0 : "Disable", 1 : "Enable"}
+fuzz_methods ={1 : "Delay_testing"}
+fuzz_delay_types = {1 : "fuzz_test_buffer_interrupt_delay", 2 :"fuzz_test_message_delay"}
+
+def parse_args():
+ parser = argparse.ArgumentParser(description = "vmbus_testing "\
+ "[-s] [0|1] [-q] [-p] <debugfs-path>\n""vmbus_testing [-s]"\
+ " [0|1] [-q][-p] <debugfs-path> delay [-d] [val][val] [-E|-D]\n"
+ "vmbus_testing [-q] disable-all\n"
+ "vmbus_testing [-q] view [-v|-V]\n"\
+ "vmbus_testing --version",
+ epilog = "Current testing options {}".format(fuzz_methods),
+ prog = 'vmbus_testing',
+ formatter_class = RawDescriptionHelpFormatter)
+ subparsers = parser.add_subparsers(dest="action")
+ parser.add_argument('--version', action='version',\
+ version = '%(prog)s 1.0')
+ parser.add_argument("-q","--quiet",action = "store_true",\
+ help = "silence none important test messages")
+ parser.add_argument("-s","--state",metavar = "", type = int,\
+ choices = range(0,2),\
+ help = "Turn testing ON or OFF for a single device."\
+ " The value (1) will turn testing ON. The value"\
+ " of (0) will turn testing OFF with the default set"\
+ " to (0).")
+ parser.add_argument("-p","--path", metavar = "",\
+ help = "Refers to the debugfs path to a vmbus device."
+ " If the path is not a valid path to a vmbus device,"\
+ " the program will exit. The path must be the"\
+ " absolute path; use the lsvmbus command to find"\
+ " the path.")
+ parser_delay = subparsers.add_parser("delay",\
+ help = "Delay buffer/message reads in microseconds.",
+ description = "vmbus_testing -s [0|1] [-q] -p "\
+ "<debugfs-path> delay -d "\
+ "[buffer-delay-value] [message-delay-value]\n"
+ "vmbus_testing [-q] delay [buffer-delay-value] "\
+ "[message-delay-value] -E\n"
+ "vmbus_testing [-q] delay [buffer-delay-value] "\
+ "[message-delay-value] -D",
+ formatter_class = RawDescriptionHelpFormatter)
+ delay_group = parser_delay.add_mutually_exclusive_group()
+ delay_group.add_argument("-E","--en-all-delay", action = "store_true",\
+ help = "Enable Buffer/Message Delay testing on ALL"\
+ " devices. Use -d option with this to set the values"\
+ " for both the buffer delay and the message delay. No"\
+ " value can be (0) or less than (-1). If testing is"\
+ " disabled on a device prior to running this command,"\
+ " testing will be enabled on the device as a result"\
+ " of this command.")
+ delay_group.add_argument("-D","--dis-all-delay", action="store_true",\
+ help = "Disable Buffer/Message delay testing on ALL"\
+ " devices. A value equal to (-1) will keep the"\
+ " current delay value, and a value equal to (0) will"\
+ " remove delay testing for the specfied delay column."\
+ " only values (-1) and (0) will be accepted but at"\
+ " least one value must be a (0) or a (-1).")
+ parser_delay.add_argument("-d","--delay-time", metavar="", nargs=2,\
+ type = check_range, default =[0,0], required = (True),\
+ help = "Buffer/message delay time. A value of (0) will"\
+ "disable delay testing on the specified delay column,"\
+ " while a value of (-1) will ignore the specified"\
+ " delay column. The default values are [0] & [0]."\
+ " The first column represents the buffer delay value"\
+ " and the second represents the message delay value."\
+ " Value constraints: -1 <= value <= 1000.")
+ parser_dis_all = subparsers.add_parser("disable-all",\
+ help = "Disable ALL testing on all vmbus devices.",
+ description = "vmbus_testing disable-all",
+ formatter_class = RawDescriptionHelpFormatter)
+ parser_view = subparsers.add_parser("view",\
+ help = "View testing on vmbus devices.",
+ description = "vmbus_testing view -V\n"
+ "vmbus_testing -p <debugfs-path> view -v",
+ formatter_class = RawDescriptionHelpFormatter)
+ view_group = parser_view.add_mutually_exclusive_group()
+ view_group.add_argument("-V","--view-all-states",action = "store_true",\
+ help = "View the test status for all vmbus devices.")
+ view_group.add_argument("-v","--view-single-device",\
+ action = "store_true",help = "View test values for a"\
+ " single vmbus device.")
+
+ 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\nError, Expected -1 <= value <= 1000, got value"\
+ " {}\n").format(val)
+ raise argparse.ArgumentTypeError(message)
+ return val
+
+def main():
+ try:
+ dev_list = []
+ for dir in os.listdir(debugfs_sys_path):\
+ dev_list.append(os.path.join(debugfs_sys_path,dir))
+ #key value, pairs
+ #key = debugfs device path
+ #value = list of fuzz testing attributes.
+ device_and_files = defaultdict(list)
+ for dev in dev_list:
+ path = os.path.join(dev,"delay")
+ for f in os.listdir(path):
+ if (f.startswith("fuzz_test")):
+ device_and_files[path].append(f)
+
+ device_and_files.default_factory = None
+ args = parse_args()
+ path = args.path
+ state = args.state
+ quiet = args.quiet
+ if (not quiet):
+ print("*** Use lsvmbus to get vmbus device type"\
+ " information.*** ")
+ if (state is not None and validate_args_path(path,dev_list)):
+ if (state is not get_test_state(path)):
+ change_test_state(path,quiet)
+ state = get_test_state(path)
+ if (state is 0 and path is not None):
+ disable_testing_single_device(path,0,quiet)
+ return
+ #Use subparsers as the key for different fuzz testing methods
+ if (args.action == "delay"):
+ delay = args.delay_time
+ if (validate_delay_values(args,delay)):
+ delay_test_all_devices(dev_list,delay,quiet)
+ elif (validate_args_path(path,dev_list)):
+ if(get_test_state(path) is 1):
+ delay_test_store(path,delay,quiet)
+ return
+ print("device testing OFF, use -s 1 to turn ON")
+ elif (args.action == "disable-all"):
+ disable_all_testing(dev_list,quiet)
+ elif (args.action == "view"):
+ if (args.view_all_states):
+ all_devices_test_status(dev_list)
+ elif (args.view_single_device):
+ if (validate_args_path(path,dev_list)):
+ device_test_values(device_and_files,\
+ path)
+ return
+ print("Error,(check path) usage: -p"\
+ " <debugfs device path> view -v")
+ except AttributeError:
+ print("check usage, 1 or more elements not provided")
+ exit(-1)
+
+#Validate delay values to make sure they are acceptable to
+#to either enable all delays on a device or disable all
+#delays on a device
+def validate_delay_values(args,delay):
+ if (args.en_all_delay):
+ for i in delay:
+ if (i < -1 or i == 0):
+ print("\nError, Values must be"\
+ " equal to -1 or be > 0, use"\
+ " -d option")
+ exit(-1)
+ return True
+ elif (args.dis_all_delay):
+ for i in delay:
+ if (i < -1 or i > 0):
+ print("\nError, at least 1 value"
+ " is not a (0) or a (-1)")
+ exit(-1)
+ return True
+ else:
+ return False
+
+
+#Validate argument path
+def validate_args_path(path,dev_list):
+ if (path in dev_list):
+ return True
+ else:
+ return False
+
+#display Testing status of single device
+def device_test_values(device_and_files,path):
+
+ delay_path = os.path.join(path,'delay')
+ for test in device_and_files.get(delay_path):
+ print("{}".format(test), end = '')
+ print((" value = {}")\
+ .format(read_test_files(os.path.join(delay_path,test))))
+
+#display Testing state of devices
+def all_devices_test_status(dev_list):
+ for device in dev_list:
+ if (get_test_state(device) 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:
+ state = f.readline().strip()
+ if (state == 'N'):
+ state = 0
+ elif (state == 'Y'):
+ state = 1
+ return int(state)
+
+ 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)
+
+#change testing state of device
+def change_test_state(device,quiet):
+ state_path = os.path.join(device,fuzz_state_location)
+ if (get_test_state(device) is 0):
+ write_test_files(state_path,1)
+ if (not quiet):
+ print("Testing = ON for device: {}"\
+ .format(state_path.split("/")[5]))
+ else:
+ write_test_files(state_path,0)
+ if (not quiet):
+ print("Testing = OFF for device: {}"\
+ .format(state_path.split("/")[5]))
+
+#get testing state of device
+def get_test_state(device):
+ #state == 1 - test = ON
+ #state == 0 - test = OFF
+ return read_test_files(os.path.join(device,fuzz_state_location))
+
+#Enter 1 - 1000 microseconds, into a single device using the
+#fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay
+#debugfs attributes
+def delay_test_store(device,delay_length,quiet):
+
+ try:
+ # delay[0]- buffer delay, delay[1]- message delay
+ buff_test = os.path.join(os.path.sep,device,'delay',
+ fuzz_delay_types.get(1))
+ mess_test = os.path.join(os.path.sep,device,'delay',
+ fuzz_delay_types.get(2))
+
+ if (delay_length[0] >= 0):
+ write_test_files(buff_test,delay_length[0])
+ if (delay_length[1] >= 0):
+ write_test_files(mess_test,delay_length[1])
+ if (not quiet):
+ print("Buffer delay testing = {} for: {}"\
+ .format(read_test_files(buff_test),\
+ buff_test.split("/")[5]))
+ print("Message delay testing = {} for: {}"\
+ .format(read_test_files(mess_test),\
+ mess_test.split("/")[5]))
+ except IOError as e:
+ errno, strerror = e.args
+ print("I/O error({0}): {1} on files {2}{3}"\
+ .format(errno,strerror,buff_test,mess_test))
+ exit(-1)
+
+#enabling/disabling delay testing on all devices
+def delay_test_all_devices(dev_list,delay,quiet):
+
+ for device in (dev_list):
+ if (get_test_state(device) is 0):
+ change_test_state(device,quiet)
+ delay_test_store(device,delay,quiet)
+
+#disabling testing on single device
+def disable_testing_single_device(device,test_type,quiet):
+
+ #test_type represents corresponding key
+ #delay method in delay_methods dict.
+ #special type 0 , used to disable all
+ #testing on SINGLE device.
+
+ if (test_type is 1 or test_type is 0):
+ #disable list [buffer,message]
+ disable_delay = [0,0]
+ if (get_test_state(device) is 1):
+ change_test_state(device,quiet)
+ delay_test_store(device,disable_delay,quiet)
+
+#disabling testing on ALL devices
+def disable_all_testing(dev_list,quiet):
+
+ #delay disable list [buffer,message]
+ for device in dev_list:
+ disable_testing_single_device(device,0,quiet)
+
+if __name__ == "__main__":
+ main()
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread