From d962e569589d85228ec4a591e015173c0ae22784 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 9 Dec 2020 13:30:25 +0530 Subject: [PATCH 1/5] xenserver: check and eject patch vbd for systemvms This failed to destroy systemvms patch VBDs that attaches systemvm.iso on host setup (ready). This will ensure for upgrades old systemvm.iso files are not cached/used. Signed-off-by: Rohit Yadav --- .../hypervisor/xenserver/resource/CitrixResourceBase.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 37ea8fc06961..8c7ce49bbda8 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1499,7 +1499,9 @@ public void destroyPatchVbd(final Connection conn, final String vmName) throws X final Set vbds = vm.getVBDs(conn); for (final VBD vbd : vbds) { if (vbd.getType(conn) == Types.VbdType.CD) { - vbd.eject(conn); + if (!vbd.getEmpty(conn)) { + vbd.eject(conn); + } vbd.destroy(conn); break; } From 6cb9b300ad19408be9d6a50f96d86b864f9880a1 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 9 Dec 2020 13:41:41 +0530 Subject: [PATCH 2/5] try to unplug before destroying Signed-off-by: Rohit Yadav --- .../cloud/hypervisor/xenserver/resource/CitrixResourceBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 8c7ce49bbda8..401ccf8578a1 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1502,6 +1502,7 @@ public void destroyPatchVbd(final Connection conn, final String vmName) throws X if (!vbd.getEmpty(conn)) { vbd.eject(conn); } + vbd.unplug(conn); vbd.destroy(conn); break; } From 8f8615f8fdd9fa3926cd0f051bc37e6ae9942103 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 9 Dec 2020 15:51:58 +0530 Subject: [PATCH 3/5] fix Signed-off-by: Rohit Yadav --- .../resource/CitrixResourceBase.java | 35 +++++++++++-------- .../xenbase/CitrixReadyCommandWrapper.java | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 401ccf8578a1..f90fc8dfa7d4 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1489,27 +1489,31 @@ protected String deleteSnapshotBackup(final Connection conn, final Long dcId, fi return result; } - public void destroyPatchVbd(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + public void ejectPatchVbd(final Connection conn, final Host host) { + try { + final Set vms = host.getResidentVMs(conn); + for (final VM vm : vms) { + destroyPatchVbd(conn, vm); + } + } catch (XenAPIException | XmlRpcException ignored) {} + } + + public void destroyPatchVbd(final Connection conn, final VM vm) throws XmlRpcException, XenAPIException { + final String vmName = vm.getNameLabel(conn); try { if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) { return; } - final Set vms = VM.getByNameLabel(conn, vmName); - for (final VM vm : vms) { - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - if (vbd.getType(conn) == Types.VbdType.CD) { - if (!vbd.getEmpty(conn)) { - vbd.eject(conn); - } - vbd.unplug(conn); - vbd.destroy(conn); - break; - } + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + if (Types.VbdType.CD.equals(vbd.getType(conn))) { + vbd.eject(conn); + vbd.destroy(conn); + break; } } } catch (final Exception e) { - s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e); + s_logger.debug("Cannot destroy CD-ROM device for VM " + vmName + " due to " + e.toString(), e); } } @@ -4845,6 +4849,9 @@ public boolean setupServer(final Connection conn, final Host host) { } } + // Remove old systemvm.iso from any systemvms + ejectPatchVbd(conn, host); + final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22); try { sshConnection.connect(null, 60000, 60000); diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java index 4079f92c26e7..2572bcf72e5d 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java @@ -55,7 +55,7 @@ public Answer execute(final ReadyCommand command, final CitrixResourceBase citri final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); final Set vms = host.getResidentVMs(conn); for (final VM vm : vms) { - citrixResourceBase.destroyPatchVbd(conn, vm.getNameLabel(conn)); + citrixResourceBase.destroyPatchVbd(conn, vm); } } catch (final Exception e) { } From a2e23fe90f83e9b3eb47568001bb712d967c792a Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 9 Dec 2020 16:40:14 +0530 Subject: [PATCH 4/5] workaround fix Signed-off-by: Rohit Yadav --- .../resource/CitrixResourceBase.java | 103 ++++++++++-------- .../xenbase/CitrixReadyCommandWrapper.java | 4 +- .../xenbase/CitrixSetupCommandWrapper.java | 1 - 3 files changed, 56 insertions(+), 52 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index f90fc8dfa7d4..ee6cd3f0c4c0 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1063,33 +1063,43 @@ protected SR createNfsSRbyURI(final Connection conn, final URI uri, final boolea } } - public VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException { + public SR findPatchIsoSR(final Connection conn) throws XmlRpcException, XenAPIException { + Set srs = SR.getByNameLabel(conn, "XenServer Tools"); + if (srs.size() != 1) { + s_logger.debug("Failed to find SR by name 'XenServer Tools', will try to find 'XCP-ng Tools' SR"); + srs = SR.getByNameLabel(conn, "XCP-ng Tools"); + } + if (srs.size() != 1) { + s_logger.debug("Failed to find SR by name 'XenServer Tools' or 'XCP-ng Tools', will try to find 'Citrix Hypervisor' SR"); + srs = SR.getByNameLabel(conn, "Citrix Hypervisor Tools"); + } + if (srs.size() != 1) { + throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools or XCP-ng Tools or Citrix Hypervisor Tools"); + } + final SR sr = srs.iterator().next(); + sr.scan(conn); + return sr; + } - if (_host.getSystemvmisouuid() == null) { - Set srs = SR.getByNameLabel(conn, "XenServer Tools"); - if (srs.size() != 1) { - s_logger.debug("Failed to find SR by name 'XenServer Tools', will try to find 'XCP-ng Tools' SR"); - srs = SR.getByNameLabel(conn, "XCP-ng Tools"); - } - if (srs.size() != 1) { - s_logger.debug("Failed to find SR by name 'XenServer Tools' or 'XCP-ng Tools', will try to find 'Citrix Hypervisor' SR"); - srs = SR.getByNameLabel(conn, "Citrix Hypervisor Tools"); - } - if (srs.size() != 1) { - throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools or XCP-ng Tools or Citrix Hypervisor Tools"); + public VDI findPatchIsoVDI(final Connection conn, final SR sr) throws XmlRpcException, XenAPIException { + final SR.Record srr = sr.getRecord(conn); + for (final VDI vdi : srr.VDIs) { + final VDI.Record vdir = vdi.getRecord(conn); + if (vdir.nameLabel.contains("systemvm.iso")) { + return vdi; } - final SR sr = srs.iterator().next(); - sr.scan(conn); + } + return null; + } - final SR.Record srr = sr.getRecord(conn); + public VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException { + if (_host.getSystemvmisouuid() == null) { + final SR sr = findPatchIsoSR(conn); if (_host.getSystemvmisouuid() == null) { - for (final VDI vdi : srr.VDIs) { - final VDI.Record vdir = vdi.getRecord(conn); - if (vdir.nameLabel.contains("systemvm.iso")) { - _host.setSystemvmisouuid(vdir.uuid); - break; - } + final VDI vdi = findPatchIsoVDI(conn, sr); + if (vdi != null) { + _host.setSystemvmisouuid(vdi.getRecord(conn).uuid); } } if (_host.getSystemvmisouuid() == null) { @@ -1489,31 +1499,31 @@ protected String deleteSnapshotBackup(final Connection conn, final Long dcId, fi return result; } - public void ejectPatchVbd(final Connection conn, final Host host) { - try { - final Set vms = host.getResidentVMs(conn); - for (final VM vm : vms) { - destroyPatchVbd(conn, vm); - } - } catch (XenAPIException | XmlRpcException ignored) {} - } - - public void destroyPatchVbd(final Connection conn, final VM vm) throws XmlRpcException, XenAPIException { - final String vmName = vm.getNameLabel(conn); - try { - if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) { - return; - } - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - if (Types.VbdType.CD.equals(vbd.getType(conn))) { - vbd.eject(conn); - vbd.destroy(conn); - break; + public void destroyPatchVbd(final Connection conn, final Set vms) throws XmlRpcException, XenAPIException { + final SR sr = findPatchIsoSR(conn); + final VDI patchVDI = findPatchIsoVDI(conn, sr); + for (final VM vm : vms) { + final String vmName = vm.getNameLabel(conn); + try { + if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) { + return; + } + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + if (Types.VbdType.CD.equals(vbd.getType(conn))) { + if (!vbd.getEmpty(conn)) { + vbd.eject(conn); + } + // Workaround for any file descriptor caching issue + vbd.insert(conn, patchVDI); + vbd.eject(conn); + vbd.destroy(conn); + break; + } } + } catch (final Exception e) { + s_logger.debug("Cannot destroy CD-ROM device for VM " + vmName + " due to " + e.toString(), e); } - } catch (final Exception e) { - s_logger.debug("Cannot destroy CD-ROM device for VM " + vmName + " due to " + e.toString(), e); } } @@ -4849,9 +4859,6 @@ public boolean setupServer(final Connection conn, final Host host) { } } - // Remove old systemvm.iso from any systemvms - ejectPatchVbd(conn, host); - final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22); try { sshConnection.connect(null, 60000, 60000); diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java index 2572bcf72e5d..78359f0ab915 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixReadyCommandWrapper.java @@ -54,9 +54,7 @@ public Answer execute(final ReadyCommand command, final CitrixResourceBase citri try { final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); final Set vms = host.getResidentVMs(conn); - for (final VM vm : vms) { - citrixResourceBase.destroyPatchVbd(conn, vm); - } + citrixResourceBase.destroyPatchVbd(conn, vms); } catch (final Exception e) { } try { diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java index 76f0e2a767af..2d2fb5d47493 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixSetupCommandWrapper.java @@ -77,7 +77,6 @@ public Answer execute(final SetupCommand command, final CitrixResourceBase citri } - final boolean r = citrixResourceBase.launchHeartBeat(conn); if (!r) { return null; From 7fe57cf25bde54c1793aafee80f2647d78301077 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 9 Dec 2020 16:42:24 +0530 Subject: [PATCH 5/5] add defensive checks Signed-off-by: Rohit Yadav --- .../xenserver/resource/CitrixResourceBase.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index ee6cd3f0c4c0..a26bcc486d08 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1082,6 +1082,9 @@ public SR findPatchIsoSR(final Connection conn) throws XmlRpcException, XenAPIEx } public VDI findPatchIsoVDI(final Connection conn, final SR sr) throws XmlRpcException, XenAPIException { + if (sr == null) { + return null; + } final SR.Record srr = sr.getRecord(conn); for (final VDI vdi : srr.VDIs) { final VDI.Record vdir = vdi.getRecord(conn); @@ -1515,8 +1518,10 @@ public void destroyPatchVbd(final Connection conn, final Set vms) throws Xml vbd.eject(conn); } // Workaround for any file descriptor caching issue - vbd.insert(conn, patchVDI); - vbd.eject(conn); + if (patchVDI != null) { + vbd.insert(conn, patchVDI); + vbd.eject(conn); + } vbd.destroy(conn); break; }