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