generic/019: don't dump cores when fio/fsstress hit io errors
[xfstests-dev.git] / ltp / doio.c
index e4f61d82fae4432ea1081489a314998b2d787ff4..83f8cf556325574a84ae1b0aaa4817f665bd7398 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2000 Silicon Graphics, Inc.
  * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 /*
  * doio -      a general purpose io initiator with system call and
@@ -29,6 +17,7 @@
 
 #include "global.h"
 
+#include <stdarg.h>
 #include <sys/uio.h>   /* for struct iovec (readv)*/
 #include <sys/mman.h>  /* for mmap(2) */
 #include <sys/ipc.h>   /* for i/o buffer in shared memory */
 #include <sys/time.h>  /* for delays */
 #include <ctype.h>
 
-#ifndef NO_XFS
 struct io_req;
 int do_xfsctl(struct io_req *);
-#endif
 
 #include "doio.h"
 #include "pattern.h"
@@ -172,11 +159,9 @@ struct fd_cache {
        int     c_oflags;
        int     c_fd;
        long    c_rtc;
-#ifndef NO_XFS
        int     c_memalign;     /* from xfsctl(XFS_IOC_DIOINFO) */
        int     c_miniosz;
        int     c_maxiosz;
-#endif
        void    *c_memaddr;     /* mmapped address */
        int     c_memlen;       /* length of above region */
 };
@@ -214,15 +199,16 @@ void      sigbus_handler();       /* Handle sigbus--check active_mmap_rw to
 
 void   cb_handler();           /* Posix aio callback handler. */
 void   noop_handler();         /* Delayop alarm, does nothing. */
-char   *hms();
+char   *hms(time_t  t);
 char   *format_rw();
 char   *format_sds();
 char   *format_listio();
-char   *check_file();
+char   *check_file(char *file, int offset, int length, char *pattern,
+                   int pattern_length, int patshift, int fsa);
 int    doio_fprintf(FILE *stream, char *format, ...);
-void   doio_upanic();
+void   doio_upanic(int mask);
 void   doio();
-void   help();
+void   help(FILE *stream);
 void   doio_delay();
 int     alloc_fd( char *, int );
 int     alloc_mem( int );
@@ -364,7 +350,7 @@ char        **argv;
                case SIGTSTP:
                case SIGSTOP:
                case SIGCONT:
-               case SIGCLD:
+               case SIGCHLD:
                case SIGBUS:
                case SIGSEGV:
                case SIGQUIT:
@@ -777,12 +763,10 @@ doio()
                case LEWRITEA:
                        rval = do_rw(&ioreq);
                        break;
-#ifndef NO_XFS
                case RESVSP:
                case UNRESVSP:
                        rval = do_xfsctl(&ioreq);
                        break;
-#endif
                case FSYNC2:
                case FDATASYNC:
                        rval = do_sync(&ioreq);
@@ -1056,9 +1040,7 @@ struct io_req     *req;
 {
        int                     fd, offset, nbytes, oflags, rval;
        char                    *addr, *file;
-#ifndef NO_XFS
        struct fd_cache         *fdc;
-#endif
 
        /*
         * Initialize common fields - assumes r_oflags, r_file, r_offset, and
@@ -1090,7 +1072,6 @@ struct io_req     *req;
 #define wtob(x)        (x * sizeof(UINT64_T))
 #endif
 
-#ifndef NO_XFS
        /* get memory alignment for using DIRECT I/O */
        fdc = alloc_fdcache(file, oflags);
 
@@ -1111,14 +1092,6 @@ struct io_req    *req;
        } else {
                addr += random_range(0, wtob(1) - 1, 1, NULL);
        }
-#else
-       if ((rval = alloc_mem(nbytes + wtob(1) * 2)) < 0) {
-               return rval;
-       }
-
-       addr = Memptr;
-#endif /* !NO_XFS */
-
 
        switch (req->r_type) {
        case READ:
@@ -1162,20 +1135,16 @@ struct io_req   *req;
        static int              pid = -1;
        int                     fd, nbytes, oflags;
        /* REFERENCED */
-       int                     signo;
        int                     logged_write, rval, got_lock;
        long                    offset, woffset = 0;
        char                    *addr, pattern, *file, *msg;
        struct wlog_rec         wrec;
-#ifndef NO_XFS
        struct fd_cache         *fdc;
-#endif
 
        /*
         * Misc variable setup
         */
 
-       signo   = 0;
        nbytes  = req->r_data.write.r_nbytes;
        offset  = req->r_data.write.r_offset;
        pattern = req->r_data.write.r_pattern;
@@ -1206,7 +1175,6 @@ struct io_req     *req;
         * Allocate SDS space for backdoor write if desired
         */
 
-#ifndef NO_XFS
        /* get memory alignment for using DIRECT I/O */
        fdc = alloc_fdcache(file, oflags);
 
@@ -1231,18 +1199,6 @@ struct io_req    *req;
        if( addr != Memptr )
                memmove( addr, Memptr, nbytes);
 
-#else /* sgi */
-       if ((rval = alloc_mem(nbytes + wtob(1) * 2)) < 0) {
-               return rval;
-       }
-
-       addr = Memptr;
-
-       (*Data_Fill)(Memptr, nbytes, Pattern, Pattern_Length, 0);
-       if( addr != Memptr )
-               memmove( addr, Memptr, nbytes);
-#endif /* sgi */
-
        rval = -1;
        got_lock = 0;
        logged_write = 0;
@@ -1312,7 +1268,6 @@ struct io_req     *req;
                                     "write() failed:  %s (%d)\n%s\n",
                                     SYSERR, errno,
                                     format_rw(req, fd, addr, -1, Pattern, NULL));
-#ifndef NO_XFS
                        doio_fprintf(stderr,
                                     "write() failed:  %s\n\twrite(%d, %#o, %d)\n\toffset %d, nbytes%%miniou(%d)=%d, oflags=%#o memalign=%d, addr%%memalign=%d\n",
                                     strerror(errno),
@@ -1320,13 +1275,6 @@ struct io_req    *req;
                                     offset,
                                     fdc->c_miniosz, nbytes%fdc->c_miniosz,
                                     oflags, fdc->c_memalign, (long)addr%fdc->c_memalign);
-#else
-                       doio_fprintf(stderr,
-                                    "write() failed:  %s\n\twrite(%d, %#o, %d)\n\toffset %d, nbytes%%1B=%d, oflags=%#o\n",
-                                    strerror(errno),
-                                    fd, addr, nbytes,
-                                    offset, nbytes%4096, oflags);
-#endif
                        doio_upanic(U_RVAL);
                } else if (rval != nbytes) {
                        doio_fprintf(stderr,
@@ -1511,8 +1459,8 @@ fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd)
        cp += sprintf(cp, "          memory alignment is %s\n",
                      (io->r_uflags & F_WORD_ALIGNED) ? "aligned" : "unaligned");
 
-#ifndef NO_XFS
        if(io->r_oflags & O_DIRECT) {
+               char            *dio_env;
                struct dioattr  finfo;
                
                if(xfsctl(io->r_file, fd, XFS_IOC_DIOINFO, &finfo) == -1) {
@@ -1523,6 +1471,10 @@ fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd)
                        finfo.d_maxiosz = 1;
                }
 
+               dio_env = getenv("XFS_DIO_MIN");
+               if (dio_env)
+                       finfo.d_mem = finfo.d_miniosz = atoi(dio_env);
+
                cp += sprintf(cp, "          DIRECT I/O: offset %% %d = %d length %% %d = %d\n",
                              finfo.d_miniosz,
                              io->r_offset % finfo.d_miniosz,
@@ -1531,8 +1483,6 @@ fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd)
                cp += sprintf(cp, "          mem alignment 0x%x xfer size: small: %d large: %d\n",
                              finfo.d_mem, finfo.d_miniosz, finfo.d_maxiosz);
        }
-#endif
-
        return(errbuf);
 }
 
@@ -1609,28 +1559,6 @@ fmt_pread(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
        return(errbuf);
 }
 
-struct status *
-sy_readv(req, sysc, fd, addr)
-struct io_req  *req;
-struct syscall_info *sysc;
-int fd;
-char *addr;
-{
-       struct status *sy_rwv();
-       return sy_rwv(req, sysc, fd, addr, 0);
-}
-
-struct status *
-sy_writev(req, sysc, fd, addr)
-struct io_req  *req;
-struct syscall_info *sysc;
-int fd;
-char *addr;
-{
-       struct status *sy_rwv();
-       return sy_rwv(req, sysc, fd, addr, 1);
-}
-
 struct status *
 sy_rwv(req, sysc, fd, addr, rw)
 struct io_req  *req;
@@ -1671,38 +1599,36 @@ int rw;
        return(status);
 }
 
-char *
-fmt_readv(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
-{
-       static char     errbuf[32768];
-       char            *cp;
-
-       cp = errbuf;
-       cp += sprintf(cp, "syscall:  %s(%d, (iov on stack), 1)\n",
-                     sy->sy_name, fd);
-       return(errbuf);
-}
-
 struct status *
-sy_mmread(req, sysc, fd, addr)
-struct io_req *req;
+sy_readv(req, sysc, fd, addr)
+struct io_req  *req;
 struct syscall_info *sysc;
 int fd;
 char *addr;
 {
-       struct status *sy_mmrw();
-       return sy_mmrw(req, sysc, fd, addr, 0);
+       return sy_rwv(req, sysc, fd, addr, 0);
 }
 
 struct status *
-sy_mmwrite(req, sysc, fd, addr)
-struct io_req *req;
+sy_writev(req, sysc, fd, addr)
+struct io_req  *req;
 struct syscall_info *sysc;
 int fd;
 char *addr;
 {
-       struct status *sy_mmrw();
-       return sy_mmrw(req, sysc, fd, addr, 1);
+       return sy_rwv(req, sysc, fd, addr, 1);
+}
+
+char *
+fmt_readv(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
+{
+       static char     errbuf[32768];
+       char            *cp;
+
+       cp = errbuf;
+       cp += sprintf(cp, "syscall:  %s(%d, (iov on stack), 1)\n",
+                     sy->sy_name, fd);
+       return(errbuf);
 }
 
 struct status *
@@ -1771,6 +1697,26 @@ int rw;
        return(status);
 }
 
+struct status *
+sy_mmread(req, sysc, fd, addr)
+struct io_req *req;
+struct syscall_info *sysc;
+int fd;
+char *addr;
+{
+       return sy_mmrw(req, sysc, fd, addr, 0);
+}
+
+struct status *
+sy_mmwrite(req, sysc, fd, addr)
+struct io_req *req;
+struct syscall_info *sysc;
+int fd;
+char *addr;
+{
+       return sy_mmrw(req, sysc, fd, addr, 1);
+}
+
 char *
 fmt_mmrw(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
 {
@@ -1846,9 +1792,7 @@ do_rw(req)
        struct status           *s;
        struct wlog_rec         wrec;
        struct syscall_info     *sy;
-#ifndef NO_XFS
        struct fd_cache         *fdc;
-#endif
 
        /*
         * Initialize common fields - assumes r_oflags, r_file, r_offset, and
@@ -1907,18 +1851,12 @@ do_rw(req)
                mem_needed = nbytes;
        }
 
-#ifndef NO_XFS
        /* get memory alignment for using DIRECT I/O */
        fdc = alloc_fdcache(file, oflags);
 
        if ((rval = alloc_mem(mem_needed + wtob(1) * 2 + fdc->c_memalign)) < 0) {
                return rval;
        }
-#else
-       if ((rval = alloc_mem(mem_needed + wtob(1) * 2)) < 0) {
-               return rval;
-       }
-#endif
 
        Pattern[0] = pattern;
 
@@ -1945,14 +1883,12 @@ do_rw(req)
                        addr += random_range(0, wtob(1) - 1, 1, NULL);
                }
 
-#ifndef NO_XFS
                /*
                 * Force memory alignment for Direct I/O
                 */
                if( (oflags & O_DIRECT) && ((long)addr % fdc->c_memalign != 0) ) {
                        addr += fdc->c_memalign - ((long)addr % fdc->c_memalign);
                }
-#endif
 
                /*
                 * FILL must be done on a word-aligned buffer.
@@ -2141,7 +2077,6 @@ do_rw(req)
  *   - XFS_IOC_RESVSP
  *   - XFS_IOC_UNRESVSP
  */
-#ifndef NO_XFS
 int
 do_xfsctl(req)
        struct io_req   *req;
@@ -2232,7 +2167,6 @@ do_xfsctl(req)
 
        return (rval == -1) ? -1 : 0;
 }
-#endif
 
 /*
  *  fsync(2) and fdatasync(2)
@@ -2379,9 +2313,7 @@ int       fsa;
        static char     errbuf[4096];
        int             fd, nb, flags;
        char            *buf, *em, *ep;
-#ifndef NO_XFS
        struct fd_cache *fdc;
-#endif
 
        buf = Memptr;
 
@@ -2406,27 +2338,18 @@ int     fsa;
                return errbuf;
        }
 
-#ifndef NO_XFS
        /* Guarantee a properly aligned address on Direct I/O */
        fdc = alloc_fdcache(file, flags);
        if( (flags & O_DIRECT) && ((long)buf % fdc->c_memalign != 0) ) {
                buf += fdc->c_memalign - ((long)buf % fdc->c_memalign);
        }
-#endif
 
        if ((nb = read(fd, buf, length)) == -1) {
-#ifndef NO_XFS
                sprintf(errbuf,
                        "Could not read %d bytes from %s for verification:  %s (%d)\n\tread(%d, 0x%p, %d)\n\tbuf %% alignment(%d) = %ld\n",
                        length, file, SYSERR, errno,
                        fd, buf, length,
                        fdc->c_memalign, (long)buf % fdc->c_memalign);
-#else
-               sprintf(errbuf,
-                       "Could not read %d bytes from %s for verification:  %s (%d)\n",
-                       length, file, SYSERR, errno);
-
-#endif
                return errbuf;
        }
 
@@ -2722,9 +2645,7 @@ int       oflags;
        struct fd_cache         *free_slot, *oldest_slot, *cp;
        static int              cache_size = 0;
        static struct fd_cache  *cache = NULL;
-#ifndef NO_XFS
        struct dioattr  finfo;
-#endif
 
        /*
         * If file is NULL, it means to free up the fd cache.
@@ -2846,13 +2767,19 @@ int     oflags;
        strcpy(free_slot->c_file, file);
        free_slot->c_rtc = Reqno;
 
-#ifndef NO_XFS
        if (oflags & O_DIRECT) {
+               char *dio_env;
+
                if (xfsctl(file, fd, XFS_IOC_DIOINFO, &finfo) == -1) {
                        finfo.d_mem = 1;
                        finfo.d_miniosz = 1;
                        finfo.d_maxiosz = 1;
                }
+
+               dio_env = getenv("XFS_DIO_MIN");
+               if (dio_env)
+                       finfo.d_mem = finfo.d_miniosz = atoi(dio_env);
+
        } else {
                finfo.d_mem = 1;
                finfo.d_miniosz = 1;
@@ -2862,7 +2789,6 @@ int       oflags;
        free_slot->c_memalign = finfo.d_mem;
        free_slot->c_miniosz = finfo.d_miniosz;
        free_slot->c_maxiosz = finfo.d_maxiosz;
-#endif
        free_slot->c_memaddr = NULL;
        free_slot->c_memlen = 0;
 
@@ -3246,7 +3172,7 @@ char      *opts;
                        break;
 
                case 'N':
-                       sprintf( TagName, "(%.39s)", optarg );
+                       sprintf( TagName, "(%.37s)", optarg );
                        break;
 
                case 'n':