/*********************************************************
- * Copyright (C) 2005-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#include "vm_basic_types.h"
-#ifdef _WIN32 /* { */
+#if defined(_WIN32) /* { */
# include <windows.h>
# define SYNCDRIVER_INVALID_HANDLE INVALID_HANDLE_VALUE
SyncDriverStatus SyncDriver_QueryStatus(const SyncDriverHandle handle,
int32 timeout);
void SyncDriver_CloseHandle(SyncDriverHandle *handle);
+#if defined(__linux__)
+void SyncDriver_GetAttr(const SyncDriverHandle handle, const char **name,
+ Bool *quiesces);
+#endif
#endif
/*********************************************************
- * Copyright (C) 2011-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
typedef struct SyncHandle {
SyncDriverErr (*thaw)(const SyncDriverHandle handle);
void (*close)(SyncDriverHandle handle);
+#if defined(__linux__)
+ void (*getattr)(const SyncDriverHandle handle, const char **name,
+ Bool *quiesces);
+#endif
} SyncHandle;
#if defined(__linux__)
}
+/*
+ *******************************************************************************
+ * LinuxFiGetAttr -- */ /**
+ *
+ * Return some attributes of the backend provider
+ *
+ * @param[out] name name of backend provider
+ * @param[out] quiesces TRUE (FALSE) if provider is (is not) capable
+ * of quiescing.
+ *
+ *******************************************************************************
+ */
+
+static void
+LinuxFiGetAttr(const SyncDriverHandle handle, // IN (ignored)
+ const char **name, // OUT
+ Bool *quiesces) // OUT
+{
+ *name = "fifreeze";
+ *quiesces = TRUE;
+}
+
+
/*
*******************************************************************************
* LinuxDriver_Freeze -- */ /**
sync->driver.thaw = LinuxFiThaw;
sync->driver.close = LinuxFiClose;
+ sync->driver.getattr = LinuxFiGetAttr;
/*
* Ensure we did not get an empty list
/*********************************************************
- * Copyright (C) 2005-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
}
}
+
+#if defined(__linux__)
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SyncDriver_GetAttr --
+ *
+ * Returns attributes of the backend provider for this handle.
+ * If the backend does not supply a getattr function, it's treated
+ * as non-quiescing.
+ *
+ * Results:
+ * No return value.
+ * Sets OUT parameters:
+ * *name: pointer to backend provider name
+ * *quiesces: indicates whether backend is capable of quiescing.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SyncDriver_GetAttr(const SyncDriverHandle handle, // IN
+ const char **name, // OUT
+ Bool *quiesces) // OUT
+{
+
+ if (handle != SYNCDRIVER_INVALID_HANDLE && handle->getattr != NULL) {
+ handle->getattr(handle, name, quiesces);
+ } else {
+ *name = NULL;
+ *quiesces = FALSE;
+ }
+}
+#endif /* __linux__ */
################################################################################
-### Copyright (C) 2009-2016 VMware, Inc. All rights reserved.
+### Copyright (C) 2009-2017 VMware, Inc. All rights reserved.
###
### This program is free software; you can redistribute it and/or modify
### it under the terms of version 2 of the GNU General Public License as
libvmbackup_la_SOURCES += scriptOps.c
libvmbackup_la_SOURCES += stateMachine.c
libvmbackup_la_SOURCES += syncDriverOps.c
+libvmbackup_la_SOURCES += syncManifest.c
libvmbackup_la_SOURCES += vmBackupSignals.c
BUILT_SOURCES =
#include "procMgr.h"
#include "syncDriver.h"
#include "util.h"
+#include "syncManifest.h"
#ifdef _WIN32
#include <windows.h>
Bool freeze;
Bool canceled;
SyncDriverHandle *syncHandle;
+ SyncManifest *manifest;
} VmBackupDriverOp;
break;
}
} else {
+ if (op->manifest != NULL) {
+ SyncManifestSend(op->manifest);
+ }
ret = VMBACKUP_STATUS_FINISHED;
}
VmBackupDriverOpRelease(VmBackupOp *_op) // IN
{
VmBackupDriverOp *op = (VmBackupDriverOp *) _op;
+
g_free(op->syncHandle);
+ SyncManifestRelease(op->manifest);
free(op);
}
state->enableNullDriver : FALSE,
op->syncHandle);
} else {
+ op->manifest = SyncNewManifest(state, *op->syncHandle);
success = VmBackupDriverThaw(op->syncHandle);
}
if (!success) {
g_warning("Error %s filesystems.", freeze ? "freezing" : "thawing");
g_free(op->syncHandle);
+ SyncManifestRelease(op->manifest);
free(op);
op = NULL;
}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2017 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * syncManifest.c --
+ *
+ * Implements a simple xml-based backup manifest file for quiesced snapshots
+ * on Linux.
+ */
+
+#include "vmBackupInt.h"
+#include "syncDriver.h"
+#include "syncManifest.h"
+#include "vm_tools_version.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * Name and format of the manifest file.
+ */
+static const char syncManifestName[] = "quiesce_manifest.xml";
+static const char syncManifestFmt[] = {
+ "<quiesceManifest>\n"
+ " <productVersion>%d</productVersion>\n" /* version of tools */
+ " <providerName>%s</providerName>\n" /* name of backend provider */
+ "</quiesceManifest>\n"
+};
+
+/*
+ * tools.conf switch to enable manifest generation
+ */
+static const char syncManifestSwitch[] = "enableXmlManifest";
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SyncNewManifest --
+ *
+ * Create a new SyncManifest structure.
+ *
+ * Results:
+ * Pointer to structure on success, otherwise NULL.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+SyncManifest *
+SyncNewManifest(VmBackupState *state, // IN
+ SyncDriverHandle handle) // IN
+{
+ Bool providerQuiesces;
+ const char *providerName;
+ SyncManifest *manifest;
+
+ /*
+ * XXX - feature is to be disabled by default until approved by QE.
+ */
+ if (!VMTools_ConfigGetBoolean(state->ctx->config, "vmbackup",
+ syncManifestSwitch, FALSE)) {
+ g_debug("No backup manifest - %s is false\n",
+ syncManifestSwitch);
+ return NULL;
+ }
+
+ if (!state->generateManifests) {
+ g_debug("No backup manifest requested\n");
+ return NULL;
+ }
+
+ SyncDriver_GetAttr(handle, &providerName, &providerQuiesces);
+ if (!providerQuiesces) {
+ g_debug("No backup manifest needed since using "
+ "non-quiescing backend.\n");
+ return NULL;
+ }
+
+ manifest = g_new0(SyncManifest, 1);
+ manifest->path = g_strdup_printf("%s/%s", state->configDir,
+ syncManifestName);
+ manifest->providerName = g_strdup(providerName);
+ return manifest;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SyncManifestRelease --
+ *
+ * Free a manifest structure.
+ *
+ * Results:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SyncManifestRelease(SyncManifest *manifest) // IN
+{
+ if (manifest != NULL) {
+ g_free(manifest->path);
+ g_free(manifest->providerName);
+ g_free(manifest);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SyncManifestSend --
+ *
+ * Generate manifest file and send it to vmx.
+ *
+ * Results:
+ * TRUE on success, FALSE on failure.
+ *
+ * Side effects:
+ * On success, writes out the backup manifest file for a quiesced
+ * snapshot and sends the file's path to vmx.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+SyncManifestSend(SyncManifest *manifest) // IN
+{
+ FILE *f;
+ int ret;
+
+ unlink(manifest->path);
+ f = fopen(manifest->path, "w");
+ if (f == NULL) {
+ g_warning("Error opening backup manifest file %s\n",
+ manifest->path);
+ return FALSE;
+ }
+
+ ret = fprintf(f, syncManifestFmt, TOOLS_VERSION_CURRENT,
+ manifest->providerName);
+ fclose(f);
+ if (ret < 0) {
+ g_warning("Error writing backup manifest file %s: %d %s\n",
+ manifest->path, errno, strerror(errno));
+ return FALSE;
+ }
+
+ if (!VmBackup_SendEvent(VMBACKUP_EVENT_GENERIC_MANIFEST,
+ VMBACKUP_SUCCESS, manifest->path)) {
+ g_warning("Error trying to send VMBACKUP_EVENT_GENERIC_MANIFEST.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
--- /dev/null
+/*********************************************************
+ * Copyright (C) 2017 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation version 2.1 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *********************************************************/
+
+/**
+ * @file syncManifest.h
+ *
+ * Interface definitions for sync driver manifest file generation.
+ * On Linux, generate an xml-format manifest file when quiescing
+ * is done via the sync driver backend that uses "FIFREEZE" and
+ * "FITHAW" ioctls. On other OSes, or on Linux with other sync
+ * driver backends, no manifest is generated for the sync driver.
+ */
+
+#ifndef _SYNCMANIFEST_H_
+#define _SYNCMANIFEST_H_
+
+#if defined(__linux__)
+
+typedef struct {
+ char *path;
+ char *providerName;
+} SyncManifest;
+
+SyncManifest *
+SyncNewManifest(VmBackupState *state, SyncDriverHandle handle);
+
+Bool
+SyncManifestSend(SyncManifest *manifest);
+
+void
+SyncManifestRelease(SyncManifest *manifest);
+
+#else /* !defined(__linux__) */
+
+typedef void SyncManifest;
+
+#define SyncNewManifest(s, h) (NULL)
+#define SyncManifestSend(m) (TRUE)
+#define SyncManifestRelease(m) ASSERT(m == NULL)
+
+#endif /* defined(__linux__) */
+
+#endif /* _SYNCMANIFEST_H_*/