diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2009-05-15 14:01:28 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2009-05-15 14:52:34 +0100 |
commit | 5cd39c83e23eb300d1bdfa806902a31b409ff420 (patch) | |
tree | a47e2bf9afc16cb9404ae996f512a9d3f22e553b /src/guestfs-actions.c | |
parent | b8e5f51c79f539a740827506cc9da3ffcb6c87f8 (diff) | |
download | libguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.tar.gz libguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.tar.xz libguestfs-5cd39c83e23eb300d1bdfa806902a31b409ff420.zip |
Add: pvresize, sfdisk-N, sfdisk-l, sfdisk-kernel-geomtry, sfdisk-disk-geometry commands. Pass --no-reread flag to sfdisk.
Diffstat (limited to 'src/guestfs-actions.c')
-rw-r--r-- | src/guestfs-actions.c | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index d27ef012..49e8961d 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -8896,3 +8896,463 @@ int guestfs_zerofree (guestfs_h *g, return 0; } +struct pvresize_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void pvresize_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct pvresize_ctx *ctx = (struct pvresize_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_pvresize"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_pvresize"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_pvresize"); + return; + } + goto done; + } + done: + ctx->cb_sequence = 1; +} + +int guestfs_pvresize (guestfs_h *g, + const char *device) +{ + struct guestfs_pvresize_args args; + struct pvresize_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_pvresize") == -1) return -1; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + serial = guestfs__send_sync (g, GUESTFS_PROC_PVRESIZE, + (xdrproc_t) xdr_guestfs_pvresize_args, (char *) &args); + if (serial == -1) { + guestfs_end_busy (g); + return -1; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, pvresize_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_pvresize"); + guestfs_end_busy (g); + return -1; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_PVRESIZE, serial) == -1) { + guestfs_end_busy (g); + return -1; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + free (ctx.err.error_message); + guestfs_end_busy (g); + return -1; + } + + guestfs_end_busy (g); + return 0; +} + +struct sfdisk_N_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; +}; + +static void sfdisk_N_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct sfdisk_N_ctx *ctx = (struct sfdisk_N_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_N"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_sfdisk_N"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_sfdisk_N"); + return; + } + goto done; + } + done: + ctx->cb_sequence = 1; +} + +int guestfs_sfdisk_N (guestfs_h *g, + const char *device, + int n, + int cyls, + int heads, + int sectors, + const char *line) +{ + struct guestfs_sfdisk_N_args args; + struct sfdisk_N_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_sfdisk_N") == -1) return -1; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + args.n = n; + args.cyls = cyls; + args.heads = heads; + args.sectors = sectors; + args.line = (char *) line; + serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_N, + (xdrproc_t) xdr_guestfs_sfdisk_N_args, (char *) &args); + if (serial == -1) { + guestfs_end_busy (g); + return -1; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, sfdisk_N_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_N"); + guestfs_end_busy (g); + return -1; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_N, serial) == -1) { + guestfs_end_busy (g); + return -1; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + free (ctx.err.error_message); + guestfs_end_busy (g); + return -1; + } + + guestfs_end_busy (g); + return 0; +} + +struct sfdisk_l_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_sfdisk_l_ret ret; +}; + +static void sfdisk_l_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct sfdisk_l_ctx *ctx = (struct sfdisk_l_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_l"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_sfdisk_l"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_sfdisk_l"); + return; + } + goto done; + } + if (!xdr_guestfs_sfdisk_l_ret (xdr, &ctx->ret)) { + error (g, "%s: failed to parse reply", "guestfs_sfdisk_l"); + return; + } + done: + ctx->cb_sequence = 1; +} + +char *guestfs_sfdisk_l (guestfs_h *g, + const char *device) +{ + struct guestfs_sfdisk_l_args args; + struct sfdisk_l_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_sfdisk_l") == -1) return NULL; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_L, + (xdrproc_t) xdr_guestfs_sfdisk_l_args, (char *) &args); + if (serial == -1) { + guestfs_end_busy (g); + return NULL; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, sfdisk_l_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_l"); + guestfs_end_busy (g); + return NULL; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_L, serial) == -1) { + guestfs_end_busy (g); + return NULL; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + free (ctx.err.error_message); + guestfs_end_busy (g); + return NULL; + } + + guestfs_end_busy (g); + return ctx.ret.partitions; /* caller will free */ +} + +struct sfdisk_kernel_geometry_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_sfdisk_kernel_geometry_ret ret; +}; + +static void sfdisk_kernel_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct sfdisk_kernel_geometry_ctx *ctx = (struct sfdisk_kernel_geometry_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_kernel_geometry"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_sfdisk_kernel_geometry"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_sfdisk_kernel_geometry"); + return; + } + goto done; + } + if (!xdr_guestfs_sfdisk_kernel_geometry_ret (xdr, &ctx->ret)) { + error (g, "%s: failed to parse reply", "guestfs_sfdisk_kernel_geometry"); + return; + } + done: + ctx->cb_sequence = 1; +} + +char *guestfs_sfdisk_kernel_geometry (guestfs_h *g, + const char *device) +{ + struct guestfs_sfdisk_kernel_geometry_args args; + struct sfdisk_kernel_geometry_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_sfdisk_kernel_geometry") == -1) return NULL; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY, + (xdrproc_t) xdr_guestfs_sfdisk_kernel_geometry_args, (char *) &args); + if (serial == -1) { + guestfs_end_busy (g); + return NULL; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, sfdisk_kernel_geometry_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_kernel_geometry"); + guestfs_end_busy (g); + return NULL; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_KERNEL_GEOMETRY, serial) == -1) { + guestfs_end_busy (g); + return NULL; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + free (ctx.err.error_message); + guestfs_end_busy (g); + return NULL; + } + + guestfs_end_busy (g); + return ctx.ret.partitions; /* caller will free */ +} + +struct sfdisk_disk_geometry_ctx { + /* This flag is set by the callbacks, so we know we've done + * the callbacks as expected, and in the right sequence. + * 0 = not called, 1 = reply_cb called. + */ + int cb_sequence; + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_sfdisk_disk_geometry_ret ret; +}; + +static void sfdisk_disk_geometry_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct sfdisk_disk_geometry_ctx *ctx = (struct sfdisk_disk_geometry_ctx *) data; + + /* This should definitely not happen. */ + if (ctx->cb_sequence != 0) { + ctx->cb_sequence = 9999; + error (g, "%s: internal error: reply callback called twice", "guestfs_sfdisk_disk_geometry"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_sfdisk_disk_geometry"); + return; + } + if (ctx->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &ctx->err)) { + error (g, "%s: failed to parse reply error", "guestfs_sfdisk_disk_geometry"); + return; + } + goto done; + } + if (!xdr_guestfs_sfdisk_disk_geometry_ret (xdr, &ctx->ret)) { + error (g, "%s: failed to parse reply", "guestfs_sfdisk_disk_geometry"); + return; + } + done: + ctx->cb_sequence = 1; +} + +char *guestfs_sfdisk_disk_geometry (guestfs_h *g, + const char *device) +{ + struct guestfs_sfdisk_disk_geometry_args args; + struct sfdisk_disk_geometry_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_sfdisk_disk_geometry") == -1) return NULL; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + serial = guestfs__send_sync (g, GUESTFS_PROC_SFDISK_DISK_GEOMETRY, + (xdrproc_t) xdr_guestfs_sfdisk_disk_geometry_args, (char *) &args); + if (serial == -1) { + guestfs_end_busy (g); + return NULL; + } + + guestfs__switch_to_receiving (g); + ctx.cb_sequence = 0; + guestfs_set_reply_callback (g, sfdisk_disk_geometry_reply_cb, &ctx); + (void) ml->main_loop_run (ml, g); + guestfs_set_reply_callback (g, NULL, NULL); + if (ctx.cb_sequence != 1) { + error (g, "%s reply failed, see earlier error messages", "guestfs_sfdisk_disk_geometry"); + guestfs_end_busy (g); + return NULL; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_SFDISK_DISK_GEOMETRY, serial) == -1) { + guestfs_end_busy (g); + return NULL; + } + + if (ctx.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", ctx.err.error_message); + free (ctx.err.error_message); + guestfs_end_busy (g); + return NULL; + } + + guestfs_end_busy (g); + return ctx.ret.partitions; /* caller will free */ +} + |