Skip to content

Commit a6c2616

Browse files
jeongda-youngDajeong-Park
authored andcommitted
vhba 복원 스크립트
1 parent 406aa26 commit a6c2616

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[Unit]
2+
Description=Restore vHBA devices after reboot
3+
After=libvirtd.service network.target
4+
Before=cloudstack-agent.service
5+
Wants=libvirtd.service
6+
Requires=libvirtd.service
7+
8+
[Service]
9+
Type=oneshot
10+
ExecStart=/usr/local/bin/restore-vhba.sh
11+
RemainAfterExit=yes
12+
TimeoutSec=300
13+
14+
[Install]
15+
WantedBy=multi-user.target

scripts/installer/restore-vhba.sh

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#!/bin/bash
2+
3+
# VHBA 자동 복원 스크립트
4+
# /etc/vhba 경로의 dumpxml 파일들을 사용하여 vHBA 복원
5+
# WWN 기반으로 vHBA 이름을 고정
6+
7+
VHBA_DIR="/etc/vhba"
8+
LOG_FILE="/var/log/cloudstack/vhba-restore.log"
9+
MAPPING_FILE="/etc/vhba/wwn_mapping.conf"
10+
11+
# 로그 함수
12+
log_message() {
13+
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
14+
}
15+
16+
# WWN 매핑 파일 생성/업데이트
17+
update_wwn_mapping() {
18+
log_message "WWN 매핑 업데이트 시작"
19+
20+
# 매핑 파일 초기화
21+
> "$MAPPING_FILE"
22+
23+
# 현재 활성 vHBA들의 WWN 정보 수집
24+
for vhba in $(virsh nodedev-list | grep "^scsi_host"); do
25+
wwnn=$(virsh nodedev-dumpxml "$vhba" 2>/dev/null | grep "<wwnn>" | sed 's/.*<wwnn>\(.*\)<\/wwnn>.*/\1/')
26+
wwpn=$(virsh nodedev-dumpxml "$vhba" 2>/dev/null | grep "<wwpn>" | sed 's/.*<wwpn>\(.*\)<\/wwpn>.*/\1/')
27+
28+
if [ -n "$wwnn" ] && [ -n "$wwpn" ]; then
29+
echo "${wwnn}:${wwpn}=$vhba" >> "$MAPPING_FILE"
30+
log_message "WWN 매핑 추가: ${wwnn}:${wwpn} -> $vhba"
31+
fi
32+
done
33+
34+
log_message "WWN 매핑 업데이트 완료"
35+
}
36+
37+
# WWN으로 vHBA 이름 찾기
38+
find_vhba_by_wwn() {
39+
local wwnn="$1"
40+
local wwpn="$2"
41+
local wwn_key="${wwnn}:${wwpn}"
42+
43+
if [ -f "$MAPPING_FILE" ]; then
44+
grep "^$wwn_key=" "$MAPPING_FILE" | cut -d'=' -f2
45+
fi
46+
}
47+
48+
log_message "VHBA 복원 시작"
49+
50+
# /etc/vhba 디렉토리 존재 확인
51+
if [ ! -d "$VHBA_DIR" ]; then
52+
log_message "/etc/vhba 디렉토리가 존재하지 않습니다: $VHBA_DIR"
53+
exit 0
54+
fi
55+
56+
# libvirtd 서비스가 완전히 시작될 때까지 대기
57+
log_message "libvirtd 서비스 대기 중..."
58+
for i in {1..30}; do
59+
if systemctl is-active --quiet libvirtd; then
60+
log_message "libvirtd 서비스가 활성화되었습니다."
61+
break
62+
fi
63+
log_message "libvirtd 서비스 대기 중... ($i/30)"
64+
sleep 2
65+
done
66+
67+
# 추가 대기 시간 (디바이스 스캔 완료 대기)
68+
log_message "디바이스 스캔 완료 대기 중..."
69+
sleep 5
70+
71+
# 기존 vHBA들의 WWN 매핑 업데이트
72+
update_wwn_mapping
73+
74+
# /etc/vhba 경로의 XML 파일들로 vHBA 복원
75+
restore_count=0
76+
failed_count=0
77+
78+
for xml_file in "$VHBA_DIR"/*.xml; do
79+
if [ -f "$xml_file" ]; then
80+
filename=$(basename "$xml_file")
81+
device_name=$(basename "$xml_file" .xml)
82+
83+
log_message "vHBA 복원 시도: $filename"
84+
85+
# XML 파일 유효성 검사
86+
if ! grep -q "<name>" "$xml_file" || ! grep -q "<path>" "$xml_file"; then
87+
log_message "XML 파일이 불완전함 (name 또는 path 태그 누락): $filename"
88+
failed_count=$((failed_count + 1))
89+
continue
90+
fi
91+
92+
# 백업된 vHBA의 WWN 추출
93+
backup_wwnn=$(grep "<wwnn>" "$xml_file" | sed 's/.*<wwnn>\(.*\)<\/wwnn>.*/\1/')
94+
backup_wwpn=$(grep "<wwpn>" "$xml_file" | sed 's/.*<wwpn>\(.*\)<\/wwpn>.*/\1/')
95+
96+
if [ -n "$backup_wwnn" ] && [ -n "$backup_wwpn" ]; then
97+
log_message "vHBA WWN: $backup_wwnn:$backup_wwpn"
98+
99+
# WWN으로 기존 vHBA 찾기
100+
existing_vhba=$(find_vhba_by_wwn "$backup_wwnn" "$backup_wwpn")
101+
102+
if [ -n "$existing_vhba" ]; then
103+
log_message "동일한 WWN을 가진 vHBA 발견: $existing_vhba"
104+
105+
# 기존 vHBA가 있으면 삭제
106+
log_message "기존 vHBA 삭제 중: $existing_vhba"
107+
virsh nodedev-destroy "$existing_vhba" 2>/dev/null
108+
sleep 1
109+
fi
110+
fi
111+
112+
# 부모 디바이스 확인
113+
parent_device=$(grep "<parent>" "$xml_file" | sed 's/.*<parent>\(.*\)<\/parent>.*/\1/')
114+
if [ -n "$parent_device" ]; then
115+
log_message "부모 디바이스 확인: $parent_device"
116+
if ! virsh nodedev-list | grep -q "^$parent_device$"; then
117+
log_message "부모 디바이스가 존재하지 않음: $parent_device"
118+
failed_count=$((failed_count + 1))
119+
continue
120+
fi
121+
fi
122+
123+
# virsh nodedev-create로 vHBA 디바이스 생성
124+
result=$(virsh nodedev-create "$xml_file" 2>&1)
125+
126+
if [ $? -eq 0 ]; then
127+
log_message "복원 성공: $filename"
128+
restore_count=$((restore_count + 1))
129+
130+
# 생성된 vHBA의 실제 이름 추출
131+
created_vhba=$(echo "$result" | grep "created" | sed 's/.*created from.*//' | tr -d ' ')
132+
if [ -n "$created_vhba" ]; then
133+
log_message "생성된 vHBA: $created_vhba"
134+
135+
# 새로운 vHBA의 WWN 매핑 업데이트
136+
new_wwnn=$(virsh nodedev-dumpxml "$created_vhba" 2>/dev/null | grep "<wwnn>" | sed 's/.*<wwnn>\(.*\)<\/wwnn>.*/\1/')
137+
new_wwpn=$(virsh nodedev-dumpxml "$created_vhba" 2>/dev/null | grep "<wwpn>" | sed 's/.*<wwpn>\(.*\)<\/wwpn>.*/\1/')
138+
139+
if [ -n "$new_wwnn" ] && [ -n "$new_wwpn" ]; then
140+
# 기존 매핑 제거
141+
sed -i "/^${new_wwnn}:${new_wwpn}=/d" "$MAPPING_FILE" 2>/dev/null
142+
# 새 매핑 추가
143+
echo "${new_wwnn}:${new_wwpn}=$created_vhba" >> "$MAPPING_FILE"
144+
log_message "WWN 매핑 업데이트: ${new_wwnn}:${new_wwpn} -> $created_vhba"
145+
fi
146+
fi
147+
else
148+
log_message "복원 실패: $filename - $result"
149+
failed_count=$((failed_count + 1))
150+
fi
151+
fi
152+
done
153+
154+
# 복원 후 상태 확인
155+
final_vhbas=$(virsh nodedev-list | grep "^scsi_host" 2>/dev/null | wc -l)
156+
log_message "복원 후 활성 vHBA 디바이스 수: $final_vhbas"
157+
158+
# 복원 결과 요약
159+
log_message "VHBA 복원 완료: 성공 $restore_count 개, 실패 $failed_count"
160+
log_message "VHBA 복원 프로세스 완료"

0 commit comments

Comments
 (0)