diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/guestfs-actions.c | 176 | ||||
-rw-r--r-- | src/guestfs-actions.h | 2 | ||||
-rw-r--r-- | src/guestfs_protocol.c | 22 | ||||
-rw-r--r-- | src/guestfs_protocol.h | 19 | ||||
-rw-r--r-- | src/guestfs_protocol.x | 11 |
5 files changed, 229 insertions, 1 deletions
diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index 41d873f9..f7f0fb93 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -9533,3 +9533,179 @@ int guestfs_vg_activate (guestfs_h *g, return 0; } +struct lvresize_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 lvresize_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct lvresize_ctx *ctx = (struct lvresize_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_lvresize"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_lvresize"); + 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_lvresize"); + return; + } + goto done; + } + done: + ctx->cb_sequence = 1; +} + +int guestfs_lvresize (guestfs_h *g, + const char *device, + int mbytes) +{ + struct guestfs_lvresize_args args; + struct lvresize_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_lvresize") == -1) return -1; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + args.mbytes = mbytes; + serial = guestfs__send_sync (g, GUESTFS_PROC_LVRESIZE, + (xdrproc_t) xdr_guestfs_lvresize_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, lvresize_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_lvresize"); + guestfs_end_busy (g); + return -1; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_LVRESIZE, 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 resize2fs_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 resize2fs_reply_cb (guestfs_h *g, void *data, XDR *xdr) +{ + guestfs_main_loop *ml = guestfs_get_main_loop (g); + struct resize2fs_ctx *ctx = (struct resize2fs_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_resize2fs"); + return; + } + + ml->main_loop_quit (ml, g); + + if (!xdr_guestfs_message_header (xdr, &ctx->hdr)) { + error (g, "%s: failed to parse reply header", "guestfs_resize2fs"); + 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_resize2fs"); + return; + } + goto done; + } + done: + ctx->cb_sequence = 1; +} + +int guestfs_resize2fs (guestfs_h *g, + const char *device) +{ + struct guestfs_resize2fs_args args; + struct resize2fs_ctx ctx; + guestfs_main_loop *ml = guestfs_get_main_loop (g); + int serial; + + if (check_state (g, "guestfs_resize2fs") == -1) return -1; + guestfs_set_busy (g); + + memset (&ctx, 0, sizeof ctx); + + args.device = (char *) device; + serial = guestfs__send_sync (g, GUESTFS_PROC_RESIZE2FS, + (xdrproc_t) xdr_guestfs_resize2fs_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, resize2fs_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_resize2fs"); + guestfs_end_busy (g); + return -1; + } + + if (check_reply_header (g, &ctx.hdr, GUESTFS_PROC_RESIZE2FS, 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; +} + diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index 3c760f23..0e9be17e 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -147,3 +147,5 @@ extern char *guestfs_sfdisk_kernel_geometry (guestfs_h *handle, const char *devi extern char *guestfs_sfdisk_disk_geometry (guestfs_h *handle, const char *device); extern int guestfs_vg_activate_all (guestfs_h *handle, int activate); extern int guestfs_vg_activate (guestfs_h *handle, int activate, char * const* const volgroups); +extern int guestfs_lvresize (guestfs_h *handle, const char *device, int mbytes); +extern int guestfs_resize2fs (guestfs_h *handle, const char *device); diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index 0a3fddc0..c352cb40 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -1786,6 +1786,28 @@ xdr_guestfs_vg_activate_args (XDR *xdrs, guestfs_vg_activate_args *objp) } bool_t +xdr_guestfs_lvresize_args (XDR *xdrs, guestfs_lvresize_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + if (!xdr_int (xdrs, &objp->mbytes)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_resize2fs_args (XDR *xdrs, guestfs_resize2fs_args *objp) +{ + register int32_t *buf; + + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp) { register int32_t *buf; diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 25ed3529..a34395a6 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -901,6 +901,17 @@ struct guestfs_vg_activate_args { }; typedef struct guestfs_vg_activate_args guestfs_vg_activate_args; +struct guestfs_lvresize_args { + char *device; + int mbytes; +}; +typedef struct guestfs_lvresize_args guestfs_lvresize_args; + +struct guestfs_resize2fs_args { + char *device; +}; +typedef struct guestfs_resize2fs_args guestfs_resize2fs_args; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -1006,7 +1017,9 @@ enum guestfs_procedure { GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102, GUESTFS_PROC_VG_ACTIVATE_ALL = 103, GUESTFS_PROC_VG_ACTIVATE = 104, - GUESTFS_PROC_NR_PROCS = 104 + 1, + GUESTFS_PROC_LVRESIZE = 105, + GUESTFS_PROC_RESIZE2FS = 106, + GUESTFS_PROC_NR_PROCS = 106 + 1, }; typedef enum guestfs_procedure guestfs_procedure; #define GUESTFS_MESSAGE_MAX 4194304 @@ -1199,6 +1212,8 @@ extern bool_t xdr_guestfs_sfdisk_disk_geometry_args (XDR *, guestfs_sfdisk_disk extern bool_t xdr_guestfs_sfdisk_disk_geometry_ret (XDR *, guestfs_sfdisk_disk_geometry_ret*); extern bool_t xdr_guestfs_vg_activate_all_args (XDR *, guestfs_vg_activate_all_args*); extern bool_t xdr_guestfs_vg_activate_args (XDR *, guestfs_vg_activate_args*); +extern bool_t xdr_guestfs_lvresize_args (XDR *, guestfs_lvresize_args*); +extern bool_t xdr_guestfs_resize2fs_args (XDR *, guestfs_resize2fs_args*); extern bool_t xdr_guestfs_procedure (XDR *, guestfs_procedure*); extern bool_t xdr_guestfs_message_direction (XDR *, guestfs_message_direction*); extern bool_t xdr_guestfs_message_status (XDR *, guestfs_message_status*); @@ -1350,6 +1365,8 @@ extern bool_t xdr_guestfs_sfdisk_disk_geometry_args (); extern bool_t xdr_guestfs_sfdisk_disk_geometry_ret (); extern bool_t xdr_guestfs_vg_activate_all_args (); extern bool_t xdr_guestfs_vg_activate_args (); +extern bool_t xdr_guestfs_lvresize_args (); +extern bool_t xdr_guestfs_resize2fs_args (); extern bool_t xdr_guestfs_procedure (); extern bool_t xdr_guestfs_message_direction (); extern bool_t xdr_guestfs_message_status (); diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index 38bb8ea9..6090810c 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -698,6 +698,15 @@ struct guestfs_vg_activate_args { str volgroups<>; }; +struct guestfs_lvresize_args { + string device<>; + int mbytes; +}; + +struct guestfs_resize2fs_args { + string device<>; +}; + enum guestfs_procedure { GUESTFS_PROC_MOUNT = 1, GUESTFS_PROC_SYNC = 2, @@ -803,6 +812,8 @@ enum guestfs_procedure { GUESTFS_PROC_SFDISK_DISK_GEOMETRY = 102, GUESTFS_PROC_VG_ACTIVATE_ALL = 103, GUESTFS_PROC_VG_ACTIVATE = 104, + GUESTFS_PROC_LVRESIZE = 105, + GUESTFS_PROC_RESIZE2FS = 106, GUESTFS_PROC_NR_PROCS }; |