* [Qemu-devel] [PATCH v7 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw @ 2012-12-07 8:39 Tomoki Sekiyama 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute " Tomoki Sekiyama 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 0 siblings, 2 replies; 14+ messages in thread From: Tomoki Sekiyama @ 2012-12-07 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: mdroth, lcapitulino Hi, This is version 7 of the qemu-ga fsfreeze hook patchset. *Changes from v6: ( http://patchwork.ozlabs.org/patch/202959/ ) 1/2: Improved an error message on failure of access(2) to fsfreeze-hook. 2/2: Moved hook scripts from docs/ to scripts/. Move fsfreeze.d.sample/flush-mysql.sh to fsfreeze.d/flush-mysql.sh.sample. fsfreeze-hook now ignores fsfreeze.d/*.sample. 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 | 55 ++++++++++++++++ 7 files changed, 201 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] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute hook to quiesce the guest on fsfreeze-freeze/thaw 2012-12-07 8:39 [Qemu-devel] [PATCH v7 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama @ 2012-12-07 8:39 ` Tomoki Sekiyama 2012-12-07 13:52 ` Luiz Capitulino 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 1 sibling, 1 reply; 14+ messages in thread From: Tomoki Sekiyama @ 2012-12-07 8:39 UTC (permalink / raw) To: qemu-devel; +Cc: mdroth, lcapitulino 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> --- 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] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute hook to quiesce the guest on fsfreeze-freeze/thaw 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute " Tomoki Sekiyama @ 2012-12-07 13:52 ` Luiz Capitulino 0 siblings, 0 replies; 14+ messages in thread From: Luiz Capitulino @ 2012-12-07 13:52 UTC (permalink / raw) To: Tomoki Sekiyama; +Cc: qemu-devel, mdroth On Fri, 07 Dec 2012 17:39:29 +0900 Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> wrote: > 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 [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 8:39 [Qemu-devel] [PATCH v7 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute " Tomoki Sekiyama @ 2012-12-07 8:39 ` Tomoki Sekiyama 2012-12-07 13:55 ` Luiz Capitulino 2012-12-07 18:34 ` Eric Blake 1 sibling, 2 replies; 14+ messages in thread From: Tomoki Sekiyama @ 2012-12-07 8:39 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 | 55 ++++++++++++++++++++ 4 files changed, 90 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..286822d 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,4 @@ cscope.* tags TAGS *~ +!scripts/qemu-guest-agent/fsfreeze-hook.d 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..4f7ff15 --- /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 freezed. 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 1 +for file in "$FSFREEZE_D"/* ; do + is_ignored_file "$file" && continue + [ -x "$file" ] || continue + echo "$(date): execute $file $@" >>$LOGFILE + "$file" "$@" >>$LOGFILE 2>&1 + STATUS=$? + echo "$(date): $file finished with status=$STATUS" >>$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..c69b8ad --- /dev/null +++ b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample @@ -0,0 +1,55 @@ +#!/bin/sh + +# Flush MySQL tables to the disk before the filesystem is freezed. +# 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=/tmp/mysql-flush.fifo +MYSQL_CMD="$MYSQL $MYSQL_OPTS" + +# Check mysql is installed and the server running +[ -x $MYSQL ] && $MYSQL_CMD < /dev/null || exit 0 + +flush_and_wait() { + printf "FLUSH TABLES WITH READ LOCK \\G\n" + read < $FIFO + printf "UNLOCK TABLES \\G\n" +} + +case "$1" in + freeze) + mkfifo $FIFO || exit 1 + flush_and_wait | $MYSQL_CMD & + # wait until every block is flushed + while [ "$(echo 'SHOW STATUS LIKE "Key_blocks_not_flushed"' |\ + $MYSQL_CMD | 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" SIGINT + while :; do + printf "SHOW ENGINE INNODB STATUS \\G" | $MYSQL_CMD > $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 + rm -f $FIFO + ;; + + *) + exit 1 + ;; +esac ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama @ 2012-12-07 13:55 ` Luiz Capitulino 2012-12-07 17:47 ` mdroth 2012-12-07 18:22 ` Eric Blake 2012-12-07 18:34 ` Eric Blake 1 sibling, 2 replies; 14+ messages in thread From: Luiz Capitulino @ 2012-12-07 13:55 UTC (permalink / raw) To: Tomoki Sekiyama; +Cc: qemu-devel, mdroth On Fri, 07 Dec 2012 17:39:32 +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> > --- > .gitignore | 1 > Makefile | 2 - > scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ > .../fsfreeze-hook.d/mysql-flush.sh.sample | 55 ++++++++++++++++++++ > 4 files changed, 90 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..286822d 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -93,3 +93,4 @@ cscope.* > tags > TAGS > *~ > +!scripts/qemu-guest-agent/fsfreeze-hook.d Why? Do we expect to have *~ files in there? > 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 {} + What does this change have to do with this patch? > 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..4f7ff15 > --- /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 freezed. 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 1 > +for file in "$FSFREEZE_D"/* ; do > + is_ignored_file "$file" && continue > + [ -x "$file" ] || continue > + echo "$(date): execute $file $@" >>$LOGFILE > + "$file" "$@" >>$LOGFILE 2>&1 > + STATUS=$? > + echo "$(date): $file finished with status=$STATUS" >>$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..c69b8ad > --- /dev/null > +++ b/scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample > @@ -0,0 +1,55 @@ > +#!/bin/sh > + > +# Flush MySQL tables to the disk before the filesystem is freezed. > +# 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=/tmp/mysql-flush.fifo > +MYSQL_CMD="$MYSQL $MYSQL_OPTS" > + > +# Check mysql is installed and the server running > +[ -x $MYSQL ] && $MYSQL_CMD < /dev/null || exit 0 > + > +flush_and_wait() { > + printf "FLUSH TABLES WITH READ LOCK \\G\n" > + read < $FIFO > + printf "UNLOCK TABLES \\G\n" > +} > + > +case "$1" in > + freeze) > + mkfifo $FIFO || exit 1 > + flush_and_wait | $MYSQL_CMD & > + # wait until every block is flushed > + while [ "$(echo 'SHOW STATUS LIKE "Key_blocks_not_flushed"' |\ > + $MYSQL_CMD | 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" SIGINT > + while :; do > + printf "SHOW ENGINE INNODB STATUS \\G" | $MYSQL_CMD > $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 > + rm -f $FIFO > + ;; > + > + *) > + exit 1 > + ;; > +esac > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 13:55 ` Luiz Capitulino @ 2012-12-07 17:47 ` mdroth 2012-12-07 18:29 ` Luiz Capitulino 2012-12-07 18:22 ` Eric Blake 1 sibling, 1 reply; 14+ messages in thread From: mdroth @ 2012-12-07 17:47 UTC (permalink / raw) To: Luiz Capitulino; +Cc: Tomoki Sekiyama, qemu-devel On Fri, Dec 07, 2012 at 11:55:16AM -0200, Luiz Capitulino wrote: > On Fri, 07 Dec 2012 17:39:32 +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> > > --- > > .gitignore | 1 > > Makefile | 2 - > > scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ > > .../fsfreeze-hook.d/mysql-flush.sh.sample | 55 ++++++++++++++++++++ > > 4 files changed, 90 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..286822d 100644 > > --- a/.gitignore > > +++ b/.gitignore > > @@ -93,3 +93,4 @@ cscope.* > > tags > > TAGS > > *~ > > +!scripts/qemu-guest-agent/fsfreeze-hook.d > > Why? Do we expect to have *~ files in there? I think default vim configurations will copy <file> to <file>~ prior to editing. > > > 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 {} + > > What does this change have to do with this patch? Looks like it'll try (and fail, due to lack of -r option to rm) to delete the fsfreeze-hook.d directory on `make clean`. For in-tree builds at least. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 17:47 ` mdroth @ 2012-12-07 18:29 ` Luiz Capitulino 0 siblings, 0 replies; 14+ messages in thread From: Luiz Capitulino @ 2012-12-07 18:29 UTC (permalink / raw) To: mdroth; +Cc: Tomoki Sekiyama, qemu-devel On Fri, 7 Dec 2012 11:47:24 -0600 mdroth <mdroth@linux.vnet.ibm.com> wrote: > On Fri, Dec 07, 2012 at 11:55:16AM -0200, Luiz Capitulino wrote: > > On Fri, 07 Dec 2012 17:39:32 +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> > > > --- > > > .gitignore | 1 > > > Makefile | 2 - > > > scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ > > > .../fsfreeze-hook.d/mysql-flush.sh.sample | 55 ++++++++++++++++++++ > > > 4 files changed, 90 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..286822d 100644 > > > --- a/.gitignore > > > +++ b/.gitignore > > > @@ -93,3 +93,4 @@ cscope.* > > > tags > > > TAGS > > > *~ > > > +!scripts/qemu-guest-agent/fsfreeze-hook.d > > > > Why? Do we expect to have *~ files in there? > > I think default vim configurations will copy <file> to <file>~ prior to > editing. But should that be tracked by git specifically in that dir? > > > 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 {} + > > > > What does this change have to do with this patch? > > Looks like it'll try (and fail, due to lack of -r option to rm) to > delete the fsfreeze-hook.d directory on `make clean`. For in-tree builds > at least. I can't see it, but well, I don't want to hold this patch for minor things either... It looks good for me apart from these two nitpicks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 13:55 ` Luiz Capitulino 2012-12-07 17:47 ` mdroth @ 2012-12-07 18:22 ` Eric Blake 2012-12-07 18:31 ` Luiz Capitulino 1 sibling, 1 reply; 14+ messages in thread From: Eric Blake @ 2012-12-07 18:22 UTC (permalink / raw) To: Luiz Capitulino; +Cc: Tomoki Sekiyama, qemu-devel, mdroth [-- Attachment #1: Type: text/plain, Size: 2091 bytes --] On 12/07/2012 06:55 AM, Luiz Capitulino wrote: > On Fri, 07 Dec 2012 17:39:32 +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> >> --- >> .gitignore | 1 >> Makefile | 2 - >> scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ >> .../fsfreeze-hook.d/mysql-flush.sh.sample | 55 ++++++++++++++++++++ >> 4 files changed, 90 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..286822d 100644 >> --- a/.gitignore >> +++ b/.gitignore >> @@ -93,3 +93,4 @@ cscope.* >> tags >> TAGS >> *~ >> +!scripts/qemu-guest-agent/fsfreeze-hook.d > > Why? Do we expect to have *~ files in there? What does your question have to do with the patch, which isn't even touching the pre-existing *~ line? > >> 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 {} + > > What does this change have to do with this patch? Because this patch introduces a directory scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample that belongs to the repo and therefore must not be cleaned. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 619 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 18:22 ` Eric Blake @ 2012-12-07 18:31 ` Luiz Capitulino 2012-12-07 18:37 ` Eric Blake 0 siblings, 1 reply; 14+ messages in thread From: Luiz Capitulino @ 2012-12-07 18:31 UTC (permalink / raw) To: Eric Blake; +Cc: Tomoki Sekiyama, qemu-devel, mdroth On Fri, 07 Dec 2012 11:22:54 -0700 Eric Blake <eblake@redhat.com> wrote: > On 12/07/2012 06:55 AM, Luiz Capitulino wrote: > > On Fri, 07 Dec 2012 17:39:32 +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> > >> --- > >> .gitignore | 1 > >> Makefile | 2 - > >> scripts/qemu-guest-agent/fsfreeze-hook | 33 ++++++++++++ > >> .../fsfreeze-hook.d/mysql-flush.sh.sample | 55 ++++++++++++++++++++ > >> 4 files changed, 90 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..286822d 100644 > >> --- a/.gitignore > >> +++ b/.gitignore > >> @@ -93,3 +93,4 @@ cscope.* > >> tags > >> TAGS > >> *~ > >> +!scripts/qemu-guest-agent/fsfreeze-hook.d > > > > Why? Do we expect to have *~ files in there? > > What does your question have to do with the patch, which isn't even > touching the pre-existing *~ line? As far I could understand the ! prefix in gitignore documention, it's changing the *~ meaning for the fsfreeze-hoo.d directory, and I wanted to understand why. > >> 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 {} + > > > > What does this change have to do with this patch? > > Because this patch introduces a directory > scripts/qemu-guest-agent/fsfreeze-hook.d/mysql-flush.sh.sample that > belongs to the repo and therefore must not be cleaned. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 18:31 ` Luiz Capitulino @ 2012-12-07 18:37 ` Eric Blake 2012-12-07 18:57 ` Luiz Capitulino 0 siblings, 1 reply; 14+ messages in thread From: Eric Blake @ 2012-12-07 18:37 UTC (permalink / raw) To: Luiz Capitulino; +Cc: Tomoki Sekiyama, qemu-devel, mdroth [-- Attachment #1: Type: text/plain, Size: 1151 bytes --] On 12/07/2012 11:31 AM, Luiz Capitulino wrote: >>>> +++ b/.gitignore >>>> @@ -93,3 +93,4 @@ cscope.* >>>> tags >>>> TAGS >>>> *~ >>>> +!scripts/qemu-guest-agent/fsfreeze-hook.d >>> >>> Why? Do we expect to have *~ files in there? >> >> What does your question have to do with the patch, which isn't even >> touching the pre-existing *~ line? > > As far I could understand the ! prefix in gitignore documention, it's > changing the *~ meaning for the fsfreeze-hoo.d directory, and I wanted > to understand why. > No, it is changing a much earlier line: *.d to say that this _particular_ .d is allowed to be committed. It has nothing to do with *~. Still, I have to wonder if we really want to store these files in a .d in the repository itself, or if we should store them under some other file name and only at 'make install' time insert them into a .d at the install destination. It would clean up this confusion about the .gitignore as well as the change to the 'find' command during 'make clean'. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 619 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 18:37 ` Eric Blake @ 2012-12-07 18:57 ` Luiz Capitulino 2012-12-10 6:23 ` Tomoki Sekiyama 0 siblings, 1 reply; 14+ messages in thread From: Luiz Capitulino @ 2012-12-07 18:57 UTC (permalink / raw) To: Eric Blake; +Cc: Tomoki Sekiyama, qemu-devel, mdroth On Fri, 07 Dec 2012 11:37:44 -0700 Eric Blake <eblake@redhat.com> wrote: > On 12/07/2012 11:31 AM, Luiz Capitulino wrote: > >>>> +++ b/.gitignore > >>>> @@ -93,3 +93,4 @@ cscope.* > >>>> tags > >>>> TAGS > >>>> *~ > >>>> +!scripts/qemu-guest-agent/fsfreeze-hook.d > >>> > >>> Why? Do we expect to have *~ files in there? > >> > >> What does your question have to do with the patch, which isn't even > >> touching the pre-existing *~ line? > > > > As far I could understand the ! prefix in gitignore documention, it's > > changing the *~ meaning for the fsfreeze-hoo.d directory, and I wanted > > to understand why. > > > > No, it is changing a much earlier line: > > *.d > > to say that this _particular_ .d is allowed to be committed. It has > nothing to do with *~. Ah, now it makes a lot of sense, thanks Eric. It would be nice to move it right below *.d, to avoid stupid comments :) > Still, I have to wonder if we really want to store these files in a .d > in the repository itself, or if we should store them under some other > file name and only at 'make install' time insert them into a .d at the > install destination. It would clean up this confusion about the > .gitignore as well as the change to the 'find' command during 'make clean'. Well, now that I understand it both ways are fine with me (ie. what you suggest and what's been implemented in this patch). ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 18:57 ` Luiz Capitulino @ 2012-12-10 6:23 ` Tomoki Sekiyama 0 siblings, 0 replies; 14+ messages in thread From: Tomoki Sekiyama @ 2012-12-10 6:23 UTC (permalink / raw) To: lcapitulino; +Cc: qemu-devel, mdroth Hi, sorry for my late reply. On 2012/12/08 3:57, Luiz Capitulino wrote: > On Fri, 07 Dec 2012 11:37:44 -0700 > Eric Blake <eblake@redhat.com> wrote: > >> On 12/07/2012 11:31 AM, Luiz Capitulino wrote: >>>>>> +++ b/.gitignore >>>>>> @@ -93,3 +93,4 @@ cscope.* >>>>>> tags >>>>>> TAGS >>>>>> *~ >>>>>> +!scripts/qemu-guest-agent/fsfreeze-hook.d >>>>> >>>>> Why? Do we expect to have *~ files in there? >>>> >>>> What does your question have to do with the patch, which isn't even >>>> touching the pre-existing *~ line? >>> >>> As far I could understand the ! prefix in gitignore documention, it's >>> changing the *~ meaning for the fsfreeze-hoo.d directory, and I wanted >>> to understand why. >>> >> >> No, it is changing a much earlier line: >> >> *.d >> >> to say that this _particular_ .d is allowed to be committed. It has >> nothing to do with *~. Yes, it's for adding fsfreeze-hook.d into the repo. > Ah, now it makes a lot of sense, thanks Eric. > > It would be nice to move it right below *.d, to avoid stupid comments :) And OK, I will move this there. >> Still, I have to wonder if we really want to store these files in a .d >> in the repository itself, or if we should store them under some other >> file name and only at 'make install' time insert them into a .d at the >> install destination. It would clean up this confusion about the >> .gitignore as well as the change to the 'find' command during 'make clean'. > > Well, now that I understand it both ways are fine with me (ie. what you > suggest and what's been implemented in this patch). Then I'd like to keep current implementation. Thanks, -- Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 2012-12-07 13:55 ` Luiz Capitulino @ 2012-12-07 18:34 ` Eric Blake 2012-12-10 6:23 ` Tomoki Sekiyama 1 sibling, 1 reply; 14+ messages in thread From: Eric Blake @ 2012-12-07 18:34 UTC (permalink / raw) To: Tomoki Sekiyama; +Cc: lcapitulino, qemu-devel, mdroth [-- Attachment #1: Type: text/plain, Size: 2930 bytes --] On 12/07/2012 01:39 AM, Tomoki Sekiyama 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> > --- > @@ -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 freezed. And for fsfreeze-thaw s/freezed/frozen/ > + > +# Iterate executables in directory "fsfreeze-hook.d" with the specified args > +[ ! -d "$FSFREEZE_D" ] && exit 1 Do you really want to fail the entire operation if the directory doesn't exist? Shouldn't you instead exit 0 because there is nothing to do? > +for file in "$FSFREEZE_D"/* ; do > + is_ignored_file "$file" && continue > + [ -x "$file" ] || continue > + echo "$(date): execute $file $@" >>$LOGFILE This is unsafe (although the worst that will happen is a poor message to the log file). $file might contain backslash, and echo cannot portably be mixed with backslash. Use printf(1) instead. > + "$file" "$@" >>$LOGFILE 2>&1 > + STATUS=$? > + echo "$(date): $file finished with status=$STATUS" >>$LOGFILE Again. > @@ -0,0 +1,55 @@ > +#!/bin/sh > + > +# Flush MySQL tables to the disk before the filesystem is freezed. s/freezed/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=/tmp/mysql-flush.fifo > +MYSQL_CMD="$MYSQL $MYSQL_OPTS" > + > +# Check mysql is installed and the server running > +[ -x $MYSQL ] && $MYSQL_CMD < /dev/null || exit 0 Safe as written, since you just initialized $MYSQL above; but risky, since the mere use of MYSQL in the initialization might encourage someone to point to an alternate path that includes spaces. Then again, if they do that, then MYSQL_CMD is broken. It might be better to be explicit and write [ -x "$MYSQL" ] && "$MYSQL" $MYSQL_OPTS < /dev/null but I won't insist. > + # for InnoDB, wait until every log is flushed > + INNODB_STATUS=$(mktemp /tmp/mysql-flush.XXXXXX) > + [ $? -ne 0 ] && exit 2 > + trap "rm -f $INNODB_STATUS" SIGINT POSIX says that 'trap foo INT' is required to work, but 'trap foo SIGINT' is optional. Also, shouldn't you also worry about HUP, ALRM, and TERM? -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 619 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks 2012-12-07 18:34 ` Eric Blake @ 2012-12-10 6:23 ` Tomoki Sekiyama 0 siblings, 0 replies; 14+ messages in thread From: Tomoki Sekiyama @ 2012-12-10 6:23 UTC (permalink / raw) To: eblake; +Cc: lcapitulino, qemu-devel, mdroth Hi Eric, Thanks for your review. On 2012/12/08 3:34, Eric Blake wrote: > On 12/07/2012 01:39 AM, Tomoki Sekiyama 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> >> --- > >> @@ -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 freezed. And for fsfreeze-thaw > > s/freezed/frozen/ Oops... >> + >> +# Iterate executables in directory "fsfreeze-hook.d" with the specified args >> +[ ! -d "$FSFREEZE_D" ] && exit 1 > > Do you really want to fail the entire operation if the directory doesn't > exist? Shouldn't you instead exit 0 because there is nothing to do? I thought that was installation failure, but this might be too cautious. Exiting 0 is also reasonable, so I will change this. >> +for file in "$FSFREEZE_D"/* ; do >> + is_ignored_file "$file" && continue >> + [ -x "$file" ] || continue >> + echo "$(date): execute $file $@" >>$LOGFILE > > This is unsafe (although the worst that will happen is a poor message to > the log file). $file might contain backslash, and echo cannot portably > be mixed with backslash. Use printf(1) instead. OK, I will use printf here, and >> + "$file" "$@" >>$LOGFILE 2>&1 >> + STATUS=$? >> + echo "$(date): $file finished with status=$STATUS" >>$LOGFILE > > Again. here too. >> @@ -0,0 +1,55 @@ >> +#!/bin/sh >> + >> +# Flush MySQL tables to the disk before the filesystem is freezed. > > s/freezed/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=/tmp/mysql-flush.fifo >> +MYSQL_CMD="$MYSQL $MYSQL_OPTS" >> + >> +# Check mysql is installed and the server running >> +[ -x $MYSQL ] && $MYSQL_CMD < /dev/null || exit 0 > > Safe as written, since you just initialized $MYSQL above; but risky, > since the mere use of MYSQL in the initialization might encourage > someone to point to an alternate path that includes spaces. Then again, > if they do that, then MYSQL_CMD is broken. It might be better to be > explicit and write > [ -x "$MYSQL" ] && "$MYSQL" $MYSQL_OPTS < /dev/null > but I won't insist. OK, I will replace $MYSQL_CMD with "$MYSQL" $MYSQL_OPTS. >> + # for InnoDB, wait until every log is flushed >> + INNODB_STATUS=$(mktemp /tmp/mysql-flush.XXXXXX) >> + [ $? -ne 0 ] && exit 2 >> + trap "rm -f $INNODB_STATUS" SIGINT > > POSIX says that 'trap foo INT' is required to work, but 'trap foo > SIGINT' is optional. Also, shouldn't you also worry about HUP, ALRM, > and TERM? I will fix this to trap "..." HUP INT QUIT ALRM TERM Thanks, -- Tomoki Sekiyama <tomoki.sekiyama.qu@hitachi.com> Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-12-10 6:22 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-07 8:39 [Qemu-devel] [PATCH v7 0/2] qemu-ga: add hook to quiesce the guest on fsfreeze-freeze/thaw Tomoki Sekiyama 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 1/2] qemu-ga: execute " Tomoki Sekiyama 2012-12-07 13:52 ` Luiz Capitulino 2012-12-07 8:39 ` [Qemu-devel] [PATCH v7 2/2] qemu-ga: sample fsfreeze hooks Tomoki Sekiyama 2012-12-07 13:55 ` Luiz Capitulino 2012-12-07 17:47 ` mdroth 2012-12-07 18:29 ` Luiz Capitulino 2012-12-07 18:22 ` Eric Blake 2012-12-07 18:31 ` Luiz Capitulino 2012-12-07 18:37 ` Eric Blake 2012-12-07 18:57 ` Luiz Capitulino 2012-12-10 6:23 ` Tomoki Sekiyama 2012-12-07 18:34 ` Eric Blake 2012-12-10 6:23 ` Tomoki Sekiyama
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).