Add linux compatibility
[zfs.git] / lib / libzfs / libzfs_dataset.c
index b7c1360..baf289b 100644 (file)
 #include <grp.h>
 #include <stddef.h>
 #include <ucred.h>
+#ifdef HAVE_IDMAP
 #include <idmap.h>
 #include <aclutils.h>
 #include <directory.h>
+#endif /* HAVE_IDMAP */
 
 #include <sys/dnode.h>
 #include <sys/spa.h>
@@ -72,55 +74,14 @@ zfs_type_to_name(zfs_type_t type)
                return (dgettext(TEXT_DOMAIN, "snapshot"));
        case ZFS_TYPE_VOLUME:
                return (dgettext(TEXT_DOMAIN, "volume"));
+       default:
+               break;
        }
 
        return (NULL);
 }
 
 /*
- * Given a path and mask of ZFS types, return a string describing this dataset.
- * This is used when we fail to open a dataset and we cannot get an exact type.
- * We guess what the type would have been based on the path and the mask of
- * acceptable types.
- */
-static const char *
-path_to_str(const char *path, int types)
-{
-       /*
-        * When given a single type, always report the exact type.
-        */
-       if (types == ZFS_TYPE_SNAPSHOT)
-               return (dgettext(TEXT_DOMAIN, "snapshot"));
-       if (types == ZFS_TYPE_FILESYSTEM)
-               return (dgettext(TEXT_DOMAIN, "filesystem"));
-       if (types == ZFS_TYPE_VOLUME)
-               return (dgettext(TEXT_DOMAIN, "volume"));
-
-       /*
-        * The user is requesting more than one type of dataset.  If this is the
-        * case, consult the path itself.  If we're looking for a snapshot, and
-        * a '@' is found, then report it as "snapshot".  Otherwise, remove the
-        * snapshot attribute and try again.
-        */
-       if (types & ZFS_TYPE_SNAPSHOT) {
-               if (strchr(path, '@') != NULL)
-                       return (dgettext(TEXT_DOMAIN, "snapshot"));
-               return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
-       }
-
-       /*
-        * The user has requested either filesystems or volumes.
-        * We have no way of knowing a priori what type this would be, so always
-        * report it as "filesystem" or "volume", our two primitive types.
-        */
-       if (types & ZFS_TYPE_FILESYSTEM)
-               return (dgettext(TEXT_DOMAIN, "filesystem"));
-
-       assert(types & ZFS_TYPE_VOLUME);
-       return (dgettext(TEXT_DOMAIN, "volume"));
-}
-
-/*
  * Validate a ZFS path.  This is used even before trying to open the dataset, to
  * provide a more meaningful error message.  We call zfs_error_aux() to
  * explain exactly why the name was not valid.
@@ -180,6 +141,8 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
                                zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
                                    "reserved disk name"));
                                break;
+                       default:
+                               break;
                        }
                }
 
@@ -344,7 +307,7 @@ get_recvd_props_ioctl(zfs_handle_t *zhp)
 {
        libzfs_handle_t *hdl = zhp->zfs_hdl;
        nvlist_t *recvdprops;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int err;
 
        if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
@@ -407,7 +370,7 @@ static int
 get_stats(zfs_handle_t *zhp)
 {
        int rc = 0;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
        if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
                return (-1);
@@ -467,7 +430,7 @@ make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
 zfs_handle_t *
 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
        zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
 
@@ -619,7 +582,7 @@ libzfs_mnttab_fini(libzfs_handle_t *hdl)
        void *cookie = NULL;
        mnttab_node_t *mtn;
 
-       while (mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie)) {
+       while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))) {
                free(mtn->mtn_mt.mnt_special);
                free(mtn->mtn_mt.mnt_mountp);
                free(mtn->mtn_mt.mnt_fstype);
@@ -691,7 +654,7 @@ libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
        mnttab_node_t *ret;
 
        find.mtn_mt.mnt_special = (char *)fsname;
-       if (ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL)) {
+       if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))) {
                avl_remove(&hdl->libzfs_mnttab_cache, ret);
                free(ret->mtn_mt.mnt_special);
                free(ret->mtn_mt.mnt_mountp);
@@ -941,6 +904,7 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
 
                case ZFS_PROP_MLSLABEL:
                {
+#ifdef HAVE_MLSLABEL
                        /*
                         * Verify the mlslabel string and convert to
                         * internal hex label string.
@@ -990,7 +954,12 @@ badlabel:
                        (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
                        m_label_free(new_sl);   /* OK if null */
                        goto error;
-
+#else
+                       zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                           "mlslabels are unsupported"));
+                       (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+                       goto error;
+#endif /* HAVE_MLSLABEL */
                }
 
                case ZFS_PROP_MOUNTPOINT:
@@ -1015,6 +984,8 @@ badlabel:
                                            "component of '%s' is too long"),
                                            propname);
                                        break;
+                               default:
+                                       break;
                                }
                                (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
                                goto error;
@@ -1139,6 +1110,8 @@ badlabel:
                case ZFS_PROP_NORMALIZE:
                        chosen_normal = (int)intval;
                        break;
+               default:
+                       break;
                }
 
                /*
@@ -1187,6 +1160,8 @@ badlabel:
                                        goto error;
                                }
                                break;
+                       default:
+                               break;
                        }
                }
        }
@@ -1343,7 +1318,7 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
 int
 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int ret = -1;
        prop_changelist_t *cl = NULL;
        char errbuf[1024];
@@ -1352,7 +1327,7 @@ zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
        zfs_prop_t prop;
        boolean_t do_prefix;
        uint64_t idx;
-       int added_resv;
+       int added_resv = 0;
 
        (void) snprintf(errbuf, sizeof (errbuf),
            dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
@@ -1455,7 +1430,7 @@ error:
 int
 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int ret;
        prop_changelist_t *cl;
        libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -1630,7 +1605,7 @@ static int
 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
     char **source, uint64_t *val)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        nvlist_t *zplprops = NULL;
        struct mnttab mnt;
        char *mntopt_on = NULL;
@@ -1674,6 +1649,8 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
                mntopt_on = MNTOPT_NBMAND;
                mntopt_off = MNTOPT_NONBMAND;
                break;
+       default:
+               break;
        }
 
        /*
@@ -1906,7 +1883,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
                            localtime_r(&time, &t) == NULL ||
                            strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
                            &t) == 0)
-                               (void) snprintf(propbuf, proplen, "%llu", val);
+                               (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t) val);
                }
                break;
 
@@ -2070,6 +2047,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
 
        case ZFS_PROP_MLSLABEL:
                {
+#ifdef HAVE_MLSLABEL
                        m_label_t *new_sl = NULL;
                        char *ascii = NULL;     /* human readable label */
 
@@ -2103,6 +2081,10 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
 
                        (void) strlcpy(propbuf, ascii, proplen);
                        free(ascii);
+#else
+                       (void) strlcpy(propbuf,
+                           getprop_string(zhp, prop, &source), proplen);
+#endif /* HAVE_MLSLABEL */
                }
                break;
 
@@ -2197,6 +2179,7 @@ zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
        return (0);
 }
 
+#ifdef HAVE_IDMAP
 static int
 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
     char **domainp, idmap_rid_t *ridp)
@@ -2226,6 +2209,7 @@ out:
                idmap_get_destroy(get_hdl);
        return (err);
 }
+#endif /* HAVE_IDMAP */
 
 /*
  * convert the propname into parameters needed by kernel
@@ -2259,6 +2243,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
        cp = strchr(propname, '@') + 1;
 
        if (strchr(cp, '@')) {
+#ifdef HAVE_IDMAP
                /*
                 * It's a SID name (eg "user@domain") that needs to be
                 * turned into S-1-domainID-RID.
@@ -2281,6 +2266,9 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
                        return (ENOENT);
                cp = numericsid;
                /* will be further decoded below */
+#else
+               return (ENOSYS);
+#endif /* HAVE_IDMAP */
        }
 
        if (strncmp(cp, "S-1-", 4) == 0) {
@@ -2319,6 +2307,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
                        *ridp = gr->gr_gid;
                }
        } else {
+#ifdef HAVE_IDMAP
                /* It's a user/group ID (eg "12345"). */
                uid_t id = strtoul(cp, &end, 10);
                idmap_rid_t rid;
@@ -2336,6 +2325,9 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
                } else {
                        *ridp = id;
                }
+#else
+               return (ENOSYS);
+#endif /* HAVE_IDMAP */
        }
 
        ASSERT3P(numericsid, ==, NULL);
@@ -2347,7 +2339,7 @@ zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
     uint64_t *propvalue, zfs_userquota_prop_t *typep)
 {
        int err;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
        (void) strncpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
@@ -2391,7 +2383,8 @@ zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
                return (err);
 
        if (literal) {
-               (void) snprintf(propbuf, proplen, "%llu", propvalue);
+               (void) snprintf(propbuf, proplen, "%llu",
+                              (u_longlong_t)propvalue);
        } else if (propvalue == 0 &&
            (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA)) {
                (void) strlcpy(propbuf, "none", proplen);
@@ -2465,7 +2458,7 @@ top:
 int
 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        zfs_handle_t *nzhp;
        int ret;
 
@@ -2501,7 +2494,7 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
 int
 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        zfs_handle_t *nzhp;
        int ret;
 
@@ -2592,7 +2585,7 @@ static int
 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
     boolean_t accept_ancestor, int *prefixlen)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        char parent[ZFS_MAXNAMELEN];
        char *slash;
        zfs_handle_t *zhp;
@@ -2721,7 +2714,7 @@ create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
         * up to the prefixlen-long one.
         */
        for (cp = target + prefixlen + 1;
-           cp = strchr(cp, '/'); *cp = '/', cp++) {
+           (cp = strchr(cp, '/')); *cp = '/', cp++) {
                char *logstr;
 
                *cp = '\0';
@@ -2778,7 +2771,7 @@ zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
 {
        int prefix;
        char *path_copy;
-       int rc;
+       int rc = 0;
 
        if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
                return (-1);
@@ -2800,7 +2793,7 @@ int
 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
     nvlist_t *props)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int ret;
        uint64_t size = 0;
        uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
@@ -2951,7 +2944,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
 int
 zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
 
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
@@ -3012,7 +3005,7 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
 int
 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int ret;
        struct destroydata dd = { 0 };
 
@@ -3057,7 +3050,7 @@ zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
 int
 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        char parent[ZFS_MAXNAMELEN];
        int ret;
        char errbuf[1024];
@@ -3147,7 +3140,7 @@ int
 zfs_promote(zfs_handle_t *zhp)
 {
        libzfs_handle_t *hdl = zhp->zfs_hdl;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        char parent[MAXPATHLEN];
        int ret;
        char errbuf[1024];
@@ -3201,7 +3194,7 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
        const char *delim;
        char parent[ZFS_MAXNAMELEN];
        zfs_handle_t *zhp;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int ret;
        char errbuf[1024];
 
@@ -3333,10 +3326,10 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
 {
        rollback_data_t cb = { 0 };
        int err;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        boolean_t restore_resv = 0;
-       uint64_t old_volsize, new_volsize;
-       zfs_prop_t resv_prop;
+       uint64_t old_volsize = 0, new_volsize;
+       zfs_prop_t resv_prop = { 0 };
 
        assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
            zhp->zfs_type == ZFS_TYPE_VOLUME);
@@ -3449,7 +3442,7 @@ int
 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive)
 {
        int ret;
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        char *delim;
        prop_changelist_t *cl = NULL;
        zfs_handle_t *zhrp = NULL;
@@ -3566,6 +3559,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive)
                            "child dataset with inherited mountpoint is used "
                            "in a non-global zone"));
                        (void) zfs_error(hdl, EZFS_ZONED, errbuf);
+                       ret = -1;
                        goto error;
                }
 
@@ -3755,7 +3749,7 @@ zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
     char *resource, void *export, void *sharetab,
     int sharemax, zfs_share_op_t operation)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int error;
 
        (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
@@ -3805,7 +3799,7 @@ static int
 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
     zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        nvlist_t *nvlist = NULL;
        int error;
 
@@ -3816,7 +3810,7 @@ zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
        if (cmd == ZFS_SMB_ACL_RENAME) {
                if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
                        (void) no_memory(hdl);
-                       return (NULL);
+                       return (-1);
                }
        }
 
@@ -3887,7 +3881,7 @@ int
 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
     zfs_userspace_cb_t func, void *arg)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        int error;
        zfs_useracct_t buf[100];
 
@@ -3924,7 +3918,7 @@ zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
     boolean_t recursive, boolean_t temphold, boolean_t enoent_ok,
     int cleanup_fd, uint64_t dsobj, uint64_t createtxg)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        libzfs_handle_t *hdl = zhp->zfs_hdl;
 
        ASSERT(!recursive || dsobj == 0);
@@ -3982,7 +3976,7 @@ int
 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
     boolean_t recursive)
 {
-       zfs_cmd_t zc = { 0 };
+       zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
        libzfs_handle_t *hdl = zhp->zfs_hdl;
 
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));