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); }
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); }
/** * 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; }
/* * 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); }
/** * 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; }
/** * 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); }
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); }
/* * 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)); }
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); }
/* * 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; }
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); }