Skip to content

Commit a14f71f

Browse files
add s3 bdev and tiering params adjustment support to cli (toggling disaster recovery a WIP)
1 parent 28fbd52 commit a14f71f

File tree

5 files changed

+182
-7
lines changed

5 files changed

+182
-7
lines changed

simplyblock_cli/cli.py

+72-4
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,25 @@ def __init__(self):
261261
sub_command = self.add_sub_command(subparser, 'dump-lvstore','Dump lvstore data')
262262
sub_command.add_argument("id", help='UUID of storage node').completer = self._completer_get_sn_list
263263

264+
265+
# S3 bdev for tiering
266+
267+
sub_command = self.add_sub_command(subparser, 's3-bdev-create', 'Create a local S3 bdev for tiering (otherwise can connect to an existing remote one over fabric)')
268+
sub_command.add_argument("id", help='UUID of storage node').completer = self._completer_get_sn_list
269+
sub_command.add_argument("--name", 'S3 bdev name', type=str)
270+
sub_command.add_argument("--bdb-lcpu-mask", 'S3 bdev SPDK thread mask', type=int, default=0)
271+
sub_command.add_argument("--s3-lcpu-mask", 'S3 bdev worker pthread mask', type=int, default=0)
272+
sub_command.add_argument("--s3-thread-pool-size", 'S3 bdev worker pthread pool size', type=int, default=32)
273+
274+
sub_command = self.add_sub_command(subparser, 's3-bdev-delete', 'Delete a local S3 bdev')
275+
sub_command.add_argument("id", help='UUID of storage node').completer = self._completer_get_sn_list
276+
sub_command.add_argument("--name", 'S3 bdev name', type=str)
277+
278+
sub_command = self.add_sub_command(subparser, 's3-bdev-add-bucket-name', 'Register a bucket name in the local S3 bdev if a bucket was newly added to the S3 endpoint')
279+
sub_command.add_argument("id", help='UUID of storage node').completer = self._completer_get_sn_list
280+
sub_command.add_argument("--name", 'S3 bdev name', type=str)
281+
sub_command.add_argument("--bucket-name", 'S3 bucket name', type=str)
282+
264283
# check lvol
265284
#
266285
# ----------------- cluster -----------------
@@ -342,6 +361,11 @@ def __init__(self):
342361
sub_command.add_argument("--support-storage-tiering", help="Whether to support storage tiering", type=bool, default=False)
343362
sub_command.add_argument("--disaster-recovery", help="AZ disaster recovery mode", type=bool, default=False)
344363

364+
# toggle disaster recovery status
365+
sub_command = self.add_sub_command(subparser, 'toggle-disaster-recovery-status', 'Toggle AZ disaster recovery status')
366+
sub_command.add_argument("cluster_id", help='the cluster UUID').completer = self._completer_get_cluster_list
367+
sub_command.add_argument("--disaster-recovery", help="AZ disaster recovery status", type=bool)
368+
345369
# Activate cluster
346370
sub_command = self.add_sub_command(subparser, 'activate', 'Create distribs and raid0 bdevs on all the storage node and move the cluster to active state')
347371
sub_command.add_argument("cluster_id", help='the cluster UUID').completer = self._completer_get_cluster_list
@@ -474,7 +498,7 @@ def __init__(self):
474498
sub_command.add_argument("--force-fetch", help="fetches are forced", type=bool, default=False)
475499
sub_command.add_argument("--sync-fetch", help="reads require synchronous fetches", type=bool, default=True)
476500
sub_command.add_argument("--pure-flush-or-evict", help="pure flush or evict", type=bool, default=False)
477-
sub_command.add_argumetn("--not-evict-blob-md", help="what to do with blob md", type=int, default=0)
501+
sub_command.add_argument("--not-evict-blob-md", help="what to do with blob md", type=int, default=0)
478502
sub_command.add_argument("--namespace", help='Set LVol namespace for k8s clients')
479503
sub_command.add_argument("--uid", help='Set LVol UUID')
480504
sub_command.add_argument("--pvc_name", help='Set LVol PVC name for k8s clients')
@@ -503,7 +527,27 @@ def __init__(self):
503527
sub_command.add_argument("--clear-method", help="any valid clear method", type=int)
504528
sub_command.add_argument("--id-of-blob-to-recover", help="id of the original snapshot blob", type=int)
505529

506-
# snapshot restore
530+
# set lvol tiering modes
531+
sub_command = self.add_sub_command(subparser, 'set-tiering-modes', 'Set tiering modes of an lvol')
532+
sub_command.add_argument("--is-tiered", help="sends tiered I/O", type=bool)
533+
sub_command.add_argument("--force-fetch", help="fetches are forced", type=bool)
534+
sub_command.add_argument("--sync-fetch", help="reads require synchronous fetches", type=bool)
535+
sub_command.add_argument("--pure-flush-or-evict", help="pure flush or evict", type=bool)
536+
#sub_command.add_argument("--not-evict-blob-md", help="what to do with blob md", type=int)
537+
538+
# update page list capacities
539+
sub_command = self.add_sub_command(subparser, 'set-distr-cache-capacities', 'Set storage tiering page list capacities of a distrib')
540+
sub_command.add_argument("--lvol-uuid", help="lvol uuid", type=str)
541+
sub_command.add_argument("--distr-name", help="distrib bdev name", type=str)
542+
sub_command.add_argument("--ghost-capacity", help="ghost queue capacity", type=str)
543+
sub_command.add_argument("--fifo-main-capacity", help="main fifo queue capacity", type=str)
544+
sub_command.add_argument("--fifo-small-capacity", help="small fifo queue capacity", type=str)
545+
546+
# update secondary I/O timeout value
547+
sub_command = self.add_sub_command(subparser, 'set-distr-secondary-io-timeout', 'Set secondary stg I/O timeout in us for a distrib')
548+
sub_command.add_arugment("--lvol-uuid", help="lvol uuid", type=str)
549+
sub_command.add_argument("--distr-name", help="distrib bdev name", type=str)
550+
sub_command.add_argument("--secondary-io-timeout-us", help="secondary stg I/O timeout in us", type=int)
507551

508552
# set lvol params
509553
sub_command = self.add_sub_command(subparser, 'qos-set', 'Change qos settings for an active logical volume')
@@ -593,8 +637,7 @@ def __init__(self):
593637
sub_command = self.add_sub_command(subparser, 'inflate', 'Inflate a logical volume',
594638
usage='All unallocated clusters are allocated and copied from the parent or zero filled if not allocated in the parent. '
595639
'Then all dependencies on the parent are removed.')
596-
sub_command.add_argument("lvol_id", help='cloned lvol id')
597-
640+
sub_command.add_argument("lvol_id", help='cloned lvol id')
598641
# mgmt-node ops
599642
subparser = self.add_command('mgmt', 'Management node commands')
600643

@@ -987,6 +1030,18 @@ def run(self):
9871030
elif sub_command == "info-spdk":
9881031
node_id = args.id
9891032
ret = storage_ops.get_spdk_info(node_id)
1033+
1034+
elif sub_command == "s3-bdev-create":
1035+
node_id = args.id
1036+
ret = storage_ops.s3_bdev_create(node_id, args.name, args.bdb_lcpu_mask, args.s3_lcpu_mask, args.s3_thread_pool_size)
1037+
1038+
elif sub_command == "s3-bdev-delete":
1039+
node_id = args.id
1040+
ret = storage_ops.s3_bdev_delete(node_id, args.name)
1041+
1042+
elif sub_command == "s3-bdev-add-bucket-name":
1043+
node_id = args.id
1044+
ret = storage_ops.s3_bdev_add_bucket_name(node_id, args.name, args.bucket_name)
9901045

9911046
elif sub_command == "get":
9921047
ret = storage_ops.get(args.id)
@@ -1018,6 +1073,8 @@ def run(self):
10181073
ret = self.cluster_create(args)
10191074
elif sub_command == 'add':
10201075
ret = self.cluster_add(args)
1076+
elif sub_command == 'toggle-disaster-recovery-status':
1077+
ret = self.cluster_toggle_disaster_recovery_status(args)
10211078
elif sub_command == 'activate':
10221079
cluster_id = args.cluster_id
10231080
ret = cluster_ops.cluster_activate(cluster_id, args.force, args.force_lvstore_create)
@@ -1135,6 +1192,14 @@ def run(self):
11351192
elif sub_command == 'recover-snapshot':
11361193
ret = lvol_controller.restore_snapshot(args.lvs_name, args.orig_name, args.orig_uuid,
11371194
args.clear_method, args.id_of_blob_to_recover)
1195+
elif sub_command == 'set-tiering-modes':
1196+
ret = lvol_controller.set_tiering_modes(args.lvol_uuid, args.is_tiered, args.force_fetch, args.sync_fetch,
1197+
args.pure_flush_or_evict, True)
1198+
elif sub_command == 'set-distr-cache-capacities':
1199+
ret = lvol_controller.set_distr_cache_capacities(args.lvol_uuid, args.distr_name,
1200+
args.ghost_capacity, args.fifo_main_capacity, args.fifo_small_capacity)
1201+
elif sub_command == 'set-distr-secondary-io-timeout':
1202+
ret = lvol_controller.set_distr_timeout_us(args.lvol_uuid, args.distr_name, args.secondary_io_timeout_us)
11381203
elif sub_command == "qos-set":
11391204
ret = lvol_controller.set_lvol(
11401205
args.id, args.max_rw_iops, args.max_rw_mbytes,
@@ -1381,6 +1446,9 @@ def cluster_add(self, args):
13811446
qpair_count, max_queue_size, inflight_io_threshold, enable_qos, strict_node_anti_affinity,
13821447
support_storage_tiering, disaster_recovery)
13831448

1449+
def cluster_toggle_disaster_recovery_status(self, args):
1450+
cluster_id = args.cluster_id
1451+
disaster_recovery = args.disaster_recovery
13841452

13851453
def cluster_create(self, args):
13861454
page_size_in_blocks = args.page_size

simplyblock_core/cluster_ops.py

+12
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,18 @@ def add_cluster(blk_size, page_size_in_blocks, cap_warn, cap_crit, prov_cap_warn
353353

354354
return cluster.get_id()
355355

356+
def cluster_toggle_disaster_recovery_status(cl_id, disaster_recovery):
357+
db_controller = DBController()
358+
cluster = db_controller.get_cluster_by_id(cl_id)
359+
if not cluster:
360+
logger.error(f"Cluster not found {cl_id}")
361+
return False
362+
363+
snodes = db_controller.get_storage_nodes_by_cluster_id(cl_id)
364+
365+
# TODO: get distribs of each snode
366+
return False
367+
356368

357369
def cluster_activate(cl_id, force=False, force_lvstore_create=False):
358370
db_controller = DBController()

simplyblock_core/controllers/lvol_controller.py

+61-1
Original file line numberDiff line numberDiff line change
@@ -1554,4 +1554,64 @@ def restore_snapshot(lvs_name, orig_name, orig_uuid, clear_method, id_of_blob_to
15541554
snode.rpc_username,
15551555
snode.rpc_password)
15561556

1557-
return rpc_client.bdev_lvol_recover(lvs_name, orig_name, orig_uuid, clear_method, id_of_blob_to_recover)
1557+
return rpc_client.bdev_lvol_recover(lvs_name, orig_name, orig_uuid, clear_method, id_of_blob_to_recover)
1558+
1559+
def set_tiering_modes(lvol_uuid, is_tiered, force_fetch, sync_fetch, pure_flush_or_evict, not_evict_blob_md):
1560+
lvol = db_controller.get_lvol_by_id(lvol_uuid)
1561+
if not lvol:
1562+
logger.error(f"LVol not found: {lvol_uuid}")
1563+
return False
1564+
pool = db_controller.get_pool_by_id(lvol.pool_uuid)
1565+
if pool.status == Pool.STATUS_INACTIVE:
1566+
logger.error(f"Pool is disabled")
1567+
return False
1568+
1569+
snode = db_controller.get_storage_node_by_id(lvol.node_id)
1570+
1571+
rpc_client = RPCClient(
1572+
snode.mgmt_ip,
1573+
snode.rpc_port,
1574+
snode.rpc_username,
1575+
snode.rpc_password)
1576+
1577+
return rpc_client.bdev_lvol_set_tiering_info(lvol_uuid, is_tiered, force_fetch, sync_fetch, pure_flush_or_evict, not_evict_blob_md)
1578+
1579+
def set_distr_cache_capacities(lvol_uuid, distr_name, ghost_capacity, fifo_main_capacity, fifo_small_capacity):
1580+
lvol = db_controller.get_lvol_by_id(lvol_uuid)
1581+
if not lvol:
1582+
logger.error(f"LVol not found: {lvol_uuid}")
1583+
return False
1584+
pool = db_controller.get_pool_by_id(lvol.pool_uuid)
1585+
if pool.status == Pool.STATUS_INACTIVE:
1586+
logger.error(f"Pool is disabled")
1587+
return False
1588+
1589+
snode = db_controller.get_storage_node_by_id(lvol.node_id)
1590+
1591+
rpc_client = RPCClient(
1592+
snode.mgmt_ip,
1593+
snode.rpc_port,
1594+
snode.rpc_username,
1595+
snode.rpc_password)
1596+
1597+
return rpc_client.distr_change_or_keep_page_cache_list_capacities(distr_name, ghost_capacity, fifo_main_capacity, fifo_small_capacity)
1598+
1599+
def set_distr_timeout_us(lvol_uuid, distr_name, secondary_io_timeout_us):
1600+
lvol = db_controller.get_lvol_by_id(lvol_uuid)
1601+
if not lvol:
1602+
logger.error(f"LVol not found: {lvol_uuid}")
1603+
return False
1604+
pool = db_controller.get_pool_by_id(lvol.pool_uuid)
1605+
if pool.status == Pool.STATUS_INACTIVE:
1606+
logger.error(f"Pool is disabled")
1607+
return False
1608+
1609+
snode = db_controller.get_storage_node_by_id(lvol.node_id)
1610+
1611+
rpc_client = RPCClient(
1612+
snode.mgmt_ip,
1613+
snode.rpc_port,
1614+
snode.rpc_username,
1615+
snode.rpc_password)
1616+
1617+
return rpc_client.distr_change_secondary_io_timeout_us(distr_name, secondary_io_timeout_us)

simplyblock_core/env_var

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
SIMPLY_BLOCK_COMMAND_NAME=sbcli-storage-tiering
2-
SIMPLY_BLOCK_VERSION=12.2.7
2+
SIMPLY_BLOCK_VERSION=12.2.8
33

44
SIMPLY_BLOCK_DOCKER_IMAGE=public.ecr.aws/simply-block/simplyblock:storage-tiering
5-
DOCKER_USER=hamdysimplyblock
5+
DOCKER_USER=hamdysimplyblock

simplyblock_core/storage_node_ops.py

+35
Original file line numberDiff line numberDiff line change
@@ -2756,6 +2756,41 @@ def get_spdk_info(node_id):
27562756
})
27572757
return utils.print_table(data)
27582758

2759+
def s3_bdev_create(node_id, name, bdb_lcpu_mask, s3_lcpu_mask, s3_thread_pool_size):
2760+
db_controller = DBController()
2761+
2762+
snode = db_controller.get_storage_node_by_id(node_id)
2763+
if not snode:
2764+
logger.error(f"Can not find storage node: {node_id}")
2765+
return False
2766+
2767+
rpc_client = RPCClient(snode.mgmt_ip, snode.rpc_port, snode.rpc_username, snode.rpc_password)
2768+
2769+
return rpc_client.bdev_s3_create(name, bdb_lcpu_mask, s3_lcpu_mask, s3_thread_pool_size)
2770+
2771+
def s3_bdev_delete(node_id, name):
2772+
db_controller = DBController()
2773+
2774+
snode = db_controller.get_storage_node_by_id(node_id)
2775+
if not snode:
2776+
logger.error(f"Can not find storage node: {node_id}")
2777+
return False
2778+
2779+
rpc_client = RPCClient(snode.mgmt_ip, snode.rpc_port, snode.rpc_username, snode.rpc_password)
2780+
2781+
return rpc_client.bdev_s3_delete(name)
2782+
2783+
def s3_bdev_add_bucket_name(node_id, name, bucket_name):
2784+
db_controller = DBController()
2785+
2786+
snode = db_controller.get_storage_node_by_id(node_id)
2787+
if not snode:
2788+
logger.error(f"Can not find storage node: {node_id}")
2789+
return False
2790+
2791+
rpc_client = RPCClient(snode.mgmt_ip, snode.rpc_port, snode.rpc_username, snode.rpc_password)
2792+
2793+
return rpc_client.bdev_s3_add_bucket(name, bucket_name)
27592794

27602795
def get(node_id):
27612796
db_controller = DBController()

0 commit comments

Comments
 (0)