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.
56 On windows platform, VSS is defined to do live backup.
57 But for VM guest running on Hyper-V, the corresponding VSS is
59 For example, a running database server instance, it knows when the
60 applications' freeze/thaw should start or finish.
61 But it is not aware of the freeze/thaw notification from Hyper-V host.
64 is designed to notify application freeze/thaw request.
65 Thus, it plays a role of broker to forward the freeze/thaw command from Hyper-V host
66 to userland application if it registered VSS service on
68 VM, and sends the result back to Hyper-V host.
72 takes the responsibility to freeze/thaw UFS file system,
73 and it is automatically launched after system boots.
74 When Hyper-V host wants to take a snapshot of the
76 VM, it will first send VSS capability check to
81 received the request and forward the request to userland application if it is
85 received the VSS_SUCCESS response from application, the
87 will be informed to check whether file system freeze/thaw is supported.
88 Any error occurs during this period,
90 will inform Hyper-V host that VSS is not supported.
91 In addition, there is a default timeout limit before sending response to Hyper-V host.
92 If the total response time from application and
94 exceeds this value, timeout
95 will occurs and VSS unsupported is responsed to Hyper-V host.
97 After Hyper-V host confirmed the
99 VM supports VSS, it will send freeze request to VM, and
101 will first forward it to application.
102 After application finished freezing, it should inform
104 and file system level freezing will be triggered by
105 .Xr hv_vss_daemon 8 .
106 After all freezing on both application and
110 will inform Hyper-V host that freezing is done.
111 Of course, there is a timeout limit as same as VSS capability is set to make sure freezing on
114 If there is any error occurs or timeout happened, the freezing is failed on Hyper-V side.
116 Hyper-V host will send thaw request after taking the snapshot, typically, this period is
117 very short in order not to block the running application.
119 firstly thaw the file system by notifying
120 .Xr hv_vss_daemon 8 ,
121 then notifies user registered
123 There is also a timeout check before sending response to Hyper-V host.
125 All the default timeout limit used in VSS capability check, freeze or thaw is the same.
126 It is 15 seconds currently.
129 only support UFS currently.
130 If any of file system partition is non UFS, the VSS capability check will fail.
131 If application does not register VSS,
133 only support backup for file system level consistent.
134 The device should be closed before it was opened again.
135 If you want to simultaneously open "/dev/hv_appvss_dev" two or more times,
136 an error (-1) will be returned, and errno was set.
140 was killed after system boots, the VSS functionality will not work.
142 The following is a complete example which does nothing except for waiting 2 seconds when
143 receiving those notifications from
148 #include <sys/ioctl.h>
149 #include <sys/param.h>
150 #include <sys/ucred.h>
151 #include <sys/mount.h>
152 #include <sys/types.h>
161 #include <ufs/ffs/fs.h>
163 #include <sys/ioccom.h>
164 #include <dev/hyperv/hv_snapshot.h>
166 #define UNDEF_FREEZE_THAW (0)
171 #define VSS_LOG(priority, format, args...) do { \\
172 if (is_debugging == 1) { \\
173 if (is_daemon == 1) \\
174 syslog(priority, format, ## args); \\
176 printf(format, ## args); \\
178 if (priority < LOG_DEBUG) { \\
179 if (is_daemon == 1) \\
180 syslog(priority, format, ## args); \\
182 printf(format, ## args); \\
187 #define CHECK_TIMEOUT 1
189 #define FREEZE_TIMEOUT 1
190 #define FREEZE_FAIL 2
191 #define THAW_TIMEOUT 1
194 static int is_daemon = 1;
195 static int is_debugging = 0;
196 static int simu_opt_waiting = 2; // seconds
198 #define GENERIC_OPT(TIMEOUT, FAIL) \\
200 sleep(simu_opt_waiting); \\
201 if (opt == CHECK_TIMEOUT) { \\
202 sleep(simu_opt_waiting * 10); \\
203 VSS_LOG(LOG_INFO, "%s timeout simulation\\n", \\
206 } else if (opt == CHECK_FAIL) { \\
207 VSS_LOG(LOG_INFO, "%s failure simulation\\n", \\
209 return (CHECK_FAIL); \\
211 VSS_LOG(LOG_INFO, "%s success simulation\\n", \\
220 GENERIC_OPT(CHECK_TIMEOUT, CHECK_FAIL);
226 GENERIC_OPT(FREEZE_TIMEOUT, FREEZE_FAIL);
232 GENERIC_OPT(THAW_TIMEOUT, THAW_FAIL);
235 static void usage(const char* cmd) {
237 "%s -f <0|1|2>: simulate app freeze."
238 " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
239 " -c <0|1|2>: simulate vss feature check"
240 " -t <0|1|2>: simulate app thaw."
241 " 0: successful, 1: freeze timeout, 2: freeze failed\\n"
242 " -d : enable debug mode\\n"
243 " -n : run this tool under non-daemon mode\\n", cmd);
247 main(int argc, char* argv[]) {
248 int ch, freezesimuop = 0, thawsimuop = 0, checksimuop = 0, fd, r, error;
250 struct pollfd app_vss_fd[1];
251 struct hv_vss_opt_msg userdata;
253 while ((ch = getopt(argc, argv, "f:c:t:dnh")) != -1) {
256 /* Run as regular process for debugging purpose. */
257 freezesimuop = (int)strtol(optarg, NULL, 10);
260 thawsimuop = (int)strtol(optarg, NULL, 10);
263 checksimuop = (int)strtol(optarg, NULL, 10);
278 openlog("APPVSS", 0, LOG_USER);
279 /* Become daemon first. */
283 VSS_LOG(LOG_DEBUG, "Run as regular process.\\n");
285 VSS_LOG(LOG_INFO, "HV_VSS starting; pid is: %d\\n", getpid());
287 fd = open(VSS_DEV(APP_VSS_DEV_NAME), O_RDWR);
289 VSS_LOG(LOG_ERR, "Fail to open %s, error: %d %s\\n",
290 VSS_DEV(APP_VSS_DEV_NAME), errno, strerror(errno));
293 app_vss_fd[0].fd = fd;
294 app_vss_fd[0].events = POLLIN | POLLRDNORM;
297 r = poll(app_vss_fd, 1, INFTIM);
299 VSS_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\\n",
300 r, app_vss_fd[0].revents);
302 if (r == 0 || (r < 0 && errno == EAGAIN) ||
303 (r < 0 && errno == EINTR)) {
304 /* Nothing to read */
310 * For poll return failure other than EAGAIN,
313 VSS_LOG(LOG_ERR, "Poll failed.\\n");
318 /* Read from character device */
319 error = ioctl(fd, IOCHVVSSREAD, &userdata);
321 VSS_LOG(LOG_ERR, "Read failed.\\n");
326 if (userdata.status != 0) {
327 VSS_LOG(LOG_ERR, "data read error\\n");
335 error = check(checksimuop);
338 error = freeze(freezesimuop);
341 error = thaw(thawsimuop);
344 VSS_LOG(LOG_ERR, "Illegal operation: %d\\n", op);
348 userdata.status = VSS_FAIL;
350 userdata.status = VSS_SUCCESS;
351 error = ioctl(fd, IOCHVVSSWRITE, &userdata);
353 VSS_LOG(LOG_ERR, "Fail to write to device\\n");
356 VSS_LOG(LOG_INFO, "Send response %d for %s to kernel\\n",
357 userdata.status, op == HV_VSS_FREEZE ? "Freeze" :
358 (op == HV_VSS_THAW ? "Thaw" : "Check"));
368 The daemon was introduced in October 2016 and developed by Microsoft Corp.
375 .An Microsoft BSD Integration Services Team Aq Mt bsdic@microsoft.com .