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