3 * Copyright (C) 2009-2010 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (* This script generates a large amount of code and documentation for
21 * all the daemon actions.
23 * To add a new action there are only two files you need to change,
24 * this one to describe the interface (see the big table of
25 * 'daemon_functions' below), and daemon/<somefile>.c to write the
28 * After editing this file, run it (./src/generator.ml) to regenerate
29 * all the output files. 'make' will rerun this automatically when
30 * necessary. Note that if you are using a separate build directory
31 * you must run generator.ml from the _source_ directory.
33 * IMPORTANT: This script should NOT print any warnings. If it prints
34 * warnings, you should treat them as errors.
37 * (1) In emacs, install tuareg-mode to display and format OCaml code
38 * correctly. 'vim' comes with a good OCaml editing mode by default.
39 * (2) Read the resources at http://ocaml-tutorial.org/
44 #directory "+xml-light";;
45 #directory "+../pkg-lib/xml-light";; (* for GODI users *)
46 #load "xml-light.cma";;
51 type style = ret * args
53 (* "RErr" as a return value means an int used as a simple error
54 * indication, ie. 0 or -1.
58 (* "RInt" as a return value means an int which is -1 for error
59 * or any value >= 0 on success. Only use this for smallish
60 * positive ints (0 <= i < 2^30).
64 (* "RInt64" is the same as RInt, but is guaranteed to be able
65 * to return a full 64 bit value, _except_ that -1 means error
66 * (so -1 cannot be a valid, non-error return value).
70 (* "RBool" is a bool return value which can be true/false or
75 (* "RConstString" is a string that refers to a constant value.
76 * The return value must NOT be NULL (since NULL indicates
79 * Try to avoid using this. In particular you cannot use this
80 * for values returned from the daemon, because there is no
81 * thread-safe way to return them in the C API.
83 | RConstString of string
85 (* "RConstOptString" is an even more broken version of
86 * "RConstString". The returned string may be NULL and there
87 * is no way to return an error indication. Avoid using this!
89 | RConstOptString of string
91 (* "RString" is a returned string. It must NOT be NULL, since
92 * a NULL return indicates an error. The caller frees this.
96 (* "RStringList" is a list of strings. No string in the list
97 * can be NULL. The caller frees the strings and the array.
99 | RStringList of string
101 (* "RStruct" is a function which returns a single named structure
102 * or an error indication (in C, a struct, and in other languages
103 * with varying representations, but usually very efficient). See
104 * after the function list below for the structures.
106 | RStruct of string * string (* name of retval, name of struct *)
108 (* "RStructList" is a function which returns either a list/array
109 * of structures (could be zero-length), or an error indication.
111 | RStructList of string * string (* name of retval, name of struct *)
113 (* Key-value pairs of untyped strings. Turns into a hashtable or
114 * dictionary in languages which support it. DON'T use this as a
115 * general "bucket" for results. Prefer a stronger typed return
116 * value if one is available, or write a custom struct. Don't use
117 * this if the list could potentially be very long, since it is
118 * inefficient. Keys should be unique. NULLs are not permitted.
120 | RHashtable of string
122 (* "RBufferOut" is handled almost exactly like RString, but
123 * it allows the string to contain arbitrary 8 bit data including
124 * ASCII NUL. In the C API this causes an implicit extra parameter
125 * to be added of type <size_t *size_r>. The extra parameter
126 * returns the actual size of the return buffer in bytes.
128 * Other programming languages support strings with arbitrary 8 bit
131 * At the RPC layer we have to use the opaque<> type instead of
132 * string<>. Returned data is still limited to the max message
135 | RBufferOut of string
137 and args = argt list (* Function parameters, guestfs handle is implicit. *)
139 (* Note in future we should allow a "variable args" parameter as
140 * the final parameter, to allow commands like
141 * chmod mode file [file(s)...]
142 * This is not implemented yet, but many commands (such as chmod)
143 * are currently defined with the argument order keeping this future
144 * possibility in mind.
147 | String of string (* const char *name, cannot be NULL *)
148 | Device of string (* /dev device name, cannot be NULL *)
149 | Pathname of string (* file name, cannot be NULL *)
150 | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *)
151 | OptString of string (* const char *name, may be NULL *)
152 | StringList of string(* list of strings (each string cannot be NULL) *)
153 | DeviceList of string(* list of Device names (each cannot be NULL) *)
154 | Bool of string (* boolean *)
155 | Int of string (* int (smallish ints, signed, <= 31 bits) *)
156 | Int64 of string (* any 64 bit int *)
157 (* These are treated as filenames (simple string parameters) in
158 * the C API and bindings. But in the RPC protocol, we transfer
159 * the actual file content up to or down from the daemon.
160 * FileIn: local machine -> daemon (in request)
161 * FileOut: daemon -> local machine (in reply)
162 * In guestfish (only), the special name "-" means read from
163 * stdin or write to stdout.
167 (* Opaque buffer which can contain arbitrary 8 bit data.
168 * In the C API, this is expressed as <const char *, size_t> pair.
169 * Most other languages have a string type which can contain
170 * ASCII NUL. We use whatever type is appropriate for each
172 * Buffers are limited by the total message size. To transfer
173 * large blocks of data, use FileIn/FileOut parameters instead.
174 * To return an arbitrary buffer, use RBufferOut.
179 | ProtocolLimitWarning (* display warning about protocol size limits *)
180 | DangerWillRobinson (* flags particularly dangerous commands *)
181 | FishAlias of string (* provide an alias for this cmd in guestfish *)
182 | FishOutput of fish_output_t (* how to display output in guestfish *)
183 | NotInFish (* do not export via guestfish *)
184 | NotInDocs (* do not add this function to documentation *)
185 | DeprecatedBy of string (* function is deprecated, use .. instead *)
186 | Optional of string (* function is part of an optional group *)
189 | FishOutputOctal (* for int return, print in octal *)
190 | FishOutputHexadecimal (* for int return, print in hex *)
192 (* You can supply zero or as many tests as you want per API call.
194 * Note that the test environment has 3 block devices, of size 500MB,
195 * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
196 * a fourth ISO block device with some known files on it (/dev/sdd).
198 * Note for partitioning purposes, the 500MB device has 1015 cylinders.
199 * Number of cylinders was 63 for IDE emulated disks with precisely
200 * the same size. How exactly this is calculated is a mystery.
202 * The ISO block device (/dev/sdd) comes from images/test.iso.
204 * To be able to run the tests in a reasonable amount of time,
205 * the virtual machine and block devices are reused between tests.
206 * So don't try testing kill_subprocess :-x
208 * Between each test we blockdev-setrw, umount-all, lvm-remove-all.
210 * Don't assume anything about the previous contents of the block
211 * devices. Use 'Init*' to create some initial scenarios.
213 * You can add a prerequisite clause to any individual test. This
214 * is a run-time check, which, if it fails, causes the test to be
215 * skipped. Useful if testing a command which might not work on
216 * all variations of libguestfs builds. A test that has prerequisite
217 * of 'Always' is run unconditionally.
219 * In addition, packagers can skip individual tests by setting the
220 * environment variables: eg:
221 * SKIP_TEST_<CMD>_<NUM>=1 SKIP_TEST_COMMAND_3=1 (skips test #3 of command)
222 * SKIP_TEST_<CMD>=1 SKIP_TEST_ZEROFREE=1 (skips all zerofree tests)
224 type tests = (test_init * test_prereq * test) list
226 (* Run the command sequence and just expect nothing to fail. *)
229 (* Run the command sequence and expect the output of the final
230 * command to be the string.
232 | TestOutput of seq * string
234 (* Run the command sequence and expect the output of the final
235 * command to be the list of strings.
237 | TestOutputList of seq * string list
239 (* Run the command sequence and expect the output of the final
240 * command to be the list of block devices (could be either
241 * "/dev/sd.." or "/dev/hd.." form - we don't check the 5th
242 * character of each string).
244 | TestOutputListOfDevices of seq * string list
246 (* Run the command sequence and expect the output of the final
247 * command to be the integer.
249 | TestOutputInt of seq * int
251 (* Run the command sequence and expect the output of the final
252 * command to be <op> <int>, eg. ">=", "1".
254 | TestOutputIntOp of seq * string * int
256 (* Run the command sequence and expect the output of the final
257 * command to be a true value (!= 0 or != NULL).
259 | TestOutputTrue of seq
261 (* Run the command sequence and expect the output of the final
262 * command to be a false value (== 0 or == NULL, but not an error).
264 | TestOutputFalse of seq
266 (* Run the command sequence and expect the output of the final
267 * command to be a list of the given length (but don't care about
270 | TestOutputLength of seq * int
272 (* Run the command sequence and expect the output of the final
273 * command to be a buffer (RBufferOut), ie. string + size.
275 | TestOutputBuffer of seq * string
277 (* Run the command sequence and expect the output of the final
278 * command to be a structure.
280 | TestOutputStruct of seq * test_field_compare list
282 (* Run the command sequence and expect the final command (only)
285 | TestLastFail of seq
287 and test_field_compare =
288 | CompareWithInt of string * int
289 | CompareWithIntOp of string * string * int
290 | CompareWithString of string * string
291 | CompareFieldsIntEq of string * string
292 | CompareFieldsStrEq of string * string
294 (* Test prerequisites. *)
296 (* Test always runs. *)
299 (* Test is currently disabled - eg. it fails, or it tests some
300 * unimplemented feature.
304 (* 'string' is some C code (a function body) that should return
305 * true or false. The test will run if the code returns true.
309 (* As for 'If' but the test runs _unless_ the code returns true. *)
312 (* Run the test only if 'string' is available in the daemon. *)
313 | IfAvailable of string
315 (* Some initial scenarios for testing. *)
317 (* Do nothing, block devices could contain random stuff including
318 * LVM PVs, and some filesystems might be mounted. This is usually
323 (* Block devices are empty and no filesystems are mounted. *)
326 (* /dev/sda contains a single partition /dev/sda1, with random
327 * content. /dev/sdb and /dev/sdc may have random content.
332 (* /dev/sda contains a single partition /dev/sda1, which is formatted
333 * as ext2, empty [except for lost+found] and mounted on /.
334 * /dev/sdb and /dev/sdc may have random content.
340 * /dev/sda1 (is a PV):
341 * /dev/VG/LV (size 8MB):
342 * formatted as ext2, empty [except for lost+found], mounted on /
343 * /dev/sdb and /dev/sdc may have random content.
347 (* /dev/sdd (the ISO, see images/ directory in source)
352 (* Sequence of commands for testing. *)
354 and cmd = string list
356 (* Note about long descriptions: When referring to another
357 * action, use the format C<guestfs_other> (ie. the full name of
358 * the C function). This will be replaced as appropriate in other
361 * Apart from that, long descriptions are just perldoc paragraphs.
364 (* Generate a random UUID (used in tests). *)
366 let chan = open_process_in "uuidgen" in
367 let uuid = input_line chan in
368 (match close_process_in chan with
371 failwith "uuidgen: process exited with non-zero status"
372 | WSIGNALED _ | WSTOPPED _ ->
373 failwith "uuidgen: process signalled or stopped by signal"
377 (* These test functions are used in the language binding tests. *)
379 let test_all_args = [
382 StringList "strlist";
391 let test_all_rets = [
392 (* except for RErr, which is tested thoroughly elsewhere *)
393 "test0rint", RInt "valout";
394 "test0rint64", RInt64 "valout";
395 "test0rbool", RBool "valout";
396 "test0rconststring", RConstString "valout";
397 "test0rconstoptstring", RConstOptString "valout";
398 "test0rstring", RString "valout";
399 "test0rstringlist", RStringList "valout";
400 "test0rstruct", RStruct ("valout", "lvm_pv");
401 "test0rstructlist", RStructList ("valout", "lvm_pv");
402 "test0rhashtable", RHashtable "valout";
405 let test_functions = [
406 ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
408 "internal test function - do not use",
410 This is an internal test function which is used to test whether
411 the automatically generated bindings can handle every possible
412 parameter type correctly.
414 It echos the contents of each parameter to stdout.
416 You probably don't want to call this function.");
420 [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
422 "internal test function - do not use",
424 This is an internal test function which is used to test whether
425 the automatically generated bindings can handle every possible
426 return type correctly.
428 It converts string C<val> to the return type.
430 You probably don't want to call this function.");
431 (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
433 "internal test function - do not use",
435 This is an internal test function which is used to test whether
436 the automatically generated bindings can handle every possible
437 return type correctly.
439 This function always returns an error.
441 You probably don't want to call this function.")]
445 (* non_daemon_functions are any functions which don't get processed
446 * in the daemon, eg. functions for setting and getting local
447 * configuration values.
450 let non_daemon_functions = test_functions @ [
451 ("launch", (RErr, []), -1, [FishAlias "run"],
453 "launch the qemu subprocess",
455 Internally libguestfs is implemented by running a virtual machine
458 You should call this after configuring the handle
459 (eg. adding drives) but before performing any actions.");
461 ("wait_ready", (RErr, []), -1, [NotInFish],
463 "wait until the qemu subprocess launches (no op)",
465 This function is a no op.
467 In versions of the API E<lt> 1.0.71 you had to call this function
468 just after calling C<guestfs_launch> to wait for the launch
469 to complete. However this is no longer necessary because
470 C<guestfs_launch> now does the waiting.
472 If you see any calls to this function in code then you can just
473 remove them, unless you want to retain compatibility with older
474 versions of the API.");
476 ("kill_subprocess", (RErr, []), -1, [],
478 "kill the qemu subprocess",
480 This kills the qemu subprocess. You should never need to call this.");
482 ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
484 "add an image to examine or modify",
486 This function adds a virtual machine disk image C<filename> to the
487 guest. The first time you call this function, the disk appears as IDE
488 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
491 You don't necessarily need to be root when using libguestfs. However
492 you obviously do need sufficient permissions to access the filename
493 for whatever operations you want to perform (ie. read access if you
494 just want to read the image or write access if you want to modify the
497 This is equivalent to the qemu parameter
498 C<-drive file=filename,cache=off,if=...>.
500 C<cache=off> is omitted in cases where it is not supported by
501 the underlying filesystem.
503 C<if=...> is set at compile time by the configuration option
504 C<./configure --with-drive-if=...>. In the rare case where you
505 might need to change this at run time, use C<guestfs_add_drive_with_if>
506 or C<guestfs_add_drive_ro_with_if>.
508 Note that this call checks for the existence of C<filename>. This
509 stops you from specifying other types of drive which are supported
510 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
511 the general C<guestfs_config> call instead.");
513 ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
515 "add a CD-ROM disk image to examine",
517 This function adds a virtual CD-ROM disk image to the guest.
519 This is equivalent to the qemu parameter C<-cdrom filename>.
527 This call checks for the existence of C<filename>. This
528 stops you from specifying other types of drive which are supported
529 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
530 the general C<guestfs_config> call instead.
534 If you just want to add an ISO file (often you use this as an
535 efficient way to transfer large files into the guest), then you
536 should probably use C<guestfs_add_drive_ro> instead.
540 ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
542 "add a drive in snapshot mode (read-only)",
544 This adds a drive in snapshot mode, making it effectively
547 Note that writes to the device are allowed, and will be seen for
548 the duration of the guestfs handle, but they are written
549 to a temporary file which is discarded as soon as the guestfs
550 handle is closed. We don't currently have any method to enable
551 changes to be committed, although qemu can support this.
553 This is equivalent to the qemu parameter
554 C<-drive file=filename,snapshot=on,readonly=on,if=...>.
556 C<if=...> is set at compile time by the configuration option
557 C<./configure --with-drive-if=...>. In the rare case where you
558 might need to change this at run time, use C<guestfs_add_drive_with_if>
559 or C<guestfs_add_drive_ro_with_if>.
561 C<readonly=on> is only added where qemu supports this option.
563 Note that this call checks for the existence of C<filename>. This
564 stops you from specifying other types of drive which are supported
565 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
566 the general C<guestfs_config> call instead.");
568 ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
570 "add qemu parameters",
572 This can be used to add arbitrary qemu command line parameters
573 of the form C<-param value>. Actually it's not quite arbitrary - we
574 prevent you from setting some parameters which would interfere with
575 parameters that we use.
577 The first character of C<param> string must be a C<-> (dash).
579 C<value> can be NULL.");
581 ("set_qemu", (RErr, [OptString "qemu"]), -1, [FishAlias "qemu"],
583 "set the qemu binary",
585 Set the qemu binary that we will use.
587 The default is chosen when the library was compiled by the
590 You can also override this by setting the C<LIBGUESTFS_QEMU>
591 environment variable.
593 Setting C<qemu> to C<NULL> restores the default qemu binary.
595 Note that you should call this function as early as possible
596 after creating the handle. This is because some pre-launch
597 operations depend on testing qemu features (by running C<qemu -help>).
598 If the qemu binary changes, we don't retest features, and
599 so you might see inconsistent results. Using the environment
600 variable C<LIBGUESTFS_QEMU> is safest of all since that picks
601 the qemu binary at the same time as the handle is created.");
603 ("get_qemu", (RConstString "qemu", []), -1, [],
604 [InitNone, Always, TestRun (
606 "get the qemu binary",
608 Return the current qemu binary.
610 This is always non-NULL. If it wasn't set already, then this will
611 return the default qemu binary name.");
613 ("set_path", (RErr, [OptString "searchpath"]), -1, [FishAlias "path"],
615 "set the search path",
617 Set the path that libguestfs searches for kernel and initrd.img.
619 The default is C<$libdir/guestfs> unless overridden by setting
620 C<LIBGUESTFS_PATH> environment variable.
622 Setting C<path> to C<NULL> restores the default path.");
624 ("get_path", (RConstString "path", []), -1, [],
625 [InitNone, Always, TestRun (
627 "get the search path",
629 Return the current search path.
631 This is always non-NULL. If it wasn't set already, then this will
632 return the default path.");
634 ("set_append", (RErr, [OptString "append"]), -1, [FishAlias "append"],
636 "add options to kernel command line",
638 This function is used to add additional options to the
639 guest kernel command line.
641 The default is C<NULL> unless overridden by setting
642 C<LIBGUESTFS_APPEND> environment variable.
644 Setting C<append> to C<NULL> means I<no> additional options
645 are passed (libguestfs always adds a few of its own).");
647 ("get_append", (RConstOptString "append", []), -1, [],
648 (* This cannot be tested with the current framework. The
649 * function can return NULL in normal operations, which the
650 * test framework interprets as an error.
653 "get the additional kernel options",
655 Return the additional kernel options which are added to the
656 guest kernel command line.
658 If C<NULL> then no options are added.");
660 ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
664 If C<autosync> is true, this enables autosync. Libguestfs will make a
665 best effort attempt to run C<guestfs_umount_all> followed by
666 C<guestfs_sync> when the handle is closed
667 (also if the program exits without closing handles).
669 This is disabled by default (except in guestfish where it is
670 enabled by default).");
672 ("get_autosync", (RBool "autosync", []), -1, [],
673 [InitNone, Always, TestRun (
674 [["get_autosync"]])],
677 Get the autosync flag.");
679 ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
683 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
685 Verbose messages are disabled unless the environment variable
686 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
688 ("get_verbose", (RBool "verbose", []), -1, [],
692 This returns the verbose messages flag.");
694 ("is_ready", (RBool "ready", []), -1, [],
695 [InitNone, Always, TestOutputTrue (
697 "is ready to accept commands",
699 This returns true iff this handle is ready to accept commands
700 (in the C<READY> state).
702 For more information on states, see L<guestfs(3)>.");
704 ("is_config", (RBool "config", []), -1, [],
705 [InitNone, Always, TestOutputFalse (
707 "is in configuration state",
709 This returns true iff this handle is being configured
710 (in the C<CONFIG> state).
712 For more information on states, see L<guestfs(3)>.");
714 ("is_launching", (RBool "launching", []), -1, [],
715 [InitNone, Always, TestOutputFalse (
716 [["is_launching"]])],
717 "is launching subprocess",
719 This returns true iff this handle is launching the subprocess
720 (in the C<LAUNCHING> state).
722 For more information on states, see L<guestfs(3)>.");
724 ("is_busy", (RBool "busy", []), -1, [],
725 [InitNone, Always, TestOutputFalse (
727 "is busy processing a command",
729 This returns true iff this handle is busy processing a command
730 (in the C<BUSY> state).
732 For more information on states, see L<guestfs(3)>.");
734 ("get_state", (RInt "state", []), -1, [],
736 "get the current state",
738 This returns the current state as an opaque integer. This is
739 only useful for printing debug and internal error messages.
741 For more information on states, see L<guestfs(3)>.");
743 ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
744 [InitNone, Always, TestOutputInt (
745 [["set_memsize"; "500"];
746 ["get_memsize"]], 500)],
747 "set memory allocated to the qemu subprocess",
749 This sets the memory size in megabytes allocated to the
750 qemu subprocess. This only has any effect if called before
753 You can also change this by setting the environment
754 variable C<LIBGUESTFS_MEMSIZE> before the handle is
757 For more information on the architecture of libguestfs,
758 see L<guestfs(3)>.");
760 ("get_memsize", (RInt "memsize", []), -1, [],
761 [InitNone, Always, TestOutputIntOp (
762 [["get_memsize"]], ">=", 256)],
763 "get memory allocated to the qemu subprocess",
765 This gets the memory size in megabytes allocated to the
768 If C<guestfs_set_memsize> was not called
769 on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
770 then this returns the compiled-in default value for memsize.
772 For more information on the architecture of libguestfs,
773 see L<guestfs(3)>.");
775 ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"],
776 [InitNone, Always, TestOutputIntOp (
777 [["get_pid"]], ">=", 1)],
778 "get PID of qemu subprocess",
780 Return the process ID of the qemu subprocess. If there is no
781 qemu subprocess, then this will return an error.
783 This is an internal call used for debugging and testing.");
785 ("version", (RStruct ("version", "version"), []), -1, [],
786 [InitNone, Always, TestOutputStruct (
787 [["version"]], [CompareWithInt ("major", 1)])],
788 "get the library version number",
790 Return the libguestfs version number that the program is linked
793 Note that because of dynamic linking this is not necessarily
794 the version of libguestfs that you compiled against. You can
795 compile the program, and then at runtime dynamically link
796 against a completely different C<libguestfs.so> library.
798 This call was added in version C<1.0.58>. In previous
799 versions of libguestfs there was no way to get the version
800 number. From C code you can use dynamic linker functions
801 to find out if this symbol exists (if it doesn't, then
802 it's an earlier version).
804 The call returns a structure with four elements. The first
805 three (C<major>, C<minor> and C<release>) are numbers and
806 correspond to the usual version triplet. The fourth element
807 (C<extra>) is a string and is normally empty, but may be
808 used for distro-specific information.
810 To construct the original version string:
811 C<$major.$minor.$release$extra>
813 See also: L<guestfs(3)/LIBGUESTFS VERSION NUMBERS>.
815 I<Note:> Don't use this call to test for availability
816 of features. In enterprise distributions we backport
817 features from later versions into earlier versions,
818 making this an unreliable way to test for features.
819 Use C<guestfs_available> instead.");
821 ("set_selinux", (RErr, [Bool "selinux"]), -1, [FishAlias "selinux"],
822 [InitNone, Always, TestOutputTrue (
823 [["set_selinux"; "true"];
825 "set SELinux enabled or disabled at appliance boot",
827 This sets the selinux flag that is passed to the appliance
828 at boot time. The default is C<selinux=0> (disabled).
830 Note that if SELinux is enabled, it is always in
831 Permissive mode (C<enforcing=0>).
833 For more information on the architecture of libguestfs,
834 see L<guestfs(3)>.");
836 ("get_selinux", (RBool "selinux", []), -1, [],
838 "get SELinux enabled flag",
840 This returns the current setting of the selinux flag which
841 is passed to the appliance at boot time. See C<guestfs_set_selinux>.
843 For more information on the architecture of libguestfs,
844 see L<guestfs(3)>.");
846 ("set_trace", (RErr, [Bool "trace"]), -1, [FishAlias "trace"],
847 [InitNone, Always, TestOutputFalse (
848 [["set_trace"; "false"];
850 "enable or disable command traces",
852 If the command trace flag is set to 1, then commands are
853 printed on stdout before they are executed in a format
854 which is very similar to the one used by guestfish. In
855 other words, you can run a program with this enabled, and
856 you will get out a script which you can feed to guestfish
857 to perform the same set of actions.
859 If you want to trace C API calls into libguestfs (and
860 other libraries) then possibly a better way is to use
861 the external ltrace(1) command.
863 Command traces are disabled unless the environment variable
864 C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
866 ("get_trace", (RBool "trace", []), -1, [],
868 "get command trace enabled flag",
870 Return the command trace flag.");
872 ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"],
873 [InitNone, Always, TestOutputFalse (
874 [["set_direct"; "false"];
876 "enable or disable direct appliance mode",
878 If the direct appliance mode flag is enabled, then stdin and
879 stdout are passed directly through to the appliance once it
882 One consequence of this is that log messages aren't caught
883 by the library and handled by C<guestfs_set_log_message_callback>,
884 but go straight to stdout.
886 You probably don't want to use this unless you know what you
889 The default is disabled.");
891 ("get_direct", (RBool "direct", []), -1, [],
893 "get direct appliance mode flag",
895 Return the direct appliance mode flag.");
897 ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"],
898 [InitNone, Always, TestOutputTrue (
899 [["set_recovery_proc"; "true"];
900 ["get_recovery_proc"]])],
901 "enable or disable the recovery process",
903 If this is called with the parameter C<false> then
904 C<guestfs_launch> does not create a recovery process. The
905 purpose of the recovery process is to stop runaway qemu
906 processes in the case where the main program aborts abruptly.
908 This only has any effect if called before C<guestfs_launch>,
909 and the default is true.
911 About the only time when you would want to disable this is
912 if the main process will fork itself into the background
913 (\"daemonize\" itself). In this case the recovery process
914 thinks that the main program has disappeared and so kills
915 qemu, which is not very helpful.");
917 ("get_recovery_proc", (RBool "recoveryproc", []), -1, [],
919 "get recovery process enabled flag",
921 Return the recovery process enabled flag.");
923 ("add_drive_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
925 "add a drive specifying the QEMU block emulation to use",
927 This is the same as C<guestfs_add_drive> but it allows you
928 to specify the QEMU interface emulation to use at run time.");
930 ("add_drive_ro_with_if", (RErr, [String "filename"; String "iface"]), -1, [],
932 "add a drive read-only specifying the QEMU block emulation to use",
934 This is the same as C<guestfs_add_drive_ro> but it allows you
935 to specify the QEMU interface emulation to use at run time.");
939 (* daemon_functions are any functions which cause some action
940 * to take place in the daemon.
943 let daemon_functions = [
944 ("mount", (RErr, [Device "device"; String "mountpoint"]), 1, [],
945 [InitEmpty, Always, TestOutput (
946 [["part_disk"; "/dev/sda"; "mbr"];
947 ["mkfs"; "ext2"; "/dev/sda1"];
948 ["mount"; "/dev/sda1"; "/"];
949 ["write"; "/new"; "new file contents"];
950 ["cat"; "/new"]], "new file contents")],
951 "mount a guest disk at a position in the filesystem",
953 Mount a guest disk at a position in the filesystem. Block devices
954 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
955 the guest. If those block devices contain partitions, they will have
956 the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style
959 The rules are the same as for L<mount(2)>: A filesystem must
960 first be mounted on C</> before others can be mounted. Other
961 filesystems can only be mounted on directories which already
964 The mounted filesystem is writable, if we have sufficient permissions
965 on the underlying device.
968 When you use this call, the filesystem options C<sync> and C<noatime>
969 are set implicitly. This was originally done because we thought it
970 would improve reliability, but it turns out that I<-o sync> has a
971 very large negative performance impact and negligible effect on
972 reliability. Therefore we recommend that you avoid using
973 C<guestfs_mount> in any code that needs performance, and instead
974 use C<guestfs_mount_options> (use an empty string for the first
975 parameter if you don't want any options).");
977 ("sync", (RErr, []), 2, [],
978 [ InitEmpty, Always, TestRun [["sync"]]],
979 "sync disks, writes are flushed through to the disk image",
981 This syncs the disk, so that any writes are flushed through to the
982 underlying disk image.
984 You should always call this if you have modified a disk image, before
985 closing the handle.");
987 ("touch", (RErr, [Pathname "path"]), 3, [],
988 [InitBasicFS, Always, TestOutputTrue (
990 ["exists"; "/new"]])],
991 "update file timestamps or create a new file",
993 Touch acts like the L<touch(1)> command. It can be used to
994 update the timestamps on a file, or, if the file does not exist,
995 to create a new zero-length file.");
997 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
998 [InitISOFS, Always, TestOutput (
999 [["cat"; "/known-2"]], "abcdef\n")],
1000 "list the contents of a file",
1002 Return the contents of the file named C<path>.
1004 Note that this function cannot correctly handle binary files
1005 (specifically, files containing C<\\0> character which is treated
1006 as end of string). For those you need to use the C<guestfs_read_file>
1007 or C<guestfs_download> functions which have a more complex interface.");
1009 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
1010 [], (* XXX Tricky to test because it depends on the exact format
1011 * of the 'ls -l' command, which changes between F10 and F11.
1013 "list the files in a directory (long format)",
1015 List the files in C<directory> (relative to the root directory,
1016 there is no cwd) in the format of 'ls -la'.
1018 This command is mostly useful for interactive sessions. It
1019 is I<not> intended that you try to parse the output string.");
1021 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
1022 [InitBasicFS, Always, TestOutputList (
1024 ["touch"; "/newer"];
1025 ["touch"; "/newest"];
1026 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
1027 "list the files in a directory",
1029 List the files in C<directory> (relative to the root directory,
1030 there is no cwd). The '.' and '..' entries are not returned, but
1031 hidden files are shown.
1033 This command is mostly useful for interactive sessions. Programs
1034 should probably use C<guestfs_readdir> instead.");
1036 ("list_devices", (RStringList "devices", []), 7, [],
1037 [InitEmpty, Always, TestOutputListOfDevices (
1038 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
1039 "list the block devices",
1041 List all the block devices.
1043 The full block device names are returned, eg. C</dev/sda>");
1045 ("list_partitions", (RStringList "partitions", []), 8, [],
1046 [InitBasicFS, Always, TestOutputListOfDevices (
1047 [["list_partitions"]], ["/dev/sda1"]);
1048 InitEmpty, Always, TestOutputListOfDevices (
1049 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1050 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1051 "list the partitions",
1053 List all the partitions detected on all block devices.
1055 The full partition device names are returned, eg. C</dev/sda1>
1057 This does not return logical volumes. For that you will need to
1058 call C<guestfs_lvs>.");
1060 ("pvs", (RStringList "physvols", []), 9, [Optional "lvm2"],
1061 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
1062 [["pvs"]], ["/dev/sda1"]);
1063 InitEmpty, Always, TestOutputListOfDevices (
1064 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1065 ["pvcreate"; "/dev/sda1"];
1066 ["pvcreate"; "/dev/sda2"];
1067 ["pvcreate"; "/dev/sda3"];
1068 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1069 "list the LVM physical volumes (PVs)",
1071 List all the physical volumes detected. This is the equivalent
1072 of the L<pvs(8)> command.
1074 This returns a list of just the device names that contain
1075 PVs (eg. C</dev/sda2>).
1077 See also C<guestfs_pvs_full>.");
1079 ("vgs", (RStringList "volgroups", []), 10, [Optional "lvm2"],
1080 [InitBasicFSonLVM, Always, TestOutputList (
1082 InitEmpty, Always, TestOutputList (
1083 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1084 ["pvcreate"; "/dev/sda1"];
1085 ["pvcreate"; "/dev/sda2"];
1086 ["pvcreate"; "/dev/sda3"];
1087 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1088 ["vgcreate"; "VG2"; "/dev/sda3"];
1089 ["vgs"]], ["VG1"; "VG2"])],
1090 "list the LVM volume groups (VGs)",
1092 List all the volumes groups detected. This is the equivalent
1093 of the L<vgs(8)> command.
1095 This returns a list of just the volume group names that were
1096 detected (eg. C<VolGroup00>).
1098 See also C<guestfs_vgs_full>.");
1100 ("lvs", (RStringList "logvols", []), 11, [Optional "lvm2"],
1101 [InitBasicFSonLVM, Always, TestOutputList (
1102 [["lvs"]], ["/dev/VG/LV"]);
1103 InitEmpty, Always, TestOutputList (
1104 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1105 ["pvcreate"; "/dev/sda1"];
1106 ["pvcreate"; "/dev/sda2"];
1107 ["pvcreate"; "/dev/sda3"];
1108 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1109 ["vgcreate"; "VG2"; "/dev/sda3"];
1110 ["lvcreate"; "LV1"; "VG1"; "50"];
1111 ["lvcreate"; "LV2"; "VG1"; "50"];
1112 ["lvcreate"; "LV3"; "VG2"; "50"];
1113 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1114 "list the LVM logical volumes (LVs)",
1116 List all the logical volumes detected. This is the equivalent
1117 of the L<lvs(8)> command.
1119 This returns a list of the logical volume device names
1120 (eg. C</dev/VolGroup00/LogVol00>).
1122 See also C<guestfs_lvs_full>.");
1124 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [Optional "lvm2"],
1125 [], (* XXX how to test? *)
1126 "list the LVM physical volumes (PVs)",
1128 List all the physical volumes detected. This is the equivalent
1129 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1131 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [Optional "lvm2"],
1132 [], (* XXX how to test? *)
1133 "list the LVM volume groups (VGs)",
1135 List all the volumes groups detected. This is the equivalent
1136 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1138 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [Optional "lvm2"],
1139 [], (* XXX how to test? *)
1140 "list the LVM logical volumes (LVs)",
1142 List all the logical volumes detected. This is the equivalent
1143 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1145 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1146 [InitISOFS, Always, TestOutputList (
1147 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1148 InitISOFS, Always, TestOutputList (
1149 [["read_lines"; "/empty"]], [])],
1150 "read file as lines",
1152 Return the contents of the file named C<path>.
1154 The file contents are returned as a list of lines. Trailing
1155 C<LF> and C<CRLF> character sequences are I<not> returned.
1157 Note that this function cannot correctly handle binary files
1158 (specifically, files containing C<\\0> character which is treated
1159 as end of line). For those you need to use the C<guestfs_read_file>
1160 function which has a more complex interface.");
1162 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [Optional "augeas"],
1163 [], (* XXX Augeas code needs tests. *)
1164 "create a new Augeas handle",
1166 Create a new Augeas handle for editing configuration files.
1167 If there was any previous Augeas handle associated with this
1168 guestfs session, then it is closed.
1170 You must call this before using any other C<guestfs_aug_*>
1173 C<root> is the filesystem root. C<root> must not be NULL,
1176 The flags are the same as the flags defined in
1177 E<lt>augeas.hE<gt>, the logical I<or> of the following
1182 =item C<AUG_SAVE_BACKUP> = 1
1184 Keep the original file with a C<.augsave> extension.
1186 =item C<AUG_SAVE_NEWFILE> = 2
1188 Save changes into a file with extension C<.augnew>, and
1189 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1191 =item C<AUG_TYPE_CHECK> = 4
1193 Typecheck lenses (can be expensive).
1195 =item C<AUG_NO_STDINC> = 8
1197 Do not use standard load path for modules.
1199 =item C<AUG_SAVE_NOOP> = 16
1201 Make save a no-op, just record what would have been changed.
1203 =item C<AUG_NO_LOAD> = 32
1205 Do not load the tree in C<guestfs_aug_init>.
1209 To close the handle, you can call C<guestfs_aug_close>.
1211 To find out more about Augeas, see L<http://augeas.net/>.");
1213 ("aug_close", (RErr, []), 26, [Optional "augeas"],
1214 [], (* XXX Augeas code needs tests. *)
1215 "close the current Augeas handle",
1217 Close the current Augeas handle and free up any resources
1218 used by it. After calling this, you have to call
1219 C<guestfs_aug_init> again before you can use any other
1220 Augeas functions.");
1222 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [Optional "augeas"],
1223 [], (* XXX Augeas code needs tests. *)
1224 "define an Augeas variable",
1226 Defines an Augeas variable C<name> whose value is the result
1227 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1230 On success this returns the number of nodes in C<expr>, or
1231 C<0> if C<expr> evaluates to something which is not a nodeset.");
1233 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [Optional "augeas"],
1234 [], (* XXX Augeas code needs tests. *)
1235 "define an Augeas node",
1237 Defines a variable C<name> whose value is the result of
1240 If C<expr> evaluates to an empty nodeset, a node is created,
1241 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1242 C<name> will be the nodeset containing that single node.
1244 On success this returns a pair containing the
1245 number of nodes in the nodeset, and a boolean flag
1246 if a node was created.");
1248 ("aug_get", (RString "val", [String "augpath"]), 19, [Optional "augeas"],
1249 [], (* XXX Augeas code needs tests. *)
1250 "look up the value of an Augeas path",
1252 Look up the value associated with C<path>. If C<path>
1253 matches exactly one node, the C<value> is returned.");
1255 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [Optional "augeas"],
1256 [], (* XXX Augeas code needs tests. *)
1257 "set Augeas path to value",
1259 Set the value associated with C<path> to C<val>.
1261 In the Augeas API, it is possible to clear a node by setting
1262 the value to NULL. Due to an oversight in the libguestfs API
1263 you cannot do that with this call. Instead you must use the
1264 C<guestfs_aug_clear> call.");
1266 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [Optional "augeas"],
1267 [], (* XXX Augeas code needs tests. *)
1268 "insert a sibling Augeas node",
1270 Create a new sibling C<label> for C<path>, inserting it into
1271 the tree before or after C<path> (depending on the boolean
1274 C<path> must match exactly one existing node in the tree, and
1275 C<label> must be a label, ie. not contain C</>, C<*> or end
1276 with a bracketed index C<[N]>.");
1278 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [Optional "augeas"],
1279 [], (* XXX Augeas code needs tests. *)
1280 "remove an Augeas path",
1282 Remove C<path> and all of its children.
1284 On success this returns the number of entries which were removed.");
1286 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [Optional "augeas"],
1287 [], (* XXX Augeas code needs tests. *)
1290 Move the node C<src> to C<dest>. C<src> must match exactly
1291 one node. C<dest> is overwritten if it exists.");
1293 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [Optional "augeas"],
1294 [], (* XXX Augeas code needs tests. *)
1295 "return Augeas nodes which match augpath",
1297 Returns a list of paths which match the path expression C<path>.
1298 The returned paths are sufficiently qualified so that they match
1299 exactly one node in the current tree.");
1301 ("aug_save", (RErr, []), 25, [Optional "augeas"],
1302 [], (* XXX Augeas code needs tests. *)
1303 "write all pending Augeas changes to disk",
1305 This writes all pending changes to disk.
1307 The flags which were passed to C<guestfs_aug_init> affect exactly
1308 how files are saved.");
1310 ("aug_load", (RErr, []), 27, [Optional "augeas"],
1311 [], (* XXX Augeas code needs tests. *)
1312 "load files into the tree",
1314 Load files into the tree.
1316 See C<aug_load> in the Augeas documentation for the full gory
1319 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [Optional "augeas"],
1320 [], (* XXX Augeas code needs tests. *)
1321 "list Augeas nodes under augpath",
1323 This is just a shortcut for listing C<guestfs_aug_match>
1324 C<path/*> and sorting the resulting nodes into alphabetical order.");
1326 ("rm", (RErr, [Pathname "path"]), 29, [],
1327 [InitBasicFS, Always, TestRun
1330 InitBasicFS, Always, TestLastFail
1332 InitBasicFS, Always, TestLastFail
1337 Remove the single file C<path>.");
1339 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1340 [InitBasicFS, Always, TestRun
1343 InitBasicFS, Always, TestLastFail
1344 [["rmdir"; "/new"]];
1345 InitBasicFS, Always, TestLastFail
1347 ["rmdir"; "/new"]]],
1348 "remove a directory",
1350 Remove the single directory C<path>.");
1352 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1353 [InitBasicFS, Always, TestOutputFalse
1355 ["mkdir"; "/new/foo"];
1356 ["touch"; "/new/foo/bar"];
1358 ["exists"; "/new"]]],
1359 "remove a file or directory recursively",
1361 Remove the file or directory C<path>, recursively removing the
1362 contents if its a directory. This is like the C<rm -rf> shell
1365 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1366 [InitBasicFS, Always, TestOutputTrue
1368 ["is_dir"; "/new"]];
1369 InitBasicFS, Always, TestLastFail
1370 [["mkdir"; "/new/foo/bar"]]],
1371 "create a directory",
1373 Create a directory named C<path>.");
1375 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1376 [InitBasicFS, Always, TestOutputTrue
1377 [["mkdir_p"; "/new/foo/bar"];
1378 ["is_dir"; "/new/foo/bar"]];
1379 InitBasicFS, Always, TestOutputTrue
1380 [["mkdir_p"; "/new/foo/bar"];
1381 ["is_dir"; "/new/foo"]];
1382 InitBasicFS, Always, TestOutputTrue
1383 [["mkdir_p"; "/new/foo/bar"];
1384 ["is_dir"; "/new"]];
1385 (* Regression tests for RHBZ#503133: *)
1386 InitBasicFS, Always, TestRun
1388 ["mkdir_p"; "/new"]];
1389 InitBasicFS, Always, TestLastFail
1391 ["mkdir_p"; "/new"]]],
1392 "create a directory and parents",
1394 Create a directory named C<path>, creating any parent directories
1395 as necessary. This is like the C<mkdir -p> shell command.");
1397 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1398 [], (* XXX Need stat command to test *)
1401 Change the mode (permissions) of C<path> to C<mode>. Only
1402 numeric modes are supported.
1404 I<Note>: When using this command from guestfish, C<mode>
1405 by default would be decimal, unless you prefix it with
1406 C<0> to get octal, ie. use C<0700> not C<700>.
1408 The mode actually set is affected by the umask.");
1410 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1411 [], (* XXX Need stat command to test *)
1412 "change file owner and group",
1414 Change the file owner to C<owner> and group to C<group>.
1416 Only numeric uid and gid are supported. If you want to use
1417 names, you will need to locate and parse the password file
1418 yourself (Augeas support makes this relatively easy).");
1420 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1421 [InitISOFS, Always, TestOutputTrue (
1422 [["exists"; "/empty"]]);
1423 InitISOFS, Always, TestOutputTrue (
1424 [["exists"; "/directory"]])],
1425 "test if file or directory exists",
1427 This returns C<true> if and only if there is a file, directory
1428 (or anything) with the given C<path> name.
1430 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1432 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1433 [InitISOFS, Always, TestOutputTrue (
1434 [["is_file"; "/known-1"]]);
1435 InitISOFS, Always, TestOutputFalse (
1436 [["is_file"; "/directory"]])],
1437 "test if file exists",
1439 This returns C<true> if and only if there is a file
1440 with the given C<path> name. Note that it returns false for
1441 other objects like directories.
1443 See also C<guestfs_stat>.");
1445 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1446 [InitISOFS, Always, TestOutputFalse (
1447 [["is_dir"; "/known-3"]]);
1448 InitISOFS, Always, TestOutputTrue (
1449 [["is_dir"; "/directory"]])],
1450 "test if file exists",
1452 This returns C<true> if and only if there is a directory
1453 with the given C<path> name. Note that it returns false for
1454 other objects like files.
1456 See also C<guestfs_stat>.");
1458 ("pvcreate", (RErr, [Device "device"]), 39, [Optional "lvm2"],
1459 [InitEmpty, Always, TestOutputListOfDevices (
1460 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1461 ["pvcreate"; "/dev/sda1"];
1462 ["pvcreate"; "/dev/sda2"];
1463 ["pvcreate"; "/dev/sda3"];
1464 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1465 "create an LVM physical volume",
1467 This creates an LVM physical volume on the named C<device>,
1468 where C<device> should usually be a partition name such
1471 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [Optional "lvm2"],
1472 [InitEmpty, Always, TestOutputList (
1473 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1474 ["pvcreate"; "/dev/sda1"];
1475 ["pvcreate"; "/dev/sda2"];
1476 ["pvcreate"; "/dev/sda3"];
1477 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1478 ["vgcreate"; "VG2"; "/dev/sda3"];
1479 ["vgs"]], ["VG1"; "VG2"])],
1480 "create an LVM volume group",
1482 This creates an LVM volume group called C<volgroup>
1483 from the non-empty list of physical volumes C<physvols>.");
1485 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [Optional "lvm2"],
1486 [InitEmpty, Always, TestOutputList (
1487 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1488 ["pvcreate"; "/dev/sda1"];
1489 ["pvcreate"; "/dev/sda2"];
1490 ["pvcreate"; "/dev/sda3"];
1491 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1492 ["vgcreate"; "VG2"; "/dev/sda3"];
1493 ["lvcreate"; "LV1"; "VG1"; "50"];
1494 ["lvcreate"; "LV2"; "VG1"; "50"];
1495 ["lvcreate"; "LV3"; "VG2"; "50"];
1496 ["lvcreate"; "LV4"; "VG2"; "50"];
1497 ["lvcreate"; "LV5"; "VG2"; "50"];
1499 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1500 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1501 "create an LVM logical volume",
1503 This creates an LVM logical volume called C<logvol>
1504 on the volume group C<volgroup>, with C<size> megabytes.");
1506 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1507 [InitEmpty, Always, TestOutput (
1508 [["part_disk"; "/dev/sda"; "mbr"];
1509 ["mkfs"; "ext2"; "/dev/sda1"];
1510 ["mount_options"; ""; "/dev/sda1"; "/"];
1511 ["write"; "/new"; "new file contents"];
1512 ["cat"; "/new"]], "new file contents")],
1513 "make a filesystem",
1515 This creates a filesystem on C<device> (usually a partition
1516 or LVM logical volume). The filesystem type is C<fstype>, for
1519 ("sfdisk", (RErr, [Device "device";
1520 Int "cyls"; Int "heads"; Int "sectors";
1521 StringList "lines"]), 43, [DangerWillRobinson],
1523 "create partitions on a block device",
1525 This is a direct interface to the L<sfdisk(8)> program for creating
1526 partitions on block devices.
1528 C<device> should be a block device, for example C</dev/sda>.
1530 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1531 and sectors on the device, which are passed directly to sfdisk as
1532 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1533 of these, then the corresponding parameter is omitted. Usually for
1534 'large' disks, you can just pass C<0> for these, but for small
1535 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1536 out the right geometry and you will need to tell it.
1538 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1539 information refer to the L<sfdisk(8)> manpage.
1541 To create a single partition occupying the whole disk, you would
1542 pass C<lines> as a single element list, when the single element being
1543 the string C<,> (comma).
1545 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1546 C<guestfs_part_init>");
1548 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning; DeprecatedBy "write"],
1549 (* Regression test for RHBZ#597135. *)
1550 [InitBasicFS, Always, TestLastFail
1551 [["write_file"; "/new"; "abc"; "10000"]]],
1554 This call creates a file called C<path>. The contents of the
1555 file is the string C<content> (which can contain any 8 bit data),
1556 with length C<size>.
1558 As a special case, if C<size> is C<0>
1559 then the length is calculated using C<strlen> (so in this case
1560 the content cannot contain embedded ASCII NULs).
1562 I<NB.> Owing to a bug, writing content containing ASCII NUL
1563 characters does I<not> work, even if the length is specified.");
1565 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1566 [InitEmpty, Always, TestOutputListOfDevices (
1567 [["part_disk"; "/dev/sda"; "mbr"];
1568 ["mkfs"; "ext2"; "/dev/sda1"];
1569 ["mount_options"; ""; "/dev/sda1"; "/"];
1570 ["mounts"]], ["/dev/sda1"]);
1571 InitEmpty, Always, TestOutputList (
1572 [["part_disk"; "/dev/sda"; "mbr"];
1573 ["mkfs"; "ext2"; "/dev/sda1"];
1574 ["mount_options"; ""; "/dev/sda1"; "/"];
1577 "unmount a filesystem",
1579 This unmounts the given filesystem. The filesystem may be
1580 specified either by its mountpoint (path) or the device which
1581 contains the filesystem.");
1583 ("mounts", (RStringList "devices", []), 46, [],
1584 [InitBasicFS, Always, TestOutputListOfDevices (
1585 [["mounts"]], ["/dev/sda1"])],
1586 "show mounted filesystems",
1588 This returns the list of currently mounted filesystems. It returns
1589 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1591 Some internal mounts are not shown.
1593 See also: C<guestfs_mountpoints>");
1595 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1596 [InitBasicFS, Always, TestOutputList (
1599 (* check that umount_all can unmount nested mounts correctly: *)
1600 InitEmpty, Always, TestOutputList (
1601 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1602 ["mkfs"; "ext2"; "/dev/sda1"];
1603 ["mkfs"; "ext2"; "/dev/sda2"];
1604 ["mkfs"; "ext2"; "/dev/sda3"];
1605 ["mount_options"; ""; "/dev/sda1"; "/"];
1607 ["mount_options"; ""; "/dev/sda2"; "/mp1"];
1608 ["mkdir"; "/mp1/mp2"];
1609 ["mount_options"; ""; "/dev/sda3"; "/mp1/mp2"];
1610 ["mkdir"; "/mp1/mp2/mp3"];
1613 "unmount all filesystems",
1615 This unmounts all mounted filesystems.
1617 Some internal mounts are not unmounted by this call.");
1619 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson; Optional "lvm2"],
1621 "remove all LVM LVs, VGs and PVs",
1623 This command removes all LVM logical volumes, volume groups
1624 and physical volumes.");
1626 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1627 [InitISOFS, Always, TestOutput (
1628 [["file"; "/empty"]], "empty");
1629 InitISOFS, Always, TestOutput (
1630 [["file"; "/known-1"]], "ASCII text");
1631 InitISOFS, Always, TestLastFail (
1632 [["file"; "/notexists"]])],
1633 "determine file type",
1635 This call uses the standard L<file(1)> command to determine
1636 the type or contents of the file. This also works on devices,
1637 for example to find out whether a partition contains a filesystem.
1639 This call will also transparently look inside various types
1642 The exact command which runs is C<file -zbsL path>. Note in
1643 particular that the filename is not prepended to the output
1644 (the C<-b> option).");
1646 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1647 [InitBasicFS, Always, TestOutput (
1648 [["upload"; "test-command"; "/test-command"];
1649 ["chmod"; "0o755"; "/test-command"];
1650 ["command"; "/test-command 1"]], "Result1");
1651 InitBasicFS, Always, TestOutput (
1652 [["upload"; "test-command"; "/test-command"];
1653 ["chmod"; "0o755"; "/test-command"];
1654 ["command"; "/test-command 2"]], "Result2\n");
1655 InitBasicFS, Always, TestOutput (
1656 [["upload"; "test-command"; "/test-command"];
1657 ["chmod"; "0o755"; "/test-command"];
1658 ["command"; "/test-command 3"]], "\nResult3");
1659 InitBasicFS, Always, TestOutput (
1660 [["upload"; "test-command"; "/test-command"];
1661 ["chmod"; "0o755"; "/test-command"];
1662 ["command"; "/test-command 4"]], "\nResult4\n");
1663 InitBasicFS, Always, TestOutput (
1664 [["upload"; "test-command"; "/test-command"];
1665 ["chmod"; "0o755"; "/test-command"];
1666 ["command"; "/test-command 5"]], "\nResult5\n\n");
1667 InitBasicFS, Always, TestOutput (
1668 [["upload"; "test-command"; "/test-command"];
1669 ["chmod"; "0o755"; "/test-command"];
1670 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1671 InitBasicFS, Always, TestOutput (
1672 [["upload"; "test-command"; "/test-command"];
1673 ["chmod"; "0o755"; "/test-command"];
1674 ["command"; "/test-command 7"]], "");
1675 InitBasicFS, Always, TestOutput (
1676 [["upload"; "test-command"; "/test-command"];
1677 ["chmod"; "0o755"; "/test-command"];
1678 ["command"; "/test-command 8"]], "\n");
1679 InitBasicFS, Always, TestOutput (
1680 [["upload"; "test-command"; "/test-command"];
1681 ["chmod"; "0o755"; "/test-command"];
1682 ["command"; "/test-command 9"]], "\n\n");
1683 InitBasicFS, Always, TestOutput (
1684 [["upload"; "test-command"; "/test-command"];
1685 ["chmod"; "0o755"; "/test-command"];
1686 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1687 InitBasicFS, Always, TestOutput (
1688 [["upload"; "test-command"; "/test-command"];
1689 ["chmod"; "0o755"; "/test-command"];
1690 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1691 InitBasicFS, Always, TestLastFail (
1692 [["upload"; "test-command"; "/test-command"];
1693 ["chmod"; "0o755"; "/test-command"];
1694 ["command"; "/test-command"]])],
1695 "run a command from the guest filesystem",
1697 This call runs a command from the guest filesystem. The
1698 filesystem must be mounted, and must contain a compatible
1699 operating system (ie. something Linux, with the same
1700 or compatible processor architecture).
1702 The single parameter is an argv-style list of arguments.
1703 The first element is the name of the program to run.
1704 Subsequent elements are parameters. The list must be
1705 non-empty (ie. must contain a program name). Note that
1706 the command runs directly, and is I<not> invoked via
1707 the shell (see C<guestfs_sh>).
1709 The return value is anything printed to I<stdout> by
1712 If the command returns a non-zero exit status, then
1713 this function returns an error message. The error message
1714 string is the content of I<stderr> from the command.
1716 The C<$PATH> environment variable will contain at least
1717 C</usr/bin> and C</bin>. If you require a program from
1718 another location, you should provide the full path in the
1721 Shared libraries and data files required by the program
1722 must be available on filesystems which are mounted in the
1723 correct places. It is the caller's responsibility to ensure
1724 all filesystems that are needed are mounted at the right
1727 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1728 [InitBasicFS, Always, TestOutputList (
1729 [["upload"; "test-command"; "/test-command"];
1730 ["chmod"; "0o755"; "/test-command"];
1731 ["command_lines"; "/test-command 1"]], ["Result1"]);
1732 InitBasicFS, Always, TestOutputList (
1733 [["upload"; "test-command"; "/test-command"];
1734 ["chmod"; "0o755"; "/test-command"];
1735 ["command_lines"; "/test-command 2"]], ["Result2"]);
1736 InitBasicFS, Always, TestOutputList (
1737 [["upload"; "test-command"; "/test-command"];
1738 ["chmod"; "0o755"; "/test-command"];
1739 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1740 InitBasicFS, Always, TestOutputList (
1741 [["upload"; "test-command"; "/test-command"];
1742 ["chmod"; "0o755"; "/test-command"];
1743 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1744 InitBasicFS, Always, TestOutputList (
1745 [["upload"; "test-command"; "/test-command"];
1746 ["chmod"; "0o755"; "/test-command"];
1747 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1748 InitBasicFS, Always, TestOutputList (
1749 [["upload"; "test-command"; "/test-command"];
1750 ["chmod"; "0o755"; "/test-command"];
1751 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1752 InitBasicFS, Always, TestOutputList (
1753 [["upload"; "test-command"; "/test-command"];
1754 ["chmod"; "0o755"; "/test-command"];
1755 ["command_lines"; "/test-command 7"]], []);
1756 InitBasicFS, Always, TestOutputList (
1757 [["upload"; "test-command"; "/test-command"];
1758 ["chmod"; "0o755"; "/test-command"];
1759 ["command_lines"; "/test-command 8"]], [""]);
1760 InitBasicFS, Always, TestOutputList (
1761 [["upload"; "test-command"; "/test-command"];
1762 ["chmod"; "0o755"; "/test-command"];
1763 ["command_lines"; "/test-command 9"]], ["";""]);
1764 InitBasicFS, Always, TestOutputList (
1765 [["upload"; "test-command"; "/test-command"];
1766 ["chmod"; "0o755"; "/test-command"];
1767 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1768 InitBasicFS, Always, TestOutputList (
1769 [["upload"; "test-command"; "/test-command"];
1770 ["chmod"; "0o755"; "/test-command"];
1771 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1772 "run a command, returning lines",
1774 This is the same as C<guestfs_command>, but splits the
1775 result into a list of lines.
1777 See also: C<guestfs_sh_lines>");
1779 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1780 [InitISOFS, Always, TestOutputStruct (
1781 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1782 "get file information",
1784 Returns file information for the given C<path>.
1786 This is the same as the C<stat(2)> system call.");
1788 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1789 [InitISOFS, Always, TestOutputStruct (
1790 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1791 "get file information for a symbolic link",
1793 Returns file information for the given C<path>.
1795 This is the same as C<guestfs_stat> except that if C<path>
1796 is a symbolic link, then the link is stat-ed, not the file it
1799 This is the same as the C<lstat(2)> system call.");
1801 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1802 [InitISOFS, Always, TestOutputStruct (
1803 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1804 "get file system statistics",
1806 Returns file system statistics for any mounted file system.
1807 C<path> should be a file or directory in the mounted file system
1808 (typically it is the mount point itself, but it doesn't need to be).
1810 This is the same as the C<statvfs(2)> system call.");
1812 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1814 "get ext2/ext3/ext4 superblock details",
1816 This returns the contents of the ext2, ext3 or ext4 filesystem
1817 superblock on C<device>.
1819 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1820 manpage for more details. The list of fields returned isn't
1821 clearly defined, and depends on both the version of C<tune2fs>
1822 that libguestfs was built against, and the filesystem itself.");
1824 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1825 [InitEmpty, Always, TestOutputTrue (
1826 [["blockdev_setro"; "/dev/sda"];
1827 ["blockdev_getro"; "/dev/sda"]])],
1828 "set block device to read-only",
1830 Sets the block device named C<device> to read-only.
1832 This uses the L<blockdev(8)> command.");
1834 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1835 [InitEmpty, Always, TestOutputFalse (
1836 [["blockdev_setrw"; "/dev/sda"];
1837 ["blockdev_getro"; "/dev/sda"]])],
1838 "set block device to read-write",
1840 Sets the block device named C<device> to read-write.
1842 This uses the L<blockdev(8)> command.");
1844 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1845 [InitEmpty, Always, TestOutputTrue (
1846 [["blockdev_setro"; "/dev/sda"];
1847 ["blockdev_getro"; "/dev/sda"]])],
1848 "is block device set to read-only",
1850 Returns a boolean indicating if the block device is read-only
1851 (true if read-only, false if not).
1853 This uses the L<blockdev(8)> command.");
1855 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1856 [InitEmpty, Always, TestOutputInt (
1857 [["blockdev_getss"; "/dev/sda"]], 512)],
1858 "get sectorsize of block device",
1860 This returns the size of sectors on a block device.
1861 Usually 512, but can be larger for modern devices.
1863 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1866 This uses the L<blockdev(8)> command.");
1868 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1869 [InitEmpty, Always, TestOutputInt (
1870 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1871 "get blocksize of block device",
1873 This returns the block size of a device.
1875 (Note this is different from both I<size in blocks> and
1876 I<filesystem block size>).
1878 This uses the L<blockdev(8)> command.");
1880 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1882 "set blocksize of block device",
1884 This sets the block size of a device.
1886 (Note this is different from both I<size in blocks> and
1887 I<filesystem block size>).
1889 This uses the L<blockdev(8)> command.");
1891 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1892 [InitEmpty, Always, TestOutputInt (
1893 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1894 "get total size of device in 512-byte sectors",
1896 This returns the size of the device in units of 512-byte sectors
1897 (even if the sectorsize isn't 512 bytes ... weird).
1899 See also C<guestfs_blockdev_getss> for the real sector size of
1900 the device, and C<guestfs_blockdev_getsize64> for the more
1901 useful I<size in bytes>.
1903 This uses the L<blockdev(8)> command.");
1905 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1906 [InitEmpty, Always, TestOutputInt (
1907 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1908 "get total size of device in bytes",
1910 This returns the size of the device in bytes.
1912 See also C<guestfs_blockdev_getsz>.
1914 This uses the L<blockdev(8)> command.");
1916 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1917 [InitEmpty, Always, TestRun
1918 [["blockdev_flushbufs"; "/dev/sda"]]],
1919 "flush device buffers",
1921 This tells the kernel to flush internal buffers associated
1924 This uses the L<blockdev(8)> command.");
1926 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1927 [InitEmpty, Always, TestRun
1928 [["blockdev_rereadpt"; "/dev/sda"]]],
1929 "reread partition table",
1931 Reread the partition table on C<device>.
1933 This uses the L<blockdev(8)> command.");
1935 ("upload", (RErr, [FileIn "filename"; Dev_or_Path "remotefilename"]), 66, [],
1936 [InitBasicFS, Always, TestOutput (
1937 (* Pick a file from cwd which isn't likely to change. *)
1938 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1939 ["checksum"; "md5"; "/COPYING.LIB"]],
1940 Digest.to_hex (Digest.file "COPYING.LIB"))],
1941 "upload a file from the local machine",
1943 Upload local file C<filename> to C<remotefilename> on the
1946 C<filename> can also be a named pipe.
1948 See also C<guestfs_download>.");
1950 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1951 [InitBasicFS, Always, TestOutput (
1952 (* Pick a file from cwd which isn't likely to change. *)
1953 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1954 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1955 ["upload"; "testdownload.tmp"; "/upload"];
1956 ["checksum"; "md5"; "/upload"]],
1957 Digest.to_hex (Digest.file "COPYING.LIB"))],
1958 "download a file to the local machine",
1960 Download file C<remotefilename> and save it as C<filename>
1961 on the local machine.
1963 C<filename> can also be a named pipe.
1965 See also C<guestfs_upload>, C<guestfs_cat>.");
1967 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1968 [InitISOFS, Always, TestOutput (
1969 [["checksum"; "crc"; "/known-3"]], "2891671662");
1970 InitISOFS, Always, TestLastFail (
1971 [["checksum"; "crc"; "/notexists"]]);
1972 InitISOFS, Always, TestOutput (
1973 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1974 InitISOFS, Always, TestOutput (
1975 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1976 InitISOFS, Always, TestOutput (
1977 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1978 InitISOFS, Always, TestOutput (
1979 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1980 InitISOFS, Always, TestOutput (
1981 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1982 InitISOFS, Always, TestOutput (
1983 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6");
1984 (* Test for RHBZ#579608, absolute symbolic links. *)
1985 InitISOFS, Always, TestOutput (
1986 [["checksum"; "sha512"; "/abssymlink"]], "5f57d0639bc95081c53afc63a449403883818edc64da48930ad6b1a4fb49be90404686877743fbcd7c99811f3def7df7bc22635c885c6a8cf79c806b43451c1a")],
1987 "compute MD5, SHAx or CRC checksum of file",
1989 This call computes the MD5, SHAx or CRC checksum of the
1992 The type of checksum to compute is given by the C<csumtype>
1993 parameter which must have one of the following values:
1999 Compute the cyclic redundancy check (CRC) specified by POSIX
2000 for the C<cksum> command.
2004 Compute the MD5 hash (using the C<md5sum> program).
2008 Compute the SHA1 hash (using the C<sha1sum> program).
2012 Compute the SHA224 hash (using the C<sha224sum> program).
2016 Compute the SHA256 hash (using the C<sha256sum> program).
2020 Compute the SHA384 hash (using the C<sha384sum> program).
2024 Compute the SHA512 hash (using the C<sha512sum> program).
2028 The checksum is returned as a printable string.
2030 To get the checksum for a device, use C<guestfs_checksum_device>.
2032 To get the checksums for many files, use C<guestfs_checksums_out>.");
2034 ("tar_in", (RErr, [FileIn "tarfile"; Pathname "directory"]), 69, [],
2035 [InitBasicFS, Always, TestOutput (
2036 [["tar_in"; "../images/helloworld.tar"; "/"];
2037 ["cat"; "/hello"]], "hello\n")],
2038 "unpack tarfile to directory",
2040 This command uploads and unpacks local file C<tarfile> (an
2041 I<uncompressed> tar file) into C<directory>.
2043 To upload a compressed tarball, use C<guestfs_tgz_in>
2044 or C<guestfs_txz_in>.");
2046 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
2048 "pack directory into tarfile",
2050 This command packs the contents of C<directory> and downloads
2051 it to local file C<tarfile>.
2053 To download a compressed tarball, use C<guestfs_tgz_out>
2054 or C<guestfs_txz_out>.");
2056 ("tgz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 71, [],
2057 [InitBasicFS, Always, TestOutput (
2058 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
2059 ["cat"; "/hello"]], "hello\n")],
2060 "unpack compressed tarball to directory",
2062 This command uploads and unpacks local file C<tarball> (a
2063 I<gzip compressed> tar file) into C<directory>.
2065 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
2067 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
2069 "pack directory into compressed tarball",
2071 This command packs the contents of C<directory> and downloads
2072 it to local file C<tarball>.
2074 To download an uncompressed tarball, use C<guestfs_tar_out>.");
2076 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
2077 [InitBasicFS, Always, TestLastFail (
2079 ["mount_ro"; "/dev/sda1"; "/"];
2080 ["touch"; "/new"]]);
2081 InitBasicFS, Always, TestOutput (
2082 [["write"; "/new"; "data"];
2084 ["mount_ro"; "/dev/sda1"; "/"];
2085 ["cat"; "/new"]], "data")],
2086 "mount a guest disk, read-only",
2088 This is the same as the C<guestfs_mount> command, but it
2089 mounts the filesystem with the read-only (I<-o ro>) flag.");
2091 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2093 "mount a guest disk with mount options",
2095 This is the same as the C<guestfs_mount> command, but it
2096 allows you to set the mount options as for the
2097 L<mount(8)> I<-o> flag.
2099 If the C<options> parameter is an empty string, then
2100 no options are passed (all options default to whatever
2101 the filesystem uses).");
2103 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2105 "mount a guest disk with mount options and vfstype",
2107 This is the same as the C<guestfs_mount> command, but it
2108 allows you to set both the mount options and the vfstype
2109 as for the L<mount(8)> I<-o> and I<-t> flags.");
2111 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2113 "debugging and internals",
2115 The C<guestfs_debug> command exposes some internals of
2116 C<guestfsd> (the guestfs daemon) that runs inside the
2119 There is no comprehensive help for this command. You have
2120 to look at the file C<daemon/debug.c> in the libguestfs source
2121 to find out what you can do.");
2123 ("lvremove", (RErr, [Device "device"]), 77, [Optional "lvm2"],
2124 [InitEmpty, Always, TestOutputList (
2125 [["part_disk"; "/dev/sda"; "mbr"];
2126 ["pvcreate"; "/dev/sda1"];
2127 ["vgcreate"; "VG"; "/dev/sda1"];
2128 ["lvcreate"; "LV1"; "VG"; "50"];
2129 ["lvcreate"; "LV2"; "VG"; "50"];
2130 ["lvremove"; "/dev/VG/LV1"];
2131 ["lvs"]], ["/dev/VG/LV2"]);
2132 InitEmpty, Always, TestOutputList (
2133 [["part_disk"; "/dev/sda"; "mbr"];
2134 ["pvcreate"; "/dev/sda1"];
2135 ["vgcreate"; "VG"; "/dev/sda1"];
2136 ["lvcreate"; "LV1"; "VG"; "50"];
2137 ["lvcreate"; "LV2"; "VG"; "50"];
2138 ["lvremove"; "/dev/VG"];
2140 InitEmpty, Always, TestOutputList (
2141 [["part_disk"; "/dev/sda"; "mbr"];
2142 ["pvcreate"; "/dev/sda1"];
2143 ["vgcreate"; "VG"; "/dev/sda1"];
2144 ["lvcreate"; "LV1"; "VG"; "50"];
2145 ["lvcreate"; "LV2"; "VG"; "50"];
2146 ["lvremove"; "/dev/VG"];
2148 "remove an LVM logical volume",
2150 Remove an LVM logical volume C<device>, where C<device> is
2151 the path to the LV, such as C</dev/VG/LV>.
2153 You can also remove all LVs in a volume group by specifying
2154 the VG name, C</dev/VG>.");
2156 ("vgremove", (RErr, [String "vgname"]), 78, [Optional "lvm2"],
2157 [InitEmpty, Always, TestOutputList (
2158 [["part_disk"; "/dev/sda"; "mbr"];
2159 ["pvcreate"; "/dev/sda1"];
2160 ["vgcreate"; "VG"; "/dev/sda1"];
2161 ["lvcreate"; "LV1"; "VG"; "50"];
2162 ["lvcreate"; "LV2"; "VG"; "50"];
2165 InitEmpty, Always, TestOutputList (
2166 [["part_disk"; "/dev/sda"; "mbr"];
2167 ["pvcreate"; "/dev/sda1"];
2168 ["vgcreate"; "VG"; "/dev/sda1"];
2169 ["lvcreate"; "LV1"; "VG"; "50"];
2170 ["lvcreate"; "LV2"; "VG"; "50"];
2173 "remove an LVM volume group",
2175 Remove an LVM volume group C<vgname>, (for example C<VG>).
2177 This also forcibly removes all logical volumes in the volume
2180 ("pvremove", (RErr, [Device "device"]), 79, [Optional "lvm2"],
2181 [InitEmpty, Always, TestOutputListOfDevices (
2182 [["part_disk"; "/dev/sda"; "mbr"];
2183 ["pvcreate"; "/dev/sda1"];
2184 ["vgcreate"; "VG"; "/dev/sda1"];
2185 ["lvcreate"; "LV1"; "VG"; "50"];
2186 ["lvcreate"; "LV2"; "VG"; "50"];
2188 ["pvremove"; "/dev/sda1"];
2190 InitEmpty, Always, TestOutputListOfDevices (
2191 [["part_disk"; "/dev/sda"; "mbr"];
2192 ["pvcreate"; "/dev/sda1"];
2193 ["vgcreate"; "VG"; "/dev/sda1"];
2194 ["lvcreate"; "LV1"; "VG"; "50"];
2195 ["lvcreate"; "LV2"; "VG"; "50"];
2197 ["pvremove"; "/dev/sda1"];
2199 InitEmpty, Always, TestOutputListOfDevices (
2200 [["part_disk"; "/dev/sda"; "mbr"];
2201 ["pvcreate"; "/dev/sda1"];
2202 ["vgcreate"; "VG"; "/dev/sda1"];
2203 ["lvcreate"; "LV1"; "VG"; "50"];
2204 ["lvcreate"; "LV2"; "VG"; "50"];
2206 ["pvremove"; "/dev/sda1"];
2208 "remove an LVM physical volume",
2210 This wipes a physical volume C<device> so that LVM will no longer
2213 The implementation uses the C<pvremove> command which refuses to
2214 wipe physical volumes that contain any volume groups, so you have
2215 to remove those first.");
2217 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2218 [InitBasicFS, Always, TestOutput (
2219 [["set_e2label"; "/dev/sda1"; "testlabel"];
2220 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2221 "set the ext2/3/4 filesystem label",
2223 This sets the ext2/3/4 filesystem label of the filesystem on
2224 C<device> to C<label>. Filesystem labels are limited to
2227 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2228 to return the existing label on a filesystem.");
2230 ("get_e2label", (RString "label", [Device "device"]), 81, [DeprecatedBy "vfs_label"],
2232 "get the ext2/3/4 filesystem label",
2234 This returns the ext2/3/4 filesystem label of the filesystem on
2237 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2238 (let uuid = uuidgen () in
2239 [InitBasicFS, Always, TestOutput (
2240 [["set_e2uuid"; "/dev/sda1"; uuid];
2241 ["get_e2uuid"; "/dev/sda1"]], uuid);
2242 InitBasicFS, Always, TestOutput (
2243 [["set_e2uuid"; "/dev/sda1"; "clear"];
2244 ["get_e2uuid"; "/dev/sda1"]], "");
2245 (* We can't predict what UUIDs will be, so just check the commands run. *)
2246 InitBasicFS, Always, TestRun (
2247 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2248 InitBasicFS, Always, TestRun (
2249 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2250 "set the ext2/3/4 filesystem UUID",
2252 This sets the ext2/3/4 filesystem UUID of the filesystem on
2253 C<device> to C<uuid>. The format of the UUID and alternatives
2254 such as C<clear>, C<random> and C<time> are described in the
2255 L<tune2fs(8)> manpage.
2257 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2258 to return the existing UUID of a filesystem.");
2260 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [DeprecatedBy "vfs_uuid"],
2261 (* Regression test for RHBZ#597112. *)
2262 (let uuid = uuidgen () in
2263 [InitBasicFS, Always, TestOutput (
2264 [["mke2journal"; "1024"; "/dev/sdb"];
2265 ["set_e2uuid"; "/dev/sdb"; uuid];
2266 ["get_e2uuid"; "/dev/sdb"]], uuid)]),
2267 "get the ext2/3/4 filesystem UUID",
2269 This returns the ext2/3/4 filesystem UUID of the filesystem on
2272 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [FishOutput FishOutputHexadecimal],
2273 [InitBasicFS, Always, TestOutputInt (
2274 [["umount"; "/dev/sda1"];
2275 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2276 InitBasicFS, Always, TestOutputInt (
2277 [["umount"; "/dev/sda1"];
2278 ["zero"; "/dev/sda1"];
2279 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2280 "run the filesystem checker",
2282 This runs the filesystem checker (fsck) on C<device> which
2283 should have filesystem type C<fstype>.
2285 The returned integer is the status. See L<fsck(8)> for the
2286 list of status codes from C<fsck>.
2294 Multiple status codes can be summed together.
2298 A non-zero return code can mean \"success\", for example if
2299 errors have been corrected on the filesystem.
2303 Checking or repairing NTFS volumes is not supported
2308 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2310 ("zero", (RErr, [Device "device"]), 85, [],
2311 [InitBasicFS, Always, TestOutput (
2312 [["umount"; "/dev/sda1"];
2313 ["zero"; "/dev/sda1"];
2314 ["file"; "/dev/sda1"]], "data")],
2315 "write zeroes to the device",
2317 This command writes zeroes over the first few blocks of C<device>.
2319 How many blocks are zeroed isn't specified (but it's I<not> enough
2320 to securely wipe the device). It should be sufficient to remove
2321 any partition tables, filesystem superblocks and so on.
2323 See also: C<guestfs_zero_device>, C<guestfs_scrub_device>.");
2325 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2327 * https://bugzilla.redhat.com/show_bug.cgi?id=484986
2328 * https://bugzilla.redhat.com/show_bug.cgi?id=479760
2330 [InitBasicFS, Always, TestOutputTrue (
2331 [["mkdir_p"; "/boot/grub"];
2332 ["write"; "/boot/grub/device.map"; "(hd0) /dev/vda"];
2333 ["grub_install"; "/"; "/dev/vda"];
2334 ["is_dir"; "/boot"]])],
2337 This command installs GRUB (the Grand Unified Bootloader) on
2338 C<device>, with the root directory being C<root>.
2340 Note: If grub-install reports the error
2341 \"No suitable drive was found in the generated device map.\"
2342 it may be that you need to create a C</boot/grub/device.map>
2343 file first that contains the mapping between grub device names
2344 and Linux device names. It is usually sufficient to create
2349 replacing C</dev/vda> with the name of the installation device.");
2351 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2352 [InitBasicFS, Always, TestOutput (
2353 [["write"; "/old"; "file content"];
2354 ["cp"; "/old"; "/new"];
2355 ["cat"; "/new"]], "file content");
2356 InitBasicFS, Always, TestOutputTrue (
2357 [["write"; "/old"; "file content"];
2358 ["cp"; "/old"; "/new"];
2359 ["is_file"; "/old"]]);
2360 InitBasicFS, Always, TestOutput (
2361 [["write"; "/old"; "file content"];
2363 ["cp"; "/old"; "/dir/new"];
2364 ["cat"; "/dir/new"]], "file content")],
2367 This copies a file from C<src> to C<dest> where C<dest> is
2368 either a destination filename or destination directory.");
2370 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2371 [InitBasicFS, Always, TestOutput (
2372 [["mkdir"; "/olddir"];
2373 ["mkdir"; "/newdir"];
2374 ["write"; "/olddir/file"; "file content"];
2375 ["cp_a"; "/olddir"; "/newdir"];
2376 ["cat"; "/newdir/olddir/file"]], "file content")],
2377 "copy a file or directory recursively",
2379 This copies a file or directory from C<src> to C<dest>
2380 recursively using the C<cp -a> command.");
2382 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2383 [InitBasicFS, Always, TestOutput (
2384 [["write"; "/old"; "file content"];
2385 ["mv"; "/old"; "/new"];
2386 ["cat"; "/new"]], "file content");
2387 InitBasicFS, Always, TestOutputFalse (
2388 [["write"; "/old"; "file content"];
2389 ["mv"; "/old"; "/new"];
2390 ["is_file"; "/old"]])],
2393 This moves a file from C<src> to C<dest> where C<dest> is
2394 either a destination filename or destination directory.");
2396 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2397 [InitEmpty, Always, TestRun (
2398 [["drop_caches"; "3"]])],
2399 "drop kernel page cache, dentries and inodes",
2401 This instructs the guest kernel to drop its page cache,
2402 and/or dentries and inode caches. The parameter C<whattodrop>
2403 tells the kernel what precisely to drop, see
2404 L<http://linux-mm.org/Drop_Caches>
2406 Setting C<whattodrop> to 3 should drop everything.
2408 This automatically calls L<sync(2)> before the operation,
2409 so that the maximum guest memory is freed.");
2411 ("dmesg", (RString "kmsgs", []), 91, [],
2412 [InitEmpty, Always, TestRun (
2414 "return kernel messages",
2416 This returns the kernel messages (C<dmesg> output) from
2417 the guest kernel. This is sometimes useful for extended
2418 debugging of problems.
2420 Another way to get the same information is to enable
2421 verbose messages with C<guestfs_set_verbose> or by setting
2422 the environment variable C<LIBGUESTFS_DEBUG=1> before
2423 running the program.");
2425 ("ping_daemon", (RErr, []), 92, [],
2426 [InitEmpty, Always, TestRun (
2427 [["ping_daemon"]])],
2428 "ping the guest daemon",
2430 This is a test probe into the guestfs daemon running inside
2431 the qemu subprocess. Calling this function checks that the
2432 daemon responds to the ping message, without affecting the daemon
2433 or attached block device(s) in any other way.");
2435 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2436 [InitBasicFS, Always, TestOutputTrue (
2437 [["write"; "/file1"; "contents of a file"];
2438 ["cp"; "/file1"; "/file2"];
2439 ["equal"; "/file1"; "/file2"]]);
2440 InitBasicFS, Always, TestOutputFalse (
2441 [["write"; "/file1"; "contents of a file"];
2442 ["write"; "/file2"; "contents of another file"];
2443 ["equal"; "/file1"; "/file2"]]);
2444 InitBasicFS, Always, TestLastFail (
2445 [["equal"; "/file1"; "/file2"]])],
2446 "test if two files have equal contents",
2448 This compares the two files C<file1> and C<file2> and returns
2449 true if their content is exactly equal, or false otherwise.
2451 The external L<cmp(1)> program is used for the comparison.");
2453 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2454 [InitISOFS, Always, TestOutputList (
2455 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2456 InitISOFS, Always, TestOutputList (
2457 [["strings"; "/empty"]], []);
2458 (* Test for RHBZ#579608, absolute symbolic links. *)
2459 InitISOFS, Always, TestRun (
2460 [["strings"; "/abssymlink"]])],
2461 "print the printable strings in a file",
2463 This runs the L<strings(1)> command on a file and returns
2464 the list of printable strings found.");
2466 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2467 [InitISOFS, Always, TestOutputList (
2468 [["strings_e"; "b"; "/known-5"]], []);
2469 InitBasicFS, Always, TestOutputList (
2470 [["write"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"];
2471 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2472 "print the printable strings in a file",
2474 This is like the C<guestfs_strings> command, but allows you to
2475 specify the encoding of strings that are looked for in
2476 the source file C<path>.
2478 Allowed encodings are:
2484 Single 7-bit-byte characters like ASCII and the ASCII-compatible
2485 parts of ISO-8859-X (this is what C<guestfs_strings> uses).
2489 Single 8-bit-byte characters.
2493 16-bit big endian strings such as those encoded in
2494 UTF-16BE or UCS-2BE.
2496 =item l (lower case letter L)
2498 16-bit little endian such as UTF-16LE and UCS-2LE.
2499 This is useful for examining binaries in Windows guests.
2503 32-bit big endian such as UCS-4BE.
2507 32-bit little endian such as UCS-4LE.
2511 The returned strings are transcoded to UTF-8.");
2513 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2514 [InitISOFS, Always, TestOutput (
2515 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2516 (* Test for RHBZ#501888c2 regression which caused large hexdump
2517 * commands to segfault.
2519 InitISOFS, Always, TestRun (
2520 [["hexdump"; "/100krandom"]]);
2521 (* Test for RHBZ#579608, absolute symbolic links. *)
2522 InitISOFS, Always, TestRun (
2523 [["hexdump"; "/abssymlink"]])],
2524 "dump a file in hexadecimal",
2526 This runs C<hexdump -C> on the given C<path>. The result is
2527 the human-readable, canonical hex dump of the file.");
2529 ("zerofree", (RErr, [Device "device"]), 97, [Optional "zerofree"],
2530 [InitNone, Always, TestOutput (
2531 [["part_disk"; "/dev/sda"; "mbr"];
2532 ["mkfs"; "ext3"; "/dev/sda1"];
2533 ["mount_options"; ""; "/dev/sda1"; "/"];
2534 ["write"; "/new"; "test file"];
2535 ["umount"; "/dev/sda1"];
2536 ["zerofree"; "/dev/sda1"];
2537 ["mount_options"; ""; "/dev/sda1"; "/"];
2538 ["cat"; "/new"]], "test file")],
2539 "zero unused inodes and disk blocks on ext2/3 filesystem",
2541 This runs the I<zerofree> program on C<device>. This program
2542 claims to zero unused inodes and disk blocks on an ext2/3
2543 filesystem, thus making it possible to compress the filesystem
2546 You should B<not> run this program if the filesystem is
2549 It is possible that using this program can damage the filesystem
2550 or data on the filesystem.");
2552 ("pvresize", (RErr, [Device "device"]), 98, [Optional "lvm2"],
2554 "resize an LVM physical volume",
2556 This resizes (expands or shrinks) an existing LVM physical
2557 volume to match the new size of the underlying device.");
2559 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2560 Int "cyls"; Int "heads"; Int "sectors";
2561 String "line"]), 99, [DangerWillRobinson],
2563 "modify a single partition on a block device",
2565 This runs L<sfdisk(8)> option to modify just the single
2566 partition C<n> (note: C<n> counts from 1).
2568 For other parameters, see C<guestfs_sfdisk>. You should usually
2569 pass C<0> for the cyls/heads/sectors parameters.
2571 See also: C<guestfs_part_add>");
2573 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2575 "display the partition table",
2577 This displays the partition table on C<device>, in the
2578 human-readable output of the L<sfdisk(8)> command. It is
2579 not intended to be parsed.
2581 See also: C<guestfs_part_list>");
2583 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2585 "display the kernel geometry",
2587 This displays the kernel's idea of the geometry of C<device>.
2589 The result is in human-readable format, and not designed to
2592 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2594 "display the disk geometry from the partition table",
2596 This displays the disk geometry of C<device> read from the
2597 partition table. Especially in the case where the underlying
2598 block device has been resized, this can be different from the
2599 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2601 The result is in human-readable format, and not designed to
2604 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [Optional "lvm2"],
2606 "activate or deactivate all volume groups",
2608 This command activates or (if C<activate> is false) deactivates
2609 all logical volumes in all volume groups.
2610 If activated, then they are made known to the
2611 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2612 then those devices disappear.
2614 This command is the same as running C<vgchange -a y|n>");
2616 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [Optional "lvm2"],
2618 "activate or deactivate some volume groups",
2620 This command activates or (if C<activate> is false) deactivates
2621 all logical volumes in the listed volume groups C<volgroups>.
2622 If activated, then they are made known to the
2623 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2624 then those devices disappear.
2626 This command is the same as running C<vgchange -a y|n volgroups...>
2628 Note that if C<volgroups> is an empty list then B<all> volume groups
2629 are activated or deactivated.");
2631 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [Optional "lvm2"],
2632 [InitNone, Always, TestOutput (
2633 [["part_disk"; "/dev/sda"; "mbr"];
2634 ["pvcreate"; "/dev/sda1"];
2635 ["vgcreate"; "VG"; "/dev/sda1"];
2636 ["lvcreate"; "LV"; "VG"; "10"];
2637 ["mkfs"; "ext2"; "/dev/VG/LV"];
2638 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2639 ["write"; "/new"; "test content"];
2641 ["lvresize"; "/dev/VG/LV"; "20"];
2642 ["e2fsck_f"; "/dev/VG/LV"];
2643 ["resize2fs"; "/dev/VG/LV"];
2644 ["mount_options"; ""; "/dev/VG/LV"; "/"];
2645 ["cat"; "/new"]], "test content");
2646 InitNone, Always, TestRun (
2647 (* Make an LV smaller to test RHBZ#587484. *)
2648 [["part_disk"; "/dev/sda"; "mbr"];
2649 ["pvcreate"; "/dev/sda1"];
2650 ["vgcreate"; "VG"; "/dev/sda1"];
2651 ["lvcreate"; "LV"; "VG"; "20"];
2652 ["lvresize"; "/dev/VG/LV"; "10"]])],
2653 "resize an LVM logical volume",
2655 This resizes (expands or shrinks) an existing LVM logical
2656 volume to C<mbytes>. When reducing, data in the reduced part
2659 ("resize2fs", (RErr, [Device "device"]), 106, [],
2660 [], (* lvresize tests this *)
2661 "resize an ext2, ext3 or ext4 filesystem",
2663 This resizes an ext2, ext3 or ext4 filesystem to match the size of
2664 the underlying device.
2666 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2667 on the C<device> before calling this command. For unknown reasons
2668 C<resize2fs> sometimes gives an error about this and sometimes not.
2669 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2670 calling this function.");
2672 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2673 [InitBasicFS, Always, TestOutputList (
2674 [["find"; "/"]], ["lost+found"]);
2675 InitBasicFS, Always, TestOutputList (
2679 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2680 InitBasicFS, Always, TestOutputList (
2681 [["mkdir_p"; "/a/b/c"];
2682 ["touch"; "/a/b/c/d"];
2683 ["find"; "/a/b/"]], ["c"; "c/d"])],
2684 "find all files and directories",
2686 This command lists out all files and directories, recursively,
2687 starting at C<directory>. It is essentially equivalent to
2688 running the shell command C<find directory -print> but some
2689 post-processing happens on the output, described below.
2691 This returns a list of strings I<without any prefix>. Thus
2692 if the directory structure was:
2698 then the returned list from C<guestfs_find> C</tmp> would be
2706 If C<directory> is not a directory, then this command returns
2709 The returned list is sorted.
2711 See also C<guestfs_find0>.");
2713 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2714 [], (* lvresize tests this *)
2715 "check an ext2/ext3 filesystem",
2717 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2718 filesystem checker on C<device>, noninteractively (C<-p>),
2719 even if the filesystem appears to be clean (C<-f>).
2721 This command is only needed because of C<guestfs_resize2fs>
2722 (q.v.). Normally you should use C<guestfs_fsck>.");
2724 ("sleep", (RErr, [Int "secs"]), 109, [],
2725 [InitNone, Always, TestRun (
2727 "sleep for some seconds",
2729 Sleep for C<secs> seconds.");
2731 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [Optional "ntfs3g"],
2732 [InitNone, Always, TestOutputInt (
2733 [["part_disk"; "/dev/sda"; "mbr"];
2734 ["mkfs"; "ntfs"; "/dev/sda1"];
2735 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2736 InitNone, Always, TestOutputInt (
2737 [["part_disk"; "/dev/sda"; "mbr"];
2738 ["mkfs"; "ext2"; "/dev/sda1"];
2739 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2740 "probe NTFS volume",
2742 This command runs the L<ntfs-3g.probe(8)> command which probes
2743 an NTFS C<device> for mountability. (Not all NTFS volumes can
2744 be mounted read-write, and some cannot be mounted at all).
2746 C<rw> is a boolean flag. Set it to true if you want to test
2747 if the volume can be mounted read-write. Set it to false if
2748 you want to test if the volume can be mounted read-only.
2750 The return value is an integer which C<0> if the operation
2751 would succeed, or some non-zero value documented in the
2752 L<ntfs-3g.probe(8)> manual page.");
2754 ("sh", (RString "output", [String "command"]), 111, [],
2755 [], (* XXX needs tests *)
2756 "run a command via the shell",
2758 This call runs a command from the guest filesystem via the
2761 This is like C<guestfs_command>, but passes the command to:
2763 /bin/sh -c \"command\"
2765 Depending on the guest's shell, this usually results in
2766 wildcards being expanded, shell expressions being interpolated
2769 All the provisos about C<guestfs_command> apply to this call.");
2771 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2772 [], (* XXX needs tests *)
2773 "run a command via the shell returning lines",
2775 This is the same as C<guestfs_sh>, but splits the result
2776 into a list of lines.
2778 See also: C<guestfs_command_lines>");
2780 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2781 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2782 * code in stubs.c, since all valid glob patterns must start with "/".
2783 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2785 [InitBasicFS, Always, TestOutputList (
2786 [["mkdir_p"; "/a/b/c"];
2787 ["touch"; "/a/b/c/d"];
2788 ["touch"; "/a/b/c/e"];
2789 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2790 InitBasicFS, Always, TestOutputList (
2791 [["mkdir_p"; "/a/b/c"];
2792 ["touch"; "/a/b/c/d"];
2793 ["touch"; "/a/b/c/e"];
2794 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2795 InitBasicFS, Always, TestOutputList (
2796 [["mkdir_p"; "/a/b/c"];
2797 ["touch"; "/a/b/c/d"];
2798 ["touch"; "/a/b/c/e"];
2799 ["glob_expand"; "/a/*/x/*"]], [])],
2800 "expand a wildcard path",
2802 This command searches for all the pathnames matching
2803 C<pattern> according to the wildcard expansion rules
2806 If no paths match, then this returns an empty list
2807 (note: not an error).
2809 It is just a wrapper around the C L<glob(3)> function
2810 with flags C<GLOB_MARK|GLOB_BRACE>.
2811 See that manual page for more details.");
2813 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson; Optional "scrub"],
2814 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2815 [["scrub_device"; "/dev/sdc"]])],
2816 "scrub (securely wipe) a device",
2818 This command writes patterns over C<device> to make data retrieval
2821 It is an interface to the L<scrub(1)> program. See that
2822 manual page for more details.");
2824 ("scrub_file", (RErr, [Pathname "file"]), 115, [Optional "scrub"],
2825 [InitBasicFS, Always, TestRun (
2826 [["write"; "/file"; "content"];
2827 ["scrub_file"; "/file"]])],
2828 "scrub (securely wipe) a file",
2830 This command writes patterns over a file to make data retrieval
2833 The file is I<removed> after scrubbing.
2835 It is an interface to the L<scrub(1)> program. See that
2836 manual page for more details.");
2838 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [Optional "scrub"],
2839 [], (* XXX needs testing *)
2840 "scrub (securely wipe) free space",
2842 This command creates the directory C<dir> and then fills it
2843 with files until the filesystem is full, and scrubs the files
2844 as for C<guestfs_scrub_file>, and deletes them.
2845 The intention is to scrub any free space on the partition
2848 It is an interface to the L<scrub(1)> program. See that
2849 manual page for more details.");
2851 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2852 [InitBasicFS, Always, TestRun (
2854 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2855 "create a temporary directory",
2857 This command creates a temporary directory. The
2858 C<template> parameter should be a full pathname for the
2859 temporary directory name with the final six characters being
2862 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2863 the second one being suitable for Windows filesystems.
2865 The name of the temporary directory that was created
2868 The temporary directory is created with mode 0700
2869 and is owned by root.
2871 The caller is responsible for deleting the temporary
2872 directory and its contents after use.
2874 See also: L<mkdtemp(3)>");
2876 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2877 [InitISOFS, Always, TestOutputInt (
2878 [["wc_l"; "/10klines"]], 10000);
2879 (* Test for RHBZ#579608, absolute symbolic links. *)
2880 InitISOFS, Always, TestOutputInt (
2881 [["wc_l"; "/abssymlink"]], 10000)],
2882 "count lines in a file",
2884 This command counts the lines in a file, using the
2885 C<wc -l> external command.");
2887 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2888 [InitISOFS, Always, TestOutputInt (
2889 [["wc_w"; "/10klines"]], 10000)],
2890 "count words in a file",
2892 This command counts the words in a file, using the
2893 C<wc -w> external command.");
2895 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2896 [InitISOFS, Always, TestOutputInt (
2897 [["wc_c"; "/100kallspaces"]], 102400)],
2898 "count characters in a file",
2900 This command counts the characters in a file, using the
2901 C<wc -c> external command.");
2903 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2904 [InitISOFS, Always, TestOutputList (
2905 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"]);
2906 (* Test for RHBZ#579608, absolute symbolic links. *)
2907 InitISOFS, Always, TestOutputList (
2908 [["head"; "/abssymlink"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2909 "return first 10 lines of a file",
2911 This command returns up to the first 10 lines of a file as
2912 a list of strings.");
2914 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2915 [InitISOFS, Always, TestOutputList (
2916 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2917 InitISOFS, Always, TestOutputList (
2918 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2919 InitISOFS, Always, TestOutputList (
2920 [["head_n"; "0"; "/10klines"]], [])],
2921 "return first N lines of a file",
2923 If the parameter C<nrlines> is a positive number, this returns the first
2924 C<nrlines> lines of the file C<path>.
2926 If the parameter C<nrlines> is a negative number, this returns lines
2927 from the file C<path>, excluding the last C<nrlines> lines.
2929 If the parameter C<nrlines> is zero, this returns an empty list.");
2931 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2932 [InitISOFS, Always, TestOutputList (
2933 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2934 "return last 10 lines of a file",
2936 This command returns up to the last 10 lines of a file as
2937 a list of strings.");
2939 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2940 [InitISOFS, Always, TestOutputList (
2941 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2942 InitISOFS, Always, TestOutputList (
2943 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2944 InitISOFS, Always, TestOutputList (
2945 [["tail_n"; "0"; "/10klines"]], [])],
2946 "return last N lines of a file",
2948 If the parameter C<nrlines> is a positive number, this returns the last
2949 C<nrlines> lines of the file C<path>.
2951 If the parameter C<nrlines> is a negative number, this returns lines
2952 from the file C<path>, starting with the C<-nrlines>th line.
2954 If the parameter C<nrlines> is zero, this returns an empty list.");
2956 ("df", (RString "output", []), 125, [],
2957 [], (* XXX Tricky to test because it depends on the exact format
2958 * of the 'df' command and other imponderables.
2960 "report file system disk space usage",
2962 This command runs the C<df> command to report disk space used.
2964 This command is mostly useful for interactive sessions. It
2965 is I<not> intended that you try to parse the output string.
2966 Use C<statvfs> from programs.");
2968 ("df_h", (RString "output", []), 126, [],
2969 [], (* XXX Tricky to test because it depends on the exact format
2970 * of the 'df' command and other imponderables.
2972 "report file system disk space usage (human readable)",
2974 This command runs the C<df -h> command to report disk space used
2975 in human-readable format.
2977 This command is mostly useful for interactive sessions. It
2978 is I<not> intended that you try to parse the output string.
2979 Use C<statvfs> from programs.");
2981 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2982 [InitISOFS, Always, TestOutputInt (
2983 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2984 "estimate file space usage",
2986 This command runs the C<du -s> command to estimate file space
2989 C<path> can be a file or a directory. If C<path> is a directory
2990 then the estimate includes the contents of the directory and all
2991 subdirectories (recursively).
2993 The result is the estimated size in I<kilobytes>
2994 (ie. units of 1024 bytes).");
2996 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
2997 [InitISOFS, Always, TestOutputList (
2998 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
2999 "list files in an initrd",
3001 This command lists out files contained in an initrd.
3003 The files are listed without any initial C</> character. The
3004 files are listed in the order they appear (not necessarily
3005 alphabetical). Directory names are listed as separate items.
3007 Old Linux kernels (2.4 and earlier) used a compressed ext2
3008 filesystem as initrd. We I<only> support the newer initramfs
3009 format (compressed cpio files).");
3011 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
3013 "mount a file using the loop device",
3015 This command lets you mount C<file> (a filesystem image
3016 in a file) on a mount point. It is entirely equivalent to
3017 the command C<mount -o loop file mountpoint>.");
3019 ("mkswap", (RErr, [Device "device"]), 130, [],
3020 [InitEmpty, Always, TestRun (
3021 [["part_disk"; "/dev/sda"; "mbr"];
3022 ["mkswap"; "/dev/sda1"]])],
3023 "create a swap partition",
3025 Create a swap partition on C<device>.");
3027 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
3028 [InitEmpty, Always, TestRun (
3029 [["part_disk"; "/dev/sda"; "mbr"];
3030 ["mkswap_L"; "hello"; "/dev/sda1"]])],
3031 "create a swap partition with a label",
3033 Create a swap partition on C<device> with label C<label>.
3035 Note that you cannot attach a swap label to a block device
3036 (eg. C</dev/sda>), just to a partition. This appears to be
3037 a limitation of the kernel or swap tools.");
3039 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [Optional "linuxfsuuid"],
3040 (let uuid = uuidgen () in
3041 [InitEmpty, Always, TestRun (
3042 [["part_disk"; "/dev/sda"; "mbr"];
3043 ["mkswap_U"; uuid; "/dev/sda1"]])]),
3044 "create a swap partition with an explicit UUID",
3046 Create a swap partition on C<device> with UUID C<uuid>.");
3048 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [Optional "mknod"],
3049 [InitBasicFS, Always, TestOutputStruct (
3050 [["mknod"; "0o10777"; "0"; "0"; "/node"];
3051 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
3052 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
3053 InitBasicFS, Always, TestOutputStruct (
3054 [["mknod"; "0o60777"; "66"; "99"; "/node"];
3055 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3056 "make block, character or FIFO devices",
3058 This call creates block or character special devices, or
3059 named pipes (FIFOs).
3061 The C<mode> parameter should be the mode, using the standard
3062 constants. C<devmajor> and C<devminor> are the
3063 device major and minor numbers, only used when creating block
3064 and character special devices.
3066 Note that, just like L<mknod(2)>, the mode must be bitwise
3067 OR'd with S_IFBLK, S_IFCHR, S_IFIFO or S_IFSOCK (otherwise this call
3068 just creates a regular file). These constants are
3069 available in the standard Linux header files, or you can use
3070 C<guestfs_mknod_b>, C<guestfs_mknod_c> or C<guestfs_mkfifo>
3071 which are wrappers around this command which bitwise OR
3072 in the appropriate constant for you.
3074 The mode actually set is affected by the umask.");
3076 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [Optional "mknod"],
3077 [InitBasicFS, Always, TestOutputStruct (
3078 [["mkfifo"; "0o777"; "/node"];
3079 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
3080 "make FIFO (named pipe)",
3082 This call creates a FIFO (named pipe) called C<path> with
3083 mode C<mode>. It is just a convenient wrapper around
3086 The mode actually set is affected by the umask.");
3088 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [Optional "mknod"],
3089 [InitBasicFS, Always, TestOutputStruct (
3090 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
3091 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
3092 "make block device node",
3094 This call creates a block device node called C<path> with
3095 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3096 It is just a convenient wrapper around C<guestfs_mknod>.
3098 The mode actually set is affected by the umask.");
3100 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [Optional "mknod"],
3101 [InitBasicFS, Always, TestOutputStruct (
3102 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
3103 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
3104 "make char device node",
3106 This call creates a char device node called C<path> with
3107 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
3108 It is just a convenient wrapper around C<guestfs_mknod>.
3110 The mode actually set is affected by the umask.");
3112 ("umask", (RInt "oldmask", [Int "mask"]), 137, [FishOutput FishOutputOctal],
3113 [InitEmpty, Always, TestOutputInt (
3114 [["umask"; "0o22"]], 0o22)],
3115 "set file mode creation mask (umask)",
3117 This function sets the mask used for creating new files and
3118 device nodes to C<mask & 0777>.
3120 Typical umask values would be C<022> which creates new files
3121 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
3122 C<002> which creates new files with permissions like
3123 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
3125 The default umask is C<022>. This is important because it
3126 means that directories and device nodes will be created with
3127 C<0644> or C<0755> mode even if you specify C<0777>.
3129 See also C<guestfs_get_umask>,
3130 L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
3132 This call returns the previous umask.");
3134 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
3136 "read directories entries",
3138 This returns the list of directory entries in directory C<dir>.
3140 All entries in the directory are returned, including C<.> and
3141 C<..>. The entries are I<not> sorted, but returned in the same
3142 order as the underlying filesystem.
3144 Also this call returns basic file type information about each
3145 file. The C<ftyp> field will contain one of the following characters:
3183 The L<readdir(3)> call returned a C<d_type> field with an
3188 This function is primarily intended for use by programs. To
3189 get a simple list of names, use C<guestfs_ls>. To get a printable
3190 directory for human consumption, use C<guestfs_ll>.");
3192 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3194 "create partitions on a block device",
3196 This is a simplified interface to the C<guestfs_sfdisk>
3197 command, where partition sizes are specified in megabytes
3198 only (rounded to the nearest cylinder) and you don't need
3199 to specify the cyls, heads and sectors parameters which
3200 were rarely if ever used anyway.
3202 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3203 and C<guestfs_part_disk>");
3205 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3207 "determine file type inside a compressed file",
3209 This command runs C<file> after first decompressing C<path>
3212 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3214 Since 1.0.63, use C<guestfs_file> instead which can now
3215 process compressed files.");
3217 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [Optional "linuxxattrs"],
3219 "list extended attributes of a file or directory",
3221 This call lists the extended attributes of the file or directory
3224 At the system call level, this is a combination of the
3225 L<listxattr(2)> and L<getxattr(2)> calls.
3227 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3229 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [Optional "linuxxattrs"],
3231 "list extended attributes of a file or directory",
3233 This is the same as C<guestfs_getxattrs>, but if C<path>
3234 is a symbolic link, then it returns the extended attributes
3235 of the link itself.");
3237 ("setxattr", (RErr, [String "xattr";
3238 String "val"; Int "vallen"; (* will be BufferIn *)
3239 Pathname "path"]), 143, [Optional "linuxxattrs"],
3241 "set extended attribute of a file or directory",
3243 This call sets the extended attribute named C<xattr>
3244 of the file C<path> to the value C<val> (of length C<vallen>).
3245 The value is arbitrary 8 bit data.
3247 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3249 ("lsetxattr", (RErr, [String "xattr";
3250 String "val"; Int "vallen"; (* will be BufferIn *)
3251 Pathname "path"]), 144, [Optional "linuxxattrs"],
3253 "set extended attribute of a file or directory",
3255 This is the same as C<guestfs_setxattr>, but if C<path>
3256 is a symbolic link, then it sets an extended attribute
3257 of the link itself.");
3259 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [Optional "linuxxattrs"],
3261 "remove extended attribute of a file or directory",
3263 This call removes the extended attribute named C<xattr>
3264 of the file C<path>.
3266 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3268 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [Optional "linuxxattrs"],
3270 "remove extended attribute of a file or directory",
3272 This is the same as C<guestfs_removexattr>, but if C<path>
3273 is a symbolic link, then it removes an extended attribute
3274 of the link itself.");
3276 ("mountpoints", (RHashtable "mps", []), 147, [],
3280 This call is similar to C<guestfs_mounts>. That call returns
3281 a list of devices. This one returns a hash table (map) of
3282 device name to directory where the device is mounted.");
3284 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3285 (* This is a special case: while you would expect a parameter
3286 * of type "Pathname", that doesn't work, because it implies
3287 * NEED_ROOT in the generated calling code in stubs.c, and
3288 * this function cannot use NEED_ROOT.
3291 "create a mountpoint",
3293 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3294 specialized calls that can be used to create extra mountpoints
3295 before mounting the first filesystem.
3297 These calls are I<only> necessary in some very limited circumstances,
3298 mainly the case where you want to mount a mix of unrelated and/or
3299 read-only filesystems together.
3301 For example, live CDs often contain a \"Russian doll\" nest of
3302 filesystems, an ISO outer layer, with a squashfs image inside, with
3303 an ext2/3 image inside that. You can unpack this as follows
3306 add-ro Fedora-11-i686-Live.iso
3309 mkmountpoint /squash
3312 mount-loop /cd/LiveOS/squashfs.img /squash
3313 mount-loop /squash/LiveOS/ext3fs.img /ext3
3315 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3317 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3319 "remove a mountpoint",
3321 This calls removes a mountpoint that was previously created
3322 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3323 for full details.");
3325 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3326 [InitISOFS, Always, TestOutputBuffer (
3327 [["read_file"; "/known-4"]], "abc\ndef\nghi");
3328 (* Test various near large, large and too large files (RHBZ#589039). *)
3329 InitBasicFS, Always, TestLastFail (
3331 ["truncate_size"; "/a"; "4194303"]; (* GUESTFS_MESSAGE_MAX - 1 *)
3332 ["read_file"; "/a"]]);
3333 InitBasicFS, Always, TestLastFail (
3335 ["truncate_size"; "/a"; "4194304"]; (* GUESTFS_MESSAGE_MAX *)
3336 ["read_file"; "/a"]]);
3337 InitBasicFS, Always, TestLastFail (
3339 ["truncate_size"; "/a"; "41943040"]; (* GUESTFS_MESSAGE_MAX * 10 *)
3340 ["read_file"; "/a"]])],
3343 This calls returns the contents of the file C<path> as a
3346 Unlike C<guestfs_cat>, this function can correctly
3347 handle files that contain embedded ASCII NUL characters.
3348 However unlike C<guestfs_download>, this function is limited
3349 in the total size of file that can be handled.");
3351 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3352 [InitISOFS, Always, TestOutputList (
3353 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3354 InitISOFS, Always, TestOutputList (
3355 [["grep"; "nomatch"; "/test-grep.txt"]], []);
3356 (* Test for RHBZ#579608, absolute symbolic links. *)
3357 InitISOFS, Always, TestOutputList (
3358 [["grep"; "nomatch"; "/abssymlink"]], [])],
3359 "return lines matching a pattern",
3361 This calls the external C<grep> program and returns the
3364 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3365 [InitISOFS, Always, TestOutputList (
3366 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3367 "return lines matching a pattern",
3369 This calls the external C<egrep> program and returns the
3372 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3373 [InitISOFS, Always, TestOutputList (
3374 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3375 "return lines matching a pattern",
3377 This calls the external C<fgrep> program and returns the
3380 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3381 [InitISOFS, Always, TestOutputList (
3382 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3383 "return lines matching a pattern",
3385 This calls the external C<grep -i> program and returns the
3388 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3389 [InitISOFS, Always, TestOutputList (
3390 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3391 "return lines matching a pattern",
3393 This calls the external C<egrep -i> program and returns the
3396 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3397 [InitISOFS, Always, TestOutputList (
3398 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3399 "return lines matching a pattern",
3401 This calls the external C<fgrep -i> program and returns the
3404 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3405 [InitISOFS, Always, TestOutputList (
3406 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3407 "return lines matching a pattern",
3409 This calls the external C<zgrep> program and returns the
3412 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3413 [InitISOFS, Always, TestOutputList (
3414 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3415 "return lines matching a pattern",
3417 This calls the external C<zegrep> program and returns the
3420 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3421 [InitISOFS, Always, TestOutputList (
3422 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3423 "return lines matching a pattern",
3425 This calls the external C<zfgrep> program and returns the
3428 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3429 [InitISOFS, Always, TestOutputList (
3430 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3431 "return lines matching a pattern",
3433 This calls the external C<zgrep -i> program and returns the
3436 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3437 [InitISOFS, Always, TestOutputList (
3438 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3439 "return lines matching a pattern",
3441 This calls the external C<zegrep -i> program and returns the
3444 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3445 [InitISOFS, Always, TestOutputList (
3446 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3447 "return lines matching a pattern",
3449 This calls the external C<zfgrep -i> program and returns the
3452 ("realpath", (RString "rpath", [Pathname "path"]), 163, [Optional "realpath"],
3453 [InitISOFS, Always, TestOutput (
3454 [["realpath"; "/../directory"]], "/directory")],
3455 "canonicalized absolute pathname",
3457 Return the canonicalized absolute pathname of C<path>. The
3458 returned path has no C<.>, C<..> or symbolic link path elements.");
3460 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3461 [InitBasicFS, Always, TestOutputStruct (
3464 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3465 "create a hard link",
3467 This command creates a hard link using the C<ln> command.");
3469 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3470 [InitBasicFS, Always, TestOutputStruct (
3473 ["ln_f"; "/a"; "/b"];
3474 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3475 "create a hard link",
3477 This command creates a hard link using the C<ln -f> command.
3478 The C<-f> option removes the link (C<linkname>) if it exists already.");
3480 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3481 [InitBasicFS, Always, TestOutputStruct (
3483 ["ln_s"; "a"; "/b"];
3484 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3485 "create a symbolic link",
3487 This command creates a symbolic link using the C<ln -s> command.");
3489 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3490 [InitBasicFS, Always, TestOutput (
3491 [["mkdir_p"; "/a/b"];
3492 ["touch"; "/a/b/c"];
3493 ["ln_sf"; "../d"; "/a/b/c"];
3494 ["readlink"; "/a/b/c"]], "../d")],
3495 "create a symbolic link",
3497 This command creates a symbolic link using the C<ln -sf> command,
3498 The C<-f> option removes the link (C<linkname>) if it exists already.");
3500 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3501 [] (* XXX tested above *),
3502 "read the target of a symbolic link",
3504 This command reads the target of a symbolic link.");
3506 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [DeprecatedBy "fallocate64"],
3507 [InitBasicFS, Always, TestOutputStruct (
3508 [["fallocate"; "/a"; "1000000"];
3509 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3510 "preallocate a file in the guest filesystem",
3512 This command preallocates a file (containing zero bytes) named
3513 C<path> of size C<len> bytes. If the file exists already, it
3516 Do not confuse this with the guestfish-specific
3517 C<alloc> command which allocates a file in the host and
3518 attaches it as a device.");
3520 ("swapon_device", (RErr, [Device "device"]), 170, [],
3521 [InitPartition, Always, TestRun (
3522 [["mkswap"; "/dev/sda1"];
3523 ["swapon_device"; "/dev/sda1"];
3524 ["swapoff_device"; "/dev/sda1"]])],
3525 "enable swap on device",
3527 This command enables the libguestfs appliance to use the
3528 swap device or partition named C<device>. The increased
3529 memory is made available for all commands, for example
3530 those run using C<guestfs_command> or C<guestfs_sh>.
3532 Note that you should not swap to existing guest swap
3533 partitions unless you know what you are doing. They may
3534 contain hibernation information, or other information that
3535 the guest doesn't want you to trash. You also risk leaking
3536 information about the host to the guest this way. Instead,
3537 attach a new host device to the guest and swap on that.");
3539 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3540 [], (* XXX tested by swapon_device *)
3541 "disable swap on device",
3543 This command disables the libguestfs appliance swap
3544 device or partition named C<device>.
3545 See C<guestfs_swapon_device>.");
3547 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3548 [InitBasicFS, Always, TestRun (
3549 [["fallocate"; "/swap"; "8388608"];
3550 ["mkswap_file"; "/swap"];
3551 ["swapon_file"; "/swap"];
3552 ["swapoff_file"; "/swap"]])],
3553 "enable swap on file",
3555 This command enables swap to a file.
3556 See C<guestfs_swapon_device> for other notes.");
3558 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3559 [], (* XXX tested by swapon_file *)
3560 "disable swap on file",
3562 This command disables the libguestfs appliance swap on file.");
3564 ("swapon_label", (RErr, [String "label"]), 174, [],
3565 [InitEmpty, Always, TestRun (
3566 [["part_disk"; "/dev/sdb"; "mbr"];
3567 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3568 ["swapon_label"; "swapit"];
3569 ["swapoff_label"; "swapit"];
3570 ["zero"; "/dev/sdb"];
3571 ["blockdev_rereadpt"; "/dev/sdb"]])],
3572 "enable swap on labeled swap partition",
3574 This command enables swap to a labeled swap partition.
3575 See C<guestfs_swapon_device> for other notes.");
3577 ("swapoff_label", (RErr, [String "label"]), 175, [],
3578 [], (* XXX tested by swapon_label *)
3579 "disable swap on labeled swap partition",
3581 This command disables the libguestfs appliance swap on
3582 labeled swap partition.");
3584 ("swapon_uuid", (RErr, [String "uuid"]), 176, [Optional "linuxfsuuid"],
3585 (let uuid = uuidgen () in
3586 [InitEmpty, Always, TestRun (
3587 [["mkswap_U"; uuid; "/dev/sdb"];
3588 ["swapon_uuid"; uuid];
3589 ["swapoff_uuid"; uuid]])]),
3590 "enable swap on swap partition by UUID",
3592 This command enables swap to a swap partition with the given UUID.
3593 See C<guestfs_swapon_device> for other notes.");
3595 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [Optional "linuxfsuuid"],
3596 [], (* XXX tested by swapon_uuid *)
3597 "disable swap on swap partition by UUID",
3599 This command disables the libguestfs appliance swap partition
3600 with the given UUID.");
3602 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3603 [InitBasicFS, Always, TestRun (
3604 [["fallocate"; "/swap"; "8388608"];
3605 ["mkswap_file"; "/swap"]])],
3606 "create a swap file",
3610 This command just writes a swap file signature to an existing
3611 file. To create the file itself, use something like C<guestfs_fallocate>.");
3613 ("inotify_init", (RErr, [Int "maxevents"]), 179, [Optional "inotify"],
3614 [InitISOFS, Always, TestRun (
3615 [["inotify_init"; "0"]])],
3616 "create an inotify handle",
3618 This command creates a new inotify handle.
3619 The inotify subsystem can be used to notify events which happen to
3620 objects in the guest filesystem.
3622 C<maxevents> is the maximum number of events which will be
3623 queued up between calls to C<guestfs_inotify_read> or
3624 C<guestfs_inotify_files>.
3625 If this is passed as C<0>, then the kernel (or previously set)
3626 default is used. For Linux 2.6.29 the default was 16384 events.
3627 Beyond this limit, the kernel throws away events, but records
3628 the fact that it threw them away by setting a flag
3629 C<IN_Q_OVERFLOW> in the returned structure list (see
3630 C<guestfs_inotify_read>).
3632 Before any events are generated, you have to add some
3633 watches to the internal watch list. See:
3634 C<guestfs_inotify_add_watch>,
3635 C<guestfs_inotify_rm_watch> and
3636 C<guestfs_inotify_watch_all>.
3638 Queued up events should be read periodically by calling
3639 C<guestfs_inotify_read>
3640 (or C<guestfs_inotify_files> which is just a helpful
3641 wrapper around C<guestfs_inotify_read>). If you don't
3642 read the events out often enough then you risk the internal
3645 The handle should be closed after use by calling
3646 C<guestfs_inotify_close>. This also removes any
3647 watches automatically.
3649 See also L<inotify(7)> for an overview of the inotify interface
3650 as exposed by the Linux kernel, which is roughly what we expose
3651 via libguestfs. Note that there is one global inotify handle
3652 per libguestfs instance.");
3654 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [Optional "inotify"],
3655 [InitBasicFS, Always, TestOutputList (
3656 [["inotify_init"; "0"];
3657 ["inotify_add_watch"; "/"; "1073741823"];
3660 ["inotify_files"]], ["a"; "b"])],
3661 "add an inotify watch",
3663 Watch C<path> for the events listed in C<mask>.
3665 Note that if C<path> is a directory then events within that
3666 directory are watched, but this does I<not> happen recursively
3667 (in subdirectories).
3669 Note for non-C or non-Linux callers: the inotify events are
3670 defined by the Linux kernel ABI and are listed in
3671 C</usr/include/sys/inotify.h>.");
3673 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [Optional "inotify"],
3675 "remove an inotify watch",
3677 Remove a previously defined inotify watch.
3678 See C<guestfs_inotify_add_watch>.");
3680 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [Optional "inotify"],
3682 "return list of inotify events",
3684 Return the complete queue of events that have happened
3685 since the previous read call.
3687 If no events have happened, this returns an empty list.
3689 I<Note>: In order to make sure that all events have been
3690 read, you must call this function repeatedly until it
3691 returns an empty list. The reason is that the call will
3692 read events up to the maximum appliance-to-host message
3693 size and leave remaining events in the queue.");
3695 ("inotify_files", (RStringList "paths", []), 183, [Optional "inotify"],
3697 "return list of watched files that had events",
3699 This function is a helpful wrapper around C<guestfs_inotify_read>
3700 which just returns a list of pathnames of objects that were
3701 touched. The returned pathnames are sorted and deduplicated.");
3703 ("inotify_close", (RErr, []), 184, [Optional "inotify"],
3705 "close the inotify handle",
3707 This closes the inotify handle which was previously
3708 opened by inotify_init. It removes all watches, throws
3709 away any pending events, and deallocates all resources.");
3711 ("setcon", (RErr, [String "context"]), 185, [Optional "selinux"],
3713 "set SELinux security context",
3715 This sets the SELinux security context of the daemon
3716 to the string C<context>.
3718 See the documentation about SELINUX in L<guestfs(3)>.");
3720 ("getcon", (RString "context", []), 186, [Optional "selinux"],
3722 "get SELinux security context",
3724 This gets the SELinux security context of the daemon.
3726 See the documentation about SELINUX in L<guestfs(3)>,
3727 and C<guestfs_setcon>");
3729 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3730 [InitEmpty, Always, TestOutput (
3731 [["part_disk"; "/dev/sda"; "mbr"];
3732 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3733 ["mount_options"; ""; "/dev/sda1"; "/"];
3734 ["write"; "/new"; "new file contents"];
3735 ["cat"; "/new"]], "new file contents")],
3736 "make a filesystem with block size",
3738 This call is similar to C<guestfs_mkfs>, but it allows you to
3739 control the block size of the resulting filesystem. Supported
3740 block sizes depend on the filesystem type, but typically they
3741 are C<1024>, C<2048> or C<4096> only.");
3743 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3744 [InitEmpty, Always, TestOutput (
3745 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3746 ["mke2journal"; "4096"; "/dev/sda1"];
3747 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3748 ["mount_options"; ""; "/dev/sda2"; "/"];
3749 ["write"; "/new"; "new file contents"];
3750 ["cat"; "/new"]], "new file contents")],
3751 "make ext2/3/4 external journal",
3753 This creates an ext2 external journal on C<device>. It is equivalent
3756 mke2fs -O journal_dev -b blocksize device");
3758 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3759 [InitEmpty, Always, TestOutput (
3760 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3761 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3762 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3763 ["mount_options"; ""; "/dev/sda2"; "/"];
3764 ["write"; "/new"; "new file contents"];
3765 ["cat"; "/new"]], "new file contents")],
3766 "make ext2/3/4 external journal with label",
3768 This creates an ext2 external journal on C<device> with label C<label>.");
3770 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [Optional "linuxfsuuid"],
3771 (let uuid = uuidgen () in
3772 [InitEmpty, Always, TestOutput (
3773 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3774 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3775 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3776 ["mount_options"; ""; "/dev/sda2"; "/"];
3777 ["write"; "/new"; "new file contents"];
3778 ["cat"; "/new"]], "new file contents")]),
3779 "make ext2/3/4 external journal with UUID",
3781 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3783 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3785 "make ext2/3/4 filesystem with external journal",
3787 This creates an ext2/3/4 filesystem on C<device> with
3788 an external journal on C<journal>. It is equivalent
3791 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3793 See also C<guestfs_mke2journal>.");
3795 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3797 "make ext2/3/4 filesystem with external journal",
3799 This creates an ext2/3/4 filesystem on C<device> with
3800 an external journal on the journal labeled C<label>.
3802 See also C<guestfs_mke2journal_L>.");
3804 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [Optional "linuxfsuuid"],
3806 "make ext2/3/4 filesystem with external journal",
3808 This creates an ext2/3/4 filesystem on C<device> with
3809 an external journal on the journal with UUID C<uuid>.
3811 See also C<guestfs_mke2journal_U>.");
3813 ("modprobe", (RErr, [String "modulename"]), 194, [Optional "linuxmodules"],
3814 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3815 "load a kernel module",
3817 This loads a kernel module in the appliance.
3819 The kernel module must have been whitelisted when libguestfs
3820 was built (see C<appliance/kmod.whitelist.in> in the source).");
3822 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3823 [InitNone, Always, TestOutput (
3824 [["echo_daemon"; "This is a test"]], "This is a test"
3826 "echo arguments back to the client",
3828 This command concatenates the list of C<words> passed with single spaces
3829 between them and returns the resulting string.
3831 You can use this command to test the connection through to the daemon.
3833 See also C<guestfs_ping_daemon>.");
3835 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3836 [], (* There is a regression test for this. *)
3837 "find all files and directories, returning NUL-separated list",
3839 This command lists out all files and directories, recursively,
3840 starting at C<directory>, placing the resulting list in the
3841 external file called C<files>.
3843 This command works the same way as C<guestfs_find> with the
3844 following exceptions:
3850 The resulting list is written to an external file.
3854 Items (filenames) in the result are separated
3855 by C<\\0> characters. See L<find(1)> option I<-print0>.
3859 This command is not limited in the number of names that it
3864 The result list is not sorted.
3868 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3869 [InitISOFS, Always, TestOutput (
3870 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3871 InitISOFS, Always, TestOutput (
3872 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3873 InitISOFS, Always, TestOutput (
3874 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3875 InitISOFS, Always, TestLastFail (
3876 [["case_sensitive_path"; "/Known-1/"]]);
3877 InitBasicFS, Always, TestOutput (
3879 ["mkdir"; "/a/bbb"];
3880 ["touch"; "/a/bbb/c"];
3881 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3882 InitBasicFS, Always, TestOutput (
3884 ["mkdir"; "/a/bbb"];
3885 ["touch"; "/a/bbb/c"];
3886 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3887 InitBasicFS, Always, TestLastFail (
3889 ["mkdir"; "/a/bbb"];
3890 ["touch"; "/a/bbb/c"];
3891 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3892 "return true path on case-insensitive filesystem",
3894 This can be used to resolve case insensitive paths on
3895 a filesystem which is case sensitive. The use case is
3896 to resolve paths which you have read from Windows configuration
3897 files or the Windows Registry, to the true path.
3899 The command handles a peculiarity of the Linux ntfs-3g
3900 filesystem driver (and probably others), which is that although
3901 the underlying filesystem is case-insensitive, the driver
3902 exports the filesystem to Linux as case-sensitive.
3904 One consequence of this is that special directories such
3905 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3906 (or other things) depending on the precise details of how
3907 they were created. In Windows itself this would not be
3910 Bug or feature? You decide:
3911 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3913 This function resolves the true case of each element in the
3914 path and returns the case-sensitive path.
3916 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3917 might return C<\"/WINDOWS/system32\"> (the exact return value
3918 would depend on details of how the directories were originally
3919 created under Windows).
3922 This function does not handle drive names, backslashes etc.
3924 See also C<guestfs_realpath>.");
3926 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3927 [InitBasicFS, Always, TestOutput (
3928 [["vfs_type"; "/dev/sda1"]], "ext2")],
3929 "get the Linux VFS type corresponding to a mounted device",
3931 This command gets the filesystem type corresponding to
3932 the filesystem on C<device>.
3934 For most filesystems, the result is the name of the Linux
3935 VFS module which would be used to mount this filesystem
3936 if you mounted it without specifying the filesystem type.
3937 For example a string such as C<ext3> or C<ntfs>.");
3939 ("truncate", (RErr, [Pathname "path"]), 199, [],
3940 [InitBasicFS, Always, TestOutputStruct (
3941 [["write"; "/test"; "some stuff so size is not zero"];
3942 ["truncate"; "/test"];
3943 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3944 "truncate a file to zero size",
3946 This command truncates C<path> to a zero-length file. The
3947 file must exist already.");
3949 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3950 [InitBasicFS, Always, TestOutputStruct (
3951 [["touch"; "/test"];
3952 ["truncate_size"; "/test"; "1000"];
3953 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3954 "truncate a file to a particular size",
3956 This command truncates C<path> to size C<size> bytes. The file
3959 If the current file size is less than C<size> then
3960 the file is extended to the required size with zero bytes.
3961 This creates a sparse file (ie. disk blocks are not allocated
3962 for the file until you write to it). To create a non-sparse
3963 file of zeroes, use C<guestfs_fallocate64> instead.");
3965 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3966 [InitBasicFS, Always, TestOutputStruct (
3967 [["touch"; "/test"];
3968 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3969 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3970 "set timestamp of a file with nanosecond precision",
3972 This command sets the timestamps of a file with nanosecond
3975 C<atsecs, atnsecs> are the last access time (atime) in secs and
3976 nanoseconds from the epoch.
3978 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3979 secs and nanoseconds from the epoch.
3981 If the C<*nsecs> field contains the special value C<-1> then
3982 the corresponding timestamp is set to the current time. (The
3983 C<*secs> field is ignored in this case).
3985 If the C<*nsecs> field contains the special value C<-2> then
3986 the corresponding timestamp is left unchanged. (The
3987 C<*secs> field is ignored in this case).");
3989 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
3990 [InitBasicFS, Always, TestOutputStruct (
3991 [["mkdir_mode"; "/test"; "0o111"];
3992 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
3993 "create a directory with a particular mode",
3995 This command creates a directory, setting the initial permissions
3996 of the directory to C<mode>.
3998 For common Linux filesystems, the actual mode which is set will
3999 be C<mode & ~umask & 01777>. Non-native-Linux filesystems may
4000 interpret the mode in other ways.
4002 See also C<guestfs_mkdir>, C<guestfs_umask>");
4004 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
4006 "change file owner and group",
4008 Change the file owner to C<owner> and group to C<group>.
4009 This is like C<guestfs_chown> but if C<path> is a symlink then
4010 the link itself is changed, not the target.
4012 Only numeric uid and gid are supported. If you want to use
4013 names, you will need to locate and parse the password file
4014 yourself (Augeas support makes this relatively easy).");
4016 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
4018 "lstat on multiple files",
4020 This call allows you to perform the C<guestfs_lstat> operation
4021 on multiple files, where all files are in the directory C<path>.
4022 C<names> is the list of files from this directory.
4024 On return you get a list of stat structs, with a one-to-one
4025 correspondence to the C<names> list. If any name did not exist
4026 or could not be lstat'd, then the C<ino> field of that structure
4029 This call is intended for programs that want to efficiently
4030 list a directory contents without making many round-trips.
4031 See also C<guestfs_lxattrlist> for a similarly efficient call
4032 for getting extended attributes. Very long directory listings
4033 might cause the protocol message size to be exceeded, causing
4034 this call to fail. The caller must split up such requests
4035 into smaller groups of names.");
4037 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [Optional "linuxxattrs"],
4039 "lgetxattr on multiple files",
4041 This call allows you to get the extended attributes
4042 of multiple files, where all files are in the directory C<path>.
4043 C<names> is the list of files from this directory.
4045 On return you get a flat list of xattr structs which must be
4046 interpreted sequentially. The first xattr struct always has a zero-length
4047 C<attrname>. C<attrval> in this struct is zero-length
4048 to indicate there was an error doing C<lgetxattr> for this
4049 file, I<or> is a C string which is a decimal number
4050 (the number of following attributes for this file, which could
4051 be C<\"0\">). Then after the first xattr struct are the
4052 zero or more attributes for the first named file.
4053 This repeats for the second and subsequent files.
4055 This call is intended for programs that want to efficiently
4056 list a directory contents without making many round-trips.
4057 See also C<guestfs_lstatlist> for a similarly efficient call
4058 for getting standard stats. Very long directory listings
4059 might cause the protocol message size to be exceeded, causing
4060 this call to fail. The caller must split up such requests
4061 into smaller groups of names.");
4063 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
4065 "readlink on multiple files",
4067 This call allows you to do a C<readlink> operation
4068 on multiple files, where all files are in the directory C<path>.
4069 C<names> is the list of files from this directory.
4071 On return you get a list of strings, with a one-to-one
4072 correspondence to the C<names> list. Each string is the
4073 value of the symbolic link.
4075 If the C<readlink(2)> operation fails on any name, then
4076 the corresponding result string is the empty string C<\"\">.
4077 However the whole operation is completed even if there
4078 were C<readlink(2)> errors, and so you can call this
4079 function with names where you don't know if they are
4080 symbolic links already (albeit slightly less efficient).
4082 This call is intended for programs that want to efficiently
4083 list a directory contents without making many round-trips.
4084 Very long directory listings might cause the protocol
4085 message size to be exceeded, causing
4086 this call to fail. The caller must split up such requests
4087 into smaller groups of names.");
4089 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
4090 [InitISOFS, Always, TestOutputBuffer (
4091 [["pread"; "/known-4"; "1"; "3"]], "\n");
4092 InitISOFS, Always, TestOutputBuffer (
4093 [["pread"; "/empty"; "0"; "100"]], "")],
4094 "read part of a file",
4096 This command lets you read part of a file. It reads C<count>
4097 bytes of the file, starting at C<offset>, from file C<path>.
4099 This may read fewer bytes than requested. For further details
4100 see the L<pread(2)> system call.
4102 See also C<guestfs_pwrite>.");
4104 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
4105 [InitEmpty, Always, TestRun (
4106 [["part_init"; "/dev/sda"; "gpt"]])],
4107 "create an empty partition table",
4109 This creates an empty partition table on C<device> of one of the
4110 partition types listed below. Usually C<parttype> should be
4111 either C<msdos> or C<gpt> (for large disks).
4113 Initially there are no partitions. Following this, you should
4114 call C<guestfs_part_add> for each partition required.
4116 Possible values for C<parttype> are:
4120 =item B<efi> | B<gpt>
4122 Intel EFI / GPT partition table.
4124 This is recommended for >= 2 TB partitions that will be accessed
4125 from Linux and Intel-based Mac OS X. It also has limited backwards
4126 compatibility with the C<mbr> format.
4128 =item B<mbr> | B<msdos>
4130 The standard PC \"Master Boot Record\" (MBR) format used
4131 by MS-DOS and Windows. This partition type will B<only> work
4132 for device sizes up to 2 TB. For large disks we recommend
4137 Other partition table types that may work but are not
4146 =item B<amiga> | B<rdb>
4148 Amiga \"Rigid Disk Block\" format.
4156 DASD, used on IBM mainframes.
4164 Old Mac partition format. Modern Macs use C<gpt>.
4168 NEC PC-98 format, common in Japan apparently.
4176 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
4177 [InitEmpty, Always, TestRun (
4178 [["part_init"; "/dev/sda"; "mbr"];
4179 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
4180 InitEmpty, Always, TestRun (
4181 [["part_init"; "/dev/sda"; "gpt"];
4182 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
4183 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
4184 InitEmpty, Always, TestRun (
4185 [["part_init"; "/dev/sda"; "mbr"];
4186 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
4187 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
4188 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
4189 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
4190 "add a partition to the device",
4192 This command adds a partition to C<device>. If there is no partition
4193 table on the device, call C<guestfs_part_init> first.
4195 The C<prlogex> parameter is the type of partition. Normally you
4196 should pass C<p> or C<primary> here, but MBR partition tables also
4197 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4200 C<startsect> and C<endsect> are the start and end of the partition
4201 in I<sectors>. C<endsect> may be negative, which means it counts
4202 backwards from the end of the disk (C<-1> is the last sector).
4204 Creating a partition which covers the whole disk is not so easy.
4205 Use C<guestfs_part_disk> to do that.");
4207 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4208 [InitEmpty, Always, TestRun (
4209 [["part_disk"; "/dev/sda"; "mbr"]]);
4210 InitEmpty, Always, TestRun (
4211 [["part_disk"; "/dev/sda"; "gpt"]])],
4212 "partition whole disk with a single primary partition",
4214 This command is simply a combination of C<guestfs_part_init>
4215 followed by C<guestfs_part_add> to create a single primary partition
4216 covering the whole disk.
4218 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4219 but other possible values are described in C<guestfs_part_init>.");
4221 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4222 [InitEmpty, Always, TestRun (
4223 [["part_disk"; "/dev/sda"; "mbr"];
4224 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4225 "make a partition bootable",
4227 This sets the bootable flag on partition numbered C<partnum> on
4228 device C<device>. Note that partitions are numbered from 1.
4230 The bootable flag is used by some operating systems (notably
4231 Windows) to determine which partition to boot from. It is by
4232 no means universally recognized.");
4234 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4235 [InitEmpty, Always, TestRun (
4236 [["part_disk"; "/dev/sda"; "gpt"];
4237 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4238 "set partition name",
4240 This sets the partition name on partition numbered C<partnum> on
4241 device C<device>. Note that partitions are numbered from 1.
4243 The partition name can only be set on certain types of partition
4244 table. This works on C<gpt> but not on C<mbr> partitions.");
4246 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4247 [], (* XXX Add a regression test for this. *)
4248 "list partitions on a device",
4250 This command parses the partition table on C<device> and
4251 returns the list of partitions found.
4253 The fields in the returned structure are:
4259 Partition number, counting from 1.
4263 Start of the partition I<in bytes>. To get sectors you have to
4264 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4268 End of the partition in bytes.
4272 Size of the partition in bytes.
4276 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4277 [InitEmpty, Always, TestOutput (
4278 [["part_disk"; "/dev/sda"; "gpt"];
4279 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4280 "get the partition table type",
4282 This command examines the partition table on C<device> and
4283 returns the partition table type (format) being used.
4285 Common return values include: C<msdos> (a DOS/Windows style MBR
4286 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4287 values are possible, although unusual. See C<guestfs_part_init>
4290 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4291 [InitBasicFS, Always, TestOutputBuffer (
4292 [["fill"; "0x63"; "10"; "/test"];
4293 ["read_file"; "/test"]], "cccccccccc")],
4294 "fill a file with octets",
4296 This command creates a new file called C<path>. The initial
4297 content of the file is C<len> octets of C<c>, where C<c>
4298 must be a number in the range C<[0..255]>.
4300 To fill a file with zero bytes (sparsely), it is
4301 much more efficient to use C<guestfs_truncate_size>.
4302 To create a file with a pattern of repeating bytes
4303 use C<guestfs_fill_pattern>.");
4305 ("available", (RErr, [StringList "groups"]), 216, [],
4306 [InitNone, Always, TestRun [["available"; ""]]],
4307 "test availability of some parts of the API",
4309 This command is used to check the availability of some
4310 groups of functionality in the appliance, which not all builds of
4311 the libguestfs appliance will be able to provide.
4313 The libguestfs groups, and the functions that those
4314 groups correspond to, are listed in L<guestfs(3)/AVAILABILITY>.
4315 You can also fetch this list at runtime by calling
4316 C<guestfs_available_all_groups>.
4318 The argument C<groups> is a list of group names, eg:
4319 C<[\"inotify\", \"augeas\"]> would check for the availability of
4320 the Linux inotify functions and Augeas (configuration file
4323 The command returns no error if I<all> requested groups are available.
4325 It fails with an error if one or more of the requested
4326 groups is unavailable in the appliance.
4328 If an unknown group name is included in the
4329 list of groups then an error is always returned.
4337 You must call C<guestfs_launch> before calling this function.
4339 The reason is because we don't know what groups are
4340 supported by the appliance/daemon until it is running and can
4345 If a group of functions is available, this does not necessarily
4346 mean that they will work. You still have to check for errors
4347 when calling individual API functions even if they are
4352 It is usually the job of distro packagers to build
4353 complete functionality into the libguestfs appliance.
4354 Upstream libguestfs, if built from source with all
4355 requirements satisfied, will support everything.
4359 This call was added in version C<1.0.80>. In previous
4360 versions of libguestfs all you could do would be to speculatively
4361 execute a command to find out if the daemon implemented it.
4362 See also C<guestfs_version>.
4366 ("dd", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"]), 217, [],
4367 [InitBasicFS, Always, TestOutputBuffer (
4368 [["write"; "/src"; "hello, world"];
4369 ["dd"; "/src"; "/dest"];
4370 ["read_file"; "/dest"]], "hello, world")],
4371 "copy from source to destination using dd",
4373 This command copies from one source device or file C<src>
4374 to another destination device or file C<dest>. Normally you
4375 would use this to copy to or from a device or partition, for
4376 example to duplicate a filesystem.
4378 If the destination is a device, it must be as large or larger
4379 than the source file or device, otherwise the copy will fail.
4380 This command cannot do partial copies (see C<guestfs_copy_size>).");
4382 ("filesize", (RInt64 "size", [Pathname "file"]), 218, [],
4383 [InitBasicFS, Always, TestOutputInt (
4384 [["write"; "/file"; "hello, world"];
4385 ["filesize"; "/file"]], 12)],
4386 "return the size of the file in bytes",
4388 This command returns the size of C<file> in bytes.
4390 To get other stats about a file, use C<guestfs_stat>, C<guestfs_lstat>,
4391 C<guestfs_is_dir>, C<guestfs_is_file> etc.
4392 To get the size of block devices, use C<guestfs_blockdev_getsize64>.");
4394 ("lvrename", (RErr, [String "logvol"; String "newlogvol"]), 219, [],
4395 [InitBasicFSonLVM, Always, TestOutputList (
4396 [["lvrename"; "/dev/VG/LV"; "/dev/VG/LV2"];
4397 ["lvs"]], ["/dev/VG/LV2"])],
4398 "rename an LVM logical volume",
4400 Rename a logical volume C<logvol> with the new name C<newlogvol>.");
4402 ("vgrename", (RErr, [String "volgroup"; String "newvolgroup"]), 220, [],
4403 [InitBasicFSonLVM, Always, TestOutputList (
4405 ["vg_activate"; "false"; "VG"];
4406 ["vgrename"; "VG"; "VG2"];
4407 ["vg_activate"; "true"; "VG2"];
4408 ["mount_options"; ""; "/dev/VG2/LV"; "/"];
4409 ["vgs"]], ["VG2"])],
4410 "rename an LVM volume group",
4412 Rename a volume group C<volgroup> with the new name C<newvolgroup>.");
4414 ("initrd_cat", (RBufferOut "content", [Pathname "initrdpath"; String "filename"]), 221, [ProtocolLimitWarning],
4415 [InitISOFS, Always, TestOutputBuffer (
4416 [["initrd_cat"; "/initrd"; "known-4"]], "abc\ndef\nghi")],
4417 "list the contents of a single file in an initrd",
4419 This command unpacks the file C<filename> from the initrd file
4420 called C<initrdpath>. The filename must be given I<without> the
4421 initial C</> character.
4423 For example, in guestfish you could use the following command
4424 to examine the boot script (usually called C</init>)
4425 contained in a Linux initrd or initramfs image:
4427 initrd-cat /boot/initrd-<version>.img init
4429 See also C<guestfs_initrd_list>.");
4431 ("pvuuid", (RString "uuid", [Device "device"]), 222, [],
4433 "get the UUID of a physical volume",
4435 This command returns the UUID of the LVM PV C<device>.");
4437 ("vguuid", (RString "uuid", [String "vgname"]), 223, [],
4439 "get the UUID of a volume group",
4441 This command returns the UUID of the LVM VG named C<vgname>.");
4443 ("lvuuid", (RString "uuid", [Device "device"]), 224, [],
4445 "get the UUID of a logical volume",
4447 This command returns the UUID of the LVM LV C<device>.");
4449 ("vgpvuuids", (RStringList "uuids", [String "vgname"]), 225, [],
4451 "get the PV UUIDs containing the volume group",
4453 Given a VG called C<vgname>, this returns the UUIDs of all
4454 the physical volumes that this volume group resides on.
4456 You can use this along with C<guestfs_pvs> and C<guestfs_pvuuid>
4457 calls to associate physical volumes and volume groups.
4459 See also C<guestfs_vglvuuids>.");
4461 ("vglvuuids", (RStringList "uuids", [String "vgname"]), 226, [],
4463 "get the LV UUIDs of all LVs in the volume group",
4465 Given a VG called C<vgname>, this returns the UUIDs of all
4466 the logical volumes created in this volume group.
4468 You can use this along with C<guestfs_lvs> and C<guestfs_lvuuid>
4469 calls to associate logical volumes and volume groups.
4471 See also C<guestfs_vgpvuuids>.");
4473 ("copy_size", (RErr, [Dev_or_Path "src"; Dev_or_Path "dest"; Int64 "size"]), 227, [],
4474 [InitBasicFS, Always, TestOutputBuffer (
4475 [["write"; "/src"; "hello, world"];
4476 ["copy_size"; "/src"; "/dest"; "5"];
4477 ["read_file"; "/dest"]], "hello")],
4478 "copy size bytes from source to destination using dd",
4480 This command copies exactly C<size> bytes from one source device
4481 or file C<src> to another destination device or file C<dest>.
4483 Note this will fail if the source is too short or if the destination
4484 is not large enough.");
4486 ("zero_device", (RErr, [Device "device"]), 228, [DangerWillRobinson],
4487 [InitBasicFSonLVM, Always, TestRun (
4488 [["zero_device"; "/dev/VG/LV"]])],
4489 "write zeroes to an entire device",
4491 This command writes zeroes over the entire C<device>. Compare
4492 with C<guestfs_zero> which just zeroes the first few blocks of
4495 ("txz_in", (RErr, [FileIn "tarball"; Pathname "directory"]), 229, [Optional "xz"],
4496 [InitBasicFS, Always, TestOutput (
4497 [["txz_in"; "../images/helloworld.tar.xz"; "/"];
4498 ["cat"; "/hello"]], "hello\n")],
4499 "unpack compressed tarball to directory",
4501 This command uploads and unpacks local file C<tarball> (an
4502 I<xz compressed> tar file) into C<directory>.");
4504 ("txz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 230, [Optional "xz"],
4506 "pack directory into compressed tarball",
4508 This command packs the contents of C<directory> and downloads
4509 it to local file C<tarball> (as an xz compressed tar archive).");
4511 ("ntfsresize", (RErr, [Device "device"]), 231, [Optional "ntfsprogs"],
4513 "resize an NTFS filesystem",
4515 This command resizes an NTFS filesystem, expanding or
4516 shrinking it to the size of the underlying device.
4517 See also L<ntfsresize(8)>.");
4519 ("vgscan", (RErr, []), 232, [],
4520 [InitEmpty, Always, TestRun (
4522 "rescan for LVM physical volumes, volume groups and logical volumes",
4524 This rescans all block devices and rebuilds the list of LVM
4525 physical volumes, volume groups and logical volumes.");
4527 ("part_del", (RErr, [Device "device"; Int "partnum"]), 233, [],
4528 [InitEmpty, Always, TestRun (
4529 [["part_init"; "/dev/sda"; "mbr"];
4530 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4531 ["part_del"; "/dev/sda"; "1"]])],
4532 "delete a partition",
4534 This command deletes the partition numbered C<partnum> on C<device>.
4536 Note that in the case of MBR partitioning, deleting an
4537 extended partition also deletes any logical partitions
4540 ("part_get_bootable", (RBool "bootable", [Device "device"; Int "partnum"]), 234, [],
4541 [InitEmpty, Always, TestOutputTrue (
4542 [["part_init"; "/dev/sda"; "mbr"];
4543 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4544 ["part_set_bootable"; "/dev/sda"; "1"; "true"];
4545 ["part_get_bootable"; "/dev/sda"; "1"]])],
4546 "return true if a partition is bootable",
4548 This command returns true if the partition C<partnum> on
4549 C<device> has the bootable flag set.
4551 See also C<guestfs_part_set_bootable>.");
4553 ("part_get_mbr_id", (RInt "idbyte", [Device "device"; Int "partnum"]), 235, [FishOutput FishOutputHexadecimal],
4554 [InitEmpty, Always, TestOutputInt (
4555 [["part_init"; "/dev/sda"; "mbr"];
4556 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"];
4557 ["part_set_mbr_id"; "/dev/sda"; "1"; "0x7f"];
4558 ["part_get_mbr_id"; "/dev/sda"; "1"]], 0x7f)],
4559 "get the MBR type byte (ID byte) from a partition",
4561 Returns the MBR type byte (also known as the ID byte) from
4562 the numbered partition C<partnum>.
4564 Note that only MBR (old DOS-style) partitions have type bytes.
4565 You will get undefined results for other partition table
4566 types (see C<guestfs_part_get_parttype>).");
4568 ("part_set_mbr_id", (RErr, [Device "device"; Int "partnum"; Int "idbyte"]), 236, [],
4569 [], (* tested by part_get_mbr_id *)
4570 "set the MBR type byte (ID byte) of a partition",
4572 Sets the MBR type byte (also known as the ID byte) of
4573 the numbered partition C<partnum> to C<idbyte>. Note
4574 that the type bytes quoted in most documentation are
4575 in fact hexadecimal numbers, but usually documented
4576 without any leading \"0x\" which might be confusing.
4578 Note that only MBR (old DOS-style) partitions have type bytes.
4579 You will get undefined results for other partition table
4580 types (see C<guestfs_part_get_parttype>).");
4582 ("checksum_device", (RString "checksum", [String "csumtype"; Device "device"]), 237, [],
4583 [InitISOFS, Always, TestOutput (
4584 [["checksum_device"; "md5"; "/dev/sdd"]],
4585 (Digest.to_hex (Digest.file "images/test.iso")))],
4586 "compute MD5, SHAx or CRC checksum of the contents of a device",
4588 This call computes the MD5, SHAx or CRC checksum of the
4589 contents of the device named C<device>. For the types of
4590 checksums supported see the C<guestfs_checksum> command.");
4592 ("lvresize_free", (RErr, [Device "lv"; Int "percent"]), 238, [Optional "lvm2"],
4593 [InitNone, Always, TestRun (
4594 [["part_disk"; "/dev/sda"; "mbr"];
4595 ["pvcreate"; "/dev/sda1"];
4596 ["vgcreate"; "VG"; "/dev/sda1"];
4597 ["lvcreate"; "LV"; "VG"; "10"];
4598 ["lvresize_free"; "/dev/VG/LV"; "100"]])],
4599 "expand an LV to fill free space",
4601 This expands an existing logical volume C<lv> so that it fills
4602 C<pc>% of the remaining free space in the volume group. Commonly
4603 you would call this with pc = 100 which expands the logical volume
4604 as much as possible, using all remaining free space in the volume
4607 ("aug_clear", (RErr, [String "augpath"]), 239, [Optional "augeas"],
4608 [], (* XXX Augeas code needs tests. *)
4609 "clear Augeas path",
4611 Set the value associated with C<path> to C<NULL>. This
4612 is the same as the L<augtool(1)> C<clear> command.");
4614 ("get_umask", (RInt "mask", []), 240, [FishOutput FishOutputOctal],
4615 [InitEmpty, Always, TestOutputInt (
4616 [["get_umask"]], 0o22)],
4617 "get the current umask",
4619 Return the current umask. By default the umask is C<022>
4620 unless it has been set by calling C<guestfs_umask>.");
4622 ("debug_upload", (RErr, [FileIn "filename"; String "tmpname"; Int "mode"]), 241, [],
4624 "upload a file to the appliance (internal use only)",
4626 The C<guestfs_debug_upload> command uploads a file to
4627 the libguestfs appliance.
4629 There is no comprehensive help for this command. You have
4630 to look at the file C<daemon/debug.c> in the libguestfs source
4631 to find out what it is for.");
4633 ("base64_in", (RErr, [FileIn "base64file"; Pathname "filename"]), 242, [],
4634 [InitBasicFS, Always, TestOutput (
4635 [["base64_in"; "../images/hello.b64"; "/hello"];
4636 ["cat"; "/hello"]], "hello\n")],
4637 "upload base64-encoded data to file",
4639 This command uploads base64-encoded data from C<base64file>
4642 ("base64_out", (RErr, [Pathname "filename"; FileOut "base64file"]), 243, [],
4644 "download file and encode as base64",
4646 This command downloads the contents of C<filename>, writing
4647 it out to local file C<base64file> encoded as base64.");
4649 ("checksums_out", (RErr, [String "csumtype"; Pathname "directory"; FileOut "sumsfile"]), 244, [],
4651 "compute MD5, SHAx or CRC checksum of files in a directory",
4653 This command computes the checksums of all regular files in
4654 C<directory> and then emits a list of those checksums to
4655 the local output file C<sumsfile>.
4657 This can be used for verifying the integrity of a virtual
4658 machine. However to be properly secure you should pay
4659 attention to the output of the checksum command (it uses
4660 the ones from GNU coreutils). In particular when the
4661 filename is not printable, coreutils uses a special
4662 backslash syntax. For more information, see the GNU
4663 coreutils info file.");
4665 ("fill_pattern", (RErr, [String "pattern"; Int "len"; Pathname "path"]), 245, [],
4666 [InitBasicFS, Always, TestOutputBuffer (
4667 [["fill_pattern"; "abcdefghijklmnopqrstuvwxyz"; "28"; "/test"];
4668 ["read_file"; "/test"]], "abcdefghijklmnopqrstuvwxyzab")],
4669 "fill a file with a repeating pattern of bytes",
4671 This function is like C<guestfs_fill> except that it creates
4672 a new file of length C<len> containing the repeating pattern
4673 of bytes in C<pattern>. The pattern is truncated if necessary
4674 to ensure the length of the file is exactly C<len> bytes.");
4676 ("write", (RErr, [Pathname "path"; BufferIn "content"]), 246, [ProtocolLimitWarning],
4677 [InitBasicFS, Always, TestOutput (
4678 [["write"; "/new"; "new file contents"];
4679 ["cat"; "/new"]], "new file contents");
4680 InitBasicFS, Always, TestOutput (
4681 [["write"; "/new"; "\nnew file contents\n"];
4682 ["cat"; "/new"]], "\nnew file contents\n");
4683 InitBasicFS, Always, TestOutput (
4684 [["write"; "/new"; "\n\n"];
4685 ["cat"; "/new"]], "\n\n");
4686 InitBasicFS, Always, TestOutput (
4687 [["write"; "/new"; ""];
4688 ["cat"; "/new"]], "");
4689 InitBasicFS, Always, TestOutput (
4690 [["write"; "/new"; "\n\n\n"];
4691 ["cat"; "/new"]], "\n\n\n");
4692 InitBasicFS, Always, TestOutput (
4693 [["write"; "/new"; "\n"];
4694 ["cat"; "/new"]], "\n")],
4695 "create a new file",
4697 This call creates a file called C<path>. The content of the
4698 file is the string C<content> (which can contain any 8 bit data).");
4700 ("pwrite", (RInt "nbytes", [Pathname "path"; BufferIn "content"; Int64 "offset"]), 247, [ProtocolLimitWarning],
4701 [InitBasicFS, Always, TestOutput (
4702 [["write"; "/new"; "new file contents"];
4703 ["pwrite"; "/new"; "data"; "4"];
4704 ["cat"; "/new"]], "new data contents");
4705 InitBasicFS, Always, TestOutput (
4706 [["write"; "/new"; "new file contents"];
4707 ["pwrite"; "/new"; "is extended"; "9"];
4708 ["cat"; "/new"]], "new file is extended");
4709 InitBasicFS, Always, TestOutput (
4710 [["write"; "/new"; "new file contents"];
4711 ["pwrite"; "/new"; ""; "4"];
4712 ["cat"; "/new"]], "new file contents")],
4713 "write to part of a file",
4715 This command writes to part of a file. It writes the data
4716 buffer C<content> to the file C<path> starting at offset C<offset>.
4718 This command implements the L<pwrite(2)> system call, and like
4719 that system call it may not write the full data requested. The
4720 return value is the number of bytes that were actually written
4721 to the file. This could even be 0, although short writes are
4722 unlikely for regular files in ordinary circumstances.
4724 See also C<guestfs_pread>.");
4726 ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [],
4728 "resize an ext2, ext3 or ext4 filesystem (with size)",
4730 This command is the same as C<guestfs_resize2fs> except that it
4731 allows you to specify the new size (in bytes) explicitly.");
4733 ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"],
4735 "resize an LVM physical volume (with size)",
4737 This command is the same as C<guestfs_pvresize> except that it
4738 allows you to specify the new size (in bytes) explicitly.");
4740 ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"],
4742 "resize an NTFS filesystem (with size)",
4744 This command is the same as C<guestfs_ntfsresize> except that it
4745 allows you to specify the new size (in bytes) explicitly.");
4747 ("available_all_groups", (RStringList "groups", []), 251, [],
4748 [InitNone, Always, TestRun [["available_all_groups"]]],
4749 "return a list of all optional groups",
4751 This command returns a list of all optional groups that this
4752 daemon knows about. Note this returns both supported and unsupported
4753 groups. To find out which ones the daemon can actually support
4754 you have to call C<guestfs_available> on each member of the
4757 See also C<guestfs_available> and L<guestfs(3)/AVAILABILITY>.");
4759 ("fallocate64", (RErr, [Pathname "path"; Int64 "len"]), 252, [],
4760 [InitBasicFS, Always, TestOutputStruct (
4761 [["fallocate64"; "/a"; "1000000"];
4762 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
4763 "preallocate a file in the guest filesystem",
4765 This command preallocates a file (containing zero bytes) named
4766 C<path> of size C<len> bytes. If the file exists already, it
4769 Note that this call allocates disk blocks for the file.
4770 To create a sparse file use C<guestfs_truncate_size> instead.
4772 The deprecated call C<guestfs_fallocate> does the same,
4773 but owing to an oversight it only allowed 30 bit lengths
4774 to be specified, effectively limiting the maximum size
4775 of files created through that call to 1GB.
4777 Do not confuse this with the guestfish-specific
4778 C<alloc> and C<sparse> commands which create
4779 a file in the host and attach it as a device.");
4781 ("vfs_label", (RString "label", [Device "device"]), 253, [],
4782 [InitBasicFS, Always, TestOutput (
4783 [["set_e2label"; "/dev/sda1"; "LTEST"];
4784 ["vfs_label"; "/dev/sda1"]], "LTEST")],
4785 "get the filesystem label",
4787 This returns the filesystem label of the filesystem on
4790 If the filesystem is unlabeled, this returns the empty string.");
4792 ("vfs_uuid", (RString "uuid", [Device "device"]), 254, [],
4793 (let uuid = uuidgen () in
4794 [InitBasicFS, Always, TestOutput (
4795 [["set_e2uuid"; "/dev/sda1"; uuid];
4796 ["vfs_uuid"; "/dev/sda1"]], uuid)]),
4797 "get the filesystem UUID",
4799 This returns the filesystem UUID of the filesystem on
4802 If the filesystem does not have a UUID, this returns the empty string.");
4806 let all_functions = non_daemon_functions @ daemon_functions
4808 (* In some places we want the functions to be displayed sorted
4809 * alphabetically, so this is useful:
4811 let all_functions_sorted =
4812 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4813 compare n1 n2) all_functions
4815 (* This is used to generate the src/MAX_PROC_NR file which
4816 * contains the maximum procedure number, a surrogate for the
4817 * ABI version number. See src/Makefile.am for the details.
4820 let proc_nrs = List.map (
4821 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
4822 ) daemon_functions in
4823 List.fold_left max 0 proc_nrs
4825 (* Field types for structures. *)
4827 | FChar (* C 'char' (really, a 7 bit byte). *)
4828 | FString (* nul-terminated ASCII string, NOT NULL. *)
4829 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4834 | FBytes (* Any int measure that counts bytes. *)
4835 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4836 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4838 (* Because we generate extra parsing code for LVM command line tools,
4839 * we have to pull out the LVM columns separately here.
4849 "pv_attr", FString (* XXX *);
4850 "pv_pe_count", FInt64;
4851 "pv_pe_alloc_count", FInt64;
4854 "pv_mda_count", FInt64;
4855 "pv_mda_free", FBytes;
4856 (* Not in Fedora 10:
4857 "pv_mda_size", FBytes;
4864 "vg_attr", FString (* XXX *);
4867 "vg_sysid", FString;
4868 "vg_extent_size", FBytes;
4869 "vg_extent_count", FInt64;
4870 "vg_free_count", FInt64;
4875 "snap_count", FInt64;
4878 "vg_mda_count", FInt64;
4879 "vg_mda_free", FBytes;
4880 (* Not in Fedora 10:
4881 "vg_mda_size", FBytes;
4887 "lv_attr", FString (* XXX *);
4890 "lv_kernel_major", FInt64;
4891 "lv_kernel_minor", FInt64;
4893 "seg_count", FInt64;
4895 "snap_percent", FOptPercent;
4896 "copy_percent", FOptPercent;
4899 "mirror_log", FString;
4903 (* Names and fields in all structures (in RStruct and RStructList)
4907 (* The old RIntBool return type, only ever used for aug_defnode. Do
4908 * not use this struct in any new code.
4911 "i", FInt32; (* for historical compatibility *)
4912 "b", FInt32; (* for historical compatibility *)
4915 (* LVM PVs, VGs, LVs. *)
4916 "lvm_pv", lvm_pv_cols;
4917 "lvm_vg", lvm_vg_cols;
4918 "lvm_lv", lvm_lv_cols;
4920 (* Column names and types from stat structures.
4921 * NB. Can't use things like 'st_atime' because glibc header files
4922 * define some of these as macros. Ugh.
4953 (* Column names in dirent structure. *)
4956 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4961 (* Version numbers. *)
4969 (* Extended attribute. *)
4971 "attrname", FString;
4975 (* Inotify events. *)
4979 "in_cookie", FUInt32;
4983 (* Partition table entry. *)
4986 "part_start", FBytes;
4988 "part_size", FBytes;
4990 ] (* end of structs *)
4992 (* Ugh, Java has to be different ..
4993 * These names are also used by the Haskell bindings.
4995 let java_structs = [
4996 "int_bool", "IntBool";
5001 "statvfs", "StatVFS";
5003 "version", "Version";
5005 "inotify_event", "INotifyEvent";
5006 "partition", "Partition";
5009 (* What structs are actually returned. *)
5010 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
5012 (* Returns a list of RStruct/RStructList structs that are returned
5013 * by any function. Each element of returned list is a pair:
5015 * (structname, RStructOnly)
5016 * == there exists function which returns RStruct (_, structname)
5017 * (structname, RStructListOnly)
5018 * == there exists function which returns RStructList (_, structname)
5019 * (structname, RStructAndList)
5020 * == there are functions returning both RStruct (_, structname)
5021 * and RStructList (_, structname)
5023 let rstructs_used_by functions =
5024 (* ||| is a "logical OR" for rstructs_used_t *)
5028 | _, RStructAndList -> RStructAndList
5029 | RStructOnly, RStructListOnly
5030 | RStructListOnly, RStructOnly -> RStructAndList
5031 | RStructOnly, RStructOnly -> RStructOnly
5032 | RStructListOnly, RStructListOnly -> RStructListOnly
5035 let h = Hashtbl.create 13 in
5037 (* if elem->oldv exists, update entry using ||| operator,
5038 * else just add elem->newv to the hash
5040 let update elem newv =
5041 try let oldv = Hashtbl.find h elem in
5042 Hashtbl.replace h elem (newv ||| oldv)
5043 with Not_found -> Hashtbl.add h elem newv
5047 fun (_, style, _, _, _, _, _) ->
5048 match fst style with
5049 | RStruct (_, structname) -> update structname RStructOnly
5050 | RStructList (_, structname) -> update structname RStructListOnly
5054 (* return key->values as a list of (key,value) *)
5055 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
5057 (* Used for testing language bindings. *)
5059 | CallString of string
5060 | CallOptString of string option
5061 | CallStringList of string list
5063 | CallInt64 of int64
5065 | CallBuffer of string
5067 (* Used to memoize the result of pod2text. *)
5068 let pod2text_memo_filename = "src/.pod2text.data"
5069 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
5071 let chan = open_in pod2text_memo_filename in
5072 let v = input_value chan in
5076 _ -> Hashtbl.create 13
5077 let pod2text_memo_updated () =
5078 let chan = open_out pod2text_memo_filename in
5079 output_value chan pod2text_memo;
5082 (* Useful functions.
5083 * Note we don't want to use any external OCaml libraries which
5084 * makes this a bit harder than it should be.
5086 module StringMap = Map.Make (String)
5088 let failwithf fs = ksprintf failwith fs
5090 let unique = let i = ref 0 in fun () -> incr i; !i
5092 let replace_char s c1 c2 =
5093 let s2 = String.copy s in
5094 let r = ref false in
5095 for i = 0 to String.length s2 - 1 do
5096 if String.unsafe_get s2 i = c1 then (
5097 String.unsafe_set s2 i c2;
5101 if not !r then s else s2
5105 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
5107 let triml ?(test = isspace) str =
5109 let n = ref (String.length str) in
5110 while !n > 0 && test str.[!i]; do
5115 else String.sub str !i !n
5117 let trimr ?(test = isspace) str =
5118 let n = ref (String.length str) in
5119 while !n > 0 && test str.[!n-1]; do
5122 if !n = String.length str then str
5123 else String.sub str 0 !n
5125 let trim ?(test = isspace) str =
5126 trimr ~test (triml ~test str)
5128 let rec find s sub =
5129 let len = String.length s in
5130 let sublen = String.length sub in
5132 if i <= len-sublen then (
5134 if j < sublen then (
5135 if s.[i+j] = sub.[j] then loop2 (j+1)
5141 if r = -1 then loop (i+1) else r
5147 let rec replace_str s s1 s2 =
5148 let len = String.length s in
5149 let sublen = String.length s1 in
5150 let i = find s s1 in
5153 let s' = String.sub s 0 i in
5154 let s'' = String.sub s (i+sublen) (len-i-sublen) in
5155 s' ^ s2 ^ replace_str s'' s1 s2
5158 let rec string_split sep str =
5159 let len = String.length str in
5160 let seplen = String.length sep in
5161 let i = find str sep in
5162 if i = -1 then [str]
5164 let s' = String.sub str 0 i in
5165 let s'' = String.sub str (i+seplen) (len-i-seplen) in
5166 s' :: string_split sep s''
5169 let files_equal n1 n2 =
5170 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
5171 match Sys.command cmd with
5174 | i -> failwithf "%s: failed with error code %d" cmd i
5176 let rec filter_map f = function
5180 | Some y -> y :: filter_map f xs
5181 | None -> filter_map f xs
5183 let rec find_map f = function
5184 | [] -> raise Not_found
5188 | None -> find_map f xs
5191 let rec loop i = function
5193 | x :: xs -> f i x; loop (i+1) xs
5198 let rec loop i = function
5200 | x :: xs -> let r = f i x in r :: loop (i+1) xs
5204 let count_chars c str =
5205 let count = ref 0 in
5206 for i = 0 to String.length str - 1 do
5207 if c = String.unsafe_get str i then incr count
5213 for i = 0 to String.length str - 1 do
5214 let c = String.unsafe_get str i in
5219 let map_chars f str =
5220 List.map f (explode str)
5222 let name_of_argt = function
5223 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
5224 | StringList n | DeviceList n | Bool n | Int n | Int64 n
5225 | FileIn n | FileOut n | BufferIn n -> n
5227 let java_name_of_struct typ =
5228 try List.assoc typ java_structs
5231 "java_name_of_struct: no java_structs entry corresponding to %s" typ
5233 let cols_of_struct typ =
5234 try List.assoc typ structs
5236 failwithf "cols_of_struct: unknown struct %s" typ
5238 let seq_of_test = function
5239 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
5240 | TestOutputListOfDevices (s, _)
5241 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
5242 | TestOutputTrue s | TestOutputFalse s
5243 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
5244 | TestOutputStruct (s, _)
5245 | TestLastFail s -> s
5247 (* Handling for function flags. *)
5248 let protocol_limit_warning =
5249 "Because of the message protocol, there is a transfer limit
5250 of somewhere between 2MB and 4MB. See L<guestfs(3)/PROTOCOL LIMITS>."
5252 let danger_will_robinson =
5253 "B<This command is dangerous. Without careful use you
5254 can easily destroy all your data>."
5256 let deprecation_notice flags =
5259 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
5261 sprintf "This function is deprecated.
5262 In new code, use the C<%s> call instead.
5264 Deprecated functions will not be removed from the API, but the
5265 fact that they are deprecated indicates that there are problems
5266 with correct use of these functions." alt in
5271 (* Create list of optional groups. *)
5273 let h = Hashtbl.create 13 in
5275 fun (name, _, _, flags, _, _, _) ->
5279 let names = try Hashtbl.find h group with Not_found -> [] in
5280 Hashtbl.replace h group (name :: names)
5284 let groups = Hashtbl.fold (fun k _ ks -> k :: ks) h [] in
5287 fun group -> group, List.sort compare (Hashtbl.find h group)
5289 List.sort (fun x y -> compare (fst x) (fst y)) groups
5291 (* Check function names etc. for consistency. *)
5292 let check_functions () =
5293 let contains_uppercase str =
5294 let len = String.length str in
5296 if i >= len then false
5299 if c >= 'A' && c <= 'Z' then true
5306 (* Check function names. *)
5308 fun (name, _, _, _, _, _, _) ->
5309 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
5310 failwithf "function name %s does not need 'guestfs' prefix" name;
5312 failwithf "function name is empty";
5313 if name.[0] < 'a' || name.[0] > 'z' then
5314 failwithf "function name %s must start with lowercase a-z" name;
5315 if String.contains name '-' then
5316 failwithf "function name %s should not contain '-', use '_' instead."
5320 (* Check function parameter/return names. *)
5322 fun (name, style, _, _, _, _, _) ->
5323 let check_arg_ret_name n =
5324 if contains_uppercase n then
5325 failwithf "%s param/ret %s should not contain uppercase chars"
5327 if String.contains n '-' || String.contains n '_' then
5328 failwithf "%s param/ret %s should not contain '-' or '_'"
5331 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;
5332 if n = "int" || n = "char" || n = "short" || n = "long" then
5333 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
5334 if n = "i" || n = "n" then
5335 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
5336 if n = "argv" || n = "args" then
5337 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
5339 (* List Haskell, OCaml and C keywords here.
5340 * http://www.haskell.org/haskellwiki/Keywords
5341 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
5342 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
5343 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
5344 * |perl -pe 's/(.+)/"$1";/'|fmt -70
5345 * Omitting _-containing words, since they're handled above.
5346 * Omitting the OCaml reserved word, "val", is ok,
5347 * and saves us from renaming several parameters.
5350 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
5351 "char"; "class"; "const"; "constraint"; "continue"; "data";
5352 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
5353 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
5354 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
5355 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
5356 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
5358 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
5359 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
5360 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
5361 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
5362 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
5363 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
5364 "volatile"; "when"; "where"; "while";
5366 if List.mem n reserved then
5367 failwithf "%s has param/ret using reserved word %s" name n;
5370 (match fst style with
5372 | RInt n | RInt64 n | RBool n
5373 | RConstString n | RConstOptString n | RString n
5374 | RStringList n | RStruct (n, _) | RStructList (n, _)
5375 | RHashtable n | RBufferOut n ->
5376 check_arg_ret_name n
5378 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
5381 (* Check short descriptions. *)
5383 fun (name, _, _, _, _, shortdesc, _) ->
5384 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
5385 failwithf "short description of %s should begin with lowercase." name;
5386 let c = shortdesc.[String.length shortdesc-1] in
5387 if c = '\n' || c = '.' then
5388 failwithf "short description of %s should not end with . or \\n." name
5391 (* Check long descriptions. *)
5393 fun (name, _, _, _, _, _, longdesc) ->
5394 if longdesc.[String.length longdesc-1] = '\n' then
5395 failwithf "long description of %s should not end with \\n." name
5398 (* Check proc_nrs. *)
5400 fun (name, _, proc_nr, _, _, _, _) ->
5401 if proc_nr <= 0 then
5402 failwithf "daemon function %s should have proc_nr > 0" name
5406 fun (name, _, proc_nr, _, _, _, _) ->
5407 if proc_nr <> -1 then
5408 failwithf "non-daemon function %s should have proc_nr -1" name
5409 ) non_daemon_functions;
5412 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
5415 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
5416 let rec loop = function
5419 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
5421 | (name1,nr1) :: (name2,nr2) :: _ ->
5422 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
5430 (* Ignore functions that have no tests. We generate a
5431 * warning when the user does 'make check' instead.
5433 | name, _, _, _, [], _, _ -> ()
5434 | name, _, _, _, tests, _, _ ->
5438 match seq_of_test test with
5440 failwithf "%s has a test containing an empty sequence" name
5441 | cmds -> List.map List.hd cmds
5443 let funcs = List.flatten funcs in
5445 let tested = List.mem name funcs in
5448 failwithf "function %s has tests but does not test itself" name
5451 (* 'pr' prints to the current output file. *)
5452 let chan = ref Pervasives.stdout
5457 let i = count_chars '\n' str in
5458 lines := !lines + i;
5459 output_string !chan str
5462 let copyright_years =
5463 let this_year = 1900 + (localtime (time ())).tm_year in
5464 if this_year > 2009 then sprintf "2009-%04d" this_year else "2009"
5466 (* Generate a header block in a number of standard styles. *)
5467 type comment_style =
5468 CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle
5469 type license = GPLv2plus | LGPLv2plus
5471 let generate_header ?(extra_inputs = []) comment license =
5472 let inputs = "src/generator.ml" :: extra_inputs in
5473 let c = match comment with
5474 | CStyle -> pr "/* "; " *"
5475 | CPlusPlusStyle -> pr "// "; "//"
5476 | HashStyle -> pr "# "; "#"
5477 | OCamlStyle -> pr "(* "; " *"
5478 | HaskellStyle -> pr "{- "; " " in
5479 pr "libguestfs generated file\n";
5480 pr "%s WARNING: THIS FILE IS GENERATED FROM:\n" c;
5481 List.iter (pr "%s %s\n" c) inputs;
5482 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
5484 pr "%s Copyright (C) %s Red Hat Inc.\n" c copyright_years;
5488 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
5489 pr "%s it under the terms of the GNU General Public License as published by\n" c;
5490 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
5491 pr "%s (at your option) any later version.\n" c;
5493 pr "%s This program is distributed in the hope that it will be useful,\n" c;
5494 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5495 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
5496 pr "%s GNU General Public License for more details.\n" c;
5498 pr "%s You should have received a copy of the GNU General Public License along\n" c;
5499 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
5500 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
5503 pr "%s This library is free software; you can redistribute it and/or\n" c;
5504 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
5505 pr "%s License as published by the Free Software Foundation; either\n" c;
5506 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
5508 pr "%s This library is distributed in the hope that it will be useful,\n" c;
5509 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
5510 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
5511 pr "%s Lesser General Public License for more details.\n" c;
5513 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
5514 pr "%s License along with this library; if not, write to the Free Software\n" c;
5515 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
5518 | CStyle -> pr " */\n"
5521 | OCamlStyle -> pr " *)\n"
5522 | HaskellStyle -> pr "-}\n"
5526 (* Start of main code generation functions below this line. *)
5528 (* Generate the pod documentation for the C API. *)
5529 let rec generate_actions_pod () =
5531 fun (shortname, style, _, flags, _, _, longdesc) ->
5532 if not (List.mem NotInDocs flags) then (
5533 let name = "guestfs_" ^ shortname in
5534 pr "=head2 %s\n\n" name;
5536 generate_prototype ~extern:false ~handle:"g" name style;
5538 pr "%s\n\n" longdesc;
5539 (match fst style with
5541 pr "This function returns 0 on success or -1 on error.\n\n"
5543 pr "On error this function returns -1.\n\n"
5545 pr "On error this function returns -1.\n\n"
5547 pr "This function returns a C truth value on success or -1 on error.\n\n"
5549 pr "This function returns a string, or NULL on error.
5550 The string is owned by the guest handle and must I<not> be freed.\n\n"
5551 | RConstOptString _ ->
5552 pr "This function returns a string which may be NULL.
5553 There is way to return an error from this function.
5554 The string is owned by the guest handle and must I<not> be freed.\n\n"
5556 pr "This function returns a string, or NULL on error.
5557 I<The caller must free the returned string after use>.\n\n"
5559 pr "This function returns a NULL-terminated array of strings
5560 (like L<environ(3)>), or NULL if there was an error.
5561 I<The caller must free the strings and the array after use>.\n\n"
5562 | RStruct (_, typ) ->
5563 pr "This function returns a C<struct guestfs_%s *>,
5564 or NULL if there was an error.
5565 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
5566 | RStructList (_, typ) ->
5567 pr "This function returns a C<struct guestfs_%s_list *>
5568 (see E<lt>guestfs-structs.hE<gt>),
5569 or NULL if there was an error.
5570 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
5572 pr "This function returns a NULL-terminated array of
5573 strings, or NULL if there was an error.
5574 The array of strings will always have length C<2n+1>, where
5575 C<n> keys and values alternate, followed by the trailing NULL entry.
5576 I<The caller must free the strings and the array after use>.\n\n"
5578 pr "This function returns a buffer, or NULL on error.
5579 The size of the returned buffer is written to C<*size_r>.
5580 I<The caller must free the returned buffer after use>.\n\n"
5582 if List.mem ProtocolLimitWarning flags then
5583 pr "%s\n\n" protocol_limit_warning;
5584 if List.mem DangerWillRobinson flags then
5585 pr "%s\n\n" danger_will_robinson;
5586 match deprecation_notice flags with
5588 | Some txt -> pr "%s\n\n" txt
5590 ) all_functions_sorted
5592 and generate_structs_pod () =
5593 (* Structs documentation. *)
5596 pr "=head2 guestfs_%s\n" typ;
5598 pr " struct guestfs_%s {\n" typ;
5601 | name, FChar -> pr " char %s;\n" name
5602 | name, FUInt32 -> pr " uint32_t %s;\n" name
5603 | name, FInt32 -> pr " int32_t %s;\n" name
5604 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5605 | name, FInt64 -> pr " int64_t %s;\n" name
5606 | name, FString -> pr " char *%s;\n" name
5608 pr " /* The next two fields describe a byte array. */\n";
5609 pr " uint32_t %s_len;\n" name;
5610 pr " char *%s;\n" name
5612 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
5613 pr " char %s[32];\n" name
5614 | name, FOptPercent ->
5615 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
5616 pr " float %s;\n" name
5620 pr " struct guestfs_%s_list {\n" typ;
5621 pr " uint32_t len; /* Number of elements in list. */\n";
5622 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
5625 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
5626 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
5631 and generate_availability_pod () =
5632 (* Availability documentation. *)
5636 fun (group, functions) ->
5637 pr "=item B<%s>\n" group;
5639 pr "The following functions:\n";
5640 List.iter (pr "L</guestfs_%s>\n") functions;
5646 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
5647 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
5649 * We have to use an underscore instead of a dash because otherwise
5650 * rpcgen generates incorrect code.
5652 * This header is NOT exported to clients, but see also generate_structs_h.
5654 and generate_xdr () =
5655 generate_header CStyle LGPLv2plus;
5657 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
5658 pr "typedef string str<>;\n";
5661 (* Internal structures. *)
5665 pr "struct guestfs_int_%s {\n" typ;
5667 | name, FChar -> pr " char %s;\n" name
5668 | name, FString -> pr " string %s<>;\n" name
5669 | name, FBuffer -> pr " opaque %s<>;\n" name
5670 | name, FUUID -> pr " opaque %s[32];\n" name
5671 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
5672 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
5673 | name, FOptPercent -> pr " float %s;\n" name
5677 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
5682 fun (shortname, style, _, _, _, _, _) ->
5683 let name = "guestfs_" ^ shortname in
5685 (match snd style with
5688 pr "struct %s_args {\n" name;
5691 | Pathname n | Device n | Dev_or_Path n | String n ->
5692 pr " string %s<>;\n" n
5693 | OptString n -> pr " str *%s;\n" n
5694 | StringList n | DeviceList n -> pr " str %s<>;\n" n
5695 | Bool n -> pr " bool %s;\n" n
5696 | Int n -> pr " int %s;\n" n
5697 | Int64 n -> pr " hyper %s;\n" n
5699 pr " opaque %s<>;\n" n
5700 | FileIn _ | FileOut _ -> ()
5704 (match fst style with
5707 pr "struct %s_ret {\n" name;
5711 pr "struct %s_ret {\n" name;
5712 pr " hyper %s;\n" n;
5715 pr "struct %s_ret {\n" name;
5718 | RConstString _ | RConstOptString _ ->
5719 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5721 pr "struct %s_ret {\n" name;
5722 pr " string %s<>;\n" n;
5725 pr "struct %s_ret {\n" name;
5726 pr " str %s<>;\n" n;
5728 | RStruct (n, typ) ->
5729 pr "struct %s_ret {\n" name;
5730 pr " guestfs_int_%s %s;\n" typ n;
5732 | RStructList (n, typ) ->
5733 pr "struct %s_ret {\n" name;
5734 pr " guestfs_int_%s_list %s;\n" typ n;
5737 pr "struct %s_ret {\n" name;
5738 pr " str %s<>;\n" n;
5741 pr "struct %s_ret {\n" name;
5742 pr " opaque %s<>;\n" n;
5747 (* Table of procedure numbers. *)
5748 pr "enum guestfs_procedure {\n";
5750 fun (shortname, _, proc_nr, _, _, _, _) ->
5751 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5753 pr " GUESTFS_PROC_NR_PROCS\n";
5757 (* Having to choose a maximum message size is annoying for several
5758 * reasons (it limits what we can do in the API), but it (a) makes
5759 * the protocol a lot simpler, and (b) provides a bound on the size
5760 * of the daemon which operates in limited memory space.
5762 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5765 (* Message header, etc. *)
5767 /* The communication protocol is now documented in the guestfs(3)
5771 const GUESTFS_PROGRAM = 0x2000F5F5;
5772 const GUESTFS_PROTOCOL_VERSION = 1;
5774 /* These constants must be larger than any possible message length. */
5775 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5776 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5778 enum guestfs_message_direction {
5779 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5780 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5783 enum guestfs_message_status {
5784 GUESTFS_STATUS_OK = 0,
5785 GUESTFS_STATUS_ERROR = 1
5788 const GUESTFS_ERROR_LEN = 256;
5790 struct guestfs_message_error {
5791 string error_message<GUESTFS_ERROR_LEN>;
5794 struct guestfs_message_header {
5795 unsigned prog; /* GUESTFS_PROGRAM */
5796 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5797 guestfs_procedure proc; /* GUESTFS_PROC_x */
5798 guestfs_message_direction direction;
5799 unsigned serial; /* message serial number */
5800 guestfs_message_status status;
5803 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5805 struct guestfs_chunk {
5806 int cancel; /* if non-zero, transfer is cancelled */
5807 /* data size is 0 bytes if the transfer has finished successfully */
5808 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5812 (* Generate the guestfs-structs.h file. *)
5813 and generate_structs_h () =
5814 generate_header CStyle LGPLv2plus;
5816 (* This is a public exported header file containing various
5817 * structures. The structures are carefully written to have
5818 * exactly the same in-memory format as the XDR structures that
5819 * we use on the wire to the daemon. The reason for creating
5820 * copies of these structures here is just so we don't have to
5821 * export the whole of guestfs_protocol.h (which includes much
5822 * unrelated and XDR-dependent stuff that we don't want to be
5823 * public, or required by clients).
5825 * To reiterate, we will pass these structures to and from the
5826 * client with a simple assignment or memcpy, so the format
5827 * must be identical to what rpcgen / the RFC defines.
5830 (* Public structures. *)
5833 pr "struct guestfs_%s {\n" typ;
5836 | name, FChar -> pr " char %s;\n" name
5837 | name, FString -> pr " char *%s;\n" name
5839 pr " uint32_t %s_len;\n" name;
5840 pr " char *%s;\n" name
5841 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5842 | name, FUInt32 -> pr " uint32_t %s;\n" name
5843 | name, FInt32 -> pr " int32_t %s;\n" name
5844 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5845 | name, FInt64 -> pr " int64_t %s;\n" name
5846 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5850 pr "struct guestfs_%s_list {\n" typ;
5851 pr " uint32_t len;\n";
5852 pr " struct guestfs_%s *val;\n" typ;
5855 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5856 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5860 (* Generate the guestfs-actions.h file. *)
5861 and generate_actions_h () =
5862 generate_header CStyle LGPLv2plus;
5864 fun (shortname, style, _, _, _, _, _) ->
5865 let name = "guestfs_" ^ shortname in
5866 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5870 (* Generate the guestfs-internal-actions.h file. *)
5871 and generate_internal_actions_h () =
5872 generate_header CStyle LGPLv2plus;
5874 fun (shortname, style, _, _, _, _, _) ->
5875 let name = "guestfs__" ^ shortname in
5876 generate_prototype ~single_line:true ~newline:true ~handle:"g"
5878 ) non_daemon_functions
5880 (* Generate the client-side dispatch stubs. *)
5881 and generate_client_actions () =
5882 generate_header CStyle LGPLv2plus;
5889 #include <inttypes.h>
5891 #include \"guestfs.h\"
5892 #include \"guestfs-internal.h\"
5893 #include \"guestfs-internal-actions.h\"
5894 #include \"guestfs_protocol.h\"
5896 #define error guestfs_error
5897 //#define perrorf guestfs_perrorf
5898 #define safe_malloc guestfs_safe_malloc
5899 #define safe_realloc guestfs_safe_realloc
5900 //#define safe_strdup guestfs_safe_strdup
5901 #define safe_memdup guestfs_safe_memdup
5903 /* Check the return message from a call for validity. */
5905 check_reply_header (guestfs_h *g,
5906 const struct guestfs_message_header *hdr,
5907 unsigned int proc_nr, unsigned int serial)
5909 if (hdr->prog != GUESTFS_PROGRAM) {
5910 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5913 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5914 error (g, \"wrong protocol version (%%d/%%d)\",
5915 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5918 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5919 error (g, \"unexpected message direction (%%d/%%d)\",
5920 hdr->direction, GUESTFS_DIRECTION_REPLY);
5923 if (hdr->proc != proc_nr) {
5924 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5927 if (hdr->serial != serial) {
5928 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5935 /* Check we are in the right state to run a high-level action. */
5937 check_state (guestfs_h *g, const char *caller)
5939 if (!guestfs__is_ready (g)) {
5940 if (guestfs__is_config (g) || guestfs__is_launching (g))
5941 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5944 error (g, \"%%s called from the wrong state, %%d != READY\",
5945 caller, guestfs__get_state (g));
5953 let error_code_of = function
5954 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5955 | RConstString _ | RConstOptString _
5956 | RString _ | RStringList _
5957 | RStruct _ | RStructList _
5958 | RHashtable _ | RBufferOut _ -> "NULL"
5961 (* Generate code to check String-like parameters are not passed in
5962 * as NULL (returning an error if they are).
5964 let check_null_strings shortname style =
5965 let pr_newline = ref false in
5968 (* parameters which should not be NULL *)
5978 pr " if (%s == NULL) {\n" n;
5979 pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
5980 pr " \"%s\", \"%s\");\n" shortname n;
5981 pr " return %s;\n" (error_code_of (fst style));
5988 (* not applicable *)
5994 if !pr_newline then pr "\n";
5997 (* Generate code to generate guestfish call traces. *)
5998 let trace_call shortname style =
5999 pr " if (guestfs__get_trace (g)) {\n";
6002 List.exists (function
6003 | StringList _ | DeviceList _ -> true
6004 | _ -> false) (snd style) in
6010 pr " printf (\"%s\");\n" shortname;
6013 | String n (* strings *)
6020 (* guestfish doesn't support string escaping, so neither do we *)
6021 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
6022 | OptString n -> (* string option *)
6023 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
6024 pr " else printf (\" null\");\n"
6026 | DeviceList n -> (* string list *)
6027 pr " putchar (' ');\n";
6028 pr " putchar ('\"');\n";
6029 pr " for (i = 0; %s[i]; ++i) {\n" n;
6030 pr " if (i > 0) putchar (' ');\n";
6031 pr " fputs (%s[i], stdout);\n" n;
6033 pr " putchar ('\"');\n";
6034 | Bool n -> (* boolean *)
6035 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
6036 | Int n -> (* int *)
6037 pr " printf (\" %%d\", %s);\n" n
6039 pr " printf (\" %%\" PRIi64, %s);\n" n
6041 pr " putchar ('\\n');\n";
6046 (* For non-daemon functions, generate a wrapper around each function. *)
6048 fun (shortname, style, _, _, _, _, _) ->
6049 let name = "guestfs_" ^ shortname in
6051 generate_prototype ~extern:false ~semicolon:false ~newline:true
6052 ~handle:"g" name style;
6054 check_null_strings shortname style;
6055 trace_call shortname style;
6056 pr " return guestfs__%s " shortname;
6057 generate_c_call_args ~handle:"g" style;
6061 ) non_daemon_functions;
6063 (* Client-side stubs for each function. *)
6065 fun (shortname, style, _, _, _, _, _) ->
6066 let name = "guestfs_" ^ shortname in
6067 let error_code = error_code_of (fst style) in
6069 (* Generate the action stub. *)
6070 generate_prototype ~extern:false ~semicolon:false ~newline:true
6071 ~handle:"g" name style;
6075 (match snd style with
6077 | _ -> pr " struct %s_args args;\n" name
6080 pr " guestfs_message_header hdr;\n";
6081 pr " guestfs_message_error err;\n";
6083 match fst style with
6085 | RConstString _ | RConstOptString _ ->
6086 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6088 | RBool _ | RString _ | RStringList _
6089 | RStruct _ | RStructList _
6090 | RHashtable _ | RBufferOut _ ->
6091 pr " struct %s_ret ret;\n" name;
6094 pr " int serial;\n";
6097 check_null_strings shortname style;
6098 trace_call shortname style;
6099 pr " if (check_state (g, \"%s\") == -1) return %s;\n"
6100 shortname error_code;
6101 pr " guestfs___set_busy (g);\n";
6104 (* Send the main header and arguments. *)
6105 (match snd style with
6107 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
6108 (String.uppercase shortname)
6112 | Pathname n | Device n | Dev_or_Path n | String n ->
6113 pr " args.%s = (char *) %s;\n" n n
6115 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
6116 | StringList n | DeviceList n ->
6117 pr " args.%s.%s_val = (char **) %s;\n" n n n;
6118 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
6120 pr " args.%s = %s;\n" n n
6122 pr " args.%s = %s;\n" n n
6124 pr " args.%s = %s;\n" n n
6125 | FileIn _ | FileOut _ -> ()
6127 pr " /* Just catch grossly large sizes. XDR encoding will make this precise. */\n";
6128 pr " if (%s_size >= GUESTFS_MESSAGE_MAX) {\n" n;
6129 pr " error (g, \"%%s: size of input buffer too large\", \"%s\");\n"
6131 pr " guestfs___end_busy (g);\n";
6132 pr " return %s;\n" error_code;
6134 pr " args.%s.%s_val = (char *) %s;\n" n n n;
6135 pr " args.%s.%s_len = %s_size;\n" n n n
6137 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
6138 (String.uppercase shortname);
6139 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
6142 pr " if (serial == -1) {\n";
6143 pr " guestfs___end_busy (g);\n";
6144 pr " return %s;\n" error_code;
6148 (* Send any additional files (FileIn) requested. *)
6149 let need_read_reply_label = ref false in
6153 pr " r = guestfs___send_file (g, %s);\n" n;
6154 pr " if (r == -1) {\n";
6155 pr " guestfs___end_busy (g);\n";
6156 pr " return %s;\n" error_code;
6158 pr " if (r == -2) /* daemon cancelled */\n";
6159 pr " goto read_reply;\n";
6160 need_read_reply_label := true;
6165 (* Wait for the reply from the remote end. *)
6166 if !need_read_reply_label then pr " read_reply:\n";
6167 pr " memset (&hdr, 0, sizeof hdr);\n";
6168 pr " memset (&err, 0, sizeof err);\n";
6169 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
6171 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
6175 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
6178 pr " if (r == -1) {\n";
6179 pr " guestfs___end_busy (g);\n";
6180 pr " return %s;\n" error_code;
6184 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
6185 (String.uppercase shortname);
6186 pr " guestfs___end_busy (g);\n";
6187 pr " return %s;\n" error_code;
6191 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
6192 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
6193 pr " free (err.error_message);\n";
6194 pr " guestfs___end_busy (g);\n";
6195 pr " return %s;\n" error_code;
6199 (* Expecting to receive further files (FileOut)? *)
6203 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
6204 pr " guestfs___end_busy (g);\n";
6205 pr " return %s;\n" error_code;
6211 pr " guestfs___end_busy (g);\n";
6213 (match fst style with
6214 | RErr -> pr " return 0;\n"
6215 | RInt n | RInt64 n | RBool n ->
6216 pr " return ret.%s;\n" n
6217 | RConstString _ | RConstOptString _ ->
6218 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6220 pr " return ret.%s; /* caller will free */\n" n
6221 | RStringList n | RHashtable n ->
6222 pr " /* caller will free this, but we need to add a NULL entry */\n";
6223 pr " ret.%s.%s_val =\n" n n;
6224 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
6225 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
6227 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
6228 pr " return ret.%s.%s_val;\n" n n
6230 pr " /* caller will free this */\n";
6231 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6232 | RStructList (n, _) ->
6233 pr " /* caller will free this */\n";
6234 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
6236 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
6237 pr " * _val might be NULL here. To make the API saner for\n";
6238 pr " * callers, we turn this case into a unique pointer (using\n";
6239 pr " * malloc(1)).\n";
6241 pr " if (ret.%s.%s_len > 0) {\n" n n;
6242 pr " *size_r = ret.%s.%s_len;\n" n n;
6243 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
6245 pr " free (ret.%s.%s_val);\n" n n;
6246 pr " char *p = safe_malloc (g, 1);\n";
6247 pr " *size_r = ret.%s.%s_len;\n" n n;
6255 (* Functions to free structures. *)
6256 pr "/* Structure-freeing functions. These rely on the fact that the\n";
6257 pr " * structure format is identical to the XDR format. See note in\n";
6258 pr " * generator.ml.\n";
6265 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
6267 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
6273 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
6275 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
6282 (* Generate daemon/actions.h. *)
6283 and generate_daemon_actions_h () =
6284 generate_header CStyle GPLv2plus;
6286 pr "#include \"../src/guestfs_protocol.h\"\n";
6290 fun (name, style, _, _, _, _, _) ->
6292 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
6296 (* Generate the linker script which controls the visibility of
6297 * symbols in the public ABI and ensures no other symbols get
6298 * exported accidentally.
6300 and generate_linker_script () =
6301 generate_header HashStyle GPLv2plus;
6306 "guestfs_get_error_handler";
6307 "guestfs_get_out_of_memory_handler";
6308 "guestfs_last_error";
6309 "guestfs_set_error_handler";
6310 "guestfs_set_launch_done_callback";
6311 "guestfs_set_log_message_callback";
6312 "guestfs_set_out_of_memory_handler";
6313 "guestfs_set_subprocess_quit_callback";
6315 (* Unofficial parts of the API: the bindings code use these
6316 * functions, so it is useful to export them.
6318 "guestfs_safe_calloc";
6319 "guestfs_safe_malloc";
6322 List.map (fun (name, _, _, _, _, _, _) -> "guestfs_" ^ name)
6326 List.map (fun (typ, _) ->
6327 ["guestfs_free_" ^ typ; "guestfs_free_" ^ typ ^ "_list"])
6330 let globals = List.sort compare (globals @ functions @ structs) in
6334 List.iter (pr " %s;\n") globals;
6341 (* Generate the server-side stubs. *)
6342 and generate_daemon_actions () =
6343 generate_header CStyle GPLv2plus;
6345 pr "#include <config.h>\n";
6347 pr "#include <stdio.h>\n";
6348 pr "#include <stdlib.h>\n";
6349 pr "#include <string.h>\n";
6350 pr "#include <inttypes.h>\n";
6351 pr "#include <rpc/types.h>\n";
6352 pr "#include <rpc/xdr.h>\n";
6354 pr "#include \"daemon.h\"\n";
6355 pr "#include \"c-ctype.h\"\n";
6356 pr "#include \"../src/guestfs_protocol.h\"\n";
6357 pr "#include \"actions.h\"\n";
6361 fun (name, style, _, _, _, _, _) ->
6362 (* Generate server-side stubs. *)
6363 pr "static void %s_stub (XDR *xdr_in)\n" name;
6366 match fst style with
6367 | RErr | RInt _ -> pr " int r;\n"; "-1"
6368 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6369 | RBool _ -> pr " int r;\n"; "-1"
6370 | RConstString _ | RConstOptString _ ->
6371 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6372 | RString _ -> pr " char *r;\n"; "NULL"
6373 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
6374 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
6375 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
6377 pr " size_t size = 1;\n";
6381 (match snd style with
6384 pr " struct guestfs_%s_args args;\n" name;
6387 | Device n | Dev_or_Path n
6390 | OptString n -> pr " char *%s;\n" n
6391 | StringList n | DeviceList n -> pr " char **%s;\n" n
6392 | Bool n -> pr " int %s;\n" n
6393 | Int n -> pr " int %s;\n" n
6394 | Int64 n -> pr " int64_t %s;\n" n
6395 | FileIn _ | FileOut _ -> ()
6397 pr " const char *%s;\n" n;
6398 pr " size_t %s_size;\n" n
6404 List.exists (function FileIn _ -> true | _ -> false) (snd style) in
6406 (match snd style with
6409 pr " memset (&args, 0, sizeof args);\n";
6411 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
6413 pr " if (cancel_receive () != -2)\n";
6414 pr " reply_with_error (\"daemon failed to decode procedure arguments\");\n";
6418 pr " char *%s = args.%s;\n" n n
6420 let pr_list_handling_code n =
6421 pr " %s = realloc (args.%s.%s_val,\n" n n n;
6422 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
6423 pr " if (%s == NULL) {\n" n;
6425 pr " if (cancel_receive () != -2)\n";
6426 pr " reply_with_perror (\"realloc\");\n";
6429 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
6430 pr " args.%s.%s_val = %s;\n" n n n;
6436 pr " ABS_PATH (%s, %s, goto done);\n"
6437 n (if is_filein then "cancel_receive ()" else "0");
6440 pr " RESOLVE_DEVICE (%s, %s, goto done);\n"
6441 n (if is_filein then "cancel_receive ()" else "0");
6444 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, %s, goto done);\n"
6445 n (if is_filein then "cancel_receive ()" else "0");
6446 | String n -> pr_args n
6447 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
6449 pr_list_handling_code n;
6451 pr_list_handling_code n;
6452 pr " /* Ensure that each is a device,\n";
6453 pr " * and perform device name translation. */\n";
6454 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
6455 pr " RESOLVE_DEVICE (physvols[pvi], %s, goto done);\n"
6456 (if is_filein then "cancel_receive ()" else "0");
6458 | Bool n -> pr " %s = args.%s;\n" n n
6459 | Int n -> pr " %s = args.%s;\n" n n
6460 | Int64 n -> pr " %s = args.%s;\n" n n
6461 | FileIn _ | FileOut _ -> ()
6463 pr " %s = args.%s.%s_val;\n" n n n;
6464 pr " %s_size = args.%s.%s_len;\n" n n n
6469 (* this is used at least for do_equal *)
6470 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
6471 (* Emit NEED_ROOT just once, even when there are two or
6472 more Pathname args *)
6473 pr " NEED_ROOT (%s, goto done);\n"
6474 (if is_filein then "cancel_receive ()" else "0");
6477 (* Don't want to call the impl with any FileIn or FileOut
6478 * parameters, since these go "outside" the RPC protocol.
6481 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
6483 pr " r = do_%s " name;
6484 generate_c_call_args (fst style, args');
6487 (match fst style with
6488 | RErr | RInt _ | RInt64 _ | RBool _
6489 | RConstString _ | RConstOptString _
6490 | RString _ | RStringList _ | RHashtable _
6491 | RStruct (_, _) | RStructList (_, _) ->
6492 pr " if (r == %s)\n" error_code;
6493 pr " /* do_%s has already called reply_with_error */\n" name;
6497 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
6498 pr " * an ordinary zero-length buffer), so be careful ...\n";
6500 pr " if (size == 1 && r == %s)\n" error_code;
6501 pr " /* do_%s has already called reply_with_error */\n" name;
6506 (* If there are any FileOut parameters, then the impl must
6507 * send its own reply.
6510 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
6512 pr " /* do_%s has already sent a reply */\n" name
6514 match fst style with
6515 | RErr -> pr " reply (NULL, NULL);\n"
6516 | RInt n | RInt64 n | RBool n ->
6517 pr " struct guestfs_%s_ret ret;\n" name;
6518 pr " ret.%s = r;\n" n;
6519 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6521 | RConstString _ | RConstOptString _ ->
6522 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
6524 pr " struct guestfs_%s_ret ret;\n" name;
6525 pr " ret.%s = r;\n" n;
6526 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6529 | RStringList n | RHashtable n ->
6530 pr " struct guestfs_%s_ret ret;\n" name;
6531 pr " ret.%s.%s_len = count_strings (r);\n" n n;
6532 pr " ret.%s.%s_val = r;\n" n n;
6533 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6535 pr " free_strings (r);\n"
6537 pr " struct guestfs_%s_ret ret;\n" name;
6538 pr " ret.%s = *r;\n" n;
6539 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6541 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6543 | RStructList (n, _) ->
6544 pr " struct guestfs_%s_ret ret;\n" name;
6545 pr " ret.%s = *r;\n" n;
6546 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6548 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
6551 pr " struct guestfs_%s_ret ret;\n" name;
6552 pr " ret.%s.%s_val = r;\n" n n;
6553 pr " ret.%s.%s_len = size;\n" n n;
6554 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
6559 (* Free the args. *)
6561 (match snd style with
6564 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
6571 (* Dispatch function. *)
6572 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
6574 pr " switch (proc_nr) {\n";
6577 fun (name, style, _, _, _, _, _) ->
6578 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
6579 pr " %s_stub (xdr_in);\n" name;
6584 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";
6589 (* LVM columns and tokenization functions. *)
6590 (* XXX This generates crap code. We should rethink how we
6596 pr "static const char *lvm_%s_cols = \"%s\";\n"
6597 typ (String.concat "," (List.map fst cols));
6600 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
6602 pr " char *tok, *p, *next;\n";
6606 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
6609 pr " if (!str) {\n";
6610 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
6613 pr " if (!*str || c_isspace (*str)) {\n";
6614 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
6619 fun (name, coltype) ->
6620 pr " if (!tok) {\n";
6621 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
6624 pr " p = strchrnul (tok, ',');\n";
6625 pr " if (*p) next = p+1; else next = NULL;\n";
6626 pr " *p = '\\0';\n";
6629 pr " r->%s = strdup (tok);\n" name;
6630 pr " if (r->%s == NULL) {\n" name;
6631 pr " perror (\"strdup\");\n";
6635 pr " for (i = j = 0; i < 32; ++j) {\n";
6636 pr " if (tok[j] == '\\0') {\n";
6637 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
6639 pr " } else if (tok[j] != '-')\n";
6640 pr " r->%s[i++] = tok[j];\n" name;
6643 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
6644 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6648 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
6649 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6653 pr " if (tok[0] == '\\0')\n";
6654 pr " r->%s = -1;\n" name;
6655 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
6656 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
6659 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
6660 assert false (* can never be an LVM column *)
6662 pr " tok = next;\n";
6665 pr " if (tok != NULL) {\n";
6666 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
6673 pr "guestfs_int_lvm_%s_list *\n" typ;
6674 pr "parse_command_line_%ss (void)\n" typ;
6676 pr " char *out, *err;\n";
6677 pr " char *p, *pend;\n";
6679 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
6680 pr " void *newp;\n";
6682 pr " ret = malloc (sizeof *ret);\n";
6683 pr " if (!ret) {\n";
6684 pr " reply_with_perror (\"malloc\");\n";
6685 pr " return NULL;\n";
6688 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
6689 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
6691 pr " r = command (&out, &err,\n";
6692 pr " \"lvm\", \"%ss\",\n" typ;
6693 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
6694 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
6695 pr " if (r == -1) {\n";
6696 pr " reply_with_error (\"%%s\", err);\n";
6697 pr " free (out);\n";
6698 pr " free (err);\n";
6699 pr " free (ret);\n";
6700 pr " return NULL;\n";
6703 pr " free (err);\n";
6705 pr " /* Tokenize each line of the output. */\n";
6708 pr " while (p) {\n";
6709 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
6710 pr " if (pend) {\n";
6711 pr " *pend = '\\0';\n";
6715 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
6718 pr " if (!*p) { /* Empty line? Skip it. */\n";
6723 pr " /* Allocate some space to store this next entry. */\n";
6724 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
6725 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
6726 pr " if (newp == NULL) {\n";
6727 pr " reply_with_perror (\"realloc\");\n";
6728 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6729 pr " free (ret);\n";
6730 pr " free (out);\n";
6731 pr " return NULL;\n";
6733 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
6735 pr " /* Tokenize the next entry. */\n";
6736 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
6737 pr " if (r == -1) {\n";
6738 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
6739 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
6740 pr " free (ret);\n";
6741 pr " free (out);\n";
6742 pr " return NULL;\n";
6749 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
6751 pr " free (out);\n";
6752 pr " return ret;\n";
6755 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
6757 (* Generate a list of function names, for debugging in the daemon.. *)
6758 and generate_daemon_names () =
6759 generate_header CStyle GPLv2plus;
6761 pr "#include <config.h>\n";
6763 pr "#include \"daemon.h\"\n";
6766 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
6767 pr "const char *function_names[] = {\n";
6769 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
6773 (* Generate the optional groups for the daemon to implement
6774 * guestfs_available.
6776 and generate_daemon_optgroups_c () =
6777 generate_header CStyle GPLv2plus;
6779 pr "#include <config.h>\n";
6781 pr "#include \"daemon.h\"\n";
6782 pr "#include \"optgroups.h\"\n";
6785 pr "struct optgroup optgroups[] = {\n";
6788 pr " { \"%s\", optgroup_%s_available },\n" group group
6790 pr " { NULL, NULL }\n";
6793 and generate_daemon_optgroups_h () =
6794 generate_header CStyle GPLv2plus;
6798 pr "extern int optgroup_%s_available (void);\n" group
6801 (* Generate the tests. *)
6802 and generate_tests () =
6803 generate_header CStyle GPLv2plus;
6810 #include <sys/types.h>
6813 #include \"guestfs.h\"
6814 #include \"guestfs-internal.h\"
6816 static guestfs_h *g;
6817 static int suppress_error = 0;
6819 static void print_error (guestfs_h *g, void *data, const char *msg)
6821 if (!suppress_error)
6822 fprintf (stderr, \"%%s\\n\", msg);
6825 /* FIXME: nearly identical code appears in fish.c */
6826 static void print_strings (char *const *argv)
6830 for (argc = 0; argv[argc] != NULL; ++argc)
6831 printf (\"\\t%%s\\n\", argv[argc]);
6835 static void print_table (char const *const *argv)
6839 for (i = 0; argv[i] != NULL; i += 2)
6840 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
6845 is_available (const char *group)
6847 const char *groups[] = { group, NULL };
6851 r = guestfs_available (g, (char **) groups);
6859 (* Generate a list of commands which are not tested anywhere. *)
6860 pr "static void no_test_warnings (void)\n";
6863 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
6865 fun (_, _, _, _, tests, _, _) ->
6866 let tests = filter_map (
6868 | (_, (Always|If _|Unless _|IfAvailable _), test) -> Some test
6869 | (_, Disabled, _) -> None
6871 let seq = List.concat (List.map seq_of_test tests) in
6872 let cmds_tested = List.map List.hd seq in
6873 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6877 fun (name, _, _, _, _, _, _) ->
6878 if not (Hashtbl.mem hash name) then
6879 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6885 (* Generate the actual tests. Note that we generate the tests
6886 * in reverse order, deliberately, so that (in general) the
6887 * newest tests run first. This makes it quicker and easier to
6892 fun (name, _, _, flags, tests, _, _) ->
6893 mapi (generate_one_test name flags) tests
6894 ) (List.rev all_functions) in
6895 let test_names = List.concat test_names in
6896 let nr_tests = List.length test_names in
6899 int main (int argc, char *argv[])
6902 unsigned long int n_failed = 0;
6903 const char *filename;
6905 int nr_tests, test_num = 0;
6907 setbuf (stdout, NULL);
6909 no_test_warnings ();
6911 g = guestfs_create ();
6913 printf (\"guestfs_create FAILED\\n\");
6914 exit (EXIT_FAILURE);
6917 guestfs_set_error_handler (g, print_error, NULL);
6919 guestfs_set_path (g, \"../appliance\");
6921 filename = \"test1.img\";
6922 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6925 exit (EXIT_FAILURE);
6927 if (lseek (fd, %d, SEEK_SET) == -1) {
6931 exit (EXIT_FAILURE);
6933 if (write (fd, &c, 1) == -1) {
6937 exit (EXIT_FAILURE);
6939 if (close (fd) == -1) {
6942 exit (EXIT_FAILURE);
6944 if (guestfs_add_drive (g, filename) == -1) {
6945 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6946 exit (EXIT_FAILURE);
6949 filename = \"test2.img\";
6950 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6953 exit (EXIT_FAILURE);
6955 if (lseek (fd, %d, SEEK_SET) == -1) {
6959 exit (EXIT_FAILURE);
6961 if (write (fd, &c, 1) == -1) {
6965 exit (EXIT_FAILURE);
6967 if (close (fd) == -1) {
6970 exit (EXIT_FAILURE);
6972 if (guestfs_add_drive (g, filename) == -1) {
6973 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6974 exit (EXIT_FAILURE);
6977 filename = \"test3.img\";
6978 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6981 exit (EXIT_FAILURE);
6983 if (lseek (fd, %d, SEEK_SET) == -1) {
6987 exit (EXIT_FAILURE);
6989 if (write (fd, &c, 1) == -1) {
6993 exit (EXIT_FAILURE);
6995 if (close (fd) == -1) {
6998 exit (EXIT_FAILURE);
7000 if (guestfs_add_drive (g, filename) == -1) {
7001 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
7002 exit (EXIT_FAILURE);
7005 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
7006 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
7007 exit (EXIT_FAILURE);
7010 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
7013 if (guestfs_launch (g) == -1) {
7014 printf (\"guestfs_launch FAILED\\n\");
7015 exit (EXIT_FAILURE);
7018 /* Cancel previous alarm. */
7023 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
7027 pr " test_num++;\n";
7028 pr " if (guestfs_get_verbose (g))\n";
7029 pr " printf (\"-------------------------------------------------------------------------------\\n\");\n";
7030 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
7031 pr " if (%s () == -1) {\n" test_name;
7032 pr " printf (\"%s FAILED\\n\");\n" test_name;
7033 pr " n_failed++;\n";
7038 pr " guestfs_close (g);\n";
7039 pr " unlink (\"test1.img\");\n";
7040 pr " unlink (\"test2.img\");\n";
7041 pr " unlink (\"test3.img\");\n";
7044 pr " if (n_failed > 0) {\n";
7045 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
7046 pr " exit (EXIT_FAILURE);\n";
7050 pr " exit (EXIT_SUCCESS);\n";
7053 and generate_one_test name flags i (init, prereq, test) =
7054 let test_name = sprintf "test_%s_%d" name i in
7057 static int %s_skip (void)
7061 str = getenv (\"TEST_ONLY\");
7063 return strstr (str, \"%s\") == NULL;
7064 str = getenv (\"SKIP_%s\");
7065 if (str && STREQ (str, \"1\")) return 1;
7066 str = getenv (\"SKIP_TEST_%s\");
7067 if (str && STREQ (str, \"1\")) return 1;
7071 " test_name name (String.uppercase test_name) (String.uppercase name);
7074 | Disabled | Always | IfAvailable _ -> ()
7075 | If code | Unless code ->
7076 pr "static int %s_prereq (void)\n" test_name;
7084 static int %s (void)
7087 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
7091 " test_name test_name test_name;
7093 (* Optional functions should only be tested if the relevant
7094 * support is available in the daemon.
7099 pr " if (!is_available (\"%s\")) {\n" group;
7100 pr " printf (\" %%s skipped (reason: group %%s not available in daemon)\\n\", \"%s\", \"%s\");\n" test_name group;
7108 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
7110 pr " if (! %s_prereq ()) {\n" test_name;
7111 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7115 generate_one_test_body name i test_name init test;
7117 pr " if (%s_prereq ()) {\n" test_name;
7118 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
7122 generate_one_test_body name i test_name init test;
7123 | IfAvailable group ->
7124 pr " if (!is_available (\"%s\")) {\n" group;
7125 pr " printf (\" %%s skipped (reason: %%s not available)\\n\", \"%s\", \"%s\");\n" test_name group;
7129 generate_one_test_body name i test_name init test;
7131 generate_one_test_body name i test_name init test
7139 and generate_one_test_body name i test_name init test =
7141 | InitNone (* XXX at some point, InitNone and InitEmpty became
7142 * folded together as the same thing. Really we should
7143 * make InitNone do nothing at all, but the tests may
7144 * need to be checked to make sure this is OK.
7147 pr " /* InitNone|InitEmpty for %s */\n" test_name;
7148 List.iter (generate_test_command_call test_name)
7149 [["blockdev_setrw"; "/dev/sda"];
7153 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
7154 List.iter (generate_test_command_call test_name)
7155 [["blockdev_setrw"; "/dev/sda"];
7158 ["part_disk"; "/dev/sda"; "mbr"]]
7160 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
7161 List.iter (generate_test_command_call test_name)
7162 [["blockdev_setrw"; "/dev/sda"];
7165 ["part_disk"; "/dev/sda"; "mbr"];
7166 ["mkfs"; "ext2"; "/dev/sda1"];
7167 ["mount_options"; ""; "/dev/sda1"; "/"]]
7168 | InitBasicFSonLVM ->
7169 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
7171 List.iter (generate_test_command_call test_name)
7172 [["blockdev_setrw"; "/dev/sda"];
7175 ["part_disk"; "/dev/sda"; "mbr"];
7176 ["pvcreate"; "/dev/sda1"];
7177 ["vgcreate"; "VG"; "/dev/sda1"];
7178 ["lvcreate"; "LV"; "VG"; "8"];
7179 ["mkfs"; "ext2"; "/dev/VG/LV"];
7180 ["mount_options"; ""; "/dev/VG/LV"; "/"]]
7182 pr " /* InitISOFS for %s */\n" test_name;
7183 List.iter (generate_test_command_call test_name)
7184 [["blockdev_setrw"; "/dev/sda"];
7187 ["mount_ro"; "/dev/sdd"; "/"]]
7190 let get_seq_last = function
7192 failwithf "%s: you cannot use [] (empty list) when expecting a command"
7195 let seq = List.rev seq in
7196 List.rev (List.tl seq), List.hd seq
7201 pr " /* TestRun for %s (%d) */\n" name i;
7202 List.iter (generate_test_command_call test_name) seq
7203 | TestOutput (seq, expected) ->
7204 pr " /* TestOutput for %s (%d) */\n" name i;
7205 pr " const char *expected = \"%s\";\n" (c_quote expected);
7206 let seq, last = get_seq_last seq in
7208 pr " if (STRNEQ (r, expected)) {\n";
7209 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7213 List.iter (generate_test_command_call test_name) seq;
7214 generate_test_command_call ~test test_name last
7215 | TestOutputList (seq, expected) ->
7216 pr " /* TestOutputList for %s (%d) */\n" name i;
7217 let seq, last = get_seq_last seq in
7221 pr " if (!r[%d]) {\n" i;
7222 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7223 pr " print_strings (r);\n";
7227 pr " const char *expected = \"%s\";\n" (c_quote str);
7228 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7229 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7234 pr " if (r[%d] != NULL) {\n" (List.length expected);
7235 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7237 pr " print_strings (r);\n";
7241 List.iter (generate_test_command_call test_name) seq;
7242 generate_test_command_call ~test test_name last
7243 | TestOutputListOfDevices (seq, expected) ->
7244 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
7245 let seq, last = get_seq_last seq in
7249 pr " if (!r[%d]) {\n" i;
7250 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
7251 pr " print_strings (r);\n";
7255 pr " const char *expected = \"%s\";\n" (c_quote str);
7256 pr " r[%d][5] = 's';\n" i;
7257 pr " if (STRNEQ (r[%d], expected)) {\n" i;
7258 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
7263 pr " if (r[%d] != NULL) {\n" (List.length expected);
7264 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
7266 pr " print_strings (r);\n";
7270 List.iter (generate_test_command_call test_name) seq;
7271 generate_test_command_call ~test test_name last
7272 | TestOutputInt (seq, expected) ->
7273 pr " /* TestOutputInt for %s (%d) */\n" name i;
7274 let seq, last = get_seq_last seq in
7276 pr " if (r != %d) {\n" expected;
7277 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
7283 List.iter (generate_test_command_call test_name) seq;
7284 generate_test_command_call ~test test_name last
7285 | TestOutputIntOp (seq, op, expected) ->
7286 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
7287 let seq, last = get_seq_last seq in
7289 pr " if (! (r %s %d)) {\n" op expected;
7290 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
7291 test_name op expected;
7296 List.iter (generate_test_command_call test_name) seq;
7297 generate_test_command_call ~test test_name last
7298 | TestOutputTrue seq ->
7299 pr " /* TestOutputTrue for %s (%d) */\n" name i;
7300 let seq, last = get_seq_last seq in
7303 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
7308 List.iter (generate_test_command_call test_name) seq;
7309 generate_test_command_call ~test test_name last
7310 | TestOutputFalse seq ->
7311 pr " /* TestOutputFalse for %s (%d) */\n" name i;
7312 let seq, last = get_seq_last seq in
7315 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
7320 List.iter (generate_test_command_call test_name) seq;
7321 generate_test_command_call ~test test_name last
7322 | TestOutputLength (seq, expected) ->
7323 pr " /* TestOutputLength for %s (%d) */\n" name i;
7324 let seq, last = get_seq_last seq in
7327 pr " for (j = 0; j < %d; ++j)\n" expected;
7328 pr " if (r[j] == NULL) {\n";
7329 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
7331 pr " print_strings (r);\n";
7334 pr " if (r[j] != NULL) {\n";
7335 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
7337 pr " print_strings (r);\n";
7341 List.iter (generate_test_command_call test_name) seq;
7342 generate_test_command_call ~test test_name last
7343 | TestOutputBuffer (seq, expected) ->
7344 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
7345 pr " const char *expected = \"%s\";\n" (c_quote expected);
7346 let seq, last = get_seq_last seq in
7347 let len = String.length expected in
7349 pr " if (size != %d) {\n" len;
7350 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
7353 pr " if (STRNEQLEN (r, expected, size)) {\n";
7354 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
7358 List.iter (generate_test_command_call test_name) seq;
7359 generate_test_command_call ~test test_name last
7360 | TestOutputStruct (seq, checks) ->
7361 pr " /* TestOutputStruct for %s (%d) */\n" name i;
7362 let seq, last = get_seq_last seq in
7366 | CompareWithInt (field, expected) ->
7367 pr " if (r->%s != %d) {\n" field expected;
7368 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
7369 test_name field expected;
7370 pr " (int) r->%s);\n" field;
7373 | CompareWithIntOp (field, op, expected) ->
7374 pr " if (!(r->%s %s %d)) {\n" field op expected;
7375 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
7376 test_name field op expected;
7377 pr " (int) r->%s);\n" field;
7380 | CompareWithString (field, expected) ->
7381 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
7382 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
7383 test_name field expected;
7384 pr " r->%s);\n" field;
7387 | CompareFieldsIntEq (field1, field2) ->
7388 pr " if (r->%s != r->%s) {\n" field1 field2;
7389 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
7390 test_name field1 field2;
7391 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
7394 | CompareFieldsStrEq (field1, field2) ->
7395 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
7396 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
7397 test_name field1 field2;
7398 pr " r->%s, r->%s);\n" field1 field2;
7403 List.iter (generate_test_command_call test_name) seq;
7404 generate_test_command_call ~test test_name last
7405 | TestLastFail seq ->
7406 pr " /* TestLastFail for %s (%d) */\n" name i;
7407 let seq, last = get_seq_last seq in
7408 List.iter (generate_test_command_call test_name) seq;
7409 generate_test_command_call test_name ~expect_error:true last
7411 (* Generate the code to run a command, leaving the result in 'r'.
7412 * If you expect to get an error then you should set expect_error:true.
7414 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
7416 | [] -> assert false
7418 (* Look up the command to find out what args/ret it has. *)
7421 let _, style, _, _, _, _, _ =
7422 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
7425 failwithf "%s: in test, command %s was not found" test_name name in
7427 if List.length (snd style) <> List.length args then
7428 failwithf "%s: in test, wrong number of args given to %s"
7435 | OptString n, "NULL" -> ()
7438 | Dev_or_Path n, arg
7440 | OptString n, arg ->
7441 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7442 | BufferIn n, arg ->
7443 pr " const char *%s = \"%s\";\n" n (c_quote arg);
7444 pr " size_t %s_size = %d;\n" n (String.length arg)
7448 | FileIn _, _ | FileOut _, _ -> ()
7449 | StringList n, "" | DeviceList n, "" ->
7450 pr " const char *const %s[1] = { NULL };\n" n
7451 | StringList n, arg | DeviceList n, arg ->
7452 let strs = string_split " " arg in
7455 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
7457 pr " const char *const %s[] = {\n" n;
7459 fun i _ -> pr " %s_%d,\n" n i
7463 ) (List.combine (snd style) args);
7466 match fst style with
7467 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
7468 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7469 | RConstString _ | RConstOptString _ ->
7470 pr " const char *r;\n"; "NULL"
7471 | RString _ -> pr " char *r;\n"; "NULL"
7472 | RStringList _ | RHashtable _ ->
7476 | RStruct (_, typ) ->
7477 pr " struct guestfs_%s *r;\n" typ; "NULL"
7478 | RStructList (_, typ) ->
7479 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7482 pr " size_t size;\n";
7485 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
7486 pr " r = guestfs_%s (g" name;
7488 (* Generate the parameters. *)
7491 | OptString _, "NULL" -> pr ", NULL"
7493 | Device n, _ | Dev_or_Path n, _
7498 pr ", %s, %s_size" n n
7499 | FileIn _, arg | FileOut _, arg ->
7500 pr ", \"%s\"" (c_quote arg)
7501 | StringList n, _ | DeviceList n, _ ->
7502 pr ", (char **) %s" n
7505 try int_of_string arg
7506 with Failure "int_of_string" ->
7507 failwithf "%s: expecting an int, but got '%s'" test_name arg in
7511 try Int64.of_string arg
7512 with Failure "int_of_string" ->
7513 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
7516 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
7517 ) (List.combine (snd style) args);
7519 (match fst style with
7520 | RBufferOut _ -> pr ", &size"
7526 if not expect_error then
7527 pr " if (r == %s)\n" error_code
7529 pr " if (r != %s)\n" error_code;
7532 (* Insert the test code. *)
7538 (match fst style with
7539 | RErr | RInt _ | RInt64 _ | RBool _
7540 | RConstString _ | RConstOptString _ -> ()
7541 | RString _ | RBufferOut _ -> pr " free (r);\n"
7542 | RStringList _ | RHashtable _ ->
7543 pr " for (i = 0; r[i] != NULL; ++i)\n";
7544 pr " free (r[i]);\n";
7546 | RStruct (_, typ) ->
7547 pr " guestfs_free_%s (r);\n" typ
7548 | RStructList (_, typ) ->
7549 pr " guestfs_free_%s_list (r);\n" typ
7555 let str = replace_str str "\r" "\\r" in
7556 let str = replace_str str "\n" "\\n" in
7557 let str = replace_str str "\t" "\\t" in
7558 let str = replace_str str "\000" "\\0" in
7561 (* Generate a lot of different functions for guestfish. *)
7562 and generate_fish_cmds () =
7563 generate_header CStyle GPLv2plus;
7567 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7569 let all_functions_sorted =
7571 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7572 ) all_functions_sorted in
7574 pr "#include <config.h>\n";
7576 pr "#include <stdio.h>\n";
7577 pr "#include <stdlib.h>\n";
7578 pr "#include <string.h>\n";
7579 pr "#include <inttypes.h>\n";
7581 pr "#include <guestfs.h>\n";
7582 pr "#include \"c-ctype.h\"\n";
7583 pr "#include \"full-write.h\"\n";
7584 pr "#include \"xstrtol.h\"\n";
7585 pr "#include \"fish.h\"\n";
7587 pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
7588 pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
7591 (* list_commands function, which implements guestfish -h *)
7592 pr "void list_commands (void)\n";
7594 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
7595 pr " list_builtin_commands ();\n";
7597 fun (name, _, _, flags, _, shortdesc, _) ->
7598 let name = replace_char name '_' '-' in
7599 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
7601 ) all_functions_sorted;
7602 pr " printf (\" %%s\\n\",";
7603 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
7607 (* display_command function, which implements guestfish -h cmd *)
7608 pr "int display_command (const char *cmd)\n";
7611 fun (name, style, _, flags, _, shortdesc, longdesc) ->
7612 let name2 = replace_char name '_' '-' in
7614 try find_map (function FishAlias n -> Some n | _ -> None) flags
7615 with Not_found -> name in
7616 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
7618 match snd style with
7622 name2 (String.concat " " (List.map name_of_argt args)) in
7625 if List.mem ProtocolLimitWarning flags then
7626 ("\n\n" ^ protocol_limit_warning)
7629 (* For DangerWillRobinson commands, we should probably have
7630 * guestfish prompt before allowing you to use them (especially
7631 * in interactive mode). XXX
7635 if List.mem DangerWillRobinson flags then
7636 ("\n\n" ^ danger_will_robinson)
7641 match deprecation_notice flags with
7643 | Some txt -> "\n\n" ^ txt in
7645 let describe_alias =
7646 if name <> alias then
7647 sprintf "\n\nYou can use '%s' as an alias for this command." alias
7651 pr "STRCASEEQ (cmd, \"%s\")" name;
7652 if name <> name2 then
7653 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7654 if name <> alias then
7655 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7657 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
7659 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
7660 "=head1 DESCRIPTION\n\n" ^
7661 longdesc ^ warnings ^ describe_alias);
7666 pr " return display_builtin_command (cmd);\n";
7670 let emit_print_list_function typ =
7671 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
7674 pr " unsigned int i;\n";
7676 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7677 pr " printf (\"[%%d] = {\\n\", i);\n";
7678 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
7679 pr " printf (\"}\\n\");\n";
7685 (* print_* functions *)
7689 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
7691 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
7694 pr " unsigned int i;\n";
7700 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
7702 pr " printf (\"%%s%s: \", indent);\n" name;
7703 pr " for (i = 0; i < 32; ++i)\n";
7704 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7705 pr " printf (\"\\n\");\n"
7707 pr " printf (\"%%s%s: \", indent);\n" name;
7708 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
7709 pr " if (c_isprint (%s->%s[i]))\n" typ name;
7710 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
7712 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
7713 pr " printf (\"\\n\");\n"
7714 | name, (FUInt64|FBytes) ->
7715 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
7718 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
7721 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
7724 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
7727 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
7729 | name, FOptPercent ->
7730 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
7731 typ name name typ name;
7732 pr " else printf (\"%%s%s: \\n\", indent);\n" name
7738 (* Emit a print_TYPE_list function definition only if that function is used. *)
7741 | typ, (RStructListOnly | RStructAndList) ->
7742 (* generate the function for typ *)
7743 emit_print_list_function typ
7744 | typ, _ -> () (* empty *)
7745 ) (rstructs_used_by all_functions);
7747 (* Emit a print_TYPE function definition only if that function is used. *)
7750 | typ, (RStructOnly | RStructAndList) ->
7751 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
7753 pr " print_%s_indent (%s, \"\");\n" typ typ;
7756 | typ, _ -> () (* empty *)
7757 ) (rstructs_used_by all_functions);
7759 (* run_<action> actions *)
7761 fun (name, style, _, flags, _, _, _) ->
7762 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
7764 (match fst style with
7767 | RBool _ -> pr " int r;\n"
7768 | RInt64 _ -> pr " int64_t r;\n"
7769 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
7770 | RString _ -> pr " char *r;\n"
7771 | RStringList _ | RHashtable _ -> pr " char **r;\n"
7772 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
7773 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
7776 pr " size_t size;\n";
7782 | OptString n -> pr " const char *%s;\n" n
7786 | FileOut n -> pr " char *%s;\n" n
7788 pr " const char *%s;\n" n;
7789 pr " size_t %s_size;\n" n
7790 | StringList n | DeviceList n -> pr " char **%s;\n" n
7791 | Bool n -> pr " int %s;\n" n
7792 | Int n -> pr " int %s;\n" n
7793 | Int64 n -> pr " int64_t %s;\n" n
7796 (* Check and convert parameters. *)
7797 let argc_expected = List.length (snd style) in
7798 pr " if (argc != %d) {\n" argc_expected;
7799 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
7801 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
7805 let parse_integer fn fntyp rtyp range name i =
7807 pr " strtol_error xerr;\n";
7808 pr " %s r;\n" fntyp;
7810 pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
7811 pr " if (xerr != LONGINT_OK) {\n";
7812 pr " fprintf (stderr,\n";
7813 pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";
7814 pr " cmd, \"%s\", \"%s\", xerr);\n" name fn;
7819 | Some (min, max, comment) ->
7820 pr " /* %s */\n" comment;
7821 pr " if (r < %s || r > %s) {\n" min max;
7822 pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n"
7826 pr " /* The check above should ensure this assignment does not overflow. */\n";
7828 pr " %s = r;\n" name;
7837 pr " %s = argv[%d];\n" name i
7839 | Dev_or_Path name ->
7840 pr " %s = resolve_win_path (argv[%d]);\n" name i;
7841 pr " if (%s == NULL) return -1;\n" name
7843 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
7846 pr " %s = argv[%d];\n" name i;
7847 pr " %s_size = strlen (argv[%d]);\n" name i
7849 pr " %s = file_in (argv[%d]);\n" name i;
7850 pr " if (%s == NULL) return -1;\n" name
7852 pr " %s = file_out (argv[%d]);\n" name i;
7853 pr " if (%s == NULL) return -1;\n" name
7854 | StringList name | DeviceList name ->
7855 pr " %s = parse_string_list (argv[%d]);\n" name i;
7856 pr " if (%s == NULL) return -1;\n" name;
7858 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
7861 let min = "(-(2LL<<30))"
7862 and max = "((2LL<<30)-1)"
7864 "The Int type in the generator is a signed 31 bit int." in
7865 Some (min, max, comment) in
7866 parse_integer "xstrtoll" "long long" "int" range name i
7868 parse_integer "xstrtoll" "long long" "int64_t" None name i
7871 (* Call C API function. *)
7872 pr " r = guestfs_%s " name;
7873 generate_c_call_args ~handle:"g" style;
7878 | Device name | String name
7879 | OptString name | Bool name
7880 | Int name | Int64 name
7881 | BufferIn name -> ()
7882 | Pathname name | Dev_or_Path name | FileOut name ->
7883 pr " free (%s);\n" name
7885 pr " free_file_in (%s);\n" name
7886 | StringList name | DeviceList name ->
7887 pr " free_strings (%s);\n" name
7890 (* Any output flags? *)
7892 let flags = filter_map (
7893 function FishOutput flag -> Some flag | _ -> None
7899 failwithf "%s: more than one FishOutput flag is not allowed" name in
7901 (* Check return value for errors and display command results. *)
7902 (match fst style with
7903 | RErr -> pr " return r;\n"
7905 pr " if (r == -1) return -1;\n";
7906 (match fish_output with
7908 pr " printf (\"%%d\\n\", r);\n";
7909 | Some FishOutputOctal ->
7910 pr " printf (\"%%s%%o\\n\", r != 0 ? \"0\" : \"\", r);\n";
7911 | Some FishOutputHexadecimal ->
7912 pr " printf (\"%%s%%x\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7915 pr " if (r == -1) return -1;\n";
7916 (match fish_output with
7918 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
7919 | Some FishOutputOctal ->
7920 pr " printf (\"%%s%%\" PRIo64 \"\\n\", r != 0 ? \"0\" : \"\", r);\n";
7921 | Some FishOutputHexadecimal ->
7922 pr " printf (\"%%s%%\" PRIx64 \"\\n\", r != 0 ? \"0x\" : \"\", r);\n");
7925 pr " if (r == -1) return -1;\n";
7926 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
7929 pr " if (r == NULL) return -1;\n";
7930 pr " printf (\"%%s\\n\", r);\n";
7932 | RConstOptString _ ->
7933 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
7936 pr " if (r == NULL) return -1;\n";
7937 pr " printf (\"%%s\\n\", r);\n";
7941 pr " if (r == NULL) return -1;\n";
7942 pr " print_strings (r);\n";
7943 pr " free_strings (r);\n";
7945 | RStruct (_, typ) ->
7946 pr " if (r == NULL) return -1;\n";
7947 pr " print_%s (r);\n" typ;
7948 pr " guestfs_free_%s (r);\n" typ;
7950 | RStructList (_, typ) ->
7951 pr " if (r == NULL) return -1;\n";
7952 pr " print_%s_list (r);\n" typ;
7953 pr " guestfs_free_%s_list (r);\n" typ;
7956 pr " if (r == NULL) return -1;\n";
7957 pr " print_table (r);\n";
7958 pr " free_strings (r);\n";
7961 pr " if (r == NULL) return -1;\n";
7962 pr " if (full_write (1, r, size) != size) {\n";
7963 pr " perror (\"write\");\n";
7974 (* run_action function *)
7975 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
7978 fun (name, _, _, flags, _, _, _) ->
7979 let name2 = replace_char name '_' '-' in
7981 try find_map (function FishAlias n -> Some n | _ -> None) flags
7982 with Not_found -> name in
7984 pr "STRCASEEQ (cmd, \"%s\")" name;
7985 if name <> name2 then
7986 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7987 if name <> alias then
7988 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7990 pr " return run_%s (cmd, argc, argv);\n" name;
7994 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
7995 pr " if (command_num == 1)\n";
7996 pr " extended_help_message ();\n";
8003 (* Readline completion for guestfish. *)
8004 and generate_fish_completion () =
8005 generate_header CStyle GPLv2plus;
8009 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
8019 #ifdef HAVE_LIBREADLINE
8020 #include <readline/readline.h>
8025 #ifdef HAVE_LIBREADLINE
8027 static const char *const commands[] = {
8028 BUILTIN_COMMANDS_FOR_COMPLETION,
8031 (* Get the commands, including the aliases. They don't need to be
8032 * sorted - the generator() function just does a dumb linear search.
8036 fun (name, _, _, flags, _, _, _) ->
8037 let name2 = replace_char name '_' '-' in
8039 try find_map (function FishAlias n -> Some n | _ -> None) flags
8040 with Not_found -> name in
8042 if name <> alias then [name2; alias] else [name2]
8044 let commands = List.flatten commands in
8046 List.iter (pr " \"%s\",\n") commands;
8052 generator (const char *text, int state)
8054 static int index, len;
8059 len = strlen (text);
8062 rl_attempted_completion_over = 1;
8064 while ((name = commands[index]) != NULL) {
8066 if (STRCASEEQLEN (name, text, len))
8067 return strdup (name);
8073 #endif /* HAVE_LIBREADLINE */
8075 #ifdef HAVE_RL_COMPLETION_MATCHES
8076 #define RL_COMPLETION_MATCHES rl_completion_matches
8078 #ifdef HAVE_COMPLETION_MATCHES
8079 #define RL_COMPLETION_MATCHES completion_matches
8081 #endif /* else just fail if we don't have either symbol */
8084 do_completion (const char *text, int start, int end)
8086 char **matches = NULL;
8088 #ifdef HAVE_LIBREADLINE
8089 rl_completion_append_character = ' ';
8092 matches = RL_COMPLETION_MATCHES (text, generator);
8093 else if (complete_dest_paths)
8094 matches = RL_COMPLETION_MATCHES (text, complete_dest_paths_generator);
8101 (* Generate the POD documentation for guestfish. *)
8102 and generate_fish_actions_pod () =
8103 let all_functions_sorted =
8105 fun (_, _, _, flags, _, _, _) ->
8106 not (List.mem NotInFish flags || List.mem NotInDocs flags)
8107 ) all_functions_sorted in
8109 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
8112 fun (name, style, _, flags, _, _, longdesc) ->
8114 Str.global_substitute rex (
8117 try Str.matched_group 1 s
8119 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
8120 "C<" ^ replace_char sub '_' '-' ^ ">"
8122 let name = replace_char name '_' '-' in
8124 try find_map (function FishAlias n -> Some n | _ -> None) flags
8125 with Not_found -> name in
8127 pr "=head2 %s" name;
8128 if name <> alias then
8135 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
8136 | OptString n -> pr " %s" n
8137 | StringList n | DeviceList n -> pr " '%s ...'" n
8138 | Bool _ -> pr " true|false"
8139 | Int n -> pr " %s" n
8140 | Int64 n -> pr " %s" n
8141 | FileIn n | FileOut n -> pr " (%s|-)" n
8142 | BufferIn n -> pr " %s" n
8146 pr "%s\n\n" longdesc;
8148 if List.exists (function FileIn _ | FileOut _ -> true
8149 | _ -> false) (snd style) then
8150 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
8152 if List.mem ProtocolLimitWarning flags then
8153 pr "%s\n\n" protocol_limit_warning;
8155 if List.mem DangerWillRobinson flags then
8156 pr "%s\n\n" danger_will_robinson;
8158 match deprecation_notice flags with
8160 | Some txt -> pr "%s\n\n" txt
8161 ) all_functions_sorted
8163 (* Generate a C function prototype. *)
8164 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
8165 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
8167 ?handle name style =
8168 if extern then pr "extern ";
8169 if static then pr "static ";
8170 (match fst style with
8172 | RInt _ -> pr "int "
8173 | RInt64 _ -> pr "int64_t "
8174 | RBool _ -> pr "int "
8175 | RConstString _ | RConstOptString _ -> pr "const char *"
8176 | RString _ | RBufferOut _ -> pr "char *"
8177 | RStringList _ | RHashtable _ -> pr "char **"
8178 | RStruct (_, typ) ->
8179 if not in_daemon then pr "struct guestfs_%s *" typ
8180 else pr "guestfs_int_%s *" typ
8181 | RStructList (_, typ) ->
8182 if not in_daemon then pr "struct guestfs_%s_list *" typ
8183 else pr "guestfs_int_%s_list *" typ
8185 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
8186 pr "%s%s (" prefix name;
8187 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
8190 let comma = ref false in
8193 | Some handle -> pr "guestfs_h *%s" handle; comma := true
8197 if single_line then pr ", " else pr ",\n\t\t"
8204 | Device n | Dev_or_Path n
8208 pr "const char *%s" n
8209 | StringList n | DeviceList n ->
8211 pr "char *const *%s" n
8212 | Bool n -> next (); pr "int %s" n
8213 | Int n -> next (); pr "int %s" n
8214 | Int64 n -> next (); pr "int64_t %s" n
8217 if not in_daemon then (next (); pr "const char *%s" n)
8220 pr "const char *%s" n;
8222 pr "size_t %s_size" n
8224 if is_RBufferOut then (next (); pr "size_t *size_r");
8227 if semicolon then pr ";";
8228 if newline then pr "\n"
8230 (* Generate C call arguments, eg "(handle, foo, bar)" *)
8231 and generate_c_call_args ?handle ?(decl = false) style =
8233 let comma = ref false in
8235 if !comma then pr ", ";
8240 | Some handle -> pr "%s" handle; comma := true
8246 pr "%s, %s_size" n n
8249 pr "%s" (name_of_argt arg)
8251 (* For RBufferOut calls, add implicit &size parameter. *)
8253 match fst style with
8261 (* Generate the OCaml bindings interface. *)
8262 and generate_ocaml_mli () =
8263 generate_header OCamlStyle LGPLv2plus;
8266 (** For API documentation you should refer to the C API
8267 in the guestfs(3) manual page. The OCaml API uses almost
8268 exactly the same calls. *)
8271 (** A [guestfs_h] handle. *)
8273 exception Error of string
8274 (** This exception is raised when there is an error. *)
8276 exception Handle_closed of string
8277 (** This exception is raised if you use a {!Guestfs.t} handle
8278 after calling {!close} on it. The string is the name of
8281 val create : unit -> t
8282 (** Create a {!Guestfs.t} handle. *)
8284 val close : t -> unit
8285 (** Close the {!Guestfs.t} handle and free up all resources used
8288 Handles are closed by the garbage collector when they become
8289 unreferenced, but callers can call this in order to provide
8290 predictable cleanup. *)
8293 generate_ocaml_structure_decls ();
8297 fun (name, style, _, _, _, shortdesc, _) ->
8298 generate_ocaml_prototype name style;
8299 pr "(** %s *)\n" shortdesc;
8301 ) all_functions_sorted
8303 (* Generate the OCaml bindings implementation. *)
8304 and generate_ocaml_ml () =
8305 generate_header OCamlStyle LGPLv2plus;
8310 exception Error of string
8311 exception Handle_closed of string
8313 external create : unit -> t = \"ocaml_guestfs_create\"
8314 external close : t -> unit = \"ocaml_guestfs_close\"
8316 (* Give the exceptions names, so they can be raised from the C code. *)
8318 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
8319 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
8323 generate_ocaml_structure_decls ();
8327 fun (name, style, _, _, _, shortdesc, _) ->
8328 generate_ocaml_prototype ~is_external:true name style;
8329 ) all_functions_sorted
8331 (* Generate the OCaml bindings C implementation. *)
8332 and generate_ocaml_c () =
8333 generate_header CStyle LGPLv2plus;
8340 #include <caml/config.h>
8341 #include <caml/alloc.h>
8342 #include <caml/callback.h>
8343 #include <caml/fail.h>
8344 #include <caml/memory.h>
8345 #include <caml/mlvalues.h>
8346 #include <caml/signals.h>
8348 #include <guestfs.h>
8350 #include \"guestfs_c.h\"
8352 /* Copy a hashtable of string pairs into an assoc-list. We return
8353 * the list in reverse order, but hashtables aren't supposed to be
8356 static CAMLprim value
8357 copy_table (char * const * argv)
8360 CAMLlocal5 (rv, pairv, kv, vv, cons);
8364 for (i = 0; argv[i] != NULL; i += 2) {
8365 kv = caml_copy_string (argv[i]);
8366 vv = caml_copy_string (argv[i+1]);
8367 pairv = caml_alloc (2, 0);
8368 Store_field (pairv, 0, kv);
8369 Store_field (pairv, 1, vv);
8370 cons = caml_alloc (2, 0);
8371 Store_field (cons, 1, rv);
8373 Store_field (cons, 0, pairv);
8381 (* Struct copy functions. *)
8383 let emit_ocaml_copy_list_function typ =
8384 pr "static CAMLprim value\n";
8385 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
8387 pr " CAMLparam0 ();\n";
8388 pr " CAMLlocal2 (rv, v);\n";
8389 pr " unsigned int i;\n";
8391 pr " if (%ss->len == 0)\n" typ;
8392 pr " CAMLreturn (Atom (0));\n";
8394 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
8395 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
8396 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
8397 pr " caml_modify (&Field (rv, i), v);\n";
8399 pr " CAMLreturn (rv);\n";
8407 let has_optpercent_col =
8408 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
8410 pr "static CAMLprim value\n";
8411 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
8413 pr " CAMLparam0 ();\n";
8414 if has_optpercent_col then
8415 pr " CAMLlocal3 (rv, v, v2);\n"
8417 pr " CAMLlocal2 (rv, v);\n";
8419 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
8424 pr " v = caml_copy_string (%s->%s);\n" typ name
8426 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
8427 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
8430 pr " v = caml_alloc_string (32);\n";
8431 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
8432 | name, (FBytes|FInt64|FUInt64) ->
8433 pr " v = caml_copy_int64 (%s->%s);\n" typ name
8434 | name, (FInt32|FUInt32) ->
8435 pr " v = caml_copy_int32 (%s->%s);\n" typ name
8436 | name, FOptPercent ->
8437 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
8438 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
8439 pr " v = caml_alloc (1, 0);\n";
8440 pr " Store_field (v, 0, v2);\n";
8441 pr " } else /* None */\n";
8442 pr " v = Val_int (0);\n";
8444 pr " v = Val_int (%s->%s);\n" typ name
8446 pr " Store_field (rv, %d, v);\n" i
8448 pr " CAMLreturn (rv);\n";
8453 (* Emit a copy_TYPE_list function definition only if that function is used. *)
8456 | typ, (RStructListOnly | RStructAndList) ->
8457 (* generate the function for typ *)
8458 emit_ocaml_copy_list_function typ
8459 | typ, _ -> () (* empty *)
8460 ) (rstructs_used_by all_functions);
8464 fun (name, style, _, _, _, _, _) ->
8465 pr "/* Automatically generated wrapper for function\n";
8467 generate_ocaml_prototype name style;
8472 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
8474 let needs_extra_vs =
8475 match fst style with RConstOptString _ -> true | _ -> false in
8477 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8478 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
8479 List.iter (pr ", value %s") (List.tl params); pr ");\n";
8482 pr "CAMLprim value\n";
8483 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
8484 List.iter (pr ", value %s") (List.tl params);
8489 | [p1; p2; p3; p4; p5] ->
8490 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
8491 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
8492 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
8493 pr " CAMLxparam%d (%s);\n"
8494 (List.length rest) (String.concat ", " rest)
8496 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
8498 if not needs_extra_vs then
8499 pr " CAMLlocal1 (rv);\n"
8501 pr " CAMLlocal3 (rv, v, v2);\n";
8504 pr " guestfs_h *g = Guestfs_val (gv);\n";
8505 pr " if (g == NULL)\n";
8506 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
8512 | Device n | Dev_or_Path n
8516 pr " const char *%s = String_val (%sv);\n" n n
8518 pr " const char *%s =\n" n;
8519 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
8522 pr " const char *%s = String_val (%sv);\n" n n;
8523 pr " size_t %s_size = caml_string_length (%sv);\n" n n
8524 | StringList n | DeviceList n ->
8525 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
8527 pr " int %s = Bool_val (%sv);\n" n n
8529 pr " int %s = Int_val (%sv);\n" n n
8531 pr " int64_t %s = Int64_val (%sv);\n" n n
8534 match fst style with
8535 | RErr -> pr " int r;\n"; "-1"
8536 | RInt _ -> pr " int r;\n"; "-1"
8537 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8538 | RBool _ -> pr " int r;\n"; "-1"
8539 | RConstString _ | RConstOptString _ ->
8540 pr " const char *r;\n"; "NULL"
8541 | RString _ -> pr " char *r;\n"; "NULL"
8546 | RStruct (_, typ) ->
8547 pr " struct guestfs_%s *r;\n" typ; "NULL"
8548 | RStructList (_, typ) ->
8549 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8556 pr " size_t size;\n";
8560 pr " caml_enter_blocking_section ();\n";
8561 pr " r = guestfs_%s " name;
8562 generate_c_call_args ~handle:"g" style;
8564 pr " caml_leave_blocking_section ();\n";
8568 | StringList n | DeviceList n ->
8569 pr " ocaml_guestfs_free_strings (%s);\n" n;
8570 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8571 | Bool _ | Int _ | Int64 _
8572 | FileIn _ | FileOut _ | BufferIn _ -> ()
8575 pr " if (r == %s)\n" error_code;
8576 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
8579 (match fst style with
8580 | RErr -> pr " rv = Val_unit;\n"
8581 | RInt _ -> pr " rv = Val_int (r);\n"
8583 pr " rv = caml_copy_int64 (r);\n"
8584 | RBool _ -> pr " rv = Val_bool (r);\n"
8586 pr " rv = caml_copy_string (r);\n"
8587 | RConstOptString _ ->
8588 pr " if (r) { /* Some string */\n";
8589 pr " v = caml_alloc (1, 0);\n";
8590 pr " v2 = caml_copy_string (r);\n";
8591 pr " Store_field (v, 0, v2);\n";
8592 pr " } else /* None */\n";
8593 pr " v = Val_int (0);\n";
8595 pr " rv = caml_copy_string (r);\n";
8598 pr " rv = caml_copy_string_array ((const char **) r);\n";
8599 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8601 | RStruct (_, typ) ->
8602 pr " rv = copy_%s (r);\n" typ;
8603 pr " guestfs_free_%s (r);\n" typ;
8604 | RStructList (_, typ) ->
8605 pr " rv = copy_%s_list (r);\n" typ;
8606 pr " guestfs_free_%s_list (r);\n" typ;
8608 pr " rv = copy_table (r);\n";
8609 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
8612 pr " rv = caml_alloc_string (size);\n";
8613 pr " memcpy (String_val (rv), r, size);\n";
8616 pr " CAMLreturn (rv);\n";
8620 if List.length params > 5 then (
8621 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
8622 pr "CAMLprim value ";
8623 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
8624 pr "CAMLprim value\n";
8625 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
8627 pr " return ocaml_guestfs_%s (argv[0]" name;
8628 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
8633 ) all_functions_sorted
8635 and generate_ocaml_structure_decls () =
8638 pr "type %s = {\n" typ;
8641 | name, FString -> pr " %s : string;\n" name
8642 | name, FBuffer -> pr " %s : string;\n" name
8643 | name, FUUID -> pr " %s : string;\n" name
8644 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
8645 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
8646 | name, FChar -> pr " %s : char;\n" name
8647 | name, FOptPercent -> pr " %s : float option;\n" name
8653 and generate_ocaml_prototype ?(is_external = false) name style =
8654 if is_external then pr "external " else pr "val ";
8655 pr "%s : t -> " name;
8658 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _
8659 | BufferIn _ -> pr "string -> "
8660 | OptString _ -> pr "string option -> "
8661 | StringList _ | DeviceList _ -> pr "string array -> "
8662 | Bool _ -> pr "bool -> "
8663 | Int _ -> pr "int -> "
8664 | Int64 _ -> pr "int64 -> "
8666 (match fst style with
8667 | RErr -> pr "unit" (* all errors are turned into exceptions *)
8668 | RInt _ -> pr "int"
8669 | RInt64 _ -> pr "int64"
8670 | RBool _ -> pr "bool"
8671 | RConstString _ -> pr "string"
8672 | RConstOptString _ -> pr "string option"
8673 | RString _ | RBufferOut _ -> pr "string"
8674 | RStringList _ -> pr "string array"
8675 | RStruct (_, typ) -> pr "%s" typ
8676 | RStructList (_, typ) -> pr "%s array" typ
8677 | RHashtable _ -> pr "(string * string) list"
8679 if is_external then (
8681 if List.length (snd style) + 1 > 5 then
8682 pr "\"ocaml_guestfs_%s_byte\" " name;
8683 pr "\"ocaml_guestfs_%s\"" name
8687 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
8688 and generate_perl_xs () =
8689 generate_header CStyle LGPLv2plus;
8692 #include \"EXTERN.h\"
8696 #include <guestfs.h>
8699 #define PRId64 \"lld\"
8703 my_newSVll(long long val) {
8704 #ifdef USE_64_BIT_ALL
8705 return newSViv(val);
8709 len = snprintf(buf, 100, \"%%\" PRId64, val);
8710 return newSVpv(buf, len);
8715 #define PRIu64 \"llu\"
8719 my_newSVull(unsigned long long val) {
8720 #ifdef USE_64_BIT_ALL
8721 return newSVuv(val);
8725 len = snprintf(buf, 100, \"%%\" PRIu64, val);
8726 return newSVpv(buf, len);
8730 /* http://www.perlmonks.org/?node_id=680842 */
8732 XS_unpack_charPtrPtr (SV *arg) {
8737 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
8738 croak (\"array reference expected\");
8740 av = (AV *)SvRV (arg);
8741 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
8743 croak (\"malloc failed\");
8745 for (i = 0; i <= av_len (av); i++) {
8746 SV **elem = av_fetch (av, i, 0);
8748 if (!elem || !*elem)
8749 croak (\"missing element in list\");
8751 ret[i] = SvPV_nolen (*elem);
8759 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
8766 RETVAL = guestfs_create ();
8768 croak (\"could not create guestfs handle\");
8769 guestfs_set_error_handler (RETVAL, NULL, NULL);
8782 fun (name, style, _, _, _, _, _) ->
8783 (match fst style with
8784 | RErr -> pr "void\n"
8785 | RInt _ -> pr "SV *\n"
8786 | RInt64 _ -> pr "SV *\n"
8787 | RBool _ -> pr "SV *\n"
8788 | RConstString _ -> pr "SV *\n"
8789 | RConstOptString _ -> pr "SV *\n"
8790 | RString _ -> pr "SV *\n"
8791 | RBufferOut _ -> pr "SV *\n"
8793 | RStruct _ | RStructList _
8795 pr "void\n" (* all lists returned implictly on the stack *)
8797 (* Call and arguments. *)
8800 fun arg -> pr ", %s" (name_of_argt arg)
8803 pr " guestfs_h *g;\n";
8807 | Pathname n | Device n | Dev_or_Path n | String n
8808 | FileIn n | FileOut n ->
8811 pr " char *%s;\n" n;
8812 pr " size_t %s_size = SvCUR (ST(%d));\n" n (i+1)
8814 (* http://www.perlmonks.org/?node_id=554277
8815 * Note that the implicit handle argument means we have
8816 * to add 1 to the ST(x) operator.
8818 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
8819 | StringList n | DeviceList n -> pr " char **%s;\n" n
8820 | Bool n -> pr " int %s;\n" n
8821 | Int n -> pr " int %s;\n" n
8822 | Int64 n -> pr " int64_t %s;\n" n
8825 let do_cleanups () =
8828 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
8829 | Bool _ | Int _ | Int64 _
8830 | FileIn _ | FileOut _
8832 | StringList n | DeviceList n -> pr " free (%s);\n" n
8837 (match fst style with
8842 pr " r = guestfs_%s " name;
8843 generate_c_call_args ~handle:"g" style;
8846 pr " if (r == -1)\n";
8847 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8853 pr " %s = guestfs_%s " n name;
8854 generate_c_call_args ~handle:"g" style;
8857 pr " if (%s == -1)\n" n;
8858 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8859 pr " RETVAL = newSViv (%s);\n" n;
8864 pr " int64_t %s;\n" n;
8866 pr " %s = guestfs_%s " n name;
8867 generate_c_call_args ~handle:"g" style;
8870 pr " if (%s == -1)\n" n;
8871 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8872 pr " RETVAL = my_newSVll (%s);\n" n;
8877 pr " const char *%s;\n" n;
8879 pr " %s = guestfs_%s " n name;
8880 generate_c_call_args ~handle:"g" style;
8883 pr " if (%s == NULL)\n" n;
8884 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8885 pr " RETVAL = newSVpv (%s, 0);\n" n;
8888 | RConstOptString n ->
8890 pr " const char *%s;\n" n;
8892 pr " %s = guestfs_%s " n name;
8893 generate_c_call_args ~handle:"g" style;
8896 pr " if (%s == NULL)\n" n;
8897 pr " RETVAL = &PL_sv_undef;\n";
8899 pr " RETVAL = newSVpv (%s, 0);\n" n;
8904 pr " char *%s;\n" n;
8906 pr " %s = guestfs_%s " n name;
8907 generate_c_call_args ~handle:"g" style;
8910 pr " if (%s == NULL)\n" n;
8911 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8912 pr " RETVAL = newSVpv (%s, 0);\n" n;
8913 pr " free (%s);\n" n;
8916 | RStringList n | RHashtable n ->
8918 pr " char **%s;\n" n;
8921 pr " %s = guestfs_%s " n name;
8922 generate_c_call_args ~handle:"g" style;
8925 pr " if (%s == NULL)\n" n;
8926 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8927 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
8928 pr " EXTEND (SP, n);\n";
8929 pr " for (i = 0; i < n; ++i) {\n";
8930 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
8931 pr " free (%s[i]);\n" n;
8933 pr " free (%s);\n" n;
8934 | RStruct (n, typ) ->
8935 let cols = cols_of_struct typ in
8936 generate_perl_struct_code typ cols name style n do_cleanups
8937 | RStructList (n, typ) ->
8938 let cols = cols_of_struct typ in
8939 generate_perl_struct_list_code typ cols name style n do_cleanups
8942 pr " char *%s;\n" n;
8943 pr " size_t size;\n";
8945 pr " %s = guestfs_%s " n name;
8946 generate_c_call_args ~handle:"g" style;
8949 pr " if (%s == NULL)\n" n;
8950 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8951 pr " RETVAL = newSVpvn (%s, size);\n" n;
8952 pr " free (%s);\n" n;
8960 and generate_perl_struct_list_code typ cols name style n do_cleanups =
8962 pr " struct guestfs_%s_list *%s;\n" typ n;
8966 pr " %s = guestfs_%s " n name;
8967 generate_c_call_args ~handle:"g" style;
8970 pr " if (%s == NULL)\n" n;
8971 pr " croak (\"%%s\", guestfs_last_error (g));\n";
8972 pr " EXTEND (SP, %s->len);\n" n;
8973 pr " for (i = 0; i < %s->len; ++i) {\n" n;
8974 pr " hv = newHV ();\n";
8978 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
8979 name (String.length name) n name
8981 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
8982 name (String.length name) n name
8984 pr " (void) hv_store (hv, \"%s\", %d, newSVpvn (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
8985 name (String.length name) n name n name
8986 | name, (FBytes|FUInt64) ->
8987 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
8988 name (String.length name) n name
8990 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
8991 name (String.length name) n name
8992 | name, (FInt32|FUInt32) ->
8993 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
8994 name (String.length name) n name
8996 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
8997 name (String.length name) n name
8998 | name, FOptPercent ->
8999 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
9000 name (String.length name) n name
9002 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
9004 pr " guestfs_free_%s_list (%s);\n" typ n
9006 and generate_perl_struct_code typ cols name style n do_cleanups =
9008 pr " struct guestfs_%s *%s;\n" typ n;
9010 pr " %s = guestfs_%s " n name;
9011 generate_c_call_args ~handle:"g" style;
9014 pr " if (%s == NULL)\n" n;
9015 pr " croak (\"%%s\", guestfs_last_error (g));\n";
9016 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
9018 fun ((name, _) as col) ->
9019 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
9023 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
9026 pr " PUSHs (sv_2mortal (newSVpvn (%s->%s, %s->%s_len)));\n"
9029 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
9031 | name, (FBytes|FUInt64) ->
9032 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
9035 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
9037 | name, (FInt32|FUInt32) ->
9038 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9041 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
9043 | name, FOptPercent ->
9044 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
9047 pr " free (%s);\n" n
9049 (* Generate Sys/Guestfs.pm. *)
9050 and generate_perl_pm () =
9051 generate_header HashStyle LGPLv2plus;
9058 Sys::Guestfs - Perl bindings for libguestfs
9064 my $h = Sys::Guestfs->new ();
9065 $h->add_drive ('guest.img');
9067 $h->mount ('/dev/sda1', '/');
9068 $h->touch ('/hello');
9073 The C<Sys::Guestfs> module provides a Perl XS binding to the
9074 libguestfs API for examining and modifying virtual machine
9077 Amongst the things this is good for: making batch configuration
9078 changes to guests, getting disk used/free statistics (see also:
9079 virt-df), migrating between virtualization systems (see also:
9080 virt-p2v), performing partial backups, performing partial guest
9081 clones, cloning guests and changing registry/UUID/hostname info, and
9084 Libguestfs uses Linux kernel and qemu code, and can access any type of
9085 guest filesystem that Linux and qemu can, including but not limited
9086 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9087 schemes, qcow, qcow2, vmdk.
9089 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9090 LVs, what filesystem is in each LV, etc.). It can also run commands
9091 in the context of the guest. Also you can access filesystems over
9094 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
9095 functions for using libguestfs from Perl, including integration
9100 All errors turn into calls to C<croak> (see L<Carp(3)>).
9108 package Sys::Guestfs;
9113 # This version number changes whenever a new function
9114 # is added to the libguestfs API. It is not directly
9115 # related to the libguestfs version number.
9116 use vars qw($VERSION);
9120 XSLoader::load ('Sys::Guestfs');
9122 =item $h = Sys::Guestfs->new ();
9124 Create a new guestfs handle.
9130 my $class = ref ($proto) || $proto;
9132 my $self = Sys::Guestfs::_create ();
9133 bless $self, $class;
9139 (* Actions. We only need to print documentation for these as
9140 * they are pulled in from the XS code automatically.
9143 fun (name, style, _, flags, _, _, longdesc) ->
9144 if not (List.mem NotInDocs flags) then (
9145 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
9147 generate_perl_prototype name style;
9149 pr "%s\n\n" longdesc;
9150 if List.mem ProtocolLimitWarning flags then
9151 pr "%s\n\n" protocol_limit_warning;
9152 if List.mem DangerWillRobinson flags then
9153 pr "%s\n\n" danger_will_robinson;
9154 match deprecation_notice flags with
9156 | Some txt -> pr "%s\n\n" txt
9158 ) all_functions_sorted;
9170 Copyright (C) %s Red Hat Inc.
9174 Please see the file COPYING.LIB for the full license.
9180 L<http://libguestfs.org>,
9181 L<Sys::Guestfs::Lib(3)>.
9186 and generate_perl_prototype name style =
9187 (match fst style with
9195 | RBufferOut n -> pr "$%s = " n
9197 | RHashtable n -> pr "%%%s = " n
9199 | RStructList (n,_) -> pr "@%s = " n
9202 let comma = ref false in
9205 if !comma then pr ", ";
9208 | Pathname n | Device n | Dev_or_Path n | String n
9209 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
9212 | StringList n | DeviceList n ->
9217 (* Generate Python C module. *)
9218 and generate_python_c () =
9219 generate_header CStyle LGPLv2plus;
9222 #define PY_SSIZE_T_CLEAN 1
9225 #if PY_VERSION_HEX < 0x02050000
9226 typedef int Py_ssize_t;
9227 #define PY_SSIZE_T_MAX INT_MAX
9228 #define PY_SSIZE_T_MIN INT_MIN
9235 #include \"guestfs.h\"
9243 get_handle (PyObject *obj)
9246 assert (obj != Py_None);
9247 return ((Pyguestfs_Object *) obj)->g;
9251 put_handle (guestfs_h *g)
9255 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
9258 /* This list should be freed (but not the strings) after use. */
9260 get_string_list (PyObject *obj)
9267 if (!PyList_Check (obj)) {
9268 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
9272 len = PyList_Size (obj);
9273 r = malloc (sizeof (char *) * (len+1));
9275 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
9279 for (i = 0; i < len; ++i)
9280 r[i] = PyString_AsString (PyList_GetItem (obj, i));
9287 put_string_list (char * const * const argv)
9292 for (argc = 0; argv[argc] != NULL; ++argc)
9295 list = PyList_New (argc);
9296 for (i = 0; i < argc; ++i)
9297 PyList_SetItem (list, i, PyString_FromString (argv[i]));
9303 put_table (char * const * const argv)
9305 PyObject *list, *item;
9308 for (argc = 0; argv[argc] != NULL; ++argc)
9311 list = PyList_New (argc >> 1);
9312 for (i = 0; i < argc; i += 2) {
9313 item = PyTuple_New (2);
9314 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
9315 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
9316 PyList_SetItem (list, i >> 1, item);
9323 free_strings (char **argv)
9327 for (argc = 0; argv[argc] != NULL; ++argc)
9333 py_guestfs_create (PyObject *self, PyObject *args)
9337 g = guestfs_create ();
9339 PyErr_SetString (PyExc_RuntimeError,
9340 \"guestfs.create: failed to allocate handle\");
9343 guestfs_set_error_handler (g, NULL, NULL);
9344 return put_handle (g);
9348 py_guestfs_close (PyObject *self, PyObject *args)
9353 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
9355 g = get_handle (py_g);
9359 Py_INCREF (Py_None);
9365 let emit_put_list_function typ =
9366 pr "static PyObject *\n";
9367 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
9369 pr " PyObject *list;\n";
9372 pr " list = PyList_New (%ss->len);\n" typ;
9373 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
9374 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
9375 pr " return list;\n";
9380 (* Structures, turned into Python dictionaries. *)
9383 pr "static PyObject *\n";
9384 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
9386 pr " PyObject *dict;\n";
9388 pr " dict = PyDict_New ();\n";
9392 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9393 pr " PyString_FromString (%s->%s));\n"
9396 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9397 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
9400 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9401 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
9403 | name, (FBytes|FUInt64) ->
9404 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9405 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
9408 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9409 pr " PyLong_FromLongLong (%s->%s));\n"
9412 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9413 pr " PyLong_FromUnsignedLong (%s->%s));\n"
9416 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9417 pr " PyLong_FromLong (%s->%s));\n"
9419 | name, FOptPercent ->
9420 pr " if (%s->%s >= 0)\n" typ name;
9421 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9422 pr " PyFloat_FromDouble ((double) %s->%s));\n"
9425 pr " Py_INCREF (Py_None);\n";
9426 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
9429 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
9430 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
9432 pr " return dict;\n";
9438 (* Emit a put_TYPE_list function definition only if that function is used. *)
9441 | typ, (RStructListOnly | RStructAndList) ->
9442 (* generate the function for typ *)
9443 emit_put_list_function typ
9444 | typ, _ -> () (* empty *)
9445 ) (rstructs_used_by all_functions);
9447 (* Python wrapper functions. *)
9449 fun (name, style, _, _, _, _, _) ->
9450 pr "static PyObject *\n";
9451 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
9454 pr " PyObject *py_g;\n";
9455 pr " guestfs_h *g;\n";
9456 pr " PyObject *py_r;\n";
9459 match fst style with
9460 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9461 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9462 | RConstString _ | RConstOptString _ ->
9463 pr " const char *r;\n"; "NULL"
9464 | RString _ -> pr " char *r;\n"; "NULL"
9465 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9466 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9467 | RStructList (_, typ) ->
9468 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9471 pr " size_t size;\n";
9476 | Pathname n | Device n | Dev_or_Path n | String n
9477 | FileIn n | FileOut n ->
9478 pr " const char *%s;\n" n
9479 | OptString n -> pr " const char *%s;\n" n
9481 pr " const char *%s;\n" n;
9482 pr " Py_ssize_t %s_size;\n" n
9483 | StringList n | DeviceList n ->
9484 pr " PyObject *py_%s;\n" n;
9485 pr " char **%s;\n" n
9486 | Bool n -> pr " int %s;\n" n
9487 | Int n -> pr " int %s;\n" n
9488 | Int64 n -> pr " long long %s;\n" n
9493 (* Convert the parameters. *)
9494 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
9497 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
9498 | OptString _ -> pr "z"
9499 | StringList _ | DeviceList _ -> pr "O"
9500 | Bool _ -> pr "i" (* XXX Python has booleans? *)
9502 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
9503 * emulate C's int/long/long long in Python?
9505 | BufferIn _ -> pr "s#"
9507 pr ":guestfs_%s\",\n" name;
9511 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
9512 | OptString n -> pr ", &%s" n
9513 | StringList n | DeviceList n -> pr ", &py_%s" n
9514 | Bool n -> pr ", &%s" n
9515 | Int n -> pr ", &%s" n
9516 | Int64 n -> pr ", &%s" n
9517 | BufferIn n -> pr ", &%s, &%s_size" n n
9521 pr " return NULL;\n";
9523 pr " g = get_handle (py_g);\n";
9526 | Pathname _ | Device _ | Dev_or_Path _ | String _
9527 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9529 | StringList n | DeviceList n ->
9530 pr " %s = get_string_list (py_%s);\n" n n;
9531 pr " if (!%s) return NULL;\n" n
9536 pr " r = guestfs_%s " name;
9537 generate_c_call_args ~handle:"g" style;
9542 | Pathname _ | Device _ | Dev_or_Path _ | String _
9543 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9545 | StringList n | DeviceList n ->
9546 pr " free (%s);\n" n
9549 pr " if (r == %s) {\n" error_code;
9550 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
9551 pr " return NULL;\n";
9555 (match fst style with
9557 pr " Py_INCREF (Py_None);\n";
9558 pr " py_r = Py_None;\n"
9560 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
9561 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
9562 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
9563 | RConstOptString _ ->
9565 pr " py_r = PyString_FromString (r);\n";
9567 pr " Py_INCREF (Py_None);\n";
9568 pr " py_r = Py_None;\n";
9571 pr " py_r = PyString_FromString (r);\n";
9574 pr " py_r = put_string_list (r);\n";
9575 pr " free_strings (r);\n"
9576 | RStruct (_, typ) ->
9577 pr " py_r = put_%s (r);\n" typ;
9578 pr " guestfs_free_%s (r);\n" typ
9579 | RStructList (_, typ) ->
9580 pr " py_r = put_%s_list (r);\n" typ;
9581 pr " guestfs_free_%s_list (r);\n" typ
9583 pr " py_r = put_table (r);\n";
9584 pr " free_strings (r);\n"
9586 pr " py_r = PyString_FromStringAndSize (r, size);\n";
9590 pr " return py_r;\n";
9595 (* Table of functions. *)
9596 pr "static PyMethodDef methods[] = {\n";
9597 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
9598 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
9600 fun (name, _, _, _, _, _, _) ->
9601 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
9604 pr " { NULL, NULL, 0, NULL }\n";
9608 (* Init function. *)
9611 initlibguestfsmod (void)
9613 static int initialized = 0;
9615 if (initialized) return;
9616 Py_InitModule ((char *) \"libguestfsmod\", methods);
9621 (* Generate Python module. *)
9622 and generate_python_py () =
9623 generate_header HashStyle LGPLv2plus;
9626 u\"\"\"Python bindings for libguestfs
9629 g = guestfs.GuestFS ()
9630 g.add_drive (\"guest.img\")
9632 parts = g.list_partitions ()
9634 The guestfs module provides a Python binding to the libguestfs API
9635 for examining and modifying virtual machine disk images.
9637 Amongst the things this is good for: making batch configuration
9638 changes to guests, getting disk used/free statistics (see also:
9639 virt-df), migrating between virtualization systems (see also:
9640 virt-p2v), performing partial backups, performing partial guest
9641 clones, cloning guests and changing registry/UUID/hostname info, and
9644 Libguestfs uses Linux kernel and qemu code, and can access any type of
9645 guest filesystem that Linux and qemu can, including but not limited
9646 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
9647 schemes, qcow, qcow2, vmdk.
9649 Libguestfs provides ways to enumerate guest storage (eg. partitions,
9650 LVs, what filesystem is in each LV, etc.). It can also run commands
9651 in the context of the guest. Also you can access filesystems over
9654 Errors which happen while using the API are turned into Python
9655 RuntimeError exceptions.
9657 To create a guestfs handle you usually have to perform the following
9660 # Create the handle, call add_drive at least once, and possibly
9661 # several times if the guest has multiple block devices:
9662 g = guestfs.GuestFS ()
9663 g.add_drive (\"guest.img\")
9665 # Launch the qemu subprocess and wait for it to become ready:
9668 # Now you can issue commands, for example:
9673 import libguestfsmod
9676 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
9678 def __init__ (self):
9679 \"\"\"Create a new libguestfs handle.\"\"\"
9680 self._o = libguestfsmod.create ()
9683 libguestfsmod.close (self._o)
9688 fun (name, style, _, flags, _, _, longdesc) ->
9690 generate_py_call_args ~handle:"self" (snd style);
9693 if not (List.mem NotInDocs flags) then (
9694 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9696 match fst style with
9697 | RErr | RInt _ | RInt64 _ | RBool _
9698 | RConstOptString _ | RConstString _
9699 | RString _ | RBufferOut _ -> doc
9701 doc ^ "\n\nThis function returns a list of strings."
9702 | RStruct (_, typ) ->
9703 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
9704 | RStructList (_, typ) ->
9705 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
9707 doc ^ "\n\nThis function returns a dictionary." in
9709 if List.mem ProtocolLimitWarning flags then
9710 doc ^ "\n\n" ^ protocol_limit_warning
9713 if List.mem DangerWillRobinson flags then
9714 doc ^ "\n\n" ^ danger_will_robinson
9717 match deprecation_notice flags with
9719 | Some txt -> doc ^ "\n\n" ^ txt in
9720 let doc = pod2text ~width:60 name doc in
9721 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
9722 let doc = String.concat "\n " doc in
9723 pr " u\"\"\"%s\"\"\"\n" doc;
9725 pr " return libguestfsmod.%s " name;
9726 generate_py_call_args ~handle:"self._o" (snd style);
9731 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
9732 and generate_py_call_args ~handle args =
9734 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9737 (* Useful if you need the longdesc POD text as plain text. Returns a
9740 * Because this is very slow (the slowest part of autogeneration),
9741 * we memoize the results.
9743 and pod2text ~width name longdesc =
9744 let key = width, name, longdesc in
9745 try Hashtbl.find pod2text_memo key
9747 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
9748 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
9750 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
9751 let chan = open_process_in cmd in
9752 let lines = ref [] in
9754 let line = input_line chan in
9755 if i = 1 then (* discard the first line of output *)
9758 let line = triml line in
9759 lines := line :: !lines;
9762 let lines = try loop 1 with End_of_file -> List.rev !lines in
9764 (match close_process_in chan with
9767 failwithf "pod2text: process exited with non-zero status (%d)" i
9768 | WSIGNALED i | WSTOPPED i ->
9769 failwithf "pod2text: process signalled or stopped by signal %d" i
9771 Hashtbl.add pod2text_memo key lines;
9772 pod2text_memo_updated ();
9775 (* Generate ruby bindings. *)
9776 and generate_ruby_c () =
9777 generate_header CStyle LGPLv2plus;
9785 #include \"guestfs.h\"
9787 #include \"extconf.h\"
9789 /* For Ruby < 1.9 */
9791 #define RARRAY_LEN(r) (RARRAY((r))->len)
9794 static VALUE m_guestfs; /* guestfs module */
9795 static VALUE c_guestfs; /* guestfs_h handle */
9796 static VALUE e_Error; /* used for all errors */
9798 static void ruby_guestfs_free (void *p)
9801 guestfs_close ((guestfs_h *) p);
9804 static VALUE ruby_guestfs_create (VALUE m)
9808 g = guestfs_create ();
9810 rb_raise (e_Error, \"failed to create guestfs handle\");
9812 /* Don't print error messages to stderr by default. */
9813 guestfs_set_error_handler (g, NULL, NULL);
9815 /* Wrap it, and make sure the close function is called when the
9818 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
9821 static VALUE ruby_guestfs_close (VALUE gv)
9824 Data_Get_Struct (gv, guestfs_h, g);
9826 ruby_guestfs_free (g);
9827 DATA_PTR (gv) = NULL;
9835 fun (name, style, _, _, _, _, _) ->
9836 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
9837 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
9840 pr " guestfs_h *g;\n";
9841 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
9843 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
9849 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
9850 pr " Check_Type (%sv, T_STRING);\n" n;
9851 pr " const char *%s = StringValueCStr (%sv);\n" n n;
9853 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9854 pr " \"%s\", \"%s\");\n" n name
9856 pr " Check_Type (%sv, T_STRING);\n" n;
9857 pr " const char *%s = RSTRING (%sv)->ptr;\n" n n;
9859 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
9860 pr " \"%s\", \"%s\");\n" n name;
9861 pr " size_t %s_size = RSTRING (%sv)->len;\n" n n
9863 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
9864 | StringList n | DeviceList n ->
9865 pr " char **%s;\n" n;
9866 pr " Check_Type (%sv, T_ARRAY);\n" n;
9868 pr " int i, len;\n";
9869 pr " len = RARRAY_LEN (%sv);\n" n;
9870 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
9872 pr " for (i = 0; i < len; ++i) {\n";
9873 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
9874 pr " %s[i] = StringValueCStr (v);\n" n;
9876 pr " %s[len] = NULL;\n" n;
9879 pr " int %s = RTEST (%sv);\n" n n
9881 pr " int %s = NUM2INT (%sv);\n" n n
9883 pr " long long %s = NUM2LL (%sv);\n" n n
9888 match fst style with
9889 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
9890 | RInt64 _ -> pr " int64_t r;\n"; "-1"
9891 | RConstString _ | RConstOptString _ ->
9892 pr " const char *r;\n"; "NULL"
9893 | RString _ -> pr " char *r;\n"; "NULL"
9894 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
9895 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
9896 | RStructList (_, typ) ->
9897 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
9900 pr " size_t size;\n";
9904 pr " r = guestfs_%s " name;
9905 generate_c_call_args ~handle:"g" style;
9910 | Pathname _ | Device _ | Dev_or_Path _ | String _
9911 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
9913 | StringList n | DeviceList n ->
9914 pr " free (%s);\n" n
9917 pr " if (r == %s)\n" error_code;
9918 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
9921 (match fst style with
9923 pr " return Qnil;\n"
9924 | RInt _ | RBool _ ->
9925 pr " return INT2NUM (r);\n"
9927 pr " return ULL2NUM (r);\n"
9929 pr " return rb_str_new2 (r);\n";
9930 | RConstOptString _ ->
9932 pr " return rb_str_new2 (r);\n";
9934 pr " return Qnil;\n";
9936 pr " VALUE rv = rb_str_new2 (r);\n";
9940 pr " int i, len = 0;\n";
9941 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
9942 pr " VALUE rv = rb_ary_new2 (len);\n";
9943 pr " for (i = 0; r[i] != NULL; ++i) {\n";
9944 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
9945 pr " free (r[i]);\n";
9949 | RStruct (_, typ) ->
9950 let cols = cols_of_struct typ in
9951 generate_ruby_struct_code typ cols
9952 | RStructList (_, typ) ->
9953 let cols = cols_of_struct typ in
9954 generate_ruby_struct_list_code typ cols
9956 pr " VALUE rv = rb_hash_new ();\n";
9958 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
9959 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
9960 pr " free (r[i]);\n";
9961 pr " free (r[i+1]);\n";
9966 pr " VALUE rv = rb_str_new (r, size);\n";
9976 /* Initialize the module. */
9977 void Init__guestfs ()
9979 m_guestfs = rb_define_module (\"Guestfs\");
9980 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
9981 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
9983 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
9984 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
9987 (* Define the rest of the methods. *)
9989 fun (name, style, _, _, _, _, _) ->
9990 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
9991 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
9996 (* Ruby code to return a struct. *)
9997 and generate_ruby_struct_code typ cols =
9998 pr " VALUE rv = rb_hash_new ();\n";
10002 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
10004 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
10006 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
10007 | name, (FBytes|FUInt64) ->
10008 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10010 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
10012 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
10014 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
10015 | name, FOptPercent ->
10016 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
10017 | name, FChar -> (* XXX wrong? *)
10018 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
10020 pr " guestfs_free_%s (r);\n" typ;
10023 (* Ruby code to return a struct list. *)
10024 and generate_ruby_struct_list_code typ cols =
10025 pr " VALUE rv = rb_ary_new2 (r->len);\n";
10027 pr " for (i = 0; i < r->len; ++i) {\n";
10028 pr " VALUE hv = rb_hash_new ();\n";
10032 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
10034 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
10036 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
10037 | name, (FBytes|FUInt64) ->
10038 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10040 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
10042 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
10044 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
10045 | name, FOptPercent ->
10046 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
10047 | name, FChar -> (* XXX wrong? *)
10048 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
10050 pr " rb_ary_push (rv, hv);\n";
10052 pr " guestfs_free_%s_list (r);\n" typ;
10055 (* Generate Java bindings GuestFS.java file. *)
10056 and generate_java_java () =
10057 generate_header CStyle LGPLv2plus;
10060 package com.redhat.et.libguestfs;
10062 import java.util.HashMap;
10063 import com.redhat.et.libguestfs.LibGuestFSException;
10064 import com.redhat.et.libguestfs.PV;
10065 import com.redhat.et.libguestfs.VG;
10066 import com.redhat.et.libguestfs.LV;
10067 import com.redhat.et.libguestfs.Stat;
10068 import com.redhat.et.libguestfs.StatVFS;
10069 import com.redhat.et.libguestfs.IntBool;
10070 import com.redhat.et.libguestfs.Dirent;
10073 * The GuestFS object is a libguestfs handle.
10077 public class GuestFS {
10078 // Load the native code.
10080 System.loadLibrary (\"guestfs_jni\");
10084 * The native guestfs_h pointer.
10089 * Create a libguestfs handle.
10091 * @throws LibGuestFSException
10093 public GuestFS () throws LibGuestFSException
10097 private native long _create () throws LibGuestFSException;
10100 * Close a libguestfs handle.
10102 * You can also leave handles to be collected by the garbage
10103 * collector, but this method ensures that the resources used
10104 * by the handle are freed up immediately. If you call any
10105 * other methods after closing the handle, you will get an
10108 * @throws LibGuestFSException
10110 public void close () throws LibGuestFSException
10116 private native void _close (long g) throws LibGuestFSException;
10118 public void finalize () throws LibGuestFSException
10126 fun (name, style, _, flags, _, shortdesc, longdesc) ->
10127 if not (List.mem NotInDocs flags); then (
10128 let doc = replace_str longdesc "C<guestfs_" "C<g." in
10130 if List.mem ProtocolLimitWarning flags then
10131 doc ^ "\n\n" ^ protocol_limit_warning
10134 if List.mem DangerWillRobinson flags then
10135 doc ^ "\n\n" ^ danger_will_robinson
10138 match deprecation_notice flags with
10140 | Some txt -> doc ^ "\n\n" ^ txt in
10141 let doc = pod2text ~width:60 name doc in
10142 let doc = List.map ( (* RHBZ#501883 *)
10145 | nonempty -> nonempty
10147 let doc = String.concat "\n * " doc in
10150 pr " * %s\n" shortdesc;
10153 pr " * @throws LibGuestFSException\n";
10157 generate_java_prototype ~public:true ~semicolon:false name style;
10160 pr " if (g == 0)\n";
10161 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
10164 if fst style <> RErr then pr "return ";
10166 generate_java_call_args ~handle:"g" (snd style);
10170 generate_java_prototype ~privat:true ~native:true name style;
10177 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
10178 and generate_java_call_args ~handle args =
10180 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
10183 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
10184 ?(semicolon=true) name style =
10185 if privat then pr "private ";
10186 if public then pr "public ";
10187 if native then pr "native ";
10190 (match fst style with
10191 | RErr -> pr "void ";
10192 | RInt _ -> pr "int ";
10193 | RInt64 _ -> pr "long ";
10194 | RBool _ -> pr "boolean ";
10195 | RConstString _ | RConstOptString _ | RString _
10196 | RBufferOut _ -> pr "String ";
10197 | RStringList _ -> pr "String[] ";
10198 | RStruct (_, typ) ->
10199 let name = java_name_of_struct typ in
10201 | RStructList (_, typ) ->
10202 let name = java_name_of_struct typ in
10204 | RHashtable _ -> pr "HashMap<String,String> ";
10207 if native then pr "_%s " name else pr "%s " name;
10209 let needs_comma = ref false in
10212 needs_comma := true
10218 if !needs_comma then pr ", ";
10219 needs_comma := true;
10223 | Device n | Dev_or_Path n
10231 | StringList n | DeviceList n ->
10242 pr " throws LibGuestFSException";
10243 if semicolon then pr ";"
10245 and generate_java_struct jtyp cols () =
10246 generate_header CStyle LGPLv2plus;
10249 package com.redhat.et.libguestfs;
10252 * Libguestfs %s structure.
10264 | name, FBuffer -> pr " public String %s;\n" name
10265 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
10266 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
10267 | name, FChar -> pr " public char %s;\n" name
10268 | name, FOptPercent ->
10269 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
10270 pr " public float %s;\n" name
10275 and generate_java_c () =
10276 generate_header CStyle LGPLv2plus;
10280 #include <stdlib.h>
10281 #include <string.h>
10283 #include \"com_redhat_et_libguestfs_GuestFS.h\"
10284 #include \"guestfs.h\"
10286 /* Note that this function returns. The exception is not thrown
10287 * until after the wrapper function returns.
10290 throw_exception (JNIEnv *env, const char *msg)
10293 cl = (*env)->FindClass (env,
10294 \"com/redhat/et/libguestfs/LibGuestFSException\");
10295 (*env)->ThrowNew (env, cl, msg);
10298 JNIEXPORT jlong JNICALL
10299 Java_com_redhat_et_libguestfs_GuestFS__1create
10300 (JNIEnv *env, jobject obj)
10304 g = guestfs_create ();
10306 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
10309 guestfs_set_error_handler (g, NULL, NULL);
10310 return (jlong) (long) g;
10313 JNIEXPORT void JNICALL
10314 Java_com_redhat_et_libguestfs_GuestFS__1close
10315 (JNIEnv *env, jobject obj, jlong jg)
10317 guestfs_h *g = (guestfs_h *) (long) jg;
10324 fun (name, style, _, _, _, _, _) ->
10326 (match fst style with
10327 | RErr -> pr "void ";
10328 | RInt _ -> pr "jint ";
10329 | RInt64 _ -> pr "jlong ";
10330 | RBool _ -> pr "jboolean ";
10331 | RConstString _ | RConstOptString _ | RString _
10332 | RBufferOut _ -> pr "jstring ";
10333 | RStruct _ | RHashtable _ ->
10335 | RStringList _ | RStructList _ ->
10336 pr "jobjectArray ";
10339 pr "Java_com_redhat_et_libguestfs_GuestFS_";
10340 pr "%s" (replace_str ("_" ^ name) "_" "_1");
10342 pr " (JNIEnv *env, jobject obj, jlong jg";
10346 | Device n | Dev_or_Path n
10351 pr ", jstring j%s" n
10353 pr ", jbyteArray j%s" n
10354 | StringList n | DeviceList n ->
10355 pr ", jobjectArray j%s" n
10357 pr ", jboolean j%s" n
10365 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
10366 let error_code, no_ret =
10367 match fst style with
10368 | RErr -> pr " int r;\n"; "-1", ""
10370 | RInt _ -> pr " int r;\n"; "-1", "0"
10371 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
10372 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
10373 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
10375 pr " jstring jr;\n";
10376 pr " char *r;\n"; "NULL", "NULL"
10378 pr " jobjectArray jr;\n";
10379 pr " int r_len;\n";
10380 pr " jclass cl;\n";
10381 pr " jstring jstr;\n";
10382 pr " char **r;\n"; "NULL", "NULL"
10383 | RStruct (_, typ) ->
10384 pr " jobject jr;\n";
10385 pr " jclass cl;\n";
10386 pr " jfieldID fl;\n";
10387 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
10388 | RStructList (_, typ) ->
10389 pr " jobjectArray jr;\n";
10390 pr " jclass cl;\n";
10391 pr " jfieldID fl;\n";
10392 pr " jobject jfl;\n";
10393 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
10394 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
10396 pr " jstring jr;\n";
10398 pr " size_t size;\n";
10403 | Device n | Dev_or_Path n
10408 pr " const char *%s;\n" n
10410 pr " jbyte *%s;\n" n;
10411 pr " size_t %s_size;\n" n
10412 | StringList n | DeviceList n ->
10413 pr " int %s_len;\n" n;
10414 pr " const char **%s;\n" n
10419 pr " int64_t %s;\n" n
10423 (match fst style with
10424 | RStringList _ | RStructList _ -> true
10425 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
10426 | RConstOptString _
10427 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
10428 List.exists (function
10429 | StringList _ -> true
10430 | DeviceList _ -> true
10431 | _ -> false) (snd style) in
10437 (* Get the parameters. *)
10441 | Device n | Dev_or_Path n
10445 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
10447 (* This is completely undocumented, but Java null becomes
10448 * a NULL parameter.
10450 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
10452 pr " %s = (*env)->GetByteArrayElements (env, j%s, NULL);\n" n n;
10453 pr " %s_size = (*env)->GetArrayLength (env, j%s);\n" n n
10454 | StringList n | DeviceList n ->
10455 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
10456 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
10457 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10458 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10460 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
10462 pr " %s[%s_len] = NULL;\n" n n;
10466 pr " %s = j%s;\n" n n
10469 (* Make the call. *)
10470 pr " r = guestfs_%s " name;
10471 generate_c_call_args ~handle:"g" style;
10474 (* Release the parameters. *)
10478 | Device n | Dev_or_Path n
10482 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10484 pr " if (j%s)\n" n;
10485 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
10487 pr " (*env)->ReleaseByteArrayElements (env, j%s, %s, 0);\n" n n
10488 | StringList n | DeviceList n ->
10489 pr " for (i = 0; i < %s_len; ++i) {\n" n;
10490 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
10492 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
10494 pr " free (%s);\n" n
10500 (* Check for errors. *)
10501 pr " if (r == %s) {\n" error_code;
10502 pr " throw_exception (env, guestfs_last_error (g));\n";
10503 pr " return %s;\n" no_ret;
10506 (* Return value. *)
10507 (match fst style with
10509 | RInt _ -> pr " return (jint) r;\n"
10510 | RBool _ -> pr " return (jboolean) r;\n"
10511 | RInt64 _ -> pr " return (jlong) r;\n"
10512 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
10513 | RConstOptString _ ->
10514 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
10516 pr " jr = (*env)->NewStringUTF (env, r);\n";
10520 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
10521 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
10522 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
10523 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
10524 pr " for (i = 0; i < r_len; ++i) {\n";
10525 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
10526 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
10527 pr " free (r[i]);\n";
10531 | RStruct (_, typ) ->
10532 let jtyp = java_name_of_struct typ in
10533 let cols = cols_of_struct typ in
10534 generate_java_struct_return typ jtyp cols
10535 | RStructList (_, typ) ->
10536 let jtyp = java_name_of_struct typ in
10537 let cols = cols_of_struct typ in
10538 generate_java_struct_list_return typ jtyp cols
10541 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
10542 pr " return NULL;\n"
10544 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
10553 and generate_java_struct_return typ jtyp cols =
10554 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10555 pr " jr = (*env)->AllocObject (env, cl);\n";
10559 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10560 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
10563 pr " char s[33];\n";
10564 pr " memcpy (s, r->%s, 32);\n" name;
10565 pr " s[32] = 0;\n";
10566 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10567 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10571 pr " int len = r->%s_len;\n" name;
10572 pr " char s[len+1];\n";
10573 pr " memcpy (s, r->%s, len);\n" name;
10574 pr " s[len] = 0;\n";
10575 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10576 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
10578 | name, (FBytes|FUInt64|FInt64) ->
10579 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10580 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10581 | name, (FUInt32|FInt32) ->
10582 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10583 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10584 | name, FOptPercent ->
10585 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10586 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
10588 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10589 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
10594 and generate_java_struct_list_return typ jtyp cols =
10595 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
10596 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
10597 pr " for (i = 0; i < r->len; ++i) {\n";
10598 pr " jfl = (*env)->AllocObject (env, cl);\n";
10602 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10603 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
10606 pr " char s[33];\n";
10607 pr " memcpy (s, r->val[i].%s, 32);\n" name;
10608 pr " s[32] = 0;\n";
10609 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10610 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10614 pr " int len = r->val[i].%s_len;\n" name;
10615 pr " char s[len+1];\n";
10616 pr " memcpy (s, r->val[i].%s, len);\n" name;
10617 pr " s[len] = 0;\n";
10618 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
10619 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
10621 | name, (FBytes|FUInt64|FInt64) ->
10622 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
10623 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10624 | name, (FUInt32|FInt32) ->
10625 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
10626 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10627 | name, FOptPercent ->
10628 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
10629 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
10631 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
10632 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
10634 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
10636 pr " guestfs_free_%s_list (r);\n" typ;
10639 and generate_java_makefile_inc () =
10640 generate_header HashStyle GPLv2plus;
10642 pr "java_built_sources = \\\n";
10645 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
10647 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
10649 and generate_haskell_hs () =
10650 generate_header HaskellStyle LGPLv2plus;
10652 (* XXX We only know how to generate partial FFI for Haskell
10653 * at the moment. Please help out!
10655 let can_generate style =
10659 | RInt64 _, _ -> true
10661 | RConstString _, _
10662 | RConstOptString _, _
10668 | RBufferOut _, _ -> false in
10671 {-# INCLUDE <guestfs.h> #-}
10672 {-# LANGUAGE ForeignFunctionInterface #-}
10677 (* List out the names of the actions we want to export. *)
10679 fun (name, style, _, _, _, _, _) ->
10680 if can_generate style then pr ",\n %s" name
10686 -- Unfortunately some symbols duplicate ones already present
10687 -- in Prelude. We don't know which, so we hard-code a list
10689 import Prelude hiding (truncate)
10693 import Foreign.C.Types
10695 import Control.Exception
10696 import Data.Typeable
10698 data GuestfsS = GuestfsS -- represents the opaque C struct
10699 type GuestfsP = Ptr GuestfsS -- guestfs_h *
10700 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
10702 -- XXX define properly later XXX
10706 data IntBool = IntBool
10708 data StatVFS = StatVFS
10709 data Hashtable = Hashtable
10711 foreign import ccall unsafe \"guestfs_create\" c_create
10713 foreign import ccall unsafe \"&guestfs_close\" c_close
10714 :: FunPtr (GuestfsP -> IO ())
10715 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
10716 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
10718 create :: IO GuestfsH
10721 c_set_error_handler p nullPtr nullPtr
10722 h <- newForeignPtr c_close p
10725 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
10726 :: GuestfsP -> IO CString
10728 -- last_error :: GuestfsH -> IO (Maybe String)
10729 -- last_error h = do
10730 -- str <- withForeignPtr h (\\p -> c_last_error p)
10731 -- maybePeek peekCString str
10733 last_error :: GuestfsH -> IO (String)
10735 str <- withForeignPtr h (\\p -> c_last_error p)
10736 if (str == nullPtr)
10737 then return \"no error\"
10738 else peekCString str
10742 (* Generate wrappers for each foreign function. *)
10744 fun (name, style, _, _, _, _, _) ->
10745 if can_generate style then (
10746 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
10748 generate_haskell_prototype ~handle:"GuestfsP" style;
10752 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
10754 pr "%s %s = do\n" name
10755 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
10757 (* Convert pointer arguments using with* functions. *)
10762 | Pathname n | Device n | Dev_or_Path n | String n ->
10763 pr "withCString %s $ \\%s -> " n n
10765 pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
10766 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
10767 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
10768 | Bool _ | Int _ | Int64 _ -> ()
10770 (* Convert integer arguments. *)
10774 | Bool n -> sprintf "(fromBool %s)" n
10775 | Int n -> sprintf "(fromIntegral %s)" n
10776 | Int64 n -> sprintf "(fromIntegral %s)" n
10777 | FileIn n | FileOut n
10778 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
10779 | BufferIn n -> sprintf "%s (fromIntegral %s_size)" n n
10781 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
10782 (String.concat " " ("p" :: args));
10783 (match fst style with
10784 | RErr | RInt _ | RInt64 _ | RBool _ ->
10785 pr " if (r == -1)\n";
10787 pr " err <- last_error h\n";
10789 | RConstString _ | RConstOptString _ | RString _
10790 | RStringList _ | RStruct _
10791 | RStructList _ | RHashtable _ | RBufferOut _ ->
10792 pr " if (r == nullPtr)\n";
10794 pr " err <- last_error h\n";
10797 (match fst style with
10799 pr " else return ()\n"
10801 pr " else return (fromIntegral r)\n"
10803 pr " else return (fromIntegral r)\n"
10805 pr " else return (toBool r)\n"
10807 | RConstOptString _
10814 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
10820 and generate_haskell_prototype ~handle ?(hs = false) style =
10821 pr "%s -> " handle;
10822 let string = if hs then "String" else "CString" in
10823 let int = if hs then "Int" else "CInt" in
10824 let bool = if hs then "Bool" else "CInt" in
10825 let int64 = if hs then "Integer" else "Int64" in
10829 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
10831 if hs then pr "String"
10832 else pr "CString -> CInt"
10833 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
10834 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
10835 | Bool _ -> pr "%s" bool
10836 | Int _ -> pr "%s" int
10837 | Int64 _ -> pr "%s" int
10838 | FileIn _ -> pr "%s" string
10839 | FileOut _ -> pr "%s" string
10844 (match fst style with
10845 | RErr -> if not hs then pr "CInt"
10846 | RInt _ -> pr "%s" int
10847 | RInt64 _ -> pr "%s" int64
10848 | RBool _ -> pr "%s" bool
10849 | RConstString _ -> pr "%s" string
10850 | RConstOptString _ -> pr "Maybe %s" string
10851 | RString _ -> pr "%s" string
10852 | RStringList _ -> pr "[%s]" string
10853 | RStruct (_, typ) ->
10854 let name = java_name_of_struct typ in
10856 | RStructList (_, typ) ->
10857 let name = java_name_of_struct typ in
10859 | RHashtable _ -> pr "Hashtable"
10860 | RBufferOut _ -> pr "%s" string
10864 and generate_csharp () =
10865 generate_header CPlusPlusStyle LGPLv2plus;
10867 (* XXX Make this configurable by the C# assembly users. *)
10868 let library = "libguestfs.so.0" in
10871 // These C# bindings are highly experimental at present.
10873 // Firstly they only work on Linux (ie. Mono). In order to get them
10874 // to work on Windows (ie. .Net) you would need to port the library
10875 // itself to Windows first.
10877 // The second issue is that some calls are known to be incorrect and
10878 // can cause Mono to segfault. Particularly: calls which pass or
10879 // return string[], or return any structure value. This is because
10880 // we haven't worked out the correct way to do this from C#.
10882 // The third issue is that when compiling you get a lot of warnings.
10883 // We are not sure whether the warnings are important or not.
10885 // Fourthly we do not routinely build or test these bindings as part
10886 // of the make && make check cycle, which means that regressions might
10889 // Suggestions and patches are welcome.
10893 // gmcs Libguestfs.cs
10894 // mono Libguestfs.exe
10896 // (You'll probably want to add a Test class / static main function
10897 // otherwise this won't do anything useful).
10901 using System.Runtime.InteropServices;
10902 using System.Runtime.Serialization;
10903 using System.Collections;
10907 class Error : System.ApplicationException
10909 public Error (string message) : base (message) {}
10910 protected Error (SerializationInfo info, StreamingContext context) {}
10917 [DllImport (\"%s\")]
10918 static extern IntPtr guestfs_create ();
10922 _handle = guestfs_create ();
10923 if (_handle == IntPtr.Zero)
10924 throw new Error (\"could not create guestfs handle\");
10927 [DllImport (\"%s\")]
10928 static extern void guestfs_close (IntPtr h);
10932 guestfs_close (_handle);
10935 [DllImport (\"%s\")]
10936 static extern string guestfs_last_error (IntPtr h);
10938 " library library library;
10940 (* Generate C# structure bindings. We prefix struct names with
10941 * underscore because C# cannot have conflicting struct names and
10942 * method names (eg. "class stat" and "stat").
10946 pr " [StructLayout (LayoutKind.Sequential)]\n";
10947 pr " public class _%s {\n" typ;
10950 | name, FChar -> pr " char %s;\n" name
10951 | name, FString -> pr " string %s;\n" name
10953 pr " uint %s_len;\n" name;
10954 pr " string %s;\n" name
10956 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
10957 pr " string %s;\n" name
10958 | name, FUInt32 -> pr " uint %s;\n" name
10959 | name, FInt32 -> pr " int %s;\n" name
10960 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
10961 | name, FInt64 -> pr " long %s;\n" name
10962 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
10968 (* Generate C# function bindings. *)
10970 fun (name, style, _, _, _, shortdesc, _) ->
10971 let rec csharp_return_type () =
10972 match fst style with
10974 | RBool n -> "bool"
10976 | RInt64 n -> "long"
10978 | RConstOptString n
10980 | RBufferOut n -> "string"
10981 | RStruct (_,n) -> "_" ^ n
10982 | RHashtable n -> "Hashtable"
10983 | RStringList n -> "string[]"
10984 | RStructList (_,n) -> sprintf "_%s[]" n
10986 and c_return_type () =
10987 match fst style with
10991 | RInt64 _ -> "long"
10993 | RConstOptString _
10995 | RBufferOut _ -> "string"
10996 | RStruct (_,n) -> "_" ^ n
10998 | RStringList _ -> "string[]"
10999 | RStructList (_,n) -> sprintf "_%s[]" n
11001 and c_error_comparison () =
11002 match fst style with
11006 | RInt64 _ -> "== -1"
11008 | RConstOptString _
11014 | RStructList (_,_) -> "== null"
11016 and generate_extern_prototype () =
11017 pr " static extern %s guestfs_%s (IntPtr h"
11018 (c_return_type ()) name;
11021 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11022 | FileIn n | FileOut n
11024 pr ", [In] string %s" n
11025 | StringList n | DeviceList n ->
11026 pr ", [In] string[] %s" n
11036 and generate_public_prototype () =
11037 pr " public %s %s (" (csharp_return_type ()) name;
11038 let comma = ref false in
11040 if !comma then pr ", ";
11045 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
11046 | FileIn n | FileOut n
11048 next (); pr "string %s" n
11049 | StringList n | DeviceList n ->
11050 next (); pr "string[] %s" n
11052 next (); pr "bool %s" n
11054 next (); pr "int %s" n
11056 next (); pr "long %s" n
11060 and generate_call () =
11061 pr "guestfs_%s (_handle" name;
11062 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
11066 pr " [DllImport (\"%s\")]\n" library;
11067 generate_extern_prototype ();
11069 pr " /// <summary>\n";
11070 pr " /// %s\n" shortdesc;
11071 pr " /// </summary>\n";
11072 generate_public_prototype ();
11074 pr " %s r;\n" (c_return_type ());
11077 pr " if (r %s)\n" (c_error_comparison ());
11078 pr " throw new Error (guestfs_last_error (_handle));\n";
11079 (match fst style with
11082 pr " return r != 0 ? true : false;\n"
11084 pr " Hashtable rr = new Hashtable ();\n";
11085 pr " for (int i = 0; i < r.Length; i += 2)\n";
11086 pr " rr.Add (r[i], r[i+1]);\n";
11088 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
11089 | RString _ | RBufferOut _ | RStruct _ | RStringList _
11095 ) all_functions_sorted;
11101 and generate_bindtests () =
11102 generate_header CStyle LGPLv2plus;
11106 #include <stdlib.h>
11107 #include <inttypes.h>
11108 #include <string.h>
11110 #include \"guestfs.h\"
11111 #include \"guestfs-internal.h\"
11112 #include \"guestfs-internal-actions.h\"
11113 #include \"guestfs_protocol.h\"
11115 #define error guestfs_error
11116 #define safe_calloc guestfs_safe_calloc
11117 #define safe_malloc guestfs_safe_malloc
11120 print_strings (char *const *argv)
11125 for (argc = 0; argv[argc] != NULL; ++argc) {
11126 if (argc > 0) printf (\", \");
11127 printf (\"\\\"%%s\\\"\", argv[argc]);
11132 /* The test0 function prints its parameters to stdout. */
11136 match test_functions with
11137 | [] -> assert false
11138 | test0 :: tests -> test0, tests in
11141 let (name, style, _, _, _, _, _) = test0 in
11142 generate_prototype ~extern:false ~semicolon:false ~newline:true
11143 ~handle:"g" ~prefix:"guestfs__" name style;
11148 | Device n | Dev_or_Path n
11151 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
11155 pr " for (i = 0; i < %s_size; ++i)\n" n;
11156 pr " printf (\"<%%02x>\", %s[i]);\n" n;
11157 pr " printf (\"\\n\");\n";
11159 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
11160 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
11161 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
11162 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
11163 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
11165 pr " /* Java changes stdout line buffering so we need this: */\n";
11166 pr " fflush (stdout);\n";
11172 fun (name, style, _, _, _, _, _) ->
11173 if String.sub name (String.length name - 3) 3 <> "err" then (
11174 pr "/* Test normal return. */\n";
11175 generate_prototype ~extern:false ~semicolon:false ~newline:true
11176 ~handle:"g" ~prefix:"guestfs__" name style;
11178 (match fst style with
11183 pr " sscanf (val, \"%%d\", &r);\n";
11186 pr " int64_t r;\n";
11187 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
11190 pr " return STREQ (val, \"true\");\n"
11192 | RConstOptString _ ->
11193 (* Can't return the input string here. Return a static
11194 * string so we ensure we get a segfault if the caller
11195 * tries to free it.
11197 pr " return \"static string\";\n"
11199 pr " return strdup (val);\n"
11201 pr " char **strs;\n";
11203 pr " sscanf (val, \"%%d\", &n);\n";
11204 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
11205 pr " for (i = 0; i < n; ++i) {\n";
11206 pr " strs[i] = safe_malloc (g, 16);\n";
11207 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
11209 pr " strs[n] = NULL;\n";
11210 pr " return strs;\n"
11211 | RStruct (_, typ) ->
11212 pr " struct guestfs_%s *r;\n" typ;
11213 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11215 | RStructList (_, typ) ->
11216 pr " struct guestfs_%s_list *r;\n" typ;
11217 pr " r = safe_calloc (g, sizeof *r, 1);\n";
11218 pr " sscanf (val, \"%%d\", &r->len);\n";
11219 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
11222 pr " char **strs;\n";
11224 pr " sscanf (val, \"%%d\", &n);\n";
11225 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
11226 pr " for (i = 0; i < n; ++i) {\n";
11227 pr " strs[i*2] = safe_malloc (g, 16);\n";
11228 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
11229 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
11230 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
11232 pr " strs[n*2] = NULL;\n";
11233 pr " return strs;\n"
11235 pr " return strdup (val);\n"
11240 pr "/* Test error return. */\n";
11241 generate_prototype ~extern:false ~semicolon:false ~newline:true
11242 ~handle:"g" ~prefix:"guestfs__" name style;
11244 pr " error (g, \"error\");\n";
11245 (match fst style with
11246 | RErr | RInt _ | RInt64 _ | RBool _ ->
11248 | RConstString _ | RConstOptString _
11249 | RString _ | RStringList _ | RStruct _
11253 pr " return NULL;\n"
11260 and generate_ocaml_bindtests () =
11261 generate_header OCamlStyle GPLv2plus;
11265 let g = Guestfs.create () in
11269 String.concat " " (
11272 | CallString s -> "\"" ^ s ^ "\""
11273 | CallOptString None -> "None"
11274 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
11275 | CallStringList xs ->
11276 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
11277 | CallInt i when i >= 0 -> string_of_int i
11278 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
11279 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
11280 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
11281 | CallBool b -> string_of_bool b
11282 | CallBuffer s -> sprintf "%S" s
11287 generate_lang_bindtests (
11288 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
11291 pr "print_endline \"EOF\"\n"
11293 and generate_perl_bindtests () =
11294 pr "#!/usr/bin/perl -w\n";
11295 generate_header HashStyle GPLv2plus;
11302 my $g = Sys::Guestfs->new ();
11306 String.concat ", " (
11309 | CallString s -> "\"" ^ s ^ "\""
11310 | CallOptString None -> "undef"
11311 | CallOptString (Some s) -> sprintf "\"%s\"" s
11312 | CallStringList xs ->
11313 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11314 | CallInt i -> string_of_int i
11315 | CallInt64 i -> Int64.to_string i
11316 | CallBool b -> if b then "1" else "0"
11317 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11322 generate_lang_bindtests (
11323 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
11326 pr "print \"EOF\\n\"\n"
11328 and generate_python_bindtests () =
11329 generate_header HashStyle GPLv2plus;
11334 g = guestfs.GuestFS ()
11338 String.concat ", " (
11341 | CallString s -> "\"" ^ s ^ "\""
11342 | CallOptString None -> "None"
11343 | CallOptString (Some s) -> sprintf "\"%s\"" s
11344 | CallStringList xs ->
11345 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11346 | CallInt i -> string_of_int i
11347 | CallInt64 i -> Int64.to_string i
11348 | CallBool b -> if b then "1" else "0"
11349 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11354 generate_lang_bindtests (
11355 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
11358 pr "print \"EOF\"\n"
11360 and generate_ruby_bindtests () =
11361 generate_header HashStyle GPLv2plus;
11366 g = Guestfs::create()
11370 String.concat ", " (
11373 | CallString s -> "\"" ^ s ^ "\""
11374 | CallOptString None -> "nil"
11375 | CallOptString (Some s) -> sprintf "\"%s\"" s
11376 | CallStringList xs ->
11377 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11378 | CallInt i -> string_of_int i
11379 | CallInt64 i -> Int64.to_string i
11380 | CallBool b -> string_of_bool b
11381 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11386 generate_lang_bindtests (
11387 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
11390 pr "print \"EOF\\n\"\n"
11392 and generate_java_bindtests () =
11393 generate_header CStyle GPLv2plus;
11396 import com.redhat.et.libguestfs.*;
11398 public class Bindtests {
11399 public static void main (String[] argv)
11402 GuestFS g = new GuestFS ();
11406 String.concat ", " (
11409 | CallString s -> "\"" ^ s ^ "\""
11410 | CallOptString None -> "null"
11411 | CallOptString (Some s) -> sprintf "\"%s\"" s
11412 | CallStringList xs ->
11414 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
11415 | CallInt i -> string_of_int i
11416 | CallInt64 i -> Int64.to_string i
11417 | CallBool b -> string_of_bool b
11419 "new byte[] { " ^ String.concat "," (
11420 map_chars (fun c -> string_of_int (Char.code c)) s
11426 generate_lang_bindtests (
11427 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
11431 System.out.println (\"EOF\");
11433 catch (Exception exn) {
11434 System.err.println (exn);
11441 and generate_haskell_bindtests () =
11442 generate_header HaskellStyle GPLv2plus;
11445 module Bindtests where
11446 import qualified Guestfs
11449 g <- Guestfs.create
11453 String.concat " " (
11456 | CallString s -> "\"" ^ s ^ "\""
11457 | CallOptString None -> "Nothing"
11458 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
11459 | CallStringList xs ->
11460 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
11461 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
11462 | CallInt i -> string_of_int i
11463 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
11464 | CallInt64 i -> Int64.to_string i
11465 | CallBool true -> "True"
11466 | CallBool false -> "False"
11467 | CallBuffer s -> "\"" ^ c_quote s ^ "\""
11472 generate_lang_bindtests (
11473 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
11476 pr " putStrLn \"EOF\"\n"
11478 (* Language-independent bindings tests - we do it this way to
11479 * ensure there is parity in testing bindings across all languages.
11481 and generate_lang_bindtests call =
11482 call "test0" [CallString "abc"; CallOptString (Some "def");
11483 CallStringList []; CallBool false;
11484 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11485 CallBuffer "abc\000abc"];
11486 call "test0" [CallString "abc"; CallOptString None;
11487 CallStringList []; CallBool false;
11488 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11489 CallBuffer "abc\000abc"];
11490 call "test0" [CallString ""; CallOptString (Some "def");
11491 CallStringList []; CallBool false;
11492 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11493 CallBuffer "abc\000abc"];
11494 call "test0" [CallString ""; CallOptString (Some "");
11495 CallStringList []; CallBool false;
11496 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11497 CallBuffer "abc\000abc"];
11498 call "test0" [CallString "abc"; CallOptString (Some "def");
11499 CallStringList ["1"]; CallBool false;
11500 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11501 CallBuffer "abc\000abc"];
11502 call "test0" [CallString "abc"; CallOptString (Some "def");
11503 CallStringList ["1"; "2"]; CallBool false;
11504 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11505 CallBuffer "abc\000abc"];
11506 call "test0" [CallString "abc"; CallOptString (Some "def");
11507 CallStringList ["1"]; CallBool true;
11508 CallInt 0; CallInt64 0L; CallString "123"; CallString "456";
11509 CallBuffer "abc\000abc"];
11510 call "test0" [CallString "abc"; CallOptString (Some "def");
11511 CallStringList ["1"]; CallBool false;
11512 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456";
11513 CallBuffer "abc\000abc"];
11514 call "test0" [CallString "abc"; CallOptString (Some "def");
11515 CallStringList ["1"]; CallBool false;
11516 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456";
11517 CallBuffer "abc\000abc"];
11518 call "test0" [CallString "abc"; CallOptString (Some "def");
11519 CallStringList ["1"]; CallBool false;
11520 CallInt 1; CallInt64 1L; CallString "123"; CallString "456";
11521 CallBuffer "abc\000abc"];
11522 call "test0" [CallString "abc"; CallOptString (Some "def");
11523 CallStringList ["1"]; CallBool false;
11524 CallInt 2; CallInt64 2L; CallString "123"; CallString "456";
11525 CallBuffer "abc\000abc"];
11526 call "test0" [CallString "abc"; CallOptString (Some "def");
11527 CallStringList ["1"]; CallBool false;
11528 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456";
11529 CallBuffer "abc\000abc"];
11530 call "test0" [CallString "abc"; CallOptString (Some "def");
11531 CallStringList ["1"]; CallBool false;
11532 CallInt 0; CallInt64 0L; CallString ""; CallString "";
11533 CallBuffer "abc\000abc"]
11535 (* XXX Add here tests of the return and error functions. *)
11537 (* Code to generator bindings for virt-inspector. Currently only
11538 * implemented for OCaml code (for virt-p2v 2.0).
11540 let rng_input = "inspector/virt-inspector.rng"
11542 (* Read the input file and parse it into internal structures. This is
11543 * by no means a complete RELAX NG parser, but is just enough to be
11544 * able to parse the specific input file.
11547 | Element of string * rng list (* <element name=name/> *)
11548 | Attribute of string * rng list (* <attribute name=name/> *)
11549 | Interleave of rng list (* <interleave/> *)
11550 | ZeroOrMore of rng (* <zeroOrMore/> *)
11551 | OneOrMore of rng (* <oneOrMore/> *)
11552 | Optional of rng (* <optional/> *)
11553 | Choice of string list (* <choice><value/>*</choice> *)
11554 | Value of string (* <value>str</value> *)
11555 | Text (* <text/> *)
11557 let rec string_of_rng = function
11558 | Element (name, xs) ->
11559 "Element (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11560 | Attribute (name, xs) ->
11561 "Attribute (\"" ^ name ^ "\", (" ^ string_of_rng_list xs ^ "))"
11562 | Interleave xs -> "Interleave (" ^ string_of_rng_list xs ^ ")"
11563 | ZeroOrMore rng -> "ZeroOrMore (" ^ string_of_rng rng ^ ")"
11564 | OneOrMore rng -> "OneOrMore (" ^ string_of_rng rng ^ ")"
11565 | Optional rng -> "Optional (" ^ string_of_rng rng ^ ")"
11566 | Choice values -> "Choice [" ^ String.concat ", " values ^ "]"
11567 | Value value -> "Value \"" ^ value ^ "\""
11570 and string_of_rng_list xs =
11571 String.concat ", " (List.map string_of_rng xs)
11573 let rec parse_rng ?defines context = function
11575 | Xml.Element ("element", ["name", name], children) :: rest ->
11576 Element (name, parse_rng ?defines context children)
11577 :: parse_rng ?defines context rest
11578 | Xml.Element ("attribute", ["name", name], children) :: rest ->
11579 Attribute (name, parse_rng ?defines context children)
11580 :: parse_rng ?defines context rest
11581 | Xml.Element ("interleave", [], children) :: rest ->
11582 Interleave (parse_rng ?defines context children)
11583 :: parse_rng ?defines context rest
11584 | Xml.Element ("zeroOrMore", [], [child]) :: rest ->
11585 let rng = parse_rng ?defines context [child] in
11587 | [child] -> ZeroOrMore child :: parse_rng ?defines context rest
11589 failwithf "%s: <zeroOrMore> contains more than one child element"
11592 | Xml.Element ("oneOrMore", [], [child]) :: rest ->
11593 let rng = parse_rng ?defines context [child] in
11595 | [child] -> OneOrMore child :: parse_rng ?defines context rest
11597 failwithf "%s: <oneOrMore> contains more than one child element"
11600 | Xml.Element ("optional", [], [child]) :: rest ->
11601 let rng = parse_rng ?defines context [child] in
11603 | [child] -> Optional child :: parse_rng ?defines context rest
11605 failwithf "%s: <optional> contains more than one child element"
11608 | Xml.Element ("choice", [], children) :: rest ->
11609 let values = List.map (
11610 function Xml.Element ("value", [], [Xml.PCData value]) -> value
11612 failwithf "%s: can't handle anything except <value> in <choice>"
11616 :: parse_rng ?defines context rest
11617 | Xml.Element ("value", [], [Xml.PCData value]) :: rest ->
11618 Value value :: parse_rng ?defines context rest
11619 | Xml.Element ("text", [], []) :: rest ->
11620 Text :: parse_rng ?defines context rest
11621 | Xml.Element ("ref", ["name", name], []) :: rest ->
11622 (* Look up the reference. Because of limitations in this parser,
11623 * we can't handle arbitrarily nested <ref> yet. You can only
11624 * use <ref> from inside <start>.
11626 (match defines with
11628 failwithf "%s: contains <ref>, but no refs are defined yet" context
11630 let rng = StringMap.find name map in
11631 rng @ parse_rng ?defines context rest
11634 failwithf "%s: can't handle '%s' in schema" context (Xml.to_string x)
11637 let xml = Xml.parse_file rng_input in
11639 | Xml.Element ("grammar", _,
11640 Xml.Element ("start", _, gram) :: defines) ->
11641 (* The <define/> elements are referenced in the <start> section,
11642 * so build a map of those first.
11644 let defines = List.fold_left (
11646 function Xml.Element ("define", ["name", name], defn) ->
11647 StringMap.add name defn map
11649 failwithf "%s: expected <define name=name/>" rng_input
11650 ) StringMap.empty defines in
11651 let defines = StringMap.mapi parse_rng defines in
11653 (* Parse the <start> clause, passing the defines. *)
11654 parse_rng ~defines "<start>" gram
11656 failwithf "%s: input is not <grammar><start/><define>*</grammar>"
11659 let name_of_field = function
11660 | Element (name, _) | Attribute (name, _)
11661 | ZeroOrMore (Element (name, _))
11662 | OneOrMore (Element (name, _))
11663 | Optional (Element (name, _)) -> name
11664 | Optional (Attribute (name, _)) -> name
11665 | Text -> (* an unnamed field in an element *)
11668 failwithf "name_of_field failed at: %s" (string_of_rng rng)
11670 (* At the moment this function only generates OCaml types. However we
11671 * should parameterize it later so it can generate types/structs in a
11672 * variety of languages.
11674 let generate_types xs =
11675 (* A simple type is one that can be printed out directly, eg.
11676 * "string option". A complex type is one which has a name and has
11677 * to be defined via another toplevel definition, eg. a struct.
11679 * generate_type generates code for either simple or complex types.
11680 * In the simple case, it returns the string ("string option"). In
11681 * the complex case, it returns the name ("mountpoint"). In the
11682 * complex case it has to print out the definition before returning,
11683 * so it should only be called when we are at the beginning of a
11684 * new line (BOL context).
11686 let rec generate_type = function
11687 | Text -> (* string *)
11689 | Choice values -> (* [`val1|`val2|...] *)
11690 "[" ^ String.concat "|" (List.map ((^)"`") values) ^ "]", true
11691 | ZeroOrMore rng -> (* <rng> list *)
11692 let t, is_simple = generate_type rng in
11693 t ^ " list (* 0 or more *)", is_simple
11694 | OneOrMore rng -> (* <rng> list *)
11695 let t, is_simple = generate_type rng in
11696 t ^ " list (* 1 or more *)", is_simple
11697 (* virt-inspector hack: bool *)
11698 | Optional (Attribute (name, [Value "1"])) ->
11700 | Optional rng -> (* <rng> list *)
11701 let t, is_simple = generate_type rng in
11702 t ^ " option", is_simple
11703 (* type name = { fields ... } *)
11704 | Element (name, fields) when is_attrs_interleave fields ->
11705 generate_type_struct name (get_attrs_interleave fields)
11706 | Element (name, [field]) (* type name = field *)
11707 | Attribute (name, [field]) ->
11708 let t, is_simple = generate_type field in
11709 if is_simple then (t, true)
11711 pr "type %s = %s\n" name t;
11714 | Element (name, fields) -> (* type name = { fields ... } *)
11715 generate_type_struct name fields
11717 failwithf "generate_type failed at: %s" (string_of_rng rng)
11719 and is_attrs_interleave = function
11720 | [Interleave _] -> true
11721 | Attribute _ :: fields -> is_attrs_interleave fields
11722 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11725 and get_attrs_interleave = function
11726 | [Interleave fields] -> fields
11727 | ((Attribute _) as field) :: fields
11728 | ((Optional (Attribute _)) as field) :: fields ->
11729 field :: get_attrs_interleave fields
11730 | _ -> assert false
11732 and generate_types xs =
11733 List.iter (fun x -> ignore (generate_type x)) xs
11735 and generate_type_struct name fields =
11736 (* Calculate the types of the fields first. We have to do this
11737 * before printing anything so we are still in BOL context.
11739 let types = List.map fst (List.map generate_type fields) in
11741 (* Special case of a struct containing just a string and another
11742 * field. Turn it into an assoc list.
11745 | ["string"; other] ->
11746 let fname1, fname2 =
11748 | [f1; f2] -> name_of_field f1, name_of_field f2
11749 | _ -> assert false in
11750 pr "type %s = string * %s (* %s -> %s *)\n" name other fname1 fname2;
11754 pr "type %s = {\n" name;
11756 fun (field, ftype) ->
11757 let fname = name_of_field field in
11758 pr " %s_%s : %s;\n" name fname ftype
11759 ) (List.combine fields types);
11761 (* Return the name of this type, and
11762 * false because it's not a simple type.
11769 let generate_parsers xs =
11770 (* As for generate_type above, generate_parser makes a parser for
11771 * some type, and returns the name of the parser it has generated.
11772 * Because it (may) need to print something, it should always be
11773 * called in BOL context.
11775 let rec generate_parser = function
11776 | Text -> (* string *)
11777 "string_child_or_empty"
11778 | Choice values -> (* [`val1|`val2|...] *)
11779 sprintf "(fun x -> match Xml.pcdata (first_child x) with %s | str -> failwith (\"unexpected field value: \" ^ str))"
11781 (List.map (fun v -> sprintf "%S -> `%s" v v) values))
11782 | ZeroOrMore rng -> (* <rng> list *)
11783 let pa = generate_parser rng in
11784 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11785 | OneOrMore rng -> (* <rng> list *)
11786 let pa = generate_parser rng in
11787 sprintf "(fun x -> List.map %s (Xml.children x))" pa
11788 (* virt-inspector hack: bool *)
11789 | Optional (Attribute (name, [Value "1"])) ->
11790 sprintf "(fun x -> try ignore (Xml.attrib x %S); true with Xml.No_attribute _ -> false)" name
11791 | Optional rng -> (* <rng> list *)
11792 let pa = generate_parser rng in
11793 sprintf "(function None -> None | Some x -> Some (%s x))" pa
11794 (* type name = { fields ... } *)
11795 | Element (name, fields) when is_attrs_interleave fields ->
11796 generate_parser_struct name (get_attrs_interleave fields)
11797 | Element (name, [field]) -> (* type name = field *)
11798 let pa = generate_parser field in
11799 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11800 pr "let %s =\n" parser_name;
11802 pr "let parse_%s = %s\n" name parser_name;
11804 | Attribute (name, [field]) ->
11805 let pa = generate_parser field in
11806 let parser_name = sprintf "parse_%s_%d" name (unique ()) in
11807 pr "let %s =\n" parser_name;
11809 pr "let parse_%s = %s\n" name parser_name;
11811 | Element (name, fields) -> (* type name = { fields ... } *)
11812 generate_parser_struct name ([], fields)
11814 failwithf "generate_parser failed at: %s" (string_of_rng rng)
11816 and is_attrs_interleave = function
11817 | [Interleave _] -> true
11818 | Attribute _ :: fields -> is_attrs_interleave fields
11819 | Optional (Attribute _) :: fields -> is_attrs_interleave fields
11822 and get_attrs_interleave = function
11823 | [Interleave fields] -> [], fields
11824 | ((Attribute _) as field) :: fields
11825 | ((Optional (Attribute _)) as field) :: fields ->
11826 let attrs, interleaves = get_attrs_interleave fields in
11827 (field :: attrs), interleaves
11828 | _ -> assert false
11830 and generate_parsers xs =
11831 List.iter (fun x -> ignore (generate_parser x)) xs
11833 and generate_parser_struct name (attrs, interleaves) =
11834 (* Generate parsers for the fields first. We have to do this
11835 * before printing anything so we are still in BOL context.
11837 let fields = attrs @ interleaves in
11838 let pas = List.map generate_parser fields in
11840 (* Generate an intermediate tuple from all the fields first.
11841 * If the type is just a string + another field, then we will
11842 * return this directly, otherwise it is turned into a record.
11844 * RELAX NG note: This code treats <interleave> and plain lists of
11845 * fields the same. In other words, it doesn't bother enforcing
11846 * any ordering of fields in the XML.
11848 pr "let parse_%s x =\n" name;
11849 pr " let t = (\n ";
11850 let comma = ref false in
11853 if !comma then pr ",\n ";
11856 | Optional (Attribute (fname, [field])), pa ->
11858 | Optional (Element (fname, [field])), pa ->
11859 pr "%s (optional_child %S x)" pa fname
11860 | Attribute (fname, [Text]), _ ->
11861 pr "attribute %S x" fname
11862 | (ZeroOrMore _ | OneOrMore _), pa ->
11867 let fname = name_of_field field in
11868 pr "%s (child %S x)" pa fname
11869 ) (List.combine fields pas);
11873 | [Element (_, [Text]) | Attribute (_, [Text]); _] ->
11877 pr " (Obj.magic t : %s)\n" name
11881 | (Optional (Attribute (fname, [field])), pa) ->
11882 pr " %s_%s =\n" name fname;
11884 | (Optional (Element (fname, [field])), pa) ->
11885 pr " %s_%s =\n" name fname;
11886 pr " (let x = optional_child %S x in\n" fname;
11889 let fname = name_of_field field in
11890 pr " %s_%s =\n" name fname;
11891 pr " (let x = child %S x in\n" fname;
11893 ) (List.combine fields pas);
11897 sprintf "parse_%s" name
11900 generate_parsers xs
11902 (* Generate ocaml/guestfs_inspector.mli. *)
11903 let generate_ocaml_inspector_mli () =
11904 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11907 (** This is an OCaml language binding to the external [virt-inspector]
11910 For more information, please read the man page [virt-inspector(1)].
11915 generate_types grammar;
11916 pr "(** The nested information returned from the {!inspect} function. *)\n";
11920 val inspect : ?connect:string -> ?xml:string -> string list -> operatingsystems
11921 (** To inspect a libvirt domain called [name], pass a singleton
11922 list: [inspect [name]]. When using libvirt only, you may
11923 optionally pass a libvirt URI using [inspect ~connect:uri ...].
11925 To inspect a disk image or images, pass a list of the filenames
11926 of the disk images: [inspect filenames]
11928 This function inspects the given guest or disk images and
11929 returns a list of operating system(s) found and a large amount
11930 of information about them. In the vast majority of cases,
11931 a virtual machine only contains a single operating system.
11933 If the optional [~xml] parameter is given, then this function
11934 skips running the external virt-inspector program and just
11935 parses the given XML directly (which is expected to be XML
11936 produced from a previous run of virt-inspector). The list of
11937 names and connect URI are ignored in this case.
11939 This function can throw a wide variety of exceptions, for example
11940 if the external virt-inspector program cannot be found, or if
11941 it doesn't generate valid XML.
11945 (* Generate ocaml/guestfs_inspector.ml. *)
11946 let generate_ocaml_inspector_ml () =
11947 generate_header ~extra_inputs:[rng_input] OCamlStyle LGPLv2plus;
11952 generate_types grammar;
11956 (* Misc functions which are used by the parser code below. *)
11957 let first_child = function
11958 | Xml.Element (_, _, c::_) -> c
11959 | Xml.Element (name, _, []) ->
11960 failwith (\"expected <\" ^ name ^ \"/> to have a child node\")
11961 | Xml.PCData str ->
11962 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11964 let string_child_or_empty = function
11965 | Xml.Element (_, _, [Xml.PCData s]) -> s
11966 | Xml.Element (_, _, []) -> \"\"
11967 | Xml.Element (x, _, _) ->
11968 failwith (\"expected XML tag with a single PCDATA child, but got \" ^
11970 | Xml.PCData str ->
11971 failwith (\"expected XML tag, but read PCDATA '\" ^ str ^ \"' instead\")
11973 let optional_child name xml =
11974 let children = Xml.children xml in
11976 Some (List.find (function
11977 | Xml.Element (n, _, _) when n = name -> true
11978 | _ -> false) children)
11982 let child name xml =
11983 match optional_child name xml with
11986 failwith (\"mandatory field <\" ^ name ^ \"/> missing in XML output\")
11988 let attribute name xml =
11989 try Xml.attrib xml name
11990 with Xml.No_attribute _ ->
11991 failwith (\"mandatory attribute \" ^ name ^ \" missing in XML output\")
11995 generate_parsers grammar;
11999 (* Run external virt-inspector, then use parser to parse the XML. *)
12000 let inspect ?connect ?xml names =
12004 if names = [] then invalid_arg \"inspect: no names given\";
12005 let cmd = [ \"virt-inspector\"; \"--xml\" ] @
12006 (match connect with None -> [] | Some uri -> [ \"--connect\"; uri ]) @
12008 let cmd = List.map Filename.quote cmd in
12009 let cmd = String.concat \" \" cmd in
12010 let chan = open_process_in cmd in
12011 let xml = Xml.parse_in chan in
12012 (match close_process_in chan with
12014 | WEXITED _ -> failwith \"external virt-inspector command failed\"
12015 | WSIGNALED i | WSTOPPED i ->
12016 failwith (\"external virt-inspector command died or stopped on sig \" ^
12021 Xml.parse_string doc in
12022 parse_operatingsystems xml
12025 and generate_max_proc_nr () =
12026 pr "%d\n" max_proc_nr
12028 let output_to filename k =
12029 let filename_new = filename ^ ".new" in
12030 chan := open_out filename_new;
12033 chan := Pervasives.stdout;
12035 (* Is the new file different from the current file? *)
12036 if Sys.file_exists filename && files_equal filename filename_new then
12037 unlink filename_new (* same, so skip it *)
12039 (* different, overwrite old one *)
12040 (try chmod filename 0o644 with Unix_error _ -> ());
12041 rename filename_new filename;
12042 chmod filename 0o444;
12043 printf "written %s\n%!" filename;
12046 let perror msg = function
12047 | Unix_error (err, _, _) ->
12048 eprintf "%s: %s\n" msg (error_message err)
12050 eprintf "%s: %s\n" msg (Printexc.to_string exn)
12052 (* Main program. *)
12055 try openfile "HACKING" [O_RDWR] 0
12057 | Unix_error (ENOENT, _, _) ->
12059 You are probably running this from the wrong directory.
12060 Run it from the top source directory using the command
12065 perror "open: HACKING" exn;
12068 (* Acquire a lock so parallel builds won't try to run the generator
12069 * twice at the same time. Subsequent builds will wait for the first
12070 * one to finish. Note the lock is released implicitly when the
12073 (try lockf lock_fd F_LOCK 1
12075 perror "lock: HACKING" exn;
12078 check_functions ();
12080 output_to "src/guestfs_protocol.x" generate_xdr;
12081 output_to "src/guestfs-structs.h" generate_structs_h;
12082 output_to "src/guestfs-actions.h" generate_actions_h;
12083 output_to "src/guestfs-internal-actions.h" generate_internal_actions_h;
12084 output_to "src/guestfs-actions.c" generate_client_actions;
12085 output_to "src/guestfs-bindtests.c" generate_bindtests;
12086 output_to "src/guestfs-structs.pod" generate_structs_pod;
12087 output_to "src/guestfs-actions.pod" generate_actions_pod;
12088 output_to "src/guestfs-availability.pod" generate_availability_pod;
12089 output_to "src/MAX_PROC_NR" generate_max_proc_nr;
12090 output_to "src/libguestfs.syms" generate_linker_script;
12091 output_to "daemon/actions.h" generate_daemon_actions_h;
12092 output_to "daemon/stubs.c" generate_daemon_actions;
12093 output_to "daemon/names.c" generate_daemon_names;
12094 output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
12095 output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
12096 output_to "capitests/tests.c" generate_tests;
12097 output_to "fish/cmds.c" generate_fish_cmds;
12098 output_to "fish/completion.c" generate_fish_completion;
12099 output_to "fish/guestfish-actions.pod" generate_fish_actions_pod;
12100 output_to "ocaml/guestfs.mli" generate_ocaml_mli;
12101 output_to "ocaml/guestfs.ml" generate_ocaml_ml;
12102 output_to "ocaml/guestfs_c_actions.c" generate_ocaml_c;
12103 output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
12104 output_to "ocaml/guestfs_inspector.mli" generate_ocaml_inspector_mli;
12105 output_to "ocaml/guestfs_inspector.ml" generate_ocaml_inspector_ml;
12106 output_to "perl/Guestfs.xs" generate_perl_xs;
12107 output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
12108 output_to "perl/bindtests.pl" generate_perl_bindtests;
12109 output_to "python/guestfs-py.c" generate_python_c;
12110 output_to "python/guestfs.py" generate_python_py;
12111 output_to "python/bindtests.py" generate_python_bindtests;
12112 output_to "ruby/ext/guestfs/_guestfs.c" generate_ruby_c;
12113 output_to "ruby/bindtests.rb" generate_ruby_bindtests;
12114 output_to "java/com/redhat/et/libguestfs/GuestFS.java" generate_java_java;
12118 let cols = cols_of_struct typ in
12119 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
12120 output_to filename (generate_java_struct jtyp cols);
12123 output_to "java/Makefile.inc" generate_java_makefile_inc;
12124 output_to "java/com_redhat_et_libguestfs_GuestFS.c" generate_java_c;
12125 output_to "java/Bindtests.java" generate_java_bindtests;
12126 output_to "haskell/Guestfs.hs" generate_haskell_hs;
12127 output_to "haskell/Bindtests.hs" generate_haskell_bindtests;
12128 output_to "csharp/Libguestfs.cs" generate_csharp;
12130 (* Always generate this file last, and unconditionally. It's used
12131 * by the Makefile to know when we must re-run the generator.
12133 let chan = open_out "src/stamp-generator" in
12134 fprintf chan "1\n";
12137 printf "generated %d lines of code\n" !lines