Skip to content

Commit 53eb46d

Browse files
committed
Add local storage support for kvm
1 parent a9bf395 commit 53eb46d

5 files changed

Lines changed: 108 additions & 10 deletions

File tree

agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,9 @@
3535
import java.util.ArrayList;
3636
import java.util.Calendar;
3737
import java.util.HashMap;
38-
import java.util.Iterator;
3938
import java.util.List;
4039
import java.util.Map;
4140
import java.util.Properties;
42-
import java.util.Set;
43-
import java.util.SortedMap;
4441
import java.util.UUID;
4542
import java.util.concurrent.ConcurrentHashMap;
4643
import java.util.concurrent.ExecutionException;
@@ -126,6 +123,7 @@
126123
import com.cloud.agent.api.StartCommand;
127124
import com.cloud.agent.api.StartupCommand;
128125
import com.cloud.agent.api.StartupRoutingCommand;
126+
import com.cloud.agent.api.StartupStorageCommand;
129127
import com.cloud.agent.api.StopAnswer;
130128
import com.cloud.agent.api.StopCommand;
131129
import com.cloud.agent.api.VmStatsEntry;
@@ -164,7 +162,6 @@
164162
import com.cloud.host.Host.Type;
165163
import com.cloud.hypervisor.Hypervisor.HypervisorType;
166164
import com.cloud.network.Networks.BroadcastDomainType;
167-
import com.cloud.network.Networks.IsolationType;
168165
import com.cloud.network.Networks.RouterPrivateIpStrategy;
169166
import com.cloud.network.Networks.TrafficType;
170167
import com.cloud.resource.ServerResource;
@@ -288,6 +285,7 @@ protected String getDefaultScriptsDir() {
288285
protected String _pool;
289286
protected String _localGateway;
290287
private boolean _can_bridge_firewall;
288+
protected String _localStoragePath;
291289
private Pair<String, String> _pifs;
292290
private final Map<String, vmStats> _vmStats = new ConcurrentHashMap<String, vmStats>();
293291

@@ -544,6 +542,11 @@ public boolean configure(String name, Map<String, Object> params)
544542
}
545543
}
546544

545+
_localStoragePath = (String)params.get("local.storage.path");
546+
if (_localStoragePath == null) {
547+
_localStoragePath = "/var/lib/libvirt/images/";
548+
}
549+
547550
value = (String)params.get("scripts.timeout");
548551
_timeout = NumbersUtil.parseInt(value, 30*60) * 1000;
549552

@@ -1309,7 +1312,6 @@ protected PrimaryStorageDownloadAnswer execute(final PrimaryStorageDownloadComma
13091312
StoragePool primaryPool = null;
13101313
StorageVol tmplVol = null;
13111314
StorageVol primaryVol = null;
1312-
String result;
13131315
Connect conn = null;
13141316
try {
13151317
conn = LibvirtConnection.getConnection();
@@ -2370,14 +2372,31 @@ private Map<String, String> getVersionStrings() {
23702372
}
23712373

23722374
final List<Object> info = getHostInfo();
2373-
2375+
23742376
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);
23752377
fillNetworkInformation(cmd);
23762378
cmd.getHostDetails().putAll(getVersionStrings());
23772379
cmd.setPool(_pool);
23782380
cmd.setCluster(_clusterId);
2379-
2380-
return new StartupCommand[]{cmd};
2381+
2382+
StartupStorageCommand sscmd = null;
2383+
try {
2384+
Connect conn = LibvirtConnection.getConnection();
2385+
com.cloud.agent.api.StoragePoolInfo pi = _storageResource.initializeLocalStorage(conn, _localStoragePath, cmd.getPrivateIpAddress());
2386+
sscmd = new StartupStorageCommand();
2387+
sscmd.setPoolInfo(pi);
2388+
sscmd.setGuid(pi.getUuid());
2389+
sscmd.setDataCenter(_dcId);
2390+
sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
2391+
} catch (LibvirtException e) {
2392+
2393+
}
2394+
2395+
if (sscmd != null) {
2396+
return new StartupCommand[]{cmd, sscmd};
2397+
} else {
2398+
return new StartupCommand[]{cmd};
2399+
}
23812400
}
23822401

23832402
protected HashMap<String, State> sync() {

agent/src/com/cloud/agent/resource/computing/LibvirtStorageResource.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
import org.libvirt.StorageVol;
1616
import org.libvirt.StoragePoolInfo.StoragePoolState;
1717

18+
import com.cloud.agent.api.StartupStorageCommand;
1819
import com.cloud.agent.api.to.StorageFilerTO;
1920
import com.cloud.agent.api.to.VolumeTO;
2021
import com.cloud.agent.resource.computing.KVMHABase.PoolType;
2122
import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType;
2223
import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat;
2324
import com.cloud.exception.InternalErrorException;
25+
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
2426
import com.cloud.storage.Storage.StoragePoolType;
27+
import com.cloud.storage.Storage;
2528
import com.cloud.storage.StorageLayer;
2629
import com.cloud.utils.script.Script;
2730

@@ -373,5 +376,64 @@ public StorageVol getVolumeFromURI(Connect conn, String volPath) throws LibvirtE
373376
}
374377
}
375378
}
379+
public com.cloud.agent.api.StoragePoolInfo initializeLocalStorage(Connect conn, String localStoragePath, String hostIp) {
380+
if (!(_storageLayer.exists(localStoragePath) && _storageLayer.isDirectory(localStoragePath))) {
381+
return null;
382+
}
383+
384+
File path = new File(localStoragePath);
385+
if (!(path.canWrite() && path.canRead() && path.canExecute())) {
386+
return null;
387+
}
388+
String lh = hostIp + localStoragePath;
389+
String uuid = UUID.nameUUIDFromBytes(lh.getBytes()).toString();
390+
StoragePool pool = null;
391+
try {
392+
pool = conn.storagePoolLookupByUUIDString(uuid);
393+
} catch (LibvirtException e) {
394+
395+
}
396+
397+
if (pool == null) {
398+
LibvirtStoragePoolDef spd = new LibvirtStoragePoolDef(poolType.DIR, uuid, uuid,
399+
null, null, localStoragePath);
400+
try {
401+
pool = conn.storagePoolDefineXML(spd.toString(), 0);
402+
pool.create(0);
403+
} catch (LibvirtException e) {
404+
if (pool != null) {
405+
try {
406+
pool.destroy();
407+
pool.undefine();
408+
} catch (LibvirtException e1) {
409+
}
410+
pool = null;
411+
}
412+
}
413+
}
414+
415+
if (pool == null) {
416+
return null;
417+
}
418+
419+
try {
420+
StoragePoolInfo spi = pool.getInfo();
421+
if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
422+
pool.create(0);
423+
}
424+
425+
spi = pool.getInfo();
426+
if (spi.state != StoragePoolState.VIR_STORAGE_POOL_RUNNING) {
427+
return null;
428+
}
429+
com.cloud.agent.api.StoragePoolInfo pInfo = new com.cloud.agent.api.StoragePoolInfo(uuid, hostIp, localStoragePath, localStoragePath, StoragePoolType.Filesystem, spi.capacity, spi.available);
430+
431+
return pInfo;
432+
} catch (LibvirtException e) {
433+
434+
}
435+
436+
return null;
437+
}
376438

377439
}

api/src/com/cloud/vm/DiskProfile.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ public boolean useLocalStorage() {
102102
return useLocalStorage;
103103
}
104104

105+
public void setUseLocalStorage(boolean useLocalStorage) {
106+
this.useLocalStorage = useLocalStorage;
107+
}
105108
/**
106109
* @return Is this volume recreatable? A volume is recreatable if the disk's content can be
107110
* reconstructed from the template.

server/src/com/cloud/configuration/DefaultComponentLibrary.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.cloud.ha.dao.HighAvailabilityDaoImpl;
6161
import com.cloud.host.dao.DetailsDaoImpl;
6262
import com.cloud.host.dao.HostDaoImpl;
63+
import com.cloud.host.dao.HostTagsDaoImpl;
6364
import com.cloud.hypervisor.HypervisorGuruManagerImpl;
6465
import com.cloud.maid.StackMaidManagerImpl;
6566
import com.cloud.maid.dao.StackMaidDaoImpl;
@@ -246,6 +247,7 @@ protected void populateDaos() {
246247
addDao("OvsTunnelDao", OvsTunnelDaoImpl.class);
247248
addDao("OvsTunnelAccountDao", OvsTunnelAccountDaoImpl.class);
248249
addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class);
250+
addDao("HostTagsDao", HostTagsDaoImpl.class);
249251
}
250252

251253
@Override

server/src/com/cloud/deploy/FirstFitPlanner.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
8585
public DeployDestination plan(VirtualMachineProfile vmProfile,
8686
DeploymentPlan plan, ExcludeList avoid)
8787
throws InsufficientServerCapacityException {
88-
String _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
88+
String _allocationAlgorithm = _configDao.getValue(Config.VmAllocationAlgorithm.key());
8989
VirtualMachine vm = vmProfile.getVirtualMachine();
9090
ServiceOffering offering = vmProfile.getServiceOffering();
9191
DataCenter dc = _dcDao.findById(vm.getDataCenterId());
@@ -430,7 +430,19 @@ protected Map<Volume, List<StoragePool>> findSuitablePoolsForVolumes(VirtualMach
430430
}
431431
}
432432
DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId());
433-
DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
433+
DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType());
434+
435+
boolean useLocalStorage = false;
436+
if (vmProfile.getType() != VirtualMachine.Type.User) {
437+
String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key());
438+
if (ssvmUseLocalStorage.equalsIgnoreCase("true")) {
439+
useLocalStorage = true;
440+
}
441+
} else {
442+
useLocalStorage = diskOffering.getUseLocalStorage();
443+
}
444+
diskProfile.setUseLocalStorage(useLocalStorage);
445+
434446

435447
boolean foundPotentialPools = false;
436448

0 commit comments

Comments
 (0)