Skip to content

Commit 2aa69f4

Browse files
committed
<feature>[vm]: add metadata local and nfs storage backend
Resolves: ZSV-11559 Change-Id: Idc34906c7c767f5fdf5213d751b293ec951a9b31
1 parent 1734662 commit 2aa69f4

11 files changed

Lines changed: 1245 additions & 12 deletions

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

Lines changed: 295 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@
3636
import org.zstack.header.message.MessageReply;
3737
import org.zstack.header.message.OverlayMessage;
3838
import org.zstack.header.storage.primary.*;
39+
import org.zstack.header.storage.primary.CleanupVmInstanceMetadataOnPrimaryStorageMsg;
40+
import org.zstack.header.storage.primary.CleanupVmInstanceMetadataOnPrimaryStorageReply;
3941
import org.zstack.header.storage.primary.VolumeSnapshotCapability.VolumeSnapshotArrangementType;
4042
import org.zstack.header.storage.snapshot.*;
4143
import org.zstack.header.vm.*;
44+
import org.zstack.header.vm.metadata.UpdateVmInstanceMetadataOnPrimaryStorageMsg;
45+
import org.zstack.header.vm.metadata.UpdateVmInstanceMetadataOnPrimaryStorageReply;
4246
import org.zstack.header.vo.ResourceVO;
4347
import org.zstack.header.volume.*;
4448
import org.zstack.storage.primary.*;
@@ -65,7 +69,8 @@
6569
import static org.zstack.core.Platform.*;
6670
import static org.zstack.storage.primary.local.LocalStorageUtils.getHostUuidFromInstallUrl;
6771
import static org.zstack.utils.CollectionDSL.*;
68-
import static org.zstack.utils.CollectionUtils.*;
72+
import static org.zstack.utils.CollectionUtils.toMap;
73+
import static org.zstack.utils.CollectionUtils.transformAndRemoveNull;
6974

7075
/**
7176
* Created by frank on 6/30/2015.
@@ -1640,6 +1645,33 @@ public void fail(ErrorCode errorCode) {
16401645
});
16411646
}
16421647

1648+
protected void handle(RebaseVolumeBackingFileOnPrimaryStorageMsg msg) {
1649+
final LocalStorageHypervisorBackend bkd;
1650+
try {
1651+
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid());
1652+
bkd = f.getHypervisorBackend(self);
1653+
} catch (Exception e) {
1654+
RebaseVolumeBackingFileOnPrimaryStorageReply reply = new RebaseVolumeBackingFileOnPrimaryStorageReply();
1655+
reply.setError(operr("failed to resolve host/backend for rebase on local primary storage[uuid:%s], hostUuid[%s]: %s",
1656+
self.getUuid(), msg.getHostUuid(), e.getMessage()));
1657+
bus.reply(msg, reply);
1658+
return;
1659+
}
1660+
bkd.handle(msg, msg.getHostUuid(), new ReturnValueCompletion<RebaseVolumeBackingFileOnPrimaryStorageReply>(msg) {
1661+
@Override
1662+
public void success(RebaseVolumeBackingFileOnPrimaryStorageReply returnValue) {
1663+
bus.reply(msg, returnValue);
1664+
}
1665+
1666+
@Override
1667+
public void fail(ErrorCode errorCode) {
1668+
RebaseVolumeBackingFileOnPrimaryStorageReply reply = new RebaseVolumeBackingFileOnPrimaryStorageReply();
1669+
reply.setError(errorCode);
1670+
bus.reply(msg, reply);
1671+
}
1672+
});
1673+
}
1674+
16431675
private void handle(RemoveHostFromLocalStorageMsg msg) {
16441676
RemoveHostFromLocalStorageReply reply = new RemoveHostFromLocalStorageReply();
16451677
thdf.chainSubmit(new ChainTask(msg) {
@@ -3329,4 +3361,266 @@ public void fail(ErrorCode errorCode) {
33293361
public static class LocalStoragePhysicalCapacityUsage extends PrimaryStorageBase.PhysicalCapacityUsage {
33303362
public long localStorageUsedSize;
33313363
}
3364+
3365+
@Override
3366+
protected void handle(final UpdateVmInstanceMetadataOnPrimaryStorageMsg msg) {
3367+
thdf.chainSubmit(new ChainTask(msg) {
3368+
@Override
3369+
public String getSyncSignature() {
3370+
return String.format("update-metadata-on-ps-%s", self.getUuid());
3371+
}
3372+
3373+
@Override
3374+
public int getSyncLevel() {
3375+
return 10;
3376+
}
3377+
3378+
@Override
3379+
public void run(SyncTaskChain chain) {
3380+
final String hostUuid;
3381+
final LocalStorageHypervisorBackend bkd;
3382+
try {
3383+
hostUuid = getHostUuidByResourceUuid(msg.getRootVolumeUuid());
3384+
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid);
3385+
bkd = f.getHypervisorBackend(self);
3386+
} catch (Exception e) {
3387+
UpdateVmInstanceMetadataOnPrimaryStorageReply reply = new UpdateVmInstanceMetadataOnPrimaryStorageReply();
3388+
reply.setError(operr("failed to resolve host for vm metadata update on local primary storage[uuid:%s], rootVolumeUuid[%s]: %s",
3389+
self.getUuid(), msg.getRootVolumeUuid(), e.getMessage()));
3390+
bus.reply(msg, reply);
3391+
chain.next();
3392+
return;
3393+
}
3394+
bkd.handle(msg, hostUuid, new ReturnValueCompletion<UpdateVmInstanceMetadataOnPrimaryStorageReply>(msg, chain) {
3395+
@Override
3396+
public void success(UpdateVmInstanceMetadataOnPrimaryStorageReply returnValue) {
3397+
bus.reply(msg, returnValue);
3398+
chain.next();
3399+
}
3400+
3401+
@Override
3402+
public void fail(ErrorCode errorCode) {
3403+
UpdateVmInstanceMetadataOnPrimaryStorageReply reply = new UpdateVmInstanceMetadataOnPrimaryStorageReply();
3404+
reply.setError(errorCode);
3405+
bus.reply(msg, reply);
3406+
chain.next();
3407+
}
3408+
});
3409+
}
3410+
3411+
@Override
3412+
public String getName() {
3413+
return String.format("update-metadata-on-ps-%s", self.getUuid());
3414+
}
3415+
});
3416+
}
3417+
3418+
@Override
3419+
protected void handle(final GetVmInstanceMetadataFromPrimaryStorageMsg msg) {
3420+
GetVmInstanceMetadataFromPrimaryStorageReply reply = new GetVmInstanceMetadataFromPrimaryStorageReply();
3421+
3422+
String hostUuid = null;
3423+
if (msg.getHostUuid() != null) {
3424+
hostUuid = msg.getHostUuid();
3425+
}
3426+
3427+
if (hostUuid == null) {
3428+
if (msg.getRootVolumeUuid() == null) {
3429+
reply.setError(operr("cannot determine host for vm metadata get on local primary storage[uuid:%s]," +
3430+
" rootVolumeUuid is null", self.getUuid()));
3431+
bus.reply(msg, reply);
3432+
return;
3433+
}
3434+
try {
3435+
hostUuid = getHostUuidByResourceUuid(msg.getRootVolumeUuid());
3436+
} catch (Exception e) {
3437+
reply.setError(operr("cannot determine host for vm metadata get on local primary storage[uuid:%s], rootVolumeUuid[%s]: %s",
3438+
self.getUuid(), msg.getRootVolumeUuid(), e.getMessage()));
3439+
bus.reply(msg, reply);
3440+
return;
3441+
}
3442+
}
3443+
3444+
final LocalStorageHypervisorBackend bkd;
3445+
try {
3446+
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid);
3447+
bkd = f.getHypervisorBackend(self);
3448+
} catch (Exception e) {
3449+
reply.setError(operr("failed to resolve host/backend for vm metadata get on local primary storage[uuid:%s], hostUuid[%s]: %s",
3450+
self.getUuid(), hostUuid, e.getMessage()));
3451+
bus.reply(msg, reply);
3452+
return;
3453+
}
3454+
bkd.handle(msg, hostUuid, new ReturnValueCompletion<GetVmInstanceMetadataFromPrimaryStorageReply>(msg) {
3455+
@Override
3456+
public void success(GetVmInstanceMetadataFromPrimaryStorageReply returnValue) {
3457+
bus.reply(msg, returnValue);
3458+
}
3459+
3460+
@Override
3461+
public void fail(ErrorCode errorCode) {
3462+
reply.setError(errorCode);
3463+
bus.reply(msg, reply);
3464+
}
3465+
});
3466+
}
3467+
3468+
@Override
3469+
protected void handle(final ScanVmInstanceMetadataFromPrimaryStorageMsg msg) {
3470+
ScanVmInstanceMetadataFromPrimaryStorageReply reply = new ScanVmInstanceMetadataFromPrimaryStorageReply();
3471+
3472+
List<String> allHostUuids = SQL.New(
3473+
"select h.hostUuid from LocalStorageHostRefVO h, HostVO host" +
3474+
" where h.primaryStorageUuid = :psUuid" +
3475+
" and h.hostUuid = host.uuid", String.class)
3476+
.param("psUuid", self.getUuid())
3477+
.list();
3478+
if (allHostUuids.isEmpty()) {
3479+
reply.setError(operr("no host found for local primary storage[uuid:%s]", self.getUuid()));
3480+
bus.reply(msg, reply);
3481+
return;
3482+
}
3483+
3484+
List<String> connectedHostUuids = SQL.New(
3485+
"select h.hostUuid from LocalStorageHostRefVO h, HostVO host" +
3486+
" where h.primaryStorageUuid = :psUuid" +
3487+
" and h.hostUuid = host.uuid" +
3488+
" and host.status = :hstatus", String.class)
3489+
.param("psUuid", self.getUuid())
3490+
.param("hstatus", HostStatus.Connected)
3491+
.list();
3492+
if (connectedHostUuids.isEmpty()) {
3493+
reply.setError(operr("no connected host found for local primary storage[uuid:%s], " +
3494+
"total hosts=%d", self.getUuid(), allHostUuids.size()));
3495+
bus.reply(msg, reply);
3496+
return;
3497+
}
3498+
3499+
// Disconnected hosts cannot be scanned; treat them as failed upfront
3500+
List<String> disconnectedHostUuids = new ArrayList<>(allHostUuids);
3501+
disconnectedHostUuids.removeAll(connectedHostUuids);
3502+
3503+
List<VmMetadataScanEntry> allSummaries = Collections.synchronizedList(new ArrayList<>());
3504+
List<String> failedHosts = Collections.synchronizedList(new ArrayList<>(disconnectedHostUuids));
3505+
if (!disconnectedHostUuids.isEmpty()) {
3506+
logger.warn(String.format("local primary storage[uuid:%s] has %d disconnected hosts that cannot be scanned: %s",
3507+
self.getUuid(), disconnectedHostUuids.size(), disconnectedHostUuids));
3508+
}
3509+
3510+
new While<>(connectedHostUuids).all((hostUuid, com) -> {
3511+
final LocalStorageHypervisorBackend bkd;
3512+
try {
3513+
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid);
3514+
bkd = f.getHypervisorBackend(self);
3515+
} catch (Exception e) {
3516+
failedHosts.add(hostUuid);
3517+
com.addError(operr("failed to prepare vm metadata scan on host[uuid:%s]: %s",
3518+
hostUuid, e.getMessage()));
3519+
com.done();
3520+
return;
3521+
}
3522+
bkd.handle(msg, hostUuid, new ReturnValueCompletion<ScanVmInstanceMetadataFromPrimaryStorageReply>(com) {
3523+
@Override
3524+
public void success(ScanVmInstanceMetadataFromPrimaryStorageReply returnValue) {
3525+
if (returnValue.getVmInstanceMetadata() != null) {
3526+
allSummaries.addAll(returnValue.getVmInstanceMetadata());
3527+
}
3528+
com.done();
3529+
}
3530+
3531+
@Override
3532+
public void fail(ErrorCode errorCode) {
3533+
logger.warn(String.format("failed to scan vm metadata from host[uuid:%s] on local primary storage[uuid:%s]: %s",
3534+
hostUuid, self.getUuid(), errorCode));
3535+
failedHosts.add(hostUuid);
3536+
com.addError(errorCode);
3537+
com.done();
3538+
}
3539+
});
3540+
}).run(new WhileDoneCompletion(msg) {
3541+
@Override
3542+
public void done(ErrorCodeList errorCodeList) {
3543+
if (!errorCodeList.getCauses().isEmpty() && errorCodeList.getCauses().size() == connectedHostUuids.size()) {
3544+
reply.setError(operr("failed to scan vm metadata from all hosts on local primary storage[uuid:%s], causes: %s",
3545+
self.getUuid(), errorCodeList));
3546+
} else {
3547+
reply.setVmInstanceMetadata(new ArrayList<>(allSummaries));
3548+
if (!failedHosts.isEmpty()) {
3549+
logger.warn(String.format("partial scan failure on local primary storage[uuid:%s], " +
3550+
"failedHosts=%s, successHosts=%d/%d", self.getUuid(), failedHosts,
3551+
connectedHostUuids.size() - failedHosts.size(), connectedHostUuids.size()));
3552+
}
3553+
}
3554+
bus.reply(msg, reply);
3555+
}
3556+
});
3557+
}
3558+
3559+
@Override
3560+
protected void handle(final CleanupVmInstanceMetadataOnPrimaryStorageMsg msg) {
3561+
thdf.chainSubmit(new ChainTask(msg) {
3562+
@Override
3563+
public String getSyncSignature() {
3564+
return String.format("update-metadata-on-ps-%s-%s", self.getUuid(), msg.getVmInstanceUuid());
3565+
}
3566+
3567+
@Override
3568+
public int getSyncLevel() {
3569+
return 1;
3570+
}
3571+
3572+
@Override
3573+
public void run(SyncTaskChain chain) {
3574+
CleanupVmInstanceMetadataOnPrimaryStorageReply reply = new CleanupVmInstanceMetadataOnPrimaryStorageReply();
3575+
3576+
String hostUuid = msg.getHostUuid();
3577+
if (hostUuid == null && msg.getRootVolumeUuid() != null) {
3578+
try {
3579+
hostUuid = getHostUuidByResourceUuid(msg.getRootVolumeUuid());
3580+
} catch (Exception e) {
3581+
logger.warn(String.format("failed to get host by rootVolumeUuid[%s]: %s", msg.getRootVolumeUuid(), e.getMessage()));
3582+
}
3583+
}
3584+
3585+
if (hostUuid == null) {
3586+
reply.setError(operr("cannot determine host for vm metadata cleanup on local primary storage[uuid:%s]," +
3587+
" rootVolumeUuid[%s], hostUuid is null", self.getUuid(), msg.getRootVolumeUuid()));
3588+
bus.reply(msg, reply);
3589+
chain.next();
3590+
return;
3591+
}
3592+
3593+
final LocalStorageHypervisorBackend bkd;
3594+
try {
3595+
LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid);
3596+
bkd = f.getHypervisorBackend(self);
3597+
} catch (Exception e) {
3598+
reply.setError(operr("failed to resolve host/backend for vm metadata cleanup on local primary storage[uuid:%s], hostUuid[%s]: %s",
3599+
self.getUuid(), hostUuid, e.getMessage()));
3600+
bus.reply(msg, reply);
3601+
chain.next();
3602+
return;
3603+
}
3604+
bkd.handle(msg, hostUuid, new ReturnValueCompletion<CleanupVmInstanceMetadataOnPrimaryStorageReply>(msg, chain) {
3605+
@Override
3606+
public void success(CleanupVmInstanceMetadataOnPrimaryStorageReply returnValue) {
3607+
bus.reply(msg, returnValue);
3608+
chain.next();
3609+
}
3610+
3611+
@Override
3612+
public void fail(ErrorCode errorCode) {
3613+
reply.setError(errorCode);
3614+
bus.reply(msg, reply);
3615+
chain.next();
3616+
}
3617+
});
3618+
}
3619+
3620+
@Override
3621+
public String getName() {
3622+
return String.format("cleanup-metadata-on-ps-%s-%s", self.getUuid(), msg.getVmInstanceUuid());
3623+
}
3624+
});
3625+
}
33323626
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.zstack.header.image.ImageInventory;
88
import org.zstack.header.storage.primary.*;
99
import org.zstack.header.storage.snapshot.VolumeSnapshotInventory;
10+
import org.zstack.header.vm.metadata.UpdateVmInstanceMetadataOnPrimaryStorageMsg;
11+
import org.zstack.header.vm.metadata.UpdateVmInstanceMetadataOnPrimaryStorageReply;
1012
import org.zstack.header.volume.*;
1113
import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageMsg;
1214
import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageReply;
@@ -121,4 +123,14 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) {
121123
abstract void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<CommitVolumeSnapshotOnPrimaryStorageReply> completion);
122124

123125
abstract void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<PullVolumeSnapshotOnPrimaryStorageReply> completion);
126+
127+
abstract void handle(UpdateVmInstanceMetadataOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<UpdateVmInstanceMetadataOnPrimaryStorageReply> completion);
128+
129+
abstract void handle(GetVmInstanceMetadataFromPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<GetVmInstanceMetadataFromPrimaryStorageReply> completion);
130+
131+
abstract void handle(ScanVmInstanceMetadataFromPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<ScanVmInstanceMetadataFromPrimaryStorageReply> completion);
132+
133+
abstract void handle(CleanupVmInstanceMetadataOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<CleanupVmInstanceMetadataOnPrimaryStorageReply> completion);
134+
135+
abstract void handle(RebaseVolumeBackingFileOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion<RebaseVolumeBackingFileOnPrimaryStorageReply> completion);
124136
}

0 commit comments

Comments
 (0)