Print this page
4986 receiving replication stream fails if any snapshot exceeds refquota
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Gordon Ross <gordon.ross@nexenta.com>


   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  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.

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


4039         pair = nvlist_next_nvpair(props, NULL);
4040         while (pair != NULL) {
4041                 const char *propname = nvpair_name(pair);
4042                 nvpair_t *match;
4043 
4044                 next_pair = nvlist_next_nvpair(props, pair);
4045 
4046                 if ((nvlist_lookup_nvpair(origprops, propname,
4047                     &match) != 0) || !propval_equals(pair, match))
4048                         goto next; /* need to set received value */
4049 
4050                 /* don't clear the existing received value */
4051                 (void) nvlist_remove_nvpair(origprops, match);
4052                 /* don't bother receiving the property */
4053                 (void) nvlist_remove_nvpair(props, pair);
4054 next:
4055                 pair = next_pair;
4056         }
4057 }
4058 


















































4059 #ifdef  DEBUG
4060 static boolean_t zfs_ioc_recv_inject_err;
4061 #endif
4062 
4063 /*
4064  * inputs:
4065  * zc_name              name of containing filesystem
4066  * zc_nvlist_src{_size} nvlist of properties to apply
4067  * zc_value             name of snapshot to create
4068  * zc_string            name of clone origin (if DRR_FLAG_CLONE)
4069  * zc_cookie            file descriptor to recv from
4070  * zc_begin_record      the BEGIN record of the stream (not byteswapped)
4071  * zc_guid              force flag
4072  * zc_cleanup_fd        cleanup-on-exit file descriptor
4073  * zc_action_handle     handle for this guid/ds mapping (or zero on first call)
4074  *
4075  * outputs:
4076  * zc_cookie            number of bytes read
4077  * zc_nvlist_dst{_size} error for each unapplied received property
4078  * zc_obj               zprop_errflags_t
4079  * zc_action_handle     handle for this guid/ds mapping
4080  */
4081 static int
4082 zfs_ioc_recv(zfs_cmd_t *zc)
4083 {
4084         file_t *fp;
4085         dmu_recv_cookie_t drc;
4086         boolean_t force = (boolean_t)zc->zc_guid;
4087         int fd;
4088         int error = 0;
4089         int props_error = 0;
4090         nvlist_t *errors;
4091         offset_t off;
4092         nvlist_t *props = NULL; /* sent properties */
4093         nvlist_t *origprops = NULL; /* existing properties */

4094         char *origin = NULL;
4095         char *tosnap;
4096         char tofs[ZFS_MAXNAMELEN];
4097         boolean_t first_recvd_props = B_FALSE;
4098 
4099         if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
4100             strchr(zc->zc_value, '@') == NULL ||
4101             strchr(zc->zc_value, '%'))
4102                 return (SET_ERROR(EINVAL));
4103 
4104         (void) strcpy(tofs, zc->zc_value);
4105         tosnap = strchr(tofs, '@');
4106         *tosnap++ = '\0';
4107 
4108         if (zc->zc_nvlist_src != NULL &&
4109             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
4110             zc->zc_iflags, &props)) != 0)
4111                 return (error);
4112 
4113         fd = zc->zc_cookie;


4154                          * regardless.
4155                          */
4156                         if (!first_recvd_props)
4157                                 props_reduce(props, origprops);
4158                         if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
4159                                 (void) nvlist_merge(errors, errlist, 0);
4160                         nvlist_free(errlist);
4161 
4162                         if (clear_received_props(tofs, origprops,
4163                             first_recvd_props ? NULL : props) != 0)
4164                                 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4165                 } else {
4166                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4167                 }
4168         }
4169 
4170         if (props != NULL) {
4171                 props_error = dsl_prop_set_hasrecvd(tofs);
4172 
4173                 if (props_error == 0) {

4174                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4175                             props, errors);
4176                 }
4177         }
4178 
4179         if (zc->zc_nvlist_dst_size != 0 &&
4180             (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4181             put_nvlist(zc, errors) != 0)) {
4182                 /*
4183                  * Caller made zc->zc_nvlist_dst less than the minimum expected
4184                  * size or supplied an invalid address.
4185                  */
4186                 props_error = SET_ERROR(EINVAL);
4187         }
4188 
4189         off = fp->f_offset;
4190         error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
4191             &zc->zc_action_handle);
4192 
4193         if (error == 0) {
4194                 zfsvfs_t *zfsvfs = NULL;
4195 
4196                 if (getzfsvfs(tofs, &zfsvfs) == 0) {
4197                         /* online recv */
4198                         int end_err;
4199 
4200                         error = zfs_suspend_fs(zfsvfs);
4201                         /*
4202                          * If the suspend fails, then the recv_end will
4203                          * likely also fail, and clean up after itself.
4204                          */
4205                         end_err = dmu_recv_end(&drc, zfsvfs);
4206                         if (error == 0)
4207                                 error = zfs_resume_fs(zfsvfs, tofs);
4208                         error = error ? error : end_err;
4209                         VFS_RELE(zfsvfs->z_vfs);
4210                 } else {
4211                         error = dmu_recv_end(&drc, NULL);
4212                 }





4213         }

4214 




























4215         zc->zc_cookie = off - fp->f_offset;
4216         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4217                 fp->f_offset = off;
4218 
4219 #ifdef  DEBUG
4220         if (zfs_ioc_recv_inject_err) {
4221                 zfs_ioc_recv_inject_err = B_FALSE;
4222                 error = 1;
4223         }
4224 #endif
4225         /*
4226          * On error, restore the original props.
4227          */
4228         if (error != 0 && props != NULL && !drc.drc_newfs) {
4229                 if (clear_received_props(tofs, props, NULL) != 0) {
4230                         /*
4231                          * We failed to clear the received properties.
4232                          * Since we may have left a $recvd value on the
4233                          * system, we can't clear the $hasrecvd flag.
4234                          */




   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  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  27  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2011, 2014 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 (c) 2014, Nexenta Systems, Inc. All rights reserved.
  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().


4040         pair = nvlist_next_nvpair(props, NULL);
4041         while (pair != NULL) {
4042                 const char *propname = nvpair_name(pair);
4043                 nvpair_t *match;
4044 
4045                 next_pair = nvlist_next_nvpair(props, pair);
4046 
4047                 if ((nvlist_lookup_nvpair(origprops, propname,
4048                     &match) != 0) || !propval_equals(pair, match))
4049                         goto next; /* need to set received value */
4050 
4051                 /* don't clear the existing received value */
4052                 (void) nvlist_remove_nvpair(origprops, match);
4053                 /* don't bother receiving the property */
4054                 (void) nvlist_remove_nvpair(props, pair);
4055 next:
4056                 pair = next_pair;
4057         }
4058 }
4059 
4060 /*
4061  * Extract properties that cannot be set PRIOR to the receipt of a dataset.
4062  * For example, refquota cannot be set until after the receipt of a dataset,
4063  * because in replication streams, an older/earlier snapshot may exceed the
4064  * refquota.  We want to receive the older/earlier snapshot, but setting
4065  * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent
4066  * the older/earlier snapshot from being received (with EDQUOT).
4067  *
4068  * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario.
4069  *
4070  * libzfs will need to be judicious handling errors encountered by props
4071  * extracted by this function.
4072  */
4073 static nvlist_t *
4074 extract_delay_props(nvlist_t *props)
4075 {
4076         nvlist_t *delayprops;
4077         nvpair_t *nvp, *tmp;
4078         static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
4079         int i;
4080 
4081         VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
4082 
4083         for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
4084             nvp = nvlist_next_nvpair(props, nvp)) {
4085                 /*
4086                  * strcmp() is safe because zfs_prop_to_name() always returns
4087                  * a bounded string.
4088                  */
4089                 for (i = 0; delayable[i] != 0; i++) {
4090                         if (strcmp(zfs_prop_to_name(delayable[i]),
4091                             nvpair_name(nvp)) == 0) {
4092                                 break;
4093                         }
4094                 }
4095                 if (delayable[i] != 0) {
4096                         tmp = nvlist_prev_nvpair(props, nvp);
4097                         VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
4098                         VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
4099                         nvp = tmp;
4100                 }
4101         }
4102 
4103         if (nvlist_empty(delayprops)) {
4104                 nvlist_free(delayprops);
4105                 delayprops = NULL;
4106         }
4107         return (delayprops);
4108 }
4109 
4110 #ifdef  DEBUG
4111 static boolean_t zfs_ioc_recv_inject_err;
4112 #endif
4113 
4114 /*
4115  * inputs:
4116  * zc_name              name of containing filesystem
4117  * zc_nvlist_src{_size} nvlist of properties to apply
4118  * zc_value             name of snapshot to create
4119  * zc_string            name of clone origin (if DRR_FLAG_CLONE)
4120  * zc_cookie            file descriptor to recv from
4121  * zc_begin_record      the BEGIN record of the stream (not byteswapped)
4122  * zc_guid              force flag
4123  * zc_cleanup_fd        cleanup-on-exit file descriptor
4124  * zc_action_handle     handle for this guid/ds mapping (or zero on first call)
4125  *
4126  * outputs:
4127  * zc_cookie            number of bytes read
4128  * zc_nvlist_dst{_size} error for each unapplied received property
4129  * zc_obj               zprop_errflags_t
4130  * zc_action_handle     handle for this guid/ds mapping
4131  */
4132 static int
4133 zfs_ioc_recv(zfs_cmd_t *zc)
4134 {
4135         file_t *fp;
4136         dmu_recv_cookie_t drc;
4137         boolean_t force = (boolean_t)zc->zc_guid;
4138         int fd;
4139         int error = 0;
4140         int props_error = 0;
4141         nvlist_t *errors;
4142         offset_t off;
4143         nvlist_t *props = NULL; /* sent properties */
4144         nvlist_t *origprops = NULL; /* existing properties */
4145         nvlist_t *delayprops = NULL; /* sent properties applied post-receive */
4146         char *origin = NULL;
4147         char *tosnap;
4148         char tofs[ZFS_MAXNAMELEN];
4149         boolean_t first_recvd_props = B_FALSE;
4150 
4151         if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
4152             strchr(zc->zc_value, '@') == NULL ||
4153             strchr(zc->zc_value, '%'))
4154                 return (SET_ERROR(EINVAL));
4155 
4156         (void) strcpy(tofs, zc->zc_value);
4157         tosnap = strchr(tofs, '@');
4158         *tosnap++ = '\0';
4159 
4160         if (zc->zc_nvlist_src != NULL &&
4161             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
4162             zc->zc_iflags, &props)) != 0)
4163                 return (error);
4164 
4165         fd = zc->zc_cookie;


4206                          * regardless.
4207                          */
4208                         if (!first_recvd_props)
4209                                 props_reduce(props, origprops);
4210                         if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
4211                                 (void) nvlist_merge(errors, errlist, 0);
4212                         nvlist_free(errlist);
4213 
4214                         if (clear_received_props(tofs, origprops,
4215                             first_recvd_props ? NULL : props) != 0)
4216                                 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4217                 } else {
4218                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4219                 }
4220         }
4221 
4222         if (props != NULL) {
4223                 props_error = dsl_prop_set_hasrecvd(tofs);
4224 
4225                 if (props_error == 0) {
4226                         delayprops = extract_delay_props(props);
4227                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4228                             props, errors);
4229                 }
4230         }
4231 










4232         off = fp->f_offset;
4233         error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
4234             &zc->zc_action_handle);
4235 
4236         if (error == 0) {
4237                 zfsvfs_t *zfsvfs = NULL;
4238 
4239                 if (getzfsvfs(tofs, &zfsvfs) == 0) {
4240                         /* online recv */
4241                         int end_err;
4242 
4243                         error = zfs_suspend_fs(zfsvfs);
4244                         /*
4245                          * If the suspend fails, then the recv_end will
4246                          * likely also fail, and clean up after itself.
4247                          */
4248                         end_err = dmu_recv_end(&drc, zfsvfs);
4249                         if (error == 0)
4250                                 error = zfs_resume_fs(zfsvfs, tofs);
4251                         error = error ? error : end_err;
4252                         VFS_RELE(zfsvfs->z_vfs);
4253                 } else {
4254                         error = dmu_recv_end(&drc, NULL);
4255                 }
4256 
4257                 /* Set delayed properties now, after we're done receiving. */
4258                 if (delayprops != NULL && error == 0) {
4259                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4260                             delayprops, errors);
4261                 }
4262         }
4263 
4264         if (delayprops != NULL) {
4265                 /*
4266                  * Merge delayed props back in with initial props, in case
4267                  * we're DEBUG and zfs_ioc_recv_inject_err is set (which means
4268                  * we have to make sure clear_received_props() includes
4269                  * the delayed properties).
4270                  *
4271                  * Since zfs_ioc_recv_inject_err is only in DEBUG kernels,
4272                  * using ASSERT() will be just like a VERIFY.
4273                  */
4274                 ASSERT(nvlist_merge(props, delayprops, 0) == 0);
4275                 nvlist_free(delayprops);
4276         }
4277 
4278         /*
4279          * Now that all props, initial and delayed, are set, report the prop
4280          * errors to the caller.
4281          */
4282         if (zc->zc_nvlist_dst_size != 0 &&
4283             (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4284             put_nvlist(zc, errors) != 0)) {
4285                 /*
4286                  * Caller made zc->zc_nvlist_dst less than the minimum expected
4287                  * size or supplied an invalid address.
4288                  */
4289                 props_error = SET_ERROR(EINVAL);
4290         }
4291 
4292         zc->zc_cookie = off - fp->f_offset;
4293         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4294                 fp->f_offset = off;
4295 
4296 #ifdef  DEBUG
4297         if (zfs_ioc_recv_inject_err) {
4298                 zfs_ioc_recv_inject_err = B_FALSE;
4299                 error = 1;
4300         }
4301 #endif
4302         /*
4303          * On error, restore the original props.
4304          */
4305         if (error != 0 && props != NULL && !drc.drc_newfs) {
4306                 if (clear_received_props(tofs, props, NULL) != 0) {
4307                         /*
4308                          * We failed to clear the received properties.
4309                          * Since we may have left a $recvd value on the
4310                          * system, we can't clear the $hasrecvd flag.
4311                          */