4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2016 Martin Matuska. All rights reserved.
26 */
27
28 #include <synch.h>
29 #include <pthread.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/errno.h>
34 #include <libzfs.h>
35
36 #include <smbsrv/libsmb.h>
37 #include <smbsrv/libsmbns.h>
38 #include <smbsrv/libmlsvc.h>
39 #include <smbsrv/smbinfo.h>
40 #include "smbd.h"
41
42 /*
43 * This file supports three basic functions that all use the
44 * the zfs_iter_snapshots function to get the snapshot info
93 time_t mg_snaptime;
94 char *mg_snapname;
95 } smbd_vss_map_gmttoken_t;
96
97
98 /*
99 * path - path of the dataset
100 * count - return value of the number of snapshots for the dataset
101 */
102 int
103 smbd_vss_get_count(const char *path, uint32_t *count)
104 {
105 char dataset[MAXPATHLEN];
106 libzfs_handle_t *libhd;
107 zfs_handle_t *zfshd;
108 smbd_vss_count_t vss_count;
109
110 bzero(&vss_count, sizeof (smbd_vss_count_t));
111 *count = 0;
112
113 if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
114 return (-1);
115
116 if ((libhd = libzfs_init()) == NULL)
117 return (-1);
118
119 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
120 libzfs_fini(libhd);
121 return (-1);
122 }
123
124 (void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_count,
125 (void *)&vss_count);
126
127 if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
128 vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;
129
130 *count = vss_count.vc_count;
131 zfs_close(zfshd);
132 libzfs_fini(libhd);
133 return (0);
134 }
135
136 /*
137 * path - is the path of the dataset
148 {
149 char dataset[MAXPATHLEN];
150 libzfs_handle_t *libhd;
151 zfs_handle_t *zfshd;
152 smbd_vss_get_uint64_date_t vss_uint64_date;
153 int i;
154 uint64_t *timep;
155
156 *return_count = 0;
157 *num_gmttokens = 0;
158
159 if (count == 0)
160 return;
161
162 if (count > SMBD_VSS_SNAPSHOT_MAX)
163 count = SMBD_VSS_SNAPSHOT_MAX;
164
165 vss_uint64_date.gd_count = count;
166 vss_uint64_date.gd_return_count = 0;
167 vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t));
168 if (vss_uint64_date.gd_gmt_array == NULL)
169 return;
170
171 if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) {
172 free(vss_uint64_date.gd_gmt_array);
173 return;
174 }
175
176 if ((libhd = libzfs_init()) == NULL) {
177 free(vss_uint64_date.gd_gmt_array);
178 return;
179 }
180
181 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
182 free(vss_uint64_date.gd_gmt_array);
183 libzfs_fini(libhd);
184 return;
185 }
186
187 (void) zfs_iter_snapshots(zfshd, B_FALSE,
188 smbd_vss_iterate_get_uint64_date, (void *)&vss_uint64_date);
189
190 *num_gmttokens = vss_uint64_date.gd_return_count;
191 *return_count = vss_uint64_date.gd_return_count;
192
193 /*
194 * Sort the list since neither zfs nor the client sorts it.
195 */
196 qsort((char *)vss_uint64_date.gd_gmt_array,
197 vss_uint64_date.gd_return_count,
234 smbd_vss_map_gmttoken(const char *path, char *gmttoken, time_t toktime,
235 char *snapname)
236 {
237 char dataset[MAXPATHLEN];
238 libzfs_handle_t *libhd;
239 zfs_handle_t *zfshd;
240 smbd_vss_map_gmttoken_t vss_map_gmttoken;
241 char *zsnap;
242 const char *lsnap;
243 struct tm tm;
244
245 if (gmttoken != NULL && *gmttoken == '@' &&
246 strptime(gmttoken, smbd_vss_gmttoken_fmt, &tm) != NULL) {
247 toktime = timegm(&tm);
248 }
249
250 vss_map_gmttoken.mg_snaptime = toktime;
251 vss_map_gmttoken.mg_snapname = snapname;
252 *snapname = '\0';
253
254 if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
255 return (-1);
256
257 if ((libhd = libzfs_init()) == NULL)
258 return (-1);
259
260 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
261 libzfs_fini(libhd);
262 return (-1);
263 }
264
265 (void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_map_gmttoken,
266 (void *)&vss_map_gmttoken);
267
268 /* compare the zfs snapshot name and the local snap name */
269 zsnap = snapname;
270 lsnap = dataset;
271 while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
272 zsnap++;
273 lsnap++;
274 }
275
276 /* Now we should be passed the dataset name */
277 if ((*zsnap == '@') && (*lsnap == '\0')) {
278 zsnap++;
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2016 Martin Matuska. All rights reserved.
26 */
27
28 #include <synch.h>
29 #include <pthread.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/errno.h>
34 #include <libzfs.h>
35
36 #include <smbsrv/libsmb.h>
37 #include <smbsrv/libsmbns.h>
38 #include <smbsrv/libmlsvc.h>
39 #include <smbsrv/smbinfo.h>
40 #include "smbd.h"
41
42 /*
43 * This file supports three basic functions that all use the
44 * the zfs_iter_snapshots function to get the snapshot info
93 time_t mg_snaptime;
94 char *mg_snapname;
95 } smbd_vss_map_gmttoken_t;
96
97
98 /*
99 * path - path of the dataset
100 * count - return value of the number of snapshots for the dataset
101 */
102 int
103 smbd_vss_get_count(const char *path, uint32_t *count)
104 {
105 char dataset[MAXPATHLEN];
106 libzfs_handle_t *libhd;
107 zfs_handle_t *zfshd;
108 smbd_vss_count_t vss_count;
109
110 bzero(&vss_count, sizeof (smbd_vss_count_t));
111 *count = 0;
112
113 if ((libhd = libzfs_init()) == NULL)
114 return (-1);
115
116 if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
117 libzfs_fini(libhd);
118 return (-1);
119 }
120
121 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
122 libzfs_fini(libhd);
123 return (-1);
124 }
125
126 (void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_count,
127 (void *)&vss_count);
128
129 if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
130 vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;
131
132 *count = vss_count.vc_count;
133 zfs_close(zfshd);
134 libzfs_fini(libhd);
135 return (0);
136 }
137
138 /*
139 * path - is the path of the dataset
150 {
151 char dataset[MAXPATHLEN];
152 libzfs_handle_t *libhd;
153 zfs_handle_t *zfshd;
154 smbd_vss_get_uint64_date_t vss_uint64_date;
155 int i;
156 uint64_t *timep;
157
158 *return_count = 0;
159 *num_gmttokens = 0;
160
161 if (count == 0)
162 return;
163
164 if (count > SMBD_VSS_SNAPSHOT_MAX)
165 count = SMBD_VSS_SNAPSHOT_MAX;
166
167 vss_uint64_date.gd_count = count;
168 vss_uint64_date.gd_return_count = 0;
169 vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t));
170
171 if (vss_uint64_date.gd_gmt_array == NULL)
172 return;
173
174 if ((libhd = libzfs_init()) == NULL) {
175 free(vss_uint64_date.gd_gmt_array);
176 return;
177 }
178
179 if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
180 free(vss_uint64_date.gd_gmt_array);
181 libzfs_fini(libhd);
182 return;
183 }
184
185 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
186 free(vss_uint64_date.gd_gmt_array);
187 libzfs_fini(libhd);
188 return;
189 }
190
191 (void) zfs_iter_snapshots(zfshd, B_FALSE,
192 smbd_vss_iterate_get_uint64_date, (void *)&vss_uint64_date);
193
194 *num_gmttokens = vss_uint64_date.gd_return_count;
195 *return_count = vss_uint64_date.gd_return_count;
196
197 /*
198 * Sort the list since neither zfs nor the client sorts it.
199 */
200 qsort((char *)vss_uint64_date.gd_gmt_array,
201 vss_uint64_date.gd_return_count,
238 smbd_vss_map_gmttoken(const char *path, char *gmttoken, time_t toktime,
239 char *snapname)
240 {
241 char dataset[MAXPATHLEN];
242 libzfs_handle_t *libhd;
243 zfs_handle_t *zfshd;
244 smbd_vss_map_gmttoken_t vss_map_gmttoken;
245 char *zsnap;
246 const char *lsnap;
247 struct tm tm;
248
249 if (gmttoken != NULL && *gmttoken == '@' &&
250 strptime(gmttoken, smbd_vss_gmttoken_fmt, &tm) != NULL) {
251 toktime = timegm(&tm);
252 }
253
254 vss_map_gmttoken.mg_snaptime = toktime;
255 vss_map_gmttoken.mg_snapname = snapname;
256 *snapname = '\0';
257
258 if ((libhd = libzfs_init()) == NULL)
259 return (-1);
260
261 if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
262 libzfs_fini(libhd);
263 return (-1);
264 }
265
266 if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
267 libzfs_fini(libhd);
268 return (-1);
269 }
270
271 (void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_map_gmttoken,
272 (void *)&vss_map_gmttoken);
273
274 /* compare the zfs snapshot name and the local snap name */
275 zsnap = snapname;
276 lsnap = dataset;
277 while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
278 zsnap++;
279 lsnap++;
280 }
281
282 /* Now we should be passed the dataset name */
283 if ((*zsnap == '@') && (*lsnap == '\0')) {
284 zsnap++;
|