LIO 타겟 프레임워크 (Linux I/O Target)
리눅스 커널의 범용 스토리지 타겟 프레임워크 LIO를 엔터프라이즈 SAN/NAS 운영 관점에서 심층 분석합니다. Target Core(TCM)의 객체 모델과 I/O 파이프라인, iSCSI/FC/NVMe-oF Fabric 모듈의 접속·세션·큐 처리 방식, configfs 기반 선언형 설정의 계층 구조와 자동화 포인트, 인증/접근 제어/ALUA 경로 정책, Persistent Reservations를 포함한 클러스터 안전성 기능, 장애 시 세션 복구 및 재접속 흐름, drivers/target/ 소스 트리를 통한 코드 추적 방법, 성능 측정과 병목 제거 절차까지 실무 구축과 운영에 필요한 세부 내용을 다룹니다.
핵심 요약
- 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 구성이 가능합니다.
단계별 이해
- 타겟 vs 이니시에이터 개념 구분 — 스토리지를 제공하는 쪽이 타겟(Target), 접근하는 쪽이 이니시에이터(Initiator)입니다.
LIO는 타겟 역할을 담당합니다. iSCSI 클라이언트(open-iscsi)가 이니시에이터 역할을 합니다.
- TCM + Fabric 구조 이해 — TCM이 공통 SCSI 로직을, Fabric이 전송 계층을 담당하는 분리 구조입니다.
iSCSI를 쓰든 NVMe-oF를 쓰든 TCM의 SCSI 처리 코드는 동일하게 재사용됩니다.
- configfs로 설정 관리 —
targetcli명령으로 backstore, target, lun, acl을 대화형으로 설정합니다.설정은
/sys/kernel/config/target/에 가상 파일로 반영됩니다. - iSCSI 타겟 설정 실습 — targetcli로 fileio/block backstore를 만들고 IQN을 생성하여 클라이언트가 접속하도록 합니다.
iscsiadm -m discovery로 타겟을 발견하고-m node --login으로 접속합니다. - ALUA로 멀티패스 제어 — 여러 포트 그룹에 Active/Standby를 지정하여 경로 장애 시 자동 페일오버를 구성합니다.
클라이언트에서 multipathd가 ALUA 상태를 읽어 최적 경로를 선택합니다.
- 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 |
| 지원 Fabric | iSCSI, 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는 이니시에이터(클라이언트)에서 스토리지 백엔드까지 명확하게 분리된 계층 구조를 가집니다.
핵심 개념
| 개념 | 설명 | 커널 구조체 |
|---|---|---|
| Target | 스토리지를 제공하는 노드 (서버) | se_device |
| Initiator | 스토리지를 사용하는 노드 (클라이언트) | se_node_acl |
| LUN | Logical Unit Number — 타겟이 노출하는 논리 디바이스 단위 | se_lun |
| Portal | 타겟이 수신 대기하는 네트워크 엔드포인트 (IP:포트) | iscsi_tpg_np |
| TPG | Target Portal Group — 포털들의 그룹 | se_portal_group |
| Session | 이니시에이터-타겟 간 연결 상태 | se_session |
| ACL | Access 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 Target | iscsi_target_mod | TCP (포트 3260) | drivers/target/iscsi/ |
| FC Target | tcm_qla2xxx | Fibre Channel | drivers/scsi/qla2xxx/ |
| SRP Target | tcm_loop | InfiniBand SRP | drivers/infiniband/ulp/srpt/ |
| NVMe-oF TCP | nvmet + nvmet-tcp | TCP (포트 4420) | drivers/nvme/target/ |
| NVMe-oF RDMA | nvmet + nvmet-rdma | InfiniBand/RoCE | drivers/nvme/target/ |
| NVMe-oF FC | nvmet + nvmet-fc | Fibre Channel | drivers/nvme/target/ |
| Loopback | tcm_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 가속)를 지원합니다.
| 기능 | 소프트웨어 iSCSI | iSCSI 오프로드 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 기반 설정을 사용합니다.
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 |
| 포트 | 3260 | 4420 | 4420 |
| 커널 모듈 | iscsi_target_mod | nvmet-tcp | nvmet-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 WE | Write Exclusive — 등록자만 쓰기 가능 | 단일 노드 쓰기 보호 |
0x03 EA | Exclusive Access — 등록자만 읽기/쓰기 | 활성-수동 클러스터 |
0x05 WEAR | Write Exclusive, All Registrants — 등록된 모든 이니시에이터 쓰기 | 공유 쓰기 |
0x06 EAAR | Exclusive 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/TCP | NVMe-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.c | TCM 코어 — 명령 처리, PR, ALUA |
drivers/target/target_core_file.c | fileio 백엔드 |
drivers/target/target_core_iblock.c | block 백엔드 (블록 디바이스) |
drivers/target/target_core_pscsi.c | pscsi 패스스루 백엔드 |
drivers/target/target_core_alua.c | ALUA 구현 |
drivers/target/target_core_pr.c | Persistent Reservations 구현 |
drivers/target/target_core_configfs.c | configfs 인터페이스 |
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 타겟 프레임워크와 관련된 다른 주제를 더 깊이 이해하고 싶다면 다음 문서를 참고하세요.