Beispiel #1
0
int
snapshot_release(char *volname, char *snapname, char *jname,
    boolean_t recursive)
{
	zfs_handle_t *zhp;
	char *p;
	int rv = 0;

	if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
		NDMP_LOG(LOG_ERR, "Cannot open volume %s", volname);
		return (-1);
	}

	p = strchr(snapname, '@') + 1;
	if (zfs_release(zhp, p, jname, recursive) != 0) {
		NDMP_LOG(LOG_DEBUG, "Cannot release snapshot %s", p);
		rv = -1;
	}
	if (cleanup_fd != -1) {
		(void) close(cleanup_fd);
		cleanup_fd = -1;
	}
	zfs_close(zhp);
	return (rv);
}
Beispiel #2
0
int
sa_zfs_is_shared(sa_handle_t sahandle, char *path)
{
	int ret = 0;
	char *dataset;
	zfs_handle_t *handle = NULL;
	char shareopts[ZFS_MAXPROPLEN];
	libzfs_handle_t *libhandle;

	dataset = get_zfs_dataset((sa_handle_t)sahandle, path, B_FALSE);
	if (dataset != NULL) {
		libhandle = libzfs_init();
		if (libhandle != NULL) {
			handle = zfs_open(libhandle, dataset,
			    ZFS_TYPE_FILESYSTEM);
			if (handle != NULL) {
				if (zfs_prop_get(handle, ZFS_PROP_SHARENFS,
				    shareopts, sizeof (shareopts), NULL, NULL,
				    0, B_FALSE) == 0 &&
				    strcmp(shareopts, "off") != 0) {
					ret = 1; /* it is shared */
				}
				zfs_close(handle);
			}
			libzfs_fini(libhandle);
		}
		free(dataset);
	}
	return (ret);
}
Beispiel #3
0
/*
 * Check if the volume type is snapshot volume
 */
boolean_t
fs_is_chkpntvol(char *path)
{
    zfs_handle_t *zhp;
    char vol[ZFS_MAXNAMELEN];

    if (!path || !*path)
        return (FALSE);

    if (get_zfsvolname(vol, sizeof (vol), path) == -1)
        return (FALSE);

    (void) mutex_lock(&zlib_mtx);
    if ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) == NULL) {
        (void) mutex_unlock(&zlib_mtx);
        return (FALSE);
    }

    if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) {
        zfs_close(zhp);
        (void) mutex_unlock(&zlib_mtx);
        return (FALSE);
    }
    zfs_close(zhp);
    (void) mutex_unlock(&zlib_mtx);

    return (TRUE);
}
static int
fsi_zfs_open(fsi_file_t *ffi, char *filename)
{
	char *fsi_bootstring;
	uint64_t *fmax;
	uint64_t *fpos;
	int rc;

	zfs_ffi = ffi;
	fmax = fsig_filemax(ffi);
	fpos = fsig_filepos(ffi);

	rc = zfs_open(filename);
	if (rc != 1) {
		return (rc);
	}

	*fmax = filemax;
	*fpos = filepos;

	if (bootstring == NULL) {
		rc = asprintf(&bootstring,
			      "zfs-bootfs=%s/%"PRIu64",bootpath='%s'",
			      current_rootpool, current_bootfs_obj,
			      current_bootpath);
		if (rc == -1) {
			return (rc);
		}
		fsi_bootstring = fsi_bootstring_alloc(ffi->ff_fsi,
		    strlen(bootstring) + 1);
		strcpy(fsi_bootstring, bootstring);
	}

	return (rc);
}
Beispiel #5
0
/*
 * Get the snapshot creation time
 */
int
chkpnt_creationtime_bypattern(char *volname, char *pattern, time_t *tp)
{
    char chk_name[PATH_MAX];
    zfs_handle_t *zhp;
    char *p;

    if (!volname || !*volname)
        return (-1);

    /* Should also return -1 if checkpoint not enabled */

    /* Remove the leading slash */
    p = volname;
    while (*p == '/')
        p++;

    (void) strlcpy(chk_name, p, PATH_MAX);
    (void) strlcat(chk_name, "@", PATH_MAX);
    (void) strlcat(chk_name, pattern, PATH_MAX);

    (void) mutex_lock(&zlib_mtx);
    if ((zhp = zfs_open(zlibh, chk_name, ZFS_TYPE_DATASET)) == NULL) {
        NDMP_LOG(LOG_DEBUG, "chkpnt_creationtime: open %s failed",
                 chk_name);
        (void) mutex_unlock(&zlib_mtx);
        return (-1);
    }

    *tp = zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
    zfs_close(zhp);
    (void) mutex_unlock(&zlib_mtx);

    return (0);
}
Beispiel #6
0
/*
 * This function is best effort. It attempts to load all the keys for the given
 * filesystem and all of its children.
 */
int
zfs_crypto_attempt_load_keys(libzfs_handle_t *hdl, char *fsname)
{
	int ret;
	zfs_handle_t *zhp = NULL;
	loadkey_cbdata_t cb = { 0 };

	zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
	if (zhp == NULL) {
		ret = ENOENT;
		goto error;
	}

	ret = load_keys_cb(zfs_handle_dup(zhp), &cb);
	if (ret)
		goto error;

	(void) printf(gettext("%llu / %llu keys successfully loaded\n"),
	    (u_longlong_t)(cb.cb_numattempted - cb.cb_numfailed),
	    (u_longlong_t)cb.cb_numattempted);

	if (cb.cb_numfailed != 0) {
		ret = -1;
		goto error;
	}

	zfs_close(zhp);
	return (0);

error:
	if (zhp != NULL)
		zfs_close(zhp);
	return (ret);
}
Beispiel #7
0
/*
 * Put a hold on snapshot
 */
int
snapshot_hold(char *volname, char *snapname, char *jname, boolean_t recursive)
{
	zfs_handle_t *zhp;
	char *p;

	if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
		NDMP_LOG(LOG_ERR, "Cannot open volume %s.", volname);
		return (-1);
	}

	if (cleanup_fd == -1 && (cleanup_fd = open(ZFS_DEV,
	    O_RDWR|O_EXCL)) < 0) {
		NDMP_LOG(LOG_ERR, "Cannot open dev %d", errno);
		zfs_close(zhp);
		return (-1);
	}

	p = strchr(snapname, '@') + 1;
	if (zfs_hold(zhp, p, jname, recursive, cleanup_fd) != 0) {
		NDMP_LOG(LOG_ERR, "Cannot hold snapshot %s", p);
		zfs_close(zhp);
		return (-1);
	}
	zfs_close(zhp);
	return (0);
}
Beispiel #8
0
/* Remove a home directory structure */
int
rm_homedir(char *dir)
{
	struct stat stbuf;
	char *nm;

	if ((stat(dir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode))
		return 0;

	if (g_zfs == NULL)
		g_zfs = libzfs_init();

	if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) && 
	    (g_zfs != NULL) &&
	    ((nm = get_mnt_special(dir, stbuf.st_fstype)) != NULL)) {
		zfs_handle_t *zhp;

	    	if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) != NULL) {
			if ((zfs_unmount(zhp, NULL, 0) == 0) &&
			    (zfs_destroy(zhp, B_FALSE) == 0)) {
				zfs_close(zhp);
				return 0;
			}

			(void) zfs_mount(zhp, NULL, 0);
			zfs_close(zhp);
		}
	}

	(void) sprintf(cmdbuf, "rm -rf %s", dir);

	return (system(cmdbuf));
}
Beispiel #9
0
int
zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
{
    get_all_cb_t cb = { 0 };
    libzfs_handle_t *hdl = zhp->zpool_hdl;
    zfs_handle_t *zfsp;
    int i, ret = -1;
    int *good;

    /*
     * Gather all non-snap datasets within the pool.
     */
    if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL)
        goto out;

    libzfs_add_handle(&cb, zfsp);
    if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0)
        goto out;
    /*
     * Sort the datasets by mountpoint.
     */
    qsort(cb.cb_handles, cb.cb_used, sizeof (void *),
          libzfs_dataset_cmp);

    /*
     * And mount all the datasets, keeping track of which ones
     * succeeded or failed.
     */
    if ((good = zfs_alloc(zhp->zpool_hdl,
                          cb.cb_used * sizeof (int))) == NULL)
        goto out;

    ret = 0;
    for (i = 0; i < cb.cb_used; i++) {
        if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0)
            ret = -1;
        else
            good[i] = 1;
    }

    /*
     * Then share all the ones that need to be shared. This needs
     * to be a separate pass in order to avoid excessive reloading
     * of the configuration. Good should never be NULL since
     * zfs_alloc is supposed to exit if memory isn't available.
     */
    for (i = 0; i < cb.cb_used; i++) {
        if (good[i] && zfs_share(cb.cb_handles[i]) != 0)
            ret = -1;
    }

    free(good);

out:
    for (i = 0; i < cb.cb_used; i++)
        zfs_close(cb.cb_handles[i]);
    free(cb.cb_handles);

    return (ret);
}
Beispiel #10
0
/*
 * path - path of the dataset
 * count - return value of the number of snapshots for the dataset
 */
int
smbd_vss_get_count(const char *path, uint32_t *count)
{
    char dataset[MAXPATHLEN];
    libzfs_handle_t *libhd;
    zfs_handle_t *zfshd;
    smbd_vss_count_t vss_count;

    bzero(&vss_count, sizeof (smbd_vss_count_t));
    *count = 0;

    if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
        return (-1);

    if ((libhd = libzfs_init()) == NULL)
        return (-1);

    if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
        libzfs_fini(libhd);
        return (-1);
    }

    (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_count,
                              (void *)&vss_count);

    if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
        vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;

    *count = vss_count.vc_count;
    zfs_close(zfshd);
    libzfs_fini(libhd);
    return (0);
}
Beispiel #11
0
/* Remove a home directory structure */
int
rm_homedir(char *dir, int flags)
{
	struct stat stbuf;
	char *nm, *rp;

	rp = realpath(dir, NULL);
	if (rp && (strcmp(rp, "/") == 0)) {
		return (0);
	}

	if ((stat(dir, &stbuf) != 0) || !S_ISDIR(stbuf.st_mode))
		return (0);

	if ((strcmp(stbuf.st_fstype, MNTTYPE_ZFS) == 0) &&
	    (flags & MANAGE_ZFS)) {
		if (g_zfs == NULL)
			g_zfs = libzfs_init();

		if (g_zfs == NULL) {
			errmsg(M_OOPS, "libzfs_init failure", strerror(errno));
			return (EX_HOMEDIR);
		}

		if ((nm = get_mnt_special(dir, stbuf.st_fstype)) != NULL) {
			zfs_handle_t *zhp;

			if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM))
			    != NULL) {
				if ((zfs_unmount(zhp, NULL, 0) == 0) &&
				    (zfs_destroy(zhp, B_FALSE) == 0)) {
					zfs_close(zhp);
					libzfs_fini(g_zfs);
					g_zfs = NULL;
					return (0);
				}

				errmsg(M_OOPS, "destroy the home directory",
				    libzfs_error_description(g_zfs));

				(void) zfs_mount(zhp, NULL, 0);
				zfs_close(zhp);

				libzfs_fini(g_zfs);
				g_zfs = NULL;
				return (EX_HOMEDIR);
			}
		}
	}

	(void) sprintf(cmdbuf, "rm -rf %s", dir);

	if (g_zfs != NULL) {
		libzfs_fini(g_zfs);
		g_zfs = NULL;
	}

	return (system(cmdbuf));
}
Beispiel #12
0
/*
 * Sets the share properties on a ZFS share. For now, this method sets only
 * the "sharesmb" property.
 *
 * This method includes building a comma seperated name-value string to be
 * set on the "sharesmb" property of a ZFS share. This name-value string is
 * build in 2 steps:
 *    - New property values given as name-value pair are set first.
 *    - Existing optionset properties, which are not part of the new properties
 *	passed in step 1, are appended to the newly set properties.
 */
int
sa_zfs_setprop(sa_handle_t handle, char *path, nvlist_t *nvl)
{
	zfs_handle_t *z_fs;
	libzfs_handle_t *z_lib;
	char sharesmb_val[MAXPATHLEN];
	char *dataset, *lastcomma;

	if (nvlist_empty(nvl))
		return (0);

	if ((handle == NULL) || (path == NULL))
		return (-1);

	if ((dataset = get_zfs_dataset(handle, path, B_FALSE)) == NULL)
		return (-1);

	if ((z_lib = libzfs_init()) == NULL) {
		free(dataset);
		return (-1);
	}

	z_fs = zfs_open(z_lib, dataset, ZFS_TYPE_DATASET);
	if (z_fs == NULL) {
		free(dataset);
		libzfs_fini(z_lib);
		return (-1);
	}

	bzero(sharesmb_val, MAXPATHLEN);
	if (sa_zfs_sprintf_new_prop(nvl, sharesmb_val) != 0) {
		free(dataset);
		zfs_close(z_fs);
		libzfs_fini(z_lib);
		return (-1);
	}

	if (sa_zfs_sprintf_existing_prop(z_fs, sharesmb_val) != 0) {
		free(dataset);
		zfs_close(z_fs);
		libzfs_fini(z_lib);
		return (-1);
	}

	lastcomma = strrchr(sharesmb_val, ',');
	if ((lastcomma != NULL) && (lastcomma[1] == '\0'))
		*lastcomma = '\0';

	(void) zfs_prop_set(z_fs, zfs_prop_to_name(ZFS_PROP_SHARESMB),
	    sharesmb_val);
	free(dataset);
	zfs_close(z_fs);
	libzfs_fini(z_lib);

	return (0);
}
Beispiel #13
0
/*
 * Read the server config as properties associated with the dataset.
 * Missing entries as not treated error and are simply skipped.
 */
int zfs_read_ldd(char *ds,  struct lustre_disk_data *ldd)
{
	zfs_handle_t *zhp;
	int ret = EINVAL;

	if (osd_check_zfs_setup() == 0)
		return EINVAL;

	zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM);
	if (zhp == NULL)
		goto out;

	ret = zfs_get_prop_int(zhp, LDD_VERSION_PROP, &ldd->ldd_config_ver);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_int(zhp, LDD_FLAGS_PROP, &ldd->ldd_flags);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_int(zhp, LDD_INDEX_PROP, &ldd->ldd_svindex);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_FSNAME_PROP, ldd->ldd_fsname);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_SVNAME_PROP, ldd->ldd_svname);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_UUID_PROP, (char *)ldd->ldd_uuid);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_USERDATA_PROP, ldd->ldd_userdata);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_MOUNTOPTS_PROP, ldd->ldd_mount_opts);
	if (ret && (ret != ENOENT))
		goto out_close;

	ret = zfs_get_prop_str(zhp, LDD_PARAMS_PROP, ldd->ldd_params);
	if (ret && (ret != ENOENT))
		goto out_close;

	ldd->ldd_mount_type = LDD_MT_ZFS;
	ret = 0;
out_close:
	zfs_close(zhp);
out:
	return ret;
}
Beispiel #14
0
/*
 * path - path of the dataset for the operation
 * gmttoken - the @GMT token to be looked up
 * toktime - time_t used if gmttoken == NULL
 * snapname - the snapshot name to be returned [MAXPATHLEN]
 *
 * Here we are going to get the snapshot name from the @GMT token
 * The snapname returned by ZFS is : <dataset name>@<snapshot name>
 * So we are going to make sure there is the @ symbol in
 * the right place and then just return the snapshot name
 */
int
smbd_vss_map_gmttoken(const char *path, char *gmttoken, time_t toktime,
                      char *snapname)
{
    char dataset[MAXPATHLEN];
    libzfs_handle_t *libhd;
    zfs_handle_t *zfshd;
    smbd_vss_map_gmttoken_t vss_map_gmttoken;
    char *zsnap;
    const char *lsnap;
    struct tm tm;

    if (gmttoken != NULL && *gmttoken == '@' &&
            strptime(gmttoken, smbd_vss_gmttoken_fmt, &tm) != NULL) {
        toktime = timegm(&tm);
    }

    vss_map_gmttoken.mg_snaptime = toktime;
    vss_map_gmttoken.mg_snapname = snapname;
    *snapname = '\0';

    if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
        return (-1);

    if ((libhd = libzfs_init()) == NULL)
        return (-1);

    if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
        libzfs_fini(libhd);
        return (-1);
    }

    (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_map_gmttoken,
                              (void *)&vss_map_gmttoken);

    /* compare the zfs snapshot name and the local snap name */
    zsnap = snapname;
    lsnap = dataset;
    while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
        zsnap++;
        lsnap++;
    }

    /* Now we should be passed the dataset name */
    if ((*zsnap == '@') && (*lsnap == '\0')) {
        zsnap++;
        (void) strlcpy(snapname, zsnap, MAXPATHLEN);
    } else {
        *snapname = '\0';
    }

    zfs_close(zfshd);
    libzfs_fini(libhd);
    return (0);
}
Beispiel #15
0
/**
 * Create the zpool
 * @param p_libzfshd: libzfs handle
 * @param psz_zpool: zpool name
 * @param pnv_root: the root tree of vdev
 * @param pnv_props: the tree of properties (can be NULL)
 * @param pnv_fsprops: the tree of the file system properties (can be NULL)
 * @param ppsz_error: the error message if any
 * @return 0 in case of error, the error code overwise
 */
int libzfs_zpool_create(libzfs_handle_t *p_libzfshd, const char* psz_zpool,
                        nvlist_t *pnv_root, nvlist_t *pnv_props,
                        nvlist_t *pnv_fsprops, const char **ppsz_error)
{
        int i_error;
        char *psz_altroot;

        /* Check the zpool name */
        if(libzfs_zpool_name_valid(psz_zpool, ppsz_error))
                return EINVAL;

        /** Check the properties
            TODO: zpool_valid_proplist and zfs_valid_proplist */

        if((i_error = spa_create(psz_zpool, pnv_root, pnv_props, "libzfswrap_zpool_create", pnv_fsprops)))
        {
                switch(i_error)
                {
                case EBUSY:
                        *ppsz_error = "one or more vdevs refer to the same device";
                        break;
                case EOVERFLOW:
                        *ppsz_error = "one or more devices is less than the minimum size (64Mo)";
                        break;
                case ENOSPC:
                        *ppsz_error = "one or more devices is out of space";
                        break;
                case ENOTBLK:
                        *ppsz_error = "cache device must be a disk or disk slice";
                        break;
                case EEXIST:
                        *ppsz_error = "the pool already exist";
                        break;
                default:
                        *ppsz_error = "unable to create the spa";
                }
                return i_error;
        }

        /* If this is an alternate root pool, then automatically set the
           mountpoint to be '/' */
        if(nvlist_lookup_string(pnv_props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &psz_altroot) == 0)
        {
                zfs_handle_t *p_zhd;
                assert((p_zhd = zfs_open(p_libzfshd, psz_zpool, ZFS_TYPE_DATASET)) != NULL);
                assert(zfs_prop_set(p_zhd, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), "/") == 0);
                zfs_close(p_zhd);
        }

        return 0;
}
Beispiel #16
0
/*
 * Function:	be_get_zone_be_list
 * Description:	Finds all the BEs for this zone on the system.
 * Parameters:
 *		zone_be_name - The name of the BE to look up.
 *              zone_be_container_ds - The dataset for the zone.
 *		zbe_nodes - A reference pointer to the list of BEs. The list
 *			   structure will be allocated here and must
 *			   be freed by a call to be_free_list. If there are no
 *			   BEs found on the system this reference will be
 *			   set to NULL.
 * Return:
 *		BE_SUCCESS - Success
 *		be_errno_t - Failure
 * Scope:
 *		Semi-private (library wide use only)
 */
int
be_get_zone_be_list(
/* LINTED */
	char *zone_be_name,
	char *zone_be_container_ds,
	be_node_list_t **zbe_nodes)
{
	zfs_handle_t *zhp = NULL;
	list_callback_data_t cb = { 0 };
	int ret = BE_SUCCESS;

	if (zbe_nodes == NULL)
		return (BE_ERR_INVAL);

	if (!zfs_dataset_exists(g_zfs, zone_be_container_ds,
	    ZFS_TYPE_FILESYSTEM)) {
		return (BE_ERR_BE_NOENT);
	}

	zone_be = B_TRUE;

	if ((zhp = zfs_open(g_zfs, zone_be_container_ds,
	    ZFS_TYPE_FILESYSTEM)) == NULL) {
		be_print_err(gettext("be_get_zone_be_list: failed to open "
		    "the zone BE dataset %s: %s\n"), zone_be_container_ds,
		    libzfs_error_description(g_zfs));
		ret = zfs_err_to_be_err(g_zfs);
		goto cleanup;
	}

	(void) strcpy(be_container_ds, zone_be_container_ds);

	if (cb.be_nodes_head == NULL) {
		if ((cb.be_nodes_head = be_list_alloc(&ret,
		    sizeof (be_node_list_t))) == NULL) {
			ZFS_CLOSE(zhp);
			goto cleanup;
		}
		cb.be_nodes = cb.be_nodes_head;
	}
	if (ret == 0)
		ret = zfs_iter_filesystems(zhp, be_add_children_callback, &cb);
	ZFS_CLOSE(zhp);

	*zbe_nodes = cb.be_nodes_head;

cleanup:
	zone_be = B_FALSE;

	return (ret);
}
Beispiel #17
0
int zfs_label_lustre(struct mount_opts *mop)
{
	zfs_handle_t *zhp;
	int ret;

	if (osd_check_zfs_setup() == 0)
		return EINVAL;

	zhp = zfs_open(g_zfs, mop->mo_source, ZFS_TYPE_FILESYSTEM);
	if (zhp == NULL)
		return EINVAL;

	ret = zfs_set_prop_str(zhp, LDD_SVNAME_PROP, mop->mo_ldd.ldd_svname);
	zfs_close(zhp);

	return ret;
}
Beispiel #18
0
static int
zpl_open(struct inode *ip, struct file *filp)
{
	cred_t *cr = CRED();
	int error;

	error = generic_file_open(ip, filp);
	if (error)
		return (error);

	crhold(cr);
	error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Beispiel #19
0
/*
 * Just checking the existance of the given target. Here we check whether
 * both zfs and iscsitarget aware of the given target/volume. It neither
 * care about the credentials nor SHAREISCSI properties.
 */
static char *
validate_zfs_iscsitgt(tgt_node_t *x)
{
	char		*msg		= NULL;
	char		*prop		= NULL;
	char		*dataset	= NULL;
	libzfs_handle_t	*zh		= NULL;
	zfs_handle_t	*zfsh		= NULL;
	tgt_node_t	*n		= NULL;

	if (tgt_find_value_str(x, XML_ELEMENT_NAME, &dataset) == False) {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME);
		return (msg);
	}

	if (((zh = libzfs_init()) == NULL) ||
	    ((zfsh = zfs_open(zh, dataset, ZFS_TYPE_DATASET)) == NULL)) {
		xml_rtn_msg(&msg, ERR_TARG_NOT_FOUND);
		goto error;
	}

	while ((n = tgt_node_next_child(targets_config, XML_ELEMENT_TARG, n)) !=
	    NULL) {
		if (strcmp(n->x_value, dataset) == 0)
			break;
	}
	if (n == NULL) {
		xml_rtn_msg(&msg, ERR_TARG_NOT_FOUND);
		goto error;
	}

	xml_rtn_msg(&msg, ERR_SUCCESS);

error:
	if (zfsh)
		zfs_close(zfsh);
	if (prop)
		free(prop);
	if (zh)
		libzfs_fini(zh);
	if (dataset)
		free(dataset);

	return (msg);

}
Beispiel #20
0
void Destroy::find(const std::string &root)
{
    zfs_handle_t *hzfs = zfs_open(m_hlib, root.c_str(),
        ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);

    if (!hzfs) {
        std::cerr << root << ": " << libzfs_error_description(m_hlib)
            << std::endl;
        return;
    }

    zfs_iter_snapshots(hzfs, B_FALSE, iter_dataset, this);

    if (m_recursive) {
        zfs_iter_filesystems(hzfs, iter_dataset, this);
    }

    zfs_close(hzfs);
}
Beispiel #21
0
/*
 * Destroy the given pool.  It is up to the caller to ensure that there are no
 * datasets left in the pool.
 */
int
zpool_destroy(zpool_handle_t *zhp)
{
	zfs_cmd_t zc = { 0 };
	zfs_handle_t *zfp = NULL;
	libzfs_handle_t *hdl = zhp->zpool_hdl;
	char msg[1024];

	if (zhp->zpool_state == POOL_STATE_ACTIVE &&
	    (zfp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
	    ZFS_TYPE_FILESYSTEM)) == NULL)
		return (-1);

	if (zpool_remove_zvol_links(zhp) != NULL)
		return (-1);

	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));

	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
		    "cannot destroy '%s'"), zhp->zpool_name);

		if (errno == EROFS) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "one or more devices is read only"));
			(void) zfs_error(hdl, EZFS_BADDEV, msg);
		} else {
			(void) zpool_standard_error(hdl, errno, msg);
		}

		if (zfp)
			zfs_close(zfp);
		return (-1);
	}

	if (zfp) {
		remove_mountpoint(zfp);
		zfs_close(zfp);
	}

	return (0);
}
Beispiel #22
0
static int
zpl_open(struct inode *ip, struct file *filp)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	error = generic_file_open(ip, filp);
	if (error)
		return (error);

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
static int
zvol_cb(const char *dataset, void *data)
{
	libzfs_handle_t *hdl = data;
	zfs_handle_t *zhp;

	/*
	 * Ignore snapshots and ignore failures from non-existant datasets.
	 */
	if (strchr(dataset, '@') != NULL ||
	    (zhp = zfs_open(hdl, dataset, ZFS_TYPE_VOLUME)) == NULL)
		return (0);

	if (zfs_unshare_iscsi(zhp) != 0)
		return (-1);

	zfs_close(zhp);

	return (0);
}
Beispiel #24
0
static char *
get_zfs_dataset(sa_handle_impl_t impl_handle, char *path,
    boolean_t search_mnttab)
{
	size_t i, count = 0;
	zfs_handle_t **zlist;
	char *cutpath;
	zfs_handle_t *handle_from_path;
	char *ret = NULL;

	/*
	 * First we optimistically assume that the mount path for the filesystem
	 * is the same as the name of the filesystem (minus some number of
	 * leading slashes). If this is true, then zfs_open should properly open
	 * the filesystem. We duplicate the error checking done later in the
	 * function for consistency. If anything fails, we resort to the
	 * (extremely slow) search of all the filesystems.
	 */
	cutpath = path + strspn(path, "/");

	assert(impl_handle->zfs_libhandle != NULL);
	if ((handle_from_path = zfs_open(impl_handle->zfs_libhandle, cutpath,
	    ZFS_TYPE_FILESYSTEM)) != NULL)
		if ((ret = verify_zfs_handle(handle_from_path, path,
		    search_mnttab)) != NULL)
			return (ret);
	/*
	 * Couldn't find a filesystem optimistically, check all the handles we
	 * can.
	 */
	get_all_filesystems(impl_handle, &zlist, &count);
	for (i = 0; i < count; i++) {
		assert(zlist[i]);
		if ((ret = verify_zfs_handle(zlist[i], path,
		    search_mnttab)) != NULL)
			return (ret);
	}

	/* Couldn't find a matching dataset */
	return (NULL);
}
Beispiel #25
0
int
zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
	nvlist_t *nvl = zfs_get_clones_nvl(zhp);
	nvpair_t *pair;

	if (nvl == NULL)
		return (0);

	for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
	    pair = nvlist_next_nvpair(nvl, pair)) {
		zfs_handle_t *clone = zfs_open(zhp->zfs_hdl, nvpair_name(pair),
		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
		if (clone != NULL) {
			int err = func(clone, data);
			if (err != 0)
				return (err);
		}
	}
	return (0);
}
Beispiel #26
0
void Destroy::destroy(const std::string &name)
{
    if (m_verbose)
        std::cout << "    "
            << (m_dry_run ? "would destroy : " : "destroying    : ") << name
            << "\n";

    if (m_dry_run)
        return;

    zfs_handle_t *hzfs = zfs_open(m_hlib, name.c_str(), ZFS_TYPE_SNAPSHOT);

    if (!hzfs) {
        std::cerr << name << ": " << libzfs_error_description(m_hlib)
            << std::endl;
        return;
    }

    zfs_destroy(hzfs, m_defer ? B_TRUE : B_FALSE);

    zfs_close(hzfs);
}
Beispiel #27
0
/*
 * Insert the backup snapshot name into the path.
 *
 * Input:
 * 	name: Original path name.
 *
 * Output:
 * 	name: Original name modified to include a snapshot.
 *
 * Returns:
 * 	Original name modified to include a snapshot.
 */
char *
tlm_build_snapshot_name(char *name, char *sname, char *jname)
{
    zfs_handle_t *zhp;
    char *rest;
    char volname[ZFS_MAXNAMELEN];
    char mountpoint[PATH_MAX];

    if (get_zfsvolname(volname, ZFS_MAXNAMELEN, name) == -1)
        goto notzfs;

    (void) mutex_lock(&zlib_mtx);
    if ((zlibh == NULL) ||
            (zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == NULL) {
        (void) mutex_unlock(&zlib_mtx);
        goto notzfs;
    }

    if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, PATH_MAX, NULL,
                     NULL, 0, B_FALSE) != 0) {
        zfs_close(zhp);
        (void) mutex_unlock(&zlib_mtx);
        goto notzfs;
    }

    zfs_close(zhp);
    (void) mutex_unlock(&zlib_mtx);

    rest = name + strlen(mountpoint);
    (void) snprintf(sname, TLM_MAX_PATH_NAME, "%s/%s/%s%s", mountpoint,
                    TLM_SNAPSHOT_DIR, jname, rest);

    return (sname);

notzfs:
    (void) strlcpy(sname, name, TLM_MAX_PATH_NAME);
    return (sname);
}
Beispiel #28
0
static int
update_zfs_share(sa_share_impl_t impl_share, const char *proto)
{
	sa_handle_impl_t impl_handle = impl_share->handle;
	zfs_handle_t *zhp;
	update_cookie_t udata;

	if (impl_handle->zfs_libhandle == NULL)
			return (SA_SYSTEM_ERR);

	assert(impl_share->dataset != NULL);

	zhp = zfs_open(impl_share->handle->zfs_libhandle, impl_share->dataset,
	    ZFS_TYPE_FILESYSTEM);

	if (zhp == NULL)
		return (SA_SYSTEM_ERR);

	udata.handle = impl_handle;
	udata.proto = proto;
	(void) update_zfs_shares_cb(zhp, &udata);

	return (SA_OK);
}
Beispiel #29
0
/*
 * ndmp_has_backup_snapshot
 *
 * Returns TRUE if the volume has an active backup snapshot, otherwise,
 * returns FALSE.
 *
 * Parameters:
 *   volname (input) - name of the volume
 *
 * Returns:
 *   0: on success
 *  -1: otherwise
 */
static int
ndmp_has_backup_snapshot(char *volname, char *jobname)
{
	zfs_handle_t *zhp;
	snap_param_t snp;
	char chname[ZFS_MAXNAMELEN];

	(void) mutex_lock(&zlib_mtx);
	if ((zhp = zfs_open(zlibh, volname, ZFS_TYPE_DATASET)) == 0) {
		NDMP_LOG(LOG_ERR, "Cannot open snapshot %s.", volname);
		(void) mutex_unlock(&zlib_mtx);
		return (-1);
	}

	snp.snp_found = 0;
	(void) snprintf(chname, ZFS_MAXNAMELEN, "@%s", jobname);
	snp.snp_name = chname;

	(void) zfs_iter_snapshots(zhp, B_FALSE, ndmp_has_backup, &snp);
	zfs_close(zhp);
	(void) mutex_unlock(&zlib_mtx);

	return (snp.snp_found);
}
Beispiel #30
0
static char *
get_zfs_property(char *dataset, zfs_prop_t property)
{
	zfs_handle_t *handle = NULL;
	char shareopts[ZFS_MAXPROPLEN];
	libzfs_handle_t *libhandle;

	libhandle = libzfs_init();
	if (libhandle != NULL) {
		handle = zfs_open(libhandle, dataset, ZFS_TYPE_FILESYSTEM);
		if (handle != NULL) {
			if (zfs_prop_get(handle, property, shareopts,
			    sizeof (shareopts), NULL, NULL, 0,
			    B_FALSE) == 0) {
				zfs_close(handle);
				libzfs_fini(libhandle);
				return (strdup(shareopts));
			}
			zfs_close(handle);
		}
		libzfs_fini(libhandle);
	}
	return (NULL);
}