def attach_root_volume(self, connection_info, instance, datastore, adapter_type=None): """Attach a root volume to the VM instance.""" driver_type = connection_info['driver_volume_type'] LOG.debug("Root volume attach. Driver type: %s", driver_type, instance=instance) if driver_type == constants.DISK_FORMAT_VMDK: vm_ref = vm_util.get_vm_ref(self._session, instance) data = connection_info['data'] # Get the volume ref volume_ref = self._get_volume_ref(data['volume']) # Pick the resource pool on which the instance resides. Move the # volume to the datastore of the instance. res_pool = self._get_res_pool_of_vm(vm_ref) vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore) self.attach_volume(connection_info, instance, adapter_type)
def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref, adapter_type=None, disk_type=None): """Consolidate volume backing VMDK files if needed. The volume's VMDK file attached to an instance can be moved by SDRS if enabled on the cluster. By this the VMDK files can get copied onto another datastore and the copy on this new location will be the latest version of the VMDK file. So at the time of detach, we need to consolidate the current backing VMDK file with the VMDK file in the new location. We need to ensure that the VMDK chain (snapshots) remains intact during the consolidation. SDRS retains the chain when it copies VMDK files over, so for consolidation we relocate the backing with move option as moveAllDiskBackingsAndAllowSharing and then delete the older version of the VMDK file attaching the new version VMDK file. In the case of a volume boot the we need to ensure that the volume is on the datastore of the instance. """ original_device = self._get_vmdk_base_volume_device(volume_ref) original_device_path = original_device.backing.fileName current_device_path = device.backing.fileName if original_device_path == current_device_path: # The volume is not moved from its original location. # No consolidation is required. LOG.debug( "The volume has not been displaced from " "its original location: %s. No consolidation " "needed.", current_device_path) return # The volume has been moved from its original location. # Need to consolidate the VMDK files. LOG.info( "The volume's backing has been relocated to %s. Need to " "consolidate backing disk file.", current_device_path) # Pick the host and resource pool on which the instance resides. # Move the volume to the datastore where the new VMDK file is present. host = self._get_host_of_vm(vm_ref) res_pool = self._get_res_pool_of_host(host) datastore = device.backing.datastore detached = False LOG.debug( "Relocating volume's backing: %(backing)s to resource " "pool: %(rp)s, datastore: %(ds)s, host: %(host)s.", { 'backing': volume_ref, 'rp': res_pool, 'ds': datastore, 'host': host }) try: vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore, host) except oslo_vmw_exceptions.FileNotFoundException: # Volume's vmdk was moved; remove the device so that we can # relocate the volume. LOG.warning("Virtual disk: %s of volume's backing not found.", original_device_path, exc_info=True) LOG.debug("Removing disk device of volume's backing and " "reattempting relocate.") self.detach_disk_from_vm(volume_ref, instance, original_device) detached = True vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore, host) # Volume's backing is relocated now; detach the old vmdk if not done # already. if not detached: try: self.detach_disk_from_vm(volume_ref, instance, original_device, destroy_disk=True) except oslo_vmw_exceptions.FileNotFoundException: LOG.debug( "Original volume backing %s is missing, no need " "to detach it", original_device.backing.fileName) # Attach the current volume to the volume_ref self.attach_disk_to_vm(volume_ref, instance, adapter_type, disk_type, vmdk_path=current_device_path)
def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref, adapter_type=None, disk_type=None): """Consolidate volume backing VMDK files if needed. The volume's VMDK file attached to an instance can be moved by SDRS if enabled on the cluster. By this the VMDK files can get copied onto another datastore and the copy on this new location will be the latest version of the VMDK file. So at the time of detach, we need to consolidate the current backing VMDK file with the VMDK file in the new location. We need to ensure that the VMDK chain (snapshots) remains intact during the consolidation. SDRS retains the chain when it copies VMDK files over, so for consolidation we relocate the backing with move option as moveAllDiskBackingsAndAllowSharing and then delete the older version of the VMDK file attaching the new version VMDK file. In the case of a volume boot the we need to ensure that the volume is on the datastore of the instance. """ original_device = self._get_vmdk_base_volume_device(volume_ref) original_device_path = original_device.backing.fileName current_device_path = device.backing.fileName if original_device_path == current_device_path: # The volume is not moved from its original location. # No consolidation is required. LOG.debug("The volume has not been displaced from " "its original location: %s. No consolidation " "needed.", current_device_path) return # The volume has been moved from its original location. # Need to consolidate the VMDK files. LOG.info("The volume's backing has been relocated to %s. Need to " "consolidate backing disk file.", current_device_path) # Pick the host and resource pool on which the instance resides. # Move the volume to the datastore where the new VMDK file is present. host = self._get_host_of_vm(vm_ref) res_pool = self._get_res_pool_of_host(host) datastore = device.backing.datastore detached = False LOG.debug("Relocating volume's backing: %(backing)s to resource " "pool: %(rp)s, datastore: %(ds)s, host: %(host)s.", {'backing': volume_ref, 'rp': res_pool, 'ds': datastore, 'host': host}) try: vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore, host) except oslo_vmw_exceptions.FileNotFoundException: # Volume's vmdk was moved; remove the device so that we can # relocate the volume. LOG.warning("Virtual disk: %s of volume's backing not found.", original_device_path, exc_info=True) LOG.debug("Removing disk device of volume's backing and " "reattempting relocate.") self.detach_disk_from_vm(volume_ref, instance, original_device) detached = True vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore, host) # Volume's backing is relocated now; detach the old vmdk if not done # already. if not detached: try: self.detach_disk_from_vm(volume_ref, instance, original_device, destroy_disk=True) except oslo_vmw_exceptions.FileNotFoundException: LOG.debug("Original volume backing %s is missing, no need " "to detach it", original_device.backing.fileName) # Attach the current volume to the volume_ref self.attach_disk_to_vm(volume_ref, instance, adapter_type, disk_type, vmdk_path=current_device_path)