commands.c revision 9e5da854b2fe0f3860a9b77dc30612faf2b0a42b
6185db853e024a486ff8837e6784dd290d866112dougm * CDDL HEADER START
6185db853e024a486ff8837e6784dd290d866112dougm * The contents of this file are subject to the terms of the
6185db853e024a486ff8837e6784dd290d866112dougm * Common Development and Distribution License (the "License").
6185db853e024a486ff8837e6784dd290d866112dougm * You may not use this file except in compliance with the License.
6185db853e024a486ff8837e6784dd290d866112dougm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6185db853e024a486ff8837e6784dd290d866112dougm * See the License for the specific language governing permissions
6185db853e024a486ff8837e6784dd290d866112dougm * and limitations under the License.
6185db853e024a486ff8837e6784dd290d866112dougm * When distributing Covered Code, include this CDDL HEADER in each
6185db853e024a486ff8837e6784dd290d866112dougm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6185db853e024a486ff8837e6784dd290d866112dougm * If applicable, add the following below this CDDL HEADER, with the
6185db853e024a486ff8837e6784dd290d866112dougm * fields enclosed by brackets "[]" replaced with your own identifying
6185db853e024a486ff8837e6784dd290d866112dougm * information: Portions Copyright [yyyy] [name of copyright owner]
6185db853e024a486ff8837e6784dd290d866112dougm * CDDL HEADER END
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
6185db853e024a486ff8837e6784dd290d866112dougm * Use is subject to license terms.
6185db853e024a486ff8837e6784dd290d866112dougm#pragma ident "%Z%%M% %I% %E% SMI"
6185db853e024a486ff8837e6784dd290d866112dougm * Implementation of the common sub-commands supported by sharemgr.
6185db853e024a486ff8837e6784dd290d866112dougm * A number of helper functions are also included.
6185db853e024a486ff8837e6784dd290d866112dougm * has_protocol(group, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * If the group has an optionset with the specified protocol,
6185db853e024a486ff8837e6784dd290d866112dougm * return true (1) otherwise false (0).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * validresource(name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check that name only has valid characters in it. The current valid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * set are the printable characters but not including:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * " / \ [ ] : | < > + ; , ? * = \t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Note that space is included and there is a maximum length.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *cp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * conv_to_utf8(input)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Convert the input string to utf8 from the current locale. If the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * conversion fails, use the current locale, it is likely close
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * enough. For example, the "C" locale is a subset of utf-8. The
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * return value may be a new string or the original input string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic char *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static int warned = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Assume worst case of characters expanding to 4 bytes. */
55bf511df53aad0fdb7eb3fa349f0308cc05234cas /* inval can be modified on return */
55bf511df53aad0fdb7eb3fa349f0308cc05234cas /* Need to return something. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * conv_from(input)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Convert the input string from utf8 to current locale. If the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * conversion isn't supported, just use as is. The return value may be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a new string or the original input string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic char *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static int warned = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Assume worst case of characters expanding to 4 bytes. */
55bf511df53aad0fdb7eb3fa349f0308cc05234cas /* Need to return something. */
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * print_rsrc_desc(resource, sharedesc)
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * Print the resource description string after converting from UTF8 to
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * the current locale. If sharedesc is not NULL and there is no
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * description on the resource, use sharedesc. sharedesc will already
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * be converted to UTF8.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
573b0c00a1ee520c3f6938dda8d693236f37ae60dougmprint_rsrc_desc(sa_resource_t resource, char *sharedesc)
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * set_resource_desc(share, description)
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * Set the share description value after converting the description
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * string to UTF8 from the current locale.
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * set_share_desc(share, description)
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * Set the resource description value after converting the description
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * string to UTF8 from the current locale.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * add_list(list, item, data, proto)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Adds a new list member that points holds item in the list.
6185db853e024a486ff8837e6784dd290d866112dougm * If list is NULL, it starts a new list. The function returns
6185db853e024a486ff8837e6784dd290d866112dougm * the first member of the list.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwadd_list(struct list *listp, void *item, void *data, char *proto)
6185db853e024a486ff8837e6784dd290d866112dougm for (tmp = listp; tmp->next != NULL; tmp = tmp->next) {
6185db853e024a486ff8837e6784dd290d866112dougm /* get to end of list */
6185db853e024a486ff8837e6784dd290d866112dougm * free_list(list)
6185db853e024a486ff8837e6784dd290d866112dougm * Given a list, free all the members of the list;
6185db853e024a486ff8837e6784dd290d866112dougm * check_authorization(instname, which)
6185db853e024a486ff8837e6784dd290d866112dougm * Checks to see if the specific type of authorization in which is
6185db853e024a486ff8837e6784dd290d866112dougm * enabled for the user in this SMF service instance.
6185db853e024a486ff8837e6784dd290d866112dougm char svcstring[SA_MAX_NAME_LEN + sizeof (SA_SVC_FMRI_BASE) + 1];
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Since names are restricted to SA_MAX_NAME_LEN won't
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * overflow.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) snprintf(svcstring, sizeof (svcstring), "%s:%s",
6185db853e024a486ff8837e6784dd290d866112dougm /* make sure we have an authorization string property */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* check if this user has one of the strings */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* no authorization string defined */
6185db853e024a486ff8837e6784dd290d866112dougm * check_authorizations(instname, flags)
6185db853e024a486ff8837e6784dd290d866112dougm * check all the needed authorizations for the user in this service
6185db853e024a486ff8837e6784dd290d866112dougm * instance. Return value of 1(true) or 0(false) indicates whether
6185db853e024a486ff8837e6784dd290d866112dougm * there are authorizations for the user or not.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* if not flags set, we assume we don't need authorizations */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * notify_or_enable_share(share, protocol)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Since some protocols don't want an "enable" when properties change,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * this function will use the protocol specific notify function
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * first. If that fails, it will then attempt to use the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sa_enable_share(). "protocol" is the protocol that was specified
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * on the command line.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* If really a resource, get parent share */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Now that we've got a share in "parent", make sure it has a path.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (protocol != NULL && strcmp(groupproto, protocol) != 0)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " share %s: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Must be a resource */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "reenable resource %s: "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * enable_group(group, updateproto, notify, proto)
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * enable all the shares in the specified group. This is a helper for
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * enable_all_groups in order to simplify regular and subgroup (zfs)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * enabling. Group has already been checked for non-NULL. If notify
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is non-zero, attempt to use the notify interface rather than
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwenable_group(sa_group_t group, char *updateproto, int notify, char *proto)
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * isenabled(group)
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * Returns B_TRUE if the group is enabled or B_FALSE if it isn't.
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * Moved to separate function to reduce clutter in the code.
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * enable_all_groups(list, setstate, online, updateproto)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Given a list of groups, enable each one found. If updateproto is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * not NULL, then update all the shares for the protocol that was
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * passed in. If enable is non-zero, tell enable_group to try the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * notify interface since this is a property change.
549ec3fff108310966327d1dc9004551b63210b7dougmenable_all_groups(sa_handle_t handle, struct list *work, int setstate,
6185db853e024a486ff8837e6784dd290d866112dougm char instance[SA_MAX_NAME_LEN + sizeof (SA_SVC_FMRI_BASE) + 1];
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * If setstate == TRUE, then make sure to set
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * enabled. This needs to be done here in order for
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * the isenabled check to succeed on a newly enabled
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * Check to see if group is enabled. If it isn't, skip
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * the rest. We don't want shares starting if the
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * group is disabled. The properties may have been
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * updated, but there won't be a change until the
330ef417fbd2286149a25e8033587edf7ae52ae5dougm * group is enabled.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* if itemdata != NULL then a single share */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* if itemdata == NULL then the whole group */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the share is managed by ZFS, don't
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * update any of the protocols since ZFS is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * handling this. Updateproto will contain
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * the name of the protocol that we want to
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * update legacy files for.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* never update legacy for ZFS subgroups */
6185db853e024a486ff8837e6784dd290d866112dougm * chk_opt(optlistp, security, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Do a sanity check on the optlist provided for the protocol. This
6185db853e024a486ff8837e6784dd290d866112dougm * is a syntax check and verification that the property is either a
6185db853e024a486ff8837e6784dd290d866112dougm * general or specific to a names optionset.
6185db853e024a486ff8837e6784dd290d866112dougmchk_opt(struct options *optlistp, int security, char *proto)
6185db853e024a486ff8837e6784dd290d866112dougm for (optlist = optlistp; optlist != NULL; optlist = optlist->next) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* extract property/value pair */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm * free_opt(optlist)
6185db853e024a486ff8837e6784dd290d866112dougm * Free the specified option list.
6185db853e024a486ff8837e6784dd290d866112dougm * check property list for valid properties
6185db853e024a486ff8837e6784dd290d866112dougm * A null value is a remove which is always valid.
6185db853e024a486ff8837e6784dd290d866112dougmvalid_options(struct options *optlist, char *proto, void *object, char *sec)
6185db853e024a486ff8837e6784dd290d866112dougm prop = sa_create_property(cur->optname, cur->optvalue);
6185db853e024a486ff8837e6784dd290d866112dougm (ret = sa_valid_property(parent, proto, prop)) != SA_OK) {
6185db853e024a486ff8837e6784dd290d866112dougm * add_optionset(group, optlist, protocol, *err)
6185db853e024a486ff8837e6784dd290d866112dougm * Add the options in optlist to an optionset and then add the optionset
6185db853e024a486ff8837e6784dd290d866112dougm * to the group.
6185db853e024a486ff8837e6784dd290d866112dougm * The return value indicates if there was a "change" while errors are
6185db853e024a486ff8837e6784dd290d866112dougm * returned via the *err parameters.
6185db853e024a486ff8837e6784dd290d866112dougmadd_optionset(sa_group_t group, struct options *optlist, char *proto, int *err)
6185db853e024a486ff8837e6784dd290d866112dougm * add the property, but only if it is
6185db853e024a486ff8837e6784dd290d866112dougm * a non-NULL or non-zero length value
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "not add property "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "%s: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not add property "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "%s: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* there was a change */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* should check to see if value changed */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * resource_compliant(group)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Go through all the shares in the group. Assume compliant, but if
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * any share doesn't have at least one resource name, it isn't
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * compliant.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fix_path(path)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * change all illegal characters to something else. For now, all get
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * converted to '_' and the leading '/' is stripped off. This is used
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to construct an resource name (SMB share name) that is valid.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Caller must pass a valid path.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* make sure we are appropriate length */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (cp != NULL && strlen(cp) > SA_MAX_RESOURCE_NAME) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* two cases - cp == NULL and cp is substring of path */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* just take last SA_MAX_RESOURCE_NAME chars */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Don't want any of the characters that are not allowed
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in and SMB share name. Replace them with '_'.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (*path) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (*path) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case '\\':
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case '\t':
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * name_adjust(path, count)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Add a ~<count> in place of last few characters. The total number of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * characters is dependent on count.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * make_resources(group)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Go through all the shares in the group and make them have resource
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Skip those with resources */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Cannot create resource name for"
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * check_valid_group(group, protocol)
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Check to see that the group should have the protocol added (if
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * there is one specified).
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougmcheck_valid_group(sa_group_t group, char *groupname, char *protocol)
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm "Group \"%s\" already exists"
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm "Group \"%s\" only allows protocol "
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm /* must add new protocol */
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm "Group already exists and no protocol "
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm "specified.\n"));
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * enforce_featureset(group, protocol, dryrun, force)
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Check the protocol featureset against the group and enforce any
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * rules that might be imposed.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougmenforce_featureset(sa_group_t group, char *protocol, boolean_t dryrun,
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * First check to see if specified protocol is one we want to
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * allow on a group. Only server protocols are allowed here.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm gettext("Protocol \"%s\" not supported.\n"), protocol);
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Check to see if the new protocol is one that requires
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * resource names and make sure we are compliant before
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * proceeding.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * set_all_protocols(group)
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Get the list of all protocols and add all server protocols to the
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Now make sure we really want to put this protocol on a
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * group. Only server protocols can go here.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm for (i = 0; i < numprotos; i++) {
6185db853e024a486ff8837e6784dd290d866112dougm * sa_create(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * create a new group
6185db853e024a486ff8837e6784dd290d866112dougm * this may or may not have a protocol associated with it.
6185db853e024a486ff8837e6784dd290d866112dougm * No protocol means "all" protocols in this case.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_create(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (ret) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Property syntax error for property: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Security properties need "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "to be set with set-security: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\tgroup must be specified.\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\textraneous group(s) at end\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* lookup default protocol */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "with properties\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "supported with create\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If a group already exists, we can only add a new protocol
6185db853e024a486ff8837e6784dd290d866112dougm * to it and not create a new one or add the same protocol
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* group exists so must be a protocol add */
6185db853e024a486ff8837e6784dd290d866112dougm * is it a valid name? Must comply with SMF instance
6185db853e024a486ff8837e6784dd290d866112dougm * name restrictions.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* check protocol vs optlist */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* check options, if any, for validity */
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * Check group and protocol against featureset
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * requirements.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * So far so good. Now add the required
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm * optionset(s) to the group.
9e5da854b2fe0f3860a9b77dc30612faf2b0a42bdougm /* default group create so add all protocols */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We have a group and legal additions
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Commit to configuration for protocols that
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * need to do block updates. For NFS, this
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * doesn't do anything but it will be run for
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * all protocols that implement the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * appropriate plugin.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Could not create group: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * group_status(group)
6185db853e024a486ff8837e6784dd290d866112dougm * return the current status (enabled/disabled) of the group.
6185db853e024a486ff8837e6784dd290d866112dougmstatic char *
6185db853e024a486ff8837e6784dd290d866112dougm * sa_delete(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Delete a group.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_delete(sa_handle_t handle, int flags, int argc, char *argv[])
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvnP:fS:")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "multiple protocols "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "multiple property "
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\tgroup must be specified.\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\textraneous group(s) at end\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\tsecurity requires protocol to be "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "specified.\n"));
6185db853e024a486ff8837e6784dd290d866112dougm * Determine if the group already exists since it must in
6185db853e024a486ff8837e6784dd290d866112dougm * order to be removed.
6185db853e024a486ff8837e6784dd290d866112dougm * We can delete when:
6185db853e024a486ff8837e6784dd290d866112dougm * - group is empty
6185db853e024a486ff8837e6784dd290d866112dougm * - force flag is set
6185db853e024a486ff8837e6784dd290d866112dougm * - if protocol specified, only delete the protocol
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * need to do the disable of
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * each share, but don't
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * actually do anything on a
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* a protocol delete */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* only delete specified security */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * have an optionset with
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * protocol to delete
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Now find all security sets
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * for the protocol and remove
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * them. Don't remove other
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * protocols.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * With the protocol items removed, make sure that all
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the shares are updated in the legacy files, if
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Could not delete group: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * strndupr(*buff, str, buffsize)
6185db853e024a486ff8837e6784dd290d866112dougm * used with small strings to duplicate and possibly increase the
6185db853e024a486ff8837e6784dd290d866112dougm * buffer size of a string.
6185db853e024a486ff8837e6784dd290d866112dougmstatic char *
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* if it fails, fail it hard */
6185db853e024a486ff8837e6784dd290d866112dougm * group_proto(group)
6185db853e024a486ff8837e6784dd290d866112dougm * return a string of all the protocols (space separated) associated
6185db853e024a486ff8837e6784dd290d866112dougm * with this group.
6185db853e024a486ff8837e6784dd290d866112dougmstatic char *
6185db853e024a486ff8837e6784dd290d866112dougm * get the protocol list by finding the optionsets on this
6185db853e024a486ff8837e6784dd290d866112dougm * group and extracting the type value. The initial call to
6185db853e024a486ff8837e6784dd290d866112dougm * strndupr() initailizes buff.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * extract out the protocol type from this optionset
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * and append it to the buffer "buff". strndupr() will
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * reallocate space as necessay.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_list(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements the "list" subcommand to list groups and optionally
6185db853e024a486ff8837e6784dd290d866112dougm * their state and protocols.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_list(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "not supported: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (protocol == NULL || has_protocol(group, protocol)) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (name != NULL && (verbose > 1 || name[0] != '#')) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Need the list of protocols
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * and current status once
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * available. We do want to
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * translate the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * enabled/disabled text here.
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm * out_properties(optionset, proto, sec)
6185db853e024a486ff8837e6784dd290d866112dougm * Format the properties and encode the protocol and optional named
6185db853e024a486ff8837e6784dd290d866112dougm * optionset into the string.
6185db853e024a486ff8837e6784dd290d866112dougm * format is protocol[:name]=(property-list)
6185db853e024a486ff8837e6784dd290d866112dougmout_properties(sa_optionset_t optionset, char *proto, char *sec)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(" %s=(", proto ? proto : gettext("all"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(" %s:%s=(", proto ? proto : gettext("all"), sec);
6185db853e024a486ff8837e6784dd290d866112dougm for (spacer = 0, prop = sa_get_property(optionset, NULL);
6185db853e024a486ff8837e6784dd290d866112dougm * extract the property name/value and output with
6185db853e024a486ff8837e6784dd290d866112dougm * appropriate spacing. I.e. no prefixed space the
6185db853e024a486ff8837e6784dd290d866112dougm * first time through but a space on subsequent
6185db853e024a486ff8837e6784dd290d866112dougm * properties.
6185db853e024a486ff8837e6784dd290d866112dougm * show_properties(group, protocol, prefix)
6185db853e024a486ff8837e6784dd290d866112dougm * print the properties for a group. If protocol is NULL, do all
6185db853e024a486ff8837e6784dd290d866112dougm * protocols otherwise only the specified protocol. All security
6185db853e024a486ff8837e6784dd290d866112dougm * (named groups specific to the protocol) are included.
6185db853e024a486ff8837e6784dd290d866112dougm * The "prefix" is always applied. The caller knows whether it wants
6185db853e024a486ff8837e6784dd290d866112dougm * some type of prefix string (white space) or not. Once the prefix
6185db853e024a486ff8837e6784dd290d866112dougm * has been output, it is reduced to the zero length string for the
6185db853e024a486ff8837e6784dd290d866112dougm * remainder of the property output.
6185db853e024a486ff8837e6784dd290d866112dougmshow_properties(sa_group_t group, char *protocol, char *prefix)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm for (security = sa_get_security(group, NULL, protocol);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * get_resource(share)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Get the first resource name, if any, and fix string to be in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * current locale and have quotes if it has embedded spaces. Return
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * an attr string that must be freed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic char *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((resource = sa_get_share_resource(share, NULL)) != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* account for quotes */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * has_resource_with_opt(share)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check to see if the share has any resource names with optionsets
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * set. Also indicate if multiple resource names since the syntax
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * would be about the same.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * has_multiple_resource(share)
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * Check to see if the share has multiple resource names since
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * the syntax would be about the same.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (num = 0, resource = sa_get_share_resource(share, NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * show_share(share, verbose, properties, proto, iszfs, sharepath)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * print out the share information. With the addition of resource as a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * full object that can have multiple instances below the share, we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * need to display that as well.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwshow_share(sa_share_t share, int verbose, int properties, char *proto,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* First, indicate if transient */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we came in with verbose, we want to handle the case of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * multiple resources as though they had properties set.
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * if there is a description on the share and there
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * are resources, treat as multiple resources in order
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * to get all descriptions displayed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Next, if not multiple follow old model */
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm /* Print the description string if there is one. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Treat as simple and then resources come later */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If there are resource names with options, show them
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * here, with one line per resource. Resource specific
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * options are at the end of the line followed by
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * description, if any.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Get description string if any */
6185db853e024a486ff8837e6784dd290d866112dougm * show_group(group, verbose, properties, proto, subgroup)
6185db853e024a486ff8837e6784dd290d866112dougm * helper function to show the contents of a group.
6185db853e024a486ff8837e6784dd290d866112dougmshow_group(sa_group_t group, int verbose, int properties, char *proto,
6185db853e024a486ff8837e6784dd290d866112dougm * check to see if the group is managed by ZFS. If
6185db853e024a486ff8837e6784dd290d866112dougm * there is an attribute, then it is. A non-NULL zfs
6185db853e024a486ff8837e6784dd290d866112dougm * variable will trigger the different way to display
6185db853e024a486ff8837e6784dd290d866112dougm * and will remove the transient property indicator
6185db853e024a486ff8837e6784dd290d866112dougm * from the output.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have a group, so list the contents. Resource and
6185db853e024a486ff8837e6784dd290d866112dougm * description are only listed if verbose is set.
6185db853e024a486ff8837e6784dd290d866112dougm * show_group_xml_init()
6185db853e024a486ff8837e6784dd290d866112dougm * Create an XML document that will be used to display config info via
6185db853e024a486ff8837e6784dd290d866112dougm * XML format.
6185db853e024a486ff8837e6784dd290d866112dougm * show_group_xml(doc, group)
6185db853e024a486ff8837e6784dd290d866112dougm * Copy the group info into the XML doc.
6185db853e024a486ff8837e6784dd290d866112dougm * In the future, we may have interally used tags that
6185db853e024a486ff8837e6784dd290d866112dougm * should not appear in the XML output. Remove
6185db853e024a486ff8837e6784dd290d866112dougm * anything we don't want to show here.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_show(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the show subcommand.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_show(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "not supported: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* No group specified so go through them all */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have a group so check if one we want and then list
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * contents with appropriate options.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Have a specified list of groups */
6185db853e024a486ff8837e6784dd290d866112dougm * enable_share(group, share, update_legacy)
6185db853e024a486ff8837e6784dd290d866112dougm * helper function to enable a share if the group is enabled.
549ec3fff108310966327d1dc9004551b63210b7dougmenable_share(sa_handle_t handle, sa_group_t group, sa_share_t share,
6185db853e024a486ff8837e6784dd290d866112dougm * need to enable this share if the group is enabled but not
6185db853e024a486ff8837e6784dd290d866112dougm * otherwise. The enable is also done on each protocol
6185db853e024a486ff8837e6784dd290d866112dougm * represented in the group.
6185db853e024a486ff8837e6784dd290d866112dougm enabled = value != NULL && strcmp(value, "enabled") == 0;
6185db853e024a486ff8837e6784dd290d866112dougm /* remove legacy config if necessary */
6185db853e024a486ff8837e6784dd290d866112dougm * Step through each optionset at the group level and
6185db853e024a486ff8837e6784dd290d866112dougm * enable the share based on the protocol type. This
6185db853e024a486ff8837e6784dd290d866112dougm * works because protocols must be set on the group
6185db853e024a486ff8837e6784dd290d866112dougm * for the protocol to be enabled.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Failed to enable share for "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\"%s\": %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we want to update the legacy, use a copy of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share so we can avoid breaking the loop we are in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * since we might also need to go up the tree to the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sa_require_resource(group)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if any of the defined protocols on the group require resource
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * names, then all shares must have them.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_addshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements add-share subcommand.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_addshare(sa_handle_t handle, int flags, int argc, char *argv[])
6185db853e024a486ff8837e6784dd290d866112dougm int persist = SA_SHARE_PERMANENT; /* default to persist */
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvns:d:r:t")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "resource names not"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " supported\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Save share path into group. Currently limit
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to one share per command.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Adding multiple shares not supported\n"));
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (dryrun || sharepath != NULL || description != NULL ||
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\tgroup must be specified\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "\t-s sharepath must be specified\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "is not valid: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* check for valid syntax */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Resource names must be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unique in the system
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\tresource names must be unique "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "in the system\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\tresource names use restricted "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "character set\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Can only have a duplicate share if a new
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * resource name is being added.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Resource name is required "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "by at least one enabled protocol "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "in group\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Make sure this isn't an attempt to put a resourced
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share into a different group than it already is in.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Share path already "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not add share: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* now enable the share(s) */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (ret) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Resource name in"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "use: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Could not set "
6185db853e024a486ff8837e6784dd290d866112dougm "attribute: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Command would fail: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm * sa_moveshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements move-share subcommand.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_moveshare(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Moving multiple resource names not"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " supported\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Remove share path from group. Currently limit
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to one share per command.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " not supported\n"));
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "\tsharepath must be specified\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "sharepath must be specified with the -s "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "option\n"));
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * If a share wasn't found, it may have been a symlink
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * or has a trailing '/'. Try again after resolving
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm * with realpath().
573b0c00a1ee520c3f6938dda8d693236f37ae60dougm "is not valid: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Note that the share may need to be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "unshared" if the new group is disabled and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the old was enabled or it may need to be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share to update if the new group is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * enabled. We disable before the move and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will have to enable after the move in order
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to cleanup entries for protocols that
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * aren't in the new group.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* enable_share determines what to do */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Reenable and update any config information.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_removeshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements remove-share subcommand.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_removeshare(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Remove share path from group. Currently limit
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to one share per command.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Removing multiple shares not "
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Remove share from group if last resource or remove
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * resource from share if multiple resources.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Removing multiple resource names not "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "supported\n"));
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (optind >= argc || (rsrcname == NULL && sharepath == NULL)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " must be specified\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Extraneous group(s) at end of "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "command\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Resource name not found for share: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Lookup the path in the internal configuration. Care
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * must be taken to handle the case where the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * underlying path has been removed since we need to
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * be able to deal with that as well.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Bad resource name for share: %s\n"),
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * If we didn't find the share with the provided path,
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * it may be a symlink so attempt to resolve it using
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * realpath and try again. Realpath will resolve any
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * symlinks and place them in "dir". Note that
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * sharepath is only used for the lookup the first
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * time and later for error messages. dir will be used
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * on the second attempt. Once a share is found, all
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * operations are based off of the share variable.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If there hasn't been an error, there was likely a
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * path found. If not, give the appropriate error
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * message and set the return error. If it was found,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * then disable the share and then remove it from the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * configuration.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We don't care if it fails since it
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * could be disabled already. Some
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * unexpected errors could occur that
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * prevent removal, so also check for
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * force being set.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If this was the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * last one, remove
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the share as well.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Command would fail: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * sa_set_share(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements set-share subcommand.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_set_share(sa_handle_t handle, int flags, int argc, char *argv[])
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hnd:r:s:")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Update share by resource name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Updating multiple resource names not "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "supported\n"));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Save share path into group. Currently limit
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to one share per command.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Updating multiple shares not "
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (optind >= argc && sharepath == NULL && rsrcname == NULL) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("\tgroup must be specified\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) printf(gettext("\tExtraneous group(s) at end\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Must have at least one of sharepath and rsrcrname.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * It is a syntax error to be missing both.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If rsrcname exists, split rename syntax and then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * convert to utf 8 if no errors.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "share %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the user has set a description, it will be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * on the resource if -r was used otherwise it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * must be on the share.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (ret) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Command would fail: %s\n"),
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm * add_security(group, sectype, optlist, proto, *err)
6185db853e024a486ff8837e6784dd290d866112dougm * Helper function to add a security option (named optionset) to the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Add the property, but only if it is
6185db853e024a486ff8837e6784dd290d866112dougm * a non-NULL or non-zero length value
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not add "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "property %s: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not add "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "property (%s=%s):"
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * When done, properties may have all been removed but
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * we need to keep the security type itself until
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * explicitly removed.
f8825440532850af4790bbc685223958d4042844dougm * zfscheck(group, share)
f8825440532850af4790bbc685223958d4042844dougm * For the special case where a share was provided, make sure it is a
f8825440532850af4790bbc685223958d4042844dougm * compatible path for a ZFS property change. The only path
f8825440532850af4790bbc685223958d4042844dougm * acceptable is the path that defines the zfs sub-group (dataset with
f8825440532850af4790bbc685223958d4042844dougm * the sharenfs property set) and not one of the paths that inherited
f8825440532850af4790bbc685223958d4042844dougm * the NFS properties. Returns SA_OK if it is usable and
f8825440532850af4790bbc685223958d4042844dougm * SA_NOT_ALLOWED if it isn't.
f8825440532850af4790bbc685223958d4042844dougm * If group is not a ZFS group/subgroup, we assume OK since the check
f8825440532850af4790bbc685223958d4042844dougm * on return will catch errors for those cases. What we are looking
f8825440532850af4790bbc685223958d4042844dougm * for here is that the group is ZFS and the share is not the defining
f8825440532850af4790bbc685223958d4042844dougm * share. All else is SA_OK.
f8825440532850af4790bbc685223958d4042844dougm * The group is a ZFS group. Does the share represent
f8825440532850af4790bbc685223958d4042844dougm * the dataset that defined the group? It is only OK
f8825440532850af4790bbc685223958d4042844dougm * if the attribute "subgroup" exists on the share and
f8825440532850af4790bbc685223958d4042844dougm * has a value of "true".
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * basic_set(groupname, optlist, protocol, sharepath, rsrcname, dryrun)
6185db853e024a486ff8837e6784dd290d866112dougm * This function implements "set" when a name space (-S) is not
6185db853e024a486ff8837e6784dd290d866112dougm * specified. It is a basic set. Options and other CLI parsing has
6185db853e024a486ff8837e6784dd290d866112dougm * already been done.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "rsrcname" is a "resource name". If it is non-NULL, it must match
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the sharepath if present or group if present, otherwise it is used
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to set options.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Resource names may take options if the protocol supports it. If the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * protocol doesn't support resource level options, rsrcname is just
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * an alias for the share.
549ec3fff108310966327d1dc9004551b63210b7dougmbasic_set(sa_handle_t handle, char *groupname, struct options *optlist,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *protocol, char *sharepath, char *rsrcname, int dryrun)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If there is a sharepath, make sure it belongs to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the group.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Share does not exist in group %s\n"),
f8825440532850af4790bbc685223958d4042844dougm /* if ZFS and OK, then only group */
f8825440532850af4790bbc685223958d4042844dougm "Properties on ZFS group shares "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If a resource name exists, make sure it belongs to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the share if present else it belongs to the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * group. Also check the protocol to see if it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * supports resource level properties or not. If not,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * use share only.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check to see if the resource can take
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * properties. If so, stick the resource into
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "share" so it will all just work.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* group must exist */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and potentially legal additions
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Commit to configuration if not a dryrunp and properties
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * have changed.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (!dryrun && ret == SA_OK && change && worklist != NULL)
6185db853e024a486ff8837e6784dd290d866112dougm /* properties changed, so update all shares */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) enable_all_groups(handle, worklist, 0, 0, protocol,
6185db853e024a486ff8837e6784dd290d866112dougm * space_set(groupname, optlist, protocol, sharepath, dryrun)
6185db853e024a486ff8837e6784dd290d866112dougm * This function implements "set" when a name space (-S) is
6185db853e024a486ff8837e6784dd290d866112dougm * specified. It is a namespace set. Options and other CLI parsing has
6185db853e024a486ff8837e6784dd290d866112dougm * already been done.
549ec3fff108310966327d1dc9004551b63210b7dougmspace_set(sa_handle_t handle, char *groupname, struct options *optlist,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *protocol, char *sharepath, int dryrun, char *sectype)
6185db853e024a486ff8837e6784dd290d866112dougm * make sure protcol and sectype are valid
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Option space \"%s\" not valid "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Share does not exist in group %s\n"),
f8825440532850af4790bbc685223958d4042844dougm /* if ZFS and OK, then only group */
f8825440532850af4790bbc685223958d4042844dougm "Properties on ZFS group shares "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* group must exist */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not set property: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * We have a group and potentially legal additions.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Commit to configuration if not a dryrun */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* properties changed, so update all shares */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_set(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the set subcommand. It keys off of -S to determine which
6185db853e024a486ff8837e6784dd290d866112dougm * set of operations to actually do.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_set(sa_handle_t handle, int flags, int argc, char *argv[])
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while ((c = getopt(argc, argv, "?hvnP:p:r:s:S:")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (ret) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Setting multiple resource names not"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw " supported\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Setting multiple shares not supported\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple property "
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
6185db853e024a486ff8837e6784dd290d866112dougm if (optind >= argc || (optlist == NULL && optset == NULL) ||
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_SET));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("%sat least one property must be"
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("%sprotocol must be specified"),
f8825440532850af4790bbc685223958d4042844dougm * Group already exists so we can proceed after a few
f8825440532850af4790bbc685223958d4042844dougm * additional checks related to ZFS handling.
f8825440532850af4790bbc685223958d4042844dougm (void) printf(gettext("Changing properties for group "
f8825440532850af4790bbc685223958d4042844dougm "\"zfs\" not allowed\n"));
6185db853e024a486ff8837e6784dd290d866112dougm * remove_options(group, optlist, proto, *err)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Helper function to actually remove options from a group after all
6185db853e024a486ff8837e6784dd290d866112dougm * preprocessing is done.
6185db853e024a486ff8837e6784dd290d866112dougmremove_options(sa_group_t group, struct options *optlist,
6185db853e024a486ff8837e6784dd290d866112dougm * valid_unset(group, optlist, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Sanity check the optlist to make sure they can be removed. Issue an
6185db853e024a486ff8837e6784dd290d866112dougm * error if a property doesn't exist.
6185db853e024a486ff8837e6784dd290d866112dougmvalid_unset(sa_group_t group, struct options *optlist, char *proto)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not unset property %s: not set\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * valid_unset_security(group, optlist, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Sanity check the optlist to make sure they can be removed. Issue an
6185db853e024a486ff8837e6784dd290d866112dougm * error if a property doesn't exist.
6185db853e024a486ff8837e6784dd290d866112dougmvalid_unset_security(sa_group_t group, struct options *optlist, char *proto,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not unset property %s: not set\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * remove_security(group, optlist, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Remove the properties since they were checked as valid.
6185db853e024a486ff8837e6784dd290d866112dougm * when done, properties may have all been removed but
6185db853e024a486ff8837e6784dd290d866112dougm * we need to keep the security type itself until
6185db853e024a486ff8837e6784dd290d866112dougm * explicitly removed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * basic_unset(groupname, optlist, protocol, sharepath, rsrcname, dryrun)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Unset non-named optionset properties.
549ec3fff108310966327d1dc9004551b63210b7dougmbasic_unset(sa_handle_t handle, char *groupname, struct options *optlist,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *protocol, char *sharepath, char *rsrcname, int dryrun)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If there is a sharepath, make sure it belongs to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the group.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Share does not exist in group %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If a resource name exists, make sure it belongs to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the share if present else it belongs to the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * group. Also check the protocol to see if it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * supports resource level properties or not. If not,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * use share only.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check to see if the resource can take
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * properties. If so, stick the resource into
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "share" so it will all just work.
6185db853e024a486ff8837e6784dd290d866112dougm /* group must exist */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If a share optionset is
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * empty, remove it.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Could not remove properties: "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) printf(gettext("Group \"%s\" not found\n"), groupname);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We have a group and potentially legal additions
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Commit to configuration if not a dryrun
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* properties changed, so update all shares */
6185db853e024a486ff8837e6784dd290d866112dougm * space_unset(groupname, optlist, protocol, sharepath, dryrun)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Unset named optionset properties.
549ec3fff108310966327d1dc9004551b63210b7dougmspace_unset(sa_handle_t handle, char *groupname, struct options *optlist,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *protocol, char *sharepath, int dryrun, char *sectype)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Share does not exist in group %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = valid_unset_security(share != NULL ? share : group,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* If a share security is empty, remove it */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Could not unset property: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We have a group and potentially legal additions
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* properties changed, so update all shares */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_unset(flags, argc, argv)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Implements the unset subcommand. Parsing done here and then basic
6185db853e024a486ff8837e6784dd290d866112dougm * or space versions of the real code are called.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_unset(sa_handle_t handle, int flags, int argc, char *argv[])
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while ((c = getopt(argc, argv, "?hvnP:p:r:s:S:")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (ret) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Unset properties on resource if applicable or on
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share if resource for this protocol doesn't use
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * resources.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Unsetting multiple resource "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "names not supported\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Adding multiple shares not supported\n"));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple property "
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
6185db853e024a486ff8837e6784dd290d866112dougm if (optind >= argc || (optlist == NULL && optset == NULL) ||
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("%sprotocol must be specified"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If a group already exists, we can only add a new
6185db853e024a486ff8837e6784dd290d866112dougm * protocol to it and not create a new one or add the
6185db853e024a486ff8837e6784dd290d866112dougm * same protocol again.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = basic_unset(handle, groupname, optlist, protocol,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = space_unset(handle, groupname, optlist, protocol,
6185db853e024a486ff8837e6784dd290d866112dougm * sa_enable_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the enable subcommand
549ec3fff108310966327d1dc9004551b63210b7dougmsa_enable_group(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* already enabled */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Group \"%s\" is already "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "enabled\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Enabling group \"%s\"\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = enable_all_groups(handle, worklist, 1, 0, NULL, B_FALSE);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not enable group: %s\n"),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * disable_group(group, proto)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Disable all the shares in the specified group.. This is a helper
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * for disable_all_groups in order to simplify regular and subgroup
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (zfs) disabling. Group has already been checked for non-NULL.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the protocol isn't enabled, skip it and treat as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * successful.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * this is OK since the path is gone. we can't
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * re-share it anyway so no error.
6185db853e024a486ff8837e6784dd290d866112dougm * disable_all_groups(work, setstate)
6185db853e024a486ff8837e6784dd290d866112dougm * helper function that disables the shares in the list of groups
6185db853e024a486ff8837e6784dd290d866112dougm * provided. It optionally marks the group as disabled. Used by both
6185db853e024a486ff8837e6784dd290d866112dougm * enable and start subcommands.
549ec3fff108310966327d1dc9004551b63210b7dougmdisable_all_groups(sa_handle_t handle, struct list *work, int setstate)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* need to get the sub-groups for stopping */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We don't want to "disable" since it won't come
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * up after a reboot. The SMF framework should do
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * the right thing. On enable we do want to do
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * something.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_disable_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the disable subcommand
549ec3fff108310966327d1dc9004551b63210b7dougmsa_disable_group(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* already disabled */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Group \"%s\" is "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "already disabled\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Disabling group "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf(gettext("Could not disable group: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * sa_start_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the start command.
6185db853e024a486ff8837e6784dd290d866112dougm * This is similar to enable except it doesn't change the state
6185db853e024a486ff8837e6784dd290d866112dougm * of the group(s) and only enables shares if the group is already
549ec3fff108310966327d1dc9004551b63210b7dougmsa_start_group(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Starting group \"%s\"\n"),
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Determine if there are any
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * protocols. If there aren't any,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * then there isn't anything to do in
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * any case so no error.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) enable_all_groups(handle, worklist, 0, 1, protocol, B_FALSE);
6185db853e024a486ff8837e6784dd290d866112dougm * sa_stop_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the stop command.
6185db853e024a486ff8837e6784dd290d866112dougm * This is similar to disable except it doesn't change the state
6185db853e024a486ff8837e6784dd290d866112dougm * of the group(s) and only disables shares if the group is already
549ec3fff108310966327d1dc9004551b63210b7dougmsa_stop_group(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Specifying multiple protocols "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: %s\n"),
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm } else if (!all) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Stopping group \"%s\"\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * remove_all_options(share, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Removes all options on a share.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We walk through the list. prevsec keeps the
6185db853e024a486ff8837e6784dd290d866112dougm * previous security so we can delete it without
6185db853e024a486ff8837e6784dd290d866112dougm * destroying the list.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* remove the previously seen security */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* set to NULL so we don't try multiple times */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * if the security matches the specified protocol, we
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * want to remove it. prevsec holds it until either
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * the next pass or we fall out of the loop.
6185db853e024a486ff8837e6784dd290d866112dougm /* in case there is one left */
6185db853e024a486ff8837e6784dd290d866112dougm * for legacy support, we need to handle the old syntax. This is what
6185db853e024a486ff8837e6784dd290d866112dougm * we get if sharemgr is called with the name "share" rather than
6185db853e024a486ff8837e6784dd290d866112dougm * sharemgr.
6185db853e024a486ff8837e6784dd290d866112dougmformat_legacy_path(char *buff, int buffsize, char *proto, char *cmd)
6185db853e024a486ff8837e6784dd290d866112dougm err = snprintf(buff, buffsize, "/usr/lib/fs/%s/%s", proto, cmd);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm return (-1);
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm * check_legacy_cmd(proto, cmd)
6185db853e024a486ff8837e6784dd290d866112dougm * Check to see if the cmd exists in /usr/lib/fs/<proto>/<cmd> and is
6185db853e024a486ff8837e6784dd290d866112dougm * executable.
6185db853e024a486ff8837e6784dd290d866112dougm * run_legacy_command(proto, cmd, argv)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * We know the command exists, so attempt to execute it with all the
6185db853e024a486ff8837e6784dd290d866112dougm * arguments. This implements full legacy share support for those
6185db853e024a486ff8837e6784dd290d866112dougm * protocols that don't have plugin providers.
6185db853e024a486ff8837e6784dd290d866112dougm if (ret < 0) {
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * out_share(out, group, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Display the share information in the format that the "share"
6185db853e024a486ff8837e6784dd290d866112dougm * command has traditionally used.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The original share command defaulted to displaying NFS
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * shares or allowed a protocol to be specified. We want to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * skip those shares that are not the specified protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (proto != NULL && sa_get_optionset(group, proto) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * get the default property string. NFS uses "rw" but
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * everything else will use "".
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (groupname != NULL && strcmp(groupname, "default") == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Want the sharetab version if it exists, defaulting
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to NFS if no protocol specified.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) snprintf(shareopts, MAXNAMLEN, "shareopts-%s", proto);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* only active shares go here */
6185db853e024a486ff8837e6784dd290d866112dougm * output_legacy_file(out, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Walk all of the groups for the specified protocol and call
6185db853e024a486ff8837e6784dd290d866112dougm * out_share() to format and write in the format displayed by the
6185db853e024a486ff8837e6784dd290d866112dougm * "share" command with no arguments.
549ec3fff108310966327d1dc9004551b63210b7dougmoutput_legacy_file(FILE *out, char *proto, sa_handle_t handle)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Go through all the groups and ZFS
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sub-groups. out_share() will format the shares in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the group appropriately.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* got a group, so display it */
549ec3fff108310966327d1dc9004551b63210b7dougmsa_legacy_share(sa_handle_t handle, int flags, int argc, char *argv[])
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hF:d:o:p")) != EOF) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid protocol specified: "
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Have the info so construct what is needed */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* display current info in share format */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* We are modifying the configuration */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* If still using legacy share/unshare, exec it */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * The legacy group is always present and zfs groups
6185db853e024a486ff8837e6784dd290d866112dougm * come and go. zfs shares may be in sub-groups and
6185db853e024a486ff8837e6784dd290d866112dougm * the zfs share will already be in that group so it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * isn't an error. If the protocol is "smb", the group
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "smb" is used when "default" would otherwise be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * used. "default" is NFS only and "smb" is SMB only.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If the share exists (not NULL), then make sure it
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * is one we want to handle by getting the parent
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This group may not exist, so create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * as necessary. It only contains the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "smb" protocol.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Could be a ZFS path being started
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This shouldn't
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * May want to change persist state, but the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * important thing is to change options. We
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * need to change them regardless of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If there is a resource name, we may
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * actually care about it if this is share for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a protocol that uses resource level sharing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (SMB). We need to find the resource and, if
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * it exists, make sure it belongs to the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * current share. If it doesn't exist, attempt
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to create it.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Have a group to hold this share path */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ZFS shares never have a description
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and we can't store the values so
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * don't try.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) fprintf(stderr, gettext("Could not share: %s: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * sa_legacy_unshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the original unshare command.
549ec3fff108310966327d1dc9004551b63210b7dougmsa_legacy_unshare(sa_handle_t handle, int flags, int argc, char *argv[])
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (c) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "Invalid file system name\n"));
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /* optopt on valid arg isn't defined */
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm /*FALLTHROUGH*/
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * Since a bad option gets to here, sort it
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * out and return a syntax error return value
e7bab3470ba5677ff5feec7af706721cfebcd6d5dougm * if necessary.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Have the info so construct what is needed */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (optind == argc || (optind + 1) < argc || options != NULL) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* if still using legacy share/unshare, exec it */
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * Find the path in the internal configuration. If it
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * isn't found, attempt to resolve the path via
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * realpath() and try again.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Could be a resource name so check that next */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we still have a resource on the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share, we don't disable the share
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * itself. IF there aren't anymore, we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * need to remove the share. The
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * removal will be done in the next
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * section if appropriate.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Didn't find path and no resource */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Errors are ok and removal should still occur. The
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * legacy unshare is more forgiving of errors than the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * remove-share subcommand which may need the force
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * flag set for some error conditions. That is, the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * "unshare" command will always unshare if it can
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * while "remove-share" might require the force option.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (ret == SA_OK && share == NULL && resource == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If both share and resource are NULL, then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * share not found. If one or the other was
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * found or there was an earlier error, we
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * assume it was handled earlier.
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm (void) printf("%s: %s\n", sharepath, sa_errorstr(ret));
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Common commands that implement the sub-commands used by all
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * protocols. The entries are found via the lookup command
6185db853e024a486ff8837e6784dd290d866112dougm {"add-share", 0, sa_addshare, USAGE_ADD_SHARE, SVC_SET},
6185db853e024a486ff8837e6784dd290d866112dougm {"create", 0, sa_create, USAGE_CREATE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"delete", 0, sa_delete, USAGE_DELETE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"disable", 0, sa_disable_group, USAGE_DISABLE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"enable", 0, sa_enable_group, USAGE_ENABLE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"move-share", 0, sa_moveshare, USAGE_MOVE_SHARE, SVC_SET},
6185db853e024a486ff8837e6784dd290d866112dougm {"remove-share", 0, sa_removeshare, USAGE_REMOVE_SHARE, SVC_SET},
6185db853e024a486ff8837e6784dd290d866112dougm {"set-share", 0, sa_set_share, USAGE_SET_SHARE, SVC_SET},
6185db853e024a486ff8837e6784dd290d866112dougm {"share", 0, sa_legacy_share, USAGE_SHARE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"stop", CMD_NODISPLAY, sa_stop_group, USAGE_STOP, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougm {"unshare", 0, sa_legacy_unshare, USAGE_UNSHARE, SVC_SET|SVC_ACTION},
6185db853e024a486ff8837e6784dd290d866112dougmstatic char *
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "[-d \"description text\"] -s sharepath group");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "create [-nvh] [-P proto [-p property=value]] group");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "move-share [-nvh] -s sharepath destination-group");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "remove-share [-fnvh] {-s sharepath | -r resource} "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "[-p property=value]* [-s sharepath] [-r resource]] "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = gettext("set-security [-nvh] -P proto -S security-type "
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "[-p property=value]* group");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "[-d \"description text\"] -s sharepath group");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = gettext("share [-F fstype] [-p] [-o optionlist]"
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "[-d description] [pathname [resourcename]]");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = gettext("start [-vh] [-P proto] {-a | group ...}");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm ret = gettext("stop [-vh] [-P proto] {-a | group ...}");
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "[-p property]* group");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "-S security-type [-p property]* group");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "unshare [-F fstype] [-p] [-o optionlist] sharepath");
6185db853e024a486ff8837e6784dd290d866112dougm * sa_lookup(cmd, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Lookup the sub-command. proto isn't currently used, but it may
6185db853e024a486ff8837e6784dd290d866112dougm * eventually provide a way to provide protocol specific sub-commands.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm return (&commands[i]);