1 /*
2 * CDDL HEADER START
3 *
4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
12 *
13 * CDDL HEADER END
14 */
15 /*
16 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
17 */
18
19 #include <syslog.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include "ndmpd.h"
23 #include <libzfs.h>
24 #include <zlib.h>
25
26 /*
27 * ndmp_clone_snapshot
28 *
29 * Given a snapshot name in the file system, create a clone and
30 * and mount it in a well known place for ndmpd to traverse it.
31 *
32 * Parameters:
33 * nlp (input) - ndmp_lbr_params_t pointer contrining
34 * name of the snapshot, and clone.
35 *
36 * Returns:
37 * 0: on success
38 * -1: otherwise
39 */
40 int
41 ndmp_clone_snapshot(ndmp_lbr_params_t *nlp)
42 {
43 int res = 0;
44 int err;
45 zfs_handle_t *zhp;
46 zfs_handle_t *clone;
47 nvlist_t *props = NULL;
48
49 if ((zhp = zfs_open(zlibh, nlp->nlp_snapname,
50 ZFS_TYPE_SNAPSHOT)) == NULL) {
51 syslog(LOG_ERR,
52 "Could not open snapshot [%s]\n", nlp->nlp_snapname);
53 return (-1);
54 }
55
56 (void) snprintf(nlp->nlp_mountpoint, sizeof (nlp->nlp_mountpoint),
57 "/%s", nlp->nlp_clonename);
58
59 if ((nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) ||
60 (nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
61 nlp->nlp_mountpoint) != 0)) {
62 nvlist_free(props);
63 syslog(LOG_ERR, "could not create snapshot clone "
64 "%s: out of memory\n", nlp->nlp_clonename);
65 zfs_close(zhp);
66 return (-1);
67 }
68
69 err = zfs_clone(zhp, nlp->nlp_clonename, props);
70 zfs_close(zhp);
71 nvlist_free(props);
72
73 if (err != 0) {
74 syslog(LOG_ERR, "zfs_clone error [%d]\n", err);
75 return (-1);
76 }
77
78 syslog(LOG_DEBUG, "Cloned snapshot [%s] "
79 "clone name [%s] mount point [%s]\n",
80 nlp->nlp_snapname, nlp->nlp_clonename,
81 nlp->nlp_mountpoint);
82
83 if ((clone = zfs_open(zlibh, nlp->nlp_clonename,
84 ZFS_TYPE_DATASET)) == NULL) {
85 syslog(LOG_ERR,
86 "zfs_open failed on clone_name [%s]\n", nlp->nlp_clonename);
87 return (-1);
88 }
89
90 if (zfs_mount(clone, NULL, 0) != 0) {
91 syslog(LOG_ERR, "could not mount ZFS clone "
92 "%s\n", zfs_get_name(clone));
93 res = -1;
94 }
95 zfs_close(clone);
96 return (res);
97 }