/** * Validate whether a disk can be shareable. Disk can be shareable if it is not based on qcow FS, * which means it should not be based on a template image with thin provisioning, it also should * not contain snapshots and it is not bootable. * * @return Indication whether the disk can be shared or not. */ protected boolean validateShareableDisk() { if (DiskStorageType.LUN == _oldDisk.getDiskStorageType()) { return true; } boolean isDiskUpdatedToShareable = getParameters().getDiskInfo().isShareable(); boolean isDiskShareable = _oldDisk.isShareable(); // Check if VM is not during snapshot. if (getSnapshotDao().exists(getVmId(), SnapshotStatus.IN_PREVIEW)) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_IN_PREVIEW); return false; } // If user want to update the disk to be shareable then update the vm snapshot id to be null. if (!isDiskShareable && isDiskUpdatedToShareable) { List<DiskImage> diskImageList = getDiskImageDao().getAllSnapshotsForImageGroup(_oldDisk.getId()); // If disk image list is more then one then we assume that it has a snapshot, since one image // is the active // disk and all the other images are the snapshots. if ((diskImageList.size() > 1) || !Guid.Empty.equals(((DiskImage) _oldDisk).getit_guid())) { addCanDoActionMessage(VdcBllMessages.SHAREABLE_DISK_IS_NOT_SUPPORTED_FOR_DISK); return false; } if (!isVersionSupportedForShareable( _oldDisk, getStoragePoolDAO() .get(getVm().getstorage_pool_id()) .getcompatibility_version() .getValue())) { addCanDoActionMessage(VdcBllMessages.ACTION_NOT_SUPPORTED_FOR_CLUSTER_POOL_LEVEL); return false; } DiskImage diskImage = (DiskImage) getParameters().getDiskInfo(); if (!isVolumeFormatSupportedForShareable(diskImage.getvolume_format())) { addCanDoActionMessage(VdcBllMessages.SHAREABLE_DISK_IS_NOT_SUPPORTED_BY_VOLUME_FORMAT); return false; } diskImage.setvm_snapshot_id(null); } else if (isDiskShareable && !isDiskUpdatedToShareable) { if (getVmDAO().getVmsListForDisk(_oldDisk.getId()).size() > 1) { addCanDoActionMessage(VdcBllMessages.DISK_IS_ALREADY_SHARED_BETWEEN_VMS); return false; } // If disk is not floating, then update its vm snapshot id to the active VM snapshot. ((DiskImage) _oldDisk) .setvm_snapshot_id( DbFacade.getInstance() .getSnapshotDao() .getId(getVmId(), SnapshotType.ACTIVE) .getValue()); } return true; }
@Override protected boolean canDoAction() { boolean retValue = isVmExist(); if (retValue) { if (!isDiskExist(_oldDisk)) { return false; } List<VM> listVms = getVmDAO().getForDisk(_oldDisk.getId()).get(Boolean.TRUE); buidSharedLockMap(listVms); buidExclusiveLockMap(listVms); acquireLockInternal(); // Check if all VMs are in status down. if (listVms != null && !listVms.isEmpty()) { for (VM vm : listVms) { if (vm.getstatus() != VMStatus.Down) { addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_IS_NOT_DOWN); return false; } } } retValue = checkCanPerformRegularUpdate(); } return retValue; }
private boolean checkCanPerformRegularUpdate() { boolean retValue = true; if (_oldDisk.getDiskInterface() != getParameters().getDiskInfo().getDiskInterface()) { List<VmNetworkInterface> allVmInterfaces = DbFacade.getInstance().getVmNetworkInterfaceDao().getAllForVm(getVmId()); List<Disk> allVmDisks = getDiskDao().getAllForVm(getVmId()); allVmDisks.removeAll( LinqUtils.filter( allVmDisks, new Predicate<Disk>() { @Override public boolean eval(Disk o) { return o.getId().equals(_oldDisk.getId()); } })); allVmDisks.add(getParameters().getDiskInfo()); if (!checkPciAndIdeLimit( getVm().getnum_of_monitors(), allVmInterfaces, allVmDisks, getReturnValue().getCanDoActionMessages())) { retValue = false; } } // Validate update boot disk. if (retValue && getParameters().getDiskInfo().isBoot()) { VmHandler.updateDisksFromDb(getVm()); for (Disk disk : getVm().getDiskMap().values()) { if (disk.isBoot() && !disk.getId().equals(_oldDisk.getId())) { retValue = false; addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_DISK_BOOT_IN_USE); getReturnValue() .getCanDoActionMessages() .add(String.format("$DiskName %1$s", disk.getDiskAlias())); break; } } } // Set disk alias name in the disk retrieved from the parameters. ImagesHandler.setDiskAlias(getParameters().getDiskInfo(), getVm()); return retValue && validateShareableDisk(); }
@Override public List<PermissionSubject> getPermissionCheckSubjects() { if (listPermissionSubjects == null) { listPermissionSubjects = new ArrayList<PermissionSubject>(); Guid diskId = _oldDisk == null ? null : _oldDisk.getId(); listPermissionSubjects.add( new PermissionSubject(diskId, VdcObjectType.Disk, ActionGroup.EDIT_DISK_PROPERTIES)); } return listPermissionSubjects; }
/** * Synchronize the VM's Disks with the images from the snapshot:<br> * * <ul> * <li>Existing disks are updated. * <li>Disks that don't exist anymore get re-added. * <ul> * <li>If the image is still in the DB, the disk is linked to it. * <li>If the image is not in the DB anymore, the disk will be marked as "broken" * </ul> * </ul> * * @param vmId The VM ID is needed to re-add disks. * @param snapshotId The snapshot ID is used to find only the VM disks at the time. * @param disksFromSnapshot The disks that existed in the snapshot. */ protected void synchronizeDisksFromSnapshot( Guid vmId, Guid snapshotId, Guid activeSnapshotId, List<DiskImage> disksFromSnapshot) { List<Guid> diskIdsFromSnapshot = new ArrayList<Guid>(); // Sync disks that exist or existed in the snapshot. for (DiskImage diskImage : disksFromSnapshot) { diskIdsFromSnapshot.add(diskImage.getimage_group_id()); Disk disk = diskImage.getDisk(); if (getDiskDao().exists(disk.getId())) { getDiskDao().update(disk); } else { // If can't find the image, insert it as illegal so that it can't be used and make the // device unplugged. if (getDiskImageDao().getSnapshotById(diskImage.getId()) == null) { diskImage.setimageStatus(ImageStatus.ILLEGAL); diskImage.setvm_snapshot_id(activeSnapshotId); ImagesHandler.addImage( diskImage, true, new image_storage_domain_map(diskImage.getId(), diskImage.getstorage_ids().get(0))); } ImagesHandler.addDiskToVm(disk, vmId); } } // Remove all disks that didn't exist in the snapshot. for (VmDevice vmDevice : getVmDeviceDao() .getVmDeviceByVmIdTypeAndDevice( vmId, VmDeviceType.DISK.getName(), VmDeviceType.DISK.getName())) { if (!diskIdsFromSnapshot.contains(vmDevice.getDeviceId())) { getDiskDao().remove(vmDevice.getDeviceId()); getVmDeviceDao().remove(vmDevice.getId()); } } }
@Override protected <T> boolean matchEntity( org.ovirt.engine.core.common.businessentities.Disk entity, T id) { return id != null && (id.equals(entity.getId())); }
@Override public VdcActionParametersBase getParameters( Disk incoming, org.ovirt.engine.core.common.businessentities.Disk entity) { return new UpdateVmDiskParameters(parentId, entity.getId(), map(incoming, entity)); }
@Override public String toString() { return String.format("%s, volumeId = %s", super.toString(), disk.getId()); }