summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Ross <gwr@nexenta.com>2011-06-08 21:42:11 -0400
committerGordon Ross <gwr@nexenta.com>2011-06-08 21:42:11 -0400
commitbd37e9869f612bc61d4ef80d1bcc1b65ffacce15 (patch)
treeb63d16b491832f82d88974ca68310736004267eb
parent02ea8248f0b3f4de8429b11ad45f24f709cb66ee (diff)
downloadillumos-gfx-drm-bd37e9869f612bc61d4ef80d1bcc1b65ffacce15.tar.gz
Prepare for building filesystems.
-rw-r--r--usr/src/cmd/Makefile4
-rw-r--r--usr/src/cmd/fs.d/Makefile75
-rw-r--r--usr/src/cmd/fs.d/Makefile.fstype97
-rw-r--r--usr/src/cmd/fs.d/Makefile.mount39
-rw-r--r--usr/src/cmd/fs.d/Makefile.mount.targ44
-rw-r--r--usr/src/cmd/fs.d/fslib.c559
-rw-r--r--usr/src/cmd/fs.d/fslib.h93
-rw-r--r--usr/src/head/Makefile44
-rw-r--r--usr/src/head/priv_utils.h96
9 files changed, 1047 insertions, 4 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 24ee238..f68975e 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -43,7 +43,8 @@ include ../Makefile.master
FIRST_SUBDIRS=
COMMON_SUBDIRS= \
- foo
+ foo \
+ fs.d
i386_SUBDIRS=
@@ -106,7 +107,6 @@ _dc: $(DCSUBDIRS)
#
# Dependencies
#
-fs.d: fstyp
$(FIRST_SUBDIRS) $(SUBDIRS) : FRC
@if [ -f $@/Makefile ]; then \
diff --git a/usr/src/cmd/fs.d/Makefile b/usr/src/cmd/fs.d/Makefile
new file mode 100644
index 0000000..ed47d82
--- /dev/null
+++ b/usr/src/cmd/fs.d/Makefile
@@ -0,0 +1,75 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+
+include ../Makefile.cmd
+
+SUBDIR1=
+SUBDIR2=
+SUBDIRS= $(SUBDIR1) $(SUBDIR2)
+I18NDIRS= $(SUBDIR2)
+
+all:= TARGET= all
+install:= TARGET= install
+clean:= TARGET= clean
+clobber:= TARGET= clobber
+lint:= TARGET= lint
+_msg:= TARGET= catalog
+
+FSLIB= fslib.o
+CLOBBERFILES += $(FSLIB)
+
+# for messaging catalog
+#
+POFILE= fs.d.po
+
+POFILES2= $(I18NDIRS:%=%/%.po)
+
+POFILES= $(POFILES1) $(POFILES2)
+
+.KEEP_STATE:
+
+# This is too intense when building the whole world.
+# .PARALLEL: $(SUBDIRS)
+
+all: $(FSLIB) .WAIT $(SUBDIRS)
+
+_msg: $(I18NDIRS) $(POFILES1) $(POFILES_XPG4)
+ $(RM) $(POFILE)
+ cat $(POFILES) > $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ cp $(POFILE) $(MSGDOMAIN)
+
+install: $(FSLIB) .WAIT $(SUBDIRS)
+
+clean: $(SUBDIRS)
+
+clobber: $(SUBDIRS)
+ $(RM) $(CLOBBERFILES)
+
+lint:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET)
+
+FRC:
diff --git a/usr/src/cmd/fs.d/Makefile.fstype b/usr/src/cmd/fs.d/Makefile.fstype
new file mode 100644
index 0000000..2233045
--- /dev/null
+++ b/usr/src/cmd/fs.d/Makefile.fstype
@@ -0,0 +1,97 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# cmd/fs.d/Makefile.fstype
+# Definitions and targets common to "simple" file system types.
+#
+
+# FSTYPE is name of filesystem type subdirectory to build
+# PROG is a list of filesystem type programs to be installed BOTH in
+# ../etc/fs/$(FSTYPE) and ../usr/lib/fs/$(FSTYPE)
+# Those installed under etc/fs must be statically linked, while
+# those installed under usr/lib/fs must be dynamically linked.
+# ETCPROG is a list of filesystem type programs to be installed ONLY in
+# ../etc/fs/$(FSTYPE)
+# LIBPROG is a list of filesystem type programs to be installed ONLY in
+# ../usr/lib/fs/$(FSTYPE)
+# TYPEPROG is a list of filesystem type programs to be installed ONLY in
+# ../usr/lib/$(FSTYPE) [as with nfs daemons]
+
+# include global command definitions; SRC should be defined in the shell.
+# SRC is needed until RFE 1026993 is implemented.
+include $(SRC)/cmd/Makefile.cmd
+
+FSCOMMONDIR= $(SRC)/cmd/fs.d
+FSLIB= $(FSCOMMONDIR)/fslib.o
+FSLIBSRC= $(FSLIB:%.o=%.c)
+
+ROOTETCFS= $(ROOTETC)/fs
+ROOTLIBFS= $(ROOTLIB)/fs
+FSDIRS= $(ROOTETCFS) $(ROOTLIBFS)
+ROOTETCFSTYPE= $(ROOTETCFS)/$(FSTYPE)
+ROOTLIBFSTYPE= $(ROOTLIBFS)/$(FSTYPE)
+ROOTETCTYPE= $(ROOTETC)/$(FSTYPE)
+ROOTLIBTYPE= $(ROOTLIB)/$(FSTYPE)
+ROOTETCFSPROG= $(PROG:%=$(ROOTETCFSTYPE)/%) $(ETCPROG:%=$(ROOTETCFSTYPE)/%)
+ROOTLIBFSPROG= $(PROG:%=$(ROOTLIBFSTYPE)/%) $(LIBPROG:%=$(ROOTLIBFSTYPE)/%)
+ROOTTYPEPROG= $(TYPEPROG:%=$(ROOTLIBTYPE)/%)
+FSTYPEDIRS= $(FSDIRS:%=%/$(FSTYPE)) $(ROOTETCTYPE) $(ROOTLIBTYPE)
+FSTYPEPROG= $(ROOTETCFSPROG) $(ROOTLIBFSPROG) $(ROOTTYPEPROG)
+
+CLOBBERFILES += $(ETCPROG) $(LIBPROG) $(TYPEPROG)
+
+.KEEP_STATE:
+
+all: $(PROG) $(ETCPROG) $(LIBPROG) $(TYPEPROG)
+
+# FSDIRS are made by $(SRC)/Targetdirs via rootdirs in $(SRC)/Makefile
+# Some FSTYPE directories are made there also and should not be made here,
+# but it is easier to handle them as a class. "install" will not remake
+# a directory that already exists.
+
+$(FSTYPEDIRS):
+ $(INS.dir)
+
+$(ROOTETCFSTYPE)/%: $(ROOTETCFSTYPE) %
+ $(INS.file)
+
+$(ROOTLIBFSTYPE)/%: $(ROOTLIBFSTYPE) %
+ $(INS.file)
+
+$(ROOTLIBTYPE)/%: $(ROOTLIBTYPE) %
+ $(INS.file)
+
+$(ROOTETCTYPE)/%: $(ROOTETCTYPE) %
+ $(INS.file)
+
+# Prevent fslib.o from being build in the sub makefiles.
+$(FSLIB):
+ @:
+
+include $(SRC)/cmd/Makefile.targ
+
+install: all $(FSTYPEPROG) $(OTHERINSTALL)
+
+clean:
+
diff --git a/usr/src/cmd/fs.d/Makefile.mount b/usr/src/cmd/fs.d/Makefile.mount
new file mode 100644
index 0000000..0f8083b
--- /dev/null
+++ b/usr/src/cmd/fs.d/Makefile.mount
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+COMMONOBJ= $(FSLIB)
+COMMONSRC= $(COMMONOBJ:%.o=%.c)
+
+OBJS= $(LIBPROG).o $(COMMONOBJ)
+SRCS= $(LIBPROG).c $(COMMONSRC)
+
+# for messaging catalog file
+#
+POFILE= $(LIBPROG).po
+
+CPPFLAGS += -I$(FSCOMMONDIR)
diff --git a/usr/src/cmd/fs.d/Makefile.mount.targ b/usr/src/cmd/fs.d/Makefile.mount.targ
new file mode 100644
index 0000000..50e9e98
--- /dev/null
+++ b/usr/src/cmd/fs.d/Makefile.mount.targ
@@ -0,0 +1,44 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+$(LIBPROG): $(OBJS)
+ $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+%.o: %.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+%.o: $(FSCOMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+lint: lint_SRCS
+
+catalog: $(POFILE)
+ cp $(POFILE) $(FSTYPE).po
diff --git a/usr/src/cmd/fs.d/fslib.c b/usr/src/cmd/fs.d/fslib.c
new file mode 100644
index 0000000..5948c1e
--- /dev/null
+++ b/usr/src/cmd/fs.d/fslib.c
@@ -0,0 +1,559 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <alloca.h>
+#include <sys/vfstab.h>
+#include <sys/mnttab.h>
+#include <sys/mntent.h>
+#include <sys/mount.h>
+#include <sys/filio.h>
+#include <sys/fs/ufs_filio.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <zone.h>
+#include <signal.h>
+#include <strings.h>
+#include "fslib.h"
+
+/* LINTLIBRARY */
+
+#define BUFLEN 256
+
+#define TIME_MAX 16
+
+/*
+ * Reads all of the entries from the in-kernel mnttab, and returns the
+ * linked list of the entries.
+ */
+mntlist_t *
+fsgetmntlist(void)
+{
+ FILE *mfp;
+ mntlist_t *mntl;
+ char buf[BUFLEN];
+
+ if ((mfp = fopen(MNTTAB, "r")) == NULL) {
+ (void) snprintf(buf, BUFLEN, "fsgetmntlist: fopen %s", MNTTAB);
+ perror(buf);
+ return (NULL);
+ }
+
+ mntl = fsmkmntlist(mfp);
+
+ (void) fclose(mfp);
+ return (mntl);
+}
+
+
+static struct extmnttab zmnttab = { 0 };
+
+struct extmnttab *
+fsdupmnttab(struct extmnttab *mnt)
+{
+ struct extmnttab *new;
+
+ new = (struct extmnttab *)malloc(sizeof (*new));
+ if (new == NULL)
+ goto alloc_failed;
+
+ *new = zmnttab;
+ /*
+ * Allocate an extra byte for the mountpoint
+ * name in case a space needs to be added.
+ */
+ new->mnt_mountp = (char *)malloc(strlen(mnt->mnt_mountp) + 2);
+ if (new->mnt_mountp == NULL)
+ goto alloc_failed;
+ (void) strcpy(new->mnt_mountp, mnt->mnt_mountp);
+
+ if ((new->mnt_special = strdup(mnt->mnt_special)) == NULL)
+ goto alloc_failed;
+
+ if ((new->mnt_fstype = strdup(mnt->mnt_fstype)) == NULL)
+ goto alloc_failed;
+
+ if (mnt->mnt_mntopts != NULL)
+ if ((new->mnt_mntopts = strdup(mnt->mnt_mntopts)) == NULL)
+ goto alloc_failed;
+
+ if (mnt->mnt_time != NULL)
+ if ((new->mnt_time = strdup(mnt->mnt_time)) == NULL)
+ goto alloc_failed;
+
+ new->mnt_major = mnt->mnt_major;
+ new->mnt_minor = mnt->mnt_minor;
+ return (new);
+
+alloc_failed:
+ (void) fprintf(stderr, gettext("fsdupmnttab: Out of memory\n"));
+ fsfreemnttab(new);
+ return (NULL);
+}
+
+/*
+ * Free a single mnttab structure
+ */
+void
+fsfreemnttab(struct extmnttab *mnt)
+{
+
+ if (mnt) {
+ if (mnt->mnt_special)
+ free(mnt->mnt_special);
+ if (mnt->mnt_mountp)
+ free(mnt->mnt_mountp);
+ if (mnt->mnt_fstype)
+ free(mnt->mnt_fstype);
+ if (mnt->mnt_mntopts)
+ free(mnt->mnt_mntopts);
+ if (mnt->mnt_time)
+ free(mnt->mnt_time);
+ free(mnt);
+ }
+}
+
+void
+fsfreemntlist(mntlist_t *mntl)
+{
+ mntlist_t *mntl_tmp;
+
+ while (mntl) {
+ fsfreemnttab(mntl->mntl_mnt);
+ mntl_tmp = mntl;
+ mntl = mntl->mntl_next;
+ free(mntl_tmp);
+ }
+}
+
+/*
+ * Read the mnttab file and return it as a list of mnttab structs.
+ * Returns NULL if there was a memory failure.
+ */
+mntlist_t *
+fsmkmntlist(FILE *mfp)
+{
+ struct extmnttab mnt;
+ mntlist_t *mhead, *mtail;
+ int ret;
+
+ mhead = mtail = NULL;
+
+ resetmnttab(mfp);
+ while ((ret = getextmntent(mfp, &mnt, sizeof (struct extmnttab)))
+ != -1) {
+ mntlist_t *mp;
+
+ if (ret != 0) /* bad entry */
+ continue;
+
+ mp = (mntlist_t *)malloc(sizeof (*mp));
+ if (mp == NULL)
+ goto alloc_failed;
+ if (mhead == NULL)
+ mhead = mp;
+ else
+ mtail->mntl_next = mp;
+ mtail = mp;
+ mp->mntl_next = NULL;
+ mp->mntl_flags = 0;
+ if ((mp->mntl_mnt = fsdupmnttab(&mnt)) == NULL)
+ goto alloc_failed;
+ }
+ return (mhead);
+
+alloc_failed:
+ fsfreemntlist(mhead);
+ return (NULL);
+}
+
+/*
+ * Return the last entry that matches mntin's special
+ * device and/or mountpt.
+ * Helps to be robust here, so we check for NULL pointers.
+ */
+mntlist_t *
+fsgetmlast(mntlist_t *ml, struct mnttab *mntin)
+{
+ mntlist_t *delete = NULL;
+
+ for (; ml; ml = ml->mntl_next) {
+ if (mntin->mnt_mountp && mntin->mnt_special) {
+ /*
+ * match if and only if both are equal.
+ */
+ if ((strcmp(ml->mntl_mnt->mnt_mountp,
+ mntin->mnt_mountp) == 0) &&
+ (strcmp(ml->mntl_mnt->mnt_special,
+ mntin->mnt_special) == 0))
+ delete = ml;
+ } else if (mntin->mnt_mountp) {
+ if (strcmp(ml->mntl_mnt->mnt_mountp,
+ mntin->mnt_mountp) == 0)
+ delete = ml;
+ } else if (mntin->mnt_special) {
+ if (strcmp(ml->mntl_mnt->mnt_special,
+ mntin->mnt_special) == 0)
+ delete = ml;
+ }
+ }
+ return (delete);
+}
+
+
+/*
+ * Returns the mountlevel of the pathname in cp. As examples,
+ * / => 1, /bin => 2, /bin/ => 2, ////bin////ls => 3, sdf => 0, etc...
+ */
+int
+fsgetmlevel(char *cp)
+{
+ int mlevel;
+ char *cp1;
+
+ if (cp == NULL || *cp == NULL || *cp != '/')
+ return (0); /* this should never happen */
+
+ mlevel = 1; /* root (/) is the minimal case */
+
+ for (cp1 = cp + 1; *cp1; cp++, cp1++)
+ if (*cp == '/' && *cp1 != '/') /* "///" counts as 1 */
+ mlevel++;
+
+ return (mlevel);
+}
+
+/*
+ * Returns non-zero if string s is a member of the strings in ps.
+ */
+int
+fsstrinlist(const char *s, const char **ps)
+{
+ const char *cp;
+ cp = *ps;
+ while (cp) {
+ if (strcmp(s, cp) == 0)
+ return (1);
+ ps++;
+ cp = *ps;
+ }
+ return (0);
+}
+
+static char *empty_opt_vector[] = {
+ NULL
+};
+/*
+ * Compare the mount options that were requested by the caller to
+ * the options actually supported by the file system. If any requested
+ * options are not supported, print a warning message.
+ *
+ * WARNING: this function modifies the string pointed to by
+ * the requested_opts argument.
+ *
+ * Arguments:
+ * requested_opts - the string containing the requested options.
+ * actual_opts - the string returned by mount(2), which lists the
+ * options actually supported. It is normal for this
+ * string to contain more options than the requested options.
+ * (The actual options may contain the default options, which
+ * may not have been included in the requested options.)
+ * special - device being mounted (only used in error messages).
+ * mountp - mount point (only used in error messages).
+ */
+void
+cmp_requested_to_actual_options(char *requested_opts, char *actual_opts,
+ char *special, char *mountp)
+{
+ char *option_ptr, *actopt, *equalptr;
+ int found;
+ char *actual_opt_hold, *bufp;
+
+ if (requested_opts == NULL)
+ return;
+
+ bufp = alloca(strlen(actual_opts) + 1);
+
+ while (*requested_opts != '\0') {
+ (void) getsubopt(&requested_opts, empty_opt_vector,
+ &option_ptr);
+
+ /*
+ * Truncate any "=<value>" string from the end of
+ * the option.
+ */
+ if ((equalptr = strchr(option_ptr, '=')) != NULL)
+ *equalptr = '\0';
+
+ if (*option_ptr == '\0')
+ continue;
+
+ /*
+ * Whilst we don't need this option to perform a lofi
+ * mount, let's not be mendacious enough to complain
+ * about it.
+ */
+ if (strcmp(option_ptr, "loop") == 0)
+ continue;
+
+ /*
+ * Search for the requested option in the list of options
+ * actually supported.
+ */
+ found = 0;
+
+ /*
+ * Need to use a copy of actual_opts because getsubopt
+ * is destructive and we need to scan the actual_opts
+ * string more than once.
+ *
+ * We also need to reset actual_opt_hold to the
+ * beginning of the buffer because getsubopt changes
+ * actual_opt_hold (the pointer).
+ */
+ actual_opt_hold = bufp;
+ if (actual_opts != NULL)
+ (void) strcpy(actual_opt_hold, actual_opts);
+ else
+ *actual_opt_hold = '\0';
+
+ while (*actual_opt_hold != '\0') {
+ (void) getsubopt(&actual_opt_hold, empty_opt_vector,
+ &actopt);
+
+ /* Truncate the "=<value>", if any. */
+ if ((equalptr = strchr(actopt, '=')) != NULL)
+ *equalptr = '\0';
+
+ if ((strcmp(option_ptr, actopt)) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ /*
+ * That we're ignoring the option is always
+ * truthful; the old message that the option
+ * was unknown is often not correct.
+ */
+ (void) fprintf(stderr, gettext(
+ "mount: %s on %s - WARNING ignoring option "
+ "\"%s\"\n"), special, mountp, option_ptr);
+ }
+ }
+}
+/*
+ * FUNCTION: fsgetmaxphys(int *, int *)
+ *
+ * INPUT: int *maxphys - a pointer to an integer that will hold
+ * the value for the system maxphys value.
+ * int *error - 0 means completed successfully
+ * otherwise this indicates the errno value.
+ *
+ * RETURNS: int - 0 if maxphys not found
+ * - 1 if maxphys is found
+ */
+int
+fsgetmaxphys(int *maxphys, int *error) {
+
+ int gotit = 0;
+ int fp = open("/", O_RDONLY);
+
+ *error = 0;
+
+ /*
+ * For some reason cannot open root as read only. Need a valid file
+ * descriptor to call the ufs private ioctl. If this open failes,
+ * just assume we cannot get maxphys in this case.
+ */
+ if (fp == -1) {
+ return (gotit);
+ }
+
+ if (ioctl(fp, _FIOGETMAXPHYS, maxphys) == -1) {
+ *error = errno;
+ (void) close(fp);
+ return (gotit);
+ }
+
+ (void) close(fp);
+ gotit = 1;
+ return (gotit);
+
+}
+
+/*
+ * The below is limited support for zone-aware commands.
+ */
+struct zone_summary {
+ zoneid_t zoneid;
+ char rootpath[MAXPATHLEN];
+ size_t rootpathlen;
+};
+
+struct zone_summary *
+fs_get_zone_summaries(void)
+{
+ uint_t numzones = 0, oldnumzones = 0;
+ uint_t i, j;
+ zoneid_t *ids = NULL;
+ struct zone_summary *summaries;
+ zoneid_t myzoneid = getzoneid();
+
+ for (;;) {
+ if (zone_list(ids, &numzones) < 0) {
+ perror("unable to retrieve list of zones");
+ if (ids != NULL)
+ free(ids);
+ return (NULL);
+ }
+ if (numzones <= oldnumzones)
+ break;
+ if (ids != NULL)
+ free(ids);
+ ids = malloc(numzones * sizeof (*ids));
+ if (ids == NULL) {
+ perror("malloc failed");
+ return (NULL);
+ }
+ oldnumzones = numzones;
+ }
+
+ summaries = malloc((numzones + 1) * sizeof (*summaries));
+ if (summaries == NULL) {
+ free(ids);
+ perror("malloc failed");
+ return (NULL);
+ }
+
+
+ for (i = 0, j = 0; i < numzones; i++) {
+ ssize_t len;
+
+ if (ids[i] == myzoneid)
+ continue;
+ len = zone_getattr(ids[i], ZONE_ATTR_ROOT,
+ summaries[j].rootpath, sizeof (summaries[j].rootpath));
+ if (len < 0) {
+ /*
+ * Zone must have gone away. Skip.
+ */
+ continue;
+ }
+ /*
+ * Adding a trailing '/' to the zone's rootpath allows us to
+ * use strncmp() to see if a given path resides within that
+ * zone.
+ *
+ * As an example, if the zone's rootpath is "/foo/root",
+ * "/foo/root/usr" resides within the zone, while
+ * "/foo/rootpath" doesn't.
+ */
+ (void) strlcat(summaries[j].rootpath, "/",
+ sizeof (summaries[j].rootpath));
+ summaries[j].rootpathlen = len;
+ summaries[j].zoneid = ids[i];
+ j++;
+ }
+ summaries[j].zoneid = -1;
+ free(ids);
+ return (summaries);
+}
+
+static zoneid_t
+fs_find_zone(const struct zone_summary *summaries, const char *mntpt)
+{
+ uint_t i;
+
+ for (i = 0; summaries[i].zoneid != -1; i++) {
+ if (strncmp(mntpt, summaries[i].rootpath,
+ summaries[i].rootpathlen) == 0)
+ return (summaries[i].zoneid);
+ }
+ /*
+ * (-1) is the special token we return to the caller if the mount
+ * wasn't found in any other mounts on the system. This means it's
+ * only visible to our zone.
+ *
+ * Odd choice of constant, I know, but it beats calling getzoneid() a
+ * million times.
+ */
+ return (-1);
+}
+
+boolean_t
+fs_mount_in_other_zone(const struct zone_summary *summaries, const char *mntpt)
+{
+ return (fs_find_zone(summaries, mntpt) != -1);
+}
+
+/*
+ * List of standard options.
+ */
+static const char *stdopts[] = {
+ MNTOPT_RO, MNTOPT_RW,
+ MNTOPT_SUID, MNTOPT_NOSUID,
+ MNTOPT_DEVICES, MNTOPT_NODEVICES,
+ MNTOPT_SETUID, MNTOPT_NOSETUID,
+ MNTOPT_NBMAND, MNTOPT_NONBMAND,
+ MNTOPT_EXEC, MNTOPT_NOEXEC,
+};
+
+#define NSTDOPT (sizeof (stdopts) / sizeof (stdopts[0]))
+
+static int
+optindx(const char *opt)
+{
+ int i;
+
+ for (i = 0; i < NSTDOPT; i++) {
+ if (strcmp(opt, stdopts[i]) == 0)
+ return (i);
+ }
+ return (-1);
+}
+
+/*
+ * INPUT: filesystem option not recognized by the fs specific option
+ * parsing code.
+ * OUTPUT: True if and only if the option is one of the standard VFS
+ * layer options.
+ */
+boolean_t
+fsisstdopt(const char *opt)
+{
+ return (optindx(opt) != -1);
+}
diff --git a/usr/src/cmd/fs.d/fslib.h b/usr/src/cmd/fs.d/fslib.h
new file mode 100644
index 0000000..69216bf
--- /dev/null
+++ b/usr/src/cmd/fs.d/fslib.h
@@ -0,0 +1,93 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _FSLIB_H
+#define _FSLIB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/mnttab.h>
+
+/*
+ * This structure is used to build a list of
+ * mnttab structures from /etc/mnttab.
+ */
+typedef struct mntlist {
+ int mntl_flags;
+ uint_t mntl_dev;
+ struct extmnttab *mntl_mnt;
+ struct mntlist *mntl_next;
+} mntlist_t;
+
+/*
+ * Bits for mntl_flags.
+ */
+#define MNTL_UNMOUNT 0x01 /* unmount this entry */
+#define MNTL_DIRECT 0x02 /* direct mount entry */
+
+/*
+ * Routines available in fslib.c:
+ */
+void fsfreemnttab(struct extmnttab *);
+struct extmnttab *fsdupmnttab(struct extmnttab *);
+void fsfreemntlist(mntlist_t *);
+
+mntlist_t *fsmkmntlist(FILE *);
+mntlist_t *fsgetmntlist(void);
+mntlist_t *fsgetmlast(mntlist_t *, struct mnttab *);
+void cmp_requested_to_actual_options(char *, char *, char *, char *);
+
+int fsgetmlevel(char *);
+int fsstrinlist(const char *, const char **);
+int fsgetmaxphys(int *, int *);
+
+boolean_t fsisstdopt(const char *);
+
+/*
+ * Routines for determining which zone a mount resides in.
+ */
+struct zone_summary;
+
+struct zone_summary *fs_get_zone_summaries(void);
+boolean_t fs_mount_in_other_zone(const struct zone_summary *,
+ const char *);
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define MAXLINE 2048
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FSLIB_H */
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index 582cad6..056dcc2 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -1,4 +1,44 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# head/Makefile
+#
+# include global definitions
+include ../Makefile.master
+
+HDRS= priv_utils.h
+
+ROOTHDRS= $(HDRS:%=$(ROOT)/usr/include/%)
+
+# install rules
+
+install_h: $(ROOTHDRS)
+
+$(ROOT)/usr/include/%: %
+ $(INS.file)
-install_h:
-check:
clean clobber:
+check:
+
+.KEEP_STATE:
diff --git a/usr/src/head/priv_utils.h b/usr/src/head/priv_utils.h
new file mode 100644
index 0000000..f32b817
--- /dev/null
+++ b/usr/src/head/priv_utils.h
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This is a private header file. The interfaces in this header are
+ * subject to change or removal without notice.
+ * The Sun classification is "Project Private".
+ */
+
+#ifndef _PRIV_UTILS_H
+#define _PRIV_UTILS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <priv.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PU_RESETGROUPS 0x0001 /* Remove supplemental groups */
+#define PU_LIMITPRIVS 0x0002 /* L=P */
+#define PU_INHERITPRIVS 0x0004 /* I=P */
+#define PU_CLEARLIMITSET 0x0008 /* L=0 */
+
+/*
+ * Should be run at the start of a set-uid root program;
+ * if the effective uid == 0 and the real uid != 0,
+ * the specified privileges X are assigned as follows:
+ *
+ * P = I + X + B (B added insofar allowable from L)
+ * E = I
+ * (i.e., the requested privileges are dormant, not active)
+ * Then resets all uids to the invoking uid; no-op if euid == uid == 0.
+ *
+ * flags: PU_LIMITPRIVS, PU_CLEARLIMITSET, PU_CLEARINHERITABLE
+ *
+ * Caches the required privileges for use by __priv_bracket().
+ *
+ */
+extern int __init_suid_priv(int, ...);
+
+/*
+ * After calling __init_suid_priv we can __priv_bracket(PRIV_ON) and
+ * __priv_bracket(PRIV_OFF) and __priv_relinquish to get rid of the
+ * privileges forever.
+ */
+extern int __priv_bracket(priv_op_t);
+extern void __priv_relinquish(void);
+
+/*
+ * Runs at the start of a daemon, assuming euid=uid=0.
+ *
+ * P = E = B + X
+ *
+ * Then resets uids.
+ *
+ * Flags: all
+ *
+ */
+extern int __init_daemon_priv(int, uid_t, gid_t, ...);
+
+/*
+ * Runs after the daemon is initialized, and gives up the privileges
+ * passed in as argument because they are no longer needed.
+ * Reenables core dumps.
+ */
+extern void __fini_daemon_priv(const char *, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PRIV_UTILS_H */