Subject: kern/6419: mmap
To: None <gnats-bugs@gnats.netbsd.org>
From: Andreas Wrede <andreas@planix.com>
List: netbsd-bugs
Date: 11/09/1998 19:00:21
>Number:         6419
>Category:       kern
>Synopsis:       mmap
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov  9 16:05:02 1998
>Last-Modified:
>Originator:     Andreas Wrede
>Organization:
Planix, Inc.
>Release:        <NetBSD-current source date>-current, Nov 4,98
>Environment:
	
System: NetBSD woffi 1.3H NetBSD 1.3H (WOFFI) #0: Wed Nov 4 20:44:02 EST 1998 root@woffi:/local1/netbsd/netbsd-current/src/sys/arch/i386/compile/WOFFI i386


>Description:
	
The configure script for the Cyrus imapd server ver 1.5.14 runs a test program 
to "Verify the OS supports the memory mapping semantics needed by 
map_private".

The program fails in different ways on both 1.3.2 and -current. On 1.3.2 it 
results in "private map does not show change", while on -current it prints 
"shared map does not match within page" (see code below).

I don't understand the intricacies of mmap well enough to see what is going 
on,  but the fact that there is a difference appears to indicate that we 
have a problem here.

Both 1.3.2 and -current are i386, -current is 1.3H from Nov 4, using gcc 
2.7.2.2, UVM and PMAP_NEW.
>How-To-Repeat:
	
Compile and run the code below. Jonathan Stone suggests to include the 
program below in a regress-test suite.
---[snip]---
    
/* Verify the OS supports the memory mapping semantics needed by map_private
 * from John Myers <jgmyers@netscape.com>
 */ 
    
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
    
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
    
/* not on Linux */ 
#ifndef MAP_VARIABLE
#define MAP_VARIABLE 0
#endif 

#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif 

fatal(char *s)
{   
    write(2, s, strlen(s));
    write(2, "\n", 1);
    unlink("conftestmmap");
    exit(1);
}   
    
main() {
    int fd = open("conftestmmap", O_RDWR|O_CREAT|O_TRUNC, 0666);
    int fd2;
    char *base_shared, *base_private, *base_private2;
    
    if (fd == -1) fatal("cannot create test file");
    if (write(fd, "test", 4) != 4) fatal("cannot write test file");
    base_shared = mmap((caddr_t)0, 10000, PROT_READ,
             MAP_SHARED | MAP_FILE| MAP_VARIABLE,
             fd, 0L);
    if (base_shared == MAP_FAILED) fatal("cannot create shared map"); 

    base_private = mmap((caddr_t)0, 4, PROT_READ,
             MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
             fd, 0L);
    if (base_private == MAP_FAILED) fatal("cannot create private map");
    
    base_private2 = mmap((caddr_t)0, 4, PROT_READ,
             MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
             fd, 0L);
    if (base_private == MAP_FAILED) fatal("cannot create private2 map");
    

    if (strncmp(base_shared, "test", 4) != 0) fatal("shared map does not match");   
    if (strncmp(base_private, "test", 4) != 0) fatal("private map does not match");

    if (write(fd, "test", 4) != 4) fatal("cannot extend test file within page");
    fsync(fd);
    msync((caddr_t)base_shared, 10000, MS_INVALIDATE);


    if (munmap(base_private, 4)) fatal("cannot unmap private map");
    base_private = mmap((caddr_t)0, 8, PROT_READ,
             MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
             fd, 0L); 
    if (base_private == MAP_FAILED) fatal("cannot create private map second time");

    if (strncmp(base_shared+4, "test", 4) != 0) fatal("shared map does not match within page"); 
    if (strncmp(base_private+4, "test", 4) != 0) fatal("private map does not match within page");
    
    fd2 = open("conftestmmap", O_RDWR, 0666);
    if (lseek(fd2, 0, 0) == -1) fatal("cannot seek second fd");
    if (write(fd2, "xyzy", 4) != 4) fatal("cannot write second fd");
    fsync(fd2);
    
    
    if (munmap(base_private, 8)) fatal("cannot unmap private map");
    base_private = mmap((caddr_t)0, 8, PROT_READ,  
             MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE, 
             fd, 0L);
    if (base_private == MAP_FAILED) fatal("cannot create private map third time");
    if (strncmp(base_private, "xyzy", 4) != 0) fatal("private map does not show change");
    
        
    {
        int i;
        for (i = 0; i < 9000; i++) {
            if (write(fd, "test", 4) != 4) fatal("cannot extend test file outside page");    
        }    
    }
   msync((caddr_t)base_shared, 10000, MS_INVALIDATE);
    msync((caddr_t)base_private, 10000, MS_INVALIDATE);
    
    if (strncmp(base_shared+9000, "test", 4) != 0) fatal("shared map does not match beyond page");
#if 0
    if (strncmp(base_private+9000, "test", 4) != 0) fatal("private map does notmatch beyond page");
#endif
    
    unlink("conftestmmap");
    exit(0);
}   
 
>Fix:
Unknown
>Audit-Trail:
>Unformatted:
mmap test program produces different results in -current and 1.3.2