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>


   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  * Portions Copyright 2011 Martin Matuska

  25  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2011, 2015 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  */
  31 
  32 /*
  33  * ZFS ioctls.
  34  *
  35  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  36  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  37  *
  38  * There are two ways that we handle ioctls: the legacy way where almost
  39  * all of the logic is in the ioctl callback, and the new way where most
  40  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  41  *
  42  * Non-legacy ioctls should be registered by calling
  43  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  44  * from userland by lzc_ioctl().


4073         pair = nvlist_next_nvpair(props, NULL);
4074         while (pair != NULL) {
4075                 const char *propname = nvpair_name(pair);
4076                 nvpair_t *match;
4077 
4078                 next_pair = nvlist_next_nvpair(props, pair);
4079 
4080                 if ((nvlist_lookup_nvpair(origprops, propname,
4081                     &match) != 0) || !propval_equals(pair, match))
4082                         goto next; /* need to set received value */
4083 
4084                 /* don't clear the existing received value */
4085                 (void) nvlist_remove_nvpair(origprops, match);
4086                 /* don't bother receiving the property */
4087                 (void) nvlist_remove_nvpair(props, pair);
4088 next:
4089                 pair = next_pair;
4090         }
4091 }
4092 


















































4093 #ifdef  DEBUG
4094 static boolean_t zfs_ioc_recv_inject_err;
4095 #endif
4096 
4097 /*
4098  * inputs:
4099  * zc_name              name of containing filesystem
4100  * zc_nvlist_src{_size} nvlist of properties to apply
4101  * zc_value             name of snapshot to create
4102  * zc_string            name of clone origin (if DRR_FLAG_CLONE)
4103  * zc_cookie            file descriptor to recv from
4104  * zc_begin_record      the BEGIN record of the stream (not byteswapped)
4105  * zc_guid              force flag
4106  * zc_cleanup_fd        cleanup-on-exit file descriptor
4107  * zc_action_handle     handle for this guid/ds mapping (or zero on first call)
4108  * zc_resumable         if data is incomplete assume sender will resume
4109  *
4110  * outputs:
4111  * zc_cookie            number of bytes read
4112  * zc_nvlist_dst{_size} error for each unapplied received property
4113  * zc_obj               zprop_errflags_t
4114  * zc_action_handle     handle for this guid/ds mapping
4115  */
4116 static int
4117 zfs_ioc_recv(zfs_cmd_t *zc)
4118 {
4119         file_t *fp;
4120         dmu_recv_cookie_t drc;
4121         boolean_t force = (boolean_t)zc->zc_guid;
4122         int fd;
4123         int error = 0;
4124         int props_error = 0;
4125         nvlist_t *errors;
4126         offset_t off;
4127         nvlist_t *props = NULL; /* sent properties */
4128         nvlist_t *origprops = NULL; /* existing properties */

4129         char *origin = NULL;
4130         char *tosnap;
4131         char tofs[ZFS_MAXNAMELEN];
4132         boolean_t first_recvd_props = B_FALSE;
4133 
4134         if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
4135             strchr(zc->zc_value, '@') == NULL ||
4136             strchr(zc->zc_value, '%'))
4137                 return (SET_ERROR(EINVAL));
4138 
4139         (void) strcpy(tofs, zc->zc_value);
4140         tosnap = strchr(tofs, '@');
4141         *tosnap++ = '\0';
4142 
4143         if (zc->zc_nvlist_src != NULL &&
4144             (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
4145             zc->zc_iflags, &props)) != 0)
4146                 return (error);
4147 
4148         fd = zc->zc_cookie;


4189                          * regardless.
4190                          */
4191                         if (!first_recvd_props)
4192                                 props_reduce(props, origprops);
4193                         if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
4194                                 (void) nvlist_merge(errors, errlist, 0);
4195                         nvlist_free(errlist);
4196 
4197                         if (clear_received_props(tofs, origprops,
4198                             first_recvd_props ? NULL : props) != 0)
4199                                 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4200                 } else {
4201                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4202                 }
4203         }
4204 
4205         if (props != NULL) {
4206                 props_error = dsl_prop_set_hasrecvd(tofs);
4207 
4208                 if (props_error == 0) {

4209                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4210                             props, errors);
4211                 }
4212         }
4213 
4214         if (zc->zc_nvlist_dst_size != 0 &&
4215             (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4216             put_nvlist(zc, errors) != 0)) {
4217                 /*
4218                  * Caller made zc->zc_nvlist_dst less than the minimum expected
4219                  * size or supplied an invalid address.
4220                  */
4221                 props_error = SET_ERROR(EINVAL);
4222         }
4223 
4224         off = fp->f_offset;
4225         error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
4226             &zc->zc_action_handle);
4227 
4228         if (error == 0) {
4229                 zfsvfs_t *zfsvfs = NULL;
4230 
4231                 if (getzfsvfs(tofs, &zfsvfs) == 0) {
4232                         /* online recv */
4233                         int end_err;
4234 
4235                         error = zfs_suspend_fs(zfsvfs);
4236                         /*
4237                          * If the suspend fails, then the recv_end will
4238                          * likely also fail, and clean up after itself.
4239                          */
4240                         end_err = dmu_recv_end(&drc, zfsvfs);
4241                         if (error == 0)
4242                                 error = zfs_resume_fs(zfsvfs, tofs);
4243                         error = error ? error : end_err;
4244                         VFS_RELE(zfsvfs->z_vfs);
4245                 } else {
4246                         error = dmu_recv_end(&drc, NULL);
4247                 }





4248         }

4249 




























4250         zc->zc_cookie = off - fp->f_offset;
4251         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4252                 fp->f_offset = off;
4253 
4254 #ifdef  DEBUG
4255         if (zfs_ioc_recv_inject_err) {
4256                 zfs_ioc_recv_inject_err = B_FALSE;
4257                 error = 1;
4258         }
4259 #endif
4260         /*
4261          * On error, restore the original props.
4262          */
4263         if (error != 0 && props != NULL && !drc.drc_newfs) {
4264                 if (clear_received_props(tofs, props, NULL) != 0) {
4265                         /*
4266                          * We failed to clear the received properties.
4267                          * Since we may have left a $recvd value on the
4268                          * system, we can't clear the $hasrecvd flag.
4269                          */




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


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


4241                          * regardless.
4242                          */
4243                         if (!first_recvd_props)
4244                                 props_reduce(props, origprops);
4245                         if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
4246                                 (void) nvlist_merge(errors, errlist, 0);
4247                         nvlist_free(errlist);
4248 
4249                         if (clear_received_props(tofs, origprops,
4250                             first_recvd_props ? NULL : props) != 0)
4251                                 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4252                 } else {
4253                         zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4254                 }
4255         }
4256 
4257         if (props != NULL) {
4258                 props_error = dsl_prop_set_hasrecvd(tofs);
4259 
4260                 if (props_error == 0) {
4261                         delayprops = extract_delay_props(props);
4262                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4263                             props, errors);
4264                 }
4265         }
4266 










4267         off = fp->f_offset;
4268         error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
4269             &zc->zc_action_handle);
4270 
4271         if (error == 0) {
4272                 zfsvfs_t *zfsvfs = NULL;
4273 
4274                 if (getzfsvfs(tofs, &zfsvfs) == 0) {
4275                         /* online recv */
4276                         int end_err;
4277 
4278                         error = zfs_suspend_fs(zfsvfs);
4279                         /*
4280                          * If the suspend fails, then the recv_end will
4281                          * likely also fail, and clean up after itself.
4282                          */
4283                         end_err = dmu_recv_end(&drc, zfsvfs);
4284                         if (error == 0)
4285                                 error = zfs_resume_fs(zfsvfs, tofs);
4286                         error = error ? error : end_err;
4287                         VFS_RELE(zfsvfs->z_vfs);
4288                 } else {
4289                         error = dmu_recv_end(&drc, NULL);
4290                 }
4291 
4292                 /* Set delayed properties now, after we're done receiving. */
4293                 if (delayprops != NULL && error == 0) {
4294                         (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4295                             delayprops, errors);
4296                 }
4297         }
4298 
4299         if (delayprops != NULL) {
4300                 /*
4301                  * Merge delayed props back in with initial props, in case
4302                  * we're DEBUG and zfs_ioc_recv_inject_err is set (which means
4303                  * we have to make sure clear_received_props() includes
4304                  * the delayed properties).
4305                  *
4306                  * Since zfs_ioc_recv_inject_err is only in DEBUG kernels,
4307                  * using ASSERT() will be just like a VERIFY.
4308                  */
4309                 ASSERT(nvlist_merge(props, delayprops, 0) == 0);
4310                 nvlist_free(delayprops);
4311         }
4312 
4313         /*
4314          * Now that all props, initial and delayed, are set, report the prop
4315          * errors to the caller.
4316          */
4317         if (zc->zc_nvlist_dst_size != 0 &&
4318             (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4319             put_nvlist(zc, errors) != 0)) {
4320                 /*
4321                  * Caller made zc->zc_nvlist_dst less than the minimum expected
4322                  * size or supplied an invalid address.
4323                  */
4324                 props_error = SET_ERROR(EINVAL);
4325         }
4326 
4327         zc->zc_cookie = off - fp->f_offset;
4328         if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4329                 fp->f_offset = off;
4330 
4331 #ifdef  DEBUG
4332         if (zfs_ioc_recv_inject_err) {
4333                 zfs_ioc_recv_inject_err = B_FALSE;
4334                 error = 1;
4335         }
4336 #endif
4337         /*
4338          * On error, restore the original props.
4339          */
4340         if (error != 0 && props != NULL && !drc.drc_newfs) {
4341                 if (clear_received_props(tofs, props, NULL) != 0) {
4342                         /*
4343                          * We failed to clear the received properties.
4344                          * Since we may have left a $recvd value on the
4345                          * system, we can't clear the $hasrecvd flag.
4346                          */