@@ -1310,6 +1310,54 @@ STEXI
Fetch and re-negotiate guest agent capabilties
ETEXI
+ {
+ .name = "agent_fsfreeze",
+ .args_type = "",
+ .params = "",
+ .help = "Freeze all local file systems mounted in the guest",
+ .user_print = do_agent_fsfreeze_print,
+ .mhandler.cmd_async = do_agent_fsfreeze,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+
+STEXI
+@item agent_fsfreeze
+@findex agent_fsfreeze
+Freeze all local mounted file systems in guest
+ETEXI
+
+ {
+ .name = "agent_fsthaw",
+ .args_type = "",
+ .params = "",
+ .help = "Thaw all local file systems mounted in the guest",
+ .user_print = do_agent_fsthaw_print,
+ .mhandler.cmd_async = do_agent_fsthaw,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+
+STEXI
+@item agent_fsthaw
+@findex agent_fsthaw
+Thaw all local mounted file systems in guest
+ETEXI
+
+ {
+ .name = "agent_fsstatus",
+ .args_type = "",
+ .params = "",
+ .help = "Display status of file system freeze progress in guest",
+ .user_print = do_agent_fsstatus_print,
+ .mhandler.cmd_async = do_agent_fsstatus,
+ .flags = MONITOR_CMD_ASYNC,
+ },
+
+STEXI
+@item agent_fsstatus
+@findex agent_fsstatus
+Get status of file system freeze in guest
+ETEXI
+
STEXI
@end table
ETEXI
@@ -24,6 +24,7 @@
#include "monitor.h"
#include "virtagent-server.h"
#include "virtagent.h"
+#include "qint.h"
#define DEBUG_VA
@@ -640,3 +640,238 @@ int va_send_hello(void)
xmlrpc_DECREF(params);
return ret;
}
+
+void do_agent_fsfreeze_print(Monitor *mon, const QObject *data)
+{
+ TRACE("called");
+
+ monitor_printf(mon, "File systems frozen: %" PRId64 "\n",
+ qint_get_int((qobject_to_qint(data))));
+}
+
+static void do_agent_fsfreeze_cb(const char *resp_data,
+ size_t resp_data_len,
+ MonitorCompletion *mon_cb,
+ void *mon_data)
+{
+ xmlrpc_value *resp = NULL;
+ xmlrpc_env env;
+ xmlrpc_int32 retval = 0;
+ QInt *qint;
+
+ TRACE("called");
+
+ if (resp_data == NULL) {
+ LOG("error handling RPC request");
+ return;
+ }
+
+ xmlrpc_env_init(&env);
+ resp = xmlrpc_parse_response(&env, resp_data, resp_data_len);
+ if (va_rpc_has_error(&env)) {
+ LOG("error parsing RPC response");
+ return;
+ }
+
+ xmlrpc_parse_value(&env, resp, "i", &retval);
+ if (va_rpc_has_error(&env)) {
+ retval = -1;
+ goto out;
+ }
+
+out:
+ qint = qint_from_int(retval);
+ xmlrpc_DECREF(resp);
+ if (mon_cb) {
+ mon_cb(mon_data, QOBJECT(qint));
+ }
+ qobject_decref(QOBJECT(qint));
+}
+
+int do_agent_fsfreeze(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque)
+{
+ xmlrpc_env env;
+ xmlrpc_value *params;
+ int ret;
+
+ TRACE("called");
+
+ xmlrpc_env_init(&env);
+ params = xmlrpc_build_value(&env, "()");
+ if (va_rpc_has_error(&env)) {
+ return -1;
+ }
+
+ ret = va_do_rpc(&env, "va.fsfreeze", params, do_agent_fsfreeze_cb,
+ cb, opaque);
+ if (ret) {
+ qerror_report(QERR_VA_FAILED, ret, strerror(ret));
+ }
+ xmlrpc_DECREF(params);
+ return ret;
+}
+
+void do_agent_fsthaw_print(Monitor *mon, const QObject *data)
+{
+ TRACE("called");
+
+ monitor_printf(mon, "File systems thawed: %" PRId64 "\n",
+ qint_get_int((qobject_to_qint(data))));
+}
+
+static void do_agent_fsthaw_cb(const char *resp_data,
+ size_t resp_data_len,
+ MonitorCompletion *mon_cb,
+ void *mon_data)
+{
+ xmlrpc_value *resp = NULL;
+ xmlrpc_env env;
+ xmlrpc_int32 retval = 0;
+ QInt *qint;
+
+ TRACE("called");
+
+ if (resp_data == NULL) {
+ LOG("error handling RPC request");
+ return;
+ }
+
+ xmlrpc_env_init(&env);
+ resp = xmlrpc_parse_response(&env, resp_data, resp_data_len);
+ if (va_rpc_has_error(&env)) {
+ LOG("error parsing RPC response");
+ return;
+ }
+
+ xmlrpc_parse_value(&env, resp, "i", &retval);
+ if (va_rpc_has_error(&env)) {
+ retval = -1;
+ goto out;
+ }
+
+out:
+ qint = qint_from_int(retval);
+ xmlrpc_DECREF(resp);
+ if (mon_cb) {
+ mon_cb(mon_data, QOBJECT(qint));
+ }
+ qobject_decref(QOBJECT(qint));
+}
+
+int do_agent_fsthaw(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque)
+{
+ xmlrpc_env env;
+ xmlrpc_value *params;
+ int ret;
+
+ TRACE("called");
+
+ xmlrpc_env_init(&env);
+ params = xmlrpc_build_value(&env, "()");
+ if (va_rpc_has_error(&env)) {
+ return -1;
+ }
+
+ ret = va_do_rpc(&env, "va.fsthaw", params, do_agent_fsthaw_cb, cb, opaque);
+ if (ret) {
+ qerror_report(QERR_VA_FAILED, ret, strerror(ret));
+ }
+ xmlrpc_DECREF(params);
+ return ret;
+}
+
+void do_agent_fsstatus_print(Monitor *mon, const QObject *data)
+{
+ int64_t fsstatus;
+ TRACE("called");
+
+ fsstatus = qint_get_int((qobject_to_qint(data)));
+
+ monitor_printf(mon, "File systems freeze status: ");
+ switch(fsstatus) {
+ case FREEZE_THAWED:
+ monitor_printf(mon, "Thawed");
+ break;
+ case FREEZE_INPROGRESS:
+ monitor_printf(mon, "Freeze in progress");
+ break;
+ case FREEZE_THAWINPROGRESS:
+ monitor_printf(mon, "Thaw in progress");
+ break;
+ case FREEZE_FROZEN:
+ monitor_printf(mon, "Frozen");
+ break;
+ case FREEZE_ERROR:
+ monitor_printf(mon, "Error");
+ break;
+ default:
+ monitor_printf(mon, "unknown");
+ }
+
+ monitor_printf(mon, "\n");
+}
+
+static void do_agent_fsstatus_cb(const char *resp_data,
+ size_t resp_data_len,
+ MonitorCompletion *mon_cb,
+ void *mon_data)
+{
+ xmlrpc_value *resp = NULL;
+ xmlrpc_env env;
+ xmlrpc_int32 retval = 0;
+ QInt *qint;
+
+ TRACE("called");
+
+ if (resp_data == NULL) {
+ LOG("error handling RPC request");
+ return;
+ }
+
+ xmlrpc_env_init(&env);
+ resp = xmlrpc_parse_response(&env, resp_data, resp_data_len);
+ if (va_rpc_has_error(&env)) {
+ LOG("error parsing RPC response");
+ return;
+ }
+
+ xmlrpc_parse_value(&env, resp, "i", &retval);
+ if (va_rpc_has_error(&env)) {
+ retval = -1;
+ goto out;
+ }
+
+out:
+ qint = qint_from_int(retval);
+ xmlrpc_DECREF(resp);
+ if (mon_cb) {
+ mon_cb(mon_data, QOBJECT(qint));
+ }
+ qobject_decref(QOBJECT(qint));
+}
+
+int do_agent_fsstatus(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque)
+{
+ xmlrpc_env env;
+ xmlrpc_value *params;
+ int ret;
+
+ TRACE("called");
+
+ xmlrpc_env_init(&env);
+ params = xmlrpc_build_value(&env, "()");
+ if (va_rpc_has_error(&env)) {
+ return -1;
+ }
+
+ ret = va_do_rpc(&env, "va.fsstatus", params, do_agent_fsstatus_cb,
+ cb, opaque);
+ if (ret) {
+ qerror_report(QERR_VA_FAILED, ret, strerror(ret));
+ }
+ xmlrpc_DECREF(params);
+ return ret;
+}
@@ -46,5 +46,14 @@ int do_agent_capabilities(Monitor *mon, const QDict *mon_params,
MonitorCompletion cb, void *opaque);
int va_client_init_capabilities(void);
int va_send_hello(void);
+void do_agent_fsfreeze_print(Monitor *mon, const QObject *qobject);
+int do_agent_fsfreeze(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque);
+void do_agent_fsthaw_print(Monitor *mon, const QObject *qobject);
+int do_agent_fsthaw(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque);
+void do_agent_fsstatus_print(Monitor *mon, const QObject *qobject);
+int do_agent_fsstatus(Monitor *mon, const QDict *mon_params,
+ MonitorCompletion cb, void *opaque);
#endif /* VIRTAGENT_H */