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