Add local storage support for kvm

This commit is contained in:
Edison Su 2011-03-01 19:51:27 -05:00
parent a9bf3959ba
commit 53eb46dc2a
5 changed files with 108 additions and 10 deletions

View File

@ -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<String, String> _pifs;
private final Map<String, vmStats> _vmStats = new ConcurrentHashMap<String, vmStats>();
@ -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<Object> 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<String, State> sync() {

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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

View File

@ -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;