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 (* Run the test only if 'string' is available in the daemon. *)
313 | IfAvailable of string
315 (* Some initial scenarios for testing. *)
317 (* Do nothing, block devices could contain random stuff including
318 * LVM PVs, and some filesystems might be mounted. This is usually
323 (* Block devices are empty and no filesystems are mounted. *)
326 (* /dev/sda contains a single partition /dev/sda1, with random
327 * content. /dev/sdb and /dev/sdc may have random content.
332 (* /dev/sda contains a single partition /dev/sda1, which is formatted
333 * as ext2, empty [except for lost+found] and mounted on /.
334 * /dev/sdb and /dev/sdc may have random content.
340 * /dev/sda1 (is a PV):
341 * /dev/VG/LV (size 8MB):
342 * formatted as ext2, empty [except for lost+found], mounted on /
343 * /dev/sdb and /dev/sdc may have random content.
347 (* /dev/sdd (the ISO, see images/ directory in source)
352 (* Sequence of commands for testing. *)
354 and cmd = string list
356 (* Note about long descriptions: When referring to another
357 * action, use the format C<guestfs_other> (ie. the full name of
358 * the C function). This will be replaced as appropriate in other
361 * Apart from that, long descriptions are just perldoc paragraphs.
364 (* Generate a random UUID (used in tests). *)
366 let chan = open_process_in "uuidgen" in
367 let uuid = input_line chan in
368 (match close_process_in chan with
371 failwith "uuidgen: process exited with non-zero status"
372 | WSIGNALED _ | WSTOPPED _ ->
373 failwith "uuidgen: process signalled or stopped by signal"
377 (* These test functions are used in the language binding tests. *)
379 let test_all_args = [
382 StringList "strlist";
391 let test_all_rets = [
392 (* except for RErr, which is tested thoroughly elsewhere *)
393 "test0rint", RInt "valout";
394 "test0rint64", RInt64 "valout";
395 "test0rbool", RBool "valout";
396 "test0rconststring", RConstString "valout";
397 "test0rconstoptstring", RConstOptString "valout";
398 "test0rstring", RString "valout";
399 "test0rstringlist", RStringList "valout";
400 "test0rstruct", RStruct ("valout", "lvm_pv");
401 "test0rstructlist", RStructList ("valout", "lvm_pv");
402 "test0rhashtable", RHashtable "valout";
405 let test_functions = [
406 ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
408 "internal test function - do not use",
410 This is an internal test function which is used to test whether
411 the automatically generated bindings can handle every possible
412 parameter type correctly.
414 It echos the contents of each parameter to stdout.
416 You probably don't want to call this function.");
420 [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
422 "internal test function - do not use",
424 This is an internal test function which is used to test whether
425 the automatically generated bindings can handle every possible
426 return type correctly.
428 It converts string C<val> to the return type.
430 You probably don't want to call this function.");
431 (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
433 "internal test function - do not use",
435 This is an internal test function which is used to test whether
436 the automatically generated bindings can handle every possible
437 return type correctly.
439 This function always returns an error.
441 You probably don't want to call this function.")]
445 (* non_daemon_functions are any functions which don't get processed
446 * in the daemon, eg. functions for setting and getting local
447 * configuration values.
450 let non_daemon_functions = test_functions @ [
451 ("launch", (RErr, []), -1, [FishAlias "run"],
453 "launch the qemu subprocess",
455 Internally libguestfs is implemented by running a virtual machine
458 You should call this after configuring the handle
459 (eg. adding drives) but before performing any actions.");
461 ("wait_ready", (RErr, []), -1, [NotInFish],
463 "wait until the qemu subprocess launches (no op)",
465 This function is a no op.
467 In versions of the API E<lt> 1.0.71 you had to call this function
468 just after calling C<guestfs_launch> to wait for the launch
469 to complete. However this is no longer necessary because
470 C<guestfs_launch> now does the waiting.
472 If you see any calls to this function in code then you can just
473 remove them, unless you want to retain compatibility with older
474 versions of the API.");
476 ("kill_subprocess", (RErr, []), -1, [],
478 "kill the qemu subprocess",
480 This kills the qemu subprocess. You should never need to call this.");
482 ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
484 "add an image to examine or modify",
486 This function adds a virtual machine disk image C<filename> to the
487 guest. The first time you call this function, the disk appears as IDE
488 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
491 You don't necessarily need to be root when using libguestfs. However
492 you obviously do need sufficient permissions to access the filename
493 for whatever operations you want to perform (ie. read access if you
494 just want to read the image or write access if you want to modify the
497 This is equivalent to the qemu parameter
498 C<-drive file=filename,cache=off,if=...>.
500 C<cache=off> is omitted in cases where it is not supported by
501 the underlying filesystem.
503 C<if=...> is set at compile time by the configuration option
504 C<./configure --with-drive-if=...>. In the rare case where you
505 might need to change this at run time, use C<guestfs_add_drive_with_if>
506 or C<guestfs_add_drive_ro_with_if>.
508 Note that this call checks for the existence of C<filename>. This
509 stops you from specifying other types of drive which are supported
510 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
511 the general C<guestfs_config> call instead.");
513 ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
515 "add a CD-ROM disk image to examine",
517 This function adds a virtual CD-ROM disk image to the guest.
519 This is equivalent to the qemu parameter C<-cdrom filename>.
527 This call checks for the existence of C<filename>. This
528 stops you from specifying other types of drive which are supported
529 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
530 the general C<guestfs_config> call instead.
534 If you just want to add an ISO file (often you use this as an
535 efficient way to transfer large files into the guest), then you
536 should probably use C<guestfs_add_drive_ro> instead.
540 ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
542 "add a drive in snapshot mode (read-only)",
544 This adds a drive in snapshot mode, making it effectively
547 Note that writes to the device are allowed, and will be seen for
548 the duration of the guestfs handle, but they are written
549 to a temporary file which is discarded as soon as the guestfs
550 handle is closed. We don't currently have any method to enable
551 changes to be committed, although qemu can support this.
553 This is equivalent to the qemu parameter
554 C<-drive file=filename,snapshot=on,readonly=on,if=...>.
556 C<if=...> is set at compile time by the configuration option
557 C<./configure --with-drive-if=...>. In the rare case where you
558 might need to change this at run time, use C<guestfs_add_drive_with_if>
559 or C<guestfs_add_drive_ro_with_if>.
561 C<readonly=on> is only added where qemu supports this option.
563 Note that this call checks for the existence of C<filename>. This
564 stops you from specifying other types of drive which are supported
565 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
566 the general C<guestfs_config> call instead.");
568 ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
570 "add qemu parameters",
572 This can be used to add arbitrary qemu command line parameters
573 of the form C<-param value>. Actually it's not quite arbitrary - we
574 prevent you from setting some parameters which would interfere with
575 parameters that we use.
577 The first character of C<param> string must be a C<-> (dash).
579 C<value> can be NULL.");
581 ("set_qemu", (RErr, [OptString "qemu"]), -1, [FishAlias "qemu"],
583 "set the qemu binary",
585 Set the qemu binary that we will use.
587 The default is chosen when the library was compiled by the
590 You can also override this by setting the C<LIBGUESTFS_QEMU>
591 environment variable.
593 Setting C<qemu> to C<NULL> restores the default qemu binary.
595 Note that you should call this function as early as possible
596 after creating the handle. This is because some pre-launch
597 operations depend on testing qemu features (by running C<qemu -help>).
598 If the qemu binary changes, we don't retest features, and
599 so you might see inconsistent results. Using the environment
600 variable C<LIBGUESTFS_QEMU> is safest of all since that picks
601 the qemu binary at the same time as the handle is created.");
603 ("get_qemu", (RConstString "qemu", []), -1, [],
604 [InitNone, Always, TestRun (
606 "get the qemu binary",
608 Return the current qemu binary.
610 This is always non-NULL. If it wasn't set already, then this will
611 return the default qemu binary name.");
613 ("set_path", (RErr, [OptString "searchpath"]), -1, [FishAlias "path"],
615 "set the search path",
617 Set the path that libguestfs searches for kernel and initrd.img.
619 The default is C<$libdir/guestfs> unless overridden by setting
620 C<LIBGUESTFS_PATH> environment variable.
622 Setting C<path> to C<NULL> restores the default path.");
624 ("get_path", (RConstString "path", []), -1, [],
625 [InitNone, Always, TestRun (
627 "get the search path",
629 Return the current search path.
631 This is always non-NULL. If it wasn't set already, then this will
632 return the default path.");
634 ("set_append", (RErr, [OptString "append"]), -1, [FishAlias "append"],
636 "add options to kernel command line",
638 This function is used to add additional options to the
639 guest kernel command line.
641 The default is C<NULL> unless overridden by setting
642 C<LIBGUESTFS_APPEND> environment variable.
644 Setting C<append> to C<NULL> means I<no> additional options
645 are passed (libguestfs always adds a few of its own).");
647 ("get_append", (RConstOptString "append", []), -1, [],
648 (* This cannot be tested with the current framework. The
649 * function can return NULL in normal operations, which the
650 * test framework interprets as an error.
653 "get the additional kernel options",
655 Return the additional kernel options which are added to the
656 guest kernel command line.
658 If C<NULL> then no options are added.");
660 ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
664 If C<autosync> is true, this enables autosync. Libguestfs will make a
665 best effort attempt to run C<guestfs_umount_all> followed by
666 C<guestfs_sync> when the handle is closed
667 (also if the program exits without closing handles).
669 This is disabled by default (except in guestfish where it is
670 enabled by default).");
672 ("get_autosync", (RBool "autosync", []), -1, [],
673 [InitNone, Always, TestRun (
674 [["get_autosync"]])],
677 Get the autosync flag.");
679 ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
683 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
685 Verbose messages are disabled unless the environment variable
686 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
688 ("get_verbose", (RBool "verbose", []), -1, [],
692 This returns the verbose messages flag.");
694 ("is_ready", (RBool "ready", []), -1, [],
695 [InitNone, Always, TestOutputTrue (
697 "is ready to accept commands",
699 This returns true iff this handle is ready to accept commands
700 (in the C<READY> state).
702 For more information on states, see L<guestfs(3)>.");
704 ("is_config", (RBool "config", []), -1, [],
705 [InitNone, Always, TestOutputFalse (
707 "is in configuration state",
709 This returns true iff this handle is being configured
710 (in the C<CONFIG> state).
712 For more information on states, see L<guestfs(3)>.");
714 ("is_launching", (RBool "launching", []), -1, [],
715 [InitNone, Always, TestOutputFalse (
716 [["is_launching"]])],
717 "is launching subprocess",
719 This returns true iff this handle is launching the subprocess
720 (in the C<LAUNCHING> state).
722 For more information on states, see L<guestfs(3)>.");
724 ("is_busy", (RBool "busy", []), -1, [],
725 [InitNone, Always, TestOutputFalse (
727 "is busy processing a command",
729 This returns true iff this handle is busy processing a command
730 (in the C<BUSY> state).
732 For more information on states, see L<guestfs(3)>.");
734 ("get_state", (RInt "state", []), -1, [],
736 "get the current state",
738 This returns the current state as an opaque integer. This is
739 only useful for printing debug and internal error messages.
741 For more information on states, see L<guestfs(3)>.");
743 ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
744 [InitNone, Always, TestOutputInt (
745 [["set_memsize"; "500"];
746 ["get_memsize"]], 500)],
747 "set memory allocated to the qemu subprocess",
749 This sets the memory size in megabytes allocated to the
750 qemu subprocess. This only has any effect if called before
753 You can also change this by setting the environment
754 variable C<LIBGUESTFS_MEMSIZE> before the handle is
757 For more information on the architecture of libguestfs,
758 see L<guestfs(3)>.");
760 ("get_memsize", (RInt "memsize", []), -1, [],
761 [InitNone, Always, TestOutputIntOp (
762 [["get_memsize"]], ">=", 256)],
763 "get memory allocated to the qemu subprocess",
765 This gets the memory size in megabytes allocated to the
768 If C<guestfs_set_memsize> was not called
769 on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
770 then this returns the compiled-in default value for memsize.
772 For more information on the architecture of libguestfs,
773 see L<guestfs(3)>.");
775 ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"],
776 [InitNone, Always, TestOutputIntOp (
777 [["get_pid"]], ">=", 1)],
778 "get PID of qemu subprocess",
780 Return the process ID of the qemu subprocess. If there is no
781 qemu subprocess, then this will return an error.
783 This is an internal call used for debugging and testing.");
785 ("version", (RStruct ("version", "version"), []), -1, [],
786 [InitNone, Always, TestOutputStruct (
787 [["version"]], [CompareWithInt ("major", 1)])],
788 "get the library version number",
790 Return the libguestfs version number that the program is linked
793 Note that because of dynamic linking this is not necessarily
794 the version of libguestfs that you compiled against. You can
795 compile the program, and then at runtime dynamically link
796 against a completely different C<libguestfs.so> library.
798 This call was added in version C<1.0.58>. In previous
799 versions of libguestfs there was no way to get the version
800 number. From C code you can use dynamic linker functions
801 to find out if this symbol exists (if it doesn't, then
802 it's an earlier version).
804 The call returns a structure with four elements. The first
805 three (C<major>, C<minor> and C<release>) are numbers and
806 correspond to the usual version triplet. The fourth element
807 (C<extra>) is a string and is normally empty, but may be
808 used for distro-specific information.
810 To construct the original version string:
811 C<$major.$minor.$release$extra>
813 See also: L<guestfs(3)/LIBGUESTFS VERSION NUMBERS>.
815 I<Note:> Don't use this call to test for availability
816 of features. In enterprise distributions we backport
817 features from later versions into earlier versions,
818 making this an unreliable way to test for features.
819 Use C<guestfs_available> instead.");
821 ("set_selinux", (RErr, [Bool "selinux"]), -1, [FishAlias "selinux"],
822 [InitNone, Always, TestOutputTrue (
823 [["set_selinux"; "true"];
825 "set SELinux enabled or disabled at appliance boot",
827 This sets the selinux flag that is passed to the appliance
828 at boot time. The default is C<selinux=0> (disabled).
830 Note that if SELinux is enabled, it is always in
831 Permissive mode (C<enforcing=0>).
833 For more information on the architecture of libguestfs,
834 see L<guestfs(3)>.");
836 ("get_selinux", (RBool "selinux", []), -1, [],
838 "get SELinux enabled flag",
840 This returns the current setting of the selinux flag which
841 is passed to the appliance at boot time. See C<guestfs_set_selinux>.
843 For more information on the architecture of libguestfs,
844 see L<guestfs(3)>.");
846 ("set_trace", (RErr, [Bool "trace"]), -1, [FishAlias "trace"],
847 [InitNone, Always, TestOutputFalse (
848 [["set_trace"; "false"];
850 "enable or disable command traces",
852 If the command trace flag is set to 1, then commands are
853 printed on stdout before they are executed in a format
854 which is very similar to the one used by guestfish. In
855 other words, you can run a program with this enabled, and
856 you will get out a script which you can feed to guestfish
857 to perform the same set of actions.
859 If you want to trace C API calls into libguestfs (and
860 other libraries) then possibly a better way is to use
861 the external ltrace(1) command.
863 Command traces are disabled unless the environment variable
864 C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
866 ("get_trace", (RBool "trace", []), -1, [],
868 "get command trace enabled flag",
870 Return the command trace flag.");
872 ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"],
873 [InitNone, Always, TestOutputFalse (
874 [["set_direct"; "false"];
876 "enable or disable direct appliance mode",
878 If the direct appliance mode flag is enabled, then stdin and
879 stdout are passed directly through to the appliance once it
882 One consequence of this is that log messages aren't caught
883 by the library and handled by C<guestfs_set_log_message_callback>,
884 but go straight to stdout.
886 You probably don't want to use this unless you know what you
889 The default is disabled.");
891 ("get_direct", (RBool "direct", []), -1, [],
893 "get direct appliance mode flag",
895 Return the direct appliance mode flag.");
897 ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"],
898 [InitNone, Always, TestOutputTrue (
899 [["set_recovery_proc"; "true"];
900 ["get_recovery_proc"]])],
901 "enable or disable the recovery process",
903 If this is called with the parameter C<false> then
904 C<guestfs_launch> does not create a recovery process. The
905 purpose of the recovery process is to stop runaway qemu
906 processes in the case where the main program aborts abruptly.
908 This only has any effect if called before C<guestfs_launch>,
909 and the default is true.
911 About the only time when you would want to disable this is
912 if the main process will fork itself into the background
913 (\"daemonize\" itself). In this case the recovery process
914 thinks that the main program has disappeared and so kills
915 qemu, which is not very helpful.");
917 ("get_recovery_proc", (RBool "recoveryproc", []), -1, [],
919 "get recovery process enabled flag",
921 Return the recovery process enabled flag.");
923 ("add_drive_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
925 "add a drive specifying the QEMU block emulation to use",
927 This is the same as C<guestfs_add_drive> but it allows you
928 to specify the QEMU interface emulation to use at run time.");
930 ("add_drive_ro_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
932 "add a drive read-only specifying the QEMU block emulation to use",
934 This is the same as C<guestfs_add_drive_ro> but it allows you
935 to specify the QEMU interface emulation to use at run time.");
939 (* daemon_functions are any functions which cause some action
940 * to take place in the daemon.
943 let daemon_functions = [
944 ("mount", (RErr, [Device "device"; String "mountpoint"]), 1, [],
945 [InitEmpty, Always, TestOutput (
946 [["part_disk"; "/dev/sda"; "mbr"];
947 ["mkfs"; "ext2"; "/dev/sda1"];
948 ["mount"; "/dev/sda1"; "/"];
949 ["write"; "/new"; "new file contents"];
950 ["cat"; "/new"]], "new file contents")],
951 "mount a guest disk at a position in the filesystem",
953 Mount a guest disk at a position in the filesystem. Block devices
954 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
955 the guest. If those block devices contain partitions, they will have
956 the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style
959 The rules are the same as for L<mount(2)>: A filesystem must
960 first be mounted on C</> before others can be mounted. Other
961 filesystems can only be mounted on directories which already
964 The mounted filesystem is writable, if we have sufficient permissions
965 on the underlying device.
968 When you use this call, the filesystem options C<sync> and C<noatime>
969 are set implicitly. This was originally done because we thought it
970 would improve reliability, but it turns out that I<-o sync> has a
971 very large negative performance impact and negligible effect on
972 reliability. Therefore we recommend that you avoid using
973 C<guestfs_mount> in any code that needs performance, and instead
974 use C<guestfs_mount_options> (use an empty string for the first
975 parameter if you don't want any options).");
977 ("sync", (RErr, []), 2, [],
978 [ InitEmpty, Always, TestRun [["sync"]]],
979 "sync disks, writes are flushed through to the disk image",
981 This syncs the disk, so that any writes are flushed through to the
982 underlying disk image.
984 You should always call this if you have modified a disk image, before
985 closing the handle.");
987 ("touch", (RErr, [Pathname "path"]), 3, [],
988 [InitBasicFS, Always, TestOutputTrue (
990 ["exists"; "/new"]])],
991 "update file timestamps or create a new file",
993 Touch acts like the L<touch(1)> command. It can be used to
994 update the timestamps on a file, or, if the file does not exist,
995 to create a new zero-length file.");
997 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
998 [InitISOFS, Always, TestOutput (
999 [["cat"; "/known-2"]], "abcdef\n")],
1000 "list the contents of a file",
1002 Return the contents of the file named C<path>.
1004 Note that this function cannot correctly handle binary files
1005 (specifically, files containing C<\\0> character which is treated
1006 as end of string). For those you need to use the C<guestfs_read_file>
1007 or C<guestfs_download> functions which have a more complex interface.");
1009 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
1010 [], (* XXX Tricky to test because it depends on the exact format
1011 * of the 'ls -l' command, which changes between F10 and F11.
1013 "list the files in a directory (long format)",
1015 List the files in C<directory> (relative to the root directory,
1016 there is no cwd) in the format of 'ls -la'.
1018 This command is mostly useful for interactive sessions. It
1019 is I<not> intended that you try to parse the output string.");
1021 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
1022 [InitBasicFS, Always, TestOutputList (
1024 ["touch"; "/newer"];
1025 ["touch"; "/newest"];
1026 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
1027 "list the files in a directory",
1029 List the files in C<directory> (relative to the root directory,
1030 there is no cwd). The '.' and '..' entries are not returned, but
1031 hidden files are shown.
1033 This command is mostly useful for interactive sessions. Programs
1034 should probably use C<guestfs_readdir> instead.");
1036 ("list_devices", (RStringList "devices", []), 7, [],
1037 [InitEmpty, Always, TestOutputListOfDevices (
1038 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
1039 "list the block devices",
1041 List all the block devices.
1043 The full block device names are returned, eg. C</dev/sda>");
1045 ("list_partitions", (RStringList "partitions", []), 8, [],
1046 [InitBasicFS, Always, TestOutputListOfDevices (
1047 [["list_partitions"]], ["/dev/sda1"]);
1048 InitEmpty, Always, TestOutputListOfDevices (
1049 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1050 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1051 "list the partitions",
1053 List all the partitions detected on all block devices.
1055 The full partition device names are returned, eg. C</dev/sda1>
1057 This does not return logical volumes. For that you will need to
1058 call C<guestfs_lvs>.");
1060 ("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
1061 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
1062 [["pvs"]], ["/dev/sda1"]);
1063 InitEmpty, Always, TestOutputListOfDevices (
1064 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1065 ["pvcreate"; "/dev/sda1"];
1066 ["pvcreate"; "/dev/sda2"];
1067 ["pvcreate"; "/dev/sda3"];
1068 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1069 "list the LVM physical volumes (PVs)",
1071 List all the physical volumes detected. This is the equivalent
1072 of the L<pvs(8)> command.
1074 This returns a list of just the device names that contain
1075 PVs (eg. C</dev/sda2>).
1077 See also C<guestfs_pvs_full>.");
1079 ("vgs", (RStringList "volgroups", []), 10, [Optional "lvm2"],
1080 [InitBasicFSonLVM, Always, TestOutputList (
1082 InitEmpty, Always, TestOutputList (
1083 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1084 ["pvcreate"; "/dev/sda1"];
1085 ["pvcreate"; "/dev/sda2"];
1086 ["pvcreate"; "/dev/sda3"];
1087 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1088 ["vgcreate"; "VG2"; "/dev/sda3"];
1089 ["vgs"]], ["VG1"; "VG2"])],
1090 "list the LVM volume groups (VGs)",
1092 List all the volumes groups detected. This is the equivalent
1093 of the L<vgs(8)> command.
1095 This returns a list of just the volume group names that were
1096 detected (eg. C<VolGroup00>).
1098 See also C<guestfs_vgs_full>.");
1100 ("lvs", (RStringList "logvols", []), 11, [Optional "lvm2"],
1101 [InitBasicFSonLVM, Always, TestOutputList (
1102 [["lvs"]], ["/dev/VG/LV"]);
1103 InitEmpty, Always, TestOutputList (
1104 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1105 ["pvcreate"; "/dev/sda1"];
1106 ["pvcreate"; "/dev/sda2"];
1107 ["pvcreate"; "/dev/sda3"];
1108 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1109 ["vgcreate"; "VG2"; "/dev/sda3"];
1110 ["lvcreate"; "LV1"; "VG1"; "50"];
1111 ["lvcreate"; "LV2"; "VG1"; "50"];
1112 ["lvcreate"; "LV3"; "VG2"; "50"];
1113 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1114 "list the LVM logical volumes (LVs)",
1116 List all the logical volumes detected. This is the equivalent
1117 of the L<lvs(8)> command.
1119 This returns a list of the logical volume device names
1120 (eg. C</dev/VolGroup00/LogVol00>).
1122 See also C<guestfs_lvs_full>.");
1124 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
1125 [], (* XXX how to test? *)
1126 "list the LVM physical volumes (PVs)",
1128 List all the physical volumes detected. This is the equivalent
1129 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1131 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [Optional "lvm2"],
1132 [], (* XXX how to test? *)
1133 "list the LVM volume groups (VGs)",
1135 List all the volumes groups detected. This is the equivalent
1136 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1138 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [Optional "lvm2"],
1139 [], (* XXX how to test? *)
1140 "list the LVM logical volumes (LVs)",
1142 List all the logical volumes detected. This is the equivalent
1143 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1145 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1146 [InitISOFS, Always, TestOutputList (
1147 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1148 InitISOFS, Always, TestOutputList (
1149 [["read_lines"; "/empty"]], [])],
1150 "read file as lines",
1152 Return the contents of the file named C<path>.
1154 The file contents are returned as a list of lines. Trailing
1155 C<LF> and C<CRLF> character sequences are I<not> returned.
1157 Note that this function cannot correctly handle binary files
1158 (specifically, files containing C<\\0> character which is treated
1159 as end of line). For those you need to use the C<guestfs_read_file>
1160 function which has a more complex interface.");
1162 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [Optional "augeas"],
1163 [], (* XXX Augeas code needs tests. *)
1164 "create a new Augeas handle",
1166 Create a new Augeas handle for editing configuration files.
1167 If there was any previous Augeas handle associated with this
1168 guestfs session, then it is closed.
1170 You must call this before using any other C<guestfs_aug_*>
1173 C<root> is the filesystem root. C<root> must not be NULL,
1176 The flags are the same as the flags defined in
1177 E<lt>augeas.hE<gt>, the logical I<or> of the following
1182 =item C<AUG_SAVE_BACKUP> = 1
1184 Keep the original file with a C<.augsave> extension.
1186 =item C<AUG_SAVE_NEWFILE> = 2
1188 Save changes into a file with extension C<.augnew>, and
1189 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1191 =item C<AUG_TYPE_CHECK> = 4
1193 Typecheck lenses (can be expensive).
1195 =item C<AUG_NO_STDINC> = 8
1197 Do not use standard load path for modules.
1199 =item C<AUG_SAVE_NOOP> = 16
1201 Make save a no-op, just record what would have been changed.
1203 =item C<AUG_NO_LOAD> = 32
1205 Do not load the tree in C<guestfs_aug_init>.
1209 To close the handle, you can call C<guestfs_aug_close>.
1211 To find out more about Augeas, see L<http://augeas.net/>.");
1213 ("aug_close", (RErr, []), 26, [Optional "augeas"],
1214 [], (* XXX Augeas code needs tests. *)
1215 "close the current Augeas handle",
1217 Close the current Augeas handle and free up any resources
1218 used by it. After calling this, you have to call
1219 C<guestfs_aug_init> again before you can use any other
1220 Augeas functions.");
1222 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [Optional "augeas"],
1223 [], (* XXX Augeas code needs tests. *)
1224 "define an Augeas variable",
1226 Defines an Augeas variable C<name> whose value is the result
1227 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1230 On success this returns the number of nodes in C<expr>, or
1231 C<0> if C<expr> evaluates to something which is not a nodeset.");
1233 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [Optional "augeas"],
1234 [], (* XXX Augeas code needs tests. *)
1235 "define an Augeas node",
1237 Defines a variable C<name> whose value is the result of
1240 If C<expr> evaluates to an empty nodeset, a node is created,
1241 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1242 C<name> will be the nodeset containing that single node.
1244 On success this returns a pair containing the
1245 number of nodes in the nodeset, and a boolean flag
1246 if a node was created.");
1248 ("aug_get", (RString "val", [String "augpath"]), 19, [Optional "augeas"],
1249 [], (* XXX Augeas code needs tests. *)
1250 "look up the value of an Augeas path",
1252 Look up the value associated with C<path>. If C<path>
1253 matches exactly one node, the C<value> is returned.");
1255 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [Optional "augeas"],
1256 [], (* XXX Augeas code needs tests. *)
1257 "set Augeas path to value",
1259 Set the value associated with C<path> to C<val>.
1261 In the Augeas API, it is possible to clear a node by setting
1262 the value to NULL. Due to an oversight in the libguestfs API
1263 you cannot do that with this call. Instead you must use the
1264 C<guestfs_aug_clear> call.");
1266 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [Optional "augeas"],
1267 [], (* XXX Augeas code needs tests. *)
1268 "insert a sibling Augeas node",
1270 Create a new sibling C<label> for C<path>, inserting it into
1271 the tree before or after C<path> (depending on the boolean
1274 C<path> must match exactly one existing node in the tree, and
1275 C<label> must be a label, ie. not contain C</>, C<*> or end
1276 with a bracketed index C<[N]>.");
1278 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [Optional "augeas"],
1279 [], (* XXX Augeas code needs tests. *)
1280 "remove an Augeas path",
1282 Remove C<path> and all of its children.
1284 On success this returns the number of entries which were removed.");
1286 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [Optional "augeas"],
1287 [], (* XXX Augeas code needs tests. *)
1290 Move the node C<src> to C<dest>. C<src> must match exactly
1291 one node. C<dest> is overwritten if it exists.");
1293 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [Optional "augeas"],
1294 [], (* XXX Augeas code needs tests. *)
1295 "return Augeas nodes which match augpath",
1297 Returns a list of paths which match the path expression C<path>.
1298 The returned paths are sufficiently qualified so that they match
1299 exactly one node in the current tree.");
1301 ("aug_save", (RErr, []), 25, [Optional "augeas"],
1302 [], (* XXX Augeas code needs tests. *)
1303 "write all pending Augeas changes to disk",
1305 This writes all pending changes to disk.
1307 The flags which were passed to C<guestfs_aug_init> affect exactly
1308 how files are saved.");
1310 ("aug_load", (RErr, []), 27, [Optional "augeas"],
1311 [], (* XXX Augeas code needs tests. *)
1312 "load files into the tree",
1314 Load files into the tree.
1316 See C<aug_load> in the Augeas documentation for the full gory
1319 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [Optional "augeas"],
1320 [], (* XXX Augeas code needs tests. *)
1321 "list Augeas nodes under augpath",
1323 This is just a shortcut for listing C<guestfs_aug_match>
1324 C<path/*> and sorting the resulting nodes into alphabetical order.");
1326 ("rm", (RErr, [Pathname "path"]), 29, [],
1327 [InitBasicFS, Always, TestRun
1330 InitBasicFS, Always, TestLastFail
1332 InitBasicFS, Always, TestLastFail
1337 Remove the single file C<path>.");
1339 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1340 [InitBasicFS, Always, TestRun
1343 InitBasicFS, Always, TestLastFail
1344 [["rmdir"; "/new"]];
1345 InitBasicFS, Always, TestLastFail
1347 ["rmdir"; "/new"]]],
1348 "remove a directory",
1350 Remove the single directory C<path>.");
1352 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1353 [InitBasicFS, Always, TestOutputFalse
1355 ["mkdir"; "/new/foo"];
1356 ["touch"; "/new/foo/bar"];
1358 ["exists"; "/new"]]],
1359 "remove a file or directory recursively",
1361 Remove the file or directory C<path>, recursively removing the
1362 contents if its a directory. This is like the C<rm -rf> shell
1365 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1366 [InitBasicFS, Always, TestOutputTrue
1368 ["is_dir"; "/new"]];
1369 InitBasicFS, Always, TestLastFail
1370 [["mkdir"; "/new/foo/bar"]]],
1371 "create a directory",
1373 Create a directory named C<path>.");
1375 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1376 [InitBasicFS, Always, TestOutputTrue
1377 [["mkdir_p"; "/new/foo/bar"];
1378 ["is_dir"; "/new/foo/bar"]];
1379 InitBasicFS, Always, TestOutputTrue
1380 [["mkdir_p"; "/new/foo/bar"];
1381 ["is_dir"; "/new/foo"]];
1382 InitBasicFS, Always, TestOutputTrue
1383 [["mkdir_p"; "/new/foo/bar"];
1384 ["is_dir"; "/new"]];
1385 (* Regression tests for RHBZ#503133: *)
1386 InitBasicFS, Always, TestRun
1388 ["mkdir_p"; "/new"]];
1389 InitBasicFS, Always, TestLastFail
1391 ["mkdir_p"; "/new"]]],
1392 "create a directory and parents",
1394 Create a directory named C<path>, creating any parent directories
1395 as necessary. This is like the C<mkdir -p> shell command.");
1397 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1398 [], (* XXX Need stat command to test *)
1401 Change the mode (permissions) of C<path> to C<mode>. Only
1402 numeric modes are supported.
1404 I<Note>: When using this command from guestfish, C<mode>
1405 by default would be decimal, unless you prefix it with
1406 C<0> to get octal, ie. use C<0700> not C<700>.
1408 The mode actually set is affected by the umask.");
1410 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1411 [], (* XXX Need stat command to test *)
1412 "change file owner and group",
1414 Change the file owner to C<owner> and group to C<group>.
1416 Only numeric uid and gid are supported. If you want to use
1417 names, you will need to locate and parse the password file
1418 yourself (Augeas support makes this relatively easy).");
1420 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1421 [InitISOFS, Always, TestOutputTrue (
1422 [["exists"; "/empty"]]);
1423 InitISOFS, Always, TestOutputTrue (
1424 [["exists"; "/directory"]])],
1425 "test if file or directory exists",
1427 This returns C<true> if and only if there is a file, directory
1428 (or anything) with the given C<path> name.
1430 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1432 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1433 [InitISOFS, Always, TestOutputTrue (
1434 [["is_file"; "/known-1"]]);
1435 InitISOFS, Always, TestOutputFalse (
1436 [["is_file"; "/directory"]])],
1437 "test if file exists",
1439 This returns C<true> if and only if there is a file
1440 with the given C<path> name. Note that it returns false for
1441 other objects like directories.
1443 See also C<guestfs_stat>.");
1445 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1446 [InitISOFS, Always, TestOutputFalse (
1447 [["is_dir"; "/known-3"]]);
1448 InitISOFS, Always, TestOutputTrue (
1449 [["is_dir"; "/directory"]])],
1450 "test if file exists",
1452 This returns C<true> if and only if there is a directory
1453 with the given C<path> name. Note that it returns false for
1454 other objects like files.
1456 See also C<guestfs_stat>.");
1458 ("pvcreate", (RErr, [Device "device"]), 39, [Optional "lvm2"],
1459 [InitEmpty, Always, TestOutputListOfDevices (
1460 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1461 ["pvcreate"; "/dev/sda1"];
1462 ["pvcreate"; "/dev/sda2"];
1463 ["pvcreate"; "/dev/sda3"];
1464 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1465 "create an LVM physical volume",
1467 This creates an LVM physical volume on the named C<device>,
1468 where C<device> should usually be a partition name such
1471 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [Optional "lvm2"],
1472 [InitEmpty, Always, TestOutputList (
1473 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1474 ["pvcreate"; "/dev/sda1"];
1475 ["pvcreate"; "/dev/sda2"];
1476 ["pvcreate"; "/dev/sda3"];
1477 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1478 ["vgcreate"; "VG2"; "/dev/sda3"];
1479 ["vgs"]], ["VG1"; "VG2"])],
1480 "create an LVM volume group",
1482 This creates an LVM volume group called C<volgroup>
1483 from the non-empty list of physical volumes C<physvols>.");
1485 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [Optional "lvm2"],
1486 [InitEmpty, Always, TestOutputList (
1487 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1488 ["pvcreate"; "/dev/sda1"];
1489 ["pvcreate"; "/dev/sda2"];
1490 ["pvcreate"; "/dev/sda3"];
1491 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1492 ["vgcreate"; "VG2"; "/dev/sda3"];
1493 ["lvcreate"; "LV1"; "VG1"; "50"];
1494 ["lvcreate"; "LV2"; "VG1"; "50"];
1495 ["lvcreate"; "LV3"; "VG2"; "50"];
1496 ["lvcreate"; "LV4"; "VG2"; "50"];
1497 ["lvcreate"; "LV5"; "VG2"; "50"];
1499 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1500 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1501 "create an LVM logical volume",
1503 This creates an LVM logical volume called C<logvol>
1504 on the volume group C<volgroup>, with C<size> megabytes.");
1506 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1507 [InitEmpty, Always, TestOutput (
1508 [["part_disk"; "/dev/sda"; "mbr"];
1509 ["mkfs"; "ext2"; "/dev/sda1"];
1510 ["mount_options"; ""; "/dev/sda1"; "/"];
1511 ["write"; "/new"; "new file contents"];
1512 ["cat"; "/new"]], "new file contents")],
1513 "make a filesystem",
1515 This creates a filesystem on C<device> (usually a partition
1516 or LVM logical volume). The filesystem type is C<fstype>, for
1519 ("sfdisk", (RErr, [Device "device";
1520 Int "cyls"; Int "heads"; Int "sectors";
1521 StringList "lines"]), 43, [DangerWillRobinson],
1523 "create partitions on a block device",
1525 This is a direct interface to the L<sfdisk(8)> program for creating
1526 partitions on block devices.
1528 C<device> should be a block device, for example C</dev/sda>.
1530 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1531 and sectors on the device, which are passed directly to sfdisk as
1532 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1533 of these, then the corresponding parameter is omitted. Usually for
1534 'large' disks, you can just pass C<0> for these, but for small
1535 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1536 out the right geometry and you will need to tell it.
1538 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1539 information refer to the L<sfdisk(8)> manpage.
1541 To create a single partition occupying the whole disk, you would
1542 pass C<lines> as a single element list, when the single element being
1543 the string C<,> (comma).
1545 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1546 C<guestfs_part_init>");
1548 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning; DeprecatedBy "write"],
1549 (* Regression test for RHBZ#597135. *)
1550 [InitBasicFS, Always, TestLastFail
1551 [["write_file"; "/new"; "abc"; "10000"]]],
1554 This call creates a file called C<path>. The contents of the
1555 file is the string C<content> (which can contain any 8 bit data),
1556 with length C<size>.
1558 As a special case, if C<size> is C<0>
1559 then the length is calculated using C<strlen> (so in this case
1560 the content cannot contain embedded ASCII NULs).
1562 I<NB.> Owing to a bug, writing content containing ASCII NUL
1563 characters does I<not> work, even if the length is specified.");
1565 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1566 [InitEmpty, Always, TestOutputListOfDevices (
1567 [["part_disk"; "/dev/sda"; "mbr"];
1568 ["mkfs"; "ext2"; "/dev/sda1"];
1569 ["mount_options"; ""; "/dev/sda1"; "/"];
1570 ["mounts"]], ["/dev/sda1"]);
1571 InitEmpty, Always, TestOutputList (
1572 [["part_disk"; "/dev/sda"; "mbr"];
1573 ["mkfs"; "ext2"; "/dev/sda1"];
1574 ["mount_options"; ""; "/dev/sda1"; "/"];
1577 "unmount a filesystem",
1579 This unmounts the given filesystem. The filesystem may be
1580 specified either by its mountpoint (path) or the device which
1581 contains the filesystem.");
1583 ("mounts", (RStringList "devices", []), 46, [],
1584 [InitBasicFS, Always, TestOutputListOfDevices (
1585 [["mounts"]], ["/dev/sda1"])],
1586 "show mounted filesystems",
1588 This returns the list of currently mounted filesystems. It returns
1589 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1591 Some internal mounts are not shown.
1593 See also: C<guestfs_mountpoints>");
1595 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1596 [InitBasicFS, Always, TestOutputList (
1599 (* check that umount_all can unmount nested mounts correctly: *)
1600 InitEmpty, Always, TestOutputList (
1601 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1602 ["mkfs"; "ext2"; "/dev/sda1"];
1603 ["mkfs"; "ext2"; "/dev/sda2"];
1604 ["mkfs"; "ext2"; "/dev/sda3"];
1605 ["mount_options"; ""; "/dev/sda1"; "/"];
1607 ["mount_options"; ""; "/dev/sda2"; "/mp1"];
1608 ["mkdir"; "/mp1/mp2"];
1609 ["mount_options"; ""; "/dev/sda3"; "/mp1/mp2"];
1610 ["mkdir"; "/mp1/mp2/mp3"];
1613 "unmount all filesystems",
1615 This unmounts all mounted filesystems.
1617 Some internal mounts are not unmounted by this call.");
1619 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson; Optional "lvm2"],
1621 "remove all LVM LVs, VGs and PVs",
1623 This command removes all LVM logical volumes, volume groups
1624 and physical volumes.");
1626 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1627 [InitISOFS, Always, TestOutput (
1628 [["file"; "/empty"]], "empty");
1629 InitISOFS, Always, TestOutput (
1630 [["file"; "/known-1"]], "ASCII text");
1631 InitISOFS, Always, TestLastFail (
1632 [["file"; "/notexists"]])],
1633 "determine file type",
1635 This call uses the standard L<file(1)> command to determine
1636 the type or contents of the file. This also works on devices,
1637 for example to find out whether a partition contains a filesystem.
1639 This call will also transparently look inside various types
1642 The exact command which runs is C<file -zbsL path>. Note in
1643 particular that the filename is not prepended to the output
1644 (the C<-b> option).");
1646 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1647 [InitBasicFS, Always, TestOutput (
1648 [["upload"; "test-command"; "/test-command"];
1649 ["chmod"; "0o755"; "/test-command"];
1650 ["command"; "/test-command 1"]], "Result1");
1651 InitBasicFS, Always, TestOutput (
1652 [["upload"; "test-command"; "/test-command"];
1653 ["chmod"; "0o755"; "/test-command"];
1654 ["command"; "/test-command 2"]], "Result2\n");
1655 InitBasicFS, Always, TestOutput (
1656 [["upload"; "test-command"; "/test-command"];
1657 ["chmod"; "0o755"; "/test-command"];
1658 ["command"; "/test-command 3"]], "\nResult3");
1659 InitBasicFS, Always, TestOutput (
1660 [["upload"; "test-command"; "/test-command"];
1661 ["chmod"; "0o755"; "/test-command"];
1662 ["command"; "/test-command 4"]], "\nResult4\n");
1663 InitBasicFS, Always, TestOutput (
1664 [["upload"; "test-command"; "/test-command"];
1665 ["chmod"; "0o755"; "/test-command"];
1666 ["command"; "/test-command 5"]], "\nResult5\n\n");
1667 InitBasicFS, Always, TestOutput (
1668 [["upload"; "test-command"; "/test-command"];
1669 ["chmod"; "0o755"; "/test-command"];
1670 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1671 InitBasicFS, Always, TestOutput (
1672 [["upload"; "test-command"; "/test-command"];
1673 ["chmod"; "0o755"; "/test-command"];
1674 ["command"; "/test-command 7"]], "");
1675 InitBasicFS, Always, TestOutput (
1676 [["upload"; "test-command"; "/test-command"];
1677 ["chmod"; "0o755"; "/test-command"];
1678 ["command"; "/test-command 8"]], "\n");
1679 InitBasicFS, Always, TestOutput (
1680 [["upload"; "test-command"; "/test-command"];
1681 ["chmod"; "0o755"; "/test-command"];
1682 ["command"; "/test-command 9"]], "\n\n");
1683 InitBasicFS, Always, TestOutput (
1684 [["upload"; "test-command"; "/test-command"];
1685 ["chmod"; "0o755"; "/test-command"];
1686 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1687 InitBasicFS, Always, TestOutput (
1688 [["upload"; "test-command"; "/test-command"];
1689 ["chmod"; "0o755"; "/test-command"];
1690 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1691 InitBasicFS, Always, TestLastFail (
1692 [["upload"; "test-command"; "/test-command"];
1693 ["chmod"; "0o755"; "/test-command"];
1694 ["command"; "/test-command"]])],
1695 "run a command from the guest filesystem",
1697 This call runs a command from the guest filesystem. The
1698 filesystem must be mounted, and must contain a compatible
1699 operating system (ie. something Linux, with the same
1700 or compatible processor architecture).
1702 The single parameter is an argv-style list of arguments.
1703 The first element is the name of the program to run.
1704 Subsequent elements are parameters. The list must be
1705 non-empty (ie. must contain a program name). Note that
1706 the command runs directly, and is I<not> invoked via
1707 the shell (see C<guestfs_sh>).
1709 The return value is anything printed to I<stdout> by
1712 If the command returns a non-zero exit status, then
1713 this function returns an error message. The error message
1714 string is the content of I<stderr> from the command.
1716 The C<$PATH> environment variable will contain at least
1717 C</usr/bin> and C</bin>. If you require a program from
1718 another location, you should provide the full path in the
1721 Shared libraries and data files required by the program
1722 must be available on filesystems which are mounted in the
1723 correct places. It is the caller's responsibility to ensure
1724 all filesystems that are needed are mounted at the right
1727 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1728 [InitBasicFS, Always, TestOutputList (
1729 [["upload"; "test-command"; "/test-command"];
1730 ["chmod"; "0o755"; "/test-command"];
1731 ["command_lines"; "/test-command 1"]], ["Result1"]);
1732 InitBasicFS, Always, TestOutputList (
1733 [["upload"; "test-command"; "/test-command"];
1734 ["chmod"; "0o755"; "/test-command"];
1735 ["command_lines"; "/test-command 2"]], ["Result2"]);
1736 InitBasicFS, Always, TestOutputList (
1737 [["upload"; "test-command"; "/test-command"];
1738 ["chmod"; "0o755"; "/test-command"];
1739 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1740 InitBasicFS, Always, TestOutputList (
1741 [["upload"; "test-command"; "/test-command"];
1742 ["chmod"; "0o755"; "/test-command"];
1743 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1744 InitBasicFS, Always, TestOutputList (
1745 [["upload"; "test-command"; "/test-command"];
1746 ["chmod"; "0o755"; "/test-command"];
1747 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1748 InitBasicFS, Always, TestOutputList (
1749 [["upload"; "test-command"; "/test-command"];
1750 ["chmod"; "0o755"; "/test-command"];
1751 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1752 InitBasicFS, Always, TestOutputList (
1753 [["upload"; "test-command"; "/test-command"];
1754 ["chmod"; "0o755"; "/test-command"];
1755 ["command_lines"; "/test-command 7"]], []);
1756 InitBasicFS, Always, TestOutputList (
1757 [["upload"; "test-command"; "/test-command"];
1758 ["chmod"; "0o755"; "/test-command"];
1759 ["command_lines"; "/test-command 8"]], [""]);
1760 InitBasicFS, Always, TestOutputList (
1761 [["upload"; "test-command"; "/test-command"];
1762 ["chmod"; "0o755"; "/test-command"];
1763 ["command_lines"; "/test-command 9"]], ["";""]);
1764 InitBasicFS, Always, TestOutputList (
1765 [["upload"; "test-command"; "/test-command"];
1766 ["chmod"; "0o755"; "/test-command"];
1767 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1768 InitBasicFS, Always, TestOutputList (
1769 [["upload"; "test-command"; "/test-command"];
1770 ["chmod"; "0o755"; "/test-command"];
1771 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1772 "run a command, returning lines",
1774 This is the same as C<guestfs_command>, but splits the
1775 result into a list of lines.
1777 See also: C<guestfs_sh_lines>");
1779 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1780 [InitISOFS, Always, TestOutputStruct (
1781 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1782 "get file information",
1784 Returns file information for the given C<path>.
1786 This is the same as the C<stat(2)> system call.");
1788 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1789 [InitISOFS, Always, TestOutputStruct (
1790 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1791 "get file information for a symbolic link",
1793 Returns file information for the given C<path>.
1795 This is the same as C<guestfs_stat> except that if C<path>
1796 is a symbolic link, then the link is stat-ed, not the file it
1799 This is the same as the C<lstat(2)> system call.");
1801 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1802 [InitISOFS, Always, TestOutputStruct (
1803 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1804 "get file system statistics",
1806 Returns file system statistics for any mounted file system.
1807 C<path> should be a file or directory in the mounted file system
1808 (typically it is the mount point itself, but it doesn't need to be).
1810 This is the same as the C<statvfs(2)> system call.");
1812 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1814 "get ext2/ext3/ext4 superblock details",
1816 This returns the contents of the ext2, ext3 or ext4 filesystem
1817 superblock on C<device>.
1819 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1820 manpage for more details. The list of fields returned isn't
1821 clearly defined, and depends on both the version of C<tune2fs>
1822 that libguestfs was built against, and the filesystem itself.");
1824 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1825 [InitEmpty, Always, TestOutputTrue (
1826 [["blockdev_setro"; "/dev/sda"];
1827 ["blockdev_getro"; "/dev/sda"]])],
1828 "set block device to read-only",
1830 Sets the block device named C<device> to read-only.
1832 This uses the L<blockdev(8)> command.");
1834 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1835 [InitEmpty, Always, TestOutputFalse (
1836 [["blockdev_setrw"; "/dev/sda"];
1837 ["blockdev_getro"; "/dev/sda"]])],
1838 "set block device to read-write",
1840 Sets the block device named C<device> to read-write.
1842 This uses the L<blockdev(8)> command.");
1844 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1845 [InitEmpty, Always, TestOutputTrue (
1846 [["blockdev_setro"; "/dev/sda"];
1847 ["blockdev_getro"; "/dev/sda"]])],
1848 "is block device set to read-only",
1850 Returns a boolean indicating if the block device is read-only
1851 (true if read-only, false if not).
1853 This uses the L<blockdev(8)> command.");
1855 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1856 [InitEmpty, Always, TestOutputInt (
1857 [["blockdev_getss"; "/dev/sda"]], 512)],
1858 "get sectorsize of block device",
1860 This returns the size of sectors on a block device.
1861 Usually 512, but can be larger for modern devices.
1863 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1866 This uses the L<blockdev(8)> command.");
1868 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1869 [InitEmpty, Always, TestOutputInt (
1870 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1871 "get blocksize of block device",
1873 This returns the block size of a device.
1875 (Note this is different from both I<size in blocks> and
1876 I<filesystem block size>).
1878 This uses the L<blockdev(8)> command.");
1880 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1882 "set blocksize of block device",
1884 This sets the block size of a device.
1886 (Note this is different from both I<size in blocks> and
1887 I<filesystem block size>).
1889 This uses the L<blockdev(8)> command.");
1891 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1892 [InitEmpty, Always, TestOutputInt (
1893 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1894 "get total size of device in 512-byte sectors",
1896 This returns the size of the device in units of 512-byte sectors
1897 (even if the sectorsize isn't 512 bytes ... weird).
1899 See also C<guestfs_blockdev_getss> for the real sector size of
1900 the device, and C<guestfs_blockdev_getsize64> for the more
1901 useful I<size in bytes>.
1903 This uses the L<blockdev(8)> command.");
1905 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1906 [InitEmpty, Always, TestOutputInt (
1907 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1908 "get total size of device in bytes",
1910 This returns the size of the device in bytes.
1912 See also C<guestfs_blockdev_getsz>.
1914 This uses the L<blockdev(8)> command.");
1916 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1917 [InitEmpty, Always, TestRun
1918 [["blockdev_flushbufs"; "/dev/sda"]]],
1919 "flush device buffers",
1921 This tells the kernel to flush internal buffers associated
1924 This uses the L<blockdev(8)> command.");
1926 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1927 [InitEmpty, Always, TestRun
1928 [["blockdev_rereadpt"; "/dev/sda"]]],
1929 "reread partition table",
1931 Reread the partition table on C<device>.
1933 This uses the L<blockdev(8)> command.");
1935 ("upload", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"]), 66, [],
1936 [InitBasicFS, Always, TestOutput (
1937 (* Pick a file from cwd which isn't likely to change. *)
1938 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1939 ["checksum"; "md5"; "/COPYING.LIB"]],
1940 Digest.to_hex (Digest.file "COPYING.LIB"))],
1941 "upload a file from the local machine",
1943 Upload local file C<filename> to C<remotefilename> on the
1946 C<filename> can also be a named pipe.
1948 See also C<guestfs_download>.");
1950 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1951 [InitBasicFS, Always, TestOutput (
1952 (* Pick a file from cwd which isn't likely to change. *)
1953 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1954 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1955 ["upload"; "testdownload.tmp"; "/upload"];
1956 ["checksum"; "md5"; "/upload"]],
1957 Digest.to_hex (Digest.file "COPYING.LIB"))],
1958 "download a file to the local machine",
1960 Download file C<remotefilename> and save it as C<filename>
1961 on the local machine.
1963 C<filename> can also be a named pipe.
1965 See also C<guestfs_upload>, C<guestfs_cat>.");
1967 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1968 [InitISOFS, Always, TestOutput (
1969 [["checksum"; "crc"; "/known-3"]], "2891671662");
1970 InitISOFS, Always, TestLastFail (
1971 [["checksum"; "crc"; "/notexists"]]);
1972 InitISOFS, Always, TestOutput (
1973 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1974 InitISOFS, Always, TestOutput (
1975 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1976 InitISOFS, Always, TestOutput (
1977 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1978 InitISOFS, Always, TestOutput (
1979 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1980 InitISOFS, Always, TestOutput (
1981 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1982 InitISOFS, Always, TestOutput (
1983 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6");
1984 (* Test for RHBZ#579608, absolute symbolic links. *)
1985 InitISOFS, Always, TestOutput (
1986 [["checksum"; "sha512"; "/abssymlink"]], "5f57d0639bc95081c53afc63a449403883818edc64da48930ad6b1a4fb49be90404686877743fbcd7c99811f3def7df7bc22635c885c6a8cf79c806b43451c1a")],
1987 "compute MD5, SHAx or CRC checksum of file",
1989 This call computes the MD5, SHAx or CRC checksum of the
1992 The type of checksum to compute is given by the C<csumtype>
1993 parameter which must have one of the following values:
1999 Compute the cyclic redundancy check (CRC) specified by POSIX
2000 for the C<cksum> command.
2004 Compute the MD5 hash (using the C<md5sum> program).
2008 Compute the SHA1 hash (using the C<sha1sum> program).
2012 Compute the SHA224 hash (using the C<sha224sum> program).
2016 Compute the SHA256 hash (using the C<sha256sum> program).
2020 Compute the SHA384 hash (using the C<sha384sum> program).
2024 Compute the SHA512 hash (using the C<sha512sum> program).
2028 The checksum is returned as a printable string.
2030 To get the checksum for a device, use C<guestfs_checksum_device>.
2032 To get the checksums for many files, use C<guestfs_checksums_out>.");
2034 ("tar_in", (RErr, [FileIn "tarfile"; Pathname "directory"]), 69, [],
2035 [InitBasicFS, Always, TestOutput (
2036 [["tar_in"; "../images/helloworld.tar"; "/"];
2037 ["cat"; "/hello"]], "hello\n")],
2038 "unpack tarfile to directory",
2040 This command uploads and unpacks local file C<tarfile> (an
2041 I<uncompressed> tar file) into C<directory>.
2043 To upload a compressed tarball, use C<guestfs_tgz_in>
2044 or C<guestfs_txz_in>.");
2046 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
2048 "pack directory into tarfile",
2050 This command packs the contents of C<directory> and downloads
2051 it to local file C<tarfile>.
2053 To download a compressed tarball, use C<guestfs_tgz_out>
2054 or C<guestfs_txz_out>.");
2056 ("tgz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 71, [],
2057 [InitBasicFS, Always, TestOutput (
2058 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
2059 ["cat"; "/hello"]], "hello\n")],
2060 "unpack compressed tarball to directory",
2062 This command uploads and unpacks local file C<tarball> (a
2063 I<gzip compressed> tar file) into C<directory>.
2065 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
2067 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
2069 "pack directory into compressed tarball",
2071 This command packs the contents of C<directory> and downloads
2072 it to local file C<tarball>.
2074 To download an uncompressed tarball, use C<guestfs_tar_out>.");
2076 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
2077 [InitBasicFS, Always, TestLastFail (
2079 ["mount_ro"; "/dev/sda1"; "/"];
2080 ["touch"; "/new"]]);
2081 InitBasicFS, Always, TestOutput (
2082 [["write"; "/new"; "data"];
2084 ["mount_ro"; "/dev/sda1"; "/"];
2085 ["cat"; "/new"]], "data")],
2086 "mount a guest disk, read-only",
2088 This is the same as the C<guestfs_mount> command, but it
2089 mounts the filesystem with the read-only (I<-o ro>) flag.");
2091 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2093 "mount a guest disk with mount options",
2095 This is the same as the C<guestfs_mount> command, but it
2096 allows you to set the mount options as for the
2097 L<mount(8)> I<-o> flag.
2099 If the C<options> parameter is an empty string, then
2100 no options are passed (all options default to whatever
2101 the filesystem uses).");
2103 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2105 "mount a guest disk with mount options and vfstype",
2107 This is the same as the C<guestfs_mount> command, but it
2108 allows you to set both the mount options and the vfstype
2109 as for the L<mount(8)> I<-o> and I<-t> flags.");
2111 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2113 "debugging and internals",
2115 The C<guestfs_debug> command exposes some internals of
2116 C<guestfsd> (the guestfs daemon) that runs inside the
2119 There is no comprehensive help for this command. You have
2120 to look at the file C<daemon/debug.c> in the libguestfs source
2121 to find out what you can do.");
2123 ("lvremove", (RErr, [Device "device"]), 77, [Optional "lvm2"],
2124 [InitEmpty, Always, TestOutputList (
2125 [["part_disk"; "/dev/sda"; "mbr"];
2126 ["pvcreate"; "/dev/sda1"];
2127 ["vgcreate"; "VG"; "/dev/sda1"];
2128 ["lvcreate"; "LV1"; "VG"; "50"];
2129 ["lvcreate"; "LV2"; "VG"; "50"];
2130 ["lvremove"; "/dev/VG/LV1"];
2131 ["lvs"]], ["/dev/VG/LV2"]);
2132 InitEmpty, Always, TestOutputList (
2133 [["part_disk"; "/dev/sda"; "mbr"];
2134 ["pvcreate"; "/dev/sda1"];
2135 ["vgcreate"; "VG"; "/dev/sda1"];
2136 ["lvcreate"; "LV1"; "VG"; "50"];
2137 ["lvcreate"; "LV2"; "VG"; "50"];
2138 ["lvremove"; "/dev/VG"];
2140 InitEmpty, Always, TestOutputList (
2141 [["part_disk"; "/dev/sda"; "mbr"];
2142 ["pvcreate"; "/dev/sda1"];
2143 ["vgcreate"; "VG"; "/dev/sda1"];
2144 ["lvcreate"; "LV1"; "VG"; "50"];
2145 ["lvcreate"; "LV2"; "VG"; "50"];
2146 ["lvremove"; "/dev/VG"];
2148 "remove an LVM logical volume",
2150 Remove an LVM logical volume C<device>, where C<device> is
2151 the path to the LV, such as C</dev/VG/LV>.
2153 You can also remove all LVs in a volume group by specifying
2154 the VG name, C</dev/VG>.");
2156 ("vgremove", (RErr, [String "vgname"]), 78, [Optional "lvm2"],
2157 [InitEmpty, Always, TestOutputList (
2158 [["part_disk"; "/dev/sda"; "mbr"];
2159 ["pvcreate"; "/dev/sda1"];
2160 ["vgcreate"; "VG"; "/dev/sda1"];
2161 ["lvcreate"; "LV1"; "VG"; "50"];
2162 ["lvcreate"; "LV2"; "VG"; "50"];
2165 InitEmpty, Always, TestOutputList (
2166 [["part_disk"; "/dev/sda"; "mbr"];
2167 ["pvcreate"; "/dev/sda1"];
2168 ["vgcreate"; "VG"; "/dev/sda1"];
2169 ["lvcreate"; "LV1"; "VG"; "50"];
2170 ["lvcreate"; "LV2"; "VG"; "50"];
2173 "remove an LVM volume group",
2175 Remove an LVM volume group C<vgname>, (for example C<VG>).
2177 This also forcibly removes all logical volumes in the volume
2180 ("pvremove", (RErr, [Device "device"]), 79, [Optional "lvm2"],
2181 [InitEmpty, Always, TestOutputListOfDevices (
2182 [["part_disk"; "/dev/sda"; "mbr"];
2183 ["pvcreate"; "/dev/sda1"];
2184 ["vgcreate"; "VG"; "/dev/sda1"];
2185 ["lvcreate"; "LV1"; "VG"; "50"];
2186 ["lvcreate"; "LV2"; "VG"; "50"];
2188 ["pvremove"; "/dev/sda1"];
2190 InitEmpty, Always, TestOutputListOfDevices (
2191 [["part_disk"; "/dev/sda"; "mbr"];
2192 ["pvcreate"; "/dev/sda1"];
2193 ["vgcreate"; "VG"; "/dev/sda1"];
2194 ["lvcreate"; "LV1"; "VG"; "50"];
2195 ["lvcreate"; "LV2"; "VG"; "50"];
2197 ["pvremove"; "/dev/sda1"];
2199 InitEmpty, Always, TestOutputListOfDevices (
2200 [["part_disk"; "/dev/sda"; "mbr"];
2201 ["pvcreate"; "/dev/sda1"];
2202 ["vgcreate"; "VG"; "/dev/sda1"];
2203 ["lvcreate"; "LV1"; "VG"; "50"];
2204 ["lvcreate"; "LV2"; "VG"; "50"];
2206 ["pvremove"; "/dev/sda1"];
2208 "remove an LVM physical volume",
2210 This wipes a physical volume C<device> so that LVM will no longer
2213 The implementation uses the C<pvremove> command which refuses to
2214 wipe physical volumes that contain any volume groups, so you have
2215 to remove those first.");
2217 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2218 [InitBasicFS, Always, TestOutput (
2219 [["set_e2label"; "/dev/sda1"; "testlabel"];
2220 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2221 "set the ext2/3/4 filesystem label",
2223 This sets the ext2/3/4 filesystem label of the filesystem on
2224 C<device> to C<label>. Filesystem labels are limited to
2227 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2228 to return the existing label on a filesystem.");
2230 ("get_e2label", (RString "label", [Device "device"]), 81, [DeprecatedBy "vfs_label"],
2232 "get the ext2/3/4 filesystem label",
2234 This returns the ext2/3/4 filesystem label of the filesystem on
2237 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2238 (let uuid = uuidgen () in
2239 [InitBasicFS, Always, TestOutput (
2240 [["set_e2uuid"; "/dev/sda1"; uuid];
2241 ["get_e2uuid"; "/dev/sda1"]], uuid);
2242 InitBasicFS, Always, TestOutput (
2243 [["set_e2uuid"; "/dev/sda1"; "clear"];
2244 ["get_e2uuid"; "/dev/sda1"]], "");
2245 (* We can't predict what UUIDs will be, so just check the commands run. *)
2246 InitBasicFS, Always, TestRun (
2247 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2248 InitBasicFS, Always, TestRun (
2249 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2250 "set the ext2/3/4 filesystem UUID",
2252 This sets the ext2/3/4 filesystem UUID of the filesystem on
2253 C<device> to C<uuid>. The format of the UUID and alternatives
2254 such as C<clear>, C<random> and C<time> are described in the
2255 L<tune2fs(8)> manpage.
2257 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2258 to return the existing UUID of a filesystem.");
2260 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [DeprecatedBy "vfs_uuid"],
2261 (* Regression test for RHBZ#597112. *)
2262 (let uuid = uuidgen () in
2263 [InitBasicFS, Always, TestOutput (
2264 [["mke2journal"; "1024"; "/dev/sdb"];
2265 ["set_e2uuid"; "/dev/sdb"; uuid];
2266 ["get_e2uuid"; "/dev/sdb"]], uuid)]),
2267 "get the ext2/3/4 filesystem UUID",
2269 This returns the ext2/3/4 filesystem UUID of the filesystem on
2272 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [FishOutput FishOutputHexadecimal],
2273 [InitBasicFS, Always, TestOutputInt (
2274 [["umount"; "/dev/sda1"];
2275 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2276 InitBasicFS, Always, TestOutputInt (
2277 [["umount"; "/dev/sda1"];
2278 ["zero"; "/dev/sda1"];
2279 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2280 "run the filesystem checker",
2282 This runs the filesystem checker (fsck) on C<device> which
2283 should have filesystem type C<fstype>.
2285 The returned integer is the status. See L<fsck(8)> for the
2286 list of status codes from C<fsck>.
2294 Multiple status codes can be summed together.
2298 A non-zero return code can mean \"success\", for example if
2299 errors have been corrected on the filesystem.
2303 Checking or repairing NTFS volumes is not supported
2308 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2310 ("zero", (RErr, [Device "device"]), 85, [],
2311 [InitBasicFS, Always, TestOutput (
2312 [["umount"; "/dev/sda1"];
2313 ["zero"; "/dev/sda1"];
2314 ["file"; "/dev/sda1"]], "data")],
2315 "write zeroes to the device",
2317 This command writes zeroes over the first few blocks of C<device>.
2319 How many blocks are zeroed isn't specified (but it's I<not> enough
2320 to securely wipe the device). It should be sufficient to remove
2321 any partition tables, filesystem superblocks and so on.
2323 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
2325 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2327 * https://bugzilla.redhat.com/show_bug.cgi?id=484986
2328 * https://bugzilla.redhat.com/show_bug.cgi?id=479760
2330 [InitBasicFS, Always, TestOutputTrue (
2331 [["mkdir_p"; "/boot/grub"];
2332 ["write"; "/boot/grub/device.map"; "(hd0) /dev/vda"];
2333 ["grub_install"; "/"; "/dev/vda"];
2334 ["is_dir"; "/boot"]])],
2337 This command installs GRUB (the Grand Unified Bootloader) on
2338 C<device>, with the root directory being C<root>.
2340 Note: If grub-install reports the error
2341 \"No suitable drive was found in the generated device map.\"
2342 it may be that you need to create a C</boot/grub/device.map>
2343 file first that contains the mapping between grub device names
2344 and Linux device names. It is usually sufficient to create
2349 replacing C</dev/vda> with the name of the installation device.");
2351 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2352 [InitBasicFS, Always, TestOutput (
2353 [["write"; "/old"; "file content"];
2354 ["cp"; "/old"; "/new"];
2355 ["cat"; "/new"]], "file content");
2356 InitBasicFS, Always, TestOutputTrue (
2357 [["write"; "/old"; "file content"];
2358 ["cp"; "/old"; "/new"];
2359 ["is_file"; "/old"]]);
2360 InitBasicFS, Always, TestOutput (
2361 [["write"; "/old"; "file content"];
2363 ["cp"; "/old"; "/dir/new"];
2364 ["cat"; "/dir/new"]], "file content")],
2367 This copies a file from C<src> to C<dest> where C<dest> is
2368 either a destination filename or destination directory.");
2370 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2371 [InitBasicFS, Always, TestOutput (
2372 [["mkdir"; "/olddir"];
2373 ["mkdir"; "/newdir"];
2374 ["write"; "/olddir/file"; "file content"];
2375 ["cp_a"; "/olddir"; "/newdir"];
2376 ["cat"; "/newdir/olddir/file"]], "file content")],
2377 "copy a file or directory recursively",
2379 This copies a file or directory from C<src> to C<dest>
2380 recursively using the C<cp -a> command.");
2382 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2383 [InitBasicFS, Always, TestOutput (
2384 [["write"; "/old"; "file content"];
2385 ["mv"; "/old"; "/new"];
2386 ["cat"; "/new"]], "file content");
2387 InitBasicFS, Always, TestOutputFalse (
2388 [["write"; "/old"; "file content"];
2389 ["mv"; "/old"; "/new"];
2390 ["is_file"; "/old"]])],
2393 This moves a file from C<src> to C<dest> where C<dest> is
2394 either a destination filename or destination directory.");
2396 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2397 [InitEmpty, Always, TestRun (
2398 [["drop_caches"; "3"]])],
2399 "drop kernel page cache, dentries and inodes",
2401 This instructs the guest kernel to drop its page cache,
2402 and/or dentries and inode caches. The parameter C<whattodrop>
2403 tells the kernel what precisely to drop, see
2404 L<http://linux-mm.org/Drop_Caches>
2406 Setting C<whattodrop> to 3 should drop everything.
2408 This automatically calls L<sync(2)> before the operation,
2409 so that the maximum guest memory is freed.");
2411 ("dmesg", (RString "kmsgs", []), 91, [],
2412 [InitEmpty, Always, TestRun (
2414 "return kernel messages",
2416 This returns the kernel messages (C<dmesg> output) from
2417 the guest kernel. This is sometimes useful for extended
2418 debugging of problems.
2420 Another way to get the same information is to enable
2421 verbose messages with C<guestfs_set_verbose> or by setting
2422 the environment variable C<LIBGUESTFS_DEBUG=1> before
2423 running the program.");
2425 ("ping_daemon", (RErr, []), 92, [],
2426 [InitEmpty, Always, TestRun (
2427 [["ping_daemon"]])],
2428 "ping the guest daemon",
2430 This is a test probe into the guestfs daemon running inside
2431 the qemu subprocess. Calling this function checks that the
2432 daemon responds to the ping message, without affecting the daemon
2433 or attached block device(s) in any other way.");
2435 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2436 [InitBasicFS, Always, TestOutputTrue (
2437 [["write"; "/file1"; "contents of a file"];
2438 ["cp"; "/file1"; "/file2"];
2439 ["equal"; "/file1"; "/file2"]]);
2440 InitBasicFS, Always, TestOutputFalse (
2441 [["write"; "/file1"; "contents of a file"];
2442 ["write"; "/file2"; "contents of another file"];
2443 ["equal"; "/file1"; "/file2"]]);
2444 InitBasicFS, Always, TestLastFail (
2445 [["equal"; "/file1"; "/file2"]])],
2446 "test if two files have equal contents",
2448 This compares the two files C<file1> and C<file2> and returns
2449 true if their content is exactly equal, or false otherwise.
2451 The external L<cmp(1)> program is used for the comparison.");
2453 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2454 [InitISOFS, Always, TestOutputList (
2455 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2456 InitISOFS, Always, TestOutputList (
2457 [["strings"; "/empty"]], []);
2458 (* Test for RHBZ#579608, absolute symbolic links. *)
2459 InitISOFS, Always, TestRun (
2460 [["strings"; "/abssymlink"]])],
2461 "print the printable strings in a file",
2463 This runs the L<strings(1)> command on a file and returns
2464 the list of printable strings found.");
2466 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2467 [InitISOFS, Always, TestOutputList (
2468 [["strings_e"; "b"; "/known-5"]], []);
2469 InitBasicFS, Always, TestOutputList (
2470 [["write"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"];
2471 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2472 "print the printable strings in a file",
2474 This is like the C<guestfs_strings> command, but allows you to
2475 specify the encoding of strings that are looked for in
2476 the source file C<path>.
2478 Allowed encodings are:
2484 Single 7-bit-byte characters like ASCII and the ASCII-compatible
2485 parts of ISO-8859-X (this is what C<guestfs_strings> uses).
2489 Single 8-bit-byte characters.
2493 16-bit big endian strings such as those encoded in
2494 UTF-16BE or UCS-2BE.
2496 =item l (lower case letter L)
2498 16-bit little endian such as UTF-16LE and UCS-2LE.
2499 This is useful for examining binaries in Windows guests.
2503 32-bit big endian such as UCS-4BE.
2507 32-bit little endian such as UCS-4LE.
2511 The returned strings are transcoded to UTF-8.");
2513 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2514 [InitISOFS, Always, TestOutput (
2515 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2516 (* Test for RHBZ#501888c2 regression which caused large hexdump
2517 * commands to segfault.
2519 InitISOFS, Always, TestRun (
2520 [["hexdump"; "/100krandom"]]);
2521 (* Test for RHBZ#579608, absolute symbolic links. *)
2522 InitISOFS, Always, TestRun (
2523 [["hexdump"; "/abssymlink"]])],
2524 "dump a file in hexadecimal",
2526 This runs C<hexdump -C> on the given C<path>. The result is
2527 the human-readable, canonical hex dump of the file.");
2529 ("zerofree", (RErr, [Device "device"]), 97, [Optional "zerofree"],
2530 [InitNone, Always, TestOutput (
2531 [["part_disk"; "/dev/sda"; "mbr"];
2532 ["mkfs"; "ext3"; "/dev/sda1"];
2533 ["mount_options"; ""; "/dev/sda1"; "/"];
2534 ["write"; "/new"; "test file"];
2535 ["umount"; "/dev/sda1"];
2536 ["zerofree"; "/dev/sda1"];
2537 ["mount_options"; ""; "/dev/sda1"; "/"];
2538 ["cat"; "/new"]], "test file")],
2539 "zero unused inodes and disk blocks on ext2/3 filesystem",
2541 This runs the I<zerofree> program on C<device>. This program
2542 claims to zero unused inodes and disk blocks on an ext2/3
2543 filesystem, thus making it possible to compress the filesystem
2546 You should B<not> run this program if the filesystem is
2549 It is possible that using this program can damage the filesystem
2550 or data on the filesystem.");
2552 ("pvresize", (RErr, [Device "device"]), 98, [Optional "lvm2"],
2554 "resize an LVM physical volume",
2556 This resizes (expands or shrinks) an existing LVM physical
2557 volume to match the new size of the underlying device.");
2559 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2560 Int "cyls"; Int "heads"; Int "sectors";
2561 String "line"]), 99, [DangerWillRobinson],
2563 "modify a single partition on a block device",
2565 This runs L<sfdisk(8)> option to modify just the single
2566 partition C<n> (note: C<n> counts from 1).
2568 For other parameters, see C<guestfs_sfdisk>. You should usually
2569 pass C<0> for the cyls/heads/sectors parameters.
2571 See also: C<guestfs_part_add>");
2573 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2575 "display the partition table",
2577 This displays the partition table on C<device>, in the
2578 human-readable output of the L<sfdisk(8)> command. It is
2579 not intended to be parsed.
2581 See also: C<guestfs_part_list>");
2583 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2585 "display the kernel geometry",
2587 This displays the kernel's idea of the geometry of C<device>.
2589 The result is in human-readable format, and not designed to
2592 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2594 "display the disk geometry from the partition table",
2596 This displays the disk geometry of C<device> read from the
2597 partition table. Especially in the case where the underlying
2598 block device has been resized, this can be different from the
2599 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2601 The result is in human-readable format, and not designed to
2604 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [Optional "lvm2"],
2606 "activate or deactivate all volume groups",
2608 This command activates or (if C<activate> is false) deactivates
2609 all logical volumes in all volume groups.
2610 If activated, then they are made known to the
2611 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2612 then those devices disappear.
2614 This command is the same as running C<vgchange -a y|n>");
2616 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [Optional "lvm2"],
2618 "activate or deactivate some volume groups",
2620 This command activates or (if C<activate> is false) deactivates
2621 all logical volumes in the listed volume groups C<volgroups>.
2622 If activated, then they are made known to the
2623 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2624 then those devices disappear.
2626 This command is the same as running C<vgchange -a y|n volgroups...>
2628 Note that if C<volgroups> is an empty list then B<all> volume groups
2629 are activated or deactivated.");
2631 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [Optional "lvm2"],
2632 [InitNone, Always, TestOutput (
2633 [["part_disk"; "/dev/sda"; "mbr"];
2634 ["pvcreate"; "/dev/sda1"];
2635 ["vgcreate"; "VG"; "/dev/sda1"];
2636 ["lvcreate"; "LV"; "VG"; "10"];
2637 ["mkfs"; "ext2"; "/dev/VG/LV"];
2638 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2639 ["write"; "/new"; "test content"];
2641 ["lvresize"; "/dev/VG/LV"; "20"];
2642 ["e2fsck_f"; "/dev/VG/LV"];
2643 ["resize2fs"; "/dev/VG/LV"];
2644 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2645 ["cat"; "/new"]], "test content");
2646 InitNone, Always, TestRun (
2647 (* Make an LV smaller to test RHBZ#587484. *)
2648 [["part_disk"; "/dev/sda"; "mbr"];
2649 ["pvcreate"; "/dev/sda1"];
2650 ["vgcreate"; "VG"; "/dev/sda1"];
2651 ["lvcreate"; "LV"; "VG"; "20"];
2652 ["lvresize"; "/dev/VG/LV"; "10"]])],
2653 "resize an LVM logical volume",
2655 This resizes (expands or shrinks) an existing LVM logical
2656 volume to C<mbytes>. When reducing, data in the reduced part
2659 ("resize2fs", (RErr, [Device "device"]), 106, [],
2660 [], (* lvresize tests this *)
2661 "resize an ext2, ext3 or ext4 filesystem",
2663 This resizes an ext2, ext3 or ext4 filesystem to match the size of
2664 the underlying device.
2666 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2667 on the C<device> before calling this command. For unknown reasons
2668 C<resize2fs> sometimes gives an error about this and sometimes not.
2669 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2670 calling this function.");
2672 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2673 [InitBasicFS, Always, TestOutputList (
2674 [["find"; "/"]], ["lost+found"]);
2675 InitBasicFS, Always, TestOutputList (
2679 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2680 InitBasicFS, Always, TestOutputList (
2681 [["mkdir_p"; "/a/b/c"];
2682 ["touch"; "/a/b/c/d"];
2683 ["find"; "/a/b/"]], ["c"; "c/d"])],
2684 "find all files and directories",
2686 This command lists out all files and directories, recursively,
2687 starting at C<directory>. It is essentially equivalent to
2688 running the shell command C<find directory -print> but some
2689 post-processing happens on the output, described below.
2691 This returns a list of strings I<without any prefix>. Thus
2692 if the directory structure was:
2698 then the returned list from C<guestfs_find> C</tmp> would be
2706 If C<directory> is not a directory, then this command returns
2709 The returned list is sorted.
2711 See also C<guestfs_find0>.");
2713 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2714 [], (* lvresize tests this *)
2715 "check an ext2/ext3 filesystem",
2717 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2718 filesystem checker on C<device>, noninteractively (C<-p>),
2719 even if the filesystem appears to be clean (C<-f>).
2721 This command is only needed because of C<guestfs_resize2fs>
2722 (q.v.). Normally you should use C<guestfs_fsck>.");
2724 ("sleep", (RErr, [Int "secs"]), 109, [],
2725 [InitNone, Always, TestRun (
2727 "sleep for some seconds",
2729 Sleep for C<secs> seconds.");
2731 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [Optional "ntfs3g"],
2732 [InitNone, Always, TestOutputInt (
2733 [["part_disk"; "/dev/sda"; "mbr"];
2734 ["mkfs"; "ntfs"; "/dev/sda1"];
2735 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2736 InitNone, Always, TestOutputInt (
2737 [["part_disk"; "/dev/sda"; "mbr"];
2738 ["mkfs"; "ext2"; "/dev/sda1"];
2739 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2740 "probe NTFS volume",
2742 This command runs the L<ntfs-3g.probe(8)> command which probes
2743 an NTFS C<device> for mountability. (Not all NTFS volumes can
2744 be mounted read-write, and some cannot be mounted at all).
2746 C<rw> is a boolean flag. Set it to true if you want to test
2747 if the volume can be mounted read-write. Set it to false if
2748 you want to test if the volume can be mounted read-only.
2750 The return value is an integer which C<0> if the operation
2751 would succeed, or some non-zero value documented in the
2752 L<ntfs-3g.probe(8)> manual page.");
2754 ("sh", (RString "output", [String "command"]), 111, [],
2755 [], (* XXX needs tests *)
2756 "run a command via the shell",
2758 This call runs a command from the guest filesystem via the
2761 This is like C<guestfs_command>, but passes the command to:
2763 /bin/sh -c \"command\"
2765 Depending on the guest's shell, this usually results in
2766 wildcards being expanded, shell expressions being interpolated
2769 All the provisos about C<guestfs_command> apply to this call.");
2771 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2772 [], (* XXX needs tests *)
2773 "run a command via the shell returning lines",
2775 This is the same as C<guestfs_sh>, but splits the result
2776 into a list of lines.
2778 See also: C<guestfs_command_lines>");
2780 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2781 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2782 * code in stubs.c, since all valid glob patterns must start with "/".
2783 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2785 [InitBasicFS, Always, TestOutputList (
2786 [["mkdir_p"; "/a/b/c"];
2787 ["touch"; "/a/b/c/d"];
2788 ["touch"; "/a/b/c/e"];
2789 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2790 InitBasicFS, Always, TestOutputList (
2791 [["mkdir_p"; "/a/b/c"];
2792 ["touch"; "/a/b/c/d"];
2793 ["touch"; "/a/b/c/e"];
2794 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2795 InitBasicFS, Always, TestOutputList (
2796 [["mkdir_p"; "/a/b/c"];
2797 ["touch"; "/a/b/c/d"];
2798 ["touch"; "/a/b/c/e"];
2799 ["glob_expand"; "/a/*/x/*"]], [])],
2800 "expand a wildcard path",
2802 This command searches for all the pathnames matching
2803 C<pattern> according to the wildcard expansion rules
2806 If no paths match, then this returns an empty list
2807 (note: not an error).
2809 It is just a wrapper around the C L<glob(3)> function
2810 with flags C<GLOB_MARK|GLOB_BRACE>.
2811 See that manual page for more details.");
2813 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson; Optional "scrub"],
2814 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2815 [["scrub_device"; "/dev/sdc"]])],
2816 "scrub (securely wipe) a device",
2818 This command writes patterns over C<device> to make data retrieval
2821 It is an interface to the L<scrub(1)> program. See that
2822 manual page for more details.");
2824 ("scrub_file", (RErr, [Pathname "file"]), 115, [Optional "scrub"],
2825 [InitBasicFS, Always, TestRun (
2826 [["write"; "/file"; "content"];
2827 ["scrub_file"; "/file"]])],
2828 "scrub (securely wipe) a file",
2830 This command writes patterns over a file to make data retrieval
2833 The file is I<removed> after scrubbing.
2835 It is an interface to the L<scrub(1)> program. See that
2836 manual page for more details.");
2838 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [Optional "scrub"],
2839 [], (* XXX needs testing *)
2840 "scrub (securely wipe) free space",
2842 This command creates the directory C<dir> and then fills it
2843 with files until the filesystem is full, and scrubs the files
2844 as for C<guestfs_scrub_file>, and deletes them.
2845 The intention is to scrub any free space on the partition
2848 It is an interface to the L<scrub(1)> program. See that
2849 manual page for more details.");
2851 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2852 [InitBasicFS, Always, TestRun (
2854 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2855 "create a temporary directory",
2857 This command creates a temporary directory. The
2858 C<template> parameter should be a full pathname for the
2859 temporary directory name with the final six characters being
2862 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2863 the second one being suitable for Windows filesystems.
2865 The name of the temporary directory that was created
2868 The temporary directory is created with mode 0700
2869 and is owned by root.
2871 The caller is responsible for deleting the temporary
2872 directory and its contents after use.
2874 See also: L<mkdtemp(3)>");
2876 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2877 [InitISOFS, Always, TestOutputInt (
2878 [["wc_l"; "/10klines"]], 10000);
2879 (* Test for RHBZ#579608, absolute symbolic links. *)
2880 InitISOFS, Always, TestOutputInt (
2881 [["wc_l"; "/abssymlink"]], 10000)],
2882 "count lines in a file",
2884 This command counts the lines in a file, using the
2885 C<wc -l> external command.");
2887 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2888 [InitISOFS, Always, TestOutputInt (
2889 [["wc_w"; "/10klines"]], 10000)],
2890 "count words in a file",
2892 This command counts the words in a file, using the
2893 C<wc -w> external command.");
2895 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2896 [InitISOFS, Always, TestOutputInt (
2897 [["wc_c"; "/100kallspaces"]], 102400)],
2898 "count characters in a file",
2900 This command counts the characters in a file, using the
2901 C<wc -c> external command.");
2903 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2904 [InitISOFS, Always, TestOutputList (
2905 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"]);
2906 (* Test for RHBZ#579608, absolute symbolic links. *)
2907 InitISOFS, Always, TestOutputList (
2908 [["head"; "/abssymlink"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2909 "return first 10 lines of a file",
2911 This command returns up to the first 10 lines of a file as
2912 a list of strings.");
2914 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2915 [InitISOFS, Always, TestOutputList (
2916 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2917 InitISOFS, Always, TestOutputList (
2918 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2919 InitISOFS, Always, TestOutputList (
2920 [["head_n"; "0"; "/10klines"]], [])],
2921 "return first N lines of a file",
2923 If the parameter C<nrlines> is a positive number, this returns the first
2924 C<nrlines> lines of the file C<path>.
2926 If the parameter C<nrlines> is a negative number, this returns lines
2927 from the file C<path>, excluding the last C<nrlines> lines.
2929 If the parameter C<nrlines> is zero, this returns an empty list.");
2931 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2932 [InitISOFS, Always, TestOutputList (
2933 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2934 "return last 10 lines of a file",
2936 This command returns up to the last 10 lines of a file as
2937 a list of strings.");
2939 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2940 [InitISOFS, Always, TestOutputList (
2941 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2942 InitISOFS, Always, TestOutputList (
2943 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2944 InitISOFS, Always, TestOutputList (
2945 [["tail_n"; "0"; "/10klines"]], [])],
2946 "return last N lines of a file",
2948 If the parameter C<nrlines> is a positive number, this returns the last
2949 C<nrlines> lines of the file C<path>.
2951 If the parameter C<nrlines> is a negative number, this returns lines
2952 from the file C<path>, starting with the C<-nrlines>th line.
2954 If the parameter C<nrlines> is zero, this returns an empty list.");
2956 ("df", (RString "output", []), 125, [],
2957 [], (* XXX Tricky to test because it depends on the exact format
2958 * of the 'df' command and other imponderables.
2960 "report file system disk space usage",
2962 This command runs the C<df> command to report disk space used.
2964 This command is mostly useful for interactive sessions. It
2965 is I<not> intended that you try to parse the output string.
2966 Use C<statvfs> from programs.");
2968 ("df_h", (RString "output", []), 126, [],
2969 [], (* XXX Tricky to test because it depends on the exact format
2970 * of the 'df' command and other imponderables.
2972 "report file system disk space usage (human readable)",
2974 This command runs the C<df -h> command to report disk space used
2975 in human-readable format.
2977 This command is mostly useful for interactive sessions. It
2978 is I<not> intended that you try to parse the output string.
2979 Use C<statvfs> from programs.");
2981 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2982 [InitISOFS, Always, TestOutputInt (
2983 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2984 "estimate file space usage",
2986 This command runs the C<du -s> command to estimate file space
2989 C<path> can be a file or a directory. If C<path> is a directory
2990 then the estimate includes the contents of the directory and all
2991 subdirectories (recursively).
2993 The result is the estimated size in I<kilobytes>
2994 (ie. units of 1024 bytes).");
2996 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
2997 [InitISOFS, Always, TestOutputList (
2998 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
2999 "list files in an initrd",
3001 This command lists out files contained in an initrd.
3003 The files are listed without any initial C</> character. The
3004 files are listed in the order they appear (not necessarily
3005 alphabetical). Directory names are listed as separate items.
3007 Old Linux kernels (2.4 and earlier) used a compressed ext2
3008 filesystem as initrd. We I<only> support the newer initramfs
3009 format (compressed cpio files).");
3011 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
3013 "mount a file using the loop device",
3015 This command lets you mount C<file> (a filesystem image
3016 in a file) on a mount point. It is entirely equivalent to
3017 the command C<mount -o loop file mountpoint>.");
3019 ("mkswap", (RErr, [Device "device"]), 130, [],
3020 [InitEmpty, Always, TestRun (
3021 [["part_disk"; "/dev/sda"; "mbr"];
3022 ["mkswap"; "/dev/sda1"]])],
3023 "create a swap partition",
3025 Create a swap partition on C<device>.");
3027 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
3028 [InitEmpty, Always, TestRun (
3029 [["part_disk"; "/dev/sda"; "mbr"];
3030 ["mkswap_L"; "hello"; "/dev/sda1"]])],
3031 "create a swap partition with a label",
3033 Create a swap partition on C<device> with label C<label>.
3035 Note that you cannot attach a swap label to a block device
3036 (eg. C</dev/sda>), just to a partition. This appears to be
3037 a limitation of the kernel or swap tools.");
3039 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [Optional "linuxfsuuid"],
3040 (let uuid = uuidgen () in
3041 [InitEmpty, Always, TestRun (
3042 [["part_disk"; "/dev/sda"; "mbr"];
3043 ["mkswap_U"; uuid; "/dev/sda1"]])]),
3044 "create a swap partition with an explicit UUID",
3046 Create a swap partition on C<device> with UUID C<uuid>.");
3048 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [Optional "mknod"],
3049 [InitBasicFS, Always, TestOutputStruct (
3050 [["mknod"; "0o10777"; "0"; "0"; "/node"];
3051 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
3052 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
3053 InitBasicFS, Always, TestOutputStruct (
3054 [["mknod"; "0o60777"; "66"; "99"; "/node"];
3055 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3056 "make block, character or FIFO devices",
3058 This call creates block or character special devices, or
3059 named pipes (FIFOs).
3061 The C<mode> parameter should be the mode, using the standard
3062 constants. C<devmajor> and C<devminor> are the
3063 device major and minor numbers, only used when creating block
3064 and character special devices.
3066 Note that, just like L<mknod(2)>, the mode must be bitwise
3067 OR'd with S_IFBLK, S_IFCHR, S_IFIFO or S_IFSOCK (otherwise this call
3068 just creates a regular file). These constants are
3069 available in the standard Linux header files, or you can use
3070 C<guestfs_mknod_b>, C<guestfs_mknod_c> or C<guestfs_mkfifo>
3071 which are wrappers around this command which bitwise OR
3072 in the appropriate constant for you.
3074 The mode actually set is affected by the umask.");
3076 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [Optional "mknod"],
3077 [InitBasicFS, Always, TestOutputStruct (
3078 [["mkfifo"; "0o777"; "/node"];
3079 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
3080 "make FIFO (named pipe)",
3082 This call creates a FIFO (named pipe) called C<path> with
3083 mode C<mode>. It is just a convenient wrapper around
3086 The mode actually set is affected by the umask.");
3088 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [Optional "mknod"],
3089 [InitBasicFS, Always, TestOutputStruct (
3090 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
3091 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3092 "make block device node",
3094 This call creates a block device node called C<path> with
3095 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3096 It is just a convenient wrapper around C<guestfs_mknod>.
3098 The mode actually set is affected by the umask.");
3100 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [Optional "mknod"],
3101 [InitBasicFS, Always, TestOutputStruct (
3102 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
3103 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
3104 "make char device node",
3106 This call creates a char device node called C<path> with
3107 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3108 It is just a convenient wrapper around C<guestfs_mknod>.
3110 The mode actually set is affected by the umask.");
3112 ("umask", (RInt "oldmask", [Int "mask"]), 137, [FishOutput FishOutputOctal],
3113 [InitEmpty, Always, TestOutputInt (
3114 [["umask"; "0o22"]], 0o22)],
3115 "set file mode creation mask (umask)",
3117 This function sets the mask used for creating new files and
3118 device nodes to C<mask & 0777>.
3120 Typical umask values would be C<022> which creates new files
3121 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
3122 C<002> which creates new files with permissions like
3123 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
3125 The default umask is C<022>. This is important because it
3126 means that directories and device nodes will be created with
3127 C<0644> or C<0755> mode even if you specify C<0777>.
3129 See also C<guestfs_get_umask>,
3130 L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
3132 This call returns the previous umask.");
3134 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
3136 "read directories entries",
3138 This returns the list of directory entries in directory C<dir>.
3140 All entries in the directory are returned, including C<.> and
3141 C<..>. The entries are I<not> sorted, but returned in the same
3142 order as the underlying filesystem.
3144 Also this call returns basic file type information about each
3145 file. The C<ftyp> field will contain one of the following characters:
3183 The L<readdir(3)> call returned a C<d_type> field with an
3188 This function is primarily intended for use by programs. To
3189 get a simple list of names, use C<guestfs_ls>. To get a printable
3190 directory for human consumption, use C<guestfs_ll>.");
3192 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3194 "create partitions on a block device",
3196 This is a simplified interface to the C<guestfs_sfdisk>
3197 command, where partition sizes are specified in megabytes
3198 only (rounded to the nearest cylinder) and you don't need
3199 to specify the cyls, heads and sectors parameters which
3200 were rarely if ever used anyway.
3202 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3203 and C<guestfs_part_disk>");
3205 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3207 "determine file type inside a compressed file",
3209 This command runs C<file> after first decompressing C<path>
3212 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3214 Since 1.0.63, use C<guestfs_file> instead which can now
3215 process compressed files.");
3217 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [Optional "linuxxattrs"],
3219 "list extended attributes of a file or directory",
3221 This call lists the extended attributes of the file or directory
3224 At the system call level, this is a combination of the
3225 L<listxattr(2)> and L<getxattr(2)> calls.
3227 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3229 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [Optional "linuxxattrs"],
3231 "list extended attributes of a file or directory",
3233 This is the same as C<guestfs_getxattrs>, but if C<path>
3234 is a symbolic link, then it returns the extended attributes
3235 of the link itself.");
3237 ("setxattr", (RErr, [String "xattr";
3238 String "val"; Int "vallen"; (* will be BufferIn *)
3239 Pathname "path"]), 143, [Optional "linuxxattrs"],
3241 "set extended attribute of a file or directory",
3243 This call sets the extended attribute named C<xattr>
3244 of the file C<path> to the value C<val> (of length C<vallen>).
3245 The value is arbitrary 8 bit data.
3247 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3249 ("lsetxattr", (RErr, [String "xattr";
3250 String "val"; Int "vallen"; (* will be BufferIn *)
3251 Pathname "path"]), 144, [Optional "linuxxattrs"],
3253 "set extended attribute of a file or directory",
3255 This is the same as C<guestfs_setxattr>, but if C<path>
3256 is a symbolic link, then it sets an extended attribute
3257 of the link itself.");
3259 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [Optional "linuxxattrs"],
3261 "remove extended attribute of a file or directory",
3263 This call removes the extended attribute named C<xattr>
3264 of the file C<path>.
3266 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3268 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [Optional "linuxxattrs"],
3270 "remove extended attribute of a file or directory",
3272 This is the same as C<guestfs_removexattr>, but if C<path>
3273 is a symbolic link, then it removes an extended attribute
3274 of the link itself.");
3276 ("mountpoints", (RHashtable "mps", []), 147, [],
3280 This call is similar to C<guestfs_mounts>. That call returns
3281 a list of devices. This one returns a hash table (map) of
3282 device name to directory where the device is mounted.");
3284 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3285 (* This is a special case: while you would expect a parameter
3286 * of type "Pathname", that doesn't work, because it implies
3287 * NEED_ROOT in the generated calling code in stubs.c, and
3288 * this function cannot use NEED_ROOT.
3291 "create a mountpoint",
3293 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3294 specialized calls that can be used to create extra mountpoints
3295 before mounting the first filesystem.
3297 These calls are I<only> necessary in some very limited circumstances,
3298 mainly the case where you want to mount a mix of unrelated and/or
3299 read-only filesystems together.
3301 For example, live CDs often contain a \"Russian doll\" nest of
3302 filesystems, an ISO outer layer, with a squashfs image inside, with
3303 an ext2/3 image inside that. You can unpack this as follows
3306 add-ro Fedora-11-i686-Live.iso
3309 mkmountpoint /squash
3312 mount-loop /cd/LiveOS/squashfs.img /squash
3313 mount-loop /squash/LiveOS/ext3fs.img /ext3
3315 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3317 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3319 "remove a mountpoint",
3321 This calls removes a mountpoint that was previously created
3322 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3323 for full details.");
3325 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3326 [InitISOFS, Always, TestOutputBuffer (
3327 [["read_file"; "/known-4"]], "abc\ndef\nghi");
3328 (* Test various near large, large and too large files (RHBZ#589039). *)
3329 InitBasicFS, Always, TestLastFail (
3331 ["truncate_size"; "/a"; "4194303"]; (* GUESTFS_MESSAGE_MAX - 1 *)
3332 ["read_file"; "/a"]]);
3333 InitBasicFS, Always, TestLastFail (
3335 ["truncate_size"; "/a"; "4194304"]; (* GUESTFS_MESSAGE_MAX *)
3336 ["read_file"; "/a"]]);
3337 InitBasicFS, Always, TestLastFail (
3339 ["truncate_size"; "/a"; "41943040"]; (* GUESTFS_MESSAGE_MAX * 10 *)
3340 ["read_file"; "/a"]])],
3343 This calls returns the contents of the file C<path> as a
3346 Unlike C<guestfs_cat>, this function can correctly
3347 handle files that contain embedded ASCII NUL characters.
3348 However unlike C<guestfs_download>, this function is limited
3349 in the total size of file that can be handled.");
3351 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3352 [InitISOFS, Always, TestOutputList (
3353 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3354 InitISOFS, Always, TestOutputList (
3355 [["grep"; "nomatch"; "/test-grep.txt"]], []);
3356 (* Test for RHBZ#579608, absolute symbolic links. *)
3357 InitISOFS, Always, TestOutputList (
3358 [["grep"; "nomatch"; "/abssymlink"]], [])],
3359 "return lines matching a pattern",
3361 This calls the external C<grep> program and returns the
3364 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3365 [InitISOFS, Always, TestOutputList (
3366 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3367 "return lines matching a pattern",
3369 This calls the external C<egrep> program and returns the
3372 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3373 [InitISOFS, Always, TestOutputList (
3374 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3375 "return lines matching a pattern",
3377 This calls the external C<fgrep> program and returns the
3380 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3381 [InitISOFS, Always, TestOutputList (
3382 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3383 "return lines matching a pattern",
3385 This calls the external C<grep -i> program and returns the
3388 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3389 [InitISOFS, Always, TestOutputList (
3390 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3391 "return lines matching a pattern",
3393 This calls the external C<egrep -i> program and returns the
3396 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3397 [InitISOFS, Always, TestOutputList (
3398 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3399 "return lines matching a pattern",
3401 This calls the external C<fgrep -i> program and returns the
3404 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3405 [InitISOFS, Always, TestOutputList (
3406 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3407 "return lines matching a pattern",
3409 This calls the external C<zgrep> program and returns the
3412 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3413 [InitISOFS, Always, TestOutputList (
3414 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3415 "return lines matching a pattern",
3417 This calls the external C<zegrep> program and returns the
3420 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3421 [InitISOFS, Always, TestOutputList (
3422 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3423 "return lines matching a pattern",
3425 This calls the external C<zfgrep> program and returns the
3428 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3429 [InitISOFS, Always, TestOutputList (
3430 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3431 "return lines matching a pattern",
3433 This calls the external C<zgrep -i> program and returns the
3436 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3437 [InitISOFS, Always, TestOutputList (
3438 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3439 "return lines matching a pattern",
3441 This calls the external C<zegrep -i> program and returns the
3444 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3445 [InitISOFS, Always, TestOutputList (
3446 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3447 "return lines matching a pattern",
3449 This calls the external C<zfgrep -i> program and returns the
3452 ("realpath", (RString "rpath", [Pathname "path"]), 163, [Optional "realpath"],
3453 [InitISOFS, Always, TestOutput (
3454 [["realpath"; "/../directory"]], "/directory")],
3455 "canonicalized absolute pathname",
3457 Return the canonicalized absolute pathname of C<path>. The
3458 returned path has no C<.>, C<..> or symbolic link path elements.");
3460 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3461 [InitBasicFS, Always, TestOutputStruct (
3464 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3465 "create a hard link",
3467 This command creates a hard link using the C<ln> command.");
3469 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3470 [InitBasicFS, Always, TestOutputStruct (
3473 ["ln_f"; "/a"; "/b"];
3474 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3475 "create a hard link",
3477 This command creates a hard link using the C<ln -f> command.
3478 The C<-f> option removes the link (C<linkname>) if it exists already.");
3480 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3481 [InitBasicFS, Always, TestOutputStruct (
3483 ["ln_s"; "a"; "/b"];
3484 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3485 "create a symbolic link",
3487 This command creates a symbolic link using the C<ln -s> command.");
3489 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3490 [InitBasicFS, Always, TestOutput (
3491 [["mkdir_p"; "/a/b"];
3492 ["touch"; "/a/b/c"];
3493 ["ln_sf"; "../d"; "/a/b/c"];
3494 ["readlink"; "/a/b/c"]], "../d")],
3495 "create a symbolic link",
3497 This command creates a symbolic link using the C<ln -sf> command,
3498 The C<-f> option removes the link (C<linkname>) if it exists already.");
3500 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3501 [] (* XXX tested above *),
3502 "read the target of a symbolic link",
3504 This command reads the target of a symbolic link.");
3506 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"],
3507 [InitBasicFS, Always, TestOutputStruct (
3508 [["fallocate"; "/a"; "1000000"];
3509 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3510 "preallocate a file in the guest filesystem",
3512 This command preallocates a file (containing zero bytes) named
3513 C<path> of size C<len> bytes. If the file exists already, it
3516 Do not confuse this with the guestfish-specific
3517 C<alloc> command which allocates a file in the host and
3518 attaches it as a device.");
3520 ("swapon_device", (RErr, [Device "device"]), 170, [],
3521 [InitPartition, Always, TestRun (
3522 [["mkswap"; "/dev/sda1"];
3523 ["swapon_device"; "/dev/sda1"];
3524 ["swapoff_device"; "/dev/sda1"]])],
3525 "enable swap on device",
3527 This command enables the libguestfs appliance to use the
3528 swap device or partition named C<device>. The increased
3529 memory is made available for all commands, for example
3530 those run using C<guestfs_command> or C<guestfs_sh>.
3532 Note that you should not swap to existing guest swap
3533 partitions unless you know what you are doing. They may
3534 contain hibernation information, or other information that
3535 the guest doesn't want you to trash. You also risk leaking
3536 information about the host to the guest this way. Instead,
3537 attach a new host device to the guest and swap on that.");
3539 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3540 [], (* XXX tested by swapon_device *)
3541 "disable swap on device",
3543 This command disables the libguestfs appliance swap
3544 device or partition named C<device>.
3545 See C<guestfs_swapon_device>.");
3547 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3548 [InitBasicFS, Always, TestRun (
3549 [["fallocate"; "/swap"; "8388608"];
3550 ["mkswap_file"; "/swap"];
3551 ["swapon_file"; "/swap"];
3552 ["swapoff_file"; "/swap"]])],
3553 "enable swap on file",
3555 This command enables swap to a file.
3556 See C<guestfs_swapon_device> for other notes.");
3558 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3559 [], (* XXX tested by swapon_file *)
3560 "disable swap on file",
3562 This command disables the libguestfs appliance swap on file.");
3564 ("swapon_label", (RErr, [String "label"]), 174, [],
3565 [InitEmpty, Always, TestRun (
3566 [["part_disk"; "/dev/sdb"; "mbr"];
3567 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3568 ["swapon_label"; "swapit"];
3569 ["swapoff_label"; "swapit"];
3570 ["zero"; "/dev/sdb"];
3571 ["blockdev_rereadpt"; "/dev/sdb"]])],
3572 "enable swap on labeled swap partition",
3574 This command enables swap to a labeled swap partition.
3575 See C<guestfs_swapon_device> for other notes.");
3577 ("swapoff_label", (RErr, [String "label"]), 175, [],
3578 [], (* XXX tested by swapon_label *)
3579 "disable swap on labeled swap partition",
3581 This command disables the libguestfs appliance swap on
3582 labeled swap partition.");
3584 ("swapon_uuid", (RErr, [String "uuid"]), 176, [Optional "linuxfsuuid"],
3585 (let uuid = uuidgen () in
3586 [InitEmpty, Always, TestRun (
3587 [["mkswap_U"; uuid; "/dev/sdb"];
3588 ["swapon_uuid"; uuid];
3589 ["swapoff_uuid"; uuid]])]),
3590 "enable swap on swap partition by UUID",
3592 This command enables swap to a swap partition with the given UUID.
3593 See C<guestfs_swapon_device> for other notes.");
3595 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [Optional "linuxfsuuid"],
3596 [], (* XXX tested by swapon_uuid *)
3597 "disable swap on swap partition by UUID",
3599 This command disables the libguestfs appliance swap partition
3600 with the given UUID.");
3602 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3603 [InitBasicFS, Always, TestRun (
3604 [["fallocate"; "/swap"; "8388608"];
3605 ["mkswap_file"; "/swap"]])],
3606 "create a swap file",
3610 This command just writes a swap file signature to an existing
3611 file. To create the file itself, use something like C<guestfs_fallocate>.");
3613 ("inotify_init", (RErr, [Int "maxevents"]), 179, [Optional "inotify"],
3614 [InitISOFS, Always, TestRun (
3615 [["inotify_init"; "0"]])],
3616 "create an inotify handle",
3618 This command creates a new inotify handle.
3619 The inotify subsystem can be used to notify events which happen to
3620 objects in the guest filesystem.
3622 C<maxevents> is the maximum number of events which will be
3623 queued up between calls to C<guestfs_inotify_read> or
3624 C<guestfs_inotify_files>.
3625 If this is passed as C<0>, then the kernel (or previously set)
3626 default is used. For Linux 2.6.29 the default was 16384 events.
3627 Beyond this limit, the kernel throws away events, but records
3628 the fact that it threw them away by setting a flag
3629 C<IN_Q_OVERFLOW> in the returned structure list (see
3630 C<guestfs_inotify_read>).
3632 Before any events are generated, you have to add some
3633 watches to the internal watch list. See:
3634 C<guestfs_inotify_add_watch>,
3635 C<guestfs_inotify_rm_watch> and
3636 C<guestfs_inotify_watch_all>.
3638 Queued up events should be read periodically by calling
3639 C<guestfs_inotify_read>
3640 (or C<guestfs_inotify_files> which is just a helpful
3641 wrapper around C<guestfs_inotify_read>). If you don't
3642 read the events out often enough then you risk the internal
3645 The handle should be closed after use by calling
3646 C<guestfs_inotify_close>. This also removes any
3647 watches automatically.
3649 See also L<inotify(7)> for an overview of the inotify interface
3650 as exposed by the Linux kernel, which is roughly what we expose
3651 via libguestfs. Note that there is one global inotify handle
3652 per libguestfs instance.");
3654 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [Optional "inotify"],
3655 [InitBasicFS, Always, TestOutputList (
3656 [["inotify_init"; "0"];
3657 ["inotify_add_watch"; "/"; "1073741823"];
3660 ["inotify_files"]], ["a"; "b"])],
3661 "add an inotify watch",
3663 Watch C<path> for the events listed in C<mask>.
3665 Note that if C<path> is a directory then events within that
3666 directory are watched, but this does I<not> happen recursively
3667 (in subdirectories).
3669 Note for non-C or non-Linux callers: the inotify events are
3670 defined by the Linux kernel ABI and are listed in
3671 C</usr/include/sys/inotify.h>.");
3673 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [Optional "inotify"],
3675 "remove an inotify watch",
3677 Remove a previously defined inotify watch.
3678 See C<guestfs_inotify_add_watch>.");
3680 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [Optional "inotify"],
3682 "return list of inotify events",
3684 Return the complete queue of events that have happened
3685 since the previous read call.
3687 If no events have happened, this returns an empty list.
3689 I<Note>: In order to make sure that all events have been
3690 read, you must call this function repeatedly until it
3691 returns an empty list. The reason is that the call will
3692 read events up to the maximum appliance-to-host message
3693 size and leave remaining events in the queue.");
3695 ("inotify_files", (RStringList "paths", []), 183, [Optional "inotify"],
3697 "return list of watched files that had events",
3699 This function is a helpful wrapper around C<guestfs_inotify_read>
3700 which just returns a list of pathnames of objects that were
3701 touched. The returned pathnames are sorted and deduplicated.");
3703 ("inotify_close", (RErr, []), 184, [Optional "inotify"],
3705 "close the inotify handle",
3707 This closes the inotify handle which was previously
3708 opened by inotify_init. It removes all watches, throws
3709 away any pending events, and deallocates all resources.");
3711 ("setcon", (RErr, [String "context"]), 185, [Optional "selinux"],
3713 "set SELinux security context",
3715 This sets the SELinux security context of the daemon
3716 to the string C<context>.
3718 See the documentation about SELINUX in L<guestfs(3)>.");
3720 ("getcon", (RString "context", []), 186, [Optional "selinux"],
3722 "get SELinux security context",
3724 This gets the SELinux security context of the daemon.
3726 See the documentation about SELINUX in L<guestfs(3)>,
3727 and C<guestfs_setcon>");
3729 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3730 [InitEmpty, Always, TestOutput (
3731 [["part_disk"; "/dev/sda"; "mbr"];
3732 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3733 ["mount_options"; ""; "/dev/sda1"; "/"];
3734 ["write"; "/new"; "new file contents"];
3735 ["cat"; "/new"]], "new file contents");
3736 InitEmpty, Always, TestRun (
3737 [["part_disk"; "/dev/sda"; "mbr"];
3738 ["mkfs_b"; "vfat"; "32768"; "/dev/sda1"]]);
3739 InitEmpty, Always, TestLastFail (
3740 [["part_disk"; "/dev/sda"; "mbr"];
3741 ["mkfs_b"; "vfat"; "32769"; "/dev/sda1"]]);
3742 InitEmpty, Always, TestLastFail (
3743 [["part_disk"; "/dev/sda"; "mbr"];
3744 ["mkfs_b"; "vfat"; "33280"; "/dev/sda1"]]);
3745 InitEmpty, IfAvailable "ntfsprogs", TestRun (
3746 [["part_disk"; "/dev/sda"; "mbr"];
3747 ["mkfs_b"; "ntfs"; "32768"; "/dev/sda1"]])],
3748 "make a filesystem with block size",
3750 This call is similar to C<guestfs_mkfs>, but it allows you to
3751 control the block size of the resulting filesystem. Supported
3752 block sizes depend on the filesystem type, but typically they
3753 are C<1024>, C<2048> or C<4096> only.
3755 For VFAT and NTFS the C<blocksize> parameter is treated as
3756 the requested cluster size.");
3758 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3759 [InitEmpty, Always, TestOutput (
3760 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3761 ["mke2journal"; "4096"; "/dev/sda1"];
3762 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3763 ["mount_options"; ""; "/dev/sda2"; "/"];
3764 ["write"; "/new"; "new file contents"];
3765 ["cat"; "/new"]], "new file contents")],
3766 "make ext2/3/4 external journal",
3768 This creates an ext2 external journal on C<device>. It is equivalent
3771 mke2fs -O journal_dev -b blocksize device");
3773 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3774 [InitEmpty, Always, TestOutput (
3775 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3776 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3777 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3778 ["mount_options"; ""; "/dev/sda2"; "/"];
3779 ["write"; "/new"; "new file contents"];
3780 ["cat"; "/new"]], "new file contents")],
3781 "make ext2/3/4 external journal with label",
3783 This creates an ext2 external journal on C<device> with label C<label>.");
3785 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [Optional "linuxfsuuid"],
3786 (let uuid = uuidgen () in
3787 [InitEmpty, Always, TestOutput (
3788 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3789 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3790 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3791 ["mount_options"; ""; "/dev/sda2"; "/"];
3792 ["write"; "/new"; "new file contents"];
3793 ["cat"; "/new"]], "new file contents")]),
3794 "make ext2/3/4 external journal with UUID",
3796 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3798 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3800 "make ext2/3/4 filesystem with external journal",
3802 This creates an ext2/3/4 filesystem on C<device> with
3803 an external journal on C<journal>. It is equivalent
3806 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3808 See also C<guestfs_mke2journal>.");
3810 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3812 "make ext2/3/4 filesystem with external journal",
3814 This creates an ext2/3/4 filesystem on C<device> with
3815 an external journal on the journal labeled C<label>.
3817 See also C<guestfs_mke2journal_L>.");
3819 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [Optional "linuxfsuuid"],
3821 "make ext2/3/4 filesystem with external journal",
3823 This creates an ext2/3/4 filesystem on C<device> with
3824 an external journal on the journal with UUID C<uuid>.
3826 See also C<guestfs_mke2journal_U>.");
3828 ("modprobe", (RErr, [String "modulename"]), 194, [Optional "linuxmodules"],
3829 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3830 "load a kernel module",
3832 This loads a kernel module in the appliance.
3834 The kernel module must have been whitelisted when libguestfs
3835 was built (see C<appliance/kmod.whitelist.in> in the source).");
3837 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3838 [InitNone, Always, TestOutput (
3839 [["echo_daemon"; "This is a test"]], "This is a test"
3841 "echo arguments back to the client",
3843 This command concatenates the list of C<words> passed with single spaces
3844 between them and returns the resulting string.
3846 You can use this command to test the connection through to the daemon.
3848 See also C<guestfs_ping_daemon>.");
3850 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3851 [], (* There is a regression test for this. *)
3852 "find all files and directories, returning NUL-separated list",
3854 This command lists out all files and directories, recursively,
3855 starting at C<directory>, placing the resulting list in the
3856 external file called C<files>.
3858 This command works the same way as C<guestfs_find> with the
3859 following exceptions:
3865 The resulting list is written to an external file.
3869 Items (filenames) in the result are separated
3870 by C<\\0> characters. See L<find(1)> option I<-print0>.
3874 This command is not limited in the number of names that it
3879 The result list is not sorted.
3883 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3884 [InitISOFS, Always, TestOutput (
3885 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3886 InitISOFS, Always, TestOutput (
3887 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3888 InitISOFS, Always, TestOutput (
3889 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3890 InitISOFS, Always, TestLastFail (
3891 [["case_sensitive_path"; "/Known-1/"]]);
3892 InitBasicFS, Always, TestOutput (
3894 ["mkdir"; "/a/bbb"];
3895 ["touch"; "/a/bbb/c"];
3896 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3897 InitBasicFS, Always, TestOutput (
3899 ["mkdir"; "/a/bbb"];
3900 ["touch"; "/a/bbb/c"];
3901 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3902 InitBasicFS, Always, TestLastFail (
3904 ["mkdir"; "/a/bbb"];
3905 ["touch"; "/a/bbb/c"];
3906 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3907 "return true path on case-insensitive filesystem",
3909 This can be used to resolve case insensitive paths on
3910 a filesystem which is case sensitive. The use case is
3911 to resolve paths which you have read from Windows configuration
3912 files or the Windows Registry, to the true path.
3914 The command handles a peculiarity of the Linux ntfs-3g
3915 filesystem driver (and probably others), which is that although
3916 the underlying filesystem is case-insensitive, the driver
3917 exports the filesystem to Linux as case-sensitive.
3919 One consequence of this is that special directories such
3920 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3921 (or other things) depending on the precise details of how
3922 they were created. In Windows itself this would not be
3925 Bug or feature? You decide:
3926 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3928 This function resolves the true case of each element in the
3929 path and returns the case-sensitive path.
3931 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3932 might return C<\"/WINDOWS/system32\"> (the exact return value
3933 would depend on details of how the directories were originally
3934 created under Windows).
3937 This function does not handle drive names, backslashes etc.
3939 See also C<guestfs_realpath>.");
3941 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3942 [InitBasicFS, Always, TestOutput (
3943 [["vfs_type"; "/dev/sda1"]], "ext2")],
3944 "get the Linux VFS type corresponding to a mounted device",
3946 This command gets the filesystem type corresponding to
3947 the filesystem on C<device>.
3949 For most filesystems, the result is the name of the Linux
3950 VFS module which would be used to mount this filesystem
3951 if you mounted it without specifying the filesystem type.
3952 For example a string such as C<ext3> or C<ntfs>.");
3954 ("truncate", (RErr, [Pathname "path"]), 199, [],
3955 [InitBasicFS, Always, TestOutputStruct (
3956 [["write"; "/test"; "some stuff so size is not zero"];
3957 ["truncate"; "/test"];
3958 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3959 "truncate a file to zero size",
3961 This command truncates C<path> to a zero-length file. The
3962 file must exist already.");
3964 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3965 [InitBasicFS, Always, TestOutputStruct (
3966 [["touch"; "/test"];
3967 ["truncate_size"; "/test"; "1000"];
3968 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3969 "truncate a file to a particular size",
3971 This command truncates C<path> to size C<size> bytes. The file
3974 If the current file size is less than C<size> then
3975 the file is extended to the required size with zero bytes.
3976 This creates a sparse file (ie. disk blocks are not allocated
3977 for the file until you write to it). To create a non-sparse
3978 file of zeroes, use C<guestfs_fallocate64> instead.");
3980 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3981 [InitBasicFS, Always, TestOutputStruct (
3982 [["touch"; "/test"];
3983 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3984 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3985 "set timestamp of a file with nanosecond precision",
3987 This command sets the timestamps of a file with nanosecond
3990 C<atsecs, atnsecs> are the last access time (atime) in secs and
3991 nanoseconds from the epoch.
3993 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3994 secs and nanoseconds from the epoch.
3996 If the C<*nsecs> field contains the special value C<-1> then
3997 the corresponding timestamp is set to the current time. (The
3998 C<*secs> field is ignored in this case).
4000 If the C<*nsecs> field contains the special value C<-2> then
4001 the corresponding timestamp is left unchanged. (The
4002 C<*secs> field is ignored in this case).");
4004 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
4005 [InitBasicFS, Always, TestOutputStruct (
4006 [["mkdir_mode"; "/test"; "0o111"];
4007 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
4008 "create a directory with a particular mode",
4010 This command creates a directory, setting the initial permissions
4011 of the directory to C<mode>.
4013 For common Linux filesystems, the actual mode which is set will
4014 be C<mode & ~umask & 01777>. Non-native-Linux filesystems may
4015 interpret the mode in other ways.
4017 See also C<guestfs_mkdir>, C<guestfs_umask>");
4019 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
4021 "change file owner and group",
4023 Change the file owner to C<owner> and group to C<group>.
4024 This is like C<guestfs_chown> but if C<path> is a symlink then
4025 the link itself is changed, not the target.
4027 Only numeric uid and gid are supported. If you want to use
4028 names, you will need to locate and parse the password file
4029 yourself (Augeas support makes this relatively easy).");
4031 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
4033 "lstat on multiple files",
4035 This call allows you to perform the C<guestfs_lstat> operation
4036 on multiple files, where all files are in the directory C<path>.
4037 C<names> is the list of files from this directory.
4039 On return you get a list of stat structs, with a one-to-one
4040 correspondence to the C<names> list. If any name did not exist
4041 or could not be lstat'd, then the C<ino> field of that structure
4044 This call is intended for programs that want to efficiently
4045 list a directory contents without making many round-trips.
4046 See also C<guestfs_lxattrlist> for a similarly efficient call
4047 for getting extended attributes. Very long directory listings
4048 might cause the protocol message size to be exceeded, causing
4049 this call to fail. The caller must split up such requests
4050 into smaller groups of names.");
4052 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [Optional "linuxxattrs"],
4054 "lgetxattr on multiple files",
4056 This call allows you to get the extended attributes
4057 of multiple files, where all files are in the directory C<path>.
4058 C<names> is the list of files from this directory.
4060 On return you get a flat list of xattr structs which must be
4061 interpreted sequentially. The first xattr struct always has a zero-length
4062 C<attrname>. C<attrval> in this struct is zero-length
4063 to indicate there was an error doing C<lgetxattr> for this
4064 file, I<or> is a C string which is a decimal number
4065 (the number of following attributes for this file, which could
4066 be C<\"0\">). Then after the first xattr struct are the
4067 zero or more attributes for the first named file.
4068 This repeats for the second and subsequent files.
4070 This call is intended for programs that want to efficiently
4071 list a directory contents without making many round-trips.
4072 See also C<guestfs_lstatlist> for a similarly efficient call
4073 for getting standard stats. Very long directory listings
4074 might cause the protocol message size to be exceeded, causing
4075 this call to fail. The caller must split up such requests
4076 into smaller groups of names.");
4078 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
4080 "readlink on multiple files",
4082 This call allows you to do a C<readlink> operation
4083 on multiple files, where all files are in the directory C<path>.
4084 C<names> is the list of files from this directory.
4086 On return you get a list of strings, with a one-to-one
4087 correspondence to the C<names> list. Each string is the
4088 value of the symbolic link.
4090 If the C<readlink(2)> operation fails on any name, then
4091 the corresponding result string is the empty string C<\"\">.
4092 However the whole operation is completed even if there
4093 were C<readlink(2)> errors, and so you can call this
4094 function with names where you don't know if they are
4095 symbolic links already (albeit slightly less efficient).
4097 This call is intended for programs that want to efficiently
4098 list a directory contents without making many round-trips.
4099 Very long directory listings might cause the protocol
4100 message size to be exceeded, causing
4101 this call to fail. The caller must split up such requests
4102 into smaller groups of names.");
4104 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
4105 [InitISOFS, Always, TestOutputBuffer (
4106 [["pread"; "/known-4"; "1"; "3"]], "\n");
4107 InitISOFS, Always, TestOutputBuffer (
4108 [["pread"; "/empty"; "0"; "100"]], "")],
4109 "read part of a file",
4111 This command lets you read part of a file. It reads C<count>
4112 bytes of the file, starting at C<offset>, from file C<path>.
4114 This may read fewer bytes than requested. For further details
4115 see the L<pread(2)> system call.
4117 See also C<guestfs_pwrite>.");
4119 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
4120 [InitEmpty, Always, TestRun (
4121 [["part_init"; "/dev/sda"; "gpt"]])],
4122 "create an empty partition table",
4124 This creates an empty partition table on C<device> of one of the
4125 partition types listed below. Usually C<parttype> should be
4126 either C<msdos> or C<gpt> (for large disks).
4128 Initially there are no partitions. Following this, you should
4129 call C<guestfs_part_add> for each partition required.
4131 Possible values for C<parttype> are:
4135 =item B<efi> | B<gpt>
4137 Intel EFI / GPT partition table.
4139 This is recommended for >= 2 TB partitions that will be accessed
4140 from Linux and Intel-based Mac OS X. It also has limited backwards
4141 compatibility with the C<mbr> format.
4143 =item B<mbr> | B<msdos>
4145 The standard PC \"Master Boot Record\" (MBR) format used
4146 by MS-DOS and Windows. This partition type will B<only> work
4147 for device sizes up to 2 TB. For large disks we recommend
4152 Other partition table types that may work but are not
4161 =item B<amiga> | B<rdb>
4163 Amiga \"Rigid Disk Block\" format.
4171 DASD, used on IBM mainframes.
4179 Old Mac partition format. Modern Macs use C<gpt>.
4183 NEC PC-98 format, common in Japan apparently.
4191 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
4192 [InitEmpty, Always, TestRun (
4193 [["part_init"; "/dev/sda"; "mbr"];
4194 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
4195 InitEmpty, Always, TestRun (
4196 [["part_init"; "/dev/sda"; "gpt"];
4197 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
4198 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
4199 InitEmpty, Always, TestRun (
4200 [["part_init"; "/dev/sda"; "mbr"];
4201 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
4202 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
4203 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
4204 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
4205 "add a partition to the device",
4207 This command adds a partition to C<device>. If there is no partition
4208 table on the device, call C<guestfs_part_init> first.
4210 The C<prlogex> parameter is the type of partition. Normally you
4211 should pass C<p> or C<primary> here, but MBR partition tables also
4212 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4215 C<startsect> and C<endsect> are the start and end of the partition
4216 in I<sectors>. C<endsect> may be negative, which means it counts
4217 backwards from the end of the disk (C<-1> is the last sector).
4219 Creating a partition which covers the whole disk is not so easy.
4220 Use C<guestfs_part_disk> to do that.");
4222 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4223 [InitEmpty, Always, TestRun (
4224 [["part_disk"; "/dev/sda"; "mbr"]]);
4225 InitEmpty, Always, TestRun (
4226 [["part_disk"; "/dev/sda"; "gpt"]])],
4227 "partition whole disk with a single primary partition",
4229 This command is simply a combination of C<guestfs_part_init>
4230 followed by C<guestfs_part_add> to create a single primary partition
4231 covering the whole disk.
4233 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4234 but other possible values are described in C<guestfs_part_init>.");
4236 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4237 [InitEmpty, Always, TestRun (
4238 [["part_disk"; "/dev/sda"; "mbr"];
4239 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4240 "make a partition bootable",
4242 This sets the bootable flag on partition numbered C<partnum> on
4243 device C<device>. Note that partitions are numbered from 1.
4245 The bootable flag is used by some operating systems (notably
4246 Windows) to determine which partition to boot from. It is by
4247 no means universally recognized.");
4249 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4250 [InitEmpty, Always, TestRun (
4251 [["part_disk"; "/dev/sda"; "gpt"];
4252 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4253 "set partition name",
4255 This sets the partition name on partition numbered C<partnum> on
4256 device C<device>. Note that partitions are numbered from 1.
4258 The partition name can only be set on certain types of partition
4259 table. This works on C<gpt> but not on C<mbr> partitions.");
4261 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4262 [], (* XXX Add a regression test for this. *)
4263 "list partitions on a device",
4265 This command parses the partition table on C<device> and
4266 returns the list of partitions found.
4268 The fields in the returned structure are:
4274 Partition number, counting from 1.
4278 Start of the partition I<in bytes>. To get sectors you have to
4279 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4283 End of the partition in bytes.
4287 Size of the partition in bytes.
4291 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4292 [InitEmpty, Always, TestOutput (
4293 [["part_disk"; "/dev/sda"; "gpt"];
4294 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4295 "get the partition table type",
4297 This command examines the partition table on C<device> and
4298 returns the partition table type (format) being used.
4300 Common return values include: C<msdos> (a DOS/Windows style MBR
4301 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4302 values are possible, although unusual. See C<guestfs_part_init>
4305 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4306 [InitBasicFS, Always, TestOutputBuffer (
4307 [["fill"; "0x63"; "10"; "/test"];
4308 ["read_file"; "/test"]], "cccccccccc")],
4309 "fill a file with octets",
4311 This command creates a new file called C<path>. The initial
4312 content of the file is C<len> octets of C<c>, where C<c>
4313 must be a number in the range C<[0..255]>.
4315 To fill a file with zero bytes (sparsely), it is
4316 much more efficient to use C<guestfs_truncate_size>.
4317 To create a file with a pattern of repeating bytes
4318 use C<guestfs_fill_pattern>.");
4320 ("available", (RErr, [StringList "groups"]), 216, [],
4321 [InitNone, Always, TestRun [["available"; ""]]],
4322 "test availability of some parts of the API",
4324 This command is used to check the availability of some
4325 groups of functionality in the appliance, which not all builds of
4326 the libguestfs appliance will be able to provide.
4328 The libguestfs groups, and the functions that those
4329 groups correspond to, are listed in L<guestfs(3)/AVAILABILITY>.
4330 You can also fetch this list at runtime by calling
4331 C<guestfs_available_all_groups>.
4333 The argument C<groups> is a list of group names, eg:
4334 C<[\"inotify\", \"augeas\"]> would check for the availability of
4335 the Linux inotify functions and Augeas (configuration file
4338 The command returns no error if I<all> requested groups are available.
4340 It fails with an error if one or more of the requested
4341 groups is unavailable in the appliance.
4343 If an unknown group name is included in the
4344 list of groups then an error is always returned.
4352 You must call C<guestfs_launch> before calling this function.
4354 The reason is because we don't know what groups are
4355 supported by the appliance/daemon until it is running and can
4360 If a group of functions is available, this does not necessarily
4361 mean that they will work. You still have to check for errors
4362 when calling individual API functions even if they are
4367 It is usually the job of distro packagers to build
4368 complete functionality into the libguestfs appliance.
4369 Upstream libguestfs, if built from source with all
4370 requirements satisfied, will support everything.
4374 This call was added in version C<1.0.80>. In previous
4375 versions of libguestfs all you could do would be to speculatively
4376 execute a command to find out if the daemon implemented it.
4377 See also C<guestfs_version>.
4381 ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [],
4382 [InitBasicFS, Always, TestOutputBuffer (
4383 [["write"; "/src"; "hello, world"];
4384 ["dd"; "/src"; "/dest"];
4385 ["read_file"; "/dest"]], "hello, world")],
4386 "copy from source to destination using dd",
4388 This command copies from one source device or file C<src>
4389 to another destination device or file C<dest>. Normally you
4390 would use this to copy to or from a device or partition, for
4391 example to duplicate a filesystem.
4393 If the destination is a device, it must be as large or larger
4394 than the source file or device, otherwise the copy will fail.
4395 This command cannot do partial copies (see C<guestfs_copy_size>).");
4397 ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
4398 [InitBasicFS, Always, TestOutputInt (
4399 [["write"; "/file"; "hello, world"];
4400 ["filesize"; "/file"]], 12)],
4401 "return the size of the file in bytes",
4403 This command returns the size of C<file> in bytes.
4405 To get other stats about a file, use C<guestfs_stat>, C<guestfs_lstat>,
4406 C<guestfs_is_dir>, C<guestfs_is_file> etc.
4407 To get the size of block devices, use C<guestfs_blockdev_getsize64>.");
4409 ("lvrename", (RErr, [String "logvol"; String "newlogvol"]), 219, [],
4410 [InitBasicFSonLVM, Always, TestOutputList (
4411 [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
4412 ["lvs"]], ["/dev/VG/LV2"])],
4413 "rename an LVM logical volume",
4415 Rename a logical volume C<logvol> with the new name C<newlogvol>.");
4417 ("vgrename", (RErr, [String "volgroup"; String "newvolgroup"]), 220, [],
4418 [InitBasicFSonLVM, Always, TestOutputList (
4420 ["vg_activate"; "false"; "VG"];
4421 ["vgrename"; "VG"; "VG2"];
4422 ["vg_activate"; "true"; "VG2"];
4423 ["mount_options"; ""; "/dev/VG2/LV"; "/"];
4424 ["vgs"]], ["VG2"])],
4425 "rename an LVM volume group",
4427 Rename a volume group C<volgroup> with the new name C<newvolgroup>.");
4429 ("initrd_cat", (RBufferOut "content", [Pathname "initrdpath"; String "filename"]), 221, [ProtocolLimitWarning],
4430 [InitISOFS, Always, TestOutputBuffer (
4431 [["initrd_cat"; "/initrd"; "known-4"]], "abc\ndef\nghi")],
4432 "list the contents of a single file in an initrd",
4434 This command unpacks the file C<filename> from the initrd file
4435 called C<initrdpath>. The filename must be given I<without> the
4436 initial C</> character.
4438 For example, in guestfish you could use the following command
4439 to examine the boot script (usually called C</init>)
4440 contained in a Linux initrd or initramfs image:
4442 initrd-cat /boot/initrd-<version>.img init
4444 See also C<guestfs_initrd_list>.");
4446 ("pvuuid", (RString "uuid", [Device "device"]), 222, [],
4448 "get the UUID of a physical volume",
4450 This command returns the UUID of the LVM PV C<device>.");
4452 ("vguuid", (RString "uuid", [String "vgname"]), 223, [],
4454 "get the UUID of a volume group",
4456 This command returns the UUID of the LVM VG named C<vgname>.");
4458 ("lvuuid", (RString "uuid", [Device "device"]), 224, [],
4460 "get the UUID of a logical volume",
4462 This command returns the UUID of the LVM LV C<device>.");
4464 ("vgpvuuids", (RStringList "uuids", [String "vgname"]), 225, [],
4466 "get the PV UUIDs containing the volume group",
4468 Given a VG called C<vgname>, this returns the UUIDs of all
4469 the physical volumes that this volume group resides on.
4471 You can use this along with C<guestfs_pvs> and C<guestfs_pvuuid>
4472 calls to associate physical volumes and volume groups.
4474 See also C<guestfs_vglvuuids>.");
4476 ("vglvuuids", (RStringList "uuids", [String "vgname"]), 226, [],
4478 "get the LV UUIDs of all LVs in the volume group",
4480 Given a VG called C<vgname>, this returns the UUIDs of all
4481 the logical volumes created in this volume group.
4483 You can use this along with C<guestfs_lvs> and C<guestfs_lvuuid>
4484 calls to associate logical volumes and volume groups.
4486 See also C<guestfs_vgpvuuids>.");
4488 ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
4489 [InitBasicFS, Always, TestOutputBuffer (
4490 [["write"; "/src"; "hello, world"];
4491 ["copy_size"; "/src"; "/dest"; "5"];
4492 ["read_file"; "/dest"]], "hello")],
4493 "copy size bytes from source to destination using dd",
4495 This command copies exactly C<size> bytes from one source device
4496 or file C<src> to another destination device or file C<dest>.
4498 Note this will fail if the source is too short or if the destination
4499 is not large enough.");
4501 ("zero_device", (RErr, [Device "device"]), 228, [DangerWillRobinson],
4502 [InitBasicFSonLVM, Always, TestRun (
4503 [["zero_device"; "/dev/VG/LV"]])],
4504 "write zeroes to an entire device",
4506 This command writes zeroes over the entire C<device>. Compare
4507 with C<guestfs_zero> which just zeroes the first few blocks of
4510 ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"],
4511 [InitBasicFS, Always, TestOutput (
4512 [["txz_in"; "../images/helloworld.tar.xz"; "/"];
4513 ["cat"; "/hello"]], "hello\n")],
4514 "unpack compressed tarball to directory",
4516 This command uploads and unpacks local file C<tarball> (an
4517 I<xz compressed> tar file) into C<directory>.");
4519 ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"],
4521 "pack directory into compressed tarball",
4523 This command packs the contents of C<directory> and downloads
4524 it to local file C<tarball> (as an xz compressed tar archive).");
4526 ("ntfsresize", (RErr, [Device "device"]), 231, [Optional "ntfsprogs"],
4528 "resize an NTFS filesystem",
4530 This command resizes an NTFS filesystem, expanding or
4531 shrinking it to the size of the underlying device.
4532 See also L<ntfsresize(8)>.");
4534 ("vgscan", (RErr, []), 232, [],
4535 [InitEmpty, Always, TestRun (
4537 "rescan for LVM physical volumes, volume groups and logical volumes",
4539 This rescans all block devices and rebuilds the list of LVM
4540 physical volumes, volume groups and logical volumes.");
4542 ("part_del", (RErr, [Device "device"; Int "partnum"]), 233, [],
4543 [InitEmpty, Always, TestRun (
4544 [["part_init"; "/dev/sda"; "mbr"];
4545 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4546 ["part_del"; "/dev/sda"; "1"]])],
4547 "delete a partition",
4549 This command deletes the partition numbered C<partnum> on C<device>.
4551 Note that in the case of MBR partitioning, deleting an
4552 extended partition also deletes any logical partitions
4555 ("part_get_bootable", (RBool "bootable", [Device "device"; Int "partnum"]), 234, [],
4556 [InitEmpty, Always, TestOutputTrue (
4557 [["part_init"; "/dev/sda"; "mbr"];
4558 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4559 ["part_set_bootable"; "/dev/sda"; "1"; "true"];
4560 ["part_get_bootable"; "/dev/sda"; "1"]])],
4561 "return true if a partition is bootable",
4563 This command returns true if the partition C<partnum> on
4564 C<device> has the bootable flag set.
4566 See also C<guestfs_part_set_bootable>.");
4568 ("part_get_mbr_id", (RInt "idbyte", [Device "device"; Int "partnum"]), 235, [FishOutput FishOutputHexadecimal],
4569 [InitEmpty, Always, TestOutputInt (
4570 [["part_init"; "/dev/sda"; "mbr"];
4571 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4572 ["part_set_mbr_id"; "/dev/sda"; "1"; "0x7f"];
4573 ["part_get_mbr_id"; "/dev/sda"; "1"]], 0x7f)],
4574 "get the MBR type byte (ID byte) from a partition",
4576 Returns the MBR type byte (also known as the ID byte) from
4577 the numbered partition C<partnum>.
4579 Note that only MBR (old DOS-style) partitions have type bytes.
4580 You will get undefined results for other partition table
4581 types (see C<guestfs_part_get_parttype>).");
4583 ("part_set_mbr_id", (RErr, [Device "device"; Int "partnum"; Int "idbyte"]), 236, [],
4584 [], (* tested by part_get_mbr_id *)
4585 "set the MBR type byte (ID byte) of a partition",
4587 Sets the MBR type byte (also known as the ID byte) of
4588 the numbered partition C<partnum> to C<idbyte>. Note
4589 that the type bytes quoted in most documentation are
4590 in fact hexadecimal numbers, but usually documented
4591 without any leading \"0x\" which might be confusing.
4593 Note that only MBR (old DOS-style) partitions have type bytes.
4594 You will get undefined results for other partition table
4595 types (see C<guestfs_part_get_parttype>).");
4597 ("checksum_device", (RString "checksum", [String "csumtype"; Device "device"]), 237, [],
4598 [InitISOFS, Always, TestOutput (
4599 [["checksum_device"; "md5"; "/dev/sdd"]],
4600 (Digest.to_hex (Digest.file "images/test.iso")))],
4601 "compute MD5, SHAx or CRC checksum of the contents of a device",
4603 This call computes the MD5, SHAx or CRC checksum of the
4604 contents of the device named C<device>. For the types of
4605 checksums supported see the C<guestfs_checksum> command.");
4607 ("lvresize_free", (RErr, [Device "lv"; Int "percent"]), 238, [Optional "lvm2"],
4608 [InitNone, Always, TestRun (
4609 [["part_disk"; "/dev/sda"; "mbr"];
4610 ["pvcreate"; "/dev/sda1"];
4611 ["vgcreate"; "VG"; "/dev/sda1"];
4612 ["lvcreate"; "LV"; "VG"; "10"];
4613 ["lvresize_free"; "/dev/VG/LV"; "100"]])],
4614 "expand an LV to fill free space",
4616 This expands an existing logical volume C<lv> so that it fills
4617 C<pc>% of the remaining free space in the volume group. Commonly
4618 you would call this with pc = 100 which expands the logical volume
4619 as much as possible, using all remaining free space in the volume
4622 ("aug_clear", (RErr, [String "augpath"]), 239, [Optional "augeas"],
4623 [], (* XXX Augeas code needs tests. *)
4624 "clear Augeas path",
4626 Set the value associated with C<path> to C<NULL>. This
4627 is the same as the L<augtool(1)> C<clear> command.");
4629 ("get_umask", (RInt "mask", []), 240, [FishOutput FishOutputOctal],
4630 [InitEmpty, Always, TestOutputInt (
4631 [["get_umask"]], 0o22)],
4632 "get the current umask",
4634 Return the current umask. By default the umask is C<022>
4635 unless it has been set by calling C<guestfs_umask>.");
4637 ("debug_upload", (RErr, [FileIn "filename"; String "tmpname"; Int "mode"]), 241, [],
4639 "upload a file to the appliance (internal use only)",
4641 The C<guestfs_debug_upload> command uploads a file to
4642 the libguestfs appliance.
4644 There is no comprehensive help for this command. You have
4645 to look at the file C<daemon/debug.c> in the libguestfs source
4646 to find out what it is for.");
4648 ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
4649 [InitBasicFS, Always, TestOutput (
4650 [["base64_in"; "../images/hello.b64"; "/hello"];
4651 ["cat"; "/hello"]], "hello\n")],
4652 "upload base64-encoded data to file",
4654 This command uploads base64-encoded data from C<base64file>
4657 ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
4659 "download file and encode as base64",
4661 This command downloads the contents of C<filename>, writing
4662 it out to local file C<base64file> encoded as base64.");
4664 ("checksums_out", (RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"]), 244, [],
4666 "compute MD5, SHAx or CRC checksum of files in a directory",
4668 This command computes the checksums of all regular files in
4669 C<directory> and then emits a list of those checksums to
4670 the local output file C<sumsfile>.
4672 This can be used for verifying the integrity of a virtual
4673 machine. However to be properly secure you should pay
4674 attention to the output of the checksum command (it uses
4675 the ones from GNU coreutils). In particular when the
4676 filename is not printable, coreutils uses a special
4677 backslash syntax. For more information, see the GNU
4678 coreutils info file.");
4680 ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
4681 [InitBasicFS, Always, TestOutputBuffer (
4682 [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
4683 ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
4684 "fill a file with a repeating pattern of bytes",
4686 This function is like C<guestfs_fill> except that it creates
4687 a new file of length C<len> containing the repeating pattern
4688 of bytes in C<pattern>. The pattern is truncated if necessary
4689 to ensure the length of the file is exactly C<len> bytes.");
4691 ("write", (RErr, [Pathname "path"; BufferIn "content"]), 246, [ProtocolLimitWarning],
4692 [InitBasicFS, Always, TestOutput (
4693 [["write"; "/new"; "new file contents"];
4694 ["cat"; "/new"]], "new file contents");
4695 InitBasicFS, Always, TestOutput (
4696 [["write"; "/new"; "\nnew file contents\n"];
4697 ["cat"; "/new"]], "\nnew file contents\n");
4698 InitBasicFS, Always, TestOutput (
4699 [["write"; "/new"; "\n\n"];
4700 ["cat"; "/new"]], "\n\n");
4701 InitBasicFS, Always, TestOutput (
4702 [["write"; "/new"; ""];
4703 ["cat"; "/new"]], "");
4704 InitBasicFS, Always, TestOutput (
4705 [["write"; "/new"; "\n\n\n"];
4706 ["cat"; "/new"]], "\n\n\n");
4707 InitBasicFS, Always, TestOutput (
4708 [["write"; "/new"; "\n"];
4709 ["cat"; "/new"]], "\n")],
4710 "create a new file",
4712 This call creates a file called C<path>. The content of the
4713 file is the string C<content> (which can contain any 8 bit data).");
4715 ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
4716 [InitBasicFS, Always, TestOutput (
4717 [["write"; "/new"; "new file contents"];
4718 ["pwrite"; "/new"; "data"; "4"];
4719 ["cat"; "/new"]], "new data contents");
4720 InitBasicFS, Always, TestOutput (
4721 [["write"; "/new"; "new file contents"];
4722 ["pwrite"; "/new"; "is extended"; "9"];
4723 ["cat"; "/new"]], "new file is extended");
4724 InitBasicFS, Always, TestOutput (
4725 [["write"; "/new"; "new file contents"];
4726 ["pwrite"; "/new"; ""; "4"];
4727 ["cat"; "/new"]], "new file contents")],
4728 "write to part of a file",
4730 This command writes to part of a file. It writes the data
4731 buffer C<content> to the file C<path> starting at offset C<offset>.
4733 This command implements the L<pwrite(2)> system call, and like
4734 that system call it may not write the full data requested. The
4735 return value is the number of bytes that were actually written
4736 to the file. This could even be 0, although short writes are
4737 unlikely for regular files in ordinary circumstances.
4739 See also C<guestfs_pread>.");
4741 ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [],
4743 "resize an ext2, ext3 or ext4 filesystem (with size)",
4745 This command is the same as C<guestfs_resize2fs> except that it
4746 allows you to specify the new size (in bytes) explicitly.");
4748 ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"],
4750 "resize an LVM physical volume (with size)",
4752 This command is the same as C<guestfs_pvresize> except that it
4753 allows you to specify the new size (in bytes) explicitly.");
4755 ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"],
4757 "resize an NTFS filesystem (with size)",
4759 This command is the same as C<guestfs_ntfsresize> except that it
4760 allows you to specify the new size (in bytes) explicitly.");
4762 ("available_all_groups", (RStringList "groups", []), 251, [],
4763 [InitNone, Always, TestRun [["available_all_groups"]]],
4764 "return a list of all optional groups",
4766 This command returns a list of all optional groups that this
4767 daemon knows about. Note this returns both supported and unsupported
4768 groups. To find out which ones the daemon can actually support
4769 you have to call C<guestfs_available> on each member of the
4772 See also C<guestfs_available> and L<guestfs(3)/AVAILABILITY>.");
4774 ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [],
4775 [InitBasicFS, Always, TestOutputStruct (
4776 [["fallocate64"; "/a"; "1000000"];
4777 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
4778 "preallocate a file in the guest filesystem",
4780 This command preallocates a file (containing zero bytes) named
4781 C<path> of size C<len> bytes. If the file exists already, it
4784 Note that this call allocates disk blocks for the file.
4785 To create a sparse file use C<guestfs_truncate_size> instead.
4787 The deprecated call C<guestfs_fallocate> does the same,
4788 but owing to an oversight it only allowed 30 bit lengths
4789 to be specified, effectively limiting the maximum size
4790 of files created through that call to 1GB.
4792 Do not confuse this with the guestfish-specific
4793 C<alloc> and C<sparse> commands which create
4794 a file in the host and attach it as a device.");
4796 ("vfs_label", (RString "label", [Device "device"]), 253, [],
4797 [InitBasicFS, Always, TestOutput (
4798 [["set_e2label"; "/dev/sda1"; "LTEST"];
4799 ["vfs_label"; "/dev/sda1"]], "LTEST")],
4800 "get the filesystem label",
4802 This returns the filesystem label of the filesystem on
4805 If the filesystem is unlabeled, this returns the empty string.");
4807 ("vfs_uuid", (RString "uuid", [Device "device"]), 254, [],
4808 (let uuid = uuidgen () in
4809 [InitBasicFS, Always, TestOutput (
4810 [["set_e2uuid"; "/dev/sda1"; uuid];
4811 ["vfs_uuid"; "/dev/sda1"]], uuid)]),
4812 "get the filesystem UUID",
4814 This returns the filesystem UUID of the filesystem on
4817 If the filesystem does not have a UUID, this returns the empty string.");
4821 let all_functions = non_daemon_functions @ daemon_functions
4823 (* In some places we want the functions to be displayed sorted
4824 * alphabetically, so this is useful:
4826 let all_functions_sorted =
4827 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4828 compare n1 n2) all_functions
4830 (* This is used to generate the src/MAX_PROC_NR file which
4831 * contains the maximum procedure number, a surrogate for the
4832 * ABI version number. See src/Makefile.am for the details.
4835 let proc_nrs = List.map (
4836 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
4837 ) daemon_functions in
4838 List.fold_left max 0 proc_nrs
4840 (* Field types for structures. *)
4842 | FChar (* C 'char' (really, a 7 bit byte). *)
4843 | FString (* nul-terminated ASCII string, NOT NULL. *)
4844 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4849 | FBytes (* Any int measure that counts bytes. *)
4850 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4851 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4853 (* Because we generate extra parsing code for LVM command line tools,
4854 * we have to pull out the LVM columns separately here.
4864 "pv_attr", FString (* XXX *);
4865 "pv_pe_count", FInt64;
4866 "pv_pe_alloc_count", FInt64;
4869 "pv_mda_count", FInt64;
4870 "pv_mda_free", FBytes;
4871 (* Not in Fedora 10:
4872 "pv_mda_size", FBytes;
4879 "vg_attr", FString (* XXX *);
4882 "vg_sysid", FString;
4883 "vg_extent_size", FBytes;
4884 "vg_extent_count", FInt64;
4885 "vg_free_count", FInt64;
4890 "snap_count", FInt64;
4893 "vg_mda_count", FInt64;
4894 "vg_mda_free", FBytes;
4895 (* Not in Fedora 10:
4896 "vg_mda_size", FBytes;
4902 "lv_attr", FString (* XXX *);
4905 "lv_kernel_major", FInt64;
4906 "lv_kernel_minor", FInt64;
4908 "seg_count", FInt64;
4910 "snap_percent", FOptPercent;
4911 "copy_percent", FOptPercent;
4914 "mirror_log", FString;
4918 (* Names and fields in all structures (in RStruct and RStructList)
4922 (* The old RIntBool return type, only ever used for aug_defnode. Do
4923 * not use this struct in any new code.
4926 "i", FInt32; (* for historical compatibility *)
4927 "b", FInt32; (* for historical compatibility *)
4930 (* LVM PVs, VGs, LVs. *)
4931 "lvm_pv", lvm_pv_cols;
4932 "lvm_vg", lvm_vg_cols;
4933 "lvm_lv", lvm_lv_cols;
4935 (* Column names and types from stat structures.
4936 * NB. Can't use things like 'st_atime' because glibc header files
4937 * define some of these as macros. Ugh.
4968 (* Column names in dirent structure. *)
4971 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4976 (* Version numbers. *)
4984 (* Extended attribute. *)
4986 "attrname", FString;
4990 (* Inotify events. *)
4994 "in_cookie", FUInt32;
4998 (* Partition table entry. *)
5001 "part_start", FBytes;
5003 "part_size", FBytes;
5005 ] (* end of structs *)
5007 (* Ugh, Java has to be different ..
5008 * These names are also used by the Haskell bindings.
5010 let java_structs = [
5011 "int_bool", "IntBool";
5016 "statvfs", "StatVFS";
5018 "version", "Version";
5020 "inotify_event", "INotifyEvent";
5021 "partition", "Partition";
5024 (* What structs are actually returned. *)
5025 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
5027 (* Returns a list of RStruct/RStructList structs that are returned
5028 * by any function. Each element of returned list is a pair:
5030 * (structname, RStructOnly)
5031 * == there exists function which returns RStruct (_, structname)
5032 * (structname, RStructListOnly)
5033 * == there exists function which returns RStructList (_, structname)
5034 * (structname, RStructAndList)
5035 * == there are functions returning both RStruct (_, structname)
5036 * and RStructList (_, structname)
5038 let rstructs_used_by functions =
5039 (* ||| is a "logical OR" for rstructs_used_t *)
5043 | _, RStructAndList -> RStructAndList
5044 | RStructOnly, RStructListOnly
5045 | RStructListOnly, RStructOnly -> RStructAndList
5046 | RStructOnly, RStructOnly -> RStructOnly
5047 | RStructListOnly, RStructListOnly -> RStructListOnly
5050 let h = Hashtbl.create 13 in
5052 (* if elem->oldv exists, update entry using ||| operator,
5053 * else just add elem->newv to the hash
5055 let update elem newv =
5056 try let oldv = Hashtbl.find h elem in
5057 Hashtbl.replace h elem (newv ||| oldv)
5058 with Not_found -> Hashtbl.add h elem newv
5062 fun (_, style, _, _, _, _, _) ->
5063 match fst style with
5064 | RStruct (_, structname) -> update structname RStructOnly
5065 | RStructList (_, structname) -> update structname RStructListOnly
5069 (* return key->values as a list of (key,value) *)
5070 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
5072 (* Used for testing language bindings. *)
5074 | CallString of string
5075 | CallOptString of string option
5076 | CallStringList of string list
5078 | CallInt64 of int64
5080 | CallBuffer of string
5082 (* Used to memoize the result of pod2text. *)
5083 let pod2text_memo_filename = "src/.pod2text.data"
5084 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
5086 let chan = open_in pod2text_memo_filename in
5087 let v = input_value chan in
5091 _ -> Hashtbl.create 13
5092 let pod2text_memo_updated () =
5093 let chan = open_out pod2text_memo_filename in
5094 output_value chan pod2text_memo;
5097 (* Useful functions.
5098 * Note we don't want to use any external OCaml libraries which
5099 * makes this a bit harder than it should be.
5101 module StringMap = Map.Make (String)
5103 let failwithf fs = ksprintf failwith fs
5105 let unique = let i = ref 0 in fun () -> incr i; !i
5107 let replace_char s c1 c2 =
5108 let s2 = String.copy s in
5109 let r = ref false in
5110 for i = 0 to String.length s2 - 1 do
5111 if String.unsafe_get s2 i = c1 then (
5112 String.unsafe_set s2 i c2;
5116 if not !r then s else s2
5120 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
5122 let triml ?(test = isspace) str =
5124 let n = ref (String.length str) in
5125 while !n > 0 && test str.[!i]; do
5130 else String.sub str !i !n
5132 let trimr ?(test = isspace) str =
5133 let n = ref (String.length str) in
5134 while !n > 0 && test str.[!n-1]; do
5137 if !n = String.length str then str
5138 else String.sub str 0 !n
5140 let trim ?(test = isspace) str =
5141 trimr ~test (triml ~test str)
5143 let rec find s sub =
5144 let len = String.length s in
5145 let sublen = String.length sub in
5147 if i <= len-sublen then (
5149 if j < sublen then (
5150 if s.[i+j] = sub.[j] then loop2 (j+1)
5156 if r = -1 then loop (i+1) else r
5162 let rec replace_str s s1 s2 =
5163 let len = String.length s in
5164 let sublen = String.length s1 in
5165 let i = find s s1 in
5168 let s' = String.sub s 0 i in
5169 let s'' = String.sub s (i+sublen) (len-i-sublen) in
5170 s' ^ s2 ^ replace_str s'' s1 s2
5173 let rec string_split sep str =
5174 let len = String.length str in
5175 let seplen = String.length sep in
5176 let i = find str sep in
5177 if i = -1 then [str]
5179 let s' = String.sub str 0 i in
5180 let s'' = String.sub str (i+seplen) (len-i-seplen) in
5181 s' :: string_split sep s''
5184 let files_equal n1 n2 =
5185 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
5186 match Sys.command cmd with
5189 | i -> failwithf "%s: failed with error code %d" cmd i
5191 let rec filter_map f = function
5195 | Some y -> y :: filter_map f xs
5196 | None -> filter_map f xs
5198 let rec find_map f = function
5199 | [] -> raise Not_found
5203 | None -> find_map f xs
5206 let rec loop i = function
5208 | x :: xs -> f i x; loop (i+1) xs
5213 let rec loop i = function
5215 | x :: xs -> let r = f i x in r :: loop (i+1) xs
5219 let count_chars c str =
5220 let count = ref 0 in
5221 for i = 0 to String.length str - 1 do
5222 if c = String.unsafe_get str i then incr count
5228 for i = 0 to String.length str - 1 do
5229 let c = String.unsafe_get str i in
5234 let map_chars f str =
5235 List.map f (explode str)
5237 let name_of_argt = function
5238 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
5239 | StringList n | DeviceList n | Bool n | Int n | Int64 n
5240 | FileIn n | FileOut n | BufferIn n -> n
5242 let java_name_of_struct typ =
5243 try List.assoc typ java_structs
5246 "java_name_of_struct: no java_structs entry corresponding to %s" typ
5248 let cols_of_struct typ =
5249 try List.assoc typ structs
5251 failwithf "cols_of_struct: unknown struct %s" typ
5253 let seq_of_test = function
5254 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
5255 | TestOutputListOfDevices (s, _)
5256 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
5257 | TestOutputTrue s | TestOutputFalse s
5258 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
5259 | TestOutputStruct (s, _)
5260 | TestLastFail s -> s
5262 (* Handling for function flags. *)
5263 let protocol_limit_warning =
5264 "Because of the message protocol, there is a transfer limit
5265 of somewhere between 2MB and 4MB. See L<guestfs(3)/PROTOCOL LIMITS>."
5267 let danger_will_robinson =
5268 "B<This command is dangerous. Without careful use you
5269 can easily destroy all your data>."
5271 let deprecation_notice flags =
5274 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
5276 sprintf "This function is deprecated.
5277 In new code, use the C<%s> call instead.
5279 Deprecated functions will not be removed from the API, but the
5280 fact that they are deprecated indicates that there are problems
5281 with correct use of these functions." alt in
5286 (* Create list of optional groups. *)
5288 let h = Hashtbl.create 13 in
5290 fun (name, _, _, flags, _, _, _) ->
5294 let names = try Hashtbl.find h group with Not_found -> [] in
5295 Hashtbl.replace h group (name :: names)
5299 let groups = Hashtbl.fold (fun k _ ks -> k :: ks) h [] in
5302 fun group -> group, List.sort compare (Hashtbl.find h group)
5304 List.sort (fun x y -> compare (fst x) (fst y)) groups
5306 (* Check function names etc. for consistency. *)
5307 let check_functions () =
5308 let contains_uppercase str =
5309 let len = String.length str in
5311 if i >= len then false
5314 if c >= 'A' && c <= 'Z' then true
5321 (* Check function names. *)
5323 fun (name, _, _, _, _, _, _) ->
5324 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
5325 failwithf "function name %s does not need 'guestfs' prefix" name;
5327 failwithf "function name is empty";
5328 if name.[0] < 'a' || name.[0] > 'z' then
5329 failwithf "function name %s must start with lowercase a-z" name;
5330 if String.contains name '-' then
5331 failwithf "function name %s should not contain '-', use '_' instead."
5335 (* Check function parameter/return names. *)
5337 fun (name, style, _, _, _, _, _) ->
5338 let check_arg_ret_name n =
5339 if contains_uppercase n then
5340 failwithf "%s param/ret %s should not contain uppercase chars"
5342 if String.contains n '-' || String.contains n '_' then
5343 failwithf "%s param/ret %s should not contain '-' or '_'"
5346 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;
5347 if n = "int" || n = "char" || n = "short" || n = "long" then
5348 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
5349 if n = "i" || n = "n" then
5350 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
5351 if n = "argv" || n = "args" then
5352 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
5354 (* List Haskell, OCaml and C keywords here.
5355 * http://www.haskell.org/haskellwiki/Keywords
5356 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
5357 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
5358 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
5359 * |perl -pe 's/(.+)/"$1";/'|fmt -70
5360 * Omitting _-containing words, since they're handled above.
5361 * Omitting the OCaml reserved word, "val", is ok,
5362 * and saves us from renaming several parameters.
5365 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
5366 "char"; "class"; "const"; "constraint"; "continue"; "data";
5367 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
5368 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
5369 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
5370 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
5371 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
5373 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
5374 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
5375 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
5376 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
5377 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
5378 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
5379 "volatile"; "when"; "where"; "while";
5381 if List.mem n reserved then
5382 failwithf "%s has param/ret using reserved word %s" name n;
5385 (match fst style with
5387 | RInt n | RInt64 n | RBool n
5388 | RConstString n | RConstOptString n | RString n
5389 | RStringList n | RStruct (n, _) | RStructList (n, _)
5390 | RHashtable n | RBufferOut n ->
5391 check_arg_ret_name n
5393 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
5396 (* Check short descriptions. *)
5398 fun (name, _, _, _, _, shortdesc, _) ->
5399 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
5400 failwithf "short description of %s should begin with lowercase." name;
5401 let c = shortdesc.[String.length shortdesc-1] in
5402 if c = '\n' || c = '.' then
5403 failwithf "short description of %s should not end with . or \\n." name
5406 (* Check long descriptions. *)
5408 fun (name, _, _, _, _, _, longdesc) ->
5409 if longdesc.[String.length longdesc-1] = '\n' then
5410 failwithf "long description of %s should not end with \\n." name
5413 (* Check proc_nrs. *)
5415 fun (name, _, proc_nr, _, _, _, _) ->
5416 if proc_nr <= 0 then
5417 failwithf "daemon function %s should have proc_nr > 0" name
5421 fun (name, _, proc_nr, _, _, _, _) ->
5422 if proc_nr <> -1 then
5423 failwithf "non-daemon function %s should have proc_nr -1" name
5424 ) non_daemon_functions;
5427 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
5430 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
5431 let rec loop = function
5434 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
5436 | (name1,nr1) :: (name2,nr2) :: _ ->
5437 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
5445 (* Ignore functions that have no tests. We generate a
5446 * warning when the user does 'make check' instead.
5448 | name, _, _, _, [], _, _ -> ()
5449 | name, _, _, _, tests, _, _ ->
5453 match seq_of_test test with
5455 failwithf "%s has a test containing an empty sequence" name
5456 | cmds -> List.map List.hd cmds
5458 let funcs = List.flatten funcs in
5460 let tested = List.mem name funcs in
5463 failwithf "function %s has tests but does not test itself" name
5466 (* 'pr' prints to the current output file. *)
5467 let chan = ref Pervasives.stdout
5472 let i = count_chars '\n' str in
5473 lines := !lines + i;
5474 output_string !chan str
5477 let copyright_years =
5478 let this_year = 1900 + (localtime (time ())).tm_year in
5479 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
5481 (* Generate a header block in a number of standard styles. *)
5482 type comment_style =
5483 CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
5484 type license = GPLv2plus | LGPLv2plus
5486 let generate_header ?(extra_inputs = []) comment license =
5487 let inputs = "src/generator.ml" :: extra_inputs in
5488 let c = match comment with
5489 | CStyle -> pr "/* "; " *"
5490 | CPlusPlusStyle -> pr "// "; "//"
5491 | HashStyle -> pr "# "; "#"
5492 | OCamlStyle -> pr "(* "; " *"
5493 | HaskellStyle -> pr "{- "; " " in
5494 pr "libguestfs generated file\n";
5495 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
5496 List.iter (pr "%s %s\n" c) inputs;
5497 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
5499 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
5503 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
5504 pr "%s it under the terms of the GNU General Public License as published by\n" c;
5505 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
5506 pr "%s (at your option) any later version.\n" c;
5508 pr "%s This program is distributed in the hope that it will be useful,\n" c;
5509 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5510 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
5511 pr "%s GNU General Public License for more details.\n" c;
5513 pr "%s You should have received a copy of the GNU General Public License along\n" c;
5514 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
5515 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
5518 pr "%s This library is free software; you can redistribute it and/or\n" c;
5519 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
5520 pr "%s License as published by the Free Software Foundation; either\n" c;
5521 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
5523 pr "%s This library is distributed in the hope that it will be useful,\n" c;
5524 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5525 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
5526 pr "%s Lesser General Public License for more details.\n" c;
5528 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
5529 pr "%s License along with this library; if not, write to the Free Software\n" c;
5530 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
5533 | CStyle -> pr " */\n"
5536 | OCamlStyle -> pr " *)\n"
5537 | HaskellStyle -> pr "-}\n"
5541 (* Start of main code generation functions below this line. *)
5543 (* Generate the pod documentation for the C API. *)
5544 let rec generate_actions_pod () =
5546 fun (shortname, style, _, flags, _, _, longdesc) ->
5547 if not (List.mem NotInDocs flags) then (
5548 let name = "guestfs_" ^ shortname in
5549 pr "=head2 %s\n\n" name;
5551 generate_prototype ~extern:false ~handle:"g" name style;
5553 pr "%s\n\n" longdesc;
5554 (match fst style with
5556 pr "This function returns 0 on success or -1 on error.\n\n"
5558 pr "On error this function returns -1.\n\n"
5560 pr "On error this function returns -1.\n\n"
5562 pr "This function returns a C truth value on success or -1 on error.\n\n"
5564 pr "This function returns a string, or NULL on error.
5565 The string is owned by the guest handle and must I<not> be freed.\n\n"
5566 | RConstOptString _ ->
5567 pr "This function returns a string which may be NULL.
5568 There is way to return an error from this function.
5569 The string is owned by the guest handle and must I<not> be freed.\n\n"
5571 pr "This function returns a string, or NULL on error.
5572 I<The caller must free the returned string after use>.\n\n"
5574 pr "This function returns a NULL-terminated array of strings
5575 (like L<environ(3)>), or NULL if there was an error.
5576 I<The caller must free the strings and the array after use>.\n\n"
5577 | RStruct (_, typ) ->
5578 pr "This function returns a C<struct guestfs_%s *>,
5579 or NULL if there was an error.
5580 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
5581 | RStructList (_, typ) ->
5582 pr "This function returns a C<struct guestfs_%s_list *>
5583 (see E<lt>guestfs-structs.hE<gt>),
5584 or NULL if there was an error.
5585 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
5587 pr "This function returns a NULL-terminated array of
5588 strings, or NULL if there was an error.
5589 The array of strings will always have length C<2n+1>, where
5590 C<n> keys and values alternate, followed by the trailing NULL entry.
5591 I<The caller must free the strings and the array after use>.\n\n"
5593 pr "This function returns a buffer, or NULL on error.
5594 The size of the returned buffer is written to C<*size_r>.
5595 I<The caller must free the returned buffer after use>.\n\n"
5597 if List.mem ProtocolLimitWarning flags then
5598 pr "%s\n\n" protocol_limit_warning;
5599 if List.mem DangerWillRobinson flags then
5600 pr "%s\n\n" danger_will_robinson;
5601 match deprecation_notice flags with
5603 | Some txt -> pr "%s\n\n" txt
5605 ) all_functions_sorted
5607 and generate_structs_pod () =
5608 (* Structs documentation. *)
5611 pr "=head2 guestfs_%s\n" typ;
5613 pr " struct guestfs_%s {\n" typ;
5616 | name, FChar -> pr " char %s;\n" name
5617 | name, FUInt32 -> pr " uint32_t %s;\n" name
5618 | name, FInt32 -> pr " int32_t %s;\n" name
5619 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5620 | name, FInt64 -> pr " int64_t %s;\n" name
5621 | name, FString -> pr " char *%s;\n" name
5623 pr " /* The next two fields describe a byte array. */\n";
5624 pr " uint32_t %s_len;\n" name;
5625 pr " char *%s;\n" name
5627 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
5628 pr " char %s[32];\n" name
5629 | name, FOptPercent ->
5630 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
5631 pr " float %s;\n" name
5635 pr " struct guestfs_%s_list {\n" typ;
5636 pr " uint32_t len; /* Number of elements in list. */\n";
5637 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
5640 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
5641 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
5646 and generate_availability_pod () =
5647 (* Availability documentation. *)
5651 fun (group, functions) ->
5652 pr "=item B<%s>\n" group;
5654 pr "The following functions:\n";
5655 List.iter (pr "L</guestfs_%s>\n") functions;
5661 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
5662 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
5664 * We have to use an underscore instead of a dash because otherwise
5665 * rpcgen generates incorrect code.
5667 * This header is NOT exported to clients, but see also generate_structs_h.
5669 and generate_xdr () =
5670 generate_header CStyle LGPLv2plus;
5672 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
5673 pr "typedef string str<>;\n";
5676 (* Internal structures. *)
5680 pr "struct guestfs_int_%s {\n" typ;
5682 | name, FChar -> pr " char %s;\n" name
5683 | name, FString -> pr " string %s<>;\n" name
5684 | name, FBuffer -> pr " opaque %s<>;\n" name
5685 | name, FUUID -> pr " opaque %s[32];\n" name
5686 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
5687 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
5688 | name, FOptPercent -> pr " float %s;\n" name
5692 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
5697 fun (shortname, style, _, _, _, _, _) ->
5698 let name = "guestfs_" ^ shortname in
5700 (match snd style with
5703 pr "struct %s_args {\n" name;
5706 | Pathname n | Device n | Dev_or_Path n | String n ->
5707 pr " string %s<>;\n" n
5708 | OptString n -> pr " str *%s;\n" n
5709 | StringList n | DeviceList n -> pr " str %s<>;\n" n
5710 | Bool n -> pr " bool %s;\n" n
5711 | Int n -> pr " int %s;\n" n
5712 | Int64 n -> pr " hyper %s;\n" n
5714 pr " opaque %s<>;\n" n
5715 | FileIn _ | FileOut _ -> ()
5719 (match fst style with
5722 pr "struct %s_ret {\n" name;
5726 pr "struct %s_ret {\n" name;
5727 pr " hyper %s;\n" n;
5730 pr "struct %s_ret {\n" name;
5733 | RConstString _ | RConstOptString _ ->
5734 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5736 pr "struct %s_ret {\n" name;
5737 pr " string %s<>;\n" n;
5740 pr "struct %s_ret {\n" name;
5741 pr " str %s<>;\n" n;
5743 | RStruct (n, typ) ->
5744 pr "struct %s_ret {\n" name;
5745 pr " guestfs_int_%s %s;\n" typ n;
5747 | RStructList (n, typ) ->
5748 pr "struct %s_ret {\n" name;
5749 pr " guestfs_int_%s_list %s;\n" typ n;
5752 pr "struct %s_ret {\n" name;
5753 pr " str %s<>;\n" n;
5756 pr "struct %s_ret {\n" name;
5757 pr " opaque %s<>;\n" n;
5762 (* Table of procedure numbers. *)
5763 pr "enum guestfs_procedure {\n";
5765 fun (shortname, _, proc_nr, _, _, _, _) ->
5766 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5768 pr " GUESTFS_PROC_NR_PROCS\n";
5772 (* Having to choose a maximum message size is annoying for several
5773 * reasons (it limits what we can do in the API), but it (a) makes
5774 * the protocol a lot simpler, and (b) provides a bound on the size
5775 * of the daemon which operates in limited memory space.
5777 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5780 (* Message header, etc. *)
5782 /* The communication protocol is now documented in the guestfs(3)
5786 const GUESTFS_PROGRAM = 0x2000F5F5;
5787 const GUESTFS_PROTOCOL_VERSION = 1;
5789 /* These constants must be larger than any possible message length. */
5790 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5791 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5793 enum guestfs_message_direction {
5794 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5795 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5798 enum guestfs_message_status {
5799 GUESTFS_STATUS_OK = 0,
5800 GUESTFS_STATUS_ERROR = 1
5803 const GUESTFS_ERROR_LEN = 256;
5805 struct guestfs_message_error {
5806 string error_message<GUESTFS_ERROR_LEN>;
5809 struct guestfs_message_header {
5810 unsigned prog; /* GUESTFS_PROGRAM */
5811 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5812 guestfs_procedure proc; /* GUESTFS_PROC_x */
5813 guestfs_message_direction direction;
5814 unsigned serial; /* message serial number */
5815 guestfs_message_status status;
5818 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5820 struct guestfs_chunk {
5821 int cancel; /* if non-zero, transfer is cancelled */
5822 /* data size is 0 bytes if the transfer has finished successfully */
5823 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5827 (* Generate the guestfs-structs.h file. *)
5828 and generate_structs_h () =
5829 generate_header CStyle LGPLv2plus;
5831 (* This is a public exported header file containing various
5832 * structures. The structures are carefully written to have
5833 * exactly the same in-memory format as the XDR structures that
5834 * we use on the wire to the daemon. The reason for creating
5835 * copies of these structures here is just so we don't have to
5836 * export the whole of guestfs_protocol.h (which includes much
5837 * unrelated and XDR-dependent stuff that we don't want to be
5838 * public, or required by clients).
5840 * To reiterate, we will pass these structures to and from the
5841 * client with a simple assignment or memcpy, so the format
5842 * must be identical to what rpcgen / the RFC defines.
5845 (* Public structures. *)
5848 pr "struct guestfs_%s {\n" typ;
5851 | name, FChar -> pr " char %s;\n" name
5852 | name, FString -> pr " char *%s;\n" name
5854 pr " uint32_t %s_len;\n" name;
5855 pr " char *%s;\n" name
5856 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5857 | name, FUInt32 -> pr " uint32_t %s;\n" name
5858 | name, FInt32 -> pr " int32_t %s;\n" name
5859 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5860 | name, FInt64 -> pr " int64_t %s;\n" name
5861 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5865 pr "struct guestfs_%s_list {\n" typ;
5866 pr " uint32_t len;\n";
5867 pr " struct guestfs_%s *val;\n" typ;
5870 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5871 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5875 (* Generate the guestfs-actions.h file. *)
5876 and generate_actions_h () =
5877 generate_header CStyle LGPLv2plus;
5879 fun (shortname, style, _, _, _, _, _) ->
5880 let name = "guestfs_" ^ shortname in
5881 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5885 (* Generate the guestfs-internal-actions.h file. *)
5886 and generate_internal_actions_h () =
5887 generate_header CStyle LGPLv2plus;
5889 fun (shortname, style, _, _, _, _, _) ->
5890 let name = "guestfs__" ^ shortname in
5891 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5893 ) non_daemon_functions
5895 (* Generate the client-side dispatch stubs. *)
5896 and generate_client_actions () =
5897 generate_header CStyle LGPLv2plus;
5904 #include <inttypes.h>
5906 #include \"guestfs.h\"
5907 #include \"guestfs-internal.h\"
5908 #include \"guestfs-internal-actions.h\"
5909 #include \"guestfs_protocol.h\"
5911 #define error guestfs_error
5912 //#define perrorf guestfs_perrorf
5913 #define safe_malloc guestfs_safe_malloc
5914 #define safe_realloc guestfs_safe_realloc
5915 //#define safe_strdup guestfs_safe_strdup
5916 #define safe_memdup guestfs_safe_memdup
5918 /* Check the return message from a call for validity. */
5920 check_reply_header (guestfs_h *g,
5921 const struct guestfs_message_header *hdr,
5922 unsigned int proc_nr, unsigned int serial)
5924 if (hdr->prog != GUESTFS_PROGRAM) {
5925 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5928 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5929 error (g, \"wrong protocol version (%%d/%%d)\",
5930 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5933 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5934 error (g, \"unexpected message direction (%%d/%%d)\",
5935 hdr->direction, GUESTFS_DIRECTION_REPLY);
5938 if (hdr->proc != proc_nr) {
5939 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5942 if (hdr->serial != serial) {
5943 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5950 /* Check we are in the right state to run a high-level action. */
5952 check_state (guestfs_h *g, const char *caller)
5954 if (!guestfs__is_ready (g)) {
5955 if (guestfs__is_config (g) || guestfs__is_launching (g))
5956 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5959 error (g, \"%%s called from the wrong state, %%d != READY\",
5960 caller, guestfs__get_state (g));
5968 let error_code_of = function
5969 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5970 | RConstString _ | RConstOptString _
5971 | RString _ | RStringList _
5972 | RStruct _ | RStructList _
5973 | RHashtable _ | RBufferOut _ -> "NULL"
5976 (* Generate code to check String-like parameters are not passed in
5977 * as NULL (returning an error if they are).
5979 let check_null_strings shortname style =
5980 let pr_newline = ref false in
5983 (* parameters which should not be NULL *)
5993 pr " if (%s == NULL) {\n" n;
5994 pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
5995 pr " \"%s\", \"%s\");\n" shortname n;
5996 pr " return %s;\n" (error_code_of (fst style));
6003 (* not applicable *)
6009 if !pr_newline then pr "\n";
6012 (* Generate code to generate guestfish call traces. *)
6013 let trace_call shortname style =
6014 pr " if (guestfs__get_trace (g)) {\n";
6017 List.exists (function
6018 | StringList _ | DeviceList _ -> true
6019 | _ -> false) (snd style) in
6025 pr " printf (\"%s\");\n" shortname;
6028 | String n (* strings *)
6035 (* guestfish doesn't support string escaping, so neither do we *)
6036 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
6037 | OptString n -> (* string option *)
6038 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
6039 pr " else printf (\" null\");\n"
6041 | DeviceList n -> (* string list *)
6042 pr " putchar (' ');\n";
6043 pr " putchar ('\"');\n";
6044 pr " for (i = 0; %s[i]; ++i) {\n" n;
6045 pr " if (i > 0) putchar (' ');\n";
6046 pr " fputs (%s[i], stdout);\n" n;
6048 pr " putchar ('\"');\n";
6049 | Bool n -> (* boolean *)
6050 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
6051 | Int n -> (* int *)
6052 pr " printf (\" %%d\", %s);\n" n
6054 pr " printf (\" %%\" PRIi64, %s);\n" n
6056 pr " putchar ('\\n');\n";
6061 (* For non-daemon functions, generate a wrapper around each function. *)
6063 fun (shortname, style, _, _, _, _, _) ->
6064 let name = "guestfs_" ^ shortname in
6066 generate_prototype ~extern:false ~semicolon:false ~newline:true
6067 ~handle:"g" name style;
6069 check_null_strings shortname style;
6070 trace_call shortname style;
6071 pr " return guestfs__%s " shortname;
6072 generate_c_call_args ~handle:"g" style;
6076 ) non_daemon_functions;
6078 (* Client-side stubs for each function. *)
6080 fun (shortname, style, _, _, _, _, _) ->
6081 let name = "guestfs_" ^ shortname in
6082 let error_code = error_code_of (fst style) in
6084 (* Generate the action stub. *)
6085 generate_prototype ~extern:false ~semicolon:false ~newline:true
6086 ~handle:"g" name style;
6090 (match snd style with
6092 | _ -> pr " struct %s_args args;\n" name
6095 pr " guestfs_message_header hdr;\n";
6096 pr " guestfs_message_error err;\n";
6098 match fst style with
6100 | RConstString _ | RConstOptString _ ->
6101 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6103 | RBool _ | RString _ | RStringList _
6104 | RStruct _ | RStructList _
6105 | RHashtable _ | RBufferOut _ ->
6106 pr " struct %s_ret ret;\n" name;
6109 pr " int serial;\n";
6112 check_null_strings shortname style;
6113 trace_call shortname style;
6114 pr " if (check_state (g, \"%s\") == -1) return %s;\n"
6115 shortname error_code;
6116 pr " guestfs___set_busy (g);\n";
6119 (* Send the main header and arguments. *)
6120 (match snd style with
6122 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
6123 (String.uppercase shortname)
6127 | Pathname n | Device n | Dev_or_Path n | String n ->
6128 pr " args.%s = (char *) %s;\n" n n
6130 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
6131 | StringList n | DeviceList n ->
6132 pr " args.%s.%s_val = (char **) %s;\n" n n n;
6133 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
6135 pr " args.%s = %s;\n" n n
6137 pr " args.%s = %s;\n" n n
6139 pr " args.%s = %s;\n" n n
6140 | FileIn _ | FileOut _ -> ()
6142 pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
6143 pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
6144 pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
6146 pr " guestfs___end_busy (g);\n";
6147 pr " return %s;\n" error_code;
6149 pr " args.%s.%s_val = (char *) %s;\n" n n n;
6150 pr " args.%s.%s_len = %s_size;\n" n n n
6152 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
6153 (String.uppercase shortname);
6154 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
6157 pr " if (serial == -1) {\n";
6158 pr " guestfs___end_busy (g);\n";
6159 pr " return %s;\n" error_code;
6163 (* Send any additional files (FileIn) requested. *)
6164 let need_read_reply_label = ref false in
6168 pr " r = guestfs___send_file (g, %s);\n" n;
6169 pr " if (r == -1) {\n";
6170 pr " guestfs___end_busy (g);\n";
6171 pr " return %s;\n" error_code;
6173 pr " if (r == -2) /* daemon cancelled */\n";
6174 pr " goto read_reply;\n";
6175 need_read_reply_label := true;
6180 (* Wait for the reply from the remote end. *)
6181 if !need_read_reply_label then pr " read_reply:\n";
6182 pr " memset (&hdr, 0, sizeof hdr);\n";
6183 pr " memset (&err, 0, sizeof err);\n";
6184 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
6186 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
6190 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
6193 pr " if (r == -1) {\n";
6194 pr " guestfs___end_busy (g);\n";
6195 pr " return %s;\n" error_code;
6199 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
6200 (String.uppercase shortname);
6201 pr " guestfs___end_busy (g);\n";
6202 pr " return %s;\n" error_code;
6206 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
6207 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
6208 pr " free (err.error_message);\n";
6209 pr " guestfs___end_busy (g);\n";
6210 pr " return %s;\n" error_code;
6214 (* Expecting to receive further files (FileOut)? *)
6218 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
6219 pr " guestfs___end_busy (g);\n";
6220 pr " return %s;\n" error_code;
6226 pr " guestfs___end_busy (g);\n";
6228 (match fst style with
6229 | RErr -> pr " return 0;\n"
6230 | RInt n | RInt64 n | RBool n ->
6231 pr " return ret.%s;\n" n
6232 | RConstString _ | RConstOptString _ ->
6233 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6235 pr " return ret.%s; /* caller will free */\n" n
6236 | RStringList n | RHashtable n ->
6237 pr " /* caller will free this, but we need to add a NULL entry */\n";
6238 pr " ret.%s.%s_val =\n" n n;
6239 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
6240 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
6242 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
6243 pr " return ret.%s.%s_val;\n" n n
6245 pr " /* caller will free this */\n";
6246 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6247 | RStructList (n, _) ->
6248 pr " /* caller will free this */\n";
6249 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6251 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
6252 pr " * _val might be NULL here. To make the API saner for\n";
6253 pr " * callers, we turn this case into a unique pointer (using\n";
6254 pr " * malloc(1)).\n";
6256 pr " if (ret.%s.%s_len > 0) {\n" n n;
6257 pr " *size_r = ret.%s.%s_len;\n" n n;
6258 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
6260 pr " free (ret.%s.%s_val);\n" n n;
6261 pr " char *p = safe_malloc (g, 1);\n";
6262 pr " *size_r = ret.%s.%s_len;\n" n n;
6270 (* Functions to free structures. *)
6271 pr "/* Structure-freeing functions. These rely on the fact that the\n";
6272 pr " * structure format is identical to the XDR format. See note in\n";
6273 pr " * generator.ml.\n";
6280 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
6282 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
6288 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
6290 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
6297 (* Generate daemon/actions.h. *)
6298 and generate_daemon_actions_h () =
6299 generate_header CStyle GPLv2plus;
6301 pr "#include \"../src/guestfs_protocol.h\"\n";
6305 fun (name, style, _, _, _, _, _) ->
6307 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
6311 (* Generate the linker script which controls the visibility of
6312 * symbols in the public ABI and ensures no other symbols get
6313 * exported accidentally.
6315 and generate_linker_script () =
6316 generate_header HashStyle GPLv2plus;
6321 "guestfs_get_error_handler";
6322 "guestfs_get_out_of_memory_handler";
6323 "guestfs_last_error";
6324 "guestfs_set_error_handler";
6325 "guestfs_set_launch_done_callback";
6326 "guestfs_set_log_message_callback";
6327 "guestfs_set_out_of_memory_handler";
6328 "guestfs_set_subprocess_quit_callback";
6330 (* Unofficial parts of the API: the bindings code use these
6331 * functions, so it is useful to export them.
6333 "guestfs_safe_calloc";
6334 "guestfs_safe_malloc";
6337 List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
6341 List.map (fun (typ, _) ->
6342 ["guestfs_free_" ^ typ; "guestfs_free_" ^ typ ^ "_list"])
6345 let globals = List.sort compare (globals @ functions @ structs) in
6349 List.iter (pr " %s;\n") globals;
6356 (* Generate the server-side stubs. *)
6357 and generate_daemon_actions () =
6358 generate_header CStyle GPLv2plus;
6360 pr "#include <config.h>\n";
6362 pr "#include <stdio.h>\n";
6363 pr "#include <stdlib.h>\n";
6364 pr "#include <string.h>\n";
6365 pr "#include <inttypes.h>\n";
6366 pr "#include <rpc/types.h>\n";
6367 pr "#include <rpc/xdr.h>\n";
6369 pr "#include \"daemon.h\"\n";
6370 pr "#include \"c-ctype.h\"\n";
6371 pr "#include \"../src/guestfs_protocol.h\"\n";
6372 pr "#include \"actions.h\"\n";
6376 fun (name, style, _, _, _, _, _) ->
6377 (* Generate server-side stubs. *)
6378 pr "static void %s_stub (XDR *xdr_in)\n" name;
6381 match fst style with
6382 | RErr | RInt _ -> pr " int r;\n"; "-1"
6383 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6384 | RBool _ -> pr " int r;\n"; "-1"
6385 | RConstString _ | RConstOptString _ ->
6386 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6387 | RString _ -> pr " char *r;\n"; "NULL"
6388 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
6389 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
6390 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
6392 pr " size_t size = 1;\n";
6396 (match snd style with
6399 pr " struct guestfs_%s_args args;\n" name;
6402 | Device n | Dev_or_Path n
6405 | OptString n -> pr " char *%s;\n" n
6406 | StringList n | DeviceList n -> pr " char **%s;\n" n
6407 | Bool n -> pr " int %s;\n" n
6408 | Int n -> pr " int %s;\n" n
6409 | Int64 n -> pr " int64_t %s;\n" n
6410 | FileIn _ | FileOut _ -> ()
6412 pr " const char *%s;\n" n;
6413 pr " size_t %s_size;\n" n
6419 List.exists (function FileIn _ -> true | _ -> false) (snd style) in
6421 (match snd style with
6424 pr " memset (&args, 0, sizeof args);\n";
6426 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
6428 pr " if (cancel_receive () != -2)\n";
6429 pr " reply_with_error (\"daemon failed to decode procedure arguments\");\n";
6433 pr " char *%s = args.%s;\n" n n
6435 let pr_list_handling_code n =
6436 pr " %s = realloc (args.%s.%s_val,\n" n n n;
6437 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
6438 pr " if (%s == NULL) {\n" n;
6440 pr " if (cancel_receive () != -2)\n";
6441 pr " reply_with_perror (\"realloc\");\n";
6444 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
6445 pr " args.%s.%s_val = %s;\n" n n n;
6451 pr " ABS_PATH (%s, %s, goto done);\n"
6452 n (if is_filein then "cancel_receive ()" else "0");
6455 pr " RESOLVE_DEVICE (%s, %s, goto done);\n"
6456 n (if is_filein then "cancel_receive ()" else "0");
6459 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
6460 n (if is_filein then "cancel_receive ()" else "0");
6461 | String n -> pr_args n
6462 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
6464 pr_list_handling_code n;
6466 pr_list_handling_code n;
6467 pr " /* Ensure that each is a device,\n";
6468 pr " * and perform device name translation. */\n";
6469 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
6470 pr " RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
6471 (if is_filein then "cancel_receive ()" else "0");
6473 | Bool n -> pr " %s = args.%s;\n" n n
6474 | Int n -> pr " %s = args.%s;\n" n n
6475 | Int64 n -> pr " %s = args.%s;\n" n n
6476 | FileIn _ | FileOut _ -> ()
6478 pr " %s = args.%s.%s_val;\n" n n n;
6479 pr " %s_size = args.%s.%s_len;\n" n n n
6484 (* this is used at least for do_equal *)
6485 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
6486 (* Emit NEED_ROOT just once, even when there are two or
6487 more Pathname args *)
6488 pr " NEED_ROOT (%s, goto done);\n"
6489 (if is_filein then "cancel_receive ()" else "0");
6492 (* Don't want to call the impl with any FileIn or FileOut
6493 * parameters, since these go "outside" the RPC protocol.
6496 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
6498 pr " r = do_%s " name;
6499 generate_c_call_args (fst style, args');
6502 (match fst style with
6503 | RErr | RInt _ | RInt64 _ | RBool _
6504 | RConstString _ | RConstOptString _
6505 | RString _ | RStringList _ | RHashtable _
6506 | RStruct (_, _) | RStructList (_, _) ->
6507 pr " if (r == %s)\n" error_code;
6508 pr " /* do_%s has already called reply_with_error */\n" name;
6512 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
6513 pr " * an ordinary zero-length buffer), so be careful ...\n";
6515 pr " if (size == 1 && r == %s)\n" error_code;
6516 pr " /* do_%s has already called reply_with_error */\n" name;
6521 (* If there are any FileOut parameters, then the impl must
6522 * send its own reply.
6525 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
6527 pr " /* do_%s has already sent a reply */\n" name
6529 match fst style with
6530 | RErr -> pr " reply (NULL, NULL);\n"
6531 | RInt n | RInt64 n | RBool n ->
6532 pr " struct guestfs_%s_ret ret;\n" name;
6533 pr " ret.%s = r;\n" n;
6534 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6536 | RConstString _ | RConstOptString _ ->
6537 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6539 pr " struct guestfs_%s_ret ret;\n" name;
6540 pr " ret.%s = r;\n" n;
6541 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6544 | RStringList n | RHashtable n ->
6545 pr " struct guestfs_%s_ret ret;\n" name;
6546 pr " ret.%s.%s_len = count_strings (r);\n" n n;
6547 pr " ret.%s.%s_val = r;\n" n n;
6548 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6550 pr " free_strings (r);\n"
6552 pr " struct guestfs_%s_ret ret;\n" name;
6553 pr " ret.%s = *r;\n" n;
6554 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6556 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6558 | RStructList (n, _) ->
6559 pr " struct guestfs_%s_ret ret;\n" name;
6560 pr " ret.%s = *r;\n" n;
6561 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6563 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6566 pr " struct guestfs_%s_ret ret;\n" name;
6567 pr " ret.%s.%s_val = r;\n" n n;
6568 pr " ret.%s.%s_len = size;\n" n n;
6569 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6574 (* Free the args. *)
6576 (match snd style with
6579 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
6586 (* Dispatch function. *)
6587 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
6589 pr " switch (proc_nr) {\n";
6592 fun (name, style, _, _, _, _, _) ->
6593 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
6594 pr " %s_stub (xdr_in);\n" name;
6599 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";
6604 (* LVM columns and tokenization functions. *)
6605 (* XXX This generates crap code. We should rethink how we
6611 pr "static const char *lvm_%s_cols = \"%s\";\n"
6612 typ (String.concat "," (List.map fst cols));
6615 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
6617 pr " char *tok, *p, *next;\n";
6621 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
6624 pr " if (!str) {\n";
6625 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
6628 pr " if (!*str || c_isspace (*str)) {\n";
6629 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
6634 fun (name, coltype) ->
6635 pr " if (!tok) {\n";
6636 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
6639 pr " p = strchrnul (tok, ',');\n";
6640 pr " if (*p) next = p+1; else next = NULL;\n";
6641 pr " *p = '\\0';\n";
6644 pr " r->%s = strdup (tok);\n" name;
6645 pr " if (r->%s == NULL) {\n" name;
6646 pr " perror (\"strdup\");\n";
6650 pr " for (i = j = 0; i < 32; ++j) {\n";
6651 pr " if (tok[j] == '\\0') {\n";
6652 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
6654 pr " } else if (tok[j] != '-')\n";
6655 pr " r->%s[i++] = tok[j];\n" name;
6658 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
6659 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6663 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
6664 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6668 pr " if (tok[0] == '\\0')\n";
6669 pr " r->%s = -1;\n" name;
6670 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
6671 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6674 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
6675 assert false (* can never be an LVM column *)
6677 pr " tok = next;\n";
6680 pr " if (tok != NULL) {\n";
6681 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
6688 pr "guestfs_int_lvm_%s_list *\n" typ;
6689 pr "parse_command_line_%ss (void)\n" typ;
6691 pr " char *out, *err;\n";
6692 pr " char *p, *pend;\n";
6694 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
6695 pr " void *newp;\n";
6697 pr " ret = malloc (sizeof *ret);\n";
6698 pr " if (!ret) {\n";
6699 pr " reply_with_perror (\"malloc\");\n";
6700 pr " return NULL;\n";
6703 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
6704 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
6706 pr " r = command (&out, &err,\n";
6707 pr " \"lvm\", \"%ss\",\n" typ;
6708 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
6709 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
6710 pr " if (r == -1) {\n";
6711 pr " reply_with_error (\"%%s\", err);\n";
6712 pr " free (out);\n";
6713 pr " free (err);\n";
6714 pr " free (ret);\n";
6715 pr " return NULL;\n";
6718 pr " free (err);\n";
6720 pr " /* Tokenize each line of the output. */\n";
6723 pr " while (p) {\n";
6724 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
6725 pr " if (pend) {\n";
6726 pr " *pend = '\\0';\n";
6730 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
6733 pr " if (!*p) { /* Empty line? Skip it. */\n";
6738 pr " /* Allocate some space to store this next entry. */\n";
6739 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
6740 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
6741 pr " if (newp == NULL) {\n";
6742 pr " reply_with_perror (\"realloc\");\n";
6743 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6744 pr " free (ret);\n";
6745 pr " free (out);\n";
6746 pr " return NULL;\n";
6748 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
6750 pr " /* Tokenize the next entry. */\n";
6751 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
6752 pr " if (r == -1) {\n";
6753 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
6754 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6755 pr " free (ret);\n";
6756 pr " free (out);\n";
6757 pr " return NULL;\n";
6764 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
6766 pr " free (out);\n";
6767 pr " return ret;\n";
6770 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
6772 (* Generate a list of function names, for debugging in the daemon.. *)
6773 and generate_daemon_names () =
6774 generate_header CStyle GPLv2plus;
6776 pr "#include <config.h>\n";
6778 pr "#include \"daemon.h\"\n";
6781 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
6782 pr "const char *function_names[] = {\n";
6784 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
6788 (* Generate the optional groups for the daemon to implement
6789 * guestfs_available.
6791 and generate_daemon_optgroups_c () =
6792 generate_header CStyle GPLv2plus;
6794 pr "#include <config.h>\n";
6796 pr "#include \"daemon.h\"\n";
6797 pr "#include \"optgroups.h\"\n";
6800 pr "struct optgroup optgroups[] = {\n";
6803 pr " { \"%s\", optgroup_%s_available },\n" group group
6805 pr " { NULL, NULL }\n";
6808 and generate_daemon_optgroups_h () =
6809 generate_header CStyle GPLv2plus;
6813 pr "extern int optgroup_%s_available (void);\n" group
6816 (* Generate the tests. *)
6817 and generate_tests () =
6818 generate_header CStyle GPLv2plus;
6825 #include <sys/types.h>
6828 #include \"guestfs.h\"
6829 #include \"guestfs-internal.h\"
6831 static guestfs_h *g;
6832 static int suppress_error = 0;
6834 static void print_error (guestfs_h *g, void *data, const char *msg)
6836 if (!suppress_error)
6837 fprintf (stderr, \"%%s\\n\", msg);
6840 /* FIXME: nearly identical code appears in fish.c */
6841 static void print_strings (char *const *argv)
6845 for (argc = 0; argv[argc] != NULL; ++argc)
6846 printf (\"\\t%%s\\n\", argv[argc]);
6850 static void print_table (char const *const *argv)
6854 for (i = 0; argv[i] != NULL; i += 2)
6855 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
6860 is_available (const char *group)
6862 const char *groups[] = { group, NULL };
6866 r = guestfs_available (g, (char **) groups);
6874 (* Generate a list of commands which are not tested anywhere. *)
6875 pr "static void no_test_warnings (void)\n";
6878 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
6880 fun (_, _, _, _, tests, _, _) ->
6881 let tests = filter_map (
6883 | (_, (Always|If _|Unless _|IfAvailable _), test) -> Some test
6884 | (_, Disabled, _) -> None
6886 let seq = List.concat (List.map seq_of_test tests) in
6887 let cmds_tested = List.map List.hd seq in
6888 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6892 fun (name, _, _, _, _, _, _) ->
6893 if not (Hashtbl.mem hash name) then
6894 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6900 (* Generate the actual tests. Note that we generate the tests
6901 * in reverse order, deliberately, so that (in general) the
6902 * newest tests run first. This makes it quicker and easier to
6907 fun (name, _, _, flags, tests, _, _) ->
6908 mapi (generate_one_test name flags) tests
6909 ) (List.rev all_functions) in
6910 let test_names = List.concat test_names in
6911 let nr_tests = List.length test_names in
6914 int main (int argc, char *argv[])
6917 unsigned long int n_failed = 0;
6918 const char *filename;
6920 int nr_tests, test_num = 0;
6922 setbuf (stdout, NULL);
6924 no_test_warnings ();
6926 g = guestfs_create ();
6928 printf (\"guestfs_create FAILED\\n\");
6929 exit (EXIT_FAILURE);
6932 guestfs_set_error_handler (g, print_error, NULL);
6934 guestfs_set_path (g, \"../appliance\");
6936 filename = \"test1.img\";
6937 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6940 exit (EXIT_FAILURE);
6942 if (lseek (fd, %d, SEEK_SET) == -1) {
6946 exit (EXIT_FAILURE);
6948 if (write (fd, &c, 1) == -1) {
6952 exit (EXIT_FAILURE);
6954 if (close (fd) == -1) {
6957 exit (EXIT_FAILURE);
6959 if (guestfs_add_drive (g, filename) == -1) {
6960 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6961 exit (EXIT_FAILURE);
6964 filename = \"test2.img\";
6965 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6968 exit (EXIT_FAILURE);
6970 if (lseek (fd, %d, SEEK_SET) == -1) {
6974 exit (EXIT_FAILURE);
6976 if (write (fd, &c, 1) == -1) {
6980 exit (EXIT_FAILURE);
6982 if (close (fd) == -1) {
6985 exit (EXIT_FAILURE);
6987 if (guestfs_add_drive (g, filename) == -1) {
6988 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6989 exit (EXIT_FAILURE);
6992 filename = \"test3.img\";
6993 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6996 exit (EXIT_FAILURE);
6998 if (lseek (fd, %d, SEEK_SET) == -1) {
7002 exit (EXIT_FAILURE);
7004 if (write (fd, &c, 1) == -1) {
7008 exit (EXIT_FAILURE);
7010 if (close (fd) == -1) {
7013 exit (EXIT_FAILURE);
7015 if (guestfs_add_drive (g, filename) == -1) {
7016 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
7017 exit (EXIT_FAILURE);
7020 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
7021 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
7022 exit (EXIT_FAILURE);
7025 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
7028 if (guestfs_launch (g) == -1) {
7029 printf (\"guestfs_launch FAILED\\n\");
7030 exit (EXIT_FAILURE);
7033 /* Cancel previous alarm. */
7038 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
7042 pr " test_num++;\n";
7043 pr " if (guestfs_get_verbose (g))\n";
7044 pr " printf (\"-------------------------------------------------------------------------------\\n\");\n";
7045 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
7046 pr " if (%s () == -1) {\n" test_name;
7047 pr " printf (\"%s FAILED\\n\");\n" test_name;
7048 pr " n_failed++;\n";
7053 pr " guestfs_close (g);\n";
7054 pr " unlink (\"test1.img\");\n";
7055 pr " unlink (\"test2.img\");\n";
7056 pr " unlink (\"test3.img\");\n";
7059 pr " if (n_failed > 0) {\n";
7060 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
7061 pr " exit (EXIT_FAILURE);\n";
7065 pr " exit (EXIT_SUCCESS);\n";
7068 and generate_one_test name flags i (init, prereq, test) =
7069 let test_name = sprintf "test_%s_%d" name i in
7072 static int %s_skip (void)
7076 str = getenv (\"TEST_ONLY\");
7078 return strstr (str, \"%s\") == NULL;
7079 str = getenv (\"SKIP_%s\");
7080 if (str && STREQ (str, \"1\")) return 1;
7081 str = getenv (\"SKIP_TEST_%s\");
7082 if (str && STREQ (str, \"1\")) return 1;
7086 " test_name name (String.uppercase test_name) (String.uppercase name);
7089 | Disabled | Always | IfAvailable _ -> ()
7090 | If code | Unless code ->
7091 pr "static int %s_prereq (void)\n" test_name;
7099 static int %s (void)
7102 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
7106 " test_name test_name test_name;
7108 (* Optional functions should only be tested if the relevant
7109 * support is available in the daemon.
7114 pr " if (!is_available (\"%s\")) {\n" group;
7115 pr " printf (\" %%s skipped (reason: group %%s not available in daemon)\\n\", \"%s\", \"%s\");\n" test_name group;
7123 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
7125 pr " if (! %s_prereq ()) {\n" test_name;
7126 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7130 generate_one_test_body name i test_name init test;
7132 pr " if (%s_prereq ()) {\n" test_name;
7133 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7137 generate_one_test_body name i test_name init test;
7138 | IfAvailable group ->
7139 pr " if (!is_available (\"%s\")) {\n" group;
7140 pr " printf (\" %%s skipped (reason: %%s not available)\\n\", \"%s\", \"%s\");\n" test_name group;
7144 generate_one_test_body name i test_name init test;
7146 generate_one_test_body name i test_name init test
7154 and generate_one_test_body name i test_name init test =
7156 | InitNone (* XXX at some point, InitNone and InitEmpty became
7157 * folded together as the same thing. Really we should
7158 * make InitNone do nothing at all, but the tests may
7159 * need to be checked to make sure this is OK.
7162 pr " /* InitNone|InitEmpty for %s */\n" test_name;
7163 List.iter (generate_test_command_call test_name)
7164 [["blockdev_setrw"; "/dev/sda"];
7168 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
7169 List.iter (generate_test_command_call test_name)
7170 [["blockdev_setrw"; "/dev/sda"];
7173 ["part_disk"; "/dev/sda"; "mbr"]]
7175 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
7176 List.iter (generate_test_command_call test_name)
7177 [["blockdev_setrw"; "/dev/sda"];
7180 ["part_disk"; "/dev/sda"; "mbr"];
7181 ["mkfs"; "ext2"; "/dev/sda1"];
7182 ["mount_options"; ""; "/dev/sda1"; "/"]]
7183 | InitBasicFSonLVM ->
7184 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
7186 List.iter (generate_test_command_call test_name)
7187 [["blockdev_setrw"; "/dev/sda"];
7190 ["part_disk"; "/dev/sda"; "mbr"];
7191 ["pvcreate"; "/dev/sda1"];
7192 ["vgcreate"; "VG"; "/dev/sda1"];
7193 ["lvcreate"; "LV"; "VG"; "8"];
7194 ["mkfs"; "ext2"; "/dev/VG/LV"];
7195 ["mount_options"; ""; "/dev/VG/LV"; "/"]]
7197 pr " /* InitISOFS for %s */\n" test_name;
7198 List.iter (generate_test_command_call test_name)
7199 [["blockdev_setrw"; "/dev/sda"];
7202 ["mount_ro"; "/dev/sdd"; "/"]]
7205 let get_seq_last = function
7207 failwithf "%s: you cannot use [] (empty list) when expecting a command"
7210 let seq = List.rev seq in
7211 List.rev (List.tl seq), List.hd seq
7216 pr " /* TestRun for %s (%d) */\n" name i;
7217 List.iter (generate_test_command_call test_name) seq
7218 | TestOutput (seq, expected) ->
7219 pr " /* TestOutput for %s (%d) */\n" name i;
7220 pr " const char *expected = \"%s\";\n" (c_quote expected);
7221 let seq, last = get_seq_last seq in
7223 pr " if (STRNEQ (r, expected)) {\n";
7224 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7228 List.iter (generate_test_command_call test_name) seq;
7229 generate_test_command_call ~test test_name last
7230 | TestOutputList (seq, expected) ->
7231 pr " /* TestOutputList for %s (%d) */\n" name i;
7232 let seq, last = get_seq_last seq in
7236 pr " if (!r[%d]) {\n" i;
7237 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7238 pr " print_strings (r);\n";
7242 pr " const char *expected = \"%s\";\n" (c_quote str);
7243 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7244 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7249 pr " if (r[%d] != NULL) {\n" (List.length expected);
7250 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7252 pr " print_strings (r);\n";
7256 List.iter (generate_test_command_call test_name) seq;
7257 generate_test_command_call ~test test_name last
7258 | TestOutputListOfDevices (seq, expected) ->
7259 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
7260 let seq, last = get_seq_last seq in
7264 pr " if (!r[%d]) {\n" i;
7265 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7266 pr " print_strings (r);\n";
7270 pr " const char *expected = \"%s\";\n" (c_quote str);
7271 pr " r[%d][5] = 's';\n" i;
7272 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7273 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7278 pr " if (r[%d] != NULL) {\n" (List.length expected);
7279 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7281 pr " print_strings (r);\n";
7285 List.iter (generate_test_command_call test_name) seq;
7286 generate_test_command_call ~test test_name last
7287 | TestOutputInt (seq, expected) ->
7288 pr " /* TestOutputInt for %s (%d) */\n" name i;
7289 let seq, last = get_seq_last seq in
7291 pr " if (r != %d) {\n" expected;
7292 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
7298 List.iter (generate_test_command_call test_name) seq;
7299 generate_test_command_call ~test test_name last
7300 | TestOutputIntOp (seq, op, expected) ->
7301 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
7302 let seq, last = get_seq_last seq in
7304 pr " if (! (r %s %d)) {\n" op expected;
7305 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
7306 test_name op expected;
7311 List.iter (generate_test_command_call test_name) seq;
7312 generate_test_command_call ~test test_name last
7313 | TestOutputTrue seq ->
7314 pr " /* TestOutputTrue for %s (%d) */\n" name i;
7315 let seq, last = get_seq_last seq in
7318 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
7323 List.iter (generate_test_command_call test_name) seq;
7324 generate_test_command_call ~test test_name last
7325 | TestOutputFalse seq ->
7326 pr " /* TestOutputFalse for %s (%d) */\n" name i;
7327 let seq, last = get_seq_last seq in
7330 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
7335 List.iter (generate_test_command_call test_name) seq;
7336 generate_test_command_call ~test test_name last
7337 | TestOutputLength (seq, expected) ->
7338 pr " /* TestOutputLength for %s (%d) */\n" name i;
7339 let seq, last = get_seq_last seq in
7342 pr " for (j = 0; j < %d; ++j)\n" expected;
7343 pr " if (r[j] == NULL) {\n";
7344 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
7346 pr " print_strings (r);\n";
7349 pr " if (r[j] != NULL) {\n";
7350 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
7352 pr " print_strings (r);\n";
7356 List.iter (generate_test_command_call test_name) seq;
7357 generate_test_command_call ~test test_name last
7358 | TestOutputBuffer (seq, expected) ->
7359 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
7360 pr " const char *expected = \"%s\";\n" (c_quote expected);
7361 let seq, last = get_seq_last seq in
7362 let len = String.length expected in
7364 pr " if (size != %d) {\n" len;
7365 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
7368 pr " if (STRNEQLEN (r, expected, size)) {\n";
7369 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7373 List.iter (generate_test_command_call test_name) seq;
7374 generate_test_command_call ~test test_name last
7375 | TestOutputStruct (seq, checks) ->
7376 pr " /* TestOutputStruct for %s (%d) */\n" name i;
7377 let seq, last = get_seq_last seq in
7381 | CompareWithInt (field, expected) ->
7382 pr " if (r->%s != %d) {\n" field expected;
7383 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
7384 test_name field expected;
7385 pr " (int) r->%s);\n" field;
7388 | CompareWithIntOp (field, op, expected) ->
7389 pr " if (!(r->%s %s %d)) {\n" field op expected;
7390 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
7391 test_name field op expected;
7392 pr " (int) r->%s);\n" field;
7395 | CompareWithString (field, expected) ->
7396 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
7397 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
7398 test_name field expected;
7399 pr " r->%s);\n" field;
7402 | CompareFieldsIntEq (field1, field2) ->
7403 pr " if (r->%s != r->%s) {\n" field1 field2;
7404 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
7405 test_name field1 field2;
7406 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
7409 | CompareFieldsStrEq (field1, field2) ->
7410 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
7411 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
7412 test_name field1 field2;
7413 pr " r->%s, r->%s);\n" field1 field2;
7418 List.iter (generate_test_command_call test_name) seq;
7419 generate_test_command_call ~test test_name last
7420 | TestLastFail seq ->
7421 pr " /* TestLastFail for %s (%d) */\n" name i;
7422 let seq, last = get_seq_last seq in
7423 List.iter (generate_test_command_call test_name) seq;
7424 generate_test_command_call test_name ~expect_error:true last
7426 (* Generate the code to run a command, leaving the result in 'r'.
7427 * If you expect to get an error then you should set expect_error:true.
7429 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
7431 | [] -> assert false
7433 (* Look up the command to find out what args/ret it has. *)
7436 let _, style, _, _, _, _, _ =
7437 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
7440 failwithf "%s: in test, command %s was not found" test_name name in
7442 if List.length (snd style) <> List.length args then
7443 failwithf "%s: in test, wrong number of args given to %s"
7450 | OptString n, "NULL" -> ()
7453 | Dev_or_Path n, arg
7455 | OptString n, arg ->
7456 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7457 | BufferIn n, arg ->
7458 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7459 pr " size_t %s_size = %d;\n" n (String.length arg)
7463 | FileIn _, _ | FileOut _, _ -> ()
7464 | StringList n, "" | DeviceList n, "" ->
7465 pr " const char *const %s[1] = { NULL };\n" n
7466 | StringList n, arg | DeviceList n, arg ->
7467 let strs = string_split " " arg in
7470 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
7472 pr " const char *const %s[] = {\n" n;
7474 fun i _ -> pr " %s_%d,\n" n i
7478 ) (List.combine (snd style) args);
7481 match fst style with
7482 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
7483 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7484 | RConstString _ | RConstOptString _ ->
7485 pr " const char *r;\n"; "NULL"
7486 | RString _ -> pr " char *r;\n"; "NULL"
7487 | RStringList _ | RHashtable _ ->
7491 | RStruct (_, typ) ->
7492 pr " struct guestfs_%s *r;\n" typ; "NULL"
7493 | RStructList (_, typ) ->
7494 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7497 pr " size_t size;\n";
7500 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
7501 pr " r = guestfs_%s (g" name;
7503 (* Generate the parameters. *)
7506 | OptString _, "NULL" -> pr ", NULL"
7508 | Device n, _ | Dev_or_Path n, _
7513 pr ", %s, %s_size" n n
7514 | FileIn _, arg | FileOut _, arg ->
7515 pr ", \"%s\"" (c_quote arg)
7516 | StringList n, _ | DeviceList n, _ ->
7517 pr ", (char **) %s" n
7520 try int_of_string arg
7521 with Failure "int_of_string" ->
7522 failwithf "%s: expecting an int, but got '%s'" test_name arg in
7526 try Int64.of_string arg
7527 with Failure "int_of_string" ->
7528 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
7531 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
7532 ) (List.combine (snd style) args);
7534 (match fst style with
7535 | RBufferOut _ -> pr ", &size"
7541 if not expect_error then
7542 pr " if (r == %s)\n" error_code
7544 pr " if (r != %s)\n" error_code;
7547 (* Insert the test code. *)
7553 (match fst style with
7554 | RErr | RInt _ | RInt64 _ | RBool _
7555 | RConstString _ | RConstOptString _ -> ()
7556 | RString _ | RBufferOut _ -> pr " free (r);\n"
7557 | RStringList _ | RHashtable _ ->
7558 pr " for (i = 0; r[i] != NULL; ++i)\n";
7559 pr " free (r[i]);\n";
7561 | RStruct (_, typ) ->
7562 pr " guestfs_free_%s (r);\n" typ
7563 | RStructList (_, typ) ->
7564 pr " guestfs_free_%s_list (r);\n" typ
7570 let str = replace_str str "\r" "\\r" in
7571 let str = replace_str str "\n" "\\n" in
7572 let str = replace_str str "\t" "\\t" in
7573 let str = replace_str str "\000" "\\0" in
7576 (* Generate a lot of different functions for guestfish. *)
7577 and generate_fish_cmds () =
7578 generate_header CStyle GPLv2plus;
7582 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7584 let all_functions_sorted =
7586 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7587 ) all_functions_sorted in
7589 pr "#include <config.h>\n";
7591 pr "#include <stdio.h>\n";
7592 pr "#include <stdlib.h>\n";
7593 pr "#include <string.h>\n";
7594 pr "#include <inttypes.h>\n";
7596 pr "#include <guestfs.h>\n";
7597 pr "#include \"c-ctype.h\"\n";
7598 pr "#include \"full-write.h\"\n";
7599 pr "#include \"xstrtol.h\"\n";
7600 pr "#include \"fish.h\"\n";
7602 pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
7603 pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
7606 (* list_commands function, which implements guestfish -h *)
7607 pr "void list_commands (void)\n";
7609 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
7610 pr " list_builtin_commands ();\n";
7612 fun (name, _, _, flags, _, shortdesc, _) ->
7613 let name = replace_char name '_' '-' in
7614 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
7616 ) all_functions_sorted;
7617 pr " printf (\" %%s\\n\",";
7618 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
7622 (* display_command function, which implements guestfish -h cmd *)
7623 pr "int display_command (const char *cmd)\n";
7626 fun (name, style, _, flags, _, shortdesc, longdesc) ->
7627 let name2 = replace_char name '_' '-' in
7629 try find_map (function FishAlias n -> Some n | _ -> None) flags
7630 with Not_found -> name in
7631 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
7633 match snd style with
7637 name2 (String.concat " " (List.map name_of_argt args)) in
7640 if List.mem ProtocolLimitWarning flags then
7641 ("\n\n" ^ protocol_limit_warning)
7644 (* For DangerWillRobinson commands, we should probably have
7645 * guestfish prompt before allowing you to use them (especially
7646 * in interactive mode). XXX
7650 if List.mem DangerWillRobinson flags then
7651 ("\n\n" ^ danger_will_robinson)
7656 match deprecation_notice flags with
7658 | Some txt -> "\n\n" ^ txt in
7660 let describe_alias =
7661 if name <> alias then
7662 sprintf "\n\nYou can use '%s' as an alias for this command." alias
7666 pr "STRCASEEQ (cmd, \"%s\")" name;
7667 if name <> name2 then
7668 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7669 if name <> alias then
7670 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7672 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
7674 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
7675 "=head1 DESCRIPTION\n\n" ^
7676 longdesc ^ warnings ^ describe_alias);
7681 pr " return display_builtin_command (cmd);\n";
7685 let emit_print_list_function typ =
7686 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
7689 pr " unsigned int i;\n";
7691 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7692 pr " printf (\"[%%d] = {\\n\", i);\n";
7693 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
7694 pr " printf (\"}\\n\");\n";
7700 (* print_* functions *)
7704 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
7706 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
7709 pr " unsigned int i;\n";
7715 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
7717 pr " printf (\"%%s%s: \", indent);\n" name;
7718 pr " for (i = 0; i < 32; ++i)\n";
7719 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7720 pr " printf (\"\\n\");\n"
7722 pr " printf (\"%%s%s: \", indent);\n" name;
7723 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
7724 pr " if (c_isprint (%s->%s[i]))\n" typ name;
7725 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7727 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
7728 pr " printf (\"\\n\");\n"
7729 | name, (FUInt64|FBytes) ->
7730 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
7733 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
7736 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
7739 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
7742 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
7744 | name, FOptPercent ->
7745 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
7746 typ name name typ name;
7747 pr " else printf (\"%%s%s: \\n\", indent);\n" name
7753 (* Emit a print_TYPE_list function definition only if that function is used. *)
7756 | typ, (RStructListOnly | RStructAndList) ->
7757 (* generate the function for typ *)
7758 emit_print_list_function typ
7759 | typ, _ -> () (* empty *)
7760 ) (rstructs_used_by all_functions);
7762 (* Emit a print_TYPE function definition only if that function is used. *)
7765 | typ, (RStructOnly | RStructAndList) ->
7766 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
7768 pr " print_%s_indent (%s, \"\");\n" typ typ;
7771 | typ, _ -> () (* empty *)
7772 ) (rstructs_used_by all_functions);
7774 (* run_<action> actions *)
7776 fun (name, style, _, flags, _, _, _) ->
7777 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
7779 (match fst style with
7782 | RBool _ -> pr " int r;\n"
7783 | RInt64 _ -> pr " int64_t r;\n"
7784 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
7785 | RString _ -> pr " char *r;\n"
7786 | RStringList _ | RHashtable _ -> pr " char **r;\n"
7787 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
7788 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
7791 pr " size_t size;\n";
7797 | OptString n -> pr " const char *%s;\n" n
7801 | FileOut n -> pr " char *%s;\n" n
7803 pr " const char *%s;\n" n;
7804 pr " size_t %s_size;\n" n
7805 | StringList n | DeviceList n -> pr " char **%s;\n" n
7806 | Bool n -> pr " int %s;\n" n
7807 | Int n -> pr " int %s;\n" n
7808 | Int64 n -> pr " int64_t %s;\n" n
7811 (* Check and convert parameters. *)
7812 let argc_expected = List.length (snd style) in
7813 pr " if (argc != %d) {\n" argc_expected;
7814 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
7816 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
7820 let parse_integer fn fntyp rtyp range name i =
7822 pr " strtol_error xerr;\n";
7823 pr " %s r;\n" fntyp;
7825 pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
7826 pr " if (xerr != LONGINT_OK) {\n";
7827 pr " fprintf (stderr,\n";
7828 pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
7829 pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
7834 | Some (min, max, comment) ->
7835 pr " /* %s */\n" comment;
7836 pr " if (r < %s || r > %s) {\n" min max;
7837 pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
7841 pr " /* The check above should ensure this assignment does not overflow. */\n";
7843 pr " %s = r;\n" name;
7852 pr " %s = argv[%d];\n" name i
7854 | Dev_or_Path name ->
7855 pr " %s = resolve_win_path (argv[%d]);\n" name i;
7856 pr " if (%s == NULL) return -1;\n" name
7858 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
7861 pr " %s = argv[%d];\n" name i;
7862 pr " %s_size = strlen (argv[%d]);\n" name i
7864 pr " %s = file_in (argv[%d]);\n" name i;
7865 pr " if (%s == NULL) return -1;\n" name
7867 pr " %s = file_out (argv[%d]);\n" name i;
7868 pr " if (%s == NULL) return -1;\n" name
7869 | StringList name | DeviceList name ->
7870 pr " %s = parse_string_list (argv[%d]);\n" name i;
7871 pr " if (%s == NULL) return -1;\n" name;
7873 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
7876 let min = "(-(2LL<<30))"
7877 and max = "((2LL<<30)-1)"
7879 "The Int type in the generator is a signed 31 bit int." in
7880 Some (min, max, comment) in
7881 parse_integer "xstrtoll" "long long" "int" range name i
7883 parse_integer "xstrtoll" "long long" "int64_t" None name i
7886 (* Call C API function. *)
7887 pr " r = guestfs_%s " name;
7888 generate_c_call_args ~handle:"g" style;
7893 | Device name | String name
7894 | OptString name | Bool name
7895 | Int name | Int64 name
7896 | BufferIn name -> ()
7897 | Pathname name | Dev_or_Path name | FileOut name ->
7898 pr " free (%s);\n" name
7900 pr " free_file_in (%s);\n" name
7901 | StringList name | DeviceList name ->
7902 pr " free_strings (%s);\n" name
7905 (* Any output flags? *)
7907 let flags = filter_map (
7908 function FishOutput flag -> Some flag | _ -> None
7914 failwithf "%s: more than one FishOutput flag is not allowed" name in
7916 (* Check return value for errors and display command results. *)
7917 (match fst style with
7918 | RErr -> pr " return r;\n"
7920 pr " if (r == -1) return -1;\n";
7921 (match fish_output with
7923 pr " printf (\"%%d\\n\", r);\n";
7924 | Some FishOutputOctal ->
7925 pr " printf (\"%%s%%o\\n\", r != 0 ? \"0\" : \"\", r);\n";
7926 | Some FishOutputHexadecimal ->
7927 pr " printf (\"%%s%%x\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7930 pr " if (r == -1) return -1;\n";
7931 (match fish_output with
7933 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
7934 | Some FishOutputOctal ->
7935 pr " printf (\"%%s%%\" PRIo64 \"\\n\", r != 0 ? \"0\" : \"\", r);\n";
7936 | Some FishOutputHexadecimal ->
7937 pr " printf (\"%%s%%\" PRIx64 \"\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7940 pr " if (r == -1) return -1;\n";
7941 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
7944 pr " if (r == NULL) return -1;\n";
7945 pr " printf (\"%%s\\n\", r);\n";
7947 | RConstOptString _ ->
7948 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
7951 pr " if (r == NULL) return -1;\n";
7952 pr " printf (\"%%s\\n\", r);\n";
7956 pr " if (r == NULL) return -1;\n";
7957 pr " print_strings (r);\n";
7958 pr " free_strings (r);\n";
7960 | RStruct (_, typ) ->
7961 pr " if (r == NULL) return -1;\n";
7962 pr " print_%s (r);\n" typ;
7963 pr " guestfs_free_%s (r);\n" typ;
7965 | RStructList (_, typ) ->
7966 pr " if (r == NULL) return -1;\n";
7967 pr " print_%s_list (r);\n" typ;
7968 pr " guestfs_free_%s_list (r);\n" typ;
7971 pr " if (r == NULL) return -1;\n";
7972 pr " print_table (r);\n";
7973 pr " free_strings (r);\n";
7976 pr " if (r == NULL) return -1;\n";
7977 pr " if (full_write (1, r, size) != size) {\n";
7978 pr " perror (\"write\");\n";
7989 (* run_action function *)
7990 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
7993 fun (name, _, _, flags, _, _, _) ->
7994 let name2 = replace_char name '_' '-' in
7996 try find_map (function FishAlias n -> Some n | _ -> None) flags
7997 with Not_found -> name in
7999 pr "STRCASEEQ (cmd, \"%s\")" name;
8000 if name <> name2 then
8001 pr " || STRCASEEQ (cmd, \"%s\")" name2;
8002 if name <> alias then
8003 pr " || STRCASEEQ (cmd, \"%s\")" alias;
8005 pr " return run_%s (cmd, argc, argv);\n" name;
8009 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
8010 pr " if (command_num == 1)\n";
8011 pr " extended_help_message ();\n";
8018 (* Readline completion for guestfish. *)
8019 and generate_fish_completion () =
8020 generate_header CStyle GPLv2plus;
8024 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
8034 #ifdef HAVE_LIBREADLINE
8035 #include <readline/readline.h>
8040 #ifdef HAVE_LIBREADLINE
8042 static const char *const commands[] = {
8043 BUILTIN_COMMANDS_FOR_COMPLETION,
8046 (* Get the commands, including the aliases. They don't need to be
8047 * sorted - the generator() function just does a dumb linear search.
8051 fun (name, _, _, flags, _, _, _) ->
8052 let name2 = replace_char name '_' '-' in
8054 try find_map (function FishAlias n -> Some n | _ -> None) flags
8055 with Not_found -> name in
8057 if name <> alias then [name2; alias] else [name2]
8059 let commands = List.flatten commands in
8061 List.iter (pr " \"%s\",\n") commands;
8067 generator (const char *text, int state)
8069 static int index, len;
8074 len = strlen (text);
8077 rl_attempted_completion_over = 1;
8079 while ((name = commands[index]) != NULL) {
8081 if (STRCASEEQLEN (name, text, len))
8082 return strdup (name);
8088 #endif /* HAVE_LIBREADLINE */
8090 #ifdef HAVE_RL_COMPLETION_MATCHES
8091 #define RL_COMPLETION_MATCHES rl_completion_matches
8093 #ifdef HAVE_COMPLETION_MATCHES
8094 #define RL_COMPLETION_MATCHES completion_matches
8096 #endif /* else just fail if we don't have either symbol */
8099 do_completion (const char *text, int start, int end)
8101 char **matches = NULL;
8103 #ifdef HAVE_LIBREADLINE
8104 rl_completion_append_character = ' ';
8107 matches = RL_COMPLETION_MATCHES (text, generator);
8108 else if (complete_dest_paths)
8109 matches = RL_COMPLETION_MATCHES (text, complete_dest_paths_generator);
8116 (* Generate the POD documentation for guestfish. *)
8117 and generate_fish_actions_pod () =
8118 let all_functions_sorted =
8120 fun (_, _, _, flags, _, _, _) ->
8121 not (List.mem NotInFish flags || List.mem NotInDocs flags)
8122 ) all_functions_sorted in
8124 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
8127 fun (name, style, _, flags, _, _, longdesc) ->
8129 Str.global_substitute rex (
8132 try Str.matched_group 1 s
8134 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
8135 "C<" ^ replace_char sub '_' '-' ^ ">"
8137 let name = replace_char name '_' '-' in
8139 try find_map (function FishAlias n -> Some n | _ -> None) flags
8140 with Not_found -> name in
8142 pr "=head2 %s" name;
8143 if name <> alias then
8150 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
8151 | OptString n -> pr " %s" n
8152 | StringList n | DeviceList n -> pr " '%s ...'" n
8153 | Bool _ -> pr " true|false"
8154 | Int n -> pr " %s" n
8155 | Int64 n -> pr " %s" n
8156 | FileIn n | FileOut n -> pr " (%s|-)" n
8157 | BufferIn n -> pr " %s" n
8161 pr "%s\n\n" longdesc;
8163 if List.exists (function FileIn _ | FileOut _ -> true
8164 | _ -> false) (snd style) then
8165 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
8167 if List.mem ProtocolLimitWarning flags then
8168 pr "%s\n\n" protocol_limit_warning;
8170 if List.mem DangerWillRobinson flags then
8171 pr "%s\n\n" danger_will_robinson;
8173 match deprecation_notice flags with
8175 | Some txt -> pr "%s\n\n" txt
8176 ) all_functions_sorted
8178 (* Generate a C function prototype. *)
8179 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
8180 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
8182 ?handle name style =
8183 if extern then pr "extern ";
8184 if static then pr "static ";
8185 (match fst style with
8187 | RInt _ -> pr "int "
8188 | RInt64 _ -> pr "int64_t "
8189 | RBool _ -> pr "int "
8190 | RConstString _ | RConstOptString _ -> pr "const char *"
8191 | RString _ | RBufferOut _ -> pr "char *"
8192 | RStringList _ | RHashtable _ -> pr "char **"
8193 | RStruct (_, typ) ->
8194 if not in_daemon then pr "struct guestfs_%s *" typ
8195 else pr "guestfs_int_%s *" typ
8196 | RStructList (_, typ) ->
8197 if not in_daemon then pr "struct guestfs_%s_list *" typ
8198 else pr "guestfs_int_%s_list *" typ
8200 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
8201 pr "%s%s (" prefix name;
8202 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
8205 let comma = ref false in
8208 | Some handle -> pr "guestfs_h *%s" handle; comma := true
8212 if single_line then pr ", " else pr ",\n\t\t"
8219 | Device n | Dev_or_Path n
8223 pr "const char *%s" n
8224 | StringList n | DeviceList n ->
8226 pr "char *const *%s" n
8227 | Bool n -> next (); pr "int %s" n
8228 | Int n -> next (); pr "int %s" n
8229 | Int64 n -> next (); pr "int64_t %s" n
8232 if not in_daemon then (next (); pr "const char *%s" n)
8235 pr "const char *%s" n;
8237 pr "size_t %s_size" n
8239 if is_RBufferOut then (next (); pr "size_t *size_r");
8242 if semicolon then pr ";";
8243 if newline then pr "\n"
8245 (* Generate C call arguments, eg "(handle, foo, bar)" *)
8246 and generate_c_call_args ?handle ?(decl = false) style =
8248 let comma = ref false in
8250 if !comma then pr ", ";
8255 | Some handle -> pr "%s" handle; comma := true
8261 pr "%s, %s_size" n n
8264 pr "%s" (name_of_argt arg)
8266 (* For RBufferOut calls, add implicit &size parameter. *)
8268 match fst style with
8276 (* Generate the OCaml bindings interface. *)
8277 and generate_ocaml_mli () =
8278 generate_header OCamlStyle LGPLv2plus;
8281 (** For API documentation you should refer to the C API
8282 in the guestfs(3) manual page. The OCaml API uses almost
8283 exactly the same calls. *)
8286 (** A [guestfs_h] handle. *)
8288 exception Error of string
8289 (** This exception is raised when there is an error. *)
8291 exception Handle_closed of string
8292 (** This exception is raised if you use a {!Guestfs.t} handle
8293 after calling {!close} on it. The string is the name of
8296 val create : unit -> t
8297 (** Create a {!Guestfs.t} handle. *)
8299 val close : t -> unit
8300 (** Close the {!Guestfs.t} handle and free up all resources used
8303 Handles are closed by the garbage collector when they become
8304 unreferenced, but callers can call this in order to provide
8305 predictable cleanup. *)
8308 generate_ocaml_structure_decls ();
8312 fun (name, style, _, _, _, shortdesc, _) ->
8313 generate_ocaml_prototype name style;
8314 pr "(** %s *)\n" shortdesc;
8316 ) all_functions_sorted
8318 (* Generate the OCaml bindings implementation. *)
8319 and generate_ocaml_ml () =
8320 generate_header OCamlStyle LGPLv2plus;
8325 exception Error of string
8326 exception Handle_closed of string
8328 external create : unit -> t = \"ocaml_guestfs_create\"
8329 external close : t -> unit = \"ocaml_guestfs_close\"
8331 (* Give the exceptions names, so they can be raised from the C code. *)
8333 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
8334 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
8338 generate_ocaml_structure_decls ();
8342 fun (name, style, _, _, _, shortdesc, _) ->
8343 generate_ocaml_prototype ~is_external:true name style;
8344 ) all_functions_sorted
8346 (* Generate the OCaml bindings C implementation. *)
8347 and generate_ocaml_c () =
8348 generate_header CStyle LGPLv2plus;
8355 #include <caml/config.h>
8356 #include <caml/alloc.h>
8357 #include <caml/callback.h>
8358 #include <caml/fail.h>
8359 #include <caml/memory.h>
8360 #include <caml/mlvalues.h>
8361 #include <caml/signals.h>
8363 #include <guestfs.h>
8365 #include \"guestfs_c.h\"
8367 /* Copy a hashtable of string pairs into an assoc-list. We return
8368 * the list in reverse order, but hashtables aren't supposed to be
8371 static CAMLprim value
8372 copy_table (char * const * argv)
8375 CAMLlocal5 (rv, pairv, kv, vv, cons);
8379 for (i = 0; argv[i] != NULL; i += 2) {
8380 kv = caml_copy_string (argv[i]);
8381 vv = caml_copy_string (argv[i+1]);
8382 pairv = caml_alloc (2, 0);
8383 Store_field (pairv, 0, kv);
8384 Store_field (pairv, 1, vv);
8385 cons = caml_alloc (2, 0);
8386 Store_field (cons, 1, rv);
8388 Store_field (cons, 0, pairv);
8396 (* Struct copy functions. *)
8398 let emit_ocaml_copy_list_function typ =
8399 pr "static CAMLprim value\n";
8400 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
8402 pr " CAMLparam0 ();\n";
8403 pr " CAMLlocal2 (rv, v);\n";
8404 pr " unsigned int i;\n";
8406 pr " if (%ss->len == 0)\n" typ;
8407 pr " CAMLreturn (Atom (0));\n";
8409 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
8410 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
8411 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
8412 pr " caml_modify (&Field (rv, i), v);\n";
8414 pr " CAMLreturn (rv);\n";
8422 let has_optpercent_col =
8423 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
8425 pr "static CAMLprim value\n";
8426 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
8428 pr " CAMLparam0 ();\n";
8429 if has_optpercent_col then
8430 pr " CAMLlocal3 (rv, v, v2);\n"
8432 pr " CAMLlocal2 (rv, v);\n";
8434 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
8439 pr " v = caml_copy_string (%s->%s);\n" typ name
8441 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
8442 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
8445 pr " v = caml_alloc_string (32);\n";
8446 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
8447 | name, (FBytes|FInt64|FUInt64) ->
8448 pr " v = caml_copy_int64 (%s->%s);\n" typ name
8449 | name, (FInt32|FUInt32) ->
8450 pr " v = caml_copy_int32 (%s->%s);\n" typ name
8451 | name, FOptPercent ->
8452 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
8453 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
8454 pr " v = caml_alloc (1, 0);\n";
8455 pr " Store_field (v, 0, v2);\n";
8456 pr " } else /* None */\n";
8457 pr " v = Val_int (0);\n";
8459 pr " v = Val_int (%s->%s);\n" typ name
8461 pr " Store_field (rv, %d, v);\n" i
8463 pr " CAMLreturn (rv);\n";
8468 (* Emit a copy_TYPE_list function definition only if that function is used. *)
8471 | typ, (RStructListOnly | RStructAndList) ->
8472 (* generate the function for typ *)
8473 emit_ocaml_copy_list_function typ
8474 | typ, _ -> () (* empty *)
8475 ) (rstructs_used_by all_functions);
8479 fun (name, style, _, _, _, _, _) ->
8480 pr "/* Automatically generated wrapper for function\n";
8482 generate_ocaml_prototype name style;
8487 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
8489 let needs_extra_vs =
8490 match fst style with RConstOptString _ -> true | _ -> false in
8492 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8493 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
8494 List.iter (pr ", value %s") (List.tl params); pr ");\n";
8497 pr "CAMLprim value\n";
8498 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
8499 List.iter (pr ", value %s") (List.tl params);
8504 | [p1; p2; p3; p4; p5] ->
8505 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
8506 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
8507 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
8508 pr " CAMLxparam%d (%s);\n"
8509 (List.length rest) (String.concat ", " rest)
8511 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
8513 if not needs_extra_vs then
8514 pr " CAMLlocal1 (rv);\n"
8516 pr " CAMLlocal3 (rv, v, v2);\n";
8519 pr " guestfs_h *g = Guestfs_val (gv);\n";
8520 pr " if (g == NULL)\n";
8521 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
8527 | Device n | Dev_or_Path n
8531 pr " const char *%s = String_val (%sv);\n" n n
8533 pr " const char *%s =\n" n;
8534 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
8537 pr " const char *%s = String_val (%sv);\n" n n;
8538 pr " size_t %s_size = caml_string_length (%sv);\n" n n
8539 | StringList n | DeviceList n ->
8540 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
8542 pr " int %s = Bool_val (%sv);\n" n n
8544 pr " int %s = Int_val (%sv);\n" n n
8546 pr " int64_t %s = Int64_val (%sv);\n" n n
8549 match fst style with
8550 | RErr -> pr " int r;\n"; "-1"
8551 | RInt _ -> pr " int r;\n"; "-1"
8552 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8553 | RBool _ -> pr " int r;\n"; "-1"
8554 | RConstString _ | RConstOptString _ ->
8555 pr " const char *r;\n"; "NULL"
8556 | RString _ -> pr " char *r;\n"; "NULL"
8561 | RStruct (_, typ) ->
8562 pr " struct guestfs_%s *r;\n" typ; "NULL"
8563 | RStructList (_, typ) ->
8564 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8571 pr " size_t size;\n";
8575 pr " caml_enter_blocking_section ();\n";
8576 pr " r = guestfs_%s " name;
8577 generate_c_call_args ~handle:"g" style;
8579 pr " caml_leave_blocking_section ();\n";
8583 | StringList n | DeviceList n ->
8584 pr " ocaml_guestfs_free_strings (%s);\n" n;
8585 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8586 | Bool _ | Int _ | Int64 _
8587 | FileIn _ | FileOut _ | BufferIn _ -> ()
8590 pr " if (r == %s)\n" error_code;
8591 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
8594 (match fst style with
8595 | RErr -> pr " rv = Val_unit;\n"
8596 | RInt _ -> pr " rv = Val_int (r);\n"
8598 pr " rv = caml_copy_int64 (r);\n"
8599 | RBool _ -> pr " rv = Val_bool (r);\n"
8601 pr " rv = caml_copy_string (r);\n"
8602 | RConstOptString _ ->
8603 pr " if (r) { /* Some string */\n";
8604 pr " v = caml_alloc (1, 0);\n";
8605 pr " v2 = caml_copy_string (r);\n";
8606 pr " Store_field (v, 0, v2);\n";
8607 pr " } else /* None */\n";
8608 pr " v = Val_int (0);\n";
8610 pr " rv = caml_copy_string (r);\n";
8613 pr " rv = caml_copy_string_array ((const char **) r);\n";
8614 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8616 | RStruct (_, typ) ->
8617 pr " rv = copy_%s (r);\n" typ;
8618 pr " guestfs_free_%s (r);\n" typ;
8619 | RStructList (_, typ) ->
8620 pr " rv = copy_%s_list (r);\n" typ;
8621 pr " guestfs_free_%s_list (r);\n" typ;
8623 pr " rv = copy_table (r);\n";
8624 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8627 pr " rv = caml_alloc_string (size);\n";
8628 pr " memcpy (String_val (rv), r, size);\n";
8631 pr " CAMLreturn (rv);\n";
8635 if List.length params > 5 then (
8636 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8637 pr "CAMLprim value ";
8638 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
8639 pr "CAMLprim value\n";
8640 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
8642 pr " return ocaml_guestfs_%s (argv[0]" name;
8643 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
8648 ) all_functions_sorted
8650 and generate_ocaml_structure_decls () =
8653 pr "type %s = {\n" typ;
8656 | name, FString -> pr " %s : string;\n" name
8657 | name, FBuffer -> pr " %s : string;\n" name
8658 | name, FUUID -> pr " %s : string;\n" name
8659 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
8660 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
8661 | name, FChar -> pr " %s : char;\n" name
8662 | name, FOptPercent -> pr " %s : float option;\n" name
8668 and generate_ocaml_prototype ?(is_external = false) name style =
8669 if is_external then pr "external " else pr "val ";
8670 pr "%s : t -> " name;
8673 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _
8674 | BufferIn _ -> pr "string -> "
8675 | OptString _ -> pr "string option -> "
8676 | StringList _ | DeviceList _ -> pr "string array -> "
8677 | Bool _ -> pr "bool -> "
8678 | Int _ -> pr "int -> "
8679 | Int64 _ -> pr "int64 -> "
8681 (match fst style with
8682 | RErr -> pr "unit" (* all errors are turned into exceptions *)
8683 | RInt _ -> pr "int"
8684 | RInt64 _ -> pr "int64"
8685 | RBool _ -> pr "bool"
8686 | RConstString _ -> pr "string"
8687 | RConstOptString _ -> pr "string option"
8688 | RString _ | RBufferOut _ -> pr "string"
8689 | RStringList _ -> pr "string array"
8690 | RStruct (_, typ) -> pr "%s" typ
8691 | RStructList (_, typ) -> pr "%s array" typ
8692 | RHashtable _ -> pr "(string * string) list"
8694 if is_external then (
8696 if List.length (snd style) + 1 > 5 then
8697 pr "\"ocaml_guestfs_%s_byte\" " name;
8698 pr "\"ocaml_guestfs_%s\"" name
8702 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
8703 and generate_perl_xs () =
8704 generate_header CStyle LGPLv2plus;
8707 #include \"EXTERN.h\"
8711 #include <guestfs.h>
8714 #define PRId64 \"lld\"
8718 my_newSVll(long long val) {
8719 #ifdef USE_64_BIT_ALL
8720 return newSViv(val);
8724 len = snprintf(buf, 100, \"%%\" PRId64, val);
8725 return newSVpv(buf, len);
8730 #define PRIu64 \"llu\"
8734 my_newSVull(unsigned long long val) {
8735 #ifdef USE_64_BIT_ALL
8736 return newSVuv(val);
8740 len = snprintf(buf, 100, \"%%\" PRIu64, val);
8741 return newSVpv(buf, len);
8745 /* http://www.perlmonks.org/?node_id=680842 */
8747 XS_unpack_charPtrPtr (SV *arg) {
8752 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
8753 croak (\"array reference expected\");
8755 av = (AV *)SvRV (arg);
8756 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
8758 croak (\"malloc failed\");
8760 for (i = 0; i <= av_len (av); i++) {
8761 SV **elem = av_fetch (av, i, 0);
8763 if (!elem || !*elem)
8764 croak (\"missing element in list\");
8766 ret[i] = SvPV_nolen (*elem);
8774 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
8781 RETVAL = guestfs_create ();
8783 croak (\"could not create guestfs handle\");
8784 guestfs_set_error_handler (RETVAL, NULL, NULL);
8797 fun (name, style, _, _, _, _, _) ->
8798 (match fst style with
8799 | RErr -> pr "void\n"
8800 | RInt _ -> pr "SV *\n"
8801 | RInt64 _ -> pr "SV *\n"
8802 | RBool _ -> pr "SV *\n"
8803 | RConstString _ -> pr "SV *\n"
8804 | RConstOptString _ -> pr "SV *\n"
8805 | RString _ -> pr "SV *\n"
8806 | RBufferOut _ -> pr "SV *\n"
8808 | RStruct _ | RStructList _
8810 pr "void\n" (* all lists returned implictly on the stack *)
8812 (* Call and arguments. *)
8815 fun arg -> pr ", %s" (name_of_argt arg)
8818 pr " guestfs_h *g;\n";
8822 | Pathname n | Device n | Dev_or_Path n | String n
8823 | FileIn n | FileOut n ->
8826 pr " char *%s;\n" n;
8827 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
8829 (* http://www.perlmonks.org/?node_id=554277
8830 * Note that the implicit handle argument means we have
8831 * to add 1 to the ST(x) operator.
8833 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
8834 | StringList n | DeviceList n -> pr " char **%s;\n" n
8835 | Bool n -> pr " int %s;\n" n
8836 | Int n -> pr " int %s;\n" n
8837 | Int64 n -> pr " int64_t %s;\n" n
8840 let do_cleanups () =
8843 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8844 | Bool _ | Int _ | Int64 _
8845 | FileIn _ | FileOut _
8847 | StringList n | DeviceList n -> pr " free (%s);\n" n
8852 (match fst style with
8857 pr " r = guestfs_%s " name;
8858 generate_c_call_args ~handle:"g" style;
8861 pr " if (r == -1)\n";
8862 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8868 pr " %s = guestfs_%s " n name;
8869 generate_c_call_args ~handle:"g" style;
8872 pr " if (%s == -1)\n" n;
8873 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8874 pr " RETVAL = newSViv (%s);\n" n;
8879 pr " int64_t %s;\n" n;
8881 pr " %s = guestfs_%s " n name;
8882 generate_c_call_args ~handle:"g" style;
8885 pr " if (%s == -1)\n" n;
8886 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8887 pr " RETVAL = my_newSVll (%s);\n" n;
8892 pr " const char *%s;\n" n;
8894 pr " %s = guestfs_%s " n name;
8895 generate_c_call_args ~handle:"g" style;
8898 pr " if (%s == NULL)\n" n;
8899 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8900 pr " RETVAL = newSVpv (%s, 0);\n" n;
8903 | RConstOptString n ->
8905 pr " const char *%s;\n" n;
8907 pr " %s = guestfs_%s " n name;
8908 generate_c_call_args ~handle:"g" style;
8911 pr " if (%s == NULL)\n" n;
8912 pr " RETVAL = &PL_sv_undef;\n";
8914 pr " RETVAL = newSVpv (%s, 0);\n" n;
8919 pr " char *%s;\n" n;
8921 pr " %s = guestfs_%s " n name;
8922 generate_c_call_args ~handle:"g" style;
8925 pr " if (%s == NULL)\n" n;
8926 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8927 pr " RETVAL = newSVpv (%s, 0);\n" n;
8928 pr " free (%s);\n" n;
8931 | RStringList n | RHashtable n ->
8933 pr " char **%s;\n" n;
8936 pr " %s = guestfs_%s " n name;
8937 generate_c_call_args ~handle:"g" style;
8940 pr " if (%s == NULL)\n" n;
8941 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8942 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
8943 pr " EXTEND (SP, n);\n";
8944 pr " for (i = 0; i < n; ++i) {\n";
8945 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
8946 pr " free (%s[i]);\n" n;
8948 pr " free (%s);\n" n;
8949 | RStruct (n, typ) ->
8950 let cols = cols_of_struct typ in
8951 generate_perl_struct_code typ cols name style n do_cleanups
8952 | RStructList (n, typ) ->
8953 let cols = cols_of_struct typ in
8954 generate_perl_struct_list_code typ cols name style n do_cleanups
8957 pr " char *%s;\n" n;
8958 pr " size_t size;\n";
8960 pr " %s = guestfs_%s " n name;
8961 generate_c_call_args ~handle:"g" style;
8964 pr " if (%s == NULL)\n" n;
8965 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8966 pr " RETVAL = newSVpvn (%s, size);\n" n;
8967 pr " free (%s);\n" n;
8975 and generate_perl_struct_list_code typ cols name style n do_cleanups =
8977 pr " struct guestfs_%s_list *%s;\n" typ n;
8981 pr " %s = guestfs_%s " n name;
8982 generate_c_call_args ~handle:"g" style;
8985 pr " if (%s == NULL)\n" n;
8986 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8987 pr " EXTEND (SP, %s->len);\n" n;
8988 pr " for (i = 0; i < %s->len; ++i) {\n" n;
8989 pr " hv = newHV ();\n";
8993 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
8994 name (String.length name) n name
8996 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
8997 name (String.length name) n name
8999 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
9000 name (String.length name) n name n name
9001 | name, (FBytes|FUInt64) ->
9002 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
9003 name (String.length name) n name
9005 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
9006 name (String.length name) n name
9007 | name, (FInt32|FUInt32) ->
9008 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
9009 name (String.length name) n name
9011 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
9012 name (String.length name) n name
9013 | name, FOptPercent ->
9014 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
9015 name (String.length name) n name
9017 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
9019 pr " guestfs_free_%s_list (%s);\n" typ n
9021 and generate_perl_struct_code typ cols name style n do_cleanups =
9023 pr " struct guestfs_%s *%s;\n" typ n;
9025 pr " %s = guestfs_%s " n name;
9026 generate_c_call_args ~handle:"g" style;
9029 pr " if (%s == NULL)\n" n;
9030 pr " croak (\"%%s\", guestfs_last_error (g));\n";
9031 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
9033 fun ((name, _) as col) ->
9034 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
9038 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
9041 pr " PUSHs (sv_2mortal (newSVpvn (%s->%s, %s->%s_len)));\n"
9044 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
9046 | name, (FBytes|FUInt64) ->
9047 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
9050 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
9052 | name, (FInt32|FUInt32) ->
9053 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9056 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
9058 | name, FOptPercent ->
9059 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9062 pr " free (%s);\n" n
9064 (* Generate Sys/Guestfs.pm. *)
9065 and generate_perl_pm () =
9066 generate_header HashStyle LGPLv2plus;
9073 Sys::Guestfs - Perl bindings for libguestfs
9079 my $h = Sys::Guestfs->new ();
9080 $h->add_drive ('guest.img');
9082 $h->mount ('/dev/sda1', '/');
9083 $h->touch ('/hello');
9088 The C<Sys::Guestfs> module provides a Perl XS binding to the
9089 libguestfs API for examining and modifying virtual machine
9092 Amongst the things this is good for: making batch configuration
9093 changes to guests, getting disk used/free statistics (see also:
9094 virt-df), migrating between virtualization systems (see also:
9095 virt-p2v), performing partial backups, performing partial guest
9096 clones, cloning guests and changing registry/UUID/hostname info, and
9099 Libguestfs uses Linux kernel and qemu code, and can access any type of
9100 guest filesystem that Linux and qemu can, including but not limited
9101 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9102 schemes, qcow, qcow2, vmdk.
9104 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9105 LVs, what filesystem is in each LV, etc.). It can also run commands
9106 in the context of the guest. Also you can access filesystems over
9109 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
9110 functions for using libguestfs from Perl, including integration
9115 All errors turn into calls to C<croak> (see L<Carp(3)>).
9123 package Sys::Guestfs;
9128 # This version number changes whenever a new function
9129 # is added to the libguestfs API. It is not directly
9130 # related to the libguestfs version number.
9131 use vars qw($VERSION);
9135 XSLoader::load ('Sys::Guestfs');
9137 =item $h = Sys::Guestfs->new ();
9139 Create a new guestfs handle.
9145 my $class = ref ($proto) || $proto;
9147 my $self = Sys::Guestfs::_create ();
9148 bless $self, $class;
9154 (* Actions. We only need to print documentation for these as
9155 * they are pulled in from the XS code automatically.
9158 fun (name, style, _, flags, _, _, longdesc) ->
9159 if not (List.mem NotInDocs flags) then (
9160 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
9162 generate_perl_prototype name style;
9164 pr "%s\n\n" longdesc;
9165 if List.mem ProtocolLimitWarning flags then
9166 pr "%s\n\n" protocol_limit_warning;
9167 if List.mem DangerWillRobinson flags then
9168 pr "%s\n\n" danger_will_robinson;
9169 match deprecation_notice flags with
9171 | Some txt -> pr "%s\n\n" txt
9173 ) all_functions_sorted;
9185 Copyright (C) %s Red Hat Inc.
9189 Please see the file COPYING.LIB for the full license.
9195 L<http://libguestfs.org>,
9196 L<Sys::Guestfs::Lib(3)>.
9201 and generate_perl_prototype name style =
9202 (match fst style with
9210 | RBufferOut n -> pr "$%s = " n
9212 | RHashtable n -> pr "%%%s = " n
9214 | RStructList (n,_) -> pr "@%s = " n
9217 let comma = ref false in
9220 if !comma then pr ", ";
9223 | Pathname n | Device n | Dev_or_Path n | String n
9224 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
9227 | StringList n | DeviceList n ->
9232 (* Generate Python C module. *)
9233 and generate_python_c () =
9234 generate_header CStyle LGPLv2plus;
9237 #define PY_SSIZE_T_CLEAN 1
9240 #if PY_VERSION_HEX < 0x02050000
9241 typedef int Py_ssize_t;
9242 #define PY_SSIZE_T_MAX INT_MAX
9243 #define PY_SSIZE_T_MIN INT_MIN
9250 #include \"guestfs.h\"
9258 get_handle (PyObject *obj)
9261 assert (obj != Py_None);
9262 return ((Pyguestfs_Object *) obj)->g;
9266 put_handle (guestfs_h *g)
9270 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
9273 /* This list should be freed (but not the strings) after use. */
9275 get_string_list (PyObject *obj)
9282 if (!PyList_Check (obj)) {
9283 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
9287 len = PyList_Size (obj);
9288 r = malloc (sizeof (char *) * (len+1));
9290 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
9294 for (i = 0; i < len; ++i)
9295 r[i] = PyString_AsString (PyList_GetItem (obj, i));
9302 put_string_list (char * const * const argv)
9307 for (argc = 0; argv[argc] != NULL; ++argc)
9310 list = PyList_New (argc);
9311 for (i = 0; i < argc; ++i)
9312 PyList_SetItem (list, i, PyString_FromString (argv[i]));
9318 put_table (char * const * const argv)
9320 PyObject *list, *item;
9323 for (argc = 0; argv[argc] != NULL; ++argc)
9326 list = PyList_New (argc >> 1);
9327 for (i = 0; i < argc; i += 2) {
9328 item = PyTuple_New (2);
9329 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
9330 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
9331 PyList_SetItem (list, i >> 1, item);
9338 free_strings (char **argv)
9342 for (argc = 0; argv[argc] != NULL; ++argc)
9348 py_guestfs_create (PyObject *self, PyObject *args)
9352 g = guestfs_create ();
9354 PyErr_SetString (PyExc_RuntimeError,
9355 \"guestfs.create: failed to allocate handle\");
9358 guestfs_set_error_handler (g, NULL, NULL);
9359 return put_handle (g);
9363 py_guestfs_close (PyObject *self, PyObject *args)
9368 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
9370 g = get_handle (py_g);
9374 Py_INCREF (Py_None);
9380 let emit_put_list_function typ =
9381 pr "static PyObject *\n";
9382 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
9384 pr " PyObject *list;\n";
9387 pr " list = PyList_New (%ss->len);\n" typ;
9388 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
9389 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
9390 pr " return list;\n";
9395 (* Structures, turned into Python dictionaries. *)
9398 pr "static PyObject *\n";
9399 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
9401 pr " PyObject *dict;\n";
9403 pr " dict = PyDict_New ();\n";
9407 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9408 pr " PyString_FromString (%s->%s));\n"
9411 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9412 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
9415 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9416 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
9418 | name, (FBytes|FUInt64) ->
9419 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9420 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
9423 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9424 pr " PyLong_FromLongLong (%s->%s));\n"
9427 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9428 pr " PyLong_FromUnsignedLong (%s->%s));\n"
9431 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9432 pr " PyLong_FromLong (%s->%s));\n"
9434 | name, FOptPercent ->
9435 pr " if (%s->%s >= 0)\n" typ name;
9436 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9437 pr " PyFloat_FromDouble ((double) %s->%s));\n"
9440 pr " Py_INCREF (Py_None);\n";
9441 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
9444 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9445 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
9447 pr " return dict;\n";
9453 (* Emit a put_TYPE_list function definition only if that function is used. *)
9456 | typ, (RStructListOnly | RStructAndList) ->
9457 (* generate the function for typ *)
9458 emit_put_list_function typ
9459 | typ, _ -> () (* empty *)
9460 ) (rstructs_used_by all_functions);
9462 (* Python wrapper functions. *)
9464 fun (name, style, _, _, _, _, _) ->
9465 pr "static PyObject *\n";
9466 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
9469 pr " PyObject *py_g;\n";
9470 pr " guestfs_h *g;\n";
9471 pr " PyObject *py_r;\n";
9474 match fst style with
9475 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9476 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9477 | RConstString _ | RConstOptString _ ->
9478 pr " const char *r;\n"; "NULL"
9479 | RString _ -> pr " char *r;\n"; "NULL"
9480 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9481 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9482 | RStructList (_, typ) ->
9483 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9486 pr " size_t size;\n";
9491 | Pathname n | Device n | Dev_or_Path n | String n
9492 | FileIn n | FileOut n ->
9493 pr " const char *%s;\n" n
9494 | OptString n -> pr " const char *%s;\n" n
9496 pr " const char *%s;\n" n;
9497 pr " Py_ssize_t %s_size;\n" n
9498 | StringList n | DeviceList n ->
9499 pr " PyObject *py_%s;\n" n;
9500 pr " char **%s;\n" n
9501 | Bool n -> pr " int %s;\n" n
9502 | Int n -> pr " int %s;\n" n
9503 | Int64 n -> pr " long long %s;\n" n
9508 (* Convert the parameters. *)
9509 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
9512 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
9513 | OptString _ -> pr "z"
9514 | StringList _ | DeviceList _ -> pr "O"
9515 | Bool _ -> pr "i" (* XXX Python has booleans? *)
9517 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
9518 * emulate C's int/long/long long in Python?
9520 | BufferIn _ -> pr "s#"
9522 pr ":guestfs_%s\",\n" name;
9526 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
9527 | OptString n -> pr ", &%s" n
9528 | StringList n | DeviceList n -> pr ", &py_%s" n
9529 | Bool n -> pr ", &%s" n
9530 | Int n -> pr ", &%s" n
9531 | Int64 n -> pr ", &%s" n
9532 | BufferIn n -> pr ", &%s, &%s_size" n n
9536 pr " return NULL;\n";
9538 pr " g = get_handle (py_g);\n";
9541 | Pathname _ | Device _ | Dev_or_Path _ | String _
9542 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9544 | StringList n | DeviceList n ->
9545 pr " %s = get_string_list (py_%s);\n" n n;
9546 pr " if (!%s) return NULL;\n" n
9551 pr " r = guestfs_%s " name;
9552 generate_c_call_args ~handle:"g" style;
9557 | Pathname _ | Device _ | Dev_or_Path _ | String _
9558 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9560 | StringList n | DeviceList n ->
9561 pr " free (%s);\n" n
9564 pr " if (r == %s) {\n" error_code;
9565 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
9566 pr " return NULL;\n";
9570 (match fst style with
9572 pr " Py_INCREF (Py_None);\n";
9573 pr " py_r = Py_None;\n"
9575 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
9576 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
9577 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
9578 | RConstOptString _ ->
9580 pr " py_r = PyString_FromString (r);\n";
9582 pr " Py_INCREF (Py_None);\n";
9583 pr " py_r = Py_None;\n";
9586 pr " py_r = PyString_FromString (r);\n";
9589 pr " py_r = put_string_list (r);\n";
9590 pr " free_strings (r);\n"
9591 | RStruct (_, typ) ->
9592 pr " py_r = put_%s (r);\n" typ;
9593 pr " guestfs_free_%s (r);\n" typ
9594 | RStructList (_, typ) ->
9595 pr " py_r = put_%s_list (r);\n" typ;
9596 pr " guestfs_free_%s_list (r);\n" typ
9598 pr " py_r = put_table (r);\n";
9599 pr " free_strings (r);\n"
9601 pr " py_r = PyString_FromStringAndSize (r, size);\n";
9605 pr " return py_r;\n";
9610 (* Table of functions. *)
9611 pr "static PyMethodDef methods[] = {\n";
9612 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
9613 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
9615 fun (name, _, _, _, _, _, _) ->
9616 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
9619 pr " { NULL, NULL, 0, NULL }\n";
9623 (* Init function. *)
9626 initlibguestfsmod (void)
9628 static int initialized = 0;
9630 if (initialized) return;
9631 Py_InitModule ((char *) \"libguestfsmod\", methods);
9636 (* Generate Python module. *)
9637 and generate_python_py () =
9638 generate_header HashStyle LGPLv2plus;
9641 u\"\"\"Python bindings for libguestfs
9644 g = guestfs.GuestFS ()
9645 g.add_drive (\"guest.img\")
9647 parts = g.list_partitions ()
9649 The guestfs module provides a Python binding to the libguestfs API
9650 for examining and modifying virtual machine disk images.
9652 Amongst the things this is good for: making batch configuration
9653 changes to guests, getting disk used/free statistics (see also:
9654 virt-df), migrating between virtualization systems (see also:
9655 virt-p2v), performing partial backups, performing partial guest
9656 clones, cloning guests and changing registry/UUID/hostname info, and
9659 Libguestfs uses Linux kernel and qemu code, and can access any type of
9660 guest filesystem that Linux and qemu can, including but not limited
9661 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9662 schemes, qcow, qcow2, vmdk.
9664 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9665 LVs, what filesystem is in each LV, etc.). It can also run commands
9666 in the context of the guest. Also you can access filesystems over
9669 Errors which happen while using the API are turned into Python
9670 RuntimeError exceptions.
9672 To create a guestfs handle you usually have to perform the following
9675 # Create the handle, call add_drive at least once, and possibly
9676 # several times if the guest has multiple block devices:
9677 g = guestfs.GuestFS ()
9678 g.add_drive (\"guest.img\")
9680 # Launch the qemu subprocess and wait for it to become ready:
9683 # Now you can issue commands, for example:
9688 import libguestfsmod
9691 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
9693 def __init__ (self):
9694 \"\"\"Create a new libguestfs handle.\"\"\"
9695 self._o = libguestfsmod.create ()
9698 libguestfsmod.close (self._o)
9703 fun (name, style, _, flags, _, _, longdesc) ->
9705 generate_py_call_args ~handle:"self" (snd style);
9708 if not (List.mem NotInDocs flags) then (
9709 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9711 match fst style with
9712 | RErr | RInt _ | RInt64 _ | RBool _
9713 | RConstOptString _ | RConstString _
9714 | RString _ | RBufferOut _ -> doc
9716 doc ^ "\n\nThis function returns a list of strings."
9717 | RStruct (_, typ) ->
9718 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
9719 | RStructList (_, typ) ->
9720 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
9722 doc ^ "\n\nThis function returns a dictionary." in
9724 if List.mem ProtocolLimitWarning flags then
9725 doc ^ "\n\n" ^ protocol_limit_warning
9728 if List.mem DangerWillRobinson flags then
9729 doc ^ "\n\n" ^ danger_will_robinson
9732 match deprecation_notice flags with
9734 | Some txt -> doc ^ "\n\n" ^ txt in
9735 let doc = pod2text ~width:60 name doc in
9736 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
9737 let doc = String.concat "\n " doc in
9738 pr " u\"\"\"%s\"\"\"\n" doc;
9740 pr " return libguestfsmod.%s " name;
9741 generate_py_call_args ~handle:"self._o" (snd style);
9746 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
9747 and generate_py_call_args ~handle args =
9749 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9752 (* Useful if you need the longdesc POD text as plain text. Returns a
9755 * Because this is very slow (the slowest part of autogeneration),
9756 * we memoize the results.
9758 and pod2text ~width name longdesc =
9759 let key = width, name, longdesc in
9760 try Hashtbl.find pod2text_memo key
9762 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
9763 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
9765 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
9766 let chan = open_process_in cmd in
9767 let lines = ref [] in
9769 let line = input_line chan in
9770 if i = 1 then (* discard the first line of output *)
9773 let line = triml line in
9774 lines := line :: !lines;
9777 let lines = try loop 1 with End_of_file -> List.rev !lines in
9779 (match close_process_in chan with
9782 failwithf "pod2text: process exited with non-zero status (%d)" i
9783 | WSIGNALED i | WSTOPPED i ->
9784 failwithf "pod2text: process signalled or stopped by signal %d" i
9786 Hashtbl.add pod2text_memo key lines;
9787 pod2text_memo_updated ();
9790 (* Generate ruby bindings. *)
9791 and generate_ruby_c () =
9792 generate_header CStyle LGPLv2plus;
9800 #include \"guestfs.h\"
9802 #include \"extconf.h\"
9804 /* For Ruby < 1.9 */
9806 #define RARRAY_LEN(r) (RARRAY((r))->len)
9809 static VALUE m_guestfs; /* guestfs module */
9810 static VALUE c_guestfs; /* guestfs_h handle */
9811 static VALUE e_Error; /* used for all errors */
9813 static void ruby_guestfs_free (void *p)
9816 guestfs_close ((guestfs_h *) p);
9819 static VALUE ruby_guestfs_create (VALUE m)
9823 g = guestfs_create ();
9825 rb_raise (e_Error, \"failed to create guestfs handle\");
9827 /* Don't print error messages to stderr by default. */
9828 guestfs_set_error_handler (g, NULL, NULL);
9830 /* Wrap it, and make sure the close function is called when the
9833 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
9836 static VALUE ruby_guestfs_close (VALUE gv)
9839 Data_Get_Struct (gv, guestfs_h, g);
9841 ruby_guestfs_free (g);
9842 DATA_PTR (gv) = NULL;
9850 fun (name, style, _, _, _, _, _) ->
9851 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
9852 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
9855 pr " guestfs_h *g;\n";
9856 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
9858 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
9864 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
9865 pr " Check_Type (%sv, T_STRING);\n" n;
9866 pr " const char *%s = StringValueCStr (%sv);\n" n n;
9868 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9869 pr " \"%s\", \"%s\");\n" n name
9871 pr " Check_Type (%sv, T_STRING);\n" n;
9872 pr " const char *%s = RSTRING (%sv)->ptr;\n" n n;
9874 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9875 pr " \"%s\", \"%s\");\n" n name;
9876 pr " size_t %s_size = RSTRING (%sv)->len;\n" n n
9878 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
9879 | StringList n | DeviceList n ->
9880 pr " char **%s;\n" n;
9881 pr " Check_Type (%sv, T_ARRAY);\n" n;
9883 pr " int i, len;\n";
9884 pr " len = RARRAY_LEN (%sv);\n" n;
9885 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
9887 pr " for (i = 0; i < len; ++i) {\n";
9888 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
9889 pr " %s[i] = StringValueCStr (v);\n" n;
9891 pr " %s[len] = NULL;\n" n;
9894 pr " int %s = RTEST (%sv);\n" n n
9896 pr " int %s = NUM2INT (%sv);\n" n n
9898 pr " long long %s = NUM2LL (%sv);\n" n n
9903 match fst style with
9904 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9905 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9906 | RConstString _ | RConstOptString _ ->
9907 pr " const char *r;\n"; "NULL"
9908 | RString _ -> pr " char *r;\n"; "NULL"
9909 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9910 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9911 | RStructList (_, typ) ->
9912 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9915 pr " size_t size;\n";
9919 pr " r = guestfs_%s " name;
9920 generate_c_call_args ~handle:"g" style;
9925 | Pathname _ | Device _ | Dev_or_Path _ | String _
9926 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9928 | StringList n | DeviceList n ->
9929 pr " free (%s);\n" n
9932 pr " if (r == %s)\n" error_code;
9933 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
9936 (match fst style with
9938 pr " return Qnil;\n"
9939 | RInt _ | RBool _ ->
9940 pr " return INT2NUM (r);\n"
9942 pr " return ULL2NUM (r);\n"
9944 pr " return rb_str_new2 (r);\n";
9945 | RConstOptString _ ->
9947 pr " return rb_str_new2 (r);\n";
9949 pr " return Qnil;\n";
9951 pr " VALUE rv = rb_str_new2 (r);\n";
9955 pr " int i, len = 0;\n";
9956 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
9957 pr " VALUE rv = rb_ary_new2 (len);\n";
9958 pr " for (i = 0; r[i] != NULL; ++i) {\n";
9959 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
9960 pr " free (r[i]);\n";
9964 | RStruct (_, typ) ->
9965 let cols = cols_of_struct typ in
9966 generate_ruby_struct_code typ cols
9967 | RStructList (_, typ) ->
9968 let cols = cols_of_struct typ in
9969 generate_ruby_struct_list_code typ cols
9971 pr " VALUE rv = rb_hash_new ();\n";
9973 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
9974 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
9975 pr " free (r[i]);\n";
9976 pr " free (r[i+1]);\n";
9981 pr " VALUE rv = rb_str_new (r, size);\n";
9991 /* Initialize the module. */
9992 void Init__guestfs ()
9994 m_guestfs = rb_define_module (\"Guestfs\");
9995 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
9996 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
9998 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
9999 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
10002 (* Define the rest of the methods. *)
10004 fun (name, style, _, _, _, _, _) ->
10005 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
10006 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
10011 (* Ruby code to return a struct. *)
10012 and generate_ruby_struct_code typ cols =
10013 pr " VALUE rv = rb_hash_new ();\n";
10017 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
10019 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
10021 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
10022 | name, (FBytes|FUInt64) ->
10023 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10025 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
10027 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
10029 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
10030 | name, FOptPercent ->
10031 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
10032 | name, FChar -> (* XXX wrong? *)
10033 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10035 pr " guestfs_free_%s (r);\n" typ;
10038 (* Ruby code to return a struct list. *)
10039 and generate_ruby_struct_list_code typ cols =
10040 pr " VALUE rv = rb_ary_new2 (r->len);\n";
10042 pr " for (i = 0; i < r->len; ++i) {\n";
10043 pr " VALUE hv = rb_hash_new ();\n";
10047 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
10049 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
10051 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
10052 | name, (FBytes|FUInt64) ->
10053 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10055 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
10057 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
10059 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
10060 | name, FOptPercent ->
10061 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
10062 | name, FChar -> (* XXX wrong? *)
10063 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10065 pr " rb_ary_push (rv, hv);\n";
10067 pr " guestfs_free_%s_list (r);\n" typ;
10070 (* Generate Java bindings GuestFS.java file. *)
10071 and generate_java_java () =
10072 generate_header CStyle LGPLv2plus;
10075 package com.redhat.et.libguestfs;
10077 import java.util.HashMap;
10078 import com.redhat.et.libguestfs.LibGuestFSException;
10079 import com.redhat.et.libguestfs.PV;
10080 import com.redhat.et.libguestfs.VG;
10081 import com.redhat.et.libguestfs.LV;
10082 import com.redhat.et.libguestfs.Stat;
10083 import com.redhat.et.libguestfs.StatVFS;
10084 import com.redhat.et.libguestfs.IntBool;
10085 import com.redhat.et.libguestfs.Dirent;
10088 * The GuestFS object is a libguestfs handle.
10092 public class GuestFS {
10093 // Load the native code.
10095 System.loadLibrary (\"guestfs_jni\");
10099 * The native guestfs_h pointer.
10104 * Create a libguestfs handle.
10106 * @throws LibGuestFSException
10108 public GuestFS () throws LibGuestFSException
10112 private native long _create () throws LibGuestFSException;
10115 * Close a libguestfs handle.
10117 * You can also leave handles to be collected by the garbage
10118 * collector, but this method ensures that the resources used
10119 * by the handle are freed up immediately. If you call any
10120 * other methods after closing the handle, you will get an
10123 * @throws LibGuestFSException
10125 public void close () throws LibGuestFSException
10131 private native void _close (long g) throws LibGuestFSException;
10133 public void finalize () throws LibGuestFSException
10141 fun (name, style, _, flags, _, shortdesc, longdesc) ->
10142 if not (List.mem NotInDocs flags); then (
10143 let doc = replace_str longdesc "C<guestfs_" "C<g." in
10145 if List.mem ProtocolLimitWarning flags then
10146 doc ^ "\n\n" ^ protocol_limit_warning
10149 if List.mem DangerWillRobinson flags then
10150 doc ^ "\n\n" ^ danger_will_robinson
10153 match deprecation_notice flags with
10155 | Some txt -> doc ^ "\n\n" ^ txt in
10156 let doc = pod2text ~width:60 name doc in
10157 let doc = List.map ( (* RHBZ#501883 *)
10160 | nonempty -> nonempty
10162 let doc = String.concat "\n * " doc in
10165 pr " * %s\n" shortdesc;
10168 pr " * @throws LibGuestFSException\n";
10172 generate_java_prototype ~public:true ~semicolon:false name style;
10175 pr " if (g == 0)\n";
10176 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
10179 if fst style <> RErr then pr "return ";
10181 generate_java_call_args ~handle:"g" (snd style);
10185 generate_java_prototype ~privat:true ~native:true name style;
10192 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
10193 and generate_java_call_args ~handle args =
10195 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
10198 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
10199 ?(semicolon=true) name style =
10200 if privat then pr "private ";
10201 if public then pr "public ";
10202 if native then pr "native ";
10205 (match fst style with
10206 | RErr -> pr "void ";
10207 | RInt _ -> pr "int ";
10208 | RInt64 _ -> pr "long ";
10209 | RBool _ -> pr "boolean ";
10210 | RConstString _ | RConstOptString _ | RString _
10211 | RBufferOut _ -> pr "String ";
10212 | RStringList _ -> pr "String[] ";
10213 | RStruct (_, typ) ->
10214 let name = java_name_of_struct typ in
10216 | RStructList (_, typ) ->
10217 let name = java_name_of_struct typ in
10219 | RHashtable _ -> pr "HashMap<String,String> ";
10222 if native then pr "_%s " name else pr "%s " name;
10224 let needs_comma = ref false in
10227 needs_comma := true
10233 if !needs_comma then pr ", ";
10234 needs_comma := true;
10238 | Device n | Dev_or_Path n
10246 | StringList n | DeviceList n ->
10257 pr " throws LibGuestFSException";
10258 if semicolon then pr ";"
10260 and generate_java_struct jtyp cols () =
10261 generate_header CStyle LGPLv2plus;
10264 package com.redhat.et.libguestfs;
10267 * Libguestfs %s structure.
10279 | name, FBuffer -> pr " public String %s;\n" name
10280 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
10281 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
10282 | name, FChar -> pr " public char %s;\n" name
10283 | name, FOptPercent ->
10284 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
10285 pr " public float %s;\n" name
10290 and generate_java_c () =
10291 generate_header CStyle LGPLv2plus;
10295 #include <stdlib.h>
10296 #include <string.h>
10298 #include \"com_redhat_et_libguestfs_GuestFS.h\"
10299 #include \"guestfs.h\"
10301 /* Note that this function returns. The exception is not thrown
10302 * until after the wrapper function returns.
10305 throw_exception (JNIEnv *env, const char *msg)
10308 cl = (*env)->FindClass (env,
10309 \"com/redhat/et/libguestfs/LibGuestFSException\");
10310 (*env)->ThrowNew (env, cl, msg);
10313 JNIEXPORT jlong JNICALL
10314 Java_com_redhat_et_libguestfs_GuestFS__1create
10315 (JNIEnv *env, jobject obj)
10319 g = guestfs_create ();
10321 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
10324 guestfs_set_error_handler (g, NULL, NULL);
10325 return (jlong) (long) g;
10328 JNIEXPORT void JNICALL
10329 Java_com_redhat_et_libguestfs_GuestFS__1close
10330 (JNIEnv *env, jobject obj, jlong jg)
10332 guestfs_h *g = (guestfs_h *) (long) jg;
10339 fun (name, style, _, _, _, _, _) ->
10341 (match fst style with
10342 | RErr -> pr "void ";
10343 | RInt _ -> pr "jint ";
10344 | RInt64 _ -> pr "jlong ";
10345 | RBool _ -> pr "jboolean ";
10346 | RConstString _ | RConstOptString _ | RString _
10347 | RBufferOut _ -> pr "jstring ";
10348 | RStruct _ | RHashtable _ ->
10350 | RStringList _ | RStructList _ ->
10351 pr "jobjectArray ";
10354 pr "Java_com_redhat_et_libguestfs_GuestFS_";
10355 pr "%s" (replace_str ("_" ^ name) "_" "_1");
10357 pr " (JNIEnv *env, jobject obj, jlong jg";
10361 | Device n | Dev_or_Path n
10366 pr ", jstring j%s" n
10368 pr ", jbyteArray j%s" n
10369 | StringList n | DeviceList n ->
10370 pr ", jobjectArray j%s" n
10372 pr ", jboolean j%s" n
10380 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
10381 let error_code, no_ret =
10382 match fst style with
10383 | RErr -> pr " int r;\n"; "-1", ""
10385 | RInt _ -> pr " int r;\n"; "-1", "0"
10386 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
10387 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
10388 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
10390 pr " jstring jr;\n";
10391 pr " char *r;\n"; "NULL", "NULL"
10393 pr " jobjectArray jr;\n";
10394 pr " int r_len;\n";
10395 pr " jclass cl;\n";
10396 pr " jstring jstr;\n";
10397 pr " char **r;\n"; "NULL", "NULL"
10398 | RStruct (_, typ) ->
10399 pr " jobject jr;\n";
10400 pr " jclass cl;\n";
10401 pr " jfieldID fl;\n";
10402 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
10403 | RStructList (_, typ) ->
10404 pr " jobjectArray jr;\n";
10405 pr " jclass cl;\n";
10406 pr " jfieldID fl;\n";
10407 pr " jobject jfl;\n";
10408 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
10409 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
10411 pr " jstring jr;\n";
10413 pr " size_t size;\n";
10418 | Device n | Dev_or_Path n
10423 pr " const char *%s;\n" n
10425 pr " jbyte *%s;\n" n;
10426 pr " size_t %s_size;\n" n
10427 | StringList n | DeviceList n ->
10428 pr " int %s_len;\n" n;
10429 pr " const char **%s;\n" n
10434 pr " int64_t %s;\n" n
10438 (match fst style with
10439 | RStringList _ | RStructList _ -> true
10440 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
10441 | RConstOptString _
10442 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
10443 List.exists (function
10444 | StringList _ -> true
10445 | DeviceList _ -> true
10446 | _ -> false) (snd style) in
10452 (* Get the parameters. *)
10456 | Device n | Dev_or_Path n
10460 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
10462 (* This is completely undocumented, but Java null becomes
10463 * a NULL parameter.
10465 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
10467 pr " %s = (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
10468 pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
10469 | StringList n | DeviceList n ->
10470 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
10471 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
10472 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10473 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10475 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
10477 pr " %s[%s_len] = NULL;\n" n n;
10481 pr " %s = j%s;\n" n n
10484 (* Make the call. *)
10485 pr " r = guestfs_%s " name;
10486 generate_c_call_args ~handle:"g" style;
10489 (* Release the parameters. *)
10493 | Device n | Dev_or_Path n
10497 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10499 pr " if (j%s)\n" n;
10500 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10502 pr " (*env)->ReleaseByteArrayElements (env, j%s, %s, 0);\n" n n
10503 | StringList n | DeviceList n ->
10504 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10505 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10507 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
10509 pr " free (%s);\n" n
10515 (* Check for errors. *)
10516 pr " if (r == %s) {\n" error_code;
10517 pr " throw_exception (env, guestfs_last_error (g));\n";
10518 pr " return %s;\n" no_ret;
10521 (* Return value. *)
10522 (match fst style with
10524 | RInt _ -> pr " return (jint) r;\n"
10525 | RBool _ -> pr " return (jboolean) r;\n"
10526 | RInt64 _ -> pr " return (jlong) r;\n"
10527 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
10528 | RConstOptString _ ->
10529 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
10531 pr " jr = (*env)->NewStringUTF (env, r);\n";
10535 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
10536 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
10537 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
10538 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
10539 pr " for (i = 0; i < r_len; ++i) {\n";
10540 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
10541 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
10542 pr " free (r[i]);\n";
10546 | RStruct (_, typ) ->
10547 let jtyp = java_name_of_struct typ in
10548 let cols = cols_of_struct typ in
10549 generate_java_struct_return typ jtyp cols
10550 | RStructList (_, typ) ->
10551 let jtyp = java_name_of_struct typ in
10552 let cols = cols_of_struct typ in
10553 generate_java_struct_list_return typ jtyp cols
10556 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
10557 pr " return NULL;\n"
10559 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
10568 and generate_java_struct_return typ jtyp cols =
10569 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10570 pr " jr = (*env)->AllocObject (env, cl);\n";
10574 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10575 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
10578 pr " char s[33];\n";
10579 pr " memcpy (s, r->%s, 32);\n" name;
10580 pr " s[32] = 0;\n";
10581 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10582 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10586 pr " int len = r->%s_len;\n" name;
10587 pr " char s[len+1];\n";
10588 pr " memcpy (s, r->%s, len);\n" name;
10589 pr " s[len] = 0;\n";
10590 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10591 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10593 | name, (FBytes|FUInt64|FInt64) ->
10594 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10595 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10596 | name, (FUInt32|FInt32) ->
10597 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10598 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10599 | name, FOptPercent ->
10600 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10601 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
10603 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10604 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10609 and generate_java_struct_list_return typ jtyp cols =
10610 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10611 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
10612 pr " for (i = 0; i < r->len; ++i) {\n";
10613 pr " jfl = (*env)->AllocObject (env, cl);\n";
10617 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10618 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
10621 pr " char s[33];\n";
10622 pr " memcpy (s, r->val[i].%s, 32);\n" name;
10623 pr " s[32] = 0;\n";
10624 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10625 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10629 pr " int len = r->val[i].%s_len;\n" name;
10630 pr " char s[len+1];\n";
10631 pr " memcpy (s, r->val[i].%s, len);\n" name;
10632 pr " s[len] = 0;\n";
10633 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10634 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10636 | name, (FBytes|FUInt64|FInt64) ->
10637 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10638 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10639 | name, (FUInt32|FInt32) ->
10640 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10641 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10642 | name, FOptPercent ->
10643 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10644 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
10646 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10647 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10649 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
10651 pr " guestfs_free_%s_list (r);\n" typ;
10654 and generate_java_makefile_inc () =
10655 generate_header HashStyle GPLv2plus;
10657 pr "java_built_sources = \\\n";
10660 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
10662 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
10664 and generate_haskell_hs () =
10665 generate_header HaskellStyle LGPLv2plus;
10667 (* XXX We only know how to generate partial FFI for Haskell
10668 * at the moment. Please help out!
10670 let can_generate style =
10674 | RInt64 _, _ -> true
10676 | RConstString _, _
10677 | RConstOptString _, _
10683 | RBufferOut _, _ -> false in
10686 {-# INCLUDE <guestfs.h> #-}
10687 {-# LANGUAGE ForeignFunctionInterface #-}
10692 (* List out the names of the actions we want to export. *)
10694 fun (name, style, _, _, _, _, _) ->
10695 if can_generate style then pr ",\n %s" name
10701 -- Unfortunately some symbols duplicate ones already present
10702 -- in Prelude. We don't know which, so we hard-code a list
10704 import Prelude hiding (truncate)
10708 import Foreign.C.Types
10710 import Control.Exception
10711 import Data.Typeable
10713 data GuestfsS = GuestfsS -- represents the opaque C struct
10714 type GuestfsP = Ptr GuestfsS -- guestfs_h *
10715 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
10717 -- XXX define properly later XXX
10721 data IntBool = IntBool
10723 data StatVFS = StatVFS
10724 data Hashtable = Hashtable
10726 foreign import ccall unsafe \"guestfs_create\" c_create
10728 foreign import ccall unsafe \"&guestfs_close\" c_close
10729 :: FunPtr (GuestfsP -> IO ())
10730 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
10731 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
10733 create :: IO GuestfsH
10736 c_set_error_handler p nullPtr nullPtr
10737 h <- newForeignPtr c_close p
10740 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
10741 :: GuestfsP -> IO CString
10743 -- last_error :: GuestfsH -> IO (Maybe String)
10744 -- last_error h = do
10745 -- str <- withForeignPtr h (\\p -> c_last_error p)
10746 -- maybePeek peekCString str
10748 last_error :: GuestfsH -> IO (String)
10750 str <- withForeignPtr h (\\p -> c_last_error p)
10751 if (str == nullPtr)
10752 then return \"no error\"
10753 else peekCString str
10757 (* Generate wrappers for each foreign function. *)
10759 fun (name, style, _, _, _, _, _) ->
10760 if can_generate style then (
10761 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
10763 generate_haskell_prototype ~handle:"GuestfsP" style;
10767 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
10769 pr "%s %s = do\n" name
10770 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
10772 (* Convert pointer arguments using with* functions. *)
10777 | Pathname n | Device n | Dev_or_Path n | String n ->
10778 pr "withCString %s $ \\%s -> " n n
10780 pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
10781 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
10782 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
10783 | Bool _ | Int _ | Int64 _ -> ()
10785 (* Convert integer arguments. *)
10789 | Bool n -> sprintf "(fromBool %s)" n
10790 | Int n -> sprintf "(fromIntegral %s)" n
10791 | Int64 n -> sprintf "(fromIntegral %s)" n
10792 | FileIn n | FileOut n
10793 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
10794 | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
10796 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
10797 (String.concat " " ("p" :: args));
10798 (match fst style with
10799 | RErr | RInt _ | RInt64 _ | RBool _ ->
10800 pr " if (r == -1)\n";
10802 pr " err <- last_error h\n";
10804 | RConstString _ | RConstOptString _ | RString _
10805 | RStringList _ | RStruct _
10806 | RStructList _ | RHashtable _ | RBufferOut _ ->
10807 pr " if (r == nullPtr)\n";
10809 pr " err <- last_error h\n";
10812 (match fst style with
10814 pr " else return ()\n"
10816 pr " else return (fromIntegral r)\n"
10818 pr " else return (fromIntegral r)\n"
10820 pr " else return (toBool r)\n"
10822 | RConstOptString _
10829 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
10835 and generate_haskell_prototype ~handle ?(hs = false) style =
10836 pr "%s -> " handle;
10837 let string = if hs then "String" else "CString" in
10838 let int = if hs then "Int" else "CInt" in
10839 let bool = if hs then "Bool" else "CInt" in
10840 let int64 = if hs then "Integer" else "Int64" in
10844 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
10846 if hs then pr "String"
10847 else pr "CString -> CInt"
10848 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
10849 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
10850 | Bool _ -> pr "%s" bool
10851 | Int _ -> pr "%s" int
10852 | Int64 _ -> pr "%s" int
10853 | FileIn _ -> pr "%s" string
10854 | FileOut _ -> pr "%s" string
10859 (match fst style with
10860 | RErr -> if not hs then pr "CInt"
10861 | RInt _ -> pr "%s" int
10862 | RInt64 _ -> pr "%s" int64
10863 | RBool _ -> pr "%s" bool
10864 | RConstString _ -> pr "%s" string
10865 | RConstOptString _ -> pr "Maybe %s" string
10866 | RString _ -> pr "%s" string
10867 | RStringList _ -> pr "[%s]" string
10868 | RStruct (_, typ) ->
10869 let name = java_name_of_struct typ in
10871 | RStructList (_, typ) ->
10872 let name = java_name_of_struct typ in
10874 | RHashtable _ -> pr "Hashtable"
10875 | RBufferOut _ -> pr "%s" string
10879 and generate_csharp () =
10880 generate_header CPlusPlusStyle LGPLv2plus;
10882 (* XXX Make this configurable by the C# assembly users. *)
10883 let library = "libguestfs.so.0" in
10886 // These C# bindings are highly experimental at present.
10888 // Firstly they only work on Linux (ie. Mono). In order to get them
10889 // to work on Windows (ie. .Net) you would need to port the library
10890 // itself to Windows first.
10892 // The second issue is that some calls are known to be incorrect and
10893 // can cause Mono to segfault. Particularly: calls which pass or
10894 // return string[], or return any structure value. This is because
10895 // we haven't worked out the correct way to do this from C#.
10897 // The third issue is that when compiling you get a lot of warnings.
10898 // We are not sure whether the warnings are important or not.
10900 // Fourthly we do not routinely build or test these bindings as part
10901 // of the make && make check cycle, which means that regressions might
10904 // Suggestions and patches are welcome.
10908 // gmcs Libguestfs.cs
10909 // mono Libguestfs.exe
10911 // (You'll probably want to add a Test class / static main function
10912 // otherwise this won't do anything useful).
10916 using System.Runtime.InteropServices;
10917 using System.Runtime.Serialization;
10918 using System.Collections;
10922 class Error : System.ApplicationException
10924 public Error (string message) : base (message) {}
10925 protected Error (SerializationInfo info, StreamingContext context) {}
10932 [DllImport (\"%s\")]
10933 static extern IntPtr guestfs_create ();
10937 _handle = guestfs_create ();
10938 if (_handle == IntPtr.Zero)
10939 throw new Error (\"could not create guestfs handle\");
10942 [DllImport (\"%s\")]
10943 static extern void guestfs_close (IntPtr h);
10947 guestfs_close (_handle);
10950 [DllImport (\"%s\")]
10951 static extern string guestfs_last_error (IntPtr h);
10953 " library library library;
10955 (* Generate C# structure bindings. We prefix struct names with
10956 * underscore because C# cannot have conflicting struct names and
10957 * method names (eg. "class stat" and "stat").
10961 pr " [StructLayout (LayoutKind.Sequential)]\n";
10962 pr " public class _%s {\n" typ;
10965 | name, FChar -> pr " char %s;\n" name
10966 | name, FString -> pr " string %s;\n" name
10968 pr " uint %s_len;\n" name;
10969 pr " string %s;\n" name
10971 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
10972 pr " string %s;\n" name
10973 | name, FUInt32 -> pr " uint %s;\n" name
10974 | name, FInt32 -> pr " int %s;\n" name
10975 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
10976 | name, FInt64 -> pr " long %s;\n" name
10977 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
10983 (* Generate C# function bindings. *)
10985 fun (name, style, _, _, _, shortdesc, _) ->
10986 let rec csharp_return_type () =
10987 match fst style with
10989 | RBool n -> "bool"
10991 | RInt64 n -> "long"
10993 | RConstOptString n
10995 | RBufferOut n -> "string"
10996 | RStruct (_,n) -> "_" ^ n
10997 | RHashtable n -> "Hashtable"
10998 | RStringList n -> "string[]"
10999 | RStructList (_,n) -> sprintf "_%s[]" n
11001 and c_return_type () =
11002 match fst style with
11006 | RInt64 _ -> "long"
11008 | RConstOptString _
11010 | RBufferOut _ -> "string"
11011 | RStruct (_,n) -> "_" ^ n
11013 | RStringList _ -> "string[]"
11014 | RStructList (_,n) -> sprintf "_%s[]" n
11016 and c_error_comparison () =
11017 match fst style with
11021 | RInt64 _ -> "== -1"
11023 | RConstOptString _
11029 | RStructList (_,_) -> "== null"
11031 and generate_extern_prototype () =
11032 pr " static extern %s guestfs_%s (IntPtr h"
11033 (c_return_type ()) name;
11036 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11037 | FileIn n | FileOut n
11039 pr ", [In] string %s" n
11040 | StringList n | DeviceList n ->
11041 pr ", [In] string[] %s" n
11051 and generate_public_prototype () =
11052 pr " public %s %s (" (csharp_return_type ()) name;
11053 let comma = ref false in
11055 if !comma then pr ", ";
11060 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11061 | FileIn n | FileOut n
11063 next (); pr "string %s" n
11064 | StringList n | DeviceList n ->
11065 next (); pr "string[] %s" n
11067 next (); pr "bool %s" n
11069 next (); pr "int %s" n
11071 next (); pr "long %s" n
11075 and generate_call () =
11076 pr "guestfs_%s (_handle" name;
11077 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
11081 pr " [DllImport (\"%s\")]\n" library;
11082 generate_extern_prototype ();
11084 pr " /// <summary>\n";
11085 pr " /// %s\n" shortdesc;
11086 pr " /// </summary>\n";
11087 generate_public_prototype ();
11089 pr " %s r;\n" (c_return_type ());
11092 pr " if (r %s)\n" (c_error_comparison ());
11093 pr " throw new Error (guestfs_last_error (_handle));\n";
11094 (match fst style with
11097 pr " return r != 0 ? true : false;\n"
11099 pr " Hashtable rr = new Hashtable ();\n";
11100 pr " for (int i = 0; i < r.Length; i += 2)\n";
11101 pr " rr.Add (r[i], r[i+1]);\n";
11103 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
11104 | RString _ | RBufferOut _ | RStruct _ | RStringList _
11110 ) all_functions_sorted;
11116 and generate_bindtests () =
11117 generate_header CStyle LGPLv2plus;
11121 #include <stdlib.h>
11122 #include <inttypes.h>
11123 #include <string.h>
11125 #include \"guestfs.h\"
11126 #include \"guestfs-internal.h\"
11127 #include \"guestfs-internal-actions.h\"
11128 #include \"guestfs_protocol.h\"
11130 #define error guestfs_error
11131 #define safe_calloc guestfs_safe_calloc
11132 #define safe_malloc guestfs_safe_malloc
11135 print_strings (char *const *argv)
11140 for (argc = 0; argv[argc] != NULL; ++argc) {
11141 if (argc > 0) printf (\", \");
11142 printf (\"\\\"%%s\\\"\", argv[argc]);
11147 /* The test0 function prints its parameters to stdout. */
11151 match test_functions with
11152 | [] -> assert false
11153 | test0 :: tests -> test0, tests in
11156 let (name, style, _, _, _, _, _) = test0 in
11157 generate_prototype ~extern:false ~semicolon:false ~newline:true
11158 ~handle:"g" ~prefix:"guestfs__" name style;
11163 | Device n | Dev_or_Path n
11166 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
11170 pr " for (i = 0; i < %s_size; ++i)\n" n;
11171 pr " printf (\"<%%02x>\", %s[i]);\n" n;
11172 pr " printf (\"\\n\");\n";
11174 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
11175 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
11176 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
11177 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
11178 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
11180 pr " /* Java changes stdout line buffering so we need this: */\n";
11181 pr " fflush (stdout);\n";
11187 fun (name, style, _, _, _, _, _) ->
11188 if String.sub name (String.length name - 3) 3 <> "err" then (
11189 pr "/* Test normal return. */\n";
11190 generate_prototype ~extern:false ~semicolon:false ~newline:true
11191 ~handle:"g" ~prefix:"guestfs__" name style;
11193 (match fst style with
11198 pr " sscanf (val, \"%%d\", &r);\n";
11201 pr " int64_t r;\n";
11202 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
11205 pr " return STREQ (val, \"true\");\n"
11207 | RConstOptString _ ->
11208 (* Can't return the input string here. Return a static
11209 * string so we ensure we get a segfault if the caller
11210 * tries to free it.
11212 pr " return \"static string\";\n"
11214 pr " return strdup (val);\n"
11216 pr " char **strs;\n";
11218 pr " sscanf (val, \"%%d\", &n);\n";
11219 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
11220 pr " for (i = 0; i < n; ++i) {\n";
11221 pr " strs[i] = safe_malloc (g, 16);\n";
11222 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
11224 pr " strs[n] = NULL;\n";
11225 pr " return strs;\n"
11226 | RStruct (_, typ) ->
11227 pr " struct guestfs_%s *r;\n" typ;
11228 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11230 | RStructList (_, typ) ->
11231 pr " struct guestfs_%s_list *r;\n" typ;
11232 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11233 pr " sscanf (val, \"%%d\", &r->len);\n";
11234 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
11237 pr " char **strs;\n";
11239 pr " sscanf (val, \"%%d\", &n);\n";
11240 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
11241 pr " for (i = 0; i < n; ++i) {\n";
11242 pr " strs[i*2] = safe_malloc (g, 16);\n";
11243 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
11244 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
11245 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
11247 pr " strs[n*2] = NULL;\n";
11248 pr " return strs;\n"
11250 pr " return strdup (val);\n"
11255 pr "/* Test error return. */\n";
11256 generate_prototype ~extern:false ~semicolon:false ~newline:true
11257 ~handle:"g" ~prefix:"guestfs__" name style;
11259 pr " error (g, \"error\");\n";
11260 (match fst style with
11261 | RErr | RInt _ | RInt64 _ | RBool _ ->
11263 | RConstString _ | RConstOptString _
11264 | RString _ | RStringList _ | RStruct _
11268 pr " return NULL;\n"
11275 and generate_ocaml_bindtests () =
11276 generate_header OCamlStyle GPLv2plus;
11280 let g = Guestfs.create () in
11284 String.concat " " (
11287 | CallString s -> "\"" ^ s ^ "\""
11288 | CallOptString None -> "None"
11289 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
11290 | CallStringList xs ->
11291 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
11292 | CallInt i when i >= 0 -> string_of_int i
11293 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
11294 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
11295 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
11296 | CallBool b -> string_of_bool b
11297 | CallBuffer s -> sprintf "%S" s
11302 generate_lang_bindtests (
11303 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
11306 pr "print_endline \"EOF\"\n"
11308 and generate_perl_bindtests () =
11309 pr "#!/usr/bin/perl -w\n";
11310 generate_header HashStyle GPLv2plus;
11317 my $g = Sys::Guestfs->new ();
11321 String.concat ", " (
11324 | CallString s -> "\"" ^ s ^ "\""
11325 | CallOptString None -> "undef"
11326 | CallOptString (Some s) -> sprintf "\"%s\"" s
11327 | CallStringList xs ->
11328 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11329 | CallInt i -> string_of_int i
11330 | CallInt64 i -> Int64.to_string i
11331 | CallBool b -> if b then "1" else "0"
11332 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11337 generate_lang_bindtests (
11338 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
11341 pr "print \"EOF\\n\"\n"
11343 and generate_python_bindtests () =
11344 generate_header HashStyle GPLv2plus;
11349 g = guestfs.GuestFS ()
11353 String.concat ", " (
11356 | CallString s -> "\"" ^ s ^ "\""
11357 | CallOptString None -> "None"
11358 | CallOptString (Some s) -> sprintf "\"%s\"" s
11359 | CallStringList xs ->
11360 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11361 | CallInt i -> string_of_int i
11362 | CallInt64 i -> Int64.to_string i
11363 | CallBool b -> if b then "1" else "0"
11364 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11369 generate_lang_bindtests (
11370 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
11373 pr "print \"EOF\"\n"
11375 and generate_ruby_bindtests () =
11376 generate_header HashStyle GPLv2plus;
11381 g = Guestfs::create()
11385 String.concat ", " (
11388 | CallString s -> "\"" ^ s ^ "\""
11389 | CallOptString None -> "nil"
11390 | CallOptString (Some s) -> sprintf "\"%s\"" s
11391 | CallStringList xs ->
11392 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11393 | CallInt i -> string_of_int i
11394 | CallInt64 i -> Int64.to_string i
11395 | CallBool b -> string_of_bool b
11396 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11401 generate_lang_bindtests (
11402 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
11405 pr "print \"EOF\\n\"\n"
11407 and generate_java_bindtests () =
11408 generate_header CStyle GPLv2plus;
11411 import com.redhat.et.libguestfs.*;
11413 public class Bindtests {
11414 public static void main (String[] argv)
11417 GuestFS g = new GuestFS ();
11421 String.concat ", " (
11424 | CallString s -> "\"" ^ s ^ "\""
11425 | CallOptString None -> "null"
11426 | CallOptString (Some s) -> sprintf "\"%s\"" s
11427 | CallStringList xs ->
11429 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
11430 | CallInt i -> string_of_int i
11431 | CallInt64 i -> Int64.to_string i
11432 | CallBool b -> string_of_bool b
11434 "new byte[] { " ^ String.concat "," (
11435 map_chars (fun c -> string_of_int (Char.code c)) s
11441 generate_lang_bindtests (
11442 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
11446 System.out.println (\"EOF\");
11448 catch (Exception exn) {
11449 System.err.println (exn);
11456 and generate_haskell_bindtests () =
11457 generate_header HaskellStyle GPLv2plus;
11460 module Bindtests where
11461 import qualified Guestfs
11464 g <- Guestfs.create
11468 String.concat " " (
11471 | CallString s -> "\"" ^ s ^ "\""
11472 | CallOptString None -> "Nothing"
11473 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
11474 | CallStringList xs ->
11475 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11476 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
11477 | CallInt i -> string_of_int i
11478 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
11479 | CallInt64 i -> Int64.to_string i
11480 | CallBool true -> "True"
11481 | CallBool false -> "False"
11482 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11487 generate_lang_bindtests (
11488 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
11491 pr " putStrLn \"EOF\"\n"
11493 (* Language-independent bindings tests - we do it this way to
11494 * ensure there is parity in testing bindings across all languages.
11496 and generate_lang_bindtests call =
11497 call "test0" [CallString "abc"; CallOptString (Some "def");
11498 CallStringList []; CallBool false;
11499 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11500 CallBuffer "abc\000abc"];
11501 call "test0" [CallString "abc"; CallOptString None;
11502 CallStringList []; CallBool false;
11503 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11504 CallBuffer "abc\000abc"];
11505 call "test0" [CallString ""; CallOptString (Some "def");
11506 CallStringList []; CallBool false;
11507 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11508 CallBuffer "abc\000abc"];
11509 call "test0" [CallString ""; CallOptString (Some "");
11510 CallStringList []; CallBool false;
11511 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11512 CallBuffer "abc\000abc"];
11513 call "test0" [CallString "abc"; CallOptString (Some "def");
11514 CallStringList ["1"]; CallBool false;
11515 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11516 CallBuffer "abc\000abc"];
11517 call "test0" [CallString "abc"; CallOptString (Some "def");
11518 CallStringList ["1"; "2"]; CallBool false;
11519 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11520 CallBuffer "abc\000abc"];
11521 call "test0" [CallString "abc"; CallOptString (Some "def");
11522 CallStringList ["1"]; CallBool true;
11523 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11524 CallBuffer "abc\000abc"];
11525 call "test0" [CallString "abc"; CallOptString (Some "def");
11526 CallStringList ["1"]; CallBool false;
11527 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456";
11528 CallBuffer "abc\000abc"];
11529 call "test0" [CallString "abc"; CallOptString (Some "def");
11530 CallStringList ["1"]; CallBool false;
11531 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456";
11532 CallBuffer "abc\000abc"];
11533 call "test0" [CallString "abc"; CallOptString (Some "def");
11534 CallStringList ["1"]; CallBool false;
11535 CallInt 1; CallInt64 1L; CallString "123"; CallString "456";
11536 CallBuffer "abc\000abc"];
11537 call "test0" [CallString "abc"; CallOptString (Some "def");
11538 CallStringList ["1"]; CallBool false;
11539 CallInt 2; CallInt64 2L; CallString "123"; CallString "456";
11540 CallBuffer "abc\000abc"];
11541 call "test0" [CallString "abc"; CallOptString (Some "def");
11542 CallStringList ["1"]; CallBool false;
11543 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456";
11544 CallBuffer "abc\000abc"];
11545 call "test0" [CallString "abc"; CallOptString (Some "def");
11546 CallStringList ["1"]; CallBool false;
11547 CallInt 0; CallInt64 0L; CallString ""; CallString "";
11548 CallBuffer "abc\000abc"]
11550 (* XXX Add here tests of the return and error functions. *)
11552 (* Code to generator bindings for virt-inspector. Currently only
11553 * implemented for OCaml code (for virt-p2v 2.0).
11555 let rng_input = "inspector/virt-inspector.rng"
11557 (* Read the input file and parse it into internal structures. This is
11558 * by no means a complete RELAX NG parser, but is just enough to be
11559 * able to parse the specific input file.
11562 | Element of string * rng list (* <element name=name/> *)
11563 | Attribute of string * rng list (* <attribute name=name/> *)
11564 | Interleave of rng list (* <interleave/> *)
11565 | ZeroOrMore of rng (* <zeroOrMore/> *)
11566 | OneOrMore of rng (* <oneOrMore/> *)
11567 | Optional of rng (* <optional/> *)
11568 | Choice of string list (* <choice><value/>*</choice> *)
11569 | Value of string (* <value>str</value> *)
11570 | Text (* <text/> *)
11572 let rec string_of_rng = function
11573 | Element (name, xs) ->
11574 "Element (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11575 | Attribute (name, xs) ->
11576 "Attribute (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11577 | Interleave xs -> "Interleave (" ^ string_of_rng_list xs ^ ")"
11578 | ZeroOrMore rng -> "ZeroOrMore (" ^ string_of_rng rng ^ ")"
11579 | OneOrMore rng -> "OneOrMore (" ^ string_of_rng rng ^ ")"
11580 | Optional rng -> "Optional (" ^ string_of_rng rng ^ ")"
11581 | Choice values -> "Choice [" ^ String.concat ", " values ^ "]"
11582 | Value value -> "Value \"" ^ value ^ "\""
11585 and string_of_rng_list xs =
11586 String.concat ", " (List.map string_of_rng xs)
11588 let rec parse_rng ?defines context = function
11590 | Xml.Element ("element", ["name", name], children) :: rest ->
11591 Element (name, parse_rng ?defines context children)
11592 :: parse_rng ?defines context rest
11593 | Xml.Element ("attribute", ["name", name], children) :: rest ->
11594 Attribute (name, parse_rng ?defines context children)
11595 :: parse_rng ?defines context rest
11596 | Xml.Element ("interleave", [], children) :: rest ->
11597 Interleave (parse_rng ?defines context children)
11598 :: parse_rng ?defines context rest
11599 | Xml.Element ("zeroOrMore", [], [child]) :: rest ->
11600 let rng = parse_rng ?defines context [child] in
11602 | [child] -> ZeroOrMore child :: parse_rng ?defines context rest
11604 failwithf "%s: <zeroOrMore> contains more than one child element"
11607 | Xml.Element ("oneOrMore", [], [child]) :: rest ->
11608 let rng = parse_rng ?defines context [child] in
11610 | [child] -> OneOrMore child :: parse_rng ?defines context rest
11612 failwithf "%s: <oneOrMore> contains more than one child element"
11615 | Xml.Element ("optional", [], [child]) :: rest ->
11616 let rng = parse_rng ?defines context [child] in
11618 | [child] -> Optional child :: parse_rng ?defines context rest
11620 failwithf "%s: <optional> contains more than one child element"
11623 | Xml.Element ("choice", [], children) :: rest ->
11624 let values = List.map (
11625 function Xml.Element ("value", [], [Xml.PCData value]) -> value
11627 failwithf "%s: can't handle anything except <value> in <choice>"
11631 :: parse_rng ?defines context rest
11632 | Xml.Element ("value", [], [Xml.PCData value]) :: rest ->
11633 Value value :: parse_rng ?defines context rest
11634 | Xml.Element ("text", [], []) :: rest ->
11635 Text :: parse_rng ?defines context rest
11636 | Xml.Element ("ref", ["name", name], []) :: rest ->
11637 (* Look up the reference. Because of limitations in this parser,
11638 * we can't handle arbitrarily nested <ref> yet. You can only
11639 * use <ref> from inside <start>.
11641 (match defines with
11643 failwithf "%s: contains <ref>, but no refs are defined yet" context
11645 let rng = StringMap.find name map in
11646 rng @ parse_rng ?defines context rest
11649 failwithf "%s: can't handle '%s' in schema" context (Xml.to_string x)
11652 let xml = Xml.parse_file rng_input in
11654 | Xml.Element ("grammar", _,
11655 Xml.Element ("start", _, gram) :: defines) ->
11656 (* The <define/> elements are referenced in the <start> section,
11657 * so build a map of those first.
11659 let defines = List.fold_left (
11661 function Xml.Element ("define", ["name", name], defn) ->
11662 StringMap.add name defn map
11664 failwithf "%s: expected <define name=name/>" rng_input
11665 ) StringMap.empty defines in
11666 let defines = StringMap.mapi parse_rng defines in
11668 (* Parse the <start> clause, passing the defines. *)
11669 parse_rng ~defines "<start>" gram
11671 failwithf "%s: input is not <grammar><start/><define>*</grammar>"
11674 let name_of_field = function
11675 | Element (name, _) | Attribute (name, _)
11676 | ZeroOrMore (Element (name, _))
11677 | OneOrMore (Element (name, _))
11678 | Optional (Element (name, _)) -> name
11679 | Optional (Attribute (name, _)) -> name
11680 | Text -> (* an unnamed field in an element *)
11683 failwithf "name_of_field failed at: %s" (string_of_rng rng)
11685 (* At the moment this function only generates OCaml types. However we
11686 * should parameterize it later so it can generate types/structs in a
11687 * variety of languages.
11689 let generate_types xs =
11690 (* A simple type is one that can be printed out directly, eg.
11691 * "string option". A complex type is one which has a name and has
11692 * to be defined via another toplevel definition, eg. a struct.
11694 * generate_type generates code for either simple or complex types.
11695 * In the simple case, it returns the string ("string option"). In
11696 * the complex case, it returns the name ("mountpoint"). In the
11697 * complex case it has to print out the definition before returning,
11698 * so it should only be called when we are at the beginning of a
11699 * new line (BOL context).
11701 let rec generate_type = function
11702 | Text -> (* string *)
11704 | Choice values -> (* [`val1|`val2|...] *)
11705 "[" ^ String.concat "|" (List.map ((^)"`") values) ^ "]", true
11706 | ZeroOrMore rng -> (* <rng> list *)
11707 let t, is_simple = generate_type rng in
11708 t ^ " list (* 0 or more *)", is_simple
11709 | OneOrMore rng -> (* <rng> list *)
11710 let t, is_simple = generate_type rng in
11711 t ^ " list (* 1 or more *)", is_simple
11712 (* virt-inspector hack: bool *)
11713 | Optional (Attribute (name, [Value "1"])) ->
11715 | Optional rng -> (* <rng> list *)
11716 let t, is_simple = generate_type rng in
11717 t ^ " option", is_simple
11718 (* type name = { fields ... } *)
11719 | Element (name, fields) when is_attrs_interleave fields ->
11720 generate_type_struct name (get_attrs_interleave fields)
11721 | Element (name, [field]) (* type name = field *)
11722 | Attribute (name, [field]) ->
11723 let t, is_simple = generate_type field in
11724 if is_simple then (t, true)
11726 pr "type %s = %s\n" name t;
11729 | Element (name, fields) -> (* type name = { fields ... } *)
11730 generate_type_struct name fields
11732 failwithf "generate_type failed at: %s" (string_of_rng rng)
11734 and is_attrs_interleave = function
11735 | [Interleave _] -> true
11736 | Attribute _ :: fields -> is_attrs_interleave fields
11737 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11740 and get_attrs_interleave = function
11741 | [Interleave fields] -> fields
11742 | ((Attribute _) as field) :: fields
11743 | ((Optional (Attribute _)) as field) :: fields ->
11744 field :: get_attrs_interleave fields
11745 | _ -> assert false
11747 and generate_types xs =
11748 List.iter (fun x -> ignore (generate_type x)) xs
11750 and generate_type_struct name fields =
11751 (* Calculate the types of the fields first. We have to do this
11752 * before printing anything so we are still in BOL context.
11754 let types = List.map fst (List.map generate_type fields) in
11756 (* Special case of a struct containing just a string and another
11757 * field. Turn it into an assoc list.
11760 | ["string"; other] ->
11761 let fname1, fname2 =
11763 | [f1; f2] -> name_of_field f1, name_of_field f2
11764 | _ -> assert false in
11765 pr "type %s = string * %s (* %s -> %s *)\n" name other fname1 fname2;
11769 pr "type %s = {\n" name;
11771 fun (field, ftype) ->
11772 let fname = name_of_field field in
11773 pr " %s_%s : %s;\n" name fname ftype
11774 ) (List.combine fields types);
11776 (* Return the name of this type, and
11777 * false because it's not a simple type.
11784 let generate_parsers xs =
11785 (* As for generate_type above, generate_parser makes a parser for
11786 * some type, and returns the name of the parser it has generated.
11787 * Because it (may) need to print something, it should always be
11788 * called in BOL context.
11790 let rec generate_parser = function
11791 | Text -> (* string *)
11792 "string_child_or_empty"
11793 | Choice values -> (* [`val1|`val2|...] *)
11794 sprintf "(fun x -> match Xml.pcdata (first_child x) with %s | str -> failwith (\"unexpected field value: \" ^ str))"
11796 (List.map (fun v -> sprintf "%S -> `%s" v v) values))
11797 | ZeroOrMore rng -> (* <rng> list *)
11798 let pa = generate_parser rng in
11799 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11800 | OneOrMore rng -> (* <rng> list *)
11801 let pa = generate_parser rng in
11802 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11803 (* virt-inspector hack: bool *)
11804 | Optional (Attribute (name, [Value "1"])) ->
11805 sprintf "(fun x -> try ignore (Xml.attrib x %S); true with Xml.No_attribute _ -> false)" name
11806 | Optional rng -> (* <rng> list *)
11807 let pa = generate_parser rng in
11808 sprintf "(function None -> None | Some x -> Some (%s x))" pa
11809 (* type name = { fields ... } *)
11810 | Element (name, fields) when is_attrs_interleave fields ->
11811 generate_parser_struct name (get_attrs_interleave fields)
11812 | Element (name, [field]) -> (* type name = field *)
11813 let pa = generate_parser field in
11814 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11815 pr "let %s =\n" parser_name;
11817 pr "let parse_%s = %s\n" name parser_name;
11819 | Attribute (name, [field]) ->
11820 let pa = generate_parser field in
11821 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11822 pr "let %s =\n" parser_name;
11824 pr "let parse_%s = %s\n" name parser_name;
11826 | Element (name, fields) -> (* type name = { fields ... } *)
11827 generate_parser_struct name ([], fields)
11829 failwithf "generate_parser failed at: %s" (string_of_rng rng)
11831 and is_attrs_interleave = function
11832 | [Interleave _] -> true
11833 | Attribute _ :: fields -> is_attrs_interleave fields
11834 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11837 and get_attrs_interleave = function
11838 | [Interleave fields] -> [], fields
11839 | ((Attribute _) as field) :: fields
11840 | ((Optional (Attribute _)) as field) :: fields ->
11841 let attrs, interleaves = get_attrs_interleave fields in
11842 (field :: attrs), interleaves
11843 | _ -> assert false
11845 and generate_parsers xs =
11846 List.iter (fun x -> ignore (generate_parser x)) xs
11848 and generate_parser_struct name (attrs, interleaves) =
11849 (* Generate parsers for the fields first. We have to do this
11850 * before printing anything so we are still in BOL context.
11852 let fields = attrs @ interleaves in
11853 let pas = List.map generate_parser fields in
11855 (* Generate an intermediate tuple from all the fields first.
11856 * If the type is just a string + another field, then we will
11857 * return this directly, otherwise it is turned into a record.
11859 * RELAX NG note: This code treats <interleave> and plain lists of
11860 * fields the same. In other words, it doesn't bother enforcing
11861 * any ordering of fields in the XML.
11863 pr "let parse_%s x =\n" name;
11864 pr " let t = (\n ";
11865 let comma = ref false in
11868 if !comma then pr ",\n ";
11871 | Optional (Attribute (fname, [field])), pa ->
11873 | Optional (Element (fname, [field])), pa ->
11874 pr "%s (optional_child %S x)" pa fname
11875 | Attribute (fname, [Text]), _ ->
11876 pr "attribute %S x" fname
11877 | (ZeroOrMore _ | OneOrMore _), pa ->
11882 let fname = name_of_field field in
11883 pr "%s (child %S x)" pa fname
11884 ) (List.combine fields pas);
11888 | [Element (_, [Text]) | Attribute (_, [Text]); _] ->
11892 pr " (Obj.magic t : %s)\n" name
11896 | (Optional (Attribute (fname, [field])), pa) ->
11897 pr " %s_%s =\n" name fname;
11899 | (Optional (Element (fname, [field])), pa) ->
11900 pr " %s_%s =\n" name fname;
11901 pr " (let x = optional_child %S x in\n" fname;
11904 let fname = name_of_field field in
11905 pr " %s_%s =\n" name fname;
11906 pr " (let x = child %S x in\n" fname;
11908 ) (List.combine fields pas);
11912 sprintf "parse_%s" name
11915 generate_parsers xs
11917 (* Generate ocaml/guestfs_inspector.mli. *)
11918 let generate_ocaml_inspector_mli () =
11919 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11922 (** This is an OCaml language binding to the external [virt-inspector]
11925 For more information, please read the man page [virt-inspector(1)].
11930 generate_types grammar;
11931 pr "(** The nested information returned from the {!inspect} function. *)\n";
11935 val inspect : ?connect:string -> ?xml:string -> string list -> operatingsystems
11936 (** To inspect a libvirt domain called [name], pass a singleton
11937 list: [inspect [name]]. When using libvirt only, you may
11938 optionally pass a libvirt URI using [inspect ~connect:uri ...].
11940 To inspect a disk image or images, pass a list of the filenames
11941 of the disk images: [inspect filenames]
11943 This function inspects the given guest or disk images and
11944 returns a list of operating system(s) found and a large amount
11945 of information about them. In the vast majority of cases,
11946 a virtual machine only contains a single operating system.
11948 If the optional [~xml] parameter is given, then this function
11949 skips running the external virt-inspector program and just
11950 parses the given XML directly (which is expected to be XML
11951 produced from a previous run of virt-inspector). The list of
11952 names and connect URI are ignored in this case.
11954 This function can throw a wide variety of exceptions, for example
11955 if the external virt-inspector program cannot be found, or if
11956 it doesn't generate valid XML.
11960 (* Generate ocaml/guestfs_inspector.ml. *)
11961 let generate_ocaml_inspector_ml () =
11962 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11967 generate_types grammar;
11971 (* Misc functions which are used by the parser code below. *)
11972 let first_child = function
11973 | Xml.Element (_, _, c::_) -> c
11974 | Xml.Element (name, _, []) ->
11975 failwith (\"expected <\" ^ name ^ \"/> to have a child node\")
11976 | Xml.PCData str ->
11977 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11979 let string_child_or_empty = function
11980 | Xml.Element (_, _, [Xml.PCData s]) -> s
11981 | Xml.Element (_, _, []) -> \"\"
11982 | Xml.Element (x, _, _) ->
11983 failwith (\"expected XML tag with a single PCDATA child, but got \" ^
11985 | Xml.PCData str ->
11986 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11988 let optional_child name xml =
11989 let children = Xml.children xml in
11991 Some (List.find (function
11992 | Xml.Element (n, _, _) when n = name -> true
11993 | _ -> false) children)
11997 let child name xml =
11998 match optional_child name xml with
12001 failwith (\"mandatory field <\" ^ name ^ \"/> missing in XML output\")
12003 let attribute name xml =
12004 try Xml.attrib xml name
12005 with Xml.No_attribute _ ->
12006 failwith (\"mandatory attribute \" ^ name ^ \" missing in XML output\")
12010 generate_parsers grammar;
12014 (* Run external virt-inspector, then use parser to parse the XML. *)
12015 let inspect ?connect ?xml names =
12019 if names = [] then invalid_arg \"inspect: no names given\";
12020 let cmd = [ \"virt-inspector\"; \"--xml\" ] @
12021 (match connect with None -> [] | Some uri -> [ \"--connect\"; uri ]) @
12023 let cmd = List.map Filename.quote cmd in
12024 let cmd = String.concat \" \" cmd in
12025 let chan = open_process_in cmd in
12026 let xml = Xml.parse_in chan in
12027 (match close_process_in chan with
12029 | WEXITED _ -> failwith \"external virt-inspector command failed\"
12030 | WSIGNALED i | WSTOPPED i ->
12031 failwith (\"external virt-inspector command died or stopped on sig \" ^
12036 Xml.parse_string doc in
12037 parse_operatingsystems xml
12040 and generate_max_proc_nr () =
12041 pr "%d\n" max_proc_nr
12043 let output_to filename k =
12044 let filename_new = filename ^ ".new" in
12045 chan := open_out filename_new;
12048 chan := Pervasives.stdout;
12050 (* Is the new file different from the current file? *)
12051 if Sys.file_exists filename && files_equal filename filename_new then
12052 unlink filename_new (* same, so skip it *)
12054 (* different, overwrite old one *)
12055 (try chmod filename 0o644 with Unix_error _ -> ());
12056 rename filename_new filename;
12057 chmod filename 0o444;
12058 printf "written %s\n%!" filename;
12061 let perror msg = function
12062 | Unix_error (err, _, _) ->
12063 eprintf "%s: %s\n" msg (error_message err)
12065 eprintf "%s: %s\n" msg (Printexc.to_string exn)
12067 (* Main program. *)
12070 try openfile "HACKING" [O_RDWR] 0
12072 | Unix_error (ENOENT, _, _) ->
12074 You are probably running this from the wrong directory.
12075 Run it from the top source directory using the command
12080 perror "open: HACKING" exn;
12083 (* Acquire a lock so parallel builds won't try to run the generator
12084 * twice at the same time. Subsequent builds will wait for the first
12085 * one to finish. Note the lock is released implicitly when the
12088 (try lockf lock_fd F_LOCK 1
12090 perror "lock: HACKING" exn;
12093 check_functions ();
12095 output_to "src/guestfs_protocol.x" generate_xdr;
12096 output_to "src/guestfs-structs.h" generate_structs_h;
12097 output_to "src/guestfs-actions.h" generate_actions_h;
12098 output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
12099 output_to "src/guestfs-actions.c" generate_client_actions;
12100 output_to "src/guestfs-bindtests.c" generate_bindtests;
12101 output_to "src/guestfs-structs.pod" generate_structs_pod;
12102 output_to "src/guestfs-actions.pod" generate_actions_pod;
12103 output_to "src/guestfs-availability.pod" generate_availability_pod;
12104 output_to "src/MAX_PROC_NR" generate_max_proc_nr;
12105 output_to "src/libguestfs.syms" generate_linker_script;
12106 output_to "daemon/actions.h" generate_daemon_actions_h;
12107 output_to "daemon/stubs.c" generate_daemon_actions;
12108 output_to "daemon/names.c" generate_daemon_names;
12109 output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
12110 output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
12111 output_to "capitests/tests.c" generate_tests;
12112 output_to "fish/cmds.c" generate_fish_cmds;
12113 output_to "fish/completion.c" generate_fish_completion;
12114 output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
12115 output_to "ocaml/guestfs.mli" generate_ocaml_mli;
12116 output_to "ocaml/guestfs.ml" generate_ocaml_ml;
12117 output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;
12118 output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
12119 output_to "ocaml/guestfs_inspector.mli" generate_ocaml_inspector_mli;
12120 output_to "ocaml/guestfs_inspector.ml" generate_ocaml_inspector_ml;
12121 output_to "perl/Guestfs.xs" generate_perl_xs;
12122 output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
12123 output_to "perl/bindtests.pl" generate_perl_bindtests;
12124 output_to "python/guestfs-py.c" generate_python_c;
12125 output_to "python/guestfs.py" generate_python_py;
12126 output_to "python/bindtests.py" generate_python_bindtests;
12127 output_to "ruby/ext/guestfs/_guestfs.c" generate_ruby_c;
12128 output_to "ruby/bindtests.rb" generate_ruby_bindtests;
12129 output_to "java/com/redhat/et/libguestfs/GuestFS.java" generate_java_java;
12133 let cols = cols_of_struct typ in
12134 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
12135 output_to filename (generate_java_struct jtyp cols);
12138 output_to "java/Makefile.inc" generate_java_makefile_inc;
12139 output_to "java/com_redhat_et_libguestfs_GuestFS.c" generate_java_c;
12140 output_to "java/Bindtests.java" generate_java_bindtests;
12141 output_to "haskell/Guestfs.hs" generate_haskell_hs;
12142 output_to "haskell/Bindtests.hs" generate_haskell_bindtests;
12143 output_to "csharp/Libguestfs.cs" generate_csharp;
12145 (* Always generate this file last, and unconditionally. It's used
12146 * by the Makefile to know when we must re-run the generator.
12148 let chan = open_out "src/stamp-generator" in
12149 fprintf chan "1\n";
12152 printf "generated %d lines of code\n" !lines