diff options
author | Gordon Ross <gwr@nexenta.com> | 2011-06-08 21:42:11 -0400 |
---|---|---|
committer | Gordon Ross <gwr@nexenta.com> | 2011-06-08 21:42:11 -0400 |
commit | bd37e9869f612bc61d4ef80d1bcc1b65ffacce15 (patch) | |
tree | b63d16b491832f82d88974ca68310736004267eb | |
parent | 02ea8248f0b3f4de8429b11ad45f24f709cb66ee (diff) | |
download | illumos-gfx-drm-bd37e9869f612bc61d4ef80d1bcc1b65ffacce15.tar.gz |
Prepare for building filesystems.
-rw-r--r-- | usr/src/cmd/Makefile | 4 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/Makefile | 75 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/Makefile.fstype | 97 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/Makefile.mount | 39 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/Makefile.mount.targ | 44 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/fslib.c | 559 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/fslib.h | 93 | ||||
-rw-r--r-- | usr/src/head/Makefile | 44 | ||||
-rw-r--r-- | usr/src/head/priv_utils.h | 96 |
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 */ |