Skip to content

Commit 97b01ac

Browse files
authored
Merge pull request #654 from jeongda-young/usb_lun_mdev-devices
[Mold] PCI, HBA, VHBA, USB,LUN, SCSI Devices 가상머신에 할당/해제/조회
2 parents 74d2037 + 1706f9e commit 97b01ac

File tree

74 files changed

+20788
-3349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+20788
-3349
lines changed

agent/bindir/restore-vhba.in

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

api/src/main/java/com/cloud/server/ManagementService.java

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,33 @@
1616
// under the License.
1717
package com.cloud.server;
1818

19+
import com.cloud.alert.Alert;
20+
import com.cloud.capacity.Capacity;
21+
import com.cloud.dc.Pod;
22+
import com.cloud.dc.Vlan;
23+
import com.cloud.exception.ConcurrentOperationException;
24+
import com.cloud.exception.ManagementServerException;
25+
import com.cloud.exception.ResourceUnavailableException;
26+
import com.cloud.exception.VirtualMachineMigrationException;
27+
import com.cloud.host.Host;
28+
import com.cloud.hypervisor.Hypervisor.HypervisorType;
29+
import com.cloud.hypervisor.HypervisorCapabilities;
30+
import com.cloud.network.IpAddress;
31+
import com.cloud.org.Cluster;
32+
import com.cloud.storage.GuestOS;
33+
import com.cloud.storage.GuestOSHypervisor;
34+
import com.cloud.storage.GuestOsCategory;
35+
import com.cloud.storage.StoragePool;
36+
import com.cloud.user.SSHKeyPair;
37+
import com.cloud.user.UserData;
38+
import com.cloud.utils.Pair;
39+
import com.cloud.utils.Ternary;
40+
import com.cloud.vm.InstanceGroup;
41+
import com.cloud.vm.VirtualMachine;
42+
import com.cloud.vm.VirtualMachine.Type;
1943
import java.util.ArrayList;
2044
import java.util.List;
2145
import java.util.Map;
22-
23-
import com.cloud.user.UserData;
2446
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
2547
import org.apache.cloudstack.api.command.admin.config.ListCfgGroupsByCmd;
2648
import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
@@ -35,13 +57,21 @@
3557
import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
3658
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
3759
import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
60+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.CreateVhbaDeviceCmd;
61+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.DeleteVhbaDeviceCmd;
3862
import org.apache.cloudstack.api.command.admin.outofbandmanagement.LicenseCheckCmd;
3963
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostDevicesCmd;
40-
// import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostLunDevicesCmd;
41-
// import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostUsbDevicesCmd;
64+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostHbaDevicesCmd;
65+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostLunDevicesCmd;
66+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostScsiDevicesCmd;
67+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListHostUsbDevicesCmd;
68+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.ListVhbaDevicesCmd;
4269
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostDevicesCmd;
43-
// import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostLunDevicesCmd;
44-
// import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostUsbDevicesCmd;
70+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostHbaDevicesCmd;
71+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostLunDevicesCmd;
72+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostScsiDevicesCmd;
73+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostUsbDevicesCmd;
74+
import org.apache.cloudstack.api.command.admin.outofbandmanagement.UpdateHostVhbaDevicesCmd;
4575
import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
4676
import org.apache.cloudstack.api.command.admin.resource.ArchiveAlertsCmd;
4777
import org.apache.cloudstack.api.command.admin.resource.DeleteAlertsCmd;
@@ -72,40 +102,27 @@
72102
import org.apache.cloudstack.api.command.user.userdata.RegisterUserDataCmd;
73103
import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
74104
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
105+
import org.apache.cloudstack.api.response.CreateVhbaDeviceResponse;
106+
import org.apache.cloudstack.api.response.DeleteVhbaDeviceResponse;
75107
import org.apache.cloudstack.api.response.LicenseCheckerResponse;
76108
import org.apache.cloudstack.api.response.ListHostDevicesResponse;
77-
// import org.apache.cloudstack.api.response.ListHostLunDevicesResponse;
78-
// import org.apache.cloudstack.api.response.ListHostUsbDevicesResponse;
109+
import org.apache.cloudstack.api.response.ListHostHbaDevicesResponse;
110+
import org.apache.cloudstack.api.response.ListHostLunDevicesResponse;
111+
import org.apache.cloudstack.api.response.ListHostScsiDevicesResponse;
112+
import org.apache.cloudstack.api.response.ListHostUsbDevicesResponse;
79113
import org.apache.cloudstack.api.response.ListResponse;
114+
import org.apache.cloudstack.api.response.ListVhbaDevicesResponse;
80115
import org.apache.cloudstack.api.response.UpdateHostDevicesResponse;
81-
// import org.apache.cloudstack.api.response.UpdateHostLunDevicesResponse;
82-
// import org.apache.cloudstack.api.response.UpdateHostUsbDevicesResponse;
116+
import org.apache.cloudstack.api.response.UpdateHostHbaDevicesResponse;
117+
import org.apache.cloudstack.api.response.UpdateHostLunDevicesResponse;
118+
import org.apache.cloudstack.api.response.UpdateHostScsiDevicesResponse;
119+
import org.apache.cloudstack.api.response.UpdateHostUsbDevicesResponse;
120+
import org.apache.cloudstack.api.response.UpdateHostVhbaDevicesResponse;
83121
import org.apache.cloudstack.config.Configuration;
84122
import org.apache.cloudstack.config.ConfigurationGroup;
85123

86-
import com.cloud.alert.Alert;
87-
import com.cloud.capacity.Capacity;
88-
import com.cloud.dc.Pod;
89-
import com.cloud.dc.Vlan;
90-
import com.cloud.exception.ConcurrentOperationException;
91-
import com.cloud.exception.ManagementServerException;
92-
import com.cloud.exception.ResourceUnavailableException;
93-
import com.cloud.exception.VirtualMachineMigrationException;
94-
import com.cloud.host.Host;
95-
import com.cloud.hypervisor.Hypervisor.HypervisorType;
96-
import com.cloud.hypervisor.HypervisorCapabilities;
97-
import com.cloud.network.IpAddress;
98-
import com.cloud.org.Cluster;
99-
import com.cloud.storage.GuestOS;
100-
import com.cloud.storage.GuestOSHypervisor;
101-
import com.cloud.storage.GuestOsCategory;
102-
import com.cloud.storage.StoragePool;
103-
import com.cloud.user.SSHKeyPair;
104-
import com.cloud.utils.Pair;
105-
import com.cloud.utils.Ternary;
106-
import com.cloud.vm.InstanceGroup;
107-
import com.cloud.vm.VirtualMachine;
108-
import com.cloud.vm.VirtualMachine.Type;
124+
125+
109126

110127

111128
/**
@@ -509,13 +526,29 @@ VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableE
509526

510527
ListResponse<UpdateHostDevicesResponse> updateHostDevices(UpdateHostDevicesCmd cmd);
511528

512-
// ListResponse<ListHostUsbDevicesResponse> listHostUsbDevices(ListHostUsbDevicesCmd cmd);
529+
ListResponse<ListHostUsbDevicesResponse> listHostUsbDevices(ListHostUsbDevicesCmd cmd);
530+
531+
ListResponse<ListHostLunDevicesResponse> listHostLunDevices(ListHostLunDevicesCmd cmd);
532+
533+
ListResponse<UpdateHostUsbDevicesResponse> updateHostUsbDevices(UpdateHostUsbDevicesCmd cmd);
534+
535+
ListResponse<UpdateHostLunDevicesResponse> updateHostLunDevices(UpdateHostLunDevicesCmd cmd);
536+
537+
ListResponse<ListHostHbaDevicesResponse> listHostHbaDevices(ListHostHbaDevicesCmd cmd);
538+
539+
ListResponse<UpdateHostHbaDevicesResponse> updateHostHbaDevices(UpdateHostHbaDevicesCmd cmd);
540+
541+
ListResponse<ListHostScsiDevicesResponse> listHostScsiDevices(ListHostScsiDevicesCmd cmd);
542+
543+
ListResponse<UpdateHostScsiDevicesResponse> updateHostScsiDevices(UpdateHostScsiDevicesCmd cmd);
544+
545+
ListResponse<CreateVhbaDeviceResponse> createVhbaDevice(CreateVhbaDeviceCmd cmd);
513546

514-
// ListResponse<ListHostLunDevicesResponse> listHostLunDevices(ListHostLunDevicesCmd cmd);
547+
ListResponse<DeleteVhbaDeviceResponse> deleteVhbaDevice(DeleteVhbaDeviceCmd cmd);
515548

516-
// ListResponse<UpdateHostUsbDevicesResponse> updateHostUsbDevices(UpdateHostUsbDevicesCmd cmd);
549+
ListResponse<ListVhbaDevicesResponse> listVhbaDevices(ListVhbaDevicesCmd cmd);
517550

518-
// ListResponse<UpdateHostLunDevicesResponse> updateHostLunDevices(UpdateHostLunDevicesCmd cmd);
551+
ListResponse<UpdateHostVhbaDevicesResponse> updateHostVhbaDevices(UpdateHostVhbaDevicesCmd cmd);
519552

520553
LicenseCheckerResponse checkLicense(LicenseCheckCmd cmd);
521554

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,11 @@ public class ApiConstants {
13161316
public static final String MIGRATION_IP = "migrationip";
13171317
public static final String VM_SNAPSHOT_NONCOPY = "noncopy";
13181318

1319+
public static final String PARENT_HB_NAME = "parenthbaname";
1320+
public static final String WWNN = "wwnn";
1321+
public static final String WWPN = "wwpn";
1322+
public static final String VHBA_NAME = "vhbaname";
1323+
13191324
/**
13201325
* This enum specifies IO Drivers, each option controls specific policies on I/O.
13211326
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
@@ -1415,4 +1420,4 @@ public static ApiKeyAccess fromBoolean(Boolean value) {
14151420
}
14161421
}
14171422
}
1418-
}
1423+
}

0 commit comments

Comments
 (0)