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 This command only works on regular files, and will fail on other
998 file types such as directories, symbolic links, block special etc.");
1000 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
1001 [InitISOFS, Always, TestOutput (
1002 [["cat"; "/known-2"]], "abcdef\n")],
1003 "list the contents of a file",
1005 Return the contents of the file named C<path>.
1007 Note that this function cannot correctly handle binary files
1008 (specifically, files containing C<\\0> character which is treated
1009 as end of string). For those you need to use the C<guestfs_read_file>
1010 or C<guestfs_download> functions which have a more complex interface.");
1012 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
1013 [], (* XXX Tricky to test because it depends on the exact format
1014 * of the 'ls -l' command, which changes between F10 and F11.
1016 "list the files in a directory (long format)",
1018 List the files in C<directory> (relative to the root directory,
1019 there is no cwd) in the format of 'ls -la'.
1021 This command is mostly useful for interactive sessions. It
1022 is I<not> intended that you try to parse the output string.");
1024 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
1025 [InitBasicFS, Always, TestOutputList (
1027 ["touch"; "/newer"];
1028 ["touch"; "/newest"];
1029 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
1030 "list the files in a directory",
1032 List the files in C<directory> (relative to the root directory,
1033 there is no cwd). The '.' and '..' entries are not returned, but
1034 hidden files are shown.
1036 This command is mostly useful for interactive sessions. Programs
1037 should probably use C<guestfs_readdir> instead.");
1039 ("list_devices", (RStringList "devices", []), 7, [],
1040 [InitEmpty, Always, TestOutputListOfDevices (
1041 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
1042 "list the block devices",
1044 List all the block devices.
1046 The full block device names are returned, eg. C</dev/sda>");
1048 ("list_partitions", (RStringList "partitions", []), 8, [],
1049 [InitBasicFS, Always, TestOutputListOfDevices (
1050 [["list_partitions"]], ["/dev/sda1"]);
1051 InitEmpty, Always, TestOutputListOfDevices (
1052 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1053 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1054 "list the partitions",
1056 List all the partitions detected on all block devices.
1058 The full partition device names are returned, eg. C</dev/sda1>
1060 This does not return logical volumes. For that you will need to
1061 call C<guestfs_lvs>.");
1063 ("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
1064 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
1065 [["pvs"]], ["/dev/sda1"]);
1066 InitEmpty, Always, TestOutputListOfDevices (
1067 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1068 ["pvcreate"; "/dev/sda1"];
1069 ["pvcreate"; "/dev/sda2"];
1070 ["pvcreate"; "/dev/sda3"];
1071 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1072 "list the LVM physical volumes (PVs)",
1074 List all the physical volumes detected. This is the equivalent
1075 of the L<pvs(8)> command.
1077 This returns a list of just the device names that contain
1078 PVs (eg. C</dev/sda2>).
1080 See also C<guestfs_pvs_full>.");
1082 ("vgs", (RStringList "volgroups", []), 10, [Optional "lvm2"],
1083 [InitBasicFSonLVM, Always, TestOutputList (
1085 InitEmpty, Always, TestOutputList (
1086 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1087 ["pvcreate"; "/dev/sda1"];
1088 ["pvcreate"; "/dev/sda2"];
1089 ["pvcreate"; "/dev/sda3"];
1090 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1091 ["vgcreate"; "VG2"; "/dev/sda3"];
1092 ["vgs"]], ["VG1"; "VG2"])],
1093 "list the LVM volume groups (VGs)",
1095 List all the volumes groups detected. This is the equivalent
1096 of the L<vgs(8)> command.
1098 This returns a list of just the volume group names that were
1099 detected (eg. C<VolGroup00>).
1101 See also C<guestfs_vgs_full>.");
1103 ("lvs", (RStringList "logvols", []), 11, [Optional "lvm2"],
1104 [InitBasicFSonLVM, Always, TestOutputList (
1105 [["lvs"]], ["/dev/VG/LV"]);
1106 InitEmpty, Always, TestOutputList (
1107 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1108 ["pvcreate"; "/dev/sda1"];
1109 ["pvcreate"; "/dev/sda2"];
1110 ["pvcreate"; "/dev/sda3"];
1111 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1112 ["vgcreate"; "VG2"; "/dev/sda3"];
1113 ["lvcreate"; "LV1"; "VG1"; "50"];
1114 ["lvcreate"; "LV2"; "VG1"; "50"];
1115 ["lvcreate"; "LV3"; "VG2"; "50"];
1116 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1117 "list the LVM logical volumes (LVs)",
1119 List all the logical volumes detected. This is the equivalent
1120 of the L<lvs(8)> command.
1122 This returns a list of the logical volume device names
1123 (eg. C</dev/VolGroup00/LogVol00>).
1125 See also C<guestfs_lvs_full>.");
1127 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
1128 [], (* XXX how to test? *)
1129 "list the LVM physical volumes (PVs)",
1131 List all the physical volumes detected. This is the equivalent
1132 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1134 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [Optional "lvm2"],
1135 [], (* XXX how to test? *)
1136 "list the LVM volume groups (VGs)",
1138 List all the volumes groups detected. This is the equivalent
1139 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1141 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [Optional "lvm2"],
1142 [], (* XXX how to test? *)
1143 "list the LVM logical volumes (LVs)",
1145 List all the logical volumes detected. This is the equivalent
1146 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1148 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1149 [InitISOFS, Always, TestOutputList (
1150 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1151 InitISOFS, Always, TestOutputList (
1152 [["read_lines"; "/empty"]], [])],
1153 "read file as lines",
1155 Return the contents of the file named C<path>.
1157 The file contents are returned as a list of lines. Trailing
1158 C<LF> and C<CRLF> character sequences are I<not> returned.
1160 Note that this function cannot correctly handle binary files
1161 (specifically, files containing C<\\0> character which is treated
1162 as end of line). For those you need to use the C<guestfs_read_file>
1163 function which has a more complex interface.");
1165 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [Optional "augeas"],
1166 [], (* XXX Augeas code needs tests. *)
1167 "create a new Augeas handle",
1169 Create a new Augeas handle for editing configuration files.
1170 If there was any previous Augeas handle associated with this
1171 guestfs session, then it is closed.
1173 You must call this before using any other C<guestfs_aug_*>
1176 C<root> is the filesystem root. C<root> must not be NULL,
1179 The flags are the same as the flags defined in
1180 E<lt>augeas.hE<gt>, the logical I<or> of the following
1185 =item C<AUG_SAVE_BACKUP> = 1
1187 Keep the original file with a C<.augsave> extension.
1189 =item C<AUG_SAVE_NEWFILE> = 2
1191 Save changes into a file with extension C<.augnew>, and
1192 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1194 =item C<AUG_TYPE_CHECK> = 4
1196 Typecheck lenses (can be expensive).
1198 =item C<AUG_NO_STDINC> = 8
1200 Do not use standard load path for modules.
1202 =item C<AUG_SAVE_NOOP> = 16
1204 Make save a no-op, just record what would have been changed.
1206 =item C<AUG_NO_LOAD> = 32
1208 Do not load the tree in C<guestfs_aug_init>.
1212 To close the handle, you can call C<guestfs_aug_close>.
1214 To find out more about Augeas, see L<http://augeas.net/>.");
1216 ("aug_close", (RErr, []), 26, [Optional "augeas"],
1217 [], (* XXX Augeas code needs tests. *)
1218 "close the current Augeas handle",
1220 Close the current Augeas handle and free up any resources
1221 used by it. After calling this, you have to call
1222 C<guestfs_aug_init> again before you can use any other
1223 Augeas functions.");
1225 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [Optional "augeas"],
1226 [], (* XXX Augeas code needs tests. *)
1227 "define an Augeas variable",
1229 Defines an Augeas variable C<name> whose value is the result
1230 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1233 On success this returns the number of nodes in C<expr>, or
1234 C<0> if C<expr> evaluates to something which is not a nodeset.");
1236 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [Optional "augeas"],
1237 [], (* XXX Augeas code needs tests. *)
1238 "define an Augeas node",
1240 Defines a variable C<name> whose value is the result of
1243 If C<expr> evaluates to an empty nodeset, a node is created,
1244 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1245 C<name> will be the nodeset containing that single node.
1247 On success this returns a pair containing the
1248 number of nodes in the nodeset, and a boolean flag
1249 if a node was created.");
1251 ("aug_get", (RString "val", [String "augpath"]), 19, [Optional "augeas"],
1252 [], (* XXX Augeas code needs tests. *)
1253 "look up the value of an Augeas path",
1255 Look up the value associated with C<path>. If C<path>
1256 matches exactly one node, the C<value> is returned.");
1258 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [Optional "augeas"],
1259 [], (* XXX Augeas code needs tests. *)
1260 "set Augeas path to value",
1262 Set the value associated with C<path> to C<val>.
1264 In the Augeas API, it is possible to clear a node by setting
1265 the value to NULL. Due to an oversight in the libguestfs API
1266 you cannot do that with this call. Instead you must use the
1267 C<guestfs_aug_clear> call.");
1269 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [Optional "augeas"],
1270 [], (* XXX Augeas code needs tests. *)
1271 "insert a sibling Augeas node",
1273 Create a new sibling C<label> for C<path>, inserting it into
1274 the tree before or after C<path> (depending on the boolean
1277 C<path> must match exactly one existing node in the tree, and
1278 C<label> must be a label, ie. not contain C</>, C<*> or end
1279 with a bracketed index C<[N]>.");
1281 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [Optional "augeas"],
1282 [], (* XXX Augeas code needs tests. *)
1283 "remove an Augeas path",
1285 Remove C<path> and all of its children.
1287 On success this returns the number of entries which were removed.");
1289 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [Optional "augeas"],
1290 [], (* XXX Augeas code needs tests. *)
1293 Move the node C<src> to C<dest>. C<src> must match exactly
1294 one node. C<dest> is overwritten if it exists.");
1296 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [Optional "augeas"],
1297 [], (* XXX Augeas code needs tests. *)
1298 "return Augeas nodes which match augpath",
1300 Returns a list of paths which match the path expression C<path>.
1301 The returned paths are sufficiently qualified so that they match
1302 exactly one node in the current tree.");
1304 ("aug_save", (RErr, []), 25, [Optional "augeas"],
1305 [], (* XXX Augeas code needs tests. *)
1306 "write all pending Augeas changes to disk",
1308 This writes all pending changes to disk.
1310 The flags which were passed to C<guestfs_aug_init> affect exactly
1311 how files are saved.");
1313 ("aug_load", (RErr, []), 27, [Optional "augeas"],
1314 [], (* XXX Augeas code needs tests. *)
1315 "load files into the tree",
1317 Load files into the tree.
1319 See C<aug_load> in the Augeas documentation for the full gory
1322 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [Optional "augeas"],
1323 [], (* XXX Augeas code needs tests. *)
1324 "list Augeas nodes under augpath",
1326 This is just a shortcut for listing C<guestfs_aug_match>
1327 C<path/*> and sorting the resulting nodes into alphabetical order.");
1329 ("rm", (RErr, [Pathname "path"]), 29, [],
1330 [InitBasicFS, Always, TestRun
1333 InitBasicFS, Always, TestLastFail
1335 InitBasicFS, Always, TestLastFail
1340 Remove the single file C<path>.");
1342 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1343 [InitBasicFS, Always, TestRun
1346 InitBasicFS, Always, TestLastFail
1347 [["rmdir"; "/new"]];
1348 InitBasicFS, Always, TestLastFail
1350 ["rmdir"; "/new"]]],
1351 "remove a directory",
1353 Remove the single directory C<path>.");
1355 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1356 [InitBasicFS, Always, TestOutputFalse
1358 ["mkdir"; "/new/foo"];
1359 ["touch"; "/new/foo/bar"];
1361 ["exists"; "/new"]]],
1362 "remove a file or directory recursively",
1364 Remove the file or directory C<path>, recursively removing the
1365 contents if its a directory. This is like the C<rm -rf> shell
1368 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1369 [InitBasicFS, Always, TestOutputTrue
1371 ["is_dir"; "/new"]];
1372 InitBasicFS, Always, TestLastFail
1373 [["mkdir"; "/new/foo/bar"]]],
1374 "create a directory",
1376 Create a directory named C<path>.");
1378 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1379 [InitBasicFS, Always, TestOutputTrue
1380 [["mkdir_p"; "/new/foo/bar"];
1381 ["is_dir"; "/new/foo/bar"]];
1382 InitBasicFS, Always, TestOutputTrue
1383 [["mkdir_p"; "/new/foo/bar"];
1384 ["is_dir"; "/new/foo"]];
1385 InitBasicFS, Always, TestOutputTrue
1386 [["mkdir_p"; "/new/foo/bar"];
1387 ["is_dir"; "/new"]];
1388 (* Regression tests for RHBZ#503133: *)
1389 InitBasicFS, Always, TestRun
1391 ["mkdir_p"; "/new"]];
1392 InitBasicFS, Always, TestLastFail
1394 ["mkdir_p"; "/new"]]],
1395 "create a directory and parents",
1397 Create a directory named C<path>, creating any parent directories
1398 as necessary. This is like the C<mkdir -p> shell command.");
1400 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1401 [], (* XXX Need stat command to test *)
1404 Change the mode (permissions) of C<path> to C<mode>. Only
1405 numeric modes are supported.
1407 I<Note>: When using this command from guestfish, C<mode>
1408 by default would be decimal, unless you prefix it with
1409 C<0> to get octal, ie. use C<0700> not C<700>.
1411 The mode actually set is affected by the umask.");
1413 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1414 [], (* XXX Need stat command to test *)
1415 "change file owner and group",
1417 Change the file owner to C<owner> and group to C<group>.
1419 Only numeric uid and gid are supported. If you want to use
1420 names, you will need to locate and parse the password file
1421 yourself (Augeas support makes this relatively easy).");
1423 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1424 [InitISOFS, Always, TestOutputTrue (
1425 [["exists"; "/empty"]]);
1426 InitISOFS, Always, TestOutputTrue (
1427 [["exists"; "/directory"]])],
1428 "test if file or directory exists",
1430 This returns C<true> if and only if there is a file, directory
1431 (or anything) with the given C<path> name.
1433 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1435 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1436 [InitISOFS, Always, TestOutputTrue (
1437 [["is_file"; "/known-1"]]);
1438 InitISOFS, Always, TestOutputFalse (
1439 [["is_file"; "/directory"]])],
1440 "test if file exists",
1442 This returns C<true> if and only if there is a file
1443 with the given C<path> name. Note that it returns false for
1444 other objects like directories.
1446 See also C<guestfs_stat>.");
1448 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1449 [InitISOFS, Always, TestOutputFalse (
1450 [["is_dir"; "/known-3"]]);
1451 InitISOFS, Always, TestOutputTrue (
1452 [["is_dir"; "/directory"]])],
1453 "test if file exists",
1455 This returns C<true> if and only if there is a directory
1456 with the given C<path> name. Note that it returns false for
1457 other objects like files.
1459 See also C<guestfs_stat>.");
1461 ("pvcreate", (RErr, [Device "device"]), 39, [Optional "lvm2"],
1462 [InitEmpty, Always, TestOutputListOfDevices (
1463 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1464 ["pvcreate"; "/dev/sda1"];
1465 ["pvcreate"; "/dev/sda2"];
1466 ["pvcreate"; "/dev/sda3"];
1467 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1468 "create an LVM physical volume",
1470 This creates an LVM physical volume on the named C<device>,
1471 where C<device> should usually be a partition name such
1474 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [Optional "lvm2"],
1475 [InitEmpty, Always, TestOutputList (
1476 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1477 ["pvcreate"; "/dev/sda1"];
1478 ["pvcreate"; "/dev/sda2"];
1479 ["pvcreate"; "/dev/sda3"];
1480 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1481 ["vgcreate"; "VG2"; "/dev/sda3"];
1482 ["vgs"]], ["VG1"; "VG2"])],
1483 "create an LVM volume group",
1485 This creates an LVM volume group called C<volgroup>
1486 from the non-empty list of physical volumes C<physvols>.");
1488 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [Optional "lvm2"],
1489 [InitEmpty, Always, TestOutputList (
1490 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1491 ["pvcreate"; "/dev/sda1"];
1492 ["pvcreate"; "/dev/sda2"];
1493 ["pvcreate"; "/dev/sda3"];
1494 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1495 ["vgcreate"; "VG2"; "/dev/sda3"];
1496 ["lvcreate"; "LV1"; "VG1"; "50"];
1497 ["lvcreate"; "LV2"; "VG1"; "50"];
1498 ["lvcreate"; "LV3"; "VG2"; "50"];
1499 ["lvcreate"; "LV4"; "VG2"; "50"];
1500 ["lvcreate"; "LV5"; "VG2"; "50"];
1502 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1503 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1504 "create an LVM logical volume",
1506 This creates an LVM logical volume called C<logvol>
1507 on the volume group C<volgroup>, with C<size> megabytes.");
1509 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1510 [InitEmpty, Always, TestOutput (
1511 [["part_disk"; "/dev/sda"; "mbr"];
1512 ["mkfs"; "ext2"; "/dev/sda1"];
1513 ["mount_options"; ""; "/dev/sda1"; "/"];
1514 ["write"; "/new"; "new file contents"];
1515 ["cat"; "/new"]], "new file contents")],
1516 "make a filesystem",
1518 This creates a filesystem on C<device> (usually a partition
1519 or LVM logical volume). The filesystem type is C<fstype>, for
1522 ("sfdisk", (RErr, [Device "device";
1523 Int "cyls"; Int "heads"; Int "sectors";
1524 StringList "lines"]), 43, [DangerWillRobinson],
1526 "create partitions on a block device",
1528 This is a direct interface to the L<sfdisk(8)> program for creating
1529 partitions on block devices.
1531 C<device> should be a block device, for example C</dev/sda>.
1533 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1534 and sectors on the device, which are passed directly to sfdisk as
1535 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1536 of these, then the corresponding parameter is omitted. Usually for
1537 'large' disks, you can just pass C<0> for these, but for small
1538 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1539 out the right geometry and you will need to tell it.
1541 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1542 information refer to the L<sfdisk(8)> manpage.
1544 To create a single partition occupying the whole disk, you would
1545 pass C<lines> as a single element list, when the single element being
1546 the string C<,> (comma).
1548 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1549 C<guestfs_part_init>");
1551 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning; DeprecatedBy "write"],
1552 (* Regression test for RHBZ#597135. *)
1553 [InitBasicFS, Always, TestLastFail
1554 [["write_file"; "/new"; "abc"; "10000"]]],
1557 This call creates a file called C<path>. The contents of the
1558 file is the string C<content> (which can contain any 8 bit data),
1559 with length C<size>.
1561 As a special case, if C<size> is C<0>
1562 then the length is calculated using C<strlen> (so in this case
1563 the content cannot contain embedded ASCII NULs).
1565 I<NB.> Owing to a bug, writing content containing ASCII NUL
1566 characters does I<not> work, even if the length is specified.");
1568 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1569 [InitEmpty, Always, TestOutputListOfDevices (
1570 [["part_disk"; "/dev/sda"; "mbr"];
1571 ["mkfs"; "ext2"; "/dev/sda1"];
1572 ["mount_options"; ""; "/dev/sda1"; "/"];
1573 ["mounts"]], ["/dev/sda1"]);
1574 InitEmpty, Always, TestOutputList (
1575 [["part_disk"; "/dev/sda"; "mbr"];
1576 ["mkfs"; "ext2"; "/dev/sda1"];
1577 ["mount_options"; ""; "/dev/sda1"; "/"];
1580 "unmount a filesystem",
1582 This unmounts the given filesystem. The filesystem may be
1583 specified either by its mountpoint (path) or the device which
1584 contains the filesystem.");
1586 ("mounts", (RStringList "devices", []), 46, [],
1587 [InitBasicFS, Always, TestOutputListOfDevices (
1588 [["mounts"]], ["/dev/sda1"])],
1589 "show mounted filesystems",
1591 This returns the list of currently mounted filesystems. It returns
1592 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1594 Some internal mounts are not shown.
1596 See also: C<guestfs_mountpoints>");
1598 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1599 [InitBasicFS, Always, TestOutputList (
1602 (* check that umount_all can unmount nested mounts correctly: *)
1603 InitEmpty, Always, TestOutputList (
1604 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1605 ["mkfs"; "ext2"; "/dev/sda1"];
1606 ["mkfs"; "ext2"; "/dev/sda2"];
1607 ["mkfs"; "ext2"; "/dev/sda3"];
1608 ["mount_options"; ""; "/dev/sda1"; "/"];
1610 ["mount_options"; ""; "/dev/sda2"; "/mp1"];
1611 ["mkdir"; "/mp1/mp2"];
1612 ["mount_options"; ""; "/dev/sda3"; "/mp1/mp2"];
1613 ["mkdir"; "/mp1/mp2/mp3"];
1616 "unmount all filesystems",
1618 This unmounts all mounted filesystems.
1620 Some internal mounts are not unmounted by this call.");
1622 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson; Optional "lvm2"],
1624 "remove all LVM LVs, VGs and PVs",
1626 This command removes all LVM logical volumes, volume groups
1627 and physical volumes.");
1629 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1630 [InitISOFS, Always, TestOutput (
1631 [["file"; "/empty"]], "empty");
1632 InitISOFS, Always, TestOutput (
1633 [["file"; "/known-1"]], "ASCII text");
1634 InitISOFS, Always, TestLastFail (
1635 [["file"; "/notexists"]])],
1636 "determine file type",
1638 This call uses the standard L<file(1)> command to determine
1639 the type or contents of the file. This also works on devices,
1640 for example to find out whether a partition contains a filesystem.
1642 This call will also transparently look inside various types
1645 The exact command which runs is C<file -zbsL path>. Note in
1646 particular that the filename is not prepended to the output
1647 (the C<-b> option).");
1649 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1650 [InitBasicFS, Always, TestOutput (
1651 [["upload"; "test-command"; "/test-command"];
1652 ["chmod"; "0o755"; "/test-command"];
1653 ["command"; "/test-command 1"]], "Result1");
1654 InitBasicFS, Always, TestOutput (
1655 [["upload"; "test-command"; "/test-command"];
1656 ["chmod"; "0o755"; "/test-command"];
1657 ["command"; "/test-command 2"]], "Result2\n");
1658 InitBasicFS, Always, TestOutput (
1659 [["upload"; "test-command"; "/test-command"];
1660 ["chmod"; "0o755"; "/test-command"];
1661 ["command"; "/test-command 3"]], "\nResult3");
1662 InitBasicFS, Always, TestOutput (
1663 [["upload"; "test-command"; "/test-command"];
1664 ["chmod"; "0o755"; "/test-command"];
1665 ["command"; "/test-command 4"]], "\nResult4\n");
1666 InitBasicFS, Always, TestOutput (
1667 [["upload"; "test-command"; "/test-command"];
1668 ["chmod"; "0o755"; "/test-command"];
1669 ["command"; "/test-command 5"]], "\nResult5\n\n");
1670 InitBasicFS, Always, TestOutput (
1671 [["upload"; "test-command"; "/test-command"];
1672 ["chmod"; "0o755"; "/test-command"];
1673 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1674 InitBasicFS, Always, TestOutput (
1675 [["upload"; "test-command"; "/test-command"];
1676 ["chmod"; "0o755"; "/test-command"];
1677 ["command"; "/test-command 7"]], "");
1678 InitBasicFS, Always, TestOutput (
1679 [["upload"; "test-command"; "/test-command"];
1680 ["chmod"; "0o755"; "/test-command"];
1681 ["command"; "/test-command 8"]], "\n");
1682 InitBasicFS, Always, TestOutput (
1683 [["upload"; "test-command"; "/test-command"];
1684 ["chmod"; "0o755"; "/test-command"];
1685 ["command"; "/test-command 9"]], "\n\n");
1686 InitBasicFS, Always, TestOutput (
1687 [["upload"; "test-command"; "/test-command"];
1688 ["chmod"; "0o755"; "/test-command"];
1689 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1690 InitBasicFS, Always, TestOutput (
1691 [["upload"; "test-command"; "/test-command"];
1692 ["chmod"; "0o755"; "/test-command"];
1693 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1694 InitBasicFS, Always, TestLastFail (
1695 [["upload"; "test-command"; "/test-command"];
1696 ["chmod"; "0o755"; "/test-command"];
1697 ["command"; "/test-command"]])],
1698 "run a command from the guest filesystem",
1700 This call runs a command from the guest filesystem. The
1701 filesystem must be mounted, and must contain a compatible
1702 operating system (ie. something Linux, with the same
1703 or compatible processor architecture).
1705 The single parameter is an argv-style list of arguments.
1706 The first element is the name of the program to run.
1707 Subsequent elements are parameters. The list must be
1708 non-empty (ie. must contain a program name). Note that
1709 the command runs directly, and is I<not> invoked via
1710 the shell (see C<guestfs_sh>).
1712 The return value is anything printed to I<stdout> by
1715 If the command returns a non-zero exit status, then
1716 this function returns an error message. The error message
1717 string is the content of I<stderr> from the command.
1719 The C<$PATH> environment variable will contain at least
1720 C</usr/bin> and C</bin>. If you require a program from
1721 another location, you should provide the full path in the
1724 Shared libraries and data files required by the program
1725 must be available on filesystems which are mounted in the
1726 correct places. It is the caller's responsibility to ensure
1727 all filesystems that are needed are mounted at the right
1730 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1731 [InitBasicFS, Always, TestOutputList (
1732 [["upload"; "test-command"; "/test-command"];
1733 ["chmod"; "0o755"; "/test-command"];
1734 ["command_lines"; "/test-command 1"]], ["Result1"]);
1735 InitBasicFS, Always, TestOutputList (
1736 [["upload"; "test-command"; "/test-command"];
1737 ["chmod"; "0o755"; "/test-command"];
1738 ["command_lines"; "/test-command 2"]], ["Result2"]);
1739 InitBasicFS, Always, TestOutputList (
1740 [["upload"; "test-command"; "/test-command"];
1741 ["chmod"; "0o755"; "/test-command"];
1742 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1743 InitBasicFS, Always, TestOutputList (
1744 [["upload"; "test-command"; "/test-command"];
1745 ["chmod"; "0o755"; "/test-command"];
1746 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1747 InitBasicFS, Always, TestOutputList (
1748 [["upload"; "test-command"; "/test-command"];
1749 ["chmod"; "0o755"; "/test-command"];
1750 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1751 InitBasicFS, Always, TestOutputList (
1752 [["upload"; "test-command"; "/test-command"];
1753 ["chmod"; "0o755"; "/test-command"];
1754 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1755 InitBasicFS, Always, TestOutputList (
1756 [["upload"; "test-command"; "/test-command"];
1757 ["chmod"; "0o755"; "/test-command"];
1758 ["command_lines"; "/test-command 7"]], []);
1759 InitBasicFS, Always, TestOutputList (
1760 [["upload"; "test-command"; "/test-command"];
1761 ["chmod"; "0o755"; "/test-command"];
1762 ["command_lines"; "/test-command 8"]], [""]);
1763 InitBasicFS, Always, TestOutputList (
1764 [["upload"; "test-command"; "/test-command"];
1765 ["chmod"; "0o755"; "/test-command"];
1766 ["command_lines"; "/test-command 9"]], ["";""]);
1767 InitBasicFS, Always, TestOutputList (
1768 [["upload"; "test-command"; "/test-command"];
1769 ["chmod"; "0o755"; "/test-command"];
1770 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1771 InitBasicFS, Always, TestOutputList (
1772 [["upload"; "test-command"; "/test-command"];
1773 ["chmod"; "0o755"; "/test-command"];
1774 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1775 "run a command, returning lines",
1777 This is the same as C<guestfs_command>, but splits the
1778 result into a list of lines.
1780 See also: C<guestfs_sh_lines>");
1782 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1783 [InitISOFS, Always, TestOutputStruct (
1784 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1785 "get file information",
1787 Returns file information for the given C<path>.
1789 This is the same as the C<stat(2)> system call.");
1791 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1792 [InitISOFS, Always, TestOutputStruct (
1793 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1794 "get file information for a symbolic link",
1796 Returns file information for the given C<path>.
1798 This is the same as C<guestfs_stat> except that if C<path>
1799 is a symbolic link, then the link is stat-ed, not the file it
1802 This is the same as the C<lstat(2)> system call.");
1804 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1805 [InitISOFS, Always, TestOutputStruct (
1806 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1807 "get file system statistics",
1809 Returns file system statistics for any mounted file system.
1810 C<path> should be a file or directory in the mounted file system
1811 (typically it is the mount point itself, but it doesn't need to be).
1813 This is the same as the C<statvfs(2)> system call.");
1815 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1817 "get ext2/ext3/ext4 superblock details",
1819 This returns the contents of the ext2, ext3 or ext4 filesystem
1820 superblock on C<device>.
1822 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1823 manpage for more details. The list of fields returned isn't
1824 clearly defined, and depends on both the version of C<tune2fs>
1825 that libguestfs was built against, and the filesystem itself.");
1827 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1828 [InitEmpty, Always, TestOutputTrue (
1829 [["blockdev_setro"; "/dev/sda"];
1830 ["blockdev_getro"; "/dev/sda"]])],
1831 "set block device to read-only",
1833 Sets the block device named C<device> to read-only.
1835 This uses the L<blockdev(8)> command.");
1837 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1838 [InitEmpty, Always, TestOutputFalse (
1839 [["blockdev_setrw"; "/dev/sda"];
1840 ["blockdev_getro"; "/dev/sda"]])],
1841 "set block device to read-write",
1843 Sets the block device named C<device> to read-write.
1845 This uses the L<blockdev(8)> command.");
1847 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1848 [InitEmpty, Always, TestOutputTrue (
1849 [["blockdev_setro"; "/dev/sda"];
1850 ["blockdev_getro"; "/dev/sda"]])],
1851 "is block device set to read-only",
1853 Returns a boolean indicating if the block device is read-only
1854 (true if read-only, false if not).
1856 This uses the L<blockdev(8)> command.");
1858 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1859 [InitEmpty, Always, TestOutputInt (
1860 [["blockdev_getss"; "/dev/sda"]], 512)],
1861 "get sectorsize of block device",
1863 This returns the size of sectors on a block device.
1864 Usually 512, but can be larger for modern devices.
1866 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1869 This uses the L<blockdev(8)> command.");
1871 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1872 [InitEmpty, Always, TestOutputInt (
1873 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1874 "get blocksize of block device",
1876 This returns the block size of a device.
1878 (Note this is different from both I<size in blocks> and
1879 I<filesystem block size>).
1881 This uses the L<blockdev(8)> command.");
1883 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1885 "set blocksize of block device",
1887 This sets the block size of a device.
1889 (Note this is different from both I<size in blocks> and
1890 I<filesystem block size>).
1892 This uses the L<blockdev(8)> command.");
1894 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1895 [InitEmpty, Always, TestOutputInt (
1896 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1897 "get total size of device in 512-byte sectors",
1899 This returns the size of the device in units of 512-byte sectors
1900 (even if the sectorsize isn't 512 bytes ... weird).
1902 See also C<guestfs_blockdev_getss> for the real sector size of
1903 the device, and C<guestfs_blockdev_getsize64> for the more
1904 useful I<size in bytes>.
1906 This uses the L<blockdev(8)> command.");
1908 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1909 [InitEmpty, Always, TestOutputInt (
1910 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1911 "get total size of device in bytes",
1913 This returns the size of the device in bytes.
1915 See also C<guestfs_blockdev_getsz>.
1917 This uses the L<blockdev(8)> command.");
1919 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1920 [InitEmpty, Always, TestRun
1921 [["blockdev_flushbufs"; "/dev/sda"]]],
1922 "flush device buffers",
1924 This tells the kernel to flush internal buffers associated
1927 This uses the L<blockdev(8)> command.");
1929 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1930 [InitEmpty, Always, TestRun
1931 [["blockdev_rereadpt"; "/dev/sda"]]],
1932 "reread partition table",
1934 Reread the partition table on C<device>.
1936 This uses the L<blockdev(8)> command.");
1938 ("upload", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"]), 66, [],
1939 [InitBasicFS, Always, TestOutput (
1940 (* Pick a file from cwd which isn't likely to change. *)
1941 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1942 ["checksum"; "md5"; "/COPYING.LIB"]],
1943 Digest.to_hex (Digest.file "COPYING.LIB"))],
1944 "upload a file from the local machine",
1946 Upload local file C<filename> to C<remotefilename> on the
1949 C<filename> can also be a named pipe.
1951 See also C<guestfs_download>.");
1953 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1954 [InitBasicFS, Always, TestOutput (
1955 (* Pick a file from cwd which isn't likely to change. *)
1956 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1957 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1958 ["upload"; "testdownload.tmp"; "/upload"];
1959 ["checksum"; "md5"; "/upload"]],
1960 Digest.to_hex (Digest.file "COPYING.LIB"))],
1961 "download a file to the local machine",
1963 Download file C<remotefilename> and save it as C<filename>
1964 on the local machine.
1966 C<filename> can also be a named pipe.
1968 See also C<guestfs_upload>, C<guestfs_cat>.");
1970 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1971 [InitISOFS, Always, TestOutput (
1972 [["checksum"; "crc"; "/known-3"]], "2891671662");
1973 InitISOFS, Always, TestLastFail (
1974 [["checksum"; "crc"; "/notexists"]]);
1975 InitISOFS, Always, TestOutput (
1976 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1977 InitISOFS, Always, TestOutput (
1978 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1979 InitISOFS, Always, TestOutput (
1980 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1981 InitISOFS, Always, TestOutput (
1982 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1983 InitISOFS, Always, TestOutput (
1984 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1985 InitISOFS, Always, TestOutput (
1986 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6");
1987 (* Test for RHBZ#579608, absolute symbolic links. *)
1988 InitISOFS, Always, TestOutput (
1989 [["checksum"; "sha512"; "/abssymlink"]], "5f57d0639bc95081c53afc63a449403883818edc64da48930ad6b1a4fb49be90404686877743fbcd7c99811f3def7df7bc22635c885c6a8cf79c806b43451c1a")],
1990 "compute MD5, SHAx or CRC checksum of file",
1992 This call computes the MD5, SHAx or CRC checksum of the
1995 The type of checksum to compute is given by the C<csumtype>
1996 parameter which must have one of the following values:
2002 Compute the cyclic redundancy check (CRC) specified by POSIX
2003 for the C<cksum> command.
2007 Compute the MD5 hash (using the C<md5sum> program).
2011 Compute the SHA1 hash (using the C<sha1sum> program).
2015 Compute the SHA224 hash (using the C<sha224sum> program).
2019 Compute the SHA256 hash (using the C<sha256sum> program).
2023 Compute the SHA384 hash (using the C<sha384sum> program).
2027 Compute the SHA512 hash (using the C<sha512sum> program).
2031 The checksum is returned as a printable string.
2033 To get the checksum for a device, use C<guestfs_checksum_device>.
2035 To get the checksums for many files, use C<guestfs_checksums_out>.");
2037 ("tar_in", (RErr, [FileIn "tarfile"; Pathname "directory"]), 69, [],
2038 [InitBasicFS, Always, TestOutput (
2039 [["tar_in"; "../images/helloworld.tar"; "/"];
2040 ["cat"; "/hello"]], "hello\n")],
2041 "unpack tarfile to directory",
2043 This command uploads and unpacks local file C<tarfile> (an
2044 I<uncompressed> tar file) into C<directory>.
2046 To upload a compressed tarball, use C<guestfs_tgz_in>
2047 or C<guestfs_txz_in>.");
2049 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
2051 "pack directory into tarfile",
2053 This command packs the contents of C<directory> and downloads
2054 it to local file C<tarfile>.
2056 To download a compressed tarball, use C<guestfs_tgz_out>
2057 or C<guestfs_txz_out>.");
2059 ("tgz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 71, [],
2060 [InitBasicFS, Always, TestOutput (
2061 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
2062 ["cat"; "/hello"]], "hello\n")],
2063 "unpack compressed tarball to directory",
2065 This command uploads and unpacks local file C<tarball> (a
2066 I<gzip compressed> tar file) into C<directory>.
2068 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
2070 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
2072 "pack directory into compressed tarball",
2074 This command packs the contents of C<directory> and downloads
2075 it to local file C<tarball>.
2077 To download an uncompressed tarball, use C<guestfs_tar_out>.");
2079 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
2080 [InitBasicFS, Always, TestLastFail (
2082 ["mount_ro"; "/dev/sda1"; "/"];
2083 ["touch"; "/new"]]);
2084 InitBasicFS, Always, TestOutput (
2085 [["write"; "/new"; "data"];
2087 ["mount_ro"; "/dev/sda1"; "/"];
2088 ["cat"; "/new"]], "data")],
2089 "mount a guest disk, read-only",
2091 This is the same as the C<guestfs_mount> command, but it
2092 mounts the filesystem with the read-only (I<-o ro>) flag.");
2094 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2096 "mount a guest disk with mount options",
2098 This is the same as the C<guestfs_mount> command, but it
2099 allows you to set the mount options as for the
2100 L<mount(8)> I<-o> flag.
2102 If the C<options> parameter is an empty string, then
2103 no options are passed (all options default to whatever
2104 the filesystem uses).");
2106 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2108 "mount a guest disk with mount options and vfstype",
2110 This is the same as the C<guestfs_mount> command, but it
2111 allows you to set both the mount options and the vfstype
2112 as for the L<mount(8)> I<-o> and I<-t> flags.");
2114 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2116 "debugging and internals",
2118 The C<guestfs_debug> command exposes some internals of
2119 C<guestfsd> (the guestfs daemon) that runs inside the
2122 There is no comprehensive help for this command. You have
2123 to look at the file C<daemon/debug.c> in the libguestfs source
2124 to find out what you can do.");
2126 ("lvremove", (RErr, [Device "device"]), 77, [Optional "lvm2"],
2127 [InitEmpty, Always, TestOutputList (
2128 [["part_disk"; "/dev/sda"; "mbr"];
2129 ["pvcreate"; "/dev/sda1"];
2130 ["vgcreate"; "VG"; "/dev/sda1"];
2131 ["lvcreate"; "LV1"; "VG"; "50"];
2132 ["lvcreate"; "LV2"; "VG"; "50"];
2133 ["lvremove"; "/dev/VG/LV1"];
2134 ["lvs"]], ["/dev/VG/LV2"]);
2135 InitEmpty, Always, TestOutputList (
2136 [["part_disk"; "/dev/sda"; "mbr"];
2137 ["pvcreate"; "/dev/sda1"];
2138 ["vgcreate"; "VG"; "/dev/sda1"];
2139 ["lvcreate"; "LV1"; "VG"; "50"];
2140 ["lvcreate"; "LV2"; "VG"; "50"];
2141 ["lvremove"; "/dev/VG"];
2143 InitEmpty, Always, TestOutputList (
2144 [["part_disk"; "/dev/sda"; "mbr"];
2145 ["pvcreate"; "/dev/sda1"];
2146 ["vgcreate"; "VG"; "/dev/sda1"];
2147 ["lvcreate"; "LV1"; "VG"; "50"];
2148 ["lvcreate"; "LV2"; "VG"; "50"];
2149 ["lvremove"; "/dev/VG"];
2151 "remove an LVM logical volume",
2153 Remove an LVM logical volume C<device>, where C<device> is
2154 the path to the LV, such as C</dev/VG/LV>.
2156 You can also remove all LVs in a volume group by specifying
2157 the VG name, C</dev/VG>.");
2159 ("vgremove", (RErr, [String "vgname"]), 78, [Optional "lvm2"],
2160 [InitEmpty, Always, TestOutputList (
2161 [["part_disk"; "/dev/sda"; "mbr"];
2162 ["pvcreate"; "/dev/sda1"];
2163 ["vgcreate"; "VG"; "/dev/sda1"];
2164 ["lvcreate"; "LV1"; "VG"; "50"];
2165 ["lvcreate"; "LV2"; "VG"; "50"];
2168 InitEmpty, Always, TestOutputList (
2169 [["part_disk"; "/dev/sda"; "mbr"];
2170 ["pvcreate"; "/dev/sda1"];
2171 ["vgcreate"; "VG"; "/dev/sda1"];
2172 ["lvcreate"; "LV1"; "VG"; "50"];
2173 ["lvcreate"; "LV2"; "VG"; "50"];
2176 "remove an LVM volume group",
2178 Remove an LVM volume group C<vgname>, (for example C<VG>).
2180 This also forcibly removes all logical volumes in the volume
2183 ("pvremove", (RErr, [Device "device"]), 79, [Optional "lvm2"],
2184 [InitEmpty, Always, TestOutputListOfDevices (
2185 [["part_disk"; "/dev/sda"; "mbr"];
2186 ["pvcreate"; "/dev/sda1"];
2187 ["vgcreate"; "VG"; "/dev/sda1"];
2188 ["lvcreate"; "LV1"; "VG"; "50"];
2189 ["lvcreate"; "LV2"; "VG"; "50"];
2191 ["pvremove"; "/dev/sda1"];
2193 InitEmpty, Always, TestOutputListOfDevices (
2194 [["part_disk"; "/dev/sda"; "mbr"];
2195 ["pvcreate"; "/dev/sda1"];
2196 ["vgcreate"; "VG"; "/dev/sda1"];
2197 ["lvcreate"; "LV1"; "VG"; "50"];
2198 ["lvcreate"; "LV2"; "VG"; "50"];
2200 ["pvremove"; "/dev/sda1"];
2202 InitEmpty, Always, TestOutputListOfDevices (
2203 [["part_disk"; "/dev/sda"; "mbr"];
2204 ["pvcreate"; "/dev/sda1"];
2205 ["vgcreate"; "VG"; "/dev/sda1"];
2206 ["lvcreate"; "LV1"; "VG"; "50"];
2207 ["lvcreate"; "LV2"; "VG"; "50"];
2209 ["pvremove"; "/dev/sda1"];
2211 "remove an LVM physical volume",
2213 This wipes a physical volume C<device> so that LVM will no longer
2216 The implementation uses the C<pvremove> command which refuses to
2217 wipe physical volumes that contain any volume groups, so you have
2218 to remove those first.");
2220 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2221 [InitBasicFS, Always, TestOutput (
2222 [["set_e2label"; "/dev/sda1"; "testlabel"];
2223 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2224 "set the ext2/3/4 filesystem label",
2226 This sets the ext2/3/4 filesystem label of the filesystem on
2227 C<device> to C<label>. Filesystem labels are limited to
2230 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2231 to return the existing label on a filesystem.");
2233 ("get_e2label", (RString "label", [Device "device"]), 81, [DeprecatedBy "vfs_label"],
2235 "get the ext2/3/4 filesystem label",
2237 This returns the ext2/3/4 filesystem label of the filesystem on
2240 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2241 (let uuid = uuidgen () in
2242 [InitBasicFS, Always, TestOutput (
2243 [["set_e2uuid"; "/dev/sda1"; uuid];
2244 ["get_e2uuid"; "/dev/sda1"]], uuid);
2245 InitBasicFS, Always, TestOutput (
2246 [["set_e2uuid"; "/dev/sda1"; "clear"];
2247 ["get_e2uuid"; "/dev/sda1"]], "");
2248 (* We can't predict what UUIDs will be, so just check the commands run. *)
2249 InitBasicFS, Always, TestRun (
2250 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2251 InitBasicFS, Always, TestRun (
2252 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2253 "set the ext2/3/4 filesystem UUID",
2255 This sets the ext2/3/4 filesystem UUID of the filesystem on
2256 C<device> to C<uuid>. The format of the UUID and alternatives
2257 such as C<clear>, C<random> and C<time> are described in the
2258 L<tune2fs(8)> manpage.
2260 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2261 to return the existing UUID of a filesystem.");
2263 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [DeprecatedBy "vfs_uuid"],
2264 (* Regression test for RHBZ#597112. *)
2265 (let uuid = uuidgen () in
2266 [InitBasicFS, Always, TestOutput (
2267 [["mke2journal"; "1024"; "/dev/sdb"];
2268 ["set_e2uuid"; "/dev/sdb"; uuid];
2269 ["get_e2uuid"; "/dev/sdb"]], uuid)]),
2270 "get the ext2/3/4 filesystem UUID",
2272 This returns the ext2/3/4 filesystem UUID of the filesystem on
2275 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [FishOutput FishOutputHexadecimal],
2276 [InitBasicFS, Always, TestOutputInt (
2277 [["umount"; "/dev/sda1"];
2278 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2279 InitBasicFS, Always, TestOutputInt (
2280 [["umount"; "/dev/sda1"];
2281 ["zero"; "/dev/sda1"];
2282 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2283 "run the filesystem checker",
2285 This runs the filesystem checker (fsck) on C<device> which
2286 should have filesystem type C<fstype>.
2288 The returned integer is the status. See L<fsck(8)> for the
2289 list of status codes from C<fsck>.
2297 Multiple status codes can be summed together.
2301 A non-zero return code can mean \"success\", for example if
2302 errors have been corrected on the filesystem.
2306 Checking or repairing NTFS volumes is not supported
2311 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2313 ("zero", (RErr, [Device "device"]), 85, [],
2314 [InitBasicFS, Always, TestOutput (
2315 [["umount"; "/dev/sda1"];
2316 ["zero"; "/dev/sda1"];
2317 ["file"; "/dev/sda1"]], "data")],
2318 "write zeroes to the device",
2320 This command writes zeroes over the first few blocks of C<device>.
2322 How many blocks are zeroed isn't specified (but it's I<not> enough
2323 to securely wipe the device). It should be sufficient to remove
2324 any partition tables, filesystem superblocks and so on.
2326 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
2328 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2330 * https://bugzilla.redhat.com/show_bug.cgi?id=484986
2331 * https://bugzilla.redhat.com/show_bug.cgi?id=479760
2333 [InitBasicFS, Always, TestOutputTrue (
2334 [["mkdir_p"; "/boot/grub"];
2335 ["write"; "/boot/grub/device.map"; "(hd0) /dev/vda"];
2336 ["grub_install"; "/"; "/dev/vda"];
2337 ["is_dir"; "/boot"]])],
2340 This command installs GRUB (the Grand Unified Bootloader) on
2341 C<device>, with the root directory being C<root>.
2343 Note: If grub-install reports the error
2344 \"No suitable drive was found in the generated device map.\"
2345 it may be that you need to create a C</boot/grub/device.map>
2346 file first that contains the mapping between grub device names
2347 and Linux device names. It is usually sufficient to create
2352 replacing C</dev/vda> with the name of the installation device.");
2354 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2355 [InitBasicFS, Always, TestOutput (
2356 [["write"; "/old"; "file content"];
2357 ["cp"; "/old"; "/new"];
2358 ["cat"; "/new"]], "file content");
2359 InitBasicFS, Always, TestOutputTrue (
2360 [["write"; "/old"; "file content"];
2361 ["cp"; "/old"; "/new"];
2362 ["is_file"; "/old"]]);
2363 InitBasicFS, Always, TestOutput (
2364 [["write"; "/old"; "file content"];
2366 ["cp"; "/old"; "/dir/new"];
2367 ["cat"; "/dir/new"]], "file content")],
2370 This copies a file from C<src> to C<dest> where C<dest> is
2371 either a destination filename or destination directory.");
2373 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2374 [InitBasicFS, Always, TestOutput (
2375 [["mkdir"; "/olddir"];
2376 ["mkdir"; "/newdir"];
2377 ["write"; "/olddir/file"; "file content"];
2378 ["cp_a"; "/olddir"; "/newdir"];
2379 ["cat"; "/newdir/olddir/file"]], "file content")],
2380 "copy a file or directory recursively",
2382 This copies a file or directory from C<src> to C<dest>
2383 recursively using the C<cp -a> command.");
2385 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2386 [InitBasicFS, Always, TestOutput (
2387 [["write"; "/old"; "file content"];
2388 ["mv"; "/old"; "/new"];
2389 ["cat"; "/new"]], "file content");
2390 InitBasicFS, Always, TestOutputFalse (
2391 [["write"; "/old"; "file content"];
2392 ["mv"; "/old"; "/new"];
2393 ["is_file"; "/old"]])],
2396 This moves a file from C<src> to C<dest> where C<dest> is
2397 either a destination filename or destination directory.");
2399 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2400 [InitEmpty, Always, TestRun (
2401 [["drop_caches"; "3"]])],
2402 "drop kernel page cache, dentries and inodes",
2404 This instructs the guest kernel to drop its page cache,
2405 and/or dentries and inode caches. The parameter C<whattodrop>
2406 tells the kernel what precisely to drop, see
2407 L<http://linux-mm.org/Drop_Caches>
2409 Setting C<whattodrop> to 3 should drop everything.
2411 This automatically calls L<sync(2)> before the operation,
2412 so that the maximum guest memory is freed.");
2414 ("dmesg", (RString "kmsgs", []), 91, [],
2415 [InitEmpty, Always, TestRun (
2417 "return kernel messages",
2419 This returns the kernel messages (C<dmesg> output) from
2420 the guest kernel. This is sometimes useful for extended
2421 debugging of problems.
2423 Another way to get the same information is to enable
2424 verbose messages with C<guestfs_set_verbose> or by setting
2425 the environment variable C<LIBGUESTFS_DEBUG=1> before
2426 running the program.");
2428 ("ping_daemon", (RErr, []), 92, [],
2429 [InitEmpty, Always, TestRun (
2430 [["ping_daemon"]])],
2431 "ping the guest daemon",
2433 This is a test probe into the guestfs daemon running inside
2434 the qemu subprocess. Calling this function checks that the
2435 daemon responds to the ping message, without affecting the daemon
2436 or attached block device(s) in any other way.");
2438 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2439 [InitBasicFS, Always, TestOutputTrue (
2440 [["write"; "/file1"; "contents of a file"];
2441 ["cp"; "/file1"; "/file2"];
2442 ["equal"; "/file1"; "/file2"]]);
2443 InitBasicFS, Always, TestOutputFalse (
2444 [["write"; "/file1"; "contents of a file"];
2445 ["write"; "/file2"; "contents of another file"];
2446 ["equal"; "/file1"; "/file2"]]);
2447 InitBasicFS, Always, TestLastFail (
2448 [["equal"; "/file1"; "/file2"]])],
2449 "test if two files have equal contents",
2451 This compares the two files C<file1> and C<file2> and returns
2452 true if their content is exactly equal, or false otherwise.
2454 The external L<cmp(1)> program is used for the comparison.");
2456 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2457 [InitISOFS, Always, TestOutputList (
2458 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2459 InitISOFS, Always, TestOutputList (
2460 [["strings"; "/empty"]], []);
2461 (* Test for RHBZ#579608, absolute symbolic links. *)
2462 InitISOFS, Always, TestRun (
2463 [["strings"; "/abssymlink"]])],
2464 "print the printable strings in a file",
2466 This runs the L<strings(1)> command on a file and returns
2467 the list of printable strings found.");
2469 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2470 [InitISOFS, Always, TestOutputList (
2471 [["strings_e"; "b"; "/known-5"]], []);
2472 InitBasicFS, Always, TestOutputList (
2473 [["write"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"];
2474 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2475 "print the printable strings in a file",
2477 This is like the C<guestfs_strings> command, but allows you to
2478 specify the encoding of strings that are looked for in
2479 the source file C<path>.
2481 Allowed encodings are:
2487 Single 7-bit-byte characters like ASCII and the ASCII-compatible
2488 parts of ISO-8859-X (this is what C<guestfs_strings> uses).
2492 Single 8-bit-byte characters.
2496 16-bit big endian strings such as those encoded in
2497 UTF-16BE or UCS-2BE.
2499 =item l (lower case letter L)
2501 16-bit little endian such as UTF-16LE and UCS-2LE.
2502 This is useful for examining binaries in Windows guests.
2506 32-bit big endian such as UCS-4BE.
2510 32-bit little endian such as UCS-4LE.
2514 The returned strings are transcoded to UTF-8.");
2516 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2517 [InitISOFS, Always, TestOutput (
2518 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2519 (* Test for RHBZ#501888c2 regression which caused large hexdump
2520 * commands to segfault.
2522 InitISOFS, Always, TestRun (
2523 [["hexdump"; "/100krandom"]]);
2524 (* Test for RHBZ#579608, absolute symbolic links. *)
2525 InitISOFS, Always, TestRun (
2526 [["hexdump"; "/abssymlink"]])],
2527 "dump a file in hexadecimal",
2529 This runs C<hexdump -C> on the given C<path>. The result is
2530 the human-readable, canonical hex dump of the file.");
2532 ("zerofree", (RErr, [Device "device"]), 97, [Optional "zerofree"],
2533 [InitNone, Always, TestOutput (
2534 [["part_disk"; "/dev/sda"; "mbr"];
2535 ["mkfs"; "ext3"; "/dev/sda1"];
2536 ["mount_options"; ""; "/dev/sda1"; "/"];
2537 ["write"; "/new"; "test file"];
2538 ["umount"; "/dev/sda1"];
2539 ["zerofree"; "/dev/sda1"];
2540 ["mount_options"; ""; "/dev/sda1"; "/"];
2541 ["cat"; "/new"]], "test file")],
2542 "zero unused inodes and disk blocks on ext2/3 filesystem",
2544 This runs the I<zerofree> program on C<device>. This program
2545 claims to zero unused inodes and disk blocks on an ext2/3
2546 filesystem, thus making it possible to compress the filesystem
2549 You should B<not> run this program if the filesystem is
2552 It is possible that using this program can damage the filesystem
2553 or data on the filesystem.");
2555 ("pvresize", (RErr, [Device "device"]), 98, [Optional "lvm2"],
2557 "resize an LVM physical volume",
2559 This resizes (expands or shrinks) an existing LVM physical
2560 volume to match the new size of the underlying device.");
2562 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2563 Int "cyls"; Int "heads"; Int "sectors";
2564 String "line"]), 99, [DangerWillRobinson],
2566 "modify a single partition on a block device",
2568 This runs L<sfdisk(8)> option to modify just the single
2569 partition C<n> (note: C<n> counts from 1).
2571 For other parameters, see C<guestfs_sfdisk>. You should usually
2572 pass C<0> for the cyls/heads/sectors parameters.
2574 See also: C<guestfs_part_add>");
2576 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2578 "display the partition table",
2580 This displays the partition table on C<device>, in the
2581 human-readable output of the L<sfdisk(8)> command. It is
2582 not intended to be parsed.
2584 See also: C<guestfs_part_list>");
2586 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2588 "display the kernel geometry",
2590 This displays the kernel's idea of the geometry of C<device>.
2592 The result is in human-readable format, and not designed to
2595 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2597 "display the disk geometry from the partition table",
2599 This displays the disk geometry of C<device> read from the
2600 partition table. Especially in the case where the underlying
2601 block device has been resized, this can be different from the
2602 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2604 The result is in human-readable format, and not designed to
2607 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [Optional "lvm2"],
2609 "activate or deactivate all volume groups",
2611 This command activates or (if C<activate> is false) deactivates
2612 all logical volumes in all volume groups.
2613 If activated, then they are made known to the
2614 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2615 then those devices disappear.
2617 This command is the same as running C<vgchange -a y|n>");
2619 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [Optional "lvm2"],
2621 "activate or deactivate some volume groups",
2623 This command activates or (if C<activate> is false) deactivates
2624 all logical volumes in the listed volume groups C<volgroups>.
2625 If activated, then they are made known to the
2626 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2627 then those devices disappear.
2629 This command is the same as running C<vgchange -a y|n volgroups...>
2631 Note that if C<volgroups> is an empty list then B<all> volume groups
2632 are activated or deactivated.");
2634 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [Optional "lvm2"],
2635 [InitNone, Always, TestOutput (
2636 [["part_disk"; "/dev/sda"; "mbr"];
2637 ["pvcreate"; "/dev/sda1"];
2638 ["vgcreate"; "VG"; "/dev/sda1"];
2639 ["lvcreate"; "LV"; "VG"; "10"];
2640 ["mkfs"; "ext2"; "/dev/VG/LV"];
2641 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2642 ["write"; "/new"; "test content"];
2644 ["lvresize"; "/dev/VG/LV"; "20"];
2645 ["e2fsck_f"; "/dev/VG/LV"];
2646 ["resize2fs"; "/dev/VG/LV"];
2647 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2648 ["cat"; "/new"]], "test content");
2649 InitNone, Always, TestRun (
2650 (* Make an LV smaller to test RHBZ#587484. *)
2651 [["part_disk"; "/dev/sda"; "mbr"];
2652 ["pvcreate"; "/dev/sda1"];
2653 ["vgcreate"; "VG"; "/dev/sda1"];
2654 ["lvcreate"; "LV"; "VG"; "20"];
2655 ["lvresize"; "/dev/VG/LV"; "10"]])],
2656 "resize an LVM logical volume",
2658 This resizes (expands or shrinks) an existing LVM logical
2659 volume to C<mbytes>. When reducing, data in the reduced part
2662 ("resize2fs", (RErr, [Device "device"]), 106, [],
2663 [], (* lvresize tests this *)
2664 "resize an ext2, ext3 or ext4 filesystem",
2666 This resizes an ext2, ext3 or ext4 filesystem to match the size of
2667 the underlying device.
2669 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2670 on the C<device> before calling this command. For unknown reasons
2671 C<resize2fs> sometimes gives an error about this and sometimes not.
2672 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2673 calling this function.");
2675 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2676 [InitBasicFS, Always, TestOutputList (
2677 [["find"; "/"]], ["lost+found"]);
2678 InitBasicFS, Always, TestOutputList (
2682 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2683 InitBasicFS, Always, TestOutputList (
2684 [["mkdir_p"; "/a/b/c"];
2685 ["touch"; "/a/b/c/d"];
2686 ["find"; "/a/b/"]], ["c"; "c/d"])],
2687 "find all files and directories",
2689 This command lists out all files and directories, recursively,
2690 starting at C<directory>. It is essentially equivalent to
2691 running the shell command C<find directory -print> but some
2692 post-processing happens on the output, described below.
2694 This returns a list of strings I<without any prefix>. Thus
2695 if the directory structure was:
2701 then the returned list from C<guestfs_find> C</tmp> would be
2709 If C<directory> is not a directory, then this command returns
2712 The returned list is sorted.
2714 See also C<guestfs_find0>.");
2716 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2717 [], (* lvresize tests this *)
2718 "check an ext2/ext3 filesystem",
2720 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2721 filesystem checker on C<device>, noninteractively (C<-p>),
2722 even if the filesystem appears to be clean (C<-f>).
2724 This command is only needed because of C<guestfs_resize2fs>
2725 (q.v.). Normally you should use C<guestfs_fsck>.");
2727 ("sleep", (RErr, [Int "secs"]), 109, [],
2728 [InitNone, Always, TestRun (
2730 "sleep for some seconds",
2732 Sleep for C<secs> seconds.");
2734 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [Optional "ntfs3g"],
2735 [InitNone, Always, TestOutputInt (
2736 [["part_disk"; "/dev/sda"; "mbr"];
2737 ["mkfs"; "ntfs"; "/dev/sda1"];
2738 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2739 InitNone, Always, TestOutputInt (
2740 [["part_disk"; "/dev/sda"; "mbr"];
2741 ["mkfs"; "ext2"; "/dev/sda1"];
2742 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2743 "probe NTFS volume",
2745 This command runs the L<ntfs-3g.probe(8)> command which probes
2746 an NTFS C<device> for mountability. (Not all NTFS volumes can
2747 be mounted read-write, and some cannot be mounted at all).
2749 C<rw> is a boolean flag. Set it to true if you want to test
2750 if the volume can be mounted read-write. Set it to false if
2751 you want to test if the volume can be mounted read-only.
2753 The return value is an integer which C<0> if the operation
2754 would succeed, or some non-zero value documented in the
2755 L<ntfs-3g.probe(8)> manual page.");
2757 ("sh", (RString "output", [String "command"]), 111, [],
2758 [], (* XXX needs tests *)
2759 "run a command via the shell",
2761 This call runs a command from the guest filesystem via the
2764 This is like C<guestfs_command>, but passes the command to:
2766 /bin/sh -c \"command\"
2768 Depending on the guest's shell, this usually results in
2769 wildcards being expanded, shell expressions being interpolated
2772 All the provisos about C<guestfs_command> apply to this call.");
2774 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2775 [], (* XXX needs tests *)
2776 "run a command via the shell returning lines",
2778 This is the same as C<guestfs_sh>, but splits the result
2779 into a list of lines.
2781 See also: C<guestfs_command_lines>");
2783 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2784 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2785 * code in stubs.c, since all valid glob patterns must start with "/".
2786 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2788 [InitBasicFS, Always, TestOutputList (
2789 [["mkdir_p"; "/a/b/c"];
2790 ["touch"; "/a/b/c/d"];
2791 ["touch"; "/a/b/c/e"];
2792 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2793 InitBasicFS, Always, TestOutputList (
2794 [["mkdir_p"; "/a/b/c"];
2795 ["touch"; "/a/b/c/d"];
2796 ["touch"; "/a/b/c/e"];
2797 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2798 InitBasicFS, Always, TestOutputList (
2799 [["mkdir_p"; "/a/b/c"];
2800 ["touch"; "/a/b/c/d"];
2801 ["touch"; "/a/b/c/e"];
2802 ["glob_expand"; "/a/*/x/*"]], [])],
2803 "expand a wildcard path",
2805 This command searches for all the pathnames matching
2806 C<pattern> according to the wildcard expansion rules
2809 If no paths match, then this returns an empty list
2810 (note: not an error).
2812 It is just a wrapper around the C L<glob(3)> function
2813 with flags C<GLOB_MARK|GLOB_BRACE>.
2814 See that manual page for more details.");
2816 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson; Optional "scrub"],
2817 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2818 [["scrub_device"; "/dev/sdc"]])],
2819 "scrub (securely wipe) a device",
2821 This command writes patterns over C<device> to make data retrieval
2824 It is an interface to the L<scrub(1)> program. See that
2825 manual page for more details.");
2827 ("scrub_file", (RErr, [Pathname "file"]), 115, [Optional "scrub"],
2828 [InitBasicFS, Always, TestRun (
2829 [["write"; "/file"; "content"];
2830 ["scrub_file"; "/file"]])],
2831 "scrub (securely wipe) a file",
2833 This command writes patterns over a file to make data retrieval
2836 The file is I<removed> after scrubbing.
2838 It is an interface to the L<scrub(1)> program. See that
2839 manual page for more details.");
2841 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [Optional "scrub"],
2842 [], (* XXX needs testing *)
2843 "scrub (securely wipe) free space",
2845 This command creates the directory C<dir> and then fills it
2846 with files until the filesystem is full, and scrubs the files
2847 as for C<guestfs_scrub_file>, and deletes them.
2848 The intention is to scrub any free space on the partition
2851 It is an interface to the L<scrub(1)> program. See that
2852 manual page for more details.");
2854 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2855 [InitBasicFS, Always, TestRun (
2857 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2858 "create a temporary directory",
2860 This command creates a temporary directory. The
2861 C<template> parameter should be a full pathname for the
2862 temporary directory name with the final six characters being
2865 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2866 the second one being suitable for Windows filesystems.
2868 The name of the temporary directory that was created
2871 The temporary directory is created with mode 0700
2872 and is owned by root.
2874 The caller is responsible for deleting the temporary
2875 directory and its contents after use.
2877 See also: L<mkdtemp(3)>");
2879 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2880 [InitISOFS, Always, TestOutputInt (
2881 [["wc_l"; "/10klines"]], 10000);
2882 (* Test for RHBZ#579608, absolute symbolic links. *)
2883 InitISOFS, Always, TestOutputInt (
2884 [["wc_l"; "/abssymlink"]], 10000)],
2885 "count lines in a file",
2887 This command counts the lines in a file, using the
2888 C<wc -l> external command.");
2890 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2891 [InitISOFS, Always, TestOutputInt (
2892 [["wc_w"; "/10klines"]], 10000)],
2893 "count words in a file",
2895 This command counts the words in a file, using the
2896 C<wc -w> external command.");
2898 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2899 [InitISOFS, Always, TestOutputInt (
2900 [["wc_c"; "/100kallspaces"]], 102400)],
2901 "count characters in a file",
2903 This command counts the characters in a file, using the
2904 C<wc -c> external command.");
2906 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2907 [InitISOFS, Always, TestOutputList (
2908 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"]);
2909 (* Test for RHBZ#579608, absolute symbolic links. *)
2910 InitISOFS, Always, TestOutputList (
2911 [["head"; "/abssymlink"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2912 "return first 10 lines of a file",
2914 This command returns up to the first 10 lines of a file as
2915 a list of strings.");
2917 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2918 [InitISOFS, Always, TestOutputList (
2919 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2920 InitISOFS, Always, TestOutputList (
2921 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2922 InitISOFS, Always, TestOutputList (
2923 [["head_n"; "0"; "/10klines"]], [])],
2924 "return first N lines of a file",
2926 If the parameter C<nrlines> is a positive number, this returns the first
2927 C<nrlines> lines of the file C<path>.
2929 If the parameter C<nrlines> is a negative number, this returns lines
2930 from the file C<path>, excluding the last C<nrlines> lines.
2932 If the parameter C<nrlines> is zero, this returns an empty list.");
2934 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2935 [InitISOFS, Always, TestOutputList (
2936 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2937 "return last 10 lines of a file",
2939 This command returns up to the last 10 lines of a file as
2940 a list of strings.");
2942 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2943 [InitISOFS, Always, TestOutputList (
2944 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2945 InitISOFS, Always, TestOutputList (
2946 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2947 InitISOFS, Always, TestOutputList (
2948 [["tail_n"; "0"; "/10klines"]], [])],
2949 "return last N lines of a file",
2951 If the parameter C<nrlines> is a positive number, this returns the last
2952 C<nrlines> lines of the file C<path>.
2954 If the parameter C<nrlines> is a negative number, this returns lines
2955 from the file C<path>, starting with the C<-nrlines>th line.
2957 If the parameter C<nrlines> is zero, this returns an empty list.");
2959 ("df", (RString "output", []), 125, [],
2960 [], (* XXX Tricky to test because it depends on the exact format
2961 * of the 'df' command and other imponderables.
2963 "report file system disk space usage",
2965 This command runs the C<df> command to report disk space used.
2967 This command is mostly useful for interactive sessions. It
2968 is I<not> intended that you try to parse the output string.
2969 Use C<statvfs> from programs.");
2971 ("df_h", (RString "output", []), 126, [],
2972 [], (* XXX Tricky to test because it depends on the exact format
2973 * of the 'df' command and other imponderables.
2975 "report file system disk space usage (human readable)",
2977 This command runs the C<df -h> command to report disk space used
2978 in human-readable format.
2980 This command is mostly useful for interactive sessions. It
2981 is I<not> intended that you try to parse the output string.
2982 Use C<statvfs> from programs.");
2984 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2985 [InitISOFS, Always, TestOutputInt (
2986 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2987 "estimate file space usage",
2989 This command runs the C<du -s> command to estimate file space
2992 C<path> can be a file or a directory. If C<path> is a directory
2993 then the estimate includes the contents of the directory and all
2994 subdirectories (recursively).
2996 The result is the estimated size in I<kilobytes>
2997 (ie. units of 1024 bytes).");
2999 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
3000 [InitISOFS, Always, TestOutputList (
3001 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
3002 "list files in an initrd",
3004 This command lists out files contained in an initrd.
3006 The files are listed without any initial C</> character. The
3007 files are listed in the order they appear (not necessarily
3008 alphabetical). Directory names are listed as separate items.
3010 Old Linux kernels (2.4 and earlier) used a compressed ext2
3011 filesystem as initrd. We I<only> support the newer initramfs
3012 format (compressed cpio files).");
3014 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
3016 "mount a file using the loop device",
3018 This command lets you mount C<file> (a filesystem image
3019 in a file) on a mount point. It is entirely equivalent to
3020 the command C<mount -o loop file mountpoint>.");
3022 ("mkswap", (RErr, [Device "device"]), 130, [],
3023 [InitEmpty, Always, TestRun (
3024 [["part_disk"; "/dev/sda"; "mbr"];
3025 ["mkswap"; "/dev/sda1"]])],
3026 "create a swap partition",
3028 Create a swap partition on C<device>.");
3030 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
3031 [InitEmpty, Always, TestRun (
3032 [["part_disk"; "/dev/sda"; "mbr"];
3033 ["mkswap_L"; "hello"; "/dev/sda1"]])],
3034 "create a swap partition with a label",
3036 Create a swap partition on C<device> with label C<label>.
3038 Note that you cannot attach a swap label to a block device
3039 (eg. C</dev/sda>), just to a partition. This appears to be
3040 a limitation of the kernel or swap tools.");
3042 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [Optional "linuxfsuuid"],
3043 (let uuid = uuidgen () in
3044 [InitEmpty, Always, TestRun (
3045 [["part_disk"; "/dev/sda"; "mbr"];
3046 ["mkswap_U"; uuid; "/dev/sda1"]])]),
3047 "create a swap partition with an explicit UUID",
3049 Create a swap partition on C<device> with UUID C<uuid>.");
3051 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [Optional "mknod"],
3052 [InitBasicFS, Always, TestOutputStruct (
3053 [["mknod"; "0o10777"; "0"; "0"; "/node"];
3054 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
3055 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
3056 InitBasicFS, Always, TestOutputStruct (
3057 [["mknod"; "0o60777"; "66"; "99"; "/node"];
3058 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3059 "make block, character or FIFO devices",
3061 This call creates block or character special devices, or
3062 named pipes (FIFOs).
3064 The C<mode> parameter should be the mode, using the standard
3065 constants. C<devmajor> and C<devminor> are the
3066 device major and minor numbers, only used when creating block
3067 and character special devices.
3069 Note that, just like L<mknod(2)>, the mode must be bitwise
3070 OR'd with S_IFBLK, S_IFCHR, S_IFIFO or S_IFSOCK (otherwise this call
3071 just creates a regular file). These constants are
3072 available in the standard Linux header files, or you can use
3073 C<guestfs_mknod_b>, C<guestfs_mknod_c> or C<guestfs_mkfifo>
3074 which are wrappers around this command which bitwise OR
3075 in the appropriate constant for you.
3077 The mode actually set is affected by the umask.");
3079 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [Optional "mknod"],
3080 [InitBasicFS, Always, TestOutputStruct (
3081 [["mkfifo"; "0o777"; "/node"];
3082 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
3083 "make FIFO (named pipe)",
3085 This call creates a FIFO (named pipe) called C<path> with
3086 mode C<mode>. It is just a convenient wrapper around
3089 The mode actually set is affected by the umask.");
3091 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [Optional "mknod"],
3092 [InitBasicFS, Always, TestOutputStruct (
3093 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
3094 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3095 "make block device node",
3097 This call creates a block device node called C<path> with
3098 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3099 It is just a convenient wrapper around C<guestfs_mknod>.
3101 The mode actually set is affected by the umask.");
3103 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [Optional "mknod"],
3104 [InitBasicFS, Always, TestOutputStruct (
3105 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
3106 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
3107 "make char device node",
3109 This call creates a char device node called C<path> with
3110 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3111 It is just a convenient wrapper around C<guestfs_mknod>.
3113 The mode actually set is affected by the umask.");
3115 ("umask", (RInt "oldmask", [Int "mask"]), 137, [FishOutput FishOutputOctal],
3116 [InitEmpty, Always, TestOutputInt (
3117 [["umask"; "0o22"]], 0o22)],
3118 "set file mode creation mask (umask)",
3120 This function sets the mask used for creating new files and
3121 device nodes to C<mask & 0777>.
3123 Typical umask values would be C<022> which creates new files
3124 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
3125 C<002> which creates new files with permissions like
3126 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
3128 The default umask is C<022>. This is important because it
3129 means that directories and device nodes will be created with
3130 C<0644> or C<0755> mode even if you specify C<0777>.
3132 See also C<guestfs_get_umask>,
3133 L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
3135 This call returns the previous umask.");
3137 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
3139 "read directories entries",
3141 This returns the list of directory entries in directory C<dir>.
3143 All entries in the directory are returned, including C<.> and
3144 C<..>. The entries are I<not> sorted, but returned in the same
3145 order as the underlying filesystem.
3147 Also this call returns basic file type information about each
3148 file. The C<ftyp> field will contain one of the following characters:
3186 The L<readdir(3)> call returned a C<d_type> field with an
3191 This function is primarily intended for use by programs. To
3192 get a simple list of names, use C<guestfs_ls>. To get a printable
3193 directory for human consumption, use C<guestfs_ll>.");
3195 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3197 "create partitions on a block device",
3199 This is a simplified interface to the C<guestfs_sfdisk>
3200 command, where partition sizes are specified in megabytes
3201 only (rounded to the nearest cylinder) and you don't need
3202 to specify the cyls, heads and sectors parameters which
3203 were rarely if ever used anyway.
3205 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3206 and C<guestfs_part_disk>");
3208 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3210 "determine file type inside a compressed file",
3212 This command runs C<file> after first decompressing C<path>
3215 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3217 Since 1.0.63, use C<guestfs_file> instead which can now
3218 process compressed files.");
3220 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [Optional "linuxxattrs"],
3222 "list extended attributes of a file or directory",
3224 This call lists the extended attributes of the file or directory
3227 At the system call level, this is a combination of the
3228 L<listxattr(2)> and L<getxattr(2)> calls.
3230 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3232 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [Optional "linuxxattrs"],
3234 "list extended attributes of a file or directory",
3236 This is the same as C<guestfs_getxattrs>, but if C<path>
3237 is a symbolic link, then it returns the extended attributes
3238 of the link itself.");
3240 ("setxattr", (RErr, [String "xattr";
3241 String "val"; Int "vallen"; (* will be BufferIn *)
3242 Pathname "path"]), 143, [Optional "linuxxattrs"],
3244 "set extended attribute of a file or directory",
3246 This call sets the extended attribute named C<xattr>
3247 of the file C<path> to the value C<val> (of length C<vallen>).
3248 The value is arbitrary 8 bit data.
3250 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3252 ("lsetxattr", (RErr, [String "xattr";
3253 String "val"; Int "vallen"; (* will be BufferIn *)
3254 Pathname "path"]), 144, [Optional "linuxxattrs"],
3256 "set extended attribute of a file or directory",
3258 This is the same as C<guestfs_setxattr>, but if C<path>
3259 is a symbolic link, then it sets an extended attribute
3260 of the link itself.");
3262 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [Optional "linuxxattrs"],
3264 "remove extended attribute of a file or directory",
3266 This call removes the extended attribute named C<xattr>
3267 of the file C<path>.
3269 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3271 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [Optional "linuxxattrs"],
3273 "remove extended attribute of a file or directory",
3275 This is the same as C<guestfs_removexattr>, but if C<path>
3276 is a symbolic link, then it removes an extended attribute
3277 of the link itself.");
3279 ("mountpoints", (RHashtable "mps", []), 147, [],
3283 This call is similar to C<guestfs_mounts>. That call returns
3284 a list of devices. This one returns a hash table (map) of
3285 device name to directory where the device is mounted.");
3287 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3288 (* This is a special case: while you would expect a parameter
3289 * of type "Pathname", that doesn't work, because it implies
3290 * NEED_ROOT in the generated calling code in stubs.c, and
3291 * this function cannot use NEED_ROOT.
3294 "create a mountpoint",
3296 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3297 specialized calls that can be used to create extra mountpoints
3298 before mounting the first filesystem.
3300 These calls are I<only> necessary in some very limited circumstances,
3301 mainly the case where you want to mount a mix of unrelated and/or
3302 read-only filesystems together.
3304 For example, live CDs often contain a \"Russian doll\" nest of
3305 filesystems, an ISO outer layer, with a squashfs image inside, with
3306 an ext2/3 image inside that. You can unpack this as follows
3309 add-ro Fedora-11-i686-Live.iso
3312 mkmountpoint /squash
3315 mount-loop /cd/LiveOS/squashfs.img /squash
3316 mount-loop /squash/LiveOS/ext3fs.img /ext3
3318 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3320 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3322 "remove a mountpoint",
3324 This calls removes a mountpoint that was previously created
3325 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3326 for full details.");
3328 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3329 [InitISOFS, Always, TestOutputBuffer (
3330 [["read_file"; "/known-4"]], "abc\ndef\nghi");
3331 (* Test various near large, large and too large files (RHBZ#589039). *)
3332 InitBasicFS, Always, TestLastFail (
3334 ["truncate_size"; "/a"; "4194303"]; (* GUESTFS_MESSAGE_MAX - 1 *)
3335 ["read_file"; "/a"]]);
3336 InitBasicFS, Always, TestLastFail (
3338 ["truncate_size"; "/a"; "4194304"]; (* GUESTFS_MESSAGE_MAX *)
3339 ["read_file"; "/a"]]);
3340 InitBasicFS, Always, TestLastFail (
3342 ["truncate_size"; "/a"; "41943040"]; (* GUESTFS_MESSAGE_MAX * 10 *)
3343 ["read_file"; "/a"]])],
3346 This calls returns the contents of the file C<path> as a
3349 Unlike C<guestfs_cat>, this function can correctly
3350 handle files that contain embedded ASCII NUL characters.
3351 However unlike C<guestfs_download>, this function is limited
3352 in the total size of file that can be handled.");
3354 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3355 [InitISOFS, Always, TestOutputList (
3356 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3357 InitISOFS, Always, TestOutputList (
3358 [["grep"; "nomatch"; "/test-grep.txt"]], []);
3359 (* Test for RHBZ#579608, absolute symbolic links. *)
3360 InitISOFS, Always, TestOutputList (
3361 [["grep"; "nomatch"; "/abssymlink"]], [])],
3362 "return lines matching a pattern",
3364 This calls the external C<grep> program and returns the
3367 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3368 [InitISOFS, Always, TestOutputList (
3369 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3370 "return lines matching a pattern",
3372 This calls the external C<egrep> program and returns the
3375 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3376 [InitISOFS, Always, TestOutputList (
3377 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3378 "return lines matching a pattern",
3380 This calls the external C<fgrep> program and returns the
3383 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3384 [InitISOFS, Always, TestOutputList (
3385 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3386 "return lines matching a pattern",
3388 This calls the external C<grep -i> program and returns the
3391 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3392 [InitISOFS, Always, TestOutputList (
3393 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3394 "return lines matching a pattern",
3396 This calls the external C<egrep -i> program and returns the
3399 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3400 [InitISOFS, Always, TestOutputList (
3401 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3402 "return lines matching a pattern",
3404 This calls the external C<fgrep -i> program and returns the
3407 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3408 [InitISOFS, Always, TestOutputList (
3409 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3410 "return lines matching a pattern",
3412 This calls the external C<zgrep> program and returns the
3415 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3416 [InitISOFS, Always, TestOutputList (
3417 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3418 "return lines matching a pattern",
3420 This calls the external C<zegrep> program and returns the
3423 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3424 [InitISOFS, Always, TestOutputList (
3425 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3426 "return lines matching a pattern",
3428 This calls the external C<zfgrep> program and returns the
3431 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3432 [InitISOFS, Always, TestOutputList (
3433 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3434 "return lines matching a pattern",
3436 This calls the external C<zgrep -i> program and returns the
3439 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3440 [InitISOFS, Always, TestOutputList (
3441 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3442 "return lines matching a pattern",
3444 This calls the external C<zegrep -i> program and returns the
3447 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3448 [InitISOFS, Always, TestOutputList (
3449 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3450 "return lines matching a pattern",
3452 This calls the external C<zfgrep -i> program and returns the
3455 ("realpath", (RString "rpath", [Pathname "path"]), 163, [Optional "realpath"],
3456 [InitISOFS, Always, TestOutput (
3457 [["realpath"; "/../directory"]], "/directory")],
3458 "canonicalized absolute pathname",
3460 Return the canonicalized absolute pathname of C<path>. The
3461 returned path has no C<.>, C<..> or symbolic link path elements.");
3463 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3464 [InitBasicFS, Always, TestOutputStruct (
3467 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3468 "create a hard link",
3470 This command creates a hard link using the C<ln> command.");
3472 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3473 [InitBasicFS, Always, TestOutputStruct (
3476 ["ln_f"; "/a"; "/b"];
3477 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3478 "create a hard link",
3480 This command creates a hard link using the C<ln -f> command.
3481 The C<-f> option removes the link (C<linkname>) if it exists already.");
3483 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3484 [InitBasicFS, Always, TestOutputStruct (
3486 ["ln_s"; "a"; "/b"];
3487 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3488 "create a symbolic link",
3490 This command creates a symbolic link using the C<ln -s> command.");
3492 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3493 [InitBasicFS, Always, TestOutput (
3494 [["mkdir_p"; "/a/b"];
3495 ["touch"; "/a/b/c"];
3496 ["ln_sf"; "../d"; "/a/b/c"];
3497 ["readlink"; "/a/b/c"]], "../d")],
3498 "create a symbolic link",
3500 This command creates a symbolic link using the C<ln -sf> command,
3501 The C<-f> option removes the link (C<linkname>) if it exists already.");
3503 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3504 [] (* XXX tested above *),
3505 "read the target of a symbolic link",
3507 This command reads the target of a symbolic link.");
3509 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"],
3510 [InitBasicFS, Always, TestOutputStruct (
3511 [["fallocate"; "/a"; "1000000"];
3512 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3513 "preallocate a file in the guest filesystem",
3515 This command preallocates a file (containing zero bytes) named
3516 C<path> of size C<len> bytes. If the file exists already, it
3519 Do not confuse this with the guestfish-specific
3520 C<alloc> command which allocates a file in the host and
3521 attaches it as a device.");
3523 ("swapon_device", (RErr, [Device "device"]), 170, [],
3524 [InitPartition, Always, TestRun (
3525 [["mkswap"; "/dev/sda1"];
3526 ["swapon_device"; "/dev/sda1"];
3527 ["swapoff_device"; "/dev/sda1"]])],
3528 "enable swap on device",
3530 This command enables the libguestfs appliance to use the
3531 swap device or partition named C<device>. The increased
3532 memory is made available for all commands, for example
3533 those run using C<guestfs_command> or C<guestfs_sh>.
3535 Note that you should not swap to existing guest swap
3536 partitions unless you know what you are doing. They may
3537 contain hibernation information, or other information that
3538 the guest doesn't want you to trash. You also risk leaking
3539 information about the host to the guest this way. Instead,
3540 attach a new host device to the guest and swap on that.");
3542 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3543 [], (* XXX tested by swapon_device *)
3544 "disable swap on device",
3546 This command disables the libguestfs appliance swap
3547 device or partition named C<device>.
3548 See C<guestfs_swapon_device>.");
3550 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3551 [InitBasicFS, Always, TestRun (
3552 [["fallocate"; "/swap"; "8388608"];
3553 ["mkswap_file"; "/swap"];
3554 ["swapon_file"; "/swap"];
3555 ["swapoff_file"; "/swap"]])],
3556 "enable swap on file",
3558 This command enables swap to a file.
3559 See C<guestfs_swapon_device> for other notes.");
3561 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3562 [], (* XXX tested by swapon_file *)
3563 "disable swap on file",
3565 This command disables the libguestfs appliance swap on file.");
3567 ("swapon_label", (RErr, [String "label"]), 174, [],
3568 [InitEmpty, Always, TestRun (
3569 [["part_disk"; "/dev/sdb"; "mbr"];
3570 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3571 ["swapon_label"; "swapit"];
3572 ["swapoff_label"; "swapit"];
3573 ["zero"; "/dev/sdb"];
3574 ["blockdev_rereadpt"; "/dev/sdb"]])],
3575 "enable swap on labeled swap partition",
3577 This command enables swap to a labeled swap partition.
3578 See C<guestfs_swapon_device> for other notes.");
3580 ("swapoff_label", (RErr, [String "label"]), 175, [],
3581 [], (* XXX tested by swapon_label *)
3582 "disable swap on labeled swap partition",
3584 This command disables the libguestfs appliance swap on
3585 labeled swap partition.");
3587 ("swapon_uuid", (RErr, [String "uuid"]), 176, [Optional "linuxfsuuid"],
3588 (let uuid = uuidgen () in
3589 [InitEmpty, Always, TestRun (
3590 [["mkswap_U"; uuid; "/dev/sdb"];
3591 ["swapon_uuid"; uuid];
3592 ["swapoff_uuid"; uuid]])]),
3593 "enable swap on swap partition by UUID",
3595 This command enables swap to a swap partition with the given UUID.
3596 See C<guestfs_swapon_device> for other notes.");
3598 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [Optional "linuxfsuuid"],
3599 [], (* XXX tested by swapon_uuid *)
3600 "disable swap on swap partition by UUID",
3602 This command disables the libguestfs appliance swap partition
3603 with the given UUID.");
3605 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3606 [InitBasicFS, Always, TestRun (
3607 [["fallocate"; "/swap"; "8388608"];
3608 ["mkswap_file"; "/swap"]])],
3609 "create a swap file",
3613 This command just writes a swap file signature to an existing
3614 file. To create the file itself, use something like C<guestfs_fallocate>.");
3616 ("inotify_init", (RErr, [Int "maxevents"]), 179, [Optional "inotify"],
3617 [InitISOFS, Always, TestRun (
3618 [["inotify_init"; "0"]])],
3619 "create an inotify handle",
3621 This command creates a new inotify handle.
3622 The inotify subsystem can be used to notify events which happen to
3623 objects in the guest filesystem.
3625 C<maxevents> is the maximum number of events which will be
3626 queued up between calls to C<guestfs_inotify_read> or
3627 C<guestfs_inotify_files>.
3628 If this is passed as C<0>, then the kernel (or previously set)
3629 default is used. For Linux 2.6.29 the default was 16384 events.
3630 Beyond this limit, the kernel throws away events, but records
3631 the fact that it threw them away by setting a flag
3632 C<IN_Q_OVERFLOW> in the returned structure list (see
3633 C<guestfs_inotify_read>).
3635 Before any events are generated, you have to add some
3636 watches to the internal watch list. See:
3637 C<guestfs_inotify_add_watch>,
3638 C<guestfs_inotify_rm_watch> and
3639 C<guestfs_inotify_watch_all>.
3641 Queued up events should be read periodically by calling
3642 C<guestfs_inotify_read>
3643 (or C<guestfs_inotify_files> which is just a helpful
3644 wrapper around C<guestfs_inotify_read>). If you don't
3645 read the events out often enough then you risk the internal
3648 The handle should be closed after use by calling
3649 C<guestfs_inotify_close>. This also removes any
3650 watches automatically.
3652 See also L<inotify(7)> for an overview of the inotify interface
3653 as exposed by the Linux kernel, which is roughly what we expose
3654 via libguestfs. Note that there is one global inotify handle
3655 per libguestfs instance.");
3657 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [Optional "inotify"],
3658 [InitBasicFS, Always, TestOutputList (
3659 [["inotify_init"; "0"];
3660 ["inotify_add_watch"; "/"; "1073741823"];
3663 ["inotify_files"]], ["a"; "b"])],
3664 "add an inotify watch",
3666 Watch C<path> for the events listed in C<mask>.
3668 Note that if C<path> is a directory then events within that
3669 directory are watched, but this does I<not> happen recursively
3670 (in subdirectories).
3672 Note for non-C or non-Linux callers: the inotify events are
3673 defined by the Linux kernel ABI and are listed in
3674 C</usr/include/sys/inotify.h>.");
3676 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [Optional "inotify"],
3678 "remove an inotify watch",
3680 Remove a previously defined inotify watch.
3681 See C<guestfs_inotify_add_watch>.");
3683 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [Optional "inotify"],
3685 "return list of inotify events",
3687 Return the complete queue of events that have happened
3688 since the previous read call.
3690 If no events have happened, this returns an empty list.
3692 I<Note>: In order to make sure that all events have been
3693 read, you must call this function repeatedly until it
3694 returns an empty list. The reason is that the call will
3695 read events up to the maximum appliance-to-host message
3696 size and leave remaining events in the queue.");
3698 ("inotify_files", (RStringList "paths", []), 183, [Optional "inotify"],
3700 "return list of watched files that had events",
3702 This function is a helpful wrapper around C<guestfs_inotify_read>
3703 which just returns a list of pathnames of objects that were
3704 touched. The returned pathnames are sorted and deduplicated.");
3706 ("inotify_close", (RErr, []), 184, [Optional "inotify"],
3708 "close the inotify handle",
3710 This closes the inotify handle which was previously
3711 opened by inotify_init. It removes all watches, throws
3712 away any pending events, and deallocates all resources.");
3714 ("setcon", (RErr, [String "context"]), 185, [Optional "selinux"],
3716 "set SELinux security context",
3718 This sets the SELinux security context of the daemon
3719 to the string C<context>.
3721 See the documentation about SELINUX in L<guestfs(3)>.");
3723 ("getcon", (RString "context", []), 186, [Optional "selinux"],
3725 "get SELinux security context",
3727 This gets the SELinux security context of the daemon.
3729 See the documentation about SELINUX in L<guestfs(3)>,
3730 and C<guestfs_setcon>");
3732 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3733 [InitEmpty, Always, TestOutput (
3734 [["part_disk"; "/dev/sda"; "mbr"];
3735 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3736 ["mount_options"; ""; "/dev/sda1"; "/"];
3737 ["write"; "/new"; "new file contents"];
3738 ["cat"; "/new"]], "new file contents");
3739 InitEmpty, Always, TestRun (
3740 [["part_disk"; "/dev/sda"; "mbr"];
3741 ["mkfs_b"; "vfat"; "32768"; "/dev/sda1"]]);
3742 InitEmpty, Always, TestLastFail (
3743 [["part_disk"; "/dev/sda"; "mbr"];
3744 ["mkfs_b"; "vfat"; "32769"; "/dev/sda1"]]);
3745 InitEmpty, Always, TestLastFail (
3746 [["part_disk"; "/dev/sda"; "mbr"];
3747 ["mkfs_b"; "vfat"; "33280"; "/dev/sda1"]]);
3748 InitEmpty, IfAvailable "ntfsprogs", TestRun (
3749 [["part_disk"; "/dev/sda"; "mbr"];
3750 ["mkfs_b"; "ntfs"; "32768"; "/dev/sda1"]])],
3751 "make a filesystem with block size",
3753 This call is similar to C<guestfs_mkfs>, but it allows you to
3754 control the block size of the resulting filesystem. Supported
3755 block sizes depend on the filesystem type, but typically they
3756 are C<1024>, C<2048> or C<4096> only.
3758 For VFAT and NTFS the C<blocksize> parameter is treated as
3759 the requested cluster size.");
3761 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3762 [InitEmpty, Always, TestOutput (
3763 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3764 ["mke2journal"; "4096"; "/dev/sda1"];
3765 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3766 ["mount_options"; ""; "/dev/sda2"; "/"];
3767 ["write"; "/new"; "new file contents"];
3768 ["cat"; "/new"]], "new file contents")],
3769 "make ext2/3/4 external journal",
3771 This creates an ext2 external journal on C<device>. It is equivalent
3774 mke2fs -O journal_dev -b blocksize device");
3776 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3777 [InitEmpty, Always, TestOutput (
3778 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3779 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3780 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3781 ["mount_options"; ""; "/dev/sda2"; "/"];
3782 ["write"; "/new"; "new file contents"];
3783 ["cat"; "/new"]], "new file contents")],
3784 "make ext2/3/4 external journal with label",
3786 This creates an ext2 external journal on C<device> with label C<label>.");
3788 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [Optional "linuxfsuuid"],
3789 (let uuid = uuidgen () in
3790 [InitEmpty, Always, TestOutput (
3791 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3792 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3793 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3794 ["mount_options"; ""; "/dev/sda2"; "/"];
3795 ["write"; "/new"; "new file contents"];
3796 ["cat"; "/new"]], "new file contents")]),
3797 "make ext2/3/4 external journal with UUID",
3799 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3801 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3803 "make ext2/3/4 filesystem with external journal",
3805 This creates an ext2/3/4 filesystem on C<device> with
3806 an external journal on C<journal>. It is equivalent
3809 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3811 See also C<guestfs_mke2journal>.");
3813 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3815 "make ext2/3/4 filesystem with external journal",
3817 This creates an ext2/3/4 filesystem on C<device> with
3818 an external journal on the journal labeled C<label>.
3820 See also C<guestfs_mke2journal_L>.");
3822 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [Optional "linuxfsuuid"],
3824 "make ext2/3/4 filesystem with external journal",
3826 This creates an ext2/3/4 filesystem on C<device> with
3827 an external journal on the journal with UUID C<uuid>.
3829 See also C<guestfs_mke2journal_U>.");
3831 ("modprobe", (RErr, [String "modulename"]), 194, [Optional "linuxmodules"],
3832 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3833 "load a kernel module",
3835 This loads a kernel module in the appliance.
3837 The kernel module must have been whitelisted when libguestfs
3838 was built (see C<appliance/kmod.whitelist.in> in the source).");
3840 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3841 [InitNone, Always, TestOutput (
3842 [["echo_daemon"; "This is a test"]], "This is a test"
3844 "echo arguments back to the client",
3846 This command concatenates the list of C<words> passed with single spaces
3847 between them and returns the resulting string.
3849 You can use this command to test the connection through to the daemon.
3851 See also C<guestfs_ping_daemon>.");
3853 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3854 [], (* There is a regression test for this. *)
3855 "find all files and directories, returning NUL-separated list",
3857 This command lists out all files and directories, recursively,
3858 starting at C<directory>, placing the resulting list in the
3859 external file called C<files>.
3861 This command works the same way as C<guestfs_find> with the
3862 following exceptions:
3868 The resulting list is written to an external file.
3872 Items (filenames) in the result are separated
3873 by C<\\0> characters. See L<find(1)> option I<-print0>.
3877 This command is not limited in the number of names that it
3882 The result list is not sorted.
3886 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3887 [InitISOFS, Always, TestOutput (
3888 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3889 InitISOFS, Always, TestOutput (
3890 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3891 InitISOFS, Always, TestOutput (
3892 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3893 InitISOFS, Always, TestLastFail (
3894 [["case_sensitive_path"; "/Known-1/"]]);
3895 InitBasicFS, Always, TestOutput (
3897 ["mkdir"; "/a/bbb"];
3898 ["touch"; "/a/bbb/c"];
3899 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3900 InitBasicFS, Always, TestOutput (
3902 ["mkdir"; "/a/bbb"];
3903 ["touch"; "/a/bbb/c"];
3904 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3905 InitBasicFS, Always, TestLastFail (
3907 ["mkdir"; "/a/bbb"];
3908 ["touch"; "/a/bbb/c"];
3909 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3910 "return true path on case-insensitive filesystem",
3912 This can be used to resolve case insensitive paths on
3913 a filesystem which is case sensitive. The use case is
3914 to resolve paths which you have read from Windows configuration
3915 files or the Windows Registry, to the true path.
3917 The command handles a peculiarity of the Linux ntfs-3g
3918 filesystem driver (and probably others), which is that although
3919 the underlying filesystem is case-insensitive, the driver
3920 exports the filesystem to Linux as case-sensitive.
3922 One consequence of this is that special directories such
3923 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3924 (or other things) depending on the precise details of how
3925 they were created. In Windows itself this would not be
3928 Bug or feature? You decide:
3929 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3931 This function resolves the true case of each element in the
3932 path and returns the case-sensitive path.
3934 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3935 might return C<\"/WINDOWS/system32\"> (the exact return value
3936 would depend on details of how the directories were originally
3937 created under Windows).
3940 This function does not handle drive names, backslashes etc.
3942 See also C<guestfs_realpath>.");
3944 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3945 [InitBasicFS, Always, TestOutput (
3946 [["vfs_type"; "/dev/sda1"]], "ext2")],
3947 "get the Linux VFS type corresponding to a mounted device",
3949 This command gets the filesystem type corresponding to
3950 the filesystem on C<device>.
3952 For most filesystems, the result is the name of the Linux
3953 VFS module which would be used to mount this filesystem
3954 if you mounted it without specifying the filesystem type.
3955 For example a string such as C<ext3> or C<ntfs>.");
3957 ("truncate", (RErr, [Pathname "path"]), 199, [],
3958 [InitBasicFS, Always, TestOutputStruct (
3959 [["write"; "/test"; "some stuff so size is not zero"];
3960 ["truncate"; "/test"];
3961 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3962 "truncate a file to zero size",
3964 This command truncates C<path> to a zero-length file. The
3965 file must exist already.");
3967 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3968 [InitBasicFS, Always, TestOutputStruct (
3969 [["touch"; "/test"];
3970 ["truncate_size"; "/test"; "1000"];
3971 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3972 "truncate a file to a particular size",
3974 This command truncates C<path> to size C<size> bytes. The file
3977 If the current file size is less than C<size> then
3978 the file is extended to the required size with zero bytes.
3979 This creates a sparse file (ie. disk blocks are not allocated
3980 for the file until you write to it). To create a non-sparse
3981 file of zeroes, use C<guestfs_fallocate64> instead.");
3983 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3984 [InitBasicFS, Always, TestOutputStruct (
3985 [["touch"; "/test"];
3986 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3987 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3988 "set timestamp of a file with nanosecond precision",
3990 This command sets the timestamps of a file with nanosecond
3993 C<atsecs, atnsecs> are the last access time (atime) in secs and
3994 nanoseconds from the epoch.
3996 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3997 secs and nanoseconds from the epoch.
3999 If the C<*nsecs> field contains the special value C<-1> then
4000 the corresponding timestamp is set to the current time. (The
4001 C<*secs> field is ignored in this case).
4003 If the C<*nsecs> field contains the special value C<-2> then
4004 the corresponding timestamp is left unchanged. (The
4005 C<*secs> field is ignored in this case).");
4007 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
4008 [InitBasicFS, Always, TestOutputStruct (
4009 [["mkdir_mode"; "/test"; "0o111"];
4010 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
4011 "create a directory with a particular mode",
4013 This command creates a directory, setting the initial permissions
4014 of the directory to C<mode>.
4016 For common Linux filesystems, the actual mode which is set will
4017 be C<mode & ~umask & 01777>. Non-native-Linux filesystems may
4018 interpret the mode in other ways.
4020 See also C<guestfs_mkdir>, C<guestfs_umask>");
4022 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
4024 "change file owner and group",
4026 Change the file owner to C<owner> and group to C<group>.
4027 This is like C<guestfs_chown> but if C<path> is a symlink then
4028 the link itself is changed, not the target.
4030 Only numeric uid and gid are supported. If you want to use
4031 names, you will need to locate and parse the password file
4032 yourself (Augeas support makes this relatively easy).");
4034 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
4036 "lstat on multiple files",
4038 This call allows you to perform the C<guestfs_lstat> operation
4039 on multiple files, where all files are in the directory C<path>.
4040 C<names> is the list of files from this directory.
4042 On return you get a list of stat structs, with a one-to-one
4043 correspondence to the C<names> list. If any name did not exist
4044 or could not be lstat'd, then the C<ino> field of that structure
4047 This call is intended for programs that want to efficiently
4048 list a directory contents without making many round-trips.
4049 See also C<guestfs_lxattrlist> for a similarly efficient call
4050 for getting extended attributes. Very long directory listings
4051 might cause the protocol message size to be exceeded, causing
4052 this call to fail. The caller must split up such requests
4053 into smaller groups of names.");
4055 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [Optional "linuxxattrs"],
4057 "lgetxattr on multiple files",
4059 This call allows you to get the extended attributes
4060 of multiple files, where all files are in the directory C<path>.
4061 C<names> is the list of files from this directory.
4063 On return you get a flat list of xattr structs which must be
4064 interpreted sequentially. The first xattr struct always has a zero-length
4065 C<attrname>. C<attrval> in this struct is zero-length
4066 to indicate there was an error doing C<lgetxattr> for this
4067 file, I<or> is a C string which is a decimal number
4068 (the number of following attributes for this file, which could
4069 be C<\"0\">). Then after the first xattr struct are the
4070 zero or more attributes for the first named file.
4071 This repeats for the second and subsequent files.
4073 This call is intended for programs that want to efficiently
4074 list a directory contents without making many round-trips.
4075 See also C<guestfs_lstatlist> for a similarly efficient call
4076 for getting standard stats. Very long directory listings
4077 might cause the protocol message size to be exceeded, causing
4078 this call to fail. The caller must split up such requests
4079 into smaller groups of names.");
4081 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
4083 "readlink on multiple files",
4085 This call allows you to do a C<readlink> operation
4086 on multiple files, where all files are in the directory C<path>.
4087 C<names> is the list of files from this directory.
4089 On return you get a list of strings, with a one-to-one
4090 correspondence to the C<names> list. Each string is the
4091 value of the symbolic link.
4093 If the C<readlink(2)> operation fails on any name, then
4094 the corresponding result string is the empty string C<\"\">.
4095 However the whole operation is completed even if there
4096 were C<readlink(2)> errors, and so you can call this
4097 function with names where you don't know if they are
4098 symbolic links already (albeit slightly less efficient).
4100 This call is intended for programs that want to efficiently
4101 list a directory contents without making many round-trips.
4102 Very long directory listings might cause the protocol
4103 message size to be exceeded, causing
4104 this call to fail. The caller must split up such requests
4105 into smaller groups of names.");
4107 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
4108 [InitISOFS, Always, TestOutputBuffer (
4109 [["pread"; "/known-4"; "1"; "3"]], "\n");
4110 InitISOFS, Always, TestOutputBuffer (
4111 [["pread"; "/empty"; "0"; "100"]], "")],
4112 "read part of a file",
4114 This command lets you read part of a file. It reads C<count>
4115 bytes of the file, starting at C<offset>, from file C<path>.
4117 This may read fewer bytes than requested. For further details
4118 see the L<pread(2)> system call.
4120 See also C<guestfs_pwrite>.");
4122 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
4123 [InitEmpty, Always, TestRun (
4124 [["part_init"; "/dev/sda"; "gpt"]])],
4125 "create an empty partition table",
4127 This creates an empty partition table on C<device> of one of the
4128 partition types listed below. Usually C<parttype> should be
4129 either C<msdos> or C<gpt> (for large disks).
4131 Initially there are no partitions. Following this, you should
4132 call C<guestfs_part_add> for each partition required.
4134 Possible values for C<parttype> are:
4138 =item B<efi> | B<gpt>
4140 Intel EFI / GPT partition table.
4142 This is recommended for >= 2 TB partitions that will be accessed
4143 from Linux and Intel-based Mac OS X. It also has limited backwards
4144 compatibility with the C<mbr> format.
4146 =item B<mbr> | B<msdos>
4148 The standard PC \"Master Boot Record\" (MBR) format used
4149 by MS-DOS and Windows. This partition type will B<only> work
4150 for device sizes up to 2 TB. For large disks we recommend
4155 Other partition table types that may work but are not
4164 =item B<amiga> | B<rdb>
4166 Amiga \"Rigid Disk Block\" format.
4174 DASD, used on IBM mainframes.
4182 Old Mac partition format. Modern Macs use C<gpt>.
4186 NEC PC-98 format, common in Japan apparently.
4194 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
4195 [InitEmpty, Always, TestRun (
4196 [["part_init"; "/dev/sda"; "mbr"];
4197 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
4198 InitEmpty, Always, TestRun (
4199 [["part_init"; "/dev/sda"; "gpt"];
4200 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
4201 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
4202 InitEmpty, Always, TestRun (
4203 [["part_init"; "/dev/sda"; "mbr"];
4204 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
4205 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
4206 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
4207 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
4208 "add a partition to the device",
4210 This command adds a partition to C<device>. If there is no partition
4211 table on the device, call C<guestfs_part_init> first.
4213 The C<prlogex> parameter is the type of partition. Normally you
4214 should pass C<p> or C<primary> here, but MBR partition tables also
4215 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4218 C<startsect> and C<endsect> are the start and end of the partition
4219 in I<sectors>. C<endsect> may be negative, which means it counts
4220 backwards from the end of the disk (C<-1> is the last sector).
4222 Creating a partition which covers the whole disk is not so easy.
4223 Use C<guestfs_part_disk> to do that.");
4225 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4226 [InitEmpty, Always, TestRun (
4227 [["part_disk"; "/dev/sda"; "mbr"]]);
4228 InitEmpty, Always, TestRun (
4229 [["part_disk"; "/dev/sda"; "gpt"]])],
4230 "partition whole disk with a single primary partition",
4232 This command is simply a combination of C<guestfs_part_init>
4233 followed by C<guestfs_part_add> to create a single primary partition
4234 covering the whole disk.
4236 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4237 but other possible values are described in C<guestfs_part_init>.");
4239 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4240 [InitEmpty, Always, TestRun (
4241 [["part_disk"; "/dev/sda"; "mbr"];
4242 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4243 "make a partition bootable",
4245 This sets the bootable flag on partition numbered C<partnum> on
4246 device C<device>. Note that partitions are numbered from 1.
4248 The bootable flag is used by some operating systems (notably
4249 Windows) to determine which partition to boot from. It is by
4250 no means universally recognized.");
4252 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4253 [InitEmpty, Always, TestRun (
4254 [["part_disk"; "/dev/sda"; "gpt"];
4255 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4256 "set partition name",
4258 This sets the partition name on partition numbered C<partnum> on
4259 device C<device>. Note that partitions are numbered from 1.
4261 The partition name can only be set on certain types of partition
4262 table. This works on C<gpt> but not on C<mbr> partitions.");
4264 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4265 [], (* XXX Add a regression test for this. *)
4266 "list partitions on a device",
4268 This command parses the partition table on C<device> and
4269 returns the list of partitions found.
4271 The fields in the returned structure are:
4277 Partition number, counting from 1.
4281 Start of the partition I<in bytes>. To get sectors you have to
4282 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4286 End of the partition in bytes.
4290 Size of the partition in bytes.
4294 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4295 [InitEmpty, Always, TestOutput (
4296 [["part_disk"; "/dev/sda"; "gpt"];
4297 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4298 "get the partition table type",
4300 This command examines the partition table on C<device> and
4301 returns the partition table type (format) being used.
4303 Common return values include: C<msdos> (a DOS/Windows style MBR
4304 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4305 values are possible, although unusual. See C<guestfs_part_init>
4308 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4309 [InitBasicFS, Always, TestOutputBuffer (
4310 [["fill"; "0x63"; "10"; "/test"];
4311 ["read_file"; "/test"]], "cccccccccc")],
4312 "fill a file with octets",
4314 This command creates a new file called C<path>. The initial
4315 content of the file is C<len> octets of C<c>, where C<c>
4316 must be a number in the range C<[0..255]>.
4318 To fill a file with zero bytes (sparsely), it is
4319 much more efficient to use C<guestfs_truncate_size>.
4320 To create a file with a pattern of repeating bytes
4321 use C<guestfs_fill_pattern>.");
4323 ("available", (RErr, [StringList "groups"]), 216, [],
4324 [InitNone, Always, TestRun [["available"; ""]]],
4325 "test availability of some parts of the API",
4327 This command is used to check the availability of some
4328 groups of functionality in the appliance, which not all builds of
4329 the libguestfs appliance will be able to provide.
4331 The libguestfs groups, and the functions that those
4332 groups correspond to, are listed in L<guestfs(3)/AVAILABILITY>.
4333 You can also fetch this list at runtime by calling
4334 C<guestfs_available_all_groups>.
4336 The argument C<groups> is a list of group names, eg:
4337 C<[\"inotify\", \"augeas\"]> would check for the availability of
4338 the Linux inotify functions and Augeas (configuration file
4341 The command returns no error if I<all> requested groups are available.
4343 It fails with an error if one or more of the requested
4344 groups is unavailable in the appliance.
4346 If an unknown group name is included in the
4347 list of groups then an error is always returned.
4355 You must call C<guestfs_launch> before calling this function.
4357 The reason is because we don't know what groups are
4358 supported by the appliance/daemon until it is running and can
4363 If a group of functions is available, this does not necessarily
4364 mean that they will work. You still have to check for errors
4365 when calling individual API functions even if they are
4370 It is usually the job of distro packagers to build
4371 complete functionality into the libguestfs appliance.
4372 Upstream libguestfs, if built from source with all
4373 requirements satisfied, will support everything.
4377 This call was added in version C<1.0.80>. In previous
4378 versions of libguestfs all you could do would be to speculatively
4379 execute a command to find out if the daemon implemented it.
4380 See also C<guestfs_version>.
4384 ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [],
4385 [InitBasicFS, Always, TestOutputBuffer (
4386 [["write"; "/src"; "hello, world"];
4387 ["dd"; "/src"; "/dest"];
4388 ["read_file"; "/dest"]], "hello, world")],
4389 "copy from source to destination using dd",
4391 This command copies from one source device or file C<src>
4392 to another destination device or file C<dest>. Normally you
4393 would use this to copy to or from a device or partition, for
4394 example to duplicate a filesystem.
4396 If the destination is a device, it must be as large or larger
4397 than the source file or device, otherwise the copy will fail.
4398 This command cannot do partial copies (see C<guestfs_copy_size>).");
4400 ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
4401 [InitBasicFS, Always, TestOutputInt (
4402 [["write"; "/file"; "hello, world"];
4403 ["filesize"; "/file"]], 12)],
4404 "return the size of the file in bytes",
4406 This command returns the size of C<file> in bytes.
4408 To get other stats about a file, use C<guestfs_stat>, C<guestfs_lstat>,
4409 C<guestfs_is_dir>, C<guestfs_is_file> etc.
4410 To get the size of block devices, use C<guestfs_blockdev_getsize64>.");
4412 ("lvrename", (RErr, [String "logvol"; String "newlogvol"]), 219, [],
4413 [InitBasicFSonLVM, Always, TestOutputList (
4414 [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
4415 ["lvs"]], ["/dev/VG/LV2"])],
4416 "rename an LVM logical volume",
4418 Rename a logical volume C<logvol> with the new name C<newlogvol>.");
4420 ("vgrename", (RErr, [String "volgroup"; String "newvolgroup"]), 220, [],
4421 [InitBasicFSonLVM, Always, TestOutputList (
4423 ["vg_activate"; "false"; "VG"];
4424 ["vgrename"; "VG"; "VG2"];
4425 ["vg_activate"; "true"; "VG2"];
4426 ["mount_options"; ""; "/dev/VG2/LV"; "/"];
4427 ["vgs"]], ["VG2"])],
4428 "rename an LVM volume group",
4430 Rename a volume group C<volgroup> with the new name C<newvolgroup>.");
4432 ("initrd_cat", (RBufferOut "content", [Pathname "initrdpath"; String "filename"]), 221, [ProtocolLimitWarning],
4433 [InitISOFS, Always, TestOutputBuffer (
4434 [["initrd_cat"; "/initrd"; "known-4"]], "abc\ndef\nghi")],
4435 "list the contents of a single file in an initrd",
4437 This command unpacks the file C<filename> from the initrd file
4438 called C<initrdpath>. The filename must be given I<without> the
4439 initial C</> character.
4441 For example, in guestfish you could use the following command
4442 to examine the boot script (usually called C</init>)
4443 contained in a Linux initrd or initramfs image:
4445 initrd-cat /boot/initrd-<version>.img init
4447 See also C<guestfs_initrd_list>.");
4449 ("pvuuid", (RString "uuid", [Device "device"]), 222, [],
4451 "get the UUID of a physical volume",
4453 This command returns the UUID of the LVM PV C<device>.");
4455 ("vguuid", (RString "uuid", [String "vgname"]), 223, [],
4457 "get the UUID of a volume group",
4459 This command returns the UUID of the LVM VG named C<vgname>.");
4461 ("lvuuid", (RString "uuid", [Device "device"]), 224, [],
4463 "get the UUID of a logical volume",
4465 This command returns the UUID of the LVM LV C<device>.");
4467 ("vgpvuuids", (RStringList "uuids", [String "vgname"]), 225, [],
4469 "get the PV UUIDs containing the volume group",
4471 Given a VG called C<vgname>, this returns the UUIDs of all
4472 the physical volumes that this volume group resides on.
4474 You can use this along with C<guestfs_pvs> and C<guestfs_pvuuid>
4475 calls to associate physical volumes and volume groups.
4477 See also C<guestfs_vglvuuids>.");
4479 ("vglvuuids", (RStringList "uuids", [String "vgname"]), 226, [],
4481 "get the LV UUIDs of all LVs in the volume group",
4483 Given a VG called C<vgname>, this returns the UUIDs of all
4484 the logical volumes created in this volume group.
4486 You can use this along with C<guestfs_lvs> and C<guestfs_lvuuid>
4487 calls to associate logical volumes and volume groups.
4489 See also C<guestfs_vgpvuuids>.");
4491 ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
4492 [InitBasicFS, Always, TestOutputBuffer (
4493 [["write"; "/src"; "hello, world"];
4494 ["copy_size"; "/src"; "/dest"; "5"];
4495 ["read_file"; "/dest"]], "hello")],
4496 "copy size bytes from source to destination using dd",
4498 This command copies exactly C<size> bytes from one source device
4499 or file C<src> to another destination device or file C<dest>.
4501 Note this will fail if the source is too short or if the destination
4502 is not large enough.");
4504 ("zero_device", (RErr, [Device "device"]), 228, [DangerWillRobinson],
4505 [InitBasicFSonLVM, Always, TestRun (
4506 [["zero_device"; "/dev/VG/LV"]])],
4507 "write zeroes to an entire device",
4509 This command writes zeroes over the entire C<device>. Compare
4510 with C<guestfs_zero> which just zeroes the first few blocks of
4513 ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"],
4514 [InitBasicFS, Always, TestOutput (
4515 [["txz_in"; "../images/helloworld.tar.xz"; "/"];
4516 ["cat"; "/hello"]], "hello\n")],
4517 "unpack compressed tarball to directory",
4519 This command uploads and unpacks local file C<tarball> (an
4520 I<xz compressed> tar file) into C<directory>.");
4522 ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"],
4524 "pack directory into compressed tarball",
4526 This command packs the contents of C<directory> and downloads
4527 it to local file C<tarball> (as an xz compressed tar archive).");
4529 ("ntfsresize", (RErr, [Device "device"]), 231, [Optional "ntfsprogs"],
4531 "resize an NTFS filesystem",
4533 This command resizes an NTFS filesystem, expanding or
4534 shrinking it to the size of the underlying device.
4535 See also L<ntfsresize(8)>.");
4537 ("vgscan", (RErr, []), 232, [],
4538 [InitEmpty, Always, TestRun (
4540 "rescan for LVM physical volumes, volume groups and logical volumes",
4542 This rescans all block devices and rebuilds the list of LVM
4543 physical volumes, volume groups and logical volumes.");
4545 ("part_del", (RErr, [Device "device"; Int "partnum"]), 233, [],
4546 [InitEmpty, Always, TestRun (
4547 [["part_init"; "/dev/sda"; "mbr"];
4548 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4549 ["part_del"; "/dev/sda"; "1"]])],
4550 "delete a partition",
4552 This command deletes the partition numbered C<partnum> on C<device>.
4554 Note that in the case of MBR partitioning, deleting an
4555 extended partition also deletes any logical partitions
4558 ("part_get_bootable", (RBool "bootable", [Device "device"; Int "partnum"]), 234, [],
4559 [InitEmpty, Always, TestOutputTrue (
4560 [["part_init"; "/dev/sda"; "mbr"];
4561 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4562 ["part_set_bootable"; "/dev/sda"; "1"; "true"];
4563 ["part_get_bootable"; "/dev/sda"; "1"]])],
4564 "return true if a partition is bootable",
4566 This command returns true if the partition C<partnum> on
4567 C<device> has the bootable flag set.
4569 See also C<guestfs_part_set_bootable>.");
4571 ("part_get_mbr_id", (RInt "idbyte", [Device "device"; Int "partnum"]), 235, [FishOutput FishOutputHexadecimal],
4572 [InitEmpty, Always, TestOutputInt (
4573 [["part_init"; "/dev/sda"; "mbr"];
4574 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4575 ["part_set_mbr_id"; "/dev/sda"; "1"; "0x7f"];
4576 ["part_get_mbr_id"; "/dev/sda"; "1"]], 0x7f)],
4577 "get the MBR type byte (ID byte) from a partition",
4579 Returns the MBR type byte (also known as the ID byte) from
4580 the numbered partition C<partnum>.
4582 Note that only MBR (old DOS-style) partitions have type bytes.
4583 You will get undefined results for other partition table
4584 types (see C<guestfs_part_get_parttype>).");
4586 ("part_set_mbr_id", (RErr, [Device "device"; Int "partnum"; Int "idbyte"]), 236, [],
4587 [], (* tested by part_get_mbr_id *)
4588 "set the MBR type byte (ID byte) of a partition",
4590 Sets the MBR type byte (also known as the ID byte) of
4591 the numbered partition C<partnum> to C<idbyte>. Note
4592 that the type bytes quoted in most documentation are
4593 in fact hexadecimal numbers, but usually documented
4594 without any leading \"0x\" which might be confusing.
4596 Note that only MBR (old DOS-style) partitions have type bytes.
4597 You will get undefined results for other partition table
4598 types (see C<guestfs_part_get_parttype>).");
4600 ("checksum_device", (RString "checksum", [String "csumtype"; Device "device"]), 237, [],
4601 [InitISOFS, Always, TestOutput (
4602 [["checksum_device"; "md5"; "/dev/sdd"]],
4603 (Digest.to_hex (Digest.file "images/test.iso")))],
4604 "compute MD5, SHAx or CRC checksum of the contents of a device",
4606 This call computes the MD5, SHAx or CRC checksum of the
4607 contents of the device named C<device>. For the types of
4608 checksums supported see the C<guestfs_checksum> command.");
4610 ("lvresize_free", (RErr, [Device "lv"; Int "percent"]), 238, [Optional "lvm2"],
4611 [InitNone, Always, TestRun (
4612 [["part_disk"; "/dev/sda"; "mbr"];
4613 ["pvcreate"; "/dev/sda1"];
4614 ["vgcreate"; "VG"; "/dev/sda1"];
4615 ["lvcreate"; "LV"; "VG"; "10"];
4616 ["lvresize_free"; "/dev/VG/LV"; "100"]])],
4617 "expand an LV to fill free space",
4619 This expands an existing logical volume C<lv> so that it fills
4620 C<pc>% of the remaining free space in the volume group. Commonly
4621 you would call this with pc = 100 which expands the logical volume
4622 as much as possible, using all remaining free space in the volume
4625 ("aug_clear", (RErr, [String "augpath"]), 239, [Optional "augeas"],
4626 [], (* XXX Augeas code needs tests. *)
4627 "clear Augeas path",
4629 Set the value associated with C<path> to C<NULL>. This
4630 is the same as the L<augtool(1)> C<clear> command.");
4632 ("get_umask", (RInt "mask", []), 240, [FishOutput FishOutputOctal],
4633 [InitEmpty, Always, TestOutputInt (
4634 [["get_umask"]], 0o22)],
4635 "get the current umask",
4637 Return the current umask. By default the umask is C<022>
4638 unless it has been set by calling C<guestfs_umask>.");
4640 ("debug_upload", (RErr, [FileIn "filename"; String "tmpname"; Int "mode"]), 241, [],
4642 "upload a file to the appliance (internal use only)",
4644 The C<guestfs_debug_upload> command uploads a file to
4645 the libguestfs appliance.
4647 There is no comprehensive help for this command. You have
4648 to look at the file C<daemon/debug.c> in the libguestfs source
4649 to find out what it is for.");
4651 ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
4652 [InitBasicFS, Always, TestOutput (
4653 [["base64_in"; "../images/hello.b64"; "/hello"];
4654 ["cat"; "/hello"]], "hello\n")],
4655 "upload base64-encoded data to file",
4657 This command uploads base64-encoded data from C<base64file>
4660 ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
4662 "download file and encode as base64",
4664 This command downloads the contents of C<filename>, writing
4665 it out to local file C<base64file> encoded as base64.");
4667 ("checksums_out", (RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"]), 244, [],
4669 "compute MD5, SHAx or CRC checksum of files in a directory",
4671 This command computes the checksums of all regular files in
4672 C<directory> and then emits a list of those checksums to
4673 the local output file C<sumsfile>.
4675 This can be used for verifying the integrity of a virtual
4676 machine. However to be properly secure you should pay
4677 attention to the output of the checksum command (it uses
4678 the ones from GNU coreutils). In particular when the
4679 filename is not printable, coreutils uses a special
4680 backslash syntax. For more information, see the GNU
4681 coreutils info file.");
4683 ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
4684 [InitBasicFS, Always, TestOutputBuffer (
4685 [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
4686 ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
4687 "fill a file with a repeating pattern of bytes",
4689 This function is like C<guestfs_fill> except that it creates
4690 a new file of length C<len> containing the repeating pattern
4691 of bytes in C<pattern>. The pattern is truncated if necessary
4692 to ensure the length of the file is exactly C<len> bytes.");
4694 ("write", (RErr, [Pathname "path"; BufferIn "content"]), 246, [ProtocolLimitWarning],
4695 [InitBasicFS, Always, TestOutput (
4696 [["write"; "/new"; "new file contents"];
4697 ["cat"; "/new"]], "new file contents");
4698 InitBasicFS, Always, TestOutput (
4699 [["write"; "/new"; "\nnew file contents\n"];
4700 ["cat"; "/new"]], "\nnew file contents\n");
4701 InitBasicFS, Always, TestOutput (
4702 [["write"; "/new"; "\n\n"];
4703 ["cat"; "/new"]], "\n\n");
4704 InitBasicFS, Always, TestOutput (
4705 [["write"; "/new"; ""];
4706 ["cat"; "/new"]], "");
4707 InitBasicFS, Always, TestOutput (
4708 [["write"; "/new"; "\n\n\n"];
4709 ["cat"; "/new"]], "\n\n\n");
4710 InitBasicFS, Always, TestOutput (
4711 [["write"; "/new"; "\n"];
4712 ["cat"; "/new"]], "\n")],
4713 "create a new file",
4715 This call creates a file called C<path>. The content of the
4716 file is the string C<content> (which can contain any 8 bit data).");
4718 ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
4719 [InitBasicFS, Always, TestOutput (
4720 [["write"; "/new"; "new file contents"];
4721 ["pwrite"; "/new"; "data"; "4"];
4722 ["cat"; "/new"]], "new data contents");
4723 InitBasicFS, Always, TestOutput (
4724 [["write"; "/new"; "new file contents"];
4725 ["pwrite"; "/new"; "is extended"; "9"];
4726 ["cat"; "/new"]], "new file is extended");
4727 InitBasicFS, Always, TestOutput (
4728 [["write"; "/new"; "new file contents"];
4729 ["pwrite"; "/new"; ""; "4"];
4730 ["cat"; "/new"]], "new file contents")],
4731 "write to part of a file",
4733 This command writes to part of a file. It writes the data
4734 buffer C<content> to the file C<path> starting at offset C<offset>.
4736 This command implements the L<pwrite(2)> system call, and like
4737 that system call it may not write the full data requested. The
4738 return value is the number of bytes that were actually written
4739 to the file. This could even be 0, although short writes are
4740 unlikely for regular files in ordinary circumstances.
4742 See also C<guestfs_pread>.");
4744 ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [],
4746 "resize an ext2, ext3 or ext4 filesystem (with size)",
4748 This command is the same as C<guestfs_resize2fs> except that it
4749 allows you to specify the new size (in bytes) explicitly.");
4751 ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"],
4753 "resize an LVM physical volume (with size)",
4755 This command is the same as C<guestfs_pvresize> except that it
4756 allows you to specify the new size (in bytes) explicitly.");
4758 ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"],
4760 "resize an NTFS filesystem (with size)",
4762 This command is the same as C<guestfs_ntfsresize> except that it
4763 allows you to specify the new size (in bytes) explicitly.");
4765 ("available_all_groups", (RStringList "groups", []), 251, [],
4766 [InitNone, Always, TestRun [["available_all_groups"]]],
4767 "return a list of all optional groups",
4769 This command returns a list of all optional groups that this
4770 daemon knows about. Note this returns both supported and unsupported
4771 groups. To find out which ones the daemon can actually support
4772 you have to call C<guestfs_available> on each member of the
4775 See also C<guestfs_available> and L<guestfs(3)/AVAILABILITY>.");
4777 ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [],
4778 [InitBasicFS, Always, TestOutputStruct (
4779 [["fallocate64"; "/a"; "1000000"];
4780 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
4781 "preallocate a file in the guest filesystem",
4783 This command preallocates a file (containing zero bytes) named
4784 C<path> of size C<len> bytes. If the file exists already, it
4787 Note that this call allocates disk blocks for the file.
4788 To create a sparse file use C<guestfs_truncate_size> instead.
4790 The deprecated call C<guestfs_fallocate> does the same,
4791 but owing to an oversight it only allowed 30 bit lengths
4792 to be specified, effectively limiting the maximum size
4793 of files created through that call to 1GB.
4795 Do not confuse this with the guestfish-specific
4796 C<alloc> and C<sparse> commands which create
4797 a file in the host and attach it as a device.");
4799 ("vfs_label", (RString "label", [Device "device"]), 253, [],
4800 [InitBasicFS, Always, TestOutput (
4801 [["set_e2label"; "/dev/sda1"; "LTEST"];
4802 ["vfs_label"; "/dev/sda1"]], "LTEST")],
4803 "get the filesystem label",
4805 This returns the filesystem label of the filesystem on
4808 If the filesystem is unlabeled, this returns the empty string.");
4810 ("vfs_uuid", (RString "uuid", [Device "device"]), 254, [],
4811 (let uuid = uuidgen () in
4812 [InitBasicFS, Always, TestOutput (
4813 [["set_e2uuid"; "/dev/sda1"; uuid];
4814 ["vfs_uuid"; "/dev/sda1"]], uuid)]),
4815 "get the filesystem UUID",
4817 This returns the filesystem UUID of the filesystem on
4820 If the filesystem does not have a UUID, this returns the empty string.");
4824 let all_functions = non_daemon_functions @ daemon_functions
4826 (* In some places we want the functions to be displayed sorted
4827 * alphabetically, so this is useful:
4829 let all_functions_sorted =
4830 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4831 compare n1 n2) all_functions
4833 (* This is used to generate the src/MAX_PROC_NR file which
4834 * contains the maximum procedure number, a surrogate for the
4835 * ABI version number. See src/Makefile.am for the details.
4838 let proc_nrs = List.map (
4839 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
4840 ) daemon_functions in
4841 List.fold_left max 0 proc_nrs
4843 (* Field types for structures. *)
4845 | FChar (* C 'char' (really, a 7 bit byte). *)
4846 | FString (* nul-terminated ASCII string, NOT NULL. *)
4847 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4852 | FBytes (* Any int measure that counts bytes. *)
4853 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4854 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4856 (* Because we generate extra parsing code for LVM command line tools,
4857 * we have to pull out the LVM columns separately here.
4867 "pv_attr", FString (* XXX *);
4868 "pv_pe_count", FInt64;
4869 "pv_pe_alloc_count", FInt64;
4872 "pv_mda_count", FInt64;
4873 "pv_mda_free", FBytes;
4874 (* Not in Fedora 10:
4875 "pv_mda_size", FBytes;
4882 "vg_attr", FString (* XXX *);
4885 "vg_sysid", FString;
4886 "vg_extent_size", FBytes;
4887 "vg_extent_count", FInt64;
4888 "vg_free_count", FInt64;
4893 "snap_count", FInt64;
4896 "vg_mda_count", FInt64;
4897 "vg_mda_free", FBytes;
4898 (* Not in Fedora 10:
4899 "vg_mda_size", FBytes;
4905 "lv_attr", FString (* XXX *);
4908 "lv_kernel_major", FInt64;
4909 "lv_kernel_minor", FInt64;
4911 "seg_count", FInt64;
4913 "snap_percent", FOptPercent;
4914 "copy_percent", FOptPercent;
4917 "mirror_log", FString;
4921 (* Names and fields in all structures (in RStruct and RStructList)
4925 (* The old RIntBool return type, only ever used for aug_defnode. Do
4926 * not use this struct in any new code.
4929 "i", FInt32; (* for historical compatibility *)
4930 "b", FInt32; (* for historical compatibility *)
4933 (* LVM PVs, VGs, LVs. *)
4934 "lvm_pv", lvm_pv_cols;
4935 "lvm_vg", lvm_vg_cols;
4936 "lvm_lv", lvm_lv_cols;
4938 (* Column names and types from stat structures.
4939 * NB. Can't use things like 'st_atime' because glibc header files
4940 * define some of these as macros. Ugh.
4971 (* Column names in dirent structure. *)
4974 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4979 (* Version numbers. *)
4987 (* Extended attribute. *)
4989 "attrname", FString;
4993 (* Inotify events. *)
4997 "in_cookie", FUInt32;
5001 (* Partition table entry. *)
5004 "part_start", FBytes;
5006 "part_size", FBytes;
5008 ] (* end of structs *)
5010 (* Ugh, Java has to be different ..
5011 * These names are also used by the Haskell bindings.
5013 let java_structs = [
5014 "int_bool", "IntBool";
5019 "statvfs", "StatVFS";
5021 "version", "Version";
5023 "inotify_event", "INotifyEvent";
5024 "partition", "Partition";
5027 (* What structs are actually returned. *)
5028 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
5030 (* Returns a list of RStruct/RStructList structs that are returned
5031 * by any function. Each element of returned list is a pair:
5033 * (structname, RStructOnly)
5034 * == there exists function which returns RStruct (_, structname)
5035 * (structname, RStructListOnly)
5036 * == there exists function which returns RStructList (_, structname)
5037 * (structname, RStructAndList)
5038 * == there are functions returning both RStruct (_, structname)
5039 * and RStructList (_, structname)
5041 let rstructs_used_by functions =
5042 (* ||| is a "logical OR" for rstructs_used_t *)
5046 | _, RStructAndList -> RStructAndList
5047 | RStructOnly, RStructListOnly
5048 | RStructListOnly, RStructOnly -> RStructAndList
5049 | RStructOnly, RStructOnly -> RStructOnly
5050 | RStructListOnly, RStructListOnly -> RStructListOnly
5053 let h = Hashtbl.create 13 in
5055 (* if elem->oldv exists, update entry using ||| operator,
5056 * else just add elem->newv to the hash
5058 let update elem newv =
5059 try let oldv = Hashtbl.find h elem in
5060 Hashtbl.replace h elem (newv ||| oldv)
5061 with Not_found -> Hashtbl.add h elem newv
5065 fun (_, style, _, _, _, _, _) ->
5066 match fst style with
5067 | RStruct (_, structname) -> update structname RStructOnly
5068 | RStructList (_, structname) -> update structname RStructListOnly
5072 (* return key->values as a list of (key,value) *)
5073 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
5075 (* Used for testing language bindings. *)
5077 | CallString of string
5078 | CallOptString of string option
5079 | CallStringList of string list
5081 | CallInt64 of int64
5083 | CallBuffer of string
5085 (* Used to memoize the result of pod2text. *)
5086 let pod2text_memo_filename = "src/.pod2text.data"
5087 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
5089 let chan = open_in pod2text_memo_filename in
5090 let v = input_value chan in
5094 _ -> Hashtbl.create 13
5095 let pod2text_memo_updated () =
5096 let chan = open_out pod2text_memo_filename in
5097 output_value chan pod2text_memo;
5100 (* Useful functions.
5101 * Note we don't want to use any external OCaml libraries which
5102 * makes this a bit harder than it should be.
5104 module StringMap = Map.Make (String)
5106 let failwithf fs = ksprintf failwith fs
5108 let unique = let i = ref 0 in fun () -> incr i; !i
5110 let replace_char s c1 c2 =
5111 let s2 = String.copy s in
5112 let r = ref false in
5113 for i = 0 to String.length s2 - 1 do
5114 if String.unsafe_get s2 i = c1 then (
5115 String.unsafe_set s2 i c2;
5119 if not !r then s else s2
5123 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
5125 let triml ?(test = isspace) str =
5127 let n = ref (String.length str) in
5128 while !n > 0 && test str.[!i]; do
5133 else String.sub str !i !n
5135 let trimr ?(test = isspace) str =
5136 let n = ref (String.length str) in
5137 while !n > 0 && test str.[!n-1]; do
5140 if !n = String.length str then str
5141 else String.sub str 0 !n
5143 let trim ?(test = isspace) str =
5144 trimr ~test (triml ~test str)
5146 let rec find s sub =
5147 let len = String.length s in
5148 let sublen = String.length sub in
5150 if i <= len-sublen then (
5152 if j < sublen then (
5153 if s.[i+j] = sub.[j] then loop2 (j+1)
5159 if r = -1 then loop (i+1) else r
5165 let rec replace_str s s1 s2 =
5166 let len = String.length s in
5167 let sublen = String.length s1 in
5168 let i = find s s1 in
5171 let s' = String.sub s 0 i in
5172 let s'' = String.sub s (i+sublen) (len-i-sublen) in
5173 s' ^ s2 ^ replace_str s'' s1 s2
5176 let rec string_split sep str =
5177 let len = String.length str in
5178 let seplen = String.length sep in
5179 let i = find str sep in
5180 if i = -1 then [str]
5182 let s' = String.sub str 0 i in
5183 let s'' = String.sub str (i+seplen) (len-i-seplen) in
5184 s' :: string_split sep s''
5187 let files_equal n1 n2 =
5188 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
5189 match Sys.command cmd with
5192 | i -> failwithf "%s: failed with error code %d" cmd i
5194 let rec filter_map f = function
5198 | Some y -> y :: filter_map f xs
5199 | None -> filter_map f xs
5201 let rec find_map f = function
5202 | [] -> raise Not_found
5206 | None -> find_map f xs
5209 let rec loop i = function
5211 | x :: xs -> f i x; loop (i+1) xs
5216 let rec loop i = function
5218 | x :: xs -> let r = f i x in r :: loop (i+1) xs
5222 let count_chars c str =
5223 let count = ref 0 in
5224 for i = 0 to String.length str - 1 do
5225 if c = String.unsafe_get str i then incr count
5231 for i = 0 to String.length str - 1 do
5232 let c = String.unsafe_get str i in
5237 let map_chars f str =
5238 List.map f (explode str)
5240 let name_of_argt = function
5241 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
5242 | StringList n | DeviceList n | Bool n | Int n | Int64 n
5243 | FileIn n | FileOut n | BufferIn n -> n
5245 let java_name_of_struct typ =
5246 try List.assoc typ java_structs
5249 "java_name_of_struct: no java_structs entry corresponding to %s" typ
5251 let cols_of_struct typ =
5252 try List.assoc typ structs
5254 failwithf "cols_of_struct: unknown struct %s" typ
5256 let seq_of_test = function
5257 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
5258 | TestOutputListOfDevices (s, _)
5259 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
5260 | TestOutputTrue s | TestOutputFalse s
5261 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
5262 | TestOutputStruct (s, _)
5263 | TestLastFail s -> s
5265 (* Handling for function flags. *)
5266 let protocol_limit_warning =
5267 "Because of the message protocol, there is a transfer limit
5268 of somewhere between 2MB and 4MB. See L<guestfs(3)/PROTOCOL LIMITS>."
5270 let danger_will_robinson =
5271 "B<This command is dangerous. Without careful use you
5272 can easily destroy all your data>."
5274 let deprecation_notice flags =
5277 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
5279 sprintf "This function is deprecated.
5280 In new code, use the C<%s> call instead.
5282 Deprecated functions will not be removed from the API, but the
5283 fact that they are deprecated indicates that there are problems
5284 with correct use of these functions." alt in
5289 (* Create list of optional groups. *)
5291 let h = Hashtbl.create 13 in
5293 fun (name, _, _, flags, _, _, _) ->
5297 let names = try Hashtbl.find h group with Not_found -> [] in
5298 Hashtbl.replace h group (name :: names)
5302 let groups = Hashtbl.fold (fun k _ ks -> k :: ks) h [] in
5305 fun group -> group, List.sort compare (Hashtbl.find h group)
5307 List.sort (fun x y -> compare (fst x) (fst y)) groups
5309 (* Check function names etc. for consistency. *)
5310 let check_functions () =
5311 let contains_uppercase str =
5312 let len = String.length str in
5314 if i >= len then false
5317 if c >= 'A' && c <= 'Z' then true
5324 (* Check function names. *)
5326 fun (name, _, _, _, _, _, _) ->
5327 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
5328 failwithf "function name %s does not need 'guestfs' prefix" name;
5330 failwithf "function name is empty";
5331 if name.[0] < 'a' || name.[0] > 'z' then
5332 failwithf "function name %s must start with lowercase a-z" name;
5333 if String.contains name '-' then
5334 failwithf "function name %s should not contain '-', use '_' instead."
5338 (* Check function parameter/return names. *)
5340 fun (name, style, _, _, _, _, _) ->
5341 let check_arg_ret_name n =
5342 if contains_uppercase n then
5343 failwithf "%s param/ret %s should not contain uppercase chars"
5345 if String.contains n '-' || String.contains n '_' then
5346 failwithf "%s param/ret %s should not contain '-' or '_'"
5349 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;
5350 if n = "int" || n = "char" || n = "short" || n = "long" then
5351 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
5352 if n = "i" || n = "n" then
5353 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
5354 if n = "argv" || n = "args" then
5355 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
5357 (* List Haskell, OCaml and C keywords here.
5358 * http://www.haskell.org/haskellwiki/Keywords
5359 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
5360 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
5361 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
5362 * |perl -pe 's/(.+)/"$1";/'|fmt -70
5363 * Omitting _-containing words, since they're handled above.
5364 * Omitting the OCaml reserved word, "val", is ok,
5365 * and saves us from renaming several parameters.
5368 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
5369 "char"; "class"; "const"; "constraint"; "continue"; "data";
5370 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
5371 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
5372 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
5373 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
5374 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
5376 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
5377 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
5378 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
5379 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
5380 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
5381 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
5382 "volatile"; "when"; "where"; "while";
5384 if List.mem n reserved then
5385 failwithf "%s has param/ret using reserved word %s" name n;
5388 (match fst style with
5390 | RInt n | RInt64 n | RBool n
5391 | RConstString n | RConstOptString n | RString n
5392 | RStringList n | RStruct (n, _) | RStructList (n, _)
5393 | RHashtable n | RBufferOut n ->
5394 check_arg_ret_name n
5396 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
5399 (* Check short descriptions. *)
5401 fun (name, _, _, _, _, shortdesc, _) ->
5402 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
5403 failwithf "short description of %s should begin with lowercase." name;
5404 let c = shortdesc.[String.length shortdesc-1] in
5405 if c = '\n' || c = '.' then
5406 failwithf "short description of %s should not end with . or \\n." name
5409 (* Check long descriptions. *)
5411 fun (name, _, _, _, _, _, longdesc) ->
5412 if longdesc.[String.length longdesc-1] = '\n' then
5413 failwithf "long description of %s should not end with \\n." name
5416 (* Check proc_nrs. *)
5418 fun (name, _, proc_nr, _, _, _, _) ->
5419 if proc_nr <= 0 then
5420 failwithf "daemon function %s should have proc_nr > 0" name
5424 fun (name, _, proc_nr, _, _, _, _) ->
5425 if proc_nr <> -1 then
5426 failwithf "non-daemon function %s should have proc_nr -1" name
5427 ) non_daemon_functions;
5430 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
5433 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
5434 let rec loop = function
5437 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
5439 | (name1,nr1) :: (name2,nr2) :: _ ->
5440 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
5448 (* Ignore functions that have no tests. We generate a
5449 * warning when the user does 'make check' instead.
5451 | name, _, _, _, [], _, _ -> ()
5452 | name, _, _, _, tests, _, _ ->
5456 match seq_of_test test with
5458 failwithf "%s has a test containing an empty sequence" name
5459 | cmds -> List.map List.hd cmds
5461 let funcs = List.flatten funcs in
5463 let tested = List.mem name funcs in
5466 failwithf "function %s has tests but does not test itself" name
5469 (* 'pr' prints to the current output file. *)
5470 let chan = ref Pervasives.stdout
5475 let i = count_chars '\n' str in
5476 lines := !lines + i;
5477 output_string !chan str
5480 let copyright_years =
5481 let this_year = 1900 + (localtime (time ())).tm_year in
5482 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
5484 (* Generate a header block in a number of standard styles. *)
5485 type comment_style =
5486 CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
5487 type license = GPLv2plus | LGPLv2plus
5489 let generate_header ?(extra_inputs = []) comment license =
5490 let inputs = "src/generator.ml" :: extra_inputs in
5491 let c = match comment with
5492 | CStyle -> pr "/* "; " *"
5493 | CPlusPlusStyle -> pr "// "; "//"
5494 | HashStyle -> pr "# "; "#"
5495 | OCamlStyle -> pr "(* "; " *"
5496 | HaskellStyle -> pr "{- "; " " in
5497 pr "libguestfs generated file\n";
5498 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
5499 List.iter (pr "%s %s\n" c) inputs;
5500 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
5502 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
5506 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
5507 pr "%s it under the terms of the GNU General Public License as published by\n" c;
5508 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
5509 pr "%s (at your option) any later version.\n" c;
5511 pr "%s This program is distributed in the hope that it will be useful,\n" c;
5512 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5513 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
5514 pr "%s GNU General Public License for more details.\n" c;
5516 pr "%s You should have received a copy of the GNU General Public License along\n" c;
5517 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
5518 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
5521 pr "%s This library is free software; you can redistribute it and/or\n" c;
5522 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
5523 pr "%s License as published by the Free Software Foundation; either\n" c;
5524 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
5526 pr "%s This library is distributed in the hope that it will be useful,\n" c;
5527 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5528 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
5529 pr "%s Lesser General Public License for more details.\n" c;
5531 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
5532 pr "%s License along with this library; if not, write to the Free Software\n" c;
5533 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
5536 | CStyle -> pr " */\n"
5539 | OCamlStyle -> pr " *)\n"
5540 | HaskellStyle -> pr "-}\n"
5544 (* Start of main code generation functions below this line. *)
5546 (* Generate the pod documentation for the C API. *)
5547 let rec generate_actions_pod () =
5549 fun (shortname, style, _, flags, _, _, longdesc) ->
5550 if not (List.mem NotInDocs flags) then (
5551 let name = "guestfs_" ^ shortname in
5552 pr "=head2 %s\n\n" name;
5554 generate_prototype ~extern:false ~handle:"g" name style;
5556 pr "%s\n\n" longdesc;
5557 (match fst style with
5559 pr "This function returns 0 on success or -1 on error.\n\n"
5561 pr "On error this function returns -1.\n\n"
5563 pr "On error this function returns -1.\n\n"
5565 pr "This function returns a C truth value on success or -1 on error.\n\n"
5567 pr "This function returns a string, or NULL on error.
5568 The string is owned by the guest handle and must I<not> be freed.\n\n"
5569 | RConstOptString _ ->
5570 pr "This function returns a string which may be NULL.
5571 There is way to return an error from this function.
5572 The string is owned by the guest handle and must I<not> be freed.\n\n"
5574 pr "This function returns a string, or NULL on error.
5575 I<The caller must free the returned string after use>.\n\n"
5577 pr "This function returns a NULL-terminated array of strings
5578 (like L<environ(3)>), or NULL if there was an error.
5579 I<The caller must free the strings and the array after use>.\n\n"
5580 | RStruct (_, typ) ->
5581 pr "This function returns a C<struct guestfs_%s *>,
5582 or NULL if there was an error.
5583 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
5584 | RStructList (_, typ) ->
5585 pr "This function returns a C<struct guestfs_%s_list *>
5586 (see E<lt>guestfs-structs.hE<gt>),
5587 or NULL if there was an error.
5588 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
5590 pr "This function returns a NULL-terminated array of
5591 strings, or NULL if there was an error.
5592 The array of strings will always have length C<2n+1>, where
5593 C<n> keys and values alternate, followed by the trailing NULL entry.
5594 I<The caller must free the strings and the array after use>.\n\n"
5596 pr "This function returns a buffer, or NULL on error.
5597 The size of the returned buffer is written to C<*size_r>.
5598 I<The caller must free the returned buffer after use>.\n\n"
5600 if List.mem ProtocolLimitWarning flags then
5601 pr "%s\n\n" protocol_limit_warning;
5602 if List.mem DangerWillRobinson flags then
5603 pr "%s\n\n" danger_will_robinson;
5604 match deprecation_notice flags with
5606 | Some txt -> pr "%s\n\n" txt
5608 ) all_functions_sorted
5610 and generate_structs_pod () =
5611 (* Structs documentation. *)
5614 pr "=head2 guestfs_%s\n" typ;
5616 pr " struct guestfs_%s {\n" typ;
5619 | name, FChar -> pr " char %s;\n" name
5620 | name, FUInt32 -> pr " uint32_t %s;\n" name
5621 | name, FInt32 -> pr " int32_t %s;\n" name
5622 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5623 | name, FInt64 -> pr " int64_t %s;\n" name
5624 | name, FString -> pr " char *%s;\n" name
5626 pr " /* The next two fields describe a byte array. */\n";
5627 pr " uint32_t %s_len;\n" name;
5628 pr " char *%s;\n" name
5630 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
5631 pr " char %s[32];\n" name
5632 | name, FOptPercent ->
5633 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
5634 pr " float %s;\n" name
5638 pr " struct guestfs_%s_list {\n" typ;
5639 pr " uint32_t len; /* Number of elements in list. */\n";
5640 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
5643 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
5644 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
5649 and generate_availability_pod () =
5650 (* Availability documentation. *)
5654 fun (group, functions) ->
5655 pr "=item B<%s>\n" group;
5657 pr "The following functions:\n";
5658 List.iter (pr "L</guestfs_%s>\n") functions;
5664 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
5665 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
5667 * We have to use an underscore instead of a dash because otherwise
5668 * rpcgen generates incorrect code.
5670 * This header is NOT exported to clients, but see also generate_structs_h.
5672 and generate_xdr () =
5673 generate_header CStyle LGPLv2plus;
5675 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
5676 pr "typedef string str<>;\n";
5679 (* Internal structures. *)
5683 pr "struct guestfs_int_%s {\n" typ;
5685 | name, FChar -> pr " char %s;\n" name
5686 | name, FString -> pr " string %s<>;\n" name
5687 | name, FBuffer -> pr " opaque %s<>;\n" name
5688 | name, FUUID -> pr " opaque %s[32];\n" name
5689 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
5690 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
5691 | name, FOptPercent -> pr " float %s;\n" name
5695 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
5700 fun (shortname, style, _, _, _, _, _) ->
5701 let name = "guestfs_" ^ shortname in
5703 (match snd style with
5706 pr "struct %s_args {\n" name;
5709 | Pathname n | Device n | Dev_or_Path n | String n ->
5710 pr " string %s<>;\n" n
5711 | OptString n -> pr " str *%s;\n" n
5712 | StringList n | DeviceList n -> pr " str %s<>;\n" n
5713 | Bool n -> pr " bool %s;\n" n
5714 | Int n -> pr " int %s;\n" n
5715 | Int64 n -> pr " hyper %s;\n" n
5717 pr " opaque %s<>;\n" n
5718 | FileIn _ | FileOut _ -> ()
5722 (match fst style with
5725 pr "struct %s_ret {\n" name;
5729 pr "struct %s_ret {\n" name;
5730 pr " hyper %s;\n" n;
5733 pr "struct %s_ret {\n" name;
5736 | RConstString _ | RConstOptString _ ->
5737 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5739 pr "struct %s_ret {\n" name;
5740 pr " string %s<>;\n" n;
5743 pr "struct %s_ret {\n" name;
5744 pr " str %s<>;\n" n;
5746 | RStruct (n, typ) ->
5747 pr "struct %s_ret {\n" name;
5748 pr " guestfs_int_%s %s;\n" typ n;
5750 | RStructList (n, typ) ->
5751 pr "struct %s_ret {\n" name;
5752 pr " guestfs_int_%s_list %s;\n" typ n;
5755 pr "struct %s_ret {\n" name;
5756 pr " str %s<>;\n" n;
5759 pr "struct %s_ret {\n" name;
5760 pr " opaque %s<>;\n" n;
5765 (* Table of procedure numbers. *)
5766 pr "enum guestfs_procedure {\n";
5768 fun (shortname, _, proc_nr, _, _, _, _) ->
5769 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5771 pr " GUESTFS_PROC_NR_PROCS\n";
5775 (* Having to choose a maximum message size is annoying for several
5776 * reasons (it limits what we can do in the API), but it (a) makes
5777 * the protocol a lot simpler, and (b) provides a bound on the size
5778 * of the daemon which operates in limited memory space.
5780 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5783 (* Message header, etc. *)
5785 /* The communication protocol is now documented in the guestfs(3)
5789 const GUESTFS_PROGRAM = 0x2000F5F5;
5790 const GUESTFS_PROTOCOL_VERSION = 1;
5792 /* These constants must be larger than any possible message length. */
5793 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5794 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5796 enum guestfs_message_direction {
5797 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5798 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5801 enum guestfs_message_status {
5802 GUESTFS_STATUS_OK = 0,
5803 GUESTFS_STATUS_ERROR = 1
5806 const GUESTFS_ERROR_LEN = 256;
5808 struct guestfs_message_error {
5809 string error_message<GUESTFS_ERROR_LEN>;
5812 struct guestfs_message_header {
5813 unsigned prog; /* GUESTFS_PROGRAM */
5814 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5815 guestfs_procedure proc; /* GUESTFS_PROC_x */
5816 guestfs_message_direction direction;
5817 unsigned serial; /* message serial number */
5818 guestfs_message_status status;
5821 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5823 struct guestfs_chunk {
5824 int cancel; /* if non-zero, transfer is cancelled */
5825 /* data size is 0 bytes if the transfer has finished successfully */
5826 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5830 (* Generate the guestfs-structs.h file. *)
5831 and generate_structs_h () =
5832 generate_header CStyle LGPLv2plus;
5834 (* This is a public exported header file containing various
5835 * structures. The structures are carefully written to have
5836 * exactly the same in-memory format as the XDR structures that
5837 * we use on the wire to the daemon. The reason for creating
5838 * copies of these structures here is just so we don't have to
5839 * export the whole of guestfs_protocol.h (which includes much
5840 * unrelated and XDR-dependent stuff that we don't want to be
5841 * public, or required by clients).
5843 * To reiterate, we will pass these structures to and from the
5844 * client with a simple assignment or memcpy, so the format
5845 * must be identical to what rpcgen / the RFC defines.
5848 (* Public structures. *)
5851 pr "struct guestfs_%s {\n" typ;
5854 | name, FChar -> pr " char %s;\n" name
5855 | name, FString -> pr " char *%s;\n" name
5857 pr " uint32_t %s_len;\n" name;
5858 pr " char *%s;\n" name
5859 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5860 | name, FUInt32 -> pr " uint32_t %s;\n" name
5861 | name, FInt32 -> pr " int32_t %s;\n" name
5862 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5863 | name, FInt64 -> pr " int64_t %s;\n" name
5864 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5868 pr "struct guestfs_%s_list {\n" typ;
5869 pr " uint32_t len;\n";
5870 pr " struct guestfs_%s *val;\n" typ;
5873 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5874 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5878 (* Generate the guestfs-actions.h file. *)
5879 and generate_actions_h () =
5880 generate_header CStyle LGPLv2plus;
5882 fun (shortname, style, _, _, _, _, _) ->
5883 let name = "guestfs_" ^ shortname in
5884 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5888 (* Generate the guestfs-internal-actions.h file. *)
5889 and generate_internal_actions_h () =
5890 generate_header CStyle LGPLv2plus;
5892 fun (shortname, style, _, _, _, _, _) ->
5893 let name = "guestfs__" ^ shortname in
5894 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5896 ) non_daemon_functions
5898 (* Generate the client-side dispatch stubs. *)
5899 and generate_client_actions () =
5900 generate_header CStyle LGPLv2plus;
5907 #include <inttypes.h>
5909 #include \"guestfs.h\"
5910 #include \"guestfs-internal.h\"
5911 #include \"guestfs-internal-actions.h\"
5912 #include \"guestfs_protocol.h\"
5914 #define error guestfs_error
5915 //#define perrorf guestfs_perrorf
5916 #define safe_malloc guestfs_safe_malloc
5917 #define safe_realloc guestfs_safe_realloc
5918 //#define safe_strdup guestfs_safe_strdup
5919 #define safe_memdup guestfs_safe_memdup
5921 /* Check the return message from a call for validity. */
5923 check_reply_header (guestfs_h *g,
5924 const struct guestfs_message_header *hdr,
5925 unsigned int proc_nr, unsigned int serial)
5927 if (hdr->prog != GUESTFS_PROGRAM) {
5928 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5931 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5932 error (g, \"wrong protocol version (%%d/%%d)\",
5933 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5936 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5937 error (g, \"unexpected message direction (%%d/%%d)\",
5938 hdr->direction, GUESTFS_DIRECTION_REPLY);
5941 if (hdr->proc != proc_nr) {
5942 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5945 if (hdr->serial != serial) {
5946 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5953 /* Check we are in the right state to run a high-level action. */
5955 check_state (guestfs_h *g, const char *caller)
5957 if (!guestfs__is_ready (g)) {
5958 if (guestfs__is_config (g) || guestfs__is_launching (g))
5959 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5962 error (g, \"%%s called from the wrong state, %%d != READY\",
5963 caller, guestfs__get_state (g));
5971 let error_code_of = function
5972 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5973 | RConstString _ | RConstOptString _
5974 | RString _ | RStringList _
5975 | RStruct _ | RStructList _
5976 | RHashtable _ | RBufferOut _ -> "NULL"
5979 (* Generate code to check String-like parameters are not passed in
5980 * as NULL (returning an error if they are).
5982 let check_null_strings shortname style =
5983 let pr_newline = ref false in
5986 (* parameters which should not be NULL *)
5996 pr " if (%s == NULL) {\n" n;
5997 pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
5998 pr " \"%s\", \"%s\");\n" shortname n;
5999 pr " return %s;\n" (error_code_of (fst style));
6006 (* not applicable *)
6012 if !pr_newline then pr "\n";
6015 (* Generate code to generate guestfish call traces. *)
6016 let trace_call shortname style =
6017 pr " if (guestfs__get_trace (g)) {\n";
6020 List.exists (function
6021 | StringList _ | DeviceList _ -> true
6022 | _ -> false) (snd style) in
6028 pr " printf (\"%s\");\n" shortname;
6031 | String n (* strings *)
6038 (* guestfish doesn't support string escaping, so neither do we *)
6039 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
6040 | OptString n -> (* string option *)
6041 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
6042 pr " else printf (\" null\");\n"
6044 | DeviceList n -> (* string list *)
6045 pr " putchar (' ');\n";
6046 pr " putchar ('\"');\n";
6047 pr " for (i = 0; %s[i]; ++i) {\n" n;
6048 pr " if (i > 0) putchar (' ');\n";
6049 pr " fputs (%s[i], stdout);\n" n;
6051 pr " putchar ('\"');\n";
6052 | Bool n -> (* boolean *)
6053 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
6054 | Int n -> (* int *)
6055 pr " printf (\" %%d\", %s);\n" n
6057 pr " printf (\" %%\" PRIi64, %s);\n" n
6059 pr " putchar ('\\n');\n";
6064 (* For non-daemon functions, generate a wrapper around each function. *)
6066 fun (shortname, style, _, _, _, _, _) ->
6067 let name = "guestfs_" ^ shortname in
6069 generate_prototype ~extern:false ~semicolon:false ~newline:true
6070 ~handle:"g" name style;
6072 check_null_strings shortname style;
6073 trace_call shortname style;
6074 pr " return guestfs__%s " shortname;
6075 generate_c_call_args ~handle:"g" style;
6079 ) non_daemon_functions;
6081 (* Client-side stubs for each function. *)
6083 fun (shortname, style, _, _, _, _, _) ->
6084 let name = "guestfs_" ^ shortname in
6085 let error_code = error_code_of (fst style) in
6087 (* Generate the action stub. *)
6088 generate_prototype ~extern:false ~semicolon:false ~newline:true
6089 ~handle:"g" name style;
6093 (match snd style with
6095 | _ -> pr " struct %s_args args;\n" name
6098 pr " guestfs_message_header hdr;\n";
6099 pr " guestfs_message_error err;\n";
6101 match fst style with
6103 | RConstString _ | RConstOptString _ ->
6104 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6106 | RBool _ | RString _ | RStringList _
6107 | RStruct _ | RStructList _
6108 | RHashtable _ | RBufferOut _ ->
6109 pr " struct %s_ret ret;\n" name;
6112 pr " int serial;\n";
6115 check_null_strings shortname style;
6116 trace_call shortname style;
6117 pr " if (check_state (g, \"%s\") == -1) return %s;\n"
6118 shortname error_code;
6119 pr " guestfs___set_busy (g);\n";
6122 (* Send the main header and arguments. *)
6123 (match snd style with
6125 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
6126 (String.uppercase shortname)
6130 | Pathname n | Device n | Dev_or_Path n | String n ->
6131 pr " args.%s = (char *) %s;\n" n n
6133 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
6134 | StringList n | DeviceList n ->
6135 pr " args.%s.%s_val = (char **) %s;\n" n n n;
6136 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
6138 pr " args.%s = %s;\n" n n
6140 pr " args.%s = %s;\n" n n
6142 pr " args.%s = %s;\n" n n
6143 | FileIn _ | FileOut _ -> ()
6145 pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
6146 pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
6147 pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
6149 pr " guestfs___end_busy (g);\n";
6150 pr " return %s;\n" error_code;
6152 pr " args.%s.%s_val = (char *) %s;\n" n n n;
6153 pr " args.%s.%s_len = %s_size;\n" n n n
6155 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
6156 (String.uppercase shortname);
6157 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
6160 pr " if (serial == -1) {\n";
6161 pr " guestfs___end_busy (g);\n";
6162 pr " return %s;\n" error_code;
6166 (* Send any additional files (FileIn) requested. *)
6167 let need_read_reply_label = ref false in
6171 pr " r = guestfs___send_file (g, %s);\n" n;
6172 pr " if (r == -1) {\n";
6173 pr " guestfs___end_busy (g);\n";
6174 pr " return %s;\n" error_code;
6176 pr " if (r == -2) /* daemon cancelled */\n";
6177 pr " goto read_reply;\n";
6178 need_read_reply_label := true;
6183 (* Wait for the reply from the remote end. *)
6184 if !need_read_reply_label then pr " read_reply:\n";
6185 pr " memset (&hdr, 0, sizeof hdr);\n";
6186 pr " memset (&err, 0, sizeof err);\n";
6187 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
6189 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
6193 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
6196 pr " if (r == -1) {\n";
6197 pr " guestfs___end_busy (g);\n";
6198 pr " return %s;\n" error_code;
6202 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
6203 (String.uppercase shortname);
6204 pr " guestfs___end_busy (g);\n";
6205 pr " return %s;\n" error_code;
6209 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
6210 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
6211 pr " free (err.error_message);\n";
6212 pr " guestfs___end_busy (g);\n";
6213 pr " return %s;\n" error_code;
6217 (* Expecting to receive further files (FileOut)? *)
6221 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
6222 pr " guestfs___end_busy (g);\n";
6223 pr " return %s;\n" error_code;
6229 pr " guestfs___end_busy (g);\n";
6231 (match fst style with
6232 | RErr -> pr " return 0;\n"
6233 | RInt n | RInt64 n | RBool n ->
6234 pr " return ret.%s;\n" n
6235 | RConstString _ | RConstOptString _ ->
6236 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6238 pr " return ret.%s; /* caller will free */\n" n
6239 | RStringList n | RHashtable n ->
6240 pr " /* caller will free this, but we need to add a NULL entry */\n";
6241 pr " ret.%s.%s_val =\n" n n;
6242 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
6243 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
6245 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
6246 pr " return ret.%s.%s_val;\n" n n
6248 pr " /* caller will free this */\n";
6249 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6250 | RStructList (n, _) ->
6251 pr " /* caller will free this */\n";
6252 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6254 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
6255 pr " * _val might be NULL here. To make the API saner for\n";
6256 pr " * callers, we turn this case into a unique pointer (using\n";
6257 pr " * malloc(1)).\n";
6259 pr " if (ret.%s.%s_len > 0) {\n" n n;
6260 pr " *size_r = ret.%s.%s_len;\n" n n;
6261 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
6263 pr " free (ret.%s.%s_val);\n" n n;
6264 pr " char *p = safe_malloc (g, 1);\n";
6265 pr " *size_r = ret.%s.%s_len;\n" n n;
6273 (* Functions to free structures. *)
6274 pr "/* Structure-freeing functions. These rely on the fact that the\n";
6275 pr " * structure format is identical to the XDR format. See note in\n";
6276 pr " * generator.ml.\n";
6283 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
6285 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
6291 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
6293 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
6300 (* Generate daemon/actions.h. *)
6301 and generate_daemon_actions_h () =
6302 generate_header CStyle GPLv2plus;
6304 pr "#include \"../src/guestfs_protocol.h\"\n";
6308 fun (name, style, _, _, _, _, _) ->
6310 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
6314 (* Generate the linker script which controls the visibility of
6315 * symbols in the public ABI and ensures no other symbols get
6316 * exported accidentally.
6318 and generate_linker_script () =
6319 generate_header HashStyle GPLv2plus;
6324 "guestfs_get_error_handler";
6325 "guestfs_get_out_of_memory_handler";
6326 "guestfs_last_error";
6327 "guestfs_set_error_handler";
6328 "guestfs_set_launch_done_callback";
6329 "guestfs_set_log_message_callback";
6330 "guestfs_set_out_of_memory_handler";
6331 "guestfs_set_subprocess_quit_callback";
6333 (* Unofficial parts of the API: the bindings code use these
6334 * functions, so it is useful to export them.
6336 "guestfs_safe_calloc";
6337 "guestfs_safe_malloc";
6340 List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
6344 List.map (fun (typ, _) ->
6345 ["guestfs_free_" ^ typ; "guestfs_free_" ^ typ ^ "_list"])
6348 let globals = List.sort compare (globals @ functions @ structs) in
6352 List.iter (pr " %s;\n") globals;
6359 (* Generate the server-side stubs. *)
6360 and generate_daemon_actions () =
6361 generate_header CStyle GPLv2plus;
6363 pr "#include <config.h>\n";
6365 pr "#include <stdio.h>\n";
6366 pr "#include <stdlib.h>\n";
6367 pr "#include <string.h>\n";
6368 pr "#include <inttypes.h>\n";
6369 pr "#include <rpc/types.h>\n";
6370 pr "#include <rpc/xdr.h>\n";
6372 pr "#include \"daemon.h\"\n";
6373 pr "#include \"c-ctype.h\"\n";
6374 pr "#include \"../src/guestfs_protocol.h\"\n";
6375 pr "#include \"actions.h\"\n";
6379 fun (name, style, _, _, _, _, _) ->
6380 (* Generate server-side stubs. *)
6381 pr "static void %s_stub (XDR *xdr_in)\n" name;
6384 match fst style with
6385 | RErr | RInt _ -> pr " int r;\n"; "-1"
6386 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6387 | RBool _ -> pr " int r;\n"; "-1"
6388 | RConstString _ | RConstOptString _ ->
6389 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6390 | RString _ -> pr " char *r;\n"; "NULL"
6391 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
6392 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
6393 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
6395 pr " size_t size = 1;\n";
6399 (match snd style with
6402 pr " struct guestfs_%s_args args;\n" name;
6405 | Device n | Dev_or_Path n
6408 | OptString n -> pr " char *%s;\n" n
6409 | StringList n | DeviceList n -> pr " char **%s;\n" n
6410 | Bool n -> pr " int %s;\n" n
6411 | Int n -> pr " int %s;\n" n
6412 | Int64 n -> pr " int64_t %s;\n" n
6413 | FileIn _ | FileOut _ -> ()
6415 pr " const char *%s;\n" n;
6416 pr " size_t %s_size;\n" n
6422 List.exists (function FileIn _ -> true | _ -> false) (snd style) in
6424 (match snd style with
6427 pr " memset (&args, 0, sizeof args);\n";
6429 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
6431 pr " if (cancel_receive () != -2)\n";
6432 pr " reply_with_error (\"daemon failed to decode procedure arguments\");\n";
6436 pr " char *%s = args.%s;\n" n n
6438 let pr_list_handling_code n =
6439 pr " %s = realloc (args.%s.%s_val,\n" n n n;
6440 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
6441 pr " if (%s == NULL) {\n" n;
6443 pr " if (cancel_receive () != -2)\n";
6444 pr " reply_with_perror (\"realloc\");\n";
6447 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
6448 pr " args.%s.%s_val = %s;\n" n n n;
6454 pr " ABS_PATH (%s, %s, goto done);\n"
6455 n (if is_filein then "cancel_receive ()" else "0");
6458 pr " RESOLVE_DEVICE (%s, %s, goto done);\n"
6459 n (if is_filein then "cancel_receive ()" else "0");
6462 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
6463 n (if is_filein then "cancel_receive ()" else "0");
6464 | String n -> pr_args n
6465 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
6467 pr_list_handling_code n;
6469 pr_list_handling_code n;
6470 pr " /* Ensure that each is a device,\n";
6471 pr " * and perform device name translation. */\n";
6472 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
6473 pr " RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
6474 (if is_filein then "cancel_receive ()" else "0");
6476 | Bool n -> pr " %s = args.%s;\n" n n
6477 | Int n -> pr " %s = args.%s;\n" n n
6478 | Int64 n -> pr " %s = args.%s;\n" n n
6479 | FileIn _ | FileOut _ -> ()
6481 pr " %s = args.%s.%s_val;\n" n n n;
6482 pr " %s_size = args.%s.%s_len;\n" n n n
6487 (* this is used at least for do_equal *)
6488 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
6489 (* Emit NEED_ROOT just once, even when there are two or
6490 more Pathname args *)
6491 pr " NEED_ROOT (%s, goto done);\n"
6492 (if is_filein then "cancel_receive ()" else "0");
6495 (* Don't want to call the impl with any FileIn or FileOut
6496 * parameters, since these go "outside" the RPC protocol.
6499 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
6501 pr " r = do_%s " name;
6502 generate_c_call_args (fst style, args');
6505 (match fst style with
6506 | RErr | RInt _ | RInt64 _ | RBool _
6507 | RConstString _ | RConstOptString _
6508 | RString _ | RStringList _ | RHashtable _
6509 | RStruct (_, _) | RStructList (_, _) ->
6510 pr " if (r == %s)\n" error_code;
6511 pr " /* do_%s has already called reply_with_error */\n" name;
6515 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
6516 pr " * an ordinary zero-length buffer), so be careful ...\n";
6518 pr " if (size == 1 && r == %s)\n" error_code;
6519 pr " /* do_%s has already called reply_with_error */\n" name;
6524 (* If there are any FileOut parameters, then the impl must
6525 * send its own reply.
6528 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
6530 pr " /* do_%s has already sent a reply */\n" name
6532 match fst style with
6533 | RErr -> pr " reply (NULL, NULL);\n"
6534 | RInt n | RInt64 n | RBool n ->
6535 pr " struct guestfs_%s_ret ret;\n" name;
6536 pr " ret.%s = r;\n" n;
6537 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6539 | RConstString _ | RConstOptString _ ->
6540 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6542 pr " struct guestfs_%s_ret ret;\n" name;
6543 pr " ret.%s = r;\n" n;
6544 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6547 | RStringList n | RHashtable n ->
6548 pr " struct guestfs_%s_ret ret;\n" name;
6549 pr " ret.%s.%s_len = count_strings (r);\n" n n;
6550 pr " ret.%s.%s_val = r;\n" n n;
6551 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6553 pr " free_strings (r);\n"
6555 pr " struct guestfs_%s_ret ret;\n" name;
6556 pr " ret.%s = *r;\n" n;
6557 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6559 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6561 | RStructList (n, _) ->
6562 pr " struct guestfs_%s_ret ret;\n" name;
6563 pr " ret.%s = *r;\n" n;
6564 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6566 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6569 pr " struct guestfs_%s_ret ret;\n" name;
6570 pr " ret.%s.%s_val = r;\n" n n;
6571 pr " ret.%s.%s_len = size;\n" n n;
6572 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6577 (* Free the args. *)
6579 (match snd style with
6582 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
6589 (* Dispatch function. *)
6590 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
6592 pr " switch (proc_nr) {\n";
6595 fun (name, style, _, _, _, _, _) ->
6596 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
6597 pr " %s_stub (xdr_in);\n" name;
6602 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";
6607 (* LVM columns and tokenization functions. *)
6608 (* XXX This generates crap code. We should rethink how we
6614 pr "static const char *lvm_%s_cols = \"%s\";\n"
6615 typ (String.concat "," (List.map fst cols));
6618 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
6620 pr " char *tok, *p, *next;\n";
6624 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
6627 pr " if (!str) {\n";
6628 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
6631 pr " if (!*str || c_isspace (*str)) {\n";
6632 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
6637 fun (name, coltype) ->
6638 pr " if (!tok) {\n";
6639 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
6642 pr " p = strchrnul (tok, ',');\n";
6643 pr " if (*p) next = p+1; else next = NULL;\n";
6644 pr " *p = '\\0';\n";
6647 pr " r->%s = strdup (tok);\n" name;
6648 pr " if (r->%s == NULL) {\n" name;
6649 pr " perror (\"strdup\");\n";
6653 pr " for (i = j = 0; i < 32; ++j) {\n";
6654 pr " if (tok[j] == '\\0') {\n";
6655 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
6657 pr " } else if (tok[j] != '-')\n";
6658 pr " r->%s[i++] = tok[j];\n" name;
6661 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
6662 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6666 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
6667 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6671 pr " if (tok[0] == '\\0')\n";
6672 pr " r->%s = -1;\n" name;
6673 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
6674 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6677 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
6678 assert false (* can never be an LVM column *)
6680 pr " tok = next;\n";
6683 pr " if (tok != NULL) {\n";
6684 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
6691 pr "guestfs_int_lvm_%s_list *\n" typ;
6692 pr "parse_command_line_%ss (void)\n" typ;
6694 pr " char *out, *err;\n";
6695 pr " char *p, *pend;\n";
6697 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
6698 pr " void *newp;\n";
6700 pr " ret = malloc (sizeof *ret);\n";
6701 pr " if (!ret) {\n";
6702 pr " reply_with_perror (\"malloc\");\n";
6703 pr " return NULL;\n";
6706 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
6707 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
6709 pr " r = command (&out, &err,\n";
6710 pr " \"lvm\", \"%ss\",\n" typ;
6711 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
6712 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
6713 pr " if (r == -1) {\n";
6714 pr " reply_with_error (\"%%s\", err);\n";
6715 pr " free (out);\n";
6716 pr " free (err);\n";
6717 pr " free (ret);\n";
6718 pr " return NULL;\n";
6721 pr " free (err);\n";
6723 pr " /* Tokenize each line of the output. */\n";
6726 pr " while (p) {\n";
6727 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
6728 pr " if (pend) {\n";
6729 pr " *pend = '\\0';\n";
6733 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
6736 pr " if (!*p) { /* Empty line? Skip it. */\n";
6741 pr " /* Allocate some space to store this next entry. */\n";
6742 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
6743 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
6744 pr " if (newp == NULL) {\n";
6745 pr " reply_with_perror (\"realloc\");\n";
6746 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6747 pr " free (ret);\n";
6748 pr " free (out);\n";
6749 pr " return NULL;\n";
6751 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
6753 pr " /* Tokenize the next entry. */\n";
6754 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
6755 pr " if (r == -1) {\n";
6756 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
6757 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6758 pr " free (ret);\n";
6759 pr " free (out);\n";
6760 pr " return NULL;\n";
6767 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
6769 pr " free (out);\n";
6770 pr " return ret;\n";
6773 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
6775 (* Generate a list of function names, for debugging in the daemon.. *)
6776 and generate_daemon_names () =
6777 generate_header CStyle GPLv2plus;
6779 pr "#include <config.h>\n";
6781 pr "#include \"daemon.h\"\n";
6784 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
6785 pr "const char *function_names[] = {\n";
6787 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
6791 (* Generate the optional groups for the daemon to implement
6792 * guestfs_available.
6794 and generate_daemon_optgroups_c () =
6795 generate_header CStyle GPLv2plus;
6797 pr "#include <config.h>\n";
6799 pr "#include \"daemon.h\"\n";
6800 pr "#include \"optgroups.h\"\n";
6803 pr "struct optgroup optgroups[] = {\n";
6806 pr " { \"%s\", optgroup_%s_available },\n" group group
6808 pr " { NULL, NULL }\n";
6811 and generate_daemon_optgroups_h () =
6812 generate_header CStyle GPLv2plus;
6816 pr "extern int optgroup_%s_available (void);\n" group
6819 (* Generate the tests. *)
6820 and generate_tests () =
6821 generate_header CStyle GPLv2plus;
6828 #include <sys/types.h>
6831 #include \"guestfs.h\"
6832 #include \"guestfs-internal.h\"
6834 static guestfs_h *g;
6835 static int suppress_error = 0;
6837 static void print_error (guestfs_h *g, void *data, const char *msg)
6839 if (!suppress_error)
6840 fprintf (stderr, \"%%s\\n\", msg);
6843 /* FIXME: nearly identical code appears in fish.c */
6844 static void print_strings (char *const *argv)
6848 for (argc = 0; argv[argc] != NULL; ++argc)
6849 printf (\"\\t%%s\\n\", argv[argc]);
6853 static void print_table (char const *const *argv)
6857 for (i = 0; argv[i] != NULL; i += 2)
6858 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
6863 is_available (const char *group)
6865 const char *groups[] = { group, NULL };
6869 r = guestfs_available (g, (char **) groups);
6877 (* Generate a list of commands which are not tested anywhere. *)
6878 pr "static void no_test_warnings (void)\n";
6881 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
6883 fun (_, _, _, _, tests, _, _) ->
6884 let tests = filter_map (
6886 | (_, (Always|If _|Unless _|IfAvailable _), test) -> Some test
6887 | (_, Disabled, _) -> None
6889 let seq = List.concat (List.map seq_of_test tests) in
6890 let cmds_tested = List.map List.hd seq in
6891 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6895 fun (name, _, _, _, _, _, _) ->
6896 if not (Hashtbl.mem hash name) then
6897 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6903 (* Generate the actual tests. Note that we generate the tests
6904 * in reverse order, deliberately, so that (in general) the
6905 * newest tests run first. This makes it quicker and easier to
6910 fun (name, _, _, flags, tests, _, _) ->
6911 mapi (generate_one_test name flags) tests
6912 ) (List.rev all_functions) in
6913 let test_names = List.concat test_names in
6914 let nr_tests = List.length test_names in
6917 int main (int argc, char *argv[])
6920 unsigned long int n_failed = 0;
6921 const char *filename;
6923 int nr_tests, test_num = 0;
6925 setbuf (stdout, NULL);
6927 no_test_warnings ();
6929 g = guestfs_create ();
6931 printf (\"guestfs_create FAILED\\n\");
6932 exit (EXIT_FAILURE);
6935 guestfs_set_error_handler (g, print_error, NULL);
6937 guestfs_set_path (g, \"../appliance\");
6939 filename = \"test1.img\";
6940 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6943 exit (EXIT_FAILURE);
6945 if (lseek (fd, %d, SEEK_SET) == -1) {
6949 exit (EXIT_FAILURE);
6951 if (write (fd, &c, 1) == -1) {
6955 exit (EXIT_FAILURE);
6957 if (close (fd) == -1) {
6960 exit (EXIT_FAILURE);
6962 if (guestfs_add_drive (g, filename) == -1) {
6963 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6964 exit (EXIT_FAILURE);
6967 filename = \"test2.img\";
6968 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6971 exit (EXIT_FAILURE);
6973 if (lseek (fd, %d, SEEK_SET) == -1) {
6977 exit (EXIT_FAILURE);
6979 if (write (fd, &c, 1) == -1) {
6983 exit (EXIT_FAILURE);
6985 if (close (fd) == -1) {
6988 exit (EXIT_FAILURE);
6990 if (guestfs_add_drive (g, filename) == -1) {
6991 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6992 exit (EXIT_FAILURE);
6995 filename = \"test3.img\";
6996 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6999 exit (EXIT_FAILURE);
7001 if (lseek (fd, %d, SEEK_SET) == -1) {
7005 exit (EXIT_FAILURE);
7007 if (write (fd, &c, 1) == -1) {
7011 exit (EXIT_FAILURE);
7013 if (close (fd) == -1) {
7016 exit (EXIT_FAILURE);
7018 if (guestfs_add_drive (g, filename) == -1) {
7019 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
7020 exit (EXIT_FAILURE);
7023 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
7024 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
7025 exit (EXIT_FAILURE);
7028 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
7031 if (guestfs_launch (g) == -1) {
7032 printf (\"guestfs_launch FAILED\\n\");
7033 exit (EXIT_FAILURE);
7036 /* Cancel previous alarm. */
7041 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
7045 pr " test_num++;\n";
7046 pr " if (guestfs_get_verbose (g))\n";
7047 pr " printf (\"-------------------------------------------------------------------------------\\n\");\n";
7048 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
7049 pr " if (%s () == -1) {\n" test_name;
7050 pr " printf (\"%s FAILED\\n\");\n" test_name;
7051 pr " n_failed++;\n";
7056 pr " guestfs_close (g);\n";
7057 pr " unlink (\"test1.img\");\n";
7058 pr " unlink (\"test2.img\");\n";
7059 pr " unlink (\"test3.img\");\n";
7062 pr " if (n_failed > 0) {\n";
7063 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
7064 pr " exit (EXIT_FAILURE);\n";
7068 pr " exit (EXIT_SUCCESS);\n";
7071 and generate_one_test name flags i (init, prereq, test) =
7072 let test_name = sprintf "test_%s_%d" name i in
7075 static int %s_skip (void)
7079 str = getenv (\"TEST_ONLY\");
7081 return strstr (str, \"%s\") == NULL;
7082 str = getenv (\"SKIP_%s\");
7083 if (str && STREQ (str, \"1\")) return 1;
7084 str = getenv (\"SKIP_TEST_%s\");
7085 if (str && STREQ (str, \"1\")) return 1;
7089 " test_name name (String.uppercase test_name) (String.uppercase name);
7092 | Disabled | Always | IfAvailable _ -> ()
7093 | If code | Unless code ->
7094 pr "static int %s_prereq (void)\n" test_name;
7102 static int %s (void)
7105 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
7109 " test_name test_name test_name;
7111 (* Optional functions should only be tested if the relevant
7112 * support is available in the daemon.
7117 pr " if (!is_available (\"%s\")) {\n" group;
7118 pr " printf (\" %%s skipped (reason: group %%s not available in daemon)\\n\", \"%s\", \"%s\");\n" test_name group;
7126 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
7128 pr " if (! %s_prereq ()) {\n" test_name;
7129 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7133 generate_one_test_body name i test_name init test;
7135 pr " if (%s_prereq ()) {\n" test_name;
7136 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7140 generate_one_test_body name i test_name init test;
7141 | IfAvailable group ->
7142 pr " if (!is_available (\"%s\")) {\n" group;
7143 pr " printf (\" %%s skipped (reason: %%s not available)\\n\", \"%s\", \"%s\");\n" test_name group;
7147 generate_one_test_body name i test_name init test;
7149 generate_one_test_body name i test_name init test
7157 and generate_one_test_body name i test_name init test =
7159 | InitNone (* XXX at some point, InitNone and InitEmpty became
7160 * folded together as the same thing. Really we should
7161 * make InitNone do nothing at all, but the tests may
7162 * need to be checked to make sure this is OK.
7165 pr " /* InitNone|InitEmpty for %s */\n" test_name;
7166 List.iter (generate_test_command_call test_name)
7167 [["blockdev_setrw"; "/dev/sda"];
7171 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
7172 List.iter (generate_test_command_call test_name)
7173 [["blockdev_setrw"; "/dev/sda"];
7176 ["part_disk"; "/dev/sda"; "mbr"]]
7178 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
7179 List.iter (generate_test_command_call test_name)
7180 [["blockdev_setrw"; "/dev/sda"];
7183 ["part_disk"; "/dev/sda"; "mbr"];
7184 ["mkfs"; "ext2"; "/dev/sda1"];
7185 ["mount_options"; ""; "/dev/sda1"; "/"]]
7186 | InitBasicFSonLVM ->
7187 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
7189 List.iter (generate_test_command_call test_name)
7190 [["blockdev_setrw"; "/dev/sda"];
7193 ["part_disk"; "/dev/sda"; "mbr"];
7194 ["pvcreate"; "/dev/sda1"];
7195 ["vgcreate"; "VG"; "/dev/sda1"];
7196 ["lvcreate"; "LV"; "VG"; "8"];
7197 ["mkfs"; "ext2"; "/dev/VG/LV"];
7198 ["mount_options"; ""; "/dev/VG/LV"; "/"]]
7200 pr " /* InitISOFS for %s */\n" test_name;
7201 List.iter (generate_test_command_call test_name)
7202 [["blockdev_setrw"; "/dev/sda"];
7205 ["mount_ro"; "/dev/sdd"; "/"]]
7208 let get_seq_last = function
7210 failwithf "%s: you cannot use [] (empty list) when expecting a command"
7213 let seq = List.rev seq in
7214 List.rev (List.tl seq), List.hd seq
7219 pr " /* TestRun for %s (%d) */\n" name i;
7220 List.iter (generate_test_command_call test_name) seq
7221 | TestOutput (seq, expected) ->
7222 pr " /* TestOutput for %s (%d) */\n" name i;
7223 pr " const char *expected = \"%s\";\n" (c_quote expected);
7224 let seq, last = get_seq_last seq in
7226 pr " if (STRNEQ (r, expected)) {\n";
7227 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7231 List.iter (generate_test_command_call test_name) seq;
7232 generate_test_command_call ~test test_name last
7233 | TestOutputList (seq, expected) ->
7234 pr " /* TestOutputList for %s (%d) */\n" name i;
7235 let seq, last = get_seq_last seq in
7239 pr " if (!r[%d]) {\n" i;
7240 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7241 pr " print_strings (r);\n";
7245 pr " const char *expected = \"%s\";\n" (c_quote str);
7246 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7247 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7252 pr " if (r[%d] != NULL) {\n" (List.length expected);
7253 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7255 pr " print_strings (r);\n";
7259 List.iter (generate_test_command_call test_name) seq;
7260 generate_test_command_call ~test test_name last
7261 | TestOutputListOfDevices (seq, expected) ->
7262 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
7263 let seq, last = get_seq_last seq in
7267 pr " if (!r[%d]) {\n" i;
7268 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7269 pr " print_strings (r);\n";
7273 pr " const char *expected = \"%s\";\n" (c_quote str);
7274 pr " r[%d][5] = 's';\n" i;
7275 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7276 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7281 pr " if (r[%d] != NULL) {\n" (List.length expected);
7282 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7284 pr " print_strings (r);\n";
7288 List.iter (generate_test_command_call test_name) seq;
7289 generate_test_command_call ~test test_name last
7290 | TestOutputInt (seq, expected) ->
7291 pr " /* TestOutputInt for %s (%d) */\n" name i;
7292 let seq, last = get_seq_last seq in
7294 pr " if (r != %d) {\n" expected;
7295 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
7301 List.iter (generate_test_command_call test_name) seq;
7302 generate_test_command_call ~test test_name last
7303 | TestOutputIntOp (seq, op, expected) ->
7304 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
7305 let seq, last = get_seq_last seq in
7307 pr " if (! (r %s %d)) {\n" op expected;
7308 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
7309 test_name op expected;
7314 List.iter (generate_test_command_call test_name) seq;
7315 generate_test_command_call ~test test_name last
7316 | TestOutputTrue seq ->
7317 pr " /* TestOutputTrue for %s (%d) */\n" name i;
7318 let seq, last = get_seq_last seq in
7321 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
7326 List.iter (generate_test_command_call test_name) seq;
7327 generate_test_command_call ~test test_name last
7328 | TestOutputFalse seq ->
7329 pr " /* TestOutputFalse for %s (%d) */\n" name i;
7330 let seq, last = get_seq_last seq in
7333 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
7338 List.iter (generate_test_command_call test_name) seq;
7339 generate_test_command_call ~test test_name last
7340 | TestOutputLength (seq, expected) ->
7341 pr " /* TestOutputLength for %s (%d) */\n" name i;
7342 let seq, last = get_seq_last seq in
7345 pr " for (j = 0; j < %d; ++j)\n" expected;
7346 pr " if (r[j] == NULL) {\n";
7347 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
7349 pr " print_strings (r);\n";
7352 pr " if (r[j] != NULL) {\n";
7353 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
7355 pr " print_strings (r);\n";
7359 List.iter (generate_test_command_call test_name) seq;
7360 generate_test_command_call ~test test_name last
7361 | TestOutputBuffer (seq, expected) ->
7362 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
7363 pr " const char *expected = \"%s\";\n" (c_quote expected);
7364 let seq, last = get_seq_last seq in
7365 let len = String.length expected in
7367 pr " if (size != %d) {\n" len;
7368 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
7371 pr " if (STRNEQLEN (r, expected, size)) {\n";
7372 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7376 List.iter (generate_test_command_call test_name) seq;
7377 generate_test_command_call ~test test_name last
7378 | TestOutputStruct (seq, checks) ->
7379 pr " /* TestOutputStruct for %s (%d) */\n" name i;
7380 let seq, last = get_seq_last seq in
7384 | CompareWithInt (field, expected) ->
7385 pr " if (r->%s != %d) {\n" field expected;
7386 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
7387 test_name field expected;
7388 pr " (int) r->%s);\n" field;
7391 | CompareWithIntOp (field, op, expected) ->
7392 pr " if (!(r->%s %s %d)) {\n" field op expected;
7393 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
7394 test_name field op expected;
7395 pr " (int) r->%s);\n" field;
7398 | CompareWithString (field, expected) ->
7399 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
7400 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
7401 test_name field expected;
7402 pr " r->%s);\n" field;
7405 | CompareFieldsIntEq (field1, field2) ->
7406 pr " if (r->%s != r->%s) {\n" field1 field2;
7407 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
7408 test_name field1 field2;
7409 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
7412 | CompareFieldsStrEq (field1, field2) ->
7413 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
7414 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
7415 test_name field1 field2;
7416 pr " r->%s, r->%s);\n" field1 field2;
7421 List.iter (generate_test_command_call test_name) seq;
7422 generate_test_command_call ~test test_name last
7423 | TestLastFail seq ->
7424 pr " /* TestLastFail for %s (%d) */\n" name i;
7425 let seq, last = get_seq_last seq in
7426 List.iter (generate_test_command_call test_name) seq;
7427 generate_test_command_call test_name ~expect_error:true last
7429 (* Generate the code to run a command, leaving the result in 'r'.
7430 * If you expect to get an error then you should set expect_error:true.
7432 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
7434 | [] -> assert false
7436 (* Look up the command to find out what args/ret it has. *)
7439 let _, style, _, _, _, _, _ =
7440 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
7443 failwithf "%s: in test, command %s was not found" test_name name in
7445 if List.length (snd style) <> List.length args then
7446 failwithf "%s: in test, wrong number of args given to %s"
7453 | OptString n, "NULL" -> ()
7456 | Dev_or_Path n, arg
7458 | OptString n, arg ->
7459 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7460 | BufferIn n, arg ->
7461 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7462 pr " size_t %s_size = %d;\n" n (String.length arg)
7466 | FileIn _, _ | FileOut _, _ -> ()
7467 | StringList n, "" | DeviceList n, "" ->
7468 pr " const char *const %s[1] = { NULL };\n" n
7469 | StringList n, arg | DeviceList n, arg ->
7470 let strs = string_split " " arg in
7473 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
7475 pr " const char *const %s[] = {\n" n;
7477 fun i _ -> pr " %s_%d,\n" n i
7481 ) (List.combine (snd style) args);
7484 match fst style with
7485 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
7486 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7487 | RConstString _ | RConstOptString _ ->
7488 pr " const char *r;\n"; "NULL"
7489 | RString _ -> pr " char *r;\n"; "NULL"
7490 | RStringList _ | RHashtable _ ->
7494 | RStruct (_, typ) ->
7495 pr " struct guestfs_%s *r;\n" typ; "NULL"
7496 | RStructList (_, typ) ->
7497 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7500 pr " size_t size;\n";
7503 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
7504 pr " r = guestfs_%s (g" name;
7506 (* Generate the parameters. *)
7509 | OptString _, "NULL" -> pr ", NULL"
7511 | Device n, _ | Dev_or_Path n, _
7516 pr ", %s, %s_size" n n
7517 | FileIn _, arg | FileOut _, arg ->
7518 pr ", \"%s\"" (c_quote arg)
7519 | StringList n, _ | DeviceList n, _ ->
7520 pr ", (char **) %s" n
7523 try int_of_string arg
7524 with Failure "int_of_string" ->
7525 failwithf "%s: expecting an int, but got '%s'" test_name arg in
7529 try Int64.of_string arg
7530 with Failure "int_of_string" ->
7531 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
7534 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
7535 ) (List.combine (snd style) args);
7537 (match fst style with
7538 | RBufferOut _ -> pr ", &size"
7544 if not expect_error then
7545 pr " if (r == %s)\n" error_code
7547 pr " if (r != %s)\n" error_code;
7550 (* Insert the test code. *)
7556 (match fst style with
7557 | RErr | RInt _ | RInt64 _ | RBool _
7558 | RConstString _ | RConstOptString _ -> ()
7559 | RString _ | RBufferOut _ -> pr " free (r);\n"
7560 | RStringList _ | RHashtable _ ->
7561 pr " for (i = 0; r[i] != NULL; ++i)\n";
7562 pr " free (r[i]);\n";
7564 | RStruct (_, typ) ->
7565 pr " guestfs_free_%s (r);\n" typ
7566 | RStructList (_, typ) ->
7567 pr " guestfs_free_%s_list (r);\n" typ
7573 let str = replace_str str "\r" "\\r" in
7574 let str = replace_str str "\n" "\\n" in
7575 let str = replace_str str "\t" "\\t" in
7576 let str = replace_str str "\000" "\\0" in
7579 (* Generate a lot of different functions for guestfish. *)
7580 and generate_fish_cmds () =
7581 generate_header CStyle GPLv2plus;
7585 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7587 let all_functions_sorted =
7589 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7590 ) all_functions_sorted in
7592 pr "#include <config.h>\n";
7594 pr "#include <stdio.h>\n";
7595 pr "#include <stdlib.h>\n";
7596 pr "#include <string.h>\n";
7597 pr "#include <inttypes.h>\n";
7599 pr "#include <guestfs.h>\n";
7600 pr "#include \"c-ctype.h\"\n";
7601 pr "#include \"full-write.h\"\n";
7602 pr "#include \"xstrtol.h\"\n";
7603 pr "#include \"fish.h\"\n";
7605 pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
7606 pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
7609 (* list_commands function, which implements guestfish -h *)
7610 pr "void list_commands (void)\n";
7612 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
7613 pr " list_builtin_commands ();\n";
7615 fun (name, _, _, flags, _, shortdesc, _) ->
7616 let name = replace_char name '_' '-' in
7617 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
7619 ) all_functions_sorted;
7620 pr " printf (\" %%s\\n\",";
7621 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
7625 (* display_command function, which implements guestfish -h cmd *)
7626 pr "int display_command (const char *cmd)\n";
7629 fun (name, style, _, flags, _, shortdesc, longdesc) ->
7630 let name2 = replace_char name '_' '-' in
7632 try find_map (function FishAlias n -> Some n | _ -> None) flags
7633 with Not_found -> name in
7634 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
7636 match snd style with
7640 name2 (String.concat " " (List.map name_of_argt args)) in
7643 if List.mem ProtocolLimitWarning flags then
7644 ("\n\n" ^ protocol_limit_warning)
7647 (* For DangerWillRobinson commands, we should probably have
7648 * guestfish prompt before allowing you to use them (especially
7649 * in interactive mode). XXX
7653 if List.mem DangerWillRobinson flags then
7654 ("\n\n" ^ danger_will_robinson)
7659 match deprecation_notice flags with
7661 | Some txt -> "\n\n" ^ txt in
7663 let describe_alias =
7664 if name <> alias then
7665 sprintf "\n\nYou can use '%s' as an alias for this command." alias
7669 pr "STRCASEEQ (cmd, \"%s\")" name;
7670 if name <> name2 then
7671 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7672 if name <> alias then
7673 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7675 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
7677 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
7678 "=head1 DESCRIPTION\n\n" ^
7679 longdesc ^ warnings ^ describe_alias);
7684 pr " return display_builtin_command (cmd);\n";
7688 let emit_print_list_function typ =
7689 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
7692 pr " unsigned int i;\n";
7694 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7695 pr " printf (\"[%%d] = {\\n\", i);\n";
7696 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
7697 pr " printf (\"}\\n\");\n";
7703 (* print_* functions *)
7707 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
7709 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
7712 pr " unsigned int i;\n";
7718 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
7720 pr " printf (\"%%s%s: \", indent);\n" name;
7721 pr " for (i = 0; i < 32; ++i)\n";
7722 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7723 pr " printf (\"\\n\");\n"
7725 pr " printf (\"%%s%s: \", indent);\n" name;
7726 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
7727 pr " if (c_isprint (%s->%s[i]))\n" typ name;
7728 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7730 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
7731 pr " printf (\"\\n\");\n"
7732 | name, (FUInt64|FBytes) ->
7733 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
7736 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
7739 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
7742 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
7745 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
7747 | name, FOptPercent ->
7748 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
7749 typ name name typ name;
7750 pr " else printf (\"%%s%s: \\n\", indent);\n" name
7756 (* Emit a print_TYPE_list function definition only if that function is used. *)
7759 | typ, (RStructListOnly | RStructAndList) ->
7760 (* generate the function for typ *)
7761 emit_print_list_function typ
7762 | typ, _ -> () (* empty *)
7763 ) (rstructs_used_by all_functions);
7765 (* Emit a print_TYPE function definition only if that function is used. *)
7768 | typ, (RStructOnly | RStructAndList) ->
7769 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
7771 pr " print_%s_indent (%s, \"\");\n" typ typ;
7774 | typ, _ -> () (* empty *)
7775 ) (rstructs_used_by all_functions);
7777 (* run_<action> actions *)
7779 fun (name, style, _, flags, _, _, _) ->
7780 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
7782 (match fst style with
7785 | RBool _ -> pr " int r;\n"
7786 | RInt64 _ -> pr " int64_t r;\n"
7787 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
7788 | RString _ -> pr " char *r;\n"
7789 | RStringList _ | RHashtable _ -> pr " char **r;\n"
7790 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
7791 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
7794 pr " size_t size;\n";
7800 | OptString n -> pr " const char *%s;\n" n
7804 | FileOut n -> pr " char *%s;\n" n
7806 pr " const char *%s;\n" n;
7807 pr " size_t %s_size;\n" n
7808 | StringList n | DeviceList n -> pr " char **%s;\n" n
7809 | Bool n -> pr " int %s;\n" n
7810 | Int n -> pr " int %s;\n" n
7811 | Int64 n -> pr " int64_t %s;\n" n
7814 (* Check and convert parameters. *)
7815 let argc_expected = List.length (snd style) in
7816 pr " if (argc != %d) {\n" argc_expected;
7817 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
7819 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
7823 let parse_integer fn fntyp rtyp range name i =
7825 pr " strtol_error xerr;\n";
7826 pr " %s r;\n" fntyp;
7828 pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
7829 pr " if (xerr != LONGINT_OK) {\n";
7830 pr " fprintf (stderr,\n";
7831 pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
7832 pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
7837 | Some (min, max, comment) ->
7838 pr " /* %s */\n" comment;
7839 pr " if (r < %s || r > %s) {\n" min max;
7840 pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
7844 pr " /* The check above should ensure this assignment does not overflow. */\n";
7846 pr " %s = r;\n" name;
7855 pr " %s = argv[%d];\n" name i
7857 | Dev_or_Path name ->
7858 pr " %s = resolve_win_path (argv[%d]);\n" name i;
7859 pr " if (%s == NULL) return -1;\n" name
7861 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
7864 pr " %s = argv[%d];\n" name i;
7865 pr " %s_size = strlen (argv[%d]);\n" name i
7867 pr " %s = file_in (argv[%d]);\n" name i;
7868 pr " if (%s == NULL) return -1;\n" name
7870 pr " %s = file_out (argv[%d]);\n" name i;
7871 pr " if (%s == NULL) return -1;\n" name
7872 | StringList name | DeviceList name ->
7873 pr " %s = parse_string_list (argv[%d]);\n" name i;
7874 pr " if (%s == NULL) return -1;\n" name;
7876 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
7879 let min = "(-(2LL<<30))"
7880 and max = "((2LL<<30)-1)"
7882 "The Int type in the generator is a signed 31 bit int." in
7883 Some (min, max, comment) in
7884 parse_integer "xstrtoll" "long long" "int" range name i
7886 parse_integer "xstrtoll" "long long" "int64_t" None name i
7889 (* Call C API function. *)
7890 pr " r = guestfs_%s " name;
7891 generate_c_call_args ~handle:"g" style;
7896 | Device name | String name
7897 | OptString name | Bool name
7898 | Int name | Int64 name
7899 | BufferIn name -> ()
7900 | Pathname name | Dev_or_Path name | FileOut name ->
7901 pr " free (%s);\n" name
7903 pr " free_file_in (%s);\n" name
7904 | StringList name | DeviceList name ->
7905 pr " free_strings (%s);\n" name
7908 (* Any output flags? *)
7910 let flags = filter_map (
7911 function FishOutput flag -> Some flag | _ -> None
7917 failwithf "%s: more than one FishOutput flag is not allowed" name in
7919 (* Check return value for errors and display command results. *)
7920 (match fst style with
7921 | RErr -> pr " return r;\n"
7923 pr " if (r == -1) return -1;\n";
7924 (match fish_output with
7926 pr " printf (\"%%d\\n\", r);\n";
7927 | Some FishOutputOctal ->
7928 pr " printf (\"%%s%%o\\n\", r != 0 ? \"0\" : \"\", r);\n";
7929 | Some FishOutputHexadecimal ->
7930 pr " printf (\"%%s%%x\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7933 pr " if (r == -1) return -1;\n";
7934 (match fish_output with
7936 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
7937 | Some FishOutputOctal ->
7938 pr " printf (\"%%s%%\" PRIo64 \"\\n\", r != 0 ? \"0\" : \"\", r);\n";
7939 | Some FishOutputHexadecimal ->
7940 pr " printf (\"%%s%%\" PRIx64 \"\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7943 pr " if (r == -1) return -1;\n";
7944 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
7947 pr " if (r == NULL) return -1;\n";
7948 pr " printf (\"%%s\\n\", r);\n";
7950 | RConstOptString _ ->
7951 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
7954 pr " if (r == NULL) return -1;\n";
7955 pr " printf (\"%%s\\n\", r);\n";
7959 pr " if (r == NULL) return -1;\n";
7960 pr " print_strings (r);\n";
7961 pr " free_strings (r);\n";
7963 | RStruct (_, typ) ->
7964 pr " if (r == NULL) return -1;\n";
7965 pr " print_%s (r);\n" typ;
7966 pr " guestfs_free_%s (r);\n" typ;
7968 | RStructList (_, typ) ->
7969 pr " if (r == NULL) return -1;\n";
7970 pr " print_%s_list (r);\n" typ;
7971 pr " guestfs_free_%s_list (r);\n" typ;
7974 pr " if (r == NULL) return -1;\n";
7975 pr " print_table (r);\n";
7976 pr " free_strings (r);\n";
7979 pr " if (r == NULL) return -1;\n";
7980 pr " if (full_write (1, r, size) != size) {\n";
7981 pr " perror (\"write\");\n";
7992 (* run_action function *)
7993 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
7996 fun (name, _, _, flags, _, _, _) ->
7997 let name2 = replace_char name '_' '-' in
7999 try find_map (function FishAlias n -> Some n | _ -> None) flags
8000 with Not_found -> name in
8002 pr "STRCASEEQ (cmd, \"%s\")" name;
8003 if name <> name2 then
8004 pr " || STRCASEEQ (cmd, \"%s\")" name2;
8005 if name <> alias then
8006 pr " || STRCASEEQ (cmd, \"%s\")" alias;
8008 pr " return run_%s (cmd, argc, argv);\n" name;
8012 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
8013 pr " if (command_num == 1)\n";
8014 pr " extended_help_message ();\n";
8021 (* Readline completion for guestfish. *)
8022 and generate_fish_completion () =
8023 generate_header CStyle GPLv2plus;
8027 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
8037 #ifdef HAVE_LIBREADLINE
8038 #include <readline/readline.h>
8043 #ifdef HAVE_LIBREADLINE
8045 static const char *const commands[] = {
8046 BUILTIN_COMMANDS_FOR_COMPLETION,
8049 (* Get the commands, including the aliases. They don't need to be
8050 * sorted - the generator() function just does a dumb linear search.
8054 fun (name, _, _, flags, _, _, _) ->
8055 let name2 = replace_char name '_' '-' in
8057 try find_map (function FishAlias n -> Some n | _ -> None) flags
8058 with Not_found -> name in
8060 if name <> alias then [name2; alias] else [name2]
8062 let commands = List.flatten commands in
8064 List.iter (pr " \"%s\",\n") commands;
8070 generator (const char *text, int state)
8072 static int index, len;
8077 len = strlen (text);
8080 rl_attempted_completion_over = 1;
8082 while ((name = commands[index]) != NULL) {
8084 if (STRCASEEQLEN (name, text, len))
8085 return strdup (name);
8091 #endif /* HAVE_LIBREADLINE */
8093 #ifdef HAVE_RL_COMPLETION_MATCHES
8094 #define RL_COMPLETION_MATCHES rl_completion_matches
8096 #ifdef HAVE_COMPLETION_MATCHES
8097 #define RL_COMPLETION_MATCHES completion_matches
8099 #endif /* else just fail if we don't have either symbol */
8102 do_completion (const char *text, int start, int end)
8104 char **matches = NULL;
8106 #ifdef HAVE_LIBREADLINE
8107 rl_completion_append_character = ' ';
8110 matches = RL_COMPLETION_MATCHES (text, generator);
8111 else if (complete_dest_paths)
8112 matches = RL_COMPLETION_MATCHES (text, complete_dest_paths_generator);
8119 (* Generate the POD documentation for guestfish. *)
8120 and generate_fish_actions_pod () =
8121 let all_functions_sorted =
8123 fun (_, _, _, flags, _, _, _) ->
8124 not (List.mem NotInFish flags || List.mem NotInDocs flags)
8125 ) all_functions_sorted in
8127 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
8130 fun (name, style, _, flags, _, _, longdesc) ->
8132 Str.global_substitute rex (
8135 try Str.matched_group 1 s
8137 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
8138 "C<" ^ replace_char sub '_' '-' ^ ">"
8140 let name = replace_char name '_' '-' in
8142 try find_map (function FishAlias n -> Some n | _ -> None) flags
8143 with Not_found -> name in
8145 pr "=head2 %s" name;
8146 if name <> alias then
8153 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
8154 | OptString n -> pr " %s" n
8155 | StringList n | DeviceList n -> pr " '%s ...'" n
8156 | Bool _ -> pr " true|false"
8157 | Int n -> pr " %s" n
8158 | Int64 n -> pr " %s" n
8159 | FileIn n | FileOut n -> pr " (%s|-)" n
8160 | BufferIn n -> pr " %s" n
8164 pr "%s\n\n" longdesc;
8166 if List.exists (function FileIn _ | FileOut _ -> true
8167 | _ -> false) (snd style) then
8168 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
8170 if List.mem ProtocolLimitWarning flags then
8171 pr "%s\n\n" protocol_limit_warning;
8173 if List.mem DangerWillRobinson flags then
8174 pr "%s\n\n" danger_will_robinson;
8176 match deprecation_notice flags with
8178 | Some txt -> pr "%s\n\n" txt
8179 ) all_functions_sorted
8181 (* Generate a C function prototype. *)
8182 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
8183 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
8185 ?handle name style =
8186 if extern then pr "extern ";
8187 if static then pr "static ";
8188 (match fst style with
8190 | RInt _ -> pr "int "
8191 | RInt64 _ -> pr "int64_t "
8192 | RBool _ -> pr "int "
8193 | RConstString _ | RConstOptString _ -> pr "const char *"
8194 | RString _ | RBufferOut _ -> pr "char *"
8195 | RStringList _ | RHashtable _ -> pr "char **"
8196 | RStruct (_, typ) ->
8197 if not in_daemon then pr "struct guestfs_%s *" typ
8198 else pr "guestfs_int_%s *" typ
8199 | RStructList (_, typ) ->
8200 if not in_daemon then pr "struct guestfs_%s_list *" typ
8201 else pr "guestfs_int_%s_list *" typ
8203 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
8204 pr "%s%s (" prefix name;
8205 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
8208 let comma = ref false in
8211 | Some handle -> pr "guestfs_h *%s" handle; comma := true
8215 if single_line then pr ", " else pr ",\n\t\t"
8222 | Device n | Dev_or_Path n
8226 pr "const char *%s" n
8227 | StringList n | DeviceList n ->
8229 pr "char *const *%s" n
8230 | Bool n -> next (); pr "int %s" n
8231 | Int n -> next (); pr "int %s" n
8232 | Int64 n -> next (); pr "int64_t %s" n
8235 if not in_daemon then (next (); pr "const char *%s" n)
8238 pr "const char *%s" n;
8240 pr "size_t %s_size" n
8242 if is_RBufferOut then (next (); pr "size_t *size_r");
8245 if semicolon then pr ";";
8246 if newline then pr "\n"
8248 (* Generate C call arguments, eg "(handle, foo, bar)" *)
8249 and generate_c_call_args ?handle ?(decl = false) style =
8251 let comma = ref false in
8253 if !comma then pr ", ";
8258 | Some handle -> pr "%s" handle; comma := true
8264 pr "%s, %s_size" n n
8267 pr "%s" (name_of_argt arg)
8269 (* For RBufferOut calls, add implicit &size parameter. *)
8271 match fst style with
8279 (* Generate the OCaml bindings interface. *)
8280 and generate_ocaml_mli () =
8281 generate_header OCamlStyle LGPLv2plus;
8284 (** For API documentation you should refer to the C API
8285 in the guestfs(3) manual page. The OCaml API uses almost
8286 exactly the same calls. *)
8289 (** A [guestfs_h] handle. *)
8291 exception Error of string
8292 (** This exception is raised when there is an error. *)
8294 exception Handle_closed of string
8295 (** This exception is raised if you use a {!Guestfs.t} handle
8296 after calling {!close} on it. The string is the name of
8299 val create : unit -> t
8300 (** Create a {!Guestfs.t} handle. *)
8302 val close : t -> unit
8303 (** Close the {!Guestfs.t} handle and free up all resources used
8306 Handles are closed by the garbage collector when they become
8307 unreferenced, but callers can call this in order to provide
8308 predictable cleanup. *)
8311 generate_ocaml_structure_decls ();
8315 fun (name, style, _, _, _, shortdesc, _) ->
8316 generate_ocaml_prototype name style;
8317 pr "(** %s *)\n" shortdesc;
8319 ) all_functions_sorted
8321 (* Generate the OCaml bindings implementation. *)
8322 and generate_ocaml_ml () =
8323 generate_header OCamlStyle LGPLv2plus;
8328 exception Error of string
8329 exception Handle_closed of string
8331 external create : unit -> t = \"ocaml_guestfs_create\"
8332 external close : t -> unit = \"ocaml_guestfs_close\"
8334 (* Give the exceptions names, so they can be raised from the C code. *)
8336 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
8337 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
8341 generate_ocaml_structure_decls ();
8345 fun (name, style, _, _, _, shortdesc, _) ->
8346 generate_ocaml_prototype ~is_external:true name style;
8347 ) all_functions_sorted
8349 (* Generate the OCaml bindings C implementation. *)
8350 and generate_ocaml_c () =
8351 generate_header CStyle LGPLv2plus;
8358 #include <caml/config.h>
8359 #include <caml/alloc.h>
8360 #include <caml/callback.h>
8361 #include <caml/fail.h>
8362 #include <caml/memory.h>
8363 #include <caml/mlvalues.h>
8364 #include <caml/signals.h>
8366 #include <guestfs.h>
8368 #include \"guestfs_c.h\"
8370 /* Copy a hashtable of string pairs into an assoc-list. We return
8371 * the list in reverse order, but hashtables aren't supposed to be
8374 static CAMLprim value
8375 copy_table (char * const * argv)
8378 CAMLlocal5 (rv, pairv, kv, vv, cons);
8382 for (i = 0; argv[i] != NULL; i += 2) {
8383 kv = caml_copy_string (argv[i]);
8384 vv = caml_copy_string (argv[i+1]);
8385 pairv = caml_alloc (2, 0);
8386 Store_field (pairv, 0, kv);
8387 Store_field (pairv, 1, vv);
8388 cons = caml_alloc (2, 0);
8389 Store_field (cons, 1, rv);
8391 Store_field (cons, 0, pairv);
8399 (* Struct copy functions. *)
8401 let emit_ocaml_copy_list_function typ =
8402 pr "static CAMLprim value\n";
8403 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
8405 pr " CAMLparam0 ();\n";
8406 pr " CAMLlocal2 (rv, v);\n";
8407 pr " unsigned int i;\n";
8409 pr " if (%ss->len == 0)\n" typ;
8410 pr " CAMLreturn (Atom (0));\n";
8412 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
8413 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
8414 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
8415 pr " caml_modify (&Field (rv, i), v);\n";
8417 pr " CAMLreturn (rv);\n";
8425 let has_optpercent_col =
8426 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
8428 pr "static CAMLprim value\n";
8429 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
8431 pr " CAMLparam0 ();\n";
8432 if has_optpercent_col then
8433 pr " CAMLlocal3 (rv, v, v2);\n"
8435 pr " CAMLlocal2 (rv, v);\n";
8437 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
8442 pr " v = caml_copy_string (%s->%s);\n" typ name
8444 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
8445 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
8448 pr " v = caml_alloc_string (32);\n";
8449 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
8450 | name, (FBytes|FInt64|FUInt64) ->
8451 pr " v = caml_copy_int64 (%s->%s);\n" typ name
8452 | name, (FInt32|FUInt32) ->
8453 pr " v = caml_copy_int32 (%s->%s);\n" typ name
8454 | name, FOptPercent ->
8455 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
8456 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
8457 pr " v = caml_alloc (1, 0);\n";
8458 pr " Store_field (v, 0, v2);\n";
8459 pr " } else /* None */\n";
8460 pr " v = Val_int (0);\n";
8462 pr " v = Val_int (%s->%s);\n" typ name
8464 pr " Store_field (rv, %d, v);\n" i
8466 pr " CAMLreturn (rv);\n";
8471 (* Emit a copy_TYPE_list function definition only if that function is used. *)
8474 | typ, (RStructListOnly | RStructAndList) ->
8475 (* generate the function for typ *)
8476 emit_ocaml_copy_list_function typ
8477 | typ, _ -> () (* empty *)
8478 ) (rstructs_used_by all_functions);
8482 fun (name, style, _, _, _, _, _) ->
8483 pr "/* Automatically generated wrapper for function\n";
8485 generate_ocaml_prototype name style;
8490 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
8492 let needs_extra_vs =
8493 match fst style with RConstOptString _ -> true | _ -> false in
8495 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8496 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
8497 List.iter (pr ", value %s") (List.tl params); pr ");\n";
8500 pr "CAMLprim value\n";
8501 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
8502 List.iter (pr ", value %s") (List.tl params);
8507 | [p1; p2; p3; p4; p5] ->
8508 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
8509 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
8510 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
8511 pr " CAMLxparam%d (%s);\n"
8512 (List.length rest) (String.concat ", " rest)
8514 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
8516 if not needs_extra_vs then
8517 pr " CAMLlocal1 (rv);\n"
8519 pr " CAMLlocal3 (rv, v, v2);\n";
8522 pr " guestfs_h *g = Guestfs_val (gv);\n";
8523 pr " if (g == NULL)\n";
8524 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
8530 | Device n | Dev_or_Path n
8534 pr " const char *%s = String_val (%sv);\n" n n
8536 pr " const char *%s =\n" n;
8537 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
8540 pr " const char *%s = String_val (%sv);\n" n n;
8541 pr " size_t %s_size = caml_string_length (%sv);\n" n n
8542 | StringList n | DeviceList n ->
8543 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
8545 pr " int %s = Bool_val (%sv);\n" n n
8547 pr " int %s = Int_val (%sv);\n" n n
8549 pr " int64_t %s = Int64_val (%sv);\n" n n
8552 match fst style with
8553 | RErr -> pr " int r;\n"; "-1"
8554 | RInt _ -> pr " int r;\n"; "-1"
8555 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8556 | RBool _ -> pr " int r;\n"; "-1"
8557 | RConstString _ | RConstOptString _ ->
8558 pr " const char *r;\n"; "NULL"
8559 | RString _ -> pr " char *r;\n"; "NULL"
8564 | RStruct (_, typ) ->
8565 pr " struct guestfs_%s *r;\n" typ; "NULL"
8566 | RStructList (_, typ) ->
8567 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8574 pr " size_t size;\n";
8578 pr " caml_enter_blocking_section ();\n";
8579 pr " r = guestfs_%s " name;
8580 generate_c_call_args ~handle:"g" style;
8582 pr " caml_leave_blocking_section ();\n";
8586 | StringList n | DeviceList n ->
8587 pr " ocaml_guestfs_free_strings (%s);\n" n;
8588 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8589 | Bool _ | Int _ | Int64 _
8590 | FileIn _ | FileOut _ | BufferIn _ -> ()
8593 pr " if (r == %s)\n" error_code;
8594 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
8597 (match fst style with
8598 | RErr -> pr " rv = Val_unit;\n"
8599 | RInt _ -> pr " rv = Val_int (r);\n"
8601 pr " rv = caml_copy_int64 (r);\n"
8602 | RBool _ -> pr " rv = Val_bool (r);\n"
8604 pr " rv = caml_copy_string (r);\n"
8605 | RConstOptString _ ->
8606 pr " if (r) { /* Some string */\n";
8607 pr " v = caml_alloc (1, 0);\n";
8608 pr " v2 = caml_copy_string (r);\n";
8609 pr " Store_field (v, 0, v2);\n";
8610 pr " } else /* None */\n";
8611 pr " v = Val_int (0);\n";
8613 pr " rv = caml_copy_string (r);\n";
8616 pr " rv = caml_copy_string_array ((const char **) r);\n";
8617 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8619 | RStruct (_, typ) ->
8620 pr " rv = copy_%s (r);\n" typ;
8621 pr " guestfs_free_%s (r);\n" typ;
8622 | RStructList (_, typ) ->
8623 pr " rv = copy_%s_list (r);\n" typ;
8624 pr " guestfs_free_%s_list (r);\n" typ;
8626 pr " rv = copy_table (r);\n";
8627 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8630 pr " rv = caml_alloc_string (size);\n";
8631 pr " memcpy (String_val (rv), r, size);\n";
8634 pr " CAMLreturn (rv);\n";
8638 if List.length params > 5 then (
8639 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8640 pr "CAMLprim value ";
8641 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
8642 pr "CAMLprim value\n";
8643 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
8645 pr " return ocaml_guestfs_%s (argv[0]" name;
8646 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
8651 ) all_functions_sorted
8653 and generate_ocaml_structure_decls () =
8656 pr "type %s = {\n" typ;
8659 | name, FString -> pr " %s : string;\n" name
8660 | name, FBuffer -> pr " %s : string;\n" name
8661 | name, FUUID -> pr " %s : string;\n" name
8662 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
8663 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
8664 | name, FChar -> pr " %s : char;\n" name
8665 | name, FOptPercent -> pr " %s : float option;\n" name
8671 and generate_ocaml_prototype ?(is_external = false) name style =
8672 if is_external then pr "external " else pr "val ";
8673 pr "%s : t -> " name;
8676 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _
8677 | BufferIn _ -> pr "string -> "
8678 | OptString _ -> pr "string option -> "
8679 | StringList _ | DeviceList _ -> pr "string array -> "
8680 | Bool _ -> pr "bool -> "
8681 | Int _ -> pr "int -> "
8682 | Int64 _ -> pr "int64 -> "
8684 (match fst style with
8685 | RErr -> pr "unit" (* all errors are turned into exceptions *)
8686 | RInt _ -> pr "int"
8687 | RInt64 _ -> pr "int64"
8688 | RBool _ -> pr "bool"
8689 | RConstString _ -> pr "string"
8690 | RConstOptString _ -> pr "string option"
8691 | RString _ | RBufferOut _ -> pr "string"
8692 | RStringList _ -> pr "string array"
8693 | RStruct (_, typ) -> pr "%s" typ
8694 | RStructList (_, typ) -> pr "%s array" typ
8695 | RHashtable _ -> pr "(string * string) list"
8697 if is_external then (
8699 if List.length (snd style) + 1 > 5 then
8700 pr "\"ocaml_guestfs_%s_byte\" " name;
8701 pr "\"ocaml_guestfs_%s\"" name
8705 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
8706 and generate_perl_xs () =
8707 generate_header CStyle LGPLv2plus;
8710 #include \"EXTERN.h\"
8714 #include <guestfs.h>
8717 #define PRId64 \"lld\"
8721 my_newSVll(long long val) {
8722 #ifdef USE_64_BIT_ALL
8723 return newSViv(val);
8727 len = snprintf(buf, 100, \"%%\" PRId64, val);
8728 return newSVpv(buf, len);
8733 #define PRIu64 \"llu\"
8737 my_newSVull(unsigned long long val) {
8738 #ifdef USE_64_BIT_ALL
8739 return newSVuv(val);
8743 len = snprintf(buf, 100, \"%%\" PRIu64, val);
8744 return newSVpv(buf, len);
8748 /* http://www.perlmonks.org/?node_id=680842 */
8750 XS_unpack_charPtrPtr (SV *arg) {
8755 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
8756 croak (\"array reference expected\");
8758 av = (AV *)SvRV (arg);
8759 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
8761 croak (\"malloc failed\");
8763 for (i = 0; i <= av_len (av); i++) {
8764 SV **elem = av_fetch (av, i, 0);
8766 if (!elem || !*elem)
8767 croak (\"missing element in list\");
8769 ret[i] = SvPV_nolen (*elem);
8777 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
8784 RETVAL = guestfs_create ();
8786 croak (\"could not create guestfs handle\");
8787 guestfs_set_error_handler (RETVAL, NULL, NULL);
8800 fun (name, style, _, _, _, _, _) ->
8801 (match fst style with
8802 | RErr -> pr "void\n"
8803 | RInt _ -> pr "SV *\n"
8804 | RInt64 _ -> pr "SV *\n"
8805 | RBool _ -> pr "SV *\n"
8806 | RConstString _ -> pr "SV *\n"
8807 | RConstOptString _ -> pr "SV *\n"
8808 | RString _ -> pr "SV *\n"
8809 | RBufferOut _ -> pr "SV *\n"
8811 | RStruct _ | RStructList _
8813 pr "void\n" (* all lists returned implictly on the stack *)
8815 (* Call and arguments. *)
8818 fun arg -> pr ", %s" (name_of_argt arg)
8821 pr " guestfs_h *g;\n";
8825 | Pathname n | Device n | Dev_or_Path n | String n
8826 | FileIn n | FileOut n ->
8829 pr " char *%s;\n" n;
8830 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
8832 (* http://www.perlmonks.org/?node_id=554277
8833 * Note that the implicit handle argument means we have
8834 * to add 1 to the ST(x) operator.
8836 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
8837 | StringList n | DeviceList n -> pr " char **%s;\n" n
8838 | Bool n -> pr " int %s;\n" n
8839 | Int n -> pr " int %s;\n" n
8840 | Int64 n -> pr " int64_t %s;\n" n
8843 let do_cleanups () =
8846 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8847 | Bool _ | Int _ | Int64 _
8848 | FileIn _ | FileOut _
8850 | StringList n | DeviceList n -> pr " free (%s);\n" n
8855 (match fst style with
8860 pr " r = guestfs_%s " name;
8861 generate_c_call_args ~handle:"g" style;
8864 pr " if (r == -1)\n";
8865 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8871 pr " %s = guestfs_%s " n name;
8872 generate_c_call_args ~handle:"g" style;
8875 pr " if (%s == -1)\n" n;
8876 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8877 pr " RETVAL = newSViv (%s);\n" n;
8882 pr " int64_t %s;\n" n;
8884 pr " %s = guestfs_%s " n name;
8885 generate_c_call_args ~handle:"g" style;
8888 pr " if (%s == -1)\n" n;
8889 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8890 pr " RETVAL = my_newSVll (%s);\n" n;
8895 pr " const char *%s;\n" n;
8897 pr " %s = guestfs_%s " n name;
8898 generate_c_call_args ~handle:"g" style;
8901 pr " if (%s == NULL)\n" n;
8902 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8903 pr " RETVAL = newSVpv (%s, 0);\n" n;
8906 | RConstOptString n ->
8908 pr " const char *%s;\n" n;
8910 pr " %s = guestfs_%s " n name;
8911 generate_c_call_args ~handle:"g" style;
8914 pr " if (%s == NULL)\n" n;
8915 pr " RETVAL = &PL_sv_undef;\n";
8917 pr " RETVAL = newSVpv (%s, 0);\n" n;
8922 pr " char *%s;\n" n;
8924 pr " %s = guestfs_%s " n name;
8925 generate_c_call_args ~handle:"g" style;
8928 pr " if (%s == NULL)\n" n;
8929 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8930 pr " RETVAL = newSVpv (%s, 0);\n" n;
8931 pr " free (%s);\n" n;
8934 | RStringList n | RHashtable n ->
8936 pr " char **%s;\n" n;
8939 pr " %s = guestfs_%s " n name;
8940 generate_c_call_args ~handle:"g" style;
8943 pr " if (%s == NULL)\n" n;
8944 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8945 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
8946 pr " EXTEND (SP, n);\n";
8947 pr " for (i = 0; i < n; ++i) {\n";
8948 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
8949 pr " free (%s[i]);\n" n;
8951 pr " free (%s);\n" n;
8952 | RStruct (n, typ) ->
8953 let cols = cols_of_struct typ in
8954 generate_perl_struct_code typ cols name style n do_cleanups
8955 | RStructList (n, typ) ->
8956 let cols = cols_of_struct typ in
8957 generate_perl_struct_list_code typ cols name style n do_cleanups
8960 pr " char *%s;\n" n;
8961 pr " size_t size;\n";
8963 pr " %s = guestfs_%s " n name;
8964 generate_c_call_args ~handle:"g" style;
8967 pr " if (%s == NULL)\n" n;
8968 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8969 pr " RETVAL = newSVpvn (%s, size);\n" n;
8970 pr " free (%s);\n" n;
8978 and generate_perl_struct_list_code typ cols name style n do_cleanups =
8980 pr " struct guestfs_%s_list *%s;\n" typ n;
8984 pr " %s = guestfs_%s " n name;
8985 generate_c_call_args ~handle:"g" style;
8988 pr " if (%s == NULL)\n" n;
8989 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8990 pr " EXTEND (SP, %s->len);\n" n;
8991 pr " for (i = 0; i < %s->len; ++i) {\n" n;
8992 pr " hv = newHV ();\n";
8996 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
8997 name (String.length name) n name
8999 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
9000 name (String.length name) n name
9002 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
9003 name (String.length name) n name n name
9004 | name, (FBytes|FUInt64) ->
9005 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
9006 name (String.length name) n name
9008 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
9009 name (String.length name) n name
9010 | name, (FInt32|FUInt32) ->
9011 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
9012 name (String.length name) n name
9014 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
9015 name (String.length name) n name
9016 | name, FOptPercent ->
9017 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
9018 name (String.length name) n name
9020 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
9022 pr " guestfs_free_%s_list (%s);\n" typ n
9024 and generate_perl_struct_code typ cols name style n do_cleanups =
9026 pr " struct guestfs_%s *%s;\n" typ n;
9028 pr " %s = guestfs_%s " n name;
9029 generate_c_call_args ~handle:"g" style;
9032 pr " if (%s == NULL)\n" n;
9033 pr " croak (\"%%s\", guestfs_last_error (g));\n";
9034 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
9036 fun ((name, _) as col) ->
9037 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
9041 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
9044 pr " PUSHs (sv_2mortal (newSVpvn (%s->%s, %s->%s_len)));\n"
9047 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
9049 | name, (FBytes|FUInt64) ->
9050 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
9053 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
9055 | name, (FInt32|FUInt32) ->
9056 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9059 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
9061 | name, FOptPercent ->
9062 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9065 pr " free (%s);\n" n
9067 (* Generate Sys/Guestfs.pm. *)
9068 and generate_perl_pm () =
9069 generate_header HashStyle LGPLv2plus;
9076 Sys::Guestfs - Perl bindings for libguestfs
9082 my $h = Sys::Guestfs->new ();
9083 $h->add_drive ('guest.img');
9085 $h->mount ('/dev/sda1', '/');
9086 $h->touch ('/hello');
9091 The C<Sys::Guestfs> module provides a Perl XS binding to the
9092 libguestfs API for examining and modifying virtual machine
9095 Amongst the things this is good for: making batch configuration
9096 changes to guests, getting disk used/free statistics (see also:
9097 virt-df), migrating between virtualization systems (see also:
9098 virt-p2v), performing partial backups, performing partial guest
9099 clones, cloning guests and changing registry/UUID/hostname info, and
9102 Libguestfs uses Linux kernel and qemu code, and can access any type of
9103 guest filesystem that Linux and qemu can, including but not limited
9104 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9105 schemes, qcow, qcow2, vmdk.
9107 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9108 LVs, what filesystem is in each LV, etc.). It can also run commands
9109 in the context of the guest. Also you can access filesystems over
9112 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
9113 functions for using libguestfs from Perl, including integration
9118 All errors turn into calls to C<croak> (see L<Carp(3)>).
9126 package Sys::Guestfs;
9131 # This version number changes whenever a new function
9132 # is added to the libguestfs API. It is not directly
9133 # related to the libguestfs version number.
9134 use vars qw($VERSION);
9138 XSLoader::load ('Sys::Guestfs');
9140 =item $h = Sys::Guestfs->new ();
9142 Create a new guestfs handle.
9148 my $class = ref ($proto) || $proto;
9150 my $self = Sys::Guestfs::_create ();
9151 bless $self, $class;
9157 (* Actions. We only need to print documentation for these as
9158 * they are pulled in from the XS code automatically.
9161 fun (name, style, _, flags, _, _, longdesc) ->
9162 if not (List.mem NotInDocs flags) then (
9163 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
9165 generate_perl_prototype name style;
9167 pr "%s\n\n" longdesc;
9168 if List.mem ProtocolLimitWarning flags then
9169 pr "%s\n\n" protocol_limit_warning;
9170 if List.mem DangerWillRobinson flags then
9171 pr "%s\n\n" danger_will_robinson;
9172 match deprecation_notice flags with
9174 | Some txt -> pr "%s\n\n" txt
9176 ) all_functions_sorted;
9188 Copyright (C) %s Red Hat Inc.
9192 Please see the file COPYING.LIB for the full license.
9198 L<http://libguestfs.org>,
9199 L<Sys::Guestfs::Lib(3)>.
9204 and generate_perl_prototype name style =
9205 (match fst style with
9213 | RBufferOut n -> pr "$%s = " n
9215 | RHashtable n -> pr "%%%s = " n
9217 | RStructList (n,_) -> pr "@%s = " n
9220 let comma = ref false in
9223 if !comma then pr ", ";
9226 | Pathname n | Device n | Dev_or_Path n | String n
9227 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
9230 | StringList n | DeviceList n ->
9235 (* Generate Python C module. *)
9236 and generate_python_c () =
9237 generate_header CStyle LGPLv2plus;
9240 #define PY_SSIZE_T_CLEAN 1
9243 #if PY_VERSION_HEX < 0x02050000
9244 typedef int Py_ssize_t;
9245 #define PY_SSIZE_T_MAX INT_MAX
9246 #define PY_SSIZE_T_MIN INT_MIN
9253 #include \"guestfs.h\"
9261 get_handle (PyObject *obj)
9264 assert (obj != Py_None);
9265 return ((Pyguestfs_Object *) obj)->g;
9269 put_handle (guestfs_h *g)
9273 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
9276 /* This list should be freed (but not the strings) after use. */
9278 get_string_list (PyObject *obj)
9285 if (!PyList_Check (obj)) {
9286 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
9290 len = PyList_Size (obj);
9291 r = malloc (sizeof (char *) * (len+1));
9293 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
9297 for (i = 0; i < len; ++i)
9298 r[i] = PyString_AsString (PyList_GetItem (obj, i));
9305 put_string_list (char * const * const argv)
9310 for (argc = 0; argv[argc] != NULL; ++argc)
9313 list = PyList_New (argc);
9314 for (i = 0; i < argc; ++i)
9315 PyList_SetItem (list, i, PyString_FromString (argv[i]));
9321 put_table (char * const * const argv)
9323 PyObject *list, *item;
9326 for (argc = 0; argv[argc] != NULL; ++argc)
9329 list = PyList_New (argc >> 1);
9330 for (i = 0; i < argc; i += 2) {
9331 item = PyTuple_New (2);
9332 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
9333 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
9334 PyList_SetItem (list, i >> 1, item);
9341 free_strings (char **argv)
9345 for (argc = 0; argv[argc] != NULL; ++argc)
9351 py_guestfs_create (PyObject *self, PyObject *args)
9355 g = guestfs_create ();
9357 PyErr_SetString (PyExc_RuntimeError,
9358 \"guestfs.create: failed to allocate handle\");
9361 guestfs_set_error_handler (g, NULL, NULL);
9362 return put_handle (g);
9366 py_guestfs_close (PyObject *self, PyObject *args)
9371 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
9373 g = get_handle (py_g);
9377 Py_INCREF (Py_None);
9383 let emit_put_list_function typ =
9384 pr "static PyObject *\n";
9385 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
9387 pr " PyObject *list;\n";
9390 pr " list = PyList_New (%ss->len);\n" typ;
9391 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
9392 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
9393 pr " return list;\n";
9398 (* Structures, turned into Python dictionaries. *)
9401 pr "static PyObject *\n";
9402 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
9404 pr " PyObject *dict;\n";
9406 pr " dict = PyDict_New ();\n";
9410 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9411 pr " PyString_FromString (%s->%s));\n"
9414 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9415 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
9418 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9419 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
9421 | name, (FBytes|FUInt64) ->
9422 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9423 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
9426 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9427 pr " PyLong_FromLongLong (%s->%s));\n"
9430 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9431 pr " PyLong_FromUnsignedLong (%s->%s));\n"
9434 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9435 pr " PyLong_FromLong (%s->%s));\n"
9437 | name, FOptPercent ->
9438 pr " if (%s->%s >= 0)\n" typ name;
9439 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9440 pr " PyFloat_FromDouble ((double) %s->%s));\n"
9443 pr " Py_INCREF (Py_None);\n";
9444 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
9447 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9448 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
9450 pr " return dict;\n";
9456 (* Emit a put_TYPE_list function definition only if that function is used. *)
9459 | typ, (RStructListOnly | RStructAndList) ->
9460 (* generate the function for typ *)
9461 emit_put_list_function typ
9462 | typ, _ -> () (* empty *)
9463 ) (rstructs_used_by all_functions);
9465 (* Python wrapper functions. *)
9467 fun (name, style, _, _, _, _, _) ->
9468 pr "static PyObject *\n";
9469 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
9472 pr " PyObject *py_g;\n";
9473 pr " guestfs_h *g;\n";
9474 pr " PyObject *py_r;\n";
9477 match fst style with
9478 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9479 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9480 | RConstString _ | RConstOptString _ ->
9481 pr " const char *r;\n"; "NULL"
9482 | RString _ -> pr " char *r;\n"; "NULL"
9483 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9484 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9485 | RStructList (_, typ) ->
9486 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9489 pr " size_t size;\n";
9494 | Pathname n | Device n | Dev_or_Path n | String n
9495 | FileIn n | FileOut n ->
9496 pr " const char *%s;\n" n
9497 | OptString n -> pr " const char *%s;\n" n
9499 pr " const char *%s;\n" n;
9500 pr " Py_ssize_t %s_size;\n" n
9501 | StringList n | DeviceList n ->
9502 pr " PyObject *py_%s;\n" n;
9503 pr " char **%s;\n" n
9504 | Bool n -> pr " int %s;\n" n
9505 | Int n -> pr " int %s;\n" n
9506 | Int64 n -> pr " long long %s;\n" n
9511 (* Convert the parameters. *)
9512 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
9515 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
9516 | OptString _ -> pr "z"
9517 | StringList _ | DeviceList _ -> pr "O"
9518 | Bool _ -> pr "i" (* XXX Python has booleans? *)
9520 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
9521 * emulate C's int/long/long long in Python?
9523 | BufferIn _ -> pr "s#"
9525 pr ":guestfs_%s\",\n" name;
9529 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
9530 | OptString n -> pr ", &%s" n
9531 | StringList n | DeviceList n -> pr ", &py_%s" n
9532 | Bool n -> pr ", &%s" n
9533 | Int n -> pr ", &%s" n
9534 | Int64 n -> pr ", &%s" n
9535 | BufferIn n -> pr ", &%s, &%s_size" n n
9539 pr " return NULL;\n";
9541 pr " g = get_handle (py_g);\n";
9544 | Pathname _ | Device _ | Dev_or_Path _ | String _
9545 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9547 | StringList n | DeviceList n ->
9548 pr " %s = get_string_list (py_%s);\n" n n;
9549 pr " if (!%s) return NULL;\n" n
9554 pr " r = guestfs_%s " name;
9555 generate_c_call_args ~handle:"g" style;
9560 | Pathname _ | Device _ | Dev_or_Path _ | String _
9561 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9563 | StringList n | DeviceList n ->
9564 pr " free (%s);\n" n
9567 pr " if (r == %s) {\n" error_code;
9568 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
9569 pr " return NULL;\n";
9573 (match fst style with
9575 pr " Py_INCREF (Py_None);\n";
9576 pr " py_r = Py_None;\n"
9578 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
9579 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
9580 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
9581 | RConstOptString _ ->
9583 pr " py_r = PyString_FromString (r);\n";
9585 pr " Py_INCREF (Py_None);\n";
9586 pr " py_r = Py_None;\n";
9589 pr " py_r = PyString_FromString (r);\n";
9592 pr " py_r = put_string_list (r);\n";
9593 pr " free_strings (r);\n"
9594 | RStruct (_, typ) ->
9595 pr " py_r = put_%s (r);\n" typ;
9596 pr " guestfs_free_%s (r);\n" typ
9597 | RStructList (_, typ) ->
9598 pr " py_r = put_%s_list (r);\n" typ;
9599 pr " guestfs_free_%s_list (r);\n" typ
9601 pr " py_r = put_table (r);\n";
9602 pr " free_strings (r);\n"
9604 pr " py_r = PyString_FromStringAndSize (r, size);\n";
9608 pr " return py_r;\n";
9613 (* Table of functions. *)
9614 pr "static PyMethodDef methods[] = {\n";
9615 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
9616 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
9618 fun (name, _, _, _, _, _, _) ->
9619 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
9622 pr " { NULL, NULL, 0, NULL }\n";
9626 (* Init function. *)
9629 initlibguestfsmod (void)
9631 static int initialized = 0;
9633 if (initialized) return;
9634 Py_InitModule ((char *) \"libguestfsmod\", methods);
9639 (* Generate Python module. *)
9640 and generate_python_py () =
9641 generate_header HashStyle LGPLv2plus;
9644 u\"\"\"Python bindings for libguestfs
9647 g = guestfs.GuestFS ()
9648 g.add_drive (\"guest.img\")
9650 parts = g.list_partitions ()
9652 The guestfs module provides a Python binding to the libguestfs API
9653 for examining and modifying virtual machine disk images.
9655 Amongst the things this is good for: making batch configuration
9656 changes to guests, getting disk used/free statistics (see also:
9657 virt-df), migrating between virtualization systems (see also:
9658 virt-p2v), performing partial backups, performing partial guest
9659 clones, cloning guests and changing registry/UUID/hostname info, and
9662 Libguestfs uses Linux kernel and qemu code, and can access any type of
9663 guest filesystem that Linux and qemu can, including but not limited
9664 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9665 schemes, qcow, qcow2, vmdk.
9667 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9668 LVs, what filesystem is in each LV, etc.). It can also run commands
9669 in the context of the guest. Also you can access filesystems over
9672 Errors which happen while using the API are turned into Python
9673 RuntimeError exceptions.
9675 To create a guestfs handle you usually have to perform the following
9678 # Create the handle, call add_drive at least once, and possibly
9679 # several times if the guest has multiple block devices:
9680 g = guestfs.GuestFS ()
9681 g.add_drive (\"guest.img\")
9683 # Launch the qemu subprocess and wait for it to become ready:
9686 # Now you can issue commands, for example:
9691 import libguestfsmod
9694 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
9696 def __init__ (self):
9697 \"\"\"Create a new libguestfs handle.\"\"\"
9698 self._o = libguestfsmod.create ()
9701 libguestfsmod.close (self._o)
9706 fun (name, style, _, flags, _, _, longdesc) ->
9708 generate_py_call_args ~handle:"self" (snd style);
9711 if not (List.mem NotInDocs flags) then (
9712 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9714 match fst style with
9715 | RErr | RInt _ | RInt64 _ | RBool _
9716 | RConstOptString _ | RConstString _
9717 | RString _ | RBufferOut _ -> doc
9719 doc ^ "\n\nThis function returns a list of strings."
9720 | RStruct (_, typ) ->
9721 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
9722 | RStructList (_, typ) ->
9723 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
9725 doc ^ "\n\nThis function returns a dictionary." in
9727 if List.mem ProtocolLimitWarning flags then
9728 doc ^ "\n\n" ^ protocol_limit_warning
9731 if List.mem DangerWillRobinson flags then
9732 doc ^ "\n\n" ^ danger_will_robinson
9735 match deprecation_notice flags with
9737 | Some txt -> doc ^ "\n\n" ^ txt in
9738 let doc = pod2text ~width:60 name doc in
9739 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
9740 let doc = String.concat "\n " doc in
9741 pr " u\"\"\"%s\"\"\"\n" doc;
9743 pr " return libguestfsmod.%s " name;
9744 generate_py_call_args ~handle:"self._o" (snd style);
9749 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
9750 and generate_py_call_args ~handle args =
9752 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9755 (* Useful if you need the longdesc POD text as plain text. Returns a
9758 * Because this is very slow (the slowest part of autogeneration),
9759 * we memoize the results.
9761 and pod2text ~width name longdesc =
9762 let key = width, name, longdesc in
9763 try Hashtbl.find pod2text_memo key
9765 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
9766 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
9768 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
9769 let chan = open_process_in cmd in
9770 let lines = ref [] in
9772 let line = input_line chan in
9773 if i = 1 then (* discard the first line of output *)
9776 let line = triml line in
9777 lines := line :: !lines;
9780 let lines = try loop 1 with End_of_file -> List.rev !lines in
9782 (match close_process_in chan with
9785 failwithf "pod2text: process exited with non-zero status (%d)" i
9786 | WSIGNALED i | WSTOPPED i ->
9787 failwithf "pod2text: process signalled or stopped by signal %d" i
9789 Hashtbl.add pod2text_memo key lines;
9790 pod2text_memo_updated ();
9793 (* Generate ruby bindings. *)
9794 and generate_ruby_c () =
9795 generate_header CStyle LGPLv2plus;
9803 #include \"guestfs.h\"
9805 #include \"extconf.h\"
9807 /* For Ruby < 1.9 */
9809 #define RARRAY_LEN(r) (RARRAY((r))->len)
9812 static VALUE m_guestfs; /* guestfs module */
9813 static VALUE c_guestfs; /* guestfs_h handle */
9814 static VALUE e_Error; /* used for all errors */
9816 static void ruby_guestfs_free (void *p)
9819 guestfs_close ((guestfs_h *) p);
9822 static VALUE ruby_guestfs_create (VALUE m)
9826 g = guestfs_create ();
9828 rb_raise (e_Error, \"failed to create guestfs handle\");
9830 /* Don't print error messages to stderr by default. */
9831 guestfs_set_error_handler (g, NULL, NULL);
9833 /* Wrap it, and make sure the close function is called when the
9836 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
9839 static VALUE ruby_guestfs_close (VALUE gv)
9842 Data_Get_Struct (gv, guestfs_h, g);
9844 ruby_guestfs_free (g);
9845 DATA_PTR (gv) = NULL;
9853 fun (name, style, _, _, _, _, _) ->
9854 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
9855 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
9858 pr " guestfs_h *g;\n";
9859 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
9861 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
9867 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
9868 pr " Check_Type (%sv, T_STRING);\n" n;
9869 pr " const char *%s = StringValueCStr (%sv);\n" n n;
9871 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9872 pr " \"%s\", \"%s\");\n" n name
9874 pr " Check_Type (%sv, T_STRING);\n" n;
9875 pr " const char *%s = RSTRING (%sv)->ptr;\n" n n;
9877 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9878 pr " \"%s\", \"%s\");\n" n name;
9879 pr " size_t %s_size = RSTRING (%sv)->len;\n" n n
9881 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
9882 | StringList n | DeviceList n ->
9883 pr " char **%s;\n" n;
9884 pr " Check_Type (%sv, T_ARRAY);\n" n;
9886 pr " int i, len;\n";
9887 pr " len = RARRAY_LEN (%sv);\n" n;
9888 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
9890 pr " for (i = 0; i < len; ++i) {\n";
9891 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
9892 pr " %s[i] = StringValueCStr (v);\n" n;
9894 pr " %s[len] = NULL;\n" n;
9897 pr " int %s = RTEST (%sv);\n" n n
9899 pr " int %s = NUM2INT (%sv);\n" n n
9901 pr " long long %s = NUM2LL (%sv);\n" n n
9906 match fst style with
9907 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9908 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9909 | RConstString _ | RConstOptString _ ->
9910 pr " const char *r;\n"; "NULL"
9911 | RString _ -> pr " char *r;\n"; "NULL"
9912 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9913 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9914 | RStructList (_, typ) ->
9915 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9918 pr " size_t size;\n";
9922 pr " r = guestfs_%s " name;
9923 generate_c_call_args ~handle:"g" style;
9928 | Pathname _ | Device _ | Dev_or_Path _ | String _
9929 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9931 | StringList n | DeviceList n ->
9932 pr " free (%s);\n" n
9935 pr " if (r == %s)\n" error_code;
9936 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
9939 (match fst style with
9941 pr " return Qnil;\n"
9942 | RInt _ | RBool _ ->
9943 pr " return INT2NUM (r);\n"
9945 pr " return ULL2NUM (r);\n"
9947 pr " return rb_str_new2 (r);\n";
9948 | RConstOptString _ ->
9950 pr " return rb_str_new2 (r);\n";
9952 pr " return Qnil;\n";
9954 pr " VALUE rv = rb_str_new2 (r);\n";
9958 pr " int i, len = 0;\n";
9959 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
9960 pr " VALUE rv = rb_ary_new2 (len);\n";
9961 pr " for (i = 0; r[i] != NULL; ++i) {\n";
9962 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
9963 pr " free (r[i]);\n";
9967 | RStruct (_, typ) ->
9968 let cols = cols_of_struct typ in
9969 generate_ruby_struct_code typ cols
9970 | RStructList (_, typ) ->
9971 let cols = cols_of_struct typ in
9972 generate_ruby_struct_list_code typ cols
9974 pr " VALUE rv = rb_hash_new ();\n";
9976 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
9977 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
9978 pr " free (r[i]);\n";
9979 pr " free (r[i+1]);\n";
9984 pr " VALUE rv = rb_str_new (r, size);\n";
9994 /* Initialize the module. */
9995 void Init__guestfs ()
9997 m_guestfs = rb_define_module (\"Guestfs\");
9998 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
9999 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
10001 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
10002 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
10005 (* Define the rest of the methods. *)
10007 fun (name, style, _, _, _, _, _) ->
10008 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
10009 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
10014 (* Ruby code to return a struct. *)
10015 and generate_ruby_struct_code typ cols =
10016 pr " VALUE rv = rb_hash_new ();\n";
10020 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
10022 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
10024 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
10025 | name, (FBytes|FUInt64) ->
10026 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10028 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
10030 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
10032 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
10033 | name, FOptPercent ->
10034 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
10035 | name, FChar -> (* XXX wrong? *)
10036 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10038 pr " guestfs_free_%s (r);\n" typ;
10041 (* Ruby code to return a struct list. *)
10042 and generate_ruby_struct_list_code typ cols =
10043 pr " VALUE rv = rb_ary_new2 (r->len);\n";
10045 pr " for (i = 0; i < r->len; ++i) {\n";
10046 pr " VALUE hv = rb_hash_new ();\n";
10050 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
10052 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
10054 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
10055 | name, (FBytes|FUInt64) ->
10056 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10058 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
10060 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
10062 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
10063 | name, FOptPercent ->
10064 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
10065 | name, FChar -> (* XXX wrong? *)
10066 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10068 pr " rb_ary_push (rv, hv);\n";
10070 pr " guestfs_free_%s_list (r);\n" typ;
10073 (* Generate Java bindings GuestFS.java file. *)
10074 and generate_java_java () =
10075 generate_header CStyle LGPLv2plus;
10078 package com.redhat.et.libguestfs;
10080 import java.util.HashMap;
10081 import com.redhat.et.libguestfs.LibGuestFSException;
10082 import com.redhat.et.libguestfs.PV;
10083 import com.redhat.et.libguestfs.VG;
10084 import com.redhat.et.libguestfs.LV;
10085 import com.redhat.et.libguestfs.Stat;
10086 import com.redhat.et.libguestfs.StatVFS;
10087 import com.redhat.et.libguestfs.IntBool;
10088 import com.redhat.et.libguestfs.Dirent;
10091 * The GuestFS object is a libguestfs handle.
10095 public class GuestFS {
10096 // Load the native code.
10098 System.loadLibrary (\"guestfs_jni\");
10102 * The native guestfs_h pointer.
10107 * Create a libguestfs handle.
10109 * @throws LibGuestFSException
10111 public GuestFS () throws LibGuestFSException
10115 private native long _create () throws LibGuestFSException;
10118 * Close a libguestfs handle.
10120 * You can also leave handles to be collected by the garbage
10121 * collector, but this method ensures that the resources used
10122 * by the handle are freed up immediately. If you call any
10123 * other methods after closing the handle, you will get an
10126 * @throws LibGuestFSException
10128 public void close () throws LibGuestFSException
10134 private native void _close (long g) throws LibGuestFSException;
10136 public void finalize () throws LibGuestFSException
10144 fun (name, style, _, flags, _, shortdesc, longdesc) ->
10145 if not (List.mem NotInDocs flags); then (
10146 let doc = replace_str longdesc "C<guestfs_" "C<g." in
10148 if List.mem ProtocolLimitWarning flags then
10149 doc ^ "\n\n" ^ protocol_limit_warning
10152 if List.mem DangerWillRobinson flags then
10153 doc ^ "\n\n" ^ danger_will_robinson
10156 match deprecation_notice flags with
10158 | Some txt -> doc ^ "\n\n" ^ txt in
10159 let doc = pod2text ~width:60 name doc in
10160 let doc = List.map ( (* RHBZ#501883 *)
10163 | nonempty -> nonempty
10165 let doc = String.concat "\n * " doc in
10168 pr " * %s\n" shortdesc;
10171 pr " * @throws LibGuestFSException\n";
10175 generate_java_prototype ~public:true ~semicolon:false name style;
10178 pr " if (g == 0)\n";
10179 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
10182 if fst style <> RErr then pr "return ";
10184 generate_java_call_args ~handle:"g" (snd style);
10188 generate_java_prototype ~privat:true ~native:true name style;
10195 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
10196 and generate_java_call_args ~handle args =
10198 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
10201 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
10202 ?(semicolon=true) name style =
10203 if privat then pr "private ";
10204 if public then pr "public ";
10205 if native then pr "native ";
10208 (match fst style with
10209 | RErr -> pr "void ";
10210 | RInt _ -> pr "int ";
10211 | RInt64 _ -> pr "long ";
10212 | RBool _ -> pr "boolean ";
10213 | RConstString _ | RConstOptString _ | RString _
10214 | RBufferOut _ -> pr "String ";
10215 | RStringList _ -> pr "String[] ";
10216 | RStruct (_, typ) ->
10217 let name = java_name_of_struct typ in
10219 | RStructList (_, typ) ->
10220 let name = java_name_of_struct typ in
10222 | RHashtable _ -> pr "HashMap<String,String> ";
10225 if native then pr "_%s " name else pr "%s " name;
10227 let needs_comma = ref false in
10230 needs_comma := true
10236 if !needs_comma then pr ", ";
10237 needs_comma := true;
10241 | Device n | Dev_or_Path n
10249 | StringList n | DeviceList n ->
10260 pr " throws LibGuestFSException";
10261 if semicolon then pr ";"
10263 and generate_java_struct jtyp cols () =
10264 generate_header CStyle LGPLv2plus;
10267 package com.redhat.et.libguestfs;
10270 * Libguestfs %s structure.
10282 | name, FBuffer -> pr " public String %s;\n" name
10283 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
10284 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
10285 | name, FChar -> pr " public char %s;\n" name
10286 | name, FOptPercent ->
10287 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
10288 pr " public float %s;\n" name
10293 and generate_java_c () =
10294 generate_header CStyle LGPLv2plus;
10298 #include <stdlib.h>
10299 #include <string.h>
10301 #include \"com_redhat_et_libguestfs_GuestFS.h\"
10302 #include \"guestfs.h\"
10304 /* Note that this function returns. The exception is not thrown
10305 * until after the wrapper function returns.
10308 throw_exception (JNIEnv *env, const char *msg)
10311 cl = (*env)->FindClass (env,
10312 \"com/redhat/et/libguestfs/LibGuestFSException\");
10313 (*env)->ThrowNew (env, cl, msg);
10316 JNIEXPORT jlong JNICALL
10317 Java_com_redhat_et_libguestfs_GuestFS__1create
10318 (JNIEnv *env, jobject obj)
10322 g = guestfs_create ();
10324 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
10327 guestfs_set_error_handler (g, NULL, NULL);
10328 return (jlong) (long) g;
10331 JNIEXPORT void JNICALL
10332 Java_com_redhat_et_libguestfs_GuestFS__1close
10333 (JNIEnv *env, jobject obj, jlong jg)
10335 guestfs_h *g = (guestfs_h *) (long) jg;
10342 fun (name, style, _, _, _, _, _) ->
10344 (match fst style with
10345 | RErr -> pr "void ";
10346 | RInt _ -> pr "jint ";
10347 | RInt64 _ -> pr "jlong ";
10348 | RBool _ -> pr "jboolean ";
10349 | RConstString _ | RConstOptString _ | RString _
10350 | RBufferOut _ -> pr "jstring ";
10351 | RStruct _ | RHashtable _ ->
10353 | RStringList _ | RStructList _ ->
10354 pr "jobjectArray ";
10357 pr "Java_com_redhat_et_libguestfs_GuestFS_";
10358 pr "%s" (replace_str ("_" ^ name) "_" "_1");
10360 pr " (JNIEnv *env, jobject obj, jlong jg";
10364 | Device n | Dev_or_Path n
10369 pr ", jstring j%s" n
10371 pr ", jbyteArray j%s" n
10372 | StringList n | DeviceList n ->
10373 pr ", jobjectArray j%s" n
10375 pr ", jboolean j%s" n
10383 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
10384 let error_code, no_ret =
10385 match fst style with
10386 | RErr -> pr " int r;\n"; "-1", ""
10388 | RInt _ -> pr " int r;\n"; "-1", "0"
10389 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
10390 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
10391 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
10393 pr " jstring jr;\n";
10394 pr " char *r;\n"; "NULL", "NULL"
10396 pr " jobjectArray jr;\n";
10397 pr " int r_len;\n";
10398 pr " jclass cl;\n";
10399 pr " jstring jstr;\n";
10400 pr " char **r;\n"; "NULL", "NULL"
10401 | RStruct (_, typ) ->
10402 pr " jobject jr;\n";
10403 pr " jclass cl;\n";
10404 pr " jfieldID fl;\n";
10405 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
10406 | RStructList (_, typ) ->
10407 pr " jobjectArray jr;\n";
10408 pr " jclass cl;\n";
10409 pr " jfieldID fl;\n";
10410 pr " jobject jfl;\n";
10411 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
10412 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
10414 pr " jstring jr;\n";
10416 pr " size_t size;\n";
10421 | Device n | Dev_or_Path n
10426 pr " const char *%s;\n" n
10428 pr " jbyte *%s;\n" n;
10429 pr " size_t %s_size;\n" n
10430 | StringList n | DeviceList n ->
10431 pr " int %s_len;\n" n;
10432 pr " const char **%s;\n" n
10437 pr " int64_t %s;\n" n
10441 (match fst style with
10442 | RStringList _ | RStructList _ -> true
10443 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
10444 | RConstOptString _
10445 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
10446 List.exists (function
10447 | StringList _ -> true
10448 | DeviceList _ -> true
10449 | _ -> false) (snd style) in
10455 (* Get the parameters. *)
10459 | Device n | Dev_or_Path n
10463 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
10465 (* This is completely undocumented, but Java null becomes
10466 * a NULL parameter.
10468 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
10470 pr " %s = (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
10471 pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
10472 | StringList n | DeviceList n ->
10473 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
10474 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
10475 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10476 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10478 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
10480 pr " %s[%s_len] = NULL;\n" n n;
10484 pr " %s = j%s;\n" n n
10487 (* Make the call. *)
10488 pr " r = guestfs_%s " name;
10489 generate_c_call_args ~handle:"g" style;
10492 (* Release the parameters. *)
10496 | Device n | Dev_or_Path n
10500 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10502 pr " if (j%s)\n" n;
10503 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10505 pr " (*env)->ReleaseByteArrayElements (env, j%s, %s, 0);\n" n n
10506 | StringList n | DeviceList n ->
10507 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10508 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10510 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
10512 pr " free (%s);\n" n
10518 (* Check for errors. *)
10519 pr " if (r == %s) {\n" error_code;
10520 pr " throw_exception (env, guestfs_last_error (g));\n";
10521 pr " return %s;\n" no_ret;
10524 (* Return value. *)
10525 (match fst style with
10527 | RInt _ -> pr " return (jint) r;\n"
10528 | RBool _ -> pr " return (jboolean) r;\n"
10529 | RInt64 _ -> pr " return (jlong) r;\n"
10530 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
10531 | RConstOptString _ ->
10532 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
10534 pr " jr = (*env)->NewStringUTF (env, r);\n";
10538 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
10539 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
10540 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
10541 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
10542 pr " for (i = 0; i < r_len; ++i) {\n";
10543 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
10544 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
10545 pr " free (r[i]);\n";
10549 | RStruct (_, typ) ->
10550 let jtyp = java_name_of_struct typ in
10551 let cols = cols_of_struct typ in
10552 generate_java_struct_return typ jtyp cols
10553 | RStructList (_, typ) ->
10554 let jtyp = java_name_of_struct typ in
10555 let cols = cols_of_struct typ in
10556 generate_java_struct_list_return typ jtyp cols
10559 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
10560 pr " return NULL;\n"
10562 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
10571 and generate_java_struct_return typ jtyp cols =
10572 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10573 pr " jr = (*env)->AllocObject (env, cl);\n";
10577 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10578 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
10581 pr " char s[33];\n";
10582 pr " memcpy (s, r->%s, 32);\n" name;
10583 pr " s[32] = 0;\n";
10584 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10585 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10589 pr " int len = r->%s_len;\n" name;
10590 pr " char s[len+1];\n";
10591 pr " memcpy (s, r->%s, len);\n" name;
10592 pr " s[len] = 0;\n";
10593 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10594 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10596 | name, (FBytes|FUInt64|FInt64) ->
10597 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10598 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10599 | name, (FUInt32|FInt32) ->
10600 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10601 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10602 | name, FOptPercent ->
10603 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10604 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
10606 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10607 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10612 and generate_java_struct_list_return typ jtyp cols =
10613 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10614 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
10615 pr " for (i = 0; i < r->len; ++i) {\n";
10616 pr " jfl = (*env)->AllocObject (env, cl);\n";
10620 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10621 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
10624 pr " char s[33];\n";
10625 pr " memcpy (s, r->val[i].%s, 32);\n" name;
10626 pr " s[32] = 0;\n";
10627 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10628 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10632 pr " int len = r->val[i].%s_len;\n" name;
10633 pr " char s[len+1];\n";
10634 pr " memcpy (s, r->val[i].%s, len);\n" name;
10635 pr " s[len] = 0;\n";
10636 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10637 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10639 | name, (FBytes|FUInt64|FInt64) ->
10640 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10641 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10642 | name, (FUInt32|FInt32) ->
10643 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10644 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10645 | name, FOptPercent ->
10646 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10647 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
10649 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10650 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10652 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
10654 pr " guestfs_free_%s_list (r);\n" typ;
10657 and generate_java_makefile_inc () =
10658 generate_header HashStyle GPLv2plus;
10660 pr "java_built_sources = \\\n";
10663 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
10665 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
10667 and generate_haskell_hs () =
10668 generate_header HaskellStyle LGPLv2plus;
10670 (* XXX We only know how to generate partial FFI for Haskell
10671 * at the moment. Please help out!
10673 let can_generate style =
10677 | RInt64 _, _ -> true
10679 | RConstString _, _
10680 | RConstOptString _, _
10686 | RBufferOut _, _ -> false in
10689 {-# INCLUDE <guestfs.h> #-}
10690 {-# LANGUAGE ForeignFunctionInterface #-}
10695 (* List out the names of the actions we want to export. *)
10697 fun (name, style, _, _, _, _, _) ->
10698 if can_generate style then pr ",\n %s" name
10704 -- Unfortunately some symbols duplicate ones already present
10705 -- in Prelude. We don't know which, so we hard-code a list
10707 import Prelude hiding (truncate)
10711 import Foreign.C.Types
10713 import Control.Exception
10714 import Data.Typeable
10716 data GuestfsS = GuestfsS -- represents the opaque C struct
10717 type GuestfsP = Ptr GuestfsS -- guestfs_h *
10718 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
10720 -- XXX define properly later XXX
10724 data IntBool = IntBool
10726 data StatVFS = StatVFS
10727 data Hashtable = Hashtable
10729 foreign import ccall unsafe \"guestfs_create\" c_create
10731 foreign import ccall unsafe \"&guestfs_close\" c_close
10732 :: FunPtr (GuestfsP -> IO ())
10733 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
10734 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
10736 create :: IO GuestfsH
10739 c_set_error_handler p nullPtr nullPtr
10740 h <- newForeignPtr c_close p
10743 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
10744 :: GuestfsP -> IO CString
10746 -- last_error :: GuestfsH -> IO (Maybe String)
10747 -- last_error h = do
10748 -- str <- withForeignPtr h (\\p -> c_last_error p)
10749 -- maybePeek peekCString str
10751 last_error :: GuestfsH -> IO (String)
10753 str <- withForeignPtr h (\\p -> c_last_error p)
10754 if (str == nullPtr)
10755 then return \"no error\"
10756 else peekCString str
10760 (* Generate wrappers for each foreign function. *)
10762 fun (name, style, _, _, _, _, _) ->
10763 if can_generate style then (
10764 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
10766 generate_haskell_prototype ~handle:"GuestfsP" style;
10770 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
10772 pr "%s %s = do\n" name
10773 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
10775 (* Convert pointer arguments using with* functions. *)
10780 | Pathname n | Device n | Dev_or_Path n | String n ->
10781 pr "withCString %s $ \\%s -> " n n
10783 pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
10784 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
10785 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
10786 | Bool _ | Int _ | Int64 _ -> ()
10788 (* Convert integer arguments. *)
10792 | Bool n -> sprintf "(fromBool %s)" n
10793 | Int n -> sprintf "(fromIntegral %s)" n
10794 | Int64 n -> sprintf "(fromIntegral %s)" n
10795 | FileIn n | FileOut n
10796 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
10797 | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
10799 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
10800 (String.concat " " ("p" :: args));
10801 (match fst style with
10802 | RErr | RInt _ | RInt64 _ | RBool _ ->
10803 pr " if (r == -1)\n";
10805 pr " err <- last_error h\n";
10807 | RConstString _ | RConstOptString _ | RString _
10808 | RStringList _ | RStruct _
10809 | RStructList _ | RHashtable _ | RBufferOut _ ->
10810 pr " if (r == nullPtr)\n";
10812 pr " err <- last_error h\n";
10815 (match fst style with
10817 pr " else return ()\n"
10819 pr " else return (fromIntegral r)\n"
10821 pr " else return (fromIntegral r)\n"
10823 pr " else return (toBool r)\n"
10825 | RConstOptString _
10832 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
10838 and generate_haskell_prototype ~handle ?(hs = false) style =
10839 pr "%s -> " handle;
10840 let string = if hs then "String" else "CString" in
10841 let int = if hs then "Int" else "CInt" in
10842 let bool = if hs then "Bool" else "CInt" in
10843 let int64 = if hs then "Integer" else "Int64" in
10847 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
10849 if hs then pr "String"
10850 else pr "CString -> CInt"
10851 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
10852 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
10853 | Bool _ -> pr "%s" bool
10854 | Int _ -> pr "%s" int
10855 | Int64 _ -> pr "%s" int
10856 | FileIn _ -> pr "%s" string
10857 | FileOut _ -> pr "%s" string
10862 (match fst style with
10863 | RErr -> if not hs then pr "CInt"
10864 | RInt _ -> pr "%s" int
10865 | RInt64 _ -> pr "%s" int64
10866 | RBool _ -> pr "%s" bool
10867 | RConstString _ -> pr "%s" string
10868 | RConstOptString _ -> pr "Maybe %s" string
10869 | RString _ -> pr "%s" string
10870 | RStringList _ -> pr "[%s]" string
10871 | RStruct (_, typ) ->
10872 let name = java_name_of_struct typ in
10874 | RStructList (_, typ) ->
10875 let name = java_name_of_struct typ in
10877 | RHashtable _ -> pr "Hashtable"
10878 | RBufferOut _ -> pr "%s" string
10882 and generate_csharp () =
10883 generate_header CPlusPlusStyle LGPLv2plus;
10885 (* XXX Make this configurable by the C# assembly users. *)
10886 let library = "libguestfs.so.0" in
10889 // These C# bindings are highly experimental at present.
10891 // Firstly they only work on Linux (ie. Mono). In order to get them
10892 // to work on Windows (ie. .Net) you would need to port the library
10893 // itself to Windows first.
10895 // The second issue is that some calls are known to be incorrect and
10896 // can cause Mono to segfault. Particularly: calls which pass or
10897 // return string[], or return any structure value. This is because
10898 // we haven't worked out the correct way to do this from C#.
10900 // The third issue is that when compiling you get a lot of warnings.
10901 // We are not sure whether the warnings are important or not.
10903 // Fourthly we do not routinely build or test these bindings as part
10904 // of the make && make check cycle, which means that regressions might
10907 // Suggestions and patches are welcome.
10911 // gmcs Libguestfs.cs
10912 // mono Libguestfs.exe
10914 // (You'll probably want to add a Test class / static main function
10915 // otherwise this won't do anything useful).
10919 using System.Runtime.InteropServices;
10920 using System.Runtime.Serialization;
10921 using System.Collections;
10925 class Error : System.ApplicationException
10927 public Error (string message) : base (message) {}
10928 protected Error (SerializationInfo info, StreamingContext context) {}
10935 [DllImport (\"%s\")]
10936 static extern IntPtr guestfs_create ();
10940 _handle = guestfs_create ();
10941 if (_handle == IntPtr.Zero)
10942 throw new Error (\"could not create guestfs handle\");
10945 [DllImport (\"%s\")]
10946 static extern void guestfs_close (IntPtr h);
10950 guestfs_close (_handle);
10953 [DllImport (\"%s\")]
10954 static extern string guestfs_last_error (IntPtr h);
10956 " library library library;
10958 (* Generate C# structure bindings. We prefix struct names with
10959 * underscore because C# cannot have conflicting struct names and
10960 * method names (eg. "class stat" and "stat").
10964 pr " [StructLayout (LayoutKind.Sequential)]\n";
10965 pr " public class _%s {\n" typ;
10968 | name, FChar -> pr " char %s;\n" name
10969 | name, FString -> pr " string %s;\n" name
10971 pr " uint %s_len;\n" name;
10972 pr " string %s;\n" name
10974 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
10975 pr " string %s;\n" name
10976 | name, FUInt32 -> pr " uint %s;\n" name
10977 | name, FInt32 -> pr " int %s;\n" name
10978 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
10979 | name, FInt64 -> pr " long %s;\n" name
10980 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
10986 (* Generate C# function bindings. *)
10988 fun (name, style, _, _, _, shortdesc, _) ->
10989 let rec csharp_return_type () =
10990 match fst style with
10992 | RBool n -> "bool"
10994 | RInt64 n -> "long"
10996 | RConstOptString n
10998 | RBufferOut n -> "string"
10999 | RStruct (_,n) -> "_" ^ n
11000 | RHashtable n -> "Hashtable"
11001 | RStringList n -> "string[]"
11002 | RStructList (_,n) -> sprintf "_%s[]" n
11004 and c_return_type () =
11005 match fst style with
11009 | RInt64 _ -> "long"
11011 | RConstOptString _
11013 | RBufferOut _ -> "string"
11014 | RStruct (_,n) -> "_" ^ n
11016 | RStringList _ -> "string[]"
11017 | RStructList (_,n) -> sprintf "_%s[]" n
11019 and c_error_comparison () =
11020 match fst style with
11024 | RInt64 _ -> "== -1"
11026 | RConstOptString _
11032 | RStructList (_,_) -> "== null"
11034 and generate_extern_prototype () =
11035 pr " static extern %s guestfs_%s (IntPtr h"
11036 (c_return_type ()) name;
11039 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11040 | FileIn n | FileOut n
11042 pr ", [In] string %s" n
11043 | StringList n | DeviceList n ->
11044 pr ", [In] string[] %s" n
11054 and generate_public_prototype () =
11055 pr " public %s %s (" (csharp_return_type ()) name;
11056 let comma = ref false in
11058 if !comma then pr ", ";
11063 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11064 | FileIn n | FileOut n
11066 next (); pr "string %s" n
11067 | StringList n | DeviceList n ->
11068 next (); pr "string[] %s" n
11070 next (); pr "bool %s" n
11072 next (); pr "int %s" n
11074 next (); pr "long %s" n
11078 and generate_call () =
11079 pr "guestfs_%s (_handle" name;
11080 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
11084 pr " [DllImport (\"%s\")]\n" library;
11085 generate_extern_prototype ();
11087 pr " /// <summary>\n";
11088 pr " /// %s\n" shortdesc;
11089 pr " /// </summary>\n";
11090 generate_public_prototype ();
11092 pr " %s r;\n" (c_return_type ());
11095 pr " if (r %s)\n" (c_error_comparison ());
11096 pr " throw new Error (guestfs_last_error (_handle));\n";
11097 (match fst style with
11100 pr " return r != 0 ? true : false;\n"
11102 pr " Hashtable rr = new Hashtable ();\n";
11103 pr " for (int i = 0; i < r.Length; i += 2)\n";
11104 pr " rr.Add (r[i], r[i+1]);\n";
11106 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
11107 | RString _ | RBufferOut _ | RStruct _ | RStringList _
11113 ) all_functions_sorted;
11119 and generate_bindtests () =
11120 generate_header CStyle LGPLv2plus;
11124 #include <stdlib.h>
11125 #include <inttypes.h>
11126 #include <string.h>
11128 #include \"guestfs.h\"
11129 #include \"guestfs-internal.h\"
11130 #include \"guestfs-internal-actions.h\"
11131 #include \"guestfs_protocol.h\"
11133 #define error guestfs_error
11134 #define safe_calloc guestfs_safe_calloc
11135 #define safe_malloc guestfs_safe_malloc
11138 print_strings (char *const *argv)
11143 for (argc = 0; argv[argc] != NULL; ++argc) {
11144 if (argc > 0) printf (\", \");
11145 printf (\"\\\"%%s\\\"\", argv[argc]);
11150 /* The test0 function prints its parameters to stdout. */
11154 match test_functions with
11155 | [] -> assert false
11156 | test0 :: tests -> test0, tests in
11159 let (name, style, _, _, _, _, _) = test0 in
11160 generate_prototype ~extern:false ~semicolon:false ~newline:true
11161 ~handle:"g" ~prefix:"guestfs__" name style;
11166 | Device n | Dev_or_Path n
11169 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
11173 pr " for (i = 0; i < %s_size; ++i)\n" n;
11174 pr " printf (\"<%%02x>\", %s[i]);\n" n;
11175 pr " printf (\"\\n\");\n";
11177 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
11178 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
11179 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
11180 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
11181 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
11183 pr " /* Java changes stdout line buffering so we need this: */\n";
11184 pr " fflush (stdout);\n";
11190 fun (name, style, _, _, _, _, _) ->
11191 if String.sub name (String.length name - 3) 3 <> "err" then (
11192 pr "/* Test normal return. */\n";
11193 generate_prototype ~extern:false ~semicolon:false ~newline:true
11194 ~handle:"g" ~prefix:"guestfs__" name style;
11196 (match fst style with
11201 pr " sscanf (val, \"%%d\", &r);\n";
11204 pr " int64_t r;\n";
11205 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
11208 pr " return STREQ (val, \"true\");\n"
11210 | RConstOptString _ ->
11211 (* Can't return the input string here. Return a static
11212 * string so we ensure we get a segfault if the caller
11213 * tries to free it.
11215 pr " return \"static string\";\n"
11217 pr " return strdup (val);\n"
11219 pr " char **strs;\n";
11221 pr " sscanf (val, \"%%d\", &n);\n";
11222 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
11223 pr " for (i = 0; i < n; ++i) {\n";
11224 pr " strs[i] = safe_malloc (g, 16);\n";
11225 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
11227 pr " strs[n] = NULL;\n";
11228 pr " return strs;\n"
11229 | RStruct (_, typ) ->
11230 pr " struct guestfs_%s *r;\n" typ;
11231 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11233 | RStructList (_, typ) ->
11234 pr " struct guestfs_%s_list *r;\n" typ;
11235 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11236 pr " sscanf (val, \"%%d\", &r->len);\n";
11237 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
11240 pr " char **strs;\n";
11242 pr " sscanf (val, \"%%d\", &n);\n";
11243 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
11244 pr " for (i = 0; i < n; ++i) {\n";
11245 pr " strs[i*2] = safe_malloc (g, 16);\n";
11246 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
11247 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
11248 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
11250 pr " strs[n*2] = NULL;\n";
11251 pr " return strs;\n"
11253 pr " return strdup (val);\n"
11258 pr "/* Test error return. */\n";
11259 generate_prototype ~extern:false ~semicolon:false ~newline:true
11260 ~handle:"g" ~prefix:"guestfs__" name style;
11262 pr " error (g, \"error\");\n";
11263 (match fst style with
11264 | RErr | RInt _ | RInt64 _ | RBool _ ->
11266 | RConstString _ | RConstOptString _
11267 | RString _ | RStringList _ | RStruct _
11271 pr " return NULL;\n"
11278 and generate_ocaml_bindtests () =
11279 generate_header OCamlStyle GPLv2plus;
11283 let g = Guestfs.create () in
11287 String.concat " " (
11290 | CallString s -> "\"" ^ s ^ "\""
11291 | CallOptString None -> "None"
11292 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
11293 | CallStringList xs ->
11294 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
11295 | CallInt i when i >= 0 -> string_of_int i
11296 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
11297 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
11298 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
11299 | CallBool b -> string_of_bool b
11300 | CallBuffer s -> sprintf "%S" s
11305 generate_lang_bindtests (
11306 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
11309 pr "print_endline \"EOF\"\n"
11311 and generate_perl_bindtests () =
11312 pr "#!/usr/bin/perl -w\n";
11313 generate_header HashStyle GPLv2plus;
11320 my $g = Sys::Guestfs->new ();
11324 String.concat ", " (
11327 | CallString s -> "\"" ^ s ^ "\""
11328 | CallOptString None -> "undef"
11329 | CallOptString (Some s) -> sprintf "\"%s\"" s
11330 | CallStringList xs ->
11331 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11332 | CallInt i -> string_of_int i
11333 | CallInt64 i -> Int64.to_string i
11334 | CallBool b -> if b then "1" else "0"
11335 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11340 generate_lang_bindtests (
11341 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
11344 pr "print \"EOF\\n\"\n"
11346 and generate_python_bindtests () =
11347 generate_header HashStyle GPLv2plus;
11352 g = guestfs.GuestFS ()
11356 String.concat ", " (
11359 | CallString s -> "\"" ^ s ^ "\""
11360 | CallOptString None -> "None"
11361 | CallOptString (Some s) -> sprintf "\"%s\"" s
11362 | CallStringList xs ->
11363 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11364 | CallInt i -> string_of_int i
11365 | CallInt64 i -> Int64.to_string i
11366 | CallBool b -> if b then "1" else "0"
11367 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11372 generate_lang_bindtests (
11373 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
11376 pr "print \"EOF\"\n"
11378 and generate_ruby_bindtests () =
11379 generate_header HashStyle GPLv2plus;
11384 g = Guestfs::create()
11388 String.concat ", " (
11391 | CallString s -> "\"" ^ s ^ "\""
11392 | CallOptString None -> "nil"
11393 | CallOptString (Some s) -> sprintf "\"%s\"" s
11394 | CallStringList xs ->
11395 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11396 | CallInt i -> string_of_int i
11397 | CallInt64 i -> Int64.to_string i
11398 | CallBool b -> string_of_bool b
11399 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11404 generate_lang_bindtests (
11405 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
11408 pr "print \"EOF\\n\"\n"
11410 and generate_java_bindtests () =
11411 generate_header CStyle GPLv2plus;
11414 import com.redhat.et.libguestfs.*;
11416 public class Bindtests {
11417 public static void main (String[] argv)
11420 GuestFS g = new GuestFS ();
11424 String.concat ", " (
11427 | CallString s -> "\"" ^ s ^ "\""
11428 | CallOptString None -> "null"
11429 | CallOptString (Some s) -> sprintf "\"%s\"" s
11430 | CallStringList xs ->
11432 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
11433 | CallInt i -> string_of_int i
11434 | CallInt64 i -> Int64.to_string i
11435 | CallBool b -> string_of_bool b
11437 "new byte[] { " ^ String.concat "," (
11438 map_chars (fun c -> string_of_int (Char.code c)) s
11444 generate_lang_bindtests (
11445 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
11449 System.out.println (\"EOF\");
11451 catch (Exception exn) {
11452 System.err.println (exn);
11459 and generate_haskell_bindtests () =
11460 generate_header HaskellStyle GPLv2plus;
11463 module Bindtests where
11464 import qualified Guestfs
11467 g <- Guestfs.create
11471 String.concat " " (
11474 | CallString s -> "\"" ^ s ^ "\""
11475 | CallOptString None -> "Nothing"
11476 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
11477 | CallStringList xs ->
11478 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11479 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
11480 | CallInt i -> string_of_int i
11481 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
11482 | CallInt64 i -> Int64.to_string i
11483 | CallBool true -> "True"
11484 | CallBool false -> "False"
11485 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11490 generate_lang_bindtests (
11491 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
11494 pr " putStrLn \"EOF\"\n"
11496 (* Language-independent bindings tests - we do it this way to
11497 * ensure there is parity in testing bindings across all languages.
11499 and generate_lang_bindtests call =
11500 call "test0" [CallString "abc"; CallOptString (Some "def");
11501 CallStringList []; CallBool false;
11502 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11503 CallBuffer "abc\000abc"];
11504 call "test0" [CallString "abc"; CallOptString None;
11505 CallStringList []; CallBool false;
11506 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11507 CallBuffer "abc\000abc"];
11508 call "test0" [CallString ""; CallOptString (Some "def");
11509 CallStringList []; CallBool false;
11510 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11511 CallBuffer "abc\000abc"];
11512 call "test0" [CallString ""; CallOptString (Some "");
11513 CallStringList []; CallBool false;
11514 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11515 CallBuffer "abc\000abc"];
11516 call "test0" [CallString "abc"; CallOptString (Some "def");
11517 CallStringList ["1"]; CallBool false;
11518 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11519 CallBuffer "abc\000abc"];
11520 call "test0" [CallString "abc"; CallOptString (Some "def");
11521 CallStringList ["1"; "2"]; CallBool false;
11522 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11523 CallBuffer "abc\000abc"];
11524 call "test0" [CallString "abc"; CallOptString (Some "def");
11525 CallStringList ["1"]; CallBool true;
11526 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11527 CallBuffer "abc\000abc"];
11528 call "test0" [CallString "abc"; CallOptString (Some "def");
11529 CallStringList ["1"]; CallBool false;
11530 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456";
11531 CallBuffer "abc\000abc"];
11532 call "test0" [CallString "abc"; CallOptString (Some "def");
11533 CallStringList ["1"]; CallBool false;
11534 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456";
11535 CallBuffer "abc\000abc"];
11536 call "test0" [CallString "abc"; CallOptString (Some "def");
11537 CallStringList ["1"]; CallBool false;
11538 CallInt 1; CallInt64 1L; CallString "123"; CallString "456";
11539 CallBuffer "abc\000abc"];
11540 call "test0" [CallString "abc"; CallOptString (Some "def");
11541 CallStringList ["1"]; CallBool false;
11542 CallInt 2; CallInt64 2L; CallString "123"; CallString "456";
11543 CallBuffer "abc\000abc"];
11544 call "test0" [CallString "abc"; CallOptString (Some "def");
11545 CallStringList ["1"]; CallBool false;
11546 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456";
11547 CallBuffer "abc\000abc"];
11548 call "test0" [CallString "abc"; CallOptString (Some "def");
11549 CallStringList ["1"]; CallBool false;
11550 CallInt 0; CallInt64 0L; CallString ""; CallString "";
11551 CallBuffer "abc\000abc"]
11553 (* XXX Add here tests of the return and error functions. *)
11555 (* Code to generator bindings for virt-inspector. Currently only
11556 * implemented for OCaml code (for virt-p2v 2.0).
11558 let rng_input = "inspector/virt-inspector.rng"
11560 (* Read the input file and parse it into internal structures. This is
11561 * by no means a complete RELAX NG parser, but is just enough to be
11562 * able to parse the specific input file.
11565 | Element of string * rng list (* <element name=name/> *)
11566 | Attribute of string * rng list (* <attribute name=name/> *)
11567 | Interleave of rng list (* <interleave/> *)
11568 | ZeroOrMore of rng (* <zeroOrMore/> *)
11569 | OneOrMore of rng (* <oneOrMore/> *)
11570 | Optional of rng (* <optional/> *)
11571 | Choice of string list (* <choice><value/>*</choice> *)
11572 | Value of string (* <value>str</value> *)
11573 | Text (* <text/> *)
11575 let rec string_of_rng = function
11576 | Element (name, xs) ->
11577 "Element (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11578 | Attribute (name, xs) ->
11579 "Attribute (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11580 | Interleave xs -> "Interleave (" ^ string_of_rng_list xs ^ ")"
11581 | ZeroOrMore rng -> "ZeroOrMore (" ^ string_of_rng rng ^ ")"
11582 | OneOrMore rng -> "OneOrMore (" ^ string_of_rng rng ^ ")"
11583 | Optional rng -> "Optional (" ^ string_of_rng rng ^ ")"
11584 | Choice values -> "Choice [" ^ String.concat ", " values ^ "]"
11585 | Value value -> "Value \"" ^ value ^ "\""
11588 and string_of_rng_list xs =
11589 String.concat ", " (List.map string_of_rng xs)
11591 let rec parse_rng ?defines context = function
11593 | Xml.Element ("element", ["name", name], children) :: rest ->
11594 Element (name, parse_rng ?defines context children)
11595 :: parse_rng ?defines context rest
11596 | Xml.Element ("attribute", ["name", name], children) :: rest ->
11597 Attribute (name, parse_rng ?defines context children)
11598 :: parse_rng ?defines context rest
11599 | Xml.Element ("interleave", [], children) :: rest ->
11600 Interleave (parse_rng ?defines context children)
11601 :: parse_rng ?defines context rest
11602 | Xml.Element ("zeroOrMore", [], [child]) :: rest ->
11603 let rng = parse_rng ?defines context [child] in
11605 | [child] -> ZeroOrMore child :: parse_rng ?defines context rest
11607 failwithf "%s: <zeroOrMore> contains more than one child element"
11610 | Xml.Element ("oneOrMore", [], [child]) :: rest ->
11611 let rng = parse_rng ?defines context [child] in
11613 | [child] -> OneOrMore child :: parse_rng ?defines context rest
11615 failwithf "%s: <oneOrMore> contains more than one child element"
11618 | Xml.Element ("optional", [], [child]) :: rest ->
11619 let rng = parse_rng ?defines context [child] in
11621 | [child] -> Optional child :: parse_rng ?defines context rest
11623 failwithf "%s: <optional> contains more than one child element"
11626 | Xml.Element ("choice", [], children) :: rest ->
11627 let values = List.map (
11628 function Xml.Element ("value", [], [Xml.PCData value]) -> value
11630 failwithf "%s: can't handle anything except <value> in <choice>"
11634 :: parse_rng ?defines context rest
11635 | Xml.Element ("value", [], [Xml.PCData value]) :: rest ->
11636 Value value :: parse_rng ?defines context rest
11637 | Xml.Element ("text", [], []) :: rest ->
11638 Text :: parse_rng ?defines context rest
11639 | Xml.Element ("ref", ["name", name], []) :: rest ->
11640 (* Look up the reference. Because of limitations in this parser,
11641 * we can't handle arbitrarily nested <ref> yet. You can only
11642 * use <ref> from inside <start>.
11644 (match defines with
11646 failwithf "%s: contains <ref>, but no refs are defined yet" context
11648 let rng = StringMap.find name map in
11649 rng @ parse_rng ?defines context rest
11652 failwithf "%s: can't handle '%s' in schema" context (Xml.to_string x)
11655 let xml = Xml.parse_file rng_input in
11657 | Xml.Element ("grammar", _,
11658 Xml.Element ("start", _, gram) :: defines) ->
11659 (* The <define/> elements are referenced in the <start> section,
11660 * so build a map of those first.
11662 let defines = List.fold_left (
11664 function Xml.Element ("define", ["name", name], defn) ->
11665 StringMap.add name defn map
11667 failwithf "%s: expected <define name=name/>" rng_input
11668 ) StringMap.empty defines in
11669 let defines = StringMap.mapi parse_rng defines in
11671 (* Parse the <start> clause, passing the defines. *)
11672 parse_rng ~defines "<start>" gram
11674 failwithf "%s: input is not <grammar><start/><define>*</grammar>"
11677 let name_of_field = function
11678 | Element (name, _) | Attribute (name, _)
11679 | ZeroOrMore (Element (name, _))
11680 | OneOrMore (Element (name, _))
11681 | Optional (Element (name, _)) -> name
11682 | Optional (Attribute (name, _)) -> name
11683 | Text -> (* an unnamed field in an element *)
11686 failwithf "name_of_field failed at: %s" (string_of_rng rng)
11688 (* At the moment this function only generates OCaml types. However we
11689 * should parameterize it later so it can generate types/structs in a
11690 * variety of languages.
11692 let generate_types xs =
11693 (* A simple type is one that can be printed out directly, eg.
11694 * "string option". A complex type is one which has a name and has
11695 * to be defined via another toplevel definition, eg. a struct.
11697 * generate_type generates code for either simple or complex types.
11698 * In the simple case, it returns the string ("string option"). In
11699 * the complex case, it returns the name ("mountpoint"). In the
11700 * complex case it has to print out the definition before returning,
11701 * so it should only be called when we are at the beginning of a
11702 * new line (BOL context).
11704 let rec generate_type = function
11705 | Text -> (* string *)
11707 | Choice values -> (* [`val1|`val2|...] *)
11708 "[" ^ String.concat "|" (List.map ((^)"`") values) ^ "]", true
11709 | ZeroOrMore rng -> (* <rng> list *)
11710 let t, is_simple = generate_type rng in
11711 t ^ " list (* 0 or more *)", is_simple
11712 | OneOrMore rng -> (* <rng> list *)
11713 let t, is_simple = generate_type rng in
11714 t ^ " list (* 1 or more *)", is_simple
11715 (* virt-inspector hack: bool *)
11716 | Optional (Attribute (name, [Value "1"])) ->
11718 | Optional rng -> (* <rng> list *)
11719 let t, is_simple = generate_type rng in
11720 t ^ " option", is_simple
11721 (* type name = { fields ... } *)
11722 | Element (name, fields) when is_attrs_interleave fields ->
11723 generate_type_struct name (get_attrs_interleave fields)
11724 | Element (name, [field]) (* type name = field *)
11725 | Attribute (name, [field]) ->
11726 let t, is_simple = generate_type field in
11727 if is_simple then (t, true)
11729 pr "type %s = %s\n" name t;
11732 | Element (name, fields) -> (* type name = { fields ... } *)
11733 generate_type_struct name fields
11735 failwithf "generate_type failed at: %s" (string_of_rng rng)
11737 and is_attrs_interleave = function
11738 | [Interleave _] -> true
11739 | Attribute _ :: fields -> is_attrs_interleave fields
11740 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11743 and get_attrs_interleave = function
11744 | [Interleave fields] -> fields
11745 | ((Attribute _) as field) :: fields
11746 | ((Optional (Attribute _)) as field) :: fields ->
11747 field :: get_attrs_interleave fields
11748 | _ -> assert false
11750 and generate_types xs =
11751 List.iter (fun x -> ignore (generate_type x)) xs
11753 and generate_type_struct name fields =
11754 (* Calculate the types of the fields first. We have to do this
11755 * before printing anything so we are still in BOL context.
11757 let types = List.map fst (List.map generate_type fields) in
11759 (* Special case of a struct containing just a string and another
11760 * field. Turn it into an assoc list.
11763 | ["string"; other] ->
11764 let fname1, fname2 =
11766 | [f1; f2] -> name_of_field f1, name_of_field f2
11767 | _ -> assert false in
11768 pr "type %s = string * %s (* %s -> %s *)\n" name other fname1 fname2;
11772 pr "type %s = {\n" name;
11774 fun (field, ftype) ->
11775 let fname = name_of_field field in
11776 pr " %s_%s : %s;\n" name fname ftype
11777 ) (List.combine fields types);
11779 (* Return the name of this type, and
11780 * false because it's not a simple type.
11787 let generate_parsers xs =
11788 (* As for generate_type above, generate_parser makes a parser for
11789 * some type, and returns the name of the parser it has generated.
11790 * Because it (may) need to print something, it should always be
11791 * called in BOL context.
11793 let rec generate_parser = function
11794 | Text -> (* string *)
11795 "string_child_or_empty"
11796 | Choice values -> (* [`val1|`val2|...] *)
11797 sprintf "(fun x -> match Xml.pcdata (first_child x) with %s | str -> failwith (\"unexpected field value: \" ^ str))"
11799 (List.map (fun v -> sprintf "%S -> `%s" v v) values))
11800 | ZeroOrMore rng -> (* <rng> list *)
11801 let pa = generate_parser rng in
11802 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11803 | OneOrMore rng -> (* <rng> list *)
11804 let pa = generate_parser rng in
11805 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11806 (* virt-inspector hack: bool *)
11807 | Optional (Attribute (name, [Value "1"])) ->
11808 sprintf "(fun x -> try ignore (Xml.attrib x %S); true with Xml.No_attribute _ -> false)" name
11809 | Optional rng -> (* <rng> list *)
11810 let pa = generate_parser rng in
11811 sprintf "(function None -> None | Some x -> Some (%s x))" pa
11812 (* type name = { fields ... } *)
11813 | Element (name, fields) when is_attrs_interleave fields ->
11814 generate_parser_struct name (get_attrs_interleave fields)
11815 | Element (name, [field]) -> (* type name = field *)
11816 let pa = generate_parser field in
11817 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11818 pr "let %s =\n" parser_name;
11820 pr "let parse_%s = %s\n" name parser_name;
11822 | Attribute (name, [field]) ->
11823 let pa = generate_parser field in
11824 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11825 pr "let %s =\n" parser_name;
11827 pr "let parse_%s = %s\n" name parser_name;
11829 | Element (name, fields) -> (* type name = { fields ... } *)
11830 generate_parser_struct name ([], fields)
11832 failwithf "generate_parser failed at: %s" (string_of_rng rng)
11834 and is_attrs_interleave = function
11835 | [Interleave _] -> true
11836 | Attribute _ :: fields -> is_attrs_interleave fields
11837 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11840 and get_attrs_interleave = function
11841 | [Interleave fields] -> [], fields
11842 | ((Attribute _) as field) :: fields
11843 | ((Optional (Attribute _)) as field) :: fields ->
11844 let attrs, interleaves = get_attrs_interleave fields in
11845 (field :: attrs), interleaves
11846 | _ -> assert false
11848 and generate_parsers xs =
11849 List.iter (fun x -> ignore (generate_parser x)) xs
11851 and generate_parser_struct name (attrs, interleaves) =
11852 (* Generate parsers for the fields first. We have to do this
11853 * before printing anything so we are still in BOL context.
11855 let fields = attrs @ interleaves in
11856 let pas = List.map generate_parser fields in
11858 (* Generate an intermediate tuple from all the fields first.
11859 * If the type is just a string + another field, then we will
11860 * return this directly, otherwise it is turned into a record.
11862 * RELAX NG note: This code treats <interleave> and plain lists of
11863 * fields the same. In other words, it doesn't bother enforcing
11864 * any ordering of fields in the XML.
11866 pr "let parse_%s x =\n" name;
11867 pr " let t = (\n ";
11868 let comma = ref false in
11871 if !comma then pr ",\n ";
11874 | Optional (Attribute (fname, [field])), pa ->
11876 | Optional (Element (fname, [field])), pa ->
11877 pr "%s (optional_child %S x)" pa fname
11878 | Attribute (fname, [Text]), _ ->
11879 pr "attribute %S x" fname
11880 | (ZeroOrMore _ | OneOrMore _), pa ->
11885 let fname = name_of_field field in
11886 pr "%s (child %S x)" pa fname
11887 ) (List.combine fields pas);
11891 | [Element (_, [Text]) | Attribute (_, [Text]); _] ->
11895 pr " (Obj.magic t : %s)\n" name
11899 | (Optional (Attribute (fname, [field])), pa) ->
11900 pr " %s_%s =\n" name fname;
11902 | (Optional (Element (fname, [field])), pa) ->
11903 pr " %s_%s =\n" name fname;
11904 pr " (let x = optional_child %S x in\n" fname;
11907 let fname = name_of_field field in
11908 pr " %s_%s =\n" name fname;
11909 pr " (let x = child %S x in\n" fname;
11911 ) (List.combine fields pas);
11915 sprintf "parse_%s" name
11918 generate_parsers xs
11920 (* Generate ocaml/guestfs_inspector.mli. *)
11921 let generate_ocaml_inspector_mli () =
11922 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11925 (** This is an OCaml language binding to the external [virt-inspector]
11928 For more information, please read the man page [virt-inspector(1)].
11933 generate_types grammar;
11934 pr "(** The nested information returned from the {!inspect} function. *)\n";
11938 val inspect : ?connect:string -> ?xml:string -> string list -> operatingsystems
11939 (** To inspect a libvirt domain called [name], pass a singleton
11940 list: [inspect [name]]. When using libvirt only, you may
11941 optionally pass a libvirt URI using [inspect ~connect:uri ...].
11943 To inspect a disk image or images, pass a list of the filenames
11944 of the disk images: [inspect filenames]
11946 This function inspects the given guest or disk images and
11947 returns a list of operating system(s) found and a large amount
11948 of information about them. In the vast majority of cases,
11949 a virtual machine only contains a single operating system.
11951 If the optional [~xml] parameter is given, then this function
11952 skips running the external virt-inspector program and just
11953 parses the given XML directly (which is expected to be XML
11954 produced from a previous run of virt-inspector). The list of
11955 names and connect URI are ignored in this case.
11957 This function can throw a wide variety of exceptions, for example
11958 if the external virt-inspector program cannot be found, or if
11959 it doesn't generate valid XML.
11963 (* Generate ocaml/guestfs_inspector.ml. *)
11964 let generate_ocaml_inspector_ml () =
11965 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11970 generate_types grammar;
11974 (* Misc functions which are used by the parser code below. *)
11975 let first_child = function
11976 | Xml.Element (_, _, c::_) -> c
11977 | Xml.Element (name, _, []) ->
11978 failwith (\"expected <\" ^ name ^ \"/> to have a child node\")
11979 | Xml.PCData str ->
11980 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11982 let string_child_or_empty = function
11983 | Xml.Element (_, _, [Xml.PCData s]) -> s
11984 | Xml.Element (_, _, []) -> \"\"
11985 | Xml.Element (x, _, _) ->
11986 failwith (\"expected XML tag with a single PCDATA child, but got \" ^
11988 | Xml.PCData str ->
11989 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11991 let optional_child name xml =
11992 let children = Xml.children xml in
11994 Some (List.find (function
11995 | Xml.Element (n, _, _) when n = name -> true
11996 | _ -> false) children)
12000 let child name xml =
12001 match optional_child name xml with
12004 failwith (\"mandatory field <\" ^ name ^ \"/> missing in XML output\")
12006 let attribute name xml =
12007 try Xml.attrib xml name
12008 with Xml.No_attribute _ ->
12009 failwith (\"mandatory attribute \" ^ name ^ \" missing in XML output\")
12013 generate_parsers grammar;
12017 (* Run external virt-inspector, then use parser to parse the XML. *)
12018 let inspect ?connect ?xml names =
12022 if names = [] then invalid_arg \"inspect: no names given\";
12023 let cmd = [ \"virt-inspector\"; \"--xml\" ] @
12024 (match connect with None -> [] | Some uri -> [ \"--connect\"; uri ]) @
12026 let cmd = List.map Filename.quote cmd in
12027 let cmd = String.concat \" \" cmd in
12028 let chan = open_process_in cmd in
12029 let xml = Xml.parse_in chan in
12030 (match close_process_in chan with
12032 | WEXITED _ -> failwith \"external virt-inspector command failed\"
12033 | WSIGNALED i | WSTOPPED i ->
12034 failwith (\"external virt-inspector command died or stopped on sig \" ^
12039 Xml.parse_string doc in
12040 parse_operatingsystems xml
12043 and generate_max_proc_nr () =
12044 pr "%d\n" max_proc_nr
12046 let output_to filename k =
12047 let filename_new = filename ^ ".new" in
12048 chan := open_out filename_new;
12051 chan := Pervasives.stdout;
12053 (* Is the new file different from the current file? *)
12054 if Sys.file_exists filename && files_equal filename filename_new then
12055 unlink filename_new (* same, so skip it *)
12057 (* different, overwrite old one *)
12058 (try chmod filename 0o644 with Unix_error _ -> ());
12059 rename filename_new filename;
12060 chmod filename 0o444;
12061 printf "written %s\n%!" filename;
12064 let perror msg = function
12065 | Unix_error (err, _, _) ->
12066 eprintf "%s: %s\n" msg (error_message err)
12068 eprintf "%s: %s\n" msg (Printexc.to_string exn)
12070 (* Main program. *)
12073 try openfile "HACKING" [O_RDWR] 0
12075 | Unix_error (ENOENT, _, _) ->
12077 You are probably running this from the wrong directory.
12078 Run it from the top source directory using the command
12083 perror "open: HACKING" exn;
12086 (* Acquire a lock so parallel builds won't try to run the generator
12087 * twice at the same time. Subsequent builds will wait for the first
12088 * one to finish. Note the lock is released implicitly when the
12091 (try lockf lock_fd F_LOCK 1
12093 perror "lock: HACKING" exn;
12096 check_functions ();
12098 output_to "src/guestfs_protocol.x" generate_xdr;
12099 output_to "src/guestfs-structs.h" generate_structs_h;
12100 output_to "src/guestfs-actions.h" generate_actions_h;
12101 output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
12102 output_to "src/guestfs-actions.c" generate_client_actions;
12103 output_to "src/guestfs-bindtests.c" generate_bindtests;
12104 output_to "src/guestfs-structs.pod" generate_structs_pod;
12105 output_to "src/guestfs-actions.pod" generate_actions_pod;
12106 output_to "src/guestfs-availability.pod" generate_availability_pod;
12107 output_to "src/MAX_PROC_NR" generate_max_proc_nr;
12108 output_to "src/libguestfs.syms" generate_linker_script;
12109 output_to "daemon/actions.h" generate_daemon_actions_h;
12110 output_to "daemon/stubs.c" generate_daemon_actions;
12111 output_to "daemon/names.c" generate_daemon_names;
12112 output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
12113 output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
12114 output_to "capitests/tests.c" generate_tests;
12115 output_to "fish/cmds.c" generate_fish_cmds;
12116 output_to "fish/completion.c" generate_fish_completion;
12117 output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
12118 output_to "ocaml/guestfs.mli" generate_ocaml_mli;
12119 output_to "ocaml/guestfs.ml" generate_ocaml_ml;
12120 output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;
12121 output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
12122 output_to "ocaml/guestfs_inspector.mli" generate_ocaml_inspector_mli;
12123 output_to "ocaml/guestfs_inspector.ml" generate_ocaml_inspector_ml;
12124 output_to "perl/Guestfs.xs" generate_perl_xs;
12125 output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
12126 output_to "perl/bindtests.pl" generate_perl_bindtests;
12127 output_to "python/guestfs-py.c" generate_python_c;
12128 output_to "python/guestfs.py" generate_python_py;
12129 output_to "python/bindtests.py" generate_python_bindtests;
12130 output_to "ruby/ext/guestfs/_guestfs.c" generate_ruby_c;
12131 output_to "ruby/bindtests.rb" generate_ruby_bindtests;
12132 output_to "java/com/redhat/et/libguestfs/GuestFS.java" generate_java_java;
12136 let cols = cols_of_struct typ in
12137 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
12138 output_to filename (generate_java_struct jtyp cols);
12141 output_to "java/Makefile.inc" generate_java_makefile_inc;
12142 output_to "java/com_redhat_et_libguestfs_GuestFS.c" generate_java_c;
12143 output_to "java/Bindtests.java" generate_java_bindtests;
12144 output_to "haskell/Guestfs.hs" generate_haskell_hs;
12145 output_to "haskell/Bindtests.hs" generate_haskell_bindtests;
12146 output_to "csharp/Libguestfs.cs" generate_csharp;
12148 (* Always generate this file last, and unconditionally. It's used
12149 * by the Makefile to know when we must re-run the generator.
12151 let chan = open_out "src/stamp-generator" in
12152 fprintf chan "1\n";
12155 printf "generated %d lines of code\n" !lines