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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2011 by Delphix. All rights reserved.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <unistd.h>
32 #include <stddef.h>
33 #include <libintl.h>
34 #include <libzfs.h>
35
36 #include "libzfs_impl.h"
37
38 int
39 zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
40 {
41 nvlist_t *nvl = zfs_get_clones_nvl(zhp);
42 nvpair_t *pair;
43
44 if (nvl == NULL)
45 return (0);
284 }
285
286 /*
287 * spec is a string like "A,B%C,D"
288 *
289 * <snaps>, where <snaps> can be:
290 * <snap> (single snapshot)
291 * <snap>%<snap> (range of snapshots, inclusive)
292 * %<snap> (range of snapshots, starting with earliest)
293 * <snap>% (range of snapshots, ending with last)
294 * % (all snapshots)
295 * <snaps>[,...] (comma separated list of the above)
296 *
297 * If a snapshot can not be opened, continue trying to open the others, but
298 * return ENOENT at the end.
299 */
300 int
301 zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
302 zfs_iter_f func, void *arg)
303 {
304 char buf[ZFS_MAXNAMELEN];
305 char *comma_separated, *cp;
306 int err = 0;
307 int ret = 0;
308
309 (void) strlcpy(buf, spec_orig, sizeof (buf));
310 cp = buf;
311
312 while ((comma_separated = strsep(&cp, ",")) != NULL) {
313 char *pct = strchr(comma_separated, '%');
314 if (pct != NULL) {
315 snapspec_arg_t ssa = { 0 };
316 ssa.ssa_func = func;
317 ssa.ssa_arg = arg;
318
319 if (pct == comma_separated)
320 ssa.ssa_seenfirst = B_TRUE;
321 else
322 ssa.ssa_first = comma_separated;
323 *pct = '\0';
324 ssa.ssa_last = pct + 1;
325
326 /*
327 * If there is a lastname specified, make sure it
328 * exists.
329 */
347 (ssa.ssa_last[0] != '\0' && !ssa.ssa_seenlast))) {
348 ret = ENOENT;
349 }
350 } else {
351 char snapname[ZFS_MAXNAMELEN];
352 zfs_handle_t *snap_zhp;
353 (void) snprintf(snapname, sizeof (snapname), "%s@%s",
354 zfs_get_name(fs_zhp), comma_separated);
355 snap_zhp = make_dataset_handle(fs_zhp->zfs_hdl,
356 snapname);
357 if (snap_zhp == NULL) {
358 ret = ENOENT;
359 continue;
360 }
361 err = func(snap_zhp, arg);
362 if (ret == 0)
363 ret = err;
364 }
365 }
366
367 return (ret);
368 }
369
370 /*
371 * Iterate over all children, snapshots and filesystems
372 */
373 int
374 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
375 {
376 int ret;
377
378 if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
379 return (ret);
380
381 return (zfs_iter_snapshots(zhp, func, data));
382 }
383
384
385 typedef struct iter_stack_frame {
386 struct iter_stack_frame *next;
|
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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2012 by Delphix. All rights reserved.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <unistd.h>
32 #include <stddef.h>
33 #include <libintl.h>
34 #include <libzfs.h>
35
36 #include "libzfs_impl.h"
37
38 int
39 zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
40 {
41 nvlist_t *nvl = zfs_get_clones_nvl(zhp);
42 nvpair_t *pair;
43
44 if (nvl == NULL)
45 return (0);
284 }
285
286 /*
287 * spec is a string like "A,B%C,D"
288 *
289 * <snaps>, where <snaps> can be:
290 * <snap> (single snapshot)
291 * <snap>%<snap> (range of snapshots, inclusive)
292 * %<snap> (range of snapshots, starting with earliest)
293 * <snap>% (range of snapshots, ending with last)
294 * % (all snapshots)
295 * <snaps>[,...] (comma separated list of the above)
296 *
297 * If a snapshot can not be opened, continue trying to open the others, but
298 * return ENOENT at the end.
299 */
300 int
301 zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
302 zfs_iter_f func, void *arg)
303 {
304 char *buf, *comma_separated, *cp;
305 int err = 0;
306 int ret = 0;
307
308 buf = zfs_strdup(fs_zhp->zfs_hdl, spec_orig);
309 cp = buf;
310
311 while ((comma_separated = strsep(&cp, ",")) != NULL) {
312 char *pct = strchr(comma_separated, '%');
313 if (pct != NULL) {
314 snapspec_arg_t ssa = { 0 };
315 ssa.ssa_func = func;
316 ssa.ssa_arg = arg;
317
318 if (pct == comma_separated)
319 ssa.ssa_seenfirst = B_TRUE;
320 else
321 ssa.ssa_first = comma_separated;
322 *pct = '\0';
323 ssa.ssa_last = pct + 1;
324
325 /*
326 * If there is a lastname specified, make sure it
327 * exists.
328 */
346 (ssa.ssa_last[0] != '\0' && !ssa.ssa_seenlast))) {
347 ret = ENOENT;
348 }
349 } else {
350 char snapname[ZFS_MAXNAMELEN];
351 zfs_handle_t *snap_zhp;
352 (void) snprintf(snapname, sizeof (snapname), "%s@%s",
353 zfs_get_name(fs_zhp), comma_separated);
354 snap_zhp = make_dataset_handle(fs_zhp->zfs_hdl,
355 snapname);
356 if (snap_zhp == NULL) {
357 ret = ENOENT;
358 continue;
359 }
360 err = func(snap_zhp, arg);
361 if (ret == 0)
362 ret = err;
363 }
364 }
365
366 free(buf);
367 return (ret);
368 }
369
370 /*
371 * Iterate over all children, snapshots and filesystems
372 */
373 int
374 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
375 {
376 int ret;
377
378 if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
379 return (ret);
380
381 return (zfs_iter_snapshots(zhp, func, data));
382 }
383
384
385 typedef struct iter_stack_frame {
386 struct iter_stack_frame *next;
|