qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Andreas Färber" <afaerber@suse.de>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: Alexey Kardashevskiy <aik@ozlabs.ru>,
	Paul Mackerras <paulus@samba.org>,
	qemu-ppc@nongnu.org, qemu-devel@nongnu.org,
	Alex Graf <agraf@suse.de>
Subject: Re: [Qemu-devel] [PATCH 04/12] qtest: add interface to save/restore
Date: Thu, 20 Jun 2013 17:38:02 +0200	[thread overview]
Message-ID: <51C321DA.9060600@suse.de> (raw)
In-Reply-To: <1371674435-14973-5-git-send-email-aliguori@us.ibm.com>

Am 19.06.2013 22:40, schrieb Anthony Liguori:
> The idea here is pretty simple.  We have a synchronous interface
> that when called, does a migration to a file, kills the QEMU
> instance, and spawns a new one using the saved file state.
> 
> We an then sprinkle calls to qtest_save_restore() thorough test
> cases to validate that we are properly saving and restoring state.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  tests/libqtest.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqtest.h | 46 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 111 insertions(+)
> 
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 235ec62..bc2e84e 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -44,6 +44,7 @@ struct QTestState
>      gchar *pid_file; /* QEMU PID file */
>      int child_pid;   /* Child process created to execute QEMU */
>      char *socket_path, *qmp_socket_path;
> +    char *extra_args;
>  };
>  
>  #define g_assert_no_errno(ret) do { \
> @@ -104,6 +105,14 @@ static pid_t qtest_qemu_pid(QTestState *s)
>      return pid;
>  }
>  
> +void qtest_qmp_wait_event(QTestState *s, const char *event)
> +{
> +    char *d;
> +    /* This is cheating */
> +    d = qtest_qmp(s, "");

This reminds me that I was unable to use GCC_FMT_ATTR(2, 3) on
qtest_qmp() because of the "" argument that gcc would warn about.

Otherwise code looks okay, although I'm not too familiar with the events.

Regards,
Andreas

> +    g_free(d);
> +}
> +
>  QTestState *qtest_init(const char *extra_args)
>  {
>      QTestState *s;
> @@ -118,6 +127,7 @@ QTestState *qtest_init(const char *extra_args)
>  
>      s = g_malloc(sizeof(*s));
>  
> +    s->extra_args = g_strdup(extra_args);
>      s->socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
>      s->qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
>      pid_file = g_strdup_printf("/tmp/qtest-%d.pid", getpid());
> @@ -177,6 +187,61 @@ void qtest_quit(QTestState *s)
>      g_free(s->pid_file);
>      g_free(s->socket_path);
>      g_free(s->qmp_socket_path);
> +    g_free(s->extra_args);
> +}
> +
> +QTestState *qtest_save_restore(QTestState *s)
> +{
> +    char *filename;
> +    char *d, *p, *extra_args;
> +    char *n;
> +
> +    filename = g_strdup_printf("/tmp/qtest-%d.savevm", getpid());
> +
> +    /* Start migration to a temporary file */
> +    d = qtest_qmp(s,
> +                  "{ 'execute': 'migrate', "
> +                  "  'arguments': { 'uri': 'exec:dd of=%s 2>/dev/null' } }",
> +                  filename);
> +    g_free(d);
> +
> +    /* Wait for critical section to be entered */
> +    qtest_qmp_wait_event(s, "STOP");
> +
> +    /* Not strictly needed as we can't possibly respond to this command until
> +     * we've completed migration by virtue of the fact that STOP has been sent
> +     * but it's good to be rigorious. */
> +    do {
> +        d = qtest_qmp(s, "{ 'execute': 'query-migrate' }");
> +        p = strstr(d, "\"status\": \"completed\",");
> +        g_free(d);
> +        if (!p) {
> +            g_usleep(100);
> +        }
> +    } while (p == NULL);
> +
> +    /* Save arguments to this qtest instance */
> +    extra_args = s->extra_args;
> +    s->extra_args = NULL;
> +
> +    /* Quit src instance */
> +    qtest_quit(s);
> +
> +    /* Spawn destination */
> +    n = g_strdup_printf("%s -incoming exec:\"dd if=%s 2>/dev/null\"",
> +                        extra_args, filename);
> +    s = qtest_init(n);
> +
> +    /* Wait for incoming migration to complete */
> +    qtest_qmp_wait_event(s, "RESUME");
> +
> +    /* Fixup extra arg so we can call repeatedly */
> +    g_free(s->extra_args);
> +    s->extra_args = extra_args;
> +
> +    g_free(filename);
> +
> +    return s;
>  }
>  
>  static void socket_sendf(int fd, const char *fmt, va_list ap)
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index 5cdcae7..f2c6e52 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -67,6 +67,15 @@ char *qtest_qmp(QTestState *s, const char *fmt, ...);
>  char *qtest_qmpv(QTestState *s, const char *fmt, va_list ap);
>  
>  /**
> + * qtest_qmp_wait_event:
> + * @s: #QTestState instance to operate on.
> + * @event: the event to wait for.
> + *
> + * Waits for a specific QMP event to occur.
> + */
> +void qtest_qmp_wait_event(QTestState *s, const char *event);
> +
> +/**
>   * qtest_get_irq:
>   * @s: #QTestState instance to operate on.
>   * @num: Interrupt to observe.
> @@ -291,6 +300,19 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
>  int64_t qtest_clock_set(QTestState *s, int64_t val);
>  
>  /**
> + * qtest_save_restore:
> + * @s: QTest instance to operate on.
> + *
> + * This function will save and restore the state of the running QEMU
> + * instance.  If the savevm code is implemented correctly for a device,
> + * this function should behave like a nop.  If a test case fails because
> + * this function is called, the savevm code for the device is broken.
> + *
> + * Returns: the new QTest instance
> + */
> +QTestState *qtest_save_restore(QTestState *s);
> +
> +/**
>   * qtest_spapr_hcall9:
>   * @s: QTestState instance to operate on.
>   * @nr: The hypercall index
> @@ -337,6 +359,17 @@ static inline QTestState *qtest_start(const char *args)
>  }
>  
>  /**
> + * qmp_wait_event:
> + * @event: the event to wait for.
> + *
> + * Waits for a specific QMP event to occur.
> + */
> +static inline void qmp_wait_event(const char *event)
> +{
> +    qtest_qmp_wait_event(global_qtest, event);
> +}
> +
> +/**
>   * qmp:
>   * @fmt...: QMP message to send to qemu
>   *
> @@ -628,6 +661,19 @@ static inline int64_t clock_set(int64_t val)
>      return qtest_clock_set(global_qtest, val);
>  }
>  
> +/**
> + * save_restore:
> + *
> + * This function will save and restore the state of the running QEMU
> + * instance.  If the savevm code is implemented correctly for a device,
> + * this function should behave like a nop.  If a test case fails because
> + * this function is called, the savevm code for the device is broken.
> + */
> +static inline void save_restore(void)
> +{
> +    global_qtest = qtest_save_restore(global_qtest);
> +}
> +
>  static inline uint64_t spapr_hcall0(uint64_t nr)
>  {
>      return qtest_spapr_hcall9(global_qtest, nr, 0, 0, 0, 0, 0, 0, 0, 0, 0);
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

  reply	other threads:[~2013-06-20 15:38 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-19 20:40 [Qemu-devel] [PATCH 00/12] spapr: add qtest support and refactor vty Anthony Liguori
2013-06-19 20:40 ` [Qemu-devel] [PATCH 01/12] chardev: ringbuf: add optional save parameter to save state Anthony Liguori
2013-06-20 19:49   ` Eric Blake
2013-06-19 20:40 ` [Qemu-devel] [PATCH 02/12] qtest: add spapr hypercall support Anthony Liguori
2013-06-20 15:20   ` Andreas Färber
2013-06-20 15:42     ` Anthony Liguori
2013-06-20 18:43       ` Alexander Graf
2013-06-20 18:58         ` Anthony Liguori
2013-06-20 19:28           ` [Qemu-devel] [Qemu-ppc] " Scott Wood
2013-06-20 21:57           ` [Qemu-devel] " Alexander Graf
2013-06-19 20:40 ` [Qemu-devel] [PATCH 03/12] qtest: return string from QMP commands Anthony Liguori
2013-06-20 15:24   ` Andreas Färber
2013-06-20 15:43     ` Anthony Liguori
2013-06-19 20:40 ` [Qemu-devel] [PATCH 04/12] qtest: add interface to save/restore Anthony Liguori
2013-06-20 15:38   ` Andreas Färber [this message]
2013-06-19 20:40 ` [Qemu-devel] [PATCH 05/12] spapr-vty: add qtest test case Anthony Liguori
2013-06-19 21:13   ` Alexander Graf
2013-06-19 21:43     ` Anthony Liguori
2013-06-19 21:47       ` Alexander Graf
2013-06-19 20:40 ` [Qemu-devel] [PATCH 06/12] spapr-vty: add copyright and license Anthony Liguori
2013-06-20  1:45   ` Michael Ellerman
2013-06-20  4:08   ` Alexey Kardashevskiy
2013-06-20  4:43   ` David Gibson
2013-06-20  8:52   ` Paolo Bonzini
2013-06-20 15:47   ` Andreas Färber
2013-06-19 20:40 ` [Qemu-devel] [PATCH 07/12] spapr-rtas: add CPU argument to RTAS calls Anthony Liguori
2013-06-19 21:15   ` Alexander Graf
2013-06-20 15:51   ` Andreas Färber
2013-06-20 16:10     ` Anthony Liguori
2013-06-19 20:40 ` [Qemu-devel] [PATCH 08/12] spapr-rtas: use hypercall interface and remove special vty interfaces Anthony Liguori
2013-06-19 21:24   ` Alexander Graf
2013-06-19 21:45     ` Anthony Liguori
2013-06-19 21:48       ` Alexander Graf
2013-06-19 20:40 ` [Qemu-devel] [PATCH 09/12] spapr-vio: move special case handling for reg=0 to vio Anthony Liguori
2013-06-19 21:28   ` Alexander Graf
2013-06-19 21:49     ` Anthony Liguori
2013-06-19 21:53       ` Alexander Graf
2013-06-19 23:20         ` Anthony Liguori
2013-06-19 23:07     ` Benjamin Herrenschmidt
2013-06-19 20:40 ` [Qemu-devel] [PATCH 10/12] spapr-vty: refactor the code to improve consistency Anthony Liguori
2013-06-19 21:37   ` Alexander Graf
2013-06-19 20:40 ` [Qemu-devel] [PATCH 11/12] spapr-vio: pass type to spapr_vio_find_by_reg() Anthony Liguori
2013-06-19 21:38   ` Alexander Graf
2013-06-19 21:56     ` Anthony Liguori
2013-06-19 20:40 ` [Qemu-devel] [PATCH 12/12] spapr-vty: remove unfixable FIXME Anthony Liguori

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=51C321DA.9060600@suse.de \
    --to=afaerber@suse.de \
    --cc=agraf@suse.de \
    --cc=aik@ozlabs.ru \
    --cc=aliguori@us.ibm.com \
    --cc=paulus@samba.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).