def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvcid=None,
                                priority=None, subnqn=None, hostnqn=None, hostaddr=None,
                                hostsvcid=None, prchk_reftag=None, prchk_guard=None,
                                hdgst=None, ddgst=None, fabrics_timeout=None, multipath=None, num_io_queues=None,
                                ctrlr_loss_timeout_sec=None, reconnect_delay_sec=None,
                                fast_io_fail_timeout_sec=None):
    """Construct block device for each NVMe namespace in the attached controller.

    Args:
        name: bdev name prefix; "n" + namespace ID will be appended to create unique names
        trtype: transport type ("PCIe", "RDMA", "FC", "TCP")
        traddr: transport address (PCI BDF or IP address)
        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
        trsvcid: transport service ID (port number for IP-based addresses)
        priority: transport connection priority (Sock priority for TCP-based transports; optional)
        subnqn: subsystem NQN to connect to (optional)
        hostnqn: NQN to connect from (optional)
        hostaddr: host transport address (IP address for IP-based transports, NULL for PCIe or FC; optional)
        hostsvcid: host transport service ID (port number for IP-based transports, NULL for PCIe or FC; optional)
        prchk_reftag: Enable checking of PI reference tag for I/O processing (optional)
        prchk_guard: Enable checking of PI guard for I/O processing (optional)
        hdgst: Enable TCP header digest (optional)
        ddgst: Enable TCP data digest (optional)
        fabrics_timeout: Fabrics connect timeout in us (optional)
        multipath: The behavior when multiple paths are created ("disable", "failover", or "multipath"; failover if not specified)
        num_io_queues: The number of IO queues to request during initialization. (optional)
        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
        -1 means infinite reconnect retries. 0 means no reconnect retry.
        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
        (optional)
        reconnect_delay_sec: Time to delay a reconnect retry.
        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
        (optional)
        fail_io_fast_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
        0 means no such timeout.
        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. (optional)

    Returns:
        Names of created block devices.
    """
    params = {'name': name,
              'trtype': trtype,
              'traddr': traddr}

    if hostnqn:
        params['hostnqn'] = hostnqn

    if hostaddr:
        params['hostaddr'] = hostaddr

    if hostsvcid:
        params['hostsvcid'] = hostsvcid

    if adrfam:
        params['adrfam'] = adrfam

    if trsvcid:
        params['trsvcid'] = trsvcid

    if priority:
        params['priority'] = priority

    if subnqn:
        params['subnqn'] = subnqn

    if prchk_reftag:
        params['prchk_reftag'] = prchk_reftag

    if prchk_guard:
        params['prchk_guard'] = prchk_guard

    if hdgst:
        params['hdgst'] = hdgst

    if ddgst:
        params['ddgst'] = ddgst

    if fabrics_timeout:
        params['fabrics_connect_timeout_us'] = fabrics_timeout

    if multipath:
        params['multipath'] = multipath

    if num_io_queues:
        params['num_io_queues'] = num_io_queues

    if ctrlr_loss_timeout_sec is not None:
        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec

    if reconnect_delay_sec is not None:
        params['reconnect_delay_sec'] = reconnect_delay_sec

    if fast_io_fail_timeout_sec is not None:
        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec

    return client.call('bdev_nvme_attach_controller', params)