This commit is contained in:
Attilio Rao 2011-05-03 18:57:46 +00:00
commit 94ebcddde3
56 changed files with 1240 additions and 235 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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 */

View File

@ -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.

View File

@ -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

View File

@ -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 },

View File

@ -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;
}

View File

@ -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]);

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -38,6 +38,6 @@ __FBSDID("$FreeBSD$");
void __main(void);
void
__main()
__main(void)
{
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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));

View File

@ -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);
}

View File

@ -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 */

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -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 .

View File

@ -20,3 +20,5 @@ options GEOM_PART_BSD
options GEOM_PART_EBR
options GEOM_PART_EBR_COMPAT
options GEOM_PART_MBR
options NEW_PCIB

View File

@ -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>

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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}

View File

@ -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

View File

@ -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));

View File

@ -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>

View File

@ -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;

View File

@ -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) {

View File

@ -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
}
/*
@ -390,17 +641,34 @@ pcib_attach_common(device_t dev)
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.

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -28,3 +28,5 @@ options GEOM_PART_MBR
# enable support for native hardware
options NATIVE
device atpic
options NEW_PCIB

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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_ */

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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) ||

View File

@ -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,6 +150,7 @@
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/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
@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;
}