diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index 394909342f8..01f87982354 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -35,12 +35,9 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; -import java.util.SortedMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; @@ -126,6 +123,7 @@ import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; @@ -164,7 +162,6 @@ import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.Networks.TrafficType; import com.cloud.resource.ServerResource; @@ -288,6 +285,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected String _pool; protected String _localGateway; private boolean _can_bridge_firewall; + protected String _localStoragePath; private Pair _pifs; private final Map _vmStats = new ConcurrentHashMap(); @@ -544,6 +542,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } + _localStoragePath = (String)params.get("local.storage.path"); + if (_localStoragePath == null) { + _localStoragePath = "/var/lib/libvirt/images/"; + } + value = (String)params.get("scripts.timeout"); _timeout = NumbersUtil.parseInt(value, 30*60) * 1000; @@ -1309,7 +1312,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv StoragePool primaryPool = null; StorageVol tmplVol = null; StorageVol primaryVol = null; - String result; Connect conn = null; try { conn = LibvirtConnection.getConnection(); @@ -2370,14 +2372,31 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } final List info = getHostInfo(); - + final StartupRoutingCommand cmd = new StartupRoutingCommand((Integer)info.get(0), (Long)info.get(1), (Long)info.get(2), (Long)info.get(4), (String)info.get(3), HypervisorType.KVM, RouterPrivateIpStrategy.HostLocal, changes); fillNetworkInformation(cmd); cmd.getHostDetails().putAll(getVersionStrings()); cmd.setPool(_pool); cmd.setCluster(_clusterId); - - return new StartupCommand[]{cmd}; + + StartupStorageCommand sscmd = null; + try { + Connect conn = LibvirtConnection.getConnection(); + com.cloud.agent.api.StoragePoolInfo pi = _storageResource.initializeLocalStorage(conn, _localStoragePath, cmd.getPrivateIpAddress()); + sscmd = new StartupStorageCommand(); + sscmd.setPoolInfo(pi); + sscmd.setGuid(pi.getUuid()); + sscmd.setDataCenter(_dcId); + sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); + } catch (LibvirtException e) { + + } + + if (sscmd != null) { + return new StartupCommand[]{cmd, sscmd}; + } else { + return new StartupCommand[]{cmd}; + } } protected HashMap sync() { diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtStorageResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtStorageResource.java index b71aa40a294..4a5206e1584 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtStorageResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtStorageResource.java @@ -15,13 +15,16 @@ import org.libvirt.StoragePoolInfo; import org.libvirt.StorageVol; import org.libvirt.StoragePoolInfo.StoragePoolState; +import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.resource.computing.KVMHABase.PoolType; import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType; import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat; import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage; import com.cloud.storage.StorageLayer; import com.cloud.utils.script.Script; @@ -373,5 +376,64 @@ public class LibvirtStorageResource { } } } + public com.cloud.agent.api.StoragePoolInfo initializeLocalStorage(Connect conn, String localStoragePath, String hostIp) { + if (!(_storageLayer.exists(localStoragePath) && _storageLayer.isDirectory(localStoragePath))) { + return null; + } + + File path = new File(localStoragePath); + if (!(path.canWrite() && path.canRead() && path.canExecute())) { + return null; + } + String lh = hostIp + localStoragePath; + String uuid = UUID.nameUUIDFromBytes(lh.getBytes()).toString(); + StoragePool pool = null; + try { + pool = conn.storagePoolLookupByUUIDString(uuid); + } catch (LibvirtException e) { + + } + + if (pool == null) { + LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(poolType.DIR, uuid, uuid, + null, null, localStoragePath); + try { + pool = conn.storagePoolDefineXML(spd.toString(), 0); + pool.create(0); + } catch (LibvirtException e) { + if (pool != null) { + try { + pool.destroy(); + pool.undefine(); + } catch (LibvirtException e1) { + } + pool = null; + } + } + } + + if (pool == null) { + return null; + } + + try { + StoragePoolInfo spi = pool.getInfo(); + if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) { + pool.create(0); + } + + spi = pool.getInfo(); + if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) { + return null; + } + com.cloud.agent.api.StoragePoolInfo pInfo = new com.cloud.agent.api.StoragePoolInfo(uuid, hostIp, localStoragePath, localStoragePath, StoragePoolType.Filesystem, spi.capacity, spi.available); + + return pInfo; + } catch (LibvirtException e) { + + } + + return null; + } } diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index 321d732bf0b..603ddeee587 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -102,6 +102,9 @@ public class DiskProfile { return useLocalStorage; } + public void setUseLocalStorage(boolean useLocalStorage) { + this.useLocalStorage = useLocalStorage; + } /** * @return Is this volume recreatable? A volume is recreatable if the disk's content can be * reconstructed from the template. diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 36f5fabc5b0..8fb78863a12 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -60,6 +60,7 @@ import com.cloud.ha.HighAvailabilityManagerImpl; import com.cloud.ha.dao.HighAvailabilityDaoImpl; import com.cloud.host.dao.DetailsDaoImpl; import com.cloud.host.dao.HostDaoImpl; +import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.hypervisor.HypervisorGuruManagerImpl; import com.cloud.maid.StackMaidManagerImpl; import com.cloud.maid.dao.StackMaidDaoImpl; @@ -246,6 +247,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("OvsTunnelDao", OvsTunnelDaoImpl.class); addDao("OvsTunnelAccountDao", OvsTunnelAccountDaoImpl.class); addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class); + addDao("HostTagsDao", HostTagsDaoImpl.class); } @Override diff --git a/server/src/com/cloud/deploy/FirstFitPlanner.java b/server/src/com/cloud/deploy/FirstFitPlanner.java index aca8251ee4d..7230840cbc2 100644 --- a/server/src/com/cloud/deploy/FirstFitPlanner.java +++ b/server/src/com/cloud/deploy/FirstFitPlanner.java @@ -85,7 +85,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { public DeployDestination plan(VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException { - String _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key()); + String _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key()); VirtualMachine vm = vmProfile.getVirtualMachine(); ServiceOffering offering = vmProfile.getServiceOffering(); DataCenter dc = _dcDao.findById(vm.getDataCenterId()); @@ -430,7 +430,19 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner { } } DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + + boolean useLocalStorage = false; + if (vmProfile.getType() != VirtualMachine.Type.User) { + String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); + if (ssvmUseLocalStorage.equalsIgnoreCase("true")) { + useLocalStorage = true; + } + } else { + useLocalStorage = diskOffering.getUseLocalStorage(); + } + diskProfile.setUseLocalStorage(useLocalStorage); + boolean foundPotentialPools = false;