commands.c revision a99982a76d4cc12b1e9021e88531cf425d1e7369
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
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * Copyright 2007 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).
6185db853e024a486ff8837e6784dd290d866112dougm * add_list(list, item)
6185db853e024a486ff8837e6784dd290d866112dougm * Adds a new list member that points to item to the list.
6185db853e024a486ff8837e6784dd290d866112dougm * If list is NULL, it starts a new list. The function returns
6185db853e024a486ff8837e6784dd290d866112dougm * the first member of the list.
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];
6185db853e024a486ff8837e6784dd290d866112dougm /* since names are restricted to SA_MAX_NAME_LEN won't overflow */
6185db853e024a486ff8837e6784dd290d866112dougm /* make sure we have an authorization string property */
6185db853e024a486ff8837e6784dd290d866112dougm /* check if this user has one of the strings */
6185db853e024a486ff8837e6784dd290d866112dougm /* 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.
6185db853e024a486ff8837e6784dd290d866112dougm /* if not flags set, we assume we don't need authorizations */
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * enable_group(group, updateproto)
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)
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * disabling. Group has already been checked for non-NULL.
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * enable_all_groups(list, setstate, online, updateproto)
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * Given a list of groups, enable each one found. If updateproto
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * is not NULL, then update all the shares for the protocol that
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * was passed in.
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougmenable_all_groups(struct list *work, int setstate, int online,
6185db853e024a486ff8837e6784dd290d866112dougm char instance[SA_MAX_NAME_LEN + sizeof (SA_SVC_FMRI_BASE) + 1];
6185db853e024a486ff8837e6784dd290d866112dougm /* if itemdata != NULL then a single share */
6185db853e024a486ff8837e6784dd290d866112dougm ret = sa_enable_share((sa_share_t)work->itemdata, NULL);
6185db853e024a486ff8837e6784dd290d866112dougm "enabled");
6185db853e024a486ff8837e6784dd290d866112dougm /* if itemdata == NULL then the whole group */
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * if the share is managed by ZFS, don't
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * update any of the protocols since ZFS is
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * handling this. updateproto will contain
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * the name of the protocol that we want to
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm * update legacy files for.
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm enable_group(group, zfs == NULL ? updateproto : NULL);
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm for (subgroup = sa_get_sub_group(group); subgroup != NULL;
7d968cb8b4b6274092771b93e94bf88d1ee31c6cdougm /* 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) {
6185db853e024a486ff8837e6784dd290d866112dougm /* extract property/value pair */
6185db853e024a486ff8837e6784dd290d866112dougm 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 (void) printf(gettext("Could not add property %s: %s\n"),
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
6185db853e024a486ff8837e6784dd290d866112dougm "%s: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm " %s: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm /* there was a change */
6185db853e024a486ff8837e6784dd290d866112dougm /* should check to see if value changed */
6185db853e024a486ff8837e6784dd290d866112dougm "property %s: %s\n"),
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.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm "property: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "to be set with set-security: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_CREATE));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tgroup must be specified.\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_CREATE));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\textraneous group(s) at end\n"));
6185db853e024a486ff8837e6784dd290d866112dougm /* lookup default protocol */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_CREATE));
6185db853e024a486ff8837e6784dd290d866112dougm "with properties\n"));
6185db853e024a486ff8837e6784dd290d866112dougm "supported with create\n"));
6185db853e024a486ff8837e6784dd290d866112dougm * 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
6185db853e024a486ff8837e6784dd290d866112dougm /* group exists so must be a protocol add */
6185db853e024a486ff8837e6784dd290d866112dougm " with protocol %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm /* must add new protocol */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group already exists and no protocol"
6185db853e024a486ff8837e6784dd290d866112dougm " specified.\n"));
6185db853e024a486ff8837e6784dd290d866112dougm * is it a valid name? Must comply with SMF instance
6185db853e024a486ff8837e6784dd290d866112dougm * name restrictions.
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid group name: %s\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm /* check protocol vs optlist */
6185db853e024a486ff8837e6784dd290d866112dougm /* check options, if any, for validity */
6185db853e024a486ff8837e6784dd290d866112dougm for (i = 0; i < numprotos; i++) {
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and legal additions
6185db853e024a486ff8837e6784dd290d866112dougm * commit to configuration for protocols that
6185db853e024a486ff8837e6784dd290d866112dougm * need to do block updates. For NFS, this
6185db853e024a486ff8837e6784dd290d866112dougm * doesn't do anything but it will be run for
6185db853e024a486ff8837e6784dd290d866112dougm * all protocols that implement the
6185db853e024a486ff8837e6784dd290d866112dougm * appropriate plugin.
6185db853e024a486ff8837e6784dd290d866112dougm (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 return (enabled ? gettext("enabled") : gettext("disabled"));
6185db853e024a486ff8837e6784dd290d866112dougm * sa_delete(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Delete a group.
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvnP:fS:")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_DELETE));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tgroup must be specified.\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_DELETE));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\textraneous group(s) at end\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_DELETE));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tsecurity requires protocol to be "
6185db853e024a486ff8837e6784dd290d866112dougm "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
6185db853e024a486ff8837e6784dd290d866112dougm * need to do the disable of each
6185db853e024a486ff8837e6784dd290d866112dougm * share, but don't actually do
6185db853e024a486ff8837e6784dd290d866112dougm * anything on a dryrun.
6185db853e024a486ff8837e6784dd290d866112dougm /* commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* a protocol delete */
6185db853e024a486ff8837e6784dd290d866112dougm /* only delete specified security */
6185db853e024a486ff8837e6784dd290d866112dougm /* have an optionset with protocol to delete */
6185db853e024a486ff8837e6784dd290d866112dougm * now find all security sets for the protocol
6185db853e024a486ff8837e6784dd290d866112dougm * and remove them. Don't remove other
6185db853e024a486ff8837e6784dd290d866112dougm * protocols.
6185db853e024a486ff8837e6784dd290d866112dougm (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 *
6185db853e024a486ff8837e6784dd290d866112dougm /* 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.
6185db853e024a486ff8837e6784dd290d866112dougm * extract out the protocol type from this optionset
6185db853e024a486ff8837e6784dd290d866112dougm * and append it to the buffer "buff". strndupr() will
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_LIST));
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm if (protocol == NULL || has_protocol(group, protocol)) {
6185db853e024a486ff8837e6784dd290d866112dougm if (name != NULL && (verbose > 1 || name[0] != '#')) {
6185db853e024a486ff8837e6784dd290d866112dougm * need the list of protocols
6185db853e024a486ff8837e6784dd290d866112dougm * and current status once
6185db853e024a486ff8837e6784dd290d866112dougm * available.
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)
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(" %s=(", proto ? proto : gettext("all"));
6185db853e024a486ff8837e6784dd290d866112dougm (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)
6185db853e024a486ff8837e6784dd290d866112dougm for (security = sa_get_security(group, NULL, protocol);
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.
6185db853e024a486ff8837e6784dd290d866112dougm for (zgroup = sa_get_sub_group(group); zgroup != NULL;
6185db853e024a486ff8837e6784dd290d866112dougm show_group(zgroup, verbose, properties, proto, "zfs");
6185db853e024a486ff8837e6784dd290d866112dougm * have a group, so list the contents. Resource and
6185db853e024a486ff8837e6784dd290d866112dougm * description are only listed if verbose is set.
6185db853e024a486ff8837e6784dd290d866112dougm for (share = sa_get_share(group, NULL); share != NULL;
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.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_SHOW));
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm /* no group specified so go through them all */
6185db853e024a486ff8837e6784dd290d866112dougm * have a group so check if one we want and then list
6185db853e024a486ff8837e6784dd290d866112dougm * contents with appropriate options.
6185db853e024a486ff8837e6784dd290d866112dougm show_group(group, verbose, properties, protocol, NULL);
6185db853e024a486ff8837e6784dd290d866112dougm /* have a specified list of groups */
6185db853e024a486ff8837e6784dd290d866112dougm show_group(group, verbose, properties, protocol, NULL);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%s: not found\n"), argv[optind]);
6185db853e024a486ff8837e6784dd290d866112dougm * enable_share(group, share, update_legacy)
6185db853e024a486ff8837e6784dd290d866112dougm * helper function to enable a share if the group is enabled.
6185db853e024a486ff8837e6784dd290d866112dougmenable_share(sa_group_t group, sa_share_t share, int update_legacy)
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.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_addshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements add-share subcommand.
6185db853e024a486ff8837e6784dd290d866112dougm int persist = SA_SHARE_PERMANENT; /* default to persist */
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvns:d:r:t")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm * save share path into group. Currently limit
6185db853e024a486ff8837e6784dd290d866112dougm * to one share per command.
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
6185db853e024a486ff8837e6784dd290d866112dougm return (1);
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm if (dryrun || sharepath != NULL || description != NULL ||
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tgroup must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\t-s sharepath must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm /* check for valid syntax */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tresource must not contain white"
6185db853e024a486ff8837e6784dd290d866112dougm "space or '/' characters\n"));
6185db853e024a486ff8837e6784dd290d866112dougm "shared in group "
6185db853e024a486ff8837e6784dd290d866112dougm "\"%s\": %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "shared: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "shared\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * need to check that resource name is unique
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * at some point. Path checking should use the
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * "normal" rules which don't check the repository.
6185db853e024a486ff8837e6784dd290d866112dougm "resource",
6185db853e024a486ff8837e6784dd290d866112dougm /* now enable the share(s) */
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm "use: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "attribute: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * sa_moveshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements move-share subcommand.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm * remove share path from group. Currently limit
6185db853e024a486ff8837e6784dd290d866112dougm * to one share per command.
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tgroup must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tsharepath must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("sharepath must be specified with "
6185db853e024a486ff8837e6784dd290d866112dougm "the -s option\n"));
6185db853e024a486ff8837e6784dd290d866112dougm * note that the share may need to be
6185db853e024a486ff8837e6784dd290d866112dougm * "unshared" if the new group is
6185db853e024a486ff8837e6784dd290d866112dougm * disabled and the old was enabled or
6185db853e024a486ff8837e6784dd290d866112dougm * it may need to be share to update
6185db853e024a486ff8837e6784dd290d866112dougm * if the new group is enabled.
6185db853e024a486ff8837e6784dd290d866112dougm /* enable_share determines what to do */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_removeshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements remove-share subcommand.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm * remove share path from group. Currently limit
6185db853e024a486ff8837e6784dd290d866112dougm * to one share per command.
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\t-s sharepath must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Extraneous group(s) at end of "
6185db853e024a486ff8837e6784dd290d866112dougm "command\n"));
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * Lookup the path in the internal configuration. Care
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * must be taken to handle the case where the
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * underlying path has been removed since we need to
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * be able to deal with that as well.
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.
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * If there hasn't been an error, there was likely a
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * path found. If not, give the appropriate error
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * message and set the return error. If it was found,
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * then disable the share and then remove it from the
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * configuration.
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_set_share(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements set-share subcommand.
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hnd:r:s:")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm * save share path into group. Currently limit
6185db853e024a486ff8837e6784dd290d866112dougm * to one share per command.
6185db853e024a486ff8837e6784dd290d866112dougm "supported\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tgroup must be specified\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("\tExtraneous group(s) at end\n"));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" does not contain "
6185db853e024a486ff8837e6784dd290d866112dougm "share %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "white space or '/'\n"));
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not set attribute: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Share path \"%s\" not found\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * add_security(group, sectype, optlist, proto, *err)
6185db853e024a486ff8837e6784dd290d866112dougm * Helper function to add a security option (named optionset) to the
6185db853e024a486ff8837e6784dd290d866112dougm * add the property, but only if it is
6185db853e024a486ff8837e6784dd290d866112dougm * a non-NULL or non-zero length value
6185db853e024a486ff8837e6784dd290d866112dougm "property %s: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "property (%s=%s): %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * when done, properties may have all been removed but
6185db853e024a486ff8837e6784dd290d866112dougm * we need to keep the security type itself until
6185db853e024a486ff8837e6784dd290d866112dougm * explicitly removed.
6185db853e024a486ff8837e6784dd290d866112dougm * basic_set(groupname, optlist, protocol, sharepath, 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.
6185db853e024a486ff8837e6784dd290d866112dougmbasic_set(char *groupname, struct options *optlist, char *protocol,
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Share does not exist in group %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm /* group must exist */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and potentially legal additions
6185db853e024a486ff8837e6784dd290d866112dougm /* commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* properties changed, so update all shares */
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.
6185db853e024a486ff8837e6784dd290d866112dougmspace_set(char *groupname, struct options *optlist, char *protocol,
6185db853e024a486ff8837e6784dd290d866112dougm * make sure protcol and sectype are valid
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Option space \"%s\" not valid "
6185db853e024a486ff8837e6784dd290d866112dougm "for protocol.\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Share does not exist in group %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm /* group must exist */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not set property: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and potentially legal additions
6185db853e024a486ff8837e6784dd290d866112dougm /* commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* 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.
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvnP:p:s:S:")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("No memory to set property: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm if (optind >= argc || (optlist == NULL && optset == NULL) ||
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_SET));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sgroup must be specified"), sep);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sat least one property must be"
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sprotocol must be specified"), sep);
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm * remove_options(group, optlist, proto, *err)
6185db853e024a486ff8837e6784dd290d866112dougm * 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)
6185db853e024a486ff8837e6784dd290d866112dougm " 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,
6185db853e024a486ff8837e6784dd290d866112dougm " not set\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not unset %s: space not defined\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.
6185db853e024a486ff8837e6784dd290d866112dougm * basic_unset(groupname, optlist, protocol, sharepath, dryrun)
6185db853e024a486ff8837e6784dd290d866112dougm * unset non-named optionset properties.
6185db853e024a486ff8837e6784dd290d866112dougmbasic_unset(char *groupname, struct options *optlist, char *protocol,
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Share does not exist in group %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm /* group must exist */
6185db853e024a486ff8837e6784dd290d866112dougm /* if a share optionset is empty, remove it */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and potentially legal additions
6185db853e024a486ff8837e6784dd290d866112dougm /* commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* properties changed, so update all shares */
6185db853e024a486ff8837e6784dd290d866112dougm * space_unset(groupname, optlist, protocol, sharepath, dryrun)
6185db853e024a486ff8837e6784dd290d866112dougm * unset named optionset properties.
6185db853e024a486ff8837e6784dd290d866112dougmspace_unset(char *groupname, struct options *optlist, char *protocol,
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Share does not exist in group %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm ret = valid_unset_security(share != NULL ? share : group,
6185db853e024a486ff8837e6784dd290d866112dougm /* if a share security is empty, remove it */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not unset property: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Group \"%s\" not found\n"), groupname);
6185db853e024a486ff8837e6784dd290d866112dougm * we have a group and potentially legal additions
6185db853e024a486ff8837e6784dd290d866112dougm /* commit to configuration if not a dryrun */
6185db853e024a486ff8837e6784dd290d866112dougm /* properties changed, so update all shares */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_unset(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * implements the unset subcommand. Parsing done here and then basic
6185db853e024a486ff8837e6784dd290d866112dougm * or space versions of the real code are called.
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hvnP:p:s:S:")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm "property %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm " with set command: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm if (optind >= argc || (optlist == NULL && optset == NULL) ||
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_UNSET));
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sgroup must be specified"), sep);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sat least one property must be "
6185db853e024a486ff8837e6784dd290d866112dougm "specified"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("%sprotocol must be specified"), sep);
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_enable_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the enable subcommand
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_ENABLE));
6185db853e024a486ff8837e6784dd290d866112dougm /* already enabled */
6185db853e024a486ff8837e6784dd290d866112dougm "enabled\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "\"%s\"\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not enable group: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * disable_group(group, setstate)
6185db853e024a486ff8837e6784dd290d866112dougm * disable all the shares in the specified group honoring the setstate
6185db853e024a486ff8837e6784dd290d866112dougm * argument. This is a helper for disable_all_groups in order to
6185db853e024a486ff8837e6784dd290d866112dougm * simplify regular and subgroup (zfs) disabling. Group has already
6185db853e024a486ff8837e6784dd290d866112dougm * been checked for non-NULL.
6185db853e024a486ff8837e6784dd290d866112dougm * this is OK since the path is gone. we can't
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm /* need to get the sub-groups for stopping */
6185db853e024a486ff8837e6784dd290d866112dougm for (subgroup = sa_get_sub_group(group); subgroup != NULL;
6185db853e024a486ff8837e6784dd290d866112dougm * we don't want to "disable" since it won't come
6185db853e024a486ff8837e6784dd290d866112dougm * up after a reboot. The SMF framework should do
6185db853e024a486ff8837e6784dd290d866112dougm * the right thing. On enable we do want to do
6185db853e024a486ff8837e6784dd290d866112dougm * something.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_disable_group(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the disable subcommand
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm /* already disabled */
6185db853e024a486ff8837e6784dd290d866112dougm "already disabled\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "\"%s\"\n"),
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Could not disable group: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * check_sharetab()
6185db853e024a486ff8837e6784dd290d866112dougm * Checks to see if the /etc/dfs/sharetab file is stale (exists from
6185db853e024a486ff8837e6784dd290d866112dougm * before the current boot). If it is, truncate it since nothing is
6185db853e024a486ff8837e6784dd290d866112dougm * really shared.
6185db853e024a486ff8837e6784dd290d866112dougm if (fd >= 0) {
6185db853e024a486ff8837e6784dd290d866112dougm * Attempt to get a lock on the file. Whgen we get
6185db853e024a486ff8837e6784dd290d866112dougm * one, then check to see if it is older than the boot
6185db853e024a486ff8837e6784dd290d866112dougm * time. Truncate if older than boot.
6185db853e024a486ff8837e6784dd290d866112dougm if ((fstat(fd, &st) == 0) && /* does sharetab exist? */
6185db853e024a486ff8837e6784dd290d866112dougm (utmpxp = getutxent()) != NULL && /* does utmpx exist? */
6185db853e024a486ff8837e6784dd290d866112dougm (utmpxp->ut_xtime > st.st_mtime)) /* sharetab older? */
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
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm "\"%s\"\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * determine if there are any
6185db853e024a486ff8837e6784dd290d866112dougm * protocols. if there aren't any,
6185db853e024a486ff8837e6784dd290d866112dougm * then there isn't anything to do in
6185db853e024a486ff8837e6784dd290d866112dougm * any case so no error.
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
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("Invalid protocol specified: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf(gettext("usage: %s\n"), sa_get_usage(USAGE_STOP));
6185db853e024a486ff8837e6784dd290d866112dougm "\"%s\"\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * remove_all_options(share, proto)
6185db853e024a486ff8837e6784dd290d866112dougm * Removes all options on a share.
6185db853e024a486ff8837e6784dd290d866112dougm * we walk through the list. prevsec keeps the
6185db853e024a486ff8837e6784dd290d866112dougm * previous security so we can delete it without
6185db853e024a486ff8837e6784dd290d866112dougm * destroying the list.
6185db853e024a486ff8837e6784dd290d866112dougm /* remove the previously seen security */
6185db853e024a486ff8837e6784dd290d866112dougm /* set to NULL so we don't try multiple times */
6185db853e024a486ff8837e6784dd290d866112dougm * if the security matches the specified protocol, we
6185db853e024a486ff8837e6784dd290d866112dougm * want to remove it. prevsec holds it until either
6185db853e024a486ff8837e6784dd290d866112dougm * 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);
6185db853e024a486ff8837e6784dd290d866112dougm 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 if (S_ISREG(st.st_mode) && st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))
6185db853e024a486ff8837e6784dd290d866112dougm * run_legacy_command(proto, cmd, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * 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.
6185db853e024a486ff8837e6784dd290d866112dougm for (share = sa_get_share(group, NULL); share != NULL;
6185db853e024a486ff8837e6784dd290d866112dougm if (groupname != NULL && strcmp(groupname, "default") == 0) {
f345c0beb4c8f75cb54c2e070498e56febd468acdougm /* want the sharetab version if it exists */
f345c0beb4c8f75cb54c2e070498e56febd468acdougm /* 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.
6185db853e024a486ff8837e6784dd290d866112dougm * get default options preformated, being careful to
6185db853e024a486ff8837e6784dd290d866112dougm * handle legacy shares differently from new style
6185db853e024a486ff8837e6784dd290d866112dougm * shares. Legacy share have options on the share.
6185db853e024a486ff8837e6784dd290d866112dougm for (zgroup = sa_get_sub_group(group); zgroup != NULL;
6185db853e024a486ff8837e6784dd290d866112dougm /* got a group, so display it */
6185db853e024a486ff8837e6784dd290d866112dougm while ((c = getopt(argc, argv, "?hF:d:o:p")) != EOF) {
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm /* have the info so construct what is needed */
6185db853e024a486ff8837e6784dd290d866112dougm /* display current info in share format */
6185db853e024a486ff8837e6784dd290d866112dougm /* we are modifying the configuration */
6185db853e024a486ff8837e6784dd290d866112dougm /* if still using legacy share/unshare, exec it */
6185db853e024a486ff8837e6784dd290d866112dougm * 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
6185db853e024a486ff8837e6784dd290d866112dougm * isn't an error.
6185db853e024a486ff8837e6784dd290d866112dougm * if the share exists, then make sure it is one we
6185db853e024a486ff8837e6784dd290d866112dougm * want to handle.
6185db853e024a486ff8837e6784dd290d866112dougm share = sa_add_share(group, sharepath, persist, &ret);
6185db853e024a486ff8837e6784dd290d866112dougm /* could be a ZFS path being started */
6185db853e024a486ff8837e6784dd290d866112dougm /* this shouldn't happen */
6185db853e024a486ff8837e6784dd290d866112dougm * may want to change persist state, but the
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm * important thing is to change options. We
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm * need to change them regardless of the
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm /* have a group to hold this share path */
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm * zfs shares never have resource or
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm * description and we can't store the values
93a6f655de601ef9f8e8bfeca1b816fbfca6bc17dougm * so don't try.
6185db853e024a486ff8837e6784dd290d866112dougm (void) fprintf(stderr, gettext("Could not share: %s: %s\n"),
6185db853e024a486ff8837e6784dd290d866112dougm * sa_legacy_unshare(flags, argc, argv)
6185db853e024a486ff8837e6784dd290d866112dougm * Implements the original unshare command.
6185db853e024a486ff8837e6784dd290d866112dougm switch (c) {
6185db853e024a486ff8837e6784dd290d866112dougm /* have the info so construct what is needed */
6185db853e024a486ff8837e6784dd290d866112dougm /* 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.
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * Errors are ok and removal should still occur. The
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * legacy unshare is more forgiving of errors than the
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * remove-share subcommand which may need the force
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * flag set for some error conditions. That is, the
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * "unshare" command will always unshare if it can
a99982a76d4cc12b1e9021e88531cf425d1e7369dougm * while "remove-share" might require the force option.
6185db853e024a486ff8837e6784dd290d866112dougm switch (ret) {
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf("%s: %s\n", sharepath, sa_errorstr(ret));
6185db853e024a486ff8837e6784dd290d866112dougm * common commands that implement the sub-commands used by all
6185db853e024a486ff8837e6784dd290d866112dougm * protcols. 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 *
6185db853e024a486ff8837e6784dd290d866112dougm "[-d \"description text\"] -s sharepath group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("create [-nvh] [-P proto [-p property=value]] group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("move-share [-nvh] -s sharepath destination-group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("remove-share [-fnvh] -s sharepath group");
6185db853e024a486ff8837e6784dd290d866112dougm "[-p property=value]* [-s sharepath] group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("set-security [-nvh] -P proto -S security-type "
6185db853e024a486ff8837e6784dd290d866112dougm "[-p property=value]* group");
6185db853e024a486ff8837e6784dd290d866112dougm "[-d \"description text\"] -s sharepath group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("share [-F fstype] [-p] [-o optionlist]"
6185db853e024a486ff8837e6784dd290d866112dougm "[-d description] [pathname [resourcename]]");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("start [-vh] [-P proto] {-a | group ...}");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("stop [-vh] [-P proto] {-a | group ...}");
6185db853e024a486ff8837e6784dd290d866112dougm "[-p property]* group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("unset-security [-nvh] -P proto -S security-type "
6185db853e024a486ff8837e6784dd290d866112dougm "[-p property]* group");
6185db853e024a486ff8837e6784dd290d866112dougm ret = gettext("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.
6185db853e024a486ff8837e6784dd290d866112dougm return (&commands[i]);