All of lore.kernel.org
 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 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.