Delete obsolete Solaris compat files
These files have been unused ever since the OpenSolaris import Sponsored by: Axcient MFC after: 2 weeks Reviewed By: freqlabs Differential Revision: https://reviews.freebsd.org/D30371
This commit is contained in:
parent
996afd401c
commit
fc3ba3e9fa
@ -1,115 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <libgeom.h>
|
||||
#include <devid.h>
|
||||
|
||||
int
|
||||
devid_str_decode(char *devidstr, ddi_devid_t *retdevid, char **retminor_name)
|
||||
{
|
||||
|
||||
if (strlcpy(retdevid->devid, devidstr, sizeof(retdevid->devid)) >=
|
||||
sizeof(retdevid->devid)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
*retminor_name = strdup("");
|
||||
if (*retminor_name == NULL)
|
||||
return (ENOMEM);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
devid_deviceid_to_nmlist(char *search_path, ddi_devid_t devid, char *minor_name,
|
||||
devid_nmlist_t **retlist)
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
char *dst;
|
||||
|
||||
if (g_get_name(devid.devid, path, sizeof(path)) == -1)
|
||||
return (errno);
|
||||
*retlist = malloc(sizeof(**retlist));
|
||||
if (*retlist == NULL)
|
||||
return (ENOMEM);
|
||||
if (strlcpy((*retlist)[0].devname, path,
|
||||
sizeof((*retlist)[0].devname)) >= sizeof((*retlist)[0].devname)) {
|
||||
free(*retlist);
|
||||
return (ENAMETOOLONG);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
devid_str_free(char *str)
|
||||
{
|
||||
|
||||
free(str);
|
||||
}
|
||||
|
||||
void
|
||||
devid_free(ddi_devid_t devid)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
void
|
||||
devid_free_nmlist(devid_nmlist_t *list)
|
||||
{
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
int
|
||||
devid_get(int fd, ddi_devid_t *retdevid)
|
||||
{
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
devid_get_minor_name(int fd, char **retminor_name)
|
||||
{
|
||||
|
||||
*retminor_name = strdup("");
|
||||
if (*retminor_name == NULL)
|
||||
return (ENOMEM);
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
devid_str_encode(ddi_devid_t devid, char *minor_name)
|
||||
{
|
||||
|
||||
return (strdup(devid.devid));
|
||||
}
|
@ -1,262 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fsshare.h>
|
||||
#include <libutil.h>
|
||||
#include <pathnames.h> /* _PATH_MOUNTDPID */
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n"
|
||||
#define OPTSSIZE 1024
|
||||
#define MAXLINESIZE (PATH_MAX + OPTSSIZE)
|
||||
|
||||
static void
|
||||
restart_mountd(void)
|
||||
{
|
||||
struct pidfh *pfh;
|
||||
pid_t mountdpid;
|
||||
|
||||
pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid);
|
||||
if (pfh != NULL) {
|
||||
/* Mountd is not running. */
|
||||
pidfile_remove(pfh);
|
||||
return;
|
||||
}
|
||||
if (errno != EEXIST) {
|
||||
/* Cannot open pidfile for some reason. */
|
||||
return;
|
||||
}
|
||||
/* We have mountd(8) PID in mountdpid varible. */
|
||||
kill(mountdpid, SIGHUP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read one line from a file. Skip comments, empty lines and a line with a
|
||||
* mountpoint specified in the 'skip' argument.
|
||||
*/
|
||||
static char *
|
||||
zgetline(FILE *fd, const char *skip)
|
||||
{
|
||||
static char line[MAXLINESIZE];
|
||||
size_t len, skiplen;
|
||||
char *s, last;
|
||||
|
||||
if (skip != NULL)
|
||||
skiplen = strlen(skip);
|
||||
for (;;) {
|
||||
s = fgets(line, sizeof(line), fd);
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
/* Skip empty lines and comments. */
|
||||
if (line[0] == '\n' || line[0] == '#')
|
||||
continue;
|
||||
len = strlen(line);
|
||||
if (line[len - 1] == '\n')
|
||||
line[len - 1] = '\0';
|
||||
last = line[skiplen];
|
||||
/* Skip the given mountpoint. */
|
||||
if (skip != NULL && strncmp(skip, line, skiplen) == 0 &&
|
||||
(last == '\t' || last == ' ' || last == '\0')) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (line);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function translate options to a format acceptable by exports(5), eg.
|
||||
*
|
||||
* -ro -network=192.168.0.0 -mask=255.255.255.0 -maproot=0 freefall.freebsd.org 69.147.83.54
|
||||
*
|
||||
* Accepted input formats:
|
||||
*
|
||||
* ro,network=192.168.0.0,mask=255.255.255.0,maproot=0,freefall.freebsd.org
|
||||
* ro network=192.168.0.0 mask=255.255.255.0 maproot=0 freefall.freebsd.org
|
||||
* -ro,-network=192.168.0.0,-mask=255.255.255.0,-maproot=0,freefall.freebsd.org
|
||||
* -ro -network=192.168.0.0 -mask=255.255.255.0 -maproot=0 freefall.freebsd.org
|
||||
*
|
||||
* Recognized keywords:
|
||||
*
|
||||
* ro, maproot, mapall, mask, network, sec, alldirs, public, webnfs, index, quiet
|
||||
*
|
||||
*/
|
||||
static const char *known_opts[] = { "ro", "maproot", "mapall", "mask",
|
||||
"network", "sec", "alldirs", "public", "webnfs", "index", "quiet", NULL };
|
||||
static char *
|
||||
translate_opts(const char *shareopts)
|
||||
{
|
||||
static char newopts[OPTSSIZE];
|
||||
char oldopts[OPTSSIZE];
|
||||
char *o, *s = NULL;
|
||||
unsigned int i;
|
||||
size_t len;
|
||||
|
||||
strlcpy(oldopts, shareopts, sizeof(oldopts));
|
||||
newopts[0] = '\0';
|
||||
s = oldopts;
|
||||
while ((o = strsep(&s, "-, ")) != NULL) {
|
||||
if (o[0] == '\0')
|
||||
continue;
|
||||
for (i = 0; known_opts[i] != NULL; i++) {
|
||||
len = strlen(known_opts[i]);
|
||||
if (strncmp(known_opts[i], o, len) == 0 &&
|
||||
(o[len] == '\0' || o[len] == '=')) {
|
||||
strlcat(newopts, "-", sizeof(newopts));
|
||||
break;
|
||||
}
|
||||
}
|
||||
strlcat(newopts, o, sizeof(newopts));
|
||||
strlcat(newopts, " ", sizeof(newopts));
|
||||
}
|
||||
return (newopts);
|
||||
}
|
||||
|
||||
static int
|
||||
fsshare_main(const char *file, const char *mountpoint, const char *shareopts,
|
||||
int share)
|
||||
{
|
||||
char tmpfile[PATH_MAX];
|
||||
char *line;
|
||||
FILE *newfd, *oldfd;
|
||||
int fd, error;
|
||||
|
||||
newfd = oldfd = NULL;
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
* Create temporary file in the same directory, so we can atomically
|
||||
* rename it.
|
||||
*/
|
||||
if (strlcpy(tmpfile, file, sizeof(tmpfile)) >= sizeof(tmpfile))
|
||||
return (ENAMETOOLONG);
|
||||
if (strlcat(tmpfile, ".XXXXXXXX", sizeof(tmpfile)) >= sizeof(tmpfile))
|
||||
return (ENAMETOOLONG);
|
||||
fd = mkstemp(tmpfile);
|
||||
if (fd == -1)
|
||||
return (errno);
|
||||
/*
|
||||
* File name is random, so we don't really need file lock now, but it
|
||||
* will be needed after rename(2).
|
||||
*/
|
||||
error = flock(fd, LOCK_EX);
|
||||
assert(error == 0 || (error == -1 && errno == EOPNOTSUPP));
|
||||
newfd = fdopen(fd, "r+");
|
||||
assert(newfd != NULL);
|
||||
/* Open old exports file. */
|
||||
oldfd = fopen(file, "r");
|
||||
if (oldfd == NULL) {
|
||||
if (share) {
|
||||
if (errno != ENOENT) {
|
||||
error = errno;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* If there is no exports file, ignore the error. */
|
||||
if (errno == ENOENT)
|
||||
errno = 0;
|
||||
error = errno;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
error = flock(fileno(oldfd), LOCK_EX);
|
||||
assert(error == 0 || (error == -1 && errno == EOPNOTSUPP));
|
||||
error = 0;
|
||||
}
|
||||
|
||||
/* Place big, fat warning at the begining of the file. */
|
||||
fprintf(newfd, "%s", FILE_HEADER);
|
||||
while (oldfd != NULL && (line = zgetline(oldfd, mountpoint)) != NULL)
|
||||
fprintf(newfd, "%s\n", line);
|
||||
if (oldfd != NULL && ferror(oldfd) != 0) {
|
||||
error = ferror(oldfd);
|
||||
goto out;
|
||||
}
|
||||
if (ferror(newfd) != 0) {
|
||||
error = ferror(newfd);
|
||||
goto out;
|
||||
}
|
||||
if (share) {
|
||||
fprintf(newfd, "%s\t%s\n", mountpoint,
|
||||
translate_opts(shareopts));
|
||||
}
|
||||
|
||||
out:
|
||||
if (error != 0)
|
||||
unlink(tmpfile);
|
||||
else {
|
||||
if (rename(tmpfile, file) == -1) {
|
||||
error = errno;
|
||||
unlink(tmpfile);
|
||||
} else {
|
||||
fflush(newfd);
|
||||
/*
|
||||
* Send SIGHUP to mountd, but unlock exports file later.
|
||||
*/
|
||||
restart_mountd();
|
||||
}
|
||||
}
|
||||
if (oldfd != NULL) {
|
||||
flock(fileno(oldfd), LOCK_UN);
|
||||
fclose(oldfd);
|
||||
}
|
||||
if (newfd != NULL) {
|
||||
flock(fileno(newfd), LOCK_UN);
|
||||
fclose(newfd);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the given mountpoint to the given exports file.
|
||||
*/
|
||||
int
|
||||
fsshare(const char *file, const char *mountpoint, const char *shareopts)
|
||||
{
|
||||
|
||||
return (fsshare_main(file, mountpoint, shareopts, 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the given mountpoint from the given exports file.
|
||||
*/
|
||||
int
|
||||
fsunshare(const char *file, const char *mountpoint)
|
||||
{
|
||||
|
||||
return (fsshare_main(file, mountpoint, NULL, 0));
|
||||
}
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1988 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "@(#)mkdirp.c 1.15 06/01/04 SMI"
|
||||
|
||||
/*
|
||||
* Creates directory and it's parents if the parents do not
|
||||
* exist yet.
|
||||
*
|
||||
* Returns -1 if fails for reasons other than non-existing
|
||||
* parents.
|
||||
* Does NOT simplify pathnames with . or .. in them.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <libgen.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static char *simplify(const char *str);
|
||||
|
||||
int
|
||||
mkdirp(const char *d, mode_t mode)
|
||||
{
|
||||
char *endptr, *ptr, *slash, *str;
|
||||
|
||||
str = simplify(d);
|
||||
|
||||
/* If space couldn't be allocated for the simplified names, return. */
|
||||
|
||||
if (str == NULL)
|
||||
return (-1);
|
||||
|
||||
/* Try to make the directory */
|
||||
|
||||
if (mkdir(str, mode) == 0) {
|
||||
free(str);
|
||||
return (0);
|
||||
}
|
||||
if (errno != ENOENT) {
|
||||
free(str);
|
||||
return (-1);
|
||||
}
|
||||
endptr = strrchr(str, '\0');
|
||||
slash = strrchr(str, '/');
|
||||
|
||||
/* Search upward for the non-existing parent */
|
||||
|
||||
while (slash != NULL) {
|
||||
|
||||
ptr = slash;
|
||||
*ptr = '\0';
|
||||
|
||||
/* If reached an existing parent, break */
|
||||
|
||||
if (access(str, F_OK) == 0)
|
||||
break;
|
||||
|
||||
/* If non-existing parent */
|
||||
|
||||
else {
|
||||
slash = strrchr(str, '/');
|
||||
|
||||
/* If under / or current directory, make it. */
|
||||
|
||||
if (slash == NULL || slash == str) {
|
||||
if (mkdir(str, mode) != 0 && errno != EEXIST) {
|
||||
free(str);
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create directories starting from upmost non-existing parent */
|
||||
|
||||
while ((ptr = strchr(str, '\0')) != endptr) {
|
||||
*ptr = '/';
|
||||
if (mkdir(str, mode) != 0 && errno != EEXIST) {
|
||||
/*
|
||||
* If the mkdir fails because str already
|
||||
* exists (EEXIST), then str has the form
|
||||
* "existing-dir/..", and this is really
|
||||
* ok. (Remember, this loop is creating the
|
||||
* portion of the path that didn't exist)
|
||||
*/
|
||||
free(str);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
free(str);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* simplify - given a pathname, simplify that path by removing
|
||||
* duplicate contiguous slashes.
|
||||
*
|
||||
* A simplified copy of the argument is returned to the
|
||||
* caller, or NULL is returned on error.
|
||||
*
|
||||
* The caller should handle error reporting based upon the
|
||||
* returned vlaue, and should free the returned value,
|
||||
* when appropriate.
|
||||
*/
|
||||
|
||||
static char *
|
||||
simplify(const char *str)
|
||||
{
|
||||
int i;
|
||||
size_t mbPathlen; /* length of multi-byte path */
|
||||
size_t wcPathlen; /* length of wide-character path */
|
||||
wchar_t *wptr; /* scratch pointer */
|
||||
wchar_t *wcPath; /* wide-character version of the path */
|
||||
char *mbPath; /* The copy fo the path to be returned */
|
||||
|
||||
/*
|
||||
* bail out if there is nothing there.
|
||||
*/
|
||||
|
||||
if (!str)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Get a copy of the argument.
|
||||
*/
|
||||
|
||||
if ((mbPath = strdup(str)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the multi-byte version of the path to a
|
||||
* wide-character rendering, for doing our figuring.
|
||||
*/
|
||||
|
||||
mbPathlen = strlen(mbPath);
|
||||
|
||||
if ((wcPath = calloc(sizeof (wchar_t), mbPathlen+1)) == NULL) {
|
||||
free(mbPath);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((wcPathlen = mbstowcs(wcPath, mbPath, mbPathlen)) == (size_t)-1) {
|
||||
free(mbPath);
|
||||
free(wcPath);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* remove duplicate slashes first ("//../" -> "/")
|
||||
*/
|
||||
|
||||
for (wptr = wcPath, i = 0; i < wcPathlen; i++) {
|
||||
*wptr++ = wcPath[i];
|
||||
|
||||
if (wcPath[i] == '/') {
|
||||
i++;
|
||||
|
||||
while (wcPath[i] == '/') {
|
||||
i++;
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
*wptr = '\0';
|
||||
|
||||
/*
|
||||
* now convert back to the multi-byte format.
|
||||
*/
|
||||
|
||||
if (wcstombs(mbPath, wcPath, mbPathlen) == (size_t)-1) {
|
||||
free(mbPath);
|
||||
free(wcPath);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
free(wcPath);
|
||||
return (mbPath);
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file implements Solaris compatible getmntany() and hasmntopt()
|
||||
* functions.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mnttab.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *
|
||||
mntopt(char **p)
|
||||
{
|
||||
char *cp = *p;
|
||||
char *retstr;
|
||||
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
|
||||
retstr = cp;
|
||||
while (*cp && *cp != ',')
|
||||
cp++;
|
||||
|
||||
if (*cp) {
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
}
|
||||
|
||||
*p = cp;
|
||||
return (retstr);
|
||||
}
|
||||
|
||||
char *
|
||||
hasmntopt(struct mnttab *mnt, char *opt)
|
||||
{
|
||||
char tmpopts[MNT_LINE_MAX];
|
||||
char *f, *opts = tmpopts;
|
||||
|
||||
if (mnt->mnt_mntopts == NULL)
|
||||
return (NULL);
|
||||
(void) strcpy(opts, mnt->mnt_mntopts);
|
||||
f = mntopt(&opts);
|
||||
for (; *f; f = mntopt(&opts)) {
|
||||
if (strncmp(opt, f, strlen(opt)) == 0)
|
||||
return (f - tmpopts + mnt->mnt_mntopts);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
optadd(char *mntopts, size_t size, const char *opt)
|
||||
{
|
||||
|
||||
if (mntopts[0] != '\0')
|
||||
strlcat(mntopts, ",", size);
|
||||
strlcat(mntopts, opt, size);
|
||||
}
|
||||
|
||||
void
|
||||
statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
|
||||
{
|
||||
static char mntopts[MNTMAXSTR];
|
||||
long flags;
|
||||
|
||||
mntopts[0] = '\0';
|
||||
|
||||
flags = sfs->f_flags;
|
||||
#define OPTADD(opt) optadd(mntopts, sizeof(mntopts), (opt))
|
||||
if (flags & MNT_RDONLY)
|
||||
OPTADD(MNTOPT_RO);
|
||||
else
|
||||
OPTADD(MNTOPT_RW);
|
||||
if (flags & MNT_NOSUID)
|
||||
OPTADD(MNTOPT_NOSUID);
|
||||
else
|
||||
OPTADD(MNTOPT_SETUID);
|
||||
if (flags & MNT_UPDATE)
|
||||
OPTADD(MNTOPT_REMOUNT);
|
||||
if (flags & MNT_NOATIME)
|
||||
OPTADD(MNTOPT_NOATIME);
|
||||
else
|
||||
OPTADD(MNTOPT_ATIME);
|
||||
OPTADD(MNTOPT_NOXATTR);
|
||||
if (flags & MNT_NOEXEC)
|
||||
OPTADD(MNTOPT_NOEXEC);
|
||||
else
|
||||
OPTADD(MNTOPT_EXEC);
|
||||
#undef OPTADD
|
||||
mp->mnt_special = sfs->f_mntfromname;
|
||||
mp->mnt_mountp = sfs->f_mntonname;
|
||||
mp->mnt_fstype = sfs->f_fstypename;
|
||||
mp->mnt_mntopts = mntopts;
|
||||
}
|
||||
|
||||
static struct statfs *gsfs = NULL;
|
||||
static int allfs = 0;
|
||||
|
||||
static int
|
||||
statfs_init(void)
|
||||
{
|
||||
struct statfs *sfs;
|
||||
int error;
|
||||
|
||||
if (gsfs != NULL) {
|
||||
free(gsfs);
|
||||
gsfs = NULL;
|
||||
}
|
||||
allfs = getfsstat(NULL, 0, MNT_WAIT);
|
||||
if (allfs == -1)
|
||||
goto fail;
|
||||
gsfs = malloc(sizeof(gsfs[0]) * allfs * 2);
|
||||
if (gsfs == NULL)
|
||||
goto fail;
|
||||
allfs = getfsstat(gsfs, (long)(sizeof(gsfs[0]) * allfs * 2),
|
||||
MNT_WAIT);
|
||||
if (allfs == -1)
|
||||
goto fail;
|
||||
sfs = realloc(gsfs, allfs * sizeof(gsfs[0]));
|
||||
if (sfs != NULL)
|
||||
gsfs = sfs;
|
||||
return (0);
|
||||
fail:
|
||||
error = errno;
|
||||
if (gsfs != NULL)
|
||||
free(gsfs);
|
||||
gsfs = NULL;
|
||||
allfs = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
|
||||
{
|
||||
struct statfs *sfs;
|
||||
int i, error;
|
||||
|
||||
error = statfs_init();
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
for (i = 0; i < allfs; i++) {
|
||||
if (mrefp->mnt_special != NULL &&
|
||||
strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (mrefp->mnt_mountp != NULL &&
|
||||
strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (mrefp->mnt_fstype != NULL &&
|
||||
strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
|
||||
continue;
|
||||
}
|
||||
statfs2mnttab(&gsfs[i], mgetp);
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
getmntent(FILE *fp, struct mnttab *mp)
|
||||
{
|
||||
struct statfs *sfs;
|
||||
int error, nfs;
|
||||
|
||||
nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
|
||||
if (nfs == -1)
|
||||
return (errno);
|
||||
/* If nfs is 0, we want to refresh out cache. */
|
||||
if (nfs == 0 || gsfs == NULL) {
|
||||
error = statfs_init();
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
if (nfs >= allfs)
|
||||
return (-1);
|
||||
statfs2mnttab(&gsfs[nfs], mp);
|
||||
if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
@ -1,428 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include "thread_pool_impl.h"
|
||||
|
||||
typedef void (*_Voidfp)(void*); /* pointer to extern "C" function */
|
||||
|
||||
static void
|
||||
delete_pool(tpool_t *tpool)
|
||||
{
|
||||
tpool_job_t *job;
|
||||
|
||||
/*
|
||||
* There should be no pending jobs, but just in case...
|
||||
*/
|
||||
for (job = tpool->tp_head; job != NULL; job = tpool->tp_head) {
|
||||
tpool->tp_head = job->tpj_next;
|
||||
free(job);
|
||||
}
|
||||
(void) pthread_attr_destroy(&tpool->tp_attr);
|
||||
free(tpool);
|
||||
}
|
||||
|
||||
/*
|
||||
* Worker thread is terminating.
|
||||
*/
|
||||
static void
|
||||
worker_cleanup(void *arg)
|
||||
{
|
||||
tpool_t *tpool = arg;
|
||||
|
||||
if (--tpool->tp_current == 0 &&
|
||||
(tpool->tp_flags & (TP_DESTROY | TP_ABANDON))) {
|
||||
if (tpool->tp_flags & TP_ABANDON) {
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
delete_pool(tpool);
|
||||
return;
|
||||
}
|
||||
if (tpool->tp_flags & TP_DESTROY)
|
||||
(void) pthread_cond_broadcast(&tpool->tp_busycv);
|
||||
}
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_waiters(tpool_t *tpool)
|
||||
{
|
||||
if (tpool->tp_head == NULL && tpool->tp_active == NULL) {
|
||||
tpool->tp_flags &= ~TP_WAIT;
|
||||
(void) pthread_cond_broadcast(&tpool->tp_waitcv);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by a worker thread on return from a tpool_dispatch()d job.
|
||||
*/
|
||||
static void
|
||||
job_cleanup(void *arg)
|
||||
{
|
||||
tpool_t *tpool = arg;
|
||||
pthread_t my_tid = pthread_self();
|
||||
tpool_active_t *activep;
|
||||
tpool_active_t **activepp;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
/* CSTYLED */
|
||||
for (activepp = &tpool->tp_active;; activepp = &activep->tpa_next) {
|
||||
activep = *activepp;
|
||||
if (activep->tpa_tid == my_tid) {
|
||||
*activepp = activep->tpa_next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tpool->tp_flags & TP_WAIT)
|
||||
notify_waiters(tpool);
|
||||
}
|
||||
|
||||
static void *
|
||||
tpool_worker(void *arg)
|
||||
{
|
||||
tpool_t *tpool = (tpool_t *)arg;
|
||||
int elapsed;
|
||||
tpool_job_t *job;
|
||||
void (*func)(void *);
|
||||
tpool_active_t active;
|
||||
sigset_t maskset;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
pthread_cleanup_push(worker_cleanup, tpool);
|
||||
|
||||
/*
|
||||
* This is the worker's main loop.
|
||||
* It will only be left if a timeout or an error has occured.
|
||||
*/
|
||||
active.tpa_tid = pthread_self();
|
||||
for (;;) {
|
||||
elapsed = 0;
|
||||
tpool->tp_idle++;
|
||||
if (tpool->tp_flags & TP_WAIT)
|
||||
notify_waiters(tpool);
|
||||
while ((tpool->tp_head == NULL ||
|
||||
(tpool->tp_flags & TP_SUSPEND)) &&
|
||||
!(tpool->tp_flags & (TP_DESTROY | TP_ABANDON))) {
|
||||
if (tpool->tp_current <= tpool->tp_minimum ||
|
||||
tpool->tp_linger == 0) {
|
||||
(void) pthread_cond_wait(&tpool->tp_workcv,
|
||||
&tpool->tp_mutex);
|
||||
} else {
|
||||
struct timespec timeout;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeout);
|
||||
timeout.tv_sec += tpool->tp_linger;
|
||||
if (pthread_cond_timedwait(&tpool->tp_workcv,
|
||||
&tpool->tp_mutex, &timeout) != 0) {
|
||||
elapsed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tpool->tp_idle--;
|
||||
if (tpool->tp_flags & TP_DESTROY)
|
||||
break;
|
||||
if (tpool->tp_flags & TP_ABANDON) {
|
||||
/* can't abandon a suspended pool */
|
||||
if (tpool->tp_flags & TP_SUSPEND) {
|
||||
tpool->tp_flags &= ~TP_SUSPEND;
|
||||
(void) pthread_cond_broadcast(&tpool->tp_workcv);
|
||||
}
|
||||
if (tpool->tp_head == NULL)
|
||||
break;
|
||||
}
|
||||
if ((job = tpool->tp_head) != NULL &&
|
||||
!(tpool->tp_flags & TP_SUSPEND)) {
|
||||
elapsed = 0;
|
||||
func = job->tpj_func;
|
||||
arg = job->tpj_arg;
|
||||
tpool->tp_head = job->tpj_next;
|
||||
if (job == tpool->tp_tail)
|
||||
tpool->tp_tail = NULL;
|
||||
tpool->tp_njobs--;
|
||||
active.tpa_next = tpool->tp_active;
|
||||
tpool->tp_active = &active;
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
pthread_cleanup_push(job_cleanup, tpool);
|
||||
free(job);
|
||||
/*
|
||||
* Call the specified function.
|
||||
*/
|
||||
func(arg);
|
||||
/*
|
||||
* We don't know what this thread has been doing,
|
||||
* so we reset its signal mask and cancellation
|
||||
* state back to the initial values.
|
||||
*/
|
||||
sigfillset(&maskset);
|
||||
(void) pthread_sigmask(SIG_SETMASK, &maskset, NULL);
|
||||
(void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,
|
||||
NULL);
|
||||
(void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
|
||||
NULL);
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
if (elapsed && tpool->tp_current > tpool->tp_minimum) {
|
||||
/*
|
||||
* We timed out and there is no work to be done
|
||||
* and the number of workers exceeds the minimum.
|
||||
* Exit now to reduce the size of the pool.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
return (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a worker thread, with all signals blocked.
|
||||
*/
|
||||
static int
|
||||
create_worker(tpool_t *tpool)
|
||||
{
|
||||
sigset_t maskset, oset;
|
||||
pthread_t thread;
|
||||
int error;
|
||||
|
||||
sigfillset(&maskset);
|
||||
(void) pthread_sigmask(SIG_SETMASK, &maskset, &oset);
|
||||
error = pthread_create(&thread, &tpool->tp_attr, tpool_worker, tpool);
|
||||
(void) pthread_sigmask(SIG_SETMASK, &oset, NULL);
|
||||
return (error);
|
||||
}
|
||||
|
||||
tpool_t *
|
||||
tpool_create(uint_t min_threads, uint_t max_threads, uint_t linger,
|
||||
pthread_attr_t *attr)
|
||||
{
|
||||
tpool_t *tpool;
|
||||
int error;
|
||||
|
||||
if (min_threads > max_threads || max_threads < 1) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
tpool = calloc(1, sizeof (*tpool));
|
||||
if (tpool == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
(void) pthread_mutex_init(&tpool->tp_mutex, NULL);
|
||||
(void) pthread_cond_init(&tpool->tp_busycv, NULL);
|
||||
(void) pthread_cond_init(&tpool->tp_workcv, NULL);
|
||||
(void) pthread_cond_init(&tpool->tp_waitcv, NULL);
|
||||
tpool->tp_minimum = min_threads;
|
||||
tpool->tp_maximum = max_threads;
|
||||
tpool->tp_linger = linger;
|
||||
|
||||
/* make all pool threads be detached daemon threads */
|
||||
(void) pthread_attr_init(&tpool->tp_attr);
|
||||
(void) pthread_attr_setdetachstate(&tpool->tp_attr,
|
||||
PTHREAD_CREATE_DETACHED);
|
||||
|
||||
return (tpool);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispatch a work request to the thread pool.
|
||||
* If there are idle workers, awaken one.
|
||||
* Else, if the maximum number of workers has
|
||||
* not been reached, spawn a new worker thread.
|
||||
* Else just return with the job added to the queue.
|
||||
*/
|
||||
int
|
||||
tpool_dispatch(tpool_t *tpool, void (*func)(void *), void *arg)
|
||||
{
|
||||
tpool_job_t *job;
|
||||
|
||||
if ((job = calloc(1, sizeof (*job))) == NULL)
|
||||
return (-1);
|
||||
job->tpj_next = NULL;
|
||||
job->tpj_func = func;
|
||||
job->tpj_arg = arg;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
|
||||
if (tpool->tp_head == NULL)
|
||||
tpool->tp_head = job;
|
||||
else
|
||||
tpool->tp_tail->tpj_next = job;
|
||||
tpool->tp_tail = job;
|
||||
tpool->tp_njobs++;
|
||||
|
||||
if (!(tpool->tp_flags & TP_SUSPEND)) {
|
||||
if (tpool->tp_idle > 0)
|
||||
(void) pthread_cond_signal(&tpool->tp_workcv);
|
||||
else if (tpool->tp_current < tpool->tp_maximum &&
|
||||
create_worker(tpool) == 0)
|
||||
tpool->tp_current++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assumes: by the time tpool_destroy() is called no one will use this
|
||||
* thread pool in any way and no one will try to dispatch entries to it.
|
||||
* Calling tpool_destroy() from a job in the pool will cause deadlock.
|
||||
*/
|
||||
void
|
||||
tpool_destroy(tpool_t *tpool)
|
||||
{
|
||||
tpool_active_t *activep;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
pthread_cleanup_push((_Voidfp)pthread_mutex_unlock, &tpool->tp_mutex);
|
||||
|
||||
/* mark the pool as being destroyed; wakeup idle workers */
|
||||
tpool->tp_flags |= TP_DESTROY;
|
||||
tpool->tp_flags &= ~TP_SUSPEND;
|
||||
(void) pthread_cond_broadcast(&tpool->tp_workcv);
|
||||
|
||||
/* cancel all active workers */
|
||||
for (activep = tpool->tp_active; activep; activep = activep->tpa_next)
|
||||
(void) pthread_cancel(activep->tpa_tid);
|
||||
|
||||
/* wait for all active workers to finish */
|
||||
while (tpool->tp_active != NULL) {
|
||||
tpool->tp_flags |= TP_WAIT;
|
||||
(void) pthread_cond_wait(&tpool->tp_waitcv, &tpool->tp_mutex);
|
||||
}
|
||||
|
||||
/* the last worker to terminate will wake us up */
|
||||
while (tpool->tp_current != 0)
|
||||
(void) pthread_cond_wait(&tpool->tp_busycv, &tpool->tp_mutex);
|
||||
|
||||
pthread_cleanup_pop(1); /* pthread_mutex_unlock(&tpool->tp_mutex); */
|
||||
delete_pool(tpool);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like tpool_destroy(), but don't cancel workers or wait for them to finish.
|
||||
* The last worker to terminate will delete the pool.
|
||||
*/
|
||||
void
|
||||
tpool_abandon(tpool_t *tpool)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
if (tpool->tp_current == 0) {
|
||||
/* no workers, just delete the pool */
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
delete_pool(tpool);
|
||||
} else {
|
||||
/* wake up all workers, last one will delete the pool */
|
||||
tpool->tp_flags |= TP_ABANDON;
|
||||
tpool->tp_flags &= ~TP_SUSPEND;
|
||||
(void) pthread_cond_broadcast(&tpool->tp_workcv);
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for all jobs to complete.
|
||||
* Calling tpool_wait() from a job in the pool will cause deadlock.
|
||||
*/
|
||||
void
|
||||
tpool_wait(tpool_t *tpool)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
pthread_cleanup_push((_Voidfp)pthread_mutex_unlock, &tpool->tp_mutex);
|
||||
while (tpool->tp_head != NULL || tpool->tp_active != NULL) {
|
||||
tpool->tp_flags |= TP_WAIT;
|
||||
(void) pthread_cond_wait(&tpool->tp_waitcv, &tpool->tp_mutex);
|
||||
}
|
||||
pthread_cleanup_pop(1); /* pthread_mutex_unlock(&tpool->tp_mutex); */
|
||||
}
|
||||
|
||||
void
|
||||
tpool_suspend(tpool_t *tpool)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
tpool->tp_flags |= TP_SUSPEND;
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
}
|
||||
|
||||
int
|
||||
tpool_suspended(tpool_t *tpool)
|
||||
{
|
||||
int suspended;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
suspended = (tpool->tp_flags & TP_SUSPEND) != 0;
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
|
||||
return (suspended);
|
||||
}
|
||||
|
||||
void
|
||||
tpool_resume(tpool_t *tpool)
|
||||
{
|
||||
int excess;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
if (!(tpool->tp_flags & TP_SUSPEND)) {
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
return;
|
||||
}
|
||||
tpool->tp_flags &= ~TP_SUSPEND;
|
||||
(void) pthread_cond_broadcast(&tpool->tp_workcv);
|
||||
excess = tpool->tp_njobs - tpool->tp_idle;
|
||||
while (excess-- > 0 && tpool->tp_current < tpool->tp_maximum) {
|
||||
if (create_worker(tpool) != 0)
|
||||
break; /* pthread_create() failed */
|
||||
tpool->tp_current++;
|
||||
}
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
}
|
||||
|
||||
int
|
||||
tpool_member(tpool_t *tpool)
|
||||
{
|
||||
pthread_t my_tid = pthread_self();
|
||||
tpool_active_t *activep;
|
||||
|
||||
pthread_mutex_lock(&tpool->tp_mutex);
|
||||
for (activep = tpool->tp_active; activep; activep = activep->tpa_next) {
|
||||
if (activep->tpa_tid == my_tid) {
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&tpool->tp_mutex);
|
||||
return (0);
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_POOL_IMPL_H
|
||||
#define _THREAD_POOL_IMPL_H
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <thread_pool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Thread pool implementation definitions.
|
||||
* See <thread_pool.h> for interface declarations.
|
||||
*/
|
||||
|
||||
/*
|
||||
* FIFO queued job
|
||||
*/
|
||||
typedef struct tpool_job tpool_job_t;
|
||||
struct tpool_job {
|
||||
tpool_job_t *tpj_next; /* list of jobs */
|
||||
void (*tpj_func)(void *); /* function to call */
|
||||
void *tpj_arg; /* its argument */
|
||||
};
|
||||
|
||||
/*
|
||||
* List of active threads, linked through their stacks.
|
||||
*/
|
||||
typedef struct tpool_active tpool_active_t;
|
||||
struct tpool_active {
|
||||
tpool_active_t *tpa_next; /* list of active threads */
|
||||
pthread_t tpa_tid; /* active thread id */
|
||||
};
|
||||
|
||||
/*
|
||||
* The thread pool.
|
||||
*/
|
||||
struct tpool {
|
||||
tpool_t *tp_forw; /* circular list of all thread pools */
|
||||
tpool_t *tp_back;
|
||||
mutex_t tp_mutex; /* protects the pool data */
|
||||
cond_t tp_busycv; /* synchronization in tpool_dispatch */
|
||||
cond_t tp_workcv; /* synchronization with workers */
|
||||
cond_t tp_waitcv; /* synchronization in tpool_wait() */
|
||||
tpool_active_t *tp_active; /* threads performing work */
|
||||
tpool_job_t *tp_head; /* FIFO job queue */
|
||||
tpool_job_t *tp_tail;
|
||||
pthread_attr_t tp_attr; /* attributes of the workers */
|
||||
int tp_flags; /* see below */
|
||||
uint_t tp_linger; /* seconds before idle workers exit */
|
||||
int tp_njobs; /* number of jobs in job queue */
|
||||
int tp_minimum; /* minimum number of worker threads */
|
||||
int tp_maximum; /* maximum number of worker threads */
|
||||
int tp_current; /* current number of worker threads */
|
||||
int tp_idle; /* number of idle workers */
|
||||
};
|
||||
|
||||
/* tp_flags */
|
||||
#define TP_WAIT 0x01 /* waiting in tpool_wait() */
|
||||
#define TP_SUSPEND 0x02 /* pool is being suspended */
|
||||
#define TP_DESTROY 0x04 /* pool is being destroyed */
|
||||
#define TP_ABANDON 0x08 /* pool is abandoned (auto-destroy) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _THREAD_POOL_IMPL_H */
|
@ -1,106 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file implements Solaris compatible zmount() function.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mnttab.h>
|
||||
|
||||
static void
|
||||
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
|
||||
size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (*iovlen < 0)
|
||||
return;
|
||||
i = *iovlen;
|
||||
*iov = realloc(*iov, sizeof(**iov) * (i + 2));
|
||||
if (*iov == NULL) {
|
||||
*iovlen = -1;
|
||||
return;
|
||||
}
|
||||
(*iov)[i].iov_base = strdup(name);
|
||||
(*iov)[i].iov_len = strlen(name) + 1;
|
||||
i++;
|
||||
(*iov)[i].iov_base = val;
|
||||
if (len == (size_t)-1) {
|
||||
if (val != NULL)
|
||||
len = strlen(val) + 1;
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
(*iov)[i].iov_len = (int)len;
|
||||
*iovlen = ++i;
|
||||
}
|
||||
|
||||
int
|
||||
zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
char *dataptr, int datalen, char *optptr, int optlen)
|
||||
{
|
||||
struct iovec *iov;
|
||||
char *optstr, *os, *p, *tofree;
|
||||
int iovlen, rv;
|
||||
|
||||
assert(spec != NULL);
|
||||
assert(dir != NULL);
|
||||
assert(mflag == 0 || mflag == MS_RDONLY);
|
||||
assert(fstype != NULL);
|
||||
assert(strcmp(fstype, MNTTYPE_ZFS) == 0);
|
||||
assert(dataptr == NULL);
|
||||
assert(datalen == 0);
|
||||
assert(optptr != NULL);
|
||||
assert(optlen > 0);
|
||||
|
||||
tofree = optstr = strdup(optptr);
|
||||
assert(optstr != NULL);
|
||||
|
||||
iov = NULL;
|
||||
iovlen = 0;
|
||||
if (mflag & MS_RDONLY)
|
||||
build_iovec(&iov, &iovlen, "ro", NULL, 0);
|
||||
build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
|
||||
build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir),
|
||||
(size_t)-1);
|
||||
build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1);
|
||||
while ((p = strsep(&optstr, ",/")) != NULL)
|
||||
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
|
||||
rv = nmount(iov, iovlen, 0);
|
||||
free(tofree);
|
||||
return (rv);
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/zone.h>
|
||||
|
||||
zoneid_t
|
||||
getzoneid(void)
|
||||
{
|
||||
size_t size;
|
||||
int jailid;
|
||||
|
||||
/* Information that we are in jail or not is enough for our needs. */
|
||||
size = sizeof(jailid);
|
||||
if (sysctlbyname("security.jail.jailed", &jailid, &size, NULL, 0) == -1)
|
||||
assert(!"No security.jail.jailed sysctl!");
|
||||
return ((zoneid_t)jailid);
|
||||
}
|
Loading…
Reference in New Issue
Block a user