8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / ndmpd / ndmp / ndmpd_chkpnt.c
blobac086b7cf80e4194a942a57b229c6f310d2aa474
1 /*
2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2013, 2015 by Delphix. All rights reserved.
4 * Copyright (c) 2013 Steven Hartland. All rights reserved.
5 * Copyright (c) 2016 Martin Matuska. All rights reserved.
6 */
8 /*
9 * BSD 3 Clause License
11 * Copyright (c) 2007, The Storage Networking Industry Association.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
19 * - Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in
21 * the documentation and/or other materials provided with the
22 * distribution.
24 * - Neither the name of The Storage Networking Industry Association (SNIA)
25 * nor the names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior written
27 * permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
42 #include <stdio.h>
43 #include <string.h>
44 #include "ndmpd.h"
45 #include <libzfs.h>
47 typedef struct snap_param {
48 char *snp_name;
49 boolean_t snp_found;
50 } snap_param_t;
52 static int cleanup_fd = -1;
55 * ndmp_has_backup
57 * Call backup function which looks for backup snapshot.
58 * This is a callback function used with zfs_iter_snapshots.
60 * Parameters:
61 * zhp (input) - ZFS handle pointer
62 * data (output) - 0 - no backup snapshot
63 * 1 - has backup snapshot
65 * Returns:
66 * 0: on success
67 * -1: otherwise
69 static int
70 ndmp_has_backup(zfs_handle_t *zhp, void *data)
72 const char *name;
73 snap_param_t *chp = (snap_param_t *)data;
75 name = zfs_get_name(zhp);
76 if (name == NULL ||
77 strstr(name, chp->snp_name) == NULL) {
78 zfs_close(zhp);
79 return (-1);
82 chp->snp_found = 1;
83 zfs_close(zhp);
85 return (0);
89 * ndmp_has_backup_snapshot
91 * Returns TRUE if the volume has an active backup snapshot, otherwise,
92 * returns FALSE.
94 * Parameters:
95 * volname (input) - name of the volume
97 * Returns:
98 * 0: on success
99 * -1: otherwise
101 static int
102 ndmp_has_backup_snapshot(char *volname, char *jobname)
104 zfs_handle_t *zhp;
105 snap_param_t snp;
106 char chname[ZFS_MAX_DATASET_NAME_LEN];
108 (void) mutex_lock(&zlib_mtx);
109 if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
110 NDMP_LOG(LOG_ERR, "Cannot open snapshot %s.", volname);
111 (void) mutex_unlock(&zlib_mtx);
112 return (-1);
115 snp.snp_found = 0;
116 (void) snprintf(chname, ZFS_MAX_DATASET_NAME_LEN, "@%s", jobname);
117 snp.snp_name = chname;
119 (void) zfs_iter_snapshots(zhp, B_FALSE, ndmp_has_backup, &snp);
120 zfs_close(zhp);
121 (void) mutex_unlock(&zlib_mtx);
123 return (snp.snp_found);
127 * ndmp_create_snapshot
129 * This function will parse the path to get the real volume name.
130 * It will then create a snapshot based on volume and job name.
131 * This function should be called before the NDMP backup is started.
133 * Parameters:
134 * vol_name (input) - name of the volume
136 * Returns:
137 * 0: on success
138 * -1: otherwise
141 ndmp_create_snapshot(char *vol_name, char *jname)
143 char vol[ZFS_MAX_DATASET_NAME_LEN];
145 if (vol_name == 0 ||
146 get_zfsvolname(vol, sizeof (vol), vol_name) == -1)
147 return (0);
150 * If there is an old snapshot left from the previous
151 * backup it could be stale one and it must be
152 * removed before using it.
154 if (ndmp_has_backup_snapshot(vol, jname))
155 (void) snapshot_destroy(vol, jname, B_FALSE, B_TRUE, NULL);
157 return (snapshot_create(vol, jname, B_FALSE, B_TRUE));
161 * ndmp_remove_snapshot
163 * This function will parse the path to get the real volume name.
164 * It will then remove the snapshot for that volume and job name.
165 * This function should be called after NDMP backup is finished.
167 * Parameters:
168 * vol_name (input) - name of the volume
170 * Returns:
171 * 0: on success
172 * -1: otherwise
175 ndmp_remove_snapshot(char *vol_name, char *jname)
177 char vol[ZFS_MAX_DATASET_NAME_LEN];
179 if (vol_name == 0 ||
180 get_zfsvolname(vol, sizeof (vol), vol_name) == -1)
181 return (0);
183 return (snapshot_destroy(vol, jname, B_FALSE, B_TRUE, NULL));
187 * Put a hold on snapshot
190 snapshot_hold(char *volname, char *snapname, char *jname, boolean_t recursive)
192 zfs_handle_t *zhp;
193 char *p;
195 if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
196 NDMP_LOG(LOG_ERR, "Cannot open volume %s.", volname);
197 return (-1);
200 if (cleanup_fd == -1 && (cleanup_fd = open(ZFS_DEV,
201 O_RDWR|O_EXCL)) < 0) {
202 NDMP_LOG(LOG_ERR, "Cannot open dev %d", errno);
203 zfs_close(zhp);
204 return (-1);
207 p = strchr(snapname, '@') + 1;
208 if (zfs_hold(zhp, p, jname, recursive, cleanup_fd) != 0) {
209 NDMP_LOG(LOG_ERR, "Cannot hold snapshot %s", p);
210 zfs_close(zhp);
211 return (-1);
213 zfs_close(zhp);
214 return (0);
218 snapshot_release(char *volname, char *snapname, char *jname,
219 boolean_t recursive)
221 zfs_handle_t *zhp;
222 char *p;
223 int rv = 0;
225 if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
226 NDMP_LOG(LOG_ERR, "Cannot open volume %s", volname);
227 return (-1);
230 p = strchr(snapname, '@') + 1;
231 if (zfs_release(zhp, p, jname, recursive) != 0) {
232 NDMP_LOG(LOG_DEBUG, "Cannot release snapshot %s", p);
233 rv = -1;
235 if (cleanup_fd != -1) {
236 (void) close(cleanup_fd);
237 cleanup_fd = -1;
239 zfs_close(zhp);
240 return (rv);
244 * Create a snapshot on the volume
247 snapshot_create(char *volname, char *jname, boolean_t recursive,
248 boolean_t hold)
250 char snapname[ZFS_MAX_DATASET_NAME_LEN];
251 int rv;
253 if (!volname || !*volname)
254 return (-1);
256 (void) snprintf(snapname, ZFS_MAX_DATASET_NAME_LEN,
257 "%s@%s", volname, jname);
259 (void) mutex_lock(&zlib_mtx);
260 if ((rv = zfs_snapshot(zlibh, snapname, recursive, NULL))
261 == -1) {
262 if (errno == EEXIST) {
263 (void) mutex_unlock(&zlib_mtx);
264 return (0);
266 NDMP_LOG(LOG_DEBUG,
267 "snapshot_create: %s failed (err=%d): %s",
268 snapname, errno, libzfs_error_description(zlibh));
269 (void) mutex_unlock(&zlib_mtx);
270 return (rv);
272 if (hold && snapshot_hold(volname, snapname, jname, recursive) != 0) {
273 NDMP_LOG(LOG_DEBUG,
274 "snapshot_create: %s hold failed (err=%d): %s",
275 snapname, errno, libzfs_error_description(zlibh));
276 (void) mutex_unlock(&zlib_mtx);
277 return (-1);
280 (void) mutex_unlock(&zlib_mtx);
281 return (0);
285 * Remove and release the backup snapshot
288 snapshot_destroy(char *volname, char *jname, boolean_t recursive,
289 boolean_t hold, int *zfs_err)
291 char snapname[ZFS_MAX_DATASET_NAME_LEN];
292 zfs_handle_t *zhp;
293 zfs_type_t ztype;
294 char *namep;
295 int err;
297 if (zfs_err)
298 *zfs_err = 0;
300 if (!volname || !*volname)
301 return (-1);
303 if (recursive) {
304 ztype = ZFS_TYPE_VOLUME | ZFS_TYPE_FILESYSTEM;
305 namep = volname;
306 } else {
307 (void) snprintf(snapname, ZFS_MAX_DATASET_NAME_LEN,
308 "%s@%s", volname, jname);
309 namep = snapname;
310 ztype = ZFS_TYPE_SNAPSHOT;
313 (void) mutex_lock(&zlib_mtx);
314 if (hold &&
315 snapshot_release(volname, namep, jname, recursive) != 0) {
316 NDMP_LOG(LOG_DEBUG,
317 "snapshot_destroy: %s release failed (err=%d): %s",
318 namep, errno, libzfs_error_description(zlibh));
319 (void) mutex_unlock(&zlib_mtx);
320 return (-1);
323 if ((zhp = zfs_open(zlibh, namep, ztype)) == NULL) {
324 NDMP_LOG(LOG_DEBUG, "snapshot_destroy: open %s failed",
325 namep);
326 (void) mutex_unlock(&zlib_mtx);
327 return (-1);
330 if (recursive) {
331 err = zfs_destroy_snaps(zhp, jname, B_TRUE);
332 } else {
333 err = zfs_destroy(zhp, B_TRUE);
336 if (err) {
337 NDMP_LOG(LOG_ERR, "%s (recursive destroy: %d): %d; %s; %s",
338 namep,
339 recursive,
340 libzfs_errno(zlibh),
341 libzfs_error_action(zlibh),
342 libzfs_error_description(zlibh));
344 if (zfs_err)
345 *zfs_err = err;
348 zfs_close(zhp);
349 (void) mutex_unlock(&zlib_mtx);
351 return (0);