MFC
This commit is contained in:
commit
94ebcddde3
@ -61,9 +61,11 @@ main(int argc, char *argv[])
|
||||
struct info i;
|
||||
enum FMT fmt;
|
||||
int ch;
|
||||
const char *file;
|
||||
|
||||
fmt = NOTSET;
|
||||
i.fd = STDIN_FILENO;
|
||||
file = "stdin";
|
||||
|
||||
opterr = 0;
|
||||
while (optind < argc &&
|
||||
@ -79,6 +81,7 @@ main(int argc, char *argv[])
|
||||
case 'f':
|
||||
if ((i.fd = open(optarg, O_RDONLY | O_NONBLOCK)) < 0)
|
||||
err(1, "%s", optarg);
|
||||
file = optarg;
|
||||
break;
|
||||
case 'g':
|
||||
fmt = GFLAG;
|
||||
@ -92,7 +95,7 @@ args: argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (tcgetattr(i.fd, &i.t) < 0)
|
||||
errx(1, "stdin isn't a terminal");
|
||||
errx(1, "%s isn't a terminal", file);
|
||||
if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0)
|
||||
err(1, "TIOCGETD");
|
||||
if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0)
|
||||
|
@ -98,8 +98,10 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir),
|
||||
(size_t)-1);
|
||||
build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1);
|
||||
for (p = optstr; p != NULL; strsep(&p, ",/ "))
|
||||
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
|
||||
for (p = optstr; p != NULL; strsep(&p, ",/ ")) {
|
||||
if (*p != '\0')
|
||||
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
|
||||
}
|
||||
rv = nmount(iov, iovlen, 0);
|
||||
free(optstr);
|
||||
return (rv);
|
||||
|
@ -289,8 +289,7 @@ op_ifentry(struct snmp_context *ctx, struct snmp_value *value,
|
||||
* cable) and hence return 'dormant'.
|
||||
*/
|
||||
if (ifp->mib.ifmd_flags & IFF_RUNNING) {
|
||||
if (ifp->mib.ifmd_data.ifi_link_state ==
|
||||
LINK_STATE_DOWN)
|
||||
if (ifp->mib.ifmd_data.ifi_link_state != LINK_STATE_UP)
|
||||
value->v.integer = 5; /* state dormant */
|
||||
else
|
||||
value->v.integer = 1; /* state up */
|
||||
|
@ -25,6 +25,32 @@ THIS SOFTWARE.
|
||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||
was sent to the printers in August, 1987.
|
||||
|
||||
May 1, 2011:
|
||||
after advice from todd miller, kevin lo, ruslan ermilov,
|
||||
and arnold robbins, changed srand() to return the previous
|
||||
seed (which is 1 on the first call of srand). the seed is
|
||||
an Awkfloat internally though converted to unsigned int to
|
||||
pass to the library srand(). thanks, everyone.
|
||||
|
||||
fixed a subtle (and i hope low-probability) overflow error
|
||||
in fldbld, by adding space for one extra \0. thanks to
|
||||
robert bassett for spotting this one and providing a fix.
|
||||
|
||||
removed the files related to compilation on windows. i no
|
||||
longer have anything like a current windows environment, so
|
||||
i can't test any of it.
|
||||
|
||||
May 23, 2010:
|
||||
fixed long-standing overflow bug in run.c; many thanks to
|
||||
nelson beebe for spotting it and providing the fix.
|
||||
|
||||
fixed bug that didn't parse -vd=1 properly; thanks to santiago
|
||||
vila for spotting it.
|
||||
|
||||
Feb 8, 2010:
|
||||
i give up. replaced isblank with isspace in b.c; there are
|
||||
no consistent header files.
|
||||
|
||||
Nov 26, 2009:
|
||||
fixed a long-standing issue with when FS takes effect. a
|
||||
change to FS is now noticed immediately for subsequent splits.
|
||||
|
@ -29,7 +29,7 @@ by Al Aho, Brian Kernighan, and Peter Weinberger
|
||||
Changes, mostly bug fixes and occasional enhancements, are listed
|
||||
in FIXES. If you distribute this code further, please please please
|
||||
distribute FIXES with it. If you find errors, please report them
|
||||
to bwk@bell-labs.com. Thanks.
|
||||
to bwk@cs.princeton.edu. Thanks.
|
||||
|
||||
The program itself is created by
|
||||
make
|
||||
|
@ -752,7 +752,7 @@ Node *unary(Node *np)
|
||||
/* #define HAS_ISBLANK */
|
||||
#ifndef HAS_ISBLANK
|
||||
|
||||
int (isblank)(int c)
|
||||
int (xisblank)(int c)
|
||||
{
|
||||
return c==' ' || c=='\t';
|
||||
}
|
||||
@ -766,7 +766,11 @@ struct charclass {
|
||||
} charclasses[] = {
|
||||
{ "alnum", 5, isalnum },
|
||||
{ "alpha", 5, isalpha },
|
||||
#ifndef HAS_ISBLANK
|
||||
{ "blank", 5, isspace }, /* was isblank */
|
||||
#else
|
||||
{ "blank", 5, isblank },
|
||||
#endif
|
||||
{ "cntrl", 5, iscntrl },
|
||||
{ "digit", 5, isdigit },
|
||||
{ "graph", 5, isgraph },
|
||||
|
@ -256,6 +256,7 @@ void fldbld(void) /* create fields from current record */
|
||||
{
|
||||
/* this relies on having fields[] the same length as $0 */
|
||||
/* the fields are all stored in this one array with \0's */
|
||||
/* possibly with a final trailing \0 not associated with any field */
|
||||
char *r, *fr, sep;
|
||||
Cell *p;
|
||||
int i, j, n;
|
||||
@ -268,7 +269,7 @@ void fldbld(void) /* create fields from current record */
|
||||
n = strlen(r);
|
||||
if (n > fieldssize) {
|
||||
xfree(fields);
|
||||
if ((fields = (char *) malloc(n+1)) == NULL)
|
||||
if ((fields = (char *) malloc(n+2)) == NULL) /* possibly 2 final \0s */
|
||||
FATAL("out of space for fields in fldbld %d", n);
|
||||
fieldssize = n;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ THIS SOFTWARE.
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
const char *version = "version 20091126 (FreeBSD)";
|
||||
const char *version = "version 20110501 (FreeBSD)";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
@ -41,6 +41,7 @@ extern char **environ;
|
||||
extern int nfields;
|
||||
|
||||
int dbg = 0;
|
||||
Awkfloat srand_seed = 1;
|
||||
char *cmdname; /* gets argv[0] for error messages */
|
||||
extern FILE *yyin; /* lex input file */
|
||||
char *lexprog; /* points to program argument if it exists */
|
||||
@ -71,6 +72,10 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
signal(SIGFPE, fpecatch);
|
||||
|
||||
srand_seed = 1;
|
||||
srand(srand_seed);
|
||||
|
||||
yyin = NULL;
|
||||
symtab = makesymtab(NSYMTAB/NSYMTAB);
|
||||
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
|
||||
@ -120,14 +125,10 @@ int main(int argc, char *argv[])
|
||||
WARNING("field separator FS is empty");
|
||||
break;
|
||||
case 'v': /* -v a=1 to be done NOW. one -v for each */
|
||||
if (argv[1][2] != 0) { /* arg is -vsomething */
|
||||
if (argv[1][2] != 0)
|
||||
setclvar(&argv[1][2]);
|
||||
} else { /* arg is -v something */
|
||||
argc--; argv++;
|
||||
if (argc > 1 && isclvar(argv[1]))
|
||||
setclvar(argv[1]);
|
||||
}
|
||||
if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
|
||||
setclvar(argv[1]);
|
||||
else if (argv[1][2] != '\0')
|
||||
setclvar(&argv[1][2]);
|
||||
break;
|
||||
case 'd':
|
||||
dbg = atoi(&argv[1][2]);
|
||||
|
@ -26,13 +26,12 @@ CFLAGS = -g
|
||||
CFLAGS = -O2
|
||||
CFLAGS =
|
||||
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
CC = gcc -Wall -g
|
||||
CC = cc
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
CC = gcc -O4
|
||||
|
||||
|
||||
YACC = bison -y
|
||||
YACC = yacc
|
||||
YFLAGS = -d
|
||||
@ -40,13 +39,13 @@ YFLAGS = -d
|
||||
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
|
||||
|
||||
SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c \
|
||||
maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
|
||||
maketab.c parse.c lib.c run.c tran.c proctab.c
|
||||
|
||||
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \
|
||||
lib.c run.c tran.c missing95.c
|
||||
lib.c run.c tran.c
|
||||
|
||||
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \
|
||||
vcvars32.bat buildwin.bat awk.1
|
||||
SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile \
|
||||
awk.1
|
||||
|
||||
a.out: ytab.o $(OFILES)
|
||||
$(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm
|
||||
|
@ -69,6 +69,7 @@ void tempfree(Cell *p) {
|
||||
|
||||
jmp_buf env;
|
||||
extern int pairstack[];
|
||||
extern Awkfloat srand_seed;
|
||||
|
||||
Node *winner = NULL; /* root of parse tree */
|
||||
Cell *tmps; /* free temporary cells for execution */
|
||||
@ -1469,6 +1470,7 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
||||
Cell *x, *y;
|
||||
Awkfloat u;
|
||||
int t;
|
||||
Awkfloat tmp;
|
||||
char *p, *buf;
|
||||
Node *nextarg;
|
||||
FILE *fp;
|
||||
@ -1520,7 +1522,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
|
||||
u = time((time_t *)0);
|
||||
else
|
||||
u = getfval(x);
|
||||
tmp = u;
|
||||
srand((unsigned int) u);
|
||||
u = srand_seed;
|
||||
srand_seed = tmp;
|
||||
break;
|
||||
case FTOUPPER:
|
||||
case FTOLOWER:
|
||||
@ -1890,9 +1895,10 @@ Cell *gsub(Node **a, int nnn) /* global substitute */
|
||||
adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub");
|
||||
while ((*pb++ = *sptr++) != 0)
|
||||
;
|
||||
done: if (pb > buf + bufsz)
|
||||
FATAL("gsub result2 %.30s too big; can't happen", buf);
|
||||
*pb = '\0';
|
||||
done: if (pb < buf + bufsz)
|
||||
*pb = '\0';
|
||||
else if (*(pb-1) != '\0')
|
||||
FATAL("gsub result2 %.30s truncated; can't happen", buf);
|
||||
setsval(x, buf); /* BUG: should be able to avoid copy + free */
|
||||
pfa->initstat = tempstat;
|
||||
}
|
||||
|
@ -256,13 +256,13 @@ current_chapter_number (void)
|
||||
return xstrdup ("");
|
||||
else if (enum_marker == APPENDIX_MAGIC)
|
||||
{
|
||||
char s[1];
|
||||
char s[2];
|
||||
sprintf (s, "%c", numbers[0] + 64);
|
||||
return xstrdup (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
char s[5];
|
||||
char s[11];
|
||||
sprintf (s, "%d", numbers[0]);
|
||||
return xstrdup (s);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
# is no process which needs to be signalled when a given log file is
|
||||
# rotated, then the entry for that file should include the 'N' flag.
|
||||
#
|
||||
# The 'flags' field is one or more of the letters: BCGJNUWZ or a '-'.
|
||||
# The 'flags' field is one or more of the letters: BCDGJNUXZ or a '-'.
|
||||
#
|
||||
# Note: some sites will want to select more restrictive protections than the
|
||||
# defaults. In particular, it may be desirable to switch many of the 644
|
||||
|
@ -38,6 +38,6 @@ __FBSDID("$FreeBSD$");
|
||||
void __main(void);
|
||||
|
||||
void
|
||||
__main()
|
||||
__main(void)
|
||||
{
|
||||
}
|
||||
|
@ -16,9 +16,11 @@ static char *rcsid = "$NetBSD: bswap64.c,v 1.1 1997/10/09 15:42:33 bouyer Exp $"
|
||||
#undef bswap32
|
||||
#undef bswap64
|
||||
|
||||
u_int32_t bswap32(u_int32_t x);
|
||||
u_int64_t bswap64(u_int64_t x);
|
||||
|
||||
u_int32_t
|
||||
bswap32(x)
|
||||
u_int32_t x;
|
||||
bswap32(u_int32_t x)
|
||||
{
|
||||
return ((x << 24) & 0xff000000 ) |
|
||||
((x << 8) & 0x00ff0000 ) |
|
||||
@ -27,8 +29,7 @@ bswap32(x)
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
bswap64(x)
|
||||
u_int64_t x;
|
||||
bswap64(u_int64_t x)
|
||||
{
|
||||
u_int32_t *p = (u_int32_t*)&x;
|
||||
u_int32_t t;
|
||||
|
@ -545,7 +545,7 @@ cd9660_readdir(struct open_file *f, struct dirent *d)
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_write(struct open_file *f, void *start, size_t size, size_t *resid)
|
||||
cd9660_write(struct open_file *f __unused, void *start __unused, size_t size __unused, size_t *resid __unused)
|
||||
{
|
||||
return EROFS;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ dos_stat(struct open_file *fd, struct stat *sb)
|
||||
static int
|
||||
dos_readdir(struct open_file *fd, struct dirent *d)
|
||||
{
|
||||
DOS_FILE *f = (DOS_FILE *)fd->f_fsdata;
|
||||
/* DOS_FILE *f = (DOS_FILE *)fd->f_fsdata; */
|
||||
u_char fn[261];
|
||||
DOS_DIR dd;
|
||||
size_t res;
|
||||
@ -414,7 +414,7 @@ dos_readdir(struct open_file *fd, struct dirent *d)
|
||||
}
|
||||
}
|
||||
|
||||
d->d_fileno = dd.de.clus[1] << 8 + dd.de.clus[0];
|
||||
d->d_fileno = (dd.de.clus[1] << 8) + dd.de.clus[0];
|
||||
d->d_reclen = sizeof(*d);
|
||||
d->d_type = (dd.de.attr & FA_DIR) ? DT_DIR : DT_REG;
|
||||
memcpy(d->d_name, fn, sizeof(d->d_name));
|
||||
|
@ -207,13 +207,14 @@ env_discard(struct env_var *ev)
|
||||
}
|
||||
|
||||
int
|
||||
env_noset(struct env_var *ev, int flags, const void *value)
|
||||
env_noset(struct env_var *ev __unused, int flags __unused,
|
||||
const void *value __unused)
|
||||
{
|
||||
return(EPERM);
|
||||
}
|
||||
|
||||
int
|
||||
env_nounset(struct env_var *ev)
|
||||
env_nounset(struct env_var *ev __unused)
|
||||
{
|
||||
return(EPERM);
|
||||
}
|
||||
|
@ -52,10 +52,7 @@ char *optarg; /* argument associated with option */
|
||||
* Parse argc/argv argument vector.
|
||||
*/
|
||||
int
|
||||
getopt(nargc, nargv, ostr)
|
||||
int nargc;
|
||||
char * const *nargv;
|
||||
const char *ostr;
|
||||
getopt(int nargc, char * const *nargv, const char *ostr)
|
||||
{
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
char *oli; /* option letter list index */
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/udp.h>
|
||||
|
@ -110,11 +110,7 @@ static const int tftperrors[8] = {
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
recvtftp(d, pkt, len, tleft)
|
||||
struct iodesc *d;
|
||||
void *pkt;
|
||||
ssize_t len;
|
||||
time_t tleft;
|
||||
recvtftp(struct iodesc *d, void *pkt, ssize_t len, time_t tleft)
|
||||
{
|
||||
struct tftphdr *t;
|
||||
|
||||
@ -152,14 +148,14 @@ recvtftp(d, pkt, len, tleft)
|
||||
printf("illegal tftp error %d\n", ntohs(t->th_code));
|
||||
errno = EIO;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
#ifdef TFTP_DEBUG
|
||||
printf("tftp-error %d\n", ntohs(t->th_code));
|
||||
#endif
|
||||
errno = tftperrors[ntohs(t->th_code)];
|
||||
}
|
||||
return (-1);
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
#ifdef TFTP_DEBUG
|
||||
printf("tftp type %d not handled\n", ntohs(t->th_opcode));
|
||||
#endif
|
||||
return (-1);
|
||||
@ -168,8 +164,7 @@ recvtftp(d, pkt, len, tleft)
|
||||
|
||||
/* send request, expect first block (or error) */
|
||||
static int
|
||||
tftp_makereq(h)
|
||||
struct tftp_handle *h;
|
||||
tftp_makereq(struct tftp_handle *h)
|
||||
{
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
@ -212,8 +207,7 @@ tftp_makereq(h)
|
||||
|
||||
/* ack block, expect next */
|
||||
static int
|
||||
tftp_getnextblock(h)
|
||||
struct tftp_handle *h;
|
||||
tftp_getnextblock(struct tftp_handle *h)
|
||||
{
|
||||
struct {
|
||||
u_char header[HEADER_SIZE];
|
||||
@ -246,9 +240,7 @@ tftp_getnextblock(h)
|
||||
}
|
||||
|
||||
static int
|
||||
tftp_open(path, f)
|
||||
const char *path;
|
||||
struct open_file *f;
|
||||
tftp_open(const char *path, struct open_file *f)
|
||||
{
|
||||
struct tftp_handle *tftpfile;
|
||||
struct iodesc *io;
|
||||
@ -287,11 +279,8 @@ tftp_open(path, f)
|
||||
}
|
||||
|
||||
static int
|
||||
tftp_read(f, addr, size, resid)
|
||||
struct open_file *f;
|
||||
void *addr;
|
||||
size_t size;
|
||||
size_t *resid; /* out */
|
||||
tftp_read(struct open_file *f, void *addr, size_t size,
|
||||
size_t *resid /* out */)
|
||||
{
|
||||
struct tftp_handle *tftpfile;
|
||||
static int tc = 0;
|
||||
@ -314,7 +303,7 @@ tftp_read(f, addr, size, resid)
|
||||
|
||||
res = tftp_getnextblock(tftpfile);
|
||||
if (res) { /* no answer */
|
||||
#ifdef DEBUG
|
||||
#ifdef TFTP_DEBUG
|
||||
printf("tftp: read error\n");
|
||||
#endif
|
||||
return (res);
|
||||
@ -330,7 +319,7 @@ tftp_read(f, addr, size, resid)
|
||||
|
||||
inbuffer = tftpfile->validsize - offinblock;
|
||||
if (inbuffer < 0) {
|
||||
#ifdef DEBUG
|
||||
#ifdef TFTP_DEBUG
|
||||
printf("tftp: invalid offset %d\n",
|
||||
tftpfile->off);
|
||||
#endif
|
||||
@ -347,7 +336,7 @@ tftp_read(f, addr, size, resid)
|
||||
if ((tftpfile->islastblock) && (count == inbuffer))
|
||||
break; /* EOF */
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
#ifdef TFTP_DEBUG
|
||||
printf("tftp: block %d not found\n", needblock);
|
||||
#endif
|
||||
return (EINVAL);
|
||||
@ -361,8 +350,7 @@ tftp_read(f, addr, size, resid)
|
||||
}
|
||||
|
||||
static int
|
||||
tftp_close(f)
|
||||
struct open_file *f;
|
||||
tftp_close(struct open_file *f)
|
||||
{
|
||||
struct tftp_handle *tftpfile;
|
||||
tftpfile = (struct tftp_handle *) f->f_fsdata;
|
||||
@ -377,19 +365,14 @@ tftp_close(f)
|
||||
}
|
||||
|
||||
static int
|
||||
tftp_write(f, start, size, resid)
|
||||
struct open_file *f;
|
||||
void *start;
|
||||
size_t size;
|
||||
size_t *resid; /* out */
|
||||
tftp_write(struct open_file *f __unused, void *start __unused, size_t size __unused,
|
||||
size_t *resid /* out */ __unused)
|
||||
{
|
||||
return (EROFS);
|
||||
}
|
||||
|
||||
static int
|
||||
tftp_stat(f, sb)
|
||||
struct open_file *f;
|
||||
struct stat *sb;
|
||||
tftp_stat(struct open_file *f, struct stat *sb)
|
||||
{
|
||||
struct tftp_handle *tftpfile;
|
||||
tftpfile = (struct tftp_handle *) f->f_fsdata;
|
||||
@ -403,10 +386,7 @@ tftp_stat(f, sb)
|
||||
}
|
||||
|
||||
static off_t
|
||||
tftp_seek(f, offset, where)
|
||||
struct open_file *f;
|
||||
off_t offset;
|
||||
int where;
|
||||
tftp_seek(struct open_file *f, off_t offset, int where)
|
||||
{
|
||||
struct tftp_handle *tftpfile;
|
||||
tftpfile = (struct tftp_handle *) f->f_fsdata;
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/udp.h>
|
||||
|
@ -93,6 +93,7 @@ static void gpart_restore(struct gctl_req *, unsigned int);
|
||||
|
||||
struct g_command PUBSYM(class_commands)[] = {
|
||||
{ "add", 0, gpart_issue, {
|
||||
{ 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING },
|
||||
{ 'b', "start", GPART_AUTOFILL, G_TYPE_STRING },
|
||||
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
||||
{ 't', "type", NULL, G_TYPE_STRING },
|
||||
@ -100,7 +101,8 @@ struct g_command PUBSYM(class_commands)[] = {
|
||||
{ 'l', "label", G_VAL_OPTIONAL, G_TYPE_STRING },
|
||||
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
||||
G_OPT_SENTINEL },
|
||||
"[-b start] [-s size] -t type [-i index] [-l label] [-f flags] geom"
|
||||
"[-a alignment] [-b start] [-s size] -t type [-i index] "
|
||||
"[-l label] [-f flags] geom"
|
||||
},
|
||||
{ "backup", 0, gpart_backup, G_NULL_OPTS,
|
||||
"geom"
|
||||
@ -168,11 +170,12 @@ struct g_command PUBSYM(class_commands)[] = {
|
||||
"-a attrib -i index [-f flags] geom"
|
||||
},
|
||||
{ "resize", 0, gpart_issue, {
|
||||
{ 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING },
|
||||
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
||||
{ 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER },
|
||||
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
||||
G_OPT_SENTINEL },
|
||||
"[-s size] -i index [-f flags] geom"
|
||||
"[-a alignment] [-s size] -i index [-f flags] geom"
|
||||
},
|
||||
{ "restore", 0, gpart_restore, {
|
||||
{ 'F', "force", NULL, G_TYPE_BOOL },
|
||||
@ -298,6 +301,9 @@ fmtattrib(struct gprovider *pp)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
#define ALIGNDOWN(d, a) (-(a) & (d))
|
||||
#define ALIGNUP(d, a) (-(-(a) & -(d)))
|
||||
|
||||
static int
|
||||
gpart_autofill_resize(struct gctl_req *req)
|
||||
{
|
||||
@ -306,7 +312,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
||||
struct ggeom *gp;
|
||||
struct gprovider *pp;
|
||||
off_t last, size, start, new_size;
|
||||
off_t lba, new_lba;
|
||||
off_t lba, new_lba, alignment;
|
||||
const char *s;
|
||||
int error, idx;
|
||||
|
||||
@ -333,6 +339,19 @@ gpart_autofill_resize(struct gctl_req *req)
|
||||
if (pp == NULL)
|
||||
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
||||
|
||||
s = gctl_get_ascii(req, "alignment");
|
||||
alignment = 1;
|
||||
if (*s != '*') {
|
||||
error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "Invalid alignment param");
|
||||
if (alignment == 0)
|
||||
errx(EXIT_FAILURE, "Invalid alignment param");
|
||||
}
|
||||
error = gctl_delete_param(req, "alignment");
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "internal error");
|
||||
|
||||
s = gctl_get_ascii(req, "size");
|
||||
if (*s == '*')
|
||||
new_size = 0;
|
||||
@ -341,10 +360,14 @@ gpart_autofill_resize(struct gctl_req *req)
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "Invalid size param");
|
||||
/* no autofill necessary. */
|
||||
goto done;
|
||||
if (alignment == 1)
|
||||
goto done;
|
||||
if (new_size > alignment)
|
||||
new_size = ALIGNDOWN(new_size, alignment);
|
||||
}
|
||||
|
||||
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
||||
last = ALIGNDOWN(last, alignment);
|
||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||
s = find_provcfg(pp, "index");
|
||||
if (s == NULL)
|
||||
@ -376,7 +399,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
||||
size = lba - start;
|
||||
pp = find_provider(gp, lba);
|
||||
if (pp == NULL)
|
||||
new_size = last - start + 1;
|
||||
new_size = ALIGNDOWN(last - start + 1, alignment);
|
||||
else {
|
||||
s = find_provcfg(pp, "start");
|
||||
if (s == NULL) {
|
||||
@ -389,6 +412,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
||||
* Is there any free space between current and
|
||||
* next providers?
|
||||
*/
|
||||
new_lba = ALIGNUP(new_lba, alignment);
|
||||
if (new_lba > lba)
|
||||
new_size = new_lba - start;
|
||||
else {
|
||||
@ -410,12 +434,12 @@ gpart_autofill(struct gctl_req *req)
|
||||
struct gclass *cp;
|
||||
struct ggeom *gp;
|
||||
struct gprovider *pp;
|
||||
off_t first, last;
|
||||
off_t size, start;
|
||||
off_t lba, len;
|
||||
off_t first, last, a_first;
|
||||
off_t size, start, a_lba;
|
||||
off_t lba, len, alignment;
|
||||
uintmax_t grade;
|
||||
const char *s;
|
||||
int error, has_size, has_start;
|
||||
int error, has_size, has_start, has_alignment;
|
||||
|
||||
s = gctl_get_ascii(req, "verb");
|
||||
if (strcmp(s, "resize") == 0)
|
||||
@ -442,6 +466,20 @@ gpart_autofill(struct gctl_req *req)
|
||||
if (pp == NULL)
|
||||
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
||||
|
||||
s = gctl_get_ascii(req, "alignment");
|
||||
has_alignment = (*s == '*') ? 0 : 1;
|
||||
alignment = 1;
|
||||
if (has_alignment) {
|
||||
error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "Invalid alignment param");
|
||||
if (alignment == 0)
|
||||
errx(EXIT_FAILURE, "Invalid alignment param");
|
||||
}
|
||||
error = gctl_delete_param(req, "alignment");
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "internal error");
|
||||
|
||||
s = gctl_get_ascii(req, "size");
|
||||
has_size = (*s == '*') ? 0 : 1;
|
||||
size = 0;
|
||||
@ -449,6 +487,8 @@ gpart_autofill(struct gctl_req *req)
|
||||
error = g_parse_lba(s, pp->lg_sectorsize, &size);
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "Invalid size param");
|
||||
if (size > alignment)
|
||||
size = ALIGNDOWN(size, alignment);
|
||||
}
|
||||
|
||||
s = gctl_get_ascii(req, "start");
|
||||
@ -458,15 +498,18 @@ gpart_autofill(struct gctl_req *req)
|
||||
error = g_parse_lba(s, pp->lg_sectorsize, &start);
|
||||
if (error)
|
||||
errc(EXIT_FAILURE, error, "Invalid start param");
|
||||
start = ALIGNUP(start, alignment);
|
||||
}
|
||||
|
||||
/* No autofill necessary. */
|
||||
if (has_size && has_start)
|
||||
if (has_size && has_start && !has_alignment)
|
||||
goto done;
|
||||
|
||||
first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0);
|
||||
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
||||
grade = ~0ULL;
|
||||
a_first = ALIGNUP(first, alignment);
|
||||
last = ALIGNDOWN(last, alignment);
|
||||
while ((pp = find_provider(gp, first)) != NULL) {
|
||||
s = find_provcfg(pp, "start");
|
||||
if (s == NULL) {
|
||||
@ -475,23 +518,24 @@ gpart_autofill(struct gctl_req *req)
|
||||
} else
|
||||
lba = (off_t)strtoimax(s, NULL, 0);
|
||||
|
||||
if (first < lba) {
|
||||
a_lba = ALIGNDOWN(lba, alignment);
|
||||
if (first < a_lba && a_first < a_lba) {
|
||||
/* Free space [first, lba> */
|
||||
len = lba - first;
|
||||
len = a_lba - a_first;
|
||||
if (has_size) {
|
||||
if (len >= size &&
|
||||
(uintmax_t)(len - size) < grade) {
|
||||
start = first;
|
||||
start = a_first;
|
||||
grade = len - size;
|
||||
}
|
||||
} else if (has_start) {
|
||||
if (start >= first && start < lba) {
|
||||
size = lba - start;
|
||||
grade = start - first;
|
||||
if (start >= a_first && start < a_lba) {
|
||||
size = a_lba - start;
|
||||
grade = start - a_first;
|
||||
}
|
||||
} else {
|
||||
if (grade == ~0ULL || len > size) {
|
||||
start = first;
|
||||
start = a_first;
|
||||
size = len;
|
||||
grade = 0;
|
||||
}
|
||||
@ -505,24 +549,25 @@ gpart_autofill(struct gctl_req *req)
|
||||
(off_t)strtoimax(s, NULL, 0) / pp->lg_sectorsize;
|
||||
} else
|
||||
first = (off_t)strtoimax(s, NULL, 0) + 1;
|
||||
a_first = ALIGNUP(first, alignment);
|
||||
}
|
||||
if (first <= last) {
|
||||
if (a_first <= last) {
|
||||
/* Free space [first-last] */
|
||||
len = last - first + 1;
|
||||
len = ALIGNDOWN(last - a_first + 1, alignment);
|
||||
if (has_size) {
|
||||
if (len >= size &&
|
||||
(uintmax_t)(len - size) < grade) {
|
||||
start = first;
|
||||
start = a_first;
|
||||
grade = len - size;
|
||||
}
|
||||
} else if (has_start) {
|
||||
if (start >= first && start <= last) {
|
||||
size = last - start + 1;
|
||||
grade = start - first;
|
||||
if (start >= a_first && start <= last) {
|
||||
size = ALIGNDOWN(last - start + 1, alignment);
|
||||
grade = start - a_first;
|
||||
}
|
||||
} else {
|
||||
if (grade == ~0ULL || len > size) {
|
||||
start = first;
|
||||
start = a_first;
|
||||
size = len;
|
||||
grade = 0;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 12, 2011
|
||||
.Dd May 03, 2011
|
||||
.Dt GPART 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -91,6 +91,7 @@ utility:
|
||||
.Nm
|
||||
.Cm add
|
||||
.Fl t Ar type
|
||||
.Op Fl a Ar alignment
|
||||
.Op Fl b Ar start
|
||||
.Op Fl s Ar size
|
||||
.Op Fl i Ar index
|
||||
@ -148,6 +149,7 @@ utility:
|
||||
.Nm
|
||||
.Cm resize
|
||||
.Fl i Ar index
|
||||
.Op Fl a Ar alignment
|
||||
.Op Fl s Ar size
|
||||
.Op Fl f Ar flags
|
||||
.Ar geom
|
||||
@ -209,7 +211,17 @@ Partition types are discussed below in the section entitled
|
||||
.Sx "PARTITION TYPES" .
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width 10n
|
||||
.Bl -tag -width 12n
|
||||
.It Fl a Ar alignment
|
||||
If specified, then
|
||||
.Nm
|
||||
utility tries to align
|
||||
.Ar start
|
||||
offset and partition
|
||||
.Ar size
|
||||
to be multiple of
|
||||
.Ar alignment
|
||||
value.
|
||||
.It Fl i Ar index
|
||||
The index in the partition table at which the new partition is to be
|
||||
placed.
|
||||
@ -416,7 +428,15 @@ to maximum available from given geom
|
||||
.Ar geom .
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width 10n
|
||||
.Bl -tag -width 12n
|
||||
.It Fl a Ar alignment
|
||||
If specified, then
|
||||
.Nm
|
||||
utility tries to align partition
|
||||
.Ar size
|
||||
to be multiple of
|
||||
.Ar alignment
|
||||
value.
|
||||
.It Fl f Ar flags
|
||||
Additional operational flags.
|
||||
See the section entitled
|
||||
@ -834,6 +854,13 @@ partition that would contain UFS where the system boots from.
|
||||
/sbin/gpart add -s 512M -t freebsd-ufs da0
|
||||
.Ed
|
||||
.Pp
|
||||
Create a 15GB-sized
|
||||
.Cm freebsd-ufs
|
||||
partition that would contain UFS and aligned on 4KB boundaries:
|
||||
.Bd -literal -offset indent
|
||||
/sbin/gpart add -s 15G -t freebsd-ufs -a 4k da0
|
||||
.Ed
|
||||
.Pp
|
||||
After having created all required partitions, embed bootstrap code into them.
|
||||
.Bd -literal -offset indent
|
||||
/sbin/gpart bootcode -p /boot/boot1 da0
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 11, 2006
|
||||
.Dd May 3, 2011
|
||||
.Dt SEM 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -73,9 +73,5 @@ dynamic kernel module.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
facility appeared as a kernel option in
|
||||
.Fx 3.0 .
|
||||
The
|
||||
.Nm
|
||||
kernel module appeared in
|
||||
facility appeared in
|
||||
.Fx 5.0 .
|
||||
|
@ -20,3 +20,5 @@ options GEOM_PART_BSD
|
||||
options GEOM_PART_EBR
|
||||
options GEOM_PART_EBR_COMPAT
|
||||
options GEOM_PART_MBR
|
||||
|
||||
options NEW_PCIB
|
||||
|
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
@ -76,7 +76,7 @@ sz2shft(vm_offset_t ofs, vm_size_t sz)
|
||||
|
||||
shft = 12; /* Start with 4K */
|
||||
s = 1 << shft;
|
||||
while (s < sz) {
|
||||
while (s <= sz) {
|
||||
shft++;
|
||||
s <<= 1;
|
||||
}
|
||||
|
@ -3600,9 +3600,12 @@ xpt_path_legacy_ata_id(struct cam_path *path)
|
||||
}
|
||||
xpt_unlock_buses();
|
||||
}
|
||||
if (path->target != NULL)
|
||||
return (bus_id * 2 + path->target->target_id);
|
||||
else
|
||||
if (path->target != NULL) {
|
||||
if (path->target->target_id < 2)
|
||||
return (bus_id * 2 + path->target->target_id);
|
||||
else
|
||||
return (-1);
|
||||
} else
|
||||
return (bus_id * 2);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,34 @@ LINT: ${NOTES} ../../conf/makeLINT.sed
|
||||
echo "include ${.TARGET}" > ${.TARGET}-VIMAGE
|
||||
echo "ident ${.TARGET}-VIMAGE" >> ${.TARGET}-VIMAGE
|
||||
echo "options VIMAGE" >> ${.TARGET}-VIMAGE
|
||||
echo "include ${.TARGET}" > ${.TARGET}-NOINET
|
||||
echo "ident ${.TARGET}-NOINET" >> ${.TARGET}-NOINET
|
||||
echo 'makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="' >> ${.TARGET}-NOINET
|
||||
echo "nooptions INET" >> ${.TARGET}-NOINET
|
||||
echo "nodevice gre" >> ${.TARGET}-NOINET
|
||||
echo "include ${.TARGET}" > ${.TARGET}-NOINET6
|
||||
echo "ident ${.TARGET}-NOINET6" >> ${.TARGET}-NOINET6
|
||||
echo "nooptions INET6" >> ${.TARGET}-NOINET6
|
||||
echo "include ${.TARGET}" > ${.TARGET}-NOIP
|
||||
echo "ident ${.TARGET}-NOIP" >> ${.TARGET}-NOIP
|
||||
echo 'makeoptions MKMODULESENV+="WITHOUT_INET_SUPPORT="' >> ${.TARGET}-NOIP
|
||||
echo 'makeoptions MKMODULESENV+="WITHOUT_INET6_SUPPORT="' >> ${.TARGET}-NOIP
|
||||
echo "nooptions INET" >> ${.TARGET}-NOIP
|
||||
echo "nooptions INET6" >> ${.TARGET}-NOIP
|
||||
echo "nodevice age" >> ${.TARGET}-NOIP
|
||||
echo "nodevice alc" >> ${.TARGET}-NOIP
|
||||
echo "nodevice ale" >> ${.TARGET}-NOIP
|
||||
echo "nodevice bxe" >> ${.TARGET}-NOIP
|
||||
echo "nodevice em" >> ${.TARGET}-NOIP
|
||||
echo "nodevice fxp" >> ${.TARGET}-NOIP
|
||||
echo "nodevice igb" >> ${.TARGET}-NOIP
|
||||
echo "nodevice jme" >> ${.TARGET}-NOIP
|
||||
echo "nodevice msk" >> ${.TARGET}-NOIP
|
||||
echo "nodevice mxge" >> ${.TARGET}-NOIP
|
||||
echo "nodevice sge" >> ${.TARGET}-NOIP
|
||||
echo "nodevice sk" >> ${.TARGET}-NOIP
|
||||
echo "nodevice txp" >> ${.TARGET}-NOIP
|
||||
echo "nodevice vxge" >> ${.TARGET}-NOIP
|
||||
.endif
|
||||
.if ${TARGET} == "powerpc" || ${TARGET} == "mips"
|
||||
echo "machine ${TARGET} ${TARGET_ARCH}" >> ${.TARGET}
|
||||
|
@ -136,6 +136,7 @@ MFI_DEBUG opt_mfi.h
|
||||
MFI_DECODE_LOG opt_mfi.h
|
||||
MPROF_BUFFERS opt_mprof.h
|
||||
MPROF_HASH_SIZE opt_mprof.h
|
||||
NEW_PCIB opt_global.h
|
||||
NO_ADAPTIVE_MUTEXES opt_adaptive_mutexes.h
|
||||
NO_ADAPTIVE_RWLOCKS
|
||||
NO_ADAPTIVE_SX
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <contrib/dev/acpica/include/acpi.h>
|
||||
@ -370,11 +371,17 @@ acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
* Hardcoding like this sucks, so a more MD/MI way needs to be
|
||||
* found to do it. This is typically only used on older laptops
|
||||
* that don't have pci busses behind pci bridge, so assuming > 32MB
|
||||
* is liekly OK.
|
||||
* is likely OK.
|
||||
*
|
||||
* PCI-PCI bridges may allocate smaller ranges for their windows,
|
||||
* but the heuristics here should apply to those, so we allow
|
||||
* several different end addresses.
|
||||
*/
|
||||
if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
|
||||
if (type == SYS_RES_MEMORY && start == 0UL && (end == ~0UL ||
|
||||
end == 0xffffffff))
|
||||
start = acpi_host_mem_start;
|
||||
if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL)
|
||||
if (type == SYS_RES_IOPORT && start == 0UL && (end == ~0UL ||
|
||||
end == 0xffff || end == 0xffffffff))
|
||||
start = 0x1000;
|
||||
return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
|
||||
count, flags));
|
||||
|
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <contrib/dev/acpica/include/acpi.h>
|
||||
#include <contrib/dev/acpica/include/accommon.h>
|
||||
|
@ -3600,7 +3600,7 @@ bxe_initial_phy_init(struct bxe_softc *sc)
|
||||
* It is recommended to turn off RX flow control for 5771x
|
||||
* when using jumbo frames for better performance.
|
||||
*/
|
||||
if (!IS_E1HMF(sc) & (sc->mbuf_alloc_size > 5000))
|
||||
if (!IS_E1HMF(sc) && (sc->mbuf_alloc_size > 5000))
|
||||
sc->link_params.req_fc_auto_adv = FLOW_CTRL_TX;
|
||||
else
|
||||
sc->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH;
|
||||
|
@ -3967,6 +3967,26 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
break;
|
||||
case SYS_RES_IOPORT:
|
||||
case SYS_RES_MEMORY:
|
||||
#ifdef NEW_PCIB
|
||||
/*
|
||||
* PCI-PCI bridge I/O window resources are not BARs.
|
||||
* For those allocations just pass the request up the
|
||||
* tree.
|
||||
*/
|
||||
if (cfg->hdrtype == PCIM_HDRTYPE_BRIDGE) {
|
||||
switch (*rid) {
|
||||
case PCIR_IOBASEL_1:
|
||||
case PCIR_MEMBASE_1:
|
||||
case PCIR_PMBASEL_1:
|
||||
/*
|
||||
* XXX: Should we bother creating a resource
|
||||
* list entry?
|
||||
*/
|
||||
return (bus_generic_alloc_resource(dev, child,
|
||||
type, rid, start, end, count, flags));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Reserve resources for this BAR if needed. */
|
||||
rle = resource_list_find(rl, type, *rid);
|
||||
if (rle == NULL) {
|
||||
|
@ -36,14 +36,16 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
@ -73,8 +75,13 @@ static device_method_t pcib_methods[] = {
|
||||
DEVMETHOD(bus_read_ivar, pcib_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, pcib_write_ivar),
|
||||
DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
|
||||
#ifdef NEW_PCIB
|
||||
DEVMETHOD(bus_adjust_resource, pcib_adjust_resource),
|
||||
DEVMETHOD(bus_release_resource, pcib_release_resource),
|
||||
#else
|
||||
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
|
||||
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
|
||||
#endif
|
||||
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
@ -100,6 +107,243 @@ static devclass_t pcib_devclass;
|
||||
DEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
|
||||
DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
|
||||
|
||||
#ifdef NEW_PCIB
|
||||
/*
|
||||
* XXX Todo:
|
||||
* - properly handle the ISA enable bit. If it is set, we should change
|
||||
* the behavior of the I/O window resource and rman to not allocate the
|
||||
* blocked ranges (upper 768 bytes of each 1K in the first 64k of the
|
||||
* I/O port address space).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Is a resource from a child device sub-allocated from one of our
|
||||
* resource managers?
|
||||
*/
|
||||
static int
|
||||
pcib_is_resource_managed(struct pcib_softc *sc, int type, struct resource *r)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
return (rman_is_region_manager(r, &sc->io.rman));
|
||||
case SYS_RES_MEMORY:
|
||||
/* Prefetchable resources may live in either memory rman. */
|
||||
if (rman_get_flags(r) & RF_PREFETCHABLE &&
|
||||
rman_is_region_manager(r, &sc->pmem.rman))
|
||||
return (1);
|
||||
return (rman_is_region_manager(r, &sc->mem.rman));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pcib_is_window_open(struct pcib_window *pw)
|
||||
{
|
||||
|
||||
return (pw->valid && pw->base < pw->limit);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: If RF_ACTIVE did not also imply allocating a bus space tag and
|
||||
* handle for the resource, we could pass RF_ACTIVE up to the PCI bus
|
||||
* when allocating the resource windows and rely on the PCI bus driver
|
||||
* to do this for us.
|
||||
*/
|
||||
static void
|
||||
pcib_activate_window(struct pcib_softc *sc, int type)
|
||||
{
|
||||
|
||||
PCI_ENABLE_IO(device_get_parent(sc->dev), sc->dev, type);
|
||||
}
|
||||
|
||||
static void
|
||||
pcib_write_windows(struct pcib_softc *sc, int mask)
|
||||
{
|
||||
device_t dev;
|
||||
uint32_t val;
|
||||
|
||||
dev = sc->dev;
|
||||
if (sc->io.valid && mask & WIN_IO) {
|
||||
val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
|
||||
if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
|
||||
pci_write_config(dev, PCIR_IOBASEH_1,
|
||||
sc->io.base >> 16, 2);
|
||||
pci_write_config(dev, PCIR_IOLIMITH_1,
|
||||
sc->io.limit >> 16, 2);
|
||||
}
|
||||
pci_write_config(dev, PCIR_IOBASEL_1, sc->io.base >> 8, 1);
|
||||
pci_write_config(dev, PCIR_IOLIMITL_1, sc->io.limit >> 8, 1);
|
||||
}
|
||||
|
||||
if (mask & WIN_MEM) {
|
||||
pci_write_config(dev, PCIR_MEMBASE_1, sc->mem.base >> 16, 2);
|
||||
pci_write_config(dev, PCIR_MEMLIMIT_1, sc->mem.limit >> 16, 2);
|
||||
}
|
||||
|
||||
if (sc->pmem.valid && mask & WIN_PMEM) {
|
||||
val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
|
||||
if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
|
||||
pci_write_config(dev, PCIR_PMBASEH_1,
|
||||
sc->pmem.base >> 32, 4);
|
||||
pci_write_config(dev, PCIR_PMLIMITH_1,
|
||||
sc->pmem.limit >> 32, 4);
|
||||
}
|
||||
pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2);
|
||||
pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
|
||||
int flags, pci_addr_t max_address)
|
||||
{
|
||||
char buf[64];
|
||||
int error, rid;
|
||||
|
||||
if (max_address != (u_long)max_address)
|
||||
max_address = ~0ul;
|
||||
w->rman.rm_start = 0;
|
||||
w->rman.rm_end = max_address;
|
||||
w->rman.rm_type = RMAN_ARRAY;
|
||||
snprintf(buf, sizeof(buf), "%s %s window",
|
||||
device_get_nameunit(sc->dev), w->name);
|
||||
w->rman.rm_descr = strdup(buf, M_DEVBUF);
|
||||
error = rman_init(&w->rman);
|
||||
if (error)
|
||||
panic("Failed to initialize %s %s rman",
|
||||
device_get_nameunit(sc->dev), w->name);
|
||||
|
||||
if (!pcib_is_window_open(w))
|
||||
return;
|
||||
|
||||
if (w->base > max_address || w->limit > max_address) {
|
||||
device_printf(sc->dev,
|
||||
"initial %s window has too many bits, ignoring\n", w->name);
|
||||
return;
|
||||
}
|
||||
rid = w->reg;
|
||||
w->res = bus_alloc_resource(sc->dev, type, &rid, w->base, w->limit,
|
||||
w->limit - w->base + 1, flags);
|
||||
if (w->res == NULL) {
|
||||
device_printf(sc->dev,
|
||||
"failed to allocate initial %s window: %#jx-%#jx\n",
|
||||
w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
|
||||
w->base = max_address;
|
||||
w->limit = 0;
|
||||
pcib_write_windows(sc, w->mask);
|
||||
return;
|
||||
}
|
||||
pcib_activate_window(sc, type);
|
||||
|
||||
error = rman_manage_region(&w->rman, rman_get_start(w->res),
|
||||
rman_get_end(w->res));
|
||||
if (error)
|
||||
panic("Failed to initialize rman with resource");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize I/O windows.
|
||||
*/
|
||||
static void
|
||||
pcib_probe_windows(struct pcib_softc *sc)
|
||||
{
|
||||
pci_addr_t max;
|
||||
device_t dev;
|
||||
uint32_t val;
|
||||
|
||||
dev = sc->dev;
|
||||
|
||||
/* Determine if the I/O port window is implemented. */
|
||||
val = pci_read_config(dev, PCIR_IOBASEL_1, 1);
|
||||
if (val == 0) {
|
||||
/*
|
||||
* If 'val' is zero, then only 16-bits of I/O space
|
||||
* are supported.
|
||||
*/
|
||||
pci_write_config(dev, PCIR_IOBASEL_1, 0xff, 1);
|
||||
if (pci_read_config(dev, PCIR_IOBASEL_1, 1) != 0) {
|
||||
sc->io.valid = 1;
|
||||
pci_write_config(dev, PCIR_IOBASEL_1, 0, 1);
|
||||
}
|
||||
} else
|
||||
sc->io.valid = 1;
|
||||
|
||||
/* Read the existing I/O port window. */
|
||||
if (sc->io.valid) {
|
||||
sc->io.reg = PCIR_IOBASEL_1;
|
||||
sc->io.step = 12;
|
||||
sc->io.mask = WIN_IO;
|
||||
sc->io.name = "I/O port";
|
||||
if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
|
||||
sc->io.base = PCI_PPBIOBASE(
|
||||
pci_read_config(dev, PCIR_IOBASEH_1, 2), val);
|
||||
sc->io.limit = PCI_PPBIOLIMIT(
|
||||
pci_read_config(dev, PCIR_IOLIMITH_1, 2),
|
||||
pci_read_config(dev, PCIR_IOLIMITL_1, 1));
|
||||
max = 0xffffffff;
|
||||
} else {
|
||||
sc->io.base = PCI_PPBIOBASE(0, val);
|
||||
sc->io.limit = PCI_PPBIOLIMIT(0,
|
||||
pci_read_config(dev, PCIR_IOLIMITL_1, 1));
|
||||
max = 0xffff;
|
||||
}
|
||||
pcib_alloc_window(sc, &sc->io, SYS_RES_IOPORT, 0, max);
|
||||
}
|
||||
|
||||
/* Read the existing memory window. */
|
||||
sc->mem.valid = 1;
|
||||
sc->mem.reg = PCIR_MEMBASE_1;
|
||||
sc->mem.step = 20;
|
||||
sc->mem.mask = WIN_MEM;
|
||||
sc->mem.name = "memory";
|
||||
sc->mem.base = PCI_PPBMEMBASE(0,
|
||||
pci_read_config(dev, PCIR_MEMBASE_1, 2));
|
||||
sc->mem.limit = PCI_PPBMEMLIMIT(0,
|
||||
pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
|
||||
pcib_alloc_window(sc, &sc->mem, SYS_RES_MEMORY, 0, 0xffffffff);
|
||||
|
||||
/* Determine if the prefetchable memory window is implemented. */
|
||||
val = pci_read_config(dev, PCIR_PMBASEL_1, 2);
|
||||
if (val == 0) {
|
||||
/*
|
||||
* If 'val' is zero, then only 32-bits of memory space
|
||||
* are supported.
|
||||
*/
|
||||
pci_write_config(dev, PCIR_PMBASEL_1, 0xffff, 2);
|
||||
if (pci_read_config(dev, PCIR_PMBASEL_1, 2) != 0) {
|
||||
sc->pmem.valid = 1;
|
||||
pci_write_config(dev, PCIR_PMBASEL_1, 0, 2);
|
||||
}
|
||||
} else
|
||||
sc->pmem.valid = 1;
|
||||
|
||||
/* Read the existing prefetchable memory window. */
|
||||
if (sc->pmem.valid) {
|
||||
sc->pmem.reg = PCIR_PMBASEL_1;
|
||||
sc->pmem.step = 20;
|
||||
sc->pmem.mask = WIN_PMEM;
|
||||
sc->pmem.name = "prefetch";
|
||||
if ((val & PCIM_BRPM_MASK) == PCIM_BRPM_64) {
|
||||
sc->pmem.base = PCI_PPBMEMBASE(
|
||||
pci_read_config(dev, PCIR_PMBASEH_1, 4), val);
|
||||
sc->pmem.limit = PCI_PPBMEMLIMIT(
|
||||
pci_read_config(dev, PCIR_PMLIMITH_1, 4),
|
||||
pci_read_config(dev, PCIR_PMLIMITL_1, 2));
|
||||
max = 0xffffffffffffffff;
|
||||
} else {
|
||||
sc->pmem.base = PCI_PPBMEMBASE(0, val);
|
||||
sc->pmem.limit = PCI_PPBMEMLIMIT(0,
|
||||
pci_read_config(dev, PCIR_PMLIMITL_1, 2));
|
||||
max = 0xffffffff;
|
||||
}
|
||||
pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY,
|
||||
RF_PREFETCHABLE, max);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Is the prefetch window open (eg, can we allocate memory in it?)
|
||||
*/
|
||||
@ -230,6 +474,7 @@ pcib_set_mem_decode(struct pcib_softc *sc)
|
||||
pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4);
|
||||
pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get current bridge configuration.
|
||||
@ -247,10 +492,12 @@ pcib_cfg_save(struct pcib_softc *sc)
|
||||
sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
|
||||
sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
|
||||
sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
|
||||
#ifndef NEW_PCIB
|
||||
if (sc->command & PCIM_CMD_PORTEN)
|
||||
pcib_get_io_decode(sc);
|
||||
if (sc->command & PCIM_CMD_MEMEN)
|
||||
pcib_get_mem_decode(sc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -269,10 +516,14 @@ pcib_cfg_restore(struct pcib_softc *sc)
|
||||
pci_write_config(dev, PCIR_SUBBUS_1, sc->subbus, 1);
|
||||
pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2);
|
||||
pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1);
|
||||
#ifdef NEW_PCIB
|
||||
pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
|
||||
#else
|
||||
if (sc->command & PCIM_CMD_PORTEN)
|
||||
pcib_set_io_decode(sc);
|
||||
if (sc->command & PCIM_CMD_MEMEN)
|
||||
pcib_set_mem_decode(sc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -389,18 +640,35 @@ pcib_attach_common(device_t dev)
|
||||
if ((pci_get_devid(dev) & 0xff00ffff) == 0x24008086 ||
|
||||
pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE)
|
||||
sc->flags |= PCIB_SUBTRACTIVE;
|
||||
|
||||
|
||||
#ifdef NEW_PCIB
|
||||
pcib_probe_windows(sc);
|
||||
#endif
|
||||
if (bootverbose) {
|
||||
device_printf(dev, " domain %d\n", sc->domain);
|
||||
device_printf(dev, " secondary bus %d\n", sc->secbus);
|
||||
device_printf(dev, " subordinate bus %d\n", sc->subbus);
|
||||
device_printf(dev, " I/O decode 0x%x-0x%x\n", sc->iobase, sc->iolimit);
|
||||
#ifdef NEW_PCIB
|
||||
if (pcib_is_window_open(&sc->io))
|
||||
device_printf(dev, " I/O decode 0x%jx-0x%jx\n",
|
||||
(uintmax_t)sc->io.base, (uintmax_t)sc->io.limit);
|
||||
if (pcib_is_window_open(&sc->mem))
|
||||
device_printf(dev, " memory decode 0x%jx-0x%jx\n",
|
||||
(uintmax_t)sc->mem.base, (uintmax_t)sc->mem.limit);
|
||||
if (pcib_is_window_open(&sc->pmem))
|
||||
device_printf(dev, " prefetched decode 0x%jx-0x%jx\n",
|
||||
(uintmax_t)sc->pmem.base, (uintmax_t)sc->pmem.limit);
|
||||
#else
|
||||
if (pcib_is_io_open(sc))
|
||||
device_printf(dev, " I/O decode 0x%x-0x%x\n",
|
||||
sc->iobase, sc->iolimit);
|
||||
if (pcib_is_nonprefetch_open(sc))
|
||||
device_printf(dev, " memory decode 0x%jx-0x%jx\n",
|
||||
(uintmax_t)sc->membase, (uintmax_t)sc->memlimit);
|
||||
if (pcib_is_prefetch_open(sc))
|
||||
device_printf(dev, " prefetched decode 0x%jx-0x%jx\n",
|
||||
(uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
|
||||
#endif
|
||||
else
|
||||
device_printf(dev, " no prefetched decode\n");
|
||||
if (sc->flags & PCIB_SUBTRACTIVE)
|
||||
@ -502,6 +770,377 @@ pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
|
||||
return(ENOENT);
|
||||
}
|
||||
|
||||
#ifdef NEW_PCIB
|
||||
static const char *
|
||||
pcib_child_name(device_t child)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
if (device_get_nameunit(child) != NULL)
|
||||
return (device_get_nameunit(child));
|
||||
snprintf(buf, sizeof(buf), "pci%d:%d:%d:%d", pci_get_domain(child),
|
||||
pci_get_bus(child), pci_get_slot(child), pci_get_function(child));
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to allocate a resource from the existing resources assigned
|
||||
* to a window.
|
||||
*/
|
||||
static struct resource *
|
||||
pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w,
|
||||
device_t child, int type, int *rid, u_long start, u_long end, u_long count,
|
||||
u_int flags)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
if (!pcib_is_window_open(w))
|
||||
return (NULL);
|
||||
|
||||
res = rman_reserve_resource(&w->rman, start, end, count,
|
||||
flags & ~RF_ACTIVE, child);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"allocated %s range (%#lx-%#lx) for rid %x of %s\n",
|
||||
w->name, rman_get_start(res), rman_get_end(res), *rid,
|
||||
pcib_child_name(child));
|
||||
rman_set_rid(res, *rid);
|
||||
|
||||
/*
|
||||
* If the resource should be active, pass that request up the
|
||||
* tree. This assumes the parent drivers can handle
|
||||
* activating sub-allocated resources.
|
||||
*/
|
||||
if (flags & RF_ACTIVE) {
|
||||
if (bus_activate_resource(child, type, *rid, res) != 0) {
|
||||
rman_release_resource(res);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to grow a window to make room for a given resource request.
|
||||
* The 'step' parameter is log_2 of the desired I/O window's alignment.
|
||||
*/
|
||||
static int
|
||||
pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
u_long align, start_free, end_free, front, back;
|
||||
int error, rid;
|
||||
|
||||
/*
|
||||
* Clamp the desired resource range to the maximum address
|
||||
* this window supports. Reject impossible requests.
|
||||
*/
|
||||
if (!w->valid)
|
||||
return (EINVAL);
|
||||
if (end > w->rman.rm_end)
|
||||
end = w->rman.rm_end;
|
||||
if (start + count - 1 > end || start + count < start)
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* If there is no resource at all, just try to allocate enough
|
||||
* aligned space for this resource.
|
||||
*/
|
||||
if (w->res == NULL) {
|
||||
if (RF_ALIGNMENT(flags) < w->step) {
|
||||
flags &= ~RF_ALIGNMENT_MASK;
|
||||
flags |= RF_ALIGNMENT_LOG2(w->step);
|
||||
}
|
||||
start &= ~((1ul << w->step) - 1);
|
||||
end |= ((1ul << w->step) - 1);
|
||||
count = roundup2(count, 1ul << w->step);
|
||||
rid = w->reg;
|
||||
w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
|
||||
count, flags & ~RF_ACTIVE);
|
||||
if (w->res == NULL) {
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"failed to allocate initial %s window (%#lx-%#lx,%#lx)\n",
|
||||
w->name, start, end, count);
|
||||
return (ENXIO);
|
||||
}
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"allocated initial %s window of %#lx-%#lx\n",
|
||||
w->name, rman_get_start(w->res),
|
||||
rman_get_end(w->res));
|
||||
error = rman_manage_region(&w->rman, rman_get_start(w->res),
|
||||
rman_get_end(w->res));
|
||||
if (error) {
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"failed to add initial %s window to rman\n",
|
||||
w->name);
|
||||
bus_release_resource(sc->dev, type, w->reg, w->res);
|
||||
w->res = NULL;
|
||||
return (error);
|
||||
}
|
||||
pcib_activate_window(sc, type);
|
||||
goto updatewin;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if growing the window would help. Compute the minimum
|
||||
* amount of address space needed on both the front and back
|
||||
* ends of the existing window to satisfy the allocation.
|
||||
*
|
||||
* For each end, build a candidate region adjusting for the
|
||||
* required alignment, etc. If there is a free region at the
|
||||
* edge of the window, grow from the inner edge of the free
|
||||
* region. Otherwise grow from the window boundary.
|
||||
*
|
||||
* XXX: Special case: if w->res is completely empty and the
|
||||
* request size is larger than w->res, we should find the
|
||||
* optimal aligned buffer containing w->res and allocate that.
|
||||
*/
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"attempting to grow %s window for (%#lx-%#lx,%#lx)\n",
|
||||
w->name, start, end, count);
|
||||
align = 1ul << RF_ALIGNMENT(flags);
|
||||
if (start < rman_get_start(w->res)) {
|
||||
if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
|
||||
0 || start_free != rman_get_start(w->res))
|
||||
end_free = rman_get_start(w->res) - 1;
|
||||
if (end_free > end)
|
||||
end_free = end;
|
||||
|
||||
/* Move end_free down until it is properly aligned. */
|
||||
end_free &= ~(align - 1);
|
||||
front = end_free - count;
|
||||
|
||||
/*
|
||||
* The resource would now be allocated at (front,
|
||||
* end_free). Ensure that fits in the (start, end)
|
||||
* bounds. end_free is checked above. If 'front' is
|
||||
* ok, ensure it is properly aligned for this window.
|
||||
* Also check for underflow.
|
||||
*/
|
||||
if (front >= start && front <= end_free) {
|
||||
if (bootverbose)
|
||||
printf("\tfront candidate range: %#lx-%#lx\n",
|
||||
front, end_free);
|
||||
front &= (1ul << w->step) - 1;
|
||||
front = rman_get_start(w->res) - front;
|
||||
} else
|
||||
front = 0;
|
||||
} else
|
||||
front = 0;
|
||||
if (end > rman_get_end(w->res)) {
|
||||
if (rman_last_free_region(&w->rman, &start_free, &end_free) !=
|
||||
0 || end_free != rman_get_end(w->res))
|
||||
start_free = rman_get_end(w->res) + 1;
|
||||
if (start_free < start)
|
||||
start_free = start;
|
||||
|
||||
/* Move start_free up until it is properly aligned. */
|
||||
start_free = roundup2(start_free, align);
|
||||
back = start_free + count;
|
||||
|
||||
/*
|
||||
* The resource would now be allocated at (start_free,
|
||||
* back). Ensure that fits in the (start, end)
|
||||
* bounds. start_free is checked above. If 'back' is
|
||||
* ok, ensure it is properly aligned for this window.
|
||||
* Also check for overflow.
|
||||
*/
|
||||
if (back <= end && start_free <= back) {
|
||||
if (bootverbose)
|
||||
printf("\tback candidate range: %#lx-%#lx\n",
|
||||
start_free, back);
|
||||
back = roundup2(back, w->step) - 1;
|
||||
back -= rman_get_end(w->res);
|
||||
} else
|
||||
back = 0;
|
||||
} else
|
||||
back = 0;
|
||||
|
||||
/*
|
||||
* Try to allocate the smallest needed region first.
|
||||
* If that fails, fall back to the other region.
|
||||
*/
|
||||
error = ENOSPC;
|
||||
while (front != 0 || back != 0) {
|
||||
if (front != 0 && (front <= back || back == 0)) {
|
||||
error = bus_adjust_resource(sc->dev, type, w->res,
|
||||
rman_get_start(w->res) - front,
|
||||
rman_get_end(w->res));
|
||||
if (error == 0)
|
||||
break;
|
||||
front = 0;
|
||||
} else {
|
||||
error = bus_adjust_resource(sc->dev, type, w->res,
|
||||
rman_get_start(w->res),
|
||||
rman_get_end(w->res) + back);
|
||||
if (error == 0)
|
||||
break;
|
||||
back = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
return (error);
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev, "grew %s window to %#lx-%#lx\n",
|
||||
w->name, rman_get_start(w->res), rman_get_end(w->res));
|
||||
|
||||
/* Add the newly allocated region to the resource manager. */
|
||||
if (w->base != rman_get_start(w->res)) {
|
||||
KASSERT(w->limit == rman_get_end(w->res), ("both ends moved"));
|
||||
error = rman_manage_region(&w->rman, rman_get_start(w->res),
|
||||
w->base - 1);
|
||||
} else {
|
||||
KASSERT(w->limit != rman_get_end(w->res),
|
||||
("neither end moved"));
|
||||
error = rman_manage_region(&w->rman, w->limit + 1,
|
||||
rman_get_end(w->res));
|
||||
}
|
||||
if (error) {
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev,
|
||||
"failed to expand %s resource manager\n", w->name);
|
||||
bus_adjust_resource(sc->dev, type, w->res, w->base, w->limit);
|
||||
return (error);
|
||||
}
|
||||
|
||||
updatewin:
|
||||
/* Save the new window. */
|
||||
w->base = rman_get_start(w->res);
|
||||
w->limit = rman_get_end(w->res);
|
||||
KASSERT((w->base & ((1ul << w->step) - 1)) == 0,
|
||||
("start address is not aligned"));
|
||||
KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1,
|
||||
("end address is not aligned"));
|
||||
pcib_write_windows(sc, w->mask);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to trap resource allocation requests and ensure that the bridge
|
||||
* is set up to, or capable of handling them.
|
||||
*/
|
||||
struct resource *
|
||||
pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct pcib_softc *sc;
|
||||
struct resource *r;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/*
|
||||
* VGA resources are decoded iff the VGA enable bit is set in
|
||||
* the bridge control register. VGA resources do not fall into
|
||||
* the resource windows and are passed up to the parent.
|
||||
*/
|
||||
if ((type == SYS_RES_IOPORT && pci_is_vga_ioport_range(start, end)) ||
|
||||
(type == SYS_RES_MEMORY && pci_is_vga_memory_range(start, end))) {
|
||||
if (sc->bridgectl & PCIB_BCR_VGA_ENABLE)
|
||||
return (bus_generic_alloc_resource(dev, child, type,
|
||||
rid, start, end, count, flags));
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start,
|
||||
end, count, flags);
|
||||
if (r != NULL)
|
||||
break;
|
||||
if (pcib_grow_window(sc, &sc->io, type, start, end, count,
|
||||
flags) == 0)
|
||||
r = pcib_suballoc_resource(sc, &sc->io, child, type,
|
||||
rid, start, end, count, flags);
|
||||
break;
|
||||
case SYS_RES_MEMORY:
|
||||
/*
|
||||
* For prefetchable resources, prefer the prefetchable
|
||||
* memory window, but fall back to the regular memory
|
||||
* window if that fails. Try both windows before
|
||||
* attempting to grow a window in case the firmware
|
||||
* has used a range in the regular memory window to
|
||||
* map a prefetchable BAR.
|
||||
*/
|
||||
if (flags & RF_PREFETCHABLE) {
|
||||
r = pcib_suballoc_resource(sc, &sc->pmem, child, type,
|
||||
rid, start, end, count, flags);
|
||||
if (r != NULL)
|
||||
break;
|
||||
}
|
||||
r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid,
|
||||
start, end, count, flags);
|
||||
if (r != NULL)
|
||||
break;
|
||||
if (flags & RF_PREFETCHABLE) {
|
||||
if (pcib_grow_window(sc, &sc->pmem, type, start, end,
|
||||
count, flags) == 0) {
|
||||
r = pcib_suballoc_resource(sc, &sc->pmem, child,
|
||||
type, rid, start, end, count, flags);
|
||||
if (r != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pcib_grow_window(sc, &sc->mem, type, start, end, count,
|
||||
flags & ~RF_PREFETCHABLE) == 0)
|
||||
r = pcib_suballoc_resource(sc, &sc->mem, child, type,
|
||||
rid, start, end, count, flags);
|
||||
break;
|
||||
default:
|
||||
return (bus_generic_alloc_resource(dev, child, type, rid,
|
||||
start, end, count, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* If attempts to suballocate from the window fail but this is a
|
||||
* subtractive bridge, pass the request up the tree.
|
||||
*/
|
||||
if (sc->flags & PCIB_SUBTRACTIVE && r == NULL)
|
||||
return (bus_generic_alloc_resource(dev, child, type, rid,
|
||||
start, end, count, flags));
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r,
|
||||
u_long start, u_long end)
|
||||
{
|
||||
struct pcib_softc *sc;
|
||||
|
||||
sc = device_get_softc(bus);
|
||||
if (pcib_is_resource_managed(sc, type, r))
|
||||
return (rman_adjust_resource(r, start, end));
|
||||
return (bus_generic_adjust_resource(bus, child, type, r, start, end));
|
||||
}
|
||||
|
||||
int
|
||||
pcib_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
struct pcib_softc *sc;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if (pcib_is_resource_managed(sc, type, r)) {
|
||||
if (rman_get_flags(r) & RF_ACTIVE) {
|
||||
error = bus_deactivate_resource(child, type, rid, r);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
return (rman_release_resource(r));
|
||||
}
|
||||
return (bus_generic_release_resource(dev, child, type, rid, r));
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* We have to trap resource allocation requests and ensure that the bridge
|
||||
* is set up to, or capable of handling them.
|
||||
@ -657,6 +1296,7 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
|
||||
count, flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PCIB interface.
|
||||
|
@ -39,6 +39,24 @@
|
||||
*/
|
||||
DECLARE_CLASS(pcib_driver);
|
||||
|
||||
#ifdef NEW_PCIB
|
||||
#define WIN_IO 0x1
|
||||
#define WIN_MEM 0x2
|
||||
#define WIN_PMEM 0x4
|
||||
|
||||
struct pcib_window {
|
||||
pci_addr_t base; /* base address */
|
||||
pci_addr_t limit; /* topmost address */
|
||||
struct rman rman;
|
||||
struct resource *res;
|
||||
int reg; /* resource id from parent */
|
||||
int valid;
|
||||
int mask; /* WIN_* bitmask of this window */
|
||||
int step; /* log_2 of window granularity */
|
||||
const char *name;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bridge-specific data.
|
||||
*/
|
||||
@ -53,12 +71,18 @@ struct pcib_softc
|
||||
u_int pribus; /* primary bus number */
|
||||
u_int secbus; /* secondary bus number */
|
||||
u_int subbus; /* subordinate bus number */
|
||||
#ifdef NEW_PCIB
|
||||
struct pcib_window io; /* I/O port window */
|
||||
struct pcib_window mem; /* memory window */
|
||||
struct pcib_window pmem; /* prefetchable memory window */
|
||||
#else
|
||||
pci_addr_t pmembase; /* base address of prefetchable memory */
|
||||
pci_addr_t pmemlimit; /* topmost address of prefetchable memory */
|
||||
pci_addr_t membase; /* base address of memory window */
|
||||
pci_addr_t memlimit; /* topmost address of memory window */
|
||||
uint32_t iobase; /* base address of port window */
|
||||
uint32_t iolimit; /* topmost address of port window */
|
||||
#endif
|
||||
uint16_t secstat; /* secondary bus status register */
|
||||
uint16_t bridgectl; /* bridge control register */
|
||||
uint8_t seclat; /* secondary bus latency timer */
|
||||
@ -74,6 +98,12 @@ int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
|
||||
int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
|
||||
struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags);
|
||||
#ifdef NEW_PCIB
|
||||
int pcib_adjust_resource(device_t bus, device_t child, int type,
|
||||
struct resource *r, u_long start, u_long end);
|
||||
int pcib_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r);
|
||||
#endif
|
||||
int pcib_maxslots(device_t dev);
|
||||
uint32_t pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width);
|
||||
void pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width);
|
||||
|
@ -1655,7 +1655,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
|
||||
/* XXX abusive DMA update: chn_rdupdate(rdch); */
|
||||
a->bytes = sndbuf_gettotal(bs);
|
||||
a->blocks = sndbuf_getblocks(bs) - rdch->blocks;
|
||||
a->ptr = sndbuf_getreadyptr(bs);
|
||||
a->ptr = sndbuf_getfreeptr(bs);
|
||||
rdch->blocks = sndbuf_getblocks(bs);
|
||||
CHN_UNLOCK(rdch);
|
||||
} else
|
||||
|
@ -3,5 +3,5 @@
|
||||
#ifndef BUILD_VERSION_H
|
||||
#define BUILD_VERSION_H
|
||||
/* Do not edit! Automatically generated when released. */
|
||||
#define GENERATED_BUILD_VERSION 22708
|
||||
#define GENERATED_BUILD_VERSION 22770
|
||||
#endif /* BUILD_VERSION_H */
|
||||
|
@ -357,6 +357,9 @@ vxge_init_locked(vxge_dev_t *vdev)
|
||||
if (!vpath_handle)
|
||||
continue;
|
||||
|
||||
/* Enabling mcast for all vpath */
|
||||
vxge_hal_vpath_mcast_enable(vpath_handle);
|
||||
|
||||
/* Enabling bcast for all vpath */
|
||||
status = vxge_hal_vpath_bcast_enable(vpath_handle);
|
||||
if (status != VXGE_HAL_OK)
|
||||
@ -2879,26 +2882,6 @@ vxge_promisc_set(vxge_dev_t *vdev)
|
||||
|
||||
ifp = vdev->ifp;
|
||||
|
||||
if ((ifp->if_flags & IFF_ALLMULTI) && (!vdev->all_multi_flag)) {
|
||||
for (i = 0; i < vdev->no_of_vpath; i++) {
|
||||
vpath_handle = vxge_vpath_handle_get(vdev, i);
|
||||
if (!vpath_handle)
|
||||
continue;
|
||||
|
||||
vxge_hal_vpath_mcast_enable(vpath_handle);
|
||||
vdev->all_multi_flag = 1;
|
||||
}
|
||||
|
||||
} else if (!(ifp->if_flags & IFF_ALLMULTI) && (vdev->all_multi_flag)) {
|
||||
for (i = 0; i < vdev->no_of_vpath; i++) {
|
||||
vpath_handle = vxge_vpath_handle_get(vdev, i);
|
||||
if (!vpath_handle)
|
||||
continue;
|
||||
|
||||
vxge_hal_vpath_mcast_disable(vpath_handle);
|
||||
vdev->all_multi_flag = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < vdev->no_of_vpath; i++) {
|
||||
vpath_handle = vxge_vpath_handle_get(vdev, i);
|
||||
if (!vpath_handle)
|
||||
|
@ -406,7 +406,6 @@ struct vxge_dev_t {
|
||||
int no_of_vpath;
|
||||
u64 active_port;
|
||||
u32 no_of_func;
|
||||
u32 all_multi_flag;
|
||||
u32 hw_fw_version;
|
||||
u32 max_supported_vpath;
|
||||
int rx_mbuf_sz;
|
||||
|
@ -28,3 +28,5 @@ options GEOM_PART_MBR
|
||||
# enable support for native hardware
|
||||
options NATIVE
|
||||
device atpic
|
||||
|
||||
options NEW_PCIB
|
||||
|
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/racct.h>
|
||||
#include <sys/rctl.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/namei.h>
|
||||
@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define DEFAULT_HOSTUUID "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
|
||||
MALLOC_DEFINE(M_PRISON_RACCT, "prison_racct", "Prison racct structures");
|
||||
|
||||
/* Keep struct prison prison0 and some code in kern_jail_set() readable. */
|
||||
#ifdef INET
|
||||
@ -114,10 +115,11 @@ struct prison prison0 = {
|
||||
};
|
||||
MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
|
||||
|
||||
/* allprison and lastprid are protected by allprison_lock. */
|
||||
/* allprison, allprison_racct and lastprid are protected by allprison_lock. */
|
||||
struct sx allprison_lock;
|
||||
SX_SYSINIT(allprison_lock, &allprison_lock, "allprison");
|
||||
struct prisonlist allprison = TAILQ_HEAD_INITIALIZER(allprison);
|
||||
LIST_HEAD(, prison_racct) allprison_racct;
|
||||
int lastprid = 0;
|
||||
|
||||
static int do_jail_attach(struct thread *td, struct prison *pr);
|
||||
@ -125,6 +127,10 @@ static void prison_complete(void *context, int pending);
|
||||
static void prison_deref(struct prison *pr, int flags);
|
||||
static char *prison_path(struct prison *pr1, struct prison *pr2);
|
||||
static void prison_remove_one(struct prison *pr);
|
||||
#ifdef RACCT
|
||||
static void prison_racct_attach(struct prison *pr);
|
||||
static void prison_racct_detach(struct prison *pr);
|
||||
#endif
|
||||
#ifdef INET
|
||||
static int _prison_check_ip4(struct prison *pr, struct in_addr *ia);
|
||||
static int prison_restrict_ip4(struct prison *pr, struct in_addr *newip4);
|
||||
@ -1197,7 +1203,6 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
|
||||
root = mypr->pr_root;
|
||||
vref(root);
|
||||
}
|
||||
racct_create(&pr->pr_racct);
|
||||
strlcpy(pr->pr_hostuuid, DEFAULT_HOSTUUID, HOSTUUIDLEN);
|
||||
pr->pr_flags |= PR_HOST;
|
||||
#if defined(INET) || defined(INET6)
|
||||
@ -1657,6 +1662,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
|
||||
pr->pr_flags = (pr->pr_flags & ~ch_flags) | pr_flags;
|
||||
mtx_unlock(&pr->pr_mtx);
|
||||
|
||||
#ifdef RACCT
|
||||
if (created)
|
||||
prison_racct_attach(pr);
|
||||
#endif
|
||||
|
||||
/* Locks may have prevented a complete restriction of child IP
|
||||
* addresses. If so, allocate some more memory and try again.
|
||||
*/
|
||||
@ -2533,10 +2543,9 @@ prison_deref(struct prison *pr, int flags)
|
||||
if (pr->pr_cpuset != NULL)
|
||||
cpuset_rel(pr->pr_cpuset);
|
||||
osd_jail_exit(pr);
|
||||
#ifdef RCTL
|
||||
rctl_racct_release(pr->pr_racct);
|
||||
#ifdef RACCT
|
||||
prison_racct_detach(pr);
|
||||
#endif
|
||||
racct_destroy(&pr->pr_racct);
|
||||
free(pr, M_PRISON);
|
||||
|
||||
/* Removing a prison frees a reference on its parent. */
|
||||
@ -4277,14 +4286,103 @@ void
|
||||
prison_racct_foreach(void (*callback)(struct racct *racct,
|
||||
void *arg2, void *arg3), void *arg2, void *arg3)
|
||||
{
|
||||
struct prison *pr;
|
||||
struct prison_racct *prr;
|
||||
|
||||
sx_slock(&allprison_lock);
|
||||
TAILQ_FOREACH(pr, &allprison, pr_list)
|
||||
(callback)(pr->pr_racct, arg2, arg3);
|
||||
LIST_FOREACH(prr, &allprison_racct, prr_next)
|
||||
(callback)(prr->prr_racct, arg2, arg3);
|
||||
sx_sunlock(&allprison_lock);
|
||||
}
|
||||
|
||||
static struct prison_racct *
|
||||
prison_racct_find_locked(const char *name)
|
||||
{
|
||||
struct prison_racct *prr;
|
||||
|
||||
sx_assert(&allprison_lock, SA_XLOCKED);
|
||||
|
||||
if (name[0] == '\0' || strlen(name) >= MAXHOSTNAMELEN)
|
||||
return (NULL);
|
||||
|
||||
LIST_FOREACH(prr, &allprison_racct, prr_next) {
|
||||
if (strcmp(name, prr->prr_name) != 0)
|
||||
continue;
|
||||
|
||||
/* Found prison_racct with a matching name? */
|
||||
prison_racct_hold(prr);
|
||||
return (prr);
|
||||
}
|
||||
|
||||
/* Add new prison_racct. */
|
||||
prr = malloc(sizeof(*prr), M_PRISON_RACCT, M_ZERO | M_WAITOK);
|
||||
racct_create(&prr->prr_racct);
|
||||
|
||||
strcpy(prr->prr_name, name);
|
||||
refcount_init(&prr->prr_refcount, 1);
|
||||
LIST_INSERT_HEAD(&allprison_racct, prr, prr_next);
|
||||
|
||||
return (prr);
|
||||
}
|
||||
|
||||
struct prison_racct *
|
||||
prison_racct_find(const char *name)
|
||||
{
|
||||
struct prison_racct *prr;
|
||||
|
||||
sx_xlock(&allprison_lock);
|
||||
prr = prison_racct_find_locked(name);
|
||||
sx_xunlock(&allprison_lock);
|
||||
return (prr);
|
||||
}
|
||||
|
||||
void
|
||||
prison_racct_hold(struct prison_racct *prr)
|
||||
{
|
||||
|
||||
refcount_acquire(&prr->prr_refcount);
|
||||
}
|
||||
|
||||
void
|
||||
prison_racct_free(struct prison_racct *prr)
|
||||
{
|
||||
int old;
|
||||
|
||||
old = prr->prr_refcount;
|
||||
if (old > 1 && atomic_cmpset_int(&prr->prr_refcount, old, old - 1))
|
||||
return;
|
||||
|
||||
sx_xlock(&allprison_lock);
|
||||
if (refcount_release(&prr->prr_refcount)) {
|
||||
racct_destroy(&prr->prr_racct);
|
||||
LIST_REMOVE(prr, prr_next);
|
||||
sx_xunlock(&allprison_lock);
|
||||
free(prr, M_PRISON_RACCT);
|
||||
|
||||
return;
|
||||
}
|
||||
sx_xunlock(&allprison_lock);
|
||||
}
|
||||
|
||||
#ifdef RACCT
|
||||
static void
|
||||
prison_racct_attach(struct prison *pr)
|
||||
{
|
||||
struct prison_racct *prr;
|
||||
|
||||
prr = prison_racct_find_locked(pr->pr_name);
|
||||
KASSERT(prr != NULL, ("cannot find prison_racct"));
|
||||
|
||||
pr->pr_prison_racct = prr;
|
||||
}
|
||||
|
||||
static void
|
||||
prison_racct_detach(struct prison *pr)
|
||||
{
|
||||
prison_racct_free(pr->pr_prison_racct);
|
||||
pr->pr_prison_racct = NULL;
|
||||
}
|
||||
#endif /* RACCT */
|
||||
|
||||
#ifdef DDB
|
||||
|
||||
static void
|
||||
|
@ -313,7 +313,8 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
|
||||
|
||||
racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
|
||||
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
|
||||
racct_alloc_resource(pr->pr_racct, resource, amount);
|
||||
racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
|
||||
amount);
|
||||
racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
|
||||
}
|
||||
|
||||
@ -522,7 +523,8 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
|
||||
|
||||
racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
|
||||
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
|
||||
racct_alloc_resource(pr->pr_racct, resource, -amount);
|
||||
racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
|
||||
-amount);
|
||||
racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
|
||||
}
|
||||
|
||||
@ -669,9 +671,11 @@ racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
|
||||
}
|
||||
if (newpr != oldpr) {
|
||||
for (pr = oldpr; pr != NULL; pr = pr->pr_parent)
|
||||
racct_sub_racct(pr->pr_racct, p->p_racct);
|
||||
racct_sub_racct(pr->pr_prison_racct->prr_racct,
|
||||
p->p_racct);
|
||||
for (pr = newpr; pr != NULL; pr = pr->pr_parent)
|
||||
racct_add_racct(pr->pr_racct, p->p_racct);
|
||||
racct_add_racct(pr->pr_prison_racct->prr_racct,
|
||||
p->p_racct);
|
||||
}
|
||||
mtx_unlock(&racct_lock);
|
||||
|
||||
@ -744,7 +748,7 @@ racct_init(void)
|
||||
/*
|
||||
* XXX: Move this somewhere.
|
||||
*/
|
||||
racct_create(&prison0.pr_racct);
|
||||
prison0.pr_prison_racct = prison_racct_find("0");
|
||||
}
|
||||
SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
|
||||
|
||||
|
@ -241,7 +241,8 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule)
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
available = rule->rr_amount -
|
||||
cred->cr_prison->pr_racct->r_resources[resource];
|
||||
cred->cr_prison->pr_prison_racct->prr_racct->
|
||||
r_resources[resource];
|
||||
break;
|
||||
default:
|
||||
panic("rctl_compute_available: unknown per %d",
|
||||
@ -327,7 +328,7 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount)
|
||||
printf("rctl: rule \"%s\" matched by pid %d "
|
||||
"(%s), uid %d, jail %s\n", sbuf_data(&sb),
|
||||
p->p_pid, p->p_comm, p->p_ucred->cr_uid,
|
||||
p->p_ucred->cr_prison->pr_name);
|
||||
p->p_ucred->cr_prison->pr_prison_racct->prr_name);
|
||||
sbuf_delete(&sb);
|
||||
free(buf, M_RCTL);
|
||||
link->rrl_exceeded = 1;
|
||||
@ -346,7 +347,7 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount)
|
||||
rctl_rule_to_sbuf(&sb, rule);
|
||||
sbuf_printf(&sb, " pid=%d ruid=%d jail=%s",
|
||||
p->p_pid, p->p_ucred->cr_ruid,
|
||||
p->p_ucred->cr_prison->pr_name);
|
||||
p->p_ucred->cr_prison->pr_prison_racct->prr_name);
|
||||
sbuf_finish(&sb);
|
||||
devctl_notify_f("RCTL", "rule", "matched",
|
||||
sbuf_data(&sb), M_NOWAIT);
|
||||
@ -481,9 +482,9 @@ rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter)
|
||||
return (0);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
if (filter->rr_subject.rs_prison != NULL &&
|
||||
rule->rr_subject.rs_prison !=
|
||||
filter->rr_subject.rs_prison)
|
||||
if (filter->rr_subject.rs_prison_racct != NULL &&
|
||||
rule->rr_subject.rs_prison_racct !=
|
||||
filter->rr_subject.rs_prison_racct)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
@ -635,7 +636,10 @@ rctl_rule_acquire_subject(struct rctl_rule *rule)
|
||||
switch (rule->rr_subject_type) {
|
||||
case RCTL_SUBJECT_TYPE_UNDEFINED:
|
||||
case RCTL_SUBJECT_TYPE_PROCESS:
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
if (rule->rr_subject.rs_prison_racct != NULL)
|
||||
prison_racct_hold(rule->rr_subject.rs_prison_racct);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_USER:
|
||||
if (rule->rr_subject.rs_uip != NULL)
|
||||
@ -658,7 +662,10 @@ rctl_rule_release_subject(struct rctl_rule *rule)
|
||||
switch (rule->rr_subject_type) {
|
||||
case RCTL_SUBJECT_TYPE_UNDEFINED:
|
||||
case RCTL_SUBJECT_TYPE_PROCESS:
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
if (rule->rr_subject.rs_prison_racct != NULL)
|
||||
prison_racct_free(rule->rr_subject.rs_prison_racct);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_USER:
|
||||
if (rule->rr_subject.rs_uip != NULL)
|
||||
@ -686,7 +693,7 @@ rctl_rule_alloc(int flags)
|
||||
rule->rr_subject.rs_proc = NULL;
|
||||
rule->rr_subject.rs_uip = NULL;
|
||||
rule->rr_subject.rs_loginclass = NULL;
|
||||
rule->rr_subject.rs_prison = NULL;
|
||||
rule->rr_subject.rs_prison_racct = NULL;
|
||||
rule->rr_per = RCTL_SUBJECT_TYPE_UNDEFINED;
|
||||
rule->rr_resource = RACCT_UNDEFINED;
|
||||
rule->rr_action = RCTL_ACTION_UNDEFINED;
|
||||
@ -708,7 +715,7 @@ rctl_rule_duplicate(const struct rctl_rule *rule, int flags)
|
||||
copy->rr_subject.rs_proc = rule->rr_subject.rs_proc;
|
||||
copy->rr_subject.rs_uip = rule->rr_subject.rs_uip;
|
||||
copy->rr_subject.rs_loginclass = rule->rr_subject.rs_loginclass;
|
||||
copy->rr_subject.rs_prison = rule->rr_subject.rs_prison;
|
||||
copy->rr_subject.rs_prison_racct = rule->rr_subject.rs_prison_racct;
|
||||
copy->rr_per = rule->rr_per;
|
||||
copy->rr_resource = rule->rr_resource;
|
||||
copy->rr_action = rule->rr_action;
|
||||
@ -784,7 +791,7 @@ rctl_rule_fully_specified(const struct rctl_rule *rule)
|
||||
return (0);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
if (rule->rr_subject.rs_prison == NULL)
|
||||
if (rule->rr_subject.rs_prison_racct == NULL)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
@ -833,7 +840,7 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep)
|
||||
rule->rr_subject.rs_proc = NULL;
|
||||
rule->rr_subject.rs_uip = NULL;
|
||||
rule->rr_subject.rs_loginclass = NULL;
|
||||
rule->rr_subject.rs_prison = NULL;
|
||||
rule->rr_subject.rs_prison_racct = NULL;
|
||||
} else {
|
||||
switch (rule->rr_subject_type) {
|
||||
case RCTL_SUBJECT_TYPE_UNDEFINED:
|
||||
@ -866,23 +873,12 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep)
|
||||
}
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
rule->rr_subject.rs_prison =
|
||||
prison_find_name(&prison0, subject_idstr);
|
||||
if (rule->rr_subject.rs_prison == NULL) {
|
||||
/*
|
||||
* No jail with that name; try with the JID.
|
||||
*/
|
||||
error = str2id(subject_idstr, &id);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
rule->rr_subject.rs_prison = prison_find(id);
|
||||
if (rule->rr_subject.rs_prison == NULL) {
|
||||
error = ESRCH;
|
||||
goto out;
|
||||
}
|
||||
rule->rr_subject.rs_prison_racct =
|
||||
prison_racct_find(subject_idstr);
|
||||
if (rule->rr_subject.rs_prison_racct == NULL) {
|
||||
error = ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
/* prison_find() returns with mutex held. */
|
||||
mtx_unlock(&rule->rr_subject.rs_prison->pr_mtx);
|
||||
break;
|
||||
default:
|
||||
panic("rctl_string_to_rule: unknown subject type %d",
|
||||
@ -944,6 +940,7 @@ rctl_rule_add(struct rctl_rule *rule)
|
||||
struct ucred *cred;
|
||||
struct uidinfo *uip;
|
||||
struct prison *pr;
|
||||
struct prison_racct *prr;
|
||||
struct loginclass *lc;
|
||||
struct rctl_rule *rule2;
|
||||
int match;
|
||||
@ -1008,9 +1005,9 @@ rctl_rule_add(struct rctl_rule *rule)
|
||||
break;
|
||||
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
pr = rule->rr_subject.rs_prison;
|
||||
KASSERT(pr != NULL, ("rctl_rule_add: NULL pr"));
|
||||
rctl_racct_add_rule(pr->pr_racct, rule);
|
||||
prr = rule->rr_subject.rs_prison_racct;
|
||||
KASSERT(prr != NULL, ("rctl_rule_add: NULL pr"));
|
||||
rctl_racct_add_rule(prr->prr_racct, rule);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1040,7 +1037,7 @@ rctl_rule_add(struct rctl_rule *rule)
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
match = 0;
|
||||
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) {
|
||||
if (pr == rule->rr_subject.rs_prison) {
|
||||
if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
@ -1144,11 +1141,11 @@ rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule)
|
||||
rule->rr_subject.rs_loginclass->lc_name);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
if (rule->rr_subject.rs_prison == NULL)
|
||||
if (rule->rr_subject.rs_prison_racct == NULL)
|
||||
sbuf_printf(sb, ":");
|
||||
else
|
||||
sbuf_printf(sb, "%s:",
|
||||
rule->rr_subject.rs_prison->pr_name);
|
||||
rule->rr_subject.rs_prison_racct->prr_name);
|
||||
break;
|
||||
default:
|
||||
panic("rctl_rule_to_sbuf: unknown subject type %d",
|
||||
@ -1245,7 +1242,7 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap)
|
||||
struct proc *p;
|
||||
struct uidinfo *uip;
|
||||
struct loginclass *lc;
|
||||
struct prison *pr;
|
||||
struct prison_racct *prr;
|
||||
|
||||
error = priv_check(td, PRIV_RCTL_GET_RACCT);
|
||||
if (error != 0)
|
||||
@ -1256,11 +1253,9 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap)
|
||||
return (error);
|
||||
|
||||
sx_slock(&allproc_lock);
|
||||
sx_slock(&allprison_lock);
|
||||
error = rctl_string_to_rule(inputstr, &filter);
|
||||
free(inputstr, M_RCTL);
|
||||
if (error != 0) {
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
@ -1295,19 +1290,18 @@ rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap)
|
||||
outputsbuf = rctl_racct_to_sbuf(lc->lc_racct, 1);
|
||||
break;
|
||||
case RCTL_SUBJECT_TYPE_JAIL:
|
||||
pr = filter->rr_subject.rs_prison;
|
||||
if (pr == NULL) {
|
||||
prr = filter->rr_subject.rs_prison_racct;
|
||||
if (prr == NULL) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
outputsbuf = rctl_racct_to_sbuf(pr->pr_racct, 1);
|
||||
outputsbuf = rctl_racct_to_sbuf(prr->prr_racct, 1);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
out:
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
@ -1354,11 +1348,9 @@ rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap)
|
||||
return (error);
|
||||
|
||||
sx_slock(&allproc_lock);
|
||||
sx_slock(&allprison_lock);
|
||||
error = rctl_string_to_rule(inputstr, &filter);
|
||||
free(inputstr, M_RCTL);
|
||||
if (error != 0) {
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
@ -1406,7 +1398,6 @@ rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap)
|
||||
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
|
||||
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
free(buf, M_RCTL);
|
||||
return (error);
|
||||
@ -1431,30 +1422,25 @@ rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap)
|
||||
return (error);
|
||||
|
||||
sx_slock(&allproc_lock);
|
||||
sx_slock(&allprison_lock);
|
||||
error = rctl_string_to_rule(inputstr, &filter);
|
||||
free(inputstr, M_RCTL);
|
||||
if (error != 0) {
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_UNDEFINED) {
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_PROCESS) {
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
if (filter->rr_subject.rs_proc == NULL) {
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (EINVAL);
|
||||
}
|
||||
@ -1486,7 +1472,6 @@ rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap)
|
||||
|
||||
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen);
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
free(buf, M_RCTL);
|
||||
return (error);
|
||||
@ -1508,11 +1493,9 @@ rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap)
|
||||
return (error);
|
||||
|
||||
sx_slock(&allproc_lock);
|
||||
sx_slock(&allprison_lock);
|
||||
error = rctl_string_to_rule(inputstr, &rule);
|
||||
free(inputstr, M_RCTL);
|
||||
if (error != 0) {
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
@ -1532,7 +1515,6 @@ rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap)
|
||||
|
||||
out:
|
||||
rctl_rule_release(rule);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
@ -1553,18 +1535,15 @@ rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap)
|
||||
return (error);
|
||||
|
||||
sx_slock(&allproc_lock);
|
||||
sx_slock(&allprison_lock);
|
||||
error = rctl_string_to_rule(inputstr, &filter);
|
||||
free(inputstr, M_RCTL);
|
||||
if (error != 0) {
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = rctl_rule_remove(filter);
|
||||
rctl_rule_release(filter);
|
||||
sx_sunlock(&allprison_lock);
|
||||
sx_sunlock(&allproc_lock);
|
||||
|
||||
return (error);
|
||||
@ -1580,12 +1559,12 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred)
|
||||
struct rctl_rule_link *link, *newlink;
|
||||
struct uidinfo *newuip;
|
||||
struct loginclass *newlc;
|
||||
struct prison *newpr;
|
||||
struct prison_racct *newprr;
|
||||
LIST_HEAD(, rctl_rule_link) newrules;
|
||||
|
||||
newuip = newcred->cr_ruidinfo;
|
||||
newlc = newcred->cr_loginclass;
|
||||
newpr = newcred->cr_prison;
|
||||
newprr = newcred->cr_prison->pr_prison_racct;
|
||||
|
||||
LIST_INIT(&newrules);
|
||||
|
||||
@ -1605,7 +1584,7 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred)
|
||||
rulecnt++;
|
||||
LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next)
|
||||
rulecnt++;
|
||||
LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next)
|
||||
LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next)
|
||||
rulecnt++;
|
||||
rw_runlock(&rctl_lock);
|
||||
|
||||
@ -1655,7 +1634,7 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred)
|
||||
rulecnt--;
|
||||
}
|
||||
|
||||
LIST_FOREACH(link, &newpr->pr_racct->r_rule_links, rrl_next) {
|
||||
LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next) {
|
||||
if (newlink == NULL)
|
||||
goto goaround;
|
||||
rctl_rule_acquire(link->rrl_rule);
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
@ -136,6 +136,7 @@ MALLOC_DECLARE(M_PRISON);
|
||||
#define HOSTUUIDLEN 64
|
||||
|
||||
struct racct;
|
||||
struct prison_racct;
|
||||
|
||||
/*
|
||||
* This structure describes a prison. It is pointed to by all struct
|
||||
@ -168,7 +169,7 @@ struct prison {
|
||||
int pr_ip6s; /* (p) number of v6 IPs */
|
||||
struct in_addr *pr_ip4; /* (p) v4 IPs of jail */
|
||||
struct in6_addr *pr_ip6; /* (p) v6 IPs of jail */
|
||||
struct racct *pr_racct; /* (c) resource accounting */
|
||||
struct prison_racct *pr_prison_racct; /* (c) racct jail proxy */
|
||||
void *pr_sparep[3];
|
||||
int pr_childcount; /* (a) number of child jails */
|
||||
int pr_childmax; /* (p) maximum child jails */
|
||||
@ -183,6 +184,13 @@ struct prison {
|
||||
char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */
|
||||
char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */
|
||||
};
|
||||
|
||||
struct prison_racct {
|
||||
LIST_ENTRY(prison_racct) prr_next;
|
||||
char prr_name[MAXHOSTNAMELEN];
|
||||
u_int prr_refcount;
|
||||
struct racct *prr_racct;
|
||||
};
|
||||
#endif /* _KERNEL || _WANT_PRISON */
|
||||
|
||||
#ifdef _KERNEL
|
||||
@ -385,6 +393,9 @@ int prison_priv_check(struct ucred *cred, int priv);
|
||||
int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
|
||||
void prison_racct_foreach(void (*callback)(struct racct *racct,
|
||||
void *arg2, void *arg3), void *arg2, void *arg3);
|
||||
struct prison_racct *prison_racct_find(const char *name);
|
||||
void prison_racct_hold(struct prison_racct *prr);
|
||||
void prison_racct_free(struct prison_racct *prr);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* !_SYS_JAIL_H_ */
|
||||
|
@ -44,7 +44,7 @@
|
||||
struct proc;
|
||||
struct uidinfo;
|
||||
struct loginclass;
|
||||
struct prison;
|
||||
struct prison_racct;
|
||||
struct ucred;
|
||||
struct rctl_rule_link;
|
||||
|
||||
@ -70,7 +70,7 @@ struct rctl_rule {
|
||||
struct proc *rs_proc;
|
||||
struct uidinfo *rs_uip;
|
||||
struct loginclass *rs_loginclass;
|
||||
struct prison *rs_prison;
|
||||
struct prison_racct *rs_prison_racct;
|
||||
} rr_subject;
|
||||
int rr_per;
|
||||
int rr_resource;
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/cputypes.h>
|
||||
|
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
@ -31,6 +31,7 @@
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#include "vxge_info.h"
|
||||
#include <unistd.h>
|
||||
|
||||
static int sockfd;
|
||||
static struct ifreq ifr;
|
||||
@ -38,6 +39,15 @@ static struct ifreq ifr;
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
uid_t uid;
|
||||
|
||||
uid = getuid();
|
||||
|
||||
if (uid) {
|
||||
printf("vxge-manage: Operation not permitted.\nExiting...\n");
|
||||
goto _exit0;
|
||||
}
|
||||
|
||||
if (argc >= 4) {
|
||||
if (!((strcasecmp(argv[2], "regs") == 0) ||
|
||||
(strcasecmp(argv[2], "stats") == 0) ||
|
||||
|
@ -45,8 +45,8 @@
|
||||
02/01 Juli Mallett <jmallett@FreeBSD.org> born in Washington, Pennsylvania, United States, 1985
|
||||
02/02 Diomidis D. Spinellis <dds@FreeBSD.org> born in Athens, Greece, 1967
|
||||
02/02 Michael W Lucas <mwlucas@FreeBSD.org> born in Detroit, Michigan, United States, 1967
|
||||
02/02 Yoichi Nakayama <yoichi@FreeBSD.org> born in Tsu, Mie, Japan, 1976
|
||||
02/02 Dmitry Chagin <dchagin@FreeBSD.org> born in Stalingrad, USSR, 1976
|
||||
02/02 Yoichi Nakayama <yoichi@FreeBSD.org> born in Tsu, Mie, Japan, 1976
|
||||
02/05 Frank Laszlo <laszlof@FreeBSD.org> born in Howell, Michigan, United States, 1983
|
||||
02/10 David Greenman <dg@FreeBSD.org> born in Portland, Oregon, United States, 1968
|
||||
02/10 Paul Richards <paul@FreeBSD.org> born in Ammanford, Carmarthenshire, United Kingdom, 1968
|
||||
@ -68,7 +68,6 @@
|
||||
02/24 Johan Karlsson <johan@FreeBSD.org> born in Mariannelund, Sweden, 1974
|
||||
02/24 Colin Percival <cperciva@FreeBSD.org> born in Burnaby, Canada, 1981
|
||||
02/26 Pietro Cerutti <gahr@FreeBSD.org> born in Faido, Switzerland, 1984
|
||||
05/19 Sofian Brabez <sbz@FreeBSD.org> born in Toulouse, France, 1984
|
||||
02/28 Daichi GOTO <daichi@FreeBSD.org> born in Shimizu Suntou, Shizuoka, Japan, 1980
|
||||
03/01 Hye-Shik Chang <perky@FreeBSD.org> born in Daejeon, Republic of Korea, 1980
|
||||
03/02 Cy Schubert <cy@FreeBSD.org> born in Edmonton, Alberta, Canada, 1956
|
||||
@ -151,7 +150,8 @@
|
||||
05/17 Thomas Abthorpe <tabthorpe@FreeBSD.org> born in Port Arthur, Ontario, Canada, 1968
|
||||
05/19 Philippe Charnier <charnier@FreeBSD.org> born in Fontainebleau, France, 1966
|
||||
05/19 Ian Dowse <iedowse@FreeBSD.org> born in Dublin, Ireland, 1975
|
||||
05/20 Dan Moschuk <dan@FreeBSD.org> died in Burlington, Ontario, Canada, 2010
|
||||
05/19 Sofian Brabez <sbz@FreeBSD.org> born in Toulouse, France, 1984
|
||||
05/20 Dan Moschuk <dan@FreeBSD.org> died in Burlington, Ontario, Canada, 2010
|
||||
05/21 Kris Kennaway <kris@FreeBSD.org> born in Winnipeg, Manitoba, Canada, 1978
|
||||
05/22 Clive Tong-I Lin <clive@FreeBSD.org> born in Changhua, Taiwan, Republic of China, 1978
|
||||
05/22 Michael Bushkov <bushman@FreeBSD.org> born in Rostov-on-Don, Russian Federation, 1985
|
||||
@ -175,7 +175,7 @@
|
||||
06/04 Justin Gibbs <gibbs@FreeBSD.org> born in San Pedro, California, United States, 1973
|
||||
06/04 Jason Evans <jasone@FreeBSD.org> born in Greeley, Colorado, United States, 1973
|
||||
06/04 Thomas Moestl <tmm@FreeBSD.org> born in Braunschweig, Niedersachsen, Germany, 1980
|
||||
06/04 Zack Kirsch <zack@FreeBSD.org> born in Memphis, Tennessee, United States, 1982
|
||||
06/04 Zack Kirsch <zack@FreeBSD.org> born in Memphis, Tennessee, United States, 1982
|
||||
06/06 Sergei Kolobov <sergei@FreeBSD.org> born in Karpinsk, Russian Federation, 1972
|
||||
06/06 Alan Eldridge <alane@FreeBSD.org> died in Denver, Colorado, 2003
|
||||
06/07 Jimmy Olgeni <olgeni@FreeBSD.org> born in Milano, Italy, 1976
|
||||
|
@ -380,6 +380,19 @@ main(int argc, char *argv[])
|
||||
au_login_success();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This needs to happen before login_getpwclass to support
|
||||
* home directories on GSS-API authenticated NFS where the
|
||||
* kerberos credentials need to be saved so that the kernel
|
||||
* can authenticate to the NFS server.
|
||||
*/
|
||||
pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
pam_syslog("pam_setcred()");
|
||||
bail(NO_SLEEP_EXIT, 1);
|
||||
}
|
||||
pam_cred_established = 1;
|
||||
|
||||
/*
|
||||
* Establish the login class.
|
||||
*/
|
||||
@ -513,12 +526,11 @@ main(int argc, char *argv[])
|
||||
bail(NO_SLEEP_EXIT, 1);
|
||||
}
|
||||
|
||||
pam_err = pam_setcred(pamh, pam_silent|PAM_ESTABLISH_CRED);
|
||||
pam_err = pam_setcred(pamh, pam_silent|PAM_REINITIALIZE_CRED);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
pam_syslog("pam_setcred()");
|
||||
bail(NO_SLEEP_EXIT, 1);
|
||||
}
|
||||
pam_cred_established = 1;
|
||||
|
||||
pam_err = pam_open_session(pamh, pam_silent);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 14, 2011
|
||||
.Dd May 3, 2011
|
||||
.Dt RCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -90,7 +90,7 @@ Subject defines the kind of entity the rule applies to.
|
||||
It can be either process, user, login class, or jail.
|
||||
.Pp
|
||||
Subject ID identifies the subject. It can be user name,
|
||||
numerical user ID, login class name, jail name, or numerical jail ID.
|
||||
numerical user ID, login class name, or jail name.
|
||||
.Pp
|
||||
Resource identifies the resource the rule controls.
|
||||
.Pp
|
||||
@ -177,9 +177,9 @@ Prevent user "joe" from allocating more than 1GB of virtual memory.
|
||||
.Pp
|
||||
Remove all RCTL rules.
|
||||
.Pp
|
||||
.Dl rctl -hu jail:5
|
||||
.Dl rctl -hu jail:www
|
||||
.Pp
|
||||
Display resource usage information for jail with JID 5.
|
||||
Display resource usage information for jail named "www".
|
||||
.Pp
|
||||
.Dl rctl -l process:512
|
||||
.Pp
|
||||
|
@ -31,6 +31,9 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "cd9660.h"
|
||||
#include "cd9660_eltorito.h"
|
||||
|
||||
@ -497,11 +500,43 @@ cd9660_setup_boot_volume_descriptor(volume_descriptor *bvd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_write_apm_partition_entry(FILE *fd, int index, int total_partitions,
|
||||
off_t sector_start, off_t nsectors, off_t sector_size,
|
||||
const char *part_name, const char *part_type) {
|
||||
uint32_t apm32;
|
||||
uint16_t apm16;
|
||||
|
||||
fseeko(fd, (off_t)(index + 1) * sector_size, SEEK_SET);
|
||||
|
||||
/* Signature */
|
||||
apm16 = htons(0x504d);
|
||||
fwrite(&apm16, sizeof(apm16), 1, fd);
|
||||
apm16 = 0;
|
||||
fwrite(&apm16, sizeof(apm16), 1, fd);
|
||||
|
||||
/* Total number of partitions */
|
||||
apm32 = htonl(total_partitions);
|
||||
fwrite(&apm32, sizeof(apm32), 1, fd);
|
||||
/* Bounds */
|
||||
apm32 = htonl(sector_start);
|
||||
fwrite(&apm32, sizeof(apm32), 1, fd);
|
||||
apm32 = htonl(nsectors);
|
||||
fwrite(&apm32, sizeof(apm32), 1, fd);
|
||||
|
||||
fwrite(part_name, strlen(part_name) + 1, 1, fd);
|
||||
fseek(fd, 32 - strlen(part_name) - 1, SEEK_CUR);
|
||||
fwrite(part_type, strlen(part_type) + 1, 1, fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_write_boot(FILE *fd)
|
||||
{
|
||||
struct boot_catalog_entry *e;
|
||||
struct cd9660_boot_image *t;
|
||||
int apm_partitions = 0;
|
||||
|
||||
/* write boot catalog */
|
||||
if (fseeko(fd, (off_t)diskStructure.boot_catalog_sector *
|
||||
@ -533,7 +568,51 @@ cd9660_write_boot(FILE *fd)
|
||||
t->filename, t->sector);
|
||||
}
|
||||
cd9660_copy_file(fd, t->sector, t->filename);
|
||||
|
||||
if (t->system == ET_SYS_MAC)
|
||||
apm_partitions++;
|
||||
}
|
||||
|
||||
if (apm_partitions > 0) {
|
||||
/* Write DDR and global APM info */
|
||||
uint32_t apm32;
|
||||
uint16_t apm16;
|
||||
int total_parts;
|
||||
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
apm16 = htons(0x4552);
|
||||
fwrite(&apm16, sizeof(apm16), 1, fd);
|
||||
apm16 = htons(diskStructure.sectorSize);
|
||||
fwrite(&apm16, sizeof(apm16), 1, fd);
|
||||
apm32 = htonl(diskStructure.totalSectors);
|
||||
fwrite(&apm32, sizeof(apm32), 1, fd);
|
||||
|
||||
/* Count total needed entries */
|
||||
total_parts = 2 + apm_partitions; /* Self + ISO9660 */
|
||||
|
||||
/* Write self-descriptor */
|
||||
cd9660_write_apm_partition_entry(fd, 0,
|
||||
total_parts, 1, total_parts, diskStructure.sectorSize,
|
||||
"Apple", "Apple_partition_map");
|
||||
|
||||
/* Write ISO9660 descriptor, enclosing the whole disk */
|
||||
cd9660_write_apm_partition_entry(fd, 1,
|
||||
total_parts, 0, diskStructure.totalSectors,
|
||||
diskStructure.sectorSize, "", "CD_ROM_Mode_1");
|
||||
|
||||
/* Write all partition entries */
|
||||
apm_partitions = 0;
|
||||
TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) {
|
||||
if (t->system != ET_SYS_MAC)
|
||||
continue;
|
||||
|
||||
cd9660_write_apm_partition_entry(fd,
|
||||
2 + apm_partitions++, total_parts,
|
||||
t->sector, t->num_sectors, diskStructure.sectorSize,
|
||||
"CD Boot", "Apple_Bootstrap");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user