Print this page
8264 want support for promoting datasets in libzfs_core


   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).