* [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw @ 2012-12-12 3:55 Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 1/2] qemu-ga: execute " Tomoki Sekiyama ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Tomoki Sekiyama @ 2012-12-12 3:55 UTC (permalink / raw) To: qemu-devel; +Cc: mdroth, lcapitulino Hi, This is version 8 of the qemu-ga fsfreeze hook patchset. *Changes from v7: ( http://patchwork.ozlabs.org/patch/204426/ ) 1/2: Not changed. 2/2: Moved .gitignore exception for fsfreeze-hook.d right below "*.d". Make fsfreeze success even if fsfreeze-hook.d doesn't exist. Use printf(1) instead of echo to output logs. Use "$MYSQL" $MYSQL_OPTS instead of $MYSQL_CMD for safety. Improve signal handling in flush-mysql.sh. Fix misspelling. This patchset depends on Luiz Capitulino's patchset to improve error handling, which is available at: https://lists.gnu.org/archive/html/qemu-devel/2012-11/msg03016.html --- Tomoki Sekiyama (2): qemu-ga: execute hook to quiesce the guest on fsfreeze-freeze/thaw qemu-ga: sample fsfreeze hooks .gitignore | 1 Makefile | 2 - qemu-ga.c | 42 ++++++++++++ qga/commands-posix.c | 69 ++++++++++++++++++++ qga/guest-agent-core.h | 1 scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++ .../fsfreeze-hook.d/mysql-flush.sh.sample | 56 ++++++++++++++++ 7 files changed, 202 insertions(+), 2 deletions(-) create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample Thanks, -- Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v8 1/2] qemu-ga: execute hook to quiesce the guest on fsfreeze-freeze/thaw 2012-12-12 3:55 [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama @ 2012-12-12 3:55 ` Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 2013-01-08 22:53 ` [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw mdroth 2 siblings, 0 replies; 5+ messages in thread From: Tomoki Sekiyama @ 2012-12-12 3:55 UTC (permalink / raw) To: qemu-devel; +Cc: mdroth, Luiz Capitulino To use the online disk snapshot for online-backup, application-level consistency of the snapshot image is required. However, currently the guest agent can provide only filesystem-level consistency, and the snapshot may contain dirty data, for example, incomplete transactions. This patch provides the opportunity to quiesce applications before snapshot is taken. If --fsfreeze-hook option is specified, the hook is executed with "freeze" argument before the filesystem is frozen by fsfreeze-freeze command. As for fsfreeze-thaw command, the hook is executed with "thaw" argument after the filesystem is thawed. This patch depends on patchset to improve error reporting by Luiz Capitulino: http://lists.gnu.org/archive/html/qemu-devel/2012-11/msg03016.html Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com> --- qemu-ga.c | 42 +++++++++++++++++++++++++++++ qga/commands-posix.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ qga/guest-agent-core.h | 1 + 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/qemu-ga.c b/qemu-ga.c index 9b59a52..53ce462 100644 --- a/qemu-ga.c +++ b/qemu-ga.c @@ -34,6 +34,12 @@ #include "qga/service-win32.h" #include <windows.h> #endif +#ifdef __linux__ +#include <linux/fs.h> +#ifdef FIFREEZE +#define CONFIG_FSFREEZE +#endif +#endif #ifndef _WIN32 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0" @@ -42,6 +48,9 @@ #endif #define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run" #define QGA_PIDFILE_DEFAULT QGA_STATEDIR_DEFAULT "/qemu-ga.pid" +#ifdef CONFIG_FSFREEZE +#define QGA_FSFREEZE_HOOK_DEFAULT CONFIG_QEMU_CONFDIR "/fsfreeze-hook" +#endif #define QGA_SENTINEL_BYTE 0xFF struct GAState { @@ -64,6 +73,9 @@ struct GAState { const char *log_filepath; const char *pid_filepath; } deferred_options; +#ifdef CONFIG_FSFREEZE + const char *fsfreeze_hook; +#endif }; struct GAState *ga_state; @@ -153,6 +165,10 @@ static void usage(const char *cmd) " %s)\n" " -l, --logfile set logfile path, logs to stderr by default\n" " -f, --pidfile specify pidfile (default is %s)\n" +#ifdef CONFIG_FSFREEZE +" -F, --fsfreeze-hook\n" +" enable fsfreeze hook (default is %s)\n" +#endif " -t, --statedir specify dir to store state information (absolute paths\n" " only, default is %s)\n" " -v, --verbose log extra debugging information\n" @@ -167,6 +183,9 @@ static void usage(const char *cmd) "\n" "Report bugs to <mdroth@linux.vnet.ibm.com>\n" , cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT, +#ifdef CONFIG_FSFREEZE + QGA_FSFREEZE_HOOK_DEFAULT, +#endif QGA_STATEDIR_DEFAULT); } @@ -401,6 +420,13 @@ void ga_unset_frozen(GAState *s) } } +#ifdef CONFIG_FSFREEZE +const char *ga_fsfreeze_hook(GAState *s) +{ + return s->fsfreeze_hook; +} +#endif + static void become_daemon(const char *pidfile) { #ifndef _WIN32 @@ -678,10 +704,13 @@ VOID WINAPI service_main(DWORD argc, TCHAR *argv[]) int main(int argc, char **argv) { - const char *sopt = "hVvdm:p:l:f:b:s:t:"; + const char *sopt = "hVvdm:p:l:f:F::b:s:t:"; const char *method = NULL, *path = NULL; const char *log_filepath = NULL; const char *pid_filepath = QGA_PIDFILE_DEFAULT; +#ifdef CONFIG_FSFREEZE + const char *fsfreeze_hook = NULL; +#endif const char *state_dir = QGA_STATEDIR_DEFAULT; #ifdef _WIN32 const char *service = NULL; @@ -691,6 +720,9 @@ int main(int argc, char **argv) { "version", 0, NULL, 'V' }, { "logfile", 1, NULL, 'l' }, { "pidfile", 1, NULL, 'f' }, +#ifdef CONFIG_FSFREEZE + { "fsfreeze-hook", 2, NULL, 'F' }, +#endif { "verbose", 0, NULL, 'v' }, { "method", 1, NULL, 'm' }, { "path", 1, NULL, 'p' }, @@ -723,6 +755,11 @@ int main(int argc, char **argv) case 'f': pid_filepath = optarg; break; +#ifdef CONFIG_FSFREEZE + case 'F': + fsfreeze_hook = optarg ? optarg : QGA_FSFREEZE_HOOK_DEFAULT; + break; +#endif case 't': state_dir = optarg; break; @@ -786,6 +823,9 @@ int main(int argc, char **argv) s = g_malloc0(sizeof(GAState)); s->log_level = log_level; s->log_file = stderr; +#ifdef CONFIG_FSFREEZE + s->fsfreeze_hook = fsfreeze_hook; +#endif g_log_set_default_handler(ga_log, s); g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR); ga_enable_logging(s); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 2591a3c..f7c0d9a 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -410,6 +410,66 @@ static void build_fs_mount_list(FsMountList *mounts, Error **err) #if defined(CONFIG_FSFREEZE) +typedef enum { + FSFREEZE_HOOK_THAW = 0, + FSFREEZE_HOOK_FREEZE, +} FsfreezeHookArg; + +const char *fsfreeze_hook_arg_string[] = { + "thaw", + "freeze", +}; + +static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **err) +{ + int status; + pid_t pid; + const char *hook; + const char *arg_str = fsfreeze_hook_arg_string[arg]; + Error *local_err = NULL; + + hook = ga_fsfreeze_hook(ga_state); + if (!hook) { + return; + } + if (access(hook, X_OK) != 0) { + error_setg_errno(err, errno, "can't access fsfreeze hook '%s'", hook); + return; + } + + slog("executing fsfreeze hook with arg '%s'", arg_str); + pid = fork(); + if (pid == 0) { + setsid(); + reopen_fd_to_null(0); + reopen_fd_to_null(1); + reopen_fd_to_null(2); + + execle(hook, hook, arg_str, NULL, environ); + _exit(EXIT_FAILURE); + } else if (pid < 0) { + error_setg_errno(err, errno, "failed to create child process"); + return; + } + + ga_wait_child(pid, &status, &local_err); + if (error_is_set(&local_err)) { + error_propagate(err, local_err); + return; + } + + if (!WIFEXITED(status)) { + error_setg(err, "fsfreeze hook has terminated abnormally"); + return; + } + + status = WEXITSTATUS(status); + if (status) { + error_setg(err, "fsfreeze hook has failed with status %d", status); + return; + } +} + /* * Return status of freeze/thaw */ @@ -436,6 +496,12 @@ int64_t qmp_guest_fsfreeze_freeze(Error **err) slog("guest-fsfreeze called"); + execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); + if (error_is_set(&local_err)) { + error_propagate(err, local_err); + return -1; + } + QTAILQ_INIT(&mounts); build_fs_mount_list(&mounts, &local_err); if (error_is_set(&local_err)) { @@ -537,6 +603,9 @@ int64_t qmp_guest_fsfreeze_thaw(Error **err) ga_unset_frozen(ga_state); free_fs_mount_list(&mounts); + + execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, err); + return i; } diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index 49a7abe..c6e8de0 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -34,6 +34,7 @@ void ga_set_response_delimited(GAState *s); bool ga_is_frozen(GAState *s); void ga_set_frozen(GAState *s); void ga_unset_frozen(GAState *s); +const char *ga_fsfreeze_hook(GAState *s); #ifndef _WIN32 void reopen_fd_to_null(int fd); ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks 2012-12-12 3:55 [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 1/2] qemu-ga: execute " Tomoki Sekiyama @ 2012-12-12 3:55 ` Tomoki Sekiyama 2012-12-12 12:11 ` Luiz Capitulino 2013-01-08 22:53 ` [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw mdroth 2 siblings, 1 reply; 5+ messages in thread From: Tomoki Sekiyama @ 2012-12-12 3:55 UTC (permalink / raw) To: qemu-devel; +Cc: mdroth, lcapitulino Adds sample hook scripts for --fsfreeze-hook option of qemu-ga. - fsfreeze-hook : execute scripts in fsfreeze-hook.d/ - fsfreeze-hook.d/mysql-flush.sh.sample : quiesce MySQL before snapshot Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> --- .gitignore | 1 Makefile | 2 - scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ .../fsfreeze-hook.d/mysql-flush.sh.sample | 56 ++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample diff --git a/.gitignore b/.gitignore index bd6ba1c..6456e9d 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,7 @@ fsdev/virtfs-proxy-helper.pod *.tp *.vr *.d +!scripts/qemu-guest-agent/fsfreeze-hook.d *.o *.lo *.la diff --git a/Makefile b/Makefile index 9ecbcbb..466dcd7 100644 --- a/Makefile +++ b/Makefile @@ -248,7 +248,7 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f qemu-options.def - find . -name '*.[od]' -exec rm -f {} + + find . -name '*.[od]' -type f -exec rm -f {} + rm -f *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -Rf .libs rm -f qemu-img-cmds.h diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook new file mode 100755 index 0000000..c27b29f --- /dev/null +++ b/scripts/qemu-guest-agent/fsfreeze-hook @@ -0,0 +1,33 @@ +#!/bin/sh + +# This script is executed when a guest agent receives fsfreeze-freeze and +# fsfreeze-thaw command, if it is specified in --fsfreeze-hook (-F) +# option of qemu-ga or placed in default path (/etc/qemu/fsfreeze-hook). +# When the agent receives fsfreeze-freeze request, this script is issued with +# "freeze" argument before the filesystem is frozen. And for fsfreeze-thaw +# request, it is issued with "thaw" argument after filesystem is thawed. + +LOGFILE=/var/log/qga-fsfreeze-hook.log +FSFREEZE_D=$(dirname -- "$0")/fsfreeze-hook.d + +# Check whether file $1 is a backup or rpm-generated file and should be ignored +is_ignored_file() { + case "$1" in + *~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave | *.sample) + return 0 ;; + esac + return 1 +} + +# Iterate executables in directory "fsfreeze-hook.d" with the specified args +[ ! -d "$FSFREEZE_D" ] && exit 0 +for file in "$FSFREEZE_D"/* ; do + is_ignored_file "$file" && continue + [ -x "$file" ] || continue + printf "$(date): execute $file $@\n" >>$LOGFILE + "$file" "$@" >>$LOGFILE 2>&1 + STATUS=$? + printf "$(date): $file finished with status=$STATUS\n" >>$LOGFILE +done + +exit 0 diff --git a/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample new file mode 100755 index 0000000..2b4fa3a --- /dev/null +++ b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample @@ -0,0 +1,56 @@ +#!/bin/sh + +# Flush MySQL tables to the disk before the filesystem is frozen. +# At the same time, this keeps a read lock in order to avoid write accesses +# from the other clients until the filesystem is thawed. + +MYSQL="/usr/bin/mysql" +MYSQL_OPTS="-uroot" #"-prootpassword" +FIFO=/var/run/mysql-flush.fifo + +# Check mysql is installed and the server running +[ -x "$MYSQL" ] && "$MYSQL" $MYSQL_OPTS < /dev/null || exit 0 + +flush_and_wait() { + printf "FLUSH TABLES WITH READ LOCK \\G\n" + trap 'printf "$(date): $0 is killed\n">&2' HUP INT QUIT ALRM TERM + read < $FIFO + printf "UNLOCK TABLES \\G\n" + rm -f $FIFO +} + +case "$1" in + freeze) + mkfifo $FIFO || exit 1 + flush_and_wait | "$MYSQL" $MYSQL_OPTS & + # wait until every block is flushed + while [ "$(echo 'SHOW STATUS LIKE "Key_blocks_not_flushed"' |\ + "$MYSQL" $MYSQL_OPTS | tail -1 | cut -f 2)" -gt 0 ]; do + sleep 1 + done + # for InnoDB, wait until every log is flushed + INNODB_STATUS=$(mktemp /tmp/mysql-flush.XXXXXX) + [ $? -ne 0 ] && exit 2 + trap "rm -f $INNODB_STATUS; exit 1" HUP INT QUIT ALRM TERM + while :; do + printf "SHOW ENGINE INNODB STATUS \\G" |\ + "$MYSQL" $MYSQL_OPTS > $INNODB_STATUS + LOG_CURRENT=$(grep 'Log sequence number' $INNODB_STATUS |\ + tr -s ' ' | cut -d' ' -f4) + LOG_FLUSHED=$(grep 'Log flushed up to' $INNODB_STATUS |\ + tr -s ' ' | cut -d' ' -f5) + [ "$LOG_CURRENT" = "$LOG_FLUSHED" ] && break + sleep 1 + done + rm -f $INNODB_STATUS + ;; + + thaw) + [ ! -p $FIFO ] && exit 1 + echo > $FIFO + ;; + + *) + exit 1 + ;; +esac ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama @ 2012-12-12 12:11 ` Luiz Capitulino 0 siblings, 0 replies; 5+ messages in thread From: Luiz Capitulino @ 2012-12-12 12:11 UTC (permalink / raw) To: Tomoki Sekiyama; +Cc: qemu-devel, mdroth On Wed, 12 Dec 2012 12:55:57 +0900 Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> wrote: > Adds sample hook scripts for --fsfreeze-hook option of qemu-ga. > - fsfreeze-hook : execute scripts in fsfreeze-hook.d/ > - fsfreeze-hook.d/mysql-flush.sh.sample : quiesce MySQL before snapshot > > Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> Looks good to me: Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com> > --- > .gitignore | 1 > Makefile | 2 - > scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ > .../fsfreeze-hook.d/mysql-flush.sh.sample | 56 ++++++++++++++++++++ > 4 files changed, 91 insertions(+), 1 deletion(-) > create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook > create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample > > diff --git a/.gitignore b/.gitignore > index bd6ba1c..6456e9d 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -68,6 +68,7 @@ fsdev/virtfs-proxy-helper.pod > *.tp > *.vr > *.d > +!scripts/qemu-guest-agent/fsfreeze-hook.d > *.o > *.lo > *.la > diff --git a/Makefile b/Makefile > index 9ecbcbb..466dcd7 100644 > --- a/Makefile > +++ b/Makefile > @@ -248,7 +248,7 @@ clean: > # avoid old build problems by removing potentially incorrect old files > rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h > rm -f qemu-options.def > - find . -name '*.[od]' -exec rm -f {} + > + find . -name '*.[od]' -type f -exec rm -f {} + > rm -f *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ > rm -Rf .libs > rm -f qemu-img-cmds.h > diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook > new file mode 100755 > index 0000000..c27b29f > --- /dev/null > +++ b/scripts/qemu-guest-agent/fsfreeze-hook > @@ -0,0 +1,33 @@ > +#!/bin/sh > + > +# This script is executed when a guest agent receives fsfreeze-freeze and > +# fsfreeze-thaw command, if it is specified in --fsfreeze-hook (-F) > +# option of qemu-ga or placed in default path (/etc/qemu/fsfreeze-hook). > +# When the agent receives fsfreeze-freeze request, this script is issued with > +# "freeze" argument before the filesystem is frozen. And for fsfreeze-thaw > +# request, it is issued with "thaw" argument after filesystem is thawed. > + > +LOGFILE=/var/log/qga-fsfreeze-hook.log > +FSFREEZE_D=$(dirname -- "$0")/fsfreeze-hook.d > + > +# Check whether file $1 is a backup or rpm-generated file and should be ignored > +is_ignored_file() { > + case "$1" in > + *~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave | *.sample) > + return 0 ;; > + esac > + return 1 > +} > + > +# Iterate executables in directory "fsfreeze-hook.d" with the specified args > +[ ! -d "$FSFREEZE_D" ] && exit 0 > +for file in "$FSFREEZE_D"/* ; do > + is_ignored_file "$file" && continue > + [ -x "$file" ] || continue > + printf "$(date): execute $file $@\n" >>$LOGFILE > + "$file" "$@" >>$LOGFILE 2>&1 > + STATUS=$? > + printf "$(date): $file finished with status=$STATUS\n" >>$LOGFILE > +done > + > +exit 0 > diff --git a/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample > new file mode 100755 > index 0000000..2b4fa3a > --- /dev/null > +++ b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample > @@ -0,0 +1,56 @@ > +#!/bin/sh > + > +# Flush MySQL tables to the disk before the filesystem is frozen. > +# At the same time, this keeps a read lock in order to avoid write accesses > +# from the other clients until the filesystem is thawed. > + > +MYSQL="/usr/bin/mysql" > +MYSQL_OPTS="-uroot" #"-prootpassword" > +FIFO=/var/run/mysql-flush.fifo > + > +# Check mysql is installed and the server running > +[ -x "$MYSQL" ] && "$MYSQL" $MYSQL_OPTS < /dev/null || exit 0 > + > +flush_and_wait() { > + printf "FLUSH TABLES WITH READ LOCK \\G\n" > + trap 'printf "$(date): $0 is killed\n">&2' HUP INT QUIT ALRM TERM > + read < $FIFO > + printf "UNLOCK TABLES \\G\n" > + rm -f $FIFO > +} > + > +case "$1" in > + freeze) > + mkfifo $FIFO || exit 1 > + flush_and_wait | "$MYSQL" $MYSQL_OPTS & > + # wait until every block is flushed > + while [ "$(echo 'SHOW STATUS LIKE "Key_blocks_not_flushed"' |\ > + "$MYSQL" $MYSQL_OPTS | tail -1 | cut -f 2)" -gt 0 ]; do > + sleep 1 > + done > + # for InnoDB, wait until every log is flushed > + INNODB_STATUS=$(mktemp /tmp/mysql-flush.XXXXXX) > + [ $? -ne 0 ] && exit 2 > + trap "rm -f $INNODB_STATUS; exit 1" HUP INT QUIT ALRM TERM > + while :; do > + printf "SHOW ENGINE INNODB STATUS \\G" |\ > + "$MYSQL" $MYSQL_OPTS > $INNODB_STATUS > + LOG_CURRENT=$(grep 'Log sequence number' $INNODB_STATUS |\ > + tr -s ' ' | cut -d' ' -f4) > + LOG_FLUSHED=$(grep 'Log flushed up to' $INNODB_STATUS |\ > + tr -s ' ' | cut -d' ' -f5) > + [ "$LOG_CURRENT" = "$LOG_FLUSHED" ] && break > + sleep 1 > + done > + rm -f $INNODB_STATUS > + ;; > + > + thaw) > + [ ! -p $FIFO ] && exit 1 > + echo > $FIFO > + ;; > + > + *) > + exit 1 > + ;; > +esac > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw 2012-12-12 3:55 [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 1/2] qemu-ga: execute " Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama @ 2013-01-08 22:53 ` mdroth 2 siblings, 0 replies; 5+ messages in thread From: mdroth @ 2013-01-08 22:53 UTC (permalink / raw) To: Tomoki Sekiyama; +Cc: qemu-devel, lcapitulino On Wed, Dec 12, 2012 at 12:55:47PM +0900, Tomoki Sekiyama wrote: > Hi, > > This is version 8 of the qemu-ga fsfreeze hook patchset. Thanks, applied to qga branch with some minor clarifications for the help output. > > *Changes from v7: ( http://patchwork.ozlabs.org/patch/204426/ ) > 1/2: Not changed. > 2/2: Moved .gitignore exception for fsfreeze-hook.d right below "*.d". > Make fsfreeze success even if fsfreeze-hook.d doesn't exist. > Use printf(1) instead of echo to output logs. > Use "$MYSQL" $MYSQL_OPTS instead of $MYSQL_CMD for safety. > Improve signal handling in flush-mysql.sh. > Fix misspelling. > > This patchset depends on Luiz Capitulino's patchset to improve error > handling, which is available at: > https://lists.gnu.org/archive/html/qemu-devel/2012-11/msg03016.html > --- > Tomoki Sekiyama (2): > qemu-ga: execute hook to quiesce the guest on fsfreeze-freeze/thaw > qemu-ga: sample fsfreeze hooks > > .gitignore | 1 > Makefile | 2 - > qemu-ga.c | 42 ++++++++++++ > qga/commands-posix.c | 69 ++++++++++++++++++++ > qga/guest-agent-core.h | 1 > scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++ > .../fsfreeze-hook.d/mysql-flush.sh.sample | 56 ++++++++++++++++ > 7 files changed, 202 insertions(+), 2 deletions(-) > create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook > create mode 100755 scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample > > Thanks, > -- > Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> > Linux Technology Center > Hitachi, Ltd., Yokohama Research Laboratory > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-01-08 22:55 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-12 3:55 [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 1/2] qemu-ga: execute " Tomoki Sekiyama 2012-12-12 3:55 ` [Qemu-devel] [PATCH v8 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 2012-12-12 12:11 ` Luiz Capitulino 2013-01-08 22:53 ` [Qemu-devel] [PATCH v8 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw mdroth
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).