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) 2012, 2014 by Delphix. All rights reserved.
24 * Copyright (c) 2013 Steven Hartland. All rights reserved.
25 * Copyright (c) 2014 Integros [integros.com]
26 */
27
28 /*
29 * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
30 * It has the following characteristics:
31 *
32 * - Thread Safe. libzfs_core is accessible concurrently from multiple
33 * threads. This is accomplished primarily by avoiding global data
34 * (e.g. caching). Since it's thread-safe, there is no reason for a
35 * process to have multiple libzfs "instances". Therefore, we store
36 * our few pieces of data (e.g. the file descriptor) in global
37 * variables. The fd is reference-counted so that the libzfs_core
38 * library can be "initialized" multiple times (e.g. by different
39 * consumers within the same process).
40 *
41 * - Committed Interface. The libzfs_core interface will be committed,
42 * therefore consumers can compile against it and be confident that
43 * their code will continue to work on future releases of this code.
44 * Currently, the interface is Evolving (not Committed), but we intend
45 * to commit to it once it is more complete and we determine that it
186 fnvlist_add_nvlist(args, "props", props);
187 error = lzc_ioctl(ZFS_IOC_CREATE, fsname, args, NULL);
188 nvlist_free(args);
189 return (error);
190 }
191
192 int
193 lzc_clone(const char *fsname, const char *origin,
194 nvlist_t *props)
195 {
196 int error;
197 nvlist_t *args = fnvlist_alloc();
198 fnvlist_add_string(args, "origin", origin);
199 if (props != NULL)
200 fnvlist_add_nvlist(args, "props", props);
201 error = lzc_ioctl(ZFS_IOC_CLONE, fsname, args, NULL);
202 nvlist_free(args);
203 return (error);
204 }
205
206 /*
207 * Creates snapshots.
208 *
209 * The keys in the snaps nvlist are the snapshots to be created.
210 * They must all be in the same pool.
211 *
212 * The props nvlist is properties to set. Currently only user properties
213 * are supported. { user:prop_name -> string value }
214 *
215 * The returned results nvlist will have an entry for each snapshot that failed.
216 * The value will be the (int32) error code.
217 *
218 * The return value will be 0 if all snapshots were created, otherwise it will
219 * be the errno of a (unspecified) snapshot that failed.
220 */
221 int
222 lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist)
223 {
224 nvpair_t *elem;
225 nvlist_t *args;
313 return (EINVAL);
314 *atp = '\0';
315
316 args = fnvlist_alloc();
317 fnvlist_add_string(args, "firstsnap", firstsnap);
318
319 err = lzc_ioctl(ZFS_IOC_SPACE_SNAPS, lastsnap, args, &result);
320 nvlist_free(args);
321 if (err == 0)
322 *usedp = fnvlist_lookup_uint64(result, "used");
323 fnvlist_free(result);
324
325 return (err);
326 }
327
328 boolean_t
329 lzc_exists(const char *dataset)
330 {
331 /*
332 * The objset_stats ioctl is still legacy, so we need to construct our
333 * own zfs_cmd_t rather than using zfsc_ioctl().
334 */
335 zfs_cmd_t zc = { 0 };
336
337 ASSERT3S(g_refcount, >, 0);
338 VERIFY3S(g_fd, !=, -1);
339
340 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
341 return (ioctl(g_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0);
342 }
343
344 /*
345 * Create "user holds" on snapshots. If there is a hold on a snapshot,
346 * the snapshot can not be destroyed. (However, it can be marked for deletion
347 * by lzc_destroy_snaps(defer=B_TRUE).)
348 *
349 * The keys in the nvlist are snapshot names.
350 * The snapshots must all be in the same pool.
351 * The value is the name of the hold (string type).
352 *
353 * If cleanup_fd is not -1, it must be the result of open("/dev/zfs", O_EXCL).
|
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) 2012, 2014 by Delphix. All rights reserved.
24 * Copyright (c) 2013 Steven Hartland. All rights reserved.
25 * Copyright (c) 2014 Integros [integros.com]
26 * Copyright 2017 RackTop Systems.
27 */
28
29 /*
30 * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
31 * It has the following characteristics:
32 *
33 * - Thread Safe. libzfs_core is accessible concurrently from multiple
34 * threads. This is accomplished primarily by avoiding global data
35 * (e.g. caching). Since it's thread-safe, there is no reason for a
36 * process to have multiple libzfs "instances". Therefore, we store
37 * our few pieces of data (e.g. the file descriptor) in global
38 * variables. The fd is reference-counted so that the libzfs_core
39 * library can be "initialized" multiple times (e.g. by different
40 * consumers within the same process).
41 *
42 * - Committed Interface. The libzfs_core interface will be committed,
43 * therefore consumers can compile against it and be confident that
44 * their code will continue to work on future releases of this code.
45 * Currently, the interface is Evolving (not Committed), but we intend
46 * to commit to it once it is more complete and we determine that it
187 fnvlist_add_nvlist(args, "props", props);
188 error = lzc_ioctl(ZFS_IOC_CREATE, fsname, args, NULL);
189 nvlist_free(args);
190 return (error);
191 }
192
193 int
194 lzc_clone(const char *fsname, const char *origin,
195 nvlist_t *props)
196 {
197 int error;
198 nvlist_t *args = fnvlist_alloc();
199 fnvlist_add_string(args, "origin", origin);
200 if (props != NULL)
201 fnvlist_add_nvlist(args, "props", props);
202 error = lzc_ioctl(ZFS_IOC_CLONE, fsname, args, NULL);
203 nvlist_free(args);
204 return (error);
205 }
206
207 int
208 lzc_promote(const char *fsname, char *snapnamebuf, int snapnamelen)
209 {
210 /*
211 * The promote ioctl is still legacy, so we need to construct our
212 * own zfs_cmd_t rather than using lzc_ioctl().
213 */
214 zfs_cmd_t zc = { 0 };
215
216 ASSERT3S(g_refcount, >, 0);
217 VERIFY3S(g_fd, !=, -1);
218
219 (void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));
220 if (ioctl(g_fd, ZFS_IOC_PROMOTE, &zc) != 0) {
221 if (errno == EEXIST && snapnamebuf != NULL)
222 (void) strlcpy(snapnamebuf, zc.zc_string, snapnamelen);
223 return (errno);
224 }
225 return (0);
226 }
227
228 /*
229 * Creates snapshots.
230 *
231 * The keys in the snaps nvlist are the snapshots to be created.
232 * They must all be in the same pool.
233 *
234 * The props nvlist is properties to set. Currently only user properties
235 * are supported. { user:prop_name -> string value }
236 *
237 * The returned results nvlist will have an entry for each snapshot that failed.
238 * The value will be the (int32) error code.
239 *
240 * The return value will be 0 if all snapshots were created, otherwise it will
241 * be the errno of a (unspecified) snapshot that failed.
242 */
243 int
244 lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist)
245 {
246 nvpair_t *elem;
247 nvlist_t *args;
335 return (EINVAL);
336 *atp = '\0';
337
338 args = fnvlist_alloc();
339 fnvlist_add_string(args, "firstsnap", firstsnap);
340
341 err = lzc_ioctl(ZFS_IOC_SPACE_SNAPS, lastsnap, args, &result);
342 nvlist_free(args);
343 if (err == 0)
344 *usedp = fnvlist_lookup_uint64(result, "used");
345 fnvlist_free(result);
346
347 return (err);
348 }
349
350 boolean_t
351 lzc_exists(const char *dataset)
352 {
353 /*
354 * The objset_stats ioctl is still legacy, so we need to construct our
355 * own zfs_cmd_t rather than using lzc_ioctl().
356 */
357 zfs_cmd_t zc = { 0 };
358
359 ASSERT3S(g_refcount, >, 0);
360 VERIFY3S(g_fd, !=, -1);
361
362 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
363 return (ioctl(g_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0);
364 }
365
366 /*
367 * Create "user holds" on snapshots. If there is a hold on a snapshot,
368 * the snapshot can not be destroyed. (However, it can be marked for deletion
369 * by lzc_destroy_snaps(defer=B_TRUE).)
370 *
371 * The keys in the nvlist are snapshot names.
372 * The snapshots must all be in the same pool.
373 * The value is the name of the hold (string type).
374 *
375 * If cleanup_fd is not -1, it must be the result of open("/dev/zfs", O_EXCL).
|