summaryrefslogtreecommitdiffstats
path: root/share/man
diff options
context:
space:
mode:
Diffstat (limited to 'share/man')
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/hv_vss.4366
2 files changed, 367 insertions, 0 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 8edad10..05c249a 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -180,6 +180,7 @@ MAN= aac.4 \
${_hv_storvsc.4} \
${_hv_utils.4} \
${_hv_vmbus.4} \
+ hv_vss.4 \
hwpmc.4 \
ichsmb.4 \
${_ichwd.4} \
diff --git a/share/man/man4/hv_vss.4 b/share/man/man4/hv_vss.4
new file mode 100644
index 0000000..4db54e3
--- /dev/null
+++ b/share/man/man4/hv_vss.4
@@ -0,0 +1,366 @@
+.\" Copyright (c) 2016 Microsoft Corp.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd October 12, 2016
+.Dt HV_VSS 4
+.Os
+.Sh NAME
+.Nm hv_vss
+.Nd Hyper-V Volume Shadow Copy Service API
+.Sh SYNOPSIS
+.In dev/hyperv/hv_snapshot.h
+.Bd -literal
+#define VSS_SUCCESS 0x00000000
+#define VSS_FAIL 0x00000001
+
+enum hv_vss_op_t {
+ HV_VSS_NONE = 0,
+ HV_VSS_CHECK,
+ HV_VSS_FREEZE,
+ HV_VSS_THAW,
+ HV_VSS_COUNT
+};
+
+struct hv_vss_opt_msg {
+ uint32_t opt; /* operation */
+ uint32_t status; /* 0 for success, 1 for error */
+ uint64_t msgid; /* an ID used to identify the transaction */
+ uint8_t reserved[48]; /* reserved values are all zeroes */
+};
+.Ed
+.Sh DESCRIPTION
+The freeze or thaw functionality of application is important to guarantee
+the application consistent backup. On windows platform, VSS is defined to do
+live backup. But for VM guest running on Hyper-V, the corresponding VSS is
+not defined yet. For example, a running database server instance, it knows when the
+applications' freeze/thaw should start or finish. But it is not aware of
+the freeze/thaw notification from Hyper-V host. The
+.Nm
+is designed to notify application freeze/thaw request.
+Thus, it plays a role of broker to forward the freeze/thaw command from Hyper-V host
+to userland application if it registered VSS service on
+.Fx
+VM, and sends the result back to Hyper-V host.
+.Pp
+Generally,
+.Xr hv_vss_daemon 8
+takes the responsiblity to freeze/thaw UFS file system,
+and it is automatically launched after system boots. When Hyper-V host wants to
+take a snapshot of the
+.Fx
+VM, it will first send VSS capability check to
+.Fx
+VM. The
+.Nm
+received the request and forward the request to userland application if it is
+registered. Only after
+.Nm
+received the VSS_SUCCESS response from application, the
+.Xr hv_vss_daemon 8
+will be informed to check whether file system freeze/thaw is supported. Any error
+occurs during this period,
+.Nm
+will inform Hyper-V host that VSS is not supported. In addition, there is a default
+timeout limit before sending response to Hyper-V host.
+If the total response time from application and
+.Xr hv_vss_daemon 8
+exceeds this value, timeout
+will occurs and VSS unsupported is responsed to Hyper-V host.
+.Pp
+After Hyper-V host confirmed the
+.Fx
+VM supports VSS, it will send freeze request to VM, and
+.Nm
+will first forward it to application. After application finished freezing, it should
+inform
+.Nm
+and file system level freezing will be triggered by
+.Xr hv_vss_daemon 8 . After all freezing
+on both application and
+.Xr hv_vss_daemon 8
+were finished, the
+.Nm
+will inform Hyper-V host that freezing is done. Of course, there is a timeout limit as
+same as VSS capability is set to make sure freezing on
+.Fx
+VM is not hang. If there is any error occurs or timeout happened, the freezing is failed
+on Hyper-V side.
+.Pp
+Hyper-V host will send thaw request after taking the snapshot, typically, this period is
+very short in order not to block the running application.
+.Nm
+firstly thaw the file system by notifying
+.Xr hv_vss_daemon 8 ,
+then notifies user registered
+application. There is also a timeout check before sending response to Hyper-V host.
+.Pp
+All the default timeout limit used in VSS capability check, freeze or thaw is the same.
+It is 15 seconds currently.
+.Sh NOTES
+.Nm
+only support UFS currently. If any of file system partition is non UFS, the VSS capability
+check will fail. If application does not register VSS,
+.Nm
+only support backup for file system level consistent. The device should be closed before it
+was opened again. If you want to simultaneously open "/dev/hv_appvss_dev" two or more times,
+an error (-1) will be returned, and errno was set.
+.Pp
+If
+.Xr hv_vss_daemon 8
+was killed after system boots, the VSS functionality will not work.
+.Sh EXAMPLES
+The following is a complete example which does nothing except for waiting 2 seconds when
+receiving those notifications from
+.Nm
+.Bd -literal
+#include <string.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <poll.h>
+#include <stdint.h>
+#include <syslog.h>
+#include <errno.h>
+#include <err.h>
+#include <fcntl.h>
+#include <ufs/ffs/fs.h>
+#include <paths.h>
+#include <sys/ioccom.h>
+#include <dev/hyperv/hv_snapshot.h>
+
+#define UNDEF_FREEZE_THAW (0)
+#define FREEZE (1)
+#define THAW (2)
+#define CHECK (3)
+
+#define VSS_LOG(priority, format, args...) do { \\
+ if (is_debugging == 1) { \\
+ if (is_daemon == 1) \\
+ syslog(priority, format, ## args); \\
+ else \\
+ printf(format, ## args); \\
+ } else { \\
+ if (priority < LOG_DEBUG) { \\
+ if (is_daemon == 1) \\
+ syslog(priority, format, ## args); \\
+ else \\
+ printf(format, ## args); \\
+ } \\
+ } \\
+ } while(0)
+
+#define CHECK_TIMEOUT 1
+#define CHECK_FAIL 2
+#define FREEZE_TIMEOUT 1
+#define FREEZE_FAIL 2
+#define THAW_TIMEOUT 1
+#define THAW_FAIL 2
+
+static int is_daemon = 1;
+static int is_debugging = 0;
+static int simu_opt_waiting = 2; // seconds
+
+#define GENERIC_OPT(TIMEOUT, FAIL) \\
+ do { \\
+ sleep(simu_opt_waiting); \\
+ if (opt == CHECK_TIMEOUT) { \\
+ sleep(simu_opt_waiting * 10); \\
+ VSS_LOG(LOG_INFO, "%s timeout simulation\\n", \\
+ __func__); \\
+ return (0); \\
+ } else if (opt == CHECK_FAIL) { \\
+ VSS_LOG(LOG_INFO, "%s failure simulation\\n", \\
+ __func__); \\
+ return (CHECK_FAIL); \\
+ } else { \\
+ VSS_LOG(LOG_INFO, "%s success simulation\\n", \\
+ __func__); \\
+ return (0); \\
+ } \\
+ } while (0)
+
+static int
+check(int opt)
+{
+ GENERIC_OPT(CHECK_TIMEOUT, CHECK_FAIL);
+}
+
+static int
+freeze(int opt)
+{
+ GENERIC_OPT(FREEZE_TIMEOUT, FREEZE_FAIL);
+}
+
+static int
+thaw(int opt)
+{
+ GENERIC_OPT(THAW_TIMEOUT, THAW_FAIL);
+}
+
+static void usage(const char* cmd) {
+ fprintf(stderr,
+ "%s -f <0|1|2>: simulate app freeze."
+ " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
+ " -c <0|1|2>: simulate vss feature check"
+ " -t <0|1|2>: simulate app thaw."
+ " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
+ " -d : enable debug mode\\n"
+ " -n : run this tool under non-daemon mode\\n", cmd);
+}
+
+int
+main(int argc, char* argv[]) {
+ int ch, freezesimuop = 0, thawsimuop = 0, checksimuop = 0, fd, r, error;
+ uint32_t op;
+ struct pollfd app_vss_fd[1];
+ struct hv_vss_opt_msg userdata;
+
+ while ((ch = getopt(argc, argv, "f:c:t:dnh")) != -1) {
+ switch (ch) {
+ case 'f':
+ /* Run as regular process for debugging purpose. */
+ freezesimuop = (int)strtol(optarg, NULL, 10);
+ break;
+ case 't':
+ thawsimuop = (int)strtol(optarg, NULL, 10);
+ break;
+ case 'c':
+ checksimuop = (int)strtol(optarg, NULL, 10);
+ break;
+ case 'd':
+ is_debugging = 1;
+ break;
+ case 'n':
+ is_daemon = 0;
+ break;
+ case 'h':
+ default:
+ usage(argv[0]);
+ exit(0);
+ }
+ }
+
+ openlog("APPVSS", 0, LOG_USER);
+ /* Become daemon first. */
+ if (is_daemon == 1)
+ daemon(1, 0);
+ else
+ VSS_LOG(LOG_DEBUG, "Run as regular process.\\n");
+
+ VSS_LOG(LOG_INFO, "HV_VSS starting; pid is: %d\\n", getpid());
+
+ fd = open(VSS_DEV(APP_VSS_DEV_NAME), O_RDWR);
+ if (fd < 0) {
+ VSS_LOG(LOG_ERR, "Fail to open %s, error: %d %s\\n",
+ VSS_DEV(APP_VSS_DEV_NAME), errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ app_vss_fd[0].fd = fd;
+ app_vss_fd[0].events = POLLIN | POLLRDNORM;
+
+ while (1) {
+ r = poll(app_vss_fd, 1, INFTIM);
+
+ VSS_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\\n",
+ r, app_vss_fd[0].revents);
+
+ if (r == 0 || (r < 0 && errno == EAGAIN) ||
+ (r < 0 && errno == EINTR)) {
+ /* Nothing to read */
+ continue;
+ }
+
+ if (r < 0) {
+ /*
+ * For poll return failure other than EAGAIN,
+ * we want to exit.
+ */
+ VSS_LOG(LOG_ERR, "Poll failed.\\n");
+ perror("poll");
+ exit(EIO);
+ }
+
+ /* Read from character device */
+ error = ioctl(fd, IOCHVVSSREAD, &userdata);
+ if (error < 0) {
+ VSS_LOG(LOG_ERR, "Read failed.\\n");
+ perror("pread");
+ exit(EIO);
+ }
+
+ if (userdata.status != 0) {
+ VSS_LOG(LOG_ERR, "data read error\\n");
+ continue;
+ }
+
+ op = userdata.opt;
+
+ switch (op) {
+ case HV_VSS_CHECK:
+ error = check(checksimuop);
+ break;
+ case HV_VSS_FREEZE:
+ error = freeze(freezesimuop);
+ break;
+ case HV_VSS_THAW:
+ error = thaw(thawsimuop);
+ break;
+ default:
+ VSS_LOG(LOG_ERR, "Illegal operation: %d\\n", op);
+ error = VSS_FAIL;
+ }
+ if (error)
+ userdata.status = VSS_FAIL;
+ else
+ userdata.status = VSS_SUCCESS;
+ error = ioctl(fd, IOCHVVSSWRITE, &userdata);
+ if (error != 0) {
+ VSS_LOG(LOG_ERR, "Fail to write to device\\n");
+ exit(EXIT_FAILURE);
+ } else {
+ VSS_LOG(LOG_INFO, "Send response %d for %s to kernel\\n",
+ userdata.status, op == HV_VSS_FREEZE ? "Freeze" :
+ (op == HV_VSS_THAW ? "Thaw" : "Check"));
+ }
+ }
+ return 0;
+}
+.Sh SEE ALSO
+.Xr hv_vss_daemon 8 ,
+.Xr hv_utils 4
+.Sh HISTORY
+The daemon was introduced in October 2016 and developed by Microsoft Corp.
+.Sh AUTHORS
+.An -nosplit
+.Fx
+support for
+.Nm
+was first added by
+.An Microsoft BSD Integration Services Team Aq Mt bsdic@microsoft.com .
OpenPOWER on IntegriCloud