mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
pvs/vgs/lvs commands working now.
This commit is contained in:
13
Makefile.am
13
Makefile.am
@@ -21,7 +21,7 @@ SUBDIRS = src daemon fish examples
|
||||
|
||||
EXTRA_DIST = \
|
||||
make-initramfs.sh update-initramfs.sh \
|
||||
guestfs.pod guestfs-actions.pod \
|
||||
guestfs.pod guestfs-actions.pod guestfs-structs.pod \
|
||||
libguestfs.spec \
|
||||
HACKING
|
||||
|
||||
@@ -57,13 +57,16 @@ clean-local:
|
||||
rm -rf initramfs
|
||||
|
||||
# Manual page.
|
||||
# guestfs-actions.pod is autogenerated. There is no include mechanism
|
||||
# for POD, so we have to do it by hand.
|
||||
# guestfs-actions.pod and guestfs-structs are autogenerated. There is
|
||||
# no include mechanism for POD, so we have to do it by hand.
|
||||
|
||||
man_MANS = guestfs.3
|
||||
|
||||
guestfs.3: guestfs.pod guestfs-actions.pod
|
||||
sed -e '/@ACTIONS@/rguestfs-actions.pod' -e 's/@ACTIONS@//' < $< | \
|
||||
guestfs.3: guestfs.pod guestfs-actions.pod guestfs-structs.pod
|
||||
sed \
|
||||
-e '/@ACTIONS@/rguestfs-actions.pod' -e 's/@ACTIONS@//' \
|
||||
-e '/@STRUCTS@/rguestfs-structs.pod' -e 's/@STRUCTS@//' \
|
||||
< $< | \
|
||||
$(POD2MAN) \
|
||||
--section 3 \
|
||||
-c "Virtualization Support" \
|
||||
|
||||
@@ -25,6 +25,7 @@ guestfsd_SOURCES = \
|
||||
file.c \
|
||||
guestfsd.c \
|
||||
ls.c \
|
||||
lvm.c \
|
||||
mount.c \
|
||||
proto.c \
|
||||
stubs.c \
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "../src/guestfs_protocol.h"
|
||||
|
||||
extern int do_mount (const char *device, const char *mountpoint);
|
||||
extern int do_sync ();
|
||||
extern int do_touch (const char *path);
|
||||
@@ -27,3 +29,6 @@ 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 guestfs_lvm_int_pv_list *do_pvs ();
|
||||
extern guestfs_lvm_int_vg_list *do_vgs ();
|
||||
extern guestfs_lvm_int_lv_list *do_lvs ();
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef GUESTFSD_DAEMON_H
|
||||
#define GUESTFSD_DAEMON_H
|
||||
|
||||
#include "../src/guestfs_protocol.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
@@ -44,6 +46,9 @@ extern int root_mounted;
|
||||
|
||||
/* in stubs.c (auto-generated) */
|
||||
extern void dispatch_incoming_message (XDR *);
|
||||
extern guestfs_lvm_int_pv_list *parse_command_line_pvs (void);
|
||||
extern guestfs_lvm_int_vg_list *parse_command_line_vgs (void);
|
||||
extern guestfs_lvm_int_lv_list *parse_command_line_lvs (void);
|
||||
|
||||
/* in proto.c */
|
||||
extern void main_loop (int sock);
|
||||
|
||||
50
daemon/lvm.c
Normal file
50
daemon/lvm.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* libguestfs - the guestfsd daemon
|
||||
* Copyright (C) 2009 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "daemon.h"
|
||||
#include "actions.h"
|
||||
|
||||
/* LVM actions. Keep an eye on liblvm, although at the time
|
||||
* of writing it hasn't progressed very far.
|
||||
*/
|
||||
|
||||
guestfs_lvm_int_pv_list *
|
||||
do_pvs (void)
|
||||
{
|
||||
return parse_command_line_pvs ();
|
||||
}
|
||||
|
||||
guestfs_lvm_int_vg_list *
|
||||
do_vgs (void)
|
||||
{
|
||||
return parse_command_line_vgs ();
|
||||
}
|
||||
|
||||
guestfs_lvm_int_lv_list *
|
||||
do_lvs (void)
|
||||
{
|
||||
return parse_command_line_lvs ();
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
/* XXX We should make this configurable from /proc/cmdline so that the
|
||||
* verbose setting of the guestfs_h can be inherited here.
|
||||
*/
|
||||
#define DEBUG 1
|
||||
#define DEBUG 0
|
||||
|
||||
/* The message currently being processed. */
|
||||
int proc_nr;
|
||||
|
||||
989
daemon/stubs.c
989
daemon/stubs.c
File diff suppressed because it is too large
Load Diff
170
fish/cmds.c
170
fish/cmds.c
@@ -22,7 +22,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <guestfs.h>
|
||||
#include "fish.h"
|
||||
|
||||
void list_commands (void)
|
||||
@@ -34,9 +36,12 @@ 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", "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", "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 (" Use -h <cmd> / help <cmd> to show detailed help for a command.\n");
|
||||
}
|
||||
|
||||
@@ -65,10 +70,121 @@ void display_command (const char *cmd)
|
||||
else
|
||||
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</dev/sda1>\n\nThis does not return logical volumes. For that you will need to\ncall C<guestfs_lvs>.");
|
||||
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<pvs(8)> command.");
|
||||
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<vgs(8)> command.");
|
||||
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<lvs(8)> command.");
|
||||
else
|
||||
display_builtin_command (cmd);
|
||||
}
|
||||
|
||||
static void print_pv (struct guestfs_lvm_pv *pv)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("pv_name: %s\n", pv->pv_name);
|
||||
printf ("pv_uuid: ");
|
||||
for (i = 0; i < 32; ++i)
|
||||
printf ("%c", pv->pv_uuid[i]);
|
||||
printf ("\n");
|
||||
printf ("pv_fmt: %s\n", pv->pv_fmt);
|
||||
printf ("pv_size: %" PRIu64 "\n", pv->pv_size);
|
||||
printf ("dev_size: %" PRIu64 "\n", pv->dev_size);
|
||||
printf ("pv_free: %" PRIu64 "\n", pv->pv_free);
|
||||
printf ("pv_used: %" PRIu64 "\n", pv->pv_used);
|
||||
printf ("pv_attr: %s\n", pv->pv_attr);
|
||||
printf ("pv_pe_count: %" PRIi64 "\n", pv->pv_pe_count);
|
||||
printf ("pv_pe_alloc_count: %" PRIi64 "\n", pv->pv_pe_alloc_count);
|
||||
printf ("pv_tags: %s\n", pv->pv_tags);
|
||||
printf ("pe_start: %" PRIu64 "\n", pv->pe_start);
|
||||
printf ("pv_mda_count: %" PRIi64 "\n", pv->pv_mda_count);
|
||||
printf ("pv_mda_free: %" PRIu64 "\n", pv->pv_mda_free);
|
||||
}
|
||||
|
||||
static void print_pv_list (struct guestfs_lvm_pv_list *pvs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pvs->len; ++i)
|
||||
print_pv (&pvs->val[i]);
|
||||
}
|
||||
|
||||
static void print_vg (struct guestfs_lvm_vg *vg)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("vg_name: %s\n", vg->vg_name);
|
||||
printf ("vg_uuid: ");
|
||||
for (i = 0; i < 32; ++i)
|
||||
printf ("%c", vg->vg_uuid[i]);
|
||||
printf ("\n");
|
||||
printf ("vg_fmt: %s\n", vg->vg_fmt);
|
||||
printf ("vg_attr: %s\n", vg->vg_attr);
|
||||
printf ("vg_size: %" PRIu64 "\n", vg->vg_size);
|
||||
printf ("vg_free: %" PRIu64 "\n", vg->vg_free);
|
||||
printf ("vg_sysid: %s\n", vg->vg_sysid);
|
||||
printf ("vg_extent_size: %" PRIu64 "\n", vg->vg_extent_size);
|
||||
printf ("vg_extent_count: %" PRIi64 "\n", vg->vg_extent_count);
|
||||
printf ("vg_free_count: %" PRIi64 "\n", vg->vg_free_count);
|
||||
printf ("max_lv: %" PRIi64 "\n", vg->max_lv);
|
||||
printf ("max_pv: %" PRIi64 "\n", vg->max_pv);
|
||||
printf ("pv_count: %" PRIi64 "\n", vg->pv_count);
|
||||
printf ("lv_count: %" PRIi64 "\n", vg->lv_count);
|
||||
printf ("snap_count: %" PRIi64 "\n", vg->snap_count);
|
||||
printf ("vg_seqno: %" PRIi64 "\n", vg->vg_seqno);
|
||||
printf ("vg_tags: %s\n", vg->vg_tags);
|
||||
printf ("vg_mda_count: %" PRIi64 "\n", vg->vg_mda_count);
|
||||
printf ("vg_mda_free: %" PRIu64 "\n", vg->vg_mda_free);
|
||||
}
|
||||
|
||||
static void print_vg_list (struct guestfs_lvm_vg_list *vgs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vgs->len; ++i)
|
||||
print_vg (&vgs->val[i]);
|
||||
}
|
||||
|
||||
static void print_lv (struct guestfs_lvm_lv *lv)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("lv_name: %s\n", lv->lv_name);
|
||||
printf ("lv_uuid: ");
|
||||
for (i = 0; i < 32; ++i)
|
||||
printf ("%c", lv->lv_uuid[i]);
|
||||
printf ("\n");
|
||||
printf ("lv_attr: %s\n", lv->lv_attr);
|
||||
printf ("lv_major: %" PRIi64 "\n", lv->lv_major);
|
||||
printf ("lv_minor: %" PRIi64 "\n", lv->lv_minor);
|
||||
printf ("lv_kernel_major: %" PRIi64 "\n", lv->lv_kernel_major);
|
||||
printf ("lv_kernel_minor: %" PRIi64 "\n", lv->lv_kernel_minor);
|
||||
printf ("lv_size: %" PRIu64 "\n", lv->lv_size);
|
||||
printf ("seg_count: %" PRIi64 "\n", lv->seg_count);
|
||||
printf ("origin: %s\n", lv->origin);
|
||||
if (lv->snap_percent >= 0) printf ("snap_percent: %g %%\n", lv->snap_percent);
|
||||
else printf ("snap_percent: \n");
|
||||
if (lv->copy_percent >= 0) printf ("copy_percent: %g %%\n", lv->copy_percent);
|
||||
else printf ("copy_percent: \n");
|
||||
printf ("move_pv: %s\n", lv->move_pv);
|
||||
printf ("lv_tags: %s\n", lv->lv_tags);
|
||||
printf ("mirror_log: %s\n", lv->mirror_log);
|
||||
printf ("modules: %s\n", lv->modules);
|
||||
}
|
||||
|
||||
static void print_lv_list (struct guestfs_lvm_lv_list *lvs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lvs->len; ++i)
|
||||
print_lv (&lvs->val[i]);
|
||||
}
|
||||
|
||||
static int run_mount (const char *cmd, int argc, char *argv[])
|
||||
{
|
||||
int r;
|
||||
@@ -192,6 +308,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[])
|
||||
{
|
||||
struct guestfs_lvm_pv_list *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_pv_list (r);
|
||||
guestfs_free_lvm_pv_list (r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_vgs (const char *cmd, int argc, char *argv[])
|
||||
{
|
||||
struct guestfs_lvm_vg_list *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_vg_list (r);
|
||||
guestfs_free_lvm_vg_list (r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_lvs (const char *cmd, int argc, char *argv[])
|
||||
{
|
||||
struct guestfs_lvm_lv_list *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_lv_list (r);
|
||||
guestfs_free_lvm_lv_list (r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int run_action (const char *cmd, int argc, char *argv[])
|
||||
{
|
||||
if (strcasecmp (cmd, "mount") == 0)
|
||||
@@ -217,6 +378,15 @@ int run_action (const char *cmd, int argc, char *argv[])
|
||||
else
|
||||
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
|
||||
{
|
||||
fprintf (stderr, "%s: unknown command\n", cmd);
|
||||
|
||||
@@ -165,7 +165,7 @@ main (int argc, char *argv[])
|
||||
mp->mountpoint = "/";
|
||||
mp->device = optarg;
|
||||
mp->next = mps;
|
||||
mps = mp->next;
|
||||
mps = mp;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
|
||||
@@ -75,6 +75,16 @@ This function returns a NULL-terminated array of strings
|
||||
(like L<environ(3)>), or NULL if there was an error.
|
||||
I<The caller must free the strings and the array after use>.
|
||||
|
||||
=head2 guestfs_lvs
|
||||
|
||||
struct guestfs_lvm_lv_list *guestfs_lvs (guestfs_h *handle);
|
||||
|
||||
List all the logical volumes detected. This is the equivalent
|
||||
of the L<lvs(8)> command.
|
||||
|
||||
This function returns a C<struct guestfs_lvm_lv_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_lv_list> after use.>.
|
||||
|
||||
=head2 guestfs_mount
|
||||
|
||||
int guestfs_mount (guestfs_h *handle,
|
||||
@@ -100,6 +110,16 @@ call, in order to improve reliability.
|
||||
|
||||
This function returns 0 on success or -1 on error.
|
||||
|
||||
=head2 guestfs_pvs
|
||||
|
||||
struct guestfs_lvm_pv_list *guestfs_pvs (guestfs_h *handle);
|
||||
|
||||
List all the physical volumes detected. This is the equivalent
|
||||
of the L<pvs(8)> command.
|
||||
|
||||
This function returns a C<struct guestfs_lvm_pv_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_pv_list> after use.>.
|
||||
|
||||
=head2 guestfs_sync
|
||||
|
||||
int guestfs_sync (guestfs_h *handle);
|
||||
@@ -123,3 +143,13 @@ to create a new zero-length file.
|
||||
|
||||
This function returns 0 on success or -1 on error.
|
||||
|
||||
=head2 guestfs_vgs
|
||||
|
||||
struct guestfs_lvm_vg_list *guestfs_vgs (guestfs_h *handle);
|
||||
|
||||
List all the volumes groups detected. This is the equivalent
|
||||
of the L<vgs(8)> command.
|
||||
|
||||
This function returns a C<struct guestfs_lvm_vg_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_vg_list> after use.>.
|
||||
|
||||
|
||||
87
guestfs-structs.pod
Normal file
87
guestfs-structs.pod
Normal file
@@ -0,0 +1,87 @@
|
||||
=head2 guestfs_lvm_pv
|
||||
|
||||
struct guestfs_lvm_pv {
|
||||
char *pv_name;
|
||||
/* The next field is NOT nul-terminated, be careful when printing it: */
|
||||
char pv_uuid[32];
|
||||
char *pv_fmt;
|
||||
uint64_t pv_size;
|
||||
uint64_t dev_size;
|
||||
uint64_t pv_free;
|
||||
uint64_t pv_used;
|
||||
char *pv_attr;
|
||||
int64_t pv_pe_count;
|
||||
int64_t pv_pe_alloc_count;
|
||||
char *pv_tags;
|
||||
uint64_t pe_start;
|
||||
int64_t pv_mda_count;
|
||||
uint64_t pv_mda_free;
|
||||
|
||||
struct guestfs_lvm_pv_list {
|
||||
uint32_t len; /* Number of elements in list. */
|
||||
struct guestfs_lvm_pv *val; /* Elements. */
|
||||
};
|
||||
|
||||
void guestfs_free_lvm_pv_list (struct guestfs_free_lvm_pv_list *);
|
||||
|
||||
=head2 guestfs_lvm_vg
|
||||
|
||||
struct guestfs_lvm_vg {
|
||||
char *vg_name;
|
||||
/* The next field is NOT nul-terminated, be careful when printing it: */
|
||||
char vg_uuid[32];
|
||||
char *vg_fmt;
|
||||
char *vg_attr;
|
||||
uint64_t vg_size;
|
||||
uint64_t vg_free;
|
||||
char *vg_sysid;
|
||||
uint64_t vg_extent_size;
|
||||
int64_t vg_extent_count;
|
||||
int64_t vg_free_count;
|
||||
int64_t max_lv;
|
||||
int64_t max_pv;
|
||||
int64_t pv_count;
|
||||
int64_t lv_count;
|
||||
int64_t snap_count;
|
||||
int64_t vg_seqno;
|
||||
char *vg_tags;
|
||||
int64_t vg_mda_count;
|
||||
uint64_t vg_mda_free;
|
||||
|
||||
struct guestfs_lvm_vg_list {
|
||||
uint32_t len; /* Number of elements in list. */
|
||||
struct guestfs_lvm_vg *val; /* Elements. */
|
||||
};
|
||||
|
||||
void guestfs_free_lvm_vg_list (struct guestfs_free_lvm_vg_list *);
|
||||
|
||||
=head2 guestfs_lvm_lv
|
||||
|
||||
struct guestfs_lvm_lv {
|
||||
char *lv_name;
|
||||
/* The next field is NOT nul-terminated, be careful when printing it: */
|
||||
char lv_uuid[32];
|
||||
char *lv_attr;
|
||||
int64_t lv_major;
|
||||
int64_t lv_minor;
|
||||
int64_t lv_kernel_major;
|
||||
int64_t lv_kernel_minor;
|
||||
uint64_t lv_size;
|
||||
int64_t seg_count;
|
||||
char *origin;
|
||||
/* The next field is [0..100] or -1 meaning 'not present': */
|
||||
float snap_percent;
|
||||
/* The next field is [0..100] or -1 meaning 'not present': */
|
||||
float copy_percent;
|
||||
char *move_pv;
|
||||
char *lv_tags;
|
||||
char *mirror_log;
|
||||
char *modules;
|
||||
|
||||
struct guestfs_lvm_lv_list {
|
||||
uint32_t len; /* Number of elements in list. */
|
||||
struct guestfs_lvm_lv *val; /* Elements. */
|
||||
};
|
||||
|
||||
void guestfs_free_lvm_lv_list (struct guestfs_free_lvm_lv_list *);
|
||||
|
||||
@@ -312,6 +312,10 @@ This returns the verbose messages flag.
|
||||
|
||||
@ACTIONS@
|
||||
|
||||
=head1 STRUCTURES
|
||||
|
||||
@STRUCTS@
|
||||
|
||||
=head1 STATE MACHINE AND LOW-LEVEL EVENT API
|
||||
|
||||
Internally, libguestfs is implemented by running a virtual machine
|
||||
|
||||
@@ -23,7 +23,7 @@ EXTRA_DIST += guestfs_protocol.x \
|
||||
guestfs_protocol.c \
|
||||
guestfs_protocol.h
|
||||
|
||||
include_HEADERS = guestfs.h guestfs-actions.h
|
||||
include_HEADERS = guestfs.h guestfs-actions.h guestfs-structs.h
|
||||
|
||||
lib_LTLIBRARIES = libguestfs.la
|
||||
|
||||
|
||||
509
src/generator.ml
509
src/generator.ml
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/ocamlrun ocaml
|
||||
#!/usr/bin/env ocaml
|
||||
(* libguestfs
|
||||
* Copyright (C) 2009 Red Hat Inc.
|
||||
*
|
||||
@@ -37,6 +37,10 @@ and ret =
|
||||
*)
|
||||
| RString of string
|
||||
| RStringList of string
|
||||
(* LVM PVs, VGs and LVs. *)
|
||||
| RPVList of string
|
||||
| RVGList of string
|
||||
| RLVList of string
|
||||
and args =
|
||||
(* 0 arguments, 1 argument, etc. The guestfs_h param is implicit. *)
|
||||
| P0
|
||||
@@ -130,6 +134,87 @@ The full partition device names are returned, eg. C</dev/sda1>
|
||||
|
||||
This does not return logical volumes. For that you will need to
|
||||
call C<guestfs_lvs>.");
|
||||
|
||||
("pvs", (RPVList "physvols", P0), 9, [],
|
||||
"list the LVM physical volumes (PVs)",
|
||||
"\
|
||||
List all the physical volumes detected. This is the equivalent
|
||||
of the L<pvs(8)> command.");
|
||||
|
||||
("vgs", (RVGList "volgroups", P0), 10, [],
|
||||
"list the LVM volume groups (VGs)",
|
||||
"\
|
||||
List all the volumes groups detected. This is the equivalent
|
||||
of the L<vgs(8)> command.");
|
||||
|
||||
("lvs", (RLVList "logvols", P0), 11, [],
|
||||
"list the LVM logical volumes (LVs)",
|
||||
"\
|
||||
List all the logical volumes detected. This is the equivalent
|
||||
of the L<lvs(8)> command.");
|
||||
]
|
||||
|
||||
(* Column names and types from LVM PVs/VGs/LVs. *)
|
||||
let pv_cols = [
|
||||
"pv_name", `String;
|
||||
"pv_uuid", `UUID;
|
||||
"pv_fmt", `String;
|
||||
"pv_size", `Bytes;
|
||||
"dev_size", `Bytes;
|
||||
"pv_free", `Bytes;
|
||||
"pv_used", `Bytes;
|
||||
"pv_attr", `String (* XXX *);
|
||||
"pv_pe_count", `Int;
|
||||
"pv_pe_alloc_count", `Int;
|
||||
"pv_tags", `String;
|
||||
"pe_start", `Bytes;
|
||||
"pv_mda_count", `Int;
|
||||
"pv_mda_free", `Bytes;
|
||||
(* Not in Fedora 10:
|
||||
"pv_mda_size", `Bytes;
|
||||
*)
|
||||
]
|
||||
let vg_cols = [
|
||||
"vg_name", `String;
|
||||
"vg_uuid", `UUID;
|
||||
"vg_fmt", `String;
|
||||
"vg_attr", `String (* XXX *);
|
||||
"vg_size", `Bytes;
|
||||
"vg_free", `Bytes;
|
||||
"vg_sysid", `String;
|
||||
"vg_extent_size", `Bytes;
|
||||
"vg_extent_count", `Int;
|
||||
"vg_free_count", `Int;
|
||||
"max_lv", `Int;
|
||||
"max_pv", `Int;
|
||||
"pv_count", `Int;
|
||||
"lv_count", `Int;
|
||||
"snap_count", `Int;
|
||||
"vg_seqno", `Int;
|
||||
"vg_tags", `String;
|
||||
"vg_mda_count", `Int;
|
||||
"vg_mda_free", `Bytes;
|
||||
(* Not in Fedora 10:
|
||||
"vg_mda_size", `Bytes;
|
||||
*)
|
||||
]
|
||||
let lv_cols = [
|
||||
"lv_name", `String;
|
||||
"lv_uuid", `UUID;
|
||||
"lv_attr", `String (* XXX *);
|
||||
"lv_major", `Int;
|
||||
"lv_minor", `Int;
|
||||
"lv_kernel_major", `Int;
|
||||
"lv_kernel_minor", `Int;
|
||||
"lv_size", `Bytes;
|
||||
"seg_count", `Int;
|
||||
"origin", `String;
|
||||
"snap_percent", `OptPercent;
|
||||
"copy_percent", `OptPercent;
|
||||
"move_pv", `String;
|
||||
"lv_tags", `String;
|
||||
"mirror_log", `String;
|
||||
"modules", `String;
|
||||
]
|
||||
|
||||
(* In some places we want the functions to be displayed sorted
|
||||
@@ -250,7 +335,7 @@ let rec generate_header comment license =
|
||||
pr "\n"
|
||||
|
||||
(* Generate the pod documentation for the C API. *)
|
||||
and generate_pod () =
|
||||
and generate_actions_pod () =
|
||||
List.iter (
|
||||
fun (shortname, style, _, flags, _, longdesc) ->
|
||||
let name = "guestfs_" ^ shortname in
|
||||
@@ -269,6 +354,15 @@ I<The caller must free the returned string after use>.\n\n"
|
||||
pr "This function returns a NULL-terminated array of strings
|
||||
(like L<environ(3)>), or NULL if there was an error.
|
||||
I<The caller must free the strings and the array after use>.\n\n"
|
||||
| RPVList _ ->
|
||||
pr "This function returns a C<struct guestfs_lvm_pv_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_pv_list> after use.>.\n\n"
|
||||
| RVGList _ ->
|
||||
pr "This function returns a C<struct guestfs_lvm_vg_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_vg_list> after use.>.\n\n"
|
||||
| RLVList _ ->
|
||||
pr "This function returns a C<struct guestfs_lvm_lv_list>.
|
||||
I<The caller must call C<guestfs_free_lvm_lv_list> after use.>.\n\n"
|
||||
);
|
||||
if List.mem ProtocolLimitWarning flags then
|
||||
pr "Because of the message protocol, there is a transfer limit
|
||||
@@ -276,7 +370,43 @@ of somewhere between 2MB and 4MB. To transfer large files you should use
|
||||
FTP.\n\n";
|
||||
) sorted_functions
|
||||
|
||||
(* Generate the protocol (XDR) file. *)
|
||||
and generate_structs_pod () =
|
||||
(* LVM structs documentation. *)
|
||||
List.iter (
|
||||
fun (typ, cols) ->
|
||||
pr "=head2 guestfs_lvm_%s\n" typ;
|
||||
pr "\n";
|
||||
pr " struct guestfs_lvm_%s {\n" typ;
|
||||
List.iter (
|
||||
function
|
||||
| name, `String -> pr " char *%s;\n" name
|
||||
| name, `UUID ->
|
||||
pr " /* The next field is NOT nul-terminated, be careful when printing it: */\n";
|
||||
pr " char %s[32];\n" name
|
||||
| name, `Bytes -> pr " uint64_t %s;\n" name
|
||||
| name, `Int -> pr " int64_t %s;\n" name
|
||||
| name, `OptPercent ->
|
||||
pr " /* The next field is [0..100] or -1 meaning 'not present': */\n";
|
||||
pr " float %s;\n" name
|
||||
) cols;
|
||||
pr " \n";
|
||||
pr " struct guestfs_lvm_%s_list {\n" typ;
|
||||
pr " uint32_t len; /* Number of elements in list. */\n";
|
||||
pr " struct guestfs_lvm_%s *val; /* Elements. */\n" typ;
|
||||
pr " };\n";
|
||||
pr " \n";
|
||||
pr " void guestfs_free_lvm_%s_list (struct guestfs_free_lvm_%s_list *);\n"
|
||||
typ typ;
|
||||
pr "\n"
|
||||
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]
|
||||
|
||||
(* Generate the protocol (XDR) file, 'guestfs_protocol.x' and
|
||||
* indirectly 'guestfs_protocol.h' and 'guestfs_protocol.c'. We
|
||||
* have to use an underscore instead of a dash because otherwise
|
||||
* rpcgen generates incorrect code.
|
||||
*
|
||||
* This header is NOT exported to clients, but see also generate_structs_h.
|
||||
*)
|
||||
and generate_xdr () =
|
||||
generate_header CStyle LGPLv2;
|
||||
|
||||
@@ -284,6 +414,24 @@ and generate_xdr () =
|
||||
pr "typedef string str<>;\n";
|
||||
pr "\n";
|
||||
|
||||
(* LVM internal structures. *)
|
||||
List.iter (
|
||||
function
|
||||
| typ, cols ->
|
||||
pr "struct guestfs_lvm_int_%s {\n" typ;
|
||||
List.iter (function
|
||||
| name, `String -> pr " string %s<>;\n" name
|
||||
| name, `UUID -> pr " opaque %s[32];\n" name
|
||||
| name, `Bytes -> pr " hyper %s;\n" name
|
||||
| name, `Int -> pr " hyper %s;\n" name
|
||||
| name, `OptPercent -> pr " float %s;\n" name
|
||||
) cols;
|
||||
pr "};\n";
|
||||
pr "\n";
|
||||
pr "typedef struct guestfs_lvm_int_%s guestfs_lvm_int_%s_list<>;\n" typ typ;
|
||||
pr "\n";
|
||||
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols];
|
||||
|
||||
List.iter (
|
||||
fun (shortname, style, _, _, _, _) ->
|
||||
let name = "guestfs_" ^ shortname in
|
||||
@@ -308,6 +456,18 @@ and generate_xdr () =
|
||||
pr "struct %s_ret {\n" name;
|
||||
pr " str %s<>;\n" n;
|
||||
pr "};\n\n"
|
||||
| RPVList n ->
|
||||
pr "struct %s_ret {\n" name;
|
||||
pr " guestfs_lvm_int_pv_list %s;\n" n;
|
||||
pr "};\n\n"
|
||||
| RVGList n ->
|
||||
pr "struct %s_ret {\n" name;
|
||||
pr " guestfs_lvm_int_vg_list %s;\n" n;
|
||||
pr "};\n\n"
|
||||
| RLVList n ->
|
||||
pr "struct %s_ret {\n" name;
|
||||
pr " guestfs_lvm_int_lv_list %s;\n" n;
|
||||
pr "};\n\n"
|
||||
);
|
||||
) functions;
|
||||
|
||||
@@ -361,6 +521,46 @@ struct guestfs_message_header {
|
||||
};
|
||||
"
|
||||
|
||||
(* Generate the guestfs-structs.h file. *)
|
||||
and generate_structs_h () =
|
||||
generate_header CStyle LGPLv2;
|
||||
|
||||
(* This is a public exported header file containing various
|
||||
* structures. The structures are carefully written to have
|
||||
* exactly the same in-memory format as the XDR structures that
|
||||
* we use on the wire to the daemon. The reason for creating
|
||||
* copies of these structures here is just so we don't have to
|
||||
* export the whole of guestfs_protocol.h (which includes much
|
||||
* unrelated and XDR-dependent stuff that we don't want to be
|
||||
* public, or required by clients).
|
||||
*
|
||||
* To reiterate, we will pass these structures to and from the
|
||||
* client with a simple assignment or memcpy, so the format
|
||||
* must be identical to what rpcgen / the RFC defines.
|
||||
*)
|
||||
|
||||
(* LVM public structures. *)
|
||||
List.iter (
|
||||
function
|
||||
| typ, cols ->
|
||||
pr "struct guestfs_lvm_%s {\n" typ;
|
||||
List.iter (
|
||||
function
|
||||
| name, `String -> pr " char *%s;\n" name
|
||||
| name, `UUID -> pr " char %s[32]; /* this is NOT nul-terminated, be careful when printing */\n" name
|
||||
| name, `Bytes -> pr " uint64_t %s;\n" name
|
||||
| name, `Int -> pr " int64_t %s;\n" name
|
||||
| name, `OptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
|
||||
) cols;
|
||||
pr "};\n";
|
||||
pr "\n";
|
||||
pr "struct guestfs_lvm_%s_list {\n" typ;
|
||||
pr " uint32_t len;\n";
|
||||
pr " struct guestfs_lvm_%s *val;\n" typ;
|
||||
pr "};\n";
|
||||
pr "\n"
|
||||
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]
|
||||
|
||||
(* Generate the guestfs-actions.h file. *)
|
||||
and generate_actions_h () =
|
||||
generate_header CStyle LGPLv2;
|
||||
@@ -374,6 +574,8 @@ and generate_actions_h () =
|
||||
(* Generate the client-side dispatch stubs. *)
|
||||
and generate_client_actions () =
|
||||
generate_header CStyle LGPLv2;
|
||||
|
||||
(* Client-side stubs for each function. *)
|
||||
List.iter (
|
||||
fun (shortname, style, _, _, _, _) ->
|
||||
let name = "guestfs_" ^ shortname in
|
||||
@@ -385,7 +587,8 @@ and generate_client_actions () =
|
||||
pr " struct guestfs_message_error err;\n";
|
||||
(match fst style with
|
||||
| Err -> ()
|
||||
| RString _ | RStringList _ -> pr " struct %s_ret ret;\n" name;
|
||||
| RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
|
||||
pr " struct %s_ret ret;\n" name
|
||||
);
|
||||
pr "};\n\n";
|
||||
|
||||
@@ -408,7 +611,7 @@ and generate_client_actions () =
|
||||
|
||||
(match fst style with
|
||||
| Err -> ()
|
||||
| RString _ | RStringList _ ->
|
||||
| RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
|
||||
pr " if (!xdr_%s_ret (xdr, &rv->ret)) {\n" name;
|
||||
pr " error (g, \"%s: failed to parse reply\");\n" name;
|
||||
pr " return;\n";
|
||||
@@ -427,7 +630,8 @@ and generate_client_actions () =
|
||||
let error_code =
|
||||
match fst style with
|
||||
| Err -> "-1"
|
||||
| RString _ | RStringList _ -> "NULL" in
|
||||
| RString _ | RStringList _ | RPVList _ | RVGList _ | RLVList _ ->
|
||||
"NULL" in
|
||||
|
||||
pr "{\n";
|
||||
|
||||
@@ -499,6 +703,15 @@ and generate_client_actions () =
|
||||
pr " rv.ret.%s.%s_val = safe_realloc (g, rv.ret.%s.%s_val, rv.ret.%s.%s_len + 1);\n" n n n n n n;
|
||||
pr " rv.ret.%s.%s_val[rv.ret.%s.%s_len] = NULL;\n" n n n n;
|
||||
pr " return rv.ret.%s.%s_val;\n" n n
|
||||
| RPVList n ->
|
||||
pr " /* caller will free this */\n";
|
||||
pr " return safe_memdup (g, &rv.ret.%s, sizeof (rv.ret.%s));\n" n n
|
||||
| RVGList n ->
|
||||
pr " /* caller will free this */\n";
|
||||
pr " return safe_memdup (g, &rv.ret.%s, sizeof (rv.ret.%s));\n" n n
|
||||
| RLVList n ->
|
||||
pr " /* caller will free this */\n";
|
||||
pr " return safe_memdup (g, &rv.ret.%s, sizeof (rv.ret.%s));\n" n n
|
||||
);
|
||||
|
||||
pr "}\n\n"
|
||||
@@ -507,17 +720,30 @@ and generate_client_actions () =
|
||||
(* Generate daemon/actions.h. *)
|
||||
and generate_daemon_actions_h () =
|
||||
generate_header CStyle GPLv2;
|
||||
|
||||
pr "#include \"../src/guestfs_protocol.h\"\n";
|
||||
pr "\n";
|
||||
|
||||
List.iter (
|
||||
fun (name, style, _, _, _, _) ->
|
||||
generate_prototype ~single_line:true ~newline:true ("do_" ^ name) style;
|
||||
generate_prototype
|
||||
~single_line:true ~newline:true ~in_daemon:true ("do_" ^ name) style;
|
||||
) functions
|
||||
|
||||
(* Generate the server-side stubs. *)
|
||||
and generate_daemon_actions () =
|
||||
generate_header CStyle GPLv2;
|
||||
|
||||
pr "#define _GNU_SOURCE // for strchrnul\n";
|
||||
pr "\n";
|
||||
pr "#include <stdio.h>\n";
|
||||
pr "#include <stdlib.h>\n";
|
||||
pr "#include <string.h>\n";
|
||||
pr "#include <inttypes.h>\n";
|
||||
pr "#include <ctype.h>\n";
|
||||
pr "#include <rpc/types.h>\n";
|
||||
pr "#include <rpc/xdr.h>\n";
|
||||
pr "\n";
|
||||
pr "#include \"daemon.h\"\n";
|
||||
pr "#include \"../src/guestfs_protocol.h\"\n";
|
||||
pr "#include \"actions.h\"\n";
|
||||
@@ -532,7 +758,11 @@ and generate_daemon_actions () =
|
||||
match fst style with
|
||||
| Err -> pr " int r;\n"; "-1"
|
||||
| RString _ -> pr " char *r;\n"; "NULL"
|
||||
| RStringList _ -> pr " char **r;\n"; "NULL" in
|
||||
| RStringList _ -> pr " char **r;\n"; "NULL"
|
||||
| RPVList _ -> pr " guestfs_lvm_int_pv_list *r;\n"; "NULL"
|
||||
| RVGList _ -> pr " guestfs_lvm_int_vg_list *r;\n"; "NULL"
|
||||
| RLVList _ -> pr " guestfs_lvm_int_lv_list *r;\n"; "NULL" in
|
||||
|
||||
(match snd style with
|
||||
| P0 -> ()
|
||||
| args ->
|
||||
@@ -582,6 +812,21 @@ and generate_daemon_actions () =
|
||||
pr " ret.%s.%s_val = r;\n" n n;
|
||||
pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name;
|
||||
pr " free_strings (r);\n"
|
||||
| RPVList n ->
|
||||
pr " struct guestfs_%s_ret ret;\n" name;
|
||||
pr " ret.%s = *r;\n" n;
|
||||
pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name;
|
||||
pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name
|
||||
| RVGList n ->
|
||||
pr " struct guestfs_%s_ret ret;\n" name;
|
||||
pr " ret.%s = *r;\n" n;
|
||||
pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name;
|
||||
pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name
|
||||
| RLVList n ->
|
||||
pr " struct guestfs_%s_ret ret;\n" name;
|
||||
pr " ret.%s = *r;\n" n;
|
||||
pr " reply ((xdrproc_t) &xdr_guestfs_%s_ret, (char *) &ret);\n" name;
|
||||
pr " xdr_free ((xdrproc_t) xdr_guestfs_%s_ret, (char *) &ret);\n" name
|
||||
);
|
||||
|
||||
pr "}\n\n";
|
||||
@@ -602,7 +847,173 @@ and generate_daemon_actions () =
|
||||
pr " default:\n";
|
||||
pr " reply_with_error (\"dispatch_incoming_message: unknown procedure number %%d\", proc_nr);\n";
|
||||
pr " }\n";
|
||||
pr "}\n"
|
||||
pr "}\n";
|
||||
pr "\n";
|
||||
|
||||
(* LVM columns and tokenization functions. *)
|
||||
(* XXX This generates crap code. We should rethink how we
|
||||
* do this parsing.
|
||||
*)
|
||||
List.iter (
|
||||
function
|
||||
| typ, cols ->
|
||||
pr "static const char *lvm_%s_cols = \"%s\";\n"
|
||||
typ (String.concat "," (List.map fst cols));
|
||||
pr "\n";
|
||||
|
||||
pr "static int lvm_tokenize_%s (char *str, struct guestfs_lvm_int_%s *r)\n" typ typ;
|
||||
pr "{\n";
|
||||
pr " char *tok, *p, *next;\n";
|
||||
pr " int i, j;\n";
|
||||
pr "\n";
|
||||
(*
|
||||
pr " fprintf (stderr, \"%%s: <<%%s>>\\n\", __func__, str);\n";
|
||||
pr "\n";
|
||||
*)
|
||||
pr " if (!str) {\n";
|
||||
pr " fprintf (stderr, \"%%s: failed: passed a NULL string\\n\", __func__);\n";
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
pr " if (!*str || isspace (*str)) {\n";
|
||||
pr " fprintf (stderr, \"%%s: failed: passed a empty string or one beginning with whitespace\\n\", __func__);\n";
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
pr " tok = str;\n";
|
||||
List.iter (
|
||||
fun (name, coltype) ->
|
||||
pr " if (!tok) {\n";
|
||||
pr " fprintf (stderr, \"%%s: failed: string finished early, around token %%s\\n\", __func__, \"%s\");\n" name;
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
pr " p = strchrnul (tok, ',');\n";
|
||||
pr " if (*p) next = p+1; else next = NULL;\n";
|
||||
pr " *p = '\\0';\n";
|
||||
(match coltype with
|
||||
| `String ->
|
||||
pr " r->%s = strdup (tok);\n" name;
|
||||
pr " if (r->%s == NULL) {\n" name;
|
||||
pr " perror (\"strdup\");\n";
|
||||
pr " return -1;\n";
|
||||
pr " }\n"
|
||||
| `UUID ->
|
||||
pr " for (i = j = 0; i < 32; ++j) {\n";
|
||||
pr " if (tok[j] == '\\0') {\n";
|
||||
pr " fprintf (stderr, \"%%s: failed to parse UUID from '%%s'\\n\", __func__, tok);\n";
|
||||
pr " return -1;\n";
|
||||
pr " } else if (tok[j] != '-')\n";
|
||||
pr " r->%s[i++] = tok[j];\n" name;
|
||||
pr " }\n";
|
||||
| `Bytes ->
|
||||
pr " if (sscanf (tok, \"%%\"SCNu64, &r->%s) != 1) {\n" name;
|
||||
pr " fprintf (stderr, \"%%s: failed to parse size '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
| `Int ->
|
||||
pr " if (sscanf (tok, \"%%\"SCNi64, &r->%s) != 1) {\n" name;
|
||||
pr " fprintf (stderr, \"%%s: failed to parse int '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
| `OptPercent ->
|
||||
pr " if (tok[0] == '\\0')\n";
|
||||
pr " r->%s = -1;\n" name;
|
||||
pr " else if (sscanf (tok, \"%%f\", &r->%s) != 1) {\n" name;
|
||||
pr " fprintf (stderr, \"%%s: failed to parse float '%%s' from token %%s\\n\", __func__, tok, \"%s\");\n" name;
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
);
|
||||
pr " tok = next;\n";
|
||||
) cols;
|
||||
|
||||
pr " if (tok != NULL) {\n";
|
||||
pr " fprintf (stderr, \"%%s: failed: extra tokens at end of string\\n\", __func__);\n";
|
||||
pr " return -1;\n";
|
||||
pr " }\n";
|
||||
pr " return 0;\n";
|
||||
pr "}\n";
|
||||
pr "\n";
|
||||
|
||||
pr "guestfs_lvm_int_%s_list *\n" typ;
|
||||
pr "parse_command_line_%ss (void)\n" typ;
|
||||
pr "{\n";
|
||||
pr " char *out, *err;\n";
|
||||
pr " char *p, *pend;\n";
|
||||
pr " int r, i;\n";
|
||||
pr " guestfs_lvm_int_%s_list *ret;\n" typ;
|
||||
pr " void *newp;\n";
|
||||
pr "\n";
|
||||
pr " ret = malloc (sizeof *ret);\n";
|
||||
pr " if (!ret) {\n";
|
||||
pr " reply_with_perror (\"malloc\");\n";
|
||||
pr " return NULL;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " ret->guestfs_lvm_int_%s_list_len = 0;\n" typ;
|
||||
pr " ret->guestfs_lvm_int_%s_list_val = NULL;\n" typ;
|
||||
pr "\n";
|
||||
pr " r = command (&out, &err,\n";
|
||||
pr " \"/sbin/lvm\", \"%ss\",\n" typ;
|
||||
pr " \"-o\", lvm_%s_cols, \"--unbuffered\", \"--noheadings\",\n" typ;
|
||||
pr " \"--nosuffix\", \"--separator\", \",\", \"--units\", \"b\", NULL);\n";
|
||||
pr " if (r == -1) {\n";
|
||||
pr " reply_with_error (\"%%s\", err);\n";
|
||||
pr " free (out);\n";
|
||||
pr " free (err);\n";
|
||||
pr " return NULL;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " free (err);\n";
|
||||
pr "\n";
|
||||
pr " /* Tokenize each line of the output. */\n";
|
||||
pr " p = out;\n";
|
||||
pr " i = 0;\n";
|
||||
pr " while (p) {\n";
|
||||
pr " pend = strchr (p, '\\n'); /* Get the next line of output. */\n";
|
||||
pr " if (pend) {\n";
|
||||
pr " *pend = '\\0';\n";
|
||||
pr " pend++;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " while (*p && isspace (*p)) /* Skip any leading whitespace. */\n";
|
||||
pr " p++;\n";
|
||||
pr "\n";
|
||||
pr " if (!*p) { /* Empty line? Skip it. */\n";
|
||||
pr " p = pend;\n";
|
||||
pr " continue;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " /* Allocate some space to store this next entry. */\n";
|
||||
pr " newp = realloc (ret->guestfs_lvm_int_%s_list_val,\n" typ;
|
||||
pr " sizeof (guestfs_lvm_int_%s) * (i+1));\n" typ;
|
||||
pr " if (newp == NULL) {\n";
|
||||
pr " reply_with_perror (\"realloc\");\n";
|
||||
pr " free (ret->guestfs_lvm_int_%s_list_val);\n" typ;
|
||||
pr " free (ret);\n";
|
||||
pr " free (out);\n";
|
||||
pr " return NULL;\n";
|
||||
pr " }\n";
|
||||
pr " ret->guestfs_lvm_int_%s_list_val = newp;\n" typ;
|
||||
pr "\n";
|
||||
pr " /* Tokenize the next entry. */\n";
|
||||
pr " r = lvm_tokenize_%s (p, &ret->guestfs_lvm_int_%s_list_val[i]);\n" typ typ;
|
||||
pr " if (r == -1) {\n";
|
||||
pr " reply_with_error (\"failed to parse output of '%ss' command\");\n" typ;
|
||||
pr " free (ret->guestfs_lvm_int_%s_list_val);\n" typ;
|
||||
pr " free (ret);\n";
|
||||
pr " free (out);\n";
|
||||
pr " return NULL;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " ++i;\n";
|
||||
pr " p = pend;\n";
|
||||
pr " }\n";
|
||||
pr "\n";
|
||||
pr " ret->guestfs_lvm_int_%s_list_len = i;\n" typ;
|
||||
pr "\n";
|
||||
pr " free (out);\n";
|
||||
pr " return ret;\n";
|
||||
pr "}\n"
|
||||
|
||||
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols]
|
||||
|
||||
(* Generate a lot of different functions for guestfish. *)
|
||||
and generate_fish_cmds () =
|
||||
@@ -611,7 +1022,9 @@ and generate_fish_cmds () =
|
||||
pr "#include <stdio.h>\n";
|
||||
pr "#include <stdlib.h>\n";
|
||||
pr "#include <string.h>\n";
|
||||
pr "#include <inttypes.h>\n";
|
||||
pr "\n";
|
||||
pr "#include <guestfs.h>\n";
|
||||
pr "#include \"fish.h\"\n";
|
||||
pr "\n";
|
||||
|
||||
@@ -669,6 +1082,45 @@ FTP."
|
||||
pr "}\n";
|
||||
pr "\n";
|
||||
|
||||
(* print_{pv,vg,lv}_list functions *)
|
||||
List.iter (
|
||||
function
|
||||
| typ, cols ->
|
||||
pr "static void print_%s (struct guestfs_lvm_%s *%s)\n" typ typ typ;
|
||||
pr "{\n";
|
||||
pr " int i;\n";
|
||||
pr "\n";
|
||||
List.iter (
|
||||
function
|
||||
| name, `String ->
|
||||
pr " printf (\"%s: %%s\\n\", %s->%s);\n" name typ name
|
||||
| name, `UUID ->
|
||||
pr " printf (\"%s: \");\n" name;
|
||||
pr " for (i = 0; i < 32; ++i)\n";
|
||||
pr " printf (\"%%c\", %s->%s[i]);\n" typ name;
|
||||
pr " printf (\"\\n\");\n"
|
||||
| name, `Bytes ->
|
||||
pr " printf (\"%s: %%\" PRIu64 \"\\n\", %s->%s);\n" name typ name
|
||||
| name, `Int ->
|
||||
pr " printf (\"%s: %%\" PRIi64 \"\\n\", %s->%s);\n" name typ name
|
||||
| name, `OptPercent ->
|
||||
pr " if (%s->%s >= 0) printf (\"%s: %%g %%%%\\n\", %s->%s);\n"
|
||||
typ name name typ name;
|
||||
pr " else printf (\"%s: \\n\");\n" name
|
||||
) cols;
|
||||
pr "}\n";
|
||||
pr "\n";
|
||||
pr "static void print_%s_list (struct guestfs_lvm_%s_list *%ss)\n"
|
||||
typ typ typ;
|
||||
pr "{\n";
|
||||
pr " int i;\n";
|
||||
pr "\n";
|
||||
pr " for (i = 0; i < %ss->len; ++i)\n" typ;
|
||||
pr " print_%s (&%ss->val[i]);\n" typ typ;
|
||||
pr "}\n";
|
||||
pr "\n";
|
||||
) ["pv", pv_cols; "vg", vg_cols; "lv", lv_cols];
|
||||
|
||||
(* run_<action> actions *)
|
||||
List.iter (
|
||||
fun (name, style, _, _, _, _) ->
|
||||
@@ -678,6 +1130,9 @@ FTP."
|
||||
| Err -> pr " int r;\n"
|
||||
| RString _ -> pr " char *r;\n"
|
||||
| RStringList _ -> pr " char **r;\n"
|
||||
| RPVList _ -> pr " struct guestfs_lvm_pv_list *r;\n"
|
||||
| RVGList _ -> pr " struct guestfs_lvm_vg_list *r;\n"
|
||||
| RLVList _ -> pr " struct guestfs_lvm_lv_list *r;\n"
|
||||
);
|
||||
iter_args (
|
||||
function
|
||||
@@ -716,6 +1171,21 @@ FTP."
|
||||
pr " print_strings (r);\n";
|
||||
pr " free_strings (r);\n";
|
||||
pr " return 0;\n"
|
||||
| RPVList _ ->
|
||||
pr " if (r == NULL) return -1;\n";
|
||||
pr " print_pv_list (r);\n";
|
||||
pr " guestfs_free_lvm_pv_list (r);\n";
|
||||
pr " return 0;\n"
|
||||
| RVGList _ ->
|
||||
pr " if (r == NULL) return -1;\n";
|
||||
pr " print_vg_list (r);\n";
|
||||
pr " guestfs_free_lvm_vg_list (r);\n";
|
||||
pr " return 0;\n"
|
||||
| RLVList _ ->
|
||||
pr " if (r == NULL) return -1;\n";
|
||||
pr " print_lv_list (r);\n";
|
||||
pr " guestfs_free_lvm_lv_list (r);\n";
|
||||
pr " return 0;\n"
|
||||
);
|
||||
pr "}\n";
|
||||
pr "\n"
|
||||
@@ -745,7 +1215,7 @@ FTP."
|
||||
|
||||
(* Generate a C function prototype. *)
|
||||
and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
|
||||
?(single_line = false) ?(newline = false)
|
||||
?(single_line = false) ?(newline = false) ?(in_daemon = false)
|
||||
?handle name style =
|
||||
if extern then pr "extern ";
|
||||
if static then pr "static ";
|
||||
@@ -753,6 +1223,15 @@ and generate_prototype ?(extern = true) ?(static = false) ?(semicolon = true)
|
||||
| Err -> pr "int "
|
||||
| RString _ -> pr "char *"
|
||||
| RStringList _ -> pr "char **"
|
||||
| RPVList _ ->
|
||||
if not in_daemon then pr "struct guestfs_lvm_pv_list *"
|
||||
else pr "guestfs_lvm_int_pv_list *"
|
||||
| RVGList _ ->
|
||||
if not in_daemon then pr "struct guestfs_lvm_vg_list *"
|
||||
else pr "guestfs_lvm_int_vg_list *"
|
||||
| RLVList _ ->
|
||||
if not in_daemon then pr "struct guestfs_lvm_lv_list *"
|
||||
else pr "guestfs_lvm_int_lv_list *"
|
||||
);
|
||||
pr "%s (" name;
|
||||
let comma = ref false in
|
||||
@@ -810,6 +1289,10 @@ let () =
|
||||
generate_xdr ();
|
||||
close ();
|
||||
|
||||
let close = output_to "src/guestfs-structs.h" in
|
||||
generate_structs_h ();
|
||||
close ();
|
||||
|
||||
let close = output_to "src/guestfs-actions.h" in
|
||||
generate_actions_h ();
|
||||
close ();
|
||||
@@ -830,6 +1313,10 @@ let () =
|
||||
generate_fish_cmds ();
|
||||
close ();
|
||||
|
||||
let close = output_to "guestfs-structs.pod" in
|
||||
generate_structs_pod ();
|
||||
close ();
|
||||
|
||||
let close = output_to "guestfs-actions.pod" in
|
||||
generate_pod ();
|
||||
generate_actions_pod ();
|
||||
close ()
|
||||
|
||||
@@ -595,3 +595,216 @@ 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);
|
||||
}
|
||||
|
||||
struct guestfs_lvm_pv_list *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 */
|
||||
return safe_memdup (g, &rv.ret.physvols, sizeof (rv.ret.physvols));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct guestfs_lvm_vg_list *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 */
|
||||
return safe_memdup (g, &rv.ret.volgroups, sizeof (rv.ret.volgroups));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct guestfs_lvm_lv_list *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 */
|
||||
return safe_memdup (g, &rv.ret.logvols, sizeof (rv.ret.logvols));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,3 +27,6 @@ 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 struct guestfs_lvm_pv_list *guestfs_pvs (guestfs_h *handle);
|
||||
extern struct guestfs_lvm_vg_list *guestfs_vgs (guestfs_h *handle);
|
||||
extern struct guestfs_lvm_lv_list *guestfs_lvs (guestfs_h *handle);
|
||||
|
||||
94
src/guestfs-structs.h
Normal file
94
src/guestfs-structs.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* libguestfs generated file
|
||||
* WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'.
|
||||
* ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
struct guestfs_lvm_pv {
|
||||
char *pv_name;
|
||||
char pv_uuid[32]; /* this is NOT nul-terminated, be careful when printing */
|
||||
char *pv_fmt;
|
||||
uint64_t pv_size;
|
||||
uint64_t dev_size;
|
||||
uint64_t pv_free;
|
||||
uint64_t pv_used;
|
||||
char *pv_attr;
|
||||
int64_t pv_pe_count;
|
||||
int64_t pv_pe_alloc_count;
|
||||
char *pv_tags;
|
||||
uint64_t pe_start;
|
||||
int64_t pv_mda_count;
|
||||
uint64_t pv_mda_free;
|
||||
};
|
||||
|
||||
struct guestfs_lvm_pv_list {
|
||||
uint32_t len;
|
||||
struct guestfs_lvm_pv *val;
|
||||
};
|
||||
|
||||
struct guestfs_lvm_vg {
|
||||
char *vg_name;
|
||||
char vg_uuid[32]; /* this is NOT nul-terminated, be careful when printing */
|
||||
char *vg_fmt;
|
||||
char *vg_attr;
|
||||
uint64_t vg_size;
|
||||
uint64_t vg_free;
|
||||
char *vg_sysid;
|
||||
uint64_t vg_extent_size;
|
||||
int64_t vg_extent_count;
|
||||
int64_t vg_free_count;
|
||||
int64_t max_lv;
|
||||
int64_t max_pv;
|
||||
int64_t pv_count;
|
||||
int64_t lv_count;
|
||||
int64_t snap_count;
|
||||
int64_t vg_seqno;
|
||||
char *vg_tags;
|
||||
int64_t vg_mda_count;
|
||||
uint64_t vg_mda_free;
|
||||
};
|
||||
|
||||
struct guestfs_lvm_vg_list {
|
||||
uint32_t len;
|
||||
struct guestfs_lvm_vg *val;
|
||||
};
|
||||
|
||||
struct guestfs_lvm_lv {
|
||||
char *lv_name;
|
||||
char lv_uuid[32]; /* this is NOT nul-terminated, be careful when printing */
|
||||
char *lv_attr;
|
||||
int64_t lv_major;
|
||||
int64_t lv_minor;
|
||||
int64_t lv_kernel_major;
|
||||
int64_t lv_kernel_minor;
|
||||
uint64_t lv_size;
|
||||
int64_t seg_count;
|
||||
char *origin;
|
||||
float snap_percent; /* [0..100] or -1 */
|
||||
float copy_percent; /* [0..100] or -1 */
|
||||
char *move_pv;
|
||||
char *lv_tags;
|
||||
char *mirror_log;
|
||||
char *modules;
|
||||
};
|
||||
|
||||
struct guestfs_lvm_lv_list {
|
||||
uint32_t len;
|
||||
struct guestfs_lvm_lv *val;
|
||||
};
|
||||
|
||||
@@ -58,9 +58,10 @@
|
||||
|
||||
static void error (guestfs_h *g, const char *fs, ...);
|
||||
static void perrorf (guestfs_h *g, const char *fs, ...);
|
||||
static void *safe_malloc (guestfs_h *g, int nbytes);
|
||||
static void *safe_malloc (guestfs_h *g, size_t nbytes);
|
||||
static void *safe_realloc (guestfs_h *g, void *ptr, int nbytes);
|
||||
static char *safe_strdup (guestfs_h *g, const char *str);
|
||||
static void *safe_memdup (guestfs_h *g, void *ptr, size_t size);
|
||||
|
||||
static void default_error_cb (guestfs_h *g, void *data, const char *msg);
|
||||
static void stdout_event (void *data, int watch, int fd, int events);
|
||||
@@ -328,7 +329,7 @@ perrorf (guestfs_h *g, const char *fs, ...)
|
||||
}
|
||||
|
||||
static void *
|
||||
safe_malloc (guestfs_h *g, int nbytes)
|
||||
safe_malloc (guestfs_h *g, size_t nbytes)
|
||||
{
|
||||
void *ptr = malloc (nbytes);
|
||||
if (!ptr) g->abort_cb ();
|
||||
@@ -351,6 +352,15 @@ safe_strdup (guestfs_h *g, const char *str)
|
||||
return s;
|
||||
}
|
||||
|
||||
static void *
|
||||
safe_memdup (guestfs_h *g, void *ptr, size_t size)
|
||||
{
|
||||
void *p = malloc (size);
|
||||
if (!p) g->abort_cb ();
|
||||
memcpy (p, ptr, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb)
|
||||
{
|
||||
@@ -1019,6 +1029,28 @@ sock_read_event (void *data, int watch, int fd, int events)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Got the full message, begin processing it. */
|
||||
if (g->verbose) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < g->msg_in_size; i += 16) {
|
||||
printf ("%04x: ", i);
|
||||
for (j = i; j < MIN (i+16, g->msg_in_size); ++j)
|
||||
printf ("%02x ", (unsigned char) g->msg_in[j]);
|
||||
for (; j < i+16; ++j)
|
||||
printf (" ");
|
||||
printf ("|");
|
||||
for (j = i; j < MIN (i+16, g->msg_in_size); ++j)
|
||||
if (isprint (g->msg_in[j]))
|
||||
printf ("%c", g->msg_in[j]);
|
||||
else
|
||||
printf (".");
|
||||
for (; j < i+16; ++j)
|
||||
printf (" ");
|
||||
printf ("|\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Not in the expected state. */
|
||||
if (g->state != BUSY)
|
||||
error (g, "state %d != BUSY", g->state);
|
||||
@@ -1231,6 +1263,31 @@ check_reply_header (guestfs_h *g,
|
||||
*/
|
||||
#include "guestfs-actions.c"
|
||||
|
||||
/* Structure-freeing functions. These rely on the fact that the
|
||||
* structure format is identical to the XDR format. See note in
|
||||
* generator.ml.
|
||||
*/
|
||||
void
|
||||
guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *x)
|
||||
{
|
||||
xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_pv_list, (char *) x);
|
||||
free (x);
|
||||
}
|
||||
|
||||
void
|
||||
guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *x)
|
||||
{
|
||||
xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_vg_list, (char *) x);
|
||||
free (x);
|
||||
}
|
||||
|
||||
void
|
||||
guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *x)
|
||||
{
|
||||
xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_lv_list, (char *) x);
|
||||
free (x);
|
||||
}
|
||||
|
||||
/* This is the default main loop implementation, using select(2). */
|
||||
|
||||
struct handle_cb_data {
|
||||
|
||||
@@ -59,8 +59,13 @@ extern int guestfs_get_autosync (guestfs_h *g);
|
||||
extern void guestfs_set_path (guestfs_h *g, const char *path);
|
||||
extern const char *guestfs_get_path (guestfs_h *g);
|
||||
|
||||
#include <guestfs-structs.h>
|
||||
#include <guestfs-actions.h>
|
||||
|
||||
extern void guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *);
|
||||
extern void guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *);
|
||||
extern void guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *);
|
||||
|
||||
/* Low-level event API. */
|
||||
typedef void (*guestfs_reply_cb) (guestfs_h *g, void *data, XDR *xdr);
|
||||
typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *data, char *buf, int len);
|
||||
|
||||
@@ -15,6 +15,164 @@ xdr_str (XDR *xdrs, str *objp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_pv (XDR *xdrs, guestfs_lvm_int_pv *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
if (!xdr_string (xdrs, &objp->pv_name, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_opaque (xdrs, objp->pv_uuid, 32))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->pv_fmt, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_size))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->dev_size))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_free))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_used))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->pv_attr, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_pe_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_pe_alloc_count))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->pv_tags, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pe_start))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_mda_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_mda_free))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_pv_list (XDR *xdrs, guestfs_lvm_int_pv_list *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->guestfs_lvm_int_pv_list_val, (u_int *) &objp->guestfs_lvm_int_pv_list_len, ~0,
|
||||
sizeof (guestfs_lvm_int_pv), (xdrproc_t) xdr_guestfs_lvm_int_pv))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_vg (XDR *xdrs, guestfs_lvm_int_vg *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
if (!xdr_string (xdrs, &objp->vg_name, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_opaque (xdrs, objp->vg_uuid, 32))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->vg_fmt, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->vg_attr, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_size))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_free))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->vg_sysid, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_extent_size))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_extent_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_free_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->max_lv))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->max_pv))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->pv_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->snap_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_seqno))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->vg_tags, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_mda_count))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->vg_mda_free))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_vg_list (XDR *xdrs, guestfs_lvm_int_vg_list *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->guestfs_lvm_int_vg_list_val, (u_int *) &objp->guestfs_lvm_int_vg_list_len, ~0,
|
||||
sizeof (guestfs_lvm_int_vg), (xdrproc_t) xdr_guestfs_lvm_int_vg))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_lv (XDR *xdrs, guestfs_lvm_int_lv *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
int i;
|
||||
if (!xdr_string (xdrs, &objp->lv_name, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_opaque (xdrs, objp->lv_uuid, 32))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->lv_attr, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_major))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_minor))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_kernel_major))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_kernel_minor))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->lv_size))
|
||||
return FALSE;
|
||||
if (!xdr_quad_t (xdrs, &objp->seg_count))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->origin, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_float (xdrs, &objp->snap_percent))
|
||||
return FALSE;
|
||||
if (!xdr_float (xdrs, &objp->copy_percent))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->move_pv, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->lv_tags, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->mirror_log, ~0))
|
||||
return FALSE;
|
||||
if (!xdr_string (xdrs, &objp->modules, ~0))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvm_int_lv_list (XDR *xdrs, guestfs_lvm_int_lv_list *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_array (xdrs, (char **)&objp->guestfs_lvm_int_lv_list_val, (u_int *) &objp->guestfs_lvm_int_lv_list_len, ~0,
|
||||
sizeof (guestfs_lvm_int_lv), (xdrproc_t) xdr_guestfs_lvm_int_lv))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_mount_args (XDR *xdrs, guestfs_mount_args *objp)
|
||||
{
|
||||
@@ -120,6 +278,36 @@ xdr_guestfs_list_partitions_ret (XDR *xdrs, guestfs_list_partitions_ret *objp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_pvs_ret (XDR *xdrs, guestfs_pvs_ret *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_guestfs_lvm_int_pv_list (xdrs, &objp->physvols))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_vgs_ret (XDR *xdrs, guestfs_vgs_ret *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_guestfs_lvm_int_vg_list (xdrs, &objp->volgroups))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_lvs_ret (XDR *xdrs, guestfs_lvs_ret *objp)
|
||||
{
|
||||
register int32_t *buf;
|
||||
|
||||
if (!xdr_guestfs_lvm_int_lv_list (xdrs, &objp->logvols))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
xdr_guestfs_procedure (XDR *xdrs, guestfs_procedure *objp)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,82 @@ extern "C" {
|
||||
|
||||
typedef char *str;
|
||||
|
||||
struct guestfs_lvm_int_pv {
|
||||
char *pv_name;
|
||||
char pv_uuid[32];
|
||||
char *pv_fmt;
|
||||
quad_t pv_size;
|
||||
quad_t dev_size;
|
||||
quad_t pv_free;
|
||||
quad_t pv_used;
|
||||
char *pv_attr;
|
||||
quad_t pv_pe_count;
|
||||
quad_t pv_pe_alloc_count;
|
||||
char *pv_tags;
|
||||
quad_t pe_start;
|
||||
quad_t pv_mda_count;
|
||||
quad_t pv_mda_free;
|
||||
};
|
||||
typedef struct guestfs_lvm_int_pv guestfs_lvm_int_pv;
|
||||
|
||||
typedef struct {
|
||||
u_int guestfs_lvm_int_pv_list_len;
|
||||
guestfs_lvm_int_pv *guestfs_lvm_int_pv_list_val;
|
||||
} guestfs_lvm_int_pv_list;
|
||||
|
||||
struct guestfs_lvm_int_vg {
|
||||
char *vg_name;
|
||||
char vg_uuid[32];
|
||||
char *vg_fmt;
|
||||
char *vg_attr;
|
||||
quad_t vg_size;
|
||||
quad_t vg_free;
|
||||
char *vg_sysid;
|
||||
quad_t vg_extent_size;
|
||||
quad_t vg_extent_count;
|
||||
quad_t vg_free_count;
|
||||
quad_t max_lv;
|
||||
quad_t max_pv;
|
||||
quad_t pv_count;
|
||||
quad_t lv_count;
|
||||
quad_t snap_count;
|
||||
quad_t vg_seqno;
|
||||
char *vg_tags;
|
||||
quad_t vg_mda_count;
|
||||
quad_t vg_mda_free;
|
||||
};
|
||||
typedef struct guestfs_lvm_int_vg guestfs_lvm_int_vg;
|
||||
|
||||
typedef struct {
|
||||
u_int guestfs_lvm_int_vg_list_len;
|
||||
guestfs_lvm_int_vg *guestfs_lvm_int_vg_list_val;
|
||||
} guestfs_lvm_int_vg_list;
|
||||
|
||||
struct guestfs_lvm_int_lv {
|
||||
char *lv_name;
|
||||
char lv_uuid[32];
|
||||
char *lv_attr;
|
||||
quad_t lv_major;
|
||||
quad_t lv_minor;
|
||||
quad_t lv_kernel_major;
|
||||
quad_t lv_kernel_minor;
|
||||
quad_t lv_size;
|
||||
quad_t seg_count;
|
||||
char *origin;
|
||||
float snap_percent;
|
||||
float copy_percent;
|
||||
char *move_pv;
|
||||
char *lv_tags;
|
||||
char *mirror_log;
|
||||
char *modules;
|
||||
};
|
||||
typedef struct guestfs_lvm_int_lv guestfs_lvm_int_lv;
|
||||
|
||||
typedef struct {
|
||||
u_int guestfs_lvm_int_lv_list_len;
|
||||
guestfs_lvm_int_lv *guestfs_lvm_int_lv_list_val;
|
||||
} guestfs_lvm_int_lv_list;
|
||||
|
||||
struct guestfs_mount_args {
|
||||
char *device;
|
||||
char *mountpoint;
|
||||
@@ -76,6 +152,21 @@ struct guestfs_list_partitions_ret {
|
||||
};
|
||||
typedef struct guestfs_list_partitions_ret guestfs_list_partitions_ret;
|
||||
|
||||
struct guestfs_pvs_ret {
|
||||
guestfs_lvm_int_pv_list physvols;
|
||||
};
|
||||
typedef struct guestfs_pvs_ret guestfs_pvs_ret;
|
||||
|
||||
struct guestfs_vgs_ret {
|
||||
guestfs_lvm_int_vg_list volgroups;
|
||||
};
|
||||
typedef struct guestfs_vgs_ret guestfs_vgs_ret;
|
||||
|
||||
struct guestfs_lvs_ret {
|
||||
guestfs_lvm_int_lv_list logvols;
|
||||
};
|
||||
typedef struct guestfs_lvs_ret guestfs_lvs_ret;
|
||||
|
||||
enum guestfs_procedure {
|
||||
GUESTFS_PROC_MOUNT = 1,
|
||||
GUESTFS_PROC_SYNC = 2,
|
||||
@@ -85,7 +176,10 @@ enum guestfs_procedure {
|
||||
GUESTFS_PROC_LS = 6,
|
||||
GUESTFS_PROC_LIST_DEVICES = 7,
|
||||
GUESTFS_PROC_LIST_PARTITIONS = 8,
|
||||
GUESTFS_PROC_dummy = 8 + 1,
|
||||
GUESTFS_PROC_PVS = 9,
|
||||
GUESTFS_PROC_VGS = 10,
|
||||
GUESTFS_PROC_LVS = 11,
|
||||
GUESTFS_PROC_dummy = 11 + 1,
|
||||
};
|
||||
typedef enum guestfs_procedure guestfs_procedure;
|
||||
#define GUESTFS_MESSAGE_MAX 4194304
|
||||
@@ -124,6 +218,12 @@ typedef struct guestfs_message_header guestfs_message_header;
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern bool_t xdr_str (XDR *, str*);
|
||||
extern bool_t xdr_guestfs_lvm_int_pv (XDR *, guestfs_lvm_int_pv*);
|
||||
extern bool_t xdr_guestfs_lvm_int_pv_list (XDR *, guestfs_lvm_int_pv_list*);
|
||||
extern bool_t xdr_guestfs_lvm_int_vg (XDR *, guestfs_lvm_int_vg*);
|
||||
extern bool_t xdr_guestfs_lvm_int_vg_list (XDR *, guestfs_lvm_int_vg_list*);
|
||||
extern bool_t xdr_guestfs_lvm_int_lv (XDR *, guestfs_lvm_int_lv*);
|
||||
extern bool_t xdr_guestfs_lvm_int_lv_list (XDR *, guestfs_lvm_int_lv_list*);
|
||||
extern bool_t xdr_guestfs_mount_args (XDR *, guestfs_mount_args*);
|
||||
extern bool_t xdr_guestfs_touch_args (XDR *, guestfs_touch_args*);
|
||||
extern bool_t xdr_guestfs_cat_args (XDR *, guestfs_cat_args*);
|
||||
@@ -134,6 +234,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_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*);
|
||||
@@ -142,6 +245,12 @@ extern bool_t xdr_guestfs_message_header (XDR *, guestfs_message_header*);
|
||||
|
||||
#else /* K&R C */
|
||||
extern bool_t xdr_str ();
|
||||
extern bool_t xdr_guestfs_lvm_int_pv ();
|
||||
extern bool_t xdr_guestfs_lvm_int_pv_list ();
|
||||
extern bool_t xdr_guestfs_lvm_int_vg ();
|
||||
extern bool_t xdr_guestfs_lvm_int_vg_list ();
|
||||
extern bool_t xdr_guestfs_lvm_int_lv ();
|
||||
extern bool_t xdr_guestfs_lvm_int_lv_list ();
|
||||
extern bool_t xdr_guestfs_mount_args ();
|
||||
extern bool_t xdr_guestfs_touch_args ();
|
||||
extern bool_t xdr_guestfs_cat_args ();
|
||||
@@ -152,6 +261,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_procedure ();
|
||||
extern bool_t xdr_guestfs_message_direction ();
|
||||
extern bool_t xdr_guestfs_message_status ();
|
||||
|
||||
@@ -21,6 +21,70 @@
|
||||
|
||||
typedef string str<>;
|
||||
|
||||
struct guestfs_lvm_int_pv {
|
||||
string pv_name<>;
|
||||
opaque pv_uuid[32];
|
||||
string pv_fmt<>;
|
||||
hyper pv_size;
|
||||
hyper dev_size;
|
||||
hyper pv_free;
|
||||
hyper pv_used;
|
||||
string pv_attr<>;
|
||||
hyper pv_pe_count;
|
||||
hyper pv_pe_alloc_count;
|
||||
string pv_tags<>;
|
||||
hyper pe_start;
|
||||
hyper pv_mda_count;
|
||||
hyper pv_mda_free;
|
||||
};
|
||||
|
||||
typedef struct guestfs_lvm_int_pv guestfs_lvm_int_pv_list<>;
|
||||
|
||||
struct guestfs_lvm_int_vg {
|
||||
string vg_name<>;
|
||||
opaque vg_uuid[32];
|
||||
string vg_fmt<>;
|
||||
string vg_attr<>;
|
||||
hyper vg_size;
|
||||
hyper vg_free;
|
||||
string vg_sysid<>;
|
||||
hyper vg_extent_size;
|
||||
hyper vg_extent_count;
|
||||
hyper vg_free_count;
|
||||
hyper max_lv;
|
||||
hyper max_pv;
|
||||
hyper pv_count;
|
||||
hyper lv_count;
|
||||
hyper snap_count;
|
||||
hyper vg_seqno;
|
||||
string vg_tags<>;
|
||||
hyper vg_mda_count;
|
||||
hyper vg_mda_free;
|
||||
};
|
||||
|
||||
typedef struct guestfs_lvm_int_vg guestfs_lvm_int_vg_list<>;
|
||||
|
||||
struct guestfs_lvm_int_lv {
|
||||
string lv_name<>;
|
||||
opaque lv_uuid[32];
|
||||
string lv_attr<>;
|
||||
hyper lv_major;
|
||||
hyper lv_minor;
|
||||
hyper lv_kernel_major;
|
||||
hyper lv_kernel_minor;
|
||||
hyper lv_size;
|
||||
hyper seg_count;
|
||||
string origin<>;
|
||||
float snap_percent;
|
||||
float copy_percent;
|
||||
string move_pv<>;
|
||||
string lv_tags<>;
|
||||
string mirror_log<>;
|
||||
string modules<>;
|
||||
};
|
||||
|
||||
typedef struct guestfs_lvm_int_lv guestfs_lvm_int_lv_list<>;
|
||||
|
||||
/* guestfs_mount */
|
||||
|
||||
struct guestfs_mount_args {
|
||||
@@ -78,6 +142,24 @@ struct guestfs_list_partitions_ret {
|
||||
str partitions<>;
|
||||
};
|
||||
|
||||
/* guestfs_pvs */
|
||||
|
||||
struct guestfs_pvs_ret {
|
||||
guestfs_lvm_int_pv_list physvols;
|
||||
};
|
||||
|
||||
/* guestfs_vgs */
|
||||
|
||||
struct guestfs_vgs_ret {
|
||||
guestfs_lvm_int_vg_list volgroups;
|
||||
};
|
||||
|
||||
/* guestfs_lvs */
|
||||
|
||||
struct guestfs_lvs_ret {
|
||||
guestfs_lvm_int_lv_list logvols;
|
||||
};
|
||||
|
||||
enum guestfs_procedure {
|
||||
GUESTFS_PROC_MOUNT = 1,
|
||||
GUESTFS_PROC_SYNC = 2,
|
||||
@@ -87,6 +169,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_dummy
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user