Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>


   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;