mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
xenserver: Fixed null pointer and deployment issue on Xenserver with L2 Guest network with configDrive (#4004)
This PR fixes an issue where an instance fails to deploy due to a null pointer when using an L2 Guest Network with DefaultL2NetworkOfferingConfigDrive on Xenserver. It also fixes migrating an instance to another host. This has been tested by: - Creating an L2 Guest network, using DefaultL2NetworkOfferingConfigDrive as the network offering. - Deploying an instance using the L2 Guest network created. - Migrating the instance away from the host and back
This commit is contained in:
parent
7e50f4a01b
commit
97f21c1835
@ -1055,7 +1055,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
} catch (final AffinityConflictException e2) {
|
||||
s_logger.warn("Unable to create deployment, affinity rules associted to the VM conflict", e2);
|
||||
throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
|
||||
|
||||
}
|
||||
|
||||
if (dest == null) {
|
||||
|
||||
@ -201,6 +201,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
|
||||
private final static int BASE_TO_CONVERT_BYTES_INTO_KILOBYTES = 1024;
|
||||
|
||||
private final static int USER_DEVICE_START_ID = 3;
|
||||
|
||||
private final static String VM_NAME_ISO_SUFFIX = "-ISO";
|
||||
|
||||
private final static String VM_FILE_ISO_SUFFIX = ".iso";
|
||||
|
||||
private static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance();
|
||||
// static min values for guests on xenserver
|
||||
private static final long mem_128m = 134217728L;
|
||||
@ -1120,7 +1126,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
public VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException {
|
||||
public VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi, int isoCount) throws XmlRpcException, XenAPIException {
|
||||
final Volume.Type type = volume.getType();
|
||||
|
||||
if (vdi == null) {
|
||||
@ -1156,7 +1162,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
if (volume.getType() == Volume.Type.ISO) {
|
||||
vbdr.mode = Types.VbdMode.RO;
|
||||
vbdr.type = Types.VbdType.CD;
|
||||
vbdr.userdevice = "3";
|
||||
vbdr.userdevice = String.valueOf(USER_DEVICE_START_ID + isoCount);
|
||||
} else {
|
||||
vbdr.mode = Types.VbdMode.RW;
|
||||
vbdr.type = Types.VbdType.DISK;
|
||||
@ -3868,7 +3874,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return getVDIbyUuid(conn, volumePath);
|
||||
}
|
||||
|
||||
protected VDI mount(final Connection conn, final String vmName, final DiskTO volume) throws XmlRpcException, XenAPIException {
|
||||
public VDI mount(final Connection conn, final String vmName, final DiskTO volume) throws XmlRpcException, XenAPIException {
|
||||
final DataTO data = volume.getData();
|
||||
final Volume.Type type = volume.getType();
|
||||
if (type == Volume.Type.ISO) {
|
||||
@ -3882,7 +3888,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
|
||||
// corer case, xenserver pv driver iso
|
||||
final String templateName = iso.getName();
|
||||
if (templateName.startsWith("xs-tools")) {
|
||||
if (templateName != null && templateName.startsWith("xs-tools")) {
|
||||
try {
|
||||
final String actualTemplateName = getActualIsoTemplate(conn);
|
||||
final Set<VDI> vdis = VDI.getByNameLabel(conn, actualTemplateName);
|
||||
@ -3911,7 +3917,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
} catch (final URISyntaxException e) {
|
||||
throw new CloudRuntimeException("Incorrect uri " + mountpoint, e);
|
||||
}
|
||||
final SR isoSr = createIsoSRbyURI(conn, uri, vmName, false);
|
||||
final SR isoSr = createIsoSRbyURI(conn, uri, vmName, true);
|
||||
|
||||
final String isoname = isoPath.substring(index + 1);
|
||||
|
||||
@ -4098,17 +4104,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
}
|
||||
final VM vm = vms.iterator().next();
|
||||
|
||||
if (vmDataList != null) {
|
||||
// create SR
|
||||
SR sr = createLocalIsoSR(conn, _configDriveSRName + getHost().getIp());
|
||||
|
||||
// 1. create vm data files
|
||||
createVmdataFiles(vmName, vmDataList, configDriveLabel);
|
||||
|
||||
// 2. copy config drive iso to host
|
||||
copyConfigDriveIsoToHost(conn, sr, vmName);
|
||||
}
|
||||
|
||||
final Set<VBD> vbds = vm.getVBDs(conn);
|
||||
for (final VBD vbd : vbds) {
|
||||
final VBD.Record vbdr = vbd.getRecord(conn);
|
||||
@ -5449,7 +5444,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
public SR createLocalIsoSR(final Connection conn, final String srName) throws XenAPIException, XmlRpcException {
|
||||
|
||||
// if config drive sr already exists then return
|
||||
SR sr = getSRByNameLabelandHost(conn, _configDriveSRName + _host.getIp());
|
||||
SR sr = getSRByNameLabelandHost(conn, srName);
|
||||
|
||||
if (sr != null) {
|
||||
s_logger.debug("Config drive SR already exist, returing it");
|
||||
@ -5542,10 +5537,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
s_logger.debug("Attaching config drive iso device for the VM " + vmName + " In host " + ipAddr);
|
||||
Set<VM> vms = VM.getByNameLabel(conn, vmName);
|
||||
|
||||
SR sr = getSRByNameLabel(conn, _configDriveSRName + ipAddr);
|
||||
SR sr = getSRByNameLabel(conn, vmName + VM_NAME_ISO_SUFFIX);
|
||||
//Here you will find only two vdis with the <vmname>.iso.
|
||||
//one is from source host and second from dest host
|
||||
Set<VDI> vdis = VDI.getByNameLabel(conn, vmName + ".iso");
|
||||
Set<VDI> vdis = VDI.getByNameLabel(conn, vmName + VM_FILE_ISO_SUFFIX);
|
||||
if (vdis.isEmpty()) {
|
||||
s_logger.debug("Could not find config drive ISO: " + vmName);
|
||||
return false;
|
||||
|
||||
@ -91,7 +91,8 @@ public class CitrixMigrateCommandWrapper extends CommandWrapper<MigrateCommand,
|
||||
|
||||
// The iso can be attached to vm only once the vm is (present in the host) migrated.
|
||||
// Attach the config drive iso device to VM
|
||||
if (!citrixResourceBase.attachConfigDriveToMigratedVm(conn, vmName, dstHostIpAddr)) {
|
||||
VM vm = vms.iterator().next();
|
||||
if (!citrixResourceBase.attachConfigDriveIsoToVm(conn, vm)) {
|
||||
s_logger.debug("Config drive ISO attach failed after migration for vm "+vmName);
|
||||
}
|
||||
|
||||
|
||||
@ -98,34 +98,8 @@ public final class CitrixStartCommandWrapper extends CommandWrapper<StartCommand
|
||||
if (vmSpec.getType() != VirtualMachine.Type.User) {
|
||||
citrixResourceBase.createPatchVbd(conn, vmName, vm);
|
||||
}
|
||||
// put cdrom at the first place in the list
|
||||
List<DiskTO> disks = new ArrayList<DiskTO>(vmSpec.getDisks().length);
|
||||
int index = 0;
|
||||
for (final DiskTO disk : vmSpec.getDisks()) {
|
||||
if (Volume.Type.ISO.equals(disk.getType())) {
|
||||
disks.add(0, disk);
|
||||
} else {
|
||||
disks.add(index, disk);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
for (DiskTO disk : disks) {
|
||||
final VDI newVdi = citrixResourceBase.prepareManagedDisk(conn, disk, vmSpec.getId(), vmSpec.getName());
|
||||
|
||||
if (newVdi != null) {
|
||||
final Map<String, String> data = new HashMap<>();
|
||||
|
||||
final String path = newVdi.getUuid(conn);
|
||||
|
||||
data.put(StartAnswer.PATH, path);
|
||||
data.put(StartAnswer.IMAGE_FORMAT, Storage.ImageFormat.VHD.toString());
|
||||
|
||||
iqnToData.put(disk.getDetails().get(DiskTO.IQN), data);
|
||||
}
|
||||
|
||||
citrixResourceBase.createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi);
|
||||
}
|
||||
prepareDisks(vmSpec, citrixResourceBase, conn, iqnToData, vmName, vm);
|
||||
|
||||
for (final NicTO nic : vmSpec.getNics()) {
|
||||
citrixResourceBase.createVif(conn, vmName, vm, vmSpec, nic);
|
||||
@ -228,4 +202,35 @@ public final class CitrixStartCommandWrapper extends CommandWrapper<StartCommand
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareDisks(VirtualMachineTO vmSpec, CitrixResourceBase citrixResourceBase, Connection conn,
|
||||
Map<String, Map<String, String>> iqnToData, String vmName, VM vm) throws Exception {
|
||||
// put cdrom at the first place in the list
|
||||
List<DiskTO> disks = new ArrayList<DiskTO>(vmSpec.getDisks().length);
|
||||
int index = 0;
|
||||
for (final DiskTO disk : vmSpec.getDisks()) {
|
||||
if (Volume.Type.ISO.equals(disk.getType())) {
|
||||
disks.add(0, disk);
|
||||
} else {
|
||||
disks.add(index, disk);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
int isoCount = 0;
|
||||
for (DiskTO disk : disks) {
|
||||
final VDI newVdi = citrixResourceBase.prepareManagedDisk(conn, disk, vmSpec.getId(), vmSpec.getName());
|
||||
if (newVdi != null) {
|
||||
final Map<String, String> data = new HashMap<>();
|
||||
final String path = newVdi.getUuid(conn);
|
||||
data.put(StartAnswer.PATH, path);
|
||||
data.put(StartAnswer.IMAGE_FORMAT, Storage.ImageFormat.VHD.toString());
|
||||
iqnToData.put(disk.getDetails().get(DiskTO.IQN), data);
|
||||
}
|
||||
citrixResourceBase.createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi, isoCount);
|
||||
|
||||
if (disk.getType() == Volume.Type.ISO) {
|
||||
isoCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,18 +305,16 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
||||
|
||||
@Override
|
||||
public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) {
|
||||
if (nic.isDefaultNic() && _networkModel.getUserDataUpdateProvider(network).getProvider().equals(Provider.ConfigDrive)) {
|
||||
if (_networkModel.getUserDataUpdateProvider(network).getProvider().equals(Provider.ConfigDrive)) {
|
||||
LOG.trace(String.format("[prepareMigration] for vm: %s", vm.getInstanceName()));
|
||||
final DataStore dataStore = findDataStore(vm, dest);
|
||||
|
||||
try {
|
||||
addConfigDriveDisk(vm, dataStore);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
addPasswordAndUserdata(network, nic, vm, dest, context);
|
||||
} catch (InsufficientCapacityException | ResourceUnavailableException e) {
|
||||
LOG.error("Failed to add config disk drive due to: ", e);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user