From: Richard Jones Date: Tue, 7 Apr 2009 09:25:46 +0000 (+0100) Subject: Implement simple lvs/vgs/pvs commands. X-Git-Tag: 0.4~3 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=6085137e65cb63aaf725207f2929a571d1149420 Implement simple lvs/vgs/pvs commands. --- diff --git a/daemon/actions.h b/daemon/actions.h index 194986f..02fe55e 100644 --- a/daemon/actions.h +++ b/daemon/actions.h @@ -29,6 +29,9 @@ extern char *do_ll (const char *directory); extern char **do_ls (const char *directory); extern char **do_list_devices (); extern char **do_list_partitions (); +extern char **do_pvs (); +extern char **do_vgs (); +extern char **do_lvs (); extern guestfs_lvm_int_pv_list *do_pvs_full (); extern guestfs_lvm_int_vg_list *do_vgs_full (); extern guestfs_lvm_int_lv_list *do_lvs_full (); diff --git a/daemon/lvm.c b/daemon/lvm.c index 43f5cd1..bc38547 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -31,6 +31,121 @@ * of writing it hasn't progressed very far. */ +static char ** +convert_lvm_output (char *out, char *prefix) +{ + char *p, *pend; + char **r = NULL; + int size = 0, alloc = 0; + char buf[256]; + char *str; + + p = out; + while (p) { + pend = strchr (p, '\n'); /* Get the next line of output. */ + if (pend) { + *pend = '\0'; + pend++; + } + + while (*p && isspace (*p)) /* Skip any leading whitespace. */ + p++; + + if (!*p) { /* Empty line? Skip it. */ + p = pend; + continue; + } + + /* Prefix? */ + if (prefix) { + snprintf (buf, sizeof buf, "%s%s", prefix, p); + str = buf; + } else + str = p; + + if (add_string (&r, &size, &alloc, str) == -1) { + free (out); + return NULL; + } + + p = pend; + } + + free (out); + + if (add_string (&r, &size, &alloc, NULL) == -1) + return NULL; + + sort_strings (r, size-1); + return r; +} + +char ** +do_pvs (void) +{ + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "pvs", "-o", "pv_name", "--noheadings", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, NULL); +} + +char ** +do_vgs (void) +{ + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "vgs", "-o", "vg_name", "--noheadings", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, NULL); +} + +char ** +do_lvs (void) +{ + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "lvs", + "-o", "vg_name,lv_name", "--noheadings", + "--separator", "/", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, "/dev/"); +} + +/* These were so complex to implement that I ended up auto-generating + * the code. That code is in stubs.c, and it is generated as usual + * by generator.ml. + */ guestfs_lvm_int_pv_list * do_pvs_full (void) { diff --git a/daemon/stubs.c b/daemon/stubs.c index 63ca770..06a8600 100644 --- a/daemon/stubs.c +++ b/daemon/stubs.c @@ -199,6 +199,54 @@ static void list_partitions_stub (XDR *xdr_in) free_strings (r); } +static void pvs_stub (XDR *xdr_in) +{ + char **r; + + r = do_pvs (); + if (r == NULL) + /* do_pvs has already called reply_with_error, so just return */ + return; + + struct guestfs_pvs_ret ret; + ret.physvols.physvols_len = count_strings (r); + ret.physvols.physvols_val = r; + reply ((xdrproc_t) &xdr_guestfs_pvs_ret, (char *) &ret); + free_strings (r); +} + +static void vgs_stub (XDR *xdr_in) +{ + char **r; + + r = do_vgs (); + if (r == NULL) + /* do_vgs has already called reply_with_error, so just return */ + return; + + struct guestfs_vgs_ret ret; + ret.volgroups.volgroups_len = count_strings (r); + ret.volgroups.volgroups_val = r; + reply ((xdrproc_t) &xdr_guestfs_vgs_ret, (char *) &ret); + free_strings (r); +} + +static void lvs_stub (XDR *xdr_in) +{ + char **r; + + r = do_lvs (); + if (r == NULL) + /* do_lvs has already called reply_with_error, so just return */ + return; + + struct guestfs_lvs_ret ret; + ret.logvols.logvols_len = count_strings (r); + ret.logvols.logvols_val = r; + reply ((xdrproc_t) &xdr_guestfs_lvs_ret, (char *) &ret); + free_strings (r); +} + static void pvs_full_stub (XDR *xdr_in) { guestfs_lvm_int_pv_list *r; @@ -271,6 +319,15 @@ void dispatch_incoming_message (XDR *xdr_in) case GUESTFS_PROC_LIST_PARTITIONS: list_partitions_stub (xdr_in); break; + case GUESTFS_PROC_PVS: + pvs_stub (xdr_in); + break; + case GUESTFS_PROC_VGS: + vgs_stub (xdr_in); + break; + case GUESTFS_PROC_LVS: + lvs_stub (xdr_in); + break; case GUESTFS_PROC_PVS_FULL: pvs_full_stub (xdr_in); break; diff --git a/fish/cmds.c b/fish/cmds.c index dc951e3..1035b67 100644 --- a/fish/cmds.c +++ b/fish/cmds.c @@ -36,11 +36,14 @@ void list_commands (void) printf ("%-20s %s\n", "list-partitions", "list the partitions"); printf ("%-20s %s\n", "ll", "list the files in a directory (long format)"); printf ("%-20s %s\n", "ls", "list the files in a directory"); + printf ("%-20s %s\n", "lvs", "list the LVM logical volumes (LVs)"); printf ("%-20s %s\n", "lvs-full", "list the LVM logical volumes (LVs)"); printf ("%-20s %s\n", "mount", "mount a guest disk at a position in the filesystem"); + printf ("%-20s %s\n", "pvs", "list the LVM physical volumes (PVs)"); printf ("%-20s %s\n", "pvs-full", "list the LVM physical volumes (PVs)"); printf ("%-20s %s\n", "sync", "sync disks, writes are flushed through to the disk image"); printf ("%-20s %s\n", "touch", "update file timestamps or create a new file"); + printf ("%-20s %s\n", "vgs", "list the LVM volume groups (VGs)"); printf ("%-20s %s\n", "vgs-full", "list the LVM volume groups (VGs)"); printf (" Use -h / help to show detailed help for a command.\n"); } @@ -71,14 +74,23 @@ void display_command (const char *cmd) if (strcasecmp (cmd, "list_partitions") == 0 || strcasecmp (cmd, "list-partitions") == 0) pod2text ("list-partitions - list the partitions", " list-partitions\n\nList all the partitions detected on all block devices.\n\nThe full partition device names are returned, eg. C\n\nThis does not return logical volumes. For that you will need to\ncall C."); else + if (strcasecmp (cmd, "pvs") == 0) + pod2text ("pvs - list the LVM physical volumes (PVs)", " pvs\n\nList all the physical volumes detected. This is the equivalent\nof the L command.\n\nThis returns a list of just the device names that contain\nPVs (eg. C).\n\nSee also C."); + else + if (strcasecmp (cmd, "vgs") == 0) + pod2text ("vgs - list the LVM volume groups (VGs)", " vgs\n\nList all the volumes groups detected. This is the equivalent\nof the L command.\n\nThis returns a list of just the volume group names that were\ndetected (eg. C).\n\nSee also C."); + else + if (strcasecmp (cmd, "lvs") == 0) + pod2text ("lvs - list the LVM logical volumes (LVs)", " lvs\n\nList all the logical volumes detected. This is the equivalent\nof the L command.\n\nThis returns a list of the logical volume device names\n(eg. C).\n\nSee also C."); + else if (strcasecmp (cmd, "pvs_full") == 0 || strcasecmp (cmd, "pvs-full") == 0) - pod2text ("pvs-full - list the LVM physical volumes (PVs)", " pvs-full\n\nList all the physical volumes detected. This is the equivalent\nof the L command."); + pod2text ("pvs-full - list the LVM physical volumes (PVs)", " pvs-full\n\nList all the physical volumes detected. This is the equivalent\nof the L command. The \"full\" version includes all fields."); else if (strcasecmp (cmd, "vgs_full") == 0 || strcasecmp (cmd, "vgs-full") == 0) - pod2text ("vgs-full - list the LVM volume groups (VGs)", " vgs-full\n\nList all the volumes groups detected. This is the equivalent\nof the L command."); + pod2text ("vgs-full - list the LVM volume groups (VGs)", " vgs-full\n\nList all the volumes groups detected. This is the equivalent\nof the L command. The \"full\" version includes all fields."); else if (strcasecmp (cmd, "lvs_full") == 0 || strcasecmp (cmd, "lvs-full") == 0) - pod2text ("lvs-full - list the LVM logical volumes (LVs)", " lvs-full\n\nList all the logical volumes detected. This is the equivalent\nof the L command."); + pod2text ("lvs-full - list the LVM logical volumes (LVs)", " lvs-full\n\nList all the logical volumes detected. This is the equivalent\nof the L command. The \"full\" version includes all fields."); else display_builtin_command (cmd); } @@ -308,6 +320,51 @@ static int run_list_partitions (const char *cmd, int argc, char *argv[]) return 0; } +static int run_pvs (const char *cmd, int argc, char *argv[]) +{ + char **r; + if (argc != 0) { + fprintf (stderr, "%s should have 0 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + r = guestfs_pvs (g); + if (r == NULL) return -1; + print_strings (r); + free_strings (r); + return 0; +} + +static int run_vgs (const char *cmd, int argc, char *argv[]) +{ + char **r; + if (argc != 0) { + fprintf (stderr, "%s should have 0 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + r = guestfs_vgs (g); + if (r == NULL) return -1; + print_strings (r); + free_strings (r); + return 0; +} + +static int run_lvs (const char *cmd, int argc, char *argv[]) +{ + char **r; + if (argc != 0) { + fprintf (stderr, "%s should have 0 parameter(s)\n", cmd); + fprintf (stderr, "type 'help %s' for help on %s\n", cmd, cmd); + return -1; + } + r = guestfs_lvs (g); + if (r == NULL) return -1; + print_strings (r); + free_strings (r); + return 0; +} + static int run_pvs_full (const char *cmd, int argc, char *argv[]) { struct guestfs_lvm_pv_list *r; @@ -379,6 +436,15 @@ int run_action (const char *cmd, int argc, char *argv[]) if (strcasecmp (cmd, "list_partitions") == 0 || strcasecmp (cmd, "list-partitions") == 0) return run_list_partitions (cmd, argc, argv); else + if (strcasecmp (cmd, "pvs") == 0) + return run_pvs (cmd, argc, argv); + else + if (strcasecmp (cmd, "vgs") == 0) + return run_vgs (cmd, argc, argv); + else + if (strcasecmp (cmd, "lvs") == 0) + return run_lvs (cmd, argc, argv); + else if (strcasecmp (cmd, "pvs_full") == 0 || strcasecmp (cmd, "pvs-full") == 0) return run_pvs_full (cmd, argc, argv); else diff --git a/guestfs-actions.pod b/guestfs-actions.pod index 1a57ae2..eb3898a 100644 --- a/guestfs-actions.pod +++ b/guestfs-actions.pod @@ -75,12 +75,28 @@ This function returns a NULL-terminated array of strings (like L), or NULL if there was an error. I. +=head2 guestfs_lvs + + char **guestfs_lvs (guestfs_h *handle); + +List all the logical volumes detected. This is the equivalent +of the L command. + +This returns a list of the logical volume device names +(eg. C). + +See also C. + +This function returns a NULL-terminated array of strings +(like L), or NULL if there was an error. +I. + =head2 guestfs_lvs_full struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *handle); List all the logical volumes detected. This is the equivalent -of the L command. +of the L command. The "full" version includes all fields. This function returns a C. I after use.>. @@ -110,12 +126,28 @@ call, in order to improve reliability. This function returns 0 on success or -1 on error. +=head2 guestfs_pvs + + char **guestfs_pvs (guestfs_h *handle); + +List all the physical volumes detected. This is the equivalent +of the L command. + +This returns a list of just the device names that contain +PVs (eg. C). + +See also C. + +This function returns a NULL-terminated array of strings +(like L), or NULL if there was an error. +I. + =head2 guestfs_pvs_full struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *handle); List all the physical volumes detected. This is the equivalent -of the L command. +of the L command. The "full" version includes all fields. This function returns a C. I after use.>. @@ -143,12 +175,28 @@ to create a new zero-length file. This function returns 0 on success or -1 on error. +=head2 guestfs_vgs + + char **guestfs_vgs (guestfs_h *handle); + +List all the volumes groups detected. This is the equivalent +of the L command. + +This returns a list of just the volume group names that were +detected (eg. C). + +See also C. + +This function returns a NULL-terminated array of strings +(like L), or NULL if there was an error. +I. + =head2 guestfs_vgs_full struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *handle); List all the volumes groups detected. This is the equivalent -of the L command. +of the L command. The "full" version includes all fields. This function returns a C. I after use.>. diff --git a/src/generator.ml b/src/generator.ml index 69981f0..d598975 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -135,43 +135,56 @@ The full partition device names are returned, eg. C This does not return logical volumes. For that you will need to call C."); -(* - ("pvs", (RPVList "physvols", P0), 9, [], + ("pvs", (RStringList "physvols", P0), 9, [], "list the LVM physical volumes (PVs)", "\ List all the physical volumes detected. This is the equivalent -of the L command."); +of the L command. - ("vgs", (RVGList "volgroups", P0), 10, [], +This returns a list of just the device names that contain +PVs (eg. C). + +See also C."); + + ("vgs", (RStringList "volgroups", P0), 10, [], "list the LVM volume groups (VGs)", "\ List all the volumes groups detected. This is the equivalent -of the L command."); +of the L command. + +This returns a list of just the volume group names that were +detected (eg. C). + +See also C."); - ("lvs", (RLVList "logvols", P0), 11, [], + ("lvs", (RStringList "logvols", P0), 11, [], "list the LVM logical volumes (LVs)", "\ List all the logical volumes detected. This is the equivalent -of the L command."); -*) +of the L command. + +This returns a list of the logical volume device names +(eg. C). + +See also C."); ("pvs_full", (RPVList "physvols", P0), 12, [], "list the LVM physical volumes (PVs)", "\ List all the physical volumes detected. This is the equivalent -of the L command."); +of the L command. The \"full\" version includes all fields."); ("vgs_full", (RVGList "volgroups", P0), 13, [], "list the LVM volume groups (VGs)", "\ List all the volumes groups detected. This is the equivalent -of the L command."); +of the L command. The \"full\" version includes all fields."); ("lvs_full", (RLVList "logvols", P0), 14, [], "list the LVM logical volumes (LVs)", "\ List all the logical volumes detected. This is the equivalent -of the L command."); +of the L command. The \"full\" version includes all fields."); ] (* Column names and types from LVM PVs/VGs/LVs. *) diff --git a/src/guestfs-actions.c b/src/guestfs-actions.c index e3598eb..3446a2d 100644 --- a/src/guestfs-actions.c +++ b/src/guestfs-actions.c @@ -595,6 +595,225 @@ char **guestfs_list_partitions (guestfs_h *g) return rv.ret.partitions.partitions_val; } +struct pvs_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_pvs_ret ret; +}; + +static void pvs_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct pvs_rv *rv = (struct pvs_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_pvs: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_pvs: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_pvs_ret (xdr, &rv->ret)) { + error (g, "guestfs_pvs: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +char **guestfs_pvs (guestfs_h *g) +{ + struct pvs_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_pvs called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + serial = dispatch (g, GUESTFS_PROC_PVS, NULL, NULL); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = pvs_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_pvs failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_PVS, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this, but we need to add a NULL entry */ + rv.ret.physvols.physvols_val = safe_realloc (g, rv.ret.physvols.physvols_val, rv.ret.physvols.physvols_len + 1); + rv.ret.physvols.physvols_val[rv.ret.physvols.physvols_len] = NULL; + return rv.ret.physvols.physvols_val; +} + +struct vgs_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_vgs_ret ret; +}; + +static void vgs_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct vgs_rv *rv = (struct vgs_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_vgs: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_vgs: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_vgs_ret (xdr, &rv->ret)) { + error (g, "guestfs_vgs: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +char **guestfs_vgs (guestfs_h *g) +{ + struct vgs_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_vgs called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + serial = dispatch (g, GUESTFS_PROC_VGS, NULL, NULL); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = vgs_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_vgs failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_VGS, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this, but we need to add a NULL entry */ + rv.ret.volgroups.volgroups_val = safe_realloc (g, rv.ret.volgroups.volgroups_val, rv.ret.volgroups.volgroups_len + 1); + rv.ret.volgroups.volgroups_val[rv.ret.volgroups.volgroups_len] = NULL; + return rv.ret.volgroups.volgroups_val; +} + +struct lvs_rv { + int cb_done; /* flag to indicate callback was called */ + struct guestfs_message_header hdr; + struct guestfs_message_error err; + struct guestfs_lvs_ret ret; +}; + +static void lvs_cb (guestfs_h *g, void *data, XDR *xdr) +{ + struct lvs_rv *rv = (struct lvs_rv *) data; + + if (!xdr_guestfs_message_header (xdr, &rv->hdr)) { + error (g, "guestfs_lvs: failed to parse reply header"); + return; + } + if (rv->hdr.status == GUESTFS_STATUS_ERROR) { + if (!xdr_guestfs_message_error (xdr, &rv->err)) { + error (g, "guestfs_lvs: failed to parse reply error"); + return; + } + goto done; + } + if (!xdr_guestfs_lvs_ret (xdr, &rv->ret)) { + error (g, "guestfs_lvs: failed to parse reply"); + return; + } + done: + rv->cb_done = 1; + main_loop.main_loop_quit (g); +} + +char **guestfs_lvs (guestfs_h *g) +{ + struct lvs_rv rv; + int serial; + + if (g->state != READY) { + error (g, "guestfs_lvs called from the wrong state, %d != READY", + g->state); + return NULL; + } + + memset (&rv, 0, sizeof rv); + + serial = dispatch (g, GUESTFS_PROC_LVS, NULL, NULL); + if (serial == -1) + return NULL; + + rv.cb_done = 0; + g->reply_cb_internal = lvs_cb; + g->reply_cb_internal_data = &rv; + main_loop.main_loop_run (g); + g->reply_cb_internal = NULL; + g->reply_cb_internal_data = NULL; + if (!rv.cb_done) { + error (g, "guestfs_lvs failed, see earlier error messages"); + return NULL; + } + + if (check_reply_header (g, &rv.hdr, GUESTFS_PROC_LVS, serial) == -1) + return NULL; + + if (rv.hdr.status == GUESTFS_STATUS_ERROR) { + error (g, "%s", rv.err.error); + return NULL; + } + + /* caller will free this, but we need to add a NULL entry */ + rv.ret.logvols.logvols_val = safe_realloc (g, rv.ret.logvols.logvols_val, rv.ret.logvols.logvols_len + 1); + rv.ret.logvols.logvols_val[rv.ret.logvols.logvols_len] = NULL; + return rv.ret.logvols.logvols_val; +} + struct pvs_full_rv { int cb_done; /* flag to indicate callback was called */ struct guestfs_message_header hdr; diff --git a/src/guestfs-actions.h b/src/guestfs-actions.h index 8e73a5e..61eedd3 100644 --- a/src/guestfs-actions.h +++ b/src/guestfs-actions.h @@ -27,6 +27,9 @@ extern char *guestfs_ll (guestfs_h *handle, const char *directory); extern char **guestfs_ls (guestfs_h *handle, const char *directory); extern char **guestfs_list_devices (guestfs_h *handle); extern char **guestfs_list_partitions (guestfs_h *handle); +extern char **guestfs_pvs (guestfs_h *handle); +extern char **guestfs_vgs (guestfs_h *handle); +extern char **guestfs_lvs (guestfs_h *handle); extern struct guestfs_lvm_pv_list *guestfs_pvs_full (guestfs_h *handle); extern struct guestfs_lvm_vg_list *guestfs_vgs_full (guestfs_h *handle); extern struct guestfs_lvm_lv_list *guestfs_lvs_full (guestfs_h *handle); diff --git a/src/guestfs_protocol.c b/src/guestfs_protocol.c index a19d7a1..2a194a7 100644 --- a/src/guestfs_protocol.c +++ b/src/guestfs_protocol.c @@ -279,6 +279,39 @@ xdr_guestfs_list_partitions_ret (XDR *xdrs, guestfs_list_partitions_ret *objp) } bool_t +xdr_guestfs_pvs_ret (XDR *xdrs, guestfs_pvs_ret *objp) +{ + register int32_t *buf; + + if (!xdr_array (xdrs, (char **)&objp->physvols.physvols_val, (u_int *) &objp->physvols.physvols_len, ~0, + sizeof (str), (xdrproc_t) xdr_str)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_vgs_ret (XDR *xdrs, guestfs_vgs_ret *objp) +{ + register int32_t *buf; + + if (!xdr_array (xdrs, (char **)&objp->volgroups.volgroups_val, (u_int *) &objp->volgroups.volgroups_len, ~0, + sizeof (str), (xdrproc_t) xdr_str)) + return FALSE; + return TRUE; +} + +bool_t +xdr_guestfs_lvs_ret (XDR *xdrs, guestfs_lvs_ret *objp) +{ + register int32_t *buf; + + if (!xdr_array (xdrs, (char **)&objp->logvols.logvols_val, (u_int *) &objp->logvols.logvols_len, ~0, + sizeof (str), (xdrproc_t) xdr_str)) + return FALSE; + return TRUE; +} + +bool_t xdr_guestfs_pvs_full_ret (XDR *xdrs, guestfs_pvs_full_ret *objp) { register int32_t *buf; diff --git a/src/guestfs_protocol.h b/src/guestfs_protocol.h index 55faa85..9a7187d 100644 --- a/src/guestfs_protocol.h +++ b/src/guestfs_protocol.h @@ -152,6 +152,30 @@ struct guestfs_list_partitions_ret { }; typedef struct guestfs_list_partitions_ret guestfs_list_partitions_ret; +struct guestfs_pvs_ret { + struct { + u_int physvols_len; + str *physvols_val; + } physvols; +}; +typedef struct guestfs_pvs_ret guestfs_pvs_ret; + +struct guestfs_vgs_ret { + struct { + u_int volgroups_len; + str *volgroups_val; + } volgroups; +}; +typedef struct guestfs_vgs_ret guestfs_vgs_ret; + +struct guestfs_lvs_ret { + struct { + u_int logvols_len; + str *logvols_val; + } logvols; +}; +typedef struct guestfs_lvs_ret guestfs_lvs_ret; + struct guestfs_pvs_full_ret { guestfs_lvm_int_pv_list physvols; }; @@ -176,6 +200,9 @@ enum guestfs_procedure { GUESTFS_PROC_LS = 6, GUESTFS_PROC_LIST_DEVICES = 7, GUESTFS_PROC_LIST_PARTITIONS = 8, + GUESTFS_PROC_PVS = 9, + GUESTFS_PROC_VGS = 10, + GUESTFS_PROC_LVS = 11, GUESTFS_PROC_PVS_FULL = 12, GUESTFS_PROC_VGS_FULL = 13, GUESTFS_PROC_LVS_FULL = 14, @@ -234,6 +261,9 @@ extern bool_t xdr_guestfs_ls_args (XDR *, guestfs_ls_args*); extern bool_t xdr_guestfs_ls_ret (XDR *, guestfs_ls_ret*); extern bool_t xdr_guestfs_list_devices_ret (XDR *, guestfs_list_devices_ret*); extern bool_t xdr_guestfs_list_partitions_ret (XDR *, guestfs_list_partitions_ret*); +extern bool_t xdr_guestfs_pvs_ret (XDR *, guestfs_pvs_ret*); +extern bool_t xdr_guestfs_vgs_ret (XDR *, guestfs_vgs_ret*); +extern bool_t xdr_guestfs_lvs_ret (XDR *, guestfs_lvs_ret*); extern bool_t xdr_guestfs_pvs_full_ret (XDR *, guestfs_pvs_full_ret*); extern bool_t xdr_guestfs_vgs_full_ret (XDR *, guestfs_vgs_full_ret*); extern bool_t xdr_guestfs_lvs_full_ret (XDR *, guestfs_lvs_full_ret*); @@ -261,6 +291,9 @@ extern bool_t xdr_guestfs_ls_args (); extern bool_t xdr_guestfs_ls_ret (); extern bool_t xdr_guestfs_list_devices_ret (); extern bool_t xdr_guestfs_list_partitions_ret (); +extern bool_t xdr_guestfs_pvs_ret (); +extern bool_t xdr_guestfs_vgs_ret (); +extern bool_t xdr_guestfs_lvs_ret (); extern bool_t xdr_guestfs_pvs_full_ret (); extern bool_t xdr_guestfs_vgs_full_ret (); extern bool_t xdr_guestfs_lvs_full_ret (); diff --git a/src/guestfs_protocol.x b/src/guestfs_protocol.x index 9bc556b..b2fe535 100644 --- a/src/guestfs_protocol.x +++ b/src/guestfs_protocol.x @@ -142,6 +142,24 @@ struct guestfs_list_partitions_ret { str partitions<>; }; +/* guestfs_pvs */ + +struct guestfs_pvs_ret { + str physvols<>; +}; + +/* guestfs_vgs */ + +struct guestfs_vgs_ret { + str volgroups<>; +}; + +/* guestfs_lvs */ + +struct guestfs_lvs_ret { + str logvols<>; +}; + /* guestfs_pvs_full */ struct guestfs_pvs_full_ret { @@ -169,6 +187,9 @@ enum guestfs_procedure { GUESTFS_PROC_LS = 6, GUESTFS_PROC_LIST_DEVICES = 7, GUESTFS_PROC_LIST_PARTITIONS = 8, + GUESTFS_PROC_PVS = 9, + GUESTFS_PROC_VGS = 10, + GUESTFS_PROC_LVS = 11, GUESTFS_PROC_PVS_FULL = 12, GUESTFS_PROC_VGS_FULL = 13, GUESTFS_PROC_LVS_FULL = 14,