1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2018 Intel Corporation 4# All rights reserved. 5# 6 7import os 8import sys 9import argparse 10import logging 11import spdk.rpc as rpc 12from spdk.rpc.client import print_dict, JSONRPCException 13 14 15def get_bdev_name_key(bdev): 16 bdev_name_key = 'name' 17 if 'method' in bdev and bdev['method'] == 'bdev_split_create': 18 bdev_name_key = "base_bdev" 19 return bdev_name_key 20 21 22def get_bdev_name(bdev): 23 bdev_name = None 24 if 'params' in bdev: 25 if 'name' in bdev['params']: 26 bdev_name = bdev['params']['name'] 27 elif 'base_name' in bdev['params']: 28 bdev_name = bdev['params']['base_name'] 29 elif 'base_bdev' in bdev['params']: 30 bdev_name = bdev['params']['base_bdev'] 31 if 'method' in bdev and bdev['method'] == 'bdev_error_create': 32 bdev_name = "EE_%s" % bdev_name 33 return bdev_name 34 35 36def get_bdev_delete_method(bdev): 37 delete_method_map = {'bdev_malloc_create': "bdev_malloc_delete", 38 'bdev_null_create': "bdev_null_delete", 39 'bdev_rbd_create': "bdev_rbd_delete", 40 'bdev_pmem_create': "bdev_pmem_delete", 41 'bdev_aio_create': "bdev_aio_delete", 42 'bdev_error_create': "bdev_error_delete", 43 'bdev_split_create': "bdev_split_delete", 44 'bdev_virtio_attach_controller': "bdev_virtio_detach_controller", 45 'bdev_crypto_create': "bdev_crypto_delete", 46 'bdev_delay_create': "bdev_delay_delete", 47 'bdev_passthru_create': "bdev_passthru_delete", 48 'bdev_compress_create': 'bdev_compress_delete', 49 } 50 destroy_method = None 51 if 'method' in bdev: 52 construct_method = bdev['method'] 53 if construct_method in list(delete_method_map.keys()): 54 destroy_method = delete_method_map[construct_method] 55 56 return destroy_method 57 58 59def clear_bdev_subsystem(args, bdev_config): 60 rpc_bdevs = args.client.call("bdev_get_bdevs") 61 for bdev in bdev_config: 62 bdev_name_key = get_bdev_name_key(bdev) 63 bdev_name = get_bdev_name(bdev) 64 destroy_method = get_bdev_delete_method(bdev) 65 if destroy_method: 66 args.client.call(destroy_method, {bdev_name_key: bdev_name}) 67 68 nvme_controllers = args.client.call("bdev_nvme_get_controllers") 69 for ctrlr in nvme_controllers: 70 args.client.call('bdev_nvme_detach_controller', {'name': ctrlr['name']}) 71 72 ''' Disable and reset hotplug ''' 73 rpc.bdev.bdev_nvme_set_hotplug(args.client, False) 74 75 76def get_nvmf_destroy_method(nvmf): 77 delete_method_map = {'nvmf_create_subsystem': "nvmf_delete_subsystem"} 78 try: 79 return delete_method_map[nvmf['method']] 80 except KeyError: 81 return None 82 83 84def clear_nvmf_subsystem(args, nvmf_config): 85 for nvmf in nvmf_config: 86 destroy_method = get_nvmf_destroy_method(nvmf) 87 if destroy_method: 88 args.client.call(destroy_method, {'nqn': nvmf['params']['nqn']}) 89 90 91def get_iscsi_destroy_method(iscsi): 92 delete_method_map = {'iscsi_create_portal_group': "iscsi_delete_portal_group", 93 'iscsi_create_initiator_group': "iscsi_delete_initiator_group", 94 'iscsi_create_target_node': "iscsi_delete_target_node", 95 'iscsi_set_options': None 96 } 97 return delete_method_map[iscsi['method']] 98 99 100def get_iscsi_name(iscsi): 101 if 'name' in iscsi['params']: 102 return iscsi['params']['name'] 103 else: 104 return iscsi['params']['tag'] 105 106 107def get_iscsi_name_key(iscsi): 108 if iscsi['method'] == 'iscsi_create_target_node': 109 return "name" 110 else: 111 return 'tag' 112 113 114def clear_iscsi_subsystem(args, iscsi_config): 115 for iscsi in iscsi_config: 116 destroy_method = get_iscsi_destroy_method(iscsi) 117 if destroy_method: 118 args.client.call(destroy_method, {get_iscsi_name_key(iscsi): get_iscsi_name(iscsi)}) 119 120 121def get_nbd_destroy_method(nbd): 122 delete_method_map = {'nbd_start_disk': "nbd_stop_disk" 123 } 124 return delete_method_map[nbd['method']] 125 126 127def clear_nbd_subsystem(args, nbd_config): 128 for nbd in nbd_config: 129 destroy_method = get_nbd_destroy_method(nbd) 130 if destroy_method: 131 args.client.call(destroy_method, {'nbd_device': nbd['params']['nbd_device']}) 132 133 134def clear_net_framework_subsystem(args, net_framework_config): 135 pass 136 137 138def clear_accel_subsystem(args, accel_config): 139 pass 140 141 142def clear_interface_subsystem(args, interface_config): 143 pass 144 145 146def clear_vhost_scsi_subsystem(args, vhost_config): 147 for vhost in reversed(vhost_config): 148 if 'method' in vhost: 149 method = vhost['method'] 150 if method in ['vhost_scsi_controller_add_target']: 151 args.client.call("vhost_scsi_controller_remove_target", 152 {"ctrlr": vhost['params']['ctrlr'], 153 "scsi_target_num": vhost['params']['scsi_target_num']}) 154 elif method in ['vhost_create_scsi_controller']: 155 args.client.call("vhost_delete_controller", {'ctrlr': vhost['params']['ctrlr']}) 156 157 158def clear_vhost_blk_subsystem(args, vhost_config): 159 for vhost in reversed(vhost_config): 160 if 'method' in vhost: 161 method = vhost['method'] 162 if method in ['vhost_create_blk_controller']: 163 args.client.call("vhost_delete_controller", {'ctrlr': vhost['params']['ctrlr']}) 164 165 166def clear_vmd_subsystem(args, vmd_config): 167 pass 168 169 170def clear_sock_subsystem(args, sock_config): 171 pass 172 173 174def clear_scheduler_subsystem(args, scheduler_config): 175 pass 176 177 178def call_test_cmd(func): 179 def rpc_test_cmd(*args, **kwargs): 180 try: 181 func(*args, **kwargs) 182 except JSONRPCException as ex: 183 print((ex.message)) 184 exit(1) 185 return rpc_test_cmd 186 187 188if __name__ == "__main__": 189 parser = argparse.ArgumentParser(description='Clear config command') 190 parser.add_argument('-s', dest='server_addr', default='/var/tmp/spdk.sock') 191 parser.add_argument('-p', dest='port', default=5260, type=int) 192 parser.add_argument('-t', dest='timeout', default=60.0, type=float) 193 parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", 194 help='Set verbose mode to INFO', default="ERROR") 195 parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], 196 help="""Set verbose level. """) 197 subparsers = parser.add_subparsers(help='RPC methods') 198 199 @call_test_cmd 200 def clear_config(args): 201 for subsystem_item in reversed(args.client.call('framework_get_subsystems')): 202 args.subsystem = subsystem_item['subsystem'] 203 clear_subsystem(args) 204 205 p = subparsers.add_parser('clear_config', help="""Clear configuration of all SPDK subsystems and targets using JSON RPC""") 206 p.set_defaults(func=clear_config) 207 208 @call_test_cmd 209 def clear_subsystem(args): 210 config = args.client.call('framework_get_config', {"name": args.subsystem}) 211 if config is None: 212 return 213 if args.verbose: 214 print("Calling clear_%s_subsystem" % args.subsystem) 215 globals()["clear_%s_subsystem" % args.subsystem](args, config) 216 217 p = subparsers.add_parser('clear_subsystem', help="""Clear configuration of SPDK subsystem using JSON RPC""") 218 p.add_argument('--subsystem', help="""Subsystem name""") 219 p.set_defaults(func=clear_subsystem) 220 221 args = parser.parse_args() 222 223 with rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) as client: 224 try: 225 args.client = client 226 args.func(args) 227 except JSONRPCException as ex: 228 print((ex.message)) 229 exit(1) 230