summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Balaev <balaev@tarantool.org>2022-11-18 13:50:11 +0300
committerPavel Balaev <mail@void.so>2022-11-18 14:01:48 +0300
commit9ffa39ac21d03510b045c46cdc59ee1b7c9be1c7 (patch)
treef1b1062cece0f5635be122149a00920dc3204200
parentec31800c34db10d0a2e5a5418baccb23b562b303 (diff)
import: fix wrong drive virtual size on import
qemu-img info --output json <path> is used to get the size. Close #123
-rw-r--r--CHANGES4
-rw-r--r--src/nm_add_vm.c15
-rw-r--r--src/nm_utils.c51
-rw-r--r--src/nm_utils.h2
4 files changed, 62 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index da742b3..1bf501e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+v3.2.0 - Future
+------------------------
+ - Bugfix: fix wrong drive virtual size on import
+
v3.1.0 - 16.10.1022
------------------------
- Feature: network hotplug
diff --git a/src/nm_add_vm.c b/src/nm_add_vm.c
index cb6615f..d7748fd 100644
--- a/src/nm_add_vm.c
+++ b/src/nm_add_vm.c
@@ -334,17 +334,12 @@ static int nm_add_vm_get_data(nm_vm_t *vm)
/* Check for free space for importing drive image */
if (import) {
off_t size_gb = 0;
- struct stat img_info;
+ off_t virtual_size, actual_size;
- memset(&img_info, 0, sizeof(img_info));
-
- if (stat(vm->srcp.data, &img_info) == 0) {
- size_gb = img_info.st_size / 1024 / 1024 / 1024;
- nm_str_format(&vm->drive.size, "%ld", size_gb);
- } else {
- nm_bug(_("%s: cannot get stat of file: %s"),
- __func__, vm->srcp.data);
- }
+ nm_get_drive_size(&vm->srcp, &virtual_size, &actual_size);
+ size_gb = actual_size / 1073741824;
+ nm_str_format(&vm->drive.size, "%g",
+ (double) virtual_size / 1073741824);
if (size_gb >= nm_hw_disk_free()) {
curs_set(0);
diff --git a/src/nm_utils.c b/src/nm_utils.c
index e79af13..833305e 100644
--- a/src/nm_utils.c
+++ b/src/nm_utils.c
@@ -16,6 +16,8 @@
#include <errno.h>
#include <time.h>
+#include <json.h>
+
enum {
NM_BLKSIZE = 131072, /* 128KiB */
NM_SOCK_READLEN = 1024,
@@ -529,4 +531,53 @@ void nm_gen_uid(nm_str_t *res)
nm_str_free(&time);
nm_str_free(&rnd);
}
+
+void
+nm_get_drive_size(const nm_str_t *path, off_t *virtual_size, off_t *actual_size)
+{
+ struct json_object *js, *jso;
+ nm_vect_t cmdv = NM_INIT_VECT;
+ nm_str_t buf = NM_INIT_STR;
+ nm_str_t out = NM_INIT_STR;
+ const char *res;
+
+ if (!virtual_size || !actual_size) {
+ return;
+ }
+
+ nm_str_format(&buf, "%s/qemu-img", nm_cfg_get()->qemu_bin_path.data);
+ nm_vect_insert(&cmdv, buf.data, buf.len + 1, NULL);
+ nm_vect_insert_cstr(&cmdv, "info");
+ nm_vect_insert_cstr(&cmdv, "--output");
+ nm_vect_insert_cstr(&cmdv, "json");
+ nm_vect_insert_cstr(&cmdv, path->data);
+ nm_vect_end_zero(&cmdv);
+
+ if (nm_spawn_process(&cmdv, &out) != NM_OK) {
+ nm_bug(_("%s: cannot get drive info"), __func__);
+ }
+
+ js = json_tokener_parse(out.data);
+ if (!js) {
+ nm_bug(_("%s: cannot parse json"), __func__);
+ }
+
+ json_object_object_get_ex(js, "virtual-size", &jso);
+ if (!jso) {
+ nm_bug(_("%s: virtual-size is missing"), __func__);
+ }
+ res = json_object_get_string(jso);
+ *virtual_size = nm_str_ttoul(res, 10);
+
+ json_object_object_get_ex(js, "actual-size", &jso);
+ if (!jso) {
+ nm_bug(_("%s: actual-size is missing"), __func__);
+ }
+ res = json_object_get_string(jso);
+ *actual_size = nm_str_ttoul(res, 10);
+
+ nm_str_free(&buf);
+ nm_vect_free(&cmdv, NULL);
+ json_object_put(js);
+}
/* vim:set ts=4 sw=4: */
diff --git a/src/nm_utils.h b/src/nm_utils.h
index d10bc29..8aa5e6e 100644
--- a/src/nm_utils.h
+++ b/src/nm_utils.h
@@ -48,6 +48,8 @@ int nm_cleanup_dir(const nm_str_t *path);
int nm_mkdir_parent(const nm_str_t *path, mode_t mode);
const char *nm_nemu_path(void);
+void nm_get_drive_size(const nm_str_t *path,
+ off_t *virtual_size, off_t *actual_size);
/*
* get date and time, format: