Skip to content

Commit 709845f

Browse files
Keep iotune section in the VM's XML after live migration (#3171)
* Keep iotune section in the VM's XML after live migration When live migrating a KVM VM among local storages, the VM loses the <iotune> section on its XML, therefore, having no IO limitations. This commit removes the piece of code that deletes the <iotune> section in the XML. * Add test for replaceStorage in LibvirtMigrateCommandWrapper Signed-off-by: Wido den Hollander <[email protected]> * Fix Javadoc for method replaceIpForVNCInDescFile
1 parent 7c5eca9 commit 709845f

File tree

2 files changed

+59
-9
lines changed

2 files changed

+59
-9
lines changed

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,17 @@ String replaceIpForVNCInDescFile(String xmlDesc, final String target) {
346346
return xmlDesc;
347347
}
348348

349-
// Pass in a list of the disks to update in the XML (xmlDesc). Each disk passed in needs to have a serial number. If any disk's serial number in the
350-
// list does not match a disk in the XML, an exception should be thrown.
351-
// In addition to the serial number, each disk in the list needs the following info:
352-
// * The value of the 'type' of the disk (ex. file, block)
353-
// * The value of the 'type' of the driver of the disk (ex. qcow2, raw)
354-
// * The source of the disk needs an attribute that is either 'file' or 'dev' as well as its corresponding value.
355-
private String replaceStorage(String xmlDesc, Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage)
349+
/**
350+
* Pass in a list of the disks to update in the XML (xmlDesc). Each disk passed in needs to have a serial number. If any disk's serial number in the
351+
* list does not match a disk in the XML, an exception should be thrown.
352+
* In addition to the serial number, each disk in the list needs the following info:
353+
* <ul>
354+
* <li>The value of the 'type' of the disk (ex. file, block)
355+
* <li>The value of the 'type' of the driver of the disk (ex. qcow2, raw)
356+
* <li>The source of the disk needs an attribute that is either 'file' or 'dev' as well as its corresponding value.
357+
* </ul>
358+
*/
359+
protected String replaceStorage(String xmlDesc, Map<String, MigrateCommand.MigrateDiskInfo> migrateStorage)
356360
throws IOException, ParserConfigurationException, SAXException, TransformerException {
357361
InputStream in = IOUtils.toInputStream(xmlDesc);
358362

@@ -411,8 +415,6 @@ private String replaceStorage(String xmlDesc, Map<String, MigrateCommand.Migrate
411415
diskNode.appendChild(newChildSourceNode);
412416
} else if ("auth".equals(diskChildNode.getNodeName())) {
413417
diskNode.removeChild(diskChildNode);
414-
} else if ("iotune".equals(diskChildNode.getNodeName())) {
415-
diskNode.removeChild(diskChildNode);
416418
}
417419
}
418420
}

plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapperTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@
2121
import static org.junit.Assert.assertEquals;
2222
import static org.junit.Assert.assertTrue;
2323

24+
import java.io.InputStream;
2425
import java.util.ArrayList;
2526
import java.util.List;
27+
import java.util.Map;
28+
import java.util.HashMap;
2629

30+
import org.apache.commons.io.IOUtils;
2731
import org.junit.Assert;
2832
import org.junit.Test;
2933
import org.junit.runner.RunWith;
@@ -43,6 +47,12 @@
4347
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
4448
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
4549
import com.cloud.utils.exception.CloudRuntimeException;
50+
import org.w3c.dom.Document;
51+
52+
import javax.xml.parsers.DocumentBuilder;
53+
import javax.xml.parsers.DocumentBuilderFactory;
54+
import javax.xml.xpath.XPathExpressionException;
55+
import javax.xml.xpath.XPathFactory;
4656

4757
@RunWith(PowerMockRunner.class)
4858
@PrepareForTest({LibvirtConnection.class, LibvirtMigrateCommandWrapper.class})
@@ -96,6 +106,11 @@ public class LibvirtMigrateCommandWrapperTest {
96106
" <backingStore/>\n" +
97107
" </backingStore>\n" +
98108
" <target dev='vda' bus='virtio'/>\n" +
109+
" <iotune>\n" +
110+
" <write_iops_sec>500</write_iops_sec>\n" +
111+
" <write_iops_sec_max>5000</write_iops_sec_max>\n" +
112+
" <write_iops_sec_max_length>60</write_iops_sec_max_length>\n" +
113+
" </iotune>\n" +
99114
" <serial>4650a2f7fce548e2beaa</serial>\n" +
100115
" <alias name='virtio-disk0'/>\n" +
101116
" <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
@@ -208,6 +223,11 @@ public class LibvirtMigrateCommandWrapperTest {
208223
" <backingStore/>\n" +
209224
" </backingStore>\n" +
210225
" <target dev='vda' bus='virtio'/>\n" +
226+
" <iotune>\n" +
227+
" <write_iops_sec>500</write_iops_sec>\n" +
228+
" <write_iops_sec_max>5000</write_iops_sec_max>\n" +
229+
" <write_iops_sec_max_length>60</write_iops_sec_max_length>\n" +
230+
" </iotune>\n" +
211231
" <serial>4650a2f7fce548e2beaa</serial>\n" +
212232
" <alias name='virtio-disk0'/>\n" +
213233
" <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>\n" +
@@ -435,4 +455,32 @@ private void inOrderVerifyDeleteOrDisconnect(InOrder inOrder, LibvirtMigrateComm
435455
inOrder.verify(virtResource, Mockito.times(timesCleanup)).cleanupDisk(disk);
436456
}
437457

458+
static void assertXpath(final Document doc, final String xPathExpr,
459+
final String expected) {
460+
try {
461+
Assert.assertEquals(expected, XPathFactory.newInstance().newXPath()
462+
.evaluate(xPathExpr, doc));
463+
} catch (final XPathExpressionException e) {
464+
Assert.fail("Could not evaluate xpath" + xPathExpr + ":"
465+
+ e.getMessage());
466+
}
467+
}
468+
469+
@Test
470+
public void testReplaceStorage() throws Exception {
471+
Map<String, MigrateDiskInfo> mapMigrateStorage = new HashMap<String, MigrateDiskInfo>();
472+
473+
MigrateDiskInfo diskInfo = new MigrateDiskInfo("123456", DiskType.BLOCK, DriverType.RAW, Source.FILE, "sourctest");
474+
mapMigrateStorage.put("/mnt/812ea6a3-7ad0-30f4-9cab-01e3f2985b98/4650a2f7-fce5-48e2-beaa-bcdf063194e6", diskInfo);
475+
final String result = libvirtMigrateCmdWrapper.replaceStorage(fullfile, mapMigrateStorage);
476+
477+
InputStream in = IOUtils.toInputStream(result);
478+
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
479+
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
480+
Document doc = docBuilder.parse(in);
481+
assertXpath(doc, "/domain/devices/disk/iotune/write_iops_sec", "500");
482+
assertXpath(doc, "/domain/devices/disk/@type", "block");
483+
assertXpath(doc, "/domain/devices/disk/driver/@type", "raw");
484+
}
485+
438486
}

0 commit comments

Comments
 (0)