3 * Copyright (C) 2009-2010 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (* This script generates a large amount of code and documentation for
21 * all the daemon actions.
23 * To add a new action there are only two files you need to change,
24 * this one to describe the interface (see the big table of
25 * 'daemon_functions' below), and daemon/<somefile>.c to write the
28 * After editing this file, run it (./src/generator.ml) to regenerate
29 * all the output files. 'make' will rerun this automatically when
30 * necessary. Note that if you are using a separate build directory
31 * you must run generator.ml from the _source_ directory.
33 * IMPORTANT: This script should NOT print any warnings. If it prints
34 * warnings, you should treat them as errors.
37 * (1) In emacs, install tuareg-mode to display and format OCaml code
38 * correctly. 'vim' comes with a good OCaml editing mode by default.
39 * (2) Read the resources at http://ocaml-tutorial.org/
44 #directory "+xml-light";;
45 #directory "+../pkg-lib/xml-light";; (* for GODI users *)
46 #load "xml-light.cma";;
51 type style = ret * args
53 (* "RErr" as a return value means an int used as a simple error
54 * indication, ie. 0 or -1.
58 (* "RInt" as a return value means an int which is -1 for error
59 * or any value >= 0 on success. Only use this for smallish
60 * positive ints (0 <= i < 2^30).
64 (* "RInt64" is the same as RInt, but is guaranteed to be able
65 * to return a full 64 bit value, _except_ that -1 means error
66 * (so -1 cannot be a valid, non-error return value).
70 (* "RBool" is a bool return value which can be true/false or
75 (* "RConstString" is a string that refers to a constant value.
76 * The return value must NOT be NULL (since NULL indicates
79 * Try to avoid using this. In particular you cannot use this
80 * for values returned from the daemon, because there is no
81 * thread-safe way to return them in the C API.
83 | RConstString of string
85 (* "RConstOptString" is an even more broken version of
86 * "RConstString". The returned string may be NULL and there
87 * is no way to return an error indication. Avoid using this!
89 | RConstOptString of string
91 (* "RString" is a returned string. It must NOT be NULL, since
92 * a NULL return indicates an error. The caller frees this.
96 (* "RStringList" is a list of strings. No string in the list
97 * can be NULL. The caller frees the strings and the array.
99 | RStringList of string
101 (* "RStruct" is a function which returns a single named structure
102 * or an error indication (in C, a struct, and in other languages
103 * with varying representations, but usually very efficient). See
104 * after the function list below for the structures.
106 | RStruct of string * string (* name of retval, name of struct *)
108 (* "RStructList" is a function which returns either a list/array
109 * of structures (could be zero-length), or an error indication.
111 | RStructList of string * string (* name of retval, name of struct *)
113 (* Key-value pairs of untyped strings. Turns into a hashtable or
114 * dictionary in languages which support it. DON'T use this as a
115 * general "bucket" for results. Prefer a stronger typed return
116 * value if one is available, or write a custom struct. Don't use
117 * this if the list could potentially be very long, since it is
118 * inefficient. Keys should be unique. NULLs are not permitted.
120 | RHashtable of string
122 (* "RBufferOut" is handled almost exactly like RString, but
123 * it allows the string to contain arbitrary 8 bit data including
124 * ASCII NUL. In the C API this causes an implicit extra parameter
125 * to be added of type <size_t *size_r>. The extra parameter
126 * returns the actual size of the return buffer in bytes.
128 * Other programming languages support strings with arbitrary 8 bit
131 * At the RPC layer we have to use the opaque<> type instead of
132 * string<>. Returned data is still limited to the max message
135 | RBufferOut of string
137 and args = argt list (* Function parameters, guestfs handle is implicit. *)
139 (* Note in future we should allow a "variable args" parameter as
140 * the final parameter, to allow commands like
141 * chmod mode file [file(s)...]
142 * This is not implemented yet, but many commands (such as chmod)
143 * are currently defined with the argument order keeping this future
144 * possibility in mind.
147 | String of string (* const char *name, cannot be NULL *)
148 | Device of string (* /dev device name, cannot be NULL *)
149 | Pathname of string (* file name, cannot be NULL *)
150 | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *)
151 | OptString of string (* const char *name, may be NULL *)
152 | StringList of string(* list of strings (each string cannot be NULL) *)
153 | DeviceList of string(* list of Device names (each cannot be NULL) *)
154 | Bool of string (* boolean *)
155 | Int of string (* int (smallish ints, signed, <= 31 bits) *)
156 | Int64 of string (* any 64 bit int *)
157 (* These are treated as filenames (simple string parameters) in
158 * the C API and bindings. But in the RPC protocol, we transfer
159 * the actual file content up to or down from the daemon.
160 * FileIn: local machine -> daemon (in request)
161 * FileOut: daemon -> local machine (in reply)
162 * In guestfish (only), the special name "-" means read from
163 * stdin or write to stdout.
167 (* Opaque buffer which can contain arbitrary 8 bit data.
168 * In the C API, this is expressed as <const char *, size_t> pair.
169 * Most other languages have a string type which can contain
170 * ASCII NUL. We use whatever type is appropriate for each
172 * Buffers are limited by the total message size. To transfer
173 * large blocks of data, use FileIn/FileOut parameters instead.
174 * To return an arbitrary buffer, use RBufferOut.
179 | ProtocolLimitWarning (* display warning about protocol size limits *)
180 | DangerWillRobinson (* flags particularly dangerous commands *)
181 | FishAlias of string (* provide an alias for this cmd in guestfish *)
182 | FishOutput of fish_output_t (* how to display output in guestfish *)
183 | NotInFish (* do not export via guestfish *)
184 | NotInDocs (* do not add this function to documentation *)
185 | DeprecatedBy of string (* function is deprecated, use .. instead *)
186 | Optional of string (* function is part of an optional group *)
189 | FishOutputOctal (* for int return, print in octal *)
190 | FishOutputHexadecimal (* for int return, print in hex *)
192 (* You can supply zero or as many tests as you want per API call.
194 * Note that the test environment has 3 block devices, of size 500MB,
195 * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
196 * a fourth ISO block device with some known files on it (/dev/sdd).
198 * Note for partitioning purposes, the 500MB device has 1015 cylinders.
199 * Number of cylinders was 63 for IDE emulated disks with precisely
200 * the same size. How exactly this is calculated is a mystery.
202 * The ISO block device (/dev/sdd) comes from images/test.iso.
204 * To be able to run the tests in a reasonable amount of time,
205 * the virtual machine and block devices are reused between tests.
206 * So don't try testing kill_subprocess :-x
208 * Between each test we blockdev-setrw, umount-all, lvm-remove-all.
210 * Don't assume anything about the previous contents of the block
211 * devices. Use 'Init*' to create some initial scenarios.
213 * You can add a prerequisite clause to any individual test. This
214 * is a run-time check, which, if it fails, causes the test to be
215 * skipped. Useful if testing a command which might not work on
216 * all variations of libguestfs builds. A test that has prerequisite
217 * of 'Always' is run unconditionally.
219 * In addition, packagers can skip individual tests by setting the
220 * environment variables: eg:
221 * SKIP_TEST_<CMD>_<NUM>=1 SKIP_TEST_COMMAND_3=1 (skips test #3 of command)
222 * SKIP_TEST_<CMD>=1 SKIP_TEST_ZEROFREE=1 (skips all zerofree tests)
224 type tests = (test_init * test_prereq * test) list
226 (* Run the command sequence and just expect nothing to fail. *)
229 (* Run the command sequence and expect the output of the final
230 * command to be the string.
232 | TestOutput of seq * string
234 (* Run the command sequence and expect the output of the final
235 * command to be the list of strings.
237 | TestOutputList of seq * string list
239 (* Run the command sequence and expect the output of the final
240 * command to be the list of block devices (could be either
241 * "/dev/sd.." or "/dev/hd.." form - we don't check the 5th
242 * character of each string).
244 | TestOutputListOfDevices of seq * string list
246 (* Run the command sequence and expect the output of the final
247 * command to be the integer.
249 | TestOutputInt of seq * int
251 (* Run the command sequence and expect the output of the final
252 * command to be <op> <int>, eg. ">=", "1".
254 | TestOutputIntOp of seq * string * int
256 (* Run the command sequence and expect the output of the final
257 * command to be a true value (!= 0 or != NULL).
259 | TestOutputTrue of seq
261 (* Run the command sequence and expect the output of the final
262 * command to be a false value (== 0 or == NULL, but not an error).
264 | TestOutputFalse of seq
266 (* Run the command sequence and expect the output of the final
267 * command to be a list of the given length (but don't care about
270 | TestOutputLength of seq * int
272 (* Run the command sequence and expect the output of the final
273 * command to be a buffer (RBufferOut), ie. string + size.
275 | TestOutputBuffer of seq * string
277 (* Run the command sequence and expect the output of the final
278 * command to be a structure.
280 | TestOutputStruct of seq * test_field_compare list
282 (* Run the command sequence and expect the final command (only)
285 | TestLastFail of seq
287 and test_field_compare =
288 | CompareWithInt of string * int
289 | CompareWithIntOp of string * string * int
290 | CompareWithString of string * string
291 | CompareFieldsIntEq of string * string
292 | CompareFieldsStrEq of string * string
294 (* Test prerequisites. *)
296 (* Test always runs. *)
299 (* Test is currently disabled - eg. it fails, or it tests some
300 * unimplemented feature.
304 (* 'string' is some C code (a function body) that should return
305 * true or false. The test will run if the code returns true.
309 (* As for 'If' but the test runs _unless_ the code returns true. *)
312 (* Some initial scenarios for testing. *)
314 (* Do nothing, block devices could contain random stuff including
315 * LVM PVs, and some filesystems might be mounted. This is usually
320 (* Block devices are empty and no filesystems are mounted. *)
323 (* /dev/sda contains a single partition /dev/sda1, with random
324 * content. /dev/sdb and /dev/sdc may have random content.
329 (* /dev/sda contains a single partition /dev/sda1, which is formatted
330 * as ext2, empty [except for lost+found] and mounted on /.
331 * /dev/sdb and /dev/sdc may have random content.
337 * /dev/sda1 (is a PV):
338 * /dev/VG/LV (size 8MB):
339 * formatted as ext2, empty [except for lost+found], mounted on /
340 * /dev/sdb and /dev/sdc may have random content.
344 (* /dev/sdd (the ISO, see images/ directory in source)
349 (* Sequence of commands for testing. *)
351 and cmd = string list
353 (* Note about long descriptions: When referring to another
354 * action, use the format C<guestfs_other> (ie. the full name of
355 * the C function). This will be replaced as appropriate in other
358 * Apart from that, long descriptions are just perldoc paragraphs.
361 (* Generate a random UUID (used in tests). *)
363 let chan = open_process_in "uuidgen" in
364 let uuid = input_line chan in
365 (match close_process_in chan with
368 failwith "uuidgen: process exited with non-zero status"
369 | WSIGNALED _ | WSTOPPED _ ->
370 failwith "uuidgen: process signalled or stopped by signal"
374 (* These test functions are used in the language binding tests. *)
376 let test_all_args = [
379 StringList "strlist";
388 let test_all_rets = [
389 (* except for RErr, which is tested thoroughly elsewhere *)
390 "test0rint", RInt "valout";
391 "test0rint64", RInt64 "valout";
392 "test0rbool", RBool "valout";
393 "test0rconststring", RConstString "valout";
394 "test0rconstoptstring", RConstOptString "valout";
395 "test0rstring", RString "valout";
396 "test0rstringlist", RStringList "valout";
397 "test0rstruct", RStruct ("valout", "lvm_pv");
398 "test0rstructlist", RStructList ("valout", "lvm_pv");
399 "test0rhashtable", RHashtable "valout";
402 let test_functions = [
403 ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
405 "internal test function - do not use",
407 This is an internal test function which is used to test whether
408 the automatically generated bindings can handle every possible
409 parameter type correctly.
411 It echos the contents of each parameter to stdout.
413 You probably don't want to call this function.");
417 [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
419 "internal test function - do not use",
421 This is an internal test function which is used to test whether
422 the automatically generated bindings can handle every possible
423 return type correctly.
425 It converts string C<val> to the return type.
427 You probably don't want to call this function.");
428 (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
430 "internal test function - do not use",
432 This is an internal test function which is used to test whether
433 the automatically generated bindings can handle every possible
434 return type correctly.
436 This function always returns an error.
438 You probably don't want to call this function.")]
442 (* non_daemon_functions are any functions which don't get processed
443 * in the daemon, eg. functions for setting and getting local
444 * configuration values.
447 let non_daemon_functions = test_functions @ [
448 ("launch", (RErr, []), -1, [FishAlias "run"],
450 "launch the qemu subprocess",
452 Internally libguestfs is implemented by running a virtual machine
455 You should call this after configuring the handle
456 (eg. adding drives) but before performing any actions.");
458 ("wait_ready", (RErr, []), -1, [NotInFish],
460 "wait until the qemu subprocess launches (no op)",
462 This function is a no op.
464 In versions of the API E<lt> 1.0.71 you had to call this function
465 just after calling C<guestfs_launch> to wait for the launch
466 to complete. However this is no longer necessary because
467 C<guestfs_launch> now does the waiting.
469 If you see any calls to this function in code then you can just
470 remove them, unless you want to retain compatibility with older
471 versions of the API.");
473 ("kill_subprocess", (RErr, []), -1, [],
475 "kill the qemu subprocess",
477 This kills the qemu subprocess. You should never need to call this.");
479 ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
481 "add an image to examine or modify",
483 This function adds a virtual machine disk image C<filename> to the
484 guest. The first time you call this function, the disk appears as IDE
485 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
488 You don't necessarily need to be root when using libguestfs. However
489 you obviously do need sufficient permissions to access the filename
490 for whatever operations you want to perform (ie. read access if you
491 just want to read the image or write access if you want to modify the
494 This is equivalent to the qemu parameter
495 C<-drive file=filename,cache=off,if=...>.
497 C<cache=off> is omitted in cases where it is not supported by
498 the underlying filesystem.
500 C<if=...> is set at compile time by the configuration option
501 C<./configure --with-drive-if=...>. In the rare case where you
502 might need to change this at run time, use C<guestfs_add_drive_with_if>
503 or C<guestfs_add_drive_ro_with_if>.
505 Note that this call checks for the existence of C<filename>. This
506 stops you from specifying other types of drive which are supported
507 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
508 the general C<guestfs_config> call instead.");
510 ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
512 "add a CD-ROM disk image to examine",
514 This function adds a virtual CD-ROM disk image to the guest.
516 This is equivalent to the qemu parameter C<-cdrom filename>.
524 This call checks for the existence of C<filename>. This
525 stops you from specifying other types of drive which are supported
526 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
527 the general C<guestfs_config> call instead.
531 If you just want to add an ISO file (often you use this as an
532 efficient way to transfer large files into the guest), then you
533 should probably use C<guestfs_add_drive_ro> instead.
537 ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
539 "add a drive in snapshot mode (read-only)",
541 This adds a drive in snapshot mode, making it effectively
544 Note that writes to the device are allowed, and will be seen for
545 the duration of the guestfs handle, but they are written
546 to a temporary file which is discarded as soon as the guestfs
547 handle is closed. We don't currently have any method to enable
548 changes to be committed, although qemu can support this.
550 This is equivalent to the qemu parameter
551 C<-drive file=filename,snapshot=on,readonly=on,if=...>.
553 C<if=...> is set at compile time by the configuration option
554 C<./configure --with-drive-if=...>. In the rare case where you
555 might need to change this at run time, use C<guestfs_add_drive_with_if>
556 or C<guestfs_add_drive_ro_with_if>.
558 C<readonly=on> is only added where qemu supports this option.
560 Note that this call checks for the existence of C<filename>. This
561 stops you from specifying other types of drive which are supported
562 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
563 the general C<guestfs_config> call instead.");
565 ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
567 "add qemu parameters",
569 This can be used to add arbitrary qemu command line parameters
570 of the form C<-param value>. Actually it's not quite arbitrary - we
571 prevent you from setting some parameters which would interfere with
572 parameters that we use.
574 The first character of C<param> string must be a C<-> (dash).
576 C<value> can be NULL.");
578 ("set_qemu", (RErr, [OptString "qemu"]), -1, [FishAlias "qemu"],
580 "set the qemu binary",
582 Set the qemu binary that we will use.
584 The default is chosen when the library was compiled by the
587 You can also override this by setting the C<LIBGUESTFS_QEMU>
588 environment variable.
590 Setting C<qemu> to C<NULL> restores the default qemu binary.
592 Note that you should call this function as early as possible
593 after creating the handle. This is because some pre-launch
594 operations depend on testing qemu features (by running C<qemu -help>).
595 If the qemu binary changes, we don't retest features, and
596 so you might see inconsistent results. Using the environment
597 variable C<LIBGUESTFS_QEMU> is safest of all since that picks
598 the qemu binary at the same time as the handle is created.");
600 ("get_qemu", (RConstString "qemu", []), -1, [],
601 [InitNone, Always, TestRun (
603 "get the qemu binary",
605 Return the current qemu binary.
607 This is always non-NULL. If it wasn't set already, then this will
608 return the default qemu binary name.");
610 ("set_path", (RErr, [OptString "searchpath"]), -1, [FishAlias "path"],
612 "set the search path",
614 Set the path that libguestfs searches for kernel and initrd.img.
616 The default is C<$libdir/guestfs> unless overridden by setting
617 C<LIBGUESTFS_PATH> environment variable.
619 Setting C<path> to C<NULL> restores the default path.");
621 ("get_path", (RConstString "path", []), -1, [],
622 [InitNone, Always, TestRun (
624 "get the search path",
626 Return the current search path.
628 This is always non-NULL. If it wasn't set already, then this will
629 return the default path.");
631 ("set_append", (RErr, [OptString "append"]), -1, [FishAlias "append"],
633 "add options to kernel command line",
635 This function is used to add additional options to the
636 guest kernel command line.
638 The default is C<NULL> unless overridden by setting
639 C<LIBGUESTFS_APPEND> environment variable.
641 Setting C<append> to C<NULL> means I<no> additional options
642 are passed (libguestfs always adds a few of its own).");
644 ("get_append", (RConstOptString "append", []), -1, [],
645 (* This cannot be tested with the current framework. The
646 * function can return NULL in normal operations, which the
647 * test framework interprets as an error.
650 "get the additional kernel options",
652 Return the additional kernel options which are added to the
653 guest kernel command line.
655 If C<NULL> then no options are added.");
657 ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
661 If C<autosync> is true, this enables autosync. Libguestfs will make a
662 best effort attempt to run C<guestfs_umount_all> followed by
663 C<guestfs_sync> when the handle is closed
664 (also if the program exits without closing handles).
666 This is disabled by default (except in guestfish where it is
667 enabled by default).");
669 ("get_autosync", (RBool "autosync", []), -1, [],
670 [InitNone, Always, TestRun (
671 [["get_autosync"]])],
674 Get the autosync flag.");
676 ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
680 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
682 Verbose messages are disabled unless the environment variable
683 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
685 ("get_verbose", (RBool "verbose", []), -1, [],
689 This returns the verbose messages flag.");
691 ("is_ready", (RBool "ready", []), -1, [],
692 [InitNone, Always, TestOutputTrue (
694 "is ready to accept commands",
696 This returns true iff this handle is ready to accept commands
697 (in the C<READY> state).
699 For more information on states, see L<guestfs(3)>.");
701 ("is_config", (RBool "config", []), -1, [],
702 [InitNone, Always, TestOutputFalse (
704 "is in configuration state",
706 This returns true iff this handle is being configured
707 (in the C<CONFIG> state).
709 For more information on states, see L<guestfs(3)>.");
711 ("is_launching", (RBool "launching", []), -1, [],
712 [InitNone, Always, TestOutputFalse (
713 [["is_launching"]])],
714 "is launching subprocess",
716 This returns true iff this handle is launching the subprocess
717 (in the C<LAUNCHING> state).
719 For more information on states, see L<guestfs(3)>.");
721 ("is_busy", (RBool "busy", []), -1, [],
722 [InitNone, Always, TestOutputFalse (
724 "is busy processing a command",
726 This returns true iff this handle is busy processing a command
727 (in the C<BUSY> state).
729 For more information on states, see L<guestfs(3)>.");
731 ("get_state", (RInt "state", []), -1, [],
733 "get the current state",
735 This returns the current state as an opaque integer. This is
736 only useful for printing debug and internal error messages.
738 For more information on states, see L<guestfs(3)>.");
740 ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
741 [InitNone, Always, TestOutputInt (
742 [["set_memsize"; "500"];
743 ["get_memsize"]], 500)],
744 "set memory allocated to the qemu subprocess",
746 This sets the memory size in megabytes allocated to the
747 qemu subprocess. This only has any effect if called before
750 You can also change this by setting the environment
751 variable C<LIBGUESTFS_MEMSIZE> before the handle is
754 For more information on the architecture of libguestfs,
755 see L<guestfs(3)>.");
757 ("get_memsize", (RInt "memsize", []), -1, [],
758 [InitNone, Always, TestOutputIntOp (
759 [["get_memsize"]], ">=", 256)],
760 "get memory allocated to the qemu subprocess",
762 This gets the memory size in megabytes allocated to the
765 If C<guestfs_set_memsize> was not called
766 on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
767 then this returns the compiled-in default value for memsize.
769 For more information on the architecture of libguestfs,
770 see L<guestfs(3)>.");
772 ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"],
773 [InitNone, Always, TestOutputIntOp (
774 [["get_pid"]], ">=", 1)],
775 "get PID of qemu subprocess",
777 Return the process ID of the qemu subprocess. If there is no
778 qemu subprocess, then this will return an error.
780 This is an internal call used for debugging and testing.");
782 ("version", (RStruct ("version", "version"), []), -1, [],
783 [InitNone, Always, TestOutputStruct (
784 [["version"]], [CompareWithInt ("major", 1)])],
785 "get the library version number",
787 Return the libguestfs version number that the program is linked
790 Note that because of dynamic linking this is not necessarily
791 the version of libguestfs that you compiled against. You can
792 compile the program, and then at runtime dynamically link
793 against a completely different C<libguestfs.so> library.
795 This call was added in version C<1.0.58>. In previous
796 versions of libguestfs there was no way to get the version
797 number. From C code you can use dynamic linker functions
798 to find out if this symbol exists (if it doesn't, then
799 it's an earlier version).
801 The call returns a structure with four elements. The first
802 three (C<major>, C<minor> and C<release>) are numbers and
803 correspond to the usual version triplet. The fourth element
804 (C<extra>) is a string and is normally empty, but may be
805 used for distro-specific information.
807 To construct the original version string:
808 C<$major.$minor.$release$extra>
810 See also: L<guestfs(3)/LIBGUESTFS VERSION NUMBERS>.
812 I<Note:> Don't use this call to test for availability
813 of features. In enterprise distributions we backport
814 features from later versions into earlier versions,
815 making this an unreliable way to test for features.
816 Use C<guestfs_available> instead.");
818 ("set_selinux", (RErr, [Bool "selinux"]), -1, [FishAlias "selinux"],
819 [InitNone, Always, TestOutputTrue (
820 [["set_selinux"; "true"];
822 "set SELinux enabled or disabled at appliance boot",
824 This sets the selinux flag that is passed to the appliance
825 at boot time. The default is C<selinux=0> (disabled).
827 Note that if SELinux is enabled, it is always in
828 Permissive mode (C<enforcing=0>).
830 For more information on the architecture of libguestfs,
831 see L<guestfs(3)>.");
833 ("get_selinux", (RBool "selinux", []), -1, [],
835 "get SELinux enabled flag",
837 This returns the current setting of the selinux flag which
838 is passed to the appliance at boot time. See C<guestfs_set_selinux>.
840 For more information on the architecture of libguestfs,
841 see L<guestfs(3)>.");
843 ("set_trace", (RErr, [Bool "trace"]), -1, [FishAlias "trace"],
844 [InitNone, Always, TestOutputFalse (
845 [["set_trace"; "false"];
847 "enable or disable command traces",
849 If the command trace flag is set to 1, then commands are
850 printed on stdout before they are executed in a format
851 which is very similar to the one used by guestfish. In
852 other words, you can run a program with this enabled, and
853 you will get out a script which you can feed to guestfish
854 to perform the same set of actions.
856 If you want to trace C API calls into libguestfs (and
857 other libraries) then possibly a better way is to use
858 the external ltrace(1) command.
860 Command traces are disabled unless the environment variable
861 C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
863 ("get_trace", (RBool "trace", []), -1, [],
865 "get command trace enabled flag",
867 Return the command trace flag.");
869 ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"],
870 [InitNone, Always, TestOutputFalse (
871 [["set_direct"; "false"];
873 "enable or disable direct appliance mode",
875 If the direct appliance mode flag is enabled, then stdin and
876 stdout are passed directly through to the appliance once it
879 One consequence of this is that log messages aren't caught
880 by the library and handled by C<guestfs_set_log_message_callback>,
881 but go straight to stdout.
883 You probably don't want to use this unless you know what you
886 The default is disabled.");
888 ("get_direct", (RBool "direct", []), -1, [],
890 "get direct appliance mode flag",
892 Return the direct appliance mode flag.");
894 ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"],
895 [InitNone, Always, TestOutputTrue (
896 [["set_recovery_proc"; "true"];
897 ["get_recovery_proc"]])],
898 "enable or disable the recovery process",
900 If this is called with the parameter C<false> then
901 C<guestfs_launch> does not create a recovery process. The
902 purpose of the recovery process is to stop runaway qemu
903 processes in the case where the main program aborts abruptly.
905 This only has any effect if called before C<guestfs_launch>,
906 and the default is true.
908 About the only time when you would want to disable this is
909 if the main process will fork itself into the background
910 (\"daemonize\" itself). In this case the recovery process
911 thinks that the main program has disappeared and so kills
912 qemu, which is not very helpful.");
914 ("get_recovery_proc", (RBool "recoveryproc", []), -1, [],
916 "get recovery process enabled flag",
918 Return the recovery process enabled flag.");
920 ("add_drive_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
922 "add a drive specifying the QEMU block emulation to use",
924 This is the same as C<guestfs_add_drive> but it allows you
925 to specify the QEMU interface emulation to use at run time.");
927 ("add_drive_ro_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
929 "add a drive read-only specifying the QEMU block emulation to use",
931 This is the same as C<guestfs_add_drive_ro> but it allows you
932 to specify the QEMU interface emulation to use at run time.");
936 (* daemon_functions are any functions which cause some action
937 * to take place in the daemon.
940 let daemon_functions = [
941 ("mount", (RErr, [Device "device"; String "mountpoint"]), 1, [],
942 [InitEmpty, Always, TestOutput (
943 [["part_disk"; "/dev/sda"; "mbr"];
944 ["mkfs"; "ext2"; "/dev/sda1"];
945 ["mount"; "/dev/sda1"; "/"];
946 ["write"; "/new"; "new file contents"];
947 ["cat"; "/new"]], "new file contents")],
948 "mount a guest disk at a position in the filesystem",
950 Mount a guest disk at a position in the filesystem. Block devices
951 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
952 the guest. If those block devices contain partitions, they will have
953 the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style
956 The rules are the same as for L<mount(2)>: A filesystem must
957 first be mounted on C</> before others can be mounted. Other
958 filesystems can only be mounted on directories which already
961 The mounted filesystem is writable, if we have sufficient permissions
962 on the underlying device.
965 When you use this call, the filesystem options C<sync> and C<noatime>
966 are set implicitly. This was originally done because we thought it
967 would improve reliability, but it turns out that I<-o sync> has a
968 very large negative performance impact and negligible effect on
969 reliability. Therefore we recommend that you avoid using
970 C<guestfs_mount> in any code that needs performance, and instead
971 use C<guestfs_mount_options> (use an empty string for the first
972 parameter if you don't want any options).");
974 ("sync", (RErr, []), 2, [],
975 [ InitEmpty, Always, TestRun [["sync"]]],
976 "sync disks, writes are flushed through to the disk image",
978 This syncs the disk, so that any writes are flushed through to the
979 underlying disk image.
981 You should always call this if you have modified a disk image, before
982 closing the handle.");
984 ("touch", (RErr, [Pathname "path"]), 3, [],
985 [InitBasicFS, Always, TestOutputTrue (
987 ["exists"; "/new"]])],
988 "update file timestamps or create a new file",
990 Touch acts like the L<touch(1)> command. It can be used to
991 update the timestamps on a file, or, if the file does not exist,
992 to create a new zero-length file.");
994 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
995 [InitISOFS, Always, TestOutput (
996 [["cat"; "/known-2"]], "abcdef\n")],
997 "list the contents of a file",
999 Return the contents of the file named C<path>.
1001 Note that this function cannot correctly handle binary files
1002 (specifically, files containing C<\\0> character which is treated
1003 as end of string). For those you need to use the C<guestfs_read_file>
1004 or C<guestfs_download> functions which have a more complex interface.");
1006 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
1007 [], (* XXX Tricky to test because it depends on the exact format
1008 * of the 'ls -l' command, which changes between F10 and F11.
1010 "list the files in a directory (long format)",
1012 List the files in C<directory> (relative to the root directory,
1013 there is no cwd) in the format of 'ls -la'.
1015 This command is mostly useful for interactive sessions. It
1016 is I<not> intended that you try to parse the output string.");
1018 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
1019 [InitBasicFS, Always, TestOutputList (
1021 ["touch"; "/newer"];
1022 ["touch"; "/newest"];
1023 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
1024 "list the files in a directory",
1026 List the files in C<directory> (relative to the root directory,
1027 there is no cwd). The '.' and '..' entries are not returned, but
1028 hidden files are shown.
1030 This command is mostly useful for interactive sessions. Programs
1031 should probably use C<guestfs_readdir> instead.");
1033 ("list_devices", (RStringList "devices", []), 7, [],
1034 [InitEmpty, Always, TestOutputListOfDevices (
1035 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
1036 "list the block devices",
1038 List all the block devices.
1040 The full block device names are returned, eg. C</dev/sda>");
1042 ("list_partitions", (RStringList "partitions", []), 8, [],
1043 [InitBasicFS, Always, TestOutputListOfDevices (
1044 [["list_partitions"]], ["/dev/sda1"]);
1045 InitEmpty, Always, TestOutputListOfDevices (
1046 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1047 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1048 "list the partitions",
1050 List all the partitions detected on all block devices.
1052 The full partition device names are returned, eg. C</dev/sda1>
1054 This does not return logical volumes. For that you will need to
1055 call C<guestfs_lvs>.");
1057 ("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
1058 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
1059 [["pvs"]], ["/dev/sda1"]);
1060 InitEmpty, Always, TestOutputListOfDevices (
1061 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1062 ["pvcreate"; "/dev/sda1"];
1063 ["pvcreate"; "/dev/sda2"];
1064 ["pvcreate"; "/dev/sda3"];
1065 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1066 "list the LVM physical volumes (PVs)",
1068 List all the physical volumes detected. This is the equivalent
1069 of the L<pvs(8)> command.
1071 This returns a list of just the device names that contain
1072 PVs (eg. C</dev/sda2>).
1074 See also C<guestfs_pvs_full>.");
1076 ("vgs", (RStringList "volgroups", []), 10, [Optional "lvm2"],
1077 [InitBasicFSonLVM, Always, TestOutputList (
1079 InitEmpty, Always, TestOutputList (
1080 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1081 ["pvcreate"; "/dev/sda1"];
1082 ["pvcreate"; "/dev/sda2"];
1083 ["pvcreate"; "/dev/sda3"];
1084 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1085 ["vgcreate"; "VG2"; "/dev/sda3"];
1086 ["vgs"]], ["VG1"; "VG2"])],
1087 "list the LVM volume groups (VGs)",
1089 List all the volumes groups detected. This is the equivalent
1090 of the L<vgs(8)> command.
1092 This returns a list of just the volume group names that were
1093 detected (eg. C<VolGroup00>).
1095 See also C<guestfs_vgs_full>.");
1097 ("lvs", (RStringList "logvols", []), 11, [Optional "lvm2"],
1098 [InitBasicFSonLVM, Always, TestOutputList (
1099 [["lvs"]], ["/dev/VG/LV"]);
1100 InitEmpty, Always, TestOutputList (
1101 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1102 ["pvcreate"; "/dev/sda1"];
1103 ["pvcreate"; "/dev/sda2"];
1104 ["pvcreate"; "/dev/sda3"];
1105 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1106 ["vgcreate"; "VG2"; "/dev/sda3"];
1107 ["lvcreate"; "LV1"; "VG1"; "50"];
1108 ["lvcreate"; "LV2"; "VG1"; "50"];
1109 ["lvcreate"; "LV3"; "VG2"; "50"];
1110 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1111 "list the LVM logical volumes (LVs)",
1113 List all the logical volumes detected. This is the equivalent
1114 of the L<lvs(8)> command.
1116 This returns a list of the logical volume device names
1117 (eg. C</dev/VolGroup00/LogVol00>).
1119 See also C<guestfs_lvs_full>.");
1121 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
1122 [], (* XXX how to test? *)
1123 "list the LVM physical volumes (PVs)",
1125 List all the physical volumes detected. This is the equivalent
1126 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1128 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [Optional "lvm2"],
1129 [], (* XXX how to test? *)
1130 "list the LVM volume groups (VGs)",
1132 List all the volumes groups detected. This is the equivalent
1133 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1135 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [Optional "lvm2"],
1136 [], (* XXX how to test? *)
1137 "list the LVM logical volumes (LVs)",
1139 List all the logical volumes detected. This is the equivalent
1140 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1142 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1143 [InitISOFS, Always, TestOutputList (
1144 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1145 InitISOFS, Always, TestOutputList (
1146 [["read_lines"; "/empty"]], [])],
1147 "read file as lines",
1149 Return the contents of the file named C<path>.
1151 The file contents are returned as a list of lines. Trailing
1152 C<LF> and C<CRLF> character sequences are I<not> returned.
1154 Note that this function cannot correctly handle binary files
1155 (specifically, files containing C<\\0> character which is treated
1156 as end of line). For those you need to use the C<guestfs_read_file>
1157 function which has a more complex interface.");
1159 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [Optional "augeas"],
1160 [], (* XXX Augeas code needs tests. *)
1161 "create a new Augeas handle",
1163 Create a new Augeas handle for editing configuration files.
1164 If there was any previous Augeas handle associated with this
1165 guestfs session, then it is closed.
1167 You must call this before using any other C<guestfs_aug_*>
1170 C<root> is the filesystem root. C<root> must not be NULL,
1173 The flags are the same as the flags defined in
1174 E<lt>augeas.hE<gt>, the logical I<or> of the following
1179 =item C<AUG_SAVE_BACKUP> = 1
1181 Keep the original file with a C<.augsave> extension.
1183 =item C<AUG_SAVE_NEWFILE> = 2
1185 Save changes into a file with extension C<.augnew>, and
1186 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1188 =item C<AUG_TYPE_CHECK> = 4
1190 Typecheck lenses (can be expensive).
1192 =item C<AUG_NO_STDINC> = 8
1194 Do not use standard load path for modules.
1196 =item C<AUG_SAVE_NOOP> = 16
1198 Make save a no-op, just record what would have been changed.
1200 =item C<AUG_NO_LOAD> = 32
1202 Do not load the tree in C<guestfs_aug_init>.
1206 To close the handle, you can call C<guestfs_aug_close>.
1208 To find out more about Augeas, see L<http://augeas.net/>.");
1210 ("aug_close", (RErr, []), 26, [Optional "augeas"],
1211 [], (* XXX Augeas code needs tests. *)
1212 "close the current Augeas handle",
1214 Close the current Augeas handle and free up any resources
1215 used by it. After calling this, you have to call
1216 C<guestfs_aug_init> again before you can use any other
1217 Augeas functions.");
1219 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [Optional "augeas"],
1220 [], (* XXX Augeas code needs tests. *)
1221 "define an Augeas variable",
1223 Defines an Augeas variable C<name> whose value is the result
1224 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1227 On success this returns the number of nodes in C<expr>, or
1228 C<0> if C<expr> evaluates to something which is not a nodeset.");
1230 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [Optional "augeas"],
1231 [], (* XXX Augeas code needs tests. *)
1232 "define an Augeas node",
1234 Defines a variable C<name> whose value is the result of
1237 If C<expr> evaluates to an empty nodeset, a node is created,
1238 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1239 C<name> will be the nodeset containing that single node.
1241 On success this returns a pair containing the
1242 number of nodes in the nodeset, and a boolean flag
1243 if a node was created.");
1245 ("aug_get", (RString "val", [String "augpath"]), 19, [Optional "augeas"],
1246 [], (* XXX Augeas code needs tests. *)
1247 "look up the value of an Augeas path",
1249 Look up the value associated with C<path>. If C<path>
1250 matches exactly one node, the C<value> is returned.");
1252 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [Optional "augeas"],
1253 [], (* XXX Augeas code needs tests. *)
1254 "set Augeas path to value",
1256 Set the value associated with C<path> to C<val>.
1258 In the Augeas API, it is possible to clear a node by setting
1259 the value to NULL. Due to an oversight in the libguestfs API
1260 you cannot do that with this call. Instead you must use the
1261 C<guestfs_aug_clear> call.");
1263 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [Optional "augeas"],
1264 [], (* XXX Augeas code needs tests. *)
1265 "insert a sibling Augeas node",
1267 Create a new sibling C<label> for C<path>, inserting it into
1268 the tree before or after C<path> (depending on the boolean
1271 C<path> must match exactly one existing node in the tree, and
1272 C<label> must be a label, ie. not contain C</>, C<*> or end
1273 with a bracketed index C<[N]>.");
1275 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [Optional "augeas"],
1276 [], (* XXX Augeas code needs tests. *)
1277 "remove an Augeas path",
1279 Remove C<path> and all of its children.
1281 On success this returns the number of entries which were removed.");
1283 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [Optional "augeas"],
1284 [], (* XXX Augeas code needs tests. *)
1287 Move the node C<src> to C<dest>. C<src> must match exactly
1288 one node. C<dest> is overwritten if it exists.");
1290 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [Optional "augeas"],
1291 [], (* XXX Augeas code needs tests. *)
1292 "return Augeas nodes which match augpath",
1294 Returns a list of paths which match the path expression C<path>.
1295 The returned paths are sufficiently qualified so that they match
1296 exactly one node in the current tree.");
1298 ("aug_save", (RErr, []), 25, [Optional "augeas"],
1299 [], (* XXX Augeas code needs tests. *)
1300 "write all pending Augeas changes to disk",
1302 This writes all pending changes to disk.
1304 The flags which were passed to C<guestfs_aug_init> affect exactly
1305 how files are saved.");
1307 ("aug_load", (RErr, []), 27, [Optional "augeas"],
1308 [], (* XXX Augeas code needs tests. *)
1309 "load files into the tree",
1311 Load files into the tree.
1313 See C<aug_load> in the Augeas documentation for the full gory
1316 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [Optional "augeas"],
1317 [], (* XXX Augeas code needs tests. *)
1318 "list Augeas nodes under augpath",
1320 This is just a shortcut for listing C<guestfs_aug_match>
1321 C<path/*> and sorting the resulting nodes into alphabetical order.");
1323 ("rm", (RErr, [Pathname "path"]), 29, [],
1324 [InitBasicFS, Always, TestRun
1327 InitBasicFS, Always, TestLastFail
1329 InitBasicFS, Always, TestLastFail
1334 Remove the single file C<path>.");
1336 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1337 [InitBasicFS, Always, TestRun
1340 InitBasicFS, Always, TestLastFail
1341 [["rmdir"; "/new"]];
1342 InitBasicFS, Always, TestLastFail
1344 ["rmdir"; "/new"]]],
1345 "remove a directory",
1347 Remove the single directory C<path>.");
1349 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1350 [InitBasicFS, Always, TestOutputFalse
1352 ["mkdir"; "/new/foo"];
1353 ["touch"; "/new/foo/bar"];
1355 ["exists"; "/new"]]],
1356 "remove a file or directory recursively",
1358 Remove the file or directory C<path>, recursively removing the
1359 contents if its a directory. This is like the C<rm -rf> shell
1362 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1363 [InitBasicFS, Always, TestOutputTrue
1365 ["is_dir"; "/new"]];
1366 InitBasicFS, Always, TestLastFail
1367 [["mkdir"; "/new/foo/bar"]]],
1368 "create a directory",
1370 Create a directory named C<path>.");
1372 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1373 [InitBasicFS, Always, TestOutputTrue
1374 [["mkdir_p"; "/new/foo/bar"];
1375 ["is_dir"; "/new/foo/bar"]];
1376 InitBasicFS, Always, TestOutputTrue
1377 [["mkdir_p"; "/new/foo/bar"];
1378 ["is_dir"; "/new/foo"]];
1379 InitBasicFS, Always, TestOutputTrue
1380 [["mkdir_p"; "/new/foo/bar"];
1381 ["is_dir"; "/new"]];
1382 (* Regression tests for RHBZ#503133: *)
1383 InitBasicFS, Always, TestRun
1385 ["mkdir_p"; "/new"]];
1386 InitBasicFS, Always, TestLastFail
1388 ["mkdir_p"; "/new"]]],
1389 "create a directory and parents",
1391 Create a directory named C<path>, creating any parent directories
1392 as necessary. This is like the C<mkdir -p> shell command.");
1394 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1395 [], (* XXX Need stat command to test *)
1398 Change the mode (permissions) of C<path> to C<mode>. Only
1399 numeric modes are supported.
1401 I<Note>: When using this command from guestfish, C<mode>
1402 by default would be decimal, unless you prefix it with
1403 C<0> to get octal, ie. use C<0700> not C<700>.
1405 The mode actually set is affected by the umask.");
1407 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1408 [], (* XXX Need stat command to test *)
1409 "change file owner and group",
1411 Change the file owner to C<owner> and group to C<group>.
1413 Only numeric uid and gid are supported. If you want to use
1414 names, you will need to locate and parse the password file
1415 yourself (Augeas support makes this relatively easy).");
1417 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1418 [InitISOFS, Always, TestOutputTrue (
1419 [["exists"; "/empty"]]);
1420 InitISOFS, Always, TestOutputTrue (
1421 [["exists"; "/directory"]])],
1422 "test if file or directory exists",
1424 This returns C<true> if and only if there is a file, directory
1425 (or anything) with the given C<path> name.
1427 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1429 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1430 [InitISOFS, Always, TestOutputTrue (
1431 [["is_file"; "/known-1"]]);
1432 InitISOFS, Always, TestOutputFalse (
1433 [["is_file"; "/directory"]])],
1434 "test if file exists",
1436 This returns C<true> if and only if there is a file
1437 with the given C<path> name. Note that it returns false for
1438 other objects like directories.
1440 See also C<guestfs_stat>.");
1442 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1443 [InitISOFS, Always, TestOutputFalse (
1444 [["is_dir"; "/known-3"]]);
1445 InitISOFS, Always, TestOutputTrue (
1446 [["is_dir"; "/directory"]])],
1447 "test if file exists",
1449 This returns C<true> if and only if there is a directory
1450 with the given C<path> name. Note that it returns false for
1451 other objects like files.
1453 See also C<guestfs_stat>.");
1455 ("pvcreate", (RErr, [Device "device"]), 39, [Optional "lvm2"],
1456 [InitEmpty, Always, TestOutputListOfDevices (
1457 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1458 ["pvcreate"; "/dev/sda1"];
1459 ["pvcreate"; "/dev/sda2"];
1460 ["pvcreate"; "/dev/sda3"];
1461 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1462 "create an LVM physical volume",
1464 This creates an LVM physical volume on the named C<device>,
1465 where C<device> should usually be a partition name such
1468 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [Optional "lvm2"],
1469 [InitEmpty, Always, TestOutputList (
1470 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1471 ["pvcreate"; "/dev/sda1"];
1472 ["pvcreate"; "/dev/sda2"];
1473 ["pvcreate"; "/dev/sda3"];
1474 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1475 ["vgcreate"; "VG2"; "/dev/sda3"];
1476 ["vgs"]], ["VG1"; "VG2"])],
1477 "create an LVM volume group",
1479 This creates an LVM volume group called C<volgroup>
1480 from the non-empty list of physical volumes C<physvols>.");
1482 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [Optional "lvm2"],
1483 [InitEmpty, Always, TestOutputList (
1484 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1485 ["pvcreate"; "/dev/sda1"];
1486 ["pvcreate"; "/dev/sda2"];
1487 ["pvcreate"; "/dev/sda3"];
1488 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1489 ["vgcreate"; "VG2"; "/dev/sda3"];
1490 ["lvcreate"; "LV1"; "VG1"; "50"];
1491 ["lvcreate"; "LV2"; "VG1"; "50"];
1492 ["lvcreate"; "LV3"; "VG2"; "50"];
1493 ["lvcreate"; "LV4"; "VG2"; "50"];
1494 ["lvcreate"; "LV5"; "VG2"; "50"];
1496 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1497 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1498 "create an LVM logical volume",
1500 This creates an LVM logical volume called C<logvol>
1501 on the volume group C<volgroup>, with C<size> megabytes.");
1503 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1504 [InitEmpty, Always, TestOutput (
1505 [["part_disk"; "/dev/sda"; "mbr"];
1506 ["mkfs"; "ext2"; "/dev/sda1"];
1507 ["mount_options"; ""; "/dev/sda1"; "/"];
1508 ["write"; "/new"; "new file contents"];
1509 ["cat"; "/new"]], "new file contents")],
1510 "make a filesystem",
1512 This creates a filesystem on C<device> (usually a partition
1513 or LVM logical volume). The filesystem type is C<fstype>, for
1516 ("sfdisk", (RErr, [Device "device";
1517 Int "cyls"; Int "heads"; Int "sectors";
1518 StringList "lines"]), 43, [DangerWillRobinson],
1520 "create partitions on a block device",
1522 This is a direct interface to the L<sfdisk(8)> program for creating
1523 partitions on block devices.
1525 C<device> should be a block device, for example C</dev/sda>.
1527 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1528 and sectors on the device, which are passed directly to sfdisk as
1529 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1530 of these, then the corresponding parameter is omitted. Usually for
1531 'large' disks, you can just pass C<0> for these, but for small
1532 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1533 out the right geometry and you will need to tell it.
1535 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1536 information refer to the L<sfdisk(8)> manpage.
1538 To create a single partition occupying the whole disk, you would
1539 pass C<lines> as a single element list, when the single element being
1540 the string C<,> (comma).
1542 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1543 C<guestfs_part_init>");
1545 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning; DeprecatedBy "write"],
1549 This call creates a file called C<path>. The contents of the
1550 file is the string C<content> (which can contain any 8 bit data),
1551 with length C<size>.
1553 As a special case, if C<size> is C<0>
1554 then the length is calculated using C<strlen> (so in this case
1555 the content cannot contain embedded ASCII NULs).
1557 I<NB.> Owing to a bug, writing content containing ASCII NUL
1558 characters does I<not> work, even if the length is specified.");
1560 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1561 [InitEmpty, Always, TestOutputListOfDevices (
1562 [["part_disk"; "/dev/sda"; "mbr"];
1563 ["mkfs"; "ext2"; "/dev/sda1"];
1564 ["mount_options"; ""; "/dev/sda1"; "/"];
1565 ["mounts"]], ["/dev/sda1"]);
1566 InitEmpty, Always, TestOutputList (
1567 [["part_disk"; "/dev/sda"; "mbr"];
1568 ["mkfs"; "ext2"; "/dev/sda1"];
1569 ["mount_options"; ""; "/dev/sda1"; "/"];
1572 "unmount a filesystem",
1574 This unmounts the given filesystem. The filesystem may be
1575 specified either by its mountpoint (path) or the device which
1576 contains the filesystem.");
1578 ("mounts", (RStringList "devices", []), 46, [],
1579 [InitBasicFS, Always, TestOutputListOfDevices (
1580 [["mounts"]], ["/dev/sda1"])],
1581 "show mounted filesystems",
1583 This returns the list of currently mounted filesystems. It returns
1584 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1586 Some internal mounts are not shown.
1588 See also: C<guestfs_mountpoints>");
1590 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1591 [InitBasicFS, Always, TestOutputList (
1594 (* check that umount_all can unmount nested mounts correctly: *)
1595 InitEmpty, Always, TestOutputList (
1596 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1597 ["mkfs"; "ext2"; "/dev/sda1"];
1598 ["mkfs"; "ext2"; "/dev/sda2"];
1599 ["mkfs"; "ext2"; "/dev/sda3"];
1600 ["mount_options"; ""; "/dev/sda1"; "/"];
1602 ["mount_options"; ""; "/dev/sda2"; "/mp1"];
1603 ["mkdir"; "/mp1/mp2"];
1604 ["mount_options"; ""; "/dev/sda3"; "/mp1/mp2"];
1605 ["mkdir"; "/mp1/mp2/mp3"];
1608 "unmount all filesystems",
1610 This unmounts all mounted filesystems.
1612 Some internal mounts are not unmounted by this call.");
1614 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson; Optional "lvm2"],
1616 "remove all LVM LVs, VGs and PVs",
1618 This command removes all LVM logical volumes, volume groups
1619 and physical volumes.");
1621 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1622 [InitISOFS, Always, TestOutput (
1623 [["file"; "/empty"]], "empty");
1624 InitISOFS, Always, TestOutput (
1625 [["file"; "/known-1"]], "ASCII text");
1626 InitISOFS, Always, TestLastFail (
1627 [["file"; "/notexists"]])],
1628 "determine file type",
1630 This call uses the standard L<file(1)> command to determine
1631 the type or contents of the file. This also works on devices,
1632 for example to find out whether a partition contains a filesystem.
1634 This call will also transparently look inside various types
1637 The exact command which runs is C<file -zbsL path>. Note in
1638 particular that the filename is not prepended to the output
1639 (the C<-b> option).");
1641 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1642 [InitBasicFS, Always, TestOutput (
1643 [["upload"; "test-command"; "/test-command"];
1644 ["chmod"; "0o755"; "/test-command"];
1645 ["command"; "/test-command 1"]], "Result1");
1646 InitBasicFS, Always, TestOutput (
1647 [["upload"; "test-command"; "/test-command"];
1648 ["chmod"; "0o755"; "/test-command"];
1649 ["command"; "/test-command 2"]], "Result2\n");
1650 InitBasicFS, Always, TestOutput (
1651 [["upload"; "test-command"; "/test-command"];
1652 ["chmod"; "0o755"; "/test-command"];
1653 ["command"; "/test-command 3"]], "\nResult3");
1654 InitBasicFS, Always, TestOutput (
1655 [["upload"; "test-command"; "/test-command"];
1656 ["chmod"; "0o755"; "/test-command"];
1657 ["command"; "/test-command 4"]], "\nResult4\n");
1658 InitBasicFS, Always, TestOutput (
1659 [["upload"; "test-command"; "/test-command"];
1660 ["chmod"; "0o755"; "/test-command"];
1661 ["command"; "/test-command 5"]], "\nResult5\n\n");
1662 InitBasicFS, Always, TestOutput (
1663 [["upload"; "test-command"; "/test-command"];
1664 ["chmod"; "0o755"; "/test-command"];
1665 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1666 InitBasicFS, Always, TestOutput (
1667 [["upload"; "test-command"; "/test-command"];
1668 ["chmod"; "0o755"; "/test-command"];
1669 ["command"; "/test-command 7"]], "");
1670 InitBasicFS, Always, TestOutput (
1671 [["upload"; "test-command"; "/test-command"];
1672 ["chmod"; "0o755"; "/test-command"];
1673 ["command"; "/test-command 8"]], "\n");
1674 InitBasicFS, Always, TestOutput (
1675 [["upload"; "test-command"; "/test-command"];
1676 ["chmod"; "0o755"; "/test-command"];
1677 ["command"; "/test-command 9"]], "\n\n");
1678 InitBasicFS, Always, TestOutput (
1679 [["upload"; "test-command"; "/test-command"];
1680 ["chmod"; "0o755"; "/test-command"];
1681 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1682 InitBasicFS, Always, TestOutput (
1683 [["upload"; "test-command"; "/test-command"];
1684 ["chmod"; "0o755"; "/test-command"];
1685 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1686 InitBasicFS, Always, TestLastFail (
1687 [["upload"; "test-command"; "/test-command"];
1688 ["chmod"; "0o755"; "/test-command"];
1689 ["command"; "/test-command"]])],
1690 "run a command from the guest filesystem",
1692 This call runs a command from the guest filesystem. The
1693 filesystem must be mounted, and must contain a compatible
1694 operating system (ie. something Linux, with the same
1695 or compatible processor architecture).
1697 The single parameter is an argv-style list of arguments.
1698 The first element is the name of the program to run.
1699 Subsequent elements are parameters. The list must be
1700 non-empty (ie. must contain a program name). Note that
1701 the command runs directly, and is I<not> invoked via
1702 the shell (see C<guestfs_sh>).
1704 The return value is anything printed to I<stdout> by
1707 If the command returns a non-zero exit status, then
1708 this function returns an error message. The error message
1709 string is the content of I<stderr> from the command.
1711 The C<$PATH> environment variable will contain at least
1712 C</usr/bin> and C</bin>. If you require a program from
1713 another location, you should provide the full path in the
1716 Shared libraries and data files required by the program
1717 must be available on filesystems which are mounted in the
1718 correct places. It is the caller's responsibility to ensure
1719 all filesystems that are needed are mounted at the right
1722 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1723 [InitBasicFS, Always, TestOutputList (
1724 [["upload"; "test-command"; "/test-command"];
1725 ["chmod"; "0o755"; "/test-command"];
1726 ["command_lines"; "/test-command 1"]], ["Result1"]);
1727 InitBasicFS, Always, TestOutputList (
1728 [["upload"; "test-command"; "/test-command"];
1729 ["chmod"; "0o755"; "/test-command"];
1730 ["command_lines"; "/test-command 2"]], ["Result2"]);
1731 InitBasicFS, Always, TestOutputList (
1732 [["upload"; "test-command"; "/test-command"];
1733 ["chmod"; "0o755"; "/test-command"];
1734 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1735 InitBasicFS, Always, TestOutputList (
1736 [["upload"; "test-command"; "/test-command"];
1737 ["chmod"; "0o755"; "/test-command"];
1738 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1739 InitBasicFS, Always, TestOutputList (
1740 [["upload"; "test-command"; "/test-command"];
1741 ["chmod"; "0o755"; "/test-command"];
1742 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1743 InitBasicFS, Always, TestOutputList (
1744 [["upload"; "test-command"; "/test-command"];
1745 ["chmod"; "0o755"; "/test-command"];
1746 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1747 InitBasicFS, Always, TestOutputList (
1748 [["upload"; "test-command"; "/test-command"];
1749 ["chmod"; "0o755"; "/test-command"];
1750 ["command_lines"; "/test-command 7"]], []);
1751 InitBasicFS, Always, TestOutputList (
1752 [["upload"; "test-command"; "/test-command"];
1753 ["chmod"; "0o755"; "/test-command"];
1754 ["command_lines"; "/test-command 8"]], [""]);
1755 InitBasicFS, Always, TestOutputList (
1756 [["upload"; "test-command"; "/test-command"];
1757 ["chmod"; "0o755"; "/test-command"];
1758 ["command_lines"; "/test-command 9"]], ["";""]);
1759 InitBasicFS, Always, TestOutputList (
1760 [["upload"; "test-command"; "/test-command"];
1761 ["chmod"; "0o755"; "/test-command"];
1762 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1763 InitBasicFS, Always, TestOutputList (
1764 [["upload"; "test-command"; "/test-command"];
1765 ["chmod"; "0o755"; "/test-command"];
1766 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1767 "run a command, returning lines",
1769 This is the same as C<guestfs_command>, but splits the
1770 result into a list of lines.
1772 See also: C<guestfs_sh_lines>");
1774 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1775 [InitISOFS, Always, TestOutputStruct (
1776 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1777 "get file information",
1779 Returns file information for the given C<path>.
1781 This is the same as the C<stat(2)> system call.");
1783 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1784 [InitISOFS, Always, TestOutputStruct (
1785 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1786 "get file information for a symbolic link",
1788 Returns file information for the given C<path>.
1790 This is the same as C<guestfs_stat> except that if C<path>
1791 is a symbolic link, then the link is stat-ed, not the file it
1794 This is the same as the C<lstat(2)> system call.");
1796 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1797 [InitISOFS, Always, TestOutputStruct (
1798 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1799 "get file system statistics",
1801 Returns file system statistics for any mounted file system.
1802 C<path> should be a file or directory in the mounted file system
1803 (typically it is the mount point itself, but it doesn't need to be).
1805 This is the same as the C<statvfs(2)> system call.");
1807 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1809 "get ext2/ext3/ext4 superblock details",
1811 This returns the contents of the ext2, ext3 or ext4 filesystem
1812 superblock on C<device>.
1814 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1815 manpage for more details. The list of fields returned isn't
1816 clearly defined, and depends on both the version of C<tune2fs>
1817 that libguestfs was built against, and the filesystem itself.");
1819 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1820 [InitEmpty, Always, TestOutputTrue (
1821 [["blockdev_setro"; "/dev/sda"];
1822 ["blockdev_getro"; "/dev/sda"]])],
1823 "set block device to read-only",
1825 Sets the block device named C<device> to read-only.
1827 This uses the L<blockdev(8)> command.");
1829 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1830 [InitEmpty, Always, TestOutputFalse (
1831 [["blockdev_setrw"; "/dev/sda"];
1832 ["blockdev_getro"; "/dev/sda"]])],
1833 "set block device to read-write",
1835 Sets the block device named C<device> to read-write.
1837 This uses the L<blockdev(8)> command.");
1839 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1840 [InitEmpty, Always, TestOutputTrue (
1841 [["blockdev_setro"; "/dev/sda"];
1842 ["blockdev_getro"; "/dev/sda"]])],
1843 "is block device set to read-only",
1845 Returns a boolean indicating if the block device is read-only
1846 (true if read-only, false if not).
1848 This uses the L<blockdev(8)> command.");
1850 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1851 [InitEmpty, Always, TestOutputInt (
1852 [["blockdev_getss"; "/dev/sda"]], 512)],
1853 "get sectorsize of block device",
1855 This returns the size of sectors on a block device.
1856 Usually 512, but can be larger for modern devices.
1858 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1861 This uses the L<blockdev(8)> command.");
1863 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1864 [InitEmpty, Always, TestOutputInt (
1865 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1866 "get blocksize of block device",
1868 This returns the block size of a device.
1870 (Note this is different from both I<size in blocks> and
1871 I<filesystem block size>).
1873 This uses the L<blockdev(8)> command.");
1875 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1877 "set blocksize of block device",
1879 This sets the block size of a device.
1881 (Note this is different from both I<size in blocks> and
1882 I<filesystem block size>).
1884 This uses the L<blockdev(8)> command.");
1886 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1887 [InitEmpty, Always, TestOutputInt (
1888 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1889 "get total size of device in 512-byte sectors",
1891 This returns the size of the device in units of 512-byte sectors
1892 (even if the sectorsize isn't 512 bytes ... weird).
1894 See also C<guestfs_blockdev_getss> for the real sector size of
1895 the device, and C<guestfs_blockdev_getsize64> for the more
1896 useful I<size in bytes>.
1898 This uses the L<blockdev(8)> command.");
1900 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1901 [InitEmpty, Always, TestOutputInt (
1902 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1903 "get total size of device in bytes",
1905 This returns the size of the device in bytes.
1907 See also C<guestfs_blockdev_getsz>.
1909 This uses the L<blockdev(8)> command.");
1911 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1912 [InitEmpty, Always, TestRun
1913 [["blockdev_flushbufs"; "/dev/sda"]]],
1914 "flush device buffers",
1916 This tells the kernel to flush internal buffers associated
1919 This uses the L<blockdev(8)> command.");
1921 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1922 [InitEmpty, Always, TestRun
1923 [["blockdev_rereadpt"; "/dev/sda"]]],
1924 "reread partition table",
1926 Reread the partition table on C<device>.
1928 This uses the L<blockdev(8)> command.");
1930 ("upload", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"]), 66, [],
1931 [InitBasicFS, Always, TestOutput (
1932 (* Pick a file from cwd which isn't likely to change. *)
1933 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1934 ["checksum"; "md5"; "/COPYING.LIB"]],
1935 Digest.to_hex (Digest.file "COPYING.LIB"))],
1936 "upload a file from the local machine",
1938 Upload local file C<filename> to C<remotefilename> on the
1941 C<filename> can also be a named pipe.
1943 See also C<guestfs_download>.");
1945 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1946 [InitBasicFS, Always, TestOutput (
1947 (* Pick a file from cwd which isn't likely to change. *)
1948 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1949 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1950 ["upload"; "testdownload.tmp"; "/upload"];
1951 ["checksum"; "md5"; "/upload"]],
1952 Digest.to_hex (Digest.file "COPYING.LIB"))],
1953 "download a file to the local machine",
1955 Download file C<remotefilename> and save it as C<filename>
1956 on the local machine.
1958 C<filename> can also be a named pipe.
1960 See also C<guestfs_upload>, C<guestfs_cat>.");
1962 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1963 [InitISOFS, Always, TestOutput (
1964 [["checksum"; "crc"; "/known-3"]], "2891671662");
1965 InitISOFS, Always, TestLastFail (
1966 [["checksum"; "crc"; "/notexists"]]);
1967 InitISOFS, Always, TestOutput (
1968 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1969 InitISOFS, Always, TestOutput (
1970 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1971 InitISOFS, Always, TestOutput (
1972 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1973 InitISOFS, Always, TestOutput (
1974 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1975 InitISOFS, Always, TestOutput (
1976 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1977 InitISOFS, Always, TestOutput (
1978 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6");
1979 (* Test for RHBZ#579608, absolute symbolic links. *)
1980 InitISOFS, Always, TestOutput (
1981 [["checksum"; "sha512"; "/abssymlink"]], "5f57d0639bc95081c53afc63a449403883818edc64da48930ad6b1a4fb49be90404686877743fbcd7c99811f3def7df7bc22635c885c6a8cf79c806b43451c1a")],
1982 "compute MD5, SHAx or CRC checksum of file",
1984 This call computes the MD5, SHAx or CRC checksum of the
1987 The type of checksum to compute is given by the C<csumtype>
1988 parameter which must have one of the following values:
1994 Compute the cyclic redundancy check (CRC) specified by POSIX
1995 for the C<cksum> command.
1999 Compute the MD5 hash (using the C<md5sum> program).
2003 Compute the SHA1 hash (using the C<sha1sum> program).
2007 Compute the SHA224 hash (using the C<sha224sum> program).
2011 Compute the SHA256 hash (using the C<sha256sum> program).
2015 Compute the SHA384 hash (using the C<sha384sum> program).
2019 Compute the SHA512 hash (using the C<sha512sum> program).
2023 The checksum is returned as a printable string.
2025 To get the checksum for a device, use C<guestfs_checksum_device>.
2027 To get the checksums for many files, use C<guestfs_checksums_out>.");
2029 ("tar_in", (RErr, [FileIn "tarfile"; Pathname "directory"]), 69, [],
2030 [InitBasicFS, Always, TestOutput (
2031 [["tar_in"; "../images/helloworld.tar"; "/"];
2032 ["cat"; "/hello"]], "hello\n")],
2033 "unpack tarfile to directory",
2035 This command uploads and unpacks local file C<tarfile> (an
2036 I<uncompressed> tar file) into C<directory>.
2038 To upload a compressed tarball, use C<guestfs_tgz_in>
2039 or C<guestfs_txz_in>.");
2041 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
2043 "pack directory into tarfile",
2045 This command packs the contents of C<directory> and downloads
2046 it to local file C<tarfile>.
2048 To download a compressed tarball, use C<guestfs_tgz_out>
2049 or C<guestfs_txz_out>.");
2051 ("tgz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 71, [],
2052 [InitBasicFS, Always, TestOutput (
2053 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
2054 ["cat"; "/hello"]], "hello\n")],
2055 "unpack compressed tarball to directory",
2057 This command uploads and unpacks local file C<tarball> (a
2058 I<gzip compressed> tar file) into C<directory>.
2060 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
2062 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
2064 "pack directory into compressed tarball",
2066 This command packs the contents of C<directory> and downloads
2067 it to local file C<tarball>.
2069 To download an uncompressed tarball, use C<guestfs_tar_out>.");
2071 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
2072 [InitBasicFS, Always, TestLastFail (
2074 ["mount_ro"; "/dev/sda1"; "/"];
2075 ["touch"; "/new"]]);
2076 InitBasicFS, Always, TestOutput (
2077 [["write"; "/new"; "data"];
2079 ["mount_ro"; "/dev/sda1"; "/"];
2080 ["cat"; "/new"]], "data")],
2081 "mount a guest disk, read-only",
2083 This is the same as the C<guestfs_mount> command, but it
2084 mounts the filesystem with the read-only (I<-o ro>) flag.");
2086 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2088 "mount a guest disk with mount options",
2090 This is the same as the C<guestfs_mount> command, but it
2091 allows you to set the mount options as for the
2092 L<mount(8)> I<-o> flag.
2094 If the C<options> parameter is an empty string, then
2095 no options are passed (all options default to whatever
2096 the filesystem uses).");
2098 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2100 "mount a guest disk with mount options and vfstype",
2102 This is the same as the C<guestfs_mount> command, but it
2103 allows you to set both the mount options and the vfstype
2104 as for the L<mount(8)> I<-o> and I<-t> flags.");
2106 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2108 "debugging and internals",
2110 The C<guestfs_debug> command exposes some internals of
2111 C<guestfsd> (the guestfs daemon) that runs inside the
2114 There is no comprehensive help for this command. You have
2115 to look at the file C<daemon/debug.c> in the libguestfs source
2116 to find out what you can do.");
2118 ("lvremove", (RErr, [Device "device"]), 77, [Optional "lvm2"],
2119 [InitEmpty, Always, TestOutputList (
2120 [["part_disk"; "/dev/sda"; "mbr"];
2121 ["pvcreate"; "/dev/sda1"];
2122 ["vgcreate"; "VG"; "/dev/sda1"];
2123 ["lvcreate"; "LV1"; "VG"; "50"];
2124 ["lvcreate"; "LV2"; "VG"; "50"];
2125 ["lvremove"; "/dev/VG/LV1"];
2126 ["lvs"]], ["/dev/VG/LV2"]);
2127 InitEmpty, Always, TestOutputList (
2128 [["part_disk"; "/dev/sda"; "mbr"];
2129 ["pvcreate"; "/dev/sda1"];
2130 ["vgcreate"; "VG"; "/dev/sda1"];
2131 ["lvcreate"; "LV1"; "VG"; "50"];
2132 ["lvcreate"; "LV2"; "VG"; "50"];
2133 ["lvremove"; "/dev/VG"];
2135 InitEmpty, Always, TestOutputList (
2136 [["part_disk"; "/dev/sda"; "mbr"];
2137 ["pvcreate"; "/dev/sda1"];
2138 ["vgcreate"; "VG"; "/dev/sda1"];
2139 ["lvcreate"; "LV1"; "VG"; "50"];
2140 ["lvcreate"; "LV2"; "VG"; "50"];
2141 ["lvremove"; "/dev/VG"];
2143 "remove an LVM logical volume",
2145 Remove an LVM logical volume C<device>, where C<device> is
2146 the path to the LV, such as C</dev/VG/LV>.
2148 You can also remove all LVs in a volume group by specifying
2149 the VG name, C</dev/VG>.");
2151 ("vgremove", (RErr, [String "vgname"]), 78, [Optional "lvm2"],
2152 [InitEmpty, Always, TestOutputList (
2153 [["part_disk"; "/dev/sda"; "mbr"];
2154 ["pvcreate"; "/dev/sda1"];
2155 ["vgcreate"; "VG"; "/dev/sda1"];
2156 ["lvcreate"; "LV1"; "VG"; "50"];
2157 ["lvcreate"; "LV2"; "VG"; "50"];
2160 InitEmpty, Always, TestOutputList (
2161 [["part_disk"; "/dev/sda"; "mbr"];
2162 ["pvcreate"; "/dev/sda1"];
2163 ["vgcreate"; "VG"; "/dev/sda1"];
2164 ["lvcreate"; "LV1"; "VG"; "50"];
2165 ["lvcreate"; "LV2"; "VG"; "50"];
2168 "remove an LVM volume group",
2170 Remove an LVM volume group C<vgname>, (for example C<VG>).
2172 This also forcibly removes all logical volumes in the volume
2175 ("pvremove", (RErr, [Device "device"]), 79, [Optional "lvm2"],
2176 [InitEmpty, Always, TestOutputListOfDevices (
2177 [["part_disk"; "/dev/sda"; "mbr"];
2178 ["pvcreate"; "/dev/sda1"];
2179 ["vgcreate"; "VG"; "/dev/sda1"];
2180 ["lvcreate"; "LV1"; "VG"; "50"];
2181 ["lvcreate"; "LV2"; "VG"; "50"];
2183 ["pvremove"; "/dev/sda1"];
2185 InitEmpty, Always, TestOutputListOfDevices (
2186 [["part_disk"; "/dev/sda"; "mbr"];
2187 ["pvcreate"; "/dev/sda1"];
2188 ["vgcreate"; "VG"; "/dev/sda1"];
2189 ["lvcreate"; "LV1"; "VG"; "50"];
2190 ["lvcreate"; "LV2"; "VG"; "50"];
2192 ["pvremove"; "/dev/sda1"];
2194 InitEmpty, Always, TestOutputListOfDevices (
2195 [["part_disk"; "/dev/sda"; "mbr"];
2196 ["pvcreate"; "/dev/sda1"];
2197 ["vgcreate"; "VG"; "/dev/sda1"];
2198 ["lvcreate"; "LV1"; "VG"; "50"];
2199 ["lvcreate"; "LV2"; "VG"; "50"];
2201 ["pvremove"; "/dev/sda1"];
2203 "remove an LVM physical volume",
2205 This wipes a physical volume C<device> so that LVM will no longer
2208 The implementation uses the C<pvremove> command which refuses to
2209 wipe physical volumes that contain any volume groups, so you have
2210 to remove those first.");
2212 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2213 [InitBasicFS, Always, TestOutput (
2214 [["set_e2label"; "/dev/sda1"; "testlabel"];
2215 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2216 "set the ext2/3/4 filesystem label",
2218 This sets the ext2/3/4 filesystem label of the filesystem on
2219 C<device> to C<label>. Filesystem labels are limited to
2222 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2223 to return the existing label on a filesystem.");
2225 ("get_e2label", (RString "label", [Device "device"]), 81, [],
2227 "get the ext2/3/4 filesystem label",
2229 This returns the ext2/3/4 filesystem label of the filesystem on
2232 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2233 (let uuid = uuidgen () in
2234 [InitBasicFS, Always, TestOutput (
2235 [["set_e2uuid"; "/dev/sda1"; uuid];
2236 ["get_e2uuid"; "/dev/sda1"]], uuid);
2237 InitBasicFS, Always, TestOutput (
2238 [["set_e2uuid"; "/dev/sda1"; "clear"];
2239 ["get_e2uuid"; "/dev/sda1"]], "");
2240 (* We can't predict what UUIDs will be, so just check the commands run. *)
2241 InitBasicFS, Always, TestRun (
2242 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2243 InitBasicFS, Always, TestRun (
2244 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2245 "set the ext2/3/4 filesystem UUID",
2247 This sets the ext2/3/4 filesystem UUID of the filesystem on
2248 C<device> to C<uuid>. The format of the UUID and alternatives
2249 such as C<clear>, C<random> and C<time> are described in the
2250 L<tune2fs(8)> manpage.
2252 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2253 to return the existing UUID of a filesystem.");
2255 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [],
2257 "get the ext2/3/4 filesystem UUID",
2259 This returns the ext2/3/4 filesystem UUID of the filesystem on
2262 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [FishOutput FishOutputHexadecimal],
2263 [InitBasicFS, Always, TestOutputInt (
2264 [["umount"; "/dev/sda1"];
2265 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2266 InitBasicFS, Always, TestOutputInt (
2267 [["umount"; "/dev/sda1"];
2268 ["zero"; "/dev/sda1"];
2269 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2270 "run the filesystem checker",
2272 This runs the filesystem checker (fsck) on C<device> which
2273 should have filesystem type C<fstype>.
2275 The returned integer is the status. See L<fsck(8)> for the
2276 list of status codes from C<fsck>.
2284 Multiple status codes can be summed together.
2288 A non-zero return code can mean \"success\", for example if
2289 errors have been corrected on the filesystem.
2293 Checking or repairing NTFS volumes is not supported
2298 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2300 ("zero", (RErr, [Device "device"]), 85, [],
2301 [InitBasicFS, Always, TestOutput (
2302 [["umount"; "/dev/sda1"];
2303 ["zero"; "/dev/sda1"];
2304 ["file"; "/dev/sda1"]], "data")],
2305 "write zeroes to the device",
2307 This command writes zeroes over the first few blocks of C<device>.
2309 How many blocks are zeroed isn't specified (but it's I<not> enough
2310 to securely wipe the device). It should be sufficient to remove
2311 any partition tables, filesystem superblocks and so on.
2313 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
2315 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2316 (* Test disabled because grub-install incompatible with virtio-blk driver.
2317 * See also: https://bugzilla.redhat.com/show_bug.cgi?id=479760
2319 [InitBasicFS, Disabled, TestOutputTrue (
2320 [["grub_install"; "/"; "/dev/sda1"];
2321 ["is_dir"; "/boot"]])],
2324 This command installs GRUB (the Grand Unified Bootloader) on
2325 C<device>, with the root directory being C<root>.");
2327 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2328 [InitBasicFS, Always, TestOutput (
2329 [["write"; "/old"; "file content"];
2330 ["cp"; "/old"; "/new"];
2331 ["cat"; "/new"]], "file content");
2332 InitBasicFS, Always, TestOutputTrue (
2333 [["write"; "/old"; "file content"];
2334 ["cp"; "/old"; "/new"];
2335 ["is_file"; "/old"]]);
2336 InitBasicFS, Always, TestOutput (
2337 [["write"; "/old"; "file content"];
2339 ["cp"; "/old"; "/dir/new"];
2340 ["cat"; "/dir/new"]], "file content")],
2343 This copies a file from C<src> to C<dest> where C<dest> is
2344 either a destination filename or destination directory.");
2346 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2347 [InitBasicFS, Always, TestOutput (
2348 [["mkdir"; "/olddir"];
2349 ["mkdir"; "/newdir"];
2350 ["write"; "/olddir/file"; "file content"];
2351 ["cp_a"; "/olddir"; "/newdir"];
2352 ["cat"; "/newdir/olddir/file"]], "file content")],
2353 "copy a file or directory recursively",
2355 This copies a file or directory from C<src> to C<dest>
2356 recursively using the C<cp -a> command.");
2358 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2359 [InitBasicFS, Always, TestOutput (
2360 [["write"; "/old"; "file content"];
2361 ["mv"; "/old"; "/new"];
2362 ["cat"; "/new"]], "file content");
2363 InitBasicFS, Always, TestOutputFalse (
2364 [["write"; "/old"; "file content"];
2365 ["mv"; "/old"; "/new"];
2366 ["is_file"; "/old"]])],
2369 This moves a file from C<src> to C<dest> where C<dest> is
2370 either a destination filename or destination directory.");
2372 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2373 [InitEmpty, Always, TestRun (
2374 [["drop_caches"; "3"]])],
2375 "drop kernel page cache, dentries and inodes",
2377 This instructs the guest kernel to drop its page cache,
2378 and/or dentries and inode caches. The parameter C<whattodrop>
2379 tells the kernel what precisely to drop, see
2380 L<http://linux-mm.org/Drop_Caches>
2382 Setting C<whattodrop> to 3 should drop everything.
2384 This automatically calls L<sync(2)> before the operation,
2385 so that the maximum guest memory is freed.");
2387 ("dmesg", (RString "kmsgs", []), 91, [],
2388 [InitEmpty, Always, TestRun (
2390 "return kernel messages",
2392 This returns the kernel messages (C<dmesg> output) from
2393 the guest kernel. This is sometimes useful for extended
2394 debugging of problems.
2396 Another way to get the same information is to enable
2397 verbose messages with C<guestfs_set_verbose> or by setting
2398 the environment variable C<LIBGUESTFS_DEBUG=1> before
2399 running the program.");
2401 ("ping_daemon", (RErr, []), 92, [],
2402 [InitEmpty, Always, TestRun (
2403 [["ping_daemon"]])],
2404 "ping the guest daemon",
2406 This is a test probe into the guestfs daemon running inside
2407 the qemu subprocess. Calling this function checks that the
2408 daemon responds to the ping message, without affecting the daemon
2409 or attached block device(s) in any other way.");
2411 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2412 [InitBasicFS, Always, TestOutputTrue (
2413 [["write"; "/file1"; "contents of a file"];
2414 ["cp"; "/file1"; "/file2"];
2415 ["equal"; "/file1"; "/file2"]]);
2416 InitBasicFS, Always, TestOutputFalse (
2417 [["write"; "/file1"; "contents of a file"];
2418 ["write"; "/file2"; "contents of another file"];
2419 ["equal"; "/file1"; "/file2"]]);
2420 InitBasicFS, Always, TestLastFail (
2421 [["equal"; "/file1"; "/file2"]])],
2422 "test if two files have equal contents",
2424 This compares the two files C<file1> and C<file2> and returns
2425 true if their content is exactly equal, or false otherwise.
2427 The external L<cmp(1)> program is used for the comparison.");
2429 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2430 [InitISOFS, Always, TestOutputList (
2431 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2432 InitISOFS, Always, TestOutputList (
2433 [["strings"; "/empty"]], []);
2434 (* Test for RHBZ#579608, absolute symbolic links. *)
2435 InitISOFS, Always, TestRun (
2436 [["strings"; "/abssymlink"]])],
2437 "print the printable strings in a file",
2439 This runs the L<strings(1)> command on a file and returns
2440 the list of printable strings found.");
2442 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2443 [InitISOFS, Always, TestOutputList (
2444 [["strings_e"; "b"; "/known-5"]], []);
2445 InitBasicFS, Always, TestOutputList (
2446 [["write"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"];
2447 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2448 "print the printable strings in a file",
2450 This is like the C<guestfs_strings> command, but allows you to
2451 specify the encoding of strings that are looked for in
2452 the source file C<path>.
2454 Allowed encodings are:
2460 Single 7-bit-byte characters like ASCII and the ASCII-compatible
2461 parts of ISO-8859-X (this is what C<guestfs_strings> uses).
2465 Single 8-bit-byte characters.
2469 16-bit big endian strings such as those encoded in
2470 UTF-16BE or UCS-2BE.
2472 =item l (lower case letter L)
2474 16-bit little endian such as UTF-16LE and UCS-2LE.
2475 This is useful for examining binaries in Windows guests.
2479 32-bit big endian such as UCS-4BE.
2483 32-bit little endian such as UCS-4LE.
2487 The returned strings are transcoded to UTF-8.");
2489 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2490 [InitISOFS, Always, TestOutput (
2491 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2492 (* Test for RHBZ#501888c2 regression which caused large hexdump
2493 * commands to segfault.
2495 InitISOFS, Always, TestRun (
2496 [["hexdump"; "/100krandom"]]);
2497 (* Test for RHBZ#579608, absolute symbolic links. *)
2498 InitISOFS, Always, TestRun (
2499 [["hexdump"; "/abssymlink"]])],
2500 "dump a file in hexadecimal",
2502 This runs C<hexdump -C> on the given C<path>. The result is
2503 the human-readable, canonical hex dump of the file.");
2505 ("zerofree", (RErr, [Device "device"]), 97, [Optional "zerofree"],
2506 [InitNone, Always, TestOutput (
2507 [["part_disk"; "/dev/sda"; "mbr"];
2508 ["mkfs"; "ext3"; "/dev/sda1"];
2509 ["mount_options"; ""; "/dev/sda1"; "/"];
2510 ["write"; "/new"; "test file"];
2511 ["umount"; "/dev/sda1"];
2512 ["zerofree"; "/dev/sda1"];
2513 ["mount_options"; ""; "/dev/sda1"; "/"];
2514 ["cat"; "/new"]], "test file")],
2515 "zero unused inodes and disk blocks on ext2/3 filesystem",
2517 This runs the I<zerofree> program on C<device>. This program
2518 claims to zero unused inodes and disk blocks on an ext2/3
2519 filesystem, thus making it possible to compress the filesystem
2522 You should B<not> run this program if the filesystem is
2525 It is possible that using this program can damage the filesystem
2526 or data on the filesystem.");
2528 ("pvresize", (RErr, [Device "device"]), 98, [Optional "lvm2"],
2530 "resize an LVM physical volume",
2532 This resizes (expands or shrinks) an existing LVM physical
2533 volume to match the new size of the underlying device.");
2535 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2536 Int "cyls"; Int "heads"; Int "sectors";
2537 String "line"]), 99, [DangerWillRobinson],
2539 "modify a single partition on a block device",
2541 This runs L<sfdisk(8)> option to modify just the single
2542 partition C<n> (note: C<n> counts from 1).
2544 For other parameters, see C<guestfs_sfdisk>. You should usually
2545 pass C<0> for the cyls/heads/sectors parameters.
2547 See also: C<guestfs_part_add>");
2549 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2551 "display the partition table",
2553 This displays the partition table on C<device>, in the
2554 human-readable output of the L<sfdisk(8)> command. It is
2555 not intended to be parsed.
2557 See also: C<guestfs_part_list>");
2559 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2561 "display the kernel geometry",
2563 This displays the kernel's idea of the geometry of C<device>.
2565 The result is in human-readable format, and not designed to
2568 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2570 "display the disk geometry from the partition table",
2572 This displays the disk geometry of C<device> read from the
2573 partition table. Especially in the case where the underlying
2574 block device has been resized, this can be different from the
2575 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2577 The result is in human-readable format, and not designed to
2580 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [Optional "lvm2"],
2582 "activate or deactivate all volume groups",
2584 This command activates or (if C<activate> is false) deactivates
2585 all logical volumes in all volume groups.
2586 If activated, then they are made known to the
2587 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2588 then those devices disappear.
2590 This command is the same as running C<vgchange -a y|n>");
2592 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [Optional "lvm2"],
2594 "activate or deactivate some volume groups",
2596 This command activates or (if C<activate> is false) deactivates
2597 all logical volumes in the listed volume groups C<volgroups>.
2598 If activated, then they are made known to the
2599 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2600 then those devices disappear.
2602 This command is the same as running C<vgchange -a y|n volgroups...>
2604 Note that if C<volgroups> is an empty list then B<all> volume groups
2605 are activated or deactivated.");
2607 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [Optional "lvm2"],
2608 [InitNone, Always, TestOutput (
2609 [["part_disk"; "/dev/sda"; "mbr"];
2610 ["pvcreate"; "/dev/sda1"];
2611 ["vgcreate"; "VG"; "/dev/sda1"];
2612 ["lvcreate"; "LV"; "VG"; "10"];
2613 ["mkfs"; "ext2"; "/dev/VG/LV"];
2614 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2615 ["write"; "/new"; "test content"];
2617 ["lvresize"; "/dev/VG/LV"; "20"];
2618 ["e2fsck_f"; "/dev/VG/LV"];
2619 ["resize2fs"; "/dev/VG/LV"];
2620 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2621 ["cat"; "/new"]], "test content");
2622 InitNone, Always, TestRun (
2623 (* Make an LV smaller to test RHBZ#587484. *)
2624 [["part_disk"; "/dev/sda"; "mbr"];
2625 ["pvcreate"; "/dev/sda1"];
2626 ["vgcreate"; "VG"; "/dev/sda1"];
2627 ["lvcreate"; "LV"; "VG"; "20"];
2628 ["lvresize"; "/dev/VG/LV"; "10"]])],
2629 "resize an LVM logical volume",
2631 This resizes (expands or shrinks) an existing LVM logical
2632 volume to C<mbytes>. When reducing, data in the reduced part
2635 ("resize2fs", (RErr, [Device "device"]), 106, [],
2636 [], (* lvresize tests this *)
2637 "resize an ext2/ext3 filesystem",
2639 This resizes an ext2 or ext3 filesystem to match the size of
2640 the underlying device.
2642 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2643 on the C<device> before calling this command. For unknown reasons
2644 C<resize2fs> sometimes gives an error about this and sometimes not.
2645 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2646 calling this function.");
2648 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2649 [InitBasicFS, Always, TestOutputList (
2650 [["find"; "/"]], ["lost+found"]);
2651 InitBasicFS, Always, TestOutputList (
2655 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2656 InitBasicFS, Always, TestOutputList (
2657 [["mkdir_p"; "/a/b/c"];
2658 ["touch"; "/a/b/c/d"];
2659 ["find"; "/a/b/"]], ["c"; "c/d"])],
2660 "find all files and directories",
2662 This command lists out all files and directories, recursively,
2663 starting at C<directory>. It is essentially equivalent to
2664 running the shell command C<find directory -print> but some
2665 post-processing happens on the output, described below.
2667 This returns a list of strings I<without any prefix>. Thus
2668 if the directory structure was:
2674 then the returned list from C<guestfs_find> C</tmp> would be
2682 If C<directory> is not a directory, then this command returns
2685 The returned list is sorted.
2687 See also C<guestfs_find0>.");
2689 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2690 [], (* lvresize tests this *)
2691 "check an ext2/ext3 filesystem",
2693 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2694 filesystem checker on C<device>, noninteractively (C<-p>),
2695 even if the filesystem appears to be clean (C<-f>).
2697 This command is only needed because of C<guestfs_resize2fs>
2698 (q.v.). Normally you should use C<guestfs_fsck>.");
2700 ("sleep", (RErr, [Int "secs"]), 109, [],
2701 [InitNone, Always, TestRun (
2703 "sleep for some seconds",
2705 Sleep for C<secs> seconds.");
2707 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [Optional "ntfs3g"],
2708 [InitNone, Always, TestOutputInt (
2709 [["part_disk"; "/dev/sda"; "mbr"];
2710 ["mkfs"; "ntfs"; "/dev/sda1"];
2711 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2712 InitNone, Always, TestOutputInt (
2713 [["part_disk"; "/dev/sda"; "mbr"];
2714 ["mkfs"; "ext2"; "/dev/sda1"];
2715 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2716 "probe NTFS volume",
2718 This command runs the L<ntfs-3g.probe(8)> command which probes
2719 an NTFS C<device> for mountability. (Not all NTFS volumes can
2720 be mounted read-write, and some cannot be mounted at all).
2722 C<rw> is a boolean flag. Set it to true if you want to test
2723 if the volume can be mounted read-write. Set it to false if
2724 you want to test if the volume can be mounted read-only.
2726 The return value is an integer which C<0> if the operation
2727 would succeed, or some non-zero value documented in the
2728 L<ntfs-3g.probe(8)> manual page.");
2730 ("sh", (RString "output", [String "command"]), 111, [],
2731 [], (* XXX needs tests *)
2732 "run a command via the shell",
2734 This call runs a command from the guest filesystem via the
2737 This is like C<guestfs_command>, but passes the command to:
2739 /bin/sh -c \"command\"
2741 Depending on the guest's shell, this usually results in
2742 wildcards being expanded, shell expressions being interpolated
2745 All the provisos about C<guestfs_command> apply to this call.");
2747 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2748 [], (* XXX needs tests *)
2749 "run a command via the shell returning lines",
2751 This is the same as C<guestfs_sh>, but splits the result
2752 into a list of lines.
2754 See also: C<guestfs_command_lines>");
2756 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2757 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2758 * code in stubs.c, since all valid glob patterns must start with "/".
2759 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2761 [InitBasicFS, Always, TestOutputList (
2762 [["mkdir_p"; "/a/b/c"];
2763 ["touch"; "/a/b/c/d"];
2764 ["touch"; "/a/b/c/e"];
2765 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2766 InitBasicFS, Always, TestOutputList (
2767 [["mkdir_p"; "/a/b/c"];
2768 ["touch"; "/a/b/c/d"];
2769 ["touch"; "/a/b/c/e"];
2770 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2771 InitBasicFS, Always, TestOutputList (
2772 [["mkdir_p"; "/a/b/c"];
2773 ["touch"; "/a/b/c/d"];
2774 ["touch"; "/a/b/c/e"];
2775 ["glob_expand"; "/a/*/x/*"]], [])],
2776 "expand a wildcard path",
2778 This command searches for all the pathnames matching
2779 C<pattern> according to the wildcard expansion rules
2782 If no paths match, then this returns an empty list
2783 (note: not an error).
2785 It is just a wrapper around the C L<glob(3)> function
2786 with flags C<GLOB_MARK|GLOB_BRACE>.
2787 See that manual page for more details.");
2789 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson; Optional "scrub"],
2790 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2791 [["scrub_device"; "/dev/sdc"]])],
2792 "scrub (securely wipe) a device",
2794 This command writes patterns over C<device> to make data retrieval
2797 It is an interface to the L<scrub(1)> program. See that
2798 manual page for more details.");
2800 ("scrub_file", (RErr, [Pathname "file"]), 115, [Optional "scrub"],
2801 [InitBasicFS, Always, TestRun (
2802 [["write"; "/file"; "content"];
2803 ["scrub_file"; "/file"]])],
2804 "scrub (securely wipe) a file",
2806 This command writes patterns over a file to make data retrieval
2809 The file is I<removed> after scrubbing.
2811 It is an interface to the L<scrub(1)> program. See that
2812 manual page for more details.");
2814 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [Optional "scrub"],
2815 [], (* XXX needs testing *)
2816 "scrub (securely wipe) free space",
2818 This command creates the directory C<dir> and then fills it
2819 with files until the filesystem is full, and scrubs the files
2820 as for C<guestfs_scrub_file>, and deletes them.
2821 The intention is to scrub any free space on the partition
2824 It is an interface to the L<scrub(1)> program. See that
2825 manual page for more details.");
2827 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2828 [InitBasicFS, Always, TestRun (
2830 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2831 "create a temporary directory",
2833 This command creates a temporary directory. The
2834 C<template> parameter should be a full pathname for the
2835 temporary directory name with the final six characters being
2838 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2839 the second one being suitable for Windows filesystems.
2841 The name of the temporary directory that was created
2844 The temporary directory is created with mode 0700
2845 and is owned by root.
2847 The caller is responsible for deleting the temporary
2848 directory and its contents after use.
2850 See also: L<mkdtemp(3)>");
2852 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2853 [InitISOFS, Always, TestOutputInt (
2854 [["wc_l"; "/10klines"]], 10000);
2855 (* Test for RHBZ#579608, absolute symbolic links. *)
2856 InitISOFS, Always, TestOutputInt (
2857 [["wc_l"; "/abssymlink"]], 10000)],
2858 "count lines in a file",
2860 This command counts the lines in a file, using the
2861 C<wc -l> external command.");
2863 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2864 [InitISOFS, Always, TestOutputInt (
2865 [["wc_w"; "/10klines"]], 10000)],
2866 "count words in a file",
2868 This command counts the words in a file, using the
2869 C<wc -w> external command.");
2871 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2872 [InitISOFS, Always, TestOutputInt (
2873 [["wc_c"; "/100kallspaces"]], 102400)],
2874 "count characters in a file",
2876 This command counts the characters in a file, using the
2877 C<wc -c> external command.");
2879 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2880 [InitISOFS, Always, TestOutputList (
2881 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"]);
2882 (* Test for RHBZ#579608, absolute symbolic links. *)
2883 InitISOFS, Always, TestOutputList (
2884 [["head"; "/abssymlink"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2885 "return first 10 lines of a file",
2887 This command returns up to the first 10 lines of a file as
2888 a list of strings.");
2890 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2891 [InitISOFS, Always, TestOutputList (
2892 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2893 InitISOFS, Always, TestOutputList (
2894 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2895 InitISOFS, Always, TestOutputList (
2896 [["head_n"; "0"; "/10klines"]], [])],
2897 "return first N lines of a file",
2899 If the parameter C<nrlines> is a positive number, this returns the first
2900 C<nrlines> lines of the file C<path>.
2902 If the parameter C<nrlines> is a negative number, this returns lines
2903 from the file C<path>, excluding the last C<nrlines> lines.
2905 If the parameter C<nrlines> is zero, this returns an empty list.");
2907 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2908 [InitISOFS, Always, TestOutputList (
2909 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2910 "return last 10 lines of a file",
2912 This command returns up to the last 10 lines of a file as
2913 a list of strings.");
2915 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2916 [InitISOFS, Always, TestOutputList (
2917 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2918 InitISOFS, Always, TestOutputList (
2919 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2920 InitISOFS, Always, TestOutputList (
2921 [["tail_n"; "0"; "/10klines"]], [])],
2922 "return last N lines of a file",
2924 If the parameter C<nrlines> is a positive number, this returns the last
2925 C<nrlines> lines of the file C<path>.
2927 If the parameter C<nrlines> is a negative number, this returns lines
2928 from the file C<path>, starting with the C<-nrlines>th line.
2930 If the parameter C<nrlines> is zero, this returns an empty list.");
2932 ("df", (RString "output", []), 125, [],
2933 [], (* XXX Tricky to test because it depends on the exact format
2934 * of the 'df' command and other imponderables.
2936 "report file system disk space usage",
2938 This command runs the C<df> command to report disk space used.
2940 This command is mostly useful for interactive sessions. It
2941 is I<not> intended that you try to parse the output string.
2942 Use C<statvfs> from programs.");
2944 ("df_h", (RString "output", []), 126, [],
2945 [], (* XXX Tricky to test because it depends on the exact format
2946 * of the 'df' command and other imponderables.
2948 "report file system disk space usage (human readable)",
2950 This command runs the C<df -h> command to report disk space used
2951 in human-readable format.
2953 This command is mostly useful for interactive sessions. It
2954 is I<not> intended that you try to parse the output string.
2955 Use C<statvfs> from programs.");
2957 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2958 [InitISOFS, Always, TestOutputInt (
2959 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2960 "estimate file space usage",
2962 This command runs the C<du -s> command to estimate file space
2965 C<path> can be a file or a directory. If C<path> is a directory
2966 then the estimate includes the contents of the directory and all
2967 subdirectories (recursively).
2969 The result is the estimated size in I<kilobytes>
2970 (ie. units of 1024 bytes).");
2972 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
2973 [InitISOFS, Always, TestOutputList (
2974 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
2975 "list files in an initrd",
2977 This command lists out files contained in an initrd.
2979 The files are listed without any initial C</> character. The
2980 files are listed in the order they appear (not necessarily
2981 alphabetical). Directory names are listed as separate items.
2983 Old Linux kernels (2.4 and earlier) used a compressed ext2
2984 filesystem as initrd. We I<only> support the newer initramfs
2985 format (compressed cpio files).");
2987 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
2989 "mount a file using the loop device",
2991 This command lets you mount C<file> (a filesystem image
2992 in a file) on a mount point. It is entirely equivalent to
2993 the command C<mount -o loop file mountpoint>.");
2995 ("mkswap", (RErr, [Device "device"]), 130, [],
2996 [InitEmpty, Always, TestRun (
2997 [["part_disk"; "/dev/sda"; "mbr"];
2998 ["mkswap"; "/dev/sda1"]])],
2999 "create a swap partition",
3001 Create a swap partition on C<device>.");
3003 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
3004 [InitEmpty, Always, TestRun (
3005 [["part_disk"; "/dev/sda"; "mbr"];
3006 ["mkswap_L"; "hello"; "/dev/sda1"]])],
3007 "create a swap partition with a label",
3009 Create a swap partition on C<device> with label C<label>.
3011 Note that you cannot attach a swap label to a block device
3012 (eg. C</dev/sda>), just to a partition. This appears to be
3013 a limitation of the kernel or swap tools.");
3015 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [Optional "linuxfsuuid"],
3016 (let uuid = uuidgen () in
3017 [InitEmpty, Always, TestRun (
3018 [["part_disk"; "/dev/sda"; "mbr"];
3019 ["mkswap_U"; uuid; "/dev/sda1"]])]),
3020 "create a swap partition with an explicit UUID",
3022 Create a swap partition on C<device> with UUID C<uuid>.");
3024 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [Optional "mknod"],
3025 [InitBasicFS, Always, TestOutputStruct (
3026 [["mknod"; "0o10777"; "0"; "0"; "/node"];
3027 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
3028 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
3029 InitBasicFS, Always, TestOutputStruct (
3030 [["mknod"; "0o60777"; "66"; "99"; "/node"];
3031 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3032 "make block, character or FIFO devices",
3034 This call creates block or character special devices, or
3035 named pipes (FIFOs).
3037 The C<mode> parameter should be the mode, using the standard
3038 constants. C<devmajor> and C<devminor> are the
3039 device major and minor numbers, only used when creating block
3040 and character special devices.
3042 Note that, just like L<mknod(2)>, the mode must be bitwise
3043 OR'd with S_IFBLK, S_IFCHR, S_IFIFO or S_IFSOCK (otherwise this call
3044 just creates a regular file). These constants are
3045 available in the standard Linux header files, or you can use
3046 C<guestfs_mknod_b>, C<guestfs_mknod_c> or C<guestfs_mkfifo>
3047 which are wrappers around this command which bitwise OR
3048 in the appropriate constant for you.
3050 The mode actually set is affected by the umask.");
3052 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [Optional "mknod"],
3053 [InitBasicFS, Always, TestOutputStruct (
3054 [["mkfifo"; "0o777"; "/node"];
3055 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
3056 "make FIFO (named pipe)",
3058 This call creates a FIFO (named pipe) called C<path> with
3059 mode C<mode>. It is just a convenient wrapper around
3062 The mode actually set is affected by the umask.");
3064 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [Optional "mknod"],
3065 [InitBasicFS, Always, TestOutputStruct (
3066 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
3067 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3068 "make block device node",
3070 This call creates a block device node called C<path> with
3071 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3072 It is just a convenient wrapper around C<guestfs_mknod>.
3074 The mode actually set is affected by the umask.");
3076 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [Optional "mknod"],
3077 [InitBasicFS, Always, TestOutputStruct (
3078 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
3079 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
3080 "make char device node",
3082 This call creates a char device node called C<path> with
3083 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3084 It is just a convenient wrapper around C<guestfs_mknod>.
3086 The mode actually set is affected by the umask.");
3088 ("umask", (RInt "oldmask", [Int "mask"]), 137, [FishOutput FishOutputOctal],
3089 [InitEmpty, Always, TestOutputInt (
3090 [["umask"; "0o22"]], 0o22)],
3091 "set file mode creation mask (umask)",
3093 This function sets the mask used for creating new files and
3094 device nodes to C<mask & 0777>.
3096 Typical umask values would be C<022> which creates new files
3097 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
3098 C<002> which creates new files with permissions like
3099 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
3101 The default umask is C<022>. This is important because it
3102 means that directories and device nodes will be created with
3103 C<0644> or C<0755> mode even if you specify C<0777>.
3105 See also C<guestfs_get_umask>,
3106 L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
3108 This call returns the previous umask.");
3110 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
3112 "read directories entries",
3114 This returns the list of directory entries in directory C<dir>.
3116 All entries in the directory are returned, including C<.> and
3117 C<..>. The entries are I<not> sorted, but returned in the same
3118 order as the underlying filesystem.
3120 Also this call returns basic file type information about each
3121 file. The C<ftyp> field will contain one of the following characters:
3159 The L<readdir(3)> call returned a C<d_type> field with an
3164 This function is primarily intended for use by programs. To
3165 get a simple list of names, use C<guestfs_ls>. To get a printable
3166 directory for human consumption, use C<guestfs_ll>.");
3168 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3170 "create partitions on a block device",
3172 This is a simplified interface to the C<guestfs_sfdisk>
3173 command, where partition sizes are specified in megabytes
3174 only (rounded to the nearest cylinder) and you don't need
3175 to specify the cyls, heads and sectors parameters which
3176 were rarely if ever used anyway.
3178 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3179 and C<guestfs_part_disk>");
3181 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3183 "determine file type inside a compressed file",
3185 This command runs C<file> after first decompressing C<path>
3188 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3190 Since 1.0.63, use C<guestfs_file> instead which can now
3191 process compressed files.");
3193 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [Optional "linuxxattrs"],
3195 "list extended attributes of a file or directory",
3197 This call lists the extended attributes of the file or directory
3200 At the system call level, this is a combination of the
3201 L<listxattr(2)> and L<getxattr(2)> calls.
3203 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3205 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [Optional "linuxxattrs"],
3207 "list extended attributes of a file or directory",
3209 This is the same as C<guestfs_getxattrs>, but if C<path>
3210 is a symbolic link, then it returns the extended attributes
3211 of the link itself.");
3213 ("setxattr", (RErr, [String "xattr";
3214 String "val"; Int "vallen"; (* will be BufferIn *)
3215 Pathname "path"]), 143, [Optional "linuxxattrs"],
3217 "set extended attribute of a file or directory",
3219 This call sets the extended attribute named C<xattr>
3220 of the file C<path> to the value C<val> (of length C<vallen>).
3221 The value is arbitrary 8 bit data.
3223 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3225 ("lsetxattr", (RErr, [String "xattr";
3226 String "val"; Int "vallen"; (* will be BufferIn *)
3227 Pathname "path"]), 144, [Optional "linuxxattrs"],
3229 "set extended attribute of a file or directory",
3231 This is the same as C<guestfs_setxattr>, but if C<path>
3232 is a symbolic link, then it sets an extended attribute
3233 of the link itself.");
3235 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [Optional "linuxxattrs"],
3237 "remove extended attribute of a file or directory",
3239 This call removes the extended attribute named C<xattr>
3240 of the file C<path>.
3242 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3244 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [Optional "linuxxattrs"],
3246 "remove extended attribute of a file or directory",
3248 This is the same as C<guestfs_removexattr>, but if C<path>
3249 is a symbolic link, then it removes an extended attribute
3250 of the link itself.");
3252 ("mountpoints", (RHashtable "mps", []), 147, [],
3256 This call is similar to C<guestfs_mounts>. That call returns
3257 a list of devices. This one returns a hash table (map) of
3258 device name to directory where the device is mounted.");
3260 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3261 (* This is a special case: while you would expect a parameter
3262 * of type "Pathname", that doesn't work, because it implies
3263 * NEED_ROOT in the generated calling code in stubs.c, and
3264 * this function cannot use NEED_ROOT.
3267 "create a mountpoint",
3269 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3270 specialized calls that can be used to create extra mountpoints
3271 before mounting the first filesystem.
3273 These calls are I<only> necessary in some very limited circumstances,
3274 mainly the case where you want to mount a mix of unrelated and/or
3275 read-only filesystems together.
3277 For example, live CDs often contain a \"Russian doll\" nest of
3278 filesystems, an ISO outer layer, with a squashfs image inside, with
3279 an ext2/3 image inside that. You can unpack this as follows
3282 add-ro Fedora-11-i686-Live.iso
3285 mkmountpoint /squash
3288 mount-loop /cd/LiveOS/squashfs.img /squash
3289 mount-loop /squash/LiveOS/ext3fs.img /ext3
3291 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3293 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3295 "remove a mountpoint",
3297 This calls removes a mountpoint that was previously created
3298 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3299 for full details.");
3301 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3302 [InitISOFS, Always, TestOutputBuffer (
3303 [["read_file"; "/known-4"]], "abc\ndef\nghi");
3304 (* Test various near large, large and too large files (RHBZ#589039). *)
3305 InitBasicFS, Always, TestLastFail (
3307 ["truncate_size"; "/a"; "4194303"]; (* GUESTFS_MESSAGE_MAX - 1 *)
3308 ["read_file"; "/a"]]);
3309 InitBasicFS, Always, TestLastFail (
3311 ["truncate_size"; "/a"; "4194304"]; (* GUESTFS_MESSAGE_MAX *)
3312 ["read_file"; "/a"]]);
3313 InitBasicFS, Always, TestLastFail (
3315 ["truncate_size"; "/a"; "41943040"]; (* GUESTFS_MESSAGE_MAX * 10 *)
3316 ["read_file"; "/a"]])],
3319 This calls returns the contents of the file C<path> as a
3322 Unlike C<guestfs_cat>, this function can correctly
3323 handle files that contain embedded ASCII NUL characters.
3324 However unlike C<guestfs_download>, this function is limited
3325 in the total size of file that can be handled.");
3327 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3328 [InitISOFS, Always, TestOutputList (
3329 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3330 InitISOFS, Always, TestOutputList (
3331 [["grep"; "nomatch"; "/test-grep.txt"]], []);
3332 (* Test for RHBZ#579608, absolute symbolic links. *)
3333 InitISOFS, Always, TestOutputList (
3334 [["grep"; "nomatch"; "/abssymlink"]], [])],
3335 "return lines matching a pattern",
3337 This calls the external C<grep> program and returns the
3340 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3341 [InitISOFS, Always, TestOutputList (
3342 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3343 "return lines matching a pattern",
3345 This calls the external C<egrep> program and returns the
3348 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3349 [InitISOFS, Always, TestOutputList (
3350 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3351 "return lines matching a pattern",
3353 This calls the external C<fgrep> program and returns the
3356 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3357 [InitISOFS, Always, TestOutputList (
3358 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3359 "return lines matching a pattern",
3361 This calls the external C<grep -i> program and returns the
3364 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3365 [InitISOFS, Always, TestOutputList (
3366 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3367 "return lines matching a pattern",
3369 This calls the external C<egrep -i> program and returns the
3372 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3373 [InitISOFS, Always, TestOutputList (
3374 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3375 "return lines matching a pattern",
3377 This calls the external C<fgrep -i> program and returns the
3380 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3381 [InitISOFS, Always, TestOutputList (
3382 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3383 "return lines matching a pattern",
3385 This calls the external C<zgrep> program and returns the
3388 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3389 [InitISOFS, Always, TestOutputList (
3390 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3391 "return lines matching a pattern",
3393 This calls the external C<zegrep> program and returns the
3396 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3397 [InitISOFS, Always, TestOutputList (
3398 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3399 "return lines matching a pattern",
3401 This calls the external C<zfgrep> program and returns the
3404 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3405 [InitISOFS, Always, TestOutputList (
3406 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3407 "return lines matching a pattern",
3409 This calls the external C<zgrep -i> program and returns the
3412 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3413 [InitISOFS, Always, TestOutputList (
3414 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3415 "return lines matching a pattern",
3417 This calls the external C<zegrep -i> program and returns the
3420 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3421 [InitISOFS, Always, TestOutputList (
3422 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3423 "return lines matching a pattern",
3425 This calls the external C<zfgrep -i> program and returns the
3428 ("realpath", (RString "rpath", [Pathname "path"]), 163, [Optional "realpath"],
3429 [InitISOFS, Always, TestOutput (
3430 [["realpath"; "/../directory"]], "/directory")],
3431 "canonicalized absolute pathname",
3433 Return the canonicalized absolute pathname of C<path>. The
3434 returned path has no C<.>, C<..> or symbolic link path elements.");
3436 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3437 [InitBasicFS, Always, TestOutputStruct (
3440 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3441 "create a hard link",
3443 This command creates a hard link using the C<ln> command.");
3445 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3446 [InitBasicFS, Always, TestOutputStruct (
3449 ["ln_f"; "/a"; "/b"];
3450 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3451 "create a hard link",
3453 This command creates a hard link using the C<ln -f> command.
3454 The C<-f> option removes the link (C<linkname>) if it exists already.");
3456 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3457 [InitBasicFS, Always, TestOutputStruct (
3459 ["ln_s"; "a"; "/b"];
3460 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3461 "create a symbolic link",
3463 This command creates a symbolic link using the C<ln -s> command.");
3465 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3466 [InitBasicFS, Always, TestOutput (
3467 [["mkdir_p"; "/a/b"];
3468 ["touch"; "/a/b/c"];
3469 ["ln_sf"; "../d"; "/a/b/c"];
3470 ["readlink"; "/a/b/c"]], "../d")],
3471 "create a symbolic link",
3473 This command creates a symbolic link using the C<ln -sf> command,
3474 The C<-f> option removes the link (C<linkname>) if it exists already.");
3476 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3477 [] (* XXX tested above *),
3478 "read the target of a symbolic link",
3480 This command reads the target of a symbolic link.");
3482 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"],
3483 [InitBasicFS, Always, TestOutputStruct (
3484 [["fallocate"; "/a"; "1000000"];
3485 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3486 "preallocate a file in the guest filesystem",
3488 This command preallocates a file (containing zero bytes) named
3489 C<path> of size C<len> bytes. If the file exists already, it
3492 Do not confuse this with the guestfish-specific
3493 C<alloc> command which allocates a file in the host and
3494 attaches it as a device.");
3496 ("swapon_device", (RErr, [Device "device"]), 170, [],
3497 [InitPartition, Always, TestRun (
3498 [["mkswap"; "/dev/sda1"];
3499 ["swapon_device"; "/dev/sda1"];
3500 ["swapoff_device"; "/dev/sda1"]])],
3501 "enable swap on device",
3503 This command enables the libguestfs appliance to use the
3504 swap device or partition named C<device>. The increased
3505 memory is made available for all commands, for example
3506 those run using C<guestfs_command> or C<guestfs_sh>.
3508 Note that you should not swap to existing guest swap
3509 partitions unless you know what you are doing. They may
3510 contain hibernation information, or other information that
3511 the guest doesn't want you to trash. You also risk leaking
3512 information about the host to the guest this way. Instead,
3513 attach a new host device to the guest and swap on that.");
3515 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3516 [], (* XXX tested by swapon_device *)
3517 "disable swap on device",
3519 This command disables the libguestfs appliance swap
3520 device or partition named C<device>.
3521 See C<guestfs_swapon_device>.");
3523 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3524 [InitBasicFS, Always, TestRun (
3525 [["fallocate"; "/swap"; "8388608"];
3526 ["mkswap_file"; "/swap"];
3527 ["swapon_file"; "/swap"];
3528 ["swapoff_file"; "/swap"]])],
3529 "enable swap on file",
3531 This command enables swap to a file.
3532 See C<guestfs_swapon_device> for other notes.");
3534 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3535 [], (* XXX tested by swapon_file *)
3536 "disable swap on file",
3538 This command disables the libguestfs appliance swap on file.");
3540 ("swapon_label", (RErr, [String "label"]), 174, [],
3541 [InitEmpty, Always, TestRun (
3542 [["part_disk"; "/dev/sdb"; "mbr"];
3543 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3544 ["swapon_label"; "swapit"];
3545 ["swapoff_label"; "swapit"];
3546 ["zero"; "/dev/sdb"];
3547 ["blockdev_rereadpt"; "/dev/sdb"]])],
3548 "enable swap on labeled swap partition",
3550 This command enables swap to a labeled swap partition.
3551 See C<guestfs_swapon_device> for other notes.");
3553 ("swapoff_label", (RErr, [String "label"]), 175, [],
3554 [], (* XXX tested by swapon_label *)
3555 "disable swap on labeled swap partition",
3557 This command disables the libguestfs appliance swap on
3558 labeled swap partition.");
3560 ("swapon_uuid", (RErr, [String "uuid"]), 176, [Optional "linuxfsuuid"],
3561 (let uuid = uuidgen () in
3562 [InitEmpty, Always, TestRun (
3563 [["mkswap_U"; uuid; "/dev/sdb"];
3564 ["swapon_uuid"; uuid];
3565 ["swapoff_uuid"; uuid]])]),
3566 "enable swap on swap partition by UUID",
3568 This command enables swap to a swap partition with the given UUID.
3569 See C<guestfs_swapon_device> for other notes.");
3571 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [Optional "linuxfsuuid"],
3572 [], (* XXX tested by swapon_uuid *)
3573 "disable swap on swap partition by UUID",
3575 This command disables the libguestfs appliance swap partition
3576 with the given UUID.");
3578 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3579 [InitBasicFS, Always, TestRun (
3580 [["fallocate"; "/swap"; "8388608"];
3581 ["mkswap_file"; "/swap"]])],
3582 "create a swap file",
3586 This command just writes a swap file signature to an existing
3587 file. To create the file itself, use something like C<guestfs_fallocate>.");
3589 ("inotify_init", (RErr, [Int "maxevents"]), 179, [Optional "inotify"],
3590 [InitISOFS, Always, TestRun (
3591 [["inotify_init"; "0"]])],
3592 "create an inotify handle",
3594 This command creates a new inotify handle.
3595 The inotify subsystem can be used to notify events which happen to
3596 objects in the guest filesystem.
3598 C<maxevents> is the maximum number of events which will be
3599 queued up between calls to C<guestfs_inotify_read> or
3600 C<guestfs_inotify_files>.
3601 If this is passed as C<0>, then the kernel (or previously set)
3602 default is used. For Linux 2.6.29 the default was 16384 events.
3603 Beyond this limit, the kernel throws away events, but records
3604 the fact that it threw them away by setting a flag
3605 C<IN_Q_OVERFLOW> in the returned structure list (see
3606 C<guestfs_inotify_read>).
3608 Before any events are generated, you have to add some
3609 watches to the internal watch list. See:
3610 C<guestfs_inotify_add_watch>,
3611 C<guestfs_inotify_rm_watch> and
3612 C<guestfs_inotify_watch_all>.
3614 Queued up events should be read periodically by calling
3615 C<guestfs_inotify_read>
3616 (or C<guestfs_inotify_files> which is just a helpful
3617 wrapper around C<guestfs_inotify_read>). If you don't
3618 read the events out often enough then you risk the internal
3621 The handle should be closed after use by calling
3622 C<guestfs_inotify_close>. This also removes any
3623 watches automatically.
3625 See also L<inotify(7)> for an overview of the inotify interface
3626 as exposed by the Linux kernel, which is roughly what we expose
3627 via libguestfs. Note that there is one global inotify handle
3628 per libguestfs instance.");
3630 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [Optional "inotify"],
3631 [InitBasicFS, Always, TestOutputList (
3632 [["inotify_init"; "0"];
3633 ["inotify_add_watch"; "/"; "1073741823"];
3636 ["inotify_files"]], ["a"; "b"])],
3637 "add an inotify watch",
3639 Watch C<path> for the events listed in C<mask>.
3641 Note that if C<path> is a directory then events within that
3642 directory are watched, but this does I<not> happen recursively
3643 (in subdirectories).
3645 Note for non-C or non-Linux callers: the inotify events are
3646 defined by the Linux kernel ABI and are listed in
3647 C</usr/include/sys/inotify.h>.");
3649 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [Optional "inotify"],
3651 "remove an inotify watch",
3653 Remove a previously defined inotify watch.
3654 See C<guestfs_inotify_add_watch>.");
3656 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [Optional "inotify"],
3658 "return list of inotify events",
3660 Return the complete queue of events that have happened
3661 since the previous read call.
3663 If no events have happened, this returns an empty list.
3665 I<Note>: In order to make sure that all events have been
3666 read, you must call this function repeatedly until it
3667 returns an empty list. The reason is that the call will
3668 read events up to the maximum appliance-to-host message
3669 size and leave remaining events in the queue.");
3671 ("inotify_files", (RStringList "paths", []), 183, [Optional "inotify"],
3673 "return list of watched files that had events",
3675 This function is a helpful wrapper around C<guestfs_inotify_read>
3676 which just returns a list of pathnames of objects that were
3677 touched. The returned pathnames are sorted and deduplicated.");
3679 ("inotify_close", (RErr, []), 184, [Optional "inotify"],
3681 "close the inotify handle",
3683 This closes the inotify handle which was previously
3684 opened by inotify_init. It removes all watches, throws
3685 away any pending events, and deallocates all resources.");
3687 ("setcon", (RErr, [String "context"]), 185, [Optional "selinux"],
3689 "set SELinux security context",
3691 This sets the SELinux security context of the daemon
3692 to the string C<context>.
3694 See the documentation about SELINUX in L<guestfs(3)>.");
3696 ("getcon", (RString "context", []), 186, [Optional "selinux"],
3698 "get SELinux security context",
3700 This gets the SELinux security context of the daemon.
3702 See the documentation about SELINUX in L<guestfs(3)>,
3703 and C<guestfs_setcon>");
3705 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3706 [InitEmpty, Always, TestOutput (
3707 [["part_disk"; "/dev/sda"; "mbr"];
3708 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3709 ["mount_options"; ""; "/dev/sda1"; "/"];
3710 ["write"; "/new"; "new file contents"];
3711 ["cat"; "/new"]], "new file contents")],
3712 "make a filesystem with block size",
3714 This call is similar to C<guestfs_mkfs>, but it allows you to
3715 control the block size of the resulting filesystem. Supported
3716 block sizes depend on the filesystem type, but typically they
3717 are C<1024>, C<2048> or C<4096> only.");
3719 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3720 [InitEmpty, Always, TestOutput (
3721 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3722 ["mke2journal"; "4096"; "/dev/sda1"];
3723 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3724 ["mount_options"; ""; "/dev/sda2"; "/"];
3725 ["write"; "/new"; "new file contents"];
3726 ["cat"; "/new"]], "new file contents")],
3727 "make ext2/3/4 external journal",
3729 This creates an ext2 external journal on C<device>. It is equivalent
3732 mke2fs -O journal_dev -b blocksize device");
3734 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3735 [InitEmpty, Always, TestOutput (
3736 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3737 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3738 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3739 ["mount_options"; ""; "/dev/sda2"; "/"];
3740 ["write"; "/new"; "new file contents"];
3741 ["cat"; "/new"]], "new file contents")],
3742 "make ext2/3/4 external journal with label",
3744 This creates an ext2 external journal on C<device> with label C<label>.");
3746 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [Optional "linuxfsuuid"],
3747 (let uuid = uuidgen () in
3748 [InitEmpty, Always, TestOutput (
3749 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3750 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3751 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3752 ["mount_options"; ""; "/dev/sda2"; "/"];
3753 ["write"; "/new"; "new file contents"];
3754 ["cat"; "/new"]], "new file contents")]),
3755 "make ext2/3/4 external journal with UUID",
3757 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3759 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3761 "make ext2/3/4 filesystem with external journal",
3763 This creates an ext2/3/4 filesystem on C<device> with
3764 an external journal on C<journal>. It is equivalent
3767 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3769 See also C<guestfs_mke2journal>.");
3771 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3773 "make ext2/3/4 filesystem with external journal",
3775 This creates an ext2/3/4 filesystem on C<device> with
3776 an external journal on the journal labeled C<label>.
3778 See also C<guestfs_mke2journal_L>.");
3780 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [Optional "linuxfsuuid"],
3782 "make ext2/3/4 filesystem with external journal",
3784 This creates an ext2/3/4 filesystem on C<device> with
3785 an external journal on the journal with UUID C<uuid>.
3787 See also C<guestfs_mke2journal_U>.");
3789 ("modprobe", (RErr, [String "modulename"]), 194, [Optional "linuxmodules"],
3790 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3791 "load a kernel module",
3793 This loads a kernel module in the appliance.
3795 The kernel module must have been whitelisted when libguestfs
3796 was built (see C<appliance/kmod.whitelist.in> in the source).");
3798 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3799 [InitNone, Always, TestOutput (
3800 [["echo_daemon"; "This is a test"]], "This is a test"
3802 "echo arguments back to the client",
3804 This command concatenates the list of C<words> passed with single spaces
3805 between them and returns the resulting string.
3807 You can use this command to test the connection through to the daemon.
3809 See also C<guestfs_ping_daemon>.");
3811 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3812 [], (* There is a regression test for this. *)
3813 "find all files and directories, returning NUL-separated list",
3815 This command lists out all files and directories, recursively,
3816 starting at C<directory>, placing the resulting list in the
3817 external file called C<files>.
3819 This command works the same way as C<guestfs_find> with the
3820 following exceptions:
3826 The resulting list is written to an external file.
3830 Items (filenames) in the result are separated
3831 by C<\\0> characters. See L<find(1)> option I<-print0>.
3835 This command is not limited in the number of names that it
3840 The result list is not sorted.
3844 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3845 [InitISOFS, Always, TestOutput (
3846 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3847 InitISOFS, Always, TestOutput (
3848 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3849 InitISOFS, Always, TestOutput (
3850 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3851 InitISOFS, Always, TestLastFail (
3852 [["case_sensitive_path"; "/Known-1/"]]);
3853 InitBasicFS, Always, TestOutput (
3855 ["mkdir"; "/a/bbb"];
3856 ["touch"; "/a/bbb/c"];
3857 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3858 InitBasicFS, Always, TestOutput (
3860 ["mkdir"; "/a/bbb"];
3861 ["touch"; "/a/bbb/c"];
3862 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3863 InitBasicFS, Always, TestLastFail (
3865 ["mkdir"; "/a/bbb"];
3866 ["touch"; "/a/bbb/c"];
3867 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3868 "return true path on case-insensitive filesystem",
3870 This can be used to resolve case insensitive paths on
3871 a filesystem which is case sensitive. The use case is
3872 to resolve paths which you have read from Windows configuration
3873 files or the Windows Registry, to the true path.
3875 The command handles a peculiarity of the Linux ntfs-3g
3876 filesystem driver (and probably others), which is that although
3877 the underlying filesystem is case-insensitive, the driver
3878 exports the filesystem to Linux as case-sensitive.
3880 One consequence of this is that special directories such
3881 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3882 (or other things) depending on the precise details of how
3883 they were created. In Windows itself this would not be
3886 Bug or feature? You decide:
3887 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3889 This function resolves the true case of each element in the
3890 path and returns the case-sensitive path.
3892 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3893 might return C<\"/WINDOWS/system32\"> (the exact return value
3894 would depend on details of how the directories were originally
3895 created under Windows).
3898 This function does not handle drive names, backslashes etc.
3900 See also C<guestfs_realpath>.");
3902 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3903 [InitBasicFS, Always, TestOutput (
3904 [["vfs_type"; "/dev/sda1"]], "ext2")],
3905 "get the Linux VFS type corresponding to a mounted device",
3907 This command gets the block device type corresponding to
3908 a mounted device called C<device>.
3910 Usually the result is the name of the Linux VFS module that
3911 is used to mount this device (probably determined automatically
3912 if you used the C<guestfs_mount> call).");
3914 ("truncate", (RErr, [Pathname "path"]), 199, [],
3915 [InitBasicFS, Always, TestOutputStruct (
3916 [["write"; "/test"; "some stuff so size is not zero"];
3917 ["truncate"; "/test"];
3918 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3919 "truncate a file to zero size",
3921 This command truncates C<path> to a zero-length file. The
3922 file must exist already.");
3924 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3925 [InitBasicFS, Always, TestOutputStruct (
3926 [["touch"; "/test"];
3927 ["truncate_size"; "/test"; "1000"];
3928 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3929 "truncate a file to a particular size",
3931 This command truncates C<path> to size C<size> bytes. The file
3934 If the current file size is less than C<size> then
3935 the file is extended to the required size with zero bytes.
3936 This creates a sparse file (ie. disk blocks are not allocated
3937 for the file until you write to it). To create a non-sparse
3938 file of zeroes, use C<guestfs_fallocate64> instead.");
3940 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3941 [InitBasicFS, Always, TestOutputStruct (
3942 [["touch"; "/test"];
3943 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3944 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3945 "set timestamp of a file with nanosecond precision",
3947 This command sets the timestamps of a file with nanosecond
3950 C<atsecs, atnsecs> are the last access time (atime) in secs and
3951 nanoseconds from the epoch.
3953 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3954 secs and nanoseconds from the epoch.
3956 If the C<*nsecs> field contains the special value C<-1> then
3957 the corresponding timestamp is set to the current time. (The
3958 C<*secs> field is ignored in this case).
3960 If the C<*nsecs> field contains the special value C<-2> then
3961 the corresponding timestamp is left unchanged. (The
3962 C<*secs> field is ignored in this case).");
3964 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
3965 [InitBasicFS, Always, TestOutputStruct (
3966 [["mkdir_mode"; "/test"; "0o111"];
3967 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
3968 "create a directory with a particular mode",
3970 This command creates a directory, setting the initial permissions
3971 of the directory to C<mode>.
3973 For common Linux filesystems, the actual mode which is set will
3974 be C<mode & ~umask & 01777>. Non-native-Linux filesystems may
3975 interpret the mode in other ways.
3977 See also C<guestfs_mkdir>, C<guestfs_umask>");
3979 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
3981 "change file owner and group",
3983 Change the file owner to C<owner> and group to C<group>.
3984 This is like C<guestfs_chown> but if C<path> is a symlink then
3985 the link itself is changed, not the target.
3987 Only numeric uid and gid are supported. If you want to use
3988 names, you will need to locate and parse the password file
3989 yourself (Augeas support makes this relatively easy).");
3991 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
3993 "lstat on multiple files",
3995 This call allows you to perform the C<guestfs_lstat> operation
3996 on multiple files, where all files are in the directory C<path>.
3997 C<names> is the list of files from this directory.
3999 On return you get a list of stat structs, with a one-to-one
4000 correspondence to the C<names> list. If any name did not exist
4001 or could not be lstat'd, then the C<ino> field of that structure
4004 This call is intended for programs that want to efficiently
4005 list a directory contents without making many round-trips.
4006 See also C<guestfs_lxattrlist> for a similarly efficient call
4007 for getting extended attributes. Very long directory listings
4008 might cause the protocol message size to be exceeded, causing
4009 this call to fail. The caller must split up such requests
4010 into smaller groups of names.");
4012 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [Optional "linuxxattrs"],
4014 "lgetxattr on multiple files",
4016 This call allows you to get the extended attributes
4017 of multiple files, where all files are in the directory C<path>.
4018 C<names> is the list of files from this directory.
4020 On return you get a flat list of xattr structs which must be
4021 interpreted sequentially. The first xattr struct always has a zero-length
4022 C<attrname>. C<attrval> in this struct is zero-length
4023 to indicate there was an error doing C<lgetxattr> for this
4024 file, I<or> is a C string which is a decimal number
4025 (the number of following attributes for this file, which could
4026 be C<\"0\">). Then after the first xattr struct are the
4027 zero or more attributes for the first named file.
4028 This repeats for the second and subsequent files.
4030 This call is intended for programs that want to efficiently
4031 list a directory contents without making many round-trips.
4032 See also C<guestfs_lstatlist> for a similarly efficient call
4033 for getting standard stats. Very long directory listings
4034 might cause the protocol message size to be exceeded, causing
4035 this call to fail. The caller must split up such requests
4036 into smaller groups of names.");
4038 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
4040 "readlink on multiple files",
4042 This call allows you to do a C<readlink> operation
4043 on multiple files, where all files are in the directory C<path>.
4044 C<names> is the list of files from this directory.
4046 On return you get a list of strings, with a one-to-one
4047 correspondence to the C<names> list. Each string is the
4048 value of the symbolic link.
4050 If the C<readlink(2)> operation fails on any name, then
4051 the corresponding result string is the empty string C<\"\">.
4052 However the whole operation is completed even if there
4053 were C<readlink(2)> errors, and so you can call this
4054 function with names where you don't know if they are
4055 symbolic links already (albeit slightly less efficient).
4057 This call is intended for programs that want to efficiently
4058 list a directory contents without making many round-trips.
4059 Very long directory listings might cause the protocol
4060 message size to be exceeded, causing
4061 this call to fail. The caller must split up such requests
4062 into smaller groups of names.");
4064 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
4065 [InitISOFS, Always, TestOutputBuffer (
4066 [["pread"; "/known-4"; "1"; "3"]], "\n");
4067 InitISOFS, Always, TestOutputBuffer (
4068 [["pread"; "/empty"; "0"; "100"]], "")],
4069 "read part of a file",
4071 This command lets you read part of a file. It reads C<count>
4072 bytes of the file, starting at C<offset>, from file C<path>.
4074 This may read fewer bytes than requested. For further details
4075 see the L<pread(2)> system call.
4077 See also C<guestfs_pwrite>.");
4079 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
4080 [InitEmpty, Always, TestRun (
4081 [["part_init"; "/dev/sda"; "gpt"]])],
4082 "create an empty partition table",
4084 This creates an empty partition table on C<device> of one of the
4085 partition types listed below. Usually C<parttype> should be
4086 either C<msdos> or C<gpt> (for large disks).
4088 Initially there are no partitions. Following this, you should
4089 call C<guestfs_part_add> for each partition required.
4091 Possible values for C<parttype> are:
4095 =item B<efi> | B<gpt>
4097 Intel EFI / GPT partition table.
4099 This is recommended for >= 2 TB partitions that will be accessed
4100 from Linux and Intel-based Mac OS X. It also has limited backwards
4101 compatibility with the C<mbr> format.
4103 =item B<mbr> | B<msdos>
4105 The standard PC \"Master Boot Record\" (MBR) format used
4106 by MS-DOS and Windows. This partition type will B<only> work
4107 for device sizes up to 2 TB. For large disks we recommend
4112 Other partition table types that may work but are not
4121 =item B<amiga> | B<rdb>
4123 Amiga \"Rigid Disk Block\" format.
4131 DASD, used on IBM mainframes.
4139 Old Mac partition format. Modern Macs use C<gpt>.
4143 NEC PC-98 format, common in Japan apparently.
4151 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
4152 [InitEmpty, Always, TestRun (
4153 [["part_init"; "/dev/sda"; "mbr"];
4154 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
4155 InitEmpty, Always, TestRun (
4156 [["part_init"; "/dev/sda"; "gpt"];
4157 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
4158 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
4159 InitEmpty, Always, TestRun (
4160 [["part_init"; "/dev/sda"; "mbr"];
4161 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
4162 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
4163 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
4164 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
4165 "add a partition to the device",
4167 This command adds a partition to C<device>. If there is no partition
4168 table on the device, call C<guestfs_part_init> first.
4170 The C<prlogex> parameter is the type of partition. Normally you
4171 should pass C<p> or C<primary> here, but MBR partition tables also
4172 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4175 C<startsect> and C<endsect> are the start and end of the partition
4176 in I<sectors>. C<endsect> may be negative, which means it counts
4177 backwards from the end of the disk (C<-1> is the last sector).
4179 Creating a partition which covers the whole disk is not so easy.
4180 Use C<guestfs_part_disk> to do that.");
4182 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4183 [InitEmpty, Always, TestRun (
4184 [["part_disk"; "/dev/sda"; "mbr"]]);
4185 InitEmpty, Always, TestRun (
4186 [["part_disk"; "/dev/sda"; "gpt"]])],
4187 "partition whole disk with a single primary partition",
4189 This command is simply a combination of C<guestfs_part_init>
4190 followed by C<guestfs_part_add> to create a single primary partition
4191 covering the whole disk.
4193 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4194 but other possible values are described in C<guestfs_part_init>.");
4196 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4197 [InitEmpty, Always, TestRun (
4198 [["part_disk"; "/dev/sda"; "mbr"];
4199 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4200 "make a partition bootable",
4202 This sets the bootable flag on partition numbered C<partnum> on
4203 device C<device>. Note that partitions are numbered from 1.
4205 The bootable flag is used by some operating systems (notably
4206 Windows) to determine which partition to boot from. It is by
4207 no means universally recognized.");
4209 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4210 [InitEmpty, Always, TestRun (
4211 [["part_disk"; "/dev/sda"; "gpt"];
4212 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4213 "set partition name",
4215 This sets the partition name on partition numbered C<partnum> on
4216 device C<device>. Note that partitions are numbered from 1.
4218 The partition name can only be set on certain types of partition
4219 table. This works on C<gpt> but not on C<mbr> partitions.");
4221 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4222 [], (* XXX Add a regression test for this. *)
4223 "list partitions on a device",
4225 This command parses the partition table on C<device> and
4226 returns the list of partitions found.
4228 The fields in the returned structure are:
4234 Partition number, counting from 1.
4238 Start of the partition I<in bytes>. To get sectors you have to
4239 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4243 End of the partition in bytes.
4247 Size of the partition in bytes.
4251 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4252 [InitEmpty, Always, TestOutput (
4253 [["part_disk"; "/dev/sda"; "gpt"];
4254 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4255 "get the partition table type",
4257 This command examines the partition table on C<device> and
4258 returns the partition table type (format) being used.
4260 Common return values include: C<msdos> (a DOS/Windows style MBR
4261 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4262 values are possible, although unusual. See C<guestfs_part_init>
4265 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4266 [InitBasicFS, Always, TestOutputBuffer (
4267 [["fill"; "0x63"; "10"; "/test"];
4268 ["read_file"; "/test"]], "cccccccccc")],
4269 "fill a file with octets",
4271 This command creates a new file called C<path>. The initial
4272 content of the file is C<len> octets of C<c>, where C<c>
4273 must be a number in the range C<[0..255]>.
4275 To fill a file with zero bytes (sparsely), it is
4276 much more efficient to use C<guestfs_truncate_size>.
4277 To create a file with a pattern of repeating bytes
4278 use C<guestfs_fill_pattern>.");
4280 ("available", (RErr, [StringList "groups"]), 216, [],
4281 [InitNone, Always, TestRun [["available"; ""]]],
4282 "test availability of some parts of the API",
4284 This command is used to check the availability of some
4285 groups of functionality in the appliance, which not all builds of
4286 the libguestfs appliance will be able to provide.
4288 The libguestfs groups, and the functions that those
4289 groups correspond to, are listed in L<guestfs(3)/AVAILABILITY>.
4290 You can also fetch this list at runtime by calling
4291 C<guestfs_available_all_groups>.
4293 The argument C<groups> is a list of group names, eg:
4294 C<[\"inotify\", \"augeas\"]> would check for the availability of
4295 the Linux inotify functions and Augeas (configuration file
4298 The command returns no error if I<all> requested groups are available.
4300 It fails with an error if one or more of the requested
4301 groups is unavailable in the appliance.
4303 If an unknown group name is included in the
4304 list of groups then an error is always returned.
4312 You must call C<guestfs_launch> before calling this function.
4314 The reason is because we don't know what groups are
4315 supported by the appliance/daemon until it is running and can
4320 If a group of functions is available, this does not necessarily
4321 mean that they will work. You still have to check for errors
4322 when calling individual API functions even if they are
4327 It is usually the job of distro packagers to build
4328 complete functionality into the libguestfs appliance.
4329 Upstream libguestfs, if built from source with all
4330 requirements satisfied, will support everything.
4334 This call was added in version C<1.0.80>. In previous
4335 versions of libguestfs all you could do would be to speculatively
4336 execute a command to find out if the daemon implemented it.
4337 See also C<guestfs_version>.
4341 ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [],
4342 [InitBasicFS, Always, TestOutputBuffer (
4343 [["write"; "/src"; "hello, world"];
4344 ["dd"; "/src"; "/dest"];
4345 ["read_file"; "/dest"]], "hello, world")],
4346 "copy from source to destination using dd",
4348 This command copies from one source device or file C<src>
4349 to another destination device or file C<dest>. Normally you
4350 would use this to copy to or from a device or partition, for
4351 example to duplicate a filesystem.
4353 If the destination is a device, it must be as large or larger
4354 than the source file or device, otherwise the copy will fail.
4355 This command cannot do partial copies (see C<guestfs_copy_size>).");
4357 ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
4358 [InitBasicFS, Always, TestOutputInt (
4359 [["write"; "/file"; "hello, world"];
4360 ["filesize"; "/file"]], 12)],
4361 "return the size of the file in bytes",
4363 This command returns the size of C<file> in bytes.
4365 To get other stats about a file, use C<guestfs_stat>, C<guestfs_lstat>,
4366 C<guestfs_is_dir>, C<guestfs_is_file> etc.
4367 To get the size of block devices, use C<guestfs_blockdev_getsize64>.");
4369 ("lvrename", (RErr, [String "logvol"; String "newlogvol"]), 219, [],
4370 [InitBasicFSonLVM, Always, TestOutputList (
4371 [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
4372 ["lvs"]], ["/dev/VG/LV2"])],
4373 "rename an LVM logical volume",
4375 Rename a logical volume C<logvol> with the new name C<newlogvol>.");
4377 ("vgrename", (RErr, [String "volgroup"; String "newvolgroup"]), 220, [],
4378 [InitBasicFSonLVM, Always, TestOutputList (
4380 ["vg_activate"; "false"; "VG"];
4381 ["vgrename"; "VG"; "VG2"];
4382 ["vg_activate"; "true"; "VG2"];
4383 ["mount_options"; ""; "/dev/VG2/LV"; "/"];
4384 ["vgs"]], ["VG2"])],
4385 "rename an LVM volume group",
4387 Rename a volume group C<volgroup> with the new name C<newvolgroup>.");
4389 ("initrd_cat", (RBufferOut "content", [Pathname "initrdpath"; String "filename"]), 221, [ProtocolLimitWarning],
4390 [InitISOFS, Always, TestOutputBuffer (
4391 [["initrd_cat"; "/initrd"; "known-4"]], "abc\ndef\nghi")],
4392 "list the contents of a single file in an initrd",
4394 This command unpacks the file C<filename> from the initrd file
4395 called C<initrdpath>. The filename must be given I<without> the
4396 initial C</> character.
4398 For example, in guestfish you could use the following command
4399 to examine the boot script (usually called C</init>)
4400 contained in a Linux initrd or initramfs image:
4402 initrd-cat /boot/initrd-<version>.img init
4404 See also C<guestfs_initrd_list>.");
4406 ("pvuuid", (RString "uuid", [Device "device"]), 222, [],
4408 "get the UUID of a physical volume",
4410 This command returns the UUID of the LVM PV C<device>.");
4412 ("vguuid", (RString "uuid", [String "vgname"]), 223, [],
4414 "get the UUID of a volume group",
4416 This command returns the UUID of the LVM VG named C<vgname>.");
4418 ("lvuuid", (RString "uuid", [Device "device"]), 224, [],
4420 "get the UUID of a logical volume",
4422 This command returns the UUID of the LVM LV C<device>.");
4424 ("vgpvuuids", (RStringList "uuids", [String "vgname"]), 225, [],
4426 "get the PV UUIDs containing the volume group",
4428 Given a VG called C<vgname>, this returns the UUIDs of all
4429 the physical volumes that this volume group resides on.
4431 You can use this along with C<guestfs_pvs> and C<guestfs_pvuuid>
4432 calls to associate physical volumes and volume groups.
4434 See also C<guestfs_vglvuuids>.");
4436 ("vglvuuids", (RStringList "uuids", [String "vgname"]), 226, [],
4438 "get the LV UUIDs of all LVs in the volume group",
4440 Given a VG called C<vgname>, this returns the UUIDs of all
4441 the logical volumes created in this volume group.
4443 You can use this along with C<guestfs_lvs> and C<guestfs_lvuuid>
4444 calls to associate logical volumes and volume groups.
4446 See also C<guestfs_vgpvuuids>.");
4448 ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
4449 [InitBasicFS, Always, TestOutputBuffer (
4450 [["write"; "/src"; "hello, world"];
4451 ["copy_size"; "/src"; "/dest"; "5"];
4452 ["read_file"; "/dest"]], "hello")],
4453 "copy size bytes from source to destination using dd",
4455 This command copies exactly C<size> bytes from one source device
4456 or file C<src> to another destination device or file C<dest>.
4458 Note this will fail if the source is too short or if the destination
4459 is not large enough.");
4461 ("zero_device", (RErr, [Device "device"]), 228, [DangerWillRobinson],
4462 [InitBasicFSonLVM, Always, TestRun (
4463 [["zero_device"; "/dev/VG/LV"]])],
4464 "write zeroes to an entire device",
4466 This command writes zeroes over the entire C<device>. Compare
4467 with C<guestfs_zero> which just zeroes the first few blocks of
4470 ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"],
4471 [InitBasicFS, Always, TestOutput (
4472 [["txz_in"; "../images/helloworld.tar.xz"; "/"];
4473 ["cat"; "/hello"]], "hello\n")],
4474 "unpack compressed tarball to directory",
4476 This command uploads and unpacks local file C<tarball> (an
4477 I<xz compressed> tar file) into C<directory>.");
4479 ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"],
4481 "pack directory into compressed tarball",
4483 This command packs the contents of C<directory> and downloads
4484 it to local file C<tarball> (as an xz compressed tar archive).");
4486 ("ntfsresize", (RErr, [Device "device"]), 231, [Optional "ntfsprogs"],
4488 "resize an NTFS filesystem",
4490 This command resizes an NTFS filesystem, expanding or
4491 shrinking it to the size of the underlying device.
4492 See also L<ntfsresize(8)>.");
4494 ("vgscan", (RErr, []), 232, [],
4495 [InitEmpty, Always, TestRun (
4497 "rescan for LVM physical volumes, volume groups and logical volumes",
4499 This rescans all block devices and rebuilds the list of LVM
4500 physical volumes, volume groups and logical volumes.");
4502 ("part_del", (RErr, [Device "device"; Int "partnum"]), 233, [],
4503 [InitEmpty, Always, TestRun (
4504 [["part_init"; "/dev/sda"; "mbr"];
4505 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4506 ["part_del"; "/dev/sda"; "1"]])],
4507 "delete a partition",
4509 This command deletes the partition numbered C<partnum> on C<device>.
4511 Note that in the case of MBR partitioning, deleting an
4512 extended partition also deletes any logical partitions
4515 ("part_get_bootable", (RBool "bootable", [Device "device"; Int "partnum"]), 234, [],
4516 [InitEmpty, Always, TestOutputTrue (
4517 [["part_init"; "/dev/sda"; "mbr"];
4518 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4519 ["part_set_bootable"; "/dev/sda"; "1"; "true"];
4520 ["part_get_bootable"; "/dev/sda"; "1"]])],
4521 "return true if a partition is bootable",
4523 This command returns true if the partition C<partnum> on
4524 C<device> has the bootable flag set.
4526 See also C<guestfs_part_set_bootable>.");
4528 ("part_get_mbr_id", (RInt "idbyte", [Device "device"; Int "partnum"]), 235, [FishOutput FishOutputHexadecimal],
4529 [InitEmpty, Always, TestOutputInt (
4530 [["part_init"; "/dev/sda"; "mbr"];
4531 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4532 ["part_set_mbr_id"; "/dev/sda"; "1"; "0x7f"];
4533 ["part_get_mbr_id"; "/dev/sda"; "1"]], 0x7f)],
4534 "get the MBR type byte (ID byte) from a partition",
4536 Returns the MBR type byte (also known as the ID byte) from
4537 the numbered partition C<partnum>.
4539 Note that only MBR (old DOS-style) partitions have type bytes.
4540 You will get undefined results for other partition table
4541 types (see C<guestfs_part_get_parttype>).");
4543 ("part_set_mbr_id", (RErr, [Device "device"; Int "partnum"; Int "idbyte"]), 236, [],
4544 [], (* tested by part_get_mbr_id *)
4545 "set the MBR type byte (ID byte) of a partition",
4547 Sets the MBR type byte (also known as the ID byte) of
4548 the numbered partition C<partnum> to C<idbyte>. Note
4549 that the type bytes quoted in most documentation are
4550 in fact hexadecimal numbers, but usually documented
4551 without any leading \"0x\" which might be confusing.
4553 Note that only MBR (old DOS-style) partitions have type bytes.
4554 You will get undefined results for other partition table
4555 types (see C<guestfs_part_get_parttype>).");
4557 ("checksum_device", (RString "checksum", [String "csumtype"; Device "device"]), 237, [],
4558 [InitISOFS, Always, TestOutput (
4559 [["checksum_device"; "md5"; "/dev/sdd"]],
4560 (Digest.to_hex (Digest.file "images/test.iso")))],
4561 "compute MD5, SHAx or CRC checksum of the contents of a device",
4563 This call computes the MD5, SHAx or CRC checksum of the
4564 contents of the device named C<device>. For the types of
4565 checksums supported see the C<guestfs_checksum> command.");
4567 ("lvresize_free", (RErr, [Device "lv"; Int "percent"]), 238, [Optional "lvm2"],
4568 [InitNone, Always, TestRun (
4569 [["part_disk"; "/dev/sda"; "mbr"];
4570 ["pvcreate"; "/dev/sda1"];
4571 ["vgcreate"; "VG"; "/dev/sda1"];
4572 ["lvcreate"; "LV"; "VG"; "10"];
4573 ["lvresize_free"; "/dev/VG/LV"; "100"]])],
4574 "expand an LV to fill free space",
4576 This expands an existing logical volume C<lv> so that it fills
4577 C<pc>% of the remaining free space in the volume group. Commonly
4578 you would call this with pc = 100 which expands the logical volume
4579 as much as possible, using all remaining free space in the volume
4582 ("aug_clear", (RErr, [String "augpath"]), 239, [Optional "augeas"],
4583 [], (* XXX Augeas code needs tests. *)
4584 "clear Augeas path",
4586 Set the value associated with C<path> to C<NULL>. This
4587 is the same as the L<augtool(1)> C<clear> command.");
4589 ("get_umask", (RInt "mask", []), 240, [FishOutput FishOutputOctal],
4590 [InitEmpty, Always, TestOutputInt (
4591 [["get_umask"]], 0o22)],
4592 "get the current umask",
4594 Return the current umask. By default the umask is C<022>
4595 unless it has been set by calling C<guestfs_umask>.");
4597 ("debug_upload", (RErr, [FileIn "filename"; String "tmpname"; Int "mode"]), 241, [],
4599 "upload a file to the appliance (internal use only)",
4601 The C<guestfs_debug_upload> command uploads a file to
4602 the libguestfs appliance.
4604 There is no comprehensive help for this command. You have
4605 to look at the file C<daemon/debug.c> in the libguestfs source
4606 to find out what it is for.");
4608 ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
4609 [InitBasicFS, Always, TestOutput (
4610 [["base64_in"; "../images/hello.b64"; "/hello"];
4611 ["cat"; "/hello"]], "hello\n")],
4612 "upload base64-encoded data to file",
4614 This command uploads base64-encoded data from C<base64file>
4617 ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
4619 "download file and encode as base64",
4621 This command downloads the contents of C<filename>, writing
4622 it out to local file C<base64file> encoded as base64.");
4624 ("checksums_out", (RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"]), 244, [],
4626 "compute MD5, SHAx or CRC checksum of files in a directory",
4628 This command computes the checksums of all regular files in
4629 C<directory> and then emits a list of those checksums to
4630 the local output file C<sumsfile>.
4632 This can be used for verifying the integrity of a virtual
4633 machine. However to be properly secure you should pay
4634 attention to the output of the checksum command (it uses
4635 the ones from GNU coreutils). In particular when the
4636 filename is not printable, coreutils uses a special
4637 backslash syntax. For more information, see the GNU
4638 coreutils info file.");
4640 ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
4641 [InitBasicFS, Always, TestOutputBuffer (
4642 [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
4643 ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
4644 "fill a file with a repeating pattern of bytes",
4646 This function is like C<guestfs_fill> except that it creates
4647 a new file of length C<len> containing the repeating pattern
4648 of bytes in C<pattern>. The pattern is truncated if necessary
4649 to ensure the length of the file is exactly C<len> bytes.");
4651 ("write", (RErr, [Pathname "path"; BufferIn "content"]), 246, [ProtocolLimitWarning],
4652 [InitBasicFS, Always, TestOutput (
4653 [["write"; "/new"; "new file contents"];
4654 ["cat"; "/new"]], "new file contents");
4655 InitBasicFS, Always, TestOutput (
4656 [["write"; "/new"; "\nnew file contents\n"];
4657 ["cat"; "/new"]], "\nnew file contents\n");
4658 InitBasicFS, Always, TestOutput (
4659 [["write"; "/new"; "\n\n"];
4660 ["cat"; "/new"]], "\n\n");
4661 InitBasicFS, Always, TestOutput (
4662 [["write"; "/new"; ""];
4663 ["cat"; "/new"]], "");
4664 InitBasicFS, Always, TestOutput (
4665 [["write"; "/new"; "\n\n\n"];
4666 ["cat"; "/new"]], "\n\n\n");
4667 InitBasicFS, Always, TestOutput (
4668 [["write"; "/new"; "\n"];
4669 ["cat"; "/new"]], "\n")],
4670 "create a new file",
4672 This call creates a file called C<path>. The content of the
4673 file is the string C<content> (which can contain any 8 bit data).");
4675 ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
4676 [InitBasicFS, Always, TestOutput (
4677 [["write"; "/new"; "new file contents"];
4678 ["pwrite"; "/new"; "data"; "4"];
4679 ["cat"; "/new"]], "new data contents");
4680 InitBasicFS, Always, TestOutput (
4681 [["write"; "/new"; "new file contents"];
4682 ["pwrite"; "/new"; "is extended"; "9"];
4683 ["cat"; "/new"]], "new file is extended");
4684 InitBasicFS, Always, TestOutput (
4685 [["write"; "/new"; "new file contents"];
4686 ["pwrite"; "/new"; ""; "4"];
4687 ["cat"; "/new"]], "new file contents")],
4688 "write to part of a file",
4690 This command writes to part of a file. It writes the data
4691 buffer C<content> to the file C<path> starting at offset C<offset>.
4693 This command implements the L<pwrite(2)> system call, and like
4694 that system call it may not write the full data requested. The
4695 return value is the number of bytes that were actually written
4696 to the file. This could even be 0, although short writes are
4697 unlikely for regular files in ordinary circumstances.
4699 See also C<guestfs_pread>.");
4701 ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [],
4703 "resize an ext2/ext3 filesystem (with size)",
4705 This command is the same as C<guestfs_resize2fs> except that it
4706 allows you to specify the new size (in bytes) explicitly.");
4708 ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"],
4710 "resize an LVM physical volume (with size)",
4712 This command is the same as C<guestfs_pvresize> except that it
4713 allows you to specify the new size (in bytes) explicitly.");
4715 ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"],
4717 "resize an NTFS filesystem (with size)",
4719 This command is the same as C<guestfs_ntfsresize> except that it
4720 allows you to specify the new size (in bytes) explicitly.");
4722 ("available_all_groups", (RStringList "groups", []), 251, [],
4723 [InitNone, Always, TestRun [["available_all_groups"]]],
4724 "return a list of all optional groups",
4726 This command returns a list of all optional groups that this
4727 daemon knows about. Note this returns both supported and unsupported
4728 groups. To find out which ones the daemon can actually support
4729 you have to call C<guestfs_available> on each member of the
4732 See also C<guestfs_available> and L<guestfs(3)/AVAILABILITY>.");
4734 ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [],
4735 [InitBasicFS, Always, TestOutputStruct (
4736 [["fallocate64"; "/a"; "1000000"];
4737 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
4738 "preallocate a file in the guest filesystem",
4740 This command preallocates a file (containing zero bytes) named
4741 C<path> of size C<len> bytes. If the file exists already, it
4744 Note that this call allocates disk blocks for the file.
4745 To create a sparse file use C<guestfs_truncate_size> instead.
4747 The deprecated call C<guestfs_fallocate> does the same,
4748 but owing to an oversight it only allowed 30 bit lengths
4749 to be specified, effectively limiting the maximum size
4750 of files created through that call to 1GB.
4752 Do not confuse this with the guestfish-specific
4753 C<alloc> and C<sparse> commands which create
4754 a file in the host and attach it as a device.");
4758 let all_functions = non_daemon_functions @ daemon_functions
4760 (* In some places we want the functions to be displayed sorted
4761 * alphabetically, so this is useful:
4763 let all_functions_sorted =
4764 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4765 compare n1 n2) all_functions
4767 (* This is used to generate the src/MAX_PROC_NR file which
4768 * contains the maximum procedure number, a surrogate for the
4769 * ABI version number. See src/Makefile.am for the details.
4772 let proc_nrs = List.map (
4773 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
4774 ) daemon_functions in
4775 List.fold_left max 0 proc_nrs
4777 (* Field types for structures. *)
4779 | FChar (* C 'char' (really, a 7 bit byte). *)
4780 | FString (* nul-terminated ASCII string, NOT NULL. *)
4781 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4786 | FBytes (* Any int measure that counts bytes. *)
4787 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4788 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4790 (* Because we generate extra parsing code for LVM command line tools,
4791 * we have to pull out the LVM columns separately here.
4801 "pv_attr", FString (* XXX *);
4802 "pv_pe_count", FInt64;
4803 "pv_pe_alloc_count", FInt64;
4806 "pv_mda_count", FInt64;
4807 "pv_mda_free", FBytes;
4808 (* Not in Fedora 10:
4809 "pv_mda_size", FBytes;
4816 "vg_attr", FString (* XXX *);
4819 "vg_sysid", FString;
4820 "vg_extent_size", FBytes;
4821 "vg_extent_count", FInt64;
4822 "vg_free_count", FInt64;
4827 "snap_count", FInt64;
4830 "vg_mda_count", FInt64;
4831 "vg_mda_free", FBytes;
4832 (* Not in Fedora 10:
4833 "vg_mda_size", FBytes;
4839 "lv_attr", FString (* XXX *);
4842 "lv_kernel_major", FInt64;
4843 "lv_kernel_minor", FInt64;
4845 "seg_count", FInt64;
4847 "snap_percent", FOptPercent;
4848 "copy_percent", FOptPercent;
4851 "mirror_log", FString;
4855 (* Names and fields in all structures (in RStruct and RStructList)
4859 (* The old RIntBool return type, only ever used for aug_defnode. Do
4860 * not use this struct in any new code.
4863 "i", FInt32; (* for historical compatibility *)
4864 "b", FInt32; (* for historical compatibility *)
4867 (* LVM PVs, VGs, LVs. *)
4868 "lvm_pv", lvm_pv_cols;
4869 "lvm_vg", lvm_vg_cols;
4870 "lvm_lv", lvm_lv_cols;
4872 (* Column names and types from stat structures.
4873 * NB. Can't use things like 'st_atime' because glibc header files
4874 * define some of these as macros. Ugh.
4905 (* Column names in dirent structure. *)
4908 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4913 (* Version numbers. *)
4921 (* Extended attribute. *)
4923 "attrname", FString;
4927 (* Inotify events. *)
4931 "in_cookie", FUInt32;
4935 (* Partition table entry. *)
4938 "part_start", FBytes;
4940 "part_size", FBytes;
4942 ] (* end of structs *)
4944 (* Ugh, Java has to be different ..
4945 * These names are also used by the Haskell bindings.
4947 let java_structs = [
4948 "int_bool", "IntBool";
4953 "statvfs", "StatVFS";
4955 "version", "Version";
4957 "inotify_event", "INotifyEvent";
4958 "partition", "Partition";
4961 (* What structs are actually returned. *)
4962 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
4964 (* Returns a list of RStruct/RStructList structs that are returned
4965 * by any function. Each element of returned list is a pair:
4967 * (structname, RStructOnly)
4968 * == there exists function which returns RStruct (_, structname)
4969 * (structname, RStructListOnly)
4970 * == there exists function which returns RStructList (_, structname)
4971 * (structname, RStructAndList)
4972 * == there are functions returning both RStruct (_, structname)
4973 * and RStructList (_, structname)
4975 let rstructs_used_by functions =
4976 (* ||| is a "logical OR" for rstructs_used_t *)
4980 | _, RStructAndList -> RStructAndList
4981 | RStructOnly, RStructListOnly
4982 | RStructListOnly, RStructOnly -> RStructAndList
4983 | RStructOnly, RStructOnly -> RStructOnly
4984 | RStructListOnly, RStructListOnly -> RStructListOnly
4987 let h = Hashtbl.create 13 in
4989 (* if elem->oldv exists, update entry using ||| operator,
4990 * else just add elem->newv to the hash
4992 let update elem newv =
4993 try let oldv = Hashtbl.find h elem in
4994 Hashtbl.replace h elem (newv ||| oldv)
4995 with Not_found -> Hashtbl.add h elem newv
4999 fun (_, style, _, _, _, _, _) ->
5000 match fst style with
5001 | RStruct (_, structname) -> update structname RStructOnly
5002 | RStructList (_, structname) -> update structname RStructListOnly
5006 (* return key->values as a list of (key,value) *)
5007 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
5009 (* Used for testing language bindings. *)
5011 | CallString of string
5012 | CallOptString of string option
5013 | CallStringList of string list
5015 | CallInt64 of int64
5017 | CallBuffer of string
5019 (* Used to memoize the result of pod2text. *)
5020 let pod2text_memo_filename = "src/.pod2text.data"
5021 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
5023 let chan = open_in pod2text_memo_filename in
5024 let v = input_value chan in
5028 _ -> Hashtbl.create 13
5029 let pod2text_memo_updated () =
5030 let chan = open_out pod2text_memo_filename in
5031 output_value chan pod2text_memo;
5034 (* Useful functions.
5035 * Note we don't want to use any external OCaml libraries which
5036 * makes this a bit harder than it should be.
5038 module StringMap = Map.Make (String)
5040 let failwithf fs = ksprintf failwith fs
5042 let unique = let i = ref 0 in fun () -> incr i; !i
5044 let replace_char s c1 c2 =
5045 let s2 = String.copy s in
5046 let r = ref false in
5047 for i = 0 to String.length s2 - 1 do
5048 if String.unsafe_get s2 i = c1 then (
5049 String.unsafe_set s2 i c2;
5053 if not !r then s else s2
5057 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
5059 let triml ?(test = isspace) str =
5061 let n = ref (String.length str) in
5062 while !n > 0 && test str.[!i]; do
5067 else String.sub str !i !n
5069 let trimr ?(test = isspace) str =
5070 let n = ref (String.length str) in
5071 while !n > 0 && test str.[!n-1]; do
5074 if !n = String.length str then str
5075 else String.sub str 0 !n
5077 let trim ?(test = isspace) str =
5078 trimr ~test (triml ~test str)
5080 let rec find s sub =
5081 let len = String.length s in
5082 let sublen = String.length sub in
5084 if i <= len-sublen then (
5086 if j < sublen then (
5087 if s.[i+j] = sub.[j] then loop2 (j+1)
5093 if r = -1 then loop (i+1) else r
5099 let rec replace_str s s1 s2 =
5100 let len = String.length s in
5101 let sublen = String.length s1 in
5102 let i = find s s1 in
5105 let s' = String.sub s 0 i in
5106 let s'' = String.sub s (i+sublen) (len-i-sublen) in
5107 s' ^ s2 ^ replace_str s'' s1 s2
5110 let rec string_split sep str =
5111 let len = String.length str in
5112 let seplen = String.length sep in
5113 let i = find str sep in
5114 if i = -1 then [str]
5116 let s' = String.sub str 0 i in
5117 let s'' = String.sub str (i+seplen) (len-i-seplen) in
5118 s' :: string_split sep s''
5121 let files_equal n1 n2 =
5122 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
5123 match Sys.command cmd with
5126 | i -> failwithf "%s: failed with error code %d" cmd i
5128 let rec filter_map f = function
5132 | Some y -> y :: filter_map f xs
5133 | None -> filter_map f xs
5135 let rec find_map f = function
5136 | [] -> raise Not_found
5140 | None -> find_map f xs
5143 let rec loop i = function
5145 | x :: xs -> f i x; loop (i+1) xs
5150 let rec loop i = function
5152 | x :: xs -> let r = f i x in r :: loop (i+1) xs
5156 let count_chars c str =
5157 let count = ref 0 in
5158 for i = 0 to String.length str - 1 do
5159 if c = String.unsafe_get str i then incr count
5165 for i = 0 to String.length str - 1 do
5166 let c = String.unsafe_get str i in
5171 let map_chars f str =
5172 List.map f (explode str)
5174 let name_of_argt = function
5175 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
5176 | StringList n | DeviceList n | Bool n | Int n | Int64 n
5177 | FileIn n | FileOut n | BufferIn n -> n
5179 let java_name_of_struct typ =
5180 try List.assoc typ java_structs
5183 "java_name_of_struct: no java_structs entry corresponding to %s" typ
5185 let cols_of_struct typ =
5186 try List.assoc typ structs
5188 failwithf "cols_of_struct: unknown struct %s" typ
5190 let seq_of_test = function
5191 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
5192 | TestOutputListOfDevices (s, _)
5193 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
5194 | TestOutputTrue s | TestOutputFalse s
5195 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
5196 | TestOutputStruct (s, _)
5197 | TestLastFail s -> s
5199 (* Handling for function flags. *)
5200 let protocol_limit_warning =
5201 "Because of the message protocol, there is a transfer limit
5202 of somewhere between 2MB and 4MB. See L<guestfs(3)/PROTOCOL LIMITS>."
5204 let danger_will_robinson =
5205 "B<This command is dangerous. Without careful use you
5206 can easily destroy all your data>."
5208 let deprecation_notice flags =
5211 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
5213 sprintf "This function is deprecated.
5214 In new code, use the C<%s> call instead.
5216 Deprecated functions will not be removed from the API, but the
5217 fact that they are deprecated indicates that there are problems
5218 with correct use of these functions." alt in
5223 (* Create list of optional groups. *)
5225 let h = Hashtbl.create 13 in
5227 fun (name, _, _, flags, _, _, _) ->
5231 let names = try Hashtbl.find h group with Not_found -> [] in
5232 Hashtbl.replace h group (name :: names)
5236 let groups = Hashtbl.fold (fun k _ ks -> k :: ks) h [] in
5239 fun group -> group, List.sort compare (Hashtbl.find h group)
5241 List.sort (fun x y -> compare (fst x) (fst y)) groups
5243 (* Check function names etc. for consistency. *)
5244 let check_functions () =
5245 let contains_uppercase str =
5246 let len = String.length str in
5248 if i >= len then false
5251 if c >= 'A' && c <= 'Z' then true
5258 (* Check function names. *)
5260 fun (name, _, _, _, _, _, _) ->
5261 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
5262 failwithf "function name %s does not need 'guestfs' prefix" name;
5264 failwithf "function name is empty";
5265 if name.[0] < 'a' || name.[0] > 'z' then
5266 failwithf "function name %s must start with lowercase a-z" name;
5267 if String.contains name '-' then
5268 failwithf "function name %s should not contain '-', use '_' instead."
5272 (* Check function parameter/return names. *)
5274 fun (name, style, _, _, _, _, _) ->
5275 let check_arg_ret_name n =
5276 if contains_uppercase n then
5277 failwithf "%s param/ret %s should not contain uppercase chars"
5279 if String.contains n '-' || String.contains n '_' then
5280 failwithf "%s param/ret %s should not contain '-' or '_'"
5283 failwithf "%s has a param/ret called 'value', which causes conflicts in the OCaml bindings, use something like 'val' or a more descriptive name" name;
5284 if n = "int" || n = "char" || n = "short" || n = "long" then
5285 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
5286 if n = "i" || n = "n" then
5287 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
5288 if n = "argv" || n = "args" then
5289 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
5291 (* List Haskell, OCaml and C keywords here.
5292 * http://www.haskell.org/haskellwiki/Keywords
5293 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
5294 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
5295 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
5296 * |perl -pe 's/(.+)/"$1";/'|fmt -70
5297 * Omitting _-containing words, since they're handled above.
5298 * Omitting the OCaml reserved word, "val", is ok,
5299 * and saves us from renaming several parameters.
5302 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
5303 "char"; "class"; "const"; "constraint"; "continue"; "data";
5304 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
5305 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
5306 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
5307 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
5308 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
5310 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
5311 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
5312 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
5313 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
5314 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
5315 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
5316 "volatile"; "when"; "where"; "while";
5318 if List.mem n reserved then
5319 failwithf "%s has param/ret using reserved word %s" name n;
5322 (match fst style with
5324 | RInt n | RInt64 n | RBool n
5325 | RConstString n | RConstOptString n | RString n
5326 | RStringList n | RStruct (n, _) | RStructList (n, _)
5327 | RHashtable n | RBufferOut n ->
5328 check_arg_ret_name n
5330 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
5333 (* Check short descriptions. *)
5335 fun (name, _, _, _, _, shortdesc, _) ->
5336 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
5337 failwithf "short description of %s should begin with lowercase." name;
5338 let c = shortdesc.[String.length shortdesc-1] in
5339 if c = '\n' || c = '.' then
5340 failwithf "short description of %s should not end with . or \\n." name
5343 (* Check long descriptions. *)
5345 fun (name, _, _, _, _, _, longdesc) ->
5346 if longdesc.[String.length longdesc-1] = '\n' then
5347 failwithf "long description of %s should not end with \\n." name
5350 (* Check proc_nrs. *)
5352 fun (name, _, proc_nr, _, _, _, _) ->
5353 if proc_nr <= 0 then
5354 failwithf "daemon function %s should have proc_nr > 0" name
5358 fun (name, _, proc_nr, _, _, _, _) ->
5359 if proc_nr <> -1 then
5360 failwithf "non-daemon function %s should have proc_nr -1" name
5361 ) non_daemon_functions;
5364 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
5367 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
5368 let rec loop = function
5371 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
5373 | (name1,nr1) :: (name2,nr2) :: _ ->
5374 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
5382 (* Ignore functions that have no tests. We generate a
5383 * warning when the user does 'make check' instead.
5385 | name, _, _, _, [], _, _ -> ()
5386 | name, _, _, _, tests, _, _ ->
5390 match seq_of_test test with
5392 failwithf "%s has a test containing an empty sequence" name
5393 | cmds -> List.map List.hd cmds
5395 let funcs = List.flatten funcs in
5397 let tested = List.mem name funcs in
5400 failwithf "function %s has tests but does not test itself" name
5403 (* 'pr' prints to the current output file. *)
5404 let chan = ref Pervasives.stdout
5409 let i = count_chars '\n' str in
5410 lines := !lines + i;
5411 output_string !chan str
5414 let copyright_years =
5415 let this_year = 1900 + (localtime (time ())).tm_year in
5416 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
5418 (* Generate a header block in a number of standard styles. *)
5419 type comment_style =
5420 CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
5421 type license = GPLv2plus | LGPLv2plus
5423 let generate_header ?(extra_inputs = []) comment license =
5424 let inputs = "src/generator.ml" :: extra_inputs in
5425 let c = match comment with
5426 | CStyle -> pr "/* "; " *"
5427 | CPlusPlusStyle -> pr "// "; "//"
5428 | HashStyle -> pr "# "; "#"
5429 | OCamlStyle -> pr "(* "; " *"
5430 | HaskellStyle -> pr "{- "; " " in
5431 pr "libguestfs generated file\n";
5432 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
5433 List.iter (pr "%s %s\n" c) inputs;
5434 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
5436 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
5440 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
5441 pr "%s it under the terms of the GNU General Public License as published by\n" c;
5442 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
5443 pr "%s (at your option) any later version.\n" c;
5445 pr "%s This program is distributed in the hope that it will be useful,\n" c;
5446 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5447 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
5448 pr "%s GNU General Public License for more details.\n" c;
5450 pr "%s You should have received a copy of the GNU General Public License along\n" c;
5451 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
5452 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
5455 pr "%s This library is free software; you can redistribute it and/or\n" c;
5456 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
5457 pr "%s License as published by the Free Software Foundation; either\n" c;
5458 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
5460 pr "%s This library is distributed in the hope that it will be useful,\n" c;
5461 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5462 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
5463 pr "%s Lesser General Public License for more details.\n" c;
5465 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
5466 pr "%s License along with this library; if not, write to the Free Software\n" c;
5467 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
5470 | CStyle -> pr " */\n"
5473 | OCamlStyle -> pr " *)\n"
5474 | HaskellStyle -> pr "-}\n"
5478 (* Start of main code generation functions below this line. *)
5480 (* Generate the pod documentation for the C API. *)
5481 let rec generate_actions_pod () =
5483 fun (shortname, style, _, flags, _, _, longdesc) ->
5484 if not (List.mem NotInDocs flags) then (
5485 let name = "guestfs_" ^ shortname in
5486 pr "=head2 %s\n\n" name;
5488 generate_prototype ~extern:false ~handle:"g" name style;
5490 pr "%s\n\n" longdesc;
5491 (match fst style with
5493 pr "This function returns 0 on success or -1 on error.\n\n"
5495 pr "On error this function returns -1.\n\n"
5497 pr "On error this function returns -1.\n\n"
5499 pr "This function returns a C truth value on success or -1 on error.\n\n"
5501 pr "This function returns a string, or NULL on error.
5502 The string is owned by the guest handle and must I<not> be freed.\n\n"
5503 | RConstOptString _ ->
5504 pr "This function returns a string which may be NULL.
5505 There is way to return an error from this function.
5506 The string is owned by the guest handle and must I<not> be freed.\n\n"
5508 pr "This function returns a string, or NULL on error.
5509 I<The caller must free the returned string after use>.\n\n"
5511 pr "This function returns a NULL-terminated array of strings
5512 (like L<environ(3)>), or NULL if there was an error.
5513 I<The caller must free the strings and the array after use>.\n\n"
5514 | RStruct (_, typ) ->
5515 pr "This function returns a C<struct guestfs_%s *>,
5516 or NULL if there was an error.
5517 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
5518 | RStructList (_, typ) ->
5519 pr "This function returns a C<struct guestfs_%s_list *>
5520 (see E<lt>guestfs-structs.hE<gt>),
5521 or NULL if there was an error.
5522 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
5524 pr "This function returns a NULL-terminated array of
5525 strings, or NULL if there was an error.
5526 The array of strings will always have length C<2n+1>, where
5527 C<n> keys and values alternate, followed by the trailing NULL entry.
5528 I<The caller must free the strings and the array after use>.\n\n"
5530 pr "This function returns a buffer, or NULL on error.
5531 The size of the returned buffer is written to C<*size_r>.
5532 I<The caller must free the returned buffer after use>.\n\n"
5534 if List.mem ProtocolLimitWarning flags then
5535 pr "%s\n\n" protocol_limit_warning;
5536 if List.mem DangerWillRobinson flags then
5537 pr "%s\n\n" danger_will_robinson;
5538 match deprecation_notice flags with
5540 | Some txt -> pr "%s\n\n" txt
5542 ) all_functions_sorted
5544 and generate_structs_pod () =
5545 (* Structs documentation. *)
5548 pr "=head2 guestfs_%s\n" typ;
5550 pr " struct guestfs_%s {\n" typ;
5553 | name, FChar -> pr " char %s;\n" name
5554 | name, FUInt32 -> pr " uint32_t %s;\n" name
5555 | name, FInt32 -> pr " int32_t %s;\n" name
5556 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5557 | name, FInt64 -> pr " int64_t %s;\n" name
5558 | name, FString -> pr " char *%s;\n" name
5560 pr " /* The next two fields describe a byte array. */\n";
5561 pr " uint32_t %s_len;\n" name;
5562 pr " char *%s;\n" name
5564 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
5565 pr " char %s[32];\n" name
5566 | name, FOptPercent ->
5567 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
5568 pr " float %s;\n" name
5572 pr " struct guestfs_%s_list {\n" typ;
5573 pr " uint32_t len; /* Number of elements in list. */\n";
5574 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
5577 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
5578 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
5583 and generate_availability_pod () =
5584 (* Availability documentation. *)
5588 fun (group, functions) ->
5589 pr "=item B<%s>\n" group;
5591 pr "The following functions:\n";
5592 List.iter (pr "L</guestfs_%s>\n") functions;
5598 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
5599 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
5601 * We have to use an underscore instead of a dash because otherwise
5602 * rpcgen generates incorrect code.
5604 * This header is NOT exported to clients, but see also generate_structs_h.
5606 and generate_xdr () =
5607 generate_header CStyle LGPLv2plus;
5609 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
5610 pr "typedef string str<>;\n";
5613 (* Internal structures. *)
5617 pr "struct guestfs_int_%s {\n" typ;
5619 | name, FChar -> pr " char %s;\n" name
5620 | name, FString -> pr " string %s<>;\n" name
5621 | name, FBuffer -> pr " opaque %s<>;\n" name
5622 | name, FUUID -> pr " opaque %s[32];\n" name
5623 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
5624 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
5625 | name, FOptPercent -> pr " float %s;\n" name
5629 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
5634 fun (shortname, style, _, _, _, _, _) ->
5635 let name = "guestfs_" ^ shortname in
5637 (match snd style with
5640 pr "struct %s_args {\n" name;
5643 | Pathname n | Device n | Dev_or_Path n | String n ->
5644 pr " string %s<>;\n" n
5645 | OptString n -> pr " str *%s;\n" n
5646 | StringList n | DeviceList n -> pr " str %s<>;\n" n
5647 | Bool n -> pr " bool %s;\n" n
5648 | Int n -> pr " int %s;\n" n
5649 | Int64 n -> pr " hyper %s;\n" n
5651 pr " opaque %s<>;\n" n
5652 | FileIn _ | FileOut _ -> ()
5656 (match fst style with
5659 pr "struct %s_ret {\n" name;
5663 pr "struct %s_ret {\n" name;
5664 pr " hyper %s;\n" n;
5667 pr "struct %s_ret {\n" name;
5670 | RConstString _ | RConstOptString _ ->
5671 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5673 pr "struct %s_ret {\n" name;
5674 pr " string %s<>;\n" n;
5677 pr "struct %s_ret {\n" name;
5678 pr " str %s<>;\n" n;
5680 | RStruct (n, typ) ->
5681 pr "struct %s_ret {\n" name;
5682 pr " guestfs_int_%s %s;\n" typ n;
5684 | RStructList (n, typ) ->
5685 pr "struct %s_ret {\n" name;
5686 pr " guestfs_int_%s_list %s;\n" typ n;
5689 pr "struct %s_ret {\n" name;
5690 pr " str %s<>;\n" n;
5693 pr "struct %s_ret {\n" name;
5694 pr " opaque %s<>;\n" n;
5699 (* Table of procedure numbers. *)
5700 pr "enum guestfs_procedure {\n";
5702 fun (shortname, _, proc_nr, _, _, _, _) ->
5703 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5705 pr " GUESTFS_PROC_NR_PROCS\n";
5709 (* Having to choose a maximum message size is annoying for several
5710 * reasons (it limits what we can do in the API), but it (a) makes
5711 * the protocol a lot simpler, and (b) provides a bound on the size
5712 * of the daemon which operates in limited memory space.
5714 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5717 (* Message header, etc. *)
5719 /* The communication protocol is now documented in the guestfs(3)
5723 const GUESTFS_PROGRAM = 0x2000F5F5;
5724 const GUESTFS_PROTOCOL_VERSION = 1;
5726 /* These constants must be larger than any possible message length. */
5727 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5728 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5730 enum guestfs_message_direction {
5731 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5732 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5735 enum guestfs_message_status {
5736 GUESTFS_STATUS_OK = 0,
5737 GUESTFS_STATUS_ERROR = 1
5740 const GUESTFS_ERROR_LEN = 256;
5742 struct guestfs_message_error {
5743 string error_message<GUESTFS_ERROR_LEN>;
5746 struct guestfs_message_header {
5747 unsigned prog; /* GUESTFS_PROGRAM */
5748 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5749 guestfs_procedure proc; /* GUESTFS_PROC_x */
5750 guestfs_message_direction direction;
5751 unsigned serial; /* message serial number */
5752 guestfs_message_status status;
5755 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5757 struct guestfs_chunk {
5758 int cancel; /* if non-zero, transfer is cancelled */
5759 /* data size is 0 bytes if the transfer has finished successfully */
5760 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5764 (* Generate the guestfs-structs.h file. *)
5765 and generate_structs_h () =
5766 generate_header CStyle LGPLv2plus;
5768 (* This is a public exported header file containing various
5769 * structures. The structures are carefully written to have
5770 * exactly the same in-memory format as the XDR structures that
5771 * we use on the wire to the daemon. The reason for creating
5772 * copies of these structures here is just so we don't have to
5773 * export the whole of guestfs_protocol.h (which includes much
5774 * unrelated and XDR-dependent stuff that we don't want to be
5775 * public, or required by clients).
5777 * To reiterate, we will pass these structures to and from the
5778 * client with a simple assignment or memcpy, so the format
5779 * must be identical to what rpcgen / the RFC defines.
5782 (* Public structures. *)
5785 pr "struct guestfs_%s {\n" typ;
5788 | name, FChar -> pr " char %s;\n" name
5789 | name, FString -> pr " char *%s;\n" name
5791 pr " uint32_t %s_len;\n" name;
5792 pr " char *%s;\n" name
5793 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5794 | name, FUInt32 -> pr " uint32_t %s;\n" name
5795 | name, FInt32 -> pr " int32_t %s;\n" name
5796 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5797 | name, FInt64 -> pr " int64_t %s;\n" name
5798 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5802 pr "struct guestfs_%s_list {\n" typ;
5803 pr " uint32_t len;\n";
5804 pr " struct guestfs_%s *val;\n" typ;
5807 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5808 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5812 (* Generate the guestfs-actions.h file. *)
5813 and generate_actions_h () =
5814 generate_header CStyle LGPLv2plus;
5816 fun (shortname, style, _, _, _, _, _) ->
5817 let name = "guestfs_" ^ shortname in
5818 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5822 (* Generate the guestfs-internal-actions.h file. *)
5823 and generate_internal_actions_h () =
5824 generate_header CStyle LGPLv2plus;
5826 fun (shortname, style, _, _, _, _, _) ->
5827 let name = "guestfs__" ^ shortname in
5828 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5830 ) non_daemon_functions
5832 (* Generate the client-side dispatch stubs. *)
5833 and generate_client_actions () =
5834 generate_header CStyle LGPLv2plus;
5841 #include <inttypes.h>
5843 #include \"guestfs.h\"
5844 #include \"guestfs-internal.h\"
5845 #include \"guestfs-internal-actions.h\"
5846 #include \"guestfs_protocol.h\"
5848 #define error guestfs_error
5849 //#define perrorf guestfs_perrorf
5850 #define safe_malloc guestfs_safe_malloc
5851 #define safe_realloc guestfs_safe_realloc
5852 //#define safe_strdup guestfs_safe_strdup
5853 #define safe_memdup guestfs_safe_memdup
5855 /* Check the return message from a call for validity. */
5857 check_reply_header (guestfs_h *g,
5858 const struct guestfs_message_header *hdr,
5859 unsigned int proc_nr, unsigned int serial)
5861 if (hdr->prog != GUESTFS_PROGRAM) {
5862 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5865 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5866 error (g, \"wrong protocol version (%%d/%%d)\",
5867 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5870 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5871 error (g, \"unexpected message direction (%%d/%%d)\",
5872 hdr->direction, GUESTFS_DIRECTION_REPLY);
5875 if (hdr->proc != proc_nr) {
5876 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5879 if (hdr->serial != serial) {
5880 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5887 /* Check we are in the right state to run a high-level action. */
5889 check_state (guestfs_h *g, const char *caller)
5891 if (!guestfs__is_ready (g)) {
5892 if (guestfs__is_config (g) || guestfs__is_launching (g))
5893 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5896 error (g, \"%%s called from the wrong state, %%d != READY\",
5897 caller, guestfs__get_state (g));
5905 let error_code_of = function
5906 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5907 | RConstString _ | RConstOptString _
5908 | RString _ | RStringList _
5909 | RStruct _ | RStructList _
5910 | RHashtable _ | RBufferOut _ -> "NULL"
5913 (* Generate code to check String-like parameters are not passed in
5914 * as NULL (returning an error if they are).
5916 let check_null_strings shortname style =
5917 let pr_newline = ref false in
5920 (* parameters which should not be NULL *)
5930 pr " if (%s == NULL) {\n" n;
5931 pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
5932 pr " \"%s\", \"%s\");\n" shortname n;
5933 pr " return %s;\n" (error_code_of (fst style));
5940 (* not applicable *)
5946 if !pr_newline then pr "\n";
5949 (* Generate code to generate guestfish call traces. *)
5950 let trace_call shortname style =
5951 pr " if (guestfs__get_trace (g)) {\n";
5954 List.exists (function
5955 | StringList _ | DeviceList _ -> true
5956 | _ -> false) (snd style) in
5962 pr " printf (\"%s\");\n" shortname;
5965 | String n (* strings *)
5972 (* guestfish doesn't support string escaping, so neither do we *)
5973 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
5974 | OptString n -> (* string option *)
5975 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
5976 pr " else printf (\" null\");\n"
5978 | DeviceList n -> (* string list *)
5979 pr " putchar (' ');\n";
5980 pr " putchar ('\"');\n";
5981 pr " for (i = 0; %s[i]; ++i) {\n" n;
5982 pr " if (i > 0) putchar (' ');\n";
5983 pr " fputs (%s[i], stdout);\n" n;
5985 pr " putchar ('\"');\n";
5986 | Bool n -> (* boolean *)
5987 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
5988 | Int n -> (* int *)
5989 pr " printf (\" %%d\", %s);\n" n
5991 pr " printf (\" %%\" PRIi64, %s);\n" n
5993 pr " putchar ('\\n');\n";
5998 (* For non-daemon functions, generate a wrapper around each function. *)
6000 fun (shortname, style, _, _, _, _, _) ->
6001 let name = "guestfs_" ^ shortname in
6003 generate_prototype ~extern:false ~semicolon:false ~newline:true
6004 ~handle:"g" name style;
6006 check_null_strings shortname style;
6007 trace_call shortname style;
6008 pr " return guestfs__%s " shortname;
6009 generate_c_call_args ~handle:"g" style;
6013 ) non_daemon_functions;
6015 (* Client-side stubs for each function. *)
6017 fun (shortname, style, _, _, _, _, _) ->
6018 let name = "guestfs_" ^ shortname in
6019 let error_code = error_code_of (fst style) in
6021 (* Generate the action stub. *)
6022 generate_prototype ~extern:false ~semicolon:false ~newline:true
6023 ~handle:"g" name style;
6027 (match snd style with
6029 | _ -> pr " struct %s_args args;\n" name
6032 pr " guestfs_message_header hdr;\n";
6033 pr " guestfs_message_error err;\n";
6035 match fst style with
6037 | RConstString _ | RConstOptString _ ->
6038 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6040 | RBool _ | RString _ | RStringList _
6041 | RStruct _ | RStructList _
6042 | RHashtable _ | RBufferOut _ ->
6043 pr " struct %s_ret ret;\n" name;
6046 pr " int serial;\n";
6049 check_null_strings shortname style;
6050 trace_call shortname style;
6051 pr " if (check_state (g, \"%s\") == -1) return %s;\n"
6052 shortname error_code;
6053 pr " guestfs___set_busy (g);\n";
6056 (* Send the main header and arguments. *)
6057 (match snd style with
6059 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
6060 (String.uppercase shortname)
6064 | Pathname n | Device n | Dev_or_Path n | String n ->
6065 pr " args.%s = (char *) %s;\n" n n
6067 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
6068 | StringList n | DeviceList n ->
6069 pr " args.%s.%s_val = (char **) %s;\n" n n n;
6070 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
6072 pr " args.%s = %s;\n" n n
6074 pr " args.%s = %s;\n" n n
6076 pr " args.%s = %s;\n" n n
6077 | FileIn _ | FileOut _ -> ()
6079 pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
6080 pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
6081 pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
6083 pr " guestfs___end_busy (g);\n";
6084 pr " return %s;\n" error_code;
6086 pr " args.%s.%s_val = (char *) %s;\n" n n n;
6087 pr " args.%s.%s_len = %s_size;\n" n n n
6089 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
6090 (String.uppercase shortname);
6091 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
6094 pr " if (serial == -1) {\n";
6095 pr " guestfs___end_busy (g);\n";
6096 pr " return %s;\n" error_code;
6100 (* Send any additional files (FileIn) requested. *)
6101 let need_read_reply_label = ref false in
6105 pr " r = guestfs___send_file (g, %s);\n" n;
6106 pr " if (r == -1) {\n";
6107 pr " guestfs___end_busy (g);\n";
6108 pr " return %s;\n" error_code;
6110 pr " if (r == -2) /* daemon cancelled */\n";
6111 pr " goto read_reply;\n";
6112 need_read_reply_label := true;
6117 (* Wait for the reply from the remote end. *)
6118 if !need_read_reply_label then pr " read_reply:\n";
6119 pr " memset (&hdr, 0, sizeof hdr);\n";
6120 pr " memset (&err, 0, sizeof err);\n";
6121 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
6123 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
6127 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
6130 pr " if (r == -1) {\n";
6131 pr " guestfs___end_busy (g);\n";
6132 pr " return %s;\n" error_code;
6136 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
6137 (String.uppercase shortname);
6138 pr " guestfs___end_busy (g);\n";
6139 pr " return %s;\n" error_code;
6143 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
6144 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
6145 pr " free (err.error_message);\n";
6146 pr " guestfs___end_busy (g);\n";
6147 pr " return %s;\n" error_code;
6151 (* Expecting to receive further files (FileOut)? *)
6155 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
6156 pr " guestfs___end_busy (g);\n";
6157 pr " return %s;\n" error_code;
6163 pr " guestfs___end_busy (g);\n";
6165 (match fst style with
6166 | RErr -> pr " return 0;\n"
6167 | RInt n | RInt64 n | RBool n ->
6168 pr " return ret.%s;\n" n
6169 | RConstString _ | RConstOptString _ ->
6170 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6172 pr " return ret.%s; /* caller will free */\n" n
6173 | RStringList n | RHashtable n ->
6174 pr " /* caller will free this, but we need to add a NULL entry */\n";
6175 pr " ret.%s.%s_val =\n" n n;
6176 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
6177 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
6179 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
6180 pr " return ret.%s.%s_val;\n" n n
6182 pr " /* caller will free this */\n";
6183 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6184 | RStructList (n, _) ->
6185 pr " /* caller will free this */\n";
6186 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6188 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
6189 pr " * _val might be NULL here. To make the API saner for\n";
6190 pr " * callers, we turn this case into a unique pointer (using\n";
6191 pr " * malloc(1)).\n";
6193 pr " if (ret.%s.%s_len > 0) {\n" n n;
6194 pr " *size_r = ret.%s.%s_len;\n" n n;
6195 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
6197 pr " free (ret.%s.%s_val);\n" n n;
6198 pr " char *p = safe_malloc (g, 1);\n";
6199 pr " *size_r = ret.%s.%s_len;\n" n n;
6207 (* Functions to free structures. *)
6208 pr "/* Structure-freeing functions. These rely on the fact that the\n";
6209 pr " * structure format is identical to the XDR format. See note in\n";
6210 pr " * generator.ml.\n";
6217 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
6219 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
6225 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
6227 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
6234 (* Generate daemon/actions.h. *)
6235 and generate_daemon_actions_h () =
6236 generate_header CStyle GPLv2plus;
6238 pr "#include \"../src/guestfs_protocol.h\"\n";
6242 fun (name, style, _, _, _, _, _) ->
6244 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
6248 (* Generate the linker script which controls the visibility of
6249 * symbols in the public ABI and ensures no other symbols get
6250 * exported accidentally.
6252 and generate_linker_script () =
6253 generate_header HashStyle GPLv2plus;
6258 "guestfs_get_error_handler";
6259 "guestfs_get_out_of_memory_handler";
6260 "guestfs_last_error";
6261 "guestfs_set_error_handler";
6262 "guestfs_set_launch_done_callback";
6263 "guestfs_set_log_message_callback";
6264 "guestfs_set_out_of_memory_handler";
6265 "guestfs_set_subprocess_quit_callback";
6267 (* Unofficial parts of the API: the bindings code use these
6268 * functions, so it is useful to export them.
6270 "guestfs_safe_calloc";
6271 "guestfs_safe_malloc";
6274 List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
6278 List.map (fun (typ, _) ->
6279 ["guestfs_free_" ^ typ; "guestfs_free_" ^ typ ^ "_list"])
6282 let globals = List.sort compare (globals @ functions @ structs) in
6286 List.iter (pr " %s;\n") globals;
6293 (* Generate the server-side stubs. *)
6294 and generate_daemon_actions () =
6295 generate_header CStyle GPLv2plus;
6297 pr "#include <config.h>\n";
6299 pr "#include <stdio.h>\n";
6300 pr "#include <stdlib.h>\n";
6301 pr "#include <string.h>\n";
6302 pr "#include <inttypes.h>\n";
6303 pr "#include <rpc/types.h>\n";
6304 pr "#include <rpc/xdr.h>\n";
6306 pr "#include \"daemon.h\"\n";
6307 pr "#include \"c-ctype.h\"\n";
6308 pr "#include \"../src/guestfs_protocol.h\"\n";
6309 pr "#include \"actions.h\"\n";
6313 fun (name, style, _, _, _, _, _) ->
6314 (* Generate server-side stubs. *)
6315 pr "static void %s_stub (XDR *xdr_in)\n" name;
6318 match fst style with
6319 | RErr | RInt _ -> pr " int r;\n"; "-1"
6320 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6321 | RBool _ -> pr " int r;\n"; "-1"
6322 | RConstString _ | RConstOptString _ ->
6323 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6324 | RString _ -> pr " char *r;\n"; "NULL"
6325 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
6326 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
6327 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
6329 pr " size_t size = 1;\n";
6333 (match snd style with
6336 pr " struct guestfs_%s_args args;\n" name;
6339 | Device n | Dev_or_Path n
6342 | OptString n -> pr " char *%s;\n" n
6343 | StringList n | DeviceList n -> pr " char **%s;\n" n
6344 | Bool n -> pr " int %s;\n" n
6345 | Int n -> pr " int %s;\n" n
6346 | Int64 n -> pr " int64_t %s;\n" n
6347 | FileIn _ | FileOut _ -> ()
6349 pr " const char *%s;\n" n;
6350 pr " size_t %s_size;\n" n
6356 List.exists (function FileIn _ -> true | _ -> false) (snd style) in
6358 (match snd style with
6361 pr " memset (&args, 0, sizeof args);\n";
6363 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
6365 pr " if (cancel_receive () != -2)\n";
6366 pr " reply_with_error (\"daemon failed to decode procedure arguments\");\n";
6370 pr " char *%s = args.%s;\n" n n
6372 let pr_list_handling_code n =
6373 pr " %s = realloc (args.%s.%s_val,\n" n n n;
6374 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
6375 pr " if (%s == NULL) {\n" n;
6377 pr " if (cancel_receive () != -2)\n";
6378 pr " reply_with_perror (\"realloc\");\n";
6381 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
6382 pr " args.%s.%s_val = %s;\n" n n n;
6388 pr " ABS_PATH (%s, %s, goto done);\n"
6389 n (if is_filein then "cancel_receive ()" else "0");
6392 pr " RESOLVE_DEVICE (%s, %s, goto done);\n"
6393 n (if is_filein then "cancel_receive ()" else "0");
6396 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
6397 n (if is_filein then "cancel_receive ()" else "0");
6398 | String n -> pr_args n
6399 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
6401 pr_list_handling_code n;
6403 pr_list_handling_code n;
6404 pr " /* Ensure that each is a device,\n";
6405 pr " * and perform device name translation. */\n";
6406 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
6407 pr " RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
6408 (if is_filein then "cancel_receive ()" else "0");
6410 | Bool n -> pr " %s = args.%s;\n" n n
6411 | Int n -> pr " %s = args.%s;\n" n n
6412 | Int64 n -> pr " %s = args.%s;\n" n n
6413 | FileIn _ | FileOut _ -> ()
6415 pr " %s = args.%s.%s_val;\n" n n n;
6416 pr " %s_size = args.%s.%s_len;\n" n n n
6421 (* this is used at least for do_equal *)
6422 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
6423 (* Emit NEED_ROOT just once, even when there are two or
6424 more Pathname args *)
6425 pr " NEED_ROOT (%s, goto done);\n"
6426 (if is_filein then "cancel_receive ()" else "0");
6429 (* Don't want to call the impl with any FileIn or FileOut
6430 * parameters, since these go "outside" the RPC protocol.
6433 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
6435 pr " r = do_%s " name;
6436 generate_c_call_args (fst style, args');
6439 (match fst style with
6440 | RErr | RInt _ | RInt64 _ | RBool _
6441 | RConstString _ | RConstOptString _
6442 | RString _ | RStringList _ | RHashtable _
6443 | RStruct (_, _) | RStructList (_, _) ->
6444 pr " if (r == %s)\n" error_code;
6445 pr " /* do_%s has already called reply_with_error */\n" name;
6449 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
6450 pr " * an ordinary zero-length buffer), so be careful ...\n";
6452 pr " if (size == 1 && r == %s)\n" error_code;
6453 pr " /* do_%s has already called reply_with_error */\n" name;
6458 (* If there are any FileOut parameters, then the impl must
6459 * send its own reply.
6462 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
6464 pr " /* do_%s has already sent a reply */\n" name
6466 match fst style with
6467 | RErr -> pr " reply (NULL, NULL);\n"
6468 | RInt n | RInt64 n | RBool n ->
6469 pr " struct guestfs_%s_ret ret;\n" name;
6470 pr " ret.%s = r;\n" n;
6471 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6473 | RConstString _ | RConstOptString _ ->
6474 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6476 pr " struct guestfs_%s_ret ret;\n" name;
6477 pr " ret.%s = r;\n" n;
6478 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6481 | RStringList n | RHashtable n ->
6482 pr " struct guestfs_%s_ret ret;\n" name;
6483 pr " ret.%s.%s_len = count_strings (r);\n" n n;
6484 pr " ret.%s.%s_val = r;\n" n n;
6485 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6487 pr " free_strings (r);\n"
6489 pr " struct guestfs_%s_ret ret;\n" name;
6490 pr " ret.%s = *r;\n" n;
6491 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6493 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6495 | RStructList (n, _) ->
6496 pr " struct guestfs_%s_ret ret;\n" name;
6497 pr " ret.%s = *r;\n" n;
6498 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6500 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6503 pr " struct guestfs_%s_ret ret;\n" name;
6504 pr " ret.%s.%s_val = r;\n" n n;
6505 pr " ret.%s.%s_len = size;\n" n n;
6506 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6511 (* Free the args. *)
6513 (match snd style with
6516 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
6523 (* Dispatch function. *)
6524 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
6526 pr " switch (proc_nr) {\n";
6529 fun (name, style, _, _, _, _, _) ->
6530 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
6531 pr " %s_stub (xdr_in);\n" name;
6536 pr " reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d, set LIBGUESTFS_PATH to point to the matching libguestfs appliance directory\", proc_nr);\n";
6541 (* LVM columns and tokenization functions. *)
6542 (* XXX This generates crap code. We should rethink how we
6548 pr "static const char *lvm_%s_cols = \"%s\";\n"
6549 typ (String.concat "," (List.map fst cols));
6552 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
6554 pr " char *tok, *p, *next;\n";
6558 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
6561 pr " if (!str) {\n";
6562 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
6565 pr " if (!*str || c_isspace (*str)) {\n";
6566 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
6571 fun (name, coltype) ->
6572 pr " if (!tok) {\n";
6573 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
6576 pr " p = strchrnul (tok, ',');\n";
6577 pr " if (*p) next = p+1; else next = NULL;\n";
6578 pr " *p = '\\0';\n";
6581 pr " r->%s = strdup (tok);\n" name;
6582 pr " if (r->%s == NULL) {\n" name;
6583 pr " perror (\"strdup\");\n";
6587 pr " for (i = j = 0; i < 32; ++j) {\n";
6588 pr " if (tok[j] == '\\0') {\n";
6589 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
6591 pr " } else if (tok[j] != '-')\n";
6592 pr " r->%s[i++] = tok[j];\n" name;
6595 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
6596 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6600 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
6601 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6605 pr " if (tok[0] == '\\0')\n";
6606 pr " r->%s = -1;\n" name;
6607 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
6608 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6611 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
6612 assert false (* can never be an LVM column *)
6614 pr " tok = next;\n";
6617 pr " if (tok != NULL) {\n";
6618 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
6625 pr "guestfs_int_lvm_%s_list *\n" typ;
6626 pr "parse_command_line_%ss (void)\n" typ;
6628 pr " char *out, *err;\n";
6629 pr " char *p, *pend;\n";
6631 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
6632 pr " void *newp;\n";
6634 pr " ret = malloc (sizeof *ret);\n";
6635 pr " if (!ret) {\n";
6636 pr " reply_with_perror (\"malloc\");\n";
6637 pr " return NULL;\n";
6640 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
6641 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
6643 pr " r = command (&out, &err,\n";
6644 pr " \"lvm\", \"%ss\",\n" typ;
6645 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
6646 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
6647 pr " if (r == -1) {\n";
6648 pr " reply_with_error (\"%%s\", err);\n";
6649 pr " free (out);\n";
6650 pr " free (err);\n";
6651 pr " free (ret);\n";
6652 pr " return NULL;\n";
6655 pr " free (err);\n";
6657 pr " /* Tokenize each line of the output. */\n";
6660 pr " while (p) {\n";
6661 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
6662 pr " if (pend) {\n";
6663 pr " *pend = '\\0';\n";
6667 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
6670 pr " if (!*p) { /* Empty line? Skip it. */\n";
6675 pr " /* Allocate some space to store this next entry. */\n";
6676 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
6677 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
6678 pr " if (newp == NULL) {\n";
6679 pr " reply_with_perror (\"realloc\");\n";
6680 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6681 pr " free (ret);\n";
6682 pr " free (out);\n";
6683 pr " return NULL;\n";
6685 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
6687 pr " /* Tokenize the next entry. */\n";
6688 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
6689 pr " if (r == -1) {\n";
6690 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
6691 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6692 pr " free (ret);\n";
6693 pr " free (out);\n";
6694 pr " return NULL;\n";
6701 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
6703 pr " free (out);\n";
6704 pr " return ret;\n";
6707 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
6709 (* Generate a list of function names, for debugging in the daemon.. *)
6710 and generate_daemon_names () =
6711 generate_header CStyle GPLv2plus;
6713 pr "#include <config.h>\n";
6715 pr "#include \"daemon.h\"\n";
6718 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
6719 pr "const char *function_names[] = {\n";
6721 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
6725 (* Generate the optional groups for the daemon to implement
6726 * guestfs_available.
6728 and generate_daemon_optgroups_c () =
6729 generate_header CStyle GPLv2plus;
6731 pr "#include <config.h>\n";
6733 pr "#include \"daemon.h\"\n";
6734 pr "#include \"optgroups.h\"\n";
6737 pr "struct optgroup optgroups[] = {\n";
6740 pr " { \"%s\", optgroup_%s_available },\n" group group
6742 pr " { NULL, NULL }\n";
6745 and generate_daemon_optgroups_h () =
6746 generate_header CStyle GPLv2plus;
6750 pr "extern int optgroup_%s_available (void);\n" group
6753 (* Generate the tests. *)
6754 and generate_tests () =
6755 generate_header CStyle GPLv2plus;
6762 #include <sys/types.h>
6765 #include \"guestfs.h\"
6766 #include \"guestfs-internal.h\"
6768 static guestfs_h *g;
6769 static int suppress_error = 0;
6771 static void print_error (guestfs_h *g, void *data, const char *msg)
6773 if (!suppress_error)
6774 fprintf (stderr, \"%%s\\n\", msg);
6777 /* FIXME: nearly identical code appears in fish.c */
6778 static void print_strings (char *const *argv)
6782 for (argc = 0; argv[argc] != NULL; ++argc)
6783 printf (\"\\t%%s\\n\", argv[argc]);
6787 static void print_table (char const *const *argv)
6791 for (i = 0; argv[i] != NULL; i += 2)
6792 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
6798 (* Generate a list of commands which are not tested anywhere. *)
6799 pr "static void no_test_warnings (void)\n";
6802 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
6804 fun (_, _, _, _, tests, _, _) ->
6805 let tests = filter_map (
6807 | (_, (Always|If _|Unless _), test) -> Some test
6808 | (_, Disabled, _) -> None
6810 let seq = List.concat (List.map seq_of_test tests) in
6811 let cmds_tested = List.map List.hd seq in
6812 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6816 fun (name, _, _, _, _, _, _) ->
6817 if not (Hashtbl.mem hash name) then
6818 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6824 (* Generate the actual tests. Note that we generate the tests
6825 * in reverse order, deliberately, so that (in general) the
6826 * newest tests run first. This makes it quicker and easier to
6831 fun (name, _, _, flags, tests, _, _) ->
6832 mapi (generate_one_test name flags) tests
6833 ) (List.rev all_functions) in
6834 let test_names = List.concat test_names in
6835 let nr_tests = List.length test_names in
6838 int main (int argc, char *argv[])
6841 unsigned long int n_failed = 0;
6842 const char *filename;
6844 int nr_tests, test_num = 0;
6846 setbuf (stdout, NULL);
6848 no_test_warnings ();
6850 g = guestfs_create ();
6852 printf (\"guestfs_create FAILED\\n\");
6853 exit (EXIT_FAILURE);
6856 guestfs_set_error_handler (g, print_error, NULL);
6858 guestfs_set_path (g, \"../appliance\");
6860 filename = \"test1.img\";
6861 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6864 exit (EXIT_FAILURE);
6866 if (lseek (fd, %d, SEEK_SET) == -1) {
6870 exit (EXIT_FAILURE);
6872 if (write (fd, &c, 1) == -1) {
6876 exit (EXIT_FAILURE);
6878 if (close (fd) == -1) {
6881 exit (EXIT_FAILURE);
6883 if (guestfs_add_drive (g, filename) == -1) {
6884 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6885 exit (EXIT_FAILURE);
6888 filename = \"test2.img\";
6889 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6892 exit (EXIT_FAILURE);
6894 if (lseek (fd, %d, SEEK_SET) == -1) {
6898 exit (EXIT_FAILURE);
6900 if (write (fd, &c, 1) == -1) {
6904 exit (EXIT_FAILURE);
6906 if (close (fd) == -1) {
6909 exit (EXIT_FAILURE);
6911 if (guestfs_add_drive (g, filename) == -1) {
6912 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6913 exit (EXIT_FAILURE);
6916 filename = \"test3.img\";
6917 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6920 exit (EXIT_FAILURE);
6922 if (lseek (fd, %d, SEEK_SET) == -1) {
6926 exit (EXIT_FAILURE);
6928 if (write (fd, &c, 1) == -1) {
6932 exit (EXIT_FAILURE);
6934 if (close (fd) == -1) {
6937 exit (EXIT_FAILURE);
6939 if (guestfs_add_drive (g, filename) == -1) {
6940 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6941 exit (EXIT_FAILURE);
6944 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
6945 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
6946 exit (EXIT_FAILURE);
6949 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
6952 if (guestfs_launch (g) == -1) {
6953 printf (\"guestfs_launch FAILED\\n\");
6954 exit (EXIT_FAILURE);
6957 /* Cancel previous alarm. */
6962 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
6966 pr " test_num++;\n";
6967 pr " if (guestfs_get_verbose (g))\n";
6968 pr " printf (\"-------------------------------------------------------------------------------\\n\");\n";
6969 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
6970 pr " if (%s () == -1) {\n" test_name;
6971 pr " printf (\"%s FAILED\\n\");\n" test_name;
6972 pr " n_failed++;\n";
6977 pr " guestfs_close (g);\n";
6978 pr " unlink (\"test1.img\");\n";
6979 pr " unlink (\"test2.img\");\n";
6980 pr " unlink (\"test3.img\");\n";
6983 pr " if (n_failed > 0) {\n";
6984 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
6985 pr " exit (EXIT_FAILURE);\n";
6989 pr " exit (EXIT_SUCCESS);\n";
6992 and generate_one_test name flags i (init, prereq, test) =
6993 let test_name = sprintf "test_%s_%d" name i in
6996 static int %s_skip (void)
7000 str = getenv (\"TEST_ONLY\");
7002 return strstr (str, \"%s\") == NULL;
7003 str = getenv (\"SKIP_%s\");
7004 if (str && STREQ (str, \"1\")) return 1;
7005 str = getenv (\"SKIP_TEST_%s\");
7006 if (str && STREQ (str, \"1\")) return 1;
7010 " test_name name (String.uppercase test_name) (String.uppercase name);
7013 | Disabled | Always -> ()
7014 | If code | Unless code ->
7015 pr "static int %s_prereq (void)\n" test_name;
7023 static int %s (void)
7026 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
7030 " test_name test_name test_name;
7032 (* Optional functions should only be tested if the relevant
7033 * support is available in the daemon.
7039 pr " const char *groups[] = { \"%s\", NULL };\n" group;
7041 pr " suppress_error = 1;\n";
7042 pr " r = guestfs_available (g, (char **) groups);\n";
7043 pr " suppress_error = 0;\n";
7044 pr " if (r == -1) {\n";
7045 pr " printf (\" %%s skipped (reason: group %%s not available in daemon)\\n\", \"%s\", groups[0]);\n" test_name;
7054 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
7056 pr " if (! %s_prereq ()) {\n" test_name;
7057 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7061 generate_one_test_body name i test_name init test;
7063 pr " if (%s_prereq ()) {\n" test_name;
7064 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7068 generate_one_test_body name i test_name init test;
7070 generate_one_test_body name i test_name init test
7078 and generate_one_test_body name i test_name init test =
7080 | InitNone (* XXX at some point, InitNone and InitEmpty became
7081 * folded together as the same thing. Really we should
7082 * make InitNone do nothing at all, but the tests may
7083 * need to be checked to make sure this is OK.
7086 pr " /* InitNone|InitEmpty for %s */\n" test_name;
7087 List.iter (generate_test_command_call test_name)
7088 [["blockdev_setrw"; "/dev/sda"];
7092 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
7093 List.iter (generate_test_command_call test_name)
7094 [["blockdev_setrw"; "/dev/sda"];
7097 ["part_disk"; "/dev/sda"; "mbr"]]
7099 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
7100 List.iter (generate_test_command_call test_name)
7101 [["blockdev_setrw"; "/dev/sda"];
7104 ["part_disk"; "/dev/sda"; "mbr"];
7105 ["mkfs"; "ext2"; "/dev/sda1"];
7106 ["mount_options"; ""; "/dev/sda1"; "/"]]
7107 | InitBasicFSonLVM ->
7108 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
7110 List.iter (generate_test_command_call test_name)
7111 [["blockdev_setrw"; "/dev/sda"];
7114 ["part_disk"; "/dev/sda"; "mbr"];
7115 ["pvcreate"; "/dev/sda1"];
7116 ["vgcreate"; "VG"; "/dev/sda1"];
7117 ["lvcreate"; "LV"; "VG"; "8"];
7118 ["mkfs"; "ext2"; "/dev/VG/LV"];
7119 ["mount_options"; ""; "/dev/VG/LV"; "/"]]
7121 pr " /* InitISOFS for %s */\n" test_name;
7122 List.iter (generate_test_command_call test_name)
7123 [["blockdev_setrw"; "/dev/sda"];
7126 ["mount_ro"; "/dev/sdd"; "/"]]
7129 let get_seq_last = function
7131 failwithf "%s: you cannot use [] (empty list) when expecting a command"
7134 let seq = List.rev seq in
7135 List.rev (List.tl seq), List.hd seq
7140 pr " /* TestRun for %s (%d) */\n" name i;
7141 List.iter (generate_test_command_call test_name) seq
7142 | TestOutput (seq, expected) ->
7143 pr " /* TestOutput for %s (%d) */\n" name i;
7144 pr " const char *expected = \"%s\";\n" (c_quote expected);
7145 let seq, last = get_seq_last seq in
7147 pr " if (STRNEQ (r, expected)) {\n";
7148 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7152 List.iter (generate_test_command_call test_name) seq;
7153 generate_test_command_call ~test test_name last
7154 | TestOutputList (seq, expected) ->
7155 pr " /* TestOutputList for %s (%d) */\n" name i;
7156 let seq, last = get_seq_last seq in
7160 pr " if (!r[%d]) {\n" i;
7161 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7162 pr " print_strings (r);\n";
7166 pr " const char *expected = \"%s\";\n" (c_quote str);
7167 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7168 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7173 pr " if (r[%d] != NULL) {\n" (List.length expected);
7174 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7176 pr " print_strings (r);\n";
7180 List.iter (generate_test_command_call test_name) seq;
7181 generate_test_command_call ~test test_name last
7182 | TestOutputListOfDevices (seq, expected) ->
7183 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
7184 let seq, last = get_seq_last seq in
7188 pr " if (!r[%d]) {\n" i;
7189 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7190 pr " print_strings (r);\n";
7194 pr " const char *expected = \"%s\";\n" (c_quote str);
7195 pr " r[%d][5] = 's';\n" i;
7196 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7197 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7202 pr " if (r[%d] != NULL) {\n" (List.length expected);
7203 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7205 pr " print_strings (r);\n";
7209 List.iter (generate_test_command_call test_name) seq;
7210 generate_test_command_call ~test test_name last
7211 | TestOutputInt (seq, expected) ->
7212 pr " /* TestOutputInt for %s (%d) */\n" name i;
7213 let seq, last = get_seq_last seq in
7215 pr " if (r != %d) {\n" expected;
7216 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
7222 List.iter (generate_test_command_call test_name) seq;
7223 generate_test_command_call ~test test_name last
7224 | TestOutputIntOp (seq, op, expected) ->
7225 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
7226 let seq, last = get_seq_last seq in
7228 pr " if (! (r %s %d)) {\n" op expected;
7229 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
7230 test_name op expected;
7235 List.iter (generate_test_command_call test_name) seq;
7236 generate_test_command_call ~test test_name last
7237 | TestOutputTrue seq ->
7238 pr " /* TestOutputTrue for %s (%d) */\n" name i;
7239 let seq, last = get_seq_last seq in
7242 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
7247 List.iter (generate_test_command_call test_name) seq;
7248 generate_test_command_call ~test test_name last
7249 | TestOutputFalse seq ->
7250 pr " /* TestOutputFalse for %s (%d) */\n" name i;
7251 let seq, last = get_seq_last seq in
7254 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
7259 List.iter (generate_test_command_call test_name) seq;
7260 generate_test_command_call ~test test_name last
7261 | TestOutputLength (seq, expected) ->
7262 pr " /* TestOutputLength for %s (%d) */\n" name i;
7263 let seq, last = get_seq_last seq in
7266 pr " for (j = 0; j < %d; ++j)\n" expected;
7267 pr " if (r[j] == NULL) {\n";
7268 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
7270 pr " print_strings (r);\n";
7273 pr " if (r[j] != NULL) {\n";
7274 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
7276 pr " print_strings (r);\n";
7280 List.iter (generate_test_command_call test_name) seq;
7281 generate_test_command_call ~test test_name last
7282 | TestOutputBuffer (seq, expected) ->
7283 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
7284 pr " const char *expected = \"%s\";\n" (c_quote expected);
7285 let seq, last = get_seq_last seq in
7286 let len = String.length expected in
7288 pr " if (size != %d) {\n" len;
7289 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
7292 pr " if (STRNEQLEN (r, expected, size)) {\n";
7293 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7297 List.iter (generate_test_command_call test_name) seq;
7298 generate_test_command_call ~test test_name last
7299 | TestOutputStruct (seq, checks) ->
7300 pr " /* TestOutputStruct for %s (%d) */\n" name i;
7301 let seq, last = get_seq_last seq in
7305 | CompareWithInt (field, expected) ->
7306 pr " if (r->%s != %d) {\n" field expected;
7307 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
7308 test_name field expected;
7309 pr " (int) r->%s);\n" field;
7312 | CompareWithIntOp (field, op, expected) ->
7313 pr " if (!(r->%s %s %d)) {\n" field op expected;
7314 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
7315 test_name field op expected;
7316 pr " (int) r->%s);\n" field;
7319 | CompareWithString (field, expected) ->
7320 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
7321 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
7322 test_name field expected;
7323 pr " r->%s);\n" field;
7326 | CompareFieldsIntEq (field1, field2) ->
7327 pr " if (r->%s != r->%s) {\n" field1 field2;
7328 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
7329 test_name field1 field2;
7330 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
7333 | CompareFieldsStrEq (field1, field2) ->
7334 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
7335 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
7336 test_name field1 field2;
7337 pr " r->%s, r->%s);\n" field1 field2;
7342 List.iter (generate_test_command_call test_name) seq;
7343 generate_test_command_call ~test test_name last
7344 | TestLastFail seq ->
7345 pr " /* TestLastFail for %s (%d) */\n" name i;
7346 let seq, last = get_seq_last seq in
7347 List.iter (generate_test_command_call test_name) seq;
7348 generate_test_command_call test_name ~expect_error:true last
7350 (* Generate the code to run a command, leaving the result in 'r'.
7351 * If you expect to get an error then you should set expect_error:true.
7353 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
7355 | [] -> assert false
7357 (* Look up the command to find out what args/ret it has. *)
7360 let _, style, _, _, _, _, _ =
7361 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
7364 failwithf "%s: in test, command %s was not found" test_name name in
7366 if List.length (snd style) <> List.length args then
7367 failwithf "%s: in test, wrong number of args given to %s"
7374 | OptString n, "NULL" -> ()
7377 | Dev_or_Path n, arg
7379 | OptString n, arg ->
7380 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7381 | BufferIn n, arg ->
7382 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7383 pr " size_t %s_size = %d;\n" n (String.length arg)
7387 | FileIn _, _ | FileOut _, _ -> ()
7388 | StringList n, "" | DeviceList n, "" ->
7389 pr " const char *const %s[1] = { NULL };\n" n
7390 | StringList n, arg | DeviceList n, arg ->
7391 let strs = string_split " " arg in
7394 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
7396 pr " const char *const %s[] = {\n" n;
7398 fun i _ -> pr " %s_%d,\n" n i
7402 ) (List.combine (snd style) args);
7405 match fst style with
7406 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
7407 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7408 | RConstString _ | RConstOptString _ ->
7409 pr " const char *r;\n"; "NULL"
7410 | RString _ -> pr " char *r;\n"; "NULL"
7411 | RStringList _ | RHashtable _ ->
7415 | RStruct (_, typ) ->
7416 pr " struct guestfs_%s *r;\n" typ; "NULL"
7417 | RStructList (_, typ) ->
7418 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7421 pr " size_t size;\n";
7424 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
7425 pr " r = guestfs_%s (g" name;
7427 (* Generate the parameters. *)
7430 | OptString _, "NULL" -> pr ", NULL"
7432 | Device n, _ | Dev_or_Path n, _
7437 pr ", %s, %s_size" n n
7438 | FileIn _, arg | FileOut _, arg ->
7439 pr ", \"%s\"" (c_quote arg)
7440 | StringList n, _ | DeviceList n, _ ->
7441 pr ", (char **) %s" n
7444 try int_of_string arg
7445 with Failure "int_of_string" ->
7446 failwithf "%s: expecting an int, but got '%s'" test_name arg in
7450 try Int64.of_string arg
7451 with Failure "int_of_string" ->
7452 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
7455 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
7456 ) (List.combine (snd style) args);
7458 (match fst style with
7459 | RBufferOut _ -> pr ", &size"
7465 if not expect_error then
7466 pr " if (r == %s)\n" error_code
7468 pr " if (r != %s)\n" error_code;
7471 (* Insert the test code. *)
7477 (match fst style with
7478 | RErr | RInt _ | RInt64 _ | RBool _
7479 | RConstString _ | RConstOptString _ -> ()
7480 | RString _ | RBufferOut _ -> pr " free (r);\n"
7481 | RStringList _ | RHashtable _ ->
7482 pr " for (i = 0; r[i] != NULL; ++i)\n";
7483 pr " free (r[i]);\n";
7485 | RStruct (_, typ) ->
7486 pr " guestfs_free_%s (r);\n" typ
7487 | RStructList (_, typ) ->
7488 pr " guestfs_free_%s_list (r);\n" typ
7494 let str = replace_str str "\r" "\\r" in
7495 let str = replace_str str "\n" "\\n" in
7496 let str = replace_str str "\t" "\\t" in
7497 let str = replace_str str "\000" "\\0" in
7500 (* Generate a lot of different functions for guestfish. *)
7501 and generate_fish_cmds () =
7502 generate_header CStyle GPLv2plus;
7506 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7508 let all_functions_sorted =
7510 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7511 ) all_functions_sorted in
7513 pr "#include <config.h>\n";
7515 pr "#include <stdio.h>\n";
7516 pr "#include <stdlib.h>\n";
7517 pr "#include <string.h>\n";
7518 pr "#include <inttypes.h>\n";
7520 pr "#include <guestfs.h>\n";
7521 pr "#include \"c-ctype.h\"\n";
7522 pr "#include \"full-write.h\"\n";
7523 pr "#include \"xstrtol.h\"\n";
7524 pr "#include \"fish.h\"\n";
7526 pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
7527 pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
7530 (* list_commands function, which implements guestfish -h *)
7531 pr "void list_commands (void)\n";
7533 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
7534 pr " list_builtin_commands ();\n";
7536 fun (name, _, _, flags, _, shortdesc, _) ->
7537 let name = replace_char name '_' '-' in
7538 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
7540 ) all_functions_sorted;
7541 pr " printf (\" %%s\\n\",";
7542 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
7546 (* display_command function, which implements guestfish -h cmd *)
7547 pr "void display_command (const char *cmd)\n";
7550 fun (name, style, _, flags, _, shortdesc, longdesc) ->
7551 let name2 = replace_char name '_' '-' in
7553 try find_map (function FishAlias n -> Some n | _ -> None) flags
7554 with Not_found -> name in
7555 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
7557 match snd style with
7561 name2 (String.concat " " (List.map name_of_argt args)) in
7564 if List.mem ProtocolLimitWarning flags then
7565 ("\n\n" ^ protocol_limit_warning)
7568 (* For DangerWillRobinson commands, we should probably have
7569 * guestfish prompt before allowing you to use them (especially
7570 * in interactive mode). XXX
7574 if List.mem DangerWillRobinson flags then
7575 ("\n\n" ^ danger_will_robinson)
7580 match deprecation_notice flags with
7582 | Some txt -> "\n\n" ^ txt in
7584 let describe_alias =
7585 if name <> alias then
7586 sprintf "\n\nYou can use '%s' as an alias for this command." alias
7590 pr "STRCASEEQ (cmd, \"%s\")" name;
7591 if name <> name2 then
7592 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7593 if name <> alias then
7594 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7596 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
7598 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
7599 "=head1 DESCRIPTION\n\n" ^
7600 longdesc ^ warnings ^ describe_alias);
7603 pr " display_builtin_command (cmd);\n";
7607 let emit_print_list_function typ =
7608 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
7611 pr " unsigned int i;\n";
7613 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7614 pr " printf (\"[%%d] = {\\n\", i);\n";
7615 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
7616 pr " printf (\"}\\n\");\n";
7622 (* print_* functions *)
7626 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
7628 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
7631 pr " unsigned int i;\n";
7637 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
7639 pr " printf (\"%%s%s: \", indent);\n" name;
7640 pr " for (i = 0; i < 32; ++i)\n";
7641 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7642 pr " printf (\"\\n\");\n"
7644 pr " printf (\"%%s%s: \", indent);\n" name;
7645 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
7646 pr " if (c_isprint (%s->%s[i]))\n" typ name;
7647 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7649 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
7650 pr " printf (\"\\n\");\n"
7651 | name, (FUInt64|FBytes) ->
7652 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
7655 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
7658 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
7661 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
7664 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
7666 | name, FOptPercent ->
7667 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
7668 typ name name typ name;
7669 pr " else printf (\"%%s%s: \\n\", indent);\n" name
7675 (* Emit a print_TYPE_list function definition only if that function is used. *)
7678 | typ, (RStructListOnly | RStructAndList) ->
7679 (* generate the function for typ *)
7680 emit_print_list_function typ
7681 | typ, _ -> () (* empty *)
7682 ) (rstructs_used_by all_functions);
7684 (* Emit a print_TYPE function definition only if that function is used. *)
7687 | typ, (RStructOnly | RStructAndList) ->
7688 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
7690 pr " print_%s_indent (%s, \"\");\n" typ typ;
7693 | typ, _ -> () (* empty *)
7694 ) (rstructs_used_by all_functions);
7696 (* run_<action> actions *)
7698 fun (name, style, _, flags, _, _, _) ->
7699 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
7701 (match fst style with
7704 | RBool _ -> pr " int r;\n"
7705 | RInt64 _ -> pr " int64_t r;\n"
7706 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
7707 | RString _ -> pr " char *r;\n"
7708 | RStringList _ | RHashtable _ -> pr " char **r;\n"
7709 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
7710 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
7713 pr " size_t size;\n";
7719 | OptString n -> pr " const char *%s;\n" n
7723 | FileOut n -> pr " char *%s;\n" n
7725 pr " const char *%s;\n" n;
7726 pr " size_t %s_size;\n" n
7727 | StringList n | DeviceList n -> pr " char **%s;\n" n
7728 | Bool n -> pr " int %s;\n" n
7729 | Int n -> pr " int %s;\n" n
7730 | Int64 n -> pr " int64_t %s;\n" n
7733 (* Check and convert parameters. *)
7734 let argc_expected = List.length (snd style) in
7735 pr " if (argc != %d) {\n" argc_expected;
7736 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
7738 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
7742 let parse_integer fn fntyp rtyp range name i =
7744 pr " strtol_error xerr;\n";
7745 pr " %s r;\n" fntyp;
7747 pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
7748 pr " if (xerr != LONGINT_OK) {\n";
7749 pr " fprintf (stderr,\n";
7750 pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
7751 pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
7756 | Some (min, max, comment) ->
7757 pr " /* %s */\n" comment;
7758 pr " if (r < %s || r > %s) {\n" min max;
7759 pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
7763 pr " /* The check above should ensure this assignment does not overflow. */\n";
7765 pr " %s = r;\n" name;
7774 pr " %s = argv[%d];\n" name i
7776 | Dev_or_Path name ->
7777 pr " %s = resolve_win_path (argv[%d]);\n" name i;
7778 pr " if (%s == NULL) return -1;\n" name
7780 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
7783 pr " %s = argv[%d];\n" name i;
7784 pr " %s_size = strlen (argv[%d]);\n" name i
7786 pr " %s = file_in (argv[%d]);\n" name i;
7787 pr " if (%s == NULL) return -1;\n" name
7789 pr " %s = file_out (argv[%d]);\n" name i;
7790 pr " if (%s == NULL) return -1;\n" name
7791 | StringList name | DeviceList name ->
7792 pr " %s = parse_string_list (argv[%d]);\n" name i;
7793 pr " if (%s == NULL) return -1;\n" name;
7795 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
7798 let min = "(-(2LL<<30))"
7799 and max = "((2LL<<30)-1)"
7801 "The Int type in the generator is a signed 31 bit int." in
7802 Some (min, max, comment) in
7803 parse_integer "xstrtoll" "long long" "int" range name i
7805 parse_integer "xstrtoll" "long long" "int64_t" None name i
7808 (* Call C API function. *)
7809 pr " r = guestfs_%s " name;
7810 generate_c_call_args ~handle:"g" style;
7815 | Device name | String name
7816 | OptString name | Bool name
7817 | Int name | Int64 name
7818 | BufferIn name -> ()
7819 | Pathname name | Dev_or_Path name | FileOut name ->
7820 pr " free (%s);\n" name
7822 pr " free_file_in (%s);\n" name
7823 | StringList name | DeviceList name ->
7824 pr " free_strings (%s);\n" name
7827 (* Any output flags? *)
7829 let flags = filter_map (
7830 function FishOutput flag -> Some flag | _ -> None
7836 failwithf "%s: more than one FishOutput flag is not allowed" name in
7838 (* Check return value for errors and display command results. *)
7839 (match fst style with
7840 | RErr -> pr " return r;\n"
7842 pr " if (r == -1) return -1;\n";
7843 (match fish_output with
7845 pr " printf (\"%%d\\n\", r);\n";
7846 | Some FishOutputOctal ->
7847 pr " printf (\"%%s%%o\\n\", r != 0 ? \"0\" : \"\", r);\n";
7848 | Some FishOutputHexadecimal ->
7849 pr " printf (\"%%s%%x\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7852 pr " if (r == -1) return -1;\n";
7853 (match fish_output with
7855 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
7856 | Some FishOutputOctal ->
7857 pr " printf (\"%%s%%\" PRIo64 \"\\n\", r != 0 ? \"0\" : \"\", r);\n";
7858 | Some FishOutputHexadecimal ->
7859 pr " printf (\"%%s%%\" PRIx64 \"\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7862 pr " if (r == -1) return -1;\n";
7863 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
7866 pr " if (r == NULL) return -1;\n";
7867 pr " printf (\"%%s\\n\", r);\n";
7869 | RConstOptString _ ->
7870 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
7873 pr " if (r == NULL) return -1;\n";
7874 pr " printf (\"%%s\\n\", r);\n";
7878 pr " if (r == NULL) return -1;\n";
7879 pr " print_strings (r);\n";
7880 pr " free_strings (r);\n";
7882 | RStruct (_, typ) ->
7883 pr " if (r == NULL) return -1;\n";
7884 pr " print_%s (r);\n" typ;
7885 pr " guestfs_free_%s (r);\n" typ;
7887 | RStructList (_, typ) ->
7888 pr " if (r == NULL) return -1;\n";
7889 pr " print_%s_list (r);\n" typ;
7890 pr " guestfs_free_%s_list (r);\n" typ;
7893 pr " if (r == NULL) return -1;\n";
7894 pr " print_table (r);\n";
7895 pr " free_strings (r);\n";
7898 pr " if (r == NULL) return -1;\n";
7899 pr " if (full_write (1, r, size) != size) {\n";
7900 pr " perror (\"write\");\n";
7911 (* run_action function *)
7912 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
7915 fun (name, _, _, flags, _, _, _) ->
7916 let name2 = replace_char name '_' '-' in
7918 try find_map (function FishAlias n -> Some n | _ -> None) flags
7919 with Not_found -> name in
7921 pr "STRCASEEQ (cmd, \"%s\")" name;
7922 if name <> name2 then
7923 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7924 if name <> alias then
7925 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7927 pr " return run_%s (cmd, argc, argv);\n" name;
7931 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
7932 pr " if (command_num == 1)\n";
7933 pr " extended_help_message ();\n";
7940 (* Readline completion for guestfish. *)
7941 and generate_fish_completion () =
7942 generate_header CStyle GPLv2plus;
7946 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7956 #ifdef HAVE_LIBREADLINE
7957 #include <readline/readline.h>
7962 #ifdef HAVE_LIBREADLINE
7964 static const char *const commands[] = {
7965 BUILTIN_COMMANDS_FOR_COMPLETION,
7968 (* Get the commands, including the aliases. They don't need to be
7969 * sorted - the generator() function just does a dumb linear search.
7973 fun (name, _, _, flags, _, _, _) ->
7974 let name2 = replace_char name '_' '-' in
7976 try find_map (function FishAlias n -> Some n | _ -> None) flags
7977 with Not_found -> name in
7979 if name <> alias then [name2; alias] else [name2]
7981 let commands = List.flatten commands in
7983 List.iter (pr " \"%s\",\n") commands;
7989 generator (const char *text, int state)
7991 static int index, len;
7996 len = strlen (text);
7999 rl_attempted_completion_over = 1;
8001 while ((name = commands[index]) != NULL) {
8003 if (STRCASEEQLEN (name, text, len))
8004 return strdup (name);
8010 #endif /* HAVE_LIBREADLINE */
8012 #ifdef HAVE_RL_COMPLETION_MATCHES
8013 #define RL_COMPLETION_MATCHES rl_completion_matches
8015 #ifdef HAVE_COMPLETION_MATCHES
8016 #define RL_COMPLETION_MATCHES completion_matches
8018 #endif /* else just fail if we don't have either symbol */
8021 do_completion (const char *text, int start, int end)
8023 char **matches = NULL;
8025 #ifdef HAVE_LIBREADLINE
8026 rl_completion_append_character = ' ';
8029 matches = RL_COMPLETION_MATCHES (text, generator);
8030 else if (complete_dest_paths)
8031 matches = RL_COMPLETION_MATCHES (text, complete_dest_paths_generator);
8038 (* Generate the POD documentation for guestfish. *)
8039 and generate_fish_actions_pod () =
8040 let all_functions_sorted =
8042 fun (_, _, _, flags, _, _, _) ->
8043 not (List.mem NotInFish flags || List.mem NotInDocs flags)
8044 ) all_functions_sorted in
8046 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
8049 fun (name, style, _, flags, _, _, longdesc) ->
8051 Str.global_substitute rex (
8054 try Str.matched_group 1 s
8056 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
8057 "C<" ^ replace_char sub '_' '-' ^ ">"
8059 let name = replace_char name '_' '-' in
8061 try find_map (function FishAlias n -> Some n | _ -> None) flags
8062 with Not_found -> name in
8064 pr "=head2 %s" name;
8065 if name <> alias then
8072 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
8073 | OptString n -> pr " %s" n
8074 | StringList n | DeviceList n -> pr " '%s ...'" n
8075 | Bool _ -> pr " true|false"
8076 | Int n -> pr " %s" n
8077 | Int64 n -> pr " %s" n
8078 | FileIn n | FileOut n -> pr " (%s|-)" n
8079 | BufferIn n -> pr " %s" n
8083 pr "%s\n\n" longdesc;
8085 if List.exists (function FileIn _ | FileOut _ -> true
8086 | _ -> false) (snd style) then
8087 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
8089 if List.mem ProtocolLimitWarning flags then
8090 pr "%s\n\n" protocol_limit_warning;
8092 if List.mem DangerWillRobinson flags then
8093 pr "%s\n\n" danger_will_robinson;
8095 match deprecation_notice flags with
8097 | Some txt -> pr "%s\n\n" txt
8098 ) all_functions_sorted
8100 (* Generate a C function prototype. *)
8101 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
8102 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
8104 ?handle name style =
8105 if extern then pr "extern ";
8106 if static then pr "static ";
8107 (match fst style with
8109 | RInt _ -> pr "int "
8110 | RInt64 _ -> pr "int64_t "
8111 | RBool _ -> pr "int "
8112 | RConstString _ | RConstOptString _ -> pr "const char *"
8113 | RString _ | RBufferOut _ -> pr "char *"
8114 | RStringList _ | RHashtable _ -> pr "char **"
8115 | RStruct (_, typ) ->
8116 if not in_daemon then pr "struct guestfs_%s *" typ
8117 else pr "guestfs_int_%s *" typ
8118 | RStructList (_, typ) ->
8119 if not in_daemon then pr "struct guestfs_%s_list *" typ
8120 else pr "guestfs_int_%s_list *" typ
8122 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
8123 pr "%s%s (" prefix name;
8124 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
8127 let comma = ref false in
8130 | Some handle -> pr "guestfs_h *%s" handle; comma := true
8134 if single_line then pr ", " else pr ",\n\t\t"
8141 | Device n | Dev_or_Path n
8145 pr "const char *%s" n
8146 | StringList n | DeviceList n ->
8148 pr "char *const *%s" n
8149 | Bool n -> next (); pr "int %s" n
8150 | Int n -> next (); pr "int %s" n
8151 | Int64 n -> next (); pr "int64_t %s" n
8154 if not in_daemon then (next (); pr "const char *%s" n)
8157 pr "const char *%s" n;
8159 pr "size_t %s_size" n
8161 if is_RBufferOut then (next (); pr "size_t *size_r");
8164 if semicolon then pr ";";
8165 if newline then pr "\n"
8167 (* Generate C call arguments, eg "(handle, foo, bar)" *)
8168 and generate_c_call_args ?handle ?(decl = false) style =
8170 let comma = ref false in
8172 if !comma then pr ", ";
8177 | Some handle -> pr "%s" handle; comma := true
8183 pr "%s, %s_size" n n
8186 pr "%s" (name_of_argt arg)
8188 (* For RBufferOut calls, add implicit &size parameter. *)
8190 match fst style with
8198 (* Generate the OCaml bindings interface. *)
8199 and generate_ocaml_mli () =
8200 generate_header OCamlStyle LGPLv2plus;
8203 (** For API documentation you should refer to the C API
8204 in the guestfs(3) manual page. The OCaml API uses almost
8205 exactly the same calls. *)
8208 (** A [guestfs_h] handle. *)
8210 exception Error of string
8211 (** This exception is raised when there is an error. *)
8213 exception Handle_closed of string
8214 (** This exception is raised if you use a {!Guestfs.t} handle
8215 after calling {!close} on it. The string is the name of
8218 val create : unit -> t
8219 (** Create a {!Guestfs.t} handle. *)
8221 val close : t -> unit
8222 (** Close the {!Guestfs.t} handle and free up all resources used
8225 Handles are closed by the garbage collector when they become
8226 unreferenced, but callers can call this in order to provide
8227 predictable cleanup. *)
8230 generate_ocaml_structure_decls ();
8234 fun (name, style, _, _, _, shortdesc, _) ->
8235 generate_ocaml_prototype name style;
8236 pr "(** %s *)\n" shortdesc;
8238 ) all_functions_sorted
8240 (* Generate the OCaml bindings implementation. *)
8241 and generate_ocaml_ml () =
8242 generate_header OCamlStyle LGPLv2plus;
8247 exception Error of string
8248 exception Handle_closed of string
8250 external create : unit -> t = \"ocaml_guestfs_create\"
8251 external close : t -> unit = \"ocaml_guestfs_close\"
8253 (* Give the exceptions names, so they can be raised from the C code. *)
8255 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
8256 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
8260 generate_ocaml_structure_decls ();
8264 fun (name, style, _, _, _, shortdesc, _) ->
8265 generate_ocaml_prototype ~is_external:true name style;
8266 ) all_functions_sorted
8268 (* Generate the OCaml bindings C implementation. *)
8269 and generate_ocaml_c () =
8270 generate_header CStyle LGPLv2plus;
8277 #include <caml/config.h>
8278 #include <caml/alloc.h>
8279 #include <caml/callback.h>
8280 #include <caml/fail.h>
8281 #include <caml/memory.h>
8282 #include <caml/mlvalues.h>
8283 #include <caml/signals.h>
8285 #include <guestfs.h>
8287 #include \"guestfs_c.h\"
8289 /* Copy a hashtable of string pairs into an assoc-list. We return
8290 * the list in reverse order, but hashtables aren't supposed to be
8293 static CAMLprim value
8294 copy_table (char * const * argv)
8297 CAMLlocal5 (rv, pairv, kv, vv, cons);
8301 for (i = 0; argv[i] != NULL; i += 2) {
8302 kv = caml_copy_string (argv[i]);
8303 vv = caml_copy_string (argv[i+1]);
8304 pairv = caml_alloc (2, 0);
8305 Store_field (pairv, 0, kv);
8306 Store_field (pairv, 1, vv);
8307 cons = caml_alloc (2, 0);
8308 Store_field (cons, 1, rv);
8310 Store_field (cons, 0, pairv);
8318 (* Struct copy functions. *)
8320 let emit_ocaml_copy_list_function typ =
8321 pr "static CAMLprim value\n";
8322 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
8324 pr " CAMLparam0 ();\n";
8325 pr " CAMLlocal2 (rv, v);\n";
8326 pr " unsigned int i;\n";
8328 pr " if (%ss->len == 0)\n" typ;
8329 pr " CAMLreturn (Atom (0));\n";
8331 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
8332 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
8333 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
8334 pr " caml_modify (&Field (rv, i), v);\n";
8336 pr " CAMLreturn (rv);\n";
8344 let has_optpercent_col =
8345 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
8347 pr "static CAMLprim value\n";
8348 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
8350 pr " CAMLparam0 ();\n";
8351 if has_optpercent_col then
8352 pr " CAMLlocal3 (rv, v, v2);\n"
8354 pr " CAMLlocal2 (rv, v);\n";
8356 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
8361 pr " v = caml_copy_string (%s->%s);\n" typ name
8363 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
8364 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
8367 pr " v = caml_alloc_string (32);\n";
8368 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
8369 | name, (FBytes|FInt64|FUInt64) ->
8370 pr " v = caml_copy_int64 (%s->%s);\n" typ name
8371 | name, (FInt32|FUInt32) ->
8372 pr " v = caml_copy_int32 (%s->%s);\n" typ name
8373 | name, FOptPercent ->
8374 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
8375 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
8376 pr " v = caml_alloc (1, 0);\n";
8377 pr " Store_field (v, 0, v2);\n";
8378 pr " } else /* None */\n";
8379 pr " v = Val_int (0);\n";
8381 pr " v = Val_int (%s->%s);\n" typ name
8383 pr " Store_field (rv, %d, v);\n" i
8385 pr " CAMLreturn (rv);\n";
8390 (* Emit a copy_TYPE_list function definition only if that function is used. *)
8393 | typ, (RStructListOnly | RStructAndList) ->
8394 (* generate the function for typ *)
8395 emit_ocaml_copy_list_function typ
8396 | typ, _ -> () (* empty *)
8397 ) (rstructs_used_by all_functions);
8401 fun (name, style, _, _, _, _, _) ->
8402 pr "/* Automatically generated wrapper for function\n";
8404 generate_ocaml_prototype name style;
8409 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
8411 let needs_extra_vs =
8412 match fst style with RConstOptString _ -> true | _ -> false in
8414 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8415 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
8416 List.iter (pr ", value %s") (List.tl params); pr ");\n";
8419 pr "CAMLprim value\n";
8420 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
8421 List.iter (pr ", value %s") (List.tl params);
8426 | [p1; p2; p3; p4; p5] ->
8427 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
8428 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
8429 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
8430 pr " CAMLxparam%d (%s);\n"
8431 (List.length rest) (String.concat ", " rest)
8433 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
8435 if not needs_extra_vs then
8436 pr " CAMLlocal1 (rv);\n"
8438 pr " CAMLlocal3 (rv, v, v2);\n";
8441 pr " guestfs_h *g = Guestfs_val (gv);\n";
8442 pr " if (g == NULL)\n";
8443 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
8449 | Device n | Dev_or_Path n
8453 pr " const char *%s = String_val (%sv);\n" n n
8455 pr " const char *%s =\n" n;
8456 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
8459 pr " const char *%s = String_val (%sv);\n" n n;
8460 pr " size_t %s_size = caml_string_length (%sv);\n" n n
8461 | StringList n | DeviceList n ->
8462 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
8464 pr " int %s = Bool_val (%sv);\n" n n
8466 pr " int %s = Int_val (%sv);\n" n n
8468 pr " int64_t %s = Int64_val (%sv);\n" n n
8471 match fst style with
8472 | RErr -> pr " int r;\n"; "-1"
8473 | RInt _ -> pr " int r;\n"; "-1"
8474 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8475 | RBool _ -> pr " int r;\n"; "-1"
8476 | RConstString _ | RConstOptString _ ->
8477 pr " const char *r;\n"; "NULL"
8478 | RString _ -> pr " char *r;\n"; "NULL"
8483 | RStruct (_, typ) ->
8484 pr " struct guestfs_%s *r;\n" typ; "NULL"
8485 | RStructList (_, typ) ->
8486 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8493 pr " size_t size;\n";
8497 pr " caml_enter_blocking_section ();\n";
8498 pr " r = guestfs_%s " name;
8499 generate_c_call_args ~handle:"g" style;
8501 pr " caml_leave_blocking_section ();\n";
8505 | StringList n | DeviceList n ->
8506 pr " ocaml_guestfs_free_strings (%s);\n" n;
8507 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8508 | Bool _ | Int _ | Int64 _
8509 | FileIn _ | FileOut _ | BufferIn _ -> ()
8512 pr " if (r == %s)\n" error_code;
8513 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
8516 (match fst style with
8517 | RErr -> pr " rv = Val_unit;\n"
8518 | RInt _ -> pr " rv = Val_int (r);\n"
8520 pr " rv = caml_copy_int64 (r);\n"
8521 | RBool _ -> pr " rv = Val_bool (r);\n"
8523 pr " rv = caml_copy_string (r);\n"
8524 | RConstOptString _ ->
8525 pr " if (r) { /* Some string */\n";
8526 pr " v = caml_alloc (1, 0);\n";
8527 pr " v2 = caml_copy_string (r);\n";
8528 pr " Store_field (v, 0, v2);\n";
8529 pr " } else /* None */\n";
8530 pr " v = Val_int (0);\n";
8532 pr " rv = caml_copy_string (r);\n";
8535 pr " rv = caml_copy_string_array ((const char **) r);\n";
8536 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8538 | RStruct (_, typ) ->
8539 pr " rv = copy_%s (r);\n" typ;
8540 pr " guestfs_free_%s (r);\n" typ;
8541 | RStructList (_, typ) ->
8542 pr " rv = copy_%s_list (r);\n" typ;
8543 pr " guestfs_free_%s_list (r);\n" typ;
8545 pr " rv = copy_table (r);\n";
8546 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8549 pr " rv = caml_alloc_string (size);\n";
8550 pr " memcpy (String_val (rv), r, size);\n";
8553 pr " CAMLreturn (rv);\n";
8557 if List.length params > 5 then (
8558 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8559 pr "CAMLprim value ";
8560 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
8561 pr "CAMLprim value\n";
8562 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
8564 pr " return ocaml_guestfs_%s (argv[0]" name;
8565 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
8570 ) all_functions_sorted
8572 and generate_ocaml_structure_decls () =
8575 pr "type %s = {\n" typ;
8578 | name, FString -> pr " %s : string;\n" name
8579 | name, FBuffer -> pr " %s : string;\n" name
8580 | name, FUUID -> pr " %s : string;\n" name
8581 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
8582 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
8583 | name, FChar -> pr " %s : char;\n" name
8584 | name, FOptPercent -> pr " %s : float option;\n" name
8590 and generate_ocaml_prototype ?(is_external = false) name style =
8591 if is_external then pr "external " else pr "val ";
8592 pr "%s : t -> " name;
8595 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _
8596 | BufferIn _ -> pr "string -> "
8597 | OptString _ -> pr "string option -> "
8598 | StringList _ | DeviceList _ -> pr "string array -> "
8599 | Bool _ -> pr "bool -> "
8600 | Int _ -> pr "int -> "
8601 | Int64 _ -> pr "int64 -> "
8603 (match fst style with
8604 | RErr -> pr "unit" (* all errors are turned into exceptions *)
8605 | RInt _ -> pr "int"
8606 | RInt64 _ -> pr "int64"
8607 | RBool _ -> pr "bool"
8608 | RConstString _ -> pr "string"
8609 | RConstOptString _ -> pr "string option"
8610 | RString _ | RBufferOut _ -> pr "string"
8611 | RStringList _ -> pr "string array"
8612 | RStruct (_, typ) -> pr "%s" typ
8613 | RStructList (_, typ) -> pr "%s array" typ
8614 | RHashtable _ -> pr "(string * string) list"
8616 if is_external then (
8618 if List.length (snd style) + 1 > 5 then
8619 pr "\"ocaml_guestfs_%s_byte\" " name;
8620 pr "\"ocaml_guestfs_%s\"" name
8624 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
8625 and generate_perl_xs () =
8626 generate_header CStyle LGPLv2plus;
8629 #include \"EXTERN.h\"
8633 #include <guestfs.h>
8636 #define PRId64 \"lld\"
8640 my_newSVll(long long val) {
8641 #ifdef USE_64_BIT_ALL
8642 return newSViv(val);
8646 len = snprintf(buf, 100, \"%%\" PRId64, val);
8647 return newSVpv(buf, len);
8652 #define PRIu64 \"llu\"
8656 my_newSVull(unsigned long long val) {
8657 #ifdef USE_64_BIT_ALL
8658 return newSVuv(val);
8662 len = snprintf(buf, 100, \"%%\" PRIu64, val);
8663 return newSVpv(buf, len);
8667 /* http://www.perlmonks.org/?node_id=680842 */
8669 XS_unpack_charPtrPtr (SV *arg) {
8674 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
8675 croak (\"array reference expected\");
8677 av = (AV *)SvRV (arg);
8678 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
8680 croak (\"malloc failed\");
8682 for (i = 0; i <= av_len (av); i++) {
8683 SV **elem = av_fetch (av, i, 0);
8685 if (!elem || !*elem)
8686 croak (\"missing element in list\");
8688 ret[i] = SvPV_nolen (*elem);
8696 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
8703 RETVAL = guestfs_create ();
8705 croak (\"could not create guestfs handle\");
8706 guestfs_set_error_handler (RETVAL, NULL, NULL);
8719 fun (name, style, _, _, _, _, _) ->
8720 (match fst style with
8721 | RErr -> pr "void\n"
8722 | RInt _ -> pr "SV *\n"
8723 | RInt64 _ -> pr "SV *\n"
8724 | RBool _ -> pr "SV *\n"
8725 | RConstString _ -> pr "SV *\n"
8726 | RConstOptString _ -> pr "SV *\n"
8727 | RString _ -> pr "SV *\n"
8728 | RBufferOut _ -> pr "SV *\n"
8730 | RStruct _ | RStructList _
8732 pr "void\n" (* all lists returned implictly on the stack *)
8734 (* Call and arguments. *)
8737 fun arg -> pr ", %s" (name_of_argt arg)
8740 pr " guestfs_h *g;\n";
8744 | Pathname n | Device n | Dev_or_Path n | String n
8745 | FileIn n | FileOut n ->
8748 pr " char *%s;\n" n;
8749 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
8751 (* http://www.perlmonks.org/?node_id=554277
8752 * Note that the implicit handle argument means we have
8753 * to add 1 to the ST(x) operator.
8755 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
8756 | StringList n | DeviceList n -> pr " char **%s;\n" n
8757 | Bool n -> pr " int %s;\n" n
8758 | Int n -> pr " int %s;\n" n
8759 | Int64 n -> pr " int64_t %s;\n" n
8762 let do_cleanups () =
8765 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8766 | Bool _ | Int _ | Int64 _
8767 | FileIn _ | FileOut _
8769 | StringList n | DeviceList n -> pr " free (%s);\n" n
8774 (match fst style with
8779 pr " r = guestfs_%s " name;
8780 generate_c_call_args ~handle:"g" style;
8783 pr " if (r == -1)\n";
8784 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8790 pr " %s = guestfs_%s " n name;
8791 generate_c_call_args ~handle:"g" style;
8794 pr " if (%s == -1)\n" n;
8795 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8796 pr " RETVAL = newSViv (%s);\n" n;
8801 pr " int64_t %s;\n" n;
8803 pr " %s = guestfs_%s " n name;
8804 generate_c_call_args ~handle:"g" style;
8807 pr " if (%s == -1)\n" n;
8808 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8809 pr " RETVAL = my_newSVll (%s);\n" n;
8814 pr " const char *%s;\n" n;
8816 pr " %s = guestfs_%s " n name;
8817 generate_c_call_args ~handle:"g" style;
8820 pr " if (%s == NULL)\n" n;
8821 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8822 pr " RETVAL = newSVpv (%s, 0);\n" n;
8825 | RConstOptString n ->
8827 pr " const char *%s;\n" n;
8829 pr " %s = guestfs_%s " n name;
8830 generate_c_call_args ~handle:"g" style;
8833 pr " if (%s == NULL)\n" n;
8834 pr " RETVAL = &PL_sv_undef;\n";
8836 pr " RETVAL = newSVpv (%s, 0);\n" n;
8841 pr " char *%s;\n" n;
8843 pr " %s = guestfs_%s " n name;
8844 generate_c_call_args ~handle:"g" style;
8847 pr " if (%s == NULL)\n" n;
8848 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8849 pr " RETVAL = newSVpv (%s, 0);\n" n;
8850 pr " free (%s);\n" n;
8853 | RStringList n | RHashtable n ->
8855 pr " char **%s;\n" n;
8858 pr " %s = guestfs_%s " n name;
8859 generate_c_call_args ~handle:"g" style;
8862 pr " if (%s == NULL)\n" n;
8863 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8864 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
8865 pr " EXTEND (SP, n);\n";
8866 pr " for (i = 0; i < n; ++i) {\n";
8867 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
8868 pr " free (%s[i]);\n" n;
8870 pr " free (%s);\n" n;
8871 | RStruct (n, typ) ->
8872 let cols = cols_of_struct typ in
8873 generate_perl_struct_code typ cols name style n do_cleanups
8874 | RStructList (n, typ) ->
8875 let cols = cols_of_struct typ in
8876 generate_perl_struct_list_code typ cols name style n do_cleanups
8879 pr " char *%s;\n" n;
8880 pr " size_t size;\n";
8882 pr " %s = guestfs_%s " n name;
8883 generate_c_call_args ~handle:"g" style;
8886 pr " if (%s == NULL)\n" n;
8887 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8888 pr " RETVAL = newSVpvn (%s, size);\n" n;
8889 pr " free (%s);\n" n;
8897 and generate_perl_struct_list_code typ cols name style n do_cleanups =
8899 pr " struct guestfs_%s_list *%s;\n" typ n;
8903 pr " %s = guestfs_%s " n name;
8904 generate_c_call_args ~handle:"g" style;
8907 pr " if (%s == NULL)\n" n;
8908 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8909 pr " EXTEND (SP, %s->len);\n" n;
8910 pr " for (i = 0; i < %s->len; ++i) {\n" n;
8911 pr " hv = newHV ();\n";
8915 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
8916 name (String.length name) n name
8918 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
8919 name (String.length name) n name
8921 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
8922 name (String.length name) n name n name
8923 | name, (FBytes|FUInt64) ->
8924 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
8925 name (String.length name) n name
8927 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
8928 name (String.length name) n name
8929 | name, (FInt32|FUInt32) ->
8930 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
8931 name (String.length name) n name
8933 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
8934 name (String.length name) n name
8935 | name, FOptPercent ->
8936 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
8937 name (String.length name) n name
8939 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
8941 pr " guestfs_free_%s_list (%s);\n" typ n
8943 and generate_perl_struct_code typ cols name style n do_cleanups =
8945 pr " struct guestfs_%s *%s;\n" typ n;
8947 pr " %s = guestfs_%s " n name;
8948 generate_c_call_args ~handle:"g" style;
8951 pr " if (%s == NULL)\n" n;
8952 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8953 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
8955 fun ((name, _) as col) ->
8956 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
8960 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
8963 pr " PUSHs (sv_2mortal (newSVpvn (%s->%s, %s->%s_len)));\n"
8966 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
8968 | name, (FBytes|FUInt64) ->
8969 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
8972 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
8974 | name, (FInt32|FUInt32) ->
8975 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8978 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
8980 | name, FOptPercent ->
8981 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8984 pr " free (%s);\n" n
8986 (* Generate Sys/Guestfs.pm. *)
8987 and generate_perl_pm () =
8988 generate_header HashStyle LGPLv2plus;
8995 Sys::Guestfs - Perl bindings for libguestfs
9001 my $h = Sys::Guestfs->new ();
9002 $h->add_drive ('guest.img');
9004 $h->mount ('/dev/sda1', '/');
9005 $h->touch ('/hello');
9010 The C<Sys::Guestfs> module provides a Perl XS binding to the
9011 libguestfs API for examining and modifying virtual machine
9014 Amongst the things this is good for: making batch configuration
9015 changes to guests, getting disk used/free statistics (see also:
9016 virt-df), migrating between virtualization systems (see also:
9017 virt-p2v), performing partial backups, performing partial guest
9018 clones, cloning guests and changing registry/UUID/hostname info, and
9021 Libguestfs uses Linux kernel and qemu code, and can access any type of
9022 guest filesystem that Linux and qemu can, including but not limited
9023 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9024 schemes, qcow, qcow2, vmdk.
9026 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9027 LVs, what filesystem is in each LV, etc.). It can also run commands
9028 in the context of the guest. Also you can access filesystems over
9031 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
9032 functions for using libguestfs from Perl, including integration
9037 All errors turn into calls to C<croak> (see L<Carp(3)>).
9045 package Sys::Guestfs;
9050 # This version number changes whenever a new function
9051 # is added to the libguestfs API. It is not directly
9052 # related to the libguestfs version number.
9053 use vars qw($VERSION);
9057 XSLoader::load ('Sys::Guestfs');
9059 =item $h = Sys::Guestfs->new ();
9061 Create a new guestfs handle.
9067 my $class = ref ($proto) || $proto;
9069 my $self = Sys::Guestfs::_create ();
9070 bless $self, $class;
9076 (* Actions. We only need to print documentation for these as
9077 * they are pulled in from the XS code automatically.
9080 fun (name, style, _, flags, _, _, longdesc) ->
9081 if not (List.mem NotInDocs flags) then (
9082 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
9084 generate_perl_prototype name style;
9086 pr "%s\n\n" longdesc;
9087 if List.mem ProtocolLimitWarning flags then
9088 pr "%s\n\n" protocol_limit_warning;
9089 if List.mem DangerWillRobinson flags then
9090 pr "%s\n\n" danger_will_robinson;
9091 match deprecation_notice flags with
9093 | Some txt -> pr "%s\n\n" txt
9095 ) all_functions_sorted;
9107 Copyright (C) %s Red Hat Inc.
9111 Please see the file COPYING.LIB for the full license.
9117 L<http://libguestfs.org>,
9118 L<Sys::Guestfs::Lib(3)>.
9123 and generate_perl_prototype name style =
9124 (match fst style with
9132 | RBufferOut n -> pr "$%s = " n
9134 | RHashtable n -> pr "%%%s = " n
9136 | RStructList (n,_) -> pr "@%s = " n
9139 let comma = ref false in
9142 if !comma then pr ", ";
9145 | Pathname n | Device n | Dev_or_Path n | String n
9146 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
9149 | StringList n | DeviceList n ->
9154 (* Generate Python C module. *)
9155 and generate_python_c () =
9156 generate_header CStyle LGPLv2plus;
9159 #define PY_SSIZE_T_CLEAN 1
9162 #if PY_VERSION_HEX < 0x02050000
9163 typedef int Py_ssize_t;
9164 #define PY_SSIZE_T_MAX INT_MAX
9165 #define PY_SSIZE_T_MIN INT_MIN
9172 #include \"guestfs.h\"
9180 get_handle (PyObject *obj)
9183 assert (obj != Py_None);
9184 return ((Pyguestfs_Object *) obj)->g;
9188 put_handle (guestfs_h *g)
9192 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
9195 /* This list should be freed (but not the strings) after use. */
9197 get_string_list (PyObject *obj)
9204 if (!PyList_Check (obj)) {
9205 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
9209 len = PyList_Size (obj);
9210 r = malloc (sizeof (char *) * (len+1));
9212 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
9216 for (i = 0; i < len; ++i)
9217 r[i] = PyString_AsString (PyList_GetItem (obj, i));
9224 put_string_list (char * const * const argv)
9229 for (argc = 0; argv[argc] != NULL; ++argc)
9232 list = PyList_New (argc);
9233 for (i = 0; i < argc; ++i)
9234 PyList_SetItem (list, i, PyString_FromString (argv[i]));
9240 put_table (char * const * const argv)
9242 PyObject *list, *item;
9245 for (argc = 0; argv[argc] != NULL; ++argc)
9248 list = PyList_New (argc >> 1);
9249 for (i = 0; i < argc; i += 2) {
9250 item = PyTuple_New (2);
9251 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
9252 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
9253 PyList_SetItem (list, i >> 1, item);
9260 free_strings (char **argv)
9264 for (argc = 0; argv[argc] != NULL; ++argc)
9270 py_guestfs_create (PyObject *self, PyObject *args)
9274 g = guestfs_create ();
9276 PyErr_SetString (PyExc_RuntimeError,
9277 \"guestfs.create: failed to allocate handle\");
9280 guestfs_set_error_handler (g, NULL, NULL);
9281 return put_handle (g);
9285 py_guestfs_close (PyObject *self, PyObject *args)
9290 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
9292 g = get_handle (py_g);
9296 Py_INCREF (Py_None);
9302 let emit_put_list_function typ =
9303 pr "static PyObject *\n";
9304 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
9306 pr " PyObject *list;\n";
9309 pr " list = PyList_New (%ss->len);\n" typ;
9310 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
9311 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
9312 pr " return list;\n";
9317 (* Structures, turned into Python dictionaries. *)
9320 pr "static PyObject *\n";
9321 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
9323 pr " PyObject *dict;\n";
9325 pr " dict = PyDict_New ();\n";
9329 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9330 pr " PyString_FromString (%s->%s));\n"
9333 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9334 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
9337 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9338 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
9340 | name, (FBytes|FUInt64) ->
9341 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9342 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
9345 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9346 pr " PyLong_FromLongLong (%s->%s));\n"
9349 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9350 pr " PyLong_FromUnsignedLong (%s->%s));\n"
9353 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9354 pr " PyLong_FromLong (%s->%s));\n"
9356 | name, FOptPercent ->
9357 pr " if (%s->%s >= 0)\n" typ name;
9358 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9359 pr " PyFloat_FromDouble ((double) %s->%s));\n"
9362 pr " Py_INCREF (Py_None);\n";
9363 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
9366 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9367 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
9369 pr " return dict;\n";
9375 (* Emit a put_TYPE_list function definition only if that function is used. *)
9378 | typ, (RStructListOnly | RStructAndList) ->
9379 (* generate the function for typ *)
9380 emit_put_list_function typ
9381 | typ, _ -> () (* empty *)
9382 ) (rstructs_used_by all_functions);
9384 (* Python wrapper functions. *)
9386 fun (name, style, _, _, _, _, _) ->
9387 pr "static PyObject *\n";
9388 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
9391 pr " PyObject *py_g;\n";
9392 pr " guestfs_h *g;\n";
9393 pr " PyObject *py_r;\n";
9396 match fst style with
9397 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9398 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9399 | RConstString _ | RConstOptString _ ->
9400 pr " const char *r;\n"; "NULL"
9401 | RString _ -> pr " char *r;\n"; "NULL"
9402 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9403 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9404 | RStructList (_, typ) ->
9405 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9408 pr " size_t size;\n";
9413 | Pathname n | Device n | Dev_or_Path n | String n
9414 | FileIn n | FileOut n ->
9415 pr " const char *%s;\n" n
9416 | OptString n -> pr " const char *%s;\n" n
9418 pr " const char *%s;\n" n;
9419 pr " Py_ssize_t %s_size;\n" n
9420 | StringList n | DeviceList n ->
9421 pr " PyObject *py_%s;\n" n;
9422 pr " char **%s;\n" n
9423 | Bool n -> pr " int %s;\n" n
9424 | Int n -> pr " int %s;\n" n
9425 | Int64 n -> pr " long long %s;\n" n
9430 (* Convert the parameters. *)
9431 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
9434 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
9435 | OptString _ -> pr "z"
9436 | StringList _ | DeviceList _ -> pr "O"
9437 | Bool _ -> pr "i" (* XXX Python has booleans? *)
9439 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
9440 * emulate C's int/long/long long in Python?
9442 | BufferIn _ -> pr "s#"
9444 pr ":guestfs_%s\",\n" name;
9448 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
9449 | OptString n -> pr ", &%s" n
9450 | StringList n | DeviceList n -> pr ", &py_%s" n
9451 | Bool n -> pr ", &%s" n
9452 | Int n -> pr ", &%s" n
9453 | Int64 n -> pr ", &%s" n
9454 | BufferIn n -> pr ", &%s, &%s_size" n n
9458 pr " return NULL;\n";
9460 pr " g = get_handle (py_g);\n";
9463 | Pathname _ | Device _ | Dev_or_Path _ | String _
9464 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9466 | StringList n | DeviceList n ->
9467 pr " %s = get_string_list (py_%s);\n" n n;
9468 pr " if (!%s) return NULL;\n" n
9473 pr " r = guestfs_%s " name;
9474 generate_c_call_args ~handle:"g" style;
9479 | Pathname _ | Device _ | Dev_or_Path _ | String _
9480 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9482 | StringList n | DeviceList n ->
9483 pr " free (%s);\n" n
9486 pr " if (r == %s) {\n" error_code;
9487 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
9488 pr " return NULL;\n";
9492 (match fst style with
9494 pr " Py_INCREF (Py_None);\n";
9495 pr " py_r = Py_None;\n"
9497 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
9498 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
9499 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
9500 | RConstOptString _ ->
9502 pr " py_r = PyString_FromString (r);\n";
9504 pr " Py_INCREF (Py_None);\n";
9505 pr " py_r = Py_None;\n";
9508 pr " py_r = PyString_FromString (r);\n";
9511 pr " py_r = put_string_list (r);\n";
9512 pr " free_strings (r);\n"
9513 | RStruct (_, typ) ->
9514 pr " py_r = put_%s (r);\n" typ;
9515 pr " guestfs_free_%s (r);\n" typ
9516 | RStructList (_, typ) ->
9517 pr " py_r = put_%s_list (r);\n" typ;
9518 pr " guestfs_free_%s_list (r);\n" typ
9520 pr " py_r = put_table (r);\n";
9521 pr " free_strings (r);\n"
9523 pr " py_r = PyString_FromStringAndSize (r, size);\n";
9527 pr " return py_r;\n";
9532 (* Table of functions. *)
9533 pr "static PyMethodDef methods[] = {\n";
9534 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
9535 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
9537 fun (name, _, _, _, _, _, _) ->
9538 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
9541 pr " { NULL, NULL, 0, NULL }\n";
9545 (* Init function. *)
9548 initlibguestfsmod (void)
9550 static int initialized = 0;
9552 if (initialized) return;
9553 Py_InitModule ((char *) \"libguestfsmod\", methods);
9558 (* Generate Python module. *)
9559 and generate_python_py () =
9560 generate_header HashStyle LGPLv2plus;
9563 u\"\"\"Python bindings for libguestfs
9566 g = guestfs.GuestFS ()
9567 g.add_drive (\"guest.img\")
9569 parts = g.list_partitions ()
9571 The guestfs module provides a Python binding to the libguestfs API
9572 for examining and modifying virtual machine disk images.
9574 Amongst the things this is good for: making batch configuration
9575 changes to guests, getting disk used/free statistics (see also:
9576 virt-df), migrating between virtualization systems (see also:
9577 virt-p2v), performing partial backups, performing partial guest
9578 clones, cloning guests and changing registry/UUID/hostname info, and
9581 Libguestfs uses Linux kernel and qemu code, and can access any type of
9582 guest filesystem that Linux and qemu can, including but not limited
9583 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9584 schemes, qcow, qcow2, vmdk.
9586 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9587 LVs, what filesystem is in each LV, etc.). It can also run commands
9588 in the context of the guest. Also you can access filesystems over
9591 Errors which happen while using the API are turned into Python
9592 RuntimeError exceptions.
9594 To create a guestfs handle you usually have to perform the following
9597 # Create the handle, call add_drive at least once, and possibly
9598 # several times if the guest has multiple block devices:
9599 g = guestfs.GuestFS ()
9600 g.add_drive (\"guest.img\")
9602 # Launch the qemu subprocess and wait for it to become ready:
9605 # Now you can issue commands, for example:
9610 import libguestfsmod
9613 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
9615 def __init__ (self):
9616 \"\"\"Create a new libguestfs handle.\"\"\"
9617 self._o = libguestfsmod.create ()
9620 libguestfsmod.close (self._o)
9625 fun (name, style, _, flags, _, _, longdesc) ->
9627 generate_py_call_args ~handle:"self" (snd style);
9630 if not (List.mem NotInDocs flags) then (
9631 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9633 match fst style with
9634 | RErr | RInt _ | RInt64 _ | RBool _
9635 | RConstOptString _ | RConstString _
9636 | RString _ | RBufferOut _ -> doc
9638 doc ^ "\n\nThis function returns a list of strings."
9639 | RStruct (_, typ) ->
9640 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
9641 | RStructList (_, typ) ->
9642 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
9644 doc ^ "\n\nThis function returns a dictionary." in
9646 if List.mem ProtocolLimitWarning flags then
9647 doc ^ "\n\n" ^ protocol_limit_warning
9650 if List.mem DangerWillRobinson flags then
9651 doc ^ "\n\n" ^ danger_will_robinson
9654 match deprecation_notice flags with
9656 | Some txt -> doc ^ "\n\n" ^ txt in
9657 let doc = pod2text ~width:60 name doc in
9658 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
9659 let doc = String.concat "\n " doc in
9660 pr " u\"\"\"%s\"\"\"\n" doc;
9662 pr " return libguestfsmod.%s " name;
9663 generate_py_call_args ~handle:"self._o" (snd style);
9668 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
9669 and generate_py_call_args ~handle args =
9671 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9674 (* Useful if you need the longdesc POD text as plain text. Returns a
9677 * Because this is very slow (the slowest part of autogeneration),
9678 * we memoize the results.
9680 and pod2text ~width name longdesc =
9681 let key = width, name, longdesc in
9682 try Hashtbl.find pod2text_memo key
9684 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
9685 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
9687 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
9688 let chan = open_process_in cmd in
9689 let lines = ref [] in
9691 let line = input_line chan in
9692 if i = 1 then (* discard the first line of output *)
9695 let line = triml line in
9696 lines := line :: !lines;
9699 let lines = try loop 1 with End_of_file -> List.rev !lines in
9701 (match close_process_in chan with
9704 failwithf "pod2text: process exited with non-zero status (%d)" i
9705 | WSIGNALED i | WSTOPPED i ->
9706 failwithf "pod2text: process signalled or stopped by signal %d" i
9708 Hashtbl.add pod2text_memo key lines;
9709 pod2text_memo_updated ();
9712 (* Generate ruby bindings. *)
9713 and generate_ruby_c () =
9714 generate_header CStyle LGPLv2plus;
9722 #include \"guestfs.h\"
9724 #include \"extconf.h\"
9726 /* For Ruby < 1.9 */
9728 #define RARRAY_LEN(r) (RARRAY((r))->len)
9731 static VALUE m_guestfs; /* guestfs module */
9732 static VALUE c_guestfs; /* guestfs_h handle */
9733 static VALUE e_Error; /* used for all errors */
9735 static void ruby_guestfs_free (void *p)
9738 guestfs_close ((guestfs_h *) p);
9741 static VALUE ruby_guestfs_create (VALUE m)
9745 g = guestfs_create ();
9747 rb_raise (e_Error, \"failed to create guestfs handle\");
9749 /* Don't print error messages to stderr by default. */
9750 guestfs_set_error_handler (g, NULL, NULL);
9752 /* Wrap it, and make sure the close function is called when the
9755 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
9758 static VALUE ruby_guestfs_close (VALUE gv)
9761 Data_Get_Struct (gv, guestfs_h, g);
9763 ruby_guestfs_free (g);
9764 DATA_PTR (gv) = NULL;
9772 fun (name, style, _, _, _, _, _) ->
9773 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
9774 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
9777 pr " guestfs_h *g;\n";
9778 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
9780 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
9786 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
9787 pr " Check_Type (%sv, T_STRING);\n" n;
9788 pr " const char *%s = StringValueCStr (%sv);\n" n n;
9790 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9791 pr " \"%s\", \"%s\");\n" n name
9793 pr " Check_Type (%sv, T_STRING);\n" n;
9794 pr " const char *%s = RSTRING (%sv)->ptr;\n" n n;
9796 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9797 pr " \"%s\", \"%s\");\n" n name;
9798 pr " size_t %s_size = RSTRING (%sv)->len;\n" n n
9800 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
9801 | StringList n | DeviceList n ->
9802 pr " char **%s;\n" n;
9803 pr " Check_Type (%sv, T_ARRAY);\n" n;
9805 pr " int i, len;\n";
9806 pr " len = RARRAY_LEN (%sv);\n" n;
9807 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
9809 pr " for (i = 0; i < len; ++i) {\n";
9810 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
9811 pr " %s[i] = StringValueCStr (v);\n" n;
9813 pr " %s[len] = NULL;\n" n;
9816 pr " int %s = RTEST (%sv);\n" n n
9818 pr " int %s = NUM2INT (%sv);\n" n n
9820 pr " long long %s = NUM2LL (%sv);\n" n n
9825 match fst style with
9826 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9827 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9828 | RConstString _ | RConstOptString _ ->
9829 pr " const char *r;\n"; "NULL"
9830 | RString _ -> pr " char *r;\n"; "NULL"
9831 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9832 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9833 | RStructList (_, typ) ->
9834 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9837 pr " size_t size;\n";
9841 pr " r = guestfs_%s " name;
9842 generate_c_call_args ~handle:"g" style;
9847 | Pathname _ | Device _ | Dev_or_Path _ | String _
9848 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9850 | StringList n | DeviceList n ->
9851 pr " free (%s);\n" n
9854 pr " if (r == %s)\n" error_code;
9855 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
9858 (match fst style with
9860 pr " return Qnil;\n"
9861 | RInt _ | RBool _ ->
9862 pr " return INT2NUM (r);\n"
9864 pr " return ULL2NUM (r);\n"
9866 pr " return rb_str_new2 (r);\n";
9867 | RConstOptString _ ->
9869 pr " return rb_str_new2 (r);\n";
9871 pr " return Qnil;\n";
9873 pr " VALUE rv = rb_str_new2 (r);\n";
9877 pr " int i, len = 0;\n";
9878 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
9879 pr " VALUE rv = rb_ary_new2 (len);\n";
9880 pr " for (i = 0; r[i] != NULL; ++i) {\n";
9881 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
9882 pr " free (r[i]);\n";
9886 | RStruct (_, typ) ->
9887 let cols = cols_of_struct typ in
9888 generate_ruby_struct_code typ cols
9889 | RStructList (_, typ) ->
9890 let cols = cols_of_struct typ in
9891 generate_ruby_struct_list_code typ cols
9893 pr " VALUE rv = rb_hash_new ();\n";
9895 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
9896 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
9897 pr " free (r[i]);\n";
9898 pr " free (r[i+1]);\n";
9903 pr " VALUE rv = rb_str_new (r, size);\n";
9913 /* Initialize the module. */
9914 void Init__guestfs ()
9916 m_guestfs = rb_define_module (\"Guestfs\");
9917 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
9918 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
9920 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
9921 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
9924 (* Define the rest of the methods. *)
9926 fun (name, style, _, _, _, _, _) ->
9927 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
9928 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
9933 (* Ruby code to return a struct. *)
9934 and generate_ruby_struct_code typ cols =
9935 pr " VALUE rv = rb_hash_new ();\n";
9939 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
9941 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
9943 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
9944 | name, (FBytes|FUInt64) ->
9945 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
9947 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
9949 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
9951 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
9952 | name, FOptPercent ->
9953 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
9954 | name, FChar -> (* XXX wrong? *)
9955 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
9957 pr " guestfs_free_%s (r);\n" typ;
9960 (* Ruby code to return a struct list. *)
9961 and generate_ruby_struct_list_code typ cols =
9962 pr " VALUE rv = rb_ary_new2 (r->len);\n";
9964 pr " for (i = 0; i < r->len; ++i) {\n";
9965 pr " VALUE hv = rb_hash_new ();\n";
9969 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
9971 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, r->val[i].%s_len));\n" name name name
9973 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
9974 | name, (FBytes|FUInt64) ->
9975 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
9977 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
9979 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
9981 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
9982 | name, FOptPercent ->
9983 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
9984 | name, FChar -> (* XXX wrong? *)
9985 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
9987 pr " rb_ary_push (rv, hv);\n";
9989 pr " guestfs_free_%s_list (r);\n" typ;
9992 (* Generate Java bindings GuestFS.java file. *)
9993 and generate_java_java () =
9994 generate_header CStyle LGPLv2plus;
9997 package com.redhat.et.libguestfs;
9999 import java.util.HashMap;
10000 import com.redhat.et.libguestfs.LibGuestFSException;
10001 import com.redhat.et.libguestfs.PV;
10002 import com.redhat.et.libguestfs.VG;
10003 import com.redhat.et.libguestfs.LV;
10004 import com.redhat.et.libguestfs.Stat;
10005 import com.redhat.et.libguestfs.StatVFS;
10006 import com.redhat.et.libguestfs.IntBool;
10007 import com.redhat.et.libguestfs.Dirent;
10010 * The GuestFS object is a libguestfs handle.
10014 public class GuestFS {
10015 // Load the native code.
10017 System.loadLibrary (\"guestfs_jni\");
10021 * The native guestfs_h pointer.
10026 * Create a libguestfs handle.
10028 * @throws LibGuestFSException
10030 public GuestFS () throws LibGuestFSException
10034 private native long _create () throws LibGuestFSException;
10037 * Close a libguestfs handle.
10039 * You can also leave handles to be collected by the garbage
10040 * collector, but this method ensures that the resources used
10041 * by the handle are freed up immediately. If you call any
10042 * other methods after closing the handle, you will get an
10045 * @throws LibGuestFSException
10047 public void close () throws LibGuestFSException
10053 private native void _close (long g) throws LibGuestFSException;
10055 public void finalize () throws LibGuestFSException
10063 fun (name, style, _, flags, _, shortdesc, longdesc) ->
10064 if not (List.mem NotInDocs flags); then (
10065 let doc = replace_str longdesc "C<guestfs_" "C<g." in
10067 if List.mem ProtocolLimitWarning flags then
10068 doc ^ "\n\n" ^ protocol_limit_warning
10071 if List.mem DangerWillRobinson flags then
10072 doc ^ "\n\n" ^ danger_will_robinson
10075 match deprecation_notice flags with
10077 | Some txt -> doc ^ "\n\n" ^ txt in
10078 let doc = pod2text ~width:60 name doc in
10079 let doc = List.map ( (* RHBZ#501883 *)
10082 | nonempty -> nonempty
10084 let doc = String.concat "\n * " doc in
10087 pr " * %s\n" shortdesc;
10090 pr " * @throws LibGuestFSException\n";
10094 generate_java_prototype ~public:true ~semicolon:false name style;
10097 pr " if (g == 0)\n";
10098 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
10101 if fst style <> RErr then pr "return ";
10103 generate_java_call_args ~handle:"g" (snd style);
10107 generate_java_prototype ~privat:true ~native:true name style;
10114 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
10115 and generate_java_call_args ~handle args =
10117 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
10120 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
10121 ?(semicolon=true) name style =
10122 if privat then pr "private ";
10123 if public then pr "public ";
10124 if native then pr "native ";
10127 (match fst style with
10128 | RErr -> pr "void ";
10129 | RInt _ -> pr "int ";
10130 | RInt64 _ -> pr "long ";
10131 | RBool _ -> pr "boolean ";
10132 | RConstString _ | RConstOptString _ | RString _
10133 | RBufferOut _ -> pr "String ";
10134 | RStringList _ -> pr "String[] ";
10135 | RStruct (_, typ) ->
10136 let name = java_name_of_struct typ in
10138 | RStructList (_, typ) ->
10139 let name = java_name_of_struct typ in
10141 | RHashtable _ -> pr "HashMap<String,String> ";
10144 if native then pr "_%s " name else pr "%s " name;
10146 let needs_comma = ref false in
10149 needs_comma := true
10155 if !needs_comma then pr ", ";
10156 needs_comma := true;
10160 | Device n | Dev_or_Path n
10168 | StringList n | DeviceList n ->
10179 pr " throws LibGuestFSException";
10180 if semicolon then pr ";"
10182 and generate_java_struct jtyp cols () =
10183 generate_header CStyle LGPLv2plus;
10186 package com.redhat.et.libguestfs;
10189 * Libguestfs %s structure.
10201 | name, FBuffer -> pr " public String %s;\n" name
10202 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
10203 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
10204 | name, FChar -> pr " public char %s;\n" name
10205 | name, FOptPercent ->
10206 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
10207 pr " public float %s;\n" name
10212 and generate_java_c () =
10213 generate_header CStyle LGPLv2plus;
10217 #include <stdlib.h>
10218 #include <string.h>
10220 #include \"com_redhat_et_libguestfs_GuestFS.h\"
10221 #include \"guestfs.h\"
10223 /* Note that this function returns. The exception is not thrown
10224 * until after the wrapper function returns.
10227 throw_exception (JNIEnv *env, const char *msg)
10230 cl = (*env)->FindClass (env,
10231 \"com/redhat/et/libguestfs/LibGuestFSException\");
10232 (*env)->ThrowNew (env, cl, msg);
10235 JNIEXPORT jlong JNICALL
10236 Java_com_redhat_et_libguestfs_GuestFS__1create
10237 (JNIEnv *env, jobject obj)
10241 g = guestfs_create ();
10243 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
10246 guestfs_set_error_handler (g, NULL, NULL);
10247 return (jlong) (long) g;
10250 JNIEXPORT void JNICALL
10251 Java_com_redhat_et_libguestfs_GuestFS__1close
10252 (JNIEnv *env, jobject obj, jlong jg)
10254 guestfs_h *g = (guestfs_h *) (long) jg;
10261 fun (name, style, _, _, _, _, _) ->
10263 (match fst style with
10264 | RErr -> pr "void ";
10265 | RInt _ -> pr "jint ";
10266 | RInt64 _ -> pr "jlong ";
10267 | RBool _ -> pr "jboolean ";
10268 | RConstString _ | RConstOptString _ | RString _
10269 | RBufferOut _ -> pr "jstring ";
10270 | RStruct _ | RHashtable _ ->
10272 | RStringList _ | RStructList _ ->
10273 pr "jobjectArray ";
10276 pr "Java_com_redhat_et_libguestfs_GuestFS_";
10277 pr "%s" (replace_str ("_" ^ name) "_" "_1");
10279 pr " (JNIEnv *env, jobject obj, jlong jg";
10283 | Device n | Dev_or_Path n
10288 pr ", jstring j%s" n
10290 pr ", jbyteArray j%s" n
10291 | StringList n | DeviceList n ->
10292 pr ", jobjectArray j%s" n
10294 pr ", jboolean j%s" n
10302 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
10303 let error_code, no_ret =
10304 match fst style with
10305 | RErr -> pr " int r;\n"; "-1", ""
10307 | RInt _ -> pr " int r;\n"; "-1", "0"
10308 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
10309 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
10310 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
10312 pr " jstring jr;\n";
10313 pr " char *r;\n"; "NULL", "NULL"
10315 pr " jobjectArray jr;\n";
10316 pr " int r_len;\n";
10317 pr " jclass cl;\n";
10318 pr " jstring jstr;\n";
10319 pr " char **r;\n"; "NULL", "NULL"
10320 | RStruct (_, typ) ->
10321 pr " jobject jr;\n";
10322 pr " jclass cl;\n";
10323 pr " jfieldID fl;\n";
10324 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
10325 | RStructList (_, typ) ->
10326 pr " jobjectArray jr;\n";
10327 pr " jclass cl;\n";
10328 pr " jfieldID fl;\n";
10329 pr " jobject jfl;\n";
10330 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
10331 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
10333 pr " jstring jr;\n";
10335 pr " size_t size;\n";
10340 | Device n | Dev_or_Path n
10345 pr " const char *%s;\n" n
10347 pr " jbyte *%s;\n" n;
10348 pr " size_t %s_size;\n" n
10349 | StringList n | DeviceList n ->
10350 pr " int %s_len;\n" n;
10351 pr " const char **%s;\n" n
10356 pr " int64_t %s;\n" n
10360 (match fst style with
10361 | RStringList _ | RStructList _ -> true
10362 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
10363 | RConstOptString _
10364 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
10365 List.exists (function
10366 | StringList _ -> true
10367 | DeviceList _ -> true
10368 | _ -> false) (snd style) in
10374 (* Get the parameters. *)
10378 | Device n | Dev_or_Path n
10382 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
10384 (* This is completely undocumented, but Java null becomes
10385 * a NULL parameter.
10387 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
10389 pr " %s = (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
10390 pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
10391 | StringList n | DeviceList n ->
10392 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
10393 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
10394 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10395 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10397 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
10399 pr " %s[%s_len] = NULL;\n" n n;
10403 pr " %s = j%s;\n" n n
10406 (* Make the call. *)
10407 pr " r = guestfs_%s " name;
10408 generate_c_call_args ~handle:"g" style;
10411 (* Release the parameters. *)
10415 | Device n | Dev_or_Path n
10419 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10421 pr " if (j%s)\n" n;
10422 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10424 pr " (*env)->ReleaseByteArrayElements (env, j%s, %s, 0);\n" n n
10425 | StringList n | DeviceList n ->
10426 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10427 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10429 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
10431 pr " free (%s);\n" n
10437 (* Check for errors. *)
10438 pr " if (r == %s) {\n" error_code;
10439 pr " throw_exception (env, guestfs_last_error (g));\n";
10440 pr " return %s;\n" no_ret;
10443 (* Return value. *)
10444 (match fst style with
10446 | RInt _ -> pr " return (jint) r;\n"
10447 | RBool _ -> pr " return (jboolean) r;\n"
10448 | RInt64 _ -> pr " return (jlong) r;\n"
10449 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
10450 | RConstOptString _ ->
10451 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
10453 pr " jr = (*env)->NewStringUTF (env, r);\n";
10457 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
10458 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
10459 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
10460 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
10461 pr " for (i = 0; i < r_len; ++i) {\n";
10462 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
10463 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
10464 pr " free (r[i]);\n";
10468 | RStruct (_, typ) ->
10469 let jtyp = java_name_of_struct typ in
10470 let cols = cols_of_struct typ in
10471 generate_java_struct_return typ jtyp cols
10472 | RStructList (_, typ) ->
10473 let jtyp = java_name_of_struct typ in
10474 let cols = cols_of_struct typ in
10475 generate_java_struct_list_return typ jtyp cols
10478 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
10479 pr " return NULL;\n"
10481 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
10490 and generate_java_struct_return typ jtyp cols =
10491 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10492 pr " jr = (*env)->AllocObject (env, cl);\n";
10496 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10497 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
10500 pr " char s[33];\n";
10501 pr " memcpy (s, r->%s, 32);\n" name;
10502 pr " s[32] = 0;\n";
10503 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10504 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10508 pr " int len = r->%s_len;\n" name;
10509 pr " char s[len+1];\n";
10510 pr " memcpy (s, r->%s, len);\n" name;
10511 pr " s[len] = 0;\n";
10512 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10513 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10515 | name, (FBytes|FUInt64|FInt64) ->
10516 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10517 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10518 | name, (FUInt32|FInt32) ->
10519 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10520 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10521 | name, FOptPercent ->
10522 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10523 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
10525 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10526 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10531 and generate_java_struct_list_return typ jtyp cols =
10532 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10533 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
10534 pr " for (i = 0; i < r->len; ++i) {\n";
10535 pr " jfl = (*env)->AllocObject (env, cl);\n";
10539 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10540 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
10543 pr " char s[33];\n";
10544 pr " memcpy (s, r->val[i].%s, 32);\n" name;
10545 pr " s[32] = 0;\n";
10546 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10547 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10551 pr " int len = r->val[i].%s_len;\n" name;
10552 pr " char s[len+1];\n";
10553 pr " memcpy (s, r->val[i].%s, len);\n" name;
10554 pr " s[len] = 0;\n";
10555 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10556 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10558 | name, (FBytes|FUInt64|FInt64) ->
10559 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10560 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10561 | name, (FUInt32|FInt32) ->
10562 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10563 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10564 | name, FOptPercent ->
10565 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10566 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
10568 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10569 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10571 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
10573 pr " guestfs_free_%s_list (r);\n" typ;
10576 and generate_java_makefile_inc () =
10577 generate_header HashStyle GPLv2plus;
10579 pr "java_built_sources = \\\n";
10582 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
10584 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
10586 and generate_haskell_hs () =
10587 generate_header HaskellStyle LGPLv2plus;
10589 (* XXX We only know how to generate partial FFI for Haskell
10590 * at the moment. Please help out!
10592 let can_generate style =
10596 | RInt64 _, _ -> true
10598 | RConstString _, _
10599 | RConstOptString _, _
10605 | RBufferOut _, _ -> false in
10608 {-# INCLUDE <guestfs.h> #-}
10609 {-# LANGUAGE ForeignFunctionInterface #-}
10614 (* List out the names of the actions we want to export. *)
10616 fun (name, style, _, _, _, _, _) ->
10617 if can_generate style then pr ",\n %s" name
10623 -- Unfortunately some symbols duplicate ones already present
10624 -- in Prelude. We don't know which, so we hard-code a list
10626 import Prelude hiding (truncate)
10630 import Foreign.C.Types
10632 import Control.Exception
10633 import Data.Typeable
10635 data GuestfsS = GuestfsS -- represents the opaque C struct
10636 type GuestfsP = Ptr GuestfsS -- guestfs_h *
10637 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
10639 -- XXX define properly later XXX
10643 data IntBool = IntBool
10645 data StatVFS = StatVFS
10646 data Hashtable = Hashtable
10648 foreign import ccall unsafe \"guestfs_create\" c_create
10650 foreign import ccall unsafe \"&guestfs_close\" c_close
10651 :: FunPtr (GuestfsP -> IO ())
10652 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
10653 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
10655 create :: IO GuestfsH
10658 c_set_error_handler p nullPtr nullPtr
10659 h <- newForeignPtr c_close p
10662 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
10663 :: GuestfsP -> IO CString
10665 -- last_error :: GuestfsH -> IO (Maybe String)
10666 -- last_error h = do
10667 -- str <- withForeignPtr h (\\p -> c_last_error p)
10668 -- maybePeek peekCString str
10670 last_error :: GuestfsH -> IO (String)
10672 str <- withForeignPtr h (\\p -> c_last_error p)
10673 if (str == nullPtr)
10674 then return \"no error\"
10675 else peekCString str
10679 (* Generate wrappers for each foreign function. *)
10681 fun (name, style, _, _, _, _, _) ->
10682 if can_generate style then (
10683 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
10685 generate_haskell_prototype ~handle:"GuestfsP" style;
10689 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
10691 pr "%s %s = do\n" name
10692 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
10694 (* Convert pointer arguments using with* functions. *)
10699 | Pathname n | Device n | Dev_or_Path n | String n ->
10700 pr "withCString %s $ \\%s -> " n n
10702 pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
10703 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
10704 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
10705 | Bool _ | Int _ | Int64 _ -> ()
10707 (* Convert integer arguments. *)
10711 | Bool n -> sprintf "(fromBool %s)" n
10712 | Int n -> sprintf "(fromIntegral %s)" n
10713 | Int64 n -> sprintf "(fromIntegral %s)" n
10714 | FileIn n | FileOut n
10715 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
10716 | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
10718 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
10719 (String.concat " " ("p" :: args));
10720 (match fst style with
10721 | RErr | RInt _ | RInt64 _ | RBool _ ->
10722 pr " if (r == -1)\n";
10724 pr " err <- last_error h\n";
10726 | RConstString _ | RConstOptString _ | RString _
10727 | RStringList _ | RStruct _
10728 | RStructList _ | RHashtable _ | RBufferOut _ ->
10729 pr " if (r == nullPtr)\n";
10731 pr " err <- last_error h\n";
10734 (match fst style with
10736 pr " else return ()\n"
10738 pr " else return (fromIntegral r)\n"
10740 pr " else return (fromIntegral r)\n"
10742 pr " else return (toBool r)\n"
10744 | RConstOptString _
10751 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
10757 and generate_haskell_prototype ~handle ?(hs = false) style =
10758 pr "%s -> " handle;
10759 let string = if hs then "String" else "CString" in
10760 let int = if hs then "Int" else "CInt" in
10761 let bool = if hs then "Bool" else "CInt" in
10762 let int64 = if hs then "Integer" else "Int64" in
10766 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
10768 if hs then pr "String"
10769 else pr "CString -> CInt"
10770 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
10771 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
10772 | Bool _ -> pr "%s" bool
10773 | Int _ -> pr "%s" int
10774 | Int64 _ -> pr "%s" int
10775 | FileIn _ -> pr "%s" string
10776 | FileOut _ -> pr "%s" string
10781 (match fst style with
10782 | RErr -> if not hs then pr "CInt"
10783 | RInt _ -> pr "%s" int
10784 | RInt64 _ -> pr "%s" int64
10785 | RBool _ -> pr "%s" bool
10786 | RConstString _ -> pr "%s" string
10787 | RConstOptString _ -> pr "Maybe %s" string
10788 | RString _ -> pr "%s" string
10789 | RStringList _ -> pr "[%s]" string
10790 | RStruct (_, typ) ->
10791 let name = java_name_of_struct typ in
10793 | RStructList (_, typ) ->
10794 let name = java_name_of_struct typ in
10796 | RHashtable _ -> pr "Hashtable"
10797 | RBufferOut _ -> pr "%s" string
10801 and generate_csharp () =
10802 generate_header CPlusPlusStyle LGPLv2plus;
10804 (* XXX Make this configurable by the C# assembly users. *)
10805 let library = "libguestfs.so.0" in
10808 // These C# bindings are highly experimental at present.
10810 // Firstly they only work on Linux (ie. Mono). In order to get them
10811 // to work on Windows (ie. .Net) you would need to port the library
10812 // itself to Windows first.
10814 // The second issue is that some calls are known to be incorrect and
10815 // can cause Mono to segfault. Particularly: calls which pass or
10816 // return string[], or return any structure value. This is because
10817 // we haven't worked out the correct way to do this from C#.
10819 // The third issue is that when compiling you get a lot of warnings.
10820 // We are not sure whether the warnings are important or not.
10822 // Fourthly we do not routinely build or test these bindings as part
10823 // of the make && make check cycle, which means that regressions might
10826 // Suggestions and patches are welcome.
10830 // gmcs Libguestfs.cs
10831 // mono Libguestfs.exe
10833 // (You'll probably want to add a Test class / static main function
10834 // otherwise this won't do anything useful).
10838 using System.Runtime.InteropServices;
10839 using System.Runtime.Serialization;
10840 using System.Collections;
10844 class Error : System.ApplicationException
10846 public Error (string message) : base (message) {}
10847 protected Error (SerializationInfo info, StreamingContext context) {}
10854 [DllImport (\"%s\")]
10855 static extern IntPtr guestfs_create ();
10859 _handle = guestfs_create ();
10860 if (_handle == IntPtr.Zero)
10861 throw new Error (\"could not create guestfs handle\");
10864 [DllImport (\"%s\")]
10865 static extern void guestfs_close (IntPtr h);
10869 guestfs_close (_handle);
10872 [DllImport (\"%s\")]
10873 static extern string guestfs_last_error (IntPtr h);
10875 " library library library;
10877 (* Generate C# structure bindings. We prefix struct names with
10878 * underscore because C# cannot have conflicting struct names and
10879 * method names (eg. "class stat" and "stat").
10883 pr " [StructLayout (LayoutKind.Sequential)]\n";
10884 pr " public class _%s {\n" typ;
10887 | name, FChar -> pr " char %s;\n" name
10888 | name, FString -> pr " string %s;\n" name
10890 pr " uint %s_len;\n" name;
10891 pr " string %s;\n" name
10893 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
10894 pr " string %s;\n" name
10895 | name, FUInt32 -> pr " uint %s;\n" name
10896 | name, FInt32 -> pr " int %s;\n" name
10897 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
10898 | name, FInt64 -> pr " long %s;\n" name
10899 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
10905 (* Generate C# function bindings. *)
10907 fun (name, style, _, _, _, shortdesc, _) ->
10908 let rec csharp_return_type () =
10909 match fst style with
10911 | RBool n -> "bool"
10913 | RInt64 n -> "long"
10915 | RConstOptString n
10917 | RBufferOut n -> "string"
10918 | RStruct (_,n) -> "_" ^ n
10919 | RHashtable n -> "Hashtable"
10920 | RStringList n -> "string[]"
10921 | RStructList (_,n) -> sprintf "_%s[]" n
10923 and c_return_type () =
10924 match fst style with
10928 | RInt64 _ -> "long"
10930 | RConstOptString _
10932 | RBufferOut _ -> "string"
10933 | RStruct (_,n) -> "_" ^ n
10935 | RStringList _ -> "string[]"
10936 | RStructList (_,n) -> sprintf "_%s[]" n
10938 and c_error_comparison () =
10939 match fst style with
10943 | RInt64 _ -> "== -1"
10945 | RConstOptString _
10951 | RStructList (_,_) -> "== null"
10953 and generate_extern_prototype () =
10954 pr " static extern %s guestfs_%s (IntPtr h"
10955 (c_return_type ()) name;
10958 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
10959 | FileIn n | FileOut n
10961 pr ", [In] string %s" n
10962 | StringList n | DeviceList n ->
10963 pr ", [In] string[] %s" n
10973 and generate_public_prototype () =
10974 pr " public %s %s (" (csharp_return_type ()) name;
10975 let comma = ref false in
10977 if !comma then pr ", ";
10982 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
10983 | FileIn n | FileOut n
10985 next (); pr "string %s" n
10986 | StringList n | DeviceList n ->
10987 next (); pr "string[] %s" n
10989 next (); pr "bool %s" n
10991 next (); pr "int %s" n
10993 next (); pr "long %s" n
10997 and generate_call () =
10998 pr "guestfs_%s (_handle" name;
10999 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
11003 pr " [DllImport (\"%s\")]\n" library;
11004 generate_extern_prototype ();
11006 pr " /// <summary>\n";
11007 pr " /// %s\n" shortdesc;
11008 pr " /// </summary>\n";
11009 generate_public_prototype ();
11011 pr " %s r;\n" (c_return_type ());
11014 pr " if (r %s)\n" (c_error_comparison ());
11015 pr " throw new Error (guestfs_last_error (_handle));\n";
11016 (match fst style with
11019 pr " return r != 0 ? true : false;\n"
11021 pr " Hashtable rr = new Hashtable ();\n";
11022 pr " for (int i = 0; i < r.Length; i += 2)\n";
11023 pr " rr.Add (r[i], r[i+1]);\n";
11025 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
11026 | RString _ | RBufferOut _ | RStruct _ | RStringList _
11032 ) all_functions_sorted;
11038 and generate_bindtests () =
11039 generate_header CStyle LGPLv2plus;
11043 #include <stdlib.h>
11044 #include <inttypes.h>
11045 #include <string.h>
11047 #include \"guestfs.h\"
11048 #include \"guestfs-internal.h\"
11049 #include \"guestfs-internal-actions.h\"
11050 #include \"guestfs_protocol.h\"
11052 #define error guestfs_error
11053 #define safe_calloc guestfs_safe_calloc
11054 #define safe_malloc guestfs_safe_malloc
11057 print_strings (char *const *argv)
11062 for (argc = 0; argv[argc] != NULL; ++argc) {
11063 if (argc > 0) printf (\", \");
11064 printf (\"\\\"%%s\\\"\", argv[argc]);
11069 /* The test0 function prints its parameters to stdout. */
11073 match test_functions with
11074 | [] -> assert false
11075 | test0 :: tests -> test0, tests in
11078 let (name, style, _, _, _, _, _) = test0 in
11079 generate_prototype ~extern:false ~semicolon:false ~newline:true
11080 ~handle:"g" ~prefix:"guestfs__" name style;
11085 | Device n | Dev_or_Path n
11088 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
11092 pr " for (i = 0; i < %s_size; ++i)\n" n;
11093 pr " printf (\"<%%02x>\", %s[i]);\n" n;
11094 pr " printf (\"\\n\");\n";
11096 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
11097 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
11098 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
11099 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
11100 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
11102 pr " /* Java changes stdout line buffering so we need this: */\n";
11103 pr " fflush (stdout);\n";
11109 fun (name, style, _, _, _, _, _) ->
11110 if String.sub name (String.length name - 3) 3 <> "err" then (
11111 pr "/* Test normal return. */\n";
11112 generate_prototype ~extern:false ~semicolon:false ~newline:true
11113 ~handle:"g" ~prefix:"guestfs__" name style;
11115 (match fst style with
11120 pr " sscanf (val, \"%%d\", &r);\n";
11123 pr " int64_t r;\n";
11124 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
11127 pr " return STREQ (val, \"true\");\n"
11129 | RConstOptString _ ->
11130 (* Can't return the input string here. Return a static
11131 * string so we ensure we get a segfault if the caller
11132 * tries to free it.
11134 pr " return \"static string\";\n"
11136 pr " return strdup (val);\n"
11138 pr " char **strs;\n";
11140 pr " sscanf (val, \"%%d\", &n);\n";
11141 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
11142 pr " for (i = 0; i < n; ++i) {\n";
11143 pr " strs[i] = safe_malloc (g, 16);\n";
11144 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
11146 pr " strs[n] = NULL;\n";
11147 pr " return strs;\n"
11148 | RStruct (_, typ) ->
11149 pr " struct guestfs_%s *r;\n" typ;
11150 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11152 | RStructList (_, typ) ->
11153 pr " struct guestfs_%s_list *r;\n" typ;
11154 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11155 pr " sscanf (val, \"%%d\", &r->len);\n";
11156 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
11159 pr " char **strs;\n";
11161 pr " sscanf (val, \"%%d\", &n);\n";
11162 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
11163 pr " for (i = 0; i < n; ++i) {\n";
11164 pr " strs[i*2] = safe_malloc (g, 16);\n";
11165 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
11166 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
11167 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
11169 pr " strs[n*2] = NULL;\n";
11170 pr " return strs;\n"
11172 pr " return strdup (val);\n"
11177 pr "/* Test error return. */\n";
11178 generate_prototype ~extern:false ~semicolon:false ~newline:true
11179 ~handle:"g" ~prefix:"guestfs__" name style;
11181 pr " error (g, \"error\");\n";
11182 (match fst style with
11183 | RErr | RInt _ | RInt64 _ | RBool _ ->
11185 | RConstString _ | RConstOptString _
11186 | RString _ | RStringList _ | RStruct _
11190 pr " return NULL;\n"
11197 and generate_ocaml_bindtests () =
11198 generate_header OCamlStyle GPLv2plus;
11202 let g = Guestfs.create () in
11206 String.concat " " (
11209 | CallString s -> "\"" ^ s ^ "\""
11210 | CallOptString None -> "None"
11211 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
11212 | CallStringList xs ->
11213 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
11214 | CallInt i when i >= 0 -> string_of_int i
11215 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
11216 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
11217 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
11218 | CallBool b -> string_of_bool b
11219 | CallBuffer s -> sprintf "%S" s
11224 generate_lang_bindtests (
11225 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
11228 pr "print_endline \"EOF\"\n"
11230 and generate_perl_bindtests () =
11231 pr "#!/usr/bin/perl -w\n";
11232 generate_header HashStyle GPLv2plus;
11239 my $g = Sys::Guestfs->new ();
11243 String.concat ", " (
11246 | CallString s -> "\"" ^ s ^ "\""
11247 | CallOptString None -> "undef"
11248 | CallOptString (Some s) -> sprintf "\"%s\"" s
11249 | CallStringList xs ->
11250 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11251 | CallInt i -> string_of_int i
11252 | CallInt64 i -> Int64.to_string i
11253 | CallBool b -> if b then "1" else "0"
11254 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11259 generate_lang_bindtests (
11260 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
11263 pr "print \"EOF\\n\"\n"
11265 and generate_python_bindtests () =
11266 generate_header HashStyle GPLv2plus;
11271 g = guestfs.GuestFS ()
11275 String.concat ", " (
11278 | CallString s -> "\"" ^ s ^ "\""
11279 | CallOptString None -> "None"
11280 | CallOptString (Some s) -> sprintf "\"%s\"" s
11281 | CallStringList xs ->
11282 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11283 | CallInt i -> string_of_int i
11284 | CallInt64 i -> Int64.to_string i
11285 | CallBool b -> if b then "1" else "0"
11286 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11291 generate_lang_bindtests (
11292 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
11295 pr "print \"EOF\"\n"
11297 and generate_ruby_bindtests () =
11298 generate_header HashStyle GPLv2plus;
11303 g = Guestfs::create()
11307 String.concat ", " (
11310 | CallString s -> "\"" ^ s ^ "\""
11311 | CallOptString None -> "nil"
11312 | CallOptString (Some s) -> sprintf "\"%s\"" s
11313 | CallStringList xs ->
11314 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11315 | CallInt i -> string_of_int i
11316 | CallInt64 i -> Int64.to_string i
11317 | CallBool b -> string_of_bool b
11318 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11323 generate_lang_bindtests (
11324 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
11327 pr "print \"EOF\\n\"\n"
11329 and generate_java_bindtests () =
11330 generate_header CStyle GPLv2plus;
11333 import com.redhat.et.libguestfs.*;
11335 public class Bindtests {
11336 public static void main (String[] argv)
11339 GuestFS g = new GuestFS ();
11343 String.concat ", " (
11346 | CallString s -> "\"" ^ s ^ "\""
11347 | CallOptString None -> "null"
11348 | CallOptString (Some s) -> sprintf "\"%s\"" s
11349 | CallStringList xs ->
11351 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
11352 | CallInt i -> string_of_int i
11353 | CallInt64 i -> Int64.to_string i
11354 | CallBool b -> string_of_bool b
11356 "new byte[] { " ^ String.concat "," (
11357 map_chars (fun c -> string_of_int (Char.code c)) s
11363 generate_lang_bindtests (
11364 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
11368 System.out.println (\"EOF\");
11370 catch (Exception exn) {
11371 System.err.println (exn);
11378 and generate_haskell_bindtests () =
11379 generate_header HaskellStyle GPLv2plus;
11382 module Bindtests where
11383 import qualified Guestfs
11386 g <- Guestfs.create
11390 String.concat " " (
11393 | CallString s -> "\"" ^ s ^ "\""
11394 | CallOptString None -> "Nothing"
11395 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
11396 | CallStringList xs ->
11397 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11398 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
11399 | CallInt i -> string_of_int i
11400 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
11401 | CallInt64 i -> Int64.to_string i
11402 | CallBool true -> "True"
11403 | CallBool false -> "False"
11404 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11409 generate_lang_bindtests (
11410 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
11413 pr " putStrLn \"EOF\"\n"
11415 (* Language-independent bindings tests - we do it this way to
11416 * ensure there is parity in testing bindings across all languages.
11418 and generate_lang_bindtests call =
11419 call "test0" [CallString "abc"; CallOptString (Some "def");
11420 CallStringList []; CallBool false;
11421 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11422 CallBuffer "abc\000abc"];
11423 call "test0" [CallString "abc"; CallOptString None;
11424 CallStringList []; CallBool false;
11425 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11426 CallBuffer "abc\000abc"];
11427 call "test0" [CallString ""; CallOptString (Some "def");
11428 CallStringList []; CallBool false;
11429 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11430 CallBuffer "abc\000abc"];
11431 call "test0" [CallString ""; CallOptString (Some "");
11432 CallStringList []; CallBool false;
11433 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11434 CallBuffer "abc\000abc"];
11435 call "test0" [CallString "abc"; CallOptString (Some "def");
11436 CallStringList ["1"]; CallBool false;
11437 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11438 CallBuffer "abc\000abc"];
11439 call "test0" [CallString "abc"; CallOptString (Some "def");
11440 CallStringList ["1"; "2"]; CallBool false;
11441 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11442 CallBuffer "abc\000abc"];
11443 call "test0" [CallString "abc"; CallOptString (Some "def");
11444 CallStringList ["1"]; CallBool true;
11445 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11446 CallBuffer "abc\000abc"];
11447 call "test0" [CallString "abc"; CallOptString (Some "def");
11448 CallStringList ["1"]; CallBool false;
11449 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456";
11450 CallBuffer "abc\000abc"];
11451 call "test0" [CallString "abc"; CallOptString (Some "def");
11452 CallStringList ["1"]; CallBool false;
11453 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456";
11454 CallBuffer "abc\000abc"];
11455 call "test0" [CallString "abc"; CallOptString (Some "def");
11456 CallStringList ["1"]; CallBool false;
11457 CallInt 1; CallInt64 1L; CallString "123"; CallString "456";
11458 CallBuffer "abc\000abc"];
11459 call "test0" [CallString "abc"; CallOptString (Some "def");
11460 CallStringList ["1"]; CallBool false;
11461 CallInt 2; CallInt64 2L; CallString "123"; CallString "456";
11462 CallBuffer "abc\000abc"];
11463 call "test0" [CallString "abc"; CallOptString (Some "def");
11464 CallStringList ["1"]; CallBool false;
11465 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456";
11466 CallBuffer "abc\000abc"];
11467 call "test0" [CallString "abc"; CallOptString (Some "def");
11468 CallStringList ["1"]; CallBool false;
11469 CallInt 0; CallInt64 0L; CallString ""; CallString "";
11470 CallBuffer "abc\000abc"]
11472 (* XXX Add here tests of the return and error functions. *)
11474 (* Code to generator bindings for virt-inspector. Currently only
11475 * implemented for OCaml code (for virt-p2v 2.0).
11477 let rng_input = "inspector/virt-inspector.rng"
11479 (* Read the input file and parse it into internal structures. This is
11480 * by no means a complete RELAX NG parser, but is just enough to be
11481 * able to parse the specific input file.
11484 | Element of string * rng list (* <element name=name/> *)
11485 | Attribute of string * rng list (* <attribute name=name/> *)
11486 | Interleave of rng list (* <interleave/> *)
11487 | ZeroOrMore of rng (* <zeroOrMore/> *)
11488 | OneOrMore of rng (* <oneOrMore/> *)
11489 | Optional of rng (* <optional/> *)
11490 | Choice of string list (* <choice><value/>*</choice> *)
11491 | Value of string (* <value>str</value> *)
11492 | Text (* <text/> *)
11494 let rec string_of_rng = function
11495 | Element (name, xs) ->
11496 "Element (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11497 | Attribute (name, xs) ->
11498 "Attribute (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11499 | Interleave xs -> "Interleave (" ^ string_of_rng_list xs ^ ")"
11500 | ZeroOrMore rng -> "ZeroOrMore (" ^ string_of_rng rng ^ ")"
11501 | OneOrMore rng -> "OneOrMore (" ^ string_of_rng rng ^ ")"
11502 | Optional rng -> "Optional (" ^ string_of_rng rng ^ ")"
11503 | Choice values -> "Choice [" ^ String.concat ", " values ^ "]"
11504 | Value value -> "Value \"" ^ value ^ "\""
11507 and string_of_rng_list xs =
11508 String.concat ", " (List.map string_of_rng xs)
11510 let rec parse_rng ?defines context = function
11512 | Xml.Element ("element", ["name", name], children) :: rest ->
11513 Element (name, parse_rng ?defines context children)
11514 :: parse_rng ?defines context rest
11515 | Xml.Element ("attribute", ["name", name], children) :: rest ->
11516 Attribute (name, parse_rng ?defines context children)
11517 :: parse_rng ?defines context rest
11518 | Xml.Element ("interleave", [], children) :: rest ->
11519 Interleave (parse_rng ?defines context children)
11520 :: parse_rng ?defines context rest
11521 | Xml.Element ("zeroOrMore", [], [child]) :: rest ->
11522 let rng = parse_rng ?defines context [child] in
11524 | [child] -> ZeroOrMore child :: parse_rng ?defines context rest
11526 failwithf "%s: <zeroOrMore> contains more than one child element"
11529 | Xml.Element ("oneOrMore", [], [child]) :: rest ->
11530 let rng = parse_rng ?defines context [child] in
11532 | [child] -> OneOrMore child :: parse_rng ?defines context rest
11534 failwithf "%s: <oneOrMore> contains more than one child element"
11537 | Xml.Element ("optional", [], [child]) :: rest ->
11538 let rng = parse_rng ?defines context [child] in
11540 | [child] -> Optional child :: parse_rng ?defines context rest
11542 failwithf "%s: <optional> contains more than one child element"
11545 | Xml.Element ("choice", [], children) :: rest ->
11546 let values = List.map (
11547 function Xml.Element ("value", [], [Xml.PCData value]) -> value
11549 failwithf "%s: can't handle anything except <value> in <choice>"
11553 :: parse_rng ?defines context rest
11554 | Xml.Element ("value", [], [Xml.PCData value]) :: rest ->
11555 Value value :: parse_rng ?defines context rest
11556 | Xml.Element ("text", [], []) :: rest ->
11557 Text :: parse_rng ?defines context rest
11558 | Xml.Element ("ref", ["name", name], []) :: rest ->
11559 (* Look up the reference. Because of limitations in this parser,
11560 * we can't handle arbitrarily nested <ref> yet. You can only
11561 * use <ref> from inside <start>.
11563 (match defines with
11565 failwithf "%s: contains <ref>, but no refs are defined yet" context
11567 let rng = StringMap.find name map in
11568 rng @ parse_rng ?defines context rest
11571 failwithf "%s: can't handle '%s' in schema" context (Xml.to_string x)
11574 let xml = Xml.parse_file rng_input in
11576 | Xml.Element ("grammar", _,
11577 Xml.Element ("start", _, gram) :: defines) ->
11578 (* The <define/> elements are referenced in the <start> section,
11579 * so build a map of those first.
11581 let defines = List.fold_left (
11583 function Xml.Element ("define", ["name", name], defn) ->
11584 StringMap.add name defn map
11586 failwithf "%s: expected <define name=name/>" rng_input
11587 ) StringMap.empty defines in
11588 let defines = StringMap.mapi parse_rng defines in
11590 (* Parse the <start> clause, passing the defines. *)
11591 parse_rng ~defines "<start>" gram
11593 failwithf "%s: input is not <grammar><start/><define>*</grammar>"
11596 let name_of_field = function
11597 | Element (name, _) | Attribute (name, _)
11598 | ZeroOrMore (Element (name, _))
11599 | OneOrMore (Element (name, _))
11600 | Optional (Element (name, _)) -> name
11601 | Optional (Attribute (name, _)) -> name
11602 | Text -> (* an unnamed field in an element *)
11605 failwithf "name_of_field failed at: %s" (string_of_rng rng)
11607 (* At the moment this function only generates OCaml types. However we
11608 * should parameterize it later so it can generate types/structs in a
11609 * variety of languages.
11611 let generate_types xs =
11612 (* A simple type is one that can be printed out directly, eg.
11613 * "string option". A complex type is one which has a name and has
11614 * to be defined via another toplevel definition, eg. a struct.
11616 * generate_type generates code for either simple or complex types.
11617 * In the simple case, it returns the string ("string option"). In
11618 * the complex case, it returns the name ("mountpoint"). In the
11619 * complex case it has to print out the definition before returning,
11620 * so it should only be called when we are at the beginning of a
11621 * new line (BOL context).
11623 let rec generate_type = function
11624 | Text -> (* string *)
11626 | Choice values -> (* [`val1|`val2|...] *)
11627 "[" ^ String.concat "|" (List.map ((^)"`") values) ^ "]", true
11628 | ZeroOrMore rng -> (* <rng> list *)
11629 let t, is_simple = generate_type rng in
11630 t ^ " list (* 0 or more *)", is_simple
11631 | OneOrMore rng -> (* <rng> list *)
11632 let t, is_simple = generate_type rng in
11633 t ^ " list (* 1 or more *)", is_simple
11634 (* virt-inspector hack: bool *)
11635 | Optional (Attribute (name, [Value "1"])) ->
11637 | Optional rng -> (* <rng> list *)
11638 let t, is_simple = generate_type rng in
11639 t ^ " option", is_simple
11640 (* type name = { fields ... } *)
11641 | Element (name, fields) when is_attrs_interleave fields ->
11642 generate_type_struct name (get_attrs_interleave fields)
11643 | Element (name, [field]) (* type name = field *)
11644 | Attribute (name, [field]) ->
11645 let t, is_simple = generate_type field in
11646 if is_simple then (t, true)
11648 pr "type %s = %s\n" name t;
11651 | Element (name, fields) -> (* type name = { fields ... } *)
11652 generate_type_struct name fields
11654 failwithf "generate_type failed at: %s" (string_of_rng rng)
11656 and is_attrs_interleave = function
11657 | [Interleave _] -> true
11658 | Attribute _ :: fields -> is_attrs_interleave fields
11659 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11662 and get_attrs_interleave = function
11663 | [Interleave fields] -> fields
11664 | ((Attribute _) as field) :: fields
11665 | ((Optional (Attribute _)) as field) :: fields ->
11666 field :: get_attrs_interleave fields
11667 | _ -> assert false
11669 and generate_types xs =
11670 List.iter (fun x -> ignore (generate_type x)) xs
11672 and generate_type_struct name fields =
11673 (* Calculate the types of the fields first. We have to do this
11674 * before printing anything so we are still in BOL context.
11676 let types = List.map fst (List.map generate_type fields) in
11678 (* Special case of a struct containing just a string and another
11679 * field. Turn it into an assoc list.
11682 | ["string"; other] ->
11683 let fname1, fname2 =
11685 | [f1; f2] -> name_of_field f1, name_of_field f2
11686 | _ -> assert false in
11687 pr "type %s = string * %s (* %s -> %s *)\n" name other fname1 fname2;
11691 pr "type %s = {\n" name;
11693 fun (field, ftype) ->
11694 let fname = name_of_field field in
11695 pr " %s_%s : %s;\n" name fname ftype
11696 ) (List.combine fields types);
11698 (* Return the name of this type, and
11699 * false because it's not a simple type.
11706 let generate_parsers xs =
11707 (* As for generate_type above, generate_parser makes a parser for
11708 * some type, and returns the name of the parser it has generated.
11709 * Because it (may) need to print something, it should always be
11710 * called in BOL context.
11712 let rec generate_parser = function
11713 | Text -> (* string *)
11714 "string_child_or_empty"
11715 | Choice values -> (* [`val1|`val2|...] *)
11716 sprintf "(fun x -> match Xml.pcdata (first_child x) with %s | str -> failwith (\"unexpected field value: \" ^ str))"
11718 (List.map (fun v -> sprintf "%S -> `%s" v v) values))
11719 | ZeroOrMore rng -> (* <rng> list *)
11720 let pa = generate_parser rng in
11721 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11722 | OneOrMore rng -> (* <rng> list *)
11723 let pa = generate_parser rng in
11724 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11725 (* virt-inspector hack: bool *)
11726 | Optional (Attribute (name, [Value "1"])) ->
11727 sprintf "(fun x -> try ignore (Xml.attrib x %S); true with Xml.No_attribute _ -> false)" name
11728 | Optional rng -> (* <rng> list *)
11729 let pa = generate_parser rng in
11730 sprintf "(function None -> None | Some x -> Some (%s x))" pa
11731 (* type name = { fields ... } *)
11732 | Element (name, fields) when is_attrs_interleave fields ->
11733 generate_parser_struct name (get_attrs_interleave fields)
11734 | Element (name, [field]) -> (* type name = field *)
11735 let pa = generate_parser field in
11736 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11737 pr "let %s =\n" parser_name;
11739 pr "let parse_%s = %s\n" name parser_name;
11741 | Attribute (name, [field]) ->
11742 let pa = generate_parser field in
11743 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11744 pr "let %s =\n" parser_name;
11746 pr "let parse_%s = %s\n" name parser_name;
11748 | Element (name, fields) -> (* type name = { fields ... } *)
11749 generate_parser_struct name ([], fields)
11751 failwithf "generate_parser failed at: %s" (string_of_rng rng)
11753 and is_attrs_interleave = function
11754 | [Interleave _] -> true
11755 | Attribute _ :: fields -> is_attrs_interleave fields
11756 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11759 and get_attrs_interleave = function
11760 | [Interleave fields] -> [], fields
11761 | ((Attribute _) as field) :: fields
11762 | ((Optional (Attribute _)) as field) :: fields ->
11763 let attrs, interleaves = get_attrs_interleave fields in
11764 (field :: attrs), interleaves
11765 | _ -> assert false
11767 and generate_parsers xs =
11768 List.iter (fun x -> ignore (generate_parser x)) xs
11770 and generate_parser_struct name (attrs, interleaves) =
11771 (* Generate parsers for the fields first. We have to do this
11772 * before printing anything so we are still in BOL context.
11774 let fields = attrs @ interleaves in
11775 let pas = List.map generate_parser fields in
11777 (* Generate an intermediate tuple from all the fields first.
11778 * If the type is just a string + another field, then we will
11779 * return this directly, otherwise it is turned into a record.
11781 * RELAX NG note: This code treats <interleave> and plain lists of
11782 * fields the same. In other words, it doesn't bother enforcing
11783 * any ordering of fields in the XML.
11785 pr "let parse_%s x =\n" name;
11786 pr " let t = (\n ";
11787 let comma = ref false in
11790 if !comma then pr ",\n ";
11793 | Optional (Attribute (fname, [field])), pa ->
11795 | Optional (Element (fname, [field])), pa ->
11796 pr "%s (optional_child %S x)" pa fname
11797 | Attribute (fname, [Text]), _ ->
11798 pr "attribute %S x" fname
11799 | (ZeroOrMore _ | OneOrMore _), pa ->
11804 let fname = name_of_field field in
11805 pr "%s (child %S x)" pa fname
11806 ) (List.combine fields pas);
11810 | [Element (_, [Text]) | Attribute (_, [Text]); _] ->
11814 pr " (Obj.magic t : %s)\n" name
11818 | (Optional (Attribute (fname, [field])), pa) ->
11819 pr " %s_%s =\n" name fname;
11821 | (Optional (Element (fname, [field])), pa) ->
11822 pr " %s_%s =\n" name fname;
11823 pr " (let x = optional_child %S x in\n" fname;
11826 let fname = name_of_field field in
11827 pr " %s_%s =\n" name fname;
11828 pr " (let x = child %S x in\n" fname;
11830 ) (List.combine fields pas);
11834 sprintf "parse_%s" name
11837 generate_parsers xs
11839 (* Generate ocaml/guestfs_inspector.mli. *)
11840 let generate_ocaml_inspector_mli () =
11841 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11844 (** This is an OCaml language binding to the external [virt-inspector]
11847 For more information, please read the man page [virt-inspector(1)].
11852 generate_types grammar;
11853 pr "(** The nested information returned from the {!inspect} function. *)\n";
11857 val inspect : ?connect:string -> ?xml:string -> string list -> operatingsystems
11858 (** To inspect a libvirt domain called [name], pass a singleton
11859 list: [inspect [name]]. When using libvirt only, you may
11860 optionally pass a libvirt URI using [inspect ~connect:uri ...].
11862 To inspect a disk image or images, pass a list of the filenames
11863 of the disk images: [inspect filenames]
11865 This function inspects the given guest or disk images and
11866 returns a list of operating system(s) found and a large amount
11867 of information about them. In the vast majority of cases,
11868 a virtual machine only contains a single operating system.
11870 If the optional [~xml] parameter is given, then this function
11871 skips running the external virt-inspector program and just
11872 parses the given XML directly (which is expected to be XML
11873 produced from a previous run of virt-inspector). The list of
11874 names and connect URI are ignored in this case.
11876 This function can throw a wide variety of exceptions, for example
11877 if the external virt-inspector program cannot be found, or if
11878 it doesn't generate valid XML.
11882 (* Generate ocaml/guestfs_inspector.ml. *)
11883 let generate_ocaml_inspector_ml () =
11884 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11889 generate_types grammar;
11893 (* Misc functions which are used by the parser code below. *)
11894 let first_child = function
11895 | Xml.Element (_, _, c::_) -> c
11896 | Xml.Element (name, _, []) ->
11897 failwith (\"expected <\" ^ name ^ \"/> to have a child node\")
11898 | Xml.PCData str ->
11899 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11901 let string_child_or_empty = function
11902 | Xml.Element (_, _, [Xml.PCData s]) -> s
11903 | Xml.Element (_, _, []) -> \"\"
11904 | Xml.Element (x, _, _) ->
11905 failwith (\"expected XML tag with a single PCDATA child, but got \" ^
11907 | Xml.PCData str ->
11908 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11910 let optional_child name xml =
11911 let children = Xml.children xml in
11913 Some (List.find (function
11914 | Xml.Element (n, _, _) when n = name -> true
11915 | _ -> false) children)
11919 let child name xml =
11920 match optional_child name xml with
11923 failwith (\"mandatory field <\" ^ name ^ \"/> missing in XML output\")
11925 let attribute name xml =
11926 try Xml.attrib xml name
11927 with Xml.No_attribute _ ->
11928 failwith (\"mandatory attribute \" ^ name ^ \" missing in XML output\")
11932 generate_parsers grammar;
11936 (* Run external virt-inspector, then use parser to parse the XML. *)
11937 let inspect ?connect ?xml names =
11941 if names = [] then invalid_arg \"inspect: no names given\";
11942 let cmd = [ \"virt-inspector\"; \"--xml\" ] @
11943 (match connect with None -> [] | Some uri -> [ \"--connect\"; uri ]) @
11945 let cmd = List.map Filename.quote cmd in
11946 let cmd = String.concat \" \" cmd in
11947 let chan = open_process_in cmd in
11948 let xml = Xml.parse_in chan in
11949 (match close_process_in chan with
11951 | WEXITED _ -> failwith \"external virt-inspector command failed\"
11952 | WSIGNALED i | WSTOPPED i ->
11953 failwith (\"external virt-inspector command died or stopped on sig \" ^
11958 Xml.parse_string doc in
11959 parse_operatingsystems xml
11962 and generate_max_proc_nr () =
11963 pr "%d\n" max_proc_nr
11965 let output_to filename k =
11966 let filename_new = filename ^ ".new" in
11967 chan := open_out filename_new;
11970 chan := Pervasives.stdout;
11972 (* Is the new file different from the current file? *)
11973 if Sys.file_exists filename && files_equal filename filename_new then
11974 unlink filename_new (* same, so skip it *)
11976 (* different, overwrite old one *)
11977 (try chmod filename 0o644 with Unix_error _ -> ());
11978 rename filename_new filename;
11979 chmod filename 0o444;
11980 printf "written %s\n%!" filename;
11983 let perror msg = function
11984 | Unix_error (err, _, _) ->
11985 eprintf "%s: %s\n" msg (error_message err)
11987 eprintf "%s: %s\n" msg (Printexc.to_string exn)
11989 (* Main program. *)
11992 try openfile "HACKING" [O_RDWR] 0
11994 | Unix_error (ENOENT, _, _) ->
11996 You are probably running this from the wrong directory.
11997 Run it from the top source directory using the command
12002 perror "open: HACKING" exn;
12005 (* Acquire a lock so parallel builds won't try to run the generator
12006 * twice at the same time. Subsequent builds will wait for the first
12007 * one to finish. Note the lock is released implicitly when the
12010 (try lockf lock_fd F_LOCK 1
12012 perror "lock: HACKING" exn;
12015 check_functions ();
12017 output_to "src/guestfs_protocol.x" generate_xdr;
12018 output_to "src/guestfs-structs.h" generate_structs_h;
12019 output_to "src/guestfs-actions.h" generate_actions_h;
12020 output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
12021 output_to "src/guestfs-actions.c" generate_client_actions;
12022 output_to "src/guestfs-bindtests.c" generate_bindtests;
12023 output_to "src/guestfs-structs.pod" generate_structs_pod;
12024 output_to "src/guestfs-actions.pod" generate_actions_pod;
12025 output_to "src/guestfs-availability.pod" generate_availability_pod;
12026 output_to "src/MAX_PROC_NR" generate_max_proc_nr;
12027 output_to "src/libguestfs.syms" generate_linker_script;
12028 output_to "daemon/actions.h" generate_daemon_actions_h;
12029 output_to "daemon/stubs.c" generate_daemon_actions;
12030 output_to "daemon/names.c" generate_daemon_names;
12031 output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
12032 output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
12033 output_to "capitests/tests.c" generate_tests;
12034 output_to "fish/cmds.c" generate_fish_cmds;
12035 output_to "fish/completion.c" generate_fish_completion;
12036 output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
12037 output_to "ocaml/guestfs.mli" generate_ocaml_mli;
12038 output_to "ocaml/guestfs.ml" generate_ocaml_ml;
12039 output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;
12040 output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
12041 output_to "ocaml/guestfs_inspector.mli" generate_ocaml_inspector_mli;
12042 output_to "ocaml/guestfs_inspector.ml" generate_ocaml_inspector_ml;
12043 output_to "perl/Guestfs.xs" generate_perl_xs;
12044 output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
12045 output_to "perl/bindtests.pl" generate_perl_bindtests;
12046 output_to "python/guestfs-py.c" generate_python_c;
12047 output_to "python/guestfs.py" generate_python_py;
12048 output_to "python/bindtests.py" generate_python_bindtests;
12049 output_to "ruby/ext/guestfs/_guestfs.c" generate_ruby_c;
12050 output_to "ruby/bindtests.rb" generate_ruby_bindtests;
12051 output_to "java/com/redhat/et/libguestfs/GuestFS.java" generate_java_java;
12055 let cols = cols_of_struct typ in
12056 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
12057 output_to filename (generate_java_struct jtyp cols);
12060 output_to "java/Makefile.inc" generate_java_makefile_inc;
12061 output_to "java/com_redhat_et_libguestfs_GuestFS.c" generate_java_c;
12062 output_to "java/Bindtests.java" generate_java_bindtests;
12063 output_to "haskell/Guestfs.hs" generate_haskell_hs;
12064 output_to "haskell/Bindtests.hs" generate_haskell_bindtests;
12065 output_to "csharp/Libguestfs.cs" generate_csharp;
12067 (* Always generate this file last, and unconditionally. It's used
12068 * by the Makefile to know when we must re-run the generator.
12070 let chan = open_out "src/stamp-generator" in
12071 fprintf chan "1\n";
12074 printf "generated %d lines of code\n" !lines