+// 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
#include "global.h"
-#ifdef sgi
-#include <aio.h> /* for aio_read,write */
-#include <inttypes.h> /* for uint64_t type */
-#include <siginfo.h> /* signal handlers & SA_SIGINFO */
-#endif
-
+#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"
#include "string_to_tokens.h"
#ifndef O_SSD
-#define O_SSD 0 /* so code compiles on a CRAY2 */
+#define O_SSD 0 /* so code compiles on a CRAY2 */
#endif
#define UINT64_T unsigned long long
#define PPID_CHECK_INTERVAL 5 /* check ppid every <-- iterations */
#define MAX_AIO 256 /* maximum number of async I/O ops */
-#ifdef _CRAYMPP
-#define MPP_BUMP 16 /* page un-alignment for MPP */
-#else
#define MPP_BUMP 0
-#endif
#define SYSERR strerror(errno)
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
-#ifndef CRAY
void *c_memaddr; /* mmapped address */
int c_memlen; /* length of above region */
-#endif
};
#define FD_ALLOC_INCR 32 /* allocate this many fd_map structs */
void die_handler(); /* Bad sig in child doios, exit 1. */
void cleanup_handler(); /* Normal kill, exit 0. */
-#ifndef CRAY
void sigbus_handler(); /* Handle sigbus--check active_mmap_rw to
decide if this should be a normal exit. */
-#endif
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 );
int fd;
int strategy;
volatile int done;
-#ifdef CRAY
- struct iosw iosw;
-#endif
-#ifdef sgi
- aiocb_t aiocb;
- int aio_ret; /* from aio_return */
- int aio_errno; /* from aio_error */
-#endif
int sig;
int signalled;
struct sigaction osa;
struct smap delaymap[] = {
{ "select", DELAY_SELECT },
{ "sleep", DELAY_SLEEP },
-#ifdef sgi
- { "sginap", DELAY_SGINAP },
-#endif
{ "alarm", DELAY_ALARM },
{ NULL, 0 },
};
{
int i, pid, stat, ex_stat;
struct sigaction sa;
- int omask;
+ sigset_t block_mask, old_mask;
umask(0); /* force new file modes to known values */
-#if _CRAYMPP
- Npes = sysconf(_SC_CRAY_NPES); /* must do this before parse_cmdline */
- Vpe = sysconf(_SC_CRAY_VPE);
-#endif
TagName[0] = '\0';
parse_cmdline(argc, argv, OPTS);
case SIGTSTP:
case SIGSTOP:
case SIGCONT:
- case SIGCLD:
+ case SIGCHLD:
case SIGBUS:
case SIGSEGV:
case SIGQUIT:
Children[i] = -1;
}
- omask = sigblock(sigmask(SIGCLD));
+ sigemptyset(&block_mask);
+ sigaddset(&block_mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &block_mask, &old_mask);
/*
* Fork Nprocs. This [parent] process is a watchdog, to notify the
char *cp;
struct io_req ioreq;
struct sigaction sa, def_action, ignore_action, exit_action;
-#ifndef CRAY
struct sigaction sigbus_action;
-#endif
Memsize = Sdssize = 0;
def_action.sa_flags = 0;
sigemptyset(&def_action.sa_mask);
-#ifdef sgi
- exit_action.sa_sigaction = cleanup_handler;
- exit_action.sa_flags = SA_SIGINFO;
- sigemptyset(&exit_action.sa_mask);
-
- sa.sa_sigaction = die_handler;
- sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
-
- sigbus_action.sa_sigaction = sigbus_handler;
- sigbus_action.sa_flags = SA_SIGINFO;
- sigemptyset(&sigbus_action.sa_mask);
-#else
exit_action.sa_handler = cleanup_handler;
exit_action.sa_flags = 0;
sigemptyset(&exit_action.sa_mask);
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
-#ifndef CRAY
sigbus_action.sa_handler = sigbus_handler;
sigbus_action.sa_flags = 0;
sigemptyset(&sigbus_action.sa_mask);
-#endif
-#endif
for (i = 1; i <= NSIG; i++) {
switch(i) {
sigaction(i, &exit_action, NULL);
break;
-#ifndef CRAY
/* This depends on active_mmap_rw */
case SIGBUS:
sigaction(i, &sigbus_action, NULL);
break;
-#endif
/* Signals to Ignore... */
case SIGSTOP:
alloc_mem(-1);
#endif
}
-
-#ifdef _CRAY1
- if (Sdssize) {
- ssbreak(-1 * btoc(Sdssize));
- Sdsptr = 0;
- Sdssize = 0;
- }
-#endif /* _CRAY1 */
-
alloc_fd(NULL, 0);
}
case LEWRITEA:
rval = do_rw(&ioreq);
break;
-
-#ifdef CRAY
- case SSREAD:
- case SSWRITE:
- rval = do_ssdio(&ioreq);
- break;
-
- case LISTIO:
- rval = do_listio(&ioreq);
- break;
-#endif
-
-#ifndef NO_XFS
case RESVSP:
case UNRESVSP:
rval = do_xfsctl(&ioreq);
break;
-#endif
-
-#ifndef CRAY
case FSYNC2:
case FDATASYNC:
rval = do_sync(&ioreq);
break;
-#endif
default:
doio_fprintf(stderr,
"Don't know how to handle io request type %d\n",
sleep(delaytime);
break;
-#ifdef sgi
- case DELAY_SGINAP:
- sginap(delaytime);
- break;
-#endif
-
case DELAY_ALARM:
sa_al.sa_flags = 0;
sa_al.sa_handler = noop_handler;
if(oflags & O_SYNC)
strcat(flags,"O_SYNC,");
-#ifdef CRAY
- if(oflags & O_RAW)
- strcat(flags,"O_RAW,");
- if(oflags & O_WELLFORMED)
- strcat(flags,"O_WELLFORMED,");
-#ifdef O_SSD
- if(oflags & O_SSD)
- strcat(flags,"O_SSD,");
-#endif
- if(oflags & O_LDRAW)
- strcat(flags,"O_LDRAW,");
- if(oflags & O_PARALLEL)
- strcat(flags,"O_PARALLEL,");
- if(oflags & O_BIG)
- strcat(flags,"O_BIG,");
- if(oflags & O_PLACE)
- strcat(flags,"O_PLACE,");
- if(oflags & O_ASYNC)
- strcat(flags,"O_ASYNC,");
-#endif
if(oflags & O_DIRECT)
strcat(flags,"O_DIRECT,");
-#ifdef sgi
- if(oflags & O_DSYNC)
- strcat(flags,"O_DSYNC,");
- if(oflags & O_RSYNC)
- strcat(flags,"O_RSYNC,");
-#endif
return(strdup(flags));
}
void *buffer,
int signo,
char *pattern,
-#ifdef CRAY
- struct iosw *iosw
-#else
void *iosw
-#endif
)
{
static char *errbuf=NULL;
return errbuf;
}
-#ifdef CRAY
-char *
-format_sds(
- struct io_req *ioreq,
- void *buffer,
- int sds,
- char *pattern
- )
-{
- int i;
- static char *errbuf=NULL;
- char *cp;
-
- struct ssread_req *ssreadp = &ioreq->r_data.ssread;
- struct sswrite_req *sswritep = &ioreq->r_data.sswrite;
-
- if(errbuf == NULL)
- errbuf = (char *)malloc(32768);
-
- cp = errbuf;
- cp += sprintf(cp, "Request number %d\n", Reqno);
-
-
- switch (ioreq->r_type) {
- case SSREAD:
- cp += sprintf(cp, "syscall: ssread(%#o, %#o, %d)\n",
- buffer, sds, ssreadp->r_nbytes);
- break;
-
- case SSWRITE:
- cp += sprintf(cp, "syscall: sswrite(%#o, %#o, %d) - pattern was %s\n",
- buffer, sds, sswritep->r_nbytes, pattern);
- break;
- }
- return errbuf;
-}
-#endif /* CRAY */
-
/*
* Perform the various sorts of disk reads
*/
{
int fd, offset, nbytes, oflags, rval;
char *addr, *file;
-#ifdef CRAY
- struct aio_info *aiop;
- int aio_id, aio_strat, signo;
-#endif
-#ifndef NO_XFS
struct fd_cache *fdc;
-#endif
/*
* Initialize common fields - assumes r_oflags, r_file, r_offset, and
#define wtob(x) (x * sizeof(UINT64_T))
#endif
-#ifdef CRAY
- if (oflags & O_SSD) {
- if (alloc_sds(nbytes) == -1)
- return -1;
-
- addr = (char *)Sdsptr;
- } else {
- if ((rval = alloc_mem(nbytes + wtob(1) * 2 + MPP_BUMP * sizeof(UINT64_T))) < 0) {
- return rval;
- }
-
- addr = Memptr;
-
- /*
- * if io is not raw, bump the offset by a random amount
- * to generate non-word-aligned io.
- */
- if (! (req->r_data.read.r_uflags & F_WORD_ALIGNED)) {
- addr += random_range(0, wtob(1) - 1, 1, NULL);
- }
- }
-#else
-#ifndef NO_XFS
/* get memory alignment for using DIRECT I/O */
fdc = alloc_fdcache(file, oflags);
} 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 /* !CRAY && sgi */
-#endif /* CRAY */
-
switch (req->r_type) {
case READ:
return -1;
}
break;
-
-#ifdef CRAY
- case READA:
- /*
- * Async read
- */
-
- /* move to the desired file position. */
- if (lseek(fd, offset, SEEK_SET) == -1) {
- doio_fprintf(stderr,
- "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n",
- fd, offset, SYSERR, errno);
- return -1;
- }
-
- aio_strat = req->r_data.read.r_aio_strat;
- signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0;
-
- aio_id = aio_register(fd, aio_strat, signo);
- aiop = aio_slot(aio_id);
-
- if (reada(fd, addr, nbytes, &aiop->iosw, signo) == -1) {
- doio_fprintf(stderr, "reada() failed: %s (%d)\n%s\n",
- SYSERR, errno,
- format_rw(req, fd, addr, signo, NULL, &aiop->iosw));
- aio_unregister(aio_id);
- doio_upanic(U_RVAL);
- rval = -1;
- } else {
- /*
- * Wait for io to complete
- */
-
- aio_wait(aio_id);
-
- /*
- * make sure the io completed without error
- */
-
- if (aiop->iosw.sw_count != nbytes) {
- doio_fprintf(stderr,
- "Bad iosw from reada()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n",
- 1, 0, nbytes,
- aiop->iosw.sw_flag,
- aiop->iosw.sw_error,
- aiop->iosw.sw_count,
- format_rw(req, fd, addr, signo, NULL, &aiop->iosw));
- aio_unregister(aio_id);
- doio_upanic(U_IOSW);
- rval = -1;
- } else {
- aio_unregister(aio_id);
- rval = 0;
- }
- }
-
- if (rval == -1)
- return rval;
- break;
-#endif /* CRAY */
}
return 0; /* if we get here, everything went ok */
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;
-#ifdef CRAY
- int aio_strat, aio_id;
- struct aio_info *aiop;
-#endif
-#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;
* Allocate SDS space for backdoor write if desired
*/
-#ifdef CRAY
- if (oflags & O_SSD) {
-#ifndef _CRAYMPP
- if ((rval = alloc_mem(nbytes + wtob(1))) < 0) {
- return rval;
- }
-
- (*Data_Fill)(Memptr, nbytes, Pattern, Pattern_Length, 0);
- /*pattern_fill(Memptr, nbytes, Pattern, Pattern_Length, 0);*/
-
- if (alloc_sds(nbytes) == -1)
- return -1;
-
- if (sswrite((long)Memptr, Sdsptr, btoc(nbytes)) == -1) {
- doio_fprintf(stderr, "sswrite(%d, %d, %d) failed: %s (%d)\n",
- (long)Memptr, Sdsptr, btoc(nbytes),
- SYSERR, errno);
- fflush(stderr);
- return -1;
- }
-
- addr = (char *)Sdsptr;
-#else
- doio_fprintf(stderr, "Invalid O_SSD flag was generated for MPP system\n");
- fflush(stderr);
- return -1;
-#endif /* !CRAYMPP */
- } else {
- if ((rval = alloc_mem(nbytes + wtob(1)) < 0)) {
- return rval;
- }
-
- addr = Memptr;
-
- /*
- * if io is not raw, bump the offset by a random amount
- * to generate non-word-aligned io.
- */
-
- if (! (req->r_data.write.r_uflags & F_WORD_ALIGNED)) {
- addr += random_range(0, wtob(1) - 1, 1, NULL);
- }
-
- (*Data_Fill)(Memptr, nbytes, Pattern, Pattern_Length, 0);
- if( addr != Memptr )
- memmove( addr, Memptr, nbytes);
- }
-#else /* CRAY */
-#ifndef NO_XFS
/* get memory alignment for using DIRECT I/O */
fdc = alloc_fdcache(file, oflags);
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 */
-#endif /* CRAY */
-
rval = -1;
got_lock = 0;
logged_write = 0;
"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),
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,
}
break;
-
-#ifdef CRAY
- case WRITEA:
- /*
- * async write
- */
- if (lseek(fd, offset, SEEK_SET) == -1) {
- doio_fprintf(stderr,
- "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n",
- fd, offset, SYSERR, errno);
- return -1;
- }
-
- aio_strat = req->r_data.write.r_aio_strat;
- signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0;
-
- aio_id = aio_register(fd, aio_strat, signo);
- aiop = aio_slot(aio_id);
-
- /*
- * init iosw and do the async write
- */
-
- if (writea(fd, addr, nbytes, &aiop->iosw, signo) == -1) {
- doio_fprintf(stderr,
- "writea() failed: %s (%d)\n%s\n",
- SYSERR, errno,
- format_rw(req, fd, addr, -1, Pattern, NULL));
- doio_upanic(U_RVAL);
- aio_unregister(aio_id);
- rval = -1;
- } else {
-
- /*
- * Wait for io to complete
- */
-
- aio_wait(aio_id);
-
- /*
- * check that iosw is ok
- */
-
- if (aiop->iosw.sw_count != nbytes) {
- doio_fprintf(stderr,
- "Bad iosw from writea()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n",
- 1, 0, nbytes,
- aiop->iosw.sw_flag,
- aiop->iosw.sw_error,
- aiop->iosw.sw_count,
- format_rw(req, fd, addr, -1, Pattern, &aiop->iosw));
- aio_unregister(aio_id);
- doio_upanic(U_IOSW);
- rval = -1;
- } else {
- aio_unregister(aio_id);
- rval = 0;
- }
- }
- break;
-
-#endif /* CRAY */
}
/*
if (msg != NULL) {
doio_fprintf(stderr, "%s%s\n",
msg,
-#ifdef CRAY
- format_rw(req, fd, addr, -1, Pattern, &aiop->iosw)
-#else
format_rw(req, fd, addr, -1, Pattern, NULL)
-#endif
);
doio_upanic(U_CORRUPTION);
exit(E_COMPARE);
return 0;
}
-/*
- * Perform a listio request.
+int
+do_listio(req)
+struct io_req *req;
+{
+ return -1;
+}
+
+/* ---------------------------------------------------------------------------
+ *
+ * A new paradigm of doing the r/w system call where there is a "stub"
+ * function that builds the info for the system call, then does the system
+ * call; this is called by code that is common to all system calls and does
+ * the syscall return checking, async I/O wait, iosw check, etc.
+ *
+ * Flags:
+ * WRITE, ASYNC, SSD/SDS,
+ * FILE_LOCK, WRITE_LOG, VERIFY_DATA,
*/
-#ifdef CRAY
+struct status {
+ int rval; /* syscall return */
+ int err; /* errno */
+ int *aioid; /* list of async I/O structures */
+};
+
+struct syscall_info {
+ char *sy_name;
+ int sy_type;
+ struct status *(*sy_syscall)();
+ int (*sy_buffer)();
+ char *(*sy_format)();
+ int sy_flags;
+ int sy_bits;
+};
+
+#define SY_WRITE 00001
+#define SY_ASYNC 00010
+#define SY_IOSW 00020
+#define SY_SDS 00100
+
char *
-format_listio(
- struct io_req *ioreq,
- int lcmd,
- struct listreq *list,
- int nent,
- int fd,
- char *pattern
- )
+fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd)
{
- static char *errbuf=NULL;
- struct listio_req *liop = &ioreq->r_data.listio;
- struct listreq *listreq;
- char *cp, *cmd, *opcode, *aio_strat;
- int i;
-
- switch (lcmd) {
- case LC_START: cmd = "LC_START"; break;
- case LC_WAIT: cmd = "LC_WAIT"; break;
- default: cmd = "???"; break;
- }
+ static char *errbuf=NULL;
+ char *cp;
+ struct rw_req *io;
+ struct smap *aname;
if(errbuf == NULL)
errbuf = (char *)malloc(32768);
- cp = errbuf;
- cp += sprintf(cp, "Request number %d\n", Reqno);
-
- cp += sprintf(cp, "syscall: listio(%s, %#o, %d)\n\n",
- cmd, list, nent);
-
- aio_strat = format_strat(liop->r_aio_strat);
-
- for (i = 0; i < nent; i++) {
- cp += sprintf(cp, "struct lioreq for request element %d\n", i);
- cp += sprintf(cp, "----------------------------------------\n");
-
- listreq = list + i;
-
- switch (listreq->li_opcode) {
- case LO_READ: opcode = "LO_READ"; break;
- case LO_WRITE: opcode = "LO_WRITE"; break;
- default: opcode = "???"; break;
- }
-
- cp += sprintf(cp, " li_opcode = %s\n", opcode);
- cp += sprintf(cp, " li_drvr = %#o\n", listreq->li_drvr);
- cp += sprintf(cp, " li_flags = %#o\n", listreq->li_flags);
- cp += sprintf(cp, " li_offset = %d\n", listreq->li_offset);
- cp += sprintf(cp, " li_fildes = %d\n", listreq->li_fildes);
- cp += sprintf(cp, " li_buf = %#o\n", listreq->li_buf);
- cp += sprintf(cp, " li_nbyte = %d\n", listreq->li_nbyte);
- cp += sprintf(cp, " li_status = %#o (%d, %d, %d)\n", listreq->li_status, listreq->li_status->sw_flag, listreq->li_status->sw_error, listreq->li_status->sw_count);
- cp += sprintf(cp, " li_signo = %d\n", listreq->li_signo);
- cp += sprintf(cp, " li_nstride = %d\n", listreq->li_nstride);
- cp += sprintf(cp, " li_filstride = %d\n", listreq->li_filstride);
- cp += sprintf(cp, " li_memstride = %d\n", listreq->li_memstride);
- cp += sprintf(cp, " io completion strategy is %s\n", aio_strat);
- }
- return errbuf;
-}
-#endif /* CRAY */
-
-int
-do_listio(req)
-struct io_req *req;
-{
-#ifdef CRAY
- struct listio_req *lio;
- int fd, oflags, signo, nb, i;
- int logged_write, rval, got_lock;
- int aio_strat, aio_id;
- int min_byte, max_byte;
- int mem_needed;
- int foffset, fstride, mstride, nstrides;
- char *moffset;
- long offset, woffset;
- char *addr, *msg;
- sigset_t block_mask, omask;
- struct wlog_rec wrec;
- struct aio_info *aiop;
- struct listreq lio_req;
-
- lio = &req->r_data.listio;
-
- /*
- * If bytes per stride is less than the stride size, drop the request
- * since it will cause overlapping strides, and we cannot predict
- * the order they will complete in.
- */
-
- if (lio->r_filestride && abs(lio->r_filestride) < lio->r_nbytes) {
- doio_fprintf(stderr, "do_listio(): Bogus listio request - abs(filestride) [%d] < nbytes [%d]\n",
- abs(lio->r_filestride), lio->r_nbytes);
- return -1;
- }
-
- /*
- * Allocate core memory. Initialize the data to be written. Make
- * sure we get enough, based on the memstride.
- */
-
- mem_needed =
- stride_bounds(0, lio->r_memstride, lio->r_nstrides,
- lio->r_nbytes, NULL, NULL);
-
- if ((rval = alloc_mem(mem_needed + wtob(1))) < 0) {
- return rval;
- }
-
- /*
- * Set the memory address pointer. If the io is not raw, adjust
- * addr by a random amount, so that non-raw io is not necessarily
- * word aligned.
- */
-
- addr = Memptr;
-
- if (! (lio->r_uflags & F_WORD_ALIGNED)) {
- addr += random_range(0, wtob(1) - 1, 1, NULL);
- }
-
- if (lio->r_opcode == LO_WRITE) {
- Pattern[0] = lio->r_pattern;
- (*Data_Fill)(Memptr, mem_needed, Pattern, Pattern_Length, 0);
- if( addr != Memptr )
- memmove( addr, Memptr, mem_needed);
- }
-
- /*
- * Get a descriptor to do the io on. No need to do an lseek, as this
- * is encoded in the listio request.
- */
-
- if ((fd = alloc_fd(lio->r_file, lio->r_oflags)) == -1) {
- return -1;
- }
-
- rval = -1;
- got_lock = 0;
- logged_write = 0;
-
- /*
- * If the opcode is LO_WRITE, lock all regions of the file that
- * are touched by this listio request. Currently, we use
- * stride_bounds() to figure out the min and max bytes affected, and
- * lock the entire region, regardless of the file stride.
- */
-
- if (lio->r_opcode == LO_WRITE && k_opt) {
- stride_bounds(lio->r_offset,
- lio->r_filestride, lio->r_nstrides,
- lio->r_nbytes, &min_byte, &max_byte);
-
- if (lock_file_region(lio->r_file, fd, F_WRLCK,
- min_byte, (max_byte-min_byte+1)) < 0) {
- doio_fprintf(stderr, "stride_bounds(%d, %d, %d, %d, ..., ...) set min_byte to %d, max_byte to %d\n",
- lio->r_offset, lio->r_filestride,
- lio->r_nstrides, lio->r_nbytes, min_byte,
- max_byte);
- return -1;
- } else {
- got_lock = 1;
- }
- }
-
- /*
- * async write
- */
-
- aio_strat = lio->r_aio_strat;
- signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0;
-
- aio_id = aio_register(fd, aio_strat, signo);
- aiop = aio_slot(aio_id);
-
- /*
- * Form the listio request, and make the call.
- */
-
- lio_req.li_opcode = lio->r_opcode;
- lio_req.li_drvr = 0;
- lio_req.li_flags = LF_LSEEK;
- lio_req.li_offset = lio->r_offset;
- lio_req.li_fildes = fd;
-
- if (lio->r_memstride >= 0 || lio->r_nstrides <= 1) {
- lio_req.li_buf = addr;
- } else {
- lio_req.li_buf = addr + mem_needed - lio->r_nbytes;
- }
-
- lio_req.li_nbyte = lio->r_nbytes;
- lio_req.li_status = &aiop->iosw;
- lio_req.li_signo = signo;
- lio_req.li_nstride = lio->r_nstrides;
- lio_req.li_filstride = lio->r_filestride;
- lio_req.li_memstride = lio->r_memstride;
-
- /*
- * If signo != 0, block signo while we're in the system call, so that
- * we don't get interrupted syscall failures.
- */
-
- if (signo) {
- sigemptyset(&block_mask);
- sigaddset(&block_mask, signo);
- sigprocmask(SIG_BLOCK, &block_mask, &omask);
- }
-
- if (listio(lio->r_cmd, &lio_req, 1) < 0) {
- doio_fprintf(stderr,
- "listio() failed: %s (%d)\n%s\n",
- SYSERR, errno,
- format_listio(req, lio->r_cmd, &lio_req, 1, fd, Pattern));
- aio_unregister(aio_id);
- doio_upanic(U_RVAL);
- goto lio_done;
- }
-
- if (signo) {
- sigprocmask(SIG_SETMASK, &omask, NULL);
- }
-
- /*
- * Wait for io to complete
- */
-
- aio_wait(aio_id);
-
- nstrides = lio->r_nstrides ? lio->r_nstrides : 1;
- if (aiop->iosw.sw_count != lio->r_nbytes * nstrides) {
- doio_fprintf(stderr,
- "Bad iosw from listio()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n",
- 1, 0, lio->r_nbytes * lio->r_nstrides,
- aiop->iosw.sw_flag,
- aiop->iosw.sw_error, aiop->iosw.sw_count,
- format_listio(req, lio->r_cmd, &lio_req, 1, fd, Pattern));
- aio_unregister(aio_id);
- doio_upanic(U_IOSW);
- goto lio_done;
- }
-
- aio_unregister(aio_id);
-
- /*
- * Verify that the data was written correctly - check_file() returns
- * a non-null pointer which contains an error message if there are
- * problems.
- *
- * For listio, we basically have to make 1 call to check_file for each
- * stride.
- */
-
- if (v_opt && lio_req.li_opcode == LO_WRITE) {
- fstride = lio->r_filestride ? lio->r_filestride : lio->r_nbytes;
- mstride = lio->r_memstride ? lio->r_memstride : lio->r_nbytes;
- foffset = lio->r_offset;
-
- if (mstride> 0 || lio->r_nstrides <= 1) {
- moffset = addr;
- } else {
- moffset = addr + mem_needed - lio->r_nbytes;
- }
-
- for (i = 0; i < lio_req.li_nstride; i++) {
- msg = check_file(lio->r_file,
- foffset, lio->r_nbytes,
- Pattern, Pattern_Length,
- moffset - addr,
- lio->r_oflags & O_PARALLEL);
-
- if (msg != NULL) {
- doio_fprintf(stderr, "%s\n%s\n",
- msg,
- format_listio(req, lio->r_cmd, &lio_req, 1, fd, Pattern));
- doio_upanic(U_CORRUPTION);
- exit(E_COMPARE);
- }
-
- moffset += mstride;
- foffset += fstride;
- }
-
- }
-
- rval = 0;
-
- lio_done:
-
- /*
- * General cleanup ...
- *
- */
-
- /*
- * Release file locks if necessary
- */
-
- if (got_lock) {
- if (lock_file_region(lio->r_file, fd, F_UNLCK,
- min_byte, (max_byte-min_byte+1)) < 0) {
- return -1;
- }
- }
-
- return rval;
-#else
- return -1;
-#endif
-}
-
-/*
- * perform ssread/sswrite operations
- */
-
-#ifdef _CRAY1
-
-int
-do_ssdio(req)
-struct io_req *req;
-{
- int nbytes, nb;
- char errbuf[BSIZE];
-
- nbytes = req->r_data.ssread.r_nbytes;
-
- /*
- * Grab core and sds space
- */
-
- if ((nb = alloc_mem(nbytes)) < 0)
- return nb;
-
- if (alloc_sds(nbytes) == -1)
- return -1;
-
- if (req->r_type == SSWRITE) {
-
- /*
- * Init data and ship it to the ssd
- */
-
- Pattern[0] = req->r_data.sswrite.r_pattern;
- /*pattern_fill(Memptr, nbytes, Pattern, Pattern_Length, 0);*/
- (*Data_Fill)(Memptr, nbytes, Pattern, Pattern_Length, 0);
-
- if (sswrite((long)Memptr, (long)Sdsptr, btoc(nbytes)) == -1) {
- doio_fprintf(stderr, "sswrite() failed: %s (%d)\n%s\n",
- SYSERR, errno,
- format_sds(req, Memptr, Sdsptr, Pattern));
- doio_upanic(U_RVAL);
- return -1;
- }
- } else {
- /*
- * read from sds
- */
-
- if (ssread((long)Memptr, (long)Sdsptr, btoc(nbytes)) == -1) {
- doio_fprintf(stderr, "ssread() failed: %s (%d)\n%s\n",
- SYSERR, errno,
- format_sds(req, Memptr, Sdsptr, Pattern));
-
- doio_upanic(U_RVAL);
- return -1;
- }
- }
-
- /*
- * Verify data if SSWRITE and v_opt
- */
-
- if (v_opt && req->r_type == SSWRITE) {
- ssread((long)Memptr, (long)Sdsptr, btoc(nbytes));
-
- if (pattern_check(Memptr, nbytes, Pattern, Pattern_Length, 0) == -1) {
- doio_fprintf(stderr,
- "sds DATA COMPARE ERROR - ABORTING\n%s\n",
- format_sds(req, Memptr, Sdsptr, Pattern));
-
- doio_upanic(U_CORRUPTION);
- exit(E_COMPARE);
- }
- }
-}
-
-#else
-
-#ifdef CRAY
-
-int
-do_ssdio(req)
-struct io_req *req;
-{
- doio_fprintf(stderr,
- "Internal Error - do_ssdio() called on a non-cray1 system\n");
- alloc_mem(-1);
- exit(E_INTERNAL);
-}
-
-#endif
-
-#endif /* _CRAY1 */
-
-\f
-/* ---------------------------------------------------------------------------
- *
- * A new paradigm of doing the r/w system call where there is a "stub"
- * function that builds the info for the system call, then does the system
- * call; this is called by code that is common to all system calls and does
- * the syscall return checking, async I/O wait, iosw check, etc.
- *
- * Flags:
- * WRITE, ASYNC, SSD/SDS,
- * FILE_LOCK, WRITE_LOG, VERIFY_DATA,
- */
-
-struct status {
- int rval; /* syscall return */
- int err; /* errno */
- int *aioid; /* list of async I/O structures */
-};
-
-struct syscall_info {
- char *sy_name;
- int sy_type;
- struct status *(*sy_syscall)();
- int (*sy_buffer)();
- char *(*sy_format)();
- int sy_flags;
- int sy_bits;
-};
-
-#define SY_WRITE 00001
-#define SY_ASYNC 00010
-#define SY_IOSW 00020
-#define SY_SDS 00100
-
-char *
-fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd)
-{
- static char *errbuf=NULL;
- char *cp;
- struct rw_req *io;
- struct smap *aname;
-#ifdef CRAY
- struct stat sbuf;
-#endif
-
- if(errbuf == NULL)
- errbuf = (char *)malloc(32768);
-
- io = &ioreq->r_data.io;
+ io = &ioreq->r_data.io;
/*
* Look up async I/O completion strategy
if(sy->sy_flags & SY_WRITE) {
cp += sprintf(cp, " write done at file offset %d - pattern is %c (%#o)\n",
io->r_offset,
- (io->r_pattern == '\0') ? '?' : io->r_pattern,
+ (io->r_pattern == '\0') ? '?' : io->r_pattern,
io->r_pattern);
} else {
cp += sprintf(cp, " read done at file offset %d\n",
cp += sprintf(cp, " memory alignment is %s\n",
(io->r_uflags & F_WORD_ALIGNED) ? "aligned" : "unaligned");
-#ifdef CRAY
- if(io->r_oflags & O_RAW) {
- cp += sprintf(cp, " RAW I/O: offset %% 4096 = %d length %% 4096 = %d\n",
- io->r_offset % 4096, io->r_nbytes % 4096);
- fstat(fd, &sbuf);
- cp += sprintf(cp, " optimal file xfer size: small: %d large: %d\n",
- sbuf.st_blksize, sbuf.st_oblksize);
- cp += sprintf(cp, " cblks %d cbits %#o\n",
- sbuf.st_cblks, sbuf.st_cbits);
- }
-#endif
-#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) {
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,
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);
}
-/*
- * Issue listio requests
- */
-#ifdef CRAY
-struct status *
-sy_listio(req, sysc, fd, addr)
-struct io_req *req;
-struct syscall_info *sysc;
-int fd;
-char *addr;
-{
- int offset, nbytes, nstrides, nents, aio_strat;
- int aio_id, signo, o, i, lc;
- char *a;
- struct listreq *lio_req, *l;
- struct aio_info *aiop;
- struct status *status;
-
- /*
- * Initialize common fields - assumes r_oflags, r_file, r_offset, and
- * r_nbytes are at the same offset in the read_req and reada_req
- * structures.
- */
- offset = req->r_data.io.r_offset;
- nbytes = req->r_data.io.r_nbytes;
- nstrides = req->r_data.io.r_nstrides;
- nents = req->r_data.io.r_nent;
- aio_strat = req->r_data.io.r_aio_strat;
-
- lc = (sysc->sy_flags & SY_ASYNC) ? LC_START : LC_WAIT;
-
- status = (struct status *)malloc(sizeof(struct status));
- if( status == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
- status->aioid = (int *)malloc( (nents+1) * sizeof(int) );
- if( status->aioid == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
-
- signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0;
-
- lio_req = (struct listreq *)malloc(nents * sizeof(struct listreq));
- if( lio_req == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
- for(l=lio_req,a=addr,o=offset,i=0;
- i < nents;
- l++, a+=nbytes, o+=nbytes, i++) {
-
- aio_id = aio_register(fd, aio_strat, signo);
- aiop = aio_slot(aio_id);
- status->aioid[i] = aio_id;
-
- l->li_opcode = (sysc->sy_flags & SY_WRITE) ? LO_WRITE : LO_READ;
- l->li_offset = o;
- l->li_fildes = fd;
- l->li_buf = a;
- l->li_nbyte = nbytes;
- l->li_status = &aiop->iosw;
- l->li_signo = signo;
- l->li_nstride = nstrides;
- l->li_filstride = 0;
- l->li_memstride = 0;
- l->li_drvr = 0;
- l->li_flags = LF_LSEEK;
- }
-
- status->aioid[nents] = -1; /* end sentinel */
-
- if( (status->rval = listio(lc, lio_req, nents)) == -1) {
- status->err = errno;
- }
-
- free(lio_req);
- return(status);
-}
-
-/*
- * Calculate the size of a request in bytes and min/max boundaries
- *
- * This assumes filestride & memstride = 0.
- */
-int
-listio_mem(struct io_req *req, int offset, int fmstride,
- int *min, int *max)
-{
- int i, size;
-
- size = stride_bounds(offset, fmstride,
- req->r_data.io.r_nstrides*req->r_data.io.r_nent,
- req->r_data.io.r_nbytes, min, max);
- return(size);
-}
-
-char *
-fmt_listio(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
-{
- static char *errbuf = NULL;
- char *cp;
- char *c, *opcode;
- int i;
-
- if(errbuf == NULL){
- errbuf = (char *)malloc(32768);
- if( errbuf == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
- }
-
- c = (sy->sy_flags & SY_ASYNC) ? "lc_wait" : "lc_start";
-
- cp = errbuf;
- cp += sprintf(cp, "syscall: listio(%s, (?), %d)\n",
- c, req->r_data.io.r_nent);
-
- cp += sprintf(cp, " data buffer at %#o\n", addr);
-
- return(errbuf);
-}
-#endif /* CRAY */
-
struct status *
sy_pread(req, sysc, fd, addr)
struct io_req *req;
return(errbuf);
}
-#ifndef CRAY
-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;
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);
-}
-#endif /* !CRAY */
-
-#ifdef sgi
struct status *
-sy_aread(req, sysc, fd, addr)
-struct io_req *req;
-struct syscall_info *sysc;
-int fd;
-char *addr;
-{
- struct status *sy_arw();
- return sy_arw(req, sysc, fd, addr, 0);
-}
-
-struct status *
-sy_awrite(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_arw();
- return sy_arw(req, sysc, fd, addr, 1);
+ return sy_rwv(req, sysc, fd, addr, 0);
}
-/*
- #define sy_aread(A, B, C, D) sy_arw(A, B, C, D, 0)
- #define sy_awrite(A, B, C, D) sy_arw(A, B, C, D, 1)
- */
-
struct status *
-sy_arw(req, sysc, fd, addr, rw)
-struct io_req *req;
+sy_writev(req, sysc, fd, addr)
+struct io_req *req;
struct syscall_info *sysc;
int fd;
char *addr;
-int rw;
{
- /* POSIX 1003.1b-1993 Async read */
- struct status *status;
- int rc;
- int aio_id, aio_strat, signo;
- struct aio_info *aiop;
-
- status = (struct status *)malloc(sizeof(struct status));
- if( status == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
- aio_strat = req->r_data.io.r_aio_strat;
- signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0;
-
- aio_id = aio_register(fd, aio_strat, signo);
- aiop = aio_slot(aio_id);
-
- memset( (void *)&aiop->aiocb, 0, sizeof(aiocb_t));
-
- aiop->aiocb.aio_fildes = fd;
- aiop->aiocb.aio_nbytes = req->r_data.io.r_nbytes;
- aiop->aiocb.aio_offset = req->r_data.io.r_offset;
- aiop->aiocb.aio_buf = addr;
- aiop->aiocb.aio_reqprio = 0; /* must be 0 */
- aiop->aiocb.aio_lio_opcode = 0;
-
- if(aio_strat == A_SIGNAL) { /* siginfo(2) stuff */
- aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- aiop->aiocb.aio_sigevent.sigev_signo = signo;
- } else if(aio_strat == A_CALLBACK) {
- aiop->aiocb.aio_sigevent.sigev_signo = 0;
- aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_CALLBACK;
- aiop->aiocb.aio_sigevent.sigev_func = cb_handler;
- aiop->aiocb.aio_sigevent.sigev_value.sival_int = aio_id;
- } else {
- aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_NONE;
- aiop->aiocb.aio_sigevent.sigev_signo = 0;
- }
-
- if(rw)
- rc = aio_write(&aiop->aiocb);
- else
- rc = aio_read(&aiop->aiocb);
-
- status->aioid = (int *)malloc( 2 * sizeof(int) );
- if( status->aioid == NULL ){
- doio_fprintf(stderr, "malloc failed, %s/%d\n",
- __FILE__, __LINE__);
- return NULL;
- }
- status->aioid[0] = aio_id;
- status->aioid[1] = -1;
- status->rval = rc;
- status->err = errno;
- return(status);
+ return sy_rwv(req, sysc, fd, addr, 1);
}
char *
-fmt_aread(struct io_req *req, struct syscall_info *sy, int fd, char *addr)
+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(&aiop->aiocb)\n",
- sy->sy_name);
+ cp += sprintf(cp, "syscall: %s(%d, (iov on stack), 1)\n",
+ sy->sy_name, fd);
return(errbuf);
}
-#endif /* sgi */
-
-#ifndef CRAY
-
-struct status *
-sy_mmread(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);
-}
-
-struct status *
-sy_mmwrite(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);
-}
struct status *
sy_mmrw(req, sysc, fd, addr, 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)
{
return(errbuf);
}
-#endif /* !CRAY */
struct syscall_info syscalls[] = {
-#ifdef CRAY
- { "listio-read-sync", LREAD,
- sy_listio, NULL, fmt_listio,
- SY_IOSW
- },
- { "listio-read-strides-sync", LSREAD,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW
- },
- { "listio-read-reqs-sync", LEREAD,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW
- },
- { "listio-read-async", LREADA,
- sy_listio, NULL, fmt_listio,
- SY_IOSW | SY_ASYNC
- },
- { "listio-read-strides-async", LSREADA,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_ASYNC
- },
- { "listio-read-reqs-async", LEREADA,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_ASYNC
- },
- { "listio-write-sync", LWRITE,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE
- },
- { "listio-write-strides-sync", LSWRITE,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE
- },
- { "listio-write-reqs-sync", LEWRITE,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE
- },
- { "listio-write-async", LWRITEA,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE | SY_ASYNC
- },
- { "listio-write-strides-async", LSWRITEA,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE | SY_ASYNC
- },
- { "listio-write-reqs-async", LEWRITEA,
- sy_listio, listio_mem, fmt_listio,
- SY_IOSW | SY_WRITE | SY_ASYNC
- },
-#endif
-
-#ifdef sgi
- { "aread", AREAD,
- sy_aread, NULL, fmt_aread,
- SY_IOSW | SY_ASYNC
- },
- { "awrite", AWRITE,
- sy_awrite, NULL, fmt_aread,
- SY_IOSW | SY_WRITE | SY_ASYNC
- },
-#endif
{ "pread", PREAD,
sy_pread, NULL, fmt_pread,
0
SY_WRITE
},
-#ifndef CRAY
{ "readv", READV,
sy_readv, NULL, fmt_readv,
0
sy_mmwrite, NULL, fmt_mmrw,
SY_WRITE
},
-#endif
{ NULL, 0,
0, 0, 0,
struct status *s;
struct wlog_rec wrec;
struct syscall_info *sy;
-#ifdef sgi
- struct aio_info *aiop;
-#endif
-#ifdef CRAY
- /* REFERENCED */
- struct iosw *iosw;
-#endif
-#ifndef NO_XFS
struct fd_cache *fdc;
-#endif
/*
* Initialize common fields - assumes r_oflags, r_file, r_offset, and
mem_needed = nbytes;
}
-#ifdef CRAY
- if ((rval = alloc_mem(mem_needed + wtob(1) * 2 + MPP_BUMP * sizeof(UINT64_T))) < 0) {
- return rval;
- }
-#else
-#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
-#endif /* CRAY */
-
- Pattern[0] = pattern;
-
- /*
- * Allocate SDS space for backdoor write if desired
- */
-
- if (oflags & O_SSD) {
-#ifdef CRAY
-#ifndef _CRAYMPP
- if (alloc_sds(nbytes) == -1)
- return -1;
-
- if( sy->sy_flags & SY_WRITE ) {
- /*pattern_fill(Memptr, mem_needed, Pattern, Pattern_Length, 0);*/
- (*Data_Fill)(Memptr, nbytes, Pattern, Pattern_Length, 0);
-
- if (sswrite((long)Memptr, Sdsptr, btoc(mem_needed)) == -1) {
- doio_fprintf(stderr, "sswrite(%d, %d, %d) failed: %s (%d)\n",
- (long)Memptr, Sdsptr,
- btoc(mem_needed), SYSERR, errno);
- fflush(stderr);
- return -1;
- }
- }
- addr = (char *)Sdsptr;
-#else
- doio_fprintf(stderr, "Invalid O_SSD flag was generated for MPP system\n");
- fflush(stderr);
- return -1;
-#endif /* _CRAYMPP */
-#else /* CRAY */
+ Pattern[0] = pattern;
+
+ /*
+ * Allocate SDS space for backdoor write if desired
+ */
+
+ if (oflags & O_SSD) {
doio_fprintf(stderr, "Invalid O_SSD flag was generated for non-Cray system\n");
fflush(stderr);
return -1;
-#endif /* CRAY */
} else {
addr = Memptr;
*/
if (! (req->r_data.io.r_uflags & F_WORD_ALIGNED)) {
-#ifdef _CRAYMPP
- addr += random_range(0, MPP_BUMP, 1, NULL) * sizeof(int);
-#endif
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.
* structure.
*/
- if( sy->sy_flags & SY_IOSW ) {
-#ifdef CRAY
- for( i=0; i < nents; i++ ) {
- if(s->aioid == NULL)
- break; /* >>> error condition? */
- aiop = aio_slot(s->aioid[i]);
- iosw = &aiop->iosw;
- if(iosw->sw_error != 0) {
- doio_fprintf(stderr,
- "%s() iosw error set: %s\n%s\n%s\n",
- sy->sy_name,
- strerror(iosw->sw_error),
- fmt_ioreq(req, sy, fd),
- (*sy->sy_format)(req, sy, fd, addr));
- doio_upanic(U_IOSW);
- rval = -1;
- } else if(iosw->sw_count != nbytes*nstrides) {
- doio_fprintf(stderr,
- "Bad iosw from %s() #%d\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n%s\n",
- sy->sy_name, i,
- 1, 0, nbytes*nstrides,
- iosw->sw_flag,
- iosw->sw_error,
- iosw->sw_count,
- fmt_ioreq(req, sy, fd),
- (*sy->sy_format)(req, sy, fd, addr));
- doio_upanic(U_IOSW);
- rval = -1;
- }
-
- aio_unregister(s->aioid[i]);
- }
-#endif /* CRAY */
-#ifdef sgi
- for( i=0; s->aioid[i] != -1; i++ ) {
- if(s->aioid == NULL) {
- doio_fprintf(stderr,
- "aioid == NULL!\n");
- break;
- }
- aiop = aio_slot(s->aioid[i]);
-
- /*
- * make sure the io completed without error
- */
- if (aiop->aio_errno != 0) {
- doio_fprintf(stderr,
- "%s() aio error set: %s (%d)\n%s\n%s\n",
- sy->sy_name,
- strerror(aiop->aio_errno),
- aiop->aio_errno,
- fmt_ioreq(req, sy, fd),
- (*sy->sy_format)(req, sy, fd, addr));
- doio_upanic(U_IOSW);
- rval = -1;
- } else if (aiop->aio_ret != nbytes) {
- doio_fprintf(stderr,
- "Bad aio return from %s() #%d\nExpected (%d,%d), got (%d,%d)\n%s\n%s\n",
- sy->sy_name, i,
- 0, nbytes,
- aiop->aio_errno,
- aiop->aio_ret,
- fmt_ioreq(req, sy, fd),
- (*sy->sy_format)(req, sy, fd, addr));
- aio_unregister(s->aioid[i]);
- doio_upanic(U_IOSW);
- return -1;
- } else {
- aio_unregister(s->aioid[i]);
- rval = 0;
- }
- }
-#endif /* sgi */
- } else {
+ if( !(sy->sy_flags & SY_IOSW) ) {
if(s->rval != mem_needed) {
doio_fprintf(stderr,
* - XFS_IOC_RESVSP
* - XFS_IOC_UNRESVSP
*/
-#ifndef NO_XFS
int
do_xfsctl(req)
struct io_req *req;
return (rval == -1) ? -1 : 0;
}
-#endif
/*
* fsync(2) and fdatasync(2)
*/
-#ifndef CRAY
int
do_sync(req)
struct io_req *req;
}
return (rval == -1) ? -1 : 0;
}
-#endif
-
int
doio_pat_fill(char *addr, int mem_needed, char *Pattern, int Pattern_Length,
static char errbuf[4096];
int fd, nb, flags;
char *buf, *em, *ep;
-#ifndef NO_XFS
struct fd_cache *fdc;
-#endif
buf = Memptr;
flags = Validation_Flags | O_RDONLY;
} else {
flags = O_RDONLY;
- if (fsa) {
-#ifdef CRAY
- flags |= O_PARALLEL | O_RAW | O_WELLFORMED;
-#endif
- }
}
if ((fd = alloc_fd(file, flags)) == -1) {
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;
}
* Simple function for allocating core memory. Uses Memsize and Memptr to
* keep track of the current amount allocated.
*/
-#ifndef CRAY
+
int
alloc_mem(nbytes)
int nbytes;
char filename[255];
#ifdef linux
struct shmid_ds shm_ds;
-#endif
-
-#ifdef linux
bzero( &shm_ds, sizeof(struct shmid_ds) );
#endif
switch(Memalloc[me].memtype) {
case MEM_DATA:
-#ifdef sgi
- if(Memalloc[me].flags & MEMF_MPIN)
- munpin(Memalloc[me].space,
- Memalloc[me].size);
-#endif
free(Memalloc[me].space);
Memalloc[me].space = NULL;
Memptr = NULL;
Memsize = 0;
break;
case MEM_SHMEM:
-#ifdef sgi
- if(Memalloc[me].flags & MEMF_MPIN)
- munpin(Memalloc[me].space,
- Memalloc[me].size);
-#endif
shmdt(Memalloc[me].space);
Memalloc[me].space = NULL;
-#ifdef sgi
- shmctl(Memalloc[me].fd, IPC_RMID);
-#else
shmctl(Memalloc[me].fd, IPC_RMID, &shm_ds);
-#endif
break;
case MEM_MMAP:
-#ifdef sgi
- if(Memalloc[me].flags & MEMF_MPIN)
- munpin(Memalloc[me].space,
- Memalloc[me].size);
-#endif
munmap(Memalloc[me].space,
Memalloc[me].size);
close(Memalloc[me].fd);
case MEM_DATA:
if( nbytes > M->size ) {
if( M->space != NULL ){
-#ifdef sgi
- if( M->flags & MEMF_MPIN )
- munpin( M->space, M->size );
-#endif
free(M->space);
}
M->space = NULL;
nbytes, SYSERR, errno);
return -1;
}
-#ifdef sgi
- if(M->flags & MEMF_MPIN) {
- if( mpin(cp, nbytes) == -1 ) {
- doio_fprintf(stderr, "mpin(0x%lx, %d) failed: %s (%d)\n",
- cp, nbytes, SYSERR, errno);
- }
- }
-#endif
M->space = (void *)cp;
M->size = nbytes;
}
case MEM_MMAP:
if( nbytes > M->size ) {
if( M->space != NULL ) {
-#ifdef sgi
- if( M->flags & MEMF_MPIN )
- munpin(M->space, M->size);
-#endif
munmap(M->space, M->size);
close(M->fd);
if( M->flags & MEMF_FILE )
/* bias flags on MEMF_PRIVATE etc */
if(M->flags & MEMF_PRIVATE)
flags |= MAP_PRIVATE;
-#ifdef sgi
- if(M->flags & MEMF_LOCAL)
- flags |= MAP_LOCAL;
- if(M->flags & MEMF_AUTORESRV)
- flags |= MAP_AUTORESRV;
- if(M->flags & MEMF_AUTOGROW)
- flags |= MAP_AUTOGROW;
-#endif
if(M->flags & MEMF_SHARED)
flags |= MAP_SHARED;
M->name);
doio_fprintf(stderr, "\t%s%s%s%s%s",
(flags & MAP_PRIVATE) ? "private " : "",
-#ifdef sgi
- (flags & MAP_LOCAL) ? "local " : "",
- (flags & MAP_AUTORESRV) ? "autoresrv " : "",
- (flags & MAP_AUTOGROW) ? "autogrow " : "",
-#endif
(flags & MAP_SHARED) ? "shared" : "");
return(-1);
}
case MEM_SHMEM:
if( nbytes > M->size ) {
if( M->space != NULL ) {
-#ifdef sgi
- if( M->flags & MEMF_MPIN )
- munpin(M->space, M->size);
-#endif
- shmdt( M->space );
-#ifdef sgi
- shmctl( M->fd, IPC_RMID );
-#else
shmctl( M->fd, IPC_RMID, &shm_ds );
-#endif
}
M->space = NULL;
M->size = 0;
shmid, SYSERR, errno);
return(-1);
}
-#ifdef sgi
- if(M->flags & MEMF_MPIN) {
- if( mpin(M->space, M->size) == -1 ) {
- doio_fprintf(stderr, "mpin(0x%lx, %d) failed: %s (%d)\n",
- M->space, M->size, SYSERR, errno);
- }
- }
-#endif
}
break;
mturn++;
return 0;
}
-#endif /* !CRAY */
-
-#ifdef CRAY
-int
-alloc_mem(nbytes)
-int nbytes;
-{
- char *cp;
- int ip;
- static char *malloc_space;
-
- /*
- * The "unicos" version of this did some stuff with sbrk;
- * this caused problems with async I/O on irix, and now appears
- * to be causing problems with FSA I/O on unicos/mk.
- */
-#ifdef NOTDEF
- if (nbytes > Memsize) {
- if ((cp = (char *)sbrk(nbytes - Memsize)) == (char *)-1) {
- doio_fprintf(stderr, "sbrk(%d) failed: %s (%d)\n",
- nbytes - Memsize, SYSERR, errno);
- return -1;
- }
-
- if (Memsize == 0)
- Memptr = cp;
- Memsize += nbytes - Memsize;
- }
-#else
-
- /* nbytes = -1 means "free all allocated memory" */
- if( nbytes == -1 ) {
- free( malloc_space );
- Memptr = NULL;
- Memsize = 0;
- return 0;
- }
-
- if( nbytes > Memsize ) {
- if( Memsize != 0 )
- free( malloc_space );
-
- if( (cp = malloc_space = malloc( nbytes )) == NULL ) {
- doio_fprintf(stderr, "malloc(%d) failed: %s (%d)\n",
- nbytes, SYSERR, errno);
- return -1;
- }
-
-#ifdef _CRAYT3E
- /* T3E requires memory to be aligned on 0x40 word boundaries */
- ip = (int)cp;
- if( ip & 0x3F != 0 ) {
- doio_fprintf(stderr, "malloc(%d) = 0x%x(0x%x) not aligned by 0x%x\n",
- nbytes, cp, ip, ip & 0x3f);
-
- free(cp);
- if( (cp = malloc_space = malloc( nbytes + 0x40 )) == NULL ) {
- doio_fprintf(stderr, "malloc(%d) failed: %s (%d)\n",
- nbytes, SYSERR, errno);
- return -1;
- }
- ip = (int)cp;
- cp += (0x40 - (ip & 0x3F));
- }
-#endif /* _CRAYT3E */
- Memptr = cp;
- Memsize = nbytes;
- }
-#endif /* NOTDEF */
- return 0;
-}
-#endif /* CRAY */
-
-/*
- * Simple function for allocating sds space. Uses Sdssize and Sdsptr to
- * keep track of location and size of currently allocated chunk.
- */
-
-#ifdef _CRAY1
-
-int
-alloc_sds(nbytes)
-int nbytes;
-{
- int nblks;
-
- if (nbytes > Sdssize) {
- if ((nblks = ssbreak(btoc(nbytes - Sdssize))) == -1) {
- doio_fprintf(stderr, "ssbreak(%d) failed: %s (%d)\n",
- btoc(nbytes - Sdssize), SYSERR, errno);
- return -1;
- }
-
- Sdssize = ctob(nblks);
- Sdsptr = 0;
- }
-
- return 0;
-}
-
-#else
-
-#ifdef CRAY
-
-int
-alloc_sds(nbytes)
-int nbytes;
-{
- doio_fprintf(stderr,
- "Internal Error - alloc_sds() called on a CRAY2 system\n");
- alloc_mem(-1);
- exit(E_INTERNAL);
-}
-
-#endif
-
-#endif /* _CRAY1 */
/*
* Function to maintain a file descriptor cache, so that doio does not have
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.
if (cp->c_fd != -1) {
close(cp->c_fd);
}
-#ifndef CRAY
if (cp->c_memaddr != NULL) {
munmap(cp->c_memaddr, cp->c_memlen);
}
-#endif
}
free(cache);
if (cp->c_fd != -1 &&
cp->c_oflags == oflags &&
strcmp(cp->c_file, file) == 0) {
-#ifdef CRAY
- cp->c_rtc = _rtc();
-#else
cp->c_rtc = Reqno;
-#endif
return cp;
}
free_slot->c_fd = fd;
free_slot->c_oflags = oflags;
strcpy(free_slot->c_file, file);
-#ifdef CRAY
- free_slot->c_rtc = _rtc();
-#else
free_slot->c_rtc = Reqno;
-#endif
-#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;
free_slot->c_memalign = finfo.d_mem;
free_slot->c_miniosz = finfo.d_miniosz;
free_slot->c_maxiosz = finfo.d_maxiosz;
-#endif
-#ifndef CRAY
free_slot->c_memaddr = NULL;
free_slot->c_memlen = 0;
-#endif
return free_slot;
}
*
*/
-#ifdef sgi
-/*
- * "caller-id" for signals
- */
-void
-signal_info(int sig, siginfo_t *info, void *v)
-{
- int haveit = 0;
-
- if(info != NULL) {
- switch(info->si_code) {
- case SI_USER:
- doio_fprintf(stderr,
- "signal_info: si_signo %d si_errno %d si_code SI_USER pid %d uid %d\n",
- info->si_signo, info->si_errno,
- info->si_pid, info->si_uid);
- haveit = 1;
- break;
-
- case SI_QUEUE:
- doio_fprintf(stderr, "signal_info si_signo %d si_code = SI_QUEUE\n",
- info->si_signo);
- haveit = 1;
- break;
- }
-
- if( ! haveit ){
- if( (info->si_signo == SIGSEGV) ||
- (info->si_signo == SIGBUS) ){
- doio_fprintf(stderr, "signal_info si_signo %d si_errno %d si_code = %d si_addr=%p active_mmap_rw=%d havesigint=%d\n",
- info->si_signo, info->si_errno,
- info->si_code, info->si_addr,
- active_mmap_rw,
- havesigint);
- haveit = 1;
- }
- }
-
- if( !haveit ){
- doio_fprintf(stderr, "signal_info: si_signo %d si_errno %d unknown code %d\n",
- info->si_signo, info->si_errno,
- info->si_code);
- }
- } else {
- doio_fprintf(stderr, "signal_info: sig %d\n", sig);
- }
-}
-#endif
-
-#ifdef sgi
-void
-cleanup_handler(int sig, siginfo_t *info, void *v)
-{
- havesigint=1; /* in case there's a followup signal */
- /*signal_info(sig, info, v);*/ /* be quiet on "normal" kill */
- alloc_mem(-1);
- exit(0);
-}
-
-
-void
-die_handler(int sig, siginfo_t *info, void *v)
-{
- doio_fprintf(stderr, "terminating on signal %d\n", sig);
- signal_info(sig, info, v);
- alloc_mem(-1);
- exit(1);
-}
-
-void
-sigbus_handler(int sig, siginfo_t *info, void *v)
-{
- /* While we are doing a memcpy to/from an mmapped region we can
- get a SIGBUS for a variety of reasons--and not all of them
- should be considered failures.
-
- Under normal conditions if we get a SIGINT it means we've been
- told to shutdown. However, if we're currently doing the above-
- mentioned memcopy then the kernel will follow that SIGINT with
- a SIGBUS. We can guess that we're in this situation by seeing
- that the si_errno field in the siginfo structure has EINTR as
- an errno. (We might make the guess stronger by looking at the
- si_addr field to see that it's not faulting off the end of the
- mmapped region, but it seems that in such a case havesigint
- would not have been set so maybe that doesn't make the guess
- stronger.)
- */
-
-
- if( active_mmap_rw && havesigint && (info->si_errno == EINTR) ){
- cleanup_handler( sig, info, v );
- }
- else{
- die_handler( sig, info, v );
- }
-}
-#else
-
void
cleanup_handler()
{
exit(1);
}
-#ifndef CRAY
void
sigbus_handler(sig)
int sig;
else
die_handler(sig);
}
-#endif /* !CRAY */
-#endif /* sgi */
-
void
noop_handler(sig)
fprintf(stderr, "%d active async i/os\n", count);
}
-
-#ifdef sgi
-/*
- * Signal handler called as a callback, not as a signal.
- * 'val' is the value from sigev_value and is assumed to be the
- * Aio_Info[] index.
- */
-void
-cb_handler(val)
-sigval_t val;
-{
- struct aio_info *aiop;
-
-/*printf("cb_handler requesting slot %d\n", val.sival_int);*/
- aiop = aio_slot( val.sival_int );
-/*printf("cb_handler, aiop=%p\n", aiop);*/
-
-/*printf("%d in cb_handler\n", getpid() );*/
- if (aiop->strategy == A_CALLBACK) {
- aiop->signalled++;
-
- if (aio_done(aiop)) {
- aiop->done++;
- }
- }
-}
-#endif
-
struct aio_info *
aio_slot(aio_id)
int aio_id;
aiop->fd = fd;
aiop->strategy = strategy;
aiop->done = 0;
-#ifdef CRAY
- bzero((char *)&aiop->iosw, sizeof(aiop->iosw));
-#endif
if (strategy == A_SIGNAL) {
aiop->sig = sig;
#endif
sigset_t sigset;
struct aio_info *aiop;
-#ifdef CRAY
- struct iosw *ioswlist[1];
-#endif
-#ifdef sgi
- const aiocb_t *aioary[1];
-#endif
- int r, cnt;
-
-
- aiop = aio_slot(aio_id);
-/*printf("%d aiop B =%p\n", getpid(), aiop);*/
-
- switch (aiop->strategy) {
- case A_POLL:
- while (! aio_done(aiop))
- ;
- break;
-
- case A_SIGNAL:
- sigemptyset(&sigset);
- sighold( aiop->sig );
-
- while ( !aiop->signalled || !aiop->done ) {
- sigsuspend(&sigset);
- sighold( aiop->sig );
- }
- break;
-
-#ifdef CRAY
- case A_RECALL:
- ioswlist[0] = &aiop->iosw;
- if (recall(aiop->fd, 1, ioswlist) < 0) {
- doio_fprintf(stderr, "recall() failed: %s (%d)\n",
- SYSERR, errno);
- exit(E_SETUP);
- }
- break;
-
-#ifdef RECALL_SIZEOF
-
- case A_RECALLA:
- RECALL_INIT(mask);
- RECALL_SET(mask, aiop->fd);
- if (recalla(mask) < 0) {
- doio_fprintf(stderr, "recalla() failed: %s (%d)\n",
- SYSERR, errno);
- exit(E_SETUP);
- }
-
- RECALL_CLR(mask, aiop->fd);
- break;
-#endif
-
- case A_RECALLS:
- ioswlist[0] = &aiop->iosw;
- if (recalls(1, ioswlist) < 0) {
- doio_fprintf(stderr, "recalls failed: %s (%d)\n",
- SYSERR, errno);
- exit(E_SETUP);
- }
- break;
-#endif /* CRAY */
-
-#ifdef sgi
- case A_CALLBACK:
- aioary[0] = &aiop->aiocb;
- cnt=0;
- do {
- r = aio_suspend(aioary, 1, NULL);
- if( r == -1 ){
- doio_fprintf(stderr, "aio_suspend failed: %s (%d)\n",
- SYSERR, errno );
- exit(E_SETUP);
- }
- cnt++;
- } while(aiop->done == 0);
-
-#if 0
- /*
- * after having this set for a while, I've decided that
- * it's too noisy
- */
- if(cnt > 1)
- doio_fprintf(stderr, "aio_wait: callback wait took %d tries\n", cnt);
-#endif
-
- /*
- * Note: cb_handler already calls aio_done
- */
- break;
-
-
- case A_SUSPEND:
- aioary[0] = &aiop->aiocb;
- r = aio_suspend(aioary, 1, NULL);
- if( r == -1 ){
- doio_fprintf(stderr, "aio_suspend failed: %s (%d)\n",
- SYSERR, errno );
- exit(E_SETUP);
- }
-
- aio_done(aiop);
- break;
-#endif
- }
/*printf("aio_wait: errno %d return %d\n", aiop->aio_errno, aiop->aio_ret);*/
int
aio_done(struct aio_info *ainfo)
{
-#ifdef CRAY
- return ainfo->iosw.sw_flag;
-#endif
-
-#ifdef sgi
- if( (ainfo->aio_errno = aio_error(&ainfo->aiocb)) == -1 ){
- doio_fprintf(stderr, "aio_done: aio_error failed: %s (%d)\n",
- SYSERR, errno );
- exit(E_SETUP);
- }
- /*printf("%d aio_done aio_errno=%d\n", getpid(), ainfo->aio_errno);*/
- if( ainfo->aio_errno != EINPROGRESS ){
- if( (ainfo->aio_ret = aio_return(&ainfo->aiocb)) == -1 ){
- doio_fprintf(stderr, "aio_done: aio_return failed: %s (%d)\n",
- SYSERR, errno );
- exit(E_SETUP);
- }
- }
-
- return (ainfo->aio_errno != EINPROGRESS);
-#else
return -1; /* invalid */
-#endif
}
/*
if (U_opt == 0 || (mask & Upanic_Conditions) == 0) {
return;
}
-
-#ifdef CRAY
- if (upanic(PA_SET) < 0) {
- doio_fprintf(stderr, "WARNING - Could not set the panic flag - upanic(PA_SET) failed: %s (%d)\n",
- SYSERR, errno);
- }
-
- upanic(PA_PANIC);
-#endif
-#ifdef sgi
- syssgi(1005); /* syssgi test panic - DEBUG kernels only */
-#endif
doio_fprintf(stderr, "WARNING - upanic() failed\n");
}
break;
case 'M': /* memory allocation types */
-#ifndef CRAY
nmemargs = string_to_tokens(optarg, memargs, 32, ",");
for(ma=0; ma < nmemargs; ma++) {
parse_memalloc(memargs[ma]);
}
/*dump_memalloc();*/
-#else
- fprintf(stderr, "%s%s: Error: -M isn't supported on this platform\n", Prog, TagName);
- exit(1);
-#endif
M_opt++;
break;
case 'N':
- sprintf( TagName, "(%.39s)", optarg );
+ sprintf( TagName, "(%.37s)", optarg );
break;
case 'n':
Validation_Flags = O_SYNC;
} else if (strcasecmp(optarg, "buffered") == 0) {
Validation_Flags = 0;
-#ifdef CRAY
- } else if (strcasecmp(optarg, "parallel") == 0) {
- Validation_Flags = O_PARALLEL;
- } else if (strcasecmp(optarg, "ldraw") == 0) {
- Validation_Flags = O_LDRAW;
- } else if (strcasecmp(optarg, "raw") == 0) {
- Validation_Flags = O_RAW;
-#endif
} else if (strcasecmp(optarg, "direct") == 0) {
Validation_Flags = O_DIRECT;
} else {
* NBLKS
* nblks worth of directories - 1 int pids
*/
-#ifndef CRAY
void
parse_memalloc(char *arg)
{
}
}
-#endif /* !CRAY */
-
/*
* -d <op>:<time> - doio inter-operation delay
* currently this permits ONE type of delay between operations.
fprintf(stream, "\t Operations are:\n");
fprintf(stream, "\t select:time (1 second=1000000)\n");
fprintf(stream, "\t sleep:time (1 second=1)\n");
-#ifdef sgi
- fprintf(stream, "\t sginap:time (1 second=CLK_TCK=100)\n");
-#endif
fprintf(stream, "\t alarm:time (1 second=1)\n");
fprintf(stream, "\t-e Re-exec children before entering the main\n");
fprintf(stream, "\t loop. This is useful for spreading\n");
fprintf(stream, "\t-v Verify writes - this is done by doing a buffered\n");
fprintf(stream, "\t read() of the data if file io was done, or\n");
fprintf(stream, "\t an ssread()of the data if sds io was done\n");
-#ifndef CRAY
fprintf(stream, "\t-M Data buffer allocation method\n");
fprintf(stream, "\t alloc-type[,type]\n");
-#ifdef sgi
- fprintf(stream, "\t data:flags\n");
- fprintf(stream, "\t p - mpin buffer\n");
- fprintf(stream, "\t shmem:shmid:size:flags\n");
- fprintf(stream, "\t p - mpin buffer\n");
-#else
fprintf(stream, "\t data\n");
fprintf(stream, "\t shmem:shmid:size\n");
-#endif /* sgi */
fprintf(stream, "\t mmap:flags:filename\n");
fprintf(stream, "\t p - private\n");
-#ifdef sgi
- fprintf(stream, "\t s - shared\n");
- fprintf(stream, "\t l - local\n");
- fprintf(stream, "\t a - autoresrv\n");
- fprintf(stream, "\t G - autogrow\n");
-#else
fprintf(stream, "\t s - shared (shared file must exist\n"),
fprintf(stream, "\t and have needed length)\n");
-#endif
fprintf(stream, "\t f - fixed address (not used)\n");
fprintf(stream, "\t a - specify address (not used)\n");
fprintf(stream, "\t U - Unlink file when done\n");
fprintf(stream, "\t The default flag is private\n");
fprintf(stream, "\n");
-#endif /* !CRAY */
fprintf(stream, "\t-m message_interval Generate a message every 'message_interval'\n");
fprintf(stream, "\t requests. An interval of 0 suppresses\n");
fprintf(stream, "\t messages. The default is 0.\n");
fprintf(stream, "\t 'buffered' - validate using bufferd read\n");
fprintf(stream, "\t 'sync' - validate using O_SYNC read\n");
fprintf(stream, "\t 'direct - validate using O_DIRECT read'\n");
-#ifdef CRAY
- fprintf(stream, "\t 'ldraw' - validate using O_LDRAW read\n");
- fprintf(stream, "\t 'parallel' - validate using O_PARALLEL read\n");
- fprintf(stream, "\t 'raw' - validate using O_RAW read\n");
-#endif
fprintf(stream, "\t By default, 'parallel'\n");
fprintf(stream, "\t is used if the write was done with O_PARALLEL\n");
fprintf(stream, "\t or 'buffered' for all other writes.\n");