summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2016-01-11 19:36:44 +0000
committerdim <dim@FreeBSD.org>2016-01-11 19:36:44 +0000
commit79c349e677e1561f808f42fec3e6151d88397dd8 (patch)
treeea943142da24fe9f4d36e8fd2ca89c22a874740d
parentca5a713355f56c0b7f18b4a361310ac52b13b066 (diff)
parent4ba3f354902d216384ffbcd5a6b1b3e219d451ea (diff)
downloadFreeBSD-src-79c349e677e1561f808f42fec3e6151d88397dd8.zip
FreeBSD-src-79c349e677e1561f808f42fec3e6151d88397dd8.tar.gz
Merge ^/head r293430 through r293685.
-rw-r--r--Makefile.inc113
-rw-r--r--bin/sh/eval.c4
-rw-r--r--bin/sh/tests/builtins/Makefile1
-rw-r--r--bin/sh/tests/builtins/local5.015
-rw-r--r--bin/sh/var.c11
-rw-r--r--contrib/hyperv/tools/hv_kvp_daemon.c2
-rw-r--r--gnu/lib/libgcc/Makefile55
-rw-r--r--include/limits.h7
-rw-r--r--lib/csu/arm/Makefile5
-rw-r--r--lib/libc/sys/sendfile.2123
-rw-r--r--lib/libstand/uuid_to_string.c4
-rwxr-xr-xrelease/release.sh1
-rw-r--r--share/man/man4/ismt.44
-rw-r--r--share/man/man5/src.conf.523
-rw-r--r--share/misc/committers-src.dot2
-rw-r--r--share/mk/src.opts.mk4
-rw-r--r--sys/amd64/amd64/elf_machdep.c1
-rw-r--r--sys/amd64/amd64/trap.c7
-rw-r--r--sys/amd64/linux/linux_sysvec.c51
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c1
-rw-r--r--sys/arm/arm/elf_machdep.c1
-rw-r--r--sys/arm64/arm64/elf_machdep.c2
-rw-r--r--sys/boot/common/ufsread.c1
-rw-r--r--sys/boot/efi/boot1/Makefile3
-rw-r--r--sys/boot/efi/boot1/boot1.c270
-rw-r--r--sys/boot/i386/loader/main.c16
-rw-r--r--sys/boot/powerpc/boot1.chrp/boot1.c4
-rw-r--r--sys/boot/userboot/libstand/Makefile134
-rw-r--r--sys/boot/userboot/libstand/Makefile.depend1
-rw-r--r--sys/boot/userboot/userboot/main.c19
-rw-r--r--sys/boot/zfs/zfs.c11
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c130
-rw-r--r--sys/compat/ia32/ia32_sysvec.c1
-rw-r--r--sys/compat/linux/linux_futex.c6
-rw-r--r--sys/compat/svr4/svr4_sysvec.c1
-rw-r--r--sys/contrib/ipfilter/netinet/ip_fil_freebsd.c71
-rw-r--r--sys/dev/cxgbe/t4_main.c7
-rw-r--r--sys/dev/ic/ns16550.h2
-rw-r--r--sys/dev/iscsi/iscsi.c99
-rw-r--r--sys/dev/iscsi/iscsi.h3
-rw-r--r--sys/dev/puc/pucdata.c154
-rw-r--r--sys/dev/rtwn/if_rtwn.c2
-rw-r--r--sys/dev/sfxge/common/efsys.h1
-rw-r--r--sys/dev/ti/if_ti.c4
-rw-r--r--sys/dev/vt/hw/ofwfb/ofwfb.c25
-rw-r--r--sys/fs/ext2fs/ext2_bmap.c31
-rw-r--r--sys/fs/ext2fs/ext2_extents.c26
-rw-r--r--sys/fs/ext2fs/ext2_extents.h6
-rw-r--r--sys/fs/ext2fs/ext2_vfsops.c2
-rw-r--r--sys/fs/ext2fs/ext2_vnops.c51
-rw-r--r--sys/fs/smbfs/smbfs_smb.c8
-rw-r--r--sys/fs/smbfs/smbfs_subr.h3
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c3
-rw-r--r--sys/i386/i386/elf_machdep.c1
-rw-r--r--sys/i386/ibcs2/ibcs2_sysvec.c1
-rw-r--r--sys/i386/linux/linux_sysvec.c2
-rw-r--r--sys/kern/imgact_aout.c1
-rw-r--r--sys/kern/init_main.c1
-rw-r--r--sys/kern/kern_condvar.c33
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/kern/uipc_sockbuf.c25
-rw-r--r--sys/kern/uipc_syscalls.c682
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/mips/mips/elf_machdep.c2
-rw-r--r--sys/mips/mips/freebsd32_machdep.c1
-rw-r--r--sys/net/if_arcsubr.c5
-rw-r--r--sys/net/if_ethersubr.c4
-rw-r--r--sys/net/if_fddisubr.c5
-rw-r--r--sys/net/if_fwsubr.c9
-rw-r--r--sys/net/if_iso88025subr.c8
-rw-r--r--sys/net/if_loop.c8
-rw-r--r--sys/net/radix_mpath.c61
-rw-r--r--sys/net/radix_mpath.h1
-rw-r--r--sys/net/route.c17
-rw-r--r--sys/net/route.h28
-rw-r--r--sys/net80211/ieee80211_freebsd.c1
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c4
-rw-r--r--sys/netgraph/netflow/netflow.c1
-rw-r--r--sys/netgraph/netflow/netflow_v9.c1
-rw-r--r--sys/netgraph/netflow/ng_netflow.c1
-rw-r--r--sys/netinet/in_fib.c7
-rw-r--r--sys/netinet/in_pcb.c1
-rw-r--r--sys/netinet/ip_encap.c2
-rw-r--r--sys/netinet/ip_mroute.c1
-rw-r--r--sys/netinet/ip_output.c1
-rw-r--r--sys/netinet/raw_ip.c1
-rw-r--r--sys/netinet/tcp_reass.c1
-rw-r--r--sys/netinet/tcp_subr.c1
-rw-r--r--sys/netinet/toecore.c15
-rw-r--r--sys/netinet6/frag6.c1
-rw-r--r--sys/netinet6/icmp6.c51
-rw-r--r--sys/netinet6/in6_fib.c7
-rw-r--r--sys/netinet6/in6_pcb.c12
-rw-r--r--sys/netinet6/in6_rmx.c30
-rw-r--r--sys/netinet6/in6_src.c84
-rw-r--r--sys/netinet6/ip6_var.h7
-rw-r--r--sys/netinet6/nd6_nbr.c41
-rw-r--r--sys/netinet6/raw_ip6.c33
-rw-r--r--sys/netinet6/udp6_usrreq.c10
-rw-r--r--sys/netpfil/ipfw/ip_fw_table.c2
-rw-r--r--sys/netpfil/ipfw/ip_fw_table_algo.c122
-rw-r--r--sys/netpfil/pf/pf_if.c1
-rw-r--r--sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c8
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c2
-rw-r--r--sys/powerpc/aim/locore32.S71
-rw-r--r--sys/powerpc/aim/locore64.S99
-rw-r--r--sys/powerpc/aim/trap_subr64.S9
-rw-r--r--sys/powerpc/booke/booke_machdep.c3
-rw-r--r--sys/powerpc/booke/locore.S23
-rw-r--r--sys/powerpc/include/pcb.h4
-rw-r--r--sys/powerpc/include/setjmp.h4
-rw-r--r--sys/powerpc/ofw/rtas.c7
-rw-r--r--sys/powerpc/powermac/grackle.c7
-rw-r--r--sys/powerpc/powerpc/copyinout.c62
-rw-r--r--sys/powerpc/powerpc/elf32_machdep.c1
-rw-r--r--sys/powerpc/powerpc/elf64_machdep.c1
-rw-r--r--sys/powerpc/powerpc/mp_machdep.c1
-rw-r--r--sys/powerpc/powerpc/setjmp.S1
-rw-r--r--sys/powerpc/powerpc/trap.c22
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c1
-rw-r--r--sys/sys/mbuf.h4
-rw-r--r--sys/sys/sf_buf.h7
-rw-r--r--sys/sys/sockbuf.h4
-rw-r--r--sys/sys/socket.h5
-rw-r--r--sys/sys/sysent.h1
-rw-r--r--sys/vm/vm_domain.c16
-rw-r--r--tools/build/options/WITHOUT_LLVM_LIBUNWIND2
-rw-r--r--tools/build/options/WITH_LLVM_LIBUNWIND2
-rw-r--r--tools/regression/geom_concat/conf.sh7
-rw-r--r--tools/regression/geom_concat/test-1.t15
-rw-r--r--tools/regression/geom_concat/test-2.t19
-rw-r--r--tools/regression/geom_eli/attach-d.t6
-rwxr-xr-xtools/regression/geom_eli/conf.sh21
-rw-r--r--tools/regression/geom_eli/configure-b-B.t5
-rw-r--r--tools/regression/geom_eli/delkey.t12
-rw-r--r--tools/regression/geom_eli/detach-l.t6
-rw-r--r--tools/regression/geom_eli/init-B.t12
-rw-r--r--tools/regression/geom_eli/init-J.t12
-rw-r--r--tools/regression/geom_eli/init-a.t7
-rw-r--r--tools/regression/geom_eli/init-i-P.t6
-rw-r--r--tools/regression/geom_eli/init.t7
-rw-r--r--tools/regression/geom_eli/integrity-copy.t7
-rw-r--r--tools/regression/geom_eli/integrity-data.t7
-rw-r--r--tools/regression/geom_eli/integrity-hmac.t7
-rw-r--r--tools/regression/geom_eli/kill.t8
-rw-r--r--tools/regression/geom_eli/nokey.t6
-rw-r--r--tools/regression/geom_eli/onetime-a.t5
-rw-r--r--tools/regression/geom_eli/onetime-d.t3
-rw-r--r--tools/regression/geom_eli/onetime.t5
-rw-r--r--tools/regression/geom_eli/readonly.t5
-rw-r--r--tools/regression/geom_eli/resize.t8
-rw-r--r--tools/regression/geom_eli/setkey.t16
-rw-r--r--tools/regression/geom_gate/Makefile8
-rw-r--r--tools/regression/geom_gate/runtests.sh8
-rw-r--r--tools/regression/geom_gate/test-1.sh36
-rw-r--r--tools/regression/geom_gate/test-1.t74
-rw-r--r--tools/regression/geom_gate/test-2.sh28
-rw-r--r--tools/regression/geom_gate/test-2.t47
-rw-r--r--tools/regression/geom_gate/test-3.sh31
-rw-r--r--tools/regression/geom_gate/test-3.t50
-rw-r--r--tools/regression/geom_nop/conf.sh7
-rw-r--r--tools/regression/geom_nop/test-1.t11
-rw-r--r--tools/regression/geom_nop/test-2.t15
-rw-r--r--tools/regression/geom_raid3/conf.sh7
-rw-r--r--tools/regression/geom_raid3/test-1.t17
-rw-r--r--tools/regression/geom_raid3/test-10.t21
-rw-r--r--tools/regression/geom_raid3/test-11.t21
-rw-r--r--tools/regression/geom_raid3/test-12.t28
-rw-r--r--tools/regression/geom_raid3/test-2.t21
-rw-r--r--tools/regression/geom_raid3/test-3.t21
-rw-r--r--tools/regression/geom_raid3/test-4.t21
-rw-r--r--tools/regression/geom_raid3/test-5.t21
-rw-r--r--tools/regression/geom_raid3/test-6.t23
-rw-r--r--tools/regression/geom_raid3/test-7.t25
-rw-r--r--tools/regression/geom_raid3/test-8.t23
-rw-r--r--tools/regression/geom_raid3/test-9.t25
-rw-r--r--tools/regression/geom_shsec/conf.sh7
-rw-r--r--tools/regression/geom_shsec/test-1.t17
-rw-r--r--tools/regression/geom_shsec/test-2.t25
-rw-r--r--tools/regression/geom_stripe/conf.sh7
-rw-r--r--tools/regression/geom_stripe/test-1.t15
-rw-r--r--tools/regression/geom_stripe/test-2.t17
-rw-r--r--tools/regression/geom_subr.sh43
-rw-r--r--tools/regression/geom_uzip/Makefile2
-rwxr-xr-xtools/regression/geom_uzip/conf.sh20
-rw-r--r--tools/regression/geom_uzip/runtests.sh10
-rw-r--r--tools/regression/geom_uzip/test-1.sh36
-rw-r--r--tools/regression/geom_uzip/test-1.t22
-rw-r--r--tools/regression/geom_uzip/test-2.sh15
-rw-r--r--usr.bin/netstat/mbuf.c26
-rw-r--r--usr.sbin/bhyve/pci_virtio_net.c306
-rw-r--r--usr.sbin/bsdconfig/share/dialog.subr1
-rwxr-xr-xusr.sbin/ntp/scripts/mkver2
193 files changed, 2459 insertions, 2052 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index c5b09f3..d0f2d2d 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -570,9 +570,8 @@ _worldtmp: .PHONY
.else
rm -rf ${WORLDTMP}/legacy/usr/include
# XXX - These three can depend on any header file.
- rm -f ${OBJTREE}${.CURDIR}/usr.bin/kdump/ioctl.c
+ rm -f ${OBJTREE}${.CURDIR}/lib/libsysdecode/ioctl.c
rm -f ${OBJTREE}${.CURDIR}/usr.bin/kdump/kdump_subr.c
- rm -f ${OBJTREE}${.CURDIR}/usr.bin/truss/ioctl.c
.endif
.for _dir in \
lib usr legacy/bin legacy/usr
@@ -1425,11 +1424,13 @@ _vtfontcvt= usr.bin/vtfontcvt
_sed= usr.bin/sed
.endif
-.if ${BOOTSTRAPPING} < 1000002
+.if ${BOOTSTRAPPING} < 1000033
_libopenbsd= lib/libopenbsd
_m4= usr.bin/m4
+_lex= usr.bin/lex
${_bt}-usr.bin/m4: ${_bt}-lib/libopenbsd
+${_bt}-usr.bin/lex: ${_bt}-usr.bin/m4
.endif
.if ${BOOTSTRAPPING} < 1000026
@@ -1443,12 +1444,6 @@ ${_bt}-usr.sbin/nmtree: ${_bt}-lib/libnetbsd
_cat= bin/cat
.endif
-.if ${BOOTSTRAPPING} < 1000033
-_lex= usr.bin/lex
-
-${_bt}-usr.bin/lex: ${_bt}-usr.bin/m4
-.endif
-
# r277259 crunchide: Correct 64-bit section header offset
# r281674 crunchide: always include both 32- and 64-bit ELF support
# r285986 crunchen: use STRIPBIN rather than STRIP
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 5a3f8e7..949157d 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -1039,12 +1039,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
reffunc(cmdentry.u.func);
savehandler = handler;
if (setjmp(jmploc.loc)) {
- freeparam(&shellparam);
- shellparam = saveparam;
popredir();
unreffunc(cmdentry.u.func);
poplocalvars();
localvars = savelocalvars;
+ freeparam(&shellparam);
+ shellparam = saveparam;
funcnest--;
handler = savehandler;
longjmp(handler->loc, 1);
diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile
index 11240ca..1511f70 100644
--- a/bin/sh/tests/builtins/Makefile
+++ b/bin/sh/tests/builtins/Makefile
@@ -111,6 +111,7 @@ FILES+= local1.0
FILES+= local2.0
FILES+= local3.0
FILES+= local4.0
+FILES+= local5.0
.if ${MK_NLS} != "no"
FILES+= locale1.0
.endif
diff --git a/bin/sh/tests/builtins/local5.0 b/bin/sh/tests/builtins/local5.0
new file mode 100644
index 0000000..2f2a14e
--- /dev/null
+++ b/bin/sh/tests/builtins/local5.0
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+f() {
+ local PATH IFS elem
+ IFS=:
+ for elem in ''$PATH''; do
+ PATH=/var/empty/$elem:$PATH
+ done
+ ls -d / >/dev/null
+}
+
+p1=$(command -v ls)
+f
+p2=$(command -v ls)
+[ "$p1" = "$p2" ]
diff --git a/bin/sh/var.c b/bin/sh/var.c
index d401361..3af7dbe 100644
--- a/bin/sh/var.c
+++ b/bin/sh/var.c
@@ -791,6 +791,7 @@ poplocalvars(void)
{
struct localvar *lvp;
struct var *vp;
+ int islocalevar;
INTOFF;
while ((lvp = localvars) != NULL) {
@@ -803,10 +804,20 @@ poplocalvars(void)
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
(void)unsetvar(vp->text);
} else {
+ islocalevar = (vp->flags | lvp->flags) & VEXPORT &&
+ localevar(lvp->text);
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
vp->flags = lvp->flags;
vp->text = lvp->text;
+ if (vp->func)
+ (*vp->func)(vp->text + vp->name_len + 1);
+ if (islocalevar) {
+ change_env(vp->text, vp->flags & VEXPORT &&
+ (vp->flags & VUNSET) == 0);
+ setlocale(LC_ALL, "");
+ updatecharset();
+ }
}
ckfree(lvp);
}
diff --git a/contrib/hyperv/tools/hv_kvp_daemon.c b/contrib/hyperv/tools/hv_kvp_daemon.c
index 50ae3ed..9b9e3a6 100644
--- a/contrib/hyperv/tools/hv_kvp_daemon.c
+++ b/contrib/hyperv/tools/hv_kvp_daemon.c
@@ -1437,7 +1437,7 @@ main(int argc, char *argv[])
for (;;) {
- r = poll (hv_kvp_poll_fd, 1, 100);
+ r = poll (hv_kvp_poll_fd, 1, INFTIM);
KVP_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\n",
r, hv_kvp_poll_fd[0].revents);
diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile
index 6972146..ad4e0f1 100644
--- a/gnu/lib/libgcc/Makefile
+++ b/gnu/lib/libgcc/Makefile
@@ -2,6 +2,9 @@
GCCDIR= ${.CURDIR}/../../../contrib/gcc
GCCLIB= ${.CURDIR}/../../../contrib/gcclibs
+COMPILERRTDIR= ${.CURDIR}/../../../contrib/compiler-rt
+UNWINDINCDIR= ${.CURDIR}/../../../contrib/llvm/projects/libunwind/include
+UNWINDSRCDIR= ${.CURDIR}/../../../contrib/llvm/projects/libunwind/src
SHLIB_NAME= libgcc_s.so.1
SHLIBDIR?= /lib
@@ -67,8 +70,37 @@ LIB2ADD = $(LIB2FUNCS_EXTRA)
LIB2ADD_ST = $(LIB2FUNCS_STATIC_EXTRA)
# Additional sources to handle exceptions; overridden by targets as needed.
+.if ${MK_LLVM_LIBUNWIND} != "no"
+
+.PATH: ${COMPILERRTDIR}/lib/builtins
+.PATH: ${UNWINDSRCDIR}
+LIB2ADDEH = gcc_personality_v0.c \
+ int_util.c \
+ Unwind-EHABI.cpp \
+ Unwind-sjlj.c \
+ UnwindLevel1-gcc-ext.c \
+ UnwindLevel1.c \
+ UnwindRegistersRestore.S \
+ UnwindRegistersSave.S \
+ libunwind.cpp
+
+CFLAGS+= -I${UNWINDINCDIR} -I${.CURDIR}
+.if empty(CXXFLAGS:M-std=*)
+CXXFLAGS+= -std=c++11
+.endif
+CXXFLAGS+= -fno-rtti
+
+.else # MK_LLVM_LIBUNWIND
+
+.if ${TARGET_CPUARCH} == "arm"
+LIB2ADDEH = unwind-arm.c libunwind.S pr-support.c unwind-c.c
+.else
LIB2ADDEH = unwind-dw2.c unwind-dw2-fde-glibc.c unwind-sjlj.c gthr-gnat.c \
unwind-c.c
+.endif
+
+.endif # MK_LLVM_LIBUNWIND
+
LIB2ADDEHSTATIC = $(LIB2ADDEH)
LIB2ADDEHSHARED = $(LIB2ADDEH)
@@ -116,7 +148,6 @@ CFLAGS.clang+= -fheinous-gnu-extensions
LIB1ASMSRC = lib1funcs.asm
LIB1ASMFUNCS = _dvmd_tls _bb_init_func
-LIB2ADDEH = unwind-arm.c libunwind.S pr-support.c unwind-c.c
# Some compilers generate __aeabi_ functions libgcc_s is missing
LIBADD+= compiler_rt
.endif
@@ -160,7 +191,10 @@ LIB2_DIVMOD_FUNCS:= ${LIB2_DIVMOD_FUNCS:S/${sym}//g}
.endfor
.endif
-COMMONHDRS= tm.h tconfig.h options.h unwind.h gthr-default.h
+COMMONHDRS= tm.h tconfig.h options.h gthr-default.h
+.if ${MK_LLVM_LIBUNWIND} == no
+COMMONHDRS+= unwind.h
+.endif
#-----------------------------------------------------------------------
#
@@ -170,6 +204,9 @@ HIDE = -fvisibility=hidden -DHIDE_EXPORTS
CC_T = ${CC} -c ${CFLAGS} ${HIDE} -fPIC
CC_P = ${CC} -c ${CFLAGS} ${HIDE} -p -fPIC
CC_S = ${CC} -c ${CFLAGS} ${PICFLAG} -DSHARED
+CXX_T = ${CXX} -c ${CXXFLAGS} ${HIDE} -fPIC
+CXX_P = ${CXX} -c ${CXXFLAGS} ${HIDE} -p -fPIC
+CXX_S = ${CXX} -c ${CXXFLAGS} ${PICFLAG} -DSHARED
#-----------------------------------------------------------------------
#
@@ -284,16 +321,26 @@ EH_OBJS_S = ${LIB2ADDEHSHARED:R:S/$/.So/}
EH_CFLAGS = -fexceptions -D__GLIBC__=3 -DElfW=__ElfN
SOBJS += ${EH_OBJS_S}
-.for _src in ${LIB2ADDEHSTATIC}
+.for _src in ${LIB2ADDEHSTATIC:M*.c}
${_src:R:S/$/.o/}: ${_src} ${COMMONHDRS}
${CC_T} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
${_src:R:S/$/.po/}: ${_src} ${COMMONHDRS}
${CC_P} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
.endfor
-.for _src in ${LIB2ADDEHSHARED}
+.for _src in ${LIB2ADDEHSTATIC:M*.cpp}
+${_src:R:S/$/.o/}: ${_src} ${COMMONHDRS}
+ ${CXX_T} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
+${_src:R:S/$/.po/}: ${_src} ${COMMONHDRS}
+ ${CXX_P} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
+.endfor
+.for _src in ${LIB2ADDEHSHARED:M*.c}
${_src:R:S/$/.So/}: ${_src} ${COMMONHDRS}
${CC_S} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
.endfor
+.for _src in ${LIB2ADDEHSHARED:M*.cpp}
+${_src:R:S/$/.So/}: ${_src} ${COMMONHDRS}
+ ${CXX_S} ${EH_CFLAGS} -o ${.TARGET} ${.IMPSRC}
+.endfor
#-----------------------------------------------------------------------
diff --git a/include/limits.h b/include/limits.h
index 3910928..a1e1b98 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -59,10 +59,12 @@
#define _POSIX_TZNAME_MAX 3
#endif
+#if __POSIX_VISIBLE >= 200112
#define BC_BASE_MAX 99 /* max ibase/obase values in bc(1) */
#define BC_DIM_MAX 2048 /* max array elements in bc(1) */
#define BC_SCALE_MAX 99 /* max scale value in bc(1) */
#define BC_STRING_MAX 1000 /* max const string length in bc(1) */
+#define CHARCLASS_NAME_MAX 14 /* max character class name size */
#define COLL_WEIGHTS_MAX 10 /* max weights for order keyword */
#define EXPR_NEST_MAX 32 /* max expressions nested in expr(1) */
#define LINE_MAX 2048 /* max bytes in an input line */
@@ -72,11 +74,14 @@
#define _POSIX2_BC_DIM_MAX 2048
#define _POSIX2_BC_SCALE_MAX 99
#define _POSIX2_BC_STRING_MAX 1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
#define _POSIX2_EQUIV_CLASS_MAX 2
#define _POSIX2_EXPR_NEST_MAX 32
#define _POSIX2_LINE_MAX 2048
#define _POSIX2_RE_DUP_MAX 255
#endif
+#endif
#if __POSIX_VISIBLE >= 199309
#define _POSIX_AIO_LISTIO_MAX 2
@@ -110,8 +115,6 @@
#define _POSIX_TRACE_SYS_MAX 8
#define _POSIX_TRACE_USER_EVENT_MAX 32
#define _POSIX_TTY_NAME_MAX 9
-#define _POSIX2_CHARCLASS_NAME_MAX 14
-#define _POSIX2_COLL_WEIGHTS_MAX 2
#define _POSIX_RE_DUP_MAX _POSIX2_RE_DUP_MAX
#endif
diff --git a/lib/csu/arm/Makefile b/lib/csu/arm/Makefile
index 9747619..1b3a6f8 100644
--- a/lib/csu/arm/Makefile
+++ b/lib/csu/arm/Makefile
@@ -7,6 +7,7 @@ OBJS= ${SRCS:N*.h:R:S/$/.o/g}
OBJS+= Scrt1.o gcrt1.o
CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
+STATIC_CFLAGS+= -mlong-calls
FILES= ${OBJS}
FILESMODE= ${LIBMODE}
@@ -23,14 +24,14 @@ CLEANFILES+= crt1.s gcrt1.s Scrt1.s
# directly compiled to .o files.
crt1.s: crt1.c
- ${CC} ${CFLAGS} -S -o ${.TARGET} ${.CURDIR}/crt1.c
+ ${CC} ${CFLAGS} ${STATIC_CFLAGS} -S -o ${.TARGET} ${.CURDIR}/crt1.c
sed ${SED_FIX_NOTE} ${.TARGET}
crt1.o: crt1.s
${CC} ${ACFLAGS} -c -o ${.TARGET} crt1.s
gcrt1.s: crt1.c
- ${CC} ${CFLAGS} -DGCRT -S -o ${.TARGET} ${.CURDIR}/crt1.c
+ ${CC} ${CFLAGS} ${STATIC_CFLAGS} -DGCRT -S -o ${.TARGET} ${.CURDIR}/crt1.c
sed ${SED_FIX_NOTE} ${.TARGET}
gcrt1.o: gcrt1.s
diff --git a/lib/libc/sys/sendfile.2 b/lib/libc/sys/sendfile.2
index b363382..2b52dd9 100644
--- a/lib/libc/sys/sendfile.2
+++ b/lib/libc/sys/sendfile.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 7, 2010
+.Dd January 7, 2016
.Dt SENDFILE 2
.Os
.Sh NAME
@@ -46,7 +46,7 @@
The
.Fn sendfile
system call
-sends a regular file specified by descriptor
+sends a regular file or shared memory object specified by descriptor
.Fa fd
out a stream socket specified by descriptor
.Fa s .
@@ -101,32 +101,55 @@ the system will write the total number of bytes sent on the socket to the
variable pointed to by
.Fa sbytes .
.Pp
-The
+The least significant 16 bits of
.Fa flags
argument is a bitmap of these values:
-.Bl -item -offset indent
-.It
-.Dv SF_NODISKIO .
-This flag causes any
-.Fn sendfile
-call which would block on disk I/O to instead
-return
-.Er EBUSY .
-Busy servers may benefit by transferring requests that would
-block to a separate I/O worker thread.
-.It
-.Dv SF_MNOWAIT .
-Do not wait for some kernel resource to become available,
-in particular,
-.Vt mbuf
-and
-.Vt sf_buf .
-The flag does not make the
-.Fn sendfile
-syscall truly non-blocking, since other resources are still allocated
-in a blocking fashion.
-.It
-.Dv SF_SYNC .
+.Bl -tag -offset indent
+.It Dv SF_NODISKIO
+This flag causes
+.Nm
+to return
+.Er EBUSY
+instead of blocking when a busy page is encountered.
+This rare situation can happen if some other process is now working
+with the same region of the file.
+It is advised to retry the operation after a short period.
+.Pp
+Note that in older
+.Fx
+versions the
+.Dv SF_NODISKIO
+had slightly different notion.
+The flag prevented
+.Nm
+to run I/O operations in case if an invalid (not cached) page is encountered,
+thus avoiding blocking on I/O.
+Starting with
+.Fx 11
+.Nm
+sending files off the
+.Xr ffs 7
+filesystem doesn't block on I/O
+(see
+.Sx IMPLEMENTATION NOTES
+), so the condition no longer applies.
+However, it is safe if an application utilizes
+.Dv SF_NODISKIO
+and on
+.Er EBUSY
+performs the same action as it did in
+older
+.Fx
+versions, e.g.
+.Xr aio_read 2,
+.Xr read 2
+or
+.Nm
+in a different context.
+.It Dv SF_NOCACHE
+The data sent to socket will not be cached by the virtual memory system,
+and will be freed directly to the pool of free pages.
+.It Dv SF_SYNC
.Nm
sleeps until the network stack no longer references the VM pages
of the file, making subsequent modifications to it safe.
@@ -134,6 +157,22 @@ Please note that this is not a guarantee that the data has actually
been sent.
.El
.Pp
+The most significant 16 bits of
+.Fa flags
+specify amount of pages that
+.Nm
+may read ahead when reading the file.
+A macro
+.Fn SF_FLAGS
+is provided to combine readahead amount and flags.
+Example shows specifing readahead of 16 pages and
+.Dv SF_NOCACHE
+flag:
+.Pp
+.Bd -literal -offset indent -compact
+ SF_FLAGS(16, SF_NOCACHE)
+.Ed
+.Pp
When using a socket marked for non-blocking I/O,
.Fn sendfile
may send fewer bytes than requested.
@@ -149,6 +188,18 @@ The
.Fx
implementation of
.Fn sendfile
+doesn't block on disk I/O when it sends a file off the
+.Xr ffs 7
+filesystem.
+The syscall returns success before the actual I/O completes, and data
+is put into the socket later unattended.
+However, the order of data in the socket is preserved, so it is safe
+to do further writes to the socket.
+.Pp
+The
+.Fx
+implementation of
+.Fn sendfile
is "zero-copy", meaning that it has been optimized so that copying of the file data is avoided.
.Sh TUNING
On some architectures, this system call internally uses a special
@@ -232,12 +283,10 @@ The
argument
is not a valid socket descriptor.
.It Bq Er EBUSY
-Completing the entire transfer would have required disk I/O, so
-it was aborted.
-Partial data may have been sent.
-(This error can only occur when
+A busy page was encountered and
.Dv SF_NODISKIO
-is specified.)
+had been specified.
+Partial data may have been sent.
.It Bq Er EFAULT
An invalid address was specified for an argument.
.It Bq Er EINTR
@@ -310,9 +359,19 @@ first appeared in
.Fx 3.0 .
This manual page first appeared in
.Fx 3.1 .
+In
+.Fx 10
+support for sending shared memory descriptors had been introduced.
+In
+.Fx 11
+a non-blocking implementation had been introduced.
.Sh AUTHORS
-The
+The initial implementation of
.Fn sendfile
system call
and this manual page were written by
.An David G. Lawrence Aq Mt dg@dglawrence.com .
+The
+.Fx 11
+implementation was written by
+.An Gleb Smirnoff Aq Mt glebius@FreeBSD.org .
diff --git a/lib/libstand/uuid_to_string.c b/lib/libstand/uuid_to_string.c
index efe921c..d878af4 100644
--- a/lib/libstand/uuid_to_string.c
+++ b/lib/libstand/uuid_to_string.c
@@ -46,7 +46,7 @@ tohex(char **buf, int len, uint32_t val)
char *walker = *buf;
int i;
- for (i = len - 1; i >= 0; i++) {
+ for (i = len - 1; i >= 0; i--) {
walker[i] = hexstr[val & 0xf];
val >>= 4;
}
@@ -107,5 +107,5 @@ uuid_to_string(const uuid_t *u, char **s, uint32_t *status)
tohex(&w, 2, u->node[3]);
tohex(&w, 2, u->node[4]);
tohex(&w, 2, u->node[5]);
- *w++ - '\0';
+ *w++ = '\0';
}
diff --git a/release/release.sh b/release/release.sh
index 313a16c..caa6f26 100755
--- a/release/release.sh
+++ b/release/release.sh
@@ -275,6 +275,7 @@ extra_chroot_setup() {
PBUILD_FLAGS="${PBUILD_FLAGS} OSREL=${REVISION}"
chroot ${CHROOTDIR} make -C /usr/ports/textproc/docproj \
${PBUILD_FLAGS} OPTIONS_UNSET="FOP IGOR" \
+ FORCE_PKG_REGISTER=1 \
install clean distclean
fi
fi
diff --git a/share/man/man4/ismt.4 b/share/man/man4/ismt.4
index 63a3952..b027f6f 100644
--- a/share/man/man4/ismt.4
+++ b/share/man/man4/ismt.4
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 9, 2014
+.Dd January 11, 2016
.Dt ISMT 4
.Os
.Sh NAME
@@ -54,6 +54,6 @@ in the Intel Atom S1200 and C2000 CPUs.
The
.Nm
driver first appeared in
-.Fx 11.0 .
+.Fx 10.3 .
.Sh AUTHORS
.An Jim Harris Aq Mt jimharris@FreeBSD.org
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 4994aab..60bf53a 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,7 +1,7 @@
.\" DO NOT EDIT-- this file is automatically generated.
.\" from FreeBSD: head/tools/build/options/makeman 292283 2015-12-15 18:42:30Z bdrewery
.\" $FreeBSD$
-.Dd December 15, 2015
+.Dd January 9, 2016
.Dt SRC.CONF 5
.Os
.Sh NAME
@@ -948,9 +948,30 @@ Set to not build the
.Nm libthr
(1:1 threading)
library.
+.It Va WITHOUT_LLDB
+.\" from FreeBSD: head/tools/build/options/WITHOUT_LLDB 289275 2015-10-14 00:23:31Z emaste
+Set to not build the LLDB debugger.
+.Pp
+It is a default setting on
+arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, pc98/i386, powerpc/powerpc, powerpc/powerpc64 and sparc64/sparc64.
.It Va WITH_LLDB
.\" from FreeBSD: head/tools/build/options/WITH_LLDB 255722 2013-09-20 01:52:02Z emaste
Set to build the LLDB debugger.
+.Pp
+It is a default setting on
+amd64/amd64 and arm64/aarch64.
+.It Va WITHOUT_LLVM_LIBUNWIND
+.\" from FreeBSD: head/tools/build/options/WITHOUT_LLVM_LIBUNWIND 293450 2016-01-09 00:42:07Z emaste
+Set to use GCC's stack unwinder (instead of LLVM's libunwind).
+.Pp
+It is a default setting on
+amd64/amd64, arm/arm, arm/armeb, arm/armv6, arm/armv6hf, i386/i386, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, pc98/i386, powerpc/powerpc, powerpc/powerpc64 and sparc64/sparc64.
+.It Va WITH_LLVM_LIBUNWIND
+.\" from FreeBSD: head/tools/build/options/WITH_LLVM_LIBUNWIND 293450 2016-01-09 00:42:07Z emaste
+Set to use LLVM's libunwind stack unwinder (instead of GCC's unwinder).
+.Pp
+It is a default setting on
+arm64/aarch64.
.It Va WITHOUT_LOCALES
.\" from FreeBSD: head/tools/build/options/WITHOUT_LOCALES 156932 2006-03-21 07:50:50Z ru
Set to not build localization files; see
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index 24893fb..63012fd 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -344,6 +344,7 @@ adrian -> loos
adrian -> monthadar
adrian -> ray
adrian -> rmh
+adrian -> sephe
ae -> melifaro
@@ -404,6 +405,7 @@ das -> rodrigc
delphij -> gabor
delphij -> rafan
+delphij -> sephe
des -> anholt
des -> hmp
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 47a67e0..678c31e 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -231,9 +231,9 @@ __DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC
# In-tree binutils/gcc are older versions without modern architecture support.
.if ${__T} == "aarch64" || ${__T} == "riscv64"
BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB
-__DEFAULT_YES_OPTIONS+=ELFCOPY_AS_OBJCOPY
+__DEFAULT_YES_OPTIONS+=ELFCOPY_AS_OBJCOPY LLVM_LIBUNWIND
.else
-__DEFAULT_NO_OPTIONS+=ELFCOPY_AS_OBJCOPY
+__DEFAULT_NO_OPTIONS+=ELFCOPY_AS_OBJCOPY LLVM_LIBUNWIND
.endif
.if ${__T} == "riscv64"
BROKEN_OPTIONS+=PROFILE # "sorry, unimplemented: profiler support for RISC-V"
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index c6520f3..ca07adc 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -80,6 +80,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 776f90c..620a461 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -322,6 +322,13 @@ trap(struct trapframe *frame)
break;
case T_PAGEFLT: /* page fault */
+ /*
+ * Emulator can take care about this trap?
+ */
+ if (*p->p_sysent->sv_trap != NULL &&
+ (*p->p_sysent->sv_trap)(td) == 0)
+ goto userout;
+
addr = frame->tf_addr;
i = trap_pfault(frame, TRUE);
if (i == -1)
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index 96428b8..d49ca79 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -129,6 +129,7 @@ static void linux_set_syscall_retval(struct thread *td, int error);
static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
static void linux_exec_setregs(struct thread *td, struct image_params *imgp,
u_long stack);
+static int linux_vsyscall(struct thread *td);
/*
* Linux syscalls return negative errno's, we do positive and map them
@@ -746,6 +747,53 @@ exec_linux_imgact_try(struct image_params *imgp)
return(error);
}
+#define LINUX_VSYSCALL_START (-10UL << 20)
+#define LINUX_VSYSCALL_SZ 1024
+
+const unsigned long linux_vsyscall_vector[] = {
+ LINUX_SYS_gettimeofday,
+ LINUX_SYS_linux_time,
+ /* getcpu not implemented */
+};
+
+static int
+linux_vsyscall(struct thread *td)
+{
+ struct trapframe *frame;
+ uint64_t retqaddr;
+ int code, traced;
+ int error;
+
+ frame = td->td_frame;
+
+ /* Check %rip for vsyscall area */
+ if (__predict_true(frame->tf_rip < LINUX_VSYSCALL_START))
+ return (EINVAL);
+ if ((frame->tf_rip & (LINUX_VSYSCALL_SZ - 1)) != 0)
+ return (EINVAL);
+ code = (frame->tf_rip - LINUX_VSYSCALL_START) / LINUX_VSYSCALL_SZ;
+ if (code >= nitems(linux_vsyscall_vector))
+ return (EINVAL);
+
+ /*
+ * vsyscall called as callq *(%rax), so we must
+ * use return address from %rsp and also fixup %rsp
+ */
+ error = copyin((void *)frame->tf_rsp, &retqaddr, sizeof(retqaddr));
+ if (error)
+ return (error);
+
+ frame->tf_rip = retqaddr;
+ frame->tf_rax = linux_vsyscall_vector[code];
+ frame->tf_rsp += 8;
+
+ traced = (frame->tf_flags & PSL_T);
+
+ amd64_syscall(td, traced);
+
+ return (0);
+}
+
struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
@@ -778,7 +826,8 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
- .sv_thread_detach = linux_thread_detach
+ .sv_thread_detach = linux_thread_detach,
+ .sv_trap = linux_vsyscall,
};
static void
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index 693f003..7d3615e 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -1040,6 +1040,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
.sv_thread_detach = linux_thread_detach,
+ .sv_trap = NULL,
};
static void
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 02f7128..84b87f7 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -86,6 +86,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c
index 9ba2541..fb2c163 100644
--- a/sys/arm64/arm64/elf_machdep.c
+++ b/sys/arm64/arm64/elf_machdep.c
@@ -87,6 +87,8 @@ static struct sysentvec elf64_freebsd_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c
index c02010f..d0ca57a 100644
--- a/sys/boot/common/ufsread.c
+++ b/sys/boot/common/ufsread.c
@@ -211,7 +211,6 @@ fsread(ufs_ino_t inode, void *buf, size_t nbyte)
break;
}
if (sblock_try[n] == -1) {
- printf("Not ufs\n");
return -1;
}
dsk_meta++;
diff --git a/sys/boot/efi/boot1/Makefile b/sys/boot/efi/boot1/Makefile
index 3642314..6ac63ee 100644
--- a/sys/boot/efi/boot1/Makefile
+++ b/sys/boot/efi/boot1/Makefile
@@ -41,14 +41,13 @@ CFLAGS+= -fPIC
LDFLAGS+= -Wl,-znocombreloc
.endif
-.if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "i386"
#
# Add libstand for the runtime functions used by the compiler - for example
# __aeabi_* (arm) or __divdi3 (i386).
+# as well as required string and memory functions for all platforms.
#
DPADD+= ${LIBSTAND}
LDADD+= -lstand
-.endif
DPADD+= ${LDSCRIPT}
diff --git a/sys/boot/efi/boot1/boot1.c b/sys/boot/efi/boot1/boot1.c
index e2e4c90..b759267 100644
--- a/sys/boot/efi/boot1/boot1.c
+++ b/sys/boot/efi/boot1/boot1.c
@@ -24,6 +24,7 @@ __FBSDID("$FreeBSD$");
#include <sys/dirent.h>
#include <machine/elf.h>
#include <machine/stdarg.h>
+#include <stand.h>
#include <efi.h>
#include <eficonsctl.h>
@@ -33,28 +34,8 @@ __FBSDID("$FreeBSD$");
#define BSIZEMAX 16384
-typedef int putc_func_t(char c, void *arg);
-
-struct sp_data {
- char *sp_buf;
- u_int sp_len;
- u_int sp_size;
-};
-
-static const char digits[] = "0123456789abcdef";
-
-static void panic(const char *fmt, ...) __dead2;
-static int printf(const char *fmt, ...);
-static int putchar(char c, void *arg);
-static int vprintf(const char *fmt, va_list ap);
-static int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
-
-static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap);
-static int __putc(char c, void *arg);
-static int __puts(const char *s, putc_func_t *putc, void *arg);
-static int __sputc(char c, void *arg);
-static char *__uitoa(char *buf, u_int val, int base);
-static char *__ultoa(char *buf, u_long val, int base);
+void panic(const char *fmt, ...) __dead2;
+void putchar(int c);
static int domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet);
static void load(const char *fname);
@@ -62,39 +43,6 @@ static void load(const char *fname);
static EFI_SYSTEM_TABLE *systab;
static EFI_HANDLE *image;
-static void
-bcopy(const void *src, void *dst, size_t len)
-{
- const char *s = src;
- char *d = dst;
-
- while (len-- != 0)
- *d++ = *s++;
-}
-
-static void
-memcpy(void *dst, const void *src, size_t len)
-{
- bcopy(src, dst, len);
-}
-
-static void
-bzero(void *b, size_t len)
-{
- char *p = b;
-
- while (len-- != 0)
- *p++ = 0;
-}
-
-static int
-strcmp(const char *s1, const char *s2)
-{
- for (; *s1 == *s2 && *s1; s1++, s2++)
- ;
- return ((u_char)*s1 - (u_char)*s2);
-}
-
static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
@@ -250,7 +198,6 @@ fsstat(ufs_ino_t inode)
break;
}
if (sblock_try[n] == -1) {
- printf("Not ufs\n");
return -1;
}
dsk_meta++;
@@ -346,38 +293,22 @@ load(const char *fname)
EFI_ERROR_CODE(status));
}
-static void
+void
panic(const char *fmt, ...)
{
- char buf[128];
va_list ap;
+ printf("panic: ");
va_start(ap, fmt);
- vsnprintf(buf, sizeof buf, fmt, ap);
- printf("panic: %s\n", buf);
+ vprintf(fmt, ap);
va_end(ap);
+ printf("\n");
while (1) {}
}
-static int
-printf(const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- /* Don't annoy the user as we probe for partitions */
- if (strcmp(fmt,"Not ufs\n") == 0)
- return 0;
-
- va_start(ap, fmt);
- ret = vprintf(fmt, ap);
- va_end(ap);
- return (ret);
-}
-
-static int
-putchar(char c, void *arg)
+void
+putchar(int c)
{
CHAR16 buf[2];
@@ -389,187 +320,4 @@ putchar(char c, void *arg)
buf[0] = c;
buf[1] = 0;
systab->ConOut->OutputString(systab->ConOut, buf);
- return (1);
-}
-
-static int
-vprintf(const char *fmt, va_list ap)
-{
- int ret;
-
- ret = __printf(fmt, putchar, 0, ap);
- return (ret);
-}
-
-static int
-vsnprintf(char *str, size_t sz, const char *fmt, va_list ap)
-{
- struct sp_data sp;
- int ret;
-
- sp.sp_buf = str;
- sp.sp_len = 0;
- sp.sp_size = sz;
- ret = __printf(fmt, __sputc, &sp, ap);
- return (ret);
-}
-
-static int
-__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap)
-{
- char buf[(sizeof(long) * 8) + 1];
- char *nbuf;
- u_long ul;
- u_int ui;
- int lflag;
- int sflag;
- char *s;
- int pad;
- int ret;
- int c;
-
- nbuf = &buf[sizeof buf - 1];
- ret = 0;
- while ((c = *fmt++) != 0) {
- if (c != '%') {
- ret += putc(c, arg);
- continue;
- }
- lflag = 0;
- sflag = 0;
- pad = 0;
-reswitch: c = *fmt++;
- switch (c) {
- case '#':
- sflag = 1;
- goto reswitch;
- case '%':
- ret += putc('%', arg);
- break;
- case 'c':
- c = va_arg(ap, int);
- ret += putc(c, arg);
- break;
- case 'd':
- if (lflag == 0) {
- ui = (u_int)va_arg(ap, int);
- if (ui < (int)ui) {
- ui = -ui;
- ret += putc('-', arg);
- }
- s = __uitoa(nbuf, ui, 10);
- } else {
- ul = (u_long)va_arg(ap, long);
- if (ul < (long)ul) {
- ul = -ul;
- ret += putc('-', arg);
- }
- s = __ultoa(nbuf, ul, 10);
- }
- ret += __puts(s, putc, arg);
- break;
- case 'l':
- lflag = 1;
- goto reswitch;
- case 'o':
- if (lflag == 0) {
- ui = (u_int)va_arg(ap, u_int);
- s = __uitoa(nbuf, ui, 8);
- } else {
- ul = (u_long)va_arg(ap, u_long);
- s = __ultoa(nbuf, ul, 8);
- }
- ret += __puts(s, putc, arg);
- break;
- case 'p':
- ul = (u_long)va_arg(ap, void *);
- s = __ultoa(nbuf, ul, 16);
- ret += __puts("0x", putc, arg);
- ret += __puts(s, putc, arg);
- break;
- case 's':
- s = va_arg(ap, char *);
- ret += __puts(s, putc, arg);
- break;
- case 'u':
- if (lflag == 0) {
- ui = va_arg(ap, u_int);
- s = __uitoa(nbuf, ui, 10);
- } else {
- ul = va_arg(ap, u_long);
- s = __ultoa(nbuf, ul, 10);
- }
- ret += __puts(s, putc, arg);
- break;
- case 'x':
- if (lflag == 0) {
- ui = va_arg(ap, u_int);
- s = __uitoa(nbuf, ui, 16);
- } else {
- ul = va_arg(ap, u_long);
- s = __ultoa(nbuf, ul, 16);
- }
- if (sflag)
- ret += __puts("0x", putc, arg);
- ret += __puts(s, putc, arg);
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- pad = pad * 10 + c - '0';
- goto reswitch;
- default:
- break;
- }
- }
- return (ret);
-}
-
-static int
-__sputc(char c, void *arg)
-{
- struct sp_data *sp;
-
- sp = arg;
- if (sp->sp_len < sp->sp_size)
- sp->sp_buf[sp->sp_len++] = c;
- sp->sp_buf[sp->sp_len] = '\0';
- return (1);
-}
-
-static int
-__puts(const char *s, putc_func_t *putc, void *arg)
-{
- const char *p;
- int ret;
-
- ret = 0;
- for (p = s; *p != '\0'; p++)
- ret += putc(*p, arg);
- return (ret);
-}
-
-static char *
-__uitoa(char *buf, u_int ui, int base)
-{
- char *p;
-
- p = buf;
- *p = '\0';
- do
- *--p = digits[ui % base];
- while ((ui /= base) != 0);
- return (p);
-}
-
-static char *
-__ultoa(char *buf, u_long ul, int base)
-{
- char *p;
-
- p = buf;
- *p = '\0';
- do
- *--p = digits[ul % base];
- while ((ul /= base) != 0);
- return (p);
}
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c
index 73f3507..644747e 100644
--- a/sys/boot/i386/loader/main.c
+++ b/sys/boot/i386/loader/main.c
@@ -296,7 +296,8 @@ extract_currdev(void)
}
#ifdef LOADER_ZFS_SUPPORT
- init_zfs_bootenv(zfs_fmtdev(&new_currdev));
+ if (new_currdev.d_type == DEVT_ZFS)
+ init_zfs_bootenv(zfs_fmtdev(&new_currdev));
#endif
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
@@ -311,9 +312,14 @@ init_zfs_bootenv(char *currdev)
{
char *beroot;
+ if (strlen(currdev) == 0)
+ return;
+ if(strncmp(currdev, "zfs:", 4) != 0)
+ return;
/* Remove the trailing : */
currdev[strlen(currdev) - 1] = '\0';
setenv("zfs_be_active", currdev, 1);
+ setenv("zfs_be_currpage", "1", 1);
/* Do not overwrite if already set */
setenv("vfs.root.mountfrom", currdev, 0);
/* Forward past zfs: */
@@ -323,9 +329,7 @@ init_zfs_bootenv(char *currdev)
beroot = strrchr(currdev, '/');
if (beroot != NULL)
beroot[0] = '\0';
-
beroot = currdev;
-
setenv("zfs_be_root", beroot, 1);
}
#endif
@@ -394,6 +398,7 @@ static int
command_reloadbe(int argc, char *argv[])
{
int err;
+ char *root;
if (argc > 2) {
command_errmsg = "wrong number of arguments";
@@ -403,6 +408,11 @@ command_reloadbe(int argc, char *argv[])
if (argc == 2) {
err = zfs_bootenv(argv[1]);
} else {
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ /* There does not appear to be a ZFS pool here, exit without error */
+ return (CMD_OK);
+ }
err = zfs_bootenv(getenv("zfs_be_root"));
}
diff --git a/sys/boot/powerpc/boot1.chrp/boot1.c b/sys/boot/powerpc/boot1.chrp/boot1.c
index 30e695b..af22488 100644
--- a/sys/boot/powerpc/boot1.chrp/boot1.c
+++ b/sys/boot/powerpc/boot1.chrp/boot1.c
@@ -564,10 +564,6 @@ printf(const char *fmt, ...)
va_list ap;
int ret;
- /* Don't annoy the user as we probe for partitions */
- if (strcmp(fmt,"Not ufs\n") == 0)
- return 0;
-
va_start(ap, fmt);
ret = vprintf(fmt, ap);
va_end(ap);
diff --git a/sys/boot/userboot/libstand/Makefile b/sys/boot/userboot/libstand/Makefile
index 401bbdac..d8a1100 100644
--- a/sys/boot/userboot/libstand/Makefile
+++ b/sys/boot/userboot/libstand/Makefile
@@ -1,136 +1,12 @@
# $FreeBSD$
-# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $
-#
-# Notes:
-# - We don't use the libc strerror/sys_errlist because the string table is
-# quite large.
-#
-MAN=
-
-.include <bsd.own.mk>
-MK_SSP= no
+.include <src.opts.mk>
LIBSTAND_SRC= ${.CURDIR}/../../../../lib/libstand
-LIBC_SRC= ${LIBSTAND_SRC}/../libc
-.PATH: ${LIBSTAND_SRC}
-LIB= stand
INTERNALLIB=
-MK_PROFILE= no
-NO_PIC=
-
-WARNS?= 0
-
-# standalone components and stuff we have modified locally
-SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c gets.c \
- globals.c pager.c printf.c strdup.c strerror.c strtol.c strtoul.c random.c \
- sbrk.c twiddle.c zalloc.c zalloc_malloc.c
-
-# private (pruned) versions of libc string functions
-SRCS+= strcasecmp.c
-
-.PATH: ${LIBC_SRC}/net
-
-SRCS+= ntoh.c
-
-# string functions from libc
-.PATH: ${LIBC_SRC}/string
-.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "powerpc" || \
- ${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "amd64" || \
- ${MACHINE_CPUARCH} == "arm"
-SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
- memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \
- strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
- strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
-.endif
-.if ${MACHINE_CPUARCH} == "arm"
-.PATH: ${LIBC_SRC}/arm/gen
-SRCS+= divsi3.S
-.endif
-.if ${MACHINE_CPUARCH} == "powerpc"
-.PATH: ${LIBC_SRC}/quad
-SRCS+= ashldi3.c ashrdi3.c
-.PATH: ${LIBC_SRC}/powerpc/gen
-SRCS+= syncicache.c
-.endif
-
-# uuid functions from libc
-.PATH: ${LIBC_SRC}/uuid
-SRCS+= uuid_equal.c uuid_is_nil.c
-
-# _setjmp/_longjmp
-.if ${MACHINE_CPUARCH} == "amd64"
-.PATH: ${LIBSTAND_SRC}/amd64
-.elif ${MACHINE_ARCH} == "powerpc64"
-.PATH: ${LIBSTAND_SRC}/powerpc
-.else
-.PATH: ${LIBSTAND_SRC}/${MACHINE_CPUARCH}
-.endif
-SRCS+= _setjmp.S
-
-# decompression functionality from libbz2
-# NOTE: to actually test this functionality after libbz2 upgrade compile
-# loader(8) with LOADER_BZIP2_SUPPORT defined
-.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2
-CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS
-SRCS+= libstand_bzlib_private.h
-
-.for file in bzlib.c crctable.c decompress.c huffman.c randtable.c
-SRCS+= _${file}
-CLEANFILES+= _${file}
-
-_${file}: ${file}
- sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \
- ${.ALLSRC} > ${.TARGET}
-.endfor
-
-CLEANFILES+= libstand_bzlib_private.h
-libstand_bzlib_private.h: bzlib_private.h
- sed -e 's|<stdlib.h>|"stand.h"|' \
- ${.ALLSRC} > ${.TARGET}
-
-# decompression functionality from libz
-.PATH: ${LIBSTAND_SRC}/../libz
-CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../libz
-SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
-
-.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
-SRCS+= _${file}
-CLEANFILES+= _${file}
-
-_${file}: ${file}
- sed -e "s|zutil\.h|libstand_zutil.h|" \
- -e "s|gzguts\.h|libstand_gzguts.h|" \
- ${.ALLSRC} > ${.TARGET}
-.endfor
-
-# depend on stand.h being able to be included multiple times
-.for file in zutil.h gzguts.h
-CLEANFILES+= libstand_${file}
-libstand_${file}: ${file}
- sed -e 's|<fcntl.h>|"stand.h"|' \
- -e 's|<stddef.h>|"stand.h"|' \
- -e 's|<string.h>|"stand.h"|' \
- -e 's|<stdio.h>|"stand.h"|' \
- -e 's|<stdlib.h>|"stand.h"|' \
- ${.ALLSRC} > ${.TARGET}
-.endfor
-
-# io routines
-SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
- fstat.c close.c lseek.c open.c read.c write.c readdir.c
-
-# network routines
-SRCS+= arp.c ether.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c
-
-# network info services:
-SRCS+= bootp.c rarp.c bootparam.c
-
-# boot filesystems
-SRCS+= ufs.c nfs.c cd9660.c tftp.c gzipfs.c bzipfs.c
-SRCS+= dosfs.c ext2fs.c
-SRCS+= splitfs.c
+INCS=
+MAN=
+.PATH: ${LIBSTAND_SRC}
-.include <bsd.stand.mk>
-.include <bsd.lib.mk>
+.include "${LIBSTAND_SRC}/Makefile"
diff --git a/sys/boot/userboot/libstand/Makefile.depend b/sys/boot/userboot/libstand/Makefile.depend
index dae5bcd..57cd80c 100644
--- a/sys/boot/userboot/libstand/Makefile.depend
+++ b/sys/boot/userboot/libstand/Makefile.depend
@@ -6,7 +6,6 @@ DIRDEPS = \
include/arpa \
include/xlocale \
lib/libbz2 \
- lib/libstand \
.include <dirdeps.mk>
diff --git a/sys/boot/userboot/userboot/main.c b/sys/boot/userboot/userboot/main.c
index 335c8fd..a52550c 100644
--- a/sys/boot/userboot/userboot/main.c
+++ b/sys/boot/userboot/userboot/main.c
@@ -168,6 +168,7 @@ extract_currdev(void)
zdev.d_type = zdev.d_dev->dv_type;
dev = *(struct disk_devdesc *)&zdev;
+ init_zfs_bootenv(zfs_fmtdev(&dev));
} else
#endif
@@ -191,10 +192,6 @@ extract_currdev(void)
dev.d_unit = 0;
}
-#if defined(USERBOOT_ZFS_SUPPORT)
- init_zfs_bootenv(zfs_fmtdev(&dev));
-#endif
-
env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
userboot_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev),
@@ -207,9 +204,14 @@ init_zfs_bootenv(char *currdev)
{
char *beroot;
+ if (strlen(currdev) == 0)
+ return;
+ if(strncmp(currdev, "zfs:", 4) != 0)
+ return;
/* Remove the trailing : */
currdev[strlen(currdev) - 1] = '\0';
setenv("zfs_be_active", currdev, 1);
+ setenv("zfs_be_currpage", "1", 1);
/* Do not overwrite if already set */
setenv("vfs.root.mountfrom", currdev, 0);
/* Forward past zfs: */
@@ -219,9 +221,7 @@ init_zfs_bootenv(char *currdev)
beroot = strrchr(currdev, '/');
if (beroot != NULL)
beroot[0] = '\0';
-
beroot = currdev;
-
setenv("zfs_be_root", beroot, 1);
}
@@ -273,6 +273,7 @@ static int
command_reloadbe(int argc, char *argv[])
{
int err;
+ char *root;
if (argc > 2) {
command_errmsg = "wrong number of arguments";
@@ -282,7 +283,11 @@ command_reloadbe(int argc, char *argv[])
if (argc == 2) {
err = zfs_bootenv(argv[1]);
} else {
- err = zfs_bootenv(getenv("zfs_be_root"));
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ return (CMD_OK);
+ }
+ err = zfs_bootenv(root);
}
if (err != 0) {
diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c
index fdb79bb..c8b1284 100644
--- a/sys/boot/zfs/zfs.c
+++ b/sys/boot/zfs/zfs.c
@@ -413,7 +413,7 @@ struct zfs_probe_args {
int fd;
const char *devname;
uint64_t *pool_guid;
- uint16_t secsz;
+ u_int secsz;
};
static int
@@ -712,13 +712,18 @@ zfs_list(const char *name)
int
zfs_bootenv(const char *name)
{
- static char poolname[ZFS_MAXNAMELEN], *dsname;
+ static char poolname[ZFS_MAXNAMELEN], *dsname, *root;
char becount[4];
uint64_t objid;
spa_t *spa;
int len, rv, pages, perpage, currpage;
- if (strcmp(name, getenv("zfs_be_root")) != 0) {
+ if (name == NULL)
+ return (EINVAL);
+ if ((root = getenv("zfs_be_root")) == NULL)
+ return (EINVAL);
+
+ if (strcmp(name, root) != 0) {
if (setenv("zfs_be_root", name, 1) != 0)
return (ENOMEM);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index 5491442..5e52759 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -78,6 +78,9 @@ static void
vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
{
vdev_t *vd;
+ spa_t *spa;
+ char *physpath;
+ int error, physpath_len;
vd = cp->private;
if (vd == NULL)
@@ -87,6 +90,47 @@ vdev_geom_attrchanged(struct g_consumer *cp, const char *attr)
vdev_geom_set_rotation_rate(vd, cp);
return;
}
+
+ if (strcmp(attr, "GEOM::physpath") != 0)
+ return;
+
+ if (g_access(cp, 1, 0, 0) != 0)
+ return;
+
+ /*
+ * Record/Update physical path information for this device.
+ */
+ spa = vd->vdev_spa;
+ physpath_len = MAXPATHLEN;
+ physpath = g_malloc(physpath_len, M_WAITOK|M_ZERO);
+ error = g_io_getattr("GEOM::physpath", cp, &physpath_len, physpath);
+ g_access(cp, -1, 0, 0);
+ if (error == 0) {
+ char *old_physpath;
+
+ old_physpath = vd->vdev_physpath;
+ vd->vdev_physpath = spa_strdup(physpath);
+ spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
+
+ if (old_physpath != NULL) {
+ int held_lock;
+
+ held_lock = spa_config_held(spa, SCL_STATE, RW_WRITER);
+ if (held_lock == 0) {
+ g_topology_unlock();
+ spa_config_enter(spa, SCL_STATE, FTAG,
+ RW_WRITER);
+ }
+
+ spa_strfree(old_physpath);
+
+ if (held_lock == 0) {
+ spa_config_exit(spa, SCL_STATE, FTAG);
+ g_topology_lock();
+ }
+ }
+ }
+ g_free(physpath);
}
static void
@@ -97,8 +141,10 @@ vdev_geom_orphan(struct g_consumer *cp)
g_topology_assert();
vd = cp->private;
- if (vd == NULL)
+ if (vd == NULL) {
+ /* Vdev close in progress. Ignore the event. */
return;
+ }
/*
* Orphan callbacks occur from the GEOM event thread.
@@ -120,7 +166,7 @@ vdev_geom_orphan(struct g_consumer *cp)
}
static struct g_consumer *
-vdev_geom_attach(struct g_provider *pp)
+vdev_geom_attach(struct g_provider *pp, vdev_t *vd)
{
struct g_geom *gp;
struct g_consumer *cp;
@@ -139,6 +185,7 @@ vdev_geom_attach(struct g_provider *pp)
if (gp == NULL) {
gp = g_new_geomf(&zfs_vdev_class, "zfs::vdev");
gp->orphan = vdev_geom_orphan;
+ gp->attrchanged = vdev_geom_attrchanged;
cp = g_new_consumer(gp);
if (g_attach(cp, pp) != 0) {
g_wither_geom(gp, ENXIO);
@@ -175,28 +222,56 @@ vdev_geom_attach(struct g_provider *pp)
ZFS_LOG(1, "Used existing consumer for %s.", pp->name);
}
}
+
+ /*
+ * BUG: cp may already belong to a vdev. This could happen if:
+ * 1) That vdev is a shared spare, or
+ * 2) We are trying to reopen a missing vdev and we are scanning by
+ * guid. In that case, we'll ultimately fail to open this consumer,
+ * but not until after setting the private field.
+ * The solution is to:
+ * 1) Don't set the private field until after the open succeeds, and
+ * 2) Set it to a linked list of vdevs, not just a single vdev
+ */
+ cp->private = vd;
+ vd->vdev_tsd = cp;
+
+ /* Fetch initial physical path information for this device. */
+ vdev_geom_attrchanged(cp, "GEOM::physpath");
+
cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
return (cp);
}
static void
-vdev_geom_detach(void *arg, int flag __unused)
+vdev_geom_close_locked(vdev_t *vd)
{
struct g_geom *gp;
struct g_consumer *cp;
g_topology_assert();
- cp = arg;
- gp = cp->geom;
+
+ cp = vd->vdev_tsd;
+ if (cp == NULL)
+ return;
ZFS_LOG(1, "Closing access to %s.", cp->provider->name);
+ KASSERT(vd->vdev_tsd == cp, ("%s: vdev_tsd is not cp", __func__));
+ vd->vdev_tsd = NULL;
+ vd->vdev_delayed_close = B_FALSE;
+ cp->private = NULL;
+
+ gp = cp->geom;
g_access(cp, -1, 0, -1);
/* Destroy consumer on last close. */
if (cp->acr == 0 && cp->ace == 0) {
- ZFS_LOG(1, "Destroyed consumer to %s.", cp->provider->name);
if (cp->acw > 0)
g_access(cp, 0, -cp->acw, 0);
- g_detach(cp);
+ if (cp->provider != NULL) {
+ ZFS_LOG(1, "Destroyed consumer to %s.",
+ cp->provider->name);
+ g_detach(cp);
+ }
g_destroy_consumer(cp);
}
/* Destroy geom if there are no consumers left. */
@@ -490,7 +565,7 @@ vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid)
}
static struct g_consumer *
-vdev_geom_attach_by_guids(uint64_t pool_guid, uint64_t vdev_guid)
+vdev_geom_attach_by_guids(vdev_t *vd)
{
struct g_class *mp;
struct g_geom *gp, *zgp;
@@ -519,9 +594,10 @@ vdev_geom_attach_by_guids(uint64_t pool_guid, uint64_t vdev_guid)
vdev_geom_read_guids(zcp, &pguid, &vguid);
g_topology_lock();
vdev_geom_detach_taster(zcp);
- if (pguid != pool_guid || vguid != vdev_guid)
+ if (pguid != spa_guid(vd->vdev_spa) ||
+ vguid != vd->vdev_guid)
continue;
- cp = vdev_geom_attach(pp);
+ cp = vdev_geom_attach(pp, vd);
if (cp == NULL) {
printf("ZFS WARNING: Unable to "
"attach to %s.\n", pp->name);
@@ -551,7 +627,7 @@ vdev_geom_open_by_guids(vdev_t *vd)
g_topology_assert();
ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid);
- cp = vdev_geom_attach_by_guids(spa_guid(vd->vdev_spa), vd->vdev_guid);
+ cp = vdev_geom_attach_by_guids(vd);
if (cp != NULL) {
len = strlen(cp->provider->name) + strlen("/dev/") + 1;
buf = kmem_alloc(len, KM_SLEEP);
@@ -585,7 +661,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1);
if (pp != NULL) {
ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path);
- cp = vdev_geom_attach(pp);
+ cp = vdev_geom_attach(pp, vd);
if (cp != NULL && check_guid && ISP2(pp->sectorsize) &&
pp->sectorsize <= VDEV_PAD_SIZE) {
g_topology_unlock();
@@ -593,7 +669,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
g_topology_lock();
if (pguid != spa_guid(vd->vdev_spa) ||
vguid != vd->vdev_guid) {
- vdev_geom_detach(cp, 0);
+ vdev_geom_close_locked(vd);
cp = NULL;
ZFS_LOG(1, "guid mismatch for provider %s: "
"%ju:%ju != %ju:%ju.", vd->vdev_path,
@@ -675,7 +751,8 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
!ISP2(cp->provider->sectorsize)) {
ZFS_LOG(1, "Provider %s has unsupported sectorsize.",
vd->vdev_path);
- vdev_geom_detach(cp, 0);
+
+ vdev_geom_close_locked(vd);
error = EINVAL;
cp = NULL;
} else if (cp->acw == 0 && (spa_mode(vd->vdev_spa) & FWRITE) != 0) {
@@ -692,19 +769,17 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
if (error != 0) {
printf("ZFS WARNING: Unable to open %s for writing (error=%d).\n",
vd->vdev_path, error);
- vdev_geom_detach(cp, 0);
+ vdev_geom_close_locked(vd);
cp = NULL;
}
}
+
g_topology_unlock();
PICKUP_GIANT();
if (cp == NULL) {
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
return (error);
}
-
- cp->private = vd;
- vd->vdev_tsd = cp;
pp = cp->provider;
/*
@@ -727,12 +802,6 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
*/
vd->vdev_nowritecache = B_FALSE;
- if (vd->vdev_physpath != NULL)
- spa_strfree(vd->vdev_physpath);
- bufsize = sizeof("/dev/") + strlen(pp->name);
- vd->vdev_physpath = kmem_alloc(bufsize, KM_SLEEP);
- snprintf(vd->vdev_physpath, bufsize, "/dev/%s", pp->name);
-
/*
* Determine the device's rotation rate.
*/
@@ -744,15 +813,12 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
static void
vdev_geom_close(vdev_t *vd)
{
- struct g_consumer *cp;
- cp = vd->vdev_tsd;
- if (cp == NULL)
- return;
- vd->vdev_tsd = NULL;
- vd->vdev_delayed_close = B_FALSE;
- cp->private = NULL; /* XXX locking */
- g_post_event(vdev_geom_detach, cp, M_WAITOK, NULL);
+ DROP_GIANT();
+ g_topology_lock();
+ vdev_geom_close_locked(vd);
+ g_topology_unlock();
+ PICKUP_GIANT();
}
static void
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index 1a6dd72..f201570 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -134,6 +134,7 @@ struct sysentvec ia32_freebsd_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec);
diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index e2aad79..db8ab2c 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -1099,8 +1099,12 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args
ESRCH);
return (ESRCH);
}
- if (SV_PROC_ABI(td2->td_proc) != SV_ABI_LINUX)
+ if (SV_PROC_ABI(td2->td_proc) != SV_ABI_LINUX) {
+ LIN_SDT_PROBE1(futex, linux_get_robust_list, return,
+ EPERM);
+ PROC_UNLOCK(td2->td_proc);
return (EPERM);
+ }
em = em_find(td2);
KASSERT(em != NULL, ("get_robust_list: emuldata notfound.\n"));
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index f37d8cb..c9ceca7 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -194,6 +194,7 @@ struct sysentvec svr4_sysvec = {
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
const char svr4_emul_path[] = "/compat/svr4";
diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
index a5d3f44..30ec46c 100644
--- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -50,6 +50,7 @@ static const char rcsid[] = "@(#)$Id$";
# include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
+#include <netinet/in_fib.h>
#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@@ -712,17 +713,16 @@ ipf_fastroute(m0, mpp, fin, fdp)
{
register struct ip *ip, *mhip;
register struct mbuf *m = *mpp;
- register struct route *ro;
int len, off, error = 0, hlen, code;
struct ifnet *ifp, *sifp;
- struct sockaddr_in *dst;
- struct route iproute;
+ struct sockaddr_in dst;
+ struct nhop4_extended nh4;
+ int has_nhop = 0;
+ u_long fibnum = 0;
u_short ip_off;
frdest_t node;
frentry_t *fr;
- ro = NULL;
-
#ifdef M_WRITABLE
/*
* HOT FIX/KLUDGE:
@@ -766,11 +766,10 @@ ipf_fastroute(m0, mpp, fin, fdp)
/*
* Route packet.
*/
- ro = &iproute;
- bzero(ro, sizeof (*ro));
- dst = (struct sockaddr_in *)&ro->ro_dst;
- dst->sin_family = AF_INET;
- dst->sin_addr = ip->ip_dst;
+ bzero(&dst, sizeof (dst));
+ dst.sin_family = AF_INET;
+ dst.sin_addr = ip->ip_dst;
+ dst.sin_len = sizeof(dst);
fr = fin->fin_fr;
if ((fr != NULL) && !(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) &&
@@ -790,25 +789,22 @@ ipf_fastroute(m0, mpp, fin, fdp)
}
if ((fdp != NULL) && (fdp->fd_ip.s_addr != 0))
- dst->sin_addr = fdp->fd_ip;
-
- dst->sin_len = sizeof(*dst);
- in_rtalloc(ro, M_GETFIB(m0));
+ dst.sin_addr = fdp->fd_ip;
- if ((ifp == NULL) && (ro->ro_rt != NULL))
- ifp = ro->ro_rt->rt_ifp;
-
- if ((ro->ro_rt == NULL) || (ifp == NULL)) {
+ fibnum = M_GETFIB(m0);
+ if (fib4_lookup_nh_ext(fibnum, dst.sin_addr, NHR_REF, 0, &nh4) != 0) {
if (in_localaddr(ip->ip_dst))
error = EHOSTUNREACH;
else
error = ENETUNREACH;
goto bad;
}
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
- if (ro->ro_rt)
- counter_u64_add(ro->ro_rt->rt_pksent, 1);
+
+ has_nhop = 1;
+ if (ifp == NULL)
+ ifp = nh4.nh_ifp;
+ if (nh4.nh_flags & NHF_GATEWAY)
+ dst.sin_addr = nh4.nh_addr;
/*
* For input packets which are being "fastrouted", they won't
@@ -852,8 +848,8 @@ ipf_fastroute(m0, mpp, fin, fdp)
if (ntohs(ip->ip_len) <= ifp->if_mtu) {
if (!ip->ip_sum)
ip->ip_sum = in_cksum(m, hlen);
- error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
- ro
+ error = (*ifp->if_output)(ifp, m, (struct sockaddr *)&dst,
+ NULL
);
goto done;
}
@@ -935,8 +931,8 @@ sendorfree:
m->m_act = 0;
if (error == 0)
error = (*ifp->if_output)(ifp, m,
- (struct sockaddr *)dst,
- ro
+ (struct sockaddr *)&dst,
+ NULL
);
else
FREE_MB_T(m);
@@ -948,9 +944,9 @@ done:
else
ipfmain.ipf_frouteok[1]++;
- if ((ro != NULL) && (ro->ro_rt != NULL)) {
- RTFREE(ro->ro_rt);
- }
+ if (has_nhop)
+ fib4_free_nh_ext(fibnum, &nh4);
+
return 0;
bad:
if (error == EMSGSIZE) {
@@ -971,18 +967,11 @@ int
ipf_verifysrc(fin)
fr_info_t *fin;
{
- struct sockaddr_in *dst;
- struct route iproute;
-
- bzero((char *)&iproute, sizeof(iproute));
- dst = (struct sockaddr_in *)&iproute.ro_dst;
- dst->sin_len = sizeof(*dst);
- dst->sin_family = AF_INET;
- dst->sin_addr = fin->fin_src;
- in_rtalloc(&iproute, 0);
- if (iproute.ro_rt == NULL)
- return 0;
- return (fin->fin_ifp == iproute.ro_rt->rt_ifp);
+ struct nhop4_basic nh4;
+
+ if (fib4_lookup_nh_basic(0, fin->fin_src, 0, 0, &nh4) != 0)
+ return (0);
+ return (fin->fin_ifp == nh4.nh_ifp);
}
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 0d00a77..21d0cb8 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -3642,6 +3642,9 @@ setup_intr_handlers(struct adapter *sc)
#ifdef DEV_NETMAP
struct sge_nm_rxq *nm_rxq;
#endif
+#ifdef RSS
+ int nbuckets = rss_getnumbuckets();
+#endif
/*
* Setup interrupts.
@@ -3700,6 +3703,10 @@ setup_intr_handlers(struct adapter *sc)
t4_intr, rxq, s);
if (rc != 0)
return (rc);
+#ifdef RSS
+ bus_bind_intr(sc->dev, irq->res,
+ rss_getcpu(q % nbuckets));
+#endif
irq++;
rid++;
vi->nintr++;
diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h
index 33a7dd1..e4c714f 100644
--- a/sys/dev/ic/ns16550.h
+++ b/sys/dev/ic/ns16550.h
@@ -205,6 +205,7 @@
* requires ACR[6].
*/
#define com_icr 5 /* index control register (R/W) */
+#define REG_ICR com_icr
/*
* 16950 register #7. It is the same as com_scr except it has a different
@@ -220,6 +221,7 @@
*/
#define com_acr 0 /* additional control register (R/W) */
+#define REG_ACR com_acr
#define ACR_ASE 0x80 /* ASR/RFL/TFL enable */
#define ACR_ICRE 0x40 /* ICR enable */
#define ACR_TLE 0x20 /* TTL/RTL enable */
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
index d792746..a9bdaf7 100644
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -98,6 +98,9 @@ SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags,
static int fail_on_disconnection = 0;
SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_disconnection, CTLFLAG_RWTUN,
&fail_on_disconnection, 0, "Destroy CAM SIM on connection failure");
+static int fail_on_shutdown = 1;
+SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_shutdown, CTLFLAG_RWTUN,
+ &fail_on_shutdown, 0, "Fail disconnected sessions on shutdown");
static MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI initiator");
static uma_zone_t iscsi_outstanding_zone;
@@ -417,8 +420,6 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is)
sc = is->is_softc;
sx_xlock(&sc->sc_lock);
- TAILQ_REMOVE(&sc->sc_sessions, is, is_next);
- sx_xunlock(&sc->sc_lock);
icl_conn_close(is->is_conn);
callout_drain(&is->is_callout);
@@ -450,6 +451,9 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is)
#ifdef ICL_KERNEL_PROXY
cv_destroy(&is->is_login_cv);
#endif
+ TAILQ_REMOVE(&sc->sc_sessions, is, is_next);
+ sx_xunlock(&sc->sc_lock);
+
ISCSI_SESSION_DEBUG(is, "terminated");
free(is, M_ISCSI);
@@ -473,12 +477,7 @@ iscsi_maintenance_thread(void *arg)
STAILQ_EMPTY(&is->is_postponed))
cv_wait(&is->is_maintenance_cv, &is->is_lock);
- if (is->is_reconnecting) {
- ISCSI_SESSION_UNLOCK(is);
- iscsi_maintenance_thread_reconnect(is);
- continue;
- }
-
+ /* Terminate supersedes reconnect. */
if (is->is_terminating) {
ISCSI_SESSION_UNLOCK(is);
iscsi_maintenance_thread_terminate(is);
@@ -486,6 +485,12 @@ iscsi_maintenance_thread(void *arg)
return;
}
+ if (is->is_reconnecting) {
+ ISCSI_SESSION_UNLOCK(is);
+ iscsi_maintenance_thread_reconnect(is);
+ continue;
+ }
+
iscsi_session_send_postponed(is);
ISCSI_SESSION_UNLOCK(is);
}
@@ -605,6 +610,11 @@ iscsi_callout(void *context)
return;
out:
+ if (is->is_terminating) {
+ ISCSI_SESSION_UNLOCK(is);
+ return;
+ }
+
ISCSI_SESSION_UNLOCK(is);
if (reconnect_needed)
@@ -2326,30 +2336,62 @@ iscsi_poll(struct cam_sim *sim)
}
static void
-iscsi_shutdown(struct iscsi_softc *sc)
+iscsi_terminate_sessions(struct iscsi_softc *sc)
{
struct iscsi_session *is;
- /*
- * Trying to reconnect during system shutdown would lead to hang.
- */
- fail_on_disconnection = 1;
+ sx_slock(&sc->sc_lock);
+ TAILQ_FOREACH(is, &sc->sc_sessions, is_next)
+ iscsi_session_terminate(is);
+ while(!TAILQ_EMPTY(&sc->sc_sessions)) {
+ ISCSI_DEBUG("waiting for sessions to terminate");
+ cv_wait(&sc->sc_cv, &sc->sc_lock);
+ }
+ ISCSI_DEBUG("all sessions terminated");
+ sx_sunlock(&sc->sc_lock);
+}
+
+static void
+iscsi_shutdown_pre(struct iscsi_softc *sc)
+{
+ struct iscsi_session *is;
+
+ if (!fail_on_shutdown)
+ return;
/*
* If we have any sessions waiting for reconnection, request
* maintenance thread to fail them immediately instead of waiting
* for reconnect timeout.
+ *
+ * This prevents LUNs with mounted filesystems that are supported
+ * by disconnected iSCSI sessions from hanging, however it will
+ * fail all queued BIOs.
*/
+ ISCSI_DEBUG("forcing failing all disconnected sessions due to shutdown");
+
+ fail_on_disconnection = 1;
+
sx_slock(&sc->sc_lock);
TAILQ_FOREACH(is, &sc->sc_sessions, is_next) {
ISCSI_SESSION_LOCK(is);
- if (is->is_waiting_for_iscsid)
+ if (!is->is_connected) {
+ ISCSI_SESSION_DEBUG(is, "force failing disconnected session early");
iscsi_session_reconnect(is);
+ }
ISCSI_SESSION_UNLOCK(is);
}
sx_sunlock(&sc->sc_lock);
}
+static void
+iscsi_shutdown_post(struct iscsi_softc *sc)
+{
+
+ ISCSI_DEBUG("removing all sessions due to shutdown");
+ iscsi_terminate_sessions(sc);
+}
+
static int
iscsi_load(void)
{
@@ -2372,8 +2414,16 @@ iscsi_load(void)
}
sc->sc_cdev->si_drv1 = sc;
- sc->sc_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
- iscsi_shutdown, sc, SHUTDOWN_PRI_DEFAULT-1);
+ sc->sc_shutdown_pre_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
+ iscsi_shutdown_pre, sc, SHUTDOWN_PRI_FIRST);
+ /*
+ * shutdown_post_sync needs to run after filesystem shutdown and before
+ * CAM shutdown - otherwise when rebooting with an iSCSI session that is
+ * disconnected but has outstanding requests, dashutdown() will hang on
+ * cam_periph_runccb().
+ */
+ sc->sc_shutdown_post_eh = EVENTHANDLER_REGISTER(shutdown_post_sync,
+ iscsi_shutdown_post, sc, SHUTDOWN_PRI_DEFAULT - 1);
return (0);
}
@@ -2381,7 +2431,6 @@ iscsi_load(void)
static int
iscsi_unload(void)
{
- struct iscsi_session *is, *tmp;
if (sc->sc_cdev != NULL) {
ISCSI_DEBUG("removing device node");
@@ -2389,18 +2438,12 @@ iscsi_unload(void)
ISCSI_DEBUG("device node removed");
}
- if (sc->sc_shutdown_eh != NULL)
- EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_eh);
+ if (sc->sc_shutdown_pre_eh != NULL)
+ EVENTHANDLER_DEREGISTER(shutdown_pre_sync, sc->sc_shutdown_pre_eh);
+ if (sc->sc_shutdown_post_eh != NULL)
+ EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->sc_shutdown_post_eh);
- sx_slock(&sc->sc_lock);
- TAILQ_FOREACH_SAFE(is, &sc->sc_sessions, is_next, tmp)
- iscsi_session_terminate(is);
- while(!TAILQ_EMPTY(&sc->sc_sessions)) {
- ISCSI_DEBUG("waiting for sessions to terminate");
- cv_wait(&sc->sc_cv, &sc->sc_lock);
- }
- ISCSI_DEBUG("all sessions terminated");
- sx_sunlock(&sc->sc_lock);
+ iscsi_terminate_sessions(sc);
uma_zdestroy(iscsi_outstanding_zone);
sx_destroy(&sc->sc_lock);
diff --git a/sys/dev/iscsi/iscsi.h b/sys/dev/iscsi/iscsi.h
index fd52fa8..a2475f4 100644
--- a/sys/dev/iscsi/iscsi.h
+++ b/sys/dev/iscsi/iscsi.h
@@ -131,7 +131,8 @@ struct iscsi_softc {
TAILQ_HEAD(, iscsi_session) sc_sessions;
struct cv sc_cv;
unsigned int sc_last_session_id;
- eventhandler_tag sc_shutdown_eh;
+ eventhandler_tag sc_shutdown_pre_eh;
+ eventhandler_tag sc_shutdown_post_eh;
};
#endif /* !ISCSI_H */
diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c
index b953146..d8ca258 100644
--- a/sys/dev/puc/pucdata.c
+++ b/sys/dev/puc/pucdata.c
@@ -42,12 +42,16 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <sys/rman.h>
+#include <dev/ic/ns16550.h>
+
+#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/puc/puc_bus.h>
#include <dev/puc/puc_cfg.h>
#include <dev/puc/puc_bfe.h>
+static puc_config_f puc_config_advantech;
static puc_config_f puc_config_amc;
static puc_config_f puc_config_diva;
static puc_config_f puc_config_exar;
@@ -691,10 +695,25 @@ const struct puc_cfg puc_pci_devices[] = {
.config_function = puc_config_exar_pcie
},
+ /*
+ * The Advantech PCI-1602 Rev. A use the first two ports of an Oxford
+ * Semiconductor OXuPCI954. Note these boards have a hardware bug in
+ * that they drive the RS-422/485 transmitters after power-on until a
+ * driver initalizes the UARTs.
+ */
{ 0x13fe, 0x1600, 0x1602, 0x0002,
- "Advantech PCI-1602",
+ "Advantech PCI-1602 Rev. A",
DEFAULT_RCLK * 8,
PUC_PORT_2S, 0x10, 0, 8,
+ .config_function = puc_config_advantech
+ },
+
+ /* Advantech PCI-1602 Rev. B1/PCI-1603 are also based on OXuPCI952. */
+ { 0x13fe, 0xa102, 0x13fe, 0xa102,
+ "Advantech 2-port PCI (PCI-1602 Rev. B1/PCI-1603)",
+ DEFAULT_RCLK * 8,
+ PUC_PORT_2S, 0x10, 4, 0,
+ .config_function = puc_config_advantech
},
{ 0x1407, 0x0100, 0xffff, 0,
@@ -1256,6 +1275,92 @@ const struct puc_cfg puc_pci_devices[] = {
};
static int
+puc_config_advantech(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
+ intptr_t *res __unused)
+{
+ const struct puc_cfg *cfg;
+ struct resource *cres;
+ struct puc_bar *bar;
+ device_t cdev, dev;
+ bus_size_t off;
+ int base, crtype, fixed, high, i, oxpcie;
+ uint8_t acr, func, mask;
+
+ if (cmd != PUC_CFG_SETUP)
+ return (ENXIO);
+
+ base = fixed = oxpcie = 0;
+ crtype = SYS_RES_IOPORT;
+ acr = mask = 0x0;
+ func = high = 1;
+ off = 0x60;
+
+ cfg = sc->sc_cfg;
+ switch (cfg->subvendor) {
+ case 0x13fe:
+ switch (cfg->device) {
+ case 0xa102:
+ high = 0;
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ if (fixed == 1)
+ goto setup;
+
+ dev = sc->sc_dev;
+ cdev = pci_find_dbsf(pci_get_domain(dev), pci_get_bus(dev),
+ pci_get_slot(dev), func);
+ if (cdev == NULL) {
+ device_printf(dev, "could not find config function\n");
+ return (ENXIO);
+ }
+
+ i = PCIR_BAR(0);
+ cres = bus_alloc_resource_any(cdev, crtype, &i, RF_ACTIVE);
+ if (cres == NULL) {
+ device_printf(dev, "could not allocate config resource\n");
+ return (ENXIO);
+ }
+
+ if (oxpcie == 0) {
+ mask = bus_read_1(cres, off);
+ if (pci_get_function(dev) == 1)
+ base = 4;
+ }
+
+ setup:
+ for (i = 0; i < sc->sc_nports; ++i) {
+ device_printf(dev, "port %d: ", i);
+ bar = puc_get_bar(sc, cfg->rid + i * cfg->d_rid);
+ if (bar == NULL) {
+ printf("could not get BAR\n");
+ continue;
+ }
+
+ if (fixed == 0) {
+ if ((mask & (1 << (base + i))) == 0) {
+ acr = 0;
+ printf("RS-232\n");
+ } else {
+ acr = (high == 1 ? 0x18 : 0x10);
+ printf("RS-422/RS-485, active-%s auto-DTR\n",
+ high == 1 ? "high" : "low");
+ }
+ }
+
+ bus_write_1(bar->b_res, REG_SPR, REG_ACR);
+ bus_write_1(bar->b_res, REG_ICR, acr);
+ }
+
+ bus_release_resource(cdev, crtype, rman_get_rid(cres), cres);
+ return (0);
+}
+
+static int
puc_config_amc(struct puc_softc *sc __unused, enum puc_cfg_cmd cmd, int port,
intptr_t *res)
{
@@ -1360,24 +1465,17 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd,
bar = puc_get_bar(sc, cfg->rid);
if (bar == NULL)
return (ENXIO);
- /* Set DLAB in the LCR register of UART 0. */
- bus_write_1(bar->b_res, 3, 0x80);
- /* Write 0 to the SPR register of UART 0. */
- bus_write_1(bar->b_res, 7, 0);
- /* Read back the contents of the SPR register of UART 0. */
- v0 = bus_read_1(bar->b_res, 7);
- /* Write a specific value to the SPR register of UART 0. */
- bus_write_1(bar->b_res, 7, 0x80 + -cfg->clock);
- /* Read back the contents of the SPR register of UART 0. */
- v1 = bus_read_1(bar->b_res, 7);
- /* Clear DLAB in the LCR register of UART 0. */
- bus_write_1(bar->b_res, 3, 0);
- /* Save the two values read-back from the SPR register. */
+ bus_write_1(bar->b_res, REG_LCR, LCR_DLAB);
+ bus_write_1(bar->b_res, REG_SPR, 0);
+ v0 = bus_read_1(bar->b_res, REG_SPR);
+ bus_write_1(bar->b_res, REG_SPR, 0x80 + -cfg->clock);
+ v1 = bus_read_1(bar->b_res, REG_SPR);
+ bus_write_1(bar->b_res, REG_LCR, 0);
sc->sc_cfg_data = (v0 << 8) | v1;
if (v0 == 0 && v1 == 0x80 + -cfg->clock) {
/*
* The SPR register echoed the two values written
- * by us. This means that the SPAD jumper is set.
+ * by us. This means that the SPAD jumper is set.
*/
device_printf(sc->sc_dev, "warning: extra features "
"not usable -- SPAD compatibility enabled\n");
@@ -1385,7 +1483,7 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd,
}
if (v0 != 0) {
/*
- * The first value doesn't match. This can only mean
+ * The first value doesn't match. This can only mean
* that the SPAD jumper is not set and that a non-
* standard fixed clock multiplier jumper is set.
*/
@@ -1399,8 +1497,8 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd,
return (0);
}
/*
- * The first value matched, but the second didn't. We know
- * that the SPAD jumper is not set. We also know that the
+ * The first value matched, but the second didn't. We know
+ * that the SPAD jumper is not set. We also know that the
* clock rate multiplier is software controlled *and* that
* we just programmed it to the maximum allowed.
*/
@@ -1415,8 +1513,8 @@ puc_config_quatech(struct puc_softc *sc, enum puc_cfg_cmd cmd,
/*
* XXX With the SPAD jumper applied, there's no
* easy way of knowing if there's also a clock
- * rate multiplier jumper installed. Let's hope
- * not...
+ * rate multiplier jumper installed. Let's hope
+ * not ...
*/
*res = DEFAULT_RCLK;
} else if (v0 == 0) {
@@ -1678,15 +1776,15 @@ puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
case PUC_CFG_GET_NPORTS:
/*
* Check if we are being called from puc_bfe_attach()
- * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
- * puc_get_bar(), so we return a value of 16. This has cosmetic
- * side-effects at worst; in PUC_CFG_GET_DESC,
- * (int)sc->sc_cfg_data will not contain the true number of
- * ports in PUC_CFG_GET_DESC, but we are not implementing that
- * call for this device family anyway.
+ * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
+ * puc_get_bar(), so we return a value of 16. This has
+ * cosmetic side-effects at worst; in PUC_CFG_GET_DESC,
+ * sc->sc_cfg_data will not contain the true number of
+ * ports in PUC_CFG_GET_DESC, but we are not implementing
+ * that call for this device family anyway.
*
- * The check is for initialisation of sc->sc_bar[idx], which is
- * only done in puc_bfe_attach().
+ * The check is for initialization of sc->sc_bar[idx],
+ * which is only done in puc_bfe_attach().
*/
idx = 0;
do {
diff --git a/sys/dev/rtwn/if_rtwn.c b/sys/dev/rtwn/if_rtwn.c
index ec17cdc..927a8c8 100644
--- a/sys/dev/rtwn/if_rtwn.c
+++ b/sys/dev/rtwn/if_rtwn.c
@@ -1683,7 +1683,7 @@ rtwn_tx(struct rtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
}
/* Set sequence number (already little endian). */
- txd->txdseq = *(uint16_t *)wh->i_seq;
+ txd->txdseq = htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
if (!qos) {
/* Use HW sequence numbering for non-QoS frames. */
diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h
index 10dc04d..a3980ff 100644
--- a/sys/dev/sfxge/common/efsys.h
+++ b/sys/dev/sfxge/common/efsys.h
@@ -238,6 +238,7 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0
#define EFSYS_OPT_SIENA 1
#define EFSYS_OPT_HUNTINGTON 1
+#define EFSYS_OPT_MEDFORD 0
#ifdef DEBUG
#define EFSYS_OPT_CHECK_REG 1
#else
diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c
index 9b9c4a1..eba7f7b 100644
--- a/sys/dev/ti/if_ti.c
+++ b/sys/dev/ti/if_ti.c
@@ -1634,7 +1634,7 @@ ti_newbuf_jumbo(struct ti_softc *sc, int idx, struct mbuf *m_old)
m[i]->m_data = (void *)sf_buf_kva(sf[i]);
m[i]->m_len = PAGE_SIZE;
MEXTADD(m[i], sf_buf_kva(sf[i]), PAGE_SIZE,
- sf_buf_mext, (void*)sf_buf_kva(sf[i]), sf[i],
+ sf_mext_free, (void*)sf_buf_kva(sf[i]), sf[i],
0, EXT_DISPOSABLE);
m[i]->m_next = m[i+1];
}
@@ -1699,7 +1699,7 @@ nobufs:
if (m[i])
m_freem(m[i]);
if (sf[i])
- sf_buf_mext((void *)sf_buf_kva(sf[i]), sf[i]);
+ sf_mext_free((void *)sf_buf_kva(sf[i]), sf[i]);
}
return (ENOBUFS);
}
diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c
index acad5d4..c3ac185 100644
--- a/sys/dev/vt/hw/ofwfb/ofwfb.c
+++ b/sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -57,6 +57,7 @@ struct ofwfb_softc {
int iso_palette;
};
+static void ofwfb_initialize(struct vt_device *vd);
static vd_probe_t ofwfb_probe;
static vd_init_t ofwfb_init;
static vd_bitblt_text_t ofwfb_bitblt_text;
@@ -124,6 +125,18 @@ ofwfb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
uint8_t c[4];
} ch1, ch2;
+#ifdef __powerpc__
+ /* Deal with unmapped framebuffers */
+ if (sc->fb_flags & FB_FLAG_NOWRITE) {
+ if (pmap_bootstrapped) {
+ sc->fb_flags &= ~FB_FLAG_NOWRITE;
+ ofwfb_initialize(vd);
+ } else {
+ return;
+ }
+ }
+#endif
+
fgc = sc->fb_cmap[fg];
bgc = sc->fb_cmap[bg];
b = m = 0;
@@ -271,6 +284,11 @@ ofwfb_initialize(struct vt_device *vd)
cell_t retval;
uint32_t oldpix;
+ sc->fb.fb_cmsize = 16;
+
+ if (sc->fb.fb_flags & FB_FLAG_NOWRITE)
+ return;
+
/*
* Set up the color map
*/
@@ -318,8 +336,6 @@ ofwfb_initialize(struct vt_device *vd)
panic("Unknown color space depth %d", sc->fb.fb_bpp);
break;
}
-
- sc->fb.fb_cmsize = 16;
}
static int
@@ -466,6 +482,11 @@ ofwfb_init(struct vt_device *vd)
#if defined(__powerpc__)
OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase);
sc->fb.fb_pbase = sc->fb.fb_vbase; /* 1:1 mapped */
+ #ifdef __powerpc64__
+ /* Real mode under a hypervisor probably doesn't cover FB */
+ if (!(mfmsr() & (PSL_HV | PSL_DR)))
+ sc->fb.fb_flags |= FB_FLAG_NOWRITE;
+ #endif
#else
/* No ability to interpret assigned-addresses otherwise */
return (CN_DEAD);
diff --git a/sys/fs/ext2fs/ext2_bmap.c b/sys/fs/ext2fs/ext2_bmap.c
index 7d4a880..8656e59 100644
--- a/sys/fs/ext2fs/ext2_bmap.c
+++ b/sys/fs/ext2fs/ext2_bmap.c
@@ -102,9 +102,6 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb)
fs = ip->i_e2fs;
lbn = bn;
- /*
- * TODO: need to implement read ahead to improve the performance.
- */
if (runp != NULL)
*runp = 0;
@@ -112,15 +109,25 @@ ext4_bmapext(struct vnode *vp, int32_t bn, int64_t *bnp, int *runp, int *runb)
*runb = 0;
ext4_ext_find_extent(fs, ip, lbn, &path);
- ep = path.ep_ext;
- if (ep == NULL)
- ret = EIO;
- else {
- *bnp = fsbtodb(fs, lbn - ep->e_blk +
- (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32));
-
- if (*bnp == 0)
- *bnp = -1;
+ if (path.ep_is_sparse) {
+ *bnp = -1;
+ if (runp != NULL)
+ *runp = path.ep_sparse_ext.e_len -
+ (lbn - path.ep_sparse_ext.e_blk) - 1;
+ } else {
+ ep = path.ep_ext;
+ if (ep == NULL)
+ ret = EIO;
+ else {
+ *bnp = fsbtodb(fs, lbn - ep->e_blk +
+ (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32));
+
+ if (*bnp == 0)
+ *bnp = -1;
+
+ if (runp != NULL)
+ *runp = ep->e_len - (lbn - ep->e_blk) - 1;
+ }
}
if (path.ep_bp != NULL) {
diff --git a/sys/fs/ext2fs/ext2_extents.c b/sys/fs/ext2fs/ext2_extents.c
index 68704bb..1317fdc 100644
--- a/sys/fs/ext2fs/ext2_extents.c
+++ b/sys/fs/ext2fs/ext2_extents.c
@@ -66,13 +66,14 @@ static void
ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn)
{
struct ext4_extent_header *ehp = path->ep_header;
- struct ext4_extent *l, *r, *m;
+ struct ext4_extent *first, *l, *r, *m;
if (ehp->eh_ecount == 0)
return;
- l = (struct ext4_extent *)(char *)(ehp + 1);
- r = (struct ext4_extent *)(char *)(ehp + 1) + ehp->eh_ecount - 1;
+ first = (struct ext4_extent *)(char *)(ehp + 1);
+ l = first;
+ r = first + ehp->eh_ecount - 1;
while (l <= r) {
m = l + (r - l) / 2;
if (lbn < m->e_blk)
@@ -81,7 +82,25 @@ ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn)
l = m + 1;
}
+ if (l == first) {
+ path->ep_sparse_ext.e_blk = lbn;
+ path->ep_sparse_ext.e_len = first->e_blk - lbn;
+ path->ep_sparse_ext.e_start_hi = 0;
+ path->ep_sparse_ext.e_start_lo = 0;
+ path->ep_is_sparse = 1;
+ return;
+ }
path->ep_ext = l - 1;
+ if (path->ep_ext->e_blk + path->ep_ext->e_len <= lbn) {
+ path->ep_sparse_ext.e_blk = lbn;
+ if (l <= (first + ehp->eh_ecount - 1))
+ path->ep_sparse_ext.e_len = l->e_blk - lbn;
+ else // XXX: where does it end?
+ path->ep_sparse_ext.e_len = 1;
+ path->ep_sparse_ext.e_start_hi = 0;
+ path->ep_sparse_ext.e_start_lo = 0;
+ path->ep_is_sparse = 1;
+ }
}
/*
@@ -169,6 +188,7 @@ ext4_ext_find_extent(struct m_ext2fs *fs, struct inode *ip,
path->ep_depth = i;
path->ep_ext = NULL;
path->ep_index = NULL;
+ path->ep_is_sparse = 0;
ext4_ext_binsearch(ip, path, lbn);
return (path);
diff --git a/sys/fs/ext2fs/ext2_extents.h b/sys/fs/ext2fs/ext2_extents.h
index 94ded83..4ce16f3 100644
--- a/sys/fs/ext2fs/ext2_extents.h
+++ b/sys/fs/ext2fs/ext2_extents.h
@@ -84,7 +84,11 @@ struct ext4_extent_cache {
struct ext4_extent_path {
uint16_t ep_depth;
struct buf *ep_bp;
- struct ext4_extent *ep_ext;
+ int ep_is_sparse;
+ union {
+ struct ext4_extent ep_sparse_ext;
+ struct ext4_extent *ep_ext;
+ };
struct ext4_extent_index *ep_index;
struct ext4_extent_header *ep_header;
};
diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c
index ce943ea..5339aa2 100644
--- a/sys/fs/ext2fs/ext2_vfsops.c
+++ b/sys/fs/ext2fs/ext2_vfsops.c
@@ -590,7 +590,7 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp)
* while Linux keeps the super block in a locked buffer.
*/
ump->um_e2fs = malloc(sizeof(struct m_ext2fs),
- M_EXT2MNT, M_WAITOK);
+ M_EXT2MNT, M_WAITOK | M_ZERO);
ump->um_e2fs->e2fs = malloc(sizeof(struct ext2fs),
M_EXT2MNT, M_WAITOK);
mtx_init(EXT2_MTX(ump), "EXT2FS", "EXT2FS Lock", MTX_DEF);
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index 5b8990ee..bc239b8 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -1787,6 +1787,7 @@ ext2_ioctl(struct vop_ioctl_args *ap)
static int
ext4_ext_read(struct vop_read_args *ap)
{
+ static unsigned char zeroes[EXT2_MAX_BLOCK_SIZE];
struct vnode *vp;
struct inode *ip;
struct uio *uio;
@@ -1831,11 +1832,15 @@ ext4_ext_read(struct vop_read_args *ap)
switch (cache_type) {
case EXT4_EXT_CACHE_NO:
ext4_ext_find_extent(fs, ip, lbn, &path);
- ep = path.ep_ext;
+ if (path.ep_is_sparse)
+ ep = &path.ep_sparse_ext;
+ else
+ ep = path.ep_ext;
if (ep == NULL)
return (EIO);
- ext4_ext_put_cache(ip, ep, EXT4_EXT_CACHE_IN);
+ ext4_ext_put_cache(ip, ep,
+ path.ep_is_sparse ? EXT4_EXT_CACHE_GAP : EXT4_EXT_CACHE_IN);
newblk = lbn - ep->e_blk + (ep->e_start_lo |
(daddr_t)ep->e_start_hi << 32);
@@ -1848,7 +1853,7 @@ ext4_ext_read(struct vop_read_args *ap)
case EXT4_EXT_CACHE_GAP:
/* block has not been allocated yet */
- return (0);
+ break;
case EXT4_EXT_CACHE_IN:
newblk = lbn - nex.e_blk + (nex.e_start_lo |
@@ -1859,24 +1864,34 @@ ext4_ext_read(struct vop_read_args *ap)
panic("%s: invalid cache type", __func__);
}
- error = bread(ip->i_devvp, fsbtodb(fs, newblk), size, NOCRED, &bp);
- if (error) {
- brelse(bp);
- return (error);
- }
+ if (cache_type == EXT4_EXT_CACHE_GAP ||
+ (cache_type == EXT4_EXT_CACHE_NO && path.ep_is_sparse)) {
+ if (xfersize > sizeof(zeroes))
+ xfersize = sizeof(zeroes);
+ error = uiomove(zeroes, xfersize, uio);
+ if (error)
+ return (error);
+ } else {
+ error = bread(ip->i_devvp, fsbtodb(fs, newblk), size,
+ NOCRED, &bp);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
- size -= bp->b_resid;
- if (size < xfersize) {
- if (size == 0) {
- bqrelse(bp);
- break;
+ size -= bp->b_resid;
+ if (size < xfersize) {
+ if (size == 0) {
+ bqrelse(bp);
+ break;
+ }
+ xfersize = size;
}
- xfersize = size;
+ error = uiomove(bp->b_data + blkoffset, xfersize, uio);
+ bqrelse(bp);
+ if (error)
+ return (error);
}
- error = uiomove(bp->b_data + blkoffset, (int)xfersize, uio);
- bqrelse(bp);
- if (error)
- return (error);
}
return (0);
diff --git a/sys/fs/smbfs/smbfs_smb.c b/sys/fs/smbfs/smbfs_smb.c
index ada84c2..c5b8a68 100644
--- a/sys/fs/smbfs/smbfs_smb.c
+++ b/sys/fs/smbfs/smbfs_smb.c
@@ -333,18 +333,18 @@ smbfs_smb_flush(struct smbnode *np, struct smb_cred *scred)
}
int
-smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
+smbfs_smb_setfsize(struct smbnode *np, int64_t newsize, struct smb_cred *scred)
{
struct smb_share *ssp = np->n_mount->sm_share;
struct smb_rq *rqp;
struct mbchain *mbp;
int error;
- if (!smbfs_smb_seteof(np, (int64_t) newsize, scred)) {
+ if (!smbfs_smb_seteof(np, newsize, scred)) {
np->n_flag |= NFLUSHWIRE;
return (0);
}
-
+ /* XXX: We should use SMB_COM_WRITE_ANDX to support large offsets */
error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_WRITE, scred, &rqp);
if (error)
return (error);
@@ -352,7 +352,7 @@ smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred)
smb_rq_wstart(rqp);
mb_put_mem(mbp, (caddr_t)&np->n_fid, 2, MB_MSYSTEM);
mb_put_uint16le(mbp, 0);
- mb_put_uint32le(mbp, newsize);
+ mb_put_uint32le(mbp, (uint32_t)newsize);
mb_put_uint16le(mbp, 0);
smb_rq_wend(rqp);
smb_rq_bstart(rqp);
diff --git a/sys/fs/smbfs/smbfs_subr.h b/sys/fs/smbfs/smbfs_subr.h
index d22df08..4ee143c 100644
--- a/sys/fs/smbfs/smbfs_subr.h
+++ b/sys/fs/smbfs/smbfs_subr.h
@@ -128,7 +128,8 @@ int smbfs_smb_lock(struct smbnode *np, int op, caddr_t id,
off_t start, off_t end, struct smb_cred *scred);
int smbfs_smb_statfs(struct smb_share *ssp, struct statfs *sbp,
struct smb_cred *scred);
-int smbfs_smb_setfsize(struct smbnode *np, int newsize, struct smb_cred *scred);
+int smbfs_smb_setfsize(struct smbnode *np, int64_t newsize,
+ struct smb_cred *scred);
int smbfs_smb_query_info(struct smbnode *np, const char *name, int len,
struct smbfattr *fap, struct smb_cred *scred);
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 8ea1198..c78ceb2 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -358,7 +358,8 @@ smbfs_setattr(ap)
doclose = 1;
}
if (error == 0)
- error = smbfs_smb_setfsize(np, vap->va_size, scred);
+ error = smbfs_smb_setfsize(np,
+ (int64_t)vap->va_size, scred);
if (doclose)
smbfs_smb_close(ssp, np->n_fid, NULL, scred);
if (error) {
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index b11cb03..3c76ab2 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -87,6 +87,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c
index 16507ee..372e5ea 100644
--- a/sys/i386/ibcs2/ibcs2_sysvec.c
+++ b/sys/i386/ibcs2/ibcs2_sysvec.c
@@ -90,6 +90,7 @@ struct sysentvec ibcs2_svr3_sysvec = {
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
static int
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 2a8b7d2..cc5fcaa 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -985,6 +985,7 @@ struct sysentvec linux_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
.sv_thread_detach = linux_thread_detach,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
@@ -1021,6 +1022,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
.sv_thread_detach = linux_thread_detach,
+ .sv_trap = NULL,
};
static void
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index a7db17e..cbde46b 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -97,6 +97,7 @@ struct sysentvec aout_sysvec = {
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
#elif defined(__amd64__)
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index f0cd3c8..8d5580b 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -414,6 +414,7 @@ struct sysentvec null_sysvec = {
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
/*
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index 2700a25..95a6d09 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@@ -47,6 +48,17 @@ __FBSDID("$FreeBSD$");
#endif
/*
+ * A bound below which cv_waiters is valid. Once cv_waiters reaches this bound,
+ * cv_signal must manually check the wait queue for threads.
+ */
+#define CV_WAITERS_BOUND INT_MAX
+
+#define CV_WAITERS_INC(cvp) do { \
+ if ((cvp)->cv_waiters < CV_WAITERS_BOUND) \
+ (cvp)->cv_waiters++; \
+} while (0)
+
+/*
* Common sanity checks for cv_wait* functions.
*/
#define CV_ASSERT(cvp, lock, td) do { \
@@ -122,7 +134,7 @@ _cv_wait(struct cv *cvp, struct lock_object *lock)
sleepq_lock(cvp);
- cvp->cv_waiters++;
+ CV_WAITERS_INC(cvp);
if (lock == &Giant.lock_object)
mtx_assert(&Giant, MA_OWNED);
DROP_GIANT();
@@ -184,7 +196,7 @@ _cv_wait_unlock(struct cv *cvp, struct lock_object *lock)
sleepq_lock(cvp);
- cvp->cv_waiters++;
+ CV_WAITERS_INC(cvp);
DROP_GIANT();
sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0);
@@ -240,7 +252,7 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock)
sleepq_lock(cvp);
- cvp->cv_waiters++;
+ CV_WAITERS_INC(cvp);
if (lock == &Giant.lock_object)
mtx_assert(&Giant, MA_OWNED);
DROP_GIANT();
@@ -307,7 +319,7 @@ _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt,
sleepq_lock(cvp);
- cvp->cv_waiters++;
+ CV_WAITERS_INC(cvp);
if (lock == &Giant.lock_object)
mtx_assert(&Giant, MA_OWNED);
DROP_GIANT();
@@ -376,7 +388,7 @@ _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock,
sleepq_lock(cvp);
- cvp->cv_waiters++;
+ CV_WAITERS_INC(cvp);
if (lock == &Giant.lock_object)
mtx_assert(&Giant, MA_OWNED);
DROP_GIANT();
@@ -422,8 +434,15 @@ cv_signal(struct cv *cvp)
wakeup_swapper = 0;
sleepq_lock(cvp);
if (cvp->cv_waiters > 0) {
- cvp->cv_waiters--;
- wakeup_swapper = sleepq_signal(cvp, SLEEPQ_CONDVAR, 0, 0);
+ if (cvp->cv_waiters == CV_WAITERS_BOUND &&
+ sleepq_lookup(cvp) == NULL) {
+ cvp->cv_waiters = 0;
+ } else {
+ if (cvp->cv_waiters < CV_WAITERS_BOUND)
+ cvp->cv_waiters--;
+ wakeup_swapper = sleepq_signal(cvp, SLEEPQ_CONDVAR, 0,
+ 0);
+ }
}
sleepq_release(cvp);
if (wakeup_swapper)
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index de6b313..0b0b697 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -338,6 +338,9 @@ mb_free_ext(struct mbuf *m)
case EXT_SFBUF:
sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2);
break;
+ case EXT_SFBUF_NOCACHE:
+ sf_ext_free_nocache(m->m_ext.ext_arg1, m->m_ext.ext_arg2);
+ break;
default:
KASSERT(m->m_ext.ext_cnt != NULL,
("%s: no refcounting pointer on %p", __func__, m));
@@ -404,6 +407,7 @@ mb_dupcl(struct mbuf *n, const struct mbuf *m)
switch (m->m_ext.ext_type) {
case EXT_SFBUF:
+ case EXT_SFBUF_NOCACHE:
sf_ext_ref(m->m_ext.ext_arg1, m->m_ext.ext_arg2);
break;
default:
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 243450d..ba77fca 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -69,6 +69,23 @@ static struct mbuf *sbcut_internal(struct sockbuf *sb, int len);
static void sbflush_internal(struct sockbuf *sb);
/*
+ * Our own version of m_clrprotoflags(), that can preserve M_NOTREADY.
+ */
+static void
+sbm_clrprotoflags(struct mbuf *m, int flags)
+{
+ int mask;
+
+ mask = ~M_PROTOFLAGS;
+ if (flags & PRUS_NOTREADY)
+ mask |= M_NOTREADY;
+ while (m) {
+ m->m_flags &= mask;
+ m = m->m_next;
+ }
+}
+
+/*
* Mark ready "count" mbufs starting with "m".
*/
int
@@ -569,7 +586,7 @@ sblastmbufchk(struct sockbuf *sb, const char *file, int line)
* are discarded and mbufs are compacted where possible.
*/
void
-sbappend_locked(struct sockbuf *sb, struct mbuf *m)
+sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags)
{
struct mbuf *n;
@@ -577,7 +594,7 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
if (m == 0)
return;
- m_clrprotoflags(m);
+ sbm_clrprotoflags(m, flags);
SBLASTRECORDCHK(sb);
n = sb->sb_mb;
if (n) {
@@ -620,11 +637,11 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
* are discarded and mbufs are compacted where possible.
*/
void
-sbappend(struct sockbuf *sb, struct mbuf *m)
+sbappend(struct sockbuf *sb, struct mbuf *m, int flags)
{
SOCKBUF_LOCK(sb);
- sbappend_locked(sb, m);
+ sbappend_locked(sb, m, flags);
SOCKBUF_UNLOCK(sb);
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index c33a2cf..cac698a 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -113,15 +113,6 @@ static int getpeername1(struct thread *td, struct getpeername_args *uap,
counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)];
-/*
- * sendfile(2)-related variables and associated sysctls
- */
-static SYSCTL_NODE(_kern_ipc, OID_AUTO, sendfile, CTLFLAG_RW, 0,
- "sendfile(2) tunables");
-static int sfreadahead = 1;
-SYSCTL_INT(_kern_ipc_sendfile, OID_AUTO, readahead, CTLFLAG_RW,
- &sfreadahead, 0, "Number of sendfile(2) read-ahead MAXBSIZE blocks");
-
static void
sfstat_init(const void *unused)
{
@@ -1858,13 +1849,12 @@ sf_ext_free(void *arg1, void *arg2)
sf_buf_free(sf);
vm_page_lock(pg);
- vm_page_unwire(pg, PQ_INACTIVE);
/*
* Check for the object going away on us. This can
* happen since we don't hold a reference to it.
* If so, we're responsible for freeing the page.
*/
- if (pg->wire_count == 0 && pg->object == NULL)
+ if (vm_page_unwire(pg, PQ_INACTIVE) && pg->object == NULL)
vm_page_free(pg);
vm_page_unlock(pg);
@@ -1878,6 +1868,43 @@ sf_ext_free(void *arg1, void *arg2)
}
/*
+ * Same as above, but forces the page to be detached from the object
+ * and go into free pool.
+ */
+void
+sf_ext_free_nocache(void *arg1, void *arg2)
+{
+ struct sf_buf *sf = arg1;
+ struct sendfile_sync *sfs = arg2;
+ vm_page_t pg = sf_buf_page(sf);
+
+ sf_buf_free(sf);
+
+ vm_page_lock(pg);
+ if (vm_page_unwire(pg, PQ_NONE)) {
+ vm_object_t obj;
+
+ /* Try to free the page, but only if it is cheap to. */
+ if ((obj = pg->object) == NULL)
+ vm_page_free(pg);
+ else if (!vm_page_xbusied(pg) && VM_OBJECT_TRYWLOCK(obj)) {
+ vm_page_free(pg);
+ VM_OBJECT_WUNLOCK(obj);
+ } else
+ vm_page_deactivate(pg);
+ }
+ vm_page_unlock(pg);
+
+ if (sfs != NULL) {
+ mtx_lock(&sfs->mtx);
+ KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0"));
+ if (--sfs->count == 0)
+ cv_signal(&sfs->cv);
+ mtx_unlock(&sfs->mtx);
+ }
+}
+
+/*
* sendfile(2)
*
* int sendfile(int fd, int s, off_t offset, size_t nbytes,
@@ -1974,103 +2001,252 @@ freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap)
}
#endif /* COMPAT_FREEBSD4 */
+ /*
+ * How much data to put into page i of n.
+ * Only first and last pages are special.
+ */
+static inline off_t
+xfsize(int i, int n, off_t off, off_t len)
+{
+
+ if (i == 0)
+ return (omin(PAGE_SIZE - (off & PAGE_MASK), len));
+
+ if (i == n - 1 && ((off + len) & PAGE_MASK) > 0)
+ return ((off + len) & PAGE_MASK);
+
+ return (PAGE_SIZE);
+}
+
+/*
+ * Offset within object for i page.
+ */
+static inline vm_offset_t
+vmoff(int i, off_t off)
+{
+
+ if (i == 0)
+ return ((vm_offset_t)off);
+
+ return (trunc_page(off + i * PAGE_SIZE));
+}
+
+/*
+ * Pretend as if we don't have enough space, subtract xfsize() of
+ * all pages that failed.
+ */
+static inline void
+fixspace(int old, int new, off_t off, int *space)
+{
+
+ KASSERT(old > new, ("%s: old %d new %d", __func__, old, new));
+
+ /* Subtract last one. */
+ *space -= xfsize(old - 1, old, off, *space);
+ old--;
+
+ if (new == old)
+ /* There was only one page. */
+ return;
+
+ /* Subtract first one. */
+ if (new == 0) {
+ *space -= xfsize(0, old, off, *space);
+ new++;
+ }
+
+ /* Rest of pages are full sized. */
+ *space -= (old - new) * PAGE_SIZE;
+
+ KASSERT(*space >= 0, ("%s: space went backwards", __func__));
+}
+
+/*
+ * Structure describing a single sendfile(2) I/O, which may consist of
+ * several underlying pager I/Os.
+ *
+ * The syscall context allocates the structure and initializes 'nios'
+ * to 1. As sendfile_swapin() runs through pages and starts asynchronous
+ * paging operations, it increments 'nios'.
+ *
+ * Every I/O completion calls sf_iodone(), which decrements the 'nios', and
+ * the syscall also calls sf_iodone() after allocating all mbufs, linking them
+ * and sending to socket. Whoever reaches zero 'nios' is responsible to
+ * call pru_ready on the socket, to notify it of readyness of the data.
+ */
+struct sf_io {
+ volatile u_int nios;
+ u_int error;
+ int npages;
+ struct file *sock_fp;
+ struct mbuf *m;
+ vm_page_t pa[];
+};
+
+static void
+sf_iodone(void *arg, vm_page_t *pg, int count, int error)
+{
+ struct sf_io *sfio = arg;
+ struct socket *so;
+
+ for (int i = 0; i < count; i++)
+ vm_page_xunbusy(pg[i]);
+
+ if (error)
+ sfio->error = error;
+
+ if (!refcount_release(&sfio->nios))
+ return;
+
+ so = sfio->sock_fp->f_data;
+
+ if (sfio->error) {
+ struct mbuf *m;
+
+ /*
+ * I/O operation failed. The state of data in the socket
+ * is now inconsistent, and all what we can do is to tear
+ * it down. Protocol abort method would tear down protocol
+ * state, free all ready mbufs and detach not ready ones.
+ * We will free the mbufs corresponding to this I/O manually.
+ *
+ * The socket would be marked with EIO and made available
+ * for read, so that application receives EIO on next
+ * syscall and eventually closes the socket.
+ */
+ so->so_proto->pr_usrreqs->pru_abort(so);
+ so->so_error = EIO;
+
+ m = sfio->m;
+ for (int i = 0; i < sfio->npages; i++)
+ m = m_free(m);
+ } else {
+ CURVNET_SET(so->so_vnet);
+ (void )(so->so_proto->pr_usrreqs->pru_ready)(so, sfio->m,
+ sfio->npages);
+ CURVNET_RESTORE();
+ }
+
+ /* XXXGL: curthread */
+ fdrop(sfio->sock_fp, curthread);
+ free(sfio, M_TEMP);
+}
+
+/*
+ * Iterate through pages vector and request paging for non-valid pages.
+ */
static int
-sendfile_readpage(vm_object_t obj, struct vnode *vp, int nd,
- off_t off, int xfsize, int bsize, struct thread *td, vm_page_t *res)
+sendfile_swapin(vm_object_t obj, struct sf_io *sfio, off_t off, off_t len,
+ int npages, int rhpages, int flags)
{
- vm_page_t m;
- vm_pindex_t pindex;
- ssize_t resid;
- int error, readahead, rv;
+ vm_page_t *pa = sfio->pa;
+ int nios;
- pindex = OFF_TO_IDX(off);
- VM_OBJECT_WLOCK(obj);
- m = vm_page_grab(obj, pindex, (vp != NULL ? VM_ALLOC_NOBUSY |
- VM_ALLOC_IGN_SBUSY : 0) | VM_ALLOC_WIRED | VM_ALLOC_NORMAL);
+ nios = 0;
+ flags = (flags & SF_NODISKIO) ? VM_ALLOC_NOWAIT : 0;
/*
- * Check if page is valid for what we need, otherwise initiate I/O.
- *
- * The non-zero nd argument prevents disk I/O, instead we
- * return the caller what he specified in nd. In particular,
- * if we already turned some pages into mbufs, nd == EAGAIN
- * and the main function send them the pages before we come
- * here again and block.
+ * First grab all the pages and wire them. Note that we grab
+ * only required pages. Readahead pages are dealt with later.
*/
- if (m->valid != 0 && vm_page_is_valid(m, off & PAGE_MASK, xfsize)) {
- if (vp == NULL)
- vm_page_xunbusy(m);
- VM_OBJECT_WUNLOCK(obj);
- *res = m;
- return (0);
- } else if (nd != 0) {
- if (vp == NULL)
- vm_page_xunbusy(m);
- error = nd;
- goto free_page;
+ VM_OBJECT_WLOCK(obj);
+ for (int i = 0; i < npages; i++) {
+ pa[i] = vm_page_grab(obj, OFF_TO_IDX(vmoff(i, off)),
+ VM_ALLOC_WIRED | VM_ALLOC_NORMAL | flags);
+ if (pa[i] == NULL) {
+ npages = i;
+ rhpages = 0;
+ break;
+ }
}
- /*
- * Get the page from backing store.
- */
- error = 0;
- if (vp != NULL) {
- VM_OBJECT_WUNLOCK(obj);
- readahead = sfreadahead * MAXBSIZE;
+ for (int i = 0; i < npages;) {
+ int j, a, count, rv;
+
+ /* Skip valid pages. */
+ if (vm_page_is_valid(pa[i], vmoff(i, off) & PAGE_MASK,
+ xfsize(i, npages, off, len))) {
+ vm_page_xunbusy(pa[i]);
+ SFSTAT_INC(sf_pages_valid);
+ i++;
+ continue;
+ }
/*
- * Use vn_rdwr() instead of the pager interface for
- * the vnode, to allow the read-ahead.
- *
- * XXXMAC: Because we don't have fp->f_cred here, we
- * pass in NOCRED. This is probably wrong, but is
- * consistent with our original implementation.
+ * Now 'i' points to first invalid page, iterate further
+ * to make 'j' point at first valid after a bunch of
+ * invalid ones.
*/
- error = vn_rdwr(UIO_READ, vp, NULL, readahead, trunc_page(off),
- UIO_NOCOPY, IO_NODELOCKED | IO_VMIO | ((readahead /
- bsize) << IO_SEQSHIFT), td->td_ucred, NOCRED, &resid, td);
- SFSTAT_INC(sf_iocnt);
- VM_OBJECT_WLOCK(obj);
- } else {
- if (vm_pager_has_page(obj, pindex, NULL, NULL)) {
- rv = vm_pager_get_pages(obj, &m, 1, NULL, NULL);
- SFSTAT_INC(sf_iocnt);
- if (rv != VM_PAGER_OK) {
- vm_page_lock(m);
- vm_page_free(m);
- vm_page_unlock(m);
- m = NULL;
- error = EIO;
+ for (j = i + 1; j < npages; j++)
+ if (vm_page_is_valid(pa[j], vmoff(j, off) & PAGE_MASK,
+ xfsize(j, npages, off, len))) {
+ SFSTAT_INC(sf_pages_valid);
+ break;
}
- } else {
- pmap_zero_page(m);
- m->valid = VM_PAGE_BITS_ALL;
- m->dirty = 0;
+
+ /*
+ * Now we got region of invalid pages between 'i' and 'j'.
+ * Check that they belong to pager. They may not be there,
+ * which is a regular situation for shmem pager. For vnode
+ * pager this happens only in case of sparse file.
+ *
+ * Important feature of vm_pager_has_page() is the hint
+ * stored in 'a', about how many pages we can pagein after
+ * this page in a single I/O.
+ */
+ while (!vm_pager_has_page(obj, OFF_TO_IDX(vmoff(i, off)),
+ NULL, &a) && i < j) {
+ pmap_zero_page(pa[i]);
+ pa[i]->valid = VM_PAGE_BITS_ALL;
+ pa[i]->dirty = 0;
+ vm_page_xunbusy(pa[i]);
+ i++;
}
- if (m != NULL)
- vm_page_xunbusy(m);
- }
- if (error == 0) {
- *res = m;
- } else if (m != NULL) {
-free_page:
- vm_page_lock(m);
- vm_page_unwire(m, PQ_INACTIVE);
+ if (i == j)
+ continue;
/*
- * See if anyone else might know about this page. If
- * not and it is not valid, then free it.
+ * We want to pagein as many pages as possible, limited only
+ * by the 'a' hint and actual request.
+ *
+ * We should not pagein into already valid page, thus if
+ * 'j' didn't reach last page, trim by that page.
+ *
+ * When the pagein fulfils the request, also specify readahead.
*/
- if (m->wire_count == 0 && m->valid == 0 && !vm_page_busied(m))
- vm_page_free(m);
- vm_page_unlock(m);
- }
- KASSERT(error != 0 || (m->wire_count > 0 &&
- vm_page_is_valid(m, off & PAGE_MASK, xfsize)),
- ("wrong page state m %p off %#jx xfsize %d", m, (uintmax_t)off,
- xfsize));
+ if (j < npages)
+ a = min(a, j - i - 1);
+ count = min(a + 1, npages - i);
+
+ refcount_acquire(&sfio->nios);
+ rv = vm_pager_get_pages_async(obj, pa + i, count, NULL,
+ i + count == npages ? &rhpages : NULL,
+ &sf_iodone, sfio);
+ KASSERT(rv == VM_PAGER_OK, ("%s: pager fail obj %p page %p",
+ __func__, obj, pa[i]));
+
+ SFSTAT_INC(sf_iocnt);
+ SFSTAT_ADD(sf_pages_read, count);
+ if (i + count == npages)
+ SFSTAT_ADD(sf_rhpages_read, rhpages);
+
+#ifdef INVARIANTS
+ for (j = i; j < i + count && j < npages; j++)
+ KASSERT(pa[j] == vm_page_lookup(obj,
+ OFF_TO_IDX(vmoff(j, off))),
+ ("pa[j] %p lookup %p\n", pa[j],
+ vm_page_lookup(obj, OFF_TO_IDX(vmoff(j, off)))));
+#endif
+ i += count;
+ nios++;
+ }
+
VM_OBJECT_WUNLOCK(obj);
- return (error);
+
+ if (nios == 0 && npages != 0)
+ SFSTAT_INC(sf_noiocnt);
+
+ return (nios);
}
static int
@@ -2178,42 +2354,37 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
struct vnode *vp;
struct vm_object *obj;
struct socket *so;
- struct mbuf *m;
+ struct mbuf *m, *mh, *mhtail;
struct sf_buf *sf;
- struct vm_page *pg;
struct shmfd *shmfd;
struct sendfile_sync *sfs;
struct vattr va;
- off_t off, xfsize, fsbytes, sbytes, rem, obj_size;
- int error, bsize, nd, hdrlen, mnw;
+ off_t off, sbytes, rem, obj_size;
+ int error, softerr, bsize, hdrlen;
- pg = NULL;
obj = NULL;
so = NULL;
- m = NULL;
+ m = mh = NULL;
sfs = NULL;
- fsbytes = sbytes = 0;
- hdrlen = mnw = 0;
- rem = nbytes;
- obj_size = 0;
+ sbytes = 0;
+ softerr = 0;
error = sendfile_getobj(td, fp, &obj, &vp, &shmfd, &obj_size, &bsize);
if (error != 0)
return (error);
- if (rem == 0)
- rem = obj_size;
error = kern_sendfile_getsock(td, sockfd, &sock_fp, &so);
if (error != 0)
goto out;
- /*
- * Do not wait on memory allocations but return ENOMEM for
- * caller to retry later.
- * XXX: Experimental.
- */
- if (flags & SF_MNOWAIT)
- mnw = 1;
+#ifdef MAC
+ error = mac_socket_check_send(td->td_ucred, so);
+ if (error != 0)
+ goto out;
+#endif
+
+ SFSTAT_INC(sf_syscalls);
+ SFSTAT_ADD(sf_rhpages_requested, SF_READAHEAD(flags));
if (flags & SF_SYNC) {
sfs = malloc(sizeof *sfs, M_TEMP, M_WAITOK | M_ZERO);
@@ -2221,37 +2392,27 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
cv_init(&sfs->cv, "sendfile");
}
-#ifdef MAC
- error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
- goto out;
-#endif
-
/* If headers are specified copy them into mbufs. */
- if (hdr_uio != NULL) {
+ if (hdr_uio != NULL && hdr_uio->uio_resid > 0) {
hdr_uio->uio_td = td;
hdr_uio->uio_rw = UIO_WRITE;
- if (hdr_uio->uio_resid > 0) {
- /*
- * In FBSD < 5.0 the nbytes to send also included
- * the header. If compat is specified subtract the
- * header size from nbytes.
- */
- if (kflags & SFK_COMPAT) {
- if (nbytes > hdr_uio->uio_resid)
- nbytes -= hdr_uio->uio_resid;
- else
- nbytes = 0;
- }
- m = m_uiotombuf(hdr_uio, (mnw ? M_NOWAIT : M_WAITOK),
- 0, 0, 0);
- if (m == NULL) {
- error = mnw ? EAGAIN : ENOBUFS;
- goto out;
- }
- hdrlen = m_length(m, NULL);
+ /*
+ * In FBSD < 5.0 the nbytes to send also included
+ * the header. If compat is specified subtract the
+ * header size from nbytes.
+ */
+ if (kflags & SFK_COMPAT) {
+ if (nbytes > hdr_uio->uio_resid)
+ nbytes -= hdr_uio->uio_resid;
+ else
+ nbytes = 0;
}
- }
+ mh = m_uiotombuf(hdr_uio, M_WAITOK, 0, 0, 0);
+ hdrlen = m_length(mh, &mhtail);
+ } else
+ hdrlen = 0;
+
+ rem = nbytes ? omin(nbytes, obj_size - offset) : obj_size - offset;
/*
* Protect against multiple writers to the socket.
@@ -2272,21 +2433,13 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
* The outer loop checks the state and available space of the socket
* and takes care of the overall progress.
*/
- for (off = offset; ; ) {
+ for (off = offset; rem > 0; ) {
+ struct sf_io *sfio;
+ vm_page_t *pa;
struct mbuf *mtail;
- int loopbytes;
- int space;
- int done;
-
- if ((nbytes != 0 && nbytes == fsbytes) ||
- (nbytes == 0 && obj_size == fsbytes))
- break;
+ int nios, space, npages, rhpages;
mtail = NULL;
- loopbytes = 0;
- space = 0;
- done = 0;
-
/*
* Check the socket state for ongoing connection,
* no errors and space in socket buffer.
@@ -2362,49 +2515,58 @@ retry_space:
VOP_UNLOCK(vp, 0);
goto done;
}
- obj_size = va.va_size;
+ if (va.va_size != obj_size) {
+ if (nbytes == 0)
+ rem += va.va_size - obj_size;
+ else if (offset + nbytes > va.va_size)
+ rem -= (offset + nbytes - va.va_size);
+ obj_size = va.va_size;
+ }
}
+ if (space > rem)
+ space = rem;
+
+ npages = howmany(space + (off & PAGE_MASK), PAGE_SIZE);
+
+ /*
+ * Calculate maximum allowed number of pages for readahead
+ * at this iteration. First, we allow readahead up to "rem".
+ * If application wants more, let it be, but there is no
+ * reason to go above MAXPHYS. Also check against "obj_size",
+ * since vm_pager_has_page() can hint beyond EOF.
+ */
+ rhpages = howmany(rem + (off & PAGE_MASK), PAGE_SIZE) - npages;
+ rhpages += SF_READAHEAD(flags);
+ rhpages = min(howmany(MAXPHYS, PAGE_SIZE), rhpages);
+ rhpages = min(howmany(obj_size - trunc_page(off), PAGE_SIZE) -
+ npages, rhpages);
+
+ sfio = malloc(sizeof(struct sf_io) +
+ npages * sizeof(vm_page_t), M_TEMP, M_WAITOK);
+ refcount_init(&sfio->nios, 1);
+ sfio->error = 0;
+
+ nios = sendfile_swapin(obj, sfio, off, space, npages, rhpages,
+ flags);
+
/*
* Loop and construct maximum sized mbuf chain to be bulk
* dumped into socket buffer.
*/
- while (space > loopbytes) {
- vm_offset_t pgoff;
+ pa = sfio->pa;
+ for (int i = 0; i < npages; i++) {
struct mbuf *m0;
/*
- * Calculate the amount to transfer.
- * Not to exceed a page, the EOF,
- * or the passed in nbytes.
+ * If a page wasn't grabbed successfully, then
+ * trim the array. Can happen only with SF_NODISKIO.
*/
- pgoff = (vm_offset_t)(off & PAGE_MASK);
- rem = obj_size - offset;
- if (nbytes != 0)
- rem = omin(rem, nbytes);
- rem -= fsbytes + loopbytes;
- xfsize = omin(PAGE_SIZE - pgoff, rem);
- xfsize = omin(space - loopbytes, xfsize);
- if (xfsize <= 0) {
- done = 1; /* all data sent */
- break;
- }
-
- /*
- * Attempt to look up the page. Allocate
- * if not found or wait and loop if busy.
- */
- if (m != NULL)
- nd = EAGAIN; /* send what we already got */
- else if ((flags & SF_NODISKIO) != 0)
- nd = EBUSY;
- else
- nd = 0;
- error = sendfile_readpage(obj, vp, nd, off,
- xfsize, bsize, td, &pg);
- if (error != 0) {
- if (error == EAGAIN)
- error = 0; /* not a real error */
+ if (pa[i] == NULL) {
+ SFSTAT_INC(sf_busy);
+ fixspace(npages, i, off, &space);
+ npages = i;
+ softerr = EBUSY;
break;
}
@@ -2417,56 +2579,59 @@ retry_space:
* threads might exhaust the buffers and then
* deadlock.
*/
- sf = sf_buf_alloc(pg, (mnw || m != NULL) ? SFB_NOWAIT :
- SFB_CATCH);
+ sf = sf_buf_alloc(pa[i],
+ m != NULL ? SFB_NOWAIT : SFB_CATCH);
if (sf == NULL) {
SFSTAT_INC(sf_allocfail);
- vm_page_lock(pg);
- vm_page_unwire(pg, PQ_INACTIVE);
- KASSERT(pg->object != NULL,
- ("%s: object disappeared", __func__));
- vm_page_unlock(pg);
+ for (int j = i; j < npages; j++) {
+ vm_page_lock(pa[j]);
+ vm_page_unwire(pa[j], PQ_INACTIVE);
+ vm_page_unlock(pa[j]);
+ }
if (m == NULL)
- error = (mnw ? EAGAIN : EINTR);
+ softerr = ENOBUFS;
+ fixspace(npages, i, off, &space);
+ npages = i;
break;
}
- /*
- * Get an mbuf and set it up as having
- * external storage.
- */
- m0 = m_get((mnw ? M_NOWAIT : M_WAITOK), MT_DATA);
- if (m0 == NULL) {
- error = (mnw ? EAGAIN : ENOBUFS);
- sf_ext_free(sf, NULL);
- break;
- }
- /*
- * Attach EXT_SFBUF external storage.
- */
- m0->m_ext.ext_buf = (caddr_t )sf_buf_kva(sf);
+ m0 = m_get(M_WAITOK, MT_DATA);
+ m0->m_ext.ext_buf = (char *)sf_buf_kva(sf);
m0->m_ext.ext_size = PAGE_SIZE;
m0->m_ext.ext_arg1 = sf;
m0->m_ext.ext_arg2 = sfs;
- m0->m_ext.ext_type = EXT_SFBUF;
+ /*
+ * SF_NOCACHE sets the page as being freed upon send.
+ * However, we ignore it for the last page in 'space',
+ * if the page is truncated, and we got more data to
+ * send (rem > space), or if we have readahead
+ * configured (rhpages > 0).
+ */
+ if ((flags & SF_NOCACHE) == 0 ||
+ (i == npages - 1 &&
+ ((off + space) & PAGE_MASK) &&
+ (rem > space || rhpages > 0)))
+ m0->m_ext.ext_type = EXT_SFBUF;
+ else
+ m0->m_ext.ext_type = EXT_SFBUF_NOCACHE;
m0->m_ext.ext_flags = 0;
- m0->m_flags |= (M_EXT|M_RDONLY);
- m0->m_data = (char *)sf_buf_kva(sf) + pgoff;
- m0->m_len = xfsize;
+ m0->m_flags |= (M_EXT | M_RDONLY);
+ if (nios)
+ m0->m_flags |= M_NOTREADY;
+ m0->m_data = (char *)sf_buf_kva(sf) +
+ (vmoff(i, off) & PAGE_MASK);
+ m0->m_len = xfsize(i, npages, off, space);
+
+ if (i == 0)
+ sfio->m = m0;
/* Append to mbuf chain. */
if (mtail != NULL)
mtail->m_next = m0;
- else if (m != NULL)
- m_last(m)->m_next = m0;
else
m = m0;
mtail = m0;
- /* Keep track of bits processed. */
- loopbytes += xfsize;
- off += xfsize;
-
if (sfs != NULL) {
mtx_lock(&sfs->mtx);
sfs->count++;
@@ -2477,49 +2642,60 @@ retry_space:
if (vp != NULL)
VOP_UNLOCK(vp, 0);
+ /* Keep track of bytes processed. */
+ off += space;
+ rem -= space;
+
+ /* Prepend header, if any. */
+ if (hdrlen) {
+ mhtail->m_next = m;
+ m = mh;
+ mh = NULL;
+ }
+
+ if (m == NULL) {
+ KASSERT(softerr, ("%s: m NULL, no error", __func__));
+ error = softerr;
+ free(sfio, M_TEMP);
+ goto done;
+ }
+
/* Add the buffer chain to the socket buffer. */
- if (m != NULL) {
- int mlen, err;
+ KASSERT(m_length(m, NULL) == space + hdrlen,
+ ("%s: mlen %u space %d hdrlen %d",
+ __func__, m_length(m, NULL), space, hdrlen));
- mlen = m_length(m, NULL);
- SOCKBUF_LOCK(&so->so_snd);
- if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
- error = EPIPE;
- SOCKBUF_UNLOCK(&so->so_snd);
- goto done;
- }
- SOCKBUF_UNLOCK(&so->so_snd);
- CURVNET_SET(so->so_vnet);
- /* Avoid error aliasing. */
- err = (*so->so_proto->pr_usrreqs->pru_send)
- (so, 0, m, NULL, NULL, td);
- CURVNET_RESTORE();
- if (err == 0) {
- /*
- * We need two counters to get the
- * file offset and nbytes to send
- * right:
- * - sbytes contains the total amount
- * of bytes sent, including headers.
- * - fsbytes contains the total amount
- * of bytes sent from the file.
- */
- sbytes += mlen;
- fsbytes += mlen;
- if (hdrlen) {
- fsbytes -= hdrlen;
- hdrlen = 0;
- }
- } else if (error == 0)
- error = err;
- m = NULL; /* pru_send always consumes */
+ CURVNET_SET(so->so_vnet);
+ if (nios == 0) {
+ /*
+ * If sendfile_swapin() didn't initiate any I/Os,
+ * which happens if all data is cached in VM, then
+ * we can send data right now without the
+ * PRUS_NOTREADY flag.
+ */
+ free(sfio, M_TEMP);
+ error = (*so->so_proto->pr_usrreqs->pru_send)
+ (so, 0, m, NULL, NULL, td);
+ } else {
+ sfio->sock_fp = sock_fp;
+ sfio->npages = npages;
+ fhold(sock_fp);
+ error = (*so->so_proto->pr_usrreqs->pru_send)
+ (so, PRUS_NOTREADY, m, NULL, NULL, td);
+ sf_iodone(sfio, NULL, 0, 0);
}
+ CURVNET_RESTORE();
- /* Quit outer loop on error or when we're done. */
- if (done)
- break;
- if (error != 0)
+ m = NULL; /* pru_send always consumes */
+ if (error)
goto done;
+ sbytes += space + hdrlen;
+ if (hdrlen)
+ hdrlen = 0;
+ if (softerr) {
+ error = softerr;
+ goto done;
+ }
}
/*
@@ -2552,6 +2728,8 @@ out:
fdrop(sock_fp, td);
if (m)
m_freem(m);
+ if (mh)
+ m_freem(mh);
if (sfs != NULL) {
mtx_lock(&sfs->mtx);
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index efed37b..e455b10 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -981,7 +981,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
control))
control = NULL;
} else
- sbappend_locked(&so2->so_rcv, m);
+ sbappend_locked(&so2->so_rcv, m, flags);
break;
case SOCK_SEQPACKET: {
diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c
index 2b50015..b332bf3 100644
--- a/sys/mips/mips/elf_machdep.c
+++ b/sys/mips/mips/elf_machdep.c
@@ -81,6 +81,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
static Elf64_Brandinfo freebsd_brand_info = {
@@ -135,6 +136,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
static Elf32_Brandinfo freebsd_brand_info = {
diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c
index 7726ecd..f4ace04 100644
--- a/sys/mips/mips/freebsd32_machdep.c
+++ b/sys/mips/mips/freebsd32_machdep.c
@@ -104,6 +104,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_syscallnames = freebsd32_syscallnames,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c
index 4944e97..16adba4 100644
--- a/sys/net/if_arcsubr.c
+++ b/sys/net/if_arcsubr.c
@@ -113,9 +113,8 @@ arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
error = 0;
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 2b82ecc..2d652ad 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -202,7 +202,6 @@ ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
uint32_t *pflags)
{
struct ether_header *eh;
- struct rtentry *rt;
uint32_t lleflags = 0;
int error = 0;
#if defined(INET) || defined(INET6)
@@ -253,8 +252,7 @@ ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
}
if (error == EHOSTDOWN) {
- rt = (ro != NULL) ? ro->ro_rt : NULL;
- if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0)
+ if (ro != NULL && (ro->ro_flags & RT_HAS_GW) != 0)
error = EHOSTUNREACH;
}
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 81b65a63..84ee669 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -119,9 +119,8 @@ fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
getmicrotime(&ifp->if_lastchange);
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c
index 626b1cb..a070f61 100644
--- a/sys/net/if_fwsubr.c
+++ b/sys/net/if_fwsubr.c
@@ -106,9 +106,8 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
}
#if defined(INET) || defined(INET6)
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
/*
* For unicast, we make a tag to store the lladdr of the
@@ -145,10 +144,6 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
* doesn't fit into the arp model.
*/
if (unicast) {
- is_gw = 0;
- if (ro != NULL && ro->ro_rt != NULL &&
- (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c
index 7192998..466784f 100644
--- a/sys/net/if_iso88025subr.c
+++ b/sys/net/if_iso88025subr.c
@@ -214,12 +214,8 @@ iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct rtentry *rt0 = NULL;
int is_gw = 0;
- if (ro != NULL) {
- rt0 = ro->ro_rt;
- if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
- }
-
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error)
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index f4ac8b4..1291f7b 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -202,15 +202,12 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
u_int32_t af;
- struct rtentry *rt = NULL;
#ifdef MAC
int error;
#endif
M_ASSERTPKTHDR(m); /* check if we have the packet header */
- if (ro != NULL)
- rt = ro->ro_rt;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error) {
@@ -219,10 +216,9 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
}
#endif
- if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ if (ro != NULL && ro->ro_flags & (RT_REJECT|RT_BLACKHOLE)) {
m_freem(m);
- return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
- rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ return (ro->ro_flags & RT_BLACKHOLE ? 0 : EHOSTUNREACH);
}
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c
index 82c0add..5657400 100644
--- a/sys/net/radix_mpath.c
+++ b/sys/net/radix_mpath.c
@@ -197,14 +197,49 @@ rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
return (0);
}
-void
-rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+static struct rtentry *
+rt_mpath_selectrte(struct rtentry *rte, uint32_t hash)
{
struct radix_node *rn0, *rn;
u_int32_t n;
struct rtentry *rt;
int64_t weight;
+ /* beyond here, we use rn as the master copy */
+ rn0 = rn = (struct radix_node *)rte;
+ n = rn_mpath_count(rn0);
+
+ /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
+ hash += hashjitter;
+ hash %= n;
+ for (weight = abs((int32_t)hash), rt = rte;
+ weight >= rt->rt_weight && rn;
+ weight -= rt->rt_weight) {
+
+ /* stay within the multipath routes */
+ if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
+ break;
+ rn = rn->rn_dupedkey;
+ rt = (struct rtentry *)rn;
+ }
+
+ return (rt);
+}
+
+struct rtentry *
+rt_mpath_select(struct rtentry *rte, uint32_t hash)
+{
+ if (rn_mpath_next((struct radix_node *)rte) == NULL)
+ return (rte);
+
+ return (rt_mpath_selectrte(rte, hash));
+}
+
+void
+rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+{
+ struct rtentry *rt;
+
/*
* XXX we don't attempt to lookup cached route again; what should
* be done for sendto(3) case?
@@ -222,34 +257,18 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
return;
}
- /* beyond here, we use rn as the master copy */
- rn0 = rn = (struct radix_node *)ro->ro_rt;
- n = rn_mpath_count(rn0);
-
- /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
- hash += hashjitter;
- hash %= n;
- for (weight = abs((int32_t)hash), rt = ro->ro_rt;
- weight >= rt->rt_weight && rn;
- weight -= rt->rt_weight) {
-
- /* stay within the multipath routes */
- if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
- break;
- rn = rn->rn_dupedkey;
- rt = (struct rtentry *)rn;
- }
+ rt = rt_mpath_selectrte(ro->ro_rt, hash);
/* XXX try filling rt_gwroute and avoid unreachable gw */
/* gw selection has failed - there must be only zero weight routes */
- if (!rn) {
+ if (!rt) {
RT_UNLOCK(ro->ro_rt);
ro->ro_rt = NULL;
return;
}
if (ro->ro_rt != rt) {
RTFREE_LOCKED(ro->ro_rt);
- ro->ro_rt = (struct rtentry *)rn;
+ ro->ro_rt = rt;
RT_LOCK(ro->ro_rt);
RT_ADDREF(ro->ro_rt);
diff --git a/sys/net/radix_mpath.h b/sys/net/radix_mpath.h
index bcb210e..fc6f777 100644
--- a/sys/net/radix_mpath.h
+++ b/sys/net/radix_mpath.h
@@ -52,6 +52,7 @@ int rt_mpath_conflict(struct radix_node_head *, struct rtentry *,
struct sockaddr *);
void rtalloc_mpath_fib(struct route *, u_int32_t, u_int);
#define rtalloc_mpath(_route, _hash) rtalloc_mpath_fib((_route), (_hash), 0)
+struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);
struct radix_node *rn_mpath_lookup(void *, void *,
struct radix_node_head *);
int rt_mpath_deldup(struct rtentry *, struct rtentry *);
diff --git a/sys/net/route.c b/sys/net/route.c
index e09cc23..9698dd3 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -568,7 +568,7 @@ rtredirect_fib(struct sockaddr *dst,
struct sockaddr *src,
u_int fibnum)
{
- struct rtentry *rt, *rt0 = NULL;
+ struct rtentry *rt;
int error = 0;
short *stat = NULL;
struct rt_addrinfo info;
@@ -627,7 +627,7 @@ rtredirect_fib(struct sockaddr *dst,
* Create new route, rather than smashing route to net.
*/
create:
- rt0 = rt;
+ RTFREE(rt);
rt = NULL;
flags |= RTF_DYNAMIC;
@@ -637,21 +637,14 @@ rtredirect_fib(struct sockaddr *dst,
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_ifa = ifa;
info.rti_flags = flags;
- if (rt0 != NULL)
- RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
if (rt != NULL) {
RT_LOCK(rt);
- if (rt0 != NULL)
- EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
flags = rt->rt_flags;
}
- if (rt0 != NULL)
- RTFREE(rt0);
stat = &V_rtstat.rts_dynamic;
} else {
- struct rtentry *gwrt;
/*
* Smash the current notion of the gateway to
@@ -669,11 +662,7 @@ rtredirect_fib(struct sockaddr *dst,
RADIX_NODE_HEAD_LOCK(rnh);
RT_LOCK(rt);
rt_setgate(rt, rt_key(rt), gateway);
- gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
RADIX_NODE_HEAD_UNLOCK(rnh);
- EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
- if (gwrt)
- RTFREE_LOCKED(gwrt);
}
} else
error = EHOSTUNREACH;
@@ -858,7 +847,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
src = rt_key(rt);
dst = info->rti_info[RTAX_DST];
sa_len = src->sa_len;
- if (src != NULL && dst != NULL) {
+ if (dst != NULL) {
if (src->sa_len > dst->sa_len)
return (ENOMEM);
memcpy(dst, src, src->sa_len);
diff --git a/sys/net/route.h b/sys/net/route.h
index 7c69e1c..f30a72f 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -64,9 +64,13 @@ struct route {
#define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */
#define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */
-#define RT_L2_ME (1 << RT_L2_ME_BIT)
-#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT)
-#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT)
+#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */
+#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */
+#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */
+
+#define RT_REJECT 0x0020 /* Destination is reject */
+#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */
+#define RT_HAS_GW 0x0080 /* Destination has GW */
struct rt_metrics {
u_long rmx_locks; /* Kernel must leave these values alone */
@@ -215,6 +219,21 @@ fib_rte_to_nh_flags(int rt_flags)
return (res);
}
+#ifdef _KERNEL
+/* rte<>ro_flags translation */
+static inline void
+rt_update_ro_flags(struct route *ro)
+{
+ int rt_flags = ro->ro_rt->rt_flags;
+
+ ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW);
+
+ ro->ro_flags |= (rt_flags & RTF_REJECT) ? RT_REJECT : 0;
+ ro->ro_flags |= (rt_flags & RTF_BLACKHOLE) ? RT_BLACKHOLE : 0;
+ ro->ro_flags |= (rt_flags & RTF_GATEWAY) ? RT_HAS_GW : 0;
+}
+#endif
+
/*
* Routing statistics.
*/
@@ -467,9 +486,6 @@ int rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, uint32_t,
struct rt_addrinfo *);
void rib_free_info(struct rt_addrinfo *info);
-#include <sys/eventhandler.h>
-typedef void (*rtevent_redirect_fn)(void *, struct rtentry *, struct rtentry *, struct sockaddr *);
-EVENTHANDLER_DECLARE(route_redirect_event, rtevent_redirect_fn);
#endif
#endif
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 7f2eae5..0ccf378 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/eventhandler.h>
#include <sys/linker.h>
#include <sys/mbuf.h>
#include <sys/module.h>
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
index f0cd01e..68c5975 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -972,7 +972,7 @@ ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m,
}
/* Put the packet on the socket's send queue and wakeup RFCOMM task */
- sbappend(&pcb->so->so_snd, m);
+ sbappend(&pcb->so->so_snd, m, flags);
m = NULL;
if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) {
@@ -2396,7 +2396,7 @@ ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci,
error = ENOBUFS;
} else {
/* Append packet to the socket receive queue */
- sbappend(&pcb->so->so_rcv, m0);
+ sbappend(&pcb->so->so_rcv, m0, 0);
m0 = NULL;
sorwakeup(pcb->so);
diff --git a/sys/netgraph/netflow/netflow.c b/sys/netgraph/netflow/netflow.c
index 644d46f..87ff189 100644
--- a/sys/netgraph/netflow/netflow.c
+++ b/sys/netgraph/netflow/netflow.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/counter.h>
#include <sys/kernel.h>
+#include <sys/ktr.h>
#include <sys/limits.h>
#include <sys/mbuf.h>
#include <sys/syslog.h>
diff --git a/sys/netgraph/netflow/netflow_v9.c b/sys/netgraph/netflow/netflow_v9.c
index fe85f42..2fc700d 100644
--- a/sys/netgraph/netflow/netflow_v9.c
+++ b/sys/netgraph/netflow/netflow_v9.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/counter.h>
#include <sys/kernel.h>
+#include <sys/ktr.h>
#include <sys/limits.h>
#include <sys/mbuf.h>
#include <sys/syslog.h>
diff --git a/sys/netgraph/netflow/ng_netflow.c b/sys/netgraph/netflow/ng_netflow.c
index b5a82a4..b524ca5 100644
--- a/sys/netgraph/netflow/ng_netflow.c
+++ b/sys/netgraph/netflow/ng_netflow.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/counter.h>
#include <sys/kernel.h>
+#include <sys/ktr.h>
#include <sys/limits.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
diff --git a/sys/netinet/in_fib.c b/sys/netinet/in_fib.c
index 451b3747..352c6d0 100644
--- a/sys/netinet/in_fib.c
+++ b/sys/netinet/in_fib.c
@@ -200,6 +200,13 @@ fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags,
rn = rh->rnh_matchaddr((void *)&sin, rh);
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
rte = RNTORT(rn);
+#ifdef RADIX_MPATH
+ rte = rt_mpath_select(rte, flowid);
+ if (rte == NULL) {
+ RADIX_NODE_HEAD_RUNLOCK(rh);
+ return (ENOENT);
+ }
+#endif
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(rte->rt_ifp)) {
fib4_rte_to_nh_extended(rte, dst, flags, pnh4);
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 9454426..ec42e67 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/callout.h>
+#include <sys/eventhandler.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/rmlock.h>
diff --git a/sys/netinet/ip_encap.c b/sys/netinet/ip_encap.c
index d3d0116..f186fe2 100644
--- a/sys/netinet/ip_encap.c
+++ b/sys/netinet/ip_encap.c
@@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index ffa88ae..9b762d6 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/stddef.h>
+#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/ktr.h>
#include <sys/malloc.h>
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 7ad43a2..fa225fc 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -376,6 +376,7 @@ again:
ia = ifatoia(rte->rt_ifa);
ifp = rte->rt_ifp;
counter_u64_add(rte->rt_pksent, 1);
+ rt_update_ro_flags(ro);
if (rte->rt_flags & RTF_GATEWAY)
gw = (struct sockaddr_in *)rte->rt_gateway;
if (rte->rt_flags & RTF_HOST)
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 4e9feda..2eecb95 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/jail.h>
#include <sys/kernel.h>
+#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 4677154..a22fb30 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/eventhandler.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 9f21f11..d68a8a6 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/callout.h>
+#include <sys/eventhandler.h>
#include <sys/hhook.h>
#include <sys/kernel.h>
#include <sys/khelp.h>
diff --git a/sys/netinet/toecore.c b/sys/netinet/toecore.c
index 6ed8eb0..cfa77e7 100644
--- a/sys/netinet/toecore.c
+++ b/sys/netinet/toecore.c
@@ -70,7 +70,6 @@ static TAILQ_HEAD(, toedev) toedev_list;
static eventhandler_tag listen_start_eh;
static eventhandler_tag listen_stop_eh;
static eventhandler_tag lle_event_eh;
-static eventhandler_tag route_redirect_eh;
static int
toedev_connect(struct toedev *tod __unused, struct socket *so __unused,
@@ -438,17 +437,6 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
}
/*
- * XXX: implement.
- */
-static void
-toe_route_redirect_event(void *arg __unused, struct rtentry *rt0,
- struct rtentry *rt1, struct sockaddr *sa)
-{
-
- return;
-}
-
-/*
* Returns 0 or EWOULDBLOCK on success (any other value is an error). 0 means
* lladdr and vtag are valid on return, EWOULDBLOCK means the TOE driver's
* tod_l2_update will be called later, when the entry is resolved or times out.
@@ -534,8 +522,6 @@ toecore_load(void)
toe_listen_stop_event, NULL, EVENTHANDLER_PRI_ANY);
lle_event_eh = EVENTHANDLER_REGISTER(lle_event, toe_lle_event, NULL,
EVENTHANDLER_PRI_ANY);
- route_redirect_eh = EVENTHANDLER_REGISTER(route_redirect_event,
- toe_route_redirect_event, NULL, EVENTHANDLER_PRI_ANY);
return (0);
}
@@ -553,7 +539,6 @@ toecore_unload(void)
EVENTHANDLER_DEREGISTER(tcp_offload_listen_start, listen_start_eh);
EVENTHANDLER_DEREGISTER(tcp_offload_listen_stop, listen_stop_eh);
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
- EVENTHANDLER_DEREGISTER(route_redirect_event, route_redirect_eh);
mtx_unlock(&toedev_lock);
mtx_destroy(&toedev_lock);
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 2f2b869..a2f6635 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
+#include <sys/eventhandler.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.h>
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 54d7e1e..dd77527 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2114,13 +2114,13 @@ icmp6_rip6_input(struct mbuf **mp, int off)
void
icmp6_reflect(struct mbuf *m, size_t off)
{
- struct in6_addr src, *srcp = NULL;
+ struct in6_addr src6, *srcp;
struct ip6_hdr *ip6;
struct icmp6_hdr *icmp6;
struct in6_ifaddr *ia = NULL;
struct ifnet *outif = NULL;
int plen;
- int type, code;
+ int type, code, hlim;
/* too short to reflect */
if (off < sizeof(struct ip6_hdr)) {
@@ -2166,6 +2166,8 @@ icmp6_reflect(struct mbuf *m, size_t off)
icmp6 = (struct icmp6_hdr *)(ip6 + 1);
type = icmp6->icmp6_type; /* keep type for statistics */
code = icmp6->icmp6_code; /* ditto. */
+ hlim = 0;
+ srcp = NULL;
/*
* If the incoming packet was addressed directly to us (i.e. unicast),
@@ -2177,34 +2179,43 @@ icmp6_reflect(struct mbuf *m, size_t off)
if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
if (ia != NULL && !(ia->ia6_flags &
- (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)))
- srcp = &ia->ia_addr.sin6_addr;
+ (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) {
+ src6 = ia->ia_addr.sin6_addr;
+ srcp = &src6;
+
+ if (m->m_pkthdr.rcvif != NULL) {
+ /* XXX: This may not be the outgoing interface */
+ hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim;
+ } else
+ hlim = V_ip6_defhlim;
+ }
+ if (ia != NULL)
+ ifa_free(&ia->ia_ifa);
}
if (srcp == NULL) {
- int e;
- struct sockaddr_in6 sin6;
+ int error;
+ struct in6_addr dst6;
+ uint32_t scopeid;
/*
* This case matches to multicasts, our anycast, or unicasts
* that we do not own. Select a source address based on the
* source address of the erroneous packet.
*/
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(sin6);
- sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */
+ in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
+ error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ scopeid, NULL, &src6, &hlim);
- e = in6_selectsrc(&sin6, NULL, NULL, NULL, &outif, &src);
- if (e) {
+ if (error) {
char ip6buf[INET6_ADDRSTRLEN];
nd6log((LOG_DEBUG,
"icmp6_reflect: source can't be determined: "
"dst=%s, error=%d\n",
- ip6_sprintf(ip6buf, &sin6.sin6_addr), e));
+ ip6_sprintf(ip6buf, &ip6->ip6_dst), error));
goto bad;
}
- srcp = &src;
+ srcp = &src6;
}
/*
* ip6_input() drops a packet if its src is multicast.
@@ -2216,13 +2227,7 @@ icmp6_reflect(struct mbuf *m, size_t off)
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
ip6->ip6_vfc |= IPV6_VERSION;
ip6->ip6_nxt = IPPROTO_ICMPV6;
- if (outif)
- ip6->ip6_hlim = ND_IFINFO(outif)->chlim;
- else if (m->m_pkthdr.rcvif) {
- /* XXX: This may not be the outgoing interface */
- ip6->ip6_hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim;
- } else
- ip6->ip6_hlim = V_ip6_defhlim;
+ ip6->ip6_hlim = hlim;
icmp6->icmp6_cksum = 0;
icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6,
@@ -2238,13 +2243,9 @@ icmp6_reflect(struct mbuf *m, size_t off)
if (outif)
icmp6_ifoutstat_inc(outif, type, code);
- if (ia != NULL)
- ifa_free(&ia->ia_ifa);
return;
bad:
- if (ia != NULL)
- ifa_free(&ia->ia_ifa);
m_freem(m);
return;
}
diff --git a/sys/netinet6/in6_fib.c b/sys/netinet6/in6_fib.c
index eba5b7c..96acfbb 100644
--- a/sys/netinet6/in6_fib.c
+++ b/sys/netinet6/in6_fib.c
@@ -241,6 +241,13 @@ fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
rn = rh->rnh_matchaddr((void *)&sin6, rh);
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
rte = RNTORT(rn);
+#ifdef RADIX_MPATH
+ rte = rt_mpath_select(rte, flowid);
+ if (rte == NULL) {
+ RADIX_NODE_HEAD_RUNLOCK(rh);
+ return (ENOENT);
+ }
+#endif
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(rte->rt_ifp)) {
fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags,
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 67ecb8c..a779b8d 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -328,7 +328,6 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
{
register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
int error = 0;
- struct ifnet *ifp = NULL;
int scope_ambiguous = 0;
struct in6_addr in6a;
@@ -358,20 +357,15 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam,
if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0)
return (error);
- error = in6_selectsrc(sin6, inp->in6p_outputopts,
- inp, inp->inp_cred, &ifp, &in6a);
+ error = in6_selectsrc_socket(sin6, inp->in6p_outputopts,
+ inp, inp->inp_cred, scope_ambiguous, &in6a, NULL);
if (error)
return (error);
- if (ifp && scope_ambiguous &&
- (error = in6_setscope(&sin6->sin6_addr, ifp, NULL)) != 0) {
- return(error);
- }
-
/*
* Do not update this earlier, in case we return with an error.
*
- * XXX: this in6_selectsrc result might replace the bound local
+ * XXX: this in6_selectsrc_socket result might replace the bound local
* address with the address specified by setsockopt(IPV6_PKTINFO).
* Is it the intended behavior?
*/
diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c
index 97e12162..93c786c 100644
--- a/sys/netinet6/in6_rmx.c
+++ b/sys/netinet6/in6_rmx.c
@@ -107,7 +107,6 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
{
struct rtentry *rt = (struct rtentry *)treenodes;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rt_key(rt);
- struct radix_node *ret;
RADIX_NODE_HEAD_WLOCK_ASSERT(head);
if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
@@ -148,34 +147,7 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
rt->rt_mtu = IN6_LINKMTU(rt->rt_ifp);
}
- ret = rn_addroute(v_arg, n_arg, head, treenodes);
- if (ret == NULL) {
- struct rtentry *rt2;
- /*
- * We are trying to add a net route, but can't.
- * The following case should be allowed, so we'll make a
- * special check for this:
- * Two IPv6 addresses with the same prefix is assigned
- * to a single interrface.
- * # ifconfig if0 inet6 3ffe:0501::1 prefix 64 alias (*1)
- * # ifconfig if0 inet6 3ffe:0501::2 prefix 64 alias (*2)
- * In this case, (*1) and (*2) want to add the same
- * net route entry, 3ffe:0501:: -> if0.
- * This case should not raise an error.
- */
- rt2 = in6_rtalloc1((struct sockaddr *)sin6, 0, RTF_RNH_LOCKED,
- rt->rt_fibnum);
- if (rt2) {
- if (((rt2->rt_flags & (RTF_HOST|RTF_GATEWAY)) == 0)
- && rt2->rt_gateway
- && rt2->rt_gateway->sa_family == AF_LINK
- && rt2->rt_ifp == rt->rt_ifp) {
- ret = rt2->rt_nodes;
- }
- RTFREE_LOCKED(rt2);
- }
- }
- return (ret);
+ return (rn_addroute(v_arg, n_arg, head, treenodes));
}
/*
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index fb362e2..4029402 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -136,6 +136,9 @@ static int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
static int in6_selectif(struct sockaddr_in6 *, struct ip6_pktopts *,
struct ip6_moptions *, struct ifnet **,
struct ifnet *, u_int);
+static int in6_selectsrc(uint32_t, struct sockaddr_in6 *,
+ struct ip6_pktopts *, struct inpcb *, struct ucred *,
+ struct ifnet **, struct in6_addr *);
static struct in6_addrpolicy *lookup_addrsel_policy(struct sockaddr_in6 *);
@@ -175,9 +178,9 @@ static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *);
goto out; /* XXX: we can't use 'break' here */ \
} while(0)
-int
-in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
- struct inpcb *inp, struct ucred *cred,
+static int
+in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock,
+ struct ip6_pktopts *opts, struct inpcb *inp, struct ucred *cred,
struct ifnet **ifpp, struct in6_addr *srcp)
{
struct rm_priotracker in6_ifa_tracker;
@@ -228,7 +231,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
/* get the outgoing interface */
if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp,
- (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB))
+ fibnum))
!= 0)
return (error);
@@ -545,6 +548,79 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
}
/*
+ * Select source address based on @inp, @dstsock and @opts.
+ * Stores selected address to @srcp. If @scope_ambiguous is set,
+ * embed scope from selected outgoing interface. If @hlim pointer
+ * is provided, stores calculated hop limit there.
+ * Returns 0 on success.
+ */
+int
+in6_selectsrc_socket(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
+ struct inpcb *inp, struct ucred *cred, int scope_ambiguous,
+ struct in6_addr *srcp, int *hlim)
+{
+ struct ifnet *retifp;
+ uint32_t fibnum;
+ int error;
+
+ fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
+ retifp = NULL;
+
+ error = in6_selectsrc(fibnum, dstsock, opts, inp, cred, &retifp, srcp);
+ if (error != 0)
+ return (error);
+
+ if (hlim != NULL)
+ *hlim = in6_selecthlim(inp, retifp);
+
+ if (retifp == NULL || scope_ambiguous == 0)
+ return (0);
+
+ /*
+ * Application should provide a proper zone ID or the use of
+ * default zone IDs should be enabled. Unfortunately, some
+ * applications do not behave as it should, so we need a
+ * workaround. Even if an appropriate ID is not determined
+ * (when it's required), if we can determine the outgoing
+ * interface. determine the zone ID based on the interface.
+ */
+ error = in6_setscope(&dstsock->sin6_addr, retifp, NULL);
+
+ return (error);
+}
+
+/*
+ * Select source address based on @fibnum, @dst and @scopeid.
+ * Stores selected address to @srcp.
+ * Returns 0 on success.
+ *
+ * Used by non-socket based consumers (ND code mostly)
+ */
+int
+in6_selectsrc_addr(uint32_t fibnum, const struct in6_addr *dst,
+ uint32_t scopeid, struct ifnet *ifp, struct in6_addr *srcp,
+ int *hlim)
+{
+ struct ifnet *retifp;
+ struct sockaddr_in6 dst_sa;
+ int error;
+
+ retifp = ifp;
+ bzero(&dst_sa, sizeof(dst_sa));
+ dst_sa.sin6_family = AF_INET6;
+ dst_sa.sin6_len = sizeof(dst_sa);
+ dst_sa.sin6_addr = *dst;
+ dst_sa.sin6_scope_id = scopeid;
+ sa6_embedscope(&dst_sa, 0);
+
+ error = in6_selectsrc(fibnum, &dst_sa, NULL, NULL, NULL, &retifp, srcp);
+ if (hlim != NULL)
+ *hlim = in6_selecthlim(NULL, retifp);
+
+ return (error);
+}
+
+/*
* clone - meaningful only for bsdi and freebsd
*/
static int
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index f43a28c..ef86eca 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -418,9 +418,10 @@ int rip6_usrreq(struct socket *,
int dest6_input(struct mbuf **, int *, int);
int none_input(struct mbuf **, int *, int);
-int in6_selectsrc(struct sockaddr_in6 *, struct ip6_pktopts *,
- struct inpcb *inp, struct ucred *cred,
- struct ifnet **, struct in6_addr *);
+int in6_selectsrc_socket(struct sockaddr_in6 *, struct ip6_pktopts *,
+ struct inpcb *, struct ucred *, int, struct in6_addr *, int *);
+int in6_selectsrc_addr(uint32_t, const struct in6_addr *,
+ uint32_t, struct ifnet *, struct in6_addr *, int *);
int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
struct ip6_moptions *, struct route_in6 *, struct ifnet **,
struct rtentry **);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index b7ba0b2..3a4e8a0 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -481,27 +481,21 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
ifa_free(ifa);
} else {
int error;
- struct sockaddr_in6 dst_sa;
- struct in6_addr src_in;
- struct ifnet *oifp;
-
- bzero(&dst_sa, sizeof(dst_sa));
- dst_sa.sin6_family = AF_INET6;
- dst_sa.sin6_len = sizeof(dst_sa);
- dst_sa.sin6_addr = ip6->ip6_dst;
-
- oifp = ifp;
- error = in6_selectsrc(&dst_sa, NULL,
- NULL, NULL, &oifp, &src_in);
+ struct in6_addr dst6, src6;
+ uint32_t scopeid;
+
+ in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
+ error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ scopeid, ifp, &src6, NULL);
if (error) {
char ip6buf[INET6_ADDRSTRLEN];
nd6log((LOG_DEBUG, "%s: source can't be "
"determined: dst=%s, error=%d\n", __func__,
- ip6_sprintf(ip6buf, &dst_sa.sin6_addr),
+ ip6_sprintf(ip6buf, &dst6),
error));
goto bad;
}
- ip6->ip6_src = src_in;
+ ip6->ip6_src = src6;
}
} else {
/*
@@ -941,12 +935,12 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
{
struct mbuf *m;
struct m_tag *mtag;
- struct ifnet *oifp;
struct ip6_hdr *ip6;
struct nd_neighbor_advert *nd_na;
struct ip6_moptions im6o;
- struct in6_addr src, daddr6;
- struct sockaddr_in6 dst_sa;
+ struct in6_addr daddr6, dst6, src6;
+ uint32_t scopeid;
+
int icmp6len, maxlen, error;
caddr_t mac = NULL;
@@ -998,24 +992,21 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
flags &= ~ND_NA_FLAG_SOLICITED;
}
ip6->ip6_dst = daddr6;
- bzero(&dst_sa, sizeof(struct sockaddr_in6));
- dst_sa.sin6_family = AF_INET6;
- dst_sa.sin6_len = sizeof(struct sockaddr_in6);
- dst_sa.sin6_addr = daddr6;
/*
* Select a source whose scope is the same as that of the dest.
*/
- oifp = ifp;
- error = in6_selectsrc(&dst_sa, NULL, NULL, NULL, &oifp, &src);
+ in6_splitscope(&daddr6, &dst6, &scopeid);
+ error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ scopeid, ifp, &src6, NULL);
if (error) {
char ip6buf[INET6_ADDRSTRLEN];
nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
"determined: dst=%s, error=%d\n",
- ip6_sprintf(ip6buf, &dst_sa.sin6_addr), error));
+ ip6_sprintf(ip6buf, &daddr6), error));
goto bad;
}
- ip6->ip6_src = src;
+ ip6->ip6_src = src6;
nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
nd_na->nd_na_code = 0;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 0725842..972eb9f 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -397,6 +397,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
int type = 0, code = 0; /* for ICMPv6 output statistics only */
int scope_ambiguous = 0;
int use_defzone = 0;
+ int hlim = 0;
struct in6_addr in6a;
va_list ap;
@@ -460,8 +461,9 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
/*
* Source address selection.
*/
- error = in6_selectsrc(dstsock, optp, in6p, so->so_cred,
- &oifp, &in6a);
+ error = in6_selectsrc_socket(dstsock, optp, in6p, so->so_cred,
+ scope_ambiguous, &in6a, &hlim);
+
if (error)
goto bad;
error = prison_check_ip6(in6p->inp_cred, &in6a);
@@ -469,19 +471,6 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
goto bad;
ip6->ip6_src = in6a;
- if (oifp && scope_ambiguous) {
- /*
- * Application should provide a proper zone ID or the use of
- * default zone IDs should be enabled. Unfortunately, some
- * applications do not behave as it should, so we need a
- * workaround. Even if an appropriate ID is not determined
- * (when it's required), if we can determine the outgoing
- * interface. determine the zone ID based on the interface.
- */
- error = in6_setscope(&dstsock->sin6_addr, oifp, NULL);
- if (error != 0)
- goto bad;
- }
ip6->ip6_dst = dstsock->sin6_addr;
/*
@@ -496,7 +485,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
* ip6_plen will be filled in ip6_output, so not fill it here.
*/
ip6->ip6_nxt = in6p->inp_ip_p;
- ip6->ip6_hlim = in6_selecthlim(in6p, oifp);
+ ip6->ip6_hlim = hlim;
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 ||
in6p->in6p_cksum != -1) {
@@ -784,7 +773,6 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
struct inpcb *inp;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
struct in6_addr in6a;
- struct ifnet *ifp = NULL;
int error = 0, scope_ambiguous = 0;
inp = sotoinpcb(so);
@@ -813,21 +801,14 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
/* Source address selection. XXX: need pcblookup? */
- error = in6_selectsrc(addr, inp->in6p_outputopts,
- inp, so->so_cred, &ifp, &in6a);
+ error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
+ inp, so->so_cred, scope_ambiguous, &in6a, NULL);
if (error) {
INP_WUNLOCK(inp);
INP_INFO_WUNLOCK(&V_ripcbinfo);
return (error);
}
- /* XXX: see above */
- if (ifp && scope_ambiguous &&
- (error = in6_setscope(&addr->sin6_addr, ifp, NULL)) != 0) {
- INP_WUNLOCK(inp);
- INP_INFO_WUNLOCK(&V_ripcbinfo);
- return (error);
- }
inp->in6p_faddr = addr->sin6_addr;
inp->in6p_laddr = in6a;
soisconnected(so);
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 353b260..9768df5 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -631,7 +631,6 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
struct udphdr *udp6;
struct in6_addr *laddr, *faddr, in6a;
struct sockaddr_in6 *sin6 = NULL;
- struct ifnet *oifp = NULL;
int cscov_partial = 0;
int scope_ambiguous = 0;
u_short fport;
@@ -731,15 +730,10 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
}
if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
- error = in6_selectsrc(sin6, optp, inp,
- td->td_ucred, &oifp, &in6a);
+ error = in6_selectsrc_socket(sin6, optp, inp,
+ td->td_ucred, scope_ambiguous, &in6a, NULL);
if (error)
goto release;
- if (oifp && scope_ambiguous &&
- (error = in6_setscope(&sin6->sin6_addr,
- oifp, NULL))) {
- goto release;
- }
laddr = &in6a;
} else
laddr = &inp->in6p_laddr; /* XXX */
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c
index 71c96b2..a1ee5dd 100644
--- a/sys/netpfil/ipfw/ip_fw_table.c
+++ b/sys/netpfil/ipfw/ip_fw_table.c
@@ -2097,7 +2097,7 @@ export_table_info(struct ip_fw_chain *ch, struct table_config *tc,
i->count = table_get_count(ch, tc);
i->limit = tc->limit;
i->flags |= (tc->locked != 0) ? IPFW_TGFLAGS_LOCKED : 0;
- i->size = tc->count * sizeof(ipfw_obj_tentry);
+ i->size = i->count * sizeof(ipfw_obj_tentry);
i->size += sizeof(ipfw_obj_header) + sizeof(ipfw_xtable_info);
strlcpy(i->tablename, tc->tablename, sizeof(i->tablename));
ti = KIDX_TO_TI(ch, tc->no.kidx);
diff --git a/sys/netpfil/ipfw/ip_fw_table_algo.c b/sys/netpfil/ipfw/ip_fw_table_algo.c
index 06a4641..2ce550e 100644
--- a/sys/netpfil/ipfw/ip_fw_table_algo.c
+++ b/sys/netpfil/ipfw/ip_fw_table_algo.c
@@ -53,8 +53,10 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <netinet/in.h>
+#include <netinet/in_fib.h>
#include <netinet/ip_var.h> /* struct ipfw_rule_ref */
#include <netinet/ip_fw.h>
+#include <netinet6/in6_fib.h>
#include <netpfil/ipfw/ip_fw_private.h>
#include <netpfil/ipfw/ip_fw_table.h>
@@ -3778,7 +3780,6 @@ struct table_algo flow_hash = {
*
*/
-static struct rtentry *lookup_kfib(void *key, int keylen, int fib);
static int ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
uint32_t *val);
static int kfib_parse_opts(int *pfib, char *data);
@@ -3792,46 +3793,45 @@ static void ta_dump_kfib_tinfo(void *ta_state, struct table_info *ti,
static int contigmask(uint8_t *p, int len);
static int ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent);
+static int ta_dump_kfib_tentry_int(struct sockaddr *paddr,
+ struct sockaddr *pmask, ipfw_obj_tentry *tent);
static int ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
ipfw_obj_tentry *tent);
static void ta_foreach_kfib(void *ta_state, struct table_info *ti,
ta_foreach_f *f, void *arg);
-static struct rtentry *
-lookup_kfib(void *key, int keylen, int fib)
-{
- struct sockaddr *s;
-
- if (keylen == 4) {
- struct sockaddr_in sin;
- bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = *(in_addr_t *)key;
- s = (struct sockaddr *)&sin;
- } else {
- struct sockaddr_in6 sin6;
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = *(struct in6_addr *)key;
- s = (struct sockaddr *)&sin6;
- }
-
- return (rtalloc1_fib(s, 0, 0, fib));
-}
static int
ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
uint32_t *val)
{
- struct rtentry *rte;
+#ifdef INET
+ struct nhop4_basic nh4;
+ struct in_addr in;
+#endif
+#ifdef INET6
+ struct nhop6_basic nh6;
+#endif
+ int error;
+
+ error = ENOENT;
+#ifdef INET
+ if (keylen == 4) {
+ in.s_addr = *(in_addr_t *)key;
+ error = fib4_lookup_nh_basic(ti->data,
+ in, 0, 0, &nh4);
+ }
+#endif
+#ifdef INET6
+ if (keylen == 6)
+ error = fib6_lookup_nh_basic(ti->data,
+ (struct in6_addr *)key, 0, 0, 0, &nh6);
+#endif
- if ((rte = lookup_kfib(key, keylen, ti->data)) == NULL)
+ if (error != 0)
return (0);
*val = 0;
- RTFREE_LOCKED(rte);
return (1);
}
@@ -3940,6 +3940,16 @@ ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
ipfw_obj_tentry *tent)
{
struct rtentry *rte;
+
+ rte = (struct rtentry *)e;
+
+ return ta_dump_kfib_tentry_int(rt_key(rte), rt_mask(rte), tent);
+}
+
+static int
+ta_dump_kfib_tentry_int(struct sockaddr *paddr, struct sockaddr *pmask,
+ ipfw_obj_tentry *tent)
+{
#ifdef INET
struct sockaddr_in *addr, *mask;
#endif
@@ -3948,14 +3958,13 @@ ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
#endif
int len;
- rte = (struct rtentry *)e;
- addr = (struct sockaddr_in *)rt_key(rte);
- mask = (struct sockaddr_in *)rt_mask(rte);
len = 0;
/* Guess IPv4/IPv6 radix by sockaddr family */
#ifdef INET
- if (addr->sin_family == AF_INET) {
+ if (paddr->sa_family == AF_INET) {
+ addr = (struct sockaddr_in *)paddr;
+ mask = (struct sockaddr_in *)pmask;
tent->k.addr.s_addr = addr->sin_addr.s_addr;
len = 32;
if (mask != NULL)
@@ -3968,9 +3977,9 @@ ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
}
#endif
#ifdef INET6
- if (addr->sin_family == AF_INET6) {
- addr6 = (struct sockaddr_in6 *)addr;
- mask6 = (struct sockaddr_in6 *)mask;
+ if (paddr->sa_family == AF_INET6) {
+ addr6 = (struct sockaddr_in6 *)paddr;
+ mask6 = (struct sockaddr_in6 *)pmask;
memcpy(&tent->k, &addr6->sin6_addr, sizeof(struct in6_addr));
len = 128;
if (mask6 != NULL)
@@ -3990,28 +3999,43 @@ static int
ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
ipfw_obj_tentry *tent)
{
- struct rtentry *rte;
- void *key;
- int keylen;
+ struct rt_addrinfo info;
+ struct sockaddr_in6 key6, dst6, mask6;
+ struct sockaddr *dst, *key, *mask;
+
+ /* Prepare sockaddr for prefix/mask and info */
+ bzero(&dst6, sizeof(dst6));
+ dst6.sin6_len = sizeof(dst6);
+ dst = (struct sockaddr *)&dst6;
+ bzero(&mask6, sizeof(mask6));
+ mask6.sin6_len = sizeof(mask6);
+ mask = (struct sockaddr *)&mask6;
+
+ bzero(&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_NETMASK] = mask;
+
+ /* Prepare the lookup key */
+ bzero(&key6, sizeof(key6));
+ key6.sin6_family = tent->subtype;
+ key = (struct sockaddr *)&key6;
if (tent->subtype == AF_INET) {
- key = &tent->k.addr;
- keylen = sizeof(struct in_addr);
+ ((struct sockaddr_in *)&key6)->sin_addr = tent->k.addr;
+ key6.sin6_len = sizeof(struct sockaddr_in);
} else {
- key = &tent->k.addr6;
- keylen = sizeof(struct in6_addr);
+ key6.sin6_addr = tent->k.addr6;
+ key6.sin6_len = sizeof(struct sockaddr_in6);
}
- if ((rte = lookup_kfib(key, keylen, ti->data)) == NULL)
- return (0);
+ if (rib_lookup_info(ti->data, key, 0, 0, &info) != 0)
+ return (ENOENT);
+ if ((info.rti_addrs & RTA_NETMASK) == 0)
+ mask = NULL;
- if (rte != NULL) {
- ta_dump_kfib_tentry(ta_state, ti, rte, tent);
- RTFREE_LOCKED(rte);
- return (0);
- }
+ ta_dump_kfib_tentry_int(dst, mask, tent);
- return (ENOENT);
+ return (0);
}
static void
diff --git a/sys/netpfil/pf/pf_if.c b/sys/netpfil/pf/pf_if.c
index a2c9c7e..6b25f5f 100644
--- a/sys/netpfil/pf/pf_if.c
+++ b/sys/netpfil/pf/pf_if.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/rwlock.h>
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
index e1f2dc0..6326bd2 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1260,16 +1260,12 @@ ipoib_output(struct ifnet *ifp, struct mbuf *m,
#if defined(INET) || defined(INET6)
struct llentry *lle = NULL;
#endif
- struct rtentry *rt0 = NULL;
struct ipoib_header *eh;
int error = 0, is_gw = 0;
short type;
- if (ro != NULL) {
- rt0 = ro->ro_rt;
- if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
- is_gw = 1;
- }
+ if (ro != NULL)
+ is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error)
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
index 0b78212..7c6f6cb 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c
@@ -242,7 +242,7 @@ sdp_sock_queue_rcv_mb(struct socket *sk, struct mbuf *mb)
SOCKBUF_LOCK(&sk->so_rcv);
if (unlikely(h->flags & SDP_OOB_PRES))
sdp_urg(ssk, mb);
- sbappend_locked(&sk->so_rcv, mb);
+ sbappend_locked(&sk->so_rcv, mb, 0);
sorwakeup_locked(sk);
return mb;
}
diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S
index 477ae88..b14215c 100644
--- a/sys/powerpc/aim/locore32.S
+++ b/sys/powerpc/aim/locore32.S
@@ -1,8 +1,7 @@
/* $FreeBSD$ */
-/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
/*-
- * Copyright (C) 2001 Benno Rice
+ * Copyright (C) 2010-2016 Nathan Whitehorn
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -14,37 +13,7 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
@@ -95,15 +64,7 @@ GLOBAL(tmpstk)
btext:
/*
- * This symbol is here for the benefit of kvm_mkdb, and is supposed to
- * mark the start of kernel text.
- */
- .globl kernel_text
-kernel_text:
-
-/*
- * Startup entry. Note, this must be the first thing in the text
- * segment!
+ * Main kernel entry point.
*/
.text
.globl __start
@@ -148,29 +109,7 @@ __start:
stw %r3, 0(%r1)
bl mi_startup
- /* If mi_startup somehow returns, exit. This would be bad. */
- b OF_exit
-
-/*
- * int setfault()
- *
- * Similar to setjmp to setup for handling faults on accesses to user memory.
- * Any routine using this may only call bcopy, either the form below,
- * or the (currently used) C code optimized, so it doesn't use any non-volatile
- * registers.
- */
- .globl setfault
-setfault:
- mflr 0
- mfcr 12
- mfsprg 4,0
- lwz 4,TD_PCB(2) /* curthread = r2 */
- stw 3,PCB_ONFAULT(4)
- stw 0,0(3)
- stw 1,4(3)
- stw 2,8(3)
- stmw 12,12(3)
- xor 3,3,3
- blr
+ /* mi_startup() does not return */
+ b .
#include <powerpc/aim/trap_subr32.S>
diff --git a/sys/powerpc/aim/locore64.S b/sys/powerpc/aim/locore64.S
index 7f93793..cd64b5f 100644
--- a/sys/powerpc/aim/locore64.S
+++ b/sys/powerpc/aim/locore64.S
@@ -1,8 +1,7 @@
/* $FreeBSD$ */
-/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
/*-
- * Copyright (C) 2001 Benno Rice
+ * Copyright (C) 2010-2016 Nathan Whitehorn
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -14,7 +13,7 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
@@ -24,36 +23,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*-
- * Copyright (C) 1995, 1996 Wolfgang Solfrank.
- * Copyright (C) 1995, 1996 TooLs GmbH.
- * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by TooLs GmbH.
- * 4. The name of TooLs GmbH may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * $FreeBSD$
*/
#include "assym.s"
@@ -69,13 +40,6 @@
.abiversion _CALL_ELF
#endif
-/* Locate the per-CPU data structure */
-#define GET_CPUINFO(r) \
- mfsprg0 r
-#define GET_TOCBASE(r) \
- li r,TRAP_TOCBASE; /* Magic address for TOC */ \
- ld r,0(r)
-
/* Glue for linker script */
.globl kernbase
.set kernbase, KERNBASE
@@ -102,15 +66,7 @@ TOC_ENTRY(tmpstk)
btext:
/*
- * This symbol is here for the benefit of kvm_mkdb, and is supposed to
- * mark the start of kernel text.
- */
- .globl kernel_text
-kernel_text:
-
-/*
- * Startup entry. Note, this must be the first thing in the text
- * segment!
+ * Main kernel entry point.
*
* Calling convention:
* r3: Flattened Device Tree pointer (or zero)
@@ -169,50 +125,7 @@ ASENTRY_NOPROF(__start)
bl mi_startup
nop
- /* If this returns (it won't), go back to firmware */
- b OF_exit
- nop
-
-/*
- * int setfault()
- *
- * Similar to setjmp to setup for handling faults on accesses to user memory.
- * Any routine using this may only call bcopy, either the form below,
- * or the (currently used) C code optimized, so it doesn't use any non-volatile
- * registers.
- */
-ASENTRY_NOPROF(setfault)
- mflr 0
- mfcr 12
- mfsprg 4,0
- ld 4,TD_PCB(13) /* curthread = r13 */
- std 3,PCB_ONFAULT(4)
- std 0,0(3)
- std 1,8(3)
- std 2,16(3)
-
- std %r12,24(%r3) /* Save the non-volatile GP regs. */
- std %r13,24+1*8(%r3)
- std %r14,24+2*8(%r3)
- std %r15,24+3*8(%r3)
- std %r16,24+4*8(%r3)
- std %r17,24+5*8(%r3)
- std %r18,24+6*8(%r3)
- std %r19,24+7*8(%r3)
- std %r20,24+8*8(%r3)
- std %r21,24+9*8(%r3)
- std %r22,24+10*8(%r3)
- std %r23,24+11*8(%r3)
- std %r24,24+12*8(%r3)
- std %r25,24+13*8(%r3)
- std %r26,24+14*8(%r3)
- std %r27,24+15*8(%r3)
- std %r28,24+16*8(%r3)
- std %r29,24+17*8(%r3)
- std %r30,24+18*8(%r3)
- std %r31,24+19*8(%r3)
-
- xor 3,3,3
- blr
+ /* Unreachable */
+ b .
#include <powerpc/aim/trap_subr64.S>
diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S
index 7ad0a70..587086e 100644
--- a/sys/powerpc/aim/trap_subr64.S
+++ b/sys/powerpc/aim/trap_subr64.S
@@ -39,9 +39,12 @@
* #include <powerpc/aim/trap_subr.S>
*/
-/*
- * Save/restore segment registers
- */
+/* Locate the per-CPU data structure */
+#define GET_CPUINFO(r) \
+ mfsprg0 r
+#define GET_TOCBASE(r) \
+ li r,TRAP_TOCBASE; /* Magic address for TOC */ \
+ ld r,0(r)
/*
* Restore SRs for a pmap
diff --git a/sys/powerpc/booke/booke_machdep.c b/sys/powerpc/booke/booke_machdep.c
index a019597..78ca12f 100644
--- a/sys/powerpc/booke/booke_machdep.c
+++ b/sys/powerpc/booke/booke_machdep.c
@@ -156,7 +156,6 @@ __FBSDID("$FreeBSD$");
#define debugf(fmt, args...)
#endif
-extern unsigned char kernel_text[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char __bss_start[];
@@ -311,7 +310,7 @@ booke_init(u_long arg1, u_long arg2)
end += fdt_totalsize((void *)dtbp);
__endkernel = end;
mdp = NULL;
- } else if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */
+ } else if (arg1 > (uintptr_t)btext) /* FreeBSD loader */
mdp = (void *)arg1;
else /* U-Boot */
mdp = NULL;
diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S
index 2d6c66d..a49d796 100644
--- a/sys/powerpc/booke/locore.S
+++ b/sys/powerpc/booke/locore.S
@@ -837,29 +837,6 @@ ENTRY(dataloss_erratum_access)
blr
-/*
- * int setfault()
- *
- * Similar to setjmp to setup for handling faults on accesses to user memory.
- * Any routine using this may only call bcopy, either the form below,
- * or the (currently used) C code optimized, so it doesn't use any non-volatile
- * registers.
- */
- .globl setfault
-setfault:
- mflr %r0
- mfsprg0 %r4
- lwz %r4, TD_PCB(%r2)
- stw %r3, PCB_ONFAULT(%r4)
- mfcr %r4
- stw %r0, 0(%r3)
- stw %r1, 4(%r3)
- stw %r2, 8(%r3)
- stw %r4, 12(%r3)
- stmw %r13, 16(%r3) /* store CR, CTR, XER, [r13 .. r31] */
- li %r3, 0 /* return FALSE */
- blr
-
/************************************************************************/
/* Data section */
/************************************************************************/
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 6caf5d2..094949e 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -35,7 +35,7 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
-typedef register_t faultbuf[25];
+#include <machine/setjmp.h>
struct pcb {
register_t pcb_context[20]; /* non-volatile r14-r31 */
@@ -44,7 +44,7 @@ struct pcb {
register_t pcb_toc; /* toc pointer */
register_t pcb_lr; /* link register */
struct pmap *pcb_pm; /* pmap of our vmspace */
- faultbuf *pcb_onfault; /* For use during
+ jmp_buf *pcb_onfault; /* For use during
copyin/copyout */
int pcb_flags;
#define PCB_FPU 1 /* Process uses FPU */
diff --git a/sys/powerpc/include/setjmp.h b/sys/powerpc/include/setjmp.h
index e453044..b95a111 100644
--- a/sys/powerpc/include/setjmp.h
+++ b/sys/powerpc/include/setjmp.h
@@ -8,7 +8,11 @@
#include <sys/cdefs.h>
+#ifdef _KERNEL
+#define _JBLEN 25 /* Kernel doesn't save FP and Altivec regs */
+#else
#define _JBLEN 100
+#endif
/*
* jmp_buf and sigjmp_buf are encapsulated in different structs to force
diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c
index 15cb58e..5dff8ef 100644
--- a/sys/powerpc/ofw/rtas.c
+++ b/sys/powerpc/ofw/rtas.c
@@ -62,8 +62,6 @@ int rtascall(vm_offset_t callbuffer, uintptr_t rtas_privdat);
extern uintptr_t rtas_entry;
extern register_t rtasmsr;
-int setfault(faultbuf); /* defined in locore.S */
-
/*
* After the VM is up, allocate RTAS memory and instantiate it
*/
@@ -203,7 +201,7 @@ int
rtas_call_method(cell_t token, int nargs, int nreturns, ...)
{
vm_offset_t argsptr;
- faultbuf env, *oldfaultbuf;
+ jmp_buf env, *oldfaultbuf;
va_list ap;
struct {
cell_t token;
@@ -233,7 +231,8 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...)
/* Get rid of any stale machine checks that have been waiting. */
__asm __volatile ("sync; isync");
oldfaultbuf = curthread->td_pcb->pcb_onfault;
- if (!setfault(env)) {
+ curthread->td_pcb->pcb_onfault = &env;
+ if (!setjmp(env)) {
__asm __volatile ("sync");
result = rtascall(argsptr, rtas_private_data);
__asm __volatile ("sync; isync");
diff --git a/sys/powerpc/powermac/grackle.c b/sys/powerpc/powermac/grackle.c
index b4a8a3b..95d59a1 100644
--- a/sys/powerpc/powermac/grackle.c
+++ b/sys/powerpc/powermac/grackle.c
@@ -82,8 +82,6 @@ static int grackle_enable_config(struct grackle_softc *, u_int,
static void grackle_disable_config(struct grackle_softc *);
static int badaddr(void *, size_t);
-int setfault(faultbuf); /* defined in locore.S */
-
/*
* Driver methods.
*/
@@ -244,7 +242,7 @@ static int
badaddr(void *addr, size_t size)
{
struct thread *td;
- faultbuf env, *oldfaultbuf;
+ jmp_buf env, *oldfaultbuf;
int x;
/* Get rid of any stale machine checks that have been waiting. */
@@ -253,7 +251,8 @@ badaddr(void *addr, size_t size)
td = curthread;
oldfaultbuf = td->td_pcb->pcb_onfault;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = oldfaultbuf;
__asm __volatile ("sync");
return 1;
diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
index fdee51d..29c4561 100644
--- a/sys/powerpc/powerpc/copyinout.c
+++ b/sys/powerpc/powerpc/copyinout.c
@@ -71,8 +71,6 @@ __FBSDID("$FreeBSD$");
#include <machine/slb.h>
#include <machine/vmparam.h>
-int setfault(faultbuf); /* defined in locore.S */
-
#ifdef AIM
/*
* Makes sure that the right segment of userspace is mapped in.
@@ -176,7 +174,7 @@ copyout(const void *kaddr, void *udaddr, size_t len)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
const char *kp;
char *up, *p;
size_t l;
@@ -184,7 +182,8 @@ copyout(const void *kaddr, void *udaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@@ -214,7 +213,7 @@ copyin(const void *udaddr, void *kaddr, size_t len)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
const char *up;
char *kp, *p;
size_t l;
@@ -222,7 +221,8 @@ copyin(const void *udaddr, void *kaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@@ -285,13 +285,14 @@ subyte(volatile void *addr, int byte)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
char *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -313,13 +314,14 @@ suword32(volatile void *addr, int word)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -341,13 +343,14 @@ suword(volatile void *addr, long word)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -382,14 +385,15 @@ fubyte(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
u_char *p;
int val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -410,13 +414,14 @@ fuword16(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
uint16_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -437,13 +442,14 @@ fueword32(volatile const void *addr, int32_t *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int32_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -465,13 +471,14 @@ fueword64(volatile const void *addr, int64_t *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
int64_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -493,13 +500,14 @@ fueword(volatile const void *addr, long *val)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -521,13 +529,14 @@ casueword32(volatile uint32_t *addr, uint32_t old, uint32_t *oldvalp,
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
uint32_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@@ -572,13 +581,14 @@ casueword(volatile u_long *addr, u_long old, u_long *oldvalp, u_long new)
{
struct thread *td;
pmap_t pm;
- faultbuf env;
+ jmp_buf env;
u_long *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
- if (setfault(env)) {
+ td->td_pcb->pcb_onfault = &env;
+ if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c
index 027105d..eed76c9 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -106,6 +106,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c
index 261660a..032728c 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -85,6 +85,7 @@ struct sysentvec elf64_freebsd_sysvec_v1 = {
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
INIT_SYSENTVEC(elf64_sysvec_v1, &elf64_freebsd_sysvec_v1);
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index 9d26e95..2f20b71 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -67,7 +67,6 @@ volatile static u_quad_t ap_timebase;
static u_int ipi_msg_cnt[32];
static struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
-int longfault(faultbuf, int);
void
machdep_ap_bootstrap(void)
diff --git a/sys/powerpc/powerpc/setjmp.S b/sys/powerpc/powerpc/setjmp.S
index 3884b11..910f58b 100644
--- a/sys/powerpc/powerpc/setjmp.S
+++ b/sys/powerpc/powerpc/setjmp.S
@@ -40,7 +40,6 @@
#define JMP_cr 22*REGWIDTH
#define JMP_ctr 23*REGWIDTH
#define JMP_xer 24*REGWIDTH
-#define JMP_sig 25*REGWIDTH
ASENTRY_NOPROF(setjmp)
ST_REG 31, JMP_r31(3)
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 4c9735a..d4dac2e 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -74,11 +74,12 @@ __FBSDID("$FreeBSD$");
#include <machine/spr.h>
#include <machine/sr.h>
-#define FAULTBUF_LR 0
+/* Below matches setjmp.S */
+#define FAULTBUF_LR 21
#define FAULTBUF_R1 1
#define FAULTBUF_R2 2
-#define FAULTBUF_CR 3
-#define FAULTBUF_R13 4
+#define FAULTBUF_CR 22
+#define FAULTBUF_R14 3
static void trap_fatal(struct trapframe *frame);
static void printtrap(u_int vector, struct trapframe *frame, int isfatal,
@@ -462,18 +463,19 @@ static int
handle_onfault(struct trapframe *frame)
{
struct thread *td;
- faultbuf *fb;
+ jmp_buf *fb;
td = curthread;
fb = td->td_pcb->pcb_onfault;
if (fb != NULL) {
- frame->srr0 = (*fb)[FAULTBUF_LR];
- frame->fixreg[1] = (*fb)[FAULTBUF_R1];
- frame->fixreg[2] = (*fb)[FAULTBUF_R2];
+ frame->srr0 = (*fb)->_jb[FAULTBUF_LR];
+ frame->fixreg[1] = (*fb)->_jb[FAULTBUF_R1];
+ frame->fixreg[2] = (*fb)->_jb[FAULTBUF_R2];
frame->fixreg[3] = 1;
- frame->cr = (*fb)[FAULTBUF_CR];
- bcopy(&(*fb)[FAULTBUF_R13], &frame->fixreg[13],
- 19 * sizeof(register_t));
+ frame->cr = (*fb)->_jb[FAULTBUF_CR];
+ bcopy(&(*fb)->_jb[FAULTBUF_R14], &frame->fixreg[14],
+ 18 * sizeof(register_t));
+ td->td_pcb->pcb_onfault = NULL; /* Returns twice, not thrice */
return (1);
}
return (0);
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index eea21a2..c2b0d26 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -85,6 +85,7 @@ static struct sysentvec elf64_freebsd_sysvec = {
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
+ .sv_trap = NULL,
};
static Elf64_Brandinfo freebsd_brand_info = {
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 8509a6c..91dd895 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -343,12 +343,13 @@ struct mbuf {
* External mbuf storage buffer types.
*/
#define EXT_CLUSTER 1 /* mbuf cluster */
-#define EXT_SFBUF 2 /* sendfile(2)'s sf_bufs */
+#define EXT_SFBUF 2 /* sendfile(2)'s sf_buf */
#define EXT_JUMBOP 3 /* jumbo cluster page sized */
#define EXT_JUMBO9 4 /* jumbo cluster 9216 bytes */
#define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */
#define EXT_PACKET 6 /* mbuf+cluster from packet zone */
#define EXT_MBUF 7 /* external mbuf reference (M_IOVEC) */
+#define EXT_SFBUF_NOCACHE 8 /* sendfile(2)'s sf_buf not to be cached */
#define EXT_VENDOR1 224 /* for vendor-internal use */
#define EXT_VENDOR2 225 /* for vendor-internal use */
@@ -397,6 +398,7 @@ struct mbuf {
*/
void sf_ext_ref(void *, void *);
void sf_ext_free(void *, void *);
+void sf_ext_free_nocache(void *, void *);
/*
* Flags indicating checksum, segmentation and other offload work to be
diff --git a/sys/sys/sf_buf.h b/sys/sys/sf_buf.h
index d3bb037..b5970d9 100644
--- a/sys/sys/sf_buf.h
+++ b/sys/sys/sf_buf.h
@@ -31,7 +31,14 @@
#define _SYS_SF_BUF_H_
struct sfstat { /* sendfile statistics */
+ uint64_t sf_syscalls; /* times sendfile was called */
+ uint64_t sf_noiocnt; /* times sendfile didn't require I/O */
uint64_t sf_iocnt; /* times sendfile had to do disk I/O */
+ uint64_t sf_pages_read; /* pages read as part of a request */
+ uint64_t sf_pages_valid; /* pages were valid for a request */
+ uint64_t sf_rhpages_requested; /* readahead pages requested */
+ uint64_t sf_rhpages_read; /* readahead pages read */
+ uint64_t sf_busy; /* times aborted on a busy page */
uint64_t sf_allocfail; /* times sfbuf allocation failed */
uint64_t sf_allocwait; /* times sfbuf allocation had to wait */
};
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 0e3e172..c6904f6 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -129,8 +129,8 @@ struct sockbuf {
#define M_BLOCKED M_PROTO2 /* M_NOTREADY in front of m */
#define M_NOTAVAIL (M_NOTREADY | M_BLOCKED)
-void sbappend(struct sockbuf *sb, struct mbuf *m);
-void sbappend_locked(struct sockbuf *sb, struct mbuf *m);
+void sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
+void sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
void sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags);
void sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
int sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 18e2de1..ee621d9 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -587,11 +587,14 @@ struct sf_hdtr {
* Sendfile-specific flag(s)
*/
#define SF_NODISKIO 0x00000001
-#define SF_MNOWAIT 0x00000002
+#define SF_MNOWAIT 0x00000002 /* obsolete */
#define SF_SYNC 0x00000004
+#define SF_NOCACHE 0x00000010
+#define SF_FLAGS(rh, flags) (((rh) << 16) | (flags))
#ifdef _KERNEL
#define SFK_COMPAT 0x00000001
+#define SF_READAHEAD(flags) ((flags) >> 16)
#endif /* _KERNEL */
#endif /* __BSD_VISIBLE */
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index d5b88eb..a79ff04 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -129,6 +129,7 @@ struct sysentvec {
void *sv_shared_page_obj;
void (*sv_schedtail)(struct thread *);
void (*sv_thread_detach)(struct thread *);
+ int (*sv_trap)(struct thread *);
};
#define SV_ILP32 0x000100 /* 32-bit executable. */
diff --git a/sys/vm/vm_domain.c b/sys/vm/vm_domain.c
index 83814d5..c042aa7 100644
--- a/sys/vm/vm_domain.c
+++ b/sys/vm/vm_domain.c
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_domain.h>
static __inline int
-vm_domain_rr_selectdomain(void)
+vm_domain_rr_selectdomain(int skip_domain)
{
#if MAXMEMDOM > 1
struct thread *td;
@@ -71,6 +71,16 @@ vm_domain_rr_selectdomain(void)
td->td_dom_rr_idx++;
td->td_dom_rr_idx %= vm_ndomains;
+
+ /*
+ * If skip_domain is provided then skip over that
+ * domain. This is intended for round robin variants
+ * which first try a fixed domain.
+ */
+ if ((skip_domain > -1) && (td->td_dom_rr_idx == skip_domain)) {
+ td->td_dom_rr_idx++;
+ td->td_dom_rr_idx %= vm_ndomains;
+ }
return (td->td_dom_rr_idx);
#else
return (0);
@@ -339,12 +349,12 @@ vm_domain_iterator_run(struct vm_domain_iterator *vi, int *domain)
if (vi->n == vm_ndomains)
*domain = vi->domain;
else
- *domain = vm_domain_rr_selectdomain();
+ *domain = vm_domain_rr_selectdomain(vi->domain);
vi->n--;
break;
case VM_POLICY_ROUND_ROBIN:
default:
- *domain = vm_domain_rr_selectdomain();
+ *domain = vm_domain_rr_selectdomain(-1);
vi->n--;
break;
}
diff --git a/tools/build/options/WITHOUT_LLVM_LIBUNWIND b/tools/build/options/WITHOUT_LLVM_LIBUNWIND
new file mode 100644
index 0000000..63a9042
--- /dev/null
+++ b/tools/build/options/WITHOUT_LLVM_LIBUNWIND
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to use GCC's stack unwinder (instead of LLVM's libunwind).
diff --git a/tools/build/options/WITH_LLVM_LIBUNWIND b/tools/build/options/WITH_LLVM_LIBUNWIND
new file mode 100644
index 0000000..ff63884
--- /dev/null
+++ b/tools/build/options/WITH_LLVM_LIBUNWIND
@@ -0,0 +1,2 @@
+.\" $FreeBSD$
+Set to use LLVM's libunwind stack unwinder (instead of GCC's unwinder).
diff --git a/tools/regression/geom_concat/conf.sh b/tools/regression/geom_concat/conf.sh
index c8692bb..374ed12 100644
--- a/tools/regression/geom_concat/conf.sh
+++ b/tools/regression/geom_concat/conf.sh
@@ -5,4 +5,11 @@ name="$(mktemp -u concat.XXXXXX)"
class="concat"
base=`basename $0`
+gconcat_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gconcat destroy $name
+ geom_test_cleanup
+}
+trap gconcat_test_cleanup ABRT EXIT INT TERM
+
. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_concat/test-1.t b/tools/regression/geom_concat/test-1.t
index 8984f79..ef80a61 100644
--- a/tools/regression/geom_concat/test-1.t
+++ b/tools/regression/geom_concat/test-1.t
@@ -5,13 +5,11 @@
echo '1..1'
-us=45
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 2M -u `expr $us + 1` || exit 1
-mdconfig -a -t malloc -s 3M -u `expr $us + 2` || exit 1
-
-gconcat create $name /dev/md${us} /dev/md`expr $us + 1` /dev/md`expr $us + 2` || exit 1
+gconcat create $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
devwait
# Size of created device should be 1MB + 2MB + 3MB.
@@ -23,8 +21,3 @@ if [ $size -eq 6291456 ]; then
else
echo "not ok - Size is 6291456"
fi
-
-gconcat destroy $name
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-mdconfig -d -u `expr $us + 2`
diff --git a/tools/regression/geom_concat/test-2.t b/tools/regression/geom_concat/test-2.t
index 445d9bc..95636be 100644
--- a/tools/regression/geom_concat/test-2.t
+++ b/tools/regression/geom_concat/test-2.t
@@ -5,18 +5,17 @@
echo '1..1'
-us=45
tsize=6
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=1m count=$tsize >/dev/null 2>&1
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 2M -u `expr $us + 1` || exit 1
-mdconfig -a -t malloc -s 3M -u `expr $us + 2` || exit 1
+dd if=/dev/random of=${src} bs=1m count=$tsize >/dev/null 2>&1
-gconcat create $name /dev/md${us} /dev/md`expr $us + 1` /dev/md`expr $us + 2` || exit 1
+gconcat create $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
devwait
dd if=${src} of=/dev/concat/${name} bs=1m count=$tsize >/dev/null 2>&1
@@ -28,8 +27,4 @@ else
echo "ok - md5 checksum comparison"
fi
-gconcat destroy $name
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-mdconfig -d -u `expr $us + 2`
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_eli/attach-d.t b/tools/regression/geom_eli/attach-d.t
index 4c4789e..5d700b3 100644
--- a/tools/regression/geom_eli/attach-d.t
+++ b/tools/regression/geom_eli/attach-d.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..3"
@@ -34,5 +35,4 @@ else
echo "not ok 3"
fi
-mdconfig -d -u $no
rm -f $keyfile
diff --git a/tools/regression/geom_eli/conf.sh b/tools/regression/geom_eli/conf.sh
new file mode 100755
index 0000000..0646e83
--- /dev/null
+++ b/tools/regression/geom_eli/conf.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# $FreeBSD$
+
+class="eli"
+base=`basename $0`
+
+# We need to use linear probing in order to detect the first available md(4)
+# device instead of using mdconfig -a -t, because geli(8) attachs md(4) devices
+no=0
+while [ -c /dev/md$no ]; do
+ : $(( no += 1 ))
+done
+
+geli_test_cleanup()
+{
+ [ -c /dev/md${no}.eli ] && geli detach md${no}.eli
+ mdconfig -d -u $no
+}
+trap geli_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_eli/configure-b-B.t b/tools/regression/geom_eli/configure-b-B.t
index 23aa412..b6cdf4f 100644
--- a/tools/regression/geom_eli/configure-b-B.t
+++ b/tools/regression/geom_eli/configure-b-B.t
@@ -1,8 +1,9 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
@@ -126,5 +127,3 @@ if [ $? -eq 0 ]; then
else
echo "not ok 17"
fi
-
-mdconfig -d -u $no
diff --git a/tools/regression/geom_eli/delkey.t b/tools/regression/geom_eli/delkey.t
index a828622..67b253e 100644
--- a/tools/regression/geom_eli/delkey.t
+++ b/tools/regression/geom_eli/delkey.t
@@ -1,13 +1,14 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile1=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile2=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile3=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile4=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
+keyfile3=`mktemp $base.XXXXXX` || exit 1
+keyfile4=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..14"
@@ -136,5 +137,4 @@ else
echo "not ok 14"
fi
-mdconfig -d -u $no
rm -f $keyfile1 $keyfile2 $keyfile3 $keyfile4
diff --git a/tools/regression/geom_eli/detach-l.t b/tools/regression/geom_eli/detach-l.t
index dfa3269..605ae94 100644
--- a/tools/regression/geom_eli/detach-l.t
+++ b/tools/regression/geom_eli/detach-l.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..4"
@@ -40,5 +41,4 @@ else
echo "not ok 4"
fi
-mdconfig -d -u $no
rm -f $keyfile
diff --git a/tools/regression/geom_eli/init-B.t b/tools/regression/geom_eli/init-B.t
index 36ab873..3ba743c 100644
--- a/tools/regression/geom_eli/init-B.t
+++ b/tools/regression/geom_eli/init-B.t
@@ -1,11 +1,12 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
-backupfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
+backupfile=`mktemp $base.XXXXXX` || exit 1
echo "1..13"
@@ -99,8 +100,5 @@ if [ -c /dev/md${no}.eli ]; then
else
echo "not ok 13 - -B file"
fi
-geli detach md${no}
-rm -f $backupfile
-mdconfig -d -u $no
-rm -f $keyfile
+rm -f $backupfile $keyfile
diff --git a/tools/regression/geom_eli/init-J.t b/tools/regression/geom_eli/init-J.t
index 6f2862f..266a3d5 100644
--- a/tools/regression/geom_eli/init-J.t
+++ b/tools/regression/geom_eli/init-J.t
@@ -1,13 +1,14 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile0=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile1=`mktemp /tmp/$base.XXXXXX` || exit 1
-passfile0=`mktemp /tmp/$base.XXXXXX` || exit 1
-passfile1=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile0=`mktemp $base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+passfile0=`mktemp $base.XXXXXX` || exit 1
+passfile1=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..150"
@@ -122,5 +123,4 @@ for iter in -1 0 64; do
echo "ok ${i}"; i=$((i+1))
done
-mdconfig -d -u $no
rm -f ${keyfile0} ${keyfile1} ${passfile0} ${passfile1}
diff --git a/tools/regression/geom_eli/init-a.t b/tools/regression/geom_eli/init-a.t
index 87612a2..dbb24fe 100644
--- a/tools/regression/geom_eli/init-a.t
+++ b/tools/regression/geom_eli/init-a.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
echo "1..1380"
@@ -26,7 +27,7 @@ for cipher in aes:0 aes:128 aes:256 \
keylen=${cipher##*:}
for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do
for secsize in 512 1024 2048 4096 8192; do
- rnd=`mktemp /tmp/$base.XXXXXX` || exit 1
+ rnd=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
diff --git a/tools/regression/geom_eli/init-i-P.t b/tools/regression/geom_eli/init-i-P.t
index a06f9f8..1c59a97 100644
--- a/tools/regression/geom_eli/init-i-P.t
+++ b/tools/regression/geom_eli/init-i-P.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..1"
@@ -18,5 +19,4 @@ else
echo "not ok 1"
fi
-mdconfig -d -u $no
rm -f $keyfile
diff --git a/tools/regression/geom_eli/init.t b/tools/regression/geom_eli/init.t
index 6934443..71dd6e2 100644
--- a/tools/regression/geom_eli/init.t
+++ b/tools/regression/geom_eli/init.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
echo "1..460"
@@ -25,7 +26,7 @@ for cipher in aes:0 aes:128 aes:256 \
ealgo=${cipher%%:*}
keylen=${cipher##*:}
for secsize in 512 1024 2048 4096 8192; do
- rnd=`mktemp /tmp/$base.XXXXXX` || exit 1
+ rnd=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
diff --git a/tools/regression/geom_eli/integrity-copy.t b/tools/regression/geom_eli/integrity-copy.t
index b52730a..4c8efd3 100644
--- a/tools/regression/geom_eli/integrity-copy.t
+++ b/tools/regression/geom_eli/integrity-copy.t
@@ -1,11 +1,12 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
-sector=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
echo "1..5520"
diff --git a/tools/regression/geom_eli/integrity-data.t b/tools/regression/geom_eli/integrity-data.t
index 6975466..7ea7c96b 100644
--- a/tools/regression/geom_eli/integrity-data.t
+++ b/tools/regression/geom_eli/integrity-data.t
@@ -1,11 +1,12 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
-sector=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
echo "1..2760"
diff --git a/tools/regression/geom_eli/integrity-hmac.t b/tools/regression/geom_eli/integrity-hmac.t
index 33f6029..243eac9 100644
--- a/tools/regression/geom_eli/integrity-hmac.t
+++ b/tools/regression/geom_eli/integrity-hmac.t
@@ -1,11 +1,12 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
-sector=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
echo "1..2760"
diff --git a/tools/regression/geom_eli/kill.t b/tools/regression/geom_eli/kill.t
index 5c315f3..ccced9f 100644
--- a/tools/regression/geom_eli/kill.t
+++ b/tools/regression/geom_eli/kill.t
@@ -1,11 +1,12 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile1=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile2=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..9"
@@ -93,5 +94,4 @@ else
echo "not ok 9"
fi
-mdconfig -d -u $no
rm -f $keyfile1 $keyfile2
diff --git a/tools/regression/geom_eli/nokey.t b/tools/regression/geom_eli/nokey.t
index 19ef680..f32e1a4 100644
--- a/tools/regression/geom_eli/nokey.t
+++ b/tools/regression/geom_eli/nokey.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..8"
@@ -61,5 +62,4 @@ else
echo "not ok 8"
fi
-mdconfig -d -u $no
rm -f $keyfile
diff --git a/tools/regression/geom_eli/onetime-a.t b/tools/regression/geom_eli/onetime-a.t
index ab19301..4e26dfb 100644
--- a/tools/regression/geom_eli/onetime-a.t
+++ b/tools/regression/geom_eli/onetime-a.t
@@ -1,8 +1,9 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
echo "1..1380"
@@ -25,7 +26,7 @@ for cipher in aes:0 aes:128 aes:256 \
keylen=${cipher##*:}
for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 hmac/sha384 hmac/sha512; do
for secsize in 512 1024 2048 4096 8192; do
- rnd=`mktemp /tmp/$base.XXXXXX` || exit 1
+ rnd=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
geli onetime -a $aalgo -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null
diff --git a/tools/regression/geom_eli/onetime-d.t b/tools/regression/geom_eli/onetime-d.t
index d49cb64..51a6abb 100644
--- a/tools/regression/geom_eli/onetime-d.t
+++ b/tools/regression/geom_eli/onetime-d.t
@@ -1,8 +1,9 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
mdconfig -a -t malloc -s $sectors -u $no || exit 1
diff --git a/tools/regression/geom_eli/onetime.t b/tools/regression/geom_eli/onetime.t
index 3a7d67e..17061d0 100644
--- a/tools/regression/geom_eli/onetime.t
+++ b/tools/regression/geom_eli/onetime.t
@@ -1,8 +1,9 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
echo "1..460"
@@ -24,7 +25,7 @@ for cipher in aes:0 aes:128 aes:256 \
ealgo=${cipher%%:*}
keylen=${cipher##*:}
for secsize in 512 1024 2048 4096 8192; do
- rnd=`mktemp /tmp/$base.XXXXXX` || exit 1
+ rnd=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $secsize \* $sectors`b -u $no || exit 1
geli onetime -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null
diff --git a/tools/regression/geom_eli/readonly.t b/tools/regression/geom_eli/readonly.t
index 210a364..721ad62 100644
--- a/tools/regression/geom_eli/readonly.t
+++ b/tools/regression/geom_eli/readonly.t
@@ -1,10 +1,11 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-keyfile=`mktemp /tmp/$base.XXXXXX` || exit 1
+keyfile=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..11"
diff --git a/tools/regression/geom_eli/resize.t b/tools/regression/geom_eli/resize.t
index 86ee364..67d6291 100644
--- a/tools/regression/geom_eli/resize.t
+++ b/tools/regression/geom_eli/resize.t
@@ -1,7 +1,8 @@
-#! /bin/sh
-#
+#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
echo 1..27
BLK=512
@@ -22,8 +23,6 @@ setsize() {
# Initialise
-kldload geom_eli >/dev/null 2>&1
-
setsize 10 40 || echo -n "not "
echo ok $i - "Sized ${md}a to 10m"
i=$((i + 1))
@@ -145,6 +144,5 @@ echo ok $i - "Attached ${md}p1.eli"
i=$((i + 1))
geli detach ${md}p1.eli
-mdconfig -du$unit
rm tmp.*
diff --git a/tools/regression/geom_eli/setkey.t b/tools/regression/geom_eli/setkey.t
index 611471a..458100c 100644
--- a/tools/regression/geom_eli/setkey.t
+++ b/tools/regression/geom_eli/setkey.t
@@ -1,15 +1,16 @@
#!/bin/sh
# $FreeBSD$
+. $(dirname $0)/conf.sh
+
base=`basename $0`
-no=45
sectors=100
-rnd=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile1=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile2=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile3=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile4=`mktemp /tmp/$base.XXXXXX` || exit 1
-keyfile5=`mktemp /tmp/$base.XXXXXX` || exit 1
+rnd=`mktemp $base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
+keyfile3=`mktemp $base.XXXXXX` || exit 1
+keyfile4=`mktemp $base.XXXXXX` || exit 1
+keyfile5=`mktemp $base.XXXXXX` || exit 1
mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
echo "1..16"
@@ -152,5 +153,4 @@ else
echo "not ok 16"
fi
-mdconfig -d -u $no
rm -f $keyfile1 $keyfile2 $keyfile3 $keyfile4 $keyfile5
diff --git a/tools/regression/geom_gate/Makefile b/tools/regression/geom_gate/Makefile
deleted file mode 100644
index c5c24ad..0000000
--- a/tools/regression/geom_gate/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# $FreeBSD$
-#
-# Regression tests for geom_gate.
-#
-
-test:
- @sh runtests.sh
diff --git a/tools/regression/geom_gate/runtests.sh b/tools/regression/geom_gate/runtests.sh
deleted file mode 100644
index 38089c5..0000000
--- a/tools/regression/geom_gate/runtests.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-dir=`dirname $0`
-
-for ts in `dirname $0`/test-*.sh; do
- sh $ts
-done
diff --git a/tools/regression/geom_gate/test-1.sh b/tools/regression/geom_gate/test-1.sh
deleted file mode 100644
index 44a4960..0000000
--- a/tools/regression/geom_gate/test-1.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-base=`basename $0`
-us=45
-work="/dev/md${us}"
-src="/dev/md`expr $us + 1`"
-conf=`mktemp /tmp/$base.XXXXXX` || exit 1
-
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 1M -u `expr $us + 1` || exit 1
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`cat $src | md5 -q`
-
-echo "127.0.0.1 RW $work" > $conf
-ggated $conf
-ggatec create -u $us 127.0.0.1 $work
-
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
-
-if [ `cat $work | md5 -q` != $sum ]; then
- echo "FAIL"
-else
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo "FAIL"
- else
- echo "PASS"
- fi
-fi
-
-ggatec destroy -u $us
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-pkill ggated $conf
-rm -f $conf
diff --git a/tools/regression/geom_gate/test-1.t b/tools/regression/geom_gate/test-1.t
index 279e316..83f6096 100644
--- a/tools/regression/geom_gate/test-1.t
+++ b/tools/regression/geom_gate/test-1.t
@@ -1,40 +1,62 @@
#!/bin/sh
# $FreeBSD$
-base=`basename $0`
-us=45
-work="/dev/md${us}"
-src="/dev/md`expr $us + 1`"
-conf=`mktemp /tmp/$base.XXXXXX` || exit 1
-
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 1M -u `expr $us + 1` || exit 1
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`cat $src | md5 -q`
+. `dirname $0`/conf.sh
-echo "127.0.0.1 RW $work" > $conf
-ggated $conf
-ggatec create -u $us 127.0.0.1 $work
+echo '1..2'
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
+base=`basename $0`
+us=0
+while [ -c /dev/ggate${us} ]; do
+ : $(( us += 1 ))
+done
+conf=`mktemp $base.XXXXXX` || exit 1
+pidfile=/var/run/ggated.pid
+port=33080
+
+work=$(attach_md -t malloc -s 1M)
+src=$(attach_md -t malloc -s 1M)
+
+test_cleanup()
+{
+ ggatec destroy -f -u $us
+ pkill -F $pidfile
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
+
+dd if=/dev/random of=/dev/$work bs=1m count=1 conv=sync
+dd if=/dev/random of=/dev/$src bs=1m count=1 conv=sync
+src_checksum=$(md5 -q /dev/$src)
+
+echo "127.0.0.1 RW /dev/$work" > $conf
+
+if ! ggated -p $port $conf; then
+ echo 'ggated failed to start'
+ echo 'Bail out!'
+ exit 1
+fi
+sleep 1
+if ! ggatec create -p $port -u $us 127.0.0.1 /dev/$work; then
+ echo 'ggatec create failed'
+ echo 'Bail out!'
+ exit 1
+fi
-echo '1..2'
+dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1
+sleep 1
-if [ `cat $work | md5 -q` != $sum ]; then
- echo 'not ok 1 - md5 checksum'
+work_checksum=$(md5 -q /dev/$work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum)"
+ echo "not ok 2 # SKIP"
else
echo 'ok 1 - md5 checksum'
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo 'not ok 2 - md5 checksum'
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
else
echo 'ok 2 - md5 checksum'
fi
fi
-
-ggatec destroy -u $us
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-pkill ggated $conf
-rm -f $conf
diff --git a/tools/regression/geom_gate/test-2.sh b/tools/regression/geom_gate/test-2.sh
deleted file mode 100644
index 498ac45..0000000
--- a/tools/regression/geom_gate/test-2.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-base=`basename $0`
-us=45
-work=`mktemp /tmp/$base.XXXXXX` || exit 1
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`md5 -q $src`
-
-ggatel create -u $us $work
-
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
-
-if [ `md5 -q $work` != $sum ]; then
- echo "FAIL"
-else
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo "FAIL"
- else
- echo "PASS"
- fi
-fi
-
-ggatel destroy -u $us
-rm -f $work $src
diff --git a/tools/regression/geom_gate/test-2.t b/tools/regression/geom_gate/test-2.t
index 2e5e254..be89acc 100644
--- a/tools/regression/geom_gate/test-2.t
+++ b/tools/regression/geom_gate/test-2.t
@@ -1,31 +1,48 @@
#!/bin/sh
# $FreeBSD$
+. `dirname $0`/conf.sh
+
base=`basename $0`
-us=45
-work=`mktemp /tmp/$base.XXXXXX` || exit 1
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
+us=46
+work=`mktemp -u $base.XXXXXX` || exit 1
+src=`mktemp -u $base.XXXXXX` || exit 1
+
+test_cleanup()
+{
+ ggatel destroy -f -u $us
+ rm -f $work $src
+
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`md5 -q $src`
+dd if=/dev/random of=$work bs=1m count=1 conv=sync
+dd if=/dev/random of=$src bs=1m count=1 conv=sync
-ggatel create -u $us $work
+if ! ggatel create -u $us $work; then
+ echo 'ggatel create failed'
+ echo 'Bail out!'
+ exit 1
+fi
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
+dd if=${src} of=/dev/ggate${us} bs=1m count=1
+sleep 1
echo '1..2'
-if [ `md5 -q $work` != $sum ]; then
- echo 'not ok 1 - md5 checksum'
+src_checksum=$(md5 -q $src)
+work_checksum=$(md5 -q $work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum) # TODO: bug 204616"
+ echo 'not ok 2 # SKIP'
else
echo 'ok 1 - md5 checksum'
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo 'not ok 2 - md5 checksum'
+
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
else
echo 'ok 2 - md5 checksum'
fi
fi
-
-ggatel destroy -u $us
-rm -f $work $src
diff --git a/tools/regression/geom_gate/test-3.sh b/tools/regression/geom_gate/test-3.sh
deleted file mode 100644
index ca73a5a..0000000
--- a/tools/regression/geom_gate/test-3.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-base=`basename $0`
-us=45
-work="/dev/md${us}"
-src="/dev/md`expr $us + 1`"
-
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 1M -u `expr $us + 1` || exit 1
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`cat $src | md5 -q`
-
-ggatel create -u $us $work
-
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
-
-if [ `cat $work | md5 -q` != $sum ]; then
- echo "FAIL"
-else
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo "FAIL"
- else
- echo "PASS"
- fi
-fi
-
-ggatel destroy -u $us
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
diff --git a/tools/regression/geom_gate/test-3.t b/tools/regression/geom_gate/test-3.t
index ba2b3c7..8901aca 100644
--- a/tools/regression/geom_gate/test-3.t
+++ b/tools/regression/geom_gate/test-3.t
@@ -1,34 +1,48 @@
#!/bin/sh
# $FreeBSD$
+. `dirname $0`/conf.sh
+
base=`basename $0`
-us=45
-work="/dev/md${us}"
-src="/dev/md`expr $us + 1`"
+us=47
+
+test_cleanup()
+{
+ ggatel destroy -f -u $us
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 1M -u `expr $us + 1` || exit 1
-dd if=/dev/random of=$work bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/random of=$src bs=1m count=1 >/dev/null 2>&1
-sum=`cat $src | md5 -q`
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
-ggatel create -u $us $work
+work=$(attach_md -t malloc -s 1M)
+src=$(attach_md -t malloc -s 1M)
-dd if=${src} of=/dev/ggate${us} bs=1m count=1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/$work bs=1m count=1 conv=sync
+dd if=/dev/random of=/dev/$src bs=1m count=1 conv=sync
+src_checksum=$(md5 -q /dev/$src)
+
+if ! ggatel create -u $us /dev/$work; then
+ echo 'ggatel create failed'
+ echo 'Bail out!'
+ exit 1
+fi
+
+dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1 conv=sync
+sleep 1
echo '1..2'
-if [ `cat $work | md5 -q` != $sum ]; then
- echo 'not ok 1 - md5 checksum'
+work_checksum=$(md5 -q /dev/$work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum)"
+ echo 'not ok 2 # SKIP'
else
echo 'ok 1 - md5 checksum'
- if [ `cat /dev/ggate${us} | md5 -q` != $sum ]; then
- echo 'not ok 2 - md5 checksum'
+
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
else
echo 'ok 2 - md5 checksum'
fi
fi
-
-ggatel destroy -u $us
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
diff --git a/tools/regression/geom_nop/conf.sh b/tools/regression/geom_nop/conf.sh
index 0dc9797..e38e10c 100644
--- a/tools/regression/geom_nop/conf.sh
+++ b/tools/regression/geom_nop/conf.sh
@@ -4,4 +4,11 @@
class="nop"
base=`basename $0`
+gnop_test_cleanup()
+{
+ [ -c /dev/${us}.nop ] && gnop destroy ${us}.nop
+ geom_test_cleanup
+}
+trap gnop_test_cleanup ABRT EXIT INT TERM
+
. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_nop/test-1.t b/tools/regression/geom_nop/test-1.t
index f08f71d..4d6b65d 100644
--- a/tools/regression/geom_nop/test-1.t
+++ b/tools/regression/geom_nop/test-1.t
@@ -5,21 +5,16 @@
echo "1..1"
-us=45
+us=$(attach_md -t malloc -s 1M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-
-gnop create /dev/md${us} || exit 1
+gnop create /dev/${us} || exit 1
# Size of created device should be 1MB.
-size=`diskinfo /dev/md${us}.nop | awk '{print $3}'`
+size=`diskinfo /dev/${us}.nop | awk '{print $3}'`
if [ $size -eq 1048576 ]; then
echo "ok 1"
else
echo "not ok 1"
fi
-
-gnop destroy md${us}.nop
-mdconfig -d -u $us
diff --git a/tools/regression/geom_nop/test-2.t b/tools/regression/geom_nop/test-2.t
index e0ddb17..7422345 100644
--- a/tools/regression/geom_nop/test-2.t
+++ b/tools/regression/geom_nop/test-2.t
@@ -3,20 +3,19 @@
. `dirname $0`/conf.sh
-us=45
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
echo "1..1"
dd if=/dev/random of=${src} bs=1m count=1 >/dev/null 2>&1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
+us=$(attach_md -t malloc -s 1M) || exit 1
-gnop create /dev/md${us} || exit 1
+gnop create /dev/${us} || exit 1
-dd if=${src} of=/dev/md${us}.nop bs=1m count=1 >/dev/null 2>&1
-dd if=/dev/md${us}.nop of=${dst} bs=1m count=1 >/dev/null 2>&1
+dd if=${src} of=/dev/${us}.nop bs=1m count=1 >/dev/null 2>&1
+dd if=/dev/${us}.nop of=${dst} bs=1m count=1 >/dev/null 2>&1
if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
echo "not ok 1"
@@ -24,6 +23,4 @@ else
echo "ok 1"
fi
-gnop destroy md${us}.nop
-mdconfig -d -u $us
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/conf.sh b/tools/regression/geom_raid3/conf.sh
index ff6485c..f1b270a 100644
--- a/tools/regression/geom_raid3/conf.sh
+++ b/tools/regression/geom_raid3/conf.sh
@@ -5,4 +5,11 @@ name="$(mktemp -u graid3.XXXXXX)"
class="raid3"
base=`basename $0`
+graid3_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && graid3 stop $name
+ geom_test_cleanup
+}
+trap graid3_test_cleanup ABRT EXIT INT TERM
+
. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_raid3/test-1.t b/tools/regression/geom_raid3/test-1.t
index 9202967..4c0b4a2 100644
--- a/tools/regression/geom_raid3/test-1.t
+++ b/tools/regression/geom_raid3/test-1.t
@@ -5,15 +5,11 @@
echo "1..2"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us0 || exit 1
-mdconfig -a -t malloc -s 2M -u $us1 || exit 1
-mdconfig -a -t malloc -s 3M -u $us2 || exit 1
-
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} 2>/dev/null || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} 2>/dev/null || exit 1
devwait
# Size of created device should be 2MB - 1024B.
@@ -30,8 +26,3 @@ if [ $sectorsize -eq 1024 ]; then
else
echo "not ok 2"
fi
-
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
diff --git a/tools/regression/geom_raid3/test-10.t b/tools/regression/geom_raid3/test-10.t
index 1320120..edd827d 100644
--- a/tools/regression/geom_raid3/test-10.t
+++ b/tools/regression/geom_raid3/test-10.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label -r $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label -r $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -32,8 +29,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-11.t b/tools/regression/geom_raid3/test-11.t
index 3382214..0407261 100644
--- a/tools/regression/geom_raid3/test-11.t
+++ b/tools/regression/geom_raid3/test-11.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label -w $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label -w $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -32,8 +29,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-12.t b/tools/regression/geom_raid3/test-12.t
index 3dec406..10533c6 100644
--- a/tools/regression/geom_raid3/test-12.t
+++ b/tools/regression/geom_raid3/test-12.t
@@ -5,31 +5,28 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
nblocks1=9
nblocks2=`expr $nblocks1 - 1`
nblocks3=`expr $nblocks2 / 2`
-mdconfig -a -t malloc -s $nblocks1 -u $us0 || exit 1
-mdconfig -a -t malloc -s $nblocks1 -u $us1 || exit 1
-mdconfig -a -t malloc -s $nblocks1 -u $us2 || exit 1
+us0=$(attach_md -t malloc -s $nblocks1) || exit 1
+us1=$(attach_md -t malloc -s $nblocks1) || exit 1
+us2=$(attach_md -t malloc -s $nblocks1) || exit 1
-dd if=/dev/random of=/dev/md${us0} count=$nblocks1 >/dev/null 2>&1
-dd if=/dev/random of=/dev/md${us1} count=$nblocks1 >/dev/null 2>&1
-dd if=/dev/random of=/dev/md${us2} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us0} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us1} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us2} count=$nblocks1 >/dev/null 2>&1
-graid3 label -w $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label -w $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
# Wait for synchronization.
sleep 2
graid3 stop $name
# Break one component.
-dd if=/dev/random of=/dev/md${us1} count=$nblocks2 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us1} count=$nblocks2 >/dev/null 2>&1
# Provoke retaste of the rest components.
-true > /dev/md${us0}
-true > /dev/md${us2}
+true > /dev/${us0}
+true > /dev/${us2}
sleep 1
dd if=/dev/raid3/${name} of=/dev/null bs=1k count=$nblocks3 >/dev/null 2>&1
@@ -39,8 +36,3 @@ if [ $ec -eq 0 ]; then
else
echo "ok 1"
fi
-
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
diff --git a/tools/regression/geom_raid3/test-2.t b/tools/regression/geom_raid3/test-2.t
index 88daf78..22ebd38 100644
--- a/tools/regression/geom_raid3/test-2.t
+++ b/tools/regression/geom_raid3/test-2.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -32,8 +29,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-3.t b/tools/regression/geom_raid3/test-3.t
index d2c1a5f..f068b06 100644
--- a/tools/regression/geom_raid3/test-3.t
+++ b/tools/regression/geom_raid3/test-3.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -36,8 +33,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-4.t b/tools/regression/geom_raid3/test-4.t
index d437ec0..810f13d 100644
--- a/tools/regression/geom_raid3/test-4.t
+++ b/tools/regression/geom_raid3/test-4.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
#
@@ -36,8 +33,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-5.t b/tools/regression/geom_raid3/test-5.t
index ffd85f6..7bc8d42 100644
--- a/tools/regression/geom_raid3/test-5.t
+++ b/tools/regression/geom_raid3/test-5.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
#
@@ -36,8 +33,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-6.t b/tools/regression/geom_raid3/test-6.t
index 97b5503..20bf192 100644
--- a/tools/regression/geom_raid3/test-6.t
+++ b/tools/regression/geom_raid3/test-6.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -29,7 +26,7 @@ dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
# Rebuild of DATA component.
#
graid3 remove -n 1 $name
-dd if=/dev/zero of=/dev/md${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
graid3 insert -n 1 $name md${us1}
sleep 1
@@ -40,8 +37,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-7.t b/tools/regression/geom_raid3/test-7.t
index 3d89873..23666f8 100644
--- a/tools/regression/geom_raid3/test-7.t
+++ b/tools/regression/geom_raid3/test-7.t
@@ -5,22 +5,19 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
@@ -29,12 +26,12 @@ dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
# Rebuild of PARITY component.
#
graid3 remove -n 2 $name
-dd if=/dev/zero of=/dev/md${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
graid3 insert -n 2 $name md${us2}
sleep 1
# Remove DATA component, so PARITY component can be used while reading.
graid3 remove -n 1 $name
-dd if=/dev/zero of=/dev/md${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
@@ -43,8 +40,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-8.t b/tools/regression/geom_raid3/test-8.t
index b9621f4..2eb9b1a 100644
--- a/tools/regression/geom_raid3/test-8.t
+++ b/tools/regression/geom_raid3/test-8.t
@@ -5,29 +5,26 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
#
# Writing without DATA component and rebuild of DATA component.
#
graid3 remove -n 1 $name
-dd if=/dev/zero of=/dev/md${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
graid3 insert -n 1 $name md${us1}
sleep 1
@@ -39,8 +36,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_raid3/test-9.t b/tools/regression/geom_raid3/test-9.t
index 0695011..0ef010a 100644
--- a/tools/regression/geom_raid3/test-9.t
+++ b/tools/regression/geom_raid3/test-9.t
@@ -5,35 +5,32 @@
echo "1..1"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
ddbs=2048
nblocks1=1024
nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
-dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us0 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us1 || exit 1
-mdconfig -a -t malloc -s `expr $nblocks1 + 1` -u $us2 || exit 1
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
-graid3 label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
devwait
#
# Writing without PARITY component and rebuild of PARITY component.
#
graid3 remove -n 2 $name
-dd if=/dev/zero of=/dev/md${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
graid3 insert -n 2 $name md${us2}
sleep 1
# Remove DATA component, so PARITY component can be used while reading.
graid3 remove -n 1 $name
-dd if=/dev/zero of=/dev/md${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
@@ -42,8 +39,4 @@ else
echo "ok 1"
fi
-graid3 stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_shsec/conf.sh b/tools/regression/geom_shsec/conf.sh
index dc416db..7800eb7 100644
--- a/tools/regression/geom_shsec/conf.sh
+++ b/tools/regression/geom_shsec/conf.sh
@@ -5,4 +5,11 @@ name="$(mktemp -u shsec.XXXXXX)"
class="shsec"
base=`basename $0`
+shsec_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gshsec stop $name
+ geom_test_cleanup
+}
+trap shsec_test_cleanup ABRT EXIT INT TERM
+
. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_shsec/test-1.t b/tools/regression/geom_shsec/test-1.t
index 5cb5b4f..ab0bb37 100644
--- a/tools/regression/geom_shsec/test-1.t
+++ b/tools/regression/geom_shsec/test-1.t
@@ -5,15 +5,11 @@
echo "1..2"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us0 || exit 1
-mdconfig -a -t malloc -s 2M -u $us1 || exit 1
-mdconfig -a -t malloc -s 3M -u $us2 || exit 1
-
-gshsec label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} 2>/dev/null || exit 1
+gshsec label $name /dev/${us0} /dev/${us1} /dev/${us2} 2>/dev/null || exit 1
devwait
# Size of created device should be 1MB - 512B.
@@ -30,8 +26,3 @@ if [ $sectorsize -eq 512 ]; then
else
echo "not ok 2"
fi
-
-gshsec stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
diff --git a/tools/regression/geom_shsec/test-2.t b/tools/regression/geom_shsec/test-2.t
index 19a4e0a..9dfe36a 100644
--- a/tools/regression/geom_shsec/test-2.t
+++ b/tools/regression/geom_shsec/test-2.t
@@ -5,21 +5,18 @@
echo "1..4"
-us0=45
-us1=`expr $us0 + 1`
-us2=`expr $us0 + 2`
nblocks1=1024
nblocks2=`expr $nblocks1 + 1`
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
dd if=/dev/random of=${src} count=$nblocks1 >/dev/null 2>&1
-mdconfig -a -t malloc -s $nblocks2 -u $us0 || exit 1
-mdconfig -a -t malloc -s $nblocks2 -u $us1 || exit 1
-mdconfig -a -t malloc -s $nblocks2 -u $us2 || exit 1
+us0=$(attach_md -t malloc -s $nblocks2) || exit 1
+us1=$(attach_md -t malloc -s $nblocks2) || exit 1
+us2=$(attach_md -t malloc -s $nblocks2) || exit 1
-gshsec label $name /dev/md${us0} /dev/md${us1} /dev/md${us2} || exit 1
+gshsec label $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
devwait
dd if=${src} of=/dev/shsec/${name} count=$nblocks1 >/dev/null 2>&1
@@ -31,29 +28,25 @@ else
echo "ok 1"
fi
-dd if=/dev/md${us0} of=${dst} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/${us0} of=${dst} count=$nblocks1 >/dev/null 2>&1
if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
echo "not ok 2"
else
echo "ok 2"
fi
-dd if=/dev/md${us1} of=${dst} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/${us1} of=${dst} count=$nblocks1 >/dev/null 2>&1
if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
echo "not ok 3"
else
echo "ok 3"
fi
-dd if=/dev/md${us2} of=${dst} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/${us2} of=${dst} count=$nblocks1 >/dev/null 2>&1
if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
echo "not ok 4"
else
echo "ok 4"
fi
-gshsec stop $name
-mdconfig -d -u $us0
-mdconfig -d -u $us1
-mdconfig -d -u $us2
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_stripe/conf.sh b/tools/regression/geom_stripe/conf.sh
index 54a0c36..fd0f41c 100644
--- a/tools/regression/geom_stripe/conf.sh
+++ b/tools/regression/geom_stripe/conf.sh
@@ -5,4 +5,11 @@ name="$(mktemp -u stripe.XXXXXX)"
class="stripe"
base=`basename $0`
+gstripe_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gstripe destroy $name
+ geom_test_cleanup
+}
+trap gstripe_test_cleanup ABRT EXIT INT TERM
+
. `dirname $0`/../geom_subr.sh
diff --git a/tools/regression/geom_stripe/test-1.t b/tools/regression/geom_stripe/test-1.t
index 9b398f0..7923763 100644
--- a/tools/regression/geom_stripe/test-1.t
+++ b/tools/regression/geom_stripe/test-1.t
@@ -5,13 +5,11 @@
echo "1..1"
-us=45
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 2M -u `expr $us + 1` || exit 1
-mdconfig -a -t malloc -s 3M -u `expr $us + 2` || exit 1
-
-gstripe create -s 16384 $name /dev/md${us} /dev/md`expr $us + 1` /dev/md`expr $us + 2` || exit 1
+gstripe create -s 16384 $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
devwait
# Size of created device should be 1MB * 3.
@@ -23,8 +21,3 @@ if [ $size -eq 3145728 ]; then
else
echo "not ok 1"
fi
-
-gstripe destroy $name
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-mdconfig -d -u `expr $us + 2`
diff --git a/tools/regression/geom_stripe/test-2.t b/tools/regression/geom_stripe/test-2.t
index 73937f4..f6e11f5 100644
--- a/tools/regression/geom_stripe/test-2.t
+++ b/tools/regression/geom_stripe/test-2.t
@@ -5,18 +5,17 @@
echo "1..1"
-us=45
tsize=3
-src=`mktemp /tmp/$base.XXXXXX` || exit 1
-dst=`mktemp /tmp/$base.XXXXXX` || exit 1
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
dd if=/dev/random of=${src} bs=1m count=$tsize >/dev/null 2>&1
-mdconfig -a -t malloc -s 1M -u $us || exit 1
-mdconfig -a -t malloc -s 2M -u `expr $us + 1` || exit 1
-mdconfig -a -t malloc -s 3M -u `expr $us + 2` || exit 1
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
-gstripe create -s 8192 $name /dev/md${us} /dev/md`expr $us + 1` /dev/md`expr $us + 2` || exit 1
+gstripe create -s 8192 $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
devwait
dd if=${src} of=/dev/stripe/${name} bs=1m count=$tsize >/dev/null 2>&1
@@ -28,8 +27,4 @@ else
echo "ok 1"
fi
-gstripe destroy $name
-mdconfig -d -u $us
-mdconfig -d -u `expr $us + 1`
-mdconfig -d -u `expr $us + 2`
rm -f ${src} ${dst}
diff --git a/tools/regression/geom_subr.sh b/tools/regression/geom_subr.sh
index 58dc31d..b437183 100644
--- a/tools/regression/geom_subr.sh
+++ b/tools/regression/geom_subr.sh
@@ -1,13 +1,6 @@
#!/bin/sh
# $FreeBSD$
-if [ $(id -u) -ne 0 ]; then
- echo 'Tests must be run as root'
- echo 'Bail out!'
- exit 1
-fi
-kldstat -q -m g_${class} || geom ${class} load || exit 1
-
devwait()
{
while :; do
@@ -18,13 +11,6 @@ devwait()
done
}
-# Need to keep track of the test md devices to avoid the scenario where a test
-# failing will cause the other tests to bomb out, or a test failing will leave
-# a large number of md(4) devices lingering around
-: ${TMPDIR=/tmp}
-export TMPDIR
-TEST_MDS_FILE=$(mktemp ${TMPDIR}/test_mds.XXXXXX) || exit 1
-
attach_md()
{
local test_md
@@ -38,12 +24,37 @@ geom_test_cleanup()
{
local test_md
- if [ -f $TEST_MDS_FILE ]; then
+ if [ -f "$TEST_MDS_FILE" ]; then
while read test_md; do
# The "#" tells the TAP parser this is a comment
echo "# Removing test memory disk: $test_md"
mdconfig -d -u $test_md
done < $TEST_MDS_FILE
fi
- rm -f $TEST_MDS_FILE
+ rm -f "$TEST_MDS_FILE"
}
+
+if [ $(id -u) -ne 0 ]; then
+ echo 'Tests must be run as root'
+ echo 'Bail out!'
+ exit 1
+fi
+# If the geom class isn't already loaded, try loading it.
+if ! kldstat -q -m g_${class}; then
+ if ! geom ${class} load; then
+ echo "Could not load module for geom class=${class}"
+ echo 'Bail out!'
+ exit 1
+ fi
+fi
+
+# Need to keep track of the test md devices to avoid the scenario where a test
+# failing will cause the other tests to bomb out, or a test failing will leave
+# a large number of md(4) devices lingering around
+: ${TMPDIR=/tmp}
+export TMPDIR
+if ! TEST_MDS_FILE=$(mktemp ${TMPDIR}/test_mds.XXXXXX); then
+ echo 'Failed to create temporary file for tracking the test md(4) devices'
+ echo 'Bail out!'
+ exit 1
+fi
diff --git a/tools/regression/geom_uzip/Makefile b/tools/regression/geom_uzip/Makefile
index 6927ff1..3186ef6 100644
--- a/tools/regression/geom_uzip/Makefile
+++ b/tools/regression/geom_uzip/Makefile
@@ -9,7 +9,7 @@ ZIMAGE= ${IMAGE}.uzip
UZIMAGE= ${ZIMAGE}.uue
test:
- @sh runtests.sh
+ prove -rv ./test-1.t
image:
makefs -s 1048576 ${IMAGE} etalon
diff --git a/tools/regression/geom_uzip/conf.sh b/tools/regression/geom_uzip/conf.sh
new file mode 100755
index 0000000..9a22841
--- /dev/null
+++ b/tools/regression/geom_uzip/conf.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# $FreeBSD$
+
+class="uzip"
+base=`basename $0`
+
+uzip_test_cleanup()
+{
+ if [ -n "$mntpoint" ]; then
+ umount $mntpoint
+ rmdir $mntpoint
+ fi
+ geom_test_cleanup
+}
+trap uzip_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
+
+# NOTE: make sure $TMPDIR has been set by geom_subr.sh if unset [by kyua, etc]
+mntpoint=$(mktemp -d tmp.XXXXXX) || exit
diff --git a/tools/regression/geom_uzip/runtests.sh b/tools/regression/geom_uzip/runtests.sh
deleted file mode 100644
index 60e78b5..0000000
--- a/tools/regression/geom_uzip/runtests.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-
-dir=`dirname $0`
-
-for ts in `dirname $0`/test-*.sh; do
- sh $ts
-done
diff --git a/tools/regression/geom_uzip/test-1.sh b/tools/regression/geom_uzip/test-1.sh
deleted file mode 100644
index 7e8f168..0000000
--- a/tools/regression/geom_uzip/test-1.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-
-mntpoint="/mnt/test-1"
-
-#
-# prepare
-kldload geom_uzip
-uudecode test-1.img.uzip.uue
-num=`mdconfig -an -f test-1.img.uzip` || exit 1
-sleep 1
-
-#
-# mount
-mkdir -p "${mntpoint}"
-mount -o ro /dev/md${num}.uzip "${mntpoint}" || exit 1
-
-#
-# compare
-#cat "${mntpoint}/etalon.txt"
-diff -u etalon/etalon.txt "${mntpoint}/etalon.txt"
-if [ $? -eq 0 ]; then
- echo "PASS"
-else
- echo "FAIL"
-fi
-
-#
-# cleanup
-umount "${mntpoint}"
-rmdir "${mntpoint}"
-mdconfig -d -u ${num}
-sleep 1
-kldunload geom_uzip
diff --git a/tools/regression/geom_uzip/test-1.t b/tools/regression/geom_uzip/test-1.t
new file mode 100644
index 0000000..b156c06
--- /dev/null
+++ b/tools/regression/geom_uzip/test-1.t
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD$
+
+testsdir=$(dirname $0)
+. $testsdir/conf.sh
+
+echo "1..1"
+
+UUE=$testsdir/test-1.img.uzip.uue
+uudecode $UUE
+us0=$(attach_md -f $(basename $UUE .uue)) || exit 1
+sleep 1
+
+mount -o ro /dev/${us0}.uzip "${mntpoint}" || exit 1
+
+#cat "${mntpoint}/etalon.txt"
+diff -I '\$FreeBSD.*\$' -u $testsdir/etalon/etalon.txt "${mntpoint}/etalon.txt"
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
diff --git a/tools/regression/geom_uzip/test-2.sh b/tools/regression/geom_uzip/test-2.sh
deleted file mode 100644
index 8662827..0000000
--- a/tools/regression/geom_uzip/test-2.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-
-#
-# prepare
-kldload geom_uzip
-uudecode test-1.img.uzip.uue
-num=`mdconfig -an -f test-1.img.uzip` || exit 1
-sleep 1
-
-#
-# destroy
-kldunload geom_uzip
diff --git a/usr.bin/netstat/mbuf.c b/usr.bin/netstat/mbuf.c
index baf7a65..8b95ddd 100644
--- a/usr.bin/netstat/mbuf.c
+++ b/usr.bin/netstat/mbuf.c
@@ -326,13 +326,33 @@ mbpr(void *kvmd, u_long mbaddr)
kread_counters) != 0)
goto out;
+ xo_emit("{:sendfile-syscalls/%ju} {N:sendfile syscalls}\n",
+ (uintmax_t)sfstat.sf_syscalls);
+ xo_emit("{:sendfile-no-io/%ju} "
+ "{N:sendfile syscalls completed without I\\/O request}\n",
+ (uintmax_t)sfstat.sf_noiocnt);
+ xo_emit("{:sendfile-io-count/%ju} "
+ "{N:requests for I\\/O initiated by sendfile}\n",
+ (uintmax_t)sfstat.sf_iocnt);
+ xo_emit("{:sendfile-pages-sent/%ju} "
+ "{N:pages read by sendfile as part of a request}\n",
+ (uintmax_t)sfstat.sf_pages_read);
+ xo_emit("{:sendfile-pages-valid/%ju} "
+ "{N:pages were valid at time of a sendfile request}\n",
+ (uintmax_t)sfstat.sf_pages_valid);
+ xo_emit("{:sendfile-requested-readahead/%ju} "
+ "{N:pages were requested for read ahead by applications}\n",
+ (uintmax_t)sfstat.sf_rhpages_requested);
+ xo_emit("{:sendfile-readahead/%ju} "
+ "{N:pages were read ahead by sendfile}\n",
+ (uintmax_t)sfstat.sf_rhpages_read);
+ xo_emit("{:sendfile-busy-encounters/%ju} "
+ "{N:times sendfile encountered an already busy page}\n",
+ (uintmax_t)sfstat.sf_busy);
xo_emit("{:sfbufs-alloc-failed/%ju} {N:requests for sfbufs denied}\n",
(uintmax_t)sfstat.sf_allocfail);
xo_emit("{:sfbufs-alloc-wait/%ju} {N:requests for sfbufs delayed}\n",
(uintmax_t)sfstat.sf_allocwait);
- xo_emit("{:sfbufs-io-count/%ju} "
- "{N:requests for I\\/O initiated by sendfile}\n",
- (uintmax_t)sfstat.sf_iocnt);
out:
xo_close_container("mbuf-statistics");
memstat_mtl_free(mtlp);
diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c
index aa9b581..6f264a7 100644
--- a/usr.sbin/bhyve/pci_virtio_net.c
+++ b/usr.sbin/bhyve/pci_virtio_net.c
@@ -36,6 +36,10 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <machine/atomic.h>
#include <net/ethernet.h>
+#ifndef NETMAP_WITH_LIBS
+#define NETMAP_WITH_LIBS
+#endif
+#include <net/netmap_user.h>
#include <errno.h>
#include <fcntl.h>
@@ -133,6 +137,8 @@ struct pci_vtnet_softc {
struct mevent *vsc_mevp;
int vsc_tapfd;
+ struct nm_desc *vsc_nmd;
+
int vsc_rx_ready;
volatile int resetting; /* set and checked outside lock */
@@ -149,6 +155,10 @@ struct pci_vtnet_softc {
pthread_mutex_t tx_mtx;
pthread_cond_t tx_cond;
int tx_in_progress;
+
+ void (*pci_vtnet_rx)(struct pci_vtnet_softc *sc);
+ void (*pci_vtnet_tx)(struct pci_vtnet_softc *sc, struct iovec *iov,
+ int iovcnt, int len);
};
static void pci_vtnet_reset(void *);
@@ -371,14 +381,208 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
vq_endchains(vq, 1);
}
+static int
+pci_vtnet_netmap_writev(struct nm_desc *nmd, struct iovec *iov, int iovcnt)
+{
+ int r, i;
+ int len = 0;
+
+ for (r = nmd->cur_tx_ring; ; ) {
+ struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, r);
+ uint32_t cur, idx;
+ char *buf;
+
+ if (nm_ring_empty(ring)) {
+ r++;
+ if (r > nmd->last_tx_ring)
+ r = nmd->first_tx_ring;
+ if (r == nmd->cur_rx_ring)
+ break;
+ continue;
+ }
+ cur = ring->cur;
+ idx = ring->slot[cur].buf_idx;
+ buf = NETMAP_BUF(ring, idx);
+
+ for (i = 0; i < iovcnt; i++) {
+ memcpy(&buf[len], iov[i].iov_base, iov[i].iov_len);
+ len += iov[i].iov_len;
+ }
+ ring->slot[cur].len = len;
+ ring->head = ring->cur = nm_ring_next(ring, cur);
+ nmd->cur_tx_ring = r;
+ ioctl(nmd->fd, NIOCTXSYNC, NULL);
+ break;
+ }
+
+ return (len);
+}
+
+static inline int
+pci_vtnet_netmap_readv(struct nm_desc *nmd, struct iovec *iov, int iovcnt)
+{
+ int len = 0;
+ int i = 0;
+ int r;
+
+ for (r = nmd->cur_rx_ring; ; ) {
+ struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, r);
+ uint32_t cur, idx;
+ char *buf;
+ size_t left;
+
+ if (nm_ring_empty(ring)) {
+ r++;
+ if (r > nmd->last_rx_ring)
+ r = nmd->first_rx_ring;
+ if (r == nmd->cur_rx_ring)
+ break;
+ continue;
+ }
+ cur = ring->cur;
+ idx = ring->slot[cur].buf_idx;
+ buf = NETMAP_BUF(ring, idx);
+ left = ring->slot[cur].len;
+
+ for (i = 0; i < iovcnt && left > 0; i++) {
+ if (iov[i].iov_len > left)
+ iov[i].iov_len = left;
+ memcpy(iov[i].iov_base, &buf[len], iov[i].iov_len);
+ len += iov[i].iov_len;
+ left -= iov[i].iov_len;
+ }
+ ring->head = ring->cur = nm_ring_next(ring, cur);
+ nmd->cur_rx_ring = r;
+ ioctl(nmd->fd, NIOCRXSYNC, NULL);
+ break;
+ }
+ for (; i < iovcnt; i++)
+ iov[i].iov_len = 0;
+
+ return (len);
+}
+
+/*
+ * Called to send a buffer chain out to the vale port
+ */
+static void
+pci_vtnet_netmap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt,
+ int len)
+{
+ static char pad[60]; /* all zero bytes */
+
+ if (sc->vsc_nmd == NULL)
+ return;
+
+ /*
+ * If the length is < 60, pad out to that and add the
+ * extra zero'd segment to the iov. It is guaranteed that
+ * there is always an extra iov available by the caller.
+ */
+ if (len < 60) {
+ iov[iovcnt].iov_base = pad;
+ iov[iovcnt].iov_len = 60 - len;
+ iovcnt++;
+ }
+ (void) pci_vtnet_netmap_writev(sc->vsc_nmd, iov, iovcnt);
+}
+
static void
-pci_vtnet_tap_callback(int fd, enum ev_type type, void *param)
+pci_vtnet_netmap_rx(struct pci_vtnet_softc *sc)
+{
+ struct iovec iov[VTNET_MAXSEGS], *riov;
+ struct vqueue_info *vq;
+ void *vrx;
+ int len, n;
+ uint16_t idx;
+
+ /*
+ * Should never be called without a valid netmap descriptor
+ */
+ assert(sc->vsc_nmd != NULL);
+
+ /*
+ * But, will be called when the rx ring hasn't yet
+ * been set up or the guest is resetting the device.
+ */
+ if (!sc->vsc_rx_ready || sc->resetting) {
+ /*
+ * Drop the packet and try later.
+ */
+ (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf);
+ return;
+ }
+
+ /*
+ * Check for available rx buffers
+ */
+ vq = &sc->vsc_queues[VTNET_RXQ];
+ if (!vq_has_descs(vq)) {
+ /*
+ * Drop the packet and try later. Interrupt on
+ * empty, if that's negotiated.
+ */
+ (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf);
+ vq_endchains(vq, 1);
+ return;
+ }
+
+ do {
+ /*
+ * Get descriptor chain.
+ */
+ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
+ assert(n >= 1 && n <= VTNET_MAXSEGS);
+
+ /*
+ * Get a pointer to the rx header, and use the
+ * data immediately following it for the packet buffer.
+ */
+ vrx = iov[0].iov_base;
+ riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen);
+
+ len = pci_vtnet_netmap_readv(sc->vsc_nmd, riov, n);
+
+ if (len == 0) {
+ /*
+ * No more packets, but still some avail ring
+ * entries. Interrupt if needed/appropriate.
+ */
+ vq_endchains(vq, 0);
+ return;
+ }
+
+ /*
+ * The only valid field in the rx packet header is the
+ * number of buffers if merged rx bufs were negotiated.
+ */
+ memset(vrx, 0, sc->rx_vhdrlen);
+
+ if (sc->rx_merge) {
+ struct virtio_net_rxhdr *vrxh;
+
+ vrxh = vrx;
+ vrxh->vrh_bufs = 1;
+ }
+
+ /*
+ * Release this chain and handle more chains.
+ */
+ vq_relchain(vq, idx, len + sc->rx_vhdrlen);
+ } while (vq_has_descs(vq));
+
+ /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */
+ vq_endchains(vq, 1);
+}
+
+static void
+pci_vtnet_rx_callback(int fd, enum ev_type type, void *param)
{
struct pci_vtnet_softc *sc = param;
pthread_mutex_lock(&sc->rx_mtx);
sc->rx_in_progress = 1;
- pci_vtnet_tap_rx(sc);
+ sc->pci_vtnet_rx(sc);
sc->rx_in_progress = 0;
pthread_mutex_unlock(&sc->rx_mtx);
@@ -421,7 +625,7 @@ pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq)
}
DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n));
- pci_vtnet_tap_tx(sc, &iov[1], n - 1, plen);
+ sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen);
/* chain is processed, release it and set tlen */
vq_relchain(vq, idx, tlen);
@@ -532,6 +736,67 @@ pci_vtnet_parsemac(char *mac_str, uint8_t *mac_addr)
return (0);
}
+static void
+pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname)
+{
+ char tbuf[80];
+
+ strcpy(tbuf, "/dev/");
+ strlcat(tbuf, devname, sizeof(tbuf));
+
+ sc->pci_vtnet_rx = pci_vtnet_tap_rx;
+ sc->pci_vtnet_tx = pci_vtnet_tap_tx;
+
+ sc->vsc_tapfd = open(tbuf, O_RDWR);
+ if (sc->vsc_tapfd == -1) {
+ WPRINTF(("open of tap device %s failed\n", tbuf));
+ return;
+ }
+
+ /*
+ * Set non-blocking and register for read
+ * notifications with the event loop
+ */
+ int opt = 1;
+ if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) {
+ WPRINTF(("tap device O_NONBLOCK failed\n"));
+ close(sc->vsc_tapfd);
+ sc->vsc_tapfd = -1;
+ }
+
+ sc->vsc_mevp = mevent_add(sc->vsc_tapfd,
+ EVF_READ,
+ pci_vtnet_rx_callback,
+ sc);
+ if (sc->vsc_mevp == NULL) {
+ WPRINTF(("Could not register event\n"));
+ close(sc->vsc_tapfd);
+ sc->vsc_tapfd = -1;
+ }
+}
+
+static void
+pci_vtnet_netmap_setup(struct pci_vtnet_softc *sc, char *ifname)
+{
+ sc->pci_vtnet_rx = pci_vtnet_netmap_rx;
+ sc->pci_vtnet_tx = pci_vtnet_netmap_tx;
+
+ sc->vsc_nmd = nm_open(ifname, NULL, 0, 0);
+ if (sc->vsc_nmd == NULL) {
+ WPRINTF(("open of netmap device %s failed\n", ifname));
+ return;
+ }
+
+ sc->vsc_mevp = mevent_add(sc->vsc_nmd->fd,
+ EVF_READ,
+ pci_vtnet_rx_callback,
+ sc);
+ if (sc->vsc_mevp == NULL) {
+ WPRINTF(("Could not register event\n"));
+ nm_close(sc->vsc_nmd);
+ sc->vsc_nmd = NULL;
+ }
+}
static int
pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
@@ -567,8 +832,8 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
*/
mac_provided = 0;
sc->vsc_tapfd = -1;
+ sc->vsc_nmd = NULL;
if (opts != NULL) {
- char tbuf[80];
int err;
devname = vtopts = strdup(opts);
@@ -583,36 +848,13 @@ pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
mac_provided = 1;
}
- strcpy(tbuf, "/dev/");
- strlcat(tbuf, devname, sizeof(tbuf));
+ if (strncmp(devname, "vale", 4) == 0)
+ pci_vtnet_netmap_setup(sc, devname);
+ if (strncmp(devname, "tap", 3) == 0 ||
+ strncmp(devname, "vmnet", 5) == 0)
+ pci_vtnet_tap_setup(sc, devname);
free(devname);
-
- sc->vsc_tapfd = open(tbuf, O_RDWR);
- if (sc->vsc_tapfd == -1) {
- WPRINTF(("open of tap device %s failed\n", tbuf));
- } else {
- /*
- * Set non-blocking and register for read
- * notifications with the event loop
- */
- int opt = 1;
- if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) {
- WPRINTF(("tap device O_NONBLOCK failed\n"));
- close(sc->vsc_tapfd);
- sc->vsc_tapfd = -1;
- }
-
- sc->vsc_mevp = mevent_add(sc->vsc_tapfd,
- EVF_READ,
- pci_vtnet_tap_callback,
- sc);
- if (sc->vsc_mevp == NULL) {
- WPRINTF(("Could not register event\n"));
- close(sc->vsc_tapfd);
- sc->vsc_tapfd = -1;
- }
- }
}
/*
diff --git a/usr.sbin/bsdconfig/share/dialog.subr b/usr.sbin/bsdconfig/share/dialog.subr
index d7c2d2c..1e63aec 100644
--- a/usr.sbin/bsdconfig/share/dialog.subr
+++ b/usr.sbin/bsdconfig/share/dialog.subr
@@ -1605,7 +1605,6 @@ f_dialog_pause()
$height $width
else
[ $duration -gt 0 ] && duration=$(( $duration - 1 ))
- [ $duration -gt 1 ] && duration=$(( $duration - 1 ))
height=$(( $height + 3 )) # Add height for progress bar
$DIALOG \
--title "$DIALOG_TITLE" \
diff --git a/usr.sbin/ntp/scripts/mkver b/usr.sbin/ntp/scripts/mkver
index 2bc36b5..6a99756 100755
--- a/usr.sbin/ntp/scripts/mkver
+++ b/usr.sbin/ntp/scripts/mkver
@@ -6,7 +6,7 @@ PROG=${1-UNKNOWN}
ConfStr="$PROG"
-ConfStr="$ConfStr 4.2.8p4"
+ConfStr="$ConfStr 4.2.8p5"
case "$CSET" in
'') ;;
OpenPOWER on IntegriCloud