Generated code for new mount_* commands.
[libguestfs.git] / src / guestfs-actions.c
1 /* libguestfs generated file
2  * WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.
3  * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
4  *
5  * Copyright (C) 2009 Red Hat Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "guestfs.h"
26 #include "guestfs_protocol.h"
27
28 #define error guestfs_error
29 #define perrorf guestfs_perrorf
30 #define safe_malloc guestfs_safe_malloc
31 #define safe_realloc guestfs_safe_realloc
32 #define safe_strdup guestfs_safe_strdup
33 #define safe_memdup guestfs_safe_memdup
34
35 /* Check the return message from a call for validity. */
36 static int
37 check_reply_header (guestfs_h *g,
38                     const struct guestfs_message_header *hdr,
39                     int proc_nr, int serial)
40 {
41   if (hdr->prog != GUESTFS_PROGRAM) {
42     error (g, "wrong program (%d/%d)", hdr->prog, GUESTFS_PROGRAM);
43     return -1;
44   }
45   if (hdr->vers != GUESTFS_PROTOCOL_VERSION) {
46     error (g, "wrong protocol version (%d/%d)",
47            hdr->vers, GUESTFS_PROTOCOL_VERSION);
48     return -1;
49   }
50   if (hdr->direction != GUESTFS_DIRECTION_REPLY) {
51     error (g, "unexpected message direction (%d/%d)",
52            hdr->direction, GUESTFS_DIRECTION_REPLY);
53     return -1;
54   }
55   if (hdr->proc != proc_nr) {
56     error (g, "unexpected procedure number (%d/%d)", hdr->proc, proc_nr);
57     return -1;
58   }
59   if (hdr->serial != serial) {
60     error (g, "unexpected serial (%d/%d)", hdr->serial, serial);
61     return -1;
62   }
63
64   return 0;
65 }
66
67 /* Check we are in the right state to run a high-level action. */
68 static int
69 check_state (guestfs_h *g, const char *caller)
70 {
71   if (!guestfs_is_ready (g)) {
72     if (guestfs_is_config (g))
73       error (g, "%s: call launch() before using this function",
74         caller);
75     else if (guestfs_is_launching (g))
76       error (g, "%s: call wait_ready() before using this function",
77         caller);
78     else
79       error (g, "%s called from the wrong state, %d != READY",
80         caller, guestfs_get_state (g));
81     return -1;
82   }
83   return 0;
84 }
85
86 struct mount_ctx {
87   /* This flag is set by the callbacks, so we know we've done
88    * the callbacks as expected, and in the right sequence.
89    * 0 = not called, 1 = send called,
90    * 1001 = reply called.
91    */
92   int cb_sequence;
93   struct guestfs_message_header hdr;
94   struct guestfs_message_error err;
95 };
96
97 static void mount_reply_cb (guestfs_h *g, void *data, XDR *xdr)
98 {
99   guestfs_main_loop *ml = guestfs_get_main_loop (g);
100   struct mount_ctx *ctx = (struct mount_ctx *) data;
101
102   ml->main_loop_quit (ml, g);
103
104   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
105     error (g, "%s: failed to parse reply header", "guestfs_mount");
106     return;
107   }
108   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
109     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
110       error (g, "%s: failed to parse reply error", "guestfs_mount");
111       return;
112     }
113     goto done;
114   }
115  done:
116   ctx->cb_sequence = 1001;
117 }
118
119 int guestfs_mount (guestfs_h *g,
120                 const char *device,
121                 const char *mountpoint)
122 {
123   struct guestfs_mount_args args;
124   struct mount_ctx ctx;
125   guestfs_main_loop *ml = guestfs_get_main_loop (g);
126   int serial;
127
128   if (check_state (g, "guestfs_mount") == -1) return -1;
129   guestfs_set_busy (g);
130
131   memset (&ctx, 0, sizeof ctx);
132
133   args.device = (char *) device;
134   args.mountpoint = (char *) mountpoint;
135   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT,
136         (xdrproc_t) xdr_guestfs_mount_args, (char *) &args);
137   if (serial == -1) {
138     guestfs_set_ready (g);
139     return -1;
140   }
141
142   guestfs__switch_to_receiving (g);
143   ctx.cb_sequence = 0;
144   guestfs_set_reply_callback (g, mount_reply_cb, &ctx);
145   (void) ml->main_loop_run (ml, g);
146   guestfs_set_reply_callback (g, NULL, NULL);
147   if (ctx.cb_sequence != 1001) {
148     error (g, "%s reply failed, see earlier error messages", "guestfs_mount");
149     guestfs_set_ready (g);
150     return -1;
151   }
152
153   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT, serial) == -1) {
154     guestfs_set_ready (g);
155     return -1;
156   }
157
158   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
159     error (g, "%s", ctx.err.error_message);
160     guestfs_set_ready (g);
161     return -1;
162   }
163
164   guestfs_set_ready (g);
165   return 0;
166 }
167
168 struct sync_ctx {
169   /* This flag is set by the callbacks, so we know we've done
170    * the callbacks as expected, and in the right sequence.
171    * 0 = not called, 1 = send called,
172    * 1001 = reply called.
173    */
174   int cb_sequence;
175   struct guestfs_message_header hdr;
176   struct guestfs_message_error err;
177 };
178
179 static void sync_reply_cb (guestfs_h *g, void *data, XDR *xdr)
180 {
181   guestfs_main_loop *ml = guestfs_get_main_loop (g);
182   struct sync_ctx *ctx = (struct sync_ctx *) data;
183
184   ml->main_loop_quit (ml, g);
185
186   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
187     error (g, "%s: failed to parse reply header", "guestfs_sync");
188     return;
189   }
190   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
191     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
192       error (g, "%s: failed to parse reply error", "guestfs_sync");
193       return;
194     }
195     goto done;
196   }
197  done:
198   ctx->cb_sequence = 1001;
199 }
200
201 int guestfs_sync (guestfs_h *g)
202 {
203   struct sync_ctx ctx;
204   guestfs_main_loop *ml = guestfs_get_main_loop (g);
205   int serial;
206
207   if (check_state (g, "guestfs_sync") == -1) return -1;
208   guestfs_set_busy (g);
209
210   memset (&ctx, 0, sizeof ctx);
211
212   serial = guestfs__send_sync (g, GUESTFS_PROC_SYNC, NULL, NULL);
213   if (serial == -1) {
214     guestfs_set_ready (g);
215     return -1;
216   }
217
218   guestfs__switch_to_receiving (g);
219   ctx.cb_sequence = 0;
220   guestfs_set_reply_callback (g, sync_reply_cb, &ctx);
221   (void) ml->main_loop_run (ml, g);
222   guestfs_set_reply_callback (g, NULL, NULL);
223   if (ctx.cb_sequence != 1001) {
224     error (g, "%s reply failed, see earlier error messages", "guestfs_sync");
225     guestfs_set_ready (g);
226     return -1;
227   }
228
229   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SYNC, serial) == -1) {
230     guestfs_set_ready (g);
231     return -1;
232   }
233
234   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
235     error (g, "%s", ctx.err.error_message);
236     guestfs_set_ready (g);
237     return -1;
238   }
239
240   guestfs_set_ready (g);
241   return 0;
242 }
243
244 struct touch_ctx {
245   /* This flag is set by the callbacks, so we know we've done
246    * the callbacks as expected, and in the right sequence.
247    * 0 = not called, 1 = send called,
248    * 1001 = reply called.
249    */
250   int cb_sequence;
251   struct guestfs_message_header hdr;
252   struct guestfs_message_error err;
253 };
254
255 static void touch_reply_cb (guestfs_h *g, void *data, XDR *xdr)
256 {
257   guestfs_main_loop *ml = guestfs_get_main_loop (g);
258   struct touch_ctx *ctx = (struct touch_ctx *) data;
259
260   ml->main_loop_quit (ml, g);
261
262   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
263     error (g, "%s: failed to parse reply header", "guestfs_touch");
264     return;
265   }
266   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
267     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
268       error (g, "%s: failed to parse reply error", "guestfs_touch");
269       return;
270     }
271     goto done;
272   }
273  done:
274   ctx->cb_sequence = 1001;
275 }
276
277 int guestfs_touch (guestfs_h *g,
278                 const char *path)
279 {
280   struct guestfs_touch_args args;
281   struct touch_ctx ctx;
282   guestfs_main_loop *ml = guestfs_get_main_loop (g);
283   int serial;
284
285   if (check_state (g, "guestfs_touch") == -1) return -1;
286   guestfs_set_busy (g);
287
288   memset (&ctx, 0, sizeof ctx);
289
290   args.path = (char *) path;
291   serial = guestfs__send_sync (g, GUESTFS_PROC_TOUCH,
292         (xdrproc_t) xdr_guestfs_touch_args, (char *) &args);
293   if (serial == -1) {
294     guestfs_set_ready (g);
295     return -1;
296   }
297
298   guestfs__switch_to_receiving (g);
299   ctx.cb_sequence = 0;
300   guestfs_set_reply_callback (g, touch_reply_cb, &ctx);
301   (void) ml->main_loop_run (ml, g);
302   guestfs_set_reply_callback (g, NULL, NULL);
303   if (ctx.cb_sequence != 1001) {
304     error (g, "%s reply failed, see earlier error messages", "guestfs_touch");
305     guestfs_set_ready (g);
306     return -1;
307   }
308
309   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TOUCH, serial) == -1) {
310     guestfs_set_ready (g);
311     return -1;
312   }
313
314   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
315     error (g, "%s", ctx.err.error_message);
316     guestfs_set_ready (g);
317     return -1;
318   }
319
320   guestfs_set_ready (g);
321   return 0;
322 }
323
324 struct cat_ctx {
325   /* This flag is set by the callbacks, so we know we've done
326    * the callbacks as expected, and in the right sequence.
327    * 0 = not called, 1 = send called,
328    * 1001 = reply called.
329    */
330   int cb_sequence;
331   struct guestfs_message_header hdr;
332   struct guestfs_message_error err;
333   struct guestfs_cat_ret ret;
334 };
335
336 static void cat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
337 {
338   guestfs_main_loop *ml = guestfs_get_main_loop (g);
339   struct cat_ctx *ctx = (struct cat_ctx *) data;
340
341   ml->main_loop_quit (ml, g);
342
343   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
344     error (g, "%s: failed to parse reply header", "guestfs_cat");
345     return;
346   }
347   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
348     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
349       error (g, "%s: failed to parse reply error", "guestfs_cat");
350       return;
351     }
352     goto done;
353   }
354   if (!xdr_guestfs_cat_ret (xdr, &ctx->ret)) {
355     error (g, "%s: failed to parse reply", "guestfs_cat");
356     return;
357   }
358  done:
359   ctx->cb_sequence = 1001;
360 }
361
362 char *guestfs_cat (guestfs_h *g,
363                 const char *path)
364 {
365   struct guestfs_cat_args args;
366   struct cat_ctx ctx;
367   guestfs_main_loop *ml = guestfs_get_main_loop (g);
368   int serial;
369
370   if (check_state (g, "guestfs_cat") == -1) return NULL;
371   guestfs_set_busy (g);
372
373   memset (&ctx, 0, sizeof ctx);
374
375   args.path = (char *) path;
376   serial = guestfs__send_sync (g, GUESTFS_PROC_CAT,
377         (xdrproc_t) xdr_guestfs_cat_args, (char *) &args);
378   if (serial == -1) {
379     guestfs_set_ready (g);
380     return NULL;
381   }
382
383   guestfs__switch_to_receiving (g);
384   ctx.cb_sequence = 0;
385   guestfs_set_reply_callback (g, cat_reply_cb, &ctx);
386   (void) ml->main_loop_run (ml, g);
387   guestfs_set_reply_callback (g, NULL, NULL);
388   if (ctx.cb_sequence != 1001) {
389     error (g, "%s reply failed, see earlier error messages", "guestfs_cat");
390     guestfs_set_ready (g);
391     return NULL;
392   }
393
394   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CAT, serial) == -1) {
395     guestfs_set_ready (g);
396     return NULL;
397   }
398
399   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
400     error (g, "%s", ctx.err.error_message);
401     guestfs_set_ready (g);
402     return NULL;
403   }
404
405   guestfs_set_ready (g);
406   return ctx.ret.content; /* caller will free */
407 }
408
409 struct ll_ctx {
410   /* This flag is set by the callbacks, so we know we've done
411    * the callbacks as expected, and in the right sequence.
412    * 0 = not called, 1 = send called,
413    * 1001 = reply called.
414    */
415   int cb_sequence;
416   struct guestfs_message_header hdr;
417   struct guestfs_message_error err;
418   struct guestfs_ll_ret ret;
419 };
420
421 static void ll_reply_cb (guestfs_h *g, void *data, XDR *xdr)
422 {
423   guestfs_main_loop *ml = guestfs_get_main_loop (g);
424   struct ll_ctx *ctx = (struct ll_ctx *) data;
425
426   ml->main_loop_quit (ml, g);
427
428   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
429     error (g, "%s: failed to parse reply header", "guestfs_ll");
430     return;
431   }
432   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
433     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
434       error (g, "%s: failed to parse reply error", "guestfs_ll");
435       return;
436     }
437     goto done;
438   }
439   if (!xdr_guestfs_ll_ret (xdr, &ctx->ret)) {
440     error (g, "%s: failed to parse reply", "guestfs_ll");
441     return;
442   }
443  done:
444   ctx->cb_sequence = 1001;
445 }
446
447 char *guestfs_ll (guestfs_h *g,
448                 const char *directory)
449 {
450   struct guestfs_ll_args args;
451   struct ll_ctx ctx;
452   guestfs_main_loop *ml = guestfs_get_main_loop (g);
453   int serial;
454
455   if (check_state (g, "guestfs_ll") == -1) return NULL;
456   guestfs_set_busy (g);
457
458   memset (&ctx, 0, sizeof ctx);
459
460   args.directory = (char *) directory;
461   serial = guestfs__send_sync (g, GUESTFS_PROC_LL,
462         (xdrproc_t) xdr_guestfs_ll_args, (char *) &args);
463   if (serial == -1) {
464     guestfs_set_ready (g);
465     return NULL;
466   }
467
468   guestfs__switch_to_receiving (g);
469   ctx.cb_sequence = 0;
470   guestfs_set_reply_callback (g, ll_reply_cb, &ctx);
471   (void) ml->main_loop_run (ml, g);
472   guestfs_set_reply_callback (g, NULL, NULL);
473   if (ctx.cb_sequence != 1001) {
474     error (g, "%s reply failed, see earlier error messages", "guestfs_ll");
475     guestfs_set_ready (g);
476     return NULL;
477   }
478
479   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LL, serial) == -1) {
480     guestfs_set_ready (g);
481     return NULL;
482   }
483
484   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
485     error (g, "%s", ctx.err.error_message);
486     guestfs_set_ready (g);
487     return NULL;
488   }
489
490   guestfs_set_ready (g);
491   return ctx.ret.listing; /* caller will free */
492 }
493
494 struct ls_ctx {
495   /* This flag is set by the callbacks, so we know we've done
496    * the callbacks as expected, and in the right sequence.
497    * 0 = not called, 1 = send called,
498    * 1001 = reply called.
499    */
500   int cb_sequence;
501   struct guestfs_message_header hdr;
502   struct guestfs_message_error err;
503   struct guestfs_ls_ret ret;
504 };
505
506 static void ls_reply_cb (guestfs_h *g, void *data, XDR *xdr)
507 {
508   guestfs_main_loop *ml = guestfs_get_main_loop (g);
509   struct ls_ctx *ctx = (struct ls_ctx *) data;
510
511   ml->main_loop_quit (ml, g);
512
513   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
514     error (g, "%s: failed to parse reply header", "guestfs_ls");
515     return;
516   }
517   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
518     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
519       error (g, "%s: failed to parse reply error", "guestfs_ls");
520       return;
521     }
522     goto done;
523   }
524   if (!xdr_guestfs_ls_ret (xdr, &ctx->ret)) {
525     error (g, "%s: failed to parse reply", "guestfs_ls");
526     return;
527   }
528  done:
529   ctx->cb_sequence = 1001;
530 }
531
532 char **guestfs_ls (guestfs_h *g,
533                 const char *directory)
534 {
535   struct guestfs_ls_args args;
536   struct ls_ctx ctx;
537   guestfs_main_loop *ml = guestfs_get_main_loop (g);
538   int serial;
539
540   if (check_state (g, "guestfs_ls") == -1) return NULL;
541   guestfs_set_busy (g);
542
543   memset (&ctx, 0, sizeof ctx);
544
545   args.directory = (char *) directory;
546   serial = guestfs__send_sync (g, GUESTFS_PROC_LS,
547         (xdrproc_t) xdr_guestfs_ls_args, (char *) &args);
548   if (serial == -1) {
549     guestfs_set_ready (g);
550     return NULL;
551   }
552
553   guestfs__switch_to_receiving (g);
554   ctx.cb_sequence = 0;
555   guestfs_set_reply_callback (g, ls_reply_cb, &ctx);
556   (void) ml->main_loop_run (ml, g);
557   guestfs_set_reply_callback (g, NULL, NULL);
558   if (ctx.cb_sequence != 1001) {
559     error (g, "%s reply failed, see earlier error messages", "guestfs_ls");
560     guestfs_set_ready (g);
561     return NULL;
562   }
563
564   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LS, serial) == -1) {
565     guestfs_set_ready (g);
566     return NULL;
567   }
568
569   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
570     error (g, "%s", ctx.err.error_message);
571     guestfs_set_ready (g);
572     return NULL;
573   }
574
575   guestfs_set_ready (g);
576   /* caller will free this, but we need to add a NULL entry */
577   ctx.ret.listing.listing_val =
578     safe_realloc (g, ctx.ret.listing.listing_val,
579                   sizeof (char *) * (ctx.ret.listing.listing_len + 1));
580   ctx.ret.listing.listing_val[ctx.ret.listing.listing_len] = NULL;
581   return ctx.ret.listing.listing_val;
582 }
583
584 struct list_devices_ctx {
585   /* This flag is set by the callbacks, so we know we've done
586    * the callbacks as expected, and in the right sequence.
587    * 0 = not called, 1 = send called,
588    * 1001 = reply called.
589    */
590   int cb_sequence;
591   struct guestfs_message_header hdr;
592   struct guestfs_message_error err;
593   struct guestfs_list_devices_ret ret;
594 };
595
596 static void list_devices_reply_cb (guestfs_h *g, void *data, XDR *xdr)
597 {
598   guestfs_main_loop *ml = guestfs_get_main_loop (g);
599   struct list_devices_ctx *ctx = (struct list_devices_ctx *) data;
600
601   ml->main_loop_quit (ml, g);
602
603   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
604     error (g, "%s: failed to parse reply header", "guestfs_list_devices");
605     return;
606   }
607   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
608     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
609       error (g, "%s: failed to parse reply error", "guestfs_list_devices");
610       return;
611     }
612     goto done;
613   }
614   if (!xdr_guestfs_list_devices_ret (xdr, &ctx->ret)) {
615     error (g, "%s: failed to parse reply", "guestfs_list_devices");
616     return;
617   }
618  done:
619   ctx->cb_sequence = 1001;
620 }
621
622 char **guestfs_list_devices (guestfs_h *g)
623 {
624   struct list_devices_ctx ctx;
625   guestfs_main_loop *ml = guestfs_get_main_loop (g);
626   int serial;
627
628   if (check_state (g, "guestfs_list_devices") == -1) return NULL;
629   guestfs_set_busy (g);
630
631   memset (&ctx, 0, sizeof ctx);
632
633   serial = guestfs__send_sync (g, GUESTFS_PROC_LIST_DEVICES, NULL, NULL);
634   if (serial == -1) {
635     guestfs_set_ready (g);
636     return NULL;
637   }
638
639   guestfs__switch_to_receiving (g);
640   ctx.cb_sequence = 0;
641   guestfs_set_reply_callback (g, list_devices_reply_cb, &ctx);
642   (void) ml->main_loop_run (ml, g);
643   guestfs_set_reply_callback (g, NULL, NULL);
644   if (ctx.cb_sequence != 1001) {
645     error (g, "%s reply failed, see earlier error messages", "guestfs_list_devices");
646     guestfs_set_ready (g);
647     return NULL;
648   }
649
650   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LIST_DEVICES, serial) == -1) {
651     guestfs_set_ready (g);
652     return NULL;
653   }
654
655   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
656     error (g, "%s", ctx.err.error_message);
657     guestfs_set_ready (g);
658     return NULL;
659   }
660
661   guestfs_set_ready (g);
662   /* caller will free this, but we need to add a NULL entry */
663   ctx.ret.devices.devices_val =
664     safe_realloc (g, ctx.ret.devices.devices_val,
665                   sizeof (char *) * (ctx.ret.devices.devices_len + 1));
666   ctx.ret.devices.devices_val[ctx.ret.devices.devices_len] = NULL;
667   return ctx.ret.devices.devices_val;
668 }
669
670 struct list_partitions_ctx {
671   /* This flag is set by the callbacks, so we know we've done
672    * the callbacks as expected, and in the right sequence.
673    * 0 = not called, 1 = send called,
674    * 1001 = reply called.
675    */
676   int cb_sequence;
677   struct guestfs_message_header hdr;
678   struct guestfs_message_error err;
679   struct guestfs_list_partitions_ret ret;
680 };
681
682 static void list_partitions_reply_cb (guestfs_h *g, void *data, XDR *xdr)
683 {
684   guestfs_main_loop *ml = guestfs_get_main_loop (g);
685   struct list_partitions_ctx *ctx = (struct list_partitions_ctx *) data;
686
687   ml->main_loop_quit (ml, g);
688
689   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
690     error (g, "%s: failed to parse reply header", "guestfs_list_partitions");
691     return;
692   }
693   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
694     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
695       error (g, "%s: failed to parse reply error", "guestfs_list_partitions");
696       return;
697     }
698     goto done;
699   }
700   if (!xdr_guestfs_list_partitions_ret (xdr, &ctx->ret)) {
701     error (g, "%s: failed to parse reply", "guestfs_list_partitions");
702     return;
703   }
704  done:
705   ctx->cb_sequence = 1001;
706 }
707
708 char **guestfs_list_partitions (guestfs_h *g)
709 {
710   struct list_partitions_ctx ctx;
711   guestfs_main_loop *ml = guestfs_get_main_loop (g);
712   int serial;
713
714   if (check_state (g, "guestfs_list_partitions") == -1) return NULL;
715   guestfs_set_busy (g);
716
717   memset (&ctx, 0, sizeof ctx);
718
719   serial = guestfs__send_sync (g, GUESTFS_PROC_LIST_PARTITIONS, NULL, NULL);
720   if (serial == -1) {
721     guestfs_set_ready (g);
722     return NULL;
723   }
724
725   guestfs__switch_to_receiving (g);
726   ctx.cb_sequence = 0;
727   guestfs_set_reply_callback (g, list_partitions_reply_cb, &ctx);
728   (void) ml->main_loop_run (ml, g);
729   guestfs_set_reply_callback (g, NULL, NULL);
730   if (ctx.cb_sequence != 1001) {
731     error (g, "%s reply failed, see earlier error messages", "guestfs_list_partitions");
732     guestfs_set_ready (g);
733     return NULL;
734   }
735
736   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LIST_PARTITIONS, serial) == -1) {
737     guestfs_set_ready (g);
738     return NULL;
739   }
740
741   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
742     error (g, "%s", ctx.err.error_message);
743     guestfs_set_ready (g);
744     return NULL;
745   }
746
747   guestfs_set_ready (g);
748   /* caller will free this, but we need to add a NULL entry */
749   ctx.ret.partitions.partitions_val =
750     safe_realloc (g, ctx.ret.partitions.partitions_val,
751                   sizeof (char *) * (ctx.ret.partitions.partitions_len + 1));
752   ctx.ret.partitions.partitions_val[ctx.ret.partitions.partitions_len] = NULL;
753   return ctx.ret.partitions.partitions_val;
754 }
755
756 struct pvs_ctx {
757   /* This flag is set by the callbacks, so we know we've done
758    * the callbacks as expected, and in the right sequence.
759    * 0 = not called, 1 = send called,
760    * 1001 = reply called.
761    */
762   int cb_sequence;
763   struct guestfs_message_header hdr;
764   struct guestfs_message_error err;
765   struct guestfs_pvs_ret ret;
766 };
767
768 static void pvs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
769 {
770   guestfs_main_loop *ml = guestfs_get_main_loop (g);
771   struct pvs_ctx *ctx = (struct pvs_ctx *) data;
772
773   ml->main_loop_quit (ml, g);
774
775   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
776     error (g, "%s: failed to parse reply header", "guestfs_pvs");
777     return;
778   }
779   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
780     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
781       error (g, "%s: failed to parse reply error", "guestfs_pvs");
782       return;
783     }
784     goto done;
785   }
786   if (!xdr_guestfs_pvs_ret (xdr, &ctx->ret)) {
787     error (g, "%s: failed to parse reply", "guestfs_pvs");
788     return;
789   }
790  done:
791   ctx->cb_sequence = 1001;
792 }
793
794 char **guestfs_pvs (guestfs_h *g)
795 {
796   struct pvs_ctx ctx;
797   guestfs_main_loop *ml = guestfs_get_main_loop (g);
798   int serial;
799
800   if (check_state (g, "guestfs_pvs") == -1) return NULL;
801   guestfs_set_busy (g);
802
803   memset (&ctx, 0, sizeof ctx);
804
805   serial = guestfs__send_sync (g, GUESTFS_PROC_PVS, NULL, NULL);
806   if (serial == -1) {
807     guestfs_set_ready (g);
808     return NULL;
809   }
810
811   guestfs__switch_to_receiving (g);
812   ctx.cb_sequence = 0;
813   guestfs_set_reply_callback (g, pvs_reply_cb, &ctx);
814   (void) ml->main_loop_run (ml, g);
815   guestfs_set_reply_callback (g, NULL, NULL);
816   if (ctx.cb_sequence != 1001) {
817     error (g, "%s reply failed, see earlier error messages", "guestfs_pvs");
818     guestfs_set_ready (g);
819     return NULL;
820   }
821
822   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVS, serial) == -1) {
823     guestfs_set_ready (g);
824     return NULL;
825   }
826
827   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
828     error (g, "%s", ctx.err.error_message);
829     guestfs_set_ready (g);
830     return NULL;
831   }
832
833   guestfs_set_ready (g);
834   /* caller will free this, but we need to add a NULL entry */
835   ctx.ret.physvols.physvols_val =
836     safe_realloc (g, ctx.ret.physvols.physvols_val,
837                   sizeof (char *) * (ctx.ret.physvols.physvols_len + 1));
838   ctx.ret.physvols.physvols_val[ctx.ret.physvols.physvols_len] = NULL;
839   return ctx.ret.physvols.physvols_val;
840 }
841
842 struct vgs_ctx {
843   /* This flag is set by the callbacks, so we know we've done
844    * the callbacks as expected, and in the right sequence.
845    * 0 = not called, 1 = send called,
846    * 1001 = reply called.
847    */
848   int cb_sequence;
849   struct guestfs_message_header hdr;
850   struct guestfs_message_error err;
851   struct guestfs_vgs_ret ret;
852 };
853
854 static void vgs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
855 {
856   guestfs_main_loop *ml = guestfs_get_main_loop (g);
857   struct vgs_ctx *ctx = (struct vgs_ctx *) data;
858
859   ml->main_loop_quit (ml, g);
860
861   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
862     error (g, "%s: failed to parse reply header", "guestfs_vgs");
863     return;
864   }
865   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
866     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
867       error (g, "%s: failed to parse reply error", "guestfs_vgs");
868       return;
869     }
870     goto done;
871   }
872   if (!xdr_guestfs_vgs_ret (xdr, &ctx->ret)) {
873     error (g, "%s: failed to parse reply", "guestfs_vgs");
874     return;
875   }
876  done:
877   ctx->cb_sequence = 1001;
878 }
879
880 char **guestfs_vgs (guestfs_h *g)
881 {
882   struct vgs_ctx ctx;
883   guestfs_main_loop *ml = guestfs_get_main_loop (g);
884   int serial;
885
886   if (check_state (g, "guestfs_vgs") == -1) return NULL;
887   guestfs_set_busy (g);
888
889   memset (&ctx, 0, sizeof ctx);
890
891   serial = guestfs__send_sync (g, GUESTFS_PROC_VGS, NULL, NULL);
892   if (serial == -1) {
893     guestfs_set_ready (g);
894     return NULL;
895   }
896
897   guestfs__switch_to_receiving (g);
898   ctx.cb_sequence = 0;
899   guestfs_set_reply_callback (g, vgs_reply_cb, &ctx);
900   (void) ml->main_loop_run (ml, g);
901   guestfs_set_reply_callback (g, NULL, NULL);
902   if (ctx.cb_sequence != 1001) {
903     error (g, "%s reply failed, see earlier error messages", "guestfs_vgs");
904     guestfs_set_ready (g);
905     return NULL;
906   }
907
908   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGS, serial) == -1) {
909     guestfs_set_ready (g);
910     return NULL;
911   }
912
913   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
914     error (g, "%s", ctx.err.error_message);
915     guestfs_set_ready (g);
916     return NULL;
917   }
918
919   guestfs_set_ready (g);
920   /* caller will free this, but we need to add a NULL entry */
921   ctx.ret.volgroups.volgroups_val =
922     safe_realloc (g, ctx.ret.volgroups.volgroups_val,
923                   sizeof (char *) * (ctx.ret.volgroups.volgroups_len + 1));
924   ctx.ret.volgroups.volgroups_val[ctx.ret.volgroups.volgroups_len] = NULL;
925   return ctx.ret.volgroups.volgroups_val;
926 }
927
928 struct lvs_ctx {
929   /* This flag is set by the callbacks, so we know we've done
930    * the callbacks as expected, and in the right sequence.
931    * 0 = not called, 1 = send called,
932    * 1001 = reply called.
933    */
934   int cb_sequence;
935   struct guestfs_message_header hdr;
936   struct guestfs_message_error err;
937   struct guestfs_lvs_ret ret;
938 };
939
940 static void lvs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
941 {
942   guestfs_main_loop *ml = guestfs_get_main_loop (g);
943   struct lvs_ctx *ctx = (struct lvs_ctx *) data;
944
945   ml->main_loop_quit (ml, g);
946
947   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
948     error (g, "%s: failed to parse reply header", "guestfs_lvs");
949     return;
950   }
951   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
952     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
953       error (g, "%s: failed to parse reply error", "guestfs_lvs");
954       return;
955     }
956     goto done;
957   }
958   if (!xdr_guestfs_lvs_ret (xdr, &ctx->ret)) {
959     error (g, "%s: failed to parse reply", "guestfs_lvs");
960     return;
961   }
962  done:
963   ctx->cb_sequence = 1001;
964 }
965
966 char **guestfs_lvs (guestfs_h *g)
967 {
968   struct lvs_ctx ctx;
969   guestfs_main_loop *ml = guestfs_get_main_loop (g);
970   int serial;
971
972   if (check_state (g, "guestfs_lvs") == -1) return NULL;
973   guestfs_set_busy (g);
974
975   memset (&ctx, 0, sizeof ctx);
976
977   serial = guestfs__send_sync (g, GUESTFS_PROC_LVS, NULL, NULL);
978   if (serial == -1) {
979     guestfs_set_ready (g);
980     return NULL;
981   }
982
983   guestfs__switch_to_receiving (g);
984   ctx.cb_sequence = 0;
985   guestfs_set_reply_callback (g, lvs_reply_cb, &ctx);
986   (void) ml->main_loop_run (ml, g);
987   guestfs_set_reply_callback (g, NULL, NULL);
988   if (ctx.cb_sequence != 1001) {
989     error (g, "%s reply failed, see earlier error messages", "guestfs_lvs");
990     guestfs_set_ready (g);
991     return NULL;
992   }
993
994   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVS, serial) == -1) {
995     guestfs_set_ready (g);
996     return NULL;
997   }
998
999   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1000     error (g, "%s", ctx.err.error_message);
1001     guestfs_set_ready (g);
1002     return NULL;
1003   }
1004
1005   guestfs_set_ready (g);
1006   /* caller will free this, but we need to add a NULL entry */
1007   ctx.ret.logvols.logvols_val =
1008     safe_realloc (g, ctx.ret.logvols.logvols_val,
1009                   sizeof (char *) * (ctx.ret.logvols.logvols_len + 1));
1010   ctx.ret.logvols.logvols_val[ctx.ret.logvols.logvols_len] = NULL;
1011   return ctx.ret.logvols.logvols_val;
1012 }
1013
1014 struct pvs_full_ctx {
1015   /* This flag is set by the callbacks, so we know we've done
1016    * the callbacks as expected, and in the right sequence.
1017    * 0 = not called, 1 = send called,
1018    * 1001 = reply called.
1019    */
1020   int cb_sequence;
1021   struct guestfs_message_header hdr;
1022   struct guestfs_message_error err;
1023   struct guestfs_pvs_full_ret ret;
1024 };
1025
1026 static void pvs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1027 {
1028   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1029   struct pvs_full_ctx *ctx = (struct pvs_full_ctx *) data;
1030
1031   ml->main_loop_quit (ml, g);
1032
1033   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1034     error (g, "%s: failed to parse reply header", "guestfs_pvs_full");
1035     return;
1036   }
1037   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1038     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1039       error (g, "%s: failed to parse reply error", "guestfs_pvs_full");
1040       return;
1041     }
1042     goto done;
1043   }
1044   if (!xdr_guestfs_pvs_full_ret (xdr, &ctx->ret)) {
1045     error (g, "%s: failed to parse reply", "guestfs_pvs_full");
1046     return;
1047   }
1048  done:
1049   ctx->cb_sequence = 1001;
1050 }
1051
1052 struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *g)
1053 {
1054   struct pvs_full_ctx ctx;
1055   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1056   int serial;
1057
1058   if (check_state (g, "guestfs_pvs_full") == -1) return NULL;
1059   guestfs_set_busy (g);
1060
1061   memset (&ctx, 0, sizeof ctx);
1062
1063   serial = guestfs__send_sync (g, GUESTFS_PROC_PVS_FULL, NULL, NULL);
1064   if (serial == -1) {
1065     guestfs_set_ready (g);
1066     return NULL;
1067   }
1068
1069   guestfs__switch_to_receiving (g);
1070   ctx.cb_sequence = 0;
1071   guestfs_set_reply_callback (g, pvs_full_reply_cb, &ctx);
1072   (void) ml->main_loop_run (ml, g);
1073   guestfs_set_reply_callback (g, NULL, NULL);
1074   if (ctx.cb_sequence != 1001) {
1075     error (g, "%s reply failed, see earlier error messages", "guestfs_pvs_full");
1076     guestfs_set_ready (g);
1077     return NULL;
1078   }
1079
1080   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVS_FULL, serial) == -1) {
1081     guestfs_set_ready (g);
1082     return NULL;
1083   }
1084
1085   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1086     error (g, "%s", ctx.err.error_message);
1087     guestfs_set_ready (g);
1088     return NULL;
1089   }
1090
1091   guestfs_set_ready (g);
1092   /* caller will free this */
1093   return safe_memdup (g, &ctx.ret.physvols, sizeof (ctx.ret.physvols));
1094 }
1095
1096 struct vgs_full_ctx {
1097   /* This flag is set by the callbacks, so we know we've done
1098    * the callbacks as expected, and in the right sequence.
1099    * 0 = not called, 1 = send called,
1100    * 1001 = reply called.
1101    */
1102   int cb_sequence;
1103   struct guestfs_message_header hdr;
1104   struct guestfs_message_error err;
1105   struct guestfs_vgs_full_ret ret;
1106 };
1107
1108 static void vgs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1109 {
1110   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1111   struct vgs_full_ctx *ctx = (struct vgs_full_ctx *) data;
1112
1113   ml->main_loop_quit (ml, g);
1114
1115   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1116     error (g, "%s: failed to parse reply header", "guestfs_vgs_full");
1117     return;
1118   }
1119   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1120     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1121       error (g, "%s: failed to parse reply error", "guestfs_vgs_full");
1122       return;
1123     }
1124     goto done;
1125   }
1126   if (!xdr_guestfs_vgs_full_ret (xdr, &ctx->ret)) {
1127     error (g, "%s: failed to parse reply", "guestfs_vgs_full");
1128     return;
1129   }
1130  done:
1131   ctx->cb_sequence = 1001;
1132 }
1133
1134 struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *g)
1135 {
1136   struct vgs_full_ctx ctx;
1137   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1138   int serial;
1139
1140   if (check_state (g, "guestfs_vgs_full") == -1) return NULL;
1141   guestfs_set_busy (g);
1142
1143   memset (&ctx, 0, sizeof ctx);
1144
1145   serial = guestfs__send_sync (g, GUESTFS_PROC_VGS_FULL, NULL, NULL);
1146   if (serial == -1) {
1147     guestfs_set_ready (g);
1148     return NULL;
1149   }
1150
1151   guestfs__switch_to_receiving (g);
1152   ctx.cb_sequence = 0;
1153   guestfs_set_reply_callback (g, vgs_full_reply_cb, &ctx);
1154   (void) ml->main_loop_run (ml, g);
1155   guestfs_set_reply_callback (g, NULL, NULL);
1156   if (ctx.cb_sequence != 1001) {
1157     error (g, "%s reply failed, see earlier error messages", "guestfs_vgs_full");
1158     guestfs_set_ready (g);
1159     return NULL;
1160   }
1161
1162   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGS_FULL, serial) == -1) {
1163     guestfs_set_ready (g);
1164     return NULL;
1165   }
1166
1167   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1168     error (g, "%s", ctx.err.error_message);
1169     guestfs_set_ready (g);
1170     return NULL;
1171   }
1172
1173   guestfs_set_ready (g);
1174   /* caller will free this */
1175   return safe_memdup (g, &ctx.ret.volgroups, sizeof (ctx.ret.volgroups));
1176 }
1177
1178 struct lvs_full_ctx {
1179   /* This flag is set by the callbacks, so we know we've done
1180    * the callbacks as expected, and in the right sequence.
1181    * 0 = not called, 1 = send called,
1182    * 1001 = reply called.
1183    */
1184   int cb_sequence;
1185   struct guestfs_message_header hdr;
1186   struct guestfs_message_error err;
1187   struct guestfs_lvs_full_ret ret;
1188 };
1189
1190 static void lvs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1191 {
1192   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1193   struct lvs_full_ctx *ctx = (struct lvs_full_ctx *) data;
1194
1195   ml->main_loop_quit (ml, g);
1196
1197   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1198     error (g, "%s: failed to parse reply header", "guestfs_lvs_full");
1199     return;
1200   }
1201   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1202     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1203       error (g, "%s: failed to parse reply error", "guestfs_lvs_full");
1204       return;
1205     }
1206     goto done;
1207   }
1208   if (!xdr_guestfs_lvs_full_ret (xdr, &ctx->ret)) {
1209     error (g, "%s: failed to parse reply", "guestfs_lvs_full");
1210     return;
1211   }
1212  done:
1213   ctx->cb_sequence = 1001;
1214 }
1215
1216 struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *g)
1217 {
1218   struct lvs_full_ctx ctx;
1219   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1220   int serial;
1221
1222   if (check_state (g, "guestfs_lvs_full") == -1) return NULL;
1223   guestfs_set_busy (g);
1224
1225   memset (&ctx, 0, sizeof ctx);
1226
1227   serial = guestfs__send_sync (g, GUESTFS_PROC_LVS_FULL, NULL, NULL);
1228   if (serial == -1) {
1229     guestfs_set_ready (g);
1230     return NULL;
1231   }
1232
1233   guestfs__switch_to_receiving (g);
1234   ctx.cb_sequence = 0;
1235   guestfs_set_reply_callback (g, lvs_full_reply_cb, &ctx);
1236   (void) ml->main_loop_run (ml, g);
1237   guestfs_set_reply_callback (g, NULL, NULL);
1238   if (ctx.cb_sequence != 1001) {
1239     error (g, "%s reply failed, see earlier error messages", "guestfs_lvs_full");
1240     guestfs_set_ready (g);
1241     return NULL;
1242   }
1243
1244   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVS_FULL, serial) == -1) {
1245     guestfs_set_ready (g);
1246     return NULL;
1247   }
1248
1249   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1250     error (g, "%s", ctx.err.error_message);
1251     guestfs_set_ready (g);
1252     return NULL;
1253   }
1254
1255   guestfs_set_ready (g);
1256   /* caller will free this */
1257   return safe_memdup (g, &ctx.ret.logvols, sizeof (ctx.ret.logvols));
1258 }
1259
1260 struct read_lines_ctx {
1261   /* This flag is set by the callbacks, so we know we've done
1262    * the callbacks as expected, and in the right sequence.
1263    * 0 = not called, 1 = send called,
1264    * 1001 = reply called.
1265    */
1266   int cb_sequence;
1267   struct guestfs_message_header hdr;
1268   struct guestfs_message_error err;
1269   struct guestfs_read_lines_ret ret;
1270 };
1271
1272 static void read_lines_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1273 {
1274   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1275   struct read_lines_ctx *ctx = (struct read_lines_ctx *) data;
1276
1277   ml->main_loop_quit (ml, g);
1278
1279   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1280     error (g, "%s: failed to parse reply header", "guestfs_read_lines");
1281     return;
1282   }
1283   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1284     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1285       error (g, "%s: failed to parse reply error", "guestfs_read_lines");
1286       return;
1287     }
1288     goto done;
1289   }
1290   if (!xdr_guestfs_read_lines_ret (xdr, &ctx->ret)) {
1291     error (g, "%s: failed to parse reply", "guestfs_read_lines");
1292     return;
1293   }
1294  done:
1295   ctx->cb_sequence = 1001;
1296 }
1297
1298 char **guestfs_read_lines (guestfs_h *g,
1299                 const char *path)
1300 {
1301   struct guestfs_read_lines_args args;
1302   struct read_lines_ctx ctx;
1303   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1304   int serial;
1305
1306   if (check_state (g, "guestfs_read_lines") == -1) return NULL;
1307   guestfs_set_busy (g);
1308
1309   memset (&ctx, 0, sizeof ctx);
1310
1311   args.path = (char *) path;
1312   serial = guestfs__send_sync (g, GUESTFS_PROC_READ_LINES,
1313         (xdrproc_t) xdr_guestfs_read_lines_args, (char *) &args);
1314   if (serial == -1) {
1315     guestfs_set_ready (g);
1316     return NULL;
1317   }
1318
1319   guestfs__switch_to_receiving (g);
1320   ctx.cb_sequence = 0;
1321   guestfs_set_reply_callback (g, read_lines_reply_cb, &ctx);
1322   (void) ml->main_loop_run (ml, g);
1323   guestfs_set_reply_callback (g, NULL, NULL);
1324   if (ctx.cb_sequence != 1001) {
1325     error (g, "%s reply failed, see earlier error messages", "guestfs_read_lines");
1326     guestfs_set_ready (g);
1327     return NULL;
1328   }
1329
1330   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_READ_LINES, serial) == -1) {
1331     guestfs_set_ready (g);
1332     return NULL;
1333   }
1334
1335   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1336     error (g, "%s", ctx.err.error_message);
1337     guestfs_set_ready (g);
1338     return NULL;
1339   }
1340
1341   guestfs_set_ready (g);
1342   /* caller will free this, but we need to add a NULL entry */
1343   ctx.ret.lines.lines_val =
1344     safe_realloc (g, ctx.ret.lines.lines_val,
1345                   sizeof (char *) * (ctx.ret.lines.lines_len + 1));
1346   ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
1347   return ctx.ret.lines.lines_val;
1348 }
1349
1350 struct aug_init_ctx {
1351   /* This flag is set by the callbacks, so we know we've done
1352    * the callbacks as expected, and in the right sequence.
1353    * 0 = not called, 1 = send called,
1354    * 1001 = reply called.
1355    */
1356   int cb_sequence;
1357   struct guestfs_message_header hdr;
1358   struct guestfs_message_error err;
1359 };
1360
1361 static void aug_init_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1362 {
1363   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1364   struct aug_init_ctx *ctx = (struct aug_init_ctx *) data;
1365
1366   ml->main_loop_quit (ml, g);
1367
1368   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1369     error (g, "%s: failed to parse reply header", "guestfs_aug_init");
1370     return;
1371   }
1372   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1373     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1374       error (g, "%s: failed to parse reply error", "guestfs_aug_init");
1375       return;
1376     }
1377     goto done;
1378   }
1379  done:
1380   ctx->cb_sequence = 1001;
1381 }
1382
1383 int guestfs_aug_init (guestfs_h *g,
1384                 const char *root,
1385                 int flags)
1386 {
1387   struct guestfs_aug_init_args args;
1388   struct aug_init_ctx ctx;
1389   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1390   int serial;
1391
1392   if (check_state (g, "guestfs_aug_init") == -1) return -1;
1393   guestfs_set_busy (g);
1394
1395   memset (&ctx, 0, sizeof ctx);
1396
1397   args.root = (char *) root;
1398   args.flags = flags;
1399   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_INIT,
1400         (xdrproc_t) xdr_guestfs_aug_init_args, (char *) &args);
1401   if (serial == -1) {
1402     guestfs_set_ready (g);
1403     return -1;
1404   }
1405
1406   guestfs__switch_to_receiving (g);
1407   ctx.cb_sequence = 0;
1408   guestfs_set_reply_callback (g, aug_init_reply_cb, &ctx);
1409   (void) ml->main_loop_run (ml, g);
1410   guestfs_set_reply_callback (g, NULL, NULL);
1411   if (ctx.cb_sequence != 1001) {
1412     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_init");
1413     guestfs_set_ready (g);
1414     return -1;
1415   }
1416
1417   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_INIT, serial) == -1) {
1418     guestfs_set_ready (g);
1419     return -1;
1420   }
1421
1422   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1423     error (g, "%s", ctx.err.error_message);
1424     guestfs_set_ready (g);
1425     return -1;
1426   }
1427
1428   guestfs_set_ready (g);
1429   return 0;
1430 }
1431
1432 struct aug_close_ctx {
1433   /* This flag is set by the callbacks, so we know we've done
1434    * the callbacks as expected, and in the right sequence.
1435    * 0 = not called, 1 = send called,
1436    * 1001 = reply called.
1437    */
1438   int cb_sequence;
1439   struct guestfs_message_header hdr;
1440   struct guestfs_message_error err;
1441 };
1442
1443 static void aug_close_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1444 {
1445   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1446   struct aug_close_ctx *ctx = (struct aug_close_ctx *) data;
1447
1448   ml->main_loop_quit (ml, g);
1449
1450   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1451     error (g, "%s: failed to parse reply header", "guestfs_aug_close");
1452     return;
1453   }
1454   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1455     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1456       error (g, "%s: failed to parse reply error", "guestfs_aug_close");
1457       return;
1458     }
1459     goto done;
1460   }
1461  done:
1462   ctx->cb_sequence = 1001;
1463 }
1464
1465 int guestfs_aug_close (guestfs_h *g)
1466 {
1467   struct aug_close_ctx ctx;
1468   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1469   int serial;
1470
1471   if (check_state (g, "guestfs_aug_close") == -1) return -1;
1472   guestfs_set_busy (g);
1473
1474   memset (&ctx, 0, sizeof ctx);
1475
1476   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_CLOSE, NULL, NULL);
1477   if (serial == -1) {
1478     guestfs_set_ready (g);
1479     return -1;
1480   }
1481
1482   guestfs__switch_to_receiving (g);
1483   ctx.cb_sequence = 0;
1484   guestfs_set_reply_callback (g, aug_close_reply_cb, &ctx);
1485   (void) ml->main_loop_run (ml, g);
1486   guestfs_set_reply_callback (g, NULL, NULL);
1487   if (ctx.cb_sequence != 1001) {
1488     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_close");
1489     guestfs_set_ready (g);
1490     return -1;
1491   }
1492
1493   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_CLOSE, serial) == -1) {
1494     guestfs_set_ready (g);
1495     return -1;
1496   }
1497
1498   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1499     error (g, "%s", ctx.err.error_message);
1500     guestfs_set_ready (g);
1501     return -1;
1502   }
1503
1504   guestfs_set_ready (g);
1505   return 0;
1506 }
1507
1508 struct aug_defvar_ctx {
1509   /* This flag is set by the callbacks, so we know we've done
1510    * the callbacks as expected, and in the right sequence.
1511    * 0 = not called, 1 = send called,
1512    * 1001 = reply called.
1513    */
1514   int cb_sequence;
1515   struct guestfs_message_header hdr;
1516   struct guestfs_message_error err;
1517   struct guestfs_aug_defvar_ret ret;
1518 };
1519
1520 static void aug_defvar_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1521 {
1522   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1523   struct aug_defvar_ctx *ctx = (struct aug_defvar_ctx *) data;
1524
1525   ml->main_loop_quit (ml, g);
1526
1527   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1528     error (g, "%s: failed to parse reply header", "guestfs_aug_defvar");
1529     return;
1530   }
1531   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1532     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1533       error (g, "%s: failed to parse reply error", "guestfs_aug_defvar");
1534       return;
1535     }
1536     goto done;
1537   }
1538   if (!xdr_guestfs_aug_defvar_ret (xdr, &ctx->ret)) {
1539     error (g, "%s: failed to parse reply", "guestfs_aug_defvar");
1540     return;
1541   }
1542  done:
1543   ctx->cb_sequence = 1001;
1544 }
1545
1546 int guestfs_aug_defvar (guestfs_h *g,
1547                 const char *name,
1548                 const char *expr)
1549 {
1550   struct guestfs_aug_defvar_args args;
1551   struct aug_defvar_ctx ctx;
1552   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1553   int serial;
1554
1555   if (check_state (g, "guestfs_aug_defvar") == -1) return -1;
1556   guestfs_set_busy (g);
1557
1558   memset (&ctx, 0, sizeof ctx);
1559
1560   args.name = (char *) name;
1561   args.expr = expr ? (char **) &expr : NULL;
1562   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_DEFVAR,
1563         (xdrproc_t) xdr_guestfs_aug_defvar_args, (char *) &args);
1564   if (serial == -1) {
1565     guestfs_set_ready (g);
1566     return -1;
1567   }
1568
1569   guestfs__switch_to_receiving (g);
1570   ctx.cb_sequence = 0;
1571   guestfs_set_reply_callback (g, aug_defvar_reply_cb, &ctx);
1572   (void) ml->main_loop_run (ml, g);
1573   guestfs_set_reply_callback (g, NULL, NULL);
1574   if (ctx.cb_sequence != 1001) {
1575     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_defvar");
1576     guestfs_set_ready (g);
1577     return -1;
1578   }
1579
1580   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_DEFVAR, serial) == -1) {
1581     guestfs_set_ready (g);
1582     return -1;
1583   }
1584
1585   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1586     error (g, "%s", ctx.err.error_message);
1587     guestfs_set_ready (g);
1588     return -1;
1589   }
1590
1591   guestfs_set_ready (g);
1592   return ctx.ret.nrnodes;
1593 }
1594
1595 struct aug_defnode_ctx {
1596   /* This flag is set by the callbacks, so we know we've done
1597    * the callbacks as expected, and in the right sequence.
1598    * 0 = not called, 1 = send called,
1599    * 1001 = reply called.
1600    */
1601   int cb_sequence;
1602   struct guestfs_message_header hdr;
1603   struct guestfs_message_error err;
1604   struct guestfs_aug_defnode_ret ret;
1605 };
1606
1607 static void aug_defnode_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1608 {
1609   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1610   struct aug_defnode_ctx *ctx = (struct aug_defnode_ctx *) data;
1611
1612   ml->main_loop_quit (ml, g);
1613
1614   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1615     error (g, "%s: failed to parse reply header", "guestfs_aug_defnode");
1616     return;
1617   }
1618   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1619     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1620       error (g, "%s: failed to parse reply error", "guestfs_aug_defnode");
1621       return;
1622     }
1623     goto done;
1624   }
1625   if (!xdr_guestfs_aug_defnode_ret (xdr, &ctx->ret)) {
1626     error (g, "%s: failed to parse reply", "guestfs_aug_defnode");
1627     return;
1628   }
1629  done:
1630   ctx->cb_sequence = 1001;
1631 }
1632
1633 struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g,
1634                 const char *name,
1635                 const char *expr,
1636                 const char *val)
1637 {
1638   struct guestfs_aug_defnode_args args;
1639   struct aug_defnode_ctx ctx;
1640   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1641   int serial;
1642
1643   if (check_state (g, "guestfs_aug_defnode") == -1) return NULL;
1644   guestfs_set_busy (g);
1645
1646   memset (&ctx, 0, sizeof ctx);
1647
1648   args.name = (char *) name;
1649   args.expr = (char *) expr;
1650   args.val = (char *) val;
1651   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_DEFNODE,
1652         (xdrproc_t) xdr_guestfs_aug_defnode_args, (char *) &args);
1653   if (serial == -1) {
1654     guestfs_set_ready (g);
1655     return NULL;
1656   }
1657
1658   guestfs__switch_to_receiving (g);
1659   ctx.cb_sequence = 0;
1660   guestfs_set_reply_callback (g, aug_defnode_reply_cb, &ctx);
1661   (void) ml->main_loop_run (ml, g);
1662   guestfs_set_reply_callback (g, NULL, NULL);
1663   if (ctx.cb_sequence != 1001) {
1664     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_defnode");
1665     guestfs_set_ready (g);
1666     return NULL;
1667   }
1668
1669   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_DEFNODE, serial) == -1) {
1670     guestfs_set_ready (g);
1671     return NULL;
1672   }
1673
1674   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1675     error (g, "%s", ctx.err.error_message);
1676     guestfs_set_ready (g);
1677     return NULL;
1678   }
1679
1680   guestfs_set_ready (g);
1681   /* caller with free this */
1682   return safe_memdup (g, &ctx.ret, sizeof (ctx.ret));
1683 }
1684
1685 struct aug_get_ctx {
1686   /* This flag is set by the callbacks, so we know we've done
1687    * the callbacks as expected, and in the right sequence.
1688    * 0 = not called, 1 = send called,
1689    * 1001 = reply called.
1690    */
1691   int cb_sequence;
1692   struct guestfs_message_header hdr;
1693   struct guestfs_message_error err;
1694   struct guestfs_aug_get_ret ret;
1695 };
1696
1697 static void aug_get_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1698 {
1699   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1700   struct aug_get_ctx *ctx = (struct aug_get_ctx *) data;
1701
1702   ml->main_loop_quit (ml, g);
1703
1704   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1705     error (g, "%s: failed to parse reply header", "guestfs_aug_get");
1706     return;
1707   }
1708   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1709     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1710       error (g, "%s: failed to parse reply error", "guestfs_aug_get");
1711       return;
1712     }
1713     goto done;
1714   }
1715   if (!xdr_guestfs_aug_get_ret (xdr, &ctx->ret)) {
1716     error (g, "%s: failed to parse reply", "guestfs_aug_get");
1717     return;
1718   }
1719  done:
1720   ctx->cb_sequence = 1001;
1721 }
1722
1723 char *guestfs_aug_get (guestfs_h *g,
1724                 const char *path)
1725 {
1726   struct guestfs_aug_get_args args;
1727   struct aug_get_ctx ctx;
1728   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1729   int serial;
1730
1731   if (check_state (g, "guestfs_aug_get") == -1) return NULL;
1732   guestfs_set_busy (g);
1733
1734   memset (&ctx, 0, sizeof ctx);
1735
1736   args.path = (char *) path;
1737   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_GET,
1738         (xdrproc_t) xdr_guestfs_aug_get_args, (char *) &args);
1739   if (serial == -1) {
1740     guestfs_set_ready (g);
1741     return NULL;
1742   }
1743
1744   guestfs__switch_to_receiving (g);
1745   ctx.cb_sequence = 0;
1746   guestfs_set_reply_callback (g, aug_get_reply_cb, &ctx);
1747   (void) ml->main_loop_run (ml, g);
1748   guestfs_set_reply_callback (g, NULL, NULL);
1749   if (ctx.cb_sequence != 1001) {
1750     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_get");
1751     guestfs_set_ready (g);
1752     return NULL;
1753   }
1754
1755   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_GET, serial) == -1) {
1756     guestfs_set_ready (g);
1757     return NULL;
1758   }
1759
1760   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1761     error (g, "%s", ctx.err.error_message);
1762     guestfs_set_ready (g);
1763     return NULL;
1764   }
1765
1766   guestfs_set_ready (g);
1767   return ctx.ret.val; /* caller will free */
1768 }
1769
1770 struct aug_set_ctx {
1771   /* This flag is set by the callbacks, so we know we've done
1772    * the callbacks as expected, and in the right sequence.
1773    * 0 = not called, 1 = send called,
1774    * 1001 = reply called.
1775    */
1776   int cb_sequence;
1777   struct guestfs_message_header hdr;
1778   struct guestfs_message_error err;
1779 };
1780
1781 static void aug_set_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1782 {
1783   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1784   struct aug_set_ctx *ctx = (struct aug_set_ctx *) data;
1785
1786   ml->main_loop_quit (ml, g);
1787
1788   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1789     error (g, "%s: failed to parse reply header", "guestfs_aug_set");
1790     return;
1791   }
1792   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1793     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1794       error (g, "%s: failed to parse reply error", "guestfs_aug_set");
1795       return;
1796     }
1797     goto done;
1798   }
1799  done:
1800   ctx->cb_sequence = 1001;
1801 }
1802
1803 int guestfs_aug_set (guestfs_h *g,
1804                 const char *path,
1805                 const char *val)
1806 {
1807   struct guestfs_aug_set_args args;
1808   struct aug_set_ctx ctx;
1809   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1810   int serial;
1811
1812   if (check_state (g, "guestfs_aug_set") == -1) return -1;
1813   guestfs_set_busy (g);
1814
1815   memset (&ctx, 0, sizeof ctx);
1816
1817   args.path = (char *) path;
1818   args.val = (char *) val;
1819   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_SET,
1820         (xdrproc_t) xdr_guestfs_aug_set_args, (char *) &args);
1821   if (serial == -1) {
1822     guestfs_set_ready (g);
1823     return -1;
1824   }
1825
1826   guestfs__switch_to_receiving (g);
1827   ctx.cb_sequence = 0;
1828   guestfs_set_reply_callback (g, aug_set_reply_cb, &ctx);
1829   (void) ml->main_loop_run (ml, g);
1830   guestfs_set_reply_callback (g, NULL, NULL);
1831   if (ctx.cb_sequence != 1001) {
1832     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_set");
1833     guestfs_set_ready (g);
1834     return -1;
1835   }
1836
1837   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_SET, serial) == -1) {
1838     guestfs_set_ready (g);
1839     return -1;
1840   }
1841
1842   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1843     error (g, "%s", ctx.err.error_message);
1844     guestfs_set_ready (g);
1845     return -1;
1846   }
1847
1848   guestfs_set_ready (g);
1849   return 0;
1850 }
1851
1852 struct aug_insert_ctx {
1853   /* This flag is set by the callbacks, so we know we've done
1854    * the callbacks as expected, and in the right sequence.
1855    * 0 = not called, 1 = send called,
1856    * 1001 = reply called.
1857    */
1858   int cb_sequence;
1859   struct guestfs_message_header hdr;
1860   struct guestfs_message_error err;
1861 };
1862
1863 static void aug_insert_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1864 {
1865   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1866   struct aug_insert_ctx *ctx = (struct aug_insert_ctx *) data;
1867
1868   ml->main_loop_quit (ml, g);
1869
1870   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1871     error (g, "%s: failed to parse reply header", "guestfs_aug_insert");
1872     return;
1873   }
1874   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1875     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1876       error (g, "%s: failed to parse reply error", "guestfs_aug_insert");
1877       return;
1878     }
1879     goto done;
1880   }
1881  done:
1882   ctx->cb_sequence = 1001;
1883 }
1884
1885 int guestfs_aug_insert (guestfs_h *g,
1886                 const char *path,
1887                 const char *label,
1888                 int before)
1889 {
1890   struct guestfs_aug_insert_args args;
1891   struct aug_insert_ctx ctx;
1892   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1893   int serial;
1894
1895   if (check_state (g, "guestfs_aug_insert") == -1) return -1;
1896   guestfs_set_busy (g);
1897
1898   memset (&ctx, 0, sizeof ctx);
1899
1900   args.path = (char *) path;
1901   args.label = (char *) label;
1902   args.before = before;
1903   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_INSERT,
1904         (xdrproc_t) xdr_guestfs_aug_insert_args, (char *) &args);
1905   if (serial == -1) {
1906     guestfs_set_ready (g);
1907     return -1;
1908   }
1909
1910   guestfs__switch_to_receiving (g);
1911   ctx.cb_sequence = 0;
1912   guestfs_set_reply_callback (g, aug_insert_reply_cb, &ctx);
1913   (void) ml->main_loop_run (ml, g);
1914   guestfs_set_reply_callback (g, NULL, NULL);
1915   if (ctx.cb_sequence != 1001) {
1916     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_insert");
1917     guestfs_set_ready (g);
1918     return -1;
1919   }
1920
1921   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_INSERT, serial) == -1) {
1922     guestfs_set_ready (g);
1923     return -1;
1924   }
1925
1926   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1927     error (g, "%s", ctx.err.error_message);
1928     guestfs_set_ready (g);
1929     return -1;
1930   }
1931
1932   guestfs_set_ready (g);
1933   return 0;
1934 }
1935
1936 struct aug_rm_ctx {
1937   /* This flag is set by the callbacks, so we know we've done
1938    * the callbacks as expected, and in the right sequence.
1939    * 0 = not called, 1 = send called,
1940    * 1001 = reply called.
1941    */
1942   int cb_sequence;
1943   struct guestfs_message_header hdr;
1944   struct guestfs_message_error err;
1945   struct guestfs_aug_rm_ret ret;
1946 };
1947
1948 static void aug_rm_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1949 {
1950   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1951   struct aug_rm_ctx *ctx = (struct aug_rm_ctx *) data;
1952
1953   ml->main_loop_quit (ml, g);
1954
1955   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1956     error (g, "%s: failed to parse reply header", "guestfs_aug_rm");
1957     return;
1958   }
1959   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1960     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1961       error (g, "%s: failed to parse reply error", "guestfs_aug_rm");
1962       return;
1963     }
1964     goto done;
1965   }
1966   if (!xdr_guestfs_aug_rm_ret (xdr, &ctx->ret)) {
1967     error (g, "%s: failed to parse reply", "guestfs_aug_rm");
1968     return;
1969   }
1970  done:
1971   ctx->cb_sequence = 1001;
1972 }
1973
1974 int guestfs_aug_rm (guestfs_h *g,
1975                 const char *path)
1976 {
1977   struct guestfs_aug_rm_args args;
1978   struct aug_rm_ctx ctx;
1979   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1980   int serial;
1981
1982   if (check_state (g, "guestfs_aug_rm") == -1) return -1;
1983   guestfs_set_busy (g);
1984
1985   memset (&ctx, 0, sizeof ctx);
1986
1987   args.path = (char *) path;
1988   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_RM,
1989         (xdrproc_t) xdr_guestfs_aug_rm_args, (char *) &args);
1990   if (serial == -1) {
1991     guestfs_set_ready (g);
1992     return -1;
1993   }
1994
1995   guestfs__switch_to_receiving (g);
1996   ctx.cb_sequence = 0;
1997   guestfs_set_reply_callback (g, aug_rm_reply_cb, &ctx);
1998   (void) ml->main_loop_run (ml, g);
1999   guestfs_set_reply_callback (g, NULL, NULL);
2000   if (ctx.cb_sequence != 1001) {
2001     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_rm");
2002     guestfs_set_ready (g);
2003     return -1;
2004   }
2005
2006   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_RM, serial) == -1) {
2007     guestfs_set_ready (g);
2008     return -1;
2009   }
2010
2011   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2012     error (g, "%s", ctx.err.error_message);
2013     guestfs_set_ready (g);
2014     return -1;
2015   }
2016
2017   guestfs_set_ready (g);
2018   return ctx.ret.nrnodes;
2019 }
2020
2021 struct aug_mv_ctx {
2022   /* This flag is set by the callbacks, so we know we've done
2023    * the callbacks as expected, and in the right sequence.
2024    * 0 = not called, 1 = send called,
2025    * 1001 = reply called.
2026    */
2027   int cb_sequence;
2028   struct guestfs_message_header hdr;
2029   struct guestfs_message_error err;
2030 };
2031
2032 static void aug_mv_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2033 {
2034   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2035   struct aug_mv_ctx *ctx = (struct aug_mv_ctx *) data;
2036
2037   ml->main_loop_quit (ml, g);
2038
2039   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2040     error (g, "%s: failed to parse reply header", "guestfs_aug_mv");
2041     return;
2042   }
2043   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2044     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2045       error (g, "%s: failed to parse reply error", "guestfs_aug_mv");
2046       return;
2047     }
2048     goto done;
2049   }
2050  done:
2051   ctx->cb_sequence = 1001;
2052 }
2053
2054 int guestfs_aug_mv (guestfs_h *g,
2055                 const char *src,
2056                 const char *dest)
2057 {
2058   struct guestfs_aug_mv_args args;
2059   struct aug_mv_ctx ctx;
2060   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2061   int serial;
2062
2063   if (check_state (g, "guestfs_aug_mv") == -1) return -1;
2064   guestfs_set_busy (g);
2065
2066   memset (&ctx, 0, sizeof ctx);
2067
2068   args.src = (char *) src;
2069   args.dest = (char *) dest;
2070   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_MV,
2071         (xdrproc_t) xdr_guestfs_aug_mv_args, (char *) &args);
2072   if (serial == -1) {
2073     guestfs_set_ready (g);
2074     return -1;
2075   }
2076
2077   guestfs__switch_to_receiving (g);
2078   ctx.cb_sequence = 0;
2079   guestfs_set_reply_callback (g, aug_mv_reply_cb, &ctx);
2080   (void) ml->main_loop_run (ml, g);
2081   guestfs_set_reply_callback (g, NULL, NULL);
2082   if (ctx.cb_sequence != 1001) {
2083     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_mv");
2084     guestfs_set_ready (g);
2085     return -1;
2086   }
2087
2088   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_MV, serial) == -1) {
2089     guestfs_set_ready (g);
2090     return -1;
2091   }
2092
2093   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2094     error (g, "%s", ctx.err.error_message);
2095     guestfs_set_ready (g);
2096     return -1;
2097   }
2098
2099   guestfs_set_ready (g);
2100   return 0;
2101 }
2102
2103 struct aug_match_ctx {
2104   /* This flag is set by the callbacks, so we know we've done
2105    * the callbacks as expected, and in the right sequence.
2106    * 0 = not called, 1 = send called,
2107    * 1001 = reply called.
2108    */
2109   int cb_sequence;
2110   struct guestfs_message_header hdr;
2111   struct guestfs_message_error err;
2112   struct guestfs_aug_match_ret ret;
2113 };
2114
2115 static void aug_match_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2116 {
2117   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2118   struct aug_match_ctx *ctx = (struct aug_match_ctx *) data;
2119
2120   ml->main_loop_quit (ml, g);
2121
2122   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2123     error (g, "%s: failed to parse reply header", "guestfs_aug_match");
2124     return;
2125   }
2126   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2127     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2128       error (g, "%s: failed to parse reply error", "guestfs_aug_match");
2129       return;
2130     }
2131     goto done;
2132   }
2133   if (!xdr_guestfs_aug_match_ret (xdr, &ctx->ret)) {
2134     error (g, "%s: failed to parse reply", "guestfs_aug_match");
2135     return;
2136   }
2137  done:
2138   ctx->cb_sequence = 1001;
2139 }
2140
2141 char **guestfs_aug_match (guestfs_h *g,
2142                 const char *path)
2143 {
2144   struct guestfs_aug_match_args args;
2145   struct aug_match_ctx ctx;
2146   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2147   int serial;
2148
2149   if (check_state (g, "guestfs_aug_match") == -1) return NULL;
2150   guestfs_set_busy (g);
2151
2152   memset (&ctx, 0, sizeof ctx);
2153
2154   args.path = (char *) path;
2155   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_MATCH,
2156         (xdrproc_t) xdr_guestfs_aug_match_args, (char *) &args);
2157   if (serial == -1) {
2158     guestfs_set_ready (g);
2159     return NULL;
2160   }
2161
2162   guestfs__switch_to_receiving (g);
2163   ctx.cb_sequence = 0;
2164   guestfs_set_reply_callback (g, aug_match_reply_cb, &ctx);
2165   (void) ml->main_loop_run (ml, g);
2166   guestfs_set_reply_callback (g, NULL, NULL);
2167   if (ctx.cb_sequence != 1001) {
2168     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_match");
2169     guestfs_set_ready (g);
2170     return NULL;
2171   }
2172
2173   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_MATCH, serial) == -1) {
2174     guestfs_set_ready (g);
2175     return NULL;
2176   }
2177
2178   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2179     error (g, "%s", ctx.err.error_message);
2180     guestfs_set_ready (g);
2181     return NULL;
2182   }
2183
2184   guestfs_set_ready (g);
2185   /* caller will free this, but we need to add a NULL entry */
2186   ctx.ret.matches.matches_val =
2187     safe_realloc (g, ctx.ret.matches.matches_val,
2188                   sizeof (char *) * (ctx.ret.matches.matches_len + 1));
2189   ctx.ret.matches.matches_val[ctx.ret.matches.matches_len] = NULL;
2190   return ctx.ret.matches.matches_val;
2191 }
2192
2193 struct aug_save_ctx {
2194   /* This flag is set by the callbacks, so we know we've done
2195    * the callbacks as expected, and in the right sequence.
2196    * 0 = not called, 1 = send called,
2197    * 1001 = reply called.
2198    */
2199   int cb_sequence;
2200   struct guestfs_message_header hdr;
2201   struct guestfs_message_error err;
2202 };
2203
2204 static void aug_save_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2205 {
2206   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2207   struct aug_save_ctx *ctx = (struct aug_save_ctx *) data;
2208
2209   ml->main_loop_quit (ml, g);
2210
2211   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2212     error (g, "%s: failed to parse reply header", "guestfs_aug_save");
2213     return;
2214   }
2215   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2216     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2217       error (g, "%s: failed to parse reply error", "guestfs_aug_save");
2218       return;
2219     }
2220     goto done;
2221   }
2222  done:
2223   ctx->cb_sequence = 1001;
2224 }
2225
2226 int guestfs_aug_save (guestfs_h *g)
2227 {
2228   struct aug_save_ctx ctx;
2229   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2230   int serial;
2231
2232   if (check_state (g, "guestfs_aug_save") == -1) return -1;
2233   guestfs_set_busy (g);
2234
2235   memset (&ctx, 0, sizeof ctx);
2236
2237   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_SAVE, NULL, NULL);
2238   if (serial == -1) {
2239     guestfs_set_ready (g);
2240     return -1;
2241   }
2242
2243   guestfs__switch_to_receiving (g);
2244   ctx.cb_sequence = 0;
2245   guestfs_set_reply_callback (g, aug_save_reply_cb, &ctx);
2246   (void) ml->main_loop_run (ml, g);
2247   guestfs_set_reply_callback (g, NULL, NULL);
2248   if (ctx.cb_sequence != 1001) {
2249     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_save");
2250     guestfs_set_ready (g);
2251     return -1;
2252   }
2253
2254   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_SAVE, serial) == -1) {
2255     guestfs_set_ready (g);
2256     return -1;
2257   }
2258
2259   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2260     error (g, "%s", ctx.err.error_message);
2261     guestfs_set_ready (g);
2262     return -1;
2263   }
2264
2265   guestfs_set_ready (g);
2266   return 0;
2267 }
2268
2269 struct aug_load_ctx {
2270   /* This flag is set by the callbacks, so we know we've done
2271    * the callbacks as expected, and in the right sequence.
2272    * 0 = not called, 1 = send called,
2273    * 1001 = reply called.
2274    */
2275   int cb_sequence;
2276   struct guestfs_message_header hdr;
2277   struct guestfs_message_error err;
2278 };
2279
2280 static void aug_load_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2281 {
2282   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2283   struct aug_load_ctx *ctx = (struct aug_load_ctx *) data;
2284
2285   ml->main_loop_quit (ml, g);
2286
2287   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2288     error (g, "%s: failed to parse reply header", "guestfs_aug_load");
2289     return;
2290   }
2291   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2292     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2293       error (g, "%s: failed to parse reply error", "guestfs_aug_load");
2294       return;
2295     }
2296     goto done;
2297   }
2298  done:
2299   ctx->cb_sequence = 1001;
2300 }
2301
2302 int guestfs_aug_load (guestfs_h *g)
2303 {
2304   struct aug_load_ctx ctx;
2305   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2306   int serial;
2307
2308   if (check_state (g, "guestfs_aug_load") == -1) return -1;
2309   guestfs_set_busy (g);
2310
2311   memset (&ctx, 0, sizeof ctx);
2312
2313   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_LOAD, NULL, NULL);
2314   if (serial == -1) {
2315     guestfs_set_ready (g);
2316     return -1;
2317   }
2318
2319   guestfs__switch_to_receiving (g);
2320   ctx.cb_sequence = 0;
2321   guestfs_set_reply_callback (g, aug_load_reply_cb, &ctx);
2322   (void) ml->main_loop_run (ml, g);
2323   guestfs_set_reply_callback (g, NULL, NULL);
2324   if (ctx.cb_sequence != 1001) {
2325     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_load");
2326     guestfs_set_ready (g);
2327     return -1;
2328   }
2329
2330   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_LOAD, serial) == -1) {
2331     guestfs_set_ready (g);
2332     return -1;
2333   }
2334
2335   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2336     error (g, "%s", ctx.err.error_message);
2337     guestfs_set_ready (g);
2338     return -1;
2339   }
2340
2341   guestfs_set_ready (g);
2342   return 0;
2343 }
2344
2345 struct aug_ls_ctx {
2346   /* This flag is set by the callbacks, so we know we've done
2347    * the callbacks as expected, and in the right sequence.
2348    * 0 = not called, 1 = send called,
2349    * 1001 = reply called.
2350    */
2351   int cb_sequence;
2352   struct guestfs_message_header hdr;
2353   struct guestfs_message_error err;
2354   struct guestfs_aug_ls_ret ret;
2355 };
2356
2357 static void aug_ls_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2358 {
2359   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2360   struct aug_ls_ctx *ctx = (struct aug_ls_ctx *) data;
2361
2362   ml->main_loop_quit (ml, g);
2363
2364   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2365     error (g, "%s: failed to parse reply header", "guestfs_aug_ls");
2366     return;
2367   }
2368   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2369     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2370       error (g, "%s: failed to parse reply error", "guestfs_aug_ls");
2371       return;
2372     }
2373     goto done;
2374   }
2375   if (!xdr_guestfs_aug_ls_ret (xdr, &ctx->ret)) {
2376     error (g, "%s: failed to parse reply", "guestfs_aug_ls");
2377     return;
2378   }
2379  done:
2380   ctx->cb_sequence = 1001;
2381 }
2382
2383 char **guestfs_aug_ls (guestfs_h *g,
2384                 const char *path)
2385 {
2386   struct guestfs_aug_ls_args args;
2387   struct aug_ls_ctx ctx;
2388   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2389   int serial;
2390
2391   if (check_state (g, "guestfs_aug_ls") == -1) return NULL;
2392   guestfs_set_busy (g);
2393
2394   memset (&ctx, 0, sizeof ctx);
2395
2396   args.path = (char *) path;
2397   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_LS,
2398         (xdrproc_t) xdr_guestfs_aug_ls_args, (char *) &args);
2399   if (serial == -1) {
2400     guestfs_set_ready (g);
2401     return NULL;
2402   }
2403
2404   guestfs__switch_to_receiving (g);
2405   ctx.cb_sequence = 0;
2406   guestfs_set_reply_callback (g, aug_ls_reply_cb, &ctx);
2407   (void) ml->main_loop_run (ml, g);
2408   guestfs_set_reply_callback (g, NULL, NULL);
2409   if (ctx.cb_sequence != 1001) {
2410     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_ls");
2411     guestfs_set_ready (g);
2412     return NULL;
2413   }
2414
2415   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_LS, serial) == -1) {
2416     guestfs_set_ready (g);
2417     return NULL;
2418   }
2419
2420   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2421     error (g, "%s", ctx.err.error_message);
2422     guestfs_set_ready (g);
2423     return NULL;
2424   }
2425
2426   guestfs_set_ready (g);
2427   /* caller will free this, but we need to add a NULL entry */
2428   ctx.ret.matches.matches_val =
2429     safe_realloc (g, ctx.ret.matches.matches_val,
2430                   sizeof (char *) * (ctx.ret.matches.matches_len + 1));
2431   ctx.ret.matches.matches_val[ctx.ret.matches.matches_len] = NULL;
2432   return ctx.ret.matches.matches_val;
2433 }
2434
2435 struct rm_ctx {
2436   /* This flag is set by the callbacks, so we know we've done
2437    * the callbacks as expected, and in the right sequence.
2438    * 0 = not called, 1 = send called,
2439    * 1001 = reply called.
2440    */
2441   int cb_sequence;
2442   struct guestfs_message_header hdr;
2443   struct guestfs_message_error err;
2444 };
2445
2446 static void rm_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2447 {
2448   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2449   struct rm_ctx *ctx = (struct rm_ctx *) data;
2450
2451   ml->main_loop_quit (ml, g);
2452
2453   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2454     error (g, "%s: failed to parse reply header", "guestfs_rm");
2455     return;
2456   }
2457   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2458     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2459       error (g, "%s: failed to parse reply error", "guestfs_rm");
2460       return;
2461     }
2462     goto done;
2463   }
2464  done:
2465   ctx->cb_sequence = 1001;
2466 }
2467
2468 int guestfs_rm (guestfs_h *g,
2469                 const char *path)
2470 {
2471   struct guestfs_rm_args args;
2472   struct rm_ctx ctx;
2473   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2474   int serial;
2475
2476   if (check_state (g, "guestfs_rm") == -1) return -1;
2477   guestfs_set_busy (g);
2478
2479   memset (&ctx, 0, sizeof ctx);
2480
2481   args.path = (char *) path;
2482   serial = guestfs__send_sync (g, GUESTFS_PROC_RM,
2483         (xdrproc_t) xdr_guestfs_rm_args, (char *) &args);
2484   if (serial == -1) {
2485     guestfs_set_ready (g);
2486     return -1;
2487   }
2488
2489   guestfs__switch_to_receiving (g);
2490   ctx.cb_sequence = 0;
2491   guestfs_set_reply_callback (g, rm_reply_cb, &ctx);
2492   (void) ml->main_loop_run (ml, g);
2493   guestfs_set_reply_callback (g, NULL, NULL);
2494   if (ctx.cb_sequence != 1001) {
2495     error (g, "%s reply failed, see earlier error messages", "guestfs_rm");
2496     guestfs_set_ready (g);
2497     return -1;
2498   }
2499
2500   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RM, serial) == -1) {
2501     guestfs_set_ready (g);
2502     return -1;
2503   }
2504
2505   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2506     error (g, "%s", ctx.err.error_message);
2507     guestfs_set_ready (g);
2508     return -1;
2509   }
2510
2511   guestfs_set_ready (g);
2512   return 0;
2513 }
2514
2515 struct rmdir_ctx {
2516   /* This flag is set by the callbacks, so we know we've done
2517    * the callbacks as expected, and in the right sequence.
2518    * 0 = not called, 1 = send called,
2519    * 1001 = reply called.
2520    */
2521   int cb_sequence;
2522   struct guestfs_message_header hdr;
2523   struct guestfs_message_error err;
2524 };
2525
2526 static void rmdir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2527 {
2528   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2529   struct rmdir_ctx *ctx = (struct rmdir_ctx *) data;
2530
2531   ml->main_loop_quit (ml, g);
2532
2533   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2534     error (g, "%s: failed to parse reply header", "guestfs_rmdir");
2535     return;
2536   }
2537   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2538     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2539       error (g, "%s: failed to parse reply error", "guestfs_rmdir");
2540       return;
2541     }
2542     goto done;
2543   }
2544  done:
2545   ctx->cb_sequence = 1001;
2546 }
2547
2548 int guestfs_rmdir (guestfs_h *g,
2549                 const char *path)
2550 {
2551   struct guestfs_rmdir_args args;
2552   struct rmdir_ctx ctx;
2553   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2554   int serial;
2555
2556   if (check_state (g, "guestfs_rmdir") == -1) return -1;
2557   guestfs_set_busy (g);
2558
2559   memset (&ctx, 0, sizeof ctx);
2560
2561   args.path = (char *) path;
2562   serial = guestfs__send_sync (g, GUESTFS_PROC_RMDIR,
2563         (xdrproc_t) xdr_guestfs_rmdir_args, (char *) &args);
2564   if (serial == -1) {
2565     guestfs_set_ready (g);
2566     return -1;
2567   }
2568
2569   guestfs__switch_to_receiving (g);
2570   ctx.cb_sequence = 0;
2571   guestfs_set_reply_callback (g, rmdir_reply_cb, &ctx);
2572   (void) ml->main_loop_run (ml, g);
2573   guestfs_set_reply_callback (g, NULL, NULL);
2574   if (ctx.cb_sequence != 1001) {
2575     error (g, "%s reply failed, see earlier error messages", "guestfs_rmdir");
2576     guestfs_set_ready (g);
2577     return -1;
2578   }
2579
2580   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RMDIR, serial) == -1) {
2581     guestfs_set_ready (g);
2582     return -1;
2583   }
2584
2585   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2586     error (g, "%s", ctx.err.error_message);
2587     guestfs_set_ready (g);
2588     return -1;
2589   }
2590
2591   guestfs_set_ready (g);
2592   return 0;
2593 }
2594
2595 struct rm_rf_ctx {
2596   /* This flag is set by the callbacks, so we know we've done
2597    * the callbacks as expected, and in the right sequence.
2598    * 0 = not called, 1 = send called,
2599    * 1001 = reply called.
2600    */
2601   int cb_sequence;
2602   struct guestfs_message_header hdr;
2603   struct guestfs_message_error err;
2604 };
2605
2606 static void rm_rf_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2607 {
2608   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2609   struct rm_rf_ctx *ctx = (struct rm_rf_ctx *) data;
2610
2611   ml->main_loop_quit (ml, g);
2612
2613   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2614     error (g, "%s: failed to parse reply header", "guestfs_rm_rf");
2615     return;
2616   }
2617   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2618     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2619       error (g, "%s: failed to parse reply error", "guestfs_rm_rf");
2620       return;
2621     }
2622     goto done;
2623   }
2624  done:
2625   ctx->cb_sequence = 1001;
2626 }
2627
2628 int guestfs_rm_rf (guestfs_h *g,
2629                 const char *path)
2630 {
2631   struct guestfs_rm_rf_args args;
2632   struct rm_rf_ctx ctx;
2633   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2634   int serial;
2635
2636   if (check_state (g, "guestfs_rm_rf") == -1) return -1;
2637   guestfs_set_busy (g);
2638
2639   memset (&ctx, 0, sizeof ctx);
2640
2641   args.path = (char *) path;
2642   serial = guestfs__send_sync (g, GUESTFS_PROC_RM_RF,
2643         (xdrproc_t) xdr_guestfs_rm_rf_args, (char *) &args);
2644   if (serial == -1) {
2645     guestfs_set_ready (g);
2646     return -1;
2647   }
2648
2649   guestfs__switch_to_receiving (g);
2650   ctx.cb_sequence = 0;
2651   guestfs_set_reply_callback (g, rm_rf_reply_cb, &ctx);
2652   (void) ml->main_loop_run (ml, g);
2653   guestfs_set_reply_callback (g, NULL, NULL);
2654   if (ctx.cb_sequence != 1001) {
2655     error (g, "%s reply failed, see earlier error messages", "guestfs_rm_rf");
2656     guestfs_set_ready (g);
2657     return -1;
2658   }
2659
2660   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RM_RF, serial) == -1) {
2661     guestfs_set_ready (g);
2662     return -1;
2663   }
2664
2665   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2666     error (g, "%s", ctx.err.error_message);
2667     guestfs_set_ready (g);
2668     return -1;
2669   }
2670
2671   guestfs_set_ready (g);
2672   return 0;
2673 }
2674
2675 struct mkdir_ctx {
2676   /* This flag is set by the callbacks, so we know we've done
2677    * the callbacks as expected, and in the right sequence.
2678    * 0 = not called, 1 = send called,
2679    * 1001 = reply called.
2680    */
2681   int cb_sequence;
2682   struct guestfs_message_header hdr;
2683   struct guestfs_message_error err;
2684 };
2685
2686 static void mkdir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2687 {
2688   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2689   struct mkdir_ctx *ctx = (struct mkdir_ctx *) data;
2690
2691   ml->main_loop_quit (ml, g);
2692
2693   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2694     error (g, "%s: failed to parse reply header", "guestfs_mkdir");
2695     return;
2696   }
2697   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2698     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2699       error (g, "%s: failed to parse reply error", "guestfs_mkdir");
2700       return;
2701     }
2702     goto done;
2703   }
2704  done:
2705   ctx->cb_sequence = 1001;
2706 }
2707
2708 int guestfs_mkdir (guestfs_h *g,
2709                 const char *path)
2710 {
2711   struct guestfs_mkdir_args args;
2712   struct mkdir_ctx ctx;
2713   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2714   int serial;
2715
2716   if (check_state (g, "guestfs_mkdir") == -1) return -1;
2717   guestfs_set_busy (g);
2718
2719   memset (&ctx, 0, sizeof ctx);
2720
2721   args.path = (char *) path;
2722   serial = guestfs__send_sync (g, GUESTFS_PROC_MKDIR,
2723         (xdrproc_t) xdr_guestfs_mkdir_args, (char *) &args);
2724   if (serial == -1) {
2725     guestfs_set_ready (g);
2726     return -1;
2727   }
2728
2729   guestfs__switch_to_receiving (g);
2730   ctx.cb_sequence = 0;
2731   guestfs_set_reply_callback (g, mkdir_reply_cb, &ctx);
2732   (void) ml->main_loop_run (ml, g);
2733   guestfs_set_reply_callback (g, NULL, NULL);
2734   if (ctx.cb_sequence != 1001) {
2735     error (g, "%s reply failed, see earlier error messages", "guestfs_mkdir");
2736     guestfs_set_ready (g);
2737     return -1;
2738   }
2739
2740   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKDIR, serial) == -1) {
2741     guestfs_set_ready (g);
2742     return -1;
2743   }
2744
2745   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2746     error (g, "%s", ctx.err.error_message);
2747     guestfs_set_ready (g);
2748     return -1;
2749   }
2750
2751   guestfs_set_ready (g);
2752   return 0;
2753 }
2754
2755 struct mkdir_p_ctx {
2756   /* This flag is set by the callbacks, so we know we've done
2757    * the callbacks as expected, and in the right sequence.
2758    * 0 = not called, 1 = send called,
2759    * 1001 = reply called.
2760    */
2761   int cb_sequence;
2762   struct guestfs_message_header hdr;
2763   struct guestfs_message_error err;
2764 };
2765
2766 static void mkdir_p_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2767 {
2768   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2769   struct mkdir_p_ctx *ctx = (struct mkdir_p_ctx *) data;
2770
2771   ml->main_loop_quit (ml, g);
2772
2773   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2774     error (g, "%s: failed to parse reply header", "guestfs_mkdir_p");
2775     return;
2776   }
2777   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2778     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2779       error (g, "%s: failed to parse reply error", "guestfs_mkdir_p");
2780       return;
2781     }
2782     goto done;
2783   }
2784  done:
2785   ctx->cb_sequence = 1001;
2786 }
2787
2788 int guestfs_mkdir_p (guestfs_h *g,
2789                 const char *path)
2790 {
2791   struct guestfs_mkdir_p_args args;
2792   struct mkdir_p_ctx ctx;
2793   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2794   int serial;
2795
2796   if (check_state (g, "guestfs_mkdir_p") == -1) return -1;
2797   guestfs_set_busy (g);
2798
2799   memset (&ctx, 0, sizeof ctx);
2800
2801   args.path = (char *) path;
2802   serial = guestfs__send_sync (g, GUESTFS_PROC_MKDIR_P,
2803         (xdrproc_t) xdr_guestfs_mkdir_p_args, (char *) &args);
2804   if (serial == -1) {
2805     guestfs_set_ready (g);
2806     return -1;
2807   }
2808
2809   guestfs__switch_to_receiving (g);
2810   ctx.cb_sequence = 0;
2811   guestfs_set_reply_callback (g, mkdir_p_reply_cb, &ctx);
2812   (void) ml->main_loop_run (ml, g);
2813   guestfs_set_reply_callback (g, NULL, NULL);
2814   if (ctx.cb_sequence != 1001) {
2815     error (g, "%s reply failed, see earlier error messages", "guestfs_mkdir_p");
2816     guestfs_set_ready (g);
2817     return -1;
2818   }
2819
2820   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1) {
2821     guestfs_set_ready (g);
2822     return -1;
2823   }
2824
2825   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2826     error (g, "%s", ctx.err.error_message);
2827     guestfs_set_ready (g);
2828     return -1;
2829   }
2830
2831   guestfs_set_ready (g);
2832   return 0;
2833 }
2834
2835 struct chmod_ctx {
2836   /* This flag is set by the callbacks, so we know we've done
2837    * the callbacks as expected, and in the right sequence.
2838    * 0 = not called, 1 = send called,
2839    * 1001 = reply called.
2840    */
2841   int cb_sequence;
2842   struct guestfs_message_header hdr;
2843   struct guestfs_message_error err;
2844 };
2845
2846 static void chmod_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2847 {
2848   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2849   struct chmod_ctx *ctx = (struct chmod_ctx *) data;
2850
2851   ml->main_loop_quit (ml, g);
2852
2853   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2854     error (g, "%s: failed to parse reply header", "guestfs_chmod");
2855     return;
2856   }
2857   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2858     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2859       error (g, "%s: failed to parse reply error", "guestfs_chmod");
2860       return;
2861     }
2862     goto done;
2863   }
2864  done:
2865   ctx->cb_sequence = 1001;
2866 }
2867
2868 int guestfs_chmod (guestfs_h *g,
2869                 int mode,
2870                 const char *path)
2871 {
2872   struct guestfs_chmod_args args;
2873   struct chmod_ctx ctx;
2874   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2875   int serial;
2876
2877   if (check_state (g, "guestfs_chmod") == -1) return -1;
2878   guestfs_set_busy (g);
2879
2880   memset (&ctx, 0, sizeof ctx);
2881
2882   args.mode = mode;
2883   args.path = (char *) path;
2884   serial = guestfs__send_sync (g, GUESTFS_PROC_CHMOD,
2885         (xdrproc_t) xdr_guestfs_chmod_args, (char *) &args);
2886   if (serial == -1) {
2887     guestfs_set_ready (g);
2888     return -1;
2889   }
2890
2891   guestfs__switch_to_receiving (g);
2892   ctx.cb_sequence = 0;
2893   guestfs_set_reply_callback (g, chmod_reply_cb, &ctx);
2894   (void) ml->main_loop_run (ml, g);
2895   guestfs_set_reply_callback (g, NULL, NULL);
2896   if (ctx.cb_sequence != 1001) {
2897     error (g, "%s reply failed, see earlier error messages", "guestfs_chmod");
2898     guestfs_set_ready (g);
2899     return -1;
2900   }
2901
2902   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHMOD, serial) == -1) {
2903     guestfs_set_ready (g);
2904     return -1;
2905   }
2906
2907   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2908     error (g, "%s", ctx.err.error_message);
2909     guestfs_set_ready (g);
2910     return -1;
2911   }
2912
2913   guestfs_set_ready (g);
2914   return 0;
2915 }
2916
2917 struct chown_ctx {
2918   /* This flag is set by the callbacks, so we know we've done
2919    * the callbacks as expected, and in the right sequence.
2920    * 0 = not called, 1 = send called,
2921    * 1001 = reply called.
2922    */
2923   int cb_sequence;
2924   struct guestfs_message_header hdr;
2925   struct guestfs_message_error err;
2926 };
2927
2928 static void chown_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2929 {
2930   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2931   struct chown_ctx *ctx = (struct chown_ctx *) data;
2932
2933   ml->main_loop_quit (ml, g);
2934
2935   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2936     error (g, "%s: failed to parse reply header", "guestfs_chown");
2937     return;
2938   }
2939   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2940     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2941       error (g, "%s: failed to parse reply error", "guestfs_chown");
2942       return;
2943     }
2944     goto done;
2945   }
2946  done:
2947   ctx->cb_sequence = 1001;
2948 }
2949
2950 int guestfs_chown (guestfs_h *g,
2951                 int owner,
2952                 int group,
2953                 const char *path)
2954 {
2955   struct guestfs_chown_args args;
2956   struct chown_ctx ctx;
2957   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2958   int serial;
2959
2960   if (check_state (g, "guestfs_chown") == -1) return -1;
2961   guestfs_set_busy (g);
2962
2963   memset (&ctx, 0, sizeof ctx);
2964
2965   args.owner = owner;
2966   args.group = group;
2967   args.path = (char *) path;
2968   serial = guestfs__send_sync (g, GUESTFS_PROC_CHOWN,
2969         (xdrproc_t) xdr_guestfs_chown_args, (char *) &args);
2970   if (serial == -1) {
2971     guestfs_set_ready (g);
2972     return -1;
2973   }
2974
2975   guestfs__switch_to_receiving (g);
2976   ctx.cb_sequence = 0;
2977   guestfs_set_reply_callback (g, chown_reply_cb, &ctx);
2978   (void) ml->main_loop_run (ml, g);
2979   guestfs_set_reply_callback (g, NULL, NULL);
2980   if (ctx.cb_sequence != 1001) {
2981     error (g, "%s reply failed, see earlier error messages", "guestfs_chown");
2982     guestfs_set_ready (g);
2983     return -1;
2984   }
2985
2986   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHOWN, serial) == -1) {
2987     guestfs_set_ready (g);
2988     return -1;
2989   }
2990
2991   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2992     error (g, "%s", ctx.err.error_message);
2993     guestfs_set_ready (g);
2994     return -1;
2995   }
2996
2997   guestfs_set_ready (g);
2998   return 0;
2999 }
3000
3001 struct exists_ctx {
3002   /* This flag is set by the callbacks, so we know we've done
3003    * the callbacks as expected, and in the right sequence.
3004    * 0 = not called, 1 = send called,
3005    * 1001 = reply called.
3006    */
3007   int cb_sequence;
3008   struct guestfs_message_header hdr;
3009   struct guestfs_message_error err;
3010   struct guestfs_exists_ret ret;
3011 };
3012
3013 static void exists_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3014 {
3015   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3016   struct exists_ctx *ctx = (struct exists_ctx *) data;
3017
3018   ml->main_loop_quit (ml, g);
3019
3020   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3021     error (g, "%s: failed to parse reply header", "guestfs_exists");
3022     return;
3023   }
3024   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3025     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3026       error (g, "%s: failed to parse reply error", "guestfs_exists");
3027       return;
3028     }
3029     goto done;
3030   }
3031   if (!xdr_guestfs_exists_ret (xdr, &ctx->ret)) {
3032     error (g, "%s: failed to parse reply", "guestfs_exists");
3033     return;
3034   }
3035  done:
3036   ctx->cb_sequence = 1001;
3037 }
3038
3039 int guestfs_exists (guestfs_h *g,
3040                 const char *path)
3041 {
3042   struct guestfs_exists_args args;
3043   struct exists_ctx ctx;
3044   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3045   int serial;
3046
3047   if (check_state (g, "guestfs_exists") == -1) return -1;
3048   guestfs_set_busy (g);
3049
3050   memset (&ctx, 0, sizeof ctx);
3051
3052   args.path = (char *) path;
3053   serial = guestfs__send_sync (g, GUESTFS_PROC_EXISTS,
3054         (xdrproc_t) xdr_guestfs_exists_args, (char *) &args);
3055   if (serial == -1) {
3056     guestfs_set_ready (g);
3057     return -1;
3058   }
3059
3060   guestfs__switch_to_receiving (g);
3061   ctx.cb_sequence = 0;
3062   guestfs_set_reply_callback (g, exists_reply_cb, &ctx);
3063   (void) ml->main_loop_run (ml, g);
3064   guestfs_set_reply_callback (g, NULL, NULL);
3065   if (ctx.cb_sequence != 1001) {
3066     error (g, "%s reply failed, see earlier error messages", "guestfs_exists");
3067     guestfs_set_ready (g);
3068     return -1;
3069   }
3070
3071   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_EXISTS, serial) == -1) {
3072     guestfs_set_ready (g);
3073     return -1;
3074   }
3075
3076   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3077     error (g, "%s", ctx.err.error_message);
3078     guestfs_set_ready (g);
3079     return -1;
3080   }
3081
3082   guestfs_set_ready (g);
3083   return ctx.ret.existsflag;
3084 }
3085
3086 struct is_file_ctx {
3087   /* This flag is set by the callbacks, so we know we've done
3088    * the callbacks as expected, and in the right sequence.
3089    * 0 = not called, 1 = send called,
3090    * 1001 = reply called.
3091    */
3092   int cb_sequence;
3093   struct guestfs_message_header hdr;
3094   struct guestfs_message_error err;
3095   struct guestfs_is_file_ret ret;
3096 };
3097
3098 static void is_file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3099 {
3100   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3101   struct is_file_ctx *ctx = (struct is_file_ctx *) data;
3102
3103   ml->main_loop_quit (ml, g);
3104
3105   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3106     error (g, "%s: failed to parse reply header", "guestfs_is_file");
3107     return;
3108   }
3109   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3110     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3111       error (g, "%s: failed to parse reply error", "guestfs_is_file");
3112       return;
3113     }
3114     goto done;
3115   }
3116   if (!xdr_guestfs_is_file_ret (xdr, &ctx->ret)) {
3117     error (g, "%s: failed to parse reply", "guestfs_is_file");
3118     return;
3119   }
3120  done:
3121   ctx->cb_sequence = 1001;
3122 }
3123
3124 int guestfs_is_file (guestfs_h *g,
3125                 const char *path)
3126 {
3127   struct guestfs_is_file_args args;
3128   struct is_file_ctx ctx;
3129   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3130   int serial;
3131
3132   if (check_state (g, "guestfs_is_file") == -1) return -1;
3133   guestfs_set_busy (g);
3134
3135   memset (&ctx, 0, sizeof ctx);
3136
3137   args.path = (char *) path;
3138   serial = guestfs__send_sync (g, GUESTFS_PROC_IS_FILE,
3139         (xdrproc_t) xdr_guestfs_is_file_args, (char *) &args);
3140   if (serial == -1) {
3141     guestfs_set_ready (g);
3142     return -1;
3143   }
3144
3145   guestfs__switch_to_receiving (g);
3146   ctx.cb_sequence = 0;
3147   guestfs_set_reply_callback (g, is_file_reply_cb, &ctx);
3148   (void) ml->main_loop_run (ml, g);
3149   guestfs_set_reply_callback (g, NULL, NULL);
3150   if (ctx.cb_sequence != 1001) {
3151     error (g, "%s reply failed, see earlier error messages", "guestfs_is_file");
3152     guestfs_set_ready (g);
3153     return -1;
3154   }
3155
3156   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_IS_FILE, serial) == -1) {
3157     guestfs_set_ready (g);
3158     return -1;
3159   }
3160
3161   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3162     error (g, "%s", ctx.err.error_message);
3163     guestfs_set_ready (g);
3164     return -1;
3165   }
3166
3167   guestfs_set_ready (g);
3168   return ctx.ret.fileflag;
3169 }
3170
3171 struct is_dir_ctx {
3172   /* This flag is set by the callbacks, so we know we've done
3173    * the callbacks as expected, and in the right sequence.
3174    * 0 = not called, 1 = send called,
3175    * 1001 = reply called.
3176    */
3177   int cb_sequence;
3178   struct guestfs_message_header hdr;
3179   struct guestfs_message_error err;
3180   struct guestfs_is_dir_ret ret;
3181 };
3182
3183 static void is_dir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3184 {
3185   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3186   struct is_dir_ctx *ctx = (struct is_dir_ctx *) data;
3187
3188   ml->main_loop_quit (ml, g);
3189
3190   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3191     error (g, "%s: failed to parse reply header", "guestfs_is_dir");
3192     return;
3193   }
3194   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3195     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3196       error (g, "%s: failed to parse reply error", "guestfs_is_dir");
3197       return;
3198     }
3199     goto done;
3200   }
3201   if (!xdr_guestfs_is_dir_ret (xdr, &ctx->ret)) {
3202     error (g, "%s: failed to parse reply", "guestfs_is_dir");
3203     return;
3204   }
3205  done:
3206   ctx->cb_sequence = 1001;
3207 }
3208
3209 int guestfs_is_dir (guestfs_h *g,
3210                 const char *path)
3211 {
3212   struct guestfs_is_dir_args args;
3213   struct is_dir_ctx ctx;
3214   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3215   int serial;
3216
3217   if (check_state (g, "guestfs_is_dir") == -1) return -1;
3218   guestfs_set_busy (g);
3219
3220   memset (&ctx, 0, sizeof ctx);
3221
3222   args.path = (char *) path;
3223   serial = guestfs__send_sync (g, GUESTFS_PROC_IS_DIR,
3224         (xdrproc_t) xdr_guestfs_is_dir_args, (char *) &args);
3225   if (serial == -1) {
3226     guestfs_set_ready (g);
3227     return -1;
3228   }
3229
3230   guestfs__switch_to_receiving (g);
3231   ctx.cb_sequence = 0;
3232   guestfs_set_reply_callback (g, is_dir_reply_cb, &ctx);
3233   (void) ml->main_loop_run (ml, g);
3234   guestfs_set_reply_callback (g, NULL, NULL);
3235   if (ctx.cb_sequence != 1001) {
3236     error (g, "%s reply failed, see earlier error messages", "guestfs_is_dir");
3237     guestfs_set_ready (g);
3238     return -1;
3239   }
3240
3241   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_IS_DIR, serial) == -1) {
3242     guestfs_set_ready (g);
3243     return -1;
3244   }
3245
3246   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3247     error (g, "%s", ctx.err.error_message);
3248     guestfs_set_ready (g);
3249     return -1;
3250   }
3251
3252   guestfs_set_ready (g);
3253   return ctx.ret.dirflag;
3254 }
3255
3256 struct pvcreate_ctx {
3257   /* This flag is set by the callbacks, so we know we've done
3258    * the callbacks as expected, and in the right sequence.
3259    * 0 = not called, 1 = send called,
3260    * 1001 = reply called.
3261    */
3262   int cb_sequence;
3263   struct guestfs_message_header hdr;
3264   struct guestfs_message_error err;
3265 };
3266
3267 static void pvcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3268 {
3269   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3270   struct pvcreate_ctx *ctx = (struct pvcreate_ctx *) data;
3271
3272   ml->main_loop_quit (ml, g);
3273
3274   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3275     error (g, "%s: failed to parse reply header", "guestfs_pvcreate");
3276     return;
3277   }
3278   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3279     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3280       error (g, "%s: failed to parse reply error", "guestfs_pvcreate");
3281       return;
3282     }
3283     goto done;
3284   }
3285  done:
3286   ctx->cb_sequence = 1001;
3287 }
3288
3289 int guestfs_pvcreate (guestfs_h *g,
3290                 const char *device)
3291 {
3292   struct guestfs_pvcreate_args args;
3293   struct pvcreate_ctx ctx;
3294   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3295   int serial;
3296
3297   if (check_state (g, "guestfs_pvcreate") == -1) return -1;
3298   guestfs_set_busy (g);
3299
3300   memset (&ctx, 0, sizeof ctx);
3301
3302   args.device = (char *) device;
3303   serial = guestfs__send_sync (g, GUESTFS_PROC_PVCREATE,
3304         (xdrproc_t) xdr_guestfs_pvcreate_args, (char *) &args);
3305   if (serial == -1) {
3306     guestfs_set_ready (g);
3307     return -1;
3308   }
3309
3310   guestfs__switch_to_receiving (g);
3311   ctx.cb_sequence = 0;
3312   guestfs_set_reply_callback (g, pvcreate_reply_cb, &ctx);
3313   (void) ml->main_loop_run (ml, g);
3314   guestfs_set_reply_callback (g, NULL, NULL);
3315   if (ctx.cb_sequence != 1001) {
3316     error (g, "%s reply failed, see earlier error messages", "guestfs_pvcreate");
3317     guestfs_set_ready (g);
3318     return -1;
3319   }
3320
3321   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVCREATE, serial) == -1) {
3322     guestfs_set_ready (g);
3323     return -1;
3324   }
3325
3326   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3327     error (g, "%s", ctx.err.error_message);
3328     guestfs_set_ready (g);
3329     return -1;
3330   }
3331
3332   guestfs_set_ready (g);
3333   return 0;
3334 }
3335
3336 struct vgcreate_ctx {
3337   /* This flag is set by the callbacks, so we know we've done
3338    * the callbacks as expected, and in the right sequence.
3339    * 0 = not called, 1 = send called,
3340    * 1001 = reply called.
3341    */
3342   int cb_sequence;
3343   struct guestfs_message_header hdr;
3344   struct guestfs_message_error err;
3345 };
3346
3347 static void vgcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3348 {
3349   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3350   struct vgcreate_ctx *ctx = (struct vgcreate_ctx *) data;
3351
3352   ml->main_loop_quit (ml, g);
3353
3354   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3355     error (g, "%s: failed to parse reply header", "guestfs_vgcreate");
3356     return;
3357   }
3358   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3359     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3360       error (g, "%s: failed to parse reply error", "guestfs_vgcreate");
3361       return;
3362     }
3363     goto done;
3364   }
3365  done:
3366   ctx->cb_sequence = 1001;
3367 }
3368
3369 int guestfs_vgcreate (guestfs_h *g,
3370                 const char *volgroup,
3371                 char * const* const physvols)
3372 {
3373   struct guestfs_vgcreate_args args;
3374   struct vgcreate_ctx ctx;
3375   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3376   int serial;
3377
3378   if (check_state (g, "guestfs_vgcreate") == -1) return -1;
3379   guestfs_set_busy (g);
3380
3381   memset (&ctx, 0, sizeof ctx);
3382
3383   args.volgroup = (char *) volgroup;
3384   args.physvols.physvols_val = (char **) physvols;
3385   for (args.physvols.physvols_len = 0; physvols[args.physvols.physvols_len]; args.physvols.physvols_len++) ;
3386   serial = guestfs__send_sync (g, GUESTFS_PROC_VGCREATE,
3387         (xdrproc_t) xdr_guestfs_vgcreate_args, (char *) &args);
3388   if (serial == -1) {
3389     guestfs_set_ready (g);
3390     return -1;
3391   }
3392
3393   guestfs__switch_to_receiving (g);
3394   ctx.cb_sequence = 0;
3395   guestfs_set_reply_callback (g, vgcreate_reply_cb, &ctx);
3396   (void) ml->main_loop_run (ml, g);
3397   guestfs_set_reply_callback (g, NULL, NULL);
3398   if (ctx.cb_sequence != 1001) {
3399     error (g, "%s reply failed, see earlier error messages", "guestfs_vgcreate");
3400     guestfs_set_ready (g);
3401     return -1;
3402   }
3403
3404   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGCREATE, serial) == -1) {
3405     guestfs_set_ready (g);
3406     return -1;
3407   }
3408
3409   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3410     error (g, "%s", ctx.err.error_message);
3411     guestfs_set_ready (g);
3412     return -1;
3413   }
3414
3415   guestfs_set_ready (g);
3416   return 0;
3417 }
3418
3419 struct lvcreate_ctx {
3420   /* This flag is set by the callbacks, so we know we've done
3421    * the callbacks as expected, and in the right sequence.
3422    * 0 = not called, 1 = send called,
3423    * 1001 = reply called.
3424    */
3425   int cb_sequence;
3426   struct guestfs_message_header hdr;
3427   struct guestfs_message_error err;
3428 };
3429
3430 static void lvcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3431 {
3432   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3433   struct lvcreate_ctx *ctx = (struct lvcreate_ctx *) data;
3434
3435   ml->main_loop_quit (ml, g);
3436
3437   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3438     error (g, "%s: failed to parse reply header", "guestfs_lvcreate");
3439     return;
3440   }
3441   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3442     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3443       error (g, "%s: failed to parse reply error", "guestfs_lvcreate");
3444       return;
3445     }
3446     goto done;
3447   }
3448  done:
3449   ctx->cb_sequence = 1001;
3450 }
3451
3452 int guestfs_lvcreate (guestfs_h *g,
3453                 const char *logvol,
3454                 const char *volgroup,
3455                 int mbytes)
3456 {
3457   struct guestfs_lvcreate_args args;
3458   struct lvcreate_ctx ctx;
3459   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3460   int serial;
3461
3462   if (check_state (g, "guestfs_lvcreate") == -1) return -1;
3463   guestfs_set_busy (g);
3464
3465   memset (&ctx, 0, sizeof ctx);
3466
3467   args.logvol = (char *) logvol;
3468   args.volgroup = (char *) volgroup;
3469   args.mbytes = mbytes;
3470   serial = guestfs__send_sync (g, GUESTFS_PROC_LVCREATE,
3471         (xdrproc_t) xdr_guestfs_lvcreate_args, (char *) &args);
3472   if (serial == -1) {
3473     guestfs_set_ready (g);
3474     return -1;
3475   }
3476
3477   guestfs__switch_to_receiving (g);
3478   ctx.cb_sequence = 0;
3479   guestfs_set_reply_callback (g, lvcreate_reply_cb, &ctx);
3480   (void) ml->main_loop_run (ml, g);
3481   guestfs_set_reply_callback (g, NULL, NULL);
3482   if (ctx.cb_sequence != 1001) {
3483     error (g, "%s reply failed, see earlier error messages", "guestfs_lvcreate");
3484     guestfs_set_ready (g);
3485     return -1;
3486   }
3487
3488   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVCREATE, serial) == -1) {
3489     guestfs_set_ready (g);
3490     return -1;
3491   }
3492
3493   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3494     error (g, "%s", ctx.err.error_message);
3495     guestfs_set_ready (g);
3496     return -1;
3497   }
3498
3499   guestfs_set_ready (g);
3500   return 0;
3501 }
3502
3503 struct mkfs_ctx {
3504   /* This flag is set by the callbacks, so we know we've done
3505    * the callbacks as expected, and in the right sequence.
3506    * 0 = not called, 1 = send called,
3507    * 1001 = reply called.
3508    */
3509   int cb_sequence;
3510   struct guestfs_message_header hdr;
3511   struct guestfs_message_error err;
3512 };
3513
3514 static void mkfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3515 {
3516   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3517   struct mkfs_ctx *ctx = (struct mkfs_ctx *) data;
3518
3519   ml->main_loop_quit (ml, g);
3520
3521   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3522     error (g, "%s: failed to parse reply header", "guestfs_mkfs");
3523     return;
3524   }
3525   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3526     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3527       error (g, "%s: failed to parse reply error", "guestfs_mkfs");
3528       return;
3529     }
3530     goto done;
3531   }
3532  done:
3533   ctx->cb_sequence = 1001;
3534 }
3535
3536 int guestfs_mkfs (guestfs_h *g,
3537                 const char *fstype,
3538                 const char *device)
3539 {
3540   struct guestfs_mkfs_args args;
3541   struct mkfs_ctx ctx;
3542   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3543   int serial;
3544
3545   if (check_state (g, "guestfs_mkfs") == -1) return -1;
3546   guestfs_set_busy (g);
3547
3548   memset (&ctx, 0, sizeof ctx);
3549
3550   args.fstype = (char *) fstype;
3551   args.device = (char *) device;
3552   serial = guestfs__send_sync (g, GUESTFS_PROC_MKFS,
3553         (xdrproc_t) xdr_guestfs_mkfs_args, (char *) &args);
3554   if (serial == -1) {
3555     guestfs_set_ready (g);
3556     return -1;
3557   }
3558
3559   guestfs__switch_to_receiving (g);
3560   ctx.cb_sequence = 0;
3561   guestfs_set_reply_callback (g, mkfs_reply_cb, &ctx);
3562   (void) ml->main_loop_run (ml, g);
3563   guestfs_set_reply_callback (g, NULL, NULL);
3564   if (ctx.cb_sequence != 1001) {
3565     error (g, "%s reply failed, see earlier error messages", "guestfs_mkfs");
3566     guestfs_set_ready (g);
3567     return -1;
3568   }
3569
3570   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKFS, serial) == -1) {
3571     guestfs_set_ready (g);
3572     return -1;
3573   }
3574
3575   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3576     error (g, "%s", ctx.err.error_message);
3577     guestfs_set_ready (g);
3578     return -1;
3579   }
3580
3581   guestfs_set_ready (g);
3582   return 0;
3583 }
3584
3585 struct sfdisk_ctx {
3586   /* This flag is set by the callbacks, so we know we've done
3587    * the callbacks as expected, and in the right sequence.
3588    * 0 = not called, 1 = send called,
3589    * 1001 = reply called.
3590    */
3591   int cb_sequence;
3592   struct guestfs_message_header hdr;
3593   struct guestfs_message_error err;
3594 };
3595
3596 static void sfdisk_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3597 {
3598   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3599   struct sfdisk_ctx *ctx = (struct sfdisk_ctx *) data;
3600
3601   ml->main_loop_quit (ml, g);
3602
3603   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3604     error (g, "%s: failed to parse reply header", "guestfs_sfdisk");
3605     return;
3606   }
3607   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3608     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3609       error (g, "%s: failed to parse reply error", "guestfs_sfdisk");
3610       return;
3611     }
3612     goto done;
3613   }
3614  done:
3615   ctx->cb_sequence = 1001;
3616 }
3617
3618 int guestfs_sfdisk (guestfs_h *g,
3619                 const char *device,
3620                 int cyls,
3621                 int heads,
3622                 int sectors,
3623                 char * const* const lines)
3624 {
3625   struct guestfs_sfdisk_args args;
3626   struct sfdisk_ctx ctx;
3627   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3628   int serial;
3629
3630   if (check_state (g, "guestfs_sfdisk") == -1) return -1;
3631   guestfs_set_busy (g);
3632
3633   memset (&ctx, 0, sizeof ctx);
3634
3635   args.device = (char *) device;
3636   args.cyls = cyls;
3637   args.heads = heads;
3638   args.sectors = sectors;
3639   args.lines.lines_val = (char **) lines;
3640   for (args.lines.lines_len = 0; lines[args.lines.lines_len]; args.lines.lines_len++) ;
3641   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK,
3642         (xdrproc_t) xdr_guestfs_sfdisk_args, (char *) &args);
3643   if (serial == -1) {
3644     guestfs_set_ready (g);
3645     return -1;
3646   }
3647
3648   guestfs__switch_to_receiving (g);
3649   ctx.cb_sequence = 0;
3650   guestfs_set_reply_callback (g, sfdisk_reply_cb, &ctx);
3651   (void) ml->main_loop_run (ml, g);
3652   guestfs_set_reply_callback (g, NULL, NULL);
3653   if (ctx.cb_sequence != 1001) {
3654     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk");
3655     guestfs_set_ready (g);
3656     return -1;
3657   }
3658
3659   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK, serial) == -1) {
3660     guestfs_set_ready (g);
3661     return -1;
3662   }
3663
3664   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3665     error (g, "%s", ctx.err.error_message);
3666     guestfs_set_ready (g);
3667     return -1;
3668   }
3669
3670   guestfs_set_ready (g);
3671   return 0;
3672 }
3673
3674 struct write_file_ctx {
3675   /* This flag is set by the callbacks, so we know we've done
3676    * the callbacks as expected, and in the right sequence.
3677    * 0 = not called, 1 = send called,
3678    * 1001 = reply called.
3679    */
3680   int cb_sequence;
3681   struct guestfs_message_header hdr;
3682   struct guestfs_message_error err;
3683 };
3684
3685 static void write_file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3686 {
3687   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3688   struct write_file_ctx *ctx = (struct write_file_ctx *) data;
3689
3690   ml->main_loop_quit (ml, g);
3691
3692   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3693     error (g, "%s: failed to parse reply header", "guestfs_write_file");
3694     return;
3695   }
3696   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3697     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3698       error (g, "%s: failed to parse reply error", "guestfs_write_file");
3699       return;
3700     }
3701     goto done;
3702   }
3703  done:
3704   ctx->cb_sequence = 1001;
3705 }
3706
3707 int guestfs_write_file (guestfs_h *g,
3708                 const char *path,
3709                 const char *content,
3710                 int size)
3711 {
3712   struct guestfs_write_file_args args;
3713   struct write_file_ctx ctx;
3714   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3715   int serial;
3716
3717   if (check_state (g, "guestfs_write_file") == -1) return -1;
3718   guestfs_set_busy (g);
3719
3720   memset (&ctx, 0, sizeof ctx);
3721
3722   args.path = (char *) path;
3723   args.content = (char *) content;
3724   args.size = size;
3725   serial = guestfs__send_sync (g, GUESTFS_PROC_WRITE_FILE,
3726         (xdrproc_t) xdr_guestfs_write_file_args, (char *) &args);
3727   if (serial == -1) {
3728     guestfs_set_ready (g);
3729     return -1;
3730   }
3731
3732   guestfs__switch_to_receiving (g);
3733   ctx.cb_sequence = 0;
3734   guestfs_set_reply_callback (g, write_file_reply_cb, &ctx);
3735   (void) ml->main_loop_run (ml, g);
3736   guestfs_set_reply_callback (g, NULL, NULL);
3737   if (ctx.cb_sequence != 1001) {
3738     error (g, "%s reply failed, see earlier error messages", "guestfs_write_file");
3739     guestfs_set_ready (g);
3740     return -1;
3741   }
3742
3743   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1) {
3744     guestfs_set_ready (g);
3745     return -1;
3746   }
3747
3748   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3749     error (g, "%s", ctx.err.error_message);
3750     guestfs_set_ready (g);
3751     return -1;
3752   }
3753
3754   guestfs_set_ready (g);
3755   return 0;
3756 }
3757
3758 struct umount_ctx {
3759   /* This flag is set by the callbacks, so we know we've done
3760    * the callbacks as expected, and in the right sequence.
3761    * 0 = not called, 1 = send called,
3762    * 1001 = reply called.
3763    */
3764   int cb_sequence;
3765   struct guestfs_message_header hdr;
3766   struct guestfs_message_error err;
3767 };
3768
3769 static void umount_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3770 {
3771   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3772   struct umount_ctx *ctx = (struct umount_ctx *) data;
3773
3774   ml->main_loop_quit (ml, g);
3775
3776   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3777     error (g, "%s: failed to parse reply header", "guestfs_umount");
3778     return;
3779   }
3780   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3781     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3782       error (g, "%s: failed to parse reply error", "guestfs_umount");
3783       return;
3784     }
3785     goto done;
3786   }
3787  done:
3788   ctx->cb_sequence = 1001;
3789 }
3790
3791 int guestfs_umount (guestfs_h *g,
3792                 const char *pathordevice)
3793 {
3794   struct guestfs_umount_args args;
3795   struct umount_ctx ctx;
3796   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3797   int serial;
3798
3799   if (check_state (g, "guestfs_umount") == -1) return -1;
3800   guestfs_set_busy (g);
3801
3802   memset (&ctx, 0, sizeof ctx);
3803
3804   args.pathordevice = (char *) pathordevice;
3805   serial = guestfs__send_sync (g, GUESTFS_PROC_UMOUNT,
3806         (xdrproc_t) xdr_guestfs_umount_args, (char *) &args);
3807   if (serial == -1) {
3808     guestfs_set_ready (g);
3809     return -1;
3810   }
3811
3812   guestfs__switch_to_receiving (g);
3813   ctx.cb_sequence = 0;
3814   guestfs_set_reply_callback (g, umount_reply_cb, &ctx);
3815   (void) ml->main_loop_run (ml, g);
3816   guestfs_set_reply_callback (g, NULL, NULL);
3817   if (ctx.cb_sequence != 1001) {
3818     error (g, "%s reply failed, see earlier error messages", "guestfs_umount");
3819     guestfs_set_ready (g);
3820     return -1;
3821   }
3822
3823   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UMOUNT, serial) == -1) {
3824     guestfs_set_ready (g);
3825     return -1;
3826   }
3827
3828   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3829     error (g, "%s", ctx.err.error_message);
3830     guestfs_set_ready (g);
3831     return -1;
3832   }
3833
3834   guestfs_set_ready (g);
3835   return 0;
3836 }
3837
3838 struct mounts_ctx {
3839   /* This flag is set by the callbacks, so we know we've done
3840    * the callbacks as expected, and in the right sequence.
3841    * 0 = not called, 1 = send called,
3842    * 1001 = reply called.
3843    */
3844   int cb_sequence;
3845   struct guestfs_message_header hdr;
3846   struct guestfs_message_error err;
3847   struct guestfs_mounts_ret ret;
3848 };
3849
3850 static void mounts_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3851 {
3852   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3853   struct mounts_ctx *ctx = (struct mounts_ctx *) data;
3854
3855   ml->main_loop_quit (ml, g);
3856
3857   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3858     error (g, "%s: failed to parse reply header", "guestfs_mounts");
3859     return;
3860   }
3861   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3862     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3863       error (g, "%s: failed to parse reply error", "guestfs_mounts");
3864       return;
3865     }
3866     goto done;
3867   }
3868   if (!xdr_guestfs_mounts_ret (xdr, &ctx->ret)) {
3869     error (g, "%s: failed to parse reply", "guestfs_mounts");
3870     return;
3871   }
3872  done:
3873   ctx->cb_sequence = 1001;
3874 }
3875
3876 char **guestfs_mounts (guestfs_h *g)
3877 {
3878   struct mounts_ctx ctx;
3879   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3880   int serial;
3881
3882   if (check_state (g, "guestfs_mounts") == -1) return NULL;
3883   guestfs_set_busy (g);
3884
3885   memset (&ctx, 0, sizeof ctx);
3886
3887   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNTS, NULL, NULL);
3888   if (serial == -1) {
3889     guestfs_set_ready (g);
3890     return NULL;
3891   }
3892
3893   guestfs__switch_to_receiving (g);
3894   ctx.cb_sequence = 0;
3895   guestfs_set_reply_callback (g, mounts_reply_cb, &ctx);
3896   (void) ml->main_loop_run (ml, g);
3897   guestfs_set_reply_callback (g, NULL, NULL);
3898   if (ctx.cb_sequence != 1001) {
3899     error (g, "%s reply failed, see earlier error messages", "guestfs_mounts");
3900     guestfs_set_ready (g);
3901     return NULL;
3902   }
3903
3904   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNTS, serial) == -1) {
3905     guestfs_set_ready (g);
3906     return NULL;
3907   }
3908
3909   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3910     error (g, "%s", ctx.err.error_message);
3911     guestfs_set_ready (g);
3912     return NULL;
3913   }
3914
3915   guestfs_set_ready (g);
3916   /* caller will free this, but we need to add a NULL entry */
3917   ctx.ret.devices.devices_val =
3918     safe_realloc (g, ctx.ret.devices.devices_val,
3919                   sizeof (char *) * (ctx.ret.devices.devices_len + 1));
3920   ctx.ret.devices.devices_val[ctx.ret.devices.devices_len] = NULL;
3921   return ctx.ret.devices.devices_val;
3922 }
3923
3924 struct umount_all_ctx {
3925   /* This flag is set by the callbacks, so we know we've done
3926    * the callbacks as expected, and in the right sequence.
3927    * 0 = not called, 1 = send called,
3928    * 1001 = reply called.
3929    */
3930   int cb_sequence;
3931   struct guestfs_message_header hdr;
3932   struct guestfs_message_error err;
3933 };
3934
3935 static void umount_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3936 {
3937   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3938   struct umount_all_ctx *ctx = (struct umount_all_ctx *) data;
3939
3940   ml->main_loop_quit (ml, g);
3941
3942   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3943     error (g, "%s: failed to parse reply header", "guestfs_umount_all");
3944     return;
3945   }
3946   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3947     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3948       error (g, "%s: failed to parse reply error", "guestfs_umount_all");
3949       return;
3950     }
3951     goto done;
3952   }
3953  done:
3954   ctx->cb_sequence = 1001;
3955 }
3956
3957 int guestfs_umount_all (guestfs_h *g)
3958 {
3959   struct umount_all_ctx ctx;
3960   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3961   int serial;
3962
3963   if (check_state (g, "guestfs_umount_all") == -1) return -1;
3964   guestfs_set_busy (g);
3965
3966   memset (&ctx, 0, sizeof ctx);
3967
3968   serial = guestfs__send_sync (g, GUESTFS_PROC_UMOUNT_ALL, NULL, NULL);
3969   if (serial == -1) {
3970     guestfs_set_ready (g);
3971     return -1;
3972   }
3973
3974   guestfs__switch_to_receiving (g);
3975   ctx.cb_sequence = 0;
3976   guestfs_set_reply_callback (g, umount_all_reply_cb, &ctx);
3977   (void) ml->main_loop_run (ml, g);
3978   guestfs_set_reply_callback (g, NULL, NULL);
3979   if (ctx.cb_sequence != 1001) {
3980     error (g, "%s reply failed, see earlier error messages", "guestfs_umount_all");
3981     guestfs_set_ready (g);
3982     return -1;
3983   }
3984
3985   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1) {
3986     guestfs_set_ready (g);
3987     return -1;
3988   }
3989
3990   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3991     error (g, "%s", ctx.err.error_message);
3992     guestfs_set_ready (g);
3993     return -1;
3994   }
3995
3996   guestfs_set_ready (g);
3997   return 0;
3998 }
3999
4000 struct lvm_remove_all_ctx {
4001   /* This flag is set by the callbacks, so we know we've done
4002    * the callbacks as expected, and in the right sequence.
4003    * 0 = not called, 1 = send called,
4004    * 1001 = reply called.
4005    */
4006   int cb_sequence;
4007   struct guestfs_message_header hdr;
4008   struct guestfs_message_error err;
4009 };
4010
4011 static void lvm_remove_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4012 {
4013   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4014   struct lvm_remove_all_ctx *ctx = (struct lvm_remove_all_ctx *) data;
4015
4016   ml->main_loop_quit (ml, g);
4017
4018   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4019     error (g, "%s: failed to parse reply header", "guestfs_lvm_remove_all");
4020     return;
4021   }
4022   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4023     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4024       error (g, "%s: failed to parse reply error", "guestfs_lvm_remove_all");
4025       return;
4026     }
4027     goto done;
4028   }
4029  done:
4030   ctx->cb_sequence = 1001;
4031 }
4032
4033 int guestfs_lvm_remove_all (guestfs_h *g)
4034 {
4035   struct lvm_remove_all_ctx ctx;
4036   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4037   int serial;
4038
4039   if (check_state (g, "guestfs_lvm_remove_all") == -1) return -1;
4040   guestfs_set_busy (g);
4041
4042   memset (&ctx, 0, sizeof ctx);
4043
4044   serial = guestfs__send_sync (g, GUESTFS_PROC_LVM_REMOVE_ALL, NULL, NULL);
4045   if (serial == -1) {
4046     guestfs_set_ready (g);
4047     return -1;
4048   }
4049
4050   guestfs__switch_to_receiving (g);
4051   ctx.cb_sequence = 0;
4052   guestfs_set_reply_callback (g, lvm_remove_all_reply_cb, &ctx);
4053   (void) ml->main_loop_run (ml, g);
4054   guestfs_set_reply_callback (g, NULL, NULL);
4055   if (ctx.cb_sequence != 1001) {
4056     error (g, "%s reply failed, see earlier error messages", "guestfs_lvm_remove_all");
4057     guestfs_set_ready (g);
4058     return -1;
4059   }
4060
4061   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1) {
4062     guestfs_set_ready (g);
4063     return -1;
4064   }
4065
4066   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4067     error (g, "%s", ctx.err.error_message);
4068     guestfs_set_ready (g);
4069     return -1;
4070   }
4071
4072   guestfs_set_ready (g);
4073   return 0;
4074 }
4075
4076 struct file_ctx {
4077   /* This flag is set by the callbacks, so we know we've done
4078    * the callbacks as expected, and in the right sequence.
4079    * 0 = not called, 1 = send called,
4080    * 1001 = reply called.
4081    */
4082   int cb_sequence;
4083   struct guestfs_message_header hdr;
4084   struct guestfs_message_error err;
4085   struct guestfs_file_ret ret;
4086 };
4087
4088 static void file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4089 {
4090   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4091   struct file_ctx *ctx = (struct file_ctx *) data;
4092
4093   ml->main_loop_quit (ml, g);
4094
4095   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4096     error (g, "%s: failed to parse reply header", "guestfs_file");
4097     return;
4098   }
4099   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4100     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4101       error (g, "%s: failed to parse reply error", "guestfs_file");
4102       return;
4103     }
4104     goto done;
4105   }
4106   if (!xdr_guestfs_file_ret (xdr, &ctx->ret)) {
4107     error (g, "%s: failed to parse reply", "guestfs_file");
4108     return;
4109   }
4110  done:
4111   ctx->cb_sequence = 1001;
4112 }
4113
4114 char *guestfs_file (guestfs_h *g,
4115                 const char *path)
4116 {
4117   struct guestfs_file_args args;
4118   struct file_ctx ctx;
4119   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4120   int serial;
4121
4122   if (check_state (g, "guestfs_file") == -1) return NULL;
4123   guestfs_set_busy (g);
4124
4125   memset (&ctx, 0, sizeof ctx);
4126
4127   args.path = (char *) path;
4128   serial = guestfs__send_sync (g, GUESTFS_PROC_FILE,
4129         (xdrproc_t) xdr_guestfs_file_args, (char *) &args);
4130   if (serial == -1) {
4131     guestfs_set_ready (g);
4132     return NULL;
4133   }
4134
4135   guestfs__switch_to_receiving (g);
4136   ctx.cb_sequence = 0;
4137   guestfs_set_reply_callback (g, file_reply_cb, &ctx);
4138   (void) ml->main_loop_run (ml, g);
4139   guestfs_set_reply_callback (g, NULL, NULL);
4140   if (ctx.cb_sequence != 1001) {
4141     error (g, "%s reply failed, see earlier error messages", "guestfs_file");
4142     guestfs_set_ready (g);
4143     return NULL;
4144   }
4145
4146   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_FILE, serial) == -1) {
4147     guestfs_set_ready (g);
4148     return NULL;
4149   }
4150
4151   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4152     error (g, "%s", ctx.err.error_message);
4153     guestfs_set_ready (g);
4154     return NULL;
4155   }
4156
4157   guestfs_set_ready (g);
4158   return ctx.ret.description; /* caller will free */
4159 }
4160
4161 struct command_ctx {
4162   /* This flag is set by the callbacks, so we know we've done
4163    * the callbacks as expected, and in the right sequence.
4164    * 0 = not called, 1 = send called,
4165    * 1001 = reply called.
4166    */
4167   int cb_sequence;
4168   struct guestfs_message_header hdr;
4169   struct guestfs_message_error err;
4170   struct guestfs_command_ret ret;
4171 };
4172
4173 static void command_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4174 {
4175   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4176   struct command_ctx *ctx = (struct command_ctx *) data;
4177
4178   ml->main_loop_quit (ml, g);
4179
4180   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4181     error (g, "%s: failed to parse reply header", "guestfs_command");
4182     return;
4183   }
4184   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4185     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4186       error (g, "%s: failed to parse reply error", "guestfs_command");
4187       return;
4188     }
4189     goto done;
4190   }
4191   if (!xdr_guestfs_command_ret (xdr, &ctx->ret)) {
4192     error (g, "%s: failed to parse reply", "guestfs_command");
4193     return;
4194   }
4195  done:
4196   ctx->cb_sequence = 1001;
4197 }
4198
4199 char *guestfs_command (guestfs_h *g,
4200                 char * const* const arguments)
4201 {
4202   struct guestfs_command_args args;
4203   struct command_ctx ctx;
4204   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4205   int serial;
4206
4207   if (check_state (g, "guestfs_command") == -1) return NULL;
4208   guestfs_set_busy (g);
4209
4210   memset (&ctx, 0, sizeof ctx);
4211
4212   args.arguments.arguments_val = (char **) arguments;
4213   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
4214   serial = guestfs__send_sync (g, GUESTFS_PROC_COMMAND,
4215         (xdrproc_t) xdr_guestfs_command_args, (char *) &args);
4216   if (serial == -1) {
4217     guestfs_set_ready (g);
4218     return NULL;
4219   }
4220
4221   guestfs__switch_to_receiving (g);
4222   ctx.cb_sequence = 0;
4223   guestfs_set_reply_callback (g, command_reply_cb, &ctx);
4224   (void) ml->main_loop_run (ml, g);
4225   guestfs_set_reply_callback (g, NULL, NULL);
4226   if (ctx.cb_sequence != 1001) {
4227     error (g, "%s reply failed, see earlier error messages", "guestfs_command");
4228     guestfs_set_ready (g);
4229     return NULL;
4230   }
4231
4232   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_COMMAND, serial) == -1) {
4233     guestfs_set_ready (g);
4234     return NULL;
4235   }
4236
4237   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4238     error (g, "%s", ctx.err.error_message);
4239     guestfs_set_ready (g);
4240     return NULL;
4241   }
4242
4243   guestfs_set_ready (g);
4244   return ctx.ret.output; /* caller will free */
4245 }
4246
4247 struct command_lines_ctx {
4248   /* This flag is set by the callbacks, so we know we've done
4249    * the callbacks as expected, and in the right sequence.
4250    * 0 = not called, 1 = send called,
4251    * 1001 = reply called.
4252    */
4253   int cb_sequence;
4254   struct guestfs_message_header hdr;
4255   struct guestfs_message_error err;
4256   struct guestfs_command_lines_ret ret;
4257 };
4258
4259 static void command_lines_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4260 {
4261   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4262   struct command_lines_ctx *ctx = (struct command_lines_ctx *) data;
4263
4264   ml->main_loop_quit (ml, g);
4265
4266   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4267     error (g, "%s: failed to parse reply header", "guestfs_command_lines");
4268     return;
4269   }
4270   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4271     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4272       error (g, "%s: failed to parse reply error", "guestfs_command_lines");
4273       return;
4274     }
4275     goto done;
4276   }
4277   if (!xdr_guestfs_command_lines_ret (xdr, &ctx->ret)) {
4278     error (g, "%s: failed to parse reply", "guestfs_command_lines");
4279     return;
4280   }
4281  done:
4282   ctx->cb_sequence = 1001;
4283 }
4284
4285 char **guestfs_command_lines (guestfs_h *g,
4286                 char * const* const arguments)
4287 {
4288   struct guestfs_command_lines_args args;
4289   struct command_lines_ctx ctx;
4290   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4291   int serial;
4292
4293   if (check_state (g, "guestfs_command_lines") == -1) return NULL;
4294   guestfs_set_busy (g);
4295
4296   memset (&ctx, 0, sizeof ctx);
4297
4298   args.arguments.arguments_val = (char **) arguments;
4299   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
4300   serial = guestfs__send_sync (g, GUESTFS_PROC_COMMAND_LINES,
4301         (xdrproc_t) xdr_guestfs_command_lines_args, (char *) &args);
4302   if (serial == -1) {
4303     guestfs_set_ready (g);
4304     return NULL;
4305   }
4306
4307   guestfs__switch_to_receiving (g);
4308   ctx.cb_sequence = 0;
4309   guestfs_set_reply_callback (g, command_lines_reply_cb, &ctx);
4310   (void) ml->main_loop_run (ml, g);
4311   guestfs_set_reply_callback (g, NULL, NULL);
4312   if (ctx.cb_sequence != 1001) {
4313     error (g, "%s reply failed, see earlier error messages", "guestfs_command_lines");
4314     guestfs_set_ready (g);
4315     return NULL;
4316   }
4317
4318   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_COMMAND_LINES, serial) == -1) {
4319     guestfs_set_ready (g);
4320     return NULL;
4321   }
4322
4323   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4324     error (g, "%s", ctx.err.error_message);
4325     guestfs_set_ready (g);
4326     return NULL;
4327   }
4328
4329   guestfs_set_ready (g);
4330   /* caller will free this, but we need to add a NULL entry */
4331   ctx.ret.lines.lines_val =
4332     safe_realloc (g, ctx.ret.lines.lines_val,
4333                   sizeof (char *) * (ctx.ret.lines.lines_len + 1));
4334   ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
4335   return ctx.ret.lines.lines_val;
4336 }
4337
4338 struct stat_ctx {
4339   /* This flag is set by the callbacks, so we know we've done
4340    * the callbacks as expected, and in the right sequence.
4341    * 0 = not called, 1 = send called,
4342    * 1001 = reply called.
4343    */
4344   int cb_sequence;
4345   struct guestfs_message_header hdr;
4346   struct guestfs_message_error err;
4347   struct guestfs_stat_ret ret;
4348 };
4349
4350 static void stat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4351 {
4352   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4353   struct stat_ctx *ctx = (struct stat_ctx *) data;
4354
4355   ml->main_loop_quit (ml, g);
4356
4357   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4358     error (g, "%s: failed to parse reply header", "guestfs_stat");
4359     return;
4360   }
4361   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4362     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4363       error (g, "%s: failed to parse reply error", "guestfs_stat");
4364       return;
4365     }
4366     goto done;
4367   }
4368   if (!xdr_guestfs_stat_ret (xdr, &ctx->ret)) {
4369     error (g, "%s: failed to parse reply", "guestfs_stat");
4370     return;
4371   }
4372  done:
4373   ctx->cb_sequence = 1001;
4374 }
4375
4376 struct guestfs_stat *guestfs_stat (guestfs_h *g,
4377                 const char *path)
4378 {
4379   struct guestfs_stat_args args;
4380   struct stat_ctx ctx;
4381   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4382   int serial;
4383
4384   if (check_state (g, "guestfs_stat") == -1) return NULL;
4385   guestfs_set_busy (g);
4386
4387   memset (&ctx, 0, sizeof ctx);
4388
4389   args.path = (char *) path;
4390   serial = guestfs__send_sync (g, GUESTFS_PROC_STAT,
4391         (xdrproc_t) xdr_guestfs_stat_args, (char *) &args);
4392   if (serial == -1) {
4393     guestfs_set_ready (g);
4394     return NULL;
4395   }
4396
4397   guestfs__switch_to_receiving (g);
4398   ctx.cb_sequence = 0;
4399   guestfs_set_reply_callback (g, stat_reply_cb, &ctx);
4400   (void) ml->main_loop_run (ml, g);
4401   guestfs_set_reply_callback (g, NULL, NULL);
4402   if (ctx.cb_sequence != 1001) {
4403     error (g, "%s reply failed, see earlier error messages", "guestfs_stat");
4404     guestfs_set_ready (g);
4405     return NULL;
4406   }
4407
4408   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STAT, serial) == -1) {
4409     guestfs_set_ready (g);
4410     return NULL;
4411   }
4412
4413   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4414     error (g, "%s", ctx.err.error_message);
4415     guestfs_set_ready (g);
4416     return NULL;
4417   }
4418
4419   guestfs_set_ready (g);
4420   /* caller will free this */
4421   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4422 }
4423
4424 struct lstat_ctx {
4425   /* This flag is set by the callbacks, so we know we've done
4426    * the callbacks as expected, and in the right sequence.
4427    * 0 = not called, 1 = send called,
4428    * 1001 = reply called.
4429    */
4430   int cb_sequence;
4431   struct guestfs_message_header hdr;
4432   struct guestfs_message_error err;
4433   struct guestfs_lstat_ret ret;
4434 };
4435
4436 static void lstat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4437 {
4438   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4439   struct lstat_ctx *ctx = (struct lstat_ctx *) data;
4440
4441   ml->main_loop_quit (ml, g);
4442
4443   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4444     error (g, "%s: failed to parse reply header", "guestfs_lstat");
4445     return;
4446   }
4447   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4448     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4449       error (g, "%s: failed to parse reply error", "guestfs_lstat");
4450       return;
4451     }
4452     goto done;
4453   }
4454   if (!xdr_guestfs_lstat_ret (xdr, &ctx->ret)) {
4455     error (g, "%s: failed to parse reply", "guestfs_lstat");
4456     return;
4457   }
4458  done:
4459   ctx->cb_sequence = 1001;
4460 }
4461
4462 struct guestfs_stat *guestfs_lstat (guestfs_h *g,
4463                 const char *path)
4464 {
4465   struct guestfs_lstat_args args;
4466   struct lstat_ctx ctx;
4467   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4468   int serial;
4469
4470   if (check_state (g, "guestfs_lstat") == -1) return NULL;
4471   guestfs_set_busy (g);
4472
4473   memset (&ctx, 0, sizeof ctx);
4474
4475   args.path = (char *) path;
4476   serial = guestfs__send_sync (g, GUESTFS_PROC_LSTAT,
4477         (xdrproc_t) xdr_guestfs_lstat_args, (char *) &args);
4478   if (serial == -1) {
4479     guestfs_set_ready (g);
4480     return NULL;
4481   }
4482
4483   guestfs__switch_to_receiving (g);
4484   ctx.cb_sequence = 0;
4485   guestfs_set_reply_callback (g, lstat_reply_cb, &ctx);
4486   (void) ml->main_loop_run (ml, g);
4487   guestfs_set_reply_callback (g, NULL, NULL);
4488   if (ctx.cb_sequence != 1001) {
4489     error (g, "%s reply failed, see earlier error messages", "guestfs_lstat");
4490     guestfs_set_ready (g);
4491     return NULL;
4492   }
4493
4494   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LSTAT, serial) == -1) {
4495     guestfs_set_ready (g);
4496     return NULL;
4497   }
4498
4499   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4500     error (g, "%s", ctx.err.error_message);
4501     guestfs_set_ready (g);
4502     return NULL;
4503   }
4504
4505   guestfs_set_ready (g);
4506   /* caller will free this */
4507   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4508 }
4509
4510 struct statvfs_ctx {
4511   /* This flag is set by the callbacks, so we know we've done
4512    * the callbacks as expected, and in the right sequence.
4513    * 0 = not called, 1 = send called,
4514    * 1001 = reply called.
4515    */
4516   int cb_sequence;
4517   struct guestfs_message_header hdr;
4518   struct guestfs_message_error err;
4519   struct guestfs_statvfs_ret ret;
4520 };
4521
4522 static void statvfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4523 {
4524   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4525   struct statvfs_ctx *ctx = (struct statvfs_ctx *) data;
4526
4527   ml->main_loop_quit (ml, g);
4528
4529   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4530     error (g, "%s: failed to parse reply header", "guestfs_statvfs");
4531     return;
4532   }
4533   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4534     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4535       error (g, "%s: failed to parse reply error", "guestfs_statvfs");
4536       return;
4537     }
4538     goto done;
4539   }
4540   if (!xdr_guestfs_statvfs_ret (xdr, &ctx->ret)) {
4541     error (g, "%s: failed to parse reply", "guestfs_statvfs");
4542     return;
4543   }
4544  done:
4545   ctx->cb_sequence = 1001;
4546 }
4547
4548 struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g,
4549                 const char *path)
4550 {
4551   struct guestfs_statvfs_args args;
4552   struct statvfs_ctx ctx;
4553   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4554   int serial;
4555
4556   if (check_state (g, "guestfs_statvfs") == -1) return NULL;
4557   guestfs_set_busy (g);
4558
4559   memset (&ctx, 0, sizeof ctx);
4560
4561   args.path = (char *) path;
4562   serial = guestfs__send_sync (g, GUESTFS_PROC_STATVFS,
4563         (xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args);
4564   if (serial == -1) {
4565     guestfs_set_ready (g);
4566     return NULL;
4567   }
4568
4569   guestfs__switch_to_receiving (g);
4570   ctx.cb_sequence = 0;
4571   guestfs_set_reply_callback (g, statvfs_reply_cb, &ctx);
4572   (void) ml->main_loop_run (ml, g);
4573   guestfs_set_reply_callback (g, NULL, NULL);
4574   if (ctx.cb_sequence != 1001) {
4575     error (g, "%s reply failed, see earlier error messages", "guestfs_statvfs");
4576     guestfs_set_ready (g);
4577     return NULL;
4578   }
4579
4580   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STATVFS, serial) == -1) {
4581     guestfs_set_ready (g);
4582     return NULL;
4583   }
4584
4585   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4586     error (g, "%s", ctx.err.error_message);
4587     guestfs_set_ready (g);
4588     return NULL;
4589   }
4590
4591   guestfs_set_ready (g);
4592   /* caller will free this */
4593   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4594 }
4595
4596 struct tune2fs_l_ctx {
4597   /* This flag is set by the callbacks, so we know we've done
4598    * the callbacks as expected, and in the right sequence.
4599    * 0 = not called, 1 = send called,
4600    * 1001 = reply called.
4601    */
4602   int cb_sequence;
4603   struct guestfs_message_header hdr;
4604   struct guestfs_message_error err;
4605   struct guestfs_tune2fs_l_ret ret;
4606 };
4607
4608 static void tune2fs_l_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4609 {
4610   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4611   struct tune2fs_l_ctx *ctx = (struct tune2fs_l_ctx *) data;
4612
4613   ml->main_loop_quit (ml, g);
4614
4615   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4616     error (g, "%s: failed to parse reply header", "guestfs_tune2fs_l");
4617     return;
4618   }
4619   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4620     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4621       error (g, "%s: failed to parse reply error", "guestfs_tune2fs_l");
4622       return;
4623     }
4624     goto done;
4625   }
4626   if (!xdr_guestfs_tune2fs_l_ret (xdr, &ctx->ret)) {
4627     error (g, "%s: failed to parse reply", "guestfs_tune2fs_l");
4628     return;
4629   }
4630  done:
4631   ctx->cb_sequence = 1001;
4632 }
4633
4634 char **guestfs_tune2fs_l (guestfs_h *g,
4635                 const char *device)
4636 {
4637   struct guestfs_tune2fs_l_args args;
4638   struct tune2fs_l_ctx ctx;
4639   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4640   int serial;
4641
4642   if (check_state (g, "guestfs_tune2fs_l") == -1) return NULL;
4643   guestfs_set_busy (g);
4644
4645   memset (&ctx, 0, sizeof ctx);
4646
4647   args.device = (char *) device;
4648   serial = guestfs__send_sync (g, GUESTFS_PROC_TUNE2FS_L,
4649         (xdrproc_t) xdr_guestfs_tune2fs_l_args, (char *) &args);
4650   if (serial == -1) {
4651     guestfs_set_ready (g);
4652     return NULL;
4653   }
4654
4655   guestfs__switch_to_receiving (g);
4656   ctx.cb_sequence = 0;
4657   guestfs_set_reply_callback (g, tune2fs_l_reply_cb, &ctx);
4658   (void) ml->main_loop_run (ml, g);
4659   guestfs_set_reply_callback (g, NULL, NULL);
4660   if (ctx.cb_sequence != 1001) {
4661     error (g, "%s reply failed, see earlier error messages", "guestfs_tune2fs_l");
4662     guestfs_set_ready (g);
4663     return NULL;
4664   }
4665
4666   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TUNE2FS_L, serial) == -1) {
4667     guestfs_set_ready (g);
4668     return NULL;
4669   }
4670
4671   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4672     error (g, "%s", ctx.err.error_message);
4673     guestfs_set_ready (g);
4674     return NULL;
4675   }
4676
4677   guestfs_set_ready (g);
4678   /* caller will free this, but we need to add a NULL entry */
4679   ctx.ret.superblock.superblock_val =
4680     safe_realloc (g, ctx.ret.superblock.superblock_val,
4681                   sizeof (char *) * (ctx.ret.superblock.superblock_len + 1));
4682   ctx.ret.superblock.superblock_val[ctx.ret.superblock.superblock_len] = NULL;
4683   return ctx.ret.superblock.superblock_val;
4684 }
4685
4686 struct blockdev_setro_ctx {
4687   /* This flag is set by the callbacks, so we know we've done
4688    * the callbacks as expected, and in the right sequence.
4689    * 0 = not called, 1 = send called,
4690    * 1001 = reply called.
4691    */
4692   int cb_sequence;
4693   struct guestfs_message_header hdr;
4694   struct guestfs_message_error err;
4695 };
4696
4697 static void blockdev_setro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4698 {
4699   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4700   struct blockdev_setro_ctx *ctx = (struct blockdev_setro_ctx *) data;
4701
4702   ml->main_loop_quit (ml, g);
4703
4704   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4705     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setro");
4706     return;
4707   }
4708   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4709     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4710       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setro");
4711       return;
4712     }
4713     goto done;
4714   }
4715  done:
4716   ctx->cb_sequence = 1001;
4717 }
4718
4719 int guestfs_blockdev_setro (guestfs_h *g,
4720                 const char *device)
4721 {
4722   struct guestfs_blockdev_setro_args args;
4723   struct blockdev_setro_ctx ctx;
4724   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4725   int serial;
4726
4727   if (check_state (g, "guestfs_blockdev_setro") == -1) return -1;
4728   guestfs_set_busy (g);
4729
4730   memset (&ctx, 0, sizeof ctx);
4731
4732   args.device = (char *) device;
4733   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETRO,
4734         (xdrproc_t) xdr_guestfs_blockdev_setro_args, (char *) &args);
4735   if (serial == -1) {
4736     guestfs_set_ready (g);
4737     return -1;
4738   }
4739
4740   guestfs__switch_to_receiving (g);
4741   ctx.cb_sequence = 0;
4742   guestfs_set_reply_callback (g, blockdev_setro_reply_cb, &ctx);
4743   (void) ml->main_loop_run (ml, g);
4744   guestfs_set_reply_callback (g, NULL, NULL);
4745   if (ctx.cb_sequence != 1001) {
4746     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setro");
4747     guestfs_set_ready (g);
4748     return -1;
4749   }
4750
4751   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETRO, serial) == -1) {
4752     guestfs_set_ready (g);
4753     return -1;
4754   }
4755
4756   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4757     error (g, "%s", ctx.err.error_message);
4758     guestfs_set_ready (g);
4759     return -1;
4760   }
4761
4762   guestfs_set_ready (g);
4763   return 0;
4764 }
4765
4766 struct blockdev_setrw_ctx {
4767   /* This flag is set by the callbacks, so we know we've done
4768    * the callbacks as expected, and in the right sequence.
4769    * 0 = not called, 1 = send called,
4770    * 1001 = reply called.
4771    */
4772   int cb_sequence;
4773   struct guestfs_message_header hdr;
4774   struct guestfs_message_error err;
4775 };
4776
4777 static void blockdev_setrw_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4778 {
4779   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4780   struct blockdev_setrw_ctx *ctx = (struct blockdev_setrw_ctx *) data;
4781
4782   ml->main_loop_quit (ml, g);
4783
4784   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4785     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setrw");
4786     return;
4787   }
4788   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4789     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4790       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setrw");
4791       return;
4792     }
4793     goto done;
4794   }
4795  done:
4796   ctx->cb_sequence = 1001;
4797 }
4798
4799 int guestfs_blockdev_setrw (guestfs_h *g,
4800                 const char *device)
4801 {
4802   struct guestfs_blockdev_setrw_args args;
4803   struct blockdev_setrw_ctx ctx;
4804   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4805   int serial;
4806
4807   if (check_state (g, "guestfs_blockdev_setrw") == -1) return -1;
4808   guestfs_set_busy (g);
4809
4810   memset (&ctx, 0, sizeof ctx);
4811
4812   args.device = (char *) device;
4813   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETRW,
4814         (xdrproc_t) xdr_guestfs_blockdev_setrw_args, (char *) &args);
4815   if (serial == -1) {
4816     guestfs_set_ready (g);
4817     return -1;
4818   }
4819
4820   guestfs__switch_to_receiving (g);
4821   ctx.cb_sequence = 0;
4822   guestfs_set_reply_callback (g, blockdev_setrw_reply_cb, &ctx);
4823   (void) ml->main_loop_run (ml, g);
4824   guestfs_set_reply_callback (g, NULL, NULL);
4825   if (ctx.cb_sequence != 1001) {
4826     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setrw");
4827     guestfs_set_ready (g);
4828     return -1;
4829   }
4830
4831   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETRW, serial) == -1) {
4832     guestfs_set_ready (g);
4833     return -1;
4834   }
4835
4836   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4837     error (g, "%s", ctx.err.error_message);
4838     guestfs_set_ready (g);
4839     return -1;
4840   }
4841
4842   guestfs_set_ready (g);
4843   return 0;
4844 }
4845
4846 struct blockdev_getro_ctx {
4847   /* This flag is set by the callbacks, so we know we've done
4848    * the callbacks as expected, and in the right sequence.
4849    * 0 = not called, 1 = send called,
4850    * 1001 = reply called.
4851    */
4852   int cb_sequence;
4853   struct guestfs_message_header hdr;
4854   struct guestfs_message_error err;
4855   struct guestfs_blockdev_getro_ret ret;
4856 };
4857
4858 static void blockdev_getro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4859 {
4860   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4861   struct blockdev_getro_ctx *ctx = (struct blockdev_getro_ctx *) data;
4862
4863   ml->main_loop_quit (ml, g);
4864
4865   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4866     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getro");
4867     return;
4868   }
4869   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4870     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4871       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getro");
4872       return;
4873     }
4874     goto done;
4875   }
4876   if (!xdr_guestfs_blockdev_getro_ret (xdr, &ctx->ret)) {
4877     error (g, "%s: failed to parse reply", "guestfs_blockdev_getro");
4878     return;
4879   }
4880  done:
4881   ctx->cb_sequence = 1001;
4882 }
4883
4884 int guestfs_blockdev_getro (guestfs_h *g,
4885                 const char *device)
4886 {
4887   struct guestfs_blockdev_getro_args args;
4888   struct blockdev_getro_ctx ctx;
4889   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4890   int serial;
4891
4892   if (check_state (g, "guestfs_blockdev_getro") == -1) return -1;
4893   guestfs_set_busy (g);
4894
4895   memset (&ctx, 0, sizeof ctx);
4896
4897   args.device = (char *) device;
4898   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETRO,
4899         (xdrproc_t) xdr_guestfs_blockdev_getro_args, (char *) &args);
4900   if (serial == -1) {
4901     guestfs_set_ready (g);
4902     return -1;
4903   }
4904
4905   guestfs__switch_to_receiving (g);
4906   ctx.cb_sequence = 0;
4907   guestfs_set_reply_callback (g, blockdev_getro_reply_cb, &ctx);
4908   (void) ml->main_loop_run (ml, g);
4909   guestfs_set_reply_callback (g, NULL, NULL);
4910   if (ctx.cb_sequence != 1001) {
4911     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getro");
4912     guestfs_set_ready (g);
4913     return -1;
4914   }
4915
4916   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETRO, serial) == -1) {
4917     guestfs_set_ready (g);
4918     return -1;
4919   }
4920
4921   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4922     error (g, "%s", ctx.err.error_message);
4923     guestfs_set_ready (g);
4924     return -1;
4925   }
4926
4927   guestfs_set_ready (g);
4928   return ctx.ret.ro;
4929 }
4930
4931 struct blockdev_getss_ctx {
4932   /* This flag is set by the callbacks, so we know we've done
4933    * the callbacks as expected, and in the right sequence.
4934    * 0 = not called, 1 = send called,
4935    * 1001 = reply called.
4936    */
4937   int cb_sequence;
4938   struct guestfs_message_header hdr;
4939   struct guestfs_message_error err;
4940   struct guestfs_blockdev_getss_ret ret;
4941 };
4942
4943 static void blockdev_getss_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4944 {
4945   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4946   struct blockdev_getss_ctx *ctx = (struct blockdev_getss_ctx *) data;
4947
4948   ml->main_loop_quit (ml, g);
4949
4950   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4951     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getss");
4952     return;
4953   }
4954   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4955     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4956       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getss");
4957       return;
4958     }
4959     goto done;
4960   }
4961   if (!xdr_guestfs_blockdev_getss_ret (xdr, &ctx->ret)) {
4962     error (g, "%s: failed to parse reply", "guestfs_blockdev_getss");
4963     return;
4964   }
4965  done:
4966   ctx->cb_sequence = 1001;
4967 }
4968
4969 int guestfs_blockdev_getss (guestfs_h *g,
4970                 const char *device)
4971 {
4972   struct guestfs_blockdev_getss_args args;
4973   struct blockdev_getss_ctx ctx;
4974   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4975   int serial;
4976
4977   if (check_state (g, "guestfs_blockdev_getss") == -1) return -1;
4978   guestfs_set_busy (g);
4979
4980   memset (&ctx, 0, sizeof ctx);
4981
4982   args.device = (char *) device;
4983   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSS,
4984         (xdrproc_t) xdr_guestfs_blockdev_getss_args, (char *) &args);
4985   if (serial == -1) {
4986     guestfs_set_ready (g);
4987     return -1;
4988   }
4989
4990   guestfs__switch_to_receiving (g);
4991   ctx.cb_sequence = 0;
4992   guestfs_set_reply_callback (g, blockdev_getss_reply_cb, &ctx);
4993   (void) ml->main_loop_run (ml, g);
4994   guestfs_set_reply_callback (g, NULL, NULL);
4995   if (ctx.cb_sequence != 1001) {
4996     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getss");
4997     guestfs_set_ready (g);
4998     return -1;
4999   }
5000
5001   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSS, serial) == -1) {
5002     guestfs_set_ready (g);
5003     return -1;
5004   }
5005
5006   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5007     error (g, "%s", ctx.err.error_message);
5008     guestfs_set_ready (g);
5009     return -1;
5010   }
5011
5012   guestfs_set_ready (g);
5013   return ctx.ret.sectorsize;
5014 }
5015
5016 struct blockdev_getbsz_ctx {
5017   /* This flag is set by the callbacks, so we know we've done
5018    * the callbacks as expected, and in the right sequence.
5019    * 0 = not called, 1 = send called,
5020    * 1001 = reply called.
5021    */
5022   int cb_sequence;
5023   struct guestfs_message_header hdr;
5024   struct guestfs_message_error err;
5025   struct guestfs_blockdev_getbsz_ret ret;
5026 };
5027
5028 static void blockdev_getbsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5029 {
5030   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5031   struct blockdev_getbsz_ctx *ctx = (struct blockdev_getbsz_ctx *) data;
5032
5033   ml->main_loop_quit (ml, g);
5034
5035   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5036     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getbsz");
5037     return;
5038   }
5039   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5040     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5041       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getbsz");
5042       return;
5043     }
5044     goto done;
5045   }
5046   if (!xdr_guestfs_blockdev_getbsz_ret (xdr, &ctx->ret)) {
5047     error (g, "%s: failed to parse reply", "guestfs_blockdev_getbsz");
5048     return;
5049   }
5050  done:
5051   ctx->cb_sequence = 1001;
5052 }
5053
5054 int guestfs_blockdev_getbsz (guestfs_h *g,
5055                 const char *device)
5056 {
5057   struct guestfs_blockdev_getbsz_args args;
5058   struct blockdev_getbsz_ctx ctx;
5059   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5060   int serial;
5061
5062   if (check_state (g, "guestfs_blockdev_getbsz") == -1) return -1;
5063   guestfs_set_busy (g);
5064
5065   memset (&ctx, 0, sizeof ctx);
5066
5067   args.device = (char *) device;
5068   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETBSZ,
5069         (xdrproc_t) xdr_guestfs_blockdev_getbsz_args, (char *) &args);
5070   if (serial == -1) {
5071     guestfs_set_ready (g);
5072     return -1;
5073   }
5074
5075   guestfs__switch_to_receiving (g);
5076   ctx.cb_sequence = 0;
5077   guestfs_set_reply_callback (g, blockdev_getbsz_reply_cb, &ctx);
5078   (void) ml->main_loop_run (ml, g);
5079   guestfs_set_reply_callback (g, NULL, NULL);
5080   if (ctx.cb_sequence != 1001) {
5081     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getbsz");
5082     guestfs_set_ready (g);
5083     return -1;
5084   }
5085
5086   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETBSZ, serial) == -1) {
5087     guestfs_set_ready (g);
5088     return -1;
5089   }
5090
5091   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5092     error (g, "%s", ctx.err.error_message);
5093     guestfs_set_ready (g);
5094     return -1;
5095   }
5096
5097   guestfs_set_ready (g);
5098   return ctx.ret.blocksize;
5099 }
5100
5101 struct blockdev_setbsz_ctx {
5102   /* This flag is set by the callbacks, so we know we've done
5103    * the callbacks as expected, and in the right sequence.
5104    * 0 = not called, 1 = send called,
5105    * 1001 = reply called.
5106    */
5107   int cb_sequence;
5108   struct guestfs_message_header hdr;
5109   struct guestfs_message_error err;
5110 };
5111
5112 static void blockdev_setbsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5113 {
5114   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5115   struct blockdev_setbsz_ctx *ctx = (struct blockdev_setbsz_ctx *) data;
5116
5117   ml->main_loop_quit (ml, g);
5118
5119   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5120     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setbsz");
5121     return;
5122   }
5123   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5124     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5125       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setbsz");
5126       return;
5127     }
5128     goto done;
5129   }
5130  done:
5131   ctx->cb_sequence = 1001;
5132 }
5133
5134 int guestfs_blockdev_setbsz (guestfs_h *g,
5135                 const char *device,
5136                 int blocksize)
5137 {
5138   struct guestfs_blockdev_setbsz_args args;
5139   struct blockdev_setbsz_ctx ctx;
5140   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5141   int serial;
5142
5143   if (check_state (g, "guestfs_blockdev_setbsz") == -1) return -1;
5144   guestfs_set_busy (g);
5145
5146   memset (&ctx, 0, sizeof ctx);
5147
5148   args.device = (char *) device;
5149   args.blocksize = blocksize;
5150   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETBSZ,
5151         (xdrproc_t) xdr_guestfs_blockdev_setbsz_args, (char *) &args);
5152   if (serial == -1) {
5153     guestfs_set_ready (g);
5154     return -1;
5155   }
5156
5157   guestfs__switch_to_receiving (g);
5158   ctx.cb_sequence = 0;
5159   guestfs_set_reply_callback (g, blockdev_setbsz_reply_cb, &ctx);
5160   (void) ml->main_loop_run (ml, g);
5161   guestfs_set_reply_callback (g, NULL, NULL);
5162   if (ctx.cb_sequence != 1001) {
5163     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setbsz");
5164     guestfs_set_ready (g);
5165     return -1;
5166   }
5167
5168   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETBSZ, serial) == -1) {
5169     guestfs_set_ready (g);
5170     return -1;
5171   }
5172
5173   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5174     error (g, "%s", ctx.err.error_message);
5175     guestfs_set_ready (g);
5176     return -1;
5177   }
5178
5179   guestfs_set_ready (g);
5180   return 0;
5181 }
5182
5183 struct blockdev_getsz_ctx {
5184   /* This flag is set by the callbacks, so we know we've done
5185    * the callbacks as expected, and in the right sequence.
5186    * 0 = not called, 1 = send called,
5187    * 1001 = reply called.
5188    */
5189   int cb_sequence;
5190   struct guestfs_message_header hdr;
5191   struct guestfs_message_error err;
5192   struct guestfs_blockdev_getsz_ret ret;
5193 };
5194
5195 static void blockdev_getsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5196 {
5197   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5198   struct blockdev_getsz_ctx *ctx = (struct blockdev_getsz_ctx *) data;
5199
5200   ml->main_loop_quit (ml, g);
5201
5202   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5203     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getsz");
5204     return;
5205   }
5206   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5207     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5208       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getsz");
5209       return;
5210     }
5211     goto done;
5212   }
5213   if (!xdr_guestfs_blockdev_getsz_ret (xdr, &ctx->ret)) {
5214     error (g, "%s: failed to parse reply", "guestfs_blockdev_getsz");
5215     return;
5216   }
5217  done:
5218   ctx->cb_sequence = 1001;
5219 }
5220
5221 int64_t guestfs_blockdev_getsz (guestfs_h *g,
5222                 const char *device)
5223 {
5224   struct guestfs_blockdev_getsz_args args;
5225   struct blockdev_getsz_ctx ctx;
5226   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5227   int serial;
5228
5229   if (check_state (g, "guestfs_blockdev_getsz") == -1) return -1;
5230   guestfs_set_busy (g);
5231
5232   memset (&ctx, 0, sizeof ctx);
5233
5234   args.device = (char *) device;
5235   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSZ,
5236         (xdrproc_t) xdr_guestfs_blockdev_getsz_args, (char *) &args);
5237   if (serial == -1) {
5238     guestfs_set_ready (g);
5239     return -1;
5240   }
5241
5242   guestfs__switch_to_receiving (g);
5243   ctx.cb_sequence = 0;
5244   guestfs_set_reply_callback (g, blockdev_getsz_reply_cb, &ctx);
5245   (void) ml->main_loop_run (ml, g);
5246   guestfs_set_reply_callback (g, NULL, NULL);
5247   if (ctx.cb_sequence != 1001) {
5248     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getsz");
5249     guestfs_set_ready (g);
5250     return -1;
5251   }
5252
5253   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSZ, serial) == -1) {
5254     guestfs_set_ready (g);
5255     return -1;
5256   }
5257
5258   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5259     error (g, "%s", ctx.err.error_message);
5260     guestfs_set_ready (g);
5261     return -1;
5262   }
5263
5264   guestfs_set_ready (g);
5265   return ctx.ret.sizeinsectors;
5266 }
5267
5268 struct blockdev_getsize64_ctx {
5269   /* This flag is set by the callbacks, so we know we've done
5270    * the callbacks as expected, and in the right sequence.
5271    * 0 = not called, 1 = send called,
5272    * 1001 = reply called.
5273    */
5274   int cb_sequence;
5275   struct guestfs_message_header hdr;
5276   struct guestfs_message_error err;
5277   struct guestfs_blockdev_getsize64_ret ret;
5278 };
5279
5280 static void blockdev_getsize64_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5281 {
5282   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5283   struct blockdev_getsize64_ctx *ctx = (struct blockdev_getsize64_ctx *) data;
5284
5285   ml->main_loop_quit (ml, g);
5286
5287   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5288     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getsize64");
5289     return;
5290   }
5291   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5292     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5293       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getsize64");
5294       return;
5295     }
5296     goto done;
5297   }
5298   if (!xdr_guestfs_blockdev_getsize64_ret (xdr, &ctx->ret)) {
5299     error (g, "%s: failed to parse reply", "guestfs_blockdev_getsize64");
5300     return;
5301   }
5302  done:
5303   ctx->cb_sequence = 1001;
5304 }
5305
5306 int64_t guestfs_blockdev_getsize64 (guestfs_h *g,
5307                 const char *device)
5308 {
5309   struct guestfs_blockdev_getsize64_args args;
5310   struct blockdev_getsize64_ctx ctx;
5311   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5312   int serial;
5313
5314   if (check_state (g, "guestfs_blockdev_getsize64") == -1) return -1;
5315   guestfs_set_busy (g);
5316
5317   memset (&ctx, 0, sizeof ctx);
5318
5319   args.device = (char *) device;
5320   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSIZE64,
5321         (xdrproc_t) xdr_guestfs_blockdev_getsize64_args, (char *) &args);
5322   if (serial == -1) {
5323     guestfs_set_ready (g);
5324     return -1;
5325   }
5326
5327   guestfs__switch_to_receiving (g);
5328   ctx.cb_sequence = 0;
5329   guestfs_set_reply_callback (g, blockdev_getsize64_reply_cb, &ctx);
5330   (void) ml->main_loop_run (ml, g);
5331   guestfs_set_reply_callback (g, NULL, NULL);
5332   if (ctx.cb_sequence != 1001) {
5333     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getsize64");
5334     guestfs_set_ready (g);
5335     return -1;
5336   }
5337
5338   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSIZE64, serial) == -1) {
5339     guestfs_set_ready (g);
5340     return -1;
5341   }
5342
5343   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5344     error (g, "%s", ctx.err.error_message);
5345     guestfs_set_ready (g);
5346     return -1;
5347   }
5348
5349   guestfs_set_ready (g);
5350   return ctx.ret.sizeinbytes;
5351 }
5352
5353 struct blockdev_flushbufs_ctx {
5354   /* This flag is set by the callbacks, so we know we've done
5355    * the callbacks as expected, and in the right sequence.
5356    * 0 = not called, 1 = send called,
5357    * 1001 = reply called.
5358    */
5359   int cb_sequence;
5360   struct guestfs_message_header hdr;
5361   struct guestfs_message_error err;
5362 };
5363
5364 static void blockdev_flushbufs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5365 {
5366   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5367   struct blockdev_flushbufs_ctx *ctx = (struct blockdev_flushbufs_ctx *) data;
5368
5369   ml->main_loop_quit (ml, g);
5370
5371   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5372     error (g, "%s: failed to parse reply header", "guestfs_blockdev_flushbufs");
5373     return;
5374   }
5375   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5376     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5377       error (g, "%s: failed to parse reply error", "guestfs_blockdev_flushbufs");
5378       return;
5379     }
5380     goto done;
5381   }
5382  done:
5383   ctx->cb_sequence = 1001;
5384 }
5385
5386 int guestfs_blockdev_flushbufs (guestfs_h *g,
5387                 const char *device)
5388 {
5389   struct guestfs_blockdev_flushbufs_args args;
5390   struct blockdev_flushbufs_ctx ctx;
5391   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5392   int serial;
5393
5394   if (check_state (g, "guestfs_blockdev_flushbufs") == -1) return -1;
5395   guestfs_set_busy (g);
5396
5397   memset (&ctx, 0, sizeof ctx);
5398
5399   args.device = (char *) device;
5400   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS,
5401         (xdrproc_t) xdr_guestfs_blockdev_flushbufs_args, (char *) &args);
5402   if (serial == -1) {
5403     guestfs_set_ready (g);
5404     return -1;
5405   }
5406
5407   guestfs__switch_to_receiving (g);
5408   ctx.cb_sequence = 0;
5409   guestfs_set_reply_callback (g, blockdev_flushbufs_reply_cb, &ctx);
5410   (void) ml->main_loop_run (ml, g);
5411   guestfs_set_reply_callback (g, NULL, NULL);
5412   if (ctx.cb_sequence != 1001) {
5413     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_flushbufs");
5414     guestfs_set_ready (g);
5415     return -1;
5416   }
5417
5418   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, serial) == -1) {
5419     guestfs_set_ready (g);
5420     return -1;
5421   }
5422
5423   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5424     error (g, "%s", ctx.err.error_message);
5425     guestfs_set_ready (g);
5426     return -1;
5427   }
5428
5429   guestfs_set_ready (g);
5430   return 0;
5431 }
5432
5433 struct blockdev_rereadpt_ctx {
5434   /* This flag is set by the callbacks, so we know we've done
5435    * the callbacks as expected, and in the right sequence.
5436    * 0 = not called, 1 = send called,
5437    * 1001 = reply called.
5438    */
5439   int cb_sequence;
5440   struct guestfs_message_header hdr;
5441   struct guestfs_message_error err;
5442 };
5443
5444 static void blockdev_rereadpt_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5445 {
5446   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5447   struct blockdev_rereadpt_ctx *ctx = (struct blockdev_rereadpt_ctx *) data;
5448
5449   ml->main_loop_quit (ml, g);
5450
5451   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5452     error (g, "%s: failed to parse reply header", "guestfs_blockdev_rereadpt");
5453     return;
5454   }
5455   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5456     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5457       error (g, "%s: failed to parse reply error", "guestfs_blockdev_rereadpt");
5458       return;
5459     }
5460     goto done;
5461   }
5462  done:
5463   ctx->cb_sequence = 1001;
5464 }
5465
5466 int guestfs_blockdev_rereadpt (guestfs_h *g,
5467                 const char *device)
5468 {
5469   struct guestfs_blockdev_rereadpt_args args;
5470   struct blockdev_rereadpt_ctx ctx;
5471   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5472   int serial;
5473
5474   if (check_state (g, "guestfs_blockdev_rereadpt") == -1) return -1;
5475   guestfs_set_busy (g);
5476
5477   memset (&ctx, 0, sizeof ctx);
5478
5479   args.device = (char *) device;
5480   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_REREADPT,
5481         (xdrproc_t) xdr_guestfs_blockdev_rereadpt_args, (char *) &args);
5482   if (serial == -1) {
5483     guestfs_set_ready (g);
5484     return -1;
5485   }
5486
5487   guestfs__switch_to_receiving (g);
5488   ctx.cb_sequence = 0;
5489   guestfs_set_reply_callback (g, blockdev_rereadpt_reply_cb, &ctx);
5490   (void) ml->main_loop_run (ml, g);
5491   guestfs_set_reply_callback (g, NULL, NULL);
5492   if (ctx.cb_sequence != 1001) {
5493     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_rereadpt");
5494     guestfs_set_ready (g);
5495     return -1;
5496   }
5497
5498   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_REREADPT, serial) == -1) {
5499     guestfs_set_ready (g);
5500     return -1;
5501   }
5502
5503   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5504     error (g, "%s", ctx.err.error_message);
5505     guestfs_set_ready (g);
5506     return -1;
5507   }
5508
5509   guestfs_set_ready (g);
5510   return 0;
5511 }
5512
5513 struct upload_ctx {
5514   /* This flag is set by the callbacks, so we know we've done
5515    * the callbacks as expected, and in the right sequence.
5516    * 0 = not called, 1 = send called,
5517    * 1001 = reply called.
5518    */
5519   int cb_sequence;
5520   struct guestfs_message_header hdr;
5521   struct guestfs_message_error err;
5522 };
5523
5524 static void upload_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5525 {
5526   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5527   struct upload_ctx *ctx = (struct upload_ctx *) data;
5528
5529   ml->main_loop_quit (ml, g);
5530
5531   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5532     error (g, "%s: failed to parse reply header", "guestfs_upload");
5533     return;
5534   }
5535   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5536     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5537       error (g, "%s: failed to parse reply error", "guestfs_upload");
5538       return;
5539     }
5540     goto done;
5541   }
5542  done:
5543   ctx->cb_sequence = 1001;
5544 }
5545
5546 int guestfs_upload (guestfs_h *g,
5547                 const char *filename,
5548                 const char *remotefilename)
5549 {
5550   struct guestfs_upload_args args;
5551   struct upload_ctx ctx;
5552   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5553   int serial;
5554
5555   if (check_state (g, "guestfs_upload") == -1) return -1;
5556   guestfs_set_busy (g);
5557
5558   memset (&ctx, 0, sizeof ctx);
5559
5560   args.remotefilename = (char *) remotefilename;
5561   serial = guestfs__send_sync (g, GUESTFS_PROC_UPLOAD,
5562         (xdrproc_t) xdr_guestfs_upload_args, (char *) &args);
5563   if (serial == -1) {
5564     guestfs_set_ready (g);
5565     return -1;
5566   }
5567
5568   {
5569     int r;
5570
5571     r = guestfs__send_file_sync (g, filename);
5572     if (r == -1) {
5573       guestfs_set_ready (g);
5574       return -1;
5575     }
5576     if (r == -2) /* daemon cancelled */
5577       goto read_reply;
5578   }
5579
5580  read_reply:
5581   guestfs__switch_to_receiving (g);
5582   ctx.cb_sequence = 0;
5583   guestfs_set_reply_callback (g, upload_reply_cb, &ctx);
5584   (void) ml->main_loop_run (ml, g);
5585   guestfs_set_reply_callback (g, NULL, NULL);
5586   if (ctx.cb_sequence != 1001) {
5587     error (g, "%s reply failed, see earlier error messages", "guestfs_upload");
5588     guestfs_set_ready (g);
5589     return -1;
5590   }
5591
5592   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UPLOAD, serial) == -1) {
5593     guestfs_set_ready (g);
5594     return -1;
5595   }
5596
5597   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5598     error (g, "%s", ctx.err.error_message);
5599     guestfs_set_ready (g);
5600     return -1;
5601   }
5602
5603   guestfs_set_ready (g);
5604   return 0;
5605 }
5606
5607 struct download_ctx {
5608   /* This flag is set by the callbacks, so we know we've done
5609    * the callbacks as expected, and in the right sequence.
5610    * 0 = not called, 1 = send called,
5611    * 1001 = reply called.
5612    */
5613   int cb_sequence;
5614   struct guestfs_message_header hdr;
5615   struct guestfs_message_error err;
5616 };
5617
5618 static void download_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5619 {
5620   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5621   struct download_ctx *ctx = (struct download_ctx *) data;
5622
5623   ml->main_loop_quit (ml, g);
5624
5625   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5626     error (g, "%s: failed to parse reply header", "guestfs_download");
5627     return;
5628   }
5629   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5630     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5631       error (g, "%s: failed to parse reply error", "guestfs_download");
5632       return;
5633     }
5634     goto done;
5635   }
5636  done:
5637   ctx->cb_sequence = 1001;
5638 }
5639
5640 int guestfs_download (guestfs_h *g,
5641                 const char *remotefilename,
5642                 const char *filename)
5643 {
5644   struct guestfs_download_args args;
5645   struct download_ctx ctx;
5646   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5647   int serial;
5648
5649   if (check_state (g, "guestfs_download") == -1) return -1;
5650   guestfs_set_busy (g);
5651
5652   memset (&ctx, 0, sizeof ctx);
5653
5654   args.remotefilename = (char *) remotefilename;
5655   serial = guestfs__send_sync (g, GUESTFS_PROC_DOWNLOAD,
5656         (xdrproc_t) xdr_guestfs_download_args, (char *) &args);
5657   if (serial == -1) {
5658     guestfs_set_ready (g);
5659     return -1;
5660   }
5661
5662   guestfs__switch_to_receiving (g);
5663   ctx.cb_sequence = 0;
5664   guestfs_set_reply_callback (g, download_reply_cb, &ctx);
5665   (void) ml->main_loop_run (ml, g);
5666   guestfs_set_reply_callback (g, NULL, NULL);
5667   if (ctx.cb_sequence != 1001) {
5668     error (g, "%s reply failed, see earlier error messages", "guestfs_download");
5669     guestfs_set_ready (g);
5670     return -1;
5671   }
5672
5673   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_DOWNLOAD, serial) == -1) {
5674     guestfs_set_ready (g);
5675     return -1;
5676   }
5677
5678   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5679     error (g, "%s", ctx.err.error_message);
5680     guestfs_set_ready (g);
5681     return -1;
5682   }
5683
5684   if (guestfs__receive_file_sync (g, filename) == -1) {
5685     guestfs_set_ready (g);
5686     return -1;
5687   }
5688
5689   guestfs_set_ready (g);
5690   return 0;
5691 }
5692
5693 struct checksum_ctx {
5694   /* This flag is set by the callbacks, so we know we've done
5695    * the callbacks as expected, and in the right sequence.
5696    * 0 = not called, 1 = send called,
5697    * 1001 = reply called.
5698    */
5699   int cb_sequence;
5700   struct guestfs_message_header hdr;
5701   struct guestfs_message_error err;
5702   struct guestfs_checksum_ret ret;
5703 };
5704
5705 static void checksum_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5706 {
5707   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5708   struct checksum_ctx *ctx = (struct checksum_ctx *) data;
5709
5710   ml->main_loop_quit (ml, g);
5711
5712   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5713     error (g, "%s: failed to parse reply header", "guestfs_checksum");
5714     return;
5715   }
5716   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5717     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5718       error (g, "%s: failed to parse reply error", "guestfs_checksum");
5719       return;
5720     }
5721     goto done;
5722   }
5723   if (!xdr_guestfs_checksum_ret (xdr, &ctx->ret)) {
5724     error (g, "%s: failed to parse reply", "guestfs_checksum");
5725     return;
5726   }
5727  done:
5728   ctx->cb_sequence = 1001;
5729 }
5730
5731 char *guestfs_checksum (guestfs_h *g,
5732                 const char *csumtype,
5733                 const char *path)
5734 {
5735   struct guestfs_checksum_args args;
5736   struct checksum_ctx ctx;
5737   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5738   int serial;
5739
5740   if (check_state (g, "guestfs_checksum") == -1) return NULL;
5741   guestfs_set_busy (g);
5742
5743   memset (&ctx, 0, sizeof ctx);
5744
5745   args.csumtype = (char *) csumtype;
5746   args.path = (char *) path;
5747   serial = guestfs__send_sync (g, GUESTFS_PROC_CHECKSUM,
5748         (xdrproc_t) xdr_guestfs_checksum_args, (char *) &args);
5749   if (serial == -1) {
5750     guestfs_set_ready (g);
5751     return NULL;
5752   }
5753
5754   guestfs__switch_to_receiving (g);
5755   ctx.cb_sequence = 0;
5756   guestfs_set_reply_callback (g, checksum_reply_cb, &ctx);
5757   (void) ml->main_loop_run (ml, g);
5758   guestfs_set_reply_callback (g, NULL, NULL);
5759   if (ctx.cb_sequence != 1001) {
5760     error (g, "%s reply failed, see earlier error messages", "guestfs_checksum");
5761     guestfs_set_ready (g);
5762     return NULL;
5763   }
5764
5765   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHECKSUM, serial) == -1) {
5766     guestfs_set_ready (g);
5767     return NULL;
5768   }
5769
5770   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5771     error (g, "%s", ctx.err.error_message);
5772     guestfs_set_ready (g);
5773     return NULL;
5774   }
5775
5776   guestfs_set_ready (g);
5777   return ctx.ret.checksum; /* caller will free */
5778 }
5779
5780 struct tar_in_ctx {
5781   /* This flag is set by the callbacks, so we know we've done
5782    * the callbacks as expected, and in the right sequence.
5783    * 0 = not called, 1 = send called,
5784    * 1001 = reply called.
5785    */
5786   int cb_sequence;
5787   struct guestfs_message_header hdr;
5788   struct guestfs_message_error err;
5789 };
5790
5791 static void tar_in_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5792 {
5793   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5794   struct tar_in_ctx *ctx = (struct tar_in_ctx *) data;
5795
5796   ml->main_loop_quit (ml, g);
5797
5798   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5799     error (g, "%s: failed to parse reply header", "guestfs_tar_in");
5800     return;
5801   }
5802   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5803     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5804       error (g, "%s: failed to parse reply error", "guestfs_tar_in");
5805       return;
5806     }
5807     goto done;
5808   }
5809  done:
5810   ctx->cb_sequence = 1001;
5811 }
5812
5813 int guestfs_tar_in (guestfs_h *g,
5814                 const char *tarfile,
5815                 const char *directory)
5816 {
5817   struct guestfs_tar_in_args args;
5818   struct tar_in_ctx ctx;
5819   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5820   int serial;
5821
5822   if (check_state (g, "guestfs_tar_in") == -1) return -1;
5823   guestfs_set_busy (g);
5824
5825   memset (&ctx, 0, sizeof ctx);
5826
5827   args.directory = (char *) directory;
5828   serial = guestfs__send_sync (g, GUESTFS_PROC_TAR_IN,
5829         (xdrproc_t) xdr_guestfs_tar_in_args, (char *) &args);
5830   if (serial == -1) {
5831     guestfs_set_ready (g);
5832     return -1;
5833   }
5834
5835   {
5836     int r;
5837
5838     r = guestfs__send_file_sync (g, tarfile);
5839     if (r == -1) {
5840       guestfs_set_ready (g);
5841       return -1;
5842     }
5843     if (r == -2) /* daemon cancelled */
5844       goto read_reply;
5845   }
5846
5847  read_reply:
5848   guestfs__switch_to_receiving (g);
5849   ctx.cb_sequence = 0;
5850   guestfs_set_reply_callback (g, tar_in_reply_cb, &ctx);
5851   (void) ml->main_loop_run (ml, g);
5852   guestfs_set_reply_callback (g, NULL, NULL);
5853   if (ctx.cb_sequence != 1001) {
5854     error (g, "%s reply failed, see earlier error messages", "guestfs_tar_in");
5855     guestfs_set_ready (g);
5856     return -1;
5857   }
5858
5859   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAR_IN, serial) == -1) {
5860     guestfs_set_ready (g);
5861     return -1;
5862   }
5863
5864   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5865     error (g, "%s", ctx.err.error_message);
5866     guestfs_set_ready (g);
5867     return -1;
5868   }
5869
5870   guestfs_set_ready (g);
5871   return 0;
5872 }
5873
5874 struct tar_out_ctx {
5875   /* This flag is set by the callbacks, so we know we've done
5876    * the callbacks as expected, and in the right sequence.
5877    * 0 = not called, 1 = send called,
5878    * 1001 = reply called.
5879    */
5880   int cb_sequence;
5881   struct guestfs_message_header hdr;
5882   struct guestfs_message_error err;
5883 };
5884
5885 static void tar_out_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5886 {
5887   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5888   struct tar_out_ctx *ctx = (struct tar_out_ctx *) data;
5889
5890   ml->main_loop_quit (ml, g);
5891
5892   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5893     error (g, "%s: failed to parse reply header", "guestfs_tar_out");
5894     return;
5895   }
5896   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5897     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5898       error (g, "%s: failed to parse reply error", "guestfs_tar_out");
5899       return;
5900     }
5901     goto done;
5902   }
5903  done:
5904   ctx->cb_sequence = 1001;
5905 }
5906
5907 int guestfs_tar_out (guestfs_h *g,
5908                 const char *directory,
5909                 const char *tarfile)
5910 {
5911   struct guestfs_tar_out_args args;
5912   struct tar_out_ctx ctx;
5913   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5914   int serial;
5915
5916   if (check_state (g, "guestfs_tar_out") == -1) return -1;
5917   guestfs_set_busy (g);
5918
5919   memset (&ctx, 0, sizeof ctx);
5920
5921   args.directory = (char *) directory;
5922   serial = guestfs__send_sync (g, GUESTFS_PROC_TAR_OUT,
5923         (xdrproc_t) xdr_guestfs_tar_out_args, (char *) &args);
5924   if (serial == -1) {
5925     guestfs_set_ready (g);
5926     return -1;
5927   }
5928
5929   guestfs__switch_to_receiving (g);
5930   ctx.cb_sequence = 0;
5931   guestfs_set_reply_callback (g, tar_out_reply_cb, &ctx);
5932   (void) ml->main_loop_run (ml, g);
5933   guestfs_set_reply_callback (g, NULL, NULL);
5934   if (ctx.cb_sequence != 1001) {
5935     error (g, "%s reply failed, see earlier error messages", "guestfs_tar_out");
5936     guestfs_set_ready (g);
5937     return -1;
5938   }
5939
5940   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAR_OUT, serial) == -1) {
5941     guestfs_set_ready (g);
5942     return -1;
5943   }
5944
5945   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5946     error (g, "%s", ctx.err.error_message);
5947     guestfs_set_ready (g);
5948     return -1;
5949   }
5950
5951   if (guestfs__receive_file_sync (g, tarfile) == -1) {
5952     guestfs_set_ready (g);
5953     return -1;
5954   }
5955
5956   guestfs_set_ready (g);
5957   return 0;
5958 }
5959
5960 struct tgz_in_ctx {
5961   /* This flag is set by the callbacks, so we know we've done
5962    * the callbacks as expected, and in the right sequence.
5963    * 0 = not called, 1 = send called,
5964    * 1001 = reply called.
5965    */
5966   int cb_sequence;
5967   struct guestfs_message_header hdr;
5968   struct guestfs_message_error err;
5969 };
5970
5971 static void tgz_in_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5972 {
5973   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5974   struct tgz_in_ctx *ctx = (struct tgz_in_ctx *) data;
5975
5976   ml->main_loop_quit (ml, g);
5977
5978   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5979     error (g, "%s: failed to parse reply header", "guestfs_tgz_in");
5980     return;
5981   }
5982   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5983     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5984       error (g, "%s: failed to parse reply error", "guestfs_tgz_in");
5985       return;
5986     }
5987     goto done;
5988   }
5989  done:
5990   ctx->cb_sequence = 1001;
5991 }
5992
5993 int guestfs_tgz_in (guestfs_h *g,
5994                 const char *tarball,
5995                 const char *directory)
5996 {
5997   struct guestfs_tgz_in_args args;
5998   struct tgz_in_ctx ctx;
5999   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6000   int serial;
6001
6002   if (check_state (g, "guestfs_tgz_in") == -1) return -1;
6003   guestfs_set_busy (g);
6004
6005   memset (&ctx, 0, sizeof ctx);
6006
6007   args.directory = (char *) directory;
6008   serial = guestfs__send_sync (g, GUESTFS_PROC_TGZ_IN,
6009         (xdrproc_t) xdr_guestfs_tgz_in_args, (char *) &args);
6010   if (serial == -1) {
6011     guestfs_set_ready (g);
6012     return -1;
6013   }
6014
6015   {
6016     int r;
6017
6018     r = guestfs__send_file_sync (g, tarball);
6019     if (r == -1) {
6020       guestfs_set_ready (g);
6021       return -1;
6022     }
6023     if (r == -2) /* daemon cancelled */
6024       goto read_reply;
6025   }
6026
6027  read_reply:
6028   guestfs__switch_to_receiving (g);
6029   ctx.cb_sequence = 0;
6030   guestfs_set_reply_callback (g, tgz_in_reply_cb, &ctx);
6031   (void) ml->main_loop_run (ml, g);
6032   guestfs_set_reply_callback (g, NULL, NULL);
6033   if (ctx.cb_sequence != 1001) {
6034     error (g, "%s reply failed, see earlier error messages", "guestfs_tgz_in");
6035     guestfs_set_ready (g);
6036     return -1;
6037   }
6038
6039   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TGZ_IN, serial) == -1) {
6040     guestfs_set_ready (g);
6041     return -1;
6042   }
6043
6044   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6045     error (g, "%s", ctx.err.error_message);
6046     guestfs_set_ready (g);
6047     return -1;
6048   }
6049
6050   guestfs_set_ready (g);
6051   return 0;
6052 }
6053
6054 struct tgz_out_ctx {
6055   /* This flag is set by the callbacks, so we know we've done
6056    * the callbacks as expected, and in the right sequence.
6057    * 0 = not called, 1 = send called,
6058    * 1001 = reply called.
6059    */
6060   int cb_sequence;
6061   struct guestfs_message_header hdr;
6062   struct guestfs_message_error err;
6063 };
6064
6065 static void tgz_out_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6066 {
6067   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6068   struct tgz_out_ctx *ctx = (struct tgz_out_ctx *) data;
6069
6070   ml->main_loop_quit (ml, g);
6071
6072   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6073     error (g, "%s: failed to parse reply header", "guestfs_tgz_out");
6074     return;
6075   }
6076   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6077     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6078       error (g, "%s: failed to parse reply error", "guestfs_tgz_out");
6079       return;
6080     }
6081     goto done;
6082   }
6083  done:
6084   ctx->cb_sequence = 1001;
6085 }
6086
6087 int guestfs_tgz_out (guestfs_h *g,
6088                 const char *directory,
6089                 const char *tarball)
6090 {
6091   struct guestfs_tgz_out_args args;
6092   struct tgz_out_ctx ctx;
6093   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6094   int serial;
6095
6096   if (check_state (g, "guestfs_tgz_out") == -1) return -1;
6097   guestfs_set_busy (g);
6098
6099   memset (&ctx, 0, sizeof ctx);
6100
6101   args.directory = (char *) directory;
6102   serial = guestfs__send_sync (g, GUESTFS_PROC_TGZ_OUT,
6103         (xdrproc_t) xdr_guestfs_tgz_out_args, (char *) &args);
6104   if (serial == -1) {
6105     guestfs_set_ready (g);
6106     return -1;
6107   }
6108
6109   guestfs__switch_to_receiving (g);
6110   ctx.cb_sequence = 0;
6111   guestfs_set_reply_callback (g, tgz_out_reply_cb, &ctx);
6112   (void) ml->main_loop_run (ml, g);
6113   guestfs_set_reply_callback (g, NULL, NULL);
6114   if (ctx.cb_sequence != 1001) {
6115     error (g, "%s reply failed, see earlier error messages", "guestfs_tgz_out");
6116     guestfs_set_ready (g);
6117     return -1;
6118   }
6119
6120   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TGZ_OUT, serial) == -1) {
6121     guestfs_set_ready (g);
6122     return -1;
6123   }
6124
6125   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6126     error (g, "%s", ctx.err.error_message);
6127     guestfs_set_ready (g);
6128     return -1;
6129   }
6130
6131   if (guestfs__receive_file_sync (g, tarball) == -1) {
6132     guestfs_set_ready (g);
6133     return -1;
6134   }
6135
6136   guestfs_set_ready (g);
6137   return 0;
6138 }
6139
6140 struct mount_ro_ctx {
6141   /* This flag is set by the callbacks, so we know we've done
6142    * the callbacks as expected, and in the right sequence.
6143    * 0 = not called, 1 = send called,
6144    * 1001 = reply called.
6145    */
6146   int cb_sequence;
6147   struct guestfs_message_header hdr;
6148   struct guestfs_message_error err;
6149 };
6150
6151 static void mount_ro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6152 {
6153   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6154   struct mount_ro_ctx *ctx = (struct mount_ro_ctx *) data;
6155
6156   ml->main_loop_quit (ml, g);
6157
6158   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6159     error (g, "%s: failed to parse reply header", "guestfs_mount_ro");
6160     return;
6161   }
6162   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6163     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6164       error (g, "%s: failed to parse reply error", "guestfs_mount_ro");
6165       return;
6166     }
6167     goto done;
6168   }
6169  done:
6170   ctx->cb_sequence = 1001;
6171 }
6172
6173 int guestfs_mount_ro (guestfs_h *g,
6174                 const char *device,
6175                 const char *mountpoint)
6176 {
6177   struct guestfs_mount_ro_args args;
6178   struct mount_ro_ctx ctx;
6179   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6180   int serial;
6181
6182   if (check_state (g, "guestfs_mount_ro") == -1) return -1;
6183   guestfs_set_busy (g);
6184
6185   memset (&ctx, 0, sizeof ctx);
6186
6187   args.device = (char *) device;
6188   args.mountpoint = (char *) mountpoint;
6189   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_RO,
6190         (xdrproc_t) xdr_guestfs_mount_ro_args, (char *) &args);
6191   if (serial == -1) {
6192     guestfs_set_ready (g);
6193     return -1;
6194   }
6195
6196   guestfs__switch_to_receiving (g);
6197   ctx.cb_sequence = 0;
6198   guestfs_set_reply_callback (g, mount_ro_reply_cb, &ctx);
6199   (void) ml->main_loop_run (ml, g);
6200   guestfs_set_reply_callback (g, NULL, NULL);
6201   if (ctx.cb_sequence != 1001) {
6202     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_ro");
6203     guestfs_set_ready (g);
6204     return -1;
6205   }
6206
6207   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_RO, serial) == -1) {
6208     guestfs_set_ready (g);
6209     return -1;
6210   }
6211
6212   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6213     error (g, "%s", ctx.err.error_message);
6214     guestfs_set_ready (g);
6215     return -1;
6216   }
6217
6218   guestfs_set_ready (g);
6219   return 0;
6220 }
6221
6222 struct mount_options_ctx {
6223   /* This flag is set by the callbacks, so we know we've done
6224    * the callbacks as expected, and in the right sequence.
6225    * 0 = not called, 1 = send called,
6226    * 1001 = reply called.
6227    */
6228   int cb_sequence;
6229   struct guestfs_message_header hdr;
6230   struct guestfs_message_error err;
6231 };
6232
6233 static void mount_options_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6234 {
6235   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6236   struct mount_options_ctx *ctx = (struct mount_options_ctx *) data;
6237
6238   ml->main_loop_quit (ml, g);
6239
6240   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6241     error (g, "%s: failed to parse reply header", "guestfs_mount_options");
6242     return;
6243   }
6244   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6245     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6246       error (g, "%s: failed to parse reply error", "guestfs_mount_options");
6247       return;
6248     }
6249     goto done;
6250   }
6251  done:
6252   ctx->cb_sequence = 1001;
6253 }
6254
6255 int guestfs_mount_options (guestfs_h *g,
6256                 const char *options,
6257                 const char *device,
6258                 const char *mountpoint)
6259 {
6260   struct guestfs_mount_options_args args;
6261   struct mount_options_ctx ctx;
6262   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6263   int serial;
6264
6265   if (check_state (g, "guestfs_mount_options") == -1) return -1;
6266   guestfs_set_busy (g);
6267
6268   memset (&ctx, 0, sizeof ctx);
6269
6270   args.options = (char *) options;
6271   args.device = (char *) device;
6272   args.mountpoint = (char *) mountpoint;
6273   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_OPTIONS,
6274         (xdrproc_t) xdr_guestfs_mount_options_args, (char *) &args);
6275   if (serial == -1) {
6276     guestfs_set_ready (g);
6277     return -1;
6278   }
6279
6280   guestfs__switch_to_receiving (g);
6281   ctx.cb_sequence = 0;
6282   guestfs_set_reply_callback (g, mount_options_reply_cb, &ctx);
6283   (void) ml->main_loop_run (ml, g);
6284   guestfs_set_reply_callback (g, NULL, NULL);
6285   if (ctx.cb_sequence != 1001) {
6286     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_options");
6287     guestfs_set_ready (g);
6288     return -1;
6289   }
6290
6291   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_OPTIONS, serial) == -1) {
6292     guestfs_set_ready (g);
6293     return -1;
6294   }
6295
6296   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6297     error (g, "%s", ctx.err.error_message);
6298     guestfs_set_ready (g);
6299     return -1;
6300   }
6301
6302   guestfs_set_ready (g);
6303   return 0;
6304 }
6305
6306 struct mount_vfs_ctx {
6307   /* This flag is set by the callbacks, so we know we've done
6308    * the callbacks as expected, and in the right sequence.
6309    * 0 = not called, 1 = send called,
6310    * 1001 = reply called.
6311    */
6312   int cb_sequence;
6313   struct guestfs_message_header hdr;
6314   struct guestfs_message_error err;
6315 };
6316
6317 static void mount_vfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6318 {
6319   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6320   struct mount_vfs_ctx *ctx = (struct mount_vfs_ctx *) data;
6321
6322   ml->main_loop_quit (ml, g);
6323
6324   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6325     error (g, "%s: failed to parse reply header", "guestfs_mount_vfs");
6326     return;
6327   }
6328   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6329     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6330       error (g, "%s: failed to parse reply error", "guestfs_mount_vfs");
6331       return;
6332     }
6333     goto done;
6334   }
6335  done:
6336   ctx->cb_sequence = 1001;
6337 }
6338
6339 int guestfs_mount_vfs (guestfs_h *g,
6340                 const char *options,
6341                 const char *vfstype,
6342                 const char *device,
6343                 const char *mountpoint)
6344 {
6345   struct guestfs_mount_vfs_args args;
6346   struct mount_vfs_ctx ctx;
6347   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6348   int serial;
6349
6350   if (check_state (g, "guestfs_mount_vfs") == -1) return -1;
6351   guestfs_set_busy (g);
6352
6353   memset (&ctx, 0, sizeof ctx);
6354
6355   args.options = (char *) options;
6356   args.vfstype = (char *) vfstype;
6357   args.device = (char *) device;
6358   args.mountpoint = (char *) mountpoint;
6359   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_VFS,
6360         (xdrproc_t) xdr_guestfs_mount_vfs_args, (char *) &args);
6361   if (serial == -1) {
6362     guestfs_set_ready (g);
6363     return -1;
6364   }
6365
6366   guestfs__switch_to_receiving (g);
6367   ctx.cb_sequence = 0;
6368   guestfs_set_reply_callback (g, mount_vfs_reply_cb, &ctx);
6369   (void) ml->main_loop_run (ml, g);
6370   guestfs_set_reply_callback (g, NULL, NULL);
6371   if (ctx.cb_sequence != 1001) {
6372     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_vfs");
6373     guestfs_set_ready (g);
6374     return -1;
6375   }
6376
6377   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_VFS, serial) == -1) {
6378     guestfs_set_ready (g);
6379     return -1;
6380   }
6381
6382   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6383     error (g, "%s", ctx.err.error_message);
6384     guestfs_set_ready (g);
6385     return -1;
6386   }
6387
6388   guestfs_set_ready (g);
6389   return 0;
6390 }
6391