const char *volumes;
Bool freeze;
Bool canceled;
- SyncDriverHandle syncHandle;
+ SyncDriverHandle *syncHandle;
+ gboolean syncEnabled;
} VmBackupDriverOp;
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VmBackupDriverThaw --
+ *
+ * Thaws the frozen filesystems, and cleans up internal state kept by the
+ * code.
+ *
+ * Results:
+ * Whether thawing was successful.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Bool
+VmBackupDriverThaw(VmBackupDriverOp *op)
+{
+ Bool success = SyncDriver_Thaw(*op->syncHandle);
+ SyncDriver_CloseHandle(op->syncHandle);
+ return success;
+}
+
+
/*
*-----------------------------------------------------------------------------
*
* VmBackupDriverOpQuery --
*
- * Checks the status of the app that is enabling or disabling the
+ * Checks the status of the operation that is enabling or disabling the
* sync driver.
*
* Result
- * None.
+ * VMBACKUP_STATUS_PENDING: still working.
+ * VMBACKUP_STATUS_FINISHED: done.
+ * VMBACKUP_STATUS_CANCELED: cancel request fulfilled.
+ * VMBACKUP_STATUS_ERROR: oops.
*
* Side effects:
* None.
VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
VmBackupOpStatus ret;
- SyncDriverStatus st;
-
- st = SyncDriver_QueryStatus(op->syncHandle, 0);
- g_debug("SyncDriver status: %d\n", st);
-
- switch(st) {
- case SYNCDRIVER_BUSY:
- ret = VMBACKUP_STATUS_PENDING;
- break;
+ if (!op->syncEnabled) {
+ return VMBACKUP_STATUS_FINISHED;
+ }
- case SYNCDRIVER_IDLE:
- if (op->freeze && op->canceled) {
- SyncDriver_Thaw(op->syncHandle);
+ if (op->freeze) {
+ SyncDriverStatus st = SyncDriver_QueryStatus(*op->syncHandle, 0);
+
+ g_debug("SyncDriver status: %d\n", st);
+ switch(st) {
+ case SYNCDRIVER_BUSY:
+ ret = VMBACKUP_STATUS_PENDING;
+ break;
+
+ case SYNCDRIVER_IDLE:
+ if (op->canceled) {
+ VmBackupDriverThaw(op);
+ }
+ ret = (op->canceled) ? VMBACKUP_STATUS_CANCELED : VMBACKUP_STATUS_FINISHED;
+ break;
+
+ default:
+ VmBackupDriverThaw(op);
+ ret = VMBACKUP_STATUS_ERROR;
+ break;
}
- ret = (op->canceled) ? VMBACKUP_STATUS_CANCELED : VMBACKUP_STATUS_FINISHED;
- break;
-
- default:
- ret = VMBACKUP_STATUS_ERROR;
- break;
+ } else {
+ ret = VMBACKUP_STATUS_FINISHED;
}
return ret;
VmBackupDriverOpRelease(VmBackupOp *_op) // IN
{
VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
- if (!op->freeze) {
- SyncDriver_CloseHandle(&op->syncHandle);
- }
+ free(op->syncHandle);
free(op);
}
*/
static VmBackupDriverOp *
-VmBackupNewDriverOp(Bool freeze, // IN
- SyncDriverHandle handle, // IN
- const char *volumes) // IN
+VmBackupNewDriverOp(VmBackupState *state, // IN
+ Bool freeze, // IN
+ SyncDriverHandle *handle, // IN
+ const char *volumes) // IN
{
+ GError *err = NULL;
VmBackupDriverOp *op = NULL;
+ g_return_val_if_fail((handle == NULL || *handle == SYNCDRIVER_INVALID_HANDLE) ||
+ !freeze,
+ NULL);
+
op = Util_SafeMalloc(sizeof *op);
memset(op, 0, sizeof *op);
op->freeze = freeze;
op->volumes = volumes;
- if (freeze && !SyncDriver_Freeze(op->volumes, &handle)) {
- g_warning("Error freezing filesystems.\n");
- free(op);
- op = NULL;
- } else if (!freeze && !SyncDriver_Thaw(handle)) {
- g_warning("Error thawing filesystems.\n");
- free(op);
- op = NULL;
- } else {
- op->syncHandle = handle;
+ op->syncHandle = Util_SafeMalloc(sizeof *op->syncHandle);
+ *op->syncHandle = (handle != NULL) ? *handle : SYNCDRIVER_INVALID_HANDLE;
+ op->syncEnabled = g_key_file_get_boolean(state->ctx->config,
+ "vmbackup",
+ "enableSyncDriver",
+ &err);
+
+ /* Enable the driver by default. */
+ if (err != NULL) {
+ g_clear_error(&err);
+ op->syncEnabled = TRUE;
+ }
+
+ if (op->syncEnabled) {
+ Bool success;
+ if (freeze) {
+ success = SyncDriver_Freeze(op->volumes, op->syncHandle);
+ } else {
+ success = VmBackupDriverThaw(op);
+ }
+ if (!success) {
+ g_warning("Error %s filesystems.", freeze ? "freezing" : "thawing");
+ free(op);
+ op = NULL;
+ }
}
return op;
}
static Bool
VmBackupSyncDriverReadyForSnapshot(VmBackupState *state)
{
+ SyncDriverHandle *handle = state->clientData;
+
g_debug("*** %s\n", __FUNCTION__);
- return VmBackup_SendEvent(VMBACKUP_EVENT_SNAPSHOT_COMMIT, 0, "");
+ if (handle != NULL && *handle != SYNCDRIVER_INVALID_HANDLE) {
+ return VmBackup_SendEvent(VMBACKUP_EVENT_SNAPSHOT_COMMIT, 0, "");
+ }
+ return TRUE;
}
VmBackupDriverOp *op;
g_debug("*** %s\n", __FUNCTION__);
- op = VmBackupNewDriverOp(TRUE,
- (SyncDriverHandle) state->clientData,
- state->volumes);
+ op = VmBackupNewDriverOp(state, TRUE, NULL, state->volumes);
if (op != NULL) {
- state->clientData = (intptr_t) op->syncHandle;
+ state->clientData = op->syncHandle;
}
return VmBackup_SetCurrentOp(state,
g_debug("*** %s\n", __FUNCTION__);
- op = VmBackupNewDriverOp(FALSE,
- (SyncDriverHandle) state->clientData,
- NULL);
+ op = VmBackupNewDriverOp(state, FALSE, state->clientData, NULL);
+ state->clientData = NULL;
return VmBackup_SetCurrentOp(state, (VmBackupOp *) op, NULL, __FUNCTION__);
}