]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man4/hv_vss.4
disk(9): Fix a few mandoc related errors
[FreeBSD/FreeBSD.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.
56 On windows platform, VSS is defined to do live backup.
57 But for VM guest running on Hyper-V, the corresponding VSS is
58 not defined yet.
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.
62 The
63 .Nm
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
67 .Fx
68 VM, and sends the result back to Hyper-V host.
69 .Pp
70 Generally,
71 .Xr hv_vss_daemon 8
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
75 .Fx
76 VM, it will first send VSS capability check to
77 .Fx
78 VM.
79 The
80 .Nm
81 received the request and forward the request to userland application if it is
82 registered.
83 Only after
84 .Nm
85 received the VSS_SUCCESS response from application, the
86 .Xr hv_vss_daemon 8
87 will be informed to check whether file system freeze/thaw is supported.
88 Any error occurs during this period,
89 .Nm
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
93 .Xr hv_vss_daemon 8
94 exceeds this value, timeout
95 will occurs and VSS unsupported is responsed to Hyper-V host.
96 .Pp
97 After Hyper-V host confirmed the
98 .Fx
99 VM supports VSS, it will send freeze request to VM, and
100 .Nm
101 will first forward it to application.
102 After application finished freezing, it should inform
103 .Nm
104 and file system level freezing will be triggered by
105 .Xr hv_vss_daemon 8 .
106 After all freezing on both application and
107 .Xr hv_vss_daemon 8
108 were finished, the
109 .Nm
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
112 .Fx
113 VM is not hang.
114 If there is any error occurs or timeout happened, the freezing is failed on Hyper-V side.
115 .Pp
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.
118 .Nm
119 firstly thaw the file system by notifying
120 .Xr hv_vss_daemon 8 ,
121 then notifies user registered
122 application.
123 There is also a timeout check before sending response to Hyper-V host.
124 .Pp
125 All the default timeout limit used in VSS capability check, freeze or thaw is the same.
126 It is 15 seconds currently.
127 .Sh NOTES
128 .Nm
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,
132 .Nm
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.
137 .Pp
138 If
139 .Xr hv_vss_daemon 8
140 was killed after system boots, the VSS functionality will not work.
141 .Sh EXAMPLES
142 The following is a complete example which does nothing except for waiting 2 seconds when
143 receiving those notifications from
144 .Nm
145 .Bd -literal
146 #include <string.h>
147 #include <stdio.h>
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>
153 #include <unistd.h>
154 #include <stdlib.h>
155 #include <poll.h>
156 #include <stdint.h>
157 #include <syslog.h>
158 #include <errno.h>
159 #include <err.h>
160 #include <fcntl.h>
161 #include <ufs/ffs/fs.h>
162 #include <paths.h>
163 #include <sys/ioccom.h>
164 #include <dev/hyperv/hv_snapshot.h>
165
166 #define UNDEF_FREEZE_THAW       (0)
167 #define FREEZE                  (1)
168 #define THAW                    (2)
169 #define CHECK                   (3)
170
171 #define VSS_LOG(priority, format, args...) do   {                               \\
172                 if (is_debugging == 1) {                                        \\
173                         if (is_daemon == 1)                                     \\
174                                 syslog(priority, format, ## args);              \\
175                         else                                                    \\
176                                 printf(format, ## args);                        \\
177                 } else {                                                        \\
178                         if (priority < LOG_DEBUG) {                             \\
179                                 if (is_daemon == 1)                             \\
180                                         syslog(priority, format, ## args);      \\
181                                 else                                            \\
182                                         printf(format, ## args);                \\
183                         }                                                       \\
184                 }                                                               \\
185         } while(0)
186
187 #define CHECK_TIMEOUT           1
188 #define CHECK_FAIL              2
189 #define FREEZE_TIMEOUT          1
190 #define FREEZE_FAIL             2
191 #define THAW_TIMEOUT            1
192 #define THAW_FAIL               2
193
194 static int is_daemon        = 1;
195 static int is_debugging     = 0;
196 static int simu_opt_waiting = 2; // seconds
197
198 #define GENERIC_OPT(TIMEOUT, FAIL)                                              \\
199         do {                                                                    \\
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",           \\
204                             __func__);                                          \\
205                         return (0);                                             \\
206                 } else if (opt == CHECK_FAIL) {                                 \\
207                         VSS_LOG(LOG_INFO, "%s failure simulation\\n",           \\
208                             __func__);                                          \\
209                         return (CHECK_FAIL);                                    \\
210                 } else {                                                        \\
211                         VSS_LOG(LOG_INFO, "%s success simulation\\n",           \\
212                             __func__);                                          \\
213                         return (0);                                             \\
214                 }                                                               \\
215         } while (0)
216
217 static int
218 check(int opt)
219 {
220         GENERIC_OPT(CHECK_TIMEOUT, CHECK_FAIL);
221 }
222
223 static int
224 freeze(int opt)
225 {
226         GENERIC_OPT(FREEZE_TIMEOUT, FREEZE_FAIL);
227 }
228
229 static int
230 thaw(int opt)
231 {
232         GENERIC_OPT(THAW_TIMEOUT, THAW_FAIL);
233 }
234
235 static void usage(const char* cmd) {
236         fprintf(stderr,
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);
244 }
245
246 int
247 main(int argc, char* argv[]) {
248         int ch, freezesimuop = 0, thawsimuop = 0, checksimuop = 0, fd, r, error;
249         uint32_t op;
250         struct pollfd app_vss_fd[1];
251         struct hv_vss_opt_msg  userdata;
252
253         while ((ch = getopt(argc, argv, "f:c:t:dnh")) != -1) {
254                 switch (ch) {
255                 case 'f':
256                         /* Run as regular process for debugging purpose. */
257                         freezesimuop = (int)strtol(optarg, NULL, 10);
258                         break;
259                 case 't':
260                         thawsimuop = (int)strtol(optarg, NULL, 10);
261                         break;
262                 case 'c':
263                         checksimuop = (int)strtol(optarg, NULL, 10);
264                         break;
265                 case 'd':
266                         is_debugging = 1;
267                         break;
268                 case 'n':
269                         is_daemon = 0;
270                         break;
271                 case 'h':
272                 default:
273                         usage(argv[0]);
274                         exit(0);
275                 }
276         }
277
278         openlog("APPVSS", 0, LOG_USER);
279         /* Become daemon first. */
280         if (is_daemon == 1)
281                 daemon(1, 0);
282         else
283                 VSS_LOG(LOG_DEBUG, "Run as regular process.\\n");
284
285         VSS_LOG(LOG_INFO, "HV_VSS starting; pid is: %d\\n", getpid());
286
287         fd = open(VSS_DEV(APP_VSS_DEV_NAME), O_RDWR);
288         if (fd < 0) {
289                 VSS_LOG(LOG_ERR, "Fail to open %s, error: %d %s\\n",
290                     VSS_DEV(APP_VSS_DEV_NAME), errno, strerror(errno));
291                 exit(EXIT_FAILURE);
292         }
293         app_vss_fd[0].fd     = fd;
294         app_vss_fd[0].events = POLLIN | POLLRDNORM;
295
296         while (1) {
297                 r = poll(app_vss_fd, 1, INFTIM);
298
299                 VSS_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\\n",
300                     r, app_vss_fd[0].revents);
301
302                 if (r == 0 || (r < 0 && errno == EAGAIN) ||
303                     (r < 0 && errno == EINTR)) {
304                         /* Nothing to read */
305                         continue;
306                 }
307
308                 if (r < 0) {
309                         /*
310                          * For poll return failure other than EAGAIN,
311                          * we want to exit.
312                          */
313                         VSS_LOG(LOG_ERR, "Poll failed.\\n");
314                         perror("poll");
315                         exit(EIO);
316                 }
317
318                 /* Read from character device */
319                 error = ioctl(fd, IOCHVVSSREAD, &userdata);
320                 if (error < 0) {
321                         VSS_LOG(LOG_ERR, "Read failed.\\n");
322                         perror("pread");
323                         exit(EIO);
324                 }
325
326                 if (userdata.status != 0) {
327                         VSS_LOG(LOG_ERR, "data read error\\n");
328                         continue;
329                 }
330
331                 op = userdata.opt;
332
333                 switch (op) {
334                 case HV_VSS_CHECK:
335                         error = check(checksimuop);
336                         break;
337                 case HV_VSS_FREEZE:
338                         error = freeze(freezesimuop);
339                         break;
340                 case HV_VSS_THAW:
341                         error = thaw(thawsimuop);
342                         break;
343                 default:
344                         VSS_LOG(LOG_ERR, "Illegal operation: %d\\n", op);
345                         error = VSS_FAIL;
346                 }
347                 if (error)
348                         userdata.status = VSS_FAIL;
349                 else
350                         userdata.status = VSS_SUCCESS;
351                 error = ioctl(fd, IOCHVVSSWRITE, &userdata);
352                 if (error != 0) {
353                         VSS_LOG(LOG_ERR, "Fail to write to device\\n");
354                         exit(EXIT_FAILURE);
355                 } else {
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"));
359                 }
360         }
361         return 0;
362 }
363 .Ed
364 .Sh SEE ALSO
365 .Xr hv_utils 4 ,
366 .Xr hv_vss_daemon 8
367 .Sh HISTORY
368 The daemon was introduced in October 2016 and developed by Microsoft Corp.
369 .Sh AUTHORS
370 .An -nosplit
371 .Fx
372 support for
373 .Nm
374 was first added by
375 .An Microsoft BSD Integration Services Team Aq Mt bsdic@microsoft.com .