Print this page
Placeholder


  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  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  26  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  29  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  30  * Copyright (c) 2013 Steven Hartland. All rights reserved.

  31  */
  32 
  33 /*
  34  * ZFS ioctls.
  35  *
  36  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  37  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  38  *
  39  * There are two ways that we handle ioctls: the legacy way where almost
  40  * all of the logic is in the ioctl callback, and the new way where most
  41  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  42  *
  43  * Non-legacy ioctls should be registered by calling
  44  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  45  * from userland by lzc_ioctl().
  46  *
  47  * The registration arguments are as follows:
  48  *
  49  * const char *name
  50  *   The name of the ioctl.  This is used for history logging.  If the


4388  * zc_name      name of snapshot to send
4389  * zc_cookie    file descriptor to send stream to
4390  * zc_obj       fromorigin flag (mutually exclusive with zc_fromobj)
4391  * zc_sendobj   objsetid of snapshot to send
4392  * zc_fromobj   objsetid of incremental fromsnap (may be zero)
4393  * zc_guid      if set, estimate size of stream only.  zc_cookie is ignored.
4394  *              output size in zc_objset_type.
4395  * zc_flags     lzc_send_flags
4396  *
4397  * outputs:
4398  * zc_objset_type       estimated size, if zc_guid is set
4399  */
4400 static int
4401 zfs_ioc_send(zfs_cmd_t *zc)
4402 {
4403         int error;
4404         offset_t off;
4405         boolean_t estimate = (zc->zc_guid != 0);
4406         boolean_t embedok = (zc->zc_flags & 0x1);
4407         boolean_t large_block_ok = (zc->zc_flags & 0x2);

4408 
4409         if (zc->zc_obj != 0) {
4410                 dsl_pool_t *dp;
4411                 dsl_dataset_t *tosnap;
4412 
4413                 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4414                 if (error != 0)
4415                         return (error);
4416 
4417                 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4418                 if (error != 0) {
4419                         dsl_pool_rele(dp, FTAG);
4420                         return (error);
4421                 }
4422 
4423                 if (dsl_dir_is_clone(tosnap->ds_dir))
4424                         zc->zc_fromobj =
4425                             dsl_dir_phys(tosnap->ds_dir)->dd_origin_obj;
4426                 dsl_dataset_rele(tosnap, FTAG);
4427                 dsl_pool_rele(dp, FTAG);


4450                                 dsl_pool_rele(dp, FTAG);
4451                                 return (error);
4452                         }
4453                 }
4454 
4455                 error = dmu_send_estimate(tosnap, fromsnap,
4456                     &zc->zc_objset_type);
4457 
4458                 if (fromsnap != NULL)
4459                         dsl_dataset_rele(fromsnap, FTAG);
4460                 dsl_dataset_rele(tosnap, FTAG);
4461                 dsl_pool_rele(dp, FTAG);
4462         } else {
4463                 file_t *fp = getf(zc->zc_cookie);
4464                 if (fp == NULL)
4465                         return (SET_ERROR(EBADF));
4466 
4467                 off = fp->f_offset;
4468                 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
4469                     zc->zc_fromobj, embedok, large_block_ok,
4470                     zc->zc_cookie, fp->f_vnode, &off);
4471 
4472                 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4473                         fp->f_offset = off;
4474                 releasef(zc->zc_cookie);
4475         }
4476         return (error);
4477 }
4478 
4479 /*
4480  * inputs:
4481  * zc_name      name of snapshot on which to report progress
4482  * zc_cookie    file descriptor of send stream
4483  *
4484  * outputs:
4485  * zc_cookie    number of bytes written in send stream thus far
4486  */
4487 static int
4488 zfs_ioc_send_progress(zfs_cmd_t *zc)
4489 {
4490         dsl_pool_t *dp;


5379         }
5380 
5381         error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
5382         dsl_dataset_rele(old, FTAG);
5383         dsl_dataset_rele(new, FTAG);
5384         dsl_pool_rele(dp, FTAG);
5385         fnvlist_add_uint64(outnvl, "used", used);
5386         fnvlist_add_uint64(outnvl, "compressed", comp);
5387         fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
5388         return (error);
5389 }
5390 
5391 /*
5392  * innvl: {
5393  *     "fd" -> file descriptor to write stream to (int32)
5394  *     (optional) "fromsnap" -> full snap name to send an incremental from
5395  *     (optional) "largeblockok" -> (value ignored)
5396  *         indicates that blocks > 128KB are permitted
5397  *     (optional) "embedok" -> (value ignored)
5398  *         presence indicates DRR_WRITE_EMBEDDED records are permitted


5399  *     (optional) "resume_object" and "resume_offset" -> (uint64)
5400  *         if present, resume send stream from specified object and offset.
5401  * }
5402  *
5403  * outnvl is unused
5404  */
5405 /* ARGSUSED */
5406 static int
5407 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5408 {
5409         int error;
5410         offset_t off;
5411         char *fromname = NULL;
5412         int fd;
5413         boolean_t largeblockok;
5414         boolean_t embedok;

5415         uint64_t resumeobj = 0;
5416         uint64_t resumeoff = 0;
5417 
5418         error = nvlist_lookup_int32(innvl, "fd", &fd);
5419         if (error != 0)
5420                 return (SET_ERROR(EINVAL));
5421 
5422         (void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
5423 
5424         largeblockok = nvlist_exists(innvl, "largeblockok");
5425         embedok = nvlist_exists(innvl, "embedok");

5426 
5427         (void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj);
5428         (void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff);
5429 
5430         file_t *fp = getf(fd);
5431         if (fp == NULL)
5432                 return (SET_ERROR(EBADF));
5433 
5434         off = fp->f_offset;
5435         error = dmu_send(snapname, fromname, embedok, largeblockok, fd,
5436             resumeobj, resumeoff, fp->f_vnode, &off);
5437 
5438         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5439                 fp->f_offset = off;
5440         releasef(fd);
5441         return (error);
5442 }
5443 
5444 /*
5445  * Determine approximately how large a zfs send stream will be -- the number
5446  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5447  *
5448  * innvl: {
5449  *     (optional) "from" -> full snap or bookmark name to send an incremental
5450  *                          from
5451  * }
5452  *
5453  * outnvl: {
5454  *     "space" -> bytes of space (uint64)
5455  * }
5456  */




  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  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  26  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  27  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  29  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  30  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  31  * Copyright 2015 RackTop Systems.
  32  */
  33 
  34 /*
  35  * ZFS ioctls.
  36  *
  37  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  38  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  39  *
  40  * There are two ways that we handle ioctls: the legacy way where almost
  41  * all of the logic is in the ioctl callback, and the new way where most
  42  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  43  *
  44  * Non-legacy ioctls should be registered by calling
  45  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  46  * from userland by lzc_ioctl().
  47  *
  48  * The registration arguments are as follows:
  49  *
  50  * const char *name
  51  *   The name of the ioctl.  This is used for history logging.  If the


4389  * zc_name      name of snapshot to send
4390  * zc_cookie    file descriptor to send stream to
4391  * zc_obj       fromorigin flag (mutually exclusive with zc_fromobj)
4392  * zc_sendobj   objsetid of snapshot to send
4393  * zc_fromobj   objsetid of incremental fromsnap (may be zero)
4394  * zc_guid      if set, estimate size of stream only.  zc_cookie is ignored.
4395  *              output size in zc_objset_type.
4396  * zc_flags     lzc_send_flags
4397  *
4398  * outputs:
4399  * zc_objset_type       estimated size, if zc_guid is set
4400  */
4401 static int
4402 zfs_ioc_send(zfs_cmd_t *zc)
4403 {
4404         int error;
4405         offset_t off;
4406         boolean_t estimate = (zc->zc_guid != 0);
4407         boolean_t embedok = (zc->zc_flags & 0x1);
4408         boolean_t large_block_ok = (zc->zc_flags & 0x2);
4409         boolean_t skip_free = (zc->zc_flags & 0x4);
4410 
4411         if (zc->zc_obj != 0) {
4412                 dsl_pool_t *dp;
4413                 dsl_dataset_t *tosnap;
4414 
4415                 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4416                 if (error != 0)
4417                         return (error);
4418 
4419                 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4420                 if (error != 0) {
4421                         dsl_pool_rele(dp, FTAG);
4422                         return (error);
4423                 }
4424 
4425                 if (dsl_dir_is_clone(tosnap->ds_dir))
4426                         zc->zc_fromobj =
4427                             dsl_dir_phys(tosnap->ds_dir)->dd_origin_obj;
4428                 dsl_dataset_rele(tosnap, FTAG);
4429                 dsl_pool_rele(dp, FTAG);


4452                                 dsl_pool_rele(dp, FTAG);
4453                                 return (error);
4454                         }
4455                 }
4456 
4457                 error = dmu_send_estimate(tosnap, fromsnap,
4458                     &zc->zc_objset_type);
4459 
4460                 if (fromsnap != NULL)
4461                         dsl_dataset_rele(fromsnap, FTAG);
4462                 dsl_dataset_rele(tosnap, FTAG);
4463                 dsl_pool_rele(dp, FTAG);
4464         } else {
4465                 file_t *fp = getf(zc->zc_cookie);
4466                 if (fp == NULL)
4467                         return (SET_ERROR(EBADF));
4468 
4469                 off = fp->f_offset;
4470                 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
4471                     zc->zc_fromobj, embedok, large_block_ok,
4472                     zc->zc_cookie, skip_free, fp->f_vnode, &off);
4473 
4474                 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4475                         fp->f_offset = off;
4476                 releasef(zc->zc_cookie);
4477         }
4478         return (error);
4479 }
4480 
4481 /*
4482  * inputs:
4483  * zc_name      name of snapshot on which to report progress
4484  * zc_cookie    file descriptor of send stream
4485  *
4486  * outputs:
4487  * zc_cookie    number of bytes written in send stream thus far
4488  */
4489 static int
4490 zfs_ioc_send_progress(zfs_cmd_t *zc)
4491 {
4492         dsl_pool_t *dp;


5381         }
5382 
5383         error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
5384         dsl_dataset_rele(old, FTAG);
5385         dsl_dataset_rele(new, FTAG);
5386         dsl_pool_rele(dp, FTAG);
5387         fnvlist_add_uint64(outnvl, "used", used);
5388         fnvlist_add_uint64(outnvl, "compressed", comp);
5389         fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
5390         return (error);
5391 }
5392 
5393 /*
5394  * innvl: {
5395  *     "fd" -> file descriptor to write stream to (int32)
5396  *     (optional) "fromsnap" -> full snap name to send an incremental from
5397  *     (optional) "largeblockok" -> (value ignored)
5398  *         indicates that blocks > 128KB are permitted
5399  *     (optional) "embedok" -> (value ignored)
5400  *         presence indicates DRR_WRITE_EMBEDDED records are permitted
5401  *     (optional) "skip_free" -> (value ignored)
5402  *         presence indicates free records should be omitted
5403  *     (optional) "resume_object" and "resume_offset" -> (uint64)
5404  *         if present, resume send stream from specified object and offset.
5405  * }
5406  *
5407  * outnvl is unused
5408  */
5409 /* ARGSUSED */
5410 static int
5411 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5412 {
5413         int error;
5414         offset_t off;
5415         char *fromname = NULL;
5416         int fd;
5417         boolean_t largeblockok;
5418         boolean_t embedok;
5419         boolean_t skip_free;
5420         uint64_t resumeobj = 0;
5421         uint64_t resumeoff = 0;
5422 
5423         error = nvlist_lookup_int32(innvl, "fd", &fd);
5424         if (error != 0)
5425                 return (SET_ERROR(EINVAL));
5426 
5427         (void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
5428 
5429         largeblockok = nvlist_exists(innvl, "largeblockok");
5430         embedok = nvlist_exists(innvl, "embedok");
5431         skip_free = nvlist_exists(innvl, "skip_free");
5432 
5433         (void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj);
5434         (void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff);
5435 
5436         file_t *fp = getf(fd);
5437         if (fp == NULL)
5438                 return (SET_ERROR(EBADF));
5439 
5440         off = fp->f_offset;
5441         error = dmu_send(snapname, fromname, embedok, largeblockok, fd,
5442             resumeobj, resumeoff, skip_free, fp->f_vnode, &off);
5443 
5444         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5445                 fp->f_offset = off;
5446         releasef(fd);
5447         return (error);
5448 }
5449 
5450 /*
5451  * Determine approximately how large a zfs send stream will be -- the number
5452  * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5453  *
5454  * innvl: {
5455  *     (optional) "from" -> full snap or bookmark name to send an incremental
5456  *                          from
5457  * }
5458  *
5459  * outnvl: {
5460  *     "space" -> bytes of space (uint64)
5461  * }
5462  */