]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - share/man/man4/hv_vss.4
MFC 308664,308742,308743
[FreeBSD/stable/10.git] / share / man / man4 / hv_vss.4
1 .\" Copyright (c) 2016 Microsoft Corp.
2 .\" All rights reserved.
3 .\"
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
6 .\" are met:
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.
12 .\"
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
23 .\" SUCH DAMAGE.
24 .\"
25 .\" $FreeBSD$
26 .Dd October 12, 2016
27 .Dt HV_VSS 4
28 .Os
29 .Sh NAME
30 .Nm hv_vss
31 .Nd Hyper-V Volume Shadow Copy Service API
32 .Sh SYNOPSIS
33 .In dev/hyperv/hv_snapshot.h
34 .Bd -literal
35 #define VSS_SUCCESS             0x00000000
36 #define VSS_FAIL                0x00000001
37
38 enum hv_vss_op_t {
39         HV_VSS_NONE = 0,
40         HV_VSS_CHECK,
41         HV_VSS_FREEZE,
42         HV_VSS_THAW,
43         HV_VSS_COUNT
44 };
45
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 */
51 };
52 .Ed
53 .Sh DESCRIPTION
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
60 .Nm
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
64 .Fx
65 VM, and sends the result back to Hyper-V host.
66 .Pp
67 Generally,
68 .Xr hv_vss_daemon 8
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
72 .Fx
73 VM, it will first send VSS capability check to
74 .Fx
75 VM. The
76 .Nm
77 received the request and forward the request to userland application if it is
78 registered. Only after
79 .Nm
80 received the VSS_SUCCESS response from application, the
81 .Xr hv_vss_daemon 8
82 will be informed to check whether file system freeze/thaw is supported. Any error
83 occurs during this period,
84 .Nm
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
88 .Xr hv_vss_daemon 8
89 exceeds this value, timeout
90 will occurs and VSS unsupported is responsed to Hyper-V host.
91 .Pp
92 After Hyper-V host confirmed the
93 .Fx
94 VM supports VSS, it will send freeze request to VM, and
95 .Nm
96 will first forward it to application. After application finished freezing, it should
97 inform
98 .Nm
99 and file system level freezing will be triggered by
100 .Xr hv_vss_daemon 8 . After all freezing
101 on both application and
102 .Xr hv_vss_daemon 8
103 were finished, the
104 .Nm
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
107 .Fx
108 VM is not hang. If there is any error occurs or timeout happened, the freezing is failed
109 on Hyper-V side.
110 .Pp
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.
113 .Nm
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.
118 .Pp
119 All the default timeout limit used in VSS capability check, freeze or thaw is the same.
120 It is 15 seconds currently.
121 .Sh NOTES
122 .Nm
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,
125 .Nm
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.
129 .Pp
130 If
131 .Xr hv_vss_daemon 8
132 was killed after system boots, the VSS functionality will not work.
133 .Sh EXAMPLES
134 The following is a complete example which does nothing except for waiting 2 seconds when
135 receiving those notifications from
136 .Nm
137 .Bd -literal
138 #include <string.h>
139 #include <stdio.h>
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>
145 #include <unistd.h>
146 #include <stdlib.h>
147 #include <poll.h>
148 #include <stdint.h>
149 #include <syslog.h>
150 #include <errno.h>
151 #include <err.h>
152 #include <fcntl.h>
153 #include <ufs/ffs/fs.h>
154 #include <paths.h>
155 #include <sys/ioccom.h>
156 #include <dev/hyperv/hv_snapshot.h>
157
158 #define UNDEF_FREEZE_THAW       (0)
159 #define FREEZE                  (1)
160 #define THAW                    (2)
161 #define CHECK                   (3)
162
163 #define VSS_LOG(priority, format, args...) do   {                               \\
164                 if (is_debugging == 1) {                                        \\
165                         if (is_daemon == 1)                                     \\
166                                 syslog(priority, format, ## args);              \\
167                         else                                                    \\
168                                 printf(format, ## args);                        \\
169                 } else {                                                        \\
170                         if (priority < LOG_DEBUG) {                             \\
171                                 if (is_daemon == 1)                             \\
172                                         syslog(priority, format, ## args);      \\
173                                 else                                            \\
174                                         printf(format, ## args);                \\
175                         }                                                       \\
176                 }                                                               \\
177         } while(0)
178
179 #define CHECK_TIMEOUT           1
180 #define CHECK_FAIL              2
181 #define FREEZE_TIMEOUT          1
182 #define FREEZE_FAIL             2
183 #define THAW_TIMEOUT            1
184 #define THAW_FAIL               2
185
186 static int is_daemon        = 1;
187 static int is_debugging     = 0;
188 static int simu_opt_waiting = 2; // seconds
189
190 #define GENERIC_OPT(TIMEOUT, FAIL)                                              \\
191         do {                                                                    \\
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",           \\
196                             __func__);                                          \\
197                         return (0);                                             \\
198                 } else if (opt == CHECK_FAIL) {                                 \\
199                         VSS_LOG(LOG_INFO, "%s failure simulation\\n",           \\
200                             __func__);                                          \\
201                         return (CHECK_FAIL);                                    \\
202                 } else {                                                        \\
203                         VSS_LOG(LOG_INFO, "%s success simulation\\n",           \\
204                             __func__);                                          \\
205                         return (0);                                             \\
206                 }                                                               \\
207         } while (0)
208
209 static int
210 check(int opt)
211 {
212         GENERIC_OPT(CHECK_TIMEOUT, CHECK_FAIL);
213 }
214
215 static int
216 freeze(int opt)
217 {
218         GENERIC_OPT(FREEZE_TIMEOUT, FREEZE_FAIL);
219 }
220
221 static int
222 thaw(int opt)
223 {
224         GENERIC_OPT(THAW_TIMEOUT, THAW_FAIL);
225 }
226
227 static void usage(const char* cmd) {
228         fprintf(stderr,
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);
236 }
237
238 int
239 main(int argc, char* argv[]) {
240         int ch, freezesimuop = 0, thawsimuop = 0, checksimuop = 0, fd, r, error;
241         uint32_t op;
242         struct pollfd app_vss_fd[1];
243         struct hv_vss_opt_msg  userdata;
244
245         while ((ch = getopt(argc, argv, "f:c:t:dnh")) != -1) {
246                 switch (ch) {
247                 case 'f':
248                         /* Run as regular process for debugging purpose. */
249                         freezesimuop = (int)strtol(optarg, NULL, 10);
250                         break;
251                 case 't':
252                         thawsimuop = (int)strtol(optarg, NULL, 10);
253                         break;
254                 case 'c':
255                         checksimuop = (int)strtol(optarg, NULL, 10);
256                         break;
257                 case 'd':
258                         is_debugging = 1;
259                         break;
260                 case 'n':
261                         is_daemon = 0;
262                         break;
263                 case 'h':
264                 default:
265                         usage(argv[0]);
266                         exit(0);
267                 }
268         }
269
270         openlog("APPVSS", 0, LOG_USER);
271         /* Become daemon first. */
272         if (is_daemon == 1)
273                 daemon(1, 0);
274         else
275                 VSS_LOG(LOG_DEBUG, "Run as regular process.\\n");
276
277         VSS_LOG(LOG_INFO, "HV_VSS starting; pid is: %d\\n", getpid());
278
279         fd = open(VSS_DEV(APP_VSS_DEV_NAME), O_RDWR);
280         if (fd < 0) {
281                 VSS_LOG(LOG_ERR, "Fail to open %s, error: %d %s\\n",
282                     VSS_DEV(APP_VSS_DEV_NAME), errno, strerror(errno));
283                 exit(EXIT_FAILURE);
284         }
285         app_vss_fd[0].fd     = fd;
286         app_vss_fd[0].events = POLLIN | POLLRDNORM;
287
288         while (1) {
289                 r = poll(app_vss_fd, 1, INFTIM);
290
291                 VSS_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\\n",
292                     r, app_vss_fd[0].revents);
293
294                 if (r == 0 || (r < 0 && errno == EAGAIN) ||
295                     (r < 0 && errno == EINTR)) {
296                         /* Nothing to read */
297                         continue;
298                 }
299
300                 if (r < 0) {
301                         /*
302                          * For poll return failure other than EAGAIN,
303                          * we want to exit.
304                          */
305                         VSS_LOG(LOG_ERR, "Poll failed.\\n");
306                         perror("poll");
307                         exit(EIO);
308                 }
309
310                 /* Read from character device */
311                 error = ioctl(fd, IOCHVVSSREAD, &userdata);
312                 if (error < 0) {
313                         VSS_LOG(LOG_ERR, "Read failed.\\n");
314                         perror("pread");
315                         exit(EIO);
316                 }
317
318                 if (userdata.status != 0) {
319                         VSS_LOG(LOG_ERR, "data read error\\n");
320                         continue;
321                 }
322
323                 op = userdata.opt;
324
325                 switch (op) {
326                 case HV_VSS_CHECK:
327                         error = check(checksimuop);
328                         break;
329                 case HV_VSS_FREEZE:
330                         error = freeze(freezesimuop);
331                         break;
332                 case HV_VSS_THAW:
333                         error = thaw(thawsimuop);
334                         break;
335                 default:
336                         VSS_LOG(LOG_ERR, "Illegal operation: %d\\n", op);
337                         error = VSS_FAIL;
338                 }
339                 if (error)
340                         userdata.status = VSS_FAIL;
341                 else
342                         userdata.status = VSS_SUCCESS;
343                 error = ioctl(fd, IOCHVVSSWRITE, &userdata);
344                 if (error != 0) {
345                         VSS_LOG(LOG_ERR, "Fail to write to device\\n");
346                         exit(EXIT_FAILURE);
347                 } else {
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"));
351                 }
352         }
353         return 0;
354 }
355 .Sh SEE ALSO
356 .Xr hv_vss_daemon 8 ,
357 .Xr hv_utils 4
358 .Sh HISTORY
359 The daemon was introduced in October 2016 and developed by Microsoft Corp.
360 .Sh AUTHORS
361 .An -nosplit
362 .Fx
363 support for
364 .Nm
365 was first added by
366 .An Microsoft BSD Integration Services Team Aq Mt bsdic@microsoft.com .