getpathbylabel.c revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * CDDL HEADER START
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * The contents of this file are subject to the terms of the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Common Development and Distribution License (the "License").
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * You may not use this file except in compliance with the License.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * See the License for the specific language governing permissions
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * and limitations under the License.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * When distributing Covered Code, include this CDDL HEADER in each
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * If applicable, add the following below this CDDL HEADER, with the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * fields enclosed by brackets "[]" replaced with your own identifying
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * information: Portions Copyright [yyyy] [name of copyright owner]
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * CDDL HEADER END
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Use is subject to license terms.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk#pragma ident "%Z%%M% %I% %E% SMI"
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Description: Returns the global zone pathname corresponding
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * to the specified label. The pathname does
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * not need to match an existing file system object.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * This structure is used to chain mntent structures into a list
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * and to cache stat information for each member of the list.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Return a pointer to the trailing suffix of full that follows the prefix
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * given by pref. If pref isn't a prefix of full, return NULL. Apply
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * pathname semantics to the prefix test, so that pref must match at a
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * component boundary.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkstatic char *
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * pref is a substring of full. To be a subpath, it cannot cover a
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * partial component of full. The last clause of the test handles the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * special case of the root.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if (full[preflen] != '\0' && full[preflen] != '/' && preflen > 1)
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Return zero iff the path named by sub is a leading subpath
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * of the path named by full.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Treat null paths as matching nothing.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkstatic void
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkstatic void
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkstatic struct mnttab *
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkstatic struct mntlist *
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * This function attempts to convert local zone NFS mounted pathnames
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * into equivalent global zone NFS mounted pathnames. At present
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * it only works for automounted filesystems. It depends on the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * assumption that both the local and global zone automounters
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * share the same nameservices. It also assumes that any automount
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * map used by a local zone is available to the global zone automounter.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * The algorithm used consists of three phases.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * 1. The local zone's mnttab is searched to find the automount map
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * with the closest matching mountpath.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * 2. The matching autmount map name is looked up in the global zone's
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * mnttab to determine the path where it should be mounted in the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * global zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * 3. A pathname covered by an appropiate autofs trigger mount in
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * the global zone is generated as the resolved pathname
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Among the things that can go wrong is that global zone doesn't have
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * a matching automount map or the mount was not done via the automounter.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Either of these cases return a NULL path.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkgetnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len)
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * First we need to get the zonename to look for
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch));
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk (void) strlcat(zonematch, zonename, sizeof (zonematch));
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Find the best match for an automount map that
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * corresponds to the local zone's pathname
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Now we may have found the corresponding autofs mount
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Try to find the matching global zone autofs entry
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * OK, we have a matching global zone automap
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * so adjust the path for the global zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * If both global zone and zone-relative
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * mountpoint match, just use the same pathname
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (1);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (1);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Find the pathname for the entry in mlist that corresponds to the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * file named by path (i.e., that names a mount table entry for the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * file system in which path lies).
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Return 0 is there an error.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk static int
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk for (;;) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Handle interesting mounts.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) ||
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * count up what's left
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * If this is a cross-zone reference to
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * a home directory, it must be corrected.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * We should only get here if the zone's
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * automounter hasn't yet mounted its
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * autofs trigger on /home.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Since it is likely to do so in the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * future, we will assume that the global
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * zone already has an equivalent autofs
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * mount established. By convention,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * this should be mounted at the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * /zone/<zonename>
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (1);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * This function is only useful for global zone callers
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * It uses the global zone mnttab to translate local zone pathnames
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * into global zone pathnames.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpkgetpathbylabel(const char *path_name, char *resolved_path, size_t bufsize,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Construct the list of mounted file systems.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk} /* end getpathbylabel() */