Add 'add_drive_ro' call. Fix up documentation. Plus a couple of minor code improvemen...
[libguestfs.git] / src / generator.ml
1 #!/usr/bin/env ocaml
2 (* libguestfs
3  * Copyright (C) 2009 Red Hat Inc.
4  *
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.
9  *
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.
14  *
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
18  *)
19
20 (* This script generates a large amount of code and documentation for
21  * all the daemon actions.
22  *
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.
26  *
27  * After editing this file, run it (./src/generator.ml) to regenerate
28  * all the output files.
29  *
30  * IMPORTANT: This script should NOT print any warnings.  If it prints
31  * warnings, you should treat them as errors.
32  * [Need to add -warn-error to ocaml command line]
33  *)
34
35 #load "unix.cma";;
36 #load "str.cma";;
37
38 open Printf
39
40 type style = ret * args
41 and ret =
42     (* "RErr" as a return value means an int used as a simple error
43      * indication, ie. 0 or -1.
44      *)
45   | RErr
46     (* "RInt" as a return value means an int which is -1 for error
47      * or any value >= 0 on success.  Only use this for smallish
48      * positive ints (0 <= i < 2^30).
49      *)
50   | RInt of string
51     (* "RInt64" is the same as RInt, but is guaranteed to be able
52      * to return a full 64 bit value, _except_ that -1 means error
53      * (so -1 cannot be a valid, non-error return value).
54      *)
55   | RInt64 of string
56     (* "RBool" is a bool return value which can be true/false or
57      * -1 for error.
58      *)
59   | RBool of string
60     (* "RConstString" is a string that refers to a constant value.
61      * Try to avoid using this.  In particular you cannot use this
62      * for values returned from the daemon, because there is no
63      * thread-safe way to return them in the C API.
64      *)
65   | RConstString of string
66     (* "RString" and "RStringList" are caller-frees. *)
67   | RString of string
68   | RStringList of string
69     (* Some limited tuples are possible: *)
70   | RIntBool of string * string
71     (* LVM PVs, VGs and LVs. *)
72   | RPVList of string
73   | RVGList of string
74   | RLVList of string
75     (* Stat buffers. *)
76   | RStat of string
77   | RStatVFS of string
78     (* Key-value pairs of untyped strings.  Turns into a hashtable or
79      * dictionary in languages which support it.  DON'T use this as a
80      * general "bucket" for results.  Prefer a stronger typed return
81      * value if one is available, or write a custom struct.  Don't use
82      * this if the list could potentially be very long, since it is
83      * inefficient.  Keys should be unique.  NULLs are not permitted.
84      *)
85   | RHashtable of string
86
87 and args = argt list    (* Function parameters, guestfs handle is implicit. *)
88
89     (* Note in future we should allow a "variable args" parameter as
90      * the final parameter, to allow commands like
91      *   chmod mode file [file(s)...]
92      * This is not implemented yet, but many commands (such as chmod)
93      * are currently defined with the argument order keeping this future
94      * possibility in mind.
95      *)
96 and argt =
97   | String of string    (* const char *name, cannot be NULL *)
98   | OptString of string (* const char *name, may be NULL *)
99   | StringList of string(* list of strings (each string cannot be NULL) *)
100   | Bool of string      (* boolean *)
101   | Int of string       (* int (smallish ints, signed, <= 31 bits) *)
102     (* These are treated as filenames (simple string parameters) in
103      * the C API and bindings.  But in the RPC protocol, we transfer
104      * the actual file content up to or down from the daemon.
105      * FileIn: local machine -> daemon (in request)
106      * FileOut: daemon -> local machine (in reply)
107      * In guestfish (only), the special name "-" means read from
108      * stdin or write to stdout.
109      *)
110   | FileIn of string
111   | FileOut of string
112
113 type flags =
114   | ProtocolLimitWarning  (* display warning about protocol size limits *)
115   | DangerWillRobinson    (* flags particularly dangerous commands *)
116   | FishAlias of string   (* provide an alias for this cmd in guestfish *)
117   | FishAction of string  (* call this function in guestfish *)
118   | NotInFish             (* do not export via guestfish *)
119   | NotInDocs             (* do not add this function to documentation *)
120
121 let protocol_limit_warning =
122   "Because of the message protocol, there is a transfer limit 
123 of somewhere between 2MB and 4MB.  To transfer large files you should use
124 FTP."
125
126 let danger_will_robinson =
127   "B<This command is dangerous.  Without careful use you
128 can easily destroy all your data>."
129
130 (* You can supply zero or as many tests as you want per API call.
131  *
132  * Note that the test environment has 3 block devices, of size 500MB,
133  * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and
134  * a fourth squashfs block device with some known files on it (/dev/sdd).
135  *
136  * Note for partitioning purposes, the 500MB device has 63 cylinders.
137  *
138  * The squashfs block device (/dev/sdd) comes from images/test.sqsh.
139  *
140  * To be able to run the tests in a reasonable amount of time,
141  * the virtual machine and block devices are reused between tests.
142  * So don't try testing kill_subprocess :-x
143  *
144  * Between each test we blockdev-setrw, umount-all, lvm-remove-all.
145  *
146  * If the appliance is running an older Linux kernel (eg. RHEL 5) then
147  * devices are named /dev/hda etc.  To cope with this, the test suite
148  * adds some hairly logic to detect this case, and then automagically
149  * replaces all strings which match "/dev/sd.*" with "/dev/hd.*".
150  * When writing test cases you shouldn't have to worry about this
151  * difference.
152  *
153  * Don't assume anything about the previous contents of the block
154  * devices.  Use 'Init*' to create some initial scenarios.
155  *
156  * You can add a prerequisite clause to any individual test.  This
157  * is a run-time check, which, if it fails, causes the test to be
158  * skipped.  Useful if testing a command which might not work on
159  * all variations of libguestfs builds.  A test that has prerequisite
160  * of 'Always' is run unconditionally.
161  *
162  * In addition, packagers can skip individual tests by setting the
163  * environment variables:     eg:
164  *   SKIP_TEST_<CMD>_<NUM>=1  SKIP_TEST_COMMAND_3=1  (skips test #3 of command)
165  *   SKIP_TEST_<CMD>=1        SKIP_TEST_ZEROFREE=1   (skips all zerofree tests)
166  *)
167 type tests = (test_init * test_prereq * test) list
168 and test =
169     (* Run the command sequence and just expect nothing to fail. *)
170   | TestRun of seq
171     (* Run the command sequence and expect the output of the final
172      * command to be the string.
173      *)
174   | TestOutput of seq * string
175     (* Run the command sequence and expect the output of the final
176      * command to be the list of strings.
177      *)
178   | TestOutputList of seq * string list
179     (* Run the command sequence and expect the output of the final
180      * command to be the integer.
181      *)
182   | TestOutputInt of seq * int
183     (* Run the command sequence and expect the output of the final
184      * command to be a true value (!= 0 or != NULL).
185      *)
186   | TestOutputTrue of seq
187     (* Run the command sequence and expect the output of the final
188      * command to be a false value (== 0 or == NULL, but not an error).
189      *)
190   | TestOutputFalse of seq
191     (* Run the command sequence and expect the output of the final
192      * command to be a list of the given length (but don't care about
193      * content).
194      *)
195   | TestOutputLength of seq * int
196     (* Run the command sequence and expect the output of the final
197      * command to be a structure.
198      *)
199   | TestOutputStruct of seq * test_field_compare list
200     (* Run the command sequence and expect the final command (only)
201      * to fail.
202      *)
203   | TestLastFail of seq
204
205 and test_field_compare =
206   | CompareWithInt of string * int
207   | CompareWithString of string * string
208   | CompareFieldsIntEq of string * string
209   | CompareFieldsStrEq of string * string
210
211 (* Test prerequisites. *)
212 and test_prereq =
213     (* Test always runs. *)
214   | Always
215     (* Test is currently disabled - eg. it fails, or it tests some
216      * unimplemented feature.
217      *)
218   | Disabled
219     (* 'string' is some C code (a function body) that should return
220      * true or false.  The test will run if the code returns true.
221      *)
222   | If of string
223     (* As for 'If' but the test runs _unless_ the code returns true. *)
224   | Unless of string
225
226 (* Some initial scenarios for testing. *)
227 and test_init =
228     (* Do nothing, block devices could contain random stuff including
229      * LVM PVs, and some filesystems might be mounted.  This is usually
230      * a bad idea.
231      *)
232   | InitNone
233     (* Block devices are empty and no filesystems are mounted. *)
234   | InitEmpty
235     (* /dev/sda contains a single partition /dev/sda1, which is formatted
236      * as ext2, empty [except for lost+found] and mounted on /.
237      * /dev/sdb and /dev/sdc may have random content.
238      * No LVM.
239      *)
240   | InitBasicFS
241     (* /dev/sda:
242      *   /dev/sda1 (is a PV):
243      *     /dev/VG/LV (size 8MB):
244      *       formatted as ext2, empty [except for lost+found], mounted on /
245      * /dev/sdb and /dev/sdc may have random content.
246      *)
247   | InitBasicFSonLVM
248
249 (* Sequence of commands for testing. *)
250 and seq = cmd list
251 and cmd = string list
252
253 (* Note about long descriptions: When referring to another
254  * action, use the format C<guestfs_other> (ie. the full name of
255  * the C function).  This will be replaced as appropriate in other
256  * language bindings.
257  *
258  * Apart from that, long descriptions are just perldoc paragraphs.
259  *)
260
261 (* These test functions are used in the language binding tests. *)
262
263 let test_all_args = [
264   String "str";
265   OptString "optstr";
266   StringList "strlist";
267   Bool "b";
268   Int "integer";
269   FileIn "filein";
270   FileOut "fileout";
271 ]
272
273 let test_all_rets = [
274   (* except for RErr, which is tested thoroughly elsewhere *)
275   "test0rint",         RInt "valout";
276   "test0rint64",       RInt64 "valout";
277   "test0rbool",        RBool "valout";
278   "test0rconststring", RConstString "valout";
279   "test0rstring",      RString "valout";
280   "test0rstringlist",  RStringList "valout";
281   "test0rintbool",     RIntBool ("valout", "valout");
282   "test0rpvlist",      RPVList "valout";
283   "test0rvglist",      RVGList "valout";
284   "test0rlvlist",      RLVList "valout";
285   "test0rstat",        RStat "valout";
286   "test0rstatvfs",     RStatVFS "valout";
287   "test0rhashtable",   RHashtable "valout";
288 ]
289
290 let test_functions = [
291   ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs],
292    [],
293    "internal test function - do not use",
294    "\
295 This is an internal test function which is used to test whether
296 the automatically generated bindings can handle every possible
297 parameter type correctly.
298
299 It echos the contents of each parameter to stdout.
300
301 You probably don't want to call this function.");
302 ] @ List.flatten (
303   List.map (
304     fun (name, ret) ->
305       [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs],
306         [],
307         "internal test function - do not use",
308         "\
309 This is an internal test function which is used to test whether
310 the automatically generated bindings can handle every possible
311 return type correctly.
312
313 It converts string C<val> to the return type.
314
315 You probably don't want to call this function.");
316        (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs],
317         [],
318         "internal test function - do not use",
319         "\
320 This is an internal test function which is used to test whether
321 the automatically generated bindings can handle every possible
322 return type correctly.
323
324 This function always returns an error.
325
326 You probably don't want to call this function.")]
327   ) test_all_rets
328 )
329
330 (* non_daemon_functions are any functions which don't get processed
331  * in the daemon, eg. functions for setting and getting local
332  * configuration values.
333  *)
334
335 let non_daemon_functions = test_functions @ [
336   ("launch", (RErr, []), -1, [FishAlias "run"; FishAction "launch"],
337    [],
338    "launch the qemu subprocess",
339    "\
340 Internally libguestfs is implemented by running a virtual machine
341 using L<qemu(1)>.
342
343 You should call this after configuring the handle
344 (eg. adding drives) but before performing any actions.");
345
346   ("wait_ready", (RErr, []), -1, [NotInFish],
347    [],
348    "wait until the qemu subprocess launches",
349    "\
350 Internally libguestfs is implemented by running a virtual machine
351 using L<qemu(1)>.
352
353 You should call this after C<guestfs_launch> to wait for the launch
354 to complete.");
355
356   ("kill_subprocess", (RErr, []), -1, [],
357    [],
358    "kill the qemu subprocess",
359    "\
360 This kills the qemu subprocess.  You should never need to call this.");
361
362   ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"],
363    [],
364    "add an image to examine or modify",
365    "\
366 This function adds a virtual machine disk image C<filename> to the
367 guest.  The first time you call this function, the disk appears as IDE
368 disk 0 (C</dev/sda>) in the guest, the second time as C</dev/sdb>, and
369 so on.
370
371 You don't necessarily need to be root when using libguestfs.  However
372 you obviously do need sufficient permissions to access the filename
373 for whatever operations you want to perform (ie. read access if you
374 just want to read the image or write access if you want to modify the
375 image).
376
377 This is equivalent to the qemu parameter C<-drive file=filename>.
378
379 Note that this call checks for the existence of C<filename>.  This
380 stops you from specifying other types of drive which are supported
381 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
382 the general C<guestfs_config> call instead.");
383
384   ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"],
385    [],
386    "add a CD-ROM disk image to examine",
387    "\
388 This function adds a virtual CD-ROM disk image to the guest.
389
390 This is equivalent to the qemu parameter C<-cdrom filename>.
391
392 Note that this call checks for the existence of C<filename>.  This
393 stops you from specifying other types of drive which are supported
394 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
395 the general C<guestfs_config> call instead.");
396
397   ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"],
398    [],
399    "add a drive in snapshot mode (read-only)",
400    "\
401 This adds a drive in snapshot mode, making it effectively
402 read-only.
403
404 Note that writes to the device are allowed, and will be seen for
405 the duration of the guestfs handle, but they are written
406 to a temporary file which is discarded as soon as the guestfs
407 handle is closed.  We don't currently have any method to enable
408 changes to be committed, although qemu can support this.
409
410 This is equivalent to the qemu parameter
411 C<-drive file=filename,snapshot=on>.
412
413 Note that this call checks for the existence of C<filename>.  This
414 stops you from specifying other types of drive which are supported
415 by qemu such as C<nbd:> and C<http:> URLs.  To specify those, use
416 the general C<guestfs_config> call instead.");
417
418   ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [],
419    [],
420    "add qemu parameters",
421    "\
422 This can be used to add arbitrary qemu command line parameters
423 of the form C<-param value>.  Actually it's not quite arbitrary - we
424 prevent you from setting some parameters which would interfere with
425 parameters that we use.
426
427 The first character of C<param> string must be a C<-> (dash).
428
429 C<value> can be NULL.");
430
431   ("set_qemu", (RErr, [String "qemu"]), -1, [FishAlias "qemu"],
432    [],
433    "set the qemu binary",
434    "\
435 Set the qemu binary that we will use.
436
437 The default is chosen when the library was compiled by the
438 configure script.
439
440 You can also override this by setting the C<LIBGUESTFS_QEMU>
441 environment variable.
442
443 Setting C<qemu> to C<NULL> restores the default qemu binary.");
444
445   ("get_qemu", (RConstString "qemu", []), -1, [],
446    [],
447    "get the qemu binary",
448    "\
449 Return the current qemu binary.
450
451 This is always non-NULL.  If it wasn't set already, then this will
452 return the default qemu binary name.");
453
454   ("set_path", (RErr, [String "path"]), -1, [FishAlias "path"],
455    [],
456    "set the search path",
457    "\
458 Set the path that libguestfs searches for kernel and initrd.img.
459
460 The default is C<$libdir/guestfs> unless overridden by setting
461 C<LIBGUESTFS_PATH> environment variable.
462
463 Setting C<path> to C<NULL> restores the default path.");
464
465   ("get_path", (RConstString "path", []), -1, [],
466    [],
467    "get the search path",
468    "\
469 Return the current search path.
470
471 This is always non-NULL.  If it wasn't set already, then this will
472 return the default path.");
473
474   ("set_append", (RErr, [String "append"]), -1, [FishAlias "append"],
475    [],
476    "add options to kernel command line",
477    "\
478 This function is used to add additional options to the
479 guest kernel command line.
480
481 The default is C<NULL> unless overridden by setting
482 C<LIBGUESTFS_APPEND> environment variable.
483
484 Setting C<append> to C<NULL> means I<no> additional options
485 are passed (libguestfs always adds a few of its own).");
486
487   ("get_append", (RConstString "append", []), -1, [],
488    [],
489    "get the additional kernel options",
490    "\
491 Return the additional kernel options which are added to the
492 guest kernel command line.
493
494 If C<NULL> then no options are added.");
495
496   ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"],
497    [],
498    "set autosync mode",
499    "\
500 If C<autosync> is true, this enables autosync.  Libguestfs will make a
501 best effort attempt to run C<guestfs_umount_all> followed by
502 C<guestfs_sync> when the handle is closed
503 (also if the program exits without closing handles).
504
505 This is disabled by default (except in guestfish where it is
506 enabled by default).");
507
508   ("get_autosync", (RBool "autosync", []), -1, [],
509    [],
510    "get autosync mode",
511    "\
512 Get the autosync flag.");
513
514   ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"],
515    [],
516    "set verbose mode",
517    "\
518 If C<verbose> is true, this turns on verbose messages (to C<stderr>).
519
520 Verbose messages are disabled unless the environment variable
521 C<LIBGUESTFS_DEBUG> is defined and set to C<1>.");
522
523   ("get_verbose", (RBool "verbose", []), -1, [],
524    [],
525    "get verbose mode",
526    "\
527 This returns the verbose messages flag.");
528
529   ("is_ready", (RBool "ready", []), -1, [],
530    [],
531    "is ready to accept commands",
532    "\
533 This returns true iff this handle is ready to accept commands
534 (in the C<READY> state).
535
536 For more information on states, see L<guestfs(3)>.");
537
538   ("is_config", (RBool "config", []), -1, [],
539    [],
540    "is in configuration state",
541    "\
542 This returns true iff this handle is being configured
543 (in the C<CONFIG> state).
544
545 For more information on states, see L<guestfs(3)>.");
546
547   ("is_launching", (RBool "launching", []), -1, [],
548    [],
549    "is launching subprocess",
550    "\
551 This returns true iff this handle is launching the subprocess
552 (in the C<LAUNCHING> state).
553
554 For more information on states, see L<guestfs(3)>.");
555
556   ("is_busy", (RBool "busy", []), -1, [],
557    [],
558    "is busy processing a command",
559    "\
560 This returns true iff this handle is busy processing a command
561 (in the C<BUSY> state).
562
563 For more information on states, see L<guestfs(3)>.");
564
565   ("get_state", (RInt "state", []), -1, [],
566    [],
567    "get the current state",
568    "\
569 This returns the current state as an opaque integer.  This is
570 only useful for printing debug and internal error messages.
571
572 For more information on states, see L<guestfs(3)>.");
573
574   ("set_busy", (RErr, []), -1, [NotInFish],
575    [],
576    "set state to busy",
577    "\
578 This sets the state to C<BUSY>.  This is only used when implementing
579 actions using the low-level API.
580
581 For more information on states, see L<guestfs(3)>.");
582
583   ("set_ready", (RErr, []), -1, [NotInFish],
584    [],
585    "set state to ready",
586    "\
587 This sets the state to C<READY>.  This is only used when implementing
588 actions using the low-level API.
589
590 For more information on states, see L<guestfs(3)>.");
591
592   ("end_busy", (RErr, []), -1, [NotInFish],
593    [],
594    "leave the busy state",
595    "\
596 This sets the state to C<READY>, or if in C<CONFIG> then it leaves the
597 state as is.  This is only used when implementing
598 actions using the low-level API.
599
600 For more information on states, see L<guestfs(3)>.");
601
602 ]
603
604 (* daemon_functions are any functions which cause some action
605  * to take place in the daemon.
606  *)
607
608 let daemon_functions = [
609   ("mount", (RErr, [String "device"; String "mountpoint"]), 1, [],
610    [InitEmpty, Always, TestOutput (
611       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
612        ["mkfs"; "ext2"; "/dev/sda1"];
613        ["mount"; "/dev/sda1"; "/"];
614        ["write_file"; "/new"; "new file contents"; "0"];
615        ["cat"; "/new"]], "new file contents")],
616    "mount a guest disk at a position in the filesystem",
617    "\
618 Mount a guest disk at a position in the filesystem.  Block devices
619 are named C</dev/sda>, C</dev/sdb> and so on, as they were added to
620 the guest.  If those block devices contain partitions, they will have
621 the usual names (eg. C</dev/sda1>).  Also LVM C</dev/VG/LV>-style
622 names can be used.
623
624 The rules are the same as for L<mount(2)>:  A filesystem must
625 first be mounted on C</> before others can be mounted.  Other
626 filesystems can only be mounted on directories which already
627 exist.
628
629 The mounted filesystem is writable, if we have sufficient permissions
630 on the underlying device.
631
632 The filesystem options C<sync> and C<noatime> are set with this
633 call, in order to improve reliability.");
634
635   ("sync", (RErr, []), 2, [],
636    [ InitEmpty, Always, TestRun [["sync"]]],
637    "sync disks, writes are flushed through to the disk image",
638    "\
639 This syncs the disk, so that any writes are flushed through to the
640 underlying disk image.
641
642 You should always call this if you have modified a disk image, before
643 closing the handle.");
644
645   ("touch", (RErr, [String "path"]), 3, [],
646    [InitBasicFS, Always, TestOutputTrue (
647       [["touch"; "/new"];
648        ["exists"; "/new"]])],
649    "update file timestamps or create a new file",
650    "\
651 Touch acts like the L<touch(1)> command.  It can be used to
652 update the timestamps on a file, or, if the file does not exist,
653 to create a new zero-length file.");
654
655   ("cat", (RString "content", [String "path"]), 4, [ProtocolLimitWarning],
656    [InitBasicFS, Always, TestOutput (
657       [["write_file"; "/new"; "new file contents"; "0"];
658        ["cat"; "/new"]], "new file contents")],
659    "list the contents of a file",
660    "\
661 Return the contents of the file named C<path>.
662
663 Note that this function cannot correctly handle binary files
664 (specifically, files containing C<\\0> character which is treated
665 as end of string).  For those you need to use the C<guestfs_download>
666 function which has a more complex interface.");
667
668   ("ll", (RString "listing", [String "directory"]), 5, [],
669    [], (* XXX Tricky to test because it depends on the exact format
670         * of the 'ls -l' command, which changes between F10 and F11.
671         *)
672    "list the files in a directory (long format)",
673    "\
674 List the files in C<directory> (relative to the root directory,
675 there is no cwd) in the format of 'ls -la'.
676
677 This command is mostly useful for interactive sessions.  It
678 is I<not> intended that you try to parse the output string.");
679
680   ("ls", (RStringList "listing", [String "directory"]), 6, [],
681    [InitBasicFS, Always, TestOutputList (
682       [["touch"; "/new"];
683        ["touch"; "/newer"];
684        ["touch"; "/newest"];
685        ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])],
686    "list the files in a directory",
687    "\
688 List the files in C<directory> (relative to the root directory,
689 there is no cwd).  The '.' and '..' entries are not returned, but
690 hidden files are shown.
691
692 This command is mostly useful for interactive sessions.  Programs
693 should probably use C<guestfs_readdir> instead.");
694
695   ("list_devices", (RStringList "devices", []), 7, [],
696    [InitEmpty, Always, TestOutputList (
697       [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])],
698    "list the block devices",
699    "\
700 List all the block devices.
701
702 The full block device names are returned, eg. C</dev/sda>");
703
704   ("list_partitions", (RStringList "partitions", []), 8, [],
705    [InitBasicFS, Always, TestOutputList (
706       [["list_partitions"]], ["/dev/sda1"]);
707     InitEmpty, Always, TestOutputList (
708       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
709        ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
710    "list the partitions",
711    "\
712 List all the partitions detected on all block devices.
713
714 The full partition device names are returned, eg. C</dev/sda1>
715
716 This does not return logical volumes.  For that you will need to
717 call C<guestfs_lvs>.");
718
719   ("pvs", (RStringList "physvols", []), 9, [],
720    [InitBasicFSonLVM, Always, TestOutputList (
721       [["pvs"]], ["/dev/sda1"]);
722     InitEmpty, Always, TestOutputList (
723       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
724        ["pvcreate"; "/dev/sda1"];
725        ["pvcreate"; "/dev/sda2"];
726        ["pvcreate"; "/dev/sda3"];
727        ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
728    "list the LVM physical volumes (PVs)",
729    "\
730 List all the physical volumes detected.  This is the equivalent
731 of the L<pvs(8)> command.
732
733 This returns a list of just the device names that contain
734 PVs (eg. C</dev/sda2>).
735
736 See also C<guestfs_pvs_full>.");
737
738   ("vgs", (RStringList "volgroups", []), 10, [],
739    [InitBasicFSonLVM, Always, TestOutputList (
740       [["vgs"]], ["VG"]);
741     InitEmpty, Always, TestOutputList (
742       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
743        ["pvcreate"; "/dev/sda1"];
744        ["pvcreate"; "/dev/sda2"];
745        ["pvcreate"; "/dev/sda3"];
746        ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
747        ["vgcreate"; "VG2"; "/dev/sda3"];
748        ["vgs"]], ["VG1"; "VG2"])],
749    "list the LVM volume groups (VGs)",
750    "\
751 List all the volumes groups detected.  This is the equivalent
752 of the L<vgs(8)> command.
753
754 This returns a list of just the volume group names that were
755 detected (eg. C<VolGroup00>).
756
757 See also C<guestfs_vgs_full>.");
758
759   ("lvs", (RStringList "logvols", []), 11, [],
760    [InitBasicFSonLVM, Always, TestOutputList (
761       [["lvs"]], ["/dev/VG/LV"]);
762     InitEmpty, Always, TestOutputList (
763       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
764        ["pvcreate"; "/dev/sda1"];
765        ["pvcreate"; "/dev/sda2"];
766        ["pvcreate"; "/dev/sda3"];
767        ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
768        ["vgcreate"; "VG2"; "/dev/sda3"];
769        ["lvcreate"; "LV1"; "VG1"; "50"];
770        ["lvcreate"; "LV2"; "VG1"; "50"];
771        ["lvcreate"; "LV3"; "VG2"; "50"];
772        ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])],
773    "list the LVM logical volumes (LVs)",
774    "\
775 List all the logical volumes detected.  This is the equivalent
776 of the L<lvs(8)> command.
777
778 This returns a list of the logical volume device names
779 (eg. C</dev/VolGroup00/LogVol00>).
780
781 See also C<guestfs_lvs_full>.");
782
783   ("pvs_full", (RPVList "physvols", []), 12, [],
784    [], (* XXX how to test? *)
785    "list the LVM physical volumes (PVs)",
786    "\
787 List all the physical volumes detected.  This is the equivalent
788 of the L<pvs(8)> command.  The \"full\" version includes all fields.");
789
790   ("vgs_full", (RVGList "volgroups", []), 13, [],
791    [], (* XXX how to test? *)
792    "list the LVM volume groups (VGs)",
793    "\
794 List all the volumes groups detected.  This is the equivalent
795 of the L<vgs(8)> command.  The \"full\" version includes all fields.");
796
797   ("lvs_full", (RLVList "logvols", []), 14, [],
798    [], (* XXX how to test? *)
799    "list the LVM logical volumes (LVs)",
800    "\
801 List all the logical volumes detected.  This is the equivalent
802 of the L<lvs(8)> command.  The \"full\" version includes all fields.");
803
804   ("read_lines", (RStringList "lines", [String "path"]), 15, [],
805    [InitBasicFS, Always, TestOutputList (
806       [["write_file"; "/new"; "line1\r\nline2\nline3"; "0"];
807        ["read_lines"; "/new"]], ["line1"; "line2"; "line3"]);
808     InitBasicFS, Always, TestOutputList (
809       [["write_file"; "/new"; ""; "0"];
810        ["read_lines"; "/new"]], [])],
811    "read file as lines",
812    "\
813 Return the contents of the file named C<path>.
814
815 The file contents are returned as a list of lines.  Trailing
816 C<LF> and C<CRLF> character sequences are I<not> returned.
817
818 Note that this function cannot correctly handle binary files
819 (specifically, files containing C<\\0> character which is treated
820 as end of line).  For those you need to use the C<guestfs_read_file>
821 function which has a more complex interface.");
822
823   ("aug_init", (RErr, [String "root"; Int "flags"]), 16, [],
824    [], (* XXX Augeas code needs tests. *)
825    "create a new Augeas handle",
826    "\
827 Create a new Augeas handle for editing configuration files.
828 If there was any previous Augeas handle associated with this
829 guestfs session, then it is closed.
830
831 You must call this before using any other C<guestfs_aug_*>
832 commands.
833
834 C<root> is the filesystem root.  C<root> must not be NULL,
835 use C</> instead.
836
837 The flags are the same as the flags defined in
838 E<lt>augeas.hE<gt>, the logical I<or> of the following
839 integers:
840
841 =over 4
842
843 =item C<AUG_SAVE_BACKUP> = 1
844
845 Keep the original file with a C<.augsave> extension.
846
847 =item C<AUG_SAVE_NEWFILE> = 2
848
849 Save changes into a file with extension C<.augnew>, and
850 do not overwrite original.  Overrides C<AUG_SAVE_BACKUP>.
851
852 =item C<AUG_TYPE_CHECK> = 4
853
854 Typecheck lenses (can be expensive).
855
856 =item C<AUG_NO_STDINC> = 8
857
858 Do not use standard load path for modules.
859
860 =item C<AUG_SAVE_NOOP> = 16
861
862 Make save a no-op, just record what would have been changed.
863
864 =item C<AUG_NO_LOAD> = 32
865
866 Do not load the tree in C<guestfs_aug_init>.
867
868 =back
869
870 To close the handle, you can call C<guestfs_aug_close>.
871
872 To find out more about Augeas, see L<http://augeas.net/>.");
873
874   ("aug_close", (RErr, []), 26, [],
875    [], (* XXX Augeas code needs tests. *)
876    "close the current Augeas handle",
877    "\
878 Close the current Augeas handle and free up any resources
879 used by it.  After calling this, you have to call
880 C<guestfs_aug_init> again before you can use any other
881 Augeas functions.");
882
883   ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [],
884    [], (* XXX Augeas code needs tests. *)
885    "define an Augeas variable",
886    "\
887 Defines an Augeas variable C<name> whose value is the result
888 of evaluating C<expr>.  If C<expr> is NULL, then C<name> is
889 undefined.
890
891 On success this returns the number of nodes in C<expr>, or
892 C<0> if C<expr> evaluates to something which is not a nodeset.");
893
894   ("aug_defnode", (RIntBool ("nrnodes", "created"), [String "name"; String "expr"; String "val"]), 18, [],
895    [], (* XXX Augeas code needs tests. *)
896    "define an Augeas node",
897    "\
898 Defines a variable C<name> whose value is the result of
899 evaluating C<expr>.
900
901 If C<expr> evaluates to an empty nodeset, a node is created,
902 equivalent to calling C<guestfs_aug_set> C<expr>, C<value>.
903 C<name> will be the nodeset containing that single node.
904
905 On success this returns a pair containing the
906 number of nodes in the nodeset, and a boolean flag
907 if a node was created.");
908
909   ("aug_get", (RString "val", [String "path"]), 19, [],
910    [], (* XXX Augeas code needs tests. *)
911    "look up the value of an Augeas path",
912    "\
913 Look up the value associated with C<path>.  If C<path>
914 matches exactly one node, the C<value> is returned.");
915
916   ("aug_set", (RErr, [String "path"; String "val"]), 20, [],
917    [], (* XXX Augeas code needs tests. *)
918    "set Augeas path to value",
919    "\
920 Set the value associated with C<path> to C<value>.");
921
922   ("aug_insert", (RErr, [String "path"; String "label"; Bool "before"]), 21, [],
923    [], (* XXX Augeas code needs tests. *)
924    "insert a sibling Augeas node",
925    "\
926 Create a new sibling C<label> for C<path>, inserting it into
927 the tree before or after C<path> (depending on the boolean
928 flag C<before>).
929
930 C<path> must match exactly one existing node in the tree, and
931 C<label> must be a label, ie. not contain C</>, C<*> or end
932 with a bracketed index C<[N]>.");
933
934   ("aug_rm", (RInt "nrnodes", [String "path"]), 22, [],
935    [], (* XXX Augeas code needs tests. *)
936    "remove an Augeas path",
937    "\
938 Remove C<path> and all of its children.
939
940 On success this returns the number of entries which were removed.");
941
942   ("aug_mv", (RErr, [String "src"; String "dest"]), 23, [],
943    [], (* XXX Augeas code needs tests. *)
944    "move Augeas node",
945    "\
946 Move the node C<src> to C<dest>.  C<src> must match exactly
947 one node.  C<dest> is overwritten if it exists.");
948
949   ("aug_match", (RStringList "matches", [String "path"]), 24, [],
950    [], (* XXX Augeas code needs tests. *)
951    "return Augeas nodes which match path",
952    "\
953 Returns a list of paths which match the path expression C<path>.
954 The returned paths are sufficiently qualified so that they match
955 exactly one node in the current tree.");
956
957   ("aug_save", (RErr, []), 25, [],
958    [], (* XXX Augeas code needs tests. *)
959    "write all pending Augeas changes to disk",
960    "\
961 This writes all pending changes to disk.
962
963 The flags which were passed to C<guestfs_aug_init> affect exactly
964 how files are saved.");
965
966   ("aug_load", (RErr, []), 27, [],
967    [], (* XXX Augeas code needs tests. *)
968    "load files into the tree",
969    "\
970 Load files into the tree.
971
972 See C<aug_load> in the Augeas documentation for the full gory
973 details.");
974
975   ("aug_ls", (RStringList "matches", [String "path"]), 28, [],
976    [], (* XXX Augeas code needs tests. *)
977    "list Augeas nodes under a path",
978    "\
979 This is just a shortcut for listing C<guestfs_aug_match>
980 C<path/*> and sorting the resulting nodes into alphabetical order.");
981
982   ("rm", (RErr, [String "path"]), 29, [],
983    [InitBasicFS, Always, TestRun
984       [["touch"; "/new"];
985        ["rm"; "/new"]];
986     InitBasicFS, Always, TestLastFail
987       [["rm"; "/new"]];
988     InitBasicFS, Always, TestLastFail
989       [["mkdir"; "/new"];
990        ["rm"; "/new"]]],
991    "remove a file",
992    "\
993 Remove the single file C<path>.");
994
995   ("rmdir", (RErr, [String "path"]), 30, [],
996    [InitBasicFS, Always, TestRun
997       [["mkdir"; "/new"];
998        ["rmdir"; "/new"]];
999     InitBasicFS, Always, TestLastFail
1000       [["rmdir"; "/new"]];
1001     InitBasicFS, Always, TestLastFail
1002       [["touch"; "/new"];
1003        ["rmdir"; "/new"]]],
1004    "remove a directory",
1005    "\
1006 Remove the single directory C<path>.");
1007
1008   ("rm_rf", (RErr, [String "path"]), 31, [],
1009    [InitBasicFS, Always, TestOutputFalse
1010       [["mkdir"; "/new"];
1011        ["mkdir"; "/new/foo"];
1012        ["touch"; "/new/foo/bar"];
1013        ["rm_rf"; "/new"];
1014        ["exists"; "/new"]]],
1015    "remove a file or directory recursively",
1016    "\
1017 Remove the file or directory C<path>, recursively removing the
1018 contents if its a directory.  This is like the C<rm -rf> shell
1019 command.");
1020
1021   ("mkdir", (RErr, [String "path"]), 32, [],
1022    [InitBasicFS, Always, TestOutputTrue
1023       [["mkdir"; "/new"];
1024        ["is_dir"; "/new"]];
1025     InitBasicFS, Always, TestLastFail
1026       [["mkdir"; "/new/foo/bar"]]],
1027    "create a directory",
1028    "\
1029 Create a directory named C<path>.");
1030
1031   ("mkdir_p", (RErr, [String "path"]), 33, [],
1032    [InitBasicFS, Always, TestOutputTrue
1033       [["mkdir_p"; "/new/foo/bar"];
1034        ["is_dir"; "/new/foo/bar"]];
1035     InitBasicFS, Always, TestOutputTrue
1036       [["mkdir_p"; "/new/foo/bar"];
1037        ["is_dir"; "/new/foo"]];
1038     InitBasicFS, Always, TestOutputTrue
1039       [["mkdir_p"; "/new/foo/bar"];
1040        ["is_dir"; "/new"]];
1041     (* Regression tests for RHBZ#503133: *)
1042     InitBasicFS, Always, TestRun
1043       [["mkdir"; "/new"];
1044        ["mkdir_p"; "/new"]];
1045     InitBasicFS, Always, TestLastFail
1046       [["touch"; "/new"];
1047        ["mkdir_p"; "/new"]]],
1048    "create a directory and parents",
1049    "\
1050 Create a directory named C<path>, creating any parent directories
1051 as necessary.  This is like the C<mkdir -p> shell command.");
1052
1053   ("chmod", (RErr, [Int "mode"; String "path"]), 34, [],
1054    [], (* XXX Need stat command to test *)
1055    "change file mode",
1056    "\
1057 Change the mode (permissions) of C<path> to C<mode>.  Only
1058 numeric modes are supported.");
1059
1060   ("chown", (RErr, [Int "owner"; Int "group"; String "path"]), 35, [],
1061    [], (* XXX Need stat command to test *)
1062    "change file owner and group",
1063    "\
1064 Change the file owner to C<owner> and group to C<group>.
1065
1066 Only numeric uid and gid are supported.  If you want to use
1067 names, you will need to locate and parse the password file
1068 yourself (Augeas support makes this relatively easy).");
1069
1070   ("exists", (RBool "existsflag", [String "path"]), 36, [],
1071    [InitBasicFS, Always, TestOutputTrue (
1072       [["touch"; "/new"];
1073        ["exists"; "/new"]]);
1074     InitBasicFS, Always, TestOutputTrue (
1075       [["mkdir"; "/new"];
1076        ["exists"; "/new"]])],
1077    "test if file or directory exists",
1078    "\
1079 This returns C<true> if and only if there is a file, directory
1080 (or anything) with the given C<path> name.
1081
1082 See also C<guestfs_is_file>, C<guestfs_is_dir>, C<guestfs_stat>.");
1083
1084   ("is_file", (RBool "fileflag", [String "path"]), 37, [],
1085    [InitBasicFS, Always, TestOutputTrue (
1086       [["touch"; "/new"];
1087        ["is_file"; "/new"]]);
1088     InitBasicFS, Always, TestOutputFalse (
1089       [["mkdir"; "/new"];
1090        ["is_file"; "/new"]])],
1091    "test if file exists",
1092    "\
1093 This returns C<true> if and only if there is a file
1094 with the given C<path> name.  Note that it returns false for
1095 other objects like directories.
1096
1097 See also C<guestfs_stat>.");
1098
1099   ("is_dir", (RBool "dirflag", [String "path"]), 38, [],
1100    [InitBasicFS, Always, TestOutputFalse (
1101       [["touch"; "/new"];
1102        ["is_dir"; "/new"]]);
1103     InitBasicFS, Always, TestOutputTrue (
1104       [["mkdir"; "/new"];
1105        ["is_dir"; "/new"]])],
1106    "test if file exists",
1107    "\
1108 This returns C<true> if and only if there is a directory
1109 with the given C<path> name.  Note that it returns false for
1110 other objects like files.
1111
1112 See also C<guestfs_stat>.");
1113
1114   ("pvcreate", (RErr, [String "device"]), 39, [],
1115    [InitEmpty, Always, TestOutputList (
1116       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
1117        ["pvcreate"; "/dev/sda1"];
1118        ["pvcreate"; "/dev/sda2"];
1119        ["pvcreate"; "/dev/sda3"];
1120        ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])],
1121    "create an LVM physical volume",
1122    "\
1123 This creates an LVM physical volume on the named C<device>,
1124 where C<device> should usually be a partition name such
1125 as C</dev/sda1>.");
1126
1127   ("vgcreate", (RErr, [String "volgroup"; StringList "physvols"]), 40, [],
1128    [InitEmpty, Always, TestOutputList (
1129       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
1130        ["pvcreate"; "/dev/sda1"];
1131        ["pvcreate"; "/dev/sda2"];
1132        ["pvcreate"; "/dev/sda3"];
1133        ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1134        ["vgcreate"; "VG2"; "/dev/sda3"];
1135        ["vgs"]], ["VG1"; "VG2"])],
1136    "create an LVM volume group",
1137    "\
1138 This creates an LVM volume group called C<volgroup>
1139 from the non-empty list of physical volumes C<physvols>.");
1140
1141   ("lvcreate", (RErr, [String "logvol"; String "volgroup"; Int "mbytes"]), 41, [],
1142    [InitEmpty, Always, TestOutputList (
1143       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
1144        ["pvcreate"; "/dev/sda1"];
1145        ["pvcreate"; "/dev/sda2"];
1146        ["pvcreate"; "/dev/sda3"];
1147        ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"];
1148        ["vgcreate"; "VG2"; "/dev/sda3"];
1149        ["lvcreate"; "LV1"; "VG1"; "50"];
1150        ["lvcreate"; "LV2"; "VG1"; "50"];
1151        ["lvcreate"; "LV3"; "VG2"; "50"];
1152        ["lvcreate"; "LV4"; "VG2"; "50"];
1153        ["lvcreate"; "LV5"; "VG2"; "50"];
1154        ["lvs"]],
1155       ["/dev/VG1/LV1"; "/dev/VG1/LV2";
1156        "/dev/VG2/LV3"; "/dev/VG2/LV4"; "/dev/VG2/LV5"])],
1157    "create an LVM volume group",
1158    "\
1159 This creates an LVM volume group called C<logvol>
1160 on the volume group C<volgroup>, with C<size> megabytes.");
1161
1162   ("mkfs", (RErr, [String "fstype"; String "device"]), 42, [],
1163    [InitEmpty, Always, TestOutput (
1164       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1165        ["mkfs"; "ext2"; "/dev/sda1"];
1166        ["mount"; "/dev/sda1"; "/"];
1167        ["write_file"; "/new"; "new file contents"; "0"];
1168        ["cat"; "/new"]], "new file contents")],
1169    "make a filesystem",
1170    "\
1171 This creates a filesystem on C<device> (usually a partition
1172 or LVM logical volume).  The filesystem type is C<fstype>, for
1173 example C<ext3>.");
1174
1175   ("sfdisk", (RErr, [String "device";
1176                      Int "cyls"; Int "heads"; Int "sectors";
1177                      StringList "lines"]), 43, [DangerWillRobinson],
1178    [],
1179    "create partitions on a block device",
1180    "\
1181 This is a direct interface to the L<sfdisk(8)> program for creating
1182 partitions on block devices.
1183
1184 C<device> should be a block device, for example C</dev/sda>.
1185
1186 C<cyls>, C<heads> and C<sectors> are the number of cylinders, heads
1187 and sectors on the device, which are passed directly to sfdisk as
1188 the I<-C>, I<-H> and I<-S> parameters.  If you pass C<0> for any
1189 of these, then the corresponding parameter is omitted.  Usually for
1190 'large' disks, you can just pass C<0> for these, but for small
1191 (floppy-sized) disks, sfdisk (or rather, the kernel) cannot work
1192 out the right geometry and you will need to tell it.
1193
1194 C<lines> is a list of lines that we feed to C<sfdisk>.  For more
1195 information refer to the L<sfdisk(8)> manpage.
1196
1197 To create a single partition occupying the whole disk, you would
1198 pass C<lines> as a single element list, when the single element being
1199 the string C<,> (comma).
1200
1201 See also: C<guestfs_sfdisk_l>, C<guestfs_sfdisk_N>");
1202
1203   ("write_file", (RErr, [String "path"; String "content"; Int "size"]), 44, [ProtocolLimitWarning],
1204    [InitBasicFS, Always, TestOutput (
1205       [["write_file"; "/new"; "new file contents"; "0"];
1206        ["cat"; "/new"]], "new file contents");
1207     InitBasicFS, Always, TestOutput (
1208       [["write_file"; "/new"; "\nnew file contents\n"; "0"];
1209        ["cat"; "/new"]], "\nnew file contents\n");
1210     InitBasicFS, Always, TestOutput (
1211       [["write_file"; "/new"; "\n\n"; "0"];
1212        ["cat"; "/new"]], "\n\n");
1213     InitBasicFS, Always, TestOutput (
1214       [["write_file"; "/new"; ""; "0"];
1215        ["cat"; "/new"]], "");
1216     InitBasicFS, Always, TestOutput (
1217       [["write_file"; "/new"; "\n\n\n"; "0"];
1218        ["cat"; "/new"]], "\n\n\n");
1219     InitBasicFS, Always, TestOutput (
1220       [["write_file"; "/new"; "\n"; "0"];
1221        ["cat"; "/new"]], "\n")],
1222    "create a file",
1223    "\
1224 This call creates a file called C<path>.  The contents of the
1225 file is the string C<content> (which can contain any 8 bit data),
1226 with length C<size>.
1227
1228 As a special case, if C<size> is C<0>
1229 then the length is calculated using C<strlen> (so in this case
1230 the content cannot contain embedded ASCII NULs).
1231
1232 I<NB.> Owing to a bug, writing content containing ASCII NUL
1233 characters does I<not> work, even if the length is specified.
1234 We hope to resolve this bug in a future version.  In the meantime
1235 use C<guestfs_upload>.");
1236
1237   ("umount", (RErr, [String "pathordevice"]), 45, [FishAlias "unmount"],
1238    [InitEmpty, Always, TestOutputList (
1239       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1240        ["mkfs"; "ext2"; "/dev/sda1"];
1241        ["mount"; "/dev/sda1"; "/"];
1242        ["mounts"]], ["/dev/sda1"]);
1243     InitEmpty, Always, TestOutputList (
1244       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1245        ["mkfs"; "ext2"; "/dev/sda1"];
1246        ["mount"; "/dev/sda1"; "/"];
1247        ["umount"; "/"];
1248        ["mounts"]], [])],
1249    "unmount a filesystem",
1250    "\
1251 This unmounts the given filesystem.  The filesystem may be
1252 specified either by its mountpoint (path) or the device which
1253 contains the filesystem.");
1254
1255   ("mounts", (RStringList "devices", []), 46, [],
1256    [InitBasicFS, Always, TestOutputList (
1257       [["mounts"]], ["/dev/sda1"])],
1258    "show mounted filesystems",
1259    "\
1260 This returns the list of currently mounted filesystems.  It returns
1261 the list of devices (eg. C</dev/sda1>, C</dev/VG/LV>).
1262
1263 Some internal mounts are not shown.");
1264
1265   ("umount_all", (RErr, []), 47, [FishAlias "unmount-all"],
1266    [InitBasicFS, Always, TestOutputList (
1267       [["umount_all"];
1268        ["mounts"]], []);
1269     (* check that umount_all can unmount nested mounts correctly: *)
1270     InitEmpty, Always, TestOutputList (
1271       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"];
1272        ["mkfs"; "ext2"; "/dev/sda1"];
1273        ["mkfs"; "ext2"; "/dev/sda2"];
1274        ["mkfs"; "ext2"; "/dev/sda3"];
1275        ["mount"; "/dev/sda1"; "/"];
1276        ["mkdir"; "/mp1"];
1277        ["mount"; "/dev/sda2"; "/mp1"];
1278        ["mkdir"; "/mp1/mp2"];
1279        ["mount"; "/dev/sda3"; "/mp1/mp2"];
1280        ["mkdir"; "/mp1/mp2/mp3"];
1281        ["umount_all"];
1282        ["mounts"]], [])],
1283    "unmount all filesystems",
1284    "\
1285 This unmounts all mounted filesystems.
1286
1287 Some internal mounts are not unmounted by this call.");
1288
1289   ("lvm_remove_all", (RErr, []), 48, [DangerWillRobinson],
1290    [],
1291    "remove all LVM LVs, VGs and PVs",
1292    "\
1293 This command removes all LVM logical volumes, volume groups
1294 and physical volumes.");
1295
1296   ("file", (RString "description", [String "path"]), 49, [],
1297    [InitBasicFS, Always, TestOutput (
1298       [["touch"; "/new"];
1299        ["file"; "/new"]], "empty");
1300     InitBasicFS, Always, TestOutput (
1301       [["write_file"; "/new"; "some content\n"; "0"];
1302        ["file"; "/new"]], "ASCII text");
1303     InitBasicFS, Always, TestLastFail (
1304       [["file"; "/nofile"]])],
1305    "determine file type",
1306    "\
1307 This call uses the standard L<file(1)> command to determine
1308 the type or contents of the file.  This also works on devices,
1309 for example to find out whether a partition contains a filesystem.
1310
1311 The exact command which runs is C<file -bsL path>.  Note in
1312 particular that the filename is not prepended to the output
1313 (the C<-b> option).");
1314
1315   ("command", (RString "output", [StringList "arguments"]), 50, [ProtocolLimitWarning],
1316    [InitBasicFS, Always, TestOutput (
1317       [["upload"; "test-command"; "/test-command"];
1318        ["chmod"; "493"; "/test-command"];
1319        ["command"; "/test-command 1"]], "Result1");
1320     InitBasicFS, Always, TestOutput (
1321       [["upload"; "test-command"; "/test-command"];
1322        ["chmod"; "493"; "/test-command"];
1323        ["command"; "/test-command 2"]], "Result2\n");
1324     InitBasicFS, Always, TestOutput (
1325       [["upload"; "test-command"; "/test-command"];
1326        ["chmod"; "493"; "/test-command"];
1327        ["command"; "/test-command 3"]], "\nResult3");
1328     InitBasicFS, Always, TestOutput (
1329       [["upload"; "test-command"; "/test-command"];
1330        ["chmod"; "493"; "/test-command"];
1331        ["command"; "/test-command 4"]], "\nResult4\n");
1332     InitBasicFS, Always, TestOutput (
1333       [["upload"; "test-command"; "/test-command"];
1334        ["chmod"; "493"; "/test-command"];
1335        ["command"; "/test-command 5"]], "\nResult5\n\n");
1336     InitBasicFS, Always, TestOutput (
1337       [["upload"; "test-command"; "/test-command"];
1338        ["chmod"; "493"; "/test-command"];
1339        ["command"; "/test-command 6"]], "\n\nResult6\n\n");
1340     InitBasicFS, Always, TestOutput (
1341       [["upload"; "test-command"; "/test-command"];
1342        ["chmod"; "493"; "/test-command"];
1343        ["command"; "/test-command 7"]], "");
1344     InitBasicFS, Always, TestOutput (
1345       [["upload"; "test-command"; "/test-command"];
1346        ["chmod"; "493"; "/test-command"];
1347        ["command"; "/test-command 8"]], "\n");
1348     InitBasicFS, Always, TestOutput (
1349       [["upload"; "test-command"; "/test-command"];
1350        ["chmod"; "493"; "/test-command"];
1351        ["command"; "/test-command 9"]], "\n\n");
1352     InitBasicFS, Always, TestOutput (
1353       [["upload"; "test-command"; "/test-command"];
1354        ["chmod"; "493"; "/test-command"];
1355        ["command"; "/test-command 10"]], "Result10-1\nResult10-2\n");
1356     InitBasicFS, Always, TestOutput (
1357       [["upload"; "test-command"; "/test-command"];
1358        ["chmod"; "493"; "/test-command"];
1359        ["command"; "/test-command 11"]], "Result11-1\nResult11-2");
1360     InitBasicFS, Always, TestLastFail (
1361       [["upload"; "test-command"; "/test-command"];
1362        ["chmod"; "493"; "/test-command"];
1363        ["command"; "/test-command"]])],
1364    "run a command from the guest filesystem",
1365    "\
1366 This call runs a command from the guest filesystem.  The
1367 filesystem must be mounted, and must contain a compatible
1368 operating system (ie. something Linux, with the same
1369 or compatible processor architecture).
1370
1371 The single parameter is an argv-style list of arguments.
1372 The first element is the name of the program to run.
1373 Subsequent elements are parameters.  The list must be
1374 non-empty (ie. must contain a program name).
1375
1376 The return value is anything printed to I<stdout> by
1377 the command.
1378
1379 If the command returns a non-zero exit status, then
1380 this function returns an error message.  The error message
1381 string is the content of I<stderr> from the command.
1382
1383 The C<$PATH> environment variable will contain at least
1384 C</usr/bin> and C</bin>.  If you require a program from
1385 another location, you should provide the full path in the
1386 first parameter.
1387
1388 Shared libraries and data files required by the program
1389 must be available on filesystems which are mounted in the
1390 correct places.  It is the caller's responsibility to ensure
1391 all filesystems that are needed are mounted at the right
1392 locations.");
1393
1394   ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [ProtocolLimitWarning],
1395    [InitBasicFS, Always, TestOutputList (
1396       [["upload"; "test-command"; "/test-command"];
1397        ["chmod"; "493"; "/test-command"];
1398        ["command_lines"; "/test-command 1"]], ["Result1"]);
1399     InitBasicFS, Always, TestOutputList (
1400       [["upload"; "test-command"; "/test-command"];
1401        ["chmod"; "493"; "/test-command"];
1402        ["command_lines"; "/test-command 2"]], ["Result2"]);
1403     InitBasicFS, Always, TestOutputList (
1404       [["upload"; "test-command"; "/test-command"];
1405        ["chmod"; "493"; "/test-command"];
1406        ["command_lines"; "/test-command 3"]], ["";"Result3"]);
1407     InitBasicFS, Always, TestOutputList (
1408       [["upload"; "test-command"; "/test-command"];
1409        ["chmod"; "493"; "/test-command"];
1410        ["command_lines"; "/test-command 4"]], ["";"Result4"]);
1411     InitBasicFS, Always, TestOutputList (
1412       [["upload"; "test-command"; "/test-command"];
1413        ["chmod"; "493"; "/test-command"];
1414        ["command_lines"; "/test-command 5"]], ["";"Result5";""]);
1415     InitBasicFS, Always, TestOutputList (
1416       [["upload"; "test-command"; "/test-command"];
1417        ["chmod"; "493"; "/test-command"];
1418        ["command_lines"; "/test-command 6"]], ["";"";"Result6";""]);
1419     InitBasicFS, Always, TestOutputList (
1420       [["upload"; "test-command"; "/test-command"];
1421        ["chmod"; "493"; "/test-command"];
1422        ["command_lines"; "/test-command 7"]], []);
1423     InitBasicFS, Always, TestOutputList (
1424       [["upload"; "test-command"; "/test-command"];
1425        ["chmod"; "493"; "/test-command"];
1426        ["command_lines"; "/test-command 8"]], [""]);
1427     InitBasicFS, Always, TestOutputList (
1428       [["upload"; "test-command"; "/test-command"];
1429        ["chmod"; "493"; "/test-command"];
1430        ["command_lines"; "/test-command 9"]], ["";""]);
1431     InitBasicFS, Always, TestOutputList (
1432       [["upload"; "test-command"; "/test-command"];
1433        ["chmod"; "493"; "/test-command"];
1434        ["command_lines"; "/test-command 10"]], ["Result10-1";"Result10-2"]);
1435     InitBasicFS, Always, TestOutputList (
1436       [["upload"; "test-command"; "/test-command"];
1437        ["chmod"; "493"; "/test-command"];
1438        ["command_lines"; "/test-command 11"]], ["Result11-1";"Result11-2"])],
1439    "run a command, returning lines",
1440    "\
1441 This is the same as C<guestfs_command>, but splits the
1442 result into a list of lines.");
1443
1444   ("stat", (RStat "statbuf", [String "path"]), 52, [],
1445    [InitBasicFS, Always, TestOutputStruct (
1446       [["touch"; "/new"];
1447        ["stat"; "/new"]], [CompareWithInt ("size", 0)])],
1448    "get file information",
1449    "\
1450 Returns file information for the given C<path>.
1451
1452 This is the same as the C<stat(2)> system call.");
1453
1454   ("lstat", (RStat "statbuf", [String "path"]), 53, [],
1455    [InitBasicFS, Always, TestOutputStruct (
1456       [["touch"; "/new"];
1457        ["lstat"; "/new"]], [CompareWithInt ("size", 0)])],
1458    "get file information for a symbolic link",
1459    "\
1460 Returns file information for the given C<path>.
1461
1462 This is the same as C<guestfs_stat> except that if C<path>
1463 is a symbolic link, then the link is stat-ed, not the file it
1464 refers to.
1465
1466 This is the same as the C<lstat(2)> system call.");
1467
1468   ("statvfs", (RStatVFS "statbuf", [String "path"]), 54, [],
1469    [InitBasicFS, Always, TestOutputStruct (
1470       [["statvfs"; "/"]], [CompareWithInt ("bfree", 487702);
1471                            CompareWithInt ("blocks", 490020);
1472                            CompareWithInt ("bsize", 1024)])],
1473    "get file system statistics",
1474    "\
1475 Returns file system statistics for any mounted file system.
1476 C<path> should be a file or directory in the mounted file system
1477 (typically it is the mount point itself, but it doesn't need to be).
1478
1479 This is the same as the C<statvfs(2)> system call.");
1480
1481   ("tune2fs_l", (RHashtable "superblock", [String "device"]), 55, [],
1482    [], (* XXX test *)
1483    "get ext2/ext3/ext4 superblock details",
1484    "\
1485 This returns the contents of the ext2, ext3 or ext4 filesystem
1486 superblock on C<device>.
1487
1488 It is the same as running C<tune2fs -l device>.  See L<tune2fs(8)>
1489 manpage for more details.  The list of fields returned isn't
1490 clearly defined, and depends on both the version of C<tune2fs>
1491 that libguestfs was built against, and the filesystem itself.");
1492
1493   ("blockdev_setro", (RErr, [String "device"]), 56, [],
1494    [InitEmpty, Always, TestOutputTrue (
1495       [["blockdev_setro"; "/dev/sda"];
1496        ["blockdev_getro"; "/dev/sda"]])],
1497    "set block device to read-only",
1498    "\
1499 Sets the block device named C<device> to read-only.
1500
1501 This uses the L<blockdev(8)> command.");
1502
1503   ("blockdev_setrw", (RErr, [String "device"]), 57, [],
1504    [InitEmpty, Always, TestOutputFalse (
1505       [["blockdev_setrw"; "/dev/sda"];
1506        ["blockdev_getro"; "/dev/sda"]])],
1507    "set block device to read-write",
1508    "\
1509 Sets the block device named C<device> to read-write.
1510
1511 This uses the L<blockdev(8)> command.");
1512
1513   ("blockdev_getro", (RBool "ro", [String "device"]), 58, [],
1514    [InitEmpty, Always, TestOutputTrue (
1515       [["blockdev_setro"; "/dev/sda"];
1516        ["blockdev_getro"; "/dev/sda"]])],
1517    "is block device set to read-only",
1518    "\
1519 Returns a boolean indicating if the block device is read-only
1520 (true if read-only, false if not).
1521
1522 This uses the L<blockdev(8)> command.");
1523
1524   ("blockdev_getss", (RInt "sectorsize", [String "device"]), 59, [],
1525    [InitEmpty, Always, TestOutputInt (
1526       [["blockdev_getss"; "/dev/sda"]], 512)],
1527    "get sectorsize of block device",
1528    "\
1529 This returns the size of sectors on a block device.
1530 Usually 512, but can be larger for modern devices.
1531
1532 (Note, this is not the size in sectors, use C<guestfs_blockdev_getsz>
1533 for that).
1534
1535 This uses the L<blockdev(8)> command.");
1536
1537   ("blockdev_getbsz", (RInt "blocksize", [String "device"]), 60, [],
1538    [InitEmpty, Always, TestOutputInt (
1539       [["blockdev_getbsz"; "/dev/sda"]], 4096)],
1540    "get blocksize of block device",
1541    "\
1542 This returns the block size of a device.
1543
1544 (Note this is different from both I<size in blocks> and
1545 I<filesystem block size>).
1546
1547 This uses the L<blockdev(8)> command.");
1548
1549   ("blockdev_setbsz", (RErr, [String "device"; Int "blocksize"]), 61, [],
1550    [], (* XXX test *)
1551    "set blocksize of block device",
1552    "\
1553 This sets the block size of a device.
1554
1555 (Note this is different from both I<size in blocks> and
1556 I<filesystem block size>).
1557
1558 This uses the L<blockdev(8)> command.");
1559
1560   ("blockdev_getsz", (RInt64 "sizeinsectors", [String "device"]), 62, [],
1561    [InitEmpty, Always, TestOutputInt (
1562       [["blockdev_getsz"; "/dev/sda"]], 1024000)],
1563    "get total size of device in 512-byte sectors",
1564    "\
1565 This returns the size of the device in units of 512-byte sectors
1566 (even if the sectorsize isn't 512 bytes ... weird).
1567
1568 See also C<guestfs_blockdev_getss> for the real sector size of
1569 the device, and C<guestfs_blockdev_getsize64> for the more
1570 useful I<size in bytes>.
1571
1572 This uses the L<blockdev(8)> command.");
1573
1574   ("blockdev_getsize64", (RInt64 "sizeinbytes", [String "device"]), 63, [],
1575    [InitEmpty, Always, TestOutputInt (
1576       [["blockdev_getsize64"; "/dev/sda"]], 524288000)],
1577    "get total size of device in bytes",
1578    "\
1579 This returns the size of the device in bytes.
1580
1581 See also C<guestfs_blockdev_getsz>.
1582
1583 This uses the L<blockdev(8)> command.");
1584
1585   ("blockdev_flushbufs", (RErr, [String "device"]), 64, [],
1586    [InitEmpty, Always, TestRun
1587       [["blockdev_flushbufs"; "/dev/sda"]]],
1588    "flush device buffers",
1589    "\
1590 This tells the kernel to flush internal buffers associated
1591 with C<device>.
1592
1593 This uses the L<blockdev(8)> command.");
1594
1595   ("blockdev_rereadpt", (RErr, [String "device"]), 65, [],
1596    [InitEmpty, Always, TestRun
1597       [["blockdev_rereadpt"; "/dev/sda"]]],
1598    "reread partition table",
1599    "\
1600 Reread the partition table on C<device>.
1601
1602 This uses the L<blockdev(8)> command.");
1603
1604   ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [],
1605    [InitBasicFS, Always, TestOutput (
1606       (* Pick a file from cwd which isn't likely to change. *)
1607     [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1608      ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")],
1609    "upload a file from the local machine",
1610    "\
1611 Upload local file C<filename> to C<remotefilename> on the
1612 filesystem.
1613
1614 C<filename> can also be a named pipe.
1615
1616 See also C<guestfs_download>.");
1617
1618   ("download", (RErr, [String "remotefilename"; FileOut "filename"]), 67, [],
1619    [InitBasicFS, Always, TestOutput (
1620       (* Pick a file from cwd which isn't likely to change. *)
1621     [["upload"; "../COPYING.LIB"; "/COPYING.LIB"];
1622      ["download"; "/COPYING.LIB"; "testdownload.tmp"];
1623      ["upload"; "testdownload.tmp"; "/upload"];
1624      ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")],
1625    "download a file to the local machine",
1626    "\
1627 Download file C<remotefilename> and save it as C<filename>
1628 on the local machine.
1629
1630 C<filename> can also be a named pipe.
1631
1632 See also C<guestfs_upload>, C<guestfs_cat>.");
1633
1634   ("checksum", (RString "checksum", [String "csumtype"; String "path"]), 68, [],
1635    [InitBasicFS, Always, TestOutput (
1636       [["write_file"; "/new"; "test\n"; "0"];
1637        ["checksum"; "crc"; "/new"]], "935282863");
1638     InitBasicFS, Always, TestLastFail (
1639       [["checksum"; "crc"; "/new"]]);
1640     InitBasicFS, Always, TestOutput (
1641       [["write_file"; "/new"; "test\n"; "0"];
1642        ["checksum"; "md5"; "/new"]], "d8e8fca2dc0f896fd7cb4cb0031ba249");
1643     InitBasicFS, Always, TestOutput (
1644       [["write_file"; "/new"; "test\n"; "0"];
1645        ["checksum"; "sha1"; "/new"]], "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83");
1646     InitBasicFS, Always, TestOutput (
1647       [["write_file"; "/new"; "test\n"; "0"];
1648        ["checksum"; "sha224"; "/new"]], "52f1bf093f4b7588726035c176c0cdb4376cfea53819f1395ac9e6ec");
1649     InitBasicFS, Always, TestOutput (
1650       [["write_file"; "/new"; "test\n"; "0"];
1651        ["checksum"; "sha256"; "/new"]], "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2");
1652     InitBasicFS, Always, TestOutput (
1653       [["write_file"; "/new"; "test\n"; "0"];
1654        ["checksum"; "sha384"; "/new"]], "109bb6b5b6d5547c1ce03c7a8bd7d8f80c1cb0957f50c4f7fda04692079917e4f9cad52b878f3d8234e1a170b154b72d");
1655     InitBasicFS, Always, TestOutput (
1656       [["write_file"; "/new"; "test\n"; "0"];
1657        ["checksum"; "sha512"; "/new"]], "0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123");
1658     InitBasicFS, Always, TestOutput (
1659       [["mount"; "/dev/sdd"; "/"];
1660        ["checksum"; "md5"; "/known-3"]], "46d6ca27ee07cdc6fa99c2e138cc522c")],
1661    "compute MD5, SHAx or CRC checksum of file",
1662    "\
1663 This call computes the MD5, SHAx or CRC checksum of the
1664 file named C<path>.
1665
1666 The type of checksum to compute is given by the C<csumtype>
1667 parameter which must have one of the following values:
1668
1669 =over 4
1670
1671 =item C<crc>
1672
1673 Compute the cyclic redundancy check (CRC) specified by POSIX
1674 for the C<cksum> command.
1675
1676 =item C<md5>
1677
1678 Compute the MD5 hash (using the C<md5sum> program).
1679
1680 =item C<sha1>
1681
1682 Compute the SHA1 hash (using the C<sha1sum> program).
1683
1684 =item C<sha224>
1685
1686 Compute the SHA224 hash (using the C<sha224sum> program).
1687
1688 =item C<sha256>
1689
1690 Compute the SHA256 hash (using the C<sha256sum> program).
1691
1692 =item C<sha384>
1693
1694 Compute the SHA384 hash (using the C<sha384sum> program).
1695
1696 =item C<sha512>
1697
1698 Compute the SHA512 hash (using the C<sha512sum> program).
1699
1700 =back
1701
1702 The checksum is returned as a printable string.");
1703
1704   ("tar_in", (RErr, [FileIn "tarfile"; String "directory"]), 69, [],
1705    [InitBasicFS, Always, TestOutput (
1706       [["tar_in"; "../images/helloworld.tar"; "/"];
1707        ["cat"; "/hello"]], "hello\n")],
1708    "unpack tarfile to directory",
1709    "\
1710 This command uploads and unpacks local file C<tarfile> (an
1711 I<uncompressed> tar file) into C<directory>.
1712
1713 To upload a compressed tarball, use C<guestfs_tgz_in>.");
1714
1715   ("tar_out", (RErr, [String "directory"; FileOut "tarfile"]), 70, [],
1716    [],
1717    "pack directory into tarfile",
1718    "\
1719 This command packs the contents of C<directory> and downloads
1720 it to local file C<tarfile>.
1721
1722 To download a compressed tarball, use C<guestfs_tgz_out>.");
1723
1724   ("tgz_in", (RErr, [FileIn "tarball"; String "directory"]), 71, [],
1725    [InitBasicFS, Always, TestOutput (
1726       [["tgz_in"; "../images/helloworld.tar.gz"; "/"];
1727        ["cat"; "/hello"]], "hello\n")],
1728    "unpack compressed tarball to directory",
1729    "\
1730 This command uploads and unpacks local file C<tarball> (a
1731 I<gzip compressed> tar file) into C<directory>.
1732
1733 To upload an uncompressed tarball, use C<guestfs_tar_in>.");
1734
1735   ("tgz_out", (RErr, [String "directory"; FileOut "tarball"]), 72, [],
1736    [],
1737    "pack directory into compressed tarball",
1738    "\
1739 This command packs the contents of C<directory> and downloads
1740 it to local file C<tarball>.
1741
1742 To download an uncompressed tarball, use C<guestfs_tar_out>.");
1743
1744   ("mount_ro", (RErr, [String "device"; String "mountpoint"]), 73, [],
1745    [InitBasicFS, Always, TestLastFail (
1746       [["umount"; "/"];
1747        ["mount_ro"; "/dev/sda1"; "/"];
1748        ["touch"; "/new"]]);
1749     InitBasicFS, Always, TestOutput (
1750       [["write_file"; "/new"; "data"; "0"];
1751        ["umount"; "/"];
1752        ["mount_ro"; "/dev/sda1"; "/"];
1753        ["cat"; "/new"]], "data")],
1754    "mount a guest disk, read-only",
1755    "\
1756 This is the same as the C<guestfs_mount> command, but it
1757 mounts the filesystem with the read-only (I<-o ro>) flag.");
1758
1759   ("mount_options", (RErr, [String "options"; String "device"; String "mountpoint"]), 74, [],
1760    [],
1761    "mount a guest disk with mount options",
1762    "\
1763 This is the same as the C<guestfs_mount> command, but it
1764 allows you to set the mount options as for the
1765 L<mount(8)> I<-o> flag.");
1766
1767   ("mount_vfs", (RErr, [String "options"; String "vfstype"; String "device"; String "mountpoint"]), 75, [],
1768    [],
1769    "mount a guest disk with mount options and vfstype",
1770    "\
1771 This is the same as the C<guestfs_mount> command, but it
1772 allows you to set both the mount options and the vfstype
1773 as for the L<mount(8)> I<-o> and I<-t> flags.");
1774
1775   ("debug", (RString "result", [String "subcmd"; StringList "extraargs"]), 76, [],
1776    [],
1777    "debugging and internals",
1778    "\
1779 The C<guestfs_debug> command exposes some internals of
1780 C<guestfsd> (the guestfs daemon) that runs inside the
1781 qemu subprocess.
1782
1783 There is no comprehensive help for this command.  You have
1784 to look at the file C<daemon/debug.c> in the libguestfs source
1785 to find out what you can do.");
1786
1787   ("lvremove", (RErr, [String "device"]), 77, [],
1788    [InitEmpty, Always, TestOutputList (
1789       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1790        ["pvcreate"; "/dev/sda1"];
1791        ["vgcreate"; "VG"; "/dev/sda1"];
1792        ["lvcreate"; "LV1"; "VG"; "50"];
1793        ["lvcreate"; "LV2"; "VG"; "50"];
1794        ["lvremove"; "/dev/VG/LV1"];
1795        ["lvs"]], ["/dev/VG/LV2"]);
1796     InitEmpty, Always, TestOutputList (
1797       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1798        ["pvcreate"; "/dev/sda1"];
1799        ["vgcreate"; "VG"; "/dev/sda1"];
1800        ["lvcreate"; "LV1"; "VG"; "50"];
1801        ["lvcreate"; "LV2"; "VG"; "50"];
1802        ["lvremove"; "/dev/VG"];
1803        ["lvs"]], []);
1804     InitEmpty, Always, TestOutputList (
1805       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1806        ["pvcreate"; "/dev/sda1"];
1807        ["vgcreate"; "VG"; "/dev/sda1"];
1808        ["lvcreate"; "LV1"; "VG"; "50"];
1809        ["lvcreate"; "LV2"; "VG"; "50"];
1810        ["lvremove"; "/dev/VG"];
1811        ["vgs"]], ["VG"])],
1812    "remove an LVM logical volume",
1813    "\
1814 Remove an LVM logical volume C<device>, where C<device> is
1815 the path to the LV, such as C</dev/VG/LV>.
1816
1817 You can also remove all LVs in a volume group by specifying
1818 the VG name, C</dev/VG>.");
1819
1820   ("vgremove", (RErr, [String "vgname"]), 78, [],
1821    [InitEmpty, Always, TestOutputList (
1822       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1823        ["pvcreate"; "/dev/sda1"];
1824        ["vgcreate"; "VG"; "/dev/sda1"];
1825        ["lvcreate"; "LV1"; "VG"; "50"];
1826        ["lvcreate"; "LV2"; "VG"; "50"];
1827        ["vgremove"; "VG"];
1828        ["lvs"]], []);
1829     InitEmpty, Always, TestOutputList (
1830       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1831        ["pvcreate"; "/dev/sda1"];
1832        ["vgcreate"; "VG"; "/dev/sda1"];
1833        ["lvcreate"; "LV1"; "VG"; "50"];
1834        ["lvcreate"; "LV2"; "VG"; "50"];
1835        ["vgremove"; "VG"];
1836        ["vgs"]], [])],
1837    "remove an LVM volume group",
1838    "\
1839 Remove an LVM volume group C<vgname>, (for example C<VG>).
1840
1841 This also forcibly removes all logical volumes in the volume
1842 group (if any).");
1843
1844   ("pvremove", (RErr, [String "device"]), 79, [],
1845    [InitEmpty, Always, TestOutputList (
1846       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1847        ["pvcreate"; "/dev/sda1"];
1848        ["vgcreate"; "VG"; "/dev/sda1"];
1849        ["lvcreate"; "LV1"; "VG"; "50"];
1850        ["lvcreate"; "LV2"; "VG"; "50"];
1851        ["vgremove"; "VG"];
1852        ["pvremove"; "/dev/sda1"];
1853        ["lvs"]], []);
1854     InitEmpty, Always, TestOutputList (
1855       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1856        ["pvcreate"; "/dev/sda1"];
1857        ["vgcreate"; "VG"; "/dev/sda1"];
1858        ["lvcreate"; "LV1"; "VG"; "50"];
1859        ["lvcreate"; "LV2"; "VG"; "50"];
1860        ["vgremove"; "VG"];
1861        ["pvremove"; "/dev/sda1"];
1862        ["vgs"]], []);
1863     InitEmpty, Always, TestOutputList (
1864       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
1865        ["pvcreate"; "/dev/sda1"];
1866        ["vgcreate"; "VG"; "/dev/sda1"];
1867        ["lvcreate"; "LV1"; "VG"; "50"];
1868        ["lvcreate"; "LV2"; "VG"; "50"];
1869        ["vgremove"; "VG"];
1870        ["pvremove"; "/dev/sda1"];
1871        ["pvs"]], [])],
1872    "remove an LVM physical volume",
1873    "\
1874 This wipes a physical volume C<device> so that LVM will no longer
1875 recognise it.
1876
1877 The implementation uses the C<pvremove> command which refuses to
1878 wipe physical volumes that contain any volume groups, so you have
1879 to remove those first.");
1880
1881   ("set_e2label", (RErr, [String "device"; String "label"]), 80, [],
1882    [InitBasicFS, Always, TestOutput (
1883       [["set_e2label"; "/dev/sda1"; "testlabel"];
1884        ["get_e2label"; "/dev/sda1"]], "testlabel")],
1885    "set the ext2/3/4 filesystem label",
1886    "\
1887 This sets the ext2/3/4 filesystem label of the filesystem on
1888 C<device> to C<label>.  Filesystem labels are limited to
1889 16 characters.
1890
1891 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2label>
1892 to return the existing label on a filesystem.");
1893
1894   ("get_e2label", (RString "label", [String "device"]), 81, [],
1895    [],
1896    "get the ext2/3/4 filesystem label",
1897    "\
1898 This returns the ext2/3/4 filesystem label of the filesystem on
1899 C<device>.");
1900
1901   ("set_e2uuid", (RErr, [String "device"; String "uuid"]), 82, [],
1902    [InitBasicFS, Always, TestOutput (
1903       [["set_e2uuid"; "/dev/sda1"; "a3a61220-882b-4f61-89f4-cf24dcc7297d"];
1904        ["get_e2uuid"; "/dev/sda1"]], "a3a61220-882b-4f61-89f4-cf24dcc7297d");
1905     InitBasicFS, Always, TestOutput (
1906       [["set_e2uuid"; "/dev/sda1"; "clear"];
1907        ["get_e2uuid"; "/dev/sda1"]], "");
1908     (* We can't predict what UUIDs will be, so just check the commands run. *)
1909     InitBasicFS, Always, TestRun (
1910       [["set_e2uuid"; "/dev/sda1"; "random"]]);
1911     InitBasicFS, Always, TestRun (
1912       [["set_e2uuid"; "/dev/sda1"; "time"]])],
1913    "set the ext2/3/4 filesystem UUID",
1914    "\
1915 This sets the ext2/3/4 filesystem UUID of the filesystem on
1916 C<device> to C<uuid>.  The format of the UUID and alternatives
1917 such as C<clear>, C<random> and C<time> are described in the
1918 L<tune2fs(8)> manpage.
1919
1920 You can use either C<guestfs_tune2fs_l> or C<guestfs_get_e2uuid>
1921 to return the existing UUID of a filesystem.");
1922
1923   ("get_e2uuid", (RString "uuid", [String "device"]), 83, [],
1924    [],
1925    "get the ext2/3/4 filesystem UUID",
1926    "\
1927 This returns the ext2/3/4 filesystem UUID of the filesystem on
1928 C<device>.");
1929
1930   ("fsck", (RInt "status", [String "fstype"; String "device"]), 84, [],
1931    [InitBasicFS, Always, TestOutputInt (
1932       [["umount"; "/dev/sda1"];
1933        ["fsck"; "ext2"; "/dev/sda1"]], 0);
1934     InitBasicFS, Always, TestOutputInt (
1935       [["umount"; "/dev/sda1"];
1936        ["zero"; "/dev/sda1"];
1937        ["fsck"; "ext2"; "/dev/sda1"]], 8)],
1938    "run the filesystem checker",
1939    "\
1940 This runs the filesystem checker (fsck) on C<device> which
1941 should have filesystem type C<fstype>.
1942
1943 The returned integer is the status.  See L<fsck(8)> for the
1944 list of status codes from C<fsck>.
1945
1946 Notes:
1947
1948 =over 4
1949
1950 =item *
1951
1952 Multiple status codes can be summed together.
1953
1954 =item *
1955
1956 A non-zero return code can mean \"success\", for example if
1957 errors have been corrected on the filesystem.
1958
1959 =item *
1960
1961 Checking or repairing NTFS volumes is not supported
1962 (by linux-ntfs).
1963
1964 =back
1965
1966 This command is entirely equivalent to running C<fsck -a -t fstype device>.");
1967
1968   ("zero", (RErr, [String "device"]), 85, [],
1969    [InitBasicFS, Always, TestOutput (
1970       [["umount"; "/dev/sda1"];
1971        ["zero"; "/dev/sda1"];
1972        ["file"; "/dev/sda1"]], "data")],
1973    "write zeroes to the device",
1974    "\
1975 This command writes zeroes over the first few blocks of C<device>.
1976
1977 How many blocks are zeroed isn't specified (but it's I<not> enough
1978 to securely wipe the device).  It should be sufficient to remove
1979 any partition tables, filesystem superblocks and so on.");
1980
1981   ("grub_install", (RErr, [String "root"; String "device"]), 86, [],
1982    [InitBasicFS, Always, TestOutputTrue (
1983       [["grub_install"; "/"; "/dev/sda1"];
1984        ["is_dir"; "/boot"]])],
1985    "install GRUB",
1986    "\
1987 This command installs GRUB (the Grand Unified Bootloader) on
1988 C<device>, with the root directory being C<root>.");
1989
1990   ("cp", (RErr, [String "src"; String "dest"]), 87, [],
1991    [InitBasicFS, Always, TestOutput (
1992       [["write_file"; "/old"; "file content"; "0"];
1993        ["cp"; "/old"; "/new"];
1994        ["cat"; "/new"]], "file content");
1995     InitBasicFS, Always, TestOutputTrue (
1996       [["write_file"; "/old"; "file content"; "0"];
1997        ["cp"; "/old"; "/new"];
1998        ["is_file"; "/old"]]);
1999     InitBasicFS, Always, TestOutput (
2000       [["write_file"; "/old"; "file content"; "0"];
2001        ["mkdir"; "/dir"];
2002        ["cp"; "/old"; "/dir/new"];
2003        ["cat"; "/dir/new"]], "file content")],
2004    "copy a file",
2005    "\
2006 This copies a file from C<src> to C<dest> where C<dest> is
2007 either a destination filename or destination directory.");
2008
2009   ("cp_a", (RErr, [String "src"; String "dest"]), 88, [],
2010    [InitBasicFS, Always, TestOutput (
2011       [["mkdir"; "/olddir"];
2012        ["mkdir"; "/newdir"];
2013        ["write_file"; "/olddir/file"; "file content"; "0"];
2014        ["cp_a"; "/olddir"; "/newdir"];
2015        ["cat"; "/newdir/olddir/file"]], "file content")],
2016    "copy a file or directory recursively",
2017    "\
2018 This copies a file or directory from C<src> to C<dest>
2019 recursively using the C<cp -a> command.");
2020
2021   ("mv", (RErr, [String "src"; String "dest"]), 89, [],
2022    [InitBasicFS, Always, TestOutput (
2023       [["write_file"; "/old"; "file content"; "0"];
2024        ["mv"; "/old"; "/new"];
2025        ["cat"; "/new"]], "file content");
2026     InitBasicFS, Always, TestOutputFalse (
2027       [["write_file"; "/old"; "file content"; "0"];
2028        ["mv"; "/old"; "/new"];
2029        ["is_file"; "/old"]])],
2030    "move a file",
2031    "\
2032 This moves a file from C<src> to C<dest> where C<dest> is
2033 either a destination filename or destination directory.");
2034
2035   ("drop_caches", (RErr, [Int "whattodrop"]), 90, [],
2036    [InitEmpty, Always, TestRun (
2037       [["drop_caches"; "3"]])],
2038    "drop kernel page cache, dentries and inodes",
2039    "\
2040 This instructs the guest kernel to drop its page cache,
2041 and/or dentries and inode caches.  The parameter C<whattodrop>
2042 tells the kernel what precisely to drop, see
2043 L<http://linux-mm.org/Drop_Caches>
2044
2045 Setting C<whattodrop> to 3 should drop everything.
2046
2047 This automatically calls L<sync(2)> before the operation,
2048 so that the maximum guest memory is freed.");
2049
2050   ("dmesg", (RString "kmsgs", []), 91, [],
2051    [InitEmpty, Always, TestRun (
2052       [["dmesg"]])],
2053    "return kernel messages",
2054    "\
2055 This returns the kernel messages (C<dmesg> output) from
2056 the guest kernel.  This is sometimes useful for extended
2057 debugging of problems.
2058
2059 Another way to get the same information is to enable
2060 verbose messages with C<guestfs_set_verbose> or by setting
2061 the environment variable C<LIBGUESTFS_DEBUG=1> before
2062 running the program.");
2063
2064   ("ping_daemon", (RErr, []), 92, [],
2065    [InitEmpty, Always, TestRun (
2066       [["ping_daemon"]])],
2067    "ping the guest daemon",
2068    "\
2069 This is a test probe into the guestfs daemon running inside
2070 the qemu subprocess.  Calling this function checks that the
2071 daemon responds to the ping message, without affecting the daemon
2072 or attached block device(s) in any other way.");
2073
2074   ("equal", (RBool "equality", [String "file1"; String "file2"]), 93, [],
2075    [InitBasicFS, Always, TestOutputTrue (
2076       [["write_file"; "/file1"; "contents of a file"; "0"];
2077        ["cp"; "/file1"; "/file2"];
2078        ["equal"; "/file1"; "/file2"]]);
2079     InitBasicFS, Always, TestOutputFalse (
2080       [["write_file"; "/file1"; "contents of a file"; "0"];
2081        ["write_file"; "/file2"; "contents of another file"; "0"];
2082        ["equal"; "/file1"; "/file2"]]);
2083     InitBasicFS, Always, TestLastFail (
2084       [["equal"; "/file1"; "/file2"]])],
2085    "test if two files have equal contents",
2086    "\
2087 This compares the two files C<file1> and C<file2> and returns
2088 true if their content is exactly equal, or false otherwise.
2089
2090 The external L<cmp(1)> program is used for the comparison.");
2091
2092   ("strings", (RStringList "stringsout", [String "path"]), 94, [ProtocolLimitWarning],
2093    [InitBasicFS, Always, TestOutputList (
2094       [["write_file"; "/new"; "hello\nworld\n"; "0"];
2095        ["strings"; "/new"]], ["hello"; "world"]);
2096     InitBasicFS, Always, TestOutputList (
2097       [["touch"; "/new"];
2098        ["strings"; "/new"]], [])],
2099    "print the printable strings in a file",
2100    "\
2101 This runs the L<strings(1)> command on a file and returns
2102 the list of printable strings found.");
2103
2104   ("strings_e", (RStringList "stringsout", [String "encoding"; String "path"]), 95, [ProtocolLimitWarning],
2105    [InitBasicFS, Always, TestOutputList (
2106       [["write_file"; "/new"; "hello\nworld\n"; "0"];
2107        ["strings_e"; "b"; "/new"]], []);
2108     InitBasicFS, Disabled, TestOutputList (
2109       [["write_file"; "/new"; "\000h\000e\000l\000l\000o\000\n\000w\000o\000r\000l\000d\000\n"; "24"];
2110        ["strings_e"; "b"; "/new"]], ["hello"; "world"])],
2111    "print the printable strings in a file",
2112    "\
2113 This is like the C<guestfs_strings> command, but allows you to
2114 specify the encoding.
2115
2116 See the L<strings(1)> manpage for the full list of encodings.
2117
2118 Commonly useful encodings are C<l> (lower case L) which will
2119 show strings inside Windows/x86 files.
2120
2121 The returned strings are transcoded to UTF-8.");
2122
2123   ("hexdump", (RString "dump", [String "path"]), 96, [ProtocolLimitWarning],
2124    [InitBasicFS, Always, TestOutput (
2125       [["write_file"; "/new"; "hello\nworld\n"; "12"];
2126        ["hexdump"; "/new"]], "00000000  68 65 6c 6c 6f 0a 77 6f  72 6c 64 0a              |hello.world.|\n0000000c\n")],
2127    "dump a file in hexadecimal",
2128    "\
2129 This runs C<hexdump -C> on the given C<path>.  The result is
2130 the human-readable, canonical hex dump of the file.");
2131
2132   ("zerofree", (RErr, [String "device"]), 97, [],
2133    [InitNone, Always, TestOutput (
2134       [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
2135        ["mkfs"; "ext3"; "/dev/sda1"];
2136        ["mount"; "/dev/sda1"; "/"];
2137        ["write_file"; "/new"; "test file"; "0"];
2138        ["umount"; "/dev/sda1"];
2139        ["zerofree"; "/dev/sda1"];
2140        ["mount"; "/dev/sda1"; "/"];
2141        ["cat"; "/new"]], "test file")],
2142    "zero unused inodes and disk blocks on ext2/3 filesystem",
2143    "\
2144 This runs the I<zerofree> program on C<device>.  This program
2145 claims to zero unused inodes and disk blocks on an ext2/3
2146 filesystem, thus making it possible to compress the filesystem
2147 more effectively.
2148
2149 You should B<not> run this program if the filesystem is
2150 mounted.
2151
2152 It is possible that using this program can damage the filesystem
2153 or data on the filesystem.");
2154
2155   ("pvresize", (RErr, [String "device"]), 98, [],
2156    [],
2157    "resize an LVM physical volume",
2158    "\
2159 This resizes (expands or shrinks) an existing LVM physical
2160 volume to match the new size of the underlying device.");
2161
2162   ("sfdisk_N", (RErr, [String "device"; Int "n";
2163                        Int "cyls"; Int "heads"; Int "sectors";
2164                        String "line"]), 99, [DangerWillRobinson],
2165    [],
2166    "modify a single partition on a block device",
2167    "\
2168 This runs L<sfdisk(8)> option to modify just the single
2169 partition C<n> (note: C<n> counts from 1).
2170
2171 For other parameters, see C<guestfs_sfdisk>.  You should usually
2172 pass C<0> for the cyls/heads/sectors parameters.");
2173
2174   ("sfdisk_l", (RString "partitions", [String "device"]), 100, [],
2175    [],
2176    "display the partition table",
2177    "\
2178 This displays the partition table on C<device>, in the
2179 human-readable output of the L<sfdisk(8)> command.  It is
2180 not intended to be parsed.");
2181
2182   ("sfdisk_kernel_geometry", (RString "partitions", [String "device"]), 101, [],
2183    [],
2184    "display the kernel geometry",
2185    "\
2186 This displays the kernel's idea of the geometry of C<device>.
2187
2188 The result is in human-readable format, and not designed to
2189 be parsed.");
2190
2191   ("sfdisk_disk_geometry", (RString "partitions", [String "device"]), 102, [],
2192    [],
2193    "display the disk geometry from the partition table",
2194    "\
2195 This displays the disk geometry of C<device> read from the
2196 partition table.  Especially in the case where the underlying
2197 block device has been resized, this can be different from the
2198 kernel's idea of the geometry (see C<guestfs_sfdisk_kernel_geometry>).
2199
2200 The result is in human-readable format, and not designed to
2201 be parsed.");
2202
2203   ("vg_activate_all", (RErr, [Bool "activate"]), 103, [],
2204    [],
2205    "activate or deactivate all volume groups",
2206    "\
2207 This command activates or (if C<activate> is false) deactivates
2208 all logical volumes in all volume groups.
2209 If activated, then they are made known to the
2210 kernel, ie. they appear as C</dev/mapper> devices.  If deactivated,
2211 then those devices disappear.
2212
2213 This command is the same as running C<vgchange -a y|n>");
2214
2215   ("vg_activate", (RErr, [Bool "activate"; StringList "volgroups"]), 104, [],
2216    [],
2217    "activate or deactivate some volume groups",
2218    "\
2219 This command activates or (if C<activate> is false) deactivates
2220 all logical volumes in the listed volume groups C<volgroups>.
2221 If activated, then they are made known to the
2222 kernel, ie. they appear as C</dev/mapper> devices.  If deactivated,
2223 then those devices disappear.
2224
2225 This command is the same as running C<vgchange -a y|n volgroups...>
2226
2227 Note that if C<volgroups> is an empty list then B<all> volume groups
2228 are activated or deactivated.");
2229
2230   ("lvresize", (RErr, [String "device"; Int "mbytes"]), 105, [],
2231    [InitNone, Always, TestOutput (
2232     [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","];
2233      ["pvcreate"; "/dev/sda1"];
2234      ["vgcreate"; "VG"; "/dev/sda1"];
2235      ["lvcreate"; "LV"; "VG"; "10"];
2236      ["mkfs"; "ext2"; "/dev/VG/LV"];
2237      ["mount"; "/dev/VG/LV"; "/"];
2238      ["write_file"; "/new"; "test content"; "0"];
2239      ["umount"; "/"];
2240      ["lvresize"; "/dev/VG/LV"; "20"];
2241      ["e2fsck_f"; "/dev/VG/LV"];
2242      ["resize2fs"; "/dev/VG/LV"];
2243      ["mount"; "/dev/VG/LV"; "/"];
2244      ["cat"; "/new"]], "test content")],
2245    "resize an LVM logical volume",
2246    "\
2247 This resizes (expands or shrinks) an existing LVM logical
2248 volume to C<mbytes>.  When reducing, data in the reduced part
2249 is lost.");
2250
2251   ("resize2fs", (RErr, [String "device"]), 106, [],
2252    [], (* lvresize tests this *)
2253    "resize an ext2/ext3 filesystem",
2254    "\
2255 This resizes an ext2 or ext3 filesystem to match the size of
2256 the underlying device.
2257
2258 I<Note:> It is sometimes required that you run C<guestfs_e2fsck_f>
2259 on the C<device> before calling this command.  For unknown reasons
2260 C<resize2fs> sometimes gives an error about this and sometimes not.
2261 In any case, it is always safe to call C<guestfs_e2fsck_f> before
2262 calling this function.");
2263
2264   ("find", (RStringList "names", [String "directory"]), 107, [],
2265    [InitBasicFS, Always, TestOutputList (
2266       [["find"; "/"]], ["lost+found"]);
2267     InitBasicFS, Always, TestOutputList (
2268       [["touch"; "/a"];
2269        ["mkdir"; "/b"];
2270        ["touch"; "/b/c"];
2271        ["find"; "/"]], ["a"; "b"; "b/c"; "lost+found"]);
2272     InitBasicFS, Always, TestOutputList (
2273       [["mkdir_p"; "/a/b/c"];
2274        ["touch"; "/a/b/c/d"];
2275        ["find"; "/a/b/"]], ["c"; "c/d"])],
2276    "find all files and directories",
2277    "\
2278 This command lists out all files and directories, recursively,
2279 starting at C<directory>.  It is essentially equivalent to
2280 running the shell command C<find directory -print> but some
2281 post-processing happens on the output, described below.
2282
2283 This returns a list of strings I<without any prefix>.  Thus
2284 if the directory structure was:
2285
2286  /tmp/a
2287  /tmp/b
2288  /tmp/c/d
2289
2290 then the returned list from C<guestfs_find> C</tmp> would be
2291 4 elements:
2292
2293  a
2294  b
2295  c
2296  c/d
2297
2298 If C<directory> is not a directory, then this command returns
2299 an error.
2300
2301 The returned list is sorted.");
2302
2303   ("e2fsck_f", (RErr, [String "device"]), 108, [],
2304    [], (* lvresize tests this *)
2305    "check an ext2/ext3 filesystem",
2306    "\
2307 This runs C<e2fsck -p -f device>, ie. runs the ext2/ext3
2308 filesystem checker on C<device>, noninteractively (C<-p>),
2309 even if the filesystem appears to be clean (C<-f>).
2310
2311 This command is only needed because of C<guestfs_resize2fs>
2312 (q.v.).  Normally you should use C<guestfs_fsck>.");
2313
2314 ]
2315
2316 let all_functions = non_daemon_functions @ daemon_functions
2317
2318 (* In some places we want the functions to be displayed sorted
2319  * alphabetically, so this is useful:
2320  *)
2321 let all_functions_sorted =
2322   List.sort (fun (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) ->
2323                compare n1 n2) all_functions
2324
2325 (* Column names and types from LVM PVs/VGs/LVs. *)
2326 let pv_cols = [
2327   "pv_name", `String;
2328   "pv_uuid", `UUID;
2329   "pv_fmt", `String;
2330   "pv_size", `Bytes;
2331   "dev_size", `Bytes;
2332   "pv_free", `Bytes;
2333   "pv_used", `Bytes;
2334   "pv_attr", `String (* XXX *);
2335   "pv_pe_count", `Int;
2336   "pv_pe_alloc_count", `Int;
2337   "pv_tags", `String;
2338   "pe_start", `Bytes;
2339   "pv_mda_count", `Int;
2340   "pv_mda_free", `Bytes;
2341 (* Not in Fedora 10:
2342   "pv_mda_size", `Bytes;
2343 *)
2344 ]
2345 let vg_cols = [
2346   "vg_name", `String;
2347   "vg_uuid", `UUID;
2348   "vg_fmt", `String;
2349   "vg_attr", `String (* XXX *);
2350   "vg_size", `Bytes;
2351   "vg_free", `Bytes;
2352   "vg_sysid", `String;
2353   "vg_extent_size", `Bytes;
2354   "vg_extent_count", `Int;
2355   "vg_free_count", `Int;
2356   "max_lv", `Int;
2357   "max_pv", `Int;
2358   "pv_count", `Int;
2359   "lv_count", `Int;
2360   "snap_count", `Int;
2361   "vg_seqno", `Int;
2362   "vg_tags", `String;
2363   "vg_mda_count", `Int;
2364   "vg_mda_free", `Bytes;
2365 (* Not in Fedora 10:
2366   "vg_mda_size", `Bytes;
2367 *)
2368 ]
2369 let lv_cols = [
2370   "lv_name", `String;
2371   "lv_uuid", `UUID;
2372   "lv_attr", `String (* XXX *);
2373   "lv_major", `Int;
2374   "lv_minor", `Int;
2375   "lv_kernel_major", `Int;
2376   "lv_kernel_minor", `Int;
2377   "lv_size", `Bytes;
2378   "seg_count", `Int;
2379   "origin", `String;
2380   "snap_percent", `OptPercent;
2381   "copy_percent", `OptPercent;
2382   "move_pv", `String;
2383   "lv_tags", `String;
2384   "mirror_log", `String;
2385   "modules", `String;
2386 ]
2387
2388 (* Column names and types from stat structures.
2389  * NB. Can't use things like 'st_atime' because glibc header files
2390  * define some of these as macros.  Ugh.
2391  *)
2392 let stat_cols = [
2393   "dev", `Int;
2394   "ino", `Int;
2395   "mode", `Int;
2396   "nlink", `Int;
2397   "uid", `Int;
2398   "gid", `Int;
2399   "rdev", `Int;
2400   "size", `Int;
2401   "blksize", `Int;
2402   "blocks", `Int;
2403   "atime", `Int;
2404   "mtime", `Int;
2405   "ctime", `Int;
2406 ]
2407 let statvfs_cols = [
2408   "bsize", `Int;
2409   "frsize", `Int;
2410   "blocks", `Int;
2411   "bfree", `Int;
2412   "bavail", `Int;
2413   "files", `Int;
2414   "ffree", `Int;
2415   "favail", `Int;
2416   "fsid", `Int;
2417   "flag", `Int;
2418   "namemax", `Int;
2419 ]
2420
2421 (* Used for testing language bindings. *)
2422 type callt =
2423   | CallString of string
2424   | CallOptString of string option
2425   | CallStringList of string list
2426   | CallInt of int
2427   | CallBool of bool
2428
2429 (* Useful functions.
2430  * Note we don't want to use any external OCaml libraries which
2431  * makes this a bit harder than it should be.
2432  *)
2433 let failwithf fs = ksprintf failwith fs
2434
2435 let replace_char s c1 c2 =
2436   let s2 = String.copy s in
2437   let r = ref false in
2438   for i = 0 to String.length s2 - 1 do
2439     if String.unsafe_get s2 i = c1 then (
2440       String.unsafe_set s2 i c2;
2441       r := true
2442     )
2443   done;
2444   if not !r then s else s2
2445
2446 let isspace c =
2447   c = ' '
2448   (* || c = '\f' *) || c = '\n' || c = '\r' || c = '\t' (* || c = '\v' *)
2449
2450 let triml ?(test = isspace) str =
2451   let i = ref 0 in
2452   let n = ref (String.length str) in
2453   while !n > 0 && test str.[!i]; do
2454     decr n;
2455     incr i
2456   done;
2457   if !i = 0 then str
2458   else String.sub str !i !n
2459
2460 let trimr ?(test = isspace) str =
2461   let n = ref (String.length str) in
2462   while !n > 0 && test str.[!n-1]; do
2463     decr n
2464   done;
2465   if !n = String.length str then str
2466   else String.sub str 0 !n
2467
2468 let trim ?(test = isspace) str =
2469   trimr ~test (triml ~test str)
2470
2471 let rec find s sub =
2472   let len = String.length s in
2473   let sublen = String.length sub in
2474   let rec loop i =
2475     if i <= len-sublen then (
2476       let rec loop2 j =
2477         if j < sublen then (
2478           if s.[i+j] = sub.[j] then loop2 (j+1)
2479           else -1
2480         ) else
2481           i (* found *)
2482       in
2483       let r = loop2 0 in
2484       if r = -1 then loop (i+1) else r
2485     ) else
2486       -1 (* not found *)
2487   in
2488   loop 0
2489
2490 let rec replace_str s s1 s2 =
2491   let len = String.length s in
2492   let sublen = String.length s1 in
2493   let i = find s s1 in
2494   if i = -1 then s
2495   else (
2496     let s' = String.sub s 0 i in
2497     let s'' = String.sub s (i+sublen) (len-i-sublen) in
2498     s' ^ s2 ^ replace_str s'' s1 s2
2499   )
2500
2501 let rec string_split sep str =
2502   let len = String.length str in
2503   let seplen = String.length sep in
2504   let i = find str sep in
2505   if i = -1 then [str]
2506   else (
2507     let s' = String.sub str 0 i in
2508     let s'' = String.sub str (i+seplen) (len-i-seplen) in
2509     s' :: string_split sep s''
2510   )
2511
2512 let files_equal n1 n2 =
2513   let cmd = sprintf "cmp -s %s %s" (Filename.quote n1) (Filename.quote n2) in
2514   match Sys.command cmd with
2515   | 0 -> true
2516   | 1 -> false
2517   | i -> failwithf "%s: failed with error code %d" cmd i
2518
2519 let rec find_map f = function
2520   | [] -> raise Not_found
2521   | x :: xs ->
2522       match f x with
2523       | Some y -> y
2524       | None -> find_map f xs
2525
2526 let iteri f xs =
2527   let rec loop i = function
2528     | [] -> ()
2529     | x :: xs -> f i x; loop (i+1) xs
2530   in
2531   loop 0 xs
2532
2533 let mapi f xs =
2534   let rec loop i = function
2535     | [] -> []
2536     | x :: xs -> let r = f i x in r :: loop (i+1) xs
2537   in
2538   loop 0 xs
2539
2540 let name_of_argt = function
2541   | String n | OptString n | StringList n | Bool n | Int n
2542   | FileIn n | FileOut n -> n
2543
2544 let seq_of_test = function
2545   | TestRun s | TestOutput (s, _) | TestOutputList (s, _)
2546   | TestOutputInt (s, _) | TestOutputTrue s | TestOutputFalse s
2547   | TestOutputLength (s, _) | TestOutputStruct (s, _)
2548   | TestLastFail s -> s
2549
2550 (* Check function names etc. for consistency. *)
2551 let check_functions () =
2552   let contains_uppercase str =
2553     let len = String.length str in
2554     let rec loop i =
2555       if i >= len then false
2556       else (
2557         let c = str.[i] in
2558         if c >= 'A' && c <= 'Z' then true
2559         else loop (i+1)
2560       )
2561     in
2562     loop 0
2563   in
2564
2565   (* Check function names. *)
2566   List.iter (
2567     fun (name, _, _, _, _, _, _) ->
2568       if String.length name >= 7 && String.sub name 0 7 = "guestfs" then
2569         failwithf "function name %s does not need 'guestfs' prefix" name;
2570       if name = "" then
2571         failwithf "function name is empty";
2572       if name.[0] < 'a' || name.[0] > 'z' then
2573         failwithf "function name %s must start with lowercase a-z" name;
2574       if String.contains name '-' then
2575         failwithf "function name %s should not contain '-', use '_' instead."
2576           name
2577   ) all_functions;
2578
2579   (* Check function parameter/return names. *)
2580   List.iter (
2581     fun (name, style, _, _, _, _, _) ->
2582       let check_arg_ret_name n =
2583         if contains_uppercase n then
2584           failwithf "%s param/ret %s should not contain uppercase chars"
2585             name n;
2586         if String.contains n '-' || String.contains n '_' then
2587           failwithf "%s param/ret %s should not contain '-' or '_'"
2588             name n;
2589         if n = "value" then
2590           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;
2591         if n = "int" || n = "char" || n = "short" || n = "long" then
2592           failwithf "%s has a param/ret which conflicts with a C type (eg. 'int', 'char' etc.)" name;
2593         if n = "i" then
2594           failwithf "%s has a param/ret called 'i', which will cause some conflicts in the generated code" name;
2595         if n = "argv" || n = "args" then
2596           failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" name
2597       in
2598
2599       (match fst style with
2600        | RErr -> ()
2601        | RInt n | RInt64 n | RBool n | RConstString n | RString n
2602        | RStringList n | RPVList n | RVGList n | RLVList n
2603        | RStat n | RStatVFS n
2604        | RHashtable n ->
2605            check_arg_ret_name n
2606        | RIntBool (n,m) ->
2607            check_arg_ret_name n;
2608            check_arg_ret_name m
2609       );
2610       List.iter (fun arg -> check_arg_ret_name (name_of_argt arg)) (snd style)
2611   ) all_functions;
2612
2613   (* Check short descriptions. *)
2614   List.iter (
2615     fun (name, _, _, _, _, shortdesc, _) ->
2616       if shortdesc.[0] <> Char.lowercase shortdesc.[0] then
2617         failwithf "short description of %s should begin with lowercase." name;
2618       let c = shortdesc.[String.length shortdesc-1] in
2619       if c = '\n' || c = '.' then
2620         failwithf "short description of %s should not end with . or \\n." name
2621   ) all_functions;
2622
2623   (* Check long dscriptions. *)
2624   List.iter (
2625     fun (name, _, _, _, _, _, longdesc) ->
2626       if longdesc.[String.length longdesc-1] = '\n' then
2627         failwithf "long description of %s should not end with \\n." name
2628   ) all_functions;
2629
2630   (* Check proc_nrs. *)
2631   List.iter (
2632     fun (name, _, proc_nr, _, _, _, _) ->
2633       if proc_nr <= 0 then
2634         failwithf "daemon function %s should have proc_nr > 0" name
2635   ) daemon_functions;
2636
2637   List.iter (
2638     fun (name, _, proc_nr, _, _, _, _) ->
2639       if proc_nr <> -1 then
2640         failwithf "non-daemon function %s should have proc_nr -1" name
2641   ) non_daemon_functions;
2642
2643   let proc_nrs =
2644     List.map (fun (name, _, proc_nr, _, _, _, _) -> name, proc_nr)
2645       daemon_functions in
2646   let proc_nrs =
2647     List.sort (fun (_,nr1) (_,nr2) -> compare nr1 nr2) proc_nrs in
2648   let rec loop = function
2649     | [] -> ()
2650     | [_] -> ()
2651     | (name1,nr1) :: ((name2,nr2) :: _ as rest) when nr1 < nr2 ->
2652         loop rest
2653     | (name1,nr1) :: (name2,nr2) :: _ ->
2654         failwithf "%s and %s have conflicting procedure numbers (%d, %d)"
2655           name1 name2 nr1 nr2
2656   in
2657   loop proc_nrs;
2658
2659   (* Check tests. *)
2660   List.iter (
2661     function
2662       (* Ignore functions that have no tests.  We generate a
2663        * warning when the user does 'make check' instead.
2664        *)
2665     | name, _, _, _, [], _, _ -> ()
2666     | name, _, _, _, tests, _, _ ->
2667         let funcs =
2668           List.map (
2669             fun (_, _, test) ->
2670               match seq_of_test test with
2671               | [] ->
2672                   failwithf "%s has a test containing an empty sequence" name
2673               | cmds -> List.map List.hd cmds
2674           ) tests in
2675         let funcs = List.flatten funcs in
2676
2677         let tested = List.mem name funcs in
2678
2679         if not tested then
2680           failwithf "function %s has tests but does not test itself" name
2681   ) all_functions
2682
2683 (* 'pr' prints to the current output file. *)
2684 let chan = ref stdout
2685 let pr fs = ksprintf (output_string !chan) fs
2686
2687 (* Generate a header block in a number of standard styles. *)
2688 type comment_style = CStyle | HashStyle | OCamlStyle | HaskellStyle
2689 type license = GPLv2 | LGPLv2
2690
2691 let generate_header comment license =
2692   let c = match comment with
2693     | CStyle ->     pr "/* "; " *"
2694     | HashStyle ->  pr "# ";  "#"
2695     | OCamlStyle -> pr "(* "; " *"
2696     | HaskellStyle -> pr "{- "; "  " in
2697   pr "libguestfs generated file\n";
2698   pr "%s WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.\n" c;
2699   pr "%s ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.\n" c;
2700   pr "%s\n" c;
2701   pr "%s Copyright (C) 2009 Red Hat Inc.\n" c;
2702   pr "%s\n" c;
2703   (match license with
2704    | GPLv2 ->
2705        pr "%s This program is free software; you can redistribute it and/or modify\n" c;
2706        pr "%s it under the terms of the GNU General Public License as published by\n" c;
2707        pr "%s the Free Software Foundation; either version 2 of the License, or\n" c;
2708        pr "%s (at your option) any later version.\n" c;
2709        pr "%s\n" c;
2710        pr "%s This program is distributed in the hope that it will be useful,\n" c;
2711        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
2712        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" c;
2713        pr "%s GNU General Public License for more details.\n" c;
2714        pr "%s\n" c;
2715        pr "%s You should have received a copy of the GNU General Public License along\n" c;
2716        pr "%s with this program; if not, write to the Free Software Foundation, Inc.,\n" c;
2717        pr "%s 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" c;
2718
2719    | LGPLv2 ->
2720        pr "%s This library is free software; you can redistribute it and/or\n" c;
2721        pr "%s modify it under the terms of the GNU Lesser General Public\n" c;
2722        pr "%s License as published by the Free Software Foundation; either\n" c;
2723        pr "%s version 2 of the License, or (at your option) any later version.\n" c;
2724        pr "%s\n" c;
2725        pr "%s This library is distributed in the hope that it will be useful,\n" c;
2726        pr "%s but WITHOUT ANY WARRANTY; without even the implied warranty of\n" c;
2727        pr "%s MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" c;
2728        pr "%s Lesser General Public License for more details.\n" c;
2729        pr "%s\n" c;
2730        pr "%s You should have received a copy of the GNU Lesser General Public\n" c;
2731        pr "%s License along with this library; if not, write to the Free Software\n" c;
2732        pr "%s Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" c;
2733   );
2734   (match comment with
2735    | CStyle -> pr " */\n"
2736    | HashStyle -> ()
2737    | OCamlStyle -> pr " *)\n"
2738    | HaskellStyle -> pr "-}\n"
2739   );
2740   pr "\n"
2741
2742 (* Start of main code generation functions below this line. *)
2743
2744 (* Generate the pod documentation for the C API. *)
2745 let rec generate_actions_pod () =
2746   List.iter (
2747     fun (shortname, style, _, flags, _, _, longdesc) ->
2748       if not (List.mem NotInDocs flags) then (
2749         let name = "guestfs_" ^ shortname in
2750         pr "=head2 %s\n\n" name;
2751         pr " ";
2752         generate_prototype ~extern:false ~handle:"handle" name style;
2753         pr "\n\n";
2754         pr "%s\n\n" longdesc;
2755         (match fst style with
2756          | RErr ->
2757              pr "This function returns 0 on success or -1 on error.\n\n"
2758          | RInt _ ->
2759              pr "On error this function returns -1.\n\n"
2760          | RInt64 _ ->
2761              pr "On error this function returns -1.\n\n"
2762          | RBool _ ->
2763              pr "This function returns a C truth value on success or -1 on error.\n\n"
2764          | RConstString _ ->
2765              pr "This function returns a string, or NULL on error.
2766 The string is owned by the guest handle and must I<not> be freed.\n\n"
2767          | RString _ ->
2768              pr "This function returns a string, or NULL on error.
2769 I<The caller must free the returned string after use>.\n\n"
2770          | RStringList _ ->
2771              pr "This function returns a NULL-terminated array of strings
2772 (like L<environ(3)>), or NULL if there was an error.
2773 I<The caller must free the strings and the array after use>.\n\n"
2774          | RIntBool _ ->
2775              pr "This function returns a C<struct guestfs_int_bool *>,
2776 or NULL if there was an error.
2777 I<The caller must call C<guestfs_free_int_bool> after use>.\n\n"
2778          | RPVList _ ->
2779              pr "This function returns a C<struct guestfs_lvm_pv_list *>
2780 (see E<lt>guestfs-structs.hE<gt>),
2781 or NULL if there was an error.
2782 I<The caller must call C<guestfs_free_lvm_pv_list> after use>.\n\n"
2783          | RVGList _ ->
2784              pr "This function returns a C<struct guestfs_lvm_vg_list *>
2785 (see E<lt>guestfs-structs.hE<gt>),
2786 or NULL if there was an error.
2787 I<The caller must call C<guestfs_free_lvm_vg_list> after use>.\n\n"
2788          | RLVList _ ->
2789              pr "This function returns a C<struct guestfs_lvm_lv_list *>
2790 (see E<lt>guestfs-structs.hE<gt>),
2791 or NULL if there was an error.
2792 I<The caller must call C<guestfs_free_lvm_lv_list> after use>.\n\n"
2793          | RStat _ ->
2794              pr "This function returns a C<struct guestfs_stat *>
2795 (see L<stat(2)> and E<lt>guestfs-structs.hE<gt>),
2796 or NULL if there was an error.
2797 I<The caller must call C<free> after use>.\n\n"
2798          | RStatVFS _ ->
2799              pr "This function returns a C<struct guestfs_statvfs *>
2800 (see L<statvfs(2)> and E<lt>guestfs-structs.hE<gt>),
2801 or NULL if there was an error.
2802 I<The caller must call C<free> after use>.\n\n"
2803          | RHashtable _ ->
2804              pr "This function returns a NULL-terminated array of
2805 strings, or NULL if there was an error.
2806 The array of strings will always have length C<2n+1>, where
2807 C<n> keys and values alternate, followed by the trailing NULL entry.
2808 I<The caller must free the strings and the array after use>.\n\n"
2809         );
2810         if List.mem ProtocolLimitWarning flags then
2811           pr "%s\n\n" protocol_limit_warning;
2812         if List.mem DangerWillRobinson flags then
2813           pr "%s\n\n" danger_will_robinson
2814       )
2815   ) all_functions_sorted
2816
2817 and generate_structs_pod () =
2818   (* LVM structs documentation. *)
2819   List.iter (
2820     fun (typ, cols) ->
2821       pr "=head2 guestfs_lvm_%s\n" typ;
2822       pr "\n";
2823       pr " struct guestfs_lvm_%s {\n" typ;
2824       List.iter (
2825         function
2826         | name, `String -> pr "  char *%s;\n" name
2827         | name, `UUID ->
2828             pr "  /* The next field is NOT nul-terminated, be careful when printing it: */\n";
2829             pr "  char %s[32];\n" name
2830         | name, `Bytes -> pr "  uint64_t %s;\n" name
2831         | name, `Int -> pr "  int64_t %s;\n" name
2832         | name, `OptPercent ->
2833             pr "  /* The next field is [0..100] or -1 meaning 'not present': */\n";
2834             pr "  float %s;\n" name
2835       ) cols;
2836       pr " \n";
2837       pr " struct guestfs_lvm_%s_list {\n" typ;
2838       pr "   uint32_t len; /* Number of elements in list. */\n";
2839       pr "   struct guestfs_lvm_%s *val; /* Elements. */\n" typ;
2840       pr " };\n";
2841       pr " \n";
2842       pr " void guestfs_free_lvm_%s_list (struct guestfs_free_lvm_%s_list *);\n"
2843         typ typ;
2844       pr "\n"
2845   ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]
2846
2847 (* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
2848  * indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'.
2849  *
2850  * We have to use an underscore instead of a dash because otherwise
2851  * rpcgen generates incorrect code.
2852  *
2853  * This header is NOT exported to clients, but see also generate_structs_h.
2854  *)
2855 and generate_xdr () =
2856   generate_header CStyle LGPLv2;
2857
2858   (* This has to be defined to get around a limitation in Sun's rpcgen. *)
2859   pr "typedef string str<>;\n";
2860   pr "\n";
2861
2862   (* LVM internal structures. *)
2863   List.iter (
2864     function
2865     | typ, cols ->
2866         pr "struct guestfs_lvm_int_%s {\n" typ;
2867         List.iter (function
2868                    | name, `String -> pr "  string %s<>;\n" name
2869                    | name, `UUID -> pr "  opaque %s[32];\n" name
2870                    | name, `Bytes -> pr "  hyper %s;\n" name
2871                    | name, `Int -> pr "  hyper %s;\n" name
2872                    | name, `OptPercent -> pr "  float %s;\n" name
2873                   ) cols;
2874         pr "};\n";
2875         pr "\n";
2876         pr "typedef struct guestfs_lvm_int_%s guestfs_lvm_int_%s_list<>;\n" typ typ;
2877         pr "\n";
2878   ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols];
2879
2880   (* Stat internal structures. *)
2881   List.iter (
2882     function
2883     | typ, cols ->
2884         pr "struct guestfs_int_%s {\n" typ;
2885         List.iter (function
2886                    | name, `Int -> pr "  hyper %s;\n" name
2887                   ) cols;
2888         pr "};\n";
2889         pr "\n";
2890   ) ["stat", stat_cols; "statvfs", statvfs_cols];
2891
2892   List.iter (
2893     fun (shortname, style, _, _, _, _, _) ->
2894       let name = "guestfs_" ^ shortname in
2895
2896       (match snd style with
2897        | [] -> ()
2898        | args ->
2899            pr "struct %s_args {\n" name;
2900            List.iter (
2901              function
2902              | String n -> pr "  string %s<>;\n" n
2903              | OptString n -> pr "  str *%s;\n" n
2904              | StringList n -> pr "  str %s<>;\n" n
2905              | Bool n -> pr "  bool %s;\n" n
2906              | Int n -> pr "  int %s;\n" n
2907              | FileIn _ | FileOut _ -> ()
2908            ) args;
2909            pr "};\n\n"
2910       );
2911       (match fst style with
2912        | RErr -> ()
2913        | RInt n ->
2914            pr "struct %s_ret {\n" name;
2915            pr "  int %s;\n" n;
2916            pr "};\n\n"
2917        | RInt64 n ->
2918            pr "struct %s_ret {\n" name;
2919            pr "  hyper %s;\n" n;
2920            pr "};\n\n"
2921        | RBool n ->
2922            pr "struct %s_ret {\n" name;
2923            pr "  bool %s;\n" n;
2924            pr "};\n\n"
2925        | RConstString _ ->
2926            failwithf "RConstString cannot be returned from a daemon function"
2927        | RString n ->
2928            pr "struct %s_ret {\n" name;
2929            pr "  string %s<>;\n" n;
2930            pr "};\n\n"
2931        | RStringList n ->
2932            pr "struct %s_ret {\n" name;
2933            pr "  str %s<>;\n" n;
2934            pr "};\n\n"
2935        | RIntBool (n,m) ->
2936            pr "struct %s_ret {\n" name;
2937            pr "  int %s;\n" n;
2938            pr "  bool %s;\n" m;
2939            pr "};\n\n"
2940        | RPVList n ->
2941            pr "struct %s_ret {\n" name;
2942            pr "  guestfs_lvm_int_pv_list %s;\n" n;
2943            pr "};\n\n"
2944        | RVGList n ->
2945            pr "struct %s_ret {\n" name;
2946            pr "  guestfs_lvm_int_vg_list %s;\n" n;
2947            pr "};\n\n"
2948        | RLVList n ->
2949            pr "struct %s_ret {\n" name;
2950            pr "  guestfs_lvm_int_lv_list %s;\n" n;
2951            pr "};\n\n"
2952        | RStat n ->
2953            pr "struct %s_ret {\n" name;
2954            pr "  guestfs_int_stat %s;\n" n;
2955            pr "};\n\n"
2956        | RStatVFS n ->
2957            pr "struct %s_ret {\n" name;
2958            pr "  guestfs_int_statvfs %s;\n" n;
2959            pr "};\n\n"
2960        | RHashtable n ->
2961            pr "struct %s_ret {\n" name;
2962            pr "  str %s<>;\n" n;
2963            pr "};\n\n"
2964       );
2965   ) daemon_functions;
2966
2967   (* Table of procedure numbers. *)
2968   pr "enum guestfs_procedure {\n";
2969   List.iter (
2970     fun (shortname, _, proc_nr, _, _, _, _) ->
2971       pr "  GUESTFS_PROC_%s = %d,\n" (String.uppercase shortname) proc_nr
2972   ) daemon_functions;
2973   pr "  GUESTFS_PROC_NR_PROCS\n";
2974   pr "};\n";
2975   pr "\n";
2976
2977   (* Having to choose a maximum message size is annoying for several
2978    * reasons (it limits what we can do in the API), but it (a) makes
2979    * the protocol a lot simpler, and (b) provides a bound on the size
2980    * of the daemon which operates in limited memory space.  For large
2981    * file transfers you should use FTP.
2982    *)
2983   pr "const GUESTFS_MESSAGE_MAX = %d;\n" (4 * 1024 * 1024);
2984   pr "\n";
2985
2986   (* Message header, etc. *)
2987   pr "\
2988 /* The communication protocol is now documented in the guestfs(3)
2989  * manpage.
2990  */
2991
2992 const GUESTFS_PROGRAM = 0x2000F5F5;
2993 const GUESTFS_PROTOCOL_VERSION = 1;
2994
2995 /* These constants must be larger than any possible message length. */
2996 const GUESTFS_LAUNCH_FLAG = 0xf5f55ff5;
2997 const GUESTFS_CANCEL_FLAG = 0xffffeeee;
2998
2999 enum guestfs_message_direction {
3000   GUESTFS_DIRECTION_CALL = 0,        /* client -> daemon */
3001   GUESTFS_DIRECTION_REPLY = 1        /* daemon -> client */
3002 };
3003
3004 enum guestfs_message_status {
3005   GUESTFS_STATUS_OK = 0,
3006   GUESTFS_STATUS_ERROR = 1
3007 };
3008
3009 const GUESTFS_ERROR_LEN = 256;
3010
3011 struct guestfs_message_error {
3012   string error_message<GUESTFS_ERROR_LEN>;
3013 };
3014
3015 struct guestfs_message_header {
3016   unsigned prog;                     /* GUESTFS_PROGRAM */
3017   unsigned vers;                     /* GUESTFS_PROTOCOL_VERSION */
3018   guestfs_procedure proc;            /* GUESTFS_PROC_x */
3019   guestfs_message_direction direction;
3020   unsigned serial;                   /* message serial number */
3021   guestfs_message_status status;
3022 };
3023
3024 const GUESTFS_MAX_CHUNK_SIZE = 8192;
3025
3026 struct guestfs_chunk {
3027   int cancel;                        /* if non-zero, transfer is cancelled */
3028   /* data size is 0 bytes if the transfer has finished successfully */
3029   opaque data<GUESTFS_MAX_CHUNK_SIZE>;
3030 };
3031 "
3032
3033 (* Generate the guestfs-structs.h file. *)
3034 and generate_structs_h () =
3035   generate_header CStyle LGPLv2;
3036
3037   (* This is a public exported header file containing various
3038    * structures.  The structures are carefully written to have
3039    * exactly the same in-memory format as the XDR structures that
3040    * we use on the wire to the daemon.  The reason for creating
3041    * copies of these structures here is just so we don't have to
3042    * export the whole of guestfs_protocol.h (which includes much
3043    * unrelated and XDR-dependent stuff that we don't want to be
3044    * public, or required by clients).
3045    *
3046    * To reiterate, we will pass these structures to and from the
3047    * client with a simple assignment or memcpy, so the format
3048    * must be identical to what rpcgen / the RFC defines.
3049    *)
3050
3051   (* guestfs_int_bool structure. *)
3052   pr "struct guestfs_int_bool {\n";
3053   pr "  int32_t i;\n";
3054   pr "  int32_t b;\n";
3055   pr "};\n";
3056   pr "\n";
3057
3058   (* LVM public structures. *)
3059   List.iter (
3060     function
3061     | typ, cols ->
3062         pr "struct guestfs_lvm_%s {\n" typ;
3063         List.iter (
3064           function
3065           | name, `String -> pr "  char *%s;\n" name
3066           | name, `UUID -> pr "  char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
3067           | name, `Bytes -> pr "  uint64_t %s;\n" name
3068           | name, `Int -> pr "  int64_t %s;\n" name
3069           | name, `OptPercent -> pr "  float %s; /* [0..100] or -1 */\n" name
3070         ) cols;
3071         pr "};\n";
3072         pr "\n";
3073         pr "struct guestfs_lvm_%s_list {\n" typ;
3074         pr "  uint32_t len;\n";
3075         pr "  struct guestfs_lvm_%s *val;\n" typ;
3076         pr "};\n";
3077         pr "\n"
3078   ) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols];
3079
3080   (* Stat structures. *)
3081   List.iter (
3082     function
3083     | typ, cols ->
3084         pr "struct guestfs_%s {\n" typ;
3085         List.iter (
3086           function
3087           | name, `Int -> pr "  int64_t %s;\n" name
3088         ) cols;
3089         pr "};\n";
3090         pr "\n"
3091   ) ["stat", stat_cols; "statvfs", statvfs_cols]
3092
3093 (* Generate the guestfs-actions.h file. *)
3094 and generate_actions_h () =
3095   generate_header CStyle LGPLv2;
3096   List.iter (
3097     fun (shortname, style, _, _, _, _, _) ->
3098       let name = "guestfs_" ^ shortname in
3099       generate_prototype ~single_line:true ~newline:true ~handle:"handle"
3100         name style
3101   ) all_functions
3102
3103 (* Generate the client-side dispatch stubs. *)
3104 and generate_client_actions () =
3105   generate_header CStyle LGPLv2;
3106
3107   pr "\
3108 #include <stdio.h>
3109 #include <stdlib.h>
3110
3111 #include \"guestfs.h\"
3112 #include \"guestfs_protocol.h\"
3113
3114 #define error guestfs_error
3115 #define perrorf guestfs_perrorf
3116 #define safe_malloc guestfs_safe_malloc
3117 #define safe_realloc guestfs_safe_realloc
3118 #define safe_strdup guestfs_safe_strdup
3119 #define safe_memdup guestfs_safe_memdup
3120
3121 /* Check the return message from a call for validity. */
3122 static int
3123 check_reply_header (guestfs_h *g,
3124                     const struct guestfs_message_header *hdr,
3125                     int proc_nr, int serial)
3126 {
3127   if (hdr->prog != GUESTFS_PROGRAM) {
3128     error (g, \"wrong program (%%d/%%d)\", hdr->prog, GUESTFS_PROGRAM);
3129     return -1;
3130   }
3131   if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
3132     error (g, \"wrong protocol version (%%d/%%d)\",
3133            hdr->vers, GUESTFS_PROTOCOL_VERSION);
3134     return -1;
3135   }
3136   if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
3137     error (g, \"unexpected message direction (%%d/%%d)\",
3138            hdr->direction, GUESTFS_DIRECTION_REPLY);
3139     return -1;
3140   }
3141   if (hdr->proc != proc_nr) {
3142     error (g, \"unexpected procedure number (%%d/%%d)\", hdr->proc, proc_nr);
3143     return -1;
3144   }
3145   if (hdr->serial != serial) {
3146     error (g, \"unexpected serial (%%d/%%d)\", hdr->serial, serial);
3147     return -1;
3148   }
3149
3150   return 0;
3151 }
3152
3153 /* Check we are in the right state to run a high-level action. */
3154 static int
3155 check_state (guestfs_h *g, const char *caller)
3156 {
3157   if (!guestfs_is_ready (g)) {
3158     if (guestfs_is_config (g))
3159       error (g, \"%%s: call launch() before using this function\",
3160         caller);
3161     else if (guestfs_is_launching (g))
3162       error (g, \"%%s: call wait_ready() before using this function\",
3163         caller);
3164     else
3165       error (g, \"%%s called from the wrong state, %%d != READY\",
3166         caller, guestfs_get_state (g));
3167     return -1;
3168   }
3169   return 0;
3170 }
3171
3172 ";
3173
3174   (* Client-side stubs for each function. *)
3175   List.iter (
3176     fun (shortname, style, _, _, _, _, _) ->
3177       let name = "guestfs_" ^ shortname in
3178
3179       (* Generate the context struct which stores the high-level
3180        * state between callback functions.
3181        *)
3182       pr "struct %s_ctx {\n" shortname;
3183       pr "  /* This flag is set by the callbacks, so we know we've done\n";
3184       pr "   * the callbacks as expected, and in the right sequence.\n";
3185       pr "   * 0 = not called, 1 = reply_cb called.\n";
3186       pr "   */\n";
3187       pr "  int cb_sequence;\n";
3188       pr "  struct guestfs_message_header hdr;\n";
3189       pr "  struct guestfs_message_error err;\n";
3190       (match fst style with
3191        | RErr -> ()
3192        | RConstString _ ->
3193            failwithf "RConstString cannot be returned from a daemon function"
3194        | RInt _ | RInt64 _
3195        | RBool _ | RString _ | RStringList _
3196        | RIntBool _
3197        | RPVList _ | RVGList _ | RLVList _
3198        | RStat _ | RStatVFS _
3199        | RHashtable _ ->
3200            pr "  struct %s_ret ret;\n" name
3201       );
3202       pr "};\n";
3203       pr "\n";
3204
3205       (* Generate the reply callback function. *)
3206       pr "static void %s_reply_cb (guestfs_h *g, void *data, XDR *xdr)\n" shortname;
3207       pr "{\n";
3208       pr "  guestfs_main_loop *ml = guestfs_get_main_loop (g);\n";
3209       pr "  struct %s_ctx *ctx = (struct %s_ctx *) data;\n" shortname shortname;
3210       pr "\n";
3211       pr "  /* This should definitely not happen. */\n";
3212       pr "  if (ctx->cb_sequence != 0) {\n";
3213       pr "    ctx->cb_sequence = 9999;\n";
3214       pr "    error (g, \"%%s: internal error: reply callback called twice\", \"%s\");\n" name;
3215       pr "    return;\n";
3216       pr "  }\n";
3217       pr "\n";
3218       pr "  ml->main_loop_quit (ml, g);\n";
3219       pr "\n";
3220       pr "  if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {\n";
3221       pr "    error (g, \"%%s: failed to parse reply header\", \"%s\");\n" name;
3222       pr "    return;\n";
3223       pr "  }\n";
3224       pr "  if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {\n";
3225       pr "    if (!xdr_guestfs_message_error (xdr, &ctx->err)) {\n";
3226       pr "      error (g, \"%%s: failed to parse reply error\", \"%s\");\n"
3227         name;
3228       pr "      return;\n";
3229       pr "    }\n";
3230       pr "    goto done;\n";
3231       pr "  }\n";
3232
3233       (match fst style with
3234        | RErr -> ()
3235        | RConstString _ ->
3236            failwithf "RConstString cannot be returned from a daemon function"
3237        | RInt _ | RInt64 _
3238        | RBool _ | RString _ | RStringList _
3239        | RIntBool _
3240        | RPVList _ | RVGList _ | RLVList _
3241        | RStat _ | RStatVFS _
3242        | RHashtable _ ->
3243             pr "  if (!xdr_%s_ret (xdr, &ctx->ret)) {\n" name;
3244             pr "    error (g, \"%%s: failed to parse reply\", \"%s\");\n" name;
3245             pr "    return;\n";
3246             pr "  }\n";
3247       );
3248
3249       pr " done:\n";
3250       pr "  ctx->cb_sequence = 1;\n";
3251       pr "}\n\n";
3252
3253       (* Generate the action stub. *)
3254       generate_prototype ~extern:false ~semicolon:false ~newline:true
3255         ~handle:"g" name style;
3256
3257       let error_code =
3258         match fst style with
3259         | RErr | RInt _ | RInt64 _ | RBool _ -> "-1"
3260         | RConstString _ ->
3261             failwithf "RConstString cannot be returned from a daemon function"
3262         | RString _ | RStringList _ | RIntBool _
3263         | RPVList _ | RVGList _ | RLVList _
3264         | RStat _ | RStatVFS _
3265         | RHashtable _ ->
3266             "NULL" in
3267
3268       pr "{\n";
3269
3270       (match snd style with
3271        | [] -> ()
3272        | _ -> pr "  struct %s_args args;\n" name
3273       );
3274
3275       pr "  struct %s_ctx ctx;\n" shortname;
3276       pr "  guestfs_main_loop *ml = guestfs_get_main_loop (g);\n";
3277       pr "  int serial;\n";
3278       pr "\n";
3279       pr "  if (check_state (g, \"%s\") == -1) return %s;\n" name error_code;
3280       pr "  guestfs_set_busy (g);\n";
3281       pr "\n";
3282       pr "  memset (&ctx, 0, sizeof ctx);\n";
3283       pr "\n";
3284
3285       (* Send the main header and arguments. *)
3286       (match snd style with
3287        | [] ->
3288            pr "  serial = guestfs__send_sync (g, GUESTFS_PROC_%s, NULL, NULL);\n"
3289              (String.uppercase shortname)
3290        | args ->
3291            List.iter (
3292              function
3293              | String n ->
3294                  pr "  args.%s = (char *) %s;\n" n n
3295              | OptString n ->
3296                  pr "  args.%s = %s ? (char **) &%s : NULL;\n" n n n
3297              | StringList n ->
3298                  pr "  args.%s.%s_val = (char **) %s;\n" n n n;
3299                  pr "  for (args.%s.%s_len = 0; %s[args.%s.%s_len]; args.%s.%s_len++) ;\n" n n n n n n n;
3300              | Bool n ->
3301                  pr "  args.%s = %s;\n" n n
3302              | Int n ->
3303                  pr "  args.%s = %s;\n" n n
3304              | FileIn _ | FileOut _ -> ()
3305            ) args;
3306            pr "  serial = guestfs__send_sync (g, GUESTFS_PROC_%s,\n"
3307              (String.uppercase shortname);
3308            pr "        (xdrproc_t) xdr_%s_args, (char *) &args);\n"
3309              name;
3310       );
3311       pr "  if (serial == -1) {\n";
3312       pr "    guestfs_end_busy (g);\n";
3313       pr "    return %s;\n" error_code;
3314       pr "  }\n";
3315       pr "\n";
3316
3317       (* Send any additional files (FileIn) requested. *)
3318       let need_read_reply_label = ref false in
3319       List.iter (
3320         function
3321         | FileIn n ->
3322             pr "  {\n";
3323             pr "    int r;\n";
3324             pr "\n";
3325             pr "    r = guestfs__send_file_sync (g, %s);\n" n;
3326             pr "    if (r == -1) {\n";
3327             pr "      guestfs_end_busy (g);\n";
3328             pr "      return %s;\n" error_code;
3329             pr "    }\n";
3330             pr "    if (r == -2) /* daemon cancelled */\n";
3331             pr "      goto read_reply;\n";
3332             need_read_reply_label := true;
3333             pr "  }\n";
3334             pr "\n";
3335         | _ -> ()
3336       ) (snd style);
3337
3338       (* Wait for the reply from the remote end. *)
3339       if !need_read_reply_label then pr " read_reply:\n";
3340       pr "  guestfs__switch_to_receiving (g);\n";
3341       pr "  ctx.cb_sequence = 0;\n";
3342       pr "  guestfs_set_reply_callback (g, %s_reply_cb, &ctx);\n" shortname;
3343       pr "  (void) ml->main_loop_run (ml, g);\n";
3344       pr "  guestfs_set_reply_callback (g, NULL, NULL);\n";
3345       pr "  if (ctx.cb_sequence != 1) {\n";
3346       pr "    error (g, \"%%s reply failed, see earlier error messages\", \"%s\");\n" name;
3347       pr "    guestfs_end_busy (g);\n";
3348       pr "    return %s;\n" error_code;
3349       pr "  }\n";
3350       pr "\n";
3351
3352       pr "  if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_%s, serial) == -1) {\n"
3353         (String.uppercase shortname);
3354       pr "    guestfs_end_busy (g);\n";
3355       pr "    return %s;\n" error_code;
3356       pr "  }\n";
3357       pr "\n";
3358
3359       pr "  if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {\n";
3360       pr "    error (g, \"%%s\", ctx.err.error_message);\n";
3361       pr "    free (ctx.err.error_message);\n";
3362       pr "    guestfs_end_busy (g);\n";
3363       pr "    return %s;\n" error_code;
3364       pr "  }\n";
3365       pr "\n";
3366
3367       (* Expecting to receive further files (FileOut)? *)
3368       List.iter (
3369         function
3370         | FileOut n ->
3371             pr "  if (guestfs__receive_file_sync (g, %s) == -1) {\n" n;
3372             pr "    guestfs_end_busy (g);\n";
3373             pr "    return %s;\n" error_code;
3374             pr "  }\n";
3375             pr "\n";
3376         | _ -> ()
3377       ) (snd style);
3378
3379       pr "  guestfs_end_busy (g);\n";
3380
3381       (match fst style with
3382        | RErr -> pr "  return 0;\n"
3383        | RInt n | RInt64 n | RBool n ->
3384            pr "  return ctx.ret.%s;\n" n
3385        | RConstString _ ->
3386            failwithf "RConstString cannot be returned from a daemon function"
3387        | RString n ->
3388            pr "  return ctx.ret.%s; /* caller will free */\n" n
3389        | RStringList n | RHashtable n ->
3390            pr "  /* caller will free this, but we need to add a NULL entry */\n";
3391            pr "  ctx.ret.%s.%s_val =\n" n n;
3392            pr "    safe_realloc (g, ctx.ret.%s.%s_val,\n" n n;
3393            pr "                  sizeof (char *) * (ctx.ret.%s.%s_len + 1));\n"
3394              n n;
3395            pr "  ctx.ret.%s.%s_val[ctx.ret.%s.%s_len] = NULL;\n" n n n n;
3396            pr "  return ctx.ret.%s.%s_val;\n" n n
3397        | RIntBool _ ->
3398            pr "  /* caller with free this */\n";
3399            pr "  return safe_memdup (g, &ctx.ret, sizeof (ctx.ret));\n"
3400        | RPVList n | RVGList n | RLVList n
3401        | RStat n | RStatVFS n ->
3402            pr "  /* caller will free this */\n";
3403            pr "  return safe_memdup (g, &ctx.ret.%s, sizeof (ctx.ret.%s));\n" n n
3404       );
3405
3406       pr "}\n\n"
3407   ) daemon_functions
3408
3409 (* Generate daemon/actions.h. *)
3410 and generate_daemon_actions_h () =
3411   generate_header CStyle GPLv2;
3412
3413   pr "#include \"../src/guestfs_protocol.h\"\n";
3414   pr "\n";
3415
3416   List.iter (
3417     fun (name, style, _, _, _, _, _) ->
3418         generate_prototype
3419           ~single_line:true ~newline:true ~in_daemon:true ~prefix:"do_"
3420           name style;
3421   ) daemon_functions
3422
3423 (* Generate the server-side stubs. *)
3424 and generate_daemon_actions () =
3425   generate_header CStyle GPLv2;
3426
3427   pr "#include <config.h>\n";
3428   pr "\n";
3429   pr "#include <stdio.h>\n";
3430   pr "#include <stdlib.h>\n";
3431   pr "#include <string.h>\n";
3432   pr "#include <inttypes.h>\n";
3433   pr "#include <ctype.h>\n";
3434   pr "#include <rpc/types.h>\n";
3435   pr "#include <rpc/xdr.h>\n";
3436   pr "\n";
3437   pr "#include \"daemon.h\"\n";
3438   pr "#include \"../src/guestfs_protocol.h\"\n";
3439   pr "#include \"actions.h\"\n";
3440   pr "\n";
3441
3442   List.iter (
3443     fun (name, style, _, _, _, _, _) ->
3444       (* Generate server-side stubs. *)
3445       pr "static void %s_stub (XDR *xdr_in)\n" name;
3446       pr "{\n";
3447       let error_code =
3448         match fst style with
3449         | RErr | RInt _ -> pr "  int r;\n"; "-1"
3450         | RInt64 _ -> pr "  int64_t r;\n"; "-1"
3451         | RBool _ -> pr "  int r;\n"; "-1"
3452         | RConstString _ ->
3453             failwithf "RConstString cannot be returned from a daemon function"
3454         | RString _ -> pr "  char *r;\n"; "NULL"
3455         | RStringList _ | RHashtable _ -> pr "  char **r;\n"; "NULL"
3456         | RIntBool _ -> pr "  guestfs_%s_ret *r;\n" name; "NULL"
3457         | RPVList _ -> pr "  guestfs_lvm_int_pv_list *r;\n"; "NULL"
3458         | RVGList _ -> pr "  guestfs_lvm_int_vg_list *r;\n"; "NULL"
3459         | RLVList _ -> pr "  guestfs_lvm_int_lv_list *r;\n"; "NULL"
3460         | RStat _ -> pr "  guestfs_int_stat *r;\n"; "NULL"
3461         | RStatVFS _ -> pr "  guestfs_int_statvfs *r;\n"; "NULL" in
3462
3463       (match snd style with
3464        | [] -> ()
3465        | args ->
3466            pr "  struct guestfs_%s_args args;\n" name;
3467            List.iter (
3468              function
3469              | String n
3470              | OptString n -> pr "  const char *%s;\n" n
3471              | StringList n -> pr "  char **%s;\n" n
3472              | Bool n -> pr "  int %s;\n" n
3473              | Int n -> pr "  int %s;\n" n
3474              | FileIn _ | FileOut _ -> ()
3475            ) args
3476       );
3477       pr "\n";
3478
3479       (match snd style with
3480        | [] -> ()
3481        | args ->
3482            pr "  memset (&args, 0, sizeof args);\n";
3483            pr "\n";
3484            pr "  if (!xdr_guestfs_%s_args (xdr_in, &args)) {\n" name;
3485            pr "    reply_with_error (\"%%s: daemon failed to decode procedure arguments\", \"%s\");\n" name;
3486            pr "    return;\n";
3487            pr "  }\n";
3488            List.iter (
3489              function
3490              | String n -> pr "  %s = args.%s;\n" n n
3491              | OptString n -> pr "  %s = args.%s ? *args.%s : NULL;\n" n n n
3492              | StringList n ->
3493                  pr "  %s = realloc (args.%s.%s_val,\n" n n n;
3494                  pr "                sizeof (char *) * (args.%s.%s_len+1));\n" n n;
3495                  pr "  if (%s == NULL) {\n" n;
3496                  pr "    reply_with_perror (\"realloc\");\n";
3497                  pr "    goto done;\n";
3498                  pr "  }\n";
3499                  pr "  %s[args.%s.%s_len] = NULL;\n" n n n;
3500                  pr "  args.%s.%s_val = %s;\n" n n n;
3501              | Bool n -> pr "  %s = args.%s;\n" n n
3502              | Int n -> pr "  %s = args.%s;\n" n n
3503              | FileIn _ | FileOut _ -> ()
3504            ) args;
3505            pr "\n"
3506       );
3507
3508       (* Don't want to call the impl with any FileIn or FileOut
3509        * parameters, since these go "outside" the RPC protocol.
3510        *)
3511       let argsnofile =
3512         List.filter (function FileIn _ | FileOut _ -> false | _ -> true)
3513           (snd style) in
3514       pr "  r = do_%s " name;
3515       generate_call_args argsnofile;
3516       pr ";\n";
3517
3518       pr "  if (r == %s)\n" error_code;
3519       pr "    /* do_%s has already called reply_with_error */\n" name;
3520       pr "    goto done;\n";
3521       pr "\n";
3522
3523       (* If there are any FileOut parameters, then the impl must
3524        * send its own reply.
3525        *)
3526       let no_reply =
3527         List.exists (function FileOut _ -> true | _ -> false) (snd style) in
3528       if no_reply then
3529         pr "  /* do_%s has already sent a reply */\n" name
3530       else (
3531         match fst style with
3532         | RErr -> pr "  reply (NULL, NULL);\n"
3533         | RInt n | RInt64 n | RBool n ->
3534             pr "  struct guestfs_%s_ret ret;\n" name;
3535             pr "  ret.%s = r;\n" n;
3536             pr "  reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
3537               name
3538         | RConstString _ ->
3539             failwithf "RConstString cannot be returned from a daemon function"
3540         | RString n ->
3541             pr "  struct guestfs_%s_ret ret;\n" name;
3542             pr "  ret.%s = r;\n" n;
3543             pr "  reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
3544               name;
3545             pr "  free (r);\n"
3546         | RStringList n | RHashtable n ->
3547             pr "  struct guestfs_%s_ret ret;\n" name;
3548             pr "  ret.%s.%s_len = count_strings (r);\n" n n;
3549             pr "  ret.%s.%s_val = r;\n" n n;
3550             pr "  reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n"
3551               name;
3552             pr "  free_strings (r);\n"
3553         | RIntBool _ ->
3554             pr "  reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n"
3555               name;
3556             pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) r);\n" name
3557         | RPVList n | RVGList n | RLVList n
3558         | RStat n | RStatVFS n ->
3559             pr "  struct guestfs_%s_ret ret;\n" name;
3560             pr "  ret.%s = *r;\n" n;
3561             pr "  reply ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
3562               name;
3563             pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n"
3564               name
3565       );
3566
3567       (* Free the args. *)
3568       (match snd style with
3569        | [] ->
3570            pr "done: ;\n";
3571        | _ ->
3572            pr "done:\n";
3573            pr "  xdr_free ((xdrproc_t) xdr_guestfs_%s_args, (char *) &args);\n"
3574              name
3575       );
3576
3577       pr "}\n\n";
3578   ) daemon_functions;
3579
3580   (* Dispatch function. *)
3581   pr "void dispatch_incoming_message (XDR *xdr_in)\n";
3582   pr "{\n";
3583   pr "  switch (proc_nr) {\n";
3584
3585   List.iter (
3586     fun (name, style, _, _, _, _, _) ->
3587         pr "    case GUESTFS_PROC_%s:\n" (String.uppercase name);
3588         pr "      %s_stub (xdr_in);\n" name;
3589         pr "      break;\n"
3590   ) daemon_functions;
3591
3592   pr "    default:\n";
3593   pr "      reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d\", proc_nr);\n";
3594   pr "  }\n";
3595   pr "}\n";
3596   pr "\n";
3597
3598   (* LVM columns and tokenization functions. *)
3599   (* XXX This generates crap code.  We should rethink how we
3600    * do this parsing.
3601    *)
3602   List.iter (
3603     function
3604     | typ, cols ->
3605         pr "static const char *lvm_%s_cols = \"%s\";\n"
3606           typ (String.concat "," (List.map fst cols));
3607         pr "\n";
3608
3609         pr "static int lvm_tokenize_%s (char *str, struct guestfs_lvm_int_%s *r)\n" typ typ;
3610         pr "{\n";
3611         pr "  char *tok, *p, *next;\n";
3612         pr "  int i, j;\n";
3613         pr "\n";
3614         (*
3615         pr "  fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
3616         pr "\n";
3617         *)
3618         pr "  if (!str) {\n";
3619         pr "    fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
3620         pr "    return -1;\n";
3621         pr "  }\n";
3622         pr "  if (!*str || isspace (*str)) {\n";
3623         pr "    fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
3624         pr "    return -1;\n";
3625         pr "  }\n";
3626         pr "  tok = str;\n";
3627         List.iter (
3628           fun (name, coltype) ->
3629             pr "  if (!tok) {\n";
3630             pr "    fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
3631             pr "    return -1;\n";
3632             pr "  }\n";
3633             pr "  p = strchrnul (tok, ',');\n";
3634             pr "  if (*p) next = p+1; else next = NULL;\n";
3635             pr "  *p = '\\0';\n";
3636             (match coltype with
3637              | `String ->
3638                  pr "  r->%s = strdup (tok);\n" name;
3639                  pr "  if (r->%s == NULL) {\n" name;
3640                  pr "    perror (\"strdup\");\n";
3641                  pr "    return -1;\n";
3642                  pr "  }\n"
3643              | `UUID ->
3644                  pr "  for (i = j = 0; i < 32; ++j) {\n";
3645                  pr "    if (tok[j] == '\\0') {\n";
3646                  pr "      fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
3647                  pr "      return -1;\n";
3648                  pr "    } else if (tok[j] != '-')\n";
3649                  pr "      r->%s[i++] = tok[j];\n" name;
3650                  pr "  }\n";
3651              | `Bytes ->
3652                  pr "  if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
3653                  pr "    fprintf (stderr, \"%%s: failed to parse size