diff --git a/Makefile.inc1 b/Makefile.inc1 index 26acc97e8478..44af27d8963b 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -833,7 +833,7 @@ IMAKEENV+= PATH=${TMPPATH}:${INSTALLTMP} # When generating install media, do not allow user and group information from # the build host to affect the contents of the distribution. -.if make(distributeworld) +.if make(distributeworld) || make(distrib-dirs) || make(distribution) DB_FROM_SRC= yes .endif @@ -1765,7 +1765,7 @@ create-packages: .PHONY create-packages-world create-packages-kernel create-world-packages: _pkgbootstrap .PHONY @rm -f ${WSTAGEDIR}/*.plist 2>/dev/null || : @cd ${WSTAGEDIR} ; \ - env -i LC_COLLATE=C sort ${WSTAGEDIR}/METALOG | \ + env -i LC_COLLATE=C sort ${WSTAGEDIR}/${DISTDIR}/METALOG | \ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk @for plist in ${WSTAGEDIR}/*.plist; do \ plist=$${plist##*/} ; \ @@ -2524,7 +2524,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ ${_cddl_lib_libuutil} \ ${_cddl_lib_libavl} \ - ${_cddl_lib_libzfs_core} \ + ${_cddl_lib_libzfs_core} ${_cddl_lib_libzfs} \ ${_cddl_lib_libctf} \ lib/libufs \ lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \ @@ -2597,7 +2597,15 @@ _cddl_lib_libavl= cddl/lib/libavl _cddl_lib_libuutil= cddl/lib/libuutil .if ${MK_ZFS} != "no" _cddl_lib_libzfs_core= cddl/lib/libzfs_core +_cddl_lib_libzfs= cddl/lib/libzfs + cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L + +cddl/lib/libzfs__L: cddl/lib/libzfs_core__L lib/msun__L lib/libutil__L +cddl/lib/libzfs__L: lib/libthr__L lib/libmd__L lib/libz__L cddl/lib/libumem__L +cddl/lib/libzfs__L: cddl/lib/libuutil__L cddl/lib/libavl__L lib/libgeom__L + +lib/libbe__L: cddl/lib/libzfs__L .endif _cddl_lib_libctf= cddl/lib/libctf _cddl_lib= cddl/lib diff --git a/UPDATING b/UPDATING index e83250bcaace..327bbecd7aa2 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20180815: + ls(1) now respects the COLORTERM environment variable used in other + systems and software to indicate that a colored terminal is both + supported and desired. If ls(1) is suddenly emitting colors, they may + be disabled again by either removing the unwanted COLORTERM from your + environment, or using `ls --color=never`. The ls(1) specific CLICOLOR + may not be observed in a future release. + 20180808: The default pager for most commands has been changed to "less". To restore the old behavior, set PAGER="more" and MANPAGER="more -s" in diff --git a/bin/csh/Makefile b/bin/csh/Makefile index 128ba5b19ab0..3aaa50d4a648 100644 --- a/bin/csh/Makefile +++ b/bin/csh/Makefile @@ -8,6 +8,8 @@ .include +CONFGROUPS= ETC +ETC= csh.cshrc csh.login csh.logout PACKAGE=runtime TCSHDIR= ${SRCTOP}/contrib/tcsh .PATH: ${TCSHDIR} diff --git a/etc/csh.cshrc b/bin/csh/csh.cshrc similarity index 100% rename from etc/csh.cshrc rename to bin/csh/csh.cshrc diff --git a/etc/csh.login b/bin/csh/csh.login similarity index 100% rename from etc/csh.login rename to bin/csh/csh.login diff --git a/etc/csh.logout b/bin/csh/csh.logout similarity index 100% rename from etc/csh.logout rename to bin/csh/csh.logout diff --git a/etc/root/dot.login b/bin/csh/dot.login similarity index 100% rename from etc/root/dot.login rename to bin/csh/dot.login diff --git a/bin/dd/Makefile b/bin/dd/Makefile index 2a9ff1f788f7..9088112536dd 100644 --- a/bin/dd/Makefile +++ b/bin/dd/Makefile @@ -6,6 +6,7 @@ PACKAGE=runtime PROG= dd SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c +LIBADD= util # # Test the character conversion functions. We have to be explicit about diff --git a/bin/dd/dd.c b/bin/dd/dd.c index 358d2c06190c..a37a3072bcff 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -95,6 +95,8 @@ volatile sig_atomic_t need_progress; int main(int argc __unused, char *argv[]) { + struct itimerval itv = { { 1, 0 }, { 1, 0 } }; /* SIGALARM every second, if needed */ + (void)setlocale(LC_CTYPE, ""); jcl(argv); setup(); @@ -104,7 +106,10 @@ main(int argc __unused, char *argv[]) err(1, "unable to enter capability mode"); (void)signal(SIGINFO, siginfo_handler); - (void)signal(SIGALRM, sigalrm_handler); + if (ddflags & C_PROGRESS) { + (void)signal(SIGALRM, sigalarm_handler); + setitimer(ITIMER_REAL, &itv, NULL); + } (void)signal(SIGINT, terminate); atexit(summary); @@ -284,14 +289,6 @@ setup(void) ctab = casetab; } - if ((ddflags & C_PROGRESS)) { - struct itimerval timer = { - .it_interval = { .tv_sec = 1, .tv_usec = 0 }, - .it_value = { .tv_sec = 1, .tv_usec = 0 }, - }; - setitimer(ITIMER_REAL, &timer, NULL); - } - if (clock_gettime(CLOCK_MONOTONIC, &st.start)) err(1, "clock_gettime"); } @@ -469,12 +466,10 @@ dd_in(void) in.dbp += in.dbrcnt; (*cfunc)(); - if (need_summary) { + if (need_summary) summary(); - } - if (need_progress) { + if (need_progress) progress(); - } } } diff --git a/bin/dd/extern.h b/bin/dd/extern.h index ca80a87f1621..45e3fb1b2808 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -45,10 +45,10 @@ void jcl(char **); void pos_in(void); void pos_out(void); double secs_elapsed(void); -void summary(void); void progress(void); +void summary(void); +void sigalarm_handler(int); void siginfo_handler(int); -void sigalrm_handler(int); void terminate(int); void unblock(void); void unblock_close(void); diff --git a/bin/dd/misc.c b/bin/dd/misc.c index e778f275fcef..dfe83fd1ef9a 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -56,8 +57,6 @@ __FBSDID("$FreeBSD$"); #include "dd.h" #include "extern.h" -static int need_newline; - double secs_elapsed(void) { @@ -85,7 +84,7 @@ summary(void) if (ddflags & C_NOINFO) return; - if (need_newline && !need_summary) + if (ddflags & C_PROGRESS) fprintf(stderr, "\n"); secs = secs_elapsed(); @@ -110,22 +109,25 @@ summary(void) void progress(void) { + static int outlen; + char si[4 + 1 + 2 + 1]; /* 123 NUL */ + char iec[4 + 1 + 2 + 1]; /* 123 NUL */ + char persec[4 + 1 + 2 + 1]; /* 123 NUL */ + char *buf; double secs; - static int lastlen; - int len; secs = secs_elapsed(); - len = fprintf(stderr, - "\r%ju bytes transferred in %.0f secs (%.0f bytes/sec)", - st.bytes, secs, st.bytes / secs); - - if (len > 0) { - if (len < lastlen) - (void)fprintf(stderr, "%*s", len - lastlen, ""); - lastlen = len; - } - - need_newline = 1; + humanize_number(si, sizeof(si), (int64_t)st.bytes, "B", HN_AUTOSCALE, + HN_DECIMAL | HN_DIVISOR_1000); + humanize_number(iec, sizeof(iec), (int64_t)st.bytes, "B", HN_AUTOSCALE, + HN_DECIMAL | HN_IEC_PREFIXES); + humanize_number(persec, sizeof(iec), (int64_t)(st.bytes / secs), "B", + HN_AUTOSCALE, HN_DECIMAL | HN_DIVISOR_1000); + asprintf(&buf, " %'ju bytes (%s, %s) transferred %.3fs, %s/s", + (uintmax_t)st.bytes, si, iec, secs, persec); + outlen = fprintf(stderr, "%-*s\r", outlen, buf); + fflush(stderr); + free(buf); need_progress = 0; } @@ -139,7 +141,7 @@ siginfo_handler(int signo __unused) /* ARGSUSED */ void -sigalrm_handler(int signo __unused) +sigalarm_handler(int signo __unused) { need_progress = 1; diff --git a/bin/dd/position.c b/bin/dd/position.c index 0bd8edcda1e9..21a100cd3b24 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -125,6 +125,8 @@ pos_in(void) --cnt; if (need_summary) summary(); + if (need_progress) + progress(); continue; } diff --git a/bin/ls/extern.h b/bin/ls/extern.h index 60f7e97c250a..8dab2bcc9d8c 100644 --- a/bin/ls/extern.h +++ b/bin/ls/extern.h @@ -32,6 +32,8 @@ * $FreeBSD$ */ +#include + int acccmp(const FTSENT *, const FTSENT *); int revacccmp(const FTSENT *, const FTSENT *); int birthcmp(const FTSENT *, const FTSENT *); @@ -64,5 +66,12 @@ extern char *ansi_bgcol; extern char *ansi_coloff; extern char *attrs_off; extern char *enter_bold; + +extern int colorflag; +extern bool explicitansi; + +#define COLORFLAG_NEVER 0 +#define COLORFLAG_AUTO 1 +#define COLORFLAG_ALWAYS 2 #endif extern int termwidth; diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 8495367de4e7..6f4303a349a1 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -32,7 +32,7 @@ .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" $FreeBSD$ .\" -.Dd August 8, 2018 +.Dd August 16, 2018 .Dt LS 1 .Os .Sh NAME @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1, +.Op Fl -color Ns = Ns Ar when .Op Fl D Ar format .Op Ar .Sh DESCRIPTION @@ -210,6 +211,47 @@ This option is not defined in .St -p1003.1-2001 . .It Fl c Use time when file status was last changed for sorting or printing. +.It Fl -color Ns = Ns Ar when +Output colored escape sequences based on +.Ar when , +which may be set to either +.Cm always , +.Cm auto +(default), or +.Cm never . +.Pp +.Cm always +will make +.Nm +always output color. +If +.Ev TERM +is unset or set to an invalid terminal, then +.Nm +will fall back to explicit +.Tn ANSI +escape sequences without the help of +.Xr termcap 5 . +.Cm always +is the default if +.Fl -color +is specified without an argument. +.Pp +.Cm auto +will make +.Nm +output escape sequences based on +.Xr termcap 5 , +but only if +.Dv stdout +is a tty and either the +.Fl G +flag is specified or the +.Ev COLORTERM +environment variable is set and not empty. +.Pp +.Cm never +will disable color regardless of environment variables. .It Fl d Directories are listed as plain files (not searched recursively). .It Fl f @@ -620,7 +662,10 @@ Colorization is silently disabled if the output is not directed to a terminal unless the .Ev CLICOLOR_FORCE -variable is defined. +variable is defined or +.Fl -color +is set to +.Dq always . .It Ev CLICOLOR_FORCE Color sequences are normally disabled if the output is not directed to a terminal. diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 7c7174f25f4f..9a8e855176eb 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -55,11 +55,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -98,6 +100,16 @@ static void display(const FTSENT *, FTSENT *, int); static int mastercmp(const FTSENT * const *, const FTSENT * const *); static void traverse(int, char **, int); +#define COLOR_OPT (CHAR_MAX + 1) + +static const struct option long_opts[] = +{ +#ifdef COLORLS + {"color", optional_argument, NULL, COLOR_OPT}, +#endif + {NULL, no_argument, NULL, 0} +}; + static void (*printfcn)(const DISPLAY *); static int (*sortfcn)(const FTSENT *, const FTSENT *); @@ -139,10 +151,10 @@ static int f_stream; /* stream the output, separate with commas */ static int f_timesort; /* sort by time vice name */ int f_type; /* add type character for non-regular files */ static int f_whiteout; /* show whiteout entries */ - #ifdef COLORLS + int colorflag = COLORFLAG_AUTO; /* passed in colorflag */ int f_color; /* add type in color for non-regular files */ - + bool explicitansi; /* Explicit ANSI sequences, no termcap(5) */ char *ansi_bgcol; /* ANSI sequence to set background colour */ char *ansi_fgcol; /* ANSI sequence to set foreground colour */ char *ansi_coloff; /* ANSI sequence to reset colours */ @@ -152,6 +164,42 @@ char *enter_bold; /* ANSI sequence to set color to bold mode */ static int rval; +static bool +do_color_from_env(void) +{ + const char *p; + bool doit; + + doit = false; + p = getenv("CLICOLOR"); + if (p == NULL) { + /* + * COLORTERM is the more standard name for this variable. We'll + * honor it as long as it's both set and not empty. + */ + p = getenv("COLORTERM"); + if (p != NULL && *p != '\0') + doit = true; + } else + doit = true; + + return (doit && + (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE"))); +} + +static bool +do_color(void) +{ + +#ifdef COLORLS + if (colorflag == COLORFLAG_NEVER) + return (false); + else if (colorflag == COLORFLAG_ALWAYS) + return (true); +#endif + return (do_color_from_env()); +} + int main(int argc, char *argv[]) { @@ -163,7 +211,7 @@ main(int argc, char *argv[]) #ifdef COLORLS char termcapbuf[1024]; /* termcap definition buffer */ char tcapbuf[512]; /* capability buffer */ - char *bp = tcapbuf; + char *bp = tcapbuf, *term; #endif (void)setlocale(LC_ALL, ""); @@ -191,8 +239,9 @@ main(int argc, char *argv[]) fts_options = FTS_PHYSICAL; if (getenv("LS_SAMESORT")) f_samesort = 1; - while ((ch = getopt(argc, argv, - "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) { + while ((ch = getopt_long(argc, argv, + "+1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,", long_opts, + NULL)) != -1) { switch (ch) { /* * The -1, -C, -x and -l options all override each other so @@ -355,6 +404,19 @@ main(int argc, char *argv[]) case 'y': f_samesort = 1; break; +#ifdef COLORLS + case COLOR_OPT: + if (optarg == NULL || strcmp(optarg, "always") == 0) + colorflag = COLORFLAG_ALWAYS; + else if (strcmp(optarg, "auto") == 0) + colorflag = COLORFLAG_AUTO; + else if (strcmp(optarg, "never") == 0) + colorflag = COLORFLAG_NEVER; + else + errx(2, "unsupported --color value '%s' (must be always, auto, or never)", + optarg); + break; +#endif default: case '?': usage(); @@ -367,11 +429,14 @@ main(int argc, char *argv[]) if (!f_listdot && getuid() == (uid_t)0 && !f_noautodot) f_listdot = 1; - /* Enabling of colours is conditional on the environment. */ - if ((getenv("CLICOLOR") || getenv("COLORTERM")) && - (isatty(STDOUT_FILENO) || getenv("CLICOLOR_FORCE"))) + /* + * Enabling of colours is conditional on the environment in conjunction + * with the --color and -G arguments, if supplied. + */ + if (do_color()) { #ifdef COLORLS - if (tgetent(termcapbuf, getenv("TERM")) == 1) { + if ((term = getenv("TERM")) != NULL && + tgetent(termcapbuf, term) == 1) { ansi_fgcol = tgetstr("AF", &bp); ansi_bgcol = tgetstr("AB", &bp); attrs_off = tgetstr("me", &bp); @@ -385,10 +450,19 @@ main(int argc, char *argv[]) ansi_coloff = tgetstr("oc", &bp); if (ansi_fgcol && ansi_bgcol && ansi_coloff) f_color = 1; + } else if (colorflag == COLORFLAG_ALWAYS) { + /* + * If we're *always* doing color but we don't have + * a functional TERM supplied, we'll fallback to + * outputting raw ANSI sequences. + */ + f_color = 1; + explicitansi = true; } #else warnx("color support not compiled in"); #endif /*COLORLS*/ + } #ifdef COLORLS if (f_color) { diff --git a/bin/ls/print.c b/bin/ls/print.c index 09e544b58a1a..9a537418f7b9 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -73,6 +73,8 @@ static void printtime(time_t); static int printtype(u_int); static void printsize(size_t, off_t); #ifdef COLORLS +static void endcolor_termcap(int); +static void endcolor_ansi(void); static void endcolor(int); static int colortype(mode_t); #endif @@ -540,7 +542,7 @@ writech(int c) } static void -printcolor(Colors c) +printcolor_termcap(Colors c) { char *ansiseq; @@ -560,12 +562,55 @@ printcolor(Colors c) } static void -endcolor(int sig) +printcolor_ansi(Colors c) { + + printf("\033["); + + if (colors[c].bold) + printf("1"); + if (colors[c].num[0] != -1) + printf(";3%d", colors[c].num[0]); + if (colors[c].num[1] != -1) + printf(";4%d", colors[c].num[1]); + printf("m"); +} + +static void +printcolor(Colors c) +{ + + if (explicitansi) + printcolor_ansi(c); + else + printcolor_termcap(c); +} + +static void +endcolor_termcap(int sig) +{ + tputs(ansi_coloff, 1, sig ? writech : putch); tputs(attrs_off, 1, sig ? writech : putch); } +static void +endcolor_ansi(void) +{ + + printf("\33[m"); +} + +static void +endcolor(int sig) +{ + + if (explicitansi) + endcolor_ansi(); + else + endcolor_termcap(sig); +} + static int colortype(mode_t mode) { diff --git a/bin/ls/util.c b/bin/ls/util.c index 7d899168b38a..44012de58bba 100644 --- a/bin/ls/util.c +++ b/bin/ls/util.c @@ -227,7 +227,7 @@ usage(void) { (void)fprintf(stderr, #ifdef COLORLS - "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]" + "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [--color=when] [-D format]" #else "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]" #endif diff --git a/bin/sh/Makefile b/bin/sh/Makefile index 5b2a66129c7a..652e9ddc3dbf 100644 --- a/bin/sh/Makefile +++ b/bin/sh/Makefile @@ -3,6 +3,7 @@ .include +CONFS= profile PACKAGE=runtime PROG= sh INSTALLFLAGS= -S diff --git a/etc/profile b/bin/sh/profile similarity index 100% rename from etc/profile rename to bin/sh/profile diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 index 907baee660b6..a566e5eafaaa 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 +++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.1 @@ -1,4 +1,3 @@ -'\" te .\" CDDL HEADER START .\" .\" The contents of this file are subject to the terms of the @@ -21,7 +20,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 18, 2015 +.Dd August 16, 2018 .Dt DTRACE 1 .Os .Sh NAME @@ -523,6 +522,116 @@ Enable or modify a DTrace runtime option or D compiler option. Boolean options are enabled by specifying their name. Options with values are set by separating the option name and value with an equals sign (=). +.Pp +A +.Ar size +argument may be suffixed with one of +.Cm K , +.Cm M , +.Cm G +or +.Cm T +(either upper or lower case) to indicate a multiple of +Kilobytes, Megabytes, Gigabytes or Terabytes +respectively. +.Pp +A +.Ar time +argument may be suffixed with one of +.Cm ns , +.Cm nsec , +.Cm us , +.Cm usec , +.Cm ms , +.Cm msec , +.Cm s , +.Cm sec , +.Cm m , +.Cm min , +.Cm h , +.Cm hour , +.Cm d , +.Cm day , +.Cm hz . +If no suffix is specified +.Cm hz +will be used as the unit. +.Bl -tag -width indent +.It Sy aggrate Ns = Ns Ar time +Rate of aggregation reading. +.It Sy aggsize Ns = Ns Ar size +Size of the aggregation buffer. +.It Sy bufpolicy Ns = Ns Cm fill Ns | Ns Cm switch Ns | Ns Cm ring +Specifies the buffer policy for the principal buffer. +.It Sy bufresize Ns = Ns Cm auto Ns | Ns Cm manual +Buffer resizing policy. +.It Sy bufsize Ns = Ns Ar size +Size of the per-CPU principal buffer. +Same as the +.Fl b +flag. +.It Sy cleanrate Ns = Ns Ar time +Cleaning rate. +Must be specified in number-per-second with the +.Dq Li hz +suffix. +.It Sy cpu Ns = Ns Ar scalar +Specifies the CPU on which to enable tracing. +.It Sy defaultargs +Allow references to unspecified macro arguments. +.It Sy destructive +Allow destructive actions. +Same as the +.Fl w +flag. +.It Sy dynvarsize Ns = Ns Ar size +Size of the dynamic variable space. +.It Sy flowindent +Turn on flow indentation. +Same as the +.Fl F +flag. +.It Sy grabanon +Claim anonymous state. +Same as the +.Fl a +flag. +.It Sy jstackframes Ns = Ns Ar scalar +Number of default stack frames for +.Fn jstack . +.It Sy jstackstrsize Ns = Ns Ar scalar +Default string space size for +.Fn jstack . +.It Sy nspec Ns = Ns Ar scalar +Number of speculations. +.It Sy quiet +Set quiet mode. +Same as the +.Fl q +flag. +.It Sy specsize Ns = Ns Ar size +Size of the speculation buffer. +.It Sy strsize Ns = Ns Ar size +Maximum size of strings. +.It Sy stackframes Ns = Ns Ar scalar +Maximum number of kernelspace stack frames to unwind when executing the +.Fn stack +action. +.It Sy stackindent Ns = Ns Ar scalar +Number of whitespace characters to use when indenting +.Fn stack +and +.Fn ustack +output. +.It Sy statusrate Ns = Ns Ar time +Rate of status checking. +.It Sy switchrate Ns = Ns Ar time +Rate of buffer switching. +.It Sy ustackframes Ns = Ns Ar scalar +Maximum number of userspace stack frames to unwind when executing the +.Fn ustack +action. +.El .It Fl X Cm a | c | s | t Specify the degree of conformance to the ISO C standard that should be selected when invoking diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c index 3c72caf1e466..3cdd90cea1f9 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c @@ -2096,7 +2096,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) dnode_t *dn; void *bonus = NULL; size_t bsize = 0; - char iblk[32], dblk[32], lsize[32], asize[32], fill[32]; + char iblk[32], dblk[32], lsize[32], asize[32], fill[32], dnsize[32]; char bonus_size[32]; char aux[50]; int error; @@ -2109,9 +2109,9 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) CTASSERT(sizeof (bonus_size) >= NN_NUMBUF_SZ); if (*print_header) { - (void) printf("\n%10s %3s %5s %5s %5s %5s %6s %s\n", - "Object", "lvl", "iblk", "dblk", "dsize", "lsize", - "%full", "type"); + (void) printf("\n%10s %3s %5s %5s %5s %6s %5s %6s %s\n", + "Object", "lvl", "iblk", "dblk", "dsize", "dnsize", + "lsize", "%full", "type"); *print_header = 0; } @@ -2133,6 +2133,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) zdb_nicenum(doi.doi_max_offset, lsize, sizeof (lsize)); zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize, sizeof (asize)); zdb_nicenum(doi.doi_bonus_size, bonus_size, sizeof (bonus_size)); + zdb_nicenum(doi.doi_dnodesize, dnsize, sizeof (dnsize)); (void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count * doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) / doi.doi_max_offset); @@ -2149,13 +2150,13 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) ZDB_COMPRESS_NAME(doi.doi_compress)); } - (void) printf("%10lld %3u %5s %5s %5s %5s %6s %s%s\n", + (void) printf("%10lld %3u %5s %5s %5s %6s %5s %6s %s%s\n", (u_longlong_t)object, doi.doi_indirection, iblk, dblk, - asize, lsize, fill, ZDB_OT_NAME(doi.doi_type), aux); + asize, dnsize, lsize, fill, ZDB_OT_NAME(doi.doi_type), aux); if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) { - (void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n", - "", "", "", "", "", bonus_size, "bonus", + (void) printf("%10s %3s %5s %5s %5s %5s %5s %6s %s\n", + "", "", "", "", "", "", bonus_size, "bonus", ZDB_OT_NAME(doi.doi_bonus_type)); } diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c index a2ebe5857e4d..75b0cd91d262 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb_il.c @@ -84,8 +84,10 @@ zil_prt_rec_create(zilog_t *zilog, int txtype, void *arg) } (void) printf("%s%s", tab_prefix, ctime(&crtime)); - (void) printf("%sdoid %llu, foid %llu, mode %llo\n", tab_prefix, - (u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_foid, + (void) printf("%sdoid %llu, foid %llu, slots %llu, mode %llo\n", tab_prefix, + (u_longlong_t)lr->lr_doid, + (u_longlong_t)LR_FOID_GET_OBJ(lr->lr_foid), + (u_longlong_t)LR_FOID_GET_SLOTS(lr->lr_foid), (longlong_t)lr->lr_mode); (void) printf("%suid %llu, gid %llu, gen %llu, rdev 0x%llx\n", tab_prefix, diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 index f6e9bbb57972..e152ad9ed4b4 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 6, 2017 +.Dd August 11, 2018 .Dt ZFS 8 .Os .Sh NAME @@ -462,8 +462,11 @@ responsible for mounting and unmounting the file system. dataset can be attached to a jail by using the .Qq Nm Cm jail subcommand. You cannot attach a dataset to one jail and the children of the -same dataset to another jails. To allow management of the dataset from within -a jail, the +same dataset to another jail. You can also not attach the root file system +of the jail or any dataset which needs to be mounted before the zfs rc script +is run inside the jail, as it would be attached unmounted until it is +mounted from the rc script inside the jail. To allow management of the +dataset from within a jail, the .Sy jailed property has to be set and the jail needs access to the .Pa /dev/zfs diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c index af8bd1867dae..67fa166df19a 100644 --- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c +++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c @@ -226,6 +226,7 @@ typedef struct ztest_block_tag { uint64_t bt_magic; uint64_t bt_objset; uint64_t bt_object; + uint64_t bt_dnodesize; uint64_t bt_offset; uint64_t bt_gen; uint64_t bt_txg; @@ -274,6 +275,7 @@ typedef struct ztest_od { dmu_object_type_t od_crtype; uint64_t od_blocksize; uint64_t od_crblocksize; + uint64_t od_crdnodesize; uint64_t od_gen; uint64_t od_crgen; char od_name[ZFS_MAX_DATASET_NAME_LEN]; @@ -350,6 +352,7 @@ ztest_func_t ztest_device_removal; ztest_func_t ztest_remap_blocks; ztest_func_t ztest_spa_checkpoint_create_discard; ztest_func_t ztest_initialize; +ztest_func_t ztest_verify_dnode_bt; uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */ uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */ @@ -394,7 +397,8 @@ ztest_info_t ztest_info[] = { { ztest_device_removal, 1, &zopt_sometimes }, { ztest_remap_blocks, 1, &zopt_sometimes }, { ztest_spa_checkpoint_create_discard, 1, &zopt_rarely }, - { ztest_initialize, 1, &zopt_sometimes } + { ztest_initialize, 1, &zopt_sometimes }, + { ztest_verify_dnode_bt, 1, &zopt_sometimes } }; #define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t)) @@ -440,8 +444,8 @@ static spa_t *ztest_spa = NULL; static ztest_ds_t *ztest_ds; static kmutex_t ztest_vdev_lock; -static kmutex_t ztest_checkpoint_lock; static boolean_t ztest_device_removal_active = B_FALSE; +static kmutex_t ztest_checkpoint_lock; /* * The ztest_name_lock protects the pool and dataset namespace used by @@ -1010,6 +1014,36 @@ ztest_random_blocksize(void) return (1 << (SPA_MINBLOCKSHIFT + block_shift)); } +static int +ztest_random_dnodesize(void) +{ + int slots; + int max_slots = spa_maxdnodesize(ztest_spa) >> DNODE_SHIFT; + + if (max_slots == DNODE_MIN_SLOTS) + return (DNODE_MIN_SIZE); + + /* + * Weight the random distribution more heavily toward smaller + * dnode sizes since that is more likely to reflect real-world + * usage. + */ + ASSERT3U(max_slots, >, 4); + switch (ztest_random(10)) { + case 0: + slots = 5 + ztest_random(max_slots - 4); + break; + case 1 ... 4: + slots = 2 + ztest_random(3); + break; + default: + slots = 1; + break; + } + + return (slots << DNODE_SHIFT); +} + static int ztest_random_ibshift(void) { @@ -1287,11 +1321,13 @@ ztest_pattern_match(void *buf, uint64_t size, uint64_t value) static void ztest_bt_generate(ztest_block_tag_t *bt, objset_t *os, uint64_t object, - uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg) + uint64_t dnodesize, uint64_t offset, uint64_t gen, uint64_t txg, + uint64_t crtxg) { bt->bt_magic = BT_MAGIC; bt->bt_objset = dmu_objset_id(os); bt->bt_object = object; + bt->bt_dnodesize = dnodesize; bt->bt_offset = offset; bt->bt_gen = gen; bt->bt_txg = txg; @@ -1300,11 +1336,13 @@ ztest_bt_generate(ztest_block_tag_t *bt, objset_t *os, uint64_t object, static void ztest_bt_verify(ztest_block_tag_t *bt, objset_t *os, uint64_t object, - uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg) + uint64_t dnodesize, uint64_t offset, uint64_t gen, uint64_t txg, + uint64_t crtxg) { ASSERT3U(bt->bt_magic, ==, BT_MAGIC); ASSERT3U(bt->bt_objset, ==, dmu_objset_id(os)); ASSERT3U(bt->bt_object, ==, object); + ASSERT3U(bt->bt_dnodesize, ==, dnodesize); ASSERT3U(bt->bt_offset, ==, offset); ASSERT3U(bt->bt_gen, <=, gen); ASSERT3U(bt->bt_txg, <=, txg); @@ -1325,6 +1363,52 @@ ztest_bt_bonus(dmu_buf_t *db) return (bt); } +/* + * Generate a token to fill up unused bonus buffer space. Try to make + * it unique to the object, generation, and offset to verify that data + * is not getting overwritten by data from other dnodes. + */ +#define ZTEST_BONUS_FILL_TOKEN(obj, ds, gen, offset) \ + (((ds) << 48) | ((gen) << 32) | ((obj) << 8) | (offset)) + +/* + * Fill up the unused bonus buffer region before the block tag with a + * verifiable pattern. Filling the whole bonus area with non-zero data + * helps ensure that all dnode traversal code properly skips the + * interior regions of large dnodes. + */ +void +ztest_fill_unused_bonus(dmu_buf_t *db, void *end, uint64_t obj, + objset_t *os, uint64_t gen) +{ + uint64_t *bonusp; + + ASSERT(IS_P2ALIGNED((char *)end - (char *)db->db_data, 8)); + + for (bonusp = db->db_data; bonusp < (uint64_t *)end; bonusp++) { + uint64_t token = ZTEST_BONUS_FILL_TOKEN(obj, dmu_objset_id(os), + gen, bonusp - (uint64_t *)db->db_data); + *bonusp = token; + } +} + +/* + * Verify that the unused area of a bonus buffer is filled with the + * expected tokens. + */ +void +ztest_verify_unused_bonus(dmu_buf_t *db, void *end, uint64_t obj, + objset_t *os, uint64_t gen) +{ + uint64_t *bonusp; + + for (bonusp = db->db_data; bonusp < (uint64_t *)end; bonusp++) { + uint64_t token = ZTEST_BONUS_FILL_TOKEN(obj, dmu_objset_id(os), + gen, bonusp - (uint64_t *)db->db_data); + VERIFY3U(*bonusp, ==, token); + } +} + /* * ZIL logging ops */ @@ -1333,7 +1417,7 @@ ztest_bt_bonus(dmu_buf_t *db) #define lrz_blocksize lr_uid #define lrz_ibshift lr_gid #define lrz_bonustype lr_rdev -#define lrz_bonuslen lr_crtime[1] +#define lrz_dnodesize lr_crtime[1] static void ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr) @@ -1449,6 +1533,7 @@ ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap) dmu_tx_t *tx; uint64_t txg; int error = 0; + int bonuslen; if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); @@ -1471,26 +1556,27 @@ ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap) return (ENOSPC); ASSERT(dmu_objset_zil(os)->zl_replay == !!lr->lr_foid); + bonuslen = DN_BONUS_SIZE(lr->lrz_dnodesize); if (lr->lrz_type == DMU_OT_ZAP_OTHER) { if (lr->lr_foid == 0) { - lr->lr_foid = zap_create(os, + lr->lr_foid = zap_create_dnsize(os, lr->lrz_type, lr->lrz_bonustype, - lr->lrz_bonuslen, tx); + bonuslen, lr->lrz_dnodesize, tx); } else { - error = zap_create_claim(os, lr->lr_foid, + error = zap_create_claim_dnsize(os, lr->lr_foid, lr->lrz_type, lr->lrz_bonustype, - lr->lrz_bonuslen, tx); + bonuslen, lr->lrz_dnodesize, tx); } } else { if (lr->lr_foid == 0) { - lr->lr_foid = dmu_object_alloc(os, + lr->lr_foid = dmu_object_alloc_dnsize(os, lr->lrz_type, 0, lr->lrz_bonustype, - lr->lrz_bonuslen, tx); + bonuslen, lr->lrz_dnodesize, tx); } else { - error = dmu_object_claim(os, lr->lr_foid, + error = dmu_object_claim_dnsize(os, lr->lr_foid, lr->lrz_type, 0, lr->lrz_bonustype, - lr->lrz_bonuslen, tx); + bonuslen, lr->lrz_dnodesize, tx); } } @@ -1510,7 +1596,9 @@ ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap) VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db)); bbt = ztest_bt_bonus(db); dmu_buf_will_dirty(db, tx); - ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_gen, txg, txg); + ztest_bt_generate(bbt, os, lr->lr_foid, lr->lrz_dnodesize, -1ULL, + lr->lr_gen, txg, txg); + ztest_fill_unused_bonus(db, bbt, lr->lr_foid, os, lr->lr_gen); dmu_buf_rele(db, FTAG); VERIFY3U(0, ==, zap_add(os, lr->lr_doid, name, sizeof (uint64_t), 1, @@ -1660,7 +1748,7 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap) VERIFY(dmu_read(os, lr->lr_foid, offset, sizeof (rbt), &rbt, prefetch) == 0); if (rbt.bt_magic == BT_MAGIC) { - ztest_bt_verify(&rbt, os, lr->lr_foid, + ztest_bt_verify(&rbt, os, lr->lr_foid, 0, offset, gen, txg, crtxg); } } @@ -1672,7 +1760,7 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap) * as it was when the write was generated. */ if (zd->zd_zilog->zl_replay) { - ztest_bt_verify(bt, os, lr->lr_foid, offset, + ztest_bt_verify(bt, os, lr->lr_foid, 0, offset, MAX(gen, bt->bt_gen), MAX(txg, lrtxg), bt->bt_crtxg); } @@ -1681,7 +1769,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap) * Set the bt's gen/txg to the bonus buffer's gen/txg * so that all of the usual ASSERTs will work. */ - ztest_bt_generate(bt, os, lr->lr_foid, offset, gen, txg, crtxg); + ztest_bt_generate(bt, os, lr->lr_foid, 0, offset, gen, txg, + crtxg); } if (abuf == NULL) { @@ -1753,7 +1842,7 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) dmu_tx_t *tx; dmu_buf_t *db; ztest_block_tag_t *bbt; - uint64_t txg, lrtxg, crtxg; + uint64_t txg, lrtxg, crtxg, dnodesize; if (byteswap) byteswap_uint64_array(lr, sizeof (*lr)); @@ -1776,6 +1865,7 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) ASSERT3U(bbt->bt_magic, ==, BT_MAGIC); crtxg = bbt->bt_crtxg; lrtxg = lr->lr_common.lrc_txg; + dnodesize = bbt->bt_dnodesize; if (zd->zd_zilog->zl_replay) { ASSERT(lr->lr_size != 0); @@ -1794,7 +1884,7 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) /* * Verify that the current bonus buffer is not newer than our txg. */ - ztest_bt_verify(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode, + ztest_bt_verify(bbt, os, lr->lr_foid, dnodesize, -1ULL, lr->lr_mode, MAX(txg, lrtxg), crtxg); dmu_buf_will_dirty(db, tx); @@ -1804,8 +1894,9 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) VERIFY0(dmu_set_bonus(db, lr->lr_size, tx)); bbt = ztest_bt_bonus(db); - ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode, txg, crtxg); - + ztest_bt_generate(bbt, os, lr->lr_foid, dnodesize, -1ULL, lr->lr_mode, + txg, crtxg); + ztest_fill_unused_bonus(db, bbt, lr->lr_foid, os, bbt->bt_gen); dmu_buf_rele(db, FTAG); (void) ztest_log_setattr(zd, tx, lr); @@ -2037,7 +2128,7 @@ ztest_create(ztest_ds_t *zd, ztest_od_t *od, int count) lr->lrz_blocksize = od->od_crblocksize; lr->lrz_ibshift = ztest_random_ibshift(); lr->lrz_bonustype = DMU_OT_UINT64_OTHER; - lr->lrz_bonuslen = dmu_bonus_max(); + lr->lrz_dnodesize = od->od_crdnodesize; lr->lr_gen = od->od_crgen; lr->lr_crtime[0] = time(NULL); @@ -2216,7 +2307,8 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset) switch (io_type) { case ZTEST_IO_WRITE_TAG: - ztest_bt_generate(&wbt, zd->zd_os, object, offset, 0, 0, 0); + ztest_bt_generate(&wbt, zd->zd_os, object, doi.doi_dnodesize, + offset, 0, 0, 0); (void) ztest_write(zd, object, offset, sizeof (wbt), &wbt); break; @@ -2277,13 +2369,15 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset) */ static void ztest_od_init(ztest_od_t *od, uint64_t id, char *tag, uint64_t index, - dmu_object_type_t type, uint64_t blocksize, uint64_t gen) + dmu_object_type_t type, uint64_t blocksize, uint64_t dnodesize, + uint64_t gen) { od->od_dir = ZTEST_DIROBJ; od->od_object = 0; od->od_crtype = type; od->od_crblocksize = blocksize ? blocksize : ztest_random_blocksize(); + od->od_crdnodesize = dnodesize ? dnodesize : ztest_random_dnodesize(); od->od_crgen = gen; od->od_type = DMU_OT_NONE; @@ -3726,7 +3820,7 @@ ztest_dmu_object_alloc_free(ztest_ds_t *zd, uint64_t id) int batchsize = sizeof (od) / sizeof (od[0]); for (int b = 0; b < batchsize; b++) - ztest_od_init(&od[b], id, FTAG, b, DMU_OT_UINT64_OTHER, 0, 0); + ztest_od_init(&od[b], id, FTAG, b, DMU_OT_UINT64_OTHER, 0, 0, 0); /* * Destroy the previous batch of objects, create a new batch, @@ -3786,8 +3880,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id) /* * Read the directory info. If it's the first time, set things up. */ - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, chunksize); - ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0, chunksize); + ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, 0, chunksize); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -4056,8 +4150,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id) /* * Read the directory info. If it's the first time, set things up. */ - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0); - ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0, 0); + ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, 0, chunksize); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -4257,7 +4351,7 @@ ztest_dmu_write_parallel(ztest_ds_t *zd, uint64_t id) * to verify that parallel writes to an object -- even to the * same blocks within the object -- doesn't cause any trouble. */ - ztest_od_init(&od[0], ID_PARALLEL, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0); + ztest_od_init(&od[0], ID_PARALLEL, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0, 0); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -4276,7 +4370,7 @@ ztest_dmu_prealloc(ztest_ds_t *zd, uint64_t id) uint64_t blocksize = ztest_random_blocksize(); void *data; - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0, 0); if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0) return; @@ -4322,7 +4416,7 @@ ztest_zap(ztest_ds_t *zd, uint64_t id) int error; char *hc[2] = { "s.acl.h", ".s.open.h.hyLZlg" }; - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0, 0); if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0) return; @@ -4454,7 +4548,7 @@ ztest_fzap(ztest_ds_t *zd, uint64_t id) ztest_od_t od[1]; uint64_t object, txg; - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0, 0); if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0) return; @@ -4500,7 +4594,7 @@ ztest_zap_parallel(ztest_ds_t *zd, uint64_t id) char name[20], string_value[20]; void *data; - ztest_od_init(&od[0], ID_PARALLEL, FTAG, micro, DMU_OT_ZAP_OTHER, 0, 0); + ztest_od_init(&od[0], ID_PARALLEL, FTAG, micro, DMU_OT_ZAP_OTHER, 0, 0, 0); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -4688,7 +4782,7 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id) uint64_t old_txg, txg; int i, error; - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0, 0); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -4802,6 +4896,41 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id) dmu_tx_commit(tx); } +/* + * Visit each object in the dataset. Verify that its properties + * are consistent what was stored in the block tag when it was created, + * and that its unused bonus buffer space has not been overwritten. + */ +void +ztest_verify_dnode_bt(ztest_ds_t *zd, uint64_t id) +{ + objset_t *os = zd->zd_os; + uint64_t obj; + int err = 0; + + for (obj = 0; err == 0; err = dmu_object_next(os, &obj, FALSE, 0)) { + ztest_block_tag_t *bt = NULL; + dmu_object_info_t doi; + dmu_buf_t *db; + + if (dmu_bonus_hold(os, obj, FTAG, &db) != 0) + continue; + + dmu_object_info_from_db(db, &doi); + if (doi.doi_bonus_size >= sizeof (*bt)) + bt = ztest_bt_bonus(db); + + if (bt && bt->bt_magic == BT_MAGIC) { + ztest_bt_verify(bt, os, obj, doi.doi_dnodesize, + bt->bt_offset, bt->bt_gen, bt->bt_txg, + bt->bt_crtxg); + ztest_verify_unused_bonus(db, bt, obj, os, bt->bt_gen); + } + + dmu_buf_rele(db, FTAG); + } +} + /* ARGSUSED */ void ztest_dsl_prop_get_set(ztest_ds_t *zd, uint64_t id) @@ -5286,7 +5415,7 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id) blocksize = ztest_random_blocksize(); blocksize = MIN(blocksize, 2048); /* because we write so many */ - ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0); + ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0, 0); if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0) return; @@ -6212,7 +6341,7 @@ ztest_freeze(void) numloops++ < ztest_opts.zo_maxloops && metaslab_class_get_alloc(spa_normal_class(spa)) < capacity) { ztest_od_t od; - ztest_od_init(&od, 0, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0); + ztest_od_init(&od, 0, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0, 0); VERIFY0(ztest_object_init(zd, &od, sizeof (od), B_FALSE)); ztest_io(zd, od.od_object, ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT); diff --git a/cddl/lib/libnvpair/Makefile b/cddl/lib/libnvpair/Makefile index 3321e274e6cd..892568d579f5 100644 --- a/cddl/lib/libnvpair/Makefile +++ b/cddl/lib/libnvpair/Makefile @@ -5,6 +5,7 @@ LIB= nvpair +INCS= libnvpair.h SRCS= libnvpair.c \ nvpair_alloc_system.c \ nvpair_json.c \ diff --git a/cddl/lib/libzfs_core/Makefile b/cddl/lib/libzfs_core/Makefile index 6728f63104fb..c5a275447e75 100644 --- a/cddl/lib/libzfs_core/Makefile +++ b/cddl/lib/libzfs_core/Makefile @@ -9,6 +9,7 @@ LIB= zfs_core LIBADD= nvpair +INCS= libzfs_core.h SRCS= libzfs_core.c \ libzfs_core_compat.c \ zfs_ioctl_compat.c diff --git a/cddl/usr.bin/ztest/Makefile b/cddl/usr.bin/ztest/Makefile index 4631ae2c6210..63ec0ff9cc66 100644 --- a/cddl/usr.bin/ztest/Makefile +++ b/cddl/usr.bin/ztest/Makefile @@ -23,6 +23,9 @@ CSTD= c99 # Since there are many asserts in this program, it makes no sense to compile # it without debugging. -CFLAGS+= -g -DDEBUG=1 +CFLAGS+= -g -DDEBUG=1 -Wno-format + +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests .include diff --git a/cddl/usr.bin/ztest/tests/Makefile b/cddl/usr.bin/ztest/tests/Makefile new file mode 100644 index 000000000000..edf2a537dbe3 --- /dev/null +++ b/cddl/usr.bin/ztest/tests/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +.include + +ATF_TESTS_SH+= ztest + +.include diff --git a/cddl/usr.bin/ztest/tests/ztest.sh b/cddl/usr.bin/ztest/tests/ztest.sh new file mode 100755 index 000000000000..9945d1a45aa9 --- /dev/null +++ b/cddl/usr.bin/ztest/tests/ztest.sh @@ -0,0 +1,52 @@ +# +# Test Case: ztest +# $FreeBSD$ +# +atf_test_case ztest +ztest_head() +{ + atf_set "descr" "Run ztest" + atf_set "timeout" 900 + atf_set "require.config" "rt_long" +} + +ztest_body() +{ + ARGS="-VVVVV -f ${TMPDIR:-/tmp}" + if atf_config_has ztest_extra_args; then + ARGS="${ARGS} $(atf_config_get ztest_extra_args)" + fi + ztest ${ARGS} + if [ $? != 0 ]; then + echo "failing" + save_ztest_artifacts + atf_fail "Testcase failed" + else + echo "passing" + atf_pass + fi +} + +# +# ATF Test Program Init Function +# +atf_init_test_cases() +{ + atf_add_test_case ztest +} + +save_ztest_artifacts() +{ + # If artifacts_dir is defined, save test artifacts for + # post-mortem analysis + if atf_config_has artifacts_dir; then + TC_ARTIFACTS_DIR=`atf_config_get artifacts_dir`/cddl/usr.bin/ztest/$(atf_get ident) + mkdir -p $TC_ARTIFACTS_DIR + TC_CORE_DIR=/var/crash + if atf_config_has core_dir; then + TC_CORE_DIR=`atf_config_get core_dir` + fi + mv *ztest*.core* $TC_ARTIFACTS_DIR || true + mv ${TC_CORE_DIR}/*ztest*.core* $TC_ARTIFACTS_DIR || true + fi +} diff --git a/contrib/amd/FREEBSD-upgrade b/contrib/amd/FREEBSD-upgrade index e31eb80c8ddf..8e77d0fb4e4a 100644 --- a/contrib/amd/FREEBSD-upgrade +++ b/contrib/amd/FREEBSD-upgrade @@ -78,6 +78,8 @@ Local changes: r1.5 mdoc(7)NG r1.3 describe all of the command line options r1.2 un-mandocafied, un4.4BSD'ed + hlfsd/hlfsd.8 + - Fix a broken SEE ALSO section and some mdoc issues mk-amd-map/mk-amd-map.8 r1.4 removed HISTORY info from the .Os call. r1.2 un-mandocafied, un4.4BSD'ed diff --git a/contrib/amd/hlfsd/hlfsd.8 b/contrib/amd/hlfsd/hlfsd.8 index 1732a446d60c..78db8bf1bcb4 100644 --- a/contrib/amd/hlfsd/hlfsd.8 +++ b/contrib/amd/hlfsd/hlfsd.8 @@ -80,9 +80,7 @@ anywhere. The .Nm utility -operates by mounting itself as an -.Tn NFS -server for the directory containing +operates by mounting itself as an NFS server for the directory containing .Ar linkname , which defaults to .Pa /hlfs/home . @@ -334,8 +332,8 @@ symbolic link returned by points if it is unable to verify the that user's home directory is accessible. .El -.SH "SEE ALSO" -.Xr mail1 , +.Sh "SEE ALSO" +.Xr mail 1 , .Xr getgrent 3 , .Xr getpwent 3 , .Xr mnttab 4 , @@ -343,7 +341,7 @@ user's home directory is accessible. .Xr mtab 5 , .Xr amd 8 , .Xr automount 8 , -.Xr cron8 , +.Xr cron 8 , .Xr mount 8 , .Xr sendmail 8 , .Xr umount 8 diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c index bffbd35793c9..3756e01ffa9e 100644 --- a/contrib/bsnmp/snmp_mibII/mibII.c +++ b/contrib/bsnmp/snmp_mibII/mibII.c @@ -439,11 +439,15 @@ mibif_restart_mibII_poll_timer(void) int mib_fetch_ifmib(struct mibif *ifp) { + static int kmib[2] = { -1, 0 }; /* for sysctl net.ifdescr_maxlen */ + int name[6]; + size_t kmiblen = nitems(kmib); size_t len; void *newmib; struct ifmibdata oldmib = ifp->mib; struct ifreq irr; + unsigned int alias_maxlen = MIBIF_ALIAS_SIZE_MAX; if (fetch_generic_mib(ifp, &oldmib) == -1) return (-1); @@ -515,18 +519,69 @@ mib_fetch_ifmib(struct mibif *ifp) } out: + + /* + * Find sysctl mib for net.ifdescr_maxlen (one time). + * kmib[0] == -1 at first call to mib_fetch_ifmib(). + * Then kmib[0] > 0 if we found sysctl mib for net.ifdescr_maxlen. + * Else, kmib[0] == 0 (unexpected error from a kernel). + */ + if (kmib[0] < 0 && + sysctlnametomib("net.ifdescr_maxlen", kmib, &kmiblen) < 0) { + kmib[0] = 0; + syslog(LOG_WARNING, "sysctlnametomib net.ifdescr_maxlen: %m"); + } + + /* + * Fetch net.ifdescr_maxlen value every time to catch up with changes. + */ + len = sizeof(alias_maxlen); + if (kmib[0] > 0 && sysctl(kmib, 2, &alias_maxlen, &len, NULL, 0) < 0) { + /* unexpected error from the kernel, use default value */ + alias_maxlen = MIBIF_ALIAS_SIZE_MAX; + syslog(LOG_WARNING, "sysctl net.ifdescr_maxlen: %m"); + } + + /* + * Kernel limit might be decreased after interfaces got + * their descriptions assigned. Try to obtain them anyway. + */ + if (alias_maxlen == 0) + alias_maxlen = MIBIF_ALIAS_SIZE_MAX; + + /* + * Allocate maximum memory for a buffer and later reallocate + * to free extra memory. + */ + if ((ifp->alias = malloc(alias_maxlen)) == NULL) { + syslog(LOG_WARNING, "malloc(%d) failed: %m", (int)alias_maxlen); + goto fin; + } + strlcpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name)); - irr.ifr_buffer.buffer = MIBIF_PRIV(ifp)->alias; - irr.ifr_buffer.length = sizeof(MIBIF_PRIV(ifp)->alias); + irr.ifr_buffer.buffer = ifp->alias; + irr.ifr_buffer.length = alias_maxlen; if (ioctl(mib_netsock, SIOCGIFDESCR, &irr) == -1) { - MIBIF_PRIV(ifp)->alias[0] = 0; + free(ifp->alias); + ifp->alias = NULL; if (errno != ENOMSG) syslog(LOG_WARNING, "SIOCGIFDESCR (%s): %m", ifp->name); } else if (irr.ifr_buffer.buffer == NULL) { - MIBIF_PRIV(ifp)->alias[0] = 0; + free(ifp->alias); + ifp->alias = NULL; syslog(LOG_WARNING, "SIOCGIFDESCR (%s): too long (%zu)", ifp->name, irr.ifr_buffer.length); + } else { + ifp->alias_size = strnlen(ifp->alias, alias_maxlen) + 1; + + if (ifp->alias_size > MIBIF_ALIAS_SIZE) + ifp->alias_size = MIBIF_ALIAS_SIZE; + + if (ifp->alias_size < alias_maxlen) + ifp->alias = realloc(ifp->alias, ifp->alias_size); } + +fin: ifp->mibtick = get_ticks(); return (0); } @@ -706,6 +761,10 @@ mibif_free(struct mibif *ifp) mibif_reset_hc_timer(); } + if (ifp->alias != NULL) { + free(ifp->alias); + ifp->alias = NULL; + } free(ifp->private); ifp->private = NULL; free(ifp->physaddr); diff --git a/contrib/bsnmp/snmp_mibII/mibII.h b/contrib/bsnmp/snmp_mibII/mibII.h index 4d82530a9f24..18eea2163673 100644 --- a/contrib/bsnmp/snmp_mibII/mibII.h +++ b/contrib/bsnmp/snmp_mibII/mibII.h @@ -57,8 +57,9 @@ #include "snmp_mibII.h" #include "mibII_tree.h" -/* maximum size of the interface alias */ +/* maximum size of the interface alias unless overridden with net.ifdescr_maxlen */ #define MIBIF_ALIAS_SIZE (64 + 1) +#define MIBIF_ALIAS_SIZE_MAX 1024 /* * Interface list and flags. @@ -81,8 +82,6 @@ struct mibif_private { uint64_t hc_imcasts; uint64_t hc_ipackets; - /* this should be made public */ - char alias[MIBIF_ALIAS_SIZE]; }; #define MIBIF_PRIV(IFP) ((struct mibif_private *)((IFP)->private)) diff --git a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c index 03ca28c8718e..aedbff684f96 100644 --- a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c +++ b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c @@ -528,7 +528,7 @@ op_ifxtable(struct snmp_context *ctx, struct snmp_value *value, break; case LEAF_ifAlias: - ret = string_get(value, MIBIF_PRIV(ifp)->alias, -1); + ret = string_get(value, ifp->alias, ifp->alias_size - 1); break; case LEAF_ifCounterDiscontinuityTime: diff --git a/contrib/bsnmp/snmp_mibII/snmp_mibII.h b/contrib/bsnmp/snmp_mibII/snmp_mibII.h index 5df80c8eb6cd..d524d668a857 100644 --- a/contrib/bsnmp/snmp_mibII/snmp_mibII.h +++ b/contrib/bsnmp/snmp_mibII/snmp_mibII.h @@ -80,6 +80,9 @@ struct mibif { /* to be set by ifType specific modules. This is ifSpecific. */ struct asn_oid spec_oid; + char *alias; + size_t alias_size; + /* private data - don't touch */ void *private; }; diff --git a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c index 36549a38f116..5adf627cf54a 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_iso9660.c @@ -409,7 +409,8 @@ static int next_entry_seek(struct archive_read *, struct iso9660 *, struct file_info **); static struct file_info * parse_file_info(struct archive_read *a, - struct file_info *parent, const unsigned char *isodirrec); + struct file_info *parent, const unsigned char *isodirrec, + size_t reclen); static int parse_rockridge(struct archive_read *a, struct file_info *file, const unsigned char *start, const unsigned char *end); @@ -1022,7 +1023,7 @@ read_children(struct archive_read *a, struct file_info *parent) if (*(p + DR_name_len_offset) == 1 && *(p + DR_name_offset) == '\001') continue; - child = parse_file_info(a, parent, p); + child = parse_file_info(a, parent, p, b - p); if (child == NULL) { __archive_read_consume(a, skip_size); return (ARCHIVE_FATAL); @@ -1112,7 +1113,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) */ seenJoliet = iso9660->seenJoliet;/* Save flag. */ iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block); + file = parse_file_info(a, NULL, block, vd->size); if (file == NULL) return (ARCHIVE_FATAL); iso9660->seenJoliet = seenJoliet; @@ -1144,7 +1145,7 @@ choose_volume(struct archive_read *a, struct iso9660 *iso9660) return (ARCHIVE_FATAL); } iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block); + file = parse_file_info(a, NULL, block, vd->size); if (file == NULL) return (ARCHIVE_FATAL); iso9660->seenJoliet = seenJoliet; @@ -1749,7 +1750,7 @@ archive_read_format_iso9660_cleanup(struct archive_read *a) */ static struct file_info * parse_file_info(struct archive_read *a, struct file_info *parent, - const unsigned char *isodirrec) + const unsigned char *isodirrec, size_t reclen) { struct iso9660 *iso9660; struct file_info *file, *filep; @@ -1763,16 +1764,20 @@ parse_file_info(struct archive_read *a, struct file_info *parent, iso9660 = (struct iso9660 *)(a->format->data); - dr_len = (size_t)isodirrec[DR_length_offset]; + if (reclen != 0) + dr_len = (size_t)isodirrec[DR_length_offset]; + /* + * Sanity check that reclen is not zero and dr_len is greater than + * reclen but at least 34 + */ + if (reclen == 0 || reclen < dr_len || dr_len < 34) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Invalid length of directory record"); + return (NULL); + } name_len = (size_t)isodirrec[DR_name_len_offset]; location = archive_le32dec(isodirrec + DR_extent_offset); fsize = toi(isodirrec + DR_size_offset, DR_size_size); - /* Sanity check that dr_len needs at least 34. */ - if (dr_len < 34) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid length of directory record"); - return (NULL); - } /* Sanity check that name_len doesn't exceed dr_len. */ if (dr_len - 33 < name_len || name_len == 0) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, diff --git a/contrib/lua/README b/contrib/lua/README index 0b31908a06cb..ed424defe025 100644 --- a/contrib/lua/README +++ b/contrib/lua/README @@ -1,5 +1,5 @@ -This is Lua 5.3.4, released on 12 Jan 2017. +This is Lua 5.3.5, released on 26 Jun 2018. For installation instructions, license details, and further information about Lua, see doc/readme.html. diff --git a/contrib/lua/doc/contents.html b/contrib/lua/doc/contents.html index 445556f96415..c4eb2677906d 100644 --- a/contrib/lua/doc/contents.html +++ b/contrib/lua/doc/contents.html @@ -32,7 +32,7 @@ For a complete introduction to Lua programming, see the book

-Copyright © 2015–2017 Lua.org, PUC-Rio. +Copyright © 2015–2018 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -609,10 +609,10 @@ Freely available under the terms of the

diff --git a/contrib/lua/doc/lua.css b/contrib/lua/doc/lua.css index 5bedf7eb898e..cbd0799d1525 100644 --- a/contrib/lua/doc/lua.css +++ b/contrib/lua/doc/lua.css @@ -10,7 +10,7 @@ body { line-height: 1.25 ; margin: 16px auto ; padding: 32px ; - border: solid #a0a0a0 1px ; + border: solid #ccc 1px ; border-radius: 20px ; max-width: 70em ; width: 90% ; @@ -111,36 +111,29 @@ pre.session { border-radius: 8px ; } -td.gutter { - width: 4% ; -} - -table.columns { +table { border: none ; border-spacing: 0 ; border-collapse: collapse ; } +td { + padding: 0 ; + margin: 0 ; +} + +td.gutter { + width: 4% ; +} + table.columns td { vertical-align: top ; - padding: 0 ; padding-bottom: 1em ; text-align: justify ; line-height: 1.25 ; } -p.logos a:link:hover, p.logos a:visited:hover { - background-color: inherit ; -} - -table.book { - border: none ; - border-spacing: 0 ; - border-collapse: collapse ; -} - table.book td { - padding: 0 ; vertical-align: top ; } @@ -159,6 +152,10 @@ table.book span { margin-top: 0.25em ; } +p.logos a:link:hover, p.logos a:visited:hover { + background-color: inherit ; +} + img { background-color: white ; } diff --git a/contrib/lua/doc/manual.html b/contrib/lua/doc/manual.html index 3126b5d6afb3..89a642a45d92 100644 --- a/contrib/lua/doc/manual.html +++ b/contrib/lua/doc/manual.html @@ -19,7 +19,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

-Copyright © 2015–2017 Lua.org, PUC-Rio. +Copyright © 2015–2018 Lua.org, PUC-Rio. Freely available under the terms of the Lua license. @@ -35,7 +35,7 @@ Freely available under the terms of the

- + @@ -203,8 +203,8 @@ even those that do not support threads natively.

The type table implements associative arrays, -that is, arrays that can be indexed not only with numbers, -but with any Lua value except nil and NaN. +that is, arrays that can have as indices not only numbers, +but any Lua value except nil and NaN. (Not a Number is a special value used to represent undefined or unrepresentable numerical results, such as 0/0.) Tables can be heterogeneous; @@ -400,6 +400,8 @@ with the event name prefixed by two underscores; the corresponding values are called metamethods. In the previous example, the key is "__add" and the metamethod is the function that performs the addition. +Unless stated otherwise, +metamethods should be function values.

@@ -597,7 +599,7 @@ it is also slower than a real __le metamethod.)

  • __index: -The indexing access table[key]. +The indexing access operation table[key]. This event happens when table is not a table or when key is not present in table. The metamethod is looked up in table. @@ -1276,13 +1278,8 @@ Square brackets are used to index a table:
     	var ::= prefixexp ‘[’ exp ‘]

    -The meaning of accesses to table fields can be changed via metatables. -An access to an indexed variable t[i] is equivalent to -a call gettable_event(t,i). -(See §2.4 for a complete description of the -gettable_event function. -This function is not defined or callable in Lua. -We use it here only for explanatory purposes.) +The meaning of accesses to table fields can be changed via metatables +(see §2.4).

    @@ -1476,23 +1473,18 @@ and cyclically permutes the values of x, y, and z. -

    -The meaning of assignments to global variables -and table fields can be changed via metatables. -An assignment to an indexed variable t[i] = val is equivalent to -settable_event(t,i,val). -(See §2.4 for a complete description of the -settable_event function. -This function is not defined or callable in Lua. -We use it here only for explanatory purposes.) - -

    An assignment to a global name x = val is equivalent to the assignment _ENV.x = val (see §2.2). +

    +The meaning of assignments to table fields and +global variables (which are actually table fields, too) +can be changed via metatables (see §2.4). + + @@ -1831,17 +1823,17 @@ Here are some examples: g(f(), x) -- f() is adjusted to 1 result g(x, f()) -- g gets x plus all results from f() a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil) - a,b = ... -- a gets the first vararg parameter, b gets + a,b = ... -- a gets the first vararg argument, b gets -- the second (both a and b can get nil if there - -- is no corresponding vararg parameter) + -- is no corresponding vararg argument) a,b,c = x, f() -- f() is adjusted to 2 results a,b,c = f() -- f() is adjusted to 3 results return f() -- returns all results from f() - return ... -- returns all received vararg parameters + return ... -- returns all received vararg arguments return x,y,f() -- returns x, y, and all results from f() {f()} -- creates a list with all results from f() - {...} -- creates a list with all vararg parameters + {...} -- creates a list with all vararg arguments {f(), nil} -- f() is adjusted to 1 result @@ -2039,9 +2031,12 @@ two objects are considered equal only if they are the same object. Every time you create a new object (a table, userdata, or thread), this new object is different from any previously existing object. -Closures with the same reference are always equal. +A closure is always equal to itself. Closures with any detectable difference (different behavior, different definition) are always different. +Closures created at different times but with no detectable differences +may be classified as equal or not +(depending on internal caching details).

    @@ -2303,7 +2298,7 @@ If the value of prefixexp has type function, then this function is called with the given arguments. Otherwise, the prefixexp "call" metamethod is called, -having as first parameter the value of prefixexp, +having as first argument the value of prefixexp, followed by the original call arguments (see §2.4). @@ -2881,7 +2876,7 @@ it can do whatever it wants on that Lua state, as it should be already protected. However, when C code operates on other Lua states -(e.g., a Lua parameter to the function, +(e.g., a Lua argument to the function, a Lua state stored in the registry, or the result of lua_newthread), it should use them only in API calls that cannot raise errors. @@ -3370,7 +3365,7 @@ it is left unchanged. Destroys all objects in the given Lua state (calling the corresponding garbage-collection metamethods, if any) and frees all dynamic memory used by this state. -On several platforms, you may not need to call this function, +In several platforms, you may not need to call this function, because all resources are naturally released when the host program ends. On the other hand, long-running programs that create multiple states, such as daemons or web servers, @@ -5584,7 +5579,7 @@ given as argument to a hook (see lua_Hook).

    -To get information about a function you push it onto the stack +To get information about a function, you push it onto the stack and start the what string with the character '>'. (In that case, lua_getinfo pops the function from the top of the stack.) @@ -6462,7 +6457,7 @@ file-related functions in the standard library

    Pushes onto the stack the field e from the metatable -of the object at index obj and returns the type of pushed value. +of the object at index obj and returns the type of the pushed value. If the object does not have a metatable, or if the metatable does not have this field, pushes nothing and returns LUA_TNIL. @@ -6749,7 +6744,7 @@ In words, if the argument arg is nil or absent, the macro results in the default dflt. Otherwise, it results in the result of calling func with the state L and the argument index arg as -parameters. +arguments. Note that it evaluates the expression dflt only if needed. @@ -8680,7 +8675,7 @@ the lowercase letters plus the '-' character.

    You can put a closing square bracket in a set by positioning it as the first character in the set. -You can put an hyphen in a set +You can put a hyphen in a set by positioning it as the first or the last character in the set. (You can also use an escape for both cases.) @@ -9082,8 +9077,8 @@ Returns the destination table a2.

    -Returns a new table with all parameters stored into keys 1, 2, etc. -and with a field "n" with the total number of parameters. +Returns a new table with all arguments stored into keys 1, 2, etc. +and with a field "n" with the total number of arguments. Note that the resulting table may not be a sequence. @@ -9215,7 +9210,7 @@ Returns the arc sine of x (in radians).

    Returns the arc tangent of y/x (in radians), -but uses the signs of both parameters to find the +but uses the signs of both arguments to find the quadrant of the result. (It also handles correctly the case of x being zero.) @@ -9516,7 +9511,7 @@ all I/O functions return nil on failure (plus an error message as a second result and a system-dependent error code as a third result) and some value different from nil on success. -On non-POSIX systems, +In non-POSIX systems, the computation of the error message and error code in case of errors may be not thread safe, @@ -9553,7 +9548,7 @@ When called with a file name, it opens the named file (in text mode), and sets its handle as the default input file. When called with a file handle, it simply sets this file handle as the default input file. -When called without parameters, +When called without arguments, it returns the current default input file. @@ -9580,7 +9575,7 @@ it returns no values (to finish the loop) and automatically closes the file. The call io.lines() (with no file name) is equivalent to io.input():lines("*l"); that is, it iterates over the lines of the default input file. -In this case it does not close the file when the loop ends. +In this case, the iterator does not close the file when the loop ends.

    @@ -9963,7 +9958,7 @@ the host system and on the current locale.

    -On non-POSIX systems, +In non-POSIX systems, this function may be not thread safe because of its reliance on C function gmtime and C function localtime. @@ -10163,7 +10158,7 @@ and explicitly removed when no longer needed.

    -On POSIX systems, +In POSIX systems, this function also creates a file with that name, to avoid security risks. (Someone else might create the file with wrong permissions @@ -10301,8 +10296,8 @@ The first parameter or local variable has index 1, and so on, following the order that they are declared in the code, counting only the variables that are active in the current scope of the function. -Negative indices refer to vararg parameters; --1 is the first vararg parameter. +Negative indices refer to vararg arguments; +-1 is the first vararg argument. The function returns nil if there is no variable with the given index, and raises an error when called with a level out of range. (You can call debug.getinfo to check whether the level is valid.) @@ -10400,7 +10395,7 @@ When called without arguments,

    -When the hook is called, its first parameter is a string +When the hook is called, its first argument is a string describing the event that has triggered its call: "call" (or "tail call"), "return", @@ -10551,7 +10546,8 @@ The options are: