[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[LTP] mmap001




I've attached a modified version of the mmap001 test from Juan
Quintela's (quintela@fi.udc.es) memtest suite:
http://carpanta.dc.fi.udc.es/~quintela/memtest/

It could be used "as is" but has a couple drawbacks.  I've made a few
mods to utilize our libs:
1.  The size of the mmap'ed file is a compile-time option.  Once
compiled, there is no way to change it.  I've added a -m <n> option
where n is the number of pages in size the mapped file should be.
2.  The temporary mmap'ed file is created in the current working
directory.  The immediate problem with this methodology is if all the
tests use the current working directory as temp space, they're
eventually going to leave garbage lying around. Also, multiple instances
of the test will collide.  I've used tst_tmpdir() and tst_rmdir() to
create and cleanup a temporary directory for the test.  Setting the
TDIRECTORY environment variable allows the manual setting of the
temporary directory.

--aaron

-- 
Aaron Laffin
Silicon Graphics, Inc. OS Test Development
Email: alaffin@sgi.com Voice: 651-683-5756
USA/MN/CRP/F5233/SSBU
/*
 * mmap001.c
 * 
 * Tests mmapping a big file and writing it once
 * 
 * (C) Juan Quintela <quintela@fi.udc.es>, 2000
 * (C) Silicon Graphics, Inc., Aaron Laffin <alaffin@sgi.com>
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

#include "test.h"
#include "usctest.h"

void cleanup()
{
  /*
   * remove the tmp directory and exit
   */
  tst_rmdir();

  tst_exit();
}

void setup()
{
  /*
   * setup a default signal hander and a
   * temporary working directory.
   */
  tst_sig(NOFORK, DEF_HANDLER, cleanup);

  tst_tmpdir();
}

char *TCID="mmap001";
int TST_TOTAL=1;
static char *filename = "mmap001_test_file";
static int m_opt = 0;
static char *m_copt;

/*
 * add the -m option whose parameter is the
 * pages that should be mapped.
 */
option_t options[] = 
{
  { "m:", &m_opt, &m_copt },
  { NULL, NULL, NULL }
};

int main(int argc, char * argv[])
{
  char *array,*msg;
  int i;
  int fd;
  int pages,memsize=getpagesize()*1024;

  if ( (msg=parse_opts(argc, argv, options)) != (char *) NULL )
   tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);

  if ( m_opt )
  {
    memsize = pages = atoi( m_copt );

    if (memsize < 1)
    {
      tst_brkm(TBROK, cleanup, "Invalid arg for -m: %s",m_copt);
    }

    memsize *= getpagesize(); /* N PAGES */

    tst_resm(TINFO,"mmap()ing file of %d pages or %d bytes",
      pages,memsize);
  }

  setup();
        
  fd = open(filename, O_RDWR | O_CREAT, 0666);
  if ((fd == -1))
          tst_brkm(TBROK, cleanup, "Problems opening files");
        
  if (lseek(fd, memsize, SEEK_SET) != memsize)
          tst_brkm(TBROK, cleanup, "Problems doing the lseek: %d: %s",
              errno,strerror(errno));

  if (write(fd,"\0",1) !=1)
          tst_brkm(TBROK, cleanup, "Problems writing: %d: %s",
              errno,strerror(errno));
 
  array = mmap(0, memsize, PROT_WRITE, MAP_SHARED,fd,0);
  if (array == (char *)MAP_FAILED)
  {
          tst_resm(TFAIL, "mmap() failed: %d: %s",
              errno,strerror(errno));
          tst_exit();
  }
  else
  {
          tst_resm(TPASS, "mmap() completed successfully.");
  }


  tst_resm(TINFO,"touching mmaped memory");

  for(i = 0; i < memsize; i++) {
          array[i] = (char) i;
  } 
 
  /*
   * seems that if the map area was bad, we'd get SEGV, hence we can
   * indicate a PASS.
   */
  tst_resm(TPASS, "we're still here, mmaped area must be good");

  msync(array, memsize, MS_SYNC);

  tst_resm(TPASS, "we're still here, msync() must have been successful");

  close(fd);
  unlink(filename);
  cleanup();
}