Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #!/usr/bin/env python3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Program to allow users to fuzz test Hyper-V drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) # by interfacing with Hyper-V debugfs attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) # Current test methods available:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #       1. delay testing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) # Current file/directory structure of hyper-V debugfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #       /sys/kernel/debug/hyperv/UUID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #       /sys/kernel/debug/hyperv/UUID/<test-state filename>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #       /sys/kernel/debug/hyperv/UUID/<test-method sub-directory>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) # author: Branden Bonaby <brandonbonaby94@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) import os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) import cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) import argparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) import glob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) from argparse import RawDescriptionHelpFormatter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) from argparse import RawTextHelpFormatter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) from enum import Enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) # Do not change unless, you change the debugfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) # in /drivers/hv/debugfs.c. All fuzz testing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) # attributes will start with "fuzz_test".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) # debugfs path for hyperv must exist before proceeding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) debugfs_hyperv_path = "/sys/kernel/debug/hyperv"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) if not os.path.isdir(debugfs_hyperv_path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)         print("{} doesn't exist/check permissions".format(debugfs_hyperv_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)         exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) class dev_state(Enum):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)         off = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)         on = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) # File names, that correspond to the files created in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) # /drivers/hv/debugfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) class f_names(Enum):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)         state_f = "fuzz_test_state"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)         buff_f =  "fuzz_test_buffer_interrupt_delay"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)         mess_f =  "fuzz_test_message_delay"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) # Both single_actions and all_actions are used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) # for error checking and to allow for some subparser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) # names to be abbreviated. Do not abbreviate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) # test method names, as it will become less intuitive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) # as to what the user can do. If you do decide to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) # abbreviate the test method name, make sure the main
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) # function reflects this change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) all_actions = [
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)         "disable_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)         "D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)         "enable_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)         "view_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)         "V"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) single_actions = [
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)         "disable_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)         "d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)         "enable_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)         "view_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)         "v"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) def main():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)         file_map = recursive_file_lookup(debugfs_hyperv_path, dict())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)         args = parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)         if (not args.action):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)                 print ("Error, no options selected...exiting")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)         arg_set = { k for (k,v) in vars(args).items() if v and k != "action" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)         arg_set.add(args.action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)         path = args.path if "path" in arg_set else None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)         if (path and path[-1] == "/"):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)                 path = path[:-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)         validate_args_path(path, arg_set, file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)         if (path and "enable_single" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)             state_path = locate_state(path, file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)             set_test_state(state_path, dev_state.on.value, args.quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)         # Use subparsers as the key for different actions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)         if ("delay" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)                 validate_delay_values(args.delay_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)                 if (args.enable_all):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)                         set_delay_all_devices(file_map, args.delay_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)                                               args.quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)                         set_delay_values(path, file_map, args.delay_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)                                          args.quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)         elif ("disable_all" in arg_set or "D" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)                 disable_all_testing(file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)         elif ("disable_single" in arg_set or "d" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)                 disable_testing_single_device(path, file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)         elif ("view_all" in arg_set or "V" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)                 get_all_devices_test_status(file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)         elif ("view_single" in arg_set or  "v" in arg_set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)                 get_device_test_values(path, file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) # Get the state location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) def locate_state(device, file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)         return file_map[device][f_names.state_f.value]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) # Validate delay values to make sure they are acceptable to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) # enable delays on a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) def validate_delay_values(delay):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)         if (delay[0]  == -1 and delay[1] == -1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)                 print("\nError, At least 1 value must be greater than 0")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)         for i in delay:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)                 if (i < -1 or i == 0 or i > 1000):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)                         print("\nError, Values must be  equal to -1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)                               "or be > 0 and <= 1000")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)                         exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) # Validate argument path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) def validate_args_path(path, arg_set, file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)         if (not path and any(element in arg_set for element in single_actions)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)                 print("Error, path (-p) REQUIRED for the specified option. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)                       "Use (-h) to check usage.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)         elif (path and any(item in arg_set for item in all_actions)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)                 print("Error, path (-p) NOT REQUIRED for the specified option. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)                       "Use (-h) to check usage." )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)         elif (path not in file_map and any(item in arg_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)                                            for item in single_actions)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)                 print("Error, path '{}' not a valid vmbus device".format(path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) # display Testing status of single device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) def get_device_test_values(path, file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)         for name in file_map[path]:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)                 file_location = file_map[path][name]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)                 print( name + " = " + str(read_test_files(file_location)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) # Create a map of the vmbus devices and their associated files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) # [key=device, value = [key = filename, value = file path]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) def recursive_file_lookup(path, file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)         for f_path in glob.iglob(path + '**/*'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)                 if (os.path.isfile(f_path)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)                         if (f_path.rsplit("/",2)[0] == debugfs_hyperv_path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)                                 directory = f_path.rsplit("/",1)[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)                         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)                                 directory = f_path.rsplit("/",2)[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)                         f_name = f_path.split("/")[-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)                         if (file_map.get(directory)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)                                 file_map[directory].update({f_name:f_path})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)                         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)                                 file_map[directory] = {f_name:f_path}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)                 elif (os.path.isdir(f_path)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)                         recursive_file_lookup(f_path,file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)         return file_map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) # display Testing state of devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) def get_all_devices_test_status(file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)         for device in file_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)                 if (get_test_state(locate_state(device, file_map)) is 1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)                         print("Testing = ON for: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)                               .format(device.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)                         print("Testing = OFF for: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)                               .format(device.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) # read the vmbus device files, path must be absolute path before calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) def read_test_files(path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)                 with open(path,"r") as f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)                         file_value = f.readline().strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)                 return int(file_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)         except IOError as e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)                 errno, strerror = e.args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)                 print("I/O error({0}): {1} on file {2}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)                       .format(errno, strerror, path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)         except ValueError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)                 print ("Element to int conversion error in: \n{}".format(path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) # writing to vmbus device files, path must be absolute path before calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) def write_test_files(path, value):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)                 with open(path,"w") as f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)                         f.write("{}".format(value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)         except IOError as e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)                 errno, strerror = e.args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)                 print("I/O error({0}): {1} on file {2}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)                       .format(errno, strerror, path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) # set testing state of device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) def set_test_state(state_path, state_value, quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)         write_test_files(state_path, state_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)         if (get_test_state(state_path) is 1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)                 if (not quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)                         print("Testing = ON for device: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)                               .format(state_path.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)                 if (not quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)                         print("Testing = OFF for device: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)                               .format(state_path.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) # get testing state of device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) def get_test_state(state_path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)         #state == 1 - test = ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)         #state == 0 - test = OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)         return  read_test_files(state_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) # write 1 - 1000 microseconds, into a single device using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) # fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) # debugfs attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) def set_delay_values(device, file_map, delay_length, quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)                 interrupt = file_map[device][f_names.buff_f.value]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)                 message = file_map[device][f_names.mess_f.value]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)                 # delay[0]- buffer interrupt delay, delay[1]- message delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)                 if (delay_length[0] >= 0 and delay_length[0] <= 1000):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)                         write_test_files(interrupt, delay_length[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)                 if (delay_length[1] >= 0 and delay_length[1] <= 1000):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)                         write_test_files(message, delay_length[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)                 if (not quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)                         print("Buffer delay testing = {} for: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)                               .format(read_test_files(interrupt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)                                       interrupt.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)                         print("Message delay testing = {} for: {}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)                               .format(read_test_files(message),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)                                       message.split("/")[5]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)         except IOError as e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)                 errno, strerror = e.args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)                 print("I/O error({0}): {1} on files {2}{3}"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)                       .format(errno, strerror, interrupt, message))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)                 exit(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) # enabling delay testing on all devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) def set_delay_all_devices(file_map, delay, quiet):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)         for device in (file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)                 set_test_state(locate_state(device, file_map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)                                dev_state.on.value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)                                quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)                 set_delay_values(device, file_map, delay, quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) # disable all testing on a SINGLE device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) def disable_testing_single_device(device, file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)         for name in file_map[device]:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)                 file_location = file_map[device][name]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)                 write_test_files(file_location, dev_state.off.value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)         print("ALL testing now OFF for {}".format(device.split("/")[-1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) # disable all testing on ALL devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) def disable_all_testing(file_map):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)         for device in file_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)                 disable_testing_single_device(device, file_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) def parse_args():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)         parser = argparse.ArgumentParser(prog = "vmbus_testing",usage ="\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)                 "%(prog)s [delay]   [-h] [-e|-E] -t [-p]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)                 "%(prog)s [view_all       | V]      [-h]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)                 "%(prog)s [disable_all    | D]      [-h]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)                 "%(prog)s [disable_single | d]      [-h|-p]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)                 "%(prog)s [view_single    | v]      [-h|-p]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)                 "%(prog)s --version\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)                 description = "\nUse lsvmbus to get vmbus device type "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)                 "information.\n" "\nThe debugfs root path is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)                 "/sys/kernel/debug/hyperv",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)                 formatter_class = RawDescriptionHelpFormatter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)         subparsers = parser.add_subparsers(dest = "action")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)         parser.add_argument("--version", action = "version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)                 version = '%(prog)s 0.1.0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)         parser.add_argument("-q","--quiet", action = "store_true",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)                 help = "silence none important test messages."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)                        " This will only work when enabling testing"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)                        " on a device.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)         # Use the path parser to hold the --path attribute so it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)         # be shared between subparsers. Also do the same for the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)         # parser, as all testing methods will use --enable_all and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)         # enable_single.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)         path_parser = argparse.ArgumentParser(add_help=False)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)         path_parser.add_argument("-p","--path", metavar = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)                 help = "Debugfs path to a vmbus device. The path "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)                 "must be the absolute path to the device.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)         state_parser = argparse.ArgumentParser(add_help=False)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)         state_group = state_parser.add_mutually_exclusive_group(required = True)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)         state_group.add_argument("-E", "--enable_all", action = "store_const",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)                                  const = "enable_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)                                  help = "Enable the specified test type "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)                                  "on ALL vmbus devices.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)         state_group.add_argument("-e", "--enable_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)                                  action = "store_const",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)                                  const = "enable_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)                                  help = "Enable the specified test type on a "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)                                  "SINGLE vmbus device.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)         parser_delay = subparsers.add_parser("delay",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)                         parents = [state_parser, path_parser],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)                         help = "Delay the ring buffer interrupt or the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)                         "ring buffer message reads in microseconds.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)                         prog = "vmbus_testing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)                         usage = "%(prog)s [-h]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)                         "%(prog)s -E -t [value] [value]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)                         "%(prog)s -e -t [value] [value] -p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)                         description = "Delay the ring buffer interrupt for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)                         "vmbus devices, or delay the ring buffer message "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)                         "reads for vmbus devices (both in microseconds). This "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)                         "is only on the host to guest channel.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)         parser_delay.add_argument("-t", "--delay_time", metavar = "", nargs = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)                         type = check_range, default =[0,0], required = (True),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)                         help = "Set [buffer] & [message] delay time. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)                         "Value constraints: -1 == value "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)                         "or 0 < value <= 1000.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)                         "Use -1 to keep the previous value for that delay "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)                         "type, or a value > 0 <= 1000 to change the delay "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)                         "time.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)         parser_dis_all = subparsers.add_parser("disable_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)                         aliases = ['D'], prog = "vmbus_testing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)                         usage = "%(prog)s [disable_all | D] -h\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)                         "%(prog)s [disable_all | D]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)                         help = "Disable ALL testing on ALL vmbus devices.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)                         description = "Disable ALL testing on ALL vmbus "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)                         "devices.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)         parser_dis_single = subparsers.add_parser("disable_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)                         aliases = ['d'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)                         parents = [path_parser], prog = "vmbus_testing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)                         usage = "%(prog)s [disable_single | d] -h\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)                         "%(prog)s [disable_single | d] -p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)                         help = "Disable ALL testing on a SINGLE vmbus device.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)                         description = "Disable ALL testing on a SINGLE vmbus "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)                         "device.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)         parser_view_all = subparsers.add_parser("view_all", aliases = ['V'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)                         help = "View the test state for ALL vmbus devices.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)                         prog = "vmbus_testing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)                         usage = "%(prog)s [view_all | V] -h\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)                         "%(prog)s [view_all | V]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)                         description = "This shows the test state for ALL the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)                         "vmbus devices.")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)         parser_view_single = subparsers.add_parser("view_single",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)                         aliases = ['v'],parents = [path_parser],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)                         help = "View the test values for a SINGLE vmbus "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)                         "device.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)                         description = "This shows the test values for a SINGLE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)                         "vmbus device.", prog = "vmbus_testing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)                         usage = "%(prog)s [view_single | v] -h\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)                         "%(prog)s [view_single | v] -p")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)         return  parser.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) # value checking for range checking input in parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) def check_range(arg1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)                 val = int(arg1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)         except ValueError as err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)                 raise argparse.ArgumentTypeError(str(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)         if val < -1 or val > 1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)                 message = ("\n\nvalue must be -1 or  0 < value <= 1000. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)                            "Value program received: {}\n").format(val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)                 raise argparse.ArgumentTypeError(message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)         return val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if __name__ == "__main__":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)         main()