LIO 타겟 프레임워크 (Linux I/O Target)

리눅스 커널의 범용 스토리지 타겟 프레임워크 LIO를 엔터프라이즈 SAN/NAS 운영 관점에서 심층 분석합니다. Target Core(TCM)의 객체 모델과 I/O 파이프라인, iSCSI/FC/NVMe-oF Fabric 모듈의 접속·세션·큐 처리 방식, configfs 기반 선언형 설정의 계층 구조와 자동화 포인트, 인증/접근 제어/ALUA 경로 정책, Persistent Reservations를 포함한 클러스터 안전성 기능, 장애 시 세션 복구 및 재접속 흐름, drivers/target/ 소스 트리를 통한 코드 추적 방법, 성능 측정과 병목 제거 절차까지 실무 구축과 운영에 필요한 세부 내용을 다룹니다.

전제 조건: SCSI / iSCSI 서브시스템, Block I/O, NVMe 문서를 먼저 읽으세요. LIO는 블록 디바이스를 여러 전송 프로토콜로 내보내는 타겟 프레임워크입니다. 블록 계층과 SCSI 스택에 대한 이해가 선행되어야 합니다.

핵심 요약

  • LIO(Linux I/O Target) — Linux 2.6.38부터 메인라인에 포함된 커널 스토리지 타겟 프레임워크입니다. SAN 환경에서 서버가 스토리지를 제공(Expose)하는 역할을 합니다.
  • Target Core(TCM) — Fabric 프로토콜과 독립적인 공통 백엔드 계층입니다. SCSI 명령 처리, 세션 관리, LUN 매핑을 담당합니다.
  • Fabric 모듈 — iSCSI, FC, SRP, NVMe-oF 등 다양한 전송 프로토콜을 TCM에 연결하는 플러그인 계층입니다.
  • configfs/sys/kernel/config/target/을 통해 타겟 설정을 파일시스템 트리로 관리합니다. targetcli가 이를 활용합니다.
  • ALUA — Asymmetric Logical Unit Access. 멀티패스 환경에서 포트별 접근 상태(Active/Optimized/Non-Optimized)를 정의합니다.
  • Persistent Reservations(PR) — 클러스터 환경에서 LUN 점유 제어. SCSI PR(PROUT/PRIN) 명령으로 독점·공유 예약을 관리합니다.
  • NVMe-oF 타겟 — nvmet.ko로 NVMe 네임스페이스를 TCP/RDMA/FC로 내보냅니다. iSCSI 대비 레이턴시가 낮습니다.
  • iSCSI 타겟 — TCP 위에서 SCSI 명령을 전송합니다. 별도 HBA 없이 이더넷만으로 SAN 구성이 가능합니다.

단계별 이해

  1. 타겟 vs 이니시에이터 개념 구분 — 스토리지를 제공하는 쪽이 타겟(Target), 접근하는 쪽이 이니시에이터(Initiator)입니다.

    LIO는 타겟 역할을 담당합니다. iSCSI 클라이언트(open-iscsi)가 이니시에이터 역할을 합니다.

  2. TCM + Fabric 구조 이해 — TCM이 공통 SCSI 로직을, Fabric이 전송 계층을 담당하는 분리 구조입니다.

    iSCSI를 쓰든 NVMe-oF를 쓰든 TCM의 SCSI 처리 코드는 동일하게 재사용됩니다.

  3. configfs로 설정 관리targetcli 명령으로 backstore, target, lun, acl을 대화형으로 설정합니다.

    설정은 /sys/kernel/config/target/에 가상 파일로 반영됩니다.

  4. iSCSI 타겟 설정 실습 — targetcli로 fileio/block backstore를 만들고 IQN을 생성하여 클라이언트가 접속하도록 합니다.

    iscsiadm -m discovery로 타겟을 발견하고 -m node --login으로 접속합니다.

  5. ALUA로 멀티패스 제어 — 여러 포트 그룹에 Active/Standby를 지정하여 경로 장애 시 자동 페일오버를 구성합니다.

    클라이언트에서 multipathd가 ALUA 상태를 읽어 최적 경로를 선택합니다.

  6. PR로 클러스터 잠금 구현 — Pacemaker 클러스터에서 SCSI PR을 사용하여 한 번에 하나의 노드만 쓰기 접근하도록 제어합니다.

    DRBD와 결합하면 완전한 HA 스토리지 클러스터를 구성할 수 있습니다.

LIO 타겟 프레임워크 개요

LIO(Linux I/O Target)는 Linux 커널 2.6.38(2011년)부터 메인라인에 포함된 범용 스토리지 타겟 프레임워크입니다. 이전에는 SCST, tgt, iSCSI Enterprise Target 등 여러 경쟁 구현이 있었으나, LIO가 공식 커널 타겟으로 통합되었습니다.

LIO는 Target Core(TCM)Fabric 모듈의 이중 계층 구조로 설계되어, 하나의 공통 SCSI 처리 엔진 위에 iSCSI, FC, SRP(InfiniBand), NVMe-oF 등 다양한 전송 계층을 플러그인 방식으로 연결할 수 있습니다.

특성내용
메인라인 포함Linux 2.6.38 (2011년 3월)
소스 위치drivers/target/
설정 인터페이스configfs (/sys/kernel/config/target/)
사용자 도구targetcli, rtslib-fb, targetcli-fb
지원 FabriciSCSI, FC(tcm_qla2xxx), SRP, NVMe-oF(TCP/RDMA/FC), Loopback
백엔드 타입fileio, block, pscsi, ramdisk, user
ALUA 지원포트 그룹별 Active/Optimized/Non-Optimized 상태
PR 지원SCSI Persistent Reservations (SPC-4)

LIO 레이어드 아키텍처

LIO는 이니시에이터(클라이언트)에서 스토리지 백엔드까지 명확하게 분리된 계층 구조를 가집니다.

이니시에이터 open-iscsi / nvme-cli 네트워크 전송 TCP/RDMA/FC/IB Fabric 모듈 계층 iscsi_target_mod tcm_qla2xxx (FC) nvmet (NVMe-oF) target_loopback Target Core (TCM) — target_core_mod SCSI 명령 처리 · 세션/LUN 관리 · ALUA · PR · 큐잉 백엔드 스토리지 fileio block (블록 디바이스) pscsi (pass-through) ramdisk

핵심 개념

개념설명커널 구조체
Target스토리지를 제공하는 노드 (서버)se_device
Initiator스토리지를 사용하는 노드 (클라이언트)se_node_acl
LUNLogical Unit Number — 타겟이 노출하는 논리 디바이스 단위se_lun
Portal타겟이 수신 대기하는 네트워크 엔드포인트 (IP:포트)iscsi_tpg_np
TPGTarget Portal Group — 포털들의 그룹se_portal_group
Session이니시에이터-타겟 간 연결 상태se_session
ACLAccess Control List — 이니시에이터별 접근 권한se_node_acl
Backstore실제 데이터를 저장하는 백엔드 (파일, 블록 디바이스 등)se_device

Target Core (TCM) 내부 구조

TCM은 Fabric으로부터 SCSI 명령(CDB)을 받아 처리하는 공통 엔진입니다. drivers/target/target_core_*.c에 구현되어 있습니다.

핵심 구조체

/* se_device: 백엔드 스토리지 디바이스 추상화 */
struct se_device {
    struct se_dev_attrib   dev_attrib;    /* 블록 사이즈, 큐 깊이 등 */
    struct target_backend  *transport;    /* fileio/block/pscsi 백엔드 */
    struct se_subsystem_api *transport_ops;
    struct alua_dev_group  *t10_alua;     /* ALUA 상태 */
    struct t10_pr_registration *dev_pr_res; /* Persistent Reservation */
    spinlock_t              execute_task_lock;
    struct list_head        state_list;   /* 실행 중인 태스크 */
    u64                     dev_sectors;  /* 디바이스 크기 (섹터) */
};

/* se_lun: Logical Unit Number 매핑 */
struct se_lun {
    u64                     unpacked_lun;  /* LUN 번호 */
    struct se_device        *lun_se_dev;   /* 연결된 디바이스 */
    struct se_portal_group  *lun_tpg;     /* 소속 TPG */
    struct percpu_ref       lun_ref;       /* 참조 카운트 */
    struct rcu_head         rcu_head;
};

/* se_session: 이니시에이터 세션 */
struct se_session {
    struct se_node_acl  *se_acl;       /* 이니시에이터 ACL */
    struct se_portal_group *se_tpg;    /* 소속 TPG */
    struct list_head     sess_acl_list; /* ACL 목록 */
    void                *fabric_sess_ptr; /* Fabric 전용 세션 데이터 */
    u64                  sess_cmd_map;
};

TCM 명령 처리 흐름

/* Fabric이 TCM으로 SCSI 명령을 전달하는 일반적인 흐름 */

/* 1. Fabric: 수신한 CDB를 se_cmd에 매핑 */
int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
                      const unsigned char *cdb, struct scatterlist *sgl,
                      u32 data_length, int task_attr, int data_dir,
                      int flags);

/* 2. TCM: LUN 조회 → 디바이스 매핑 */
/*    → target_core_mod.c: target_check_reservation() PR 검사 */
/*    → target_core_mod.c: target_execute_cmd() 백엔드 호출 */

/* 3. 백엔드(fileio 예시): 실제 I/O 수행 */
static sense_reason_t
fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
              enum dma_data_direction data_direction)
{
    struct fd_dev *fd_dev = TCM_FD_DEV(cmd->se_dev);
    struct fd_prot fd_prot;

    if (data_direction == DMA_FROM_DEVICE)
        return fd_do_rw(cmd, fd_dev->fd_file, sgl, sgl_nents, 0);
    else
        return fd_do_rw(cmd, fd_dev->fd_file, sgl, sgl_nents, 1);
}

/* 4. 완료: Fabric의 완료 콜백 호출 */
transport_generic_complete_ok(cmd);   /* → Fabric이 이니시에이터에게 응답 전송 */

Fabric 모듈 구조

Fabric 모듈은 target_core_fabric_ops 구조체를 통해 TCM과 인터페이스합니다. 각 Fabric은 고유한 전송 프로토콜을 구현하고 TCM API를 호출합니다.

/* Fabric 모듈이 TCM에 등록하는 연산자 테이블 */
struct target_core_fabric_ops {
    struct module  *module;
    const char     *name;

    /* 이니시에이터 식별자 (IQN, WWN 등) */
    char *(*get_fabric_name)(void);
    char *(*get_wwn)(struct se_portal_group *);

    /* 세션 관리 */
    int  (*sess_get_index)(struct se_session *);
    u32  (*sess_get_initiator_sid)(struct se_session *,
                                    unsigned char *, u32);

    /* 응답 전송 */
    int  (*write_pending)(struct se_cmd *);
    int  (*queue_data_in)(struct se_cmd *);
    int  (*queue_status)(struct se_cmd *);

    /* configfs 등록 */
    const struct config_item_type *tfc_wwn_cit;
    const struct config_item_type *tfc_tpg_cit;
    const struct config_item_type *tfc_tpg_lun_cit;
};
Fabric 모듈커널 모듈명전송 프로토콜소스 경로
iSCSI Targetiscsi_target_modTCP (포트 3260)drivers/target/iscsi/
FC Targettcm_qla2xxxFibre Channeldrivers/scsi/qla2xxx/
SRP Targettcm_loopInfiniBand SRPdrivers/infiniband/ulp/srpt/
NVMe-oF TCPnvmet + nvmet-tcpTCP (포트 4420)drivers/nvme/target/
NVMe-oF RDMAnvmet + nvmet-rdmaInfiniBand/RoCEdrivers/nvme/target/
NVMe-oF FCnvmet + nvmet-fcFibre Channeldrivers/nvme/target/
Loopbacktcm_loop로컬 (테스트용)drivers/target/loopback/

configfs 기반 설정 체계

LIO의 모든 설정은 /sys/kernel/config/target/ configfs 마운트 포인트를 통해 이루어집니다. targetcli는 이 인터페이스를 래핑한 사용자 친화적 도구입니다.

configfs 트리 구조

/sys/kernel/config/target/
├── core/                          # TCM 백엔드 설정
│   ├── fileio_0/                  # fileio 백엔드 그룹
│   │   └── disk1/                 # 개별 backstore 객체
│   │       ├── udev_path          # 파일 경로 또는 블록 디바이스
│   │       ├── enable             # 활성화 (1 쓰면 활성화)
│   │       └── attrib/            # 속성 (블록 사이즈, 큐 깊이)
│   └── iblock_0/                  # block 백엔드 그룹
├── iscsi/                         # iSCSI Fabric 설정
│   └── iqn.2024-01.com.example:storage/
│       └── tpgt_1/               # Target Portal Group
│           ├── acls/             # 이니시에이터 ACL
│           │   └── iqn.1991-05.com.redhat:client/
│           ├── lun/              # LUN 매핑
│           │   └── lun_0 -> core/fileio_0/disk1
│           └── np/               # Network Portals (IP:포트)
│               └── 0.0.0.0:3260
└── nvmet/                        # NVMe-oF Fabric 설정
    ├── subsystems/
    └── ports/

targetcli 단계별 설정

# targetcli 시작 (대화형 모드)
$ targetcli

# 또는 직접 명령어 실행
$ targetcli /backstores/block create name=lun0 dev=/dev/sdb

===================== 단계별 iSCSI 타겟 설정 =====================

# 1. Block 백엔드 생성
/> backstores/block create name=lun0 dev=/dev/sdb
Created block storage object lun0 using /dev/sdb.

# 2. iSCSI 타겟 생성 (IQN 자동 생성)
/> iscsi/ create iqn.2024-01.com.example:storage.lun0
Created target iqn.2024-01.com.example:storage.lun0.
Created TPG 1.

# 3. Network Portal 설정 (모든 IP, 기본 포트 3260)
/> iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1/portals/ create
Using default IP port 3260

# 4. LUN 매핑
/> iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1/luns/ create /backstores/block/lun0
Created LUN 0.

# 5. 이니시에이터 ACL 추가
/> iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1/acls/ create iqn.1991-05.com.redhat:client
Created Node ACL for iqn.1991-05.com.redhat:client
Created mapped LUN 0.

# 6. 인증 없이 접근 (개발/테스트 환경)
/> iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1/ set attribute authentication=0
# 프로덕션에서는 CHAP 인증 필수!

# 7. 설정 저장 및 확인
/> saveconfig
/> ls

fileio 백엔드 (파일 기반)

# 희소 파일로 가상 디스크 생성 (테스트용)
$ dd if=/dev/zero of=/var/lib/target/disk.img bs=1M count=0 seek=10240

# fileio 백엔드 생성
$ targetcli /backstores/fileio create name=testdisk file_or_dev=/var/lib/target/disk.img size=10G write_back=false

# write_back=false: 쓰기마다 동기화 (데이터 안전성 우선)
# write_back=true: 페이지 캐시 사용 (성능 우선)

iSCSI 타겟 심화

iSCSI 타겟은 TCP 소켓 위에서 iSCSI PDU(Protocol Data Unit)를 처리합니다. drivers/target/iscsi/에 구현되어 있습니다.

iSCSI 로그인 시퀀스

# iSCSI 로그인 3단계: Security → Operational → Full Feature

Phase 1: Security Negotiation
  Initiator: Login Request (AuthMethod=CHAP,None)
  Target:    Login Response (AuthMethod=CHAP)
  Initiator: CHAP_A=5 (MD5 선택)
  Target:    CHAP_I=1,CHAP_C=
  Initiator: CHAP_N=username,CHAP_R=
  Target:    Login Response (status=0x0000)

Phase 2: Operational Negotiation
  MaxRecvDataSegmentLength, MaxBurstLength, FirstBurstLength
  ImmediateData, InitialR2T, HeaderDigest, DataDigest

Phase 3: Full Feature Phase
  → SCSI Command PDU 교환 시작

커널 내부 iSCSI 처리

/* iscsi_target_mod 주요 처리 함수 */

/* TCP 수신 → PDU 파싱 */
static int iscsit_get_rx_pdu(struct iscsi_conn *conn)
{
    struct kvec iov;
    u32 checksum = 0, iov_count = 0;
    struct iscsi_hdr *hdr = &conn->work_buf[0];

    /* BHS(Basic Header Segment) 수신 */
    iscsit_recv_data_segment(conn, &iov, &iov_count, ISCSI_HDR_LEN);

    switch (hdr->opcode & ISCSI_OPCODE_MASK) {
    case ISCSI_OP_SCSI_CMD:
        iscsit_handle_scsi_cmd(conn, cmd, buf);
        break;
    case ISCSI_OP_NOOP_OUT:
        iscsit_handle_nop_out(conn, cmd, buf);
        break;
    case ISCSI_OP_SCSI_TMFUNC:
        iscsit_handle_task_mgt_cmd(conn, cmd, buf);
        break;
    }
}

iSCSI 오프로드 지원

일부 NIC는 iSCSI 오프로드(TOE: TCP Offload Engine + iSCSI 가속)를 지원합니다.

기능소프트웨어 iSCSIiSCSI 오프로드 NIC
TCP 처리커널 TCP 스택NIC 하드웨어
CRC(HeaderDigest)소프트웨어 CRC32C하드웨어 CRC32C
CPU 사용률높음 (대역폭 비례)낮음
드라이버iscsi_tcp (커널)bnx2i, cxgbi, be2iscsi
iSER (RDMA)해당 없음ib_iser + RDMA 어댑터

NVMe-oF 타겟

NVMe-oF 타겟은 drivers/nvme/target/에 구현되어 있으며, nvmet.ko가 공통 타겟 코어 역할을 합니다. iSCSI/LIO와는 별도의 스택이지만 유사한 configfs 기반 설정을 사용합니다.

iSCSI 타겟 (LIO) TCP 소켓 (포트 3260) iscsi_target_mod (PDU 파싱) Target Core (TCM) SCSI 처리 백엔드 (block/fileio) NVMe-oF 타겟 (nvmet) TCP/RDMA/FC (포트 4420) nvmet-tcp/rdma/fc (전송 계층) nvmet 코어 (NVMe 명령 처리) NVMe 네임스페이스 (블록/파일)

nvmet 설정

# 커널 모듈 로드
$ modprobe nvmet
$ modprobe nvmet-tcp

# configfs 마운트 (보통 자동 마운트됨)
$ mount -t configfs none /sys/kernel/config

# NVMe-oF 서브시스템 생성
$ mkdir /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0

# 모든 호스트 허용 (개발용)
$ echo 1 > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0/attr_allow_any_host

# 네임스페이스 생성 및 블록 디바이스 연결
$ mkdir /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0/namespaces/1
$ echo /dev/sdb > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0/namespaces/1/device_path
$ echo 1 > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0/namespaces/1/enable

# 포트 생성 (TCP, 포트 4420)
$ mkdir /sys/kernel/config/nvmet/ports/1
$ echo 0.0.0.0 > /sys/kernel/config/nvmet/ports/1/addr_traddr
$ echo 4420    > /sys/kernel/config/nvmet/ports/1/addr_trsvcid
$ echo tcp     > /sys/kernel/config/nvmet/ports/1/addr_trtype
$ echo ipv4    > /sys/kernel/config/nvmet/ports/1/addr_adrfam

# 서브시스템을 포트에 연결
$ ln -s /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.example:nvme0 \
        /sys/kernel/config/nvmet/ports/1/subsystems/

# 클라이언트에서 발견 및 접속
$ nvme discover -t tcp -a 192.168.1.100 -s 4420
$ nvme connect -t tcp -a 192.168.1.100 -s 4420 -n nqn.2024-01.com.example:nvme0
항목iSCSI (LIO)NVMe-oF (TCP)NVMe-oF (RDMA)
레이턴시~100µs~30µs~5µs
대역폭 오버헤드높음 (SCSI 변환)낮음매우 낮음
CPU 사용률높음중간낮음 (커널 바이패스)
네트워크 요구일반 이더넷일반 이더넷RoCE/InfiniBand
포트326044204420
커널 모듈iscsi_target_modnvmet-tcpnvmet-rdma

ALUA (Asymmetric Logical Unit Access)

ALUA는 멀티패스 환경에서 각 포트 그룹의 LUN 접근 상태를 비대칭적으로 정의하는 SCSI 표준(SPC-4)입니다. Active/Standby 포트 구성으로 고가용성을 실현합니다.

ALUA 포트 그룹 상태

상태설명I/O 처리
Active/Optimized (AO)최적 경로 — 로컬 컨트롤러I/O 직접 처리
Active/Non-Optimized (ANO)비최적 경로 — 원격 컨트롤러 경유I/O 처리 (성능 저하)
Standby (SB)대기 상태I/O 거부 (페일오버 대기)
Unavailable (UA)사용 불가I/O 거부
Offline (OF)오프라인I/O 거부
Transitioning (TR)상태 전환 중일시적 거부
# targetcli로 ALUA 포트 그룹 설정
/> /backstores/block/lun0 set alua_write_metadata=true

# 기본 ALUA 그룹 확인
/> /backstores/block/lun0/alua/ ls
o- alua
  o- default_tg_pt_gp [ALUA state: Active/Optimized]

# 새 포트 그룹 생성 (Active/Non-Optimized)
/> /backstores/block/lun0/alua/ create standby_group
/> /backstores/block/lun0/alua/standby_group set alua_access_state=2
# 0=Active/Optimized, 1=Active/Non-Optimized, 2=Standby, 3=Unavailable

# 클라이언트에서 ALUA 상태 확인
$ sg_rtpg /dev/sdb    # REPORT TARGET PORT GROUPS

Persistent Reservations (PR)

SCSI PR은 클러스터 환경에서 여러 이니시에이터 중 하나(또는 그룹)가 LUN 접근을 독점하거나 공유하는 메커니즘입니다. Pacemaker/Corosync와 함께 활성-수동 클러스터를 구성할 때 핵심 역할을 합니다.

PR 예약 타입

타입 (16진)설명사용 사례
0x01 WEWrite Exclusive — 등록자만 쓰기 가능단일 노드 쓰기 보호
0x03 EAExclusive Access — 등록자만 읽기/쓰기활성-수동 클러스터
0x05 WEARWrite Exclusive, All Registrants — 등록된 모든 이니시에이터 쓰기공유 쓰기
0x06 EAARExclusive Access, All Registrants — 등록된 모든 이니시에이터 독점클러스터 공유
# sg_persist로 PR 명령 테스트

# 키 등록 (PROUT REGISTER)
$ sg_persist --out --register --param-rk=0x0000000000000001 /dev/sdb

# 예약 획득 (PROUT RESERVE, EA 타입)
$ sg_persist --out --reserve --param-rk=0x0000000000000001 --prout-type=3 /dev/sdb

# 현재 예약 상태 확인 (PRIN READ RESERVATION)
$ sg_persist --in --read-reservation /dev/sdb

# 모든 등록자 확인 (PRIN READ FULL STATUS)
$ sg_persist --in --read-full-status /dev/sdb

# 예약 해제
$ sg_persist --out --release --param-rk=0x0000000000000001 --prout-type=3 /dev/sdb

Pacemaker + PR 연동

# Pacemaker SBD(Storage-Based Death) + SCSI PR 조합
# 노드 장애 시 SCSI PR로 스토리지 잠금 해제 → 다른 노드가 인수

# SBD 디바이스 초기화
$ sbd -d /dev/sdb create

# corosync.conf에서 SBD fence 에이전트 설정
$ crm configure primitive p_sbd stonith:external/sbd \
    params pcmk_delay_max=30 \
    op monitor interval=15 timeout=15

성능 튜닝

큐 깊이 및 스레드 설정

# iSCSI 타겟 스레드 수 조정 (기본: 논리 CPU 수)
$ targetcli /iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1 \
    set parameter MaxRecvDataSegmentLength=262144
$ targetcli /iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1 \
    set parameter MaxBurstLength=16776192
$ targetcli /iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1 \
    set parameter FirstBurstLength=262144

# 백엔드 블록 디바이스 큐 깊이 설정
$ targetcli /backstores/block/lun0 set attrib queue_depth=128

# iSCSI 이니시에이터 큐 깊이
$ iscsiadm -m node -T iqn.2024-01.com.example:storage.lun0 \
    --op update -n node.session.cmds_max -v 1024
$ iscsiadm -m node -T iqn.2024-01.com.example:storage.lun0 \
    --op update -n node.session.queue_depth -v 128

성능 측정 기준

시나리오iSCSI (10GbE)NVMe-oF/TCPNVMe-oF/RDMA
순차 읽기 대역폭~9.5 GB/s~9.8 GB/s~10 GB/s
4K 랜덤 읽기 IOPS~800K~1.2M~2M+
4K 읽기 레이턴시 (avg)~100µs~35µs~8µs
CPU 오버헤드 (10GbE)높음중간낮음

커널 소스 구조

경로내용
drivers/target/LIO Target Core 루트
drivers/target/target_core_mod.cTCM 코어 — 명령 처리, PR, ALUA
drivers/target/target_core_file.cfileio 백엔드
drivers/target/target_core_iblock.cblock 백엔드 (블록 디바이스)
drivers/target/target_core_pscsi.cpscsi 패스스루 백엔드
drivers/target/target_core_alua.cALUA 구현
drivers/target/target_core_pr.cPersistent Reservations 구현
drivers/target/target_core_configfs.cconfigfs 인터페이스
drivers/target/iscsi/iSCSI Fabric 모듈
drivers/target/loopback/Loopback Fabric (테스트용)
drivers/nvme/target/NVMe-oF 타겟 (nvmet)
include/target/LIO 공개 헤더
# 주요 Kconfig 옵션
CONFIG_TARGET_CORE=m              # LIO Target Core
CONFIG_ISCSI_TARGET=m             # iSCSI Fabric 모듈
CONFIG_LOOPBACK_TARGET=m          # Loopback 테스트 Fabric
CONFIG_TCM_FC=m                   # FC Fabric (tcm_qla2xxx 등)
CONFIG_NVME_TARGET=m              # NVMe-oF 타겟 코어
CONFIG_NVME_TARGET_TCP=m          # NVMe-oF TCP 전송
CONFIG_NVME_TARGET_RDMA=m         # NVMe-oF RDMA 전송

디버깅 도구

# targetcli 현재 설정 전체 보기
$ targetcli ls /

# 활성 세션 확인
$ targetcli /iscsi/iqn.2024-01.com.example:storage.lun0/tpgt1/acls/ ls

# /proc를 통한 iSCSI 세션 정보
$ cat /proc/net/iscsi/session
$ cat /proc/net/iscsi/connection

# LIO tracepoint 활성화
$ ls /sys/kernel/debug/tracing/events/target/
$ echo 1 > /sys/kernel/debug/tracing/events/target/target_cmd_complete/enable

# nvmet 디버그 로그
$ dmesg | grep nvmet

# iSCSI 세션 통계
$ cat /sys/kernel/config/target/iscsi/iqn.2024-01.com.example:storage.lun0/tpgt_1/sess_err_stats

# 백엔드 I/O 통계
$ cat /sys/kernel/config/target/core/iblock_0/lun0/statistics/scsi_dev/

# bpftrace로 TCM 완료 레이턴시 측정
$ bpftrace -e '
tracepoint:target:target_cmd_complete {
    @usecs = hist(args->data_length);
}'

LIO 타겟 프레임워크와 관련된 다른 주제를 더 깊이 이해하고 싶다면 다음 문서를 참고하세요.