Skip to content

Commit f7c9a4f

Browse files
committed
[VM]exception happens when query vminstance after delete the vm from LS when host is deleted #1660
https://github.com/zxwing/premium/issues/1660
1 parent aa662c3 commit f7c9a4f

File tree

3 files changed

+124
-33
lines changed

3 files changed

+124
-33
lines changed

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java

+37-33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.zstack.core.cloudbus.CloudBusCallBack;
77
import org.zstack.core.cloudbus.CloudBusListCallBack;
88
import org.zstack.core.componentloader.PluginRegistry;
9+
import org.zstack.core.db.Q;
910
import org.zstack.core.db.SimpleQuery;
1011
import org.zstack.core.db.SimpleQuery.Op;
1112
import org.zstack.core.db.UpdateQuery;
@@ -36,10 +37,7 @@
3637
import org.zstack.header.storage.snapshot.VolumeSnapshotInventory;
3738
import org.zstack.header.storage.snapshot.VolumeSnapshotVO;
3839
import org.zstack.header.storage.snapshot.VolumeSnapshotVO_;
39-
import org.zstack.header.volume.VolumeConstant;
40-
import org.zstack.header.volume.VolumeInventory;
41-
import org.zstack.header.volume.VolumeVO;
42-
import org.zstack.header.volume.VolumeVO_;
40+
import org.zstack.header.volume.*;
4341
import org.zstack.storage.primary.PrimaryStorageBase;
4442
import org.zstack.storage.primary.PrimaryStorageCapacityUpdater;
4543
import org.zstack.storage.primary.PrimaryStoragePhysicalCapacityManager;
@@ -1057,36 +1055,32 @@ public void fail(ErrorCode errorCode) {
10571055
});
10581056
}
10591057

1060-
@Transactional
10611058
private void handle(RemoveHostFromLocalStorageMsg msg) {
1062-
String sqlLocalStorageHostRefVO = "select ref" +
1063-
" from LocalStorageHostRefVO ref" +
1064-
" where hostUuid = :hostUuid" +
1065-
" and primaryStorageUuid = :primaryStorageUuid";
1066-
TypedQuery<LocalStorageHostRefVO> query = dbf.getEntityManager().
1067-
createQuery(sqlLocalStorageHostRefVO, LocalStorageHostRefVO.class);
1068-
query.setParameter("hostUuid", msg.getHostUuid());
1069-
query.setParameter("primaryStorageUuid", msg.getPrimaryStorageUuid());
1070-
LocalStorageHostRefVO ref = query.getSingleResult();
1071-
if (ref == null) {
1072-
return;
1059+
LocalStorageHostRefVO ref = Q.New(LocalStorageHostRefVO.class)
1060+
.eq(LocalStorageHostRefVO_.hostUuid, msg.getHostUuid())
1061+
.eq(LocalStorageHostRefVO_.primaryStorageUuid, self.getUuid())
1062+
.find();
1063+
1064+
if (ref != null) {
1065+
// on remove, subtract the capacity from every capacity
1066+
decreaseCapacity(ref.getTotalCapacity(),
1067+
ref.getAvailableCapacity(),
1068+
ref.getTotalPhysicalCapacity(),
1069+
ref.getAvailablePhysicalCapacity(),
1070+
ref.getSystemUsedCapacity());
1071+
1072+
dbf.remove(ref);
10731073
}
1074-
dbf.remove(ref);
10751074

10761075
deleteResourceRef(msg.getHostUuid());
10771076

1078-
// on remove, subtract the capacity from every capacity
1079-
decreaseCapacity(ref.getTotalCapacity(),
1080-
ref.getAvailableCapacity(),
1081-
ref.getTotalPhysicalCapacity(),
1082-
ref.getAvailablePhysicalCapacity(),
1083-
ref.getSystemUsedCapacity());
10841077
bus.reply(msg, new RemoveHostFromLocalStorageReply());
10851078
}
10861079

10871080
void deleteResourceRef(String hostUuid) {
10881081
SimpleQuery<LocalStorageResourceRefVO> rq = dbf.createQuery(LocalStorageResourceRefVO.class);
10891082
rq.add(LocalStorageResourceRefVO_.hostUuid, Op.EQ, hostUuid);
1083+
rq.add(LocalStorageResourceRefVO_.primaryStorageUuid, Op.EQ, self.getUuid());
10901084
List<LocalStorageResourceRefVO> refs = rq.list();
10911085
if (refs.isEmpty()) {
10921086
return;
@@ -1111,6 +1105,20 @@ void deleteResourceRef(String hostUuid) {
11111105

11121106
// delete volumes
11131107
if (!volumes.isEmpty()) {
1108+
new Runnable() {
1109+
@Override
1110+
@Transactional
1111+
public void run() {
1112+
// delete VMs on the host
1113+
String sql = "delete from VmInstanceVO vm where vm.rootVolumeUuid in (select vol.uuid from VolumeVO vol" +
1114+
" where vol.uuid in (:volUuids) and vol.type = :volType)";
1115+
Query q = dbf.getEntityManager().createQuery(sql);
1116+
q.setParameter("volType", VolumeType.Root);
1117+
q.setParameter("volUuids", volumes);
1118+
q.executeUpdate();
1119+
}
1120+
}.run();
1121+
11141122
uq = UpdateQuery.New();
11151123
uq.entity(VolumeVO.class);
11161124
uq.condAnd(VolumeVO_.uuid, Op.IN, volumes);
@@ -1136,19 +1144,15 @@ protected void handle(final InitPrimaryStorageOnHostConnectedMsg msg) {
11361144
final InitPrimaryStorageOnHostConnectedReply reply = new InitPrimaryStorageOnHostConnectedReply();
11371145
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid());
11381146
final LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self);
1147+
11391148
bkd.handle(msg, new ReturnValueCompletion<PhysicalCapacityUsage>(msg) {
11401149
@Override
1141-
@Transactional
11421150
public void success(PhysicalCapacityUsage c) {
1143-
String sqlLocalStorageHostRefVO = "select ref" +
1144-
" from LocalStorageHostRefVO ref" +
1145-
" where hostUuid = :hostUuid" +
1146-
" and primaryStorageUuid = :primaryStorageUuid";
1147-
TypedQuery<LocalStorageHostRefVO> query = dbf.getEntityManager().
1148-
createQuery(sqlLocalStorageHostRefVO, LocalStorageHostRefVO.class);
1149-
query.setParameter("hostUuid", msg.getHostUuid());
1150-
query.setParameter("primaryStorageUuid", msg.getPrimaryStorageUuid());
1151-
List<LocalStorageHostRefVO> refs = query.getResultList();
1151+
List<LocalStorageHostRefVO> refs = Q.New(LocalStorageHostRefVO.class)
1152+
.eq(LocalStorageHostRefVO_.hostUuid, msg.getHostUuid())
1153+
.eq(LocalStorageHostRefVO_.primaryStorageUuid, self.getUuid())
1154+
.list();
1155+
11521156
LocalStorageHostRefVO ref;
11531157
if (refs == null || refs.isEmpty()) {
11541158
ref = new LocalStorageHostRefVO();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package org.zstack.test.storage.primary.local;
2+
3+
import junit.framework.Assert;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
import org.zstack.core.cloudbus.CloudBus;
7+
import org.zstack.core.componentloader.ComponentLoader;
8+
import org.zstack.core.db.DatabaseFacade;
9+
import org.zstack.core.db.SimpleQuery;
10+
import org.zstack.core.db.SimpleQuery.Op;
11+
import org.zstack.header.host.HostInventory;
12+
import org.zstack.header.identity.SessionInventory;
13+
import org.zstack.header.storage.primary.PrimaryStorageInventory;
14+
import org.zstack.header.vm.VmInstanceConstant.Capability;
15+
import org.zstack.header.vm.VmInstanceInventory;
16+
import org.zstack.header.vm.VmInstanceVO;
17+
import org.zstack.header.volume.VolumeConstant;
18+
import org.zstack.header.volume.VolumeVO;
19+
import org.zstack.storage.primary.local.*;
20+
import org.zstack.storage.primary.local.LocalStorageSimulatorConfig.Capacity;
21+
import org.zstack.test.Api;
22+
import org.zstack.test.ApiSenderException;
23+
import org.zstack.test.DBUtil;
24+
import org.zstack.test.WebBeanConstructor;
25+
import org.zstack.test.deployer.Deployer;
26+
import org.zstack.utils.data.SizeUnit;
27+
28+
import java.util.Map;
29+
30+
/**
31+
* 1. use local storage
32+
* 2. create a vm
33+
* <p>
34+
* confirm all local storage related commands, VOs are set
35+
* <p>
36+
* 3. attach another local storage to the cluster
37+
* <p>
38+
* confirm able to attach
39+
*/
40+
public class TestLocalStorage56 {
41+
Deployer deployer;
42+
Api api;
43+
ComponentLoader loader;
44+
CloudBus bus;
45+
DatabaseFacade dbf;
46+
SessionInventory session;
47+
LocalStorageSimulatorConfig config;
48+
long totalSize = SizeUnit.GIGABYTE.toByte(100);
49+
50+
@Before
51+
public void setUp() throws Exception {
52+
DBUtil.reDeployDB();
53+
WebBeanConstructor con = new WebBeanConstructor();
54+
deployer = new Deployer("deployerXml/localStorage/TestLocalStorage1.xml", con);
55+
deployer.addSpringConfig("KVMRelated.xml");
56+
deployer.addSpringConfig("localStorageSimulator.xml");
57+
deployer.addSpringConfig("localStorage.xml");
58+
deployer.load();
59+
60+
loader = deployer.getComponentLoader();
61+
bus = loader.getComponent(CloudBus.class);
62+
dbf = loader.getComponent(DatabaseFacade.class);
63+
config = loader.getComponent(LocalStorageSimulatorConfig.class);
64+
65+
Capacity c = new Capacity();
66+
c.total = totalSize;
67+
c.avail = totalSize;
68+
69+
config.capacityMap.put("host1", c);
70+
config.capacityMap.put("host4", c);
71+
72+
deployer.build();
73+
api = deployer.getApi();
74+
session = api.loginAsAdmin();
75+
}
76+
77+
@Test
78+
public void test() throws ApiSenderException {
79+
VmInstanceInventory vm = deployer.vms.get("TestVm");
80+
HostInventory host = deployer.hosts.get("host1");
81+
82+
api.deleteHost(host.getUuid());
83+
Assert.assertFalse(dbf.isExist(vm.getUuid(), VmInstanceVO.class));
84+
Assert.assertFalse(dbf.isExist(vm.getRootVolumeUuid(), VolumeVO.class));
85+
}
86+
}

test/src/test/resources/unitTestSuiteXml/localStorage.xml

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<TestCase class="org.zstack.test.storage.primary.local.TestLocalStorage53"/>
6464
<TestCase class="org.zstack.test.storage.primary.local.TestLocalStorage54"/>
6565
<TestCase class="org.zstack.test.storage.primary.local.TestLocalStorage55"/>
66+
<TestCase class="org.zstack.test.storage.primary.local.TestLocalStorage56"/>
6667
<TestCase class="org.zstack.test.storage.primary.local.TestQueryLocalStorage"/>
6768
<TestCase class="org.zstack.test.storage.primary.local.TestLocalStorageCreateDataVolume"/>
6869
</UnitTestSuiteConfig>

0 commit comments

Comments
 (0)