Merge branch '4.19'

This commit is contained in:
João Jandre 2024-11-13 10:45:16 -03:00
commit b38ee63c48
12 changed files with 68 additions and 11 deletions

View File

@ -533,6 +533,11 @@ public class TemplateServiceImpl implements TemplateService {
logger.info("Skip downloading template " + tmplt.getUniqueName() + " since no url is specified."); logger.info("Skip downloading template " + tmplt.getUniqueName() + " since no url is specified.");
continue; continue;
} }
// if this is private template, skip sync to a new image store
if (isSkipTemplateStoreDownload(tmplt, zoneId)) {
logger.info("Skip sync downloading private template " + tmplt.getUniqueName() + " to a new image store");
continue;
}
// if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which // if this is a region store, and there is already an DOWNLOADED entry there without install_path information, which
// means that this is a duplicate entry from migration of previous NFS to staging. // means that this is a duplicate entry from migration of previous NFS to staging.

View File

@ -43,7 +43,7 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor {
private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>(); private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool = new HashMap<>();
@Override @Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details) { public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details, boolean isPrimaryStorage) {
IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this); IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this);
MapStorageUuidToStoragePool.put(uuid, storagePool); MapStorageUuidToStoragePool.put(uuid, storagePool);

View File

@ -389,7 +389,7 @@ public class KVMStoragePoolManager {
//Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced. //Note: due to bug CLOUDSTACK-4459, createStoragepool can be called in parallel, so need to be synced.
private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean primaryStorage) { private synchronized KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean primaryStorage) {
StorageAdaptor adaptor = getStorageAdaptor(type); StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details); KVMStoragePool pool = adaptor.createStoragePool(name, host, port, path, userInfo, type, details, primaryStorage);
// LibvirtStorageAdaptor-specific statement // LibvirtStorageAdaptor-specific statement
if (pool.isPoolSupportHA() && primaryStorage) { if (pool.isPoolSupportHA() && primaryStorage) {

View File

@ -73,6 +73,7 @@ import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -81,6 +82,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
private StorageLayer _storageLayer; private StorageLayer _storageLayer;
private String _mountPoint = "/mnt"; private String _mountPoint = "/mnt";
private String _manageSnapshotPath; private String _manageSnapshotPath;
private static final ConcurrentHashMap<String, Integer> storagePoolRefCounts = new ConcurrentHashMap<>();
private String rbdTemplateSnapName = "cloudstack-base-snap"; private String rbdTemplateSnapName = "cloudstack-base-snap";
private static final int RBD_FEATURE_LAYERING = 1; private static final int RBD_FEATURE_LAYERING = 1;
@ -644,8 +646,44 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
} }
} }
/**
* adjust refcount
*/
private int adjustStoragePoolRefCount(String uuid, int adjustment) {
final String mutexKey = storagePoolRefCounts.keySet().stream()
.filter(k -> k.equals(uuid))
.findFirst()
.orElse(uuid);
synchronized (mutexKey) {
// some access on the storagePoolRefCounts.key(mutexKey) element
int refCount = storagePoolRefCounts.computeIfAbsent(mutexKey, k -> 0);
refCount += adjustment;
if (refCount < 1) {
storagePoolRefCounts.remove(mutexKey);
} else {
storagePoolRefCounts.put(mutexKey, refCount);
}
return refCount;
}
}
/**
* Thread-safe increment storage pool usage refcount
* @param uuid UUID of the storage pool to increment the count
*/
private void incStoragePoolRefCount(String uuid) {
adjustStoragePoolRefCount(uuid, 1);
}
/**
* Thread-safe decrement storage pool usage refcount for the given uuid and return if storage pool still in use.
* @param uuid UUID of the storage pool to decrement the count
* @return true if the storage pool is still used, else false.
*/
private boolean decStoragePoolRefCount(String uuid) {
return adjustStoragePoolRefCount(uuid, -1) > 0;
}
@Override @Override
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details) { public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt"); logger.info("Attempting to create storage pool " + name + " (" + type.toString() + ") in libvirt");
StoragePool sp = null; StoragePool sp = null;
@ -751,6 +789,12 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
} }
try { try {
if (!isPrimaryStorage) {
// only ref count storage pools for secondary storage, as primary storage is assumed
// to be always mounted, as long the primary storage isn't fully deleted.
incStoragePoolRefCount(name);
}
if (sp.isActive() == 0) { if (sp.isActive() == 0) {
logger.debug("Attempting to activate pool " + name); logger.debug("Attempting to activate pool " + name);
sp.create(0); sp.create(0);
@ -762,6 +806,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
return getStoragePool(name); return getStoragePool(name);
} catch (LibvirtException e) { } catch (LibvirtException e) {
decStoragePoolRefCount(name);
String error = e.toString(); String error = e.toString();
if (error.contains("Storage source conflict")) { if (error.contains("Storage source conflict")) {
throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " + throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " +
@ -812,6 +857,13 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
@Override @Override
public boolean deleteStoragePool(String uuid) { public boolean deleteStoragePool(String uuid) {
logger.info("Attempting to remove storage pool " + uuid + " from libvirt"); logger.info("Attempting to remove storage pool " + uuid + " from libvirt");
// decrement and check if storage pool still in use
if (decStoragePoolRefCount(uuid)) {
logger.info(String.format("deleteStoragePool: Storage pool %s still in use", uuid));
return true;
}
Connect conn = null; Connect conn = null;
try { try {
conn = LibvirtConnection.getConnection(); conn = LibvirtConnection.getConnection();

View File

@ -56,7 +56,7 @@ public class ManagedNfsStorageAdaptor implements StorageAdaptor {
} }
@Override @Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details) { public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details, boolean isPrimaryStorage) {
LibvirtStoragePool storagePool = new LibvirtStoragePool(uuid, path, StoragePoolType.ManagedNFS, this, null); LibvirtStoragePool storagePool = new LibvirtStoragePool(uuid, path, StoragePoolType.ManagedNFS, this, null);
storagePool.setSourceHost(host); storagePool.setSourceHost(host);

View File

@ -169,7 +169,7 @@ public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
} }
@Override @Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details) { public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
LOGGER.info(String.format("createStoragePool(uuid,host,port,path,type) called with args (%s, %s, %s, %s, %s)", uuid, host, ""+port, path, type)); LOGGER.info(String.format("createStoragePool(uuid,host,port,path,type) called with args (%s, %s, %s, %s, %s)", uuid, host, ""+port, path, type));
MultipathSCSIPool storagePool = new MultipathSCSIPool(uuid, host, port, path, type, details, this); MultipathSCSIPool storagePool = new MultipathSCSIPool(uuid, host, port, path, type, details, this);
MapStorageUuidToStoragePool.put(uuid, storagePool); MapStorageUuidToStoragePool.put(uuid, storagePool);

View File

@ -146,7 +146,7 @@ public class ScaleIOStorageAdaptor implements StorageAdaptor {
} }
@Override @Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details) { public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, Storage.StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage) {
ScaleIOStoragePool storagePool = new ScaleIOStoragePool(uuid, host, port, path, type, details, this); ScaleIOStoragePool storagePool = new ScaleIOStoragePool(uuid, host, port, path, type, details, this);
MapStorageUuidToStoragePool.put(uuid, storagePool); MapStorageUuidToStoragePool.put(uuid, storagePool);
return storagePool; return storagePool;

View File

@ -40,7 +40,7 @@ public interface StorageAdaptor {
// it with info from local disk, and return it // it with info from local disk, and return it
public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool); public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool);
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details); public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage);
public boolean deleteStoragePool(String uuid); public boolean deleteStoragePool(String uuid);

View File

@ -86,6 +86,6 @@ public class LibvirtStorageAdaptorTest {
Map<String, String> details = new HashMap<>(); Map<String, String> details = new HashMap<>();
details.put("nfsmountopts", "vers=4.1, nconnect=4"); details.put("nfsmountopts", "vers=4.1, nconnect=4");
KVMStoragePool pool = libvirtStorageAdaptor.createStoragePool(uuid, null, 0, dir, null, Storage.StoragePoolType.NetworkFilesystem, details); KVMStoragePool pool = libvirtStorageAdaptor.createStoragePool(uuid, null, 0, dir, null, Storage.StoragePoolType.NetworkFilesystem, details, true);
} }
} }

View File

@ -154,7 +154,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
@Override @Override
public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo, public KVMStoragePool createStoragePool(String name, String host, int port, String path, String userInfo,
Storage.StoragePoolType type, Map<String, String> details) Storage.StoragePoolType type, Map<String, String> details, boolean isPrimaryStorage)
{ {
logger.debug("Linstor createStoragePool: name: '{}', host: '{}', path: {}, userinfo: {}", name, host, path, userInfo); logger.debug("Linstor createStoragePool: name: '{}', host: '{}', path: {}, userinfo: {}", name, host, path, userInfo);
LinstorStoragePool storagePool = new LinstorStoragePool(name, host, port, userInfo, type, this); LinstorStoragePool storagePool = new LinstorStoragePool(name, host, port, userInfo, type, this);

View File

@ -57,7 +57,7 @@ public class StorPoolStorageAdaptor implements StorageAdaptor {
private static final Map<String, KVMStoragePool> storageUuidToStoragePool = new HashMap<String, KVMStoragePool>(); private static final Map<String, KVMStoragePool> storageUuidToStoragePool = new HashMap<String, KVMStoragePool>();
@Override @Override
public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details) { public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map<String, String> details, boolean isPrimaryStorage) {
SP_LOG("StorPoolStorageAdaptor.createStoragePool: uuid=%s, host=%s:%d, path=%s, userInfo=%s, type=%s", uuid, host, port, path, userInfo, storagePoolType); SP_LOG("StorPoolStorageAdaptor.createStoragePool: uuid=%s, host=%s:%d, path=%s, userInfo=%s, type=%s", uuid, host, port, path, userInfo, storagePoolType);
StorPoolStoragePool storagePool = new StorPoolStoragePool(uuid, host, port, storagePoolType, this); StorPoolStoragePool storagePool = new StorPoolStoragePool(uuid, host, port, storagePoolType, this);

View File

@ -3861,7 +3861,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
serviceOfferingSearch.and().op("vmMemory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ); serviceOfferingSearch.and().op("vmMemory", serviceOfferingSearch.entity().getRamSize(), Op.GTEQ);
serviceOfferingSearch.or().op("vmMemoryNull", serviceOfferingSearch.entity().getRamSize(), Op.NULL); serviceOfferingSearch.or().op("vmMemoryNull", serviceOfferingSearch.entity().getRamSize(), Op.NULL);
serviceOfferingSearch.and().op("maxMemoryDetailsSearch", "vmMaxMemoryNull", maxMemoryDetailsSearch.entity().getValue(), Op.NULL); serviceOfferingSearch.and().op("maxMemoryDetailsSearch", "vmMaxMemoryNull", maxMemoryDetailsSearch.entity().getValue(), Op.NULL);
serviceOfferingSearch.and("maxMemoryDetailsSearch", "vmMaxMemoryGTEQ", maxMemoryDetailsSearch.entity().getValue(), Op.GTEQ).cp(); serviceOfferingSearch.or("maxMemoryDetailsSearch", "vmMaxMemoryGTEQ", maxMemoryDetailsSearch.entity().getValue(), Op.GTEQ).cp();
serviceOfferingSearch.cp().cp(); serviceOfferingSearch.cp().cp();
} }