diff --git a/contrib/top/commands.c b/contrib/top/commands.c index 47f4a2ea05fb..7891068a2517 100644 --- a/contrib/top/commands.c +++ b/contrib/top/commands.c @@ -94,6 +94,7 @@ S - toggle the displaying of system processes\n\ a - toggle the displaying of process titles\n\ t - toggle the display of this process\n\ u - display processes for only one user (+ selects all users)\n\ +z - toggle the displaying of the system idle process\n\ \n\ \n", stdout); } diff --git a/contrib/top/machine.h b/contrib/top/machine.h index a09424c19ca2..3e1af1609ece 100644 --- a/contrib/top/machine.h +++ b/contrib/top/machine.h @@ -65,6 +65,7 @@ struct process_select int uid; /* only this uid (unless uid == -1) */ int wcpu; /* show weighted cpu */ int jail; /* show jail ID */ + int kidle; /* show per-CPU idle threads */ char *command; /* only this command (unless == NULL) */ }; diff --git a/contrib/top/top.X b/contrib/top/top.X index 830e50dd2346..41c3d78bd67a 100644 --- a/contrib/top/top.X +++ b/contrib/top/top.X @@ -10,7 +10,7 @@ top \- display and update information about the top cpu processes .SH SYNOPSIS .B top [ -.B \-abCHIijnPqStuv +.B \-abCHIijnPqStuvz ] [ .BI \-d count ] [ @@ -89,6 +89,10 @@ Use \*(lqbatch\*(rq mode. In this mode, all input from the terminal is ignored. Interrupt characters (such as ^C and ^\e) still have an effect. This is the default on a dumb terminal, or when the output is not a terminal. .TP +.B \-H +Display each thread for a multithreaded process individually. +By default a single summary line is displayed for each process. +.TP .B \-i Use \*(lqinteractive\*(rq mode. In this mode, any input is immediately read for processing. See the section on \*(lqInteractive Mode\*(rq @@ -142,6 +146,9 @@ Write version number information to stderr then exit immediately. No other processing takes place when this option is used. To see current revision information while top is running, use the help command \*(lq?\*(rq. .TP +.B \-z +Do not display the system idle process. +.TP .BI \-d count Show only .I count @@ -289,6 +296,9 @@ or .BR r enice command. .TP +.B H +Toggle the display of threads. +.TP .B i (or .BR I ) @@ -303,6 +313,9 @@ ID. Toggle the display of the .I top process. +.TP +.B z +Toggle the display of the system idle process. .SH "THE DISPLAY" The actual display varies depending on the specific variant of Unix that the machine is running. This description may not exactly match @@ -352,8 +365,11 @@ the order of the processes, and COMMAND is the name of the command that the process is currently running (if the process is swapped out, this column is marked \*(lq\*(rq). .SH NOTES -The \*(lqABANDONED\*(rq state (known in the kernel as \*(lqSWAIT\*(rq) was -abandoned, thus the name. A process should never end up in this state. +If a process is in the \*(lqSLEEP\*(rq or \*(lqLOCK\*(rq state, +the state column will report the name of the event or lock on which the +process is waiting. +Lock names are prefixed with an asterisk \*(lq*\*(rq while sleep events +are not. .SH AUTHOR William LeFebvre, EECS Department, Northwestern University .SH ENVIRONMENT diff --git a/contrib/top/top.c b/contrib/top/top.c index 762efaa2a723..6673a2768846 100644 --- a/contrib/top/top.c +++ b/contrib/top/top.c @@ -196,9 +196,9 @@ char *argv[]; fd_set readfds; #ifdef ORDER - static char command_chars[] = "\f qh?en#sdkriIutHmSCajo"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzo"; #else - static char command_chars[] = "\f qh?en#sdkriIutHmSCaj"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajz"; #endif /* these defines enumerate the "strchr"s of the commands in command_chars */ #define CMD_redraw 0 @@ -224,8 +224,9 @@ char *argv[]; #define CMD_wcputog 19 #define CMD_showargs 20 #define CMD_jidtog 21 +#define CMD_kidletog 22 #ifdef ORDER -#define CMD_order 22 +#define CMD_order 23 #endif /* set the buffer for stdout */ @@ -258,6 +259,7 @@ char *argv[]; ps.thread = No; ps.wcpu = 1; ps.jail = No; + ps.kidle = Yes; ps.command = NULL; /* get preset options from the environment */ @@ -283,7 +285,7 @@ char *argv[]; optind = 1; } - while ((i = getopt(ac, av, "CSIHPabijnquvs:d:U:m:o:t")) != EOF) + while ((i = getopt(ac, av, "CSIHPabijnquvzs:d:U:m:o:t")) != EOF) { switch(i) { @@ -412,10 +414,14 @@ char *argv[]; pcpu_stats = Yes; break; + case 'z': + ps.kidle = !ps.kidle; + break; + default: fprintf(stderr, "Top version %s\n" -"Usage: %s [-abCHIijnPqStuv] [-d count] [-m io | cpu] [-o field] [-s time]\n" +"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" " [-U username] [number]\n", version_string(), myname); exit(1); @@ -1075,7 +1081,13 @@ restart: reset_display(); putchar('\r'); break; - + case CMD_kidletog: + ps.kidle = !ps.kidle; + new_message(MT_standout | MT_delayed, + " %sisplaying system idle process.", + ps.kidle ? "D" : "Not d"); + putchar('\r'); + break; default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putchar('\r'); diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile index 77491f25207f..461de7100487 100644 --- a/sbin/ifconfig/Makefile +++ b/sbin/ifconfig/Makefile @@ -15,10 +15,16 @@ SRCS= ifconfig.c # base support # of the toolchain. # SRCS+= af_link.c # LLC support +.if ${MK_INET_SUPPORT} != "no" SRCS+= af_inet.c # IPv4 support +.endif +.if ${MK_INET6_SUPPORT} != "no" SRCS+= af_inet6.c # IPv6 support +.endif SRCS+= af_atalk.c # AppleTalk support +.if ${MK_INET6_SUPPORT} != "no" SRCS+= af_nd6.c # ND6 support +.endif SRCS+= ifclone.c # clone device support SRCS+= ifmac.c # MAC support @@ -38,6 +44,12 @@ SRCS+= ifpfsync.c # pfsync(4) support SRCS+= ifbridge.c # bridge support SRCS+= iflagg.c # lagg support +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+= -DINET6 +.endif +.if ${MK_INET_SUPPORT} != "no" +CFLAGS+= -DINET +.endif .if ${MK_IPX_SUPPORT} != "no" && !defined(RELEASE_CRUNCH) SRCS+= af_ipx.c # IPX support DPADD+= ${LIBIPX} diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index 2e27114af13a..6b4d73576382 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -200,5 +200,7 @@ static struct afswtch af_inet = { static __constructor void inet_ctor(void) { + if (!feature_present("inet")) + return; af_register(&af_inet); } diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 8fc143a5571d..2337c345647c 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -541,6 +541,9 @@ inet6_ctor(void) #define N(a) (sizeof(a) / sizeof(a[0])) size_t i; + if (!feature_present("inet6")) + return; + for (i = 0; i < N(inet6_cmds); i++) cmd_register(&inet6_cmds[i]); af_register(&af_inet6); diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c index e6b920af7bd4..5260c505c0d3 100644 --- a/sbin/ifconfig/af_nd6.c +++ b/sbin/ifconfig/af_nd6.c @@ -225,5 +225,9 @@ static struct afswtch af_nd6 = { static __constructor void nd6_ctor(void) { + + if (!feature_present("inet6")) + return; + af_register(&af_nd6); } diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index e28178a4b16b..45cf59b68919 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94 .\" $FreeBSD$ .\" -.Dd March 20, 2011 +.Dd May 31, 2011 .Dt IFCONFIG 8 .Os .Sh NAME @@ -42,7 +42,7 @@ .Op Fl n .Ar interface .Op Cm create -.Op Ar address_family +.Ar address_family .Oo .Ar address .Op Ar dest_address @@ -165,8 +165,10 @@ and .Dq link . .\" and .\" .Dq ns . -The default is -.Dq inet . +The default if available is +.Dq inet +or otherwise +.Dq link . .Dq ether and .Dq lladdr diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 7c5d3519f224..2963b9f092df 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -220,8 +220,10 @@ main(int argc, char *argv[]) ifindex = 0; if (argc == 1) { afp = af_getbyname(*argv); - if (afp == NULL) + if (afp == NULL) { + warnx("Address family '%s' unknown.", *argv); usage(); + } if (afp->af_name != NULL) argc--, argv++; /* leave with afp non-zero */ @@ -484,7 +486,28 @@ ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp) int s; strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); - afp = uafp != NULL ? uafp : af_getbyname("inet"); + afp = NULL; + if (uafp != NULL) + afp = uafp; + /* + * This is the historical "accident" allowing users to configure IPv4 + * addresses without the "inet" keyword which while a nice feature has + * proven to complicate other things. We cannot remove this but only + * make sure we will never have a similar implicit default for IPv6 or + * any other address familiy. We need a fallback though for + * ifconfig IF up/down etc. to work without INET support as people + * never used ifconfig IF link up/down, etc. either. + */ +#ifdef INET + if (afp == NULL && feature_present("inet")) + afp = af_getbyname("inet"); +#endif + if (afp == NULL) + afp = af_getbyname("link"); + if (afp == NULL) { + warnx("Please specify an address_family."); + usage(); + } top: ifr.ifr_addr.sa_family = afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? diff --git a/sbin/umount/umount.8 b/sbin/umount/umount.8 index 91231a78b38c..cb3a97b8ed23 100644 --- a/sbin/umount/umount.8 +++ b/sbin/umount/umount.8 @@ -28,7 +28,7 @@ .\" @(#)umount.8 8.2 (Berkeley) 5/8/95 .\" $FreeBSD$ .\" -.Dd July 18, 2003 +.Dd May 31, 2011 .Dt UMOUNT 8 .Os .Sh NAME @@ -78,6 +78,9 @@ The file system is forcibly unmounted. Active special devices continue to work, but all other files return errors if further accesses are attempted. The root file system cannot be forcibly unmounted. +For NFS, a forced dismount can take up to 1 minute or more to +complete against an unresponsive server and may throw away +data not yet written to the server for this case. .It Fl h Ar host Only file systems mounted from the specified host will be unmounted. diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt index 68dda91e7013..f53fd426da4a 100644 --- a/sys/contrib/dev/acpica/changes.txt +++ b/sys/contrib/dev/acpica/changes.txt @@ -1,31 +1,99 @@ +---------------------------------------- +27 May 2011. Summary of changes for version 20110527: + +This release is available at www.acpica.org/downloads + +1) ACPI CA Core Subsystem: + +ASL Load() operator: Reinstate most restrictions on the incoming ACPI table +signature. Now, only allow SSDT, OEMx, and a null signature. History: + 1) Originally, we checked the table signature for "SSDT" or "PSDT". + (PSDT is now obsolete.) + 2) We added support for OEMx tables, signature "OEM" plus a fourth + "don't care" character. + 3) Valid tables were encountered with a null signature, so we just + gave up on validating the signature, (05/2008). + 4) We encountered non-AML tables such as the MADT, which caused + interpreter errors and kernel faults. So now, we once again allow + only SSDT, OEMx, and now, also a null signature. (05/2011). + +Added the missing _TDL predefined name to the global name list in order to +enable validation. Affects both the core ACPICA code and the iASL compiler. + +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug +version of the code includes the debug output trace mechanism and has a much +larger code and data size. + + Previous Release (VC 9.0): + Non-Debug Version: 90.0K Code, 23.8K Data, 113.8K Total + Debug Version: 164.5K Code, 68.0K Data, 232.5K Total + Current Release (VC 9.0): + Non-Debug Version: 90.1K Code, 23.9K Data, 114.0K Total + Debug Version: 165.6K Code, 68.4K Data, 234.0K Total + +2) iASL Compiler/Disassembler and Tools: + +Debugger/AcpiExec: Implemented support for "complex" method arguments on the +debugger command line. This adds support beyond simple integers -- including +Strings, Buffers, and Packages. Includes support for nested packages. +Increased the default command line buffer size to accommodate these arguments. +See the ACPICA reference for details and syntax. ACPICA BZ 917. + +Debugger/AcpiExec: Implemented support for "default" method arguments for the +Execute/Debug command. Now, the debugger will always invoke a control method +with the required number of arguments -- even if the command line specifies +none or insufficient arguments. It uses default integer values for any missing +arguments. Also fixes a bug where only six method arguments maximum were +supported instead of the required seven. + +Debugger/AcpiExec: Add a maximum buffer length parameter to AcpiOsGetLine and +also return status in order to prevent buffer overruns. See the ACPICA +reference for details and syntax. ACPICA BZ 921 + +iASL: Cleaned up support for Berkeley yacc. A general cleanup of code and +makefiles to simplify support for the two different but similar parser +generators, bison and yacc. + +Updated the generic unix makefile for gcc 4. The default gcc version is now +expected to be 4 or greater, since options specific to gcc 4 are used. + ---------------------------------------- 13 April 2011. Summary of changes for version 20110413: 1) ACPI CA Core Subsystem: Implemented support to execute a so-called "orphan" _REG method under the EC -device. This change will force the execution of a _REG method underneath the EC +device. This change will force the execution of a _REG method underneath the +EC device even if there is no corresponding operation region of type EmbeddedControl. Fixes a problem seen on some machines and apparently is compatible with Windows behavior. ACPICA BZ 875. Added more predefined methods that are eligible for automatic NULL package -element removal. This change adds another group of predefined names to the list +element removal. This change adds another group of predefined names to the +list of names that can be repaired by having NULL package elements dynamically removed. This group are those methods that return a single variable-length package containing simple data types such as integers, buffers, strings. This -includes: _ALx, _BCL, _CID,_ DOD, _EDL, _FIX, _PCL, _PLD, _PMD, _PRx, _PSL, _Sx, +includes: _ALx, _BCL, _CID,_ DOD, _EDL, _FIX, _PCL, _PLD, _PMD, _PRx, _PSL, +_Sx, and _TZD. ACPICA BZ 914. -Split and segregated all internal global lock functions to a new file, evglock.c. +Split and segregated all internal global lock functions to a new file, +evglock.c. -Updated internal address SpaceID for DataTable regions. Moved this internal space -id in preparation for ACPI 5.0 changes that will include some new space IDs. This +Updated internal address SpaceID for DataTable regions. Moved this internal +space +id in preparation for ACPI 5.0 changes that will include some new space IDs. +This change should not affect user/host code. -Example Code and Data Size: These are the sizes for the OS-independent acpica.lib +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug version of -the code includes the debug output trace mechanism and has a much larger code and +the code includes the debug output trace mechanism and has a much larger code +and data size. Previous Release (VC 9.0): @@ -40,34 +108,44 @@ data size. iASL/DTC: Major update for new grammar features. Allow generic data types in custom ACPI tables. Field names are now optional. Any line can be split to multiple lines using the continuation char (\). Large buffers now use line- -continuation character(s) and no colon on the continuation lines. See the grammar +continuation character(s) and no colon on the continuation lines. See the +grammar update in the iASL compiler reference. ACPI BZ 910,911. Lin Ming, Bob Moore. iASL: Mark ASL "Return()" and the simple "Return" as "Null" return statements. -Since the parser stuffs a "zero" as the return value for these statements (due to +Since the parser stuffs a "zero" as the return value for these statements (due +to the underlying AML grammar), they were seen as "return with value" by the iASL semantic checking. They are now seen correctly as "null" return statements. iASL: Check if a_REG declaration has a corresponding Operation Region. Adds a check for each _REG to ensure that there is in fact a corresponding operation -region declaration in the same scope. If not, the _REG method is not very useful +region declaration in the same scope. If not, the _REG method is not very +useful since it probably won't be executed. ACPICA BZ 915. -iASL/DTC: Finish support for expression evaluation. Added a new expression parser -that implements c-style operator precedence and parenthesization. ACPICA bugzilla +iASL/DTC: Finish support for expression evaluation. Added a new expression +parser +that implements c-style operator precedence and parenthesization. ACPICA +bugzilla 908. -Disassembler/DTC: Remove support for () and <> style comments in data tables. Now -that DTC has full expression support, we don't want to have comment strings that -start with a parentheses or a less-than symbol. Now, only the standard /* and // +Disassembler/DTC: Remove support for () and <> style comments in data tables. +Now +that DTC has full expression support, we don't want to have comment strings +that +start with a parentheses or a less-than symbol. Now, only the standard /* and +// comments are supported, as well as the bracket [] comments. -AcpiXtract: Fix for RSDP and dynamic SSDT extraction. These tables have "unusual" +AcpiXtract: Fix for RSDP and dynamic SSDT extraction. These tables have +"unusual" headers in the acpidump file. Update the header validation to support these tables. Problem introduced in previous AcpiXtract version in the change to support "wrong checksum" error messages emitted by acpidump utility. -iASL: Add a * option to generate all template files (as a synonym for ALL) as in +iASL: Add a * option to generate all template files (as a synonym for ALL) as +in "iasl -T *" or "iasl -T ALL". iASL/DTC: Do not abort compiler on fatal errors. We do not want to completely @@ -81,7 +159,8 @@ invocation. 1) ACPI CA Core Subsystem: Fixed a problem caused by a _PRW method appearing at the namespace root scope -during the setup of wake GPEs. A fault could occur if a _PRW directly under the +during the setup of wake GPEs. A fault could occur if a _PRW directly under +the root object was passed to the AcpiSetupGpeForWake interface. Lin Ming. Implemented support for "spurious" Global Lock interrupts. On some systems, a @@ -89,9 +168,11 @@ global lock interrupt can occur without the pending flag being set. Upon a GL interrupt, we now ensure that a thread is actually waiting for the lock before signaling GL availability. Rafael Wysocki, Bob Moore. -Example Code and Data Size: These are the sizes for the OS-independent acpica.lib +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 9.0 32-bit compiler. The debug version of -the code includes the debug output trace mechanism and has a much larger code and +the code includes the debug output trace mechanism and has a much larger code +and data size. Previous Release (VC 9.0): @@ -108,14 +189,16 @@ header files, disassembler, table compiler, and template generator. Bob Moore, Lin Ming. AcpiXtract: Correctly handle embedded comments and messages from AcpiDump. -Apparently some or all versions of acpidump will occasionally emit a comment like +Apparently some or all versions of acpidump will occasionally emit a comment +like "Wrong checksum", etc., into the dump file. This was causing problems for AcpiXtract. ACPICA BZ 905. iASL: Fix the Linux makefile by removing an inadvertent double file inclusion. ACPICA BZ 913. -AcpiExec: Update installation of operation region handlers. Install one handler +AcpiExec: Update installation of operation region handlers. Install one +handler for a user-defined address space. This is used by the ASL test suite (ASLTS). ---------------------------------------- diff --git a/sys/contrib/dev/acpica/debugger/dbexec.c b/sys/contrib/dev/acpica/debugger/dbexec.c index 3d46335fefa3..eb0dde21dde9 100644 --- a/sys/contrib/dev/acpica/debugger/dbexec.c +++ b/sys/contrib/dev/acpica/debugger/dbexec.c @@ -53,7 +53,8 @@ ACPI_MODULE_NAME ("dbexec") -static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; +static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo; +#define DB_DEFAULT_PKG_ELEMENTS 33 /* Local prototypes */ @@ -81,6 +82,348 @@ AcpiDbExecutionWalk ( void *Context, void **ReturnValue); +static ACPI_STATUS +AcpiDbHexCharToValue ( + int HexChar, + UINT8 *ReturnValue); + +static ACPI_STATUS +AcpiDbConvertToPackage ( + char *String, + ACPI_OBJECT *Object); + +static ACPI_STATUS +AcpiDbConvertToObject ( + ACPI_OBJECT_TYPE Type, + char *String, + ACPI_OBJECT *Object); + +static void +AcpiDbDeleteObjects ( + UINT32 Count, + ACPI_OBJECT *Objects); + + +/******************************************************************************* + * + * FUNCTION: AcpiDbHexCharToValue + * + * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F + * ReturnValue - Where the converted value is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16). + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbHexCharToValue ( + int HexChar, + UINT8 *ReturnValue) +{ + UINT8 Value; + + + /* Digit must be ascii [0-9a-fA-F] */ + + if (!ACPI_IS_XDIGIT (HexChar)) + { + return (AE_BAD_HEX_CONSTANT); + } + + if (HexChar <= 0x39) + { + Value = (UINT8) (HexChar - 0x30); + } + else + { + Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37); + } + + *ReturnValue = Value; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbHexByteToBinary + * + * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format: + * HiByte then LoByte. + * ReturnValue - Where the converted value is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255). + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbHexByteToBinary ( + char *HexByte, + UINT8 *ReturnValue) +{ + UINT8 Local0; + UINT8 Local1; + ACPI_STATUS Status; + + + /* High byte */ + + Status = AcpiDbHexCharToValue (HexByte[0], &Local0); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* Low byte */ + + Status = AcpiDbHexCharToValue (HexByte[1], &Local1); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + *ReturnValue = (UINT8) ((Local0 << 4) | Local1); + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbConvertToBuffer + * + * PARAMETERS: String - Input string to be converted + * Object - Where the buffer object is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a string to a buffer object. String is treated a list + * of buffer elements, each separated by a space or comma. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbConvertToBuffer ( + char *String, + ACPI_OBJECT *Object) +{ + UINT32 i; + UINT32 j; + UINT32 Length; + UINT8 *Buffer; + ACPI_STATUS Status; + + + /* Generate the final buffer length */ + + for (i = 0, Length = 0; String[i];) + { + i+=2; + Length++; + + while (String[i] && + ((String[i] == ',') || (String[i] == ' '))) + { + i++; + } + } + + Buffer = ACPI_ALLOCATE (Length); + if (!Buffer) + { + return (AE_NO_MEMORY); + } + + /* Convert the command line bytes to the buffer */ + + for (i = 0, j = 0; String[i];) + { + Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]); + if (ACPI_FAILURE (Status)) + { + ACPI_FREE (Buffer); + return (Status); + } + + j++; + i+=2; + while (String[i] && + ((String[i] == ',') || (String[i] == ' '))) + { + i++; + } + } + + Object->Type = ACPI_TYPE_BUFFER; + Object->Buffer.Pointer = Buffer; + Object->Buffer.Length = Length; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbConvertToPackage + * + * PARAMETERS: String - Input string to be converted + * Object - Where the package object is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a string to a package object. Handles nested packages + * via recursion with AcpiDbConvertToObject. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbConvertToPackage ( + char *String, + ACPI_OBJECT *Object) +{ + char *This; + char *Next; + UINT32 i; + ACPI_OBJECT_TYPE Type; + ACPI_OBJECT *Elements; + ACPI_STATUS Status; + + + Elements = ACPI_ALLOCATE_ZEROED ( + DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT)); + + This = String; + for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) + { + This = AcpiDbGetNextToken (This, &Next, &Type); + if (!This) + { + break; + } + + /* Recursive call to convert each package element */ + + Status = AcpiDbConvertToObject (Type, This, &Elements[i]); + if (ACPI_FAILURE (Status)) + { + AcpiDbDeleteObjects (i + 1, Elements); + ACPI_FREE (Elements); + return (Status); + } + + This = Next; + } + + Object->Type = ACPI_TYPE_PACKAGE; + Object->Package.Count = i; + Object->Package.Elements = Elements; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbConvertToObject + * + * PARAMETERS: Type - Object type as determined by parser + * String - Input string to be converted + * Object - Where the new object is returned + * + * RETURN: Status + * + * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing: + * 1) String objects were surrounded by quotes. + * 2) Buffer objects were surrounded by parentheses. + * 3) Package objects were surrounded by brackets "[]". + * 4) All standalone tokens are treated as integers. + * + ******************************************************************************/ + +static ACPI_STATUS +AcpiDbConvertToObject ( + ACPI_OBJECT_TYPE Type, + char *String, + ACPI_OBJECT *Object) +{ + ACPI_STATUS Status = AE_OK; + + + switch (Type) + { + case ACPI_TYPE_STRING: + Object->Type = ACPI_TYPE_STRING; + Object->String.Pointer = String; + Object->String.Length = (UINT32) ACPI_STRLEN (String); + break; + + case ACPI_TYPE_BUFFER: + Status = AcpiDbConvertToBuffer (String, Object); + break; + + case ACPI_TYPE_PACKAGE: + Status = AcpiDbConvertToPackage (String, Object); + break; + + default: + Object->Type = ACPI_TYPE_INTEGER; + Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value); + break; + } + + return (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDbDeleteObjects + * + * PARAMETERS: Count - Count of objects in the list + * Objects - Array of ACPI_OBJECTs to be deleted + * + * RETURN: None + * + * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested + * packages via recursion. + * + ******************************************************************************/ + +static void +AcpiDbDeleteObjects ( + UINT32 Count, + ACPI_OBJECT *Objects) +{ + UINT32 i; + + + for (i = 0; i < Count; i++) + { + switch (Objects[i].Type) + { + case ACPI_TYPE_BUFFER: + ACPI_FREE (Objects[i].Buffer.Pointer); + break; + + case ACPI_TYPE_PACKAGE: + + /* Recursive call to delete package elements */ + + AcpiDbDeleteObjects (Objects[i].Package.Count, + Objects[i].Package.Elements); + + /* Free the elements array */ + + ACPI_FREE (Objects[i].Package.Elements); + break; + + default: + break; + } + } +} + /******************************************************************************* * @@ -104,8 +447,8 @@ AcpiDbExecuteMethod ( ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_HANDLE Handle; - UINT32 i; ACPI_DEVICE_INFO *ObjInfo; + UINT32 i; ACPI_FUNCTION_TRACE (DbExecuteMethod); @@ -139,25 +482,37 @@ AcpiDbExecuteMethod ( { /* Are there arguments to the method? */ + i = 0; if (Info->Args && Info->Args[0]) { - for (i = 0; Info->Args[i] && + /* Get arguments passed on the command line */ + + for (; Info->Args[i] && (i < ACPI_METHOD_NUM_ARGS) && (i < ObjInfo->ParamCount); i++) { - Params[i].Type = ACPI_TYPE_INTEGER; - Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); + /* Convert input string (token) to an actual ACPI_OBJECT */ + + Status = AcpiDbConvertToObject (Info->Types[i], + Info->Args[i], &Params[i]); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "While parsing method arguments")); + goto Cleanup; + } } - - ParamObjects.Pointer = Params; - ParamObjects.Count = i; } - else - { - /* Setup default parameters */ - for (i = 0; i < ObjInfo->ParamCount; i++) + /* Create additional "default" parameters as needed */ + + if (i < ObjInfo->ParamCount) + { + AcpiOsPrintf ("Adding %u arguments containing default values\n", + ObjInfo->ParamCount - i); + + for (; i < ObjInfo->ParamCount; i++) { switch (i) { @@ -181,13 +536,11 @@ AcpiDbExecuteMethod ( break; } } - - ParamObjects.Pointer = Params; - ParamObjects.Count = ObjInfo->ParamCount; } - } - ACPI_FREE (ObjInfo); + ParamObjects.Count = ObjInfo->ParamCount; + ParamObjects.Pointer = Params; + } /* Prepare for a return object of arbitrary size */ @@ -198,7 +551,7 @@ AcpiDbExecuteMethod ( AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (NULL, - Info->Pathname, &ParamObjects, ReturnObj); + Info->Pathname, &ParamObjects, ReturnObj); AcpiGbl_CmSingleStep = FALSE; AcpiGbl_MethodExecuting = FALSE; @@ -206,16 +559,20 @@ AcpiDbExecuteMethod ( if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, - "while executing %s from debugger", Info->Pathname)); + "while executing %s from debugger", Info->Pathname)); if (Status == AE_BUFFER_OVERFLOW) { ACPI_ERROR ((AE_INFO, - "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", + "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length)); } } +Cleanup: + AcpiDbDeleteObjects (ObjInfo->ParamCount, Params); + ACPI_FREE (ObjInfo); + return_ACPI_STATUS (Status); } @@ -380,6 +737,7 @@ void AcpiDbExecute ( char *Name, char **Args, + ACPI_OBJECT_TYPE *Types, UINT32 Flags) { ACPI_STATUS Status; @@ -417,6 +775,7 @@ AcpiDbExecute ( AcpiUtStrupr (NameString); AcpiGbl_DbMethodInfo.Name = NameString; AcpiGbl_DbMethodInfo.Args = Args; + AcpiGbl_DbMethodInfo.Types = Types; AcpiGbl_DbMethodInfo.Flags = Flags; ReturnObj.Pointer = NULL; @@ -529,6 +888,8 @@ AcpiDbMethodThread ( LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr; LocalInfo.Arguments[3] = NULL; + LocalInfo.Types = LocalInfo.ArgTypes; + (void) AcpiOsSignalSemaphore (Info->InfoGate, 1); for (i = 0; i < Info->NumLoops; i++) @@ -696,6 +1057,12 @@ AcpiDbCreateExecutionThreads ( AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; AcpiGbl_DbMethodInfo.Arguments[3] = NULL; + + AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes; + AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER; + AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER; + AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER; + AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); diff --git a/sys/contrib/dev/acpica/debugger/dbinput.c b/sys/contrib/dev/acpica/debugger/dbinput.c index 5b8e70a4d007..7d8bbb765740 100644 --- a/sys/contrib/dev/acpica/debugger/dbinput.c +++ b/sys/contrib/dev/acpica/debugger/dbinput.c @@ -54,11 +54,6 @@ /* Local prototypes */ -static char * -AcpiDbGetNextToken ( - char *String, - char **Next); - static UINT32 AcpiDbGetLine ( char *InputBuffer); @@ -285,6 +280,10 @@ AcpiDbDisplayHelp ( AcpiOsPrintf (" Call Run to next control method invocation\n"); AcpiOsPrintf (" Debug [Arguments] Single Step a control method\n"); AcpiOsPrintf (" Execute [Arguments] Execute control method\n"); + AcpiOsPrintf (" Hex Integer Integer method argument\n"); + AcpiOsPrintf (" \"Ascii String\" String method argument\n"); + AcpiOsPrintf (" (Byte List) Buffer method argument\n"); + AcpiOsPrintf (" [Package Element List] Package method argument\n"); AcpiOsPrintf (" Go Allow method to run to completion\n"); AcpiOsPrintf (" Information Display info about the current method\n"); AcpiOsPrintf (" Into Step into (not over) a method call\n"); @@ -318,12 +317,15 @@ AcpiDbDisplayHelp ( * ******************************************************************************/ -static char * +char * AcpiDbGetNextToken ( char *String, - char **Next) + char **Next, + ACPI_OBJECT_TYPE *ReturnType) { char *Start; + UINT32 Depth; + ACPI_OBJECT_TYPE Type = ACPI_TYPE_INTEGER; /* At end of buffer? */ @@ -333,7 +335,7 @@ AcpiDbGetNextToken ( return (NULL); } - /* Get rid of any spaces at the beginning */ + /* Remove any spaces at the beginning */ if (*String == ' ') { @@ -348,22 +350,88 @@ AcpiDbGetNextToken ( } } - if (*String == '"') + switch (*String) { + case '"': + /* This is a quoted string, scan until closing quote */ String++; Start = String; + Type = ACPI_TYPE_STRING; - /* Find end of token */ + /* Find end of string */ while (*String && (*String != '"')) { String++; } - } - else - { + break; + + case '(': + + /* This is the start of a buffer, scan until closing paren */ + + String++; + Start = String; + Type = ACPI_TYPE_BUFFER; + + /* Find end of buffer */ + + while (*String && (*String != ')')) + { + String++; + } + break; + + case '[': + + /* This is the start of a package, scan until closing bracket */ + + String++; + Depth = 1; + Start = String; + Type = ACPI_TYPE_PACKAGE; + + /* Find end of package (closing bracket) */ + + while (*String) + { + /* Handle String package elements */ + + if (*String == '"') + { + /* Find end of string */ + + String++; + while (*String && (*String != '"')) + { + String++; + } + if (!(*String)) + { + break; + } + } + else if (*String == '[') + { + Depth++; /* A nested package declaration */ + } + else if (*String == ']') + { + Depth--; + if (Depth == 0) /* Found final package closing bracket */ + { + break; + } + } + + String++; + } + break; + + default: + Start = String; /* Find end of token */ @@ -372,6 +440,7 @@ AcpiDbGetNextToken ( { String++; } + break; } if (!(*String)) @@ -384,6 +453,7 @@ AcpiDbGetNextToken ( *Next = String + 1; } + *ReturnType = Type; return (Start); } @@ -416,7 +486,8 @@ AcpiDbGetLine ( This = AcpiGbl_DbParsedBuf; for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) { - AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next); + AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next, + &AcpiGbl_DbArgTypes[i]); if (!AcpiGbl_DbArgs[i]) { break; @@ -575,7 +646,8 @@ AcpiDbCommandDispatch ( break; case CMD_DEBUG: - AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], EX_SINGLE_STEP); + AcpiDbExecute (AcpiGbl_DbArgs[1], + &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP); break; case CMD_DISASSEMBLE: @@ -601,7 +673,7 @@ AcpiDbCommandDispatch ( case CMD_EXECUTE: AcpiDbExecute (AcpiGbl_DbArgs[1], - &AcpiGbl_DbArgs[2], EX_NO_SINGLE_STEP); + &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP); break; case CMD_FIND: @@ -961,7 +1033,13 @@ AcpiDbUserCommands ( /* Get the user input line */ - (void) AcpiOsGetLine (AcpiGbl_DbLineBuf); + Status = AcpiOsGetLine (AcpiGbl_DbLineBuf, + ACPI_DB_LINE_BUFFER_SIZE, NULL); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line")); + return (Status); + } /* Check for single or multithreaded debug */ diff --git a/sys/contrib/dev/acpica/debugger/dbutils.c b/sys/contrib/dev/acpica/debugger/dbutils.c index 8385fc861411..bed52e6674e9 100644 --- a/sys/contrib/dev/acpica/debugger/dbutils.c +++ b/sys/contrib/dev/acpica/debugger/dbutils.c @@ -382,7 +382,7 @@ AcpiDbUInt32ToHexString ( UINT32 Value, char *Buffer) { - UINT8 i; + int i; if (Value == 0) @@ -391,10 +391,9 @@ AcpiDbUInt32ToHexString ( return; } - ACPI_STRCPY (Buffer, "0x"); - Buffer[10] = '\0'; + Buffer[8] = '\0'; - for (i = 9; i > 1; i--) + for (i = 7; i >= 0; i--) { Buffer[i] = Converter [Value & 0x0F]; Value = Value >> 4; diff --git a/sys/contrib/dev/acpica/debugger/dbxface.c b/sys/contrib/dev/acpica/debugger/dbxface.c index 2f3708ace971..e8602bc34a5a 100644 --- a/sys/contrib/dev/acpica/debugger/dbxface.c +++ b/sys/contrib/dev/acpica/debugger/dbxface.c @@ -137,7 +137,13 @@ AcpiDbStartCommand ( /* Get the user input line */ - (void) AcpiOsGetLine (AcpiGbl_DbLineBuf); + Status = AcpiOsGetLine (AcpiGbl_DbLineBuf, + ACPI_DB_LINE_BUFFER_SIZE, NULL); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line")); + return (Status); + } } Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, WalkState, Op); diff --git a/sys/contrib/dev/acpica/include/acconfig.h b/sys/contrib/dev/acpica/include/acconfig.h index 4b05ed383105..7a2107aa7699 100644 --- a/sys/contrib/dev/acpica/include/acconfig.h +++ b/sys/contrib/dev/acpica/include/acconfig.h @@ -200,7 +200,8 @@ * *****************************************************************************/ -#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */ +#define ACPI_DEBUGGER_MAX_ARGS ACPI_METHOD_NUM_ARGS + 2 /* Max command line arguments */ +#define ACPI_DB_LINE_BUFFER_SIZE 512 #define ACPI_DEBUGGER_COMMAND_PROMPT '-' #define ACPI_DEBUGGER_EXECUTE_PROMPT '%' diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h index 9b4822d14ae1..2c1fe73429d1 100644 --- a/sys/contrib/dev/acpica/include/acdebug.h +++ b/sys/contrib/dev/acpica/include/acdebug.h @@ -277,6 +277,7 @@ void AcpiDbExecute ( char *Name, char **Args, + ACPI_OBJECT_TYPE *Types, UINT32 Flags); void @@ -357,6 +358,12 @@ AcpiDbUserCommands ( char Prompt, ACPI_PARSE_OBJECT *Op); +char * +AcpiDbGetNextToken ( + char *String, + char **Next, + ACPI_OBJECT_TYPE *ReturnType); + /* * dbstats - Generation and display of ACPI table statistics diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h index fc20994fea42..ebbae0f59597 100644 --- a/sys/contrib/dev/acpica/include/acglobal.h +++ b/sys/contrib/dev/acpica/include/acglobal.h @@ -425,10 +425,11 @@ ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_ini_methods; ACPI_EXTERN BOOLEAN AcpiGbl_DbOpt_NoRegionSupport; ACPI_EXTERN char *AcpiGbl_DbArgs[ACPI_DEBUGGER_MAX_ARGS]; -ACPI_EXTERN char AcpiGbl_DbLineBuf[80]; -ACPI_EXTERN char AcpiGbl_DbParsedBuf[80]; -ACPI_EXTERN char AcpiGbl_DbScopeBuf[40]; -ACPI_EXTERN char AcpiGbl_DbDebugFilename[40]; +ACPI_EXTERN ACPI_OBJECT_TYPE AcpiGbl_DbArgTypes[ACPI_DEBUGGER_MAX_ARGS]; +ACPI_EXTERN char AcpiGbl_DbLineBuf[ACPI_DB_LINE_BUFFER_SIZE]; +ACPI_EXTERN char AcpiGbl_DbParsedBuf[ACPI_DB_LINE_BUFFER_SIZE]; +ACPI_EXTERN char AcpiGbl_DbScopeBuf[80]; +ACPI_EXTERN char AcpiGbl_DbDebugFilename[80]; ACPI_EXTERN BOOLEAN AcpiGbl_DbOutputToFile; ACPI_EXTERN char *AcpiGbl_DbBuffer; ACPI_EXTERN char *AcpiGbl_DbFilename; diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h index bdefb7671f60..2eb6fc21d465 100644 --- a/sys/contrib/dev/acpica/include/aclocal.h +++ b/sys/contrib/dev/acpica/include/aclocal.h @@ -1198,6 +1198,7 @@ typedef struct acpi_db_method_info UINT32 NumLoops; char Pathname[128]; char **Args; + ACPI_OBJECT_TYPE *Types; /* * Arguments to be passed to method for the command @@ -1206,6 +1207,7 @@ typedef struct acpi_db_method_info * Index of current thread inside all them created. */ char InitArgs; + ACPI_OBJECT_TYPE ArgTypes[4]; char *Arguments[4]; char NumThreadsStr[11]; char IdOfThreadStr[11]; diff --git a/sys/contrib/dev/acpica/include/acpiosxf.h b/sys/contrib/dev/acpica/include/acpiosxf.h index 53605ad162d3..43ca582ae3b2 100644 --- a/sys/contrib/dev/acpica/include/acpiosxf.h +++ b/sys/contrib/dev/acpica/include/acpiosxf.h @@ -376,9 +376,11 @@ AcpiOsRedirectOutput ( /* * Debug input */ -UINT32 +ACPI_STATUS AcpiOsGetLine ( - char *Buffer); + char *Buffer, + UINT32 BufferLength, + UINT32 *BytesRead); /* diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h index 891ccf388d8c..17552612ba77 100644 --- a/sys/contrib/dev/acpica/include/acpixf.h +++ b/sys/contrib/dev/acpica/include/acpixf.h @@ -48,7 +48,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20110413 +#define ACPI_CA_VERSION 0x20110527 #include #include diff --git a/sys/contrib/dev/acpica/include/acpredef.h b/sys/contrib/dev/acpica/include/acpredef.h index 884f118043a1..0496767a8675 100644 --- a/sys/contrib/dev/acpica/include/acpredef.h +++ b/sys/contrib/dev/acpica/include/acpredef.h @@ -470,6 +470,7 @@ static const ACPI_PREDEFINED_INFO PredefinedNames[] = {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, + {{"_TDL", 0, ACPI_RTYPE_INTEGER}}, {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, diff --git a/sys/contrib/dev/acpica/osunixxf.c b/sys/contrib/dev/acpica/osunixxf.c index 0983bd4d4ef0..f486c27da2a4 100644 --- a/sys/contrib/dev/acpica/osunixxf.c +++ b/sys/contrib/dev/acpica/osunixxf.c @@ -311,18 +311,21 @@ AcpiOsVprintf ( * * FUNCTION: AcpiOsGetLine * - * PARAMETERS: fmt - Standard printf format - * args - Argument list + * PARAMETERS: Buffer - Where to return the command line + * BufferLength - Maximum length of Buffer + * BytesRead - Where the actual byte count is returned * - * RETURN: Actual bytes read + * RETURN: Status and actual bytes read * * DESCRIPTION: Formatted input with argument list pointer * *****************************************************************************/ -UINT32 +ACPI_STATUS AcpiOsGetLine ( - char *Buffer) + char *Buffer, + UINT32 BufferLength, + UINT32 *BytesRead) { UINT8 Temp; UINT32 i; @@ -330,6 +333,11 @@ AcpiOsGetLine ( for (i = 0; ; i++) { + if (i >= BufferLength) + { + return (AE_BUFFER_OVERFLOW); + } + scanf ("%1c", &Temp); if (!Temp || Temp == '\n') { @@ -345,7 +353,11 @@ AcpiOsGetLine ( /* Return the number of bytes in the string */ - return (i); + if (BytesRead) + { + *BytesRead = i; + } + return (AE_OK); } diff --git a/sys/contrib/dev/acpica/tables/tbinstal.c b/sys/contrib/dev/acpica/tables/tbinstal.c index 8e2199fac7bf..8697fa1a39b4 100644 --- a/sys/contrib/dev/acpica/tables/tbinstal.c +++ b/sys/contrib/dev/acpica/tables/tbinstal.c @@ -144,12 +144,28 @@ AcpiTbAddTable ( } /* - * Originally, we checked the table signature for "SSDT" or "PSDT" here. - * Next, we added support for OEMx tables, signature "OEM". - * Valid tables were encountered with a null signature, so we've just - * given up on validating the signature, since it seems to be a waste - * of code. The original code was removed (05/2008). + * Validate the incoming table signature. + * + * 1) Originally, we checked the table signature for "SSDT" or "PSDT". + * 2) We added support for OEMx tables, signature "OEM". + * 3) Valid tables were encountered with a null signature, so we just + * gave up on validating the signature, (05/2008). + * 4) We encountered non-AML tables such as the MADT, which caused + * interpreter errors and kernel faults. So now, we once again allow + * only "SSDT", "OEMx", and now, also a null signature. (05/2011). */ + if ((TableDesc->Pointer->Signature[0] != 0x00) && + (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && + (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) + { + ACPI_ERROR ((AE_INFO, + "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx", + AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ? + TableDesc->Pointer->Signature : "????", + *(UINT32 *) TableDesc->Pointer->Signature)); + + return_ACPI_STATUS (AE_BAD_SIGNATURE); + } (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index 756ad3aa78b9..2ce254f4c4b0 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -6132,9 +6132,11 @@ pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) #ifdef __FreeBSD__ /* XXX MRT not always INET */ /* stick with table 0 though */ +#ifdef INET if (af == AF_INET) in_rtalloc_ign((struct route *)&ro, 0, 0); else +#endif rtalloc_ign((struct route *)&ro, 0); #else /* ! __FreeBSD__ */ rtalloc_noclone((struct route *)&ro, NO_CLONING); @@ -6214,9 +6216,11 @@ pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) # ifdef RTF_PRCLONING rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); # else /* !RTF_PRCLONING */ +#ifdef INET if (af == AF_INET) in_rtalloc_ign((struct route *)&ro, 0, 0); else +#endif rtalloc_ign((struct route *)&ro, 0); # endif #else /* ! __FreeBSD__ */ @@ -6789,11 +6793,13 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t a KMOD_UDPSTAT_INC(udps_badsum); break; } +#ifdef INET case IPPROTO_ICMP: { KMOD_ICMPSTAT_INC(icps_checksum); break; } +#endif #ifdef INET6 case IPPROTO_ICMPV6: { @@ -6889,9 +6895,11 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, case IPPROTO_UDP: KMOD_UDPSTAT_INC(udps_badsum); break; +#ifdef INET case IPPROTO_ICMP: KMOD_ICMPSTAT_INC(icps_checksum); break; +#endif #ifdef INET6 case IPPROTO_ICMPV6: KMOD_ICMP6STAT_INC(icp6s_checksum); diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c index 2a66fd8aa8bb..c41fcc6476ca 100644 --- a/sys/contrib/pf/net/pf_ioctl.c +++ b/sys/contrib/pf/net/pf_ioctl.c @@ -3735,9 +3735,12 @@ pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, */ int chk; - /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */ + /* We need a proper CSUM before we start (s. OpenBSD ip_output) */ if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { +#ifdef INET + /* XXX-BZ copy&paste error from r126261? */ in_delayed_cksum(*m); +#endif (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } chk = pf_test6(PF_OUT, ifp, m, NULL, inp); diff --git a/sys/contrib/pf/net/pf_norm.c b/sys/contrib/pf/net/pf_norm.c index 32ba9f418a47..cd6d65af082a 100644 --- a/sys/contrib/pf/net/pf_norm.c +++ b/sys/contrib/pf/net/pf_norm.c @@ -949,6 +949,7 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff, return (NULL); } +#ifdef INET int pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason, struct pf_pdesc *pd) @@ -1198,6 +1199,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason, return (PF_DROP); } +#endif #ifdef INET6 int diff --git a/sys/dev/acpica/Osd/OsdDebug.c b/sys/dev/acpica/Osd/OsdDebug.c index 84253574cf98..0547f758fcb3 100644 --- a/sys/dev/acpica/Osd/OsdDebug.c +++ b/sys/dev/acpica/Osd/OsdDebug.c @@ -47,20 +47,23 @@ __FBSDID("$FreeBSD$"); #include -UINT32 -AcpiOsGetLine(char *Buffer) +ACPI_STATUS +AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead) { #ifdef DDB - char *cp; + char *cp; - db_readline(Buffer, 80); - for (cp = Buffer; *cp != 0; cp++) - if (*cp == '\n') - *cp = 0; - return (AE_OK); + cp = Buffer; + if (db_readline(Buffer, BufferLength) > 0) + while (*cp != '\0' && *cp != '\n' && *cp != '\r') + cp++; + *cp = '\0'; + if (BytesRead != NULL) + *BytesRead = cp - Buffer; + return (AE_OK); #else - printf("AcpiOsGetLine called but no input support"); - return (AE_NOT_EXIST); + printf("AcpiOsGetLine called but no input support"); + return (AE_NOT_EXIST); #endif /* DDB */ } diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index db76bfab27d0..7560430bf8d7 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -199,6 +199,8 @@ static devclass_t ipw_devclass; DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, 0, 0); +MODULE_VERSION(ipw, 1); + static int ipw_probe(device_t dev) { diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index dc81309b1404..73b861c62cff 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -232,6 +232,8 @@ static devclass_t iwi_devclass; DRIVER_MODULE(iwi, pci, iwi_driver, iwi_devclass, 0, 0); +MODULE_VERSION(iwi, 1); + static __inline uint8_t MEM_READ_1(struct iwi_softc *sc, uint32_t addr) { diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 29e391f3548c..67e1a449a14b 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -401,6 +401,8 @@ static devclass_t iwn_devclass; DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0); +MODULE_VERSION(iwn, 1); + MODULE_DEPEND(iwn, firmware, 1, 1, 1); MODULE_DEPEND(iwn, pci, 1, 1, 1); MODULE_DEPEND(iwn, wlan, 1, 1, 1); diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c index 6cdfa348808f..28a3c0149f29 100644 --- a/sys/dev/nfe/if_nfe.c +++ b/sys/dev/nfe/if_nfe.c @@ -1889,7 +1889,7 @@ nfe_int_task(void *arg, int pending) if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { NFE_UNLOCK(sc); - nfe_enable_intr(sc); + nfe_disable_intr(sc); return; } diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index e1fffe14214e..38ebb7e4cc8b 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -273,6 +273,8 @@ static devclass_t wpi_devclass; DRIVER_MODULE(wpi, pci, wpi_driver, wpi_devclass, 0, 0); +MODULE_VERSION(wpi, 1); + static const uint8_t wpi_ridx_to_plcp[] = { /* OFDM: IEEE Std 802.11a-1999, pp. 14 Table 80 */ /* R1-R4 (ral/ural is R4-R1) */ diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 3ec12ca37a26..984724d93aed 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -3293,7 +3293,13 @@ nfs_pathconf(struct vop_pathconf_args *ap) struct thread *td = curthread; int attrflag, error; - if (NFS_ISV34(vp)) { + if (NFS_ISV4(vp) || (NFS_ISV3(vp) && (ap->a_name == _PC_LINK_MAX || + ap->a_name == _PC_NAME_MAX || ap->a_name == _PC_CHOWN_RESTRICTED || + ap->a_name == _PC_NO_TRUNC))) { + /* + * Since only the above 4 a_names are returned by the NFSv3 + * Pathconf RPC, there is no point in doing it for others. + */ error = nfsrpc_pathconf(vp, &pc, td->td_ucred, td, &nfsva, &attrflag, NULL); if (attrflag != 0) @@ -3302,7 +3308,10 @@ nfs_pathconf(struct vop_pathconf_args *ap) if (error != 0) return (error); } else { - /* For NFSv2, just fake them. */ + /* + * For NFSv2 (or NFSv3 when not one of the above 4 a_names), + * just fake them. + */ pc.pc_linkmax = LINK_MAX; pc.pc_namemax = NFS_MAXNAMLEN; pc.pc_notrunc = 1; diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index ae56990cd7ba..ac641a808226 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -553,7 +553,7 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus) (uintmax_t)base); #ifdef SMP - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) #endif { diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 41d2211bd124..7252865afe7e 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -316,7 +316,7 @@ cpu_startup(void *dummy) /* * Create sysctl tree for per-CPU information. */ - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { snprintf(nodename, sizeof(nodename), "%u", pc->pc_cpuid); sysctl_ctx_init(&pc->pc_md.sysctl_ctx); pc->pc_md.sysctl_tree = SYSCTL_ADD_NODE(&pc->pc_md.sysctl_ctx, diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index e3df54a0286c..15afea030182 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -357,7 +357,7 @@ cpu_mp_start() /* Keep 'em spinning until we unleash them... */ ia64_ap_state.as_spin = 1; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { pc->pc_md.current_pmap = kernel_pmap; pc->pc_other_cpus = all_cpus; CPU_NAND(&pc->pc_other_cpus, &pc->pc_cpumask); @@ -425,7 +425,7 @@ cpu_mp_unleash(void *dummy) cpus = 0; smp_cpus = 0; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { cpus++; if (pc->pc_md.awake) { kproc_create(ia64_store_mca_state, pc, NULL, 0, 0, @@ -463,7 +463,7 @@ ipi_selected(cpuset_t cpus, int ipi) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (CPU_OVERLAP(&cpus, &pc->pc_cpumask)) ipi_send(pc, ipi); } @@ -487,7 +487,7 @@ ipi_all_but_self(int ipi) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (pc != pcpup) ipi_send(pc, ipi); } diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 5f10ad6ff79a..411d53a64d83 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -535,7 +535,7 @@ pmap_invalidate_page(vm_offset_t va) critical_enter(); vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt); tag = ia64_ttag(va); - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs); atomic_cmpset_64(&pte->tag, tag, 1UL << 63); } diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c index af12d7dcf5a9..f412d17f6cc8 100644 --- a/sys/kern/kern_idle.c +++ b/sys/kern/kern_idle.c @@ -60,7 +60,7 @@ idle_setup(void *dummy) p = NULL; /* start with no idle process */ #ifdef SMP - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { #endif #ifdef SMP error = kproc_kthread_add(sched_idletd, NULL, &p, &td, diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 2fad27ce505c..592bb80aff52 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -1089,7 +1089,7 @@ forward_wakeup(int cpunum) CPU_OR(&dontuse, &hlt_cpus_mask); CPU_ZERO(&map2); if (forward_wakeup_use_loop) { - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { id = pc->pc_cpumask; if (!CPU_OVERLAP(&id, &dontuse) && pc->pc_curthread == pc->pc_idlethread) { @@ -1124,7 +1124,7 @@ forward_wakeup(int cpunum) } if (!CPU_EMPTY(&map)) { forward_wakeups_delivered++; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { id = pc->pc_cpumask; if (!CPU_OVERLAP(&map, &id)) continue; diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index bb78c00a7591..1d67864b1533 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -412,7 +412,7 @@ kdb_thr_ctx(struct thread *thr) return (&kdb_pcb); #if defined(SMP) && defined(KDB_STOPPEDPCB) - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (pc->pc_curthread == thr && CPU_OVERLAP(&stopped_cpus, &pc->pc_cpumask)) return (KDB_STOPPEDPCB(pc)); diff --git a/sys/kern/subr_msgbuf.c b/sys/kern/subr_msgbuf.c index 14cd39dd8316..c146ab0900ae 100644 --- a/sys/kern/subr_msgbuf.c +++ b/sys/kern/subr_msgbuf.c @@ -31,8 +31,16 @@ #include #include +#include +#include #include +/* + * Maximum number conversion buffer length: uintmax_t in base 2, plus <> + * around the priority, and a terminating NUL. + */ +#define MAXPRIBUF (sizeof(intmax_t) * NBBY + 3) + /* Read/write sequence numbers are modulo a multiple of the buffer size. */ #define SEQMOD(size) ((size) * 16) @@ -51,6 +59,9 @@ msgbuf_init(struct msgbuf *mbp, void *ptr, int size) mbp->msg_seqmod = SEQMOD(size); msgbuf_clear(mbp); mbp->msg_magic = MSG_MAGIC; + mbp->msg_lastpri = -1; + mbp->msg_needsnl = 0; + mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN); } /* @@ -80,6 +91,11 @@ msgbuf_reinit(struct msgbuf *mbp, void *ptr, int size) } msgbuf_clear(mbp); } + + mbp->msg_lastpri = -1; + /* Assume that the old message buffer didn't end in a newline. */ + mbp->msg_needsnl = 1; + mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN); } /* @@ -110,25 +126,140 @@ msgbuf_getcount(struct msgbuf *mbp) } /* - * Append a character to a message buffer. This function can be - * considered fully reentrant so long as the number of concurrent - * callers is less than the number of characters in the buffer. - * However, the message buffer is only guaranteed to be consistent - * for reading when there are no callers in this function. + * Add a character into the message buffer, and update the checksum and + * sequence number. + * + * The caller should hold the message buffer spinlock. + */ +static inline void +msgbuf_do_addchar(struct msgbuf *mbp, u_int *seq, int c) +{ + u_int pos; + + /* Make sure we properly wrap the sequence number. */ + pos = MSGBUF_SEQ_TO_POS(mbp, *seq); + + mbp->msg_cksum += (u_int)c - + (u_int)(u_char)mbp->msg_ptr[pos]; + + mbp->msg_ptr[pos] = c; + + *seq = MSGBUF_SEQNORM(mbp, *seq + 1); +} + +/* + * Append a character to a message buffer. */ void msgbuf_addchar(struct msgbuf *mbp, int c) { - u_int new_seq, pos, seq; + mtx_lock_spin(&mbp->msg_lock); + + msgbuf_do_addchar(mbp, &mbp->msg_wseq, c); + + mtx_unlock_spin(&mbp->msg_lock); +} + +/* + * Append a NUL-terminated string with a priority to a message buffer. + * Filter carriage returns if the caller requests it. + * + * XXX The carriage return filtering behavior is present in the + * msglogchar() API, however testing has shown that we don't seem to send + * carriage returns down this path. So do we still need it? + */ +void +msgbuf_addstr(struct msgbuf *mbp, int pri, char *str, int filter_cr) +{ + u_int seq; + size_t len, prefix_len; + char prefix[MAXPRIBUF]; + int nl, i; + + len = strlen(str); + prefix_len = 0; + nl = 0; + + /* If we have a zero-length string, no need to do anything. */ + if (len == 0) + return; + + mtx_lock_spin(&mbp->msg_lock); + + /* + * If this is true, we may need to insert a new priority sequence, + * so prepare the prefix. + */ + if (pri != -1) + prefix_len = sprintf(prefix, "<%d>", pri); + + /* + * Starting write sequence number. + */ + seq = mbp->msg_wseq; + + /* + * Whenever there is a change in priority, we have to insert a + * newline, and a priority prefix if the priority is not -1. Here + * we detect whether there was a priority change, and whether we + * did not end with a newline. If that is the case, we need to + * insert a newline before this string. + */ + if (mbp->msg_lastpri != pri && mbp->msg_needsnl != 0) { + + msgbuf_do_addchar(mbp, &seq, '\n'); + mbp->msg_needsnl = 0; + } + + for (i = 0; i < len; i++) { + /* + * If we just had a newline, and the priority is not -1 + * (and therefore prefix_len != 0), then we need a priority + * prefix for this line. + */ + if (mbp->msg_needsnl == 0 && prefix_len != 0) { + int j; + + for (j = 0; j < prefix_len; j++) + msgbuf_do_addchar(mbp, &seq, prefix[j]); + } + + /* + * Don't copy carriage returns if the caller requested + * filtering. + * + * XXX This matches the behavior of msglogchar(), but is it + * necessary? Testing has shown that we don't seem to get + * carriage returns here. + */ + if ((filter_cr != 0) && (str[i] == '\r')) + continue; + + /* + * Clear this flag if we see a newline. This affects whether + * we need to insert a new prefix or insert a newline later. + */ + if (str[i] == '\n') + mbp->msg_needsnl = 0; + else + mbp->msg_needsnl = 1; + + msgbuf_do_addchar(mbp, &seq, str[i]); + } + /* + * Update the write sequence number for the actual number of + * characters we put in the message buffer. (Depends on whether + * carriage returns are filtered.) + */ + mbp->msg_wseq = seq; + + /* + * Set the last priority. + */ + mbp->msg_lastpri = pri; + + mtx_unlock_spin(&mbp->msg_lock); - do { - seq = mbp->msg_wseq; - new_seq = MSGBUF_SEQNORM(mbp, seq + 1); - } while (atomic_cmpset_rel_int(&mbp->msg_wseq, seq, new_seq) == 0); - pos = MSGBUF_SEQ_TO_POS(mbp, seq); - atomic_add_int(&mbp->msg_cksum, (u_int)(u_char)c - - (u_int)(u_char)mbp->msg_ptr[pos]); - mbp->msg_ptr[pos] = c; } /* @@ -141,14 +272,21 @@ msgbuf_getchar(struct msgbuf *mbp) u_int len, wseq; int c; + mtx_lock_spin(&mbp->msg_lock); + wseq = mbp->msg_wseq; len = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq); - if (len == 0) + if (len == 0) { + mtx_unlock_spin(&mbp->msg_lock); return (-1); + } if (len > mbp->msg_size) mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size); c = (u_char)mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, mbp->msg_rseq)]; mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + 1); + + mtx_unlock_spin(&mbp->msg_lock); + return (c); } @@ -161,10 +299,14 @@ msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen) { u_int len, pos, wseq; + mtx_lock_spin(&mbp->msg_lock); + wseq = mbp->msg_wseq; len = MSGBUF_SEQSUB(mbp, wseq, mbp->msg_rseq); - if (len == 0) + if (len == 0) { + mtx_unlock_spin(&mbp->msg_lock); return (0); + } if (len > mbp->msg_size) { mbp->msg_rseq = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size); len = mbp->msg_size; @@ -175,6 +317,9 @@ msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen) bcopy(&mbp->msg_ptr[pos], buf, len); mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq + len); + + mtx_unlock_spin(&mbp->msg_lock); + return (len); } @@ -193,16 +338,21 @@ msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp) { u_int len, pos, wseq; + mtx_lock_spin(&mbp->msg_lock); + if (buf == NULL) { /* Just initialise *seqp. */ *seqp = MSGBUF_SEQNORM(mbp, mbp->msg_wseq - mbp->msg_size); + mtx_unlock_spin(&mbp->msg_lock); return (0); } wseq = mbp->msg_wseq; len = MSGBUF_SEQSUB(mbp, wseq, *seqp); - if (len == 0) + if (len == 0) { + mtx_unlock_spin(&mbp->msg_lock); return (0); + } if (len > mbp->msg_size) { *seqp = MSGBUF_SEQNORM(mbp, wseq - mbp->msg_size); len = mbp->msg_size; @@ -212,6 +362,9 @@ msgbuf_peekbytes(struct msgbuf *mbp, char *buf, int buflen, u_int *seqp) len = min(len, (u_int)buflen); bcopy(&mbp->msg_ptr[MSGBUF_SEQ_TO_POS(mbp, *seqp)], buf, len); *seqp = MSGBUF_SEQNORM(mbp, *seqp + len); + + mtx_unlock_spin(&mbp->msg_lock); + return (len); } diff --git a/sys/kern/subr_pcpu.c b/sys/kern/subr_pcpu.c index 9201bb7e8cfc..a6b3ae09defc 100644 --- a/sys/kern/subr_pcpu.c +++ b/sys/kern/subr_pcpu.c @@ -74,7 +74,7 @@ static TAILQ_HEAD(, dpcpu_free) dpcpu_head = TAILQ_HEAD_INITIALIZER(dpcpu_head); static struct sx dpcpu_lock; uintptr_t dpcpu_off[MAXCPU]; struct pcpu *cpuid_to_pcpu[MAXCPU]; -struct cpuhead cpuhead = SLIST_HEAD_INITIALIZER(cpuhead); +struct cpuhead cpuhead = STAILQ_HEAD_INITIALIZER(cpuhead); /* * Initialize the MI portions of a struct pcpu. @@ -89,7 +89,7 @@ pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) pcpu->pc_cpuid = cpuid; CPU_SETOF(cpuid, &pcpu->pc_cpumask); cpuid_to_pcpu[cpuid] = pcpu; - SLIST_INSERT_HEAD(&cpuhead, pcpu, pc_allcpu); + STAILQ_INSERT_TAIL(&cpuhead, pcpu, pc_allcpu); cpu_pcpu_init(pcpu, cpuid, size); pcpu->pc_rm_queue.rmq_next = &pcpu->pc_rm_queue; pcpu->pc_rm_queue.rmq_prev = &pcpu->pc_rm_queue; @@ -245,7 +245,7 @@ void pcpu_destroy(struct pcpu *pcpu) { - SLIST_REMOVE(&cpuhead, pcpu, pcpu, pc_allcpu); + STAILQ_REMOVE(&cpuhead, pcpu, pcpu, pc_allcpu); cpuid_to_pcpu[pcpu->pc_cpuid] = NULL; dpcpu_off[pcpu->pc_cpuid] = 0; } diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index d0d2ad7f3614..3334837747f5 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -94,6 +94,7 @@ struct snprintf_arg { extern int log_open; static void msglogchar(int c, int pri); +static void msglogstr(char *str, int pri, int filter_cr); static void putchar(int ch, void *arg); static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper); static void snprintf_func(int ch, void *arg); @@ -106,6 +107,14 @@ TUNABLE_INT("kern.log_console_output", &log_console_output); SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW, &log_console_output, 0, "Duplicate console output to the syslog."); +/* + * See the comment in log_console() below for more explanation of this. + */ +static int log_console_add_linefeed = 0; +TUNABLE_INT("kern.log_console_add_linefeed", &log_console_add_linefeed); +SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RW, + &log_console_add_linefeed, 0, "log_console() adds extra newlines."); + static int always_console_output = 0; TUNABLE_INT("kern.always_console_output", &always_console_output); SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RW, @@ -240,16 +249,37 @@ log(int level, const char *fmt, ...) { va_list ap; struct putchar_arg pca; +#ifdef PRINTF_BUFR_SIZE + char bufr[PRINTF_BUFR_SIZE]; +#endif pca.tty = NULL; pca.pri = level; pca.flags = log_open ? TOLOG : TOCONS; +#ifdef PRINTF_BUFR_SIZE + pca.p_bufr = bufr; + pca.p_next = pca.p_bufr; + pca.n_bufr = sizeof(bufr); + pca.remain = sizeof(bufr); + *pca.p_next = '\0'; +#else pca.p_bufr = NULL; +#endif va_start(ap, fmt); kvprintf(fmt, putchar, &pca, 10, ap); va_end(ap); +#ifdef PRINTF_BUFR_SIZE + /* Write any buffered console/log output: */ + if (*pca.p_bufr != '\0') { + if (pca.flags & TOLOG) + msglogstr(pca.p_bufr, level, /*filter_cr*/1); + + if (pca.flags & TOCONS) + cnputs(pca.p_bufr); + } +#endif msgbuftrigger = 1; } @@ -258,7 +288,7 @@ log(int level, const char *fmt, ...) void log_console(struct uio *uio) { - int c, i, error, nl; + int c, error, nl; char *consbuffer; int pri; @@ -271,20 +301,48 @@ log_console(struct uio *uio) nl = 0; while (uio->uio_resid > 0) { - c = imin(uio->uio_resid, CONSCHUNK); + c = imin(uio->uio_resid, CONSCHUNK - 1); error = uiomove(consbuffer, c, uio); if (error != 0) break; - for (i = 0; i < c; i++) { - msglogchar(consbuffer[i], pri); - if (consbuffer[i] == '\n') - nl = 1; - else - nl = 0; - } + /* Make sure we're NUL-terminated */ + consbuffer[c] = '\0'; + if (consbuffer[c - 1] == '\n') + nl = 1; + else + nl = 0; + msglogstr(consbuffer, pri, /*filter_cr*/ 1); + } + /* + * The previous behavior in log_console() is preserved when + * log_console_add_linefeed is non-zero. For that behavior, if an + * individual console write came in that was not terminated with a + * line feed, it would add a line feed. + * + * This results in different data in the message buffer than + * appears on the system console (which doesn't add extra line feed + * characters). + * + * A number of programs and rc scripts write a line feed, or a period + * and a line feed when they have completed their operation. On + * the console, this looks seamless, but when displayed with + * 'dmesg -a', you wind up with output that looks like this: + * + * Updating motd: + * . + * + * On the console, it looks like this: + * Updating motd:. + * + * We could add logic to detect that situation, or just not insert + * the extra newlines. Set the kern.log_console_add_linefeed + * sysctl/tunable variable to get the old behavior. + */ + if (!nl && log_console_add_linefeed) { + consbuffer[0] = '\n'; + consbuffer[1] = '\0'; + msglogstr(consbuffer, pri, /*filter_cr*/ 1); } - if (!nl) - msglogchar('\n', pri); msgbuftrigger = 1; free(uio, M_IOV); free(consbuffer, M_TEMP); @@ -330,9 +388,11 @@ vprintf(const char *fmt, va_list ap) retval = kvprintf(fmt, putchar, &pca, 10, ap); #ifdef PRINTF_BUFR_SIZE - /* Write any buffered console output: */ - if (*pca.p_bufr != '\0') + /* Write any buffered console/log output: */ + if (*pca.p_bufr != '\0') { cnputs(pca.p_bufr); + msglogstr(pca.p_bufr, pca.pri, /*filter_cr*/ 1); + } #endif if (!panicstr) @@ -342,18 +402,18 @@ vprintf(const char *fmt, va_list ap) } static void -putcons(int c, struct putchar_arg *ap) +putbuf(int c, struct putchar_arg *ap) { /* Check if no console output buffer was provided. */ - if (ap->p_bufr == NULL) + if (ap->p_bufr == NULL) { /* Output direct to the console. */ - cnputc(c); - else { + if (ap->flags & TOCONS) + cnputc(c); + + if (ap->flags & TOLOG) + msglogchar(c, ap->pri); + } else { /* Buffer the character: */ - if (c == '\n') { - *ap->p_next++ = '\r'; - ap->remain--; - } *ap->p_next++ = c; ap->remain--; @@ -361,12 +421,35 @@ putcons(int c, struct putchar_arg *ap) *ap->p_next = '\0'; /* Check if the buffer needs to be flushed. */ - if (ap->remain < 3 || c == '\n') { - cnputs(ap->p_bufr); + if (ap->remain == 2 || c == '\n') { + + if (ap->flags & TOLOG) + msglogstr(ap->p_bufr, ap->pri, /*filter_cr*/1); + + if (ap->flags & TOCONS) { + if ((panicstr == NULL) && (constty != NULL)) + msgbuf_addstr(&consmsgbuf, -1, + ap->p_bufr, /*filter_cr*/ 0); + + if ((constty == NULL) ||(always_console_output)) + cnputs(ap->p_bufr); + } + ap->p_next = ap->p_bufr; ap->remain = ap->n_bufr; *ap->p_next = '\0'; } + + /* + * Since we fill the buffer up one character at a time, + * this should not happen. We should always catch it when + * ap->remain == 2 (if not sooner due to a newline), flush + * the buffer and move on. One way this could happen is + * if someone sets PRINTF_BUFR_SIZE to 1 or something + * similarly silly. + */ + KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd", + ap->remain)); } } @@ -381,26 +464,25 @@ putchar(int c, void *arg) struct putchar_arg *ap = (struct putchar_arg*) arg; struct tty *tp = ap->tty; int flags = ap->flags; + int putbuf_done = 0; /* Don't use the tty code after a panic or while in ddb. */ if (kdb_active) { if (c != '\0') cnputc(c); - } else if (panicstr || ((flags & TOCONS) && constty == NULL)) { - if (c != '\0') - putcons(c, ap); } else { - if ((flags & TOTTY) && tp != NULL) + if ((panicstr == NULL) && (flags & TOTTY) && (tp != NULL)) tty_putchar(tp, c); + if (flags & TOCONS) { - if (constty != NULL) - msgbuf_addchar(&consmsgbuf, c); - if (always_console_output && c != '\0') - putcons(c, ap); + putbuf(c, ap); + putbuf_done = 1; } } - if ((flags & TOLOG)) - msglogchar(c, ap->pri); + if ((flags & TOLOG) && (putbuf_done == 0)) { + if (c != '\0') + putbuf(c, ap); + } } /* @@ -890,6 +972,15 @@ msglogchar(int c, int pri) } } +static void +msglogstr(char *str, int pri, int filter_cr) +{ + if (!msgbufmapped) + return; + + msgbuf_addstr(msgbufp, pri, str, filter_cr); +} + void msgbufinit(void *ptr, int size) { diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c index 8c93bd134fcc..79a3476a7784 100644 --- a/sys/mips/mips/mp_machdep.c +++ b/sys/mips/mips/mp_machdep.c @@ -85,7 +85,7 @@ ipi_selected(cpuset_t cpus, int ipi) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (CPU_OVERLAP(&cpus, &pc->pc_cpumask)) { CTR3(KTR_SMP, "%s: pc: %p, ipi: %x\n", __func__, pc, ipi); diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 67ec16014c32..127cf67706f4 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -1221,7 +1221,7 @@ netisr_start(void *arg) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (nws_count >= netisr_maxthreads) break; /* XXXRW: Is skipping absent CPUs still required here? */ diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 81fce092caba..e1cd071db40d 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -391,7 +391,7 @@ tlb_miss_lock(void) if (!smp_started) return; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (pc != pcpup) { CTR3(KTR_PMAP, "%s: tlb miss LOCK of CPU=%d, " @@ -417,7 +417,7 @@ tlb_miss_unlock(void) if (!smp_started) return; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (pc != pcpup) { CTR2(KTR_PMAP, "%s: tlb miss UNLOCK of CPU=%d", __func__, pc->pc_cpuid); diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 2e2fe24c1c13..62a97e925050 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -213,7 +213,7 @@ cpu_mp_unleash(void *dummy) cpus = 0; smp_cpus = 0; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { cpus++; pc->pc_other_cpus = all_cpus; CPU_NAND(&pc->pc_other_cpus, &pc->pc_cpumask); @@ -349,7 +349,7 @@ ipi_selected(cpuset_t cpus, int ipi) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (CPU_OVERLAP(&cpus, &pc->pc_cpumask)) ipi_send(pc, ipi); } @@ -369,7 +369,7 @@ ipi_all_but_self(int ipi) { struct pcpu *pc; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { if (pc != pcpup) ipi_send(pc, ipi); } diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c index 7edc3a33014a..304a0f39d17e 100644 --- a/sys/sparc64/sparc64/mp_machdep.c +++ b/sys/sparc64/sparc64/mp_machdep.c @@ -386,7 +386,7 @@ cpu_mp_unleash(void *v) ctx_inc = (TLB_CTX_USER_MAX - 1) / mp_ncpus; csa = &cpu_start_args; csa->csa_count = mp_ncpus; - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) { pc->pc_tlb_ctx = ctx_min; pc->pc_tlb_ctx_min = ctx_min; pc->pc_tlb_ctx_max = ctx_min + ctx_inc; diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 49eeae6b6ba6..b01a558c3b24 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -1278,7 +1278,7 @@ pmap_release(pmap_t pm) * to a kernel thread, leaving the pmap pointer unchanged. */ mtx_lock_spin(&sched_lock); - SLIST_FOREACH(pc, &cpuhead, pc_allcpu) + STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) if (pc->pc_pmap == pm) pc->pc_pmap = NULL; mtx_unlock_spin(&sched_lock); diff --git a/sys/sys/msgbuf.h b/sys/sys/msgbuf.h index 8435c6874532..67f80a55196a 100644 --- a/sys/sys/msgbuf.h +++ b/sys/sys/msgbuf.h @@ -33,15 +33,21 @@ #ifndef _SYS_MSGBUF_H_ #define _SYS_MSGBUF_H_ +#include +#include + struct msgbuf { - char *msg_ptr; /* pointer to buffer */ + char *msg_ptr; /* pointer to buffer */ #define MSG_MAGIC 0x063062 - u_int msg_magic; - u_int msg_size; /* size of buffer area */ - u_int msg_wseq; /* write sequence number */ - u_int msg_rseq; /* read sequence number */ - u_int msg_cksum; /* checksum of contents */ - u_int msg_seqmod; /* range for sequence numbers */ + u_int msg_magic; + u_int msg_size; /* size of buffer area */ + u_int msg_wseq; /* write sequence number */ + u_int msg_rseq; /* read sequence number */ + u_int msg_cksum; /* checksum of contents */ + u_int msg_seqmod; /* range for sequence numbers */ + int msg_lastpri; /* saved priority value */ + int msg_needsnl; /* set when newline needed */ + struct mtx msg_lock; /* mutex to protect the buffer */ }; /* Normalise a sequence number or a difference between sequence numbers. */ @@ -59,6 +65,7 @@ extern struct mtx msgbuf_lock; void msgbufinit(void *ptr, int size); void msgbuf_addchar(struct msgbuf *mbp, int c); +void msgbuf_addstr(struct msgbuf *mbp, int pri, char *str, int filter_cr); void msgbuf_clear(struct msgbuf *mbp); void msgbuf_copy(struct msgbuf *src, struct msgbuf *dst); int msgbuf_getbytes(struct msgbuf *mbp, char *buf, int buflen); diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h index 752d2dfbec0c..e6044a7a57b6 100644 --- a/sys/sys/pcpu.h +++ b/sys/sys/pcpu.h @@ -163,7 +163,7 @@ struct pcpu { uint64_t pc_switchtime; /* cpu_ticks() at last csw */ int pc_switchticks; /* `ticks' at last csw */ u_int pc_cpuid; /* This cpu number */ - SLIST_ENTRY(pcpu) pc_allcpu; + STAILQ_ENTRY(pcpu) pc_allcpu; struct lock_list_entry *pc_spinlocks; #ifdef KTR char pc_name[PCPU_NAME_LEN]; /* String name for KTR */ @@ -212,7 +212,7 @@ struct pcpu { #ifdef _KERNEL -SLIST_HEAD(cpuhead, pcpu); +STAILQ_HEAD(cpuhead, pcpu); extern struct cpuhead cpuhead; extern struct pcpu *cpuid_to_pcpu[MAXCPU]; diff --git a/tools/tools/nanobsd/nanobsd.sh b/tools/tools/nanobsd/nanobsd.sh index 2d2a4e797a22..c3e96b3f5cdc 100644 --- a/tools/tools/nanobsd/nanobsd.sh +++ b/tools/tools/nanobsd/nanobsd.sh @@ -418,7 +418,7 @@ populate_slice ( ) ( echo "Creating ${dev} with ${dir} (mounting on ${mnt})" newfs_part $dev $mnt $lbl cd ${dir} - find . -print | grep -Ev '/(CVS|\.svn)' | cpio -Ldumpv ${mnt} + find . -print | grep -Ev '/(CVS|\.svn)' | cpio -dumpv ${mnt} df -i ${mnt} umount ${mnt} ) diff --git a/usr.bin/tftp/main.c b/usr.bin/tftp/main.c index 989a5ae14d2c..e2954c88a0bf 100644 --- a/usr.bin/tftp/main.c +++ b/usr.bin/tftp/main.c @@ -155,7 +155,7 @@ static struct cmd cmdtab[] = { { "options", setoptions, "enable or disable RFC2347 style options" }, { "help", help, "print help information" }, - { "packetdrop", setpacketdrop, "artifical packetloss feature" }, + { "packetdrop", setpacketdrop, "artificial packetloss feature" }, { "?", help, "print help information" }, { NULL, NULL, NULL } }; @@ -955,7 +955,7 @@ setblocksize(int argc, char *argv[]) if (!options_rfc_enabled) printf("RFC2347 style options are not enabled " - "(but proceding anyway)\n"); + "(but proceeding anyway)\n"); if (argc != 1) { int size = atoi(argv[1]); @@ -993,7 +993,7 @@ setblocksize2(int argc, char *argv[]) if (!options_rfc_enabled || !options_extra_enabled) printf( "RFC2347 style or non-RFC defined options are not enabled " - "(but proceding anyway)\n"); + "(but proceeding anyway)\n"); if (argc != 1) { int size = atoi(argv[1]); diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index f98f64eb766b..4c5568249d40 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -624,6 +624,7 @@ get_process_info(struct system_info *si, struct process_select *sel, int show_system; int show_uid; int show_command; + int show_kidle; /* * Save the previous process info. @@ -664,6 +665,7 @@ get_process_info(struct system_info *si, struct process_select *sel, show_system = sel->system; show_uid = sel->uid != -1; show_command = sel->command != NULL; + show_kidle = sel->kidle; /* count up process states and get pointers to interesting procs */ total_procs = 0; @@ -705,6 +707,11 @@ get_process_info(struct system_info *si, struct process_select *sel, /* skip idle or non-running processes */ continue; + if (displaymode == DISP_CPU && !show_kidle && + pp->ki_tdflags & TDF_IDLETD) + /* skip kernel idle process */ + continue; + if (displaymode == DISP_IO && !show_idle && p_io == 0) /* skip processes that aren't doing I/O */ continue; diff --git a/usr.bin/top/top.local.1 b/usr.bin/top/top.local.1 index d7705e8a96c4..015b969b7251 100644 --- a/usr.bin/top/top.local.1 +++ b/usr.bin/top/top.local.1 @@ -1,10 +1,6 @@ .\" $FreeBSD$ .SH "FreeBSD NOTES" -.SH DISPLAY OF THREADS -The '-H' option will toggle the display of kernel visible thread contexts. -At runtime the 'H' key will toggle this mode. The default is OFF. - .SH DESCRIPTION OF MEMORY Mem: 9220K Active, 1M Inact, 3284K Wired, 1M Cache, 2M Buf, 1320K Free Swap: 91M Total, 79M Free, 13% Inuse, 80K In, 104K Out diff --git a/usr.sbin/pc-sysinstall/backend-query/enable-net.sh b/usr.sbin/pc-sysinstall/backend-query/enable-net.sh index 3c73550fa59e..8cd72a1bc5e7 100755 --- a/usr.sbin/pc-sysinstall/backend-query/enable-net.sh +++ b/usr.sbin/pc-sysinstall/backend-query/enable-net.sh @@ -1,6 +1,11 @@ #!/bin/sh #- # Copyright (c) 2010 iXsystems, Inc. All rights reserved. +# Copyright (c) 2011 The FreeBSD Foundation +# All rights reserved. +# +# Portions of this software were developed by Bjoern Zeeb +# under sponsorship from the FreeBSD Foundation. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -40,23 +45,67 @@ NETMASK="$3" DNS="$4" GATEWAY="$5" MIRRORFETCH="$6" +IPV6="$7" +IPV6GATE="$8" +IPV6DNS="$9" if [ -z "${NIC}" ] then - echo "ERROR: Usage enable-net " + echo "ERROR: Usage enable-net " \ + " " exit 150 fi if [ "$NIC" = "AUTO-DHCP" ] then enable_auto_dhcp +elif [ "$NIC" = "IPv6-SLAAC" ] +then + enable_auto_slaac + # In addition, if static values were defined, add them as well. + # We might not get DNS information from RAs, for example. + if [ -n "${IPV6}" ]; then + VAL="" + get_first_wired_nic + if [ -n "${VAL}" ]; then + ifconfig ${VAL} inet6 ${IPV6} alias + fi + fi + # Append only here. + if [ -n "${IPV6DNS}" ]; then + echo "nameserver ${IPV6DNS}" >>/etc/resolv.conf + fi + # Do not + if [ -n "${IPV6GATE}" ]; then + # Check if we have a default route already to not overwrite. + if ! route -n get -inet6 default > /dev/null 2>&1 ; then + route add -inet6 default ${IPV6GATE} + fi + fi else echo "Enabling NIC: $NIC" - ifconfig ${NIC} ${IP} ${NETMASK} + if [ -n "${IP}" ]; then + ifconfig ${NIC} inet ${IP} ${NETMASK} + fi + if [ -n "${IPV6}" ]; then + ifconfig ${NIC} inet6 ${IPV6} alias + fi - echo "nameserver ${DNS}" >/etc/resolv.conf + # Keep default from IPv4-only support times and clear the resolv.conf file. + : > /etc/resolv.conf + if [ -n "${DNS}" ]; then + echo "nameserver ${DNS}" >>/etc/resolv.conf + fi + if [ -n "${IPV6DNS}" ]; then + echo "nameserver ${IPV6DNS}" >>/etc/resolv.conf + fi - route add default ${GATE} + if [ -n "${GATE}" ]; then + route add -inet default ${GATE} + fi + if [ -n "${IPV6GATE}" ]; then + route add -inet6 default ${IPV6GATE} + fi fi case ${MIRRORFETCH} in diff --git a/usr.sbin/pc-sysinstall/backend-query/test-netup.sh b/usr.sbin/pc-sysinstall/backend-query/test-netup.sh index 4c8304ef7416..e0a3ebae0bb6 100755 --- a/usr.sbin/pc-sysinstall/backend-query/test-netup.sh +++ b/usr.sbin/pc-sysinstall/backend-query/test-netup.sh @@ -1,6 +1,11 @@ #!/bin/sh #- # Copyright (c) 2010 iXsystems, Inc. All rights reserved. +# Copyright (c) 2011 The FreeBSD Foundation +# All rights reserved. +# +# Portions of this software were developed by Bjoern Zeeb +# under sponsorship from the FreeBSD Foundation.# # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -26,8 +31,8 @@ # $FreeBSD$ -# Script which tests "fetch" when using a network connection, and saves -# if we are using direct connect, or need FTP passive mode +# Script which tries to ping "home" to see if Internet connectivity is +# available. ############################################################################# rm ${TMPDIR}/.testftp >/dev/null 2>/dev/null @@ -39,12 +44,26 @@ then exit 0 fi +ping6 -c 2 www.pcbsd.org >/dev/null 2>/dev/null +if [ "$?" = "0" ] +then + echo "ftp: Up" + exit 0 +fi + ping -c 2 www.freebsd.org >/dev/null 2>/dev/null if [ "$?" = "0" ] then echo "ftp: Up" exit 0 fi - + +ping6 -c 2 www.freebsd.org >/dev/null 2>/dev/null +if [ "$?" = "0" ] +then + echo "ftp: Up" + exit 0 +fi + echo "ftp: Down" exit 1 diff --git a/usr.sbin/pc-sysinstall/backend/functions-networking.sh b/usr.sbin/pc-sysinstall/backend/functions-networking.sh index d12a9cceb3a0..bdd5a1a84c16 100755 --- a/usr.sbin/pc-sysinstall/backend/functions-networking.sh +++ b/usr.sbin/pc-sysinstall/backend/functions-networking.sh @@ -1,6 +1,11 @@ #!/bin/sh #- # Copyright (c) 2010 iXsystems, Inc. All rights reserved. +# Copyright (c) 2011 The FreeBSD Foundation +# All rights reserved. +# +# Portions of this software were developed by Bjoern Zeeb +# under sponsorship from the FreeBSD Foundation. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -119,6 +124,61 @@ save_auto_dhcp() enable_dhcp_all }; +# Function which simply enables iPv6 SLAAC on all detected nics +enable_slaac_all() +{ + rm ${TMPDIR}/.niclist >/dev/null 2>/dev/null + # start by getting a list of nics on this system + ${QUERYDIR}/detect-nics.sh > ${TMPDIR}/.niclist + if [ -e "${TMPDIR}/.niclist" ] + then + echo "# Auto-Enabled NICs from pc-sysinstall" >>${FSMNT}/etc/rc.conf + WLANCOUNT="0" + while read line + do + NIC="`echo $line | cut -d ':' -f 1`" + DESC="`echo $line | cut -d ':' -f 2`" + echo_log "Setting $NIC to acceptign RAs on the system." + check_is_wifi ${NIC} + if [ $? -eq 0 ] + then + # We have a wifi device, setup a wlan* entry for it + # Given we cannot have DHCP and SLAAC the same time currently + # it's save to just duplicate. + WLAN="wlan${WLANCOUNT}" + echo "wlans_${NIC}=\"${WLAN}\"" >>${FSMNT}/etc/rc.conf + #echo "ifconfig_${NIC}=\"up\"" >>${FSMNT}/etc/rc.conf + echo "ifconfig_${WLAN}=\"inet6 accept_rtadv\"" >>${FSMNT}/etc/rc.conf + CNIC="${WLAN}" + WLANCOUNT=$((WLANCOUNT+1)) + else + #echo "ifconfig_${NIC}=\"up\"" >>${FSMNT}/etc/rc.conf + echo "ifconfig_${NIC}_ipv6=\"inet6 accept_rtadv\"" >>${FSMNT}/etc/rc.conf + CNIC="${NIC}" + fi + + done < ${TMPDIR}/.niclist + fi + + # Given we cannot yet rely on RAs to provide DNS information as much + # as we can in the DHCP world, we should append a given nameserver. + : > ${FSMNT}/etc/resolv.conf + get_value_from_cfg netSaveIPv6NameServer + NAMESERVER="${VAL}" + if [ -n "${NAMESERVER}" ] + then + echo "nameserver ${NAMESERVER}" >>${FSMNT}/etc/resolv.conf + fi + +}; + + +# Function which detects available nics, and enables IPv6 SLAAC on them +save_auto_slaac() +{ + enable_slaac_all +}; + # Function which saves a manual nic setup to the installed system save_manual_nic() @@ -137,21 +197,41 @@ save_manual_nic() fi # If we get here, we have a manual setup, lets do so now + IFARGS="" + IF6ARGS="" # Set the manual IP - IFARGS="inet ${NETIP}" - - # Check if we have a netmask to set - get_value_from_cfg netSaveMask - NETMASK="${VAL}" - if [ -n "${NETMASK}" ] + if [ -n "${NETIP}" ] then - IFARGS="${IFARGS} netmask ${NETMASK}" + IFARGS="inet ${NETIP}" + + # Check if we have a netmask to set + get_value_from_cfg netSaveMask + NETMASK="${VAL}" + if [ -n "${NETMASK}" ] + then + IFARGS="${IFARGS} netmask ${NETMASK}" + fi fi + get_value_from_cfg netSaveIPv6 + NETIP6="${VAL}" + if [ -n "${NETIP6}" ] + then + # Make sure we have one inet6 prefix. + IF6ARGS=`echo "${NETIP6}" | awk '{ if ("^inet6 ") { print $0; } else + { printf "inet6 %s", $0; } }'` + fi echo "# Auto-Enabled NICs from pc-sysinstall" >>${FSMNT}/etc/rc.conf - echo "ifconfig_${NIC}=\"${IFARGS}\"" >>${FSMNT}/etc/rc.conf + if [ -n "${IFARGS}" ] + then + echo "ifconfig_${NIC}=\"${IFARGS}\"" >>${FSMNT}/etc/rc.conf + fi + if [ -n "${IF6ARGS}" ] + then + echo "ifconfig_${NIC}_ipv6=\"${IF6ARGS}\"" >>${FSMNT}/etc/rc.conf + fi # Check if we have a default router to set get_value_from_cfg netSaveDefaultRouter @@ -160,15 +240,28 @@ save_manual_nic() then echo "defaultrouter=\"${NETROUTE}\"" >>${FSMNT}/etc/rc.conf fi + get_value_from_cfg netSaveIPv6DefaultRouter + NETROUTE="${VAL}" + if [ -n "${NETROUTE}" ] + then + echo "ipv6_defaultrouter=\"${NETROUTE}\"" >>${FSMNT}/etc/rc.conf + fi # Check if we have a nameserver to enable + : > ${FSMNT}/etc/resolv.conf get_value_from_cfg netSaveNameServer NAMESERVER="${VAL}" if [ -n "${NAMESERVER}" ] then - echo "nameserver ${NAMESERVER}" >${FSMNT}/etc/resolv.conf + echo "nameserver ${NAMESERVER}" >>${FSMNT}/etc/resolv.conf fi - + get_value_from_cfg netSaveIPv6NameServer + NAMESERVER="${VAL}" + if [ -n "${NAMESERVER}" ] + then + echo "nameserver ${NAMESERVER}" >>${FSMNT}/etc/resolv.conf + fi + }; # Function which determines if a nic is active / up @@ -208,6 +301,31 @@ enable_auto_dhcp() }; +# Function which detects available nics, and runs rtsol on them. +enable_auto_slaac() +{ + + # start by getting a list of nics on this system + ${QUERYDIR}/detect-nics.sh > ${TMPDIR}/.niclist + ALLNICS="" + while read line + do + NIC="`echo $line | cut -d ':' -f 1`" + DESC="`echo $line | cut -d ':' -f 2`" + + is_nic_active "${NIC}" + if [ $? -eq 0 ] ; then + echo_log "Will try IPv6 SLAAC on $NIC $DESC" + ifconfig ${NIC} inet6 -ifdisabled accept_rtadv up + ALLNICS="${ALLNICS} ${NIC}" + fi + done < ${TMPDIR}/.niclist + + # XXX once we support it in-tree call /sbin/resovconf here. + echo_log "Running rtsol on ${ALLNICS}" + rtsol -F ${ALLNICS} >/dev/null 2>/dev/null +} + # Get the mac address of a target NIC get_nic_mac() { @@ -236,15 +354,20 @@ enable_manual_nic() # If we get here, we have a manual setup, lets do so now - # Set the manual IP - rc_halt "ifconfig ${NIC} ${NETIP}" + # IPv4: - # Check if we have a netmask to set - get_value_from_cfg netMask - NETMASK="${VAL}" - if [ -n "${NETMASK}" ] + # Set the manual IP + if [ -n "${NETIP}" ] then - rc_halt "ifconfig ${NIC} netmask ${NETMASK}" + # Check if we have a netmask to set + get_value_from_cfg netMask + NETMASK="${VAL}" + if [ -n "${NETMASK}" ] + then + rc_halt "ifconfig inet ${NIC} netmask ${NETMASK}" + else + rc_halt "ifconfig inet ${NIC} ${NETIP}" + fi fi # Check if we have a default router to set @@ -252,18 +375,42 @@ enable_manual_nic() NETROUTE="${VAL}" if [ -n "${NETROUTE}" ] then - rc_halt "route add default ${NETROUTE}" + rc_halt "route add -inet default ${NETROUTE}" + fi + + # IPv6: + + # Set static IPv6 address + get_value_from_cfg netIPv6 + NETIP="${VAL}" + if [ -n ${NETIP} ] + then + rc_halt "ifconfig inet6 ${NIC} ${NETIP} -ifdisabled up" + fi + + # Default router + get_value_from_cfg netIPv6DefaultRouter + NETROUTE="${VAL}" + if [ -n "${NETROUTE}" ] + then + rc_halt "route add -inet6 default ${NETROUTE}" fi # Check if we have a nameserver to enable + : >/etc/resolv.conf get_value_from_cfg netNameServer NAMESERVER="${VAL}" if [ -n "${NAMESERVER}" ] then - echo "nameserver ${NAMESERVER}" >/etc/resolv.conf + echo "nameserver ${NAMESERVER}" >>/etc/resolv.conf fi - - + get_value_from_cfg netIPv6NameServer + NAMESERVER="${VAL}" + if [ -n "${NAMESERVER}" ] + then + echo "nameserver ${NAMESERVER}" >>/etc/resolv.conf + fi + }; @@ -281,6 +428,9 @@ start_networking() if [ "$NETDEV" = "AUTO-DHCP" ] then enable_auto_dhcp + elif [ "$NETDEV" = "IPv6-SLAAC" ] + then + enable_auto_slaac else enable_manual_nic ${NETDEV} fi @@ -304,6 +454,9 @@ save_networking_install() if [ "$NETDEV" = "AUTO-DHCP" ] then save_auto_dhcp + elif [ "$NETDEV" = "IPv6-SLAAC" ] + then + save_auto_slaac else save_manual_nic ${NETDEV} fi