On Monday 19 October 2015 17:05:03 Maxim Perevedentsev wrote:
--- daemon/daemon.h | 1 + daemon/ext2.c | 45 +++++++++++++++++++++++++++++++++++++++------ daemon/fs-min-size.c | 3 +++ generator/actions.ml | 20 ++++---------------- src/MAX_PROC_NR | 2 +- 5 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/daemon/daemon.h b/daemon/daemon.h index a690152..61b61e7 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -224,6 +224,7 @@ extern int sync_disks (void); #define EXT2_LABEL_MAX 16 extern int fstype_is_extfs (const char *fstype); extern int ext_set_uuid_random (const char *device); +extern int64_t ext_min_size (const char *device);
/*-- in blkid.c --*/ extern char *get_blkid_tag (const char *device, const char *tag); diff --git a/daemon/ext2.c b/daemon/ext2.c index 0cd6a66..f00e081 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -279,8 +279,34 @@ do_resize2fs_M (const char *device) return 0; }
+static int32_t +get_block_size (const char *device) +{ + CLEANUP_FREE_STRING_LIST char **params = NULL; + const char *block_pattern = "Block size"; + size_t i; + int32_t block_size; + + params = do_tune2fs_l (device);
This works, yes, although maybe there should be a way to run tune2fs -l and traverse its output to either build a return hash (i.e. what do_tune2fs_l currently does) or just lookup one or more keys (like needed here).
+ if (params == NULL) + return -1; + + for (i = 0; params[i] != NULL; i += 2) { + if ((!strcmp (params[i], block_pattern))) {
Please use STREQ, like use everywhere else in libguestfs. (and the extra brackets are not needed)
+ if (sscanf (params[i + 1], "%" SCNd32, &block_size) != 1) { + reply_with_error("Cannot parse block size");
This could use a simplier xstrtoul/xstrtoull.
+ return -1; + } + return block_size; + } + } + + reply_with_error("No block size in tune2fs_l output. Check format.")
"missing 'Block size' in tune2fs_l output"
+ return -1; +} + int64_t -do_resize2fs_P (const char *device) +ext_min_size (const char *device) { CLEANUP_FREE char *err = NULL, *out = NULL; CLEANUP_FREE_STRING_LIST char **lines = NULL; @@ -288,6 +314,7 @@ do_resize2fs_P (const char *device) size_t i; char *p; int64_t ret; + int32_t block_size; const char *pattern = "Estimated minimum size of the filesystem: ";
r = command (&out, &err, str_resize2fs, "-P", device, NULL); @@ -301,16 +328,22 @@ do_resize2fs_P (const char *device) return -1;
for (i = 0; lines[i] != NULL; ++i) { - if (verbose) - fprintf (stderr, "resize2fs_P: lines[%zu] = \"%s\"\n", i, lines[i]); - if ((p = strstr (lines[i], pattern))) {
STRPREFIX here.
- if (sscanf (p + strlen(pattern), "%" SCNd64, &ret) != 1) + if (sscanf (p + strlen(pattern), "%" SCNd64, &ret) != 1) {
Ditto (xstrtoul).
+ reply_with_error("Cannot parse min size"); + return -1; + } + if ((block_size = get_block_size (device)) == -1) return -1; - return ret; + if (verbose) { + fprintf(stderr, "Minimum size in blocks: %" SCNd64 \ + "\nBlock count: %" SCNd32 "\n", ret, block_size); + } + return ret * block_size;
Might better check ret for possible overflows before multiplying it with block_size.
} }
+ reply_with_error("Minimum size not found. Check output format:\n%s", out); return -1; }
diff --git a/daemon/fs-min-size.c b/daemon/fs-min-size.c index 9c107d1..8c7287f 100644 --- a/daemon/fs-min-size.c +++ b/daemon/fs-min-size.c @@ -35,6 +35,9 @@ do_vfs_min_size(const mountable_t *mountable) if (vfs_type == NULL) return -1;
+ else if (fstype_is_extfs (vfs_type)) + r = ext_min_size (mountable->device); + else if (STREQ (vfs_type, "ntfs")) r = ntfs_min_size (mountable->device);
diff --git a/generator/actions.ml b/generator/actions.ml index 0646a16..22358ef 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12752,24 +12752,12 @@ Only some filesystem types support setting UUIDs. To read the UUID on a filesystem, call C<guestfs_vfs_uuid>." };
{ defaults with - name = "resize2fs_P"; added = (1, 31, 17); - style = RInt64 "sizeinblocks", [Device "device"], []; - proc_nr = Some 457; - tests = [ - InitBasicFS, Always, TestRun ( - [["resize2fs_P"; "/dev/sda1"]]), []; - ]; - shortdesc = "get minimum filesystem size in blocks"; - longdesc = "\ -Get the estimated minimum filesystem size of an ext2/3/4 filesystem in blocks. - -See also L<resize2fs(8)>." }; - - { defaults with name = "vfs_min_size"; added = (1, 31, 18); style = RInt64 "sizeinbytes", [Mountable "mountable"], []; - proc_nr = Some 458; + proc_nr = Some 457; tests = [ + InitBasicFS, Always, TestRun ( + [["vfs_min_size"; "/dev/sda1"]]), []; InitPartition, IfAvailable "ntfsprogs", TestRun( [["mkfs"; "ntfs"; "/dev/sda1"; ""; "NOARG"; ""; ""; "NOARG"]; ["vfs_min_size"; "/dev/sda1"]]), []; @@ -12779,7 +12767,7 @@ See also L<resize2fs(8)>." }; Get the minimum size of filesystem in bytes. This is the minimum possible size for filesystem shrinking.
-See also L<ntfsresize(8)>." }; +See also L<ntfsresize(8)>, L<resize2fs(8)>." };
]
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index c92ddb6..de2a00c 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -458 +457
Thanks, -- Pino Toscano