3 * Copyright (C) 2009 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 below), and
25 * daemon/<somefile>.c to write the implementation.
27 * After editing this file, run it (./src/generator.ml) to regenerate all the
28 * output files. Note that if you are using a separate build directory you
29 * must run generator.ml from the _source_ directory.
31 * IMPORTANT: This script should NOT print any warnings. If it prints
32 * warnings, you should treat them as errors.
41 type style = ret * args
43 (* "RErr" as a return value means an int used as a simple error
44 * indication, ie. 0 or -1.
48 (* "RInt" as a return value means an int which is -1 for error
49 * or any value >= 0 on success. Only use this for smallish
50 * positive ints (0 <= i < 2^30).
54 (* "RInt64" is the same as RInt, but is guaranteed to be able
55 * to return a full 64 bit value, _except_ that -1 means error
56 * (so -1 cannot be a valid, non-error return value).
60 (* "RBool" is a bool return value which can be true/false or
65 (* "RConstString" is a string that refers to a constant value.
66 * The return value must NOT be NULL (since NULL indicates
69 * Try to avoid using this. In particular you cannot use this
70 * for values returned from the daemon, because there is no
71 * thread-safe way to return them in the C API.
73 | RConstString of string
75 (* "RConstOptString" is an even more broken version of
76 * "RConstString". The returned string may be NULL and there
77 * is no way to return an error indication. Avoid using this!
79 | RConstOptString of string
81 (* "RString" is a returned string. It must NOT be NULL, since
82 * a NULL return indicates an error. The caller frees this.
86 (* "RStringList" is a list of strings. No string in the list
87 * can be NULL. The caller frees the strings and the array.
89 | RStringList of string
91 (* "RStruct" is a function which returns a single named structure
92 * or an error indication (in C, a struct, and in other languages
93 * with varying representations, but usually very efficient). See
94 * after the function list below for the structures.
96 | RStruct of string * string (* name of retval, name of struct *)
98 (* "RStructList" is a function which returns either a list/array
99 * of structures (could be zero-length), or an error indication.
101 | RStructList of string * string (* name of retval, name of struct *)
103 (* Key-value pairs of untyped strings. Turns into a hashtable or
104 * dictionary in languages which support it. DON'T use this as a
105 * general "bucket" for results. Prefer a stronger typed return
106 * value if one is available, or write a custom struct. Don't use
107 * this if the list could potentially be very long, since it is
108 * inefficient. Keys should be unique. NULLs are not permitted.
110 | RHashtable of string
112 (* "RBufferOut" is handled almost exactly like RString, but
113 * it allows the string to contain arbitrary 8 bit data including
114 * ASCII NUL. In the C API this causes an implicit extra parameter
115 * to be added of type <size_t *size_r>. The extra parameter
116 * returns the actual size of the return buffer in bytes.
118 * Other programming languages support strings with arbitrary 8 bit
121 * At the RPC layer we have to use the opaque<> type instead of
122 * string<>. Returned data is still limited to the max message
125 | RBufferOut of string
127 and args = argt list (* Function parameters, guestfs handle is implicit. *)
129 (* Note in future we should allow a "variable args" parameter as
130 * the final parameter, to allow commands like
131 * chmod mode file [file(s)...]
132 * This is not implemented yet, but many commands (such as chmod)
133 * are currently defined with the argument order keeping this future
134 * possibility in mind.
137 | String of string (* const char *name, cannot be NULL *)
138 | Device of string (* /dev device name, cannot be NULL *)
139 | Pathname of string (* file name, cannot be NULL *)
140 | Dev_or_Path of string (* /dev device name or Pathname, cannot be NULL *)
141 | OptString of string (* const char *name, may be NULL *)
142 | StringList of string(* list of strings (each string cannot be NULL) *)
143 | DeviceList of string(* list of Device names (each cannot be NULL) *)
144 | Bool of string (* boolean *)
145 | Int of string (* int (smallish ints, signed, <= 31 bits) *)
146 | Int64 of string (* any 64 bit int *)
147 (* These are treated as filenames (simple string parameters) in
148 * the C API and bindings. But in the RPC protocol, we transfer
149 * the actual file content up to or down from the daemon.
150 * FileIn: local machine -> daemon (in request)
151 * FileOut: daemon -> local machine (in reply)
152 * In guestfish (only), the special name "-" means read from
153 * stdin or write to stdout.
158 (* Opaque buffer which can contain arbitrary 8 bit data.
159 * In the C API, this is expressed as <char *, int> pair.
160 * Most other languages have a string type which can contain
161 * ASCII NUL. We use whatever type is appropriate for each
163 * Buffers are limited by the total message size. To transfer
164 * large blocks of data, use FileIn/FileOut parameters instead.
165 * To return an arbitrary buffer, use RBufferOut.
171 | ProtocolLimitWarning (* display warning about protocol size limits *)
172 | DangerWillRobinson (* flags particularly dangerous commands *)
173 | FishAlias of string (* provide an alias for this cmd in guestfish *)
174 | FishAction of string (* call this function in guestfish *)
175 | NotInFish (* do not export via guestfish *)
176 | NotInDocs (* do not add this function to documentation *)
177 | DeprecatedBy of string (* function is deprecated, use .. instead *)
179 (* You can supply zero or as many tests as you want per API call.
181 * Note that the test environment has 3 block devices, of size 500MB,
182 * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
183 * a fourth ISO block device with some known files on it (/dev/sdd).
185 * Note for partitioning purposes, the 500MB device has 1015 cylinders.
186 * Number of cylinders was 63 for IDE emulated disks with precisely
187 * the same size. How exactly this is calculated is a mystery.
189 * The ISO block device (/dev/sdd) comes from images/test.iso.
191 * To be able to run the tests in a reasonable amount of time,
192 * the virtual machine and block devices are reused between tests.
193 * So don't try testing kill_subprocess :-x
195 * Between each test we blockdev-setrw, umount-all, lvm-remove-all.
197 * Don't assume anything about the previous contents of the block
198 * devices. Use 'Init*' to create some initial scenarios.
200 * You can add a prerequisite clause to any individual test. This
201 * is a run-time check, which, if it fails, causes the test to be
202 * skipped. Useful if testing a command which might not work on
203 * all variations of libguestfs builds. A test that has prerequisite
204 * of 'Always' is run unconditionally.
206 * In addition, packagers can skip individual tests by setting the
207 * environment variables: eg:
208 * SKIP_TEST_<CMD>_<NUM>=1 SKIP_TEST_COMMAND_3=1 (skips test #3 of command)
209 * SKIP_TEST_<CMD>=1 SKIP_TEST_ZEROFREE=1 (skips all zerofree tests)
211 type tests = (test_init * test_prereq * test) list
213 (* Run the command sequence and just expect nothing to fail. *)
216 (* Run the command sequence and expect the output of the final
217 * command to be the string.
219 | TestOutput of seq * string
221 (* Run the command sequence and expect the output of the final
222 * command to be the list of strings.
224 | TestOutputList of seq * string list
226 (* Run the command sequence and expect the output of the final
227 * command to be the list of block devices (could be either
228 * "/dev/sd.." or "/dev/hd.." form - we don't check the 5th
229 * character of each string).
231 | TestOutputListOfDevices of seq * string list
233 (* Run the command sequence and expect the output of the final
234 * command to be the integer.
236 | TestOutputInt of seq * int
238 (* Run the command sequence and expect the output of the final
239 * command to be <op> <int>, eg. ">=", "1".
241 | TestOutputIntOp of seq * string * int
243 (* Run the command sequence and expect the output of the final
244 * command to be a true value (!= 0 or != NULL).
246 | TestOutputTrue of seq
248 (* Run the command sequence and expect the output of the final
249 * command to be a false value (== 0 or == NULL, but not an error).
251 | TestOutputFalse of seq
253 (* Run the command sequence and expect the output of the final
254 * command to be a list of the given length (but don't care about
257 | TestOutputLength of seq * int
259 (* Run the command sequence and expect the output of the final
260 * command to be a buffer (RBufferOut), ie. string + size.
262 | TestOutputBuffer of seq * string
264 (* Run the command sequence and expect the output of the final
265 * command to be a structure.
267 | TestOutputStruct of seq * test_field_compare list
269 (* Run the command sequence and expect the final command (only)
272 | TestLastFail of seq
274 and test_field_compare =
275 | CompareWithInt of string * int
276 | CompareWithIntOp of string * string * int
277 | CompareWithString of string * string
278 | CompareFieldsIntEq of string * string
279 | CompareFieldsStrEq of string * string
281 (* Test prerequisites. *)
283 (* Test always runs. *)
286 (* Test is currently disabled - eg. it fails, or it tests some
287 * unimplemented feature.
291 (* 'string' is some C code (a function body) that should return
292 * true or false. The test will run if the code returns true.
296 (* As for 'If' but the test runs _unless_ the code returns true. *)
299 (* Some initial scenarios for testing. *)
301 (* Do nothing, block devices could contain random stuff including
302 * LVM PVs, and some filesystems might be mounted. This is usually
307 (* Block devices are empty and no filesystems are mounted. *)
310 (* /dev/sda contains a single partition /dev/sda1, with random
311 * content. /dev/sdb and /dev/sdc may have random content.
316 (* /dev/sda contains a single partition /dev/sda1, which is formatted
317 * as ext2, empty [except for lost+found] and mounted on /.
318 * /dev/sdb and /dev/sdc may have random content.
324 * /dev/sda1 (is a PV):
325 * /dev/VG/LV (size 8MB):
326 * formatted as ext2, empty [except for lost+found], mounted on /
327 * /dev/sdb and /dev/sdc may have random content.
331 (* /dev/sdd (the ISO, see images/ directory in source)
336 (* Sequence of commands for testing. *)
338 and cmd = string list
340 (* Note about long descriptions: When referring to another
341 * action, use the format C<guestfs_other> (ie. the full name of
342 * the C function). This will be replaced as appropriate in other
345 * Apart from that, long descriptions are just perldoc paragraphs.
348 (* Generate a random UUID (used in tests). *)
350 let chan = open_process_in "uuidgen" in
351 let uuid = input_line chan in
352 (match close_process_in chan with
355 failwith "uuidgen: process exited with non-zero status"
356 | WSIGNALED _ | WSTOPPED _ ->
357 failwith "uuidgen: process signalled or stopped by signal"
361 (* These test functions are used in the language binding tests. *)
363 let test_all_args = [
366 StringList "strlist";
374 let test_all_rets = [
375 (* except for RErr, which is tested thoroughly elsewhere *)
376 "test0rint", RInt "valout";
377 "test0rint64", RInt64 "valout";
378 "test0rbool", RBool "valout";
379 "test0rconststring", RConstString "valout";
380 "test0rconstoptstring", RConstOptString "valout";
381 "test0rstring", RString "valout";
382 "test0rstringlist", RStringList "valout";
383 "test0rstruct", RStruct ("valout", "lvm_pv");
384 "test0rstructlist", RStructList ("valout", "lvm_pv");
385 "test0rhashtable", RHashtable "valout";
388 let test_functions = [
389 ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
391 "internal test function - do not use",
393 This is an internal test function which is used to test whether
394 the automatically generated bindings can handle every possible
395 parameter type correctly.
397 It echos the contents of each parameter to stdout.
399 You probably don't want to call this function.");
403 [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
405 "internal test function - do not use",
407 This is an internal test function which is used to test whether
408 the automatically generated bindings can handle every possible
409 return type correctly.
411 It converts string C<val> to the return type.
413 You probably don't want to call this function.");
414 (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
416 "internal test function - do not use",
418 This is an internal test function which is used to test whether
419 the automatically generated bindings can handle every possible
420 return type correctly.
422 This function always returns an error.
424 You probably don't want to call this function.")]
428 (* non_daemon_functions are any functions which don't get processed
429 * in the daemon, eg. functions for setting and getting local
430 * configuration values.
433 let non_daemon_functions = test_functions @ [
434 ("launch", (RErr, []), -1, [FishAlias "run"; FishAction "launch"],
436 "launch the qemu subprocess",
438 Internally libguestfs is implemented by running a virtual machine
441 You should call this after configuring the handle
442 (eg. adding drives) but before performing any actions.");
444 ("wait_ready", (RErr, []), -1, [NotInFish],
446 "wait until the qemu subprocess launches (no op)",
448 This function is a no op.
450 In versions of the API E<lt> 1.0.71 you had to call this function
451 just after calling C<guestfs_launch> to wait for the launch
452 to complete. However this is no longer necessary because
453 C<guestfs_launch> now does the waiting.
455 If you see any calls to this function in code then you can just
456 remove them, unless you want to retain compatibility with older
457 versions of the API.");
459 ("kill_subprocess", (RErr, []), -1, [],
461 "kill the qemu subprocess",
463 This kills the qemu subprocess. You should never need to call this.");
465 ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
467 "add an image to examine or modify",
469 This function adds a virtual machine disk image C<filename> to the
470 guest. The first time you call this function, the disk appears as IDE
471 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
474 You don't necessarily need to be root when using libguestfs. However
475 you obviously do need sufficient permissions to access the filename
476 for whatever operations you want to perform (ie. read access if you
477 just want to read the image or write access if you want to modify the
480 This is equivalent to the qemu parameter
481 C<-drive file=filename,cache=off,if=...>.
482 C<cache=off> is omitted in cases where it is not supported by
483 the underlying filesystem.
485 Note that this call checks for the existence of C<filename>. This
486 stops you from specifying other types of drive which are supported
487 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
488 the general C<guestfs_config> call instead.");
490 ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
492 "add a CD-ROM disk image to examine",
494 This function adds a virtual CD-ROM disk image to the guest.
496 This is equivalent to the qemu parameter C<-cdrom filename>.
498 Note that this call checks for the existence of C<filename>. This
499 stops you from specifying other types of drive which are supported
500 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
501 the general C<guestfs_config> call instead.");
503 ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
505 "add a drive in snapshot mode (read-only)",
507 This adds a drive in snapshot mode, making it effectively
510 Note that writes to the device are allowed, and will be seen for
511 the duration of the guestfs handle, but they are written
512 to a temporary file which is discarded as soon as the guestfs
513 handle is closed. We don't currently have any method to enable
514 changes to be committed, although qemu can support this.
516 This is equivalent to the qemu parameter
517 C<-drive file=filename,snapshot=on,if=...>.
519 Note that this call checks for the existence of C<filename>. This
520 stops you from specifying other types of drive which are supported
521 by qemu such as C<nbd:> and C<http:> URLs. To specify those, use
522 the general C<guestfs_config> call instead.");
524 ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
526 "add qemu parameters",
528 This can be used to add arbitrary qemu command line parameters
529 of the form C<-param value>. Actually it's not quite arbitrary - we
530 prevent you from setting some parameters which would interfere with
531 parameters that we use.
533 The first character of C<param> string must be a C<-> (dash).
535 C<value> can be NULL.");
537 ("set_qemu", (RErr, [String "qemu"]), -1, [FishAlias "qemu"],
539 "set the qemu binary",
541 Set the qemu binary that we will use.
543 The default is chosen when the library was compiled by the
546 You can also override this by setting the C<LIBGUESTFS_QEMU>
547 environment variable.
549 Setting C<qemu> to C<NULL> restores the default qemu binary.");
551 ("get_qemu", (RConstString "qemu", []), -1, [],
552 [InitNone, Always, TestRun (
554 "get the qemu binary",
556 Return the current qemu binary.
558 This is always non-NULL. If it wasn't set already, then this will
559 return the default qemu binary name.");
561 ("set_path", (RErr, [String "searchpath"]), -1, [FishAlias "path"],
563 "set the search path",
565 Set the path that libguestfs searches for kernel and initrd.img.
567 The default is C<$libdir/guestfs> unless overridden by setting
568 C<LIBGUESTFS_PATH> environment variable.
570 Setting C<path> to C<NULL> restores the default path.");
572 ("get_path", (RConstString "path", []), -1, [],
573 [InitNone, Always, TestRun (
575 "get the search path",
577 Return the current search path.
579 This is always non-NULL. If it wasn't set already, then this will
580 return the default path.");
582 ("set_append", (RErr, [OptString "append"]), -1, [FishAlias "append"],
584 "add options to kernel command line",
586 This function is used to add additional options to the
587 guest kernel command line.
589 The default is C<NULL> unless overridden by setting
590 C<LIBGUESTFS_APPEND> environment variable.
592 Setting C<append> to C<NULL> means I<no> additional options
593 are passed (libguestfs always adds a few of its own).");
595 ("get_append", (RConstOptString "append", []), -1, [],
596 (* This cannot be tested with the current framework. The
597 * function can return NULL in normal operations, which the
598 * test framework interprets as an error.
601 "get the additional kernel options",
603 Return the additional kernel options which are added to the
604 guest kernel command line.
606 If C<NULL> then no options are added.");
608 ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
612 If C<autosync> is true, this enables autosync. Libguestfs will make a
613 best effort attempt to run C<guestfs_umount_all> followed by
614 C<guestfs_sync> when the handle is closed
615 (also if the program exits without closing handles).
617 This is disabled by default (except in guestfish where it is
618 enabled by default).");
620 ("get_autosync", (RBool "autosync", []), -1, [],
621 [InitNone, Always, TestRun (
622 [["get_autosync"]])],
625 Get the autosync flag.");
627 ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
631 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
633 Verbose messages are disabled unless the environment variable
634 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
636 ("get_verbose", (RBool "verbose", []), -1, [],
640 This returns the verbose messages flag.");
642 ("is_ready", (RBool "ready", []), -1, [],
643 [InitNone, Always, TestOutputTrue (
645 "is ready to accept commands",
647 This returns true iff this handle is ready to accept commands
648 (in the C<READY> state).
650 For more information on states, see L<guestfs(3)>.");
652 ("is_config", (RBool "config", []), -1, [],
653 [InitNone, Always, TestOutputFalse (
655 "is in configuration state",
657 This returns true iff this handle is being configured
658 (in the C<CONFIG> state).
660 For more information on states, see L<guestfs(3)>.");
662 ("is_launching", (RBool "launching", []), -1, [],
663 [InitNone, Always, TestOutputFalse (
664 [["is_launching"]])],
665 "is launching subprocess",
667 This returns true iff this handle is launching the subprocess
668 (in the C<LAUNCHING> state).
670 For more information on states, see L<guestfs(3)>.");
672 ("is_busy", (RBool "busy", []), -1, [],
673 [InitNone, Always, TestOutputFalse (
675 "is busy processing a command",
677 This returns true iff this handle is busy processing a command
678 (in the C<BUSY> state).
680 For more information on states, see L<guestfs(3)>.");
682 ("get_state", (RInt "state", []), -1, [],
684 "get the current state",
686 This returns the current state as an opaque integer. This is
687 only useful for printing debug and internal error messages.
689 For more information on states, see L<guestfs(3)>.");
691 ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"],
692 [InitNone, Always, TestOutputInt (
693 [["set_memsize"; "500"];
694 ["get_memsize"]], 500)],
695 "set memory allocated to the qemu subprocess",
697 This sets the memory size in megabytes allocated to the
698 qemu subprocess. This only has any effect if called before
701 You can also change this by setting the environment
702 variable C<LIBGUESTFS_MEMSIZE> before the handle is
705 For more information on the architecture of libguestfs,
706 see L<guestfs(3)>.");
708 ("get_memsize", (RInt "memsize", []), -1, [],
709 [InitNone, Always, TestOutputIntOp (
710 [["get_memsize"]], ">=", 256)],
711 "get memory allocated to the qemu subprocess",
713 This gets the memory size in megabytes allocated to the
716 If C<guestfs_set_memsize> was not called
717 on this handle, and if C<LIBGUESTFS_MEMSIZE> was not set,
718 then this returns the compiled-in default value for memsize.
720 For more information on the architecture of libguestfs,
721 see L<guestfs(3)>.");
723 ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"],
724 [InitNone, Always, TestOutputIntOp (
725 [["get_pid"]], ">=", 1)],
726 "get PID of qemu subprocess",
728 Return the process ID of the qemu subprocess. If there is no
729 qemu subprocess, then this will return an error.
731 This is an internal call used for debugging and testing.");
733 ("version", (RStruct ("version", "version"), []), -1, [],
734 [InitNone, Always, TestOutputStruct (
735 [["version"]], [CompareWithInt ("major", 1)])],
736 "get the library version number",
738 Return the libguestfs version number that the program is linked
741 Note that because of dynamic linking this is not necessarily
742 the version of libguestfs that you compiled against. You can
743 compile the program, and then at runtime dynamically link
744 against a completely different C<libguestfs.so> library.
746 This call was added in version C<1.0.58>. In previous
747 versions of libguestfs there was no way to get the version
748 number. From C code you can use ELF weak linking tricks to find out if
749 this symbol exists (if it doesn't, then it's an earlier version).
751 The call returns a structure with four elements. The first
752 three (C<major>, C<minor> and C<release>) are numbers and
753 correspond to the usual version triplet. The fourth element
754 (C<extra>) is a string and is normally empty, but may be
755 used for distro-specific information.
757 To construct the original version string:
758 C<$major.$minor.$release$extra>
760 I<Note:> Don't use this call to test for availability
761 of features. Distro backports makes this unreliable. Use
762 C<guestfs_available> instead.");
764 ("set_selinux", (RErr, [Bool "selinux"]), -1, [FishAlias "selinux"],
765 [InitNone, Always, TestOutputTrue (
766 [["set_selinux"; "true"];
768 "set SELinux enabled or disabled at appliance boot",
770 This sets the selinux flag that is passed to the appliance
771 at boot time. The default is C<selinux=0> (disabled).
773 Note that if SELinux is enabled, it is always in
774 Permissive mode (C<enforcing=0>).
776 For more information on the architecture of libguestfs,
777 see L<guestfs(3)>.");
779 ("get_selinux", (RBool "selinux", []), -1, [],
781 "get SELinux enabled flag",
783 This returns the current setting of the selinux flag which
784 is passed to the appliance at boot time. See C<guestfs_set_selinux>.
786 For more information on the architecture of libguestfs,
787 see L<guestfs(3)>.");
789 ("set_trace", (RErr, [Bool "trace"]), -1, [FishAlias "trace"],
790 [InitNone, Always, TestOutputFalse (
791 [["set_trace"; "false"];
793 "enable or disable command traces",
795 If the command trace flag is set to 1, then commands are
796 printed on stdout before they are executed in a format
797 which is very similar to the one used by guestfish. In
798 other words, you can run a program with this enabled, and
799 you will get out a script which you can feed to guestfish
800 to perform the same set of actions.
802 If you want to trace C API calls into libguestfs (and
803 other libraries) then possibly a better way is to use
804 the external ltrace(1) command.
806 Command traces are disabled unless the environment variable
807 C<LIBGUESTFS_TRACE> is defined and set to C<1>.");
809 ("get_trace", (RBool "trace", []), -1, [],
811 "get command trace enabled flag",
813 Return the command trace flag.");
815 ("set_direct", (RErr, [Bool "direct"]), -1, [FishAlias "direct"],
816 [InitNone, Always, TestOutputFalse (
817 [["set_direct"; "false"];
819 "enable or disable direct appliance mode",
821 If the direct appliance mode flag is enabled, then stdin and
822 stdout are passed directly through to the appliance once it
825 One consequence of this is that log messages aren't caught
826 by the library and handled by C<guestfs_set_log_message_callback>,
827 but go straight to stdout.
829 You probably don't want to use this unless you know what you
832 The default is disabled.");
834 ("get_direct", (RBool "direct", []), -1, [],
836 "get direct appliance mode flag",
838 Return the direct appliance mode flag.");
840 ("set_recovery_proc", (RErr, [Bool "recoveryproc"]), -1, [FishAlias "recovery-proc"],
841 [InitNone, Always, TestOutputTrue (
842 [["set_recovery_proc"; "true"];
843 ["get_recovery_proc"]])],
844 "enable or disable the recovery process",
846 If this is called with the parameter C<false> then
847 C<guestfs_launch> does not create a recovery process. The
848 purpose of the recovery process is to stop runaway qemu
849 processes in the case where the main program aborts abruptly.
851 This only has any effect if called before C<guestfs_launch>,
852 and the default is true.
854 About the only time when you would want to disable this is
855 if the main process will fork itself into the background
856 (\"daemonize\" itself). In this case the recovery process
857 thinks that the main program has disappeared and so kills
858 qemu, which is not very helpful.");
860 ("get_recovery_proc", (RBool "recoveryproc", []), -1, [],
862 "get recovery process enabled flag",
864 Return the recovery process enabled flag.");
868 (* daemon_functions are any functions which cause some action
869 * to take place in the daemon.
872 let daemon_functions = [
873 ("mount", (RErr, [Device "device"; String "mountpoint"]), 1, [],
874 [InitEmpty, Always, TestOutput (
875 [["part_disk"; "/dev/sda"; "mbr"];
876 ["mkfs"; "ext2"; "/dev/sda1"];
877 ["mount"; "/dev/sda1"; "/"];
878 ["write_file"; "/new"; "new file contents"; "0"];
879 ["cat"; "/new"]], "new file contents")],
880 "mount a guest disk at a position in the filesystem",
882 Mount a guest disk at a position in the filesystem. Block devices
883 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
884 the guest. If those block devices contain partitions, they will have
885 the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style
888 The rules are the same as for L<mount(2)>: A filesystem must
889 first be mounted on C</> before others can be mounted. Other
890 filesystems can only be mounted on directories which already
893 The mounted filesystem is writable, if we have sufficient permissions
894 on the underlying device.
896 The filesystem options C<sync> and C<noatime> are set with this
897 call, in order to improve reliability.");
899 ("sync", (RErr, []), 2, [],
900 [ InitEmpty, Always, TestRun [["sync"]]],
901 "sync disks, writes are flushed through to the disk image",
903 This syncs the disk, so that any writes are flushed through to the
904 underlying disk image.
906 You should always call this if you have modified a disk image, before
907 closing the handle.");
909 ("touch", (RErr, [Pathname "path"]), 3, [],
910 [InitBasicFS, Always, TestOutputTrue (
912 ["exists"; "/new"]])],
913 "update file timestamps or create a new file",
915 Touch acts like the L<touch(1)> command. It can be used to
916 update the timestamps on a file, or, if the file does not exist,
917 to create a new zero-length file.");
919 ("cat", (RString "content", [Pathname "path"]), 4, [ProtocolLimitWarning],
920 [InitISOFS, Always, TestOutput (
921 [["cat"; "/known-2"]], "abcdef\n")],
922 "list the contents of a file",
924 Return the contents of the file named C<path>.
926 Note that this function cannot correctly handle binary files
927 (specifically, files containing C<\\0> character which is treated
928 as end of string). For those you need to use the C<guestfs_read_file>
929 or C<guestfs_download> functions which have a more complex interface.");
931 ("ll", (RString "listing", [Pathname "directory"]), 5, [],
932 [], (* XXX Tricky to test because it depends on the exact format
933 * of the 'ls -l' command, which changes between F10 and F11.
935 "list the files in a directory (long format)",
937 List the files in C<directory> (relative to the root directory,
938 there is no cwd) in the format of 'ls -la'.
940 This command is mostly useful for interactive sessions. It
941 is I<not> intended that you try to parse the output string.");
943 ("ls", (RStringList "listing", [Pathname "directory"]), 6, [],
944 [InitBasicFS, Always, TestOutputList (
947 ["touch"; "/newest"];
948 ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
949 "list the files in a directory",
951 List the files in C<directory> (relative to the root directory,
952 there is no cwd). The '.' and '..' entries are not returned, but
953 hidden files are shown.
955 This command is mostly useful for interactive sessions. Programs
956 should probably use C<guestfs_readdir> instead.");
958 ("list_devices", (RStringList "devices", []), 7, [],
959 [InitEmpty, Always, TestOutputListOfDevices (
960 [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
961 "list the block devices",
963 List all the block devices.
965 The full block device names are returned, eg. C</dev/sda>");
967 ("list_partitions", (RStringList "partitions", []), 8, [],
968 [InitBasicFS, Always, TestOutputListOfDevices (
969 [["list_partitions"]], ["/dev/sda1"]);
970 InitEmpty, Always, TestOutputListOfDevices (
971 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
972 ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
973 "list the partitions",
975 List all the partitions detected on all block devices.
977 The full partition device names are returned, eg. C</dev/sda1>
979 This does not return logical volumes. For that you will need to
980 call C<guestfs_lvs>.");
982 ("pvs", (RStringList "physvols", []), 9, [],
983 [InitBasicFSonLVM, Always, TestOutputListOfDevices (
984 [["pvs"]], ["/dev/sda1"]);
985 InitEmpty, Always, TestOutputListOfDevices (
986 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
987 ["pvcreate"; "/dev/sda1"];
988 ["pvcreate"; "/dev/sda2"];
989 ["pvcreate"; "/dev/sda3"];
990 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
991 "list the LVM physical volumes (PVs)",
993 List all the physical volumes detected. This is the equivalent
994 of the L<pvs(8)> command.
996 This returns a list of just the device names that contain
997 PVs (eg. C</dev/sda2>).
999 See also C<guestfs_pvs_full>.");
1001 ("vgs", (RStringList "volgroups", []), 10, [],
1002 [InitBasicFSonLVM, Always, TestOutputList (
1004 InitEmpty, Always, TestOutputList (
1005 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1006 ["pvcreate"; "/dev/sda1"];
1007 ["pvcreate"; "/dev/sda2"];
1008 ["pvcreate"; "/dev/sda3"];
1009 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1010 ["vgcreate"; "VG2"; "/dev/sda3"];
1011 ["vgs"]], ["VG1"; "VG2"])],
1012 "list the LVM volume groups (VGs)",
1014 List all the volumes groups detected. This is the equivalent
1015 of the L<vgs(8)> command.
1017 This returns a list of just the volume group names that were
1018 detected (eg. C<VolGroup00>).
1020 See also C<guestfs_vgs_full>.");
1022 ("lvs", (RStringList "logvols", []), 11, [],
1023 [InitBasicFSonLVM, Always, TestOutputList (
1024 [["lvs"]], ["/dev/VG/LV"]);
1025 InitEmpty, Always, TestOutputList (
1026 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1027 ["pvcreate"; "/dev/sda1"];
1028 ["pvcreate"; "/dev/sda2"];
1029 ["pvcreate"; "/dev/sda3"];
1030 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1031 ["vgcreate"; "VG2"; "/dev/sda3"];
1032 ["lvcreate"; "LV1"; "VG1"; "50"];
1033 ["lvcreate"; "LV2"; "VG1"; "50"];
1034 ["lvcreate"; "LV3"; "VG2"; "50"];
1035 ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
1036 "list the LVM logical volumes (LVs)",
1038 List all the logical volumes detected. This is the equivalent
1039 of the L<lvs(8)> command.
1041 This returns a list of the logical volume device names
1042 (eg. C</dev/VolGroup00/LogVol00>).
1044 See also C<guestfs_lvs_full>.");
1046 ("pvs_full", (RStructList ("physvols", "lvm_pv"), []), 12, [],
1047 [], (* XXX how to test? *)
1048 "list the LVM physical volumes (PVs)",
1050 List all the physical volumes detected. This is the equivalent
1051 of the L<pvs(8)> command. The \"full\" version includes all fields.");
1053 ("vgs_full", (RStructList ("volgroups", "lvm_vg"), []), 13, [],
1054 [], (* XXX how to test? *)
1055 "list the LVM volume groups (VGs)",
1057 List all the volumes groups detected. This is the equivalent
1058 of the L<vgs(8)> command. The \"full\" version includes all fields.");
1060 ("lvs_full", (RStructList ("logvols", "lvm_lv"), []), 14, [],
1061 [], (* XXX how to test? *)
1062 "list the LVM logical volumes (LVs)",
1064 List all the logical volumes detected. This is the equivalent
1065 of the L<lvs(8)> command. The \"full\" version includes all fields.");
1067 ("read_lines", (RStringList "lines", [Pathname "path"]), 15, [],
1068 [InitISOFS, Always, TestOutputList (
1069 [["read_lines"; "/known-4"]], ["abc"; "def"; "ghi"]);
1070 InitISOFS, Always, TestOutputList (
1071 [["read_lines"; "/empty"]], [])],
1072 "read file as lines",
1074 Return the contents of the file named C<path>.
1076 The file contents are returned as a list of lines. Trailing
1077 C<LF> and C<CRLF> character sequences are I<not> returned.
1079 Note that this function cannot correctly handle binary files
1080 (specifically, files containing C<\\0> character which is treated
1081 as end of line). For those you need to use the C<guestfs_read_file>
1082 function which has a more complex interface.");
1084 ("aug_init", (RErr, [Pathname "root"; Int "flags"]), 16, [],
1085 [], (* XXX Augeas code needs tests. *)
1086 "create a new Augeas handle",
1088 Create a new Augeas handle for editing configuration files.
1089 If there was any previous Augeas handle associated with this
1090 guestfs session, then it is closed.
1092 You must call this before using any other C<guestfs_aug_*>
1095 C<root> is the filesystem root. C<root> must not be NULL,
1098 The flags are the same as the flags defined in
1099 E<lt>augeas.hE<gt>, the logical I<or> of the following
1104 =item C<AUG_SAVE_BACKUP> = 1
1106 Keep the original file with a C<.augsave> extension.
1108 =item C<AUG_SAVE_NEWFILE> = 2
1110 Save changes into a file with extension C<.augnew>, and
1111 do not overwrite original. Overrides C<AUG_SAVE_BACKUP>.
1113 =item C<AUG_TYPE_CHECK> = 4
1115 Typecheck lenses (can be expensive).
1117 =item C<AUG_NO_STDINC> = 8
1119 Do not use standard load path for modules.
1121 =item C<AUG_SAVE_NOOP> = 16
1123 Make save a no-op, just record what would have been changed.
1125 =item C<AUG_NO_LOAD> = 32
1127 Do not load the tree in C<guestfs_aug_init>.
1131 To close the handle, you can call C<guestfs_aug_close>.
1133 To find out more about Augeas, see L<http://augeas.net/>.");
1135 ("aug_close", (RErr, []), 26, [],
1136 [], (* XXX Augeas code needs tests. *)
1137 "close the current Augeas handle",
1139 Close the current Augeas handle and free up any resources
1140 used by it. After calling this, you have to call
1141 C<guestfs_aug_init> again before you can use any other
1142 Augeas functions.");
1144 ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [],
1145 [], (* XXX Augeas code needs tests. *)
1146 "define an Augeas variable",
1148 Defines an Augeas variable C<name> whose value is the result
1149 of evaluating C<expr>. If C<expr> is NULL, then C<name> is
1152 On success this returns the number of nodes in C<expr>, or
1153 C<0> if C<expr> evaluates to something which is not a nodeset.");
1155 ("aug_defnode", (RStruct ("nrnodescreated", "int_bool"), [String "name"; String "expr"; String "val"]), 18, [],
1156 [], (* XXX Augeas code needs tests. *)
1157 "define an Augeas node",
1159 Defines a variable C<name> whose value is the result of
1162 If C<expr> evaluates to an empty nodeset, a node is created,
1163 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
1164 C<name> will be the nodeset containing that single node.
1166 On success this returns a pair containing the
1167 number of nodes in the nodeset, and a boolean flag
1168 if a node was created.");
1170 ("aug_get", (RString "val", [String "augpath"]), 19, [],
1171 [], (* XXX Augeas code needs tests. *)
1172 "look up the value of an Augeas path",
1174 Look up the value associated with C<path>. If C<path>
1175 matches exactly one node, the C<value> is returned.");
1177 ("aug_set", (RErr, [String "augpath"; String "val"]), 20, [],
1178 [], (* XXX Augeas code needs tests. *)
1179 "set Augeas path to value",
1181 Set the value associated with C<path> to C<value>.");
1183 ("aug_insert", (RErr, [String "augpath"; String "label"; Bool "before"]), 21, [],
1184 [], (* XXX Augeas code needs tests. *)
1185 "insert a sibling Augeas node",
1187 Create a new sibling C<label> for C<path>, inserting it into
1188 the tree before or after C<path> (depending on the boolean
1191 C<path> must match exactly one existing node in the tree, and
1192 C<label> must be a label, ie. not contain C</>, C<*> or end
1193 with a bracketed index C<[N]>.");
1195 ("aug_rm", (RInt "nrnodes", [String "augpath"]), 22, [],
1196 [], (* XXX Augeas code needs tests. *)
1197 "remove an Augeas path",
1199 Remove C<path> and all of its children.
1201 On success this returns the number of entries which were removed.");
1203 ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [],
1204 [], (* XXX Augeas code needs tests. *)
1207 Move the node C<src> to C<dest>. C<src> must match exactly
1208 one node. C<dest> is overwritten if it exists.");
1210 ("aug_match", (RStringList "matches", [String "augpath"]), 24, [],
1211 [], (* XXX Augeas code needs tests. *)
1212 "return Augeas nodes which match augpath",
1214 Returns a list of paths which match the path expression C<path>.
1215 The returned paths are sufficiently qualified so that they match
1216 exactly one node in the current tree.");
1218 ("aug_save", (RErr, []), 25, [],
1219 [], (* XXX Augeas code needs tests. *)
1220 "write all pending Augeas changes to disk",
1222 This writes all pending changes to disk.
1224 The flags which were passed to C<guestfs_aug_init> affect exactly
1225 how files are saved.");
1227 ("aug_load", (RErr, []), 27, [],
1228 [], (* XXX Augeas code needs tests. *)
1229 "load files into the tree",
1231 Load files into the tree.
1233 See C<aug_load> in the Augeas documentation for the full gory
1236 ("aug_ls", (RStringList "matches", [String "augpath"]), 28, [],
1237 [], (* XXX Augeas code needs tests. *)
1238 "list Augeas nodes under augpath",
1240 This is just a shortcut for listing C<guestfs_aug_match>
1241 C<path/*> and sorting the resulting nodes into alphabetical order.");
1243 ("rm", (RErr, [Pathname "path"]), 29, [],
1244 [InitBasicFS, Always, TestRun
1247 InitBasicFS, Always, TestLastFail
1249 InitBasicFS, Always, TestLastFail
1254 Remove the single file C<path>.");
1256 ("rmdir", (RErr, [Pathname "path"]), 30, [],
1257 [InitBasicFS, Always, TestRun
1260 InitBasicFS, Always, TestLastFail
1261 [["rmdir"; "/new"]];
1262 InitBasicFS, Always, TestLastFail
1264 ["rmdir"; "/new"]]],
1265 "remove a directory",
1267 Remove the single directory C<path>.");
1269 ("rm_rf", (RErr, [Pathname "path"]), 31, [],
1270 [InitBasicFS, Always, TestOutputFalse
1272 ["mkdir"; "/new/foo"];
1273 ["touch"; "/new/foo/bar"];
1275 ["exists"; "/new"]]],
1276 "remove a file or directory recursively",
1278 Remove the file or directory C<path>, recursively removing the
1279 contents if its a directory. This is like the C<rm -rf> shell
1282 ("mkdir", (RErr, [Pathname "path"]), 32, [],
1283 [InitBasicFS, Always, TestOutputTrue
1285 ["is_dir"; "/new"]];
1286 InitBasicFS, Always, TestLastFail
1287 [["mkdir"; "/new/foo/bar"]]],
1288 "create a directory",
1290 Create a directory named C<path>.");
1292 ("mkdir_p", (RErr, [Pathname "path"]), 33, [],
1293 [InitBasicFS, Always, TestOutputTrue
1294 [["mkdir_p"; "/new/foo/bar"];
1295 ["is_dir"; "/new/foo/bar"]];
1296 InitBasicFS, Always, TestOutputTrue
1297 [["mkdir_p"; "/new/foo/bar"];
1298 ["is_dir"; "/new/foo"]];
1299 InitBasicFS, Always, TestOutputTrue
1300 [["mkdir_p"; "/new/foo/bar"];
1301 ["is_dir"; "/new"]];
1302 (* Regression tests for RHBZ#503133: *)
1303 InitBasicFS, Always, TestRun
1305 ["mkdir_p"; "/new"]];
1306 InitBasicFS, Always, TestLastFail
1308 ["mkdir_p"; "/new"]]],
1309 "create a directory and parents",
1311 Create a directory named C<path>, creating any parent directories
1312 as necessary. This is like the C<mkdir -p> shell command.");
1314 ("chmod", (RErr, [Int "mode"; Pathname "path"]), 34, [],
1315 [], (* XXX Need stat command to test *)
1318 Change the mode (permissions) of C<path> to C<mode>. Only
1319 numeric modes are supported.");
1321 ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [],
1322 [], (* XXX Need stat command to test *)
1323 "change file owner and group",
1325 Change the file owner to C<owner> and group to C<group>.
1327 Only numeric uid and gid are supported. If you want to use
1328 names, you will need to locate and parse the password file
1329 yourself (Augeas support makes this relatively easy).");
1331 ("exists", (RBool "existsflag", [Pathname "path"]), 36, [],
1332 [InitISOFS, Always, TestOutputTrue (
1333 [["exists"; "/empty"]]);
1334 InitISOFS, Always, TestOutputTrue (
1335 [["exists"; "/directory"]])],
1336 "test if file or directory exists",
1338 This returns C<true> if and only if there is a file, directory
1339 (or anything) with the given C<path> name.
1341 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1343 ("is_file", (RBool "fileflag", [Pathname "path"]), 37, [],
1344 [InitISOFS, Always, TestOutputTrue (
1345 [["is_file"; "/known-1"]]);
1346 InitISOFS, Always, TestOutputFalse (
1347 [["is_file"; "/directory"]])],
1348 "test if file exists",
1350 This returns C<true> if and only if there is a file
1351 with the given C<path> name. Note that it returns false for
1352 other objects like directories.
1354 See also C<guestfs_stat>.");
1356 ("is_dir", (RBool "dirflag", [Pathname "path"]), 38, [],
1357 [InitISOFS, Always, TestOutputFalse (
1358 [["is_dir"; "/known-3"]]);
1359 InitISOFS, Always, TestOutputTrue (
1360 [["is_dir"; "/directory"]])],
1361 "test if file exists",
1363 This returns C<true> if and only if there is a directory
1364 with the given C<path> name. Note that it returns false for
1365 other objects like files.
1367 See also C<guestfs_stat>.");
1369 ("pvcreate", (RErr, [Device "device"]), 39, [],
1370 [InitEmpty, Always, TestOutputListOfDevices (
1371 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1372 ["pvcreate"; "/dev/sda1"];
1373 ["pvcreate"; "/dev/sda2"];
1374 ["pvcreate"; "/dev/sda3"];
1375 ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1376 "create an LVM physical volume",
1378 This creates an LVM physical volume on the named C<device>,
1379 where C<device> should usually be a partition name such
1382 ("vgcreate", (RErr, [String "volgroup"; DeviceList "physvols"]), 40, [],
1383 [InitEmpty, Always, TestOutputList (
1384 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1385 ["pvcreate"; "/dev/sda1"];
1386 ["pvcreate"; "/dev/sda2"];
1387 ["pvcreate"; "/dev/sda3"];
1388 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1389 ["vgcreate"; "VG2"; "/dev/sda3"];
1390 ["vgs"]], ["VG1"; "VG2"])],
1391 "create an LVM volume group",
1393 This creates an LVM volume group called C<volgroup>
1394 from the non-empty list of physical volumes C<physvols>.");
1396 ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [],
1397 [InitEmpty, Always, TestOutputList (
1398 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1399 ["pvcreate"; "/dev/sda1"];
1400 ["pvcreate"; "/dev/sda2"];
1401 ["pvcreate"; "/dev/sda3"];
1402 ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1403 ["vgcreate"; "VG2"; "/dev/sda3"];
1404 ["lvcreate"; "LV1"; "VG1"; "50"];
1405 ["lvcreate"; "LV2"; "VG1"; "50"];
1406 ["lvcreate"; "LV3"; "VG2"; "50"];
1407 ["lvcreate"; "LV4"; "VG2"; "50"];
1408 ["lvcreate"; "LV5"; "VG2"; "50"];
1410 ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1411 "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1412 "create an LVM volume group",
1414 This creates an LVM volume group called C<logvol>
1415 on the volume group C<volgroup>, with C<size> megabytes.");
1417 ("mkfs", (RErr, [String "fstype"; Device "device"]), 42, [],
1418 [InitEmpty, Always, TestOutput (
1419 [["part_disk"; "/dev/sda"; "mbr"];
1420 ["mkfs"; "ext2"; "/dev/sda1"];
1421 ["mount"; "/dev/sda1"; "/"];
1422 ["write_file"; "/new"; "new file contents"; "0"];
1423 ["cat"; "/new"]], "new file contents")],
1424 "make a filesystem",
1426 This creates a filesystem on C<device> (usually a partition
1427 or LVM logical volume). The filesystem type is C<fstype>, for
1430 ("sfdisk", (RErr, [Device "device";
1431 Int "cyls"; Int "heads"; Int "sectors";
1432 StringList "lines"]), 43, [DangerWillRobinson],
1434 "create partitions on a block device",
1436 This is a direct interface to the L<sfdisk(8)> program for creating
1437 partitions on block devices.
1439 C<device> should be a block device, for example C</dev/sda>.
1441 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1442 and sectors on the device, which are passed directly to sfdisk as
1443 the I<-C>, I<-H> and I<-S> parameters. If you pass C<0> for any
1444 of these, then the corresponding parameter is omitted. Usually for
1445 'large' disks, you can just pass C<0> for these, but for small
1446 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1447 out the right geometry and you will need to tell it.
1449 C<lines> is a list of lines that we feed to C<sfdisk>. For more
1450 information refer to the L<sfdisk(8)> manpage.
1452 To create a single partition occupying the whole disk, you would
1453 pass C<lines> as a single element list, when the single element being
1454 the string C<,> (comma).
1456 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>,
1457 C<guestfs_part_init>");
1459 ("write_file", (RErr, [Pathname "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning],
1460 [InitBasicFS, Always, TestOutput (
1461 [["write_file"; "/new"; "new file contents"; "0"];
1462 ["cat"; "/new"]], "new file contents");
1463 InitBasicFS, Always, TestOutput (
1464 [["write_file"; "/new"; "\nnew file contents\n"; "0"];
1465 ["cat"; "/new"]], "\nnew file contents\n");
1466 InitBasicFS, Always, TestOutput (
1467 [["write_file"; "/new"; "\n\n"; "0"];
1468 ["cat"; "/new"]], "\n\n");
1469 InitBasicFS, Always, TestOutput (
1470 [["write_file"; "/new"; ""; "0"];
1471 ["cat"; "/new"]], "");
1472 InitBasicFS, Always, TestOutput (
1473 [["write_file"; "/new"; "\n\n\n"; "0"];
1474 ["cat"; "/new"]], "\n\n\n");
1475 InitBasicFS, Always, TestOutput (
1476 [["write_file"; "/new"; "\n"; "0"];
1477 ["cat"; "/new"]], "\n")],
1480 This call creates a file called C<path>. The contents of the
1481 file is the string C<content> (which can contain any 8 bit data),
1482 with length C<size>.
1484 As a special case, if C<size> is C<0>
1485 then the length is calculated using C<strlen> (so in this case
1486 the content cannot contain embedded ASCII NULs).
1488 I<NB.> Owing to a bug, writing content containing ASCII NUL
1489 characters does I<not> work, even if the length is specified.
1490 We hope to resolve this bug in a future version. In the meantime
1491 use C<guestfs_upload>.");
1493 ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1494 [InitEmpty, Always, TestOutputListOfDevices (
1495 [["part_disk"; "/dev/sda"; "mbr"];
1496 ["mkfs"; "ext2"; "/dev/sda1"];
1497 ["mount"; "/dev/sda1"; "/"];
1498 ["mounts"]], ["/dev/sda1"]);
1499 InitEmpty, Always, TestOutputList (
1500 [["part_disk"; "/dev/sda"; "mbr"];
1501 ["mkfs"; "ext2"; "/dev/sda1"];
1502 ["mount"; "/dev/sda1"; "/"];
1505 "unmount a filesystem",
1507 This unmounts the given filesystem. The filesystem may be
1508 specified either by its mountpoint (path) or the device which
1509 contains the filesystem.");
1511 ("mounts", (RStringList "devices", []), 46, [],
1512 [InitBasicFS, Always, TestOutputListOfDevices (
1513 [["mounts"]], ["/dev/sda1"])],
1514 "show mounted filesystems",
1516 This returns the list of currently mounted filesystems. It returns
1517 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1519 Some internal mounts are not shown.
1521 See also: C<guestfs_mountpoints>");
1523 ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1524 [InitBasicFS, Always, TestOutputList (
1527 (* check that umount_all can unmount nested mounts correctly: *)
1528 InitEmpty, Always, TestOutputList (
1529 [["sfdiskM"; "/dev/sda"; ",100 ,200 ,"];
1530 ["mkfs"; "ext2"; "/dev/sda1"];
1531 ["mkfs"; "ext2"; "/dev/sda2"];
1532 ["mkfs"; "ext2"; "/dev/sda3"];
1533 ["mount"; "/dev/sda1"; "/"];
1535 ["mount"; "/dev/sda2"; "/mp1"];
1536 ["mkdir"; "/mp1/mp2"];
1537 ["mount"; "/dev/sda3"; "/mp1/mp2"];
1538 ["mkdir"; "/mp1/mp2/mp3"];
1541 "unmount all filesystems",
1543 This unmounts all mounted filesystems.
1545 Some internal mounts are not unmounted by this call.");
1547 ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson],
1549 "remove all LVM LVs, VGs and PVs",
1551 This command removes all LVM logical volumes, volume groups
1552 and physical volumes.");
1554 ("file", (RString "description", [Dev_or_Path "path"]), 49, [],
1555 [InitISOFS, Always, TestOutput (
1556 [["file"; "/empty"]], "empty");
1557 InitISOFS, Always, TestOutput (
1558 [["file"; "/known-1"]], "ASCII text");
1559 InitISOFS, Always, TestLastFail (
1560 [["file"; "/notexists"]])],
1561 "determine file type",
1563 This call uses the standard L<file(1)> command to determine
1564 the type or contents of the file. This also works on devices,
1565 for example to find out whether a partition contains a filesystem.
1567 This call will also transparently look inside various types
1570 The exact command which runs is C<file -zbsL path>. Note in
1571 particular that the filename is not prepended to the output
1572 (the C<-b> option).");
1574 ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1575 [InitBasicFS, Always, TestOutput (
1576 [["upload"; "test-command"; "/test-command"];
1577 ["chmod"; "0o755"; "/test-command"];
1578 ["command"; "/test-command 1"]], "Result1");
1579 InitBasicFS, Always, TestOutput (
1580 [["upload"; "test-command"; "/test-command"];
1581 ["chmod"; "0o755"; "/test-command"];
1582 ["command"; "/test-command 2"]], "Result2\n");
1583 InitBasicFS, Always, TestOutput (
1584 [["upload"; "test-command"; "/test-command"];
1585 ["chmod"; "0o755"; "/test-command"];
1586 ["command"; "/test-command 3"]], "\nResult3");
1587 InitBasicFS, Always, TestOutput (
1588 [["upload"; "test-command"; "/test-command"];
1589 ["chmod"; "0o755"; "/test-command"];
1590 ["command"; "/test-command 4"]], "\nResult4\n");
1591 InitBasicFS, Always, TestOutput (
1592 [["upload"; "test-command"; "/test-command"];
1593 ["chmod"; "0o755"; "/test-command"];
1594 ["command"; "/test-command 5"]], "\nResult5\n\n");
1595 InitBasicFS, Always, TestOutput (
1596 [["upload"; "test-command"; "/test-command"];
1597 ["chmod"; "0o755"; "/test-command"];
1598 ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1599 InitBasicFS, Always, TestOutput (
1600 [["upload"; "test-command"; "/test-command"];
1601 ["chmod"; "0o755"; "/test-command"];
1602 ["command"; "/test-command 7"]], "");
1603 InitBasicFS, Always, TestOutput (
1604 [["upload"; "test-command"; "/test-command"];
1605 ["chmod"; "0o755"; "/test-command"];
1606 ["command"; "/test-command 8"]], "\n");
1607 InitBasicFS, Always, TestOutput (
1608 [["upload"; "test-command"; "/test-command"];
1609 ["chmod"; "0o755"; "/test-command"];
1610 ["command"; "/test-command 9"]], "\n\n");
1611 InitBasicFS, Always, TestOutput (
1612 [["upload"; "test-command"; "/test-command"];
1613 ["chmod"; "0o755"; "/test-command"];
1614 ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1615 InitBasicFS, Always, TestOutput (
1616 [["upload"; "test-command"; "/test-command"];
1617 ["chmod"; "0o755"; "/test-command"];
1618 ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1619 InitBasicFS, Always, TestLastFail (
1620 [["upload"; "test-command"; "/test-command"];
1621 ["chmod"; "0o755"; "/test-command"];
1622 ["command"; "/test-command"]])],
1623 "run a command from the guest filesystem",
1625 This call runs a command from the guest filesystem. The
1626 filesystem must be mounted, and must contain a compatible
1627 operating system (ie. something Linux, with the same
1628 or compatible processor architecture).
1630 The single parameter is an argv-style list of arguments.
1631 The first element is the name of the program to run.
1632 Subsequent elements are parameters. The list must be
1633 non-empty (ie. must contain a program name). Note that
1634 the command runs directly, and is I<not> invoked via
1635 the shell (see C<guestfs_sh>).
1637 The return value is anything printed to I<stdout> by
1640 If the command returns a non-zero exit status, then
1641 this function returns an error message. The error message
1642 string is the content of I<stderr> from the command.
1644 The C<$PATH> environment variable will contain at least
1645 C</usr/bin> and C</bin>. If you require a program from
1646 another location, you should provide the full path in the
1649 Shared libraries and data files required by the program
1650 must be available on filesystems which are mounted in the
1651 correct places. It is the caller's responsibility to ensure
1652 all filesystems that are needed are mounted at the right
1655 ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1656 [InitBasicFS, Always, TestOutputList (
1657 [["upload"; "test-command"; "/test-command"];
1658 ["chmod"; "0o755"; "/test-command"];
1659 ["command_lines"; "/test-command 1"]], ["Result1"]);
1660 InitBasicFS, Always, TestOutputList (
1661 [["upload"; "test-command"; "/test-command"];
1662 ["chmod"; "0o755"; "/test-command"];
1663 ["command_lines"; "/test-command 2"]], ["Result2"]);
1664 InitBasicFS, Always, TestOutputList (
1665 [["upload"; "test-command"; "/test-command"];
1666 ["chmod"; "0o755"; "/test-command"];
1667 ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1668 InitBasicFS, Always, TestOutputList (
1669 [["upload"; "test-command"; "/test-command"];
1670 ["chmod"; "0o755"; "/test-command"];
1671 ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1672 InitBasicFS, Always, TestOutputList (
1673 [["upload"; "test-command"; "/test-command"];
1674 ["chmod"; "0o755"; "/test-command"];
1675 ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1676 InitBasicFS, Always, TestOutputList (
1677 [["upload"; "test-command"; "/test-command"];
1678 ["chmod"; "0o755"; "/test-command"];
1679 ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1680 InitBasicFS, Always, TestOutputList (
1681 [["upload"; "test-command"; "/test-command"];
1682 ["chmod"; "0o755"; "/test-command"];
1683 ["command_lines"; "/test-command 7"]], []);
1684 InitBasicFS, Always, TestOutputList (
1685 [["upload"; "test-command"; "/test-command"];
1686 ["chmod"; "0o755"; "/test-command"];
1687 ["command_lines"; "/test-command 8"]], [""]);
1688 InitBasicFS, Always, TestOutputList (
1689 [["upload"; "test-command"; "/test-command"];
1690 ["chmod"; "0o755"; "/test-command"];
1691 ["command_lines"; "/test-command 9"]], ["";""]);
1692 InitBasicFS, Always, TestOutputList (
1693 [["upload"; "test-command"; "/test-command"];
1694 ["chmod"; "0o755"; "/test-command"];
1695 ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1696 InitBasicFS, Always, TestOutputList (
1697 [["upload"; "test-command"; "/test-command"];
1698 ["chmod"; "0o755"; "/test-command"];
1699 ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1700 "run a command, returning lines",
1702 This is the same as C<guestfs_command>, but splits the
1703 result into a list of lines.
1705 See also: C<guestfs_sh_lines>");
1707 ("stat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 52, [],
1708 [InitISOFS, Always, TestOutputStruct (
1709 [["stat"; "/empty"]], [CompareWithInt ("size", 0)])],
1710 "get file information",
1712 Returns file information for the given C<path>.
1714 This is the same as the C<stat(2)> system call.");
1716 ("lstat", (RStruct ("statbuf", "stat"), [Pathname "path"]), 53, [],
1717 [InitISOFS, Always, TestOutputStruct (
1718 [["lstat"; "/empty"]], [CompareWithInt ("size", 0)])],
1719 "get file information for a symbolic link",
1721 Returns file information for the given C<path>.
1723 This is the same as C<guestfs_stat> except that if C<path>
1724 is a symbolic link, then the link is stat-ed, not the file it
1727 This is the same as the C<lstat(2)> system call.");
1729 ("statvfs", (RStruct ("statbuf", "statvfs"), [Pathname "path"]), 54, [],
1730 [InitISOFS, Always, TestOutputStruct (
1731 [["statvfs"; "/"]], [CompareWithInt ("namemax", 255)])],
1732 "get file system statistics",
1734 Returns file system statistics for any mounted file system.
1735 C<path> should be a file or directory in the mounted file system
1736 (typically it is the mount point itself, but it doesn't need to be).
1738 This is the same as the C<statvfs(2)> system call.");
1740 ("tune2fs_l", (RHashtable "superblock", [Device "device"]), 55, [],
1742 "get ext2/ext3/ext4 superblock details",
1744 This returns the contents of the ext2, ext3 or ext4 filesystem
1745 superblock on C<device>.
1747 It is the same as running C<tune2fs -l device>. See L<tune2fs(8)>
1748 manpage for more details. The list of fields returned isn't
1749 clearly defined, and depends on both the version of C<tune2fs>
1750 that libguestfs was built against, and the filesystem itself.");
1752 ("blockdev_setro", (RErr, [Device "device"]), 56, [],
1753 [InitEmpty, Always, TestOutputTrue (
1754 [["blockdev_setro"; "/dev/sda"];
1755 ["blockdev_getro"; "/dev/sda"]])],
1756 "set block device to read-only",
1758 Sets the block device named C<device> to read-only.
1760 This uses the L<blockdev(8)> command.");
1762 ("blockdev_setrw", (RErr, [Device "device"]), 57, [],
1763 [InitEmpty, Always, TestOutputFalse (
1764 [["blockdev_setrw"; "/dev/sda"];
1765 ["blockdev_getro"; "/dev/sda"]])],
1766 "set block device to read-write",
1768 Sets the block device named C<device> to read-write.
1770 This uses the L<blockdev(8)> command.");
1772 ("blockdev_getro", (RBool "ro", [Device "device"]), 58, [],
1773 [InitEmpty, Always, TestOutputTrue (
1774 [["blockdev_setro"; "/dev/sda"];
1775 ["blockdev_getro"; "/dev/sda"]])],
1776 "is block device set to read-only",
1778 Returns a boolean indicating if the block device is read-only
1779 (true if read-only, false if not).
1781 This uses the L<blockdev(8)> command.");
1783 ("blockdev_getss", (RInt "sectorsize", [Device "device"]), 59, [],
1784 [InitEmpty, Always, TestOutputInt (
1785 [["blockdev_getss"; "/dev/sda"]], 512)],
1786 "get sectorsize of block device",
1788 This returns the size of sectors on a block device.
1789 Usually 512, but can be larger for modern devices.
1791 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1794 This uses the L<blockdev(8)> command.");
1796 ("blockdev_getbsz", (RInt "blocksize", [Device "device"]), 60, [],
1797 [InitEmpty, Always, TestOutputInt (
1798 [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1799 "get blocksize of block device",
1801 This returns the block size of a device.
1803 (Note this is different from both I<size in blocks> and
1804 I<filesystem block size>).
1806 This uses the L<blockdev(8)> command.");
1808 ("blockdev_setbsz", (RErr, [Device "device"; Int "blocksize"]), 61, [],
1810 "set blocksize of block device",
1812 This sets the block size of a device.
1814 (Note this is different from both I<size in blocks> and
1815 I<filesystem block size>).
1817 This uses the L<blockdev(8)> command.");
1819 ("blockdev_getsz", (RInt64 "sizeinsectors", [Device "device"]), 62, [],
1820 [InitEmpty, Always, TestOutputInt (
1821 [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1822 "get total size of device in 512-byte sectors",
1824 This returns the size of the device in units of 512-byte sectors
1825 (even if the sectorsize isn't 512 bytes ... weird).
1827 See also C<guestfs_blockdev_getss> for the real sector size of
1828 the device, and C<guestfs_blockdev_getsize64> for the more
1829 useful I<size in bytes>.
1831 This uses the L<blockdev(8)> command.");
1833 ("blockdev_getsize64", (RInt64 "sizeinbytes", [Device "device"]), 63, [],
1834 [InitEmpty, Always, TestOutputInt (
1835 [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1836 "get total size of device in bytes",
1838 This returns the size of the device in bytes.
1840 See also C<guestfs_blockdev_getsz>.
1842 This uses the L<blockdev(8)> command.");
1844 ("blockdev_flushbufs", (RErr, [Device "device"]), 64, [],
1845 [InitEmpty, Always, TestRun
1846 [["blockdev_flushbufs"; "/dev/sda"]]],
1847 "flush device buffers",
1849 This tells the kernel to flush internal buffers associated
1852 This uses the L<blockdev(8)> command.");
1854 ("blockdev_rereadpt", (RErr, [Device "device"]), 65, [],
1855 [InitEmpty, Always, TestRun
1856 [["blockdev_rereadpt"; "/dev/sda"]]],
1857 "reread partition table",
1859 Reread the partition table on C<device>.
1861 This uses the L<blockdev(8)> command.");
1863 ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [],
1864 [InitBasicFS, Always, TestOutput (
1865 (* Pick a file from cwd which isn't likely to change. *)
1866 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1867 ["checksum"; "md5"; "/COPYING.LIB"]],
1868 Digest.to_hex (Digest.file "COPYING.LIB"))],
1869 "upload a file from the local machine",
1871 Upload local file C<filename> to C<remotefilename> on the
1874 C<filename> can also be a named pipe.
1876 See also C<guestfs_download>.");
1878 ("download", (RErr, [Dev_or_Path "remotefilename"; FileOut "filename"]), 67, [],
1879 [InitBasicFS, Always, TestOutput (
1880 (* Pick a file from cwd which isn't likely to change. *)
1881 [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1882 ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1883 ["upload"; "testdownload.tmp"; "/upload"];
1884 ["checksum"; "md5"; "/upload"]],
1885 Digest.to_hex (Digest.file "COPYING.LIB"))],
1886 "download a file to the local machine",
1888 Download file C<remotefilename> and save it as C<filename>
1889 on the local machine.
1891 C<filename> can also be a named pipe.
1893 See also C<guestfs_upload>, C<guestfs_cat>.");
1895 ("checksum", (RString "checksum", [String "csumtype"; Pathname "path"]), 68, [],
1896 [InitISOFS, Always, TestOutput (
1897 [["checksum"; "crc"; "/known-3"]], "2891671662");
1898 InitISOFS, Always, TestLastFail (
1899 [["checksum"; "crc"; "/notexists"]]);
1900 InitISOFS, Always, TestOutput (
1901 [["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c");
1902 InitISOFS, Always, TestOutput (
1903 [["checksum"; "sha1"; "/known-3"]], "b7ebccc3ee418311091c3eda0a45b83c0a770f15");
1904 InitISOFS, Always, TestOutput (
1905 [["checksum"; "sha224"; "/known-3"]], "d2cd1774b28f3659c14116be0a6dc2bb5c4b350ce9cd5defac707741");
1906 InitISOFS, Always, TestOutput (
1907 [["checksum"; "sha256"; "/known-3"]], "75bb71b90cd20cb13f86d2bea8dad63ac7194e7517c3b52b8d06ff52d3487d30");
1908 InitISOFS, Always, TestOutput (
1909 [["checksum"; "sha384"; "/known-3"]], "5fa7883430f357b5d7b7271d3a1d2872b51d73cba72731de6863d3dea55f30646af2799bef44d5ea776a5ec7941ac640");
1910 InitISOFS, Always, TestOutput (
1911 [["checksum"; "sha512"; "/known-3"]], "2794062c328c6b216dca90443b7f7134c5f40e56bd0ed7853123275a09982a6f992e6ca682f9d2fba34a4c5e870d8fe077694ff831e3032a004ee077e00603f6")],
1912 "compute MD5, SHAx or CRC checksum of file",
1914 This call computes the MD5, SHAx or CRC checksum of the
1917 The type of checksum to compute is given by the C<csumtype>
1918 parameter which must have one of the following values:
1924 Compute the cyclic redundancy check (CRC) specified by POSIX
1925 for the C<cksum> command.
1929 Compute the MD5 hash (using the C<md5sum> program).
1933 Compute the SHA1 hash (using the C<sha1sum> program).
1937 Compute the SHA224 hash (using the C<sha224sum> program).
1941 Compute the SHA256 hash (using the C<sha256sum> program).
1945 Compute the SHA384 hash (using the C<sha384sum> program).
1949 Compute the SHA512 hash (using the C<sha512sum> program).
1953 The checksum is returned as a printable string.");
1955 ("tar_in", (RErr, [FileIn "tarfile"; String "directory"]), 69, [],
1956 [InitBasicFS, Always, TestOutput (
1957 [["tar_in"; "../images/helloworld.tar"; "/"];
1958 ["cat"; "/hello"]], "hello\n")],
1959 "unpack tarfile to directory",
1961 This command uploads and unpacks local file C<tarfile> (an
1962 I<uncompressed> tar file) into C<directory>.
1964 To upload a compressed tarball, use C<guestfs_tgz_in>.");
1966 ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
1968 "pack directory into tarfile",
1970 This command packs the contents of C<directory> and downloads
1971 it to local file C<tarfile>.
1973 To download a compressed tarball, use C<guestfs_tgz_out>.");
1975 ("tgz_in", (RErr, [FileIn "tarball"; String "directory"]), 71, [],
1976 [InitBasicFS, Always, TestOutput (
1977 [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
1978 ["cat"; "/hello"]], "hello\n")],
1979 "unpack compressed tarball to directory",
1981 This command uploads and unpacks local file C<tarball> (a
1982 I<gzip compressed> tar file) into C<directory>.
1984 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
1986 ("tgz_out", (RErr, [Pathname "directory"; FileOut "tarball"]), 72, [],
1988 "pack directory into compressed tarball",
1990 This command packs the contents of C<directory> and downloads
1991 it to local file C<tarball>.
1993 To download an uncompressed tarball, use C<guestfs_tar_out>.");
1995 ("mount_ro", (RErr, [Device "device"; String "mountpoint"]), 73, [],
1996 [InitBasicFS, Always, TestLastFail (
1998 ["mount_ro"; "/dev/sda1"; "/"];
1999 ["touch"; "/new"]]);
2000 InitBasicFS, Always, TestOutput (
2001 [["write_file"; "/new"; "data"; "0"];
2003 ["mount_ro"; "/dev/sda1"; "/"];
2004 ["cat"; "/new"]], "data")],
2005 "mount a guest disk, read-only",
2007 This is the same as the C<guestfs_mount> command, but it
2008 mounts the filesystem with the read-only (I<-o ro>) flag.");
2010 ("mount_options", (RErr, [String "options"; Device "device"; String "mountpoint"]), 74, [],
2012 "mount a guest disk with mount options",
2014 This is the same as the C<guestfs_mount> command, but it
2015 allows you to set the mount options as for the
2016 L<mount(8)> I<-o> flag.");
2018 ("mount_vfs", (RErr, [String "options"; String "vfstype"; Device "device"; String "mountpoint"]), 75, [],
2020 "mount a guest disk with mount options and vfstype",
2022 This is the same as the C<guestfs_mount> command, but it
2023 allows you to set both the mount options and the vfstype
2024 as for the L<mount(8)> I<-o> and I<-t> flags.");
2026 ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
2028 "debugging and internals",
2030 The C<guestfs_debug> command exposes some internals of
2031 C<guestfsd> (the guestfs daemon) that runs inside the
2034 There is no comprehensive help for this command. You have
2035 to look at the file C<daemon/debug.c> in the libguestfs source
2036 to find out what you can do.");
2038 ("lvremove", (RErr, [Device "device"]), 77, [],
2039 [InitEmpty, Always, TestOutputList (
2040 [["part_disk"; "/dev/sda"; "mbr"];
2041 ["pvcreate"; "/dev/sda1"];
2042 ["vgcreate"; "VG"; "/dev/sda1"];
2043 ["lvcreate"; "LV1"; "VG"; "50"];
2044 ["lvcreate"; "LV2"; "VG"; "50"];
2045 ["lvremove"; "/dev/VG/LV1"];
2046 ["lvs"]], ["/dev/VG/LV2"]);
2047 InitEmpty, Always, TestOutputList (
2048 [["part_disk"; "/dev/sda"; "mbr"];
2049 ["pvcreate"; "/dev/sda1"];
2050 ["vgcreate"; "VG"; "/dev/sda1"];
2051 ["lvcreate"; "LV1"; "VG"; "50"];
2052 ["lvcreate"; "LV2"; "VG"; "50"];
2053 ["lvremove"; "/dev/VG"];
2055 InitEmpty, Always, TestOutputList (
2056 [["part_disk"; "/dev/sda"; "mbr"];
2057 ["pvcreate"; "/dev/sda1"];
2058 ["vgcreate"; "VG"; "/dev/sda1"];
2059 ["lvcreate"; "LV1"; "VG"; "50"];
2060 ["lvcreate"; "LV2"; "VG"; "50"];
2061 ["lvremove"; "/dev/VG"];
2063 "remove an LVM logical volume",
2065 Remove an LVM logical volume C<device>, where C<device> is
2066 the path to the LV, such as C</dev/VG/LV>.
2068 You can also remove all LVs in a volume group by specifying
2069 the VG name, C</dev/VG>.");
2071 ("vgremove", (RErr, [String "vgname"]), 78, [],
2072 [InitEmpty, Always, TestOutputList (
2073 [["part_disk"; "/dev/sda"; "mbr"];
2074 ["pvcreate"; "/dev/sda1"];
2075 ["vgcreate"; "VG"; "/dev/sda1"];
2076 ["lvcreate"; "LV1"; "VG"; "50"];
2077 ["lvcreate"; "LV2"; "VG"; "50"];
2080 InitEmpty, Always, TestOutputList (
2081 [["part_disk"; "/dev/sda"; "mbr"];
2082 ["pvcreate"; "/dev/sda1"];
2083 ["vgcreate"; "VG"; "/dev/sda1"];
2084 ["lvcreate"; "LV1"; "VG"; "50"];
2085 ["lvcreate"; "LV2"; "VG"; "50"];
2088 "remove an LVM volume group",
2090 Remove an LVM volume group C<vgname>, (for example C<VG>).
2092 This also forcibly removes all logical volumes in the volume
2095 ("pvremove", (RErr, [Device "device"]), 79, [],
2096 [InitEmpty, Always, TestOutputListOfDevices (
2097 [["part_disk"; "/dev/sda"; "mbr"];
2098 ["pvcreate"; "/dev/sda1"];
2099 ["vgcreate"; "VG"; "/dev/sda1"];
2100 ["lvcreate"; "LV1"; "VG"; "50"];
2101 ["lvcreate"; "LV2"; "VG"; "50"];
2103 ["pvremove"; "/dev/sda1"];
2105 InitEmpty, Always, TestOutputListOfDevices (
2106 [["part_disk"; "/dev/sda"; "mbr"];
2107 ["pvcreate"; "/dev/sda1"];
2108 ["vgcreate"; "VG"; "/dev/sda1"];
2109 ["lvcreate"; "LV1"; "VG"; "50"];
2110 ["lvcreate"; "LV2"; "VG"; "50"];
2112 ["pvremove"; "/dev/sda1"];
2114 InitEmpty, Always, TestOutputListOfDevices (
2115 [["part_disk"; "/dev/sda"; "mbr"];
2116 ["pvcreate"; "/dev/sda1"];
2117 ["vgcreate"; "VG"; "/dev/sda1"];
2118 ["lvcreate"; "LV1"; "VG"; "50"];
2119 ["lvcreate"; "LV2"; "VG"; "50"];
2121 ["pvremove"; "/dev/sda1"];
2123 "remove an LVM physical volume",
2125 This wipes a physical volume C<device> so that LVM will no longer
2128 The implementation uses the C<pvremove> command which refuses to
2129 wipe physical volumes that contain any volume groups, so you have
2130 to remove those first.");
2132 ("set_e2label", (RErr, [Device "device"; String "label"]), 80, [],
2133 [InitBasicFS, Always, TestOutput (
2134 [["set_e2label"; "/dev/sda1"; "testlabel"];
2135 ["get_e2label"; "/dev/sda1"]], "testlabel")],
2136 "set the ext2/3/4 filesystem label",
2138 This sets the ext2/3/4 filesystem label of the filesystem on
2139 C<device> to C<label>. Filesystem labels are limited to
2142 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
2143 to return the existing label on a filesystem.");
2145 ("get_e2label", (RString "label", [Device "device"]), 81, [],
2147 "get the ext2/3/4 filesystem label",
2149 This returns the ext2/3/4 filesystem label of the filesystem on
2152 ("set_e2uuid", (RErr, [Device "device"; String "uuid"]), 82, [],
2153 (let uuid = uuidgen () in
2154 [InitBasicFS, Always, TestOutput (
2155 [["set_e2uuid"; "/dev/sda1"; uuid];
2156 ["get_e2uuid"; "/dev/sda1"]], uuid);
2157 InitBasicFS, Always, TestOutput (
2158 [["set_e2uuid"; "/dev/sda1"; "clear"];
2159 ["get_e2uuid"; "/dev/sda1"]], "");
2160 (* We can't predict what UUIDs will be, so just check the commands run. *)
2161 InitBasicFS, Always, TestRun (
2162 [["set_e2uuid"; "/dev/sda1"; "random"]]);
2163 InitBasicFS, Always, TestRun (
2164 [["set_e2uuid"; "/dev/sda1"; "time"]])]),
2165 "set the ext2/3/4 filesystem UUID",
2167 This sets the ext2/3/4 filesystem UUID of the filesystem on
2168 C<device> to C<uuid>. The format of the UUID and alternatives
2169 such as C<clear>, C<random> and C<time> are described in the
2170 L<tune2fs(8)> manpage.
2172 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
2173 to return the existing UUID of a filesystem.");
2175 ("get_e2uuid", (RString "uuid", [Device "device"]), 83, [],
2177 "get the ext2/3/4 filesystem UUID",
2179 This returns the ext2/3/4 filesystem UUID of the filesystem on
2182 ("fsck", (RInt "status", [String "fstype"; Device "device"]), 84, [],
2183 [InitBasicFS, Always, TestOutputInt (
2184 [["umount"; "/dev/sda1"];
2185 ["fsck"; "ext2"; "/dev/sda1"]], 0);
2186 InitBasicFS, Always, TestOutputInt (
2187 [["umount"; "/dev/sda1"];
2188 ["zero"; "/dev/sda1"];
2189 ["fsck"; "ext2"; "/dev/sda1"]], 8)],
2190 "run the filesystem checker",
2192 This runs the filesystem checker (fsck) on C<device> which
2193 should have filesystem type C<fstype>.
2195 The returned integer is the status. See L<fsck(8)> for the
2196 list of status codes from C<fsck>.
2204 Multiple status codes can be summed together.
2208 A non-zero return code can mean \"success\", for example if
2209 errors have been corrected on the filesystem.
2213 Checking or repairing NTFS volumes is not supported
2218 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
2220 ("zero", (RErr, [Device "device"]), 85, [],
2221 [InitBasicFS, Always, TestOutput (
2222 [["umount"; "/dev/sda1"];
2223 ["zero"; "/dev/sda1"];
2224 ["file"; "/dev/sda1"]], "data")],
2225 "write zeroes to the device",
2227 This command writes zeroes over the first few blocks of C<device>.
2229 How many blocks are zeroed isn't specified (but it's I<not> enough
2230 to securely wipe the device). It should be sufficient to remove
2231 any partition tables, filesystem superblocks and so on.
2233 See also: C<guestfs_scrub_device>.");
2235 ("grub_install", (RErr, [Pathname "root"; Device "device"]), 86, [],
2236 (* Test disabled because grub-install incompatible with virtio-blk driver.
2237 * See also: https://bugzilla.redhat.com/show_bug.cgi?id=479760
2239 [InitBasicFS, Disabled, TestOutputTrue (
2240 [["grub_install"; "/"; "/dev/sda1"];
2241 ["is_dir"; "/boot"]])],
2244 This command installs GRUB (the Grand Unified Bootloader) on
2245 C<device>, with the root directory being C<root>.");
2247 ("cp", (RErr, [Pathname "src"; Pathname "dest"]), 87, [],
2248 [InitBasicFS, Always, TestOutput (
2249 [["write_file"; "/old"; "file content"; "0"];
2250 ["cp"; "/old"; "/new"];
2251 ["cat"; "/new"]], "file content");
2252 InitBasicFS, Always, TestOutputTrue (
2253 [["write_file"; "/old"; "file content"; "0"];
2254 ["cp"; "/old"; "/new"];
2255 ["is_file"; "/old"]]);
2256 InitBasicFS, Always, TestOutput (
2257 [["write_file"; "/old"; "file content"; "0"];
2259 ["cp"; "/old"; "/dir/new"];
2260 ["cat"; "/dir/new"]], "file content")],
2263 This copies a file from C<src> to C<dest> where C<dest> is
2264 either a destination filename or destination directory.");
2266 ("cp_a", (RErr, [Pathname "src"; Pathname "dest"]), 88, [],
2267 [InitBasicFS, Always, TestOutput (
2268 [["mkdir"; "/olddir"];
2269 ["mkdir"; "/newdir"];
2270 ["write_file"; "/olddir/file"; "file content"; "0"];
2271 ["cp_a"; "/olddir"; "/newdir"];
2272 ["cat"; "/newdir/olddir/file"]], "file content")],
2273 "copy a file or directory recursively",
2275 This copies a file or directory from C<src> to C<dest>
2276 recursively using the C<cp -a> command.");
2278 ("mv", (RErr, [Pathname "src"; Pathname "dest"]), 89, [],
2279 [InitBasicFS, Always, TestOutput (
2280 [["write_file"; "/old"; "file content"; "0"];
2281 ["mv"; "/old"; "/new"];
2282 ["cat"; "/new"]], "file content");
2283 InitBasicFS, Always, TestOutputFalse (
2284 [["write_file"; "/old"; "file content"; "0"];
2285 ["mv"; "/old"; "/new"];
2286 ["is_file"; "/old"]])],
2289 This moves a file from C<src> to C<dest> where C<dest> is
2290 either a destination filename or destination directory.");
2292 ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2293 [InitEmpty, Always, TestRun (
2294 [["drop_caches"; "3"]])],
2295 "drop kernel page cache, dentries and inodes",
2297 This instructs the guest kernel to drop its page cache,
2298 and/or dentries and inode caches. The parameter C<whattodrop>
2299 tells the kernel what precisely to drop, see
2300 L<http://linux-mm.org/Drop_Caches>
2302 Setting C<whattodrop> to 3 should drop everything.
2304 This automatically calls L<sync(2)> before the operation,
2305 so that the maximum guest memory is freed.");
2307 ("dmesg", (RString "kmsgs", []), 91, [],
2308 [InitEmpty, Always, TestRun (
2310 "return kernel messages",
2312 This returns the kernel messages (C<dmesg> output) from
2313 the guest kernel. This is sometimes useful for extended
2314 debugging of problems.
2316 Another way to get the same information is to enable
2317 verbose messages with C<guestfs_set_verbose> or by setting
2318 the environment variable C<LIBGUESTFS_DEBUG=1> before
2319 running the program.");
2321 ("ping_daemon", (RErr, []), 92, [],
2322 [InitEmpty, Always, TestRun (
2323 [["ping_daemon"]])],
2324 "ping the guest daemon",
2326 This is a test probe into the guestfs daemon running inside
2327 the qemu subprocess. Calling this function checks that the
2328 daemon responds to the ping message, without affecting the daemon
2329 or attached block device(s) in any other way.");
2331 ("equal", (RBool "equality", [Pathname "file1"; Pathname "file2"]), 93, [],
2332 [InitBasicFS, Always, TestOutputTrue (
2333 [["write_file"; "/file1"; "contents of a file"; "0"];
2334 ["cp"; "/file1"; "/file2"];
2335 ["equal"; "/file1"; "/file2"]]);
2336 InitBasicFS, Always, TestOutputFalse (
2337 [["write_file"; "/file1"; "contents of a file"; "0"];
2338 ["write_file"; "/file2"; "contents of another file"; "0"];
2339 ["equal"; "/file1"; "/file2"]]);
2340 InitBasicFS, Always, TestLastFail (
2341 [["equal"; "/file1"; "/file2"]])],
2342 "test if two files have equal contents",
2344 This compares the two files C<file1> and C<file2> and returns
2345 true if their content is exactly equal, or false otherwise.
2347 The external L<cmp(1)> program is used for the comparison.");
2349 ("strings", (RStringList "stringsout", [Pathname "path"]), 94, [ProtocolLimitWarning],
2350 [InitISOFS, Always, TestOutputList (
2351 [["strings"; "/known-5"]], ["abcdefghi"; "jklmnopqr"]);
2352 InitISOFS, Always, TestOutputList (
2353 [["strings"; "/empty"]], [])],
2354 "print the printable strings in a file",
2356 This runs the L<strings(1)> command on a file and returns
2357 the list of printable strings found.");
2359 ("strings_e", (RStringList "stringsout", [String "encoding"; Pathname "path"]), 95, [ProtocolLimitWarning],
2360 [InitISOFS, Always, TestOutputList (
2361 [["strings_e"; "b"; "/known-5"]], []);
2362 InitBasicFS, Disabled, TestOutputList (
2363 [["write_file"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"; "24"];
2364 ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2365 "print the printable strings in a file",
2367 This is like the C<guestfs_strings> command, but allows you to
2368 specify the encoding.
2370 See the L<strings(1)> manpage for the full list of encodings.
2372 Commonly useful encodings are C<l> (lower case L) which will
2373 show strings inside Windows/x86 files.
2375 The returned strings are transcoded to UTF-8.");
2377 ("hexdump", (RString "dump", [Pathname "path"]), 96, [ProtocolLimitWarning],
2378 [InitISOFS, Always, TestOutput (
2379 [["hexdump"; "/known-4"]], "00000000 61 62 63 0a 64 65 66 0a 67 68 69 |abc.def.ghi|\n0000000b\n");
2380 (* Test for RHBZ#501888c2 regression which caused large hexdump
2381 * commands to segfault.
2383 InitISOFS, Always, TestRun (
2384 [["hexdump"; "/100krandom"]])],
2385 "dump a file in hexadecimal",
2387 This runs C<hexdump -C> on the given C<path>. The result is
2388 the human-readable, canonical hex dump of the file.");
2390 ("zerofree", (RErr, [Device "device"]), 97, [],
2391 [InitNone, Always, TestOutput (
2392 [["part_disk"; "/dev/sda"; "mbr"];
2393 ["mkfs"; "ext3"; "/dev/sda1"];
2394 ["mount"; "/dev/sda1"; "/"];
2395 ["write_file"; "/new"; "test file"; "0"];
2396 ["umount"; "/dev/sda1"];
2397 ["zerofree"; "/dev/sda1"];
2398 ["mount"; "/dev/sda1"; "/"];
2399 ["cat"; "/new"]], "test file")],
2400 "zero unused inodes and disk blocks on ext2/3 filesystem",
2402 This runs the I<zerofree> program on C<device>. This program
2403 claims to zero unused inodes and disk blocks on an ext2/3
2404 filesystem, thus making it possible to compress the filesystem
2407 You should B<not> run this program if the filesystem is
2410 It is possible that using this program can damage the filesystem
2411 or data on the filesystem.");
2413 ("pvresize", (RErr, [Device "device"]), 98, [],
2415 "resize an LVM physical volume",
2417 This resizes (expands or shrinks) an existing LVM physical
2418 volume to match the new size of the underlying device.");
2420 ("sfdisk_N", (RErr, [Device "device"; Int "partnum";
2421 Int "cyls"; Int "heads"; Int "sectors";
2422 String "line"]), 99, [DangerWillRobinson],
2424 "modify a single partition on a block device",
2426 This runs L<sfdisk(8)> option to modify just the single
2427 partition C<n> (note: C<n> counts from 1).
2429 For other parameters, see C<guestfs_sfdisk>. You should usually
2430 pass C<0> for the cyls/heads/sectors parameters.
2432 See also: C<guestfs_part_add>");
2434 ("sfdisk_l", (RString "partitions", [Device "device"]), 100, [],
2436 "display the partition table",
2438 This displays the partition table on C<device>, in the
2439 human-readable output of the L<sfdisk(8)> command. It is
2440 not intended to be parsed.
2442 See also: C<guestfs_part_list>");
2444 ("sfdisk_kernel_geometry", (RString "partitions", [Device "device"]), 101, [],
2446 "display the kernel geometry",
2448 This displays the kernel's idea of the geometry of C<device>.
2450 The result is in human-readable format, and not designed to
2453 ("sfdisk_disk_geometry", (RString "partitions", [Device "device"]), 102, [],
2455 "display the disk geometry from the partition table",
2457 This displays the disk geometry of C<device> read from the
2458 partition table. Especially in the case where the underlying
2459 block device has been resized, this can be different from the
2460 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2462 The result is in human-readable format, and not designed to
2465 ("vg_activate_all", (RErr, [Bool "activate"]), 103, [],
2467 "activate or deactivate all volume groups",
2469 This command activates or (if C<activate> is false) deactivates
2470 all logical volumes in all volume groups.
2471 If activated, then they are made known to the
2472 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2473 then those devices disappear.
2475 This command is the same as running C<vgchange -a y|n>");
2477 ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [],
2479 "activate or deactivate some volume groups",
2481 This command activates or (if C<activate> is false) deactivates
2482 all logical volumes in the listed volume groups C<volgroups>.
2483 If activated, then they are made known to the
2484 kernel, ie. they appear as C</dev/mapper> devices. If deactivated,
2485 then those devices disappear.
2487 This command is the same as running C<vgchange -a y|n volgroups...>
2489 Note that if C<volgroups> is an empty list then B<all> volume groups
2490 are activated or deactivated.");
2492 ("lvresize", (RErr, [Device "device"; Int "mbytes"]), 105, [],
2493 [InitNone, Always, TestOutput (
2494 [["part_disk"; "/dev/sda"; "mbr"];
2495 ["pvcreate"; "/dev/sda1"];
2496 ["vgcreate"; "VG"; "/dev/sda1"];
2497 ["lvcreate"; "LV"; "VG"; "10"];
2498 ["mkfs"; "ext2"; "/dev/VG/LV"];
2499 ["mount"; "/dev/VG/LV"; "/"];
2500 ["write_file"; "/new"; "test content"; "0"];
2502 ["lvresize"; "/dev/VG/LV"; "20"];
2503 ["e2fsck_f"; "/dev/VG/LV"];
2504 ["resize2fs"; "/dev/VG/LV"];
2505 ["mount"; "/dev/VG/LV"; "/"];
2506 ["cat"; "/new"]], "test content")],
2507 "resize an LVM logical volume",
2509 This resizes (expands or shrinks) an existing LVM logical
2510 volume to C<mbytes>. When reducing, data in the reduced part
2513 ("resize2fs", (RErr, [Device "device"]), 106, [],
2514 [], (* lvresize tests this *)
2515 "resize an ext2/ext3 filesystem",
2517 This resizes an ext2 or ext3 filesystem to match the size of
2518 the underlying device.
2520 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2521 on the C<device> before calling this command. For unknown reasons
2522 C<resize2fs> sometimes gives an error about this and sometimes not.
2523 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2524 calling this function.");
2526 ("find", (RStringList "names", [Pathname "directory"]), 107, [ProtocolLimitWarning],
2527 [InitBasicFS, Always, TestOutputList (
2528 [["find"; "/"]], ["lost+found"]);
2529 InitBasicFS, Always, TestOutputList (
2533 ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2534 InitBasicFS, Always, TestOutputList (
2535 [["mkdir_p"; "/a/b/c"];
2536 ["touch"; "/a/b/c/d"];
2537 ["find"; "/a/b/"]], ["c"; "c/d"])],
2538 "find all files and directories",
2540 This command lists out all files and directories, recursively,
2541 starting at C<directory>. It is essentially equivalent to
2542 running the shell command C<find directory -print> but some
2543 post-processing happens on the output, described below.
2545 This returns a list of strings I<without any prefix>. Thus
2546 if the directory structure was:
2552 then the returned list from C<guestfs_find> C</tmp> would be
2560 If C<directory> is not a directory, then this command returns
2563 The returned list is sorted.
2565 See also C<guestfs_find0>.");
2567 ("e2fsck_f", (RErr, [Device "device"]), 108, [],
2568 [], (* lvresize tests this *)
2569 "check an ext2/ext3 filesystem",
2571 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2572 filesystem checker on C<device>, noninteractively (C<-p>),
2573 even if the filesystem appears to be clean (C<-f>).
2575 This command is only needed because of C<guestfs_resize2fs>
2576 (q.v.). Normally you should use C<guestfs_fsck>.");
2578 ("sleep", (RErr, [Int "secs"]), 109, [],
2579 [InitNone, Always, TestRun (
2581 "sleep for some seconds",
2583 Sleep for C<secs> seconds.");
2585 ("ntfs_3g_probe", (RInt "status", [Bool "rw"; Device "device"]), 110, [],
2586 [InitNone, Always, TestOutputInt (
2587 [["part_disk"; "/dev/sda"; "mbr"];
2588 ["mkfs"; "ntfs"; "/dev/sda1"];
2589 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 0);
2590 InitNone, Always, TestOutputInt (
2591 [["part_disk"; "/dev/sda"; "mbr"];
2592 ["mkfs"; "ext2"; "/dev/sda1"];
2593 ["ntfs_3g_probe"; "true"; "/dev/sda1"]], 12)],
2594 "probe NTFS volume",
2596 This command runs the L<ntfs-3g.probe(8)> command which probes
2597 an NTFS C<device> for mountability. (Not all NTFS volumes can
2598 be mounted read-write, and some cannot be mounted at all).
2600 C<rw> is a boolean flag. Set it to true if you want to test
2601 if the volume can be mounted read-write. Set it to false if
2602 you want to test if the volume can be mounted read-only.
2604 The return value is an integer which C<0> if the operation
2605 would succeed, or some non-zero value documented in the
2606 L<ntfs-3g.probe(8)> manual page.");
2608 ("sh", (RString "output", [String "command"]), 111, [],
2609 [], (* XXX needs tests *)
2610 "run a command via the shell",
2612 This call runs a command from the guest filesystem via the
2615 This is like C<guestfs_command>, but passes the command to:
2617 /bin/sh -c \"command\"
2619 Depending on the guest's shell, this usually results in
2620 wildcards being expanded, shell expressions being interpolated
2623 All the provisos about C<guestfs_command> apply to this call.");
2625 ("sh_lines", (RStringList "lines", [String "command"]), 112, [],
2626 [], (* XXX needs tests *)
2627 "run a command via the shell returning lines",
2629 This is the same as C<guestfs_sh>, but splits the result
2630 into a list of lines.
2632 See also: C<guestfs_command_lines>");
2634 ("glob_expand", (RStringList "paths", [Pathname "pattern"]), 113, [],
2635 (* Use Pathname here, and hence ABS_PATH (pattern,... in generated
2636 * code in stubs.c, since all valid glob patterns must start with "/".
2637 * There is no concept of "cwd" in libguestfs, hence no "."-relative names.
2639 [InitBasicFS, Always, TestOutputList (
2640 [["mkdir_p"; "/a/b/c"];
2641 ["touch"; "/a/b/c/d"];
2642 ["touch"; "/a/b/c/e"];
2643 ["glob_expand"; "/a/b/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2644 InitBasicFS, Always, TestOutputList (
2645 [["mkdir_p"; "/a/b/c"];
2646 ["touch"; "/a/b/c/d"];
2647 ["touch"; "/a/b/c/e"];
2648 ["glob_expand"; "/a/*/c/*"]], ["/a/b/c/d"; "/a/b/c/e"]);
2649 InitBasicFS, Always, TestOutputList (
2650 [["mkdir_p"; "/a/b/c"];
2651 ["touch"; "/a/b/c/d"];
2652 ["touch"; "/a/b/c/e"];
2653 ["glob_expand"; "/a/*/x/*"]], [])],
2654 "expand a wildcard path",
2656 This command searches for all the pathnames matching
2657 C<pattern> according to the wildcard expansion rules
2660 If no paths match, then this returns an empty list
2661 (note: not an error).
2663 It is just a wrapper around the C L<glob(3)> function
2664 with flags C<GLOB_MARK|GLOB_BRACE>.
2665 See that manual page for more details.");
2667 ("scrub_device", (RErr, [Device "device"]), 114, [DangerWillRobinson],
2668 [InitNone, Always, TestRun ( (* use /dev/sdc because it's smaller *)
2669 [["scrub_device"; "/dev/sdc"]])],
2670 "scrub (securely wipe) a device",
2672 This command writes patterns over C<device> to make data retrieval
2675 It is an interface to the L<scrub(1)> program. See that
2676 manual page for more details.");
2678 ("scrub_file", (RErr, [Pathname "file"]), 115, [],
2679 [InitBasicFS, Always, TestRun (
2680 [["write_file"; "/file"; "content"; "0"];
2681 ["scrub_file"; "/file"]])],
2682 "scrub (securely wipe) a file",
2684 This command writes patterns over a file to make data retrieval
2687 The file is I<removed> after scrubbing.
2689 It is an interface to the L<scrub(1)> program. See that
2690 manual page for more details.");
2692 ("scrub_freespace", (RErr, [Pathname "dir"]), 116, [],
2693 [], (* XXX needs testing *)
2694 "scrub (securely wipe) free space",
2696 This command creates the directory C<dir> and then fills it
2697 with files until the filesystem is full, and scrubs the files
2698 as for C<guestfs_scrub_file>, and deletes them.
2699 The intention is to scrub any free space on the partition
2702 It is an interface to the L<scrub(1)> program. See that
2703 manual page for more details.");
2705 ("mkdtemp", (RString "dir", [Pathname "template"]), 117, [],
2706 [InitBasicFS, Always, TestRun (
2708 ["mkdtemp"; "/tmp/tmpXXXXXX"]])],
2709 "create a temporary directory",
2711 This command creates a temporary directory. The
2712 C<template> parameter should be a full pathname for the
2713 temporary directory name with the final six characters being
2716 For example: \"/tmp/myprogXXXXXX\" or \"/Temp/myprogXXXXXX\",
2717 the second one being suitable for Windows filesystems.
2719 The name of the temporary directory that was created
2722 The temporary directory is created with mode 0700
2723 and is owned by root.
2725 The caller is responsible for deleting the temporary
2726 directory and its contents after use.
2728 See also: L<mkdtemp(3)>");
2730 ("wc_l", (RInt "lines", [Pathname "path"]), 118, [],
2731 [InitISOFS, Always, TestOutputInt (
2732 [["wc_l"; "/10klines"]], 10000)],
2733 "count lines in a file",
2735 This command counts the lines in a file, using the
2736 C<wc -l> external command.");
2738 ("wc_w", (RInt "words", [Pathname "path"]), 119, [],
2739 [InitISOFS, Always, TestOutputInt (
2740 [["wc_w"; "/10klines"]], 10000)],
2741 "count words in a file",
2743 This command counts the words in a file, using the
2744 C<wc -w> external command.");
2746 ("wc_c", (RInt "chars", [Pathname "path"]), 120, [],
2747 [InitISOFS, Always, TestOutputInt (
2748 [["wc_c"; "/100kallspaces"]], 102400)],
2749 "count characters in a file",
2751 This command counts the characters in a file, using the
2752 C<wc -c> external command.");
2754 ("head", (RStringList "lines", [Pathname "path"]), 121, [ProtocolLimitWarning],
2755 [InitISOFS, Always, TestOutputList (
2756 [["head"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz";"3abcdefghijklmnopqrstuvwxyz";"4abcdefghijklmnopqrstuvwxyz";"5abcdefghijklmnopqrstuvwxyz";"6abcdefghijklmnopqrstuvwxyz";"7abcdefghijklmnopqrstuvwxyz";"8abcdefghijklmnopqrstuvwxyz";"9abcdefghijklmnopqrstuvwxyz"])],
2757 "return first 10 lines of a file",
2759 This command returns up to the first 10 lines of a file as
2760 a list of strings.");
2762 ("head_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 122, [ProtocolLimitWarning],
2763 [InitISOFS, Always, TestOutputList (
2764 [["head_n"; "3"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2765 InitISOFS, Always, TestOutputList (
2766 [["head_n"; "-9997"; "/10klines"]], ["0abcdefghijklmnopqrstuvwxyz";"1abcdefghijklmnopqrstuvwxyz";"2abcdefghijklmnopqrstuvwxyz"]);
2767 InitISOFS, Always, TestOutputList (
2768 [["head_n"; "0"; "/10klines"]], [])],
2769 "return first N lines of a file",
2771 If the parameter C<nrlines> is a positive number, this returns the first
2772 C<nrlines> lines of the file C<path>.
2774 If the parameter C<nrlines> is a negative number, this returns lines
2775 from the file C<path>, excluding the last C<nrlines> lines.
2777 If the parameter C<nrlines> is zero, this returns an empty list.");
2779 ("tail", (RStringList "lines", [Pathname "path"]), 123, [ProtocolLimitWarning],
2780 [InitISOFS, Always, TestOutputList (
2781 [["tail"; "/10klines"]], ["9990abcdefghijklmnopqrstuvwxyz";"9991abcdefghijklmnopqrstuvwxyz";"9992abcdefghijklmnopqrstuvwxyz";"9993abcdefghijklmnopqrstuvwxyz";"9994abcdefghijklmnopqrstuvwxyz";"9995abcdefghijklmnopqrstuvwxyz";"9996abcdefghijklmnopqrstuvwxyz";"9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"])],
2782 "return last 10 lines of a file",
2784 This command returns up to the last 10 lines of a file as
2785 a list of strings.");
2787 ("tail_n", (RStringList "lines", [Int "nrlines"; Pathname "path"]), 124, [ProtocolLimitWarning],
2788 [InitISOFS, Always, TestOutputList (
2789 [["tail_n"; "3"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2790 InitISOFS, Always, TestOutputList (
2791 [["tail_n"; "-9998"; "/10klines"]], ["9997abcdefghijklmnopqrstuvwxyz";"9998abcdefghijklmnopqrstuvwxyz";"9999abcdefghijklmnopqrstuvwxyz"]);
2792 InitISOFS, Always, TestOutputList (
2793 [["tail_n"; "0"; "/10klines"]], [])],
2794 "return last N lines of a file",
2796 If the parameter C<nrlines> is a positive number, this returns the last
2797 C<nrlines> lines of the file C<path>.
2799 If the parameter C<nrlines> is a negative number, this returns lines
2800 from the file C<path>, starting with the C<-nrlines>th line.
2802 If the parameter C<nrlines> is zero, this returns an empty list.");
2804 ("df", (RString "output", []), 125, [],
2805 [], (* XXX Tricky to test because it depends on the exact format
2806 * of the 'df' command and other imponderables.
2808 "report file system disk space usage",
2810 This command runs the C<df> command to report disk space used.
2812 This command is mostly useful for interactive sessions. It
2813 is I<not> intended that you try to parse the output string.
2814 Use C<statvfs> from programs.");
2816 ("df_h", (RString "output", []), 126, [],
2817 [], (* XXX Tricky to test because it depends on the exact format
2818 * of the 'df' command and other imponderables.
2820 "report file system disk space usage (human readable)",
2822 This command runs the C<df -h> command to report disk space used
2823 in human-readable format.
2825 This command is mostly useful for interactive sessions. It
2826 is I<not> intended that you try to parse the output string.
2827 Use C<statvfs> from programs.");
2829 ("du", (RInt64 "sizekb", [Pathname "path"]), 127, [],
2830 [InitISOFS, Always, TestOutputInt (
2831 [["du"; "/directory"]], 2 (* ISO fs blocksize is 2K *))],
2832 "estimate file space usage",
2834 This command runs the C<du -s> command to estimate file space
2837 C<path> can be a file or a directory. If C<path> is a directory
2838 then the estimate includes the contents of the directory and all
2839 subdirectories (recursively).
2841 The result is the estimated size in I<kilobytes>
2842 (ie. units of 1024 bytes).");
2844 ("initrd_list", (RStringList "filenames", [Pathname "path"]), 128, [],
2845 [InitISOFS, Always, TestOutputList (
2846 [["initrd_list"; "/initrd"]], ["empty";"known-1";"known-2";"known-3";"known-4"; "known-5"])],
2847 "list files in an initrd",
2849 This command lists out files contained in an initrd.
2851 The files are listed without any initial C</> character. The
2852 files are listed in the order they appear (not necessarily
2853 alphabetical). Directory names are listed as separate items.
2855 Old Linux kernels (2.4 and earlier) used a compressed ext2
2856 filesystem as initrd. We I<only> support the newer initramfs
2857 format (compressed cpio files).");
2859 ("mount_loop", (RErr, [Pathname "file"; Pathname "mountpoint"]), 129, [],
2861 "mount a file using the loop device",
2863 This command lets you mount C<file> (a filesystem image
2864 in a file) on a mount point. It is entirely equivalent to
2865 the command C<mount -o loop file mountpoint>.");
2867 ("mkswap", (RErr, [Device "device"]), 130, [],
2868 [InitEmpty, Always, TestRun (
2869 [["part_disk"; "/dev/sda"; "mbr"];
2870 ["mkswap"; "/dev/sda1"]])],
2871 "create a swap partition",
2873 Create a swap partition on C<device>.");
2875 ("mkswap_L", (RErr, [String "label"; Device "device"]), 131, [],
2876 [InitEmpty, Always, TestRun (
2877 [["part_disk"; "/dev/sda"; "mbr"];
2878 ["mkswap_L"; "hello"; "/dev/sda1"]])],
2879 "create a swap partition with a label",
2881 Create a swap partition on C<device> with label C<label>.
2883 Note that you cannot attach a swap label to a block device
2884 (eg. C</dev/sda>), just to a partition. This appears to be
2885 a limitation of the kernel or swap tools.");
2887 ("mkswap_U", (RErr, [String "uuid"; Device "device"]), 132, [],
2888 (let uuid = uuidgen () in
2889 [InitEmpty, Always, TestRun (
2890 [["part_disk"; "/dev/sda"; "mbr"];
2891 ["mkswap_U"; uuid; "/dev/sda1"]])]),
2892 "create a swap partition with an explicit UUID",
2894 Create a swap partition on C<device> with UUID C<uuid>.");
2896 ("mknod", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 133, [],
2897 [InitBasicFS, Always, TestOutputStruct (
2898 [["mknod"; "0o10777"; "0"; "0"; "/node"];
2899 (* NB: default umask 022 means 0777 -> 0755 in these tests *)
2900 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)]);
2901 InitBasicFS, Always, TestOutputStruct (
2902 [["mknod"; "0o60777"; "66"; "99"; "/node"];
2903 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
2904 "make block, character or FIFO devices",
2906 This call creates block or character special devices, or
2907 named pipes (FIFOs).
2909 The C<mode> parameter should be the mode, using the standard
2910 constants. C<devmajor> and C<devminor> are the
2911 device major and minor numbers, only used when creating block
2912 and character special devices.");
2914 ("mkfifo", (RErr, [Int "mode"; Pathname "path"]), 134, [],
2915 [InitBasicFS, Always, TestOutputStruct (
2916 [["mkfifo"; "0o777"; "/node"];
2917 ["stat"; "/node"]], [CompareWithInt ("mode", 0o10755)])],
2918 "make FIFO (named pipe)",
2920 This call creates a FIFO (named pipe) called C<path> with
2921 mode C<mode>. It is just a convenient wrapper around
2922 C<guestfs_mknod>.");
2924 ("mknod_b", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 135, [],
2925 [InitBasicFS, Always, TestOutputStruct (
2926 [["mknod_b"; "0o777"; "99"; "66"; "/node"];
2927 ["stat"; "/node"]], [CompareWithInt ("mode", 0o60755)])],
2928 "make block device node",
2930 This call creates a block device node called C<path> with
2931 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
2932 It is just a convenient wrapper around C<guestfs_mknod>.");
2934 ("mknod_c", (RErr, [Int "mode"; Int "devmajor"; Int "devminor"; Pathname "path"]), 136, [],
2935 [InitBasicFS, Always, TestOutputStruct (
2936 [["mknod_c"; "0o777"; "99"; "66"; "/node"];
2937 ["stat"; "/node"]], [CompareWithInt ("mode", 0o20755)])],
2938 "make char device node",
2940 This call creates a char device node called C<path> with
2941 mode C<mode> and device major/minor C<devmajor> and C<devminor>.
2942 It is just a convenient wrapper around C<guestfs_mknod>.");
2944 ("umask", (RInt "oldmask", [Int "mask"]), 137, [],
2945 [], (* XXX umask is one of those stateful things that we should
2946 * reset between each test.
2948 "set file mode creation mask (umask)",
2950 This function sets the mask used for creating new files and
2951 device nodes to C<mask & 0777>.
2953 Typical umask values would be C<022> which creates new files
2954 with permissions like \"-rw-r--r--\" or \"-rwxr-xr-x\", and
2955 C<002> which creates new files with permissions like
2956 \"-rw-rw-r--\" or \"-rwxrwxr-x\".
2958 The default umask is C<022>. This is important because it
2959 means that directories and device nodes will be created with
2960 C<0644> or C<0755> mode even if you specify C<0777>.
2962 See also L<umask(2)>, C<guestfs_mknod>, C<guestfs_mkdir>.
2964 This call returns the previous umask.");
2966 ("readdir", (RStructList ("entries", "dirent"), [Pathname "dir"]), 138, [],
2968 "read directories entries",
2970 This returns the list of directory entries in directory C<dir>.
2972 All entries in the directory are returned, including C<.> and
2973 C<..>. The entries are I<not> sorted, but returned in the same
2974 order as the underlying filesystem.
2976 Also this call returns basic file type information about each
2977 file. The C<ftyp> field will contain one of the following characters:
3015 The L<readdir(3)> returned a C<d_type> field with an
3020 This function is primarily intended for use by programs. To
3021 get a simple list of names, use C<guestfs_ls>. To get a printable
3022 directory for human consumption, use C<guestfs_ll>.");
3024 ("sfdiskM", (RErr, [Device "device"; StringList "lines"]), 139, [DangerWillRobinson],
3026 "create partitions on a block device",
3028 This is a simplified interface to the C<guestfs_sfdisk>
3029 command, where partition sizes are specified in megabytes
3030 only (rounded to the nearest cylinder) and you don't need
3031 to specify the cyls, heads and sectors parameters which
3032 were rarely if ever used anyway.
3034 See also: C<guestfs_sfdisk>, the L<sfdisk(8)> manpage
3035 and C<guestfs_part_disk>");
3037 ("zfile", (RString "description", [String "meth"; Pathname "path"]), 140, [DeprecatedBy "file"],
3039 "determine file type inside a compressed file",
3041 This command runs C<file> after first decompressing C<path>
3044 C<method> must be one of C<gzip>, C<compress> or C<bzip2>.
3046 Since 1.0.63, use C<guestfs_file> instead which can now
3047 process compressed files.");
3049 ("getxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 141, [],
3051 "list extended attributes of a file or directory",
3053 This call lists the extended attributes of the file or directory
3056 At the system call level, this is a combination of the
3057 L<listxattr(2)> and L<getxattr(2)> calls.
3059 See also: C<guestfs_lgetxattrs>, L<attr(5)>.");
3061 ("lgetxattrs", (RStructList ("xattrs", "xattr"), [Pathname "path"]), 142, [],
3063 "list extended attributes of a file or directory",
3065 This is the same as C<guestfs_getxattrs>, but if C<path>
3066 is a symbolic link, then it returns the extended attributes
3067 of the link itself.");
3069 ("setxattr", (RErr, [String "xattr";
3070 String "val"; Int "vallen"; (* will be BufferIn *)
3071 Pathname "path"]), 143, [],
3073 "set extended attribute of a file or directory",
3075 This call sets the extended attribute named C<xattr>
3076 of the file C<path> to the value C<val> (of length C<vallen>).
3077 The value is arbitrary 8 bit data.
3079 See also: C<guestfs_lsetxattr>, L<attr(5)>.");
3081 ("lsetxattr", (RErr, [String "xattr";
3082 String "val"; Int "vallen"; (* will be BufferIn *)
3083 Pathname "path"]), 144, [],
3085 "set extended attribute of a file or directory",
3087 This is the same as C<guestfs_setxattr>, but if C<path>
3088 is a symbolic link, then it sets an extended attribute
3089 of the link itself.");
3091 ("removexattr", (RErr, [String "xattr"; Pathname "path"]), 145, [],
3093 "remove extended attribute of a file or directory",
3095 This call removes the extended attribute named C<xattr>
3096 of the file C<path>.
3098 See also: C<guestfs_lremovexattr>, L<attr(5)>.");
3100 ("lremovexattr", (RErr, [String "xattr"; Pathname "path"]), 146, [],
3102 "remove extended attribute of a file or directory",
3104 This is the same as C<guestfs_removexattr>, but if C<path>
3105 is a symbolic link, then it removes an extended attribute
3106 of the link itself.");
3108 ("mountpoints", (RHashtable "mps", []), 147, [],
3112 This call is similar to C<guestfs_mounts>. That call returns
3113 a list of devices. This one returns a hash table (map) of
3114 device name to directory where the device is mounted.");
3116 ("mkmountpoint", (RErr, [String "exemptpath"]), 148, [],
3117 (* This is a special case: while you would expect a parameter
3118 * of type "Pathname", that doesn't work, because it implies
3119 * NEED_ROOT in the generated calling code in stubs.c, and
3120 * this function cannot use NEED_ROOT.
3123 "create a mountpoint",
3125 C<guestfs_mkmountpoint> and C<guestfs_rmmountpoint> are
3126 specialized calls that can be used to create extra mountpoints
3127 before mounting the first filesystem.
3129 These calls are I<only> necessary in some very limited circumstances,
3130 mainly the case where you want to mount a mix of unrelated and/or
3131 read-only filesystems together.
3133 For example, live CDs often contain a \"Russian doll\" nest of
3134 filesystems, an ISO outer layer, with a squashfs image inside, with
3135 an ext2/3 image inside that. You can unpack this as follows
3138 add-ro Fedora-11-i686-Live.iso
3141 mkmountpoint /squash
3144 mount-loop /cd/LiveOS/squashfs.img /squash
3145 mount-loop /squash/LiveOS/ext3fs.img /ext3
3147 The inner filesystem is now unpacked under the /ext3 mountpoint.");
3149 ("rmmountpoint", (RErr, [String "exemptpath"]), 149, [],
3151 "remove a mountpoint",
3153 This calls removes a mountpoint that was previously created
3154 with C<guestfs_mkmountpoint>. See C<guestfs_mkmountpoint>
3155 for full details.");
3157 ("read_file", (RBufferOut "content", [Pathname "path"]), 150, [ProtocolLimitWarning],
3158 [InitISOFS, Always, TestOutputBuffer (
3159 [["read_file"; "/known-4"]], "abc\ndef\nghi")],
3162 This calls returns the contents of the file C<path> as a
3165 Unlike C<guestfs_cat>, this function can correctly
3166 handle files that contain embedded ASCII NUL characters.
3167 However unlike C<guestfs_download>, this function is limited
3168 in the total size of file that can be handled.");
3170 ("grep", (RStringList "lines", [String "regex"; Pathname "path"]), 151, [ProtocolLimitWarning],
3171 [InitISOFS, Always, TestOutputList (
3172 [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
3173 InitISOFS, Always, TestOutputList (
3174 [["grep"; "nomatch"; "/test-grep.txt"]], [])],
3175 "return lines matching a pattern",
3177 This calls the external C<grep> program and returns the
3180 ("egrep", (RStringList "lines", [String "regex"; Pathname "path"]), 152, [ProtocolLimitWarning],
3181 [InitISOFS, Always, TestOutputList (
3182 [["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3183 "return lines matching a pattern",
3185 This calls the external C<egrep> program and returns the
3188 ("fgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 153, [ProtocolLimitWarning],
3189 [InitISOFS, Always, TestOutputList (
3190 [["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])],
3191 "return lines matching a pattern",
3193 This calls the external C<fgrep> program and returns the
3196 ("grepi", (RStringList "lines", [String "regex"; Pathname "path"]), 154, [ProtocolLimitWarning],
3197 [InitISOFS, Always, TestOutputList (
3198 [["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3199 "return lines matching a pattern",
3201 This calls the external C<grep -i> program and returns the
3204 ("egrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 155, [ProtocolLimitWarning],
3205 [InitISOFS, Always, TestOutputList (
3206 [["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3207 "return lines matching a pattern",
3209 This calls the external C<egrep -i> program and returns the
3212 ("fgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 156, [ProtocolLimitWarning],
3213 [InitISOFS, Always, TestOutputList (
3214 [["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])],
3215 "return lines matching a pattern",
3217 This calls the external C<fgrep -i> program and returns the
3220 ("zgrep", (RStringList "lines", [String "regex"; Pathname "path"]), 157, [ProtocolLimitWarning],
3221 [InitISOFS, Always, TestOutputList (
3222 [["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3223 "return lines matching a pattern",
3225 This calls the external C<zgrep> program and returns the
3228 ("zegrep", (RStringList "lines", [String "regex"; Pathname "path"]), 158, [ProtocolLimitWarning],
3229 [InitISOFS, Always, TestOutputList (
3230 [["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3231 "return lines matching a pattern",
3233 This calls the external C<zegrep> program and returns the
3236 ("zfgrep", (RStringList "lines", [String "pattern"; Pathname "path"]), 159, [ProtocolLimitWarning],
3237 [InitISOFS, Always, TestOutputList (
3238 [["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])],
3239 "return lines matching a pattern",
3241 This calls the external C<zfgrep> program and returns the
3244 ("zgrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 160, [ProtocolLimitWarning],
3245 [InitISOFS, Always, TestOutputList (
3246 [["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3247 "return lines matching a pattern",
3249 This calls the external C<zgrep -i> program and returns the
3252 ("zegrepi", (RStringList "lines", [String "regex"; Pathname "path"]), 161, [ProtocolLimitWarning],
3253 [InitISOFS, Always, TestOutputList (
3254 [["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3255 "return lines matching a pattern",
3257 This calls the external C<zegrep -i> program and returns the
3260 ("zfgrepi", (RStringList "lines", [String "pattern"; Pathname "path"]), 162, [ProtocolLimitWarning],
3261 [InitISOFS, Always, TestOutputList (
3262 [["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])],
3263 "return lines matching a pattern",
3265 This calls the external C<zfgrep -i> program and returns the
3268 ("realpath", (RString "rpath", [Pathname "path"]), 163, [],
3269 [InitISOFS, Always, TestOutput (
3270 [["realpath"; "/../directory"]], "/directory")],
3271 "canonicalized absolute pathname",
3273 Return the canonicalized absolute pathname of C<path>. The
3274 returned path has no C<.>, C<..> or symbolic link path elements.");
3276 ("ln", (RErr, [String "target"; Pathname "linkname"]), 164, [],
3277 [InitBasicFS, Always, TestOutputStruct (
3280 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3281 "create a hard link",
3283 This command creates a hard link using the C<ln> command.");
3285 ("ln_f", (RErr, [String "target"; Pathname "linkname"]), 165, [],
3286 [InitBasicFS, Always, TestOutputStruct (
3289 ["ln_f"; "/a"; "/b"];
3290 ["stat"; "/b"]], [CompareWithInt ("nlink", 2)])],
3291 "create a hard link",
3293 This command creates a hard link using the C<ln -f> command.
3294 The C<-f> option removes the link (C<linkname>) if it exists already.");
3296 ("ln_s", (RErr, [String "target"; Pathname "linkname"]), 166, [],
3297 [InitBasicFS, Always, TestOutputStruct (
3299 ["ln_s"; "a"; "/b"];
3300 ["lstat"; "/b"]], [CompareWithInt ("mode", 0o120777)])],
3301 "create a symbolic link",
3303 This command creates a symbolic link using the C<ln -s> command.");
3305 ("ln_sf", (RErr, [String "target"; Pathname "linkname"]), 167, [],
3306 [InitBasicFS, Always, TestOutput (
3307 [["mkdir_p"; "/a/b"];
3308 ["touch"; "/a/b/c"];
3309 ["ln_sf"; "../d"; "/a/b/c"];
3310 ["readlink"; "/a/b/c"]], "../d")],
3311 "create a symbolic link",
3313 This command creates a symbolic link using the C<ln -sf> command,
3314 The C<-f> option removes the link (C<linkname>) if it exists already.");
3316 ("readlink", (RString "link", [Pathname "path"]), 168, [],
3317 [] (* XXX tested above *),
3318 "read the target of a symbolic link",
3320 This command reads the target of a symbolic link.");
3322 ("fallocate", (RErr, [Pathname "path"; Int "len"]), 169, [],
3323 [InitBasicFS, Always, TestOutputStruct (
3324 [["fallocate"; "/a"; "1000000"];
3325 ["stat"; "/a"]], [CompareWithInt ("size", 1_000_000)])],
3326 "preallocate a file in the guest filesystem",
3328 This command preallocates a file (containing zero bytes) named
3329 C<path> of size C<len> bytes. If the file exists already, it
3332 Do not confuse this with the guestfish-specific
3333 C<alloc> command which allocates a file in the host and
3334 attaches it as a device.");
3336 ("swapon_device", (RErr, [Device "device"]), 170, [],
3337 [InitPartition, Always, TestRun (
3338 [["mkswap"; "/dev/sda1"];
3339 ["swapon_device"; "/dev/sda1"];
3340 ["swapoff_device"; "/dev/sda1"]])],
3341 "enable swap on device",
3343 This command enables the libguestfs appliance to use the
3344 swap device or partition named C<device>. The increased
3345 memory is made available for all commands, for example
3346 those run using C<guestfs_command> or C<guestfs_sh>.
3348 Note that you should not swap to existing guest swap
3349 partitions unless you know what you are doing. They may
3350 contain hibernation information, or other information that
3351 the guest doesn't want you to trash. You also risk leaking
3352 information about the host to the guest this way. Instead,
3353 attach a new host device to the guest and swap on that.");
3355 ("swapoff_device", (RErr, [Device "device"]), 171, [],
3356 [], (* XXX tested by swapon_device *)
3357 "disable swap on device",
3359 This command disables the libguestfs appliance swap
3360 device or partition named C<device>.
3361 See C<guestfs_swapon_device>.");
3363 ("swapon_file", (RErr, [Pathname "file"]), 172, [],
3364 [InitBasicFS, Always, TestRun (
3365 [["fallocate"; "/swap"; "8388608"];
3366 ["mkswap_file"; "/swap"];
3367 ["swapon_file"; "/swap"];
3368 ["swapoff_file"; "/swap"]])],
3369 "enable swap on file",
3371 This command enables swap to a file.
3372 See C<guestfs_swapon_device> for other notes.");
3374 ("swapoff_file", (RErr, [Pathname "file"]), 173, [],
3375 [], (* XXX tested by swapon_file *)
3376 "disable swap on file",
3378 This command disables the libguestfs appliance swap on file.");
3380 ("swapon_label", (RErr, [String "label"]), 174, [],
3381 [InitEmpty, Always, TestRun (
3382 [["part_disk"; "/dev/sdb"; "mbr"];
3383 ["mkswap_L"; "swapit"; "/dev/sdb1"];
3384 ["swapon_label"; "swapit"];
3385 ["swapoff_label"; "swapit"];
3386 ["zero"; "/dev/sdb"];
3387 ["blockdev_rereadpt"; "/dev/sdb"]])],
3388 "enable swap on labeled swap partition",
3390 This command enables swap to a labeled swap partition.
3391 See C<guestfs_swapon_device> for other notes.");
3393 ("swapoff_label", (RErr, [String "label"]), 175, [],
3394 [], (* XXX tested by swapon_label *)
3395 "disable swap on labeled swap partition",
3397 This command disables the libguestfs appliance swap on
3398 labeled swap partition.");
3400 ("swapon_uuid", (RErr, [String "uuid"]), 176, [],
3401 (let uuid = uuidgen () in
3402 [InitEmpty, Always, TestRun (
3403 [["mkswap_U"; uuid; "/dev/sdb"];
3404 ["swapon_uuid"; uuid];
3405 ["swapoff_uuid"; uuid]])]),
3406 "enable swap on swap partition by UUID",
3408 This command enables swap to a swap partition with the given UUID.
3409 See C<guestfs_swapon_device> for other notes.");
3411 ("swapoff_uuid", (RErr, [String "uuid"]), 177, [],
3412 [], (* XXX tested by swapon_uuid *)
3413 "disable swap on swap partition by UUID",
3415 This command disables the libguestfs appliance swap partition
3416 with the given UUID.");
3418 ("mkswap_file", (RErr, [Pathname "path"]), 178, [],
3419 [InitBasicFS, Always, TestRun (
3420 [["fallocate"; "/swap"; "8388608"];
3421 ["mkswap_file"; "/swap"]])],
3422 "create a swap file",
3426 This command just writes a swap file signature to an existing
3427 file. To create the file itself, use something like C<guestfs_fallocate>.");
3429 ("inotify_init", (RErr, [Int "maxevents"]), 179, [],
3430 [InitISOFS, Always, TestRun (
3431 [["inotify_init"; "0"]])],
3432 "create an inotify handle",
3434 This command creates a new inotify handle.
3435 The inotify subsystem can be used to notify events which happen to
3436 objects in the guest filesystem.
3438 C<maxevents> is the maximum number of events which will be
3439 queued up between calls to C<guestfs_inotify_read> or
3440 C<guestfs_inotify_files>.
3441 If this is passed as C<0>, then the kernel (or previously set)
3442 default is used. For Linux 2.6.29 the default was 16384 events.
3443 Beyond this limit, the kernel throws away events, but records
3444 the fact that it threw them away by setting a flag
3445 C<IN_Q_OVERFLOW> in the returned structure list (see
3446 C<guestfs_inotify_read>).
3448 Before any events are generated, you have to add some
3449 watches to the internal watch list. See:
3450 C<guestfs_inotify_add_watch>,
3451 C<guestfs_inotify_rm_watch> and
3452 C<guestfs_inotify_watch_all>.
3454 Queued up events should be read periodically by calling
3455 C<guestfs_inotify_read>
3456 (or C<guestfs_inotify_files> which is just a helpful
3457 wrapper around C<guestfs_inotify_read>). If you don't
3458 read the events out often enough then you risk the internal
3461 The handle should be closed after use by calling
3462 C<guestfs_inotify_close>. This also removes any
3463 watches automatically.
3465 See also L<inotify(7)> for an overview of the inotify interface
3466 as exposed by the Linux kernel, which is roughly what we expose
3467 via libguestfs. Note that there is one global inotify handle
3468 per libguestfs instance.");
3470 ("inotify_add_watch", (RInt64 "wd", [Pathname "path"; Int "mask"]), 180, [],
3471 [InitBasicFS, Always, TestOutputList (
3472 [["inotify_init"; "0"];
3473 ["inotify_add_watch"; "/"; "1073741823"];
3476 ["inotify_files"]], ["a"; "b"])],
3477 "add an inotify watch",
3479 Watch C<path> for the events listed in C<mask>.
3481 Note that if C<path> is a directory then events within that
3482 directory are watched, but this does I<not> happen recursively
3483 (in subdirectories).
3485 Note for non-C or non-Linux callers: the inotify events are
3486 defined by the Linux kernel ABI and are listed in
3487 C</usr/include/sys/inotify.h>.");
3489 ("inotify_rm_watch", (RErr, [Int(*XXX64*) "wd"]), 181, [],
3491 "remove an inotify watch",
3493 Remove a previously defined inotify watch.
3494 See C<guestfs_inotify_add_watch>.");
3496 ("inotify_read", (RStructList ("events", "inotify_event"), []), 182, [],
3498 "return list of inotify events",
3500 Return the complete queue of events that have happened
3501 since the previous read call.
3503 If no events have happened, this returns an empty list.
3505 I<Note>: In order to make sure that all events have been
3506 read, you must call this function repeatedly until it
3507 returns an empty list. The reason is that the call will
3508 read events up to the maximum appliance-to-host message
3509 size and leave remaining events in the queue.");
3511 ("inotify_files", (RStringList "paths", []), 183, [],
3513 "return list of watched files that had events",
3515 This function is a helpful wrapper around C<guestfs_inotify_read>
3516 which just returns a list of pathnames of objects that were
3517 touched. The returned pathnames are sorted and deduplicated.");
3519 ("inotify_close", (RErr, []), 184, [],
3521 "close the inotify handle",
3523 This closes the inotify handle which was previously
3524 opened by inotify_init. It removes all watches, throws
3525 away any pending events, and deallocates all resources.");
3527 ("setcon", (RErr, [String "context"]), 185, [],
3529 "set SELinux security context",
3531 This sets the SELinux security context of the daemon
3532 to the string C<context>.
3534 See the documentation about SELINUX in L<guestfs(3)>.");
3536 ("getcon", (RString "context", []), 186, [],
3538 "get SELinux security context",
3540 This gets the SELinux security context of the daemon.
3542 See the documentation about SELINUX in L<guestfs(3)>,
3543 and C<guestfs_setcon>");
3545 ("mkfs_b", (RErr, [String "fstype"; Int "blocksize"; Device "device"]), 187, [],
3546 [InitEmpty, Always, TestOutput (
3547 [["part_disk"; "/dev/sda"; "mbr"];
3548 ["mkfs_b"; "ext2"; "4096"; "/dev/sda1"];
3549 ["mount"; "/dev/sda1"; "/"];
3550 ["write_file"; "/new"; "new file contents"; "0"];
3551 ["cat"; "/new"]], "new file contents")],
3552 "make a filesystem with block size",
3554 This call is similar to C<guestfs_mkfs>, but it allows you to
3555 control the block size of the resulting filesystem. Supported
3556 block sizes depend on the filesystem type, but typically they
3557 are C<1024>, C<2048> or C<4096> only.");
3559 ("mke2journal", (RErr, [Int "blocksize"; Device "device"]), 188, [],
3560 [InitEmpty, Always, TestOutput (
3561 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3562 ["mke2journal"; "4096"; "/dev/sda1"];
3563 ["mke2fs_J"; "ext2"; "4096"; "/dev/sda2"; "/dev/sda1"];
3564 ["mount"; "/dev/sda2"; "/"];
3565 ["write_file"; "/new"; "new file contents"; "0"];
3566 ["cat"; "/new"]], "new file contents")],
3567 "make ext2/3/4 external journal",
3569 This creates an ext2 external journal on C<device>. It is equivalent
3572 mke2fs -O journal_dev -b blocksize device");
3574 ("mke2journal_L", (RErr, [Int "blocksize"; String "label"; Device "device"]), 189, [],
3575 [InitEmpty, Always, TestOutput (
3576 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3577 ["mke2journal_L"; "4096"; "JOURNAL"; "/dev/sda1"];
3578 ["mke2fs_JL"; "ext2"; "4096"; "/dev/sda2"; "JOURNAL"];
3579 ["mount"; "/dev/sda2"; "/"];
3580 ["write_file"; "/new"; "new file contents"; "0"];
3581 ["cat"; "/new"]], "new file contents")],
3582 "make ext2/3/4 external journal with label",
3584 This creates an ext2 external journal on C<device> with label C<label>.");
3586 ("mke2journal_U", (RErr, [Int "blocksize"; String "uuid"; Device "device"]), 190, [],
3587 (let uuid = uuidgen () in
3588 [InitEmpty, Always, TestOutput (
3589 [["sfdiskM"; "/dev/sda"; ",100 ,"];
3590 ["mke2journal_U"; "4096"; uuid; "/dev/sda1"];
3591 ["mke2fs_JU"; "ext2"; "4096"; "/dev/sda2"; uuid];
3592 ["mount"; "/dev/sda2"; "/"];
3593 ["write_file"; "/new"; "new file contents"; "0"];
3594 ["cat"; "/new"]], "new file contents")]),
3595 "make ext2/3/4 external journal with UUID",
3597 This creates an ext2 external journal on C<device> with UUID C<uuid>.");
3599 ("mke2fs_J", (RErr, [String "fstype"; Int "blocksize"; Device "device"; Device "journal"]), 191, [],
3601 "make ext2/3/4 filesystem with external journal",
3603 This creates an ext2/3/4 filesystem on C<device> with
3604 an external journal on C<journal>. It is equivalent
3607 mke2fs -t fstype -b blocksize -J device=<journal> <device>
3609 See also C<guestfs_mke2journal>.");
3611 ("mke2fs_JL", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "label"]), 192, [],
3613 "make ext2/3/4 filesystem with external journal",
3615 This creates an ext2/3/4 filesystem on C<device> with
3616 an external journal on the journal labeled C<label>.
3618 See also C<guestfs_mke2journal_L>.");
3620 ("mke2fs_JU", (RErr, [String "fstype"; Int "blocksize"; Device "device"; String "uuid"]), 193, [],
3622 "make ext2/3/4 filesystem with external journal",
3624 This creates an ext2/3/4 filesystem on C<device> with
3625 an external journal on the journal with UUID C<uuid>.
3627 See also C<guestfs_mke2journal_U>.");
3629 ("modprobe", (RErr, [String "modulename"]), 194, [],
3630 [InitNone, Always, TestRun [["modprobe"; "fat"]]],
3631 "load a kernel module",
3633 This loads a kernel module in the appliance.
3635 The kernel module must have been whitelisted when libguestfs
3636 was built (see C<appliance/kmod.whitelist.in> in the source).");
3638 ("echo_daemon", (RString "output", [StringList "words"]), 195, [],
3639 [InitNone, Always, TestOutput (
3640 [["echo_daemon"; "This is a test"]], "This is a test"
3642 "echo arguments back to the client",
3644 This command concatenate the list of C<words> passed with single spaces between
3645 them and returns the resulting string.
3647 You can use this command to test the connection through to the daemon.
3649 See also C<guestfs_ping_daemon>.");
3651 ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
3652 [], (* There is a regression test for this. *)
3653 "find all files and directories, returning NUL-separated list",
3655 This command lists out all files and directories, recursively,
3656 starting at C<directory>, placing the resulting list in the
3657 external file called C<files>.
3659 This command works the same way as C<guestfs_find> with the
3660 following exceptions:
3666 The resulting list is written to an external file.
3670 Items (filenames) in the result are separated
3671 by C<\\0> characters. See L<find(1)> option I<-print0>.
3675 This command is not limited in the number of names that it
3680 The result list is not sorted.
3684 ("case_sensitive_path", (RString "rpath", [Pathname "path"]), 197, [],
3685 [InitISOFS, Always, TestOutput (
3686 [["case_sensitive_path"; "/DIRECTORY"]], "/directory");
3687 InitISOFS, Always, TestOutput (
3688 [["case_sensitive_path"; "/DIRECTORY/"]], "/directory");
3689 InitISOFS, Always, TestOutput (
3690 [["case_sensitive_path"; "/Known-1"]], "/known-1");
3691 InitISOFS, Always, TestLastFail (
3692 [["case_sensitive_path"; "/Known-1/"]]);
3693 InitBasicFS, Always, TestOutput (
3695 ["mkdir"; "/a/bbb"];
3696 ["touch"; "/a/bbb/c"];
3697 ["case_sensitive_path"; "/A/bbB/C"]], "/a/bbb/c");
3698 InitBasicFS, Always, TestOutput (
3700 ["mkdir"; "/a/bbb"];
3701 ["touch"; "/a/bbb/c"];
3702 ["case_sensitive_path"; "/A////bbB/C"]], "/a/bbb/c");
3703 InitBasicFS, Always, TestLastFail (
3705 ["mkdir"; "/a/bbb"];
3706 ["touch"; "/a/bbb/c"];
3707 ["case_sensitive_path"; "/A/bbb/../bbb/C"]])],
3708 "return true path on case-insensitive filesystem",
3710 This can be used to resolve case insensitive paths on
3711 a filesystem which is case sensitive. The use case is
3712 to resolve paths which you have read from Windows configuration
3713 files or the Windows Registry, to the true path.
3715 The command handles a peculiarity of the Linux ntfs-3g
3716 filesystem driver (and probably others), which is that although
3717 the underlying filesystem is case-insensitive, the driver
3718 exports the filesystem to Linux as case-sensitive.
3720 One consequence of this is that special directories such
3721 as C<c:\\windows> may appear as C</WINDOWS> or C</windows>
3722 (or other things) depending on the precise details of how
3723 they were created. In Windows itself this would not be
3726 Bug or feature? You decide:
3727 L<http://www.tuxera.com/community/ntfs-3g-faq/#posixfilenames1>
3729 This function resolves the true case of each element in the
3730 path and returns the case-sensitive path.
3732 Thus C<guestfs_case_sensitive_path> (\"/Windows/System32\")
3733 might return C<\"/WINDOWS/system32\"> (the exact return value
3734 would depend on details of how the directories were originally
3735 created under Windows).
3738 This function does not handle drive names, backslashes etc.
3740 See also C<guestfs_realpath>.");
3742 ("vfs_type", (RString "fstype", [Device "device"]), 198, [],
3743 [InitBasicFS, Always, TestOutput (
3744 [["vfs_type"; "/dev/sda1"]], "ext2")],
3745 "get the Linux VFS type corresponding to a mounted device",
3747 This command gets the block device type corresponding to
3748 a mounted device called C<device>.
3750 Usually the result is the name of the Linux VFS module that
3751 is used to mount this device (probably determined automatically
3752 if you used the C<guestfs_mount> call).");
3754 ("truncate", (RErr, [Pathname "path"]), 199, [],
3755 [InitBasicFS, Always, TestOutputStruct (
3756 [["write_file"; "/test"; "some stuff so size is not zero"; "0"];
3757 ["truncate"; "/test"];
3758 ["stat"; "/test"]], [CompareWithInt ("size", 0)])],
3759 "truncate a file to zero size",
3761 This command truncates C<path> to a zero-length file. The
3762 file must exist already.");
3764 ("truncate_size", (RErr, [Pathname "path"; Int64 "size"]), 200, [],
3765 [InitBasicFS, Always, TestOutputStruct (
3766 [["touch"; "/test"];
3767 ["truncate_size"; "/test"; "1000"];
3768 ["stat"; "/test"]], [CompareWithInt ("size", 1000)])],
3769 "truncate a file to a particular size",
3771 This command truncates C<path> to size C<size> bytes. The file
3772 must exist already. If the file is smaller than C<size> then
3773 the file is extended to the required size with null bytes.");
3775 ("utimens", (RErr, [Pathname "path"; Int64 "atsecs"; Int64 "atnsecs"; Int64 "mtsecs"; Int64 "mtnsecs"]), 201, [],
3776 [InitBasicFS, Always, TestOutputStruct (
3777 [["touch"; "/test"];
3778 ["utimens"; "/test"; "12345"; "67890"; "9876"; "5432"];
3779 ["stat"; "/test"]], [CompareWithInt ("mtime", 9876)])],
3780 "set timestamp of a file with nanosecond precision",
3782 This command sets the timestamps of a file with nanosecond
3785 C<atsecs, atnsecs> are the last access time (atime) in secs and
3786 nanoseconds from the epoch.
3788 C<mtsecs, mtnsecs> are the last modification time (mtime) in
3789 secs and nanoseconds from the epoch.
3791 If the C<*nsecs> field contains the special value C<-1> then
3792 the corresponding timestamp is set to the current time. (The
3793 C<*secs> field is ignored in this case).
3795 If the C<*nsecs> field contains the special value C<-2> then
3796 the corresponding timestamp is left unchanged. (The
3797 C<*secs> field is ignored in this case).");
3799 ("mkdir_mode", (RErr, [Pathname "path"; Int "mode"]), 202, [],
3800 [InitBasicFS, Always, TestOutputStruct (
3801 [["mkdir_mode"; "/test"; "0o111"];
3802 ["stat"; "/test"]], [CompareWithInt ("mode", 0o40111)])],
3803 "create a directory with a particular mode",
3805 This command creates a directory, setting the initial permissions
3806 of the directory to C<mode>. See also C<guestfs_mkdir>.");
3808 ("lchown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 203, [],
3810 "change file owner and group",
3812 Change the file owner to C<owner> and group to C<group>.
3813 This is like C<guestfs_chown> but if C<path> is a symlink then
3814 the link itself is changed, not the target.
3816 Only numeric uid and gid are supported. If you want to use
3817 names, you will need to locate and parse the password file
3818 yourself (Augeas support makes this relatively easy).");
3820 ("lstatlist", (RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"]), 204, [],
3822 "lstat on multiple files",
3824 This call allows you to perform the C<guestfs_lstat> operation
3825 on multiple files, where all files are in the directory C<path>.
3826 C<names> is the list of files from this directory.
3828 On return you get a list of stat structs, with a one-to-one
3829 correspondence to the C<names> list. If any name did not exist
3830 or could not be lstat'd, then the C<ino> field of that structure
3833 This call is intended for programs that want to efficiently
3834 list a directory contents without making many round-trips.
3835 See also C<guestfs_lxattrlist> for a similarly efficient call
3836 for getting extended attributes. Very long directory listings
3837 might cause the protocol message size to be exceeded, causing
3838 this call to fail. The caller must split up such requests
3839 into smaller groups of names.");
3841 ("lxattrlist", (RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"]), 205, [],
3843 "lgetxattr on multiple files",
3845 This call allows you to get the extended attributes
3846 of multiple files, where all files are in the directory C<path>.
3847 C<names> is the list of files from this directory.
3849 On return you get a flat list of xattr structs which must be
3850 interpreted sequentially. The first xattr struct always has a zero-length
3851 C<attrname>. C<attrval> in this struct is zero-length
3852 to indicate there was an error doing C<lgetxattr> for this
3853 file, I<or> is a C string which is a decimal number
3854 (the number of following attributes for this file, which could
3855 be C<\"0\">). Then after the first xattr struct are the
3856 zero or more attributes for the first named file.
3857 This repeats for the second and subsequent files.
3859 This call is intended for programs that want to efficiently
3860 list a directory contents without making many round-trips.
3861 See also C<guestfs_lstatlist> for a similarly efficient call
3862 for getting standard stats. Very long directory listings
3863 might cause the protocol message size to be exceeded, causing
3864 this call to fail. The caller must split up such requests
3865 into smaller groups of names.");
3867 ("readlinklist", (RStringList "links", [Pathname "path"; StringList "names"]), 206, [],
3869 "readlink on multiple files",
3871 This call allows you to do a C<readlink> operation
3872 on multiple files, where all files are in the directory C<path>.
3873 C<names> is the list of files from this directory.
3875 On return you get a list of strings, with a one-to-one
3876 correspondence to the C<names> list. Each string is the
3877 value of the symbol link.
3879 If the C<readlink(2)> operation fails on any name, then
3880 the corresponding result string is the empty string C<\"\">.
3881 However the whole operation is completed even if there
3882 were C<readlink(2)> errors, and so you can call this
3883 function with names where you don't know if they are
3884 symbolic links already (albeit slightly less efficient).
3886 This call is intended for programs that want to efficiently
3887 list a directory contents without making many round-trips.
3888 Very long directory listings might cause the protocol
3889 message size to be exceeded, causing
3890 this call to fail. The caller must split up such requests
3891 into smaller groups of names.");
3893 ("pread", (RBufferOut "content", [Pathname "path"; Int "count"; Int64 "offset"]), 207, [ProtocolLimitWarning],
3894 [InitISOFS, Always, TestOutputBuffer (
3895 [["pread"; "/known-4"; "1"; "3"]], "\n");
3896 InitISOFS, Always, TestOutputBuffer (
3897 [["pread"; "/empty"; "0"; "100"]], "")],
3898 "read part of a file",
3900 This command lets you read part of a file. It reads C<count>
3901 bytes of the file, starting at C<offset>, from file C<path>.
3903 This may read fewer bytes than requested. For further details
3904 see the L<pread(2)> system call.");
3906 ("part_init", (RErr, [Device "device"; String "parttype"]), 208, [],
3907 [InitEmpty, Always, TestRun (
3908 [["part_init"; "/dev/sda"; "gpt"]])],
3909 "create an empty partition table",
3911 This creates an empty partition table on C<device> of one of the
3912 partition types listed below. Usually C<parttype> should be
3913 either C<msdos> or C<gpt> (for large disks).
3915 Initially there are no partitions. Following this, you should
3916 call C<guestfs_part_add> for each partition required.
3918 Possible values for C<parttype> are:
3922 =item B<efi> | B<gpt>
3924 Intel EFI / GPT partition table.
3926 This is recommended for >= 2 TB partitions that will be accessed
3927 from Linux and Intel-based Mac OS X. It also has limited backwards
3928 compatibility with the C<mbr> format.
3930 =item B<mbr> | B<msdos>
3932 The standard PC \"Master Boot Record\" (MBR) format used
3933 by MS-DOS and Windows. This partition type will B<only> work
3934 for device sizes up to 2 TB. For large disks we recommend
3939 Other partition table types that may work but are not
3948 =item B<amiga> | B<rdb>
3950 Amiga \"Rigid Disk Block\" format.
3958 DASD, used on IBM mainframes.
3966 Old Mac partition format. Modern Macs use C<gpt>.
3970 NEC PC-98 format, common in Japan apparently.
3978 ("part_add", (RErr, [Device "device"; String "prlogex"; Int64 "startsect"; Int64 "endsect"]), 209, [],
3979 [InitEmpty, Always, TestRun (
3980 [["part_init"; "/dev/sda"; "mbr"];
3981 ["part_add"; "/dev/sda"; "primary"; "1"; "-1"]]);
3982 InitEmpty, Always, TestRun (
3983 [["part_init"; "/dev/sda"; "gpt"];
3984 ["part_add"; "/dev/sda"; "primary"; "34"; "127"];
3985 ["part_add"; "/dev/sda"; "primary"; "128"; "-34"]]);
3986 InitEmpty, Always, TestRun (
3987 [["part_init"; "/dev/sda"; "mbr"];
3988 ["part_add"; "/dev/sda"; "primary"; "32"; "127"];
3989 ["part_add"; "/dev/sda"; "primary"; "128"; "255"];
3990 ["part_add"; "/dev/sda"; "primary"; "256"; "511"];
3991 ["part_add"; "/dev/sda"; "primary"; "512"; "-1"]])],
3992 "add a partition to the device",
3994 This command adds a partition to C<device>. If there is no partition
3995 table on the device, call C<guestfs_part_init> first.
3997 The C<prlogex> parameter is the type of partition. Normally you
3998 should pass C<p> or C<primary> here, but MBR partition tables also
3999 support C<l> (or C<logical>) and C<e> (or C<extended>) partition
4002 C<startsect> and C<endsect> are the start and end of the partition
4003 in I<sectors>. C<endsect> may be negative, which means it counts
4004 backwards from the end of the disk (C<-1> is the last sector).
4006 Creating a partition which covers the whole disk is not so easy.
4007 Use C<guestfs_part_disk> to do that.");
4009 ("part_disk", (RErr, [Device "device"; String "parttype"]), 210, [DangerWillRobinson],
4010 [InitEmpty, Always, TestRun (
4011 [["part_disk"; "/dev/sda"; "mbr"]]);
4012 InitEmpty, Always, TestRun (
4013 [["part_disk"; "/dev/sda"; "gpt"]])],
4014 "partition whole disk with a single primary partition",
4016 This command is simply a combination of C<guestfs_part_init>
4017 followed by C<guestfs_part_add> to create a single primary partition
4018 covering the whole disk.
4020 C<parttype> is the partition table type, usually C<mbr> or C<gpt>,
4021 but other possible values are described in C<guestfs_part_init>.");
4023 ("part_set_bootable", (RErr, [Device "device"; Int "partnum"; Bool "bootable"]), 211, [],
4024 [InitEmpty, Always, TestRun (
4025 [["part_disk"; "/dev/sda"; "mbr"];
4026 ["part_set_bootable"; "/dev/sda"; "1"; "true"]])],
4027 "make a partition bootable",
4029 This sets the bootable flag on partition numbered C<partnum> on
4030 device C<device>. Note that partitions are numbered from 1.
4032 The bootable flag is used by some PC BIOSes to determine which
4033 partition to boot from. It is by no means universally recognized,
4034 and in any case if your operating system installed a boot
4035 sector on the device itself, then that takes precedence.");
4037 ("part_set_name", (RErr, [Device "device"; Int "partnum"; String "name"]), 212, [],
4038 [InitEmpty, Always, TestRun (
4039 [["part_disk"; "/dev/sda"; "gpt"];
4040 ["part_set_name"; "/dev/sda"; "1"; "thepartname"]])],
4041 "set partition name",
4043 This sets the partition name on partition numbered C<partnum> on
4044 device C<device>. Note that partitions are numbered from 1.
4046 The partition name can only be set on certain types of partition
4047 table. This works on C<gpt> but not on C<mbr> partitions.");
4049 ("part_list", (RStructList ("partitions", "partition"), [Device "device"]), 213, [],
4050 [], (* XXX Add a regression test for this. *)
4051 "list partitions on a device",
4053 This command parses the partition table on C<device> and
4054 returns the list of partitions found.
4056 The fields in the returned structure are:
4062 Partition number, counting from 1.
4066 Start of the partition I<in bytes>. To get sectors you have to
4067 divide by the device's sector size, see C<guestfs_blockdev_getss>.
4071 End of the partition in bytes.
4075 Size of the partition in bytes.
4079 ("part_get_parttype", (RString "parttype", [Device "device"]), 214, [],
4080 [InitEmpty, Always, TestOutput (
4081 [["part_disk"; "/dev/sda"; "gpt"];
4082 ["part_get_parttype"; "/dev/sda"]], "gpt")],
4083 "get the partition table type",
4085 This command examines the partition table on C<device> and
4086 returns the partition table type (format) being used.
4088 Common return values include: C<msdos> (a DOS/Windows style MBR
4089 partition table), C<gpt> (a GPT/EFI-style partition table). Other
4090 values are possible, although unusual. See C<guestfs_part_init>
4093 ("fill", (RErr, [Int "c"; Int "len"; Pathname "path"]), 215, [],
4094 [InitBasicFS, Always, TestOutputBuffer (
4095 [["fill"; "0x63"; "10"; "/test"];
4096 ["read_file"; "/test"]], "cccccccccc")],
4097 "fill a file with octets",
4099 This command creates a new file called C<path>. The initial
4100 content of the file is C<len> octets of C<c>, where C<c>
4101 must be a number in the range C<[0..255]>.
4103 To fill a file with zero bytes (sparsely), it is
4104 much more efficient to use C<guestfs_truncate_size>.");
4106 ("available", (RErr, [StringList "groups"]), 216, [],
4108 "test availability of some parts of the API",
4110 This command is used to check the availability of some
4111 groups of libguestfs functions which not all builds of
4112 libguestfs will be able to provide.
4114 The precise libguestfs function groups that may be checked by this
4115 command are listed in L<guestfs(3)/AVAILABILITY>.
4117 The argument C<groups> is a list of API group names, eg:
4118 C<[\"inotify\", \"part\"]> would check for the availability of
4119 the C<guestfs_inotify_*> functions and C<guestfs_part_*>
4120 (partition editing) functions.
4122 The command returns no error if I<all> requested groups are available.
4124 It returns an error if one or more of the requested
4125 groups is unavailable.
4127 If an unknown group name is included in the
4128 list of C<groups> then an error is always returned.
4136 You must call C<guestfs_launch> before calling this function.
4137 The reason is because we don't know what function groups are
4138 supported by the appliance/daemon until it is running and can
4143 If a group of functions is available, this does not necessarily
4144 mean that they will work. You still have to check for errors
4145 when calling individual API functions even if they are
4150 It is usually the job of distro packagers to build
4151 complete functionality into the libguestfs appliance.
4152 Upstream libguestfs, if built from source with all
4153 requirements satisfied, will support everything.
4157 This call was added in version C<1.0.80>. In previous
4158 versions of libguestfs all you could do would be to speculatively
4159 execute a command to find out if the daemon implemented it.
4160 See also C<guestfs_version>.
4166 let all_functions = non_daemon_functions @ daemon_functions
4168 (* In some places we want the functions to be displayed sorted
4169 * alphabetically, so this is useful:
4171 let all_functions_sorted =
4172 List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
4173 compare n1 n2) all_functions
4175 (* Field types for structures. *)
4177 | FChar (* C 'char' (really, a 7 bit byte). *)
4178 | FString (* nul-terminated ASCII string, NOT NULL. *)
4179 | FBuffer (* opaque buffer of bytes, (char *, int) pair *)
4184 | FBytes (* Any int measure that counts bytes. *)
4185 | FUUID (* 32 bytes long, NOT nul-terminated. *)
4186 | FOptPercent (* [0..100], or -1 meaning "not present". *)
4188 (* Because we generate extra parsing code for LVM command line tools,
4189 * we have to pull out the LVM columns separately here.
4199 "pv_attr", FString (* XXX *);
4200 "pv_pe_count", FInt64;
4201 "pv_pe_alloc_count", FInt64;
4204 "pv_mda_count", FInt64;
4205 "pv_mda_free", FBytes;
4206 (* Not in Fedora 10:
4207 "pv_mda_size", FBytes;
4214 "vg_attr", FString (* XXX *);
4217 "vg_sysid", FString;
4218 "vg_extent_size", FBytes;
4219 "vg_extent_count", FInt64;
4220 "vg_free_count", FInt64;
4225 "snap_count", FInt64;
4228 "vg_mda_count", FInt64;
4229 "vg_mda_free", FBytes;
4230 (* Not in Fedora 10:
4231 "vg_mda_size", FBytes;
4237 "lv_attr", FString (* XXX *);
4240 "lv_kernel_major", FInt64;
4241 "lv_kernel_minor", FInt64;
4243 "seg_count", FInt64;
4245 "snap_percent", FOptPercent;
4246 "copy_percent", FOptPercent;
4249 "mirror_log", FString;
4253 (* Names and fields in all structures (in RStruct and RStructList)
4257 (* The old RIntBool return type, only ever used for aug_defnode. Do
4258 * not use this struct in any new code.
4261 "i", FInt32; (* for historical compatibility *)
4262 "b", FInt32; (* for historical compatibility *)
4265 (* LVM PVs, VGs, LVs. *)
4266 "lvm_pv", lvm_pv_cols;
4267 "lvm_vg", lvm_vg_cols;
4268 "lvm_lv", lvm_lv_cols;
4270 (* Column names and types from stat structures.
4271 * NB. Can't use things like 'st_atime' because glibc header files
4272 * define some of these as macros. Ugh.
4303 (* Column names in dirent structure. *)
4306 (* 'b' 'c' 'd' 'f' (FIFO) 'l' 'r' (regular file) 's' 'u' '?' *)
4311 (* Version numbers. *)
4319 (* Extended attribute. *)
4321 "attrname", FString;
4325 (* Inotify events. *)
4329 "in_cookie", FUInt32;
4333 (* Partition table entry. *)
4336 "part_start", FBytes;
4338 "part_size", FBytes;
4340 ] (* end of structs *)
4342 (* Ugh, Java has to be different ..
4343 * These names are also used by the Haskell bindings.
4345 let java_structs = [
4346 "int_bool", "IntBool";
4351 "statvfs", "StatVFS";
4353 "version", "Version";
4355 "inotify_event", "INotifyEvent";
4356 "partition", "Partition";
4359 (* What structs are actually returned. *)
4360 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList
4362 (* Returns a list of RStruct/RStructList structs that are returned
4363 * by any function. Each element of returned list is a pair:
4365 * (structname, RStructOnly)
4366 * == there exists function which returns RStruct (_, structname)
4367 * (structname, RStructListOnly)
4368 * == there exists function which returns RStructList (_, structname)
4369 * (structname, RStructAndList)
4370 * == there are functions returning both RStruct (_, structname)
4371 * and RStructList (_, structname)
4373 let rstructs_used_by functions =
4374 (* ||| is a "logical OR" for rstructs_used_t *)
4378 | _, RStructAndList -> RStructAndList
4379 | RStructOnly, RStructListOnly
4380 | RStructListOnly, RStructOnly -> RStructAndList
4381 | RStructOnly, RStructOnly -> RStructOnly
4382 | RStructListOnly, RStructListOnly -> RStructListOnly
4385 let h = Hashtbl.create 13 in
4387 (* if elem->oldv exists, update entry using ||| operator,
4388 * else just add elem->newv to the hash
4390 let update elem newv =
4391 try let oldv = Hashtbl.find h elem in
4392 Hashtbl.replace h elem (newv ||| oldv)
4393 with Not_found -> Hashtbl.add h elem newv
4397 fun (_, style, _, _, _, _, _) ->
4398 match fst style with
4399 | RStruct (_, structname) -> update structname RStructOnly
4400 | RStructList (_, structname) -> update structname RStructListOnly
4404 (* return key->values as a list of (key,value) *)
4405 Hashtbl.fold (fun key value xs -> (key, value) :: xs) h []
4407 (* Used for testing language bindings. *)
4409 | CallString of string
4410 | CallOptString of string option
4411 | CallStringList of string list
4413 | CallInt64 of int64
4416 (* Used to memoize the result of pod2text. *)
4417 let pod2text_memo_filename = "src/.pod2text.data"
4418 let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
4420 let chan = open_in pod2text_memo_filename in
4421 let v = input_value chan in
4425 _ -> Hashtbl.create 13
4426 let pod2text_memo_updated () =
4427 let chan = open_out pod2text_memo_filename in
4428 output_value chan pod2text_memo;
4431 (* Useful functions.
4432 * Note we don't want to use any external OCaml libraries which
4433 * makes this a bit harder than it should be.
4435 let failwithf fs = ksprintf failwith fs
4437 let replace_char s c1 c2 =
4438 let s2 = String.copy s in
4439 let r = ref false in
4440 for i = 0 to String.length s2 - 1 do
4441 if String.unsafe_get s2 i = c1 then (
4442 String.unsafe_set s2 i c2;
4446 if not !r then s else s2
4450 (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
4452 let triml ?(test = isspace) str =
4454 let n = ref (String.length str) in
4455 while !n > 0 && test str.[!i]; do
4460 else String.sub str !i !n
4462 let trimr ?(test = isspace) str =
4463 let n = ref (String.length str) in
4464 while !n > 0 && test str.[!n-1]; do
4467 if !n = String.length str then str
4468 else String.sub str 0 !n
4470 let trim ?(test = isspace) str =
4471 trimr ~test (triml ~test str)
4473 let rec find s sub =
4474 let len = String.length s in
4475 let sublen = String.length sub in
4477 if i <= len-sublen then (
4479 if j < sublen then (
4480 if s.[i+j] = sub.[j] then loop2 (j+1)
4486 if r = -1 then loop (i+1) else r
4492 let rec replace_str s s1 s2 =
4493 let len = String.length s in
4494 let sublen = String.length s1 in
4495 let i = find s s1 in
4498 let s' = String.sub s 0 i in
4499 let s'' = String.sub s (i+sublen) (len-i-sublen) in
4500 s' ^ s2 ^ replace_str s'' s1 s2
4503 let rec string_split sep str =
4504 let len = String.length str in
4505 let seplen = String.length sep in
4506 let i = find str sep in
4507 if i = -1 then [str]
4509 let s' = String.sub str 0 i in
4510 let s'' = String.sub str (i+seplen) (len-i-seplen) in
4511 s' :: string_split sep s''
4514 let files_equal n1 n2 =
4515 let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
4516 match Sys.command cmd with
4519 | i -> failwithf "%s: failed with error code %d" cmd i
4521 let rec filter_map f = function
4525 | Some y -> y :: filter_map f xs
4526 | None -> filter_map f xs
4528 let rec find_map f = function
4529 | [] -> raise Not_found
4533 | None -> find_map f xs
4536 let rec loop i = function
4538 | x :: xs -> f i x; loop (i+1) xs
4543 let rec loop i = function
4545 | x :: xs -> let r = f i x in r :: loop (i+1) xs
4549 let name_of_argt = function
4550 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
4551 | StringList n | DeviceList n | Bool n | Int n | Int64 n
4552 | FileIn n | FileOut n -> n
4554 let java_name_of_struct typ =
4555 try List.assoc typ java_structs
4558 "java_name_of_struct: no java_structs entry corresponding to %s" typ
4560 let cols_of_struct typ =
4561 try List.assoc typ structs
4563 failwithf "cols_of_struct: unknown struct %s" typ
4565 let seq_of_test = function
4566 | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
4567 | TestOutputListOfDevices (s, _)
4568 | TestOutputInt (s, _) | TestOutputIntOp (s, _, _)
4569 | TestOutputTrue s | TestOutputFalse s
4570 | TestOutputLength (s, _) | TestOutputBuffer (s, _)
4571 | TestOutputStruct (s, _)
4572 | TestLastFail s -> s
4574 (* Handling for function flags. *)
4575 let protocol_limit_warning =
4576 "Because of the message protocol, there is a transfer limit
4577 of somewhere between 2MB and 4MB. To transfer large files you should use
4580 let danger_will_robinson =
4581 "B<This command is dangerous. Without careful use you
4582 can easily destroy all your data>."
4584 let deprecation_notice flags =
4587 find_map (function DeprecatedBy str -> Some str | _ -> None) flags in
4589 sprintf "This function is deprecated.
4590 In new code, use the C<%s> call instead.
4592 Deprecated functions will not be removed from the API, but the
4593 fact that they are deprecated indicates that there are problems
4594 with correct use of these functions." alt in
4599 (* Check function names etc. for consistency. *)
4600 let check_functions () =
4601 let contains_uppercase str =
4602 let len = String.length str in
4604 if i >= len then false
4607 if c >= 'A' && c <= 'Z' then true
4614 (* Check function names. *)
4616 fun (name, _, _, _, _, _, _) ->
4617 if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
4618 failwithf "function name %s does not need 'guestfs' prefix" name;
4620 failwithf "function name is empty";
4621 if name.[0] < 'a' || name.[0] > 'z' then
4622 failwithf "function name %s must start with lowercase a-z" name;
4623 if String.contains name '-' then
4624 failwithf "function name %s should not contain '-', use '_' instead."
4628 (* Check function parameter/return names. *)
4630 fun (name, style, _, _, _, _, _) ->
4631 let check_arg_ret_name n =
4632 if contains_uppercase n then
4633 failwithf "%s param/ret %s should not contain uppercase chars"
4635 if String.contains n '-' || String.contains n '_' then
4636 failwithf "%s param/ret %s should not contain '-' or '_'"
4639 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;
4640 if n = "int" || n = "char" || n = "short" || n = "long" then
4641 failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
4642 if n = "i" || n = "n" then
4643 failwithf "%s has a param/ret called 'i' or 'n', which will cause some conflicts in the generated code" name;
4644 if n = "argv" || n = "args" then
4645 failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name;
4647 (* List Haskell, OCaml and C keywords here.
4648 * http://www.haskell.org/haskellwiki/Keywords
4649 * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#operator-char
4650 * http://en.wikipedia.org/wiki/C_syntax#Reserved_keywords
4651 * Formatted via: cat c haskell ocaml|sort -u|grep -vE '_|^val$' \
4652 * |perl -pe 's/(.+)/"$1";/'|fmt -70
4653 * Omitting _-containing words, since they're handled above.
4654 * Omitting the OCaml reserved word, "val", is ok,
4655 * and saves us from renaming several parameters.
4658 "and"; "as"; "asr"; "assert"; "auto"; "begin"; "break"; "case";
4659 "char"; "class"; "const"; "constraint"; "continue"; "data";
4660 "default"; "deriving"; "do"; "done"; "double"; "downto"; "else";
4661 "end"; "enum"; "exception"; "extern"; "external"; "false"; "float";
4662 "for"; "forall"; "foreign"; "fun"; "function"; "functor"; "goto";
4663 "hiding"; "if"; "import"; "in"; "include"; "infix"; "infixl";
4664 "infixr"; "inherit"; "initializer"; "inline"; "instance"; "int";
4665 "land"; "lazy"; "let"; "long"; "lor"; "lsl"; "lsr"; "lxor";
4666 "match"; "mdo"; "method"; "mod"; "module"; "mutable"; "new";
4667 "newtype"; "object"; "of"; "open"; "or"; "private"; "qualified";
4668 "rec"; "register"; "restrict"; "return"; "short"; "sig"; "signed";
4669 "sizeof"; "static"; "struct"; "switch"; "then"; "to"; "true"; "try";
4670 "type"; "typedef"; "union"; "unsigned"; "virtual"; "void";
4671 "volatile"; "when"; "where"; "while";
4673 if List.mem n reserved then
4674 failwithf "%s has param/ret using reserved word %s" name n;
4677 (match fst style with
4679 | RInt n | RInt64 n | RBool n
4680 | RConstString n | RConstOptString n | RString n
4681 | RStringList n | RStruct (n, _) | RStructList (n, _)
4682 | RHashtable n | RBufferOut n ->
4683 check_arg_ret_name n
4685 List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
4688 (* Check short descriptions. *)
4690 fun (name, _, _, _, _, shortdesc, _) ->
4691 if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
4692 failwithf "short description of %s should begin with lowercase." name;
4693 let c = shortdesc.[String.length shortdesc-1] in
4694 if c = '\n' || c = '.' then
4695 failwithf "short description of %s should not end with . or \\n." name
4698 (* Check long dscriptions. *)
4700 fun (name, _, _, _, _, _, longdesc) ->
4701 if longdesc.[String.length longdesc-1] = '\n' then
4702 failwithf "long description of %s should not end with \\n." name
4705 (* Check proc_nrs. *)
4707 fun (name, _, proc_nr, _, _, _, _) ->
4708 if proc_nr <= 0 then
4709 failwithf "daemon function %s should have proc_nr > 0" name
4713 fun (name, _, proc_nr, _, _, _, _) ->
4714 if proc_nr <> -1 then
4715 failwithf "non-daemon function %s should have proc_nr -1" name
4716 ) non_daemon_functions;
4719 List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
4722 List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
4723 let rec loop = function
4726 | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
4728 | (name1,nr1) :: (name2,nr2) :: _ ->
4729 failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
4737 (* Ignore functions that have no tests. We generate a
4738 * warning when the user does 'make check' instead.
4740 | name, _, _, _, [], _, _ -> ()
4741 | name, _, _, _, tests, _, _ ->
4745 match seq_of_test test with
4747 failwithf "%s has a test containing an empty sequence" name
4748 | cmds -> List.map List.hd cmds
4750 let funcs = List.flatten funcs in
4752 let tested = List.mem name funcs in
4755 failwithf "function %s has tests but does not test itself" name
4758 (* 'pr' prints to the current output file. *)
4759 let chan = ref Pervasives.stdout
4760 let pr fs = ksprintf (output_string !chan) fs
4762 (* Generate a header block in a number of standard styles. *)
4763 type comment_style = CStyle | HashStyle | OCamlStyle | HaskellStyle
4764 type license = GPLv2 | LGPLv2
4766 let generate_header comment license =
4767 let c = match comment with
4768 | CStyle -> pr "/* "; " *"
4769 | HashStyle -> pr "# "; "#"
4770 | OCamlStyle -> pr "(* "; " *"
4771 | HaskellStyle -> pr "{- "; " " in
4772 pr "libguestfs generated file\n";
4773 pr "%s WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.\n" c;
4774 pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
4776 pr "%s Copyright (C) 2009 Red Hat Inc.\n" c;
4780 pr "%s This program is free software; you can redistribute it and/or modify\n" c;
4781 pr "%s it under the terms of the GNU General Public License as published by\n" c;
4782 pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
4783 pr "%s (at your option) any later version.\n" c;
4785 pr "%s This program is distributed in the hope that it will be useful,\n" c;
4786 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
4787 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" c;
4788 pr "%s GNU General Public License for more details.\n" c;
4790 pr "%s You should have received a copy of the GNU General Public License along\n" c;
4791 pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
4792 pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
4795 pr "%s This library is free software; you can redistribute it and/or\n" c;
4796 pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
4797 pr "%s License as published by the Free Software Foundation; either\n" c;
4798 pr "%s version 2 of the License, or (at your option) any later version.\n" c;
4800 pr "%s This library is distributed in the hope that it will be useful,\n" c;
4801 pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
4802 pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" c;
4803 pr "%s Lesser General Public License for more details.\n" c;
4805 pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
4806 pr "%s License along with this library; if not, write to the Free Software\n" c;
4807 pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
4810 | CStyle -> pr " */\n"
4812 | OCamlStyle -> pr " *)\n"
4813 | HaskellStyle -> pr "-}\n"
4817 (* Start of main code generation functions below this line. *)
4819 (* Generate the pod documentation for the C API. *)
4820 let rec generate_actions_pod () =
4822 fun (shortname, style, _, flags, _, _, longdesc) ->
4823 if not (List.mem NotInDocs flags) then (
4824 let name = "guestfs_" ^ shortname in
4825 pr "=head2 %s\n\n" name;
4827 generate_prototype ~extern:false ~handle:"handle" name style;
4829 pr "%s\n\n" longdesc;
4830 (match fst style with
4832 pr "This function returns 0 on success or -1 on error.\n\n"
4834 pr "On error this function returns -1.\n\n"
4836 pr "On error this function returns -1.\n\n"
4838 pr "This function returns a C truth value on success or -1 on error.\n\n"
4840 pr "This function returns a string, or NULL on error.
4841 The string is owned by the guest handle and must I<not> be freed.\n\n"
4842 | RConstOptString _ ->
4843 pr "This function returns a string which may be NULL.
4844 There is way to return an error from this function.
4845 The string is owned by the guest handle and must I<not> be freed.\n\n"
4847 pr "This function returns a string, or NULL on error.
4848 I<The caller must free the returned string after use>.\n\n"
4850 pr "This function returns a NULL-terminated array of strings
4851 (like L<environ(3)>), or NULL if there was an error.
4852 I<The caller must free the strings and the array after use>.\n\n"
4853 | RStruct (_, typ) ->
4854 pr "This function returns a C<struct guestfs_%s *>,
4855 or NULL if there was an error.
4856 I<The caller must call C<guestfs_free_%s> after use>.\n\n" typ typ
4857 | RStructList (_, typ) ->
4858 pr "This function returns a C<struct guestfs_%s_list *>
4859 (see E<lt>guestfs-structs.hE<gt>),
4860 or NULL if there was an error.
4861 I<The caller must call C<guestfs_free_%s_list> after use>.\n\n" typ typ
4863 pr "This function returns a NULL-terminated array of
4864 strings, or NULL if there was an error.
4865 The array of strings will always have length C<2n+1>, where
4866 C<n> keys and values alternate, followed by the trailing NULL entry.
4867 I<The caller must free the strings and the array after use>.\n\n"
4869 pr "This function returns a buffer, or NULL on error.
4870 The size of the returned buffer is written to C<*size_r>.
4871 I<The caller must free the returned buffer after use>.\n\n"
4873 if List.mem ProtocolLimitWarning flags then
4874 pr "%s\n\n" protocol_limit_warning;
4875 if List.mem DangerWillRobinson flags then
4876 pr "%s\n\n" danger_will_robinson;
4877 match deprecation_notice flags with
4879 | Some txt -> pr "%s\n\n" txt
4881 ) all_functions_sorted
4883 and generate_structs_pod () =
4884 (* Structs documentation. *)
4887 pr "=head2 guestfs_%s\n" typ;
4889 pr " struct guestfs_%s {\n" typ;
4892 | name, FChar -> pr " char %s;\n" name
4893 | name, FUInt32 -> pr " uint32_t %s;\n" name
4894 | name, FInt32 -> pr " int32_t %s;\n" name
4895 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
4896 | name, FInt64 -> pr " int64_t %s;\n" name
4897 | name, FString -> pr " char *%s;\n" name
4899 pr " /* The next two fields describe a byte array. */\n";
4900 pr " uint32_t %s_len;\n" name;
4901 pr " char *%s;\n" name
4903 pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
4904 pr " char %s[32];\n" name
4905 | name, FOptPercent ->
4906 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
4907 pr " float %s;\n" name
4911 pr " struct guestfs_%s_list {\n" typ;
4912 pr " uint32_t len; /* Number of elements in list. */\n";
4913 pr " struct guestfs_%s *val; /* Elements. */\n" typ;
4916 pr " void guestfs_free_%s (struct guestfs_free_%s *);\n" typ typ;
4917 pr " void guestfs_free_%s_list (struct guestfs_free_%s_list *);\n"
4922 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
4923 * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
4925 * We have to use an underscore instead of a dash because otherwise
4926 * rpcgen generates incorrect code.
4928 * This header is NOT exported to clients, but see also generate_structs_h.
4930 and generate_xdr () =
4931 generate_header CStyle LGPLv2;
4933 (* This has to be defined to get around a limitation in Sun's rpcgen. *)
4934 pr "typedef string str<>;\n";
4937 (* Internal structures. *)
4941 pr "struct guestfs_int_%s {\n" typ;
4943 | name, FChar -> pr " char %s;\n" name
4944 | name, FString -> pr " string %s<>;\n" name
4945 | name, FBuffer -> pr " opaque %s<>;\n" name
4946 | name, FUUID -> pr " opaque %s[32];\n" name
4947 | name, (FInt32|FUInt32) -> pr " int %s;\n" name
4948 | name, (FInt64|FUInt64|FBytes) -> pr " hyper %s;\n" name
4949 | name, FOptPercent -> pr " float %s;\n" name
4953 pr "typedef struct guestfs_int_%s guestfs_int_%s_list<>;\n" typ typ;
4958 fun (shortname, style, _, _, _, _, _) ->
4959 let name = "guestfs_" ^ shortname in
4961 (match snd style with
4964 pr "struct %s_args {\n" name;
4967 | Pathname n | Device n | Dev_or_Path n | String n ->
4968 pr " string %s<>;\n" n
4969 | OptString n -> pr " str *%s;\n" n
4970 | StringList n | DeviceList n -> pr " str %s<>;\n" n
4971 | Bool n -> pr " bool %s;\n" n
4972 | Int n -> pr " int %s;\n" n
4973 | Int64 n -> pr " hyper %s;\n" n
4974 | FileIn _ | FileOut _ -> ()
4978 (match fst style with
4981 pr "struct %s_ret {\n" name;
4985 pr "struct %s_ret {\n" name;
4986 pr " hyper %s;\n" n;
4989 pr "struct %s_ret {\n" name;
4992 | RConstString _ | RConstOptString _ ->
4993 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
4995 pr "struct %s_ret {\n" name;
4996 pr " string %s<>;\n" n;
4999 pr "struct %s_ret {\n" name;
5000 pr " str %s<>;\n" n;
5002 | RStruct (n, typ) ->
5003 pr "struct %s_ret {\n" name;
5004 pr " guestfs_int_%s %s;\n" typ n;
5006 | RStructList (n, typ) ->
5007 pr "struct %s_ret {\n" name;
5008 pr " guestfs_int_%s_list %s;\n" typ n;
5011 pr "struct %s_ret {\n" name;
5012 pr " str %s<>;\n" n;
5015 pr "struct %s_ret {\n" name;
5016 pr " opaque %s<>;\n" n;
5021 (* Table of procedure numbers. *)
5022 pr "enum guestfs_procedure {\n";
5024 fun (shortname, _, proc_nr, _, _, _, _) ->
5025 pr " GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
5027 pr " GUESTFS_PROC_NR_PROCS\n";
5031 (* Having to choose a maximum message size is annoying for several
5032 * reasons (it limits what we can do in the API), but it (a) makes
5033 * the protocol a lot simpler, and (b) provides a bound on the size
5034 * of the daemon which operates in limited memory space. For large
5035 * file transfers you should use FTP.
5037 pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
5040 (* Message header, etc. *)
5042 /* The communication protocol is now documented in the guestfs(3)
5046 const GUESTFS_PROGRAM = 0x2000F5F5;
5047 const GUESTFS_PROTOCOL_VERSION = 1;
5049 /* These constants must be larger than any possible message length. */
5050 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
5051 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
5053 enum guestfs_message_direction {
5054 GUESTFS_DIRECTION_CALL = 0, /* client -> daemon */
5055 GUESTFS_DIRECTION_REPLY = 1 /* daemon -> client */
5058 enum guestfs_message_status {
5059 GUESTFS_STATUS_OK = 0,
5060 GUESTFS_STATUS_ERROR = 1
5063 const GUESTFS_ERROR_LEN = 256;
5065 struct guestfs_message_error {
5066 string error_message<GUESTFS_ERROR_LEN>;
5069 struct guestfs_message_header {
5070 unsigned prog; /* GUESTFS_PROGRAM */
5071 unsigned vers; /* GUESTFS_PROTOCOL_VERSION */
5072 guestfs_procedure proc; /* GUESTFS_PROC_x */
5073 guestfs_message_direction direction;
5074 unsigned serial; /* message serial number */
5075 guestfs_message_status status;
5078 const GUESTFS_MAX_CHUNK_SIZE = 8192;
5080 struct guestfs_chunk {
5081 int cancel; /* if non-zero, transfer is cancelled */
5082 /* data size is 0 bytes if the transfer has finished successfully */
5083 opaque data<GUESTFS_MAX_CHUNK_SIZE>;
5087 (* Generate the guestfs-structs.h file. *)
5088 and generate_structs_h () =
5089 generate_header CStyle LGPLv2;
5091 (* This is a public exported header file containing various
5092 * structures. The structures are carefully written to have
5093 * exactly the same in-memory format as the XDR structures that
5094 * we use on the wire to the daemon. The reason for creating
5095 * copies of these structures here is just so we don't have to
5096 * export the whole of guestfs_protocol.h (which includes much
5097 * unrelated and XDR-dependent stuff that we don't want to be
5098 * public, or required by clients).
5100 * To reiterate, we will pass these structures to and from the
5101 * client with a simple assignment or memcpy, so the format
5102 * must be identical to what rpcgen / the RFC defines.
5105 (* Public structures. *)
5108 pr "struct guestfs_%s {\n" typ;
5111 | name, FChar -> pr " char %s;\n" name
5112 | name, FString -> pr " char *%s;\n" name
5114 pr " uint32_t %s_len;\n" name;
5115 pr " char *%s;\n" name
5116 | name, FUUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
5117 | name, FUInt32 -> pr " uint32_t %s;\n" name
5118 | name, FInt32 -> pr " int32_t %s;\n" name
5119 | name, (FUInt64|FBytes) -> pr " uint64_t %s;\n" name
5120 | name, FInt64 -> pr " int64_t %s;\n" name
5121 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
5125 pr "struct guestfs_%s_list {\n" typ;
5126 pr " uint32_t len;\n";
5127 pr " struct guestfs_%s *val;\n" typ;
5130 pr "extern void guestfs_free_%s (struct guestfs_%s *);\n" typ typ;
5131 pr "extern void guestfs_free_%s_list (struct guestfs_%s_list *);\n" typ typ;
5135 (* Generate the guestfs-actions.h file. *)
5136 and generate_actions_h () =
5137 generate_header CStyle LGPLv2;
5139 fun (shortname, style, _, _, _, _, _) ->
5140 let name = "guestfs_" ^ shortname in
5141 generate_prototype ~single_line:true ~newline:true ~handle:"handle"
5145 (* Generate the guestfs-internal-actions.h file. *)
5146 and generate_internal_actions_h () =
5147 generate_header CStyle LGPLv2;
5149 fun (shortname, style, _, _, _, _, _) ->
5150 let name = "guestfs__" ^ shortname in
5151 generate_prototype ~single_line:true ~newline:true ~handle:"handle"
5153 ) non_daemon_functions
5155 (* Generate the client-side dispatch stubs. *)
5156 and generate_client_actions () =
5157 generate_header CStyle LGPLv2;
5163 #include <inttypes.h>
5165 #include \"guestfs.h\"
5166 #include \"guestfs-internal.h\"
5167 #include \"guestfs-internal-actions.h\"
5168 #include \"guestfs_protocol.h\"
5170 #define error guestfs_error
5171 //#define perrorf guestfs_perrorf
5172 #define safe_malloc guestfs_safe_malloc
5173 #define safe_realloc guestfs_safe_realloc
5174 //#define safe_strdup guestfs_safe_strdup
5175 #define safe_memdup guestfs_safe_memdup
5177 /* Check the return message from a call for validity. */
5179 check_reply_header (guestfs_h *g,
5180 const struct guestfs_message_header *hdr,
5181 unsigned int proc_nr, unsigned int serial)
5183 if (hdr->prog != GUESTFS_PROGRAM) {
5184 error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
5187 if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
5188 error (g, \"wrong protocol version (%%d/%%d)\",
5189 hdr->vers, GUESTFS_PROTOCOL_VERSION);
5192 if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
5193 error (g, \"unexpected message direction (%%d/%%d)\",
5194 hdr->direction, GUESTFS_DIRECTION_REPLY);
5197 if (hdr->proc != proc_nr) {
5198 error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
5201 if (hdr->serial != serial) {
5202 error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
5209 /* Check we are in the right state to run a high-level action. */
5211 check_state (guestfs_h *g, const char *caller)
5213 if (!guestfs__is_ready (g)) {
5214 if (guestfs__is_config (g) || guestfs__is_launching (g))
5215 error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\",
5218 error (g, \"%%s called from the wrong state, %%d != READY\",
5219 caller, guestfs__get_state (g));
5227 (* Generate code to generate guestfish call traces. *)
5228 let trace_call shortname style =
5229 pr " if (guestfs__get_trace (g)) {\n";
5232 List.exists (function
5233 | StringList _ | DeviceList _ -> true
5234 | _ -> false) (snd style) in
5240 pr " printf (\"%s\");\n" shortname;
5243 | String n (* strings *)
5249 (* guestfish doesn't support string escaping, so neither do we *)
5250 pr " printf (\" \\\"%%s\\\"\", %s);\n" n
5251 | OptString n -> (* string option *)
5252 pr " if (%s) printf (\" \\\"%%s\\\"\", %s);\n" n n;
5253 pr " else printf (\" null\");\n"
5255 | DeviceList n -> (* string list *)
5256 pr " putchar (' ');\n";
5257 pr " putchar ('\"');\n";
5258 pr " for (i = 0; %s[i]; ++i) {\n" n;
5259 pr " if (i > 0) putchar (' ');\n";
5260 pr " fputs (%s[i], stdout);\n" n;
5262 pr " putchar ('\"');\n";
5263 | Bool n -> (* boolean *)
5264 pr " fputs (%s ? \" true\" : \" false\", stdout);\n" n
5265 | Int n -> (* int *)
5266 pr " printf (\" %%d\", %s);\n" n
5268 pr " printf (\" %%\" PRIi64, %s);\n" n
5270 pr " putchar ('\\n');\n";
5275 (* For non-daemon functions, generate a wrapper around each function. *)
5277 fun (shortname, style, _, _, _, _, _) ->
5278 let name = "guestfs_" ^ shortname in
5280 generate_prototype ~extern:false ~semicolon:false ~newline:true
5281 ~handle:"g" name style;
5283 trace_call shortname style;
5284 pr " return guestfs__%s " shortname;
5285 generate_c_call_args ~handle:"g" style;
5289 ) non_daemon_functions;
5291 (* Client-side stubs for each function. *)
5293 fun (shortname, style, _, _, _, _, _) ->
5294 let name = "guestfs_" ^ shortname in
5296 (* Generate the action stub. *)
5297 generate_prototype ~extern:false ~semicolon:false ~newline:true
5298 ~handle:"g" name style;
5301 match fst style with
5302 | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
5303 | RConstString _ | RConstOptString _ ->
5304 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5305 | RString _ | RStringList _
5306 | RStruct _ | RStructList _
5307 | RHashtable _ | RBufferOut _ ->
5312 (match snd style with
5314 | _ -> pr " struct %s_args args;\n" name
5317 pr " guestfs_message_header hdr;\n";
5318 pr " guestfs_message_error err;\n";
5320 match fst style with
5322 | RConstString _ | RConstOptString _ ->
5323 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5325 | RBool _ | RString _ | RStringList _
5326 | RStruct _ | RStructList _
5327 | RHashtable _ | RBufferOut _ ->
5328 pr " struct %s_ret ret;\n" name;
5331 pr " int serial;\n";
5334 trace_call shortname style;
5335 pr " if (check_state (g, \"%s\") == -1) return %s;\n" name error_code;
5336 pr " guestfs___set_busy (g);\n";
5339 (* Send the main header and arguments. *)
5340 (match snd style with
5342 pr " serial = guestfs___send (g, GUESTFS_PROC_%s, NULL, NULL);\n"
5343 (String.uppercase shortname)
5347 | Pathname n | Device n | Dev_or_Path n | String n ->
5348 pr " args.%s = (char *) %s;\n" n n
5350 pr " args.%s = %s ? (char **) &%s : NULL;\n" n n n
5351 | StringList n | DeviceList n ->
5352 pr " args.%s.%s_val = (char **) %s;\n" n n n;
5353 pr " for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
5355 pr " args.%s = %s;\n" n n
5357 pr " args.%s = %s;\n" n n
5359 pr " args.%s = %s;\n" n n
5360 | FileIn _ | FileOut _ -> ()
5362 pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
5363 (String.uppercase shortname);
5364 pr " (xdrproc_t) xdr_%s_args, (char *) &args);\n"
5367 pr " if (serial == -1) {\n";
5368 pr " guestfs___end_busy (g);\n";
5369 pr " return %s;\n" error_code;
5373 (* Send any additional files (FileIn) requested. *)
5374 let need_read_reply_label = ref false in
5378 pr " r = guestfs___send_file (g, %s);\n" n;
5379 pr " if (r == -1) {\n";
5380 pr " guestfs___end_busy (g);\n";
5381 pr " return %s;\n" error_code;
5383 pr " if (r == -2) /* daemon cancelled */\n";
5384 pr " goto read_reply;\n";
5385 need_read_reply_label := true;
5390 (* Wait for the reply from the remote end. *)
5391 if !need_read_reply_label then pr " read_reply:\n";
5392 pr " memset (&hdr, 0, sizeof hdr);\n";
5393 pr " memset (&err, 0, sizeof err);\n";
5394 if has_ret then pr " memset (&ret, 0, sizeof ret);\n";
5396 pr " r = guestfs___recv (g, \"%s\", &hdr, &err,\n " shortname;
5400 pr "(xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret" shortname;
5403 pr " if (r == -1) {\n";
5404 pr " guestfs___end_busy (g);\n";
5405 pr " return %s;\n" error_code;
5409 pr " if (check_reply_header (g, &hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
5410 (String.uppercase shortname);
5411 pr " guestfs___end_busy (g);\n";
5412 pr " return %s;\n" error_code;
5416 pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
5417 pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
5418 pr " free (err.error_message);\n";
5419 pr " guestfs___end_busy (g);\n";
5420 pr " return %s;\n" error_code;
5424 (* Expecting to receive further files (FileOut)? *)
5428 pr " if (guestfs___recv_file (g, %s) == -1) {\n" n;
5429 pr " guestfs___end_busy (g);\n";
5430 pr " return %s;\n" error_code;
5436 pr " guestfs___end_busy (g);\n";
5438 (match fst style with
5439 | RErr -> pr " return 0;\n"
5440 | RInt n | RInt64 n | RBool n ->
5441 pr " return ret.%s;\n" n
5442 | RConstString _ | RConstOptString _ ->
5443 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5445 pr " return ret.%s; /* caller will free */\n" n
5446 | RStringList n | RHashtable n ->
5447 pr " /* caller will free this, but we need to add a NULL entry */\n";
5448 pr " ret.%s.%s_val =\n" n n;
5449 pr " safe_realloc (g, ret.%s.%s_val,\n" n n;
5450 pr " sizeof (char *) * (ret.%s.%s_len + 1));\n"
5452 pr " ret.%s.%s_val[ret.%s.%s_len] = NULL;\n" n n n n;
5453 pr " return ret.%s.%s_val;\n" n n
5455 pr " /* caller will free this */\n";
5456 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
5457 | RStructList (n, _) ->
5458 pr " /* caller will free this */\n";
5459 pr " return safe_memdup (g, &ret.%s, sizeof (ret.%s));\n" n n
5461 pr " /* RBufferOut is tricky: If the buffer is zero-length, then\n";
5462 pr " * _val might be NULL here. To make the API saner for\n";
5463 pr " * callers, we turn this case into a unique pointer (using\n";
5464 pr " * malloc(1)).\n";
5466 pr " if (ret.%s.%s_len > 0) {\n" n n;
5467 pr " *size_r = ret.%s.%s_len;\n" n n;
5468 pr " return ret.%s.%s_val; /* caller will free */\n" n n;
5470 pr " free (ret.%s.%s_val);\n" n n;
5471 pr " char *p = safe_malloc (g, 1);\n";
5472 pr " *size_r = ret.%s.%s_len;\n" n n;
5480 (* Functions to free structures. *)
5481 pr "/* Structure-freeing functions. These rely on the fact that the\n";
5482 pr " * structure format is identical to the XDR format. See note in\n";
5483 pr " * generator.ml.\n";
5490 pr "guestfs_free_%s (struct guestfs_%s *x)\n" typ typ;
5492 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
5498 pr "guestfs_free_%s_list (struct guestfs_%s_list *x)\n" typ typ;
5500 pr " xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n" typ;
5507 (* Generate daemon/actions.h. *)
5508 and generate_daemon_actions_h () =
5509 generate_header CStyle GPLv2;
5511 pr "#include \"../src/guestfs_protocol.h\"\n";
5515 fun (name, style, _, _, _, _, _) ->
5517 ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
5521 (* Generate the server-side stubs. *)
5522 and generate_daemon_actions () =
5523 generate_header CStyle GPLv2;
5525 pr "#include <config.h>\n";
5527 pr "#include <stdio.h>\n";
5528 pr "#include <stdlib.h>\n";
5529 pr "#include <string.h>\n";
5530 pr "#include <inttypes.h>\n";
5531 pr "#include <rpc/types.h>\n";
5532 pr "#include <rpc/xdr.h>\n";
5534 pr "#include \"daemon.h\"\n";
5535 pr "#include \"c-ctype.h\"\n";
5536 pr "#include \"../src/guestfs_protocol.h\"\n";
5537 pr "#include \"actions.h\"\n";
5541 fun (name, style, _, _, _, _, _) ->
5542 (* Generate server-side stubs. *)
5543 pr "static void %s_stub (XDR *xdr_in)\n" name;
5546 match fst style with
5547 | RErr | RInt _ -> pr " int r;\n"; "-1"
5548 | RInt64 _ -> pr " int64_t r;\n"; "-1"
5549 | RBool _ -> pr " int r;\n"; "-1"
5550 | RConstString _ | RConstOptString _ ->
5551 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5552 | RString _ -> pr " char *r;\n"; "NULL"
5553 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
5554 | RStruct (_, typ) -> pr " guestfs_int_%s *r;\n" typ; "NULL"
5555 | RStructList (_, typ) -> pr " guestfs_int_%s_list *r;\n" typ; "NULL"
5557 pr " size_t size = 1;\n";
5561 (match snd style with
5564 pr " struct guestfs_%s_args args;\n" name;
5567 | Device n | Dev_or_Path n
5570 | OptString n -> pr " char *%s;\n" n
5571 | StringList n | DeviceList n -> pr " char **%s;\n" n
5572 | Bool n -> pr " int %s;\n" n
5573 | Int n -> pr " int %s;\n" n
5574 | Int64 n -> pr " int64_t %s;\n" n
5575 | FileIn _ | FileOut _ -> ()
5580 (match snd style with
5583 pr " memset (&args, 0, sizeof args);\n";
5585 pr " if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
5586 pr " reply_with_error (\"%%s: daemon failed to decode procedure arguments\", \"%s\");\n" name;
5590 pr " char *%s = args.%s;\n" n n
5592 let pr_list_handling_code n =
5593 pr " %s = realloc (args.%s.%s_val,\n" n n n;
5594 pr " sizeof (char *) * (args.%s.%s_len+1));\n" n n;
5595 pr " if (%s == NULL) {\n" n;
5596 pr " reply_with_perror (\"realloc\");\n";
5599 pr " %s[args.%s.%s_len] = NULL;\n" n n n;
5600 pr " args.%s.%s_val = %s;\n" n n n;
5606 pr " ABS_PATH (%s, goto done);\n" n;
5609 pr " RESOLVE_DEVICE (%s, goto done);\n" n;
5612 pr " REQUIRE_ROOT_OR_RESOLVE_DEVICE (%s, goto done);\n" n;
5613 | String n -> pr_args n
5614 | OptString n -> pr " %s = args.%s ? *args.%s : NULL;\n" n n n
5616 pr_list_handling_code n;
5618 pr_list_handling_code n;
5619 pr " /* Ensure that each is a device,\n";
5620 pr " * and perform device name translation. */\n";
5621 pr " { int pvi; for (pvi = 0; physvols[pvi] != NULL; ++pvi)\n";
5622 pr " RESOLVE_DEVICE (physvols[pvi], goto done);\n";
5624 | Bool n -> pr " %s = args.%s;\n" n n
5625 | Int n -> pr " %s = args.%s;\n" n n
5626 | Int64 n -> pr " %s = args.%s;\n" n n
5627 | FileIn _ | FileOut _ -> ()
5633 (* this is used at least for do_equal *)
5634 if List.exists (function Pathname _ -> true | _ -> false) (snd style) then (
5635 (* Emit NEED_ROOT just once, even when there are two or
5636 more Pathname args *)
5637 pr " NEED_ROOT (goto done);\n";
5640 (* Don't want to call the impl with any FileIn or FileOut
5641 * parameters, since these go "outside" the RPC protocol.
5644 List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
5646 pr " r = do_%s " name;
5647 generate_c_call_args (fst style, args');
5650 (match fst style with
5651 | RErr | RInt _ | RInt64 _ | RBool _
5652 | RConstString _ | RConstOptString _
5653 | RString _ | RStringList _ | RHashtable _
5654 | RStruct (_, _) | RStructList (_, _) ->
5655 pr " if (r == %s)\n" error_code;
5656 pr " /* do_%s has already called reply_with_error */\n" name;
5660 pr " /* size == 0 && r == NULL could be a non-error case (just\n";
5661 pr " * an ordinary zero-length buffer), so be careful ...\n";
5663 pr " if (size == 1 && r == %s)\n" error_code;
5664 pr " /* do_%s has already called reply_with_error */\n" name;
5669 (* If there are any FileOut parameters, then the impl must
5670 * send its own reply.
5673 List.exists (function FileOut _ -> true | _ -> false) (snd style) in
5675 pr " /* do_%s has already sent a reply */\n" name
5677 match fst style with
5678 | RErr -> pr " reply (NULL, NULL);\n"
5679 | RInt n | RInt64 n | RBool n ->
5680 pr " struct guestfs_%s_ret ret;\n" name;
5681 pr " ret.%s = r;\n" n;
5682 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
5684 | RConstString _ | RConstOptString _ ->
5685 failwithf "RConstString|RConstOptString cannot be used by daemon functions"
5687 pr " struct guestfs_%s_ret ret;\n" name;
5688 pr " ret.%s = r;\n" n;
5689 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
5692 | RStringList n | RHashtable n ->
5693 pr " struct guestfs_%s_ret ret;\n" name;
5694 pr " ret.%s.%s_len = count_strings (r);\n" n n;
5695 pr " ret.%s.%s_val = r;\n" n n;
5696 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
5698 pr " free_strings (r);\n"
5700 pr " struct guestfs_%s_ret ret;\n" name;
5701 pr " ret.%s = *r;\n" n;
5702 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
5704 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
5706 | RStructList (n, _) ->
5707 pr " struct guestfs_%s_ret ret;\n" name;
5708 pr " ret.%s = *r;\n" n;
5709 pr " reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
5711 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
5714 pr " struct guestfs_%s_ret ret;\n" name;
5715 pr " ret.%s.%s_val = r;\n" n n;
5716 pr " ret.%s.%s_len = size;\n" n n;
5717 pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
5722 (* Free the args. *)
5723 (match snd style with
5728 pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
5735 (* Dispatch function. *)
5736 pr "void dispatch_incoming_message (XDR *xdr_in)\n";
5738 pr " switch (proc_nr) {\n";
5741 fun (name, style, _, _, _, _, _) ->
5742 pr " case GUESTFS_PROC_%s:\n" (String.uppercase name);
5743 pr " %s_stub (xdr_in);\n" name;
5748 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";
5753 (* LVM columns and tokenization functions. *)
5754 (* XXX This generates crap code. We should rethink how we
5760 pr "static const char *lvm_%s_cols = \"%s\";\n"
5761 typ (String.concat "," (List.map fst cols));
5764 pr "static int lvm_tokenize_%s (char *str, guestfs_int_lvm_%s *r)\n" typ typ;
5766 pr " char *tok, *p, *next;\n";
5770 pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
5773 pr " if (!str) {\n";
5774 pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
5777 pr " if (!*str || c_isspace (*str)) {\n";
5778 pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
5783 fun (name, coltype) ->
5784 pr " if (!tok) {\n";
5785 pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
5788 pr " p = strchrnul (tok, ',');\n";
5789 pr " if (*p) next = p+1; else next = NULL;\n";
5790 pr " *p = '\\0';\n";
5793 pr " r->%s = strdup (tok);\n" name;
5794 pr " if (r->%s == NULL) {\n" name;
5795 pr " perror (\"strdup\");\n";
5799 pr " for (i = j = 0; i < 32; ++j) {\n";
5800 pr " if (tok[j] == '\\0') {\n";
5801 pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
5803 pr " } else if (tok[j] != '-')\n";
5804 pr " r->%s[i++] = tok[j];\n" name;
5807 pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
5808 pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
5812 pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
5813 pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
5817 pr " if (tok[0] == '\\0')\n";
5818 pr " r->%s = -1;\n" name;
5819 pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
5820 pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
5823 | FBuffer | FInt32 | FUInt32 | FUInt64 | FChar ->
5824 assert false (* can never be an LVM column *)
5826 pr " tok = next;\n";
5829 pr " if (tok != NULL) {\n";
5830 pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
5837 pr "guestfs_int_lvm_%s_list *\n" typ;
5838 pr "parse_command_line_%ss (void)\n" typ;
5840 pr " char *out, *err;\n";
5841 pr " char *p, *pend;\n";
5843 pr " guestfs_int_lvm_%s_list *ret;\n" typ;
5844 pr " void *newp;\n";
5846 pr " ret = malloc (sizeof *ret);\n";
5847 pr " if (!ret) {\n";
5848 pr " reply_with_perror (\"malloc\");\n";
5849 pr " return NULL;\n";
5852 pr " ret->guestfs_int_lvm_%s_list_len = 0;\n" typ;
5853 pr " ret->guestfs_int_lvm_%s_list_val = NULL;\n" typ;
5855 pr " r = command (&out, &err,\n";
5856 pr " \"/sbin/lvm\", \"%ss\",\n" typ;
5857 pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
5858 pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
5859 pr " if (r == -1) {\n";
5860 pr " reply_with_error (\"%%s\", err);\n";
5861 pr " free (out);\n";
5862 pr " free (err);\n";
5863 pr " free (ret);\n";
5864 pr " return NULL;\n";
5867 pr " free (err);\n";
5869 pr " /* Tokenize each line of the output. */\n";
5872 pr " while (p) {\n";
5873 pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
5874 pr " if (pend) {\n";
5875 pr " *pend = '\\0';\n";
5879 pr " while (*p && c_isspace (*p)) /* Skip any leading whitespace. */\n";
5882 pr " if (!*p) { /* Empty line? Skip it. */\n";
5887 pr " /* Allocate some space to store this next entry. */\n";
5888 pr " newp = realloc (ret->guestfs_int_lvm_%s_list_val,\n" typ;
5889 pr " sizeof (guestfs_int_lvm_%s) * (i+1));\n" typ;
5890 pr " if (newp == NULL) {\n";
5891 pr " reply_with_perror (\"realloc\");\n";
5892 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
5893 pr " free (ret);\n";
5894 pr " free (out);\n";
5895 pr " return NULL;\n";
5897 pr " ret->guestfs_int_lvm_%s_list_val = newp;\n" typ;
5899 pr " /* Tokenize the next entry. */\n";
5900 pr " r = lvm_tokenize_%s (p, &ret->guestfs_int_lvm_%s_list_val[i]);\n" typ typ;
5901 pr " if (r == -1) {\n";
5902 pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
5903 pr " free (ret->guestfs_int_lvm_%s_list_val);\n" typ;
5904 pr " free (ret);\n";
5905 pr " free (out);\n";
5906 pr " return NULL;\n";
5913 pr " ret->guestfs_int_lvm_%s_list_len = i;\n" typ;
5915 pr " free (out);\n";
5916 pr " return ret;\n";
5919 ) ["pv", lvm_pv_cols; "vg", lvm_vg_cols; "lv", lvm_lv_cols]
5921 (* Generate a list of function names, for debugging in the daemon.. *)
5922 and generate_daemon_names () =
5923 generate_header CStyle GPLv2;
5925 pr "#include <config.h>\n";
5927 pr "#include \"daemon.h\"\n";
5930 pr "/* This array is indexed by proc_nr. See guestfs_protocol.x. */\n";
5931 pr "const char *function_names[] = {\n";
5933 fun (name, _, proc_nr, _, _, _, _) -> pr " [%d] = \"%s\",\n" proc_nr name
5937 (* Generate the tests. *)
5938 and generate_tests () =
5939 generate_header CStyle GPLv2;
5946 #include <sys/types.h>
5949 #include \"guestfs.h\"
5950 #include \"guestfs-internal.h\"
5952 static guestfs_h *g;
5953 static int suppress_error = 0;
5955 static void print_error (guestfs_h *g, void *data, const char *msg)
5957 if (!suppress_error)
5958 fprintf (stderr, \"%%s\\n\", msg);
5961 /* FIXME: nearly identical code appears in fish.c */
5962 static void print_strings (char *const *argv)
5966 for (argc = 0; argv[argc] != NULL; ++argc)
5967 printf (\"\\t%%s\\n\", argv[argc]);
5971 static void print_table (char const *const *argv)
5975 for (i = 0; argv[i] != NULL; i += 2)
5976 printf (\"%%s: %%s\\n\", argv[i], argv[i+1]);
5982 (* Generate a list of commands which are not tested anywhere. *)
5983 pr "static void no_test_warnings (void)\n";
5986 let hash : (string, bool) Hashtbl.t = Hashtbl.create 13 in
5988 fun (_, _, _, _, tests, _, _) ->
5989 let tests = filter_map (
5991 | (_, (Always|If _|Unless _), test) -> Some test
5992 | (_, Disabled, _) -> None
5994 let seq = List.concat (List.map seq_of_test tests) in
5995 let cmds_tested = List.map List.hd seq in
5996 List.iter (fun cmd -> Hashtbl.replace hash cmd true) cmds_tested
6000 fun (name, _, _, _, _, _, _) ->
6001 if not (Hashtbl.mem hash name) then
6002 pr " fprintf (stderr, \"warning: \\\"guestfs_%s\\\" has no tests\\n\");\n" name
6008 (* Generate the actual tests. Note that we generate the tests
6009 * in reverse order, deliberately, so that (in general) the
6010 * newest tests run first. This makes it quicker and easier to
6015 fun (name, _, _, _, tests, _, _) ->
6016 mapi (generate_one_test name) tests
6017 ) (List.rev all_functions) in
6018 let test_names = List.concat test_names in
6019 let nr_tests = List.length test_names in
6022 int main (int argc, char *argv[])
6025 unsigned long int n_failed = 0;
6026 const char *filename;
6028 int nr_tests, test_num = 0;
6030 setbuf (stdout, NULL);
6032 no_test_warnings ();
6034 g = guestfs_create ();
6036 printf (\"guestfs_create FAILED\\n\");
6037 exit (EXIT_FAILURE);
6040 guestfs_set_error_handler (g, print_error, NULL);
6042 guestfs_set_path (g, \"../appliance\");
6044 filename = \"test1.img\";
6045 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6048 exit (EXIT_FAILURE);
6050 if (lseek (fd, %d, SEEK_SET) == -1) {
6054 exit (EXIT_FAILURE);
6056 if (write (fd, &c, 1) == -1) {
6060 exit (EXIT_FAILURE);
6062 if (close (fd) == -1) {
6065 exit (EXIT_FAILURE);
6067 if (guestfs_add_drive (g, filename) == -1) {
6068 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6069 exit (EXIT_FAILURE);
6072 filename = \"test2.img\";
6073 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6076 exit (EXIT_FAILURE);
6078 if (lseek (fd, %d, SEEK_SET) == -1) {
6082 exit (EXIT_FAILURE);
6084 if (write (fd, &c, 1) == -1) {
6088 exit (EXIT_FAILURE);
6090 if (close (fd) == -1) {
6093 exit (EXIT_FAILURE);
6095 if (guestfs_add_drive (g, filename) == -1) {
6096 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6097 exit (EXIT_FAILURE);
6100 filename = \"test3.img\";
6101 fd = open (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_TRUNC, 0666);
6104 exit (EXIT_FAILURE);
6106 if (lseek (fd, %d, SEEK_SET) == -1) {
6110 exit (EXIT_FAILURE);
6112 if (write (fd, &c, 1) == -1) {
6116 exit (EXIT_FAILURE);
6118 if (close (fd) == -1) {
6121 exit (EXIT_FAILURE);
6123 if (guestfs_add_drive (g, filename) == -1) {
6124 printf (\"guestfs_add_drive %%s FAILED\\n\", filename);
6125 exit (EXIT_FAILURE);
6128 if (guestfs_add_drive_ro (g, \"../images/test.iso\") == -1) {
6129 printf (\"guestfs_add_drive_ro ../images/test.iso FAILED\\n\");
6130 exit (EXIT_FAILURE);
6133 if (guestfs_launch (g) == -1) {
6134 printf (\"guestfs_launch FAILED\\n\");
6135 exit (EXIT_FAILURE);
6138 /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
6141 /* Cancel previous alarm. */
6146 " (500 * 1024 * 1024) (50 * 1024 * 1024) (10 * 1024 * 1024) nr_tests;
6150 pr " test_num++;\n";
6151 pr " printf (\"%%3d/%%3d %s\\n\", test_num, nr_tests);\n" test_name;
6152 pr " if (%s () == -1) {\n" test_name;
6153 pr " printf (\"%s FAILED\\n\");\n" test_name;
6154 pr " n_failed++;\n";
6159 pr " guestfs_close (g);\n";
6160 pr " unlink (\"test1.img\");\n";
6161 pr " unlink (\"test2.img\");\n";
6162 pr " unlink (\"test3.img\");\n";
6165 pr " if (n_failed > 0) {\n";
6166 pr " printf (\"***** %%lu / %%d tests FAILED *****\\n\", n_failed, nr_tests);\n";
6167 pr " exit (EXIT_FAILURE);\n";
6171 pr " exit (EXIT_SUCCESS);\n";
6174 and generate_one_test name i (init, prereq, test) =
6175 let test_name = sprintf "test_%s_%d" name i in
6178 static int %s_skip (void)
6182 str = getenv (\"TEST_ONLY\");
6184 return strstr (str, \"%s\") == NULL;
6185 str = getenv (\"SKIP_%s\");
6186 if (str && STREQ (str, \"1\")) return 1;
6187 str = getenv (\"SKIP_TEST_%s\");
6188 if (str && STREQ (str, \"1\")) return 1;
6192 " test_name name (String.uppercase test_name) (String.uppercase name);
6195 | Disabled | Always -> ()
6196 | If code | Unless code ->
6197 pr "static int %s_prereq (void)\n" test_name;
6205 static int %s (void)
6208 printf (\" %%s skipped (reason: environment variable set)\\n\", \"%s\");
6212 " test_name test_name test_name;
6216 pr " printf (\" %%s skipped (reason: test disabled in generator)\\n\", \"%s\");\n" test_name
6218 pr " if (! %s_prereq ()) {\n" test_name;
6219 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
6223 generate_one_test_body name i test_name init test;
6225 pr " if (%s_prereq ()) {\n" test_name;
6226 pr " printf (\" %%s skipped (reason: test prerequisite)\\n\", \"%s\");\n" test_name;
6230 generate_one_test_body name i test_name init test;
6232 generate_one_test_body name i test_name init test
6240 and generate_one_test_body name i test_name init test =
6242 | InitNone (* XXX at some point, InitNone and InitEmpty became
6243 * folded together as the same thing. Really we should
6244 * make InitNone do nothing at all, but the tests may
6245 * need to be checked to make sure this is OK.
6248 pr " /* InitNone|InitEmpty for %s */\n" test_name;
6249 List.iter (generate_test_command_call test_name)
6250 [["blockdev_setrw"; "/dev/sda"];
6254 pr " /* InitPartition for %s: create /dev/sda1 */\n" test_name;
6255 List.iter (generate_test_command_call test_name)
6256 [["blockdev_setrw"; "/dev/sda"];
6259 ["part_disk"; "/dev/sda"; "mbr"]]
6261 pr " /* InitBasicFS for %s: create ext2 on /dev/sda1 */\n" test_name;
6262 List.iter (generate_test_command_call test_name)
6263 [["blockdev_setrw"; "/dev/sda"];
6266 ["part_disk"; "/dev/sda"; "mbr"];
6267 ["mkfs"; "ext2"; "/dev/sda1"];
6268 ["mount"; "/dev/sda1"; "/"]]
6269 | InitBasicFSonLVM ->
6270 pr " /* InitBasicFSonLVM for %s: create ext2 on /dev/VG/LV */\n"
6272 List.iter (generate_test_command_call test_name)
6273 [["blockdev_setrw"; "/dev/sda"];
6276 ["part_disk"; "/dev/sda"; "mbr"];
6277 ["pvcreate"; "/dev/sda1"];
6278 ["vgcreate"; "VG"; "/dev/sda1"];
6279 ["lvcreate"; "LV"; "VG"; "8"];
6280 ["mkfs"; "ext2"; "/dev/VG/LV"];
6281 ["mount"; "/dev/VG/LV"; "/"]]
6283 pr " /* InitISOFS for %s */\n" test_name;
6284 List.iter (generate_test_command_call test_name)
6285 [["blockdev_setrw"; "/dev/sda"];
6288 ["mount_ro"; "/dev/sdd"; "/"]]
6291 let get_seq_last = function
6293 failwithf "%s: you cannot use [] (empty list) when expecting a command"
6296 let seq = List.rev seq in
6297 List.rev (List.tl seq), List.hd seq
6302 pr " /* TestRun for %s (%d) */\n" name i;
6303 List.iter (generate_test_command_call test_name) seq
6304 | TestOutput (seq, expected) ->
6305 pr " /* TestOutput for %s (%d) */\n" name i;
6306 pr " const char *expected = \"%s\";\n" (c_quote expected);
6307 let seq, last = get_seq_last seq in
6309 pr " if (STRNEQ (r, expected)) {\n";
6310 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
6314 List.iter (generate_test_command_call test_name) seq;
6315 generate_test_command_call ~test test_name last
6316 | TestOutputList (seq, expected) ->
6317 pr " /* TestOutputList for %s (%d) */\n" name i;
6318 let seq, last = get_seq_last seq in
6322 pr " if (!r[%d]) {\n" i;
6323 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
6324 pr " print_strings (r);\n";
6328 pr " const char *expected = \"%s\";\n" (c_quote str);
6329 pr " if (STRNEQ (r[%d], expected)) {\n" i;
6330 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
6335 pr " if (r[%d] != NULL) {\n" (List.length expected);
6336 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
6338 pr " print_strings (r);\n";
6342 List.iter (generate_test_command_call test_name) seq;
6343 generate_test_command_call ~test test_name last
6344 | TestOutputListOfDevices (seq, expected) ->
6345 pr " /* TestOutputListOfDevices for %s (%d) */\n" name i;
6346 let seq, last = get_seq_last seq in
6350 pr " if (!r[%d]) {\n" i;
6351 pr " fprintf (stderr, \"%s: short list returned from command\\n\");\n" test_name;
6352 pr " print_strings (r);\n";
6356 pr " const char *expected = \"%s\";\n" (c_quote str);
6357 pr " r[%d][5] = 's';\n" i;
6358 pr " if (STRNEQ (r[%d], expected)) {\n" i;
6359 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r[%d]);\n" test_name i;
6364 pr " if (r[%d] != NULL) {\n" (List.length expected);
6365 pr " fprintf (stderr, \"%s: extra elements returned from command\\n\");\n"
6367 pr " print_strings (r);\n";
6371 List.iter (generate_test_command_call test_name) seq;
6372 generate_test_command_call ~test test_name last
6373 | TestOutputInt (seq, expected) ->
6374 pr " /* TestOutputInt for %s (%d) */\n" name i;
6375 let seq, last = get_seq_last seq in
6377 pr " if (r != %d) {\n" expected;
6378 pr " fprintf (stderr, \"%s: expected %d but got %%d\\n\","
6384 List.iter (generate_test_command_call test_name) seq;
6385 generate_test_command_call ~test test_name last
6386 | TestOutputIntOp (seq, op, expected) ->
6387 pr " /* TestOutputIntOp for %s (%d) */\n" name i;
6388 let seq, last = get_seq_last seq in
6390 pr " if (! (r %s %d)) {\n" op expected;
6391 pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\","
6392 test_name op expected;
6397 List.iter (generate_test_command_call test_name) seq;
6398 generate_test_command_call ~test test_name last
6399 | TestOutputTrue seq ->
6400 pr " /* TestOutputTrue for %s (%d) */\n" name i;
6401 let seq, last = get_seq_last seq in
6404 pr " fprintf (stderr, \"%s: expected true, got false\\n\");\n"
6409 List.iter (generate_test_command_call test_name) seq;
6410 generate_test_command_call ~test test_name last
6411 | TestOutputFalse seq ->
6412 pr " /* TestOutputFalse for %s (%d) */\n" name i;
6413 let seq, last = get_seq_last seq in
6416 pr " fprintf (stderr, \"%s: expected false, got true\\n\");\n"
6421 List.iter (generate_test_command_call test_name) seq;
6422 generate_test_command_call ~test test_name last
6423 | TestOutputLength (seq, expected) ->
6424 pr " /* TestOutputLength for %s (%d) */\n" name i;
6425 let seq, last = get_seq_last seq in
6428 pr " for (j = 0; j < %d; ++j)\n" expected;
6429 pr " if (r[j] == NULL) {\n";
6430 pr " fprintf (stderr, \"%s: short list returned\\n\");\n"
6432 pr " print_strings (r);\n";
6435 pr " if (r[j] != NULL) {\n";
6436 pr " fprintf (stderr, \"%s: long list returned\\n\");\n"
6438 pr " print_strings (r);\n";
6442 List.iter (generate_test_command_call test_name) seq;
6443 generate_test_command_call ~test test_name last
6444 | TestOutputBuffer (seq, expected) ->
6445 pr " /* TestOutputBuffer for %s (%d) */\n" name i;
6446 pr " const char *expected = \"%s\";\n" (c_quote expected);
6447 let seq, last = get_seq_last seq in
6448 let len = String.length expected in
6450 pr " if (size != %d) {\n" len;
6451 pr " fprintf (stderr, \"%s: returned size of buffer wrong, expected %d but got %%zu\\n\", size);\n" test_name len;
6454 pr " if (STRNEQLEN (r, expected, size)) {\n";
6455 pr " fprintf (stderr, \"%s: expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", expected, r);\n" test_name;
6459 List.iter (generate_test_command_call test_name) seq;
6460 generate_test_command_call ~test test_name last
6461 | TestOutputStruct (seq, checks) ->
6462 pr " /* TestOutputStruct for %s (%d) */\n" name i;
6463 let seq, last = get_seq_last seq in
6467 | CompareWithInt (field, expected) ->
6468 pr " if (r->%s != %d) {\n" field expected;
6469 pr " fprintf (stderr, \"%s: %s was %%d, expected %d\\n\",\n"
6470 test_name field expected;
6471 pr " (int) r->%s);\n" field;
6474 | CompareWithIntOp (field, op, expected) ->
6475 pr " if (!(r->%s %s %d)) {\n" field op expected;
6476 pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n"
6477 test_name field op expected;
6478 pr " (int) r->%s);\n" field;
6481 | CompareWithString (field, expected) ->
6482 pr " if (STRNEQ (r->%s, \"%s\")) {\n" field expected;
6483 pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n"
6484 test_name field expected;
6485 pr " r->%s);\n" field;
6488 | CompareFieldsIntEq (field1, field2) ->
6489 pr " if (r->%s != r->%s) {\n" field1 field2;
6490 pr " fprintf (stderr, \"%s: %s (%%d) <> %s (%%d)\\n\",\n"
6491 test_name field1 field2;
6492 pr " (int) r->%s, (int) r->%s);\n" field1 field2;
6495 | CompareFieldsStrEq (field1, field2) ->
6496 pr " if (STRNEQ (r->%s, r->%s)) {\n" field1 field2;
6497 pr " fprintf (stderr, \"%s: %s (\"%%s\") <> %s (\"%%s\")\\n\",\n"
6498 test_name field1 field2;
6499 pr " r->%s, r->%s);\n" field1 field2;
6504 List.iter (generate_test_command_call test_name) seq;
6505 generate_test_command_call ~test test_name last
6506 | TestLastFail seq ->
6507 pr " /* TestLastFail for %s (%d) */\n" name i;
6508 let seq, last = get_seq_last seq in
6509 List.iter (generate_test_command_call test_name) seq;
6510 generate_test_command_call test_name ~expect_error:true last
6512 (* Generate the code to run a command, leaving the result in 'r'.
6513 * If you expect to get an error then you should set expect_error:true.
6515 and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
6517 | [] -> assert false
6519 (* Look up the command to find out what args/ret it has. *)
6522 let _, style, _, _, _, _, _ =
6523 List.find (fun (n, _, _, _, _, _, _) -> n = name) all_functions in
6526 failwithf "%s: in test, command %s was not found" test_name name in
6528 if List.length (snd style) <> List.length args then
6529 failwithf "%s: in test, wrong number of args given to %s"
6536 | OptString n, "NULL" -> ()
6539 | Dev_or_Path n, arg
6541 | OptString n, arg ->
6542 pr " const char *%s = \"%s\";\n" n (c_quote arg);
6546 | FileIn _, _ | FileOut _, _ -> ()
6547 | StringList n, arg | DeviceList n, arg ->
6548 let strs = string_split " " arg in
6551 pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
6553 pr " const char *const %s[] = {\n" n;
6555 fun i _ -> pr " %s_%d,\n" n i
6559 ) (List.combine (snd style) args);
6562 match fst style with
6563 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
6564 | RInt64 _ -> pr " int64_t r;\n"; "-1"
6565 | RConstString _ | RConstOptString _ ->
6566 pr " const char *r;\n"; "NULL"
6567 | RString _ -> pr " char *r;\n"; "NULL"
6568 | RStringList _ | RHashtable _ ->
6572 | RStruct (_, typ) ->
6573 pr " struct guestfs_%s *r;\n" typ; "NULL"
6574 | RStructList (_, typ) ->
6575 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
6578 pr " size_t size;\n";
6581 pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
6582 pr " r = guestfs_%s (g" name;
6584 (* Generate the parameters. *)
6587 | OptString _, "NULL" -> pr ", NULL"
6589 | Device n, _ | Dev_or_Path n, _
6593 | FileIn _, arg | FileOut _, arg ->
6594 pr ", \"%s\"" (c_quote arg)
6595 | StringList n, _ | DeviceList n, _ ->
6596 pr ", (char **) %s" n
6599 try int_of_string arg
6600 with Failure "int_of_string" ->
6601 failwithf "%s: expecting an int, but got '%s'" test_name arg in
6605 try Int64.of_string arg
6606 with Failure "int_of_string" ->
6607 failwithf "%s: expecting an int64, but got '%s'" test_name arg in
6610 let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
6611 ) (List.combine (snd style) args);
6613 (match fst style with
6614 | RBufferOut _ -> pr ", &size"
6620 if not expect_error then
6621 pr " if (r == %s)\n" error_code
6623 pr " if (r != %s)\n" error_code;
6626 (* Insert the test code. *)
6632 (match fst style with
6633 | RErr | RInt _ | RInt64 _ | RBool _
6634 | RConstString _ | RConstOptString _ -> ()
6635 | RString _ | RBufferOut _ -> pr " free (r);\n"
6636 | RStringList _ | RHashtable _ ->
6637 pr " for (i = 0; r[i] != NULL; ++i)\n";
6638 pr " free (r[i]);\n";
6640 | RStruct (_, typ) ->
6641 pr " guestfs_free_%s (r);\n" typ
6642 | RStructList (_, typ) ->
6643 pr " guestfs_free_%s_list (r);\n" typ
6649 let str = replace_str str "\r" "\\r" in
6650 let str = replace_str str "\n" "\\n" in
6651 let str = replace_str str "\t" "\\t" in
6652 let str = replace_str str "\000" "\\0" in
6655 (* Generate a lot of different functions for guestfish. *)
6656 and generate_fish_cmds () =
6657 generate_header CStyle GPLv2;
6661 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
6663 let all_functions_sorted =
6665 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
6666 ) all_functions_sorted in
6668 pr "#include <stdio.h>\n";
6669 pr "#include <stdlib.h>\n";
6670 pr "#include <string.h>\n";
6671 pr "#include <inttypes.h>\n";
6673 pr "#include <guestfs.h>\n";
6674 pr "#include \"c-ctype.h\"\n";
6675 pr "#include \"fish.h\"\n";
6678 (* list_commands function, which implements guestfish -h *)
6679 pr "void list_commands (void)\n";
6681 pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
6682 pr " list_builtin_commands ();\n";
6684 fun (name, _, _, flags, _, shortdesc, _) ->
6685 let name = replace_char name '_' '-' in
6686 pr " printf (\"%%-20s %%s\\n\", \"%s\", _(\"%s\"));\n"
6688 ) all_functions_sorted;
6689 pr " printf (\" %%s\\n\",";
6690 pr " _(\"Use -h <cmd> / help <cmd> to show detailed help for a command.\"));\n";
6694 (* display_command function, which implements guestfish -h cmd *)
6695 pr "void display_command (const char *cmd)\n";
6698 fun (name, style, _, flags, _, shortdesc, longdesc) ->
6699 let name2 = replace_char name '_' '-' in
6701 try find_map (function FishAlias n -> Some n | _ -> None) flags
6702 with Not_found -> name in
6703 let longdesc = replace_str longdesc "C<guestfs_" "C<" in
6705 match snd style with
6709 name2 (String.concat " " (List.map name_of_argt args)) in
6712 if List.mem ProtocolLimitWarning flags then
6713 ("\n\n" ^ protocol_limit_warning)
6716 (* For DangerWillRobinson commands, we should probably have
6717 * guestfish prompt before allowing you to use them (especially
6718 * in interactive mode). XXX
6722 if List.mem DangerWillRobinson flags then
6723 ("\n\n" ^ danger_will_robinson)
6728 match deprecation_notice flags with
6730 | Some txt -> "\n\n" ^ txt in
6732 let describe_alias =
6733 if name <> alias then
6734 sprintf "\n\nYou can use '%s' as an alias for this command." alias
6738 pr "STRCASEEQ (cmd, \"%s\")" name;
6739 if name <> name2 then
6740 pr " || STRCASEEQ (cmd, \"%s\")" name2;
6741 if name <> alias then
6742 pr " || STRCASEEQ (cmd, \"%s\")" alias;
6744 pr " pod2text (\"%s\", _(\"%s\"), %S);\n"
6746 ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^
6747 "=head1 DESCRIPTION\n\n" ^
6748 longdesc ^ warnings ^ describe_alias);
6751 pr " display_builtin_command (cmd);\n";
6755 let emit_print_list_function typ =
6756 pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
6759 pr " unsigned int i;\n";
6761 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
6762 pr " printf (\"[%%d] = {\\n\", i);\n";
6763 pr " print_%s_indent (&%ss->val[i], \" \");\n" typ typ;
6764 pr " printf (\"}\\n\");\n";
6770 (* print_* functions *)
6774 List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
6776 pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
6779 pr " unsigned int i;\n";
6785 pr " printf (\"%%s%s: %%s\\n\", indent, %s->%s);\n" name typ name
6787 pr " printf (\"%%s%s: \", indent);\n" name;
6788 pr " for (i = 0; i < 32; ++i)\n";
6789 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
6790 pr " printf (\"\\n\");\n"
6792 pr " printf (\"%%s%s: \", indent);\n" name;
6793 pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
6794 pr " if (c_isprint (%s->%s[i]))\n" typ name;
6795 pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
6797 pr " printf (\"\\\\x%%02x\", %s->%s[i]);\n" typ name;
6798 pr " printf (\"\\n\");\n"
6799 | name, (FUInt64|FBytes) ->
6800 pr " printf (\"%%s%s: %%\" PRIu64 \"\\n\", indent, %s->%s);\n"
6803 pr " printf (\"%%s%s: %%\" PRIi64 \"\\n\", indent, %s->%s);\n"
6806 pr " printf (\"%%s%s: %%\" PRIu32 \"\\n\", indent, %s->%s);\n"
6809 pr " printf (\"%%s%s: %%\" PRIi32 \"\\n\", indent, %s->%s);\n"
6812 pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
6814 | name, FOptPercent ->
6815 pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
6816 typ name name typ name;
6817 pr " else printf (\"%%s%s: \\n\", indent);\n" name
6823 (* Emit a print_TYPE_list function definition only if that function is used. *)
6826 | typ, (RStructListOnly | RStructAndList) ->
6827 (* generate the function for typ *)
6828 emit_print_list_function typ
6829 | typ, _ -> () (* empty *)
6830 ) (rstructs_used_by all_functions);
6832 (* Emit a print_TYPE function definition only if that function is used. *)
6835 | typ, (RStructOnly | RStructAndList) ->
6836 pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
6838 pr " print_%s_indent (%s, \"\");\n" typ typ;
6841 | typ, _ -> () (* empty *)
6842 ) (rstructs_used_by all_functions);
6844 (* run_<action> actions *)
6846 fun (name, style, _, flags, _, _, _) ->
6847 pr "static int run_%s (const char *cmd, int argc, char *argv[])\n" name;
6849 (match fst style with
6852 | RBool _ -> pr " int r;\n"
6853 | RInt64 _ -> pr " int64_t r;\n"
6854 | RConstString _ | RConstOptString _ -> pr " const char *r;\n"
6855 | RString _ -> pr " char *r;\n"
6856 | RStringList _ | RHashtable _ -> pr " char **r;\n"
6857 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
6858 | RStructList (_, typ) -> pr " struct guestfs_%s_list *r;\n" typ
6861 pr " size_t size;\n";
6869 | FileOut n -> pr " const char *%s;\n" n
6871 | Dev_or_Path n -> pr " char *%s;\n" n
6872 | StringList n | DeviceList n -> pr " char **%s;\n" n
6873 | Bool n -> pr " int %s;\n" n
6874 | Int n -> pr " int %s;\n" n
6875 | Int64 n -> pr " int64_t %s;\n" n
6878 (* Check and convert parameters. *)
6879 let argc_expected = List.length (snd style) in
6880 pr " if (argc != %d) {\n" argc_expected;
6881 pr " fprintf (stderr, _(\"%%s should have %%d parameter(s)\\n\"), cmd, %d);\n"
6883 pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n";
6891 pr " %s = argv[%d];\n" name i
6893 | Dev_or_Path name ->
6894 pr " %s = resolve_win_path (argv[%d]);\n" name i;
6895 pr " if (%s == NULL) return -1;\n" name
6897 pr " %s = STRNEQ (argv[%d], \"\") ? argv[%d] : NULL;\n"
6900 pr " %s = STRNEQ (argv[%d], \"-\") ? argv[%d] : \"/dev/stdin\";\n"
6903 pr " %s = STRNEQ (argv[%d], \"-\") ? argv[%d] : \"/dev/stdout\";\n"
6905 | StringList name | DeviceList name ->
6906 pr " %s = parse_string_list (argv[%d]);\n" name i;
6907 pr " if (%s == NULL) return -1;\n" name;
6909 pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i
6911 pr " %s = atoi (argv[%d]);\n" name i
6913 pr " %s = atoll (argv[%d]);\n" name i
6916 (* Call C API function. *)
6918 try find_map (function FishAction n -> Some n | _ -> None) flags
6919 with Not_found -> sprintf "guestfs_%s" name in
6921 generate_c_call_args ~handle:"g" style;
6926 | Device name | String name
6927 | OptString name | FileIn name | FileOut name | Bool name
6928 | Int name | Int64 name -> ()
6929 | Pathname name | Dev_or_Path name ->
6930 pr " free (%s);\n" name
6931 | StringList name | DeviceList name ->
6932 pr " free_strings (%s);\n" name
6935 (* Check return value for errors and display command results. *)
6936 (match fst style with
6937 | RErr -> pr " return r;\n"
6939 pr " if (r == -1) return -1;\n";
6940 pr " printf (\"%%d\\n\", r);\n";
6943 pr " if (r == -1) return -1;\n";
6944 pr " printf (\"%%\" PRIi64 \"\\n\", r);\n";
6947 pr " if (r == -1) return -1;\n";
6948 pr " if (r) printf (\"true\\n\"); else printf (\"false\\n\");\n";
6951 pr " if (r == NULL) return -1;\n";
6952 pr " printf (\"%%s\\n\", r);\n";
6954 | RConstOptString _ ->
6955 pr " printf (\"%%s\\n\", r ? : \"(null)\");\n";
6958 pr " if (r == NULL) return -1;\n";
6959 pr " printf (\"%%s\\n\", r);\n";
6963 pr " if (r == NULL) return -1;\n";
6964 pr " print_strings (r);\n";
6965 pr " free_strings (r);\n";
6967 | RStruct (_, typ) ->
6968 pr " if (r == NULL) return -1;\n";
6969 pr " print_%s (r);\n" typ;
6970 pr " guestfs_free_%s (r);\n" typ;
6972 | RStructList (_, typ) ->
6973 pr " if (r == NULL) return -1;\n";
6974 pr " print_%s_list (r);\n" typ;
6975 pr " guestfs_free_%s_list (r);\n" typ;
6978 pr " if (r == NULL) return -1;\n";
6979 pr " print_table (r);\n";
6980 pr " free_strings (r);\n";
6983 pr " if (r == NULL) return -1;\n";
6984 pr " fwrite (r, size, 1, stdout);\n";
6992 (* run_action function *)
6993 pr "int run_action (const char *cmd, int argc, char *argv[])\n";
6996 fun (name, _, _, flags, _, _, _) ->
6997 let name2 = replace_char name '_' '-' in
6999 try find_map (function FishAlias n -> Some n | _ -> None) flags
7000 with Not_found -> name in
7002 pr "STRCASEEQ (cmd, \"%s\")" name;
7003 if name <> name2 then
7004 pr " || STRCASEEQ (cmd, \"%s\")" name2;
7005 if name <> alias then
7006 pr " || STRCASEEQ (cmd, \"%s\")" alias;
7008 pr " return run_%s (cmd, argc, argv);\n" name;
7012 pr " fprintf (stderr, _(\"%%s: unknown command\\n\"), cmd);\n";
7019 (* Readline completion for guestfish. *)
7020 and generate_fish_completion () =
7021 generate_header CStyle GPLv2;
7025 fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags)
7035 #ifdef HAVE_LIBREADLINE
7036 #include <readline/readline.h>
7041 #ifdef HAVE_LIBREADLINE
7043 static const char *const commands[] = {
7044 BUILTIN_COMMANDS_FOR_COMPLETION,
7047 (* Get the commands, including the aliases. They don't need to be
7048 * sorted - the generator() function just does a dumb linear search.
7052 fun (name, _, _, flags, _, _, _) ->
7053 let name2 = replace_char name '_' '-' in
7055 try find_map (function FishAlias n -> Some n | _ -> None) flags
7056 with Not_found -> name in
7058 if name <> alias then [name2; alias] else [name2]
7060 let commands = List.flatten commands in
7062 List.iter (pr " \"%s\",\n") commands;
7068 generator (const char *text, int state)
7070 static int index, len;
7075 len = strlen (text);
7078 rl_attempted_completion_over = 1;
7080 while ((name = commands[index]) != NULL) {
7082 if (STRCASEEQLEN (name, text, len))
7083 return strdup (name);
7089 #endif /* HAVE_LIBREADLINE */
7091 char **do_completion (const char *text, int start, int end)
7093 char **matches = NULL;
7095 #ifdef HAVE_LIBREADLINE
7096 rl_completion_append_character = ' ';
7099 matches = rl_completion_matches (text, generator);
7100 else if (complete_dest_paths)
7101 matches = rl_completion_matches (text, complete_dest_paths_generator);
7108 (* Generate the POD documentation for guestfish. *)
7109 and generate_fish_actions_pod () =
7110 let all_functions_sorted =
7112 fun (_, _, _, flags, _, _, _) ->
7113 not (List.mem NotInFish flags || List.mem NotInDocs flags)
7114 ) all_functions_sorted in
7116 let rex = Str.regexp "C<guestfs_\\([^>]+\\)>" in
7119 fun (name, style, _, flags, _, _, longdesc) ->
7121 Str.global_substitute rex (
7124 try Str.matched_group 1 s
7126 failwithf "error substituting C<guestfs_...> in longdesc of function %s" name in
7127 "C<" ^ replace_char sub '_' '-' ^ ">"
7129 let name = replace_char name '_' '-' in
7131 try find_map (function FishAlias n -> Some n | _ -> None) flags
7132 with Not_found -> name in
7134 pr "=head2 %s" name;
7135 if name <> alias then
7142 | Pathname n | Device n | Dev_or_Path n | String n -> pr " %s" n
7143 | OptString n -> pr " %s" n
7144 | StringList n | DeviceList n -> pr " '%s ...'" n
7145 | Bool _ -> pr " true|false"
7146 | Int n -> pr " %s" n
7147 | Int64 n -> pr " %s" n
7148 | FileIn n | FileOut n -> pr " (%s|-)" n
7152 pr "%s\n\n" longdesc;
7154 if List.exists (function FileIn _ | FileOut _ -> true
7155 | _ -> false) (snd style) then
7156 pr "Use C<-> instead of a filename to read/write from stdin/stdout.\n\n";
7158 if List.mem ProtocolLimitWarning flags then
7159 pr "%s\n\n" protocol_limit_warning;
7161 if List.mem DangerWillRobinson flags then
7162 pr "%s\n\n" danger_will_robinson;
7164 match deprecation_notice flags with
7166 | Some txt -> pr "%s\n\n" txt
7167 ) all_functions_sorted
7169 (* Generate a C function prototype. *)
7170 and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
7171 ?(single_line = false) ?(newline = false) ?(in_daemon = false)
7173 ?handle name style =
7174 if extern then pr "extern ";
7175 if static then pr "static ";
7176 (match fst style with
7178 | RInt _ -> pr "int "
7179 | RInt64 _ -> pr "int64_t "
7180 | RBool _ -> pr "int "
7181 | RConstString _ | RConstOptString _ -> pr "const char *"
7182 | RString _ | RBufferOut _ -> pr "char *"
7183 | RStringList _ | RHashtable _ -> pr "char **"
7184 | RStruct (_, typ) ->
7185 if not in_daemon then pr "struct guestfs_%s *" typ
7186 else pr "guestfs_int_%s *" typ
7187 | RStructList (_, typ) ->
7188 if not in_daemon then pr "struct guestfs_%s_list *" typ
7189 else pr "guestfs_int_%s_list *" typ
7191 let is_RBufferOut = match fst style with RBufferOut _ -> true | _ -> false in
7192 pr "%s%s (" prefix name;
7193 if handle = None && List.length (snd style) = 0 && not is_RBufferOut then
7196 let comma = ref false in
7199 | Some handle -> pr "guestfs_h *%s" handle; comma := true
7203 if single_line then pr ", " else pr ",\n\t\t"
7210 | Device n | Dev_or_Path n
7214 pr "const char *%s" n
7215 | StringList n | DeviceList n ->
7217 pr "char *const *%s" n
7218 | Bool n -> next (); pr "int %s" n
7219 | Int n -> next (); pr "int %s" n
7220 | Int64 n -> next (); pr "int64_t %s" n
7223 if not in_daemon then (next (); pr "const char *%s" n)
7225 if is_RBufferOut then (next (); pr "size_t *size_r");
7228 if semicolon then pr ";";
7229 if newline then pr "\n"
7231 (* Generate C call arguments, eg "(handle, foo, bar)" *)
7232 and generate_c_call_args ?handle ?(decl = false) style =
7234 let comma = ref false in
7236 if !comma then pr ", ";
7241 | Some handle -> pr "%s" handle; comma := true
7246 pr "%s" (name_of_argt arg)
7248 (* For RBufferOut calls, add implicit &size parameter. *)
7250 match fst style with
7258 (* Generate the OCaml bindings interface. *)
7259 and generate_ocaml_mli () =
7260 generate_header OCamlStyle LGPLv2;
7263 (** For API documentation you should refer to the C API
7264 in the guestfs(3) manual page. The OCaml API uses almost
7265 exactly the same calls. *)
7268 (** A [guestfs_h] handle. *)
7270 exception Error of string
7271 (** This exception is raised when there is an error. *)
7273 exception Handle_closed of string
7274 (** This exception is raised if you use a {!Guestfs.t} handle
7275 after calling {!close} on it. The string is the name of
7278 val create : unit -> t
7279 (** Create a {!Guestfs.t} handle. *)
7281 val close : t -> unit
7282 (** Close the {!Guestfs.t} handle and free up all resources used
7285 Handles are closed by the garbage collector when they become
7286 unreferenced, but callers can call this in order to provide
7287 predictable cleanup. *)
7290 generate_ocaml_structure_decls ();
7294 fun (name, style, _, _, _, shortdesc, _) ->
7295 generate_ocaml_prototype name style;
7296 pr "(** %s *)\n" shortdesc;
7298 ) all_functions_sorted
7300 (* Generate the OCaml bindings implementation. *)
7301 and generate_ocaml_ml () =
7302 generate_header OCamlStyle LGPLv2;
7307 exception Error of string
7308 exception Handle_closed of string
7310 external create : unit -> t = \"ocaml_guestfs_create\"
7311 external close : t -> unit = \"ocaml_guestfs_close\"
7313 (* Give the exceptions names, so they can be raised from the C code. *)
7315 Callback.register_exception \"ocaml_guestfs_error\" (Error \"\");
7316 Callback.register_exception \"ocaml_guestfs_closed\" (Handle_closed \"\")
7320 generate_ocaml_structure_decls ();
7324 fun (name, style, _, _, _, shortdesc, _) ->
7325 generate_ocaml_prototype ~is_external:true name style;
7326 ) all_functions_sorted
7328 (* Generate the OCaml bindings C implementation. *)
7329 and generate_ocaml_c () =
7330 generate_header CStyle LGPLv2;
7337 #include <caml/config.h>
7338 #include <caml/alloc.h>
7339 #include <caml/callback.h>
7340 #include <caml/fail.h>
7341 #include <caml/memory.h>
7342 #include <caml/mlvalues.h>
7343 #include <caml/signals.h>
7345 #include <guestfs.h>
7347 #include \"guestfs_c.h\"
7349 /* Copy a hashtable of string pairs into an assoc-list. We return
7350 * the list in reverse order, but hashtables aren't supposed to be
7353 static CAMLprim value
7354 copy_table (char * const * argv)
7357 CAMLlocal5 (rv, pairv, kv, vv, cons);
7361 for (i = 0; argv[i] != NULL; i += 2) {
7362 kv = caml_copy_string (argv[i]);
7363 vv = caml_copy_string (argv[i+1]);
7364 pairv = caml_alloc (2, 0);
7365 Store_field (pairv, 0, kv);
7366 Store_field (pairv, 1, vv);
7367 cons = caml_alloc (2, 0);
7368 Store_field (cons, 1, rv);
7370 Store_field (cons, 0, pairv);
7378 (* Struct copy functions. *)
7380 let emit_ocaml_copy_list_function typ =
7381 pr "static CAMLprim value\n";
7382 pr "copy_%s_list (const struct guestfs_%s_list *%ss)\n" typ typ typ;
7384 pr " CAMLparam0 ();\n";
7385 pr " CAMLlocal2 (rv, v);\n";
7386 pr " unsigned int i;\n";
7388 pr " if (%ss->len == 0)\n" typ;
7389 pr " CAMLreturn (Atom (0));\n";
7391 pr " rv = caml_alloc (%ss->len, 0);\n" typ;
7392 pr " for (i = 0; i < %ss->len; ++i) {\n" typ;
7393 pr " v = copy_%s (&%ss->val[i]);\n" typ typ;
7394 pr " caml_modify (&Field (rv, i), v);\n";
7396 pr " CAMLreturn (rv);\n";
7404 let has_optpercent_col =
7405 List.exists (function (_, FOptPercent) -> true | _ -> false) cols in
7407 pr "static CAMLprim value\n";
7408 pr "copy_%s (const struct guestfs_%s *%s)\n" typ typ typ;
7410 pr " CAMLparam0 ();\n";
7411 if has_optpercent_col then
7412 pr " CAMLlocal3 (rv, v, v2);\n"
7414 pr " CAMLlocal2 (rv, v);\n";
7416 pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
7421 pr " v = caml_copy_string (%s->%s);\n" typ name
7423 pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
7424 pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
7427 pr " v = caml_alloc_string (32);\n";
7428 pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
7429 | name, (FBytes|FInt64|FUInt64) ->
7430 pr " v = caml_copy_int64 (%s->%s);\n" typ name
7431 | name, (FInt32|FUInt32) ->
7432 pr " v = caml_copy_int32 (%s->%s);\n" typ name
7433 | name, FOptPercent ->
7434 pr " if (%s->%s >= 0) { /* Some %s */\n" typ name name;
7435 pr " v2 = caml_copy_double (%s->%s);\n" typ name;
7436 pr " v = caml_alloc (1, 0);\n";
7437 pr " Store_field (v, 0, v2);\n";
7438 pr " } else /* None */\n";
7439 pr " v = Val_int (0);\n";
7441 pr " v = Val_int (%s->%s);\n" typ name
7443 pr " Store_field (rv, %d, v);\n" i
7445 pr " CAMLreturn (rv);\n";
7450 (* Emit a copy_TYPE_list function definition only if that function is used. *)
7453 | typ, (RStructListOnly | RStructAndList) ->
7454 (* generate the function for typ *)
7455 emit_ocaml_copy_list_function typ
7456 | typ, _ -> () (* empty *)
7457 ) (rstructs_used_by all_functions);
7461 fun (name, style, _, _, _, _, _) ->
7462 pr "/* Automatically generated wrapper for function\n";
7464 generate_ocaml_prototype name style;
7469 "gv" :: List.map (fun arg -> name_of_argt arg ^ "v") (snd style) in
7471 let needs_extra_vs =
7472 match fst style with RConstOptString _ -> true | _ -> false in
7474 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
7475 pr "CAMLprim value ocaml_guestfs_%s (value %s" name (List.hd params);
7476 List.iter (pr ", value %s") (List.tl params); pr ");\n";
7479 pr "CAMLprim value\n";
7480 pr "ocaml_guestfs_%s (value %s" name (List.hd params);
7481 List.iter (pr ", value %s") (List.tl params);
7486 | [p1; p2; p3; p4; p5] ->
7487 pr " CAMLparam5 (%s);\n" (String.concat ", " params)
7488 | p1 :: p2 :: p3 :: p4 :: p5 :: rest ->
7489 pr " CAMLparam5 (%s);\n" (String.concat ", " [p1; p2; p3; p4; p5]);
7490 pr " CAMLxparam%d (%s);\n"
7491 (List.length rest) (String.concat ", " rest)
7493 pr " CAMLparam%d (%s);\n" (List.length ps) (String.concat ", " ps)
7495 if not needs_extra_vs then
7496 pr " CAMLlocal1 (rv);\n"
7498 pr " CAMLlocal3 (rv, v, v2);\n";
7501 pr " guestfs_h *g = Guestfs_val (gv);\n";
7502 pr " if (g == NULL)\n";
7503 pr " ocaml_guestfs_raise_closed (\"%s\");\n" name;
7509 | Device n | Dev_or_Path n
7513 pr " const char *%s = String_val (%sv);\n" n n
7515 pr " const char *%s =\n" n;
7516 pr " %sv != Val_int (0) ? String_val (Field (%sv, 0)) : NULL;\n"
7518 | StringList n | DeviceList n ->
7519 pr " char **%s = ocaml_guestfs_strings_val (g, %sv);\n" n n
7521 pr " int %s = Bool_val (%sv);\n" n n
7523 pr " int %s = Int_val (%sv);\n" n n
7525 pr " int64_t %s = Int64_val (%sv);\n" n n
7528 match fst style with
7529 | RErr -> pr " int r;\n"; "-1"
7530 | RInt _ -> pr " int r;\n"; "-1"
7531 | RInt64 _ -> pr " int64_t r;\n"; "-1"
7532 | RBool _ -> pr " int r;\n"; "-1"
7533 | RConstString _ | RConstOptString _ ->
7534 pr " const char *r;\n"; "NULL"
7535 | RString _ -> pr " char *r;\n"; "NULL"
7540 | RStruct (_, typ) ->
7541 pr " struct guestfs_%s *r;\n" typ; "NULL"
7542 | RStructList (_, typ) ->
7543 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
7550 pr " size_t size;\n";
7554 pr " caml_enter_blocking_section ();\n";
7555 pr " r = guestfs_%s " name;
7556 generate_c_call_args ~handle:"g" style;
7558 pr " caml_leave_blocking_section ();\n";
7562 | StringList n | DeviceList n ->
7563 pr " ocaml_guestfs_free_strings (%s);\n" n;
7564 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
7565 | Bool _ | Int _ | Int64 _
7566 | FileIn _ | FileOut _ -> ()
7569 pr " if (r == %s)\n" error_code;
7570 pr " ocaml_guestfs_raise_error (g, \"%s\");\n" name;
7573 (match fst style with
7574 | RErr -> pr " rv = Val_unit;\n"
7575 | RInt _ -> pr " rv = Val_int (r);\n"
7577 pr " rv = caml_copy_int64 (r);\n"
7578 | RBool _ -> pr " rv = Val_bool (r);\n"
7580 pr " rv = caml_copy_string (r);\n"
7581 | RConstOptString _ ->
7582 pr " if (r) { /* Some string */\n";
7583 pr " v = caml_alloc (1, 0);\n";
7584 pr " v2 = caml_copy_string (r);\n";
7585 pr " Store_field (v, 0, v2);\n";
7586 pr " } else /* None */\n";
7587 pr " v = Val_int (0);\n";
7589 pr " rv = caml_copy_string (r);\n";
7592 pr " rv = caml_copy_string_array ((const char **) r);\n";
7593 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
7595 | RStruct (_, typ) ->
7596 pr " rv = copy_%s (r);\n" typ;
7597 pr " guestfs_free_%s (r);\n" typ;
7598 | RStructList (_, typ) ->
7599 pr " rv = copy_%s_list (r);\n" typ;
7600 pr " guestfs_free_%s_list (r);\n" typ;
7602 pr " rv = copy_table (r);\n";
7603 pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
7606 pr " rv = caml_alloc_string (size);\n";
7607 pr " memcpy (String_val (rv), r, size);\n";
7610 pr " CAMLreturn (rv);\n";
7614 if List.length params > 5 then (
7615 pr "/* Emit prototype to appease gcc's -Wmissing-prototypes. */\n";
7616 pr "CAMLprim value ";
7617 pr "ocaml_guestfs_%s_byte (value *argv, int argn);\n" name;
7618 pr "CAMLprim value\n";
7619 pr "ocaml_guestfs_%s_byte (value *argv, int argn)\n" name;
7621 pr " return ocaml_guestfs_%s (argv[0]" name;
7622 iteri (fun i _ -> pr ", argv[%d]" i) (List.tl params);
7627 ) all_functions_sorted
7629 and generate_ocaml_structure_decls () =
7632 pr "type %s = {\n" typ;
7635 | name, FString -> pr " %s : string;\n" name
7636 | name, FBuffer -> pr " %s : string;\n" name
7637 | name, FUUID -> pr " %s : string;\n" name
7638 | name, (FBytes|FInt64|FUInt64) -> pr " %s : int64;\n" name
7639 | name, (FInt32|FUInt32) -> pr " %s : int32;\n" name
7640 | name, FChar -> pr " %s : char;\n" name
7641 | name, FOptPercent -> pr " %s : float option;\n" name
7647 and generate_ocaml_prototype ?(is_external = false) name style =
7648 if is_external then pr "external " else pr "val ";
7649 pr "%s : t -> " name;
7652 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "string -> "
7653 | OptString _ -> pr "string option -> "
7654 | StringList _ | DeviceList _ -> pr "string array -> "
7655 | Bool _ -> pr "bool -> "
7656 | Int _ -> pr "int -> "
7657 | Int64 _ -> pr "int64 -> "
7659 (match fst style with
7660 | RErr -> pr "unit" (* all errors are turned into exceptions *)
7661 | RInt _ -> pr "int"
7662 | RInt64 _ -> pr "int64"
7663 | RBool _ -> pr "bool"
7664 | RConstString _ -> pr "string"
7665 | RConstOptString _ -> pr "string option"
7666 | RString _ | RBufferOut _ -> pr "string"
7667 | RStringList _ -> pr "string array"
7668 | RStruct (_, typ) -> pr "%s" typ
7669 | RStructList (_, typ) -> pr "%s array" typ
7670 | RHashtable _ -> pr "(string * string) list"
7672 if is_external then (
7674 if List.length (snd style) + 1 > 5 then
7675 pr "\"ocaml_guestfs_%s_byte\" " name;
7676 pr "\"ocaml_guestfs_%s\"" name
7680 (* Generate Perl xs code, a sort of crazy variation of C with macros. *)
7681 and generate_perl_xs () =
7682 generate_header CStyle LGPLv2;
7685 #include \"EXTERN.h\"
7689 #include <guestfs.h>
7692 #define PRId64 \"lld\"
7696 my_newSVll(long long val) {
7697 #ifdef USE_64_BIT_ALL
7698 return newSViv(val);
7702 len = snprintf(buf, 100, \"%%\" PRId64, val);
7703 return newSVpv(buf, len);
7708 #define PRIu64 \"llu\"
7712 my_newSVull(unsigned long long val) {
7713 #ifdef USE_64_BIT_ALL
7714 return newSVuv(val);
7718 len = snprintf(buf, 100, \"%%\" PRIu64, val);
7719 return newSVpv(buf, len);
7723 /* http://www.perlmonks.org/?node_id=680842 */
7725 XS_unpack_charPtrPtr (SV *arg) {
7730 if (!arg || !SvOK (arg) || !SvROK (arg) || SvTYPE (SvRV (arg)) != SVt_PVAV)
7731 croak (\"array reference expected\");
7733 av = (AV *)SvRV (arg);
7734 ret = malloc ((av_len (av) + 1 + 1) * sizeof (char *));
7736 croak (\"malloc failed\");
7738 for (i = 0; i <= av_len (av); i++) {
7739 SV **elem = av_fetch (av, i, 0);
7741 if (!elem || !*elem)
7742 croak (\"missing element in list\");
7744 ret[i] = SvPV_nolen (*elem);
7752 MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs
7759 RETVAL = guestfs_create ();
7761 croak (\"could not create guestfs handle\");
7762 guestfs_set_error_handler (RETVAL, NULL, NULL);
7775 fun (name, style, _, _, _, _, _) ->
7776 (match fst style with
7777 | RErr -> pr "void\n"
7778 | RInt _ -> pr "SV *\n"
7779 | RInt64 _ -> pr "SV *\n"
7780 | RBool _ -> pr "SV *\n"
7781 | RConstString _ -> pr "SV *\n"
7782 | RConstOptString _ -> pr "SV *\n"
7783 | RString _ -> pr "SV *\n"
7784 | RBufferOut _ -> pr "SV *\n"
7786 | RStruct _ | RStructList _
7788 pr "void\n" (* all lists returned implictly on the stack *)
7790 (* Call and arguments. *)
7792 generate_c_call_args ~handle:"g" ~decl:true style;
7794 pr " guestfs_h *g;\n";
7798 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
7801 (* http://www.perlmonks.org/?node_id=554277
7802 * Note that the implicit handle argument means we have
7803 * to add 1 to the ST(x) operator.
7805 pr " char *%s = SvOK(ST(%d)) ? SvPV_nolen(ST(%d)) : NULL;\n" n (i+1) (i+1)
7806 | StringList n | DeviceList n -> pr " char **%s;\n" n
7807 | Bool n -> pr " int %s;\n" n
7808 | Int n -> pr " int %s;\n" n
7809 | Int64 n -> pr " int64_t %s;\n" n
7812 let do_cleanups () =
7815 | Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
7816 | Bool _ | Int _ | Int64 _
7817 | FileIn _ | FileOut _ -> ()
7818 | StringList n | DeviceList n -> pr " free (%s);\n" n
7823 (match fst style with
7828 pr " r = guestfs_%s " name;
7829 generate_c_call_args ~handle:"g" style;
7832 pr " if (r == -1)\n";
7833 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7839 pr " %s = guestfs_%s " n name;
7840 generate_c_call_args ~handle:"g" style;
7843 pr " if (%s == -1)\n" n;
7844 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7845 pr " RETVAL = newSViv (%s);\n" n;
7850 pr " int64_t %s;\n" n;
7852 pr " %s = guestfs_%s " n name;
7853 generate_c_call_args ~handle:"g" style;
7856 pr " if (%s == -1)\n" n;
7857 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7858 pr " RETVAL = my_newSVll (%s);\n" n;
7863 pr " const char *%s;\n" n;
7865 pr " %s = guestfs_%s " n name;
7866 generate_c_call_args ~handle:"g" style;
7869 pr " if (%s == NULL)\n" n;
7870 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7871 pr " RETVAL = newSVpv (%s, 0);\n" n;
7874 | RConstOptString n ->
7876 pr " const char *%s;\n" n;
7878 pr " %s = guestfs_%s " n name;
7879 generate_c_call_args ~handle:"g" style;
7882 pr " if (%s == NULL)\n" n;
7883 pr " RETVAL = &PL_sv_undef;\n";
7885 pr " RETVAL = newSVpv (%s, 0);\n" n;
7890 pr " char *%s;\n" n;
7892 pr " %s = guestfs_%s " n name;
7893 generate_c_call_args ~handle:"g" style;
7896 pr " if (%s == NULL)\n" n;
7897 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7898 pr " RETVAL = newSVpv (%s, 0);\n" n;
7899 pr " free (%s);\n" n;
7902 | RStringList n | RHashtable n ->
7904 pr " char **%s;\n" n;
7907 pr " %s = guestfs_%s " n name;
7908 generate_c_call_args ~handle:"g" style;
7911 pr " if (%s == NULL)\n" n;
7912 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7913 pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n;
7914 pr " EXTEND (SP, n);\n";
7915 pr " for (i = 0; i < n; ++i) {\n";
7916 pr " PUSHs (sv_2mortal (newSVpv (%s[i], 0)));\n" n;
7917 pr " free (%s[i]);\n" n;
7919 pr " free (%s);\n" n;
7920 | RStruct (n, typ) ->
7921 let cols = cols_of_struct typ in
7922 generate_perl_struct_code typ cols name style n do_cleanups
7923 | RStructList (n, typ) ->
7924 let cols = cols_of_struct typ in
7925 generate_perl_struct_list_code typ cols name style n do_cleanups
7928 pr " char *%s;\n" n;
7929 pr " size_t size;\n";
7931 pr " %s = guestfs_%s " n name;
7932 generate_c_call_args ~handle:"g" style;
7935 pr " if (%s == NULL)\n" n;
7936 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7937 pr " RETVAL = newSVpv (%s, size);\n" n;
7938 pr " free (%s);\n" n;
7946 and generate_perl_struct_list_code typ cols name style n do_cleanups =
7948 pr " struct guestfs_%s_list *%s;\n" typ n;
7952 pr " %s = guestfs_%s " n name;
7953 generate_c_call_args ~handle:"g" style;
7956 pr " if (%s == NULL)\n" n;
7957 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
7958 pr " EXTEND (SP, %s->len);\n" n;
7959 pr " for (i = 0; i < %s->len; ++i) {\n" n;
7960 pr " hv = newHV ();\n";
7964 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 0), 0);\n"
7965 name (String.length name) n name
7967 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, 32), 0);\n"
7968 name (String.length name) n name
7970 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (%s->val[i].%s, %s->val[i].%s_len), 0);\n"
7971 name (String.length name) n name n name
7972 | name, (FBytes|FUInt64) ->
7973 pr " (void) hv_store (hv, \"%s\", %d, my_newSVull (%s->val[i].%s), 0);\n"
7974 name (String.length name) n name
7976 pr " (void) hv_store (hv, \"%s\", %d, my_newSVll (%s->val[i].%s), 0);\n"
7977 name (String.length name) n name
7978 | name, (FInt32|FUInt32) ->
7979 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
7980 name (String.length name) n name
7982 pr " (void) hv_store (hv, \"%s\", %d, newSVpv (&%s->val[i].%s, 1), 0);\n"
7983 name (String.length name) n name
7984 | name, FOptPercent ->
7985 pr " (void) hv_store (hv, \"%s\", %d, newSVnv (%s->val[i].%s), 0);\n"
7986 name (String.length name) n name
7988 pr " PUSHs (sv_2mortal (newRV ((SV *) hv)));\n";
7990 pr " guestfs_free_%s_list (%s);\n" typ n
7992 and generate_perl_struct_code typ cols name style n do_cleanups =
7994 pr " struct guestfs_%s *%s;\n" typ n;
7996 pr " %s = guestfs_%s " n name;
7997 generate_c_call_args ~handle:"g" style;
8000 pr " if (%s == NULL)\n" n;
8001 pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name;
8002 pr " EXTEND (SP, 2 * %d);\n" (List.length cols);
8004 fun ((name, _) as col) ->
8005 pr " PUSHs (sv_2mortal (newSVpv (\"%s\", 0)));\n" name;
8009 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 0)));\n"
8012 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, %s->%s_len)));\n"
8015 pr " PUSHs (sv_2mortal (newSVpv (%s->%s, 32)));\n"
8017 | name, (FBytes|FUInt64) ->
8018 pr " PUSHs (sv_2mortal (my_newSVull (%s->%s)));\n"
8021 pr " PUSHs (sv_2mortal (my_newSVll (%s->%s)));\n"
8023 | name, (FInt32|FUInt32) ->
8024 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8027 pr " PUSHs (sv_2mortal (newSVpv (&%s->%s, 1)));\n"
8029 | name, FOptPercent ->
8030 pr " PUSHs (sv_2mortal (newSVnv (%s->%s)));\n"
8033 pr " free (%s);\n" n
8035 (* Generate Sys/Guestfs.pm. *)
8036 and generate_perl_pm () =
8037 generate_header HashStyle LGPLv2;
8044 Sys::Guestfs - Perl bindings for libguestfs
8050 my $h = Sys::Guestfs->new ();
8051 $h->add_drive ('guest.img');
8053 $h->mount ('/dev/sda1', '/');
8054 $h->touch ('/hello');
8059 The C<Sys::Guestfs> module provides a Perl XS binding to the
8060 libguestfs API for examining and modifying virtual machine
8063 Amongst the things this is good for: making batch configuration
8064 changes to guests, getting disk used/free statistics (see also:
8065 virt-df), migrating between virtualization systems (see also:
8066 virt-p2v), performing partial backups, performing partial guest
8067 clones, cloning guests and changing registry/UUID/hostname info, and
8070 Libguestfs uses Linux kernel and qemu code, and can access any type of
8071 guest filesystem that Linux and qemu can, including but not limited
8072 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
8073 schemes, qcow, qcow2, vmdk.
8075 Libguestfs provides ways to enumerate guest storage (eg. partitions,
8076 LVs, what filesystem is in each LV, etc.). It can also run commands
8077 in the context of the guest. Also you can access filesystems over FTP.
8079 See also L<Sys::Guestfs::Lib(3)> for a set of useful library
8080 functions for using libguestfs from Perl, including integration
8085 All errors turn into calls to C<croak> (see L<Carp(3)>).
8093 package Sys::Guestfs;
8099 XSLoader::load ('Sys::Guestfs');
8101 =item $h = Sys::Guestfs->new ();
8103 Create a new guestfs handle.
8109 my $class = ref ($proto) || $proto;
8111 my $self = Sys::Guestfs::_create ();
8112 bless $self, $class;
8118 (* Actions. We only need to print documentation for these as
8119 * they are pulled in from the XS code automatically.
8122 fun (name, style, _, flags, _, _, longdesc) ->
8123 if not (List.mem NotInDocs flags) then (
8124 let longdesc = replace_str longdesc "C<guestfs_" "C<$h-E<gt>" in
8126 generate_perl_prototype name style;
8128 pr "%s\n\n" longdesc;
8129 if List.mem ProtocolLimitWarning flags then
8130 pr "%s\n\n" protocol_limit_warning;
8131 if List.mem DangerWillRobinson flags then
8132 pr "%s\n\n" danger_will_robinson;
8133 match deprecation_notice flags with
8135 | Some txt -> pr "%s\n\n" txt
8137 ) all_functions_sorted;
8149 Copyright (C) 2009 Red Hat Inc.
8153 Please see the file COPYING.LIB for the full license.
8159 L<http://libguestfs.org>,
8160 L<Sys::Guestfs::Lib(3)>.
8165 and generate_perl_prototype name style =
8166 (match fst style with
8174 | RBufferOut n -> pr "$%s = " n
8176 | RHashtable n -> pr "%%%s = " n
8178 | RStructList (n,_) -> pr "@%s = " n
8181 let comma = ref false in
8184 if !comma then pr ", ";
8187 | Pathname n | Device n | Dev_or_Path n | String n
8188 | OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n ->
8190 | StringList n | DeviceList n ->
8195 (* Generate Python C module. *)
8196 and generate_python_c () =
8197 generate_header CStyle LGPLv2;
8206 #include \"guestfs.h\"
8214 get_handle (PyObject *obj)
8217 assert (obj != Py_None);
8218 return ((Pyguestfs_Object *) obj)->g;
8222 put_handle (guestfs_h *g)
8226 PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) \"guestfs_h\", NULL);
8229 /* This list should be freed (but not the strings) after use. */
8231 get_string_list (PyObject *obj)
8238 if (!PyList_Check (obj)) {
8239 PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
8243 len = PyList_Size (obj);
8244 r = malloc (sizeof (char *) * (len+1));
8246 PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
8250 for (i = 0; i < len; ++i)
8251 r[i] = PyString_AsString (PyList_GetItem (obj, i));
8258 put_string_list (char * const * const argv)
8263 for (argc = 0; argv[argc] != NULL; ++argc)
8266 list = PyList_New (argc);
8267 for (i = 0; i < argc; ++i)
8268 PyList_SetItem (list, i, PyString_FromString (argv[i]));
8274 put_table (char * const * const argv)
8276 PyObject *list, *item;
8279 for (argc = 0; argv[argc] != NULL; ++argc)
8282 list = PyList_New (argc >> 1);
8283 for (i = 0; i < argc; i += 2) {
8284 item = PyTuple_New (2);
8285 PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
8286 PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
8287 PyList_SetItem (list, i >> 1, item);
8294 free_strings (char **argv)
8298 for (argc = 0; argv[argc] != NULL; ++argc)
8304 py_guestfs_create (PyObject *self, PyObject *args)
8308 g = guestfs_create ();
8310 PyErr_SetString (PyExc_RuntimeError,
8311 \"guestfs.create: failed to allocate handle\");
8314 guestfs_set_error_handler (g, NULL, NULL);
8315 return put_handle (g);
8319 py_guestfs_close (PyObject *self, PyObject *args)
8324 if (!PyArg_ParseTuple (args, (char *) \"O:guestfs_close\", &py_g))
8326 g = get_handle (py_g);
8330 Py_INCREF (Py_None);
8336 let emit_put_list_function typ =
8337 pr "static PyObject *\n";
8338 pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
8340 pr " PyObject *list;\n";
8343 pr " list = PyList_New (%ss->len);\n" typ;
8344 pr " for (i = 0; i < %ss->len; ++i)\n" typ;
8345 pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
8346 pr " return list;\n";
8351 (* Structures, turned into Python dictionaries. *)
8354 pr "static PyObject *\n";
8355 pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
8357 pr " PyObject *dict;\n";
8359 pr " dict = PyDict_New ();\n";
8363 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8364 pr " PyString_FromString (%s->%s));\n"
8367 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8368 pr " PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
8371 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8372 pr " PyString_FromStringAndSize (%s->%s, 32));\n"
8374 | name, (FBytes|FUInt64) ->
8375 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8376 pr " PyLong_FromUnsignedLongLong (%s->%s));\n"
8379 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8380 pr " PyLong_FromLongLong (%s->%s));\n"
8383 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8384 pr " PyLong_FromUnsignedLong (%s->%s));\n"
8387 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8388 pr " PyLong_FromLong (%s->%s));\n"
8390 | name, FOptPercent ->
8391 pr " if (%s->%s >= 0)\n" typ name;
8392 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8393 pr " PyFloat_FromDouble ((double) %s->%s));\n"
8396 pr " Py_INCREF (Py_None);\n";
8397 pr " PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
8400 pr " PyDict_SetItemString (dict, \"%s\",\n" name;
8401 pr " PyString_FromStringAndSize (&dirent->%s, 1));\n" name
8403 pr " return dict;\n";
8409 (* Emit a put_TYPE_list function definition only if that function is used. *)
8412 | typ, (RStructListOnly | RStructAndList) ->
8413 (* generate the function for typ *)
8414 emit_put_list_function typ
8415 | typ, _ -> () (* empty *)
8416 ) (rstructs_used_by all_functions);
8418 (* Python wrapper functions. *)
8420 fun (name, style, _, _, _, _, _) ->
8421 pr "static PyObject *\n";
8422 pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
8425 pr " PyObject *py_g;\n";
8426 pr " guestfs_h *g;\n";
8427 pr " PyObject *py_r;\n";
8430 match fst style with
8431 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
8432 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8433 | RConstString _ | RConstOptString _ ->
8434 pr " const char *r;\n"; "NULL"
8435 | RString _ -> pr " char *r;\n"; "NULL"
8436 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
8437 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
8438 | RStructList (_, typ) ->
8439 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8442 pr " size_t size;\n";
8447 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
8448 pr " const char *%s;\n" n
8449 | OptString n -> pr " const char *%s;\n" n
8450 | StringList n | DeviceList n ->
8451 pr " PyObject *py_%s;\n" n;
8452 pr " char **%s;\n" n
8453 | Bool n -> pr " int %s;\n" n
8454 | Int n -> pr " int %s;\n" n
8455 | Int64 n -> pr " long long %s;\n" n
8460 (* Convert the parameters. *)
8461 pr " if (!PyArg_ParseTuple (args, (char *) \"O";
8464 | Pathname _ | Device _ | Dev_or_Path _ | String _ | FileIn _ | FileOut _ -> pr "s"
8465 | OptString _ -> pr "z"
8466 | StringList _ | DeviceList _ -> pr "O"
8467 | Bool _ -> pr "i" (* XXX Python has booleans? *)
8469 | Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
8470 * emulate C's int/long/long long in Python?
8473 pr ":guestfs_%s\",\n" name;
8477 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n -> pr ", &%s" n
8478 | OptString n -> pr ", &%s" n
8479 | StringList n | DeviceList n -> pr ", &py_%s" n
8480 | Bool n -> pr ", &%s" n
8481 | Int n -> pr ", &%s" n
8482 | Int64 n -> pr ", &%s" n
8486 pr " return NULL;\n";
8488 pr " g = get_handle (py_g);\n";
8491 | Pathname _ | Device _ | Dev_or_Path _ | String _
8492 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> ()
8493 | StringList n | DeviceList n ->
8494 pr " %s = get_string_list (py_%s);\n" n n;
8495 pr " if (!%s) return NULL;\n" n
8500 pr " r = guestfs_%s " name;
8501 generate_c_call_args ~handle:"g" style;
8506 | Pathname _ | Device _ | Dev_or_Path _ | String _
8507 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> ()
8508 | StringList n | DeviceList n ->
8509 pr " free (%s);\n" n
8512 pr " if (r == %s) {\n" error_code;
8513 pr " PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
8514 pr " return NULL;\n";
8518 (match fst style with
8520 pr " Py_INCREF (Py_None);\n";
8521 pr " py_r = Py_None;\n"
8523 | RBool _ -> pr " py_r = PyInt_FromLong ((long) r);\n"
8524 | RInt64 _ -> pr " py_r = PyLong_FromLongLong (r);\n"
8525 | RConstString _ -> pr " py_r = PyString_FromString (r);\n"
8526 | RConstOptString _ ->
8528 pr " py_r = PyString_FromString (r);\n";
8530 pr " Py_INCREF (Py_None);\n";
8531 pr " py_r = Py_None;\n";
8534 pr " py_r = PyString_FromString (r);\n";
8537 pr " py_r = put_string_list (r);\n";
8538 pr " free_strings (r);\n"
8539 | RStruct (_, typ) ->
8540 pr " py_r = put_%s (r);\n" typ;
8541 pr " guestfs_free_%s (r);\n" typ
8542 | RStructList (_, typ) ->
8543 pr " py_r = put_%s_list (r);\n" typ;
8544 pr " guestfs_free_%s_list (r);\n" typ
8546 pr " py_r = put_table (r);\n";
8547 pr " free_strings (r);\n"
8549 pr " py_r = PyString_FromStringAndSize (r, size);\n";
8553 pr " return py_r;\n";
8558 (* Table of functions. *)
8559 pr "static PyMethodDef methods[] = {\n";
8560 pr " { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
8561 pr " { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
8563 fun (name, _, _, _, _, _, _) ->
8564 pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
8567 pr " { NULL, NULL, 0, NULL }\n";
8571 (* Init function. *)
8574 initlibguestfsmod (void)
8576 static int initialized = 0;
8578 if (initialized) return;
8579 Py_InitModule ((char *) \"libguestfsmod\", methods);
8584 (* Generate Python module. *)
8585 and generate_python_py () =
8586 generate_header HashStyle LGPLv2;
8589 u\"\"\"Python bindings for libguestfs
8592 g = guestfs.GuestFS ()
8593 g.add_drive (\"guest.img\")
8595 parts = g.list_partitions ()
8597 The guestfs module provides a Python binding to the libguestfs API
8598 for examining and modifying virtual machine disk images.
8600 Amongst the things this is good for: making batch configuration
8601 changes to guests, getting disk used/free statistics (see also:
8602 virt-df), migrating between virtualization systems (see also:
8603 virt-p2v), performing partial backups, performing partial guest
8604 clones, cloning guests and changing registry/UUID/hostname info, and
8607 Libguestfs uses Linux kernel and qemu code, and can access any type of
8608 guest filesystem that Linux and qemu can, including but not limited
8609 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
8610 schemes, qcow, qcow2, vmdk.
8612 Libguestfs provides ways to enumerate guest storage (eg. partitions,
8613 LVs, what filesystem is in each LV, etc.). It can also run commands
8614 in the context of the guest. Also you can access filesystems over FTP.
8616 Errors which happen while using the API are turned into Python
8617 RuntimeError exceptions.
8619 To create a guestfs handle you usually have to perform the following
8622 # Create the handle, call add_drive at least once, and possibly
8623 # several times if the guest has multiple block devices:
8624 g = guestfs.GuestFS ()
8625 g.add_drive (\"guest.img\")
8627 # Launch the qemu subprocess and wait for it to become ready:
8630 # Now you can issue commands, for example:
8635 import libguestfsmod
8638 \"\"\"Instances of this class are libguestfs API handles.\"\"\"
8640 def __init__ (self):
8641 \"\"\"Create a new libguestfs handle.\"\"\"
8642 self._o = libguestfsmod.create ()
8645 libguestfsmod.close (self._o)
8650 fun (name, style, _, flags, _, _, longdesc) ->
8652 generate_py_call_args ~handle:"self" (snd style);
8655 if not (List.mem NotInDocs flags) then (
8656 let doc = replace_str longdesc "C<guestfs_" "C<g." in
8658 match fst style with
8659 | RErr | RInt _ | RInt64 _ | RBool _
8660 | RConstOptString _ | RConstString _
8661 | RString _ | RBufferOut _ -> doc
8663 doc ^ "\n\nThis function returns a list of strings."
8664 | RStruct (_, typ) ->
8665 doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
8666 | RStructList (_, typ) ->
8667 doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
8669 doc ^ "\n\nThis function returns a dictionary." in
8671 if List.mem ProtocolLimitWarning flags then
8672 doc ^ "\n\n" ^ protocol_limit_warning
8675 if List.mem DangerWillRobinson flags then
8676 doc ^ "\n\n" ^ danger_will_robinson
8679 match deprecation_notice flags with
8681 | Some txt -> doc ^ "\n\n" ^ txt in
8682 let doc = pod2text ~width:60 name doc in
8683 let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
8684 let doc = String.concat "\n " doc in
8685 pr " u\"\"\"%s\"\"\"\n" doc;
8687 pr " return libguestfsmod.%s " name;
8688 generate_py_call_args ~handle:"self._o" (snd style);
8693 (* Generate Python call arguments, eg "(handle, foo, bar)" *)
8694 and generate_py_call_args ~handle args =
8696 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
8699 (* Useful if you need the longdesc POD text as plain text. Returns a
8702 * Because this is very slow (the slowest part of autogeneration),
8703 * we memoize the results.
8705 and pod2text ~width name longdesc =
8706 let key = width, name, longdesc in
8707 try Hashtbl.find pod2text_memo key
8709 let filename, chan = Filename.open_temp_file "gen" ".tmp" in
8710 fprintf chan "=head1 %s\n\n%s\n" name longdesc;
8712 let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
8713 let chan = open_process_in cmd in
8714 let lines = ref [] in
8716 let line = input_line chan in
8717 if i = 1 then (* discard the first line of output *)
8720 let line = triml line in
8721 lines := line :: !lines;
8724 let lines = try loop 1 with End_of_file -> List.rev !lines in
8726 (match close_process_in chan with
8729 failwithf "pod2text: process exited with non-zero status (%d)" i
8730 | WSIGNALED i | WSTOPPED i ->
8731 failwithf "pod2text: process signalled or stopped by signal %d" i
8733 Hashtbl.add pod2text_memo key lines;
8734 pod2text_memo_updated ();
8737 (* Generate ruby bindings. *)
8738 and generate_ruby_c () =
8739 generate_header CStyle LGPLv2;
8747 #include \"guestfs.h\"
8749 #include \"extconf.h\"
8751 /* For Ruby < 1.9 */
8753 #define RARRAY_LEN(r) (RARRAY((r))->len)
8756 static VALUE m_guestfs; /* guestfs module */
8757 static VALUE c_guestfs; /* guestfs_h handle */
8758 static VALUE e_Error; /* used for all errors */
8760 static void ruby_guestfs_free (void *p)
8763 guestfs_close ((guestfs_h *) p);
8766 static VALUE ruby_guestfs_create (VALUE m)
8770 g = guestfs_create ();
8772 rb_raise (e_Error, \"failed to create guestfs handle\");
8774 /* Don't print error messages to stderr by default. */
8775 guestfs_set_error_handler (g, NULL, NULL);
8777 /* Wrap it, and make sure the close function is called when the
8780 return Data_Wrap_Struct (c_guestfs, NULL, ruby_guestfs_free, g);
8783 static VALUE ruby_guestfs_close (VALUE gv)
8786 Data_Get_Struct (gv, guestfs_h, g);
8788 ruby_guestfs_free (g);
8789 DATA_PTR (gv) = NULL;
8797 fun (name, style, _, _, _, _, _) ->
8798 pr "static VALUE ruby_guestfs_%s (VALUE gv" name;
8799 List.iter (fun arg -> pr ", VALUE %sv" (name_of_argt arg)) (snd style);
8802 pr " guestfs_h *g;\n";
8803 pr " Data_Get_Struct (gv, guestfs_h, g);\n";
8805 pr " rb_raise (rb_eArgError, \"%%s: used handle after closing it\", \"%s\");\n"
8811 | Pathname n | Device n | Dev_or_Path n | String n | FileIn n | FileOut n ->
8812 pr " Check_Type (%sv, T_STRING);\n" n;
8813 pr " const char *%s = StringValueCStr (%sv);\n" n n;
8815 pr " rb_raise (rb_eTypeError, \"expected string for parameter %%s of %%s\",\n";
8816 pr " \"%s\", \"%s\");\n" n name
8818 pr " const char *%s = !NIL_P (%sv) ? StringValueCStr (%sv) : NULL;\n" n n n
8819 | StringList n | DeviceList n ->
8820 pr " char **%s;\n" n;
8821 pr " Check_Type (%sv, T_ARRAY);\n" n;
8823 pr " int i, len;\n";
8824 pr " len = RARRAY_LEN (%sv);\n" n;
8825 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (len+1));\n"
8827 pr " for (i = 0; i < len; ++i) {\n";
8828 pr " VALUE v = rb_ary_entry (%sv, i);\n" n;
8829 pr " %s[i] = StringValueCStr (v);\n" n;
8831 pr " %s[len] = NULL;\n" n;
8834 pr " int %s = RTEST (%sv);\n" n n
8836 pr " int %s = NUM2INT (%sv);\n" n n
8838 pr " long long %s = NUM2LL (%sv);\n" n n
8843 match fst style with
8844 | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
8845 | RInt64 _ -> pr " int64_t r;\n"; "-1"
8846 | RConstString _ | RConstOptString _ ->
8847 pr " const char *r;\n"; "NULL"
8848 | RString _ -> pr " char *r;\n"; "NULL"
8849 | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
8850 | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
8851 | RStructList (_, typ) ->
8852 pr " struct guestfs_%s_list *r;\n" typ; "NULL"
8855 pr " size_t size;\n";
8859 pr " r = guestfs_%s " name;
8860 generate_c_call_args ~handle:"g" style;
8865 | Pathname _ | Device _ | Dev_or_Path _ | String _
8866 | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _ -> ()
8867 | StringList n | DeviceList n ->
8868 pr " free (%s);\n" n
8871 pr " if (r == %s)\n" error_code;
8872 pr " rb_raise (e_Error, \"%%s\", guestfs_last_error (g));\n";
8875 (match fst style with
8877 pr " return Qnil;\n"
8878 | RInt _ | RBool _ ->
8879 pr " return INT2NUM (r);\n"
8881 pr " return ULL2NUM (r);\n"
8883 pr " return rb_str_new2 (r);\n";
8884 | RConstOptString _ ->
8886 pr " return rb_str_new2 (r);\n";
8888 pr " return Qnil;\n";
8890 pr " VALUE rv = rb_str_new2 (r);\n";
8894 pr " int i, len = 0;\n";
8895 pr " for (i = 0; r[i] != NULL; ++i) len++;\n";
8896 pr " VALUE rv = rb_ary_new2 (len);\n";
8897 pr " for (i = 0; r[i] != NULL; ++i) {\n";
8898 pr " rb_ary_push (rv, rb_str_new2 (r[i]));\n";
8899 pr " free (r[i]);\n";
8903 | RStruct (_, typ) ->
8904 let cols = cols_of_struct typ in
8905 generate_ruby_struct_code typ cols
8906 | RStructList (_, typ) ->
8907 let cols = cols_of_struct typ in
8908 generate_ruby_struct_list_code typ cols
8910 pr " VALUE rv = rb_hash_new ();\n";
8912 pr " for (i = 0; r[i] != NULL; i+=2) {\n";
8913 pr " rb_hash_aset (rv, rb_str_new2 (r[i]), rb_str_new2 (r[i+1]));\n";
8914 pr " free (r[i]);\n";
8915 pr " free (r[i+1]);\n";
8920 pr " VALUE rv = rb_str_new (r, size);\n";
8930 /* Initialize the module. */
8931 void Init__guestfs ()
8933 m_guestfs = rb_define_module (\"Guestfs\");
8934 c_guestfs = rb_define_class_under (m_guestfs, \"Guestfs\", rb_cObject);
8935 e_Error = rb_define_class_under (m_guestfs, \"Error\", rb_eStandardError);
8937 rb_define_module_function (m_guestfs, \"create\", ruby_guestfs_create, 0);
8938 rb_define_method (c_guestfs, \"close\", ruby_guestfs_close, 0);
8941 (* Define the rest of the methods. *)
8943 fun (name, style, _, _, _, _, _) ->
8944 pr " rb_define_method (c_guestfs, \"%s\",\n" name;
8945 pr " ruby_guestfs_%s, %d);\n" name (List.length (snd style))
8950 (* Ruby code to return a struct. *)
8951 and generate_ruby_struct_code typ cols =
8952 pr " VALUE rv = rb_hash_new ();\n";
8956 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new2 (r->%s));\n" name name
8958 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, r->%s_len));\n" name name name
8960 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_str_new (r->%s, 32));\n" name name
8961 | name, (FBytes|FUInt64) ->
8962 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
8964 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), LL2NUM (r->%s));\n" name name
8966 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), UINT2NUM (r->%s));\n" name name
8968 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), INT2NUM (r->%s));\n" name name
8969 | name, FOptPercent ->
8970 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), rb_dbl2big (r->%s));\n" name name
8971 | name, FChar -> (* XXX wrong? *)
8972 pr " rb_hash_aset (rv, rb_str_new2 (\"%s\"), ULL2NUM (r->%s));\n" name name
8974 pr " guestfs_free_%s (r);\n" typ;
8977 (* Ruby code to return a struct list. *)
8978 and generate_ruby_struct_list_code typ cols =
8979 pr " VALUE rv = rb_ary_new2 (r->len);\n";
8981 pr " for (i = 0; i < r->len; ++i) {\n";
8982 pr " VALUE hv = rb_hash_new ();\n";
8986 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new2 (r->val[i].%s));\n" name name
8988 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
8990 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_str_new (r->val[i].%s, 32));\n" name name
8991 | name, (FBytes|FUInt64) ->
8992 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
8994 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), LL2NUM (r->val[i].%s));\n" name name
8996 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), UINT2NUM (r->val[i].%s));\n" name name
8998 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), INT2NUM (r->val[i].%s));\n" name name
8999 | name, FOptPercent ->
9000 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), rb_dbl2big (r->val[i].%s));\n" name name
9001 | name, FChar -> (* XXX wrong? *)
9002 pr " rb_hash_aset (hv, rb_str_new2 (\"%s\"), ULL2NUM (r->val[i].%s));\n" name name
9004 pr " rb_ary_push (rv, hv);\n";
9006 pr " guestfs_free_%s_list (r);\n" typ;
9009 (* Generate Java bindings GuestFS.java file. *)
9010 and generate_java_java () =
9011 generate_header CStyle LGPLv2;
9014 package com.redhat.et.libguestfs;
9016 import java.util.HashMap;
9017 import com.redhat.et.libguestfs.LibGuestFSException;
9018 import com.redhat.et.libguestfs.PV;
9019 import com.redhat.et.libguestfs.VG;
9020 import com.redhat.et.libguestfs.LV;
9021 import com.redhat.et.libguestfs.Stat;
9022 import com.redhat.et.libguestfs.StatVFS;
9023 import com.redhat.et.libguestfs.IntBool;
9024 import com.redhat.et.libguestfs.Dirent;
9027 * The GuestFS object is a libguestfs handle.
9031 public class GuestFS {
9032 // Load the native code.
9034 System.loadLibrary (\"guestfs_jni\");
9038 * The native guestfs_h pointer.
9043 * Create a libguestfs handle.
9045 * @throws LibGuestFSException
9047 public GuestFS () throws LibGuestFSException
9051 private native long _create () throws LibGuestFSException;
9054 * Close a libguestfs handle.
9056 * You can also leave handles to be collected by the garbage
9057 * collector, but this method ensures that the resources used
9058 * by the handle are freed up immediately. If you call any
9059 * other methods after closing the handle, you will get an
9062 * @throws LibGuestFSException
9064 public void close () throws LibGuestFSException
9070 private native void _close (long g) throws LibGuestFSException;
9072 public void finalize () throws LibGuestFSException
9080 fun (name, style, _, flags, _, shortdesc, longdesc) ->
9081 if not (List.mem NotInDocs flags); then (
9082 let doc = replace_str longdesc "C<guestfs_" "C<g." in
9084 if List.mem ProtocolLimitWarning flags then
9085 doc ^ "\n\n" ^ protocol_limit_warning
9088 if List.mem DangerWillRobinson flags then
9089 doc ^ "\n\n" ^ danger_will_robinson
9092 match deprecation_notice flags with
9094 | Some txt -> doc ^ "\n\n" ^ txt in
9095 let doc = pod2text ~width:60 name doc in
9096 let doc = List.map ( (* RHBZ#501883 *)
9099 | nonempty -> nonempty
9101 let doc = String.concat "\n * " doc in
9104 pr " * %s\n" shortdesc;
9107 pr " * @throws LibGuestFSException\n";
9111 generate_java_prototype ~public:true ~semicolon:false name style;
9114 pr " if (g == 0)\n";
9115 pr " throw new LibGuestFSException (\"%s: handle is closed\");\n"
9118 if fst style <> RErr then pr "return ";
9120 generate_java_call_args ~handle:"g" (snd style);
9124 generate_java_prototype ~privat:true ~native:true name style;
9131 (* Generate Java call arguments, eg "(handle, foo, bar)" *)
9132 and generate_java_call_args ~handle args =
9134 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
9137 and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
9138 ?(semicolon=true) name style =
9139 if privat then pr "private ";
9140 if public then pr "public ";
9141 if native then pr "native ";
9144 (match fst style with
9145 | RErr -> pr "void ";
9146 | RInt _ -> pr "int ";
9147 | RInt64 _ -> pr "long ";
9148 | RBool _ -> pr "boolean ";
9149 | RConstString _ | RConstOptString _ | RString _
9150 | RBufferOut _ -> pr "String ";
9151 | RStringList _ -> pr "String[] ";
9152 | RStruct (_, typ) ->
9153 let name = java_name_of_struct typ in
9155 | RStructList (_, typ) ->
9156 let name = java_name_of_struct typ in
9158 | RHashtable _ -> pr "HashMap<String,String> ";
9161 if native then pr "_%s " name else pr "%s " name;
9163 let needs_comma = ref false in
9172 if !needs_comma then pr ", ";
9173 needs_comma := true;
9177 | Device n | Dev_or_Path n
9183 | StringList n | DeviceList n ->
9194 pr " throws LibGuestFSException";
9195 if semicolon then pr ";"
9197 and generate_java_struct jtyp cols =
9198 generate_header CStyle LGPLv2;
9201 package com.redhat.et.libguestfs;
9204 * Libguestfs %s structure.
9216 | name, FBuffer -> pr " public String %s;\n" name
9217 | name, (FBytes|FUInt64|FInt64) -> pr " public long %s;\n" name
9218 | name, (FUInt32|FInt32) -> pr " public int %s;\n" name
9219 | name, FChar -> pr " public char %s;\n" name
9220 | name, FOptPercent ->
9221 pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
9222 pr " public float %s;\n" name
9227 and generate_java_c () =
9228 generate_header CStyle LGPLv2;
9235 #include \"com_redhat_et_libguestfs_GuestFS.h\"
9236 #include \"guestfs.h\"
9238 /* Note that this function returns. The exception is not thrown
9239 * until after the wrapper function returns.
9242 throw_exception (JNIEnv *env, const char *msg)
9245 cl = (*env)->FindClass (env,
9246 \"com/redhat/et/libguestfs/LibGuestFSException\");
9247 (*env)->ThrowNew (env, cl, msg);
9250 JNIEXPORT jlong JNICALL
9251 Java_com_redhat_et_libguestfs_GuestFS__1create
9252 (JNIEnv *env, jobject obj)
9256 g = guestfs_create ();
9258 throw_exception (env, \"GuestFS.create: failed to allocate handle\");
9261 guestfs_set_error_handler (g, NULL, NULL);
9262 return (jlong) (long) g;
9265 JNIEXPORT void JNICALL
9266 Java_com_redhat_et_libguestfs_GuestFS__1close
9267 (JNIEnv *env, jobject obj, jlong jg)
9269 guestfs_h *g = (guestfs_h *) (long) jg;
9276 fun (name, style, _, _, _, _, _) ->
9278 (match fst style with
9279 | RErr -> pr "void ";
9280 | RInt _ -> pr "jint ";
9281 | RInt64 _ -> pr "jlong ";
9282 | RBool _ -> pr "jboolean ";
9283 | RConstString _ | RConstOptString _ | RString _
9284 | RBufferOut _ -> pr "jstring ";
9285 | RStruct _ | RHashtable _ ->
9287 | RStringList _ | RStructList _ ->
9291 pr "Java_com_redhat_et_libguestfs_GuestFS_";
9292 pr "%s" (replace_str ("_" ^ name) "_" "_1");
9294 pr " (JNIEnv *env, jobject obj, jlong jg";
9298 | Device n | Dev_or_Path n
9303 pr ", jstring j%s" n
9304 | StringList n | DeviceList n ->
9305 pr ", jobjectArray j%s" n
9307 pr ", jboolean j%s" n
9315 pr " guestfs_h *g = (guestfs_h *) (long) jg;\n";
9316 let error_code, no_ret =
9317 match fst style with
9318 | RErr -> pr " int r;\n"; "-1", ""
9320 | RInt _ -> pr " int r;\n"; "-1", "0"
9321 | RInt64 _ -> pr " int64_t r;\n"; "-1", "0"
9322 | RConstString _ -> pr " const char *r;\n"; "NULL", "NULL"
9323 | RConstOptString _ -> pr " const char *r;\n"; "NULL", "NULL"
9325 pr " jstring jr;\n";
9326 pr " char *r;\n"; "NULL", "NULL"
9328 pr " jobjectArray jr;\n";
9331 pr " jstring jstr;\n";
9332 pr " char **r;\n"; "NULL", "NULL"
9333 | RStruct (_, typ) ->
9334 pr " jobject jr;\n";
9336 pr " jfieldID fl;\n";
9337 pr " struct guestfs_%s *r;\n" typ; "NULL", "NULL"
9338 | RStructList (_, typ) ->
9339 pr " jobjectArray jr;\n";
9341 pr " jfieldID fl;\n";
9342 pr " jobject jfl;\n";
9343 pr " struct guestfs_%s_list *r;\n" typ; "NULL", "NULL"
9344 | RHashtable _ -> pr " char **r;\n"; "NULL", "NULL"
9346 pr " jstring jr;\n";
9348 pr " size_t size;\n";
9353 | Device n | Dev_or_Path n
9358 pr " const char *%s;\n" n
9359 | StringList n | DeviceList n ->
9360 pr " int %s_len;\n" n;
9361 pr " const char **%s;\n" n
9366 pr " int64_t %s;\n" n
9370 (match fst style with
9371 | RStringList _ | RStructList _ -> true
9372 | RErr | RBool _ | RInt _ | RInt64 _ | RConstString _
9374 | RString _ | RBufferOut _ | RStruct _ | RHashtable _ -> false) ||
9375 List.exists (function
9376 | StringList _ -> true
9377 | DeviceList _ -> true
9378 | _ -> false) (snd style) in
9384 (* Get the parameters. *)
9388 | Device n | Dev_or_Path n
9392 pr " %s = (*env)->GetStringUTFChars (env, j%s, NULL);\n" n n
9394 (* This is completely undocumented, but Java null becomes
9397 pr " %s = j%s ? (*env)->GetStringUTFChars (env, j%s, NULL) : NULL;\n" n n n
9398 | StringList n | DeviceList n ->
9399 pr " %s_len = (*env)->GetArrayLength (env, j%s);\n" n n;
9400 pr " %s = guestfs_safe_malloc (g, sizeof (char *) * (%s_len+1));\n" n n;
9401 pr " for (i = 0; i < %s_len; ++i) {\n" n;
9402 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
9404 pr " %s[i] = (*env)->GetStringUTFChars (env, o, NULL);\n" n;
9406 pr " %s[%s_len] = NULL;\n" n n;
9410 pr " %s = j%s;\n" n n
9413 (* Make the call. *)
9414 pr " r = guestfs_%s " name;
9415 generate_c_call_args ~handle:"g" style;
9418 (* Release the parameters. *)
9422 | Device n | Dev_or_Path n
9426 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
9429 pr " (*env)->ReleaseStringUTFChars (env, j%s, %s);\n" n n
9430 | StringList n | DeviceList n ->
9431 pr " for (i = 0; i < %s_len; ++i) {\n" n;
9432 pr " jobject o = (*env)->GetObjectArrayElement (env, j%s, i);\n"
9434 pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
9436 pr " free (%s);\n" n
9442 (* Check for errors. *)
9443 pr " if (r == %s) {\n" error_code;
9444 pr " throw_exception (env, guestfs_last_error (g));\n";
9445 pr " return %s;\n" no_ret;
9449 (match fst style with
9451 | RInt _ -> pr " return (jint) r;\n"
9452 | RBool _ -> pr " return (jboolean) r;\n"
9453 | RInt64 _ -> pr " return (jlong) r;\n"
9454 | RConstString _ -> pr " return (*env)->NewStringUTF (env, r);\n"
9455 | RConstOptString _ ->
9456 pr " return (*env)->NewStringUTF (env, r); /* XXX r NULL? */\n"
9458 pr " jr = (*env)->NewStringUTF (env, r);\n";
9462 pr " for (r_len = 0; r[r_len] != NULL; ++r_len) ;\n";
9463 pr " cl = (*env)->FindClass (env, \"java/lang/String\");\n";
9464 pr " jstr = (*env)->NewStringUTF (env, \"\");\n";
9465 pr " jr = (*env)->NewObjectArray (env, r_len, cl, jstr);\n";
9466 pr " for (i = 0; i < r_len; ++i) {\n";
9467 pr " jstr = (*env)->NewStringUTF (env, r[i]);\n";
9468 pr " (*env)->SetObjectArrayElement (env, jr, i, jstr);\n";
9469 pr " free (r[i]);\n";
9473 | RStruct (_, typ) ->
9474 let jtyp = java_name_of_struct typ in
9475 let cols = cols_of_struct typ in
9476 generate_java_struct_return typ jtyp cols
9477 | RStructList (_, typ) ->
9478 let jtyp = java_name_of_struct typ in
9479 let cols = cols_of_struct typ in
9480 generate_java_struct_list_return typ jtyp cols
9483 pr " throw_exception (env, \"%s: internal error: please let us know how to make a Java HashMap from JNI bindings!\");\n" name;
9484 pr " return NULL;\n"
9486 pr " jr = (*env)->NewStringUTF (env, r); /* XXX size */\n";
9495 and generate_java_struct_return typ jtyp cols =
9496 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
9497 pr " jr = (*env)->AllocObject (env, cl);\n";
9501 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9502 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, r->%s));\n" name;
9505 pr " char s[33];\n";
9506 pr " memcpy (s, r->%s, 32);\n" name;
9508 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9509 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
9513 pr " int len = r->%s_len;\n" name;
9514 pr " char s[len+1];\n";
9515 pr " memcpy (s, r->%s, len);\n" name;
9516 pr " s[len] = 0;\n";
9517 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9518 pr " (*env)->SetObjectField (env, jr, fl, (*env)->NewStringUTF (env, s));\n";
9520 | name, (FBytes|FUInt64|FInt64) ->
9521 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
9522 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
9523 | name, (FUInt32|FInt32) ->
9524 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
9525 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
9526 | name, FOptPercent ->
9527 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
9528 pr " (*env)->SetFloatField (env, jr, fl, r->%s);\n" name;
9530 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
9531 pr " (*env)->SetLongField (env, jr, fl, r->%s);\n" name;
9536 and generate_java_struct_list_return typ jtyp cols =
9537 pr " cl = (*env)->FindClass (env, \"com/redhat/et/libguestfs/%s\");\n" jtyp;
9538 pr " jr = (*env)->NewObjectArray (env, r->len, cl, NULL);\n";
9539 pr " for (i = 0; i < r->len; ++i) {\n";
9540 pr " jfl = (*env)->AllocObject (env, cl);\n";
9544 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9545 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, r->val[i].%s));\n" name;
9548 pr " char s[33];\n";
9549 pr " memcpy (s, r->val[i].%s, 32);\n" name;
9551 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9552 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
9556 pr " int len = r->val[i].%s_len;\n" name;
9557 pr " char s[len+1];\n";
9558 pr " memcpy (s, r->val[i].%s, len);\n" name;
9559 pr " s[len] = 0;\n";
9560 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"Ljava/lang/String;\");\n" name;
9561 pr " (*env)->SetObjectField (env, jfl, fl, (*env)->NewStringUTF (env, s));\n";
9563 | name, (FBytes|FUInt64|FInt64) ->
9564 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"J\");\n" name;
9565 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
9566 | name, (FUInt32|FInt32) ->
9567 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"I\");\n" name;
9568 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
9569 | name, FOptPercent ->
9570 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"F\");\n" name;
9571 pr " (*env)->SetFloatField (env, jfl, fl, r->val[i].%s);\n" name;
9573 pr " fl = (*env)->GetFieldID (env, cl, \"%s\", \"C\");\n" name;
9574 pr " (*env)->SetLongField (env, jfl, fl, r->val[i].%s);\n" name;
9576 pr " (*env)->SetObjectArrayElement (env, jfl, i, jfl);\n";
9578 pr " guestfs_free_%s_list (r);\n" typ;
9581 and generate_java_makefile_inc () =
9582 generate_header HashStyle GPLv2;
9584 pr "java_built_sources = \\\n";
9587 pr "\tcom/redhat/et/libguestfs/%s.java \\\n" jtyp;
9589 pr "\tcom/redhat/et/libguestfs/GuestFS.java\n"
9591 and generate_haskell_hs () =
9592 generate_header HaskellStyle LGPLv2;
9594 (* XXX We only know how to generate partial FFI for Haskell
9595 * at the moment. Please help out!
9597 let can_generate style =
9601 | RInt64 _, _ -> true
9604 | RConstOptString _, _
9610 | RBufferOut _, _ -> false in
9613 {-# INCLUDE <guestfs.h> #-}
9614 {-# LANGUAGE ForeignFunctionInterface #-}
9619 (* List out the names of the actions we want to export. *)
9621 fun (name, style, _, _, _, _, _) ->
9622 if can_generate style then pr ",\n %s" name
9628 -- Unfortunately some symbols duplicate ones already present
9629 -- in Prelude. We don't know which, so we hard-code a list
9631 import Prelude hiding (truncate)
9635 import Foreign.C.Types
9637 import Control.Exception
9638 import Data.Typeable
9640 data GuestfsS = GuestfsS -- represents the opaque C struct
9641 type GuestfsP = Ptr GuestfsS -- guestfs_h *
9642 type GuestfsH = ForeignPtr GuestfsS -- guestfs_h * with attached finalizer
9644 -- XXX define properly later XXX
9648 data IntBool = IntBool
9650 data StatVFS = StatVFS
9651 data Hashtable = Hashtable
9653 foreign import ccall unsafe \"guestfs_create\" c_create
9655 foreign import ccall unsafe \"&guestfs_close\" c_close
9656 :: FunPtr (GuestfsP -> IO ())
9657 foreign import ccall unsafe \"guestfs_set_error_handler\" c_set_error_handler
9658 :: GuestfsP -> Ptr CInt -> Ptr CInt -> IO ()
9660 create :: IO GuestfsH
9663 c_set_error_handler p nullPtr nullPtr
9664 h <- newForeignPtr c_close p
9667 foreign import ccall unsafe \"guestfs_last_error\" c_last_error
9668 :: GuestfsP -> IO CString
9670 -- last_error :: GuestfsH -> IO (Maybe String)
9671 -- last_error h = do
9672 -- str <- withForeignPtr h (\\p -> c_last_error p)
9673 -- maybePeek peekCString str
9675 last_error :: GuestfsH -> IO (String)
9677 str <- withForeignPtr h (\\p -> c_last_error p)
9679 then return \"no error\"
9680 else peekCString str
9684 (* Generate wrappers for each foreign function. *)
9686 fun (name, style, _, _, _, _, _) ->
9687 if can_generate style then (
9688 pr "foreign import ccall unsafe \"guestfs_%s\" c_%s\n" name name;
9690 generate_haskell_prototype ~handle:"GuestfsP" style;
9694 generate_haskell_prototype ~handle:"GuestfsH" ~hs:true style;
9696 pr "%s %s = do\n" name
9697 (String.concat " " ("h" :: List.map name_of_argt (snd style)));
9699 (* Convert pointer arguments using with* functions. *)
9704 | Pathname n | Device n | Dev_or_Path n | String n -> pr "withCString %s $ \\%s -> " n n
9705 | OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
9706 | StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
9707 | Bool _ | Int _ | Int64 _ -> ()
9709 (* Convert integer arguments. *)
9713 | Bool n -> sprintf "(fromBool %s)" n
9714 | Int n -> sprintf "(fromIntegral %s)" n
9715 | Int64 n -> sprintf "(fromIntegral %s)" n
9716 | FileIn n | FileOut n
9717 | Pathname n | Device n | Dev_or_Path n | String n | OptString n | StringList n | DeviceList n -> n
9719 pr "withForeignPtr h (\\p -> c_%s %s)\n" name
9720 (String.concat " " ("p" :: args));
9721 (match fst style with
9722 | RErr | RInt _ | RInt64 _ | RBool _ ->
9723 pr " if (r == -1)\n";
9725 pr " err <- last_error h\n";
9727 | RConstString _ | RConstOptString _ | RString _
9728 | RStringList _ | RStruct _
9729 | RStructList _ | RHashtable _ | RBufferOut _ ->
9730 pr " if (r == nullPtr)\n";
9732 pr " err <- last_error h\n";
9735 (match fst style with
9737 pr " else return ()\n"
9739 pr " else return (fromIntegral r)\n"
9741 pr " else return (fromIntegral r)\n"
9743 pr " else return (toBool r)\n"
9752 pr " else return ()\n" (* XXXXXXXXXXXXXXXXXXXX *)
9758 and generate_haskell_prototype ~handle ?(hs = false) style =
9760 let string = if hs then "String" else "CString" in
9761 let int = if hs then "Int" else "CInt" in
9762 let bool = if hs then "Bool" else "CInt" in
9763 let int64 = if hs then "Integer" else "Int64" in
9767 | Pathname _ | Device _ | Dev_or_Path _ | String _ -> pr "%s" string
9768 | OptString _ -> if hs then pr "Maybe String" else pr "CString"
9769 | StringList _ | DeviceList _ -> if hs then pr "[String]" else pr "Ptr CString"
9770 | Bool _ -> pr "%s" bool
9771 | Int _ -> pr "%s" int
9772 | Int64 _ -> pr "%s" int
9773 | FileIn _ -> pr "%s" string
9774 | FileOut _ -> pr "%s" string
9779 (match fst style with
9780 | RErr -> if not hs then pr "CInt"
9781 | RInt _ -> pr "%s" int
9782 | RInt64 _ -> pr "%s" int64
9783 | RBool _ -> pr "%s" bool
9784 | RConstString _ -> pr "%s" string
9785 | RConstOptString _ -> pr "Maybe %s" string
9786 | RString _ -> pr "%s" string
9787 | RStringList _ -> pr "[%s]" string
9788 | RStruct (_, typ) ->
9789 let name = java_name_of_struct typ in
9791 | RStructList (_, typ) ->
9792 let name = java_name_of_struct typ in
9794 | RHashtable _ -> pr "Hashtable"
9795 | RBufferOut _ -> pr "%s" string
9799 and generate_bindtests () =
9800 generate_header CStyle LGPLv2;
9805 #include <inttypes.h>
9808 #include \"guestfs.h\"
9809 #include \"guestfs-internal.h\"
9810 #include \"guestfs-internal-actions.h\"
9811 #include \"guestfs_protocol.h\"
9813 #define error guestfs_error
9814 #define safe_calloc guestfs_safe_calloc
9815 #define safe_malloc guestfs_safe_malloc
9818 print_strings (char *const *argv)
9823 for (argc = 0; argv[argc] != NULL; ++argc) {
9824 if (argc > 0) printf (\", \");
9825 printf (\"\\\"%%s\\\"\", argv[argc]);
9830 /* The test0 function prints its parameters to stdout. */
9834 match test_functions with
9835 | [] -> assert false
9836 | test0 :: tests -> test0, tests in
9839 let (name, style, _, _, _, _, _) = test0 in
9840 generate_prototype ~extern:false ~semicolon:false ~newline:true
9841 ~handle:"g" ~prefix:"guestfs__" name style;
9846 | Device n | Dev_or_Path n
9849 | FileOut n -> pr " printf (\"%%s\\n\", %s);\n" n
9850 | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
9851 | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
9852 | Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
9853 | Int n -> pr " printf (\"%%d\\n\", %s);\n" n
9854 | Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
9856 pr " /* Java changes stdout line buffering so we need this: */\n";
9857 pr " fflush (stdout);\n";
9863 fun (name, style, _, _, _, _, _) ->
9864 if String.sub name (String.length name - 3) 3 <> "err" then (
9865 pr "/* Test normal return. */\n";
9866 generate_prototype ~extern:false ~semicolon:false ~newline:true
9867 ~handle:"g" ~prefix:"guestfs__" name style;
9869 (match fst style with
9874 pr " sscanf (val, \"%%d\", &r);\n";
9878 pr " sscanf (val, \"%%\" SCNi64, &r);\n";
9881 pr " return STREQ (val, \"true\");\n"
9883 | RConstOptString _ ->
9884 (* Can't return the input string here. Return a static
9885 * string so we ensure we get a segfault if the caller
9888 pr " return \"static string\";\n"
9890 pr " return strdup (val);\n"
9892 pr " char **strs;\n";
9894 pr " sscanf (val, \"%%d\", &n);\n";
9895 pr " strs = safe_malloc (g, (n+1) * sizeof (char *));\n";
9896 pr " for (i = 0; i < n; ++i) {\n";
9897 pr " strs[i] = safe_malloc (g, 16);\n";
9898 pr " snprintf (strs[i], 16, \"%%d\", i);\n";
9900 pr " strs[n] = NULL;\n";
9901 pr " return strs;\n"
9902 | RStruct (_, typ) ->
9903 pr " struct guestfs_%s *r;\n" typ;
9904 pr " r = safe_calloc (g, sizeof *r, 1);\n";
9906 | RStructList (_, typ) ->
9907 pr " struct guestfs_%s_list *r;\n" typ;
9908 pr " r = safe_calloc (g, sizeof *r, 1);\n";
9909 pr " sscanf (val, \"%%d\", &r->len);\n";
9910 pr " r->val = safe_calloc (g, r->len, sizeof *r->val);\n";
9913 pr " char **strs;\n";
9915 pr " sscanf (val, \"%%d\", &n);\n";
9916 pr " strs = safe_malloc (g, (n*2+1) * sizeof (*strs));\n";
9917 pr " for (i = 0; i < n; ++i) {\n";
9918 pr " strs[i*2] = safe_malloc (g, 16);\n";
9919 pr " strs[i*2+1] = safe_malloc (g, 16);\n";
9920 pr " snprintf (strs[i*2], 16, \"%%d\", i);\n";
9921 pr " snprintf (strs[i*2+1], 16, \"%%d\", i);\n";
9923 pr " strs[n*2] = NULL;\n";
9924 pr " return strs;\n"
9926 pr " return strdup (val);\n"
9931 pr "/* Test error return. */\n";
9932 generate_prototype ~extern:false ~semicolon:false ~newline:true
9933 ~handle:"g" ~prefix:"guestfs__" name style;
9935 pr " error (g, \"error\");\n";
9936 (match fst style with
9937 | RErr | RInt _ | RInt64 _ | RBool _ ->
9939 | RConstString _ | RConstOptString _
9940 | RString _ | RStringList _ | RStruct _
9944 pr " return NULL;\n"
9951 and generate_ocaml_bindtests () =
9952 generate_header OCamlStyle GPLv2;
9956 let g = Guestfs.create () in
9963 | CallString s -> "\"" ^ s ^ "\""
9964 | CallOptString None -> "None"
9965 | CallOptString (Some s) -> sprintf "(Some \"%s\")" s
9966 | CallStringList xs ->
9967 "[|" ^ String.concat ";" (List.map (sprintf "\"%s\"") xs) ^ "|]"
9968 | CallInt i when i >= 0 -> string_of_int i
9969 | CallInt i (* when i < 0 *) -> "(" ^ string_of_int i ^ ")"
9970 | CallInt64 i when i >= 0L -> Int64.to_string i ^ "L"
9971 | CallInt64 i (* when i < 0L *) -> "(" ^ Int64.to_string i ^ "L)"
9972 | CallBool b -> string_of_bool b
9977 generate_lang_bindtests (
9978 fun f args -> pr " Guestfs.%s g %s;\n" f (mkargs args)
9981 pr "print_endline \"EOF\"\n"
9983 and generate_perl_bindtests () =
9984 pr "#!/usr/bin/perl -w\n";
9985 generate_header HashStyle GPLv2;
9992 my $g = Sys::Guestfs->new ();
9996 String.concat ", " (
9999 | CallString s -> "\"" ^ s ^ "\""
10000 | CallOptString None -> "undef"
10001 | CallOptString (Some s) -> sprintf "\"%s\"" s
10002 | CallStringList xs ->
10003 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
10004 | CallInt i -> string_of_int i
10005 | CallInt64 i -> Int64.to_string i
10006 | CallBool b -> if b then "1" else "0"
10011 generate_lang_bindtests (
10012 fun f args -> pr "$g->%s (%s);\n" f (mkargs args)
10015 pr "print \"EOF\\n\"\n"
10017 and generate_python_bindtests () =
10018 generate_header HashStyle GPLv2;
10023 g = guestfs.GuestFS ()
10027 String.concat ", " (
10030 | CallString s -> "\"" ^ s ^ "\""
10031 | CallOptString None -> "None"
10032 | CallOptString (Some s) -> sprintf "\"%s\"" s
10033 | CallStringList xs ->
10034 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
10035 | CallInt i -> string_of_int i
10036 | CallInt64 i -> Int64.to_string i
10037 | CallBool b -> if b then "1" else "0"
10042 generate_lang_bindtests (
10043 fun f args -> pr "g.%s (%s)\n" f (mkargs args)
10046 pr "print \"EOF\"\n"
10048 and generate_ruby_bindtests () =
10049 generate_header HashStyle GPLv2;
10054 g = Guestfs::create()
10058 String.concat ", " (
10061 | CallString s -> "\"" ^ s ^ "\""
10062 | CallOptString None -> "nil"
10063 | CallOptString (Some s) -> sprintf "\"%s\"" s
10064 | CallStringList xs ->
10065 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
10066 | CallInt i -> string_of_int i
10067 | CallInt64 i -> Int64.to_string i
10068 | CallBool b -> string_of_bool b
10073 generate_lang_bindtests (
10074 fun f args -> pr "g.%s(%s)\n" f (mkargs args)
10077 pr "print \"EOF\\n\"\n"
10079 and generate_java_bindtests () =
10080 generate_header CStyle GPLv2;
10083 import com.redhat.et.libguestfs.*;
10085 public class Bindtests {
10086 public static void main (String[] argv)
10089 GuestFS g = new GuestFS ();
10093 String.concat ", " (
10096 | CallString s -> "\"" ^ s ^ "\""
10097 | CallOptString None -> "null"
10098 | CallOptString (Some s) -> sprintf "\"%s\"" s
10099 | CallStringList xs ->
10101 String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "}"
10102 | CallInt i -> string_of_int i
10103 | CallInt64 i -> Int64.to_string i
10104 | CallBool b -> string_of_bool b
10109 generate_lang_bindtests (
10110 fun f args -> pr " g.%s (%s);\n" f (mkargs args)
10114 System.out.println (\"EOF\");
10116 catch (Exception exn) {
10117 System.err.println (exn);
10124 and generate_haskell_bindtests () =
10125 generate_header HaskellStyle GPLv2;
10128 module Bindtests where
10129 import qualified Guestfs
10132 g <- Guestfs.create
10136 String.concat " " (
10139 | CallString s -> "\"" ^ s ^ "\""
10140 | CallOptString None -> "Nothing"
10141 | CallOptString (Some s) -> sprintf "(Just \"%s\")" s
10142 | CallStringList xs ->
10143 "[" ^ String.concat "," (List.map (sprintf "\"%s\"") xs) ^ "]"
10144 | CallInt i when i < 0 -> "(" ^ string_of_int i ^ ")"
10145 | CallInt i -> string_of_int i
10146 | CallInt64 i when i < 0L -> "(" ^ Int64.to_string i ^ ")"
10147 | CallInt64 i -> Int64.to_string i
10148 | CallBool true -> "True"
10149 | CallBool false -> "False"
10154 generate_lang_bindtests (
10155 fun f args -> pr " Guestfs.%s g %s\n" f (mkargs args)
10158 pr " putStrLn \"EOF\"\n"
10160 (* Language-independent bindings tests - we do it this way to
10161 * ensure there is parity in testing bindings across all languages.
10163 and generate_lang_bindtests call =
10164 call "test0" [CallString "abc"; CallOptString (Some "def");
10165 CallStringList []; CallBool false;
10166 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10167 call "test0" [CallString "abc"; CallOptString None;
10168 CallStringList []; CallBool false;
10169 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10170 call "test0" [CallString ""; CallOptString (Some "def");
10171 CallStringList []; CallBool false;
10172 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10173 call "test0" [CallString ""; CallOptString (Some "");
10174 CallStringList []; CallBool false;
10175 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10176 call "test0" [CallString "abc"; CallOptString (Some "def");
10177 CallStringList ["1"]; CallBool false;
10178 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10179 call "test0" [CallString "abc"; CallOptString (Some "def");
10180 CallStringList ["1"; "2"]; CallBool false;
10181 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10182 call "test0" [CallString "abc"; CallOptString (Some "def");
10183 CallStringList ["1"]; CallBool true;
10184 CallInt 0; CallInt64 0L; CallString "123"; CallString "456"];
10185 call "test0" [CallString "abc"; CallOptString (Some "def");
10186 CallStringList ["1"]; CallBool false;
10187 CallInt (-1); CallInt64 (-1L); CallString "123"; CallString "456"];
10188 call "test0" [CallString "abc"; CallOptString (Some "def");
10189 CallStringList ["1"]; CallBool false;
10190 CallInt (-2); CallInt64 (-2L); CallString "123"; CallString "456"];
10191 call "test0" [CallString "abc"; CallOptString (Some "def");
10192 CallStringList ["1"]; CallBool false;
10193 CallInt 1; CallInt64 1L; CallString "123"; CallString "456"];
10194 call "test0" [CallString "abc"; CallOptString (Some "def");
10195 CallStringList ["1"]; CallBool false;
10196 CallInt 2; CallInt64 2L; CallString "123"; CallString "456"];
10197 call "test0" [CallString "abc"; CallOptString (Some "def");
10198 CallStringList ["1"]; CallBool false;
10199 CallInt 4095; CallInt64 4095L; CallString "123"; CallString "456"];
10200 call "test0" [CallString "abc"; CallOptString (Some "def");
10201 CallStringList ["1"]; CallBool false;
10202 CallInt 0; CallInt64 0L; CallString ""; CallString ""]
10204 (* XXX Add here tests of the return and error functions. *)
10206 (* This is used to generate the src/MAX_PROC_NR file which
10207 * contains the maximum procedure number, a surrogate for the
10208 * ABI version number. See src/Makefile.am for the details.
10210 and generate_max_proc_nr () =
10211 let proc_nrs = List.map (
10212 fun (_, _, proc_nr, _, _, _, _) -> proc_nr
10213 ) daemon_functions in
10215 let max_proc_nr = List.fold_left max 0 proc_nrs in
10217 pr "%d\n" max_proc_nr
10219 let output_to filename =
10220 let filename_new = filename ^ ".new" in
10221 chan := open_out filename_new;
10224 chan := Pervasives.stdout;
10226 (* Is the new file different from the current file? *)
10227 if Sys.file_exists filename && files_equal filename filename_new then
10228 unlink filename_new (* same, so skip it *)
10230 (* different, overwrite old one *)
10231 (try chmod filename 0o644 with Unix_error _ -> ());
10232 rename filename_new filename;
10233 chmod filename 0o444;
10234 printf "written %s\n%!" filename;
10239 let perror msg = function
10240 | Unix_error (err, _, _) ->
10241 eprintf "%s: %s\n" msg (error_message err)
10243 eprintf "%s: %s\n" msg (Printexc.to_string exn)
10245 (* Main program. *)
10248 try openfile "HACKING" [O_RDWR] 0
10250 | Unix_error (ENOENT, _, _) ->
10252 You are probably running this from the wrong directory.
10253 Run it from the top source directory using the command
10258 perror "open: HACKING" exn;
10261 (* Acquire a lock so parallel builds won't try to run the generator
10262 * twice at the same time. Subsequent builds will wait for the first
10263 * one to finish. Note the lock is released implicitly when the
10266 (try lockf lock_fd F_LOCK 1
10268 perror "lock: HACKING" exn;
10271 check_functions ();
10273 let close = output_to "src/guestfs_protocol.x" in
10277 let close = output_to "src/guestfs-structs.h" in
10278 generate_structs_h ();
10281 let close = output_to "src/guestfs-actions.h" in
10282 generate_actions_h ();
10285 let close = output_to "src/guestfs-internal-actions.h" in
10286 generate_internal_actions_h ();
10289 let close = output_to "src/guestfs-actions.c" in
10290 generate_client_actions ();
10293 let close = output_to "daemon/actions.h" in
10294 generate_daemon_actions_h ();
10297 let close = output_to "daemon/stubs.c" in
10298 generate_daemon_actions ();
10301 let close = output_to "daemon/names.c" in
10302 generate_daemon_names ();
10305 let close = output_to "capitests/tests.c" in
10309 let close = output_to "src/guestfs-bindtests.c" in
10310 generate_bindtests ();
10313 let close = output_to "fish/cmds.c" in
10314 generate_fish_cmds ();
10317 let close = output_to "fish/completion.c" in
10318 generate_fish_completion ();
10321 let close = output_to "guestfs-structs.pod" in
10322 generate_structs_pod ();
10325 let close = output_to "guestfs-actions.pod" in
10326 generate_actions_pod ();
10329 let close = output_to "guestfish-actions.pod" in
10330 generate_fish_actions_pod ();
10333 let close = output_to "ocaml/guestfs.mli" in
10334 generate_ocaml_mli ();
10337 let close = output_to "ocaml/guestfs.ml" in
10338 generate_ocaml_ml ();
10341 let close = output_to "ocaml/guestfs_c_actions.c" in
10342 generate_ocaml_c ();
10345 let close = output_to "ocaml/bindtests.ml" in
10346 generate_ocaml_bindtests ();
10349 let close = output_to "perl/Guestfs.xs" in
10350 generate_perl_xs ();
10353 let close = output_to "perl/lib/Sys/Guestfs.pm" in
10354 generate_perl_pm ();
10357 let close = output_to "perl/bindtests.pl" in
10358 generate_perl_bindtests ();
10361 let close = output_to "python/guestfs-py.c" in
10362 generate_python_c ();
10365 let close = output_to "python/guestfs.py" in
10366 generate_python_py ();
10369 let close = output_to "python/bindtests.py" in
10370 generate_python_bindtests ();
10373 let close = output_to "ruby/ext/guestfs/_guestfs.c" in
10374 generate_ruby_c ();
10377 let close = output_to "ruby/bindtests.rb" in
10378 generate_ruby_bindtests ();
10381 let close = output_to "java/com/redhat/et/libguestfs/GuestFS.java" in
10382 generate_java_java ();
10387 let cols = cols_of_struct typ in
10388 let filename = sprintf "java/com/redhat/et/libguestfs/%s.java" jtyp in
10389 let close = output_to filename in
10390 generate_java_struct jtyp cols;
10394 let close = output_to "java/Makefile.inc" in
10395 generate_java_makefile_inc ();
10398 let close = output_to "java/com_redhat_et_libguestfs_GuestFS.c" in
10399 generate_java_c ();
10402 let close = output_to "java/Bindtests.java" in
10403 generate_java_bindtests ();
10406 let close = output_to "haskell/Guestfs.hs" in
10407 generate_haskell_hs ();
10410 let close = output_to "haskell/Bindtests.hs" in
10411 generate_haskell_bindtests ();
10414 let close = output_to "src/MAX_PROC_NR" in
10415 generate_max_proc_nr ();
10418 (* Always generate this file last, and unconditionally. It's used
10419 * by the Makefile to know when we must re-run the generator.
10421 let chan = open_out "src/stamp-generator" in
10422 fprintf chan "1\n";