|
51 | 51 |
|
52 | 52 | import org.apache.cloudstack.storage.to.TemplateObjectTO; |
53 | 53 | import org.apache.cloudstack.storage.to.VolumeObjectTO; |
| 54 | +import org.apache.commons.collections.CollectionUtils; |
54 | 55 | import org.apache.commons.collections.MapUtils; |
55 | 56 | import org.apache.commons.io.FileUtils; |
| 57 | +import org.apache.commons.lang3.BooleanUtils; |
56 | 58 | import org.apache.log4j.Logger; |
57 | 59 | import org.apache.xmlrpc.XmlRpcException; |
58 | 60 | import org.joda.time.Duration; |
@@ -173,7 +175,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe |
173 | 175 | * used to describe what type of resource a storage device is of |
174 | 176 | */ |
175 | 177 | public enum SRType { |
176 | | - EXT, FILE, ISCSI, ISO, LVM, LVMOHBA, LVMOISCSI, |
| 178 | + EXT, ISO, LVM, LVMOHBA, LVMOISCSI, |
177 | 179 | /** |
178 | 180 | * used for resigning metadata (like SR UUID and VDI UUID when a |
179 | 181 | * particular storage manager is installed on a XenServer host (for back-end snapshots to work)) |
@@ -756,11 +758,6 @@ public HashMap<String, String> clusterVMMetaDataSync(final Connection conn) { |
756 | 758 | final HashMap<String, String> vmMetaDatum = new HashMap<String, String>(); |
757 | 759 | try { |
758 | 760 | final Map<VM, VM.Record> vm_map = VM.getAllRecords(conn); // USE |
759 | | - // THIS TO |
760 | | - // GET ALL |
761 | | - // VMS |
762 | | - // FROM A |
763 | | - // CLUSTER |
764 | 761 | if (vm_map != null) { |
765 | 762 | for (final VM.Record record : vm_map.values()) { |
766 | 763 | if (record.isControlDomain || record.isASnapshot || record.isATemplate) { |
@@ -2645,76 +2642,6 @@ public String getLabel() { |
2645 | 2642 | return result; |
2646 | 2643 | } |
2647 | 2644 |
|
2648 | | - protected SR getLocalEXTSR(final Connection conn) { |
2649 | | - try { |
2650 | | - final Map<SR, SR.Record> map = SR.getAllRecords(conn); |
2651 | | - if (map != null && !map.isEmpty()) { |
2652 | | - for (final Map.Entry<SR, SR.Record> entry : map.entrySet()) { |
2653 | | - final SR.Record srRec = entry.getValue(); |
2654 | | - if (SRType.FILE.equals(srRec.type) || SRType.EXT.equals(srRec.type)) { |
2655 | | - final Set<PBD> pbds = srRec.PBDs; |
2656 | | - if (pbds == null) { |
2657 | | - continue; |
2658 | | - } |
2659 | | - for (final PBD pbd : pbds) { |
2660 | | - final Host host = pbd.getHost(conn); |
2661 | | - if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) { |
2662 | | - if (!pbd.getCurrentlyAttached(conn)) { |
2663 | | - pbd.plug(conn); |
2664 | | - } |
2665 | | - final SR sr = entry.getKey(); |
2666 | | - sr.scan(conn); |
2667 | | - return sr; |
2668 | | - } |
2669 | | - } |
2670 | | - } |
2671 | | - } |
2672 | | - } |
2673 | | - } catch (final XenAPIException e) { |
2674 | | - final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.toString(); |
2675 | | - s_logger.warn(msg); |
2676 | | - } catch (final XmlRpcException e) { |
2677 | | - final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.getCause(); |
2678 | | - s_logger.warn(msg); |
2679 | | - } |
2680 | | - return null; |
2681 | | - } |
2682 | | - |
2683 | | - protected SR getLocalLVMSR(final Connection conn) { |
2684 | | - try { |
2685 | | - final Map<SR, SR.Record> map = SR.getAllRecords(conn); |
2686 | | - if (map != null && !map.isEmpty()) { |
2687 | | - for (final Map.Entry<SR, SR.Record> entry : map.entrySet()) { |
2688 | | - final SR.Record srRec = entry.getValue(); |
2689 | | - if (SRType.LVM.equals(srRec.type)) { |
2690 | | - final Set<PBD> pbds = srRec.PBDs; |
2691 | | - if (pbds == null) { |
2692 | | - continue; |
2693 | | - } |
2694 | | - for (final PBD pbd : pbds) { |
2695 | | - final Host host = pbd.getHost(conn); |
2696 | | - if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) { |
2697 | | - if (!pbd.getCurrentlyAttached(conn)) { |
2698 | | - pbd.plug(conn); |
2699 | | - } |
2700 | | - final SR sr = entry.getKey(); |
2701 | | - sr.scan(conn); |
2702 | | - return sr; |
2703 | | - } |
2704 | | - } |
2705 | | - } |
2706 | | - } |
2707 | | - } |
2708 | | - } catch (final XenAPIException e) { |
2709 | | - final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.toString(); |
2710 | | - s_logger.warn(msg); |
2711 | | - } catch (final XmlRpcException e) { |
2712 | | - final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.getCause(); |
2713 | | - s_logger.warn(msg); |
2714 | | - } |
2715 | | - return null; |
2716 | | - } |
2717 | | - |
2718 | 2645 | public String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) { |
2719 | 2646 | String vmName = ""; |
2720 | 2647 | try { |
@@ -3670,75 +3597,144 @@ public StartupCommand[] initialize() throws IllegalArgumentException { |
3670 | 3597 | } catch (final Throwable e) { |
3671 | 3598 | s_logger.warn("Check for master failed, failing the FULL Cluster sync command"); |
3672 | 3599 | } |
3673 | | - final StartupStorageCommand sscmd = initializeLocalSR(conn); |
3674 | | - if (sscmd != null) { |
3675 | | - return new StartupCommand[] {cmd, sscmd}; |
| 3600 | + List<StartupStorageCommand> startUpLocalStorageCommands = null; |
| 3601 | + try { |
| 3602 | + startUpLocalStorageCommands = initializeLocalSrs(conn); |
| 3603 | + } catch (XenAPIException | XmlRpcException e) { |
| 3604 | + s_logger.warn("Could not initialize local SRs on host: " + _host.getUuid(), e); |
| 3605 | + } |
| 3606 | + if (CollectionUtils.isEmpty(startUpLocalStorageCommands)) { |
| 3607 | + return new StartupCommand[] {cmd}; |
3676 | 3608 | } |
3677 | | - return new StartupCommand[] {cmd}; |
| 3609 | + return createStartupCommandsArray(cmd, startUpLocalStorageCommands); |
3678 | 3610 | } |
3679 | 3611 |
|
3680 | | - protected StartupStorageCommand initializeLocalSR(final Connection conn) { |
3681 | | - final SR lvmsr = getLocalLVMSR(conn); |
3682 | | - if (lvmsr != null) { |
3683 | | - try { |
3684 | | - _host.setLocalSRuuid(lvmsr.getUuid(conn)); |
3685 | | - |
3686 | | - final String lvmuuid = lvmsr.getUuid(conn); |
3687 | | - final long cap = lvmsr.getPhysicalSize(conn); |
3688 | | - if (cap > 0) { |
3689 | | - final long avail = cap - lvmsr.getPhysicalUtilisation(conn); |
3690 | | - lvmsr.setNameLabel(conn, lvmuuid); |
3691 | | - final String name = "Cloud Stack Local LVM Storage Pool for " + _host.getUuid(); |
3692 | | - lvmsr.setNameDescription(conn, name); |
3693 | | - final Host host = Host.getByUuid(conn, _host.getUuid()); |
3694 | | - final String address = host.getAddress(conn); |
3695 | | - final StoragePoolInfo pInfo = new StoragePoolInfo(lvmuuid, address, SRType.LVM.toString(), SRType.LVM.toString(), StoragePoolType.LVM, cap, avail); |
3696 | | - final StartupStorageCommand cmd = new StartupStorageCommand(); |
3697 | | - cmd.setPoolInfo(pInfo); |
3698 | | - cmd.setGuid(_host.getUuid()); |
3699 | | - cmd.setDataCenter(Long.toString(_dcId)); |
3700 | | - cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); |
3701 | | - return cmd; |
| 3612 | + /** |
| 3613 | + * We simply create an array and add the {@link StartupRoutingCommand} as the first element of the array. Then, we add all elements from startUpLocalStorageCommands |
| 3614 | + */ |
| 3615 | + private StartupCommand[] createStartupCommandsArray(StartupRoutingCommand startupRoutingCommand, List<StartupStorageCommand> startUpLocalStorageCommands) { |
| 3616 | + StartupCommand[] startupCommands = new StartupCommand[startUpLocalStorageCommands.size() + 1]; |
| 3617 | + startupCommands[0] = startupRoutingCommand; |
| 3618 | + for (int i = 1; i < startupCommands.length; i++) { |
| 3619 | + startupCommands[i] = startUpLocalStorageCommands.get(i - 1); |
| 3620 | + } |
| 3621 | + return startupCommands; |
| 3622 | + } |
| 3623 | + |
| 3624 | + /** |
| 3625 | + * This method will return a list of all local SRs. |
| 3626 | + * An SR is considered local if it meets all of the following criteria: |
| 3627 | + * <ul> |
| 3628 | + * <li> {@link Record#shared} is equal to false |
| 3629 | + * <li> The PBDs of the SR ({@link Record#PBDs}) are connected to host {@link #_host} |
| 3630 | + * <li> SR type is equal to the {@link SRType} sent as parameter |
| 3631 | + * </ul> |
| 3632 | + */ |
| 3633 | + protected List<SR> getAllLocalSrForType(Connection conn, SRType srType) throws XenAPIException, XmlRpcException { |
| 3634 | + List<SR> localSrs = new ArrayList<>(); |
| 3635 | + Map<SR, SR.Record> allSrRecords = SR.getAllRecords(conn); |
| 3636 | + if (MapUtils.isEmpty(allSrRecords)) { |
| 3637 | + return localSrs; |
| 3638 | + } |
| 3639 | + for (Map.Entry<SR, SR.Record> entry : allSrRecords.entrySet()) { |
| 3640 | + SR.Record srRec = entry.getValue(); |
| 3641 | + if (!srType.equals(srRec.type)) { |
| 3642 | + continue; |
| 3643 | + } |
| 3644 | + if (BooleanUtils.toBoolean(srRec.shared)) { |
| 3645 | + continue; |
| 3646 | + } |
| 3647 | + Set<PBD> pbds = srRec.PBDs; |
| 3648 | + if (CollectionUtils.isEmpty(pbds)) { |
| 3649 | + continue; |
| 3650 | + } |
| 3651 | + for (PBD pbd : pbds) { |
| 3652 | + Host host = pbd.getHost(conn); |
| 3653 | + if (!isRefNull(host) && org.apache.commons.lang3.StringUtils.equals(host.getUuid(conn), _host.getUuid())) { |
| 3654 | + if (!pbd.getCurrentlyAttached(conn)) { |
| 3655 | + s_logger.debug(String.format("PBD [%s] of local SR [%s] was unplugged, pluggin it now", pbd.getUuid(conn), srRec.uuid)); |
| 3656 | + pbd.plug(conn); |
| 3657 | + } |
| 3658 | + s_logger.debug("Scanning local SR: " + srRec.uuid); |
| 3659 | + SR sr = entry.getKey(); |
| 3660 | + sr.scan(conn); |
| 3661 | + localSrs.add(sr); |
3702 | 3662 | } |
3703 | | - } catch (final XenAPIException e) { |
3704 | | - final String msg = "build local LVM info err in host:" + _host.getUuid() + e.toString(); |
3705 | | - s_logger.warn(msg); |
3706 | | - } catch (final XmlRpcException e) { |
3707 | | - final String msg = "build local LVM info err in host:" + _host.getUuid() + e.getMessage(); |
3708 | | - s_logger.warn(msg); |
3709 | 3663 | } |
3710 | 3664 | } |
| 3665 | + s_logger.debug(String.format("Found %d local storage of type [%s] for host [%s]", localSrs.size(), srType.toString(), _host.getUuid())); |
| 3666 | + return localSrs; |
| 3667 | + } |
3711 | 3668 |
|
3712 | | - final SR extsr = getLocalEXTSR(conn); |
3713 | | - if (extsr != null) { |
3714 | | - try { |
3715 | | - final String extuuid = extsr.getUuid(conn); |
3716 | | - _host.setLocalSRuuid(extuuid); |
3717 | | - final long cap = extsr.getPhysicalSize(conn); |
3718 | | - if (cap > 0) { |
3719 | | - final long avail = cap - extsr.getPhysicalUtilisation(conn); |
3720 | | - extsr.setNameLabel(conn, extuuid); |
3721 | | - final String name = "Cloud Stack Local EXT Storage Pool for " + _host.getUuid(); |
3722 | | - extsr.setNameDescription(conn, name); |
3723 | | - final Host host = Host.getByUuid(conn, _host.getUuid()); |
3724 | | - final String address = host.getAddress(conn); |
3725 | | - final StoragePoolInfo pInfo = new StoragePoolInfo(extuuid, address, SRType.EXT.toString(), SRType.EXT.toString(), StoragePoolType.EXT, cap, avail); |
3726 | | - final StartupStorageCommand cmd = new StartupStorageCommand(); |
3727 | | - cmd.setPoolInfo(pInfo); |
3728 | | - cmd.setGuid(_host.getUuid()); |
3729 | | - cmd.setDataCenter(Long.toString(_dcId)); |
3730 | | - cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); |
3731 | | - return cmd; |
3732 | | - } |
3733 | | - } catch (final XenAPIException e) { |
3734 | | - final String msg = "build local EXT info err in host:" + _host.getUuid() + e.toString(); |
3735 | | - s_logger.warn(msg); |
3736 | | - } catch (final XmlRpcException e) { |
3737 | | - final String msg = "build local EXT info err in host:" + _host.getUuid() + e.getMessage(); |
3738 | | - s_logger.warn(msg); |
| 3669 | + /** |
| 3670 | + * This method will prepare Local SRs to be used by Apache CloudStack. |
| 3671 | + */ |
| 3672 | + protected List<StartupStorageCommand> initializeLocalSrs(Connection conn) throws XenAPIException, XmlRpcException { |
| 3673 | + List<StartupStorageCommand> localStorageStartupCommands = new ArrayList<>(); |
| 3674 | + List<SR> allLocalSrs = getAllLocalSrs(conn); |
| 3675 | + |
| 3676 | + for (SR sr : allLocalSrs) { |
| 3677 | + long totalCapacity = sr.getPhysicalSize(conn); |
| 3678 | + if (totalCapacity > 0) { |
| 3679 | + StartupStorageCommand cmd = createStartUpStorageCommand(conn, sr); |
| 3680 | + localStorageStartupCommands.add(cmd); |
3739 | 3681 | } |
3740 | 3682 | } |
3741 | | - return null; |
| 3683 | + return localStorageStartupCommands; |
| 3684 | + } |
| 3685 | + |
| 3686 | + /** |
| 3687 | + * This method will retrieve all Local SRs according to {@link #getAllLocalSrForType(Connection, SRType)}. |
| 3688 | + * The types used are {@link SRType#LVM} and {@link SRType#EXT}. |
| 3689 | + * |
| 3690 | + */ |
| 3691 | + protected List<SR> getAllLocalSrs(Connection conn) throws XenAPIException, XmlRpcException { |
| 3692 | + List<SR> allLocalSrLvmType = getAllLocalSrForType(conn, SRType.LVM); |
| 3693 | + List<SR> allLocalSrExtType = getAllLocalSrForType(conn, SRType.EXT); |
| 3694 | + List<SR> allLocalSrs = new ArrayList<>(allLocalSrLvmType); |
| 3695 | + allLocalSrs.addAll(allLocalSrExtType); |
| 3696 | + return allLocalSrs; |
| 3697 | + } |
| 3698 | + |
| 3699 | + /** |
| 3700 | + * This method creates the StartUp storage command for the local SR. |
| 3701 | + * We will configure 'name-label' and 'description' using {@link #configureStorageNameAndDescription(Connection, SR)}. |
| 3702 | + * Then, we will create the POJO {@link StoragePoolInfo} with SR's information using method {@link #createStoragePoolInfo(Connection, SR)}. |
| 3703 | + */ |
| 3704 | + protected StartupStorageCommand createStartUpStorageCommand(Connection conn, SR sr) throws XenAPIException, XmlRpcException { |
| 3705 | + configureStorageNameAndDescription(conn, sr); |
| 3706 | + |
| 3707 | + StoragePoolInfo storagePoolInfo = createStoragePoolInfo(conn, sr); |
| 3708 | + |
| 3709 | + StartupStorageCommand cmd = new StartupStorageCommand(); |
| 3710 | + cmd.setPoolInfo(storagePoolInfo); |
| 3711 | + cmd.setGuid(_host.getUuid()); |
| 3712 | + cmd.setDataCenter(Long.toString(_dcId)); |
| 3713 | + cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); |
| 3714 | + |
| 3715 | + String.format("StartUp command created for local storage [%s] of type [%s] on host [%s]", storagePoolInfo.getUuid(), storagePoolInfo.getPoolType(), _host.getUuid()); |
| 3716 | + return cmd; |
| 3717 | + } |
| 3718 | + |
| 3719 | + /** |
| 3720 | + * Instantiate {@link StoragePoolInfo} with SR's information. |
| 3721 | + */ |
| 3722 | + protected StoragePoolInfo createStoragePoolInfo(Connection conn, SR sr) throws XenAPIException, XmlRpcException { |
| 3723 | + long totalCapacity = sr.getPhysicalSize(conn); |
| 3724 | + String srUuid = sr.getUuid(conn); |
| 3725 | + Host host = Host.getByUuid(conn, _host.getUuid()); |
| 3726 | + String address = host.getAddress(conn); |
| 3727 | + long availableCapacity = totalCapacity - sr.getPhysicalUtilisation(conn); |
| 3728 | + String srType = sr.getType(conn).toUpperCase(); |
| 3729 | + return new StoragePoolInfo(srUuid, address, srType, srType, StoragePoolType.valueOf(srType), totalCapacity, availableCapacity); |
| 3730 | + } |
| 3731 | + |
| 3732 | + protected void configureStorageNameAndDescription(Connection conn, SR sr) throws XenAPIException, XmlRpcException { |
| 3733 | + String srUuid = sr.getUuid(conn); |
| 3734 | + sr.setNameLabel(conn, srUuid); |
| 3735 | + |
| 3736 | + String nameFormat = "Cloud Stack Local (%s) Storage Pool for %s"; |
| 3737 | + sr.setNameDescription(conn, String.format(nameFormat, sr.getType(conn), _host.getUuid())); |
3742 | 3738 | } |
3743 | 3739 |
|
3744 | 3740 | public boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId) { |
|
0 commit comments