Beispiel #1
0
static void
update_sharetab(sa_handle_impl_t impl_handle)
{
	sa_share_impl_t impl_share;
	int temp_fd;
	FILE *temp_fp;
	char tempfile[] = ZFS_SHARETAB".XXXXXX";
	sa_fstype_t *fstype;
	const char *resource;

	if (mkdir("/etc/dfs", 0755) < 0 && errno != EEXIST) {
		return;
	}

	temp_fd = mkstemp(tempfile);

	if (temp_fd < 0)
		return;

	temp_fp = fdopen(temp_fd, "w");

	if (temp_fp == NULL)
		return;

	impl_share = impl_handle->shares;
	while (impl_share != NULL) {
		fstype = fstypes;
		while (fstype != NULL) {
			if (FSINFO(impl_share, fstype)->active &&
			    FSINFO(impl_share, fstype)->shareopts != NULL) {
				resource = FSINFO(impl_share, fstype)->resource;

				if (resource == NULL)
					resource = "-";

				fprintf(temp_fp, "%s\t%s\t%s\t%s\n",
				    impl_share->sharepath, resource,
				    fstype->name,
				    FSINFO(impl_share, fstype)->shareopts);
			}

			fstype = fstype->next;
		}

		impl_share = impl_share->next;
	}

	fflush(temp_fp);
	fsync(temp_fd);
	fclose(temp_fp);

	(void) rename(tempfile, ZFS_SHARETAB);
}
Beispiel #2
0
int
sa_disable_share(sa_share_t share, char *protocol)
{
	sa_share_impl_t impl_share = (sa_share_impl_t)share;
	int rc, ret = SA_OK;
	boolean_t found_protocol = B_FALSE;
	sa_fstype_t *fstype;

	fstype = fstypes;
	while (fstype != NULL) {
		if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
			rc = fstype->ops->disable_share(impl_share);

			if (rc == SA_OK) {
				fstype->ops->clear_shareopts(impl_share);

				FSINFO(impl_share, fstype)->active = B_FALSE;
			} else
				ret = rc;

			found_protocol = B_TRUE;
		}

		fstype = fstype->next;
	}

	update_sharetab(impl_share->handle);

	return (found_protocol ? ret : SA_INVALID_PROTOCOL);
}
Beispiel #3
0
/**
 * Enables NFS sharing for the specified share.
 */
static int
nfs_enable_share(sa_share_impl_t impl_share)
{
	char *shareopts, *linux_opts;
	int rc;

	if (!nfs_available()) {
		return SA_SYSTEM_ERR;
	}

	shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;

	if (shareopts == NULL)
		return SA_OK;

	rc = get_linux_shareopts(shareopts, &linux_opts);

	if (rc != SA_OK)
		return rc;

	rc = foreach_nfs_host(impl_share, nfs_enable_share_one, linux_opts);

	free(linux_opts);

	return rc;
}
Beispiel #4
0
Datei: smb.c Projekt: GeLiXin/zfs
/*
 * Called to update a share's options. A share's options might be out of
 * date if the share was loaded from disk and the "sharesmb" dataset
 * property has changed in the meantime. This function also takes care
 * of re-enabling the share if necessary.
 */
static int
smb_update_shareopts(sa_share_impl_t impl_share, const char *resource,
    const char *shareopts)
{
	char *shareopts_dup;
	boolean_t needs_reshare = B_FALSE;
	char *old_shareopts;

	if (!impl_share)
		return (SA_SYSTEM_ERR);

	FSINFO(impl_share, smb_fstype)->active =
	    smb_is_share_active(impl_share);

	old_shareopts = FSINFO(impl_share, smb_fstype)->shareopts;

	if (FSINFO(impl_share, smb_fstype)->active && old_shareopts != NULL &&
		strcmp(old_shareopts, shareopts) != 0) {
		needs_reshare = B_TRUE;
		smb_disable_share(impl_share);
	}

	shareopts_dup = strdup(shareopts);

	if (shareopts_dup == NULL)
		return (SA_NO_MEMORY);

	if (old_shareopts != NULL)
		free(old_shareopts);

	FSINFO(impl_share, smb_fstype)->shareopts = shareopts_dup;

	if (needs_reshare)
		smb_enable_share(impl_share);

	return (SA_OK);
}
Beispiel #5
0
/**
 * Called to update a share's options. A share's options might be out of
 * date if the share was loaded from disk (i.e. /etc/dfs/sharetab) and the
 * "sharenfs" dataset property has changed in the meantime. This function
 * also takes care of re-enabling the share if necessary.
 */
static int
nfs_update_shareopts(sa_share_impl_t impl_share, const char *resource,
    const char *shareopts)
{
	char *shareopts_dup;
	boolean_t needs_reshare = B_FALSE;
	char *old_shareopts;

	FSINFO(impl_share, nfs_fstype)->active = is_share_active(impl_share);

	old_shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;

	if (strcmp(shareopts, "on") == 0)
		shareopts = "rw";

	if (FSINFO(impl_share, nfs_fstype)->active && old_shareopts != NULL &&
	    strcmp(old_shareopts, shareopts) != 0) {
		needs_reshare = B_TRUE;
		nfs_disable_share(impl_share);
	}

	shareopts_dup = strdup(shareopts);

	if (shareopts_dup == NULL)
		return SA_NO_MEMORY;

	if (old_shareopts != NULL)
		free(old_shareopts);

	FSINFO(impl_share, nfs_fstype)->shareopts = shareopts_dup;

	if (needs_reshare)
		nfs_enable_share(impl_share);

	return SA_OK;
}
Beispiel #6
0
/**
 * Invokes a callback function for all NFS hosts that are set for a share.
 */
static int
foreach_nfs_host(sa_share_impl_t impl_share, nfs_host_callback_t callback,
    void *cookie)
{
	nfs_host_cookie_t udata;
	char *shareopts;

	udata.callback = callback;
	udata.sharepath = impl_share->sharepath;
	udata.cookie = cookie;
	udata.security = "sys";

	shareopts = FSINFO(impl_share, nfs_fstype)->shareopts;

	return foreach_nfs_shareopt(shareopts, foreach_nfs_host_cb,
	    &udata);
}
Beispiel #7
0
static void
free_share(sa_share_impl_t impl_share) {
	sa_fstype_t *fstype;

	fstype = fstypes;
	while (fstype != NULL) {
		fstype->ops->clear_shareopts(impl_share);

		free(FSINFO(impl_share, fstype)->resource);

		fstype = fstype->next;
	}

	free(impl_share->sharepath);
	free(impl_share->dataset);
	free(impl_share->fsinfo);
	free(impl_share);
}
Beispiel #8
0
Datei: smb.c Projekt: GeLiXin/zfs
/*
 * Enables SMB sharing for the specified share.
 */
static int
smb_enable_share(sa_share_impl_t impl_share)
{
	char *shareopts;

	if (!smb_available())
		return (SA_SYSTEM_ERR);

	shareopts = FSINFO(impl_share, smb_fstype)->shareopts;
	if (shareopts == NULL) /* on/off */
		return (SA_SYSTEM_ERR);

	if (strcmp(shareopts, "off") == 0)
		return (SA_OK);

	/* Magic: Enable (i.e., 'create new') share */
	return (smb_enable_share_one(impl_share->dataset,
	    impl_share->sharepath));
}
Beispiel #9
0
int
sa_enable_share(sa_share_t share, char *protocol)
{
	sa_share_impl_t impl_share = (sa_share_impl_t)share;
	int rc, ret;
	boolean_t found_protocol;
	sa_fstype_t *fstype;

#ifdef DEBUG
	fprintf(stderr, "sa_enable_share: share->sharepath=%s, protocol=%s\n",
		impl_share->sharepath, protocol);
#endif

	assert(impl_share->handle != NULL);

	ret = SA_OK;
	found_protocol = B_FALSE;

	fstype = fstypes;
	while (fstype != NULL) {
		if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
			update_zfs_share(impl_share, fstype->name);

			rc = fstype->ops->enable_share(impl_share);

			if (rc != SA_OK)
				ret = rc;
			else
				FSINFO(impl_share, fstype)->active = B_TRUE;

			found_protocol = B_TRUE;
		}

		fstype = fstype->next;
	}

	update_sharetab(impl_share->handle);

	return (found_protocol ? ret : SA_INVALID_PROTOCOL);
}
Beispiel #10
0
Datei: smb.c Projekt: GeLiXin/zfs
/*
 * Clears a share's SMB options. Used by libshare to
 * clean up shares that are about to be free()'d.
 */
static void
smb_clear_shareopts(sa_share_impl_t impl_share)
{
	free(FSINFO(impl_share, smb_fstype)->shareopts);
	FSINFO(impl_share, smb_fstype)->shareopts = NULL;
}
Beispiel #11
0
static int
process_share(sa_handle_impl_t impl_handle, sa_share_impl_t impl_share,
    char *pathname, char *resource, char *proto,
    char *options, char *description, char *dataset,
    boolean_t from_sharetab)
{
	struct stat statbuf;
	int rc;
	char *resource_dup = NULL, *dataset_dup = NULL;
	boolean_t new_share;
	sa_fstype_t *fstype;

	new_share = B_FALSE;

	if (impl_share == NULL)
		impl_share = find_share(impl_handle, pathname);

	if (impl_share == NULL) {
		if (lstat(pathname, &statbuf) != 0 ||
		    !S_ISDIR(statbuf.st_mode))
			return (SA_BAD_PATH);

		impl_share = alloc_share(pathname);

		if (impl_share == NULL) {
			rc = SA_NO_MEMORY;
			goto err;
		}

		new_share = B_TRUE;
	}

	if (dataset != NULL) {
		dataset_dup = strdup(dataset);

		if (dataset_dup == NULL) {
			rc = SA_NO_MEMORY;
			goto err;
		}
	}

	free(impl_share->dataset);
	impl_share->dataset = dataset_dup;

	rc = SA_INVALID_PROTOCOL;

	fstype = fstypes;
	while (fstype != NULL) {
		if (strcmp(fstype->name, proto) == 0) {
			if (resource != NULL) {
				resource_dup = strdup(resource);

				if (resource_dup == NULL) {
					rc = SA_NO_MEMORY;
					goto err;
				}
			}

			free(FSINFO(impl_share, fstype)->resource);
			FSINFO(impl_share, fstype)->resource = resource_dup;

			rc = fstype->ops->update_shareopts(impl_share,
			    resource, options);

			if (rc == SA_OK && from_sharetab)
				FSINFO(impl_share, fstype)->active = B_TRUE;

			break;
		}

		fstype = fstype->next;
	}

	if (rc != SA_OK)
		goto err;

	if (new_share) {
		impl_share->handle = impl_handle;

		impl_share->next = impl_handle->shares;
		impl_handle->shares = impl_share;

	}

err:
	if (rc != SA_OK) {
		if (new_share)
			free_share(impl_share);
	}

	return (rc);
}