diff options
author | Pavel Balaev <balaev@tarantool.org> | 2022-11-18 13:50:11 +0300 |
---|---|---|
committer | Pavel Balaev <mail@void.so> | 2022-11-18 14:01:48 +0300 |
commit | 9ffa39ac21d03510b045c46cdc59ee1b7c9be1c7 (patch) | |
tree | f1b1062cece0f5635be122149a00920dc3204200 | |
parent | ec31800c34db10d0a2e5a5418baccb23b562b303 (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-- | CHANGES | 4 | ||||
-rw-r--r-- | src/nm_add_vm.c | 15 | ||||
-rw-r--r-- | src/nm_utils.c | 51 | ||||
-rw-r--r-- | src/nm_utils.h | 2 |
4 files changed, 62 insertions, 10 deletions
@@ -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: |