[libvirt] [PATCH] qemu: work around dash 0.5.5 bug in managed save

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Oct 25 23:57:32 UTC 2010


  On 10/22/2010 07:29 PM, Eric Blake wrote:
> * configure.ac (VIR_WRAPPER_SHELL): Define to a replacement shell,
> if /bin/sh is broken on<>  redirection.
> * src/qemu/qemu_monitor.h (VIR_WRAPPER_SHELL_PREFIX)
> (VIR_WRAPPER_SHELL_SUFFIX): New macros.
> * src/qemu/qemu_monitor_text.c (qemuMonitorTextMigrateToFile): Use
> them.
> * src/qemu/qemu_monitor_json.c (qemuMonitorJSONMigrateToFile):
> Likewise.
> ---
>
> Took longer than I thought, but this should do the trick with no
> overhead on decent systems, and while still avoiding buggy dash ==
> /bin/sh with something that works elsewhere.
>
> This passes for me on Fedora, where /bin/sh is bash; testing on
> Ubuntu or other debian-based system where /bin/sh is dash 0.5.5
> would be appreciated.
>
>   configure.ac                 |   50 ++++++++++++++++++++++++++++++++++++++++++
>   src/qemu/qemu_monitor.h      |   13 +++++++++++
>   src/qemu/qemu_monitor_json.c |    5 ++-
>   src/qemu/qemu_monitor_text.c |    5 ++-
>   4 files changed, 69 insertions(+), 4 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index e41f2b5..6aa09f7 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -583,6 +583,56 @@ if test "$with_lxc" = "yes" ; then
>   fi
>   AM_CONDITIONAL([WITH_LXC], [test "$with_lxc" = "yes"])
>
> +dnl
> +dnl check for shell that understands<>  redirection without truncation,
> +dnl needed by src/qemu/qemu_monitor_{text,json}.c.
> +dnl
> +if test "$with_qemu" = yes; then
> +  lv_wrapper_shell=
> +  AC_CACHE_CHECK([for shell that supports<>  redirection],
> +    [lv_cv_wrapper_shell],
> +    [
> +    # If cross-compiling, guess that /bin/sh is good enough except for
> +    # Linux, where it might be dash 0.5.5 which is known broken; and on
> +    # Linux, we have a good chance that /bin/bash will exist.
> +    # If we guess wrong, a user can override the cache variable.
> +    # Going through /bin/bash is a slight slowdown if /bin/sh works.
> +    if test "$cross_compiling" = yes; then
> +      case $host_os in
> +        linux*) lv_cv_wrapper_shell=/bin/bash ;;
> +        *) lv_cv_wrapper_shell=/bin/sh ;;
> +      esac
> +    else
> +      for lv_cv_wrapper_shell in /bin/sh bash ksh zsh none; do
> +        test $lv_cv_wrapper_shell = none&&
> +          AC_MSG_ERROR([could not find decent shell])
> +        echo a>  conftest.a
> +        $lv_cv_wrapper_shell -c ': 1<>conftest.a'
> +        case `cat conftest.a`.$lv_cv_wrapper_shell in
> +          a./*) break;; dnl /bin/sh is good enough
> +          a.*) dnl bash, ksh, and zsh all understand 'command', use that
> +               dnl to determine the absolute path of the shell
> +            lv_cv_wrapper_shell=`$lv_cv_wrapper_shell -c \
> +              'command -v $lv_cv_wrapper_shell'`
> +            case $lv_cv_wrapper_shell in
> +              /*) break;;
> +            esac
> +            ;;
> +        esac
> +      done
> +      rm -f conftest.a
> +    fi
> +  ])
> +  if test "x$lv_cv_wrapper_shell" != x/bin/sh; then
> +    lv_wrapper_shell=$lv_cv_wrapper_shell
> +  fi
> +  if test "x$lv_wrapper_shell" != x; then
> +    AC_DEFINE_UNQUOTED([VIR_WRAPPER_SHELL], [$lv_wrapper_shell],
> +      [Define to the absolute path of a shell that does not truncate on
> +<>  redirection, if /bin/sh does not fit the bill])
> +  fi
> +fi
> +
>
>   dnl
>   dnl check for kernel headers required by src/bridge.c
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 48f4c20..7d09145 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -391,4 +391,17 @@ int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
>
>   int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply);
>
> +/**
> + * When running two dd process and using<>  redirection, we need a
> + * shell that will not truncate files.  These two strings serve that
> + * purpose.
> + */
> +# ifdef VIR_WRAPPER_SHELL
> +#  define VIR_WRAPPER_SHELL_PREFIX VIR_WRAPPER_SHELL " -c '"
> +#  define VIR_WRAPPER_SHELL_SUFFIX "'"
> +# else
> +#  define VIR_WRAPPER_SHELL_PREFIX /* nothing */
> +#  define VIR_WRAPPER_SHELL_SUFFIX /* nothing */
> +# endif
> +
>   #endif /* QEMU_MONITOR_H */
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index d3ab25f..d2c6f0a 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -1698,8 +1698,9 @@ int qemuMonitorJSONMigrateToFile(qemuMonitorPtr mon,
>        * allow starting at an alignment of 512, but without wasting
>        * padding to get to the larger alignment useful for speed.  Use
>        *<>  redirection to avoid truncating a regular file.  */
> -    if (virAsprintf(&dest, "exec:%s | { dd bs=%llu seek=%llu if=/dev/null&&  "
> -                    "dd bs=%llu; } 1<>%s",
> +    if (virAsprintf(&dest, "exec:" VIR_WRAPPER_SHELL_PREFIX "%s | "
> +                    "{ dd bs=%llu seek=%llu if=/dev/null&&  "
> +                    "dd bs=%llu; } 1<>%s" VIR_WRAPPER_SHELL_SUFFIX,
>                       argstr, QEMU_MONITOR_MIGRATE_TO_FILE_BS,
>                       offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS,
>                       QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,
> diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
> index 69971a6..d7e128c 100644
> --- a/src/qemu/qemu_monitor_text.c
> +++ b/src/qemu/qemu_monitor_text.c
> @@ -1277,8 +1277,9 @@ int qemuMonitorTextMigrateToFile(qemuMonitorPtr mon,
>        * allow starting at an alignment of 512, but without wasting
>        * padding to get to the larger alignment useful for speed.  Use
>        *<>  redirection to avoid truncating a regular file.  */
> -    if (virAsprintf(&dest, "exec:%s | { dd bs=%llu seek=%llu if=/dev/null&&  "
> -                    "dd bs=%llu; } 1<>%s",
> +    if (virAsprintf(&dest, "exec:" VIR_WRAPPER_SHELL_PREFIX "%s | "
> +                    "{ dd bs=%llu seek=%llu if=/dev/null&&  "
> +                    "dd bs=%llu; } 1<>%s" VIR_WRAPPER_SHELL_SUFFIX,
>                       argstr, QEMU_MONITOR_MIGRATE_TO_FILE_BS,
>                       offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS,
>                       QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,

Cannot test it, but looks good. ACK.

     Stefan




More information about the libvir-list mailing list