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
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
6185db853e024a486ff8837e6784dd290d866112dougm * Use is subject to license terms.
6185db853e024a486ff8837e6784dd290d866112dougm/* helper functions for using libscf with sharemgr */
549ec3fff108310966327d1dc9004551b63210b7dougmextern sa_handle_impl_t get_handle_for_root(xmlNodePtr);
6185db853e024a486ff8837e6784dd290d866112dougm * The SMF facility uses some properties that must exist. We want to
6185db853e024a486ff8837e6784dd290d866112dougm * skip over these when processing protocol options.
6185db853e024a486ff8837e6784dd290d866112dougm "modify_authorization",
6185db853e024a486ff8837e6784dd290d866112dougm "action_authorization",
6185db853e024a486ff8837e6784dd290d866112dougm "value_authorization",
6185db853e024a486ff8837e6784dd290d866112dougm * sa_scf_fini(handle)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Must be called when done. Called with the handle allocated in
6185db853e024a486ff8837e6784dd290d866112dougm * sa_scf_init(), it cleans up the state and frees any SCF resources
6185db853e024a486ff8837e6784dd290d866112dougm * still in use. Called by sa_fini().
6185db853e024a486ff8837e6784dd290d866112dougm * sa_scf_init()
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Must be called before using any of the SCF functions. Called by
6185db853e024a486ff8837e6784dd290d866112dougm * sa_init() during the API setup.
6185db853e024a486ff8837e6784dd290d866112dougm scf_max_name_len = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH);
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf("libshare could not access SMF repository: %s\n",
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Make sure we have sufficient SMF running */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm handle->instance = scf_instance_create(handle->handle);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (handle->scope == NULL || handle->service == NULL ||
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm defgrp = sa_create_group((sa_handle_t)ihandle, "default", NULL);
1f29d134f841501a6ae1c2be035dd0647720537cdougm /* Only NFS enabled for "default" group. */
6185db853e024a486ff8837e6784dd290d866112dougm (void) printf("libshare SMF initialization problem: %s\n",
6185db853e024a486ff8837e6784dd290d866112dougm * get_scf_limit(name)
6185db853e024a486ff8837e6784dd290d866112dougm * Since we use scf_limit a lot and do the same check and return the
6185db853e024a486ff8837e6784dd290d866112dougm * same value if it fails, implement as a function for code
6185db853e024a486ff8837e6784dd290d866112dougm * simplification. Basically, if name isn't found, return MAXPATHLEN
6185db853e024a486ff8837e6784dd290d866112dougm * (1024) so we have a reasonable default buffer size.
6185db853e024a486ff8837e6784dd290d866112dougm * skip_property(name)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Internal function to check to see if a property is an SMF magic
6185db853e024a486ff8837e6784dd290d866112dougm * property that needs to be skipped.
6185db853e024a486ff8837e6784dd290d866112dougm return (1);
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm * generate_unique_sharename(sharename)
6185db853e024a486ff8837e6784dd290d866112dougm * Shares are represented in SMF as property groups. Due to share
6185db853e024a486ff8837e6784dd290d866112dougm * paths containing characters that are not allowed in SMF names and
6185db853e024a486ff8837e6784dd290d866112dougm * the need to be unique, we use UUIDs to construct a unique name.
6185db853e024a486ff8837e6784dd290d866112dougm * valid_protocol(proto)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Check to see if the specified protocol is a valid one for the
6185db853e024a486ff8837e6784dd290d866112dougm * general sharemgr facility. We determine this by checking which
6185db853e024a486ff8837e6784dd290d866112dougm * plugin protocols were found.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (strcmp(proto, plugin->plugin_ops->sa_protocol) == 0)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm return (1);
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
6185db853e024a486ff8837e6784dd290d866112dougm * sa_extract_pgroup(root, handle, pg, nodetype, proto, sectype)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Extract the name property group and create the specified type of
6185db853e024a486ff8837e6784dd290d866112dougm * node on the provided group. type will be optionset or security.
6185db853e024a486ff8837e6784dd290d866112dougmsa_extract_pgroup(xmlNodePtr root, scfutilhandle_t *handle,
6185db853e024a486ff8837e6784dd290d866112dougm node = xmlNewChild(root, NULL, (xmlChar *)nodetype, NULL);
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"type", (xmlChar *)proto);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have node to work with so iterate over the properties
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * in the pg and create option sub nodes.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Want to iterate through the properties and add them
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to the base optionset.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Now iterate the properties in the group */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* have a property */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Some properties are part of the framework */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Since in SMF, don't
6185db853e024a486ff8837e6784dd290d866112dougm * recurse. Use xmlAddChild
6185db853e024a486ff8837e6784dd290d866112dougm * directly, instead.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* cleanup to avoid memory leaks */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_extract_attrs(root, handle, instance)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Local function to extract the actual attributes/properties from the
6185db853e024a486ff8837e6784dd290d866112dougm * property group of the service instance. These are the well known
6185db853e024a486ff8837e6784dd290d866112dougm * attributes of "state" and "zfs". If additional attributes are
6185db853e024a486ff8837e6784dd290d866112dougm * added, they should be added here.
6185db853e024a486ff8837e6784dd290d866112dougmsa_extract_attrs(xmlNodePtr root, scfutilhandle_t *handle,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (prop == NULL || value == NULL || valuestr == NULL ||
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm scf_instance_get_pg(instance, "operation", handle->pg) != 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have a property group with desired name so now get
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * the known attributes.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_pg_get_property(handle->pg, "state", prop) == 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Found the property so get the value */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_pg_get_property(handle->pg, "zfs", prop) == 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Found the property so get the value */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * List of known share attributes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "drive-letter",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "exclude",
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm return (1);
6185db853e024a486ff8837e6784dd290d866112dougm return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * _sa_make_resource(node, valuestr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Make a resource node on the share node. The valusestr will either
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * be old format (SMF acceptable string) or new format (pretty much an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * arbitrary string with "nnn:" prefixing in order to persist
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * mapping). The input valuestr will get modified in place. This is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * only used in SMF repository parsing. A possible third field will be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a "description" string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* this is old form so give an index of "0" */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* NUL the ':' and move past it */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* There could also be a description string */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node = xmlNewChild(node, NULL, (xmlChar *)"resource", NULL);
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"name", (xmlChar *)name);
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"id", (xmlChar *)idx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* SMF values are always persistent */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) xmlNewChild(node, NULL, (xmlChar *)"description",
6185db853e024a486ff8837e6784dd290d866112dougm * sa_share_from_pgroup
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Extract the share definition from the share property group. We do
6185db853e024a486ff8837e6784dd290d866112dougm * some sanity checking to avoid bad data.
6185db853e024a486ff8837e6784dd290d866112dougm * Since this is only constructing the internal data structures, we
6185db853e024a486ff8837e6784dd290d866112dougm * don't use the sa_* functions most of the time.
6185db853e024a486ff8837e6784dd290d866112dougmsa_share_from_pgroup(xmlNodePtr root, scfutilhandle_t *handle,
6185db853e024a486ff8837e6784dd290d866112dougm * While preliminary check (starts with 'S') passed before
6185db853e024a486ff8837e6784dd290d866112dougm * getting here. Need to make sure it is in ID syntax
6185db853e024a486ff8837e6784dd290d866112dougm * (Snnnnnn). Note that shares with properties have similar
6185db853e024a486ff8837e6784dd290d866112dougm if (*id == SA_SHARE_PG_PREFIX[0] && vallen == SA_SHARE_PG_LEN) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Construct the share XML node. It is similar to sa_add_share
6185db853e024a486ff8837e6784dd290d866112dougm * but never changes the repository. Also, there won't be any
6185db853e024a486ff8837e6784dd290d866112dougm * ZFS or transient shares. Root will be the group it is
6185db853e024a486ff8837e6784dd290d866112dougm * associated with.
6185db853e024a486ff8837e6784dd290d866112dougm node = xmlNewChild(root, NULL, (xmlChar *)"share", NULL);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Make sure the UUID part of the property group is
6185db853e024a486ff8837e6784dd290d866112dougm * stored in the share "id" property. We use this
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"id", (xmlChar *)id);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (iter == NULL || value == NULL || prop == NULL || name == NULL)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Iterate over the share pg properties */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_property_get_name(prop, name, scf_max_name_len) > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check that we have the "path" property in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * name. The string in name will always be nul
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * terminated if scf_property_get_name()
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * succeeded.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If a share attr, then simple -
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * usually path and id name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Resource names handled differently since
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * there can be multiple on each share. The
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "resource" id must be preserved since this
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will be used by some protocols in mapping
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * "property spaces" to names and is always
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * used to create SMF property groups specific
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to resources. CIFS needs this. The first
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * value is present so add and then loop for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * any additional. Since this is new and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * previous values may exist, handle
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * conversions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Have a value so process it */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* have a ustring */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* have an astring */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* We have a description node */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * A share without a path is broken so we want to not include
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * these. They shouldn't happen but if you kill a sharemgr in
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * the process of creating a share, it could happen. They
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * should be harmless. It is also possible that another
f345c0beb4c8f75cb54c2e070498e56febd468acdougm * sharemgr is running and in the process of creating a share.
6185db853e024a486ff8837e6784dd290d866112dougm * find_share_by_id(shareid)
6185db853e024a486ff8837e6784dd290d866112dougm * Search all shares in all groups until we find the share represented
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * find_resource_by_index(share, index)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Search the resource records on the share for the id index.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw id = (char *)xmlGetProp((xmlNodePtr)resource, (xmlChar *)"id");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* found it so save in "found" */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sa_share_props_from_pgroup(root, handle, pg, id, sahandle)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Extract share properties from the SMF property group. More sanity
6185db853e024a486ff8837e6784dd290d866112dougm * checks are done and the share object is created. We ignore some
6185db853e024a486ff8837e6784dd290d866112dougm * errors that could exist in the repository and only worry about
6185db853e024a486ff8837e6784dd290d866112dougm * property groups that validate in naming.
6185db853e024a486ff8837e6784dd290d866112dougmsa_share_props_from_pgroup(xmlNodePtr root, scfutilhandle_t *handle,
549ec3fff108310966327d1dc9004551b63210b7dougm scf_propertygroup_t *pg, char *id, sa_handle_t sahandle)
6185db853e024a486ff8837e6784dd290d866112dougm * While preliminary check (starts with 'S') passed before
6185db853e024a486ff8837e6784dd290d866112dougm * getting here. Need to make sure it is in ID syntax
6185db853e024a486ff8837e6784dd290d866112dougm * (Snnnnnn). Note that shares with properties have similar
6185db853e024a486ff8837e6784dd290d866112dougm * pgroups. If the pg name is more than SA_SHARE_PG_LEN
6185db853e024a486ff8837e6784dd290d866112dougm * characters, it is likely one of the protocol/security
6185db853e024a486ff8837e6784dd290d866112dougm * versions.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (*id != SA_SHARE_PG_PREFIX[0] || vallen <= SA_SHARE_PG_LEN) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * It is ok to not have what we thought since someone might
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * have added a name via SMF.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (strncmp(id, SA_SHARE_PG_PREFIX, SA_SHARE_PG_PREFIXLEN) == 0) {
6185db853e024a486ff8837e6784dd290d866112dougm * probably a legal optionset so check a few more
6185db853e024a486ff8837e6784dd290d866112dougm * syntax points below.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* not a valid proto (null) */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * To get here, we have a valid protocol and possibly a
6185db853e024a486ff8837e6784dd290d866112dougm * security. We now have to find the share that it is really
6185db853e024a486ff8837e6784dd290d866112dougm * associated with. The "id" portion of the pgroup name will
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm node = xmlNewChild(root, NULL, (xmlChar *)"optionset", NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If sectype[0] is a digit, then it is an index into
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the resource names. We need to find a resource
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * record and then get the properties into an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * optionset. The optionset becomes the "node" and the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * rest is hung off of the share.
55bf511df53aad0fdb7eb3fa349f0308cc05234cas /* This shouldn't happen. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If not a digit, then it is a security type
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (alternate option space). Security types start with
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * an alphabetic.
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"type", (xmlChar *)proto);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* now find the properties */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (iter == NULL || value == NULL || prop == NULL || name == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* iterate over the share pg properties */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_extract_group(root, handle, instance)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Get the config info for this instance of a group and create the XML
6185db853e024a486ff8837e6784dd290d866112dougm * subtree from it.
6185db853e024a486ff8837e6784dd290d866112dougmsa_extract_group(xmlNodePtr root, scfutilhandle_t *handle,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_instance_get_name(instance, buff, scf_max_name_len) > 0) {
6185db853e024a486ff8837e6784dd290d866112dougm node = xmlNewChild(root, NULL, (xmlChar *)"group", NULL);
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp(node, (xmlChar *)"name", (xmlChar *)buff);
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Iterate through all the property groups
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * looking for those with security or
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * optionset prefixes. The names of the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * matching pgroups are parsed to get the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * protocol, and for security, the sectype.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Syntax is as follows:
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * optionset | optionset_<proto>
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * security_default | security_<proto>_<sectype>
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * "operation" is handled by
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * sa_extract_attrs().
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Have a pgroup so sort it out */
1f29d134f841501a6ae1c2be035dd0647720537cdougm /* Have an optionset */
1f29d134f841501a6ae1c2be035dd0647720537cdougm * This can only occur if
1f29d134f841501a6ae1c2be035dd0647720537cdougm * someone has made changes
1f29d134f841501a6ae1c2be035dd0647720537cdougm * via an SMF command. Since
1f29d134f841501a6ae1c2be035dd0647720537cdougm * this would be an unknown
1f29d134f841501a6ae1c2be035dd0647720537cdougm * syntax, we just ignore it.
1f29d134f841501a6ae1c2be035dd0647720537cdougm * If the group is not "default" or is
1f29d134f841501a6ae1c2be035dd0647720537cdougm * "default" and is_nfs, then extract the
1f29d134f841501a6ae1c2be035dd0647720537cdougm * pgroup. If it is_default and !is_nfs,
1f29d134f841501a6ae1c2be035dd0647720537cdougm * then we have an error and should remove
1f29d134f841501a6ae1c2be035dd0647720537cdougm * the extraneous protocols. We don't care
1f29d134f841501a6ae1c2be035dd0647720537cdougm * about errors on scf_pg_delete since we
1f29d134f841501a6ae1c2be035dd0647720537cdougm * might not have permission during an
1f29d134f841501a6ae1c2be035dd0647720537cdougm * extract only.
1f29d134f841501a6ae1c2be035dd0647720537cdougm "Removed protocol \"%s\" "
1f29d134f841501a6ae1c2be035dd0647720537cdougm "from group \"default\"\n"),
1f29d134f841501a6ae1c2be035dd0647720537cdougm * Have a security (note that
1f29d134f841501a6ae1c2be035dd0647720537cdougm * this should change in the
1f29d134f841501a6ae1c2be035dd0647720537cdougm /* Ignore everything else */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Make sure we have a valid default group.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * On first boot, default won't have any
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * protocols defined and won't be enabled (but
1f29d134f841501a6ae1c2be035dd0647720537cdougm * should be). "default" only has NFS enabled on it.
6185db853e024a486ff8837e6784dd290d866112dougm /* set attribute to enabled */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Do a second pass if shares were found */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (have_shares && scf_iter_instance_pgs(iter, instance) == 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have a pgroup so see if it is a
6185db853e024a486ff8837e6784dd290d866112dougm * share optionset
6185db853e024a486ff8837e6784dd290d866112dougm * sa_extract_defaults(root, handle, instance)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Local function to find the default properties that live in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * default instance's "operation" property group.
6185db853e024a486ff8837e6784dd290d866112dougmsa_extract_defaults(xmlNodePtr root, scfutilhandle_t *handle,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm scf_instance_get_pg(instance, "operation", handle->pg) != 0)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_pg_get_property(handle->pg, "legacy-timestamp", prop) != 0)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Found the property so get the value */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_value_get_astring(value, valuestr, vallen) > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sa_get_config(handle, root, doc, sahandle)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Walk the SMF repository for /network/shares/group and find all the
6185db853e024a486ff8837e6784dd290d866112dougm * instances. These become group names. Then add the XML structure
6185db853e024a486ff8837e6784dd290d866112dougm * below the groups based on property groups and properties.
1d1813a7a7c570174c2b6adc372045307b266117dougmsa_get_config(scfutilhandle_t *handle, xmlNodePtr root, sa_handle_t sahandle)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm sizeof (buff)) > 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Always cleanup these */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_get_instance(handle, instance)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Get the instance of the group service. This is actually the
6185db853e024a486ff8837e6784dd290d866112dougm * specific group name. The instance is needed for all property and
6185db853e024a486ff8837e6784dd290d866112dougm * control operations.
6185db853e024a486ff8837e6784dd290d866112dougmsa_get_instance(scfutilhandle_t *handle, char *instname)
6185db853e024a486ff8837e6784dd290d866112dougm if (scf_service_get_instance(handle->service, instname,
6185db853e024a486ff8837e6784dd290d866112dougm * sa_create_instance(handle, instname)
6185db853e024a486ff8837e6784dd290d866112dougm * Create a new SMF service instance. There can only be one with a
6185db853e024a486ff8837e6784dd290d866112dougm * given name.
6185db853e024a486ff8837e6784dd290d866112dougmsa_create_instance(scfutilhandle_t *handle, char *instname)
6185db853e024a486ff8837e6784dd290d866112dougm if (scf_service_add_instance(handle->service, instname,
6185db853e024a486ff8837e6784dd290d866112dougm /* better error returns need to be added based on real error */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* have the service created, so enable it */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_delete_instance(handle, instname)
6185db853e024a486ff8837e6784dd290d866112dougm * When a group goes away, we also remove the service instance.
6185db853e024a486ff8837e6784dd290d866112dougmsa_delete_instance(scfutilhandle_t *handle, char *instname)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if ((ret = sa_get_instance(handle, instname)) == SA_OK) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* need better analysis */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_create_pgroup(handle, pgroup)
6185db853e024a486ff8837e6784dd290d866112dougm * create a new property group
6185db853e024a486ff8837e6784dd290d866112dougmsa_create_pgroup(scfutilhandle_t *handle, char *pgroup)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Only create a handle if it doesn't exist. It is ok to exist
6185db853e024a486ff8837e6784dd290d866112dougm * since the pg handle will be set as a side effect.
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * Special case for a non-persistent property group. This is
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * internal use only.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If the pgroup exists, we are done. If it doesn't, then we
6185db853e024a486ff8837e6784dd290d866112dougm * need to actually add one to the service instance.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Doesn't exist so create one */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (scf_error()) {
6185db853e024a486ff8837e6784dd290d866112dougm * sa_delete_pgroup(handle, pgroup)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Remove the property group from the current instance of the service,
6185db853e024a486ff8837e6784dd290d866112dougm * but only if it actually exists.
6185db853e024a486ff8837e6784dd290d866112dougmsa_delete_pgroup(scfutilhandle_t *handle, char *pgroup)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Only delete if it does exist.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_instance_get_pg(handle->instance, pgroup, handle->pg) == 0) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* does exist so delete it */
6185db853e024a486ff8837e6784dd290d866112dougm * sa_start_transaction(handle, pgroup)
6185db853e024a486ff8837e6784dd290d866112dougm * Start an SMF transaction so we can deal with properties. it would
6185db853e024a486ff8837e6784dd290d866112dougm * be nice to not have to expose this, but we have to in order to
6185db853e024a486ff8837e6784dd290d866112dougm * optimize.
6185db853e024a486ff8837e6784dd290d866112dougm * Basic model is to hold the transaction in the handle and allow
6185db853e024a486ff8837e6784dd290d866112dougm * property adds/deletes/updates to be added then close the
6185db853e024a486ff8837e6784dd290d866112dougm * transaction (or abort). There may eventually be a need to handle
6185db853e024a486ff8837e6784dd290d866112dougm * other types of transaction mechanisms but we don't do that now.
6185db853e024a486ff8837e6784dd290d866112dougm * An sa_start_transaction must be followed by either an
6185db853e024a486ff8837e6784dd290d866112dougm * sa_end_transaction or sa_abort_transaction before another
6185db853e024a486ff8837e6784dd290d866112dougm * sa_start_transaction can be done.
6185db853e024a486ff8837e6784dd290d866112dougmsa_start_transaction(scfutilhandle_t *handle, char *propgroup)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Lookup the property group and create it if it doesn't already
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm handle->trans = scf_transaction_create(handle->handle);
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * sa_end_transaction(scfhandle, sahandle)
6185db853e024a486ff8837e6784dd290d866112dougm * Commit the changes that were added to the transaction in the
6185db853e024a486ff8837e6784dd290d866112dougm * handle. Do all necessary cleanup.
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougmsa_end_transaction(scfutilhandle_t *handle, sa_handle_impl_t sahandle)
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm if (handle == NULL || handle->trans == NULL || sahandle == NULL) {
6185db853e024a486ff8837e6784dd290d866112dougm * sa_abort_transaction(handle)
6185db853e024a486ff8837e6784dd290d866112dougm * Abort the changes that were added to the transaction in the
6185db853e024a486ff8837e6784dd290d866112dougm * handle. Do all necessary cleanup.
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * set_transaction_tstamp(sahandle)
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * After a successful transaction commit, update the timestamp of the
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * last transaction. This lets us detect changes from other processes.
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm if (sa_start_transaction(scfhandle, "*state") != SA_OK)
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm (void) snprintf(tstring, sizeof (tstring), "%lld", sahandle->tstrans);
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm if (sa_set_property(sahandle->scfhandle, "lastupdate", tstring) ==
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * While best if it succeeds, a failure doesn't cause
5b6e0c463149a26dd0aeb4c1f70611c97161ff32dougm * problems and we will ignore it anyway.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_set_property(handle, prop, value)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Set a property transaction entry into the pending SMF transaction.
6185db853e024a486ff8837e6784dd290d866112dougmsa_set_property(scfutilhandle_t *handle, char *propname, char *valstr)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Properties must be set in transactions and don't take
6185db853e024a486ff8837e6784dd290d866112dougm * effect until the transaction has been ended/committed.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm if (scf_transaction_property_change(handle->trans, entry,
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* The value is in the transaction */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Value couldn't be constructed */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* The entry is in the transaction */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm switch (scf_error()) {
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Cleanup if there were any errors that didn't leave these
6185db853e024a486ff8837e6784dd290d866112dougm * values where they would be cleaned up later.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * check_resource(share)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check to see if share has any persistent resources. We don't want
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to save if they are all transient.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sa_set_resource_property(handle, prop, value)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * set a property transaction entry into the pending SMF
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * transaction. We don't want to include any transient resources
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsa_set_resource_property(scfutilhandle_t *handle, sa_share_t share)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* don't bother if no persistent resources */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * properties must be set in transactions and don't take
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * effect until the transaction has been ended/committed.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (scf_transaction_property_change(handle->trans, entry,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Get size of complete string */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw strsize += (description != NULL) ? strlen(description) : 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* the value is in the transaction */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* the entry is in the transaction */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (scf_error()) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * cleanup if there were any errors that didn't leave
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * these values where they would be cleaned up later.
6185db853e024a486ff8837e6784dd290d866112dougm * sa_commit_share(handle, group, share)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Commit this share to the repository.
6185db853e024a486ff8837e6784dd290d866112dougm * properties are added if they exist but can be added later.
6185db853e024a486ff8837e6784dd290d866112dougm * Need to add to dfstab and sharetab, if appropriate.
6185db853e024a486ff8837e6784dd290d866112dougmsa_commit_share(scfutilhandle_t *handle, sa_group_t group, sa_share_t share)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Don't commit in the zfs group. We do commit legacy
6185db853e024a486ff8837e6784dd290d866112dougm * (default) and all other groups/shares. ZFS is handled
6185db853e024a486ff8837e6784dd290d866112dougm * through the ZFS configuration rather than SMF.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Adding to the ZFS group will result in the sharenfs
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * property being set but we don't want to do anything
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * SMF related at this point.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* slipped by */
7a9d7716b53eb5c2c08bf4f0fdf4369571dbde4dthurlow (void) xmlSetProp((xmlNodePtr)share, (xmlChar *)"id",
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Have a share name allocated so create a pgroup for
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * it. It may already exist, but that is OK. In order
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * to avoid creating a share pgroup that doesn't have
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * a path property, block signals around the critical
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * region of creating the share pgroup and props.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Now start the transaction for the
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * properties that define this share. They may
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * exist so attempt to update before create.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * There needs to be a path
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * for a share to exist.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* A drive letter may exist for SMB */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * In special cases need to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * exclude proto enable.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If there are resource names, bundle them up
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and save appropriately.
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm "description",
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* Make sure we cleanup the transaction */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * remove_resources(handle, share, shareid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the share has resources, remove all of them and their
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * optionsets.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwremove_resources(scfutilhandle_t *handle, sa_share_t share, char *shareid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw resource != NULL; resource = sa_get_next_resource(resource)) {
6185db853e024a486ff8837e6784dd290d866112dougm * sa_delete_share(handle, group, share)
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * Remove the specified share from the group (and service instance).
6185db853e024a486ff8837e6784dd290d866112dougmsa_delete_share(scfutilhandle_t *handle, sa_group_t group, sa_share_t share)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* If a share has resources, remove them */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm /* If a share has properties, remove them */
25a68471b9ababbc21cfdbbb2866014f34f419ecdougm * If a share has security/negotiable
6185db853e024a486ff8837e6784dd290d866112dougm * properties, remove them.