Whamcloud - gitweb
updated from b_devel (8/14/03)
authormfrey <mfrey>
Thu, 14 Aug 2003 16:25:15 +0000 (16:25 +0000)
committermfrey <mfrey>
Thu, 14 Aug 2003 16:25:15 +0000 (16:25 +0000)
14 files changed:
lnet/klnds/lgmlnd/lgmnal.h
lnet/klnds/lgmlnd/lgmnal_api.c
lnet/klnds/lgmlnd/lgmnal_cb.c
lnet/klnds/lgmlnd/lgmnal_comm.c
lnet/klnds/lgmlnd/lgmnal_module.c
lnet/klnds/lgmlnd/lgmnal_utils.c
lustre/portals/knals/lgmnal/lgmnal.h
lustre/portals/knals/lgmnal/lgmnal_api.c
lustre/portals/knals/lgmnal/lgmnal_cb.c
lustre/portals/knals/lgmnal/lgmnal_comm.c
lustre/portals/knals/lgmnal/lgmnal_module.c
lustre/portals/knals/lgmnal/lgmnal_utils.c
lustre/tests/sleeptest.c [new file with mode: 0644]
lustre/tests/write_append_truncate.c [new file with mode: 0644]

index 1147078..8b496ec 100644 (file)
@@ -1,10 +1,22 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index 8e774bf..8322e83 100644 (file)
@@ -1,15 +1,24 @@
-
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
-
 /*
  *     Implements the API NAL functions
  */
index bb231af..dcd5446 100644 (file)
@@ -1,13 +1,23 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
-
 /*
  *     This file implements the nal cb functions
  */
index 091f665..4cd1b83 100644 (file)
@@ -1,12 +1,25 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 /*
  *     This file contains all lgmnal send and receive functions
  */
index 51383fc..ce870f0 100644 (file)
@@ -1,13 +1,23 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
-
 #include "lgmnal.h"
 
 
index 4f17c7b..8a91ca4 100644 (file)
@@ -1,10 +1,22 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index 1147078..8b496ec 100644 (file)
@@ -1,10 +1,22 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
index 8e774bf..8322e83 100644 (file)
@@ -1,15 +1,24 @@
-
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
-
 /*
  *     Implements the API NAL functions
  */
index bb231af..dcd5446 100644 (file)
@@ -1,13 +1,23 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
-
 /*
  *     This file implements the nal cb functions
  */
index 091f665..4cd1b83 100644 (file)
@@ -1,12 +1,25 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+
 /*
  *     This file contains all lgmnal send and receive functions
  */
index 51383fc..ce870f0 100644 (file)
@@ -1,13 +1,23 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
-
 #include "lgmnal.h"
 
 
index 4f17c7b..8a91ca4 100644 (file)
@@ -1,10 +1,22 @@
-/*
- * This program was prepared by the Regents of the University of
- * California at Los Alamos National Laboratory (the University) under 
- * contract number W-7405-ENG-36 with the U.S. Department of Energy
- * (DoE). Neither the U.S. Government nor the
- * University makes any warranty, express or implied, or assumes any
- * liability or responsibility for the use of this software.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (c) 2003 Los Alamos National Laboratory (LANL)
+ *
+ *   This file is part of Lustre, http://www.lustre.org/
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff --git a/lustre/tests/sleeptest.c b/lustre/tests/sleeptest.c
new file mode 100644 (file)
index 0000000..d8beceb
--- /dev/null
@@ -0,0 +1,115 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define BUFSIZE (4096)
+
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+int main(int argc, char *argv[])
+{
+
+       FILE *w_str;
+       int read_fd;
+       int rc, iter;
+       int line, delta, next;
+       int sleeptime = 0;
+       char *now_time;
+       const char ok_chars[] = "MonTueWedThuFriSatSun"
+                               "JanFebMarAprMayJunJulAugSepOctNovDec"
+                               "Line 0123456789 of file, written at:\n";
+
+       char buf_r[BUFSIZE];
+
+       char pathname[256] = "/mnt/lustre/linetest_";
+       char *host;
+
+       if (argc > 1) {
+               strncpy(pathname, argv[1], 255);
+               pathname[255] = '\0';
+       }
+
+       host = getenv("HOSTNAME");
+       if (host)
+               strcat(pathname, host);
+
+       if (argc > 2)
+               sleeptime = strtoul(argv[2], NULL, 0);
+
+       if (sleeptime == 0)
+               sleeptime = 30;
+
+       printf("Test file used is: %s at %ds intervals\n", pathname, sleeptime);
+
+       w_str = fopen(pathname, "wb");
+       if (w_str == NULL) {
+               perror("fopen");
+               exit(1);
+       }
+       read_fd = open(pathname, O_RDONLY);
+       if (read_fd < 0) {
+               perror("open");
+               exit(1);
+       }
+
+       next = 1;
+       delta = 17;
+       iter = 1;
+       while (1) {
+               time_t now;
+               struct tm *t;
+               long offset;
+
+               now = time((time_t *)NULL);
+               t = localtime(&now);
+               now_time = asctime(t);
+
+               printf("iter: %d\n", iter);
+
+               for (line=next; line<(next+delta); line++) {
+                       rc = fprintf(w_str, "Line %8d of file, written at: %s",
+                                    line, now_time);
+                       /* \n comes from ctime() result */
+                       if (rc <= 0) {
+                               perror("fprintf");
+                               exit(4);
+                       }
+                       rc = fflush(w_str);
+                       if (rc != 0) {
+                               perror("fflush");
+                               exit(5);
+                       }
+               }
+               next += delta;
+
+               /* Check for corruption */
+               offset = ftell(w_str);
+               rc = lseek(read_fd, offset & ~4095, SEEK_SET);
+               if (rc != (offset & ~4095)) {
+                       perror("lseek");
+                       exit(7);
+               }
+
+               rc = read(read_fd, buf_r, min(100, offset & 4095));
+               if (rc != min(100, offset & 4095)) {
+                       printf("rc: %d, off %lu buf: '%s'\n", rc,offset,buf_r);
+                       exit(8);
+               }
+               buf_r[rc] = 0;
+               /* Chars from "C" days/months, and above Line */
+               if (strspn(buf_r, ok_chars) != rc) {
+                       printf("Corruption detected at %lu on %s",
+                              offset & ~4095, now_time);
+                       exit(9);
+               }
+
+               sleep(sleeptime);
+               iter++;
+       }
+
+}
diff --git a/lustre/tests/write_append_truncate.c b/lustre/tests/write_append_truncate.c
new file mode 100644 (file)
index 0000000..b0557bb
--- /dev/null
@@ -0,0 +1,271 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Each loop does 3 things:
+ *   - truncate file to zero (not via ftruncate though, to test O_APPEND)
+ *   - append a "chunk" of data (should be at file offset 0 after truncate)
+ *   - on each of two threads either append or truncate-up the file
+ *
+ * If the truncate happened first, we should have a hole in the file.
+ * If the append happened first, we should have truncated the file down.
+ *
+ * We pick the CHUNK_SIZE_MAX and APPEND_SIZE_MAX so that we cross a stripe.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include "mpi.h"
+
+
+#define CHUNK_SIZE_MAX   123456
+#define CHUNK_CHAR   'C'
+
+#define APPEND_SIZE_MAX  123456
+#define APPEND_CHAR  'A'
+
+#define TRUNC_SIZE_MAX   (CHUNK_SIZE_MAX+APPEND_SIZE_MAX)
+
+#define HOSTNAME_SIZE 50
+
+void usage(char *prog)
+{
+        printf("usage: %s <filename> [nloops]\n", prog);
+        printf("%s must be run on 2 nodes\n", prog);
+
+        exit(1);
+}
+
+/* Print process rank, loop count, message, and exit (i.e. a fatal error) */
+int rprintf(int rank, int loop, const char *fmt, ...)
+{
+        va_list       ap;
+
+        printf("rank %d, loop %d: ", rank, loop);
+
+        va_start(ap, fmt);
+
+        printf(fmt, ap);
+
+        exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+        int n, nloops = 0, fd;
+        int rank, ret;
+        int chunk_size, append_size, trunc_offset;
+        char append_buf[APPEND_SIZE_MAX];
+        char chunk_buf[CHUNK_SIZE_MAX];
+        char read_buf[TRUNC_SIZE_MAX+APPEND_SIZE_MAX];
+        char trunc_buf[TRUNC_SIZE_MAX];
+        int done;
+        int error;
+        char hostname[HOSTNAME_SIZE];
+        char *fname, *prog;
+
+        error = MPI_Init(&argc, &argv);
+        if (error != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Init failed: %d\n", error);
+
+        prog = strrchr(argv[0], '/');
+        if (prog == NULL)
+                prog = argv[0];
+        else
+                prog++;
+
+        if (argc < 2 || argc > 3)
+                usage(prog);
+
+        error = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+        if (error != MPI_SUCCESS)
+                rprintf(-1, -1, "MPI_Comm_rank failed: %d\n", error);
+
+        error = MPI_Comm_size(MPI_COMM_WORLD, &n);
+        if (error != MPI_SUCCESS)
+                rprintf(rank, -1, "MPI_Comm_size failed: %d\n", error);
+
+        if (n != 2)
+                rprintf(rank, -1, "%s: must run with 2 processes, not %d\n",
+                        prog, n);
+
+        memset(append_buf, APPEND_CHAR, APPEND_SIZE_MAX);
+        memset(chunk_buf, CHUNK_CHAR, CHUNK_SIZE_MAX);
+        memset(trunc_buf, 0, TRUNC_SIZE_MAX);
+
+        if (gethostname(hostname, HOSTNAME_SIZE) < 0)
+                rprintf(rank, -1, "gethostname failed: %s\n", strerror(errno));
+
+        fname = argv[1];
+
+        if (argc == 3)
+                nloops = strtoul(argv[2], NULL, 0);
+        if (nloops == 0)
+                nloops = 100000;
+
+        if (rank == 0) {
+                fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+                if (fd <= 0)
+                        rprintf(0, -1, "create %s failed: %s\n", fname,
+                                strerror(errno));
+                printf("using %s\n", fname);
+        }
+        error = MPI_Barrier(MPI_COMM_WORLD);
+        if (error != MPI_SUCCESS)
+                rprintf(rank, -1, "prep MPI_Barrier failed: %d\n", error);
+
+        fd = open(fname, O_RDWR | O_APPEND);
+        if (fd <= 0)
+                rprintf(rank, -1, "open %s failed: %s\n",fname,strerror(errno));
+
+        for (n = 0; n < nloops; n++) {
+                /* reset the environment */
+                chunk_size = (rand()%(CHUNK_SIZE_MAX-1))+1;
+                append_size = (rand()%(APPEND_SIZE_MAX-1))+1;
+                trunc_offset = chunk_size + rand()%append_size;
+                if (rank == 0) {
+                        if (n % 1000 == 0)
+                                printf("loop %5d: chunk %6d/%#06x, "
+                                       "append %6d/%#06x, trunc @ %6d/%#06x\n",
+                                       n, chunk_size, chunk_size, append_size,
+                                       append_size, trunc_offset, trunc_offset);
+
+                        ret = truncate(fname, (off_t)0);
+                        if (ret < 0)
+                                rprintf(0, n, "truncate @ 0: %s\n",
+                                        strerror(errno));
+                        done = 0;
+                        do {
+                                ret = write(fd, chunk_buf+done,chunk_size-done);
+                                if (ret <= 0) {
+                                        rprintf(0, n, "chunk @ %d: %s\n",
+                                                done, strerror(errno));
+                                        break;
+                                }
+                                done += ret;
+                        } while (done != chunk_size);
+                }
+
+                error = MPI_Barrier(MPI_COMM_WORLD);
+                if (error != MPI_SUCCESS)
+                        rprintf(rank, n, "start MPI_Barrier: %d\n",error);
+
+                /* Do the race */
+                if (rank == n % 2) {
+                        //
+                        done = 0;
+                        do {
+                                ret = write(fd, append_buf + done,
+                                            append_size - done);
+                                if (ret < 0) {
+                                        rprintf(rank, n,
+                                                "loop %d: append @ %u: %s\n",
+                                                done, strerror(errno));
+                                        break;
+                                }
+                                done += ret;
+                        } while (done != append_size);
+                } else if (rank == 1 - n % 2) {
+                        ret = truncate(fname, (off_t)trunc_offset);
+                        if (ret != 0)
+                                rprintf(rank, n, "truncate @ %u: %s\n",
+                                        trunc_offset, strerror(errno) );
+                }
+
+                error = MPI_Barrier(MPI_COMM_WORLD);
+                if (error != MPI_SUCCESS)
+                        rprintf(rank, n, "end MPI_Barrier: %d\n", error);
+
+                error = 0;
+
+                /* Check the result */
+                if (rank == 0) {
+                        struct stat st;
+                        if (stat(fname, &st) < 0)
+                                rprintf(0, n, "loop %d: stat %s: %s\n",
+                                        fname, strerror(errno));
+
+                        if (lseek(fd, (off_t)0, SEEK_SET) != 0)
+                                rprintf(0, n, "lseek fname 0: %s\n", fname,
+                                        strerror(errno));
+
+                        done = 0;
+                        do {
+                                ret = read(fd, read_buf+done, st.st_size-done);
+                                if (ret < 0) {
+                                        rprintf(0, n, "read @ %u: %s\n",
+                                               done, strerror(errno));
+                                }
+                                done += ret;
+                        } while (done != st.st_size);
+
+                        if (memcmp(read_buf, chunk_buf, chunk_size)) {
+                                printf("loop %d: base chunk bad"
+                                       " [0-%d]/[0-%#x] != %c\n", n,
+                                       chunk_size - 1, chunk_size - 1,
+                                       CHUNK_CHAR);
+                                error = 1;
+                        }
+
+                        if (st.st_size == trunc_offset) {
+                                /* Check case 1: first append then truncate */
+                                error = memcmp(read_buf+chunk_size, append_buf,
+                                               trunc_offset - chunk_size);
+                                if (error) {
+                                        printf("loop %d: trunc-after-append bad"
+                                               " [%d-%d]/[%#x-%#x] != %c\n",
+                                               n, chunk_size, trunc_offset - 1,
+                                               chunk_size, trunc_offset - 1,
+                                               APPEND_CHAR);
+                                }
+                        } else {
+                                /* Check case 2: first truncate then append */
+                                if (memcmp(read_buf+chunk_size, trunc_buf,
+                                           trunc_offset-chunk_size)) {
+                                        printf("loop %d: append-after-TRUNC"
+                                               " bad [%d-%d]/[%#x-%#x] != 0\n",
+                                               n, chunk_size, trunc_offset - 1,
+                                               chunk_size, trunc_offset - 1);
+                                        error = 1;
+                                } else if (memcmp(read_buf+trunc_offset,
+                                                  append_buf, append_size)) {
+                                        printf("loop %d: APPEND-after-trunc"
+                                               " bad [%d-%d]/[%#x-%#x] != %c\n",
+                                               n, trunc_offset, append_size - 1,
+                                               trunc_offset, append_size - 1,
+                                               APPEND_CHAR);
+                                        error = 1;
+                                }
+                        }
+                }
+                ret = MPI_Bcast(&error, 1, MPI_INT, 0, MPI_COMM_WORLD);
+                if (ret != MPI_SUCCESS)
+                        rprintf(rank, n, "MPI_Bcast: %d\n");
+
+                if (error == 1) {
+                        if (rank == 0) {
+                                char command[4096];
+
+                                printf("loop %5d: chunk %6d/%#06x, "
+                                       "append %6d/%#06x, trunc @ %6d/%#06x\n",
+                                       n, chunk_size, chunk_size, append_size,
+                                       append_size, trunc_offset, trunc_offset);
+
+                                sprintf(command, "od -Ax -a %s", fname);
+                                system(command);
+                        }
+                        rprintf(rank, n, "on machine %s with pid %d\n",
+                                hostname, (int)getpid());
+                }
+        }
+
+        printf("Finished after %d loops\n", n);
+
+        MPI_Finalize();
+        return 0;
+}