1 .\" Copyright (c) 2016 Microsoft Corp.
2 .\" All rights reserved.
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\" notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\" notice, this list of conditions and the following disclaimer in the
11 .\" documentation and/or other materials provided with the distribution.
13 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 .Nd Hyper-V Volume Shadow Copy Service API
33 .In dev/hyperv/hv_snapshot.h
35 #define VSS_SUCCESS 0x00000000
36 #define VSS_FAIL 0x00000001
46 struct hv_vss_opt_msg {
47 uint32_t opt; /* operation */
48 uint32_t status; /* 0 for success, 1 for error */
49 uint64_t msgid; /* an ID used to identify the transaction */
50 uint8_t reserved[48]; /* reserved values are all zeroes */
54 The freeze or thaw functionality of application is important to guarantee
55 the application consistent backup. On windows platform, VSS is defined to do
56 live backup. But for VM guest running on Hyper-V, the corresponding VSS is
57 not defined yet. For example, a running database server instance, it knows when the
58 applications' freeze/thaw should start or finish. But it is not aware of
59 the freeze/thaw notification from Hyper-V host. The
61 is designed to notify application freeze/thaw request.
62 Thus, it plays a role of broker to forward the freeze/thaw command from Hyper-V host
63 to userland application if it registered VSS service on
65 VM, and sends the result back to Hyper-V host.
69 takes the responsiblity to freeze/thaw UFS file system,
70 and it is automatically launched after system boots. When Hyper-V host wants to
71 take a snapshot of the
73 VM, it will first send VSS capability check to
77 received the request and forward the request to userland application if it is
78 registered. Only after
80 received the VSS_SUCCESS response from application, the
82 will be informed to check whether file system freeze/thaw is supported. Any error
83 occurs during this period,
85 will inform Hyper-V host that VSS is not supported. In addition, there is a default
86 timeout limit before sending response to Hyper-V host.
87 If the total response time from application and
89 exceeds this value, timeout
90 will occurs and VSS unsupported is responsed to Hyper-V host.
92 After Hyper-V host confirmed the
94 VM supports VSS, it will send freeze request to VM, and
96 will first forward it to application. After application finished freezing, it should
99 and file system level freezing will be triggered by
100 .Xr hv_vss_daemon 8 . After all freezing
101 on both application and
105 will inform Hyper-V host that freezing is done. Of course, there is a timeout limit as
106 same as VSS capability is set to make sure freezing on
108 VM is not hang. If there is any error occurs or timeout happened, the freezing is failed
111 Hyper-V host will send thaw request after taking the snapshot, typically, this period is
112 very short in order not to block the running application.
114 firstly thaw the file system by notifying
115 .Xr hv_vss_daemon 8 ,
116 then notifies user registered
117 application. There is also a timeout check before sending response to Hyper-V host.
119 All the default timeout limit used in VSS capability check, freeze or thaw is the same.
120 It is 15 seconds currently.
123 only support UFS currently. If any of file system partition is non UFS, the VSS capability
124 check will fail. If application does not register VSS,
126 only support backup for file system level consistent. The device should be closed before it
127 was opened again. If you want to simultaneously open "/dev/hv_appvss_dev" two or more times,
128 an error (-1) will be returned, and errno was set.
132 was killed after system boots, the VSS functionality will not work.
134 The following is a complete example which does nothing except for waiting 2 seconds when
135 receiving those notifications from
140 #include <sys/ioctl.h>
141 #include <sys/param.h>
142 #include <sys/ucred.h>
143 #include <sys/mount.h>
144 #include <sys/types.h>
153 #include <ufs/ffs/fs.h>
155 #include <sys/ioccom.h>
156 #include <dev/hyperv/hv_snapshot.h>
158 #define UNDEF_FREEZE_THAW (0)
163 #define VSS_LOG(priority, format, args...) do { \\
164 if (is_debugging == 1) { \\
165 if (is_daemon == 1) \\
166 syslog(priority, format, ## args); \\
168 printf(format, ## args); \\
170 if (priority < LOG_DEBUG) { \\
171 if (is_daemon == 1) \\
172 syslog(priority, format, ## args); \\
174 printf(format, ## args); \\
179 #define CHECK_TIMEOUT 1
181 #define FREEZE_TIMEOUT 1
182 #define FREEZE_FAIL 2
183 #define THAW_TIMEOUT 1
186 static int is_daemon = 1;
187 static int is_debugging = 0;
188 static int simu_opt_waiting = 2; // seconds
190 #define GENERIC_OPT(TIMEOUT, FAIL) \\
192 sleep(simu_opt_waiting); \\
193 if (opt == CHECK_TIMEOUT) { \\
194 sleep(simu_opt_waiting * 10); \\
195 VSS_LOG(LOG_INFO, "%s timeout simulation\\n", \\
198 } else if (opt == CHECK_FAIL) { \\
199 VSS_LOG(LOG_INFO, "%s failure simulation\\n", \\
201 return (CHECK_FAIL); \\
203 VSS_LOG(LOG_INFO, "%s success simulation\\n", \\
212 GENERIC_OPT(CHECK_TIMEOUT, CHECK_FAIL);
218 GENERIC_OPT(FREEZE_TIMEOUT, FREEZE_FAIL);
224 GENERIC_OPT(THAW_TIMEOUT, THAW_FAIL);
227 static void usage(const char* cmd) {
229 "%s -f <0|1|2>: simulate app freeze."
230 " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
231 " -c <0|1|2>: simulate vss feature check"
232 " -t <0|1|2>: simulate app thaw."
233 " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
234 " -d : enable debug mode\\n"
235 " -n : run this tool under non-daemon mode\\n", cmd);
239 main(int argc, char* argv[]) {
240 int ch, freezesimuop = 0, thawsimuop = 0, checksimuop = 0, fd, r, error;
242 struct pollfd app_vss_fd[1];
243 struct hv_vss_opt_msg userdata;
245 while ((ch = getopt(argc, argv, "f:c:t:dnh")) != -1) {
248 /* Run as regular process for debugging purpose. */
249 freezesimuop = (int)strtol(optarg, NULL, 10);
252 thawsimuop = (int)strtol(optarg, NULL, 10);
255 checksimuop = (int)strtol(optarg, NULL, 10);
270 openlog("APPVSS", 0, LOG_USER);
271 /* Become daemon first. */
275 VSS_LOG(LOG_DEBUG, "Run as regular process.\\n");
277 VSS_LOG(LOG_INFO, "HV_VSS starting; pid is: %d\\n", getpid());
279 fd = open(VSS_DEV(APP_VSS_DEV_NAME), O_RDWR);
281 VSS_LOG(LOG_ERR, "Fail to open %s, error: %d %s\\n",
282 VSS_DEV(APP_VSS_DEV_NAME), errno, strerror(errno));
285 app_vss_fd[0].fd = fd;
286 app_vss_fd[0].events = POLLIN | POLLRDNORM;
289 r = poll(app_vss_fd, 1, INFTIM);
291 VSS_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\\n",
292 r, app_vss_fd[0].revents);
294 if (r == 0 || (r < 0 && errno == EAGAIN) ||
295 (r < 0 && errno == EINTR)) {
296 /* Nothing to read */
302 * For poll return failure other than EAGAIN,
305 VSS_LOG(LOG_ERR, "Poll failed.\\n");
310 /* Read from character device */
311 error = ioctl(fd, IOCHVVSSREAD, &userdata);
313 VSS_LOG(LOG_ERR, "Read failed.\\n");
318 if (userdata.status != 0) {
319 VSS_LOG(LOG_ERR, "data read error\\n");
327 error = check(checksimuop);
330 error = freeze(freezesimuop);
333 error = thaw(thawsimuop);
336 VSS_LOG(LOG_ERR, "Illegal operation: %d\\n", op);
340 userdata.status = VSS_FAIL;
342 userdata.status = VSS_SUCCESS;
343 error = ioctl(fd, IOCHVVSSWRITE, &userdata);
345 VSS_LOG(LOG_ERR, "Fail to write to device\\n");
348 VSS_LOG(LOG_INFO, "Send response %d for %s to kernel\\n",
349 userdata.status, op == HV_VSS_FREEZE ? "Freeze" :
350 (op == HV_VSS_THAW ? "Thaw" : "Check"));
356 .Xr hv_vss_daemon 8 ,
359 The daemon was introduced in October 2016 and developed by Microsoft Corp.
366 .An Microsoft BSD Integration Services Team Aq Mt bsdic@microsoft.com .