scripts/nvmf_perf: add allowlist and blocklist
Use "allowlist" and "blocklist" options in JSON configuration file to specify which NVMe drives are OK to use when setting up Target side. If no list is specified the user can continue with the test and use all available NVMe drives by passing "-f" option when running the script. Previously the default behaviour was to use all NVMe drives available in the system for test, which could cause data loss on those drives. This is a failsafe primarily aimed at KernelTarget class, as SPDKTarget is already safer to use because of existing checks in "setup.sh" script which must be run prior to executing NVMe-oF performance test script. Change-Id: I5ff93672a92cb09f2aef8355542ad197d96e14e1 Signed-off-by: Karol Latecki <karol.latecki@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14854 Reviewed-by: Pawel Piatek <pawelx.piatek@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
241d9c0a8a
commit
f5d6d59482
@ -393,6 +393,8 @@ class Target(Server):
|
||||
self.pm_delay = 0
|
||||
self.pm_interval = 0
|
||||
self.pm_count = 1
|
||||
self.nvme_allowlist = []
|
||||
self.nvme_blocklist = []
|
||||
|
||||
if "null_block_devices" in target_config:
|
||||
self.null_block = target_config["null_block_devices"]
|
||||
@ -415,6 +417,15 @@ class Target(Server):
|
||||
self.enable_pm, self.pm_delay, self.pm_interval, self.pm_count = target_config["pm_settings"]
|
||||
# Normalize pm_count - <= 0 means to loop indefinitely so let's avoid that to not block forever
|
||||
self.pm_count = self.pm_count if self.pm_count > 0 else 1
|
||||
if "blocklist" in target_config:
|
||||
self.nvme_blocklist = target_config["blocklist"]
|
||||
if "allowlist" in target_config:
|
||||
self.nvme_allowlist = target_config["allowlist"]
|
||||
# Blocklist takes precedence, remove common elements from allowlist
|
||||
self.nvme_allowlist = list(set(self.nvme_allowlist) - set(self.nvme_blocklist))
|
||||
|
||||
self.log.info("Items now on allowlist: %s" % self.nvme_allowlist)
|
||||
self.log.info("Items now on blocklist: %s" % self.nvme_blocklist)
|
||||
|
||||
self.script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
self.spdk_dir = os.path.abspath(os.path.join(self.script_dir, "../../../"))
|
||||
@ -872,10 +883,24 @@ class KernelTarget(Target):
|
||||
def stop(self):
|
||||
self.nvmet_command(self.nvmet_bin, "clear")
|
||||
|
||||
def get_nvme_device_bdf(self, nvme_dev_path):
|
||||
nvme_name = os.path.basename(nvme_dev_path)
|
||||
return self.exec_cmd(["cat", "/sys/block/%s/device/address" % nvme_name]).strip()
|
||||
|
||||
def get_nvme_devices(self):
|
||||
output = self.exec_cmd(["lsblk", "-o", "NAME", "-nlpd"])
|
||||
output = [x for x in output.split("\n") if "nvme" in x]
|
||||
return output
|
||||
dev_list = self.exec_cmd(["lsblk", "-o", "NAME", "-nlpd"]).split("\n")
|
||||
nvme_list = []
|
||||
for dev in dev_list:
|
||||
if "nvme" not in dev:
|
||||
continue
|
||||
if self.get_nvme_device_bdf(dev) in self.nvme_blocklist:
|
||||
continue
|
||||
if len(self.nvme_allowlist) == 0:
|
||||
nvme_list.append(dev)
|
||||
continue
|
||||
if self.get_nvme_device_bdf(dev) in self.nvme_allowlist:
|
||||
nvme_list.append(dev)
|
||||
return dev_list
|
||||
|
||||
def nvmet_command(self, nvmet_bin, command):
|
||||
return self.exec_cmd([nvmet_bin, *(command.split(" "))])
|
||||
@ -995,7 +1020,15 @@ class SPDKTarget(Target):
|
||||
|
||||
def get_nvme_devices(self):
|
||||
bdev_subsys_json_obj = json.loads(self.exec_cmd([os.path.join(self.spdk_dir, "scripts/gen_nvme.sh")]))
|
||||
bdev_bdfs = [bdev["params"]["traddr"] for bdev in bdev_subsys_json_obj["config"]]
|
||||
bdev_bdfs = []
|
||||
for bdev in bdev_subsys_json_obj["config"]:
|
||||
bdev_traddr = bdev["params"]["traddr"]
|
||||
if bdev_traddr in self.nvme_blocklist:
|
||||
continue
|
||||
if len(self.nvme_allowlist) == 0:
|
||||
bdev_bdfs.append(bdev_traddr)
|
||||
if bdev_traddr in self.nvme_allowlist:
|
||||
bdev_bdfs.append(bdev_traddr)
|
||||
return bdev_bdfs
|
||||
|
||||
@staticmethod
|
||||
@ -1421,6 +1454,10 @@ if __name__ == "__main__":
|
||||
help='Results directory.')
|
||||
parser.add_argument('-s', '--csv-filename', type=str, default='nvmf_results.csv',
|
||||
help='CSV results filename.')
|
||||
parser.add_argument('-f', '--force', default=False, action='store_true',
|
||||
dest='force', help="""Force script to continue and try to use all
|
||||
available NVMe devices during test.
|
||||
WARNING: Might result in data loss on used NVMe drives""")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -1438,6 +1475,16 @@ if __name__ == "__main__":
|
||||
target_config = data["target"]
|
||||
initiator_configs = [data[x] for x in data.keys() if "initiator" in x]
|
||||
|
||||
if "null_block_devices" not in data["target"] and \
|
||||
(args.force is False and
|
||||
"allowlist" not in data["target"] and
|
||||
"blocklist" not in data["target"]):
|
||||
# TODO: Also check if allowlist or blocklist are not empty.
|
||||
logging.warning("""WARNING: This script requires allowlist and blocklist to be defined.
|
||||
You can choose to use all available NVMe drives on your system, which may potentially
|
||||
lead to data loss. If you wish to proceed with all attached NVMes, use "-f" option.""")
|
||||
exit(1)
|
||||
|
||||
for k, v in data.items():
|
||||
if "target" in k:
|
||||
v.update({"results_dir": args.results})
|
||||
|
Loading…
Reference in New Issue
Block a user