Prepare for 1.0.46.
[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 = reply_cb called.
90    */
91   int cb_sequence;
92   struct guestfs_message_header hdr;
93   struct guestfs_message_error err;
94 };
95
96 static void mount_reply_cb (guestfs_h *g, void *data, XDR *xdr)
97 {
98   guestfs_main_loop *ml = guestfs_get_main_loop (g);
99   struct mount_ctx *ctx = (struct mount_ctx *) data;
100
101   /* This should definitely not happen. */
102   if (ctx->cb_sequence != 0) {
103     ctx->cb_sequence = 9999;
104     error (g, "%s: internal error: reply callback called twice", "guestfs_mount");
105     return;
106   }
107
108   ml->main_loop_quit (ml, g);
109
110   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
111     error (g, "%s: failed to parse reply header", "guestfs_mount");
112     return;
113   }
114   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
115     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
116       error (g, "%s: failed to parse reply error", "guestfs_mount");
117       return;
118     }
119     goto done;
120   }
121  done:
122   ctx->cb_sequence = 1;
123 }
124
125 int guestfs_mount (guestfs_h *g,
126                 const char *device,
127                 const char *mountpoint)
128 {
129   struct guestfs_mount_args args;
130   struct mount_ctx ctx;
131   guestfs_main_loop *ml = guestfs_get_main_loop (g);
132   int serial;
133
134   if (check_state (g, "guestfs_mount") == -1) return -1;
135   guestfs_set_busy (g);
136
137   memset (&ctx, 0, sizeof ctx);
138
139   args.device = (char *) device;
140   args.mountpoint = (char *) mountpoint;
141   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT,
142         (xdrproc_t) xdr_guestfs_mount_args, (char *) &args);
143   if (serial == -1) {
144     guestfs_end_busy (g);
145     return -1;
146   }
147
148   guestfs__switch_to_receiving (g);
149   ctx.cb_sequence = 0;
150   guestfs_set_reply_callback (g, mount_reply_cb, &ctx);
151   (void) ml->main_loop_run (ml, g);
152   guestfs_set_reply_callback (g, NULL, NULL);
153   if (ctx.cb_sequence != 1) {
154     error (g, "%s reply failed, see earlier error messages", "guestfs_mount");
155     guestfs_end_busy (g);
156     return -1;
157   }
158
159   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT, serial) == -1) {
160     guestfs_end_busy (g);
161     return -1;
162   }
163
164   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
165     error (g, "%s", ctx.err.error_message);
166     free (ctx.err.error_message);
167     guestfs_end_busy (g);
168     return -1;
169   }
170
171   guestfs_end_busy (g);
172   return 0;
173 }
174
175 struct sync_ctx {
176   /* This flag is set by the callbacks, so we know we've done
177    * the callbacks as expected, and in the right sequence.
178    * 0 = not called, 1 = reply_cb called.
179    */
180   int cb_sequence;
181   struct guestfs_message_header hdr;
182   struct guestfs_message_error err;
183 };
184
185 static void sync_reply_cb (guestfs_h *g, void *data, XDR *xdr)
186 {
187   guestfs_main_loop *ml = guestfs_get_main_loop (g);
188   struct sync_ctx *ctx = (struct sync_ctx *) data;
189
190   /* This should definitely not happen. */
191   if (ctx->cb_sequence != 0) {
192     ctx->cb_sequence = 9999;
193     error (g, "%s: internal error: reply callback called twice", "guestfs_sync");
194     return;
195   }
196
197   ml->main_loop_quit (ml, g);
198
199   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
200     error (g, "%s: failed to parse reply header", "guestfs_sync");
201     return;
202   }
203   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
204     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
205       error (g, "%s: failed to parse reply error", "guestfs_sync");
206       return;
207     }
208     goto done;
209   }
210  done:
211   ctx->cb_sequence = 1;
212 }
213
214 int guestfs_sync (guestfs_h *g)
215 {
216   struct sync_ctx ctx;
217   guestfs_main_loop *ml = guestfs_get_main_loop (g);
218   int serial;
219
220   if (check_state (g, "guestfs_sync") == -1) return -1;
221   guestfs_set_busy (g);
222
223   memset (&ctx, 0, sizeof ctx);
224
225   serial = guestfs__send_sync (g, GUESTFS_PROC_SYNC, NULL, NULL);
226   if (serial == -1) {
227     guestfs_end_busy (g);
228     return -1;
229   }
230
231   guestfs__switch_to_receiving (g);
232   ctx.cb_sequence = 0;
233   guestfs_set_reply_callback (g, sync_reply_cb, &ctx);
234   (void) ml->main_loop_run (ml, g);
235   guestfs_set_reply_callback (g, NULL, NULL);
236   if (ctx.cb_sequence != 1) {
237     error (g, "%s reply failed, see earlier error messages", "guestfs_sync");
238     guestfs_end_busy (g);
239     return -1;
240   }
241
242   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SYNC, serial) == -1) {
243     guestfs_end_busy (g);
244     return -1;
245   }
246
247   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
248     error (g, "%s", ctx.err.error_message);
249     free (ctx.err.error_message);
250     guestfs_end_busy (g);
251     return -1;
252   }
253
254   guestfs_end_busy (g);
255   return 0;
256 }
257
258 struct touch_ctx {
259   /* This flag is set by the callbacks, so we know we've done
260    * the callbacks as expected, and in the right sequence.
261    * 0 = not called, 1 = reply_cb called.
262    */
263   int cb_sequence;
264   struct guestfs_message_header hdr;
265   struct guestfs_message_error err;
266 };
267
268 static void touch_reply_cb (guestfs_h *g, void *data, XDR *xdr)
269 {
270   guestfs_main_loop *ml = guestfs_get_main_loop (g);
271   struct touch_ctx *ctx = (struct touch_ctx *) data;
272
273   /* This should definitely not happen. */
274   if (ctx->cb_sequence != 0) {
275     ctx->cb_sequence = 9999;
276     error (g, "%s: internal error: reply callback called twice", "guestfs_touch");
277     return;
278   }
279
280   ml->main_loop_quit (ml, g);
281
282   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
283     error (g, "%s: failed to parse reply header", "guestfs_touch");
284     return;
285   }
286   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
287     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
288       error (g, "%s: failed to parse reply error", "guestfs_touch");
289       return;
290     }
291     goto done;
292   }
293  done:
294   ctx->cb_sequence = 1;
295 }
296
297 int guestfs_touch (guestfs_h *g,
298                 const char *path)
299 {
300   struct guestfs_touch_args args;
301   struct touch_ctx ctx;
302   guestfs_main_loop *ml = guestfs_get_main_loop (g);
303   int serial;
304
305   if (check_state (g, "guestfs_touch") == -1) return -1;
306   guestfs_set_busy (g);
307
308   memset (&ctx, 0, sizeof ctx);
309
310   args.path = (char *) path;
311   serial = guestfs__send_sync (g, GUESTFS_PROC_TOUCH,
312         (xdrproc_t) xdr_guestfs_touch_args, (char *) &args);
313   if (serial == -1) {
314     guestfs_end_busy (g);
315     return -1;
316   }
317
318   guestfs__switch_to_receiving (g);
319   ctx.cb_sequence = 0;
320   guestfs_set_reply_callback (g, touch_reply_cb, &ctx);
321   (void) ml->main_loop_run (ml, g);
322   guestfs_set_reply_callback (g, NULL, NULL);
323   if (ctx.cb_sequence != 1) {
324     error (g, "%s reply failed, see earlier error messages", "guestfs_touch");
325     guestfs_end_busy (g);
326     return -1;
327   }
328
329   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TOUCH, serial) == -1) {
330     guestfs_end_busy (g);
331     return -1;
332   }
333
334   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
335     error (g, "%s", ctx.err.error_message);
336     free (ctx.err.error_message);
337     guestfs_end_busy (g);
338     return -1;
339   }
340
341   guestfs_end_busy (g);
342   return 0;
343 }
344
345 struct cat_ctx {
346   /* This flag is set by the callbacks, so we know we've done
347    * the callbacks as expected, and in the right sequence.
348    * 0 = not called, 1 = reply_cb called.
349    */
350   int cb_sequence;
351   struct guestfs_message_header hdr;
352   struct guestfs_message_error err;
353   struct guestfs_cat_ret ret;
354 };
355
356 static void cat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
357 {
358   guestfs_main_loop *ml = guestfs_get_main_loop (g);
359   struct cat_ctx *ctx = (struct cat_ctx *) data;
360
361   /* This should definitely not happen. */
362   if (ctx->cb_sequence != 0) {
363     ctx->cb_sequence = 9999;
364     error (g, "%s: internal error: reply callback called twice", "guestfs_cat");
365     return;
366   }
367
368   ml->main_loop_quit (ml, g);
369
370   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
371     error (g, "%s: failed to parse reply header", "guestfs_cat");
372     return;
373   }
374   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
375     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
376       error (g, "%s: failed to parse reply error", "guestfs_cat");
377       return;
378     }
379     goto done;
380   }
381   if (!xdr_guestfs_cat_ret (xdr, &ctx->ret)) {
382     error (g, "%s: failed to parse reply", "guestfs_cat");
383     return;
384   }
385  done:
386   ctx->cb_sequence = 1;
387 }
388
389 char *guestfs_cat (guestfs_h *g,
390                 const char *path)
391 {
392   struct guestfs_cat_args args;
393   struct cat_ctx ctx;
394   guestfs_main_loop *ml = guestfs_get_main_loop (g);
395   int serial;
396
397   if (check_state (g, "guestfs_cat") == -1) return NULL;
398   guestfs_set_busy (g);
399
400   memset (&ctx, 0, sizeof ctx);
401
402   args.path = (char *) path;
403   serial = guestfs__send_sync (g, GUESTFS_PROC_CAT,
404         (xdrproc_t) xdr_guestfs_cat_args, (char *) &args);
405   if (serial == -1) {
406     guestfs_end_busy (g);
407     return NULL;
408   }
409
410   guestfs__switch_to_receiving (g);
411   ctx.cb_sequence = 0;
412   guestfs_set_reply_callback (g, cat_reply_cb, &ctx);
413   (void) ml->main_loop_run (ml, g);
414   guestfs_set_reply_callback (g, NULL, NULL);
415   if (ctx.cb_sequence != 1) {
416     error (g, "%s reply failed, see earlier error messages", "guestfs_cat");
417     guestfs_end_busy (g);
418     return NULL;
419   }
420
421   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CAT, serial) == -1) {
422     guestfs_end_busy (g);
423     return NULL;
424   }
425
426   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
427     error (g, "%s", ctx.err.error_message);
428     free (ctx.err.error_message);
429     guestfs_end_busy (g);
430     return NULL;
431   }
432
433   guestfs_end_busy (g);
434   return ctx.ret.content; /* caller will free */
435 }
436
437 struct ll_ctx {
438   /* This flag is set by the callbacks, so we know we've done
439    * the callbacks as expected, and in the right sequence.
440    * 0 = not called, 1 = reply_cb called.
441    */
442   int cb_sequence;
443   struct guestfs_message_header hdr;
444   struct guestfs_message_error err;
445   struct guestfs_ll_ret ret;
446 };
447
448 static void ll_reply_cb (guestfs_h *g, void *data, XDR *xdr)
449 {
450   guestfs_main_loop *ml = guestfs_get_main_loop (g);
451   struct ll_ctx *ctx = (struct ll_ctx *) data;
452
453   /* This should definitely not happen. */
454   if (ctx->cb_sequence != 0) {
455     ctx->cb_sequence = 9999;
456     error (g, "%s: internal error: reply callback called twice", "guestfs_ll");
457     return;
458   }
459
460   ml->main_loop_quit (ml, g);
461
462   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
463     error (g, "%s: failed to parse reply header", "guestfs_ll");
464     return;
465   }
466   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
467     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
468       error (g, "%s: failed to parse reply error", "guestfs_ll");
469       return;
470     }
471     goto done;
472   }
473   if (!xdr_guestfs_ll_ret (xdr, &ctx->ret)) {
474     error (g, "%s: failed to parse reply", "guestfs_ll");
475     return;
476   }
477  done:
478   ctx->cb_sequence = 1;
479 }
480
481 char *guestfs_ll (guestfs_h *g,
482                 const char *directory)
483 {
484   struct guestfs_ll_args args;
485   struct ll_ctx ctx;
486   guestfs_main_loop *ml = guestfs_get_main_loop (g);
487   int serial;
488
489   if (check_state (g, "guestfs_ll") == -1) return NULL;
490   guestfs_set_busy (g);
491
492   memset (&ctx, 0, sizeof ctx);
493
494   args.directory = (char *) directory;
495   serial = guestfs__send_sync (g, GUESTFS_PROC_LL,
496         (xdrproc_t) xdr_guestfs_ll_args, (char *) &args);
497   if (serial == -1) {
498     guestfs_end_busy (g);
499     return NULL;
500   }
501
502   guestfs__switch_to_receiving (g);
503   ctx.cb_sequence = 0;
504   guestfs_set_reply_callback (g, ll_reply_cb, &ctx);
505   (void) ml->main_loop_run (ml, g);
506   guestfs_set_reply_callback (g, NULL, NULL);
507   if (ctx.cb_sequence != 1) {
508     error (g, "%s reply failed, see earlier error messages", "guestfs_ll");
509     guestfs_end_busy (g);
510     return NULL;
511   }
512
513   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LL, serial) == -1) {
514     guestfs_end_busy (g);
515     return NULL;
516   }
517
518   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
519     error (g, "%s", ctx.err.error_message);
520     free (ctx.err.error_message);
521     guestfs_end_busy (g);
522     return NULL;
523   }
524
525   guestfs_end_busy (g);
526   return ctx.ret.listing; /* caller will free */
527 }
528
529 struct ls_ctx {
530   /* This flag is set by the callbacks, so we know we've done
531    * the callbacks as expected, and in the right sequence.
532    * 0 = not called, 1 = reply_cb called.
533    */
534   int cb_sequence;
535   struct guestfs_message_header hdr;
536   struct guestfs_message_error err;
537   struct guestfs_ls_ret ret;
538 };
539
540 static void ls_reply_cb (guestfs_h *g, void *data, XDR *xdr)
541 {
542   guestfs_main_loop *ml = guestfs_get_main_loop (g);
543   struct ls_ctx *ctx = (struct ls_ctx *) data;
544
545   /* This should definitely not happen. */
546   if (ctx->cb_sequence != 0) {
547     ctx->cb_sequence = 9999;
548     error (g, "%s: internal error: reply callback called twice", "guestfs_ls");
549     return;
550   }
551
552   ml->main_loop_quit (ml, g);
553
554   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
555     error (g, "%s: failed to parse reply header", "guestfs_ls");
556     return;
557   }
558   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
559     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
560       error (g, "%s: failed to parse reply error", "guestfs_ls");
561       return;
562     }
563     goto done;
564   }
565   if (!xdr_guestfs_ls_ret (xdr, &ctx->ret)) {
566     error (g, "%s: failed to parse reply", "guestfs_ls");
567     return;
568   }
569  done:
570   ctx->cb_sequence = 1;
571 }
572
573 char **guestfs_ls (guestfs_h *g,
574                 const char *directory)
575 {
576   struct guestfs_ls_args args;
577   struct ls_ctx ctx;
578   guestfs_main_loop *ml = guestfs_get_main_loop (g);
579   int serial;
580
581   if (check_state (g, "guestfs_ls") == -1) return NULL;
582   guestfs_set_busy (g);
583
584   memset (&ctx, 0, sizeof ctx);
585
586   args.directory = (char *) directory;
587   serial = guestfs__send_sync (g, GUESTFS_PROC_LS,
588         (xdrproc_t) xdr_guestfs_ls_args, (char *) &args);
589   if (serial == -1) {
590     guestfs_end_busy (g);
591     return NULL;
592   }
593
594   guestfs__switch_to_receiving (g);
595   ctx.cb_sequence = 0;
596   guestfs_set_reply_callback (g, ls_reply_cb, &ctx);
597   (void) ml->main_loop_run (ml, g);
598   guestfs_set_reply_callback (g, NULL, NULL);
599   if (ctx.cb_sequence != 1) {
600     error (g, "%s reply failed, see earlier error messages", "guestfs_ls");
601     guestfs_end_busy (g);
602     return NULL;
603   }
604
605   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LS, serial) == -1) {
606     guestfs_end_busy (g);
607     return NULL;
608   }
609
610   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
611     error (g, "%s", ctx.err.error_message);
612     free (ctx.err.error_message);
613     guestfs_end_busy (g);
614     return NULL;
615   }
616
617   guestfs_end_busy (g);
618   /* caller will free this, but we need to add a NULL entry */
619   ctx.ret.listing.listing_val =
620     safe_realloc (g, ctx.ret.listing.listing_val,
621                   sizeof (char *) * (ctx.ret.listing.listing_len + 1));
622   ctx.ret.listing.listing_val[ctx.ret.listing.listing_len] = NULL;
623   return ctx.ret.listing.listing_val;
624 }
625
626 struct list_devices_ctx {
627   /* This flag is set by the callbacks, so we know we've done
628    * the callbacks as expected, and in the right sequence.
629    * 0 = not called, 1 = reply_cb called.
630    */
631   int cb_sequence;
632   struct guestfs_message_header hdr;
633   struct guestfs_message_error err;
634   struct guestfs_list_devices_ret ret;
635 };
636
637 static void list_devices_reply_cb (guestfs_h *g, void *data, XDR *xdr)
638 {
639   guestfs_main_loop *ml = guestfs_get_main_loop (g);
640   struct list_devices_ctx *ctx = (struct list_devices_ctx *) data;
641
642   /* This should definitely not happen. */
643   if (ctx->cb_sequence != 0) {
644     ctx->cb_sequence = 9999;
645     error (g, "%s: internal error: reply callback called twice", "guestfs_list_devices");
646     return;
647   }
648
649   ml->main_loop_quit (ml, g);
650
651   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
652     error (g, "%s: failed to parse reply header", "guestfs_list_devices");
653     return;
654   }
655   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
656     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
657       error (g, "%s: failed to parse reply error", "guestfs_list_devices");
658       return;
659     }
660     goto done;
661   }
662   if (!xdr_guestfs_list_devices_ret (xdr, &ctx->ret)) {
663     error (g, "%s: failed to parse reply", "guestfs_list_devices");
664     return;
665   }
666  done:
667   ctx->cb_sequence = 1;
668 }
669
670 char **guestfs_list_devices (guestfs_h *g)
671 {
672   struct list_devices_ctx ctx;
673   guestfs_main_loop *ml = guestfs_get_main_loop (g);
674   int serial;
675
676   if (check_state (g, "guestfs_list_devices") == -1) return NULL;
677   guestfs_set_busy (g);
678
679   memset (&ctx, 0, sizeof ctx);
680
681   serial = guestfs__send_sync (g, GUESTFS_PROC_LIST_DEVICES, NULL, NULL);
682   if (serial == -1) {
683     guestfs_end_busy (g);
684     return NULL;
685   }
686
687   guestfs__switch_to_receiving (g);
688   ctx.cb_sequence = 0;
689   guestfs_set_reply_callback (g, list_devices_reply_cb, &ctx);
690   (void) ml->main_loop_run (ml, g);
691   guestfs_set_reply_callback (g, NULL, NULL);
692   if (ctx.cb_sequence != 1) {
693     error (g, "%s reply failed, see earlier error messages", "guestfs_list_devices");
694     guestfs_end_busy (g);
695     return NULL;
696   }
697
698   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LIST_DEVICES, serial) == -1) {
699     guestfs_end_busy (g);
700     return NULL;
701   }
702
703   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
704     error (g, "%s", ctx.err.error_message);
705     free (ctx.err.error_message);
706     guestfs_end_busy (g);
707     return NULL;
708   }
709
710   guestfs_end_busy (g);
711   /* caller will free this, but we need to add a NULL entry */
712   ctx.ret.devices.devices_val =
713     safe_realloc (g, ctx.ret.devices.devices_val,
714                   sizeof (char *) * (ctx.ret.devices.devices_len + 1));
715   ctx.ret.devices.devices_val[ctx.ret.devices.devices_len] = NULL;
716   return ctx.ret.devices.devices_val;
717 }
718
719 struct list_partitions_ctx {
720   /* This flag is set by the callbacks, so we know we've done
721    * the callbacks as expected, and in the right sequence.
722    * 0 = not called, 1 = reply_cb called.
723    */
724   int cb_sequence;
725   struct guestfs_message_header hdr;
726   struct guestfs_message_error err;
727   struct guestfs_list_partitions_ret ret;
728 };
729
730 static void list_partitions_reply_cb (guestfs_h *g, void *data, XDR *xdr)
731 {
732   guestfs_main_loop *ml = guestfs_get_main_loop (g);
733   struct list_partitions_ctx *ctx = (struct list_partitions_ctx *) data;
734
735   /* This should definitely not happen. */
736   if (ctx->cb_sequence != 0) {
737     ctx->cb_sequence = 9999;
738     error (g, "%s: internal error: reply callback called twice", "guestfs_list_partitions");
739     return;
740   }
741
742   ml->main_loop_quit (ml, g);
743
744   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
745     error (g, "%s: failed to parse reply header", "guestfs_list_partitions");
746     return;
747   }
748   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
749     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
750       error (g, "%s: failed to parse reply error", "guestfs_list_partitions");
751       return;
752     }
753     goto done;
754   }
755   if (!xdr_guestfs_list_partitions_ret (xdr, &ctx->ret)) {
756     error (g, "%s: failed to parse reply", "guestfs_list_partitions");
757     return;
758   }
759  done:
760   ctx->cb_sequence = 1;
761 }
762
763 char **guestfs_list_partitions (guestfs_h *g)
764 {
765   struct list_partitions_ctx ctx;
766   guestfs_main_loop *ml = guestfs_get_main_loop (g);
767   int serial;
768
769   if (check_state (g, "guestfs_list_partitions") == -1) return NULL;
770   guestfs_set_busy (g);
771
772   memset (&ctx, 0, sizeof ctx);
773
774   serial = guestfs__send_sync (g, GUESTFS_PROC_LIST_PARTITIONS, NULL, NULL);
775   if (serial == -1) {
776     guestfs_end_busy (g);
777     return NULL;
778   }
779
780   guestfs__switch_to_receiving (g);
781   ctx.cb_sequence = 0;
782   guestfs_set_reply_callback (g, list_partitions_reply_cb, &ctx);
783   (void) ml->main_loop_run (ml, g);
784   guestfs_set_reply_callback (g, NULL, NULL);
785   if (ctx.cb_sequence != 1) {
786     error (g, "%s reply failed, see earlier error messages", "guestfs_list_partitions");
787     guestfs_end_busy (g);
788     return NULL;
789   }
790
791   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LIST_PARTITIONS, serial) == -1) {
792     guestfs_end_busy (g);
793     return NULL;
794   }
795
796   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
797     error (g, "%s", ctx.err.error_message);
798     free (ctx.err.error_message);
799     guestfs_end_busy (g);
800     return NULL;
801   }
802
803   guestfs_end_busy (g);
804   /* caller will free this, but we need to add a NULL entry */
805   ctx.ret.partitions.partitions_val =
806     safe_realloc (g, ctx.ret.partitions.partitions_val,
807                   sizeof (char *) * (ctx.ret.partitions.partitions_len + 1));
808   ctx.ret.partitions.partitions_val[ctx.ret.partitions.partitions_len] = NULL;
809   return ctx.ret.partitions.partitions_val;
810 }
811
812 struct pvs_ctx {
813   /* This flag is set by the callbacks, so we know we've done
814    * the callbacks as expected, and in the right sequence.
815    * 0 = not called, 1 = reply_cb called.
816    */
817   int cb_sequence;
818   struct guestfs_message_header hdr;
819   struct guestfs_message_error err;
820   struct guestfs_pvs_ret ret;
821 };
822
823 static void pvs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
824 {
825   guestfs_main_loop *ml = guestfs_get_main_loop (g);
826   struct pvs_ctx *ctx = (struct pvs_ctx *) data;
827
828   /* This should definitely not happen. */
829   if (ctx->cb_sequence != 0) {
830     ctx->cb_sequence = 9999;
831     error (g, "%s: internal error: reply callback called twice", "guestfs_pvs");
832     return;
833   }
834
835   ml->main_loop_quit (ml, g);
836
837   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
838     error (g, "%s: failed to parse reply header", "guestfs_pvs");
839     return;
840   }
841   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
842     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
843       error (g, "%s: failed to parse reply error", "guestfs_pvs");
844       return;
845     }
846     goto done;
847   }
848   if (!xdr_guestfs_pvs_ret (xdr, &ctx->ret)) {
849     error (g, "%s: failed to parse reply", "guestfs_pvs");
850     return;
851   }
852  done:
853   ctx->cb_sequence = 1;
854 }
855
856 char **guestfs_pvs (guestfs_h *g)
857 {
858   struct pvs_ctx ctx;
859   guestfs_main_loop *ml = guestfs_get_main_loop (g);
860   int serial;
861
862   if (check_state (g, "guestfs_pvs") == -1) return NULL;
863   guestfs_set_busy (g);
864
865   memset (&ctx, 0, sizeof ctx);
866
867   serial = guestfs__send_sync (g, GUESTFS_PROC_PVS, NULL, NULL);
868   if (serial == -1) {
869     guestfs_end_busy (g);
870     return NULL;
871   }
872
873   guestfs__switch_to_receiving (g);
874   ctx.cb_sequence = 0;
875   guestfs_set_reply_callback (g, pvs_reply_cb, &ctx);
876   (void) ml->main_loop_run (ml, g);
877   guestfs_set_reply_callback (g, NULL, NULL);
878   if (ctx.cb_sequence != 1) {
879     error (g, "%s reply failed, see earlier error messages", "guestfs_pvs");
880     guestfs_end_busy (g);
881     return NULL;
882   }
883
884   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVS, serial) == -1) {
885     guestfs_end_busy (g);
886     return NULL;
887   }
888
889   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
890     error (g, "%s", ctx.err.error_message);
891     free (ctx.err.error_message);
892     guestfs_end_busy (g);
893     return NULL;
894   }
895
896   guestfs_end_busy (g);
897   /* caller will free this, but we need to add a NULL entry */
898   ctx.ret.physvols.physvols_val =
899     safe_realloc (g, ctx.ret.physvols.physvols_val,
900                   sizeof (char *) * (ctx.ret.physvols.physvols_len + 1));
901   ctx.ret.physvols.physvols_val[ctx.ret.physvols.physvols_len] = NULL;
902   return ctx.ret.physvols.physvols_val;
903 }
904
905 struct vgs_ctx {
906   /* This flag is set by the callbacks, so we know we've done
907    * the callbacks as expected, and in the right sequence.
908    * 0 = not called, 1 = reply_cb called.
909    */
910   int cb_sequence;
911   struct guestfs_message_header hdr;
912   struct guestfs_message_error err;
913   struct guestfs_vgs_ret ret;
914 };
915
916 static void vgs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
917 {
918   guestfs_main_loop *ml = guestfs_get_main_loop (g);
919   struct vgs_ctx *ctx = (struct vgs_ctx *) data;
920
921   /* This should definitely not happen. */
922   if (ctx->cb_sequence != 0) {
923     ctx->cb_sequence = 9999;
924     error (g, "%s: internal error: reply callback called twice", "guestfs_vgs");
925     return;
926   }
927
928   ml->main_loop_quit (ml, g);
929
930   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
931     error (g, "%s: failed to parse reply header", "guestfs_vgs");
932     return;
933   }
934   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
935     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
936       error (g, "%s: failed to parse reply error", "guestfs_vgs");
937       return;
938     }
939     goto done;
940   }
941   if (!xdr_guestfs_vgs_ret (xdr, &ctx->ret)) {
942     error (g, "%s: failed to parse reply", "guestfs_vgs");
943     return;
944   }
945  done:
946   ctx->cb_sequence = 1;
947 }
948
949 char **guestfs_vgs (guestfs_h *g)
950 {
951   struct vgs_ctx ctx;
952   guestfs_main_loop *ml = guestfs_get_main_loop (g);
953   int serial;
954
955   if (check_state (g, "guestfs_vgs") == -1) return NULL;
956   guestfs_set_busy (g);
957
958   memset (&ctx, 0, sizeof ctx);
959
960   serial = guestfs__send_sync (g, GUESTFS_PROC_VGS, NULL, NULL);
961   if (serial == -1) {
962     guestfs_end_busy (g);
963     return NULL;
964   }
965
966   guestfs__switch_to_receiving (g);
967   ctx.cb_sequence = 0;
968   guestfs_set_reply_callback (g, vgs_reply_cb, &ctx);
969   (void) ml->main_loop_run (ml, g);
970   guestfs_set_reply_callback (g, NULL, NULL);
971   if (ctx.cb_sequence != 1) {
972     error (g, "%s reply failed, see earlier error messages", "guestfs_vgs");
973     guestfs_end_busy (g);
974     return NULL;
975   }
976
977   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGS, serial) == -1) {
978     guestfs_end_busy (g);
979     return NULL;
980   }
981
982   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
983     error (g, "%s", ctx.err.error_message);
984     free (ctx.err.error_message);
985     guestfs_end_busy (g);
986     return NULL;
987   }
988
989   guestfs_end_busy (g);
990   /* caller will free this, but we need to add a NULL entry */
991   ctx.ret.volgroups.volgroups_val =
992     safe_realloc (g, ctx.ret.volgroups.volgroups_val,
993                   sizeof (char *) * (ctx.ret.volgroups.volgroups_len + 1));
994   ctx.ret.volgroups.volgroups_val[ctx.ret.volgroups.volgroups_len] = NULL;
995   return ctx.ret.volgroups.volgroups_val;
996 }
997
998 struct lvs_ctx {
999   /* This flag is set by the callbacks, so we know we've done
1000    * the callbacks as expected, and in the right sequence.
1001    * 0 = not called, 1 = reply_cb called.
1002    */
1003   int cb_sequence;
1004   struct guestfs_message_header hdr;
1005   struct guestfs_message_error err;
1006   struct guestfs_lvs_ret ret;
1007 };
1008
1009 static void lvs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1010 {
1011   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1012   struct lvs_ctx *ctx = (struct lvs_ctx *) data;
1013
1014   /* This should definitely not happen. */
1015   if (ctx->cb_sequence != 0) {
1016     ctx->cb_sequence = 9999;
1017     error (g, "%s: internal error: reply callback called twice", "guestfs_lvs");
1018     return;
1019   }
1020
1021   ml->main_loop_quit (ml, g);
1022
1023   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1024     error (g, "%s: failed to parse reply header", "guestfs_lvs");
1025     return;
1026   }
1027   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1028     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1029       error (g, "%s: failed to parse reply error", "guestfs_lvs");
1030       return;
1031     }
1032     goto done;
1033   }
1034   if (!xdr_guestfs_lvs_ret (xdr, &ctx->ret)) {
1035     error (g, "%s: failed to parse reply", "guestfs_lvs");
1036     return;
1037   }
1038  done:
1039   ctx->cb_sequence = 1;
1040 }
1041
1042 char **guestfs_lvs (guestfs_h *g)
1043 {
1044   struct lvs_ctx ctx;
1045   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1046   int serial;
1047
1048   if (check_state (g, "guestfs_lvs") == -1) return NULL;
1049   guestfs_set_busy (g);
1050
1051   memset (&ctx, 0, sizeof ctx);
1052
1053   serial = guestfs__send_sync (g, GUESTFS_PROC_LVS, NULL, NULL);
1054   if (serial == -1) {
1055     guestfs_end_busy (g);
1056     return NULL;
1057   }
1058
1059   guestfs__switch_to_receiving (g);
1060   ctx.cb_sequence = 0;
1061   guestfs_set_reply_callback (g, lvs_reply_cb, &ctx);
1062   (void) ml->main_loop_run (ml, g);
1063   guestfs_set_reply_callback (g, NULL, NULL);
1064   if (ctx.cb_sequence != 1) {
1065     error (g, "%s reply failed, see earlier error messages", "guestfs_lvs");
1066     guestfs_end_busy (g);
1067     return NULL;
1068   }
1069
1070   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVS, serial) == -1) {
1071     guestfs_end_busy (g);
1072     return NULL;
1073   }
1074
1075   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1076     error (g, "%s", ctx.err.error_message);
1077     free (ctx.err.error_message);
1078     guestfs_end_busy (g);
1079     return NULL;
1080   }
1081
1082   guestfs_end_busy (g);
1083   /* caller will free this, but we need to add a NULL entry */
1084   ctx.ret.logvols.logvols_val =
1085     safe_realloc (g, ctx.ret.logvols.logvols_val,
1086                   sizeof (char *) * (ctx.ret.logvols.logvols_len + 1));
1087   ctx.ret.logvols.logvols_val[ctx.ret.logvols.logvols_len] = NULL;
1088   return ctx.ret.logvols.logvols_val;
1089 }
1090
1091 struct pvs_full_ctx {
1092   /* This flag is set by the callbacks, so we know we've done
1093    * the callbacks as expected, and in the right sequence.
1094    * 0 = not called, 1 = reply_cb called.
1095    */
1096   int cb_sequence;
1097   struct guestfs_message_header hdr;
1098   struct guestfs_message_error err;
1099   struct guestfs_pvs_full_ret ret;
1100 };
1101
1102 static void pvs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1103 {
1104   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1105   struct pvs_full_ctx *ctx = (struct pvs_full_ctx *) data;
1106
1107   /* This should definitely not happen. */
1108   if (ctx->cb_sequence != 0) {
1109     ctx->cb_sequence = 9999;
1110     error (g, "%s: internal error: reply callback called twice", "guestfs_pvs_full");
1111     return;
1112   }
1113
1114   ml->main_loop_quit (ml, g);
1115
1116   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1117     error (g, "%s: failed to parse reply header", "guestfs_pvs_full");
1118     return;
1119   }
1120   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1121     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1122       error (g, "%s: failed to parse reply error", "guestfs_pvs_full");
1123       return;
1124     }
1125     goto done;
1126   }
1127   if (!xdr_guestfs_pvs_full_ret (xdr, &ctx->ret)) {
1128     error (g, "%s: failed to parse reply", "guestfs_pvs_full");
1129     return;
1130   }
1131  done:
1132   ctx->cb_sequence = 1;
1133 }
1134
1135 struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *g)
1136 {
1137   struct pvs_full_ctx ctx;
1138   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1139   int serial;
1140
1141   if (check_state (g, "guestfs_pvs_full") == -1) return NULL;
1142   guestfs_set_busy (g);
1143
1144   memset (&ctx, 0, sizeof ctx);
1145
1146   serial = guestfs__send_sync (g, GUESTFS_PROC_PVS_FULL, NULL, NULL);
1147   if (serial == -1) {
1148     guestfs_end_busy (g);
1149     return NULL;
1150   }
1151
1152   guestfs__switch_to_receiving (g);
1153   ctx.cb_sequence = 0;
1154   guestfs_set_reply_callback (g, pvs_full_reply_cb, &ctx);
1155   (void) ml->main_loop_run (ml, g);
1156   guestfs_set_reply_callback (g, NULL, NULL);
1157   if (ctx.cb_sequence != 1) {
1158     error (g, "%s reply failed, see earlier error messages", "guestfs_pvs_full");
1159     guestfs_end_busy (g);
1160     return NULL;
1161   }
1162
1163   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVS_FULL, serial) == -1) {
1164     guestfs_end_busy (g);
1165     return NULL;
1166   }
1167
1168   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1169     error (g, "%s", ctx.err.error_message);
1170     free (ctx.err.error_message);
1171     guestfs_end_busy (g);
1172     return NULL;
1173   }
1174
1175   guestfs_end_busy (g);
1176   /* caller will free this */
1177   return safe_memdup (g, &ctx.ret.physvols, sizeof (ctx.ret.physvols));
1178 }
1179
1180 struct vgs_full_ctx {
1181   /* This flag is set by the callbacks, so we know we've done
1182    * the callbacks as expected, and in the right sequence.
1183    * 0 = not called, 1 = reply_cb called.
1184    */
1185   int cb_sequence;
1186   struct guestfs_message_header hdr;
1187   struct guestfs_message_error err;
1188   struct guestfs_vgs_full_ret ret;
1189 };
1190
1191 static void vgs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1192 {
1193   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1194   struct vgs_full_ctx *ctx = (struct vgs_full_ctx *) data;
1195
1196   /* This should definitely not happen. */
1197   if (ctx->cb_sequence != 0) {
1198     ctx->cb_sequence = 9999;
1199     error (g, "%s: internal error: reply callback called twice", "guestfs_vgs_full");
1200     return;
1201   }
1202
1203   ml->main_loop_quit (ml, g);
1204
1205   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1206     error (g, "%s: failed to parse reply header", "guestfs_vgs_full");
1207     return;
1208   }
1209   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1210     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1211       error (g, "%s: failed to parse reply error", "guestfs_vgs_full");
1212       return;
1213     }
1214     goto done;
1215   }
1216   if (!xdr_guestfs_vgs_full_ret (xdr, &ctx->ret)) {
1217     error (g, "%s: failed to parse reply", "guestfs_vgs_full");
1218     return;
1219   }
1220  done:
1221   ctx->cb_sequence = 1;
1222 }
1223
1224 struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *g)
1225 {
1226   struct vgs_full_ctx ctx;
1227   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1228   int serial;
1229
1230   if (check_state (g, "guestfs_vgs_full") == -1) return NULL;
1231   guestfs_set_busy (g);
1232
1233   memset (&ctx, 0, sizeof ctx);
1234
1235   serial = guestfs__send_sync (g, GUESTFS_PROC_VGS_FULL, NULL, NULL);
1236   if (serial == -1) {
1237     guestfs_end_busy (g);
1238     return NULL;
1239   }
1240
1241   guestfs__switch_to_receiving (g);
1242   ctx.cb_sequence = 0;
1243   guestfs_set_reply_callback (g, vgs_full_reply_cb, &ctx);
1244   (void) ml->main_loop_run (ml, g);
1245   guestfs_set_reply_callback (g, NULL, NULL);
1246   if (ctx.cb_sequence != 1) {
1247     error (g, "%s reply failed, see earlier error messages", "guestfs_vgs_full");
1248     guestfs_end_busy (g);
1249     return NULL;
1250   }
1251
1252   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGS_FULL, serial) == -1) {
1253     guestfs_end_busy (g);
1254     return NULL;
1255   }
1256
1257   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1258     error (g, "%s", ctx.err.error_message);
1259     free (ctx.err.error_message);
1260     guestfs_end_busy (g);
1261     return NULL;
1262   }
1263
1264   guestfs_end_busy (g);
1265   /* caller will free this */
1266   return safe_memdup (g, &ctx.ret.volgroups, sizeof (ctx.ret.volgroups));
1267 }
1268
1269 struct lvs_full_ctx {
1270   /* This flag is set by the callbacks, so we know we've done
1271    * the callbacks as expected, and in the right sequence.
1272    * 0 = not called, 1 = reply_cb called.
1273    */
1274   int cb_sequence;
1275   struct guestfs_message_header hdr;
1276   struct guestfs_message_error err;
1277   struct guestfs_lvs_full_ret ret;
1278 };
1279
1280 static void lvs_full_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1281 {
1282   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1283   struct lvs_full_ctx *ctx = (struct lvs_full_ctx *) data;
1284
1285   /* This should definitely not happen. */
1286   if (ctx->cb_sequence != 0) {
1287     ctx->cb_sequence = 9999;
1288     error (g, "%s: internal error: reply callback called twice", "guestfs_lvs_full");
1289     return;
1290   }
1291
1292   ml->main_loop_quit (ml, g);
1293
1294   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1295     error (g, "%s: failed to parse reply header", "guestfs_lvs_full");
1296     return;
1297   }
1298   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1299     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1300       error (g, "%s: failed to parse reply error", "guestfs_lvs_full");
1301       return;
1302     }
1303     goto done;
1304   }
1305   if (!xdr_guestfs_lvs_full_ret (xdr, &ctx->ret)) {
1306     error (g, "%s: failed to parse reply", "guestfs_lvs_full");
1307     return;
1308   }
1309  done:
1310   ctx->cb_sequence = 1;
1311 }
1312
1313 struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *g)
1314 {
1315   struct lvs_full_ctx ctx;
1316   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1317   int serial;
1318
1319   if (check_state (g, "guestfs_lvs_full") == -1) return NULL;
1320   guestfs_set_busy (g);
1321
1322   memset (&ctx, 0, sizeof ctx);
1323
1324   serial = guestfs__send_sync (g, GUESTFS_PROC_LVS_FULL, NULL, NULL);
1325   if (serial == -1) {
1326     guestfs_end_busy (g);
1327     return NULL;
1328   }
1329
1330   guestfs__switch_to_receiving (g);
1331   ctx.cb_sequence = 0;
1332   guestfs_set_reply_callback (g, lvs_full_reply_cb, &ctx);
1333   (void) ml->main_loop_run (ml, g);
1334   guestfs_set_reply_callback (g, NULL, NULL);
1335   if (ctx.cb_sequence != 1) {
1336     error (g, "%s reply failed, see earlier error messages", "guestfs_lvs_full");
1337     guestfs_end_busy (g);
1338     return NULL;
1339   }
1340
1341   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVS_FULL, serial) == -1) {
1342     guestfs_end_busy (g);
1343     return NULL;
1344   }
1345
1346   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1347     error (g, "%s", ctx.err.error_message);
1348     free (ctx.err.error_message);
1349     guestfs_end_busy (g);
1350     return NULL;
1351   }
1352
1353   guestfs_end_busy (g);
1354   /* caller will free this */
1355   return safe_memdup (g, &ctx.ret.logvols, sizeof (ctx.ret.logvols));
1356 }
1357
1358 struct read_lines_ctx {
1359   /* This flag is set by the callbacks, so we know we've done
1360    * the callbacks as expected, and in the right sequence.
1361    * 0 = not called, 1 = reply_cb called.
1362    */
1363   int cb_sequence;
1364   struct guestfs_message_header hdr;
1365   struct guestfs_message_error err;
1366   struct guestfs_read_lines_ret ret;
1367 };
1368
1369 static void read_lines_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1370 {
1371   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1372   struct read_lines_ctx *ctx = (struct read_lines_ctx *) data;
1373
1374   /* This should definitely not happen. */
1375   if (ctx->cb_sequence != 0) {
1376     ctx->cb_sequence = 9999;
1377     error (g, "%s: internal error: reply callback called twice", "guestfs_read_lines");
1378     return;
1379   }
1380
1381   ml->main_loop_quit (ml, g);
1382
1383   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1384     error (g, "%s: failed to parse reply header", "guestfs_read_lines");
1385     return;
1386   }
1387   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1388     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1389       error (g, "%s: failed to parse reply error", "guestfs_read_lines");
1390       return;
1391     }
1392     goto done;
1393   }
1394   if (!xdr_guestfs_read_lines_ret (xdr, &ctx->ret)) {
1395     error (g, "%s: failed to parse reply", "guestfs_read_lines");
1396     return;
1397   }
1398  done:
1399   ctx->cb_sequence = 1;
1400 }
1401
1402 char **guestfs_read_lines (guestfs_h *g,
1403                 const char *path)
1404 {
1405   struct guestfs_read_lines_args args;
1406   struct read_lines_ctx ctx;
1407   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1408   int serial;
1409
1410   if (check_state (g, "guestfs_read_lines") == -1) return NULL;
1411   guestfs_set_busy (g);
1412
1413   memset (&ctx, 0, sizeof ctx);
1414
1415   args.path = (char *) path;
1416   serial = guestfs__send_sync (g, GUESTFS_PROC_READ_LINES,
1417         (xdrproc_t) xdr_guestfs_read_lines_args, (char *) &args);
1418   if (serial == -1) {
1419     guestfs_end_busy (g);
1420     return NULL;
1421   }
1422
1423   guestfs__switch_to_receiving (g);
1424   ctx.cb_sequence = 0;
1425   guestfs_set_reply_callback (g, read_lines_reply_cb, &ctx);
1426   (void) ml->main_loop_run (ml, g);
1427   guestfs_set_reply_callback (g, NULL, NULL);
1428   if (ctx.cb_sequence != 1) {
1429     error (g, "%s reply failed, see earlier error messages", "guestfs_read_lines");
1430     guestfs_end_busy (g);
1431     return NULL;
1432   }
1433
1434   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_READ_LINES, serial) == -1) {
1435     guestfs_end_busy (g);
1436     return NULL;
1437   }
1438
1439   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1440     error (g, "%s", ctx.err.error_message);
1441     free (ctx.err.error_message);
1442     guestfs_end_busy (g);
1443     return NULL;
1444   }
1445
1446   guestfs_end_busy (g);
1447   /* caller will free this, but we need to add a NULL entry */
1448   ctx.ret.lines.lines_val =
1449     safe_realloc (g, ctx.ret.lines.lines_val,
1450                   sizeof (char *) * (ctx.ret.lines.lines_len + 1));
1451   ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
1452   return ctx.ret.lines.lines_val;
1453 }
1454
1455 struct aug_init_ctx {
1456   /* This flag is set by the callbacks, so we know we've done
1457    * the callbacks as expected, and in the right sequence.
1458    * 0 = not called, 1 = reply_cb called.
1459    */
1460   int cb_sequence;
1461   struct guestfs_message_header hdr;
1462   struct guestfs_message_error err;
1463 };
1464
1465 static void aug_init_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1466 {
1467   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1468   struct aug_init_ctx *ctx = (struct aug_init_ctx *) data;
1469
1470   /* This should definitely not happen. */
1471   if (ctx->cb_sequence != 0) {
1472     ctx->cb_sequence = 9999;
1473     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_init");
1474     return;
1475   }
1476
1477   ml->main_loop_quit (ml, g);
1478
1479   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1480     error (g, "%s: failed to parse reply header", "guestfs_aug_init");
1481     return;
1482   }
1483   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1484     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1485       error (g, "%s: failed to parse reply error", "guestfs_aug_init");
1486       return;
1487     }
1488     goto done;
1489   }
1490  done:
1491   ctx->cb_sequence = 1;
1492 }
1493
1494 int guestfs_aug_init (guestfs_h *g,
1495                 const char *root,
1496                 int flags)
1497 {
1498   struct guestfs_aug_init_args args;
1499   struct aug_init_ctx ctx;
1500   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1501   int serial;
1502
1503   if (check_state (g, "guestfs_aug_init") == -1) return -1;
1504   guestfs_set_busy (g);
1505
1506   memset (&ctx, 0, sizeof ctx);
1507
1508   args.root = (char *) root;
1509   args.flags = flags;
1510   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_INIT,
1511         (xdrproc_t) xdr_guestfs_aug_init_args, (char *) &args);
1512   if (serial == -1) {
1513     guestfs_end_busy (g);
1514     return -1;
1515   }
1516
1517   guestfs__switch_to_receiving (g);
1518   ctx.cb_sequence = 0;
1519   guestfs_set_reply_callback (g, aug_init_reply_cb, &ctx);
1520   (void) ml->main_loop_run (ml, g);
1521   guestfs_set_reply_callback (g, NULL, NULL);
1522   if (ctx.cb_sequence != 1) {
1523     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_init");
1524     guestfs_end_busy (g);
1525     return -1;
1526   }
1527
1528   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_INIT, serial) == -1) {
1529     guestfs_end_busy (g);
1530     return -1;
1531   }
1532
1533   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1534     error (g, "%s", ctx.err.error_message);
1535     free (ctx.err.error_message);
1536     guestfs_end_busy (g);
1537     return -1;
1538   }
1539
1540   guestfs_end_busy (g);
1541   return 0;
1542 }
1543
1544 struct aug_close_ctx {
1545   /* This flag is set by the callbacks, so we know we've done
1546    * the callbacks as expected, and in the right sequence.
1547    * 0 = not called, 1 = reply_cb called.
1548    */
1549   int cb_sequence;
1550   struct guestfs_message_header hdr;
1551   struct guestfs_message_error err;
1552 };
1553
1554 static void aug_close_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1555 {
1556   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1557   struct aug_close_ctx *ctx = (struct aug_close_ctx *) data;
1558
1559   /* This should definitely not happen. */
1560   if (ctx->cb_sequence != 0) {
1561     ctx->cb_sequence = 9999;
1562     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_close");
1563     return;
1564   }
1565
1566   ml->main_loop_quit (ml, g);
1567
1568   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1569     error (g, "%s: failed to parse reply header", "guestfs_aug_close");
1570     return;
1571   }
1572   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1573     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1574       error (g, "%s: failed to parse reply error", "guestfs_aug_close");
1575       return;
1576     }
1577     goto done;
1578   }
1579  done:
1580   ctx->cb_sequence = 1;
1581 }
1582
1583 int guestfs_aug_close (guestfs_h *g)
1584 {
1585   struct aug_close_ctx ctx;
1586   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1587   int serial;
1588
1589   if (check_state (g, "guestfs_aug_close") == -1) return -1;
1590   guestfs_set_busy (g);
1591
1592   memset (&ctx, 0, sizeof ctx);
1593
1594   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_CLOSE, NULL, NULL);
1595   if (serial == -1) {
1596     guestfs_end_busy (g);
1597     return -1;
1598   }
1599
1600   guestfs__switch_to_receiving (g);
1601   ctx.cb_sequence = 0;
1602   guestfs_set_reply_callback (g, aug_close_reply_cb, &ctx);
1603   (void) ml->main_loop_run (ml, g);
1604   guestfs_set_reply_callback (g, NULL, NULL);
1605   if (ctx.cb_sequence != 1) {
1606     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_close");
1607     guestfs_end_busy (g);
1608     return -1;
1609   }
1610
1611   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_CLOSE, serial) == -1) {
1612     guestfs_end_busy (g);
1613     return -1;
1614   }
1615
1616   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1617     error (g, "%s", ctx.err.error_message);
1618     free (ctx.err.error_message);
1619     guestfs_end_busy (g);
1620     return -1;
1621   }
1622
1623   guestfs_end_busy (g);
1624   return 0;
1625 }
1626
1627 struct aug_defvar_ctx {
1628   /* This flag is set by the callbacks, so we know we've done
1629    * the callbacks as expected, and in the right sequence.
1630    * 0 = not called, 1 = reply_cb called.
1631    */
1632   int cb_sequence;
1633   struct guestfs_message_header hdr;
1634   struct guestfs_message_error err;
1635   struct guestfs_aug_defvar_ret ret;
1636 };
1637
1638 static void aug_defvar_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1639 {
1640   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1641   struct aug_defvar_ctx *ctx = (struct aug_defvar_ctx *) data;
1642
1643   /* This should definitely not happen. */
1644   if (ctx->cb_sequence != 0) {
1645     ctx->cb_sequence = 9999;
1646     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_defvar");
1647     return;
1648   }
1649
1650   ml->main_loop_quit (ml, g);
1651
1652   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1653     error (g, "%s: failed to parse reply header", "guestfs_aug_defvar");
1654     return;
1655   }
1656   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1657     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1658       error (g, "%s: failed to parse reply error", "guestfs_aug_defvar");
1659       return;
1660     }
1661     goto done;
1662   }
1663   if (!xdr_guestfs_aug_defvar_ret (xdr, &ctx->ret)) {
1664     error (g, "%s: failed to parse reply", "guestfs_aug_defvar");
1665     return;
1666   }
1667  done:
1668   ctx->cb_sequence = 1;
1669 }
1670
1671 int guestfs_aug_defvar (guestfs_h *g,
1672                 const char *name,
1673                 const char *expr)
1674 {
1675   struct guestfs_aug_defvar_args args;
1676   struct aug_defvar_ctx ctx;
1677   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1678   int serial;
1679
1680   if (check_state (g, "guestfs_aug_defvar") == -1) return -1;
1681   guestfs_set_busy (g);
1682
1683   memset (&ctx, 0, sizeof ctx);
1684
1685   args.name = (char *) name;
1686   args.expr = expr ? (char **) &expr : NULL;
1687   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_DEFVAR,
1688         (xdrproc_t) xdr_guestfs_aug_defvar_args, (char *) &args);
1689   if (serial == -1) {
1690     guestfs_end_busy (g);
1691     return -1;
1692   }
1693
1694   guestfs__switch_to_receiving (g);
1695   ctx.cb_sequence = 0;
1696   guestfs_set_reply_callback (g, aug_defvar_reply_cb, &ctx);
1697   (void) ml->main_loop_run (ml, g);
1698   guestfs_set_reply_callback (g, NULL, NULL);
1699   if (ctx.cb_sequence != 1) {
1700     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_defvar");
1701     guestfs_end_busy (g);
1702     return -1;
1703   }
1704
1705   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_DEFVAR, serial) == -1) {
1706     guestfs_end_busy (g);
1707     return -1;
1708   }
1709
1710   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1711     error (g, "%s", ctx.err.error_message);
1712     free (ctx.err.error_message);
1713     guestfs_end_busy (g);
1714     return -1;
1715   }
1716
1717   guestfs_end_busy (g);
1718   return ctx.ret.nrnodes;
1719 }
1720
1721 struct aug_defnode_ctx {
1722   /* This flag is set by the callbacks, so we know we've done
1723    * the callbacks as expected, and in the right sequence.
1724    * 0 = not called, 1 = reply_cb called.
1725    */
1726   int cb_sequence;
1727   struct guestfs_message_header hdr;
1728   struct guestfs_message_error err;
1729   struct guestfs_aug_defnode_ret ret;
1730 };
1731
1732 static void aug_defnode_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1733 {
1734   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1735   struct aug_defnode_ctx *ctx = (struct aug_defnode_ctx *) data;
1736
1737   /* This should definitely not happen. */
1738   if (ctx->cb_sequence != 0) {
1739     ctx->cb_sequence = 9999;
1740     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_defnode");
1741     return;
1742   }
1743
1744   ml->main_loop_quit (ml, g);
1745
1746   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1747     error (g, "%s: failed to parse reply header", "guestfs_aug_defnode");
1748     return;
1749   }
1750   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1751     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1752       error (g, "%s: failed to parse reply error", "guestfs_aug_defnode");
1753       return;
1754     }
1755     goto done;
1756   }
1757   if (!xdr_guestfs_aug_defnode_ret (xdr, &ctx->ret)) {
1758     error (g, "%s: failed to parse reply", "guestfs_aug_defnode");
1759     return;
1760   }
1761  done:
1762   ctx->cb_sequence = 1;
1763 }
1764
1765 struct guestfs_int_bool *guestfs_aug_defnode (guestfs_h *g,
1766                 const char *name,
1767                 const char *expr,
1768                 const char *val)
1769 {
1770   struct guestfs_aug_defnode_args args;
1771   struct aug_defnode_ctx ctx;
1772   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1773   int serial;
1774
1775   if (check_state (g, "guestfs_aug_defnode") == -1) return NULL;
1776   guestfs_set_busy (g);
1777
1778   memset (&ctx, 0, sizeof ctx);
1779
1780   args.name = (char *) name;
1781   args.expr = (char *) expr;
1782   args.val = (char *) val;
1783   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_DEFNODE,
1784         (xdrproc_t) xdr_guestfs_aug_defnode_args, (char *) &args);
1785   if (serial == -1) {
1786     guestfs_end_busy (g);
1787     return NULL;
1788   }
1789
1790   guestfs__switch_to_receiving (g);
1791   ctx.cb_sequence = 0;
1792   guestfs_set_reply_callback (g, aug_defnode_reply_cb, &ctx);
1793   (void) ml->main_loop_run (ml, g);
1794   guestfs_set_reply_callback (g, NULL, NULL);
1795   if (ctx.cb_sequence != 1) {
1796     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_defnode");
1797     guestfs_end_busy (g);
1798     return NULL;
1799   }
1800
1801   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_DEFNODE, serial) == -1) {
1802     guestfs_end_busy (g);
1803     return NULL;
1804   }
1805
1806   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1807     error (g, "%s", ctx.err.error_message);
1808     free (ctx.err.error_message);
1809     guestfs_end_busy (g);
1810     return NULL;
1811   }
1812
1813   guestfs_end_busy (g);
1814   /* caller with free this */
1815   return safe_memdup (g, &ctx.ret, sizeof (ctx.ret));
1816 }
1817
1818 struct aug_get_ctx {
1819   /* This flag is set by the callbacks, so we know we've done
1820    * the callbacks as expected, and in the right sequence.
1821    * 0 = not called, 1 = reply_cb called.
1822    */
1823   int cb_sequence;
1824   struct guestfs_message_header hdr;
1825   struct guestfs_message_error err;
1826   struct guestfs_aug_get_ret ret;
1827 };
1828
1829 static void aug_get_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1830 {
1831   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1832   struct aug_get_ctx *ctx = (struct aug_get_ctx *) data;
1833
1834   /* This should definitely not happen. */
1835   if (ctx->cb_sequence != 0) {
1836     ctx->cb_sequence = 9999;
1837     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_get");
1838     return;
1839   }
1840
1841   ml->main_loop_quit (ml, g);
1842
1843   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1844     error (g, "%s: failed to parse reply header", "guestfs_aug_get");
1845     return;
1846   }
1847   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1848     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1849       error (g, "%s: failed to parse reply error", "guestfs_aug_get");
1850       return;
1851     }
1852     goto done;
1853   }
1854   if (!xdr_guestfs_aug_get_ret (xdr, &ctx->ret)) {
1855     error (g, "%s: failed to parse reply", "guestfs_aug_get");
1856     return;
1857   }
1858  done:
1859   ctx->cb_sequence = 1;
1860 }
1861
1862 char *guestfs_aug_get (guestfs_h *g,
1863                 const char *path)
1864 {
1865   struct guestfs_aug_get_args args;
1866   struct aug_get_ctx ctx;
1867   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1868   int serial;
1869
1870   if (check_state (g, "guestfs_aug_get") == -1) return NULL;
1871   guestfs_set_busy (g);
1872
1873   memset (&ctx, 0, sizeof ctx);
1874
1875   args.path = (char *) path;
1876   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_GET,
1877         (xdrproc_t) xdr_guestfs_aug_get_args, (char *) &args);
1878   if (serial == -1) {
1879     guestfs_end_busy (g);
1880     return NULL;
1881   }
1882
1883   guestfs__switch_to_receiving (g);
1884   ctx.cb_sequence = 0;
1885   guestfs_set_reply_callback (g, aug_get_reply_cb, &ctx);
1886   (void) ml->main_loop_run (ml, g);
1887   guestfs_set_reply_callback (g, NULL, NULL);
1888   if (ctx.cb_sequence != 1) {
1889     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_get");
1890     guestfs_end_busy (g);
1891     return NULL;
1892   }
1893
1894   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_GET, serial) == -1) {
1895     guestfs_end_busy (g);
1896     return NULL;
1897   }
1898
1899   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1900     error (g, "%s", ctx.err.error_message);
1901     free (ctx.err.error_message);
1902     guestfs_end_busy (g);
1903     return NULL;
1904   }
1905
1906   guestfs_end_busy (g);
1907   return ctx.ret.val; /* caller will free */
1908 }
1909
1910 struct aug_set_ctx {
1911   /* This flag is set by the callbacks, so we know we've done
1912    * the callbacks as expected, and in the right sequence.
1913    * 0 = not called, 1 = reply_cb called.
1914    */
1915   int cb_sequence;
1916   struct guestfs_message_header hdr;
1917   struct guestfs_message_error err;
1918 };
1919
1920 static void aug_set_reply_cb (guestfs_h *g, void *data, XDR *xdr)
1921 {
1922   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1923   struct aug_set_ctx *ctx = (struct aug_set_ctx *) data;
1924
1925   /* This should definitely not happen. */
1926   if (ctx->cb_sequence != 0) {
1927     ctx->cb_sequence = 9999;
1928     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_set");
1929     return;
1930   }
1931
1932   ml->main_loop_quit (ml, g);
1933
1934   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
1935     error (g, "%s: failed to parse reply header", "guestfs_aug_set");
1936     return;
1937   }
1938   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
1939     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
1940       error (g, "%s: failed to parse reply error", "guestfs_aug_set");
1941       return;
1942     }
1943     goto done;
1944   }
1945  done:
1946   ctx->cb_sequence = 1;
1947 }
1948
1949 int guestfs_aug_set (guestfs_h *g,
1950                 const char *path,
1951                 const char *val)
1952 {
1953   struct guestfs_aug_set_args args;
1954   struct aug_set_ctx ctx;
1955   guestfs_main_loop *ml = guestfs_get_main_loop (g);
1956   int serial;
1957
1958   if (check_state (g, "guestfs_aug_set") == -1) return -1;
1959   guestfs_set_busy (g);
1960
1961   memset (&ctx, 0, sizeof ctx);
1962
1963   args.path = (char *) path;
1964   args.val = (char *) val;
1965   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_SET,
1966         (xdrproc_t) xdr_guestfs_aug_set_args, (char *) &args);
1967   if (serial == -1) {
1968     guestfs_end_busy (g);
1969     return -1;
1970   }
1971
1972   guestfs__switch_to_receiving (g);
1973   ctx.cb_sequence = 0;
1974   guestfs_set_reply_callback (g, aug_set_reply_cb, &ctx);
1975   (void) ml->main_loop_run (ml, g);
1976   guestfs_set_reply_callback (g, NULL, NULL);
1977   if (ctx.cb_sequence != 1) {
1978     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_set");
1979     guestfs_end_busy (g);
1980     return -1;
1981   }
1982
1983   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_SET, serial) == -1) {
1984     guestfs_end_busy (g);
1985     return -1;
1986   }
1987
1988   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
1989     error (g, "%s", ctx.err.error_message);
1990     free (ctx.err.error_message);
1991     guestfs_end_busy (g);
1992     return -1;
1993   }
1994
1995   guestfs_end_busy (g);
1996   return 0;
1997 }
1998
1999 struct aug_insert_ctx {
2000   /* This flag is set by the callbacks, so we know we've done
2001    * the callbacks as expected, and in the right sequence.
2002    * 0 = not called, 1 = reply_cb called.
2003    */
2004   int cb_sequence;
2005   struct guestfs_message_header hdr;
2006   struct guestfs_message_error err;
2007 };
2008
2009 static void aug_insert_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2010 {
2011   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2012   struct aug_insert_ctx *ctx = (struct aug_insert_ctx *) data;
2013
2014   /* This should definitely not happen. */
2015   if (ctx->cb_sequence != 0) {
2016     ctx->cb_sequence = 9999;
2017     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_insert");
2018     return;
2019   }
2020
2021   ml->main_loop_quit (ml, g);
2022
2023   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2024     error (g, "%s: failed to parse reply header", "guestfs_aug_insert");
2025     return;
2026   }
2027   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2028     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2029       error (g, "%s: failed to parse reply error", "guestfs_aug_insert");
2030       return;
2031     }
2032     goto done;
2033   }
2034  done:
2035   ctx->cb_sequence = 1;
2036 }
2037
2038 int guestfs_aug_insert (guestfs_h *g,
2039                 const char *path,
2040                 const char *label,
2041                 int before)
2042 {
2043   struct guestfs_aug_insert_args args;
2044   struct aug_insert_ctx ctx;
2045   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2046   int serial;
2047
2048   if (check_state (g, "guestfs_aug_insert") == -1) return -1;
2049   guestfs_set_busy (g);
2050
2051   memset (&ctx, 0, sizeof ctx);
2052
2053   args.path = (char *) path;
2054   args.label = (char *) label;
2055   args.before = before;
2056   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_INSERT,
2057         (xdrproc_t) xdr_guestfs_aug_insert_args, (char *) &args);
2058   if (serial == -1) {
2059     guestfs_end_busy (g);
2060     return -1;
2061   }
2062
2063   guestfs__switch_to_receiving (g);
2064   ctx.cb_sequence = 0;
2065   guestfs_set_reply_callback (g, aug_insert_reply_cb, &ctx);
2066   (void) ml->main_loop_run (ml, g);
2067   guestfs_set_reply_callback (g, NULL, NULL);
2068   if (ctx.cb_sequence != 1) {
2069     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_insert");
2070     guestfs_end_busy (g);
2071     return -1;
2072   }
2073
2074   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_INSERT, serial) == -1) {
2075     guestfs_end_busy (g);
2076     return -1;
2077   }
2078
2079   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2080     error (g, "%s", ctx.err.error_message);
2081     free (ctx.err.error_message);
2082     guestfs_end_busy (g);
2083     return -1;
2084   }
2085
2086   guestfs_end_busy (g);
2087   return 0;
2088 }
2089
2090 struct aug_rm_ctx {
2091   /* This flag is set by the callbacks, so we know we've done
2092    * the callbacks as expected, and in the right sequence.
2093    * 0 = not called, 1 = reply_cb called.
2094    */
2095   int cb_sequence;
2096   struct guestfs_message_header hdr;
2097   struct guestfs_message_error err;
2098   struct guestfs_aug_rm_ret ret;
2099 };
2100
2101 static void aug_rm_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2102 {
2103   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2104   struct aug_rm_ctx *ctx = (struct aug_rm_ctx *) data;
2105
2106   /* This should definitely not happen. */
2107   if (ctx->cb_sequence != 0) {
2108     ctx->cb_sequence = 9999;
2109     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_rm");
2110     return;
2111   }
2112
2113   ml->main_loop_quit (ml, g);
2114
2115   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2116     error (g, "%s: failed to parse reply header", "guestfs_aug_rm");
2117     return;
2118   }
2119   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2120     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2121       error (g, "%s: failed to parse reply error", "guestfs_aug_rm");
2122       return;
2123     }
2124     goto done;
2125   }
2126   if (!xdr_guestfs_aug_rm_ret (xdr, &ctx->ret)) {
2127     error (g, "%s: failed to parse reply", "guestfs_aug_rm");
2128     return;
2129   }
2130  done:
2131   ctx->cb_sequence = 1;
2132 }
2133
2134 int guestfs_aug_rm (guestfs_h *g,
2135                 const char *path)
2136 {
2137   struct guestfs_aug_rm_args args;
2138   struct aug_rm_ctx ctx;
2139   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2140   int serial;
2141
2142   if (check_state (g, "guestfs_aug_rm") == -1) return -1;
2143   guestfs_set_busy (g);
2144
2145   memset (&ctx, 0, sizeof ctx);
2146
2147   args.path = (char *) path;
2148   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_RM,
2149         (xdrproc_t) xdr_guestfs_aug_rm_args, (char *) &args);
2150   if (serial == -1) {
2151     guestfs_end_busy (g);
2152     return -1;
2153   }
2154
2155   guestfs__switch_to_receiving (g);
2156   ctx.cb_sequence = 0;
2157   guestfs_set_reply_callback (g, aug_rm_reply_cb, &ctx);
2158   (void) ml->main_loop_run (ml, g);
2159   guestfs_set_reply_callback (g, NULL, NULL);
2160   if (ctx.cb_sequence != 1) {
2161     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_rm");
2162     guestfs_end_busy (g);
2163     return -1;
2164   }
2165
2166   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_RM, serial) == -1) {
2167     guestfs_end_busy (g);
2168     return -1;
2169   }
2170
2171   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2172     error (g, "%s", ctx.err.error_message);
2173     free (ctx.err.error_message);
2174     guestfs_end_busy (g);
2175     return -1;
2176   }
2177
2178   guestfs_end_busy (g);
2179   return ctx.ret.nrnodes;
2180 }
2181
2182 struct aug_mv_ctx {
2183   /* This flag is set by the callbacks, so we know we've done
2184    * the callbacks as expected, and in the right sequence.
2185    * 0 = not called, 1 = reply_cb called.
2186    */
2187   int cb_sequence;
2188   struct guestfs_message_header hdr;
2189   struct guestfs_message_error err;
2190 };
2191
2192 static void aug_mv_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2193 {
2194   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2195   struct aug_mv_ctx *ctx = (struct aug_mv_ctx *) data;
2196
2197   /* This should definitely not happen. */
2198   if (ctx->cb_sequence != 0) {
2199     ctx->cb_sequence = 9999;
2200     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_mv");
2201     return;
2202   }
2203
2204   ml->main_loop_quit (ml, g);
2205
2206   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2207     error (g, "%s: failed to parse reply header", "guestfs_aug_mv");
2208     return;
2209   }
2210   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2211     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2212       error (g, "%s: failed to parse reply error", "guestfs_aug_mv");
2213       return;
2214     }
2215     goto done;
2216   }
2217  done:
2218   ctx->cb_sequence = 1;
2219 }
2220
2221 int guestfs_aug_mv (guestfs_h *g,
2222                 const char *src,
2223                 const char *dest)
2224 {
2225   struct guestfs_aug_mv_args args;
2226   struct aug_mv_ctx ctx;
2227   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2228   int serial;
2229
2230   if (check_state (g, "guestfs_aug_mv") == -1) return -1;
2231   guestfs_set_busy (g);
2232
2233   memset (&ctx, 0, sizeof ctx);
2234
2235   args.src = (char *) src;
2236   args.dest = (char *) dest;
2237   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_MV,
2238         (xdrproc_t) xdr_guestfs_aug_mv_args, (char *) &args);
2239   if (serial == -1) {
2240     guestfs_end_busy (g);
2241     return -1;
2242   }
2243
2244   guestfs__switch_to_receiving (g);
2245   ctx.cb_sequence = 0;
2246   guestfs_set_reply_callback (g, aug_mv_reply_cb, &ctx);
2247   (void) ml->main_loop_run (ml, g);
2248   guestfs_set_reply_callback (g, NULL, NULL);
2249   if (ctx.cb_sequence != 1) {
2250     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_mv");
2251     guestfs_end_busy (g);
2252     return -1;
2253   }
2254
2255   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_MV, serial) == -1) {
2256     guestfs_end_busy (g);
2257     return -1;
2258   }
2259
2260   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2261     error (g, "%s", ctx.err.error_message);
2262     free (ctx.err.error_message);
2263     guestfs_end_busy (g);
2264     return -1;
2265   }
2266
2267   guestfs_end_busy (g);
2268   return 0;
2269 }
2270
2271 struct aug_match_ctx {
2272   /* This flag is set by the callbacks, so we know we've done
2273    * the callbacks as expected, and in the right sequence.
2274    * 0 = not called, 1 = reply_cb called.
2275    */
2276   int cb_sequence;
2277   struct guestfs_message_header hdr;
2278   struct guestfs_message_error err;
2279   struct guestfs_aug_match_ret ret;
2280 };
2281
2282 static void aug_match_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2283 {
2284   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2285   struct aug_match_ctx *ctx = (struct aug_match_ctx *) data;
2286
2287   /* This should definitely not happen. */
2288   if (ctx->cb_sequence != 0) {
2289     ctx->cb_sequence = 9999;
2290     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_match");
2291     return;
2292   }
2293
2294   ml->main_loop_quit (ml, g);
2295
2296   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2297     error (g, "%s: failed to parse reply header", "guestfs_aug_match");
2298     return;
2299   }
2300   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2301     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2302       error (g, "%s: failed to parse reply error", "guestfs_aug_match");
2303       return;
2304     }
2305     goto done;
2306   }
2307   if (!xdr_guestfs_aug_match_ret (xdr, &ctx->ret)) {
2308     error (g, "%s: failed to parse reply", "guestfs_aug_match");
2309     return;
2310   }
2311  done:
2312   ctx->cb_sequence = 1;
2313 }
2314
2315 char **guestfs_aug_match (guestfs_h *g,
2316                 const char *path)
2317 {
2318   struct guestfs_aug_match_args args;
2319   struct aug_match_ctx ctx;
2320   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2321   int serial;
2322
2323   if (check_state (g, "guestfs_aug_match") == -1) return NULL;
2324   guestfs_set_busy (g);
2325
2326   memset (&ctx, 0, sizeof ctx);
2327
2328   args.path = (char *) path;
2329   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_MATCH,
2330         (xdrproc_t) xdr_guestfs_aug_match_args, (char *) &args);
2331   if (serial == -1) {
2332     guestfs_end_busy (g);
2333     return NULL;
2334   }
2335
2336   guestfs__switch_to_receiving (g);
2337   ctx.cb_sequence = 0;
2338   guestfs_set_reply_callback (g, aug_match_reply_cb, &ctx);
2339   (void) ml->main_loop_run (ml, g);
2340   guestfs_set_reply_callback (g, NULL, NULL);
2341   if (ctx.cb_sequence != 1) {
2342     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_match");
2343     guestfs_end_busy (g);
2344     return NULL;
2345   }
2346
2347   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_MATCH, serial) == -1) {
2348     guestfs_end_busy (g);
2349     return NULL;
2350   }
2351
2352   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2353     error (g, "%s", ctx.err.error_message);
2354     free (ctx.err.error_message);
2355     guestfs_end_busy (g);
2356     return NULL;
2357   }
2358
2359   guestfs_end_busy (g);
2360   /* caller will free this, but we need to add a NULL entry */
2361   ctx.ret.matches.matches_val =
2362     safe_realloc (g, ctx.ret.matches.matches_val,
2363                   sizeof (char *) * (ctx.ret.matches.matches_len + 1));
2364   ctx.ret.matches.matches_val[ctx.ret.matches.matches_len] = NULL;
2365   return ctx.ret.matches.matches_val;
2366 }
2367
2368 struct aug_save_ctx {
2369   /* This flag is set by the callbacks, so we know we've done
2370    * the callbacks as expected, and in the right sequence.
2371    * 0 = not called, 1 = reply_cb called.
2372    */
2373   int cb_sequence;
2374   struct guestfs_message_header hdr;
2375   struct guestfs_message_error err;
2376 };
2377
2378 static void aug_save_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2379 {
2380   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2381   struct aug_save_ctx *ctx = (struct aug_save_ctx *) data;
2382
2383   /* This should definitely not happen. */
2384   if (ctx->cb_sequence != 0) {
2385     ctx->cb_sequence = 9999;
2386     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_save");
2387     return;
2388   }
2389
2390   ml->main_loop_quit (ml, g);
2391
2392   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2393     error (g, "%s: failed to parse reply header", "guestfs_aug_save");
2394     return;
2395   }
2396   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2397     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2398       error (g, "%s: failed to parse reply error", "guestfs_aug_save");
2399       return;
2400     }
2401     goto done;
2402   }
2403  done:
2404   ctx->cb_sequence = 1;
2405 }
2406
2407 int guestfs_aug_save (guestfs_h *g)
2408 {
2409   struct aug_save_ctx ctx;
2410   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2411   int serial;
2412
2413   if (check_state (g, "guestfs_aug_save") == -1) return -1;
2414   guestfs_set_busy (g);
2415
2416   memset (&ctx, 0, sizeof ctx);
2417
2418   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_SAVE, NULL, NULL);
2419   if (serial == -1) {
2420     guestfs_end_busy (g);
2421     return -1;
2422   }
2423
2424   guestfs__switch_to_receiving (g);
2425   ctx.cb_sequence = 0;
2426   guestfs_set_reply_callback (g, aug_save_reply_cb, &ctx);
2427   (void) ml->main_loop_run (ml, g);
2428   guestfs_set_reply_callback (g, NULL, NULL);
2429   if (ctx.cb_sequence != 1) {
2430     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_save");
2431     guestfs_end_busy (g);
2432     return -1;
2433   }
2434
2435   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_SAVE, serial) == -1) {
2436     guestfs_end_busy (g);
2437     return -1;
2438   }
2439
2440   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2441     error (g, "%s", ctx.err.error_message);
2442     free (ctx.err.error_message);
2443     guestfs_end_busy (g);
2444     return -1;
2445   }
2446
2447   guestfs_end_busy (g);
2448   return 0;
2449 }
2450
2451 struct aug_load_ctx {
2452   /* This flag is set by the callbacks, so we know we've done
2453    * the callbacks as expected, and in the right sequence.
2454    * 0 = not called, 1 = reply_cb called.
2455    */
2456   int cb_sequence;
2457   struct guestfs_message_header hdr;
2458   struct guestfs_message_error err;
2459 };
2460
2461 static void aug_load_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2462 {
2463   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2464   struct aug_load_ctx *ctx = (struct aug_load_ctx *) data;
2465
2466   /* This should definitely not happen. */
2467   if (ctx->cb_sequence != 0) {
2468     ctx->cb_sequence = 9999;
2469     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_load");
2470     return;
2471   }
2472
2473   ml->main_loop_quit (ml, g);
2474
2475   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2476     error (g, "%s: failed to parse reply header", "guestfs_aug_load");
2477     return;
2478   }
2479   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2480     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2481       error (g, "%s: failed to parse reply error", "guestfs_aug_load");
2482       return;
2483     }
2484     goto done;
2485   }
2486  done:
2487   ctx->cb_sequence = 1;
2488 }
2489
2490 int guestfs_aug_load (guestfs_h *g)
2491 {
2492   struct aug_load_ctx ctx;
2493   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2494   int serial;
2495
2496   if (check_state (g, "guestfs_aug_load") == -1) return -1;
2497   guestfs_set_busy (g);
2498
2499   memset (&ctx, 0, sizeof ctx);
2500
2501   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_LOAD, NULL, NULL);
2502   if (serial == -1) {
2503     guestfs_end_busy (g);
2504     return -1;
2505   }
2506
2507   guestfs__switch_to_receiving (g);
2508   ctx.cb_sequence = 0;
2509   guestfs_set_reply_callback (g, aug_load_reply_cb, &ctx);
2510   (void) ml->main_loop_run (ml, g);
2511   guestfs_set_reply_callback (g, NULL, NULL);
2512   if (ctx.cb_sequence != 1) {
2513     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_load");
2514     guestfs_end_busy (g);
2515     return -1;
2516   }
2517
2518   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_LOAD, serial) == -1) {
2519     guestfs_end_busy (g);
2520     return -1;
2521   }
2522
2523   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2524     error (g, "%s", ctx.err.error_message);
2525     free (ctx.err.error_message);
2526     guestfs_end_busy (g);
2527     return -1;
2528   }
2529
2530   guestfs_end_busy (g);
2531   return 0;
2532 }
2533
2534 struct aug_ls_ctx {
2535   /* This flag is set by the callbacks, so we know we've done
2536    * the callbacks as expected, and in the right sequence.
2537    * 0 = not called, 1 = reply_cb called.
2538    */
2539   int cb_sequence;
2540   struct guestfs_message_header hdr;
2541   struct guestfs_message_error err;
2542   struct guestfs_aug_ls_ret ret;
2543 };
2544
2545 static void aug_ls_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2546 {
2547   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2548   struct aug_ls_ctx *ctx = (struct aug_ls_ctx *) data;
2549
2550   /* This should definitely not happen. */
2551   if (ctx->cb_sequence != 0) {
2552     ctx->cb_sequence = 9999;
2553     error (g, "%s: internal error: reply callback called twice", "guestfs_aug_ls");
2554     return;
2555   }
2556
2557   ml->main_loop_quit (ml, g);
2558
2559   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2560     error (g, "%s: failed to parse reply header", "guestfs_aug_ls");
2561     return;
2562   }
2563   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2564     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2565       error (g, "%s: failed to parse reply error", "guestfs_aug_ls");
2566       return;
2567     }
2568     goto done;
2569   }
2570   if (!xdr_guestfs_aug_ls_ret (xdr, &ctx->ret)) {
2571     error (g, "%s: failed to parse reply", "guestfs_aug_ls");
2572     return;
2573   }
2574  done:
2575   ctx->cb_sequence = 1;
2576 }
2577
2578 char **guestfs_aug_ls (guestfs_h *g,
2579                 const char *path)
2580 {
2581   struct guestfs_aug_ls_args args;
2582   struct aug_ls_ctx ctx;
2583   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2584   int serial;
2585
2586   if (check_state (g, "guestfs_aug_ls") == -1) return NULL;
2587   guestfs_set_busy (g);
2588
2589   memset (&ctx, 0, sizeof ctx);
2590
2591   args.path = (char *) path;
2592   serial = guestfs__send_sync (g, GUESTFS_PROC_AUG_LS,
2593         (xdrproc_t) xdr_guestfs_aug_ls_args, (char *) &args);
2594   if (serial == -1) {
2595     guestfs_end_busy (g);
2596     return NULL;
2597   }
2598
2599   guestfs__switch_to_receiving (g);
2600   ctx.cb_sequence = 0;
2601   guestfs_set_reply_callback (g, aug_ls_reply_cb, &ctx);
2602   (void) ml->main_loop_run (ml, g);
2603   guestfs_set_reply_callback (g, NULL, NULL);
2604   if (ctx.cb_sequence != 1) {
2605     error (g, "%s reply failed, see earlier error messages", "guestfs_aug_ls");
2606     guestfs_end_busy (g);
2607     return NULL;
2608   }
2609
2610   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_AUG_LS, serial) == -1) {
2611     guestfs_end_busy (g);
2612     return NULL;
2613   }
2614
2615   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2616     error (g, "%s", ctx.err.error_message);
2617     free (ctx.err.error_message);
2618     guestfs_end_busy (g);
2619     return NULL;
2620   }
2621
2622   guestfs_end_busy (g);
2623   /* caller will free this, but we need to add a NULL entry */
2624   ctx.ret.matches.matches_val =
2625     safe_realloc (g, ctx.ret.matches.matches_val,
2626                   sizeof (char *) * (ctx.ret.matches.matches_len + 1));
2627   ctx.ret.matches.matches_val[ctx.ret.matches.matches_len] = NULL;
2628   return ctx.ret.matches.matches_val;
2629 }
2630
2631 struct rm_ctx {
2632   /* This flag is set by the callbacks, so we know we've done
2633    * the callbacks as expected, and in the right sequence.
2634    * 0 = not called, 1 = reply_cb called.
2635    */
2636   int cb_sequence;
2637   struct guestfs_message_header hdr;
2638   struct guestfs_message_error err;
2639 };
2640
2641 static void rm_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2642 {
2643   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2644   struct rm_ctx *ctx = (struct rm_ctx *) data;
2645
2646   /* This should definitely not happen. */
2647   if (ctx->cb_sequence != 0) {
2648     ctx->cb_sequence = 9999;
2649     error (g, "%s: internal error: reply callback called twice", "guestfs_rm");
2650     return;
2651   }
2652
2653   ml->main_loop_quit (ml, g);
2654
2655   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2656     error (g, "%s: failed to parse reply header", "guestfs_rm");
2657     return;
2658   }
2659   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2660     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2661       error (g, "%s: failed to parse reply error", "guestfs_rm");
2662       return;
2663     }
2664     goto done;
2665   }
2666  done:
2667   ctx->cb_sequence = 1;
2668 }
2669
2670 int guestfs_rm (guestfs_h *g,
2671                 const char *path)
2672 {
2673   struct guestfs_rm_args args;
2674   struct rm_ctx ctx;
2675   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2676   int serial;
2677
2678   if (check_state (g, "guestfs_rm") == -1) return -1;
2679   guestfs_set_busy (g);
2680
2681   memset (&ctx, 0, sizeof ctx);
2682
2683   args.path = (char *) path;
2684   serial = guestfs__send_sync (g, GUESTFS_PROC_RM,
2685         (xdrproc_t) xdr_guestfs_rm_args, (char *) &args);
2686   if (serial == -1) {
2687     guestfs_end_busy (g);
2688     return -1;
2689   }
2690
2691   guestfs__switch_to_receiving (g);
2692   ctx.cb_sequence = 0;
2693   guestfs_set_reply_callback (g, rm_reply_cb, &ctx);
2694   (void) ml->main_loop_run (ml, g);
2695   guestfs_set_reply_callback (g, NULL, NULL);
2696   if (ctx.cb_sequence != 1) {
2697     error (g, "%s reply failed, see earlier error messages", "guestfs_rm");
2698     guestfs_end_busy (g);
2699     return -1;
2700   }
2701
2702   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RM, serial) == -1) {
2703     guestfs_end_busy (g);
2704     return -1;
2705   }
2706
2707   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2708     error (g, "%s", ctx.err.error_message);
2709     free (ctx.err.error_message);
2710     guestfs_end_busy (g);
2711     return -1;
2712   }
2713
2714   guestfs_end_busy (g);
2715   return 0;
2716 }
2717
2718 struct rmdir_ctx {
2719   /* This flag is set by the callbacks, so we know we've done
2720    * the callbacks as expected, and in the right sequence.
2721    * 0 = not called, 1 = reply_cb called.
2722    */
2723   int cb_sequence;
2724   struct guestfs_message_header hdr;
2725   struct guestfs_message_error err;
2726 };
2727
2728 static void rmdir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2729 {
2730   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2731   struct rmdir_ctx *ctx = (struct rmdir_ctx *) data;
2732
2733   /* This should definitely not happen. */
2734   if (ctx->cb_sequence != 0) {
2735     ctx->cb_sequence = 9999;
2736     error (g, "%s: internal error: reply callback called twice", "guestfs_rmdir");
2737     return;
2738   }
2739
2740   ml->main_loop_quit (ml, g);
2741
2742   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2743     error (g, "%s: failed to parse reply header", "guestfs_rmdir");
2744     return;
2745   }
2746   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2747     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2748       error (g, "%s: failed to parse reply error", "guestfs_rmdir");
2749       return;
2750     }
2751     goto done;
2752   }
2753  done:
2754   ctx->cb_sequence = 1;
2755 }
2756
2757 int guestfs_rmdir (guestfs_h *g,
2758                 const char *path)
2759 {
2760   struct guestfs_rmdir_args args;
2761   struct rmdir_ctx ctx;
2762   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2763   int serial;
2764
2765   if (check_state (g, "guestfs_rmdir") == -1) return -1;
2766   guestfs_set_busy (g);
2767
2768   memset (&ctx, 0, sizeof ctx);
2769
2770   args.path = (char *) path;
2771   serial = guestfs__send_sync (g, GUESTFS_PROC_RMDIR,
2772         (xdrproc_t) xdr_guestfs_rmdir_args, (char *) &args);
2773   if (serial == -1) {
2774     guestfs_end_busy (g);
2775     return -1;
2776   }
2777
2778   guestfs__switch_to_receiving (g);
2779   ctx.cb_sequence = 0;
2780   guestfs_set_reply_callback (g, rmdir_reply_cb, &ctx);
2781   (void) ml->main_loop_run (ml, g);
2782   guestfs_set_reply_callback (g, NULL, NULL);
2783   if (ctx.cb_sequence != 1) {
2784     error (g, "%s reply failed, see earlier error messages", "guestfs_rmdir");
2785     guestfs_end_busy (g);
2786     return -1;
2787   }
2788
2789   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RMDIR, serial) == -1) {
2790     guestfs_end_busy (g);
2791     return -1;
2792   }
2793
2794   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2795     error (g, "%s", ctx.err.error_message);
2796     free (ctx.err.error_message);
2797     guestfs_end_busy (g);
2798     return -1;
2799   }
2800
2801   guestfs_end_busy (g);
2802   return 0;
2803 }
2804
2805 struct rm_rf_ctx {
2806   /* This flag is set by the callbacks, so we know we've done
2807    * the callbacks as expected, and in the right sequence.
2808    * 0 = not called, 1 = reply_cb called.
2809    */
2810   int cb_sequence;
2811   struct guestfs_message_header hdr;
2812   struct guestfs_message_error err;
2813 };
2814
2815 static void rm_rf_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2816 {
2817   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2818   struct rm_rf_ctx *ctx = (struct rm_rf_ctx *) data;
2819
2820   /* This should definitely not happen. */
2821   if (ctx->cb_sequence != 0) {
2822     ctx->cb_sequence = 9999;
2823     error (g, "%s: internal error: reply callback called twice", "guestfs_rm_rf");
2824     return;
2825   }
2826
2827   ml->main_loop_quit (ml, g);
2828
2829   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2830     error (g, "%s: failed to parse reply header", "guestfs_rm_rf");
2831     return;
2832   }
2833   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2834     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2835       error (g, "%s: failed to parse reply error", "guestfs_rm_rf");
2836       return;
2837     }
2838     goto done;
2839   }
2840  done:
2841   ctx->cb_sequence = 1;
2842 }
2843
2844 int guestfs_rm_rf (guestfs_h *g,
2845                 const char *path)
2846 {
2847   struct guestfs_rm_rf_args args;
2848   struct rm_rf_ctx ctx;
2849   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2850   int serial;
2851
2852   if (check_state (g, "guestfs_rm_rf") == -1) return -1;
2853   guestfs_set_busy (g);
2854
2855   memset (&ctx, 0, sizeof ctx);
2856
2857   args.path = (char *) path;
2858   serial = guestfs__send_sync (g, GUESTFS_PROC_RM_RF,
2859         (xdrproc_t) xdr_guestfs_rm_rf_args, (char *) &args);
2860   if (serial == -1) {
2861     guestfs_end_busy (g);
2862     return -1;
2863   }
2864
2865   guestfs__switch_to_receiving (g);
2866   ctx.cb_sequence = 0;
2867   guestfs_set_reply_callback (g, rm_rf_reply_cb, &ctx);
2868   (void) ml->main_loop_run (ml, g);
2869   guestfs_set_reply_callback (g, NULL, NULL);
2870   if (ctx.cb_sequence != 1) {
2871     error (g, "%s reply failed, see earlier error messages", "guestfs_rm_rf");
2872     guestfs_end_busy (g);
2873     return -1;
2874   }
2875
2876   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RM_RF, serial) == -1) {
2877     guestfs_end_busy (g);
2878     return -1;
2879   }
2880
2881   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2882     error (g, "%s", ctx.err.error_message);
2883     free (ctx.err.error_message);
2884     guestfs_end_busy (g);
2885     return -1;
2886   }
2887
2888   guestfs_end_busy (g);
2889   return 0;
2890 }
2891
2892 struct mkdir_ctx {
2893   /* This flag is set by the callbacks, so we know we've done
2894    * the callbacks as expected, and in the right sequence.
2895    * 0 = not called, 1 = reply_cb called.
2896    */
2897   int cb_sequence;
2898   struct guestfs_message_header hdr;
2899   struct guestfs_message_error err;
2900 };
2901
2902 static void mkdir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2903 {
2904   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2905   struct mkdir_ctx *ctx = (struct mkdir_ctx *) data;
2906
2907   /* This should definitely not happen. */
2908   if (ctx->cb_sequence != 0) {
2909     ctx->cb_sequence = 9999;
2910     error (g, "%s: internal error: reply callback called twice", "guestfs_mkdir");
2911     return;
2912   }
2913
2914   ml->main_loop_quit (ml, g);
2915
2916   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
2917     error (g, "%s: failed to parse reply header", "guestfs_mkdir");
2918     return;
2919   }
2920   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
2921     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
2922       error (g, "%s: failed to parse reply error", "guestfs_mkdir");
2923       return;
2924     }
2925     goto done;
2926   }
2927  done:
2928   ctx->cb_sequence = 1;
2929 }
2930
2931 int guestfs_mkdir (guestfs_h *g,
2932                 const char *path)
2933 {
2934   struct guestfs_mkdir_args args;
2935   struct mkdir_ctx ctx;
2936   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2937   int serial;
2938
2939   if (check_state (g, "guestfs_mkdir") == -1) return -1;
2940   guestfs_set_busy (g);
2941
2942   memset (&ctx, 0, sizeof ctx);
2943
2944   args.path = (char *) path;
2945   serial = guestfs__send_sync (g, GUESTFS_PROC_MKDIR,
2946         (xdrproc_t) xdr_guestfs_mkdir_args, (char *) &args);
2947   if (serial == -1) {
2948     guestfs_end_busy (g);
2949     return -1;
2950   }
2951
2952   guestfs__switch_to_receiving (g);
2953   ctx.cb_sequence = 0;
2954   guestfs_set_reply_callback (g, mkdir_reply_cb, &ctx);
2955   (void) ml->main_loop_run (ml, g);
2956   guestfs_set_reply_callback (g, NULL, NULL);
2957   if (ctx.cb_sequence != 1) {
2958     error (g, "%s reply failed, see earlier error messages", "guestfs_mkdir");
2959     guestfs_end_busy (g);
2960     return -1;
2961   }
2962
2963   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKDIR, serial) == -1) {
2964     guestfs_end_busy (g);
2965     return -1;
2966   }
2967
2968   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
2969     error (g, "%s", ctx.err.error_message);
2970     free (ctx.err.error_message);
2971     guestfs_end_busy (g);
2972     return -1;
2973   }
2974
2975   guestfs_end_busy (g);
2976   return 0;
2977 }
2978
2979 struct mkdir_p_ctx {
2980   /* This flag is set by the callbacks, so we know we've done
2981    * the callbacks as expected, and in the right sequence.
2982    * 0 = not called, 1 = reply_cb called.
2983    */
2984   int cb_sequence;
2985   struct guestfs_message_header hdr;
2986   struct guestfs_message_error err;
2987 };
2988
2989 static void mkdir_p_reply_cb (guestfs_h *g, void *data, XDR *xdr)
2990 {
2991   guestfs_main_loop *ml = guestfs_get_main_loop (g);
2992   struct mkdir_p_ctx *ctx = (struct mkdir_p_ctx *) data;
2993
2994   /* This should definitely not happen. */
2995   if (ctx->cb_sequence != 0) {
2996     ctx->cb_sequence = 9999;
2997     error (g, "%s: internal error: reply callback called twice", "guestfs_mkdir_p");
2998     return;
2999   }
3000
3001   ml->main_loop_quit (ml, g);
3002
3003   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3004     error (g, "%s: failed to parse reply header", "guestfs_mkdir_p");
3005     return;
3006   }
3007   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3008     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3009       error (g, "%s: failed to parse reply error", "guestfs_mkdir_p");
3010       return;
3011     }
3012     goto done;
3013   }
3014  done:
3015   ctx->cb_sequence = 1;
3016 }
3017
3018 int guestfs_mkdir_p (guestfs_h *g,
3019                 const char *path)
3020 {
3021   struct guestfs_mkdir_p_args args;
3022   struct mkdir_p_ctx ctx;
3023   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3024   int serial;
3025
3026   if (check_state (g, "guestfs_mkdir_p") == -1) return -1;
3027   guestfs_set_busy (g);
3028
3029   memset (&ctx, 0, sizeof ctx);
3030
3031   args.path = (char *) path;
3032   serial = guestfs__send_sync (g, GUESTFS_PROC_MKDIR_P,
3033         (xdrproc_t) xdr_guestfs_mkdir_p_args, (char *) &args);
3034   if (serial == -1) {
3035     guestfs_end_busy (g);
3036     return -1;
3037   }
3038
3039   guestfs__switch_to_receiving (g);
3040   ctx.cb_sequence = 0;
3041   guestfs_set_reply_callback (g, mkdir_p_reply_cb, &ctx);
3042   (void) ml->main_loop_run (ml, g);
3043   guestfs_set_reply_callback (g, NULL, NULL);
3044   if (ctx.cb_sequence != 1) {
3045     error (g, "%s reply failed, see earlier error messages", "guestfs_mkdir_p");
3046     guestfs_end_busy (g);
3047     return -1;
3048   }
3049
3050   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKDIR_P, serial) == -1) {
3051     guestfs_end_busy (g);
3052     return -1;
3053   }
3054
3055   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3056     error (g, "%s", ctx.err.error_message);
3057     free (ctx.err.error_message);
3058     guestfs_end_busy (g);
3059     return -1;
3060   }
3061
3062   guestfs_end_busy (g);
3063   return 0;
3064 }
3065
3066 struct chmod_ctx {
3067   /* This flag is set by the callbacks, so we know we've done
3068    * the callbacks as expected, and in the right sequence.
3069    * 0 = not called, 1 = reply_cb called.
3070    */
3071   int cb_sequence;
3072   struct guestfs_message_header hdr;
3073   struct guestfs_message_error err;
3074 };
3075
3076 static void chmod_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3077 {
3078   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3079   struct chmod_ctx *ctx = (struct chmod_ctx *) data;
3080
3081   /* This should definitely not happen. */
3082   if (ctx->cb_sequence != 0) {
3083     ctx->cb_sequence = 9999;
3084     error (g, "%s: internal error: reply callback called twice", "guestfs_chmod");
3085     return;
3086   }
3087
3088   ml->main_loop_quit (ml, g);
3089
3090   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3091     error (g, "%s: failed to parse reply header", "guestfs_chmod");
3092     return;
3093   }
3094   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3095     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3096       error (g, "%s: failed to parse reply error", "guestfs_chmod");
3097       return;
3098     }
3099     goto done;
3100   }
3101  done:
3102   ctx->cb_sequence = 1;
3103 }
3104
3105 int guestfs_chmod (guestfs_h *g,
3106                 int mode,
3107                 const char *path)
3108 {
3109   struct guestfs_chmod_args args;
3110   struct chmod_ctx ctx;
3111   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3112   int serial;
3113
3114   if (check_state (g, "guestfs_chmod") == -1) return -1;
3115   guestfs_set_busy (g);
3116
3117   memset (&ctx, 0, sizeof ctx);
3118
3119   args.mode = mode;
3120   args.path = (char *) path;
3121   serial = guestfs__send_sync (g, GUESTFS_PROC_CHMOD,
3122         (xdrproc_t) xdr_guestfs_chmod_args, (char *) &args);
3123   if (serial == -1) {
3124     guestfs_end_busy (g);
3125     return -1;
3126   }
3127
3128   guestfs__switch_to_receiving (g);
3129   ctx.cb_sequence = 0;
3130   guestfs_set_reply_callback (g, chmod_reply_cb, &ctx);
3131   (void) ml->main_loop_run (ml, g);
3132   guestfs_set_reply_callback (g, NULL, NULL);
3133   if (ctx.cb_sequence != 1) {
3134     error (g, "%s reply failed, see earlier error messages", "guestfs_chmod");
3135     guestfs_end_busy (g);
3136     return -1;
3137   }
3138
3139   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHMOD, serial) == -1) {
3140     guestfs_end_busy (g);
3141     return -1;
3142   }
3143
3144   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3145     error (g, "%s", ctx.err.error_message);
3146     free (ctx.err.error_message);
3147     guestfs_end_busy (g);
3148     return -1;
3149   }
3150
3151   guestfs_end_busy (g);
3152   return 0;
3153 }
3154
3155 struct chown_ctx {
3156   /* This flag is set by the callbacks, so we know we've done
3157    * the callbacks as expected, and in the right sequence.
3158    * 0 = not called, 1 = reply_cb called.
3159    */
3160   int cb_sequence;
3161   struct guestfs_message_header hdr;
3162   struct guestfs_message_error err;
3163 };
3164
3165 static void chown_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3166 {
3167   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3168   struct chown_ctx *ctx = (struct chown_ctx *) data;
3169
3170   /* This should definitely not happen. */
3171   if (ctx->cb_sequence != 0) {
3172     ctx->cb_sequence = 9999;
3173     error (g, "%s: internal error: reply callback called twice", "guestfs_chown");
3174     return;
3175   }
3176
3177   ml->main_loop_quit (ml, g);
3178
3179   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3180     error (g, "%s: failed to parse reply header", "guestfs_chown");
3181     return;
3182   }
3183   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3184     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3185       error (g, "%s: failed to parse reply error", "guestfs_chown");
3186       return;
3187     }
3188     goto done;
3189   }
3190  done:
3191   ctx->cb_sequence = 1;
3192 }
3193
3194 int guestfs_chown (guestfs_h *g,
3195                 int owner,
3196                 int group,
3197                 const char *path)
3198 {
3199   struct guestfs_chown_args args;
3200   struct chown_ctx ctx;
3201   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3202   int serial;
3203
3204   if (check_state (g, "guestfs_chown") == -1) return -1;
3205   guestfs_set_busy (g);
3206
3207   memset (&ctx, 0, sizeof ctx);
3208
3209   args.owner = owner;
3210   args.group = group;
3211   args.path = (char *) path;
3212   serial = guestfs__send_sync (g, GUESTFS_PROC_CHOWN,
3213         (xdrproc_t) xdr_guestfs_chown_args, (char *) &args);
3214   if (serial == -1) {
3215     guestfs_end_busy (g);
3216     return -1;
3217   }
3218
3219   guestfs__switch_to_receiving (g);
3220   ctx.cb_sequence = 0;
3221   guestfs_set_reply_callback (g, chown_reply_cb, &ctx);
3222   (void) ml->main_loop_run (ml, g);
3223   guestfs_set_reply_callback (g, NULL, NULL);
3224   if (ctx.cb_sequence != 1) {
3225     error (g, "%s reply failed, see earlier error messages", "guestfs_chown");
3226     guestfs_end_busy (g);
3227     return -1;
3228   }
3229
3230   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHOWN, serial) == -1) {
3231     guestfs_end_busy (g);
3232     return -1;
3233   }
3234
3235   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3236     error (g, "%s", ctx.err.error_message);
3237     free (ctx.err.error_message);
3238     guestfs_end_busy (g);
3239     return -1;
3240   }
3241
3242   guestfs_end_busy (g);
3243   return 0;
3244 }
3245
3246 struct exists_ctx {
3247   /* This flag is set by the callbacks, so we know we've done
3248    * the callbacks as expected, and in the right sequence.
3249    * 0 = not called, 1 = reply_cb called.
3250    */
3251   int cb_sequence;
3252   struct guestfs_message_header hdr;
3253   struct guestfs_message_error err;
3254   struct guestfs_exists_ret ret;
3255 };
3256
3257 static void exists_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3258 {
3259   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3260   struct exists_ctx *ctx = (struct exists_ctx *) data;
3261
3262   /* This should definitely not happen. */
3263   if (ctx->cb_sequence != 0) {
3264     ctx->cb_sequence = 9999;
3265     error (g, "%s: internal error: reply callback called twice", "guestfs_exists");
3266     return;
3267   }
3268
3269   ml->main_loop_quit (ml, g);
3270
3271   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3272     error (g, "%s: failed to parse reply header", "guestfs_exists");
3273     return;
3274   }
3275   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3276     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3277       error (g, "%s: failed to parse reply error", "guestfs_exists");
3278       return;
3279     }
3280     goto done;
3281   }
3282   if (!xdr_guestfs_exists_ret (xdr, &ctx->ret)) {
3283     error (g, "%s: failed to parse reply", "guestfs_exists");
3284     return;
3285   }
3286  done:
3287   ctx->cb_sequence = 1;
3288 }
3289
3290 int guestfs_exists (guestfs_h *g,
3291                 const char *path)
3292 {
3293   struct guestfs_exists_args args;
3294   struct exists_ctx ctx;
3295   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3296   int serial;
3297
3298   if (check_state (g, "guestfs_exists") == -1) return -1;
3299   guestfs_set_busy (g);
3300
3301   memset (&ctx, 0, sizeof ctx);
3302
3303   args.path = (char *) path;
3304   serial = guestfs__send_sync (g, GUESTFS_PROC_EXISTS,
3305         (xdrproc_t) xdr_guestfs_exists_args, (char *) &args);
3306   if (serial == -1) {
3307     guestfs_end_busy (g);
3308     return -1;
3309   }
3310
3311   guestfs__switch_to_receiving (g);
3312   ctx.cb_sequence = 0;
3313   guestfs_set_reply_callback (g, exists_reply_cb, &ctx);
3314   (void) ml->main_loop_run (ml, g);
3315   guestfs_set_reply_callback (g, NULL, NULL);
3316   if (ctx.cb_sequence != 1) {
3317     error (g, "%s reply failed, see earlier error messages", "guestfs_exists");
3318     guestfs_end_busy (g);
3319     return -1;
3320   }
3321
3322   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_EXISTS, serial) == -1) {
3323     guestfs_end_busy (g);
3324     return -1;
3325   }
3326
3327   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3328     error (g, "%s", ctx.err.error_message);
3329     free (ctx.err.error_message);
3330     guestfs_end_busy (g);
3331     return -1;
3332   }
3333
3334   guestfs_end_busy (g);
3335   return ctx.ret.existsflag;
3336 }
3337
3338 struct is_file_ctx {
3339   /* This flag is set by the callbacks, so we know we've done
3340    * the callbacks as expected, and in the right sequence.
3341    * 0 = not called, 1 = reply_cb called.
3342    */
3343   int cb_sequence;
3344   struct guestfs_message_header hdr;
3345   struct guestfs_message_error err;
3346   struct guestfs_is_file_ret ret;
3347 };
3348
3349 static void is_file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3350 {
3351   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3352   struct is_file_ctx *ctx = (struct is_file_ctx *) data;
3353
3354   /* This should definitely not happen. */
3355   if (ctx->cb_sequence != 0) {
3356     ctx->cb_sequence = 9999;
3357     error (g, "%s: internal error: reply callback called twice", "guestfs_is_file");
3358     return;
3359   }
3360
3361   ml->main_loop_quit (ml, g);
3362
3363   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3364     error (g, "%s: failed to parse reply header", "guestfs_is_file");
3365     return;
3366   }
3367   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3368     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3369       error (g, "%s: failed to parse reply error", "guestfs_is_file");
3370       return;
3371     }
3372     goto done;
3373   }
3374   if (!xdr_guestfs_is_file_ret (xdr, &ctx->ret)) {
3375     error (g, "%s: failed to parse reply", "guestfs_is_file");
3376     return;
3377   }
3378  done:
3379   ctx->cb_sequence = 1;
3380 }
3381
3382 int guestfs_is_file (guestfs_h *g,
3383                 const char *path)
3384 {
3385   struct guestfs_is_file_args args;
3386   struct is_file_ctx ctx;
3387   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3388   int serial;
3389
3390   if (check_state (g, "guestfs_is_file") == -1) return -1;
3391   guestfs_set_busy (g);
3392
3393   memset (&ctx, 0, sizeof ctx);
3394
3395   args.path = (char *) path;
3396   serial = guestfs__send_sync (g, GUESTFS_PROC_IS_FILE,
3397         (xdrproc_t) xdr_guestfs_is_file_args, (char *) &args);
3398   if (serial == -1) {
3399     guestfs_end_busy (g);
3400     return -1;
3401   }
3402
3403   guestfs__switch_to_receiving (g);
3404   ctx.cb_sequence = 0;
3405   guestfs_set_reply_callback (g, is_file_reply_cb, &ctx);
3406   (void) ml->main_loop_run (ml, g);
3407   guestfs_set_reply_callback (g, NULL, NULL);
3408   if (ctx.cb_sequence != 1) {
3409     error (g, "%s reply failed, see earlier error messages", "guestfs_is_file");
3410     guestfs_end_busy (g);
3411     return -1;
3412   }
3413
3414   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_IS_FILE, serial) == -1) {
3415     guestfs_end_busy (g);
3416     return -1;
3417   }
3418
3419   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3420     error (g, "%s", ctx.err.error_message);
3421     free (ctx.err.error_message);
3422     guestfs_end_busy (g);
3423     return -1;
3424   }
3425
3426   guestfs_end_busy (g);
3427   return ctx.ret.fileflag;
3428 }
3429
3430 struct is_dir_ctx {
3431   /* This flag is set by the callbacks, so we know we've done
3432    * the callbacks as expected, and in the right sequence.
3433    * 0 = not called, 1 = reply_cb called.
3434    */
3435   int cb_sequence;
3436   struct guestfs_message_header hdr;
3437   struct guestfs_message_error err;
3438   struct guestfs_is_dir_ret ret;
3439 };
3440
3441 static void is_dir_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3442 {
3443   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3444   struct is_dir_ctx *ctx = (struct is_dir_ctx *) data;
3445
3446   /* This should definitely not happen. */
3447   if (ctx->cb_sequence != 0) {
3448     ctx->cb_sequence = 9999;
3449     error (g, "%s: internal error: reply callback called twice", "guestfs_is_dir");
3450     return;
3451   }
3452
3453   ml->main_loop_quit (ml, g);
3454
3455   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3456     error (g, "%s: failed to parse reply header", "guestfs_is_dir");
3457     return;
3458   }
3459   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3460     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3461       error (g, "%s: failed to parse reply error", "guestfs_is_dir");
3462       return;
3463     }
3464     goto done;
3465   }
3466   if (!xdr_guestfs_is_dir_ret (xdr, &ctx->ret)) {
3467     error (g, "%s: failed to parse reply", "guestfs_is_dir");
3468     return;
3469   }
3470  done:
3471   ctx->cb_sequence = 1;
3472 }
3473
3474 int guestfs_is_dir (guestfs_h *g,
3475                 const char *path)
3476 {
3477   struct guestfs_is_dir_args args;
3478   struct is_dir_ctx ctx;
3479   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3480   int serial;
3481
3482   if (check_state (g, "guestfs_is_dir") == -1) return -1;
3483   guestfs_set_busy (g);
3484
3485   memset (&ctx, 0, sizeof ctx);
3486
3487   args.path = (char *) path;
3488   serial = guestfs__send_sync (g, GUESTFS_PROC_IS_DIR,
3489         (xdrproc_t) xdr_guestfs_is_dir_args, (char *) &args);
3490   if (serial == -1) {
3491     guestfs_end_busy (g);
3492     return -1;
3493   }
3494
3495   guestfs__switch_to_receiving (g);
3496   ctx.cb_sequence = 0;
3497   guestfs_set_reply_callback (g, is_dir_reply_cb, &ctx);
3498   (void) ml->main_loop_run (ml, g);
3499   guestfs_set_reply_callback (g, NULL, NULL);
3500   if (ctx.cb_sequence != 1) {
3501     error (g, "%s reply failed, see earlier error messages", "guestfs_is_dir");
3502     guestfs_end_busy (g);
3503     return -1;
3504   }
3505
3506   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_IS_DIR, serial) == -1) {
3507     guestfs_end_busy (g);
3508     return -1;
3509   }
3510
3511   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3512     error (g, "%s", ctx.err.error_message);
3513     free (ctx.err.error_message);
3514     guestfs_end_busy (g);
3515     return -1;
3516   }
3517
3518   guestfs_end_busy (g);
3519   return ctx.ret.dirflag;
3520 }
3521
3522 struct pvcreate_ctx {
3523   /* This flag is set by the callbacks, so we know we've done
3524    * the callbacks as expected, and in the right sequence.
3525    * 0 = not called, 1 = reply_cb called.
3526    */
3527   int cb_sequence;
3528   struct guestfs_message_header hdr;
3529   struct guestfs_message_error err;
3530 };
3531
3532 static void pvcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3533 {
3534   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3535   struct pvcreate_ctx *ctx = (struct pvcreate_ctx *) data;
3536
3537   /* This should definitely not happen. */
3538   if (ctx->cb_sequence != 0) {
3539     ctx->cb_sequence = 9999;
3540     error (g, "%s: internal error: reply callback called twice", "guestfs_pvcreate");
3541     return;
3542   }
3543
3544   ml->main_loop_quit (ml, g);
3545
3546   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3547     error (g, "%s: failed to parse reply header", "guestfs_pvcreate");
3548     return;
3549   }
3550   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3551     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3552       error (g, "%s: failed to parse reply error", "guestfs_pvcreate");
3553       return;
3554     }
3555     goto done;
3556   }
3557  done:
3558   ctx->cb_sequence = 1;
3559 }
3560
3561 int guestfs_pvcreate (guestfs_h *g,
3562                 const char *device)
3563 {
3564   struct guestfs_pvcreate_args args;
3565   struct pvcreate_ctx ctx;
3566   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3567   int serial;
3568
3569   if (check_state (g, "guestfs_pvcreate") == -1) return -1;
3570   guestfs_set_busy (g);
3571
3572   memset (&ctx, 0, sizeof ctx);
3573
3574   args.device = (char *) device;
3575   serial = guestfs__send_sync (g, GUESTFS_PROC_PVCREATE,
3576         (xdrproc_t) xdr_guestfs_pvcreate_args, (char *) &args);
3577   if (serial == -1) {
3578     guestfs_end_busy (g);
3579     return -1;
3580   }
3581
3582   guestfs__switch_to_receiving (g);
3583   ctx.cb_sequence = 0;
3584   guestfs_set_reply_callback (g, pvcreate_reply_cb, &ctx);
3585   (void) ml->main_loop_run (ml, g);
3586   guestfs_set_reply_callback (g, NULL, NULL);
3587   if (ctx.cb_sequence != 1) {
3588     error (g, "%s reply failed, see earlier error messages", "guestfs_pvcreate");
3589     guestfs_end_busy (g);
3590     return -1;
3591   }
3592
3593   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVCREATE, serial) == -1) {
3594     guestfs_end_busy (g);
3595     return -1;
3596   }
3597
3598   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3599     error (g, "%s", ctx.err.error_message);
3600     free (ctx.err.error_message);
3601     guestfs_end_busy (g);
3602     return -1;
3603   }
3604
3605   guestfs_end_busy (g);
3606   return 0;
3607 }
3608
3609 struct vgcreate_ctx {
3610   /* This flag is set by the callbacks, so we know we've done
3611    * the callbacks as expected, and in the right sequence.
3612    * 0 = not called, 1 = reply_cb called.
3613    */
3614   int cb_sequence;
3615   struct guestfs_message_header hdr;
3616   struct guestfs_message_error err;
3617 };
3618
3619 static void vgcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3620 {
3621   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3622   struct vgcreate_ctx *ctx = (struct vgcreate_ctx *) data;
3623
3624   /* This should definitely not happen. */
3625   if (ctx->cb_sequence != 0) {
3626     ctx->cb_sequence = 9999;
3627     error (g, "%s: internal error: reply callback called twice", "guestfs_vgcreate");
3628     return;
3629   }
3630
3631   ml->main_loop_quit (ml, g);
3632
3633   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3634     error (g, "%s: failed to parse reply header", "guestfs_vgcreate");
3635     return;
3636   }
3637   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3638     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3639       error (g, "%s: failed to parse reply error", "guestfs_vgcreate");
3640       return;
3641     }
3642     goto done;
3643   }
3644  done:
3645   ctx->cb_sequence = 1;
3646 }
3647
3648 int guestfs_vgcreate (guestfs_h *g,
3649                 const char *volgroup,
3650                 char * const* const physvols)
3651 {
3652   struct guestfs_vgcreate_args args;
3653   struct vgcreate_ctx ctx;
3654   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3655   int serial;
3656
3657   if (check_state (g, "guestfs_vgcreate") == -1) return -1;
3658   guestfs_set_busy (g);
3659
3660   memset (&ctx, 0, sizeof ctx);
3661
3662   args.volgroup = (char *) volgroup;
3663   args.physvols.physvols_val = (char **) physvols;
3664   for (args.physvols.physvols_len = 0; physvols[args.physvols.physvols_len]; args.physvols.physvols_len++) ;
3665   serial = guestfs__send_sync (g, GUESTFS_PROC_VGCREATE,
3666         (xdrproc_t) xdr_guestfs_vgcreate_args, (char *) &args);
3667   if (serial == -1) {
3668     guestfs_end_busy (g);
3669     return -1;
3670   }
3671
3672   guestfs__switch_to_receiving (g);
3673   ctx.cb_sequence = 0;
3674   guestfs_set_reply_callback (g, vgcreate_reply_cb, &ctx);
3675   (void) ml->main_loop_run (ml, g);
3676   guestfs_set_reply_callback (g, NULL, NULL);
3677   if (ctx.cb_sequence != 1) {
3678     error (g, "%s reply failed, see earlier error messages", "guestfs_vgcreate");
3679     guestfs_end_busy (g);
3680     return -1;
3681   }
3682
3683   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGCREATE, serial) == -1) {
3684     guestfs_end_busy (g);
3685     return -1;
3686   }
3687
3688   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3689     error (g, "%s", ctx.err.error_message);
3690     free (ctx.err.error_message);
3691     guestfs_end_busy (g);
3692     return -1;
3693   }
3694
3695   guestfs_end_busy (g);
3696   return 0;
3697 }
3698
3699 struct lvcreate_ctx {
3700   /* This flag is set by the callbacks, so we know we've done
3701    * the callbacks as expected, and in the right sequence.
3702    * 0 = not called, 1 = reply_cb called.
3703    */
3704   int cb_sequence;
3705   struct guestfs_message_header hdr;
3706   struct guestfs_message_error err;
3707 };
3708
3709 static void lvcreate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3710 {
3711   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3712   struct lvcreate_ctx *ctx = (struct lvcreate_ctx *) data;
3713
3714   /* This should definitely not happen. */
3715   if (ctx->cb_sequence != 0) {
3716     ctx->cb_sequence = 9999;
3717     error (g, "%s: internal error: reply callback called twice", "guestfs_lvcreate");
3718     return;
3719   }
3720
3721   ml->main_loop_quit (ml, g);
3722
3723   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3724     error (g, "%s: failed to parse reply header", "guestfs_lvcreate");
3725     return;
3726   }
3727   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3728     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3729       error (g, "%s: failed to parse reply error", "guestfs_lvcreate");
3730       return;
3731     }
3732     goto done;
3733   }
3734  done:
3735   ctx->cb_sequence = 1;
3736 }
3737
3738 int guestfs_lvcreate (guestfs_h *g,
3739                 const char *logvol,
3740                 const char *volgroup,
3741                 int mbytes)
3742 {
3743   struct guestfs_lvcreate_args args;
3744   struct lvcreate_ctx ctx;
3745   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3746   int serial;
3747
3748   if (check_state (g, "guestfs_lvcreate") == -1) return -1;
3749   guestfs_set_busy (g);
3750
3751   memset (&ctx, 0, sizeof ctx);
3752
3753   args.logvol = (char *) logvol;
3754   args.volgroup = (char *) volgroup;
3755   args.mbytes = mbytes;
3756   serial = guestfs__send_sync (g, GUESTFS_PROC_LVCREATE,
3757         (xdrproc_t) xdr_guestfs_lvcreate_args, (char *) &args);
3758   if (serial == -1) {
3759     guestfs_end_busy (g);
3760     return -1;
3761   }
3762
3763   guestfs__switch_to_receiving (g);
3764   ctx.cb_sequence = 0;
3765   guestfs_set_reply_callback (g, lvcreate_reply_cb, &ctx);
3766   (void) ml->main_loop_run (ml, g);
3767   guestfs_set_reply_callback (g, NULL, NULL);
3768   if (ctx.cb_sequence != 1) {
3769     error (g, "%s reply failed, see earlier error messages", "guestfs_lvcreate");
3770     guestfs_end_busy (g);
3771     return -1;
3772   }
3773
3774   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVCREATE, serial) == -1) {
3775     guestfs_end_busy (g);
3776     return -1;
3777   }
3778
3779   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3780     error (g, "%s", ctx.err.error_message);
3781     free (ctx.err.error_message);
3782     guestfs_end_busy (g);
3783     return -1;
3784   }
3785
3786   guestfs_end_busy (g);
3787   return 0;
3788 }
3789
3790 struct mkfs_ctx {
3791   /* This flag is set by the callbacks, so we know we've done
3792    * the callbacks as expected, and in the right sequence.
3793    * 0 = not called, 1 = reply_cb called.
3794    */
3795   int cb_sequence;
3796   struct guestfs_message_header hdr;
3797   struct guestfs_message_error err;
3798 };
3799
3800 static void mkfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3801 {
3802   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3803   struct mkfs_ctx *ctx = (struct mkfs_ctx *) data;
3804
3805   /* This should definitely not happen. */
3806   if (ctx->cb_sequence != 0) {
3807     ctx->cb_sequence = 9999;
3808     error (g, "%s: internal error: reply callback called twice", "guestfs_mkfs");
3809     return;
3810   }
3811
3812   ml->main_loop_quit (ml, g);
3813
3814   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3815     error (g, "%s: failed to parse reply header", "guestfs_mkfs");
3816     return;
3817   }
3818   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3819     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3820       error (g, "%s: failed to parse reply error", "guestfs_mkfs");
3821       return;
3822     }
3823     goto done;
3824   }
3825  done:
3826   ctx->cb_sequence = 1;
3827 }
3828
3829 int guestfs_mkfs (guestfs_h *g,
3830                 const char *fstype,
3831                 const char *device)
3832 {
3833   struct guestfs_mkfs_args args;
3834   struct mkfs_ctx ctx;
3835   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3836   int serial;
3837
3838   if (check_state (g, "guestfs_mkfs") == -1) return -1;
3839   guestfs_set_busy (g);
3840
3841   memset (&ctx, 0, sizeof ctx);
3842
3843   args.fstype = (char *) fstype;
3844   args.device = (char *) device;
3845   serial = guestfs__send_sync (g, GUESTFS_PROC_MKFS,
3846         (xdrproc_t) xdr_guestfs_mkfs_args, (char *) &args);
3847   if (serial == -1) {
3848     guestfs_end_busy (g);
3849     return -1;
3850   }
3851
3852   guestfs__switch_to_receiving (g);
3853   ctx.cb_sequence = 0;
3854   guestfs_set_reply_callback (g, mkfs_reply_cb, &ctx);
3855   (void) ml->main_loop_run (ml, g);
3856   guestfs_set_reply_callback (g, NULL, NULL);
3857   if (ctx.cb_sequence != 1) {
3858     error (g, "%s reply failed, see earlier error messages", "guestfs_mkfs");
3859     guestfs_end_busy (g);
3860     return -1;
3861   }
3862
3863   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MKFS, serial) == -1) {
3864     guestfs_end_busy (g);
3865     return -1;
3866   }
3867
3868   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3869     error (g, "%s", ctx.err.error_message);
3870     free (ctx.err.error_message);
3871     guestfs_end_busy (g);
3872     return -1;
3873   }
3874
3875   guestfs_end_busy (g);
3876   return 0;
3877 }
3878
3879 struct sfdisk_ctx {
3880   /* This flag is set by the callbacks, so we know we've done
3881    * the callbacks as expected, and in the right sequence.
3882    * 0 = not called, 1 = reply_cb called.
3883    */
3884   int cb_sequence;
3885   struct guestfs_message_header hdr;
3886   struct guestfs_message_error err;
3887 };
3888
3889 static void sfdisk_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3890 {
3891   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3892   struct sfdisk_ctx *ctx = (struct sfdisk_ctx *) data;
3893
3894   /* This should definitely not happen. */
3895   if (ctx->cb_sequence != 0) {
3896     ctx->cb_sequence = 9999;
3897     error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk");
3898     return;
3899   }
3900
3901   ml->main_loop_quit (ml, g);
3902
3903   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
3904     error (g, "%s: failed to parse reply header", "guestfs_sfdisk");
3905     return;
3906   }
3907   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
3908     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
3909       error (g, "%s: failed to parse reply error", "guestfs_sfdisk");
3910       return;
3911     }
3912     goto done;
3913   }
3914  done:
3915   ctx->cb_sequence = 1;
3916 }
3917
3918 int guestfs_sfdisk (guestfs_h *g,
3919                 const char *device,
3920                 int cyls,
3921                 int heads,
3922                 int sectors,
3923                 char * const* const lines)
3924 {
3925   struct guestfs_sfdisk_args args;
3926   struct sfdisk_ctx ctx;
3927   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3928   int serial;
3929
3930   if (check_state (g, "guestfs_sfdisk") == -1) return -1;
3931   guestfs_set_busy (g);
3932
3933   memset (&ctx, 0, sizeof ctx);
3934
3935   args.device = (char *) device;
3936   args.cyls = cyls;
3937   args.heads = heads;
3938   args.sectors = sectors;
3939   args.lines.lines_val = (char **) lines;
3940   for (args.lines.lines_len = 0; lines[args.lines.lines_len]; args.lines.lines_len++) ;
3941   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK,
3942         (xdrproc_t) xdr_guestfs_sfdisk_args, (char *) &args);
3943   if (serial == -1) {
3944     guestfs_end_busy (g);
3945     return -1;
3946   }
3947
3948   guestfs__switch_to_receiving (g);
3949   ctx.cb_sequence = 0;
3950   guestfs_set_reply_callback (g, sfdisk_reply_cb, &ctx);
3951   (void) ml->main_loop_run (ml, g);
3952   guestfs_set_reply_callback (g, NULL, NULL);
3953   if (ctx.cb_sequence != 1) {
3954     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk");
3955     guestfs_end_busy (g);
3956     return -1;
3957   }
3958
3959   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK, serial) == -1) {
3960     guestfs_end_busy (g);
3961     return -1;
3962   }
3963
3964   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
3965     error (g, "%s", ctx.err.error_message);
3966     free (ctx.err.error_message);
3967     guestfs_end_busy (g);
3968     return -1;
3969   }
3970
3971   guestfs_end_busy (g);
3972   return 0;
3973 }
3974
3975 struct write_file_ctx {
3976   /* This flag is set by the callbacks, so we know we've done
3977    * the callbacks as expected, and in the right sequence.
3978    * 0 = not called, 1 = reply_cb called.
3979    */
3980   int cb_sequence;
3981   struct guestfs_message_header hdr;
3982   struct guestfs_message_error err;
3983 };
3984
3985 static void write_file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
3986 {
3987   guestfs_main_loop *ml = guestfs_get_main_loop (g);
3988   struct write_file_ctx *ctx = (struct write_file_ctx *) data;
3989
3990   /* This should definitely not happen. */
3991   if (ctx->cb_sequence != 0) {
3992     ctx->cb_sequence = 9999;
3993     error (g, "%s: internal error: reply callback called twice", "guestfs_write_file");
3994     return;
3995   }
3996
3997   ml->main_loop_quit (ml, g);
3998
3999   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4000     error (g, "%s: failed to parse reply header", "guestfs_write_file");
4001     return;
4002   }
4003   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4004     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4005       error (g, "%s: failed to parse reply error", "guestfs_write_file");
4006       return;
4007     }
4008     goto done;
4009   }
4010  done:
4011   ctx->cb_sequence = 1;
4012 }
4013
4014 int guestfs_write_file (guestfs_h *g,
4015                 const char *path,
4016                 const char *content,
4017                 int size)
4018 {
4019   struct guestfs_write_file_args args;
4020   struct write_file_ctx ctx;
4021   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4022   int serial;
4023
4024   if (check_state (g, "guestfs_write_file") == -1) return -1;
4025   guestfs_set_busy (g);
4026
4027   memset (&ctx, 0, sizeof ctx);
4028
4029   args.path = (char *) path;
4030   args.content = (char *) content;
4031   args.size = size;
4032   serial = guestfs__send_sync (g, GUESTFS_PROC_WRITE_FILE,
4033         (xdrproc_t) xdr_guestfs_write_file_args, (char *) &args);
4034   if (serial == -1) {
4035     guestfs_end_busy (g);
4036     return -1;
4037   }
4038
4039   guestfs__switch_to_receiving (g);
4040   ctx.cb_sequence = 0;
4041   guestfs_set_reply_callback (g, write_file_reply_cb, &ctx);
4042   (void) ml->main_loop_run (ml, g);
4043   guestfs_set_reply_callback (g, NULL, NULL);
4044   if (ctx.cb_sequence != 1) {
4045     error (g, "%s reply failed, see earlier error messages", "guestfs_write_file");
4046     guestfs_end_busy (g);
4047     return -1;
4048   }
4049
4050   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_WRITE_FILE, serial) == -1) {
4051     guestfs_end_busy (g);
4052     return -1;
4053   }
4054
4055   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4056     error (g, "%s", ctx.err.error_message);
4057     free (ctx.err.error_message);
4058     guestfs_end_busy (g);
4059     return -1;
4060   }
4061
4062   guestfs_end_busy (g);
4063   return 0;
4064 }
4065
4066 struct umount_ctx {
4067   /* This flag is set by the callbacks, so we know we've done
4068    * the callbacks as expected, and in the right sequence.
4069    * 0 = not called, 1 = reply_cb called.
4070    */
4071   int cb_sequence;
4072   struct guestfs_message_header hdr;
4073   struct guestfs_message_error err;
4074 };
4075
4076 static void umount_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4077 {
4078   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4079   struct umount_ctx *ctx = (struct umount_ctx *) data;
4080
4081   /* This should definitely not happen. */
4082   if (ctx->cb_sequence != 0) {
4083     ctx->cb_sequence = 9999;
4084     error (g, "%s: internal error: reply callback called twice", "guestfs_umount");
4085     return;
4086   }
4087
4088   ml->main_loop_quit (ml, g);
4089
4090   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4091     error (g, "%s: failed to parse reply header", "guestfs_umount");
4092     return;
4093   }
4094   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4095     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4096       error (g, "%s: failed to parse reply error", "guestfs_umount");
4097       return;
4098     }
4099     goto done;
4100   }
4101  done:
4102   ctx->cb_sequence = 1;
4103 }
4104
4105 int guestfs_umount (guestfs_h *g,
4106                 const char *pathordevice)
4107 {
4108   struct guestfs_umount_args args;
4109   struct umount_ctx ctx;
4110   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4111   int serial;
4112
4113   if (check_state (g, "guestfs_umount") == -1) return -1;
4114   guestfs_set_busy (g);
4115
4116   memset (&ctx, 0, sizeof ctx);
4117
4118   args.pathordevice = (char *) pathordevice;
4119   serial = guestfs__send_sync (g, GUESTFS_PROC_UMOUNT,
4120         (xdrproc_t) xdr_guestfs_umount_args, (char *) &args);
4121   if (serial == -1) {
4122     guestfs_end_busy (g);
4123     return -1;
4124   }
4125
4126   guestfs__switch_to_receiving (g);
4127   ctx.cb_sequence = 0;
4128   guestfs_set_reply_callback (g, umount_reply_cb, &ctx);
4129   (void) ml->main_loop_run (ml, g);
4130   guestfs_set_reply_callback (g, NULL, NULL);
4131   if (ctx.cb_sequence != 1) {
4132     error (g, "%s reply failed, see earlier error messages", "guestfs_umount");
4133     guestfs_end_busy (g);
4134     return -1;
4135   }
4136
4137   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UMOUNT, serial) == -1) {
4138     guestfs_end_busy (g);
4139     return -1;
4140   }
4141
4142   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4143     error (g, "%s", ctx.err.error_message);
4144     free (ctx.err.error_message);
4145     guestfs_end_busy (g);
4146     return -1;
4147   }
4148
4149   guestfs_end_busy (g);
4150   return 0;
4151 }
4152
4153 struct mounts_ctx {
4154   /* This flag is set by the callbacks, so we know we've done
4155    * the callbacks as expected, and in the right sequence.
4156    * 0 = not called, 1 = reply_cb called.
4157    */
4158   int cb_sequence;
4159   struct guestfs_message_header hdr;
4160   struct guestfs_message_error err;
4161   struct guestfs_mounts_ret ret;
4162 };
4163
4164 static void mounts_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4165 {
4166   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4167   struct mounts_ctx *ctx = (struct mounts_ctx *) data;
4168
4169   /* This should definitely not happen. */
4170   if (ctx->cb_sequence != 0) {
4171     ctx->cb_sequence = 9999;
4172     error (g, "%s: internal error: reply callback called twice", "guestfs_mounts");
4173     return;
4174   }
4175
4176   ml->main_loop_quit (ml, g);
4177
4178   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4179     error (g, "%s: failed to parse reply header", "guestfs_mounts");
4180     return;
4181   }
4182   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4183     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4184       error (g, "%s: failed to parse reply error", "guestfs_mounts");
4185       return;
4186     }
4187     goto done;
4188   }
4189   if (!xdr_guestfs_mounts_ret (xdr, &ctx->ret)) {
4190     error (g, "%s: failed to parse reply", "guestfs_mounts");
4191     return;
4192   }
4193  done:
4194   ctx->cb_sequence = 1;
4195 }
4196
4197 char **guestfs_mounts (guestfs_h *g)
4198 {
4199   struct mounts_ctx ctx;
4200   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4201   int serial;
4202
4203   if (check_state (g, "guestfs_mounts") == -1) return NULL;
4204   guestfs_set_busy (g);
4205
4206   memset (&ctx, 0, sizeof ctx);
4207
4208   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNTS, NULL, NULL);
4209   if (serial == -1) {
4210     guestfs_end_busy (g);
4211     return NULL;
4212   }
4213
4214   guestfs__switch_to_receiving (g);
4215   ctx.cb_sequence = 0;
4216   guestfs_set_reply_callback (g, mounts_reply_cb, &ctx);
4217   (void) ml->main_loop_run (ml, g);
4218   guestfs_set_reply_callback (g, NULL, NULL);
4219   if (ctx.cb_sequence != 1) {
4220     error (g, "%s reply failed, see earlier error messages", "guestfs_mounts");
4221     guestfs_end_busy (g);
4222     return NULL;
4223   }
4224
4225   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNTS, serial) == -1) {
4226     guestfs_end_busy (g);
4227     return NULL;
4228   }
4229
4230   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4231     error (g, "%s", ctx.err.error_message);
4232     free (ctx.err.error_message);
4233     guestfs_end_busy (g);
4234     return NULL;
4235   }
4236
4237   guestfs_end_busy (g);
4238   /* caller will free this, but we need to add a NULL entry */
4239   ctx.ret.devices.devices_val =
4240     safe_realloc (g, ctx.ret.devices.devices_val,
4241                   sizeof (char *) * (ctx.ret.devices.devices_len + 1));
4242   ctx.ret.devices.devices_val[ctx.ret.devices.devices_len] = NULL;
4243   return ctx.ret.devices.devices_val;
4244 }
4245
4246 struct umount_all_ctx {
4247   /* This flag is set by the callbacks, so we know we've done
4248    * the callbacks as expected, and in the right sequence.
4249    * 0 = not called, 1 = reply_cb called.
4250    */
4251   int cb_sequence;
4252   struct guestfs_message_header hdr;
4253   struct guestfs_message_error err;
4254 };
4255
4256 static void umount_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4257 {
4258   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4259   struct umount_all_ctx *ctx = (struct umount_all_ctx *) data;
4260
4261   /* This should definitely not happen. */
4262   if (ctx->cb_sequence != 0) {
4263     ctx->cb_sequence = 9999;
4264     error (g, "%s: internal error: reply callback called twice", "guestfs_umount_all");
4265     return;
4266   }
4267
4268   ml->main_loop_quit (ml, g);
4269
4270   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4271     error (g, "%s: failed to parse reply header", "guestfs_umount_all");
4272     return;
4273   }
4274   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4275     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4276       error (g, "%s: failed to parse reply error", "guestfs_umount_all");
4277       return;
4278     }
4279     goto done;
4280   }
4281  done:
4282   ctx->cb_sequence = 1;
4283 }
4284
4285 int guestfs_umount_all (guestfs_h *g)
4286 {
4287   struct umount_all_ctx ctx;
4288   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4289   int serial;
4290
4291   if (check_state (g, "guestfs_umount_all") == -1) return -1;
4292   guestfs_set_busy (g);
4293
4294   memset (&ctx, 0, sizeof ctx);
4295
4296   serial = guestfs__send_sync (g, GUESTFS_PROC_UMOUNT_ALL, NULL, NULL);
4297   if (serial == -1) {
4298     guestfs_end_busy (g);
4299     return -1;
4300   }
4301
4302   guestfs__switch_to_receiving (g);
4303   ctx.cb_sequence = 0;
4304   guestfs_set_reply_callback (g, umount_all_reply_cb, &ctx);
4305   (void) ml->main_loop_run (ml, g);
4306   guestfs_set_reply_callback (g, NULL, NULL);
4307   if (ctx.cb_sequence != 1) {
4308     error (g, "%s reply failed, see earlier error messages", "guestfs_umount_all");
4309     guestfs_end_busy (g);
4310     return -1;
4311   }
4312
4313   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UMOUNT_ALL, serial) == -1) {
4314     guestfs_end_busy (g);
4315     return -1;
4316   }
4317
4318   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4319     error (g, "%s", ctx.err.error_message);
4320     free (ctx.err.error_message);
4321     guestfs_end_busy (g);
4322     return -1;
4323   }
4324
4325   guestfs_end_busy (g);
4326   return 0;
4327 }
4328
4329 struct lvm_remove_all_ctx {
4330   /* This flag is set by the callbacks, so we know we've done
4331    * the callbacks as expected, and in the right sequence.
4332    * 0 = not called, 1 = reply_cb called.
4333    */
4334   int cb_sequence;
4335   struct guestfs_message_header hdr;
4336   struct guestfs_message_error err;
4337 };
4338
4339 static void lvm_remove_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4340 {
4341   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4342   struct lvm_remove_all_ctx *ctx = (struct lvm_remove_all_ctx *) data;
4343
4344   /* This should definitely not happen. */
4345   if (ctx->cb_sequence != 0) {
4346     ctx->cb_sequence = 9999;
4347     error (g, "%s: internal error: reply callback called twice", "guestfs_lvm_remove_all");
4348     return;
4349   }
4350
4351   ml->main_loop_quit (ml, g);
4352
4353   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4354     error (g, "%s: failed to parse reply header", "guestfs_lvm_remove_all");
4355     return;
4356   }
4357   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4358     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4359       error (g, "%s: failed to parse reply error", "guestfs_lvm_remove_all");
4360       return;
4361     }
4362     goto done;
4363   }
4364  done:
4365   ctx->cb_sequence = 1;
4366 }
4367
4368 int guestfs_lvm_remove_all (guestfs_h *g)
4369 {
4370   struct lvm_remove_all_ctx ctx;
4371   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4372   int serial;
4373
4374   if (check_state (g, "guestfs_lvm_remove_all") == -1) return -1;
4375   guestfs_set_busy (g);
4376
4377   memset (&ctx, 0, sizeof ctx);
4378
4379   serial = guestfs__send_sync (g, GUESTFS_PROC_LVM_REMOVE_ALL, NULL, NULL);
4380   if (serial == -1) {
4381     guestfs_end_busy (g);
4382     return -1;
4383   }
4384
4385   guestfs__switch_to_receiving (g);
4386   ctx.cb_sequence = 0;
4387   guestfs_set_reply_callback (g, lvm_remove_all_reply_cb, &ctx);
4388   (void) ml->main_loop_run (ml, g);
4389   guestfs_set_reply_callback (g, NULL, NULL);
4390   if (ctx.cb_sequence != 1) {
4391     error (g, "%s reply failed, see earlier error messages", "guestfs_lvm_remove_all");
4392     guestfs_end_busy (g);
4393     return -1;
4394   }
4395
4396   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVM_REMOVE_ALL, serial) == -1) {
4397     guestfs_end_busy (g);
4398     return -1;
4399   }
4400
4401   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4402     error (g, "%s", ctx.err.error_message);
4403     free (ctx.err.error_message);
4404     guestfs_end_busy (g);
4405     return -1;
4406   }
4407
4408   guestfs_end_busy (g);
4409   return 0;
4410 }
4411
4412 struct file_ctx {
4413   /* This flag is set by the callbacks, so we know we've done
4414    * the callbacks as expected, and in the right sequence.
4415    * 0 = not called, 1 = reply_cb called.
4416    */
4417   int cb_sequence;
4418   struct guestfs_message_header hdr;
4419   struct guestfs_message_error err;
4420   struct guestfs_file_ret ret;
4421 };
4422
4423 static void file_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4424 {
4425   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4426   struct file_ctx *ctx = (struct file_ctx *) data;
4427
4428   /* This should definitely not happen. */
4429   if (ctx->cb_sequence != 0) {
4430     ctx->cb_sequence = 9999;
4431     error (g, "%s: internal error: reply callback called twice", "guestfs_file");
4432     return;
4433   }
4434
4435   ml->main_loop_quit (ml, g);
4436
4437   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4438     error (g, "%s: failed to parse reply header", "guestfs_file");
4439     return;
4440   }
4441   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4442     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4443       error (g, "%s: failed to parse reply error", "guestfs_file");
4444       return;
4445     }
4446     goto done;
4447   }
4448   if (!xdr_guestfs_file_ret (xdr, &ctx->ret)) {
4449     error (g, "%s: failed to parse reply", "guestfs_file");
4450     return;
4451   }
4452  done:
4453   ctx->cb_sequence = 1;
4454 }
4455
4456 char *guestfs_file (guestfs_h *g,
4457                 const char *path)
4458 {
4459   struct guestfs_file_args args;
4460   struct file_ctx ctx;
4461   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4462   int serial;
4463
4464   if (check_state (g, "guestfs_file") == -1) return NULL;
4465   guestfs_set_busy (g);
4466
4467   memset (&ctx, 0, sizeof ctx);
4468
4469   args.path = (char *) path;
4470   serial = guestfs__send_sync (g, GUESTFS_PROC_FILE,
4471         (xdrproc_t) xdr_guestfs_file_args, (char *) &args);
4472   if (serial == -1) {
4473     guestfs_end_busy (g);
4474     return NULL;
4475   }
4476
4477   guestfs__switch_to_receiving (g);
4478   ctx.cb_sequence = 0;
4479   guestfs_set_reply_callback (g, file_reply_cb, &ctx);
4480   (void) ml->main_loop_run (ml, g);
4481   guestfs_set_reply_callback (g, NULL, NULL);
4482   if (ctx.cb_sequence != 1) {
4483     error (g, "%s reply failed, see earlier error messages", "guestfs_file");
4484     guestfs_end_busy (g);
4485     return NULL;
4486   }
4487
4488   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_FILE, serial) == -1) {
4489     guestfs_end_busy (g);
4490     return NULL;
4491   }
4492
4493   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4494     error (g, "%s", ctx.err.error_message);
4495     free (ctx.err.error_message);
4496     guestfs_end_busy (g);
4497     return NULL;
4498   }
4499
4500   guestfs_end_busy (g);
4501   return ctx.ret.description; /* caller will free */
4502 }
4503
4504 struct command_ctx {
4505   /* This flag is set by the callbacks, so we know we've done
4506    * the callbacks as expected, and in the right sequence.
4507    * 0 = not called, 1 = reply_cb called.
4508    */
4509   int cb_sequence;
4510   struct guestfs_message_header hdr;
4511   struct guestfs_message_error err;
4512   struct guestfs_command_ret ret;
4513 };
4514
4515 static void command_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4516 {
4517   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4518   struct command_ctx *ctx = (struct command_ctx *) data;
4519
4520   /* This should definitely not happen. */
4521   if (ctx->cb_sequence != 0) {
4522     ctx->cb_sequence = 9999;
4523     error (g, "%s: internal error: reply callback called twice", "guestfs_command");
4524     return;
4525   }
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_command");
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_command");
4536       return;
4537     }
4538     goto done;
4539   }
4540   if (!xdr_guestfs_command_ret (xdr, &ctx->ret)) {
4541     error (g, "%s: failed to parse reply", "guestfs_command");
4542     return;
4543   }
4544  done:
4545   ctx->cb_sequence = 1;
4546 }
4547
4548 char *guestfs_command (guestfs_h *g,
4549                 char * const* const arguments)
4550 {
4551   struct guestfs_command_args args;
4552   struct command_ctx ctx;
4553   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4554   int serial;
4555
4556   if (check_state (g, "guestfs_command") == -1) return NULL;
4557   guestfs_set_busy (g);
4558
4559   memset (&ctx, 0, sizeof ctx);
4560
4561   args.arguments.arguments_val = (char **) arguments;
4562   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
4563   serial = guestfs__send_sync (g, GUESTFS_PROC_COMMAND,
4564         (xdrproc_t) xdr_guestfs_command_args, (char *) &args);
4565   if (serial == -1) {
4566     guestfs_end_busy (g);
4567     return NULL;
4568   }
4569
4570   guestfs__switch_to_receiving (g);
4571   ctx.cb_sequence = 0;
4572   guestfs_set_reply_callback (g, command_reply_cb, &ctx);
4573   (void) ml->main_loop_run (ml, g);
4574   guestfs_set_reply_callback (g, NULL, NULL);
4575   if (ctx.cb_sequence != 1) {
4576     error (g, "%s reply failed, see earlier error messages", "guestfs_command");
4577     guestfs_end_busy (g);
4578     return NULL;
4579   }
4580
4581   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_COMMAND, serial) == -1) {
4582     guestfs_end_busy (g);
4583     return NULL;
4584   }
4585
4586   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4587     error (g, "%s", ctx.err.error_message);
4588     free (ctx.err.error_message);
4589     guestfs_end_busy (g);
4590     return NULL;
4591   }
4592
4593   guestfs_end_busy (g);
4594   return ctx.ret.output; /* caller will free */
4595 }
4596
4597 struct command_lines_ctx {
4598   /* This flag is set by the callbacks, so we know we've done
4599    * the callbacks as expected, and in the right sequence.
4600    * 0 = not called, 1 = reply_cb called.
4601    */
4602   int cb_sequence;
4603   struct guestfs_message_header hdr;
4604   struct guestfs_message_error err;
4605   struct guestfs_command_lines_ret ret;
4606 };
4607
4608 static void command_lines_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4609 {
4610   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4611   struct command_lines_ctx *ctx = (struct command_lines_ctx *) data;
4612
4613   /* This should definitely not happen. */
4614   if (ctx->cb_sequence != 0) {
4615     ctx->cb_sequence = 9999;
4616     error (g, "%s: internal error: reply callback called twice", "guestfs_command_lines");
4617     return;
4618   }
4619
4620   ml->main_loop_quit (ml, g);
4621
4622   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4623     error (g, "%s: failed to parse reply header", "guestfs_command_lines");
4624     return;
4625   }
4626   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4627     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4628       error (g, "%s: failed to parse reply error", "guestfs_command_lines");
4629       return;
4630     }
4631     goto done;
4632   }
4633   if (!xdr_guestfs_command_lines_ret (xdr, &ctx->ret)) {
4634     error (g, "%s: failed to parse reply", "guestfs_command_lines");
4635     return;
4636   }
4637  done:
4638   ctx->cb_sequence = 1;
4639 }
4640
4641 char **guestfs_command_lines (guestfs_h *g,
4642                 char * const* const arguments)
4643 {
4644   struct guestfs_command_lines_args args;
4645   struct command_lines_ctx ctx;
4646   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4647   int serial;
4648
4649   if (check_state (g, "guestfs_command_lines") == -1) return NULL;
4650   guestfs_set_busy (g);
4651
4652   memset (&ctx, 0, sizeof ctx);
4653
4654   args.arguments.arguments_val = (char **) arguments;
4655   for (args.arguments.arguments_len = 0; arguments[args.arguments.arguments_len]; args.arguments.arguments_len++) ;
4656   serial = guestfs__send_sync (g, GUESTFS_PROC_COMMAND_LINES,
4657         (xdrproc_t) xdr_guestfs_command_lines_args, (char *) &args);
4658   if (serial == -1) {
4659     guestfs_end_busy (g);
4660     return NULL;
4661   }
4662
4663   guestfs__switch_to_receiving (g);
4664   ctx.cb_sequence = 0;
4665   guestfs_set_reply_callback (g, command_lines_reply_cb, &ctx);
4666   (void) ml->main_loop_run (ml, g);
4667   guestfs_set_reply_callback (g, NULL, NULL);
4668   if (ctx.cb_sequence != 1) {
4669     error (g, "%s reply failed, see earlier error messages", "guestfs_command_lines");
4670     guestfs_end_busy (g);
4671     return NULL;
4672   }
4673
4674   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_COMMAND_LINES, serial) == -1) {
4675     guestfs_end_busy (g);
4676     return NULL;
4677   }
4678
4679   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4680     error (g, "%s", ctx.err.error_message);
4681     free (ctx.err.error_message);
4682     guestfs_end_busy (g);
4683     return NULL;
4684   }
4685
4686   guestfs_end_busy (g);
4687   /* caller will free this, but we need to add a NULL entry */
4688   ctx.ret.lines.lines_val =
4689     safe_realloc (g, ctx.ret.lines.lines_val,
4690                   sizeof (char *) * (ctx.ret.lines.lines_len + 1));
4691   ctx.ret.lines.lines_val[ctx.ret.lines.lines_len] = NULL;
4692   return ctx.ret.lines.lines_val;
4693 }
4694
4695 struct stat_ctx {
4696   /* This flag is set by the callbacks, so we know we've done
4697    * the callbacks as expected, and in the right sequence.
4698    * 0 = not called, 1 = reply_cb called.
4699    */
4700   int cb_sequence;
4701   struct guestfs_message_header hdr;
4702   struct guestfs_message_error err;
4703   struct guestfs_stat_ret ret;
4704 };
4705
4706 static void stat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4707 {
4708   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4709   struct stat_ctx *ctx = (struct stat_ctx *) data;
4710
4711   /* This should definitely not happen. */
4712   if (ctx->cb_sequence != 0) {
4713     ctx->cb_sequence = 9999;
4714     error (g, "%s: internal error: reply callback called twice", "guestfs_stat");
4715     return;
4716   }
4717
4718   ml->main_loop_quit (ml, g);
4719
4720   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4721     error (g, "%s: failed to parse reply header", "guestfs_stat");
4722     return;
4723   }
4724   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4725     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4726       error (g, "%s: failed to parse reply error", "guestfs_stat");
4727       return;
4728     }
4729     goto done;
4730   }
4731   if (!xdr_guestfs_stat_ret (xdr, &ctx->ret)) {
4732     error (g, "%s: failed to parse reply", "guestfs_stat");
4733     return;
4734   }
4735  done:
4736   ctx->cb_sequence = 1;
4737 }
4738
4739 struct guestfs_stat *guestfs_stat (guestfs_h *g,
4740                 const char *path)
4741 {
4742   struct guestfs_stat_args args;
4743   struct stat_ctx ctx;
4744   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4745   int serial;
4746
4747   if (check_state (g, "guestfs_stat") == -1) return NULL;
4748   guestfs_set_busy (g);
4749
4750   memset (&ctx, 0, sizeof ctx);
4751
4752   args.path = (char *) path;
4753   serial = guestfs__send_sync (g, GUESTFS_PROC_STAT,
4754         (xdrproc_t) xdr_guestfs_stat_args, (char *) &args);
4755   if (serial == -1) {
4756     guestfs_end_busy (g);
4757     return NULL;
4758   }
4759
4760   guestfs__switch_to_receiving (g);
4761   ctx.cb_sequence = 0;
4762   guestfs_set_reply_callback (g, stat_reply_cb, &ctx);
4763   (void) ml->main_loop_run (ml, g);
4764   guestfs_set_reply_callback (g, NULL, NULL);
4765   if (ctx.cb_sequence != 1) {
4766     error (g, "%s reply failed, see earlier error messages", "guestfs_stat");
4767     guestfs_end_busy (g);
4768     return NULL;
4769   }
4770
4771   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STAT, serial) == -1) {
4772     guestfs_end_busy (g);
4773     return NULL;
4774   }
4775
4776   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4777     error (g, "%s", ctx.err.error_message);
4778     free (ctx.err.error_message);
4779     guestfs_end_busy (g);
4780     return NULL;
4781   }
4782
4783   guestfs_end_busy (g);
4784   /* caller will free this */
4785   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4786 }
4787
4788 struct lstat_ctx {
4789   /* This flag is set by the callbacks, so we know we've done
4790    * the callbacks as expected, and in the right sequence.
4791    * 0 = not called, 1 = reply_cb called.
4792    */
4793   int cb_sequence;
4794   struct guestfs_message_header hdr;
4795   struct guestfs_message_error err;
4796   struct guestfs_lstat_ret ret;
4797 };
4798
4799 static void lstat_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4800 {
4801   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4802   struct lstat_ctx *ctx = (struct lstat_ctx *) data;
4803
4804   /* This should definitely not happen. */
4805   if (ctx->cb_sequence != 0) {
4806     ctx->cb_sequence = 9999;
4807     error (g, "%s: internal error: reply callback called twice", "guestfs_lstat");
4808     return;
4809   }
4810
4811   ml->main_loop_quit (ml, g);
4812
4813   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4814     error (g, "%s: failed to parse reply header", "guestfs_lstat");
4815     return;
4816   }
4817   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4818     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4819       error (g, "%s: failed to parse reply error", "guestfs_lstat");
4820       return;
4821     }
4822     goto done;
4823   }
4824   if (!xdr_guestfs_lstat_ret (xdr, &ctx->ret)) {
4825     error (g, "%s: failed to parse reply", "guestfs_lstat");
4826     return;
4827   }
4828  done:
4829   ctx->cb_sequence = 1;
4830 }
4831
4832 struct guestfs_stat *guestfs_lstat (guestfs_h *g,
4833                 const char *path)
4834 {
4835   struct guestfs_lstat_args args;
4836   struct lstat_ctx ctx;
4837   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4838   int serial;
4839
4840   if (check_state (g, "guestfs_lstat") == -1) return NULL;
4841   guestfs_set_busy (g);
4842
4843   memset (&ctx, 0, sizeof ctx);
4844
4845   args.path = (char *) path;
4846   serial = guestfs__send_sync (g, GUESTFS_PROC_LSTAT,
4847         (xdrproc_t) xdr_guestfs_lstat_args, (char *) &args);
4848   if (serial == -1) {
4849     guestfs_end_busy (g);
4850     return NULL;
4851   }
4852
4853   guestfs__switch_to_receiving (g);
4854   ctx.cb_sequence = 0;
4855   guestfs_set_reply_callback (g, lstat_reply_cb, &ctx);
4856   (void) ml->main_loop_run (ml, g);
4857   guestfs_set_reply_callback (g, NULL, NULL);
4858   if (ctx.cb_sequence != 1) {
4859     error (g, "%s reply failed, see earlier error messages", "guestfs_lstat");
4860     guestfs_end_busy (g);
4861     return NULL;
4862   }
4863
4864   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LSTAT, serial) == -1) {
4865     guestfs_end_busy (g);
4866     return NULL;
4867   }
4868
4869   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4870     error (g, "%s", ctx.err.error_message);
4871     free (ctx.err.error_message);
4872     guestfs_end_busy (g);
4873     return NULL;
4874   }
4875
4876   guestfs_end_busy (g);
4877   /* caller will free this */
4878   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4879 }
4880
4881 struct statvfs_ctx {
4882   /* This flag is set by the callbacks, so we know we've done
4883    * the callbacks as expected, and in the right sequence.
4884    * 0 = not called, 1 = reply_cb called.
4885    */
4886   int cb_sequence;
4887   struct guestfs_message_header hdr;
4888   struct guestfs_message_error err;
4889   struct guestfs_statvfs_ret ret;
4890 };
4891
4892 static void statvfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4893 {
4894   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4895   struct statvfs_ctx *ctx = (struct statvfs_ctx *) data;
4896
4897   /* This should definitely not happen. */
4898   if (ctx->cb_sequence != 0) {
4899     ctx->cb_sequence = 9999;
4900     error (g, "%s: internal error: reply callback called twice", "guestfs_statvfs");
4901     return;
4902   }
4903
4904   ml->main_loop_quit (ml, g);
4905
4906   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
4907     error (g, "%s: failed to parse reply header", "guestfs_statvfs");
4908     return;
4909   }
4910   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
4911     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
4912       error (g, "%s: failed to parse reply error", "guestfs_statvfs");
4913       return;
4914     }
4915     goto done;
4916   }
4917   if (!xdr_guestfs_statvfs_ret (xdr, &ctx->ret)) {
4918     error (g, "%s: failed to parse reply", "guestfs_statvfs");
4919     return;
4920   }
4921  done:
4922   ctx->cb_sequence = 1;
4923 }
4924
4925 struct guestfs_statvfs *guestfs_statvfs (guestfs_h *g,
4926                 const char *path)
4927 {
4928   struct guestfs_statvfs_args args;
4929   struct statvfs_ctx ctx;
4930   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4931   int serial;
4932
4933   if (check_state (g, "guestfs_statvfs") == -1) return NULL;
4934   guestfs_set_busy (g);
4935
4936   memset (&ctx, 0, sizeof ctx);
4937
4938   args.path = (char *) path;
4939   serial = guestfs__send_sync (g, GUESTFS_PROC_STATVFS,
4940         (xdrproc_t) xdr_guestfs_statvfs_args, (char *) &args);
4941   if (serial == -1) {
4942     guestfs_end_busy (g);
4943     return NULL;
4944   }
4945
4946   guestfs__switch_to_receiving (g);
4947   ctx.cb_sequence = 0;
4948   guestfs_set_reply_callback (g, statvfs_reply_cb, &ctx);
4949   (void) ml->main_loop_run (ml, g);
4950   guestfs_set_reply_callback (g, NULL, NULL);
4951   if (ctx.cb_sequence != 1) {
4952     error (g, "%s reply failed, see earlier error messages", "guestfs_statvfs");
4953     guestfs_end_busy (g);
4954     return NULL;
4955   }
4956
4957   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STATVFS, serial) == -1) {
4958     guestfs_end_busy (g);
4959     return NULL;
4960   }
4961
4962   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
4963     error (g, "%s", ctx.err.error_message);
4964     free (ctx.err.error_message);
4965     guestfs_end_busy (g);
4966     return NULL;
4967   }
4968
4969   guestfs_end_busy (g);
4970   /* caller will free this */
4971   return safe_memdup (g, &ctx.ret.statbuf, sizeof (ctx.ret.statbuf));
4972 }
4973
4974 struct tune2fs_l_ctx {
4975   /* This flag is set by the callbacks, so we know we've done
4976    * the callbacks as expected, and in the right sequence.
4977    * 0 = not called, 1 = reply_cb called.
4978    */
4979   int cb_sequence;
4980   struct guestfs_message_header hdr;
4981   struct guestfs_message_error err;
4982   struct guestfs_tune2fs_l_ret ret;
4983 };
4984
4985 static void tune2fs_l_reply_cb (guestfs_h *g, void *data, XDR *xdr)
4986 {
4987   guestfs_main_loop *ml = guestfs_get_main_loop (g);
4988   struct tune2fs_l_ctx *ctx = (struct tune2fs_l_ctx *) data;
4989
4990   /* This should definitely not happen. */
4991   if (ctx->cb_sequence != 0) {
4992     ctx->cb_sequence = 9999;
4993     error (g, "%s: internal error: reply callback called twice", "guestfs_tune2fs_l");
4994     return;
4995   }
4996
4997   ml->main_loop_quit (ml, g);
4998
4999   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5000     error (g, "%s: failed to parse reply header", "guestfs_tune2fs_l");
5001     return;
5002   }
5003   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5004     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5005       error (g, "%s: failed to parse reply error", "guestfs_tune2fs_l");
5006       return;
5007     }
5008     goto done;
5009   }
5010   if (!xdr_guestfs_tune2fs_l_ret (xdr, &ctx->ret)) {
5011     error (g, "%s: failed to parse reply", "guestfs_tune2fs_l");
5012     return;
5013   }
5014  done:
5015   ctx->cb_sequence = 1;
5016 }
5017
5018 char **guestfs_tune2fs_l (guestfs_h *g,
5019                 const char *device)
5020 {
5021   struct guestfs_tune2fs_l_args args;
5022   struct tune2fs_l_ctx ctx;
5023   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5024   int serial;
5025
5026   if (check_state (g, "guestfs_tune2fs_l") == -1) return NULL;
5027   guestfs_set_busy (g);
5028
5029   memset (&ctx, 0, sizeof ctx);
5030
5031   args.device = (char *) device;
5032   serial = guestfs__send_sync (g, GUESTFS_PROC_TUNE2FS_L,
5033         (xdrproc_t) xdr_guestfs_tune2fs_l_args, (char *) &args);
5034   if (serial == -1) {
5035     guestfs_end_busy (g);
5036     return NULL;
5037   }
5038
5039   guestfs__switch_to_receiving (g);
5040   ctx.cb_sequence = 0;
5041   guestfs_set_reply_callback (g, tune2fs_l_reply_cb, &ctx);
5042   (void) ml->main_loop_run (ml, g);
5043   guestfs_set_reply_callback (g, NULL, NULL);
5044   if (ctx.cb_sequence != 1) {
5045     error (g, "%s reply failed, see earlier error messages", "guestfs_tune2fs_l");
5046     guestfs_end_busy (g);
5047     return NULL;
5048   }
5049
5050   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TUNE2FS_L, serial) == -1) {
5051     guestfs_end_busy (g);
5052     return NULL;
5053   }
5054
5055   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5056     error (g, "%s", ctx.err.error_message);
5057     free (ctx.err.error_message);
5058     guestfs_end_busy (g);
5059     return NULL;
5060   }
5061
5062   guestfs_end_busy (g);
5063   /* caller will free this, but we need to add a NULL entry */
5064   ctx.ret.superblock.superblock_val =
5065     safe_realloc (g, ctx.ret.superblock.superblock_val,
5066                   sizeof (char *) * (ctx.ret.superblock.superblock_len + 1));
5067   ctx.ret.superblock.superblock_val[ctx.ret.superblock.superblock_len] = NULL;
5068   return ctx.ret.superblock.superblock_val;
5069 }
5070
5071 struct blockdev_setro_ctx {
5072   /* This flag is set by the callbacks, so we know we've done
5073    * the callbacks as expected, and in the right sequence.
5074    * 0 = not called, 1 = reply_cb called.
5075    */
5076   int cb_sequence;
5077   struct guestfs_message_header hdr;
5078   struct guestfs_message_error err;
5079 };
5080
5081 static void blockdev_setro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5082 {
5083   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5084   struct blockdev_setro_ctx *ctx = (struct blockdev_setro_ctx *) data;
5085
5086   /* This should definitely not happen. */
5087   if (ctx->cb_sequence != 0) {
5088     ctx->cb_sequence = 9999;
5089     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_setro");
5090     return;
5091   }
5092
5093   ml->main_loop_quit (ml, g);
5094
5095   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5096     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setro");
5097     return;
5098   }
5099   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5100     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5101       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setro");
5102       return;
5103     }
5104     goto done;
5105   }
5106  done:
5107   ctx->cb_sequence = 1;
5108 }
5109
5110 int guestfs_blockdev_setro (guestfs_h *g,
5111                 const char *device)
5112 {
5113   struct guestfs_blockdev_setro_args args;
5114   struct blockdev_setro_ctx ctx;
5115   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5116   int serial;
5117
5118   if (check_state (g, "guestfs_blockdev_setro") == -1) return -1;
5119   guestfs_set_busy (g);
5120
5121   memset (&ctx, 0, sizeof ctx);
5122
5123   args.device = (char *) device;
5124   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETRO,
5125         (xdrproc_t) xdr_guestfs_blockdev_setro_args, (char *) &args);
5126   if (serial == -1) {
5127     guestfs_end_busy (g);
5128     return -1;
5129   }
5130
5131   guestfs__switch_to_receiving (g);
5132   ctx.cb_sequence = 0;
5133   guestfs_set_reply_callback (g, blockdev_setro_reply_cb, &ctx);
5134   (void) ml->main_loop_run (ml, g);
5135   guestfs_set_reply_callback (g, NULL, NULL);
5136   if (ctx.cb_sequence != 1) {
5137     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setro");
5138     guestfs_end_busy (g);
5139     return -1;
5140   }
5141
5142   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETRO, serial) == -1) {
5143     guestfs_end_busy (g);
5144     return -1;
5145   }
5146
5147   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5148     error (g, "%s", ctx.err.error_message);
5149     free (ctx.err.error_message);
5150     guestfs_end_busy (g);
5151     return -1;
5152   }
5153
5154   guestfs_end_busy (g);
5155   return 0;
5156 }
5157
5158 struct blockdev_setrw_ctx {
5159   /* This flag is set by the callbacks, so we know we've done
5160    * the callbacks as expected, and in the right sequence.
5161    * 0 = not called, 1 = reply_cb called.
5162    */
5163   int cb_sequence;
5164   struct guestfs_message_header hdr;
5165   struct guestfs_message_error err;
5166 };
5167
5168 static void blockdev_setrw_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5169 {
5170   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5171   struct blockdev_setrw_ctx *ctx = (struct blockdev_setrw_ctx *) data;
5172
5173   /* This should definitely not happen. */
5174   if (ctx->cb_sequence != 0) {
5175     ctx->cb_sequence = 9999;
5176     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_setrw");
5177     return;
5178   }
5179
5180   ml->main_loop_quit (ml, g);
5181
5182   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5183     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setrw");
5184     return;
5185   }
5186   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5187     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5188       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setrw");
5189       return;
5190     }
5191     goto done;
5192   }
5193  done:
5194   ctx->cb_sequence = 1;
5195 }
5196
5197 int guestfs_blockdev_setrw (guestfs_h *g,
5198                 const char *device)
5199 {
5200   struct guestfs_blockdev_setrw_args args;
5201   struct blockdev_setrw_ctx ctx;
5202   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5203   int serial;
5204
5205   if (check_state (g, "guestfs_blockdev_setrw") == -1) return -1;
5206   guestfs_set_busy (g);
5207
5208   memset (&ctx, 0, sizeof ctx);
5209
5210   args.device = (char *) device;
5211   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETRW,
5212         (xdrproc_t) xdr_guestfs_blockdev_setrw_args, (char *) &args);
5213   if (serial == -1) {
5214     guestfs_end_busy (g);
5215     return -1;
5216   }
5217
5218   guestfs__switch_to_receiving (g);
5219   ctx.cb_sequence = 0;
5220   guestfs_set_reply_callback (g, blockdev_setrw_reply_cb, &ctx);
5221   (void) ml->main_loop_run (ml, g);
5222   guestfs_set_reply_callback (g, NULL, NULL);
5223   if (ctx.cb_sequence != 1) {
5224     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setrw");
5225     guestfs_end_busy (g);
5226     return -1;
5227   }
5228
5229   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETRW, serial) == -1) {
5230     guestfs_end_busy (g);
5231     return -1;
5232   }
5233
5234   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5235     error (g, "%s", ctx.err.error_message);
5236     free (ctx.err.error_message);
5237     guestfs_end_busy (g);
5238     return -1;
5239   }
5240
5241   guestfs_end_busy (g);
5242   return 0;
5243 }
5244
5245 struct blockdev_getro_ctx {
5246   /* This flag is set by the callbacks, so we know we've done
5247    * the callbacks as expected, and in the right sequence.
5248    * 0 = not called, 1 = reply_cb called.
5249    */
5250   int cb_sequence;
5251   struct guestfs_message_header hdr;
5252   struct guestfs_message_error err;
5253   struct guestfs_blockdev_getro_ret ret;
5254 };
5255
5256 static void blockdev_getro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5257 {
5258   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5259   struct blockdev_getro_ctx *ctx = (struct blockdev_getro_ctx *) data;
5260
5261   /* This should definitely not happen. */
5262   if (ctx->cb_sequence != 0) {
5263     ctx->cb_sequence = 9999;
5264     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_getro");
5265     return;
5266   }
5267
5268   ml->main_loop_quit (ml, g);
5269
5270   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5271     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getro");
5272     return;
5273   }
5274   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5275     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5276       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getro");
5277       return;
5278     }
5279     goto done;
5280   }
5281   if (!xdr_guestfs_blockdev_getro_ret (xdr, &ctx->ret)) {
5282     error (g, "%s: failed to parse reply", "guestfs_blockdev_getro");
5283     return;
5284   }
5285  done:
5286   ctx->cb_sequence = 1;
5287 }
5288
5289 int guestfs_blockdev_getro (guestfs_h *g,
5290                 const char *device)
5291 {
5292   struct guestfs_blockdev_getro_args args;
5293   struct blockdev_getro_ctx ctx;
5294   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5295   int serial;
5296
5297   if (check_state (g, "guestfs_blockdev_getro") == -1) return -1;
5298   guestfs_set_busy (g);
5299
5300   memset (&ctx, 0, sizeof ctx);
5301
5302   args.device = (char *) device;
5303   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETRO,
5304         (xdrproc_t) xdr_guestfs_blockdev_getro_args, (char *) &args);
5305   if (serial == -1) {
5306     guestfs_end_busy (g);
5307     return -1;
5308   }
5309
5310   guestfs__switch_to_receiving (g);
5311   ctx.cb_sequence = 0;
5312   guestfs_set_reply_callback (g, blockdev_getro_reply_cb, &ctx);
5313   (void) ml->main_loop_run (ml, g);
5314   guestfs_set_reply_callback (g, NULL, NULL);
5315   if (ctx.cb_sequence != 1) {
5316     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getro");
5317     guestfs_end_busy (g);
5318     return -1;
5319   }
5320
5321   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETRO, serial) == -1) {
5322     guestfs_end_busy (g);
5323     return -1;
5324   }
5325
5326   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5327     error (g, "%s", ctx.err.error_message);
5328     free (ctx.err.error_message);
5329     guestfs_end_busy (g);
5330     return -1;
5331   }
5332
5333   guestfs_end_busy (g);
5334   return ctx.ret.ro;
5335 }
5336
5337 struct blockdev_getss_ctx {
5338   /* This flag is set by the callbacks, so we know we've done
5339    * the callbacks as expected, and in the right sequence.
5340    * 0 = not called, 1 = reply_cb called.
5341    */
5342   int cb_sequence;
5343   struct guestfs_message_header hdr;
5344   struct guestfs_message_error err;
5345   struct guestfs_blockdev_getss_ret ret;
5346 };
5347
5348 static void blockdev_getss_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5349 {
5350   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5351   struct blockdev_getss_ctx *ctx = (struct blockdev_getss_ctx *) data;
5352
5353   /* This should definitely not happen. */
5354   if (ctx->cb_sequence != 0) {
5355     ctx->cb_sequence = 9999;
5356     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_getss");
5357     return;
5358   }
5359
5360   ml->main_loop_quit (ml, g);
5361
5362   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5363     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getss");
5364     return;
5365   }
5366   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5367     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5368       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getss");
5369       return;
5370     }
5371     goto done;
5372   }
5373   if (!xdr_guestfs_blockdev_getss_ret (xdr, &ctx->ret)) {
5374     error (g, "%s: failed to parse reply", "guestfs_blockdev_getss");
5375     return;
5376   }
5377  done:
5378   ctx->cb_sequence = 1;
5379 }
5380
5381 int guestfs_blockdev_getss (guestfs_h *g,
5382                 const char *device)
5383 {
5384   struct guestfs_blockdev_getss_args args;
5385   struct blockdev_getss_ctx ctx;
5386   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5387   int serial;
5388
5389   if (check_state (g, "guestfs_blockdev_getss") == -1) return -1;
5390   guestfs_set_busy (g);
5391
5392   memset (&ctx, 0, sizeof ctx);
5393
5394   args.device = (char *) device;
5395   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSS,
5396         (xdrproc_t) xdr_guestfs_blockdev_getss_args, (char *) &args);
5397   if (serial == -1) {
5398     guestfs_end_busy (g);
5399     return -1;
5400   }
5401
5402   guestfs__switch_to_receiving (g);
5403   ctx.cb_sequence = 0;
5404   guestfs_set_reply_callback (g, blockdev_getss_reply_cb, &ctx);
5405   (void) ml->main_loop_run (ml, g);
5406   guestfs_set_reply_callback (g, NULL, NULL);
5407   if (ctx.cb_sequence != 1) {
5408     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getss");
5409     guestfs_end_busy (g);
5410     return -1;
5411   }
5412
5413   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSS, serial) == -1) {
5414     guestfs_end_busy (g);
5415     return -1;
5416   }
5417
5418   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5419     error (g, "%s", ctx.err.error_message);
5420     free (ctx.err.error_message);
5421     guestfs_end_busy (g);
5422     return -1;
5423   }
5424
5425   guestfs_end_busy (g);
5426   return ctx.ret.sectorsize;
5427 }
5428
5429 struct blockdev_getbsz_ctx {
5430   /* This flag is set by the callbacks, so we know we've done
5431    * the callbacks as expected, and in the right sequence.
5432    * 0 = not called, 1 = reply_cb called.
5433    */
5434   int cb_sequence;
5435   struct guestfs_message_header hdr;
5436   struct guestfs_message_error err;
5437   struct guestfs_blockdev_getbsz_ret ret;
5438 };
5439
5440 static void blockdev_getbsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5441 {
5442   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5443   struct blockdev_getbsz_ctx *ctx = (struct blockdev_getbsz_ctx *) data;
5444
5445   /* This should definitely not happen. */
5446   if (ctx->cb_sequence != 0) {
5447     ctx->cb_sequence = 9999;
5448     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_getbsz");
5449     return;
5450   }
5451
5452   ml->main_loop_quit (ml, g);
5453
5454   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5455     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getbsz");
5456     return;
5457   }
5458   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5459     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5460       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getbsz");
5461       return;
5462     }
5463     goto done;
5464   }
5465   if (!xdr_guestfs_blockdev_getbsz_ret (xdr, &ctx->ret)) {
5466     error (g, "%s: failed to parse reply", "guestfs_blockdev_getbsz");
5467     return;
5468   }
5469  done:
5470   ctx->cb_sequence = 1;
5471 }
5472
5473 int guestfs_blockdev_getbsz (guestfs_h *g,
5474                 const char *device)
5475 {
5476   struct guestfs_blockdev_getbsz_args args;
5477   struct blockdev_getbsz_ctx ctx;
5478   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5479   int serial;
5480
5481   if (check_state (g, "guestfs_blockdev_getbsz") == -1) return -1;
5482   guestfs_set_busy (g);
5483
5484   memset (&ctx, 0, sizeof ctx);
5485
5486   args.device = (char *) device;
5487   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETBSZ,
5488         (xdrproc_t) xdr_guestfs_blockdev_getbsz_args, (char *) &args);
5489   if (serial == -1) {
5490     guestfs_end_busy (g);
5491     return -1;
5492   }
5493
5494   guestfs__switch_to_receiving (g);
5495   ctx.cb_sequence = 0;
5496   guestfs_set_reply_callback (g, blockdev_getbsz_reply_cb, &ctx);
5497   (void) ml->main_loop_run (ml, g);
5498   guestfs_set_reply_callback (g, NULL, NULL);
5499   if (ctx.cb_sequence != 1) {
5500     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getbsz");
5501     guestfs_end_busy (g);
5502     return -1;
5503   }
5504
5505   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETBSZ, serial) == -1) {
5506     guestfs_end_busy (g);
5507     return -1;
5508   }
5509
5510   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5511     error (g, "%s", ctx.err.error_message);
5512     free (ctx.err.error_message);
5513     guestfs_end_busy (g);
5514     return -1;
5515   }
5516
5517   guestfs_end_busy (g);
5518   return ctx.ret.blocksize;
5519 }
5520
5521 struct blockdev_setbsz_ctx {
5522   /* This flag is set by the callbacks, so we know we've done
5523    * the callbacks as expected, and in the right sequence.
5524    * 0 = not called, 1 = reply_cb called.
5525    */
5526   int cb_sequence;
5527   struct guestfs_message_header hdr;
5528   struct guestfs_message_error err;
5529 };
5530
5531 static void blockdev_setbsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5532 {
5533   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5534   struct blockdev_setbsz_ctx *ctx = (struct blockdev_setbsz_ctx *) data;
5535
5536   /* This should definitely not happen. */
5537   if (ctx->cb_sequence != 0) {
5538     ctx->cb_sequence = 9999;
5539     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_setbsz");
5540     return;
5541   }
5542
5543   ml->main_loop_quit (ml, g);
5544
5545   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5546     error (g, "%s: failed to parse reply header", "guestfs_blockdev_setbsz");
5547     return;
5548   }
5549   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5550     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5551       error (g, "%s: failed to parse reply error", "guestfs_blockdev_setbsz");
5552       return;
5553     }
5554     goto done;
5555   }
5556  done:
5557   ctx->cb_sequence = 1;
5558 }
5559
5560 int guestfs_blockdev_setbsz (guestfs_h *g,
5561                 const char *device,
5562                 int blocksize)
5563 {
5564   struct guestfs_blockdev_setbsz_args args;
5565   struct blockdev_setbsz_ctx ctx;
5566   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5567   int serial;
5568
5569   if (check_state (g, "guestfs_blockdev_setbsz") == -1) return -1;
5570   guestfs_set_busy (g);
5571
5572   memset (&ctx, 0, sizeof ctx);
5573
5574   args.device = (char *) device;
5575   args.blocksize = blocksize;
5576   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_SETBSZ,
5577         (xdrproc_t) xdr_guestfs_blockdev_setbsz_args, (char *) &args);
5578   if (serial == -1) {
5579     guestfs_end_busy (g);
5580     return -1;
5581   }
5582
5583   guestfs__switch_to_receiving (g);
5584   ctx.cb_sequence = 0;
5585   guestfs_set_reply_callback (g, blockdev_setbsz_reply_cb, &ctx);
5586   (void) ml->main_loop_run (ml, g);
5587   guestfs_set_reply_callback (g, NULL, NULL);
5588   if (ctx.cb_sequence != 1) {
5589     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_setbsz");
5590     guestfs_end_busy (g);
5591     return -1;
5592   }
5593
5594   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_SETBSZ, serial) == -1) {
5595     guestfs_end_busy (g);
5596     return -1;
5597   }
5598
5599   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5600     error (g, "%s", ctx.err.error_message);
5601     free (ctx.err.error_message);
5602     guestfs_end_busy (g);
5603     return -1;
5604   }
5605
5606   guestfs_end_busy (g);
5607   return 0;
5608 }
5609
5610 struct blockdev_getsz_ctx {
5611   /* This flag is set by the callbacks, so we know we've done
5612    * the callbacks as expected, and in the right sequence.
5613    * 0 = not called, 1 = reply_cb called.
5614    */
5615   int cb_sequence;
5616   struct guestfs_message_header hdr;
5617   struct guestfs_message_error err;
5618   struct guestfs_blockdev_getsz_ret ret;
5619 };
5620
5621 static void blockdev_getsz_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5622 {
5623   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5624   struct blockdev_getsz_ctx *ctx = (struct blockdev_getsz_ctx *) data;
5625
5626   /* This should definitely not happen. */
5627   if (ctx->cb_sequence != 0) {
5628     ctx->cb_sequence = 9999;
5629     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_getsz");
5630     return;
5631   }
5632
5633   ml->main_loop_quit (ml, g);
5634
5635   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5636     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getsz");
5637     return;
5638   }
5639   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5640     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5641       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getsz");
5642       return;
5643     }
5644     goto done;
5645   }
5646   if (!xdr_guestfs_blockdev_getsz_ret (xdr, &ctx->ret)) {
5647     error (g, "%s: failed to parse reply", "guestfs_blockdev_getsz");
5648     return;
5649   }
5650  done:
5651   ctx->cb_sequence = 1;
5652 }
5653
5654 int64_t guestfs_blockdev_getsz (guestfs_h *g,
5655                 const char *device)
5656 {
5657   struct guestfs_blockdev_getsz_args args;
5658   struct blockdev_getsz_ctx ctx;
5659   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5660   int serial;
5661
5662   if (check_state (g, "guestfs_blockdev_getsz") == -1) return -1;
5663   guestfs_set_busy (g);
5664
5665   memset (&ctx, 0, sizeof ctx);
5666
5667   args.device = (char *) device;
5668   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSZ,
5669         (xdrproc_t) xdr_guestfs_blockdev_getsz_args, (char *) &args);
5670   if (serial == -1) {
5671     guestfs_end_busy (g);
5672     return -1;
5673   }
5674
5675   guestfs__switch_to_receiving (g);
5676   ctx.cb_sequence = 0;
5677   guestfs_set_reply_callback (g, blockdev_getsz_reply_cb, &ctx);
5678   (void) ml->main_loop_run (ml, g);
5679   guestfs_set_reply_callback (g, NULL, NULL);
5680   if (ctx.cb_sequence != 1) {
5681     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getsz");
5682     guestfs_end_busy (g);
5683     return -1;
5684   }
5685
5686   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSZ, serial) == -1) {
5687     guestfs_end_busy (g);
5688     return -1;
5689   }
5690
5691   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5692     error (g, "%s", ctx.err.error_message);
5693     free (ctx.err.error_message);
5694     guestfs_end_busy (g);
5695     return -1;
5696   }
5697
5698   guestfs_end_busy (g);
5699   return ctx.ret.sizeinsectors;
5700 }
5701
5702 struct blockdev_getsize64_ctx {
5703   /* This flag is set by the callbacks, so we know we've done
5704    * the callbacks as expected, and in the right sequence.
5705    * 0 = not called, 1 = reply_cb called.
5706    */
5707   int cb_sequence;
5708   struct guestfs_message_header hdr;
5709   struct guestfs_message_error err;
5710   struct guestfs_blockdev_getsize64_ret ret;
5711 };
5712
5713 static void blockdev_getsize64_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5714 {
5715   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5716   struct blockdev_getsize64_ctx *ctx = (struct blockdev_getsize64_ctx *) data;
5717
5718   /* This should definitely not happen. */
5719   if (ctx->cb_sequence != 0) {
5720     ctx->cb_sequence = 9999;
5721     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_getsize64");
5722     return;
5723   }
5724
5725   ml->main_loop_quit (ml, g);
5726
5727   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5728     error (g, "%s: failed to parse reply header", "guestfs_blockdev_getsize64");
5729     return;
5730   }
5731   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5732     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5733       error (g, "%s: failed to parse reply error", "guestfs_blockdev_getsize64");
5734       return;
5735     }
5736     goto done;
5737   }
5738   if (!xdr_guestfs_blockdev_getsize64_ret (xdr, &ctx->ret)) {
5739     error (g, "%s: failed to parse reply", "guestfs_blockdev_getsize64");
5740     return;
5741   }
5742  done:
5743   ctx->cb_sequence = 1;
5744 }
5745
5746 int64_t guestfs_blockdev_getsize64 (guestfs_h *g,
5747                 const char *device)
5748 {
5749   struct guestfs_blockdev_getsize64_args args;
5750   struct blockdev_getsize64_ctx ctx;
5751   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5752   int serial;
5753
5754   if (check_state (g, "guestfs_blockdev_getsize64") == -1) return -1;
5755   guestfs_set_busy (g);
5756
5757   memset (&ctx, 0, sizeof ctx);
5758
5759   args.device = (char *) device;
5760   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_GETSIZE64,
5761         (xdrproc_t) xdr_guestfs_blockdev_getsize64_args, (char *) &args);
5762   if (serial == -1) {
5763     guestfs_end_busy (g);
5764     return -1;
5765   }
5766
5767   guestfs__switch_to_receiving (g);
5768   ctx.cb_sequence = 0;
5769   guestfs_set_reply_callback (g, blockdev_getsize64_reply_cb, &ctx);
5770   (void) ml->main_loop_run (ml, g);
5771   guestfs_set_reply_callback (g, NULL, NULL);
5772   if (ctx.cb_sequence != 1) {
5773     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_getsize64");
5774     guestfs_end_busy (g);
5775     return -1;
5776   }
5777
5778   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_GETSIZE64, serial) == -1) {
5779     guestfs_end_busy (g);
5780     return -1;
5781   }
5782
5783   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5784     error (g, "%s", ctx.err.error_message);
5785     free (ctx.err.error_message);
5786     guestfs_end_busy (g);
5787     return -1;
5788   }
5789
5790   guestfs_end_busy (g);
5791   return ctx.ret.sizeinbytes;
5792 }
5793
5794 struct blockdev_flushbufs_ctx {
5795   /* This flag is set by the callbacks, so we know we've done
5796    * the callbacks as expected, and in the right sequence.
5797    * 0 = not called, 1 = reply_cb called.
5798    */
5799   int cb_sequence;
5800   struct guestfs_message_header hdr;
5801   struct guestfs_message_error err;
5802 };
5803
5804 static void blockdev_flushbufs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5805 {
5806   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5807   struct blockdev_flushbufs_ctx *ctx = (struct blockdev_flushbufs_ctx *) data;
5808
5809   /* This should definitely not happen. */
5810   if (ctx->cb_sequence != 0) {
5811     ctx->cb_sequence = 9999;
5812     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_flushbufs");
5813     return;
5814   }
5815
5816   ml->main_loop_quit (ml, g);
5817
5818   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5819     error (g, "%s: failed to parse reply header", "guestfs_blockdev_flushbufs");
5820     return;
5821   }
5822   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5823     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5824       error (g, "%s: failed to parse reply error", "guestfs_blockdev_flushbufs");
5825       return;
5826     }
5827     goto done;
5828   }
5829  done:
5830   ctx->cb_sequence = 1;
5831 }
5832
5833 int guestfs_blockdev_flushbufs (guestfs_h *g,
5834                 const char *device)
5835 {
5836   struct guestfs_blockdev_flushbufs_args args;
5837   struct blockdev_flushbufs_ctx ctx;
5838   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5839   int serial;
5840
5841   if (check_state (g, "guestfs_blockdev_flushbufs") == -1) return -1;
5842   guestfs_set_busy (g);
5843
5844   memset (&ctx, 0, sizeof ctx);
5845
5846   args.device = (char *) device;
5847   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS,
5848         (xdrproc_t) xdr_guestfs_blockdev_flushbufs_args, (char *) &args);
5849   if (serial == -1) {
5850     guestfs_end_busy (g);
5851     return -1;
5852   }
5853
5854   guestfs__switch_to_receiving (g);
5855   ctx.cb_sequence = 0;
5856   guestfs_set_reply_callback (g, blockdev_flushbufs_reply_cb, &ctx);
5857   (void) ml->main_loop_run (ml, g);
5858   guestfs_set_reply_callback (g, NULL, NULL);
5859   if (ctx.cb_sequence != 1) {
5860     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_flushbufs");
5861     guestfs_end_busy (g);
5862     return -1;
5863   }
5864
5865   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_FLUSHBUFS, serial) == -1) {
5866     guestfs_end_busy (g);
5867     return -1;
5868   }
5869
5870   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5871     error (g, "%s", ctx.err.error_message);
5872     free (ctx.err.error_message);
5873     guestfs_end_busy (g);
5874     return -1;
5875   }
5876
5877   guestfs_end_busy (g);
5878   return 0;
5879 }
5880
5881 struct blockdev_rereadpt_ctx {
5882   /* This flag is set by the callbacks, so we know we've done
5883    * the callbacks as expected, and in the right sequence.
5884    * 0 = not called, 1 = reply_cb called.
5885    */
5886   int cb_sequence;
5887   struct guestfs_message_header hdr;
5888   struct guestfs_message_error err;
5889 };
5890
5891 static void blockdev_rereadpt_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5892 {
5893   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5894   struct blockdev_rereadpt_ctx *ctx = (struct blockdev_rereadpt_ctx *) data;
5895
5896   /* This should definitely not happen. */
5897   if (ctx->cb_sequence != 0) {
5898     ctx->cb_sequence = 9999;
5899     error (g, "%s: internal error: reply callback called twice", "guestfs_blockdev_rereadpt");
5900     return;
5901   }
5902
5903   ml->main_loop_quit (ml, g);
5904
5905   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5906     error (g, "%s: failed to parse reply header", "guestfs_blockdev_rereadpt");
5907     return;
5908   }
5909   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5910     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5911       error (g, "%s: failed to parse reply error", "guestfs_blockdev_rereadpt");
5912       return;
5913     }
5914     goto done;
5915   }
5916  done:
5917   ctx->cb_sequence = 1;
5918 }
5919
5920 int guestfs_blockdev_rereadpt (guestfs_h *g,
5921                 const char *device)
5922 {
5923   struct guestfs_blockdev_rereadpt_args args;
5924   struct blockdev_rereadpt_ctx ctx;
5925   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5926   int serial;
5927
5928   if (check_state (g, "guestfs_blockdev_rereadpt") == -1) return -1;
5929   guestfs_set_busy (g);
5930
5931   memset (&ctx, 0, sizeof ctx);
5932
5933   args.device = (char *) device;
5934   serial = guestfs__send_sync (g, GUESTFS_PROC_BLOCKDEV_REREADPT,
5935         (xdrproc_t) xdr_guestfs_blockdev_rereadpt_args, (char *) &args);
5936   if (serial == -1) {
5937     guestfs_end_busy (g);
5938     return -1;
5939   }
5940
5941   guestfs__switch_to_receiving (g);
5942   ctx.cb_sequence = 0;
5943   guestfs_set_reply_callback (g, blockdev_rereadpt_reply_cb, &ctx);
5944   (void) ml->main_loop_run (ml, g);
5945   guestfs_set_reply_callback (g, NULL, NULL);
5946   if (ctx.cb_sequence != 1) {
5947     error (g, "%s reply failed, see earlier error messages", "guestfs_blockdev_rereadpt");
5948     guestfs_end_busy (g);
5949     return -1;
5950   }
5951
5952   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_BLOCKDEV_REREADPT, serial) == -1) {
5953     guestfs_end_busy (g);
5954     return -1;
5955   }
5956
5957   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
5958     error (g, "%s", ctx.err.error_message);
5959     free (ctx.err.error_message);
5960     guestfs_end_busy (g);
5961     return -1;
5962   }
5963
5964   guestfs_end_busy (g);
5965   return 0;
5966 }
5967
5968 struct upload_ctx {
5969   /* This flag is set by the callbacks, so we know we've done
5970    * the callbacks as expected, and in the right sequence.
5971    * 0 = not called, 1 = reply_cb called.
5972    */
5973   int cb_sequence;
5974   struct guestfs_message_header hdr;
5975   struct guestfs_message_error err;
5976 };
5977
5978 static void upload_reply_cb (guestfs_h *g, void *data, XDR *xdr)
5979 {
5980   guestfs_main_loop *ml = guestfs_get_main_loop (g);
5981   struct upload_ctx *ctx = (struct upload_ctx *) data;
5982
5983   /* This should definitely not happen. */
5984   if (ctx->cb_sequence != 0) {
5985     ctx->cb_sequence = 9999;
5986     error (g, "%s: internal error: reply callback called twice", "guestfs_upload");
5987     return;
5988   }
5989
5990   ml->main_loop_quit (ml, g);
5991
5992   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
5993     error (g, "%s: failed to parse reply header", "guestfs_upload");
5994     return;
5995   }
5996   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
5997     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
5998       error (g, "%s: failed to parse reply error", "guestfs_upload");
5999       return;
6000     }
6001     goto done;
6002   }
6003  done:
6004   ctx->cb_sequence = 1;
6005 }
6006
6007 int guestfs_upload (guestfs_h *g,
6008                 const char *filename,
6009                 const char *remotefilename)
6010 {
6011   struct guestfs_upload_args args;
6012   struct upload_ctx ctx;
6013   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6014   int serial;
6015
6016   if (check_state (g, "guestfs_upload") == -1) return -1;
6017   guestfs_set_busy (g);
6018
6019   memset (&ctx, 0, sizeof ctx);
6020
6021   args.remotefilename = (char *) remotefilename;
6022   serial = guestfs__send_sync (g, GUESTFS_PROC_UPLOAD,
6023         (xdrproc_t) xdr_guestfs_upload_args, (char *) &args);
6024   if (serial == -1) {
6025     guestfs_end_busy (g);
6026     return -1;
6027   }
6028
6029   {
6030     int r;
6031
6032     r = guestfs__send_file_sync (g, filename);
6033     if (r == -1) {
6034       guestfs_end_busy (g);
6035       return -1;
6036     }
6037     if (r == -2) /* daemon cancelled */
6038       goto read_reply;
6039   }
6040
6041  read_reply:
6042   guestfs__switch_to_receiving (g);
6043   ctx.cb_sequence = 0;
6044   guestfs_set_reply_callback (g, upload_reply_cb, &ctx);
6045   (void) ml->main_loop_run (ml, g);
6046   guestfs_set_reply_callback (g, NULL, NULL);
6047   if (ctx.cb_sequence != 1) {
6048     error (g, "%s reply failed, see earlier error messages", "guestfs_upload");
6049     guestfs_end_busy (g);
6050     return -1;
6051   }
6052
6053   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_UPLOAD, serial) == -1) {
6054     guestfs_end_busy (g);
6055     return -1;
6056   }
6057
6058   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6059     error (g, "%s", ctx.err.error_message);
6060     free (ctx.err.error_message);
6061     guestfs_end_busy (g);
6062     return -1;
6063   }
6064
6065   guestfs_end_busy (g);
6066   return 0;
6067 }
6068
6069 struct download_ctx {
6070   /* This flag is set by the callbacks, so we know we've done
6071    * the callbacks as expected, and in the right sequence.
6072    * 0 = not called, 1 = reply_cb called.
6073    */
6074   int cb_sequence;
6075   struct guestfs_message_header hdr;
6076   struct guestfs_message_error err;
6077 };
6078
6079 static void download_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6080 {
6081   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6082   struct download_ctx *ctx = (struct download_ctx *) data;
6083
6084   /* This should definitely not happen. */
6085   if (ctx->cb_sequence != 0) {
6086     ctx->cb_sequence = 9999;
6087     error (g, "%s: internal error: reply callback called twice", "guestfs_download");
6088     return;
6089   }
6090
6091   ml->main_loop_quit (ml, g);
6092
6093   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6094     error (g, "%s: failed to parse reply header", "guestfs_download");
6095     return;
6096   }
6097   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6098     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6099       error (g, "%s: failed to parse reply error", "guestfs_download");
6100       return;
6101     }
6102     goto done;
6103   }
6104  done:
6105   ctx->cb_sequence = 1;
6106 }
6107
6108 int guestfs_download (guestfs_h *g,
6109                 const char *remotefilename,
6110                 const char *filename)
6111 {
6112   struct guestfs_download_args args;
6113   struct download_ctx ctx;
6114   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6115   int serial;
6116
6117   if (check_state (g, "guestfs_download") == -1) return -1;
6118   guestfs_set_busy (g);
6119
6120   memset (&ctx, 0, sizeof ctx);
6121
6122   args.remotefilename = (char *) remotefilename;
6123   serial = guestfs__send_sync (g, GUESTFS_PROC_DOWNLOAD,
6124         (xdrproc_t) xdr_guestfs_download_args, (char *) &args);
6125   if (serial == -1) {
6126     guestfs_end_busy (g);
6127     return -1;
6128   }
6129
6130   guestfs__switch_to_receiving (g);
6131   ctx.cb_sequence = 0;
6132   guestfs_set_reply_callback (g, download_reply_cb, &ctx);
6133   (void) ml->main_loop_run (ml, g);
6134   guestfs_set_reply_callback (g, NULL, NULL);
6135   if (ctx.cb_sequence != 1) {
6136     error (g, "%s reply failed, see earlier error messages", "guestfs_download");
6137     guestfs_end_busy (g);
6138     return -1;
6139   }
6140
6141   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_DOWNLOAD, serial) == -1) {
6142     guestfs_end_busy (g);
6143     return -1;
6144   }
6145
6146   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6147     error (g, "%s", ctx.err.error_message);
6148     free (ctx.err.error_message);
6149     guestfs_end_busy (g);
6150     return -1;
6151   }
6152
6153   if (guestfs__receive_file_sync (g, filename) == -1) {
6154     guestfs_end_busy (g);
6155     return -1;
6156   }
6157
6158   guestfs_end_busy (g);
6159   return 0;
6160 }
6161
6162 struct checksum_ctx {
6163   /* This flag is set by the callbacks, so we know we've done
6164    * the callbacks as expected, and in the right sequence.
6165    * 0 = not called, 1 = reply_cb called.
6166    */
6167   int cb_sequence;
6168   struct guestfs_message_header hdr;
6169   struct guestfs_message_error err;
6170   struct guestfs_checksum_ret ret;
6171 };
6172
6173 static void checksum_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6174 {
6175   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6176   struct checksum_ctx *ctx = (struct checksum_ctx *) data;
6177
6178   /* This should definitely not happen. */
6179   if (ctx->cb_sequence != 0) {
6180     ctx->cb_sequence = 9999;
6181     error (g, "%s: internal error: reply callback called twice", "guestfs_checksum");
6182     return;
6183   }
6184
6185   ml->main_loop_quit (ml, g);
6186
6187   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6188     error (g, "%s: failed to parse reply header", "guestfs_checksum");
6189     return;
6190   }
6191   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6192     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6193       error (g, "%s: failed to parse reply error", "guestfs_checksum");
6194       return;
6195     }
6196     goto done;
6197   }
6198   if (!xdr_guestfs_checksum_ret (xdr, &ctx->ret)) {
6199     error (g, "%s: failed to parse reply", "guestfs_checksum");
6200     return;
6201   }
6202  done:
6203   ctx->cb_sequence = 1;
6204 }
6205
6206 char *guestfs_checksum (guestfs_h *g,
6207                 const char *csumtype,
6208                 const char *path)
6209 {
6210   struct guestfs_checksum_args args;
6211   struct checksum_ctx ctx;
6212   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6213   int serial;
6214
6215   if (check_state (g, "guestfs_checksum") == -1) return NULL;
6216   guestfs_set_busy (g);
6217
6218   memset (&ctx, 0, sizeof ctx);
6219
6220   args.csumtype = (char *) csumtype;
6221   args.path = (char *) path;
6222   serial = guestfs__send_sync (g, GUESTFS_PROC_CHECKSUM,
6223         (xdrproc_t) xdr_guestfs_checksum_args, (char *) &args);
6224   if (serial == -1) {
6225     guestfs_end_busy (g);
6226     return NULL;
6227   }
6228
6229   guestfs__switch_to_receiving (g);
6230   ctx.cb_sequence = 0;
6231   guestfs_set_reply_callback (g, checksum_reply_cb, &ctx);
6232   (void) ml->main_loop_run (ml, g);
6233   guestfs_set_reply_callback (g, NULL, NULL);
6234   if (ctx.cb_sequence != 1) {
6235     error (g, "%s reply failed, see earlier error messages", "guestfs_checksum");
6236     guestfs_end_busy (g);
6237     return NULL;
6238   }
6239
6240   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CHECKSUM, serial) == -1) {
6241     guestfs_end_busy (g);
6242     return NULL;
6243   }
6244
6245   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6246     error (g, "%s", ctx.err.error_message);
6247     free (ctx.err.error_message);
6248     guestfs_end_busy (g);
6249     return NULL;
6250   }
6251
6252   guestfs_end_busy (g);
6253   return ctx.ret.checksum; /* caller will free */
6254 }
6255
6256 struct tar_in_ctx {
6257   /* This flag is set by the callbacks, so we know we've done
6258    * the callbacks as expected, and in the right sequence.
6259    * 0 = not called, 1 = reply_cb called.
6260    */
6261   int cb_sequence;
6262   struct guestfs_message_header hdr;
6263   struct guestfs_message_error err;
6264 };
6265
6266 static void tar_in_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6267 {
6268   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6269   struct tar_in_ctx *ctx = (struct tar_in_ctx *) data;
6270
6271   /* This should definitely not happen. */
6272   if (ctx->cb_sequence != 0) {
6273     ctx->cb_sequence = 9999;
6274     error (g, "%s: internal error: reply callback called twice", "guestfs_tar_in");
6275     return;
6276   }
6277
6278   ml->main_loop_quit (ml, g);
6279
6280   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6281     error (g, "%s: failed to parse reply header", "guestfs_tar_in");
6282     return;
6283   }
6284   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6285     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6286       error (g, "%s: failed to parse reply error", "guestfs_tar_in");
6287       return;
6288     }
6289     goto done;
6290   }
6291  done:
6292   ctx->cb_sequence = 1;
6293 }
6294
6295 int guestfs_tar_in (guestfs_h *g,
6296                 const char *tarfile,
6297                 const char *directory)
6298 {
6299   struct guestfs_tar_in_args args;
6300   struct tar_in_ctx ctx;
6301   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6302   int serial;
6303
6304   if (check_state (g, "guestfs_tar_in") == -1) return -1;
6305   guestfs_set_busy (g);
6306
6307   memset (&ctx, 0, sizeof ctx);
6308
6309   args.directory = (char *) directory;
6310   serial = guestfs__send_sync (g, GUESTFS_PROC_TAR_IN,
6311         (xdrproc_t) xdr_guestfs_tar_in_args, (char *) &args);
6312   if (serial == -1) {
6313     guestfs_end_busy (g);
6314     return -1;
6315   }
6316
6317   {
6318     int r;
6319
6320     r = guestfs__send_file_sync (g, tarfile);
6321     if (r == -1) {
6322       guestfs_end_busy (g);
6323       return -1;
6324     }
6325     if (r == -2) /* daemon cancelled */
6326       goto read_reply;
6327   }
6328
6329  read_reply:
6330   guestfs__switch_to_receiving (g);
6331   ctx.cb_sequence = 0;
6332   guestfs_set_reply_callback (g, tar_in_reply_cb, &ctx);
6333   (void) ml->main_loop_run (ml, g);
6334   guestfs_set_reply_callback (g, NULL, NULL);
6335   if (ctx.cb_sequence != 1) {
6336     error (g, "%s reply failed, see earlier error messages", "guestfs_tar_in");
6337     guestfs_end_busy (g);
6338     return -1;
6339   }
6340
6341   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAR_IN, serial) == -1) {
6342     guestfs_end_busy (g);
6343     return -1;
6344   }
6345
6346   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6347     error (g, "%s", ctx.err.error_message);
6348     free (ctx.err.error_message);
6349     guestfs_end_busy (g);
6350     return -1;
6351   }
6352
6353   guestfs_end_busy (g);
6354   return 0;
6355 }
6356
6357 struct tar_out_ctx {
6358   /* This flag is set by the callbacks, so we know we've done
6359    * the callbacks as expected, and in the right sequence.
6360    * 0 = not called, 1 = reply_cb called.
6361    */
6362   int cb_sequence;
6363   struct guestfs_message_header hdr;
6364   struct guestfs_message_error err;
6365 };
6366
6367 static void tar_out_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6368 {
6369   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6370   struct tar_out_ctx *ctx = (struct tar_out_ctx *) data;
6371
6372   /* This should definitely not happen. */
6373   if (ctx->cb_sequence != 0) {
6374     ctx->cb_sequence = 9999;
6375     error (g, "%s: internal error: reply callback called twice", "guestfs_tar_out");
6376     return;
6377   }
6378
6379   ml->main_loop_quit (ml, g);
6380
6381   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6382     error (g, "%s: failed to parse reply header", "guestfs_tar_out");
6383     return;
6384   }
6385   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6386     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6387       error (g, "%s: failed to parse reply error", "guestfs_tar_out");
6388       return;
6389     }
6390     goto done;
6391   }
6392  done:
6393   ctx->cb_sequence = 1;
6394 }
6395
6396 int guestfs_tar_out (guestfs_h *g,
6397                 const char *directory,
6398                 const char *tarfile)
6399 {
6400   struct guestfs_tar_out_args args;
6401   struct tar_out_ctx ctx;
6402   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6403   int serial;
6404
6405   if (check_state (g, "guestfs_tar_out") == -1) return -1;
6406   guestfs_set_busy (g);
6407
6408   memset (&ctx, 0, sizeof ctx);
6409
6410   args.directory = (char *) directory;
6411   serial = guestfs__send_sync (g, GUESTFS_PROC_TAR_OUT,
6412         (xdrproc_t) xdr_guestfs_tar_out_args, (char *) &args);
6413   if (serial == -1) {
6414     guestfs_end_busy (g);
6415     return -1;
6416   }
6417
6418   guestfs__switch_to_receiving (g);
6419   ctx.cb_sequence = 0;
6420   guestfs_set_reply_callback (g, tar_out_reply_cb, &ctx);
6421   (void) ml->main_loop_run (ml, g);
6422   guestfs_set_reply_callback (g, NULL, NULL);
6423   if (ctx.cb_sequence != 1) {
6424     error (g, "%s reply failed, see earlier error messages", "guestfs_tar_out");
6425     guestfs_end_busy (g);
6426     return -1;
6427   }
6428
6429   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TAR_OUT, serial) == -1) {
6430     guestfs_end_busy (g);
6431     return -1;
6432   }
6433
6434   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6435     error (g, "%s", ctx.err.error_message);
6436     free (ctx.err.error_message);
6437     guestfs_end_busy (g);
6438     return -1;
6439   }
6440
6441   if (guestfs__receive_file_sync (g, tarfile) == -1) {
6442     guestfs_end_busy (g);
6443     return -1;
6444   }
6445
6446   guestfs_end_busy (g);
6447   return 0;
6448 }
6449
6450 struct tgz_in_ctx {
6451   /* This flag is set by the callbacks, so we know we've done
6452    * the callbacks as expected, and in the right sequence.
6453    * 0 = not called, 1 = reply_cb called.
6454    */
6455   int cb_sequence;
6456   struct guestfs_message_header hdr;
6457   struct guestfs_message_error err;
6458 };
6459
6460 static void tgz_in_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6461 {
6462   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6463   struct tgz_in_ctx *ctx = (struct tgz_in_ctx *) data;
6464
6465   /* This should definitely not happen. */
6466   if (ctx->cb_sequence != 0) {
6467     ctx->cb_sequence = 9999;
6468     error (g, "%s: internal error: reply callback called twice", "guestfs_tgz_in");
6469     return;
6470   }
6471
6472   ml->main_loop_quit (ml, g);
6473
6474   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6475     error (g, "%s: failed to parse reply header", "guestfs_tgz_in");
6476     return;
6477   }
6478   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6479     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6480       error (g, "%s: failed to parse reply error", "guestfs_tgz_in");
6481       return;
6482     }
6483     goto done;
6484   }
6485  done:
6486   ctx->cb_sequence = 1;
6487 }
6488
6489 int guestfs_tgz_in (guestfs_h *g,
6490                 const char *tarball,
6491                 const char *directory)
6492 {
6493   struct guestfs_tgz_in_args args;
6494   struct tgz_in_ctx ctx;
6495   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6496   int serial;
6497
6498   if (check_state (g, "guestfs_tgz_in") == -1) return -1;
6499   guestfs_set_busy (g);
6500
6501   memset (&ctx, 0, sizeof ctx);
6502
6503   args.directory = (char *) directory;
6504   serial = guestfs__send_sync (g, GUESTFS_PROC_TGZ_IN,
6505         (xdrproc_t) xdr_guestfs_tgz_in_args, (char *) &args);
6506   if (serial == -1) {
6507     guestfs_end_busy (g);
6508     return -1;
6509   }
6510
6511   {
6512     int r;
6513
6514     r = guestfs__send_file_sync (g, tarball);
6515     if (r == -1) {
6516       guestfs_end_busy (g);
6517       return -1;
6518     }
6519     if (r == -2) /* daemon cancelled */
6520       goto read_reply;
6521   }
6522
6523  read_reply:
6524   guestfs__switch_to_receiving (g);
6525   ctx.cb_sequence = 0;
6526   guestfs_set_reply_callback (g, tgz_in_reply_cb, &ctx);
6527   (void) ml->main_loop_run (ml, g);
6528   guestfs_set_reply_callback (g, NULL, NULL);
6529   if (ctx.cb_sequence != 1) {
6530     error (g, "%s reply failed, see earlier error messages", "guestfs_tgz_in");
6531     guestfs_end_busy (g);
6532     return -1;
6533   }
6534
6535   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TGZ_IN, serial) == -1) {
6536     guestfs_end_busy (g);
6537     return -1;
6538   }
6539
6540   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6541     error (g, "%s", ctx.err.error_message);
6542     free (ctx.err.error_message);
6543     guestfs_end_busy (g);
6544     return -1;
6545   }
6546
6547   guestfs_end_busy (g);
6548   return 0;
6549 }
6550
6551 struct tgz_out_ctx {
6552   /* This flag is set by the callbacks, so we know we've done
6553    * the callbacks as expected, and in the right sequence.
6554    * 0 = not called, 1 = reply_cb called.
6555    */
6556   int cb_sequence;
6557   struct guestfs_message_header hdr;
6558   struct guestfs_message_error err;
6559 };
6560
6561 static void tgz_out_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6562 {
6563   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6564   struct tgz_out_ctx *ctx = (struct tgz_out_ctx *) data;
6565
6566   /* This should definitely not happen. */
6567   if (ctx->cb_sequence != 0) {
6568     ctx->cb_sequence = 9999;
6569     error (g, "%s: internal error: reply callback called twice", "guestfs_tgz_out");
6570     return;
6571   }
6572
6573   ml->main_loop_quit (ml, g);
6574
6575   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6576     error (g, "%s: failed to parse reply header", "guestfs_tgz_out");
6577     return;
6578   }
6579   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6580     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6581       error (g, "%s: failed to parse reply error", "guestfs_tgz_out");
6582       return;
6583     }
6584     goto done;
6585   }
6586  done:
6587   ctx->cb_sequence = 1;
6588 }
6589
6590 int guestfs_tgz_out (guestfs_h *g,
6591                 const char *directory,
6592                 const char *tarball)
6593 {
6594   struct guestfs_tgz_out_args args;
6595   struct tgz_out_ctx ctx;
6596   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6597   int serial;
6598
6599   if (check_state (g, "guestfs_tgz_out") == -1) return -1;
6600   guestfs_set_busy (g);
6601
6602   memset (&ctx, 0, sizeof ctx);
6603
6604   args.directory = (char *) directory;
6605   serial = guestfs__send_sync (g, GUESTFS_PROC_TGZ_OUT,
6606         (xdrproc_t) xdr_guestfs_tgz_out_args, (char *) &args);
6607   if (serial == -1) {
6608     guestfs_end_busy (g);
6609     return -1;
6610   }
6611
6612   guestfs__switch_to_receiving (g);
6613   ctx.cb_sequence = 0;
6614   guestfs_set_reply_callback (g, tgz_out_reply_cb, &ctx);
6615   (void) ml->main_loop_run (ml, g);
6616   guestfs_set_reply_callback (g, NULL, NULL);
6617   if (ctx.cb_sequence != 1) {
6618     error (g, "%s reply failed, see earlier error messages", "guestfs_tgz_out");
6619     guestfs_end_busy (g);
6620     return -1;
6621   }
6622
6623   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_TGZ_OUT, serial) == -1) {
6624     guestfs_end_busy (g);
6625     return -1;
6626   }
6627
6628   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6629     error (g, "%s", ctx.err.error_message);
6630     free (ctx.err.error_message);
6631     guestfs_end_busy (g);
6632     return -1;
6633   }
6634
6635   if (guestfs__receive_file_sync (g, tarball) == -1) {
6636     guestfs_end_busy (g);
6637     return -1;
6638   }
6639
6640   guestfs_end_busy (g);
6641   return 0;
6642 }
6643
6644 struct mount_ro_ctx {
6645   /* This flag is set by the callbacks, so we know we've done
6646    * the callbacks as expected, and in the right sequence.
6647    * 0 = not called, 1 = reply_cb called.
6648    */
6649   int cb_sequence;
6650   struct guestfs_message_header hdr;
6651   struct guestfs_message_error err;
6652 };
6653
6654 static void mount_ro_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6655 {
6656   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6657   struct mount_ro_ctx *ctx = (struct mount_ro_ctx *) data;
6658
6659   /* This should definitely not happen. */
6660   if (ctx->cb_sequence != 0) {
6661     ctx->cb_sequence = 9999;
6662     error (g, "%s: internal error: reply callback called twice", "guestfs_mount_ro");
6663     return;
6664   }
6665
6666   ml->main_loop_quit (ml, g);
6667
6668   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6669     error (g, "%s: failed to parse reply header", "guestfs_mount_ro");
6670     return;
6671   }
6672   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6673     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6674       error (g, "%s: failed to parse reply error", "guestfs_mount_ro");
6675       return;
6676     }
6677     goto done;
6678   }
6679  done:
6680   ctx->cb_sequence = 1;
6681 }
6682
6683 int guestfs_mount_ro (guestfs_h *g,
6684                 const char *device,
6685                 const char *mountpoint)
6686 {
6687   struct guestfs_mount_ro_args args;
6688   struct mount_ro_ctx ctx;
6689   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6690   int serial;
6691
6692   if (check_state (g, "guestfs_mount_ro") == -1) return -1;
6693   guestfs_set_busy (g);
6694
6695   memset (&ctx, 0, sizeof ctx);
6696
6697   args.device = (char *) device;
6698   args.mountpoint = (char *) mountpoint;
6699   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_RO,
6700         (xdrproc_t) xdr_guestfs_mount_ro_args, (char *) &args);
6701   if (serial == -1) {
6702     guestfs_end_busy (g);
6703     return -1;
6704   }
6705
6706   guestfs__switch_to_receiving (g);
6707   ctx.cb_sequence = 0;
6708   guestfs_set_reply_callback (g, mount_ro_reply_cb, &ctx);
6709   (void) ml->main_loop_run (ml, g);
6710   guestfs_set_reply_callback (g, NULL, NULL);
6711   if (ctx.cb_sequence != 1) {
6712     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_ro");
6713     guestfs_end_busy (g);
6714     return -1;
6715   }
6716
6717   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_RO, serial) == -1) {
6718     guestfs_end_busy (g);
6719     return -1;
6720   }
6721
6722   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6723     error (g, "%s", ctx.err.error_message);
6724     free (ctx.err.error_message);
6725     guestfs_end_busy (g);
6726     return -1;
6727   }
6728
6729   guestfs_end_busy (g);
6730   return 0;
6731 }
6732
6733 struct mount_options_ctx {
6734   /* This flag is set by the callbacks, so we know we've done
6735    * the callbacks as expected, and in the right sequence.
6736    * 0 = not called, 1 = reply_cb called.
6737    */
6738   int cb_sequence;
6739   struct guestfs_message_header hdr;
6740   struct guestfs_message_error err;
6741 };
6742
6743 static void mount_options_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6744 {
6745   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6746   struct mount_options_ctx *ctx = (struct mount_options_ctx *) data;
6747
6748   /* This should definitely not happen. */
6749   if (ctx->cb_sequence != 0) {
6750     ctx->cb_sequence = 9999;
6751     error (g, "%s: internal error: reply callback called twice", "guestfs_mount_options");
6752     return;
6753   }
6754
6755   ml->main_loop_quit (ml, g);
6756
6757   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6758     error (g, "%s: failed to parse reply header", "guestfs_mount_options");
6759     return;
6760   }
6761   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6762     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6763       error (g, "%s: failed to parse reply error", "guestfs_mount_options");
6764       return;
6765     }
6766     goto done;
6767   }
6768  done:
6769   ctx->cb_sequence = 1;
6770 }
6771
6772 int guestfs_mount_options (guestfs_h *g,
6773                 const char *options,
6774                 const char *device,
6775                 const char *mountpoint)
6776 {
6777   struct guestfs_mount_options_args args;
6778   struct mount_options_ctx ctx;
6779   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6780   int serial;
6781
6782   if (check_state (g, "guestfs_mount_options") == -1) return -1;
6783   guestfs_set_busy (g);
6784
6785   memset (&ctx, 0, sizeof ctx);
6786
6787   args.options = (char *) options;
6788   args.device = (char *) device;
6789   args.mountpoint = (char *) mountpoint;
6790   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_OPTIONS,
6791         (xdrproc_t) xdr_guestfs_mount_options_args, (char *) &args);
6792   if (serial == -1) {
6793     guestfs_end_busy (g);
6794     return -1;
6795   }
6796
6797   guestfs__switch_to_receiving (g);
6798   ctx.cb_sequence = 0;
6799   guestfs_set_reply_callback (g, mount_options_reply_cb, &ctx);
6800   (void) ml->main_loop_run (ml, g);
6801   guestfs_set_reply_callback (g, NULL, NULL);
6802   if (ctx.cb_sequence != 1) {
6803     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_options");
6804     guestfs_end_busy (g);
6805     return -1;
6806   }
6807
6808   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_OPTIONS, serial) == -1) {
6809     guestfs_end_busy (g);
6810     return -1;
6811   }
6812
6813   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6814     error (g, "%s", ctx.err.error_message);
6815     free (ctx.err.error_message);
6816     guestfs_end_busy (g);
6817     return -1;
6818   }
6819
6820   guestfs_end_busy (g);
6821   return 0;
6822 }
6823
6824 struct mount_vfs_ctx {
6825   /* This flag is set by the callbacks, so we know we've done
6826    * the callbacks as expected, and in the right sequence.
6827    * 0 = not called, 1 = reply_cb called.
6828    */
6829   int cb_sequence;
6830   struct guestfs_message_header hdr;
6831   struct guestfs_message_error err;
6832 };
6833
6834 static void mount_vfs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6835 {
6836   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6837   struct mount_vfs_ctx *ctx = (struct mount_vfs_ctx *) data;
6838
6839   /* This should definitely not happen. */
6840   if (ctx->cb_sequence != 0) {
6841     ctx->cb_sequence = 9999;
6842     error (g, "%s: internal error: reply callback called twice", "guestfs_mount_vfs");
6843     return;
6844   }
6845
6846   ml->main_loop_quit (ml, g);
6847
6848   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6849     error (g, "%s: failed to parse reply header", "guestfs_mount_vfs");
6850     return;
6851   }
6852   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6853     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6854       error (g, "%s: failed to parse reply error", "guestfs_mount_vfs");
6855       return;
6856     }
6857     goto done;
6858   }
6859  done:
6860   ctx->cb_sequence = 1;
6861 }
6862
6863 int guestfs_mount_vfs (guestfs_h *g,
6864                 const char *options,
6865                 const char *vfstype,
6866                 const char *device,
6867                 const char *mountpoint)
6868 {
6869   struct guestfs_mount_vfs_args args;
6870   struct mount_vfs_ctx ctx;
6871   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6872   int serial;
6873
6874   if (check_state (g, "guestfs_mount_vfs") == -1) return -1;
6875   guestfs_set_busy (g);
6876
6877   memset (&ctx, 0, sizeof ctx);
6878
6879   args.options = (char *) options;
6880   args.vfstype = (char *) vfstype;
6881   args.device = (char *) device;
6882   args.mountpoint = (char *) mountpoint;
6883   serial = guestfs__send_sync (g, GUESTFS_PROC_MOUNT_VFS,
6884         (xdrproc_t) xdr_guestfs_mount_vfs_args, (char *) &args);
6885   if (serial == -1) {
6886     guestfs_end_busy (g);
6887     return -1;
6888   }
6889
6890   guestfs__switch_to_receiving (g);
6891   ctx.cb_sequence = 0;
6892   guestfs_set_reply_callback (g, mount_vfs_reply_cb, &ctx);
6893   (void) ml->main_loop_run (ml, g);
6894   guestfs_set_reply_callback (g, NULL, NULL);
6895   if (ctx.cb_sequence != 1) {
6896     error (g, "%s reply failed, see earlier error messages", "guestfs_mount_vfs");
6897     guestfs_end_busy (g);
6898     return -1;
6899   }
6900
6901   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MOUNT_VFS, serial) == -1) {
6902     guestfs_end_busy (g);
6903     return -1;
6904   }
6905
6906   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
6907     error (g, "%s", ctx.err.error_message);
6908     free (ctx.err.error_message);
6909     guestfs_end_busy (g);
6910     return -1;
6911   }
6912
6913   guestfs_end_busy (g);
6914   return 0;
6915 }
6916
6917 struct debug_ctx {
6918   /* This flag is set by the callbacks, so we know we've done
6919    * the callbacks as expected, and in the right sequence.
6920    * 0 = not called, 1 = reply_cb called.
6921    */
6922   int cb_sequence;
6923   struct guestfs_message_header hdr;
6924   struct guestfs_message_error err;
6925   struct guestfs_debug_ret ret;
6926 };
6927
6928 static void debug_reply_cb (guestfs_h *g, void *data, XDR *xdr)
6929 {
6930   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6931   struct debug_ctx *ctx = (struct debug_ctx *) data;
6932
6933   /* This should definitely not happen. */
6934   if (ctx->cb_sequence != 0) {
6935     ctx->cb_sequence = 9999;
6936     error (g, "%s: internal error: reply callback called twice", "guestfs_debug");
6937     return;
6938   }
6939
6940   ml->main_loop_quit (ml, g);
6941
6942   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
6943     error (g, "%s: failed to parse reply header", "guestfs_debug");
6944     return;
6945   }
6946   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
6947     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
6948       error (g, "%s: failed to parse reply error", "guestfs_debug");
6949       return;
6950     }
6951     goto done;
6952   }
6953   if (!xdr_guestfs_debug_ret (xdr, &ctx->ret)) {
6954     error (g, "%s: failed to parse reply", "guestfs_debug");
6955     return;
6956   }
6957  done:
6958   ctx->cb_sequence = 1;
6959 }
6960
6961 char *guestfs_debug (guestfs_h *g,
6962                 const char *subcmd,
6963                 char * const* const extraargs)
6964 {
6965   struct guestfs_debug_args args;
6966   struct debug_ctx ctx;
6967   guestfs_main_loop *ml = guestfs_get_main_loop (g);
6968   int serial;
6969
6970   if (check_state (g, "guestfs_debug") == -1) return NULL;
6971   guestfs_set_busy (g);
6972
6973   memset (&ctx, 0, sizeof ctx);
6974
6975   args.subcmd = (char *) subcmd;
6976   args.extraargs.extraargs_val = (char **) extraargs;
6977   for (args.extraargs.extraargs_len = 0; extraargs[args.extraargs.extraargs_len]; args.extraargs.extraargs_len++) ;
6978   serial = guestfs__send_sync (g, GUESTFS_PROC_DEBUG,
6979         (xdrproc_t) xdr_guestfs_debug_args, (char *) &args);
6980   if (serial == -1) {
6981     guestfs_end_busy (g);
6982     return NULL;
6983   }
6984
6985   guestfs__switch_to_receiving (g);
6986   ctx.cb_sequence = 0;
6987   guestfs_set_reply_callback (g, debug_reply_cb, &ctx);
6988   (void) ml->main_loop_run (ml, g);
6989   guestfs_set_reply_callback (g, NULL, NULL);
6990   if (ctx.cb_sequence != 1) {
6991     error (g, "%s reply failed, see earlier error messages", "guestfs_debug");
6992     guestfs_end_busy (g);
6993     return NULL;
6994   }
6995
6996   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_DEBUG, serial) == -1) {
6997     guestfs_end_busy (g);
6998     return NULL;
6999   }
7000
7001   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7002     error (g, "%s", ctx.err.error_message);
7003     free (ctx.err.error_message);
7004     guestfs_end_busy (g);
7005     return NULL;
7006   }
7007
7008   guestfs_end_busy (g);
7009   return ctx.ret.result; /* caller will free */
7010 }
7011
7012 struct lvremove_ctx {
7013   /* This flag is set by the callbacks, so we know we've done
7014    * the callbacks as expected, and in the right sequence.
7015    * 0 = not called, 1 = reply_cb called.
7016    */
7017   int cb_sequence;
7018   struct guestfs_message_header hdr;
7019   struct guestfs_message_error err;
7020 };
7021
7022 static void lvremove_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7023 {
7024   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7025   struct lvremove_ctx *ctx = (struct lvremove_ctx *) data;
7026
7027   /* This should definitely not happen. */
7028   if (ctx->cb_sequence != 0) {
7029     ctx->cb_sequence = 9999;
7030     error (g, "%s: internal error: reply callback called twice", "guestfs_lvremove");
7031     return;
7032   }
7033
7034   ml->main_loop_quit (ml, g);
7035
7036   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7037     error (g, "%s: failed to parse reply header", "guestfs_lvremove");
7038     return;
7039   }
7040   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7041     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7042       error (g, "%s: failed to parse reply error", "guestfs_lvremove");
7043       return;
7044     }
7045     goto done;
7046   }
7047  done:
7048   ctx->cb_sequence = 1;
7049 }
7050
7051 int guestfs_lvremove (guestfs_h *g,
7052                 const char *device)
7053 {
7054   struct guestfs_lvremove_args args;
7055   struct lvremove_ctx ctx;
7056   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7057   int serial;
7058
7059   if (check_state (g, "guestfs_lvremove") == -1) return -1;
7060   guestfs_set_busy (g);
7061
7062   memset (&ctx, 0, sizeof ctx);
7063
7064   args.device = (char *) device;
7065   serial = guestfs__send_sync (g, GUESTFS_PROC_LVREMOVE,
7066         (xdrproc_t) xdr_guestfs_lvremove_args, (char *) &args);
7067   if (serial == -1) {
7068     guestfs_end_busy (g);
7069     return -1;
7070   }
7071
7072   guestfs__switch_to_receiving (g);
7073   ctx.cb_sequence = 0;
7074   guestfs_set_reply_callback (g, lvremove_reply_cb, &ctx);
7075   (void) ml->main_loop_run (ml, g);
7076   guestfs_set_reply_callback (g, NULL, NULL);
7077   if (ctx.cb_sequence != 1) {
7078     error (g, "%s reply failed, see earlier error messages", "guestfs_lvremove");
7079     guestfs_end_busy (g);
7080     return -1;
7081   }
7082
7083   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVREMOVE, serial) == -1) {
7084     guestfs_end_busy (g);
7085     return -1;
7086   }
7087
7088   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7089     error (g, "%s", ctx.err.error_message);
7090     free (ctx.err.error_message);
7091     guestfs_end_busy (g);
7092     return -1;
7093   }
7094
7095   guestfs_end_busy (g);
7096   return 0;
7097 }
7098
7099 struct vgremove_ctx {
7100   /* This flag is set by the callbacks, so we know we've done
7101    * the callbacks as expected, and in the right sequence.
7102    * 0 = not called, 1 = reply_cb called.
7103    */
7104   int cb_sequence;
7105   struct guestfs_message_header hdr;
7106   struct guestfs_message_error err;
7107 };
7108
7109 static void vgremove_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7110 {
7111   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7112   struct vgremove_ctx *ctx = (struct vgremove_ctx *) data;
7113
7114   /* This should definitely not happen. */
7115   if (ctx->cb_sequence != 0) {
7116     ctx->cb_sequence = 9999;
7117     error (g, "%s: internal error: reply callback called twice", "guestfs_vgremove");
7118     return;
7119   }
7120
7121   ml->main_loop_quit (ml, g);
7122
7123   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7124     error (g, "%s: failed to parse reply header", "guestfs_vgremove");
7125     return;
7126   }
7127   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7128     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7129       error (g, "%s: failed to parse reply error", "guestfs_vgremove");
7130       return;
7131     }
7132     goto done;
7133   }
7134  done:
7135   ctx->cb_sequence = 1;
7136 }
7137
7138 int guestfs_vgremove (guestfs_h *g,
7139                 const char *vgname)
7140 {
7141   struct guestfs_vgremove_args args;
7142   struct vgremove_ctx ctx;
7143   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7144   int serial;
7145
7146   if (check_state (g, "guestfs_vgremove") == -1) return -1;
7147   guestfs_set_busy (g);
7148
7149   memset (&ctx, 0, sizeof ctx);
7150
7151   args.vgname = (char *) vgname;
7152   serial = guestfs__send_sync (g, GUESTFS_PROC_VGREMOVE,
7153         (xdrproc_t) xdr_guestfs_vgremove_args, (char *) &args);
7154   if (serial == -1) {
7155     guestfs_end_busy (g);
7156     return -1;
7157   }
7158
7159   guestfs__switch_to_receiving (g);
7160   ctx.cb_sequence = 0;
7161   guestfs_set_reply_callback (g, vgremove_reply_cb, &ctx);
7162   (void) ml->main_loop_run (ml, g);
7163   guestfs_set_reply_callback (g, NULL, NULL);
7164   if (ctx.cb_sequence != 1) {
7165     error (g, "%s reply failed, see earlier error messages", "guestfs_vgremove");
7166     guestfs_end_busy (g);
7167     return -1;
7168   }
7169
7170   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VGREMOVE, serial) == -1) {
7171     guestfs_end_busy (g);
7172     return -1;
7173   }
7174
7175   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7176     error (g, "%s", ctx.err.error_message);
7177     free (ctx.err.error_message);
7178     guestfs_end_busy (g);
7179     return -1;
7180   }
7181
7182   guestfs_end_busy (g);
7183   return 0;
7184 }
7185
7186 struct pvremove_ctx {
7187   /* This flag is set by the callbacks, so we know we've done
7188    * the callbacks as expected, and in the right sequence.
7189    * 0 = not called, 1 = reply_cb called.
7190    */
7191   int cb_sequence;
7192   struct guestfs_message_header hdr;
7193   struct guestfs_message_error err;
7194 };
7195
7196 static void pvremove_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7197 {
7198   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7199   struct pvremove_ctx *ctx = (struct pvremove_ctx *) data;
7200
7201   /* This should definitely not happen. */
7202   if (ctx->cb_sequence != 0) {
7203     ctx->cb_sequence = 9999;
7204     error (g, "%s: internal error: reply callback called twice", "guestfs_pvremove");
7205     return;
7206   }
7207
7208   ml->main_loop_quit (ml, g);
7209
7210   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7211     error (g, "%s: failed to parse reply header", "guestfs_pvremove");
7212     return;
7213   }
7214   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7215     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7216       error (g, "%s: failed to parse reply error", "guestfs_pvremove");
7217       return;
7218     }
7219     goto done;
7220   }
7221  done:
7222   ctx->cb_sequence = 1;
7223 }
7224
7225 int guestfs_pvremove (guestfs_h *g,
7226                 const char *device)
7227 {
7228   struct guestfs_pvremove_args args;
7229   struct pvremove_ctx ctx;
7230   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7231   int serial;
7232
7233   if (check_state (g, "guestfs_pvremove") == -1) return -1;
7234   guestfs_set_busy (g);
7235
7236   memset (&ctx, 0, sizeof ctx);
7237
7238   args.device = (char *) device;
7239   serial = guestfs__send_sync (g, GUESTFS_PROC_PVREMOVE,
7240         (xdrproc_t) xdr_guestfs_pvremove_args, (char *) &args);
7241   if (serial == -1) {
7242     guestfs_end_busy (g);
7243     return -1;
7244   }
7245
7246   guestfs__switch_to_receiving (g);
7247   ctx.cb_sequence = 0;
7248   guestfs_set_reply_callback (g, pvremove_reply_cb, &ctx);
7249   (void) ml->main_loop_run (ml, g);
7250   guestfs_set_reply_callback (g, NULL, NULL);
7251   if (ctx.cb_sequence != 1) {
7252     error (g, "%s reply failed, see earlier error messages", "guestfs_pvremove");
7253     guestfs_end_busy (g);
7254     return -1;
7255   }
7256
7257   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVREMOVE, serial) == -1) {
7258     guestfs_end_busy (g);
7259     return -1;
7260   }
7261
7262   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7263     error (g, "%s", ctx.err.error_message);
7264     free (ctx.err.error_message);
7265     guestfs_end_busy (g);
7266     return -1;
7267   }
7268
7269   guestfs_end_busy (g);
7270   return 0;
7271 }
7272
7273 struct set_e2label_ctx {
7274   /* This flag is set by the callbacks, so we know we've done
7275    * the callbacks as expected, and in the right sequence.
7276    * 0 = not called, 1 = reply_cb called.
7277    */
7278   int cb_sequence;
7279   struct guestfs_message_header hdr;
7280   struct guestfs_message_error err;
7281 };
7282
7283 static void set_e2label_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7284 {
7285   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7286   struct set_e2label_ctx *ctx = (struct set_e2label_ctx *) data;
7287
7288   /* This should definitely not happen. */
7289   if (ctx->cb_sequence != 0) {
7290     ctx->cb_sequence = 9999;
7291     error (g, "%s: internal error: reply callback called twice", "guestfs_set_e2label");
7292     return;
7293   }
7294
7295   ml->main_loop_quit (ml, g);
7296
7297   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7298     error (g, "%s: failed to parse reply header", "guestfs_set_e2label");
7299     return;
7300   }
7301   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7302     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7303       error (g, "%s: failed to parse reply error", "guestfs_set_e2label");
7304       return;
7305     }
7306     goto done;
7307   }
7308  done:
7309   ctx->cb_sequence = 1;
7310 }
7311
7312 int guestfs_set_e2label (guestfs_h *g,
7313                 const char *device,
7314                 const char *label)
7315 {
7316   struct guestfs_set_e2label_args args;
7317   struct set_e2label_ctx ctx;
7318   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7319   int serial;
7320
7321   if (check_state (g, "guestfs_set_e2label") == -1) return -1;
7322   guestfs_set_busy (g);
7323
7324   memset (&ctx, 0, sizeof ctx);
7325
7326   args.device = (char *) device;
7327   args.label = (char *) label;
7328   serial = guestfs__send_sync (g, GUESTFS_PROC_SET_E2LABEL,
7329         (xdrproc_t) xdr_guestfs_set_e2label_args, (char *) &args);
7330   if (serial == -1) {
7331     guestfs_end_busy (g);
7332     return -1;
7333   }
7334
7335   guestfs__switch_to_receiving (g);
7336   ctx.cb_sequence = 0;
7337   guestfs_set_reply_callback (g, set_e2label_reply_cb, &ctx);
7338   (void) ml->main_loop_run (ml, g);
7339   guestfs_set_reply_callback (g, NULL, NULL);
7340   if (ctx.cb_sequence != 1) {
7341     error (g, "%s reply failed, see earlier error messages", "guestfs_set_e2label");
7342     guestfs_end_busy (g);
7343     return -1;
7344   }
7345
7346   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SET_E2LABEL, serial) == -1) {
7347     guestfs_end_busy (g);
7348     return -1;
7349   }
7350
7351   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7352     error (g, "%s", ctx.err.error_message);
7353     free (ctx.err.error_message);
7354     guestfs_end_busy (g);
7355     return -1;
7356   }
7357
7358   guestfs_end_busy (g);
7359   return 0;
7360 }
7361
7362 struct get_e2label_ctx {
7363   /* This flag is set by the callbacks, so we know we've done
7364    * the callbacks as expected, and in the right sequence.
7365    * 0 = not called, 1 = reply_cb called.
7366    */
7367   int cb_sequence;
7368   struct guestfs_message_header hdr;
7369   struct guestfs_message_error err;
7370   struct guestfs_get_e2label_ret ret;
7371 };
7372
7373 static void get_e2label_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7374 {
7375   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7376   struct get_e2label_ctx *ctx = (struct get_e2label_ctx *) data;
7377
7378   /* This should definitely not happen. */
7379   if (ctx->cb_sequence != 0) {
7380     ctx->cb_sequence = 9999;
7381     error (g, "%s: internal error: reply callback called twice", "guestfs_get_e2label");
7382     return;
7383   }
7384
7385   ml->main_loop_quit (ml, g);
7386
7387   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7388     error (g, "%s: failed to parse reply header", "guestfs_get_e2label");
7389     return;
7390   }
7391   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7392     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7393       error (g, "%s: failed to parse reply error", "guestfs_get_e2label");
7394       return;
7395     }
7396     goto done;
7397   }
7398   if (!xdr_guestfs_get_e2label_ret (xdr, &ctx->ret)) {
7399     error (g, "%s: failed to parse reply", "guestfs_get_e2label");
7400     return;
7401   }
7402  done:
7403   ctx->cb_sequence = 1;
7404 }
7405
7406 char *guestfs_get_e2label (guestfs_h *g,
7407                 const char *device)
7408 {
7409   struct guestfs_get_e2label_args args;
7410   struct get_e2label_ctx ctx;
7411   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7412   int serial;
7413
7414   if (check_state (g, "guestfs_get_e2label") == -1) return NULL;
7415   guestfs_set_busy (g);
7416
7417   memset (&ctx, 0, sizeof ctx);
7418
7419   args.device = (char *) device;
7420   serial = guestfs__send_sync (g, GUESTFS_PROC_GET_E2LABEL,
7421         (xdrproc_t) xdr_guestfs_get_e2label_args, (char *) &args);
7422   if (serial == -1) {
7423     guestfs_end_busy (g);
7424     return NULL;
7425   }
7426
7427   guestfs__switch_to_receiving (g);
7428   ctx.cb_sequence = 0;
7429   guestfs_set_reply_callback (g, get_e2label_reply_cb, &ctx);
7430   (void) ml->main_loop_run (ml, g);
7431   guestfs_set_reply_callback (g, NULL, NULL);
7432   if (ctx.cb_sequence != 1) {
7433     error (g, "%s reply failed, see earlier error messages", "guestfs_get_e2label");
7434     guestfs_end_busy (g);
7435     return NULL;
7436   }
7437
7438   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_GET_E2LABEL, serial) == -1) {
7439     guestfs_end_busy (g);
7440     return NULL;
7441   }
7442
7443   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7444     error (g, "%s", ctx.err.error_message);
7445     free (ctx.err.error_message);
7446     guestfs_end_busy (g);
7447     return NULL;
7448   }
7449
7450   guestfs_end_busy (g);
7451   return ctx.ret.label; /* caller will free */
7452 }
7453
7454 struct set_e2uuid_ctx {
7455   /* This flag is set by the callbacks, so we know we've done
7456    * the callbacks as expected, and in the right sequence.
7457    * 0 = not called, 1 = reply_cb called.
7458    */
7459   int cb_sequence;
7460   struct guestfs_message_header hdr;
7461   struct guestfs_message_error err;
7462 };
7463
7464 static void set_e2uuid_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7465 {
7466   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7467   struct set_e2uuid_ctx *ctx = (struct set_e2uuid_ctx *) data;
7468
7469   /* This should definitely not happen. */
7470   if (ctx->cb_sequence != 0) {
7471     ctx->cb_sequence = 9999;
7472     error (g, "%s: internal error: reply callback called twice", "guestfs_set_e2uuid");
7473     return;
7474   }
7475
7476   ml->main_loop_quit (ml, g);
7477
7478   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7479     error (g, "%s: failed to parse reply header", "guestfs_set_e2uuid");
7480     return;
7481   }
7482   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7483     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7484       error (g, "%s: failed to parse reply error", "guestfs_set_e2uuid");
7485       return;
7486     }
7487     goto done;
7488   }
7489  done:
7490   ctx->cb_sequence = 1;
7491 }
7492
7493 int guestfs_set_e2uuid (guestfs_h *g,
7494                 const char *device,
7495                 const char *uuid)
7496 {
7497   struct guestfs_set_e2uuid_args args;
7498   struct set_e2uuid_ctx ctx;
7499   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7500   int serial;
7501
7502   if (check_state (g, "guestfs_set_e2uuid") == -1) return -1;
7503   guestfs_set_busy (g);
7504
7505   memset (&ctx, 0, sizeof ctx);
7506
7507   args.device = (char *) device;
7508   args.uuid = (char *) uuid;
7509   serial = guestfs__send_sync (g, GUESTFS_PROC_SET_E2UUID,
7510         (xdrproc_t) xdr_guestfs_set_e2uuid_args, (char *) &args);
7511   if (serial == -1) {
7512     guestfs_end_busy (g);
7513     return -1;
7514   }
7515
7516   guestfs__switch_to_receiving (g);
7517   ctx.cb_sequence = 0;
7518   guestfs_set_reply_callback (g, set_e2uuid_reply_cb, &ctx);
7519   (void) ml->main_loop_run (ml, g);
7520   guestfs_set_reply_callback (g, NULL, NULL);
7521   if (ctx.cb_sequence != 1) {
7522     error (g, "%s reply failed, see earlier error messages", "guestfs_set_e2uuid");
7523     guestfs_end_busy (g);
7524     return -1;
7525   }
7526
7527   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SET_E2UUID, serial) == -1) {
7528     guestfs_end_busy (g);
7529     return -1;
7530   }
7531
7532   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7533     error (g, "%s", ctx.err.error_message);
7534     free (ctx.err.error_message);
7535     guestfs_end_busy (g);
7536     return -1;
7537   }
7538
7539   guestfs_end_busy (g);
7540   return 0;
7541 }
7542
7543 struct get_e2uuid_ctx {
7544   /* This flag is set by the callbacks, so we know we've done
7545    * the callbacks as expected, and in the right sequence.
7546    * 0 = not called, 1 = reply_cb called.
7547    */
7548   int cb_sequence;
7549   struct guestfs_message_header hdr;
7550   struct guestfs_message_error err;
7551   struct guestfs_get_e2uuid_ret ret;
7552 };
7553
7554 static void get_e2uuid_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7555 {
7556   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7557   struct get_e2uuid_ctx *ctx = (struct get_e2uuid_ctx *) data;
7558
7559   /* This should definitely not happen. */
7560   if (ctx->cb_sequence != 0) {
7561     ctx->cb_sequence = 9999;
7562     error (g, "%s: internal error: reply callback called twice", "guestfs_get_e2uuid");
7563     return;
7564   }
7565
7566   ml->main_loop_quit (ml, g);
7567
7568   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7569     error (g, "%s: failed to parse reply header", "guestfs_get_e2uuid");
7570     return;
7571   }
7572   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7573     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7574       error (g, "%s: failed to parse reply error", "guestfs_get_e2uuid");
7575       return;
7576     }
7577     goto done;
7578   }
7579   if (!xdr_guestfs_get_e2uuid_ret (xdr, &ctx->ret)) {
7580     error (g, "%s: failed to parse reply", "guestfs_get_e2uuid");
7581     return;
7582   }
7583  done:
7584   ctx->cb_sequence = 1;
7585 }
7586
7587 char *guestfs_get_e2uuid (guestfs_h *g,
7588                 const char *device)
7589 {
7590   struct guestfs_get_e2uuid_args args;
7591   struct get_e2uuid_ctx ctx;
7592   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7593   int serial;
7594
7595   if (check_state (g, "guestfs_get_e2uuid") == -1) return NULL;
7596   guestfs_set_busy (g);
7597
7598   memset (&ctx, 0, sizeof ctx);
7599
7600   args.device = (char *) device;
7601   serial = guestfs__send_sync (g, GUESTFS_PROC_GET_E2UUID,
7602         (xdrproc_t) xdr_guestfs_get_e2uuid_args, (char *) &args);
7603   if (serial == -1) {
7604     guestfs_end_busy (g);
7605     return NULL;
7606   }
7607
7608   guestfs__switch_to_receiving (g);
7609   ctx.cb_sequence = 0;
7610   guestfs_set_reply_callback (g, get_e2uuid_reply_cb, &ctx);
7611   (void) ml->main_loop_run (ml, g);
7612   guestfs_set_reply_callback (g, NULL, NULL);
7613   if (ctx.cb_sequence != 1) {
7614     error (g, "%s reply failed, see earlier error messages", "guestfs_get_e2uuid");
7615     guestfs_end_busy (g);
7616     return NULL;
7617   }
7618
7619   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_GET_E2UUID, serial) == -1) {
7620     guestfs_end_busy (g);
7621     return NULL;
7622   }
7623
7624   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7625     error (g, "%s", ctx.err.error_message);
7626     free (ctx.err.error_message);
7627     guestfs_end_busy (g);
7628     return NULL;
7629   }
7630
7631   guestfs_end_busy (g);
7632   return ctx.ret.uuid; /* caller will free */
7633 }
7634
7635 struct fsck_ctx {
7636   /* This flag is set by the callbacks, so we know we've done
7637    * the callbacks as expected, and in the right sequence.
7638    * 0 = not called, 1 = reply_cb called.
7639    */
7640   int cb_sequence;
7641   struct guestfs_message_header hdr;
7642   struct guestfs_message_error err;
7643   struct guestfs_fsck_ret ret;
7644 };
7645
7646 static void fsck_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7647 {
7648   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7649   struct fsck_ctx *ctx = (struct fsck_ctx *) data;
7650
7651   /* This should definitely not happen. */
7652   if (ctx->cb_sequence != 0) {
7653     ctx->cb_sequence = 9999;
7654     error (g, "%s: internal error: reply callback called twice", "guestfs_fsck");
7655     return;
7656   }
7657
7658   ml->main_loop_quit (ml, g);
7659
7660   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7661     error (g, "%s: failed to parse reply header", "guestfs_fsck");
7662     return;
7663   }
7664   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7665     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7666       error (g, "%s: failed to parse reply error", "guestfs_fsck");
7667       return;
7668     }
7669     goto done;
7670   }
7671   if (!xdr_guestfs_fsck_ret (xdr, &ctx->ret)) {
7672     error (g, "%s: failed to parse reply", "guestfs_fsck");
7673     return;
7674   }
7675  done:
7676   ctx->cb_sequence = 1;
7677 }
7678
7679 int guestfs_fsck (guestfs_h *g,
7680                 const char *fstype,
7681                 const char *device)
7682 {
7683   struct guestfs_fsck_args args;
7684   struct fsck_ctx ctx;
7685   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7686   int serial;
7687
7688   if (check_state (g, "guestfs_fsck") == -1) return -1;
7689   guestfs_set_busy (g);
7690
7691   memset (&ctx, 0, sizeof ctx);
7692
7693   args.fstype = (char *) fstype;
7694   args.device = (char *) device;
7695   serial = guestfs__send_sync (g, GUESTFS_PROC_FSCK,
7696         (xdrproc_t) xdr_guestfs_fsck_args, (char *) &args);
7697   if (serial == -1) {
7698     guestfs_end_busy (g);
7699     return -1;
7700   }
7701
7702   guestfs__switch_to_receiving (g);
7703   ctx.cb_sequence = 0;
7704   guestfs_set_reply_callback (g, fsck_reply_cb, &ctx);
7705   (void) ml->main_loop_run (ml, g);
7706   guestfs_set_reply_callback (g, NULL, NULL);
7707   if (ctx.cb_sequence != 1) {
7708     error (g, "%s reply failed, see earlier error messages", "guestfs_fsck");
7709     guestfs_end_busy (g);
7710     return -1;
7711   }
7712
7713   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_FSCK, serial) == -1) {
7714     guestfs_end_busy (g);
7715     return -1;
7716   }
7717
7718   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7719     error (g, "%s", ctx.err.error_message);
7720     free (ctx.err.error_message);
7721     guestfs_end_busy (g);
7722     return -1;
7723   }
7724
7725   guestfs_end_busy (g);
7726   return ctx.ret.status;
7727 }
7728
7729 struct zero_ctx {
7730   /* This flag is set by the callbacks, so we know we've done
7731    * the callbacks as expected, and in the right sequence.
7732    * 0 = not called, 1 = reply_cb called.
7733    */
7734   int cb_sequence;
7735   struct guestfs_message_header hdr;
7736   struct guestfs_message_error err;
7737 };
7738
7739 static void zero_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7740 {
7741   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7742   struct zero_ctx *ctx = (struct zero_ctx *) data;
7743
7744   /* This should definitely not happen. */
7745   if (ctx->cb_sequence != 0) {
7746     ctx->cb_sequence = 9999;
7747     error (g, "%s: internal error: reply callback called twice", "guestfs_zero");
7748     return;
7749   }
7750
7751   ml->main_loop_quit (ml, g);
7752
7753   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7754     error (g, "%s: failed to parse reply header", "guestfs_zero");
7755     return;
7756   }
7757   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7758     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7759       error (g, "%s: failed to parse reply error", "guestfs_zero");
7760       return;
7761     }
7762     goto done;
7763   }
7764  done:
7765   ctx->cb_sequence = 1;
7766 }
7767
7768 int guestfs_zero (guestfs_h *g,
7769                 const char *device)
7770 {
7771   struct guestfs_zero_args args;
7772   struct zero_ctx ctx;
7773   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7774   int serial;
7775
7776   if (check_state (g, "guestfs_zero") == -1) return -1;
7777   guestfs_set_busy (g);
7778
7779   memset (&ctx, 0, sizeof ctx);
7780
7781   args.device = (char *) device;
7782   serial = guestfs__send_sync (g, GUESTFS_PROC_ZERO,
7783         (xdrproc_t) xdr_guestfs_zero_args, (char *) &args);
7784   if (serial == -1) {
7785     guestfs_end_busy (g);
7786     return -1;
7787   }
7788
7789   guestfs__switch_to_receiving (g);
7790   ctx.cb_sequence = 0;
7791   guestfs_set_reply_callback (g, zero_reply_cb, &ctx);
7792   (void) ml->main_loop_run (ml, g);
7793   guestfs_set_reply_callback (g, NULL, NULL);
7794   if (ctx.cb_sequence != 1) {
7795     error (g, "%s reply failed, see earlier error messages", "guestfs_zero");
7796     guestfs_end_busy (g);
7797     return -1;
7798   }
7799
7800   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_ZERO, serial) == -1) {
7801     guestfs_end_busy (g);
7802     return -1;
7803   }
7804
7805   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7806     error (g, "%s", ctx.err.error_message);
7807     free (ctx.err.error_message);
7808     guestfs_end_busy (g);
7809     return -1;
7810   }
7811
7812   guestfs_end_busy (g);
7813   return 0;
7814 }
7815
7816 struct grub_install_ctx {
7817   /* This flag is set by the callbacks, so we know we've done
7818    * the callbacks as expected, and in the right sequence.
7819    * 0 = not called, 1 = reply_cb called.
7820    */
7821   int cb_sequence;
7822   struct guestfs_message_header hdr;
7823   struct guestfs_message_error err;
7824 };
7825
7826 static void grub_install_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7827 {
7828   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7829   struct grub_install_ctx *ctx = (struct grub_install_ctx *) data;
7830
7831   /* This should definitely not happen. */
7832   if (ctx->cb_sequence != 0) {
7833     ctx->cb_sequence = 9999;
7834     error (g, "%s: internal error: reply callback called twice", "guestfs_grub_install");
7835     return;
7836   }
7837
7838   ml->main_loop_quit (ml, g);
7839
7840   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7841     error (g, "%s: failed to parse reply header", "guestfs_grub_install");
7842     return;
7843   }
7844   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7845     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7846       error (g, "%s: failed to parse reply error", "guestfs_grub_install");
7847       return;
7848     }
7849     goto done;
7850   }
7851  done:
7852   ctx->cb_sequence = 1;
7853 }
7854
7855 int guestfs_grub_install (guestfs_h *g,
7856                 const char *root,
7857                 const char *device)
7858 {
7859   struct guestfs_grub_install_args args;
7860   struct grub_install_ctx ctx;
7861   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7862   int serial;
7863
7864   if (check_state (g, "guestfs_grub_install") == -1) return -1;
7865   guestfs_set_busy (g);
7866
7867   memset (&ctx, 0, sizeof ctx);
7868
7869   args.root = (char *) root;
7870   args.device = (char *) device;
7871   serial = guestfs__send_sync (g, GUESTFS_PROC_GRUB_INSTALL,
7872         (xdrproc_t) xdr_guestfs_grub_install_args, (char *) &args);
7873   if (serial == -1) {
7874     guestfs_end_busy (g);
7875     return -1;
7876   }
7877
7878   guestfs__switch_to_receiving (g);
7879   ctx.cb_sequence = 0;
7880   guestfs_set_reply_callback (g, grub_install_reply_cb, &ctx);
7881   (void) ml->main_loop_run (ml, g);
7882   guestfs_set_reply_callback (g, NULL, NULL);
7883   if (ctx.cb_sequence != 1) {
7884     error (g, "%s reply failed, see earlier error messages", "guestfs_grub_install");
7885     guestfs_end_busy (g);
7886     return -1;
7887   }
7888
7889   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_GRUB_INSTALL, serial) == -1) {
7890     guestfs_end_busy (g);
7891     return -1;
7892   }
7893
7894   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7895     error (g, "%s", ctx.err.error_message);
7896     free (ctx.err.error_message);
7897     guestfs_end_busy (g);
7898     return -1;
7899   }
7900
7901   guestfs_end_busy (g);
7902   return 0;
7903 }
7904
7905 struct cp_ctx {
7906   /* This flag is set by the callbacks, so we know we've done
7907    * the callbacks as expected, and in the right sequence.
7908    * 0 = not called, 1 = reply_cb called.
7909    */
7910   int cb_sequence;
7911   struct guestfs_message_header hdr;
7912   struct guestfs_message_error err;
7913 };
7914
7915 static void cp_reply_cb (guestfs_h *g, void *data, XDR *xdr)
7916 {
7917   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7918   struct cp_ctx *ctx = (struct cp_ctx *) data;
7919
7920   /* This should definitely not happen. */
7921   if (ctx->cb_sequence != 0) {
7922     ctx->cb_sequence = 9999;
7923     error (g, "%s: internal error: reply callback called twice", "guestfs_cp");
7924     return;
7925   }
7926
7927   ml->main_loop_quit (ml, g);
7928
7929   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
7930     error (g, "%s: failed to parse reply header", "guestfs_cp");
7931     return;
7932   }
7933   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
7934     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
7935       error (g, "%s: failed to parse reply error", "guestfs_cp");
7936       return;
7937     }
7938     goto done;
7939   }
7940  done:
7941   ctx->cb_sequence = 1;
7942 }
7943
7944 int guestfs_cp (guestfs_h *g,
7945                 const char *src,
7946                 const char *dest)
7947 {
7948   struct guestfs_cp_args args;
7949   struct cp_ctx ctx;
7950   guestfs_main_loop *ml = guestfs_get_main_loop (g);
7951   int serial;
7952
7953   if (check_state (g, "guestfs_cp") == -1) return -1;
7954   guestfs_set_busy (g);
7955
7956   memset (&ctx, 0, sizeof ctx);
7957
7958   args.src = (char *) src;
7959   args.dest = (char *) dest;
7960   serial = guestfs__send_sync (g, GUESTFS_PROC_CP,
7961         (xdrproc_t) xdr_guestfs_cp_args, (char *) &args);
7962   if (serial == -1) {
7963     guestfs_end_busy (g);
7964     return -1;
7965   }
7966
7967   guestfs__switch_to_receiving (g);
7968   ctx.cb_sequence = 0;
7969   guestfs_set_reply_callback (g, cp_reply_cb, &ctx);
7970   (void) ml->main_loop_run (ml, g);
7971   guestfs_set_reply_callback (g, NULL, NULL);
7972   if (ctx.cb_sequence != 1) {
7973     error (g, "%s reply failed, see earlier error messages", "guestfs_cp");
7974     guestfs_end_busy (g);
7975     return -1;
7976   }
7977
7978   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CP, serial) == -1) {
7979     guestfs_end_busy (g);
7980     return -1;
7981   }
7982
7983   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
7984     error (g, "%s", ctx.err.error_message);
7985     free (ctx.err.error_message);
7986     guestfs_end_busy (g);
7987     return -1;
7988   }
7989
7990   guestfs_end_busy (g);
7991   return 0;
7992 }
7993
7994 struct cp_a_ctx {
7995   /* This flag is set by the callbacks, so we know we've done
7996    * the callbacks as expected, and in the right sequence.
7997    * 0 = not called, 1 = reply_cb called.
7998    */
7999   int cb_sequence;
8000   struct guestfs_message_header hdr;
8001   struct guestfs_message_error err;
8002 };
8003
8004 static void cp_a_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8005 {
8006   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8007   struct cp_a_ctx *ctx = (struct cp_a_ctx *) data;
8008
8009   /* This should definitely not happen. */
8010   if (ctx->cb_sequence != 0) {
8011     ctx->cb_sequence = 9999;
8012     error (g, "%s: internal error: reply callback called twice", "guestfs_cp_a");
8013     return;
8014   }
8015
8016   ml->main_loop_quit (ml, g);
8017
8018   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8019     error (g, "%s: failed to parse reply header", "guestfs_cp_a");
8020     return;
8021   }
8022   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8023     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8024       error (g, "%s: failed to parse reply error", "guestfs_cp_a");
8025       return;
8026     }
8027     goto done;
8028   }
8029  done:
8030   ctx->cb_sequence = 1;
8031 }
8032
8033 int guestfs_cp_a (guestfs_h *g,
8034                 const char *src,
8035                 const char *dest)
8036 {
8037   struct guestfs_cp_a_args args;
8038   struct cp_a_ctx ctx;
8039   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8040   int serial;
8041
8042   if (check_state (g, "guestfs_cp_a") == -1) return -1;
8043   guestfs_set_busy (g);
8044
8045   memset (&ctx, 0, sizeof ctx);
8046
8047   args.src = (char *) src;
8048   args.dest = (char *) dest;
8049   serial = guestfs__send_sync (g, GUESTFS_PROC_CP_A,
8050         (xdrproc_t) xdr_guestfs_cp_a_args, (char *) &args);
8051   if (serial == -1) {
8052     guestfs_end_busy (g);
8053     return -1;
8054   }
8055
8056   guestfs__switch_to_receiving (g);
8057   ctx.cb_sequence = 0;
8058   guestfs_set_reply_callback (g, cp_a_reply_cb, &ctx);
8059   (void) ml->main_loop_run (ml, g);
8060   guestfs_set_reply_callback (g, NULL, NULL);
8061   if (ctx.cb_sequence != 1) {
8062     error (g, "%s reply failed, see earlier error messages", "guestfs_cp_a");
8063     guestfs_end_busy (g);
8064     return -1;
8065   }
8066
8067   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_CP_A, serial) == -1) {
8068     guestfs_end_busy (g);
8069     return -1;
8070   }
8071
8072   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8073     error (g, "%s", ctx.err.error_message);
8074     free (ctx.err.error_message);
8075     guestfs_end_busy (g);
8076     return -1;
8077   }
8078
8079   guestfs_end_busy (g);
8080   return 0;
8081 }
8082
8083 struct mv_ctx {
8084   /* This flag is set by the callbacks, so we know we've done
8085    * the callbacks as expected, and in the right sequence.
8086    * 0 = not called, 1 = reply_cb called.
8087    */
8088   int cb_sequence;
8089   struct guestfs_message_header hdr;
8090   struct guestfs_message_error err;
8091 };
8092
8093 static void mv_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8094 {
8095   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8096   struct mv_ctx *ctx = (struct mv_ctx *) data;
8097
8098   /* This should definitely not happen. */
8099   if (ctx->cb_sequence != 0) {
8100     ctx->cb_sequence = 9999;
8101     error (g, "%s: internal error: reply callback called twice", "guestfs_mv");
8102     return;
8103   }
8104
8105   ml->main_loop_quit (ml, g);
8106
8107   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8108     error (g, "%s: failed to parse reply header", "guestfs_mv");
8109     return;
8110   }
8111   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8112     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8113       error (g, "%s: failed to parse reply error", "guestfs_mv");
8114       return;
8115     }
8116     goto done;
8117   }
8118  done:
8119   ctx->cb_sequence = 1;
8120 }
8121
8122 int guestfs_mv (guestfs_h *g,
8123                 const char *src,
8124                 const char *dest)
8125 {
8126   struct guestfs_mv_args args;
8127   struct mv_ctx ctx;
8128   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8129   int serial;
8130
8131   if (check_state (g, "guestfs_mv") == -1) return -1;
8132   guestfs_set_busy (g);
8133
8134   memset (&ctx, 0, sizeof ctx);
8135
8136   args.src = (char *) src;
8137   args.dest = (char *) dest;
8138   serial = guestfs__send_sync (g, GUESTFS_PROC_MV,
8139         (xdrproc_t) xdr_guestfs_mv_args, (char *) &args);
8140   if (serial == -1) {
8141     guestfs_end_busy (g);
8142     return -1;
8143   }
8144
8145   guestfs__switch_to_receiving (g);
8146   ctx.cb_sequence = 0;
8147   guestfs_set_reply_callback (g, mv_reply_cb, &ctx);
8148   (void) ml->main_loop_run (ml, g);
8149   guestfs_set_reply_callback (g, NULL, NULL);
8150   if (ctx.cb_sequence != 1) {
8151     error (g, "%s reply failed, see earlier error messages", "guestfs_mv");
8152     guestfs_end_busy (g);
8153     return -1;
8154   }
8155
8156   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_MV, serial) == -1) {
8157     guestfs_end_busy (g);
8158     return -1;
8159   }
8160
8161   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8162     error (g, "%s", ctx.err.error_message);
8163     free (ctx.err.error_message);
8164     guestfs_end_busy (g);
8165     return -1;
8166   }
8167
8168   guestfs_end_busy (g);
8169   return 0;
8170 }
8171
8172 struct drop_caches_ctx {
8173   /* This flag is set by the callbacks, so we know we've done
8174    * the callbacks as expected, and in the right sequence.
8175    * 0 = not called, 1 = reply_cb called.
8176    */
8177   int cb_sequence;
8178   struct guestfs_message_header hdr;
8179   struct guestfs_message_error err;
8180 };
8181
8182 static void drop_caches_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8183 {
8184   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8185   struct drop_caches_ctx *ctx = (struct drop_caches_ctx *) data;
8186
8187   /* This should definitely not happen. */
8188   if (ctx->cb_sequence != 0) {
8189     ctx->cb_sequence = 9999;
8190     error (g, "%s: internal error: reply callback called twice", "guestfs_drop_caches");
8191     return;
8192   }
8193
8194   ml->main_loop_quit (ml, g);
8195
8196   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8197     error (g, "%s: failed to parse reply header", "guestfs_drop_caches");
8198     return;
8199   }
8200   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8201     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8202       error (g, "%s: failed to parse reply error", "guestfs_drop_caches");
8203       return;
8204     }
8205     goto done;
8206   }
8207  done:
8208   ctx->cb_sequence = 1;
8209 }
8210
8211 int guestfs_drop_caches (guestfs_h *g,
8212                 int whattodrop)
8213 {
8214   struct guestfs_drop_caches_args args;
8215   struct drop_caches_ctx ctx;
8216   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8217   int serial;
8218
8219   if (check_state (g, "guestfs_drop_caches") == -1) return -1;
8220   guestfs_set_busy (g);
8221
8222   memset (&ctx, 0, sizeof ctx);
8223
8224   args.whattodrop = whattodrop;
8225   serial = guestfs__send_sync (g, GUESTFS_PROC_DROP_CACHES,
8226         (xdrproc_t) xdr_guestfs_drop_caches_args, (char *) &args);
8227   if (serial == -1) {
8228     guestfs_end_busy (g);
8229     return -1;
8230   }
8231
8232   guestfs__switch_to_receiving (g);
8233   ctx.cb_sequence = 0;
8234   guestfs_set_reply_callback (g, drop_caches_reply_cb, &ctx);
8235   (void) ml->main_loop_run (ml, g);
8236   guestfs_set_reply_callback (g, NULL, NULL);
8237   if (ctx.cb_sequence != 1) {
8238     error (g, "%s reply failed, see earlier error messages", "guestfs_drop_caches");
8239     guestfs_end_busy (g);
8240     return -1;
8241   }
8242
8243   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_DROP_CACHES, serial) == -1) {
8244     guestfs_end_busy (g);
8245     return -1;
8246   }
8247
8248   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8249     error (g, "%s", ctx.err.error_message);
8250     free (ctx.err.error_message);
8251     guestfs_end_busy (g);
8252     return -1;
8253   }
8254
8255   guestfs_end_busy (g);
8256   return 0;
8257 }
8258
8259 struct dmesg_ctx {
8260   /* This flag is set by the callbacks, so we know we've done
8261    * the callbacks as expected, and in the right sequence.
8262    * 0 = not called, 1 = reply_cb called.
8263    */
8264   int cb_sequence;
8265   struct guestfs_message_header hdr;
8266   struct guestfs_message_error err;
8267   struct guestfs_dmesg_ret ret;
8268 };
8269
8270 static void dmesg_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8271 {
8272   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8273   struct dmesg_ctx *ctx = (struct dmesg_ctx *) data;
8274
8275   /* This should definitely not happen. */
8276   if (ctx->cb_sequence != 0) {
8277     ctx->cb_sequence = 9999;
8278     error (g, "%s: internal error: reply callback called twice", "guestfs_dmesg");
8279     return;
8280   }
8281
8282   ml->main_loop_quit (ml, g);
8283
8284   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8285     error (g, "%s: failed to parse reply header", "guestfs_dmesg");
8286     return;
8287   }
8288   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8289     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8290       error (g, "%s: failed to parse reply error", "guestfs_dmesg");
8291       return;
8292     }
8293     goto done;
8294   }
8295   if (!xdr_guestfs_dmesg_ret (xdr, &ctx->ret)) {
8296     error (g, "%s: failed to parse reply", "guestfs_dmesg");
8297     return;
8298   }
8299  done:
8300   ctx->cb_sequence = 1;
8301 }
8302
8303 char *guestfs_dmesg (guestfs_h *g)
8304 {
8305   struct dmesg_ctx ctx;
8306   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8307   int serial;
8308
8309   if (check_state (g, "guestfs_dmesg") == -1) return NULL;
8310   guestfs_set_busy (g);
8311
8312   memset (&ctx, 0, sizeof ctx);
8313
8314   serial = guestfs__send_sync (g, GUESTFS_PROC_DMESG, NULL, NULL);
8315   if (serial == -1) {
8316     guestfs_end_busy (g);
8317     return NULL;
8318   }
8319
8320   guestfs__switch_to_receiving (g);
8321   ctx.cb_sequence = 0;
8322   guestfs_set_reply_callback (g, dmesg_reply_cb, &ctx);
8323   (void) ml->main_loop_run (ml, g);
8324   guestfs_set_reply_callback (g, NULL, NULL);
8325   if (ctx.cb_sequence != 1) {
8326     error (g, "%s reply failed, see earlier error messages", "guestfs_dmesg");
8327     guestfs_end_busy (g);
8328     return NULL;
8329   }
8330
8331   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_DMESG, serial) == -1) {
8332     guestfs_end_busy (g);
8333     return NULL;
8334   }
8335
8336   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8337     error (g, "%s", ctx.err.error_message);
8338     free (ctx.err.error_message);
8339     guestfs_end_busy (g);
8340     return NULL;
8341   }
8342
8343   guestfs_end_busy (g);
8344   return ctx.ret.kmsgs; /* caller will free */
8345 }
8346
8347 struct ping_daemon_ctx {
8348   /* This flag is set by the callbacks, so we know we've done
8349    * the callbacks as expected, and in the right sequence.
8350    * 0 = not called, 1 = reply_cb called.
8351    */
8352   int cb_sequence;
8353   struct guestfs_message_header hdr;
8354   struct guestfs_message_error err;
8355 };
8356
8357 static void ping_daemon_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8358 {
8359   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8360   struct ping_daemon_ctx *ctx = (struct ping_daemon_ctx *) data;
8361
8362   /* This should definitely not happen. */
8363   if (ctx->cb_sequence != 0) {
8364     ctx->cb_sequence = 9999;
8365     error (g, "%s: internal error: reply callback called twice", "guestfs_ping_daemon");
8366     return;
8367   }
8368
8369   ml->main_loop_quit (ml, g);
8370
8371   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8372     error (g, "%s: failed to parse reply header", "guestfs_ping_daemon");
8373     return;
8374   }
8375   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8376     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8377       error (g, "%s: failed to parse reply error", "guestfs_ping_daemon");
8378       return;
8379     }
8380     goto done;
8381   }
8382  done:
8383   ctx->cb_sequence = 1;
8384 }
8385
8386 int guestfs_ping_daemon (guestfs_h *g)
8387 {
8388   struct ping_daemon_ctx ctx;
8389   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8390   int serial;
8391
8392   if (check_state (g, "guestfs_ping_daemon") == -1) return -1;
8393   guestfs_set_busy (g);
8394
8395   memset (&ctx, 0, sizeof ctx);
8396
8397   serial = guestfs__send_sync (g, GUESTFS_PROC_PING_DAEMON, NULL, NULL);
8398   if (serial == -1) {
8399     guestfs_end_busy (g);
8400     return -1;
8401   }
8402
8403   guestfs__switch_to_receiving (g);
8404   ctx.cb_sequence = 0;
8405   guestfs_set_reply_callback (g, ping_daemon_reply_cb, &ctx);
8406   (void) ml->main_loop_run (ml, g);
8407   guestfs_set_reply_callback (g, NULL, NULL);
8408   if (ctx.cb_sequence != 1) {
8409     error (g, "%s reply failed, see earlier error messages", "guestfs_ping_daemon");
8410     guestfs_end_busy (g);
8411     return -1;
8412   }
8413
8414   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PING_DAEMON, serial) == -1) {
8415     guestfs_end_busy (g);
8416     return -1;
8417   }
8418
8419   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8420     error (g, "%s", ctx.err.error_message);
8421     free (ctx.err.error_message);
8422     guestfs_end_busy (g);
8423     return -1;
8424   }
8425
8426   guestfs_end_busy (g);
8427   return 0;
8428 }
8429
8430 struct equal_ctx {
8431   /* This flag is set by the callbacks, so we know we've done
8432    * the callbacks as expected, and in the right sequence.
8433    * 0 = not called, 1 = reply_cb called.
8434    */
8435   int cb_sequence;
8436   struct guestfs_message_header hdr;
8437   struct guestfs_message_error err;
8438   struct guestfs_equal_ret ret;
8439 };
8440
8441 static void equal_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8442 {
8443   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8444   struct equal_ctx *ctx = (struct equal_ctx *) data;
8445
8446   /* This should definitely not happen. */
8447   if (ctx->cb_sequence != 0) {
8448     ctx->cb_sequence = 9999;
8449     error (g, "%s: internal error: reply callback called twice", "guestfs_equal");
8450     return;
8451   }
8452
8453   ml->main_loop_quit (ml, g);
8454
8455   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8456     error (g, "%s: failed to parse reply header", "guestfs_equal");
8457     return;
8458   }
8459   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8460     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8461       error (g, "%s: failed to parse reply error", "guestfs_equal");
8462       return;
8463     }
8464     goto done;
8465   }
8466   if (!xdr_guestfs_equal_ret (xdr, &ctx->ret)) {
8467     error (g, "%s: failed to parse reply", "guestfs_equal");
8468     return;
8469   }
8470  done:
8471   ctx->cb_sequence = 1;
8472 }
8473
8474 int guestfs_equal (guestfs_h *g,
8475                 const char *file1,
8476                 const char *file2)
8477 {
8478   struct guestfs_equal_args args;
8479   struct equal_ctx ctx;
8480   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8481   int serial;
8482
8483   if (check_state (g, "guestfs_equal") == -1) return -1;
8484   guestfs_set_busy (g);
8485
8486   memset (&ctx, 0, sizeof ctx);
8487
8488   args.file1 = (char *) file1;
8489   args.file2 = (char *) file2;
8490   serial = guestfs__send_sync (g, GUESTFS_PROC_EQUAL,
8491         (xdrproc_t) xdr_guestfs_equal_args, (char *) &args);
8492   if (serial == -1) {
8493     guestfs_end_busy (g);
8494     return -1;
8495   }
8496
8497   guestfs__switch_to_receiving (g);
8498   ctx.cb_sequence = 0;
8499   guestfs_set_reply_callback (g, equal_reply_cb, &ctx);
8500   (void) ml->main_loop_run (ml, g);
8501   guestfs_set_reply_callback (g, NULL, NULL);
8502   if (ctx.cb_sequence != 1) {
8503     error (g, "%s reply failed, see earlier error messages", "guestfs_equal");
8504     guestfs_end_busy (g);
8505     return -1;
8506   }
8507
8508   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_EQUAL, serial) == -1) {
8509     guestfs_end_busy (g);
8510     return -1;
8511   }
8512
8513   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8514     error (g, "%s", ctx.err.error_message);
8515     free (ctx.err.error_message);
8516     guestfs_end_busy (g);
8517     return -1;
8518   }
8519
8520   guestfs_end_busy (g);
8521   return ctx.ret.equality;
8522 }
8523
8524 struct strings_ctx {
8525   /* This flag is set by the callbacks, so we know we've done
8526    * the callbacks as expected, and in the right sequence.
8527    * 0 = not called, 1 = reply_cb called.
8528    */
8529   int cb_sequence;
8530   struct guestfs_message_header hdr;
8531   struct guestfs_message_error err;
8532   struct guestfs_strings_ret ret;
8533 };
8534
8535 static void strings_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8536 {
8537   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8538   struct strings_ctx *ctx = (struct strings_ctx *) data;
8539
8540   /* This should definitely not happen. */
8541   if (ctx->cb_sequence != 0) {
8542     ctx->cb_sequence = 9999;
8543     error (g, "%s: internal error: reply callback called twice", "guestfs_strings");
8544     return;
8545   }
8546
8547   ml->main_loop_quit (ml, g);
8548
8549   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8550     error (g, "%s: failed to parse reply header", "guestfs_strings");
8551     return;
8552   }
8553   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8554     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8555       error (g, "%s: failed to parse reply error", "guestfs_strings");
8556       return;
8557     }
8558     goto done;
8559   }
8560   if (!xdr_guestfs_strings_ret (xdr, &ctx->ret)) {
8561     error (g, "%s: failed to parse reply", "guestfs_strings");
8562     return;
8563   }
8564  done:
8565   ctx->cb_sequence = 1;
8566 }
8567
8568 char **guestfs_strings (guestfs_h *g,
8569                 const char *path)
8570 {
8571   struct guestfs_strings_args args;
8572   struct strings_ctx ctx;
8573   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8574   int serial;
8575
8576   if (check_state (g, "guestfs_strings") == -1) return NULL;
8577   guestfs_set_busy (g);
8578
8579   memset (&ctx, 0, sizeof ctx);
8580
8581   args.path = (char *) path;
8582   serial = guestfs__send_sync (g, GUESTFS_PROC_STRINGS,
8583         (xdrproc_t) xdr_guestfs_strings_args, (char *) &args);
8584   if (serial == -1) {
8585     guestfs_end_busy (g);
8586     return NULL;
8587   }
8588
8589   guestfs__switch_to_receiving (g);
8590   ctx.cb_sequence = 0;
8591   guestfs_set_reply_callback (g, strings_reply_cb, &ctx);
8592   (void) ml->main_loop_run (ml, g);
8593   guestfs_set_reply_callback (g, NULL, NULL);
8594   if (ctx.cb_sequence != 1) {
8595     error (g, "%s reply failed, see earlier error messages", "guestfs_strings");
8596     guestfs_end_busy (g);
8597     return NULL;
8598   }
8599
8600   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STRINGS, serial) == -1) {
8601     guestfs_end_busy (g);
8602     return NULL;
8603   }
8604
8605   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8606     error (g, "%s", ctx.err.error_message);
8607     free (ctx.err.error_message);
8608     guestfs_end_busy (g);
8609     return NULL;
8610   }
8611
8612   guestfs_end_busy (g);
8613   /* caller will free this, but we need to add a NULL entry */
8614   ctx.ret.stringsout.stringsout_val =
8615     safe_realloc (g, ctx.ret.stringsout.stringsout_val,
8616                   sizeof (char *) * (ctx.ret.stringsout.stringsout_len + 1));
8617   ctx.ret.stringsout.stringsout_val[ctx.ret.stringsout.stringsout_len] = NULL;
8618   return ctx.ret.stringsout.stringsout_val;
8619 }
8620
8621 struct strings_e_ctx {
8622   /* This flag is set by the callbacks, so we know we've done
8623    * the callbacks as expected, and in the right sequence.
8624    * 0 = not called, 1 = reply_cb called.
8625    */
8626   int cb_sequence;
8627   struct guestfs_message_header hdr;
8628   struct guestfs_message_error err;
8629   struct guestfs_strings_e_ret ret;
8630 };
8631
8632 static void strings_e_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8633 {
8634   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8635   struct strings_e_ctx *ctx = (struct strings_e_ctx *) data;
8636
8637   /* This should definitely not happen. */
8638   if (ctx->cb_sequence != 0) {
8639     ctx->cb_sequence = 9999;
8640     error (g, "%s: internal error: reply callback called twice", "guestfs_strings_e");
8641     return;
8642   }
8643
8644   ml->main_loop_quit (ml, g);
8645
8646   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8647     error (g, "%s: failed to parse reply header", "guestfs_strings_e");
8648     return;
8649   }
8650   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8651     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8652       error (g, "%s: failed to parse reply error", "guestfs_strings_e");
8653       return;
8654     }
8655     goto done;
8656   }
8657   if (!xdr_guestfs_strings_e_ret (xdr, &ctx->ret)) {
8658     error (g, "%s: failed to parse reply", "guestfs_strings_e");
8659     return;
8660   }
8661  done:
8662   ctx->cb_sequence = 1;
8663 }
8664
8665 char **guestfs_strings_e (guestfs_h *g,
8666                 const char *encoding,
8667                 const char *path)
8668 {
8669   struct guestfs_strings_e_args args;
8670   struct strings_e_ctx ctx;
8671   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8672   int serial;
8673
8674   if (check_state (g, "guestfs_strings_e") == -1) return NULL;
8675   guestfs_set_busy (g);
8676
8677   memset (&ctx, 0, sizeof ctx);
8678
8679   args.encoding = (char *) encoding;
8680   args.path = (char *) path;
8681   serial = guestfs__send_sync (g, GUESTFS_PROC_STRINGS_E,
8682         (xdrproc_t) xdr_guestfs_strings_e_args, (char *) &args);
8683   if (serial == -1) {
8684     guestfs_end_busy (g);
8685     return NULL;
8686   }
8687
8688   guestfs__switch_to_receiving (g);
8689   ctx.cb_sequence = 0;
8690   guestfs_set_reply_callback (g, strings_e_reply_cb, &ctx);
8691   (void) ml->main_loop_run (ml, g);
8692   guestfs_set_reply_callback (g, NULL, NULL);
8693   if (ctx.cb_sequence != 1) {
8694     error (g, "%s reply failed, see earlier error messages", "guestfs_strings_e");
8695     guestfs_end_busy (g);
8696     return NULL;
8697   }
8698
8699   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_STRINGS_E, serial) == -1) {
8700     guestfs_end_busy (g);
8701     return NULL;
8702   }
8703
8704   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8705     error (g, "%s", ctx.err.error_message);
8706     free (ctx.err.error_message);
8707     guestfs_end_busy (g);
8708     return NULL;
8709   }
8710
8711   guestfs_end_busy (g);
8712   /* caller will free this, but we need to add a NULL entry */
8713   ctx.ret.stringsout.stringsout_val =
8714     safe_realloc (g, ctx.ret.stringsout.stringsout_val,
8715                   sizeof (char *) * (ctx.ret.stringsout.stringsout_len + 1));
8716   ctx.ret.stringsout.stringsout_val[ctx.ret.stringsout.stringsout_len] = NULL;
8717   return ctx.ret.stringsout.stringsout_val;
8718 }
8719
8720 struct hexdump_ctx {
8721   /* This flag is set by the callbacks, so we know we've done
8722    * the callbacks as expected, and in the right sequence.
8723    * 0 = not called, 1 = reply_cb called.
8724    */
8725   int cb_sequence;
8726   struct guestfs_message_header hdr;
8727   struct guestfs_message_error err;
8728   struct guestfs_hexdump_ret ret;
8729 };
8730
8731 static void hexdump_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8732 {
8733   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8734   struct hexdump_ctx *ctx = (struct hexdump_ctx *) data;
8735
8736   /* This should definitely not happen. */
8737   if (ctx->cb_sequence != 0) {
8738     ctx->cb_sequence = 9999;
8739     error (g, "%s: internal error: reply callback called twice", "guestfs_hexdump");
8740     return;
8741   }
8742
8743   ml->main_loop_quit (ml, g);
8744
8745   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8746     error (g, "%s: failed to parse reply header", "guestfs_hexdump");
8747     return;
8748   }
8749   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8750     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8751       error (g, "%s: failed to parse reply error", "guestfs_hexdump");
8752       return;
8753     }
8754     goto done;
8755   }
8756   if (!xdr_guestfs_hexdump_ret (xdr, &ctx->ret)) {
8757     error (g, "%s: failed to parse reply", "guestfs_hexdump");
8758     return;
8759   }
8760  done:
8761   ctx->cb_sequence = 1;
8762 }
8763
8764 char *guestfs_hexdump (guestfs_h *g,
8765                 const char *path)
8766 {
8767   struct guestfs_hexdump_args args;
8768   struct hexdump_ctx ctx;
8769   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8770   int serial;
8771
8772   if (check_state (g, "guestfs_hexdump") == -1) return NULL;
8773   guestfs_set_busy (g);
8774
8775   memset (&ctx, 0, sizeof ctx);
8776
8777   args.path = (char *) path;
8778   serial = guestfs__send_sync (g, GUESTFS_PROC_HEXDUMP,
8779         (xdrproc_t) xdr_guestfs_hexdump_args, (char *) &args);
8780   if (serial == -1) {
8781     guestfs_end_busy (g);
8782     return NULL;
8783   }
8784
8785   guestfs__switch_to_receiving (g);
8786   ctx.cb_sequence = 0;
8787   guestfs_set_reply_callback (g, hexdump_reply_cb, &ctx);
8788   (void) ml->main_loop_run (ml, g);
8789   guestfs_set_reply_callback (g, NULL, NULL);
8790   if (ctx.cb_sequence != 1) {
8791     error (g, "%s reply failed, see earlier error messages", "guestfs_hexdump");
8792     guestfs_end_busy (g);
8793     return NULL;
8794   }
8795
8796   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_HEXDUMP, serial) == -1) {
8797     guestfs_end_busy (g);
8798     return NULL;
8799   }
8800
8801   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8802     error (g, "%s", ctx.err.error_message);
8803     free (ctx.err.error_message);
8804     guestfs_end_busy (g);
8805     return NULL;
8806   }
8807
8808   guestfs_end_busy (g);
8809   return ctx.ret.dump; /* caller will free */
8810 }
8811
8812 struct zerofree_ctx {
8813   /* This flag is set by the callbacks, so we know we've done
8814    * the callbacks as expected, and in the right sequence.
8815    * 0 = not called, 1 = reply_cb called.
8816    */
8817   int cb_sequence;
8818   struct guestfs_message_header hdr;
8819   struct guestfs_message_error err;
8820 };
8821
8822 static void zerofree_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8823 {
8824   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8825   struct zerofree_ctx *ctx = (struct zerofree_ctx *) data;
8826
8827   /* This should definitely not happen. */
8828   if (ctx->cb_sequence != 0) {
8829     ctx->cb_sequence = 9999;
8830     error (g, "%s: internal error: reply callback called twice", "guestfs_zerofree");
8831     return;
8832   }
8833
8834   ml->main_loop_quit (ml, g);
8835
8836   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8837     error (g, "%s: failed to parse reply header", "guestfs_zerofree");
8838     return;
8839   }
8840   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8841     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8842       error (g, "%s: failed to parse reply error", "guestfs_zerofree");
8843       return;
8844     }
8845     goto done;
8846   }
8847  done:
8848   ctx->cb_sequence = 1;
8849 }
8850
8851 int guestfs_zerofree (guestfs_h *g,
8852                 const char *device)
8853 {
8854   struct guestfs_zerofree_args args;
8855   struct zerofree_ctx ctx;
8856   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8857   int serial;
8858
8859   if (check_state (g, "guestfs_zerofree") == -1) return -1;
8860   guestfs_set_busy (g);
8861
8862   memset (&ctx, 0, sizeof ctx);
8863
8864   args.device = (char *) device;
8865   serial = guestfs__send_sync (g, GUESTFS_PROC_ZEROFREE,
8866         (xdrproc_t) xdr_guestfs_zerofree_args, (char *) &args);
8867   if (serial == -1) {
8868     guestfs_end_busy (g);
8869     return -1;
8870   }
8871
8872   guestfs__switch_to_receiving (g);
8873   ctx.cb_sequence = 0;
8874   guestfs_set_reply_callback (g, zerofree_reply_cb, &ctx);
8875   (void) ml->main_loop_run (ml, g);
8876   guestfs_set_reply_callback (g, NULL, NULL);
8877   if (ctx.cb_sequence != 1) {
8878     error (g, "%s reply failed, see earlier error messages", "guestfs_zerofree");
8879     guestfs_end_busy (g);
8880     return -1;
8881   }
8882
8883   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_ZEROFREE, serial) == -1) {
8884     guestfs_end_busy (g);
8885     return -1;
8886   }
8887
8888   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8889     error (g, "%s", ctx.err.error_message);
8890     free (ctx.err.error_message);
8891     guestfs_end_busy (g);
8892     return -1;
8893   }
8894
8895   guestfs_end_busy (g);
8896   return 0;
8897 }
8898
8899 struct pvresize_ctx {
8900   /* This flag is set by the callbacks, so we know we've done
8901    * the callbacks as expected, and in the right sequence.
8902    * 0 = not called, 1 = reply_cb called.
8903    */
8904   int cb_sequence;
8905   struct guestfs_message_header hdr;
8906   struct guestfs_message_error err;
8907 };
8908
8909 static void pvresize_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8910 {
8911   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8912   struct pvresize_ctx *ctx = (struct pvresize_ctx *) data;
8913
8914   /* This should definitely not happen. */
8915   if (ctx->cb_sequence != 0) {
8916     ctx->cb_sequence = 9999;
8917     error (g, "%s: internal error: reply callback called twice", "guestfs_pvresize");
8918     return;
8919   }
8920
8921   ml->main_loop_quit (ml, g);
8922
8923   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
8924     error (g, "%s: failed to parse reply header", "guestfs_pvresize");
8925     return;
8926   }
8927   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
8928     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
8929       error (g, "%s: failed to parse reply error", "guestfs_pvresize");
8930       return;
8931     }
8932     goto done;
8933   }
8934  done:
8935   ctx->cb_sequence = 1;
8936 }
8937
8938 int guestfs_pvresize (guestfs_h *g,
8939                 const char *device)
8940 {
8941   struct guestfs_pvresize_args args;
8942   struct pvresize_ctx ctx;
8943   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8944   int serial;
8945
8946   if (check_state (g, "guestfs_pvresize") == -1) return -1;
8947   guestfs_set_busy (g);
8948
8949   memset (&ctx, 0, sizeof ctx);
8950
8951   args.device = (char *) device;
8952   serial = guestfs__send_sync (g, GUESTFS_PROC_PVRESIZE,
8953         (xdrproc_t) xdr_guestfs_pvresize_args, (char *) &args);
8954   if (serial == -1) {
8955     guestfs_end_busy (g);
8956     return -1;
8957   }
8958
8959   guestfs__switch_to_receiving (g);
8960   ctx.cb_sequence = 0;
8961   guestfs_set_reply_callback (g, pvresize_reply_cb, &ctx);
8962   (void) ml->main_loop_run (ml, g);
8963   guestfs_set_reply_callback (g, NULL, NULL);
8964   if (ctx.cb_sequence != 1) {
8965     error (g, "%s reply failed, see earlier error messages", "guestfs_pvresize");
8966     guestfs_end_busy (g);
8967     return -1;
8968   }
8969
8970   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVRESIZE, serial) == -1) {
8971     guestfs_end_busy (g);
8972     return -1;
8973   }
8974
8975   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
8976     error (g, "%s", ctx.err.error_message);
8977     free (ctx.err.error_message);
8978     guestfs_end_busy (g);
8979     return -1;
8980   }
8981
8982   guestfs_end_busy (g);
8983   return 0;
8984 }
8985
8986 struct sfdisk_N_ctx {
8987   /* This flag is set by the callbacks, so we know we've done
8988    * the callbacks as expected, and in the right sequence.
8989    * 0 = not called, 1 = reply_cb called.
8990    */
8991   int cb_sequence;
8992   struct guestfs_message_header hdr;
8993   struct guestfs_message_error err;
8994 };
8995
8996 static void sfdisk_N_reply_cb (guestfs_h *g, void *data, XDR *xdr)
8997 {
8998   guestfs_main_loop *ml = guestfs_get_main_loop (g);
8999   struct sfdisk_N_ctx *ctx = (struct sfdisk_N_ctx *) data;
9000
9001   /* This should definitely not happen. */
9002   if (ctx->cb_sequence != 0) {
9003     ctx->cb_sequence = 9999;
9004     error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_N");
9005     return;
9006   }
9007
9008   ml->main_loop_quit (ml, g);
9009
9010   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9011     error (g, "%s: failed to parse reply header", "guestfs_sfdisk_N");
9012     return;
9013   }
9014   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9015     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9016       error (g, "%s: failed to parse reply error", "guestfs_sfdisk_N");
9017       return;
9018     }
9019     goto done;
9020   }
9021  done:
9022   ctx->cb_sequence = 1;
9023 }
9024
9025 int guestfs_sfdisk_N (guestfs_h *g,
9026                 const char *device,
9027                 int n,
9028                 int cyls,
9029                 int heads,
9030                 int sectors,
9031                 const char *line)
9032 {
9033   struct guestfs_sfdisk_N_args args;
9034   struct sfdisk_N_ctx ctx;
9035   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9036   int serial;
9037
9038   if (check_state (g, "guestfs_sfdisk_N") == -1) return -1;
9039   guestfs_set_busy (g);
9040
9041   memset (&ctx, 0, sizeof ctx);
9042
9043   args.device = (char *) device;
9044   args.n = n;
9045   args.cyls = cyls;
9046   args.heads = heads;
9047   args.sectors = sectors;
9048   args.line = (char *) line;
9049   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_N,
9050         (xdrproc_t) xdr_guestfs_sfdisk_N_args, (char *) &args);
9051   if (serial == -1) {
9052     guestfs_end_busy (g);
9053     return -1;
9054   }
9055
9056   guestfs__switch_to_receiving (g);
9057   ctx.cb_sequence = 0;
9058   guestfs_set_reply_callback (g, sfdisk_N_reply_cb, &ctx);
9059   (void) ml->main_loop_run (ml, g);
9060   guestfs_set_reply_callback (g, NULL, NULL);
9061   if (ctx.cb_sequence != 1) {
9062     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_N");
9063     guestfs_end_busy (g);
9064     return -1;
9065   }
9066
9067   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_N, serial) == -1) {
9068     guestfs_end_busy (g);
9069     return -1;
9070   }
9071
9072   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9073     error (g, "%s", ctx.err.error_message);
9074     free (ctx.err.error_message);
9075     guestfs_end_busy (g);
9076     return -1;
9077   }
9078
9079   guestfs_end_busy (g);
9080   return 0;
9081 }
9082
9083 struct sfdisk_l_ctx {
9084   /* This flag is set by the callbacks, so we know we've done
9085    * the callbacks as expected, and in the right sequence.
9086    * 0 = not called, 1 = reply_cb called.
9087    */
9088   int cb_sequence;
9089   struct guestfs_message_header hdr;
9090   struct guestfs_message_error err;
9091   struct guestfs_sfdisk_l_ret ret;
9092 };
9093
9094 static void sfdisk_l_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9095 {
9096   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9097   struct sfdisk_l_ctx *ctx = (struct sfdisk_l_ctx *) data;
9098
9099   /* This should definitely not happen. */
9100   if (ctx->cb_sequence != 0) {
9101     ctx->cb_sequence = 9999;
9102     error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_l");
9103     return;
9104   }
9105
9106   ml->main_loop_quit (ml, g);
9107
9108   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9109     error (g, "%s: failed to parse reply header", "guestfs_sfdisk_l");
9110     return;
9111   }
9112   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9113     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9114       error (g, "%s: failed to parse reply error", "guestfs_sfdisk_l");
9115       return;
9116     }
9117     goto done;
9118   }
9119   if (!xdr_guestfs_sfdisk_l_ret (xdr, &ctx->ret)) {
9120     error (g, "%s: failed to parse reply", "guestfs_sfdisk_l");
9121     return;
9122   }
9123  done:
9124   ctx->cb_sequence = 1;
9125 }
9126
9127 char *guestfs_sfdisk_l (guestfs_h *g,
9128                 const char *device)
9129 {
9130   struct guestfs_sfdisk_l_args args;
9131   struct sfdisk_l_ctx ctx;
9132   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9133   int serial;
9134
9135   if (check_state (g, "guestfs_sfdisk_l") == -1) return NULL;
9136   guestfs_set_busy (g);
9137
9138   memset (&ctx, 0, sizeof ctx);
9139
9140   args.device = (char *) device;
9141   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_L,
9142         (xdrproc_t) xdr_guestfs_sfdisk_l_args, (char *) &args);
9143   if (serial == -1) {
9144     guestfs_end_busy (g);
9145     return NULL;
9146   }
9147
9148   guestfs__switch_to_receiving (g);
9149   ctx.cb_sequence = 0;
9150   guestfs_set_reply_callback (g, sfdisk_l_reply_cb, &ctx);
9151   (void) ml->main_loop_run (ml, g);
9152   guestfs_set_reply_callback (g, NULL, NULL);
9153   if (ctx.cb_sequence != 1) {
9154     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_l");
9155     guestfs_end_busy (g);
9156     return NULL;
9157   }
9158
9159   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_L, serial) == -1) {
9160     guestfs_end_busy (g);
9161     return NULL;
9162   }
9163
9164   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9165     error (g, "%s", ctx.err.error_message);
9166     free (ctx.err.error_message);
9167     guestfs_end_busy (g);
9168     return NULL;
9169   }
9170
9171   guestfs_end_busy (g);
9172   return ctx.ret.partitions; /* caller will free */
9173 }
9174
9175 struct sfdisk_kernel_geometry_ctx {
9176   /* This flag is set by the callbacks, so we know we've done
9177    * the callbacks as expected, and in the right sequence.
9178    * 0 = not called, 1 = reply_cb called.
9179    */
9180   int cb_sequence;
9181   struct guestfs_message_header hdr;
9182   struct guestfs_message_error err;
9183   struct guestfs_sfdisk_kernel_geometry_ret ret;
9184 };
9185
9186 static void sfdisk_kernel_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9187 {
9188   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9189   struct sfdisk_kernel_geometry_ctx *ctx = (struct sfdisk_kernel_geometry_ctx *) data;
9190
9191   /* This should definitely not happen. */
9192   if (ctx->cb_sequence != 0) {
9193     ctx->cb_sequence = 9999;
9194     error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_kernel_geometry");
9195     return;
9196   }
9197
9198   ml->main_loop_quit (ml, g);
9199
9200   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9201     error (g, "%s: failed to parse reply header", "guestfs_sfdisk_kernel_geometry");
9202     return;
9203   }
9204   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9205     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9206       error (g, "%s: failed to parse reply error", "guestfs_sfdisk_kernel_geometry");
9207       return;
9208     }
9209     goto done;
9210   }
9211   if (!xdr_guestfs_sfdisk_kernel_geometry_ret (xdr, &ctx->ret)) {
9212     error (g, "%s: failed to parse reply", "guestfs_sfdisk_kernel_geometry");
9213     return;
9214   }
9215  done:
9216   ctx->cb_sequence = 1;
9217 }
9218
9219 char *guestfs_sfdisk_kernel_geometry (guestfs_h *g,
9220                 const char *device)
9221 {
9222   struct guestfs_sfdisk_kernel_geometry_args args;
9223   struct sfdisk_kernel_geometry_ctx ctx;
9224   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9225   int serial;
9226
9227   if (check_state (g, "guestfs_sfdisk_kernel_geometry") == -1) return NULL;
9228   guestfs_set_busy (g);
9229
9230   memset (&ctx, 0, sizeof ctx);
9231
9232   args.device = (char *) device;
9233   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY,
9234         (xdrproc_t) xdr_guestfs_sfdisk_kernel_geometry_args, (char *) &args);
9235   if (serial == -1) {
9236     guestfs_end_busy (g);
9237     return NULL;
9238   }
9239
9240   guestfs__switch_to_receiving (g);
9241   ctx.cb_sequence = 0;
9242   guestfs_set_reply_callback (g, sfdisk_kernel_geometry_reply_cb, &ctx);
9243   (void) ml->main_loop_run (ml, g);
9244   guestfs_set_reply_callback (g, NULL, NULL);
9245   if (ctx.cb_sequence != 1) {
9246     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_kernel_geometry");
9247     guestfs_end_busy (g);
9248     return NULL;
9249   }
9250
9251   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY, serial) == -1) {
9252     guestfs_end_busy (g);
9253     return NULL;
9254   }
9255
9256   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9257     error (g, "%s", ctx.err.error_message);
9258     free (ctx.err.error_message);
9259     guestfs_end_busy (g);
9260     return NULL;
9261   }
9262
9263   guestfs_end_busy (g);
9264   return ctx.ret.partitions; /* caller will free */
9265 }
9266
9267 struct sfdisk_disk_geometry_ctx {
9268   /* This flag is set by the callbacks, so we know we've done
9269    * the callbacks as expected, and in the right sequence.
9270    * 0 = not called, 1 = reply_cb called.
9271    */
9272   int cb_sequence;
9273   struct guestfs_message_header hdr;
9274   struct guestfs_message_error err;
9275   struct guestfs_sfdisk_disk_geometry_ret ret;
9276 };
9277
9278 static void sfdisk_disk_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9279 {
9280   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9281   struct sfdisk_disk_geometry_ctx *ctx = (struct sfdisk_disk_geometry_ctx *) data;
9282
9283   /* This should definitely not happen. */
9284   if (ctx->cb_sequence != 0) {
9285     ctx->cb_sequence = 9999;
9286     error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_disk_geometry");
9287     return;
9288   }
9289
9290   ml->main_loop_quit (ml, g);
9291
9292   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9293     error (g, "%s: failed to parse reply header", "guestfs_sfdisk_disk_geometry");
9294     return;
9295   }
9296   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9297     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9298       error (g, "%s: failed to parse reply error", "guestfs_sfdisk_disk_geometry");
9299       return;
9300     }
9301     goto done;
9302   }
9303   if (!xdr_guestfs_sfdisk_disk_geometry_ret (xdr, &ctx->ret)) {
9304     error (g, "%s: failed to parse reply", "guestfs_sfdisk_disk_geometry");
9305     return;
9306   }
9307  done:
9308   ctx->cb_sequence = 1;
9309 }
9310
9311 char *guestfs_sfdisk_disk_geometry (guestfs_h *g,
9312                 const char *device)
9313 {
9314   struct guestfs_sfdisk_disk_geometry_args args;
9315   struct sfdisk_disk_geometry_ctx ctx;
9316   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9317   int serial;
9318
9319   if (check_state (g, "guestfs_sfdisk_disk_geometry") == -1) return NULL;
9320   guestfs_set_busy (g);
9321
9322   memset (&ctx, 0, sizeof ctx);
9323
9324   args.device = (char *) device;
9325   serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_DISK_GEOMETRY,
9326         (xdrproc_t) xdr_guestfs_sfdisk_disk_geometry_args, (char *) &args);
9327   if (serial == -1) {
9328     guestfs_end_busy (g);
9329     return NULL;
9330   }
9331
9332   guestfs__switch_to_receiving (g);
9333   ctx.cb_sequence = 0;
9334   guestfs_set_reply_callback (g, sfdisk_disk_geometry_reply_cb, &ctx);
9335   (void) ml->main_loop_run (ml, g);
9336   guestfs_set_reply_callback (g, NULL, NULL);
9337   if (ctx.cb_sequence != 1) {
9338     error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_disk_geometry");
9339     guestfs_end_busy (g);
9340     return NULL;
9341   }
9342
9343   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_DISK_GEOMETRY, serial) == -1) {
9344     guestfs_end_busy (g);
9345     return NULL;
9346   }
9347
9348   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9349     error (g, "%s", ctx.err.error_message);
9350     free (ctx.err.error_message);
9351     guestfs_end_busy (g);
9352     return NULL;
9353   }
9354
9355   guestfs_end_busy (g);
9356   return ctx.ret.partitions; /* caller will free */
9357 }
9358
9359 struct vg_activate_all_ctx {
9360   /* This flag is set by the callbacks, so we know we've done
9361    * the callbacks as expected, and in the right sequence.
9362    * 0 = not called, 1 = reply_cb called.
9363    */
9364   int cb_sequence;
9365   struct guestfs_message_header hdr;
9366   struct guestfs_message_error err;
9367 };
9368
9369 static void vg_activate_all_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9370 {
9371   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9372   struct vg_activate_all_ctx *ctx = (struct vg_activate_all_ctx *) data;
9373
9374   /* This should definitely not happen. */
9375   if (ctx->cb_sequence != 0) {
9376     ctx->cb_sequence = 9999;
9377     error (g, "%s: internal error: reply callback called twice", "guestfs_vg_activate_all");
9378     return;
9379   }
9380
9381   ml->main_loop_quit (ml, g);
9382
9383   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9384     error (g, "%s: failed to parse reply header", "guestfs_vg_activate_all");
9385     return;
9386   }
9387   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9388     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9389       error (g, "%s: failed to parse reply error", "guestfs_vg_activate_all");
9390       return;
9391     }
9392     goto done;
9393   }
9394  done:
9395   ctx->cb_sequence = 1;
9396 }
9397
9398 int guestfs_vg_activate_all (guestfs_h *g,
9399                 int activate)
9400 {
9401   struct guestfs_vg_activate_all_args args;
9402   struct vg_activate_all_ctx ctx;
9403   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9404   int serial;
9405
9406   if (check_state (g, "guestfs_vg_activate_all") == -1) return -1;
9407   guestfs_set_busy (g);
9408
9409   memset (&ctx, 0, sizeof ctx);
9410
9411   args.activate = activate;
9412   serial = guestfs__send_sync (g, GUESTFS_PROC_VG_ACTIVATE_ALL,
9413         (xdrproc_t) xdr_guestfs_vg_activate_all_args, (char *) &args);
9414   if (serial == -1) {
9415     guestfs_end_busy (g);
9416     return -1;
9417   }
9418
9419   guestfs__switch_to_receiving (g);
9420   ctx.cb_sequence = 0;
9421   guestfs_set_reply_callback (g, vg_activate_all_reply_cb, &ctx);
9422   (void) ml->main_loop_run (ml, g);
9423   guestfs_set_reply_callback (g, NULL, NULL);
9424   if (ctx.cb_sequence != 1) {
9425     error (g, "%s reply failed, see earlier error messages", "guestfs_vg_activate_all");
9426     guestfs_end_busy (g);
9427     return -1;
9428   }
9429
9430   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VG_ACTIVATE_ALL, serial) == -1) {
9431     guestfs_end_busy (g);
9432     return -1;
9433   }
9434
9435   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9436     error (g, "%s", ctx.err.error_message);
9437     free (ctx.err.error_message);
9438     guestfs_end_busy (g);
9439     return -1;
9440   }
9441
9442   guestfs_end_busy (g);
9443   return 0;
9444 }
9445
9446 struct vg_activate_ctx {
9447   /* This flag is set by the callbacks, so we know we've done
9448    * the callbacks as expected, and in the right sequence.
9449    * 0 = not called, 1 = reply_cb called.
9450    */
9451   int cb_sequence;
9452   struct guestfs_message_header hdr;
9453   struct guestfs_message_error err;
9454 };
9455
9456 static void vg_activate_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9457 {
9458   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9459   struct vg_activate_ctx *ctx = (struct vg_activate_ctx *) data;
9460
9461   /* This should definitely not happen. */
9462   if (ctx->cb_sequence != 0) {
9463     ctx->cb_sequence = 9999;
9464     error (g, "%s: internal error: reply callback called twice", "guestfs_vg_activate");
9465     return;
9466   }
9467
9468   ml->main_loop_quit (ml, g);
9469
9470   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9471     error (g, "%s: failed to parse reply header", "guestfs_vg_activate");
9472     return;
9473   }
9474   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9475     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9476       error (g, "%s: failed to parse reply error", "guestfs_vg_activate");
9477       return;
9478     }
9479     goto done;
9480   }
9481  done:
9482   ctx->cb_sequence = 1;
9483 }
9484
9485 int guestfs_vg_activate (guestfs_h *g,
9486                 int activate,
9487                 char * const* const volgroups)
9488 {
9489   struct guestfs_vg_activate_args args;
9490   struct vg_activate_ctx ctx;
9491   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9492   int serial;
9493
9494   if (check_state (g, "guestfs_vg_activate") == -1) return -1;
9495   guestfs_set_busy (g);
9496
9497   memset (&ctx, 0, sizeof ctx);
9498
9499   args.activate = activate;
9500   args.volgroups.volgroups_val = (char **) volgroups;
9501   for (args.volgroups.volgroups_len = 0; volgroups[args.volgroups.volgroups_len]; args.volgroups.volgroups_len++) ;
9502   serial = guestfs__send_sync (g, GUESTFS_PROC_VG_ACTIVATE,
9503         (xdrproc_t) xdr_guestfs_vg_activate_args, (char *) &args);
9504   if (serial == -1) {
9505     guestfs_end_busy (g);
9506     return -1;
9507   }
9508
9509   guestfs__switch_to_receiving (g);
9510   ctx.cb_sequence = 0;
9511   guestfs_set_reply_callback (g, vg_activate_reply_cb, &ctx);
9512   (void) ml->main_loop_run (ml, g);
9513   guestfs_set_reply_callback (g, NULL, NULL);
9514   if (ctx.cb_sequence != 1) {
9515     error (g, "%s reply failed, see earlier error messages", "guestfs_vg_activate");
9516     guestfs_end_busy (g);
9517     return -1;
9518   }
9519
9520   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_VG_ACTIVATE, serial) == -1) {
9521     guestfs_end_busy (g);
9522     return -1;
9523   }
9524
9525   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9526     error (g, "%s", ctx.err.error_message);
9527     free (ctx.err.error_message);
9528     guestfs_end_busy (g);
9529     return -1;
9530   }
9531
9532   guestfs_end_busy (g);
9533   return 0;
9534 }
9535
9536 struct lvresize_ctx {
9537   /* This flag is set by the callbacks, so we know we've done
9538    * the callbacks as expected, and in the right sequence.
9539    * 0 = not called, 1 = reply_cb called.
9540    */
9541   int cb_sequence;
9542   struct guestfs_message_header hdr;
9543   struct guestfs_message_error err;
9544 };
9545
9546 static void lvresize_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9547 {
9548   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9549   struct lvresize_ctx *ctx = (struct lvresize_ctx *) data;
9550
9551   /* This should definitely not happen. */
9552   if (ctx->cb_sequence != 0) {
9553     ctx->cb_sequence = 9999;
9554     error (g, "%s: internal error: reply callback called twice", "guestfs_lvresize");
9555     return;
9556   }
9557
9558   ml->main_loop_quit (ml, g);
9559
9560   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9561     error (g, "%s: failed to parse reply header", "guestfs_lvresize");
9562     return;
9563   }
9564   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9565     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9566       error (g, "%s: failed to parse reply error", "guestfs_lvresize");
9567       return;
9568     }
9569     goto done;
9570   }
9571  done:
9572   ctx->cb_sequence = 1;
9573 }
9574
9575 int guestfs_lvresize (guestfs_h *g,
9576                 const char *device,
9577                 int mbytes)
9578 {
9579   struct guestfs_lvresize_args args;
9580   struct lvresize_ctx ctx;
9581   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9582   int serial;
9583
9584   if (check_state (g, "guestfs_lvresize") == -1) return -1;
9585   guestfs_set_busy (g);
9586
9587   memset (&ctx, 0, sizeof ctx);
9588
9589   args.device = (char *) device;
9590   args.mbytes = mbytes;
9591   serial = guestfs__send_sync (g, GUESTFS_PROC_LVRESIZE,
9592         (xdrproc_t) xdr_guestfs_lvresize_args, (char *) &args);
9593   if (serial == -1) {
9594     guestfs_end_busy (g);
9595     return -1;
9596   }
9597
9598   guestfs__switch_to_receiving (g);
9599   ctx.cb_sequence = 0;
9600   guestfs_set_reply_callback (g, lvresize_reply_cb, &ctx);
9601   (void) ml->main_loop_run (ml, g);
9602   guestfs_set_reply_callback (g, NULL, NULL);
9603   if (ctx.cb_sequence != 1) {
9604     error (g, "%s reply failed, see earlier error messages", "guestfs_lvresize");
9605     guestfs_end_busy (g);
9606     return -1;
9607   }
9608
9609   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVRESIZE, serial) == -1) {
9610     guestfs_end_busy (g);
9611     return -1;
9612   }
9613
9614   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9615     error (g, "%s", ctx.err.error_message);
9616     free (ctx.err.error_message);
9617     guestfs_end_busy (g);
9618     return -1;
9619   }
9620
9621   guestfs_end_busy (g);
9622   return 0;
9623 }
9624
9625 struct resize2fs_ctx {
9626   /* This flag is set by the callbacks, so we know we've done
9627    * the callbacks as expected, and in the right sequence.
9628    * 0 = not called, 1 = reply_cb called.
9629    */
9630   int cb_sequence;
9631   struct guestfs_message_header hdr;
9632   struct guestfs_message_error err;
9633 };
9634
9635 static void resize2fs_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9636 {
9637   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9638   struct resize2fs_ctx *ctx = (struct resize2fs_ctx *) data;
9639
9640   /* This should definitely not happen. */
9641   if (ctx->cb_sequence != 0) {
9642     ctx->cb_sequence = 9999;
9643     error (g, "%s: internal error: reply callback called twice", "guestfs_resize2fs");
9644     return;
9645   }
9646
9647   ml->main_loop_quit (ml, g);
9648
9649   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9650     error (g, "%s: failed to parse reply header", "guestfs_resize2fs");
9651     return;
9652   }
9653   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9654     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9655       error (g, "%s: failed to parse reply error", "guestfs_resize2fs");
9656       return;
9657     }
9658     goto done;
9659   }
9660  done:
9661   ctx->cb_sequence = 1;
9662 }
9663
9664 int guestfs_resize2fs (guestfs_h *g,
9665                 const char *device)
9666 {
9667   struct guestfs_resize2fs_args args;
9668   struct resize2fs_ctx ctx;
9669   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9670   int serial;
9671
9672   if (check_state (g, "guestfs_resize2fs") == -1) return -1;
9673   guestfs_set_busy (g);
9674
9675   memset (&ctx, 0, sizeof ctx);
9676
9677   args.device = (char *) device;
9678   serial = guestfs__send_sync (g, GUESTFS_PROC_RESIZE2FS,
9679         (xdrproc_t) xdr_guestfs_resize2fs_args, (char *) &args);
9680   if (serial == -1) {
9681     guestfs_end_busy (g);
9682     return -1;
9683   }
9684
9685   guestfs__switch_to_receiving (g);
9686   ctx.cb_sequence = 0;
9687   guestfs_set_reply_callback (g, resize2fs_reply_cb, &ctx);
9688   (void) ml->main_loop_run (ml, g);
9689   guestfs_set_reply_callback (g, NULL, NULL);
9690   if (ctx.cb_sequence != 1) {
9691     error (g, "%s reply failed, see earlier error messages", "guestfs_resize2fs");
9692     guestfs_end_busy (g);
9693     return -1;
9694   }
9695
9696   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RESIZE2FS, serial) == -1) {
9697     guestfs_end_busy (g);
9698     return -1;
9699   }
9700
9701   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9702     error (g, "%s", ctx.err.error_message);
9703     free (ctx.err.error_message);
9704     guestfs_end_busy (g);
9705     return -1;
9706   }
9707
9708   guestfs_end_busy (g);
9709   return 0;
9710 }
9711
9712 struct find_ctx {
9713   /* This flag is set by the callbacks, so we know we've done
9714    * the callbacks as expected, and in the right sequence.
9715    * 0 = not called, 1 = reply_cb called.
9716    */
9717   int cb_sequence;
9718   struct guestfs_message_header hdr;
9719   struct guestfs_message_error err;
9720   struct guestfs_find_ret ret;
9721 };
9722
9723 static void find_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9724 {
9725   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9726   struct find_ctx *ctx = (struct find_ctx *) data;
9727
9728   /* This should definitely not happen. */
9729   if (ctx->cb_sequence != 0) {
9730     ctx->cb_sequence = 9999;
9731     error (g, "%s: internal error: reply callback called twice", "guestfs_find");
9732     return;
9733   }
9734
9735   ml->main_loop_quit (ml, g);
9736
9737   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9738     error (g, "%s: failed to parse reply header", "guestfs_find");
9739     return;
9740   }
9741   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9742     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9743       error (g, "%s: failed to parse reply error", "guestfs_find");
9744       return;
9745     }
9746     goto done;
9747   }
9748   if (!xdr_guestfs_find_ret (xdr, &ctx->ret)) {
9749     error (g, "%s: failed to parse reply", "guestfs_find");
9750     return;
9751   }
9752  done:
9753   ctx->cb_sequence = 1;
9754 }
9755
9756 char **guestfs_find (guestfs_h *g,
9757                 const char *directory)
9758 {
9759   struct guestfs_find_args args;
9760   struct find_ctx ctx;
9761   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9762   int serial;
9763
9764   if (check_state (g, "guestfs_find") == -1) return NULL;
9765   guestfs_set_busy (g);
9766
9767   memset (&ctx, 0, sizeof ctx);
9768
9769   args.directory = (char *) directory;
9770   serial = guestfs__send_sync (g, GUESTFS_PROC_FIND,
9771         (xdrproc_t) xdr_guestfs_find_args, (char *) &args);
9772   if (serial == -1) {
9773     guestfs_end_busy (g);
9774     return NULL;
9775   }
9776
9777   guestfs__switch_to_receiving (g);
9778   ctx.cb_sequence = 0;
9779   guestfs_set_reply_callback (g, find_reply_cb, &ctx);
9780   (void) ml->main_loop_run (ml, g);
9781   guestfs_set_reply_callback (g, NULL, NULL);
9782   if (ctx.cb_sequence != 1) {
9783     error (g, "%s reply failed, see earlier error messages", "guestfs_find");
9784     guestfs_end_busy (g);
9785     return NULL;
9786   }
9787
9788   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_FIND, serial) == -1) {
9789     guestfs_end_busy (g);
9790     return NULL;
9791   }
9792
9793   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9794     error (g, "%s", ctx.err.error_message);
9795     free (ctx.err.error_message);
9796     guestfs_end_busy (g);
9797     return NULL;
9798   }
9799
9800   guestfs_end_busy (g);
9801   /* caller will free this, but we need to add a NULL entry */
9802   ctx.ret.names.names_val =
9803     safe_realloc (g, ctx.ret.names.names_val,
9804                   sizeof (char *) * (ctx.ret.names.names_len + 1));
9805   ctx.ret.names.names_val[ctx.ret.names.names_len] = NULL;
9806   return ctx.ret.names.names_val;
9807 }
9808
9809 struct e2fsck_f_ctx {
9810   /* This flag is set by the callbacks, so we know we've done
9811    * the callbacks as expected, and in the right sequence.
9812    * 0 = not called, 1 = reply_cb called.
9813    */
9814   int cb_sequence;
9815   struct guestfs_message_header hdr;
9816   struct guestfs_message_error err;
9817 };
9818
9819 static void e2fsck_f_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9820 {
9821   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9822   struct e2fsck_f_ctx *ctx = (struct e2fsck_f_ctx *) data;
9823
9824   /* This should definitely not happen. */
9825   if (ctx->cb_sequence != 0) {
9826     ctx->cb_sequence = 9999;
9827     error (g, "%s: internal error: reply callback called twice", "guestfs_e2fsck_f");
9828     return;
9829   }
9830
9831   ml->main_loop_quit (ml, g);
9832
9833   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9834     error (g, "%s: failed to parse reply header", "guestfs_e2fsck_f");
9835     return;
9836   }
9837   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9838     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9839       error (g, "%s: failed to parse reply error", "guestfs_e2fsck_f");
9840       return;
9841     }
9842     goto done;
9843   }
9844  done:
9845   ctx->cb_sequence = 1;
9846 }
9847
9848 int guestfs_e2fsck_f (guestfs_h *g,
9849                 const char *device)
9850 {
9851   struct guestfs_e2fsck_f_args args;
9852   struct e2fsck_f_ctx ctx;
9853   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9854   int serial;
9855
9856   if (check_state (g, "guestfs_e2fsck_f") == -1) return -1;
9857   guestfs_set_busy (g);
9858
9859   memset (&ctx, 0, sizeof ctx);
9860
9861   args.device = (char *) device;
9862   serial = guestfs__send_sync (g, GUESTFS_PROC_E2FSCK_F,
9863         (xdrproc_t) xdr_guestfs_e2fsck_f_args, (char *) &args);
9864   if (serial == -1) {
9865     guestfs_end_busy (g);
9866     return -1;
9867   }
9868
9869   guestfs__switch_to_receiving (g);
9870   ctx.cb_sequence = 0;
9871   guestfs_set_reply_callback (g, e2fsck_f_reply_cb, &ctx);
9872   (void) ml->main_loop_run (ml, g);
9873   guestfs_set_reply_callback (g, NULL, NULL);
9874   if (ctx.cb_sequence != 1) {
9875     error (g, "%s reply failed, see earlier error messages", "guestfs_e2fsck_f");
9876     guestfs_end_busy (g);
9877     return -1;
9878   }
9879
9880   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_E2FSCK_F, serial) == -1) {
9881     guestfs_end_busy (g);
9882     return -1;
9883   }
9884
9885   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9886     error (g, "%s", ctx.err.error_message);
9887     free (ctx.err.error_message);
9888     guestfs_end_busy (g);
9889     return -1;
9890   }
9891
9892   guestfs_end_busy (g);
9893   return 0;
9894 }
9895
9896 struct sleep_ctx {
9897   /* This flag is set by the callbacks, so we know we've done
9898    * the callbacks as expected, and in the right sequence.
9899    * 0 = not called, 1 = reply_cb called.
9900    */
9901   int cb_sequence;
9902   struct guestfs_message_header hdr;
9903   struct guestfs_message_error err;
9904 };
9905
9906 static void sleep_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9907 {
9908   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9909   struct sleep_ctx *ctx = (struct sleep_ctx *) data;
9910
9911   /* This should definitely not happen. */
9912   if (ctx->cb_sequence != 0) {
9913     ctx->cb_sequence = 9999;
9914     error (g, "%s: internal error: reply callback called twice", "guestfs_sleep");
9915     return;
9916   }
9917
9918   ml->main_loop_quit (ml, g);
9919
9920   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
9921     error (g, "%s: failed to parse reply header", "guestfs_sleep");
9922     return;
9923   }
9924   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
9925     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
9926       error (g, "%s: failed to parse reply error", "guestfs_sleep");
9927       return;
9928     }
9929     goto done;
9930   }
9931  done:
9932   ctx->cb_sequence = 1;
9933 }
9934
9935 int guestfs_sleep (guestfs_h *g,
9936                 int secs)
9937 {
9938   struct guestfs_sleep_args args;
9939   struct sleep_ctx ctx;
9940   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9941   int serial;
9942
9943   if (check_state (g, "guestfs_sleep") == -1) return -1;
9944   guestfs_set_busy (g);
9945
9946   memset (&ctx, 0, sizeof ctx);
9947
9948   args.secs = secs;
9949   serial = guestfs__send_sync (g, GUESTFS_PROC_SLEEP,
9950         (xdrproc_t) xdr_guestfs_sleep_args, (char *) &args);
9951   if (serial == -1) {
9952     guestfs_end_busy (g);
9953     return -1;
9954   }
9955
9956   guestfs__switch_to_receiving (g);
9957   ctx.cb_sequence = 0;
9958   guestfs_set_reply_callback (g, sleep_reply_cb, &ctx);
9959   (void) ml->main_loop_run (ml, g);
9960   guestfs_set_reply_callback (g, NULL, NULL);
9961   if (ctx.cb_sequence != 1) {
9962     error (g, "%s reply failed, see earlier error messages", "guestfs_sleep");
9963     guestfs_end_busy (g);
9964     return -1;
9965   }
9966
9967   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SLEEP, serial) == -1) {
9968     guestfs_end_busy (g);
9969     return -1;
9970   }
9971
9972   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
9973     error (g, "%s", ctx.err.error_message);
9974     free (ctx.err.error_message);
9975     guestfs_end_busy (g);
9976     return -1;
9977   }
9978
9979   guestfs_end_busy (g);
9980   return 0;
9981 }
9982
9983 struct ntfs_3g_probe_ctx {
9984   /* This flag is set by the callbacks, so we know we've done
9985    * the callbacks as expected, and in the right sequence.
9986    * 0 = not called, 1 = reply_cb called.
9987    */
9988   int cb_sequence;
9989   struct guestfs_message_header hdr;
9990   struct guestfs_message_error err;
9991   struct guestfs_ntfs_3g_probe_ret ret;
9992 };
9993
9994 static void ntfs_3g_probe_reply_cb (guestfs_h *g, void *data, XDR *xdr)
9995 {
9996   guestfs_main_loop *ml = guestfs_get_main_loop (g);
9997   struct ntfs_3g_probe_ctx *ctx = (struct ntfs_3g_probe_ctx *) data;
9998
9999   /* This should definitely not happen. */
10000   if (ctx->cb_sequence != 0) {
10001     ctx->cb_sequence = 9999;
10002     error (g, "%s: internal error: reply callback called twice", "guestfs_ntfs_3g_probe");
10003     return;
10004   }
10005
10006   ml->main_loop_quit (ml, g);
10007
10008   if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) {
10009     error (g, "%s: failed to parse reply header", "guestfs_ntfs_3g_probe");
10010     return;
10011   }
10012   if (ctx->hdr.status == GUESTFS_STATUS_ERROR) {
10013     if (!xdr_guestfs_message_error (xdr, &ctx->err)) {
10014       error (g, "%s: failed to parse reply error", "guestfs_ntfs_3g_probe");
10015       return;
10016     }
10017     goto done;
10018   }
10019   if (!xdr_guestfs_ntfs_3g_probe_ret (xdr, &ctx->ret)) {
10020     error (g, "%s: failed to parse reply", "guestfs_ntfs_3g_probe");
10021     return;
10022   }
10023  done:
10024   ctx->cb_sequence = 1;
10025 }
10026
10027 int guestfs_ntfs_3g_probe (guestfs_h *g,
10028                 int rw,
10029                 const char *device)
10030 {
10031   struct guestfs_ntfs_3g_probe_args args;
10032   struct ntfs_3g_probe_ctx ctx;
10033   guestfs_main_loop *ml = guestfs_get_main_loop (g);
10034   int serial;
10035
10036   if (check_state (g, "guestfs_ntfs_3g_probe") == -1) return -1;
10037   guestfs_set_busy (g);
10038
10039   memset (&ctx, 0, sizeof ctx);
10040
10041   args.rw = rw;
10042   args.device = (char *) device;
10043   serial = guestfs__send_sync (g, GUESTFS_PROC_NTFS_3G_PROBE,
10044         (xdrproc_t) xdr_guestfs_ntfs_3g_probe_args, (char *) &args);
10045   if (serial == -1) {
10046     guestfs_end_busy (g);
10047     return -1;
10048   }
10049
10050   guestfs__switch_to_receiving (g);
10051   ctx.cb_sequence = 0;
10052   guestfs_set_reply_callback (g, ntfs_3g_probe_reply_cb, &ctx);
10053   (void) ml->main_loop_run (ml, g);
10054   guestfs_set_reply_callback (g, NULL, NULL);
10055   if (ctx.cb_sequence != 1) {
10056     error (g, "%s reply failed, see earlier error messages", "guestfs_ntfs_3g_probe");
10057     guestfs_end_busy (g);
10058     return -1;
10059   }
10060
10061   if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_NTFS_3G_PROBE, serial) == -1) {
10062     guestfs_end_busy (g);
10063     return -1;
10064   }
10065
10066   if (ctx.hdr.status == GUESTFS_STATUS_ERROR) {
10067     error (g, "%s", ctx.err.error_message);
10068     free (ctx.err.error_message);
10069     guestfs_end_busy (g);
10070     return -1;
10071   }
10072
10073   guestfs_end_busy (g);
10074   return ctx.ret.status;
10075 }
10076