|
@@ -34,6 +34,12 @@
|
|
#include "qga/service-win32.h"
|
|
#include "qga/service-win32.h"
|
|
#include <windows.h>
|
|
#include <windows.h>
|
|
#endif
|
|
#endif
|
|
|
|
+#ifdef __linux__
|
|
|
|
+#include <linux/fs.h>
|
|
|
|
+#ifdef FIFREEZE
|
|
|
|
+#define CONFIG_FSFREEZE
|
|
|
|
+#endif
|
|
|
|
+#endif
|
|
|
|
|
|
#ifndef _WIN32
|
|
#ifndef _WIN32
|
|
#define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
|
|
#define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
|
|
@@ -42,6 +48,9 @@
|
|
#endif
|
|
#endif
|
|
#define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run"
|
|
#define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run"
|
|
#define QGA_PIDFILE_DEFAULT QGA_STATEDIR_DEFAULT "/qemu-ga.pid"
|
|
#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
|
|
#define QGA_SENTINEL_BYTE 0xFF
|
|
|
|
|
|
struct GAState {
|
|
struct GAState {
|
|
@@ -64,6 +73,9 @@ struct GAState {
|
|
const char *log_filepath;
|
|
const char *log_filepath;
|
|
const char *pid_filepath;
|
|
const char *pid_filepath;
|
|
} deferred_options;
|
|
} deferred_options;
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ const char *fsfreeze_hook;
|
|
|
|
+#endif
|
|
};
|
|
};
|
|
|
|
|
|
struct GAState *ga_state;
|
|
struct GAState *ga_state;
|
|
@@ -153,6 +165,16 @@ static void usage(const char *cmd)
|
|
" %s)\n"
|
|
" %s)\n"
|
|
" -l, --logfile set logfile path, logs to stderr by default\n"
|
|
" -l, --logfile set logfile path, logs to stderr by default\n"
|
|
" -f, --pidfile specify pidfile (default is %s)\n"
|
|
" -f, --pidfile specify pidfile (default is %s)\n"
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+" -F, --fsfreeze-hook\n"
|
|
|
|
+" enable fsfreeze hook. Accepts an optional argument that\n"
|
|
|
|
+" specifies script to run on freeze/thaw. Script will be\n"
|
|
|
|
+" called with 'freeze'/'thaw' arguments accordingly.\n"
|
|
|
|
+" (default is %s)\n"
|
|
|
|
+" If using -F with an argument, do not follow -F with a\n"
|
|
|
|
+" space.\n"
|
|
|
|
+" (for example: -F/var/run/fsfreezehook.sh)\n"
|
|
|
|
+#endif
|
|
" -t, --statedir specify dir to store state information (absolute paths\n"
|
|
" -t, --statedir specify dir to store state information (absolute paths\n"
|
|
" only, default is %s)\n"
|
|
" only, default is %s)\n"
|
|
" -v, --verbose log extra debugging information\n"
|
|
" -v, --verbose log extra debugging information\n"
|
|
@@ -167,6 +189,9 @@ static void usage(const char *cmd)
|
|
"\n"
|
|
"\n"
|
|
"Report bugs to <mdroth@linux.vnet.ibm.com>\n"
|
|
"Report bugs to <mdroth@linux.vnet.ibm.com>\n"
|
|
, cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT,
|
|
, cmd, QEMU_VERSION, QGA_VIRTIO_PATH_DEFAULT, QGA_PIDFILE_DEFAULT,
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ QGA_FSFREEZE_HOOK_DEFAULT,
|
|
|
|
+#endif
|
|
QGA_STATEDIR_DEFAULT);
|
|
QGA_STATEDIR_DEFAULT);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -401,6 +426,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)
|
|
static void become_daemon(const char *pidfile)
|
|
{
|
|
{
|
|
#ifndef _WIN32
|
|
#ifndef _WIN32
|
|
@@ -678,10 +710,13 @@ VOID WINAPI service_main(DWORD argc, TCHAR *argv[])
|
|
|
|
|
|
int main(int argc, char **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 *method = NULL, *path = NULL;
|
|
const char *log_filepath = NULL;
|
|
const char *log_filepath = NULL;
|
|
const char *pid_filepath = QGA_PIDFILE_DEFAULT;
|
|
const char *pid_filepath = QGA_PIDFILE_DEFAULT;
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ const char *fsfreeze_hook = NULL;
|
|
|
|
+#endif
|
|
const char *state_dir = QGA_STATEDIR_DEFAULT;
|
|
const char *state_dir = QGA_STATEDIR_DEFAULT;
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
const char *service = NULL;
|
|
const char *service = NULL;
|
|
@@ -691,6 +726,9 @@ int main(int argc, char **argv)
|
|
{ "version", 0, NULL, 'V' },
|
|
{ "version", 0, NULL, 'V' },
|
|
{ "logfile", 1, NULL, 'l' },
|
|
{ "logfile", 1, NULL, 'l' },
|
|
{ "pidfile", 1, NULL, 'f' },
|
|
{ "pidfile", 1, NULL, 'f' },
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ { "fsfreeze-hook", 2, NULL, 'F' },
|
|
|
|
+#endif
|
|
{ "verbose", 0, NULL, 'v' },
|
|
{ "verbose", 0, NULL, 'v' },
|
|
{ "method", 1, NULL, 'm' },
|
|
{ "method", 1, NULL, 'm' },
|
|
{ "path", 1, NULL, 'p' },
|
|
{ "path", 1, NULL, 'p' },
|
|
@@ -723,6 +761,11 @@ int main(int argc, char **argv)
|
|
case 'f':
|
|
case 'f':
|
|
pid_filepath = optarg;
|
|
pid_filepath = optarg;
|
|
break;
|
|
break;
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ case 'F':
|
|
|
|
+ fsfreeze_hook = optarg ? optarg : QGA_FSFREEZE_HOOK_DEFAULT;
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
case 't':
|
|
case 't':
|
|
state_dir = optarg;
|
|
state_dir = optarg;
|
|
break;
|
|
break;
|
|
@@ -786,6 +829,9 @@ int main(int argc, char **argv)
|
|
s = g_malloc0(sizeof(GAState));
|
|
s = g_malloc0(sizeof(GAState));
|
|
s->log_level = log_level;
|
|
s->log_level = log_level;
|
|
s->log_file = stderr;
|
|
s->log_file = stderr;
|
|
|
|
+#ifdef CONFIG_FSFREEZE
|
|
|
|
+ s->fsfreeze_hook = fsfreeze_hook;
|
|
|
|
+#endif
|
|
g_log_set_default_handler(ga_log, s);
|
|
g_log_set_default_handler(ga_log, s);
|
|
g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR);
|
|
g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR);
|
|
ga_enable_logging(s);
|
|
ga_enable_logging(s);
|