~ubuntu-branches/ubuntu/quantal/zfs-fuse/quantal

« back to all changes in this revision

Viewing changes to src/lib/libzfs/libzfs_dataset.c

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey, Mike Hommey, Seth Heeren
  • Date: 2010-06-30 18:03:52 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100630180352-d3jq25ytbcl23q3y
Tags: 0.6.9-1
* New upstream release.

[ Mike Hommey ]
* debian/control:
  - Build depend on libssl-dev and libattr1-dev, now required to build.
  - Build depend on docbook-xml to avoid xsltproc I/O error loading
    docbook DTD.
  - Add suggestions for a NFS server and kpartx.
* debian/man/*, debian/copyright, debian/rules: Remove manual pages, they
  are now shipped upstream.
* debian/copyright: Change download link.
* src/SConstruct:
  - Add an optim option to the build system.
  - Add support for DESTDIR.
  - Force debug=1 to mean optim, no strip, no debug.
  - Use -ffunction-sections, -fdata-sections, and --gc-sections flags to
    reduce the binary sizes.
* src/lib/libumem/SConscript: Cleanup src/lib/libumem when cleaning up
  build directory.
* src/cmd/*/SConscript: Don't link zfs, zpool and zdb against libssl.
* src/lib/libumem/SConscript: Only build static libumem.
* src/lib/libumem/sol_compat.h:
  - Add atomic cas support for sparc.
  - Use atomic functions from libsolcompat in libumem on unsupported
    platforms.
* debian/rules:
  - Set optimization level in build system according to DEB_BUILD_OPTIONS.
  - Build with debug=1 to have unstripped binaries ; dh_strip will do the
    right thing.
  - Don't depend on the local location of the docbook XSLT stylesheets.
    Use the catalogged url in place of the full path.
  - Don't clean src/.sconsign.dblite and src/path.pyc.
  - Set all destination directories when installing with scons.
  - Install bash completion and zfsrc files.
  - Don't use scons cache when building.
* debian/prerm: Remove /var/lib/zfs/zpool.cache in prerm.
* debian/dirs: Create /etc/bash_completion.d.
* debian/watch: Fix watch file.
* debian/rules, debian/control, debian/compat: Switch to dh.
* debian/README.Debian: Update README.Debian.
* debian/zfs-fuse.man.xml: Update zfs-fuse manual page.
* debian/zfs-fuse.init: Start sharing datasets marked as such at daemon
  startup.
* debian/rules, debian/control: Use config.guess and config.sub from
  autotools-dev.

[ Seth Heeren ]
* debian/zfs-fuse.man.xml:
  Added notes on the precedence, zfsrc, commandline, initscript vs.
  /etc/default/zfs-fuse on some systems.
* debian/zfs-fuse.init, debian/zfs-fuse.default: Deprecating DAEMON_OPTS.
* debian/zfs-fuse.init:
  - Removing import -a -f.
  - Removing the now unnecessary 'sleep 2'.
  - Extended shutdown wait to allow for zfs-fuse daemon's own shutdown
    timeouts.
  - Re-ordered dubious PATH setting.
* debian/zfs-fuse.init: Move existing zpool.cache to new location if
  possible.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
/*
23
 
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 
23
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24
24
 * Use is subject to license terms.
25
25
 */
26
26
 
27
 
#include <assert.h>
28
27
#include <ctype.h>
29
28
#include <errno.h>
30
 
#include <libdevinfo.h>
31
29
#include <libintl.h>
32
30
#include <math.h>
33
31
#include <stdio.h>
39
37
#include <fcntl.h>
40
38
#include <sys/mntent.h>
41
39
#include <sys/mount.h>
42
 
#include <sys/avl.h>
43
40
#include <priv.h>
44
41
#include <pwd.h>
45
42
#include <grp.h>
48
45
#include <aclutils.h>
49
46
#include <acl_impl.h>
50
47
 
 
48
#include <sys/dnode.h>
51
49
#include <sys/spa.h>
52
50
#include <sys/zap.h>
53
51
#include <libzfs.h>
57
55
#include "libzfs_impl.h"
58
56
#include "zfs_deleg.h"
59
57
 
60
 
static int zvol_create_link_common(libzfs_handle_t *, const char *, int);
61
58
static int userquota_propname_decode(const char *propname, boolean_t zoned,
62
59
    zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
63
60
 
341
338
        return (0);
342
339
}
343
340
 
 
341
/*
 
342
 * Utility function to get the received properties of the given object.
 
343
 */
 
344
static int
 
345
get_recvd_props_ioctl(zfs_handle_t *zhp)
 
346
{
 
347
        libzfs_handle_t *hdl = zhp->zfs_hdl;
 
348
        nvlist_t *recvdprops;
 
349
        zfs_cmd_t zc = { 0 };
 
350
        int err;
 
351
 
 
352
        if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
 
353
                return (-1);
 
354
 
 
355
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
356
 
 
357
        while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
 
358
                if (errno == ENOMEM) {
 
359
                        if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
 
360
                                return (-1);
 
361
                        }
 
362
                } else {
 
363
                        zcmd_free_nvlists(&zc);
 
364
                        return (-1);
 
365
                }
 
366
        }
 
367
 
 
368
        err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
 
369
        zcmd_free_nvlists(&zc);
 
370
        if (err != 0)
 
371
                return (-1);
 
372
 
 
373
        nvlist_free(zhp->zfs_recvd_props);
 
374
        zhp->zfs_recvd_props = recvdprops;
 
375
 
 
376
        return (0);
 
377
}
 
378
 
344
379
static int
345
380
put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
346
381
{
402
437
static int
403
438
make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
404
439
{
405
 
        char *logstr;
406
 
        libzfs_handle_t *hdl = zhp->zfs_hdl;
407
 
 
408
 
        /*
409
 
         * Preserve history log string.
410
 
         * any changes performed here will be
411
 
         * logged as an internal event.
412
 
         */
413
 
        logstr = zhp->zfs_hdl->libzfs_log_str;
414
 
        zhp->zfs_hdl->libzfs_log_str = NULL;
415
 
 
416
 
top:
417
 
        if (put_stats_zhdl(zhp, zc) != 0) {
418
 
                zhp->zfs_hdl->libzfs_log_str = logstr;
 
440
        if (put_stats_zhdl(zhp, zc) != 0)
419
441
                return (-1);
420
 
        }
421
 
 
422
 
 
423
 
        if (zhp->zfs_dmustats.dds_inconsistent) {
424
 
                zfs_cmd_t zc2 = { 0 };
425
 
 
426
 
                /*
427
 
                 * If it is dds_inconsistent, then we've caught it in
428
 
                 * the middle of a 'zfs receive' or 'zfs destroy', and
429
 
                 * it is inconsistent from the ZPL's point of view, so
430
 
                 * can't be mounted.  However, it could also be that we
431
 
                 * have crashed in the middle of one of those
432
 
                 * operations, in which case we need to get rid of the
433
 
                 * inconsistent state.  We do that by either rolling
434
 
                 * back to the previous snapshot (which will fail if
435
 
                 * there is none), or destroying the filesystem.  Note
436
 
                 * that if we are still in the middle of an active
437
 
                 * 'receive' or 'destroy', then the rollback and destroy
438
 
                 * will fail with EBUSY and we will drive on as usual.
439
 
                 */
440
 
 
441
 
                (void) strlcpy(zc2.zc_name, zhp->zfs_name,
442
 
                    sizeof (zc2.zc_name));
443
 
 
444
 
                if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
445
 
                        (void) zvol_remove_link(hdl, zhp->zfs_name);
446
 
                        zc2.zc_objset_type = DMU_OST_ZVOL;
447
 
                } else {
448
 
                        zc2.zc_objset_type = DMU_OST_ZFS;
449
 
                }
450
 
 
451
 
                /*
452
 
                 * If we can successfully destroy it, pretend that it
453
 
                 * never existed.
454
 
                 */
455
 
                if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc2) == 0) {
456
 
                        zhp->zfs_hdl->libzfs_log_str = logstr;
457
 
                        errno = ENOENT;
458
 
                        return (-1);
459
 
                }
460
 
                /* If we can successfully roll it back, reset the stats */
461
 
                if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc2) == 0) {
462
 
                        if (get_stats_ioctl(zhp, zc) != 0) {
463
 
                                zhp->zfs_hdl->libzfs_log_str = logstr;
464
 
                                return (-1);
465
 
                        }
466
 
                        goto top;
467
 
                }
468
 
        }
469
442
 
470
443
        /*
471
444
         * We've managed to open the dataset and gather statistics.  Determine
487
460
        else
488
461
                abort();        /* we should never see any other types */
489
462
 
490
 
        zhp->zfs_hdl->libzfs_log_str = logstr;
491
463
        zhp->zpool_hdl = zpool_handle(zhp);
492
464
        return (0);
493
465
}
590
562
                free(zhp->zfs_mntopts);
591
563
        nvlist_free(zhp->zfs_props);
592
564
        nvlist_free(zhp->zfs_user_props);
 
565
        nvlist_free(zhp->zfs_recvd_props);
593
566
        free(zhp);
594
567
}
595
568
 
620
593
            sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
621
594
}
622
595
 
 
596
static void free_mnttab_node(mnttab_node_t *mtn) {
 
597
    free(mtn->mtn_mt.mnt_special);
 
598
    free(mtn->mtn_mt.mnt_mountp);
 
599
    free(mtn->mtn_mt.mnt_fstype);
 
600
    free(mtn->mtn_mt.mnt_mntopts);
 
601
    free(mtn);
 
602
}
 
603
 
623
604
void
624
605
libzfs_mnttab_update(libzfs_handle_t *hdl)
625
606
{
626
607
        struct mnttab entry;
 
608
        avl_index_t where;
627
609
 
628
610
        rewind(hdl->libzfs_mnttab);
629
611
        while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
636
618
                mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
637
619
                mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
638
620
                mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
639
 
                avl_add(&hdl->libzfs_mnttab_cache, mtn);
 
621
                if (avl_find(&hdl->libzfs_mnttab_cache, mtn, &where) != NULL) {
 
622
                    /* If mounting a zfs-fuse dir with the bind option, then
 
623
                     * this mount point appears twice in /proc/mounts as if
 
624
                     * it were mounted twice by zfs-fuse with exactly the
 
625
                     * same options but on 2 different mount points.
 
626
                     * So if we find another entry here, we keep only the 1st
 
627
                     * one */
 
628
                    free_mnttab_node(mtn);
 
629
                } else
 
630
                    avl_add(&hdl->libzfs_mnttab_cache, mtn);
640
631
        }
641
632
}
642
633
 
647
638
        mnttab_node_t *mtn;
648
639
 
649
640
        while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) {
650
 
                free(mtn->mtn_mt.mnt_special);
651
 
                free(mtn->mtn_mt.mnt_mountp);
652
 
                free(mtn->mtn_mt.mnt_fstype);
653
 
                free(mtn->mtn_mt.mnt_mntopts);
654
 
                free(mtn);
 
641
            free_mnttab_node(mtn);
655
642
        }
656
643
        avl_destroy(&hdl->libzfs_mnttab_cache);
657
644
}
883
870
                                goto error;
884
871
                        }
885
872
 
 
873
                        /*
 
874
                         * Encode the prop name as
 
875
                         * userquota@<hex-rid>-domain, to make it easy
 
876
                         * for the kernel to decode.
 
877
                         */
886
878
                        (void) snprintf(newpropname, sizeof (newpropname),
887
 
                            "%s%s", zfs_userquota_prop_prefixes[uqtype],
888
 
                            domain);
 
879
                            "%s%llx-%s", zfs_userquota_prop_prefixes[uqtype],
 
880
                            (longlong_t)rid, domain);
889
881
                        valary[0] = uqtype;
890
882
                        valary[1] = rid;
891
883
                        valary[2] = intval;
961
953
                        }
962
954
                        break;
963
955
 
964
 
                case ZFS_PROP_SHAREISCSI:
965
 
                        if (strcmp(strval, "off") != 0 &&
966
 
                            strcmp(strval, "on") != 0 &&
967
 
                            strcmp(strval, "type=disk") != 0) {
968
 
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
969
 
                                    "'%s' must be 'on', 'off', or 'type=disk'"),
970
 
                                    propname);
971
 
                                (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
972
 
                                goto error;
973
 
                        }
 
956
                case ZFS_PROP_MLSLABEL:
 
957
                {
 
958
                        /*
 
959
                         * Verify the mlslabel string and convert to
 
960
                         * internal hex label string.
 
961
                         */
 
962
 
 
963
#if 0
 
964
                    /* zfs-fuse : we are going to ignore all this for now
 
965
                     * 1 : they are supposed to be enforced by the kernel
 
966
                     * 2 : they use m_label_* api which is external
 
967
                     * so just forget it for now */
 
968
                        m_label_t *new_sl;
 
969
                        char *hex = NULL;       /* internal label string */
 
970
 
 
971
                        /* Default value is already OK. */
 
972
                        if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
 
973
                                break;
 
974
 
 
975
                        /* Verify the label can be converted to binary form */
 
976
                        if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
 
977
                            (str_to_label(strval, &new_sl, MAC_LABEL,
 
978
                            L_NO_CORRECTION, NULL) == -1)) {
 
979
                                goto badlabel;
 
980
                        }
 
981
 
 
982
                        /* Now translate to hex internal label string */
 
983
                        if (label_to_str(new_sl, &hex, M_INTERNAL,
 
984
                            DEF_NAMES) != 0) {
 
985
                                if (hex)
 
986
                                        free(hex);
 
987
                                goto badlabel;
 
988
                        }
 
989
                        m_label_free(new_sl);
 
990
 
 
991
                        /* If string is already in internal form, we're done. */
 
992
                        if (strcmp(strval, hex) == 0) {
 
993
                                free(hex);
 
994
                                break;
 
995
                        }
 
996
 
 
997
                        /* Replace the label string with the internal form. */
 
998
                        nvlist_remove(ret, zfs_prop_to_name(prop),
 
999
                            DATA_TYPE_STRING);
 
1000
                        verify(nvlist_add_string(ret, zfs_prop_to_name(prop),
 
1001
                            hex) == 0);
 
1002
                        free(hex);
974
1003
 
975
1004
                        break;
976
1005
 
 
1006
#endif
 
1007
badlabel:
 
1008
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
1009
                            "invalid mlslabel '%s'"), strval);
 
1010
                        (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 
1011
                        // m_label_free(new_sl);        /* OK if null */
 
1012
                        goto error;
 
1013
 
 
1014
                }
 
1015
 
977
1016
                case ZFS_PROP_MOUNTPOINT:
978
1017
                {
979
1018
                        namecheck_err_t why;
1068
1107
                                else
1069
1108
                                        proto = PROTO_NFS;
1070
1109
 
 
1110
#if 0
 
1111
                                /* zfs-fuse : no options checking
 
1112
                                 * to check that I would have to call exportfs
 
1113
                                 * which will be done later anyway */
1071
1114
                                /*
1072
1115
                                 * Must be an valid sharing protocol
1073
1116
                                 * option string so init the libshare
1111
1154
                                        goto error;
1112
1155
                                }
1113
1156
                                zfs_uninit_libshare(hdl);
 
1157
#endif
1114
1158
                        }
1115
1159
 
1116
1160
                        break;
1168
1212
                                        goto error;
1169
1213
                                }
1170
1214
                                break;
1171
 
                        default:
1172
 
                                break;
1173
1215
                        }
1174
1216
                }
1175
1217
        }
1229
1271
        return (NULL);
1230
1272
}
1231
1273
 
 
1274
void
 
1275
zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
 
1276
    char *errbuf)
 
1277
{
 
1278
        switch (err) {
 
1279
 
 
1280
        case ENOSPC:
 
1281
                /*
 
1282
                 * For quotas and reservations, ENOSPC indicates
 
1283
                 * something different; setting a quota or reservation
 
1284
                 * doesn't use any disk space.
 
1285
                 */
 
1286
                switch (prop) {
 
1287
                case ZFS_PROP_QUOTA:
 
1288
                case ZFS_PROP_REFQUOTA:
 
1289
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
1290
                            "size is less than current used or "
 
1291
                            "reserved space"));
 
1292
                        (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
 
1293
                        break;
 
1294
 
 
1295
                case ZFS_PROP_RESERVATION:
 
1296
                case ZFS_PROP_REFRESERVATION:
 
1297
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
1298
                            "size is greater than available space"));
 
1299
                        (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
 
1300
                        break;
 
1301
 
 
1302
                default:
 
1303
                        (void) zfs_standard_error(hdl, err, errbuf);
 
1304
                        break;
 
1305
                }
 
1306
                break;
 
1307
 
 
1308
        case EBUSY:
 
1309
                (void) zfs_standard_error(hdl, EBUSY, errbuf);
 
1310
                break;
 
1311
 
 
1312
        case EROFS:
 
1313
                (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
 
1314
                break;
 
1315
 
 
1316
        case ENOTSUP:
 
1317
                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
1318
                    "pool and or dataset must be upgraded to set this "
 
1319
                    "property or value"));
 
1320
                (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
 
1321
                break;
 
1322
 
 
1323
        case ERANGE:
 
1324
                if (prop == ZFS_PROP_COMPRESSION) {
 
1325
                        (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
1326
                            "property setting is not allowed on "
 
1327
                            "bootable datasets"));
 
1328
                        (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
 
1329
                } else {
 
1330
                        (void) zfs_standard_error(hdl, err, errbuf);
 
1331
                }
 
1332
                break;
 
1333
 
 
1334
        case EINVAL:
 
1335
                if (prop == ZPROP_INVAL) {
 
1336
                        (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 
1337
                } else {
 
1338
                        (void) zfs_standard_error(hdl, err, errbuf);
 
1339
                }
 
1340
                break;
 
1341
 
 
1342
        case EOVERFLOW:
 
1343
                /*
 
1344
                 * This platform can't address a volume this big.
 
1345
                 */
 
1346
#ifdef _ILP32
 
1347
                if (prop == ZFS_PROP_VOLSIZE) {
 
1348
                        (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
 
1349
                        break;
 
1350
                }
 
1351
#endif
 
1352
                /* FALLTHROUGH */
 
1353
        default:
 
1354
                (void) zfs_standard_error(hdl, err, errbuf);
 
1355
        }
 
1356
}
 
1357
 
1232
1358
/*
1233
1359
 * Given a property name and value, set the property for the given dataset.
1234
1360
 */
1297
1423
        ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1298
1424
 
1299
1425
        if (ret != 0) {
1300
 
                switch (errno) {
1301
 
 
1302
 
                case ENOSPC:
1303
 
                        /*
1304
 
                         * For quotas and reservations, ENOSPC indicates
1305
 
                         * something different; setting a quota or reservation
1306
 
                         * doesn't use any disk space.
1307
 
                         */
1308
 
                        switch (prop) {
1309
 
                        case ZFS_PROP_QUOTA:
1310
 
                        case ZFS_PROP_REFQUOTA:
1311
 
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1312
 
                                    "size is less than current used or "
1313
 
                                    "reserved space"));
1314
 
                                (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1315
 
                                break;
1316
 
 
1317
 
                        case ZFS_PROP_RESERVATION:
1318
 
                        case ZFS_PROP_REFRESERVATION:
1319
 
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1320
 
                                    "size is greater than available space"));
1321
 
                                (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1322
 
                                break;
1323
 
 
1324
 
                        default:
1325
 
                                (void) zfs_standard_error(hdl, errno, errbuf);
1326
 
                                break;
1327
 
                        }
1328
 
                        break;
1329
 
 
1330
 
                case EBUSY:
1331
 
                        if (prop == ZFS_PROP_VOLBLOCKSIZE)
1332
 
                                (void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
1333
 
                        else
1334
 
                                (void) zfs_standard_error(hdl, EBUSY, errbuf);
1335
 
                        break;
1336
 
 
1337
 
                case EROFS:
1338
 
                        (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1339
 
                        break;
1340
 
 
1341
 
                case ENOTSUP:
1342
 
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1343
 
                            "pool and or dataset must be upgraded to set this "
1344
 
                            "property or value"));
1345
 
                        (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1346
 
                        break;
1347
 
 
1348
 
                case ERANGE:
1349
 
                        if (prop == ZFS_PROP_COMPRESSION) {
1350
 
                                (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1351
 
                                    "property setting is not allowed on "
1352
 
                                    "bootable datasets"));
1353
 
                                (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1354
 
                        } else {
1355
 
                                (void) zfs_standard_error(hdl, errno, errbuf);
1356
 
                        }
1357
 
                        break;
1358
 
 
1359
 
                case EOVERFLOW:
1360
 
                        /*
1361
 
                         * This platform can't address a volume this big.
1362
 
                         */
1363
 
#ifdef _ILP32
1364
 
                        if (prop == ZFS_PROP_VOLSIZE) {
1365
 
                                (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1366
 
                                break;
1367
 
                        }
1368
 
#endif
1369
 
                        /* FALLTHROUGH */
1370
 
                default:
1371
 
                        (void) zfs_standard_error(hdl, errno, errbuf);
1372
 
                }
 
1426
                zfs_setprop_error(hdl, prop, errno, errbuf);
1373
1427
        } else {
1374
1428
                if (do_prefix)
1375
1429
                        ret = changelist_postfix(cl);
1391
1445
}
1392
1446
 
1393
1447
/*
1394
 
 * Given a property, inherit the value from the parent dataset.
 
1448
 * Given a property, inherit the value from the parent dataset, or if received
 
1449
 * is TRUE, revert to the received value, if any.
1395
1450
 */
1396
1451
int
1397
 
zfs_prop_inherit(zfs_handle_t *zhp, const char *propname)
 
1452
zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
1398
1453
{
1399
1454
        zfs_cmd_t zc = { 0 };
1400
1455
        int ret;
1406
1461
        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1407
1462
            "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1408
1463
 
 
1464
        zc.zc_cookie = received;
1409
1465
        if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1410
1466
                /*
1411
1467
                 * For user properties, the amount of work we have to do is very
1432
1488
        if (zfs_prop_readonly(prop))
1433
1489
                return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1434
1490
 
1435
 
        if (!zfs_prop_inheritable(prop))
 
1491
        if (!zfs_prop_inheritable(prop) && !received)
1436
1492
                return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1437
1493
 
1438
1494
        /*
1537
1593
        return (value);
1538
1594
}
1539
1595
 
 
1596
static boolean_t
 
1597
zfs_is_recvd_props_mode(zfs_handle_t *zhp)
 
1598
{
 
1599
        return (zhp->zfs_props == zhp->zfs_recvd_props);
 
1600
}
 
1601
 
 
1602
static void
 
1603
zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
 
1604
{
 
1605
        *cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
 
1606
        zhp->zfs_props = zhp->zfs_recvd_props;
 
1607
}
 
1608
 
 
1609
static void
 
1610
zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
 
1611
{
 
1612
        zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
 
1613
        *cookie = 0;
 
1614
}
 
1615
 
1540
1616
/*
1541
1617
 * Internal function for getting a numeric property.  Both zfs_prop_get() and
1542
1618
 * zfs_prop_get_int() are built using this interface.
1555
1631
        struct mnttab mnt;
1556
1632
        char *mntopt_on = NULL;
1557
1633
        char *mntopt_off = NULL;
 
1634
        boolean_t received = zfs_is_recvd_props_mode(zhp);
1558
1635
 
1559
1636
        *source = NULL;
1560
1637
 
1630
1707
        case ZFS_PROP_NBMAND:
1631
1708
                *val = getprop_uint64(zhp, prop, source);
1632
1709
 
 
1710
                if (received)
 
1711
                        break;
 
1712
 
1633
1713
                if (hasmntopt(&mnt, mntopt_on) && !*val) {
1634
1714
                        *val = B_TRUE;
1635
1715
                        if (src)
1642
1722
                break;
1643
1723
 
1644
1724
        case ZFS_PROP_CANMOUNT:
1645
 
                *val = getprop_uint64(zhp, prop, source);
1646
 
                if (*val != ZFS_CANMOUNT_ON)
1647
 
                        *source = zhp->zfs_name;
1648
 
                else
1649
 
                        *source = "";   /* default */
1650
 
                break;
1651
 
 
 
1725
        case ZFS_PROP_VOLSIZE:
1652
1726
        case ZFS_PROP_QUOTA:
1653
1727
        case ZFS_PROP_REFQUOTA:
1654
1728
        case ZFS_PROP_RESERVATION:
1655
1729
        case ZFS_PROP_REFRESERVATION:
1656
1730
                *val = getprop_uint64(zhp, prop, source);
1657
 
                if (*val == 0)
1658
 
                        *source = "";   /* default */
1659
 
                else
 
1731
 
 
1732
                if (*source == NULL) {
 
1733
                        /* not default, must be local */
1660
1734
                        *source = zhp->zfs_name;
 
1735
                }
1661
1736
                break;
1662
1737
 
1663
1738
        case ZFS_PROP_MOUNTED:
1678
1753
                (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1679
1754
                if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
1680
1755
                        zcmd_free_nvlists(&zc);
1681
 
                        zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1682
 
                            "unable to get %s property"),
1683
 
                            zfs_prop_to_name(prop));
1684
 
                        return (zfs_error(zhp->zfs_hdl, EZFS_BADVERSION,
1685
 
                            dgettext(TEXT_DOMAIN, "internal error")));
 
1756
                        return (-1);
1686
1757
                }
1687
1758
                if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
1688
1759
                    nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
1689
1760
                    val) != 0) {
1690
1761
                        zcmd_free_nvlists(&zc);
1691
 
                        zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1692
 
                            "unable to get %s property"),
1693
 
                            zfs_prop_to_name(prop));
1694
 
                        return (zfs_error(zhp->zfs_hdl, EZFS_NOMEM,
1695
 
                            dgettext(TEXT_DOMAIN, "internal error")));
 
1762
                        return (-1);
1696
1763
                }
1697
1764
                if (zplprops)
1698
1765
                        nvlist_free(zplprops);
1707
1774
                        /*
1708
1775
                         * If we tried to use a default value for a
1709
1776
                         * readonly property, it means that it was not
1710
 
                         * present; return an error.
 
1777
                         * present.
1711
1778
                         */
1712
1779
                        if (zfs_prop_readonly(prop) &&
1713
 
                            *source && (*source)[0] == '\0') {
1714
 
                                return (-1);
 
1780
                            *source != NULL && (*source)[0] == '\0') {
 
1781
                                *source = NULL;
1715
1782
                        }
1716
1783
                        break;
1717
1784
 
1741
1808
                *srctype = ZPROP_SRC_NONE;
1742
1809
        } else if (source[0] == '\0') {
1743
1810
                *srctype = ZPROP_SRC_DEFAULT;
 
1811
        } else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
 
1812
                *srctype = ZPROP_SRC_RECEIVED;
1744
1813
        } else {
1745
1814
                if (strcmp(source, zhp->zfs_name) == 0) {
1746
1815
                        *srctype = ZPROP_SRC_LOCAL;
1752
1821
 
1753
1822
}
1754
1823
 
 
1824
int
 
1825
zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
 
1826
    size_t proplen, boolean_t literal)
 
1827
{
 
1828
        zfs_prop_t prop;
 
1829
        int err = 0;
 
1830
 
 
1831
        if (zhp->zfs_recvd_props == NULL)
 
1832
                if (get_recvd_props_ioctl(zhp) != 0)
 
1833
                        return (-1);
 
1834
 
 
1835
        prop = zfs_name_to_prop(propname);
 
1836
 
 
1837
        if (prop != ZPROP_INVAL) {
 
1838
                uint64_t cookie;
 
1839
                if (!nvlist_exists(zhp->zfs_recvd_props, propname))
 
1840
                        return (-1);
 
1841
                zfs_set_recvd_props_mode(zhp, &cookie);
 
1842
                err = zfs_prop_get(zhp, prop, propbuf, proplen,
 
1843
                    NULL, NULL, 0, literal);
 
1844
                zfs_unset_recvd_props_mode(zhp, &cookie);
 
1845
        } else if (zfs_prop_userquota(propname)) {
 
1846
                return (-1);
 
1847
        } else {
 
1848
                nvlist_t *propval;
 
1849
                char *recvdval;
 
1850
                if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
 
1851
                    propname, &propval) != 0)
 
1852
                        return (-1);
 
1853
                verify(nvlist_lookup_string(propval, ZPROP_VALUE,
 
1854
                    &recvdval) == 0);
 
1855
                (void) strlcpy(propbuf, recvdval, proplen);
 
1856
        }
 
1857
 
 
1858
        return (err == 0 ? 0 : -1);
 
1859
}
 
1860
 
1755
1861
/*
1756
1862
 * Retrieve a property from the given object.  If 'literal' is specified, then
1757
1863
 * numbers are left as exact values.  Otherwise, numbers are converted to a
1767
1873
        uint64_t val;
1768
1874
        char *str;
1769
1875
        const char *strval;
 
1876
        boolean_t received = zfs_is_recvd_props_mode(zhp);
1770
1877
 
1771
1878
        /*
1772
1879
         * Check to see if this property applies to our object
1774
1881
        if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1775
1882
                return (-1);
1776
1883
 
 
1884
        if (received && zfs_prop_readonly(prop))
 
1885
                return (-1);
 
1886
 
1777
1887
        if (src)
1778
1888
                *src = ZPROP_SRC_NONE;
1779
1889
 
1813
1923
                if (str[0] == '/') {
1814
1924
                        char buf[MAXPATHLEN];
1815
1925
                        char *root = buf;
1816
 
                        const char *relpath = zhp->zfs_name + strlen(source);
 
1926
                        const char *relpath;
1817
1927
 
1818
 
                        if (relpath[0] == '/')
1819
 
                                relpath++;
 
1928
                        /*
 
1929
                         * If we inherit the mountpoint, even from a dataset
 
1930
                         * with a received value, the source will be the path of
 
1931
                         * the dataset we inherit from. If source is
 
1932
                         * ZPROP_SOURCE_VAL_RECVD, the received value is not
 
1933
                         * inherited.
 
1934
                         */
 
1935
                        if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
 
1936
                                relpath = "";
 
1937
                        } else {
 
1938
                                relpath = zhp->zfs_name + strlen(source);
 
1939
                                if (relpath[0] == '/')
 
1940
                                        relpath++;
 
1941
                        }
1820
1942
 
1821
1943
                        if ((zpool_get_prop(zhp->zpool_hdl,
1822
1944
                            ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) ||
1895
2017
        case ZFS_PROP_COMPRESSRATIO:
1896
2018
                if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1897
2019
                        return (-1);
1898
 
                (void) snprintf(propbuf, proplen, "%lld.%02lldx", (longlong_t)
1899
 
                    val / 100, (longlong_t)val % 100);
 
2020
                (void) snprintf(propbuf, proplen, "%llu.%02llux",
 
2021
                    (u_longlong_t)(val / 100),
 
2022
                    (u_longlong_t)(val % 100));
1900
2023
                break;
1901
2024
 
1902
2025
        case ZFS_PROP_TYPE:
1941
2064
                (void) strlcpy(propbuf, zhp->zfs_name, proplen);
1942
2065
                break;
1943
2066
 
 
2067
        case ZFS_PROP_MLSLABEL:
 
2068
                {
 
2069
#if 0
 
2070
                    /* zfs-fuse : disabled */
 
2071
                        m_label_t *new_sl = NULL;
 
2072
                        char *ascii = NULL;     /* human readable label */
 
2073
 
 
2074
                        (void) strlcpy(propbuf,
 
2075
                            getprop_string(zhp, prop, &source), proplen);
 
2076
 
 
2077
                        if (literal || (strcasecmp(propbuf,
 
2078
                            ZFS_MLSLABEL_DEFAULT) == 0))
 
2079
                                break;
 
2080
 
 
2081
                        /*
 
2082
                         * Try to translate the internal hex string to
 
2083
                         * human-readable output.  If there are any
 
2084
                         * problems just use the hex string.
 
2085
                         */
 
2086
 
 
2087
                        if (str_to_label(propbuf, &new_sl, MAC_LABEL,
 
2088
                            L_NO_CORRECTION, NULL) == -1) {
 
2089
                                m_label_free(new_sl);
 
2090
                                break;
 
2091
                        }
 
2092
 
 
2093
                        if (label_to_str(new_sl, &ascii, M_LABEL,
 
2094
                            DEF_NAMES) != 0) {
 
2095
                                if (ascii)
 
2096
                                        free(ascii);
 
2097
                                m_label_free(new_sl);
 
2098
                                break;
 
2099
                        }
 
2100
                        m_label_free(new_sl);
 
2101
 
 
2102
                        (void) strlcpy(propbuf, ascii, proplen);
 
2103
                        free(ascii);
 
2104
#endif
 
2105
                }
 
2106
                break;
 
2107
 
1944
2108
        default:
1945
2109
                switch (zfs_prop_get_type(prop)) {
1946
2110
                case PROP_TYPE_NUMBER:
2127
2291
#endif
2128
2292
        } else if (strncmp(cp, "S-1-", 4) == 0) {
2129
2293
                /* It's a numeric SID (eg "S-1-234-567-89") */
2130
 
                (void) strcpy(domain, cp);
 
2294
                (void) strlcpy(domain, cp, domainlen);
2131
2295
                cp = strrchr(domain, '-');
2132
2296
                *cp = '\0';
2133
2297
                cp++;
2170
2334
                        if (idmap_id_to_numeric_domain_rid(id, isuser,
2171
2335
                            &mapdomain, &rid) != 0)
2172
2336
                                return (ENOENT);
2173
 
                        (void) strcpy(domain, mapdomain);
 
2337
                        (void) strlcpy(domain, mapdomain, domainlen);
2174
2338
                        *ridp = rid;
2175
2339
#endif
2176
2340
                return (ENOENT);
2384
2548
}
2385
2549
 
2386
2550
/*
 
2551
 * Is one dataset name a child dataset of another?
 
2552
 *
 
2553
 * Needs to handle these cases:
 
2554
 * Dataset 1    "a/foo"         "a/foo"         "a/foo"         "a/foo"
 
2555
 * Dataset 2    "a/fo"          "a/foobar"      "a/bar/baz"     "a/foo/bar"
 
2556
 * Descendant?  No.             No.             No.             Yes.
 
2557
 */
 
2558
static boolean_t
 
2559
is_descendant(const char *ds1, const char *ds2)
 
2560
{
 
2561
        size_t d1len = strlen(ds1);
 
2562
 
 
2563
        /* ds2 can't be a descendant if it's smaller */
 
2564
        if (strlen(ds2) < d1len)
 
2565
                return (B_FALSE);
 
2566
 
 
2567
        /* otherwise, compare strings and verify that there's a '/' char */
 
2568
        return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
 
2569
}
 
2570
 
 
2571
/*
2387
2572
 * Given a complete name, return just the portion that refers to the parent.
2388
2573
 * Can return NULL if this is a pool.
2389
2574
 */
2418
2603
        char *slash;
2419
2604
        zfs_handle_t *zhp;
2420
2605
        char errbuf[1024];
 
2606
        uint64_t is_zoned;
2421
2607
 
2422
2608
        (void) snprintf(errbuf, sizeof (errbuf),
2423
2609
            dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
2460
2646
                        return (zfs_standard_error(hdl, errno, errbuf));
2461
2647
        }
2462
2648
 
2463
 
        *zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
 
2649
        is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
 
2650
        if (zoned != NULL)
 
2651
                *zoned = is_zoned;
 
2652
 
2464
2653
        /* we are in a non-global zone, but parent is in the global zone */
2465
 
        if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) {
 
2654
        if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
2466
2655
                (void) zfs_standard_error(hdl, EPERM, errbuf);
2467
2656
                zfs_close(zhp);
2468
2657
                return (-1);
2594
2783
zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
2595
2784
{
2596
2785
        int prefix;
2597
 
        uint64_t zoned;
2598
2786
        char *path_copy;
2599
2787
        int rc;
2600
2788
 
2601
 
        if (check_parents(hdl, path, &zoned, B_TRUE, &prefix) != 0)
 
2789
        if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
2602
2790
                return (-1);
2603
2791
 
2604
2792
        if ((path_copy = strdup(path)) != NULL) {
2712
2900
        /* create the dataset */
2713
2901
        ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc);
2714
2902
 
2715
 
        if (ret == 0 && type == ZFS_TYPE_VOLUME) {
2716
 
                ret = zvol_create_link(hdl, path);
2717
 
                if (ret) {
2718
 
                        (void) zfs_standard_error(hdl, errno,
2719
 
                            dgettext(TEXT_DOMAIN,
2720
 
                            "Volume successfully created, but device links "
2721
 
                            "were not created"));
2722
 
                        zcmd_free_nvlists(&zc);
2723
 
                        return (-1);
2724
 
                }
2725
 
        }
2726
 
 
2727
2903
        zcmd_free_nvlists(&zc);
2728
2904
 
2729
2905
        /* check for failure */
2779
2955
 * isn't mounted, and that there are no active dependents.
2780
2956
 */
2781
2957
int
2782
 
zfs_destroy(zfs_handle_t *zhp)
 
2958
zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
2783
2959
{
2784
2960
        zfs_cmd_t zc = { 0 };
2785
2961
 
2786
2962
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2787
2963
 
2788
2964
        if (ZFS_IS_VOLUME(zhp)) {
2789
 
                /*
2790
 
                 * If user doesn't have permissions to unshare volume, then
2791
 
                 * abort the request.  This would only happen for a
2792
 
                 * non-privileged user.
2793
 
                 */
2794
 
                if (zfs_unshare_iscsi(zhp) != 0) {
2795
 
                        return (-1);
2796
 
                }
2797
 
 
2798
 
                if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
2799
 
                        return (-1);
2800
 
 
2801
2965
                zc.zc_objset_type = DMU_OST_ZVOL;
2802
2966
        } else {
2803
2967
                zc.zc_objset_type = DMU_OST_ZFS;
2804
2968
        }
2805
2969
 
 
2970
        zc.zc_defer_destroy = defer;
 
2971
        sync();
2806
2972
        if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0) {
2807
2973
                return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
2808
2974
                    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
2821
2987
};
2822
2988
 
2823
2989
static int
2824
 
zfs_remove_link_cb(zfs_handle_t *zhp, void *arg)
 
2990
zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
2825
2991
{
2826
2992
        struct destroydata *dd = arg;
2827
2993
        zfs_handle_t *szhp;
2828
2994
        char name[ZFS_MAXNAMELEN];
2829
2995
        boolean_t closezhp = dd->closezhp;
2830
 
        int rv;
 
2996
        int rv = 0;
2831
2997
 
2832
2998
        (void) strlcpy(name, zhp->zfs_name, sizeof (name));
2833
2999
        (void) strlcat(name, "@", sizeof (name));
2839
3005
                zfs_close(szhp);
2840
3006
        }
2841
3007
 
2842
 
        if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2843
 
                (void) zvol_remove_link(zhp->zfs_hdl, name);
2844
 
                /*
2845
 
                 * NB: this is simply a best-effort.  We don't want to
2846
 
                 * return an error, because then we wouldn't visit all
2847
 
                 * the volumes.
2848
 
                 */
2849
 
        }
2850
 
 
2851
3008
        dd->closezhp = B_TRUE;
2852
 
        rv = zfs_iter_filesystems(zhp, zfs_remove_link_cb, arg);
 
3009
        if (!dd->gotone)
 
3010
                rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, arg);
2853
3011
        if (closezhp)
2854
3012
                zfs_close(zhp);
2855
3013
        return (rv);
2859
3017
 * Destroys all snapshots with the given name in zhp & descendants.
2860
3018
 */
2861
3019
int
2862
 
zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname)
 
3020
zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
2863
3021
{
2864
3022
        zfs_cmd_t zc = { 0 };
2865
3023
        int ret;
2866
3024
        struct destroydata dd = { 0 };
2867
3025
 
2868
3026
        dd.snapname = snapname;
2869
 
        (void) zfs_remove_link_cb(zhp, &dd);
 
3027
        (void) zfs_check_snap_cb(zhp, &dd);
2870
3028
 
2871
3029
        if (!dd.gotone) {
2872
3030
                return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
2876
3034
 
2877
3035
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2878
3036
        (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
 
3037
        zc.zc_defer_destroy = defer;
2879
3038
 
2880
3039
        ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS, &zc);
2881
3040
        if (ret != 0) {
2983
3142
                        return (zfs_standard_error(zhp->zfs_hdl, errno,
2984
3143
                            errbuf));
2985
3144
                }
2986
 
        } else if (ZFS_IS_VOLUME(zhp)) {
2987
 
                ret = zvol_create_link(zhp->zfs_hdl, target);
2988
3145
        }
2989
3146
 
2990
3147
        return (ret);
2991
3148
}
2992
3149
 
2993
 
typedef struct promote_data {
2994
 
        char cb_mountpoint[MAXPATHLEN];
2995
 
        const char *cb_target;
2996
 
        const char *cb_errbuf;
2997
 
        uint64_t cb_pivot_txg;
2998
 
} promote_data_t;
2999
 
 
3000
 
static int
3001
 
promote_snap_cb(zfs_handle_t *zhp, void *data)
3002
 
{
3003
 
        promote_data_t *pd = data;
3004
 
        zfs_handle_t *szhp;
3005
 
        char snapname[MAXPATHLEN];
3006
 
        int rv = 0;
3007
 
 
3008
 
        /* We don't care about snapshots after the pivot point */
3009
 
        if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg) {
3010
 
                zfs_close(zhp);
3011
 
                return (0);
3012
 
        }
3013
 
 
3014
 
        /* Remove the device link if it's a zvol. */
3015
 
        if (ZFS_IS_VOLUME(zhp))
3016
 
                (void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
3017
 
 
3018
 
        /* Check for conflicting names */
3019
 
        (void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
3020
 
        (void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
3021
 
        szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
3022
 
        if (szhp != NULL) {
3023
 
                zfs_close(szhp);
3024
 
                zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3025
 
                    "snapshot name '%s' from origin \n"
3026
 
                    "conflicts with '%s' from target"),
3027
 
                    zhp->zfs_name, snapname);
3028
 
                rv = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf);
3029
 
        }
3030
 
        zfs_close(zhp);
3031
 
        return (rv);
3032
 
}
3033
 
 
3034
 
static int
3035
 
promote_snap_done_cb(zfs_handle_t *zhp, void *data)
3036
 
{
3037
 
        promote_data_t *pd = data;
3038
 
 
3039
 
        /* We don't care about snapshots after the pivot point */
3040
 
        if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) <= pd->cb_pivot_txg) {
3041
 
                /* Create the device link if it's a zvol. */
3042
 
                if (ZFS_IS_VOLUME(zhp))
3043
 
                        (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
3044
 
        }
3045
 
 
3046
 
        zfs_close(zhp);
3047
 
        return (0);
3048
 
}
3049
 
 
3050
3150
/*
3051
3151
 * Promotes the given clone fs to be the clone parent.
3052
3152
 */
3056
3156
        libzfs_handle_t *hdl = zhp->zfs_hdl;
3057
3157
        zfs_cmd_t zc = { 0 };
3058
3158
        char parent[MAXPATHLEN];
3059
 
        char *cp;
3060
3159
        int ret;
3061
 
        zfs_handle_t *pzhp;
3062
 
        promote_data_t pd;
3063
3160
        char errbuf[1024];
3064
3161
 
3065
3162
        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3077
3174
                    "not a cloned filesystem"));
3078
3175
                return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3079
3176
        }
3080
 
        cp = strchr(parent, '@');
3081
 
        *cp = '\0';
3082
 
 
3083
 
        /* Walk the snapshots we will be moving */
3084
 
        pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
3085
 
        if (pzhp == NULL)
3086
 
                return (-1);
3087
 
        pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
3088
 
        zfs_close(pzhp);
3089
 
        pd.cb_target = zhp->zfs_name;
3090
 
        pd.cb_errbuf = errbuf;
3091
 
        pzhp = zfs_open(hdl, parent, ZFS_TYPE_DATASET);
3092
 
        if (pzhp == NULL)
3093
 
                return (-1);
3094
 
        (void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
3095
 
            sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
3096
 
        ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
3097
 
        if (ret != 0) {
3098
 
                zfs_close(pzhp);
3099
 
                return (-1);
3100
 
        }
3101
 
 
3102
 
        /* issue the ioctl */
 
3177
 
3103
3178
        (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin,
3104
3179
            sizeof (zc.zc_value));
3105
3180
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3108
3183
        if (ret != 0) {
3109
3184
                int save_errno = errno;
3110
3185
 
3111
 
                (void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
3112
 
                zfs_close(pzhp);
3113
 
 
3114
3186
                switch (save_errno) {
3115
3187
                case EEXIST:
3116
 
                        /*
3117
 
                         * There is a conflicting snapshot name.  We
3118
 
                         * should have caught this above, but they could
3119
 
                         * have renamed something in the mean time.
3120
 
                         */
 
3188
                        /* There is a conflicting snapshot name. */
3121
3189
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3122
 
                            "conflicting snapshot name from parent '%s'"),
3123
 
                            parent);
 
3190
                            "conflicting snapshot '%s' from parent '%s'"),
 
3191
                            zc.zc_string, parent);
3124
3192
                        return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3125
3193
 
3126
3194
                default:
3127
3195
                        return (zfs_standard_error(hdl, save_errno, errbuf));
3128
3196
                }
3129
 
        } else {
3130
 
                (void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
3131
 
        }
3132
 
 
3133
 
        zfs_close(pzhp);
3134
 
        return (ret);
3135
 
}
3136
 
 
3137
 
struct createdata {
3138
 
        const char *cd_snapname;
3139
 
        int cd_ifexists;
3140
 
};
3141
 
 
3142
 
static int
3143
 
zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
3144
 
{
3145
 
        struct createdata *cd = arg;
3146
 
        int ret;
3147
 
 
3148
 
        if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3149
 
                char name[MAXPATHLEN];
3150
 
 
3151
 
                (void) strlcpy(name, zhp->zfs_name, sizeof (name));
3152
 
                (void) strlcat(name, "@", sizeof (name));
3153
 
                (void) strlcat(name, cd->cd_snapname, sizeof (name));
3154
 
                (void) zvol_create_link_common(zhp->zfs_hdl, name,
3155
 
                    cd->cd_ifexists);
3156
 
                /*
3157
 
                 * NB: this is simply a best-effort.  We don't want to
3158
 
                 * return an error, because then we wouldn't visit all
3159
 
                 * the volumes.
3160
 
                 */
3161
 
        }
3162
 
 
3163
 
        ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, cd);
3164
 
 
3165
 
        zfs_close(zhp);
3166
 
 
 
3197
        }
3167
3198
        return (ret);
3168
3199
}
3169
3200
 
3227
3258
         * if it was recursive, the one that actually failed will be in
3228
3259
         * zc.zc_name.
3229
3260
         */
3230
 
        if (ret != 0)
 
3261
        if (ret != 0) {
3231
3262
                (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3232
3263
                    "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
3233
 
 
3234
 
        if (ret == 0 && recursive) {
3235
 
                struct createdata cd;
3236
 
 
3237
 
                cd.cd_snapname = delim + 1;
3238
 
                cd.cd_ifexists = B_FALSE;
3239
 
                (void) zfs_iter_filesystems(zhp, zfs_create_link_cb, &cd);
3240
 
        }
3241
 
        if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
3242
 
                ret = zvol_create_link(zhp->zfs_hdl, path);
3243
 
                if (ret != 0) {
3244
 
                        (void) zfs_standard_error(hdl, errno,
3245
 
                            dgettext(TEXT_DOMAIN,
3246
 
                            "Volume successfully snapshotted, but device links "
3247
 
                            "were not created"));
3248
 
                        zfs_close(zhp);
3249
 
                        return (-1);
3250
 
                }
3251
 
        }
3252
 
 
3253
 
        if (ret != 0)
3254
3264
                (void) zfs_standard_error(hdl, errno, errbuf);
 
3265
        }
3255
3266
 
3256
3267
        zfs_close(zhp);
3257
3268
 
3291
3302
 
3292
3303
                        logstr = zhp->zfs_hdl->libzfs_log_str;
3293
3304
                        zhp->zfs_hdl->libzfs_log_str = NULL;
3294
 
                        cbp->cb_error |= zfs_destroy(zhp);
 
3305
                        cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
3295
3306
                        zhp->zfs_hdl->libzfs_log_str = logstr;
3296
3307
                }
3297
3308
        } else {
3305
3316
                        zfs_close(zhp);
3306
3317
                        return (0);
3307
3318
                }
3308
 
                if (zfs_destroy(zhp) != 0)
 
3319
                if (zfs_destroy(zhp, B_FALSE) != 0)
3309
3320
                        cbp->cb_error = B_TRUE;
3310
3321
                else
3311
3322
                        changelist_remove(clp, zhp->zfs_name);
3354
3365
         */
3355
3366
 
3356
3367
        if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3357
 
                if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3358
 
                        return (-1);
3359
3368
                if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
3360
3369
                        return (-1);
3361
3370
                old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3393
3402
         */
3394
3403
        if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
3395
3404
            (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
3396
 
                if (err = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name)) {
3397
 
                        zfs_close(zhp);
3398
 
                        return (err);
3399
 
                }
3400
3405
                if (restore_resv) {
3401
3406
                        new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3402
3407
                        if (old_volsize != new_volsize)
3511
3516
 
3512
3517
                if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3513
3518
                        return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3514
 
                uint64_t unused;
3515
3519
 
3516
3520
                /* validate parents */
3517
 
                if (check_parents(hdl, target, &unused, B_FALSE, NULL) != 0)
 
3521
                if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
3518
3522
                        return (-1);
3519
3523
 
3520
 
                (void) parent_name(target, parent, sizeof (parent));
3521
 
 
3522
3524
                /* make sure we're in the same pool */
3523
3525
                verify((delim = strchr(target, '/')) != NULL);
3524
3526
                if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
3529
3531
                }
3530
3532
 
3531
3533
                /* new name cannot be a child of the current dataset name */
3532
 
                if (strncmp(parent, zhp->zfs_name,
3533
 
                    strlen(zhp->zfs_name)) == 0) {
 
3534
                if (is_descendant(zhp->zfs_name, target)) {
3534
3535
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3535
 
                            "New dataset name cannot be a descendent of "
 
3536
                            "New dataset name cannot be a descendant of "
3536
3537
                            "current dataset name"));
3537
3538
                        return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3538
3539
                }
3549
3550
        }
3550
3551
 
3551
3552
        if (recursive) {
3552
 
                struct destroydata dd;
3553
3553
 
3554
3554
                parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
3555
3555
                if (parentname == NULL) {
3564
3564
                        goto error;
3565
3565
                }
3566
3566
 
3567
 
                dd.snapname = delim + 1;
3568
 
                dd.gotone = B_FALSE;
3569
 
                dd.closezhp = B_TRUE;
3570
 
 
3571
 
                /* We remove any zvol links prior to renaming them */
3572
 
                ret = zfs_iter_filesystems(zhrp, zfs_remove_link_cb, &dd);
3573
 
                if (ret) {
3574
 
                        goto error;
3575
 
                }
3576
3567
        } else {
3577
3568
                if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0)) == NULL)
3578
3569
                        return (-1);
3620
3611
                 * On failure, we still want to remount any filesystems that
3621
3612
                 * were previously mounted, so we don't alter the system state.
3622
3613
                 */
3623
 
                if (recursive) {
3624
 
                        struct createdata cd;
3625
 
 
3626
 
                        /* only create links for datasets that had existed */
3627
 
                        cd.cd_snapname = delim + 1;
3628
 
                        cd.cd_ifexists = B_TRUE;
3629
 
                        (void) zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3630
 
                            &cd);
3631
 
                } else {
 
3614
                if (!recursive)
3632
3615
                        (void) changelist_postfix(cl);
3633
 
                }
3634
3616
        } else {
3635
 
                if (recursive) {
3636
 
                        struct createdata cd;
3637
 
 
3638
 
                        /* only create links for datasets that had existed */
3639
 
                        cd.cd_snapname = strchr(target, '@') + 1;
3640
 
                        cd.cd_ifexists = B_TRUE;
3641
 
                        ret = zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3642
 
                            &cd);
3643
 
                } else {
 
3617
                if (!recursive) {
3644
3618
                        changelist_rename(cl, zfs_get_name(zhp), target);
3645
3619
                        ret = changelist_postfix(cl);
3646
3620
                }
3659
3633
        return (ret);
3660
3634
}
3661
3635
 
3662
 
/*
3663
 
 * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
3664
 
 * poke devfsadm to create the /dev link, and then wait for the link to appear.
3665
 
 */
3666
 
int
3667
 
zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
3668
 
{
3669
 
        return (zvol_create_link_common(hdl, dataset, B_FALSE));
3670
 
}
3671
 
 
3672
 
static int
3673
 
zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
3674
 
{
3675
 
#if 0
3676
 
        zfs_cmd_t zc = { 0 };
3677
 
        di_devlink_handle_t dhdl;
3678
 
        priv_set_t *priv_effective;
3679
 
        int privileged;
3680
 
 
3681
 
        (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3682
 
 
3683
 
        /*
3684
 
         * Issue the appropriate ioctl.
3685
 
         */
3686
 
        if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
3687
 
                switch (errno) {
3688
 
                case EEXIST:
3689
 
                        /*
3690
 
                         * Silently ignore the case where the link already
3691
 
                         * exists.  This allows 'zfs volinit' to be run multiple
3692
 
                         * times without errors.
3693
 
                         */
3694
 
                        return (0);
3695
 
 
3696
 
                case ENOENT:
3697
 
                        /*
3698
 
                         * Dataset does not exist in the kernel.  If we
3699
 
                         * don't care (see zfs_rename), then ignore the
3700
 
                         * error quietly.
3701
 
                         */
3702
 
                        if (ifexists) {
3703
 
                                return (0);
3704
 
                        }
3705
 
 
3706
 
                        /* FALLTHROUGH */
3707
 
 
3708
 
                default:
3709
 
                        return (zfs_standard_error_fmt(hdl, errno,
3710
 
                            dgettext(TEXT_DOMAIN, "cannot create device links "
3711
 
                            "for '%s'"), dataset));
3712
 
                }
3713
 
        }
3714
 
 
3715
 
        /*
3716
 
         * If privileged call devfsadm and wait for the links to
3717
 
         * magically appear.
3718
 
         * Otherwise, print out an informational message.
3719
 
         */
3720
 
 
3721
 
        priv_effective = priv_allocset();
3722
 
        (void) getppriv(PRIV_EFFECTIVE, priv_effective);
3723
 
        privileged = (priv_isfullset(priv_effective) == B_TRUE);
3724
 
        priv_freeset(priv_effective);
3725
 
 
3726
 
        if (privileged) {
3727
 
                if ((dhdl = di_devlink_init(ZFS_DRIVER,
3728
 
                    DI_MAKE_LINK)) == NULL) {
3729
 
                        zfs_error_aux(hdl, strerror(errno));
3730
 
                        (void) zfs_error_fmt(hdl, errno,
3731
 
                            dgettext(TEXT_DOMAIN, "cannot create device links "
3732
 
                            "for '%s'"), dataset);
3733
 
                        (void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
3734
 
                        return (-1);
3735
 
                } else {
3736
 
                        (void) di_devlink_fini(&dhdl);
3737
 
                }
3738
 
        } else {
3739
 
                char pathname[MAXPATHLEN];
3740
 
                struct stat64 statbuf;
3741
 
                int i;
3742
 
 
3743
 
#define MAX_WAIT        10
3744
 
 
3745
 
                /*
3746
 
                 * This is the poor mans way of waiting for the link
3747
 
                 * to show up.  If after 10 seconds we still don't
3748
 
                 * have it, then print out a message.
3749
 
                 */
3750
 
                (void) snprintf(pathname, sizeof (pathname), "/dev/zvol/dsk/%s",
3751
 
                    dataset);
3752
 
 
3753
 
                for (i = 0; i != MAX_WAIT; i++) {
3754
 
                        if (stat64(pathname, &statbuf) == 0)
3755
 
                                break;
3756
 
                        (void) sleep(1);
3757
 
                }
3758
 
                if (i == MAX_WAIT)
3759
 
                        (void) printf(gettext("%s may not be immediately "
3760
 
                            "available\n"), pathname);
3761
 
        }
3762
 
 
3763
 
        return (0);
3764
 
#endif
3765
 
 
3766
 
        /* zfs-fuse TODO: implement ZVOLs */
3767
 
        abort();
3768
 
}
3769
 
 
3770
 
/*
3771
 
 * Remove a minor node for the given zvol and the associated /dev links.
3772
 
 */
3773
 
int
3774
 
zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
3775
 
{
3776
 
        zfs_cmd_t zc = { 0 };
3777
 
 
3778
 
        (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3779
 
 
3780
 
        if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
3781
 
                switch (errno) {
3782
 
                case ENXIO:
3783
 
                        /*
3784
 
                         * Silently ignore the case where the link no longer
3785
 
                         * exists, so that 'zfs volfini' can be run multiple
3786
 
                         * times without errors.
3787
 
                         */
3788
 
                        return (0);
3789
 
 
3790
 
                default:
3791
 
                        return (zfs_standard_error_fmt(hdl, errno,
3792
 
                            dgettext(TEXT_DOMAIN, "cannot remove device "
3793
 
                            "links for '%s'"), dataset));
3794
 
                }
3795
 
        }
3796
 
 
3797
 
        return (0);
3798
 
}
3799
 
 
3800
3636
nvlist_t *
3801
3637
zfs_get_user_props(zfs_handle_t *zhp)
3802
3638
{
3803
3639
        return (zhp->zfs_user_props);
3804
3640
}
3805
3641
 
 
3642
nvlist_t *
 
3643
zfs_get_recvd_props(zfs_handle_t *zhp)
 
3644
{
 
3645
        if (zhp->zfs_recvd_props == NULL)
 
3646
                if (get_recvd_props_ioctl(zhp) != 0)
 
3647
                        return (NULL);
 
3648
        return (zhp->zfs_recvd_props);
 
3649
}
 
3650
 
3806
3651
/*
3807
3652
 * This function is used by 'zfs list' to determine the exact set of columns to
3808
3653
 * display, and their maximum widths.  This does two main things:
3812
3657
 *        for new unique user properties and add them to the list.
3813
3658
 *
3814
3659
 *      - For non fixed-width properties, keep track of the maximum width seen
3815
 
 *        so that we can size the column appropriately.
 
3660
 *        so that we can size the column appropriately. If the user has
 
3661
 *        requested received property values, we also need to compute the width
 
3662
 *        of the RECEIVED column.
3816
3663
 */
3817
3664
int
3818
 
zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp)
 
3665
zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received)
3819
3666
{
3820
3667
        libzfs_handle_t *hdl = zhp->zfs_hdl;
3821
3668
        zprop_list_t *entry;
3886
3733
                                if (strlen(buf) > entry->pl_width)
3887
3734
                                        entry->pl_width = strlen(buf);
3888
3735
                        }
3889
 
                } else if (nvlist_lookup_nvlist(userprops,
3890
 
                    entry->pl_user_prop, &propval)  == 0) {
3891
 
                        verify(nvlist_lookup_string(propval,
3892
 
                            ZPROP_VALUE, &strval) == 0);
3893
 
                        if (strlen(strval) > entry->pl_width)
3894
 
                                entry->pl_width = strlen(strval);
 
3736
                        if (received && zfs_prop_get_recvd(zhp,
 
3737
                            zfs_prop_to_name(entry->pl_prop),
 
3738
                            buf, sizeof (buf), B_FALSE) == 0)
 
3739
                                if (strlen(buf) > entry->pl_recvd_width)
 
3740
                                        entry->pl_recvd_width = strlen(buf);
 
3741
                } else {
 
3742
                        if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
 
3743
                            &propval) == 0) {
 
3744
                                verify(nvlist_lookup_string(propval,
 
3745
                                    ZPROP_VALUE, &strval) == 0);
 
3746
                                if (strlen(strval) > entry->pl_width)
 
3747
                                        entry->pl_width = strlen(strval);
 
3748
                        }
 
3749
                        if (received && zfs_prop_get_recvd(zhp,
 
3750
                            entry->pl_user_prop,
 
3751
                            buf, sizeof (buf), B_FALSE) == 0)
 
3752
                                if (strlen(buf) > entry->pl_recvd_width)
 
3753
                                        entry->pl_recvd_width = strlen(buf);
3895
3754
                }
3896
3755
        }
3897
3756
 
3899
3758
}
3900
3759
 
3901
3760
int
3902
 
zfs_iscsi_perm_check(libzfs_handle_t *hdl, char *dataset, ucred_t *cred)
3903
 
{
3904
 
        /* ZFS-FUSE: not implemented */
3905
 
        return (ENOTSUP);
3906
 
#if 0
3907
 
        zfs_cmd_t zc = { 0 };
3908
 
        nvlist_t *nvp;
3909
 
        gid_t gid;
3910
 
        uid_t uid;
3911
 
        const gid_t *groups;
3912
 
        int group_cnt;
3913
 
        int error;
3914
 
 
3915
 
        if (nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0) != 0)
3916
 
                return (no_memory(hdl));
3917
 
 
3918
 
        uid = ucred_geteuid(cred);
3919
 
        gid = ucred_getegid(cred);
3920
 
        group_cnt = ucred_getgroups(cred, &groups);
3921
 
 
3922
 
        if (uid == (uid_t)-1 || gid == (uid_t)-1 || group_cnt == (uid_t)-1)
3923
 
                return (1);
3924
 
 
3925
 
        if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_UID, uid) != 0) {
3926
 
                nvlist_free(nvp);
3927
 
                return (1);
3928
 
        }
3929
 
 
3930
 
        if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_GID, gid) != 0) {
3931
 
                nvlist_free(nvp);
3932
 
                return (1);
3933
 
        }
3934
 
 
3935
 
        if (nvlist_add_uint32_array(nvp,
3936
 
            ZFS_DELEG_PERM_GROUPS, (uint32_t *)groups, group_cnt) != 0) {
3937
 
                nvlist_free(nvp);
3938
 
                return (1);
3939
 
        }
3940
 
        (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3941
 
 
3942
 
        if (zcmd_write_src_nvlist(hdl, &zc, nvp))
3943
 
                return (-1);
3944
 
 
3945
 
        error = ioctl(hdl->libzfs_fd, ZFS_IOC_ISCSI_PERM_CHECK, &zc);
3946
 
        nvlist_free(nvp);
3947
 
        return (error);
3948
 
#endif
3949
 
}
3950
 
 
3951
 
int
3952
3761
zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
3953
3762
    char *resource, void *export, void *sharetab,
3954
3763
    int sharemax, zfs_share_op_t operation)
3986
3795
                nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
3987
3796
 
3988
3797
                /*
3989
 
                 * We leave user:props in the nvlist, so there will be
3990
 
                 * some ZPROP_INVAL.  To be extra safe, don't prune
3991
 
                 * those.
 
3798
                 * User properties will result in ZPROP_INVAL, and since we
 
3799
                 * only know how to prune standard ZFS properties, we always
 
3800
                 * leave these in the list.  This can also happen if we
 
3801
                 * encounter an unknown DSL property (when running older
 
3802
                 * software, for example).
3992
3803
                 */
3993
3804
                if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
3994
3805
                        (void) nvlist_remove(zhp->zfs_props,
4114
3925
 
4115
3926
        return (error);
4116
3927
}
 
3928
 
 
3929
int
 
3930
zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
 
3931
    boolean_t recursive, boolean_t temphold, boolean_t enoent_ok)
 
3932
{
 
3933
        zfs_cmd_t zc = { 0 };
 
3934
        libzfs_handle_t *hdl = zhp->zfs_hdl;
 
3935
 
 
3936
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
3937
        (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
 
3938
        if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
 
3939
            >= sizeof (zc.zc_string))
 
3940
                return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
 
3941
        zc.zc_cookie = recursive;
 
3942
        zc.zc_temphold = temphold;
 
3943
 
 
3944
        if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) {
 
3945
                char errbuf[ZFS_MAXNAMELEN+32];
 
3946
 
 
3947
                /*
 
3948
                 * if it was recursive, the one that actually failed will be in
 
3949
                 * zc.zc_name.
 
3950
                 */
 
3951
                (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 
3952
                    "cannot hold '%s@%s'"), zc.zc_name, snapname);
 
3953
                switch (errno) {
 
3954
                case E2BIG:
 
3955
                        /*
 
3956
                         * Temporary tags wind up having the ds object id
 
3957
                         * prepended. So even if we passed the length check
 
3958
                         * above, it's still possible for the tag to wind
 
3959
                         * up being slightly too long.
 
3960
                         */
 
3961
                        return (zfs_error(hdl, EZFS_TAGTOOLONG, errbuf));
 
3962
                case ENOTSUP:
 
3963
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
3964
                            "pool must be upgraded"));
 
3965
                        return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
 
3966
                case EINVAL:
 
3967
                        return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
 
3968
                case EEXIST:
 
3969
                        return (zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf));
 
3970
                case ENOENT:
 
3971
                        if (enoent_ok)
 
3972
                                return (0);
 
3973
                        /* FALLTHROUGH */
 
3974
                default:
 
3975
                        return (zfs_standard_error_fmt(hdl, errno, errbuf));
 
3976
                }
 
3977
        }
 
3978
 
 
3979
        return (0);
 
3980
}
 
3981
 
 
3982
struct hold_range_arg {
 
3983
        zfs_handle_t    *origin;
 
3984
        const char      *fromsnap;
 
3985
        const char      *tosnap;
 
3986
        char            lastsnapheld[ZFS_MAXNAMELEN];
 
3987
        const char      *tag;
 
3988
        boolean_t       temphold;
 
3989
        boolean_t       seento;
 
3990
        boolean_t       seenfrom;
 
3991
        boolean_t       holding;
 
3992
        boolean_t       recursive;
 
3993
        snapfilter_cb_t *filter_cb;
 
3994
        void            *filter_cb_arg;
 
3995
};
 
3996
 
 
3997
static int
 
3998
zfs_hold_range_one(zfs_handle_t *zhp, void *arg)
 
3999
{
 
4000
        struct hold_range_arg *hra = arg;
 
4001
        const char *thissnap;
 
4002
        int error;
 
4003
 
 
4004
        thissnap = strchr(zfs_get_name(zhp), '@') + 1;
 
4005
 
 
4006
        if (hra->fromsnap && !hra->seenfrom &&
 
4007
            strcmp(hra->fromsnap, thissnap) == 0)
 
4008
                hra->seenfrom = B_TRUE;
 
4009
 
 
4010
        /* snap is older or newer than the desired range, ignore it */
 
4011
        if (hra->seento || !hra->seenfrom) {
 
4012
                zfs_close(zhp);
 
4013
                return (0);
 
4014
        }
 
4015
 
 
4016
        if (!hra->seento && strcmp(hra->tosnap, thissnap) == 0)
 
4017
                hra->seento = B_TRUE;
 
4018
 
 
4019
        if (hra->filter_cb != NULL &&
 
4020
            hra->filter_cb(zhp, hra->filter_cb_arg) == B_FALSE) {
 
4021
                zfs_close(zhp);
 
4022
                return (0);
 
4023
        }
 
4024
 
 
4025
        if (hra->holding) {
 
4026
                /* We could be racing with destroy, so ignore ENOENT. */
 
4027
                error = zfs_hold(hra->origin, thissnap, hra->tag,
 
4028
                    hra->recursive, hra->temphold, B_TRUE);
 
4029
                if (error == 0) {
 
4030
                        (void) strlcpy(hra->lastsnapheld, zfs_get_name(zhp),
 
4031
                            sizeof (hra->lastsnapheld));
 
4032
                }
 
4033
        } else {
 
4034
                error = zfs_release(hra->origin, thissnap, hra->tag,
 
4035
                    hra->recursive);
 
4036
        }
 
4037
 
 
4038
        zfs_close(zhp);
 
4039
        return (error);
 
4040
}
 
4041
 
 
4042
/*
 
4043
 * Add a user hold on the set of snapshots starting with fromsnap up to
 
4044
 * and including tosnap. If we're unable to to acquire a particular hold,
 
4045
 * undo any holds up to that point.
 
4046
 */
 
4047
int
 
4048
zfs_hold_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
 
4049
    const char *tag, boolean_t recursive, boolean_t temphold,
 
4050
    snapfilter_cb_t filter_cb, void *cbarg)
 
4051
{
 
4052
        struct hold_range_arg arg = { 0 };
 
4053
        int error;
 
4054
 
 
4055
        arg.origin = zhp;
 
4056
        arg.fromsnap = fromsnap;
 
4057
        arg.tosnap = tosnap;
 
4058
        arg.tag = tag;
 
4059
        arg.temphold = temphold;
 
4060
        arg.holding = B_TRUE;
 
4061
        arg.recursive = recursive;
 
4062
        arg.seenfrom = (fromsnap == NULL);
 
4063
        arg.filter_cb = filter_cb;
 
4064
        arg.filter_cb_arg = cbarg;
 
4065
 
 
4066
        error = zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg);
 
4067
 
 
4068
        /*
 
4069
         * Make sure we either hold the entire range or none.
 
4070
         */
 
4071
        if (error && arg.lastsnapheld[0] != '\0') {
 
4072
                (void) zfs_release_range(zhp, fromsnap,
 
4073
                    (const char *)arg.lastsnapheld, tag, recursive);
 
4074
        }
 
4075
        return (error);
 
4076
}
 
4077
 
 
4078
int
 
4079
zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
 
4080
    boolean_t recursive)
 
4081
{
 
4082
        zfs_cmd_t zc = { 0 };
 
4083
        libzfs_handle_t *hdl = zhp->zfs_hdl;
 
4084
 
 
4085
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
4086
        (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
 
4087
        if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string))
 
4088
            >= sizeof (zc.zc_string))
 
4089
                return (zfs_error(hdl, EZFS_TAGTOOLONG, tag));
 
4090
        zc.zc_cookie = recursive;
 
4091
 
 
4092
        if (zfs_ioctl(hdl, ZFS_IOC_RELEASE, &zc) != 0) {
 
4093
                char errbuf[ZFS_MAXNAMELEN+32];
 
4094
 
 
4095
                /*
 
4096
                 * if it was recursive, the one that actually failed will be in
 
4097
                 * zc.zc_name.
 
4098
                 */
 
4099
                (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 
4100
                    "cannot release '%s' from '%s@%s'"), tag, zc.zc_name,
 
4101
                    snapname);
 
4102
                switch (errno) {
 
4103
                case ESRCH:
 
4104
                        return (zfs_error(hdl, EZFS_REFTAG_RELE, errbuf));
 
4105
                case ENOTSUP:
 
4106
                        zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 
4107
                            "pool must be upgraded"));
 
4108
                        return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
 
4109
                case EINVAL:
 
4110
                        return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
 
4111
                default:
 
4112
                        return (zfs_standard_error_fmt(hdl, errno, errbuf));
 
4113
                }
 
4114
        }
 
4115
 
 
4116
        return (0);
 
4117
}
 
4118
 
 
4119
/*
 
4120
 * Release a user hold from the set of snapshots starting with fromsnap
 
4121
 * up to and including tosnap.
 
4122
 */
 
4123
int
 
4124
zfs_release_range(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
 
4125
    const char *tag, boolean_t recursive)
 
4126
{
 
4127
        struct hold_range_arg arg = { 0 };
 
4128
 
 
4129
        arg.origin = zhp;
 
4130
        arg.fromsnap = fromsnap;
 
4131
        arg.tosnap = tosnap;
 
4132
        arg.tag = tag;
 
4133
        arg.recursive = recursive;
 
4134
        arg.seenfrom = (fromsnap == NULL);
 
4135
 
 
4136
        return (zfs_iter_snapshots_sorted(zhp, zfs_hold_range_one, &arg));
 
4137
}
 
4138
 
 
4139
uint64_t
 
4140
zvol_volsize_to_reservation(uint64_t volsize, nvlist_t *props)
 
4141
{
 
4142
        uint64_t numdb;
 
4143
        uint64_t nblocks, volblocksize;
 
4144
        int ncopies;
 
4145
        char *strval;
 
4146
 
 
4147
        if (nvlist_lookup_string(props,
 
4148
            zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
 
4149
                ncopies = atoi(strval);
 
4150
        else
 
4151
                ncopies = 1;
 
4152
        if (nvlist_lookup_uint64(props,
 
4153
            zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
 
4154
            &volblocksize) != 0)
 
4155
                volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
 
4156
        nblocks = volsize/volblocksize;
 
4157
        /* start with metadnode L0-L6 */
 
4158
        numdb = 7;
 
4159
        /* calculate number of indirects */
 
4160
        while (nblocks > 1) {
 
4161
                nblocks += DNODES_PER_LEVEL - 1;
 
4162
                nblocks /= DNODES_PER_LEVEL;
 
4163
                numdb += nblocks;
 
4164
        }
 
4165
        numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
 
4166
        volsize *= ncopies;
 
4167
        /*
 
4168
         * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
 
4169
         * compressed, but in practice they compress down to about
 
4170
         * 1100 bytes
 
4171
         */
 
4172
        numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
 
4173
        volsize += numdb;
 
4174
        return (volsize);
 
4175
}