Skip to content

Commit

Permalink
set anagroup per added namespace, set ana_report_enabled per create s…
Browse files Browse the repository at this point in the history
…ubsystem, added test

Add and process enable_ha

Signed-off-by: leonidc <[email protected]>
  • Loading branch information
leonidc committed Oct 17, 2023
1 parent ee92f6c commit d8a4ef2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 8 deletions.
16 changes: 13 additions & 3 deletions control/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,17 @@ def delete_bdev(self, args):
argument("-n", "--subnqn", help="Subsystem NQN", required=True),
argument("-s", "--serial", help="Serial number", required=False),
argument("-m", "--max-namespaces", help="Maximum number of namespaces", type=int, default=0, required=False),
argument("-a", "--ana_reporting", help="Enable ANA reporting", type=bool, default=False, required=False),
argument("-t", "--enable_ha", help="Enable automatic HA" , type=bool, default=False, required=False),
])
def create_subsystem(self, args):
"""Creates a subsystem."""
req = pb2.create_subsystem_req(subsystem_nqn=args.subnqn,
serial_number=args.serial,
max_namespaces=args.max_namespaces)
max_namespaces=args.max_namespaces,
ana_reporting=args.ana_reporting,
enable_ha=args.enable_ha)
ret = self.stub.create_subsystem(req)
self.logger.info(f"Created subsystem {args.subnqn}: {ret.status}")

Expand All @@ -209,15 +214,20 @@ def delete_subsystem(self, args):
argument("-n", "--subnqn", help="Subsystem NQN", required=True),
argument("-b", "--bdev", help="Bdev name", required=True),
argument("-i", "--nsid", help="Namespace ID", type=int),
argument("-a", "--anagrpid", help="ANA group ID", type=int),
])
def add_namespace(self, args):
"""Adds a namespace to a subsystem."""
if args.anagrpid == 0:
args.anagrpid = 1

req = pb2.add_namespace_req(subsystem_nqn=args.subnqn,
bdev_name=args.bdev,
nsid=args.nsid)
nsid=args.nsid,
anagrpid=args.anagrpid)
ret = self.stub.add_namespace(req)
self.logger.info(
f"Added namespace {ret.nsid} to {args.subnqn}: {ret.status}")
f"Added namespace {ret.nsid} to {args.subnqn}, ana_grpid {args.anagrpid} : {ret.status}")

@cli.cmd([
argument("-n", "--subnqn", help="Subsystem NQN", required=True),
Expand Down
36 changes: 32 additions & 4 deletions control/grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .proto import gateway_pb2 as pb2
from .proto import gateway_pb2_grpc as pb2_grpc

MAX_ANA_GROUPS = 4

class GatewayService(pb2_grpc.GatewayServicer):
"""Implements gateway service interface.
Expand Down Expand Up @@ -190,7 +191,7 @@ def create_subsystem(self, request, context=None):
"""Creates a subsystem."""

self.logger.info(
f"Received request to create subsystem {request.subsystem_nqn}")
f"Received request to create subsystem {request.subsystem_nqn}, ana reporting: {request.ana_reporting} ")
min_cntlid = self.config.getint_with_default("gateway", "min_controller_id", 1)
max_cntlid = self.config.getint_with_default("gateway", "max_controller_id", 65519)
if not request.serial_number:
Expand All @@ -205,6 +206,7 @@ def create_subsystem(self, request, context=None):
max_namespaces=request.max_namespaces,
min_cntlid=min_cntlid,
max_cntlid=max_cntlid,
ana_reporting = request.ana_reporting,
)
self.logger.info(f"create_subsystem {request.subsystem_nqn}: {ret}")
except Exception as ex:
Expand Down Expand Up @@ -259,7 +261,9 @@ def delete_subsystem(self, request, context=None):

def add_namespace(self, request, context=None):
"""Adds a namespace to a subsystem."""

if request.anagrpid > MAX_ANA_GROUPS:
raise Exception(f"Error groupId {request.anagrpid} is more than configured maximum {MAX_ANA_GROUPS}\n")

self.logger.info(f"Received request to add {request.bdev_name} to"
f" {request.subsystem_nqn}")
try:
Expand All @@ -268,6 +272,7 @@ def add_namespace(self, request, context=None):
nqn=request.subsystem_nqn,
bdev_name=request.bdev_name,
nsid=request.nsid,
anagrpid=request.anagrpid,
)
self.logger.info(f"add_namespace: {nsid}")
except Exception as ex:
Expand Down Expand Up @@ -296,7 +301,7 @@ def add_namespace(self, request, context=None):
def remove_namespace(self, request, context=None):
"""Removes a namespace from a subsystem."""

self.logger.info(f"Received request to remove {request.nsid} from"
self.logger.info(f"Received request to remove nsid {request.nsid} from"
f" {request.subsystem_nqn}")
try:
ret = rpc_nvmf.nvmf_subsystem_remove_ns(
Expand Down Expand Up @@ -412,7 +417,6 @@ def remove_host(self, request, context=None):

def create_listener(self, request, context=None):
"""Creates a listener for a subsystem at a given IP/Port."""

ret = True
self.logger.info(f"Received request to create {request.gateway_name}"
f" {request.trtype} listener for {request.nqn} at"
Expand All @@ -438,6 +442,30 @@ def create_listener(self, request, context=None):
context.set_details(f"{ex}")
return pb2.req_status()

state = self.gateway_state.omap.get_state()
for key,val in state.items():
if (key.startswith(self.gateway_state.omap.SUBSYSTEM_PREFIX + request.nqn)):
self.logger.info(f"values of key: {key} val: {val} \n")
req = json_format.Parse(val, pb2.create_subsystem_req())
self.logger.info(f" enable_ha :{req.enable_ha} \n")
break

if req.enable_ha:
for x in range (MAX_ANA_GROUPS):
try:
ret = rpc_nvmf.nvmf_subsystem_listener_set_ana_state(
self.spdk_rpc_client,
nqn=request.nqn,
ana_state="inaccessible",
trtype=request.trtype,
traddr=request.traddr,
trsvcid=request.trsvcid,
adrfam=request.adrfam,
anagrpid=(x+1) )
except Exception as ex:
self.logger.error(f" set_listener_ana_state failed with: \n {ex}")
raise

if context:
# Update gateway state
try:
Expand Down
3 changes: 3 additions & 0 deletions control/proto/gateway.proto
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ message create_subsystem_req {
string subsystem_nqn = 1;
string serial_number = 2;
int32 max_namespaces = 3;
bool ana_reporting = 4;
bool enable_ha = 5;
}

message delete_subsystem_req {
Expand All @@ -74,6 +76,7 @@ message add_namespace_req {
string subsystem_nqn = 1;
string bdev_name = 2;
optional int32 nsid = 3;
optional int32 anagrpid = 4;
}

message remove_namespace_req {
Expand Down
2 changes: 1 addition & 1 deletion mk/demo.mk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rbd: CMD = bash -c "rbd -p $(RBD_POOL) info $(RBD_IMAGE_NAME) || rbd -p $(RBD_PO
demo: export NVMEOF_HOSTNAME != docker ps -q -f name=ceph-nvmeof_nvmeof_1
demo: rbd ## Expose RBD_IMAGE_NAME as NVMe-oF target
$(NVMEOF_CLI) create_bdev --pool $(RBD_POOL) --image $(RBD_IMAGE_NAME) --bdev $(BDEV_NAME)
$(NVMEOF_CLI) create_subsystem --subnqn $(NQN)
$(NVMEOF_CLI) create_subsystem --subnqn $(NQN) --serial $(SERIAL)
$(NVMEOF_CLI) add_namespace --subnqn $(NQN) --bdev $(BDEV_NAME)
$(NVMEOF_CLI) create_listener --subnqn $(NQN) --gateway-name $(NVMEOF_HOSTNAME) --traddr $(NVMEOF_IP_ADDRESS) --trsvcid $(NVMEOF_IO_PORT)
$(NVMEOF_CLI) add_host --subnqn $(NQN) --host "*"
Expand Down
44 changes: 44 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
serial = "SPDK00000000000001"
host_list = ["nqn.2016-06.io.spdk:host1", "*"]
nsid = "1"
anagrpid = "2"
trtype = "TCP"
gateway_name = socket.gethostname()
addr = "127.0.0.1"
Expand Down Expand Up @@ -98,3 +99,46 @@ def test_delete_subsystem(self, caplog, gateway):
assert "Failed to delete" not in caplog.text
cli(["delete_subsystem", "-n", subsystem2])
assert "Failed to delete" not in caplog.text


class TestCreateWithAna:
def test_create_bdev_ana(self, caplog, gateway):
cli(["create_bdev", "-i", image, "-p", pool, "-b", bdev])
assert "Failed to create" not in caplog.text


def test_create_subsystem_ana(self, caplog, gateway):
cli(["create_subsystem", "-n", subsystem, "-a", true, -t, true])
assert "Failed to create" not in caplog.text
cli(["get_subsystems"])
assert serial not in caplog.text

def test_add_namespace_ana(self, caplog, gateway):
cli(["add_namespace", "-n", subsystem, "-b", bdev, "-a", anagrpid])
assert "Failed to add" not in caplog.text

@pytest.mark.parametrize("listener", listener_list)
def test_create_listener_ana(self, caplog, listener, gateway):
cli(["create_listener", "-n", subsystem] + listener)
assert "Failed to create" not in caplog.text


class TestDeleteAna:

@pytest.mark.parametrize("listener", listener_list)
def test_delete_listener_ana(self, caplog, listener, gateway):
cli(["delete_listener", "-n", subsystem] + listener)
assert "Failed to delete" not in caplog.text

def test_remove_namespace_ana(self, caplog, gateway):
cli(["remove_namespace", "-n", subsystem, "-i", nsid])
assert "Failed to remove" not in caplog.text

def test_delete_bdev_ana(self, caplog, gateway):
cli(["delete_bdev", "-b", bdev, "-f"])
assert "Failed to delete" not in caplog.text

def test_delete_subsystem_ana(self, caplog, gateway):
cli(["delete_subsystem", "-n", subsystem])
assert "Failed to delete" not in caplog.text

0 comments on commit d8a4ef2

Please sign in to comment.