// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.netapp; import java.io.IOException; import java.rmi.ServerException; import java.util.HashMap; import java.util.List; import org.apache.log4j.Logger; import netapp.manage.NaException; public class NetappDefaultAllocatorImpl implements NetappAllocator { private static HashMap<String, Integer> _poolNameToLastVolumeIdAllocated = new HashMap<String, Integer>(); private NetappManager _netappMgr; public static final Logger s_logger = Logger.getLogger(NetappDefaultAllocatorImpl.class.getName()); public NetappDefaultAllocatorImpl(NetappManager netappMgr) { _netappMgr = netappMgr; } public synchronized NetappVolumeVO chooseLeastFullVolumeFromPool(String poolName, long lunSizeGb) { List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName); if(volumesOnPoolAscending==null) { //no pools exist in db return null; } long maxAvailable = 0; NetappVolumeVO selectedVol = null; for(NetappVolumeVO vol : volumesOnPoolAscending) { try { long availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress()); if(lunSizeGb <= bytesToGb(availableBytes) && availableBytes>maxAvailable) { maxAvailable = availableBytes; //new max selectedVol = vol; //new least loaded vol } } catch (ServerException se) { s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName()); continue; } } return selectedVol; } /** * This method does the actual round robin allocation * @param poolName * @param lunSizeGb * @return -- the selected volume to create the lun on * @throws IOException * @throws NaException */ public synchronized NetappVolumeVO chooseVolumeFromPool(String poolName, long lunSizeGb) { int pos = 0; //0 by default List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName); if(volumesOnPoolAscending==null) { //no pools exist in db return null; } //get the index of the record from the map if(_poolNameToLastVolumeIdAllocated.get(poolName)==null) { pos=0; } else { pos=_poolNameToLastVolumeIdAllocated.get(poolName); } //update for RR effect _poolNameToLastVolumeIdAllocated.put(poolName, (pos+1)%volumesOnPoolAscending.size()); //now iterate over the records Object[] volumesOnPoolAscendingArray = volumesOnPoolAscending.toArray(); int counter=0; while (counter < volumesOnPoolAscendingArray.length) { NetappVolumeVO vol = (NetappVolumeVO)volumesOnPoolAscendingArray[pos]; //check if the volume fits the bill long availableBytes; try { availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress()); if(lunSizeGb <= bytesToGb(availableBytes)) { //found one return vol; } pos = (pos + 1) % volumesOnPoolAscendingArray.length; counter++; } catch (ServerException e) { s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName()); continue; } } return null; } /** * This method does the byte to gb conversion * @param bytes * @return -- converted gb */ private long bytesToGb(long bytes){ long returnVal = (bytes/(1024*1024*1024)); return returnVal; } }