3 * Copyright (C) 2009-2010 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (* This script generates a large amount of code and documentation for
21 * all the daemon actions.
23 * To add a new action there are only two files you need to change,
24 * this one to describe the interface (see the big table of
25 * 'daemon_functions' below), and daemon/<somefile>.c to write the
28 * After editing this file, run it (./src/generator.ml) to regenerate
29 * all the output files. 'make' will rerun this automatically when
30 * necessary. Note that if you are using a separate build directory
31 * you must run generator.ml from the _source_ directory.
33 * IMPORTANT: This script should NOT print any warnings. If it prints
34 * warnings, you should treat them as errors.
37 * (1) In emacs, install tuareg-mode to display and format OCaml code
38 * correctly. 'vim' comes with a good OCaml editing mode by default.
39 * (2) Read the resources at http://ocaml-tutorial.org/
44 #directory "+xml-light";;
45 #directory "+../pkg-lib/xml-light";; (* for GODI users *)
46 #load "xml-light.cma";;
51 type style = ret * args
53 (* "RErr" as a return value means an int used as a simple error
54 * indication, ie. 0 or -1.
58 (* "RInt" as a return value means an int which is -1 for error
59 * or any value >= 0 on success. Only use this for smallish
60 * positive ints (0 <= i < 2^30).
64 (* "RInt64" is the same as RInt, but is guaranteed to be able
65 * to return a full 64 bit value, _except_ that -1 means error
66 * (so -1 cannot be a valid, non-error return value).
70 (* "RBool" is a bool return value which can be true/false or
75 (* "RConstString" is a string that refers to a constant value.
76 * The return value must NOT be NULL (since NULL indicates
79 * Try to avoid using this. In particular you cannot use this
80 * for values returned from the daemon, because there is no
81 * thread-safe way to return them in the C API.
83 | RConstString of string
85 (* "RConstOptString" is an even more broken version of
86 * "RConstString". The returned string may be NULL and there
87 * is no way to return an error indication. Avoid using this!
89 | RConstOptString of string
91 (* "RString" is a returned string. It must NOT be NULL, since
92 * a NULL return indicates an error. The caller frees this.
96 (* "RStringList" is a list of strings. No string in the list
97 * can be NULL. The caller frees the strings and the array.
99 | RStringList of string
101 (* "RStruct" is a function which returns a single named structure
102 * or an error indication (in C, a struct, and in other languages
103 * with varying representations, but usually very efficient). See
104 * after the function list below for the structures.
106 | RStruct of string * string (* name of retval, name of struct *)
108 (* "RStructList" is a function which returns either a list/array
109 * of structures (could be zero-length), or an error indication.
111 | RStructList of string * string (* name of retval, name of struct *)
113 (* Key-value pairs of untyped strings. Turns into a hashtable or
114 * dictionary in languages which support it. DON'T use this as a
115 * general "bucket" for results. Prefer a stronger typed return
116 * value if one is available, or write a custom struct. Don't use
117 * this if the list could potentially be very long, since it is
118 * inefficient. Keys should be unique. NULLs are not permitted.
120 | RHashtable of string
122 (* "RBufferOut" is handled almost exactly like RString, but
123 * it allows the string to contain arbitrary 8 bit data including
124 * ASCII NUL. In the C API this causes an implicit extra parameter
125 * to be added of type <size_t *size_r>. The extra parameter
126 * returns the actual size of the return buffer in bytes.
128 * Other programming languages support strings with arbitrary 8 bit
131 * At the RPC layer we have to use the opaque<> type instead of
132 * string<>. Returned data is still limited to the max message
135 | RBufferOut of string
137 and args = argt list (* Function parameters, guestfs handle is implicit. *)
139 (* Note in future we should allow a "variable args" parameter as
140 * the final parameter, to allow commands like
141 * chmod mode file [file(s)...]
142 * This is not implemented yet, but many commands (such as chmod)
143 * are currently defined with the argument order keeping this future
144 * possibility in mind.
147 | String of string (* const char *name, cannot be NULL *)
148 | Device of string (* /dev device name, cannot be NULL *)
149 | Pathname of string (* file name, cannot be NULL *)
150 | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *)
151 | OptString of string (* const char *name, may be NULL *)
152 | StringList of string(* list of strings (each string cannot be NULL) *)
153 | DeviceList of string(* list of Device names (each cannot be NULL) *)
154 | Bool of string (* boolean *)
155 | Int of string (* int (smallish ints, signed, <= 31 bits) *)
156 | Int64 of string (* any 64 bit int *)
157 (* These are treated as filenames (simple string parameters) in
158 * the C API and bindings. But in the RPC protocol, we transfer
159 * the actual file content up to or down from the daemon.
160 * FileIn: local machine -> daemon (in request)
161 * FileOut: daemon -> local machine (in reply)
162 * In guestfish (only), the special name "-" means read from
163 * stdin or write to stdout.
167 (* Opaque buffer which can contain arbitrary 8 bit data.
168 * In the C API, this is expressed as <const char *, size_t> pair.
169 * Most other languages have a string type which can contain
170 * ASCII NUL. We use whatever type is appropriate for each
172 * Buffers are limited by the total message size. To transfer
173 * large blocks of data, use FileIn/FileOut parameters instead.
174 * To return an arbitrary buffer, use RBufferOut.
179 | ProtocolLimitWarning (* display warning about protocol size limits *)
180 | DangerWillRobinson (* flags particularly dangerous commands *)
181 | FishAlias of string (* provide an alias for this cmd in guestfish *)
182 | FishOutput of fish_output_t (* how to display output in guestfish *)
183 | NotInFish (* do not export via guestfish *)
184 | NotInDocs (* do not add this function to documentation *)
185 | DeprecatedBy of string (* function is deprecated, use .. instead *)
186 | Optional of string (* function is part of an optional group *)
189 | FishOutputOctal (* for int return, print in octal *)
190 | FishOutputHexadecimal (* for int return, print in hex *)
192 (* You can supply zero or as many tests as you want per API call.
194 * Note that the test environment has 3 block devices, of size 500MB,
195 * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
196 * a fourth ISO block device with some known files on it (/dev/sdd).
198 * Note for partitioning purposes, the 500MB device has 1015 cylinders.
199 * Number of cylinders was 63 for IDE emulated disks with precisely
200 * the same size. How exactly this is calculated is a mystery.
202 * The ISO block device (/dev/sdd) comes from images/test.iso.
204 * To be able to run the tests in a reasonable amount of time,
205 * the virtual machine and block devices are reused between tests.
206 * So don't try testing kill_subprocess :-x
208 * Between each test we blockdev-setrw, umount-all, lvm-remove-all.
210 * Don't assume anything about the previous contents of the block
211 * devices. Use 'Init*' to create some initial scenarios.
213 * You can add a prerequisite clause to any individual test. This
214 * is a run-time check, which, if it fails, causes the test to be
215 * skipped. Useful if testing a command which might not work on
216 * all variations of libguestfs builds. A test that has prerequisite
217 * of 'Always' is run unconditionally.
219 * In addition, packagers can skip individual tests by setting the
220 * environment variables: eg:
221 * SKIP_TEST_<CMD>_<NUM>=1 SKIP_TEST_COMMAND_3=1 (skips test #3 of command)
222 * SKIP_TEST_<CMD>=1 SKIP_TEST_ZEROFREE=1 (skips all zerofree tests)
224 type tests = (test_init * test_prereq * test) list
226 (* Run the command sequence and just expect nothing to fail. *)
229 (* Run the command sequence and expect the output of the final
230 * command to be the string.
232 | TestOutput of seq * string
234 (* Run the command sequence and expect the output of the final
235 * command to be the list of strings.
237 | TestOutputList of seq * string list
239 (* Run the command sequence and expect the output of the final
240 * command to be the list of block devices (could be either
241 * "/dev/sd.." or "/dev/hd.." form - we don't check the 5th
242 * character of each string).
244 | TestOutputListOfDevices of seq * string list
246 (* Run the command sequence and expect the output of the final
247 * command to be the integer.
249 | TestOutputInt of seq * int
251 (* Run the command sequence and expect the output of the final
252 * command to be <op> <int>, eg. ">=", "1".
254 | TestOutputIntOp of seq * string * int
256 (* Run the command sequence and expect the output of the final
257 * command to be a true value (!= 0 or != NULL).
259 | TestOutputTrue of seq
261 (* Run the command sequence and expect the output of the final
262 * command to be a false value (== 0 or == NULL, but not an error).
264 | TestOutputFalse of seq
266 (* Run the command sequence and expect the output of the final
267 * command to be a list of the given length (but don't care about
270 | TestOutputLength of seq * int
272 (* Run the command sequence and expect the output of the final
273 * command to be a buffer (RBufferOut), ie. string + size.
275 | TestOutputBuffer of seq * string
277 (* Run the command sequence and expect the output of the final
278 * command to be a structure.
280 | TestOutputStruct of seq * test_field_compare list
282 (* Run the command sequence and expect the final command (only)
285 | TestLastFail of seq
287 and test_field_compare =
288 | CompareWithInt of string * int
289 | CompareWithIntOp of string * string * int
290 | CompareWithString of string * string
291 | CompareFieldsIntEq of string * string
292 | CompareFieldsStrEq of string * string
294 (* Test prerequisites. *)
296 (* Test always runs. *)
299 (* Test is currently disabled - eg. it fails, or it tests some
300 * unimplemented feature.
304 (* 'string' is some C code (a function body) that should return
305 * true or false. The test will run if the code returns true.
309 (* As for 'If' but the test runs _unless_ the code returns true. *)
312 (* Some initial scenarios for testing. *)
314 (* Do nothing, block devices could contain random stuff including
315 * LVM PVs, and some filesystems might be mounted. This is usually
320 (* Block devices are empty and no filesystems are mounted. *)
323 (* /dev/sda contains a single partition /dev/sda1, with random
324 * content. /dev/sdb and /dev/sdc may have random content.
329 (* /dev/sda contains a single partition /dev/sda1, which is formatted
330 * as ext2, empty [except for lost+found] and mounted on /.
331 * /dev/sdb and /dev/sdc may have random content.
337 * /dev/sda1 (is a PV):
338 * /dev/VG/LV (size 8MB):
339 * formatted as ext2, empty [except for lost+found], mounted on /
340 * /dev/sdb and /dev/sdc may have random content.
344 (* /dev/sdd (the ISO, see images/ directory in source)
349 (* Sequence of commands for testing. *)
351 and cmd = string list
353 (* Note about long descriptions: When referring to another
354 * action, use the format C<guestfs_other> (ie. the full name of
355 * the C function). This will be replaced as appropriate in other
358 * Apart from that, long descriptions are just perldoc paragraphs.
361 (* Generate a random UUID (used in tests). *)
363 let chan = open_process_in "uuidgen" in
364 let uuid = input_line chan in
365 (match close_process_in chan with
368 failwith "uuidgen: process exited with non-zero status"
369 | WSIGNALED _ | WSTOPPED _ ->
370 failwith "uuidgen: process signalled or stopped by signal"
374 (* These test functions are used in the language binding tests. *)
376 let test_all_args = [
379 StringList "strlist";
388 let test_all_rets = [
389 (* except for RErr, which is tested thoroughly elsewhere *)
390 "test0rint", RInt "valout";
391 "test0rint64", RInt64 "valout";
392 "test0rbool", RBool "valout";
393 "test0rconststring", RConstString "valout";
394 "test0rconstoptstring", RConstOptString "valout";
395 "test0rstring", RString "valout";
396 "test0rstringlist", RStringList "valout";
397 "test0rstruct", RStruct ("valout", "lvm_pv");
398 "test0rstructlist", RStructList ("valout", "lvm_pv");
399 "test0rhashtable", RHashtable "valout";
402 let test_functions = [
403 ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
405 "internal test function - do not use",
407 This is an internal test function which is used to test whether
408 the automatically generated bindings can handle every possible
409 parameter type correctly.
411 It echos the contents of each parameter to stdout.
413 You probably don't want to call this function.");
417 [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
419 "internal test function - do not use",
421 This is an internal test function which is used to test whether
422 the automatically generated bindings can handle every possible
423 return type correctly.
425 It converts string C<val> to the return type.
427 You probably don't want to call this function.");
428 (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
430 "internal test function - do not use",
432 This is an internal test function which is used to test whether
433 the automatically generated bindings can handle every possible
434 return type correctly.
436 This function always returns an error.
438 You probably don't want to call this function.")]
442 (* non_daemon_functions are any functions which don't get processed
443 * in the daemon, eg. functions for setting and getting local
444 * configuration values.
447 let non_daemon_functions = test_functions @ [
448 ("launch", (RErr, []), -1, [FishAlias "run"],
450 "launch the qemu subprocess",
452 Internally libguestfs is implemented by running a virtual machine
455 You should call this after configuring the handle
456 (eg. adding drives) but before performing any actions.");
458 ("wait_ready", (RErr, []), -1, [NotInFish],
460 "wait until the qemu subprocess launches (no op)",
462 This function is a no op.
464 In versions of the API E<lt> 1.0.71 you had to call this function
465 just after calling C<guestfs_launch> to wait for the launch
466 to complete. However this is no longer necessary because
467 C<guestfs_launch> now does the waiting.
469 If you see any calls to this function in code then you can just
470 remove them, unless you want to retain compatibility with older
471 versions of the API.");
473 ("kill_subprocess", (RErr, []), -1, [],
475 "kill the qemu subprocess",
477 This kills the qemu subprocess. You should never need to call this.");
479 ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
481 "add an image to examine or modify",
483 This function adds a virtual machine disk image C<filename> to the
484 guest. The first time you call this function, the disk appears as IDE
485 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
488 You don't necessarily need to be root when using libguestfs. However
489 you obviously do need sufficient permissions to access the filename
490 for whatever operations you want to perform (ie. read access if you
491 just want to read the image or write access if you want to modify the
494 This is equivalent to the qemu parameter
495 C<-drive file=filename,cache=off,if=...>.
497 C<cache=off> is omitted in cases where it is not supported by
498 the underlying filesystem.
500 C<if=...> is set at compile time by the configuration option
501 C<./configure --with-drive-if=...>. In the rare case where you
502 might need to change this at run time, use C<guestfs_add_drive_with_if>
503 or C<guestfs_add_drive_ro_with_if>.
505 Note that this call checks for the existence of C<filename>. This
506 stops you from specifying other types of drive which are supported
507 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
508 the general C<guestfs_config> call instead.");
510 ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
512 "add a CD-ROM disk image to examine",
514 This function adds a virtual CD-ROM disk image to the guest.
516 This is equivalent to the qemu parameter C<-cdrom filename>.
524 This call checks for the existence of C<filename>. This
525 stops you from specifying other types of drive which are supported
526 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
527 the general C<guestfs_config> call instead.
531 If you just want to add an ISO file (often you use this as an
532 efficient way to transfer large files into the guest), then you
533 should probably use C<guestfs_add_drive_ro> instead.
537 ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
539 "add a drive in snapshot mode (read-only)",
541 This adds a drive in snapshot mode, making it effectively
544 Note that writes to the device are allowed, and will be seen for
545 the duration of the guestfs handle, but they are written
546 to a temporary file which is discarded as soon as the guestfs
547 handle is closed. We don't currently have any method to enable
548 changes to be committed, although qemu can support this.
550 This is equivalent to the qemu parameter
551 C<-drive file=filename,snapshot=on,readonly=on,if=...>.
553 C<if=...> is set at compile time by the configuration option
554 C<./configure --with-drive-if=...>. In the rare case where you
555 might need to change this at run time, use C<guestfs_add_drive_with_if>
556 or C<guestfs_add_drive_ro_with_if>.
558 C<readonly=on> is only added where qemu supports this option.
560 Note that this call checks for the existence of C<filename>. This
561 stops you from specifying other types of drive which are supported
562 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
563 the general C<guestfs_config> call instead.");
565 ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
567 "add qemu parameters",
569 This can be used to add arbitrary qemu command line parameters
570 of the form C<-param value>. Actually it's not quite arbitrary - we
571 prevent you from setting some parameters which would interfere with
572 parameters that we use.
574 The first character of C<param> string must be a C<-> (dash).
576 C<value> can be NULL.");
578 ("set_qemu", (RErr, [OptString "qemu"]), -1, [FishAlias "qemu"],
580 "set the qemu binary",
582 Set the qemu binary that we will use.
584 The default is chosen when the library was compiled by the
587 You can also override this by setting the C<LIBGUESTFS_QEMU>
588 environment variable.
590 Setting C<qemu> to C<NULL> restores the default qemu binary.
592 Note that you should call this function as early as possible
593 after creating the handle. This is because some pre-launch
594 operations depend on testing qemu features (by running C<qemu -help>).
595 If the qemu binary changes, we don't retest features, and
596 so you might see inconsistent results. Using the environment
597 variable C<LIBGUESTFS_QEMU> is safest of all since that picks
598 the qemu binary at the same time as the handle is created.");
600 ("get_qemu", (RConstString "qemu", []), -1, [],
601 [InitNone, Always, TestRun (
603 "get the qemu binary",
605 Return the current qemu binary.
607 This is always non-NULL. If it wasn't set already, then this will
608 return the default qemu binary name.");
610 ("set_path", (RErr, [OptString "searchpath"]), -1, [FishAlias "path"],
612 "set the search path",
614 Set the path that libguestfs searches for kernel and initrd.img.
616 The default is C<$libdir/guestfs> unless overridden by setting
617 C<LIBGUESTFS_PATH> environment variable.
619 Setting C<path> to C<NULL> restores the default path.");
621 ("get_path", (RConstString "path", []), -1, [],
622 [InitNone, Always, TestRun (
624 "get the search path",
626 Return the current search path.
628 This is always non-NULL. If it wasn't set already, then this will
629 return the default path.");
631 ("set_append", (RErr, [OptString "append"]), -1, [FishAlias "append"],
633 "add options to kernel command line",
635 This function is used to add additional options to the
636 guest kernel command line.
638 The default is C<NULL> unless overridden by setting
639 C<LIBGUESTFS_APPEND> environment variable.
641 Setting C<append> to C<NULL> means I<no> additional options
642 are passed (libguestfs always adds a few of its own).");
644 ("get_append", (RConstOptString "append", []), -1, [],
645 (* This cannot be tested with the current framework. The
646 * function can return NULL in normal operations, which the
647 * test framework interprets as an error.
650 "get the additional kernel options",
652 Return the additional kernel options which are added to the
653 guest kernel command line.
655 If C<NULL> then no options are added.");
657 ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
661 If C<autosync> is true, this enables autosync. Libguestfs will make a
662 best effort attempt to run C<guestfs_umount_all> followed by
663 C<guestfs_sync> when the handle is closed
664 (also if the program exits without closing handles).
666 This is disabled by default (except in guestfish where it is
667 enabled by default).");
669 ("get_autosync", (RBool "autosync", []), -1, [],
670 [InitNone, Always, TestRun (
671 [["get_autosync"]])],
674 Get the autosync flag.");
676 ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
680 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
682 Verbose messages are disabled unless the environment variable
683 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
685 ("get_verbose", (RBool "verbose", []), -1, [],
689 This returns the verbose messages flag.");
691 ("is_ready", (RBool "ready", []), -1, [],
692 [InitNone, Always, TestOutputTrue (
694 "is ready to accept commands",
696 This returns true iff this handle is ready to accept commands
697 (in the C<READY> state).
699 For more information on states, see L<guestfs(3)>.");
701 ("is_config", (RBool "config", []), -1, [],
702 [InitNone, Always, TestOutputFalse (
704 "is in configuration state",
706 This returns true iff this handle is being configured
707 (in the C<CONFIG> state).
709 For more information on states, see L<guestfs(3)>.");
711 ("is_launching", (RBool "launching", []), -1, [],
712 [InitNone, Always, TestOutputFalse (
713 [["is_launching"]])],
714 "is launching subprocess",
716 This returns true iff this handle is launching the subprocess
717 (in the C<LAUNCHING> state).
719 For more information on states, see L<guestfs(3)>.");
721 ("is_busy", (RBool "busy", []), -1, [],
722 [InitNone, Always, TestOutputFalse (
724 "is busy processing a command",
726 This returns true iff this handle is busy processing a command
727 (in the C<BUSY> state).
729 For more information on states, see L<guestfs(3)>.");
731 ("get_state", (RInt "state", []), -1, [],
733 "get the current state",
735 This returns the current state as an opaque integer. This is
736 only useful for printing debug and internal error messages.
738 For more information on states, see L<guestfs(3)>.");
740 ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
741 [InitNone, Always, TestOutputInt (
742 [["set_memsize"; "500"];
743 ["get_memsize"]], 500)],
744 "set memory allocated to the qemu subprocess",
746 This sets the memory size in megabytes allocated to the
747 qemu subprocess. This only has any effect if called before
750 You can also change this by setting the environment
751 variable C<LIBGUESTFS_MEMSIZE> before the handle is
754 For more information on the architecture of libguestfs,
755 see L<guestfs(3)>.");
757 ("get_memsize", (RInt "memsize", []), -1, [],
758 [InitNone, Always, TestOutputIntOp (
759 [["get_memsize"]], ">=", 256)],
760 "get memory allocated to the qemu subprocess",
762 This gets the memory size in megabytes allocated to the
765 If C<guestfs_set_memsize> was not called
766 on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
767 then this returns the compiled-in default value for memsize.
769 For more information on the architecture of libguestfs,
770 see L<guestfs(3)>.");
772 ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"],
773 [InitNone, Always, TestOutputIntOp (
774 [["get_pid"]], ">=", 1)],
775 "get PID of qemu subprocess",
777 Return the process ID of the qemu subprocess. If there is no
778 qemu subprocess, then this will return an error.
780 This is an internal call used for debugging and testing.");
782 ("version", (RStruct ("version", "version"), []), -1, [],
783 [InitNone, Always, TestOutputStruct (
784 [["version"]], [CompareWithInt ("major", 1)])],
785 "get the library version number",
787 Return the libguestfs version number that the program is linked
790 Note that because of dynamic linking this is not necessarily
791 the version of libguestfs that you compiled against. You can
792 compile the program, and then at runtime dynamically link
793 against a completely different C<libguestfs.so> library.
795 This call was added in version C<1.0.58>. In previous
796 versions of libguestfs there was no way to get the version
797 number. From C code you can use dynamic linker functions
798 to find out if this symbol exists (if it doesn't, then
799 it's an earlier version).
801 The call returns a structure with four elements. The first
802 three (C<major>, C<minor> and C<release>) are numbers and
803 correspond to the usual version triplet. The fourth element
804 (C<extra>) is a string and is normally empty, but may be
805 used for distro-specific information.
807 To construct the original version string:
808 C<$major.$minor.$release$extra>
810 I<Note:> Don't use this call to test for availability
811 of features. Distro backports makes this unreliable. Use
812 C<guestfs_available> instead.");
814 ("set_selinux", (RErr, [Bool "selinux"]), -1, [FishAlias "selinux"],
815 [InitNone, Always, TestOutputTrue (
816 [["set_selinux"; "true"];
818 "set SELinux enabled or disabled at appliance boot",
820 This sets the selinux flag that is passed to the appliance
821 at boot time. The default is C<selinux=0> (disabled).
823 Note that if SELinux is enabled, it is always in
824 Permissive mode (C<enforcing=0>).
826 For more information on the architecture of libguestfs,
827 see L<guestfs(3)>.");
829 ("get_selinux", (RBool "selinux", []), -1, [],
831 "get SELinux enabled flag",
833 This returns the current setting of the selinux flag which
834 is passed to the appliance at boot time. See C<guestfs_set_selinux>.
836 For more information on the architecture of libguestfs,
837 see L<guestfs(3)>.");
839 ("set_trace", (RErr, [Bool "trace"]), -1, [FishAlias "trace"],
840 [InitNone, Always, TestOutputFalse (
841 [["set_trace"; "false"];
843 "enable or disable command traces",
845 If the command trace flag is set to 1, then commands are
846 printed on stdout before they are executed in a format
847 which is very similar to the one used by guestfish. In
848 other words, you can run a program with this enabled, and
849 you will get out a script which you can feed to guestfish
850 to perform the same set of actions.
852 If you want to trace C API calls into libguestfs (and
853 other libraries) then possibly a better way is to use
854 the external ltrace(1) command.
856 Command traces are disabled unless the environment variable
857 C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
859 ("get_trace", (RBool "trace", []), -1, [],
861 "get command trace enabled flag",
863 Return the command trace flag.");
865 ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"],
866 [InitNone, Always, TestOutputFalse (
867 [["set_direct"; "false"];
869 "enable or disable direct appliance mode",
871 If the direct appliance mode flag is enabled, then stdin and
872 stdout are passed directly through to the appliance once it
875 One consequence of this is that log messages aren't caught
876 by the library and handled by C<guestfs_set_log_message_callback>,
877 but go straight to stdout.
879 You probably don't want to use this unless you know what you
882 The default is disabled.");
884 ("get_direct", (RBool "direct", []), -1, [],
886 "get direct appliance mode flag",
888 Return the direct appliance mode flag.");
890 ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"],
891 [InitNone, Always, TestOutputTrue (
892 [["set_recovery_proc"; "true"];
893 ["get_recovery_proc"]])],
894 "enable or disable the recovery process",
896 If this is called with the parameter C<false> then
897 C<guestfs_launch> does not create a recovery process. The
898 purpose of the recovery process is to stop runaway qemu
899 processes in the case where the main program aborts abruptly.
901 This only has any effect if called before C<guestfs_launch>,
902 and the default is true.
904 About the only time when you would want to disable this is
905 if the main process will fork itself into the background
906 (\"daemonize\" itself). In this case the recovery process
907 thinks that the main program has disappeared and so kills
908 qemu, which is not very helpful.");
910 ("get_recovery_proc", (RBool "recoveryproc", []), -1, [],
912 "get recovery process enabled flag",
914 Return the recovery process enabled flag.");
916 ("add_drive_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
918 "add a drive specifying the QEMU block emulation to use",
920 This is the same as C<guestfs_add_drive> but it allows you
921 to specify the QEMU interface emulation to use at run time.");
923 ("add_drive_ro_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
925 "add a drive read-only specifying the QEMU block emulation to use",
927 This is the same as C<guestfs_add_drive_ro> but it allows you
928 to specify the QEMU interface emulation to use at run time.");
932 (* daemon_functions are any functions which cause some action
933 * to take place in the daemon.
936 let daemon_functions = [
937 ("mount", (RErr, [Device "device"; String "mountpoint"]), 1, [],
938 [InitEmpty, Always, TestOutput (
939 [["part_disk"; "/dev/sda"; "mbr"];
940 ["mkfs"; "ext2"; "/dev/sda1"];
941 ["mount"; "/dev/sda1"; "/"];
942 ["write"; "/new"; "new file contents"];
943 ["cat"; "/new"]], "new file contents")],
944 "mount a guest disk at a position in the filesystem",
946 Mount a guest disk at a position in the filesystem. Block devices
947 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
948 the guest. If those block devices contain partitions, they will have
949 the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style
952 The rules are the same as for L<mount(2)>: A filesystem must
953 first be mounted on C</> before others can be mounted. Other
954 filesystems can only be mounted on directories which already
957 The mounted filesystem is writable, if we have sufficient permissions
958 on the underlying device.
961 When you use this call, the filesystem options C<sync> and C<noatime>
962 are set implicitly. This was originally done because we thought it
963 would improve reliability, but it turns out that I<-o sync> has a
964 very large negative performance impact and negligible effect on
965 reliability. Therefore we recommend that you avoid using
966 C<guestfs_mount> in any code that needs performance, and instead
967 use C<guestfs_mount_options> (use an empty string for the first
968 parameter if you don't want any options).");
970 ("sync", (RErr, []), 2, [],
971 [ InitEmpty, Always, TestRun [["sync"]]],
972 "sync disks, writes are flushed through to the disk image",
974 This syncs the disk, so that any writes are flushed through to the
975 underlying disk image.
977 You should always call this if you have modified a disk image, before
978 closing the handle.");
980 ("touch", (RErr, [Pathname "path"]), 3, [],
981 [InitBasicFS, Always, TestOutputTrue (
983 ["exists"; "/new"]])],
984 "update file timestamps or create a new file",
986 Touch acts like the L<touch(1)> command. It can be used to
987 update the timestamps on a file, or, if the file does not exist,
988 to create a new zero-length file.");
990 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
991 [InitISOFS, Always, TestOutput (
992 [["cat"; "/known-2"]], "abcdef\n")],
993 "list the contents of a file",
995 Return the contents of the file named C<path>.
997 Note that this function cannot correctly handle binary files
998 (specifically, files containing C<\\0> character which is treated
999 as end of string). For those you need to use the C<guestfs_read_file>
1000 or C<guestfs_download> functions which have a more complex interface.");
1002 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
1003 [], (* XXX Tricky to test because it depends on the exact format
1004 * of the 'ls -l' command, which changes between F10 and F11.
1006 "list the files in a directory (long format)",
1008 List the files in C<directory> (relative to the root directory,
1009 there is no cwd) in the format of 'ls -la'.
1011 This command is mostly useful for interactive sessions. It
1012 is I<not> intended that you try to parse the output string.");
1014 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
1015 [InitBasicFS, Always, TestOutputList (
1017 ["touch"; "/newer"];
1018 ["touch"; "/newest"];
1019 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
1020 "list the files in a directory",
1022 List the files in C<directory> (relative to the root directory,
1023 there is no cwd). The '.' and '..' entries are not returned, but
1024 hidden files are shown.
1026 This command is mostly useful for interactive sessions. Programs
1027 should probably use C<guestfs_readdir> instead.");
1029 ("list_devices", (RStringList "devices", []), 7, [],
1030 [InitEmpty, Always, TestOutputListOfDevices (
1031 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
1032 "list the block devices",
1034 List all the block devices.
1036 The full block device names are returned, eg. C</dev/sda>");
1038 ("list_partitions", (RStringList "partitions", []), 8, [],
1039 [InitBasicFS, Always, TestOutputListOfDevices (
1040 [["list_partitions"]], ["/dev/sda1"]);
1041 InitEmpty, Always, TestOutputListOfDevices (
1042 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1043 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1044 "list the partitions",
1046 List all the partitions detected on all block devices.
1048 The full partition device names are returned, eg. C</dev/sda1>
1050 This does not return logical volumes. For that you will need to
1051 call C<guestfs_lvs>.");
1053 ("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
1054 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
1055 [["pvs"]], ["/dev/sda1"]);
1056 InitEmpty, Always, TestOutputListOfDevices (
1057 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1058 ["pvcreate"; "/dev/sda1"];
1059 ["pvcreate"; "/dev/sda2"];
1060 ["pvcreate"; "/dev/sda3"];
1061 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1062 "list the LVM physical volumes (PVs)",
1064 List all the physical volumes detected. This is the equivalent
1065 of the L<pvs(8)> command.
1067 This returns a list of just the device names that contain
1068 PVs (eg. C</dev/sda2>).
1070 See also C<guestfs_pvs_full>.");
1072 ("vgs", (RStringList "volgroups", []), 10, [Optional "lvm2"],
1073 [InitBasicFSonLVM, Always, TestOutputList (
1075 InitEmpty, Always, TestOutputList (
1076 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1077 ["pvcreate"; "/dev/sda1"];
1078 ["pvcreate"; "/dev/sda2"];
1079 ["pvcreate"; "/dev/sda3"];
1080 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1081 ["vgcreate"; "VG2"; "/dev/sda3"];
1082 ["vgs"]], ["VG1"; "VG2"])],
1083 "list the LVM volume groups (VGs)",
1085 List all the volumes groups detected. This is the equivalent
1086 of the L<vgs(8)> command.
1088 This returns a list of just the volume group names that were
1089 detected (eg. C<VolGroup00>).
1091 See also C<guestfs_vgs_full>.");
1093 ("lvs", (RStringList "logvols", []), 11, [Optional "lvm2"],
1094 [InitBasicFSonLVM, Always, TestOutputList (
1095 [["lvs"]], ["/dev/VG/LV"]);
1096 InitEmpty, Always, TestOutputList (
1097 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1098 ["pvcreate"; "/dev/sda1"];
1099 ["pvcreate"; "/dev/sda2"];
1100 ["pvcreate"; "/dev/sda3"];
1101 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1102 ["vgcreate"; "VG2"; "/dev/sda3"];
1103 ["lvcreate"; "LV1"; "VG1"; "50"];
1104 ["lvcreate"; "LV2"; "VG1"; "50"];
1105 ["lvcreate"; "LV3"; "VG2"; "50"];
1106 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1107 "list the LVM logical volumes (LVs)",
1109 List all the logical volumes detected. This is the equivalent
1110 of the L<lvs(8)> command.
1112 This returns a list of the logical volume device names
1113 (eg. C</dev/VolGroup00/LogVol00>).
1115 See also C<guestfs_lvs_full>.");
1117 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
1118 [], (* XXX how to test? *)
1119 "list the LVM physical volumes (PVs)",
1121 List all the physical volumes detected. This is the equivalent
1122 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1124 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [Optional "lvm2"],
1125 [], (* XXX how to test? *)
1126 "list the LVM volume groups (VGs)",
1128 List all the volumes groups detected. This is the equivalent
1129 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1131 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [Optional "lvm2"],
1132 [], (* XXX how to test? *)
1133 "list the LVM logical volumes (LVs)",
1135 List all the logical volumes detected. This is the equivalent
1136 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1138 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1139 [InitISOFS, Always, TestOutputList (
1140 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1141 InitISOFS, Always, TestOutputList (
1142 [["read_lines"; "/empty"]], [])],
1143 "read file as lines",
1145 Return the contents of the file named C<path>.
1147 The file contents are returned as a list of lines. Trailing
1148 C<LF> and C<CRLF> character sequences are I<not> returned.
1150 Note that this function cannot correctly handle binary files
1151 (specifically, files containing C<\\0> character which is treated
1152 as end of line). For those you need to use the C<guestfs_read_file>
1153 function which has a more complex interface.");
1155 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [Optional "augeas"],
1156 [], (* XXX Augeas code needs tests. *)
1157 "create a new Augeas handle",
1159 Create a new Augeas handle for editing configuration files.
1160 If there was any previous Augeas handle associated with this
1161 guestfs session, then it is closed.
1163 You must call this before using any other C<guestfs_aug_*>
1166 C<root> is the filesystem root. C<root> must not be NULL,
1169 The flags are the same as the flags defined in
1170 E<lt>augeas.hE<gt>, the logical I<or> of the following
1175 =item C<AUG_SAVE_BACKUP> = 1
1177 Keep the original file with a C<.augsave> extension.
1179 =item C<AUG_SAVE_NEWFILE> = 2
1181 Save changes into a file with extension C<.augnew>, and
1182 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1184 =item C<AUG_TYPE_CHECK> = 4
1186 Typecheck lenses (can be expensive).
1188 =item C<AUG_NO_STDINC> = 8
1190 Do not use standard load path for modules.
1192 =item C<AUG_SAVE_NOOP> = 16
1194 Make save a no-op, just record what would have been changed.
1196 =item C<AUG_NO_LOAD> = 32
1198 Do not load the tree in C<guestfs_aug_init>.
1202 To close the handle, you can call C<guestfs_aug_close>.
1204 To find out more about Augeas, see L<http://augeas.net/>.");
1206 ("aug_close", (RErr, []), 26, [Optional "augeas"],
1207 [], (* XXX Augeas code needs tests. *)
1208 "close the current Augeas handle",
1210 Close the current Augeas handle and free up any resources
1211 used by it. After calling this, you have to call
1212 C<guestfs_aug_init> again before you can use any other
1213 Augeas functions.");
1215 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [Optional "augeas"],
1216 [], (* XXX Augeas code needs tests. *)
1217 "define an Augeas variable",
1219 Defines an Augeas variable C<name> whose value is the result
1220 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1223 On success this returns the number of nodes in C<expr>, or
1224 C<0> if C<expr> evaluates to something which is not a nodeset.");
1226 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [Optional "augeas"],
1227 [], (* XXX Augeas code needs tests. *)
1228 "define an Augeas node",
1230 Defines a variable C<name> whose value is the result of
1233 If C<expr> evaluates to an empty nodeset, a node is created,
1234 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1235 C<name> will be the nodeset containing that single node.
1237 On success this returns a pair containing the
1238 number of nodes in the nodeset, and a boolean flag
1239 if a node was created.");
1241 ("aug_get", (RString "val", [String "augpath"]), 19, [Optional "augeas"],
1242 [], (* XXX Augeas code needs tests. *)
1243 "look up the value of an Augeas path",
1245 Look up the value associated with C<path>. If C<path>
1246 matches exactly one node, the C<value> is returned.");
1248 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [Optional "augeas"],
1249 [], (* XXX Augeas code needs tests. *)
1250 "set Augeas path to value",
1252 Set the value associated with C<path> to C<val>.
1254 In the Augeas API, it is possible to clear a node by setting
1255 the value to NULL. Due to an oversight in the libguestfs API
1256 you cannot do that with this call. Instead you must use the
1257 C<guestfs_aug_clear> call.");
1259 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [Optional "augeas"],
1260 [], (* XXX Augeas code needs tests. *)
1261 "insert a sibling Augeas node",
1263 Create a new sibling C<label> for C<path>, inserting it into
1264 the tree before or after C<path> (depending on the boolean
1267 C<path> must match exactly one existing node in the tree, and
1268 C<label> must be a label, ie. not contain C</>, C<*> or end
1269 with a bracketed index C<[N]>.");
1271 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [Optional "augeas"],
1272 [], (* XXX Augeas code needs tests. *)
1273 "remove an Augeas path",
1275 Remove C<path> and all of its children.
1277 On success this returns the number of entries which were removed.");
1279 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [Optional "augeas"],
1280 [], (* XXX Augeas code needs tests. *)
1283 Move the node C<src> to C<dest>. C<src> must match exactly
1284 one node. C<dest> is overwritten if it exists.");
1286 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [Optional "augeas"],
1287 [], (* XXX Augeas code needs tests. *)
1288 "return Augeas nodes which match augpath",
1290 Returns a list of paths which match the path expression C<path>.
1291 The returned paths are sufficiently qualified so that they match
1292 exactly one node in the current tree.");
1294 ("aug_save", (RErr, []), 25, [Optional "augeas"],
1295 [], (* XXX Augeas code needs tests. *)
1296 "write all pending Augeas changes to disk",
1298 This writes all pending changes to disk.
1300 The flags which were passed to C<guestfs_aug_init> affect exactly
1301 how files are saved.");
1303 ("aug_load", (RErr, []), 27, [Optional "augeas"],
1304 [], (* XXX Augeas code needs tests. *)
1305 "load files into the tree",
1307 Load files into the tree.
1309 See C<aug_load> in the Augeas documentation for the full gory
1312 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [Optional "augeas"],
1313 [], (* XXX Augeas code needs tests. *)
1314 "list Augeas nodes under augpath",
1316 This is just a shortcut for listing C<guestfs_aug_match>
1317 C<path/*> and sorting the resulting nodes into alphabetical order.");
1319 ("rm", (RErr, [Pathname "path"]), 29, [],
1320 [InitBasicFS, Always, TestRun
1323 InitBasicFS, Always, TestLastFail
1325 InitBasicFS, Always, TestLastFail
1330 Remove the single file C<path>.");
1332 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1333 [InitBasicFS, Always, TestRun
1336 InitBasicFS, Always, TestLastFail
1337 [["rmdir"; "/new"]];
1338 InitBasicFS, Always, TestLastFail
1340 ["rmdir"; "/new"]]],
1341 "remove a directory",
1343 Remove the single directory C<path>.");
1345 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1346 [InitBasicFS, Always, TestOutputFalse
1348 ["mkdir"; "/new/foo"];
1349 ["touch"; "/new/foo/bar"];
1351 ["exists"; "/new"]]],
1352 "remove a file or directory recursively",
1354 Remove the file or directory C<path>, recursively removing the
1355 contents if its a directory. This is like the C<rm -rf> shell
1358 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1359 [InitBasicFS, Always, TestOutputTrue
1361 ["is_dir"; "/new"]];
1362 InitBasicFS, Always, TestLastFail
1363 [["mkdir"; "/new/foo/bar"]]],
1364 "create a directory",
1366 Create a directory named C<path>.");
1368 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1369 [InitBasicFS, Always, TestOutputTrue
1370 [["mkdir_p"; "/new/foo/bar"];
1371 ["is_dir"; "/new/foo/bar"]];
1372 InitBasicFS, Always, TestOutputTrue
1373 [["mkdir_p"; "/new/foo/bar"];
1374 ["is_dir"; "/new/foo"]];
1375 InitBasicFS, Always, TestOutputTrue
1376 [["mkdir_p"; "/new/foo/bar"];
1377 ["is_dir"; "/new"]];
1378 (* Regression tests for RHBZ#503133: *)
1379 InitBasicFS, Always, TestRun
1381 ["mkdir_p"; "/new"]];
1382 InitBasicFS, Always, TestLastFail
1384 ["mkdir_p"; "/new"]]],
1385 "create a directory and parents",
1387 Create a directory named C<path>, creating any parent directories
1388 as necessary. This is like the C<mkdir -p> shell command.");
1390 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1391 [], (* XXX Need stat command to test *)
1394 Change the mode (permissions) of C<path> to C<mode>. Only
1395 numeric modes are supported.
1397 I<Note>: When using this command from guestfish, C<mode>
1398 by default would be decimal, unless you prefix it with
1399 C<0> to get octal, ie. use C<0700> not C<700>.
1401 The mode actually set is affected by the umask.");
1403 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1404 [], (* XXX Need stat command to test *)
1405 "change file owner and group",
1407 Change the file owner to C<owner> and group to C<group>.
1409 Only numeric uid and gid are supported. If you want to use
1410 names, you will need to locate and parse the password file
1411 yourself (Augeas support makes this relatively easy).");
1413 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1414 [InitISOFS, Always, TestOutputTrue (
1415 [["exists"; "/empty"]]);
1416 InitISOFS, Always, TestOutputTrue (
1417 [["exists"; "/directory"]])],
1418 "test if file or directory exists",
1420 This returns C<true> if and only if there is a file, directory
1421 (or anything) with the given C<path> name.
1423 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1425 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1426 [InitISOFS, Always, TestOutputTrue (
1427 [["is_file"; "/known-1"]]);
1428 InitISOFS, Always, TestOutputFalse (
1429 [["is_file"; "/directory"]])],
1430 "test if file exists",
1432 This returns C<true> if and only if there is a file
1433 with the given C<path> name. Note that it returns false for
1434 other objects like directories.
1436 See also C<guestfs_stat>.");
1438 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1439 [InitISOFS, Always, TestOutputFalse (
1440 [["is_dir"; "/known-3"]]);
1441 InitISOFS, Always, TestOutputTrue (
1442 [["is_dir"; "/directory"]])],
1443 "test if file exists",
1445 This returns C<true> if and only if there is a directory
1446 with the given C<path> name. Note that it returns false for
1447 other objects like files.
1449 See also C<guestfs_stat>.");
1451 ("pvcreate", (RErr, [Device "device"]), 39, [Optional "lvm2"],
1452 [InitEmpty, Always, TestOutputListOfDevices (
1453 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1454 ["pvcreate"; "/dev/sda1"];
1455 ["pvcreate"; "/dev/sda2"];
1456 ["pvcreate"; "/dev/sda3"];
1457 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1458 "create an LVM physical volume",
1460 This creates an LVM physical volume on the named C<device>,
1461 where C<device> should usually be a partition name such
1464 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [Optional "lvm2"],
1465 [InitEmpty, Always, TestOutputList (
1466 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1467 ["pvcreate"; "/dev/sda1"];
1468 ["pvcreate"; "/dev/sda2"];
1469 ["pvcreate"; "/dev/sda3"];
1470 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1471 ["vgcreate"; "VG2"; "/dev/sda3"];
1472 ["vgs"]], ["VG1"; "VG2"])],
1473 "create an LVM volume group",
1475 This creates an LVM volume group called C<volgroup>
1476 from the non-empty list of physical volumes C<physvols>.");
1478 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [Optional "lvm2"],
1479 [InitEmpty, Always, TestOutputList (
1480 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1481 ["pvcreate"; "/dev/sda1"];
1482 ["pvcreate"; "/dev/sda2"];
1483 ["pvcreate"; "/dev/sda3"];
1484 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1485 ["vgcreate"; "VG2"; "/dev/sda3"];
1486 ["lvcreate"; "LV1"; "VG1"; "50"];
1487 ["lvcreate"; "LV2"; "VG1"; "50"];
1488 ["lvcreate"; "LV3"; "VG2"; "50"];
1489 ["lvcreate"; "LV4"; "VG2"; "50"];
1490 ["lvcreate"; "LV5"; "VG2"; "50"];
1492 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1493 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1494 "create an LVM logical volume",
1496 This creates an LVM logical volume called C<logvol>
1497 on the volume group C<volgroup>, with C<size> megabytes.");
1499 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1500 [InitEmpty, Always, TestOutput (
1501 [["part_disk"; "/dev/sda"; "mbr"];
1502 ["mkfs"; "ext2"; "/dev/sda1"];
1503 ["mount_options"; ""; "/dev/sda1"; "/"];
1504 ["write"; "/new"; "new file contents"];
1505 ["cat"; "/new"]], "new file contents")],
1506 "make a filesystem",
1508 This creates a filesystem on C<device> (usually a partition
1509 or LVM logical volume). The filesystem type is C<fstype>, for
1512 ("sfdisk", (RErr, [Device "device";
1513 Int "cyls"; Int "heads"; Int "sectors";
1514 StringList "lines"]), 43, [DangerWillRobinson],
1516 "create partitions on a block device",
1518 This is a direct interface to the L<sfdisk(8)> program for creating
1519 partitions on block devices.
1521 C<device> should be a block device, for example C</dev/sda>.
1523 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1524 and sectors on the device, which are passed directly to sfdisk as
1525 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1526 of these, then the corresponding parameter is omitted. Usually for
1527 'large' disks, you can just pass C<0> for these, but for small
1528 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1529 out the right geometry and you will need to tell it.
1531 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1532 information refer to the L<sfdisk(8)> manpage.
1534 To create a single partition occupying the whole disk, you would
1535 pass C<lines> as a single element list, when the single element being
1536 the string C<,> (comma).
1538 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1539 C<guestfs_part_init>");
1541 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning; DeprecatedBy "write"],
1545 This call creates a file called C<path>. The contents of the
1546 file is the string C<content> (which can contain any 8 bit data),
1547 with length C<size>.
1549 As a special case, if C<size> is C<0>
1550 then the length is calculated using C<strlen> (so in this case
1551 the content cannot contain embedded ASCII NULs).
1553 I<NB.> Owing to a bug, writing content containing ASCII NUL
1554 characters does I<not> work, even if the length is specified.");
1556 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1557 [InitEmpty, Always, TestOutputListOfDevices (
1558 [["part_disk"; "/dev/sda"; "mbr"];
1559 ["mkfs"; "ext2"; "/dev/sda1"];
1560 ["mount_options"; ""; "/dev/sda1"; "/"];
1561 ["mounts"]], ["/dev/sda1"]);
1562 InitEmpty, Always, TestOutputList (
1563 [["part_disk"; "/dev/sda"; "mbr"];
1564 ["mkfs"; "ext2"; "/dev/sda1"];
1565 ["mount_options"; ""; "/dev/sda1"; "/"];
1568 "unmount a filesystem",
1570 This unmounts the given filesystem. The filesystem may be
1571 specified either by its mountpoint (path) or the device which
1572 contains the filesystem.");
1574 ("mounts", (RStringList "devices", []), 46, [],
1575 [InitBasicFS, Always, TestOutputListOfDevices (
1576 [["mounts"]], ["/dev/sda1"])],
1577 "show mounted filesystems",
1579 This returns the list of currently mounted filesystems. It returns
1580 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1582 Some internal mounts are not shown.
1584 See also: C<guestfs_mountpoints>");
1586 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1587 [InitBasicFS, Always, TestOutputList (
1590 (* check that umount_all can unmount nested mounts correctly: *)
1591 InitEmpty, Always, TestOutputList (
1592 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1593 ["mkfs"; "ext2"; "/dev/sda1"];
1594 ["mkfs"; "ext2"; "/dev/sda2"];
1595 ["mkfs"; "ext2"; "/dev/sda3"];
1596 ["mount_options"; ""; "/dev/sda1"; "/"];
1598 ["mount_options"; ""; "/dev/sda2"; "/mp1"];
1599 ["mkdir"; "/mp1/mp2"];
1600 ["mount_options"; ""; "/dev/sda3"; "/mp1/mp2"];
1601 ["mkdir"; "/mp1/mp2/mp3"];
1604 "unmount all filesystems",
1606 This unmounts all mounted filesystems.
1608 Some internal mounts are not unmounted by this call.");
1610 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson; Optional "lvm2"],
1612 "remove all LVM LVs, VGs and PVs",
1614 This command removes all LVM logical volumes, volume groups
1615 and physical volumes.");
1617 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1618 [InitISOFS, Always, TestOutput (
1619 [["file"; "/empty"]], "empty");
1620 InitISOFS, Always, TestOutput (
1621 [["file"; "/known-1"]], "ASCII text");
1622 InitISOFS, Always, TestLastFail (
1623 [["file"; "/notexists"]])],
1624 "determine file type",
1626 This call uses the standard L<file(1)> command to determine
1627 the type or contents of the file. This also works on devices,
1628 for example to find out whether a partition contains a filesystem.
1630 This call will also transparently look inside various types
1633 The exact command which runs is C<file -zbsL path>. Note in
1634 particular that the filename is not prepended to the output
1635 (the C<-b> option).");
1637 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1638 [InitBasicFS, Always, TestOutput (
1639 [["upload"; "test-command"; "/test-command"];
1640 ["chmod"; "0o755"; "/test-command"];
1641 ["command"; "/test-command 1"]], "Result1");
1642 InitBasicFS, Always, TestOutput (
1643 [["upload"; "test-command"; "/test-command"];
1644 ["chmod"; "0o755"; "/test-command"];
1645 ["command"; "/test-command 2"]], "Result2\n");
1646 InitBasicFS, Always, TestOutput (
1647 [["upload"; "test-command"; "/test-command"];
1648 ["chmod"; "0o755"; "/test-command"];
1649 ["command"; "/test-command 3"]], "\nResult3");
1650 InitBasicFS, Always, TestOutput (
1651 [["upload"; "test-command"; "/test-command"];
1652 ["chmod"; "0o755"; "/test-command"];
1653 ["command"; "/test-command 4"]], "\nResult4\n");
1654 InitBasicFS, Always, TestOutput (
1655 [["upload"; "test-command"; "/test-command"];
1656 ["chmod"; "0o755"; "/test-command"];
1657 ["command"; "/test-command 5"]], "\nResult5\n\n");
1658 InitBasicFS, Always, TestOutput (
1659 [["upload"; "test-command"; "/test-command"];
1660 ["chmod"; "0o755"; "/test-command"];
1661 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1662 InitBasicFS, Always, TestOutput (
1663 [["upload"; "test-command"; "/test-command"];
1664 ["chmod"; "0o755"; "/test-command"];
1665 ["command"; "/test-command 7"]], "");
1666 InitBasicFS, Always, TestOutput (
1667 [["upload"; "test-command"; "/test-command"];
1668 ["chmod"; "0o755"; "/test-command"];
1669 ["command"; "/test-command 8"]], "\n");
1670 InitBasicFS, Always, TestOutput (
1671 [["upload"; "test-command"; "/test-command"];
1672 ["chmod"; "0o755"; "/test-command"];
1673 ["command"; "/test-command 9"]], "\n\n");
1674 InitBasicFS, Always, TestOutput (
1675 [["upload"; "test-command"; "/test-command"];
1676 ["chmod"; "0o755"; "/test-command"];
1677 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1678 InitBasicFS, Always, TestOutput (
1679 [["upload"; "test-command"; "/test-command"];
1680 ["chmod"; "0o755"; "/test-command"];
1681 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1682 InitBasicFS, Always, TestLastFail (
1683 [["upload"; "test-command"; "/test-command"];
1684 ["chmod"; "0o755"; "/test-command"];
1685 ["command"; "/test-command"]])],
1686 "run a command from the guest filesystem",
1688 This call runs a command from the guest filesystem. The
1689 filesystem must be mounted, and must contain a compatible
1690 operating system (ie. something Linux, with the same
1691 or compatible processor architecture).
1693 The single parameter is an argv-style list of arguments.
1694 The first element is the name of the program to run.
1695 Subsequent elements are parameters. The list must be
1696 non-empty (ie. must contain a program name). Note that
1697 the command runs directly, and is I<not> invoked via
1698 the shell (see C<guestfs_sh>).
1700 The return value is anything printed to I<stdout> by
1703 If the command returns a non-zero exit status, then
1704 this function returns an error message. The error message
1705 string is the content of I<stderr> from the command.
1707 The C<$PATH> environment variable will contain at least
1708 C</usr/bin> and C</bin>. If you require a program from
1709 another location, you should provide the full path in the
1712 Shared libraries and data files required by the program
1713 must be available on filesystems which are mounted in the
1714 correct places. It is the caller's responsibility to ensure
1715 all filesystems that are needed are mounted at the right
1718 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1719 [InitBasicFS, Always, TestOutputList (
1720 [["upload"; "test-command"; "/test-command"];
1721 ["chmod"; "0o755"; "/test-command"];
1722 ["command_lines"; "/test-command 1"]], ["Result1"]);
1723 InitBasicFS, Always, TestOutputList (
1724 [["upload"; "test-command"; "/test-command"];
1725 ["chmod"; "0o755"; "/test-command"];
1726 ["command_lines"; "/test-command 2"]], ["Result2"]);
1727 InitBasicFS, Always, TestOutputList (
1728 [["upload"; "test-command"; "/test-command"];
1729 ["chmod"; "0o755"; "/test-command"];
1730 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1731 InitBasicFS, Always, TestOutputList (
1732 [["upload"; "test-command"; "/test-command"];
1733 ["chmod"; "0o755"; "/test-command"];
1734 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1735 InitBasicFS, Always, TestOutputList (
1736 [["upload"; "test-command"; "/test-command"];
1737 ["chmod"; "0o755"; "/test-command"];
1738 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1739 InitBasicFS, Always, TestOutputList (
1740 [["upload"; "test-command"; "/test-command"];
1741 ["chmod"; "0o755"; "/test-command"];
1742 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1743 InitBasicFS, Always, TestOutputList (
1744 [["upload"; "test-command"; "/test-command"];
1745 ["chmod"; "0o755"; "/test-command"];
1746 ["command_lines"; "/test-command 7"]], []);
1747 InitBasicFS, Always, TestOutputList (
1748 [["upload"; "test-command"; "/test-command"];
1749 ["chmod"; "0o755"; "/test-command"];
1750 ["command_lines"; "/test-command 8"]], [""]);
1751 InitBasicFS, Always, TestOutputList (
1752 [["upload"; "test-command"; "/test-command"];
1753 ["chmod"; "0o755"; "/test-command"];
1754 ["command_lines"; "/test-command 9"]], ["";""]);
1755 InitBasicFS, Always, TestOutputList (
1756 [["upload"; "test-command"; "/test-command"];
1757 ["chmod"; "0o755"; "/test-command"];
1758 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1759 InitBasicFS, Always, TestOutputList (
1760 [["upload"; "test-command"; "/test-command"];
1761 ["chmod"; "0o755"; "/test-command"];
1762 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1763 "run a command, returning lines",
1765 This is the same as C<guestfs_command>, but splits the
1766 result into a list of lines.
1768 See also: C<guestfs_sh_lines>");
1770 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1771 [InitISOFS, Always, TestOutputStruct (
1772 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1773 "get file information",
1775 Returns file information for the given C<path>.
1777 This is the same as the C<stat(2)> system call.");
1779 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1780 [InitISOFS, Always, TestOutputStruct (
1781 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1782 "get file information for a symbolic link",
1784 Returns file information for the given C<path>.
1786 This is the same as C<guestfs_stat> except that if C<path>
1787 is a symbolic link, then the link is stat-ed, not the file it
1790 This is the same as the C<lstat(2)> system call.");
1792 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1793 [InitISOFS, Always, TestOutputStruct (
1794 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1795 "get file system statistics",
1797 Returns file system statistics for any mounted file system.
1798 C<path> should be a file or directory in the mounted file system
1799 (typically it is the mount point itself, but it doesn't need to be).
1801 This is the same as the C<statvfs(2)> system call.");
1803 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1805 "get ext2/ext3/ext4 superblock details",
1807 This returns the contents of the ext2, ext3 or ext4 filesystem
1808 superblock on C<device>.
1810 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1811 manpage for more details. The list of fields returned isn't
1812 clearly defined, and depends on both the version of C<tune2fs>
1813 that libguestfs was built against, and the filesystem itself.");
1815 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1816 [InitEmpty, Always, TestOutputTrue (
1817 [["blockdev_setro"; "/dev/sda"];
1818 ["blockdev_getro"; "/dev/sda"]])],
1819 "set block device to read-only",
1821 Sets the block device named C<device> to read-only.
1823 This uses the L<blockdev(8)> command.");
1825 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1826 [InitEmpty, Always, TestOutputFalse (
1827 [["blockdev_setrw"; "/dev/sda"];
1828 ["blockdev_getro"; "/dev/sda"]])],
1829 "set block device to read-write",
1831 Sets the block device named C<device> to read-write.
1833 This uses the L<blockdev(8)> command.");
1835 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1836 [InitEmpty, Always, TestOutputTrue (
1837 [["blockdev_setro"; "/dev/sda"];
1838 ["blockdev_getro"; "/dev/sda"]])],
1839 "is block device set to read-only",
1841 Returns a boolean indicating if the block device is read-only
1842 (true if read-only, false if not).
1844 This uses the L<blockdev(8)> command.");
1846 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1847 [InitEmpty, Always, TestOutputInt (
1848 [["blockdev_getss"; "/dev/sda"]], 512)],
1849 "get sectorsize of block device",
1851 This returns the size of sectors on a block device.
1852 Usually 512, but can be larger for modern devices.
1854 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1857 This uses the L<blockdev(8)> command.");
1859 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1860 [InitEmpty, Always, TestOutputInt (
1861 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1862 "get blocksize of block device",
1864 This returns the block size of a device.
1866 (Note this is different from both I<size in blocks> and
1867 I<filesystem block size>).
1869 This uses the L<blockdev(8)> command.");
1871 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1873 "set blocksize of block device",
1875 This sets the block size of a device.
1877 (Note this is different from both I<size in blocks> and
1878 I<filesystem block size>).
1880 This uses the L<blockdev(8)> command.");
1882 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1883 [InitEmpty, Always, TestOutputInt (
1884 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1885 "get total size of device in 512-byte sectors",
1887 This returns the size of the device in units of 512-byte sectors
1888 (even if the sectorsize isn't 512 bytes ... weird).
1890 See also C<guestfs_blockdev_getss> for the real sector size of
1891 the device, and C<guestfs_blockdev_getsize64> for the more
1892 useful I<size in bytes>.
1894 This uses the L<blockdev(8)> command.");
1896 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1897 [InitEmpty, Always, TestOutputInt (
1898 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1899 "get total size of device in bytes",
1901 This returns the size of the device in bytes.
1903 See also C<guestfs_blockdev_getsz>.
1905 This uses the L<blockdev(8)> command.");
1907 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1908 [InitEmpty, Always, TestRun
1909 [["blockdev_flushbufs"; "/dev/sda"]]],
1910 "flush device buffers",
1912 This tells the kernel to flush internal buffers associated
1915 This uses the L<blockdev(8)> command.");
1917 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1918 [InitEmpty, Always, TestRun
1919 [["blockdev_rereadpt"; "/dev/sda"]]],
1920 "reread partition table",
1922 Reread the partition table on C<device>.
1924 This uses the L<blockdev(8)> command.");
1926 ("upload", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"]), 66, [],
1927 [InitBasicFS, Always, TestOutput (
1928 (* Pick a file from cwd which isn't likely to change. *)
1929 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1930 ["checksum"; "md5"; "/COPYING.LIB"]],
1931 Digest.to_hex (Digest.file "COPYING.LIB"))],
1932 "upload a file from the local machine",
1934 Upload local file C<filename> to C<remotefilename> on the
1937 C<filename> can also be a named pipe.
1939 See also C<guestfs_download>.");
1941 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1942 [InitBasicFS, Always, TestOutput (
1943 (* Pick a file from cwd which isn't likely to change. *)
1944 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1945 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1946 ["upload"; "testdownload.tmp"; "/upload"];
1947 ["checksum"; "md5"; "/upload"]],
1948 Digest.to_hex (Digest.file "COPYING.LIB"))],
1949 "download a file to the local machine",
1951 Download file C<remotefilename> and save it as C<filename>
1952 on the local machine.
1954 C<filename> can also be a named pipe.
1956 See also C<guestfs_upload>, C<guestfs_cat>.");
1958 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1959 [InitISOFS, Always, TestOutput (
1960 [["checksum"; "crc"; "/known-3"]], "2891671662");
1961 InitISOFS, Always, TestLastFail (
1962 [["checksum"; "crc"; "/notexists"]]);
1963 InitISOFS, Always, TestOutput (
1964 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1965 InitISOFS, Always, TestOutput (
1966 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1967 InitISOFS, Always, TestOutput (
1968 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1969 InitISOFS, Always, TestOutput (
1970 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1971 InitISOFS, Always, TestOutput (
1972 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1973 InitISOFS, Always, TestOutput (
1974 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6");
1975 (* Test for RHBZ#579608, absolute symbolic links. *)
1976 InitISOFS, Always, TestOutput (
1977 [["checksum"; "sha512"; "/abssymlink"]], "5f57d0639bc95081c53afc63a449403883818edc64da48930ad6b1a4fb49be90404686877743fbcd7c99811f3def7df7bc22635c885c6a8cf79c806b43451c1a")],
1978 "compute MD5, SHAx or CRC checksum of file",
1980 This call computes the MD5, SHAx or CRC checksum of the
1983 The type of checksum to compute is given by the C<csumtype>
1984 parameter which must have one of the following values:
1990 Compute the cyclic redundancy check (CRC) specified by POSIX
1991 for the C<cksum> command.
1995 Compute the MD5 hash (using the C<md5sum> program).
1999 Compute the SHA1 hash (using the C<sha1sum> program).
2003 Compute the SHA224 hash (using the C<sha224sum> program).
2007 Compute the SHA256 hash (using the C<sha256sum> program).
2011 Compute the SHA384 hash (using the C<sha384sum> program).
2015 Compute the SHA512 hash (using the C<sha512sum> program).
2019 The checksum is returned as a printable string.
2021 To get the checksum for a device, use C<guestfs_checksum_device>.
2023 To get the checksums for many files, use C<guestfs_checksums_out>.");
2025 ("tar_in", (RErr, [FileIn "tarfile"; Pathname "directory"]), 69, [],
2026 [InitBasicFS, Always, TestOutput (
2027 [["tar_in"; "../images/helloworld.tar"; "/"];
2028 ["cat"; "/hello"]], "hello\n")],
2029 "unpack tarfile to directory",
2031 This command uploads and unpacks local file C<tarfile> (an
2032 I<uncompressed> tar file) into C<directory>.
2034 To upload a compressed tarball, use C<guestfs_tgz_in>
2035 or C<guestfs_txz_in>.");
2037 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
2039 "pack directory into tarfile",
2041 This command packs the contents of C<directory> and downloads
2042 it to local file C<tarfile>.
2044 To download a compressed tarball, use C<guestfs_tgz_out>
2045 or C<guestfs_txz_out>.");
2047 ("tgz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 71, [],
2048 [InitBasicFS, Always, TestOutput (
2049 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
2050 ["cat"; "/hello"]], "hello\n")],
2051 "unpack compressed tarball to directory",
2053 This command uploads and unpacks local file C<tarball> (a
2054 I<gzip compressed> tar file) into C<directory>.
2056 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
2058 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
2060 "pack directory into compressed tarball",
2062 This command packs the contents of C<directory> and downloads
2063 it to local file C<tarball>.
2065 To download an uncompressed tarball, use C<guestfs_tar_out>.");
2067 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
2068 [InitBasicFS, Always, TestLastFail (
2070 ["mount_ro"; "/dev/sda1"; "/"];
2071 ["touch"; "/new"]]);
2072 InitBasicFS, Always, TestOutput (
2073 [["write"; "/new"; "data"];
2075 ["mount_ro"; "/dev/sda1"; "/"];
2076 ["cat"; "/new"]], "data")],
2077 "mount a guest disk, read-only",
2079 This is the same as the C<guestfs_mount> command, but it
2080 mounts the filesystem with the read-only (I<-o ro>) flag.");
2082 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2084 "mount a guest disk with mount options",
2086 This is the same as the C<guestfs_mount> command, but it
2087 allows you to set the mount options as for the
2088 L<mount(8)> I<-o> flag.
2090 If the C<options> parameter is an empty string, then
2091 no options are passed (all options default to whatever
2092 the filesystem uses).");
2094 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2096 "mount a guest disk with mount options and vfstype",
2098 This is the same as the C<guestfs_mount> command, but it
2099 allows you to set both the mount options and the vfstype
2100 as for the L<mount(8)> I<-o> and I<-t> flags.");
2102 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2104 "debugging and internals",
2106 The C<guestfs_debug> command exposes some internals of
2107 C<guestfsd> (the guestfs daemon) that runs inside the
2110 There is no comprehensive help for this command. You have
2111 to look at the file C<daemon/debug.c> in the libguestfs source
2112 to find out what you can do.");
2114 ("lvremove", (RErr, [Device "device"]), 77, [Optional "lvm2"],
2115 [InitEmpty, Always, TestOutputList (
2116 [["part_disk"; "/dev/sda"; "mbr"];
2117 ["pvcreate"; "/dev/sda1"];
2118 ["vgcreate"; "VG"; "/dev/sda1"];
2119 ["lvcreate"; "LV1"; "VG"; "50"];
2120 ["lvcreate"; "LV2"; "VG"; "50"];
2121 ["lvremove"; "/dev/VG/LV1"];
2122 ["lvs"]], ["/dev/VG/LV2"]);
2123 InitEmpty, Always, TestOutputList (
2124 [["part_disk"; "/dev/sda"; "mbr"];
2125 ["pvcreate"; "/dev/sda1"];
2126 ["vgcreate"; "VG"; "/dev/sda1"];
2127 ["lvcreate"; "LV1"; "VG"; "50"];
2128 ["lvcreate"; "LV2"; "VG"; "50"];
2129 ["lvremove"; "/dev/VG"];
2131 InitEmpty, Always, TestOutputList (
2132 [["part_disk"; "/dev/sda"; "mbr"];
2133 ["pvcreate"; "/dev/sda1"];
2134 ["vgcreate"; "VG"; "/dev/sda1"];
2135 ["lvcreate"; "LV1"; "VG"; "50"];
2136 ["lvcreate"; "LV2"; "VG"; "50"];
2137 ["lvremove"; "/dev/VG"];
2139 "remove an LVM logical volume",
2141 Remove an LVM logical volume C<device>, where C<device> is
2142 the path to the LV, such as C</dev/VG/LV>.
2144 You can also remove all LVs in a volume group by specifying
2145 the VG name, C</dev/VG>.");
2147 ("vgremove", (RErr, [String "vgname"]), 78, [Optional "lvm2"],
2148 [InitEmpty, Always, TestOutputList (
2149 [["part_disk"; "/dev/sda"; "mbr"];
2150 ["pvcreate"; "/dev/sda1"];
2151 ["vgcreate"; "VG"; "/dev/sda1"];
2152 ["lvcreate"; "LV1"; "VG"; "50"];
2153 ["lvcreate"; "LV2"; "VG"; "50"];
2156 InitEmpty, Always, TestOutputList (
2157 [["part_disk"; "/dev/sda"; "mbr"];
2158 ["pvcreate"; "/dev/sda1"];
2159 ["vgcreate"; "VG"; "/dev/sda1"];
2160 ["lvcreate"; "LV1"; "VG"; "50"];
2161 ["lvcreate"; "LV2"; "VG"; "50"];
2164 "remove an LVM volume group",
2166 Remove an LVM volume group C<vgname>, (for example C<VG>).
2168 This also forcibly removes all logical volumes in the volume
2171 ("pvremove", (RErr, [Device "device"]), 79, [Optional "lvm2"],
2172 [InitEmpty, Always, TestOutputListOfDevices (
2173 [["part_disk"; "/dev/sda"; "mbr"];
2174 ["pvcreate"; "/dev/sda1"];
2175 ["vgcreate"; "VG"; "/dev/sda1"];
2176 ["lvcreate"; "LV1"; "VG"; "50"];
2177 ["lvcreate"; "LV2"; "VG"; "50"];
2179 ["pvremove"; "/dev/sda1"];
2181 InitEmpty, Always, TestOutputListOfDevices (
2182 [["part_disk"; "/dev/sda"; "mbr"];
2183 ["pvcreate"; "/dev/sda1"];
2184 ["vgcreate"; "VG"; "/dev/sda1"];
2185 ["lvcreate"; "LV1"; "VG"; "50"];
2186 ["lvcreate"; "LV2"; "VG"; "50"];
2188 ["pvremove"; "/dev/sda1"];
2190 InitEmpty, Always, TestOutputListOfDevices (
2191 [["part_disk"; "/dev/sda"; "mbr"];
2192 ["pvcreate"; "/dev/sda1"];
2193 ["vgcreate"; "VG"; "/dev/sda1"];
2194 ["lvcreate"; "LV1"; "VG"; "50"];
2195 ["lvcreate"; "LV2"; "VG"; "50"];
2197 ["pvremove"; "/dev/sda1"];
2199 "remove an LVM physical volume",
2201 This wipes a physical volume C<device> so that LVM will no longer
2204 The implementation uses the C<pvremove> command which refuses to
2205 wipe physical volumes that contain any volume groups, so you have
2206 to remove those first.");
2208 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2209 [InitBasicFS, Always, TestOutput (
2210 [["set_e2label"; "/dev/sda1"; "testlabel"];
2211 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2212 "set the ext2/3/4 filesystem label",
2214 This sets the ext2/3/4 filesystem label of the filesystem on
2215 C<device> to C<label>. Filesystem labels are limited to
2218 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2219 to return the existing label on a filesystem.");
2221 ("get_e2label", (RString "label", [Device "device"]), 81, [],
2223 "get the ext2/3/4 filesystem label",
2225 This returns the ext2/3/4 filesystem label of the filesystem on
2228 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2229 (let uuid = uuidgen () in
2230 [InitBasicFS, Always, TestOutput (
2231 [["set_e2uuid"; "/dev/sda1"; uuid];
2232 ["get_e2uuid"; "/dev/sda1"]], uuid);
2233 InitBasicFS, Always, TestOutput (
2234 [["set_e2uuid"; "/dev/sda1"; "clear"];
2235 ["get_e2uuid"; "/dev/sda1"]], "");
2236 (* We can't predict what UUIDs will be, so just check the commands run. *)
2237 InitBasicFS, Always, TestRun (
2238 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2239 InitBasicFS, Always, TestRun (
2240 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2241 "set the ext2/3/4 filesystem UUID",
2243 This sets the ext2/3/4 filesystem UUID of the filesystem on
2244 C<device> to C<uuid>. The format of the UUID and alternatives
2245 such as C<clear>, C<random> and C<time> are described in the
2246 L<tune2fs(8)> manpage.
2248 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2249 to return the existing UUID of a filesystem.");
2251 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [],
2253 "get the ext2/3/4 filesystem UUID",
2255 This returns the ext2/3/4 filesystem UUID of the filesystem on
2258 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [FishOutput FishOutputHexadecimal],
2259 [InitBasicFS, Always, TestOutputInt (
2260 [["umount"; "/dev/sda1"];
2261 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2262 InitBasicFS, Always, TestOutputInt (
2263 [["umount"; "/dev/sda1"];
2264 ["zero"; "/dev/sda1"];
2265 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2266 "run the filesystem checker",
2268 This runs the filesystem checker (fsck) on C<device> which
2269 should have filesystem type C<fstype>.
2271 The returned integer is the status. See L<fsck(8)> for the
2272 list of status codes from C<fsck>.
2280 Multiple status codes can be summed together.
2284 A non-zero return code can mean \"success\", for example if
2285 errors have been corrected on the filesystem.
2289 Checking or repairing NTFS volumes is not supported
2294 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2296 ("zero", (RErr, [Device "device"]), 85, [],
2297 [InitBasicFS, Always, TestOutput (
2298 [["umount"; "/dev/sda1"];
2299 ["zero"; "/dev/sda1"];
2300 ["file"; "/dev/sda1"]], "data")],
2301 "write zeroes to the device",
2303 This command writes zeroes over the first few blocks of C<device>.
2305 How many blocks are zeroed isn't specified (but it's I<not> enough
2306 to securely wipe the device). It should be sufficient to remove
2307 any partition tables, filesystem superblocks and so on.
2309 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
2311 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2312 (* Test disabled because grub-install incompatible with virtio-blk driver.
2313 * See also: https://bugzilla.redhat.com/show_bug.cgi?id=479760
2315 [InitBasicFS, Disabled, TestOutputTrue (
2316 [["grub_install"; "/"; "/dev/sda1"];
2317 ["is_dir"; "/boot"]])],
2320 This command installs GRUB (the Grand Unified Bootloader) on
2321 C<device>, with the root directory being C<root>.");
2323 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2324 [InitBasicFS, Always, TestOutput (
2325 [["write"; "/old"; "file content"];
2326 ["cp"; "/old"; "/new"];
2327 ["cat"; "/new"]], "file content");
2328 InitBasicFS, Always, TestOutputTrue (
2329 [["write"; "/old"; "file content"];
2330 ["cp"; "/old"; "/new"];
2331 ["is_file"; "/old"]]);
2332 InitBasicFS, Always, TestOutput (
2333 [["write"; "/old"; "file content"];
2335 ["cp"; "/old"; "/dir/new"];
2336 ["cat"; "/dir/new"]], "file content")],
2339 This copies a file from C<src> to C<dest> where C<dest> is
2340 either a destination filename or destination directory.");
2342 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2343 [InitBasicFS, Always, TestOutput (
2344 [["mkdir"; "/olddir"];
2345 ["mkdir"; "/newdir"];
2346 ["write"; "/olddir/file"; "file content"];
2347 ["cp_a"; "/olddir"; "/newdir"];
2348 ["cat"; "/newdir/olddir/file"]], "file content")],
2349 "copy a file or directory recursively",
2351 This copies a file or directory from C<src> to C<dest>
2352 recursively using the C<cp -a> command.");
2354 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2355 [InitBasicFS, Always, TestOutput (
2356 [["write"; "/old"; "file content"];
2357 ["mv"; "/old"; "/new"];
2358 ["cat"; "/new"]], "file content");
2359 InitBasicFS, Always, TestOutputFalse (
2360 [["write"; "/old"; "file content"];
2361 ["mv"; "/old"; "/new"];
2362 ["is_file"; "/old"]])],
2365 This moves a file from C<src> to C<dest> where C<dest> is
2366 either a destination filename or destination directory.");
2368 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2369 [InitEmpty, Always, TestRun (
2370 [["drop_caches"; "3"]])],
2371 "drop kernel page cache, dentries and inodes",
2373 This instructs the guest kernel to drop its page cache,
2374 and/or dentries and inode caches. The parameter C<whattodrop>
2375 tells the kernel what precisely to drop, see
2376 L<http://linux-mm.org/Drop_Caches>
2378 Setting C<whattodrop> to 3 should drop everything.
2380 This automatically calls L<sync(2)> before the operation,
2381 so that the maximum guest memory is freed.");
2383 ("dmesg", (RString "kmsgs", []), 91, [],
2384 [InitEmpty, Always, TestRun (
2386 "return kernel messages",
2388 This returns the kernel messages (C<dmesg> output) from
2389 the guest kernel. This is sometimes useful for extended
2390 debugging of problems.
2392 Another way to get the same information is to enable
2393 verbose messages with C<guestfs_set_verbose> or by setting
2394 the environment variable C<LIBGUESTFS_DEBUG=1> before
2395 running the program.");
2397 ("ping_daemon", (RErr, []), 92, [],
2398 [InitEmpty, Always, TestRun (
2399 [["ping_daemon"]])],
2400 "ping the guest daemon",
2402 This is a test probe into the guestfs daemon running inside
2403 the qemu subprocess. Calling this function checks that the
2404 daemon responds to the ping message, without affecting the daemon
2405 or attached block device(s) in any other way.");
2407 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2408 [InitBasicFS, Always, TestOutputTrue (
2409 [["write"; "/file1"; "contents of a file"];
2410 ["cp"; "/file1"; "/file2"];
2411 ["equal"; "/file1"; "/file2"]]);
2412 InitBasicFS, Always, TestOutputFalse (
2413 [["write"; "/file1"; "contents of a file"];
2414 ["write"; "/file2"; "contents of another file"];
2415 ["equal"; "/file1"; "/file2"]]);
2416 InitBasicFS, Always, TestLastFail (
2417 [["equal"; "/file1"; "/file2"]])],
2418 "test if two files have equal contents",
2420 This compares the two files C<file1> and C<file2> and returns
2421 true if their content is exactly equal, or false otherwise.
2423 The external L<cmp(1)> program is used for the comparison.");
2425 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2426 [InitISOFS, Always, TestOutputList (
2427 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2428 InitISOFS, Always, TestOutputList (
2429 [["strings"; "/empty"]], []);
2430 (* Test for RHBZ#579608, absolute symbolic links. *)
2431 InitISOFS, Always, TestRun (
2432 [["strings"; "/abssymlink"]])],
2433 "print the printable strings in a file",
2435 This runs the L<strings(1)> command on a file and returns
2436 the list of printable strings found.");
2438 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2439 [InitISOFS, Always, TestOutputList (
2440 [["strings_e"; "b"; "/known-5"]], []);
2441 InitBasicFS, Always, TestOutputList (
2442 [["write"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"];
2443 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2444 "print the printable strings in a file",
2446 This is like the C<guestfs_strings> command, but allows you to
2447 specify the encoding of strings that are looked for in
2448 the source file C<path>.
2450 Allowed encodings are:
2456 Single 7-bit-byte characters like ASCII and the ASCII-compatible
2457 parts of ISO-8859-X (this is what C<guestfs_strings> uses).
2461 Single 8-bit-byte characters.
2465 16-bit big endian strings such as those encoded in
2466 UTF-16BE or UCS-2BE.
2468 =item l (lower case letter L)
2470 16-bit little endian such as UTF-16LE and UCS-2LE.
2471 This is useful for examining binaries in Windows guests.
2475 32-bit big endian such as UCS-4BE.
2479 32-bit little endian such as UCS-4LE.
2483 The returned strings are transcoded to UTF-8.");
2485 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2486 [InitISOFS, Always, TestOutput (
2487 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2488 (* Test for RHBZ#501888c2 regression which caused large hexdump
2489 * commands to segfault.
2491 InitISOFS, Always, TestRun (
2492 [["hexdump"; "/100krandom"]]);
2493 (* Test for RHBZ#579608, absolute symbolic links. *)
2494 InitISOFS, Always, TestRun (
2495 [["hexdump"; "/abssymlink"]])],
2496 "dump a file in hexadecimal",
2498 This runs C<hexdump -C> on the given C<path>. The result is
2499 the human-readable, canonical hex dump of the file.");
2501 ("zerofree", (RErr, [Device "device"]), 97, [Optional "zerofree"],
2502 [InitNone, Always, TestOutput (
2503 [["part_disk"; "/dev/sda"; "mbr"];
2504 ["mkfs"; "ext3"; "/dev/sda1"];
2505 ["mount_options"; ""; "/dev/sda1"; "/"];
2506 ["write"; "/new"; "test file"];
2507 ["umount"; "/dev/sda1"];
2508 ["zerofree"; "/dev/sda1"];
2509 ["mount_options"; ""; "/dev/sda1"; "/"];
2510 ["cat"; "/new"]], "test file")],
2511 "zero unused inodes and disk blocks on ext2/3 filesystem",
2513 This runs the I<zerofree> program on C<device>. This program
2514 claims to zero unused inodes and disk blocks on an ext2/3
2515 filesystem, thus making it possible to compress the filesystem
2518 You should B<not> run this program if the filesystem is
2521 It is possible that using this program can damage the filesystem
2522 or data on the filesystem.");
2524 ("pvresize", (RErr, [Device "device"]), 98, [Optional "lvm2"],
2526 "resize an LVM physical volume",
2528 This resizes (expands or shrinks) an existing LVM physical
2529 volume to match the new size of the underlying device.");
2531 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2532 Int "cyls"; Int "heads"; Int "sectors";
2533 String "line"]), 99, [DangerWillRobinson],
2535 "modify a single partition on a block device",
2537 This runs L<sfdisk(8)> option to modify just the single
2538 partition C<n> (note: C<n> counts from 1).
2540 For other parameters, see C<guestfs_sfdisk>. You should usually
2541 pass C<0> for the cyls/heads/sectors parameters.
2543 See also: C<guestfs_part_add>");
2545 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2547 "display the partition table",
2549 This displays the partition table on C<device>, in the
2550 human-readable output of the L<sfdisk(8)> command. It is
2551 not intended to be parsed.
2553 See also: C<guestfs_part_list>");
2555 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2557 "display the kernel geometry",
2559 This displays the kernel's idea of the geometry of C<device>.
2561 The result is in human-readable format, and not designed to
2564 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2566 "display the disk geometry from the partition table",
2568 This displays the disk geometry of C<device> read from the
2569 partition table. Especially in the case where the underlying
2570 block device has been resized, this can be different from the
2571 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2573 The result is in human-readable format, and not designed to
2576 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [Optional "lvm2"],
2578 "activate or deactivate all volume groups",
2580 This command activates or (if C<activate> is false) deactivates
2581 all logical volumes in all volume groups.
2582 If activated, then they are made known to the
2583 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2584 then those devices disappear.
2586 This command is the same as running C<vgchange -a y|n>");
2588 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [Optional "lvm2"],
2590 "activate or deactivate some volume groups",
2592 This command activates or (if C<activate> is false) deactivates
2593 all logical volumes in the listed volume groups C<volgroups>.
2594 If activated, then they are made known to the
2595 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2596 then those devices disappear.
2598 This command is the same as running C<vgchange -a y|n volgroups...>
2600 Note that if C<volgroups> is an empty list then B<all> volume groups
2601 are activated or deactivated.");
2603 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [Optional "lvm2"],
2604 [InitNone, Always, TestOutput (
2605 [["part_disk"; "/dev/sda"; "mbr"];
2606 ["pvcreate"; "/dev/sda1"];
2607 ["vgcreate"; "VG"; "/dev/sda1"];
2608 ["lvcreate"; "LV"; "VG"; "10"];
2609 ["mkfs"; "ext2"; "/dev/VG/LV"];
2610 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2611 ["write"; "/new"; "test content"];
2613 ["lvresize"; "/dev/VG/LV"; "20"];
2614 ["e2fsck_f"; "/dev/VG/LV"];
2615 ["resize2fs"; "/dev/VG/LV"];
2616 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2617 ["cat"; "/new"]], "test content");
2618 InitNone, Always, TestRun (
2619 (* Make an LV smaller to test RHBZ#587484. *)
2620 [["part_disk"; "/dev/sda"; "mbr"];
2621 ["pvcreate"; "/dev/sda1"];
2622 ["vgcreate"; "VG"; "/dev/sda1"];
2623 ["lvcreate"; "LV"; "VG"; "20"];
2624 ["lvresize"; "/dev/VG/LV"; "10"]])],
2625 "resize an LVM logical volume",
2627 This resizes (expands or shrinks) an existing LVM logical
2628 volume to C<mbytes>. When reducing, data in the reduced part
2631 ("resize2fs", (RErr, [Device "device"]), 106, [],
2632 [], (* lvresize tests this *)
2633 "resize an ext2/ext3 filesystem",
2635 This resizes an ext2 or ext3 filesystem to match the size of
2636 the underlying device.
2638 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2639 on the C<device> before calling this command. For unknown reasons
2640 C<resize2fs> sometimes gives an error about this and sometimes not.
2641 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2642 calling this function.");
2644 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2645 [InitBasicFS, Always, TestOutputList (
2646 [["find"; "/"]], ["lost+found"]);
2647 InitBasicFS, Always, TestOutputList (
2651 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2652 InitBasicFS, Always, TestOutputList (
2653 [["mkdir_p"; "/a/b/c"];
2654 ["touch"; "/a/b/c/d"];
2655 ["find"; "/a/b/"]], ["c"; "c/d"])],
2656 "find all files and directories",
2658 This command lists out all files and directories, recursively,
2659 starting at C<directory>. It is essentially equivalent to
2660 running the shell command C<find directory -print> but some
2661 post-processing happens on the output, described below.
2663 This returns a list of strings I<without any prefix>. Thus
2664 if the directory structure was:
2670 then the returned list from C<guestfs_find> C</tmp> would be
2678 If C<directory> is not a directory, then this command returns
2681 The returned list is sorted.
2683 See also C<guestfs_find0>.");
2685 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2686 [], (* lvresize tests this *)
2687 "check an ext2/ext3 filesystem",
2689 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2690 filesystem checker on C<device>, noninteractively (C<-p>),
2691 even if the filesystem appears to be clean (C<-f>).
2693 This command is only needed because of C<guestfs_resize2fs>
2694 (q.v.). Normally you should use C<guestfs_fsck>.");
2696 ("sleep", (RErr, [Int "secs"]), 109, [],
2697 [InitNone, Always, TestRun (
2699 "sleep for some seconds",
2701 Sleep for C<secs> seconds.");
2703 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [Optional "ntfs3g"],
2704 [InitNone, Always, TestOutputInt (
2705 [["part_disk"; "/dev/sda"; "mbr"];
2706 ["mkfs"; "ntfs"; "/dev/sda1"];
2707 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2708 InitNone, Always, TestOutputInt (
2709 [["part_disk"; "/dev/sda"; "mbr"];
2710 ["mkfs"; "ext2"; "/dev/sda1"];
2711 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2712 "probe NTFS volume",
2714 This command runs the L<ntfs-3g.probe(8)> command which probes
2715 an NTFS C<device> for mountability. (Not all NTFS volumes can
2716 be mounted read-write, and some cannot be mounted at all).
2718 C<rw> is a boolean flag. Set it to true if you want to test
2719 if the volume can be mounted read-write. Set it to false if
2720 you want to test if the volume can be mounted read-only.
2722 The return value is an integer which C<0> if the operation
2723 would succeed, or some non-zero value documented in the
2724 L<ntfs-3g.probe(8)> manual page.");
2726 ("sh", (RString "output", [String "command"]), 111, [],
2727 [], (* XXX needs tests *)
2728 "run a command via the shell",
2730 This call runs a command from the guest filesystem via the
2733 This is like C<guestfs_command>, but passes the command to:
2735 /bin/sh -c \"command\"
2737 Depending on the guest's shell, this usually results in
2738 wildcards being expanded, shell expressions being interpolated
2741 All the provisos about C<guestfs_command> apply to this call.");
2743 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2744 [], (* XXX needs tests *)
2745 "run a command via the shell returning lines",
2747 This is the same as C<guestfs_sh>, but splits the result
2748 into a list of lines.
2750 See also: C<guestfs_command_lines>");
2752 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2753 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2754 * code in stubs.c, since all valid glob patterns must start with "/".
2755 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2757 [InitBasicFS, Always, TestOutputList (
2758 [["mkdir_p"; "/a/b/c"];
2759 ["touch"; "/a/b/c/d"];
2760 ["touch"; "/a/b/c/e"];
2761 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2762 InitBasicFS, Always, TestOutputList (
2763 [["mkdir_p"; "/a/b/c"];
2764 ["touch"; "/a/b/c/d"];
2765 ["touch"; "/a/b/c/e"];
2766 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2767 InitBasicFS, Always, TestOutputList (
2768 [["mkdir_p"; "/a/b/c"];
2769 ["touch"; "/a/b/c/d"];
2770 ["touch"; "/a/b/c/e"];
2771 ["glob_expand"; "/a/*/x/*"]], [])],
2772 "expand a wildcard path",
2774 This command searches for all the pathnames matching
2775 C<pattern> according to the wildcard expansion rules
2778 If no paths match, then this returns an empty list
2779 (note: not an error).
2781 It is just a wrapper around the C L<glob(3)> function
2782 with flags C<GLOB_MARK|GLOB_BRACE>.
2783 See that manual page for more details.");
2785 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson; Optional "scrub"],
2786 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2787 [["scrub_device"; "/dev/sdc"]])],
2788 "scrub (securely wipe) a device",
2790 This command writes patterns over C<device> to make data retrieval
2793 It is an interface to the L<scrub(1)> program. See that
2794 manual page for more details.");
2796 ("scrub_file", (RErr, [Pathname "file"]), 115, [Optional "scrub"],
2797 [InitBasicFS, Always, TestRun (
2798 [["write"; "/file"; "content"];
2799 ["scrub_file"; "/file"]])],
2800 "scrub (securely wipe) a file",
2802 This command writes patterns over a file to make data retrieval
2805 The file is I<removed> after scrubbing.
2807 It is an interface to the L<scrub(1)> program. See that
2808 manual page for more details.");
2810 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [Optional "scrub"],
2811 [], (* XXX needs testing *)
2812 "scrub (securely wipe) free space",
2814 This command creates the directory C<dir> and then fills it
2815 with files until the filesystem is full, and scrubs the files
2816 as for C<guestfs_scrub_file>, and deletes them.
2817 The intention is to scrub any free space on the partition
2820 It is an interface to the L<scrub(1)> program. See that
2821 manual page for more details.");
2823 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2824 [InitBasicFS, Always, TestRun (
2826 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2827 "create a temporary directory",
2829 This command creates a temporary directory. The
2830 C<template> parameter should be a full pathname for the
2831 temporary directory name with the final six characters being
2834 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2835 the second one being suitable for Windows filesystems.
2837 The name of the temporary directory that was created
2840 The temporary directory is created with mode 0700
2841 and is owned by root.
2843 The caller is responsible for deleting the temporary
2844 directory and its contents after use.
2846 See also: L<mkdtemp(3)>");
2848 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2849 [InitISOFS, Always, TestOutputInt (
2850 [["wc_l"; "/10klines"]], 10000);
2851 (* Test for RHBZ#579608, absolute symbolic links. *)
2852 InitISOFS, Always, TestOutputInt (
2853 [["wc_l"; "/abssymlink"]], 10000)],
2854 "count lines in a file",
2856 This command counts the lines in a file, using the
2857 C<wc -l> external command.");
2859 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2860 [InitISOFS, Always, TestOutputInt (
2861 [["wc_w"; "/10klines"]], 10000)],
2862 "count words in a file",
2864 This command counts the words in a file, using the
2865 C<wc -w> external command.");
2867 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2868 [InitISOFS, Always, TestOutputInt (
2869 [["wc_c"; "/100kallspaces"]], 102400)],
2870 "count characters in a file",
2872 This command counts the characters in a file, using the
2873 C<wc -c> external command.");
2875 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2876 [InitISOFS, Always, TestOutputList (
2877 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"]);
2878 (* Test for RHBZ#579608, absolute symbolic links. *)
2879 InitISOFS, Always, TestOutputList (
2880 [["head"; "/abssymlink"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2881 "return first 10 lines of a file",
2883 This command returns up to the first 10 lines of a file as
2884 a list of strings.");
2886 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2887 [InitISOFS, Always, TestOutputList (
2888 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2889 InitISOFS, Always, TestOutputList (
2890 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2891 InitISOFS, Always, TestOutputList (
2892 [["head_n"; "0"; "/10klines"]], [])],
2893 "return first N lines of a file",
2895 If the parameter C<nrlines> is a positive number, this returns the first
2896 C<nrlines> lines of the file C<path>.
2898 If the parameter C<nrlines> is a negative number, this returns lines
2899 from the file C<path>, excluding the last C<nrlines> lines.
2901 If the parameter C<nrlines> is zero, this returns an empty list.");
2903 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2904 [InitISOFS, Always, TestOutputList (
2905 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2906 "return last 10 lines of a file",
2908 This command returns up to the last 10 lines of a file as
2909 a list of strings.");
2911 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2912 [InitISOFS, Always, TestOutputList (
2913 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2914 InitISOFS, Always, TestOutputList (
2915 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2916 InitISOFS, Always, TestOutputList (
2917 [["tail_n"; "0"; "/10klines"]], [])],
2918 "return last N lines of a file",
2920 If the parameter C<nrlines> is a positive number, this returns the last
2921 C<nrlines> lines of the file C<path>.
2923 If the parameter C<nrlines> is a negative number, this returns lines
2924 from the file C<path>, starting with the C<-nrlines>th line.
2926 If the parameter C<nrlines> is zero, this returns an empty list.");
2928 ("df", (RString "output", []), 125, [],
2929 [], (* XXX Tricky to test because it depends on the exact format
2930 * of the 'df' command and other imponderables.
2932 "report file system disk space usage",
2934 This command runs the C<df> command to report disk space used.
2936 This command is mostly useful for interactive sessions. It
2937 is I<not> intended that you try to parse the output string.
2938 Use C<statvfs> from programs.");
2940 ("df_h", (RString "output", []), 126, [],
2941 [], (* XXX Tricky to test because it depends on the exact format
2942 * of the 'df' command and other imponderables.
2944 "report file system disk space usage (human readable)",
2946 This command runs the C<df -h> command to report disk space used
2947 in human-readable format.
2949 This command is mostly useful for interactive sessions. It
2950 is I<not> intended that you try to parse the output string.
2951 Use C<statvfs> from programs.");
2953 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2954 [InitISOFS, Always, TestOutputInt (
2955 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2956 "estimate file space usage",
2958 This command runs the C<du -s> command to estimate file space
2961 C<path> can be a file or a directory. If C<path> is a directory
2962 then the estimate includes the contents of the directory and all
2963 subdirectories (recursively).
2965 The result is the estimated size in I<kilobytes>
2966 (ie. units of 1024 bytes).");
2968 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
2969 [InitISOFS, Always, TestOutputList (
2970 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
2971 "list files in an initrd",
2973 This command lists out files contained in an initrd.
2975 The files are listed without any initial C</> character. The
2976 files are listed in the order they appear (not necessarily
2977 alphabetical). Directory names are listed as separate items.
2979 Old Linux kernels (2.4 and earlier) used a compressed ext2
2980 filesystem as initrd. We I<only> support the newer initramfs
2981 format (compressed cpio files).");
2983 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
2985 "mount a file using the loop device",
2987 This command lets you mount C<file> (a filesystem image
2988 in a file) on a mount point. It is entirely equivalent to
2989 the command C<mount -o loop file mountpoint>.");
2991 ("mkswap", (RErr, [Device "device"]), 130, [],
2992 [InitEmpty, Always, TestRun (
2993 [["part_disk"; "/dev/sda"; "mbr"];
2994 ["mkswap"; "/dev/sda1"]])],
2995 "create a swap partition",
2997 Create a swap partition on C<device>.");
2999 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
3000 [InitEmpty, Always, TestRun (
3001 [["part_disk"; "/dev/sda"; "mbr"];
3002 ["mkswap_L"; "hello"; "/dev/sda1"]])],
3003 "create a swap partition with a label",
3005 Create a swap partition on C<device> with label C<label>.
3007 Note that you cannot attach a swap label to a block device
3008 (eg. C</dev/sda>), just to a partition. This appears to be
3009 a limitation of the kernel or swap tools.");
3011 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [Optional "linuxfsuuid"],
3012 (let uuid = uuidgen () in
3013 [InitEmpty, Always, TestRun (
3014 [["part_disk"; "/dev/sda"; "mbr"];
3015 ["mkswap_U"; uuid; "/dev/sda1"]])]),
3016 "create a swap partition with an explicit UUID",
3018 Create a swap partition on C<device> with UUID C<uuid>.");
3020 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [Optional "mknod"],
3021 [InitBasicFS, Always, TestOutputStruct (
3022 [["mknod"; "0o10777"; "0"; "0"; "/node"];
3023 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
3024 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
3025 InitBasicFS, Always, TestOutputStruct (
3026 [["mknod"; "0o60777"; "66"; "99"; "/node"];
3027 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3028 "make block, character or FIFO devices",
3030 This call creates block or character special devices, or
3031 named pipes (FIFOs).
3033 The C<mode> parameter should be the mode, using the standard
3034 constants. C<devmajor> and C<devminor> are the
3035 device major and minor numbers, only used when creating block
3036 and character special devices.
3038 Note that, just like L<mknod(2)>, the mode must be bitwise
3039 OR'd with S_IFBLK, S_IFCHR, S_IFIFO or S_IFSOCK (otherwise this call
3040 just creates a regular file). These constants are
3041 available in the standard Linux header files, or you can use
3042 C<guestfs_mknod_b>, C<guestfs_mknod_c> or C<guestfs_mkfifo>
3043 which are wrappers around this command which bitwise OR
3044 in the appropriate constant for you.
3046 The mode actually set is affected by the umask.");
3048 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [Optional "mknod"],
3049 [InitBasicFS, Always, TestOutputStruct (
3050 [["mkfifo"; "0o777"; "/node"];
3051 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
3052 "make FIFO (named pipe)",
3054 This call creates a FIFO (named pipe) called C<path> with
3055 mode C<mode>. It is just a convenient wrapper around
3058 The mode actually set is affected by the umask.");
3060 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [Optional "mknod"],
3061 [InitBasicFS, Always, TestOutputStruct (
3062 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
3063 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3064 "make block device node",
3066 This call creates a block device node called C<path> with
3067 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3068 It is just a convenient wrapper around C<guestfs_mknod>.
3070 The mode actually set is affected by the umask.");
3072 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [Optional "mknod"],
3073 [InitBasicFS, Always, TestOutputStruct (
3074 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
3075 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
3076 "make char device node",
3078 This call creates a char device node called C<path> with
3079 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3080 It is just a convenient wrapper around C<guestfs_mknod>.
3082 The mode actually set is affected by the umask.");
3084 ("umask", (RInt "oldmask", [Int "mask"]), 137, [FishOutput FishOutputOctal],
3085 [InitEmpty, Always, TestOutputInt (
3086 [["umask"; "0o22"]], 0o22)],
3087 "set file mode creation mask (umask)",
3089 This function sets the mask used for creating new files and
3090 device nodes to C<mask & 0777>.
3092 Typical umask values would be C<022> which creates new files
3093 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
3094 C<002> which creates new files with permissions like
3095 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
3097 The default umask is C<022>. This is important because it
3098 means that directories and device nodes will be created with
3099 C<0644> or C<0755> mode even if you specify C<0777>.
3101 See also C<guestfs_get_umask>,
3102 L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
3104 This call returns the previous umask.");
3106 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
3108 "read directories entries",
3110 This returns the list of directory entries in directory C<dir>.
3112 All entries in the directory are returned, including C<.> and
3113 C<..>. The entries are I<not> sorted, but returned in the same
3114 order as the underlying filesystem.
3116 Also this call returns basic file type information about each
3117 file. The C<ftyp> field will contain one of the following characters:
3155 The L<readdir(3)> call returned a C<d_type> field with an
3160 This function is primarily intended for use by programs. To
3161 get a simple list of names, use C<guestfs_ls>. To get a printable
3162 directory for human consumption, use C<guestfs_ll>.");
3164 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3166 "create partitions on a block device",
3168 This is a simplified interface to the C<guestfs_sfdisk>
3169 command, where partition sizes are specified in megabytes
3170 only (rounded to the nearest cylinder) and you don't need
3171 to specify the cyls, heads and sectors parameters which
3172 were rarely if ever used anyway.
3174 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3175 and C<guestfs_part_disk>");
3177 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3179 "determine file type inside a compressed file",
3181 This command runs C<file> after first decompressing C<path>
3184 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3186 Since 1.0.63, use C<guestfs_file> instead which can now
3187 process compressed files.");
3189 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [Optional "linuxxattrs"],
3191 "list extended attributes of a file or directory",
3193 This call lists the extended attributes of the file or directory
3196 At the system call level, this is a combination of the
3197 L<listxattr(2)> and L<getxattr(2)> calls.
3199 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3201 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [Optional "linuxxattrs"],
3203 "list extended attributes of a file or directory",
3205 This is the same as C<guestfs_getxattrs>, but if C<path>
3206 is a symbolic link, then it returns the extended attributes
3207 of the link itself.");
3209 ("setxattr", (RErr, [String "xattr";
3210 String "val"; Int "vallen"; (* will be BufferIn *)
3211 Pathname "path"]), 143, [Optional "linuxxattrs"],
3213 "set extended attribute of a file or directory",
3215 This call sets the extended attribute named C<xattr>
3216 of the file C<path> to the value C<val> (of length C<vallen>).
3217 The value is arbitrary 8 bit data.
3219 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3221 ("lsetxattr", (RErr, [String "xattr";
3222 String "val"; Int "vallen"; (* will be BufferIn *)
3223 Pathname "path"]), 144, [Optional "linuxxattrs"],
3225 "set extended attribute of a file or directory",
3227 This is the same as C<guestfs_setxattr>, but if C<path>
3228 is a symbolic link, then it sets an extended attribute
3229 of the link itself.");
3231 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [Optional "linuxxattrs"],
3233 "remove extended attribute of a file or directory",
3235 This call removes the extended attribute named C<xattr>
3236 of the file C<path>.
3238 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3240 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [Optional "linuxxattrs"],
3242 "remove extended attribute of a file or directory",
3244 This is the same as C<guestfs_removexattr>, but if C<path>
3245 is a symbolic link, then it removes an extended attribute
3246 of the link itself.");
3248 ("mountpoints", (RHashtable "mps", []), 147, [],
3252 This call is similar to C<guestfs_mounts>. That call returns
3253 a list of devices. This one returns a hash table (map) of
3254 device name to directory where the device is mounted.");
3256 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3257 (* This is a special case: while you would expect a parameter
3258 * of type "Pathname", that doesn't work, because it implies
3259 * NEED_ROOT in the generated calling code in stubs.c, and
3260 * this function cannot use NEED_ROOT.
3263 "create a mountpoint",
3265 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3266 specialized calls that can be used to create extra mountpoints
3267 before mounting the first filesystem.
3269 These calls are I<only> necessary in some very limited circumstances,
3270 mainly the case where you want to mount a mix of unrelated and/or
3271 read-only filesystems together.
3273 For example, live CDs often contain a \"Russian doll\" nest of
3274 filesystems, an ISO outer layer, with a squashfs image inside, with
3275 an ext2/3 image inside that. You can unpack this as follows
3278 add-ro Fedora-11-i686-Live.iso
3281 mkmountpoint /squash
3284 mount-loop /cd/LiveOS/squashfs.img /squash
3285 mount-loop /squash/LiveOS/ext3fs.img /ext3
3287 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3289 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3291 "remove a mountpoint",
3293 This calls removes a mountpoint that was previously created
3294 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3295 for full details.");
3297 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3298 [InitISOFS, Always, TestOutputBuffer (
3299 [["read_file"; "/known-4"]], "abc\ndef\nghi");
3300 (* Test various near large, large and too large files (RHBZ#589039). *)
3301 InitBasicFS, Always, TestLastFail (
3303 ["truncate_size"; "/a"; "4194303"]; (* GUESTFS_MESSAGE_MAX - 1 *)
3304 ["read_file"; "/a"]]);
3305 InitBasicFS, Always, TestLastFail (
3307 ["truncate_size"; "/a"; "4194304"]; (* GUESTFS_MESSAGE_MAX *)
3308 ["read_file"; "/a"]]);
3309 InitBasicFS, Always, TestLastFail (
3311 ["truncate_size"; "/a"; "41943040"]; (* GUESTFS_MESSAGE_MAX * 10 *)
3312 ["read_file"; "/a"]])],
3315 This calls returns the contents of the file C<path> as a
3318 Unlike C<guestfs_cat>, this function can correctly
3319 handle files that contain embedded ASCII NUL characters.
3320 However unlike C<guestfs_download>, this function is limited
3321 in the total size of file that can be handled.");
3323 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3324 [InitISOFS, Always, TestOutputList (
3325 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3326 InitISOFS, Always, TestOutputList (
3327 [["grep"; "nomatch"; "/test-grep.txt"]], []);
3328 (* Test for RHBZ#579608, absolute symbolic links. *)
3329 InitISOFS, Always, TestOutputList (
3330 [["grep"; "nomatch"; "/abssymlink"]], [])],
3331 "return lines matching a pattern",
3333 This calls the external C<grep> program and returns the
3336 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3337 [InitISOFS, Always, TestOutputList (
3338 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3339 "return lines matching a pattern",
3341 This calls the external C<egrep> program and returns the
3344 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3345 [InitISOFS, Always, TestOutputList (
3346 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3347 "return lines matching a pattern",
3349 This calls the external C<fgrep> program and returns the
3352 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3353 [InitISOFS, Always, TestOutputList (
3354 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3355 "return lines matching a pattern",
3357 This calls the external C<grep -i> program and returns the
3360 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3361 [InitISOFS, Always, TestOutputList (
3362 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3363 "return lines matching a pattern",
3365 This calls the external C<egrep -i> program and returns the
3368 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3369 [InitISOFS, Always, TestOutputList (
3370 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3371 "return lines matching a pattern",
3373 This calls the external C<fgrep -i> program and returns the
3376 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3377 [InitISOFS, Always, TestOutputList (
3378 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3379 "return lines matching a pattern",
3381 This calls the external C<zgrep> program and returns the
3384 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3385 [InitISOFS, Always, TestOutputList (
3386 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3387 "return lines matching a pattern",
3389 This calls the external C<zegrep> program and returns the
3392 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3393 [InitISOFS, Always, TestOutputList (
3394 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3395 "return lines matching a pattern",
3397 This calls the external C<zfgrep> program and returns the
3400 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3401 [InitISOFS, Always, TestOutputList (
3402 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3403 "return lines matching a pattern",
3405 This calls the external C<zgrep -i> program and returns the
3408 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3409 [InitISOFS, Always, TestOutputList (
3410 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3411 "return lines matching a pattern",
3413 This calls the external C<zegrep -i> program and returns the
3416 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3417 [InitISOFS, Always, TestOutputList (
3418 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3419 "return lines matching a pattern",
3421 This calls the external C<zfgrep -i> program and returns the
3424 ("realpath", (RString "rpath", [Pathname "path"]), 163, [Optional "realpath"],
3425 [InitISOFS, Always, TestOutput (
3426 [["realpath"; "/../directory"]], "/directory")],
3427 "canonicalized absolute pathname",
3429 Return the canonicalized absolute pathname of C<path>. The
3430 returned path has no C<.>, C<..> or symbolic link path elements.");
3432 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3433 [InitBasicFS, Always, TestOutputStruct (
3436 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3437 "create a hard link",
3439 This command creates a hard link using the C<ln> command.");
3441 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3442 [InitBasicFS, Always, TestOutputStruct (
3445 ["ln_f"; "/a"; "/b"];
3446 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3447 "create a hard link",
3449 This command creates a hard link using the C<ln -f> command.
3450 The C<-f> option removes the link (C<linkname>) if it exists already.");
3452 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3453 [InitBasicFS, Always, TestOutputStruct (
3455 ["ln_s"; "a"; "/b"];
3456 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3457 "create a symbolic link",
3459 This command creates a symbolic link using the C<ln -s> command.");
3461 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3462 [InitBasicFS, Always, TestOutput (
3463 [["mkdir_p"; "/a/b"];
3464 ["touch"; "/a/b/c"];
3465 ["ln_sf"; "../d"; "/a/b/c"];
3466 ["readlink"; "/a/b/c"]], "../d")],
3467 "create a symbolic link",
3469 This command creates a symbolic link using the C<ln -sf> command,
3470 The C<-f> option removes the link (C<linkname>) if it exists already.");
3472 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3473 [] (* XXX tested above *),
3474 "read the target of a symbolic link",
3476 This command reads the target of a symbolic link.");
3478 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"],
3479 [InitBasicFS, Always, TestOutputStruct (
3480 [["fallocate"; "/a"; "1000000"];
3481 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3482 "preallocate a file in the guest filesystem",
3484 This command preallocates a file (containing zero bytes) named
3485 C<path> of size C<len> bytes. If the file exists already, it
3488 Do not confuse this with the guestfish-specific
3489 C<alloc> command which allocates a file in the host and
3490 attaches it as a device.");
3492 ("swapon_device", (RErr, [Device "device"]), 170, [],
3493 [InitPartition, Always, TestRun (
3494 [["mkswap"; "/dev/sda1"];
3495 ["swapon_device"; "/dev/sda1"];
3496 ["swapoff_device"; "/dev/sda1"]])],
3497 "enable swap on device",
3499 This command enables the libguestfs appliance to use the
3500 swap device or partition named C<device>. The increased
3501 memory is made available for all commands, for example
3502 those run using C<guestfs_command> or C<guestfs_sh>.
3504 Note that you should not swap to existing guest swap
3505 partitions unless you know what you are doing. They may
3506 contain hibernation information, or other information that
3507 the guest doesn't want you to trash. You also risk leaking
3508 information about the host to the guest this way. Instead,
3509 attach a new host device to the guest and swap on that.");
3511 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3512 [], (* XXX tested by swapon_device *)
3513 "disable swap on device",
3515 This command disables the libguestfs appliance swap
3516 device or partition named C<device>.
3517 See C<guestfs_swapon_device>.");
3519 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3520 [InitBasicFS, Always, TestRun (
3521 [["fallocate"; "/swap"; "8388608"];
3522 ["mkswap_file"; "/swap"];
3523 ["swapon_file"; "/swap"];
3524 ["swapoff_file"; "/swap"]])],
3525 "enable swap on file",
3527 This command enables swap to a file.
3528 See C<guestfs_swapon_device> for other notes.");
3530 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3531 [], (* XXX tested by swapon_file *)
3532 "disable swap on file",
3534 This command disables the libguestfs appliance swap on file.");
3536 ("swapon_label", (RErr, [String "label"]), 174, [],
3537 [InitEmpty, Always, TestRun (
3538 [["part_disk"; "/dev/sdb"; "mbr"];
3539 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3540 ["swapon_label"; "swapit"];
3541 ["swapoff_label"; "swapit"];
3542 ["zero"; "/dev/sdb"];
3543 ["blockdev_rereadpt"; "/dev/sdb"]])],
3544 "enable swap on labeled swap partition",
3546 This command enables swap to a labeled swap partition.
3547 See C<guestfs_swapon_device> for other notes.");
3549 ("swapoff_label", (RErr, [String "label"]), 175, [],
3550 [], (* XXX tested by swapon_label *)
3551 "disable swap on labeled swap partition",
3553 This command disables the libguestfs appliance swap on
3554 labeled swap partition.");
3556 ("swapon_uuid", (RErr, [String "uuid"]), 176, [Optional "linuxfsuuid"],
3557 (let uuid = uuidgen () in
3558 [InitEmpty, Always, TestRun (
3559 [["mkswap_U"; uuid; "/dev/sdb"];
3560 ["swapon_uuid"; uuid];
3561 ["swapoff_uuid"; uuid]])]),
3562 "enable swap on swap partition by UUID",
3564 This command enables swap to a swap partition with the given UUID.
3565 See C<guestfs_swapon_device> for other notes.");
3567 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [Optional "linuxfsuuid"],
3568 [], (* XXX tested by swapon_uuid *)
3569 "disable swap on swap partition by UUID",
3571 This command disables the libguestfs appliance swap partition
3572 with the given UUID.");
3574 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3575 [InitBasicFS, Always, TestRun (
3576 [["fallocate"; "/swap"; "8388608"];
3577 ["mkswap_file"; "/swap"]])],
3578 "create a swap file",
3582 This command just writes a swap file signature to an existing
3583 file. To create the file itself, use something like C<guestfs_fallocate>.");
3585 ("inotify_init", (RErr, [Int "maxevents"]), 179, [Optional "inotify"],
3586 [InitISOFS, Always, TestRun (
3587 [["inotify_init"; "0"]])],
3588 "create an inotify handle",
3590 This command creates a new inotify handle.
3591 The inotify subsystem can be used to notify events which happen to
3592 objects in the guest filesystem.
3594 C<maxevents> is the maximum number of events which will be
3595 queued up between calls to C<guestfs_inotify_read> or
3596 C<guestfs_inotify_files>.
3597 If this is passed as C<0>, then the kernel (or previously set)
3598 default is used. For Linux 2.6.29 the default was 16384 events.
3599 Beyond this limit, the kernel throws away events, but records
3600 the fact that it threw them away by setting a flag
3601 C<IN_Q_OVERFLOW> in the returned structure list (see
3602 C<guestfs_inotify_read>).
3604 Before any events are generated, you have to add some
3605 watches to the internal watch list. See:
3606 C<guestfs_inotify_add_watch>,
3607 C<guestfs_inotify_rm_watch> and
3608 C<guestfs_inotify_watch_all>.
3610 Queued up events should be read periodically by calling
3611 C<guestfs_inotify_read>
3612 (or C<guestfs_inotify_files> which is just a helpful
3613 wrapper around C<guestfs_inotify_read>). If you don't
3614 read the events out often enough then you risk the internal
3617 The handle should be closed after use by calling
3618 C<guestfs_inotify_close>. This also removes any
3619 watches automatically.
3621 See also L<inotify(7)> for an overview of the inotify interface
3622 as exposed by the Linux kernel, which is roughly what we expose
3623 via libguestfs. Note that there is one global inotify handle
3624 per libguestfs instance.");
3626 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [Optional "inotify"],
3627 [InitBasicFS, Always, TestOutputList (
3628 [["inotify_init"; "0"];
3629 ["inotify_add_watch"; "/"; "1073741823"];
3632 ["inotify_files"]], ["a"; "b"])],
3633 "add an inotify watch",
3635 Watch C<path> for the events listed in C<mask>.
3637 Note that if C<path> is a directory then events within that
3638 directory are watched, but this does I<not> happen recursively
3639 (in subdirectories).
3641 Note for non-C or non-Linux callers: the inotify events are
3642 defined by the Linux kernel ABI and are listed in
3643 C</usr/include/sys/inotify.h>.");
3645 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [Optional "inotify"],
3647 "remove an inotify watch",
3649 Remove a previously defined inotify watch.
3650 See C<guestfs_inotify_add_watch>.");
3652 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [Optional "inotify"],
3654 "return list of inotify events",
3656 Return the complete queue of events that have happened
3657 since the previous read call.
3659 If no events have happened, this returns an empty list.
3661 I<Note>: In order to make sure that all events have been
3662 read, you must call this function repeatedly until it
3663 returns an empty list. The reason is that the call will
3664 read events up to the maximum appliance-to-host message
3665 size and leave remaining events in the queue.");
3667 ("inotify_files", (RStringList "paths", []), 183, [Optional "inotify"],
3669 "return list of watched files that had events",
3671 This function is a helpful wrapper around C<guestfs_inotify_read>
3672 which just returns a list of pathnames of objects that were
3673 touched. The returned pathnames are sorted and deduplicated.");
3675 ("inotify_close", (RErr, []), 184, [Optional "inotify"],
3677 "close the inotify handle",
3679 This closes the inotify handle which was previously
3680 opened by inotify_init. It removes all watches, throws
3681 away any pending events, and deallocates all resources.");
3683 ("setcon", (RErr, [String "context"]), 185, [Optional "selinux"],
3685 "set SELinux security context",
3687 This sets the SELinux security context of the daemon
3688 to the string C<context>.
3690 See the documentation about SELINUX in L<guestfs(3)>.");
3692 ("getcon", (RString "context", []), 186, [Optional "selinux"],
3694 "get SELinux security context",
3696 This gets the SELinux security context of the daemon.
3698 See the documentation about SELINUX in L<guestfs(3)>,
3699 and C<guestfs_setcon>");
3701 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3702 [InitEmpty, Always, TestOutput (
3703 [["part_disk"; "/dev/sda"; "mbr"];
3704 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3705 ["mount_options"; ""; "/dev/sda1"; "/"];
3706 ["write"; "/new"; "new file contents"];
3707 ["cat"; "/new"]], "new file contents")],
3708 "make a filesystem with block size",
3710 This call is similar to C<guestfs_mkfs>, but it allows you to
3711 control the block size of the resulting filesystem. Supported
3712 block sizes depend on the filesystem type, but typically they
3713 are C<1024>, C<2048> or C<4096> only.");
3715 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3716 [InitEmpty, Always, TestOutput (
3717 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3718 ["mke2journal"; "4096"; "/dev/sda1"];
3719 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3720 ["mount_options"; ""; "/dev/sda2"; "/"];
3721 ["write"; "/new"; "new file contents"];
3722 ["cat"; "/new"]], "new file contents")],
3723 "make ext2/3/4 external journal",
3725 This creates an ext2 external journal on C<device>. It is equivalent
3728 mke2fs -O journal_dev -b blocksize device");
3730 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3731 [InitEmpty, Always, TestOutput (
3732 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3733 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3734 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3735 ["mount_options"; ""; "/dev/sda2"; "/"];
3736 ["write"; "/new"; "new file contents"];
3737 ["cat"; "/new"]], "new file contents")],
3738 "make ext2/3/4 external journal with label",
3740 This creates an ext2 external journal on C<device> with label C<label>.");
3742 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [Optional "linuxfsuuid"],
3743 (let uuid = uuidgen () in
3744 [InitEmpty, Always, TestOutput (
3745 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3746 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3747 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3748 ["mount_options"; ""; "/dev/sda2"; "/"];
3749 ["write"; "/new"; "new file contents"];
3750 ["cat"; "/new"]], "new file contents")]),
3751 "make ext2/3/4 external journal with UUID",
3753 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3755 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3757 "make ext2/3/4 filesystem with external journal",
3759 This creates an ext2/3/4 filesystem on C<device> with
3760 an external journal on C<journal>. It is equivalent
3763 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3765 See also C<guestfs_mke2journal>.");
3767 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3769 "make ext2/3/4 filesystem with external journal",
3771 This creates an ext2/3/4 filesystem on C<device> with
3772 an external journal on the journal labeled C<label>.
3774 See also C<guestfs_mke2journal_L>.");
3776 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [Optional "linuxfsuuid"],
3778 "make ext2/3/4 filesystem with external journal",
3780 This creates an ext2/3/4 filesystem on C<device> with
3781 an external journal on the journal with UUID C<uuid>.
3783 See also C<guestfs_mke2journal_U>.");
3785 ("modprobe", (RErr, [String "modulename"]), 194, [Optional "linuxmodules"],
3786 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3787 "load a kernel module",
3789 This loads a kernel module in the appliance.
3791 The kernel module must have been whitelisted when libguestfs
3792 was built (see C<appliance/kmod.whitelist.in> in the source).");
3794 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3795 [InitNone, Always, TestOutput (
3796 [["echo_daemon"; "This is a test"]], "This is a test"
3798 "echo arguments back to the client",
3800 This command concatenates the list of C<words> passed with single spaces
3801 between them and returns the resulting string.
3803 You can use this command to test the connection through to the daemon.
3805 See also C<guestfs_ping_daemon>.");
3807 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3808 [], (* There is a regression test for this. *)
3809 "find all files and directories, returning NUL-separated list",
3811 This command lists out all files and directories, recursively,
3812 starting at C<directory>, placing the resulting list in the
3813 external file called C<files>.
3815 This command works the same way as C<guestfs_find> with the
3816 following exceptions:
3822 The resulting list is written to an external file.
3826 Items (filenames) in the result are separated
3827 by C<\\0> characters. See L<find(1)> option I<-print0>.
3831 This command is not limited in the number of names that it
3836 The result list is not sorted.
3840 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3841 [InitISOFS, Always, TestOutput (
3842 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3843 InitISOFS, Always, TestOutput (
3844 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3845 InitISOFS, Always, TestOutput (
3846 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3847 InitISOFS, Always, TestLastFail (
3848 [["case_sensitive_path"; "/Known-1/"]]);
3849 InitBasicFS, Always, TestOutput (
3851 ["mkdir"; "/a/bbb"];
3852 ["touch"; "/a/bbb/c"];
3853 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3854 InitBasicFS, Always, TestOutput (
3856 ["mkdir"; "/a/bbb"];
3857 ["touch"; "/a/bbb/c"];
3858 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3859 InitBasicFS, Always, TestLastFail (
3861 ["mkdir"; "/a/bbb"];
3862 ["touch"; "/a/bbb/c"];
3863 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3864 "return true path on case-insensitive filesystem",
3866 This can be used to resolve case insensitive paths on
3867 a filesystem which is case sensitive. The use case is
3868 to resolve paths which you have read from Windows configuration
3869 files or the Windows Registry, to the true path.
3871 The command handles a peculiarity of the Linux ntfs-3g
3872 filesystem driver (and probably others), which is that although
3873 the underlying filesystem is case-insensitive, the driver
3874 exports the filesystem to Linux as case-sensitive.
3876 One consequence of this is that special directories such
3877 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3878 (or other things) depending on the precise details of how
3879 they were created. In Windows itself this would not be
3882 Bug or feature? You decide:
3883 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3885 This function resolves the true case of each element in the
3886 path and returns the case-sensitive path.
3888 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3889 might return C<\"/WINDOWS/system32\"> (the exact return value
3890 would depend on details of how the directories were originally
3891 created under Windows).
3894 This function does not handle drive names, backslashes etc.
3896 See also C<guestfs_realpath>.");
3898 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3899 [InitBasicFS, Always, TestOutput (
3900 [["vfs_type"; "/dev/sda1"]], "ext2")],
3901 "get the Linux VFS type corresponding to a mounted device",
3903 This command gets the block device type corresponding to
3904 a mounted device called C<device>.
3906 Usually the result is the name of the Linux VFS module that
3907 is used to mount this device (probably determined automatically
3908 if you used the C<guestfs_mount> call).");
3910 ("truncate", (RErr, [Pathname "path"]), 199, [],
3911 [InitBasicFS, Always, TestOutputStruct (
3912 [["write"; "/test"; "some stuff so size is not zero"];
3913 ["truncate"; "/test"];
3914 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3915 "truncate a file to zero size",
3917 This command truncates C<path> to a zero-length file. The
3918 file must exist already.");
3920 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3921 [InitBasicFS, Always, TestOutputStruct (
3922 [["touch"; "/test"];
3923 ["truncate_size"; "/test"; "1000"];
3924 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3925 "truncate a file to a particular size",
3927 This command truncates C<path> to size C<size> bytes. The file
3928 must exist already. If the file is smaller than C<size> then
3929 the file is extended to the required size with null bytes.");
3931 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3932 [InitBasicFS, Always, TestOutputStruct (
3933 [["touch"; "/test"];
3934 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3935 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3936 "set timestamp of a file with nanosecond precision",
3938 This command sets the timestamps of a file with nanosecond
3941 C<atsecs, atnsecs> are the last access time (atime) in secs and
3942 nanoseconds from the epoch.
3944 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3945 secs and nanoseconds from the epoch.
3947 If the C<*nsecs> field contains the special value C<-1> then
3948 the corresponding timestamp is set to the current time. (The
3949 C<*secs> field is ignored in this case).
3951 If the C<*nsecs> field contains the special value C<-2> then
3952 the corresponding timestamp is left unchanged. (The
3953 C<*secs> field is ignored in this case).");
3955 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
3956 [InitBasicFS, Always, TestOutputStruct (
3957 [["mkdir_mode"; "/test"; "0o111"];
3958 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
3959 "create a directory with a particular mode",
3961 This command creates a directory, setting the initial permissions
3962 of the directory to C<mode>.
3964 For common Linux filesystems, the actual mode which is set will
3965 be C<mode & ~umask & 01777>. Non-native-Linux filesystems may
3966 interpret the mode in other ways.
3968 See also C<guestfs_mkdir>, C<guestfs_umask>");
3970 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
3972 "change file owner and group",
3974 Change the file owner to C<owner> and group to C<group>.
3975 This is like C<guestfs_chown> but if C<path> is a symlink then
3976 the link itself is changed, not the target.
3978 Only numeric uid and gid are supported. If you want to use
3979 names, you will need to locate and parse the password file
3980 yourself (Augeas support makes this relatively easy).");
3982 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
3984 "lstat on multiple files",
3986 This call allows you to perform the C<guestfs_lstat> operation
3987 on multiple files, where all files are in the directory C<path>.
3988 C<names> is the list of files from this directory.
3990 On return you get a list of stat structs, with a one-to-one
3991 correspondence to the C<names> list. If any name did not exist
3992 or could not be lstat'd, then the C<ino> field of that structure
3995 This call is intended for programs that want to efficiently
3996 list a directory contents without making many round-trips.
3997 See also C<guestfs_lxattrlist> for a similarly efficient call
3998 for getting extended attributes. Very long directory listings
3999 might cause the protocol message size to be exceeded, causing
4000 this call to fail. The caller must split up such requests
4001 into smaller groups of names.");
4003 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [Optional "linuxxattrs"],
4005 "lgetxattr on multiple files",
4007 This call allows you to get the extended attributes
4008 of multiple files, where all files are in the directory C<path>.
4009 C<names> is the list of files from this directory.
4011 On return you get a flat list of xattr structs which must be
4012 interpreted sequentially. The first xattr struct always has a zero-length
4013 C<attrname>. C<attrval> in this struct is zero-length
4014 to indicate there was an error doing C<lgetxattr> for this
4015 file, I<or> is a C string which is a decimal number
4016 (the number of following attributes for this file, which could
4017 be C<\"0\">). Then after the first xattr struct are the
4018 zero or more attributes for the first named file.
4019 This repeats for the second and subsequent files.
4021 This call is intended for programs that want to efficiently
4022 list a directory contents without making many round-trips.
4023 See also C<guestfs_lstatlist> for a similarly efficient call
4024 for getting standard stats. Very long directory listings
4025 might cause the protocol message size to be exceeded, causing
4026 this call to fail. The caller must split up such requests
4027 into smaller groups of names.");
4029 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
4031 "readlink on multiple files",
4033 This call allows you to do a C<readlink> operation
4034 on multiple files, where all files are in the directory C<path>.
4035 C<names> is the list of files from this directory.
4037 On return you get a list of strings, with a one-to-one
4038 correspondence to the C<names> list. Each string is the
4039 value of the symbolic link.
4041 If the C<readlink(2)> operation fails on any name, then
4042 the corresponding result string is the empty string C<\"\">.
4043 However the whole operation is completed even if there
4044 were C<readlink(2)> errors, and so you can call this
4045 function with names where you don't know if they are
4046 symbolic links already (albeit slightly less efficient).
4048 This call is intended for programs that want to efficiently
4049 list a directory contents without making many round-trips.
4050 Very long directory listings might cause the protocol
4051 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 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
4056 [InitISOFS, Always, TestOutputBuffer (
4057 [["pread"; "/known-4"; "1"; "3"]], "\n");
4058 InitISOFS, Always, TestOutputBuffer (
4059 [["pread"; "/empty"; "0"; "100"]], "")],
4060 "read part of a file",
4062 This command lets you read part of a file. It reads C<count>
4063 bytes of the file, starting at C<offset>, from file C<path>.
4065 This may read fewer bytes than requested. For further details
4066 see the L<pread(2)> system call.
4068 See also C<guestfs_pwrite>.");
4070 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
4071 [InitEmpty, Always, TestRun (
4072 [["part_init"; "/dev/sda"; "gpt"]])],
4073 "create an empty partition table",
4075 This creates an empty partition table on C<device> of one of the
4076 partition types listed below. Usually C<parttype> should be
4077 either C<msdos> or C<gpt> (for large disks).
4079 Initially there are no partitions. Following this, you should
4080 call C<guestfs_part_add> for each partition required.
4082 Possible values for C<parttype> are:
4086 =item B<efi> | B<gpt>
4088 Intel EFI / GPT partition table.
4090 This is recommended for >= 2 TB partitions that will be accessed
4091 from Linux and Intel-based Mac OS X. It also has limited backwards
4092 compatibility with the C<mbr> format.
4094 =item B<mbr> | B<msdos>
4096 The standard PC \"Master Boot Record\" (MBR) format used
4097 by MS-DOS and Windows. This partition type will B<only> work
4098 for device sizes up to 2 TB. For large disks we recommend
4103 Other partition table types that may work but are not
4112 =item B<amiga> | B<rdb>
4114 Amiga \"Rigid Disk Block\" format.
4122 DASD, used on IBM mainframes.
4130 Old Mac partition format. Modern Macs use C<gpt>.
4134 NEC PC-98 format, common in Japan apparently.
4142 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
4143 [InitEmpty, Always, TestRun (
4144 [["part_init"; "/dev/sda"; "mbr"];
4145 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
4146 InitEmpty, Always, TestRun (
4147 [["part_init"; "/dev/sda"; "gpt"];
4148 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
4149 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
4150 InitEmpty, Always, TestRun (
4151 [["part_init"; "/dev/sda"; "mbr"];
4152 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
4153 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
4154 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
4155 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
4156 "add a partition to the device",
4158 This command adds a partition to C<device>. If there is no partition
4159 table on the device, call C<guestfs_part_init> first.
4161 The C<prlogex> parameter is the type of partition. Normally you
4162 should pass C<p> or C<primary> here, but MBR partition tables also
4163 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4166 C<startsect> and C<endsect> are the start and end of the partition
4167 in I<sectors>. C<endsect> may be negative, which means it counts
4168 backwards from the end of the disk (C<-1> is the last sector).
4170 Creating a partition which covers the whole disk is not so easy.
4171 Use C<guestfs_part_disk> to do that.");
4173 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4174 [InitEmpty, Always, TestRun (
4175 [["part_disk"; "/dev/sda"; "mbr"]]);
4176 InitEmpty, Always, TestRun (
4177 [["part_disk"; "/dev/sda"; "gpt"]])],
4178 "partition whole disk with a single primary partition",
4180 This command is simply a combination of C<guestfs_part_init>
4181 followed by C<guestfs_part_add> to create a single primary partition
4182 covering the whole disk.
4184 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4185 but other possible values are described in C<guestfs_part_init>.");
4187 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4188 [InitEmpty, Always, TestRun (
4189 [["part_disk"; "/dev/sda"; "mbr"];
4190 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4191 "make a partition bootable",
4193 This sets the bootable flag on partition numbered C<partnum> on
4194 device C<device>. Note that partitions are numbered from 1.
4196 The bootable flag is used by some operating systems (notably
4197 Windows) to determine which partition to boot from. It is by
4198 no means universally recognized.");
4200 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4201 [InitEmpty, Always, TestRun (
4202 [["part_disk"; "/dev/sda"; "gpt"];
4203 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4204 "set partition name",
4206 This sets the partition name on partition numbered C<partnum> on
4207 device C<device>. Note that partitions are numbered from 1.
4209 The partition name can only be set on certain types of partition
4210 table. This works on C<gpt> but not on C<mbr> partitions.");
4212 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4213 [], (* XXX Add a regression test for this. *)
4214 "list partitions on a device",
4216 This command parses the partition table on C<device> and
4217 returns the list of partitions found.
4219 The fields in the returned structure are:
4225 Partition number, counting from 1.
4229 Start of the partition I<in bytes>. To get sectors you have to
4230 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4234 End of the partition in bytes.
4238 Size of the partition in bytes.
4242 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4243 [InitEmpty, Always, TestOutput (
4244 [["part_disk"; "/dev/sda"; "gpt"];
4245 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4246 "get the partition table type",
4248 This command examines the partition table on C<device> and
4249 returns the partition table type (format) being used.
4251 Common return values include: C<msdos> (a DOS/Windows style MBR
4252 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4253 values are possible, although unusual. See C<guestfs_part_init>
4256 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4257 [InitBasicFS, Always, TestOutputBuffer (
4258 [["fill"; "0x63"; "10"; "/test"];
4259 ["read_file"; "/test"]], "cccccccccc")],
4260 "fill a file with octets",
4262 This command creates a new file called C<path>. The initial
4263 content of the file is C<len> octets of C<c>, where C<c>
4264 must be a number in the range C<[0..255]>.
4266 To fill a file with zero bytes (sparsely), it is
4267 much more efficient to use C<guestfs_truncate_size>.
4268 To create a file with a pattern of repeating bytes
4269 use C<guestfs_fill_pattern>.");
4271 ("available", (RErr, [StringList "groups"]), 216, [],
4272 [InitNone, Always, TestRun [["available"; ""]]],
4273 "test availability of some parts of the API",
4275 This command is used to check the availability of some
4276 groups of functionality in the appliance, which not all builds of
4277 the libguestfs appliance will be able to provide.
4279 The libguestfs groups, and the functions that those
4280 groups correspond to, are listed in L<guestfs(3)/AVAILABILITY>.
4281 You can also fetch this list at runtime by calling
4282 C<guestfs_available_all_groups>.
4284 The argument C<groups> is a list of group names, eg:
4285 C<[\"inotify\", \"augeas\"]> would check for the availability of
4286 the Linux inotify functions and Augeas (configuration file
4289 The command returns no error if I<all> requested groups are available.
4291 It fails with an error if one or more of the requested
4292 groups is unavailable in the appliance.
4294 If an unknown group name is included in the
4295 list of groups then an error is always returned.
4303 You must call C<guestfs_launch> before calling this function.
4305 The reason is because we don't know what groups are
4306 supported by the appliance/daemon until it is running and can
4311 If a group of functions is available, this does not necessarily
4312 mean that they will work. You still have to check for errors
4313 when calling individual API functions even if they are
4318 It is usually the job of distro packagers to build
4319 complete functionality into the libguestfs appliance.
4320 Upstream libguestfs, if built from source with all
4321 requirements satisfied, will support everything.
4325 This call was added in version C<1.0.80>. In previous
4326 versions of libguestfs all you could do would be to speculatively
4327 execute a command to find out if the daemon implemented it.
4328 See also C<guestfs_version>.
4332 ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [],
4333 [InitBasicFS, Always, TestOutputBuffer (
4334 [["write"; "/src"; "hello, world"];
4335 ["dd"; "/src"; "/dest"];
4336 ["read_file"; "/dest"]], "hello, world")],
4337 "copy from source to destination using dd",
4339 This command copies from one source device or file C<src>
4340 to another destination device or file C<dest>. Normally you
4341 would use this to copy to or from a device or partition, for
4342 example to duplicate a filesystem.
4344 If the destination is a device, it must be as large or larger
4345 than the source file or device, otherwise the copy will fail.
4346 This command cannot do partial copies (see C<guestfs_copy_size>).");
4348 ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
4349 [InitBasicFS, Always, TestOutputInt (
4350 [["write"; "/file"; "hello, world"];
4351 ["filesize"; "/file"]], 12)],
4352 "return the size of the file in bytes",
4354 This command returns the size of C<file> in bytes.
4356 To get other stats about a file, use C<guestfs_stat>, C<guestfs_lstat>,
4357 C<guestfs_is_dir>, C<guestfs_is_file> etc.
4358 To get the size of block devices, use C<guestfs_blockdev_getsize64>.");
4360 ("lvrename", (RErr, [String "logvol"; String "newlogvol"]), 219, [],
4361 [InitBasicFSonLVM, Always, TestOutputList (
4362 [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
4363 ["lvs"]], ["/dev/VG/LV2"])],
4364 "rename an LVM logical volume",
4366 Rename a logical volume C<logvol> with the new name C<newlogvol>.");
4368 ("vgrename", (RErr, [String "volgroup"; String "newvolgroup"]), 220, [],
4369 [InitBasicFSonLVM, Always, TestOutputList (
4371 ["vg_activate"; "false"; "VG"];
4372 ["vgrename"; "VG"; "VG2"];
4373 ["vg_activate"; "true"; "VG2"];
4374 ["mount_options"; ""; "/dev/VG2/LV"; "/"];
4375 ["vgs"]], ["VG2"])],
4376 "rename an LVM volume group",
4378 Rename a volume group C<volgroup> with the new name C<newvolgroup>.");
4380 ("initrd_cat", (RBufferOut "content", [Pathname "initrdpath"; String "filename"]), 221, [ProtocolLimitWarning],
4381 [InitISOFS, Always, TestOutputBuffer (
4382 [["initrd_cat"; "/initrd"; "known-4"]], "abc\ndef\nghi")],
4383 "list the contents of a single file in an initrd",
4385 This command unpacks the file C<filename> from the initrd file
4386 called C<initrdpath>. The filename must be given I<without> the
4387 initial C</> character.
4389 For example, in guestfish you could use the following command
4390 to examine the boot script (usually called C</init>)
4391 contained in a Linux initrd or initramfs image:
4393 initrd-cat /boot/initrd-<version>.img init
4395 See also C<guestfs_initrd_list>.");
4397 ("pvuuid", (RString "uuid", [Device "device"]), 222, [],
4399 "get the UUID of a physical volume",
4401 This command returns the UUID of the LVM PV C<device>.");
4403 ("vguuid", (RString "uuid", [String "vgname"]), 223, [],
4405 "get the UUID of a volume group",
4407 This command returns the UUID of the LVM VG named C<vgname>.");
4409 ("lvuuid", (RString "uuid", [Device "device"]), 224, [],
4411 "get the UUID of a logical volume",
4413 This command returns the UUID of the LVM LV C<device>.");
4415 ("vgpvuuids", (RStringList "uuids", [String "vgname"]), 225, [],
4417 "get the PV UUIDs containing the volume group",
4419 Given a VG called C<vgname>, this returns the UUIDs of all
4420 the physical volumes that this volume group resides on.
4422 You can use this along with C<guestfs_pvs> and C<guestfs_pvuuid>
4423 calls to associate physical volumes and volume groups.
4425 See also C<guestfs_vglvuuids>.");
4427 ("vglvuuids", (RStringList "uuids", [String "vgname"]), 226, [],
4429 "get the LV UUIDs of all LVs in the volume group",
4431 Given a VG called C<vgname>, this returns the UUIDs of all
4432 the logical volumes created in this volume group.
4434 You can use this along with C<guestfs_lvs> and C<guestfs_lvuuid>
4435 calls to associate logical volumes and volume groups.
4437 See also C<guestfs_vgpvuuids>.");
4439 ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
4440 [InitBasicFS, Always, TestOutputBuffer (
4441 [["write"; "/src"; "hello, world"];
4442 ["copy_size"; "/src"; "/dest"; "5"];
4443 ["read_file"; "/dest"]], "hello")],
4444 "copy size bytes from source to destination using dd",
4446 This command copies exactly C<size> bytes from one source device
4447 or file C<src> to another destination device or file C<dest>.
4449 Note this will fail if the source is too short or if the destination
4450 is not large enough.");
4452 ("zero_device", (RErr, [Device "device"]), 228, [DangerWillRobinson],
4453 [InitBasicFSonLVM, Always, TestRun (
4454 [["zero_device"; "/dev/VG/LV"]])],
4455 "write zeroes to an entire device",
4457 This command writes zeroes over the entire C<device>. Compare
4458 with C<guestfs_zero> which just zeroes the first few blocks of
4461 ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"],
4462 [InitBasicFS, Always, TestOutput (
4463 [["txz_in"; "../images/helloworld.tar.xz"; "/"];
4464 ["cat"; "/hello"]], "hello\n")],
4465 "unpack compressed tarball to directory",
4467 This command uploads and unpacks local file C<tarball> (an
4468 I<xz compressed> tar file) into C<directory>.");
4470 ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"],
4472 "pack directory into compressed tarball",
4474 This command packs the contents of C<directory> and downloads
4475 it to local file C<tarball> (as an xz compressed tar archive).");
4477 ("ntfsresize", (RErr, [Device "device"]), 231, [Optional "ntfsprogs"],
4479 "resize an NTFS filesystem",
4481 This command resizes an NTFS filesystem, expanding or
4482 shrinking it to the size of the underlying device.
4483 See also L<ntfsresize(8)>.");
4485 ("vgscan", (RErr, []), 232, [],
4486 [InitEmpty, Always, TestRun (
4488 "rescan for LVM physical volumes, volume groups and logical volumes",
4490 This rescans all block devices and rebuilds the list of LVM
4491 physical volumes, volume groups and logical volumes.");
4493 ("part_del", (RErr, [Device "device"; Int "partnum"]), 233, [],
4494 [InitEmpty, Always, TestRun (
4495 [["part_init"; "/dev/sda"; "mbr"];
4496 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4497 ["part_del"; "/dev/sda"; "1"]])],
4498 "delete a partition",
4500 This command deletes the partition numbered C<partnum> on C<device>.
4502 Note that in the case of MBR partitioning, deleting an
4503 extended partition also deletes any logical partitions
4506 ("part_get_bootable", (RBool "bootable", [Device "device"; Int "partnum"]), 234, [],
4507 [InitEmpty, Always, TestOutputTrue (
4508 [["part_init"; "/dev/sda"; "mbr"];
4509 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4510 ["part_set_bootable"; "/dev/sda"; "1"; "true"];
4511 ["part_get_bootable"; "/dev/sda"; "1"]])],
4512 "return true if a partition is bootable",
4514 This command returns true if the partition C<partnum> on
4515 C<device> has the bootable flag set.
4517 See also C<guestfs_part_set_bootable>.");
4519 ("part_get_mbr_id", (RInt "idbyte", [Device "device"; Int "partnum"]), 235, [FishOutput FishOutputHexadecimal],
4520 [InitEmpty, Always, TestOutputInt (
4521 [["part_init"; "/dev/sda"; "mbr"];
4522 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4523 ["part_set_mbr_id"; "/dev/sda"; "1"; "0x7f"];
4524 ["part_get_mbr_id"; "/dev/sda"; "1"]], 0x7f)],
4525 "get the MBR type byte (ID byte) from a partition",
4527 Returns the MBR type byte (also known as the ID byte) from
4528 the numbered partition C<partnum>.
4530 Note that only MBR (old DOS-style) partitions have type bytes.
4531 You will get undefined results for other partition table
4532 types (see C<guestfs_part_get_parttype>).");
4534 ("part_set_mbr_id", (RErr, [Device "device"; Int "partnum"; Int "idbyte"]), 236, [],
4535 [], (* tested by part_get_mbr_id *)
4536 "set the MBR type byte (ID byte) of a partition",
4538 Sets the MBR type byte (also known as the ID byte) of
4539 the numbered partition C<partnum> to C<idbyte>. Note
4540 that the type bytes quoted in most documentation are
4541 in fact hexadecimal numbers, but usually documented
4542 without any leading \"0x\" which might be confusing.
4544 Note that only MBR (old DOS-style) partitions have type bytes.
4545 You will get undefined results for other partition table
4546 types (see C<guestfs_part_get_parttype>).");
4548 ("checksum_device", (RString "checksum", [String "csumtype"; Device "device"]), 237, [],
4549 [InitISOFS, Always, TestOutput (
4550 [["checksum_device"; "md5"; "/dev/sdd"]],
4551 (Digest.to_hex (Digest.file "images/test.iso")))],
4552 "compute MD5, SHAx or CRC checksum of the contents of a device",
4554 This call computes the MD5, SHAx or CRC checksum of the
4555 contents of the device named C<device>. For the types of
4556 checksums supported see the C<guestfs_checksum> command.");
4558 ("lvresize_free", (RErr, [Device "lv"; Int "percent"]), 238, [Optional "lvm2"],
4559 [InitNone, Always, TestRun (
4560 [["part_disk"; "/dev/sda"; "mbr"];
4561 ["pvcreate"; "/dev/sda1"];
4562 ["vgcreate"; "VG"; "/dev/sda1"];
4563 ["lvcreate"; "LV"; "VG"; "10"];
4564 ["lvresize_free"; "/dev/VG/LV"; "100"]])],
4565 "expand an LV to fill free space",
4567 This expands an existing logical volume C<lv> so that it fills
4568 C<pc>% of the remaining free space in the volume group. Commonly
4569 you would call this with pc = 100 which expands the logical volume
4570 as much as possible, using all remaining free space in the volume
4573 ("aug_clear", (RErr, [String "augpath"]), 239, [Optional "augeas"],
4574 [], (* XXX Augeas code needs tests. *)
4575 "clear Augeas path",
4577 Set the value associated with C<path> to C<NULL>. This
4578 is the same as the L<augtool(1)> C<clear> command.");
4580 ("get_umask", (RInt "mask", []), 240, [FishOutput FishOutputOctal],
4581 [InitEmpty, Always, TestOutputInt (
4582 [["get_umask"]], 0o22)],
4583 "get the current umask",
4585 Return the current umask. By default the umask is C<022>
4586 unless it has been set by calling C<guestfs_umask>.");
4588 ("debug_upload", (RErr, [FileIn "filename"; String "tmpname"; Int "mode"]), 241, [],
4590 "upload a file to the appliance (internal use only)",
4592 The C<guestfs_debug_upload> command uploads a file to
4593 the libguestfs appliance.
4595 There is no comprehensive help for this command. You have
4596 to look at the file C<daemon/debug.c> in the libguestfs source
4597 to find out what it is for.");
4599 ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
4600 [InitBasicFS, Always, TestOutput (
4601 [["base64_in"; "../images/hello.b64"; "/hello"];
4602 ["cat"; "/hello"]], "hello\n")],
4603 "upload base64-encoded data to file",
4605 This command uploads base64-encoded data from C<base64file>
4608 ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
4610 "download file and encode as base64",
4612 This command downloads the contents of C<filename>, writing
4613 it out to local file C<base64file> encoded as base64.");
4615 ("checksums_out", (RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"]), 244, [],
4617 "compute MD5, SHAx or CRC checksum of files in a directory",
4619 This command computes the checksums of all regular files in
4620 C<directory> and then emits a list of those checksums to
4621 the local output file C<sumsfile>.
4623 This can be used for verifying the integrity of a virtual
4624 machine. However to be properly secure you should pay
4625 attention to the output of the checksum command (it uses
4626 the ones from GNU coreutils). In particular when the
4627 filename is not printable, coreutils uses a special
4628 backslash syntax. For more information, see the GNU
4629 coreutils info file.");
4631 ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
4632 [InitBasicFS, Always, TestOutputBuffer (
4633 [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
4634 ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
4635 "fill a file with a repeating pattern of bytes",
4637 This function is like C<guestfs_fill> except that it creates
4638 a new file of length C<len> containing the repeating pattern
4639 of bytes in C<pattern>. The pattern is truncated if necessary
4640 to ensure the length of the file is exactly C<len> bytes.");
4642 ("write", (RErr, [Pathname "path"; BufferIn "content"]), 246, [ProtocolLimitWarning],
4643 [InitBasicFS, Always, TestOutput (
4644 [["write"; "/new"; "new file contents"];
4645 ["cat"; "/new"]], "new file contents");
4646 InitBasicFS, Always, TestOutput (
4647 [["write"; "/new"; "\nnew file contents\n"];
4648 ["cat"; "/new"]], "\nnew file contents\n");
4649 InitBasicFS, Always, TestOutput (
4650 [["write"; "/new"; "\n\n"];
4651 ["cat"; "/new"]], "\n\n");
4652 InitBasicFS, Always, TestOutput (
4653 [["write"; "/new"; ""];
4654 ["cat"; "/new"]], "");
4655 InitBasicFS, Always, TestOutput (
4656 [["write"; "/new"; "\n\n\n"];
4657 ["cat"; "/new"]], "\n\n\n");
4658 InitBasicFS, Always, TestOutput (
4659 [["write"; "/new"; "\n"];
4660 ["cat"; "/new"]], "\n")],
4661 "create a new file",
4663 This call creates a file called C<path>. The content of the
4664 file is the string C<content> (which can contain any 8 bit data).");
4666 ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
4667 [InitBasicFS, Always, TestOutput (
4668 [["write"; "/new"; "new file contents"];
4669 ["pwrite"; "/new"; "data"; "4"];
4670 ["cat"; "/new"]], "new data contents");
4671 InitBasicFS, Always, TestOutput (
4672 [["write"; "/new"; "new file contents"];
4673 ["pwrite"; "/new"; "is extended"; "9"];
4674 ["cat"; "/new"]], "new file is extended");
4675 InitBasicFS, Always, TestOutput (
4676 [["write"; "/new"; "new file contents"];
4677 ["pwrite"; "/new"; ""; "4"];
4678 ["cat"; "/new"]], "new file contents")],
4679 "write to part of a file",
4681 This command writes to part of a file. It writes the data
4682 buffer C<content> to the file C<path> starting at offset C<offset>.
4684 This command implements the L<pwrite(2)> system call, and like
4685 that system call it may not write the full data requested. The
4686 return value is the number of bytes that were actually written
4687 to the file. This could even be 0, although short writes are
4688 unlikely for regular files in ordinary circumstances.
4690 See also C<guestfs_pread>.");
4692 ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [],
4694 "resize an ext2/ext3 filesystem (with size)",
4696 This command is the same as C<guestfs_resize2fs> except that it
4697 allows you to specify the new size (in bytes) explicitly.");
4699 ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"],
4701 "resize an LVM physical volume (with size)",
4703 This command is the same as C<guestfs_pvresize> except that it
4704 allows you to specify the new size (in bytes) explicitly.");
4706 ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"],
4708 "resize an NTFS filesystem (with size)",
4710 This command is the same as C<guestfs_ntfsresize> except that it
4711 allows you to specify the new size (in bytes) explicitly.");
4713 ("available_all_groups", (RStringList "groups", []), 251, [],
4714 [InitNone, Always, TestRun [["available_all_groups"]]],
4715 "return a list of all optional groups",
4717 This command returns a list of all optional groups that this
4718 daemon knows about. Note this returns both supported and unsupported
4719 groups. To find out which ones the daemon can actually support
4720 you have to call C<guestfs_available> on each member of the
4723 See also C<guestfs_available> and L<guestfs(3)/AVAILABILITY>.");
4725 ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [],
4726 [InitBasicFS, Always, TestOutputStruct (
4727 [["fallocate64"; "/a"; "1000000"];
4728 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
4729 "preallocate a file in the guest filesystem",
4731 This command preallocates a file (containing zero bytes) named
4732 C<path> of size C<len> bytes. If the file exists already, it
4735 Note that this call allocates disk blocks for the file.
4736 To create a sparse file use C<guestfs_truncate_size> instead.
4738 The deprecated call C<guestfs_fallocate> does the same,
4739 but owing to an oversight it only allowed 30 bit lengths
4740 to be specified, effectively limiting the maximum size
4741 of files created through that call to 1GB.
4743 Do not confuse this with the guestfish-specific
4744 C<alloc> and C<sparse> commands which create
4745 a file in the host and attach it as a device.");
4749 let all_functions = non_daemon_functions @ daemon_functions
4751 (* In some places we want the functions to be displayed sorted
4752 * alphabetically, so this is useful:
4754 let all_functions_sorted =
4755 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4756 compare n1 n2) all_functions
4758 (* This is used to generate the src/MAX_PROC_NR file which
4759 * contains the maximum procedure number, a surrogate for the
4760 * ABI version number. See src/Makefile.am for the details.
4763 let proc_nrs = List.map (
4764 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
4765 ) daemon_functions in
4766 List.fold_left max 0 proc_nrs
4768 (* Field types for structures. *)
4770 | FChar (* C 'char' (really, a 7 bit byte). *)
4771 | FString (* nul-terminated ASCII string, NOT NULL. *)
4772 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4777 | FBytes (* Any int measure that counts bytes. *)
4778 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4779 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4781 (* Because we generate extra parsing code for LVM command line tools,
4782 * we have to pull out the LVM columns separately here.
4792 "pv_attr", FString (* XXX *);
4793 "pv_pe_count", FInt64;
4794 "pv_pe_alloc_count", FInt64;
4797 "pv_mda_count", FInt64;
4798 "pv_mda_free", FBytes;
4799 (* Not in Fedora 10:
4800 "pv_mda_size", FBytes;
4807 "vg_attr", FString (* XXX *);
4810 "vg_sysid", FString;
4811 "vg_extent_size", FBytes;
4812 "vg_extent_count", FInt64;
4813 "vg_free_count", FInt64;
4818 "snap_count", FInt64;
4821 "vg_mda_count", FInt64;
4822 "vg_mda_free", FBytes;
4823 (* Not in Fedora 10:
4824 "vg_mda_size", FBytes;
4830 "lv_attr", FString (* XXX *);
4833 "lv_kernel_major", FInt64;
4834 "lv_kernel_minor", FInt64;
4836 "seg_count", FInt64;
4838 "snap_percent", FOptPercent;
4839 "copy_percent", FOptPercent;
4842 "mirror_log", FString;
4846 (* Names and fields in all structures (in RStruct and RStructList)
4850 (* The old RIntBool return type, only ever used for aug_defnode. Do
4851 * not use this struct in any new code.
4854 "i", FInt32; (* for historical compatibility *)
4855 "b", FInt32; (* for historical compatibility *)
4858 (* LVM PVs, VGs, LVs. *)
4859 "lvm_pv", lvm_pv_cols;
4860 "lvm_vg", lvm_vg_cols;
4861 "lvm_lv", lvm_lv_cols;
4863 (* Column names and types from stat structures.
4864 * NB. Can't use things like 'st_atime' because glibc header files
4865 * define some of these as macros. Ugh.
4896 (* Column names in dirent structure. *)
4899 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4904 (* Version numbers. *)
4912 (* Extended attribute. *)
4914 "attrname", FString;
4918 (* Inotify events. *)
4922 "in_cookie", FUInt32;
4926 (* Partition table entry. *)
4929 "part_start", FBytes;
4931 "part_size", FBytes;
4933 ] (* end of structs *)
4935 (* Ugh, Java has to be different ..
4936 * These names are also used by the Haskell bindings.
4938 let java_structs = [
4939 "int_bool", "IntBool";
4944 "statvfs", "StatVFS";
4946 "version", "Version";
4948 "inotify_event", "INotifyEvent";
4949 "partition", "Partition";
4952 (* What structs are actually returned. *)
4953 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
4955 (* Returns a list of RStruct/RStructList structs that are returned
4956 * by any function. Each element of returned list is a pair:
4958 * (structname, RStructOnly)
4959 * == there exists function which returns RStruct (_, structname)
4960 * (structname, RStructListOnly)
4961 * == there exists function which returns RStructList (_, structname)
4962 * (structname, RStructAndList)
4963 * == there are functions returning both RStruct (_, structname)
4964 * and RStructList (_, structname)
4966 let rstructs_used_by functions =
4967 (* ||| is a "logical OR" for rstructs_used_t *)
4971 | _, RStructAndList -> RStructAndList
4972 | RStructOnly, RStructListOnly
4973 | RStructListOnly, RStructOnly -> RStructAndList
4974 | RStructOnly, RStructOnly -> RStructOnly
4975 | RStructListOnly, RStructListOnly -> RStructListOnly
4978 let h = Hashtbl.create 13 in
4980 (* if elem->oldv exists, update entry using ||| operator,
4981 * else just add elem->newv to the hash
4983 let update elem newv =
4984 try let oldv = Hashtbl.find h elem in
4985 Hashtbl.replace h elem (newv ||| oldv)
4986 with Not_found -> Hashtbl.add h elem newv
4990 fun (_, style, _, _, _, _, _) ->
4991 match fst style with
4992 | RStruct (_, structname) -> update structname RStructOnly
4993 | RStructList (_, structname) -> update structname RStructListOnly
4997 (* return key->values as a list of (key,value) *)
4998 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
5000 (* Used for testing language bindings. *)
5002 | CallString of string
5003 | CallOptString of string option
5004 | CallStringList of string list
5006 | CallInt64 of int64
5008 | CallBuffer of string
5010 (* Used to memoize the result of pod2text. *)
5011 let pod2text_memo_filename = "src/.pod2text.data"
5012 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
5014 let chan = open_in pod2text_memo_filename in
5015 let v = input_value chan in
5019 _ -> Hashtbl.create 13
5020 let pod2text_memo_updated () =
5021 let chan = open_out pod2text_memo_filename in
5022 output_value chan pod2text_memo;
5025 (* Useful functions.
5026 * Note we don't want to use any external OCaml libraries which
5027 * makes this a bit harder than it should be.
5029 module StringMap = Map.Make (String)
5031 let failwithf fs = ksprintf failwith fs
5033 let unique = let i = ref 0 in fun () -> incr i; !i
5035 let replace_char s c1 c2 =
5036 let s2 = String.copy s in
5037 let r = ref false in
5038 for i = 0 to String.length s2 - 1 do
5039 if String.unsafe_get s2 i = c1 then (
5040 String.unsafe_set s2 i c2;
5044 if not !r then s else s2
5048 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
5050 let triml ?(test = isspace) str =
5052 let n = ref (String.length str) in
5053 while !n > 0 && test str.[!i]; do
5058 else String.sub str !i !n
5060 let trimr ?(test = isspace) str =
5061 let n = ref (String.length str) in
5062 while !n > 0 && test str.[!n-1]; do
5065 if !n = String.length str then str
5066 else String.sub str 0 !n
5068 let trim ?(test = isspace) str =
5069 trimr ~test (triml ~test str)
5071 let rec find s sub =
5072 let len = String.length s in
5073 let sublen = String.length sub in
5075 if i <= len-sublen then (
5077 if j < sublen then (
5078 if s.[i+j] = sub.[j] then loop2 (j+1)
5084 if r = -1 then loop (i+1) else r
5090 let rec replace_str s s1 s2 =
5091 let len = String.length s in
5092 let sublen = String.length s1 in
5093 let i = find s s1 in
5096 let s' = String.sub s 0 i in
5097 let s'' = String.sub s (i+sublen) (len-i-sublen) in
5098 s' ^ s2 ^ replace_str s'' s1 s2
5101 let rec string_split sep str =
5102 let len = String.length str in
5103 let seplen = String.length sep in
5104 let i = find str sep in
5105 if i = -1 then [str]
5107 let s' = String.sub str 0 i in
5108 let s'' = String.sub str (i+seplen) (len-i-seplen) in
5109 s' :: string_split sep s''
5112 let files_equal n1 n2 =
5113 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
5114 match Sys.command cmd with
5117 | i -> failwithf "%s: failed with error code %d" cmd i
5119 let rec filter_map f = function
5123 | Some y -> y :: filter_map f xs
5124 | None -> filter_map f xs
5126 let rec find_map f = function
5127 | [] -> raise Not_found
5131 | None -> find_map f xs
5134 let rec loop i = function
5136 | x :: xs -> f i x; loop (i+1) xs
5141 let rec loop i = function
5143 | x :: xs -> let r = f i x in r :: loop (i+1) xs
5147 let count_chars c str =
5148 let count = ref 0 in
5149 for i = 0 to String.length str - 1 do
5150 if c = String.unsafe_get str i then incr count
5156 for i = 0 to String.length str - 1 do
5157 let c = String.unsafe_get str i in
5162 let map_chars f str =
5163 List.map f (explode str)
5165 let name_of_argt = function
5166 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
5167 | StringList n | DeviceList n | Bool n | Int n | Int64 n
5168 | FileIn n | FileOut n | BufferIn n -> n
5170 let java_name_of_struct typ =
5171 try List.assoc typ java_structs
5174 "java_name_of_struct: no java_structs entry corresponding to %s" typ
5176 let cols_of_struct typ =
5177 try List.assoc typ structs
5179 failwithf "cols_of_struct: unknown struct %s" typ
5181 let seq_of_test = function
5182 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
5183 | TestOutputListOfDevices (s, _)
5184 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
5185 | TestOutputTrue s | TestOutputFalse s
5186 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
5187 | TestOutputStruct (s, _)
5188 | TestLastFail s -> s
5190 (* Handling for function flags. *)
5191 let protocol_limit_warning =
5192 "Because of the message protocol, there is a transfer limit
5193 of somewhere between 2MB and 4MB. See L<guestfs(3)/PROTOCOL LIMITS>."
5195 let danger_will_robinson =
5196 "B<This command is dangerous. Without careful use you
5197 can easily destroy all your data>."
5199 let deprecation_notice flags =
5202 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
5204 sprintf "This function is deprecated.
5205 In new code, use the C<%s> call instead.
5207 Deprecated functions will not be removed from the API, but the
5208 fact that they are deprecated indicates that there are problems
5209 with correct use of these functions." alt in
5214 (* Create list of optional groups. *)
5216 let h = Hashtbl.create 13 in
5218 fun (name, _, _, flags, _, _, _) ->
5222 let names = try Hashtbl.find h group with Not_found -> [] in
5223 Hashtbl.replace h group (name :: names)
5227 let groups = Hashtbl.fold (fun k _ ks -> k :: ks) h [] in
5230 fun group -> group, List.sort compare (Hashtbl.find h group)
5232 List.sort (fun x y -> compare (fst x) (fst y)) groups
5234 (* Check function names etc. for consistency. *)
5235 let check_functions () =
5236 let contains_uppercase str =
5237 let len = String.length str in
5239 if i >= len then false
5242 if c >= 'A' && c <= 'Z' then true
5249 (* Check function names. *)
5251 fun (name, _, _, _, _, _, _) ->
5252 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
5253 failwithf "function name %s does not need 'guestfs' prefix" name;
5255 failwithf "function name is empty";
5256 if name.[0] < 'a' || name.[0] > 'z' then
5257 failwithf "function name %s must start with lowercase a-z" name;
5258 if String.contains name '-' then
5259 failwithf "function name %s should not contain '-', use '_' instead."
5263 (* Check function parameter/return names. *)
5265 fun (name, style, _, _, _, _, _) ->
5266 let check_arg_ret_name n =
5267 if contains_uppercase n then
5268 failwithf "%s param/ret %s should not contain uppercase chars"
5270 if String.contains n '-' || String.contains n '_' then
5271 failwithf "%s param/ret %s should not contain '-' or '_'"
5274 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;
5275 if n = "int" || n = "char" || n = "short" || n = "long" then
5276 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
5277 if n = "i" || n = "n" then
5278 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
5279 if n = "argv" || n = "args" then
5280 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
5282 (* List Haskell, OCaml and C keywords here.
5283 * http://www.haskell.org/haskellwiki/Keywords
5284 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
5285 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
5286 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
5287 * |perl -pe 's/(.+)/"$1";/'|fmt -70
5288 * Omitting _-containing words, since they're handled above.
5289 * Omitting the OCaml reserved word, "val", is ok,
5290 * and saves us from renaming several parameters.
5293 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
5294 "char"; "class"; "const"; "constraint"; "continue"; "data";
5295 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
5296 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
5297 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
5298 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
5299 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
5301 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
5302 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
5303 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
5304 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
5305 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
5306 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
5307 "volatile"; "when"; "where"; "while";
5309 if List.mem n reserved then
5310 failwithf "%s has param/ret using reserved word %s" name n;
5313 (match fst style with
5315 | RInt n | RInt64 n | RBool n
5316 | RConstString n | RConstOptString n | RString n
5317 | RStringList n | RStruct (n, _) | RStructList (n, _)
5318 | RHashtable n | RBufferOut n ->
5319 check_arg_ret_name n
5321 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
5324 (* Check short descriptions. *)
5326 fun (name, _, _, _, _, shortdesc, _) ->
5327 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
5328 failwithf "short description of %s should begin with lowercase." name;
5329 let c = shortdesc.[String.length shortdesc-1] in
5330 if c = '\n' || c = '.' then
5331 failwithf "short description of %s should not end with . or \\n." name
5334 (* Check long descriptions. *)
5336 fun (name, _, _, _, _, _, longdesc) ->
5337 if longdesc.[String.length longdesc-1] = '\n' then
5338 failwithf "long description of %s should not end with \\n." name
5341 (* Check proc_nrs. *)
5343 fun (name, _, proc_nr, _, _, _, _) ->
5344 if proc_nr <= 0 then
5345 failwithf "daemon function %s should have proc_nr > 0" name
5349 fun (name, _, proc_nr, _, _, _, _) ->
5350 if proc_nr <> -1 then
5351 failwithf "non-daemon function %s should have proc_nr -1" name
5352 ) non_daemon_functions;
5355 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
5358 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
5359 let rec loop = function
5362 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
5364 | (name1,nr1) :: (name2,nr2) :: _ ->
5365 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
5373 (* Ignore functions that have no tests. We generate a
5374 * warning when the user does 'make check' instead.
5376 | name, _, _, _, [], _, _ -> ()
5377 | name, _, _, _, tests, _, _ ->
5381 match seq_of_test test with
5383 failwithf "%s has a test containing an empty sequence" name
5384 | cmds -> List.map List.hd cmds
5386 let funcs = List.flatten funcs in
5388 let tested = List.mem name funcs in
5391 failwithf "function %s has tests but does not test itself" name
5394 (* 'pr' prints to the current output file. *)
5395 let chan = ref Pervasives.stdout
5400 let i = count_chars '\n' str in
5401 lines := !lines + i;
5402 output_string !chan str
5405 let copyright_years =
5406 let this_year = 1900 + (localtime (time ())).tm_year in
5407 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
5409 (* Generate a header block in a number of standard styles. *)
5410 type comment_style =
5411 CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
5412 type license = GPLv2plus | LGPLv2plus
5414 let generate_header ?(extra_inputs = []) comment license =
5415 let inputs = "src/generator.ml" :: extra_inputs in
5416 let c = match comment with
5417 | CStyle -> pr "/* "; " *"
5418 | CPlusPlusStyle -> pr "// "; "//"
5419 | HashStyle -> pr "# "; "#"
5420 | OCamlStyle -> pr "(* "; " *"
5421 | HaskellStyle -> pr "{- "; " " in
5422 pr "libguestfs generated file\n";
5423 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
5424 List.iter (pr "%s %s\n" c) inputs;
5425 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
5427 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
5431 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
5432 pr "%s it under the terms of the GNU General Public License as published by\n" c;
5433 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
5434 pr "%s (at your option) any later version.\n" c;
5436 pr "%s This program is distributed in the hope that it will be useful,\n" c;
5437 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5438 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
5439 pr "%s GNU General Public License for more details.\n" c;
5441 pr "%s You should have received a copy of the GNU General Public License along\n" c;
5442 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
5443 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
5446 pr "%s This library is free software; you can redistribute it and/or\n" c;
5447 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
5448 pr "%s License as published by the Free Software Foundation; either\n" c;
5449 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
5451 pr "%s This library is distributed in the hope that it will be useful,\n" c;
5452 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5453 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
5454 pr "%s Lesser General Public License for more details.\n" c;
5456 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
5457 pr "%s License along with this library; if not, write to the Free Software\n" c;
5458 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
5461 | CStyle -> pr " */\n"
5464 | OCamlStyle -> pr " *)\n"
5465 | HaskellStyle -> pr "-}\n"
5469 (* Start of main code generation functions below this line. *)
5471 (* Generate the pod documentation for the C API. *)
5472 let rec generate_actions_pod () =
5474 fun (shortname, style, _, flags, _, _, longdesc) ->
5475 if not (List.mem NotInDocs flags) then (
5476 let name = "guestfs_" ^ shortname in
5477 pr "=head2 %s\n\n" name;
5479 generate_prototype ~extern:false ~handle:"g" name style;
5481 pr "%s\n\n" longdesc;
5482 (match fst style with
5484 pr "This function returns 0 on success or -1 on error.\n\n"
5486 pr "On error this function returns -1.\n\n"
5488 pr "On error this function returns -1.\n\n"
5490 pr "This function returns a C truth value on success or -1 on error.\n\n"
5492 pr "This function returns a string, or NULL on error.
5493 The string is owned by the guest handle and must I<not> be freed.\n\n"
5494 | RConstOptString _ ->
5495 pr "This function returns a string which may be NULL.
5496 There is way to return an error from this function.
5497 The string is owned by the guest handle and must I<not> be freed.\n\n"
5499 pr "This function returns a string, or NULL on error.
5500 I<The caller must free the returned string after use>.\n\n"
5502 pr "This function returns a NULL-terminated array of strings
5503 (like L<environ(3)>), or NULL if there was an error.
5504 I<The caller must free the strings and the array after use>.\n\n"
5505 | RStruct (_, typ) ->
5506 pr "This function returns a C<struct guestfs_%s *>,
5507 or NULL if there was an error.
5508 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
5509 | RStructList (_, typ) ->
5510 pr "This function returns a C<struct guestfs_%s_list *>
5511 (see E<lt>guestfs-structs.hE<gt>),
5512 or NULL if there was an error.
5513 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
5515 pr "This function returns a NULL-terminated array of
5516 strings, or NULL if there was an error.
5517 The array of strings will always have length C<2n+1>, where
5518 C<n> keys and values alternate, followed by the trailing NULL entry.
5519 I<The caller must free the strings and the array after use>.\n\n"
5521 pr "This function returns a buffer, or NULL on error.
5522 The size of the returned buffer is written to C<*size_r>.
5523 I<The caller must free the returned buffer after use>.\n\n"
5525 if List.mem ProtocolLimitWarning flags then
5526 pr "%s\n\n" protocol_limit_warning;
5527 if List.mem DangerWillRobinson flags then
5528 pr "%s\n\n" danger_will_robinson;
5529 match deprecation_notice flags with
5531 | Some txt -> pr "%s\n\n" txt
5533 ) all_functions_sorted
5535 and generate_structs_pod () =
5536 (* Structs documentation. *)
5539 pr "=head2 guestfs_%s\n" typ;
5541 pr " struct guestfs_%s {\n" typ;
5544 | name, FChar -> pr " char %s;\n" name
5545 | name, FUInt32 -> pr " uint32_t %s;\n" name
5546 | name, FInt32 -> pr " int32_t %s;\n" name
5547 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5548 | name, FInt64 -> pr " int64_t %s;\n" name
5549 | name, FString -> pr " char *%s;\n" name
5551 pr " /* The next two fields describe a byte array. */\n";
5552 pr " uint32_t %s_len;\n" name;
5553 pr " char *%s;\n" name
5555 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
5556 pr " char %s[32];\n" name
5557 | name, FOptPercent ->
5558 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
5559 pr " float %s;\n" name
5563 pr " struct guestfs_%s_list {\n" typ;
5564 pr " uint32_t len; /* Number of elements in list. */\n";
5565 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
5568 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
5569 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
5574 and generate_availability_pod () =
5575 (* Availability documentation. *)
5579 fun (group, functions) ->
5580 pr "=item B<%s>\n" group;
5582 pr "The following functions:\n";
5583 List.iter (pr "L</guestfs_%s>\n") functions;
5589 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
5590 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
5592 * We have to use an underscore instead of a dash because otherwise
5593 * rpcgen generates incorrect code.
5595 * This header is NOT exported to clients, but see also generate_structs_h.
5597 and generate_xdr () =
5598 generate_header CStyle LGPLv2plus;
5600 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
5601 pr "typedef string str<>;\n";
5604 (* Internal structures. *)
5608 pr "struct guestfs_int_%s {\n" typ;
5610 | name, FChar -> pr " char %s;\n" name
5611 | name, FString -> pr " string %s<>;\n" name
5612 | name, FBuffer -> pr " opaque %s<>;\n" name
5613 | name, FUUID -> pr " opaque %s[32];\n" name
5614 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
5615 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
5616 | name, FOptPercent -> pr " float %s;\n" name
5620 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
5625 fun (shortname, style, _, _, _, _, _) ->
5626 let name = "guestfs_" ^ shortname in
5628 (match snd style with
5631 pr "struct %s_args {\n" name;
5634 | Pathname n | Device n | Dev_or_Path n | String n ->
5635 pr " string %s<>;\n" n
5636 | OptString n -> pr " str *%s;\n" n
5637 | StringList n | DeviceList n -> pr " str %s<>;\n" n
5638 | Bool n -> pr " bool %s;\n" n
5639 | Int n -> pr " int %s;\n" n
5640 | Int64 n -> pr " hyper %s;\n" n
5642 pr " opaque %s<>;\n" n
5643 | FileIn _ | FileOut _ -> ()
5647 (match fst style with
5650 pr "struct %s_ret {\n" name;
5654 pr "struct %s_ret {\n" name;
5655 pr " hyper %s;\n" n;
5658 pr "struct %s_ret {\n" name;
5661 | RConstString _ | RConstOptString _ ->
5662 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5664 pr "struct %s_ret {\n" name;
5665 pr " string %s<>;\n" n;
5668 pr "struct %s_ret {\n" name;
5669 pr " str %s<>;\n" n;
5671 | RStruct (n, typ) ->
5672 pr "struct %s_ret {\n" name;
5673 pr " guestfs_int_%s %s;\n" typ n;
5675 | RStructList (n, typ) ->
5676 pr "struct %s_ret {\n" name;
5677 pr " guestfs_int_%s_list %s;\n" typ n;
5680 pr "struct %s_ret {\n" name;
5681 pr " str %s<>;\n" n;
5684 pr "struct %s_ret {\n" name;
5685 pr " opaque %s<>;\n" n;
5690 (* Table of procedure numbers. *)
5691 pr "enum guestfs_procedure {\n";
5693 fun (shortname, _, proc_nr, _, _, _, _) ->
5694 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5696 pr " GUESTFS_PROC_NR_PROCS\n";
5700 (* Having to choose a maximum message size is annoying for several
5701 * reasons (it limits what we can do in the API), but it (a) makes
5702 * the protocol a lot simpler, and (b) provides a bound on the size
5703 * of the daemon which operates in limited memory space.
5705 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5708 (* Message header, etc. *)
5710 /* The communication protocol is now documented in the guestfs(3)
5714 const GUESTFS_PROGRAM = 0x2000F5F5;
5715 const GUESTFS_PROTOCOL_VERSION = 1;
5717 /* These constants must be larger than any possible message length. */
5718 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5719 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5721 enum guestfs_message_direction {
5722 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5723 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5726 enum guestfs_message_status {
5727 GUESTFS_STATUS_OK = 0,
5728 GUESTFS_STATUS_ERROR = 1
5731 const GUESTFS_ERROR_LEN = 256;
5733 struct guestfs_message_error {
5734 string error_message<GUESTFS_ERROR_LEN>;
5737 struct guestfs_message_header {
5738 unsigned prog; /* GUESTFS_PROGRAM */
5739 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5740 guestfs_procedure proc; /* GUESTFS_PROC_x */
5741 guestfs_message_direction direction;
5742 unsigned serial; /* message serial number */
5743 guestfs_message_status status;
5746 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5748 struct guestfs_chunk {
5749 int cancel; /* if non-zero, transfer is cancelled */
5750 /* data size is 0 bytes if the transfer has finished successfully */
5751 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5755 (* Generate the guestfs-structs.h file. *)
5756 and generate_structs_h () =
5757 generate_header CStyle LGPLv2plus;
5759 (* This is a public exported header file containing various
5760 * structures. The structures are carefully written to have
5761 * exactly the same in-memory format as the XDR structures that
5762 * we use on the wire to the daemon. The reason for creating
5763 * copies of these structures here is just so we don't have to
5764 * export the whole of guestfs_protocol.h (which includes much
5765 * unrelated and XDR-dependent stuff that we don't want to be
5766 * public, or required by clients).
5768 * To reiterate, we will pass these structures to and from the
5769 * client with a simple assignment or memcpy, so the format
5770 * must be identical to what rpcgen / the RFC defines.
5773 (* Public structures. *)
5776 pr "struct guestfs_%s {\n" typ;
5779 | name, FChar -> pr " char %s;\n" name
5780 | name, FString -> pr " char *%s;\n" name
5782 pr " uint32_t %s_len;\n" name;
5783 pr " char *%s;\n" name
5784 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5785 | name, FUInt32 -> pr " uint32_t %s;\n" name
5786 | name, FInt32 -> pr " int32_t %s;\n" name
5787 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5788 | name, FInt64 -> pr " int64_t %s;\n" name
5789 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5793 pr "struct guestfs_%s_list {\n" typ;
5794 pr " uint32_t len;\n";
5795 pr " struct guestfs_%s *val;\n" typ;
5798 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5799 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5803 (* Generate the guestfs-actions.h file. *)
5804 and generate_actions_h () =
5805 generate_header CStyle LGPLv2plus;
5807 fun (shortname, style, _, _, _, _, _) ->
5808 let name = "guestfs_" ^ shortname in
5809 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5813 (* Generate the guestfs-internal-actions.h file. *)
5814 and generate_internal_actions_h () =
5815 generate_header CStyle LGPLv2plus;
5817 fun (shortname, style, _, _, _, _, _) ->
5818 let name = "guestfs__" ^ shortname in
5819 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5821 ) non_daemon_functions
5823 (* Generate the client-side dispatch stubs. *)
5824 and generate_client_actions () =
5825 generate_header CStyle LGPLv2plus;
5832 #include <inttypes.h>
5834 #include \"guestfs.h\"
5835 #include \"guestfs-internal.h\"
5836 #include \"guestfs-internal-actions.h\"
5837 #include \"guestfs_protocol.h\"
5839 #define error guestfs_error
5840 //#define perrorf guestfs_perrorf
5841 #define safe_malloc guestfs_safe_malloc
5842 #define safe_realloc guestfs_safe_realloc
5843 //#define safe_strdup guestfs_safe_strdup
5844 #define safe_memdup guestfs_safe_memdup
5846 /* Check the return message from a call for validity. */
5848 check_reply_header (guestfs_h *g,
5849 const struct guestfs_message_header *hdr,
5850 unsigned int proc_nr, unsigned int serial)
5852 if (hdr->prog != GUESTFS_PROGRAM) {
5853 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5856 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5857 error (g, \"wrong protocol version (%%d/%%d)\",
5858 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5861 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5862 error (g, \"unexpected message direction (%%d/%%d)\",
5863 hdr->direction, GUESTFS_DIRECTION_REPLY);
5866 if (hdr->proc != proc_nr) {
5867 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5870 if (hdr->serial != serial) {
5871 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5878 /* Check we are in the right state to run a high-level action. */
5880 check_state (guestfs_h *g, const char *caller)
5882 if (!guestfs__is_ready (g)) {
5883 if (guestfs__is_config (g) || guestfs__is_launching (g))
5884 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5887 error (g, \"%%s called from the wrong state, %%d != READY\",
5888 caller, guestfs__get_state (g));
5896 let error_code_of = function
5897 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5898 | RConstString _ | RConstOptString _
5899 | RString _ | RStringList _
5900 | RStruct _ | RStructList _
5901 | RHashtable _ | RBufferOut _ -> "NULL"
5904 (* Generate code to check String-like parameters are not passed in
5905 * as NULL (returning an error if they are).
5907 let check_null_strings shortname style =
5908 let pr_newline = ref false in
5911 (* parameters which should not be NULL *)
5921 pr " if (%s == NULL) {\n" n;
5922 pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
5923 pr " \"%s\", \"%s\");\n" shortname n;
5924 pr " return %s;\n" (error_code_of (fst style));
5931 (* not applicable *)
5937 if !pr_newline then pr "\n";
5940 (* Generate code to generate guestfish call traces. *)
5941 let trace_call shortname style =
5942 pr " if (guestfs__get_trace (g)) {\n";
5945 List.exists (function
5946 | StringList _ | DeviceList _ -> true
5947 | _ -> false) (snd style) in
5953 pr " printf (\"%s\");\n" shortname;
5956 | String n (* strings *)
5963 (* guestfish doesn't support string escaping, so neither do we *)
5964 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
5965 | OptString n -> (* string option *)
5966 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
5967 pr " else printf (\" null\");\n"
5969 | DeviceList n -> (* string list *)
5970 pr " putchar (' ');\n";
5971 pr " putchar ('\"');\n";
5972 pr " for (i = 0; %s[i]; ++i) {\n" n;
5973 pr " if (i > 0) putchar (' ');\n";
5974 pr " fputs (%s[i], stdout);\n" n;
5976 pr " putchar ('\"');\n";
5977 | Bool n -> (* boolean *)
5978 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
5979 | Int n -> (* int *)
5980 pr " printf (\" %%d\", %s);\n" n
5982 pr " printf (\" %%\" PRIi64, %s);\n" n
5984 pr " putchar ('\\n');\n";
5989 (* For non-daemon functions, generate a wrapper around each function. *)
5991 fun (shortname, style, _, _, _, _, _) ->
5992 let name = "guestfs_" ^ shortname in
5994 generate_prototype ~extern:false ~semicolon:false ~newline:true
5995 ~handle:"g" name style;
5997 check_null_strings shortname style;
5998 trace_call shortname style;
5999 pr " return guestfs__%s " shortname;
6000 generate_c_call_args ~handle:"g" style;
6004 ) non_daemon_functions;
6006 (* Client-side stubs for each function. *)
6008 fun (shortname, style, _, _, _, _, _) ->
6009 let name = "guestfs_" ^ shortname in
6010 let error_code = error_code_of (fst style) in
6012 (* Generate the action stub. *)
6013 generate_prototype ~extern:false ~semicolon:false ~newline:true
6014 ~handle:"g" name style;
6018 (match snd style with
6020 | _ -> pr " struct %s_args args;\n" name
6023 pr " guestfs_message_header hdr;\n";
6024 pr " guestfs_message_error err;\n";
6026 match fst style with
6028 | RConstString _ | RConstOptString _ ->
6029 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6031 | RBool _ | RString _ | RStringList _
6032 | RStruct _ | RStructList _
6033 | RHashtable _ | RBufferOut _ ->
6034 pr " struct %s_ret ret;\n" name;
6037 pr " int serial;\n";
6040 check_null_strings shortname style;
6041 trace_call shortname style;
6042 pr " if (check_state (g, \"%s\") == -1) return %s;\n"
6043 shortname error_code;
6044 pr " guestfs___set_busy (g);\n";
6047 (* Send the main header and arguments. *)
6048 (match snd style with
6050 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
6051 (String.uppercase shortname)
6055 | Pathname n | Device n | Dev_or_Path n | String n ->
6056 pr " args.%s = (char *) %s;\n" n n
6058 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
6059 | StringList n | DeviceList n ->
6060 pr " args.%s.%s_val = (char **) %s;\n" n n n;
6061 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
6063 pr " args.%s = %s;\n" n n
6065 pr " args.%s = %s;\n" n n
6067 pr " args.%s = %s;\n" n n
6068 | FileIn _ | FileOut _ -> ()
6070 pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
6071 pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
6072 pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
6074 pr " guestfs___end_busy (g);\n";
6075 pr " return %s;\n" error_code;
6077 pr " args.%s.%s_val = (char *) %s;\n" n n n;
6078 pr " args.%s.%s_len = %s_size;\n" n n n
6080 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
6081 (String.uppercase shortname);
6082 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
6085 pr " if (serial == -1) {\n";
6086 pr " guestfs___end_busy (g);\n";
6087 pr " return %s;\n" error_code;
6091 (* Send any additional files (FileIn) requested. *)
6092 let need_read_reply_label = ref false in
6096 pr " r = guestfs___send_file (g, %s);\n" n;
6097 pr " if (r == -1) {\n";
6098 pr " guestfs___end_busy (g);\n";
6099 pr " return %s;\n" error_code;
6101 pr " if (r == -2) /* daemon cancelled */\n";
6102 pr " goto read_reply;\n";
6103 need_read_reply_label := true;
6108 (* Wait for the reply from the remote end. *)
6109 if !need_read_reply_label then pr " read_reply:\n";
6110 pr " memset (&hdr, 0, sizeof hdr);\n";
6111 pr " memset (&err, 0, sizeof err);\n";
6112 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
6114 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
6118 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
6121 pr " if (r == -1) {\n";
6122 pr " guestfs___end_busy (g);\n";
6123 pr " return %s;\n" error_code;
6127 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
6128 (String.uppercase shortname);
6129 pr " guestfs___end_busy (g);\n";
6130 pr " return %s;\n" error_code;
6134 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
6135 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
6136 pr " free (err.error_message);\n";
6137 pr " guestfs___end_busy (g);\n";
6138 pr " return %s;\n" error_code;
6142 (* Expecting to receive further files (FileOut)? *)
6146 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
6147 pr " guestfs___end_busy (g);\n";
6148 pr " return %s;\n" error_code;
6154 pr " guestfs___end_busy (g);\n";
6156 (match fst style with
6157 | RErr -> pr " return 0;\n"
6158 | RInt n | RInt64 n | RBool n ->
6159 pr " return ret.%s;\n" n
6160 | RConstString _ | RConstOptString _ ->
6161 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6163 pr " return ret.%s; /* caller will free */\n" n
6164 | RStringList n | RHashtable n ->
6165 pr " /* caller will free this, but we need to add a NULL entry */\n";
6166 pr " ret.%s.%s_val =\n" n n;
6167 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
6168 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
6170 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
6171 pr " return ret.%s.%s_val;\n" n n
6173 pr " /* caller will free this */\n";
6174 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6175 | RStructList (n, _) ->
6176 pr " /* caller will free this */\n";
6177 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6179 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
6180 pr " * _val might be NULL here. To make the API saner for\n";
6181 pr " * callers, we turn this case into a unique pointer (using\n";
6182 pr " * malloc(1)).\n";
6184 pr " if (ret.%s.%s_len > 0) {\n" n n;
6185 pr " *size_r = ret.%s.%s_len;\n" n n;
6186 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
6188 pr " free (ret.%s.%s_val);\n" n n;
6189 pr " char *p = safe_malloc (g, 1);\n";
6190 pr " *size_r = ret.%s.%s_len;\n" n n;
6198 (* Functions to free structures. *)
6199 pr "/* Structure-freeing functions. These rely on the fact that the\n";
6200 pr " * structure format is identical to the XDR format. See note in\n";
6201 pr " * generator.ml.\n";
6208 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
6210 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
6216 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
6218 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
6225 (* Generate daemon/actions.h. *)
6226 and generate_daemon_actions_h () =
6227 generate_header CStyle GPLv2plus;
6229 pr "#include \"../src/guestfs_protocol.h\"\n";
6233 fun (name, style, _, _, _, _, _) ->
6235 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
6239 (* Generate the linker script which controls the visibility of
6240 * symbols in the public ABI and ensures no other symbols get
6241 * exported accidentally.
6243 and generate_linker_script () =
6244 generate_header HashStyle GPLv2plus;
6249 "guestfs_get_error_handler";
6250 "guestfs_get_out_of_memory_handler";
6251 "guestfs_last_error";
6252 "guestfs_set_error_handler";
6253 "guestfs_set_launch_done_callback";
6254 "guestfs_set_log_message_callback";
6255 "guestfs_set_out_of_memory_handler";
6256 "guestfs_set_subprocess_quit_callback";
6258 (* Unofficial parts of the API: the bindings code use these
6259 * functions, so it is useful to export them.
6261 "guestfs_safe_calloc";
6262 "guestfs_safe_malloc";
6265 List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
6269 List.map (fun (typ, _) ->
6270 ["guestfs_free_" ^ typ; "guestfs_free_" ^ typ ^ "_list"])
6273 let globals = List.sort compare (globals @ functions @ structs) in
6277 List.iter (pr " %s;\n") globals;
6284 (* Generate the server-side stubs. *)
6285 and generate_daemon_actions () =
6286 generate_header CStyle GPLv2plus;
6288 pr "#include <config.h>\n";
6290 pr "#include <stdio.h>\n";
6291 pr "#include <stdlib.h>\n";
6292 pr "#include <string.h>\n";
6293 pr "#include <inttypes.h>\n";
6294 pr "#include <rpc/types.h>\n";
6295 pr "#include <rpc/xdr.h>\n";
6297 pr "#include \"daemon.h\"\n";
6298 pr "#include \"c-ctype.h\"\n";
6299 pr "#include \"../src/guestfs_protocol.h\"\n";
6300 pr "#include \"actions.h\"\n";
6304 fun (name, style, _, _, _, _, _) ->
6305 (* Generate server-side stubs. *)
6306 pr "static void %s_stub (XDR *xdr_in)\n" name;
6309 match fst style with
6310 | RErr | RInt _ -> pr " int r;\n"; "-1"
6311 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6312 | RBool _ -> pr " int r;\n"; "-1"
6313 | RConstString _ | RConstOptString _ ->
6314 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6315 | RString _ -> pr " char *r;\n"; "NULL"
6316 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
6317 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
6318 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
6320 pr " size_t size = 1;\n";
6324 (match snd style with
6327 pr " struct guestfs_%s_args args;\n" name;
6330 | Device n | Dev_or_Path n
6333 | OptString n -> pr " char *%s;\n" n
6334 | StringList n | DeviceList n -> pr " char **%s;\n" n
6335 | Bool n -> pr " int %s;\n" n
6336 | Int n -> pr " int %s;\n" n
6337 | Int64 n -> pr " int64_t %s;\n" n
6338 | FileIn _ | FileOut _ -> ()
6340 pr " const char *%s;\n" n;
6341 pr " size_t %s_size;\n" n
6347 List.exists (function FileIn _ -> true | _ -> false) (snd style) in
6349 (match snd style with
6352 pr " memset (&args, 0, sizeof args);\n";
6354 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
6356 pr " if (cancel_receive () != -2)\n";
6357 pr " reply_with_error (\"daemon failed to decode procedure arguments\");\n";
6361 pr " char *%s = args.%s;\n" n n
6363 let pr_list_handling_code n =
6364 pr " %s = realloc (args.%s.%s_val,\n" n n n;
6365 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
6366 pr " if (%s == NULL) {\n" n;
6368 pr " if (cancel_receive () != -2)\n";
6369 pr " reply_with_perror (\"realloc\");\n";
6372 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
6373 pr " args.%s.%s_val = %s;\n" n n n;
6379 pr " ABS_PATH (%s, %s, goto done);\n"
6380 n (if is_filein then "cancel_receive ()" else "0");
6383 pr " RESOLVE_DEVICE (%s, %s, goto done);\n"
6384 n (if is_filein then "cancel_receive ()" else "0");
6387 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
6388 n (if is_filein then "cancel_receive ()" else "0");
6389 | String n -> pr_args n
6390 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
6392 pr_list_handling_code n;
6394 pr_list_handling_code n;
6395 pr " /* Ensure that each is a device,\n";
6396 pr " * and perform device name translation. */\n";
6397 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
6398 pr " RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
6399 (if is_filein then "cancel_receive ()" else "0");
6401 | Bool n -> pr " %s = args.%s;\n" n n
6402 | Int n -> pr " %s = args.%s;\n" n n
6403 | Int64 n -> pr " %s = args.%s;\n" n n
6404 | FileIn _ | FileOut _ -> ()
6406 pr " %s = args.%s.%s_val;\n" n n n;
6407 pr " %s_size = args.%s.%s_len;\n" n n n
6412 (* this is used at least for do_equal *)
6413 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
6414 (* Emit NEED_ROOT just once, even when there are two or
6415 more Pathname args *)
6416 pr " NEED_ROOT (%s, goto done);\n"
6417 (if is_filein then "cancel_receive ()" else "0");
6420 (* Don't want to call the impl with any FileIn or FileOut
6421 * parameters, since these go "outside" the RPC protocol.
6424 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
6426 pr " r = do_%s " name;
6427 generate_c_call_args (fst style, args');
6430 (match fst style with
6431 | RErr | RInt _ | RInt64 _ | RBool _
6432 | RConstString _ | RConstOptString _
6433 | RString _ | RStringList _ | RHashtable _
6434 | RStruct (_, _) | RStructList (_, _) ->
6435 pr " if (r == %s)\n" error_code;
6436 pr " /* do_%s has already called reply_with_error */\n" name;
6440 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
6441 pr " * an ordinary zero-length buffer), so be careful ...\n";
6443 pr " if (size == 1 && r == %s)\n" error_code;
6444 pr " /* do_%s has already called reply_with_error */\n" name;
6449 (* If there are any FileOut parameters, then the impl must
6450 * send its own reply.
6453 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
6455 pr " /* do_%s has already sent a reply */\n" name
6457 match fst style with
6458 | RErr -> pr " reply (NULL, NULL);\n"
6459 | RInt n | RInt64 n | RBool n ->
6460 pr " struct guestfs_%s_ret ret;\n" name;
6461 pr " ret.%s = r;\n" n;
6462 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6464 | RConstString _ | RConstOptString _ ->
6465 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6467 pr " struct guestfs_%s_ret ret;\n" name;
6468 pr " ret.%s = r;\n" n;
6469 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6472 | RStringList n | RHashtable n ->
6473 pr " struct guestfs_%s_ret ret;\n" name;
6474 pr " ret.%s.%s_len = count_strings (r);\n" n n;
6475 pr " ret.%s.%s_val = r;\n" n n;
6476 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6478 pr " free_strings (r);\n"
6480 pr " struct guestfs_%s_ret ret;\n" name;
6481 pr " ret.%s = *r;\n" n;
6482 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6484 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6486 | RStructList (n, _) ->
6487 pr " struct guestfs_%s_ret ret;\n" name;
6488 pr " ret.%s = *r;\n" n;
6489 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6491 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6494 pr " struct guestfs_%s_ret ret;\n" name;
6495 pr " ret.%s.%s_val = r;\n" n n;
6496 pr " ret.%s.%s_len = size;\n" n n;
6497 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6502 (* Free the args. *)
6504 (match snd style with
6507 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
6514 (* Dispatch function. *)
6515 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
6517 pr " switch (proc_nr) {\n";
6520 fun (name, style, _, _, _, _, _) ->
6521 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
6522 pr " %s_stub (xdr_in);\n" name;
6527 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";
6532 (* LVM columns and tokenization functions. *)
6533 (* XXX This generates crap code. We should rethink how we
6539 pr "static const char *lvm_%s_cols = \"%s\";\n"
6540 typ (String.concat "," (List.map fst cols));
6543 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
6545 pr " char *tok, *p, *next;\n";
6549 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
6552 pr " if (!str) {\n";
6553 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
6556 pr " if (!*str || c_isspace (*str)) {\n";
6557 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
6562 fun (name, coltype) ->
6563 pr " if (!tok) {\n";
6564 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
6567 pr " p = strchrnul (tok, ',');\n";
6568 pr " if (*p) next = p+1; else next = NULL;\n";
6569 pr " *p = '\\0';\n";
6572 pr " r->%s = strdup (tok);\n" name;
6573 pr " if (r->%s == NULL) {\n" name;
6574 pr " perror (\"strdup\");\n";
6578 pr " for (i = j = 0; i < 32; ++j) {\n";
6579 pr " if (tok[j] == '\\0') {\n";
6580 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
6582 pr " } else if (tok[j] != '-')\n";
6583 pr " r->%s[i++] = tok[j];\n" name;
6586 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
6587 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6591 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
6592 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6596 pr " if (tok[0] == '\\0')\n";
6597 pr " r->%s = -1;\n" name;
6598 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
6599 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6602 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
6603 assert false (* can never be an LVM column *)
6605 pr " tok = next;\n";
6608 pr " if (tok != NULL) {\n";
6609 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
6616 pr "guestfs_int_lvm_%s_list *\n" typ;
6617 pr "parse_command_line_%ss (void)\n" typ;
6619 pr " char *out, *err;\n";
6620 pr " char *p, *pend;\n";
6622 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
6623 pr " void *newp;\n";
6625 pr " ret = malloc (sizeof *ret);\n";
6626 pr " if (!ret) {\n";
6627 pr " reply_with_perror (\"malloc\");\n";
6628 pr " return NULL;\n";
6631 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
6632 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
6634 pr " r = command (&out, &err,\n";
6635 pr " \"lvm\", \"%ss\",\n" typ;
6636 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
6637 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
6638 pr " if (r == -1) {\n";
6639 pr " reply_with_error (\"%%s\", err);\n";
6640 pr " free (out);\n";
6641 pr " free (err);\n";
6642 pr " free (ret);\n";
6643 pr " return NULL;\n";
6646 pr " free (err);\n";
6648 pr " /* Tokenize each line of the output. */\n";
6651 pr " while (p) {\n";
6652 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
6653 pr " if (pend) {\n";
6654 pr " *pend = '\\0';\n";
6658 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
6661 pr " if (!*p) { /* Empty line? Skip it. */\n";
6666 pr " /* Allocate some space to store this next entry. */\n";
6667 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
6668 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
6669 pr " if (newp == NULL) {\n";
6670 pr " reply_with_perror (\"realloc\");\n";
6671 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6672 pr " free (ret);\n";
6673 pr " free (out);\n";
6674 pr " return NULL;\n";
6676 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
6678 pr " /* Tokenize the next entry. */\n";
6679 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
6680 pr " if (r == -1) {\n";
6681 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
6682 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6683 pr " free (ret);\n";
6684 pr " free (out);\n";
6685 pr " return NULL;\n";
6692 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
6694 pr " free (out);\n";
6695 pr " return ret;\n";
6698 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
6700 (* Generate a list of function names, for debugging in the daemon.. *)
6701 and generate_daemon_names () =
6702 generate_header CStyle GPLv2plus;
6704 pr "#include <config.h>\n";
6706 pr "#include \"daemon.h\"\n";
6709 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
6710 pr "const char *function_names[] = {\n";
6712 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
6716 (* Generate the optional groups for the daemon to implement
6717 * guestfs_available.
6719 and generate_daemon_optgroups_c () =
6720 generate_header CStyle GPLv2plus;
6722 pr "#include <config.h>\n";
6724 pr "#include \"daemon.h\"\n";
6725 pr "#include \"optgroups.h\"\n";
6728 pr "struct optgroup optgroups[] = {\n";
6731 pr " { \"%s\", optgroup_%s_available },\n" group group
6733 pr " { NULL, NULL }\n";
6736 and generate_daemon_optgroups_h () =
6737 generate_header CStyle GPLv2plus;
6741 pr "extern int optgroup_%s_available (void);\n" group
6744 (* Generate the tests. *)
6745 and generate_tests () =
6746 generate_header CStyle GPLv2plus;
6753 #include <sys/types.h>
6756 #include \"guestfs.h\"
6757 #include \"guestfs-internal.h\"
6759 static guestfs_h *g;
6760 static int suppress_error = 0;
6762 static void print_error (guestfs_h *g, void *data, const char *msg)
6764 if (!suppress_error)
6765 fprintf (stderr, \"%%s\\n\", msg);
6768 /* FIXME: nearly identical code appears in fish.c */
6769 static void print_strings (char *const *argv)
6773 for (argc = 0; argv[argc] != NULL; ++argc)
6774 printf (\"\\t%%s\\n\", argv[argc]);
6778 static void print_table (char const *const *argv)
6782 for (i = 0; argv[i] != NULL; i += 2)
6783 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
6789 (* Generate a list of commands which are not tested anywhere. *)
6790 pr "static void no_test_warnings (void)\n";
6793 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
6795 fun (_, _, _, _, tests, _, _) ->
6796 let tests = filter_map (
6798 | (_, (Always|If _|Unless _), test) -> Some test
6799 | (_, Disabled, _) -> None
6801 let seq = List.concat (List.map seq_of_test tests) in
6802 let cmds_tested = List.map List.hd seq in
6803 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6807 fun (name, _, _, _, _, _, _) ->
6808 if not (Hashtbl.mem hash name) then
6809 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6815 (* Generate the actual tests. Note that we generate the tests
6816 * in reverse order, deliberately, so that (in general) the
6817 * newest tests run first. This makes it quicker and easier to
6822 fun (name, _, _, flags, tests, _, _) ->
6823 mapi (generate_one_test name flags) tests
6824 ) (List.rev all_functions) in
6825 let test_names = List.concat test_names in
6826 let nr_tests = List.length test_names in
6829 int main (int argc, char *argv[])
6832 unsigned long int n_failed = 0;
6833 const char *filename;
6835 int nr_tests, test_num = 0;
6837 setbuf (stdout, NULL);
6839 no_test_warnings ();
6841 g = guestfs_create ();
6843 printf (\"guestfs_create FAILED\\n\");
6844 exit (EXIT_FAILURE);
6847 guestfs_set_error_handler (g, print_error, NULL);
6849 guestfs_set_path (g, \"../appliance\");
6851 filename = \"test1.img\";
6852 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6855 exit (EXIT_FAILURE);
6857 if (lseek (fd, %d, SEEK_SET) == -1) {
6861 exit (EXIT_FAILURE);
6863 if (write (fd, &c, 1) == -1) {
6867 exit (EXIT_FAILURE);
6869 if (close (fd) == -1) {
6872 exit (EXIT_FAILURE);
6874 if (guestfs_add_drive (g, filename) == -1) {
6875 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6876 exit (EXIT_FAILURE);
6879 filename = \"test2.img\";
6880 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6883 exit (EXIT_FAILURE);
6885 if (lseek (fd, %d, SEEK_SET) == -1) {
6889 exit (EXIT_FAILURE);
6891 if (write (fd, &c, 1) == -1) {
6895 exit (EXIT_FAILURE);
6897 if (close (fd) == -1) {
6900 exit (EXIT_FAILURE);
6902 if (guestfs_add_drive (g, filename) == -1) {
6903 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6904 exit (EXIT_FAILURE);
6907 filename = \"test3.img\";
6908 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6911 exit (EXIT_FAILURE);
6913 if (lseek (fd, %d, SEEK_SET) == -1) {
6917 exit (EXIT_FAILURE);
6919 if (write (fd, &c, 1) == -1) {
6923 exit (EXIT_FAILURE);
6925 if (close (fd) == -1) {
6928 exit (EXIT_FAILURE);
6930 if (guestfs_add_drive (g, filename) == -1) {
6931 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6932 exit (EXIT_FAILURE);
6935 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
6936 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
6937 exit (EXIT_FAILURE);
6940 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
6943 if (guestfs_launch (g) == -1) {
6944 printf (\"guestfs_launch FAILED\\n\");
6945 exit (EXIT_FAILURE);
6948 /* Cancel previous alarm. */
6953 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
6957 pr " test_num++;\n";
6958 pr " if (guestfs_get_verbose (g))\n";
6959 pr " printf (\"-------------------------------------------------------------------------------\\n\");\n";
6960 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
6961 pr " if (%s () == -1) {\n" test_name;
6962 pr " printf (\"%s FAILED\\n\");\n" test_name;
6963 pr " n_failed++;\n";
6968 pr " guestfs_close (g);\n";
6969 pr " unlink (\"test1.img\");\n";
6970 pr " unlink (\"test2.img\");\n";
6971 pr " unlink (\"test3.img\");\n";
6974 pr " if (n_failed > 0) {\n";
6975 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
6976 pr " exit (EXIT_FAILURE);\n";
6980 pr " exit (EXIT_SUCCESS);\n";
6983 and generate_one_test name flags i (init, prereq, test) =
6984 let test_name = sprintf "test_%s_%d" name i in
6987 static int %s_skip (void)
6991 str = getenv (\"TEST_ONLY\");
6993 return strstr (str, \"%s\") == NULL;
6994 str = getenv (\"SKIP_%s\");
6995 if (str && STREQ (str, \"1\")) return 1;
6996 str = getenv (\"SKIP_TEST_%s\");
6997 if (str && STREQ (str, \"1\")) return 1;
7001 " test_name name (String.uppercase test_name) (String.uppercase name);
7004 | Disabled | Always -> ()
7005 | If code | Unless code ->
7006 pr "static int %s_prereq (void)\n" test_name;
7014 static int %s (void)
7017 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
7021 " test_name test_name test_name;
7023 (* Optional functions should only be tested if the relevant
7024 * support is available in the daemon.
7030 pr " const char *groups[] = { \"%s\", NULL };\n" group;
7032 pr " suppress_error = 1;\n";
7033 pr " r = guestfs_available (g, (char **) groups);\n";
7034 pr " suppress_error = 0;\n";
7035 pr " if (r == -1) {\n";
7036 pr " printf (\" %%s skipped (reason: group %%s not available in daemon)\\n\", \"%s\", groups[0]);\n" test_name;
7045 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
7047 pr " if (! %s_prereq ()) {\n" test_name;
7048 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7052 generate_one_test_body name i test_name init test;
7054 pr " if (%s_prereq ()) {\n" test_name;
7055 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7059 generate_one_test_body name i test_name init test;
7061 generate_one_test_body name i test_name init test
7069 and generate_one_test_body name i test_name init test =
7071 | InitNone (* XXX at some point, InitNone and InitEmpty became
7072 * folded together as the same thing. Really we should
7073 * make InitNone do nothing at all, but the tests may
7074 * need to be checked to make sure this is OK.
7077 pr " /* InitNone|InitEmpty for %s */\n" test_name;
7078 List.iter (generate_test_command_call test_name)
7079 [["blockdev_setrw"; "/dev/sda"];
7083 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
7084 List.iter (generate_test_command_call test_name)
7085 [["blockdev_setrw"; "/dev/sda"];
7088 ["part_disk"; "/dev/sda"; "mbr"]]
7090 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
7091 List.iter (generate_test_command_call test_name)
7092 [["blockdev_setrw"; "/dev/sda"];
7095 ["part_disk"; "/dev/sda"; "mbr"];
7096 ["mkfs"; "ext2"; "/dev/sda1"];
7097 ["mount_options"; ""; "/dev/sda1"; "/"]]
7098 | InitBasicFSonLVM ->
7099 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
7101 List.iter (generate_test_command_call test_name)
7102 [["blockdev_setrw"; "/dev/sda"];
7105 ["part_disk"; "/dev/sda"; "mbr"];
7106 ["pvcreate"; "/dev/sda1"];
7107 ["vgcreate"; "VG"; "/dev/sda1"];
7108 ["lvcreate"; "LV"; "VG"; "8"];
7109 ["mkfs"; "ext2"; "/dev/VG/LV"];
7110 ["mount_options"; ""; "/dev/VG/LV"; "/"]]
7112 pr " /* InitISOFS for %s */\n" test_name;
7113 List.iter (generate_test_command_call test_name)
7114 [["blockdev_setrw"; "/dev/sda"];
7117 ["mount_ro"; "/dev/sdd"; "/"]]
7120 let get_seq_last = function
7122 failwithf "%s: you cannot use [] (empty list) when expecting a command"
7125 let seq = List.rev seq in
7126 List.rev (List.tl seq), List.hd seq
7131 pr " /* TestRun for %s (%d) */\n" name i;
7132 List.iter (generate_test_command_call test_name) seq
7133 | TestOutput (seq, expected) ->
7134 pr " /* TestOutput for %s (%d) */\n" name i;
7135 pr " const char *expected = \"%s\";\n" (c_quote expected);
7136 let seq, last = get_seq_last seq in
7138 pr " if (STRNEQ (r, expected)) {\n";
7139 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7143 List.iter (generate_test_command_call test_name) seq;
7144 generate_test_command_call ~test test_name last
7145 | TestOutputList (seq, expected) ->
7146 pr " /* TestOutputList for %s (%d) */\n" name i;
7147 let seq, last = get_seq_last seq in
7151 pr " if (!r[%d]) {\n" i;
7152 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7153 pr " print_strings (r);\n";
7157 pr " const char *expected = \"%s\";\n" (c_quote str);
7158 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7159 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7164 pr " if (r[%d] != NULL) {\n" (List.length expected);
7165 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7167 pr " print_strings (r);\n";
7171 List.iter (generate_test_command_call test_name) seq;
7172 generate_test_command_call ~test test_name last
7173 | TestOutputListOfDevices (seq, expected) ->
7174 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
7175 let seq, last = get_seq_last seq in
7179 pr " if (!r[%d]) {\n" i;
7180 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7181 pr " print_strings (r);\n";
7185 pr " const char *expected = \"%s\";\n" (c_quote str);
7186 pr " r[%d][5] = 's';\n" i;
7187 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7188 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7193 pr " if (r[%d] != NULL) {\n" (List.length expected);
7194 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7196 pr " print_strings (r);\n";
7200 List.iter (generate_test_command_call test_name) seq;
7201 generate_test_command_call ~test test_name last
7202 | TestOutputInt (seq, expected) ->
7203 pr " /* TestOutputInt for %s (%d) */\n" name i;
7204 let seq, last = get_seq_last seq in
7206 pr " if (r != %d) {\n" expected;
7207 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
7213 List.iter (generate_test_command_call test_name) seq;
7214 generate_test_command_call ~test test_name last
7215 | TestOutputIntOp (seq, op, expected) ->
7216 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
7217 let seq, last = get_seq_last seq in
7219 pr " if (! (r %s %d)) {\n" op expected;
7220 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
7221 test_name op expected;
7226 List.iter (generate_test_command_call test_name) seq;
7227 generate_test_command_call ~test test_name last
7228 | TestOutputTrue seq ->
7229 pr " /* TestOutputTrue for %s (%d) */\n" name i;
7230 let seq, last = get_seq_last seq in
7233 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
7238 List.iter (generate_test_command_call test_name) seq;
7239 generate_test_command_call ~test test_name last
7240 | TestOutputFalse seq ->
7241 pr " /* TestOutputFalse for %s (%d) */\n" name i;
7242 let seq, last = get_seq_last seq in
7245 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
7250 List.iter (generate_test_command_call test_name) seq;
7251 generate_test_command_call ~test test_name last
7252 | TestOutputLength (seq, expected) ->
7253 pr " /* TestOutputLength for %s (%d) */\n" name i;
7254 let seq, last = get_seq_last seq in
7257 pr " for (j = 0; j < %d; ++j)\n" expected;
7258 pr " if (r[j] == NULL) {\n";
7259 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
7261 pr " print_strings (r);\n";
7264 pr " if (r[j] != NULL) {\n";
7265 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
7267 pr " print_strings (r);\n";
7271 List.iter (generate_test_command_call test_name) seq;
7272 generate_test_command_call ~test test_name last
7273 | TestOutputBuffer (seq, expected) ->
7274 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
7275 pr " const char *expected = \"%s\";\n" (c_quote expected);
7276 let seq, last = get_seq_last seq in
7277 let len = String.length expected in
7279 pr " if (size != %d) {\n" len;
7280 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
7283 pr " if (STRNEQLEN (r, expected, size)) {\n";
7284 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7288 List.iter (generate_test_command_call test_name) seq;
7289 generate_test_command_call ~test test_name last
7290 | TestOutputStruct (seq, checks) ->
7291 pr " /* TestOutputStruct for %s (%d) */\n" name i;
7292 let seq, last = get_seq_last seq in
7296 | CompareWithInt (field, expected) ->
7297 pr " if (r->%s != %d) {\n" field expected;
7298 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
7299 test_name field expected;
7300 pr " (int) r->%s);\n" field;
7303 | CompareWithIntOp (field, op, expected) ->
7304 pr " if (!(r->%s %s %d)) {\n" field op expected;
7305 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
7306 test_name field op expected;
7307 pr " (int) r->%s);\n" field;
7310 | CompareWithString (field, expected) ->
7311 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
7312 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
7313 test_name field expected;
7314 pr " r->%s);\n" field;
7317 | CompareFieldsIntEq (field1, field2) ->
7318 pr " if (r->%s != r->%s) {\n" field1 field2;
7319 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
7320 test_name field1 field2;
7321 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
7324 | CompareFieldsStrEq (field1, field2) ->
7325 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
7326 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
7327 test_name field1 field2;
7328 pr " r->%s, r->%s);\n" field1 field2;
7333 List.iter (generate_test_command_call test_name) seq;
7334 generate_test_command_call ~test test_name last
7335 | TestLastFail seq ->
7336 pr " /* TestLastFail for %s (%d) */\n" name i;
7337 let seq, last = get_seq_last seq in
7338 List.iter (generate_test_command_call test_name) seq;
7339 generate_test_command_call test_name ~expect_error:true last
7341 (* Generate the code to run a command, leaving the result in 'r'.
7342 * If you expect to get an error then you should set expect_error:true.
7344 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
7346 | [] -> assert false
7348 (* Look up the command to find out what args/ret it has. *)
7351 let _, style, _, _, _, _, _ =
7352 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
7355 failwithf "%s: in test, command %s was not found" test_name name in
7357 if List.length (snd style) <> List.length args then
7358 failwithf "%s: in test, wrong number of args given to %s"
7365 | OptString n, "NULL" -> ()
7368 | Dev_or_Path n, arg
7370 | OptString n, arg ->
7371 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7372 | BufferIn n, arg ->
7373 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7374 pr " size_t %s_size = %d;\n" n (String.length arg)
7378 | FileIn _, _ | FileOut _, _ -> ()
7379 | StringList n, "" | DeviceList n, "" ->
7380 pr " const char *const %s[1] = { NULL };\n" n
7381 | StringList n, arg | DeviceList n, arg ->
7382 let strs = string_split " " arg in
7385 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
7387 pr " const char *const %s[] = {\n" n;
7389 fun i _ -> pr " %s_%d,\n" n i
7393 ) (List.combine (snd style) args);
7396 match fst style with
7397 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
7398 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7399 | RConstString _ | RConstOptString _ ->
7400 pr " const char *r;\n"; "NULL"
7401 | RString _ -> pr " char *r;\n"; "NULL"
7402 | RStringList _ | RHashtable _ ->
7406 | RStruct (_, typ) ->
7407 pr " struct guestfs_%s *r;\n" typ; "NULL"
7408 | RStructList (_, typ) ->
7409 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7412 pr " size_t size;\n";
7415 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
7416 pr " r = guestfs_%s (g" name;
7418 (* Generate the parameters. *)
7421 | OptString _, "NULL" -> pr ", NULL"
7423 | Device n, _ | Dev_or_Path n, _
7428 pr ", %s, %s_size" n n
7429 | FileIn _, arg | FileOut _, arg ->
7430 pr ", \"%s\"" (c_quote arg)
7431 | StringList n, _ | DeviceList n, _ ->
7432 pr ", (char **) %s" n
7435 try int_of_string arg
7436 with Failure "int_of_string" ->
7437 failwithf "%s: expecting an int, but got '%s'" test_name arg in
7441 try Int64.of_string arg
7442 with Failure "int_of_string" ->
7443 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
7446 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
7447 ) (List.combine (snd style) args);
7449 (match fst style with
7450 | RBufferOut _ -> pr ", &size"
7456 if not expect_error then
7457 pr " if (r == %s)\n" error_code
7459 pr " if (r != %s)\n" error_code;
7462 (* Insert the test code. *)
7468 (match fst style with
7469 | RErr | RInt _ | RInt64 _ | RBool _
7470 | RConstString _ | RConstOptString _ -> ()
7471 | RString _ | RBufferOut _ -> pr " free (r);\n"
7472 | RStringList _ | RHashtable _ ->
7473 pr " for (i = 0; r[i] != NULL; ++i)\n";
7474 pr " free (r[i]);\n";
7476 | RStruct (_, typ) ->
7477 pr " guestfs_free_%s (r);\n" typ
7478 | RStructList (_, typ) ->
7479 pr " guestfs_free_%s_list (r);\n" typ
7485 let str = replace_str str "\r" "\\r" in
7486 let str = replace_str str "\n" "\\n" in
7487 let str = replace_str str "\t" "\\t" in
7488 let str = replace_str str "\000" "\\0" in
7491 (* Generate a lot of different functions for guestfish. *)
7492 and generate_fish_cmds () =
7493 generate_header CStyle GPLv2plus;
7497 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7499 let all_functions_sorted =
7501 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7502 ) all_functions_sorted in
7504 pr "#include <config.h>\n";
7506 pr "#include <stdio.h>\n";
7507 pr "#include <stdlib.h>\n";
7508 pr "#include <string.h>\n";
7509 pr "#include <inttypes.h>\n";
7511 pr "#include <guestfs.h>\n";
7512 pr "#include \"c-ctype.h\"\n";
7513 pr "#include \"full-write.h\"\n";
7514 pr "#include \"xstrtol.h\"\n";
7515 pr "#include \"fish.h\"\n";
7517 pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
7518 pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
7521 (* list_commands function, which implements guestfish -h *)
7522 pr "void list_commands (void)\n";
7524 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
7525 pr " list_builtin_commands ();\n";
7527 fun (name, _, _, flags, _, shortdesc, _) ->
7528 let name = replace_char name '_' '-' in
7529 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
7531 ) all_functions_sorted;
7532 pr " printf (\" %%s\\n\",";
7533 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
7537 (* display_command function, which implements guestfish -h cmd *)
7538 pr "void display_command (const char *cmd)\n";
7541 fun (name, style, _, flags, _, shortdesc, longdesc) ->
7542 let name2 = replace_char name '_' '-' in
7544 try find_map (function FishAlias n -> Some n | _ -> None) flags
7545 with Not_found -> name in
7546 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
7548 match snd style with
7552 name2 (String.concat " " (List.map name_of_argt args)) in
7555 if List.mem ProtocolLimitWarning flags then
7556 ("\n\n" ^ protocol_limit_warning)
7559 (* For DangerWillRobinson commands, we should probably have
7560 * guestfish prompt before allowing you to use them (especially
7561 * in interactive mode). XXX
7565 if List.mem DangerWillRobinson flags then
7566 ("\n\n" ^ danger_will_robinson)
7571 match deprecation_notice flags with
7573 | Some txt -> "\n\n" ^ txt in
7575 let describe_alias =
7576 if name <> alias then
7577 sprintf "\n\nYou can use '%s' as an alias for this command." alias
7581 pr "STRCASEEQ (cmd, \"%s\")" name;
7582 if name <> name2 then
7583 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7584 if name <> alias then
7585 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7587 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
7589 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
7590 "=head1 DESCRIPTION\n\n" ^
7591 longdesc ^ warnings ^ describe_alias);
7594 pr " display_builtin_command (cmd);\n";
7598 let emit_print_list_function typ =
7599 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
7602 pr " unsigned int i;\n";
7604 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7605 pr " printf (\"[%%d] = {\\n\", i);\n";
7606 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
7607 pr " printf (\"}\\n\");\n";
7613 (* print_* functions *)
7617 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
7619 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
7622 pr " unsigned int i;\n";
7628 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
7630 pr " printf (\"%%s%s: \", indent);\n" name;
7631 pr " for (i = 0; i < 32; ++i)\n";
7632 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7633 pr " printf (\"\\n\");\n"
7635 pr " printf (\"%%s%s: \", indent);\n" name;
7636 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
7637 pr " if (c_isprint (%s->%s[i]))\n" typ name;
7638 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7640 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
7641 pr " printf (\"\\n\");\n"
7642 | name, (FUInt64|FBytes) ->
7643 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
7646 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
7649 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
7652 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
7655 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
7657 | name, FOptPercent ->
7658 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
7659 typ name name typ name;
7660 pr " else printf (\"%%s%s: \\n\", indent);\n" name
7666 (* Emit a print_TYPE_list function definition only if that function is used. *)
7669 | typ, (RStructListOnly | RStructAndList) ->
7670 (* generate the function for typ *)
7671 emit_print_list_function typ
7672 | typ, _ -> () (* empty *)
7673 ) (rstructs_used_by all_functions);
7675 (* Emit a print_TYPE function definition only if that function is used. *)
7678 | typ, (RStructOnly | RStructAndList) ->
7679 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
7681 pr " print_%s_indent (%s, \"\");\n" typ typ;
7684 | typ, _ -> () (* empty *)
7685 ) (rstructs_used_by all_functions);
7687 (* run_<action> actions *)
7689 fun (name, style, _, flags, _, _, _) ->
7690 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
7692 (match fst style with
7695 | RBool _ -> pr " int r;\n"
7696 | RInt64 _ -> pr " int64_t r;\n"
7697 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
7698 | RString _ -> pr " char *r;\n"
7699 | RStringList _ | RHashtable _ -> pr " char **r;\n"
7700 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
7701 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
7704 pr " size_t size;\n";
7710 | OptString n -> pr " const char *%s;\n" n
7714 | FileOut n -> pr " char *%s;\n" n
7716 pr " const char *%s;\n" n;
7717 pr " size_t %s_size;\n" n
7718 | StringList n | DeviceList n -> pr " char **%s;\n" n
7719 | Bool n -> pr " int %s;\n" n
7720 | Int n -> pr " int %s;\n" n
7721 | Int64 n -> pr " int64_t %s;\n" n
7724 (* Check and convert parameters. *)
7725 let argc_expected = List.length (snd style) in
7726 pr " if (argc != %d) {\n" argc_expected;
7727 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
7729 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
7733 let parse_integer fn fntyp rtyp range name i =
7735 pr " strtol_error xerr;\n";
7736 pr " %s r;\n" fntyp;
7738 pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
7739 pr " if (xerr != LONGINT_OK) {\n";
7740 pr " fprintf (stderr,\n";
7741 pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
7742 pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
7747 | Some (min, max, comment) ->
7748 pr " /* %s */\n" comment;
7749 pr " if (r < %s || r > %s) {\n" min max;
7750 pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
7754 pr " /* The check above should ensure this assignment does not overflow. */\n";
7756 pr " %s = r;\n" name;
7765 pr " %s = argv[%d];\n" name i
7767 | Dev_or_Path name ->
7768 pr " %s = resolve_win_path (argv[%d]);\n" name i;
7769 pr " if (%s == NULL) return -1;\n" name
7771 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
7774 pr " %s = argv[%d];\n" name i;
7775 pr " %s_size = strlen (argv[%d]);\n" name i
7777 pr " %s = file_in (argv[%d]);\n" name i;
7778 pr " if (%s == NULL) return -1;\n" name
7780 pr " %s = file_out (argv[%d]);\n" name i;
7781 pr " if (%s == NULL) return -1;\n" name
7782 | StringList name | DeviceList name ->
7783 pr " %s = parse_string_list (argv[%d]);\n" name i;
7784 pr " if (%s == NULL) return -1;\n" name;
7786 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
7789 let min = "(-(2LL<<30))"
7790 and max = "((2LL<<30)-1)"
7792 "The Int type in the generator is a signed 31 bit int." in
7793 Some (min, max, comment) in
7794 parse_integer "xstrtoll" "long long" "int" range name i
7796 parse_integer "xstrtoll" "long long" "int64_t" None name i
7799 (* Call C API function. *)
7800 pr " r = guestfs_%s " name;
7801 generate_c_call_args ~handle:"g" style;
7806 | Device name | String name
7807 | OptString name | Bool name
7808 | Int name | Int64 name
7809 | BufferIn name -> ()
7810 | Pathname name | Dev_or_Path name | FileOut name ->
7811 pr " free (%s);\n" name
7813 pr " free_file_in (%s);\n" name
7814 | StringList name | DeviceList name ->
7815 pr " free_strings (%s);\n" name
7818 (* Any output flags? *)
7820 let flags = filter_map (
7821 function FishOutput flag -> Some flag | _ -> None
7827 failwithf "%s: more than one FishOutput flag is not allowed" name in
7829 (* Check return value for errors and display command results. *)
7830 (match fst style with
7831 | RErr -> pr " return r;\n"
7833 pr " if (r == -1) return -1;\n";
7834 (match fish_output with
7836 pr " printf (\"%%d\\n\", r);\n";
7837 | Some FishOutputOctal ->
7838 pr " printf (\"%%s%%o\\n\", r != 0 ? \"0\" : \"\", r);\n";
7839 | Some FishOutputHexadecimal ->
7840 pr " printf (\"%%s%%x\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7843 pr " if (r == -1) return -1;\n";
7844 (match fish_output with
7846 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
7847 | Some FishOutputOctal ->
7848 pr " printf (\"%%s%%\" PRIo64 \"\\n\", r != 0 ? \"0\" : \"\", r);\n";
7849 | Some FishOutputHexadecimal ->
7850 pr " printf (\"%%s%%\" PRIx64 \"\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7853 pr " if (r == -1) return -1;\n";
7854 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
7857 pr " if (r == NULL) return -1;\n";
7858 pr " printf (\"%%s\\n\", r);\n";
7860 | RConstOptString _ ->
7861 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
7864 pr " if (r == NULL) return -1;\n";
7865 pr " printf (\"%%s\\n\", r);\n";
7869 pr " if (r == NULL) return -1;\n";
7870 pr " print_strings (r);\n";
7871 pr " free_strings (r);\n";
7873 | RStruct (_, typ) ->
7874 pr " if (r == NULL) return -1;\n";
7875 pr " print_%s (r);\n" typ;
7876 pr " guestfs_free_%s (r);\n" typ;
7878 | RStructList (_, typ) ->
7879 pr " if (r == NULL) return -1;\n";
7880 pr " print_%s_list (r);\n" typ;
7881 pr " guestfs_free_%s_list (r);\n" typ;
7884 pr " if (r == NULL) return -1;\n";
7885 pr " print_table (r);\n";
7886 pr " free_strings (r);\n";
7889 pr " if (r == NULL) return -1;\n";
7890 pr " if (full_write (1, r, size) != size) {\n";
7891 pr " perror (\"write\");\n";
7902 (* run_action function *)
7903 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
7906 fun (name, _, _, flags, _, _, _) ->
7907 let name2 = replace_char name '_' '-' in
7909 try find_map (function FishAlias n -> Some n | _ -> None) flags
7910 with Not_found -> name in
7912 pr "STRCASEEQ (cmd, \"%s\")" name;
7913 if name <> name2 then
7914 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7915 if name <> alias then
7916 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7918 pr " return run_%s (cmd, argc, argv);\n" name;
7922 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
7923 pr " if (command_num == 1)\n";
7924 pr " extended_help_message ();\n";
7931 (* Readline completion for guestfish. *)
7932 and generate_fish_completion () =
7933 generate_header CStyle GPLv2plus;
7937 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7947 #ifdef HAVE_LIBREADLINE
7948 #include <readline/readline.h>
7953 #ifdef HAVE_LIBREADLINE
7955 static const char *const commands[] = {
7956 BUILTIN_COMMANDS_FOR_COMPLETION,
7959 (* Get the commands, including the aliases. They don't need to be
7960 * sorted - the generator() function just does a dumb linear search.
7964 fun (name, _, _, flags, _, _, _) ->
7965 let name2 = replace_char name '_' '-' in
7967 try find_map (function FishAlias n -> Some n | _ -> None) flags
7968 with Not_found -> name in
7970 if name <> alias then [name2; alias] else [name2]
7972 let commands = List.flatten commands in
7974 List.iter (pr " \"%s\",\n") commands;
7980 generator (const char *text, int state)
7982 static int index, len;
7987 len = strlen (text);
7990 rl_attempted_completion_over = 1;
7992 while ((name = commands[index]) != NULL) {
7994 if (STRCASEEQLEN (name, text, len))
7995 return strdup (name);
8001 #endif /* HAVE_LIBREADLINE */
8003 #ifdef HAVE_RL_COMPLETION_MATCHES
8004 #define RL_COMPLETION_MATCHES rl_completion_matches
8006 #ifdef HAVE_COMPLETION_MATCHES
8007 #define RL_COMPLETION_MATCHES completion_matches
8009 #endif /* else just fail if we don't have either symbol */
8012 do_completion (const char *text, int start, int end)
8014 char **matches = NULL;
8016 #ifdef HAVE_LIBREADLINE
8017 rl_completion_append_character = ' ';
8020 matches = RL_COMPLETION_MATCHES (text, generator);
8021 else if (complete_dest_paths)
8022 matches = RL_COMPLETION_MATCHES (text, complete_dest_paths_generator);
8029 (* Generate the POD documentation for guestfish. *)
8030 and generate_fish_actions_pod () =
8031 let all_functions_sorted =
8033 fun (_, _, _, flags, _, _, _) ->
8034 not (List.mem NotInFish flags || List.mem NotInDocs flags)
8035 ) all_functions_sorted in
8037 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
8040 fun (name, style, _, flags, _, _, longdesc) ->
8042 Str.global_substitute rex (
8045 try Str.matched_group 1 s
8047 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
8048 "C<" ^ replace_char sub '_' '-' ^ ">"
8050 let name = replace_char name '_' '-' in
8052 try find_map (function FishAlias n -> Some n | _ -> None) flags
8053 with Not_found -> name in
8055 pr "=head2 %s" name;
8056 if name <> alias then
8063 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
8064 | OptString n -> pr " %s" n
8065 | StringList n | DeviceList n -> pr " '%s ...'" n
8066 | Bool _ -> pr " true|false"
8067 | Int n -> pr " %s" n
8068 | Int64 n -> pr " %s" n
8069 | FileIn n | FileOut n -> pr " (%s|-)" n
8070 | BufferIn n -> pr " %s" n
8074 pr "%s\n\n" longdesc;
8076 if List.exists (function FileIn _ | FileOut _ -> true
8077 | _ -> false) (snd style) then
8078 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
8080 if List.mem ProtocolLimitWarning flags then
8081 pr "%s\n\n" protocol_limit_warning;
8083 if List.mem DangerWillRobinson flags then
8084 pr "%s\n\n" danger_will_robinson;
8086 match deprecation_notice flags with
8088 | Some txt -> pr "%s\n\n" txt
8089 ) all_functions_sorted
8091 (* Generate a C function prototype. *)
8092 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
8093 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
8095 ?handle name style =
8096 if extern then pr "extern ";
8097 if static then pr "static ";
8098 (match fst style with
8100 | RInt _ -> pr "int "
8101 | RInt64 _ -> pr "int64_t "
8102 | RBool _ -> pr "int "
8103 | RConstString _ | RConstOptString _ -> pr "const char *"
8104 | RString _ | RBufferOut _ -> pr "char *"
8105 | RStringList _ | RHashtable _ -> pr "char **"
8106 | RStruct (_, typ) ->
8107 if not in_daemon then pr "struct guestfs_%s *" typ
8108 else pr "guestfs_int_%s *" typ
8109 | RStructList (_, typ) ->
8110 if not in_daemon then pr "struct guestfs_%s_list *" typ
8111 else pr "guestfs_int_%s_list *" typ
8113 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
8114 pr "%s%s (" prefix name;
8115 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
8118 let comma = ref false in
8121 | Some handle -> pr "guestfs_h *%s" handle; comma := true
8125 if single_line then pr ", " else pr ",\n\t\t"
8132 | Device n | Dev_or_Path n
8136 pr "const char *%s" n
8137 | StringList n | DeviceList n ->
8139 pr "char *const *%s" n
8140 | Bool n -> next (); pr "int %s" n
8141 | Int n -> next (); pr "int %s" n
8142 | Int64 n -> next (); pr "int64_t %s" n
8145 if not in_daemon then (next (); pr "const char *%s" n)
8148 pr "const char *%s" n;
8150 pr "size_t %s_size" n
8152 if is_RBufferOut then (next (); pr "size_t *size_r");
8155 if semicolon then pr ";";
8156 if newline then pr "\n"
8158 (* Generate C call arguments, eg "(handle, foo, bar)" *)
8159 and generate_c_call_args ?handle ?(decl = false) style =
8161 let comma = ref false in
8163 if !comma then pr ", ";
8168 | Some handle -> pr "%s" handle; comma := true
8174 pr "%s, %s_size" n n
8177 pr "%s" (name_of_argt arg)
8179 (* For RBufferOut calls, add implicit &size parameter. *)
8181 match fst style with
8189 (* Generate the OCaml bindings interface. *)
8190 and generate_ocaml_mli () =
8191 generate_header OCamlStyle LGPLv2plus;
8194 (** For API documentation you should refer to the C API
8195 in the guestfs(3) manual page. The OCaml API uses almost
8196 exactly the same calls. *)
8199 (** A [guestfs_h] handle. *)
8201 exception Error of string
8202 (** This exception is raised when there is an error. *)
8204 exception Handle_closed of string
8205 (** This exception is raised if you use a {!Guestfs.t} handle
8206 after calling {!close} on it. The string is the name of
8209 val create : unit -> t
8210 (** Create a {!Guestfs.t} handle. *)
8212 val close : t -> unit
8213 (** Close the {!Guestfs.t} handle and free up all resources used
8216 Handles are closed by the garbage collector when they become
8217 unreferenced, but callers can call this in order to provide
8218 predictable cleanup. *)
8221 generate_ocaml_structure_decls ();
8225 fun (name, style, _, _, _, shortdesc, _) ->
8226 generate_ocaml_prototype name style;
8227 pr "(** %s *)\n" shortdesc;
8229 ) all_functions_sorted
8231 (* Generate the OCaml bindings implementation. *)
8232 and generate_ocaml_ml () =
8233 generate_header OCamlStyle LGPLv2plus;
8238 exception Error of string
8239 exception Handle_closed of string
8241 external create : unit -> t = \"ocaml_guestfs_create\"
8242 external close : t -> unit = \"ocaml_guestfs_close\"
8244 (* Give the exceptions names, so they can be raised from the C code. *)
8246 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
8247 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
8251 generate_ocaml_structure_decls ();
8255 fun (name, style, _, _, _, shortdesc, _) ->
8256 generate_ocaml_prototype ~is_external:true name style;
8257 ) all_functions_sorted
8259 (* Generate the OCaml bindings C implementation. *)
8260 and generate_ocaml_c () =
8261 generate_header CStyle LGPLv2plus;
8268 #include <caml/config.h>
8269 #include <caml/alloc.h>
8270 #include <caml/callback.h>
8271 #include <caml/fail.h>
8272 #include <caml/memory.h>
8273 #include <caml/mlvalues.h>
8274 #include <caml/signals.h>
8276 #include <guestfs.h>
8278 #include \"guestfs_c.h\"
8280 /* Copy a hashtable of string pairs into an assoc-list. We return
8281 * the list in reverse order, but hashtables aren't supposed to be
8284 static CAMLprim value
8285 copy_table (char * const * argv)
8288 CAMLlocal5 (rv, pairv, kv, vv, cons);
8292 for (i = 0; argv[i] != NULL; i += 2) {
8293 kv = caml_copy_string (argv[i]);
8294 vv = caml_copy_string (argv[i+1]);
8295 pairv = caml_alloc (2, 0);
8296 Store_field (pairv, 0, kv);
8297 Store_field (pairv, 1, vv);
8298 cons = caml_alloc (2, 0);
8299 Store_field (cons, 1, rv);
8301 Store_field (cons, 0, pairv);
8309 (* Struct copy functions. *)
8311 let emit_ocaml_copy_list_function typ =
8312 pr "static CAMLprim value\n";
8313 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
8315 pr " CAMLparam0 ();\n";
8316 pr " CAMLlocal2 (rv, v);\n";
8317 pr " unsigned int i;\n";
8319 pr " if (%ss->len == 0)\n" typ;
8320 pr " CAMLreturn (Atom (0));\n";
8322 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
8323 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
8324 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
8325 pr " caml_modify (&Field (rv, i), v);\n";
8327 pr " CAMLreturn (rv);\n";
8335 let has_optpercent_col =
8336 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
8338 pr "static CAMLprim value\n";
8339 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
8341 pr " CAMLparam0 ();\n";
8342 if has_optpercent_col then
8343 pr " CAMLlocal3 (rv, v, v2);\n"
8345 pr " CAMLlocal2 (rv, v);\n";
8347 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
8352 pr " v = caml_copy_string (%s->%s);\n" typ name
8354 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
8355 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
8358 pr " v = caml_alloc_string (32);\n";
8359 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
8360 | name, (FBytes|FInt64|FUInt64) ->
8361 pr " v = caml_copy_int64 (%s->%s);\n" typ name
8362 | name, (FInt32|FUInt32) ->
8363 pr " v = caml_copy_int32 (%s->%s);\n" typ name
8364 | name, FOptPercent ->
8365 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
8366 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
8367 pr " v = caml_alloc (1, 0);\n";
8368 pr " Store_field (v, 0, v2);\n";
8369 pr " } else /* None */\n";
8370 pr " v = Val_int (0);\n";
8372 pr " v = Val_int (%s->%s);\n" typ name
8374 pr " Store_field (rv, %d, v);\n" i
8376 pr " CAMLreturn (rv);\n";
8381 (* Emit a copy_TYPE_list function definition only if that function is used. *)
8384 | typ, (RStructListOnly | RStructAndList) ->
8385 (* generate the function for typ *)
8386 emit_ocaml_copy_list_function typ
8387 | typ, _ -> () (* empty *)
8388 ) (rstructs_used_by all_functions);
8392 fun (name, style, _, _, _, _, _) ->
8393 pr "/* Automatically generated wrapper for function\n";
8395 generate_ocaml_prototype name style;
8400 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
8402 let needs_extra_vs =
8403 match fst style with RConstOptString _ -> true | _ -> false in
8405 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8406 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
8407 List.iter (pr ", value %s") (List.tl params); pr ");\n";
8410 pr "CAMLprim value\n";
8411 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
8412 List.iter (pr ", value %s") (List.tl params);
8417 | [p1; p2; p3; p4; p5] ->
8418 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
8419 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
8420 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
8421 pr " CAMLxparam%d (%s);\n"
8422 (List.length rest) (String.concat ", " rest)
8424 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
8426 if not needs_extra_vs then
8427 pr " CAMLlocal1 (rv);\n"
8429 pr " CAMLlocal3 (rv, v, v2);\n";
8432 pr " guestfs_h *g = Guestfs_val (gv);\n";
8433 pr " if (g == NULL)\n";
8434 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
8440 | Device n | Dev_or_Path n
8444 pr " const char *%s = String_val (%sv);\n" n n
8446 pr " const char *%s =\n" n;
8447 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
8450 pr " const char *%s = String_val (%sv);\n" n n;
8451 pr " size_t %s_size = caml_string_length (%sv);\n" n n
8452 | StringList n | DeviceList n ->
8453 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
8455 pr " int %s = Bool_val (%sv);\n" n n
8457 pr " int %s = Int_val (%sv);\n" n n
8459 pr " int64_t %s = Int64_val (%sv);\n" n n
8462 match fst style with
8463 | RErr -> pr " int r;\n"; "-1"
8464 | RInt _ -> pr " int r;\n"; "-1"
8465 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8466 | RBool _ -> pr " int r;\n"; "-1"
8467 | RConstString _ | RConstOptString _ ->
8468 pr " const char *r;\n"; "NULL"
8469 | RString _ -> pr " char *r;\n"; "NULL"
8474 | RStruct (_, typ) ->
8475 pr " struct guestfs_%s *r;\n" typ; "NULL"
8476 | RStructList (_, typ) ->
8477 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8484 pr " size_t size;\n";
8488 pr " caml_enter_blocking_section ();\n";
8489 pr " r = guestfs_%s " name;
8490 generate_c_call_args ~handle:"g" style;
8492 pr " caml_leave_blocking_section ();\n";
8496 | StringList n | DeviceList n ->
8497 pr " ocaml_guestfs_free_strings (%s);\n" n;
8498 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8499 | Bool _ | Int _ | Int64 _
8500 | FileIn _ | FileOut _ | BufferIn _ -> ()
8503 pr " if (r == %s)\n" error_code;
8504 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
8507 (match fst style with
8508 | RErr -> pr " rv = Val_unit;\n"
8509 | RInt _ -> pr " rv = Val_int (r);\n"
8511 pr " rv = caml_copy_int64 (r);\n"
8512 | RBool _ -> pr " rv = Val_bool (r);\n"
8514 pr " rv = caml_copy_string (r);\n"
8515 | RConstOptString _ ->
8516 pr " if (r) { /* Some string */\n";
8517 pr " v = caml_alloc (1, 0);\n";
8518 pr " v2 = caml_copy_string (r);\n";
8519 pr " Store_field (v, 0, v2);\n";
8520 pr " } else /* None */\n";
8521 pr " v = Val_int (0);\n";
8523 pr " rv = caml_copy_string (r);\n";
8526 pr " rv = caml_copy_string_array ((const char **) r);\n";
8527 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8529 | RStruct (_, typ) ->
8530 pr " rv = copy_%s (r);\n" typ;
8531 pr " guestfs_free_%s (r);\n" typ;
8532 | RStructList (_, typ) ->
8533 pr " rv = copy_%s_list (r);\n" typ;
8534 pr " guestfs_free_%s_list (r);\n" typ;
8536 pr " rv = copy_table (r);\n";
8537 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8540 pr " rv = caml_alloc_string (size);\n";
8541 pr " memcpy (String_val (rv), r, size);\n";
8544 pr " CAMLreturn (rv);\n";
8548 if List.length params > 5 then (
8549 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8550 pr "CAMLprim value ";
8551 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
8552 pr "CAMLprim value\n";
8553 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
8555 pr " return ocaml_guestfs_%s (argv[0]" name;
8556 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
8561 ) all_functions_sorted
8563 and generate_ocaml_structure_decls () =
8566 pr "type %s = {\n" typ;
8569 | name, FString -> pr " %s : string;\n" name
8570 | name, FBuffer -> pr " %s : string;\n" name
8571 | name, FUUID -> pr " %s : string;\n" name
8572 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
8573 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
8574 | name, FChar -> pr " %s : char;\n" name
8575 | name, FOptPercent -> pr " %s : float option;\n" name
8581 and generate_ocaml_prototype ?(is_external = false) name style =
8582 if is_external then pr "external " else pr "val ";
8583 pr "%s : t -> " name;
8586 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _
8587 | BufferIn _ -> pr "string -> "
8588 | OptString _ -> pr "string option -> "
8589 | StringList _ | DeviceList _ -> pr "string array -> "
8590 | Bool _ -> pr "bool -> "
8591 | Int _ -> pr "int -> "
8592 | Int64 _ -> pr "int64 -> "
8594 (match fst style with
8595 | RErr -> pr "unit" (* all errors are turned into exceptions *)
8596 | RInt _ -> pr "int"
8597 | RInt64 _ -> pr "int64"
8598 | RBool _ -> pr "bool"
8599 | RConstString _ -> pr "string"
8600 | RConstOptString _ -> pr "string option"
8601 | RString _ | RBufferOut _ -> pr "string"
8602 | RStringList _ -> pr "string array"
8603 | RStruct (_, typ) -> pr "%s" typ
8604 | RStructList (_, typ) -> pr "%s array" typ
8605 | RHashtable _ -> pr "(string * string) list"
8607 if is_external then (
8609 if List.length (snd style) + 1 > 5 then
8610 pr "\"ocaml_guestfs_%s_byte\" " name;
8611 pr "\"ocaml_guestfs_%s\"" name
8615 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
8616 and generate_perl_xs () =
8617 generate_header CStyle LGPLv2plus;
8620 #include \"EXTERN.h\"
8624 #include <guestfs.h>
8627 #define PRId64 \"lld\"
8631 my_newSVll(long long val) {
8632 #ifdef USE_64_BIT_ALL
8633 return newSViv(val);
8637 len = snprintf(buf, 100, \"%%\" PRId64, val);
8638 return newSVpv(buf, len);
8643 #define PRIu64 \"llu\"
8647 my_newSVull(unsigned long long val) {
8648 #ifdef USE_64_BIT_ALL
8649 return newSVuv(val);
8653 len = snprintf(buf, 100, \"%%\" PRIu64, val);
8654 return newSVpv(buf, len);
8658 /* http://www.perlmonks.org/?node_id=680842 */
8660 XS_unpack_charPtrPtr (SV *arg) {
8665 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
8666 croak (\"array reference expected\");
8668 av = (AV *)SvRV (arg);
8669 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
8671 croak (\"malloc failed\");
8673 for (i = 0; i <= av_len (av); i++) {
8674 SV **elem = av_fetch (av, i, 0);
8676 if (!elem || !*elem)
8677 croak (\"missing element in list\");
8679 ret[i] = SvPV_nolen (*elem);
8687 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
8694 RETVAL = guestfs_create ();
8696 croak (\"could not create guestfs handle\");
8697 guestfs_set_error_handler (RETVAL, NULL, NULL);
8710 fun (name, style, _, _, _, _, _) ->
8711 (match fst style with
8712 | RErr -> pr "void\n"
8713 | RInt _ -> pr "SV *\n"
8714 | RInt64 _ -> pr "SV *\n"
8715 | RBool _ -> pr "SV *\n"
8716 | RConstString _ -> pr "SV *\n"
8717 | RConstOptString _ -> pr "SV *\n"
8718 | RString _ -> pr "SV *\n"
8719 | RBufferOut _ -> pr "SV *\n"
8721 | RStruct _ | RStructList _
8723 pr "void\n" (* all lists returned implictly on the stack *)
8725 (* Call and arguments. *)
8728 fun arg -> pr ", %s" (name_of_argt arg)
8731 pr " guestfs_h *g;\n";
8735 | Pathname n | Device n | Dev_or_Path n | String n
8736 | FileIn n | FileOut n ->
8739 pr " char *%s;\n" n;
8740 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
8742 (* http://www.perlmonks.org/?node_id=554277
8743 * Note that the implicit handle argument means we have
8744 * to add 1 to the ST(x) operator.
8746 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
8747 | StringList n | DeviceList n -> pr " char **%s;\n" n
8748 | Bool n -> pr " int %s;\n" n
8749 | Int n -> pr " int %s;\n" n
8750 | Int64 n -> pr " int64_t %s;\n" n
8753 let do_cleanups () =
8756 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8757 | Bool _ | Int _ | Int64 _
8758 | FileIn _ | FileOut _
8760 | StringList n | DeviceList n -> pr " free (%s);\n" n
8765 (match fst style with
8770 pr " r = guestfs_%s " name;
8771 generate_c_call_args ~handle:"g" style;
8774 pr " if (r == -1)\n";
8775 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8781 pr " %s = guestfs_%s " n name;
8782 generate_c_call_args ~handle:"g" style;
8785 pr " if (%s == -1)\n" n;
8786 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8787 pr " RETVAL = newSViv (%s);\n" n;
8792 pr " int64_t %s;\n" n;
8794 pr " %s = guestfs_%s " n name;
8795 generate_c_call_args ~handle:"g" style;
8798 pr " if (%s == -1)\n" n;
8799 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8800 pr " RETVAL = my_newSVll (%s);\n" n;
8805 pr " const char *%s;\n" n;
8807 pr " %s = guestfs_%s " n name;
8808 generate_c_call_args ~handle:"g" style;
8811 pr " if (%s == NULL)\n" n;
8812 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8813 pr " RETVAL = newSVpv (%s, 0);\n" n;
8816 | RConstOptString n ->
8818 pr " const char *%s;\n" n;
8820 pr " %s = guestfs_%s " n name;
8821 generate_c_call_args ~handle:"g" style;
8824 pr " if (%s == NULL)\n" n;
8825 pr " RETVAL = &PL_sv_undef;\n";
8827 pr " RETVAL = newSVpv (%s, 0);\n" n;
8832 pr " char *%s;\n" n;
8834 pr " %s = guestfs_%s " n name;
8835 generate_c_call_args ~handle:"g" style;
8838 pr " if (%s == NULL)\n" n;
8839 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8840 pr " RETVAL = newSVpv (%s, 0);\n" n;
8841 pr " free (%s);\n" n;
8844 | RStringList n | RHashtable n ->
8846 pr " char **%s;\n" n;
8849 pr " %s = guestfs_%s " n name;
8850 generate_c_call_args ~handle:"g" style;
8853 pr " if (%s == NULL)\n" n;
8854 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8855 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
8856 pr " EXTEND (SP, n);\n";
8857 pr " for (i = 0; i < n; ++i) {\n";
8858 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
8859 pr " free (%s[i]);\n" n;
8861 pr " free (%s);\n" n;
8862 | RStruct (n, typ) ->
8863 let cols = cols_of_struct typ in
8864 generate_perl_struct_code typ cols name style n do_cleanups
8865 | RStructList (n, typ) ->
8866 let cols = cols_of_struct typ in
8867 generate_perl_struct_list_code typ cols name style n do_cleanups
8870 pr " char *%s;\n" n;
8871 pr " size_t size;\n";
8873 pr " %s = guestfs_%s " n name;
8874 generate_c_call_args ~handle:"g" style;
8877 pr " if (%s == NULL)\n" n;
8878 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8879 pr " RETVAL = newSVpvn (%s, size);\n" n;
8880 pr " free (%s);\n" n;
8888 and generate_perl_struct_list_code typ cols name style n do_cleanups =
8890 pr " struct guestfs_%s_list *%s;\n" typ n;
8894 pr " %s = guestfs_%s " n name;
8895 generate_c_call_args ~handle:"g" style;
8898 pr " if (%s == NULL)\n" n;
8899 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8900 pr " EXTEND (SP, %s->len);\n" n;
8901 pr " for (i = 0; i < %s->len; ++i) {\n" n;
8902 pr " hv = newHV ();\n";
8906 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
8907 name (String.length name) n name
8909 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
8910 name (String.length name) n name
8912 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
8913 name (String.length name) n name n name
8914 | name, (FBytes|FUInt64) ->
8915 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
8916 name (String.length name) n name
8918 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
8919 name (String.length name) n name
8920 | name, (FInt32|FUInt32) ->
8921 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
8922 name (String.length name) n name
8924 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
8925 name (String.length name) n name
8926 | name, FOptPercent ->
8927 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
8928 name (String.length name) n name
8930 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
8932 pr " guestfs_free_%s_list (%s);\n" typ n
8934 and generate_perl_struct_code typ cols name style n do_cleanups =
8936 pr " struct guestfs_%s *%s;\n" typ n;
8938 pr " %s = guestfs_%s " n name;
8939 generate_c_call_args ~handle:"g" style;
8942 pr " if (%s == NULL)\n" n;
8943 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8944 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
8946 fun ((name, _) as col) ->
8947 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
8951 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
8954 pr " PUSHs (sv_2mortal (newSVpvn (%s->%s, %s->%s_len)));\n"
8957 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
8959 | name, (FBytes|FUInt64) ->
8960 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
8963 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
8965 | name, (FInt32|FUInt32) ->
8966 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8969 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
8971 | name, FOptPercent ->
8972 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8975 pr " free (%s);\n" n
8977 (* Generate Sys/Guestfs.pm. *)
8978 and generate_perl_pm () =
8979 generate_header HashStyle LGPLv2plus;
8986 Sys::Guestfs - Perl bindings for libguestfs
8992 my $h = Sys::Guestfs->new ();
8993 $h->add_drive ('guest.img');
8995 $h->mount ('/dev/sda1', '/');
8996 $h->touch ('/hello');
9001 The C<Sys::Guestfs> module provides a Perl XS binding to the
9002 libguestfs API for examining and modifying virtual machine
9005 Amongst the things this is good for: making batch configuration
9006 changes to guests, getting disk used/free statistics (see also:
9007 virt-df), migrating between virtualization systems (see also:
9008 virt-p2v), performing partial backups, performing partial guest
9009 clones, cloning guests and changing registry/UUID/hostname info, and
9012 Libguestfs uses Linux kernel and qemu code, and can access any type of
9013 guest filesystem that Linux and qemu can, including but not limited
9014 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9015 schemes, qcow, qcow2, vmdk.
9017 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9018 LVs, what filesystem is in each LV, etc.). It can also run commands
9019 in the context of the guest. Also you can access filesystems over
9022 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
9023 functions for using libguestfs from Perl, including integration
9028 All errors turn into calls to C<croak> (see L<Carp(3)>).
9036 package Sys::Guestfs;
9041 # This version number changes whenever a new function
9042 # is added to the libguestfs API. It is not directly
9043 # related to the libguestfs version number.
9044 use vars qw($VERSION);
9048 XSLoader::load ('Sys::Guestfs');
9050 =item $h = Sys::Guestfs->new ();
9052 Create a new guestfs handle.
9058 my $class = ref ($proto) || $proto;
9060 my $self = Sys::Guestfs::_create ();
9061 bless $self, $class;
9067 (* Actions. We only need to print documentation for these as
9068 * they are pulled in from the XS code automatically.
9071 fun (name, style, _, flags, _, _, longdesc) ->
9072 if not (List.mem NotInDocs flags) then (
9073 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
9075 generate_perl_prototype name style;
9077 pr "%s\n\n" longdesc;
9078 if List.mem ProtocolLimitWarning flags then
9079 pr "%s\n\n" protocol_limit_warning;
9080 if List.mem DangerWillRobinson flags then
9081 pr "%s\n\n" danger_will_robinson;
9082 match deprecation_notice flags with
9084 | Some txt -> pr "%s\n\n" txt
9086 ) all_functions_sorted;
9098 Copyright (C) %s Red Hat Inc.
9102 Please see the file COPYING.LIB for the full license.
9108 L<http://libguestfs.org>,
9109 L<Sys::Guestfs::Lib(3)>.
9114 and generate_perl_prototype name style =
9115 (match fst style with
9123 | RBufferOut n -> pr "$%s = " n
9125 | RHashtable n -> pr "%%%s = " n
9127 | RStructList (n,_) -> pr "@%s = " n
9130 let comma = ref false in
9133 if !comma then pr ", ";
9136 | Pathname n | Device n | Dev_or_Path n | String n
9137 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
9140 | StringList n | DeviceList n ->
9145 (* Generate Python C module. *)
9146 and generate_python_c () =
9147 generate_header CStyle LGPLv2plus;
9150 #define PY_SSIZE_T_CLEAN 1
9153 #if PY_VERSION_HEX < 0x02050000
9154 typedef int Py_ssize_t;
9155 #define PY_SSIZE_T_MAX INT_MAX
9156 #define PY_SSIZE_T_MIN INT_MIN
9163 #include \"guestfs.h\"
9171 get_handle (PyObject *obj)
9174 assert (obj != Py_None);
9175 return ((Pyguestfs_Object *) obj)->g;
9179 put_handle (guestfs_h *g)
9183 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
9186 /* This list should be freed (but not the strings) after use. */
9188 get_string_list (PyObject *obj)
9195 if (!PyList_Check (obj)) {
9196 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
9200 len = PyList_Size (obj);
9201 r = malloc (sizeof (char *) * (len+1));
9203 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
9207 for (i = 0; i < len; ++i)
9208 r[i] = PyString_AsString (PyList_GetItem (obj, i));
9215 put_string_list (char * const * const argv)
9220 for (argc = 0; argv[argc] != NULL; ++argc)
9223 list = PyList_New (argc);
9224 for (i = 0; i < argc; ++i)
9225 PyList_SetItem (list, i, PyString_FromString (argv[i]));
9231 put_table (char * const * const argv)
9233 PyObject *list, *item;
9236 for (argc = 0; argv[argc] != NULL; ++argc)
9239 list = PyList_New (argc >> 1);
9240 for (i = 0; i < argc; i += 2) {
9241 item = PyTuple_New (2);
9242 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
9243 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
9244 PyList_SetItem (list, i >> 1, item);
9251 free_strings (char **argv)
9255 for (argc = 0; argv[argc] != NULL; ++argc)
9261 py_guestfs_create (PyObject *self, PyObject *args)
9265 g = guestfs_create ();
9267 PyErr_SetString (PyExc_RuntimeError,
9268 \"guestfs.create: failed to allocate handle\");
9271 guestfs_set_error_handler (g, NULL, NULL);
9272 return put_handle (g);
9276 py_guestfs_close (PyObject *self, PyObject *args)
9281 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
9283 g = get_handle (py_g);
9287 Py_INCREF (Py_None);
9293 let emit_put_list_function typ =
9294 pr "static PyObject *\n";
9295 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
9297 pr " PyObject *list;\n";
9300 pr " list = PyList_New (%ss->len);\n" typ;
9301 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
9302 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
9303 pr " return list;\n";
9308 (* Structures, turned into Python dictionaries. *)
9311 pr "static PyObject *\n";
9312 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
9314 pr " PyObject *dict;\n";
9316 pr " dict = PyDict_New ();\n";
9320 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9321 pr " PyString_FromString (%s->%s));\n"
9324 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9325 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
9328 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9329 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
9331 | name, (FBytes|FUInt64) ->
9332 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9333 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
9336 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9337 pr " PyLong_FromLongLong (%s->%s));\n"
9340 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9341 pr " PyLong_FromUnsignedLong (%s->%s));\n"
9344 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9345 pr " PyLong_FromLong (%s->%s));\n"
9347 | name, FOptPercent ->
9348 pr " if (%s->%s >= 0)\n" typ name;
9349 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9350 pr " PyFloat_FromDouble ((double) %s->%s));\n"
9353 pr " Py_INCREF (Py_None);\n";
9354 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
9357 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9358 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
9360 pr " return dict;\n";
9366 (* Emit a put_TYPE_list function definition only if that function is used. *)
9369 | typ, (RStructListOnly | RStructAndList) ->
9370 (* generate the function for typ *)
9371 emit_put_list_function typ
9372 | typ, _ -> () (* empty *)
9373 ) (rstructs_used_by all_functions);
9375 (* Python wrapper functions. *)
9377 fun (name, style, _, _, _, _, _) ->
9378 pr "static PyObject *\n";
9379 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
9382 pr " PyObject *py_g;\n";
9383 pr " guestfs_h *g;\n";
9384 pr " PyObject *py_r;\n";
9387 match fst style with
9388 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9389 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9390 | RConstString _ | RConstOptString _ ->
9391 pr " const char *r;\n"; "NULL"
9392 | RString _ -> pr " char *r;\n"; "NULL"
9393 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9394 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9395 | RStructList (_, typ) ->
9396 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9399 pr " size_t size;\n";
9404 | Pathname n | Device n | Dev_or_Path n | String n
9405 | FileIn n | FileOut n ->
9406 pr " const char *%s;\n" n
9407 | OptString n -> pr " const char *%s;\n" n
9409 pr " const char *%s;\n" n;
9410 pr " Py_ssize_t %s_size;\n" n
9411 | StringList n | DeviceList n ->
9412 pr " PyObject *py_%s;\n" n;
9413 pr " char **%s;\n" n
9414 | Bool n -> pr " int %s;\n" n
9415 | Int n -> pr " int %s;\n" n
9416 | Int64 n -> pr " long long %s;\n" n
9421 (* Convert the parameters. *)
9422 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
9425 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
9426 | OptString _ -> pr "z"
9427 | StringList _ | DeviceList _ -> pr "O"
9428 | Bool _ -> pr "i" (* XXX Python has booleans? *)
9430 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
9431 * emulate C's int/long/long long in Python?
9433 | BufferIn _ -> pr "s#"
9435 pr ":guestfs_%s\",\n" name;
9439 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
9440 | OptString n -> pr ", &%s" n
9441 | StringList n | DeviceList n -> pr ", &py_%s" n
9442 | Bool n -> pr ", &%s" n
9443 | Int n -> pr ", &%s" n
9444 | Int64 n -> pr ", &%s" n
9445 | BufferIn n -> pr ", &%s, &%s_size" n n
9449 pr " return NULL;\n";
9451 pr " g = get_handle (py_g);\n";
9454 | Pathname _ | Device _ | Dev_or_Path _ | String _
9455 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9457 | StringList n | DeviceList n ->
9458 pr " %s = get_string_list (py_%s);\n" n n;
9459 pr " if (!%s) return NULL;\n" n
9464 pr " r = guestfs_%s " name;
9465 generate_c_call_args ~handle:"g" style;
9470 | Pathname _ | Device _ | Dev_or_Path _ | String _
9471 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9473 | StringList n | DeviceList n ->
9474 pr " free (%s);\n" n
9477 pr " if (r == %s) {\n" error_code;
9478 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
9479 pr " return NULL;\n";
9483 (match fst style with
9485 pr " Py_INCREF (Py_None);\n";
9486 pr " py_r = Py_None;\n"
9488 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
9489 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
9490 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
9491 | RConstOptString _ ->
9493 pr " py_r = PyString_FromString (r);\n";
9495 pr " Py_INCREF (Py_None);\n";
9496 pr " py_r = Py_None;\n";
9499 pr " py_r = PyString_FromString (r);\n";
9502 pr " py_r = put_string_list (r);\n";
9503 pr " free_strings (r);\n"
9504 | RStruct (_, typ) ->
9505 pr " py_r = put_%s (r);\n" typ;
9506 pr " guestfs_free_%s (r);\n" typ
9507 | RStructList (_, typ) ->
9508 pr " py_r = put_%s_list (r);\n" typ;
9509 pr " guestfs_free_%s_list (r);\n" typ
9511 pr " py_r = put_table (r);\n";
9512 pr " free_strings (r);\n"
9514 pr " py_r = PyString_FromStringAndSize (r, size);\n";
9518 pr " return py_r;\n";
9523 (* Table of functions. *)
9524 pr "static PyMethodDef methods[] = {\n";
9525 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
9526 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
9528 fun (name, _, _, _, _, _, _) ->
9529 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
9532 pr " { NULL, NULL, 0, NULL }\n";
9536 (* Init function. *)
9539 initlibguestfsmod (void)
9541 static int initialized = 0;
9543 if (initialized) return;
9544 Py_InitModule ((char *) \"libguestfsmod\", methods);
9549 (* Generate Python module. *)
9550 and generate_python_py () =
9551 generate_header HashStyle LGPLv2plus;
9554 u\"\"\"Python bindings for libguestfs
9557 g = guestfs.GuestFS ()
9558 g.add_drive (\"guest.img\")
9560 parts = g.list_partitions ()
9562 The guestfs module provides a Python binding to the libguestfs API
9563 for examining and modifying virtual machine disk images.
9565 Amongst the things this is good for: making batch configuration
9566 changes to guests, getting disk used/free statistics (see also:
9567 virt-df), migrating between virtualization systems (see also:
9568 virt-p2v), performing partial backups, performing partial guest
9569 clones, cloning guests and changing registry/UUID/hostname info, and
9572 Libguestfs uses Linux kernel and qemu code, and can access any type of
9573 guest filesystem that Linux and qemu can, including but not limited
9574 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9575 schemes, qcow, qcow2, vmdk.
9577 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9578 LVs, what filesystem is in each LV, etc.). It can also run commands
9579 in the context of the guest. Also you can access filesystems over
9582 Errors which happen while using the API are turned into Python
9583 RuntimeError exceptions.
9585 To create a guestfs handle you usually have to perform the following
9588 # Create the handle, call add_drive at least once, and possibly
9589 # several times if the guest has multiple block devices:
9590 g = guestfs.GuestFS ()
9591 g.add_drive (\"guest.img\")
9593 # Launch the qemu subprocess and wait for it to become ready:
9596 # Now you can issue commands, for example:
9601 import libguestfsmod
9604 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
9606 def __init__ (self):
9607 \"\"\"Create a new libguestfs handle.\"\"\"
9608 self._o = libguestfsmod.create ()
9611 libguestfsmod.close (self._o)
9616 fun (name, style, _, flags, _, _, longdesc) ->
9618 generate_py_call_args ~handle:"self" (snd style);
9621 if not (List.mem NotInDocs flags) then (
9622 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9624 match fst style with
9625 | RErr | RInt _ | RInt64 _ | RBool _
9626 | RConstOptString _ | RConstString _
9627 | RString _ | RBufferOut _ -> doc
9629 doc ^ "\n\nThis function returns a list of strings."
9630 | RStruct (_, typ) ->
9631 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
9632 | RStructList (_, typ) ->
9633 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
9635 doc ^ "\n\nThis function returns a dictionary." in
9637 if List.mem ProtocolLimitWarning flags then
9638 doc ^ "\n\n" ^ protocol_limit_warning
9641 if List.mem DangerWillRobinson flags then
9642 doc ^ "\n\n" ^ danger_will_robinson
9645 match deprecation_notice flags with
9647 | Some txt -> doc ^ "\n\n" ^ txt in
9648 let doc = pod2text ~width:60 name doc in
9649 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
9650 let doc = String.concat "\n " doc in
9651 pr " u\"\"\"%s\"\"\"\n" doc;
9653 pr " return libguestfsmod.%s " name;
9654 generate_py_call_args ~handle:"self._o" (snd style);
9659 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
9660 and generate_py_call_args ~handle args =
9662 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9665 (* Useful if you need the longdesc POD text as plain text. Returns a
9668 * Because this is very slow (the slowest part of autogeneration),
9669 * we memoize the results.
9671 and pod2text ~width name longdesc =
9672 let key = width, name, longdesc in
9673 try Hashtbl.find pod2text_memo key
9675 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
9676 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
9678 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
9679 let chan = open_process_in cmd in
9680 let lines = ref [] in
9682 let line = input_line chan in
9683 if i = 1 then (* discard the first line of output *)
9686 let line = triml line in
9687 lines := line :: !lines;
9690 let lines = try loop 1 with End_of_file -> List.rev !lines in
9692 (match close_process_in chan with
9695 failwithf "pod2text: process exited with non-zero status (%d)" i
9696 | WSIGNALED i | WSTOPPED i ->
9697 failwithf "pod2text: process signalled or stopped by signal %d" i
9699 Hashtbl.add pod2text_memo key lines;
9700 pod2text_memo_updated ();
9703 (* Generate ruby bindings. *)
9704 and generate_ruby_c () =
9705 generate_header CStyle LGPLv2plus;
9713 #include \"guestfs.h\"
9715 #include \"extconf.h\"
9717 /* For Ruby < 1.9 */
9719 #define RARRAY_LEN(r) (RARRAY((r))->len)
9722 static VALUE m_guestfs; /* guestfs module */
9723 static VALUE c_guestfs; /* guestfs_h handle */
9724 static VALUE e_Error; /* used for all errors */
9726 static void ruby_guestfs_free (void *p)
9729 guestfs_close ((guestfs_h *) p);
9732 static VALUE ruby_guestfs_create (VALUE m)
9736 g = guestfs_create ();
9738 rb_raise (e_Error, \"failed to create guestfs handle\");
9740 /* Don't print error messages to stderr by default. */
9741 guestfs_set_error_handler (g, NULL, NULL);
9743 /* Wrap it, and make sure the close function is called when the
9746 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
9749 static VALUE ruby_guestfs_close (VALUE gv)
9752 Data_Get_Struct (gv, guestfs_h, g);
9754 ruby_guestfs_free (g);
9755 DATA_PTR (gv) = NULL;
9763 fun (name, style, _, _, _, _, _) ->
9764 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
9765 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
9768 pr " guestfs_h *g;\n";
9769 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
9771 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
9777 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
9778 pr " Check_Type (%sv, T_STRING);\n" n;
9779 pr " const char *%s = StringValueCStr (%sv);\n" n n;
9781 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9782 pr " \"%s\", \"%s\");\n" n name
9784 pr " Check_Type (%sv, T_STRING);\n" n;
9785 pr " const char *%s = RSTRING (%sv)->ptr;\n" n n;
9787 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9788 pr " \"%s\", \"%s\");\n" n name;
9789 pr " size_t %s_size = RSTRING (%sv)->len;\n" n n
9791 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
9792 | StringList n | DeviceList n ->
9793 pr " char **%s;\n" n;
9794 pr " Check_Type (%sv, T_ARRAY);\n" n;
9796 pr " int i, len;\n";
9797 pr " len = RARRAY_LEN (%sv);\n" n;
9798 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
9800 pr " for (i = 0; i < len; ++i) {\n";
9801 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
9802 pr " %s[i] = StringValueCStr (v);\n" n;
9804 pr " %s[len] = NULL;\n" n;
9807 pr " int %s = RTEST (%sv);\n" n n
9809 pr " int %s = NUM2INT (%sv);\n" n n
9811 pr " long long %s = NUM2LL (%sv);\n" n n
9816 match fst style with
9817 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9818 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9819 | RConstString _ | RConstOptString _ ->
9820 pr " const char *r;\n"; "NULL"
9821 | RString _ -> pr " char *r;\n"; "NULL"
9822 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9823 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9824 | RStructList (_, typ) ->
9825 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9828 pr " size_t size;\n";
9832 pr " r = guestfs_%s " name;
9833 generate_c_call_args ~handle:"g" style;
9838 | Pathname _ | Device _ | Dev_or_Path _ | String _
9839 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9841 | StringList n | DeviceList n ->
9842 pr " free (%s);\n" n
9845 pr " if (r == %s)\n" error_code;
9846 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
9849 (match fst style with
9851 pr " return Qnil;\n"
9852 | RInt _ | RBool _ ->
9853 pr " return INT2NUM (r);\n"
9855 pr " return ULL2NUM (r);\n"
9857 pr " return rb_str_new2 (r);\n";
9858 | RConstOptString _ ->
9860 pr " return rb_str_new2 (r);\n";
9862 pr " return Qnil;\n";
9864 pr " VALUE rv = rb_str_new2 (r);\n";
9868 pr " int i, len = 0;\n";
9869 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
9870 pr " VALUE rv = rb_ary_new2 (len);\n";
9871 pr " for (i = 0; r[i] != NULL; ++i) {\n";
9872 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
9873 pr " free (r[i]);\n";
9877 | RStruct (_, typ) ->
9878 let cols = cols_of_struct typ in
9879 generate_ruby_struct_code typ cols
9880 | RStructList (_, typ) ->
9881 let cols = cols_of_struct typ in
9882 generate_ruby_struct_list_code typ cols
9884 pr " VALUE rv = rb_hash_new ();\n";
9886 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
9887 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
9888 pr " free (r[i]);\n";
9889 pr " free (r[i+1]);\n";
9894 pr " VALUE rv = rb_str_new (r, size);\n";
9904 /* Initialize the module. */
9905 void Init__guestfs ()
9907 m_guestfs = rb_define_module (\"Guestfs\");
9908 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
9909 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
9911 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
9912 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
9915 (* Define the rest of the methods. *)
9917 fun (name, style, _, _, _, _, _) ->
9918 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
9919 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
9924 (* Ruby code to return a struct. *)
9925 and generate_ruby_struct_code typ cols =
9926 pr " VALUE rv = rb_hash_new ();\n";
9930 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
9932 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
9934 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
9935 | name, (FBytes|FUInt64) ->
9936 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
9938 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
9940 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
9942 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
9943 | name, FOptPercent ->
9944 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
9945 | name, FChar -> (* XXX wrong? *)
9946 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
9948 pr " guestfs_free_%s (r);\n" typ;
9951 (* Ruby code to return a struct list. *)
9952 and generate_ruby_struct_list_code typ cols =
9953 pr " VALUE rv = rb_ary_new2 (r->len);\n";
9955 pr " for (i = 0; i < r->len; ++i) {\n";
9956 pr " VALUE hv = rb_hash_new ();\n";
9960 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
9962 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
9964 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
9965 | name, (FBytes|FUInt64) ->
9966 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
9968 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
9970 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
9972 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
9973 | name, FOptPercent ->
9974 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
9975 | name, FChar -> (* XXX wrong? *)
9976 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
9978 pr " rb_ary_push (rv, hv);\n";
9980 pr " guestfs_free_%s_list (r);\n" typ;
9983 (* Generate Java bindings GuestFS.java file. *)
9984 and generate_java_java () =
9985 generate_header CStyle LGPLv2plus;
9988 package com.redhat.et.libguestfs;
9990 import java.util.HashMap;
9991 import com.redhat.et.libguestfs.LibGuestFSException;
9992 import com.redhat.et.libguestfs.PV;
9993 import com.redhat.et.libguestfs.VG;
9994 import com.redhat.et.libguestfs.LV;
9995 import com.redhat.et.libguestfs.Stat;
9996 import com.redhat.et.libguestfs.StatVFS;
9997 import com.redhat.et.libguestfs.IntBool;
9998 import com.redhat.et.libguestfs.Dirent;
10001 * The GuestFS object is a libguestfs handle.
10005 public class GuestFS {
10006 // Load the native code.
10008 System.loadLibrary (\"guestfs_jni\");
10012 * The native guestfs_h pointer.
10017 * Create a libguestfs handle.
10019 * @throws LibGuestFSException
10021 public GuestFS () throws LibGuestFSException
10025 private native long _create () throws LibGuestFSException;
10028 * Close a libguestfs handle.
10030 * You can also leave handles to be collected by the garbage
10031 * collector, but this method ensures that the resources used
10032 * by the handle are freed up immediately. If you call any
10033 * other methods after closing the handle, you will get an
10036 * @throws LibGuestFSException
10038 public void close () throws LibGuestFSException
10044 private native void _close (long g) throws LibGuestFSException;
10046 public void finalize () throws LibGuestFSException
10054 fun (name, style, _, flags, _, shortdesc, longdesc) ->
10055 if not (List.mem NotInDocs flags); then (
10056 let doc = replace_str longdesc "C<guestfs_" "C<g." in
10058 if List.mem ProtocolLimitWarning flags then
10059 doc ^ "\n\n" ^ protocol_limit_warning
10062 if List.mem DangerWillRobinson flags then
10063 doc ^ "\n\n" ^ danger_will_robinson
10066 match deprecation_notice flags with
10068 | Some txt -> doc ^ "\n\n" ^ txt in
10069 let doc = pod2text ~width:60 name doc in
10070 let doc = List.map ( (* RHBZ#501883 *)
10073 | nonempty -> nonempty
10075 let doc = String.concat "\n * " doc in
10078 pr " * %s\n" shortdesc;
10081 pr " * @throws LibGuestFSException\n";
10085 generate_java_prototype ~public:true ~semicolon:false name style;
10088 pr " if (g == 0)\n";
10089 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
10092 if fst style <> RErr then pr "return ";
10094 generate_java_call_args ~handle:"g" (snd style);
10098 generate_java_prototype ~privat:true ~native:true name style;
10105 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
10106 and generate_java_call_args ~handle args =
10108 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
10111 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
10112 ?(semicolon=true) name style =
10113 if privat then pr "private ";
10114 if public then pr "public ";
10115 if native then pr "native ";
10118 (match fst style with
10119 | RErr -> pr "void ";
10120 | RInt _ -> pr "int ";
10121 | RInt64 _ -> pr "long ";
10122 | RBool _ -> pr "boolean ";
10123 | RConstString _ | RConstOptString _ | RString _
10124 | RBufferOut _ -> pr "String ";
10125 | RStringList _ -> pr "String[] ";
10126 | RStruct (_, typ) ->
10127 let name = java_name_of_struct typ in
10129 | RStructList (_, typ) ->
10130 let name = java_name_of_struct typ in
10132 | RHashtable _ -> pr "HashMap<String,String> ";
10135 if native then pr "_%s " name else pr "%s " name;
10137 let needs_comma = ref false in
10140 needs_comma := true
10146 if !needs_comma then pr ", ";
10147 needs_comma := true;
10151 | Device n | Dev_or_Path n
10159 | StringList n | DeviceList n ->
10170 pr " throws LibGuestFSException";
10171 if semicolon then pr ";"
10173 and generate_java_struct jtyp cols () =
10174 generate_header CStyle LGPLv2plus;
10177 package com.redhat.et.libguestfs;
10180 * Libguestfs %s structure.
10192 | name, FBuffer -> pr " public String %s;\n" name
10193 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
10194 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
10195 | name, FChar -> pr " public char %s;\n" name
10196 | name, FOptPercent ->
10197 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
10198 pr " public float %s;\n" name
10203 and generate_java_c () =
10204 generate_header CStyle LGPLv2plus;
10208 #include <stdlib.h>
10209 #include <string.h>
10211 #include \"com_redhat_et_libguestfs_GuestFS.h\"
10212 #include \"guestfs.h\"
10214 /* Note that this function returns. The exception is not thrown
10215 * until after the wrapper function returns.
10218 throw_exception (JNIEnv *env, const char *msg)
10221 cl = (*env)->FindClass (env,
10222 \"com/redhat/et/libguestfs/LibGuestFSException\");
10223 (*env)->ThrowNew (env, cl, msg);
10226 JNIEXPORT jlong JNICALL
10227 Java_com_redhat_et_libguestfs_GuestFS__1create
10228 (JNIEnv *env, jobject obj)
10232 g = guestfs_create ();
10234 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
10237 guestfs_set_error_handler (g, NULL, NULL);
10238 return (jlong) (long) g;
10241 JNIEXPORT void JNICALL
10242 Java_com_redhat_et_libguestfs_GuestFS__1close
10243 (JNIEnv *env, jobject obj, jlong jg)
10245 guestfs_h *g = (guestfs_h *) (long) jg;
10252 fun (name, style, _, _, _, _, _) ->
10254 (match fst style with
10255 | RErr -> pr "void ";
10256 | RInt _ -> pr "jint ";
10257 | RInt64 _ -> pr "jlong ";
10258 | RBool _ -> pr "jboolean ";
10259 | RConstString _ | RConstOptString _ | RString _
10260 | RBufferOut _ -> pr "jstring ";
10261 | RStruct _ | RHashtable _ ->
10263 | RStringList _ | RStructList _ ->
10264 pr "jobjectArray ";
10267 pr "Java_com_redhat_et_libguestfs_GuestFS_";
10268 pr "%s" (replace_str ("_" ^ name) "_" "_1");
10270 pr " (JNIEnv *env, jobject obj, jlong jg";
10274 | Device n | Dev_or_Path n
10279 pr ", jstring j%s" n
10281 pr ", jbyteArray j%s" n
10282 | StringList n | DeviceList n ->
10283 pr ", jobjectArray j%s" n
10285 pr ", jboolean j%s" n
10293 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
10294 let error_code, no_ret =
10295 match fst style with
10296 | RErr -> pr " int r;\n"; "-1", ""
10298 | RInt _ -> pr " int r;\n"; "-1", "0"
10299 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
10300 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
10301 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
10303 pr " jstring jr;\n";
10304 pr " char *r;\n"; "NULL", "NULL"
10306 pr " jobjectArray jr;\n";
10307 pr " int r_len;\n";
10308 pr " jclass cl;\n";
10309 pr " jstring jstr;\n";
10310 pr " char **r;\n"; "NULL", "NULL"
10311 | RStruct (_, typ) ->
10312 pr " jobject jr;\n";
10313 pr " jclass cl;\n";
10314 pr " jfieldID fl;\n";
10315 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
10316 | RStructList (_, typ) ->
10317 pr " jobjectArray jr;\n";
10318 pr " jclass cl;\n";
10319 pr " jfieldID fl;\n";
10320 pr " jobject jfl;\n";
10321 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
10322 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
10324 pr " jstring jr;\n";
10326 pr " size_t size;\n";
10331 | Device n | Dev_or_Path n
10336 pr " const char *%s;\n" n
10338 pr " jbyte *%s;\n" n;
10339 pr " size_t %s_size;\n" n
10340 | StringList n | DeviceList n ->
10341 pr " int %s_len;\n" n;
10342 pr " const char **%s;\n" n
10347 pr " int64_t %s;\n" n
10351 (match fst style with
10352 | RStringList _ | RStructList _ -> true
10353 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
10354 | RConstOptString _
10355 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
10356 List.exists (function
10357 | StringList _ -> true
10358 | DeviceList _ -> true
10359 | _ -> false) (snd style) in
10365 (* Get the parameters. *)
10369 | Device n | Dev_or_Path n
10373 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
10375 (* This is completely undocumented, but Java null becomes
10376 * a NULL parameter.
10378 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
10380 pr " %s = (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
10381 pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
10382 | StringList n | DeviceList n ->
10383 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
10384 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
10385 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10386 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10388 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
10390 pr " %s[%s_len] = NULL;\n" n n;
10394 pr " %s = j%s;\n" n n
10397 (* Make the call. *)
10398 pr " r = guestfs_%s " name;
10399 generate_c_call_args ~handle:"g" style;
10402 (* Release the parameters. *)
10406 | Device n | Dev_or_Path n
10410 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10412 pr " if (j%s)\n" n;
10413 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10415 pr " (*env)->ReleaseByteArrayElements (env, j%s, %s, 0);\n" n n
10416 | StringList n | DeviceList n ->
10417 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10418 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10420 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
10422 pr " free (%s);\n" n
10428 (* Check for errors. *)
10429 pr " if (r == %s) {\n" error_code;
10430 pr " throw_exception (env, guestfs_last_error (g));\n";
10431 pr " return %s;\n" no_ret;
10434 (* Return value. *)
10435 (match fst style with
10437 | RInt _ -> pr " return (jint) r;\n"
10438 | RBool _ -> pr " return (jboolean) r;\n"
10439 | RInt64 _ -> pr " return (jlong) r;\n"
10440 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
10441 | RConstOptString _ ->
10442 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
10444 pr " jr = (*env)->NewStringUTF (env, r);\n";
10448 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
10449 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
10450 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
10451 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
10452 pr " for (i = 0; i < r_len; ++i) {\n";
10453 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
10454 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
10455 pr " free (r[i]);\n";
10459 | RStruct (_, typ) ->
10460 let jtyp = java_name_of_struct typ in
10461 let cols = cols_of_struct typ in
10462 generate_java_struct_return typ jtyp cols
10463 | RStructList (_, typ) ->
10464 let jtyp = java_name_of_struct typ in
10465 let cols = cols_of_struct typ in
10466 generate_java_struct_list_return typ jtyp cols
10469 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
10470 pr " return NULL;\n"
10472 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
10481 and generate_java_struct_return typ jtyp cols =
10482 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10483 pr " jr = (*env)->AllocObject (env, cl);\n";
10487 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10488 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
10491 pr " char s[33];\n";
10492 pr " memcpy (s, r->%s, 32);\n" name;
10493 pr " s[32] = 0;\n";
10494 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10495 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10499 pr " int len = r->%s_len;\n" name;
10500 pr " char s[len+1];\n";
10501 pr " memcpy (s, r->%s, len);\n" name;
10502 pr " s[len] = 0;\n";
10503 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10504 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10506 | name, (FBytes|FUInt64|FInt64) ->
10507 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10508 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10509 | name, (FUInt32|FInt32) ->
10510 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10511 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10512 | name, FOptPercent ->
10513 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10514 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
10516 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10517 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10522 and generate_java_struct_list_return typ jtyp cols =
10523 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10524 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
10525 pr " for (i = 0; i < r->len; ++i) {\n";
10526 pr " jfl = (*env)->AllocObject (env, cl);\n";
10530 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10531 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
10534 pr " char s[33];\n";
10535 pr " memcpy (s, r->val[i].%s, 32);\n" name;
10536 pr " s[32] = 0;\n";
10537 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10538 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10542 pr " int len = r->val[i].%s_len;\n" name;
10543 pr " char s[len+1];\n";
10544 pr " memcpy (s, r->val[i].%s, len);\n" name;
10545 pr " s[len] = 0;\n";
10546 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10547 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10549 | name, (FBytes|FUInt64|FInt64) ->
10550 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10551 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10552 | name, (FUInt32|FInt32) ->
10553 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10554 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10555 | name, FOptPercent ->
10556 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10557 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
10559 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10560 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10562 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
10564 pr " guestfs_free_%s_list (r);\n" typ;
10567 and generate_java_makefile_inc () =
10568 generate_header HashStyle GPLv2plus;
10570 pr "java_built_sources = \\\n";
10573 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
10575 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
10577 and generate_haskell_hs () =
10578 generate_header HaskellStyle LGPLv2plus;
10580 (* XXX We only know how to generate partial FFI for Haskell
10581 * at the moment. Please help out!
10583 let can_generate style =
10587 | RInt64 _, _ -> true
10589 | RConstString _, _
10590 | RConstOptString _, _
10596 | RBufferOut _, _ -> false in
10599 {-# INCLUDE <guestfs.h> #-}
10600 {-# LANGUAGE ForeignFunctionInterface #-}
10605 (* List out the names of the actions we want to export. *)
10607 fun (name, style, _, _, _, _, _) ->
10608 if can_generate style then pr ",\n %s" name
10614 -- Unfortunately some symbols duplicate ones already present
10615 -- in Prelude. We don't know which, so we hard-code a list
10617 import Prelude hiding (truncate)
10621 import Foreign.C.Types
10623 import Control.Exception
10624 import Data.Typeable
10626 data GuestfsS = GuestfsS -- represents the opaque C struct
10627 type GuestfsP = Ptr GuestfsS -- guestfs_h *
10628 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
10630 -- XXX define properly later XXX
10634 data IntBool = IntBool
10636 data StatVFS = StatVFS
10637 data Hashtable = Hashtable
10639 foreign import ccall unsafe \"guestfs_create\" c_create
10641 foreign import ccall unsafe \"&guestfs_close\" c_close
10642 :: FunPtr (GuestfsP -> IO ())
10643 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
10644 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
10646 create :: IO GuestfsH
10649 c_set_error_handler p nullPtr nullPtr
10650 h <- newForeignPtr c_close p
10653 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
10654 :: GuestfsP -> IO CString
10656 -- last_error :: GuestfsH -> IO (Maybe String)
10657 -- last_error h = do
10658 -- str <- withForeignPtr h (\\p -> c_last_error p)
10659 -- maybePeek peekCString str
10661 last_error :: GuestfsH -> IO (String)
10663 str <- withForeignPtr h (\\p -> c_last_error p)
10664 if (str == nullPtr)
10665 then return \"no error\"
10666 else peekCString str
10670 (* Generate wrappers for each foreign function. *)
10672 fun (name, style, _, _, _, _, _) ->
10673 if can_generate style then (
10674 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
10676 generate_haskell_prototype ~handle:"GuestfsP" style;
10680 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
10682 pr "%s %s = do\n" name
10683 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
10685 (* Convert pointer arguments using with* functions. *)
10690 | Pathname n | Device n | Dev_or_Path n | String n ->
10691 pr "withCString %s $ \\%s -> " n n
10693 pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
10694 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
10695 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
10696 | Bool _ | Int _ | Int64 _ -> ()
10698 (* Convert integer arguments. *)
10702 | Bool n -> sprintf "(fromBool %s)" n
10703 | Int n -> sprintf "(fromIntegral %s)" n
10704 | Int64 n -> sprintf "(fromIntegral %s)" n
10705 | FileIn n | FileOut n
10706 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
10707 | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
10709 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
10710 (String.concat " " ("p" :: args));
10711 (match fst style with
10712 | RErr | RInt _ | RInt64 _ | RBool _ ->
10713 pr " if (r == -1)\n";
10715 pr " err <- last_error h\n";
10717 | RConstString _ | RConstOptString _ | RString _
10718 | RStringList _ | RStruct _
10719 | RStructList _ | RHashtable _ | RBufferOut _ ->
10720 pr " if (r == nullPtr)\n";
10722 pr " err <- last_error h\n";
10725 (match fst style with
10727 pr " else return ()\n"
10729 pr " else return (fromIntegral r)\n"
10731 pr " else return (fromIntegral r)\n"
10733 pr " else return (toBool r)\n"
10735 | RConstOptString _
10742 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
10748 and generate_haskell_prototype ~handle ?(hs = false) style =
10749 pr "%s -> " handle;
10750 let string = if hs then "String" else "CString" in
10751 let int = if hs then "Int" else "CInt" in
10752 let bool = if hs then "Bool" else "CInt" in
10753 let int64 = if hs then "Integer" else "Int64" in
10757 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
10759 if hs then pr "String"
10760 else pr "CString -> CInt"
10761 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
10762 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
10763 | Bool _ -> pr "%s" bool
10764 | Int _ -> pr "%s" int
10765 | Int64 _ -> pr "%s" int
10766 | FileIn _ -> pr "%s" string
10767 | FileOut _ -> pr "%s" string
10772 (match fst style with
10773 | RErr -> if not hs then pr "CInt"
10774 | RInt _ -> pr "%s" int
10775 | RInt64 _ -> pr "%s" int64
10776 | RBool _ -> pr "%s" bool
10777 | RConstString _ -> pr "%s" string
10778 | RConstOptString _ -> pr "Maybe %s" string
10779 | RString _ -> pr "%s" string
10780 | RStringList _ -> pr "[%s]" string
10781 | RStruct (_, typ) ->
10782 let name = java_name_of_struct typ in
10784 | RStructList (_, typ) ->
10785 let name = java_name_of_struct typ in
10787 | RHashtable _ -> pr "Hashtable"
10788 | RBufferOut _ -> pr "%s" string
10792 and generate_csharp () =
10793 generate_header CPlusPlusStyle LGPLv2plus;
10795 (* XXX Make this configurable by the C# assembly users. *)
10796 let library = "libguestfs.so.0" in
10799 // These C# bindings are highly experimental at present.
10801 // Firstly they only work on Linux (ie. Mono). In order to get them
10802 // to work on Windows (ie. .Net) you would need to port the library
10803 // itself to Windows first.
10805 // The second issue is that some calls are known to be incorrect and
10806 // can cause Mono to segfault. Particularly: calls which pass or
10807 // return string[], or return any structure value. This is because
10808 // we haven't worked out the correct way to do this from C#.
10810 // The third issue is that when compiling you get a lot of warnings.
10811 // We are not sure whether the warnings are important or not.
10813 // Fourthly we do not routinely build or test these bindings as part
10814 // of the make && make check cycle, which means that regressions might
10817 // Suggestions and patches are welcome.
10821 // gmcs Libguestfs.cs
10822 // mono Libguestfs.exe
10824 // (You'll probably want to add a Test class / static main function
10825 // otherwise this won't do anything useful).
10829 using System.Runtime.InteropServices;
10830 using System.Runtime.Serialization;
10831 using System.Collections;
10835 class Error : System.ApplicationException
10837 public Error (string message) : base (message) {}
10838 protected Error (SerializationInfo info, StreamingContext context) {}
10845 [DllImport (\"%s\")]
10846 static extern IntPtr guestfs_create ();
10850 _handle = guestfs_create ();
10851 if (_handle == IntPtr.Zero)
10852 throw new Error (\"could not create guestfs handle\");
10855 [DllImport (\"%s\")]
10856 static extern void guestfs_close (IntPtr h);
10860 guestfs_close (_handle);
10863 [DllImport (\"%s\")]
10864 static extern string guestfs_last_error (IntPtr h);
10866 " library library library;
10868 (* Generate C# structure bindings. We prefix struct names with
10869 * underscore because C# cannot have conflicting struct names and
10870 * method names (eg. "class stat" and "stat").
10874 pr " [StructLayout (LayoutKind.Sequential)]\n";
10875 pr " public class _%s {\n" typ;
10878 | name, FChar -> pr " char %s;\n" name
10879 | name, FString -> pr " string %s;\n" name
10881 pr " uint %s_len;\n" name;
10882 pr " string %s;\n" name
10884 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
10885 pr " string %s;\n" name
10886 | name, FUInt32 -> pr " uint %s;\n" name
10887 | name, FInt32 -> pr " int %s;\n" name
10888 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
10889 | name, FInt64 -> pr " long %s;\n" name
10890 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
10896 (* Generate C# function bindings. *)
10898 fun (name, style, _, _, _, shortdesc, _) ->
10899 let rec csharp_return_type () =
10900 match fst style with
10902 | RBool n -> "bool"
10904 | RInt64 n -> "long"
10906 | RConstOptString n
10908 | RBufferOut n -> "string"
10909 | RStruct (_,n) -> "_" ^ n
10910 | RHashtable n -> "Hashtable"
10911 | RStringList n -> "string[]"
10912 | RStructList (_,n) -> sprintf "_%s[]" n
10914 and c_return_type () =
10915 match fst style with
10919 | RInt64 _ -> "long"
10921 | RConstOptString _
10923 | RBufferOut _ -> "string"
10924 | RStruct (_,n) -> "_" ^ n
10926 | RStringList _ -> "string[]"
10927 | RStructList (_,n) -> sprintf "_%s[]" n
10929 and c_error_comparison () =
10930 match fst style with
10934 | RInt64 _ -> "== -1"
10936 | RConstOptString _
10942 | RStructList (_,_) -> "== null"
10944 and generate_extern_prototype () =
10945 pr " static extern %s guestfs_%s (IntPtr h"
10946 (c_return_type ()) name;
10949 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
10950 | FileIn n | FileOut n
10952 pr ", [In] string %s" n
10953 | StringList n | DeviceList n ->
10954 pr ", [In] string[] %s" n
10964 and generate_public_prototype () =
10965 pr " public %s %s (" (csharp_return_type ()) name;
10966 let comma = ref false in
10968 if !comma then pr ", ";
10973 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
10974 | FileIn n | FileOut n
10976 next (); pr "string %s" n
10977 | StringList n | DeviceList n ->
10978 next (); pr "string[] %s" n
10980 next (); pr "bool %s" n
10982 next (); pr "int %s" n
10984 next (); pr "long %s" n
10988 and generate_call () =
10989 pr "guestfs_%s (_handle" name;
10990 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
10994 pr " [DllImport (\"%s\")]\n" library;
10995 generate_extern_prototype ();
10997 pr " /// <summary>\n";
10998 pr " /// %s\n" shortdesc;
10999 pr " /// </summary>\n";
11000 generate_public_prototype ();
11002 pr " %s r;\n" (c_return_type ());
11005 pr " if (r %s)\n" (c_error_comparison ());
11006 pr " throw new Error (guestfs_last_error (_handle));\n";
11007 (match fst style with
11010 pr " return r != 0 ? true : false;\n"
11012 pr " Hashtable rr = new Hashtable ();\n";
11013 pr " for (int i = 0; i < r.Length; i += 2)\n";
11014 pr " rr.Add (r[i], r[i+1]);\n";
11016 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
11017 | RString _ | RBufferOut _ | RStruct _ | RStringList _
11023 ) all_functions_sorted;
11029 and generate_bindtests () =
11030 generate_header CStyle LGPLv2plus;
11034 #include <stdlib.h>
11035 #include <inttypes.h>
11036 #include <string.h>
11038 #include \"guestfs.h\"
11039 #include \"guestfs-internal.h\"
11040 #include \"guestfs-internal-actions.h\"
11041 #include \"guestfs_protocol.h\"
11043 #define error guestfs_error
11044 #define safe_calloc guestfs_safe_calloc
11045 #define safe_malloc guestfs_safe_malloc
11048 print_strings (char *const *argv)
11053 for (argc = 0; argv[argc] != NULL; ++argc) {
11054 if (argc > 0) printf (\", \");
11055 printf (\"\\\"%%s\\\"\", argv[argc]);
11060 /* The test0 function prints its parameters to stdout. */
11064 match test_functions with
11065 | [] -> assert false
11066 | test0 :: tests -> test0, tests in
11069 let (name, style, _, _, _, _, _) = test0 in
11070 generate_prototype ~extern:false ~semicolon:false ~newline:true
11071 ~handle:"g" ~prefix:"guestfs__" name style;
11076 | Device n | Dev_or_Path n
11079 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
11083 pr " for (i = 0; i < %s_size; ++i)\n" n;
11084 pr " printf (\"<%%02x>\", %s[i]);\n" n;
11085 pr " printf (\"\\n\");\n";
11087 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
11088 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
11089 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
11090 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
11091 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
11093 pr " /* Java changes stdout line buffering so we need this: */\n";
11094 pr " fflush (stdout);\n";
11100 fun (name, style, _, _, _, _, _) ->
11101 if String.sub name (String.length name - 3) 3 <> "err" then (
11102 pr "/* Test normal return. */\n";
11103 generate_prototype ~extern:false ~semicolon:false ~newline:true
11104 ~handle:"g" ~prefix:"guestfs__" name style;
11106 (match fst style with
11111 pr " sscanf (val, \"%%d\", &r);\n";
11114 pr " int64_t r;\n";
11115 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
11118 pr " return STREQ (val, \"true\");\n"
11120 | RConstOptString _ ->
11121 (* Can't return the input string here. Return a static
11122 * string so we ensure we get a segfault if the caller
11123 * tries to free it.
11125 pr " return \"static string\";\n"
11127 pr " return strdup (val);\n"
11129 pr " char **strs;\n";
11131 pr " sscanf (val, \"%%d\", &n);\n";
11132 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
11133 pr " for (i = 0; i < n; ++i) {\n";
11134 pr " strs[i] = safe_malloc (g, 16);\n";
11135 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
11137 pr " strs[n] = NULL;\n";
11138 pr " return strs;\n"
11139 | RStruct (_, typ) ->
11140 pr " struct guestfs_%s *r;\n" typ;
11141 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11143 | RStructList (_, typ) ->
11144 pr " struct guestfs_%s_list *r;\n" typ;
11145 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11146 pr " sscanf (val, \"%%d\", &r->len);\n";
11147 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
11150 pr " char **strs;\n";
11152 pr " sscanf (val, \"%%d\", &n);\n";
11153 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
11154 pr " for (i = 0; i < n; ++i) {\n";
11155 pr " strs[i*2] = safe_malloc (g, 16);\n";
11156 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
11157 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
11158 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
11160 pr " strs[n*2] = NULL;\n";
11161 pr " return strs;\n"
11163 pr " return strdup (val);\n"
11168 pr "/* Test error return. */\n";
11169 generate_prototype ~extern:false ~semicolon:false ~newline:true
11170 ~handle:"g" ~prefix:"guestfs__" name style;
11172 pr " error (g, \"error\");\n";
11173 (match fst style with
11174 | RErr | RInt _ | RInt64 _ | RBool _ ->
11176 | RConstString _ | RConstOptString _
11177 | RString _ | RStringList _ | RStruct _
11181 pr " return NULL;\n"
11188 and generate_ocaml_bindtests () =
11189 generate_header OCamlStyle GPLv2plus;
11193 let g = Guestfs.create () in
11197 String.concat " " (
11200 | CallString s -> "\"" ^ s ^ "\""
11201 | CallOptString None -> "None"
11202 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
11203 | CallStringList xs ->
11204 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
11205 | CallInt i when i >= 0 -> string_of_int i
11206 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
11207 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
11208 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
11209 | CallBool b -> string_of_bool b
11210 | CallBuffer s -> sprintf "%S" s
11215 generate_lang_bindtests (
11216 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
11219 pr "print_endline \"EOF\"\n"
11221 and generate_perl_bindtests () =
11222 pr "#!/usr/bin/perl -w\n";
11223 generate_header HashStyle GPLv2plus;
11230 my $g = Sys::Guestfs->new ();
11234 String.concat ", " (
11237 | CallString s -> "\"" ^ s ^ "\""
11238 | CallOptString None -> "undef"
11239 | CallOptString (Some s) -> sprintf "\"%s\"" s
11240 | CallStringList xs ->
11241 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11242 | CallInt i -> string_of_int i
11243 | CallInt64 i -> Int64.to_string i
11244 | CallBool b -> if b then "1" else "0"
11245 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11250 generate_lang_bindtests (
11251 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
11254 pr "print \"EOF\\n\"\n"
11256 and generate_python_bindtests () =
11257 generate_header HashStyle GPLv2plus;
11262 g = guestfs.GuestFS ()
11266 String.concat ", " (
11269 | CallString s -> "\"" ^ s ^ "\""
11270 | CallOptString None -> "None"
11271 | CallOptString (Some s) -> sprintf "\"%s\"" s
11272 | CallStringList xs ->
11273 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11274 | CallInt i -> string_of_int i
11275 | CallInt64 i -> Int64.to_string i
11276 | CallBool b -> if b then "1" else "0"
11277 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11282 generate_lang_bindtests (
11283 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
11286 pr "print \"EOF\"\n"
11288 and generate_ruby_bindtests () =
11289 generate_header HashStyle GPLv2plus;
11294 g = Guestfs::create()
11298 String.concat ", " (
11301 | CallString s -> "\"" ^ s ^ "\""
11302 | CallOptString None -> "nil"
11303 | CallOptString (Some s) -> sprintf "\"%s\"" s
11304 | CallStringList xs ->
11305 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11306 | CallInt i -> string_of_int i
11307 | CallInt64 i -> Int64.to_string i
11308 | CallBool b -> string_of_bool b
11309 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11314 generate_lang_bindtests (
11315 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
11318 pr "print \"EOF\\n\"\n"
11320 and generate_java_bindtests () =
11321 generate_header CStyle GPLv2plus;
11324 import com.redhat.et.libguestfs.*;
11326 public class Bindtests {
11327 public static void main (String[] argv)
11330 GuestFS g = new GuestFS ();
11334 String.concat ", " (
11337 | CallString s -> "\"" ^ s ^ "\""
11338 | CallOptString None -> "null"
11339 | CallOptString (Some s) -> sprintf "\"%s\"" s
11340 | CallStringList xs ->
11342 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
11343 | CallInt i -> string_of_int i
11344 | CallInt64 i -> Int64.to_string i
11345 | CallBool b -> string_of_bool b
11347 "new byte[] { " ^ String.concat "," (
11348 map_chars (fun c -> string_of_int (Char.code c)) s
11354 generate_lang_bindtests (
11355 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
11359 System.out.println (\"EOF\");
11361 catch (Exception exn) {
11362 System.err.println (exn);
11369 and generate_haskell_bindtests () =
11370 generate_header HaskellStyle GPLv2plus;
11373 module Bindtests where
11374 import qualified Guestfs
11377 g <- Guestfs.create
11381 String.concat " " (
11384 | CallString s -> "\"" ^ s ^ "\""
11385 | CallOptString None -> "Nothing"
11386 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
11387 | CallStringList xs ->
11388 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11389 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
11390 | CallInt i -> string_of_int i
11391 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
11392 | CallInt64 i -> Int64.to_string i
11393 | CallBool true -> "True"
11394 | CallBool false -> "False"
11395 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11400 generate_lang_bindtests (
11401 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
11404 pr " putStrLn \"EOF\"\n"
11406 (* Language-independent bindings tests - we do it this way to
11407 * ensure there is parity in testing bindings across all languages.
11409 and generate_lang_bindtests call =
11410 call "test0" [CallString "abc"; CallOptString (Some "def");
11411 CallStringList []; CallBool false;
11412 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11413 CallBuffer "abc\000abc"];
11414 call "test0" [CallString "abc"; CallOptString None;
11415 CallStringList []; CallBool false;
11416 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11417 CallBuffer "abc\000abc"];
11418 call "test0" [CallString ""; CallOptString (Some "def");
11419 CallStringList []; CallBool false;
11420 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11421 CallBuffer "abc\000abc"];
11422 call "test0" [CallString ""; CallOptString (Some "");
11423 CallStringList []; CallBool false;
11424 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11425 CallBuffer "abc\000abc"];
11426 call "test0" [CallString "abc"; CallOptString (Some "def");
11427 CallStringList ["1"]; CallBool false;
11428 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11429 CallBuffer "abc\000abc"];
11430 call "test0" [CallString "abc"; CallOptString (Some "def");
11431 CallStringList ["1"; "2"]; CallBool false;
11432 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11433 CallBuffer "abc\000abc"];
11434 call "test0" [CallString "abc"; CallOptString (Some "def");
11435 CallStringList ["1"]; CallBool true;
11436 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11437 CallBuffer "abc\000abc"];
11438 call "test0" [CallString "abc"; CallOptString (Some "def");
11439 CallStringList ["1"]; CallBool false;
11440 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456";
11441 CallBuffer "abc\000abc"];
11442 call "test0" [CallString "abc"; CallOptString (Some "def");
11443 CallStringList ["1"]; CallBool false;
11444 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456";
11445 CallBuffer "abc\000abc"];
11446 call "test0" [CallString "abc"; CallOptString (Some "def");
11447 CallStringList ["1"]; CallBool false;
11448 CallInt 1; CallInt64 1L; CallString "123"; CallString "456";
11449 CallBuffer "abc\000abc"];
11450 call "test0" [CallString "abc"; CallOptString (Some "def");
11451 CallStringList ["1"]; CallBool false;
11452 CallInt 2; CallInt64 2L; CallString "123"; CallString "456";
11453 CallBuffer "abc\000abc"];
11454 call "test0" [CallString "abc"; CallOptString (Some "def");
11455 CallStringList ["1"]; CallBool false;
11456 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456";
11457 CallBuffer "abc\000abc"];
11458 call "test0" [CallString "abc"; CallOptString (Some "def");
11459 CallStringList ["1"]; CallBool false;
11460 CallInt 0; CallInt64 0L; CallString ""; CallString "";
11461 CallBuffer "abc\000abc"]
11463 (* XXX Add here tests of the return and error functions. *)
11465 (* Code to generator bindings for virt-inspector. Currently only
11466 * implemented for OCaml code (for virt-p2v 2.0).
11468 let rng_input = "inspector/virt-inspector.rng"
11470 (* Read the input file and parse it into internal structures. This is
11471 * by no means a complete RELAX NG parser, but is just enough to be
11472 * able to parse the specific input file.
11475 | Element of string * rng list (* <element name=name/> *)
11476 | Attribute of string * rng list (* <attribute name=name/> *)
11477 | Interleave of rng list (* <interleave/> *)
11478 | ZeroOrMore of rng (* <zeroOrMore/> *)
11479 | OneOrMore of rng (* <oneOrMore/> *)
11480 | Optional of rng (* <optional/> *)
11481 | Choice of string list (* <choice><value/>*</choice> *)
11482 | Value of string (* <value>str</value> *)
11483 | Text (* <text/> *)
11485 let rec string_of_rng = function
11486 | Element (name, xs) ->
11487 "Element (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11488 | Attribute (name, xs) ->
11489 "Attribute (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11490 | Interleave xs -> "Interleave (" ^ string_of_rng_list xs ^ ")"
11491 | ZeroOrMore rng -> "ZeroOrMore (" ^ string_of_rng rng ^ ")"
11492 | OneOrMore rng -> "OneOrMore (" ^ string_of_rng rng ^ ")"
11493 | Optional rng -> "Optional (" ^ string_of_rng rng ^ ")"
11494 | Choice values -> "Choice [" ^ String.concat ", " values ^ "]"
11495 | Value value -> "Value \"" ^ value ^ "\""
11498 and string_of_rng_list xs =
11499 String.concat ", " (List.map string_of_rng xs)
11501 let rec parse_rng ?defines context = function
11503 | Xml.Element ("element", ["name", name], children) :: rest ->
11504 Element (name, parse_rng ?defines context children)
11505 :: parse_rng ?defines context rest
11506 | Xml.Element ("attribute", ["name", name], children) :: rest ->
11507 Attribute (name, parse_rng ?defines context children)
11508 :: parse_rng ?defines context rest
11509 | Xml.Element ("interleave", [], children) :: rest ->
11510 Interleave (parse_rng ?defines context children)
11511 :: parse_rng ?defines context rest
11512 | Xml.Element ("zeroOrMore", [], [child]) :: rest ->
11513 let rng = parse_rng ?defines context [child] in
11515 | [child] -> ZeroOrMore child :: parse_rng ?defines context rest
11517 failwithf "%s: <zeroOrMore> contains more than one child element"
11520 | Xml.Element ("oneOrMore", [], [child]) :: rest ->
11521 let rng = parse_rng ?defines context [child] in
11523 | [child] -> OneOrMore child :: parse_rng ?defines context rest
11525 failwithf "%s: <oneOrMore> contains more than one child element"
11528 | Xml.Element ("optional", [], [child]) :: rest ->
11529 let rng = parse_rng ?defines context [child] in
11531 | [child] -> Optional child :: parse_rng ?defines context rest
11533 failwithf "%s: <optional> contains more than one child element"
11536 | Xml.Element ("choice", [], children) :: rest ->
11537 let values = List.map (
11538 function Xml.Element ("value", [], [Xml.PCData value]) -> value
11540 failwithf "%s: can't handle anything except <value> in <choice>"
11544 :: parse_rng ?defines context rest
11545 | Xml.Element ("value", [], [Xml.PCData value]) :: rest ->
11546 Value value :: parse_rng ?defines context rest
11547 | Xml.Element ("text", [], []) :: rest ->
11548 Text :: parse_rng ?defines context rest
11549 | Xml.Element ("ref", ["name", name], []) :: rest ->
11550 (* Look up the reference. Because of limitations in this parser,
11551 * we can't handle arbitrarily nested <ref> yet. You can only
11552 * use <ref> from inside <start>.
11554 (match defines with
11556 failwithf "%s: contains <ref>, but no refs are defined yet" context
11558 let rng = StringMap.find name map in
11559 rng @ parse_rng ?defines context rest
11562 failwithf "%s: can't handle '%s' in schema" context (Xml.to_string x)
11565 let xml = Xml.parse_file rng_input in
11567 | Xml.Element ("grammar", _,
11568 Xml.Element ("start", _, gram) :: defines) ->
11569 (* The <define/> elements are referenced in the <start> section,
11570 * so build a map of those first.
11572 let defines = List.fold_left (
11574 function Xml.Element ("define", ["name", name], defn) ->
11575 StringMap.add name defn map
11577 failwithf "%s: expected <define name=name/>" rng_input
11578 ) StringMap.empty defines in
11579 let defines = StringMap.mapi parse_rng defines in
11581 (* Parse the <start> clause, passing the defines. *)
11582 parse_rng ~defines "<start>" gram
11584 failwithf "%s: input is not <grammar><start/><define>*</grammar>"
11587 let name_of_field = function
11588 | Element (name, _) | Attribute (name, _)
11589 | ZeroOrMore (Element (name, _))
11590 | OneOrMore (Element (name, _))
11591 | Optional (Element (name, _)) -> name
11592 | Optional (Attribute (name, _)) -> name
11593 | Text -> (* an unnamed field in an element *)
11596 failwithf "name_of_field failed at: %s" (string_of_rng rng)
11598 (* At the moment this function only generates OCaml types. However we
11599 * should parameterize it later so it can generate types/structs in a
11600 * variety of languages.
11602 let generate_types xs =
11603 (* A simple type is one that can be printed out directly, eg.
11604 * "string option". A complex type is one which has a name and has
11605 * to be defined via another toplevel definition, eg. a struct.
11607 * generate_type generates code for either simple or complex types.
11608 * In the simple case, it returns the string ("string option"). In
11609 * the complex case, it returns the name ("mountpoint"). In the
11610 * complex case it has to print out the definition before returning,
11611 * so it should only be called when we are at the beginning of a
11612 * new line (BOL context).
11614 let rec generate_type = function
11615 | Text -> (* string *)
11617 | Choice values -> (* [`val1|`val2|...] *)
11618 "[" ^ String.concat "|" (List.map ((^)"`") values) ^ "]", true
11619 | ZeroOrMore rng -> (* <rng> list *)
11620 let t, is_simple = generate_type rng in
11621 t ^ " list (* 0 or more *)", is_simple
11622 | OneOrMore rng -> (* <rng> list *)
11623 let t, is_simple = generate_type rng in
11624 t ^ " list (* 1 or more *)", is_simple
11625 (* virt-inspector hack: bool *)
11626 | Optional (Attribute (name, [Value "1"])) ->
11628 | Optional rng -> (* <rng> list *)
11629 let t, is_simple = generate_type rng in
11630 t ^ " option", is_simple
11631 (* type name = { fields ... } *)
11632 | Element (name, fields) when is_attrs_interleave fields ->
11633 generate_type_struct name (get_attrs_interleave fields)
11634 | Element (name, [field]) (* type name = field *)
11635 | Attribute (name, [field]) ->
11636 let t, is_simple = generate_type field in
11637 if is_simple then (t, true)
11639 pr "type %s = %s\n" name t;
11642 | Element (name, fields) -> (* type name = { fields ... } *)
11643 generate_type_struct name fields
11645 failwithf "generate_type failed at: %s" (string_of_rng rng)
11647 and is_attrs_interleave = function
11648 | [Interleave _] -> true
11649 | Attribute _ :: fields -> is_attrs_interleave fields
11650 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11653 and get_attrs_interleave = function
11654 | [Interleave fields] -> fields
11655 | ((Attribute _) as field) :: fields
11656 | ((Optional (Attribute _)) as field) :: fields ->
11657 field :: get_attrs_interleave fields
11658 | _ -> assert false
11660 and generate_types xs =
11661 List.iter (fun x -> ignore (generate_type x)) xs
11663 and generate_type_struct name fields =
11664 (* Calculate the types of the fields first. We have to do this
11665 * before printing anything so we are still in BOL context.
11667 let types = List.map fst (List.map generate_type fields) in
11669 (* Special case of a struct containing just a string and another
11670 * field. Turn it into an assoc list.
11673 | ["string"; other] ->
11674 let fname1, fname2 =
11676 | [f1; f2] -> name_of_field f1, name_of_field f2
11677 | _ -> assert false in
11678 pr "type %s = string * %s (* %s -> %s *)\n" name other fname1 fname2;
11682 pr "type %s = {\n" name;
11684 fun (field, ftype) ->
11685 let fname = name_of_field field in
11686 pr " %s_%s : %s;\n" name fname ftype
11687 ) (List.combine fields types);
11689 (* Return the name of this type, and
11690 * false because it's not a simple type.
11697 let generate_parsers xs =
11698 (* As for generate_type above, generate_parser makes a parser for
11699 * some type, and returns the name of the parser it has generated.
11700 * Because it (may) need to print something, it should always be
11701 * called in BOL context.
11703 let rec generate_parser = function
11704 | Text -> (* string *)
11705 "string_child_or_empty"
11706 | Choice values -> (* [`val1|`val2|...] *)
11707 sprintf "(fun x -> match Xml.pcdata (first_child x) with %s | str -> failwith (\"unexpected field value: \" ^ str))"
11709 (List.map (fun v -> sprintf "%S -> `%s" v v) values))
11710 | ZeroOrMore rng -> (* <rng> list *)
11711 let pa = generate_parser rng in
11712 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11713 | OneOrMore rng -> (* <rng> list *)
11714 let pa = generate_parser rng in
11715 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11716 (* virt-inspector hack: bool *)
11717 | Optional (Attribute (name, [Value "1"])) ->
11718 sprintf "(fun x -> try ignore (Xml.attrib x %S); true with Xml.No_attribute _ -> false)" name
11719 | Optional rng -> (* <rng> list *)
11720 let pa = generate_parser rng in
11721 sprintf "(function None -> None | Some x -> Some (%s x))" pa
11722 (* type name = { fields ... } *)
11723 | Element (name, fields) when is_attrs_interleave fields ->
11724 generate_parser_struct name (get_attrs_interleave fields)
11725 | Element (name, [field]) -> (* type name = field *)
11726 let pa = generate_parser field in
11727 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11728 pr "let %s =\n" parser_name;
11730 pr "let parse_%s = %s\n" name parser_name;
11732 | Attribute (name, [field]) ->
11733 let pa = generate_parser field in
11734 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11735 pr "let %s =\n" parser_name;
11737 pr "let parse_%s = %s\n" name parser_name;
11739 | Element (name, fields) -> (* type name = { fields ... } *)
11740 generate_parser_struct name ([], fields)
11742 failwithf "generate_parser failed at: %s" (string_of_rng rng)
11744 and is_attrs_interleave = function
11745 | [Interleave _] -> true
11746 | Attribute _ :: fields -> is_attrs_interleave fields
11747 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11750 and get_attrs_interleave = function
11751 | [Interleave fields] -> [], fields
11752 | ((Attribute _) as field) :: fields
11753 | ((Optional (Attribute _)) as field) :: fields ->
11754 let attrs, interleaves = get_attrs_interleave fields in
11755 (field :: attrs), interleaves
11756 | _ -> assert false
11758 and generate_parsers xs =
11759 List.iter (fun x -> ignore (generate_parser x)) xs
11761 and generate_parser_struct name (attrs, interleaves) =
11762 (* Generate parsers for the fields first. We have to do this
11763 * before printing anything so we are still in BOL context.
11765 let fields = attrs @ interleaves in
11766 let pas = List.map generate_parser fields in
11768 (* Generate an intermediate tuple from all the fields first.
11769 * If the type is just a string + another field, then we will
11770 * return this directly, otherwise it is turned into a record.
11772 * RELAX NG note: This code treats <interleave> and plain lists of
11773 * fields the same. In other words, it doesn't bother enforcing
11774 * any ordering of fields in the XML.
11776 pr "let parse_%s x =\n" name;
11777 pr " let t = (\n ";
11778 let comma = ref false in
11781 if !comma then pr ",\n ";
11784 | Optional (Attribute (fname, [field])), pa ->
11786 | Optional (Element (fname, [field])), pa ->
11787 pr "%s (optional_child %S x)" pa fname
11788 | Attribute (fname, [Text]), _ ->
11789 pr "attribute %S x" fname
11790 | (ZeroOrMore _ | OneOrMore _), pa ->
11795 let fname = name_of_field field in
11796 pr "%s (child %S x)" pa fname
11797 ) (List.combine fields pas);
11801 | [Element (_, [Text]) | Attribute (_, [Text]); _] ->
11805 pr " (Obj.magic t : %s)\n" name
11809 | (Optional (Attribute (fname, [field])), pa) ->
11810 pr " %s_%s =\n" name fname;
11812 | (Optional (Element (fname, [field])), pa) ->
11813 pr " %s_%s =\n" name fname;
11814 pr " (let x = optional_child %S x in\n" fname;
11817 let fname = name_of_field field in
11818 pr " %s_%s =\n" name fname;
11819 pr " (let x = child %S x in\n" fname;
11821 ) (List.combine fields pas);
11825 sprintf "parse_%s" name
11828 generate_parsers xs
11830 (* Generate ocaml/guestfs_inspector.mli. *)
11831 let generate_ocaml_inspector_mli () =
11832 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11835 (** This is an OCaml language binding to the external [virt-inspector]
11838 For more information, please read the man page [virt-inspector(1)].
11843 generate_types grammar;
11844 pr "(** The nested information returned from the {!inspect} function. *)\n";
11848 val inspect : ?connect:string -> ?xml:string -> string list -> operatingsystems
11849 (** To inspect a libvirt domain called [name], pass a singleton
11850 list: [inspect [name]]. When using libvirt only, you may
11851 optionally pass a libvirt URI using [inspect ~connect:uri ...].
11853 To inspect a disk image or images, pass a list of the filenames
11854 of the disk images: [inspect filenames]
11856 This function inspects the given guest or disk images and
11857 returns a list of operating system(s) found and a large amount
11858 of information about them. In the vast majority of cases,
11859 a virtual machine only contains a single operating system.
11861 If the optional [~xml] parameter is given, then this function
11862 skips running the external virt-inspector program and just
11863 parses the given XML directly (which is expected to be XML
11864 produced from a previous run of virt-inspector). The list of
11865 names and connect URI are ignored in this case.
11867 This function can throw a wide variety of exceptions, for example
11868 if the external virt-inspector program cannot be found, or if
11869 it doesn't generate valid XML.
11873 (* Generate ocaml/guestfs_inspector.ml. *)
11874 let generate_ocaml_inspector_ml () =
11875 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11880 generate_types grammar;
11884 (* Misc functions which are used by the parser code below. *)
11885 let first_child = function
11886 | Xml.Element (_, _, c::_) -> c
11887 | Xml.Element (name, _, []) ->
11888 failwith (\"expected <\" ^ name ^ \"/> to have a child node\")
11889 | Xml.PCData str ->
11890 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11892 let string_child_or_empty = function
11893 | Xml.Element (_, _, [Xml.PCData s]) -> s
11894 | Xml.Element (_, _, []) -> \"\"
11895 | Xml.Element (x, _, _) ->
11896 failwith (\"expected XML tag with a single PCDATA child, but got \" ^
11898 | Xml.PCData str ->
11899 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11901 let optional_child name xml =
11902 let children = Xml.children xml in
11904 Some (List.find (function
11905 | Xml.Element (n, _, _) when n = name -> true
11906 | _ -> false) children)
11910 let child name xml =
11911 match optional_child name xml with
11914 failwith (\"mandatory field <\" ^ name ^ \"/> missing in XML output\")
11916 let attribute name xml =
11917 try Xml.attrib xml name
11918 with Xml.No_attribute _ ->
11919 failwith (\"mandatory attribute \" ^ name ^ \" missing in XML output\")
11923 generate_parsers grammar;
11927 (* Run external virt-inspector, then use parser to parse the XML. *)
11928 let inspect ?connect ?xml names =
11932 if names = [] then invalid_arg \"inspect: no names given\";
11933 let cmd = [ \"virt-inspector\"; \"--xml\" ] @
11934 (match connect with None -> [] | Some uri -> [ \"--connect\"; uri ]) @
11936 let cmd = List.map Filename.quote cmd in
11937 let cmd = String.concat \" \" cmd in
11938 let chan = open_process_in cmd in
11939 let xml = Xml.parse_in chan in
11940 (match close_process_in chan with
11942 | WEXITED _ -> failwith \"external virt-inspector command failed\"
11943 | WSIGNALED i | WSTOPPED i ->
11944 failwith (\"external virt-inspector command died or stopped on sig \" ^
11949 Xml.parse_string doc in
11950 parse_operatingsystems xml
11953 and generate_max_proc_nr () =
11954 pr "%d\n" max_proc_nr
11956 let output_to filename k =
11957 let filename_new = filename ^ ".new" in
11958 chan := open_out filename_new;
11961 chan := Pervasives.stdout;
11963 (* Is the new file different from the current file? *)
11964 if Sys.file_exists filename && files_equal filename filename_new then
11965 unlink filename_new (* same, so skip it *)
11967 (* different, overwrite old one *)
11968 (try chmod filename 0o644 with Unix_error _ -> ());
11969 rename filename_new filename;
11970 chmod filename 0o444;
11971 printf "written %s\n%!" filename;
11974 let perror msg = function
11975 | Unix_error (err, _, _) ->
11976 eprintf "%s: %s\n" msg (error_message err)
11978 eprintf "%s: %s\n" msg (Printexc.to_string exn)
11980 (* Main program. *)
11983 try openfile "HACKING" [O_RDWR] 0
11985 | Unix_error (ENOENT, _, _) ->
11987 You are probably running this from the wrong directory.
11988 Run it from the top source directory using the command
11993 perror "open: HACKING" exn;
11996 (* Acquire a lock so parallel builds won't try to run the generator
11997 * twice at the same time. Subsequent builds will wait for the first
11998 * one to finish. Note the lock is released implicitly when the
12001 (try lockf lock_fd F_LOCK 1
12003 perror "lock: HACKING" exn;
12006 check_functions ();
12008 output_to "src/guestfs_protocol.x" generate_xdr;
12009 output_to "src/guestfs-structs.h" generate_structs_h;
12010 output_to "src/guestfs-actions.h" generate_actions_h;
12011 output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
12012 output_to "src/guestfs-actions.c" generate_client_actions;
12013 output_to "src/guestfs-bindtests.c" generate_bindtests;
12014 output_to "src/guestfs-structs.pod" generate_structs_pod;
12015 output_to "src/guestfs-actions.pod" generate_actions_pod;
12016 output_to "src/guestfs-availability.pod" generate_availability_pod;
12017 output_to "src/MAX_PROC_NR" generate_max_proc_nr;
12018 output_to "src/libguestfs.syms" generate_linker_script;
12019 output_to "daemon/actions.h" generate_daemon_actions_h;
12020 output_to "daemon/stubs.c" generate_daemon_actions;
12021 output_to "daemon/names.c" generate_daemon_names;
12022 output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
12023 output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
12024 output_to "capitests/tests.c" generate_tests;
12025 output_to "fish/cmds.c" generate_fish_cmds;
12026 output_to "fish/completion.c" generate_fish_completion;
12027 output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
12028 output_to "ocaml/guestfs.mli" generate_ocaml_mli;
12029 output_to "ocaml/guestfs.ml" generate_ocaml_ml;
12030 output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;
12031 output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
12032 output_to "ocaml/guestfs_inspector.mli" generate_ocaml_inspector_mli;
12033 output_to "ocaml/guestfs_inspector.ml" generate_ocaml_inspector_ml;
12034 output_to "perl/Guestfs.xs" generate_perl_xs;
12035 output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
12036 output_to "perl/bindtests.pl" generate_perl_bindtests;
12037 output_to "python/guestfs-py.c" generate_python_c;
12038 output_to "python/guestfs.py" generate_python_py;
12039 output_to "python/bindtests.py" generate_python_bindtests;
12040 output_to "ruby/ext/guestfs/_guestfs.c" generate_ruby_c;
12041 output_to "ruby/bindtests.rb" generate_ruby_bindtests;
12042 output_to "java/com/redhat/et/libguestfs/GuestFS.java" generate_java_java;
12046 let cols = cols_of_struct typ in
12047 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
12048 output_to filename (generate_java_struct jtyp cols);
12051 output_to "java/Makefile.inc" generate_java_makefile_inc;
12052 output_to "java/com_redhat_et_libguestfs_GuestFS.c" generate_java_c;
12053 output_to "java/Bindtests.java" generate_java_bindtests;
12054 output_to "haskell/Guestfs.hs" generate_haskell_hs;
12055 output_to "haskell/Bindtests.hs" generate_haskell_bindtests;
12056 output_to "csharp/Libguestfs.cs" generate_csharp;
12058 (* Always generate this file last, and unconditionally. It's used
12059 * by the Makefile to know when we must re-run the generator.
12061 let chan = open_out "src/stamp-generator" in
12062 fprintf chan "1\n";
12065 printf "generated %d lines of code\n" !lines