From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: Jes.Sorensen@redhat.com
Cc: lcapitulino@redhat.com, qemu-devel@nongnu.org,
stefanha@linux.vnet.ibm.com, agl@us.ibm.com
Subject: [Qemu-devel] Re: [PATCH 1/2] Add virtagent file system freeze/thaw
Date: Thu, 03 Feb 2011 12:11:35 -0600 [thread overview]
Message-ID: <4D4AEFD7.8060808@linux.vnet.ibm.com> (raw)
In-Reply-To: <1296636160-991-2-git-send-email-Jes.Sorensen@redhat.com>
On 02/02/2011 02:42 AM, Jes.Sorensen@redhat.com wrote:
> From: Jes Sorensen<Jes.Sorensen@redhat.com>
>
> Implement freeze/thaw support in the guest, allowing the host to
> request the guest freezes all it's file systems before a live snapshot
> is performed.
> - fsfreeze(): Walk the list of mounted local real file systems,
> and freeze them.
> - fsthaw(): Walk the list of previously frozen file systems and
> thaw them.
> - fsstatus(): Return the current status of freeze/thaw. The host must
> poll this function, in case fsfreeze() returned with a
> timeout, to wait for the operation to finish.
>
> Signed-off-by: Jes Sorensen<Jes.Sorensen@redhat.com>
> ---
> virtagent-common.h | 8 ++
> virtagent-server.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 198 insertions(+), 0 deletions(-)
>
> diff --git a/virtagent-common.h b/virtagent-common.h
> index 5d8f5c1..7c6d9ef 100644
> --- a/virtagent-common.h
> +++ b/virtagent-common.h
> @@ -61,6 +61,14 @@ typedef struct VAContext {
> const char *channel_path;
> } VAContext;
>
> +enum va_fsfreeze_status {
> + FREEZE_ERROR = -1,
> + FREEZE_THAWED = 0,
> + FREEZE_INPROGRESS = 1,
> + FREEZE_FROZEN = 2,
> + FREEZE_THAWINPROGRESS = 3,
> +};
> +
> enum va_job_status {
> VA_JOB_STATUS_PENDING = 0,
> VA_JOB_STATUS_OK,
> diff --git a/virtagent-server.c b/virtagent-server.c
> index 7bb35b2..ffbe163 100644
> --- a/virtagent-server.c
> +++ b/virtagent-server.c
> @@ -14,6 +14,10 @@
> #include<syslog.h>
> #include "qemu_socket.h"
> #include "virtagent-common.h"
> +#include<mntent.h>
> +#include<sys/types.h>
> +#include<sys/ioctl.h>
> +#include<linux/fs.h>
>
> static VAServerData *va_server_data;
> static bool va_enable_syslog = false; /* enable syslog'ing of RPCs */
> @@ -217,6 +221,186 @@ static xmlrpc_value *va_hello(xmlrpc_env *env,
> return result;
> }
>
> +
> +/*
> + * Walk the mount table and build a list of local file systems
> + */
> +
> +struct direntry {
> + char *dirname;
> + char *devtype;
> + struct direntry *next;
> +};
> +
> +static struct direntry *va_mount_list;
> +static int va_fsfreeze_status;
And what I meant in the last RFC about using "objects" was to
encapsulate global state information for a particular group of commands
in single data type/variable. We're gonna end up with a similar set of
variables for stateful RPCs like copyfile and potentially a few for
things like spice. So to avoid having things get too cluttered up I'd
prefer something like, in this particular case:
typedef struct VAFSFreezeState {
struct direntry *mount_list;
int status;
} VAFSFeezeState;
static VAFSFreezeState va_fsfreeze_state;
> +
> +static int build_mount_list(void)
> +{
> + struct mntent *mnt;
> + struct direntry *entry;
> + struct direntry *next;
> + char const *mtab = MOUNTED;
> + FILE *fp;
> +
> + fp = setmntent(mtab, "r");
> + if (!fp) {
> + fprintf(stderr, "unable to read mtab\n");
> + goto fail;
> + }
You have tabs instead of spaces here
> +
> + while ((mnt = getmntent(fp))) {
> + /*
> + * An entry which device name doesn't start with a '/' is
> + * either a dummy file system or a network file system.
> + * Add special handling for smbfs and cifs as is done by
> + * coreutils as well.
> + */
> + if ((mnt->mnt_fsname[0] != '/') ||
> + (strcmp(mnt->mnt_type, "smbfs") == 0) ||
> + (strcmp(mnt->mnt_type, "cifs") == 0)) {
> + continue;
> + }
> +
> + entry = qemu_malloc(sizeof(struct direntry));
> + entry->dirname = qemu_strdup(mnt->mnt_dir);
> + entry->devtype = qemu_strdup(mnt->mnt_type);
> + entry->next = va_mount_list;
> +
> + va_mount_list = entry;
Here too
> + }
> +
> + endmntent(fp);
> +
> + return 0;
> +
> +fail:
> + while(va_mount_list) {
> + next = va_mount_list->next;
Here too. Might be some other spots but you get the point :)
> + qemu_free(va_mount_list->dirname);
> + qemu_free(va_mount_list->devtype);
> + qemu_free(va_mount_list);
> + va_mount_list = next;
> + }
> +
> + return -1;
> +}
> +
> +/*
> + * va_fsfreeze(): Walk list of mounted file systems in the guest, and
> + * freeze the ones which are real local file systems.
> + * rpc return values: Number of file systems frozen, -1 on error.
> + */
> +static xmlrpc_value *va_fsfreeze(xmlrpc_env *env,
> + xmlrpc_value *params,
> + void *user_data)
> +{
> + xmlrpc_int32 ret = 0, i = 0;
> + xmlrpc_value *result;
> + struct direntry *entry;
> + int fd;
> + SLOG("va_fsfreeze()");
> +
> + if (va_fsfreeze_status != FREEZE_THAWED) {
> + ret = 0;
> + goto out;
> + }
> +
> + ret = build_mount_list();
> + if (ret< 0) {
> + goto out;
> + }
> +
> + va_fsfreeze_status = FREEZE_INPROGRESS;
> +
> + entry = va_mount_list;
> + while(entry) {
> + fd = qemu_open(entry->dirname, O_RDONLY);
> + if (fd == -1) {
> + ret = errno;
> + goto error;
> + }
> + ret = ioctl(fd, FIFREEZE);
> + close(fd);
> + if (ret< 0&& ret != EOPNOTSUPP) {
> + goto error;
> + }
> +
> + entry = entry->next;
> + i++;
> + }
> +
> + va_fsfreeze_status = FREEZE_FROZEN;
> + ret = i;
> +out:
> + result = xmlrpc_build_value(env, "i", ret);
> + return result;
> +error:
> + if (i> 0) {
> + va_fsfreeze_status = FREEZE_ERROR;
> + }
> + goto out;
> +}
> +
> +/*
> + * va_fsthaw(): Walk list of frozen file systems in the guest, and
> + * thaw them.
> + * rpc return values: Number of file systems thawed on success, -1 on error.
> + */
> +static xmlrpc_value *va_fsthaw(xmlrpc_env *env,
> + xmlrpc_value *params,
> + void *user_data)
> +{
> + xmlrpc_int32 ret;
> + xmlrpc_value *result;
> + struct direntry *entry;
> + int fd, i = 0;
> + SLOG("va_fsthaw()");
> +
> + if (va_fsfreeze_status != FREEZE_FROZEN) {
> + ret = 0;
> + goto out;
> + }
> +
> + while((entry = va_mount_list)) {
> + fd = qemu_open(entry->dirname, O_RDONLY);
> + if (fd == -1) {
> + ret = -1;
> + goto out;
> + }
> + ret = ioctl(fd, FITHAW);
> + close(fd);
> + if (ret< 0&& ret != EOPNOTSUPP) {
> + ret = -1;
> + goto out;
> + }
> +
> + va_mount_list = entry->next;
> + qemu_free(entry->dirname);
> + qemu_free(entry->devtype);
> + qemu_free(entry);
> + i++;
> + }
> +
> + va_fsfreeze_status = FREEZE_THAWED;
> + ret = i;
> +out:
> + result = xmlrpc_build_value(env, "i", ret);
> + return result;
> +}
> +
> +/* va_fsstatus(): Return status of freeze/thaw
> + * rpc return values: fsfreeze_status
> + */
> +static xmlrpc_value *va_fsstatus(xmlrpc_env *env,
> + xmlrpc_value *params,
> + void *user_data)
> +{
> + xmlrpc_value *result = xmlrpc_build_value(env, "i", va_fsfreeze_status);
> + SLOG("va_fsstatus()");
> + return result;
> +}
> +
> typedef struct RPCFunction {
> xmlrpc_value *(*func)(xmlrpc_env *env, xmlrpc_value *param, void *unused);
> const char *func_name;
> @@ -237,6 +421,12 @@ static RPCFunction guest_functions[] = {
> .func_name = "va.ping" },
> { .func = va_capabilities,
> .func_name = "va.capabilities" },
> + { .func = va_fsfreeze,
> + .func_name = "va.fsfreeze" },
> + { .func = va_fsthaw,
> + .func_name = "va.fsthaw" },
> + { .func = va_fsstatus,
> + .func_name = "va.fsstatus" },
> { NULL, NULL }
> };
> static RPCFunction host_functions[] = {
next prev parent reply other threads:[~2011-02-03 18:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-02 8:42 [Qemu-devel] [PATCH v2 0/2] virtagent - fsfreeze support Jes.Sorensen
2011-02-02 8:42 ` [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw Jes.Sorensen
2011-02-03 18:11 ` Michael Roth [this message]
2011-02-04 10:54 ` [Qemu-devel] " Jes Sorensen
2011-02-02 8:42 ` [Qemu-devel] [PATCH 2/2] Add monitor commands for fsfreeze support Jes.Sorensen
2011-02-03 18:15 ` [Qemu-devel] Re: [PATCH v2 0/2] virtagent - " Michael Roth
-- strict thread matches above, loose matches on Subject: below --
2011-02-01 10:58 [Qemu-devel] [PATCH " Jes.Sorensen
2011-02-01 10:58 ` [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw Jes.Sorensen
2011-02-01 14:48 ` [Qemu-devel] " Adam Litke
2011-02-01 15:02 ` Jes Sorensen
2011-02-01 16:50 ` Michael Roth
2011-02-02 8:38 ` Jes Sorensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D4AEFD7.8060808@linux.vnet.ibm.com \
--to=mdroth@linux.vnet.ibm.com \
--cc=Jes.Sorensen@redhat.com \
--cc=agl@us.ibm.com \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.