Example #1
0
def connect_multipath_nexuses(uris):
    dev1 = nvme_connect(uris[0])
    dev2 = None

    try:
        dev2 = nvme_connect(uris[1])
    except Exception:
        # The first connect is allowed to fail due to controller ID collision.
        pass

    if dev2 is None:
        dev2 = nvme_connect(uris[1])

    return (dev1, dev2)
def create_nexus_2(mayastor_mod, nexus_name, nexus_uuid, min_cntlid_2,
                   resv_key_2):
    """ Create a 2nd nexus on ms0 with the same 2 replicas but with resv_key_2 """
    hdls = mayastor_mod
    NEXUS_NAME = nexus_name

    replicas = []
    list = mayastor_mod.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == NEXUS_NAME)
    replicas.append(nexus.children[0].uri)
    replicas.append(nexus.children[1].uri)

    NEXUS_UUID, size_mb = nexus_uuid

    hdls["ms0"].nexus_create_v2(
        NEXUS_NAME,
        NEXUS_UUID,
        size_mb,
        min_cntlid_2,
        min_cntlid_2 + 9,
        resv_key_2,
        0,
        replicas,
    )
    uri = hdls["ms0"].nexus_publish(NEXUS_NAME)
    assert len(hdls["ms0"].bdev_list()) == 1
    assert len(hdls["ms1"].bdev_list()) == 2
    assert len(hdls["ms2"].bdev_list()) == 2
    assert len(hdls["ms3"].bdev_list()) == 1

    dev = nvme_connect(uri)

    yield dev
    nvme_disconnect(uri)
    hdls["ms0"].nexus_destroy(NEXUS_NAME)
def create_nexus(mayastor_mod, nexus_name, nexus_uuid, create_replica,
                 min_cntlid, resv_key):
    """ Create a nexus on ms3 with 2 replicas """
    hdls = mayastor_mod
    replicas = create_replica
    replicas = [k.uri for k in replicas]

    NEXUS_UUID, size_mb = nexus_uuid
    NEXUS_NAME = nexus_name

    hdls["ms3"].nexus_create_v2(
        NEXUS_NAME,
        NEXUS_UUID,
        size_mb,
        min_cntlid,
        min_cntlid + 9,
        resv_key,
        0,
        replicas,
    )
    uri = hdls["ms3"].nexus_publish(NEXUS_NAME)
    assert len(hdls["ms1"].bdev_list()) == 2
    assert len(hdls["ms2"].bdev_list()) == 2
    assert len(hdls["ms3"].bdev_list()) == 1

    assert len(hdls["ms1"].pool_list().pools) == 1
    assert len(hdls["ms2"].pool_list().pools) == 1

    dev = nvme_connect(uri)

    yield dev
    nvme_disconnect(uri)
    hdls["ms3"].nexus_destroy(NEXUS_NAME)
Example #4
0
def test_nexus_resv_key(create_nexus_v2, nexus_name, nexus_uuid, mayastors,
                        resv_key):
    """Test create_nexus_v2 replica NVMe reservation key"""

    uri = create_nexus_v2
    NEXUS_UUID, _ = nexus_uuid

    list = mayastors.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == nexus_name)
    assert nexus.uuid == NEXUS_UUID
    child_uri = nexus.children[0].uri

    dev = nvme_connect(child_uri)
    try:
        report = nvme_resv_report(dev)
        print(report)

        assert (report["rtype"] == 5
                ), "should have write exclusive, all registrants reservation"
        assert report["regctl"] == 1, "should have 1 registered controller"
        assert report[
            "ptpls"] == 0, "should have Persist Through Power Loss State of 0"
        assert (report["regctlext"][0]["cntlid"] == 0xFFFF
                ), "should have dynamic controller ID"

        # reservation status reserved
        assert (report["regctlext"][0]["rcsts"] & 0x1) == 1
        assert report["regctlext"][0]["rkey"] == resv_key

    finally:
        nvme_disconnect(child_uri)
Example #5
0
async def test_namespace_guid(create_replicas, create_nexuses, mayastor_mod):
    uri = create_nexuses[0]
    device = nvme_connect(uri)
    ns = identify_namespace(device)
    nvme_disconnect(uri)

    # Namespace's GUID must match Nexus GUID.
    assert uuid.UUID(ns["nguid"]) == uuid.UUID(
        NEXUS_GUID
    ), "Namespace NGID doesn't match Nexus GUID"

    # Extended Unique Identifier must be zero.
    assert ns["eui64"] == "0000000000000000", "Namespace EUI64 is not zero"
Example #6
0
async def test_nexus_2_mirror_kill_one(containers, mayastors, create_nexus):

    uri = create_nexus
    nvme_discover(uri)
    dev = nvme_connect(uri)
    try:
        job = Fio("job1", "rw", dev).build()
        print(job)

        to_kill = containers.get("ms2")
        await asyncio.gather(run_cmd_async(job), kill_after(to_kill, 5))

    finally:
        # disconnect target before we shutdown
        nvme_disconnect(uri)
Example #7
0
async def test_nexus_2_remote_mirror_kill_one(containers, mayastors,
                                              nexus_uuid, create_nexus):
    """
    This test does the following steps:

        - creates mayastor instances
        - creates pools on mayastor 1 and 2
        - creates replicas on those pools
        - creates a nexus on mayastor 3
        - starts fio on a remote VM (vixos1) for 15 secondsj
        - kills mayastor 2 after 4 seconds
        - assume the test to succeed
        - disconnect the VM from mayastor 3 when FIO completes
        - removes the nexus from mayastor 3
        - removes the replicas but as mayastor 2 is down, will swallow errors
        - removes the pool

    The bulk of this is done by reusing fixtures those fitures are not as
    generic as one might like at this point so look/determine if you need them
    to begin with.

    By yielding from fixtures, after the tests the function is resumed where
    yield is called.
    """

    uri = create_nexus
    dev = nvme_connect(uri)
    try:
        job = Fio("job1", "randwrite", dev).build()
        print(job)

        to_kill = containers.get("ms2")

        # create an event loop polling the async processes for completion
        await asyncio.gather(run_cmd_async(job), kill_after(to_kill, 4))

        list = mayastors.get("ms3").nexus_list()

        NEXUS_UUID, size_mb = nexus_uuid
        nexus = next(n for n in list if n.uuid == NEXUS_UUID)

        assert nexus.state == pb.NEXUS_DEGRADED
        assert nexus.children[1].state == pb.CHILD_FAULTED

    finally:
        # disconnect target before we shutdown
        nvme_disconnect(uri)
Example #8
0
async def test_nexus_cntlid(create_nexus_v2, min_cntlid):
    """Test create_nexus_v2 NVMe controller ID"""

    uri = create_nexus_v2

    dev = nvme_connect(uri)
    try:
        id_ctrl = nvme_id_ctrl(dev)
        assert id_ctrl["cntlid"] == min_cntlid

        # Test optional command support
        oncs = id_ctrl["oncs"]
        assert oncs & 0x04, "should support Dataset Management"
        assert oncs & 0x08, "should support Write Zeroes"

    finally:
        # disconnect target before we shut down
        nvme_disconnect(uri)
Example #9
0
def connect_to_node_2(publish_to_node_2):
    device = nvme_connect(publish_to_node_2)
    desc = nvme_list_subsystems(device)
    subsystem = desc["Subsystems"][0]
    assert len(
        subsystem["Paths"]) == 2, "Second nexus must be added to I/O path"

    good_path_checked = False
    broken_path_checked = False
    for p in subsystem["Paths"]:
        if p["Name"] in device:
            assert p[
                "State"] == "connecting", "Degraded I/O path has incorrect state"
            broken_path_checked = True
        else:
            assert p["State"] == "live", "Healthy I/O path has incorrect state"
            good_path_checked = True
    assert good_path_checked, "No state reported for healthy I/O path"
    assert broken_path_checked, "No state reported for broken I/O path"
Example #10
0
def test_nexus_multipath(
    create_nexus,
    create_nexus_2,
    nexus_name,
    nexus_uuid,
    mayastor_mod,
    resv_key,
    resv_key_2,
):
    """Create 2 nexuses, each with 2 replicas, with different NVMe reservation keys"""

    uri = create_nexus
    uri2 = create_nexus_2
    NEXUS_UUID, _ = nexus_uuid
    NEXUS_NAME = nexus_name
    resv_key = resv_key
    resv_key_2 = resv_key_2

    list = mayastor_mod.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == NEXUS_NAME)
    assert nexus.uuid == NEXUS_UUID

    for c in range(2):
        child_uri = nexus.children[c].uri

        dev = nvme_connect(child_uri)
        report = nvme_resv_report(dev)

        assert (report["rtype"] == 5
                ), "should have write exclusive, all registrants reservation"
        assert report["regctl"] == 2, "should have 2 registered controllers"
        assert report[
            "ptpls"] == 0, "should have Persist Through Power Loss State of 0"
        for i in range(2):
            assert (report["regctlext"][i]["cntlid"] == 0xFFFF
                    ), "should have dynamic controller ID"
        assert report["regctlext"][0]["rkey"] == resv_key
        assert report["regctlext"][1]["rkey"] == resv_key_2
        assert (report["regctlext"][0]["rcsts"] & 0x1) == 1
        assert (report["regctlext"][1]["rcsts"] & 0x1) == 0

        nvme_disconnect(child_uri)
Example #11
0
def create_nexus_3_dev(mayastor_mod, nexus_name, nexus_uuid, replica_uuid,
                       min_cntlid_3, resv_key_3):
    """ Create a 3rd nexus on ms1 with the same 2 replicas but with resv_key_3 """
    hdls = mayastor_mod
    NEXUS_NAME = nexus_name

    replicas = []
    list = mayastor_mod.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == NEXUS_NAME)
    # use loopback until nvme initiator can connect to target in same instance
    REP_UUID, rep_size_mb = replica_uuid
    replicas.append("loopback:///" + REP_UUID)
    replicas.append(nexus.children[1].uri)

    NEXUS_UUID, size_mb = nexus_uuid

    hdls["ms1"].nexus_create_v2(
        NEXUS_NAME,
        NEXUS_UUID,
        size_mb,
        min_cntlid_3,
        min_cntlid_3 + 9,
        resv_key_3,
        0,
        replicas,
    )
    uri = hdls["ms1"].nexus_publish(NEXUS_NAME)
    assert len(hdls["ms0"].bdev_list()) == 1
    assert len(hdls["ms1"].bdev_list()) == 3
    assert len(hdls["ms2"].bdev_list()) == 2
    assert len(hdls["ms3"].bdev_list()) == 1

    dev = nvme_connect(uri)

    yield dev
    nvme_disconnect(uri)
    hdls["ms1"].nexus_destroy(NEXUS_NAME)
Example #12
0
def connect_devices(publish_nexuses):
    yield [nvme_connect(nexus) for nexus in publish_nexuses]
    for nexus in publish_nexuses:
        nvme_disconnect(nexus)
Example #13
0
def connect_devices(create_nexuses):
    "Connect an nvmf device to each nexus."
    yield [nvme_connect(nexus) for nexus in create_nexuses]

    for nexus in create_nexuses:
        nvme_disconnect(nexus)
Example #14
0
def connect_to_first_path(background):
    volume = background
    device_uri = volume.state["target"]["deviceUri"]
    yield nvme_connect(device_uri)
    nvme_disconnect(device_uri)
Example #15
0
def test_nexus_preempt_key(
    create_nexus_v2,
    create_nexus_2_v2,
    nexus_name,
    nexus_uuid,
    mayastors,
    resv_key_2,
):
    """Create a nexus on ms3 and ms0, with the latter preempting the NVMe
    reservation key registered by ms3, verify that ms3 is no longer registered.
    Verify that writes succeed via the nexus on ms0 but not ms3."""

    NEXUS_UUID, _ = nexus_uuid

    list = mayastors.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == nexus_name)
    assert nexus.uuid == NEXUS_UUID
    child_uri = nexus.children[0].uri
    assert nexus.state == pb.NEXUS_ONLINE
    assert nexus.children[0].state == pb.CHILD_ONLINE
    assert nexus.children[1].state == pb.CHILD_ONLINE

    dev = nvme_connect(child_uri)
    try:
        report = nvme_resv_report(dev)
        print(report)

        assert (report["rtype"] == 5
                ), "should have write exclusive, all registrants reservation"
        assert report["regctl"] == 1, "should have 1 registered controller"
        assert report[
            "ptpls"] == 0, "should have Persist Through Power Loss State of 0"
        assert (report["regctlext"][0]["cntlid"] == 0xFFFF
                ), "should have dynamic controller ID"

        # reservation status reserved
        assert (report["regctlext"][0]["rcsts"] & 0x1) == 1
        assert report["regctlext"][0]["rkey"] == resv_key_2

    finally:
        nvme_disconnect(child_uri)

    # verify write with nexus on ms0
    uri = create_nexus_2_v2
    dev = nvme_connect(uri)
    job = "sudo dd if=/dev/urandom of={0} bs=512 count=1".format(dev)

    try:
        run_cmd(job)

    finally:
        nvme_disconnect(uri)

    list = mayastors.get("ms0").nexus_list_v2()
    nexus = next(n for n in list if n.name == nexus_name)
    assert nexus.state == pb.NEXUS_ONLINE
    assert nexus.children[0].state == pb.CHILD_ONLINE
    assert nexus.children[1].state == pb.CHILD_ONLINE

    # verify write error with nexus on ms3
    uri = create_nexus_v2
    dev = nvme_connect(uri)
    job = "sudo dd if=/dev/urandom of={0} bs=512 count=1".format(dev)

    try:
        run_cmd(job)

    finally:
        nvme_disconnect(uri)

    list = mayastors.get("ms3").nexus_list_v2()
    nexus = next(n for n in list if n.name == nexus_name)
    assert nexus.state == pb.NEXUS_FAULTED
    assert nexus.children[0].state == pb.CHILD_FAULTED
    assert nexus.children[1].state == pb.CHILD_FAULTED
Example #16
0
def connect_nexus_2(create_nexus_2_no_destroy):
    uri = create_nexus_2_no_destroy
    dev = nvme_connect(uri)
    return dev