diff options
author | Renato Botelho <renato@netgate.com> | 2015-11-11 11:08:21 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-11-11 11:08:21 -0200 |
commit | 4119672798028ff673a738690b48575973689004 (patch) | |
tree | 6a05ea1f50fa6610fe798bbf45852d32a83ab41a | |
parent | 5e6268df600406a1570e822ac652576059d820e3 (diff) | |
parent | 2867f2c1d4795c2446a1c1d0b30db57d3aaca364 (diff) | |
download | FreeBSD-src-4119672798028ff673a738690b48575973689004.zip FreeBSD-src-4119672798028ff673a738690b48575973689004.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
73 files changed, 1846 insertions, 1183 deletions
diff --git a/bin/dd/Makefile b/bin/dd/Makefile index eb8ec85..db6e854 100644 --- a/bin/dd/Makefile +++ b/bin/dd/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 # $FreeBSD$ +.include <bsd.own.mk> + PROG= dd SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c @@ -24,4 +26,8 @@ test: ${PROG} gen .endfor @rm -f gen +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.prog.mk> diff --git a/bin/dd/tests/Makefile b/bin/dd/tests/Makefile new file mode 100644 index 0000000..f87af65 --- /dev/null +++ b/bin/dd/tests/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H} +SRCTOP= ${.CURDIR:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/bin/dd +TESTSDIR= ${TESTSBASE}/bin/dd + +NETBSD_ATF_TESTS_SH= dd_test + +.include <netbsd-tests.test.mk> + +.include <bsd.test.mk> diff --git a/bin/rm/rm.1 b/bin/rm/rm.1 index 824b627..a0e7754 100644 --- a/bin/rm/rm.1 +++ b/bin/rm/rm.1 @@ -32,7 +32,7 @@ .\" @(#)rm.1 8.5 (Berkeley) 12/5/94 .\" $FreeBSD$ .\" -.Dd April 25, 2013 +.Dd November 7, 2015 .Dt RM 1 .Os .Sh NAME @@ -235,7 +235,7 @@ not the standard error output. The .Nm command conforms to -.St -p1003.2 . +.St -p1003.1-2013 . .Pp The simplified .Nm unlink diff --git a/bin/rm/rm.c b/bin/rm/rm.c index d91af54..7beae2d 100644 --- a/bin/rm/rm.c +++ b/bin/rm/rm.c @@ -155,8 +155,7 @@ main(int argc, char *argv[]) } checkdot(argv); - if (getenv("POSIXLY_CORRECT") == NULL) - checkslash(argv); + checkslash(argv); uid = geteuid(); (void)signal(SIGINFO, siginfo); diff --git a/contrib/netbsd-tests/bin/dd/t_dd.sh b/contrib/netbsd-tests/bin/dd/t_dd.sh index d713ad9..62379c2 100755 --- a/contrib/netbsd-tests/bin/dd/t_dd.sh +++ b/contrib/netbsd-tests/bin/dd/t_dd.sh @@ -44,6 +44,12 @@ length_head() { "the one expected to fail. (NetBSD PR bin/8521)" } length_body() { + # Begin FreeBSD + if ! df /dev/fd | grep -q '^fdescfs'; then + atf_skip "fdescfs is not mounted on /dev/fd" + fi + # End FreeBSD + test_dd_length 512 \ "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >/dev/null 2>/dev/null" test_dd_length 512 \ diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c index 7e8bff6..30e9c1e 100644 --- a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c +++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c @@ -46,7 +46,6 @@ main(int argc, char *argv[]) { #ifdef __FreeBSD__ char b[512], *sl; - int n; size_t len = atoi(argv[1]); sl = malloc(len); memset(sl, 'a', len); @@ -54,7 +53,7 @@ main(int argc, char *argv[]) unlink("symlink"); if (symlink(sl, "symlink") == -1) err(1, "symlink()"); - n = readlink("symlink", b, len); + (void)readlink("symlink", b, len); unlink("symlink"); #else char b[MAXPATHLEN]; diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 76df3ca..d0a7ca5 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -10,6 +10,8 @@ .. date .. + dd + .. expr .. ls @@ -107,6 +109,8 @@ data .. .. + rpc + .. ssp .. stdio @@ -232,6 +236,8 @@ unlink .. .. + posixshm + .. vfs .. vm @@ -398,6 +404,8 @@ .. fstyp .. + makefs + .. newsyslog .. nmtree diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c index cb13d71..104d8c5 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c @@ -72,7 +72,6 @@ kgdb_trgt_fetch_registers(int regno __unused) supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); - amd64_supply_fxsave(current_regcache, -1, (struct fpusave *)(&pcb + 1)); } void diff --git a/include/stdio.h b/include/stdio.h index 6d7916a..d37ea06 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -144,6 +144,7 @@ struct __sFILE { int _fl_count; /* recursive lock count */ int _orientation; /* orientation for fwide() */ __mbstate_t _mbstate; /* multibyte conversion state */ + int _flags2; /* additional flags */ }; #ifndef _STDFILE_DECLARED #define _STDFILE_DECLARED @@ -176,6 +177,8 @@ __END_DECLS #define __SALC 0x4000 /* allocate string space dynamically */ #define __SIGN 0x8000 /* ignore this file in _fwalk */ +#define __S2OAP 0x0001 /* O_APPEND mode is set */ + /* * The following three definitions are for ANSI C, which took them * from System V, which brilliantly took internal interface macros and diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index f9480c3..cc4a235 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -659,14 +659,13 @@ __getgroupmembership(const char *uname, gid_t agroup, gid_t *groups, NS_FALLBACK_CB(getgroupmembership_fallback) { NULL, NULL, NULL } }; - int rv; assert(uname != NULL); /* groups may be NULL if just sizing when invoked with maxgrp = 0 */ assert(grpcnt != NULL); *grpcnt = 0; - rv = _nsdispatch(NULL, dtab, NSDB_GROUP, "getgroupmembership", + (void)_nsdispatch(NULL, dtab, NSDB_GROUP, "getgroupmembership", defaultsrc, uname, agroup, groups, maxgrp, grpcnt); /* too many groups found? */ diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c index 2e19b9f..e5d167a 100644 --- a/lib/libc/stdio/fdopen.c +++ b/lib/libc/stdio/fdopen.c @@ -90,7 +90,9 @@ fdopen(int fd, const char *mode) * O_APPEND bit set, assert __SAPP so that __swrite() caller * will _sseek() to the end before write. */ - if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) + if (fdflags & O_APPEND) + fp->_flags2 |= __S2OAP; + else if (oflags & O_APPEND) fp->_flags |= __SAPP; fp->_file = fd; fp->_cookie = fp; diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index be196b7..12d3659 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -155,6 +155,7 @@ found: /* fp->_fl_mutex = NULL; */ /* once set always set (reused) */ fp->_orientation = 0; memset(&fp->_mbstate, 0, sizeof(mbstate_t)); + fp->_flags2 = 0; return (fp); } diff --git a/lib/libc/stdio/fmemopen.c b/lib/libc/stdio/fmemopen.c index ebd3596..bcf187d 100644 --- a/lib/libc/stdio/fmemopen.c +++ b/lib/libc/stdio/fmemopen.c @@ -149,6 +149,9 @@ fmemopen(void * __restrict buf, size_t size, const char * __restrict mode) return (NULL); } + if (mode[0] == 'a') + f->_flags |= __SAPP; + /* * Turn off buffering, so a write past the end of the buffer * correctly returns a short object count. diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c index b08e336..9ab61ba 100644 --- a/lib/libc/stdio/fopen.c +++ b/lib/libc/stdio/fopen.c @@ -91,7 +91,9 @@ fopen(const char * __restrict file, const char * __restrict mode) * we can do about this. (We could set __SAPP and check in * fseek and ftell.) */ - if (oflags & O_APPEND) + if (oflags & O_APPEND) { + fp->_flags2 |= __S2OAP; (void)_sseek(fp, (fpos_t)0, SEEK_END); + } return (fp); } diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c index bf3f030..58227fa 100644 --- a/lib/libc/stdio/freopen.c +++ b/lib/libc/stdio/freopen.c @@ -186,6 +186,7 @@ finish: fp->_lb._size = 0; fp->_orientation = 0; memset(&fp->_mbstate, 0, sizeof(mbstate_t)); + fp->_flags2 = 0; if (f < 0) { /* did not get it after all */ if (isopen) @@ -239,8 +240,10 @@ finish: * we can do about this. (We could set __SAPP and check in * fseek and ftell.) */ - if (oflags & O_APPEND) + if (oflags & O_APPEND) { + fp->_flags2 |= __S2OAP; (void) _sseek(fp, (fpos_t)0, SEEK_END); + } FUNLOCKFILE(fp); return (fp); } diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c index 745d500..152617f 100644 --- a/lib/libc/stdio/ftell.c +++ b/lib/libc/stdio/ftell.c @@ -88,7 +88,6 @@ _ftello(FILE *fp, fpos_t *offset) { fpos_t pos; size_t n; - int dflags; if (fp->_seek == NULL) { errno = ESPIPE; /* historic practice */ @@ -119,29 +118,33 @@ _ftello(FILE *fp, fpos_t *offset) } if (HASUB(fp)) pos -= fp->_r; /* Can be negative at this point. */ - } else if ((fp->_flags & __SWR) && fp->_p != NULL) { - dflags = 0; - if (fp->_flags & __SAPP) - dflags = O_APPEND; - else if (fp->_file != -1 && - (dflags = _fcntl(fp->_file, F_GETFL)) < 0) - return (1); - if ((dflags & O_APPEND) && - (pos = _sseek(fp, (fpos_t)0, SEEK_END)) == -1) { - if ((fp->_flags & __SOPT) || __sflush(fp) || - (pos = _sseek(fp, (fpos_t)0, SEEK_CUR)) == -1) - return (1); - else { - *offset = pos; - return (0); - } - } + } else if ((fp->_flags & __SWR) && fp->_p != NULL && + (n = fp->_p - fp->_bf._base) > 0) { /* * Writing. Any buffered characters cause the * position to be greater than that in the * underlying object. */ - n = fp->_p - fp->_bf._base; + if ((fp->_flags & __SAPP) || (fp->_flags2 & __S2OAP)) { + int serrno = errno; + + errno = 0; + if ((pos = _sseek(fp, (fpos_t)0, SEEK_END)) == -1) { + if (errno == ESPIPE || + (fp->_flags & __SOPT) || __sflush(fp) || + (pos = + _sseek(fp, (fpos_t)0, SEEK_CUR)) == -1) + return (1); + else { + errno = serrno; + *offset = pos; + return (0); + } + } + errno = serrno; + /* fp->_p can be changed in _sseek(), recalculate. */ + n = fp->_p - fp->_bf._base; + } if (pos > OFF_MAX - n) { errno = EOVERFLOW; return (1); diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c index 44ee0ab..5d6fb9a 100644 --- a/lib/libc/stdio/stdio.c +++ b/lib/libc/stdio/stdio.c @@ -117,7 +117,7 @@ _swrite(FILE *fp, char const *buf, int n) ret = (*fp->_write)(fp->_cookie, buf, n); /* __SOFF removed even on success in case O_APPEND mode is set. */ if (ret >= 0) { - if ((fp->_flags & (__SAPP|__SOFF)) == (__SAPP|__SOFF) && + if ((fp->_flags & __SOFF) && !(fp->_flags2 & __S2OAP) && fp->_offset <= OFF_MAX - ret) fp->_offset += ret; else diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2 index 5c93438..a94e314 100644 --- a/lib/libc/sys/ptrace.2 +++ b/lib/libc/sys/ptrace.2 @@ -2,7 +2,7 @@ .\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $ .\" .\" This file is in the public domain. -.Dd October 6, 2015 +.Dd October 20, 2015 .Dt PTRACE 2 .Os .Sh NAME @@ -306,7 +306,7 @@ struct ptrace_lwpinfo { sigset_t pl_siglist; siginfo_t pl_siginfo; char pl_tdname[MAXCOMLEN + 1]; - int pl_child_pid; + pid_t pl_child_pid; u_int pl_syscall_code; u_int pl_syscall_narg; }; diff --git a/lib/libc/tests/Makefile b/lib/libc/tests/Makefile index ad523aa..bf5bf25 100644 --- a/lib/libc/tests/Makefile +++ b/lib/libc/tests/Makefile @@ -13,6 +13,7 @@ TESTS_SUBDIRS+= hash TESTS_SUBDIRS+= inet TESTS_SUBDIRS+= net TESTS_SUBDIRS+= regex +TESTS_SUBDIRS+= rpc TESTS_SUBDIRS+= stdio TESTS_SUBDIRS+= stdlib TESTS_SUBDIRS+= string diff --git a/sbin/camcontrol/modeedit.c b/sbin/camcontrol/modeedit.c index 00ab974..8262c3c 100644 --- a/sbin/camcontrol/modeedit.c +++ b/sbin/camcontrol/modeedit.c @@ -246,7 +246,7 @@ editentry_set(char *name, char *newvalue, int editonly) * currently workaround it (even for int64's), so we have to kludge it. */ #define RESOLUTION_MAX(size) ((resolution * (size) == 32)? \ - (int)0xffffffff: (1 << (resolution * (size))) - 1) + INT_MAX: (1 << (resolution * (size))) - 1) assert(newvalue != NULL); if (*newvalue == '\0') diff --git a/secure/lib/libcrypto/engines/libgost/Makefile b/secure/lib/libcrypto/engines/libgost/Makefile index ad718fa..47ab05b 100644 --- a/secure/lib/libcrypto/engines/libgost/Makefile +++ b/secure/lib/libcrypto/engines/libgost/Makefile @@ -3,6 +3,7 @@ SHLIB_NAME?= libgost.so SRCS= gost2001.c gost2001_keyx.c gost89.c gost94_keyx.c gost_ameth.c \ gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gost_keywrap.c \ - gost_md.c gost_params.c gost_pmeth.c gost_sign.c gosthash.c + gost_md.c gost_params.c gost_pmeth.c gost_sign.c gosthash.c \ + e_gost_err.c .include <bsd.lib.mk> diff --git a/share/misc/scsi_modes b/share/misc/scsi_modes index 781b8f1..80752e7 100644 --- a/share/misc/scsi_modes +++ b/share/misc/scsi_modes @@ -106,7 +106,7 @@ {EBACKERR} t1 {LogErr} t1 {Reserved} *t4 - {MRIE} b4 + {MRIE} t4 {Interval Timer} i4 {Report Count} i4 } diff --git a/sys/boot/amd64/efi/copy.c b/sys/boot/amd64/efi/copy.c index c3cb475..cd8b6da 100644 --- a/sys/boot/amd64/efi/copy.c +++ b/sys/boot/amd64/efi/copy.c @@ -38,10 +38,10 @@ __FBSDID("$FreeBSD$"); #include <efilib.h> #ifndef EFI_STAGING_SIZE -#define EFI_STAGING_SIZE 32 +#define EFI_STAGING_SIZE 48 #endif -#define STAGE_PAGES ((EFI_STAGING_SIZE) * 1024 * 1024 / 4096) +#define STAGE_PAGES EFI_SIZE_TO_PAGES((EFI_STAGING_SIZE) * 1024 * 1024) EFI_PHYSICAL_ADDRESS staging, staging_end; int stage_offset_set = 0; @@ -59,7 +59,7 @@ x86_efi_copy_init(void) (unsigned long)(status & EFI_ERROR_MASK)); return (status); } - staging_end = staging + STAGE_PAGES * 4096; + staging_end = staging + STAGE_PAGES * EFI_PAGE_SIZE; return (0); } @@ -114,7 +114,7 @@ x86_efi_copy_finish(void) src = (uint64_t *)staging; dst = (uint64_t *)(staging - stage_offset); - last = (uint64_t *)(staging + STAGE_PAGES * EFI_PAGE_SIZE); + last = (uint64_t *)staging_end; while (src < last) *dst++ = *src++; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index 24d4744..06824f7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -2808,7 +2808,8 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *vs) vs->vs_rsize = vdev_get_min_asize(vd); if (vd->vdev_ops->vdev_op_leaf) vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE; - vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize; + if (vd->vdev_max_asize != 0) + vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize; vs->vs_configured_ashift = vd->vdev_top != NULL ? vd->vdev_top->vdev_ashift : vd->vdev_ashift; vs->vs_logical_ashift = vd->vdev_logical_ashift; diff --git a/sys/dev/drm2/i915/i915_gem_execbuffer.c b/sys/dev/drm2/i915/i915_gem_execbuffer.c index 5f0614c..9323844 100644 --- a/sys/dev/drm2/i915/i915_gem_execbuffer.c +++ b/sys/dev/drm2/i915/i915_gem_execbuffer.c @@ -939,13 +939,15 @@ i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) static int validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count, - vm_page_t ***map) + vm_page_t ***map, int **maplen) { vm_page_t *ma; int i, length, page_count; /* XXXKIB various limits checking is missing there */ *map = malloc(count * sizeof(*ma), DRM_I915_GEM, M_WAITOK | M_ZERO); + *maplen = malloc(count * sizeof(*maplen), DRM_I915_GEM, M_WAITOK | + M_ZERO); for (i = 0; i < count; i++) { /* First check for malicious input causing overflow */ if (exec[i].relocation_count > @@ -967,9 +969,10 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count, page_count = howmany(length, PAGE_SIZE) + 2; ma = (*map)[i] = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, M_WAITOK | M_ZERO); - if (vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, - exec[i].relocs_ptr, length, VM_PROT_READ | VM_PROT_WRITE, - ma, page_count) == -1) { + (*maplen)[i] = vm_fault_quick_hold_pages( + &curproc->p_vmspace->vm_map, exec[i].relocs_ptr, length, + VM_PROT_READ | VM_PROT_WRITE, ma, page_count); + if ((*maplen)[i] == -1) { free(ma, DRM_I915_GEM); (*map)[i] = NULL; return (-EFAULT); @@ -1121,6 +1124,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_clip_rect *cliprects = NULL; struct intel_ring_buffer *ring; vm_page_t **relocs_ma; + int *relocs_len; u32 ctx_id = i915_execbuffer2_get_context_id(*args); u32 exec_start, exec_len; u32 seqno; @@ -1135,7 +1139,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (args->batch_len == 0) return (0); - ret = validate_exec_list(exec, args->buffer_count, &relocs_ma); + ret = validate_exec_list(exec, args->buffer_count, &relocs_ma, + &relocs_len); if (ret != 0) goto pre_struct_lock_err; @@ -1149,7 +1154,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx_id != 0) { DRM_DEBUG("Ring %s doesn't support contexts\n", ring->name); - return -EPERM; + ret = -EPERM; + goto pre_struct_lock_err; } break; case I915_EXEC_BLT: @@ -1157,7 +1163,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ctx_id != 0) { DRM_DEBUG("Ring %s doesn't support contexts\n", ring->name); - return -EPERM; + ret = -EPERM; + goto pre_struct_lock_err; } break; default: @@ -1169,7 +1176,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (!intel_ring_initialized(ring)) { DRM_DEBUG("execbuf with invalid ring: %d\n", (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; + ret = -EINVAL; + goto pre_struct_lock_err; } mode = args->flags & I915_EXEC_CONSTANTS_MASK; @@ -1401,13 +1409,11 @@ err: pre_struct_lock_err: for (i = 0; i < args->buffer_count; i++) { if (relocs_ma[i] != NULL) { - vm_page_unhold_pages(relocs_ma[i], howmany( - exec[i].relocation_count * - sizeof(struct drm_i915_gem_relocation_entry), - PAGE_SIZE)); + vm_page_unhold_pages(relocs_ma[i], relocs_len[i]); free(relocs_ma[i], DRM_I915_GEM); } } + free(relocs_len, DRM_I915_GEM); free(relocs_ma, DRM_I915_GEM); free(cliprects, DRM_I915_GEM); return ret; diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index 744321b..14cf5ce 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -2559,6 +2559,7 @@ dwc_otg_interrupt_poll_locked(struct dwc_otg_softc *sc) struct usb_xfer *xfer; uint32_t count; uint32_t temp; + uint32_t haint; uint8_t got_rx_status; uint8_t x; @@ -2576,14 +2577,18 @@ repeat: DPRINTF("Yield\n"); return; } + /* get all host channel interrupts */ - for (x = 0; x != sc->sc_host_ch_max; x++) { + haint = DWC_OTG_READ_4(sc, DOTG_HAINT); + while (1) { + x = ffs(haint) - 1; + if (x >= sc->sc_host_ch_max) + break; temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x)); - if (temp != 0) { - DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp); - temp &= ~HCINT_SOFTWARE_ONLY; - sc->sc_chan_state[x].hcint |= temp; - } + DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp); + temp &= ~HCINT_SOFTWARE_ONLY; + sc->sc_chan_state[x].hcint |= temp; + haint &= ~(1U << x); } if (sc->sc_last_rx_status == 0) { diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 6649bc0..b107232 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -1381,6 +1381,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) /* check if we have a buffer */ if (m) { + m->m_len = m->m_pkthdr.len = temp + ETHER_ALIGN; m_adj(m, ETHER_ALIGN); usbd_copy_out(pc, offset, m->m_data, temp); diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c index fd7aec9..6509e78 100644 --- a/sys/dev/usb/net/if_urndis.c +++ b/sys/dev/usb/net/if_urndis.c @@ -848,7 +848,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) DPRINTF("invalid ethernet size " "%u < %u\n", msg.rm_datalen, (unsigned)sizeof(struct ether_header)); goto tr_setup; - } else if (msg.rm_datalen > (uint32_t)MCLBYTES) { + } else if (msg.rm_datalen > (uint32_t)(MCLBYTES - ETHER_ALIGN)) { ifp->if_ierrors++; DPRINTF("invalid ethernet size " "%u > %u\n", @@ -862,6 +862,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) /* check if we have a buffer */ if (m != NULL) { + m->m_len = m->m_pkthdr.len = msg.rm_datalen + ETHER_ALIGN; m_adj(m, ETHER_ALIGN); usbd_copy_out(pc, offset + msg.rm_dataoffset + diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index 58cd3e8..9386ada 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -158,9 +158,12 @@ IDTVEC(xmm) .type alltraps,@function alltraps: pushal - pushl %ds - pushl %es - pushl %fs + pushl $0 + movw %ds,(%esp) + pushl $0 + movw %es,(%esp) + pushl $0 + movw %fs,(%esp) alltraps_with_regs_pushed: SET_KERNEL_SREGS cld @@ -234,9 +237,12 @@ IDTVEC(lcall_syscall) pushl $7 /* sizeof "lcall 7,0" */ subl $4,%esp /* skip over tf_trapno */ pushal - pushl %ds - pushl %es - pushl %fs + pushl $0 + movw %ds,(%esp) + pushl $0 + movw %es,(%esp) + pushl $0 + movw %fs,(%esp) SET_KERNEL_SREGS cld FAKE_MCOUNT(TF_EIP(%esp)) @@ -260,9 +266,12 @@ IDTVEC(int0x80_syscall) pushl $2 /* sizeof "int 0x80" */ subl $4,%esp /* skip over tf_trapno */ pushal - pushl %ds - pushl %es - pushl %fs + pushl $0 + movw %ds,(%esp) + pushl $0 + movw %es,(%esp) + pushl $0 + movw %fs,(%esp) SET_KERNEL_SREGS cld FAKE_MCOUNT(TF_EIP(%esp)) @@ -417,13 +426,16 @@ doreti_iret: doreti_iret_fault: subl $8,%esp pushal - pushl %ds + pushl $0 + movw %ds,(%esp) .globl doreti_popl_ds_fault doreti_popl_ds_fault: - pushl %es + pushl $0 + movw %es,(%esp) .globl doreti_popl_es_fault doreti_popl_es_fault: - pushl %fs + pushl $0 + movw %fs,(%esp) .globl doreti_popl_fs_fault doreti_popl_fs_fault: sti diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h index c1c3f64..ef08d03 100644 --- a/sys/i386/include/asmacros.h +++ b/sys/i386/include/asmacros.h @@ -146,9 +146,12 @@ pushl $0 ; /* dummy error code */ \ pushl $0 ; /* dummy trap type */ \ pushal ; /* 8 ints */ \ - pushl %ds ; /* save data and extra segments ... */ \ - pushl %es ; \ - pushl %fs + pushl $0 ; /* save data and extra segments ... */ \ + movw %ds,(%esp) ; \ + pushl $0 ; \ + movw %es,(%esp) ; \ + pushl $0 ; \ + movw %fs,(%esp) #define POP_FRAME \ popl %fs ; \ diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 5efec4f..bbfe321 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -95,7 +95,7 @@ struct ptrace_lwpinfo32 { sigset_t pl_siglist; /* LWP pending signal */ struct siginfo32 pl_siginfo; /* siginfo for signal */ char pl_tdname[MAXCOMLEN + 1]; /* LWP name. */ - int pl_child_pid; /* New child pid */ + pid_t pl_child_pid; /* New child pid */ u_int pl_syscall_code; u_int pl_syscall_narg; }; @@ -938,25 +938,29 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) switch (req) { case PT_TO_SCE: p->p_stops |= S_PT_SCE; - CTR2(KTR_PTRACE, - "PT_TO_SCE: pid %d, stops = %#x", p->p_pid, - p->p_stops); + CTR4(KTR_PTRACE, + "PT_TO_SCE: pid %d, stops = %#x, PC = %#lx, sig = %d", + p->p_pid, p->p_stops, + (u_long)(uintfptr_t)addr, data); break; case PT_TO_SCX: p->p_stops |= S_PT_SCX; - CTR2(KTR_PTRACE, - "PT_TO_SCX: pid %d, stops = %#x", p->p_pid, - p->p_stops); + CTR4(KTR_PTRACE, + "PT_TO_SCX: pid %d, stops = %#x, PC = %#lx, sig = %d", + p->p_pid, p->p_stops, + (u_long)(uintfptr_t)addr, data); break; case PT_SYSCALL: p->p_stops |= S_PT_SCE | S_PT_SCX; - CTR2(KTR_PTRACE, - "PT_SYSCALL: pid %d, stops = %#x", p->p_pid, - p->p_stops); + CTR4(KTR_PTRACE, + "PT_SYSCALL: pid %d, stops = %#x, PC = %#lx, sig = %d", + p->p_pid, p->p_stops, + (u_long)(uintfptr_t)addr, data); break; case PT_CONTINUE: - CTR1(KTR_PTRACE, - "PT_CONTINUE: pid %d", p->p_pid); + CTR3(KTR_PTRACE, + "PT_CONTINUE: pid %d, PC = %#lx, sig = %d", + p->p_pid, (u_long)(uintfptr_t)addr, data); break; } break; @@ -979,11 +983,12 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) proc_reparent(p, pp); if (pp == initproc) p->p_sigparent = SIGCHLD; - CTR2(KTR_PTRACE, - "PT_DETACH: pid %d reparented to pid %d", - p->p_pid, pp->p_pid); + CTR3(KTR_PTRACE, + "PT_DETACH: pid %d reparented to pid %d, sig %d", + p->p_pid, pp->p_pid, data); } else - CTR1(KTR_PTRACE, "PT_DETACH: pid %d", p->p_pid); + CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d", + p->p_pid, data); p->p_oppid = 0; p->p_stops = 0; @@ -1236,10 +1241,10 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) if (wrap32) ptrace_lwpinfo_to32(pl, pl32); #endif - CTR5(KTR_PTRACE, - "PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d", + CTR6(KTR_PTRACE, + "PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d syscall %d", td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags, - pl->pl_child_pid); + pl->pl_child_pid, pl->pl_syscall_code); break; case PT_GETNUMLWPS: diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 5058080..b5f5b42 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -3836,17 +3836,20 @@ vn_isdisk(struct vnode *vp, int *errp) { int error; + if (vp->v_type != VCHR) { + error = ENOTBLK; + goto out; + } error = 0; dev_lock(); - if (vp->v_type != VCHR) - error = ENOTBLK; - else if (vp->v_rdev == NULL) + if (vp->v_rdev == NULL) error = ENXIO; else if (vp->v_rdev->si_devsw == NULL) error = ENXIO; else if (!(vp->v_rdev->si_devsw->d_flags & D_DISK)) error = ENOTBLK; dev_unlock(); +out: if (errp != NULL) *errp = error; return (error == 0); diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index f2a38c1..589fa3f 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -196,6 +196,8 @@ gif_clone_create(struct if_clone *ifc, int unit, caddr_t params) GIF2IFP(sc)->if_transmit = gif_transmit; GIF2IFP(sc)->if_qflush = gif_qflush; GIF2IFP(sc)->if_output = gif_output; + GIF2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + GIF2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(GIF2IFP(sc)); bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int32_t)); if (ng_gif_attach_p != NULL) @@ -1038,10 +1040,13 @@ gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) #if defined(INET) || defined(INET6) bad: #endif - if (error == 0 && sc->gif_family != 0) + if (error == 0 && sc->gif_family != 0) { ifp->if_drv_flags |= IFF_DRV_RUNNING; - else + if_link_state_change(ifp, LINK_STATE_UP); + } else { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); + } return (error); } @@ -1063,4 +1068,5 @@ gif_delete_tunnel(struct ifnet *ifp) free(sc->gif_hdr, M_GIF); } ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 3e2d826..17a324c 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -179,6 +179,8 @@ gre_clone_create(struct if_clone *ifc, int unit, caddr_t params) GRE2IFP(sc)->if_ioctl = gre_ioctl; GRE2IFP(sc)->if_transmit = gre_transmit; GRE2IFP(sc)->if_qflush = gre_qflush; + GRE2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + GRE2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(GRE2IFP(sc)); bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t)); GRE_LIST_LOCK(); @@ -648,8 +650,10 @@ gre_set_tunnel(struct ifnet *ifp, struct sockaddr *src, break; #endif } - if (error == 0) + if (error == 0) { ifp->if_drv_flags |= IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_UP); + } return (error); } @@ -668,6 +672,7 @@ gre_delete_tunnel(struct ifnet *ifp) free(sc->gre_hdr, M_GRE); } ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } int @@ -686,6 +691,14 @@ gre_input(struct mbuf **mp, int *offp, int proto) KASSERT(sc != NULL, ("encap_getarg returned NULL")); ifp = GRE2IFP(sc); + hlen = *offp + sizeof(struct grehdr) + 4 * sizeof(uint32_t); + if (m->m_pkthdr.len < hlen) + goto drop; + if (m->m_len < hlen) { + m = m_pullup(m, hlen); + if (m == NULL) + goto drop; + } gh = (struct grehdr *)mtodo(m, *offp); flags = ntohs(gh->gre_flags); if (flags & ~GRE_FLAGS_MASK) diff --git a/sys/net/if_me.c b/sys/net/if_me.c index 1e927a8..effb758 100644 --- a/sys/net/if_me.c +++ b/sys/net/if_me.c @@ -193,6 +193,8 @@ me_clone_create(struct if_clone *ifc, int unit, caddr_t params) ME2IFP(sc)->if_ioctl = me_ioctl; ME2IFP(sc)->if_transmit = me_transmit; ME2IFP(sc)->if_qflush = me_qflush; + ME2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE; + ME2IFP(sc)->if_capenable |= IFCAP_LINKSTATE; if_attach(ME2IFP(sc)); bpfattach(ME2IFP(sc), DLT_NULL, sizeof(u_int32_t)); ME_LIST_LOCK(); @@ -377,8 +379,10 @@ me_set_tunnel(struct ifnet *ifp, struct sockaddr_in *src, if (sc->me_ecookie == NULL) sc->me_ecookie = encap_attach_func(AF_INET, IPPROTO_MOBILE, me_encapcheck, &in_mobile_protosw, sc); - if (sc->me_ecookie != NULL) + if (sc->me_ecookie != NULL) { ifp->if_drv_flags |= IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_UP); + } return (0); } @@ -396,6 +400,7 @@ me_delete_tunnel(struct ifnet *ifp) sc->me_dst.s_addr = 0; ME_WUNLOCK(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + if_link_state_change(ifp, LINK_STATE_DOWN); } static uint16_t diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index d2aa188..8032e9f 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -687,8 +687,31 @@ nd6_timer(void *arg) goto addrloop; } } + } else if ((ia6->ia6_flags & IN6_IFF_TENTATIVE) != 0) { + /* + * Schedule DAD for a tentative address. This happens + * if the interface was down or not running + * when the address was configured. + */ + int delay; + + delay = arc4random() % + (MAX_RTR_SOLICITATION_DELAY * hz); + nd6_dad_start((struct ifaddr *)ia6, delay); } else { /* + * Check status of the interface. If it is down, + * mark the address as tentative for future DAD. + */ + if ((ia6->ia_ifp->if_flags & IFF_UP) == 0 || + (ia6->ia_ifp->if_drv_flags & IFF_DRV_RUNNING) + == 0 || + (ND_IFINFO(ia6->ia_ifp)->flags & + ND6_IFF_IFDISABLED) != 0) { + ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; + ia6->ia6_flags |= IN6_IFF_TENTATIVE; + } + /* * A new RA might have made a deprecated address * preferred. */ @@ -1341,7 +1364,8 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) /* Mark all IPv6 address as tentative. */ ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; - if ((ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) { + if (V_ip6_dad_count > 0 && + (ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) { IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 8f287dc..5232f8f 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -86,11 +86,11 @@ static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *); static void nd6_dad_add(struct dadq *dp); static void nd6_dad_del(struct dadq *dp); static void nd6_dad_rele(struct dadq *); -static void nd6_dad_starttimer(struct dadq *, int); +static void nd6_dad_starttimer(struct dadq *, int, int); static void nd6_dad_stoptimer(struct dadq *); static void nd6_dad_timer(struct dadq *); static void nd6_dad_duplicated(struct ifaddr *, struct dadq *); -static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); +static void nd6_dad_ns_output(struct dadq *); static void nd6_dad_ns_input(struct ifaddr *, struct nd_opt_nonce *); static void nd6_dad_na_input(struct ifaddr *); static void nd6_na_output_fib(struct ifnet *, const struct in6_addr *, @@ -1242,9 +1242,11 @@ nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *n) } static void -nd6_dad_starttimer(struct dadq *dp, int ticks) +nd6_dad_starttimer(struct dadq *dp, int ticks, int send_ns) { + if (send_ns != 0) + nd6_dad_ns_output(dp); callout_reset(&dp->dad_timer_ch, ticks, (void (*)(void *))nd6_dad_timer, (void *)dp); } @@ -1283,6 +1285,7 @@ nd6_dad_start(struct ifaddr *ifa, int delay) struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; struct dadq *dp; char ip6buf[INET6_ADDRSTRLEN]; + int send_ns; /* * If we don't need DAD, don't do it. @@ -1319,8 +1322,10 @@ nd6_dad_start(struct ifaddr *ifa, int delay) return; } if ((dp = nd6_dad_find(ifa, NULL)) != NULL) { - /* DAD already in progress */ - nd6_dad_rele(dp); + /* + * DAD already in progress. Let the existing entry + * to finish it. + */ return; } @@ -1353,13 +1358,12 @@ nd6_dad_start(struct ifaddr *ifa, int delay) dp->dad_ns_lcount = dp->dad_loopbackprobe = 0; refcount_init(&dp->dad_refcnt, 1); nd6_dad_add(dp); + send_ns = 0; if (delay == 0) { - nd6_dad_ns_output(dp, ifa); - nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); - } else { - nd6_dad_starttimer(dp, delay); + send_ns = 1; + delay = (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000; } + nd6_dad_starttimer(dp, delay, send_ns); } /* @@ -1429,7 +1433,8 @@ nd6_dad_timer(struct dadq *dp) if ((dp->dad_ns_tcount > V_dad_maxtry) && (((ifp->if_flags & IFF_UP) == 0) || ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))) { - nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", + nd6log((LOG_INFO, "%s: could not run DAD " + "because the interface was down or not running.\n", if_name(ifa->ifa_ifp))); goto err; } @@ -1439,9 +1444,8 @@ nd6_dad_timer(struct dadq *dp) /* * We have more NS to go. Send NS packet for DAD. */ - nd6_dad_ns_output(dp, ifa); nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000, 1); goto done; } else { /* @@ -1469,11 +1473,11 @@ nd6_dad_timer(struct dadq *dp) * Send an NS immediately and increase dad_count by * V_nd6_mmaxtries - 1. */ - nd6_dad_ns_output(dp, ifa); dp->dad_count = dp->dad_ns_ocount + V_nd6_mmaxtries - 1; nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000, + 1); goto done; } else { /* @@ -1562,10 +1566,10 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) } static void -nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) +nd6_dad_ns_output(struct dadq *dp) { - struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; - struct ifnet *ifp = ifa->ifa_ifp; + struct in6_ifaddr *ia = (struct in6_ifaddr *)dp->dad_ifa; + struct ifnet *ifp = dp->dad_ifa->ifa_ifp; int i; dp->dad_ns_tcount++; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index a535ddf..c4f1b9d 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6025,6 +6025,13 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, if (ifp->if_flags & IFF_LOOPBACK) m0->m_flags |= M_SKIP_FIREWALL; + if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6 & + ~ifp->if_hwassist) { + uint32_t plen = m0->m_pkthdr.len - sizeof(*ip6); + in6_delayed_cksum(m0, plen, sizeof(struct ip6_hdr)); + m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; + } + /* * If the packet is too large for the outgoing interface, * send back an icmp6 error. diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index de4e7a7..7135767 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -112,7 +112,7 @@ struct ptrace_lwpinfo { sigset_t pl_siglist; /* LWP pending signal */ struct __siginfo pl_siginfo; /* siginfo for signal */ char pl_tdname[MAXCOMLEN + 1]; /* LWP name */ - int pl_child_pid; /* New child pid */ + pid_t pl_child_pid; /* New child pid */ u_int pl_syscall_code; u_int pl_syscall_narg; }; diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index 9c33a7f..8551085 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -429,7 +429,9 @@ retry: brelse(bp); if (flags & BA_CLRBUF) { int seqcount = (flags & BA_SEQMASK) >> BA_SEQSHIFT; - if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { + if (seqcount != 0 && + (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0 && + !(vm_page_count_severe() || buf_dirty_count_severe())) { error = cluster_read(vp, ip->i_size, lbn, (int)fs->fs_bsize, NOCRED, MAXBSIZE, seqcount, gbflags, &nbp); @@ -998,7 +1000,9 @@ retry: */ if (flags & BA_CLRBUF) { int seqcount = (flags & BA_SEQMASK) >> BA_SEQSHIFT; - if (seqcount && (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { + if (seqcount != 0 && + (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0 && + !(vm_page_count_severe() || buf_dirty_count_severe())) { error = cluster_read(vp, ip->i_size, lbn, (int)fs->fs_bsize, NOCRED, MAXBSIZE, seqcount, gbflags, &nbp); diff --git a/tests/sys/Makefile b/tests/sys/Makefile index 0f20aa6..a22214a 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -12,6 +12,7 @@ TESTS_SUBDIRS+= kqueue TESTS_SUBDIRS+= mqueue TESTS_SUBDIRS+= netinet TESTS_SUBDIRS+= opencrypto +TESTS_SUBDIRS+= posixshm TESTS_SUBDIRS+= vfs TESTS_SUBDIRS+= vm diff --git a/tests/sys/posixshm/Makefile b/tests/sys/posixshm/Makefile new file mode 100644 index 0000000..2acdfa4 --- /dev/null +++ b/tests/sys/posixshm/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/sys/posixshm + +ATF_TESTS_C+= posixshm_test + +.include <bsd.test.mk> diff --git a/tests/sys/posixshm/posixshm_test.c b/tests/sys/posixshm/posixshm_test.c new file mode 100644 index 0000000..b1a7c08 --- /dev/null +++ b/tests/sys/posixshm/posixshm_test.c @@ -0,0 +1,629 @@ +/*- + * Copyright (c) 2006 Robert N. M. Watson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#define TEST_PATH_LEN 256 +static char test_path[TEST_PATH_LEN]; + +static void +gen_test_path(void) +{ + char *tmpdir = getenv("TMPDIR"); + + if (tmpdir == NULL) + tmpdir = "/tmp"; + + snprintf(test_path, sizeof(test_path), "%s/tmp.XXXXXX", tmpdir); + test_path[sizeof(test_path) - 1] = '\0'; + ATF_REQUIRE_MSG(mkstemp(test_path) != -1, + "mkstemp failed; errno=%d", errno); + ATF_REQUIRE_MSG(unlink(test_path) == 0, + "unlink failed; errno=%d", errno); +} + +/* + * Attempt a shm_open() that should fail with an expected error of 'error'. + */ +static void +shm_open_should_fail(const char *path, int flags, mode_t mode, int error) +{ + int fd; + + fd = shm_open(path, flags, mode); + ATF_CHECK_MSG(fd == -1, "shm_open didn't fail"); + ATF_CHECK_MSG(error == errno, + "shm_open didn't fail with expected errno; errno=%d; expected " + "errno=%d", errno, error); +} + +/* + * Attempt a shm_unlink() that should fail with an expected error of 'error'. + */ +static void +shm_unlink_should_fail(const char *path, int error) +{ + + ATF_CHECK_MSG(shm_unlink(path) == -1, "shm_unlink didn't fail"); + ATF_CHECK_MSG(error == errno, + "shm_unlink didn't fail with expected errno; errno=%d; expected " + "errno=%d", errno, error); +} + +/* + * Open the test object and write '1' to the first byte. Returns valid fd + * on success and -1 on failure. + */ +static int +scribble_object(void) +{ + char *page; + int fd; + + gen_test_path(); + + fd = shm_open(test_path, O_CREAT|O_EXCL|O_RDWR, 0777); + if (fd < 0 && errno == EEXIST) { + if (shm_unlink(test_path) < 0) + atf_tc_fail("shm_unlink"); + fd = shm_open(test_path, O_CREAT | O_EXCL | O_RDWR, 0777); + } + if (fd < 0) + atf_tc_fail("shm_open failed; errno=%d", errno); + if (ftruncate(fd, getpagesize()) < 0) + atf_tc_fail("ftruncate failed; errno=%d", errno); + + page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, + 0); + if (page == MAP_FAILED) + atf_tc_fail("mmap failed; errno=%d", errno); + + page[0] = '1'; + if (munmap(page, getpagesize()) < 0) + atf_tc_fail("munmap failed; errno=%d", errno); + + return (fd); +} + +ATF_TC_WITHOUT_HEAD(remap_object); +ATF_TC_BODY(remap_object, tc) +{ + char *page; + int fd; + + fd = scribble_object(); + + page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, + 0); + if (page == MAP_FAILED) + atf_tc_fail("mmap(2) failed; errno=%d", errno); + + if (page[0] != '1') + atf_tc_fail("missing data ('%c' != '1')", page[0]); + + close(fd); + if (munmap(page, getpagesize()) < 0) + atf_tc_fail("munmap failed; errno=%d", errno); + + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, + "shm_unlink failed; errno=%d", errno); +} + +ATF_TC_WITHOUT_HEAD(reopen_object); +ATF_TC_BODY(reopen_object, tc) +{ + char *page; + int fd; + + fd = scribble_object(); + close(fd); + + fd = shm_open(test_path, O_RDONLY, 0777); + if (fd < 0) + atf_tc_fail("shm_open(2) failed; errno=%d", errno); + + page = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0); + if (page == MAP_FAILED) + atf_tc_fail("mmap(2) failed; errno=%d", errno); + + if (page[0] != '1') + atf_tc_fail("missing data ('%c' != '1')", page[0]); + + munmap(page, getpagesize()); + close(fd); + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, + "shm_unlink failed; errno=%d", errno); +} + +ATF_TC_WITHOUT_HEAD(readonly_mmap_write); +ATF_TC_BODY(readonly_mmap_write, tc) +{ + char *page; + int fd; + + gen_test_path(); + + fd = shm_open(test_path, O_RDONLY | O_CREAT, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); + + /* PROT_WRITE should fail with EACCES. */ + page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, + 0); + if (page != MAP_FAILED) + atf_tc_fail("mmap(PROT_WRITE) succeeded unexpectedly"); + + if (errno != EACCES) + atf_tc_fail("mmap(PROT_WRITE) didn't fail with EACCES; " + "errno=%d", errno); + + close(fd); + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, + "shm_unlink failed; errno=%d", errno); +} + +ATF_TC_WITHOUT_HEAD(open_after_link); +ATF_TC_BODY(open_after_link, tc) +{ + int fd; + + gen_test_path(); + + fd = shm_open(test_path, O_RDONLY | O_CREAT, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open(1) failed; errno=%d", errno); + close(fd); + + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, "shm_unlink failed: %d", + errno); + + shm_open_should_fail(test_path, O_RDONLY, 0777, ENOENT); +} + +ATF_TC_WITHOUT_HEAD(open_invalid_path); +ATF_TC_BODY(open_invalid_path, tc) +{ + + shm_open_should_fail("blah", O_RDONLY, 0777, EINVAL); +} + +ATF_TC_WITHOUT_HEAD(open_write_only); +ATF_TC_BODY(open_write_only, tc) +{ + + gen_test_path(); + + shm_open_should_fail(test_path, O_WRONLY, 0777, EINVAL); +} + +ATF_TC_WITHOUT_HEAD(open_extra_flags); +ATF_TC_BODY(open_extra_flags, tc) +{ + + gen_test_path(); + + shm_open_should_fail(test_path, O_RDONLY | O_DIRECT, 0777, EINVAL); +} + +ATF_TC_WITHOUT_HEAD(open_anon); +ATF_TC_BODY(open_anon, tc) +{ + int fd; + + fd = shm_open(SHM_ANON, O_RDWR, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); + close(fd); +} + +ATF_TC_WITHOUT_HEAD(open_anon_readonly); +ATF_TC_BODY(open_anon_readonly, tc) +{ + + shm_open_should_fail(SHM_ANON, O_RDONLY, 0777, EINVAL); +} + +ATF_TC_WITHOUT_HEAD(open_bad_path_pointer); +ATF_TC_BODY(open_bad_path_pointer, tc) +{ + + shm_open_should_fail((char *)1024, O_RDONLY, 0777, EFAULT); +} + +ATF_TC_WITHOUT_HEAD(open_path_too_long); +ATF_TC_BODY(open_path_too_long, tc) +{ + char *page; + + page = malloc(MAXPATHLEN + 1); + memset(page, 'a', MAXPATHLEN); + page[MAXPATHLEN] = '\0'; + shm_open_should_fail(page, O_RDONLY, 0777, ENAMETOOLONG); + free(page); +} + +ATF_TC_WITHOUT_HEAD(open_nonexisting_object); +ATF_TC_BODY(open_nonexisting_object, tc) +{ + + shm_open_should_fail("/notreallythere", O_RDONLY, 0777, ENOENT); +} + +ATF_TC_WITHOUT_HEAD(open_create_existing_object); +ATF_TC_BODY(open_create_existing_object, tc) +{ + int fd; + + gen_test_path(); + + fd = shm_open(test_path, O_RDONLY|O_CREAT, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open failed; errno=%d", errno); + close(fd); + + shm_open_should_fail(test_path, O_RDONLY|O_CREAT|O_EXCL, + 0777, EEXIST); + + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, + "shm_unlink failed; errno=%d", errno); +} + +ATF_TC_WITHOUT_HEAD(trunc_resets_object); +ATF_TC_BODY(trunc_resets_object, tc) +{ + struct stat sb; + int fd; + + gen_test_path(); + + /* Create object and set size to 1024. */ + fd = shm_open(test_path, O_RDWR | O_CREAT, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open(1) failed; errno=%d", errno); + ATF_REQUIRE_MSG(ftruncate(fd, 1024) != -1, + "ftruncate failed; errno=%d", errno); + ATF_REQUIRE_MSG(fstat(fd, &sb) != -1, + "fstat(1) failed; errno=%d", errno); + ATF_REQUIRE_MSG(sb.st_size == 1024, "size %d != 1024", (int)sb.st_size); + close(fd); + + /* Open with O_TRUNC which should reset size to 0. */ + fd = shm_open(test_path, O_RDWR | O_TRUNC, 0777); + ATF_REQUIRE_MSG(fd >= 0, "shm_open(2) failed; errno=%d", errno); + ATF_REQUIRE_MSG(fstat(fd, &sb) != -1, + "fstat(2) failed; errno=%d", errno); + ATF_REQUIRE_MSG(sb.st_size == 0, + "size was not 0 after truncation: %d", (int)sb.st_size); + close(fd); + ATF_REQUIRE_MSG(shm_unlink(test_path) != -1, + "shm_unlink failed; errno=%d", errno); +} + +ATF_TC_WITHOUT_HEAD(unlink_bad_path_pointer); +ATF_TC_BODY(unlink_bad_path_pointer, tc) +{ + + shm_unlink_should_fail((char *)1024, EFAULT); +} + +ATF_TC_WITHOUT_HEAD(unlink_path_too_long); +ATF_TC_BODY(unlink_path_too_long, tc) +{ + char *page; + + page = malloc(MAXPATHLEN + 1); + memset(page, 'a', MAXPATHLEN); + page[MAXPATHLEN] = '\0'; + shm_unlink_should_fail(page, ENAMETOOLONG); + free(page); +} + +ATF_TC_WITHOUT_HEAD(object_resize); +ATF_TC_BODY(object_resize, tc) +{ + pid_t pid; + struct stat sb; + char err_buf[1024], *page; + int fd, status; + + /* Start off with a size of a single page. */ + fd = shm_open(SHM_ANON, O_CREAT|O_RDWR, 0777); + if (fd < 0) + atf_tc_fail("shm_open failed; errno=%d", errno); + + if (ftruncate(fd, getpagesize()) < 0) + atf_tc_fail("ftruncate(1) failed; errno=%d", errno); + + if (fstat(fd, &sb) < 0) + atf_tc_fail("fstat(1) failed; errno=%d", errno); + + if (sb.st_size != getpagesize()) + atf_tc_fail("first resize failed (%d != %d)", + (int)sb.st_size, getpagesize()); + + /* Write a '1' to the first byte. */ + page = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, + 0); + if (page == MAP_FAILED) + atf_tc_fail("mmap(1)"); + + page[0] = '1'; + + if (munmap(page, getpagesize()) < 0) + atf_tc_fail("munmap(1) failed; errno=%d", errno); + + /* Grow the object to 2 pages. */ + if (ftruncate(fd, getpagesize() * 2) < 0) + atf_tc_fail("ftruncate(2) failed; errno=%d", errno); + + if (fstat(fd, &sb) < 0) + atf_tc_fail("fstat(2) failed; errno=%d", errno); + + if (sb.st_size != getpagesize() * 2) + atf_tc_fail("second resize failed (%d != %d)", + (int)sb.st_size, getpagesize() * 2); + + /* Check for '1' at the first byte. */ + page = mmap(0, getpagesize() * 2, PROT_READ|PROT_WRITE, MAP_SHARED, + fd, 0); + if (page == MAP_FAILED) + atf_tc_fail("mmap(2) failed; errno=%d", errno); + + if (page[0] != '1') + atf_tc_fail("'%c' != '1'", page[0]); + + /* Write a '2' at the start of the second page. */ + page[getpagesize()] = '2'; + + /* Shrink the object back to 1 page. */ + if (ftruncate(fd, getpagesize()) < 0) + atf_tc_fail("ftruncate(3) failed; errno=%d", errno); + + if (fstat(fd, &sb) < 0) + atf_tc_fail("fstat(3) failed; errno=%d", errno); + + if (sb.st_size != getpagesize()) + atf_tc_fail("third resize failed (%d != %d)", + (int)sb.st_size, getpagesize()); + + /* + * Fork a child process to make sure the second page is no + * longer valid. + */ + pid = fork(); + if (pid == -1) + atf_tc_fail("fork failed; errno=%d", errno); + + if (pid == 0) { + struct rlimit lim; + char c; + + /* Don't generate a core dump. */ + getrlimit(RLIMIT_CORE, &lim); + lim.rlim_cur = 0; + setrlimit(RLIMIT_CORE, &lim); + + /* + * The previous ftruncate(2) shrunk the backing object + * so that this address is no longer valid, so reading + * from it should trigger a SIGSEGV. + */ + c = page[getpagesize()]; + fprintf(stderr, "child: page 1: '%c'\n", c); + exit(0); + } + + if (wait(&status) < 0) + atf_tc_fail("wait failed; errno=%d", errno); + + if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGSEGV) + atf_tc_fail("child terminated with status %x", status); + + /* Grow the object back to 2 pages. */ + if (ftruncate(fd, getpagesize() * 2) < 0) + atf_tc_fail("ftruncate(2) failed; errno=%d", errno); + + if (fstat(fd, &sb) < 0) + atf_tc_fail("fstat(2) failed; errno=%d", errno); + + if (sb.st_size != getpagesize() * 2) + atf_tc_fail("fourth resize failed (%d != %d)", + (int)sb.st_size, getpagesize()); + + /* + * Note that the mapping at 'page' for the second page is + * still valid, and now that the shm object has been grown + * back up to 2 pages, there is now memory backing this page + * so the read will work. However, the data should be zero + * rather than '2' as the old data was thrown away when the + * object was shrunk and the new pages when an object are + * grown are zero-filled. + */ + if (page[getpagesize()] != 0) + atf_tc_fail("invalid data at %d: %x != 0", + getpagesize(), (int)page[getpagesize()]); + + close(fd); +} + +/* Signal handler which does nothing. */ +static void +ignoreit(int sig __unused) +{ + ; +} + +ATF_TC_WITHOUT_HEAD(shm_functionality_across_fork); +ATF_TC_BODY(shm_functionality_across_fork, tc) +{ + char *cp, c; + int error, desc, rv; + long scval; + sigset_t ss; + struct sigaction sa; + void *region; + size_t i, psize; + +#ifndef _POSIX_SHARED_MEMORY_OBJECTS + printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n"); +#else + printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", + (long)_POSIX_SHARED_MEMORY_OBJECTS - 0); + if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1) + printf("***Indicates this feature may be unsupported!\n"); +#endif + errno = 0; + scval = sysconf(_SC_SHARED_MEMORY_OBJECTS); + if (scval == -1 && errno != 0) { + atf_tc_fail("sysconf(_SC_SHARED_MEMORY_OBJECTS) failed; " + "errno=%d", errno); + } else { + printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n", + scval); + if (scval == -1) + printf("***Indicates this feature is unsupported!\n"); + } + + errno = 0; + scval = sysconf(_SC_PAGESIZE); + if (scval == -1 && errno != 0) { + atf_tc_fail("sysconf(_SC_PAGESIZE) failed; errno=%d", errno); + } else if (scval <= 0 || (size_t)psize != psize) { + fprintf(stderr, "bogus return from sysconf(_SC_PAGESIZE): %ld", + scval); + psize = 4096; + } else { + printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval); + psize = scval; + } + + gen_test_path(); + desc = shm_open(test_path, O_EXCL | O_CREAT | O_RDWR, 0600); + + ATF_REQUIRE_MSG(desc >= 0, "shm_open failed; errno=%d", errno); + ATF_REQUIRE_MSG(shm_unlink(test_path) == 0, + "shm_unlink failed; errno=%d", errno); + ATF_REQUIRE_MSG(ftruncate(desc, (off_t)psize) != -1, + "ftruncate failed; errno=%d", errno); + + region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED, + desc, (off_t)0); + ATF_REQUIRE_MSG(region != MAP_FAILED, "mmap failed; errno=%d", errno); + memset(region, '\377', psize); + + sa.sa_flags = 0; + sa.sa_handler = ignoreit; + sigemptyset(&sa.sa_mask); + ATF_REQUIRE_MSG(sigaction(SIGUSR1, &sa, (struct sigaction *)0) == 0, + "sigaction failed; errno=%d", errno); + + sigemptyset(&ss); + sigaddset(&ss, SIGUSR1); + ATF_REQUIRE_MSG(sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) == 0, + "sigprocmask failed; errno=%d", errno); + + rv = fork(); + ATF_REQUIRE_MSG(rv != -1, "fork failed; errno=%d", errno); + if (rv == 0) { + sigemptyset(&ss); + sigsuspend(&ss); + + for (cp = region; cp < (char *)region + psize; cp++) { + if (*cp != '\151') + _exit(1); + } + if (lseek(desc, 0, SEEK_SET) == -1) + _exit(1); + for (i = 0; i < psize; i++) { + error = read(desc, &c, 1); + if (c != '\151') + _exit(1); + } + _exit(0); + } else { + int status; + + memset(region, '\151', psize - 2); + error = pwrite(desc, region, 2, psize - 2); + if (error != 2) { + if (error >= 0) + atf_tc_fail("short write; %d bytes written", + error); + else + atf_tc_fail("shmfd write"); + } + kill(rv, SIGUSR1); + waitpid(rv, &status, 0); + + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + printf("Functionality test successful\n"); + } else if (WIFEXITED(status)) { + atf_tc_fail("Child process exited with status %d", + WEXITSTATUS(status)); + } else { + atf_tc_fail("Child process terminated with %s", + strsignal(WTERMSIG(status))); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, remap_object); + ATF_TP_ADD_TC(tp, reopen_object); + ATF_TP_ADD_TC(tp, readonly_mmap_write); + ATF_TP_ADD_TC(tp, open_after_link); + ATF_TP_ADD_TC(tp, open_invalid_path); + ATF_TP_ADD_TC(tp, open_write_only); + ATF_TP_ADD_TC(tp, open_extra_flags); + ATF_TP_ADD_TC(tp, open_anon); + ATF_TP_ADD_TC(tp, open_anon_readonly); + ATF_TP_ADD_TC(tp, open_bad_path_pointer); + ATF_TP_ADD_TC(tp, open_path_too_long); + ATF_TP_ADD_TC(tp, open_nonexisting_object); + ATF_TP_ADD_TC(tp, open_create_existing_object); + ATF_TP_ADD_TC(tp, shm_functionality_across_fork); + ATF_TP_ADD_TC(tp, trunc_resets_object); + ATF_TP_ADD_TC(tp, unlink_bad_path_pointer); + ATF_TP_ADD_TC(tp, unlink_path_too_long); + ATF_TP_ADD_TC(tp, object_resize); + + return (atf_no_error()); +} diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 747f3c4..ade842b 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -172,6 +172,10 @@ OLD_DIRS+=etc/autofs .endif .if ${MK_BHYVE} == no +OLD_FILES+=usr/lib/libvmmapi.a +OLD_FILES+=usr/lib/libvmmapi.so +OLD_LIBS+=usr/lib/libvmmapi.so.5 +OLD_FILES+=usr/include/vmmapi.h OLD_FILES+=usr/sbin/bhyve OLD_FILES+=usr/sbin/bhyvectl OLD_FILES+=usr/sbin/bhyveload diff --git a/tools/regression/posixshm/Makefile b/tools/regression/posixshm/Makefile deleted file mode 100644 index 5ef70c9..0000000 --- a/tools/regression/posixshm/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $FreeBSD$ - -PROG= posixshm -SRCS= posixshm.c test.c -MAN= - -WARNS?= 3 - -.include <bsd.prog.mk> diff --git a/tools/regression/posixshm/posixshm.c b/tools/regression/posixshm/posixshm.c deleted file mode 100644 index 6f4c306..0000000 --- a/tools/regression/posixshm/posixshm.c +++ /dev/null @@ -1,627 +0,0 @@ -/*- - * Copyright (c) 2006 Robert N. M. Watson - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/mman.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/wait.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "test.h" - -#define TEST_PATH "/tmp/posixshm_regression_test" - -/* - * Attempt a shm_open() that should fail with an expected error of 'error'. - */ -static void -shm_open_should_fail(const char *path, int flags, mode_t mode, int error) -{ - int fd; - - fd = shm_open(path, flags, mode); - if (fd >= 0) { - fail_err("shm_open() didn't fail"); - close(fd); - return; - } - if (errno != error) { - fail_errno("shm_open"); - return; - } - pass(); -} - -/* - * Attempt a shm_unlink() that should fail with an expected error of 'error'. - */ -static void -shm_unlink_should_fail(const char *path, int error) -{ - - if (shm_unlink(path) >= 0) { - fail_err("shm_unlink() didn't fail"); - return; - } - if (errno != error) { - fail_errno("shm_unlink"); - return; - } - pass(); -} - -/* - * Open the test object and write '1' to the first byte. Returns valid fd - * on success and -1 on failure. - */ -static int -scribble_object(void) -{ - char *page; - int fd; - - fd = shm_open(TEST_PATH, O_CREAT | O_EXCL | O_RDWR, 0777); - if (fd < 0 && errno == EEXIST) { - if (shm_unlink(TEST_PATH) < 0) { - fail_errno("shm_unlink"); - return (-1); - } - fd = shm_open(TEST_PATH, O_CREAT | O_EXCL | O_RDWR, 0777); - } - if (fd < 0) { - fail_errno("shm_open"); - return (-1); - } - if (ftruncate(fd, getpagesize()) < 0) { - fail_errno("ftruncate"); - close(fd); - shm_unlink(TEST_PATH); - return (-1); - } - - page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, - 0); - if (page == MAP_FAILED) { - fail_errno("mmap"); - close(fd); - shm_unlink(TEST_PATH); - return (-1); - } - - page[0] = '1'; - - if (munmap(page, getpagesize()) < 0) { - fail_errno("munmap"); - close(fd); - shm_unlink(TEST_PATH); - return (-1); - } - - return (fd); -} - -static void -remap_object(void) -{ - char *page; - int fd; - - fd = scribble_object(); - if (fd < 0) - return; - - page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, - 0); - if (page == MAP_FAILED) { - fail_errno("mmap(2)"); - close(fd); - shm_unlink(TEST_PATH); - return; - } - - if (page[0] != '1') { - fail_err("missing data"); - close(fd); - shm_unlink(TEST_PATH); - return; - } - - close(fd); - if (munmap(page, getpagesize()) < 0) { - fail_errno("munmap"); - shm_unlink(TEST_PATH); - return; - } - - if (shm_unlink(TEST_PATH) < 0) { - fail_errno("shm_unlink"); - return; - } - - pass(); -} -TEST(remap_object, "remap object"); - -static void -reopen_object(void) -{ - char *page; - int fd; - - fd = scribble_object(); - if (fd < 0) - return; - close(fd); - - fd = shm_open(TEST_PATH, O_RDONLY, 0777); - if (fd < 0) { - fail_errno("shm_open(2)"); - shm_unlink(TEST_PATH); - return; - } - page = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0); - if (page == MAP_FAILED) { - fail_errno("mmap(2)"); - close(fd); - shm_unlink(TEST_PATH); - return; - } - - if (page[0] != '1') { - fail_err("missing data"); - munmap(page, getpagesize()); - close(fd); - shm_unlink(TEST_PATH); - return; - } - - munmap(page, getpagesize()); - close(fd); - shm_unlink(TEST_PATH); - pass(); -} -TEST(reopen_object, "reopen object"); - -static void -readonly_mmap_write(void) -{ - char *page; - int fd; - - fd = shm_open(TEST_PATH, O_RDONLY | O_CREAT, 0777); - if (fd < 0) { - fail_errno("shm_open"); - return; - } - - /* PROT_WRITE should fail with EACCES. */ - page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, - 0); - if (page != MAP_FAILED) { - fail_err("mmap(PROT_WRITE) succeeded"); - munmap(page, getpagesize()); - close(fd); - shm_unlink(TEST_PATH); - return; - } - if (errno != EACCES) { - fail_errno("mmap"); - close(fd); - shm_unlink(TEST_PATH); - return; - } - - close(fd); - shm_unlink(TEST_PATH); - pass(); -} -TEST(readonly_mmap_write, "RDONLY object"); - -static void -open_after_unlink(void) -{ - int fd; - - fd = shm_open(TEST_PATH, O_RDONLY | O_CREAT, 0777); - if (fd < 0) { - fail_errno("shm_open(1)"); - return; - } - close(fd); - - if (shm_unlink(TEST_PATH) < 0) { - fail_errno("shm_unlink"); - return; - } - - shm_open_should_fail(TEST_PATH, O_RDONLY, 0777, ENOENT); -} -TEST(open_after_unlink, "open after unlink"); - -static void -open_invalid_path(void) -{ - - shm_open_should_fail("blah", O_RDONLY, 0777, EINVAL); -} -TEST(open_invalid_path, "open invalid path"); - -static void -open_write_only(void) -{ - - shm_open_should_fail(TEST_PATH, O_WRONLY, 0777, EINVAL); -} -TEST(open_write_only, "open with O_WRONLY"); - -static void -open_extra_flags(void) -{ - - shm_open_should_fail(TEST_PATH, O_RDONLY | O_DIRECT, 0777, EINVAL); -} -TEST(open_extra_flags, "open with extra flags"); - -static void -open_anon(void) -{ - int fd; - - fd = shm_open(SHM_ANON, O_RDWR, 0777); - if (fd < 0) { - fail_errno("shm_open"); - return; - } - close(fd); - pass(); -} -TEST(open_anon, "open anonymous object"); - -static void -open_anon_readonly(void) -{ - - shm_open_should_fail(SHM_ANON, O_RDONLY, 0777, EINVAL); -} -TEST(open_anon_readonly, "open SHM_ANON with O_RDONLY"); - -static void -open_bad_path_pointer(void) -{ - - shm_open_should_fail((char *)1024, O_RDONLY, 0777, EFAULT); -} -TEST(open_bad_path_pointer, "open bad path pointer"); - -static void -open_path_too_long(void) -{ - char *page; - - page = malloc(MAXPATHLEN + 1); - memset(page, 'a', MAXPATHLEN); - page[MAXPATHLEN] = '\0'; - shm_open_should_fail(page, O_RDONLY, 0777, ENAMETOOLONG); - free(page); -} -TEST(open_path_too_long, "open pathname too long"); - -static void -open_nonexisting_object(void) -{ - - shm_open_should_fail("/notreallythere", O_RDONLY, 0777, ENOENT); -} -TEST(open_nonexisting_object, "open nonexistent object"); - -static void -exclusive_create_existing_object(void) -{ - int fd; - - fd = shm_open("/tmp/notreallythere", O_RDONLY | O_CREAT, 0777); - if (fd < 0) { - fail_errno("shm_open(O_CREAT)"); - return; - } - close(fd); - - shm_open_should_fail("/tmp/notreallythere", O_RDONLY | O_CREAT | O_EXCL, - 0777, EEXIST); - - shm_unlink("/tmp/notreallythere"); -} -TEST(exclusive_create_existing_object, "O_EXCL of existing object"); - -static void -trunc_resets_object(void) -{ - struct stat sb; - int fd; - - /* Create object and set size to 1024. */ - fd = shm_open(TEST_PATH, O_RDWR | O_CREAT, 0777); - if (fd < 0) { - fail_errno("shm_open(1)"); - return; - } - if (ftruncate(fd, 1024) < 0) { - fail_errno("ftruncate"); - close(fd); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(1)"); - close(fd); - return; - } - if (sb.st_size != 1024) { - fail_err("size %d != 1024", (int)sb.st_size); - close(fd); - return; - } - close(fd); - - /* Open with O_TRUNC which should reset size to 0. */ - fd = shm_open(TEST_PATH, O_RDWR | O_TRUNC, 0777); - if (fd < 0) { - fail_errno("shm_open(2)"); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(2)"); - close(fd); - return; - } - if (sb.st_size != 0) { - fail_err("size after O_TRUNC %d != 0", (int)sb.st_size); - close(fd); - return; - } - close(fd); - if (shm_unlink(TEST_PATH) < 0) { - fail_errno("shm_unlink"); - return; - } - pass(); -} -TEST(trunc_resets_object, "O_TRUNC resets size"); - -static void -unlink_bad_path_pointer(void) -{ - - shm_unlink_should_fail((char *)1024, EFAULT); -} -TEST(unlink_bad_path_pointer, "unlink bad path pointer"); - -static void -unlink_path_too_long(void) -{ - char *page; - - page = malloc(MAXPATHLEN + 1); - memset(page, 'a', MAXPATHLEN); - page[MAXPATHLEN] = '\0'; - shm_unlink_should_fail(page, ENAMETOOLONG); - free(page); -} -TEST(unlink_path_too_long, "unlink pathname too long"); - -static void -test_object_resize(void) -{ - pid_t pid; - struct stat sb; - char *page; - int fd, status; - - /* Start off with a size of a single page. */ - fd = shm_open(SHM_ANON, O_CREAT | O_RDWR, 0777); - if (fd < 0) { - fail_errno("shm_open"); - return; - } - if (ftruncate(fd, getpagesize()) < 0) { - fail_errno("ftruncate(1)"); - close(fd); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(1)"); - close(fd); - return; - } - if (sb.st_size != getpagesize()) { - fail_err("first resize failed"); - close(fd); - return; - } - - /* Write a '1' to the first byte. */ - page = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, - 0); - if (page == MAP_FAILED) { - fail_errno("mmap(1)"); - close(fd); - return; - } - - page[0] = '1'; - - if (munmap(page, getpagesize()) < 0) { - fail_errno("munmap(1)"); - close(fd); - return; - } - - /* Grow the object to 2 pages. */ - if (ftruncate(fd, getpagesize() * 2) < 0) { - fail_errno("ftruncate(2)"); - close(fd); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(2)"); - close(fd); - return; - } - if (sb.st_size != getpagesize() * 2) { - fail_err("second resize failed"); - close(fd); - return; - } - - /* Check for '1' at the first byte. */ - page = mmap(0, getpagesize() * 2, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, 0); - if (page == MAP_FAILED) { - fail_errno("mmap(2)"); - close(fd); - return; - } - - if (page[0] != '1') { - fail_err("missing data at 0"); - close(fd); - return; - } - - /* Write a '2' at the start of the second page. */ - page[getpagesize()] = '2'; - - /* Shrink the object back to 1 page. */ - if (ftruncate(fd, getpagesize()) < 0) { - fail_errno("ftruncate(3)"); - close(fd); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(3)"); - close(fd); - return; - } - if (sb.st_size != getpagesize()) { - fail_err("third resize failed"); - close(fd); - return; - } - - /* - * Fork a child process to make sure the second page is no - * longer valid. - */ - pid = fork(); - if (pid < 0) { - fail_errno("fork"); - close(fd); - return; - } - - if (pid == 0) { - struct rlimit lim; - char c; - - /* Don't generate a core dump. */ - getrlimit(RLIMIT_CORE, &lim); - lim.rlim_cur = 0; - setrlimit(RLIMIT_CORE, &lim); - - /* - * The previous ftruncate(2) shrunk the backing object - * so that this address is no longer valid, so reading - * from it should trigger a SIGSEGV. - */ - c = page[getpagesize()]; - fprintf(stderr, "child: page 1: '%c'\n", c); - exit(0); - } - if (wait(&status) < 0) { - fail_errno("wait"); - close(fd); - return; - } - if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGSEGV) { - fail_err("child terminated with status %x", status); - close(fd); - return; - } - - /* Grow the object back to 2 pages. */ - if (ftruncate(fd, getpagesize() * 2) < 0) { - fail_errno("ftruncate(4)"); - close(fd); - return; - } - if (fstat(fd, &sb) < 0) { - fail_errno("fstat(4)"); - close(fd); - return; - } - if (sb.st_size != getpagesize() * 2) { - fail_err("second resize failed"); - close(fd); - return; - } - - /* - * Note that the mapping at 'page' for the second page is - * still valid, and now that the shm object has been grown - * back up to 2 pages, there is now memory backing this page - * so the read will work. However, the data should be zero - * rather than '2' as the old data was thrown away when the - * object was shrunk and the new pages when an object are - * grown are zero-filled. - */ - if (page[getpagesize()] != 0) { - fail_err("invalid data at %d", getpagesize()); - close(fd); - return; - } - - close(fd); - pass(); -} -TEST(test_object_resize, "object resize"); - -int -main(int argc, char *argv[]) -{ - - run_tests(); - return (0); -} diff --git a/tools/regression/posixshm/posixshm.t b/tools/regression/posixshm/posixshm.t deleted file mode 100644 index a2159ac..0000000 --- a/tools/regression/posixshm/posixshm.t +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ - -./posixshm diff --git a/tools/regression/posixshm/test.c b/tools/regression/posixshm/test.c deleted file mode 100644 index 8583a0d..0000000 --- a/tools/regression/posixshm/test.c +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 2008 Yahoo!, Inc. - * All rights reserved. - * Written by: John Baldwin <jhb@FreeBSD.org> - * - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdarg.h> -#include <stdio.h> - -#include "test.h" - -static int test_index; -static struct regression_test *test; -static int test_acknowleged; - -SET_DECLARE(regression_tests_set, struct regression_test); - -/* - * Outputs a test summary of the following: - * - * <status> <test #> [name] [# <fmt> [fmt args]] - */ -static void -vprint_status(const char *status, const char *fmt, va_list ap) -{ - - printf("%s %d", status, test_index); - if (test->rt_name) - printf(" - %s", test->rt_name); - if (fmt) { - printf(" # "); - vprintf(fmt, ap); - } - printf("\n"); - test_acknowleged = 1; -} - -static void -print_status(const char *status, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vprint_status(status, fmt, ap); - va_end(ap); -} - -void -pass(void) -{ - - print_status("ok", NULL); -} - -void -fail(void) -{ - - print_status("not ok", NULL); -} - -void -fail_err(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vprint_status("not ok", fmt, ap); - va_end(ap); -} - -void -skip(const char *reason) -{ - - print_status("ok", "skip %s", reason); -} - -void -todo(const char *reason) -{ - - print_status("not ok", "TODO %s", reason); -} - -void -run_tests(void) -{ - struct regression_test **testp; - - printf("1..%td\n", SET_COUNT(regression_tests_set)); - test_index = 1; - SET_FOREACH(testp, regression_tests_set) { - test_acknowleged = 0; - test = *testp; - test->rt_function(); - if (!test_acknowleged) - print_status("not ok", "unknown status"); - test_index++; - } -} diff --git a/tools/regression/posixshm/test.h b/tools/regression/posixshm/test.h deleted file mode 100644 index 505679b..0000000 --- a/tools/regression/posixshm/test.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2008 Yahoo!, Inc. - * All rights reserved. - * Written by: John Baldwin <jhb@FreeBSD.org> - * - * 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. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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$ - */ - -#ifndef __TEST_H__ -#define __TEST_H__ - -#include <sys/linker_set.h> - -struct regression_test { - void (*rt_function)(void); - const char *rt_name; -}; - -#define TEST(function, name) \ - static struct regression_test _regtest_##function = { \ - (function), \ - (name) \ - }; \ - DATA_SET(regression_tests_set, _regtest_##function) - -void fail(void); -void fail_err(const char *fmt, ...); -void pass(void); -void run_tests(void); -void skip(const char *reason); -void todo(const char *reason); - -#define fail_errno(tag) fail_err("%s: %s", (tag), strerror(errno)) - -#endif /* !__TEST_H__ */ diff --git a/tools/regression/security/open_to_operation/Makefile b/tools/regression/security/open_to_operation/Makefile index 462626f..fbc0dc7 100644 --- a/tools/regression/security/open_to_operation/Makefile +++ b/tools/regression/security/open_to_operation/Makefile @@ -2,6 +2,6 @@ PROG= open_to_operation MAN= -#WARNS= 3 +WARNS?= 3 .include <bsd.prog.mk> diff --git a/tools/regression/security/open_to_operation/open_to_operation.c b/tools/regression/security/open_to_operation/open_to_operation.c index 38af3c6..c8c816b 100644 --- a/tools/regression/security/open_to_operation/open_to_operation.c +++ b/tools/regression/security/open_to_operation/open_to_operation.c @@ -119,10 +119,10 @@ __FBSDID("$FreeBSD$"); */ static const int file_modes[] = { O_RDONLY, O_WRONLY, O_RDWR, O_RDONLY | O_TRUNC, O_WRONLY | O_TRUNC, O_RDWR | O_TRUNC }; -static const int file_modes_count = sizeof(file_modes) / sizeof(int); +static const int file_modes_count = nitems(file_modes); static const int dir_modes[] = { O_RDONLY }; -static const int dir_modes_count = sizeof(dir_modes) / sizeof(int); +static const int dir_modes_count = nitems(dir_modes); static int testnum; static int aio_present; @@ -169,9 +169,9 @@ try_directory_open(const char *testname, const char *directory, ok_mode(testname, NULL, mode); close(dfd); } else { - if (expected_errno && expected_errno == expected_errno) + if (expected_errno && expected_errno == errno) ok_mode(testname, NULL, mode); - else if (expected_errno) + else if (expected_errno != 0) notok_mode(testname, "wrong errno", mode); else notok_mode(testname, "failed", mode); @@ -753,7 +753,8 @@ pwritev_wrapper(int d, const void *buf, size_t nbytes) static ssize_t aio_write_wrapper(int d, const void *buf, size_t nbytes) { - struct aiocb aiocb, *aiocb_array[1]; + struct aiocb aiocb; + struct aiocb const *aiocb_array[] = { &aiocb }; bzero(&aiocb, sizeof(aiocb)); aiocb.aio_fildes = d; @@ -839,7 +840,8 @@ preadv_wrapper(int d, void *buf, size_t nbytes) static ssize_t aio_read_wrapper(int d, void *buf, size_t nbytes) { - struct aiocb aiocb, *aiocb_array[1]; + struct aiocb aiocb; + struct aiocb const *aiocb_array[] = { &aiocb }; bzero(&aiocb, sizeof(aiocb)); aiocb.aio_fildes = d; @@ -847,7 +849,6 @@ aio_read_wrapper(int d, void *buf, size_t nbytes) aiocb.aio_nbytes = nbytes; if (aio_read(&aiocb) < 0) return (-1); - aiocb_array[0] = &aiocb; if (aio_suspend(aiocb_array, 1, NULL) < 0) return (-1); return (aio_return(&aiocb)); @@ -1009,12 +1010,8 @@ check_mmap_exec(const char *testname, const char *path, int isdir, if (isdir) notok_mode(testname, "mmap dir succeeded", mode); - else if ((mode & O_ACCMODE) == O_RDONLY || - (mode & O_ACCMODE) == O_RDWR) - ok_mode(testname, "mmap file succeeded", - mode); else - notok_mode(testname, "mmap file succeeded", + ok_mode(testname, "mmap file succeeded", mode); (void)munmap(addr, getpagesize()); } @@ -1069,7 +1066,7 @@ check_mmap_write_private(const char *testname, const char *path, int isdir, } int -main(int argc, char *argv[]) +main(void) { char dir_path[PATH_MAX], file_path[PATH_MAX]; int dummy, fd; @@ -1084,25 +1081,25 @@ main(int argc, char *argv[]) strlcpy(dir_path, "/tmp/open-dir.XXXXXXXXXXX", sizeof(dir_path)); if (mkdtemp(dir_path) == NULL) - err(-1, "mkdtemp"); + err(1, "mkdtemp"); if (chmod(dir_path, PERM_DIR) < 0) { warn("chmod %s", dir_path); (void)rmdir(dir_path); - exit(-1); + exit(1); } strlcpy(file_path, "/tmp/open-file.XXXXXXXXXXX", sizeof(file_path)); fd = mkstemp(file_path); if (fd < 0) { warn("mkstemp"); (void)rmdir(dir_path); - exit(-1); + exit(1); } close(fd); if (chmod(file_path, PERM_FILE) < 0) { warn("chmod %s", file_path); (void)unlink(file_path); (void)rmdir(dir_path); - exit(-1); + exit(1); } check_directory_open_modes(dir_path, file_modes, file_modes_count); diff --git a/tools/test/posixshm/README b/tools/test/posixshm/README deleted file mode 100644 index 514e18b..0000000 --- a/tools/test/posixshm/README +++ /dev/null @@ -1,4 +0,0 @@ -$FreeBSD$ - -This is a simple program to test/demonstrate the POSIX Shared Memory -Objects feature set. `make shm_test' to build. diff --git a/tools/test/posixshm/shm_test.c b/tools/test/posixshm/shm_test.c deleted file mode 100644 index 0ec890a..0000000 --- a/tools/test/posixshm/shm_test.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Test the POSIX shared-memory API. - * Dedicated to the public domain by Garrett A. Wollman, 2000. - * $FreeBSD$ - */ - -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/wait.h> - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/* - * Signal handler which does nothing. - */ -static void -ignoreit(int sig __unused) -{ - ; -} - -int -main(int argc, char **argv) -{ - char buf[1024], *cp, c; - int error, desc, rv; - long scval; - sigset_t ss; - struct sigaction sa; - void *region; - size_t i, psize; - -#ifndef _POSIX_SHARED_MEMORY_OBJECTS - printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n"); -#else - printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", - (long)_POSIX_SHARED_MEMORY_OBJECTS - 0); - if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1) - printf("***Indicates this feature may be unsupported!\n"); -#endif - errno = 0; - scval = sysconf(_SC_SHARED_MEMORY_OBJECTS); - if (scval == -1 && errno != 0) { - err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)"); - } else { - printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n", - scval); - if (scval == -1) - printf("***Indicates this feature is unsupported!\n"); - } - - errno = 0; - scval = sysconf(_SC_PAGESIZE); - if (scval == -1 && errno != 0) { - err(1, "sysconf(_SC_PAGESIZE)"); - } else if (scval <= 0 || (size_t)psize != psize) { - warnx("bogus return from sysconf(_SC_PAGESIZE): %ld", - scval); - psize = 4096; - } else { - printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval); - psize = scval; - } - - argc--, argv++; - - if (*argv) { - strncat(buf, *argv, (sizeof buf) - 1); - desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600); - } else { - do { - /* - * Can't use mkstemp for obvious reasons... - */ - strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX"); - mktemp(buf); - desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600); - } while (desc < 0 && errno == EEXIST); - } - - if (desc < 0) - err(1, "shm_open"); - - if (shm_unlink(buf) < 0) - err(1, "shm_unlink"); - - if (ftruncate(desc, (off_t)psize) < 0) - err(1, "ftruncate"); - - region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED, - desc, (off_t)0); - if (region == MAP_FAILED) - err(1, "mmap"); - memset(region, '\377', psize); - - sa.sa_flags = 0; - sa.sa_handler = ignoreit; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0) - err(1, "sigaction"); - - sigemptyset(&ss); - sigaddset(&ss, SIGUSR1); - if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0) - err(1, "sigprocmask"); - - rv = fork(); - if (rv < 0) { - err(1, "fork"); - } else if (rv == 0) { - sigemptyset(&ss); - sigsuspend(&ss); - - for (cp = region; cp < (char *)region + psize; cp++) { - if (*cp != '\151') - _exit(1); - } - if (lseek(desc, 0, SEEK_SET) == -1) - _exit(1); - for (i = 0; i < psize; i++) { - error = read(desc, &c, 1); - if (c != '\151') - _exit(1); - } - _exit(0); - } else { - int status; - - memset(region, '\151', psize - 2); - error = pwrite(desc, region, 2, psize - 2); - if (error != 2) { - if (error >= 0) - errx(1, "short write %d", error); - else - err(1, "shmfd write"); - } - kill(rv, SIGUSR1); - waitpid(rv, &status, 0); - - if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { - printf("Functionality test successful\n"); - exit(0); - } else if (WIFEXITED(status)) { - printf("Child process exited with status %d\n", - WEXITSTATUS(status)); - } else { - printf("Child process terminated with %s\n", - strsignal(WTERMSIG(status))); - } - } - exit(1); -} diff --git a/usr.bin/bsdiff/bsdiff/bsdiff.c b/usr.bin/bsdiff/bsdiff/bsdiff.c index 8b764da..fe7da7c 100644 --- a/usr.bin/bsdiff/bsdiff/bsdiff.c +++ b/usr.bin/bsdiff/bsdiff/bsdiff.c @@ -31,7 +31,10 @@ __FBSDID("$FreeBSD$"); #include <bzlib.h> #include <err.h> +#include <errno.h> #include <fcntl.h> +#include <limits.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -221,8 +224,17 @@ int main(int argc,char *argv[]) /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[1],O_RDONLY|O_BINARY,0))<0) || - ((oldsize=lseek(fd,0,SEEK_END))==-1) || - ((old=malloc(oldsize+1))==NULL) || + ((oldsize=lseek(fd,0,SEEK_END))==-1)) + err(1, "%s", argv[1]); + + if (oldsize > SSIZE_MAX || + (uintmax_t)oldsize >= SIZE_T_MAX / sizeof(off_t) || + oldsize == OFF_MAX) { + errno = EFBIG; + err(1, "%s", argv[1]); + } + + if (((old=malloc(oldsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,old,oldsize)!=oldsize) || (close(fd)==-1)) err(1,"%s",argv[1]); @@ -237,8 +249,16 @@ int main(int argc,char *argv[]) /* Allocate newsize+1 bytes instead of newsize bytes to ensure that we never try to malloc(0) and get a NULL pointer */ if(((fd=open(argv[2],O_RDONLY|O_BINARY,0))<0) || - ((newsize=lseek(fd,0,SEEK_END))==-1) || - ((new=malloc(newsize+1))==NULL) || + ((newsize=lseek(fd,0,SEEK_END))==-1)) + err(1, "%s", argv[2]); + + if (newsize > SSIZE_MAX || (uintmax_t)newsize >= SIZE_T_MAX || + newsize == OFF_MAX) { + errno = EFBIG; + err(1, "%s", argv[2]); + } + + if (((new=malloc(newsize+1))==NULL) || (lseek(fd,0,SEEK_SET)!=0) || (read(fd,new,newsize)!=newsize) || (close(fd)==-1)) err(1,"%s",argv[2]); diff --git a/usr.bin/gzip/gzip.1 b/usr.bin/gzip/gzip.1 index 723c675..16a9035 100644 --- a/usr.bin/gzip/gzip.1 +++ b/usr.bin/gzip/gzip.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: gzip.1,v 1.25 2015/04/06 21:41:17 wiz Exp $ +.\" $NetBSD: gzip.1,v 1.26 2015/10/27 07:36:18 mrg Exp $ .\" .\" Copyright (c) 1997, 2003, 2004 Matthew R. Green .\" All rights reserved. @@ -25,7 +25,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd April 6, 2015 +.Dd October 26, 2015 .Dt GZIP 1 .Os .Sh NAME @@ -136,7 +136,7 @@ option, allowing non-compressed data to pass through unchanged. .It Fl h , -help This option prints a usage summary and exits. .It Fl k , -keep -Keep (don't delete) input files during compression +Keep (do not delete) input files during compression or decompression. .It Fl L , -license This option prints @@ -183,6 +183,12 @@ is set, it is parsed as a white-space separated list of options handled before any options on the command line. Options on the command line will override anything in .Ev GZIP . +.Sh EXIT STATUS +The +.Nm +utility exits 0 on success, +1 on errors, +and 2 if a warning occurs. .Sh SEE ALSO .Xr bzip2 1 , .Xr compress 1 , @@ -220,7 +226,7 @@ with unpack support written by .An Xin LI Aq delphij@FreeBSD.org . .Sh BUGS According to RFC 1952, the recorded file size is stored in a 32-bit -integer, therefore, it can not represent files larger than 4GB. +integer, therefore, it cannot represent files larger than 4GB. This limitation also applies to .Fl l option of diff --git a/usr.bin/gzip/gzip.c b/usr.bin/gzip/gzip.c index 495392b..eba7a9d 100644 --- a/usr.bin/gzip/gzip.c +++ b/usr.bin/gzip/gzip.c @@ -1,4 +1,4 @@ -/* $NetBSD: gzip.c,v 1.108 2015/04/15 02:29:12 christos Exp $ */ +/* $NetBSD: gzip.c,v 1.109 2015/10/27 07:36:18 mrg Exp $ */ /*- * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green @@ -810,6 +810,7 @@ gz_uncompress(int in, int out, char *pre, size_t prelen, off_t *gsizep, if (in_tot > 0) { maybe_warnx("%s: trailing garbage " "ignored", filename); + exit_value = 2; goto stop; } maybe_warnx("input not gziped (MAGIC0)"); diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index ee0f106..5b277af 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -258,7 +258,8 @@ fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip) * with vm_suspend(). */ error = vm_activate_cpu(ctx, newcpu); - assert(error == 0); + if (error != 0) + err(EX_OSERR, "could not activate CPU %d", newcpu); CPU_SET_ATOMIC(newcpu, &cpumask); diff --git a/usr.sbin/bluetooth/sdpcontrol/search.c b/usr.sbin/bluetooth/sdpcontrol/search.c index e7d8244..09ef5a3 100644 --- a/usr.sbin/bluetooth/sdpcontrol/search.c +++ b/usr.sbin/bluetooth/sdpcontrol/search.c @@ -102,6 +102,12 @@ print_service_class_id_list(uint8_t const *start, uint8_t const *end) /* NOT REACHED */ } + if (len > (end - start)) { + fprintf(stderr, "Invalid Service Class ID List. " \ + "Too long len=%d\n", len); + return; + } + while (start < end) { SDP_GET8(type, start); switch (type) { @@ -258,28 +264,31 @@ print_protocol_descriptor(uint8_t const *start, uint8_t const *end) case SDP_DATA_STR8: case SDP_DATA_URL8: SDP_GET8(len, start); - fprintf(stdout, "%*.*s\n", len, len, (char *) start); - start += len; + for (; start < end && len > 0; start ++, len --) + fprintf(stdout, "%c", *start); + fprintf(stdout, "\n"); break; case SDP_DATA_STR16: case SDP_DATA_URL16: SDP_GET16(len, start); - fprintf(stdout, "%*.*s\n", len, len, (char *) start); - start += len; + for (; start < end && len > 0; start ++, len --) + fprintf(stdout, "%c", *start); + fprintf(stdout, "\n"); break; case SDP_DATA_STR32: case SDP_DATA_URL32: SDP_GET32(len, start); - fprintf(stdout, "%*.*s\n", len, len, (char *) start); - start += len; + for (; start < end && len > 0; start ++, len --) + fprintf(stdout, "%c", *start); + fprintf(stdout, "\n"); break; case SDP_DATA_SEQ8: case SDP_DATA_ALT8: SDP_GET8(len, start); - for (; len > 0; start ++, len --) + for (; start < end && len > 0; start ++, len --) fprintf(stdout, "%#2.2x ", *start); fprintf(stdout, "\n"); break; @@ -287,7 +296,7 @@ print_protocol_descriptor(uint8_t const *start, uint8_t const *end) case SDP_DATA_SEQ16: case SDP_DATA_ALT16: SDP_GET16(len, start); - for (; len > 0; start ++, len --) + for (; start < end && len > 0; start ++, len --) fprintf(stdout, "%#2.2x ", *start); fprintf(stdout, "\n"); break; @@ -295,7 +304,7 @@ print_protocol_descriptor(uint8_t const *start, uint8_t const *end) case SDP_DATA_SEQ32: case SDP_DATA_ALT32: SDP_GET32(len, start); - for (; len > 0; start ++, len --) + for (; start < end && len > 0; start ++, len --) fprintf(stdout, "%#2.2x ", *start); fprintf(stdout, "\n"); break; @@ -341,6 +350,12 @@ print_protocol_descriptor_list(uint8_t const *start, uint8_t const *end) /* NOT REACHED */ } + if (len > (end - start)) { + fprintf(stderr, "Invalid Protocol Descriptor List. " \ + "Too long, len=%d\n", len); + return; + } + while (start < end) { SDP_GET8(type, start); switch (type) { @@ -363,6 +378,12 @@ print_protocol_descriptor_list(uint8_t const *start, uint8_t const *end) /* NOT REACHED */ } + if (len > (end - start)) { + fprintf(stderr, "Invalid Protocol Descriptor List. " \ + "Too long, len=%d\n", len); + return; + } + print_protocol_descriptor(start, start + len); start += len; } @@ -415,6 +436,12 @@ print_bluetooth_profile_descriptor_list(uint8_t const *start, uint8_t const *end /* NOT REACHED */ } + if (len > (end - start)) { + fprintf(stderr, "Invalid Bluetooth Profile Descriptor List. " \ + "Too long, len=%d\n", len); + return; + } + while (start < end) { SDP_GET8(type, start); switch (type) { @@ -438,6 +465,13 @@ print_bluetooth_profile_descriptor_list(uint8_t const *start, uint8_t const *end /* NOT REACHED */ } + if (len > (end - start)) { + fprintf(stderr, "Invalid Bluetooth Profile " \ + "Descriptor List. " \ + "Too long, len=%d\n", len); + return; + } + /* Get UUID */ SDP_GET8(type, start); switch (type) { diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile index 6253148..f1afc55 100644 --- a/usr.sbin/makefs/Makefile +++ b/usr.sbin/makefs/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <bsd.own.mk> + PROG= makefs CFLAGS+=-I${.CURDIR} @@ -38,4 +40,8 @@ LDADD+= ${LIBNETBSD} DPADD+= ${LIBSBUF} ${LIBUTIL} LDADD+= -lsbuf -lutil +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.prog.mk> diff --git a/usr.sbin/makefs/cd9660.c b/usr.sbin/makefs/cd9660.c index ea4ed44..dcee66f 100644 --- a/usr.sbin/makefs/cd9660.c +++ b/usr.sbin/makefs/cd9660.c @@ -296,8 +296,8 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts) int rv; /* Set up allowed options - integer options ONLY */ option_t cd9660_options[] = { - { "l", &diskStructure.isoLevel, 1, 3, "ISO Level" }, - { "isolevel", &diskStructure.isoLevel, 1, 3, "ISO Level" }, + { "l", &diskStructure.isoLevel, 1, 2, "ISO Level" }, + { "isolevel", &diskStructure.isoLevel, 1, 2, "ISO Level" }, { "verbose", &diskStructure.verbose_level, 0, 2, "Turns on verbose output" }, { "v", &diskStructure.verbose_level, 0 , 2, @@ -1055,6 +1055,7 @@ cd9660_rename_filename(cd9660node *iter, int num, int delete_chars) if (diskStructure.verbose_level > 0) printf("Rename_filename called\n"); + assert(1 <= diskStructure.isoLevel && diskStructure.isoLevel <= 2); /* TODO : A LOT of chanes regarding 8.3 filenames */ if (diskStructure.isoLevel == 1) maxlength = 8; @@ -1730,6 +1731,7 @@ cd9660_joliet_convert_filename(const char *oldname, char *newname, int is_file) static int cd9660_convert_filename(const char *oldname, char *newname, int is_file) { + assert(1 <= diskStructure.isoLevel && diskStructure.isoLevel <= 2); /* NEW */ cd9660_filename_conversion_functor conversion_function = 0; if (diskStructure.isoLevel == 1) diff --git a/usr.sbin/makefs/cd9660/cd9660_write.c b/usr.sbin/makefs/cd9660/cd9660_write.c index f27a76f..e17752a 100644 --- a/usr.sbin/makefs/cd9660/cd9660_write.c +++ b/usr.sbin/makefs/cd9660/cd9660_write.c @@ -165,7 +165,7 @@ cd9660_write_path_table(FILE *fd, off_t sector, int mode) diskStructure.pathTableLength); unsigned char *buffer; unsigned char *buffer_head; - int len; + int len, ret; path_table_entry temp_entry; cd9660node *ptcur; @@ -213,8 +213,10 @@ cd9660_write_path_table(FILE *fd, off_t sector, int mode) ptcur = ptcur->ptnext; } - return cd9660_write_filedata(fd, sector, buffer_head, + ret = cd9660_write_filedata(fd, sector, buffer_head, path_table_sectors); + free(buffer_head); + return ret; } diff --git a/usr.sbin/makefs/cd9660/iso9660_rrip.c b/usr.sbin/makefs/cd9660/iso9660_rrip.c index 5382857..749747b 100644 --- a/usr.sbin/makefs/cd9660/iso9660_rrip.c +++ b/usr.sbin/makefs/cd9660/iso9660_rrip.c @@ -1,4 +1,4 @@ -/* $NetBSD: iso9660_rrip.c,v 1.11 2012/04/29 13:32:21 joerg Exp $ */ +/* $NetBSD: iso9660_rrip.c,v 1.14 2014/05/30 13:14:47 martin Exp $ */ /* * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan @@ -656,13 +656,14 @@ cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode) pn_field->attr.rr_entry.PN.h.length[0] = 20; pn_field->attr.rr_entry.PN.h.version[0] = 1; - if (sizeof (fnode->inode->st.st_dev) > 32) - cd9660_bothendian_dword((uint64_t)fnode->inode->st.st_dev >> 32, + if (sizeof (fnode->inode->st.st_rdev) > 4) + cd9660_bothendian_dword( + (uint64_t)fnode->inode->st.st_rdev >> 32, pn_field->attr.rr_entry.PN.high); else cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high); - cd9660_bothendian_dword(fnode->inode->st.st_dev & 0xffffffff, + cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff, pn_field->attr.rr_entry.PN.low); return 1; } diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 459d9ed..fb5403e 100644 --- a/usr.sbin/makefs/ffs.c +++ b/usr.sbin/makefs/ffs.c @@ -410,6 +410,10 @@ ffs_validate(const char *dir, fsnode *root, fsinfo_t *fsopts) /* round up to the next block */ fsopts->size = roundup(fsopts->size, ffs_opts->bsize); + /* round up to requested block size, if any */ + if (fsopts->roundup > 0) + fsopts->size = roundup(fsopts->size, fsopts->roundup); + /* calculate density if necessary */ if (ffs_opts->density == -1) ffs_opts->density = fsopts->size / fsopts->inodes + 1; diff --git a/usr.sbin/makefs/ffs/ffs_bswap.c b/usr.sbin/makefs/ffs/ffs_bswap.c index a1a1c46..e62eb19 100644 --- a/usr.sbin/makefs/ffs/ffs_bswap.c +++ b/usr.sbin/makefs/ffs/ffs_bswap.c @@ -67,7 +67,7 @@ void ffs_csumtotal_swap(struct csum_total *o, struct csum_total *n); void ffs_sb_swap(struct fs *o, struct fs *n) { - int i; + size_t i; u_int32_t *o32, *n32; /* @@ -97,7 +97,7 @@ ffs_sb_swap(struct fs *o, struct fs *n) n->fs_csaddr = bswap64(o->fs_csaddr); n->fs_pendingblocks = bswap64(o->fs_pendingblocks); n->fs_pendinginodes = bswap32(o->fs_pendinginodes); - + /* These fields overlap with the second half of the * historic FS_42POSTBLFMT postbl table */ @@ -171,9 +171,9 @@ ffs_dinode2_swap(struct ufs2_dinode *o, struct ufs2_dinode *n) void ffs_csum_swap(struct csum *o, struct csum *n, int size) { - int i; + size_t i; u_int32_t *oint, *nint; - + oint = (u_int32_t*)o; nint = (u_int32_t*)n; diff --git a/usr.sbin/makefs/ffs/mkfs.c b/usr.sbin/makefs/ffs/mkfs.c index f99ecab..b1bdd09 100644 --- a/usr.sbin/makefs/ffs/mkfs.c +++ b/usr.sbin/makefs/ffs/mkfs.c @@ -248,15 +248,16 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts) exit(21); } sblock.fs_fsbtodb = ilog2(sblock.fs_fsize / sectorsize); - sblock.fs_size = fssize = dbtofsb(&sblock, fssize); + sblock.fs_size = sblock.fs_providersize = fssize = + dbtofsb(&sblock, fssize); if (Oflag <= 1) { sblock.fs_magic = FS_UFS1_MAGIC; sblock.fs_sblockloc = SBLOCK_UFS1; - sblock.fs_nindir = sblock.fs_bsize / sizeof(int32_t); + sblock.fs_nindir = sblock.fs_bsize / sizeof(ufs1_daddr_t); sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode); sblock.fs_maxsymlinklen = ((NDADDR + NIADDR) * - sizeof (int32_t)); + sizeof (ufs1_daddr_t)); sblock.fs_old_inodefmt = FS_44INODEFMT; sblock.fs_old_cgoffset = 0; sblock.fs_old_cgmask = 0xffffffff; @@ -272,15 +273,11 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts) sblock.fs_old_nrpos = 1; } else { sblock.fs_magic = FS_UFS2_MAGIC; -#if 0 /* XXX makefs is used for small filesystems. */ sblock.fs_sblockloc = SBLOCK_UFS2; -#else - sblock.fs_sblockloc = SBLOCK_UFS1; -#endif - sblock.fs_nindir = sblock.fs_bsize / sizeof(int64_t); + sblock.fs_nindir = sblock.fs_bsize / sizeof(ufs2_daddr_t); sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs2_dinode); sblock.fs_maxsymlinklen = ((NDADDR + NIADDR) * - sizeof (int64_t)); + sizeof (ufs2_daddr_t)); } sblock.fs_sblkno = diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8 index 51e536f..6b8f5cd 100644 --- a/usr.sbin/makefs/makefs.8 +++ b/usr.sbin/makefs/makefs.8 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 16, 2013 +.Dd October 29, 2015 .Dt MAKEFS 8 .Os .Sh NAME @@ -53,6 +53,7 @@ .Op Fl m Ar maximum-size .Op Fl N Ar userdb-dir .Op Fl o Ar fs-options +.Op Fl R Ar roundup-size .Op Fl S Ar sector-size .Op Fl s Ar image-size .Op Fl t Ar fs-type @@ -195,6 +196,14 @@ Deprecated. See the .Fl Z flag. +.It Fl R Ar roundup-size +Round the image up to +.Ar roundup-size . +.Ar roundup-size +should be a multiple of the file system block size. +This option only applies to the +.Sy ffs +file system type. .It Fl S Ar sector-size Set the file system sector size to .Ar sector-size . diff --git a/usr.sbin/makefs/makefs.c b/usr.sbin/makefs/makefs.c index bf10034..bca9722 100644 --- a/usr.sbin/makefs/makefs.c +++ b/usr.sbin/makefs/makefs.c @@ -113,7 +113,7 @@ main(int argc, char *argv[]) start_time.tv_sec = start.tv_sec; start_time.tv_nsec = start.tv_usec * 1000; - while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:ps:S:t:xZ")) != -1) { + while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:pr:s:S:t:xZ")) != -1) { switch (ch) { case 'B': @@ -209,6 +209,12 @@ main(int argc, char *argv[]) fsoptions.sparse = 1; break; + case 'R': + /* Round image size up to specified block size */ + fsoptions.roundup = + strsuftoll("roundup-size", optarg, 0, LLONG_MAX); + break; + case 's': fsoptions.minsize = fsoptions.maxsize = strsuftoll("size", optarg, 1LL, LLONG_MAX); @@ -359,9 +365,9 @@ usage(void) prog = getprogname(); fprintf(stderr, "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n" -"\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-s image-size]\n" -"\t[-b free-blocks] [-f free-files] [-F mtree-specfile] [-xZ]\n" -"\t[-N userdb-dir] image-file directory | manifest [extra-directory ...]\n", +"\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-R roundup-size]\n" +"\t[-s image-size] [-b free-blocks] [-f free-files] [-F mtree-specfile]\n" +"\t[-xZ] [-N userdb-dir] image-file directory | manifest [extra-directory ...]\n", prog); exit(1); } diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h index 5ab0444..ba80f74 100644 --- a/usr.sbin/makefs/makefs.h +++ b/usr.sbin/makefs/makefs.h @@ -130,6 +130,7 @@ typedef struct { int needswap; /* non-zero if byte swapping needed */ int sectorsize; /* sector size */ int sparse; /* sparse image, don't fill it with zeros */ + off_t roundup; /* round image size up to this value */ void *fs_specific; /* File system specific additions. */ } fsinfo_t; diff --git a/usr.sbin/makefs/tests/Makefile b/usr.sbin/makefs/tests/Makefile new file mode 100644 index 0000000..0d1a1b6 --- /dev/null +++ b/usr.sbin/makefs/tests/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/usr.sbin/makefs + +ATF_TESTS_SH+= makefs_cd9660_tests +ATF_TESTS_SH+= makefs_ffs_tests + +BINDIR= ${TESTSDIR} + +SCRIPTS+= makefs_tests_common.sh +SCRIPTSNAME_makefs_tests_common.sh= makefs_tests_common.sh + +.for t in ${ATF_TESTS_SH} +TEST_METADATA.$t+= required_user="root" +.endfor + +.include <bsd.test.mk> diff --git a/usr.sbin/makefs/tests/makefs_cd9660_tests.sh b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh new file mode 100755 index 0000000..161b56b --- /dev/null +++ b/usr.sbin/makefs/tests/makefs_cd9660_tests.sh @@ -0,0 +1,373 @@ +# +# Copyright 2015 EMC Corp. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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$ +# + +# A note on specs: +# - A copy of the ISO-9660 spec can be found here: +# http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf +# - Any references to `rockridge` are referring to the `Rock Ridge` extensions +# of the ISO-9660 spec. A copy of the draft `IEEE-P1282` spec can be found +# here: +# http://www.ymi.com/ymi/sites/default/files/pdf/Rockridge.pdf + +MAKEFS="makefs -t cd9660" +MOUNT="mount_cd9660" + +. "$(dirname "$0")/makefs_tests_common.sh" + +common_cleanup() +{ + if ! test_md_device=$(cat $TEST_MD_DEVICE_FILE); then + echo "$TEST_MD_DEVICE_FILE could not be opened; has an md(4) device been attached?" + return + fi + + umount -f /dev/$test_md_device || : + mdconfig -d -u $test_md_device || : +} + +check_base_iso9660_image_contents() +{ + # Symlinks are treated like files when rockridge support isn't + # specified + check_image_contents "$@" -X c + + atf_check -e empty -o empty -s exit:0 test -L $TEST_INPUTS_DIR/c + atf_check -e empty -o empty -s exit:0 test -f $TEST_MOUNT_DIR/c +} + +atf_test_case D_flag cleanup +D_flag_body() +{ + atf_skip "makefs crashes with SIGBUS with dupe mtree entries; see FreeBSD bug # 192839" + + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -cp $TEST_INPUTS_DIR + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + atf_check -e empty -o empty -s exit:0 \ + cp $TEST_SPEC_FILE spec2.mtree + atf_check -e empty -o save:dupe_$TEST_SPEC_FILE -s exit:0 \ + cat $TEST_SPEC_FILE spec2.mtree + + atf_check -e empty -o not-empty -s not-exit:0 \ + $MAKEFS -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -D -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR +} +D_flag_cleanup() +{ + common_cleanup +} + +atf_test_case F_flag cleanup +F_flag_body() +{ + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -cp $TEST_INPUTS_DIR + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +F_flag_cleanup() +{ + common_cleanup +} + +atf_test_case from_mtree_spec_file cleanup +from_mtree_spec_file_body() +{ + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -c -k "$DEFAULT_MTREE_KEYWORDS" -p $TEST_INPUTS_DIR + cd $TEST_INPUTS_DIR + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS $TEST_IMAGE $TEST_SPEC_FILE + cd - + + mount_image + check_base_iso9660_image_contents +} +from_mtree_spec_file_cleanup() +{ + common_cleanup +} + +atf_test_case from_multiple_dirs cleanup +from_multiple_dirs_body() +{ + test_inputs_dir2=$TMPDIR/inputs2 + + create_test_inputs + + atf_check -e empty -o empty -s exit:0 mkdir -p $test_inputs_dir2 + atf_check -e empty -o empty -s exit:0 \ + touch $test_inputs_dir2/multiple_dirs_test_file + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR $test_inputs_dir2 + + mount_image + check_base_iso9660_image_contents -d $test_inputs_dir2 +} +from_multiple_dirs_cleanup() +{ + common_cleanup +} + +atf_test_case from_single_dir cleanup +from_single_dir_body() +{ + create_test_inputs + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +from_single_dir_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_allow_deep_trees cleanup +o_flag_allow_deep_trees_body() +{ + create_test_inputs + + # Make sure the "more than 8 levels deep" requirement is met. + atf_check -e empty -o empty -s exit:0 \ + mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o allow-deep-trees $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_allow_deep_trees_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_allow_max_name cleanup +o_flag_allow_max_name_body() +{ + atf_expect_fail "-o allow-max-name doesn't appear to be implemented on FreeBSD's copy of makefs [yet]" + + create_test_inputs + + long_path=$TEST_INPUTS_DIR/$(jot -s '' -b 0 37) + + # Make sure the "37 char name" limit requirement is met. + atf_check -e empty -o empty -s exit:0 touch $long_path + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o allow-max-name $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_allow_max_name_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_isolevel_1 cleanup +o_flag_isolevel_1_body() +{ + atf_expect_fail "this testcase needs work; the filenames generated seem incorrect/corrupt" + + create_test_inputs + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=1 $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_isolevel_1_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_isolevel_2 cleanup +o_flag_isolevel_2_body() +{ + create_test_inputs + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=2 $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_base_iso9660_image_contents +} +o_flag_isolevel_2_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_isolevel_3 cleanup +o_flag_isolevel_3_body() +{ + create_test_inputs + + # XXX: isolevel=3 isn't implemented yet. See FreeBSD bug # 203645 + if true; then + atf_check -e match:'makefs: ISO Level 3 is greater than 2\.' -o empty -s not-exit:0 \ + $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR + else + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR + mount_image + check_base_iso9660_image_contents + fi +} +o_flag_isolevel_3_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_preparer +o_flag_preparer_body() +{ + create_test_dirs + + preparer='My Very First ISO' + preparer_uppercase="$(echo $preparer | tr '[[:lower:]]' '[[:upper:]]')" + + atf_check -e empty -o empty -s exit:0 touch $TEST_INPUTS_DIR/dummy_file + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o preparer="$preparer" $TEST_IMAGE $TEST_INPUTS_DIR + atf_check -e empty -o match:"$preparer_uppercase" -s exit:0 \ + strings $TEST_IMAGE +} + +atf_test_case o_flag_publisher +o_flag_publisher_body() +{ + create_test_dirs + + publisher='My Super Awesome Publishing Company LTD' + publisher_uppercase="$(echo $publisher | tr '[[:lower:]]' '[[:upper:]]')" + + atf_check -e empty -o empty -s exit:0 touch $TEST_INPUTS_DIR/dummy_file + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o publisher="$publisher" $TEST_IMAGE $TEST_INPUTS_DIR + atf_check -e empty -o match:"$publisher_uppercase" -s exit:0 \ + strings $TEST_IMAGE +} + +atf_test_case o_flag_rockridge cleanup +o_flag_rockridge_body() +{ + create_test_dirs + + # Make sure the "more than 8 levels deep" requirement is met. + atf_check -e empty -o empty -s exit:0 \ + mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j + + # Make sure the "pathname larger than 255 chars" requirement is met. + # + # $long_path's needs to be nested in a directory, as creating it + # outright as a 256 char filename via touch will fail with ENAMETOOLONG + long_path=$TEST_INPUTS_DIR/$(jot -s '/' -b "$(jot -s '' -b 0 64)" 4) + atf_check -e empty -o empty -s exit:0 mkdir -p "$(dirname $long_path)" + atf_check -e empty -o empty -s exit:0 touch "$long_path" + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_image_contents -X .rr_moved + + # .rr_moved is a special directory created when you have deep directory + # trees with rock ridge extensions on + atf_check -e empty -o empty -s exit:0 \ + test -d $TEST_MOUNT_DIR/.rr_moved +} +o_flag_rockridge_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_rockridge_dev_nodes cleanup +o_flag_rockridge_dev_nodes_head() +{ + atf_set "descr" "Functional tests to ensure that dev nodes are handled properly with rockridge extensions (NetBSD kern/48852; FreeBSD bug 203648)" +} +o_flag_rockridge_dev_nodes_body() +{ + create_test_dirs + + (tar -cvf - -C /dev null && touch .tar_ok) | \ + atf_check -e not-empty -o empty -s exit:0 tar -xvf - -C "$TEST_INPUTS_DIR" + + atf_check -e empty -o empty -s exit:0 test -c $TEST_INPUTS_DIR/null + atf_check -e empty -o empty -s exit:0 test -f .tar_ok + + atf_check -e empty -o empty -s exit:0 \ + $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_image_contents +} +o_flag_rockridge_dev_nodes_cleanup() +{ + common_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case D_flag + atf_add_test_case F_flag + + atf_add_test_case from_mtree_spec_file + atf_add_test_case from_multiple_dirs + atf_add_test_case from_single_dir + + atf_add_test_case o_flag_allow_deep_trees + atf_add_test_case o_flag_allow_max_name + atf_add_test_case o_flag_isolevel_1 + atf_add_test_case o_flag_isolevel_2 + atf_add_test_case o_flag_isolevel_3 + atf_add_test_case o_flag_preparer + atf_add_test_case o_flag_publisher + atf_add_test_case o_flag_rockridge + atf_add_test_case o_flag_rockridge_dev_nodes +} diff --git a/usr.sbin/makefs/tests/makefs_ffs_tests.sh b/usr.sbin/makefs/tests/makefs_ffs_tests.sh new file mode 100755 index 0000000..121c2a2 --- /dev/null +++ b/usr.sbin/makefs/tests/makefs_ffs_tests.sh @@ -0,0 +1,237 @@ +# +# Copyright 2015 EMC Corp. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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$ +# + +MAKEFS="makefs -t ffs" +MOUNT="mount" + +. "$(dirname "$0")/makefs_tests_common.sh" + +TEST_TUNEFS_OUTPUT=$TMPDIR/tunefs.output + +common_cleanup() +{ + if ! test_md_device=$(cat $TEST_MD_DEVICE_FILE); then + echo "$TEST_MD_DEVICE_FILE could not be opened; has an md(4) device been attached?" + return + fi + + umount -f /dev/$test_md_device || : + mdconfig -d -u $test_md_device || : +} + +check_ffs_image_contents() +{ + atf_check -e save:$TEST_TUNEFS_OUTPUT -o empty -s exit:0 \ + tunefs -p /dev/$(cat $TEST_MD_DEVICE_FILE) + + check_image_contents "$@" +} + +atf_test_case D_flag cleanup +D_flag_body() +{ + atf_skip "makefs crashes with SIGBUS with dupe mtree entries; see FreeBSD bug # 192839" + + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -cp $TEST_INPUTS_DIR + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + atf_check -e empty -o empty -s exit:0 \ + cp $TEST_SPEC_FILE spec2.mtree + atf_check -e empty -o save:dupe_$TEST_SPEC_FILE -s exit:0 \ + cat $TEST_SPEC_FILE spec2.mtree + + atf_check -e empty -o not-empty -s not-exit:0 \ + $MAKEFS -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -D -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR +} +D_flag_cleanup() +{ + common_cleanup +} + +atf_test_case F_flag cleanup +F_flag_body() +{ + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -cp $TEST_INPUTS_DIR + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_ffs_image_contents +} +F_flag_cleanup() +{ + common_cleanup +} + +atf_test_case from_mtree_spec_file cleanup +from_mtree_spec_file_body() +{ + create_test_inputs + + atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ + mtree -c -k "$DEFAULT_MTREE_KEYWORDS" -p $TEST_INPUTS_DIR + + cd $TEST_INPUTS_DIR + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS $TEST_IMAGE $TEST_SPEC_FILE + cd - + + mount_image + check_ffs_image_contents +} +from_mtree_spec_file_cleanup() +{ + common_cleanup +} + +atf_test_case from_multiple_dirs cleanup +from_multiple_dirs_body() +{ + test_inputs_dir2=$TMPDIR/inputs2 + + create_test_inputs + + atf_check -e empty -o empty -s exit:0 mkdir -p $test_inputs_dir2 + atf_check -e empty -o empty -s exit:0 \ + touch $test_inputs_dir2/multiple_dirs_test_file + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR $test_inputs_dir2 + + mount_image + check_image_contents -d $test_inputs_dir2 +} +from_multiple_dirs_cleanup() +{ + common_cleanup +} + +atf_test_case from_single_dir cleanup +from_single_dir_body() +{ + create_test_inputs + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + check_ffs_image_contents +} +from_single_dir_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_version_1 cleanup +o_flag_version_1_body() +{ + ffs_version=1 + + platform=$(uname) + case "$platform" in + FreeBSD) + ffs_label=UFS${ffs_version} + ;; + NetBSD) + ffs_label=FFSv${ffs_version} + ;; + *) + atf_skip "Unsupported platform" + ;; + esac + + create_test_inputs + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m -o version=$ffs_version $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + atf_check -e empty -o match:"$ffs_label" dumpfs $TEST_MOUNT_DIR + check_ffs_image_contents +} +o_flag_version_1_cleanup() +{ + common_cleanup +} + +atf_test_case o_flag_version_2 cleanup +o_flag_version_2_body() +{ + ffs_version=2 + + platform=$(uname) + case "$platform" in + FreeBSD) + ffs_label=UFS${ffs_version} + ;; + NetBSD) + ffs_label=FFSv${ffs_version} + ;; + *) + atf_skip "Unsupported platform" + ;; + esac + + create_test_inputs + + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m -o version=$ffs_version $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + atf_check -e empty -o match:"$ffs_label" dumpfs $TEST_MOUNT_DIR + check_ffs_image_contents +} +o_flag_version_2_cleanup() +{ + common_cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case D_flag + atf_add_test_case F_flag + + atf_add_test_case from_mtree_spec_file + atf_add_test_case from_multiple_dirs + atf_add_test_case from_single_dir + + atf_add_test_case o_flag_version_1 + atf_add_test_case o_flag_version_2 +} diff --git a/usr.sbin/makefs/tests/makefs_tests_common.sh b/usr.sbin/makefs/tests/makefs_tests_common.sh new file mode 100755 index 0000000..add0b88 --- /dev/null +++ b/usr.sbin/makefs/tests/makefs_tests_common.sh @@ -0,0 +1,152 @@ +# +# Copyright 2015 EMC Corp. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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$ +# + +KB=1024 +: ${TMPDIR=/tmp} +# TODO: add mtree `time` support; get a lot of errors like this right now when +# passing generating disk images with keyword mtree support, like: +# +# `[...]/mtree.spec:8: error: time: invalid value '1446458503'` +# +#DEFAULT_MTREE_KEYWORDS="type,mode,gid,uid,size,link,time" +DEFAULT_MTREE_KEYWORDS="type,mode,gid,uid,size,link" +TEST_IMAGE="$TMPDIR/test.img" +TEST_INPUTS_DIR="$TMPDIR/inputs" +TEST_MD_DEVICE_FILE="$TMPDIR/md.output" +TEST_MOUNT_DIR="$TMPDIR/mnt" +TEST_SPEC_FILE="$TMPDIR/mtree.spec" + +check_image_contents() +{ + local directories=$TEST_INPUTS_DIR + local excludes mtree_excludes_arg mtree_file + local mtree_keywords="$DEFAULT_MTREE_KEYWORDS" + + while getopts "d:f:m:X:" flag; do + case "$flag" in + d) + directories="$directories $OPTARG" + ;; + f) + mtree_file=$OPTARG + ;; + m) + mtree_keywords=$OPTARG + ;; + X) + excludes="$excludes $OPTARG" + ;; + *) + echo "usage: check_image_contents [-d directory ...] [-f mtree-file] [-m mtree-keywords] [-X exclude]" + atf_fail "unhandled option: $flag" + ;; + esac + done + + if [ -n "$excludes" ]; then + echo "$excludes" | tr ' ' '\n' > excludes.txt + mtree_excludes_arg="-X excludes.txt" + fi + + if [ -z "$mtree_file" ]; then + mtree_file=input_spec.mtree + for directory in $directories; do + mtree -c -k $mtree_keywords -p $directory $mtree_excludes_arg + done > $mtree_file + fi + + echo "<---- Input spec BEGIN ---->" + cat $mtree_file + echo "<---- Input spec END ---->" + atf_check -e empty -o empty -s exit:0 \ + mtree -UW -f $mtree_file \ + -p $TEST_MOUNT_DIR \ + $mtree_excludes_arg +} + +create_test_dirs() +{ + atf_check -e empty -s exit:0 mkdir -m 0777 -p $TEST_MOUNT_DIR + atf_check -e empty -s exit:0 mkdir -m 0777 -p $TEST_INPUTS_DIR +} + +create_test_inputs() +{ + create_test_dirs + + cd $TEST_INPUTS_DIR + + atf_check -e empty -s exit:0 mkdir -m 0755 -p a/b/1 + atf_check -e empty -s exit:0 ln -s a/b c + atf_check -e empty -s exit:0 touch d + atf_check -e empty -s exit:0 ln d e + atf_check -e empty -s exit:0 touch .f + atf_check -e empty -s exit:0 mkdir .g + # XXX: fifos on the filesystem don't match fifos created by makefs for + # some odd reason. + #atf_check -e empty -s exit:0 mkfifo h + atf_check -e ignore -s exit:0 dd if=/dev/zero of=i count=1000 bs=1 + atf_check -e empty -s exit:0 touch klmn + atf_check -e empty -s exit:0 touch opqr + atf_check -e empty -s exit:0 touch stuv + atf_check -e empty -s exit:0 install -m 0755 /dev/null wxyz + atf_check -e empty -s exit:0 touch 0b00000001 + atf_check -e empty -s exit:0 touch 0b00000010 + atf_check -e empty -s exit:0 touch 0b00000011 + atf_check -e empty -s exit:0 touch 0b00000100 + atf_check -e empty -s exit:0 touch 0b00000101 + atf_check -e empty -s exit:0 touch 0b00000110 + atf_check -e empty -s exit:0 touch 0b00000111 + atf_check -e empty -s exit:0 touch 0b00001000 + atf_check -e empty -s exit:0 touch 0b00001001 + atf_check -e empty -s exit:0 touch 0b00001010 + atf_check -e empty -s exit:0 touch 0b00001011 + atf_check -e empty -s exit:0 touch 0b00001100 + atf_check -e empty -s exit:0 touch 0b00001101 + atf_check -e empty -s exit:0 touch 0b00001110 + + for filesize in 1 512 $(( 2 * $KB )) $(( 10 * $KB )) $(( 512 * $KB )); \ + do + atf_check -e ignore -o empty -s exit:0 \ + dd if=/dev/zero of=${filesize}.file bs=1 \ + count=1 oseek=${filesize} conv=sparse + files="${files} ${filesize}.file" + done + + cd - +} + +mount_image() +{ + atf_check -e empty -o save:$TEST_MD_DEVICE_FILE -s exit:0 \ + mdconfig -a -f $TEST_IMAGE + atf_check -e empty -o empty -s exit:0 \ + $MOUNT /dev/$(cat $TEST_MD_DEVICE_FILE) $TEST_MOUNT_DIR +} + diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c index 46bdb1e..7710537 100644 --- a/usr.sbin/rtsold/rtsold.c +++ b/usr.sbin/rtsold/rtsold.c @@ -834,15 +834,15 @@ static void usage(void) { #ifndef SMALL - fprintf(stderr, "usage: rtsold [-adDfFm1] [-O script-name] " - "[-P pidfile] [-R script-name] interfaces...\n"); fprintf(stderr, "usage: rtsold [-dDfFm1] [-O script-name] " - "[-P pidfile] [-R script-name] -a\n"); + "[-p pidfile] [-R script-name] interface ...\n"); + fprintf(stderr, "usage: rtsold [-dDfFm1] [-O script-name] " + "[-p pidfile] [-R script-name] -a\n"); #else fprintf(stderr, "usage: rtsol [-dDF] [-O script-name] " - "[-P pidfile] [-R script-name] interfaces...\n"); + "[-p pidfile] [-R script-name] interface ...\n"); fprintf(stderr, "usage: rtsol [-dDF] [-O script-name] " - "[-P pidfile] [-R script-name] -a\n"); + "[-p pidfile] [-R script-name] -a\n"); #endif } |