3030
3131import com .cloud .utils .EncryptionUtil ;
3232import com .cloud .utils .db .TransactionCallbackWithException ;
33+ import com .google .common .base .Strings ;
3334import com .google .gson .Gson ;
3435import com .google .gson .GsonBuilder ;
36+ import com .google .gson .JsonParseException ;
3537
3638import org .apache .cloudstack .api .command .user .volume .GetUploadParamsForVolumeCmd ;
3739import org .apache .cloudstack .api .response .GetUploadParamsResponse ;
3840import org .apache .cloudstack .engine .subsystem .api .storage .DataObject ;
3941import org .apache .cloudstack .engine .subsystem .api .storage .EndPoint ;
4042import org .apache .cloudstack .storage .command .TemplateOrVolumePostUploadCommand ;
4143import org .apache .cloudstack .utils .imagestore .ImageStoreUtil ;
44+ import org .apache .cloudstack .utils .volume .VirtualMachineDiskInfo ;
4245import org .apache .log4j .Logger ;
4346import org .apache .cloudstack .api .command .user .volume .AttachVolumeCmd ;
4447import org .apache .cloudstack .api .command .user .volume .CreateVolumeCmd ;
112115import com .cloud .hypervisor .HypervisorCapabilitiesVO ;
113116import com .cloud .hypervisor .dao .HypervisorCapabilitiesDao ;
114117import com .cloud .org .Grouping ;
118+ import com .cloud .serializer .GsonHelper ;
115119import com .cloud .service .dao .ServiceOfferingDetailsDao ;
116120import com .cloud .storage .Storage .ImageFormat ;
117121import com .cloud .storage .dao .DiskOfferingDao ;
118122import com .cloud .storage .dao .SnapshotDao ;
119123import com .cloud .storage .dao .VMTemplateDao ;
120124import com .cloud .storage .dao .VolumeDao ;
125+ import com .cloud .storage .dao .VolumeDetailsDao ;
121126import com .cloud .storage .snapshot .SnapshotApiService ;
122127import com .cloud .storage .snapshot .SnapshotManager ;
123128import com .cloud .template .TemplateManager ;
146151import com .cloud .utils .exception .CloudRuntimeException ;
147152import com .cloud .utils .fsm .NoTransitionException ;
148153import com .cloud .utils .fsm .StateMachine2 ;
154+ import com .cloud .vm .UserVmManager ;
149155import com .cloud .vm .UserVmVO ;
150156import com .cloud .vm .VMInstanceVO ;
151157import com .cloud .vm .VirtualMachine ;
@@ -191,6 +197,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
191197 @ Inject
192198 VolumeDao _volsDao ;
193199 @ Inject
200+ VolumeDetailsDao _volDetailDao ;
201+ @ Inject
194202 HostDao _hostDao ;
195203 @ Inject
196204 SnapshotDao _snapshotDao ;
@@ -240,6 +248,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
240248 VmWorkJobDao _workJobDao ;
241249 @ Inject
242250 ClusterDetailsDao _clusterDetailsDao ;
251+ @ Inject
252+ UserVmManager _userVmMgr ;
253+ protected Gson _gson ;
243254
244255 private List <StoragePoolAllocator > _storagePoolAllocators ;
245256
@@ -253,6 +264,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
253264
254265 protected VolumeApiServiceImpl () {
255266 _volStateMachine = Volume .State .getStateMachine ();
267+ _gson = GsonHelper .getGsonLogger ();
256268 }
257269
258270 /*
@@ -1835,6 +1847,26 @@ private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) {
18351847 }
18361848 }
18371849
1850+ public void updateMissingRootDiskController (final VMInstanceVO vm , final String rootVolChainInfo ) {
1851+ if (vm == null || !VirtualMachine .Type .User .equals (vm .getType ()) || Strings .isNullOrEmpty (rootVolChainInfo )) {
1852+ return ;
1853+ }
1854+ String rootDiskController = null ;
1855+ try {
1856+ final VirtualMachineDiskInfo infoInChain = _gson .fromJson (rootVolChainInfo , VirtualMachineDiskInfo .class );
1857+ if (infoInChain != null ) {
1858+ rootDiskController = infoInChain .getControllerFromDeviceBusName ();
1859+ }
1860+ final UserVmVO userVmVo = _userVmDao .findById (vm .getId ());
1861+ if ((rootDiskController != null ) && (!rootDiskController .isEmpty ())) {
1862+ _userVmDao .loadDetails (userVmVo );
1863+ _userVmMgr .persistDeviceBusInfo (userVmVo , rootDiskController );
1864+ }
1865+ } catch (JsonParseException e ) {
1866+ s_logger .debug ("Error parsing chain info json: " + e .getMessage ());
1867+ }
1868+ }
1869+
18381870 @ DB
18391871 @ Override
18401872 @ ActionEvent (eventType = EventTypes .EVENT_VOLUME_MIGRATE , eventDescription = "migrating volume" , async = true )
@@ -1924,6 +1956,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) {
19241956 throw new InvalidParameterValueException ("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter" );
19251957 }
19261958 }
1959+ updateMissingRootDiskController (vm , vol .getChainInfo ());
19271960 }
19281961 }
19291962 }
@@ -2475,6 +2508,7 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
24752508 controllerInfo .put (VmDetailConstants .ROOT_DISK_CONTROLLER , vm .getDetail (VmDetailConstants .ROOT_DISK_CONTROLLER ));
24762509 controllerInfo .put (VmDetailConstants .DATA_DISK_CONTROLLER , vm .getDetail (VmDetailConstants .DATA_DISK_CONTROLLER ));
24772510 cmd .setControllerInfo (controllerInfo );
2511+ s_logger .debug ("Attach volume id:" + volumeToAttach .getId () + " on VM id:" + vm .getId () + " has controller info:" + controllerInfo );
24782512
24792513 try {
24802514 answer = (AttachAnswer )_agentMgr .send (hostId , cmd );
0 commit comments