Skip to content

Commit 849035f

Browse files
author
Daniel Augusto Veronezi Salvador
committed
Qemu 2.10 requires -U flag to read volume metadata
`Qemu 2.10 added the requirement of a --force-share flag to `qemu-img info` command when reading information about a disk that is in use by a guest`. After this Qemu release, to obtain the attached disk metadata, we need to use a flag to force information reading. This PR intends to add the required flag to the `qemu-img info` command if the qemu version is 2.10+. We can get the Qemu version in the LibvirtConnection.
1 parent 261750c commit 849035f

File tree

6 files changed

+41
-27
lines changed

6 files changed

+41
-27
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.cloud.storage.template.TemplateLocation;
5656
import com.cloud.utils.exception.CloudRuntimeException;
5757
import com.cloud.utils.script.Script;
58+
import org.libvirt.LibvirtException;
5859

5960
@ResourceWrapper(handles = CreatePrivateTemplateFromVolumeCommand.class)
6061
public final class LibvirtCreatePrivateTemplateFromVolumeCommandWrapper extends CommandWrapper<CreatePrivateTemplateFromVolumeCommand, Answer, LibvirtComputingResource> {
@@ -120,7 +121,7 @@ public Answer execute(final CreatePrivateTemplateFromVolumeCommand command, fina
120121
final QemuImg q = new QemuImg(0);
121122
try {
122123
q.convert(srcFile, destFile);
123-
} catch (final QemuImgException e) {
124+
} catch (final QemuImgException | LibvirtException e) {
124125
s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " +
125126
e.getMessage());
126127
}

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.cloud.utils.exception.CloudRuntimeException;
3636
import com.cloud.utils.script.OutputInterpreter;
3737
import com.cloud.utils.script.Script;
38+
import org.libvirt.LibvirtException;
3839

3940
@StorageAdaptorInfo(storagePoolType=StoragePoolType.Iscsi)
4041
public class IscsiAdmStorageAdaptor implements StorageAdaptor {
@@ -414,7 +415,7 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk srcDisk, String destVolu
414415

415416
try {
416417
q.convert(srcFile, destFile);
417-
} catch (QemuImgException ex) {
418+
} catch (QemuImgException | LibvirtException ex) {
418419
String msg = "Failed to copy data from " + srcDisk.getPath() + " to " +
419420
destDisk.getPath() + ". The error was the following: " + ex.getMessage();
420421

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ public Answer createTemplateFromVolume(final CopyCommand cmd) {
595595
final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
596596
try {
597597
q.convert(srcFile, destFile);
598-
} catch (final QemuImgException e) {
598+
} catch (final QemuImgException | LibvirtException e) {
599599
final String message = "Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " +
600600
e.getMessage();
601601

@@ -951,7 +951,7 @@ public Answer backupSnapshot(final CopyCommand cmd) {
951951
} catch (final IOException e) {
952952
s_logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
953953
return new CopyCmdAnswer(e.toString());
954-
} catch (final QemuImgException e) {
954+
} catch (final QemuImgException | LibvirtException e) {
955955
s_logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot +
956956
" to " + snapshotFile + " the error was: " + e.getMessage());
957957
return new CopyCmdAnswer(e.toString());

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ private KVMPhysicalDisk createPhysicalDiskByQemuImg(String name, KVMStoragePool
811811
Map<String, String> info = qemu.info(destFile);
812812
virtualSize = Long.parseLong(info.get(new String("virtual_size")));
813813
actualSize = new File(destFile.getFileName()).length();
814-
} catch (QemuImgException e) {
814+
} catch (QemuImgException | LibvirtException e) {
815815
s_logger.error("Failed to create " + volPath +
816816
" due to a failed executing of qemu-img: " + e.getMessage());
817817
}
@@ -1016,7 +1016,7 @@ public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template,
10161016
Map<String, String> options = new HashMap<String, String>();
10171017
qemu.convert(sourceFile, destFile, options, null);
10181018
}
1019-
} catch (QemuImgException e) {
1019+
} catch (QemuImgException | LibvirtException e) {
10201020
s_logger.error("Failed to create " + disk.getPath() +
10211021
" due to a failed executing of qemu-img: " + e.getMessage());
10221022
}
@@ -1068,7 +1068,7 @@ private KVMPhysicalDisk createDiskFromTemplateOnRBD(KVMPhysicalDisk template,
10681068
srcFile = new QemuImgFile(template.getPath(), template.getFormat());
10691069
try{
10701070
qemu.convert(srcFile, destFile);
1071-
} catch (QemuImgException e) {
1071+
} catch (QemuImgException | LibvirtException e) {
10721072
s_logger.error("Failed to create " + disk.getPath() +
10731073
" due to a failed executing of qemu-img: " + e.getMessage());
10741074
}
@@ -1302,12 +1302,12 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
13021302
Long virtualSize = Long.parseLong(destInfo.get(new String("virtual_size")));
13031303
newDisk.setVirtualSize(virtualSize);
13041304
newDisk.setSize(virtualSize);
1305-
} catch (QemuImgException e) {
1305+
} catch (QemuImgException | LibvirtException e) {
13061306
s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
13071307
newDisk = null;
13081308
}
13091309
}
1310-
} catch (QemuImgException e) {
1310+
} catch (QemuImgException | LibvirtException e) {
13111311
s_logger.error("Failed to fetch the information of file " + srcFile.getFileName() + " the error was: " + e.getMessage());
13121312
newDisk = null;
13131313
}
@@ -1351,7 +1351,7 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
13511351
rbd.close(image);
13521352

13531353
r.ioCtxDestroy(io);
1354-
} catch (QemuImgException e) {
1354+
} catch (QemuImgException | LibvirtException e) {
13551355
s_logger.error("Failed to convert from " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
13561356
newDisk = null;
13571357
} catch (RadosException e) {
@@ -1375,7 +1375,7 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMSt
13751375

13761376
try {
13771377
qemu.convert(srcFile, destFile);
1378-
} catch (QemuImgException e) {
1378+
} catch (QemuImgException | LibvirtException e) {
13791379
s_logger.error("Failed to convert " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage());
13801380
newDisk = null;
13811381
}
@@ -1412,7 +1412,7 @@ public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String s
14121412
QemuImgFile srcFile = new QemuImgFile(snapshot.getPath(), snapshot.getFormat());
14131413
qemu.convert(srcFile, destFile, snapshotName);
14141414
}
1415-
} catch (QemuImgException e) {
1415+
} catch (QemuImgException | LibvirtException e) {
14161416
s_logger.error("Failed to create " + destPath +
14171417
" due to a failed executing of qemu-img: " + e.getMessage());
14181418
}

plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020
import java.util.Iterator;
2121
import java.util.Map;
2222

23-
import org.apache.commons.lang.StringUtils;
24-
import org.apache.commons.lang.NotImplementedException;
25-
23+
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
2624
import com.cloud.storage.Storage;
2725
import com.cloud.utils.script.OutputInterpreter;
2826
import com.cloud.utils.script.Script;
27+
import org.apache.commons.lang.StringUtils;
28+
import org.apache.commons.lang.NotImplementedException;
29+
import org.libvirt.LibvirtException;
2930

3031
public class QemuImg {
3132

@@ -234,14 +235,19 @@ public void create(final QemuImgFile file, final Map<String, String> options) th
234235
* @return void
235236
*/
236237
public void convert(final QemuImgFile srcFile, final QemuImgFile destFile,
237-
final Map<String, String> options, final String snapshotName) throws QemuImgException {
238+
final Map<String, String> options, final String snapshotName) throws QemuImgException, LibvirtException {
238239
Script script = new Script(_qemuImgPath, timeout);
239240
if (StringUtils.isNotBlank(snapshotName)) {
240241
String qemuPath = Script.runSimpleBashScript(getQemuImgPathScript);
241242
script = new Script(qemuPath, timeout);
242243
}
243244

244245
script.add("convert");
246+
Long version = LibvirtConnection.getConnection().getVersion();
247+
if (version > 2009000) {
248+
script.add("-U");
249+
}
250+
245251
// autodetect source format. Sometime int he future we may teach KVMPhysicalDisk about more formats, then we can explicitly pass them if necessary
246252
//s.add("-f");
247253
//s.add(srcFile.getFormat().toString());
@@ -292,7 +298,7 @@ public void convert(final QemuImgFile srcFile, final QemuImgFile destFile,
292298
* The destination file
293299
* @return void
294300
*/
295-
public void convert(final QemuImgFile srcFile, final QemuImgFile destFile) throws QemuImgException {
301+
public void convert(final QemuImgFile srcFile, final QemuImgFile destFile) throws QemuImgException, LibvirtException {
296302
this.convert(srcFile, destFile, null, null);
297303
}
298304

@@ -311,7 +317,7 @@ public void convert(final QemuImgFile srcFile, final QemuImgFile destFile) throw
311317
* The snapshot name
312318
* @return void
313319
*/
314-
public void convert(final QemuImgFile srcFile, final QemuImgFile destFile, String snapshotName) throws QemuImgException {
320+
public void convert(final QemuImgFile srcFile, final QemuImgFile destFile, String snapshotName) throws QemuImgException, LibvirtException {
315321
this.convert(srcFile, destFile, null, snapshotName);
316322
}
317323

@@ -343,10 +349,15 @@ public void commit(final QemuImgFile file) throws QemuImgException {
343349
* A QemuImgFile object containing the file to get the information from
344350
* @return A HashMap with String key-value information as returned by 'qemu-img info'
345351
*/
346-
public Map<String, String> info(final QemuImgFile file) throws QemuImgException {
352+
public Map<String, String> info(final QemuImgFile file) throws QemuImgException, LibvirtException {
347353
final Script s = new Script(_qemuImgPath);
348354
s.add("info");
355+
Long version = LibvirtConnection.getConnection().getVersion();
356+
if (version > 2009000) {
357+
s.add("-U");
358+
}
349359
s.add(file.getFileName());
360+
350361
final OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
351362
final String result = s.execute(parser);
352363
if (result != null) {

plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@
3030
import org.junit.Test;
3131

3232
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
33+
import org.libvirt.LibvirtException;
3334

3435

3536
@Ignore
3637
public class QemuImgTest {
3738

3839
@Test
39-
public void testCreateAndInfo() throws QemuImgException {
40+
public void testCreateAndInfo() throws QemuImgException, LibvirtException {
4041
String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
4142

4243
/* 10TB virtual_size */
@@ -63,7 +64,7 @@ public void testCreateAndInfo() throws QemuImgException {
6364
}
6465

6566
@Test
66-
public void testCreateAndInfoWithOptions() throws QemuImgException {
67+
public void testCreateAndInfoWithOptions() throws QemuImgException, LibvirtException {
6768
String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
6869

6970
/* 10TB virtual_size */
@@ -118,7 +119,7 @@ public void testCreateSparseVolume() throws QemuImgException {
118119
}
119120

120121
@Test
121-
public void testCreateAndResize() throws QemuImgException {
122+
public void testCreateAndResize() throws QemuImgException, LibvirtException {
122123
String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
123124

124125
long startSize = 20480;
@@ -147,7 +148,7 @@ public void testCreateAndResize() throws QemuImgException {
147148
}
148149

149150
@Test
150-
public void testCreateAndResizeDeltaPositive() throws QemuImgException {
151+
public void testCreateAndResizeDeltaPositive() throws QemuImgException, LibvirtException {
151152
String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
152153

153154
long startSize = 20480;
@@ -175,7 +176,7 @@ public void testCreateAndResizeDeltaPositive() throws QemuImgException {
175176
}
176177

177178
@Test
178-
public void testCreateAndResizeDeltaNegative() throws QemuImgException {
179+
public void testCreateAndResizeDeltaNegative() throws QemuImgException, LibvirtException {
179180
String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";
180181

181182
long startSize = 81920;
@@ -239,7 +240,7 @@ public void testCreateAndResizeZero() throws QemuImgException {
239240
}
240241

241242
@Test
242-
public void testCreateWithBackingFile() throws QemuImgException {
243+
public void testCreateWithBackingFile() throws QemuImgException, LibvirtException {
243244
String firstFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
244245
String secondFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
245246

@@ -262,7 +263,7 @@ public void testCreateWithBackingFile() throws QemuImgException {
262263
}
263264

264265
@Test
265-
public void testConvertBasic() throws QemuImgException {
266+
public void testConvertBasic() throws QemuImgException, LibvirtException {
266267
long srcSize = 20480;
267268
String srcFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
268269
String destFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
@@ -287,7 +288,7 @@ public void testConvertBasic() throws QemuImgException {
287288
}
288289

289290
@Test
290-
public void testConvertAdvanced() throws QemuImgException {
291+
public void testConvertAdvanced() throws QemuImgException, LibvirtException {
291292
long srcSize = 4019200;
292293
String srcFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";
293294
String destFileName = "/tmp/" + UUID.randomUUID() + ".qcow2";

0 commit comments

Comments
 (0)