[PATCH] customize: handle Arg.Set parameters in commands file
by Pino Toscano
When reading commands from a file, handle also Arg.Set parameters, so
they can be enabled as well.
---
generator/customize.ml | 1 +
1 file changed, 1 insertion(+)
diff --git a/generator/customize.ml b/generator/customize.ml
index 4844681..1c9092b 100644
--- a/generator/customize.ml
+++ b/generator/customize.ml
@@ -696,6 +696,7 @@ pr " ] in
(match spec with
| Arg.Unit fn -> fn ()
| Arg.String fn -> fn arg
+ | Arg.Set varref -> varref := true
| _ -> error \"INTERNAL error: spec not handled for %%s\" cmd
)
with Not_found ->
--
1.9.3
9 years, 11 months
[PATCH 00/16] btrfs: add support to btrfs scrub, balance, rescue and inspect
by Hu Tao
Hi,
This series adds new APIs to support btrfs scrub, balance, rescue
and inspect.
Some of them don't have tests because:
- btrfs_scrub and btrfs_balance completes too early before we can
test btrfs_scrub_cancel, btrfs_scrub_resume, btrfs_scrub_status,
btrfs_balance_pause, btrfs_balance_cancel, btrfs_balance_resume
and btrfs_balance_status.
- can't determine a valid logical address for test
btrfs_inspect_logical_resolve.
Thank you very much for review!
Regards,
Hu
Hu Tao (16):
New API: btrfs_scrub
New API: btrfs_scrub_cancel
New API: btrfs_scrub_resume
btrfs: replace "btrfs filesystem balance" with "btrfs balance"
New API: btrfs_balance_pause
New API: btrfs_balance_cancel
New API: btrfs_balance_resume
New API: btrfs_balance_status
New API: btrfs_scrub_status
New API: add btrfs_filesystem_defragment
New API: add btrfs_rescue_chunk_recover
New API: add btrfs_rescue_super_recover
New API: btrfs_inspect_rootid
New API: btrfs_inspect_subvolid_resolve
New API: btrfs_inspect_inode_resolve
New API: btrfs_inspect_logical_resolve
daemon/btrfs.c | 519 ++++++++++++++++++++++++++++++++++++++++++++++++++-
generator/actions.ml | 198 ++++++++++++++++++++
gobject/Makefile.inc | 4 +-
java/Makefile.inc | 2 +-
po/POTFILES | 1 +
src/MAX_PROC_NR | 2 +-
6 files changed, 722 insertions(+), 4 deletions(-)
--
2.1.0
9 years, 11 months
[PATCH v2] virt-copy, virt-tar: show help for -h
by Maros Zatko
Shows manpage for virt-copy-in,out and virt-tar-in,out
when user supplies -h as a parameter instead of listing
unrelated commands with descriptions.
Maros Zatko (1):
virt-copy, virt-tar: show help for -h
fish/virt-copy-in | 13 ++++++++++++-
fish/virt-copy-out | 13 ++++++++++++-
fish/virt-tar-in | 13 ++++++++++++-
fish/virt-tar-out | 13 ++++++++++++-
4 files changed, 48 insertions(+), 4 deletions(-)
--
1.9.3
9 years, 11 months
[PATCH] virt-copy, virt-tar: show help for -h
by Maros Zatko
Shows manpage for virt-copy-in,out and virt-tar-in,out
when user supplies -h as a parameter instead of listing
unrelated commands with descriptions.
Maros Zatko (1):
virt-copy, virt-tar: show help for -h
fish/virt-copy-in | 13 ++++++++++++-
fish/virt-copy-out | 13 ++++++++++++-
fish/virt-tar-in | 13 ++++++++++++-
fish/virt-tar-out | 13 ++++++++++++-
4 files changed, 48 insertions(+), 4 deletions(-)
--
1.9.3
9 years, 11 months
[PATCH 1/2] mllib: tests: add tests for string_lines_split
by Pino Toscano
---
mllib/common_utils_tests.ml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/mllib/common_utils_tests.ml b/mllib/common_utils_tests.ml
index 09d5c51..283e9a1 100644
--- a/mllib/common_utils_tests.ml
+++ b/mllib/common_utils_tests.ml
@@ -27,6 +27,7 @@ let prog = "common_utils_tests"
let assert_equal_string = assert_equal ~printer:(fun x -> x)
let assert_equal_int = assert_equal ~printer:(fun x -> string_of_int x)
let assert_equal_int64 = assert_equal ~printer:(fun x -> Int64.to_string x)
+let assert_equal_stringlist = assert_equal ~printer:(fun x -> "(" ^ (String.escaped (String.concat "," x)) ^ ")")
(* Test Common_utils.int_of_le32 and Common_utils.le32_of_int. *)
let test_le32 () =
@@ -110,6 +111,22 @@ let test_string_find () =
assert_equal_int (-1) (string_find "" "baz");
assert_equal_int (-1) (string_find "foobar" "baz")
+(* Test Common_utils.string_lines_split. *)
+let test_string_lines_split () =
+ assert_equal_stringlist [""] (string_lines_split "");
+ assert_equal_stringlist ["A"] (string_lines_split "A");
+ assert_equal_stringlist ["A"; ""] (string_lines_split "A\n");
+ assert_equal_stringlist ["A"; "B"] (string_lines_split "A\nB");
+ assert_equal_stringlist ["A"; "B"; "C"] (string_lines_split "A\nB\nC");
+ assert_equal_stringlist ["A"; "B"; "C"; "D"] (string_lines_split "A\nB\nC\nD");
+ assert_equal_stringlist ["A\n"] (string_lines_split "A\\");
+ assert_equal_stringlist ["A\nB"] (string_lines_split "A\\\nB");
+ assert_equal_stringlist ["A"; "B\nC"] (string_lines_split "A\nB\\\nC");
+ assert_equal_stringlist ["A"; "B\nC"; "D"] (string_lines_split "A\nB\\\nC\nD");
+ assert_equal_stringlist ["A"; "B\nC\nD"] (string_lines_split "A\nB\\\nC\\\nD");
+ assert_equal_stringlist ["A\nB"; ""] (string_lines_split "A\\\nB\n");
+ assert_equal_stringlist ["A\nB\n"] (string_lines_split "A\\\nB\\\n")
+
(* Suites declaration. *)
let suite =
TestList ([
@@ -124,6 +141,7 @@ let suite =
"prefix" >:: test_string_prefix;
"suffix" >:: test_string_suffix;
"find" >:: test_string_find;
+ "string_lines_split" >:: test_string_lines_split;
];
])
--
1.9.3
9 years, 11 months
[PATCH 1/2] configure: look for the oUnit OCaml module
by Pino Toscano
It will be used for the OCaml unit tests.
---
configure.ac | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/configure.ac b/configure.ac
index e0fb481..e360bbb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1120,6 +1120,7 @@ AS_IF([test "x$OCAMLC" != "xno"],[
])
OCAML_PKG_gettext=no
+OCAML_PKG_oUnit=no
AS_IF([test "x$OCAMLC" != "xno"],[
# Create mllib/common_gettext.ml, gettext functions or stubs.
@@ -1128,9 +1129,13 @@ AS_IF([test "x$OCAMLC" != "xno"],[
mkdir -p mllib
GUESTFS_CREATE_COMMON_GETTEXT_ML([mllib/common_gettext.ml])
+
+ AC_CHECK_OCAML_PKG(oUnit)
])
AM_CONDITIONAL([HAVE_OCAML_PKG_GETTEXT],
[test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno"])
+AM_CONDITIONAL([HAVE_OCAML_PKG_OUNIT],
+ [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_oUnit" != "xno"])
AC_CHECK_PROG([OCAML_GETTEXT],[ocaml-gettext],[ocaml-gettext],[no])
AM_CONDITIONAL([HAVE_OCAML_GETTEXT],
--
1.9.3
9 years, 11 months
[PATCH] customize: add --commands-from-file
by Pino Toscano
Pass to --commands-from-file the name of a file containing customization
commands in each line, as if they were specified as command line
arguments.
This eases the reuse of commands among different
builder/customize/sysprep invocations.
---
builder/cmdline.ml | 3 +-
customize/customize_run.ml | 5 +++
generator/customize.ml | 98 ++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 101 insertions(+), 5 deletions(-)
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index bb7b1d0..1c6ab98 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -308,7 +308,8 @@ read the man page virt-builder(1).
| `Delete _ | `Edit _ | `FirstbootCommand _ | `FirstbootPackages _
| `FirstbootScript _ | `Hostname _ | `Link _ | `Mkdir _
| `Password _ | `RootPassword _ | `Scrub _ | `SSHInject _
- | `Timezone _ | `Upload _ | `Write _ | `Chmod _ -> false
+ | `Timezone _ | `Upload _ | `Write _ | `Chmod _
+ | `CommandsFromFile _ -> false
) ops.ops in
if requires_execute_on_guest then
error (f_"sorry, cannot run commands on a guest with a different architecture");
diff --git a/customize/customize_run.ml b/customize/customize_run.ml
index 19b7a7d..fed905b 100644
--- a/customize/customize_run.ml
+++ b/customize/customize_run.ml
@@ -170,6 +170,11 @@ exec >>%s 2>&1
msg (f_"Running: %s") cmd;
do_run ~display:cmd cmd
+ | `CommandsFromFile _ ->
+ (* Nothing to do, the files with customize commands are already
+ * read when their arguments are met. *)
+ ()
+
| `Delete path ->
msg (f_"Deleting: %s") path;
g#rm_rf path
diff --git a/generator/customize.ml b/generator/customize.ml
index 82ecb79..d5e72ac 100644
--- a/generator/customize.ml
+++ b/generator/customize.ml
@@ -43,6 +43,7 @@ and op_type =
| PasswordSelector of string (* password selector *)
| UserPasswordSelector of string (* user:selector *)
| SSHKeySelector of string (* user:selector *)
+| StringFn of (string * string) (* string, function name *)
let ops = [
{ op_name = "chmod";
@@ -56,6 +57,29 @@ I<Note>: C<PERMISSIONS> by default would be decimal, unless you prefix
it with C<0> to get octal, ie. use C<0700> not C<700>.";
};
+ { op_name = "commands-from-file";
+ op_type = StringFn ("FILENAME", "customize_read_from_file");
+ op_discrim = "`CommandsFromFile";
+ op_shortdesc = "Read customize commands from file";
+ op_pod_longdesc = "\
+Read the customize commands from a file, one (and its arguments)
+each line.
+
+Each line contains a single customization command and its arguments,
+for example:
+
+ delete /some/file
+ install some-package
+ password some-user:password:its-new-password
+
+Empty lines are ignored, and lines starting with C<#> are comments
+and are ignored as well.
+
+The commands are handled in the same order as they are in the file,
+as if they were specified as I<--delete /some/file> on the command
+line.";
+ };
+
{ op_name = "delete";
op_type = String "PATH";
op_discrim = "`Delete";
@@ -474,7 +498,7 @@ let rec argspec () =
| target :: lns -> target, lns
in
- let argspec = [
+ let rec argspec = [
";
List.iter (
@@ -569,6 +593,18 @@ let rec argspec () =
pr " s_\"%s\" ^ \" \" ^ s_\"%s\"\n" v shortdesc;
pr " ),\n";
pr " Some %S, %S;\n" v longdesc
+ | { op_type = StringFn (v, fn); op_name = name; op_discrim = discrim;
+ op_shortdesc = shortdesc; op_pod_longdesc = longdesc } ->
+ pr " (\n";
+ pr " \"--%s\",\n" name;
+ pr " Arg.String (\n";
+ pr " fun s ->\n";
+ pr " %s s;\n" fn;
+ pr " ops := %s s :: !ops\n" discrim;
+ pr " ),\n";
+ pr " s_\"%s\" ^ \" \" ^ s_\"%s\"\n" v shortdesc;
+ pr " ),\n";
+ pr " Some %S, %S;\n" v longdesc
) ops;
List.iter (
@@ -598,7 +634,57 @@ let rec argspec () =
pr " Some %S, %S;\n" v longdesc
) flags;
- pr " ] in
+ pr " ]
+ and customize_read_from_file filename =
+ let forbidden_commands = [
+";
+
+ List.iter (
+ function
+ | { op_type = StringFn (_, _); op_name = name; } ->
+ pr " \"%s\";\n" name
+ | { op_type = Unit; }
+ | { op_type = String _; }
+ | { op_type = StringPair _; }
+ | { op_type = StringList _; }
+ | { op_type = TargetLinks _; }
+ | { op_type = PasswordSelector _; }
+ | { op_type = UserPasswordSelector _; }
+ | { op_type = SSHKeySelector _; } -> ()
+ ) ops;
+
+pr " ] in
+ let lines = read_whole_file filename in
+ let lines = string_nsplit \"\\n\" lines in
+ let lines = List.filter (
+ fun line ->
+ String.length line > 0 && line.[0] <> '#'
+ ) lines in
+ let cmds = List.map (fun line -> string_split \" \" line) lines in
+ (* Check for commands not allowed in files containing commands. *)
+ List.iter (
+ fun (cmd, _) ->
+ if List.mem cmd forbidden_commands then
+ error (f_\"command '%%s' cannot be used in command files, see the man page\")
+ cmd
+ ) cmds;
+ List.iter (
+ fun (cmd, arg) ->
+ try
+ let ((_, spec, _), _, _) = List.find (
+ fun ((key, _, _), _, _) ->
+ key = \"--\" ^ cmd
+ ) argspec in
+ (match spec with
+ | Arg.Unit fn -> fn ()
+ | Arg.String fn -> fn arg
+ | _ -> error \"INTERNAL error: spec not handled for %%s\" cmd
+ )
+ with Not_found ->
+ error (f_\"command '%%s' not valid, see the man page\")
+ cmd
+ ) cmds
+ in
argspec, get_ops
"
@@ -640,6 +726,8 @@ type ops = {
op_name = name } ->
pr " | %s of string * Ssh_key.ssh_key_selector\n (* --%s %s *)\n"
discrim name v
+ | { op_type = StringFn (v, _); op_discrim = discrim; op_name = name } ->
+ pr " | %s of string\n (* --%s %s *)\n" discrim name v
) ops;
pr "]\n";
@@ -665,7 +753,8 @@ let generate_customize_synopsis_pod () =
| { op_type = Unit; op_name = n } ->
n, sprintf "[--%s]" n
| { op_type = String v | StringPair v | StringList v | TargetLinks v
- | PasswordSelector v | UserPasswordSelector v | SSHKeySelector v;
+ | PasswordSelector v | UserPasswordSelector v | SSHKeySelector v
+ | StringFn (v, _);
op_name = n } ->
n, sprintf "[--%s %s]" n v
) ops @
@@ -705,7 +794,8 @@ let generate_customize_options_pod () =
| { op_type = Unit; op_name = n; op_pod_longdesc = ld } ->
n, sprintf "B<--%s>" n, ld
| { op_type = String v | StringPair v | StringList v | TargetLinks v
- | PasswordSelector v | UserPasswordSelector v | SSHKeySelector v;
+ | PasswordSelector v | UserPasswordSelector v | SSHKeySelector v
+ | StringFn (v, _);
op_name = n; op_pod_longdesc = ld } ->
n, sprintf "B<--%s> %s" n v, ld
) ops @
--
1.9.3
9 years, 11 months
[PATCH] daemon: readdir: fix invalid memory access on error
by Pino Toscano
If "strdup (d->d_name)" fails with "i" > 0, then both "p" and
"ret->guestfs_int_dirent_list_val" are non-null pointers, but the latter
is no more valid (since "p" is the new realloc'ed buffer). Hence, trying
to free both will access to invalid memory.
Make sure to free only one of them, "p" if not null or
"ret->guestfs_int_dirent_list_val" otherwise.
---
daemon/readdir.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/daemon/readdir.c b/daemon/readdir.c
index f0ddd21..e488f93 100644
--- a/daemon/readdir.c
+++ b/daemon/readdir.c
@@ -27,6 +27,17 @@
#include "daemon.h"
#include "actions.h"
+static void
+free_int_dirent_list (guestfs_int_dirent *p, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; ++i) {
+ free (p[i].name);
+ }
+ free (p);
+}
+
guestfs_int_dirent_list *
do_readdir (const char *path)
{
@@ -64,8 +75,11 @@ do_readdir (const char *path)
v.name = strdup (d->d_name);
if (!p || !v.name) {
reply_with_perror ("allocate");
- free (ret->guestfs_int_dirent_list_val);
- free (p);
+ if (p) {
+ free_int_dirent_list (p, i);
+ } else {
+ free_int_dirent_list (ret->guestfs_int_dirent_list_val, i);
+ }
free (v.name);
free (ret);
closedir (dir);
--
1.9.3
9 years, 11 months
[PATCH] aarch64: launch: libvirt: As a workaround, pass -cpu parameter to qemu.
by Richard W.M. Jones
From: "Richard W.M. Jones" <rjones(a)redhat.com>
When libguestfs is running using TCG on aarch64, we need to pass the
-cpu cortex-a57 parameter to qemu. Libvirt doesn't let us do this,
complaining "Unable to find CPU definition".
As a temporary workaround only, use <qemu:commandline> to pass this
argument directly to qemu. When libvirt is fixed we can remove this
hack.
This is a workaround for libvirt bug RHBZ#1184411.
See:
https://www.redhat.com/archives/libvirt-users/2014-August/msg00043.html
https://bugzilla.redhat.com/show_bug.cgi?id=1184411
---
src/launch-libvirt.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index 7a57f30..ca12320 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -1085,12 +1085,16 @@ construct_libvirt_xml_cpu (guestfs_h *g,
} end_element ();
}
else {
- /* XXX This does not work, see:
+ /* XXX This does not work on aarch64, see:
* https://www.redhat.com/archives/libvirt-users/2014-August/msg00043.html
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1184411
+ * Instead we hack around it using <qemu:commandline> below.
*/
+#ifndef __aarch64__
start_element ("model") {
string (cpu_model);
} end_element ();
+#endif
}
} end_element ();
}
@@ -1728,6 +1732,21 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
}
}
+#ifdef __aarch64__
+ /* This is a temporary hack until RHBZ#1184411 is resolved.
+ * See comments above about cpu model and aarch64.
+ */
+ const char *cpu_model = guestfs___get_cpu_model (params->data->is_kvm);
+ if (STRNEQ (cpu_model, "host")) {
+ start_element ("qemu:arg") {
+ attribute ("value", "-cpu");
+ } end_element ();
+ start_element ("qemu:arg") {
+ attribute ("value", cpu_model);
+ } end_element ();
+ }
+#endif
+
} end_element (); /* </qemu:commandline> */
return 0;
--
1.8.3.1
9 years, 11 months