The changes since the previous patch: - safe ADD_ARG macro for adding arguments to a fixed size stack array - support for testing functions that return RHashtable, ie. tune2fs-l. - add tests that set (tune2fs) and get (tune2fs-l) various parameters. - only one 'intervalbetweenchecks' parameter (in seconds) Rich.
Richard W.M. Jones
2011-Nov-10 17:52 UTC
[Libguestfs] [PATCH 1/4] daemon: Define safe ADD_ARG macro for constructing arg lists on the stack.
From: "Richard W.M. Jones" <rjones at redhat.com> --- daemon/btrfs.c | 18 +++++++----- daemon/daemon.h | 12 ++++++++ daemon/luks.c | 82 ++++++++++++++++++++++++++++--------------------------- daemon/mkfs.c | 59 +++++++++++++++++++--------------------- daemon/ntfs.c | 18 +++++++----- 5 files changed, 102 insertions(+), 87 deletions(-) diff --git a/daemon/btrfs.c b/daemon/btrfs.c index 755f47e..a20ee08 100644 --- a/daemon/btrfs.c +++ b/daemon/btrfs.c @@ -28,6 +28,8 @@ #include "actions.h" #include "optgroups.h" +#define MAX_ARGS 64 + int optgroup_btrfs_available (void) { @@ -41,13 +43,13 @@ do_btrfs_filesystem_resize (const char *filesystem, int64_t size) char *buf; char *err; int r; - const char *argv[16]; + const char *argv[MAX_ARGS]; size_t i = 0; char size_str[32]; - argv[i++] = "btrfs"; - argv[i++] = "filesystem"; - argv[i++] = "resize"; + ADD_ARG (argv, i, "btrfs"); + ADD_ARG (argv, i, "filesystem"); + ADD_ARG (argv, i, "resize"); if (optargs_bitmask & GUESTFS_BTRFS_FILESYSTEM_RESIZE_SIZE_BITMASK) { if (size <= 0) { @@ -56,10 +58,10 @@ do_btrfs_filesystem_resize (const char *filesystem, int64_t size) } snprintf (size_str, sizeof size_str, "%" PRIi64, size); - argv[i++] = size_str; + ADD_ARG (argv, i, size_str); } else - argv[i++] = "max"; + ADD_ARG (argv, i, "max"); buf = sysroot_path (filesystem); if (!buf) { @@ -67,8 +69,8 @@ do_btrfs_filesystem_resize (const char *filesystem, int64_t size) return -1; } - argv[i++] = buf; - argv[i++] = NULL; + ADD_ARG (argv, i, buf); + ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); free (buf); diff --git a/daemon/daemon.h b/daemon/daemon.h index 6ed68fd..7360a2f 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -212,6 +212,18 @@ is_zero (const char *buffer, size_t size) return 1; } +/* Helper for building up short lists of arguments. Your code has to + * define MAX_ARGS to a suitable value. + */ +#define ADD_ARG(argv,i,v) \ + do { \ + if ((i) >= MAX_ARGS) { \ + fprintf (stderr, "%s: %d: internal error: exceeded MAX_ARGS (%d) when constructing the command line\n", __FILE__, __LINE__, MAX_ARGS); \ + abort (); \ + } \ + (argv)[(i)++] = (v); \ + } while (0) + /* Helper for functions that need a root filesystem mounted. * NB. Cannot be used for FileIn functions. */ diff --git a/daemon/luks.c b/daemon/luks.c index bbe6328..02620ef 100644 --- a/daemon/luks.c +++ b/daemon/luks.c @@ -26,6 +26,8 @@ #include "actions.h" #include "optgroups.h" +#define MAX_ARGS 64 + int optgroup_luks_available (void) { @@ -95,17 +97,17 @@ luks_open (const char *device, const char *key, const char *mapname, if (!tempfile) return -1; - const char *argv[16]; + const char *argv[MAX_ARGS]; size_t i = 0; - argv[i++] = "cryptsetup"; - argv[i++] = "-d"; - argv[i++] = tempfile; - if (readonly) argv[i++] = "--readonly"; - argv[i++] = "luksOpen"; - argv[i++] = device; - argv[i++] = mapname; - argv[i++] = NULL; + ADD_ARG (argv, i, "cryptsetup"); + ADD_ARG (argv, i, "-d"); + ADD_ARG (argv, i, tempfile); + if (readonly) ADD_ARG (argv, i, "--readonly"); + ADD_ARG (argv, i, "luksOpen"); + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, mapname); + ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); @@ -170,23 +172,23 @@ luks_format (const char *device, const char *key, int keyslot, if (!tempfile) return -1; - const char *argv[16]; + const char *argv[MAX_ARGS]; char keyslot_s[16]; size_t i = 0; - argv[i++] = "cryptsetup"; - argv[i++] = "-q"; + ADD_ARG (argv, i, "cryptsetup"); + ADD_ARG (argv, i, "-q"); if (cipher) { - argv[i++] = "--cipher"; - argv[i++] = cipher; + ADD_ARG (argv, i, "--cipher"); + ADD_ARG (argv, i, cipher); } - argv[i++] = "--key-slot"; + ADD_ARG (argv, i, "--key-slot"); snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot); - argv[i++] = keyslot_s; - argv[i++] = "luksFormat"; - argv[i++] = device; - argv[i++] = tempfile; - argv[i++] = NULL; + ADD_ARG (argv, i, keyslot_s); + ADD_ARG (argv, i, "luksFormat"); + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, tempfile); + ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); @@ -232,21 +234,21 @@ do_luks_add_key (const char *device, const char *key, const char *newkey, return -1; } - const char *argv[16]; + const char *argv[MAX_ARGS]; char keyslot_s[16]; size_t i = 0; - argv[i++] = "cryptsetup"; - argv[i++] = "-q"; - argv[i++] = "-d"; - argv[i++] = keyfile; - argv[i++] = "--key-slot"; + ADD_ARG (argv, i, "cryptsetup"); + ADD_ARG (argv, i, "-q"); + ADD_ARG (argv, i, "-d"); + ADD_ARG (argv, i, keyfile); + ADD_ARG (argv, i, "--key-slot"); snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot); - argv[i++] = keyslot_s; - argv[i++] = "luksAddKey"; - argv[i++] = device; - argv[i++] = newkeyfile; - argv[i++] = NULL; + ADD_ARG (argv, i, keyslot_s); + ADD_ARG (argv, i, "luksAddKey"); + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, newkeyfile); + ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); @@ -271,19 +273,19 @@ do_luks_kill_slot (const char *device, const char *key, int keyslot) if (!tempfile) return -1; - const char *argv[16]; + const char *argv[MAX_ARGS]; char keyslot_s[16]; size_t i = 0; - argv[i++] = "cryptsetup"; - argv[i++] = "-q"; - argv[i++] = "-d"; - argv[i++] = tempfile; - argv[i++] = "luksKillSlot"; - argv[i++] = device; + ADD_ARG (argv, i, "cryptsetup"); + ADD_ARG (argv, i, "-q"); + ADD_ARG (argv, i, "-d"); + ADD_ARG (argv, i, tempfile); + ADD_ARG (argv, i, "luksKillSlot"); + ADD_ARG (argv, i, device); snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot); - argv[i++] = keyslot_s; - argv[i++] = NULL; + ADD_ARG (argv, i, keyslot_s); + ADD_ARG (argv, i, NULL); char *err; int r = commandv (NULL, &err, (const char * const *) argv); diff --git a/daemon/mkfs.c b/daemon/mkfs.c index d073c07..f3975dc 100644 --- a/daemon/mkfs.c +++ b/daemon/mkfs.c @@ -29,7 +29,7 @@ #include "daemon.h" #include "actions.h" -#define MAX_ARGS 16 +#define MAX_ARGS 64 /* Takes optional arguments, consult optargs_bitmask. */ int @@ -53,47 +53,47 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize, STREQ (fstype, "ext4")) { if (e2prog (mke2fs) == -1) return -1; - argv[i++] = mke2fs; + ADD_ARG (argv, i, mke2fs); } else - argv[i++] = "mkfs"; + ADD_ARG (argv, i, "mkfs"); - argv[i++] = "-t"; - argv[i++] = fstype; + ADD_ARG (argv, i, "-t"); + ADD_ARG (argv, i, fstype); /* Force mke2fs to create a filesystem, even if it thinks it * shouldn't (RHBZ#690819). */ if (STREQ (fstype, "ext2") || STREQ (fstype, "ext3") || STREQ (fstype, "ext4")) - argv[i++] = "-F"; + ADD_ARG (argv, i, "-F"); /* mkfs.ntfs requires the -Q argument otherwise it writes zeroes * to every block and does bad block detection, neither of which * are useful behaviour for virtual devices. */ if (STREQ (fstype, "ntfs")) - argv[i++] = "-Q"; + ADD_ARG (argv, i, "-Q"); /* mkfs.reiserfs produces annoying interactive prompts unless you * tell it to be quiet. */ if (STREQ (fstype, "reiserfs")) - argv[i++] = "-f"; + ADD_ARG (argv, i, "-f"); /* Same for JFS. */ if (STREQ (fstype, "jfs")) - argv[i++] = "-f"; + ADD_ARG (argv, i, "-f"); /* For GFS, GFS2, assume a single node. */ if (STREQ (fstype, "gfs") || STREQ (fstype, "gfs2")) { - argv[i++] = "-p"; - argv[i++] = "lock_nolock"; + ADD_ARG (argv, i, "-p"); + ADD_ARG (argv, i, "lock_nolock"); /* The man page says this is default, but it doesn't seem to be: */ - argv[i++] = "-j"; - argv[i++] = "1"; + ADD_ARG (argv, i, "-j"); + ADD_ARG (argv, i, "1"); /* Don't ask questions: */ - argv[i++] = "-O"; + ADD_ARG (argv, i, "-O"); } /* Process blocksize parameter if set. */ @@ -121,26 +121,26 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize, } snprintf (blocksize_str, sizeof blocksize_str, "%d", sectors_per_cluster); - argv[i++] = "-s"; - argv[i++] = blocksize_str; + ADD_ARG (argv, i, "-s"); + ADD_ARG (argv, i, blocksize_str); } else if (STREQ (fstype, "ntfs")) { /* For NTFS map the blocksize into a cluster size. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); - argv[i++] = "-c"; - argv[i++] = blocksize_str; + ADD_ARG (argv, i, "-c"); + ADD_ARG (argv, i, blocksize_str); } else { /* For all other filesystem types, try the -b option. */ snprintf (blocksize_str, sizeof blocksize_str, "%d", blocksize); - argv[i++] = "-b"; - argv[i++] = blocksize_str; + ADD_ARG (argv, i, "-b"); + ADD_ARG (argv, i, blocksize_str); } } if (optargs_bitmask & GUESTFS_MKFS_OPTS_FEATURES_BITMASK) { - argv[i++] = "-O"; - argv[i++] = features; + ADD_ARG (argv, i, "-O"); + ADD_ARG (argv, i, features); } if (optargs_bitmask & GUESTFS_MKFS_OPTS_INODE_BITMASK) { @@ -156,8 +156,8 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize, } snprintf (inode_str, sizeof inode_str, "%d", inode); - argv[i++] = "-I"; - argv[i++] = inode_str; + ADD_ARG (argv, i, "-I"); + ADD_ARG (argv, i, inode_str); } if (optargs_bitmask & GUESTFS_MKFS_OPTS_SECTORSIZE_BITMASK) { @@ -172,15 +172,12 @@ do_mkfs_opts (const char *fstype, const char *device, int blocksize, } snprintf (sectorsize_str, sizeof sectorsize_str, "%d", sectorsize); - argv[i++] = "-S"; - argv[i++] = sectorsize_str; + ADD_ARG (argv, i, "-S"); + ADD_ARG (argv, i, sectorsize_str); } - argv[i++] = device; - argv[i++] = NULL; - - if (i > MAX_ARGS) - abort (); + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { diff --git a/daemon/ntfs.c b/daemon/ntfs.c index 92d2432..076e297 100644 --- a/daemon/ntfs.c +++ b/daemon/ntfs.c @@ -28,6 +28,8 @@ #include "actions.h" #include "optgroups.h" +#define MAX_ARGS 64 + int optgroup_ntfs3g_available (void) { @@ -66,12 +68,12 @@ do_ntfsresize_opts (const char *device, int64_t size, int force) { char *err; int r; - const char *argv[16]; + const char *argv[MAX_ARGS]; size_t i = 0; char size_str[32]; - argv[i++] = "ntfsresize"; - argv[i++] = "-P"; + ADD_ARG (argv, i, "ntfsresize"); + ADD_ARG (argv, i, "-P"); if (optargs_bitmask & GUESTFS_NTFSRESIZE_OPTS_SIZE_BITMASK) { if (size <= 0) { @@ -80,15 +82,15 @@ do_ntfsresize_opts (const char *device, int64_t size, int force) } snprintf (size_str, sizeof size_str, "%" PRIi64, size); - argv[i++] = "--size"; - argv[i++] = size_str; + ADD_ARG (argv, i, "--size"); + ADD_ARG (argv, i, size_str); } if (optargs_bitmask & GUESTFS_NTFSRESIZE_OPTS_FORCE_BITMASK && force) - argv[i++] = "--force"; + ADD_ARG (argv, i, "--force"); - argv[i++] = device; - argv[i++] = NULL; + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, NULL); r = commandv (NULL, &err, argv); if (r == -1) { -- 1.7.6
Richard W.M. Jones
2011-Nov-10 17:52 UTC
[Libguestfs] [PATCH 2/4] generator: Support testing the output of RHashtable functions.
From: "Richard W.M. Jones" <rjones at redhat.com> You can use TestOutputHashtable to test the output of RHashtable functions. --- generator/generator_capitests.ml | 38 ++++++++++++++++++++++++++++++++++++++ generator/generator_types.ml | 6 ++++++ generator/generator_utils.ml | 1 + 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/generator/generator_capitests.ml b/generator/generator_capitests.ml index 7bfd87c..f9cacf2 100644 --- a/generator/generator_capitests.ml +++ b/generator/generator_capitests.ml @@ -113,6 +113,22 @@ md5sum (const char *filename, char *result) result[32] = '\\0'; } +/* Return the value for a key in a hashtable. + * Note: the return value is part of the hash and should not be freed. + */ +static const char * +get_key (char **hash, const char *key) +{ + size_t i; + + for (i = 0; hash[i] != NULL; i += 2) { + if (STREQ (hash[i], key)) + return hash[i+1]; + } + + return NULL; /* key not found */ +} + "; (* Generate a list of commands which are not tested anywhere. *) @@ -695,6 +711,28 @@ and generate_one_test_body name i test_name init test in List.iter (generate_test_command_call test_name) seq; generate_test_command_call ~test test_name last + | TestOutputHashtable (seq, fields) -> + pr " /* TestOutputHashtable for %s (%d) */\n" name i; + pr " const char *key, *expected, *value;\n"; + let seq, last = get_seq_last seq in + let test () + List.iter ( + fun (key, value) -> + pr " key = \"%s\";\n" (c_quote key); + pr " expected = \"%s\";\n" (c_quote value); + pr " value = get_key (r, key);\n"; + pr " if (value == NULL) {\n"; + pr " fprintf (stderr, \"%s: key \\\"%%s\\\" not found in hash: expecting \\\"%%s\\\"\\n\", key, expected);\n" test_name; + pr " return -1;\n"; + pr " }\n"; + pr " if (STRNEQ (value, expected)) {\n"; + pr " fprintf (stderr, \"%s: key \\\"%%s\\\": expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", key, expected, value);\n" test_name; + pr " return -1;\n"; + pr " }\n"; + ) fields + in + List.iter (generate_test_command_call test_name) seq; + generate_test_command_call ~test test_name last | TestLastFail seq -> pr " /* TestLastFail for %s (%d) */\n" name i; let seq, last = get_seq_last seq in diff --git a/generator/generator_types.ml b/generator/generator_types.ml index 9da7e45..9459299 100644 --- a/generator/generator_types.ml +++ b/generator/generator_types.ml @@ -290,6 +290,12 @@ and test *) | TestOutputDevice of seq * string + (* Run the command sequence and expect a hashtable. Check + * one of more fields in the hashtable against known good + * strings. + *) + | TestOutputHashtable of seq * (string * string) list + (* Run the command sequence and expect the final command (only) * to fail. *) diff --git a/generator/generator_utils.ml b/generator/generator_utils.ml index 4180c0d..aa7fcba 100644 --- a/generator/generator_utils.ml +++ b/generator/generator_utils.ml @@ -264,6 +264,7 @@ let seq_of_test = function | TestOutputStruct (s, _) | TestOutputFileMD5 (s, _) | TestOutputDevice (s, _) + | TestOutputHashtable (s, _) | TestLastFail s -> s let c_quote str -- 1.7.6
From: "Richard W.M. Jones" <rjones at redhat.com> --- generator/generator_actions.ml | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index d3fa3e0..243ea9b 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -2585,7 +2585,10 @@ C<path> should be a file or directory in the mounted file system This is the same as the C<statvfs(2)> system call."); ("tune2fs_l", (RHashtable "superblock", [Device "device"], []), 55, [], - [], (* XXX test *) + [InitScratchFS, Always, TestOutputHashtable ( + [["tune2fs_l"; "/dev/sdb1"]], + ["Filesystem magic number", "0xEF53"; + "Filesystem OS type", "Linux"])], "get ext2/ext3/ext4 superblock details", "\ This returns the contents of the ext2, ext3 or ext4 filesystem -- 1.7.6
Richard W.M. Jones
2011-Nov-10 17:52 UTC
[Libguestfs] [PATCH 4/4] New API: Bind the tune2fs command.
From: "Richard W.M. Jones" <rjones at redhat.com> Previously we bound the 'tune2fs -l' command so that we could list out the tunables of an ext2/3/4 filesystem. Also commands like set_e2label and set_e2uuid used tune2fs. This commit binds many of the tunables that can be set using tune2fs. The coverage is not complete, but we can add more later because this uses optional parameters so the call is extensible without breaking ABI. The current change gives us enough for using libguestfs within OpenStack. --- daemon/ext2.c | 149 ++++++++++++++++++++++++++++++++++++++++ generator/generator_actions.ml | 97 ++++++++++++++++++++++++++ src/MAX_PROC_NR | 2 +- 3 files changed, 247 insertions(+), 1 deletions(-) diff --git a/daemon/ext2.c b/daemon/ext2.c index f7889da..79fd354 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -32,6 +32,8 @@ /* Confirmed this is true up to ext4 from the Linux sources. */ #define EXT2_LABEL_MAX 16 +#define MAX_ARGS 64 + /* Choose which tools like mke2fs to use. For RHEL 5 (only) there * is a special set of tools which support ext2/3/4. eg. On RHEL 5, * mke2fs only supports ext2/3, but mke4fs supports ext2/3/4. @@ -498,3 +500,150 @@ do_mke2fs_JU (const char *fstype, int blocksize, const char *device, free (err); return 0; } + +/* Takes optional arguments, consult optargs_bitmask. */ +int +do_tune2fs (const char *device, /* only required parameter */ + int force, + int maxmountcount, + int mountcount, + const char *errorbehavior, + int64_t group, + int intervalbetweenchecks, + int reservedblockspercentage, + const char *lastmounteddirectory, + int64_t reservedblockscount, + int64_t user) +{ + const char *argv[MAX_ARGS]; + size_t i = 0; + int r; + char *err; + char prog[] = "tune2fs"; + char maxmountcount_s[64]; + char mountcount_s[64]; + char group_s[64]; + char intervalbetweenchecks_s[64]; + char reservedblockspercentage_s[64]; + char reservedblockscount_s[64]; + char user_s[64]; + + if (e2prog (prog) == -1) + return -1; + + ADD_ARG (argv, i, prog); + + if (optargs_bitmask & GUESTFS_TUNE2FS_FORCE_BITMASK) { + if (force) + ADD_ARG (argv, i, "-f"); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_MAXMOUNTCOUNT_BITMASK) { + if (maxmountcount < 0) { + reply_with_error ("maxmountcount cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-c"); + snprintf (maxmountcount_s, sizeof maxmountcount_s, "%d", maxmountcount); + ADD_ARG (argv, i, maxmountcount_s); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_MOUNTCOUNT_BITMASK) { + if (mountcount < 0) { + reply_with_error ("mountcount cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-C"); + snprintf (mountcount_s, sizeof mountcount_s, "%d", mountcount); + ADD_ARG (argv, i, mountcount_s); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_ERRORBEHAVIOR_BITMASK) { + if (STRNEQ (errorbehavior, "continue") && + STRNEQ (errorbehavior, "remount-ro") && + STRNEQ (errorbehavior, "panic")) { + reply_with_error ("invalid errorbehavior parameter: %s", errorbehavior); + return -1; + } + ADD_ARG (argv, i, "-e"); + ADD_ARG (argv, i, errorbehavior); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_GROUP_BITMASK) { + if (group < 0) { + reply_with_error ("group cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-g"); + snprintf (group_s, sizeof group_s, "%" PRIi64, group); + ADD_ARG (argv, i, group_s); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_INTERVALBETWEENCHECKS_BITMASK) { + if (intervalbetweenchecks < 0) { + reply_with_error ("intervalbetweenchecks cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-i"); + if (intervalbetweenchecks > 0) { + /* -i <NN>s is not documented in the man page, but has been + * supported in tune2fs for several years. + */ + snprintf (intervalbetweenchecks_s, sizeof intervalbetweenchecks_s, + "%ds", intervalbetweenchecks); + ADD_ARG (argv, i, intervalbetweenchecks_s); + } + else + ADD_ARG (argv, i, "0"); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSPERCENTAGE_BITMASK) { + if (reservedblockspercentage < 0) { + reply_with_error ("reservedblockspercentage cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-m"); + snprintf (reservedblockspercentage_s, sizeof reservedblockspercentage_s, + "%d", reservedblockspercentage); + ADD_ARG (argv, i, reservedblockspercentage_s); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_LASTMOUNTEDDIRECTORY_BITMASK) { + ADD_ARG (argv, i, "-M"); + ADD_ARG (argv, i, lastmounteddirectory); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_RESERVEDBLOCKSCOUNT_BITMASK) { + if (reservedblockscount < 0) { + reply_with_error ("reservedblockscount cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-r"); + snprintf (reservedblockscount_s, sizeof reservedblockscount_s, + "%" PRIi64, reservedblockscount); + ADD_ARG (argv, i, reservedblockscount_s); + } + + if (optargs_bitmask & GUESTFS_TUNE2FS_USER_BITMASK) { + if (user < 0) { + reply_with_error ("user cannot be negative"); + return -1; + } + ADD_ARG (argv, i, "-u"); + snprintf (user_s, sizeof user_s, "%" PRIi64, user); + ADD_ARG (argv, i, user_s); + } + + ADD_ARG (argv, i, device); + ADD_ARG (argv, i, NULL); + + r = commandv (NULL, &err, argv); + if (r == -1) { + reply_with_error ("%s: %s: %s", prog, device, err); + free (err); + return -1; + } + + free (err); + return 0; +} diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 243ea9b..fe40fbf 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -6335,6 +6335,103 @@ is for copying blocks within existing files. See C<guestfs_cp>, C<guestfs_cp_a> and C<guestfs_mv> for general file copying and moving functions."); + ("tune2fs", (RErr, [Device "device"], [Bool "force"; Int "maxmountcount"; Int "mountcount"; String "errorbehavior"; Int64 "group"; Int "intervalbetweenchecks"; Int "reservedblockspercentage"; String "lastmounteddirectory"; Int64 "reservedblockscount"; Int64 "user"]), 298, [], + [InitScratchFS, Always, TestOutputHashtable ( + [["tune2fs"; "/dev/sdb1"; "false"; "0"; ""; "NOARG"; ""; "0"; ""; "NOARG"; ""; ""]; + ["tune2fs_l"; "/dev/sdb1"]], + ["Check interval", "0 (<none>)"; + "Maximum mount count", "-1"]); + InitScratchFS, Always, TestOutputHashtable ( + [["tune2fs"; "/dev/sdb1"; "false"; "0"; ""; "NOARG"; ""; "86400"; ""; "NOARG"; ""; ""]; + ["tune2fs_l"; "/dev/sdb1"]], + ["Check interval", "86400 (1 day)"; + "Maximum mount count", "-1"]); + InitScratchFS, Always, TestOutputHashtable ( + [["tune2fs"; "/dev/sdb1"; "false"; ""; ""; "NOARG"; "1"; ""; ""; "NOARG"; ""; "1"]; + ["tune2fs_l"; "/dev/sdb1"]], + ["Reserved blocks uid", "1 (user bin)"; + "Reserved blocks gid", "1 (group bin)"]); + InitScratchFS, Always, TestOutputHashtable ( + [["tune2fs"; "/dev/sdb1"; "false"; ""; ""; "NOARG"; "0"; ""; ""; "NOARG"; ""; "0"]; + ["tune2fs_l"; "/dev/sdb1"]], + ["Reserved blocks uid", "0 (user root)"; + "Reserved blocks gid", "0 (group root)"]) + ], + "adjust ext2/ext3/ext4 filesystem parameters", + "\ +This call allows you to adjust various filesystem parameters of +an ext2/ext3/ext4 filesystem called C<device>. + +The optional parameters are: + +=over 4 + +=item C<force> + +Force tune2fs to complete the operation even in the face of errors. +This is the same as the tune2fs C<-f> option. + +=item C<maxmountcount> + +Set the number of mounts after which the filesystem is checked +by L<e2fsck(8)>. If this is C<0> then the number of mounts is +disregarded. This is the same as the tune2fs C<-c> option. + +=item C<mountcount> + +Set the number of times the filesystem has been mounted. +This is the same as the tune2fs C<-C> option. + +=item C<errorbehavior> + +Change the behavior of the kernel code when errors are detected. +Possible values currently are: C<continue>, C<remount-ro>, C<panic>. +In practice these options don't really make any difference, +particularly for write errors. + +This is the same as the tune2fs C<-e> option. + +=item C<group> + +Set the group which can use reserved filesystem blocks. +This is the same as the tune2fs C<-g> option except that it +can only be specified as a number. + +=item C<intervalbetweenchecks> + +Adjust the maximal time between two filesystem checks +(in seconds). If the option is passed as C<0> then +time-dependent checking is disabled. + +This is the same as the tune2fs C<-i> option. + +=item C<reservedblockspercentage> + +Set the percentage of the filesystem which may only be allocated +by privileged processes. +This is the same as the tune2fs C<-m> option. + +=item C<lastmounteddirectory> + +Set the last mounted directory. +This is the same as the tune2fs C<-M> option. + +=item C<reservedblockscount> +Set the number of reserved filesystem blocks. +This is the same as the tune2fs C<-r> option. + +=item C<user> + +Set the user who can use the reserved filesystem blocks. +This is the same as the tune2fs C<-u> option except that it +can only be specified as a number. + +=back + +To get the current values of filesystem parameters, see +C<guestfs_tune2fs_l>. For precise details of how tune2fs +works, see the L<tune2fs(8)> man page."); + ] let all_functions = non_daemon_functions @ daemon_functions diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 95de1ee..a1f7f63 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -297 +298 -- 1.7.6
On 10/11/11 17:52, Richard W.M. Jones wrote:> The changes since the previous patch: > > - safe ADD_ARG macro for adding arguments to a fixed size stack array > > - support for testing functions that return RHashtable, ie. tune2fs-l. > > - add tests that set (tune2fs) and get (tune2fs-l) various parameters. > > - only one 'intervalbetweenchecks' parameter (in seconds) > > Rich. >ACK to the series. Matt -- Matthew Booth, RHCA, RHCSS Red Hat Engineering, Virtualisation Team GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
Reasonably Related Threads
- [PATCH] Add tune2fs support to libguestfs.
- [PATCH 0/2] Fix btrfs blocksize and bind mkfs.btrfs (RHBZ#807905).
- [PATCH 1/2] generator: Rename java_structs to camel_structs to better reflect their purpose
- [PATCH v2] daemon: Remove GUESTFSD_EXT_CMD.
- [PATCH v3 00/11] btrfs support part2: qgroup/quota commands