1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it 5f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as 6f08c3bdfSopenharmony_ci * published by the Free Software Foundation. 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but 9f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it is 13f08c3bdfSopenharmony_ci * free of the rightful claim of any third person regarding infringement 14f08c3bdfSopenharmony_ci * or the like. Any license provided herein, whether implied or 15f08c3bdfSopenharmony_ci * otherwise, applies only to this software file. Patent licenses, if 16f08c3bdfSopenharmony_ci * any, provided herein do not apply to combinations of this program with 17f08c3bdfSopenharmony_ci * other software, or any other product whatsoever. 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along 20f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc., 21f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24f08c3bdfSopenharmony_ci * Mountain View, CA 94043, or: 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * http://www.sgi.com 27f08c3bdfSopenharmony_ci * 28f08c3bdfSopenharmony_ci * For further information regarding this notice, see: 29f08c3bdfSopenharmony_ci * 30f08c3bdfSopenharmony_ci * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31f08c3bdfSopenharmony_ci */ 32f08c3bdfSopenharmony_ci/* 33f08c3bdfSopenharmony_ci * doio - a general purpose io initiator with system call and 34f08c3bdfSopenharmony_ci * write logging. See doio.h for the structure which defines 35f08c3bdfSopenharmony_ci * what doio requests should look like. 36f08c3bdfSopenharmony_ci * 37f08c3bdfSopenharmony_ci * Currently doio can handle read,write,reada,writea,ssread, 38f08c3bdfSopenharmony_ci * sswrite, and many varieties of listio requests. 39f08c3bdfSopenharmony_ci * For disk io, if the O_SSD flag is set doio will allocate 40f08c3bdfSopenharmony_ci * the appropriate amount of ssd and do the transfer - thus, doio 41f08c3bdfSopenharmony_ci * can handle all of the primitive types of file io. 42f08c3bdfSopenharmony_ci * 43f08c3bdfSopenharmony_ci * programming 44f08c3bdfSopenharmony_ci * notes: 45f08c3bdfSopenharmony_ci * ----------- 46f08c3bdfSopenharmony_ci * messages should generally be printed using doio_fprintf(). 47f08c3bdfSopenharmony_ci * 48f08c3bdfSopenharmony_ci */ 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci#include <stdio.h> 51f08c3bdfSopenharmony_ci#include <errno.h> 52f08c3bdfSopenharmony_ci#include <fcntl.h> 53f08c3bdfSopenharmony_ci#include <stdlib.h> 54f08c3bdfSopenharmony_ci#include <signal.h> 55f08c3bdfSopenharmony_ci#include <string.h> 56f08c3bdfSopenharmony_ci#include <ctype.h> 57f08c3bdfSopenharmony_ci#include <unistd.h> 58f08c3bdfSopenharmony_ci#include <time.h> 59f08c3bdfSopenharmony_ci#include <stdarg.h> 60f08c3bdfSopenharmony_ci#include <sys/stat.h> 61f08c3bdfSopenharmony_ci#include <sys/param.h> 62f08c3bdfSopenharmony_ci#include <sys/types.h> 63f08c3bdfSopenharmony_ci#include <sys/sysmacros.h> 64f08c3bdfSopenharmony_ci#ifdef CRAY 65f08c3bdfSopenharmony_ci#include <sys/iosw.h> 66f08c3bdfSopenharmony_ci#endif 67f08c3bdfSopenharmony_ci#ifdef sgi 68f08c3bdfSopenharmony_ci#include <aio.h> /* for aio_read,write */ 69f08c3bdfSopenharmony_ci#include <inttypes.h> /* for uint64_t type */ 70f08c3bdfSopenharmony_ci#include <siginfo.h> /* signal handlers & SA_SIGINFO */ 71f08c3bdfSopenharmony_ci#endif 72f08c3bdfSopenharmony_ci#ifndef CRAY 73f08c3bdfSopenharmony_ci#include <sys/uio.h> /* for struct iovec (readv) */ 74f08c3bdfSopenharmony_ci#include <sys/mman.h> /* for mmap(2) */ 75f08c3bdfSopenharmony_ci#include <sys/ipc.h> /* for i/o buffer in shared memory */ 76f08c3bdfSopenharmony_ci#include <sys/shm.h> /* for i/o buffer in shared memory */ 77f08c3bdfSopenharmony_ci#endif 78f08c3bdfSopenharmony_ci#include <sys/wait.h> 79f08c3bdfSopenharmony_ci#ifdef CRAY 80f08c3bdfSopenharmony_ci#include <sys/listio.h> 81f08c3bdfSopenharmony_ci#include <sys/panic.h> 82f08c3bdfSopenharmony_ci#endif 83f08c3bdfSopenharmony_ci#include <sys/time.h> /* for delays */ 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci#include "doio.h" 86f08c3bdfSopenharmony_ci#include "write_log.h" 87f08c3bdfSopenharmony_ci#include "random_range.h" 88f08c3bdfSopenharmony_ci#include "string_to_tokens.h" 89f08c3bdfSopenharmony_ci#include "pattern.h" 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci#define NMEMALLOC 32 92f08c3bdfSopenharmony_ci#define MEM_DATA 1 /* data space */ 93f08c3bdfSopenharmony_ci#define MEM_SHMEM 2 /* System V shared memory */ 94f08c3bdfSopenharmony_ci#define MEM_T3ESHMEM 3 /* T3E Shared Memory */ 95f08c3bdfSopenharmony_ci#define MEM_MMAP 4 /* mmap(2) */ 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci#define MEMF_PRIVATE 0001 98f08c3bdfSopenharmony_ci#define MEMF_AUTORESRV 0002 99f08c3bdfSopenharmony_ci#define MEMF_LOCAL 0004 100f08c3bdfSopenharmony_ci#define MEMF_SHARED 0010 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ci#define MEMF_FIXADDR 0100 103f08c3bdfSopenharmony_ci#define MEMF_ADDR 0200 104f08c3bdfSopenharmony_ci#define MEMF_AUTOGROW 0400 105f08c3bdfSopenharmony_ci#define MEMF_FILE 01000 /* regular file -- unlink on close */ 106f08c3bdfSopenharmony_ci#define MEMF_MPIN 010000 /* use mpin(2) to lock pages in memory */ 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_cistruct memalloc { 109f08c3bdfSopenharmony_ci int memtype; 110f08c3bdfSopenharmony_ci int flags; 111f08c3bdfSopenharmony_ci int nblks; 112f08c3bdfSopenharmony_ci char *name; 113f08c3bdfSopenharmony_ci void *space; /* memory address of allocated space */ 114f08c3bdfSopenharmony_ci int fd; /* FD open for mmaping */ 115f08c3bdfSopenharmony_ci int size; 116f08c3bdfSopenharmony_ci} Memalloc[NMEMALLOC]; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci/* 119f08c3bdfSopenharmony_ci * Structure for maintaining open file test descriptors. Used by 120f08c3bdfSopenharmony_ci * alloc_fd(). 121f08c3bdfSopenharmony_ci */ 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_cistruct fd_cache { 124f08c3bdfSopenharmony_ci char c_file[MAX_FNAME_LENGTH + 1]; 125f08c3bdfSopenharmony_ci int c_oflags; 126f08c3bdfSopenharmony_ci int c_fd; 127f08c3bdfSopenharmony_ci long c_rtc; 128f08c3bdfSopenharmony_ci#ifdef sgi 129f08c3bdfSopenharmony_ci int c_memalign; /* from F_DIOINFO */ 130f08c3bdfSopenharmony_ci int c_miniosz; 131f08c3bdfSopenharmony_ci int c_maxiosz; 132f08c3bdfSopenharmony_ci#endif 133f08c3bdfSopenharmony_ci#ifndef CRAY 134f08c3bdfSopenharmony_ci void *c_memaddr; /* mmapped address */ 135f08c3bdfSopenharmony_ci int c_memlen; /* length of above region */ 136f08c3bdfSopenharmony_ci#endif 137f08c3bdfSopenharmony_ci}; 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci/* 140f08c3bdfSopenharmony_ci * Name-To-Value map 141f08c3bdfSopenharmony_ci * Used to map cmdline arguments to values 142f08c3bdfSopenharmony_ci */ 143f08c3bdfSopenharmony_cistruct smap { 144f08c3bdfSopenharmony_ci char *string; 145f08c3bdfSopenharmony_ci int value; 146f08c3bdfSopenharmony_ci}; 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_cistruct aio_info { 149f08c3bdfSopenharmony_ci int busy; 150f08c3bdfSopenharmony_ci int id; 151f08c3bdfSopenharmony_ci int fd; 152f08c3bdfSopenharmony_ci int strategy; 153f08c3bdfSopenharmony_ci volatile int done; 154f08c3bdfSopenharmony_ci#ifdef CRAY 155f08c3bdfSopenharmony_ci struct iosw iosw; 156f08c3bdfSopenharmony_ci#endif 157f08c3bdfSopenharmony_ci#ifdef sgi 158f08c3bdfSopenharmony_ci aiocb_t aiocb; 159f08c3bdfSopenharmony_ci int aio_ret; /* from aio_return */ 160f08c3bdfSopenharmony_ci int aio_errno; /* from aio_error */ 161f08c3bdfSopenharmony_ci#endif 162f08c3bdfSopenharmony_ci int sig; 163f08c3bdfSopenharmony_ci int signalled; 164f08c3bdfSopenharmony_ci struct sigaction osa; 165f08c3bdfSopenharmony_ci}; 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_ci/* --------------------------------------------------------------------------- 168f08c3bdfSopenharmony_ci * 169f08c3bdfSopenharmony_ci * A new paradigm of doing the r/w system call where there is a "stub" 170f08c3bdfSopenharmony_ci * function that builds the info for the system call, then does the system 171f08c3bdfSopenharmony_ci * call; this is called by code that is common to all system calls and does 172f08c3bdfSopenharmony_ci * the syscall return checking, async I/O wait, iosw check, etc. 173f08c3bdfSopenharmony_ci * 174f08c3bdfSopenharmony_ci * Flags: 175f08c3bdfSopenharmony_ci * WRITE, ASYNC, SSD/SDS, 176f08c3bdfSopenharmony_ci * FILE_LOCK, WRITE_LOG, VERIFY_DATA, 177f08c3bdfSopenharmony_ci */ 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_cistruct status { 180f08c3bdfSopenharmony_ci int rval; /* syscall return */ 181f08c3bdfSopenharmony_ci int err; /* errno */ 182f08c3bdfSopenharmony_ci int *aioid; /* list of async I/O structures */ 183f08c3bdfSopenharmony_ci}; 184f08c3bdfSopenharmony_ci 185f08c3bdfSopenharmony_cistruct syscall_info { 186f08c3bdfSopenharmony_ci char *sy_name; 187f08c3bdfSopenharmony_ci int sy_type; 188f08c3bdfSopenharmony_ci struct status *(*sy_syscall) (); 189f08c3bdfSopenharmony_ci int (*sy_buffer) (); 190f08c3bdfSopenharmony_ci char *(*sy_format) (); 191f08c3bdfSopenharmony_ci int sy_flags; 192f08c3bdfSopenharmony_ci int sy_bits; 193f08c3bdfSopenharmony_ci}; 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci#define SY_WRITE 00001 196f08c3bdfSopenharmony_ci#define SY_ASYNC 00010 197f08c3bdfSopenharmony_ci#define SY_IOSW 00020 198f08c3bdfSopenharmony_ci#define SY_SDS 00100 199f08c3bdfSopenharmony_ci 200f08c3bdfSopenharmony_ci#ifndef O_SSD 201f08c3bdfSopenharmony_ci#define O_SSD 0 /* so code compiles on a CRAY2 */ 202f08c3bdfSopenharmony_ci#endif 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci#ifdef sgi 205f08c3bdfSopenharmony_ci#define UINT64_T uint64_t 206f08c3bdfSopenharmony_ci#else 207f08c3bdfSopenharmony_ci#define UINT64_T unsigned long 208f08c3bdfSopenharmony_ci#endif 209f08c3bdfSopenharmony_ci 210f08c3bdfSopenharmony_ci#ifndef O_PARALLEL 211f08c3bdfSopenharmony_ci#define O_PARALLEL 0 /* so O_PARALLEL may be used in expressions */ 212f08c3bdfSopenharmony_ci#endif 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci#define PPID_CHECK_INTERVAL 5 /* check ppid every <-- iterations */ 215f08c3bdfSopenharmony_ci#define MAX_AIO 256 /* maximum number of async I/O ops */ 216f08c3bdfSopenharmony_ci#ifdef _CRAYMPP 217f08c3bdfSopenharmony_ci#define MPP_BUMP 16 /* page un-alignment for MPP */ 218f08c3bdfSopenharmony_ci#else 219f08c3bdfSopenharmony_ci#define MPP_BUMP 0 220f08c3bdfSopenharmony_ci#endif 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci#define SYSERR strerror(errno) 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_ci/* 225f08c3bdfSopenharmony_ci * getopt() string of supported cmdline arguments. 226f08c3bdfSopenharmony_ci */ 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci#define OPTS "aC:d:ehm:n:kr:w:vU:V:M:N:" 229f08c3bdfSopenharmony_ci 230f08c3bdfSopenharmony_ci#define DEF_RELEASE_INTERVAL 0 231f08c3bdfSopenharmony_ci 232f08c3bdfSopenharmony_ci/* 233f08c3bdfSopenharmony_ci * Flags set in parse_cmdline() to indicate which options were selected 234f08c3bdfSopenharmony_ci * on the cmdline. 235f08c3bdfSopenharmony_ci */ 236f08c3bdfSopenharmony_ci 237f08c3bdfSopenharmony_ciint a_opt = 0; /* abort on data compare errors */ 238f08c3bdfSopenharmony_ciint e_opt = 0; /* exec() after fork()'ing */ 239f08c3bdfSopenharmony_ciint C_opt = 0; /* Data Check Type */ 240f08c3bdfSopenharmony_ciint d_opt = 0; /* delay between operations */ 241f08c3bdfSopenharmony_ciint k_opt = 0; /* lock file regions during writes */ 242f08c3bdfSopenharmony_ciint m_opt = 0; /* generate periodic messages */ 243f08c3bdfSopenharmony_ciint n_opt = 0; /* nprocs */ 244f08c3bdfSopenharmony_ciint r_opt = 0; /* resource release interval */ 245f08c3bdfSopenharmony_ciint w_opt = 0; /* file write log file */ 246f08c3bdfSopenharmony_ciint v_opt = 0; /* verify writes if set */ 247f08c3bdfSopenharmony_ciint U_opt = 0; /* upanic() on varios conditions */ 248f08c3bdfSopenharmony_ciint V_opt = 0; /* over-ride default validation fd type */ 249f08c3bdfSopenharmony_ciint M_opt = 0; /* data buffer allocation types */ 250f08c3bdfSopenharmony_cichar TagName[40]; /* name of this doio (see Monster) */ 251f08c3bdfSopenharmony_ci 252f08c3bdfSopenharmony_ci/* 253f08c3bdfSopenharmony_ci * Misc globals initialized in parse_cmdline() 254f08c3bdfSopenharmony_ci */ 255f08c3bdfSopenharmony_ci 256f08c3bdfSopenharmony_cichar *Prog = NULL; /* set up in parse_cmdline() */ 257f08c3bdfSopenharmony_ciint Upanic_Conditions; /* set by args to -U */ 258f08c3bdfSopenharmony_ciint Release_Interval; /* arg to -r */ 259f08c3bdfSopenharmony_ciint Nprocs; /* arg to -n */ 260f08c3bdfSopenharmony_cichar *Write_Log; /* arg to -w */ 261f08c3bdfSopenharmony_cichar *Infile; /* input file (defaults to stdin) */ 262f08c3bdfSopenharmony_ciint *Children; /* pids of child procs */ 263f08c3bdfSopenharmony_ciint Nchildren = 0; 264f08c3bdfSopenharmony_ciint Nsiblings = 0; /* tfork'ed siblings */ 265f08c3bdfSopenharmony_ciint Execd = 0; 266f08c3bdfSopenharmony_ciint Message_Interval = 0; 267f08c3bdfSopenharmony_ciint Npes = 0; /* non-zero if built as an mpp multi-pe app */ 268f08c3bdfSopenharmony_ciint Vpe = -1; /* Virtual pe number if Npes >= 0 */ 269f08c3bdfSopenharmony_ciint Reqno = 1; /* request # - used in some error messages */ 270f08c3bdfSopenharmony_ciint Reqskipcnt = 0; /* count of I/O requests that are skipped */ 271f08c3bdfSopenharmony_ciint Validation_Flags; 272f08c3bdfSopenharmony_cichar *(*Data_Check) (); /* function to call for data checking */ 273f08c3bdfSopenharmony_ciint (*Data_Fill) (); /* function to call for data filling */ 274f08c3bdfSopenharmony_ciint Nmemalloc = 0; /* number of memory allocation strategies */ 275f08c3bdfSopenharmony_ciint delayop = 0; /* delay between operations - type of delay */ 276f08c3bdfSopenharmony_ciint delaytime = 0; /* delay between operations - how long */ 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_cistruct wlog_file Wlog; 279f08c3bdfSopenharmony_ci 280f08c3bdfSopenharmony_ciint active_mmap_rw = 0; /* Indicates that mmapped I/O is occurring. */ 281f08c3bdfSopenharmony_ci /* Used by sigbus_action() in the child doio. */ 282f08c3bdfSopenharmony_ciint havesigint = 0; 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci#define SKIP_REQ -2 /* skip I/O request */ 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_ci/* 287f08c3bdfSopenharmony_ci * Global file descriptors 288f08c3bdfSopenharmony_ci */ 289f08c3bdfSopenharmony_ci 290f08c3bdfSopenharmony_ciint Wfd_Append; /* for appending to the write-log */ 291f08c3bdfSopenharmony_ciint Wfd_Random; /* for overlaying write-log entries */ 292f08c3bdfSopenharmony_ci 293f08c3bdfSopenharmony_ci#define FD_ALLOC_INCR 32 /* allocate this many fd_map structs */ 294f08c3bdfSopenharmony_ci /* at a time */ 295f08c3bdfSopenharmony_ci 296f08c3bdfSopenharmony_ci/* 297f08c3bdfSopenharmony_ci * Globals for tracking Sds and Core usage 298f08c3bdfSopenharmony_ci */ 299f08c3bdfSopenharmony_ci 300f08c3bdfSopenharmony_cichar *Memptr; /* ptr to core buffer space */ 301f08c3bdfSopenharmony_ciint Memsize; /* # bytes pointed to by Memptr */ 302f08c3bdfSopenharmony_ci /* maintained by alloc_mem() */ 303f08c3bdfSopenharmony_ci 304f08c3bdfSopenharmony_ciint Sdsptr; /* sds offset (always 0) */ 305f08c3bdfSopenharmony_ciint Sdssize; /* # bytes of allocated sds space */ 306f08c3bdfSopenharmony_ci /* Maintained by alloc_sds() */ 307f08c3bdfSopenharmony_cichar Host[16]; 308f08c3bdfSopenharmony_cichar Pattern[128]; 309f08c3bdfSopenharmony_ciint Pattern_Length; 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci/* 312f08c3bdfSopenharmony_ci * Signal handlers, and related globals 313f08c3bdfSopenharmony_ci */ 314f08c3bdfSopenharmony_ci 315f08c3bdfSopenharmony_cichar *syserrno(int err); 316f08c3bdfSopenharmony_civoid doio(void); 317f08c3bdfSopenharmony_civoid doio_delay(void); 318f08c3bdfSopenharmony_cichar *format_oflags(int oflags); 319f08c3bdfSopenharmony_cichar *format_strat(int strategy); 320f08c3bdfSopenharmony_cichar *format_rw(struct io_req *ioreq, int fd, void *buffer, 321f08c3bdfSopenharmony_ci int signo, char *pattern, void *iosw); 322f08c3bdfSopenharmony_ci#ifdef CRAY 323f08c3bdfSopenharmony_cichar *format_sds(struct io_req *ioreq, void *buffer, int sds char *pattern); 324f08c3bdfSopenharmony_ci#endif /* CRAY */ 325f08c3bdfSopenharmony_ci 326f08c3bdfSopenharmony_ciint do_read(struct io_req *req); 327f08c3bdfSopenharmony_ciint do_write(struct io_req *req); 328f08c3bdfSopenharmony_ciint lock_file_region(char *fname, int fd, int type, int start, int nbytes); 329f08c3bdfSopenharmony_ci 330f08c3bdfSopenharmony_ci#ifdef CRAY 331f08c3bdfSopenharmony_cichar *format_listio(struct io_req *ioreq, int lcmd, 332f08c3bdfSopenharmony_ci struct listreq *list, int nent, int fd, char *pattern); 333f08c3bdfSopenharmony_ci#endif /* CRAY */ 334f08c3bdfSopenharmony_ci 335f08c3bdfSopenharmony_ciint do_listio(struct io_req *req); 336f08c3bdfSopenharmony_ci 337f08c3bdfSopenharmony_ci#if defined(_CRAY1) || defined(CRAY) 338f08c3bdfSopenharmony_ciint do_ssdio(struct io_req *req); 339f08c3bdfSopenharmony_ci#endif /* defined(_CRAY1) || defined(CRAY) */ 340f08c3bdfSopenharmony_ci 341f08c3bdfSopenharmony_cichar *fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd); 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ci#ifdef CRAY 344f08c3bdfSopenharmony_cistruct status *sy_listio(struct io_req *req, struct syscall_info *sysc, 345f08c3bdfSopenharmony_ci int fd, char *addr); 346f08c3bdfSopenharmony_ciint listio_mem(struct io_req *req, int offset, int fmstride, 347f08c3bdfSopenharmony_ci int *min, int *max); 348f08c3bdfSopenharmony_cichar *fmt_listio(struct io_req *req, struct syscall_info *sy, 349f08c3bdfSopenharmony_ci int fd, char *addr); 350f08c3bdfSopenharmony_ci#endif /* CRAY */ 351f08c3bdfSopenharmony_ci 352f08c3bdfSopenharmony_ci#ifdef sgi 353f08c3bdfSopenharmony_cistruct status *sy_pread(struct io_req *req, struct syscall_info *sysc, 354f08c3bdfSopenharmony_ci int fd, char *addr); 355f08c3bdfSopenharmony_cistruct status *sy_pwrite(struct io_req *req, struct syscall_info *sysc, 356f08c3bdfSopenharmony_ci int fd, char *addr); 357f08c3bdfSopenharmony_cichar *fmt_pread(struct io_req *req, struct syscall_info *sy, 358f08c3bdfSopenharmony_ci int fd, char *addr); 359f08c3bdfSopenharmony_ci#endif /* sgi */ 360f08c3bdfSopenharmony_ci 361f08c3bdfSopenharmony_ci#ifndef CRAY 362f08c3bdfSopenharmony_cistruct status *sy_readv(struct io_req *req, struct syscall_info *sysc, 363f08c3bdfSopenharmony_ci int fd, char *addr); 364f08c3bdfSopenharmony_cistruct status *sy_writev(struct io_req *req, struct syscall_info *sysc, 365f08c3bdfSopenharmony_ci int fd, char *addr); 366f08c3bdfSopenharmony_cistruct status *sy_rwv(struct io_req *req, struct syscall_info *sysc, 367f08c3bdfSopenharmony_ci int fd, char *addr, int rw); 368f08c3bdfSopenharmony_cichar *fmt_readv(struct io_req *req, struct syscall_info *sy, 369f08c3bdfSopenharmony_ci int fd, char *addr); 370f08c3bdfSopenharmony_ci#endif /* !CRAY */ 371f08c3bdfSopenharmony_ci 372f08c3bdfSopenharmony_ci#ifdef sgi 373f08c3bdfSopenharmony_cistruct status *sy_aread(struct io_req *req, struct syscall_info *sysc, 374f08c3bdfSopenharmony_ci int fd, char *addr); 375f08c3bdfSopenharmony_cistruct status *sy_awrite(struct io_req *req, struct syscall_info *sysc, 376f08c3bdfSopenharmony_ci int fd, char *addr) 377f08c3bdfSopenharmony_cistruct status *sy_arw(struct io_req *req, struct syscall_info *sysc, 378f08c3bdfSopenharmony_ci int fd, char *addr, int rw); 379f08c3bdfSopenharmony_cichar *fmt_aread(struct io_req *req, struct syscall_info *sy, 380f08c3bdfSopenharmony_ci int fd, char *addr); 381f08c3bdfSopenharmony_ci#endif /* sgi */ 382f08c3bdfSopenharmony_ci 383f08c3bdfSopenharmony_ci#ifndef CRAY 384f08c3bdfSopenharmony_cistruct status *sy_mmread(struct io_req *req, struct syscall_info *sysc, 385f08c3bdfSopenharmony_ci int fd, char *addr); 386f08c3bdfSopenharmony_cistruct status *sy_mmwrite(struct io_req *req, struct syscall_info *sysc, 387f08c3bdfSopenharmony_ci int fd, char *addr); 388f08c3bdfSopenharmony_cistruct status *sy_mmrw(struct io_req *req, struct syscall_info *sysc, 389f08c3bdfSopenharmony_ci int fd, char *addr, int rw); 390f08c3bdfSopenharmony_cichar *fmt_mmrw(struct io_req *req, struct syscall_info *sy, int fd, char *addr); 391f08c3bdfSopenharmony_ci#endif /* !CRAY */ 392f08c3bdfSopenharmony_ci 393f08c3bdfSopenharmony_ciint do_rw(struct io_req *req); 394f08c3bdfSopenharmony_ci 395f08c3bdfSopenharmony_ci#ifdef sgi 396f08c3bdfSopenharmony_ciint do_fcntl(struct io_req *req); 397f08c3bdfSopenharmony_ci#endif /* sgi */ 398f08c3bdfSopenharmony_ci 399f08c3bdfSopenharmony_ci#ifndef CRAY 400f08c3bdfSopenharmony_ciint do_sync(struct io_req *req); 401f08c3bdfSopenharmony_ci#endif /* !CRAY */ 402f08c3bdfSopenharmony_ci 403f08c3bdfSopenharmony_ciint doio_pat_fill(char *addr, int mem_needed, char *Pattern, 404f08c3bdfSopenharmony_ci int Pattern_Length, int shift); 405f08c3bdfSopenharmony_cichar *doio_pat_check(char *buf, int offset, int length, 406f08c3bdfSopenharmony_ci char *pattern, int pattern_length, int patshift); 407f08c3bdfSopenharmony_cichar *check_file(char *file, int offset, int length, char *pattern, 408f08c3bdfSopenharmony_ci int pattern_length, int patshift, int fsa); 409f08c3bdfSopenharmony_ciint doio_fprintf(FILE * stream, char *format, ...); 410f08c3bdfSopenharmony_ciint alloc_mem(int nbytes); 411f08c3bdfSopenharmony_ci 412f08c3bdfSopenharmony_ci#if defined(_CRAY1) || defined(CRAY) 413f08c3bdfSopenharmony_ciint alloc_sds(int nbytes); 414f08c3bdfSopenharmony_ci#endif /* defined(_CRAY1) || defined(CRAY) */ 415f08c3bdfSopenharmony_ci 416f08c3bdfSopenharmony_ciint alloc_fd(char *file, int oflags); 417f08c3bdfSopenharmony_cistruct fd_cache *alloc_fdcache(char *file, int oflags); 418f08c3bdfSopenharmony_ci 419f08c3bdfSopenharmony_ci#ifdef sgi 420f08c3bdfSopenharmony_civoid signal_info(int sig, siginfo_t * info, void *v); 421f08c3bdfSopenharmony_civoid cleanup_handler(int sig, siginfo_t * info, void *v); 422f08c3bdfSopenharmony_civoid die_handler(int sig, siginfo_t * info, void *v); 423f08c3bdfSopenharmony_civoid sigbus_handler(int sig, siginfo_t * info, void *v); 424f08c3bdfSopenharmony_ci#else /* !sgi */ 425f08c3bdfSopenharmony_civoid cleanup_handler(int sig); 426f08c3bdfSopenharmony_civoid die_handler(int sig); 427f08c3bdfSopenharmony_ci 428f08c3bdfSopenharmony_ci#ifndef CRAY 429f08c3bdfSopenharmony_civoid sigbus_handler(int sig); 430f08c3bdfSopenharmony_ci#endif /* !CRAY */ 431f08c3bdfSopenharmony_ci#endif /* sgi */ 432f08c3bdfSopenharmony_ci 433f08c3bdfSopenharmony_civoid noop_handler(int sig); 434f08c3bdfSopenharmony_civoid sigint_handler(int sig); 435f08c3bdfSopenharmony_civoid aio_handler(int sig); 436f08c3bdfSopenharmony_civoid dump_aio(void); 437f08c3bdfSopenharmony_ci 438f08c3bdfSopenharmony_ci#ifdef sgi 439f08c3bdfSopenharmony_civoid cb_handler(sigval_t val); 440f08c3bdfSopenharmony_ci#endif /* sgi */ 441f08c3bdfSopenharmony_ci 442f08c3bdfSopenharmony_cistruct aio_info *aio_slot(int aio_id); 443f08c3bdfSopenharmony_ciint aio_register(int fd, int strategy, int sig); 444f08c3bdfSopenharmony_ciint aio_unregister(int aio_id); 445f08c3bdfSopenharmony_ci 446f08c3bdfSopenharmony_ci#ifndef __linux__ 447f08c3bdfSopenharmony_ciint aio_wait(int aio_id); 448f08c3bdfSopenharmony_ci#endif /* !__linux__ */ 449f08c3bdfSopenharmony_ci 450f08c3bdfSopenharmony_cichar *hms(time_t t); 451f08c3bdfSopenharmony_ciint aio_done(struct aio_info *ainfo); 452f08c3bdfSopenharmony_civoid doio_upanic(int mask); 453f08c3bdfSopenharmony_ciint parse_cmdline(int argc, char **argv, char *opts); 454f08c3bdfSopenharmony_ci 455f08c3bdfSopenharmony_ci#ifndef CRAY 456f08c3bdfSopenharmony_civoid parse_memalloc(char *arg); 457f08c3bdfSopenharmony_civoid dump_memalloc(void); 458f08c3bdfSopenharmony_ci#endif /* !CRAY */ 459f08c3bdfSopenharmony_ci 460f08c3bdfSopenharmony_civoid parse_delay(char *arg); 461f08c3bdfSopenharmony_ciint usage(FILE * stream); 462f08c3bdfSopenharmony_civoid help(FILE * stream); 463f08c3bdfSopenharmony_ci 464f08c3bdfSopenharmony_ci/* 465f08c3bdfSopenharmony_ci * Upanic conditions, and a map from symbolics to values 466f08c3bdfSopenharmony_ci */ 467f08c3bdfSopenharmony_ci 468f08c3bdfSopenharmony_ci#define U_CORRUPTION 0001 /* upanic on data corruption */ 469f08c3bdfSopenharmony_ci#define U_IOSW 0002 /* upanic on bad iosw */ 470f08c3bdfSopenharmony_ci#define U_RVAL 0004 /* upanic on bad rval */ 471f08c3bdfSopenharmony_ci 472f08c3bdfSopenharmony_ci#define U_ALL (U_CORRUPTION | U_IOSW | U_RVAL) 473f08c3bdfSopenharmony_ci 474f08c3bdfSopenharmony_cistruct smap Upanic_Args[] = { 475f08c3bdfSopenharmony_ci {"corruption", U_CORRUPTION}, 476f08c3bdfSopenharmony_ci {"iosw", U_IOSW}, 477f08c3bdfSopenharmony_ci {"rval", U_RVAL}, 478f08c3bdfSopenharmony_ci {"all", U_ALL}, 479f08c3bdfSopenharmony_ci {NULL, 0} 480f08c3bdfSopenharmony_ci}; 481f08c3bdfSopenharmony_ci 482f08c3bdfSopenharmony_cistruct aio_info Aio_Info[MAX_AIO]; 483f08c3bdfSopenharmony_ci 484f08c3bdfSopenharmony_ci/* -C data-fill/check type */ 485f08c3bdfSopenharmony_ci#define C_DEFAULT 1 486f08c3bdfSopenharmony_cistruct smap checkmap[] = { 487f08c3bdfSopenharmony_ci {"default", C_DEFAULT}, 488f08c3bdfSopenharmony_ci {NULL, 0}, 489f08c3bdfSopenharmony_ci}; 490f08c3bdfSopenharmony_ci 491f08c3bdfSopenharmony_ci/* -d option delay types */ 492f08c3bdfSopenharmony_ci#define DELAY_SELECT 1 493f08c3bdfSopenharmony_ci#define DELAY_SLEEP 2 494f08c3bdfSopenharmony_ci#define DELAY_SGINAP 3 495f08c3bdfSopenharmony_ci#define DELAY_ALARM 4 496f08c3bdfSopenharmony_ci#define DELAY_ITIMER 5 /* POSIX timer */ 497f08c3bdfSopenharmony_ci 498f08c3bdfSopenharmony_cistruct smap delaymap[] = { 499f08c3bdfSopenharmony_ci {"select", DELAY_SELECT}, 500f08c3bdfSopenharmony_ci {"sleep", DELAY_SLEEP}, 501f08c3bdfSopenharmony_ci#ifdef sgi 502f08c3bdfSopenharmony_ci {"sginap", DELAY_SGINAP}, 503f08c3bdfSopenharmony_ci#endif 504f08c3bdfSopenharmony_ci {"alarm", DELAY_ALARM}, 505f08c3bdfSopenharmony_ci {NULL, 0}, 506f08c3bdfSopenharmony_ci}; 507f08c3bdfSopenharmony_ci 508f08c3bdfSopenharmony_ci/****** 509f08c3bdfSopenharmony_ci* 510f08c3bdfSopenharmony_ci* strerror() does similar actions. 511f08c3bdfSopenharmony_ci 512f08c3bdfSopenharmony_cichar * 513f08c3bdfSopenharmony_cisyserrno(int err) 514f08c3bdfSopenharmony_ci{ 515f08c3bdfSopenharmony_ci static char sys_errno[10]; 516f08c3bdfSopenharmony_ci sprintf(sys_errno, "%d", errno); 517f08c3bdfSopenharmony_ci return(sys_errno); 518f08c3bdfSopenharmony_ci} 519f08c3bdfSopenharmony_ci 520f08c3bdfSopenharmony_ci******/ 521f08c3bdfSopenharmony_ci 522f08c3bdfSopenharmony_ciint main(int argc, char **argv) 523f08c3bdfSopenharmony_ci{ 524f08c3bdfSopenharmony_ci int i, pid, stat, ex_stat; 525f08c3bdfSopenharmony_ci#ifdef CRAY 526f08c3bdfSopenharmony_ci sigset_t omask; 527f08c3bdfSopenharmony_ci#elif defined(linux) 528f08c3bdfSopenharmony_ci sigset_t omask, block_mask; 529f08c3bdfSopenharmony_ci#else 530f08c3bdfSopenharmony_ci int omask; 531f08c3bdfSopenharmony_ci#endif 532f08c3bdfSopenharmony_ci struct sigaction sa; 533f08c3bdfSopenharmony_ci 534f08c3bdfSopenharmony_ci umask(0); /* force new file modes to known values */ 535f08c3bdfSopenharmony_ci#if _CRAYMPP 536f08c3bdfSopenharmony_ci Npes = sysconf(_SC_CRAY_NPES); /* must do this before parse_cmdline */ 537f08c3bdfSopenharmony_ci Vpe = sysconf(_SC_CRAY_VPE); 538f08c3bdfSopenharmony_ci#endif 539f08c3bdfSopenharmony_ci 540f08c3bdfSopenharmony_ci TagName[0] = '\0'; 541f08c3bdfSopenharmony_ci parse_cmdline(argc, argv, OPTS); 542f08c3bdfSopenharmony_ci 543f08c3bdfSopenharmony_ci random_range_seed(getpid()); /* initialize random number generator */ 544f08c3bdfSopenharmony_ci 545f08c3bdfSopenharmony_ci /* 546f08c3bdfSopenharmony_ci * If this is a re-exec of doio, jump directly into the doio function. 547f08c3bdfSopenharmony_ci */ 548f08c3bdfSopenharmony_ci 549f08c3bdfSopenharmony_ci if (Execd) { 550f08c3bdfSopenharmony_ci doio(); 551f08c3bdfSopenharmony_ci exit(E_SETUP); 552f08c3bdfSopenharmony_ci } 553f08c3bdfSopenharmony_ci 554f08c3bdfSopenharmony_ci /* 555f08c3bdfSopenharmony_ci * Stop on all but a few signals... 556f08c3bdfSopenharmony_ci */ 557f08c3bdfSopenharmony_ci sigemptyset(&sa.sa_mask); 558f08c3bdfSopenharmony_ci sa.sa_handler = sigint_handler; 559f08c3bdfSopenharmony_ci sa.sa_flags = SA_RESETHAND; /* sigint is ignored after the */ 560f08c3bdfSopenharmony_ci /* first time */ 561f08c3bdfSopenharmony_ci for (i = 1; i <= NSIG; i++) { 562f08c3bdfSopenharmony_ci switch (i) { 563f08c3bdfSopenharmony_ci#ifdef SIGRECOVERY 564f08c3bdfSopenharmony_ci case SIGRECOVERY: 565f08c3bdfSopenharmony_ci break; 566f08c3bdfSopenharmony_ci#endif 567f08c3bdfSopenharmony_ci#ifdef SIGCKPT 568f08c3bdfSopenharmony_ci case SIGCKPT: 569f08c3bdfSopenharmony_ci#endif 570f08c3bdfSopenharmony_ci#ifdef SIGRESTART 571f08c3bdfSopenharmony_ci case SIGRESTART: 572f08c3bdfSopenharmony_ci#endif 573f08c3bdfSopenharmony_ci case SIGTSTP: 574f08c3bdfSopenharmony_ci case SIGSTOP: 575f08c3bdfSopenharmony_ci case SIGCONT: 576f08c3bdfSopenharmony_ci case SIGCHLD: 577f08c3bdfSopenharmony_ci case SIGBUS: 578f08c3bdfSopenharmony_ci case SIGSEGV: 579f08c3bdfSopenharmony_ci case SIGQUIT: 580f08c3bdfSopenharmony_ci break; 581f08c3bdfSopenharmony_ci default: 582f08c3bdfSopenharmony_ci sigaction(i, &sa, NULL); 583f08c3bdfSopenharmony_ci } 584f08c3bdfSopenharmony_ci } 585f08c3bdfSopenharmony_ci 586f08c3bdfSopenharmony_ci /* 587f08c3bdfSopenharmony_ci * If we're logging write operations, make a dummy call to wlog_open 588f08c3bdfSopenharmony_ci * to initialize the write history file. This call must be done in 589f08c3bdfSopenharmony_ci * the parent, to ensure that the history file exists and/or has 590f08c3bdfSopenharmony_ci * been truncated before any children attempt to open it, as the doio 591f08c3bdfSopenharmony_ci * children are not allowed to truncate the file. 592f08c3bdfSopenharmony_ci */ 593f08c3bdfSopenharmony_ci 594f08c3bdfSopenharmony_ci if (w_opt) { 595f08c3bdfSopenharmony_ci strcpy(Wlog.w_file, Write_Log); 596f08c3bdfSopenharmony_ci 597f08c3bdfSopenharmony_ci if (wlog_open(&Wlog, 1, 0666) < 0) { 598f08c3bdfSopenharmony_ci doio_fprintf(stderr, 599f08c3bdfSopenharmony_ci "Could not create/truncate write log %s\n", 600f08c3bdfSopenharmony_ci Write_Log); 601f08c3bdfSopenharmony_ci exit(2); 602f08c3bdfSopenharmony_ci } 603f08c3bdfSopenharmony_ci 604f08c3bdfSopenharmony_ci wlog_close(&Wlog); 605f08c3bdfSopenharmony_ci } 606f08c3bdfSopenharmony_ci 607f08c3bdfSopenharmony_ci /* 608f08c3bdfSopenharmony_ci * Malloc space for the children pid array. Initialize all entries 609f08c3bdfSopenharmony_ci * to -1. 610f08c3bdfSopenharmony_ci */ 611f08c3bdfSopenharmony_ci 612f08c3bdfSopenharmony_ci Children = malloc(sizeof(int) * Nprocs); 613f08c3bdfSopenharmony_ci for (i = 0; i < Nprocs; i++) { 614f08c3bdfSopenharmony_ci Children[i] = -1; 615f08c3bdfSopenharmony_ci } 616f08c3bdfSopenharmony_ci 617f08c3bdfSopenharmony_ci sigemptyset(&block_mask); 618f08c3bdfSopenharmony_ci sigaddset(&block_mask, SIGCHLD); 619f08c3bdfSopenharmony_ci sigprocmask(SIG_BLOCK, &block_mask, &omask); 620f08c3bdfSopenharmony_ci 621f08c3bdfSopenharmony_ci /* 622f08c3bdfSopenharmony_ci * Fork Nprocs. This [parent] process is a watchdog, to notify the 623f08c3bdfSopenharmony_ci * invoker of procs which exit abnormally, and to make sure that all 624f08c3bdfSopenharmony_ci * child procs get cleaned up. If the -e option was used, we will also 625f08c3bdfSopenharmony_ci * re-exec. This is mostly for unicos/mk on mpp's, to ensure that not 626f08c3bdfSopenharmony_ci * all of the doio's don't end up in the same pe. 627f08c3bdfSopenharmony_ci * 628f08c3bdfSopenharmony_ci * Note - if Nprocs is 1, or this doio is a multi-pe app (Npes > 1), 629f08c3bdfSopenharmony_ci * jump directly to doio(). multi-pe apps can't fork(), and there is 630f08c3bdfSopenharmony_ci * no reason to fork() for 1 proc. 631f08c3bdfSopenharmony_ci */ 632f08c3bdfSopenharmony_ci 633f08c3bdfSopenharmony_ci if (Nprocs == 1 || Npes > 1) { 634f08c3bdfSopenharmony_ci doio(); 635f08c3bdfSopenharmony_ci exit(0); 636f08c3bdfSopenharmony_ci } else { 637f08c3bdfSopenharmony_ci for (i = 0; i < Nprocs; i++) { 638f08c3bdfSopenharmony_ci if ((pid = fork()) == -1) { 639f08c3bdfSopenharmony_ci doio_fprintf(stderr, 640f08c3bdfSopenharmony_ci "(parent) Could not fork %d children: %s (%d)\n", 641f08c3bdfSopenharmony_ci i + 1, SYSERR, errno); 642f08c3bdfSopenharmony_ci exit(E_SETUP); 643f08c3bdfSopenharmony_ci } 644f08c3bdfSopenharmony_ci 645f08c3bdfSopenharmony_ci Children[Nchildren] = pid; 646f08c3bdfSopenharmony_ci Nchildren++; 647f08c3bdfSopenharmony_ci 648f08c3bdfSopenharmony_ci if (pid == 0) { 649f08c3bdfSopenharmony_ci if (e_opt) { 650f08c3bdfSopenharmony_ci char *exec_path; 651f08c3bdfSopenharmony_ci 652f08c3bdfSopenharmony_ci exec_path = argv[0]; 653f08c3bdfSopenharmony_ci argv[0] = malloc(strlen(exec_path) + 2); 654f08c3bdfSopenharmony_ci sprintf(argv[0], "-%s", exec_path); 655f08c3bdfSopenharmony_ci 656f08c3bdfSopenharmony_ci execvp(exec_path, argv); 657f08c3bdfSopenharmony_ci doio_fprintf(stderr, 658f08c3bdfSopenharmony_ci "(parent) Could not execvp %s: %s (%d)\n", 659f08c3bdfSopenharmony_ci exec_path, SYSERR, errno); 660f08c3bdfSopenharmony_ci exit(E_SETUP); 661f08c3bdfSopenharmony_ci } else { 662f08c3bdfSopenharmony_ci doio(); 663f08c3bdfSopenharmony_ci exit(E_SETUP); 664f08c3bdfSopenharmony_ci } 665f08c3bdfSopenharmony_ci } 666f08c3bdfSopenharmony_ci } 667f08c3bdfSopenharmony_ci 668f08c3bdfSopenharmony_ci /* 669f08c3bdfSopenharmony_ci * Parent spins on wait(), until all children exit. 670f08c3bdfSopenharmony_ci */ 671f08c3bdfSopenharmony_ci 672f08c3bdfSopenharmony_ci ex_stat = E_NORMAL; 673f08c3bdfSopenharmony_ci 674f08c3bdfSopenharmony_ci while (Nprocs) { 675f08c3bdfSopenharmony_ci if ((pid = wait(&stat)) == -1) { 676f08c3bdfSopenharmony_ci if (errno == EINTR) 677f08c3bdfSopenharmony_ci continue; 678f08c3bdfSopenharmony_ci } 679f08c3bdfSopenharmony_ci 680f08c3bdfSopenharmony_ci for (i = 0; i < Nchildren; i++) 681f08c3bdfSopenharmony_ci if (Children[i] == pid) 682f08c3bdfSopenharmony_ci Children[i] = -1; 683f08c3bdfSopenharmony_ci 684f08c3bdfSopenharmony_ci Nprocs--; 685f08c3bdfSopenharmony_ci 686f08c3bdfSopenharmony_ci if (WIFEXITED(stat)) { 687f08c3bdfSopenharmony_ci switch (WEXITSTATUS(stat)) { 688f08c3bdfSopenharmony_ci case E_NORMAL: 689f08c3bdfSopenharmony_ci /* noop */ 690f08c3bdfSopenharmony_ci break; 691f08c3bdfSopenharmony_ci 692f08c3bdfSopenharmony_ci case E_INTERNAL: 693f08c3bdfSopenharmony_ci doio_fprintf(stderr, 694f08c3bdfSopenharmony_ci "(parent) pid %d exited because of an internal error\n", 695f08c3bdfSopenharmony_ci pid); 696f08c3bdfSopenharmony_ci ex_stat |= E_INTERNAL; 697f08c3bdfSopenharmony_ci break; 698f08c3bdfSopenharmony_ci 699f08c3bdfSopenharmony_ci case E_SETUP: 700f08c3bdfSopenharmony_ci doio_fprintf(stderr, 701f08c3bdfSopenharmony_ci "(parent) pid %d exited because of a setup error\n", 702f08c3bdfSopenharmony_ci pid); 703f08c3bdfSopenharmony_ci ex_stat |= E_SETUP; 704f08c3bdfSopenharmony_ci break; 705f08c3bdfSopenharmony_ci 706f08c3bdfSopenharmony_ci case E_COMPARE: 707f08c3bdfSopenharmony_ci doio_fprintf(stderr, 708f08c3bdfSopenharmony_ci "(parent) pid %d exited because of data compare errors\n", 709f08c3bdfSopenharmony_ci pid); 710f08c3bdfSopenharmony_ci 711f08c3bdfSopenharmony_ci ex_stat |= E_COMPARE; 712f08c3bdfSopenharmony_ci 713f08c3bdfSopenharmony_ci if (a_opt) 714f08c3bdfSopenharmony_ci kill(0, SIGINT); 715f08c3bdfSopenharmony_ci 716f08c3bdfSopenharmony_ci break; 717f08c3bdfSopenharmony_ci 718f08c3bdfSopenharmony_ci case E_USAGE: 719f08c3bdfSopenharmony_ci doio_fprintf(stderr, 720f08c3bdfSopenharmony_ci "(parent) pid %d exited because of a usage error\n", 721f08c3bdfSopenharmony_ci pid); 722f08c3bdfSopenharmony_ci 723f08c3bdfSopenharmony_ci ex_stat |= E_USAGE; 724f08c3bdfSopenharmony_ci break; 725f08c3bdfSopenharmony_ci 726f08c3bdfSopenharmony_ci default: 727f08c3bdfSopenharmony_ci doio_fprintf(stderr, 728f08c3bdfSopenharmony_ci "(parent) pid %d exited with unknown status %d\n", 729f08c3bdfSopenharmony_ci pid, WEXITSTATUS(stat)); 730f08c3bdfSopenharmony_ci ex_stat |= E_INTERNAL; 731f08c3bdfSopenharmony_ci break; 732f08c3bdfSopenharmony_ci } 733f08c3bdfSopenharmony_ci } else if (WIFSIGNALED(stat) 734f08c3bdfSopenharmony_ci && WTERMSIG(stat) != SIGINT) { 735f08c3bdfSopenharmony_ci doio_fprintf(stderr, 736f08c3bdfSopenharmony_ci "(parent) pid %d terminated by signal %d\n", 737f08c3bdfSopenharmony_ci pid, WTERMSIG(stat)); 738f08c3bdfSopenharmony_ci 739f08c3bdfSopenharmony_ci ex_stat |= E_SIGNAL; 740f08c3bdfSopenharmony_ci } 741f08c3bdfSopenharmony_ci 742f08c3bdfSopenharmony_ci fflush(NULL); 743f08c3bdfSopenharmony_ci } 744f08c3bdfSopenharmony_ci } 745f08c3bdfSopenharmony_ci 746f08c3bdfSopenharmony_ci exit(ex_stat); 747f08c3bdfSopenharmony_ci 748f08c3bdfSopenharmony_ci} /* main */ 749f08c3bdfSopenharmony_ci 750f08c3bdfSopenharmony_ci/* 751f08c3bdfSopenharmony_ci * main doio function. Each doio child starts here, and never returns. 752f08c3bdfSopenharmony_ci */ 753f08c3bdfSopenharmony_ci 754f08c3bdfSopenharmony_civoid doio(void) 755f08c3bdfSopenharmony_ci{ 756f08c3bdfSopenharmony_ci int rval, i, infd, nbytes; 757f08c3bdfSopenharmony_ci char *cp; 758f08c3bdfSopenharmony_ci struct io_req ioreq; 759f08c3bdfSopenharmony_ci struct sigaction sa, def_action, ignore_action, exit_action; 760f08c3bdfSopenharmony_ci#ifndef CRAY 761f08c3bdfSopenharmony_ci struct sigaction sigbus_action; 762f08c3bdfSopenharmony_ci#endif 763f08c3bdfSopenharmony_ci 764f08c3bdfSopenharmony_ci Memsize = Sdssize = 0; 765f08c3bdfSopenharmony_ci 766f08c3bdfSopenharmony_ci /* 767f08c3bdfSopenharmony_ci * Initialize the Pattern - write-type syscalls will replace Pattern[1] 768f08c3bdfSopenharmony_ci * with the pattern passed in the request. Make sure that 769f08c3bdfSopenharmony_ci * strlen(Pattern) is not mod 16 so that out of order words will be 770f08c3bdfSopenharmony_ci * detected. 771f08c3bdfSopenharmony_ci */ 772f08c3bdfSopenharmony_ci 773f08c3bdfSopenharmony_ci gethostname(Host, sizeof(Host)); 774f08c3bdfSopenharmony_ci if ((cp = strchr(Host, '.')) != NULL) 775f08c3bdfSopenharmony_ci *cp = '\0'; 776f08c3bdfSopenharmony_ci 777f08c3bdfSopenharmony_ci Pattern_Length = sprintf(Pattern, "-:%d:%s:%s*", getpid(), Host, Prog); 778f08c3bdfSopenharmony_ci 779f08c3bdfSopenharmony_ci if (!(Pattern_Length % 16)) { 780f08c3bdfSopenharmony_ci Pattern_Length = sprintf(Pattern, "-:%d:%s:%s**", 781f08c3bdfSopenharmony_ci getpid(), Host, Prog); 782f08c3bdfSopenharmony_ci } 783f08c3bdfSopenharmony_ci 784f08c3bdfSopenharmony_ci /* 785f08c3bdfSopenharmony_ci * Open a couple of descriptors for the write-log file. One descriptor 786f08c3bdfSopenharmony_ci * is for appending, one for random access. Write logging is done for 787f08c3bdfSopenharmony_ci * file corruption detection. The program doio_check is capable of 788f08c3bdfSopenharmony_ci * doing corruption detection based on a doio write-log. 789f08c3bdfSopenharmony_ci */ 790f08c3bdfSopenharmony_ci 791f08c3bdfSopenharmony_ci if (w_opt) { 792f08c3bdfSopenharmony_ci 793f08c3bdfSopenharmony_ci strcpy(Wlog.w_file, Write_Log); 794f08c3bdfSopenharmony_ci 795f08c3bdfSopenharmony_ci if (wlog_open(&Wlog, 0, 0666) == -1) { 796f08c3bdfSopenharmony_ci doio_fprintf(stderr, 797f08c3bdfSopenharmony_ci "Could not open write log file (%s): wlog_open() failed\n", 798f08c3bdfSopenharmony_ci Write_Log); 799f08c3bdfSopenharmony_ci exit(E_SETUP); 800f08c3bdfSopenharmony_ci } 801f08c3bdfSopenharmony_ci } 802f08c3bdfSopenharmony_ci 803f08c3bdfSopenharmony_ci /* 804f08c3bdfSopenharmony_ci * Open the input stream - either a file or stdin 805f08c3bdfSopenharmony_ci */ 806f08c3bdfSopenharmony_ci 807f08c3bdfSopenharmony_ci if (Infile == NULL) { 808f08c3bdfSopenharmony_ci infd = 0; 809f08c3bdfSopenharmony_ci } else { 810f08c3bdfSopenharmony_ci if ((infd = open(Infile, O_RDWR)) == -1) { 811f08c3bdfSopenharmony_ci doio_fprintf(stderr, 812f08c3bdfSopenharmony_ci "Could not open input file (%s): %s (%d)\n", 813f08c3bdfSopenharmony_ci Infile, SYSERR, errno); 814f08c3bdfSopenharmony_ci exit(E_SETUP); 815f08c3bdfSopenharmony_ci } 816f08c3bdfSopenharmony_ci } 817f08c3bdfSopenharmony_ci 818f08c3bdfSopenharmony_ci /* 819f08c3bdfSopenharmony_ci * Define a set of signals that should never be masked. Receipt of 820f08c3bdfSopenharmony_ci * these signals generally indicates a programming error, and we want 821f08c3bdfSopenharmony_ci * a corefile at the point of error. We put SIGQUIT in this list so 822f08c3bdfSopenharmony_ci * that ^\ will force a user core dump. 823f08c3bdfSopenharmony_ci * 824f08c3bdfSopenharmony_ci * Note: the handler for these should be SIG_DFL, all of them 825f08c3bdfSopenharmony_ci * produce a corefile as the default action. 826f08c3bdfSopenharmony_ci */ 827f08c3bdfSopenharmony_ci 828f08c3bdfSopenharmony_ci ignore_action.sa_handler = SIG_IGN; 829f08c3bdfSopenharmony_ci ignore_action.sa_flags = 0; 830f08c3bdfSopenharmony_ci sigemptyset(&ignore_action.sa_mask); 831f08c3bdfSopenharmony_ci 832f08c3bdfSopenharmony_ci def_action.sa_handler = SIG_DFL; 833f08c3bdfSopenharmony_ci def_action.sa_flags = 0; 834f08c3bdfSopenharmony_ci sigemptyset(&def_action.sa_mask); 835f08c3bdfSopenharmony_ci 836f08c3bdfSopenharmony_ci#ifdef sgi 837f08c3bdfSopenharmony_ci exit_action.sa_sigaction = cleanup_handler; 838f08c3bdfSopenharmony_ci exit_action.sa_flags = SA_SIGINFO; 839f08c3bdfSopenharmony_ci sigemptyset(&exit_action.sa_mask); 840f08c3bdfSopenharmony_ci 841f08c3bdfSopenharmony_ci sa.sa_sigaction = die_handler; 842f08c3bdfSopenharmony_ci sa.sa_flags = SA_SIGINFO; 843f08c3bdfSopenharmony_ci sigemptyset(&sa.sa_mask); 844f08c3bdfSopenharmony_ci 845f08c3bdfSopenharmony_ci sigbus_action.sa_sigaction = sigbus_handler; 846f08c3bdfSopenharmony_ci sigbus_action.sa_flags = SA_SIGINFO; 847f08c3bdfSopenharmony_ci sigemptyset(&sigbus_action.sa_mask); 848f08c3bdfSopenharmony_ci#else 849f08c3bdfSopenharmony_ci exit_action.sa_handler = cleanup_handler; 850f08c3bdfSopenharmony_ci exit_action.sa_flags = 0; 851f08c3bdfSopenharmony_ci sigemptyset(&exit_action.sa_mask); 852f08c3bdfSopenharmony_ci 853f08c3bdfSopenharmony_ci sa.sa_handler = die_handler; 854f08c3bdfSopenharmony_ci sa.sa_flags = 0; 855f08c3bdfSopenharmony_ci sigemptyset(&sa.sa_mask); 856f08c3bdfSopenharmony_ci 857f08c3bdfSopenharmony_ci#ifndef CRAY 858f08c3bdfSopenharmony_ci sigbus_action.sa_handler = sigbus_handler; 859f08c3bdfSopenharmony_ci sigbus_action.sa_flags = 0; 860f08c3bdfSopenharmony_ci sigemptyset(&sigbus_action.sa_mask); 861f08c3bdfSopenharmony_ci#endif 862f08c3bdfSopenharmony_ci#endif 863f08c3bdfSopenharmony_ci 864f08c3bdfSopenharmony_ci for (i = 1; i <= NSIG; i++) { 865f08c3bdfSopenharmony_ci switch (i) { 866f08c3bdfSopenharmony_ci /* Signals to terminate program on */ 867f08c3bdfSopenharmony_ci case SIGINT: 868f08c3bdfSopenharmony_ci sigaction(i, &exit_action, NULL); 869f08c3bdfSopenharmony_ci break; 870f08c3bdfSopenharmony_ci 871f08c3bdfSopenharmony_ci#ifndef CRAY 872f08c3bdfSopenharmony_ci /* This depends on active_mmap_rw */ 873f08c3bdfSopenharmony_ci case SIGBUS: 874f08c3bdfSopenharmony_ci sigaction(i, &sigbus_action, NULL); 875f08c3bdfSopenharmony_ci break; 876f08c3bdfSopenharmony_ci#endif 877f08c3bdfSopenharmony_ci 878f08c3bdfSopenharmony_ci /* Signals to Ignore... */ 879f08c3bdfSopenharmony_ci case SIGSTOP: 880f08c3bdfSopenharmony_ci case SIGCONT: 881f08c3bdfSopenharmony_ci#ifdef SIGRECOVERY 882f08c3bdfSopenharmony_ci case SIGRECOVERY: 883f08c3bdfSopenharmony_ci#endif 884f08c3bdfSopenharmony_ci sigaction(i, &ignore_action, NULL); 885f08c3bdfSopenharmony_ci break; 886f08c3bdfSopenharmony_ci 887f08c3bdfSopenharmony_ci /* Signals to trap & report & die */ 888f08c3bdfSopenharmony_ci /*case SIGTRAP: */ 889f08c3bdfSopenharmony_ci /*case SIGABRT: */ 890f08c3bdfSopenharmony_ci#ifdef SIGERR /* cray only signals */ 891f08c3bdfSopenharmony_ci case SIGERR: 892f08c3bdfSopenharmony_ci case SIGBUFIO: 893f08c3bdfSopenharmony_ci case SIGINFO: 894f08c3bdfSopenharmony_ci#endif 895f08c3bdfSopenharmony_ci /*case SIGFPE: */ 896f08c3bdfSopenharmony_ci case SIGURG: 897f08c3bdfSopenharmony_ci case SIGHUP: 898f08c3bdfSopenharmony_ci case SIGTERM: 899f08c3bdfSopenharmony_ci case SIGPIPE: 900f08c3bdfSopenharmony_ci case SIGIO: 901f08c3bdfSopenharmony_ci case SIGUSR1: 902f08c3bdfSopenharmony_ci case SIGUSR2: 903f08c3bdfSopenharmony_ci sigaction(i, &sa, NULL); 904f08c3bdfSopenharmony_ci break; 905f08c3bdfSopenharmony_ci 906f08c3bdfSopenharmony_ci /* Default Action for all other signals */ 907f08c3bdfSopenharmony_ci default: 908f08c3bdfSopenharmony_ci sigaction(i, &def_action, NULL); 909f08c3bdfSopenharmony_ci break; 910f08c3bdfSopenharmony_ci } 911f08c3bdfSopenharmony_ci } 912f08c3bdfSopenharmony_ci 913f08c3bdfSopenharmony_ci /* 914f08c3bdfSopenharmony_ci * Main loop - each doio proc does this until the read returns eof (0). 915f08c3bdfSopenharmony_ci * Call the appropriate io function based on the request type. 916f08c3bdfSopenharmony_ci */ 917f08c3bdfSopenharmony_ci 918f08c3bdfSopenharmony_ci while ((nbytes = read(infd, (char *)&ioreq, sizeof(ioreq)))) { 919f08c3bdfSopenharmony_ci 920f08c3bdfSopenharmony_ci /* 921f08c3bdfSopenharmony_ci * Periodically check our ppid. If it is 1, the child exits to 922f08c3bdfSopenharmony_ci * help clean up in the case that the main doio process was 923f08c3bdfSopenharmony_ci * killed. 924f08c3bdfSopenharmony_ci */ 925f08c3bdfSopenharmony_ci 926f08c3bdfSopenharmony_ci if (Reqno && ((Reqno % PPID_CHECK_INTERVAL) == 0)) { 927f08c3bdfSopenharmony_ci if (getppid() == 1) { 928f08c3bdfSopenharmony_ci doio_fprintf(stderr, 929f08c3bdfSopenharmony_ci "Parent doio process has exited\n"); 930f08c3bdfSopenharmony_ci alloc_mem(-1); 931f08c3bdfSopenharmony_ci exit(E_SETUP); 932f08c3bdfSopenharmony_ci } 933f08c3bdfSopenharmony_ci } 934f08c3bdfSopenharmony_ci 935f08c3bdfSopenharmony_ci if (nbytes == -1) { 936f08c3bdfSopenharmony_ci doio_fprintf(stderr, 937f08c3bdfSopenharmony_ci "read of %d bytes from input failed: %s (%d)\n", 938f08c3bdfSopenharmony_ci sizeof(ioreq), SYSERR, errno); 939f08c3bdfSopenharmony_ci alloc_mem(-1); 940f08c3bdfSopenharmony_ci exit(E_SETUP); 941f08c3bdfSopenharmony_ci } 942f08c3bdfSopenharmony_ci 943f08c3bdfSopenharmony_ci if (nbytes != sizeof(ioreq)) { 944f08c3bdfSopenharmony_ci doio_fprintf(stderr, 945f08c3bdfSopenharmony_ci "read wrong # bytes from input stream, expected %d, got %d\n", 946f08c3bdfSopenharmony_ci sizeof(ioreq), nbytes); 947f08c3bdfSopenharmony_ci alloc_mem(-1); 948f08c3bdfSopenharmony_ci exit(E_SETUP); 949f08c3bdfSopenharmony_ci } 950f08c3bdfSopenharmony_ci 951f08c3bdfSopenharmony_ci if (ioreq.r_magic != DOIO_MAGIC) { 952f08c3bdfSopenharmony_ci doio_fprintf(stderr, 953f08c3bdfSopenharmony_ci "got a bad magic # from input stream. Expected 0%o, got 0%o\n", 954f08c3bdfSopenharmony_ci DOIO_MAGIC, ioreq.r_magic); 955f08c3bdfSopenharmony_ci alloc_mem(-1); 956f08c3bdfSopenharmony_ci exit(E_SETUP); 957f08c3bdfSopenharmony_ci } 958f08c3bdfSopenharmony_ci 959f08c3bdfSopenharmony_ci /* 960f08c3bdfSopenharmony_ci * If we're on a Release_Interval multiple, relase all ssd and 961f08c3bdfSopenharmony_ci * core space, and close all fd's in Fd_Map[]. 962f08c3bdfSopenharmony_ci */ 963f08c3bdfSopenharmony_ci 964f08c3bdfSopenharmony_ci if (Reqno && Release_Interval && !(Reqno % Release_Interval)) { 965f08c3bdfSopenharmony_ci if (Memsize) { 966f08c3bdfSopenharmony_ci#ifdef NOTDEF 967f08c3bdfSopenharmony_ci sbrk(-1 * Memsize); 968f08c3bdfSopenharmony_ci#else 969f08c3bdfSopenharmony_ci alloc_mem(-1); 970f08c3bdfSopenharmony_ci#endif 971f08c3bdfSopenharmony_ci } 972f08c3bdfSopenharmony_ci#ifdef _CRAY1 973f08c3bdfSopenharmony_ci if (Sdssize) { 974f08c3bdfSopenharmony_ci ssbreak(-1 * btoc(Sdssize)); 975f08c3bdfSopenharmony_ci Sdsptr = 0; 976f08c3bdfSopenharmony_ci Sdssize = 0; 977f08c3bdfSopenharmony_ci } 978f08c3bdfSopenharmony_ci#endif /* _CRAY1 */ 979f08c3bdfSopenharmony_ci 980f08c3bdfSopenharmony_ci alloc_fd(NULL, 0); 981f08c3bdfSopenharmony_ci } 982f08c3bdfSopenharmony_ci 983f08c3bdfSopenharmony_ci switch (ioreq.r_type) { 984f08c3bdfSopenharmony_ci case READ: 985f08c3bdfSopenharmony_ci case READA: 986f08c3bdfSopenharmony_ci rval = do_read(&ioreq); 987f08c3bdfSopenharmony_ci break; 988f08c3bdfSopenharmony_ci 989f08c3bdfSopenharmony_ci case WRITE: 990f08c3bdfSopenharmony_ci case WRITEA: 991f08c3bdfSopenharmony_ci rval = do_write(&ioreq); 992f08c3bdfSopenharmony_ci break; 993f08c3bdfSopenharmony_ci 994f08c3bdfSopenharmony_ci case READV: 995f08c3bdfSopenharmony_ci case AREAD: 996f08c3bdfSopenharmony_ci case PREAD: 997f08c3bdfSopenharmony_ci case LREAD: 998f08c3bdfSopenharmony_ci case LREADA: 999f08c3bdfSopenharmony_ci case LSREAD: 1000f08c3bdfSopenharmony_ci case LSREADA: 1001f08c3bdfSopenharmony_ci case WRITEV: 1002f08c3bdfSopenharmony_ci case AWRITE: 1003f08c3bdfSopenharmony_ci case PWRITE: 1004f08c3bdfSopenharmony_ci case MMAPR: 1005f08c3bdfSopenharmony_ci case MMAPW: 1006f08c3bdfSopenharmony_ci case LWRITE: 1007f08c3bdfSopenharmony_ci case LWRITEA: 1008f08c3bdfSopenharmony_ci case LSWRITE: 1009f08c3bdfSopenharmony_ci case LSWRITEA: 1010f08c3bdfSopenharmony_ci case LEREAD: 1011f08c3bdfSopenharmony_ci case LEREADA: 1012f08c3bdfSopenharmony_ci case LEWRITE: 1013f08c3bdfSopenharmony_ci case LEWRITEA: 1014f08c3bdfSopenharmony_ci rval = do_rw(&ioreq); 1015f08c3bdfSopenharmony_ci break; 1016f08c3bdfSopenharmony_ci 1017f08c3bdfSopenharmony_ci#ifdef CRAY 1018f08c3bdfSopenharmony_ci case SSREAD: 1019f08c3bdfSopenharmony_ci case SSWRITE: 1020f08c3bdfSopenharmony_ci rval = do_ssdio(&ioreq); 1021f08c3bdfSopenharmony_ci break; 1022f08c3bdfSopenharmony_ci 1023f08c3bdfSopenharmony_ci case LISTIO: 1024f08c3bdfSopenharmony_ci rval = do_listio(&ioreq); 1025f08c3bdfSopenharmony_ci break; 1026f08c3bdfSopenharmony_ci#endif 1027f08c3bdfSopenharmony_ci 1028f08c3bdfSopenharmony_ci#ifdef sgi 1029f08c3bdfSopenharmony_ci case RESVSP: 1030f08c3bdfSopenharmony_ci case UNRESVSP: 1031f08c3bdfSopenharmony_ci#ifdef F_FSYNC 1032f08c3bdfSopenharmony_ci case DFFSYNC: 1033f08c3bdfSopenharmony_ci#endif 1034f08c3bdfSopenharmony_ci rval = do_fcntl(&ioreq); 1035f08c3bdfSopenharmony_ci break; 1036f08c3bdfSopenharmony_ci#endif /* sgi */ 1037f08c3bdfSopenharmony_ci 1038f08c3bdfSopenharmony_ci#ifndef CRAY 1039f08c3bdfSopenharmony_ci case FSYNC2: 1040f08c3bdfSopenharmony_ci case FDATASYNC: 1041f08c3bdfSopenharmony_ci rval = do_sync(&ioreq); 1042f08c3bdfSopenharmony_ci break; 1043f08c3bdfSopenharmony_ci#endif 1044f08c3bdfSopenharmony_ci default: 1045f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1046f08c3bdfSopenharmony_ci "Don't know how to handle io request type %d\n", 1047f08c3bdfSopenharmony_ci ioreq.r_type); 1048f08c3bdfSopenharmony_ci alloc_mem(-1); 1049f08c3bdfSopenharmony_ci exit(E_SETUP); 1050f08c3bdfSopenharmony_ci } 1051f08c3bdfSopenharmony_ci 1052f08c3bdfSopenharmony_ci if (rval == SKIP_REQ) { 1053f08c3bdfSopenharmony_ci Reqskipcnt++; 1054f08c3bdfSopenharmony_ci } else if (rval != 0) { 1055f08c3bdfSopenharmony_ci alloc_mem(-1); 1056f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1057f08c3bdfSopenharmony_ci "doio(): operation %d returned != 0\n", 1058f08c3bdfSopenharmony_ci ioreq.r_type); 1059f08c3bdfSopenharmony_ci exit(E_SETUP); 1060f08c3bdfSopenharmony_ci } 1061f08c3bdfSopenharmony_ci 1062f08c3bdfSopenharmony_ci if (Message_Interval && Reqno % Message_Interval == 0) { 1063f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1064f08c3bdfSopenharmony_ci "Info: %d requests done (%d skipped) by this process\n", 1065f08c3bdfSopenharmony_ci Reqno, Reqskipcnt); 1066f08c3bdfSopenharmony_ci } 1067f08c3bdfSopenharmony_ci 1068f08c3bdfSopenharmony_ci Reqno++; 1069f08c3bdfSopenharmony_ci 1070f08c3bdfSopenharmony_ci if (delayop != 0) 1071f08c3bdfSopenharmony_ci doio_delay(); 1072f08c3bdfSopenharmony_ci } 1073f08c3bdfSopenharmony_ci 1074f08c3bdfSopenharmony_ci /* 1075f08c3bdfSopenharmony_ci * Child exits normally 1076f08c3bdfSopenharmony_ci */ 1077f08c3bdfSopenharmony_ci alloc_mem(-1); 1078f08c3bdfSopenharmony_ci exit(E_NORMAL); 1079f08c3bdfSopenharmony_ci 1080f08c3bdfSopenharmony_ci} /* doio */ 1081f08c3bdfSopenharmony_ci 1082f08c3bdfSopenharmony_civoid doio_delay(void) 1083f08c3bdfSopenharmony_ci{ 1084f08c3bdfSopenharmony_ci struct timeval tv_delay; 1085f08c3bdfSopenharmony_ci struct sigaction sa_al, sa_old; 1086f08c3bdfSopenharmony_ci sigset_t al_mask; 1087f08c3bdfSopenharmony_ci 1088f08c3bdfSopenharmony_ci switch (delayop) { 1089f08c3bdfSopenharmony_ci case DELAY_SELECT: 1090f08c3bdfSopenharmony_ci tv_delay.tv_sec = delaytime / 1000000; 1091f08c3bdfSopenharmony_ci tv_delay.tv_usec = delaytime % 1000000; 1092f08c3bdfSopenharmony_ci /*doio_fprintf(stdout, "delay_select: %d %d\n", 1093f08c3bdfSopenharmony_ci tv_delay.tv_sec, tv_delay.tv_usec); */ 1094f08c3bdfSopenharmony_ci select(0, NULL, NULL, NULL, &tv_delay); 1095f08c3bdfSopenharmony_ci break; 1096f08c3bdfSopenharmony_ci 1097f08c3bdfSopenharmony_ci case DELAY_SLEEP: 1098f08c3bdfSopenharmony_ci sleep(delaytime); 1099f08c3bdfSopenharmony_ci break; 1100f08c3bdfSopenharmony_ci 1101f08c3bdfSopenharmony_ci#ifdef sgi 1102f08c3bdfSopenharmony_ci case DELAY_SGINAP: 1103f08c3bdfSopenharmony_ci sginap(delaytime); 1104f08c3bdfSopenharmony_ci break; 1105f08c3bdfSopenharmony_ci#endif 1106f08c3bdfSopenharmony_ci 1107f08c3bdfSopenharmony_ci case DELAY_ALARM: 1108f08c3bdfSopenharmony_ci sa_al.sa_flags = 0; 1109f08c3bdfSopenharmony_ci sa_al.sa_handler = noop_handler; 1110f08c3bdfSopenharmony_ci sigemptyset(&sa_al.sa_mask); 1111f08c3bdfSopenharmony_ci sigaction(SIGALRM, &sa_al, &sa_old); 1112f08c3bdfSopenharmony_ci sigemptyset(&al_mask); 1113f08c3bdfSopenharmony_ci alarm(delaytime); 1114f08c3bdfSopenharmony_ci sigsuspend(&al_mask); 1115f08c3bdfSopenharmony_ci sigaction(SIGALRM, &sa_old, 0); 1116f08c3bdfSopenharmony_ci break; 1117f08c3bdfSopenharmony_ci } 1118f08c3bdfSopenharmony_ci} 1119f08c3bdfSopenharmony_ci 1120f08c3bdfSopenharmony_ci/* 1121f08c3bdfSopenharmony_ci * Format IO requests, returning a pointer to the formatted text. 1122f08c3bdfSopenharmony_ci * 1123f08c3bdfSopenharmony_ci * format_strat - formats the async i/o completion strategy 1124f08c3bdfSopenharmony_ci * format_rw - formats a read[a]/write[a] request 1125f08c3bdfSopenharmony_ci * format_sds - formats a ssread/sswrite request 1126f08c3bdfSopenharmony_ci * format_listio- formats a listio request 1127f08c3bdfSopenharmony_ci * 1128f08c3bdfSopenharmony_ci * ioreq is the doio io request structure. 1129f08c3bdfSopenharmony_ci */ 1130f08c3bdfSopenharmony_ci 1131f08c3bdfSopenharmony_cistruct smap sysnames[] = { 1132f08c3bdfSopenharmony_ci {"READ", READ}, 1133f08c3bdfSopenharmony_ci {"WRITE", WRITE}, 1134f08c3bdfSopenharmony_ci {"READA", READA}, 1135f08c3bdfSopenharmony_ci {"WRITEA", WRITEA}, 1136f08c3bdfSopenharmony_ci {"SSREAD", SSREAD}, 1137f08c3bdfSopenharmony_ci {"SSWRITE", SSWRITE}, 1138f08c3bdfSopenharmony_ci {"LISTIO", LISTIO}, 1139f08c3bdfSopenharmony_ci {"LREAD", LREAD}, 1140f08c3bdfSopenharmony_ci {"LREADA", LREADA}, 1141f08c3bdfSopenharmony_ci {"LWRITE", LWRITE}, 1142f08c3bdfSopenharmony_ci {"LWRITEA", LWRITEA}, 1143f08c3bdfSopenharmony_ci {"LSREAD", LSREAD}, 1144f08c3bdfSopenharmony_ci {"LSREADA", LSREADA}, 1145f08c3bdfSopenharmony_ci {"LSWRITE", LSWRITE}, 1146f08c3bdfSopenharmony_ci {"LSWRITEA", LSWRITEA}, 1147f08c3bdfSopenharmony_ci 1148f08c3bdfSopenharmony_ci /* Irix System Calls */ 1149f08c3bdfSopenharmony_ci {"PREAD", PREAD}, 1150f08c3bdfSopenharmony_ci {"PWRITE", PWRITE}, 1151f08c3bdfSopenharmony_ci {"AREAD", AREAD}, 1152f08c3bdfSopenharmony_ci {"AWRITE", AWRITE}, 1153f08c3bdfSopenharmony_ci {"LLREAD", LLREAD}, 1154f08c3bdfSopenharmony_ci {"LLAREAD", LLAREAD}, 1155f08c3bdfSopenharmony_ci {"LLWRITE", LLWRITE}, 1156f08c3bdfSopenharmony_ci {"LLAWRITE", LLAWRITE}, 1157f08c3bdfSopenharmony_ci {"RESVSP", RESVSP}, 1158f08c3bdfSopenharmony_ci {"UNRESVSP", UNRESVSP}, 1159f08c3bdfSopenharmony_ci {"DFFSYNC", DFFSYNC}, 1160f08c3bdfSopenharmony_ci 1161f08c3bdfSopenharmony_ci /* Irix and Linux System Calls */ 1162f08c3bdfSopenharmony_ci {"READV", READV}, 1163f08c3bdfSopenharmony_ci {"WRITEV", WRITEV}, 1164f08c3bdfSopenharmony_ci {"MMAPR", MMAPR}, 1165f08c3bdfSopenharmony_ci {"MMAPW", MMAPW}, 1166f08c3bdfSopenharmony_ci {"FSYNC2", FSYNC2}, 1167f08c3bdfSopenharmony_ci {"FDATASYNC", FDATASYNC}, 1168f08c3bdfSopenharmony_ci 1169f08c3bdfSopenharmony_ci {"unknown", -1}, 1170f08c3bdfSopenharmony_ci}; 1171f08c3bdfSopenharmony_ci 1172f08c3bdfSopenharmony_cistruct smap aionames[] = { 1173f08c3bdfSopenharmony_ci {"poll", A_POLL}, 1174f08c3bdfSopenharmony_ci {"signal", A_SIGNAL}, 1175f08c3bdfSopenharmony_ci {"recall", A_RECALL}, 1176f08c3bdfSopenharmony_ci {"recalla", A_RECALLA}, 1177f08c3bdfSopenharmony_ci {"recalls", A_RECALLS}, 1178f08c3bdfSopenharmony_ci {"suspend", A_SUSPEND}, 1179f08c3bdfSopenharmony_ci {"callback", A_CALLBACK}, 1180f08c3bdfSopenharmony_ci {"synch", 0}, 1181f08c3bdfSopenharmony_ci {"unknown", -1}, 1182f08c3bdfSopenharmony_ci}; 1183f08c3bdfSopenharmony_ci 1184f08c3bdfSopenharmony_cichar *format_oflags(int oflags) 1185f08c3bdfSopenharmony_ci{ 1186f08c3bdfSopenharmony_ci char flags[255]; 1187f08c3bdfSopenharmony_ci 1188f08c3bdfSopenharmony_ci flags[0] = '\0'; 1189f08c3bdfSopenharmony_ci switch (oflags & 03) { 1190f08c3bdfSopenharmony_ci case O_RDONLY: 1191f08c3bdfSopenharmony_ci strcat(flags, "O_RDONLY,"); 1192f08c3bdfSopenharmony_ci break; 1193f08c3bdfSopenharmony_ci case O_WRONLY: 1194f08c3bdfSopenharmony_ci strcat(flags, "O_WRONLY,"); 1195f08c3bdfSopenharmony_ci break; 1196f08c3bdfSopenharmony_ci case O_RDWR: 1197f08c3bdfSopenharmony_ci strcat(flags, "O_RDWR,"); 1198f08c3bdfSopenharmony_ci break; 1199f08c3bdfSopenharmony_ci default: 1200f08c3bdfSopenharmony_ci strcat(flags, "O_weird"); 1201f08c3bdfSopenharmony_ci break; 1202f08c3bdfSopenharmony_ci } 1203f08c3bdfSopenharmony_ci 1204f08c3bdfSopenharmony_ci if (oflags & O_EXCL) 1205f08c3bdfSopenharmony_ci strcat(flags, "O_EXCL,"); 1206f08c3bdfSopenharmony_ci 1207f08c3bdfSopenharmony_ci if (oflags & O_SYNC) 1208f08c3bdfSopenharmony_ci strcat(flags, "O_SYNC,"); 1209f08c3bdfSopenharmony_ci#ifdef CRAY 1210f08c3bdfSopenharmony_ci if (oflags & O_RAW) 1211f08c3bdfSopenharmony_ci strcat(flags, "O_RAW,"); 1212f08c3bdfSopenharmony_ci if (oflags & O_WELLFORMED) 1213f08c3bdfSopenharmony_ci strcat(flags, "O_WELLFORMED,"); 1214f08c3bdfSopenharmony_ci#ifdef O_SSD 1215f08c3bdfSopenharmony_ci if (oflags & O_SSD) 1216f08c3bdfSopenharmony_ci strcat(flags, "O_SSD,"); 1217f08c3bdfSopenharmony_ci#endif 1218f08c3bdfSopenharmony_ci if (oflags & O_LDRAW) 1219f08c3bdfSopenharmony_ci strcat(flags, "O_LDRAW,"); 1220f08c3bdfSopenharmony_ci if (oflags & O_PARALLEL) 1221f08c3bdfSopenharmony_ci strcat(flags, "O_PARALLEL,"); 1222f08c3bdfSopenharmony_ci if (oflags & O_BIG) 1223f08c3bdfSopenharmony_ci strcat(flags, "O_BIG,"); 1224f08c3bdfSopenharmony_ci if (oflags & O_PLACE) 1225f08c3bdfSopenharmony_ci strcat(flags, "O_PLACE,"); 1226f08c3bdfSopenharmony_ci if (oflags & O_ASYNC) 1227f08c3bdfSopenharmony_ci strcat(flags, "O_ASYNC,"); 1228f08c3bdfSopenharmony_ci#endif 1229f08c3bdfSopenharmony_ci 1230f08c3bdfSopenharmony_ci#ifdef sgi 1231f08c3bdfSopenharmony_ci if (oflags & O_DIRECT) 1232f08c3bdfSopenharmony_ci strcat(flags, "O_DIRECT,"); 1233f08c3bdfSopenharmony_ci if (oflags & O_DSYNC) 1234f08c3bdfSopenharmony_ci strcat(flags, "O_DSYNC,"); 1235f08c3bdfSopenharmony_ci if (oflags & O_RSYNC) 1236f08c3bdfSopenharmony_ci strcat(flags, "O_RSYNC,"); 1237f08c3bdfSopenharmony_ci#endif 1238f08c3bdfSopenharmony_ci 1239f08c3bdfSopenharmony_ci return (strdup(flags)); 1240f08c3bdfSopenharmony_ci} 1241f08c3bdfSopenharmony_ci 1242f08c3bdfSopenharmony_cichar *format_strat(int strategy) 1243f08c3bdfSopenharmony_ci{ 1244f08c3bdfSopenharmony_ci char msg[64]; 1245f08c3bdfSopenharmony_ci char *aio_strat; 1246f08c3bdfSopenharmony_ci 1247f08c3bdfSopenharmony_ci switch (strategy) { 1248f08c3bdfSopenharmony_ci case A_POLL: 1249f08c3bdfSopenharmony_ci aio_strat = "POLL"; 1250f08c3bdfSopenharmony_ci break; 1251f08c3bdfSopenharmony_ci case A_SIGNAL: 1252f08c3bdfSopenharmony_ci aio_strat = "SIGNAL"; 1253f08c3bdfSopenharmony_ci break; 1254f08c3bdfSopenharmony_ci case A_RECALL: 1255f08c3bdfSopenharmony_ci aio_strat = "RECALL"; 1256f08c3bdfSopenharmony_ci break; 1257f08c3bdfSopenharmony_ci case A_RECALLA: 1258f08c3bdfSopenharmony_ci aio_strat = "RECALLA"; 1259f08c3bdfSopenharmony_ci break; 1260f08c3bdfSopenharmony_ci case A_RECALLS: 1261f08c3bdfSopenharmony_ci aio_strat = "RECALLS"; 1262f08c3bdfSopenharmony_ci break; 1263f08c3bdfSopenharmony_ci case A_SUSPEND: 1264f08c3bdfSopenharmony_ci aio_strat = "SUSPEND"; 1265f08c3bdfSopenharmony_ci break; 1266f08c3bdfSopenharmony_ci case A_CALLBACK: 1267f08c3bdfSopenharmony_ci aio_strat = "CALLBACK"; 1268f08c3bdfSopenharmony_ci break; 1269f08c3bdfSopenharmony_ci case 0: 1270f08c3bdfSopenharmony_ci aio_strat = "<zero>"; 1271f08c3bdfSopenharmony_ci break; 1272f08c3bdfSopenharmony_ci default: 1273f08c3bdfSopenharmony_ci sprintf(msg, "<error:%#o>", strategy); 1274f08c3bdfSopenharmony_ci aio_strat = strdup(msg); 1275f08c3bdfSopenharmony_ci break; 1276f08c3bdfSopenharmony_ci } 1277f08c3bdfSopenharmony_ci 1278f08c3bdfSopenharmony_ci return (aio_strat); 1279f08c3bdfSopenharmony_ci} 1280f08c3bdfSopenharmony_ci 1281f08c3bdfSopenharmony_cichar *format_rw(struct io_req *ioreq, int fd, void *buffer, int signo, 1282f08c3bdfSopenharmony_ci char *pattern, void *iosw) 1283f08c3bdfSopenharmony_ci{ 1284f08c3bdfSopenharmony_ci static char *errbuf = NULL; 1285f08c3bdfSopenharmony_ci char *aio_strat, *cp; 1286f08c3bdfSopenharmony_ci struct read_req *readp = &ioreq->r_data.read; 1287f08c3bdfSopenharmony_ci struct write_req *writep = &ioreq->r_data.write; 1288f08c3bdfSopenharmony_ci struct read_req *readap = &ioreq->r_data.read; 1289f08c3bdfSopenharmony_ci struct write_req *writeap = &ioreq->r_data.write; 1290f08c3bdfSopenharmony_ci 1291f08c3bdfSopenharmony_ci if (errbuf == NULL) 1292f08c3bdfSopenharmony_ci errbuf = malloc(32768); 1293f08c3bdfSopenharmony_ci 1294f08c3bdfSopenharmony_ci cp = errbuf; 1295f08c3bdfSopenharmony_ci cp += sprintf(cp, "Request number %d\n", Reqno); 1296f08c3bdfSopenharmony_ci 1297f08c3bdfSopenharmony_ci switch (ioreq->r_type) { 1298f08c3bdfSopenharmony_ci case READ: 1299f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: read(%d, %#lo, %d)\n", 1300f08c3bdfSopenharmony_ci fd, (unsigned long)buffer, readp->r_nbytes); 1301f08c3bdfSopenharmony_ci cp += 1302f08c3bdfSopenharmony_ci sprintf(cp, 1303f08c3bdfSopenharmony_ci " fd %d is file %s - open flags are %#o\n", 1304f08c3bdfSopenharmony_ci fd, readp->r_file, readp->r_oflags); 1305f08c3bdfSopenharmony_ci cp += 1306f08c3bdfSopenharmony_ci sprintf(cp, " read done at file offset %d\n", 1307f08c3bdfSopenharmony_ci readp->r_offset); 1308f08c3bdfSopenharmony_ci break; 1309f08c3bdfSopenharmony_ci 1310f08c3bdfSopenharmony_ci case WRITE: 1311f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: write(%d, %#lo, %d)\n", 1312f08c3bdfSopenharmony_ci fd, (unsigned long)buffer, writep->r_nbytes); 1313f08c3bdfSopenharmony_ci cp += 1314f08c3bdfSopenharmony_ci sprintf(cp, 1315f08c3bdfSopenharmony_ci " fd %d is file %s - open flags are %#o\n", 1316f08c3bdfSopenharmony_ci fd, writep->r_file, writep->r_oflags); 1317f08c3bdfSopenharmony_ci cp += 1318f08c3bdfSopenharmony_ci sprintf(cp, 1319f08c3bdfSopenharmony_ci " write done at file offset %d - pattern is %s\n", 1320f08c3bdfSopenharmony_ci writep->r_offset, pattern); 1321f08c3bdfSopenharmony_ci break; 1322f08c3bdfSopenharmony_ci 1323f08c3bdfSopenharmony_ci case READA: 1324f08c3bdfSopenharmony_ci aio_strat = format_strat(readap->r_aio_strat); 1325f08c3bdfSopenharmony_ci 1326f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: reada(%d, %#lo, %d, %#lo, %d)\n", 1327f08c3bdfSopenharmony_ci fd, (unsigned long)buffer, readap->r_nbytes, 1328f08c3bdfSopenharmony_ci (unsigned long)iosw, signo); 1329f08c3bdfSopenharmony_ci cp += 1330f08c3bdfSopenharmony_ci sprintf(cp, 1331f08c3bdfSopenharmony_ci " fd %d is file %s - open flags are %#o\n", 1332f08c3bdfSopenharmony_ci fd, readap->r_file, readp->r_oflags); 1333f08c3bdfSopenharmony_ci cp += 1334f08c3bdfSopenharmony_ci sprintf(cp, " reada done at file offset %d\n", 1335f08c3bdfSopenharmony_ci readap->r_offset); 1336f08c3bdfSopenharmony_ci cp += 1337f08c3bdfSopenharmony_ci sprintf(cp, 1338f08c3bdfSopenharmony_ci " async io completion strategy is %s\n", 1339f08c3bdfSopenharmony_ci aio_strat); 1340f08c3bdfSopenharmony_ci break; 1341f08c3bdfSopenharmony_ci 1342f08c3bdfSopenharmony_ci case WRITEA: 1343f08c3bdfSopenharmony_ci aio_strat = format_strat(writeap->r_aio_strat); 1344f08c3bdfSopenharmony_ci 1345f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: writea(%d, %#lo, %d, %#lo, %d)\n", 1346f08c3bdfSopenharmony_ci fd, (unsigned long)buffer, writeap->r_nbytes, 1347f08c3bdfSopenharmony_ci (unsigned long)iosw, signo); 1348f08c3bdfSopenharmony_ci cp += 1349f08c3bdfSopenharmony_ci sprintf(cp, 1350f08c3bdfSopenharmony_ci " fd %d is file %s - open flags are %#o\n", 1351f08c3bdfSopenharmony_ci fd, writeap->r_file, writeap->r_oflags); 1352f08c3bdfSopenharmony_ci cp += 1353f08c3bdfSopenharmony_ci sprintf(cp, 1354f08c3bdfSopenharmony_ci " writea done at file offset %d - pattern is %s\n", 1355f08c3bdfSopenharmony_ci writeap->r_offset, pattern); 1356f08c3bdfSopenharmony_ci cp += 1357f08c3bdfSopenharmony_ci sprintf(cp, 1358f08c3bdfSopenharmony_ci " async io completion strategy is %s\n", 1359f08c3bdfSopenharmony_ci aio_strat); 1360f08c3bdfSopenharmony_ci break; 1361f08c3bdfSopenharmony_ci 1362f08c3bdfSopenharmony_ci } 1363f08c3bdfSopenharmony_ci 1364f08c3bdfSopenharmony_ci return errbuf; 1365f08c3bdfSopenharmony_ci} 1366f08c3bdfSopenharmony_ci 1367f08c3bdfSopenharmony_ci#ifdef CRAY 1368f08c3bdfSopenharmony_cichar *format_sds(struct io_req *ioreq, void *buffer, int sds, char *pattern) 1369f08c3bdfSopenharmony_ci{ 1370f08c3bdfSopenharmony_ci int i; 1371f08c3bdfSopenharmony_ci static char *errbuf = NULL; 1372f08c3bdfSopenharmony_ci char *cp; 1373f08c3bdfSopenharmony_ci 1374f08c3bdfSopenharmony_ci struct ssread_req *ssreadp = &ioreq->r_data.ssread; 1375f08c3bdfSopenharmony_ci struct sswrite_req *sswritep = &ioreq->r_data.sswrite; 1376f08c3bdfSopenharmony_ci 1377f08c3bdfSopenharmony_ci if (errbuf == NULL) 1378f08c3bdfSopenharmony_ci errbuf = malloc(32768); 1379f08c3bdfSopenharmony_ci 1380f08c3bdfSopenharmony_ci cp = errbuf; 1381f08c3bdfSopenharmony_ci cp += sprintf(cp, "Request number %d\n", Reqno); 1382f08c3bdfSopenharmony_ci 1383f08c3bdfSopenharmony_ci switch (ioreq->r_type) { 1384f08c3bdfSopenharmony_ci case SSREAD: 1385f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: ssread(%#o, %#o, %d)\n", 1386f08c3bdfSopenharmony_ci buffer, sds, ssreadp->r_nbytes); 1387f08c3bdfSopenharmony_ci break; 1388f08c3bdfSopenharmony_ci 1389f08c3bdfSopenharmony_ci case SSWRITE: 1390f08c3bdfSopenharmony_ci cp += 1391f08c3bdfSopenharmony_ci sprintf(cp, 1392f08c3bdfSopenharmony_ci "syscall: sswrite(%#o, %#o, %d) - pattern was %s\n", 1393f08c3bdfSopenharmony_ci buffer, sds, sswritep->r_nbytes, pattern); 1394f08c3bdfSopenharmony_ci break; 1395f08c3bdfSopenharmony_ci } 1396f08c3bdfSopenharmony_ci return errbuf; 1397f08c3bdfSopenharmony_ci} 1398f08c3bdfSopenharmony_ci#endif /* CRAY */ 1399f08c3bdfSopenharmony_ci 1400f08c3bdfSopenharmony_ci/* 1401f08c3bdfSopenharmony_ci * Perform the various sorts of disk reads 1402f08c3bdfSopenharmony_ci */ 1403f08c3bdfSopenharmony_ci 1404f08c3bdfSopenharmony_ciint do_read(struct io_req *req) 1405f08c3bdfSopenharmony_ci{ 1406f08c3bdfSopenharmony_ci int fd, offset, nbytes, oflags, rval; 1407f08c3bdfSopenharmony_ci char *addr, *file; 1408f08c3bdfSopenharmony_ci#ifdef CRAY 1409f08c3bdfSopenharmony_ci struct aio_info *aiop; 1410f08c3bdfSopenharmony_ci int aio_id, aio_strat, signo; 1411f08c3bdfSopenharmony_ci#endif 1412f08c3bdfSopenharmony_ci#ifdef sgi 1413f08c3bdfSopenharmony_ci struct fd_cache *fdc; 1414f08c3bdfSopenharmony_ci#endif 1415f08c3bdfSopenharmony_ci 1416f08c3bdfSopenharmony_ci /* 1417f08c3bdfSopenharmony_ci * Initialize common fields - assumes r_oflags, r_file, r_offset, and 1418f08c3bdfSopenharmony_ci * r_nbytes are at the same offset in the read_req and reada_req 1419f08c3bdfSopenharmony_ci * structures. 1420f08c3bdfSopenharmony_ci */ 1421f08c3bdfSopenharmony_ci 1422f08c3bdfSopenharmony_ci file = req->r_data.read.r_file; 1423f08c3bdfSopenharmony_ci oflags = req->r_data.read.r_oflags; 1424f08c3bdfSopenharmony_ci offset = req->r_data.read.r_offset; 1425f08c3bdfSopenharmony_ci nbytes = req->r_data.read.r_nbytes; 1426f08c3bdfSopenharmony_ci 1427f08c3bdfSopenharmony_ci /*printf("read: %s, %#o, %d %d\n", file, oflags, offset, nbytes); */ 1428f08c3bdfSopenharmony_ci 1429f08c3bdfSopenharmony_ci /* 1430f08c3bdfSopenharmony_ci * Grab an open file descriptor 1431f08c3bdfSopenharmony_ci * Note: must be done before memory allocation so that the direct i/o 1432f08c3bdfSopenharmony_ci * information is available in mem. allocate 1433f08c3bdfSopenharmony_ci */ 1434f08c3bdfSopenharmony_ci 1435f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, oflags)) == -1) 1436f08c3bdfSopenharmony_ci return -1; 1437f08c3bdfSopenharmony_ci 1438f08c3bdfSopenharmony_ci /* 1439f08c3bdfSopenharmony_ci * Allocate core or sds - based on the O_SSD flag 1440f08c3bdfSopenharmony_ci */ 1441f08c3bdfSopenharmony_ci 1442f08c3bdfSopenharmony_ci#ifndef wtob 1443f08c3bdfSopenharmony_ci#define wtob(x) (x * sizeof(UINT64_T)) 1444f08c3bdfSopenharmony_ci#endif 1445f08c3bdfSopenharmony_ci 1446f08c3bdfSopenharmony_ci#ifdef CRAY 1447f08c3bdfSopenharmony_ci if (oflags & O_SSD) { 1448f08c3bdfSopenharmony_ci if (alloc_sds(nbytes) == -1) 1449f08c3bdfSopenharmony_ci return -1; 1450f08c3bdfSopenharmony_ci 1451f08c3bdfSopenharmony_ci addr = (char *)Sdsptr; 1452f08c3bdfSopenharmony_ci } else { 1453f08c3bdfSopenharmony_ci if ((rval = 1454f08c3bdfSopenharmony_ci alloc_mem(nbytes + wtob(1) * 2 + 1455f08c3bdfSopenharmony_ci MPP_BUMP * sizeof(UINT64_T))) < 0) { 1456f08c3bdfSopenharmony_ci return rval; 1457f08c3bdfSopenharmony_ci } 1458f08c3bdfSopenharmony_ci 1459f08c3bdfSopenharmony_ci addr = Memptr; 1460f08c3bdfSopenharmony_ci 1461f08c3bdfSopenharmony_ci /* 1462f08c3bdfSopenharmony_ci * if io is not raw, bump the offset by a random amount 1463f08c3bdfSopenharmony_ci * to generate non-word-aligned io. 1464f08c3bdfSopenharmony_ci */ 1465f08c3bdfSopenharmony_ci if (!(req->r_data.read.r_uflags & F_WORD_ALIGNED)) { 1466f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 1467f08c3bdfSopenharmony_ci } 1468f08c3bdfSopenharmony_ci } 1469f08c3bdfSopenharmony_ci#else 1470f08c3bdfSopenharmony_ci#ifdef sgi 1471f08c3bdfSopenharmony_ci /* get memory alignment for using DIRECT I/O */ 1472f08c3bdfSopenharmony_ci fdc = alloc_fdcache(file, oflags); 1473f08c3bdfSopenharmony_ci 1474f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1) * 2 + fdc->c_memalign)) < 0) { 1475f08c3bdfSopenharmony_ci return rval; 1476f08c3bdfSopenharmony_ci } 1477f08c3bdfSopenharmony_ci 1478f08c3bdfSopenharmony_ci addr = Memptr; 1479f08c3bdfSopenharmony_ci 1480f08c3bdfSopenharmony_ci if ((req->r_data.read.r_uflags & F_WORD_ALIGNED)) { 1481f08c3bdfSopenharmony_ci /* 1482f08c3bdfSopenharmony_ci * Force memory alignment for Direct I/O 1483f08c3bdfSopenharmony_ci */ 1484f08c3bdfSopenharmony_ci if ((oflags & O_DIRECT) && ((long)addr % fdc->c_memalign != 0)) { 1485f08c3bdfSopenharmony_ci addr += 1486f08c3bdfSopenharmony_ci fdc->c_memalign - ((long)addr % fdc->c_memalign); 1487f08c3bdfSopenharmony_ci } 1488f08c3bdfSopenharmony_ci } else { 1489f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 1490f08c3bdfSopenharmony_ci } 1491f08c3bdfSopenharmony_ci#else 1492f08c3bdfSopenharmony_ci /* what is !CRAY && !sgi ? */ 1493f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1) * 2)) < 0) { 1494f08c3bdfSopenharmony_ci return rval; 1495f08c3bdfSopenharmony_ci } 1496f08c3bdfSopenharmony_ci 1497f08c3bdfSopenharmony_ci addr = Memptr; 1498f08c3bdfSopenharmony_ci#endif /* !CRAY && sgi */ 1499f08c3bdfSopenharmony_ci#endif /* CRAY */ 1500f08c3bdfSopenharmony_ci 1501f08c3bdfSopenharmony_ci switch (req->r_type) { 1502f08c3bdfSopenharmony_ci case READ: 1503f08c3bdfSopenharmony_ci /* move to the desired file position. */ 1504f08c3bdfSopenharmony_ci if (lseek(fd, offset, SEEK_SET) == -1) { 1505f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1506f08c3bdfSopenharmony_ci "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n", 1507f08c3bdfSopenharmony_ci fd, offset, SYSERR, errno); 1508f08c3bdfSopenharmony_ci return -1; 1509f08c3bdfSopenharmony_ci } 1510f08c3bdfSopenharmony_ci 1511f08c3bdfSopenharmony_ci if ((rval = read(fd, addr, nbytes)) == -1) { 1512f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1513f08c3bdfSopenharmony_ci "read() request failed: %s (%d)\n%s\n", 1514f08c3bdfSopenharmony_ci SYSERR, errno, 1515f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, NULL, NULL)); 1516f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1517f08c3bdfSopenharmony_ci return -1; 1518f08c3bdfSopenharmony_ci } else if (rval != nbytes) { 1519f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1520f08c3bdfSopenharmony_ci "read() request returned wrong # of bytes - expected %d, got %d\n%s\n", 1521f08c3bdfSopenharmony_ci nbytes, rval, 1522f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, NULL, NULL)); 1523f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1524f08c3bdfSopenharmony_ci return -1; 1525f08c3bdfSopenharmony_ci } 1526f08c3bdfSopenharmony_ci break; 1527f08c3bdfSopenharmony_ci 1528f08c3bdfSopenharmony_ci#ifdef CRAY 1529f08c3bdfSopenharmony_ci case READA: 1530f08c3bdfSopenharmony_ci /* 1531f08c3bdfSopenharmony_ci * Async read 1532f08c3bdfSopenharmony_ci */ 1533f08c3bdfSopenharmony_ci 1534f08c3bdfSopenharmony_ci /* move to the desired file position. */ 1535f08c3bdfSopenharmony_ci if (lseek(fd, offset, SEEK_SET) == -1) { 1536f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1537f08c3bdfSopenharmony_ci "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n", 1538f08c3bdfSopenharmony_ci fd, offset, SYSERR, errno); 1539f08c3bdfSopenharmony_ci return -1; 1540f08c3bdfSopenharmony_ci } 1541f08c3bdfSopenharmony_ci 1542f08c3bdfSopenharmony_ci aio_strat = req->r_data.read.r_aio_strat; 1543f08c3bdfSopenharmony_ci signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0; 1544f08c3bdfSopenharmony_ci 1545f08c3bdfSopenharmony_ci aio_id = aio_register(fd, aio_strat, signo); 1546f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 1547f08c3bdfSopenharmony_ci 1548f08c3bdfSopenharmony_ci if (reada(fd, addr, nbytes, &aiop->iosw, signo) == -1) { 1549f08c3bdfSopenharmony_ci doio_fprintf(stderr, "reada() failed: %s (%d)\n%s\n", 1550f08c3bdfSopenharmony_ci SYSERR, errno, 1551f08c3bdfSopenharmony_ci format_rw(req, fd, addr, signo, NULL, 1552f08c3bdfSopenharmony_ci &aiop->iosw)); 1553f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1554f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1555f08c3bdfSopenharmony_ci rval = -1; 1556f08c3bdfSopenharmony_ci } else { 1557f08c3bdfSopenharmony_ci /* 1558f08c3bdfSopenharmony_ci * Wait for io to complete 1559f08c3bdfSopenharmony_ci */ 1560f08c3bdfSopenharmony_ci 1561f08c3bdfSopenharmony_ci aio_wait(aio_id); 1562f08c3bdfSopenharmony_ci 1563f08c3bdfSopenharmony_ci /* 1564f08c3bdfSopenharmony_ci * make sure the io completed without error 1565f08c3bdfSopenharmony_ci */ 1566f08c3bdfSopenharmony_ci 1567f08c3bdfSopenharmony_ci if (aiop->iosw.sw_count != nbytes) { 1568f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1569f08c3bdfSopenharmony_ci "Bad iosw from reada()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n", 1570f08c3bdfSopenharmony_ci 1, 0, nbytes, 1571f08c3bdfSopenharmony_ci aiop->iosw.sw_flag, 1572f08c3bdfSopenharmony_ci aiop->iosw.sw_error, 1573f08c3bdfSopenharmony_ci aiop->iosw.sw_count, 1574f08c3bdfSopenharmony_ci format_rw(req, fd, addr, signo, 1575f08c3bdfSopenharmony_ci NULL, &aiop->iosw)); 1576f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1577f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 1578f08c3bdfSopenharmony_ci rval = -1; 1579f08c3bdfSopenharmony_ci } else { 1580f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1581f08c3bdfSopenharmony_ci rval = 0; 1582f08c3bdfSopenharmony_ci } 1583f08c3bdfSopenharmony_ci } 1584f08c3bdfSopenharmony_ci 1585f08c3bdfSopenharmony_ci if (rval == -1) 1586f08c3bdfSopenharmony_ci return rval; 1587f08c3bdfSopenharmony_ci break; 1588f08c3bdfSopenharmony_ci#endif /* CRAY */ 1589f08c3bdfSopenharmony_ci } 1590f08c3bdfSopenharmony_ci 1591f08c3bdfSopenharmony_ci return 0; /* if we get here, everything went ok */ 1592f08c3bdfSopenharmony_ci} 1593f08c3bdfSopenharmony_ci 1594f08c3bdfSopenharmony_ci/* 1595f08c3bdfSopenharmony_ci * Perform the verious types of disk writes. 1596f08c3bdfSopenharmony_ci */ 1597f08c3bdfSopenharmony_ci 1598f08c3bdfSopenharmony_ciint do_write(struct io_req *req) 1599f08c3bdfSopenharmony_ci{ 1600f08c3bdfSopenharmony_ci static int pid = -1; 1601f08c3bdfSopenharmony_ci int fd, nbytes, oflags, signo; 1602f08c3bdfSopenharmony_ci int logged_write, rval, got_lock; 1603f08c3bdfSopenharmony_ci off_t offset, woffset; 1604f08c3bdfSopenharmony_ci char *addr, pattern, *file, *msg; 1605f08c3bdfSopenharmony_ci struct wlog_rec wrec; 1606f08c3bdfSopenharmony_ci#ifdef CRAY 1607f08c3bdfSopenharmony_ci int aio_strat, aio_id; 1608f08c3bdfSopenharmony_ci struct aio_info *aiop; 1609f08c3bdfSopenharmony_ci#endif 1610f08c3bdfSopenharmony_ci#ifdef sgi 1611f08c3bdfSopenharmony_ci struct fd_cache *fdc; 1612f08c3bdfSopenharmony_ci#endif 1613f08c3bdfSopenharmony_ci 1614f08c3bdfSopenharmony_ci woffset = 0; 1615f08c3bdfSopenharmony_ci 1616f08c3bdfSopenharmony_ci /* 1617f08c3bdfSopenharmony_ci * Misc variable setup 1618f08c3bdfSopenharmony_ci */ 1619f08c3bdfSopenharmony_ci 1620f08c3bdfSopenharmony_ci signo = 0; 1621f08c3bdfSopenharmony_ci nbytes = req->r_data.write.r_nbytes; 1622f08c3bdfSopenharmony_ci offset = req->r_data.write.r_offset; 1623f08c3bdfSopenharmony_ci pattern = req->r_data.write.r_pattern; 1624f08c3bdfSopenharmony_ci file = req->r_data.write.r_file; 1625f08c3bdfSopenharmony_ci oflags = req->r_data.write.r_oflags; 1626f08c3bdfSopenharmony_ci 1627f08c3bdfSopenharmony_ci /*printf("pwrite: %s, %#o, %d %d\n", file, oflags, offset, nbytes); */ 1628f08c3bdfSopenharmony_ci 1629f08c3bdfSopenharmony_ci /* 1630f08c3bdfSopenharmony_ci * Allocate core memory and possibly sds space. Initialize the data 1631f08c3bdfSopenharmony_ci * to be written. 1632f08c3bdfSopenharmony_ci */ 1633f08c3bdfSopenharmony_ci 1634f08c3bdfSopenharmony_ci Pattern[0] = pattern; 1635f08c3bdfSopenharmony_ci 1636f08c3bdfSopenharmony_ci /* 1637f08c3bdfSopenharmony_ci * Get a descriptor to do the io on 1638f08c3bdfSopenharmony_ci */ 1639f08c3bdfSopenharmony_ci 1640f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, oflags)) == -1) 1641f08c3bdfSopenharmony_ci return -1; 1642f08c3bdfSopenharmony_ci 1643f08c3bdfSopenharmony_ci /*printf("write: %d, %s, %#o, %d %d\n", 1644f08c3bdfSopenharmony_ci fd, file, oflags, offset, nbytes); */ 1645f08c3bdfSopenharmony_ci 1646f08c3bdfSopenharmony_ci /* 1647f08c3bdfSopenharmony_ci * Allocate SDS space for backdoor write if desired 1648f08c3bdfSopenharmony_ci */ 1649f08c3bdfSopenharmony_ci 1650f08c3bdfSopenharmony_ci#ifdef CRAY 1651f08c3bdfSopenharmony_ci if (oflags & O_SSD) { 1652f08c3bdfSopenharmony_ci#ifndef _CRAYMPP 1653f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1))) < 0) { 1654f08c3bdfSopenharmony_ci return rval; 1655f08c3bdfSopenharmony_ci } 1656f08c3bdfSopenharmony_ci 1657f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 0); 1658f08c3bdfSopenharmony_ci /*pattern_fill(Memptr, nbytes, Pattern, Pattern_Length, 0); */ 1659f08c3bdfSopenharmony_ci 1660f08c3bdfSopenharmony_ci if (alloc_sds(nbytes) == -1) 1661f08c3bdfSopenharmony_ci return -1; 1662f08c3bdfSopenharmony_ci 1663f08c3bdfSopenharmony_ci if (sswrite((long)Memptr, Sdsptr, btoc(nbytes)) == -1) { 1664f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1665f08c3bdfSopenharmony_ci "sswrite(%d, %d, %d) failed: %s (%d)\n", 1666f08c3bdfSopenharmony_ci (long)Memptr, Sdsptr, btoc(nbytes), SYSERR, 1667f08c3bdfSopenharmony_ci errno); 1668f08c3bdfSopenharmony_ci fflush(stderr); 1669f08c3bdfSopenharmony_ci return -1; 1670f08c3bdfSopenharmony_ci } 1671f08c3bdfSopenharmony_ci 1672f08c3bdfSopenharmony_ci addr = (char *)Sdsptr; 1673f08c3bdfSopenharmony_ci#else 1674f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1675f08c3bdfSopenharmony_ci "Invalid O_SSD flag was generated for MPP system\n"); 1676f08c3bdfSopenharmony_ci fflush(stderr); 1677f08c3bdfSopenharmony_ci return -1; 1678f08c3bdfSopenharmony_ci#endif /* !CRAYMPP */ 1679f08c3bdfSopenharmony_ci } else { 1680f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1)) < 0)) { 1681f08c3bdfSopenharmony_ci return rval; 1682f08c3bdfSopenharmony_ci } 1683f08c3bdfSopenharmony_ci 1684f08c3bdfSopenharmony_ci addr = Memptr; 1685f08c3bdfSopenharmony_ci 1686f08c3bdfSopenharmony_ci /* 1687f08c3bdfSopenharmony_ci * if io is not raw, bump the offset by a random amount 1688f08c3bdfSopenharmony_ci * to generate non-word-aligned io. 1689f08c3bdfSopenharmony_ci */ 1690f08c3bdfSopenharmony_ci 1691f08c3bdfSopenharmony_ci if (!(req->r_data.write.r_uflags & F_WORD_ALIGNED)) { 1692f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 1693f08c3bdfSopenharmony_ci } 1694f08c3bdfSopenharmony_ci 1695f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 0); 1696f08c3bdfSopenharmony_ci if (addr != Memptr) 1697f08c3bdfSopenharmony_ci memmove(addr, Memptr, nbytes); 1698f08c3bdfSopenharmony_ci } 1699f08c3bdfSopenharmony_ci#else /* CRAY */ 1700f08c3bdfSopenharmony_ci#ifdef sgi 1701f08c3bdfSopenharmony_ci /* get memory alignment for using DIRECT I/O */ 1702f08c3bdfSopenharmony_ci fdc = alloc_fdcache(file, oflags); 1703f08c3bdfSopenharmony_ci 1704f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1) * 2 + fdc->c_memalign)) < 0) { 1705f08c3bdfSopenharmony_ci return rval; 1706f08c3bdfSopenharmony_ci } 1707f08c3bdfSopenharmony_ci 1708f08c3bdfSopenharmony_ci addr = Memptr; 1709f08c3bdfSopenharmony_ci 1710f08c3bdfSopenharmony_ci if ((req->r_data.write.r_uflags & F_WORD_ALIGNED)) { 1711f08c3bdfSopenharmony_ci /* 1712f08c3bdfSopenharmony_ci * Force memory alignment for Direct I/O 1713f08c3bdfSopenharmony_ci */ 1714f08c3bdfSopenharmony_ci if ((oflags & O_DIRECT) && ((long)addr % fdc->c_memalign != 0)) { 1715f08c3bdfSopenharmony_ci addr += 1716f08c3bdfSopenharmony_ci fdc->c_memalign - ((long)addr % fdc->c_memalign); 1717f08c3bdfSopenharmony_ci } 1718f08c3bdfSopenharmony_ci } else { 1719f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 1720f08c3bdfSopenharmony_ci } 1721f08c3bdfSopenharmony_ci 1722f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 0); 1723f08c3bdfSopenharmony_ci if (addr != Memptr) 1724f08c3bdfSopenharmony_ci memmove(addr, Memptr, nbytes); 1725f08c3bdfSopenharmony_ci 1726f08c3bdfSopenharmony_ci#else /* sgi */ 1727f08c3bdfSopenharmony_ci if ((rval = alloc_mem(nbytes + wtob(1) * 2)) < 0) { 1728f08c3bdfSopenharmony_ci return rval; 1729f08c3bdfSopenharmony_ci } 1730f08c3bdfSopenharmony_ci 1731f08c3bdfSopenharmony_ci addr = Memptr; 1732f08c3bdfSopenharmony_ci 1733f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 0); 1734f08c3bdfSopenharmony_ci if (addr != Memptr) 1735f08c3bdfSopenharmony_ci memmove(addr, Memptr, nbytes); 1736f08c3bdfSopenharmony_ci#endif /* sgi */ 1737f08c3bdfSopenharmony_ci#endif /* CRAY */ 1738f08c3bdfSopenharmony_ci 1739f08c3bdfSopenharmony_ci rval = -1; 1740f08c3bdfSopenharmony_ci got_lock = 0; 1741f08c3bdfSopenharmony_ci logged_write = 0; 1742f08c3bdfSopenharmony_ci 1743f08c3bdfSopenharmony_ci if (k_opt) { 1744f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_WRLCK, offset, nbytes) < 0) { 1745f08c3bdfSopenharmony_ci alloc_mem(-1); 1746f08c3bdfSopenharmony_ci exit(E_INTERNAL); 1747f08c3bdfSopenharmony_ci } 1748f08c3bdfSopenharmony_ci 1749f08c3bdfSopenharmony_ci got_lock = 1; 1750f08c3bdfSopenharmony_ci } 1751f08c3bdfSopenharmony_ci 1752f08c3bdfSopenharmony_ci /* 1753f08c3bdfSopenharmony_ci * Write a preliminary write-log entry. This is done so that 1754f08c3bdfSopenharmony_ci * doio_check can do corruption detection across an interrupt/crash. 1755f08c3bdfSopenharmony_ci * Note that w_done is set to 0. If doio_check sees this, it 1756f08c3bdfSopenharmony_ci * re-creates the file extents as if the write completed, but does not 1757f08c3bdfSopenharmony_ci * do any checking - see comments in doio_check for more details. 1758f08c3bdfSopenharmony_ci */ 1759f08c3bdfSopenharmony_ci 1760f08c3bdfSopenharmony_ci if (w_opt) { 1761f08c3bdfSopenharmony_ci if (pid == -1) { 1762f08c3bdfSopenharmony_ci pid = getpid(); 1763f08c3bdfSopenharmony_ci } 1764f08c3bdfSopenharmony_ci wrec.w_async = (req->r_type == WRITEA) ? 1 : 0; 1765f08c3bdfSopenharmony_ci wrec.w_oflags = oflags; 1766f08c3bdfSopenharmony_ci wrec.w_pid = pid; 1767f08c3bdfSopenharmony_ci wrec.w_offset = offset; 1768f08c3bdfSopenharmony_ci wrec.w_nbytes = nbytes; 1769f08c3bdfSopenharmony_ci 1770f08c3bdfSopenharmony_ci wrec.w_pathlen = strlen(file); 1771f08c3bdfSopenharmony_ci memcpy(wrec.w_path, file, wrec.w_pathlen); 1772f08c3bdfSopenharmony_ci wrec.w_hostlen = strlen(Host); 1773f08c3bdfSopenharmony_ci memcpy(wrec.w_host, Host, wrec.w_hostlen); 1774f08c3bdfSopenharmony_ci wrec.w_patternlen = Pattern_Length; 1775f08c3bdfSopenharmony_ci memcpy(wrec.w_pattern, Pattern, wrec.w_patternlen); 1776f08c3bdfSopenharmony_ci 1777f08c3bdfSopenharmony_ci wrec.w_done = 0; 1778f08c3bdfSopenharmony_ci 1779f08c3bdfSopenharmony_ci if ((woffset = wlog_record_write(&Wlog, &wrec, -1)) == -1) { 1780f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1781f08c3bdfSopenharmony_ci "Could not append to write-log: %s (%d)\n", 1782f08c3bdfSopenharmony_ci SYSERR, errno); 1783f08c3bdfSopenharmony_ci } else { 1784f08c3bdfSopenharmony_ci logged_write = 1; 1785f08c3bdfSopenharmony_ci } 1786f08c3bdfSopenharmony_ci } 1787f08c3bdfSopenharmony_ci 1788f08c3bdfSopenharmony_ci switch (req->r_type) { 1789f08c3bdfSopenharmony_ci case WRITE: 1790f08c3bdfSopenharmony_ci /* 1791f08c3bdfSopenharmony_ci * sync write 1792f08c3bdfSopenharmony_ci */ 1793f08c3bdfSopenharmony_ci 1794f08c3bdfSopenharmony_ci if (lseek(fd, offset, SEEK_SET) == -1) { 1795f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1796f08c3bdfSopenharmony_ci "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n", 1797f08c3bdfSopenharmony_ci fd, offset, SYSERR, errno); 1798f08c3bdfSopenharmony_ci return -1; 1799f08c3bdfSopenharmony_ci } 1800f08c3bdfSopenharmony_ci 1801f08c3bdfSopenharmony_ci rval = write(fd, addr, nbytes); 1802f08c3bdfSopenharmony_ci 1803f08c3bdfSopenharmony_ci if (rval == -1) { 1804f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1805f08c3bdfSopenharmony_ci "write() failed: %s (%d)\n%s\n", 1806f08c3bdfSopenharmony_ci SYSERR, errno, 1807f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, Pattern, 1808f08c3bdfSopenharmony_ci NULL)); 1809f08c3bdfSopenharmony_ci#ifdef sgi 1810f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1811f08c3bdfSopenharmony_ci "write() failed: %s\n\twrite(%d, %#o, %d)\n\toffset %d, nbytes%%miniou(%d)=%d, oflags=%#o memalign=%d, addr%%memalign=%d\n", 1812f08c3bdfSopenharmony_ci strerror(errno), 1813f08c3bdfSopenharmony_ci fd, addr, nbytes, 1814f08c3bdfSopenharmony_ci offset, 1815f08c3bdfSopenharmony_ci fdc->c_miniosz, nbytes % fdc->c_miniosz, 1816f08c3bdfSopenharmony_ci oflags, fdc->c_memalign, 1817f08c3bdfSopenharmony_ci (long)addr % fdc->c_memalign); 1818f08c3bdfSopenharmony_ci#else 1819f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1820f08c3bdfSopenharmony_ci "write() failed: %s\n\twrite(%d, %#o, %d)\n\toffset %d, nbytes%%1B=%d, oflags=%#o\n", 1821f08c3bdfSopenharmony_ci strerror(errno), 1822f08c3bdfSopenharmony_ci fd, addr, nbytes, 1823f08c3bdfSopenharmony_ci offset, nbytes % 4096, oflags); 1824f08c3bdfSopenharmony_ci#endif 1825f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1826f08c3bdfSopenharmony_ci } else if (rval != nbytes) { 1827f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1828f08c3bdfSopenharmony_ci "write() returned wrong # bytes - expected %d, got %d\n%s\n", 1829f08c3bdfSopenharmony_ci nbytes, rval, 1830f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, Pattern, 1831f08c3bdfSopenharmony_ci NULL)); 1832f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1833f08c3bdfSopenharmony_ci rval = -1; 1834f08c3bdfSopenharmony_ci } 1835f08c3bdfSopenharmony_ci 1836f08c3bdfSopenharmony_ci break; 1837f08c3bdfSopenharmony_ci 1838f08c3bdfSopenharmony_ci#ifdef CRAY 1839f08c3bdfSopenharmony_ci case WRITEA: 1840f08c3bdfSopenharmony_ci /* 1841f08c3bdfSopenharmony_ci * async write 1842f08c3bdfSopenharmony_ci */ 1843f08c3bdfSopenharmony_ci if (lseek(fd, offset, SEEK_SET) == -1) { 1844f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1845f08c3bdfSopenharmony_ci "lseek(%d, %d, SEEK_SET) failed: %s (%d)\n", 1846f08c3bdfSopenharmony_ci fd, offset, SYSERR, errno); 1847f08c3bdfSopenharmony_ci return -1; 1848f08c3bdfSopenharmony_ci } 1849f08c3bdfSopenharmony_ci 1850f08c3bdfSopenharmony_ci aio_strat = req->r_data.write.r_aio_strat; 1851f08c3bdfSopenharmony_ci signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0; 1852f08c3bdfSopenharmony_ci 1853f08c3bdfSopenharmony_ci aio_id = aio_register(fd, aio_strat, signo); 1854f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 1855f08c3bdfSopenharmony_ci 1856f08c3bdfSopenharmony_ci /* 1857f08c3bdfSopenharmony_ci * init iosw and do the async write 1858f08c3bdfSopenharmony_ci */ 1859f08c3bdfSopenharmony_ci 1860f08c3bdfSopenharmony_ci if (writea(fd, addr, nbytes, &aiop->iosw, signo) == -1) { 1861f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1862f08c3bdfSopenharmony_ci "writea() failed: %s (%d)\n%s\n", 1863f08c3bdfSopenharmony_ci SYSERR, errno, 1864f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, Pattern, 1865f08c3bdfSopenharmony_ci NULL)); 1866f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 1867f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1868f08c3bdfSopenharmony_ci rval = -1; 1869f08c3bdfSopenharmony_ci } else { 1870f08c3bdfSopenharmony_ci 1871f08c3bdfSopenharmony_ci /* 1872f08c3bdfSopenharmony_ci * Wait for io to complete 1873f08c3bdfSopenharmony_ci */ 1874f08c3bdfSopenharmony_ci 1875f08c3bdfSopenharmony_ci aio_wait(aio_id); 1876f08c3bdfSopenharmony_ci 1877f08c3bdfSopenharmony_ci /* 1878f08c3bdfSopenharmony_ci * check that iosw is ok 1879f08c3bdfSopenharmony_ci */ 1880f08c3bdfSopenharmony_ci 1881f08c3bdfSopenharmony_ci if (aiop->iosw.sw_count != nbytes) { 1882f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1883f08c3bdfSopenharmony_ci "Bad iosw from writea()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n", 1884f08c3bdfSopenharmony_ci 1, 0, nbytes, 1885f08c3bdfSopenharmony_ci aiop->iosw.sw_flag, 1886f08c3bdfSopenharmony_ci aiop->iosw.sw_error, 1887f08c3bdfSopenharmony_ci aiop->iosw.sw_count, 1888f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, 1889f08c3bdfSopenharmony_ci Pattern, &aiop->iosw)); 1890f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1891f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 1892f08c3bdfSopenharmony_ci rval = -1; 1893f08c3bdfSopenharmony_ci } else { 1894f08c3bdfSopenharmony_ci aio_unregister(aio_id); 1895f08c3bdfSopenharmony_ci rval = 0; 1896f08c3bdfSopenharmony_ci } 1897f08c3bdfSopenharmony_ci } 1898f08c3bdfSopenharmony_ci break; 1899f08c3bdfSopenharmony_ci 1900f08c3bdfSopenharmony_ci#endif /* CRAY */ 1901f08c3bdfSopenharmony_ci } 1902f08c3bdfSopenharmony_ci 1903f08c3bdfSopenharmony_ci /* 1904f08c3bdfSopenharmony_ci * Verify that the data was written correctly - check_file() returns 1905f08c3bdfSopenharmony_ci * a non-null pointer which contains an error message if there are 1906f08c3bdfSopenharmony_ci * problems. 1907f08c3bdfSopenharmony_ci */ 1908f08c3bdfSopenharmony_ci 1909f08c3bdfSopenharmony_ci if (v_opt) { 1910f08c3bdfSopenharmony_ci msg = check_file(file, offset, nbytes, Pattern, Pattern_Length, 1911f08c3bdfSopenharmony_ci 0, oflags & O_PARALLEL); 1912f08c3bdfSopenharmony_ci if (msg != NULL) { 1913f08c3bdfSopenharmony_ci doio_fprintf(stderr, "%s%s\n", msg, 1914f08c3bdfSopenharmony_ci#ifdef CRAY 1915f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, Pattern, 1916f08c3bdfSopenharmony_ci &aiop->iosw) 1917f08c3bdfSopenharmony_ci#else 1918f08c3bdfSopenharmony_ci format_rw(req, fd, addr, -1, Pattern, NULL) 1919f08c3bdfSopenharmony_ci#endif 1920f08c3bdfSopenharmony_ci ); 1921f08c3bdfSopenharmony_ci doio_upanic(U_CORRUPTION); 1922f08c3bdfSopenharmony_ci exit(E_COMPARE); 1923f08c3bdfSopenharmony_ci 1924f08c3bdfSopenharmony_ci } 1925f08c3bdfSopenharmony_ci } 1926f08c3bdfSopenharmony_ci 1927f08c3bdfSopenharmony_ci /* 1928f08c3bdfSopenharmony_ci * General cleanup ... 1929f08c3bdfSopenharmony_ci * 1930f08c3bdfSopenharmony_ci * Write extent information to the write-log, so that doio_check can do 1931f08c3bdfSopenharmony_ci * corruption detection. Note that w_done is set to 1, indicating that 1932f08c3bdfSopenharmony_ci * the write has been verified as complete. We don't need to write the 1933f08c3bdfSopenharmony_ci * filename on the second logging. 1934f08c3bdfSopenharmony_ci */ 1935f08c3bdfSopenharmony_ci 1936f08c3bdfSopenharmony_ci if (w_opt && logged_write) { 1937f08c3bdfSopenharmony_ci wrec.w_done = 1; 1938f08c3bdfSopenharmony_ci wlog_record_write(&Wlog, &wrec, woffset); 1939f08c3bdfSopenharmony_ci } 1940f08c3bdfSopenharmony_ci 1941f08c3bdfSopenharmony_ci /* 1942f08c3bdfSopenharmony_ci * Unlock file region if necessary 1943f08c3bdfSopenharmony_ci */ 1944f08c3bdfSopenharmony_ci 1945f08c3bdfSopenharmony_ci if (got_lock) { 1946f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_UNLCK, offset, nbytes) < 0) { 1947f08c3bdfSopenharmony_ci alloc_mem(-1); 1948f08c3bdfSopenharmony_ci exit(E_INTERNAL); 1949f08c3bdfSopenharmony_ci } 1950f08c3bdfSopenharmony_ci } 1951f08c3bdfSopenharmony_ci 1952f08c3bdfSopenharmony_ci return ((rval == -1) ? -1 : 0); 1953f08c3bdfSopenharmony_ci} 1954f08c3bdfSopenharmony_ci 1955f08c3bdfSopenharmony_ci/* 1956f08c3bdfSopenharmony_ci * Simple routine to lock/unlock a file using fcntl() 1957f08c3bdfSopenharmony_ci */ 1958f08c3bdfSopenharmony_ci 1959f08c3bdfSopenharmony_ciint lock_file_region(char *fname, int fd, int type, int start, int nbytes) 1960f08c3bdfSopenharmony_ci{ 1961f08c3bdfSopenharmony_ci struct flock flk; 1962f08c3bdfSopenharmony_ci 1963f08c3bdfSopenharmony_ci flk.l_type = type; 1964f08c3bdfSopenharmony_ci flk.l_whence = 0; 1965f08c3bdfSopenharmony_ci flk.l_start = start; 1966f08c3bdfSopenharmony_ci flk.l_len = nbytes; 1967f08c3bdfSopenharmony_ci 1968f08c3bdfSopenharmony_ci if (fcntl(fd, F_SETLKW, &flk) < 0) { 1969f08c3bdfSopenharmony_ci doio_fprintf(stderr, 1970f08c3bdfSopenharmony_ci "fcntl(%d, %d, %#o) failed for file %s, lock type %d, offset %d, length %d: %s (%d), open flags: %#o\n", 1971f08c3bdfSopenharmony_ci fd, F_SETLKW, &flk, fname, type, 1972f08c3bdfSopenharmony_ci start, nbytes, SYSERR, errno, 1973f08c3bdfSopenharmony_ci fcntl(fd, F_GETFL, 0)); 1974f08c3bdfSopenharmony_ci return -1; 1975f08c3bdfSopenharmony_ci } 1976f08c3bdfSopenharmony_ci 1977f08c3bdfSopenharmony_ci return 0; 1978f08c3bdfSopenharmony_ci} 1979f08c3bdfSopenharmony_ci 1980f08c3bdfSopenharmony_ci/* 1981f08c3bdfSopenharmony_ci * Perform a listio request. 1982f08c3bdfSopenharmony_ci */ 1983f08c3bdfSopenharmony_ci 1984f08c3bdfSopenharmony_ci#ifdef CRAY 1985f08c3bdfSopenharmony_cichar *format_listio(struct io_req *ioreq, int lcmd, struct listreq *list, 1986f08c3bdfSopenharmony_ci int nent, int fd, char *pattern) 1987f08c3bdfSopenharmony_ci{ 1988f08c3bdfSopenharmony_ci static char *errbuf = NULL; 1989f08c3bdfSopenharmony_ci struct listio_req *liop = &ioreq->r_data.listio; 1990f08c3bdfSopenharmony_ci struct listreq *listreq; 1991f08c3bdfSopenharmony_ci char *cp, *cmd, *opcode, *aio_strat; 1992f08c3bdfSopenharmony_ci int i; 1993f08c3bdfSopenharmony_ci 1994f08c3bdfSopenharmony_ci switch (lcmd) { 1995f08c3bdfSopenharmony_ci case LC_START: 1996f08c3bdfSopenharmony_ci cmd = "LC_START"; 1997f08c3bdfSopenharmony_ci break; 1998f08c3bdfSopenharmony_ci case LC_WAIT: 1999f08c3bdfSopenharmony_ci cmd = "LC_WAIT"; 2000f08c3bdfSopenharmony_ci break; 2001f08c3bdfSopenharmony_ci default: 2002f08c3bdfSopenharmony_ci cmd = "???"; 2003f08c3bdfSopenharmony_ci break; 2004f08c3bdfSopenharmony_ci } 2005f08c3bdfSopenharmony_ci 2006f08c3bdfSopenharmony_ci if (errbuf == NULL) 2007f08c3bdfSopenharmony_ci errbuf = malloc(32768); 2008f08c3bdfSopenharmony_ci 2009f08c3bdfSopenharmony_ci cp = errbuf; 2010f08c3bdfSopenharmony_ci cp += sprintf(cp, "Request number %d\n", Reqno); 2011f08c3bdfSopenharmony_ci 2012f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: listio(%s, %#o, %d)\n\n", cmd, list, nent); 2013f08c3bdfSopenharmony_ci 2014f08c3bdfSopenharmony_ci aio_strat = format_strat(liop->r_aio_strat); 2015f08c3bdfSopenharmony_ci 2016f08c3bdfSopenharmony_ci for (i = 0; i < nent; i++) { 2017f08c3bdfSopenharmony_ci cp += sprintf(cp, "struct lioreq for request element %d\n", i); 2018f08c3bdfSopenharmony_ci cp += sprintf(cp, "----------------------------------------\n"); 2019f08c3bdfSopenharmony_ci 2020f08c3bdfSopenharmony_ci listreq = list + i; 2021f08c3bdfSopenharmony_ci 2022f08c3bdfSopenharmony_ci switch (listreq->li_opcode) { 2023f08c3bdfSopenharmony_ci case LO_READ: 2024f08c3bdfSopenharmony_ci opcode = "LO_READ"; 2025f08c3bdfSopenharmony_ci break; 2026f08c3bdfSopenharmony_ci case LO_WRITE: 2027f08c3bdfSopenharmony_ci opcode = "LO_WRITE"; 2028f08c3bdfSopenharmony_ci break; 2029f08c3bdfSopenharmony_ci default: 2030f08c3bdfSopenharmony_ci opcode = "???"; 2031f08c3bdfSopenharmony_ci break; 2032f08c3bdfSopenharmony_ci } 2033f08c3bdfSopenharmony_ci 2034f08c3bdfSopenharmony_ci cp += sprintf(cp, " li_opcode = %s\n", opcode); 2035f08c3bdfSopenharmony_ci cp += 2036f08c3bdfSopenharmony_ci sprintf(cp, " li_drvr = %#o\n", 2037f08c3bdfSopenharmony_ci listreq->li_drvr); 2038f08c3bdfSopenharmony_ci cp += 2039f08c3bdfSopenharmony_ci sprintf(cp, " li_flags = %#o\n", 2040f08c3bdfSopenharmony_ci listreq->li_flags); 2041f08c3bdfSopenharmony_ci cp += 2042f08c3bdfSopenharmony_ci sprintf(cp, " li_offset = %d\n", 2043f08c3bdfSopenharmony_ci listreq->li_offset); 2044f08c3bdfSopenharmony_ci cp += 2045f08c3bdfSopenharmony_ci sprintf(cp, " li_fildes = %d\n", 2046f08c3bdfSopenharmony_ci listreq->li_fildes); 2047f08c3bdfSopenharmony_ci cp += 2048f08c3bdfSopenharmony_ci sprintf(cp, " li_buf = %#o\n", 2049f08c3bdfSopenharmony_ci listreq->li_buf); 2050f08c3bdfSopenharmony_ci cp += 2051f08c3bdfSopenharmony_ci sprintf(cp, " li_nbyte = %d\n", 2052f08c3bdfSopenharmony_ci listreq->li_nbyte); 2053f08c3bdfSopenharmony_ci cp += 2054f08c3bdfSopenharmony_ci sprintf(cp, " li_status = %#o (%d, %d, %d)\n", 2055f08c3bdfSopenharmony_ci listreq->li_status, listreq->li_status->sw_flag, 2056f08c3bdfSopenharmony_ci listreq->li_status->sw_error, 2057f08c3bdfSopenharmony_ci listreq->li_status->sw_count); 2058f08c3bdfSopenharmony_ci cp += 2059f08c3bdfSopenharmony_ci sprintf(cp, " li_signo = %d\n", 2060f08c3bdfSopenharmony_ci listreq->li_signo); 2061f08c3bdfSopenharmony_ci cp += 2062f08c3bdfSopenharmony_ci sprintf(cp, " li_nstride = %d\n", 2063f08c3bdfSopenharmony_ci listreq->li_nstride); 2064f08c3bdfSopenharmony_ci cp += 2065f08c3bdfSopenharmony_ci sprintf(cp, " li_filstride = %d\n", 2066f08c3bdfSopenharmony_ci listreq->li_filstride); 2067f08c3bdfSopenharmony_ci cp += 2068f08c3bdfSopenharmony_ci sprintf(cp, " li_memstride = %d\n", 2069f08c3bdfSopenharmony_ci listreq->li_memstride); 2070f08c3bdfSopenharmony_ci cp += 2071f08c3bdfSopenharmony_ci sprintf(cp, " io completion strategy is %s\n", 2072f08c3bdfSopenharmony_ci aio_strat); 2073f08c3bdfSopenharmony_ci } 2074f08c3bdfSopenharmony_ci return errbuf; 2075f08c3bdfSopenharmony_ci} 2076f08c3bdfSopenharmony_ci#endif /* CRAY */ 2077f08c3bdfSopenharmony_ci 2078f08c3bdfSopenharmony_ciint do_listio(struct io_req *req) 2079f08c3bdfSopenharmony_ci{ 2080f08c3bdfSopenharmony_ci#ifdef CRAY 2081f08c3bdfSopenharmony_ci struct listio_req *lio; 2082f08c3bdfSopenharmony_ci int fd, oflags, signo, nb, i; 2083f08c3bdfSopenharmony_ci int logged_write, rval, got_lock; 2084f08c3bdfSopenharmony_ci int aio_strat, aio_id; 2085f08c3bdfSopenharmony_ci int min_byte, max_byte; 2086f08c3bdfSopenharmony_ci int mem_needed; 2087f08c3bdfSopenharmony_ci int foffset, fstride, mstride, nstrides; 2088f08c3bdfSopenharmony_ci char *moffset; 2089f08c3bdfSopenharmony_ci long offset, woffset; 2090f08c3bdfSopenharmony_ci char *addr, *msg; 2091f08c3bdfSopenharmony_ci sigset_t block_mask, omask; 2092f08c3bdfSopenharmony_ci struct wlog_rec wrec; 2093f08c3bdfSopenharmony_ci struct aio_info *aiop; 2094f08c3bdfSopenharmony_ci struct listreq lio_req; 2095f08c3bdfSopenharmony_ci 2096f08c3bdfSopenharmony_ci lio = &req->r_data.listio; 2097f08c3bdfSopenharmony_ci 2098f08c3bdfSopenharmony_ci /* 2099f08c3bdfSopenharmony_ci * If bytes per stride is less than the stride size, drop the request 2100f08c3bdfSopenharmony_ci * since it will cause overlapping strides, and we cannot predict 2101f08c3bdfSopenharmony_ci * the order they will complete in. 2102f08c3bdfSopenharmony_ci */ 2103f08c3bdfSopenharmony_ci 2104f08c3bdfSopenharmony_ci if (lio->r_filestride && abs(lio->r_filestride) < lio->r_nbytes) { 2105f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2106f08c3bdfSopenharmony_ci "do_listio(): Bogus listio request - abs(filestride) [%d] < nbytes [%d]\n", 2107f08c3bdfSopenharmony_ci abs(lio->r_filestride), lio->r_nbytes); 2108f08c3bdfSopenharmony_ci return -1; 2109f08c3bdfSopenharmony_ci } 2110f08c3bdfSopenharmony_ci 2111f08c3bdfSopenharmony_ci /* 2112f08c3bdfSopenharmony_ci * Allocate core memory. Initialize the data to be written. Make 2113f08c3bdfSopenharmony_ci * sure we get enough, based on the memstride. 2114f08c3bdfSopenharmony_ci */ 2115f08c3bdfSopenharmony_ci 2116f08c3bdfSopenharmony_ci mem_needed = 2117f08c3bdfSopenharmony_ci stride_bounds(0, lio->r_memstride, lio->r_nstrides, 2118f08c3bdfSopenharmony_ci lio->r_nbytes, NULL, NULL); 2119f08c3bdfSopenharmony_ci 2120f08c3bdfSopenharmony_ci if ((rval = alloc_mem(mem_needed + wtob(1))) < 0) { 2121f08c3bdfSopenharmony_ci return rval; 2122f08c3bdfSopenharmony_ci } 2123f08c3bdfSopenharmony_ci 2124f08c3bdfSopenharmony_ci /* 2125f08c3bdfSopenharmony_ci * Set the memory address pointer. If the io is not raw, adjust 2126f08c3bdfSopenharmony_ci * addr by a random amount, so that non-raw io is not necessarily 2127f08c3bdfSopenharmony_ci * word aligned. 2128f08c3bdfSopenharmony_ci */ 2129f08c3bdfSopenharmony_ci 2130f08c3bdfSopenharmony_ci addr = Memptr; 2131f08c3bdfSopenharmony_ci 2132f08c3bdfSopenharmony_ci if (!(lio->r_uflags & F_WORD_ALIGNED)) { 2133f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 2134f08c3bdfSopenharmony_ci } 2135f08c3bdfSopenharmony_ci 2136f08c3bdfSopenharmony_ci if (lio->r_opcode == LO_WRITE) { 2137f08c3bdfSopenharmony_ci Pattern[0] = lio->r_pattern; 2138f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, mem_needed, Pattern, Pattern_Length, 0); 2139f08c3bdfSopenharmony_ci if (addr != Memptr) 2140f08c3bdfSopenharmony_ci memmove(addr, Memptr, mem_needed); 2141f08c3bdfSopenharmony_ci } 2142f08c3bdfSopenharmony_ci 2143f08c3bdfSopenharmony_ci /* 2144f08c3bdfSopenharmony_ci * Get a descriptor to do the io on. No need to do an lseek, as this 2145f08c3bdfSopenharmony_ci * is encoded in the listio request. 2146f08c3bdfSopenharmony_ci */ 2147f08c3bdfSopenharmony_ci 2148f08c3bdfSopenharmony_ci if ((fd = alloc_fd(lio->r_file, lio->r_oflags)) == -1) { 2149f08c3bdfSopenharmony_ci return -1; 2150f08c3bdfSopenharmony_ci } 2151f08c3bdfSopenharmony_ci 2152f08c3bdfSopenharmony_ci rval = -1; 2153f08c3bdfSopenharmony_ci got_lock = 0; 2154f08c3bdfSopenharmony_ci logged_write = 0; 2155f08c3bdfSopenharmony_ci 2156f08c3bdfSopenharmony_ci /* 2157f08c3bdfSopenharmony_ci * If the opcode is LO_WRITE, lock all regions of the file that 2158f08c3bdfSopenharmony_ci * are touched by this listio request. Currently, we use 2159f08c3bdfSopenharmony_ci * stride_bounds() to figure out the min and max bytes affected, and 2160f08c3bdfSopenharmony_ci * lock the entire region, regardless of the file stride. 2161f08c3bdfSopenharmony_ci */ 2162f08c3bdfSopenharmony_ci 2163f08c3bdfSopenharmony_ci if (lio->r_opcode == LO_WRITE && k_opt) { 2164f08c3bdfSopenharmony_ci stride_bounds(lio->r_offset, 2165f08c3bdfSopenharmony_ci lio->r_filestride, lio->r_nstrides, 2166f08c3bdfSopenharmony_ci lio->r_nbytes, &min_byte, &max_byte); 2167f08c3bdfSopenharmony_ci 2168f08c3bdfSopenharmony_ci if (lock_file_region(lio->r_file, fd, F_WRLCK, 2169f08c3bdfSopenharmony_ci min_byte, (max_byte - min_byte + 1)) < 0) { 2170f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2171f08c3bdfSopenharmony_ci "stride_bounds(%d, %d, %d, %d, ..., ...) set min_byte to %d, max_byte to %d\n", 2172f08c3bdfSopenharmony_ci lio->r_offset, lio->r_filestride, 2173f08c3bdfSopenharmony_ci lio->r_nstrides, lio->r_nbytes, min_byte, 2174f08c3bdfSopenharmony_ci max_byte); 2175f08c3bdfSopenharmony_ci return -1; 2176f08c3bdfSopenharmony_ci } else { 2177f08c3bdfSopenharmony_ci got_lock = 1; 2178f08c3bdfSopenharmony_ci } 2179f08c3bdfSopenharmony_ci } 2180f08c3bdfSopenharmony_ci 2181f08c3bdfSopenharmony_ci /* 2182f08c3bdfSopenharmony_ci * async write 2183f08c3bdfSopenharmony_ci */ 2184f08c3bdfSopenharmony_ci 2185f08c3bdfSopenharmony_ci aio_strat = lio->r_aio_strat; 2186f08c3bdfSopenharmony_ci signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0; 2187f08c3bdfSopenharmony_ci 2188f08c3bdfSopenharmony_ci aio_id = aio_register(fd, aio_strat, signo); 2189f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 2190f08c3bdfSopenharmony_ci 2191f08c3bdfSopenharmony_ci /* 2192f08c3bdfSopenharmony_ci * Form the listio request, and make the call. 2193f08c3bdfSopenharmony_ci */ 2194f08c3bdfSopenharmony_ci 2195f08c3bdfSopenharmony_ci lio_req.li_opcode = lio->r_opcode; 2196f08c3bdfSopenharmony_ci lio_req.li_drvr = 0; 2197f08c3bdfSopenharmony_ci lio_req.li_flags = LF_LSEEK; 2198f08c3bdfSopenharmony_ci lio_req.li_offset = lio->r_offset; 2199f08c3bdfSopenharmony_ci lio_req.li_fildes = fd; 2200f08c3bdfSopenharmony_ci 2201f08c3bdfSopenharmony_ci if (lio->r_memstride >= 0 || lio->r_nstrides <= 1) { 2202f08c3bdfSopenharmony_ci lio_req.li_buf = addr; 2203f08c3bdfSopenharmony_ci } else { 2204f08c3bdfSopenharmony_ci lio_req.li_buf = addr + mem_needed - lio->r_nbytes; 2205f08c3bdfSopenharmony_ci } 2206f08c3bdfSopenharmony_ci 2207f08c3bdfSopenharmony_ci lio_req.li_nbyte = lio->r_nbytes; 2208f08c3bdfSopenharmony_ci lio_req.li_status = &aiop->iosw; 2209f08c3bdfSopenharmony_ci lio_req.li_signo = signo; 2210f08c3bdfSopenharmony_ci lio_req.li_nstride = lio->r_nstrides; 2211f08c3bdfSopenharmony_ci lio_req.li_filstride = lio->r_filestride; 2212f08c3bdfSopenharmony_ci lio_req.li_memstride = lio->r_memstride; 2213f08c3bdfSopenharmony_ci 2214f08c3bdfSopenharmony_ci /* 2215f08c3bdfSopenharmony_ci * If signo != 0, block signo while we're in the system call, so that 2216f08c3bdfSopenharmony_ci * we don't get interrupted syscall failures. 2217f08c3bdfSopenharmony_ci */ 2218f08c3bdfSopenharmony_ci 2219f08c3bdfSopenharmony_ci if (signo) { 2220f08c3bdfSopenharmony_ci sigemptyset(&block_mask); 2221f08c3bdfSopenharmony_ci sigaddset(&block_mask, signo); 2222f08c3bdfSopenharmony_ci sigprocmask(SIG_BLOCK, &block_mask, &omask); 2223f08c3bdfSopenharmony_ci } 2224f08c3bdfSopenharmony_ci 2225f08c3bdfSopenharmony_ci if (listio(lio->r_cmd, &lio_req, 1) < 0) { 2226f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2227f08c3bdfSopenharmony_ci "listio() failed: %s (%d)\n%s\n", 2228f08c3bdfSopenharmony_ci SYSERR, errno, 2229f08c3bdfSopenharmony_ci format_listio(req, lio->r_cmd, &lio_req, 1, fd, 2230f08c3bdfSopenharmony_ci Pattern)); 2231f08c3bdfSopenharmony_ci aio_unregister(aio_id); 2232f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 2233f08c3bdfSopenharmony_ci goto lio_done; 2234f08c3bdfSopenharmony_ci } 2235f08c3bdfSopenharmony_ci 2236f08c3bdfSopenharmony_ci if (signo) { 2237f08c3bdfSopenharmony_ci sigprocmask(SIG_SETMASK, &omask, NULL); 2238f08c3bdfSopenharmony_ci } 2239f08c3bdfSopenharmony_ci 2240f08c3bdfSopenharmony_ci /* 2241f08c3bdfSopenharmony_ci * Wait for io to complete 2242f08c3bdfSopenharmony_ci */ 2243f08c3bdfSopenharmony_ci 2244f08c3bdfSopenharmony_ci aio_wait(aio_id); 2245f08c3bdfSopenharmony_ci 2246f08c3bdfSopenharmony_ci nstrides = lio->r_nstrides ? lio->r_nstrides : 1; 2247f08c3bdfSopenharmony_ci if (aiop->iosw.sw_count != lio->r_nbytes * nstrides) { 2248f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2249f08c3bdfSopenharmony_ci "Bad iosw from listio()\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n", 2250f08c3bdfSopenharmony_ci 1, 0, lio->r_nbytes * lio->r_nstrides, 2251f08c3bdfSopenharmony_ci aiop->iosw.sw_flag, 2252f08c3bdfSopenharmony_ci aiop->iosw.sw_error, aiop->iosw.sw_count, 2253f08c3bdfSopenharmony_ci format_listio(req, lio->r_cmd, &lio_req, 1, fd, 2254f08c3bdfSopenharmony_ci Pattern)); 2255f08c3bdfSopenharmony_ci aio_unregister(aio_id); 2256f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 2257f08c3bdfSopenharmony_ci goto lio_done; 2258f08c3bdfSopenharmony_ci } 2259f08c3bdfSopenharmony_ci 2260f08c3bdfSopenharmony_ci aio_unregister(aio_id); 2261f08c3bdfSopenharmony_ci 2262f08c3bdfSopenharmony_ci /* 2263f08c3bdfSopenharmony_ci * Verify that the data was written correctly - check_file() returns 2264f08c3bdfSopenharmony_ci * a non-null pointer which contains an error message if there are 2265f08c3bdfSopenharmony_ci * problems. 2266f08c3bdfSopenharmony_ci * 2267f08c3bdfSopenharmony_ci * For listio, we basically have to make 1 call to check_file for each 2268f08c3bdfSopenharmony_ci * stride. 2269f08c3bdfSopenharmony_ci */ 2270f08c3bdfSopenharmony_ci 2271f08c3bdfSopenharmony_ci if (v_opt && lio_req.li_opcode == LO_WRITE) { 2272f08c3bdfSopenharmony_ci fstride = lio->r_filestride ? lio->r_filestride : lio->r_nbytes; 2273f08c3bdfSopenharmony_ci mstride = lio->r_memstride ? lio->r_memstride : lio->r_nbytes; 2274f08c3bdfSopenharmony_ci foffset = lio->r_offset; 2275f08c3bdfSopenharmony_ci 2276f08c3bdfSopenharmony_ci if (mstride > 0 || lio->r_nstrides <= 1) { 2277f08c3bdfSopenharmony_ci moffset = addr; 2278f08c3bdfSopenharmony_ci } else { 2279f08c3bdfSopenharmony_ci moffset = addr + mem_needed - lio->r_nbytes; 2280f08c3bdfSopenharmony_ci } 2281f08c3bdfSopenharmony_ci 2282f08c3bdfSopenharmony_ci for (i = 0; i < lio_req.li_nstride; i++) { 2283f08c3bdfSopenharmony_ci msg = check_file(lio->r_file, 2284f08c3bdfSopenharmony_ci foffset, lio->r_nbytes, 2285f08c3bdfSopenharmony_ci Pattern, Pattern_Length, 2286f08c3bdfSopenharmony_ci moffset - addr, 2287f08c3bdfSopenharmony_ci lio->r_oflags & O_PARALLEL); 2288f08c3bdfSopenharmony_ci 2289f08c3bdfSopenharmony_ci if (msg != NULL) { 2290f08c3bdfSopenharmony_ci doio_fprintf(stderr, "%s\n%s\n", 2291f08c3bdfSopenharmony_ci msg, 2292f08c3bdfSopenharmony_ci format_listio(req, lio->r_cmd, 2293f08c3bdfSopenharmony_ci &lio_req, 1, fd, 2294f08c3bdfSopenharmony_ci Pattern)); 2295f08c3bdfSopenharmony_ci doio_upanic(U_CORRUPTION); 2296f08c3bdfSopenharmony_ci exit(E_COMPARE); 2297f08c3bdfSopenharmony_ci } 2298f08c3bdfSopenharmony_ci 2299f08c3bdfSopenharmony_ci moffset += mstride; 2300f08c3bdfSopenharmony_ci foffset += fstride; 2301f08c3bdfSopenharmony_ci } 2302f08c3bdfSopenharmony_ci 2303f08c3bdfSopenharmony_ci } 2304f08c3bdfSopenharmony_ci 2305f08c3bdfSopenharmony_ci rval = 0; 2306f08c3bdfSopenharmony_ci 2307f08c3bdfSopenharmony_cilio_done: 2308f08c3bdfSopenharmony_ci 2309f08c3bdfSopenharmony_ci /* 2310f08c3bdfSopenharmony_ci * General cleanup ... 2311f08c3bdfSopenharmony_ci * 2312f08c3bdfSopenharmony_ci */ 2313f08c3bdfSopenharmony_ci 2314f08c3bdfSopenharmony_ci /* 2315f08c3bdfSopenharmony_ci * Release file locks if necessary 2316f08c3bdfSopenharmony_ci */ 2317f08c3bdfSopenharmony_ci 2318f08c3bdfSopenharmony_ci if (got_lock) { 2319f08c3bdfSopenharmony_ci if (lock_file_region(lio->r_file, fd, F_UNLCK, 2320f08c3bdfSopenharmony_ci min_byte, (max_byte - min_byte + 1)) < 0) { 2321f08c3bdfSopenharmony_ci return -1; 2322f08c3bdfSopenharmony_ci } 2323f08c3bdfSopenharmony_ci } 2324f08c3bdfSopenharmony_ci 2325f08c3bdfSopenharmony_ci return rval; 2326f08c3bdfSopenharmony_ci#else 2327f08c3bdfSopenharmony_ci return -1; 2328f08c3bdfSopenharmony_ci#endif 2329f08c3bdfSopenharmony_ci} 2330f08c3bdfSopenharmony_ci 2331f08c3bdfSopenharmony_ci/* 2332f08c3bdfSopenharmony_ci * perform ssread/sswrite operations 2333f08c3bdfSopenharmony_ci */ 2334f08c3bdfSopenharmony_ci 2335f08c3bdfSopenharmony_ci#ifdef _CRAY1 2336f08c3bdfSopenharmony_ci 2337f08c3bdfSopenharmony_ciint do_ssdio(struct io_req *req) 2338f08c3bdfSopenharmony_ci{ 2339f08c3bdfSopenharmony_ci int nbytes, nb; 2340f08c3bdfSopenharmony_ci char errbuf[BSIZE]; 2341f08c3bdfSopenharmony_ci 2342f08c3bdfSopenharmony_ci nbytes = req->r_data.ssread.r_nbytes; 2343f08c3bdfSopenharmony_ci 2344f08c3bdfSopenharmony_ci /* 2345f08c3bdfSopenharmony_ci * Grab core and sds space 2346f08c3bdfSopenharmony_ci */ 2347f08c3bdfSopenharmony_ci 2348f08c3bdfSopenharmony_ci if ((nb = alloc_mem(nbytes)) < 0) 2349f08c3bdfSopenharmony_ci return nb; 2350f08c3bdfSopenharmony_ci 2351f08c3bdfSopenharmony_ci if (alloc_sds(nbytes) == -1) 2352f08c3bdfSopenharmony_ci return -1; 2353f08c3bdfSopenharmony_ci 2354f08c3bdfSopenharmony_ci if (req->r_type == SSWRITE) { 2355f08c3bdfSopenharmony_ci 2356f08c3bdfSopenharmony_ci /* 2357f08c3bdfSopenharmony_ci * Init data and ship it to the ssd 2358f08c3bdfSopenharmony_ci */ 2359f08c3bdfSopenharmony_ci 2360f08c3bdfSopenharmony_ci Pattern[0] = req->r_data.sswrite.r_pattern; 2361f08c3bdfSopenharmony_ci /*pattern_fill(Memptr, nbytes, Pattern, Pattern_Length, 0); */ 2362f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 0); 2363f08c3bdfSopenharmony_ci 2364f08c3bdfSopenharmony_ci if (sswrite((long)Memptr, (long)Sdsptr, btoc(nbytes)) == -1) { 2365f08c3bdfSopenharmony_ci doio_fprintf(stderr, "sswrite() failed: %s (%d)\n%s\n", 2366f08c3bdfSopenharmony_ci SYSERR, errno, 2367f08c3bdfSopenharmony_ci format_sds(req, Memptr, Sdsptr, Pattern)); 2368f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 2369f08c3bdfSopenharmony_ci return -1; 2370f08c3bdfSopenharmony_ci } 2371f08c3bdfSopenharmony_ci } else { 2372f08c3bdfSopenharmony_ci /* 2373f08c3bdfSopenharmony_ci * read from sds 2374f08c3bdfSopenharmony_ci */ 2375f08c3bdfSopenharmony_ci 2376f08c3bdfSopenharmony_ci if (ssread((long)Memptr, (long)Sdsptr, btoc(nbytes)) == -1) { 2377f08c3bdfSopenharmony_ci doio_fprintf(stderr, "ssread() failed: %s (%d)\n%s\n", 2378f08c3bdfSopenharmony_ci SYSERR, errno, 2379f08c3bdfSopenharmony_ci format_sds(req, Memptr, Sdsptr, Pattern)); 2380f08c3bdfSopenharmony_ci 2381f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 2382f08c3bdfSopenharmony_ci return -1; 2383f08c3bdfSopenharmony_ci } 2384f08c3bdfSopenharmony_ci } 2385f08c3bdfSopenharmony_ci 2386f08c3bdfSopenharmony_ci /* 2387f08c3bdfSopenharmony_ci * Verify data if SSWRITE and v_opt 2388f08c3bdfSopenharmony_ci */ 2389f08c3bdfSopenharmony_ci 2390f08c3bdfSopenharmony_ci if (v_opt && req->r_type == SSWRITE) { 2391f08c3bdfSopenharmony_ci ssread((long)Memptr, (long)Sdsptr, btoc(nbytes)); 2392f08c3bdfSopenharmony_ci 2393f08c3bdfSopenharmony_ci if (pattern_check(Memptr, nbytes, Pattern, Pattern_Length, 0) == 2394f08c3bdfSopenharmony_ci -1) { 2395f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2396f08c3bdfSopenharmony_ci "sds DATA COMPARE ERROR - ABORTING\n%s\n", 2397f08c3bdfSopenharmony_ci format_sds(req, Memptr, Sdsptr, Pattern)); 2398f08c3bdfSopenharmony_ci 2399f08c3bdfSopenharmony_ci doio_upanic(U_CORRUPTION); 2400f08c3bdfSopenharmony_ci exit(E_COMPARE); 2401f08c3bdfSopenharmony_ci } 2402f08c3bdfSopenharmony_ci } 2403f08c3bdfSopenharmony_ci} 2404f08c3bdfSopenharmony_ci 2405f08c3bdfSopenharmony_ci#else 2406f08c3bdfSopenharmony_ci 2407f08c3bdfSopenharmony_ci#ifdef CRAY 2408f08c3bdfSopenharmony_ci 2409f08c3bdfSopenharmony_ciint do_ssdio(struct io_req *req) 2410f08c3bdfSopenharmony_ci{ 2411f08c3bdfSopenharmony_ci doio_fprintf(stderr, 2412f08c3bdfSopenharmony_ci "Internal Error - do_ssdio() called on a non-cray1 system\n"); 2413f08c3bdfSopenharmony_ci alloc_mem(-1); 2414f08c3bdfSopenharmony_ci exit(E_INTERNAL); 2415f08c3bdfSopenharmony_ci} 2416f08c3bdfSopenharmony_ci 2417f08c3bdfSopenharmony_ci#endif /* CRAY */ 2418f08c3bdfSopenharmony_ci 2419f08c3bdfSopenharmony_ci#endif /* _CRAY1 */ 2420f08c3bdfSopenharmony_ci 2421f08c3bdfSopenharmony_cichar *fmt_ioreq(struct io_req *ioreq, struct syscall_info *sy, int fd) 2422f08c3bdfSopenharmony_ci{ 2423f08c3bdfSopenharmony_ci static char *errbuf = NULL; 2424f08c3bdfSopenharmony_ci char *cp; 2425f08c3bdfSopenharmony_ci struct rw_req *io; 2426f08c3bdfSopenharmony_ci struct smap *aname; 2427f08c3bdfSopenharmony_ci#ifdef CRAY 2428f08c3bdfSopenharmony_ci struct stat sbuf; 2429f08c3bdfSopenharmony_ci#endif 2430f08c3bdfSopenharmony_ci#ifdef sgi 2431f08c3bdfSopenharmony_ci struct dioattr finfo; 2432f08c3bdfSopenharmony_ci#endif 2433f08c3bdfSopenharmony_ci 2434f08c3bdfSopenharmony_ci if (errbuf == NULL) 2435f08c3bdfSopenharmony_ci errbuf = malloc(32768); 2436f08c3bdfSopenharmony_ci 2437f08c3bdfSopenharmony_ci io = &ioreq->r_data.io; 2438f08c3bdfSopenharmony_ci 2439f08c3bdfSopenharmony_ci /* 2440f08c3bdfSopenharmony_ci * Look up async I/O completion strategy 2441f08c3bdfSopenharmony_ci */ 2442f08c3bdfSopenharmony_ci for (aname = aionames; 2443f08c3bdfSopenharmony_ci aname->value != -1 && aname->value != io->r_aio_strat; aname++) ; 2444f08c3bdfSopenharmony_ci 2445f08c3bdfSopenharmony_ci cp = errbuf; 2446f08c3bdfSopenharmony_ci cp += sprintf(cp, "Request number %d\n", Reqno); 2447f08c3bdfSopenharmony_ci 2448f08c3bdfSopenharmony_ci cp += 2449f08c3bdfSopenharmony_ci sprintf(cp, " fd %d is file %s - open flags are %#o %s\n", 2450f08c3bdfSopenharmony_ci fd, io->r_file, io->r_oflags, format_oflags(io->r_oflags)); 2451f08c3bdfSopenharmony_ci 2452f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_WRITE) { 2453f08c3bdfSopenharmony_ci cp += 2454f08c3bdfSopenharmony_ci sprintf(cp, 2455f08c3bdfSopenharmony_ci " write done at file offset %d - pattern is %c (%#o)\n", 2456f08c3bdfSopenharmony_ci io->r_offset, 2457f08c3bdfSopenharmony_ci (io->r_pattern == '\0') ? '?' : io->r_pattern, 2458f08c3bdfSopenharmony_ci io->r_pattern); 2459f08c3bdfSopenharmony_ci } else { 2460f08c3bdfSopenharmony_ci cp += sprintf(cp, " read done at file offset %d\n", 2461f08c3bdfSopenharmony_ci io->r_offset); 2462f08c3bdfSopenharmony_ci } 2463f08c3bdfSopenharmony_ci 2464f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_ASYNC) { 2465f08c3bdfSopenharmony_ci cp += 2466f08c3bdfSopenharmony_ci sprintf(cp, 2467f08c3bdfSopenharmony_ci " async io completion strategy is %s\n", 2468f08c3bdfSopenharmony_ci aname->string); 2469f08c3bdfSopenharmony_ci } 2470f08c3bdfSopenharmony_ci 2471f08c3bdfSopenharmony_ci cp += 2472f08c3bdfSopenharmony_ci sprintf(cp, 2473f08c3bdfSopenharmony_ci " number of requests is %d, strides per request is %d\n", 2474f08c3bdfSopenharmony_ci io->r_nent, io->r_nstrides); 2475f08c3bdfSopenharmony_ci 2476f08c3bdfSopenharmony_ci cp += sprintf(cp, " i/o byte count = %d\n", io->r_nbytes); 2477f08c3bdfSopenharmony_ci 2478f08c3bdfSopenharmony_ci cp += sprintf(cp, " memory alignment is %s\n", 2479f08c3bdfSopenharmony_ci (io-> 2480f08c3bdfSopenharmony_ci r_uflags & F_WORD_ALIGNED) ? "aligned" : "unaligned"); 2481f08c3bdfSopenharmony_ci 2482f08c3bdfSopenharmony_ci#ifdef CRAY 2483f08c3bdfSopenharmony_ci if (io->r_oflags & O_RAW) { 2484f08c3bdfSopenharmony_ci cp += 2485f08c3bdfSopenharmony_ci sprintf(cp, 2486f08c3bdfSopenharmony_ci " RAW I/O: offset %% 4096 = %d length %% 4096 = %d\n", 2487f08c3bdfSopenharmony_ci io->r_offset % 4096, io->r_nbytes % 4096); 2488f08c3bdfSopenharmony_ci fstat(fd, &sbuf); 2489f08c3bdfSopenharmony_ci cp += 2490f08c3bdfSopenharmony_ci sprintf(cp, 2491f08c3bdfSopenharmony_ci " optimal file xfer size: small: %d large: %d\n", 2492f08c3bdfSopenharmony_ci sbuf.st_blksize, sbuf.st_oblksize); 2493f08c3bdfSopenharmony_ci cp += 2494f08c3bdfSopenharmony_ci sprintf(cp, " cblks %d cbits %#o\n", sbuf.st_cblks, 2495f08c3bdfSopenharmony_ci sbuf.st_cbits); 2496f08c3bdfSopenharmony_ci } 2497f08c3bdfSopenharmony_ci#endif 2498f08c3bdfSopenharmony_ci#ifdef sgi 2499f08c3bdfSopenharmony_ci if (io->r_oflags & O_DIRECT) { 2500f08c3bdfSopenharmony_ci 2501f08c3bdfSopenharmony_ci if (fcntl(fd, F_DIOINFO, &finfo) == -1) { 2502f08c3bdfSopenharmony_ci cp += 2503f08c3bdfSopenharmony_ci sprintf(cp, 2504f08c3bdfSopenharmony_ci " Error %s (%d) getting direct I/O info\n", 2505f08c3bdfSopenharmony_ci strerror(errno), errno); 2506f08c3bdfSopenharmony_ci finfo.d_mem = 1; 2507f08c3bdfSopenharmony_ci finfo.d_miniosz = 1; 2508f08c3bdfSopenharmony_ci finfo.d_maxiosz = 1; 2509f08c3bdfSopenharmony_ci } 2510f08c3bdfSopenharmony_ci 2511f08c3bdfSopenharmony_ci cp += 2512f08c3bdfSopenharmony_ci sprintf(cp, 2513f08c3bdfSopenharmony_ci " DIRECT I/O: offset %% %d = %d length %% %d = %d\n", 2514f08c3bdfSopenharmony_ci finfo.d_miniosz, io->r_offset % finfo.d_miniosz, 2515f08c3bdfSopenharmony_ci io->r_nbytes, io->r_nbytes % finfo.d_miniosz); 2516f08c3bdfSopenharmony_ci cp += 2517f08c3bdfSopenharmony_ci sprintf(cp, 2518f08c3bdfSopenharmony_ci " mem alignment 0x%x xfer size: small: %d large: %d\n", 2519f08c3bdfSopenharmony_ci finfo.d_mem, finfo.d_miniosz, finfo.d_maxiosz); 2520f08c3bdfSopenharmony_ci } 2521f08c3bdfSopenharmony_ci#endif 2522f08c3bdfSopenharmony_ci 2523f08c3bdfSopenharmony_ci return (errbuf); 2524f08c3bdfSopenharmony_ci} 2525f08c3bdfSopenharmony_ci 2526f08c3bdfSopenharmony_ci/* 2527f08c3bdfSopenharmony_ci * Issue listio requests 2528f08c3bdfSopenharmony_ci */ 2529f08c3bdfSopenharmony_ci#ifdef CRAY 2530f08c3bdfSopenharmony_cistruct status *sy_listio(struct io_req *req, struct syscall_info *sysc, int fd, 2531f08c3bdfSopenharmony_ci char *addr) 2532f08c3bdfSopenharmony_ci{ 2533f08c3bdfSopenharmony_ci int offset, nbytes, nstrides, nents, aio_strat; 2534f08c3bdfSopenharmony_ci int aio_id, signo, o, i, lc; 2535f08c3bdfSopenharmony_ci char *a; 2536f08c3bdfSopenharmony_ci struct listreq *lio_req, *l; 2537f08c3bdfSopenharmony_ci struct aio_info *aiop; 2538f08c3bdfSopenharmony_ci struct status *status; 2539f08c3bdfSopenharmony_ci 2540f08c3bdfSopenharmony_ci /* 2541f08c3bdfSopenharmony_ci * Initialize common fields - assumes r_oflags, r_file, r_offset, and 2542f08c3bdfSopenharmony_ci * r_nbytes are at the same offset in the read_req and reada_req 2543f08c3bdfSopenharmony_ci * structures. 2544f08c3bdfSopenharmony_ci */ 2545f08c3bdfSopenharmony_ci offset = req->r_data.io.r_offset; 2546f08c3bdfSopenharmony_ci nbytes = req->r_data.io.r_nbytes; 2547f08c3bdfSopenharmony_ci nstrides = req->r_data.io.r_nstrides; 2548f08c3bdfSopenharmony_ci nents = req->r_data.io.r_nent; 2549f08c3bdfSopenharmony_ci aio_strat = req->r_data.io.r_aio_strat; 2550f08c3bdfSopenharmony_ci 2551f08c3bdfSopenharmony_ci lc = (sysc->sy_flags & SY_ASYNC) ? LC_START : LC_WAIT; 2552f08c3bdfSopenharmony_ci 2553f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2554f08c3bdfSopenharmony_ci if (status == NULL) { 2555f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2556f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2557f08c3bdfSopenharmony_ci return NULL; 2558f08c3bdfSopenharmony_ci } 2559f08c3bdfSopenharmony_ci status->aioid = malloc((nents + 1) * sizeof(int)); 2560f08c3bdfSopenharmony_ci if (status->aioid == NULL) { 2561f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2562f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2563f08c3bdfSopenharmony_ci return NULL; 2564f08c3bdfSopenharmony_ci } 2565f08c3bdfSopenharmony_ci 2566f08c3bdfSopenharmony_ci signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0; 2567f08c3bdfSopenharmony_ci 2568f08c3bdfSopenharmony_ci lio_req = malloc(nents * sizeof(struct listreq)); 2569f08c3bdfSopenharmony_ci if (lio_req == NULL) { 2570f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2571f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2572f08c3bdfSopenharmony_ci return NULL; 2573f08c3bdfSopenharmony_ci } 2574f08c3bdfSopenharmony_ci for (l = lio_req, a = addr, o = offset, i = 0; 2575f08c3bdfSopenharmony_ci i < nents; l++, a += nbytes, o += nbytes, i++) { 2576f08c3bdfSopenharmony_ci 2577f08c3bdfSopenharmony_ci aio_id = aio_register(fd, aio_strat, signo); 2578f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 2579f08c3bdfSopenharmony_ci status->aioid[i] = aio_id; 2580f08c3bdfSopenharmony_ci 2581f08c3bdfSopenharmony_ci l->li_opcode = (sysc->sy_flags & SY_WRITE) ? LO_WRITE : LO_READ; 2582f08c3bdfSopenharmony_ci l->li_offset = o; 2583f08c3bdfSopenharmony_ci l->li_fildes = fd; 2584f08c3bdfSopenharmony_ci l->li_buf = a; 2585f08c3bdfSopenharmony_ci l->li_nbyte = nbytes; 2586f08c3bdfSopenharmony_ci l->li_status = &aiop->iosw; 2587f08c3bdfSopenharmony_ci l->li_signo = signo; 2588f08c3bdfSopenharmony_ci l->li_nstride = nstrides; 2589f08c3bdfSopenharmony_ci l->li_filstride = 0; 2590f08c3bdfSopenharmony_ci l->li_memstride = 0; 2591f08c3bdfSopenharmony_ci l->li_drvr = 0; 2592f08c3bdfSopenharmony_ci l->li_flags = LF_LSEEK; 2593f08c3bdfSopenharmony_ci } 2594f08c3bdfSopenharmony_ci 2595f08c3bdfSopenharmony_ci status->aioid[nents] = -1; /* end sentinel */ 2596f08c3bdfSopenharmony_ci 2597f08c3bdfSopenharmony_ci if ((status->rval = listio(lc, lio_req, nents)) == -1) { 2598f08c3bdfSopenharmony_ci status->err = errno; 2599f08c3bdfSopenharmony_ci } 2600f08c3bdfSopenharmony_ci 2601f08c3bdfSopenharmony_ci free(lio_req); 2602f08c3bdfSopenharmony_ci return (status); 2603f08c3bdfSopenharmony_ci} 2604f08c3bdfSopenharmony_ci 2605f08c3bdfSopenharmony_ci/* 2606f08c3bdfSopenharmony_ci * Calculate the size of a request in bytes and min/max boundaries 2607f08c3bdfSopenharmony_ci * 2608f08c3bdfSopenharmony_ci * This assumes filestride & memstride = 0. 2609f08c3bdfSopenharmony_ci */ 2610f08c3bdfSopenharmony_ciint listio_mem(struct io_req *req, int offset, int fmstride, int *min, int *max) 2611f08c3bdfSopenharmony_ci{ 2612f08c3bdfSopenharmony_ci int i, size; 2613f08c3bdfSopenharmony_ci 2614f08c3bdfSopenharmony_ci size = stride_bounds(offset, fmstride, 2615f08c3bdfSopenharmony_ci req->r_data.io.r_nstrides * req->r_data.io.r_nent, 2616f08c3bdfSopenharmony_ci req->r_data.io.r_nbytes, min, max); 2617f08c3bdfSopenharmony_ci return (size); 2618f08c3bdfSopenharmony_ci} 2619f08c3bdfSopenharmony_ci 2620f08c3bdfSopenharmony_cichar *fmt_listio(struct io_req *req, struct syscall_info *sy, int fd, 2621f08c3bdfSopenharmony_ci char *addr) 2622f08c3bdfSopenharmony_ci{ 2623f08c3bdfSopenharmony_ci static char *errbuf = NULL; 2624f08c3bdfSopenharmony_ci char *cp; 2625f08c3bdfSopenharmony_ci char *c, *opcode; 2626f08c3bdfSopenharmony_ci int i; 2627f08c3bdfSopenharmony_ci 2628f08c3bdfSopenharmony_ci if (errbuf == NULL) { 2629f08c3bdfSopenharmony_ci errbuf = malloc(32768); 2630f08c3bdfSopenharmony_ci if (errbuf == NULL) { 2631f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2632f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2633f08c3bdfSopenharmony_ci return NULL; 2634f08c3bdfSopenharmony_ci } 2635f08c3bdfSopenharmony_ci } 2636f08c3bdfSopenharmony_ci 2637f08c3bdfSopenharmony_ci c = (sy->sy_flags & SY_ASYNC) ? "lc_wait" : "lc_start"; 2638f08c3bdfSopenharmony_ci 2639f08c3bdfSopenharmony_ci cp = errbuf; 2640f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: listio(%s, (?), %d)\n", 2641f08c3bdfSopenharmony_ci c, req->r_data.io.r_nent); 2642f08c3bdfSopenharmony_ci 2643f08c3bdfSopenharmony_ci cp += sprintf(cp, " data buffer at %#o\n", addr); 2644f08c3bdfSopenharmony_ci 2645f08c3bdfSopenharmony_ci return (errbuf); 2646f08c3bdfSopenharmony_ci} 2647f08c3bdfSopenharmony_ci#endif /* CRAY */ 2648f08c3bdfSopenharmony_ci 2649f08c3bdfSopenharmony_ci#ifdef sgi 2650f08c3bdfSopenharmony_cistruct status *sy_pread(struct io_req *req, struct syscall_info *sysc, int fd, 2651f08c3bdfSopenharmony_ci char *addr) 2652f08c3bdfSopenharmony_ci{ 2653f08c3bdfSopenharmony_ci int rc; 2654f08c3bdfSopenharmony_ci struct status *status; 2655f08c3bdfSopenharmony_ci 2656f08c3bdfSopenharmony_ci rc = pread(fd, addr, req->r_data.io.r_nbytes, req->r_data.io.r_offset); 2657f08c3bdfSopenharmony_ci 2658f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2659f08c3bdfSopenharmony_ci if (status == NULL) { 2660f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2661f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2662f08c3bdfSopenharmony_ci return NULL; 2663f08c3bdfSopenharmony_ci } 2664f08c3bdfSopenharmony_ci status->aioid = NULL; 2665f08c3bdfSopenharmony_ci status->rval = rc; 2666f08c3bdfSopenharmony_ci status->err = errno; 2667f08c3bdfSopenharmony_ci 2668f08c3bdfSopenharmony_ci return (status); 2669f08c3bdfSopenharmony_ci} 2670f08c3bdfSopenharmony_ci 2671f08c3bdfSopenharmony_cistruct status *sy_pwrite(struct io_req *req, struct syscall_info *sysc, int fd, 2672f08c3bdfSopenharmony_ci char *addr) 2673f08c3bdfSopenharmony_ci{ 2674f08c3bdfSopenharmony_ci int rc; 2675f08c3bdfSopenharmony_ci struct status *status; 2676f08c3bdfSopenharmony_ci 2677f08c3bdfSopenharmony_ci rc = pwrite(fd, addr, req->r_data.io.r_nbytes, req->r_data.io.r_offset); 2678f08c3bdfSopenharmony_ci 2679f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2680f08c3bdfSopenharmony_ci if (status == NULL) { 2681f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2682f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2683f08c3bdfSopenharmony_ci return NULL; 2684f08c3bdfSopenharmony_ci } 2685f08c3bdfSopenharmony_ci status->aioid = NULL; 2686f08c3bdfSopenharmony_ci status->rval = rc; 2687f08c3bdfSopenharmony_ci status->err = errno; 2688f08c3bdfSopenharmony_ci 2689f08c3bdfSopenharmony_ci return (status); 2690f08c3bdfSopenharmony_ci} 2691f08c3bdfSopenharmony_ci 2692f08c3bdfSopenharmony_cichar *fmt_pread(struct io_req *req, struct syscall_info *sy, int fd, char *addr) 2693f08c3bdfSopenharmony_ci{ 2694f08c3bdfSopenharmony_ci static char *errbuf = NULL; 2695f08c3bdfSopenharmony_ci char *cp; 2696f08c3bdfSopenharmony_ci 2697f08c3bdfSopenharmony_ci if (errbuf == NULL) { 2698f08c3bdfSopenharmony_ci errbuf = malloc(32768); 2699f08c3bdfSopenharmony_ci if (errbuf == NULL) { 2700f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2701f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2702f08c3bdfSopenharmony_ci return NULL; 2703f08c3bdfSopenharmony_ci } 2704f08c3bdfSopenharmony_ci } 2705f08c3bdfSopenharmony_ci 2706f08c3bdfSopenharmony_ci cp = errbuf; 2707f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: %s(%d, 0x%lx, %d)\n", 2708f08c3bdfSopenharmony_ci sy->sy_name, fd, addr, req->r_data.io.r_nbytes); 2709f08c3bdfSopenharmony_ci return (errbuf); 2710f08c3bdfSopenharmony_ci} 2711f08c3bdfSopenharmony_ci#endif /* sgi */ 2712f08c3bdfSopenharmony_ci 2713f08c3bdfSopenharmony_ci#ifndef CRAY 2714f08c3bdfSopenharmony_cistruct status *sy_readv(struct io_req *req, struct syscall_info *sysc, int fd, 2715f08c3bdfSopenharmony_ci char *addr) 2716f08c3bdfSopenharmony_ci{ 2717f08c3bdfSopenharmony_ci struct status *sy_rwv(); 2718f08c3bdfSopenharmony_ci return sy_rwv(req, sysc, fd, addr, 0); 2719f08c3bdfSopenharmony_ci} 2720f08c3bdfSopenharmony_ci 2721f08c3bdfSopenharmony_cistruct status *sy_writev(struct io_req *req, struct syscall_info *sysc, int fd, 2722f08c3bdfSopenharmony_ci char *addr) 2723f08c3bdfSopenharmony_ci{ 2724f08c3bdfSopenharmony_ci struct status *sy_rwv(); 2725f08c3bdfSopenharmony_ci return sy_rwv(req, sysc, fd, addr, 1); 2726f08c3bdfSopenharmony_ci} 2727f08c3bdfSopenharmony_ci 2728f08c3bdfSopenharmony_cistruct status *sy_rwv(struct io_req *req, struct syscall_info *sysc, int fd, 2729f08c3bdfSopenharmony_ci char *addr, int rw) 2730f08c3bdfSopenharmony_ci{ 2731f08c3bdfSopenharmony_ci int rc; 2732f08c3bdfSopenharmony_ci struct status *status; 2733f08c3bdfSopenharmony_ci struct iovec iov[2]; 2734f08c3bdfSopenharmony_ci 2735f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2736f08c3bdfSopenharmony_ci if (status == NULL) { 2737f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2738f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2739f08c3bdfSopenharmony_ci return NULL; 2740f08c3bdfSopenharmony_ci } 2741f08c3bdfSopenharmony_ci status->aioid = NULL; 2742f08c3bdfSopenharmony_ci 2743f08c3bdfSopenharmony_ci /* move to the desired file position. */ 2744f08c3bdfSopenharmony_ci if ((rc = lseek(fd, req->r_data.io.r_offset, SEEK_SET)) == -1) { 2745f08c3bdfSopenharmony_ci status->rval = rc; 2746f08c3bdfSopenharmony_ci status->err = errno; 2747f08c3bdfSopenharmony_ci return (status); 2748f08c3bdfSopenharmony_ci } 2749f08c3bdfSopenharmony_ci 2750f08c3bdfSopenharmony_ci iov[0].iov_base = addr; 2751f08c3bdfSopenharmony_ci iov[0].iov_len = req->r_data.io.r_nbytes; 2752f08c3bdfSopenharmony_ci 2753f08c3bdfSopenharmony_ci if (rw) 2754f08c3bdfSopenharmony_ci rc = writev(fd, iov, 1); 2755f08c3bdfSopenharmony_ci else 2756f08c3bdfSopenharmony_ci rc = readv(fd, iov, 1); 2757f08c3bdfSopenharmony_ci status->aioid = NULL; 2758f08c3bdfSopenharmony_ci status->rval = rc; 2759f08c3bdfSopenharmony_ci status->err = errno; 2760f08c3bdfSopenharmony_ci return (status); 2761f08c3bdfSopenharmony_ci} 2762f08c3bdfSopenharmony_ci 2763f08c3bdfSopenharmony_cichar *fmt_readv(struct io_req *req, struct syscall_info *sy, int fd, char *addr) 2764f08c3bdfSopenharmony_ci{ 2765f08c3bdfSopenharmony_ci static char errbuf[32768]; 2766f08c3bdfSopenharmony_ci char *cp; 2767f08c3bdfSopenharmony_ci 2768f08c3bdfSopenharmony_ci cp = errbuf; 2769f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: %s(%d, (iov on stack), 1)\n", 2770f08c3bdfSopenharmony_ci sy->sy_name, fd); 2771f08c3bdfSopenharmony_ci return (errbuf); 2772f08c3bdfSopenharmony_ci} 2773f08c3bdfSopenharmony_ci#endif /* !CRAY */ 2774f08c3bdfSopenharmony_ci 2775f08c3bdfSopenharmony_ci#ifdef sgi 2776f08c3bdfSopenharmony_cistruct status *sy_aread(struct io_req *req, struct syscall_info *sysc, int fd, 2777f08c3bdfSopenharmony_ci char *addr) 2778f08c3bdfSopenharmony_ci{ 2779f08c3bdfSopenharmony_ci struct status *sy_arw(); 2780f08c3bdfSopenharmony_ci return sy_arw(req, sysc, fd, addr, 0); 2781f08c3bdfSopenharmony_ci} 2782f08c3bdfSopenharmony_ci 2783f08c3bdfSopenharmony_cistruct status *sy_awrite(struct io_req *req, struct syscall_info *sysc, int fd, 2784f08c3bdfSopenharmony_ci char *addr) 2785f08c3bdfSopenharmony_ci{ 2786f08c3bdfSopenharmony_ci struct status *sy_arw(); 2787f08c3bdfSopenharmony_ci return sy_arw(req, sysc, fd, addr, 1); 2788f08c3bdfSopenharmony_ci} 2789f08c3bdfSopenharmony_ci 2790f08c3bdfSopenharmony_ci/* 2791f08c3bdfSopenharmony_ci #define sy_aread(A, B, C, D) sy_arw(A, B, C, D, 0) 2792f08c3bdfSopenharmony_ci #define sy_awrite(A, B, C, D) sy_arw(A, B, C, D, 1) 2793f08c3bdfSopenharmony_ci */ 2794f08c3bdfSopenharmony_ci 2795f08c3bdfSopenharmony_cistruct status *sy_arw(struct io_req *req, struct syscall_info *sysc, int fd, 2796f08c3bdfSopenharmony_ci char *addr, int rw) 2797f08c3bdfSopenharmony_ci{ 2798f08c3bdfSopenharmony_ci /* POSIX 1003.1b-1993 Async read */ 2799f08c3bdfSopenharmony_ci struct status *status; 2800f08c3bdfSopenharmony_ci int rc; 2801f08c3bdfSopenharmony_ci int aio_id, aio_strat, signo; 2802f08c3bdfSopenharmony_ci struct aio_info *aiop; 2803f08c3bdfSopenharmony_ci 2804f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2805f08c3bdfSopenharmony_ci if (status == NULL) { 2806f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2807f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2808f08c3bdfSopenharmony_ci return NULL; 2809f08c3bdfSopenharmony_ci } 2810f08c3bdfSopenharmony_ci aio_strat = req->r_data.io.r_aio_strat; 2811f08c3bdfSopenharmony_ci signo = (aio_strat == A_SIGNAL) ? SIGUSR1 : 0; 2812f08c3bdfSopenharmony_ci 2813f08c3bdfSopenharmony_ci aio_id = aio_register(fd, aio_strat, signo); 2814f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 2815f08c3bdfSopenharmony_ci 2816f08c3bdfSopenharmony_ci memset((void *)&aiop->aiocb, 0, sizeof(aiocb_t)); 2817f08c3bdfSopenharmony_ci 2818f08c3bdfSopenharmony_ci aiop->aiocb.aio_fildes = fd; 2819f08c3bdfSopenharmony_ci aiop->aiocb.aio_nbytes = req->r_data.io.r_nbytes; 2820f08c3bdfSopenharmony_ci aiop->aiocb.aio_offset = req->r_data.io.r_offset; 2821f08c3bdfSopenharmony_ci aiop->aiocb.aio_buf = addr; 2822f08c3bdfSopenharmony_ci aiop->aiocb.aio_reqprio = 0; /* must be 0 */ 2823f08c3bdfSopenharmony_ci aiop->aiocb.aio_lio_opcode = 0; 2824f08c3bdfSopenharmony_ci 2825f08c3bdfSopenharmony_ci if (aio_strat == A_SIGNAL) { /* siginfo(2) stuff */ 2826f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 2827f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_signo = signo; 2828f08c3bdfSopenharmony_ci } else if (aio_strat == A_CALLBACK) { 2829f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_signo = 0; 2830f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_CALLBACK; 2831f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_func = cb_handler; 2832f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_value.sival_int = aio_id; 2833f08c3bdfSopenharmony_ci } else { 2834f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_notify = SIGEV_NONE; 2835f08c3bdfSopenharmony_ci aiop->aiocb.aio_sigevent.sigev_signo = 0; 2836f08c3bdfSopenharmony_ci } 2837f08c3bdfSopenharmony_ci 2838f08c3bdfSopenharmony_ci if (rw) 2839f08c3bdfSopenharmony_ci rc = aio_write(&aiop->aiocb); 2840f08c3bdfSopenharmony_ci else 2841f08c3bdfSopenharmony_ci rc = aio_read(&aiop->aiocb); 2842f08c3bdfSopenharmony_ci 2843f08c3bdfSopenharmony_ci status->aioid = malloc(2 * sizeof(int)); 2844f08c3bdfSopenharmony_ci if (status->aioid == NULL) { 2845f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2846f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2847f08c3bdfSopenharmony_ci return NULL; 2848f08c3bdfSopenharmony_ci } 2849f08c3bdfSopenharmony_ci status->aioid[0] = aio_id; 2850f08c3bdfSopenharmony_ci status->aioid[1] = -1; 2851f08c3bdfSopenharmony_ci status->rval = rc; 2852f08c3bdfSopenharmony_ci status->err = errno; 2853f08c3bdfSopenharmony_ci return (status); 2854f08c3bdfSopenharmony_ci} 2855f08c3bdfSopenharmony_ci 2856f08c3bdfSopenharmony_cichar *fmt_aread(struct io_req *req, struct syscall_info *sy, int fd, char *addr) 2857f08c3bdfSopenharmony_ci{ 2858f08c3bdfSopenharmony_ci static char errbuf[32768]; 2859f08c3bdfSopenharmony_ci char *cp; 2860f08c3bdfSopenharmony_ci 2861f08c3bdfSopenharmony_ci cp = errbuf; 2862f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: %s(&aiop->aiocb)\n", sy->sy_name); 2863f08c3bdfSopenharmony_ci return (errbuf); 2864f08c3bdfSopenharmony_ci} 2865f08c3bdfSopenharmony_ci#endif /* sgi */ 2866f08c3bdfSopenharmony_ci 2867f08c3bdfSopenharmony_ci#ifndef CRAY 2868f08c3bdfSopenharmony_ci 2869f08c3bdfSopenharmony_cistruct status *sy_mmread(struct io_req *req, struct syscall_info *sysc, int fd, 2870f08c3bdfSopenharmony_ci char *addr) 2871f08c3bdfSopenharmony_ci{ 2872f08c3bdfSopenharmony_ci struct status *sy_mmrw(); 2873f08c3bdfSopenharmony_ci return sy_mmrw(req, sysc, fd, addr, 0); 2874f08c3bdfSopenharmony_ci} 2875f08c3bdfSopenharmony_ci 2876f08c3bdfSopenharmony_cistruct status *sy_mmwrite(struct io_req *req, struct syscall_info *sysc, int fd, 2877f08c3bdfSopenharmony_ci char *addr) 2878f08c3bdfSopenharmony_ci{ 2879f08c3bdfSopenharmony_ci struct status *sy_mmrw(); 2880f08c3bdfSopenharmony_ci return sy_mmrw(req, sysc, fd, addr, 1); 2881f08c3bdfSopenharmony_ci} 2882f08c3bdfSopenharmony_ci 2883f08c3bdfSopenharmony_cistruct status *sy_mmrw(struct io_req *req, struct syscall_info *sysc, int fd, 2884f08c3bdfSopenharmony_ci char *addr, int rw) 2885f08c3bdfSopenharmony_ci{ 2886f08c3bdfSopenharmony_ci /* 2887f08c3bdfSopenharmony_ci * mmap read/write 2888f08c3bdfSopenharmony_ci * This version is oriented towards mmaping the file to memory 2889f08c3bdfSopenharmony_ci * ONCE and keeping it mapped. 2890f08c3bdfSopenharmony_ci */ 2891f08c3bdfSopenharmony_ci struct status *status; 2892f08c3bdfSopenharmony_ci void *mrc = NULL, *memaddr = NULL; 2893f08c3bdfSopenharmony_ci struct fd_cache *fdc; 2894f08c3bdfSopenharmony_ci struct stat sbuf; 2895f08c3bdfSopenharmony_ci int rc; 2896f08c3bdfSopenharmony_ci 2897f08c3bdfSopenharmony_ci status = malloc(sizeof(struct status)); 2898f08c3bdfSopenharmony_ci if (status == NULL) { 2899f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc failed, %s/%d\n", 2900f08c3bdfSopenharmony_ci __FILE__, __LINE__); 2901f08c3bdfSopenharmony_ci return NULL; 2902f08c3bdfSopenharmony_ci } 2903f08c3bdfSopenharmony_ci status->aioid = NULL; 2904f08c3bdfSopenharmony_ci status->rval = -1; 2905f08c3bdfSopenharmony_ci 2906f08c3bdfSopenharmony_ci fdc = alloc_fdcache(req->r_data.io.r_file, req->r_data.io.r_oflags); 2907f08c3bdfSopenharmony_ci 2908f08c3bdfSopenharmony_ci if (v_opt || fdc->c_memaddr == NULL) { 2909f08c3bdfSopenharmony_ci if (fstat(fd, &sbuf) < 0) { 2910f08c3bdfSopenharmony_ci doio_fprintf(stderr, "fstat failed, errno=%d\n", errno); 2911f08c3bdfSopenharmony_ci status->err = errno; 2912f08c3bdfSopenharmony_ci return (status); 2913f08c3bdfSopenharmony_ci } 2914f08c3bdfSopenharmony_ci 2915f08c3bdfSopenharmony_ci fdc->c_memlen = (int)sbuf.st_size; 2916f08c3bdfSopenharmony_ci mrc = mmap(NULL, (int)sbuf.st_size, 2917f08c3bdfSopenharmony_ci rw ? PROT_WRITE | PROT_READ : PROT_READ, 2918f08c3bdfSopenharmony_ci MAP_SHARED, fd, 0); 2919f08c3bdfSopenharmony_ci 2920f08c3bdfSopenharmony_ci if (mrc == MAP_FAILED) { 2921f08c3bdfSopenharmony_ci doio_fprintf(stderr, "mmap() failed - 0x%lx %d\n", 2922f08c3bdfSopenharmony_ci mrc, errno); 2923f08c3bdfSopenharmony_ci status->err = errno; 2924f08c3bdfSopenharmony_ci return (status); 2925f08c3bdfSopenharmony_ci } 2926f08c3bdfSopenharmony_ci 2927f08c3bdfSopenharmony_ci fdc->c_memaddr = mrc; 2928f08c3bdfSopenharmony_ci } 2929f08c3bdfSopenharmony_ci 2930f08c3bdfSopenharmony_ci memaddr = (void *)((char *)fdc->c_memaddr + req->r_data.io.r_offset); 2931f08c3bdfSopenharmony_ci 2932f08c3bdfSopenharmony_ci active_mmap_rw = 1; 2933f08c3bdfSopenharmony_ci if (rw) 2934f08c3bdfSopenharmony_ci memcpy(memaddr, addr, req->r_data.io.r_nbytes); 2935f08c3bdfSopenharmony_ci else 2936f08c3bdfSopenharmony_ci memcpy(addr, memaddr, req->r_data.io.r_nbytes); 2937f08c3bdfSopenharmony_ci if (v_opt) 2938f08c3bdfSopenharmony_ci msync(fdc->c_memaddr, (int)sbuf.st_size, MS_SYNC); 2939f08c3bdfSopenharmony_ci active_mmap_rw = 0; 2940f08c3bdfSopenharmony_ci 2941f08c3bdfSopenharmony_ci status->rval = req->r_data.io.r_nbytes; 2942f08c3bdfSopenharmony_ci status->err = 0; 2943f08c3bdfSopenharmony_ci 2944f08c3bdfSopenharmony_ci if (v_opt) { 2945f08c3bdfSopenharmony_ci rc = munmap(mrc, (int)sbuf.st_size); 2946f08c3bdfSopenharmony_ci } 2947f08c3bdfSopenharmony_ci 2948f08c3bdfSopenharmony_ci return (status); 2949f08c3bdfSopenharmony_ci} 2950f08c3bdfSopenharmony_ci 2951f08c3bdfSopenharmony_cichar *fmt_mmrw(struct io_req *req, struct syscall_info *sy, int fd, char *addr) 2952f08c3bdfSopenharmony_ci{ 2953f08c3bdfSopenharmony_ci static char errbuf[32768]; 2954f08c3bdfSopenharmony_ci char *cp; 2955f08c3bdfSopenharmony_ci struct fd_cache *fdc; 2956f08c3bdfSopenharmony_ci void *memaddr; 2957f08c3bdfSopenharmony_ci 2958f08c3bdfSopenharmony_ci fdc = alloc_fdcache(req->r_data.io.r_file, req->r_data.io.r_oflags); 2959f08c3bdfSopenharmony_ci 2960f08c3bdfSopenharmony_ci cp = errbuf; 2961f08c3bdfSopenharmony_ci cp += sprintf(cp, "syscall: %s(NULL, %d, %s, MAP_SHARED, %d, 0)\n", 2962f08c3bdfSopenharmony_ci sy->sy_name, 2963f08c3bdfSopenharmony_ci fdc->c_memlen, 2964f08c3bdfSopenharmony_ci (sy->sy_flags & SY_WRITE) ? "PROT_WRITE" : "PROT_READ", 2965f08c3bdfSopenharmony_ci fd); 2966f08c3bdfSopenharmony_ci 2967f08c3bdfSopenharmony_ci cp += sprintf(cp, "\tfile is mmaped to: 0x%lx\n", 2968f08c3bdfSopenharmony_ci (unsigned long)fdc->c_memaddr); 2969f08c3bdfSopenharmony_ci 2970f08c3bdfSopenharmony_ci memaddr = (void *)((char *)fdc->c_memaddr + req->r_data.io.r_offset); 2971f08c3bdfSopenharmony_ci 2972f08c3bdfSopenharmony_ci cp += sprintf(cp, "\tfile-mem=0x%lx, length=%d, buffer=0x%lx\n", 2973f08c3bdfSopenharmony_ci (unsigned long)memaddr, req->r_data.io.r_nbytes, 2974f08c3bdfSopenharmony_ci (unsigned long)addr); 2975f08c3bdfSopenharmony_ci 2976f08c3bdfSopenharmony_ci return (errbuf); 2977f08c3bdfSopenharmony_ci} 2978f08c3bdfSopenharmony_ci#endif /* !CRAY */ 2979f08c3bdfSopenharmony_ci 2980f08c3bdfSopenharmony_cistruct syscall_info syscalls[] = { 2981f08c3bdfSopenharmony_ci#ifdef CRAY 2982f08c3bdfSopenharmony_ci {"listio-read-sync", LREAD, 2983f08c3bdfSopenharmony_ci sy_listio, NULL, fmt_listio, 2984f08c3bdfSopenharmony_ci SY_IOSW}, 2985f08c3bdfSopenharmony_ci {"listio-read-strides-sync", LSREAD, 2986f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 2987f08c3bdfSopenharmony_ci SY_IOSW}, 2988f08c3bdfSopenharmony_ci {"listio-read-reqs-sync", LEREAD, 2989f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 2990f08c3bdfSopenharmony_ci SY_IOSW}, 2991f08c3bdfSopenharmony_ci {"listio-read-async", LREADA, 2992f08c3bdfSopenharmony_ci sy_listio, NULL, fmt_listio, 2993f08c3bdfSopenharmony_ci SY_IOSW | SY_ASYNC}, 2994f08c3bdfSopenharmony_ci {"listio-read-strides-async", LSREADA, 2995f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 2996f08c3bdfSopenharmony_ci SY_IOSW | SY_ASYNC}, 2997f08c3bdfSopenharmony_ci {"listio-read-reqs-async", LEREADA, 2998f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 2999f08c3bdfSopenharmony_ci SY_IOSW | SY_ASYNC}, 3000f08c3bdfSopenharmony_ci {"listio-write-sync", LWRITE, 3001f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3002f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE}, 3003f08c3bdfSopenharmony_ci {"listio-write-strides-sync", LSWRITE, 3004f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3005f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE}, 3006f08c3bdfSopenharmony_ci {"listio-write-reqs-sync", LEWRITE, 3007f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3008f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE}, 3009f08c3bdfSopenharmony_ci {"listio-write-async", LWRITEA, 3010f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3011f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE | SY_ASYNC}, 3012f08c3bdfSopenharmony_ci {"listio-write-strides-async", LSWRITEA, 3013f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3014f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE | SY_ASYNC}, 3015f08c3bdfSopenharmony_ci {"listio-write-reqs-async", LEWRITEA, 3016f08c3bdfSopenharmony_ci sy_listio, listio_mem, fmt_listio, 3017f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE | SY_ASYNC}, 3018f08c3bdfSopenharmony_ci#endif 3019f08c3bdfSopenharmony_ci 3020f08c3bdfSopenharmony_ci#ifdef sgi 3021f08c3bdfSopenharmony_ci {"aread", AREAD, 3022f08c3bdfSopenharmony_ci sy_aread, NULL, fmt_aread, 3023f08c3bdfSopenharmony_ci SY_IOSW | SY_ASYNC}, 3024f08c3bdfSopenharmony_ci {"awrite", AWRITE, 3025f08c3bdfSopenharmony_ci sy_awrite, NULL, fmt_aread, 3026f08c3bdfSopenharmony_ci SY_IOSW | SY_WRITE | SY_ASYNC}, 3027f08c3bdfSopenharmony_ci {"pread", PREAD, 3028f08c3bdfSopenharmony_ci sy_pread, NULL, fmt_pread, 3029f08c3bdfSopenharmony_ci 0}, 3030f08c3bdfSopenharmony_ci {"pwrite", PWRITE, 3031f08c3bdfSopenharmony_ci sy_pwrite, NULL, fmt_pread, 3032f08c3bdfSopenharmony_ci SY_WRITE}, 3033f08c3bdfSopenharmony_ci#endif 3034f08c3bdfSopenharmony_ci 3035f08c3bdfSopenharmony_ci#ifndef CRAY 3036f08c3bdfSopenharmony_ci {"readv", READV, 3037f08c3bdfSopenharmony_ci sy_readv, NULL, fmt_readv, 3038f08c3bdfSopenharmony_ci 0}, 3039f08c3bdfSopenharmony_ci {"writev", WRITEV, 3040f08c3bdfSopenharmony_ci sy_writev, NULL, fmt_readv, 3041f08c3bdfSopenharmony_ci SY_WRITE}, 3042f08c3bdfSopenharmony_ci {"mmap-read", MMAPR, 3043f08c3bdfSopenharmony_ci sy_mmread, NULL, fmt_mmrw, 3044f08c3bdfSopenharmony_ci 0}, 3045f08c3bdfSopenharmony_ci {"mmap-write", MMAPW, 3046f08c3bdfSopenharmony_ci sy_mmwrite, NULL, fmt_mmrw, 3047f08c3bdfSopenharmony_ci SY_WRITE}, 3048f08c3bdfSopenharmony_ci#endif 3049f08c3bdfSopenharmony_ci 3050f08c3bdfSopenharmony_ci {NULL, 0, 3051f08c3bdfSopenharmony_ci 0, 0, 0, 3052f08c3bdfSopenharmony_ci 0}, 3053f08c3bdfSopenharmony_ci}; 3054f08c3bdfSopenharmony_ci 3055f08c3bdfSopenharmony_ciint do_rw(struct io_req *req) 3056f08c3bdfSopenharmony_ci{ 3057f08c3bdfSopenharmony_ci static int pid = -1; 3058f08c3bdfSopenharmony_ci int fd, offset, nbytes, nstrides, nents, oflags; 3059f08c3bdfSopenharmony_ci int rval, mem_needed, i; 3060f08c3bdfSopenharmony_ci int logged_write, got_lock, pattern; 3061f08c3bdfSopenharmony_ci off_t woffset; 3062f08c3bdfSopenharmony_ci int min_byte, max_byte; 3063f08c3bdfSopenharmony_ci char *addr, *file, *msg; 3064f08c3bdfSopenharmony_ci struct status *s; 3065f08c3bdfSopenharmony_ci struct wlog_rec wrec; 3066f08c3bdfSopenharmony_ci struct syscall_info *sy; 3067f08c3bdfSopenharmony_ci#if defined(CRAY) || defined(sgi) 3068f08c3bdfSopenharmony_ci struct aio_info *aiop; 3069f08c3bdfSopenharmony_ci struct iosw *iosw; 3070f08c3bdfSopenharmony_ci#endif 3071f08c3bdfSopenharmony_ci#ifdef sgi 3072f08c3bdfSopenharmony_ci struct fd_cache *fdc; 3073f08c3bdfSopenharmony_ci#endif 3074f08c3bdfSopenharmony_ci 3075f08c3bdfSopenharmony_ci woffset = 0; 3076f08c3bdfSopenharmony_ci 3077f08c3bdfSopenharmony_ci /* 3078f08c3bdfSopenharmony_ci * Initialize common fields - assumes r_oflags, r_file, r_offset, and 3079f08c3bdfSopenharmony_ci * r_nbytes are at the same offset in the read_req and reada_req 3080f08c3bdfSopenharmony_ci * structures. 3081f08c3bdfSopenharmony_ci */ 3082f08c3bdfSopenharmony_ci file = req->r_data.io.r_file; 3083f08c3bdfSopenharmony_ci oflags = req->r_data.io.r_oflags; 3084f08c3bdfSopenharmony_ci offset = req->r_data.io.r_offset; 3085f08c3bdfSopenharmony_ci nbytes = req->r_data.io.r_nbytes; 3086f08c3bdfSopenharmony_ci nstrides = req->r_data.io.r_nstrides; 3087f08c3bdfSopenharmony_ci nents = req->r_data.io.r_nent; 3088f08c3bdfSopenharmony_ci pattern = req->r_data.io.r_pattern; 3089f08c3bdfSopenharmony_ci 3090f08c3bdfSopenharmony_ci if (nents >= MAX_AIO) { 3091f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3092f08c3bdfSopenharmony_ci "do_rw: too many list requests, %d. Maximum is %d\n", 3093f08c3bdfSopenharmony_ci nents, MAX_AIO); 3094f08c3bdfSopenharmony_ci return (-1); 3095f08c3bdfSopenharmony_ci } 3096f08c3bdfSopenharmony_ci 3097f08c3bdfSopenharmony_ci /* 3098f08c3bdfSopenharmony_ci * look up system call info 3099f08c3bdfSopenharmony_ci */ 3100f08c3bdfSopenharmony_ci for (sy = syscalls; sy->sy_name != NULL && sy->sy_type != req->r_type; 3101f08c3bdfSopenharmony_ci sy++) ; 3102f08c3bdfSopenharmony_ci 3103f08c3bdfSopenharmony_ci if (sy->sy_name == NULL) { 3104f08c3bdfSopenharmony_ci doio_fprintf(stderr, "do_rw: unknown r_type %d.\n", 3105f08c3bdfSopenharmony_ci req->r_type); 3106f08c3bdfSopenharmony_ci return (-1); 3107f08c3bdfSopenharmony_ci } 3108f08c3bdfSopenharmony_ci 3109f08c3bdfSopenharmony_ci /* 3110f08c3bdfSopenharmony_ci * Get an open file descriptor 3111f08c3bdfSopenharmony_ci * Note: must be done before memory allocation so that the direct i/o 3112f08c3bdfSopenharmony_ci * information is available in mem. allocate 3113f08c3bdfSopenharmony_ci */ 3114f08c3bdfSopenharmony_ci 3115f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, oflags)) == -1) 3116f08c3bdfSopenharmony_ci return -1; 3117f08c3bdfSopenharmony_ci 3118f08c3bdfSopenharmony_ci /* 3119f08c3bdfSopenharmony_ci * Allocate core memory and possibly sds space. Initialize the 3120f08c3bdfSopenharmony_ci * data to be written. Make sure we get enough, based on the 3121f08c3bdfSopenharmony_ci * memstride. 3122f08c3bdfSopenharmony_ci * 3123f08c3bdfSopenharmony_ci * need: 3124f08c3bdfSopenharmony_ci * 1 extra word for possible partial-word address "bump" 3125f08c3bdfSopenharmony_ci * 1 extra word for dynamic pattern overrun 3126f08c3bdfSopenharmony_ci * MPP_BUMP extra words for T3E non-hw-aligned memory address. 3127f08c3bdfSopenharmony_ci */ 3128f08c3bdfSopenharmony_ci 3129f08c3bdfSopenharmony_ci if (sy->sy_buffer != NULL) { 3130f08c3bdfSopenharmony_ci mem_needed = (*sy->sy_buffer) (req, 0, 0, NULL, NULL); 3131f08c3bdfSopenharmony_ci } else { 3132f08c3bdfSopenharmony_ci mem_needed = nbytes; 3133f08c3bdfSopenharmony_ci } 3134f08c3bdfSopenharmony_ci 3135f08c3bdfSopenharmony_ci#ifdef CRAY 3136f08c3bdfSopenharmony_ci if ((rval = 3137f08c3bdfSopenharmony_ci alloc_mem(mem_needed + wtob(1) * 2 + 3138f08c3bdfSopenharmony_ci MPP_BUMP * sizeof(UINT64_T))) < 0) { 3139f08c3bdfSopenharmony_ci return rval; 3140f08c3bdfSopenharmony_ci } 3141f08c3bdfSopenharmony_ci#else 3142f08c3bdfSopenharmony_ci#ifdef sgi 3143f08c3bdfSopenharmony_ci /* get memory alignment for using DIRECT I/O */ 3144f08c3bdfSopenharmony_ci fdc = alloc_fdcache(file, oflags); 3145f08c3bdfSopenharmony_ci 3146f08c3bdfSopenharmony_ci if ((rval = alloc_mem(mem_needed + wtob(1) * 2 + fdc->c_memalign)) < 0) { 3147f08c3bdfSopenharmony_ci return rval; 3148f08c3bdfSopenharmony_ci } 3149f08c3bdfSopenharmony_ci#else 3150f08c3bdfSopenharmony_ci /* what is !CRAY && !sgi ? */ 3151f08c3bdfSopenharmony_ci if ((rval = alloc_mem(mem_needed + wtob(1) * 2)) < 0) { 3152f08c3bdfSopenharmony_ci return rval; 3153f08c3bdfSopenharmony_ci } 3154f08c3bdfSopenharmony_ci#endif /* sgi */ 3155f08c3bdfSopenharmony_ci#endif /* CRAY */ 3156f08c3bdfSopenharmony_ci 3157f08c3bdfSopenharmony_ci Pattern[0] = pattern; 3158f08c3bdfSopenharmony_ci 3159f08c3bdfSopenharmony_ci /* 3160f08c3bdfSopenharmony_ci * Allocate SDS space for backdoor write if desired 3161f08c3bdfSopenharmony_ci */ 3162f08c3bdfSopenharmony_ci 3163f08c3bdfSopenharmony_ci if (oflags & O_SSD) { 3164f08c3bdfSopenharmony_ci#ifdef CRAY 3165f08c3bdfSopenharmony_ci#ifndef _CRAYMPP 3166f08c3bdfSopenharmony_ci if (alloc_sds(nbytes) == -1) 3167f08c3bdfSopenharmony_ci return -1; 3168f08c3bdfSopenharmony_ci 3169f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_WRITE) { 3170f08c3bdfSopenharmony_ci /*pattern_fill(Memptr, mem_needed, Pattern, Pattern_Length, 0); */ 3171f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, nbytes, Pattern, Pattern_Length, 3172f08c3bdfSopenharmony_ci 0); 3173f08c3bdfSopenharmony_ci 3174f08c3bdfSopenharmony_ci if (sswrite((long)Memptr, Sdsptr, btoc(mem_needed)) == 3175f08c3bdfSopenharmony_ci -1) { 3176f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3177f08c3bdfSopenharmony_ci "sswrite(%d, %d, %d) failed: %s (%d)\n", 3178f08c3bdfSopenharmony_ci (long)Memptr, Sdsptr, 3179f08c3bdfSopenharmony_ci btoc(mem_needed), SYSERR, errno); 3180f08c3bdfSopenharmony_ci fflush(stderr); 3181f08c3bdfSopenharmony_ci return -1; 3182f08c3bdfSopenharmony_ci } 3183f08c3bdfSopenharmony_ci } 3184f08c3bdfSopenharmony_ci 3185f08c3bdfSopenharmony_ci addr = (char *)Sdsptr; 3186f08c3bdfSopenharmony_ci#else 3187f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3188f08c3bdfSopenharmony_ci "Invalid O_SSD flag was generated for MPP system\n"); 3189f08c3bdfSopenharmony_ci fflush(stderr); 3190f08c3bdfSopenharmony_ci return -1; 3191f08c3bdfSopenharmony_ci#endif /* _CRAYMPP */ 3192f08c3bdfSopenharmony_ci#else /* CRAY */ 3193f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3194f08c3bdfSopenharmony_ci "Invalid O_SSD flag was generated for non-Cray system\n"); 3195f08c3bdfSopenharmony_ci fflush(stderr); 3196f08c3bdfSopenharmony_ci return -1; 3197f08c3bdfSopenharmony_ci#endif /* CRAY */ 3198f08c3bdfSopenharmony_ci } else { 3199f08c3bdfSopenharmony_ci addr = Memptr; 3200f08c3bdfSopenharmony_ci 3201f08c3bdfSopenharmony_ci /* 3202f08c3bdfSopenharmony_ci * if io is not raw, bump the offset by a random amount 3203f08c3bdfSopenharmony_ci * to generate non-word-aligned io. 3204f08c3bdfSopenharmony_ci * 3205f08c3bdfSopenharmony_ci * On MPP systems, raw I/O must start on an 0x80 byte boundary. 3206f08c3bdfSopenharmony_ci * For non-aligned I/O, bump the address from 1 to 8 words. 3207f08c3bdfSopenharmony_ci */ 3208f08c3bdfSopenharmony_ci 3209f08c3bdfSopenharmony_ci if (!(req->r_data.io.r_uflags & F_WORD_ALIGNED)) { 3210f08c3bdfSopenharmony_ci#ifdef _CRAYMPP 3211f08c3bdfSopenharmony_ci addr += 3212f08c3bdfSopenharmony_ci random_range(0, MPP_BUMP, 1, NULL) * sizeof(int); 3213f08c3bdfSopenharmony_ci#endif 3214f08c3bdfSopenharmony_ci addr += random_range(0, wtob(1) - 1, 1, NULL); 3215f08c3bdfSopenharmony_ci } 3216f08c3bdfSopenharmony_ci#ifdef sgi 3217f08c3bdfSopenharmony_ci /* 3218f08c3bdfSopenharmony_ci * Force memory alignment for Direct I/O 3219f08c3bdfSopenharmony_ci */ 3220f08c3bdfSopenharmony_ci if ((oflags & O_DIRECT) && ((long)addr % fdc->c_memalign != 0)) { 3221f08c3bdfSopenharmony_ci addr += 3222f08c3bdfSopenharmony_ci fdc->c_memalign - ((long)addr % fdc->c_memalign); 3223f08c3bdfSopenharmony_ci } 3224f08c3bdfSopenharmony_ci#endif 3225f08c3bdfSopenharmony_ci 3226f08c3bdfSopenharmony_ci /* 3227f08c3bdfSopenharmony_ci * FILL must be done on a word-aligned buffer. 3228f08c3bdfSopenharmony_ci * Call the fill function with Memptr which is aligned, 3229f08c3bdfSopenharmony_ci * then memmove it to the right place. 3230f08c3bdfSopenharmony_ci */ 3231f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_WRITE) { 3232f08c3bdfSopenharmony_ci (*Data_Fill) (Memptr, mem_needed, Pattern, 3233f08c3bdfSopenharmony_ci Pattern_Length, 0); 3234f08c3bdfSopenharmony_ci if (addr != Memptr) 3235f08c3bdfSopenharmony_ci memmove(addr, Memptr, mem_needed); 3236f08c3bdfSopenharmony_ci } 3237f08c3bdfSopenharmony_ci } 3238f08c3bdfSopenharmony_ci 3239f08c3bdfSopenharmony_ci rval = 0; 3240f08c3bdfSopenharmony_ci got_lock = 0; 3241f08c3bdfSopenharmony_ci logged_write = 0; 3242f08c3bdfSopenharmony_ci 3243f08c3bdfSopenharmony_ci /* 3244f08c3bdfSopenharmony_ci * Lock data if this is a write and locking option is set 3245f08c3bdfSopenharmony_ci */ 3246f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_WRITE && k_opt) { 3247f08c3bdfSopenharmony_ci if (sy->sy_buffer != NULL) { 3248f08c3bdfSopenharmony_ci (*sy->sy_buffer) (req, offset, 0, &min_byte, &max_byte); 3249f08c3bdfSopenharmony_ci } else { 3250f08c3bdfSopenharmony_ci min_byte = offset; 3251f08c3bdfSopenharmony_ci max_byte = offset + (nbytes * nstrides * nents); 3252f08c3bdfSopenharmony_ci } 3253f08c3bdfSopenharmony_ci 3254f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_WRLCK, 3255f08c3bdfSopenharmony_ci min_byte, (max_byte - min_byte + 1)) < 0) { 3256f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3257f08c3bdfSopenharmony_ci "file lock failed:\n%s\n", 3258f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd)); 3259f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3260f08c3bdfSopenharmony_ci " buffer(req, %d, 0, 0x%x, 0x%x)\n", 3261f08c3bdfSopenharmony_ci offset, min_byte, max_byte); 3262f08c3bdfSopenharmony_ci alloc_mem(-1); 3263f08c3bdfSopenharmony_ci exit(E_INTERNAL); 3264f08c3bdfSopenharmony_ci } 3265f08c3bdfSopenharmony_ci 3266f08c3bdfSopenharmony_ci got_lock = 1; 3267f08c3bdfSopenharmony_ci } 3268f08c3bdfSopenharmony_ci 3269f08c3bdfSopenharmony_ci /* 3270f08c3bdfSopenharmony_ci * Write a preliminary write-log entry. This is done so that 3271f08c3bdfSopenharmony_ci * doio_check can do corruption detection across an interrupt/crash. 3272f08c3bdfSopenharmony_ci * Note that w_done is set to 0. If doio_check sees this, it 3273f08c3bdfSopenharmony_ci * re-creates the file extents as if the write completed, but does not 3274f08c3bdfSopenharmony_ci * do any checking - see comments in doio_check for more details. 3275f08c3bdfSopenharmony_ci */ 3276f08c3bdfSopenharmony_ci 3277f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_WRITE && w_opt) { 3278f08c3bdfSopenharmony_ci if (pid == -1) { 3279f08c3bdfSopenharmony_ci pid = getpid(); 3280f08c3bdfSopenharmony_ci } 3281f08c3bdfSopenharmony_ci 3282f08c3bdfSopenharmony_ci wrec.w_async = (sy->sy_flags & SY_ASYNC) ? 1 : 0; 3283f08c3bdfSopenharmony_ci wrec.w_oflags = oflags; 3284f08c3bdfSopenharmony_ci wrec.w_pid = pid; 3285f08c3bdfSopenharmony_ci wrec.w_offset = offset; 3286f08c3bdfSopenharmony_ci wrec.w_nbytes = nbytes; /* mem_needed -- total length */ 3287f08c3bdfSopenharmony_ci 3288f08c3bdfSopenharmony_ci wrec.w_pathlen = strlen(file); 3289f08c3bdfSopenharmony_ci memcpy(wrec.w_path, file, wrec.w_pathlen); 3290f08c3bdfSopenharmony_ci wrec.w_hostlen = strlen(Host); 3291f08c3bdfSopenharmony_ci memcpy(wrec.w_host, Host, wrec.w_hostlen); 3292f08c3bdfSopenharmony_ci wrec.w_patternlen = Pattern_Length; 3293f08c3bdfSopenharmony_ci memcpy(wrec.w_pattern, Pattern, wrec.w_patternlen); 3294f08c3bdfSopenharmony_ci 3295f08c3bdfSopenharmony_ci wrec.w_done = 0; 3296f08c3bdfSopenharmony_ci 3297f08c3bdfSopenharmony_ci if ((woffset = wlog_record_write(&Wlog, &wrec, -1)) == -1) { 3298f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3299f08c3bdfSopenharmony_ci "Could not append to write-log: %s (%d)\n", 3300f08c3bdfSopenharmony_ci SYSERR, errno); 3301f08c3bdfSopenharmony_ci } else { 3302f08c3bdfSopenharmony_ci logged_write = 1; 3303f08c3bdfSopenharmony_ci } 3304f08c3bdfSopenharmony_ci } 3305f08c3bdfSopenharmony_ci 3306f08c3bdfSopenharmony_ci s = (*sy->sy_syscall) (req, sy, fd, addr); 3307f08c3bdfSopenharmony_ci 3308f08c3bdfSopenharmony_ci if (s->rval == -1) { 3309f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3310f08c3bdfSopenharmony_ci "%s() request failed: %s (%d)\n%s\n%s\n", 3311f08c3bdfSopenharmony_ci sy->sy_name, SYSERR, errno, 3312f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3313f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, fd, addr)); 3314f08c3bdfSopenharmony_ci 3315f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 3316f08c3bdfSopenharmony_ci 3317f08c3bdfSopenharmony_ci for (i = 0; i < nents; i++) { 3318f08c3bdfSopenharmony_ci if (s->aioid == NULL) 3319f08c3bdfSopenharmony_ci break; 3320f08c3bdfSopenharmony_ci aio_unregister(s->aioid[i]); 3321f08c3bdfSopenharmony_ci } 3322f08c3bdfSopenharmony_ci rval = -1; 3323f08c3bdfSopenharmony_ci } else { 3324f08c3bdfSopenharmony_ci /* 3325f08c3bdfSopenharmony_ci * If the syscall was async, wait for I/O to complete 3326f08c3bdfSopenharmony_ci */ 3327f08c3bdfSopenharmony_ci#ifndef __linux__ 3328f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_ASYNC) { 3329f08c3bdfSopenharmony_ci for (i = 0; i < nents; i++) { 3330f08c3bdfSopenharmony_ci aio_wait(s->aioid[i]); 3331f08c3bdfSopenharmony_ci } 3332f08c3bdfSopenharmony_ci } 3333f08c3bdfSopenharmony_ci#endif 3334f08c3bdfSopenharmony_ci 3335f08c3bdfSopenharmony_ci /* 3336f08c3bdfSopenharmony_ci * Check the syscall how-much-data-written return. Look 3337f08c3bdfSopenharmony_ci * for this in either the return value or the 'iosw' 3338f08c3bdfSopenharmony_ci * structure. 3339f08c3bdfSopenharmony_ci */ 3340f08c3bdfSopenharmony_ci 3341f08c3bdfSopenharmony_ci if (sy->sy_flags & SY_IOSW) { 3342f08c3bdfSopenharmony_ci#ifdef CRAY 3343f08c3bdfSopenharmony_ci for (i = 0; i < nents; i++) { 3344f08c3bdfSopenharmony_ci if (s->aioid == NULL) 3345f08c3bdfSopenharmony_ci break; /* >>> error condition? */ 3346f08c3bdfSopenharmony_ci aiop = aio_slot(s->aioid[i]); 3347f08c3bdfSopenharmony_ci iosw = &aiop->iosw; 3348f08c3bdfSopenharmony_ci if (iosw->sw_error != 0) { 3349f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3350f08c3bdfSopenharmony_ci "%s() iosw error set: %s\n%s\n%s\n", 3351f08c3bdfSopenharmony_ci sy->sy_name, 3352f08c3bdfSopenharmony_ci strerror(iosw->sw_error), 3353f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3354f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, 3355f08c3bdfSopenharmony_ci fd, 3356f08c3bdfSopenharmony_ci addr)); 3357f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 3358f08c3bdfSopenharmony_ci rval = -1; 3359f08c3bdfSopenharmony_ci } else if (iosw->sw_count != nbytes * nstrides) { 3360f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3361f08c3bdfSopenharmony_ci "Bad iosw from %s() #%d\nExpected (%d,%d,%d), got (%d,%d,%d)\n%s\n%s\n", 3362f08c3bdfSopenharmony_ci sy->sy_name, i, 3363f08c3bdfSopenharmony_ci 1, 0, nbytes * nstrides, 3364f08c3bdfSopenharmony_ci iosw->sw_flag, 3365f08c3bdfSopenharmony_ci iosw->sw_error, 3366f08c3bdfSopenharmony_ci iosw->sw_count, 3367f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3368f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, 3369f08c3bdfSopenharmony_ci fd, 3370f08c3bdfSopenharmony_ci addr)); 3371f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 3372f08c3bdfSopenharmony_ci rval = -1; 3373f08c3bdfSopenharmony_ci } 3374f08c3bdfSopenharmony_ci 3375f08c3bdfSopenharmony_ci aio_unregister(s->aioid[i]); 3376f08c3bdfSopenharmony_ci } 3377f08c3bdfSopenharmony_ci#endif /* CRAY */ 3378f08c3bdfSopenharmony_ci#ifdef sgi 3379f08c3bdfSopenharmony_ci for (i = 0; s->aioid[i] != -1; i++) { 3380f08c3bdfSopenharmony_ci if (s->aioid == NULL) { 3381f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3382f08c3bdfSopenharmony_ci "aioid == NULL!\n"); 3383f08c3bdfSopenharmony_ci break; 3384f08c3bdfSopenharmony_ci } 3385f08c3bdfSopenharmony_ci aiop = aio_slot(s->aioid[i]); 3386f08c3bdfSopenharmony_ci 3387f08c3bdfSopenharmony_ci /* 3388f08c3bdfSopenharmony_ci * make sure the io completed without error 3389f08c3bdfSopenharmony_ci */ 3390f08c3bdfSopenharmony_ci if (aiop->aio_errno != 0) { 3391f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3392f08c3bdfSopenharmony_ci "%s() aio error set: %s (%d)\n%s\n%s\n", 3393f08c3bdfSopenharmony_ci sy->sy_name, 3394f08c3bdfSopenharmony_ci strerror(aiop->aio_errno), 3395f08c3bdfSopenharmony_ci aiop->aio_errno, 3396f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3397f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, 3398f08c3bdfSopenharmony_ci fd, 3399f08c3bdfSopenharmony_ci addr)); 3400f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 3401f08c3bdfSopenharmony_ci rval = -1; 3402f08c3bdfSopenharmony_ci } else if (aiop->aio_ret != nbytes) { 3403f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3404f08c3bdfSopenharmony_ci "Bad aio return from %s() #%d\nExpected (%d,%d), got (%d,%d)\n%s\n%s\n", 3405f08c3bdfSopenharmony_ci sy->sy_name, i, 3406f08c3bdfSopenharmony_ci 0, nbytes, 3407f08c3bdfSopenharmony_ci aiop->aio_errno, 3408f08c3bdfSopenharmony_ci aiop->aio_ret, 3409f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3410f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, 3411f08c3bdfSopenharmony_ci fd, 3412f08c3bdfSopenharmony_ci addr)); 3413f08c3bdfSopenharmony_ci aio_unregister(s->aioid[i]); 3414f08c3bdfSopenharmony_ci doio_upanic(U_IOSW); 3415f08c3bdfSopenharmony_ci return -1; 3416f08c3bdfSopenharmony_ci } else { 3417f08c3bdfSopenharmony_ci aio_unregister(s->aioid[i]); 3418f08c3bdfSopenharmony_ci rval = 0; 3419f08c3bdfSopenharmony_ci } 3420f08c3bdfSopenharmony_ci } 3421f08c3bdfSopenharmony_ci#endif /* sgi */ 3422f08c3bdfSopenharmony_ci } else { 3423f08c3bdfSopenharmony_ci 3424f08c3bdfSopenharmony_ci if (s->rval != mem_needed) { 3425f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3426f08c3bdfSopenharmony_ci "%s() request returned wrong # of bytes - expected %d, got %d\n%s\n%s\n", 3427f08c3bdfSopenharmony_ci sy->sy_name, nbytes, s->rval, 3428f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3429f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, fd, 3430f08c3bdfSopenharmony_ci addr)); 3431f08c3bdfSopenharmony_ci rval = -1; 3432f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 3433f08c3bdfSopenharmony_ci } 3434f08c3bdfSopenharmony_ci } 3435f08c3bdfSopenharmony_ci } 3436f08c3bdfSopenharmony_ci 3437f08c3bdfSopenharmony_ci /* 3438f08c3bdfSopenharmony_ci * Verify that the data was written correctly - check_file() returns 3439f08c3bdfSopenharmony_ci * a non-null pointer which contains an error message if there are 3440f08c3bdfSopenharmony_ci * problems. 3441f08c3bdfSopenharmony_ci */ 3442f08c3bdfSopenharmony_ci 3443f08c3bdfSopenharmony_ci if (rval == 0 && sy->sy_flags & SY_WRITE && v_opt) { 3444f08c3bdfSopenharmony_ci msg = check_file(file, offset, nbytes * nstrides * nents, 3445f08c3bdfSopenharmony_ci Pattern, Pattern_Length, 0, 3446f08c3bdfSopenharmony_ci oflags & O_PARALLEL); 3447f08c3bdfSopenharmony_ci if (msg != NULL) { 3448f08c3bdfSopenharmony_ci doio_fprintf(stderr, "%s\n%s\n%s\n", 3449f08c3bdfSopenharmony_ci msg, 3450f08c3bdfSopenharmony_ci fmt_ioreq(req, sy, fd), 3451f08c3bdfSopenharmony_ci (*sy->sy_format) (req, sy, fd, addr)); 3452f08c3bdfSopenharmony_ci doio_upanic(U_CORRUPTION); 3453f08c3bdfSopenharmony_ci exit(E_COMPARE); 3454f08c3bdfSopenharmony_ci } 3455f08c3bdfSopenharmony_ci } 3456f08c3bdfSopenharmony_ci 3457f08c3bdfSopenharmony_ci /* 3458f08c3bdfSopenharmony_ci * General cleanup ... 3459f08c3bdfSopenharmony_ci * 3460f08c3bdfSopenharmony_ci * Write extent information to the write-log, so that doio_check can do 3461f08c3bdfSopenharmony_ci * corruption detection. Note that w_done is set to 1, indicating that 3462f08c3bdfSopenharmony_ci * the write has been verified as complete. We don't need to write the 3463f08c3bdfSopenharmony_ci * filename on the second logging. 3464f08c3bdfSopenharmony_ci */ 3465f08c3bdfSopenharmony_ci 3466f08c3bdfSopenharmony_ci if (w_opt && logged_write) { 3467f08c3bdfSopenharmony_ci wrec.w_done = 1; 3468f08c3bdfSopenharmony_ci wlog_record_write(&Wlog, &wrec, woffset); 3469f08c3bdfSopenharmony_ci } 3470f08c3bdfSopenharmony_ci 3471f08c3bdfSopenharmony_ci /* 3472f08c3bdfSopenharmony_ci * Unlock file region if necessary 3473f08c3bdfSopenharmony_ci */ 3474f08c3bdfSopenharmony_ci 3475f08c3bdfSopenharmony_ci if (got_lock) { 3476f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_UNLCK, 3477f08c3bdfSopenharmony_ci min_byte, (max_byte - min_byte + 1)) < 0) { 3478f08c3bdfSopenharmony_ci alloc_mem(-1); 3479f08c3bdfSopenharmony_ci exit(E_INTERNAL); 3480f08c3bdfSopenharmony_ci } 3481f08c3bdfSopenharmony_ci } 3482f08c3bdfSopenharmony_ci 3483f08c3bdfSopenharmony_ci if (s->aioid != NULL) 3484f08c3bdfSopenharmony_ci free(s->aioid); 3485f08c3bdfSopenharmony_ci free(s); 3486f08c3bdfSopenharmony_ci return (rval == -1) ? -1 : 0; 3487f08c3bdfSopenharmony_ci} 3488f08c3bdfSopenharmony_ci 3489f08c3bdfSopenharmony_ci/* 3490f08c3bdfSopenharmony_ci * fcntl-based requests 3491f08c3bdfSopenharmony_ci * - F_FRESVSP 3492f08c3bdfSopenharmony_ci * - F_UNRESVSP 3493f08c3bdfSopenharmony_ci * - F_FSYNC 3494f08c3bdfSopenharmony_ci */ 3495f08c3bdfSopenharmony_ci#ifdef sgi 3496f08c3bdfSopenharmony_ciint do_fcntl(struct io_req *req) 3497f08c3bdfSopenharmony_ci{ 3498f08c3bdfSopenharmony_ci int fd, oflags, offset, nbytes; 3499f08c3bdfSopenharmony_ci int rval, op; 3500f08c3bdfSopenharmony_ci int got_lock; 3501f08c3bdfSopenharmony_ci int min_byte, max_byte; 3502f08c3bdfSopenharmony_ci char *file, *msg; 3503f08c3bdfSopenharmony_ci struct flock flk; 3504f08c3bdfSopenharmony_ci 3505f08c3bdfSopenharmony_ci /* 3506f08c3bdfSopenharmony_ci * Initialize common fields - assumes r_oflags, r_file, r_offset, and 3507f08c3bdfSopenharmony_ci * r_nbytes are at the same offset in the read_req and reada_req 3508f08c3bdfSopenharmony_ci * structures. 3509f08c3bdfSopenharmony_ci */ 3510f08c3bdfSopenharmony_ci file = req->r_data.io.r_file; 3511f08c3bdfSopenharmony_ci oflags = req->r_data.io.r_oflags; 3512f08c3bdfSopenharmony_ci offset = req->r_data.io.r_offset; 3513f08c3bdfSopenharmony_ci nbytes = req->r_data.io.r_nbytes; 3514f08c3bdfSopenharmony_ci 3515f08c3bdfSopenharmony_ci flk.l_type = 0; 3516f08c3bdfSopenharmony_ci flk.l_whence = SEEK_SET; 3517f08c3bdfSopenharmony_ci flk.l_start = offset; 3518f08c3bdfSopenharmony_ci flk.l_len = nbytes; 3519f08c3bdfSopenharmony_ci 3520f08c3bdfSopenharmony_ci /* 3521f08c3bdfSopenharmony_ci * Get an open file descriptor 3522f08c3bdfSopenharmony_ci */ 3523f08c3bdfSopenharmony_ci 3524f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, oflags)) == -1) 3525f08c3bdfSopenharmony_ci return -1; 3526f08c3bdfSopenharmony_ci 3527f08c3bdfSopenharmony_ci rval = 0; 3528f08c3bdfSopenharmony_ci got_lock = 0; 3529f08c3bdfSopenharmony_ci 3530f08c3bdfSopenharmony_ci /* 3531f08c3bdfSopenharmony_ci * Lock data if this is locking option is set 3532f08c3bdfSopenharmony_ci */ 3533f08c3bdfSopenharmony_ci if (k_opt) { 3534f08c3bdfSopenharmony_ci min_byte = offset; 3535f08c3bdfSopenharmony_ci max_byte = offset + nbytes; 3536f08c3bdfSopenharmony_ci 3537f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_WRLCK, 3538f08c3bdfSopenharmony_ci min_byte, (nbytes + 1)) < 0) { 3539f08c3bdfSopenharmony_ci doio_fprintf(stderr, "file lock failed:\n"); 3540f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3541f08c3bdfSopenharmony_ci " buffer(req, %d, 0, 0x%x, 0x%x)\n", 3542f08c3bdfSopenharmony_ci offset, min_byte, max_byte); 3543f08c3bdfSopenharmony_ci alloc_mem(-1); 3544f08c3bdfSopenharmony_ci exit(E_INTERNAL); 3545f08c3bdfSopenharmony_ci } 3546f08c3bdfSopenharmony_ci 3547f08c3bdfSopenharmony_ci got_lock = 1; 3548f08c3bdfSopenharmony_ci } 3549f08c3bdfSopenharmony_ci 3550f08c3bdfSopenharmony_ci switch (req->r_type) { 3551f08c3bdfSopenharmony_ci case RESVSP: 3552f08c3bdfSopenharmony_ci op = F_RESVSP; 3553f08c3bdfSopenharmony_ci msg = "f_resvsp"; 3554f08c3bdfSopenharmony_ci break; 3555f08c3bdfSopenharmony_ci case UNRESVSP: 3556f08c3bdfSopenharmony_ci op = F_UNRESVSP; 3557f08c3bdfSopenharmony_ci msg = "f_unresvsp"; 3558f08c3bdfSopenharmony_ci break; 3559f08c3bdfSopenharmony_ci#ifdef F_FSYNC 3560f08c3bdfSopenharmony_ci case DFFSYNC: 3561f08c3bdfSopenharmony_ci op = F_FSYNC; 3562f08c3bdfSopenharmony_ci msg = "f_fsync"; 3563f08c3bdfSopenharmony_ci break; 3564f08c3bdfSopenharmony_ci#endif 3565f08c3bdfSopenharmony_ci } 3566f08c3bdfSopenharmony_ci 3567f08c3bdfSopenharmony_ci rval = fcntl(fd, op, &flk); 3568f08c3bdfSopenharmony_ci 3569f08c3bdfSopenharmony_ci if (rval == -1) { 3570f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3571f08c3bdfSopenharmony_ci "fcntl %s request failed: %s (%d)\n\tfcntl(%d, %s %d, {%d %lld ==> %lld}\n", 3572f08c3bdfSopenharmony_ci msg, SYSERR, errno, 3573f08c3bdfSopenharmony_ci fd, msg, op, flk.l_whence, 3574f08c3bdfSopenharmony_ci (long long)flk.l_start, (long long)flk.l_len); 3575f08c3bdfSopenharmony_ci 3576f08c3bdfSopenharmony_ci doio_upanic(U_RVAL); 3577f08c3bdfSopenharmony_ci rval = -1; 3578f08c3bdfSopenharmony_ci } 3579f08c3bdfSopenharmony_ci 3580f08c3bdfSopenharmony_ci /* 3581f08c3bdfSopenharmony_ci * Unlock file region if necessary 3582f08c3bdfSopenharmony_ci */ 3583f08c3bdfSopenharmony_ci 3584f08c3bdfSopenharmony_ci if (got_lock) { 3585f08c3bdfSopenharmony_ci if (lock_file_region(file, fd, F_UNLCK, 3586f08c3bdfSopenharmony_ci min_byte, (max_byte - min_byte + 1)) < 0) { 3587f08c3bdfSopenharmony_ci alloc_mem(-1); 3588f08c3bdfSopenharmony_ci exit(E_INTERNAL); 3589f08c3bdfSopenharmony_ci } 3590f08c3bdfSopenharmony_ci } 3591f08c3bdfSopenharmony_ci 3592f08c3bdfSopenharmony_ci return (rval == -1) ? -1 : 0; 3593f08c3bdfSopenharmony_ci} 3594f08c3bdfSopenharmony_ci#endif /* sgi */ 3595f08c3bdfSopenharmony_ci 3596f08c3bdfSopenharmony_ci/* 3597f08c3bdfSopenharmony_ci * fsync(2) and fdatasync(2) 3598f08c3bdfSopenharmony_ci */ 3599f08c3bdfSopenharmony_ci#ifndef CRAY 3600f08c3bdfSopenharmony_ciint do_sync(struct io_req *req) 3601f08c3bdfSopenharmony_ci{ 3602f08c3bdfSopenharmony_ci int fd, oflags; 3603f08c3bdfSopenharmony_ci int rval; 3604f08c3bdfSopenharmony_ci char *file; 3605f08c3bdfSopenharmony_ci 3606f08c3bdfSopenharmony_ci /* 3607f08c3bdfSopenharmony_ci * Initialize common fields - assumes r_oflags, r_file, r_offset, and 3608f08c3bdfSopenharmony_ci * r_nbytes are at the same offset in the read_req and reada_req 3609f08c3bdfSopenharmony_ci * structures. 3610f08c3bdfSopenharmony_ci */ 3611f08c3bdfSopenharmony_ci file = req->r_data.io.r_file; 3612f08c3bdfSopenharmony_ci oflags = req->r_data.io.r_oflags; 3613f08c3bdfSopenharmony_ci 3614f08c3bdfSopenharmony_ci /* 3615f08c3bdfSopenharmony_ci * Get an open file descriptor 3616f08c3bdfSopenharmony_ci */ 3617f08c3bdfSopenharmony_ci 3618f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, oflags)) == -1) 3619f08c3bdfSopenharmony_ci return -1; 3620f08c3bdfSopenharmony_ci 3621f08c3bdfSopenharmony_ci rval = 0; 3622f08c3bdfSopenharmony_ci switch (req->r_type) { 3623f08c3bdfSopenharmony_ci case FSYNC2: 3624f08c3bdfSopenharmony_ci rval = fsync(fd); 3625f08c3bdfSopenharmony_ci break; 3626f08c3bdfSopenharmony_ci case FDATASYNC: 3627f08c3bdfSopenharmony_ci rval = fdatasync(fd); 3628f08c3bdfSopenharmony_ci break; 3629f08c3bdfSopenharmony_ci default: 3630f08c3bdfSopenharmony_ci rval = -1; 3631f08c3bdfSopenharmony_ci } 3632f08c3bdfSopenharmony_ci return (rval == -1) ? -1 : 0; 3633f08c3bdfSopenharmony_ci} 3634f08c3bdfSopenharmony_ci#endif /* !CRAY */ 3635f08c3bdfSopenharmony_ci 3636f08c3bdfSopenharmony_ciint 3637f08c3bdfSopenharmony_cidoio_pat_fill(char *addr, int mem_needed, char *Pattern, int Pattern_Length, 3638f08c3bdfSopenharmony_ci int shift) 3639f08c3bdfSopenharmony_ci{ 3640f08c3bdfSopenharmony_ci return pattern_fill(addr, mem_needed, Pattern, Pattern_Length, 0); 3641f08c3bdfSopenharmony_ci} 3642f08c3bdfSopenharmony_ci 3643f08c3bdfSopenharmony_cichar *doio_pat_check(char *buf, int offset, int length, char *pattern, 3644f08c3bdfSopenharmony_ci int pattern_length, int patshift) 3645f08c3bdfSopenharmony_ci{ 3646f08c3bdfSopenharmony_ci static char errbuf[4096]; 3647f08c3bdfSopenharmony_ci int nb, i, pattern_index; 3648f08c3bdfSopenharmony_ci char *cp, *bufend, *ep; 3649f08c3bdfSopenharmony_ci char actual[33], expected[33]; 3650f08c3bdfSopenharmony_ci 3651f08c3bdfSopenharmony_ci if (pattern_check(buf, length, pattern, pattern_length, patshift) != 0) { 3652f08c3bdfSopenharmony_ci ep = errbuf; 3653f08c3bdfSopenharmony_ci ep += 3654f08c3bdfSopenharmony_ci sprintf(ep, 3655f08c3bdfSopenharmony_ci "Corrupt regions follow - unprintable chars are represented as '.'\n"); 3656f08c3bdfSopenharmony_ci ep += 3657f08c3bdfSopenharmony_ci sprintf(ep, 3658f08c3bdfSopenharmony_ci "-----------------------------------------------------------------\n"); 3659f08c3bdfSopenharmony_ci 3660f08c3bdfSopenharmony_ci pattern_index = patshift % pattern_length;; 3661f08c3bdfSopenharmony_ci cp = buf; 3662f08c3bdfSopenharmony_ci bufend = buf + length; 3663f08c3bdfSopenharmony_ci 3664f08c3bdfSopenharmony_ci while (cp < bufend) { 3665f08c3bdfSopenharmony_ci if (*cp != pattern[pattern_index]) { 3666f08c3bdfSopenharmony_ci nb = bufend - cp; 3667f08c3bdfSopenharmony_ci if ((unsigned int)nb > sizeof(expected) - 1) { 3668f08c3bdfSopenharmony_ci nb = sizeof(expected) - 1; 3669f08c3bdfSopenharmony_ci } 3670f08c3bdfSopenharmony_ci 3671f08c3bdfSopenharmony_ci ep += 3672f08c3bdfSopenharmony_ci sprintf(ep, 3673f08c3bdfSopenharmony_ci "corrupt bytes starting at file offset %d\n", 3674f08c3bdfSopenharmony_ci offset + (int)(cp - buf)); 3675f08c3bdfSopenharmony_ci 3676f08c3bdfSopenharmony_ci /* 3677f08c3bdfSopenharmony_ci * Fill in the expected and actual patterns 3678f08c3bdfSopenharmony_ci */ 3679f08c3bdfSopenharmony_ci memset(expected, 0x00, sizeof(expected)); 3680f08c3bdfSopenharmony_ci memset(actual, 0x00, sizeof(actual)); 3681f08c3bdfSopenharmony_ci 3682f08c3bdfSopenharmony_ci for (i = 0; i < nb; i++) { 3683f08c3bdfSopenharmony_ci expected[i] = 3684f08c3bdfSopenharmony_ci pattern[(pattern_index + 3685f08c3bdfSopenharmony_ci i) % pattern_length]; 3686f08c3bdfSopenharmony_ci if (!isprint(expected[i])) { 3687f08c3bdfSopenharmony_ci expected[i] = '.'; 3688f08c3bdfSopenharmony_ci } 3689f08c3bdfSopenharmony_ci 3690f08c3bdfSopenharmony_ci actual[i] = cp[i]; 3691f08c3bdfSopenharmony_ci if (!isprint(actual[i])) { 3692f08c3bdfSopenharmony_ci actual[i] = '.'; 3693f08c3bdfSopenharmony_ci } 3694f08c3bdfSopenharmony_ci } 3695f08c3bdfSopenharmony_ci 3696f08c3bdfSopenharmony_ci ep += 3697f08c3bdfSopenharmony_ci sprintf(ep, 3698f08c3bdfSopenharmony_ci " 1st %2d expected bytes: %s\n", 3699f08c3bdfSopenharmony_ci nb, expected); 3700f08c3bdfSopenharmony_ci ep += 3701f08c3bdfSopenharmony_ci sprintf(ep, 3702f08c3bdfSopenharmony_ci " 1st %2d actual bytes: %s\n", 3703f08c3bdfSopenharmony_ci nb, actual); 3704f08c3bdfSopenharmony_ci fflush(stderr); 3705f08c3bdfSopenharmony_ci return errbuf; 3706f08c3bdfSopenharmony_ci } else { 3707f08c3bdfSopenharmony_ci cp++; 3708f08c3bdfSopenharmony_ci pattern_index++; 3709f08c3bdfSopenharmony_ci 3710f08c3bdfSopenharmony_ci if (pattern_index == pattern_length) { 3711f08c3bdfSopenharmony_ci pattern_index = 0; 3712f08c3bdfSopenharmony_ci } 3713f08c3bdfSopenharmony_ci } 3714f08c3bdfSopenharmony_ci } 3715f08c3bdfSopenharmony_ci return errbuf; 3716f08c3bdfSopenharmony_ci } 3717f08c3bdfSopenharmony_ci 3718f08c3bdfSopenharmony_ci return NULL; 3719f08c3bdfSopenharmony_ci} 3720f08c3bdfSopenharmony_ci 3721f08c3bdfSopenharmony_ci/* 3722f08c3bdfSopenharmony_ci * Check the contents of a file beginning at offset, for length bytes. It 3723f08c3bdfSopenharmony_ci * is assumed that there is a string of pattern bytes in this area of the 3724f08c3bdfSopenharmony_ci * file. Use normal buffered reads to do the verification. 3725f08c3bdfSopenharmony_ci * 3726f08c3bdfSopenharmony_ci * If there is a data mismatch, write a detailed message into a static buffer 3727f08c3bdfSopenharmony_ci * suitable for the caller to print. Otherwise print NULL. 3728f08c3bdfSopenharmony_ci * 3729f08c3bdfSopenharmony_ci * The fsa flag is set to non-zero if the buffer should be read back through 3730f08c3bdfSopenharmony_ci * the FSA (unicos/mk). This implies the file will be opened 3731f08c3bdfSopenharmony_ci * O_PARALLEL|O_RAW|O_WELLFORMED to do the validation. We must do this because 3732f08c3bdfSopenharmony_ci * FSA will not allow the file to be opened for buffered io if it was 3733f08c3bdfSopenharmony_ci * previously opened for O_PARALLEL io. 3734f08c3bdfSopenharmony_ci */ 3735f08c3bdfSopenharmony_ci 3736f08c3bdfSopenharmony_cichar *check_file(char *file, int offset, int length, char *pattern, 3737f08c3bdfSopenharmony_ci int pattern_length, int patshift, int fsa) 3738f08c3bdfSopenharmony_ci{ 3739f08c3bdfSopenharmony_ci static char errbuf[4096]; 3740f08c3bdfSopenharmony_ci int fd, nb, flags; 3741f08c3bdfSopenharmony_ci char *buf, *em, *ep; 3742f08c3bdfSopenharmony_ci#ifdef sgi 3743f08c3bdfSopenharmony_ci struct fd_cache *fdc; 3744f08c3bdfSopenharmony_ci#endif 3745f08c3bdfSopenharmony_ci 3746f08c3bdfSopenharmony_ci buf = Memptr; 3747f08c3bdfSopenharmony_ci 3748f08c3bdfSopenharmony_ci if (V_opt) { 3749f08c3bdfSopenharmony_ci flags = Validation_Flags | O_RDONLY; 3750f08c3bdfSopenharmony_ci } else { 3751f08c3bdfSopenharmony_ci flags = O_RDONLY; 3752f08c3bdfSopenharmony_ci if (fsa) { 3753f08c3bdfSopenharmony_ci#ifdef CRAY 3754f08c3bdfSopenharmony_ci flags |= O_PARALLEL | O_RAW | O_WELLFORMED; 3755f08c3bdfSopenharmony_ci#endif 3756f08c3bdfSopenharmony_ci } 3757f08c3bdfSopenharmony_ci } 3758f08c3bdfSopenharmony_ci 3759f08c3bdfSopenharmony_ci if ((fd = alloc_fd(file, flags)) == -1) { 3760f08c3bdfSopenharmony_ci sprintf(errbuf, 3761f08c3bdfSopenharmony_ci "Could not open file %s with flags %#o (%s) for data comparison: %s (%d)\n", 3762f08c3bdfSopenharmony_ci file, flags, format_oflags(flags), SYSERR, errno); 3763f08c3bdfSopenharmony_ci return errbuf; 3764f08c3bdfSopenharmony_ci } 3765f08c3bdfSopenharmony_ci 3766f08c3bdfSopenharmony_ci if (lseek(fd, offset, SEEK_SET) == -1) { 3767f08c3bdfSopenharmony_ci sprintf(errbuf, 3768f08c3bdfSopenharmony_ci "Could not lseek to offset %d in %s for verification: %s (%d)\n", 3769f08c3bdfSopenharmony_ci offset, file, SYSERR, errno); 3770f08c3bdfSopenharmony_ci return errbuf; 3771f08c3bdfSopenharmony_ci } 3772f08c3bdfSopenharmony_ci#ifdef sgi 3773f08c3bdfSopenharmony_ci /* Irix: Guarantee a properly aligned address on Direct I/O */ 3774f08c3bdfSopenharmony_ci fdc = alloc_fdcache(file, flags); 3775f08c3bdfSopenharmony_ci if ((flags & O_DIRECT) && ((long)buf % fdc->c_memalign != 0)) { 3776f08c3bdfSopenharmony_ci buf += fdc->c_memalign - ((long)buf % fdc->c_memalign); 3777f08c3bdfSopenharmony_ci } 3778f08c3bdfSopenharmony_ci#endif 3779f08c3bdfSopenharmony_ci 3780f08c3bdfSopenharmony_ci if ((nb = read(fd, buf, length)) == -1) { 3781f08c3bdfSopenharmony_ci#ifdef sgi 3782f08c3bdfSopenharmony_ci sprintf(errbuf, 3783f08c3bdfSopenharmony_ci "Could not read %d bytes from %s for verification: %s (%d)\n\tread(%d, 0x%lx, %d)\n\tbuf %% alignment(%d) = %ld\n", 3784f08c3bdfSopenharmony_ci length, file, SYSERR, errno, 3785f08c3bdfSopenharmony_ci fd, buf, length, 3786f08c3bdfSopenharmony_ci fdc->c_memalign, (long)buf % fdc->c_memalign); 3787f08c3bdfSopenharmony_ci#else 3788f08c3bdfSopenharmony_ci sprintf(errbuf, 3789f08c3bdfSopenharmony_ci "Could not read %d bytes from %s for verification: %s (%d)\n", 3790f08c3bdfSopenharmony_ci length, file, SYSERR, errno); 3791f08c3bdfSopenharmony_ci 3792f08c3bdfSopenharmony_ci#endif 3793f08c3bdfSopenharmony_ci return errbuf; 3794f08c3bdfSopenharmony_ci } 3795f08c3bdfSopenharmony_ci 3796f08c3bdfSopenharmony_ci if (nb != length) { 3797f08c3bdfSopenharmony_ci sprintf(errbuf, 3798f08c3bdfSopenharmony_ci "Read wrong # bytes from %s. Expected %d, got %d\n", 3799f08c3bdfSopenharmony_ci file, length, nb); 3800f08c3bdfSopenharmony_ci return errbuf; 3801f08c3bdfSopenharmony_ci } 3802f08c3bdfSopenharmony_ci 3803f08c3bdfSopenharmony_ci if ((em = 3804f08c3bdfSopenharmony_ci (*Data_Check) (buf, offset, length, pattern, pattern_length, 3805f08c3bdfSopenharmony_ci patshift)) != NULL) { 3806f08c3bdfSopenharmony_ci ep = errbuf; 3807f08c3bdfSopenharmony_ci ep += sprintf(ep, "*** DATA COMPARISON ERROR ***\n"); 3808f08c3bdfSopenharmony_ci ep += 3809f08c3bdfSopenharmony_ci sprintf(ep, "check_file(%s, %d, %d, %s, %d, %d) failed\n\n", 3810f08c3bdfSopenharmony_ci file, offset, length, pattern, pattern_length, 3811f08c3bdfSopenharmony_ci patshift); 3812f08c3bdfSopenharmony_ci ep += 3813f08c3bdfSopenharmony_ci sprintf(ep, "Comparison fd is %d, with open flags %#o\n", 3814f08c3bdfSopenharmony_ci fd, flags); 3815f08c3bdfSopenharmony_ci strcpy(ep, em); 3816f08c3bdfSopenharmony_ci return (errbuf); 3817f08c3bdfSopenharmony_ci } 3818f08c3bdfSopenharmony_ci return NULL; 3819f08c3bdfSopenharmony_ci} 3820f08c3bdfSopenharmony_ci 3821f08c3bdfSopenharmony_ci/* 3822f08c3bdfSopenharmony_ci * Function to single-thread stdio output. 3823f08c3bdfSopenharmony_ci */ 3824f08c3bdfSopenharmony_ci 3825f08c3bdfSopenharmony_ciint doio_fprintf(FILE * stream, char *format, ...) 3826f08c3bdfSopenharmony_ci{ 3827f08c3bdfSopenharmony_ci static int pid = -1; 3828f08c3bdfSopenharmony_ci char *date; 3829f08c3bdfSopenharmony_ci int rval; 3830f08c3bdfSopenharmony_ci struct flock flk; 3831f08c3bdfSopenharmony_ci va_list arglist; 3832f08c3bdfSopenharmony_ci struct timeval ts; 3833f08c3bdfSopenharmony_ci gettimeofday(&ts, NULL); 3834f08c3bdfSopenharmony_ci date = hms(ts.tv_sec); 3835f08c3bdfSopenharmony_ci 3836f08c3bdfSopenharmony_ci if (pid == -1) { 3837f08c3bdfSopenharmony_ci pid = getpid(); 3838f08c3bdfSopenharmony_ci } 3839f08c3bdfSopenharmony_ci 3840f08c3bdfSopenharmony_ci flk.l_whence = flk.l_start = flk.l_len = 0; 3841f08c3bdfSopenharmony_ci flk.l_type = F_WRLCK; 3842f08c3bdfSopenharmony_ci fcntl(fileno(stream), F_SETLKW, &flk); 3843f08c3bdfSopenharmony_ci 3844f08c3bdfSopenharmony_ci va_start(arglist, format); 3845f08c3bdfSopenharmony_ci rval = fprintf(stream, "\n%s%s (%5d) %s\n", Prog, TagName, pid, date); 3846f08c3bdfSopenharmony_ci rval += fprintf(stream, "---------------------\n"); 3847f08c3bdfSopenharmony_ci vfprintf(stream, format, arglist); 3848f08c3bdfSopenharmony_ci va_end(arglist); 3849f08c3bdfSopenharmony_ci 3850f08c3bdfSopenharmony_ci fflush(stream); 3851f08c3bdfSopenharmony_ci 3852f08c3bdfSopenharmony_ci flk.l_type = F_UNLCK; 3853f08c3bdfSopenharmony_ci fcntl(fileno(stream), F_SETLKW, &flk); 3854f08c3bdfSopenharmony_ci 3855f08c3bdfSopenharmony_ci return rval; 3856f08c3bdfSopenharmony_ci} 3857f08c3bdfSopenharmony_ci 3858f08c3bdfSopenharmony_ci/* 3859f08c3bdfSopenharmony_ci * Simple function for allocating core memory. Uses Memsize and Memptr to 3860f08c3bdfSopenharmony_ci * keep track of the current amount allocated. 3861f08c3bdfSopenharmony_ci */ 3862f08c3bdfSopenharmony_ci#ifndef CRAY 3863f08c3bdfSopenharmony_ciint alloc_mem(int nbytes) 3864f08c3bdfSopenharmony_ci{ 3865f08c3bdfSopenharmony_ci char *cp; 3866f08c3bdfSopenharmony_ci void *addr; 3867f08c3bdfSopenharmony_ci int me = 0, flags, key, shmid; 3868f08c3bdfSopenharmony_ci static int mturn = 0; /* which memory type to use */ 3869f08c3bdfSopenharmony_ci struct memalloc *M; 3870f08c3bdfSopenharmony_ci char filename[255]; 3871f08c3bdfSopenharmony_ci#ifdef __linux__ 3872f08c3bdfSopenharmony_ci struct shmid_ds shm_ds; 3873f08c3bdfSopenharmony_ci#endif 3874f08c3bdfSopenharmony_ci 3875f08c3bdfSopenharmony_ci#ifdef __linux__ 3876f08c3bdfSopenharmony_ci memset(&shm_ds, 0x00, sizeof(struct shmid_ds)); 3877f08c3bdfSopenharmony_ci#endif 3878f08c3bdfSopenharmony_ci 3879f08c3bdfSopenharmony_ci /* nbytes = -1 means "free all allocated memory" */ 3880f08c3bdfSopenharmony_ci if (nbytes == -1) { 3881f08c3bdfSopenharmony_ci 3882f08c3bdfSopenharmony_ci for (me = 0; me < Nmemalloc; me++) { 3883f08c3bdfSopenharmony_ci if (Memalloc[me].space == NULL) 3884f08c3bdfSopenharmony_ci continue; 3885f08c3bdfSopenharmony_ci 3886f08c3bdfSopenharmony_ci switch (Memalloc[me].memtype) { 3887f08c3bdfSopenharmony_ci case MEM_DATA: 3888f08c3bdfSopenharmony_ci#ifdef sgi 3889f08c3bdfSopenharmony_ci if (Memalloc[me].flags & MEMF_MPIN) 3890f08c3bdfSopenharmony_ci munpin(Memalloc[me].space, 3891f08c3bdfSopenharmony_ci Memalloc[me].size); 3892f08c3bdfSopenharmony_ci#endif 3893f08c3bdfSopenharmony_ci free(Memalloc[me].space); 3894f08c3bdfSopenharmony_ci Memalloc[me].space = NULL; 3895f08c3bdfSopenharmony_ci Memptr = NULL; 3896f08c3bdfSopenharmony_ci Memsize = 0; 3897f08c3bdfSopenharmony_ci break; 3898f08c3bdfSopenharmony_ci case MEM_SHMEM: 3899f08c3bdfSopenharmony_ci#ifdef sgi 3900f08c3bdfSopenharmony_ci if (Memalloc[me].flags & MEMF_MPIN) 3901f08c3bdfSopenharmony_ci munpin(Memalloc[me].space, 3902f08c3bdfSopenharmony_ci Memalloc[me].size); 3903f08c3bdfSopenharmony_ci#endif 3904f08c3bdfSopenharmony_ci shmdt(Memalloc[me].space); 3905f08c3bdfSopenharmony_ci Memalloc[me].space = NULL; 3906f08c3bdfSopenharmony_ci#ifdef sgi 3907f08c3bdfSopenharmony_ci shmctl(Memalloc[me].fd, IPC_RMID); 3908f08c3bdfSopenharmony_ci#else 3909f08c3bdfSopenharmony_ci shmctl(Memalloc[me].fd, IPC_RMID, &shm_ds); 3910f08c3bdfSopenharmony_ci#endif 3911f08c3bdfSopenharmony_ci break; 3912f08c3bdfSopenharmony_ci case MEM_MMAP: 3913f08c3bdfSopenharmony_ci#ifdef sgi 3914f08c3bdfSopenharmony_ci if (Memalloc[me].flags & MEMF_MPIN) 3915f08c3bdfSopenharmony_ci munpin(Memalloc[me].space, 3916f08c3bdfSopenharmony_ci Memalloc[me].size); 3917f08c3bdfSopenharmony_ci#endif 3918f08c3bdfSopenharmony_ci munmap(Memalloc[me].space, Memalloc[me].size); 3919f08c3bdfSopenharmony_ci close(Memalloc[me].fd); 3920f08c3bdfSopenharmony_ci if (Memalloc[me].flags & MEMF_FILE) { 3921f08c3bdfSopenharmony_ci unlink(Memalloc[me].name); 3922f08c3bdfSopenharmony_ci } 3923f08c3bdfSopenharmony_ci Memalloc[me].space = NULL; 3924f08c3bdfSopenharmony_ci break; 3925f08c3bdfSopenharmony_ci default: 3926f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3927f08c3bdfSopenharmony_ci "alloc_mem: HELP! Unknown memory space type %d index %d\n", 3928f08c3bdfSopenharmony_ci Memalloc[me].memtype, me); 3929f08c3bdfSopenharmony_ci break; 3930f08c3bdfSopenharmony_ci } 3931f08c3bdfSopenharmony_ci } 3932f08c3bdfSopenharmony_ci return 0; 3933f08c3bdfSopenharmony_ci } 3934f08c3bdfSopenharmony_ci 3935f08c3bdfSopenharmony_ci /* 3936f08c3bdfSopenharmony_ci * Select a memory area (currently round-robbin) 3937f08c3bdfSopenharmony_ci */ 3938f08c3bdfSopenharmony_ci 3939f08c3bdfSopenharmony_ci if (mturn >= Nmemalloc) 3940f08c3bdfSopenharmony_ci mturn = 0; 3941f08c3bdfSopenharmony_ci 3942f08c3bdfSopenharmony_ci M = &Memalloc[mturn]; 3943f08c3bdfSopenharmony_ci 3944f08c3bdfSopenharmony_ci switch (M->memtype) { 3945f08c3bdfSopenharmony_ci case MEM_DATA: 3946f08c3bdfSopenharmony_ci if (nbytes > M->size) { 3947f08c3bdfSopenharmony_ci if (M->space != NULL) { 3948f08c3bdfSopenharmony_ci#ifdef sgi 3949f08c3bdfSopenharmony_ci if (M->flags & MEMF_MPIN) 3950f08c3bdfSopenharmony_ci munpin(M->space, M->size); 3951f08c3bdfSopenharmony_ci#endif 3952f08c3bdfSopenharmony_ci free(M->space); 3953f08c3bdfSopenharmony_ci } 3954f08c3bdfSopenharmony_ci M->space = NULL; 3955f08c3bdfSopenharmony_ci M->size = 0; 3956f08c3bdfSopenharmony_ci } 3957f08c3bdfSopenharmony_ci 3958f08c3bdfSopenharmony_ci if (M->space == NULL) { 3959f08c3bdfSopenharmony_ci if ((cp = malloc(nbytes)) == NULL) { 3960f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3961f08c3bdfSopenharmony_ci "malloc(%d) failed: %s (%d)\n", 3962f08c3bdfSopenharmony_ci nbytes, SYSERR, errno); 3963f08c3bdfSopenharmony_ci return -1; 3964f08c3bdfSopenharmony_ci } 3965f08c3bdfSopenharmony_ci#ifdef sgi 3966f08c3bdfSopenharmony_ci if (M->flags & MEMF_MPIN) { 3967f08c3bdfSopenharmony_ci if (mpin(cp, nbytes) == -1) { 3968f08c3bdfSopenharmony_ci doio_fprintf(stderr, 3969f08c3bdfSopenharmony_ci "mpin(0x%lx, %d) failed: %s (%d)\n", 3970f08c3bdfSopenharmony_ci cp, nbytes, SYSERR, errno); 3971f08c3bdfSopenharmony_ci } 3972f08c3bdfSopenharmony_ci } 3973f08c3bdfSopenharmony_ci#endif 3974f08c3bdfSopenharmony_ci M->space = (void *)cp; 3975f08c3bdfSopenharmony_ci M->size = nbytes; 3976f08c3bdfSopenharmony_ci } 3977f08c3bdfSopenharmony_ci break; 3978f08c3bdfSopenharmony_ci 3979f08c3bdfSopenharmony_ci case MEM_MMAP: 3980f08c3bdfSopenharmony_ci if (nbytes > M->size) { 3981f08c3bdfSopenharmony_ci if (M->space != NULL) { 3982f08c3bdfSopenharmony_ci#ifdef sgi 3983f08c3bdfSopenharmony_ci if (M->flags & MEMF_MPIN) 3984f08c3bdfSopenharmony_ci munpin(M->space, M->size); 3985f08c3bdfSopenharmony_ci#endif 3986f08c3bdfSopenharmony_ci munmap(M->space, M->size); 3987f08c3bdfSopenharmony_ci close(M->fd); 3988f08c3bdfSopenharmony_ci if (M->flags & MEMF_FILE) 3989f08c3bdfSopenharmony_ci unlink(M->name); 3990f08c3bdfSopenharmony_ci } 3991f08c3bdfSopenharmony_ci M->space = NULL; 3992f08c3bdfSopenharmony_ci M->size = 0; 3993f08c3bdfSopenharmony_ci } 3994f08c3bdfSopenharmony_ci 3995f08c3bdfSopenharmony_ci if (M->space == NULL) { 3996f08c3bdfSopenharmony_ci if (strchr(M->name, '%')) { 3997f08c3bdfSopenharmony_ci sprintf(filename, M->name, getpid()); 3998f08c3bdfSopenharmony_ci M->name = strdup(filename); 3999f08c3bdfSopenharmony_ci } 4000f08c3bdfSopenharmony_ci 4001f08c3bdfSopenharmony_ci if ((M->fd = 4002f08c3bdfSopenharmony_ci open(M->name, O_CREAT | O_RDWR, 0666)) == -1) { 4003f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4004f08c3bdfSopenharmony_ci "alloc_mmap: error %d (%s) opening '%s'\n", 4005f08c3bdfSopenharmony_ci errno, SYSERR, M->name); 4006f08c3bdfSopenharmony_ci return (-1); 4007f08c3bdfSopenharmony_ci } 4008f08c3bdfSopenharmony_ci 4009f08c3bdfSopenharmony_ci addr = NULL; 4010f08c3bdfSopenharmony_ci flags = 0; 4011f08c3bdfSopenharmony_ci M->size = nbytes * 4; 4012f08c3bdfSopenharmony_ci 4013f08c3bdfSopenharmony_ci /* bias addr if MEMF_ADDR | MEMF_FIXADDR */ 4014f08c3bdfSopenharmony_ci /* >>> how to pick a memory address? */ 4015f08c3bdfSopenharmony_ci 4016f08c3bdfSopenharmony_ci /* bias flags on MEMF_PRIVATE etc */ 4017f08c3bdfSopenharmony_ci if (M->flags & MEMF_PRIVATE) 4018f08c3bdfSopenharmony_ci flags |= MAP_PRIVATE; 4019f08c3bdfSopenharmony_ci#ifdef sgi 4020f08c3bdfSopenharmony_ci if (M->flags & MEMF_LOCAL) 4021f08c3bdfSopenharmony_ci flags |= MAP_LOCAL; 4022f08c3bdfSopenharmony_ci if (M->flags & MEMF_AUTORESRV) 4023f08c3bdfSopenharmony_ci flags |= MAP_AUTORESRV; 4024f08c3bdfSopenharmony_ci if (M->flags & MEMF_AUTOGROW) 4025f08c3bdfSopenharmony_ci flags |= MAP_AUTOGROW; 4026f08c3bdfSopenharmony_ci#endif 4027f08c3bdfSopenharmony_ci if (M->flags & MEMF_SHARED) 4028f08c3bdfSopenharmony_ci flags |= MAP_SHARED; 4029f08c3bdfSopenharmony_ci 4030f08c3bdfSopenharmony_ci/*printf("alloc_mem, about to mmap, fd=%d, name=(%s)\n", M->fd, M->name);*/ 4031f08c3bdfSopenharmony_ci if ((M->space = mmap(addr, M->size, 4032f08c3bdfSopenharmony_ci PROT_READ | PROT_WRITE, 4033f08c3bdfSopenharmony_ci flags, M->fd, 0)) 4034f08c3bdfSopenharmony_ci == MAP_FAILED) { 4035f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4036f08c3bdfSopenharmony_ci "alloc_mem: mmap error. errno %d (%s)\n\tmmap(addr 0x%x, size %d, read|write 0x%x, mmap flags 0x%x [%#o], fd %d, 0)\n\tfile %s\n", 4037f08c3bdfSopenharmony_ci errno, SYSERR, addr, M->size, 4038f08c3bdfSopenharmony_ci PROT_READ | PROT_WRITE, flags, 4039f08c3bdfSopenharmony_ci M->flags, M->fd, M->name); 4040f08c3bdfSopenharmony_ci doio_fprintf(stderr, "\t%s%s%s%s%s", 4041f08c3bdfSopenharmony_ci (flags & MAP_PRIVATE) ? "private " 4042f08c3bdfSopenharmony_ci : "", 4043f08c3bdfSopenharmony_ci#ifdef sgi 4044f08c3bdfSopenharmony_ci (flags & MAP_LOCAL) ? "local " : 4045f08c3bdfSopenharmony_ci "", 4046f08c3bdfSopenharmony_ci (flags & MAP_AUTORESRV) ? 4047f08c3bdfSopenharmony_ci "autoresrv " : "", 4048f08c3bdfSopenharmony_ci (flags & MAP_AUTOGROW) ? 4049f08c3bdfSopenharmony_ci "autogrow " : "", 4050f08c3bdfSopenharmony_ci#endif 4051f08c3bdfSopenharmony_ci (flags & MAP_SHARED) ? "shared" : 4052f08c3bdfSopenharmony_ci ""); 4053f08c3bdfSopenharmony_ci return (-1); 4054f08c3bdfSopenharmony_ci } 4055f08c3bdfSopenharmony_ci } 4056f08c3bdfSopenharmony_ci break; 4057f08c3bdfSopenharmony_ci 4058f08c3bdfSopenharmony_ci case MEM_SHMEM: 4059f08c3bdfSopenharmony_ci if (nbytes > M->size) { 4060f08c3bdfSopenharmony_ci if (M->space != NULL) { 4061f08c3bdfSopenharmony_ci#ifdef sgi 4062f08c3bdfSopenharmony_ci if (M->flags & MEMF_MPIN) 4063f08c3bdfSopenharmony_ci munpin(M->space, M->size); 4064f08c3bdfSopenharmony_ci#endif 4065f08c3bdfSopenharmony_ci shmdt(M->space); 4066f08c3bdfSopenharmony_ci#ifdef sgi 4067f08c3bdfSopenharmony_ci shmctl(M->fd, IPC_RMID); 4068f08c3bdfSopenharmony_ci#else 4069f08c3bdfSopenharmony_ci shmctl(M->fd, IPC_RMID, &shm_ds); 4070f08c3bdfSopenharmony_ci#endif 4071f08c3bdfSopenharmony_ci } 4072f08c3bdfSopenharmony_ci M->space = NULL; 4073f08c3bdfSopenharmony_ci M->size = 0; 4074f08c3bdfSopenharmony_ci } 4075f08c3bdfSopenharmony_ci 4076f08c3bdfSopenharmony_ci if (M->space == NULL) { 4077f08c3bdfSopenharmony_ci if (!strcmp(M->name, "private")) { 4078f08c3bdfSopenharmony_ci key = IPC_PRIVATE; 4079f08c3bdfSopenharmony_ci } else { 4080f08c3bdfSopenharmony_ci sscanf(M->name, "%i", &key); 4081f08c3bdfSopenharmony_ci } 4082f08c3bdfSopenharmony_ci 4083f08c3bdfSopenharmony_ci M->size = M->nblks ? M->nblks * 512 : nbytes; 4084f08c3bdfSopenharmony_ci 4085f08c3bdfSopenharmony_ci if (nbytes > M->size) { 4086f08c3bdfSopenharmony_ci#ifdef DEBUG 4087f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4088f08c3bdfSopenharmony_ci "MEM_SHMEM: nblks(%d) too small: nbytes=%d Msize=%d, skipping this req.\n", 4089f08c3bdfSopenharmony_ci M->nblks, nbytes, M->size); 4090f08c3bdfSopenharmony_ci#endif 4091f08c3bdfSopenharmony_ci return SKIP_REQ; 4092f08c3bdfSopenharmony_ci } 4093f08c3bdfSopenharmony_ci 4094f08c3bdfSopenharmony_ci shmid = shmget(key, M->size, IPC_CREAT | 0666); 4095f08c3bdfSopenharmony_ci if (shmid == -1) { 4096f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4097f08c3bdfSopenharmony_ci "shmget(0x%x, %d, CREAT) failed: %s (%d)\n", 4098f08c3bdfSopenharmony_ci key, M->size, SYSERR, errno); 4099f08c3bdfSopenharmony_ci return (-1); 4100f08c3bdfSopenharmony_ci } 4101f08c3bdfSopenharmony_ci M->fd = shmid; 4102f08c3bdfSopenharmony_ci M->space = shmat(shmid, NULL, SHM_RND); 4103f08c3bdfSopenharmony_ci if (M->space == (void *)-1) { 4104f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4105f08c3bdfSopenharmony_ci "shmat(0x%x, NULL, SHM_RND) failed: %s (%d)\n", 4106f08c3bdfSopenharmony_ci shmid, SYSERR, errno); 4107f08c3bdfSopenharmony_ci return (-1); 4108f08c3bdfSopenharmony_ci } 4109f08c3bdfSopenharmony_ci#ifdef sgi 4110f08c3bdfSopenharmony_ci if (M->flags & MEMF_MPIN) { 4111f08c3bdfSopenharmony_ci if (mpin(M->space, M->size) == -1) { 4112f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4113f08c3bdfSopenharmony_ci "mpin(0x%lx, %d) failed: %s (%d)\n", 4114f08c3bdfSopenharmony_ci M->space, M->size, SYSERR, 4115f08c3bdfSopenharmony_ci errno); 4116f08c3bdfSopenharmony_ci } 4117f08c3bdfSopenharmony_ci } 4118f08c3bdfSopenharmony_ci#endif 4119f08c3bdfSopenharmony_ci } 4120f08c3bdfSopenharmony_ci break; 4121f08c3bdfSopenharmony_ci 4122f08c3bdfSopenharmony_ci default: 4123f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4124f08c3bdfSopenharmony_ci "alloc_mem: HELP! Unknown memory space type %d index %d\n", 4125f08c3bdfSopenharmony_ci Memalloc[me].memtype, mturn); 4126f08c3bdfSopenharmony_ci break; 4127f08c3bdfSopenharmony_ci } 4128f08c3bdfSopenharmony_ci 4129f08c3bdfSopenharmony_ci Memptr = M->space; 4130f08c3bdfSopenharmony_ci Memsize = M->size; 4131f08c3bdfSopenharmony_ci 4132f08c3bdfSopenharmony_ci mturn++; 4133f08c3bdfSopenharmony_ci return 0; 4134f08c3bdfSopenharmony_ci} 4135f08c3bdfSopenharmony_ci#else /* CRAY */ 4136f08c3bdfSopenharmony_ciint alloc_mem(int nbytes) 4137f08c3bdfSopenharmony_ci{ 4138f08c3bdfSopenharmony_ci char *cp; 4139f08c3bdfSopenharmony_ci int ip; 4140f08c3bdfSopenharmony_ci static char *malloc_space; 4141f08c3bdfSopenharmony_ci 4142f08c3bdfSopenharmony_ci /* 4143f08c3bdfSopenharmony_ci * The "unicos" version of this did some stuff with sbrk; 4144f08c3bdfSopenharmony_ci * this caused problems with async I/O on irix, and now appears 4145f08c3bdfSopenharmony_ci * to be causing problems with FSA I/O on unicos/mk. 4146f08c3bdfSopenharmony_ci */ 4147f08c3bdfSopenharmony_ci#ifdef NOTDEF 4148f08c3bdfSopenharmony_ci if (nbytes > Memsize) { 4149f08c3bdfSopenharmony_ci if ((cp = (char *)sbrk(nbytes - Memsize)) == (char *)-1) { 4150f08c3bdfSopenharmony_ci doio_fprintf(stderr, "sbrk(%d) failed: %s (%d)\n", 4151f08c3bdfSopenharmony_ci nbytes - Memsize, SYSERR, errno); 4152f08c3bdfSopenharmony_ci return -1; 4153f08c3bdfSopenharmony_ci } 4154f08c3bdfSopenharmony_ci 4155f08c3bdfSopenharmony_ci if (Memsize == 0) 4156f08c3bdfSopenharmony_ci Memptr = cp; 4157f08c3bdfSopenharmony_ci Memsize += nbytes - Memsize; 4158f08c3bdfSopenharmony_ci } 4159f08c3bdfSopenharmony_ci#else 4160f08c3bdfSopenharmony_ci 4161f08c3bdfSopenharmony_ci /* nbytes = -1 means "free all allocated memory" */ 4162f08c3bdfSopenharmony_ci if (nbytes == -1) { 4163f08c3bdfSopenharmony_ci free(malloc_space); 4164f08c3bdfSopenharmony_ci Memptr = NULL; 4165f08c3bdfSopenharmony_ci Memsize = 0; 4166f08c3bdfSopenharmony_ci return 0; 4167f08c3bdfSopenharmony_ci } 4168f08c3bdfSopenharmony_ci 4169f08c3bdfSopenharmony_ci if (nbytes > Memsize) { 4170f08c3bdfSopenharmony_ci if (Memsize != 0) 4171f08c3bdfSopenharmony_ci free(malloc_space); 4172f08c3bdfSopenharmony_ci 4173f08c3bdfSopenharmony_ci if ((cp = malloc_space = malloc(nbytes)) == NULL) { 4174f08c3bdfSopenharmony_ci doio_fprintf(stderr, "malloc(%d) failed: %s (%d)\n", 4175f08c3bdfSopenharmony_ci nbytes, SYSERR, errno); 4176f08c3bdfSopenharmony_ci return -1; 4177f08c3bdfSopenharmony_ci } 4178f08c3bdfSopenharmony_ci#ifdef _CRAYT3E 4179f08c3bdfSopenharmony_ci /* T3E requires memory to be aligned on 0x40 word boundaries */ 4180f08c3bdfSopenharmony_ci ip = (int)cp; 4181f08c3bdfSopenharmony_ci if ((ip & 0x3F) != 0) { 4182f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4183f08c3bdfSopenharmony_ci "malloc(%d) = 0x%x(0x%x) not aligned by 0x%x\n", 4184f08c3bdfSopenharmony_ci nbytes, cp, ip, ip & 0x3f); 4185f08c3bdfSopenharmony_ci 4186f08c3bdfSopenharmony_ci free(cp); 4187f08c3bdfSopenharmony_ci if ((cp = malloc_space = malloc(nbytes + 0x40)) == NULL) { 4188f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4189f08c3bdfSopenharmony_ci "malloc(%d) failed: %s (%d)\n", 4190f08c3bdfSopenharmony_ci nbytes, SYSERR, errno); 4191f08c3bdfSopenharmony_ci return -1; 4192f08c3bdfSopenharmony_ci } 4193f08c3bdfSopenharmony_ci ip = (int)cp; 4194f08c3bdfSopenharmony_ci cp += (0x40 - (ip & 0x3F)); 4195f08c3bdfSopenharmony_ci } 4196f08c3bdfSopenharmony_ci#endif /* _CRAYT3E */ 4197f08c3bdfSopenharmony_ci Memptr = cp; 4198f08c3bdfSopenharmony_ci Memsize = nbytes; 4199f08c3bdfSopenharmony_ci } 4200f08c3bdfSopenharmony_ci#endif /* NOTDEF */ 4201f08c3bdfSopenharmony_ci return 0; 4202f08c3bdfSopenharmony_ci} 4203f08c3bdfSopenharmony_ci#endif /* CRAY */ 4204f08c3bdfSopenharmony_ci 4205f08c3bdfSopenharmony_ci/* 4206f08c3bdfSopenharmony_ci * Simple function for allocating sds space. Uses Sdssize and Sdsptr to 4207f08c3bdfSopenharmony_ci * keep track of location and size of currently allocated chunk. 4208f08c3bdfSopenharmony_ci */ 4209f08c3bdfSopenharmony_ci 4210f08c3bdfSopenharmony_ci#ifdef _CRAY1 4211f08c3bdfSopenharmony_ci 4212f08c3bdfSopenharmony_ciint alloc_sds(int nbytes) 4213f08c3bdfSopenharmony_ci{ 4214f08c3bdfSopenharmony_ci int nblks; 4215f08c3bdfSopenharmony_ci 4216f08c3bdfSopenharmony_ci if (nbytes > Sdssize) { 4217f08c3bdfSopenharmony_ci if ((nblks = ssbreak(btoc(nbytes - Sdssize))) == -1) { 4218f08c3bdfSopenharmony_ci doio_fprintf(stderr, "ssbreak(%d) failed: %s (%d)\n", 4219f08c3bdfSopenharmony_ci btoc(nbytes - Sdssize), SYSERR, errno); 4220f08c3bdfSopenharmony_ci return -1; 4221f08c3bdfSopenharmony_ci } 4222f08c3bdfSopenharmony_ci 4223f08c3bdfSopenharmony_ci Sdssize = ctob(nblks); 4224f08c3bdfSopenharmony_ci Sdsptr = 0; 4225f08c3bdfSopenharmony_ci } 4226f08c3bdfSopenharmony_ci 4227f08c3bdfSopenharmony_ci return 0; 4228f08c3bdfSopenharmony_ci} 4229f08c3bdfSopenharmony_ci 4230f08c3bdfSopenharmony_ci#else 4231f08c3bdfSopenharmony_ci 4232f08c3bdfSopenharmony_ci#ifdef CRAY 4233f08c3bdfSopenharmony_ci 4234f08c3bdfSopenharmony_ciint alloc_sds(int nbytes) 4235f08c3bdfSopenharmony_ci{ 4236f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4237f08c3bdfSopenharmony_ci "Internal Error - alloc_sds() called on a CRAY2 system\n"); 4238f08c3bdfSopenharmony_ci alloc_mem(-1); 4239f08c3bdfSopenharmony_ci exit(E_INTERNAL); 4240f08c3bdfSopenharmony_ci} 4241f08c3bdfSopenharmony_ci 4242f08c3bdfSopenharmony_ci#endif 4243f08c3bdfSopenharmony_ci 4244f08c3bdfSopenharmony_ci#endif /* _CRAY1 */ 4245f08c3bdfSopenharmony_ci 4246f08c3bdfSopenharmony_ci/* 4247f08c3bdfSopenharmony_ci * Function to maintain a file descriptor cache, so that doio does not have 4248f08c3bdfSopenharmony_ci * to do so many open() and close() calls. Descriptors are stored in the 4249f08c3bdfSopenharmony_ci * cache by file name, and open flags. Each entry also has a _rtc value 4250f08c3bdfSopenharmony_ci * associated with it which is used in aging. If doio cannot open a file 4251f08c3bdfSopenharmony_ci * because it already has too many open (ie. system limit hit) it will close 4252f08c3bdfSopenharmony_ci * the one in the cache that has the oldest _rtc value. 4253f08c3bdfSopenharmony_ci * 4254f08c3bdfSopenharmony_ci * If alloc_fd() is called with a file of NULL, it will close all descriptors 4255f08c3bdfSopenharmony_ci * in the cache, and free the memory in the cache. 4256f08c3bdfSopenharmony_ci */ 4257f08c3bdfSopenharmony_ci 4258f08c3bdfSopenharmony_ciint alloc_fd(char *file, int oflags) 4259f08c3bdfSopenharmony_ci{ 4260f08c3bdfSopenharmony_ci struct fd_cache *fdc; 4261f08c3bdfSopenharmony_ci struct fd_cache *alloc_fdcache(char *file, int oflags); 4262f08c3bdfSopenharmony_ci 4263f08c3bdfSopenharmony_ci fdc = alloc_fdcache(file, oflags); 4264f08c3bdfSopenharmony_ci if (fdc != NULL) 4265f08c3bdfSopenharmony_ci return (fdc->c_fd); 4266f08c3bdfSopenharmony_ci else 4267f08c3bdfSopenharmony_ci return (-1); 4268f08c3bdfSopenharmony_ci} 4269f08c3bdfSopenharmony_ci 4270f08c3bdfSopenharmony_cistruct fd_cache *alloc_fdcache(char *file, int oflags) 4271f08c3bdfSopenharmony_ci{ 4272f08c3bdfSopenharmony_ci int fd; 4273f08c3bdfSopenharmony_ci struct fd_cache *free_slot, *oldest_slot, *cp; 4274f08c3bdfSopenharmony_ci static int cache_size = 0; 4275f08c3bdfSopenharmony_ci static struct fd_cache *cache = NULL; 4276f08c3bdfSopenharmony_ci#ifdef sgi 4277f08c3bdfSopenharmony_ci struct dioattr finfo; 4278f08c3bdfSopenharmony_ci#endif 4279f08c3bdfSopenharmony_ci 4280f08c3bdfSopenharmony_ci /* 4281f08c3bdfSopenharmony_ci * If file is NULL, it means to free up the fd cache. 4282f08c3bdfSopenharmony_ci */ 4283f08c3bdfSopenharmony_ci 4284f08c3bdfSopenharmony_ci if (file == NULL && cache != NULL) { 4285f08c3bdfSopenharmony_ci for (cp = cache; cp < &cache[cache_size]; cp++) { 4286f08c3bdfSopenharmony_ci if (cp->c_fd != -1) { 4287f08c3bdfSopenharmony_ci close(cp->c_fd); 4288f08c3bdfSopenharmony_ci } 4289f08c3bdfSopenharmony_ci#ifndef CRAY 4290f08c3bdfSopenharmony_ci if (cp->c_memaddr != NULL) { 4291f08c3bdfSopenharmony_ci munmap(cp->c_memaddr, cp->c_memlen); 4292f08c3bdfSopenharmony_ci } 4293f08c3bdfSopenharmony_ci#endif 4294f08c3bdfSopenharmony_ci } 4295f08c3bdfSopenharmony_ci 4296f08c3bdfSopenharmony_ci free(cache); 4297f08c3bdfSopenharmony_ci cache = NULL; 4298f08c3bdfSopenharmony_ci cache_size = 0; 4299f08c3bdfSopenharmony_ci return 0; 4300f08c3bdfSopenharmony_ci } 4301f08c3bdfSopenharmony_ci 4302f08c3bdfSopenharmony_ci free_slot = NULL; 4303f08c3bdfSopenharmony_ci oldest_slot = NULL; 4304f08c3bdfSopenharmony_ci 4305f08c3bdfSopenharmony_ci /* 4306f08c3bdfSopenharmony_ci * Look for a fd in the cache. If one is found, return it directly. 4307f08c3bdfSopenharmony_ci * Otherwise, when this loop exits, oldest_slot will point to the 4308f08c3bdfSopenharmony_ci * oldest fd slot in the cache, and free_slot will point to an 4309f08c3bdfSopenharmony_ci * unoccupied slot if there are any. 4310f08c3bdfSopenharmony_ci */ 4311f08c3bdfSopenharmony_ci 4312f08c3bdfSopenharmony_ci for (cp = cache; cp != NULL && cp < &cache[cache_size]; cp++) { 4313f08c3bdfSopenharmony_ci if (cp->c_fd != -1 && 4314f08c3bdfSopenharmony_ci cp->c_oflags == oflags && strcmp(cp->c_file, file) == 0) { 4315f08c3bdfSopenharmony_ci#ifdef CRAY 4316f08c3bdfSopenharmony_ci cp->c_rtc = _rtc(); 4317f08c3bdfSopenharmony_ci#else 4318f08c3bdfSopenharmony_ci cp->c_rtc = Reqno; 4319f08c3bdfSopenharmony_ci#endif 4320f08c3bdfSopenharmony_ci return cp; 4321f08c3bdfSopenharmony_ci } 4322f08c3bdfSopenharmony_ci 4323f08c3bdfSopenharmony_ci if (cp->c_fd == -1) { 4324f08c3bdfSopenharmony_ci if (free_slot == NULL) { 4325f08c3bdfSopenharmony_ci free_slot = cp; 4326f08c3bdfSopenharmony_ci } 4327f08c3bdfSopenharmony_ci } else { 4328f08c3bdfSopenharmony_ci if (oldest_slot == NULL || 4329f08c3bdfSopenharmony_ci cp->c_rtc < oldest_slot->c_rtc) { 4330f08c3bdfSopenharmony_ci oldest_slot = cp; 4331f08c3bdfSopenharmony_ci } 4332f08c3bdfSopenharmony_ci } 4333f08c3bdfSopenharmony_ci } 4334f08c3bdfSopenharmony_ci 4335f08c3bdfSopenharmony_ci /* 4336f08c3bdfSopenharmony_ci * No matching file/oflags pair was found in the cache. Attempt to 4337f08c3bdfSopenharmony_ci * open a new fd. 4338f08c3bdfSopenharmony_ci */ 4339f08c3bdfSopenharmony_ci 4340f08c3bdfSopenharmony_ci if ((fd = open(file, oflags, 0666)) < 0) { 4341f08c3bdfSopenharmony_ci if (errno != EMFILE) { 4342f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4343f08c3bdfSopenharmony_ci "Could not open file %s with flags %#o (%s): %s (%d)\n", 4344f08c3bdfSopenharmony_ci file, oflags, format_oflags(oflags), 4345f08c3bdfSopenharmony_ci SYSERR, errno); 4346f08c3bdfSopenharmony_ci alloc_mem(-1); 4347f08c3bdfSopenharmony_ci exit(E_SETUP); 4348f08c3bdfSopenharmony_ci } 4349f08c3bdfSopenharmony_ci 4350f08c3bdfSopenharmony_ci /* 4351f08c3bdfSopenharmony_ci * If we get here, we have as many open fd's as we can have. 4352f08c3bdfSopenharmony_ci * Close the oldest one in the cache (pointed to by 4353f08c3bdfSopenharmony_ci * oldest_slot), and attempt to re-open. 4354f08c3bdfSopenharmony_ci */ 4355f08c3bdfSopenharmony_ci 4356f08c3bdfSopenharmony_ci close(oldest_slot->c_fd); 4357f08c3bdfSopenharmony_ci oldest_slot->c_fd = -1; 4358f08c3bdfSopenharmony_ci free_slot = oldest_slot; 4359f08c3bdfSopenharmony_ci 4360f08c3bdfSopenharmony_ci if ((fd = open(file, oflags, 0666)) < 0) { 4361f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4362f08c3bdfSopenharmony_ci "Could not open file %s with flags %#o (%s): %s (%d)\n", 4363f08c3bdfSopenharmony_ci file, oflags, format_oflags(oflags), 4364f08c3bdfSopenharmony_ci SYSERR, errno); 4365f08c3bdfSopenharmony_ci alloc_mem(-1); 4366f08c3bdfSopenharmony_ci exit(E_SETUP); 4367f08c3bdfSopenharmony_ci } 4368f08c3bdfSopenharmony_ci } 4369f08c3bdfSopenharmony_ci 4370f08c3bdfSopenharmony_ci/*printf("alloc_fd: new file %s flags %#o fd %d\n", file, oflags, fd);*/ 4371f08c3bdfSopenharmony_ci 4372f08c3bdfSopenharmony_ci /* 4373f08c3bdfSopenharmony_ci * If we get here, fd is our open descriptor. If free_slot is NULL, 4374f08c3bdfSopenharmony_ci * we need to grow the cache, otherwise free_slot is the slot that 4375f08c3bdfSopenharmony_ci * should hold the fd info. 4376f08c3bdfSopenharmony_ci */ 4377f08c3bdfSopenharmony_ci 4378f08c3bdfSopenharmony_ci if (free_slot == NULL) { 4379f08c3bdfSopenharmony_ci cache = 4380f08c3bdfSopenharmony_ci (struct fd_cache *)realloc(cache, 4381f08c3bdfSopenharmony_ci sizeof(struct fd_cache) * 4382f08c3bdfSopenharmony_ci (FD_ALLOC_INCR + cache_size)); 4383f08c3bdfSopenharmony_ci if (cache == NULL) { 4384f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4385f08c3bdfSopenharmony_ci "Could not malloc() space for fd chace"); 4386f08c3bdfSopenharmony_ci alloc_mem(-1); 4387f08c3bdfSopenharmony_ci exit(E_SETUP); 4388f08c3bdfSopenharmony_ci } 4389f08c3bdfSopenharmony_ci 4390f08c3bdfSopenharmony_ci cache_size += FD_ALLOC_INCR; 4391f08c3bdfSopenharmony_ci 4392f08c3bdfSopenharmony_ci for (cp = &cache[cache_size - FD_ALLOC_INCR]; 4393f08c3bdfSopenharmony_ci cp < &cache[cache_size]; cp++) { 4394f08c3bdfSopenharmony_ci cp->c_fd = -1; 4395f08c3bdfSopenharmony_ci } 4396f08c3bdfSopenharmony_ci 4397f08c3bdfSopenharmony_ci free_slot = &cache[cache_size - FD_ALLOC_INCR]; 4398f08c3bdfSopenharmony_ci } 4399f08c3bdfSopenharmony_ci 4400f08c3bdfSopenharmony_ci /* 4401f08c3bdfSopenharmony_ci * finally, fill in the cache slot info 4402f08c3bdfSopenharmony_ci */ 4403f08c3bdfSopenharmony_ci 4404f08c3bdfSopenharmony_ci free_slot->c_fd = fd; 4405f08c3bdfSopenharmony_ci free_slot->c_oflags = oflags; 4406f08c3bdfSopenharmony_ci strcpy(free_slot->c_file, file); 4407f08c3bdfSopenharmony_ci#ifdef CRAY 4408f08c3bdfSopenharmony_ci free_slot->c_rtc = _rtc(); 4409f08c3bdfSopenharmony_ci#else 4410f08c3bdfSopenharmony_ci free_slot->c_rtc = Reqno; 4411f08c3bdfSopenharmony_ci#endif 4412f08c3bdfSopenharmony_ci 4413f08c3bdfSopenharmony_ci#ifdef sgi 4414f08c3bdfSopenharmony_ci if (oflags & O_DIRECT) { 4415f08c3bdfSopenharmony_ci if (fcntl(fd, F_DIOINFO, &finfo) == -1) { 4416f08c3bdfSopenharmony_ci finfo.d_mem = 1; 4417f08c3bdfSopenharmony_ci finfo.d_miniosz = 1; 4418f08c3bdfSopenharmony_ci finfo.d_maxiosz = 1; 4419f08c3bdfSopenharmony_ci } 4420f08c3bdfSopenharmony_ci } else { 4421f08c3bdfSopenharmony_ci finfo.d_mem = 1; 4422f08c3bdfSopenharmony_ci finfo.d_miniosz = 1; 4423f08c3bdfSopenharmony_ci finfo.d_maxiosz = 1; 4424f08c3bdfSopenharmony_ci } 4425f08c3bdfSopenharmony_ci 4426f08c3bdfSopenharmony_ci free_slot->c_memalign = finfo.d_mem; 4427f08c3bdfSopenharmony_ci free_slot->c_miniosz = finfo.d_miniosz; 4428f08c3bdfSopenharmony_ci free_slot->c_maxiosz = finfo.d_maxiosz; 4429f08c3bdfSopenharmony_ci#endif /* sgi */ 4430f08c3bdfSopenharmony_ci#ifndef CRAY 4431f08c3bdfSopenharmony_ci free_slot->c_memaddr = NULL; 4432f08c3bdfSopenharmony_ci free_slot->c_memlen = 0; 4433f08c3bdfSopenharmony_ci#endif 4434f08c3bdfSopenharmony_ci 4435f08c3bdfSopenharmony_ci return free_slot; 4436f08c3bdfSopenharmony_ci} 4437f08c3bdfSopenharmony_ci 4438f08c3bdfSopenharmony_ci/* 4439f08c3bdfSopenharmony_ci * 4440f08c3bdfSopenharmony_ci * Signal Handling Section 4441f08c3bdfSopenharmony_ci * 4442f08c3bdfSopenharmony_ci * 4443f08c3bdfSopenharmony_ci */ 4444f08c3bdfSopenharmony_ci 4445f08c3bdfSopenharmony_ci#ifdef sgi 4446f08c3bdfSopenharmony_ci/* 4447f08c3bdfSopenharmony_ci * "caller-id" for signals 4448f08c3bdfSopenharmony_ci */ 4449f08c3bdfSopenharmony_civoid signal_info(int sig, siginfo_t * info, void *v) 4450f08c3bdfSopenharmony_ci{ 4451f08c3bdfSopenharmony_ci int haveit = 0; 4452f08c3bdfSopenharmony_ci 4453f08c3bdfSopenharmony_ci if (info != NULL) { 4454f08c3bdfSopenharmony_ci switch (info->si_code) { 4455f08c3bdfSopenharmony_ci case SI_USER: 4456f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4457f08c3bdfSopenharmony_ci "signal_info: si_signo %d si_errno %d si_code SI_USER pid %d uid %d\n", 4458f08c3bdfSopenharmony_ci info->si_signo, info->si_errno, 4459f08c3bdfSopenharmony_ci info->si_pid, info->si_uid); 4460f08c3bdfSopenharmony_ci haveit = 1; 4461f08c3bdfSopenharmony_ci break; 4462f08c3bdfSopenharmony_ci 4463f08c3bdfSopenharmony_ci case SI_QUEUE: 4464f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4465f08c3bdfSopenharmony_ci "signal_info si_signo %d si_code = SI_QUEUE\n", 4466f08c3bdfSopenharmony_ci info->si_signo); 4467f08c3bdfSopenharmony_ci haveit = 1; 4468f08c3bdfSopenharmony_ci break; 4469f08c3bdfSopenharmony_ci } 4470f08c3bdfSopenharmony_ci 4471f08c3bdfSopenharmony_ci if (!haveit) { 4472f08c3bdfSopenharmony_ci if ((info->si_signo == SIGSEGV) || 4473f08c3bdfSopenharmony_ci (info->si_signo == SIGBUS)) { 4474f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4475f08c3bdfSopenharmony_ci "signal_info si_signo %d si_errno %d si_code = %d si_addr=%p active_mmap_rw=%d havesigint=%d\n", 4476f08c3bdfSopenharmony_ci info->si_signo, info->si_errno, 4477f08c3bdfSopenharmony_ci info->si_code, info->si_addr, 4478f08c3bdfSopenharmony_ci active_mmap_rw, havesigint); 4479f08c3bdfSopenharmony_ci haveit = 1; 4480f08c3bdfSopenharmony_ci } 4481f08c3bdfSopenharmony_ci } 4482f08c3bdfSopenharmony_ci 4483f08c3bdfSopenharmony_ci if (!haveit) { 4484f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4485f08c3bdfSopenharmony_ci "signal_info: si_signo %d si_errno %d unknown code %d\n", 4486f08c3bdfSopenharmony_ci info->si_signo, info->si_errno, 4487f08c3bdfSopenharmony_ci info->si_code); 4488f08c3bdfSopenharmony_ci } 4489f08c3bdfSopenharmony_ci } else { 4490f08c3bdfSopenharmony_ci doio_fprintf(stderr, "signal_info: sig %d\n", sig); 4491f08c3bdfSopenharmony_ci } 4492f08c3bdfSopenharmony_ci} 4493f08c3bdfSopenharmony_ci 4494f08c3bdfSopenharmony_civoid cleanup_handler(int sig, siginfo_t * info, void *v) 4495f08c3bdfSopenharmony_ci{ 4496f08c3bdfSopenharmony_ci havesigint = 1; /* in case there's a followup signal */ 4497f08c3bdfSopenharmony_ci /*signal_info(sig, info, v); *//* be quiet on "normal" kill */ 4498f08c3bdfSopenharmony_ci alloc_mem(-1); 4499f08c3bdfSopenharmony_ci exit(0); 4500f08c3bdfSopenharmony_ci} 4501f08c3bdfSopenharmony_ci 4502f08c3bdfSopenharmony_civoid die_handler(int sig, siginfo_t * info, void *v) 4503f08c3bdfSopenharmony_ci{ 4504f08c3bdfSopenharmony_ci doio_fprintf(stderr, "terminating on signal %d\n", sig); 4505f08c3bdfSopenharmony_ci signal_info(sig, info, v); 4506f08c3bdfSopenharmony_ci alloc_mem(-1); 4507f08c3bdfSopenharmony_ci exit(1); 4508f08c3bdfSopenharmony_ci} 4509f08c3bdfSopenharmony_ci 4510f08c3bdfSopenharmony_civoid sigbus_handler(int sig, siginfo_t * info, void *v) 4511f08c3bdfSopenharmony_ci{ 4512f08c3bdfSopenharmony_ci /* While we are doing a memcpy to/from an mmapped region we can 4513f08c3bdfSopenharmony_ci get a SIGBUS for a variety of reasons--and not all of them 4514f08c3bdfSopenharmony_ci should be considered failures. 4515f08c3bdfSopenharmony_ci 4516f08c3bdfSopenharmony_ci Under normal conditions if we get a SIGINT it means we've been 4517f08c3bdfSopenharmony_ci told to shutdown. However, if we're currently doing the above- 4518f08c3bdfSopenharmony_ci mentioned memcopy then the kernel will follow that SIGINT with 4519f08c3bdfSopenharmony_ci a SIGBUS. We can guess that we're in this situation by seeing 4520f08c3bdfSopenharmony_ci that the si_errno field in the siginfo structure has EINTR as 4521f08c3bdfSopenharmony_ci an errno. (We might make the guess stronger by looking at the 4522f08c3bdfSopenharmony_ci si_addr field to see that it's not faulting off the end of the 4523f08c3bdfSopenharmony_ci mmapped region, but it seems that in such a case havesigint 4524f08c3bdfSopenharmony_ci would not have been set so maybe that doesn't make the guess 4525f08c3bdfSopenharmony_ci stronger.) 4526f08c3bdfSopenharmony_ci */ 4527f08c3bdfSopenharmony_ci 4528f08c3bdfSopenharmony_ci if (active_mmap_rw && havesigint && (info->si_errno == EINTR)) { 4529f08c3bdfSopenharmony_ci cleanup_handler(sig, info, v); 4530f08c3bdfSopenharmony_ci } else { 4531f08c3bdfSopenharmony_ci die_handler(sig, info, v); 4532f08c3bdfSopenharmony_ci } 4533f08c3bdfSopenharmony_ci} 4534f08c3bdfSopenharmony_ci#else 4535f08c3bdfSopenharmony_ci 4536f08c3bdfSopenharmony_civoid cleanup_handler(int sig) 4537f08c3bdfSopenharmony_ci{ 4538f08c3bdfSopenharmony_ci havesigint = 1; /* in case there's a followup signal */ 4539f08c3bdfSopenharmony_ci alloc_mem(-1); 4540f08c3bdfSopenharmony_ci exit(0); 4541f08c3bdfSopenharmony_ci} 4542f08c3bdfSopenharmony_ci 4543f08c3bdfSopenharmony_civoid die_handler(int sig) 4544f08c3bdfSopenharmony_ci{ 4545f08c3bdfSopenharmony_ci doio_fprintf(stderr, "terminating on signal %d\n", sig); 4546f08c3bdfSopenharmony_ci alloc_mem(-1); 4547f08c3bdfSopenharmony_ci exit(1); 4548f08c3bdfSopenharmony_ci} 4549f08c3bdfSopenharmony_ci 4550f08c3bdfSopenharmony_ci#ifndef CRAY 4551f08c3bdfSopenharmony_civoid sigbus_handler(int sig) 4552f08c3bdfSopenharmony_ci{ 4553f08c3bdfSopenharmony_ci /* See sigbus_handler() in the 'ifdef sgi' case for details. Here, 4554f08c3bdfSopenharmony_ci we don't have the siginfo stuff so the guess is weaker but we'll 4555f08c3bdfSopenharmony_ci do it anyway. 4556f08c3bdfSopenharmony_ci */ 4557f08c3bdfSopenharmony_ci 4558f08c3bdfSopenharmony_ci if (active_mmap_rw && havesigint) 4559f08c3bdfSopenharmony_ci cleanup_handler(sig); 4560f08c3bdfSopenharmony_ci else 4561f08c3bdfSopenharmony_ci die_handler(sig); 4562f08c3bdfSopenharmony_ci} 4563f08c3bdfSopenharmony_ci#endif /* !CRAY */ 4564f08c3bdfSopenharmony_ci#endif /* sgi */ 4565f08c3bdfSopenharmony_ci 4566f08c3bdfSopenharmony_civoid noop_handler(int sig) 4567f08c3bdfSopenharmony_ci{ 4568f08c3bdfSopenharmony_ci return; 4569f08c3bdfSopenharmony_ci} 4570f08c3bdfSopenharmony_ci 4571f08c3bdfSopenharmony_ci/* 4572f08c3bdfSopenharmony_ci * SIGINT handler for the parent (original doio) process. It simply sends 4573f08c3bdfSopenharmony_ci * a SIGINT to all of the doio children. Since they're all in the same 4574f08c3bdfSopenharmony_ci * pgrp, this can be done with a single kill(). 4575f08c3bdfSopenharmony_ci */ 4576f08c3bdfSopenharmony_ci 4577f08c3bdfSopenharmony_civoid sigint_handler(int sig) 4578f08c3bdfSopenharmony_ci{ 4579f08c3bdfSopenharmony_ci int i; 4580f08c3bdfSopenharmony_ci 4581f08c3bdfSopenharmony_ci for (i = 0; i < Nchildren; i++) { 4582f08c3bdfSopenharmony_ci if (Children[i] != -1) { 4583f08c3bdfSopenharmony_ci kill(Children[i], SIGINT); 4584f08c3bdfSopenharmony_ci } 4585f08c3bdfSopenharmony_ci } 4586f08c3bdfSopenharmony_ci} 4587f08c3bdfSopenharmony_ci 4588f08c3bdfSopenharmony_ci/* 4589f08c3bdfSopenharmony_ci * Signal handler used to inform a process when async io completes. Referenced 4590f08c3bdfSopenharmony_ci * in do_read() and do_write(). Note that the signal handler is not 4591f08c3bdfSopenharmony_ci * re-registered. 4592f08c3bdfSopenharmony_ci */ 4593f08c3bdfSopenharmony_ci 4594f08c3bdfSopenharmony_civoid aio_handler(int sig) 4595f08c3bdfSopenharmony_ci{ 4596f08c3bdfSopenharmony_ci unsigned int i; 4597f08c3bdfSopenharmony_ci struct aio_info *aiop; 4598f08c3bdfSopenharmony_ci 4599f08c3bdfSopenharmony_ci for (i = 0; i < sizeof(Aio_Info) / sizeof(Aio_Info[0]); i++) { 4600f08c3bdfSopenharmony_ci aiop = &Aio_Info[i]; 4601f08c3bdfSopenharmony_ci 4602f08c3bdfSopenharmony_ci if (aiop->strategy == A_SIGNAL && aiop->sig == sig) { 4603f08c3bdfSopenharmony_ci aiop->signalled++; 4604f08c3bdfSopenharmony_ci 4605f08c3bdfSopenharmony_ci if (aio_done(aiop)) { 4606f08c3bdfSopenharmony_ci aiop->done++; 4607f08c3bdfSopenharmony_ci } 4608f08c3bdfSopenharmony_ci } 4609f08c3bdfSopenharmony_ci } 4610f08c3bdfSopenharmony_ci} 4611f08c3bdfSopenharmony_ci 4612f08c3bdfSopenharmony_ci/* 4613f08c3bdfSopenharmony_ci * dump info on all open aio slots 4614f08c3bdfSopenharmony_ci */ 4615f08c3bdfSopenharmony_civoid dump_aio(void) 4616f08c3bdfSopenharmony_ci{ 4617f08c3bdfSopenharmony_ci unsigned int i, count; 4618f08c3bdfSopenharmony_ci 4619f08c3bdfSopenharmony_ci count = 0; 4620f08c3bdfSopenharmony_ci for (i = 0; i < sizeof(Aio_Info) / sizeof(Aio_Info[0]); i++) { 4621f08c3bdfSopenharmony_ci if (Aio_Info[i].busy) { 4622f08c3bdfSopenharmony_ci count++; 4623f08c3bdfSopenharmony_ci fprintf(stderr, 4624f08c3bdfSopenharmony_ci "Aio_Info[%03d] id=%d fd=%d signal=%d signaled=%d\n", 4625f08c3bdfSopenharmony_ci i, Aio_Info[i].id, 4626f08c3bdfSopenharmony_ci Aio_Info[i].fd, 4627f08c3bdfSopenharmony_ci Aio_Info[i].sig, Aio_Info[i].signalled); 4628f08c3bdfSopenharmony_ci fprintf(stderr, "\tstrategy=%s\n", 4629f08c3bdfSopenharmony_ci format_strat(Aio_Info[i].strategy)); 4630f08c3bdfSopenharmony_ci } 4631f08c3bdfSopenharmony_ci } 4632f08c3bdfSopenharmony_ci fprintf(stderr, "%d active async i/os\n", count); 4633f08c3bdfSopenharmony_ci} 4634f08c3bdfSopenharmony_ci 4635f08c3bdfSopenharmony_ci#ifdef sgi 4636f08c3bdfSopenharmony_ci/* 4637f08c3bdfSopenharmony_ci * Signal handler called as a callback, not as a signal. 4638f08c3bdfSopenharmony_ci * 'val' is the value from sigev_value and is assumed to be the 4639f08c3bdfSopenharmony_ci * Aio_Info[] index. 4640f08c3bdfSopenharmony_ci */ 4641f08c3bdfSopenharmony_civoid cb_handler(sigval_t val) 4642f08c3bdfSopenharmony_ci{ 4643f08c3bdfSopenharmony_ci struct aio_info *aiop; 4644f08c3bdfSopenharmony_ci 4645f08c3bdfSopenharmony_ci/*printf("cb_handler requesting slot %d\n", val.sival_int);*/ 4646f08c3bdfSopenharmony_ci aiop = aio_slot(val.sival_int); 4647f08c3bdfSopenharmony_ci/*printf("cb_handler, aiop=%p\n", aiop);*/ 4648f08c3bdfSopenharmony_ci 4649f08c3bdfSopenharmony_ci/*printf("%d in cb_handler\n", getpid() );*/ 4650f08c3bdfSopenharmony_ci if (aiop->strategy == A_CALLBACK) { 4651f08c3bdfSopenharmony_ci aiop->signalled++; 4652f08c3bdfSopenharmony_ci 4653f08c3bdfSopenharmony_ci if (aio_done(aiop)) { 4654f08c3bdfSopenharmony_ci aiop->done++; 4655f08c3bdfSopenharmony_ci } 4656f08c3bdfSopenharmony_ci } 4657f08c3bdfSopenharmony_ci} 4658f08c3bdfSopenharmony_ci#endif 4659f08c3bdfSopenharmony_ci 4660f08c3bdfSopenharmony_cistruct aio_info *aio_slot(int aio_id) 4661f08c3bdfSopenharmony_ci{ 4662f08c3bdfSopenharmony_ci unsigned int i; 4663f08c3bdfSopenharmony_ci static int id = 1; 4664f08c3bdfSopenharmony_ci struct aio_info *aiop; 4665f08c3bdfSopenharmony_ci 4666f08c3bdfSopenharmony_ci aiop = NULL; 4667f08c3bdfSopenharmony_ci 4668f08c3bdfSopenharmony_ci for (i = 0; i < sizeof(Aio_Info) / sizeof(Aio_Info[0]); i++) { 4669f08c3bdfSopenharmony_ci if (aio_id == -1) { 4670f08c3bdfSopenharmony_ci if (!Aio_Info[i].busy) { 4671f08c3bdfSopenharmony_ci aiop = &Aio_Info[i]; 4672f08c3bdfSopenharmony_ci aiop->busy = 1; 4673f08c3bdfSopenharmony_ci aiop->id = id++; 4674f08c3bdfSopenharmony_ci break; 4675f08c3bdfSopenharmony_ci } 4676f08c3bdfSopenharmony_ci } else { 4677f08c3bdfSopenharmony_ci if (Aio_Info[i].busy && Aio_Info[i].id == aio_id) { 4678f08c3bdfSopenharmony_ci aiop = &Aio_Info[i]; 4679f08c3bdfSopenharmony_ci break; 4680f08c3bdfSopenharmony_ci } 4681f08c3bdfSopenharmony_ci } 4682f08c3bdfSopenharmony_ci } 4683f08c3bdfSopenharmony_ci 4684f08c3bdfSopenharmony_ci if (aiop == NULL) { 4685f08c3bdfSopenharmony_ci doio_fprintf(stderr, "aio_slot(%d) not found. Request %d\n", 4686f08c3bdfSopenharmony_ci aio_id, Reqno); 4687f08c3bdfSopenharmony_ci dump_aio(); 4688f08c3bdfSopenharmony_ci alloc_mem(-1); 4689f08c3bdfSopenharmony_ci exit(E_INTERNAL); 4690f08c3bdfSopenharmony_ci } 4691f08c3bdfSopenharmony_ci 4692f08c3bdfSopenharmony_ci return aiop; 4693f08c3bdfSopenharmony_ci} 4694f08c3bdfSopenharmony_ci 4695f08c3bdfSopenharmony_ciint aio_register(int fd, int strategy, int sig) 4696f08c3bdfSopenharmony_ci{ 4697f08c3bdfSopenharmony_ci struct aio_info *aiop; 4698f08c3bdfSopenharmony_ci struct sigaction sa; 4699f08c3bdfSopenharmony_ci 4700f08c3bdfSopenharmony_ci aiop = aio_slot(-1); 4701f08c3bdfSopenharmony_ci 4702f08c3bdfSopenharmony_ci aiop->fd = fd; 4703f08c3bdfSopenharmony_ci aiop->strategy = strategy; 4704f08c3bdfSopenharmony_ci aiop->done = 0; 4705f08c3bdfSopenharmony_ci#ifdef CRAY 4706f08c3bdfSopenharmony_ci memset((char *)&aiop->iosw, 0x00, sizeof(aiop->iosw)); 4707f08c3bdfSopenharmony_ci#endif 4708f08c3bdfSopenharmony_ci 4709f08c3bdfSopenharmony_ci if (strategy == A_SIGNAL) { 4710f08c3bdfSopenharmony_ci aiop->sig = sig; 4711f08c3bdfSopenharmony_ci aiop->signalled = 0; 4712f08c3bdfSopenharmony_ci 4713f08c3bdfSopenharmony_ci sa.sa_handler = aio_handler; 4714f08c3bdfSopenharmony_ci sa.sa_flags = 0; 4715f08c3bdfSopenharmony_ci sigemptyset(&sa.sa_mask); 4716f08c3bdfSopenharmony_ci 4717f08c3bdfSopenharmony_ci sigaction(sig, &sa, &aiop->osa); 4718f08c3bdfSopenharmony_ci } else { 4719f08c3bdfSopenharmony_ci aiop->sig = -1; 4720f08c3bdfSopenharmony_ci aiop->signalled = 0; 4721f08c3bdfSopenharmony_ci } 4722f08c3bdfSopenharmony_ci 4723f08c3bdfSopenharmony_ci return aiop->id; 4724f08c3bdfSopenharmony_ci} 4725f08c3bdfSopenharmony_ci 4726f08c3bdfSopenharmony_ciint aio_unregister(int aio_id) 4727f08c3bdfSopenharmony_ci{ 4728f08c3bdfSopenharmony_ci struct aio_info *aiop; 4729f08c3bdfSopenharmony_ci 4730f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 4731f08c3bdfSopenharmony_ci 4732f08c3bdfSopenharmony_ci if (aiop->strategy == A_SIGNAL) { 4733f08c3bdfSopenharmony_ci sigaction(aiop->sig, &aiop->osa, NULL); 4734f08c3bdfSopenharmony_ci } 4735f08c3bdfSopenharmony_ci 4736f08c3bdfSopenharmony_ci aiop->busy = 0; 4737f08c3bdfSopenharmony_ci return 0; 4738f08c3bdfSopenharmony_ci} 4739f08c3bdfSopenharmony_ci 4740f08c3bdfSopenharmony_ci#ifndef __linux__ 4741f08c3bdfSopenharmony_ciint aio_wait(int aio_id) 4742f08c3bdfSopenharmony_ci{ 4743f08c3bdfSopenharmony_ci#ifdef RECALL_SIZEOF 4744f08c3bdfSopenharmony_ci long mask[RECALL_SIZEOF]; 4745f08c3bdfSopenharmony_ci#endif 4746f08c3bdfSopenharmony_ci sigset_t signalset; 4747f08c3bdfSopenharmony_ci struct aio_info *aiop; 4748f08c3bdfSopenharmony_ci#ifdef CRAY 4749f08c3bdfSopenharmony_ci struct iosw *ioswlist[1]; 4750f08c3bdfSopenharmony_ci#endif 4751f08c3bdfSopenharmony_ci#ifdef sgi 4752f08c3bdfSopenharmony_ci const aiocb_t *aioary[1]; 4753f08c3bdfSopenharmony_ci#endif 4754f08c3bdfSopenharmony_ci int r, cnt; 4755f08c3bdfSopenharmony_ci 4756f08c3bdfSopenharmony_ci aiop = aio_slot(aio_id); 4757f08c3bdfSopenharmony_ci/*printf("%d aiop B =%p\n", getpid(), aiop);*/ 4758f08c3bdfSopenharmony_ci 4759f08c3bdfSopenharmony_ci switch (aiop->strategy) { 4760f08c3bdfSopenharmony_ci case A_POLL: 4761f08c3bdfSopenharmony_ci while (!aio_done(aiop)) ; 4762f08c3bdfSopenharmony_ci break; 4763f08c3bdfSopenharmony_ci 4764f08c3bdfSopenharmony_ci case A_SIGNAL: 4765f08c3bdfSopenharmony_ci sigemptyset(&signalset); 4766f08c3bdfSopenharmony_ci sighold(aiop->sig); 4767f08c3bdfSopenharmony_ci 4768f08c3bdfSopenharmony_ci while (!aiop->signalled || !aiop->done) { 4769f08c3bdfSopenharmony_ci sigsuspend(&signalset); 4770f08c3bdfSopenharmony_ci sighold(aiop->sig); 4771f08c3bdfSopenharmony_ci } 4772f08c3bdfSopenharmony_ci break; 4773f08c3bdfSopenharmony_ci 4774f08c3bdfSopenharmony_ci#ifdef CRAY 4775f08c3bdfSopenharmony_ci case A_RECALL: 4776f08c3bdfSopenharmony_ci ioswlist[0] = &aiop->iosw; 4777f08c3bdfSopenharmony_ci if (recall(aiop->fd, 1, ioswlist) < 0) { 4778f08c3bdfSopenharmony_ci doio_fprintf(stderr, "recall() failed: %s (%d)\n", 4779f08c3bdfSopenharmony_ci SYSERR, errno); 4780f08c3bdfSopenharmony_ci exit(E_SETUP); 4781f08c3bdfSopenharmony_ci } 4782f08c3bdfSopenharmony_ci break; 4783f08c3bdfSopenharmony_ci 4784f08c3bdfSopenharmony_ci#ifdef RECALL_SIZEOF 4785f08c3bdfSopenharmony_ci 4786f08c3bdfSopenharmony_ci case A_RECALLA: 4787f08c3bdfSopenharmony_ci RECALL_INIT(mask); 4788f08c3bdfSopenharmony_ci RECALL_SET(mask, aiop->fd); 4789f08c3bdfSopenharmony_ci if (recalla(mask) < 0) { 4790f08c3bdfSopenharmony_ci doio_fprintf(stderr, "recalla() failed: %s (%d)\n", 4791f08c3bdfSopenharmony_ci SYSERR, errno); 4792f08c3bdfSopenharmony_ci exit(E_SETUP); 4793f08c3bdfSopenharmony_ci } 4794f08c3bdfSopenharmony_ci 4795f08c3bdfSopenharmony_ci RECALL_CLR(mask, aiop->fd); 4796f08c3bdfSopenharmony_ci break; 4797f08c3bdfSopenharmony_ci#endif 4798f08c3bdfSopenharmony_ci 4799f08c3bdfSopenharmony_ci case A_RECALLS: 4800f08c3bdfSopenharmony_ci ioswlist[0] = &aiop->iosw; 4801f08c3bdfSopenharmony_ci if (recalls(1, ioswlist) < 0) { 4802f08c3bdfSopenharmony_ci doio_fprintf(stderr, "recalls failed: %s (%d)\n", 4803f08c3bdfSopenharmony_ci SYSERR, errno); 4804f08c3bdfSopenharmony_ci exit(E_SETUP); 4805f08c3bdfSopenharmony_ci } 4806f08c3bdfSopenharmony_ci break; 4807f08c3bdfSopenharmony_ci#endif /* CRAY */ 4808f08c3bdfSopenharmony_ci 4809f08c3bdfSopenharmony_ci#ifdef sgi 4810f08c3bdfSopenharmony_ci case A_CALLBACK: 4811f08c3bdfSopenharmony_ci aioary[0] = &aiop->aiocb; 4812f08c3bdfSopenharmony_ci cnt = 0; 4813f08c3bdfSopenharmony_ci do { 4814f08c3bdfSopenharmony_ci r = aio_suspend(aioary, 1, NULL); 4815f08c3bdfSopenharmony_ci if (r == -1) { 4816f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4817f08c3bdfSopenharmony_ci "aio_suspend failed: %s (%d)\n", 4818f08c3bdfSopenharmony_ci SYSERR, errno); 4819f08c3bdfSopenharmony_ci exit(E_SETUP); 4820f08c3bdfSopenharmony_ci } 4821f08c3bdfSopenharmony_ci cnt++; 4822f08c3bdfSopenharmony_ci } while (aiop->done == 0); 4823f08c3bdfSopenharmony_ci 4824f08c3bdfSopenharmony_ci#if 0 4825f08c3bdfSopenharmony_ci /* 4826f08c3bdfSopenharmony_ci * after having this set for a while, I've decided that 4827f08c3bdfSopenharmony_ci * it's too noisy 4828f08c3bdfSopenharmony_ci */ 4829f08c3bdfSopenharmony_ci if (cnt > 1) 4830f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4831f08c3bdfSopenharmony_ci "aio_wait: callback wait took %d tries\n", 4832f08c3bdfSopenharmony_ci cnt); 4833f08c3bdfSopenharmony_ci#endif 4834f08c3bdfSopenharmony_ci 4835f08c3bdfSopenharmony_ci /* 4836f08c3bdfSopenharmony_ci * Note: cb_handler already calls aio_done 4837f08c3bdfSopenharmony_ci */ 4838f08c3bdfSopenharmony_ci break; 4839f08c3bdfSopenharmony_ci 4840f08c3bdfSopenharmony_ci case A_SUSPEND: 4841f08c3bdfSopenharmony_ci aioary[0] = &aiop->aiocb; 4842f08c3bdfSopenharmony_ci r = aio_suspend(aioary, 1, NULL); 4843f08c3bdfSopenharmony_ci if (r == -1) { 4844f08c3bdfSopenharmony_ci doio_fprintf(stderr, "aio_suspend failed: %s (%d)\n", 4845f08c3bdfSopenharmony_ci SYSERR, errno); 4846f08c3bdfSopenharmony_ci exit(E_SETUP); 4847f08c3bdfSopenharmony_ci } 4848f08c3bdfSopenharmony_ci 4849f08c3bdfSopenharmony_ci aio_done(aiop); 4850f08c3bdfSopenharmony_ci break; 4851f08c3bdfSopenharmony_ci#endif 4852f08c3bdfSopenharmony_ci } 4853f08c3bdfSopenharmony_ci 4854f08c3bdfSopenharmony_ci/*printf("aio_wait: errno %d return %d\n", aiop->aio_errno, aiop->aio_ret);*/ 4855f08c3bdfSopenharmony_ci 4856f08c3bdfSopenharmony_ci return 0; 4857f08c3bdfSopenharmony_ci} 4858f08c3bdfSopenharmony_ci#endif /* !linux */ 4859f08c3bdfSopenharmony_ci 4860f08c3bdfSopenharmony_ci/* 4861f08c3bdfSopenharmony_ci * Format specified time into HH:MM:SS format. t is the time to format 4862f08c3bdfSopenharmony_ci * in seconds (as returned from time(2)). 4863f08c3bdfSopenharmony_ci */ 4864f08c3bdfSopenharmony_ci 4865f08c3bdfSopenharmony_cichar *hms(time_t t) 4866f08c3bdfSopenharmony_ci{ 4867f08c3bdfSopenharmony_ci static char ascii_time[9]; 4868f08c3bdfSopenharmony_ci struct tm *ltime; 4869f08c3bdfSopenharmony_ci 4870f08c3bdfSopenharmony_ci ltime = localtime(&t); 4871f08c3bdfSopenharmony_ci strftime(ascii_time, sizeof(ascii_time), "%H:%M:%S", ltime); 4872f08c3bdfSopenharmony_ci 4873f08c3bdfSopenharmony_ci return ascii_time; 4874f08c3bdfSopenharmony_ci} 4875f08c3bdfSopenharmony_ci 4876f08c3bdfSopenharmony_ci/* 4877f08c3bdfSopenharmony_ci * Simple routine to check if an async io request has completed. 4878f08c3bdfSopenharmony_ci */ 4879f08c3bdfSopenharmony_ci 4880f08c3bdfSopenharmony_ciint aio_done(struct aio_info *ainfo) 4881f08c3bdfSopenharmony_ci{ 4882f08c3bdfSopenharmony_ci#ifdef CRAY 4883f08c3bdfSopenharmony_ci return ainfo->iosw.sw_flag; 4884f08c3bdfSopenharmony_ci#endif 4885f08c3bdfSopenharmony_ci 4886f08c3bdfSopenharmony_ci#ifdef sgi 4887f08c3bdfSopenharmony_ci if ((ainfo->aio_errno = aio_error(&ainfo->aiocb)) == -1) { 4888f08c3bdfSopenharmony_ci doio_fprintf(stderr, "aio_done: aio_error failed: %s (%d)\n", 4889f08c3bdfSopenharmony_ci SYSERR, errno); 4890f08c3bdfSopenharmony_ci exit(E_SETUP); 4891f08c3bdfSopenharmony_ci } 4892f08c3bdfSopenharmony_ci /*printf("%d aio_done aio_errno=%d\n", getpid(), ainfo->aio_errno); */ 4893f08c3bdfSopenharmony_ci if (ainfo->aio_errno != EINPROGRESS) { 4894f08c3bdfSopenharmony_ci if ((ainfo->aio_ret = aio_return(&ainfo->aiocb)) == -1) { 4895f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4896f08c3bdfSopenharmony_ci "aio_done: aio_return failed: %s (%d)\n", 4897f08c3bdfSopenharmony_ci SYSERR, errno); 4898f08c3bdfSopenharmony_ci exit(E_SETUP); 4899f08c3bdfSopenharmony_ci } 4900f08c3bdfSopenharmony_ci } 4901f08c3bdfSopenharmony_ci 4902f08c3bdfSopenharmony_ci return (ainfo->aio_errno != EINPROGRESS); 4903f08c3bdfSopenharmony_ci#else 4904f08c3bdfSopenharmony_ci return -1; /* invalid */ 4905f08c3bdfSopenharmony_ci#endif 4906f08c3bdfSopenharmony_ci} 4907f08c3bdfSopenharmony_ci 4908f08c3bdfSopenharmony_ci/* 4909f08c3bdfSopenharmony_ci * Routine to handle upanic() - it first attempts to set the panic flag. If 4910f08c3bdfSopenharmony_ci * the flag cannot be set, an error message is issued. A call to upanic 4911f08c3bdfSopenharmony_ci * with PA_PANIC is then done unconditionally, in case the panic flag was set 4912f08c3bdfSopenharmony_ci * from outside the program (as with the panic(8) program). 4913f08c3bdfSopenharmony_ci * 4914f08c3bdfSopenharmony_ci * Note - we only execute the upanic code if -U was used, and the passed in 4915f08c3bdfSopenharmony_ci * mask is set in the Upanic_Conditions bitmask. 4916f08c3bdfSopenharmony_ci */ 4917f08c3bdfSopenharmony_ci 4918f08c3bdfSopenharmony_civoid doio_upanic(int mask) 4919f08c3bdfSopenharmony_ci{ 4920f08c3bdfSopenharmony_ci if (U_opt == 0 || (mask & Upanic_Conditions) == 0) { 4921f08c3bdfSopenharmony_ci return; 4922f08c3bdfSopenharmony_ci } 4923f08c3bdfSopenharmony_ci#ifdef CRAY 4924f08c3bdfSopenharmony_ci if (upanic(PA_SET) < 0) { 4925f08c3bdfSopenharmony_ci doio_fprintf(stderr, 4926f08c3bdfSopenharmony_ci "WARNING - Could not set the panic flag - upanic(PA_SET) failed: %s (%d)\n", 4927f08c3bdfSopenharmony_ci SYSERR, errno); 4928f08c3bdfSopenharmony_ci } 4929f08c3bdfSopenharmony_ci 4930f08c3bdfSopenharmony_ci upanic(PA_PANIC); 4931f08c3bdfSopenharmony_ci#endif 4932f08c3bdfSopenharmony_ci#ifdef sgi 4933f08c3bdfSopenharmony_ci syssgi(1005); /* syssgi test panic - DEBUG kernels only */ 4934f08c3bdfSopenharmony_ci#endif 4935f08c3bdfSopenharmony_ci doio_fprintf(stderr, "WARNING - upanic() failed\n"); 4936f08c3bdfSopenharmony_ci} 4937f08c3bdfSopenharmony_ci 4938f08c3bdfSopenharmony_ci/* 4939f08c3bdfSopenharmony_ci * Parse cmdline options/arguments and set appropriate global variables. 4940f08c3bdfSopenharmony_ci * If the cmdline is valid, return 0 to caller. Otherwise exit with a status 4941f08c3bdfSopenharmony_ci * of 1. 4942f08c3bdfSopenharmony_ci */ 4943f08c3bdfSopenharmony_ci 4944f08c3bdfSopenharmony_ciint parse_cmdline(int argc, char **argv, char *opts) 4945f08c3bdfSopenharmony_ci{ 4946f08c3bdfSopenharmony_ci int c; 4947f08c3bdfSopenharmony_ci char cc, *cp = NULL, *tok = NULL; 4948f08c3bdfSopenharmony_ci extern int opterr; 4949f08c3bdfSopenharmony_ci extern int optind; 4950f08c3bdfSopenharmony_ci extern char *optarg; 4951f08c3bdfSopenharmony_ci struct smap *s; 4952f08c3bdfSopenharmony_ci char *memargs[NMEMALLOC]; 4953f08c3bdfSopenharmony_ci int nmemargs, ma; 4954f08c3bdfSopenharmony_ci 4955f08c3bdfSopenharmony_ci if (*argv[0] == '-') { 4956f08c3bdfSopenharmony_ci argv[0]++; 4957f08c3bdfSopenharmony_ci Execd = 1; 4958f08c3bdfSopenharmony_ci } 4959f08c3bdfSopenharmony_ci 4960f08c3bdfSopenharmony_ci if ((Prog = strrchr(argv[0], '/')) == NULL) { 4961f08c3bdfSopenharmony_ci Prog = argv[0]; 4962f08c3bdfSopenharmony_ci } else { 4963f08c3bdfSopenharmony_ci Prog++; 4964f08c3bdfSopenharmony_ci } 4965f08c3bdfSopenharmony_ci 4966f08c3bdfSopenharmony_ci opterr = 0; 4967f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, opts)) != EOF) { 4968f08c3bdfSopenharmony_ci switch ((char)c) { 4969f08c3bdfSopenharmony_ci case 'a': 4970f08c3bdfSopenharmony_ci a_opt++; 4971f08c3bdfSopenharmony_ci break; 4972f08c3bdfSopenharmony_ci 4973f08c3bdfSopenharmony_ci case 'C': 4974f08c3bdfSopenharmony_ci C_opt++; 4975f08c3bdfSopenharmony_ci for (s = checkmap; s->string != NULL; s++) 4976f08c3bdfSopenharmony_ci if (!strcmp(s->string, optarg)) 4977f08c3bdfSopenharmony_ci break; 4978f08c3bdfSopenharmony_ci if (s->string == NULL && tok != NULL) { 4979f08c3bdfSopenharmony_ci fprintf(stderr, 4980f08c3bdfSopenharmony_ci "%s%s: Illegal -C arg (%s). Must be one of: ", 4981f08c3bdfSopenharmony_ci Prog, TagName, tok); 4982f08c3bdfSopenharmony_ci 4983f08c3bdfSopenharmony_ci for (s = checkmap; s->string != NULL; s++) 4984f08c3bdfSopenharmony_ci fprintf(stderr, "%s ", s->string); 4985f08c3bdfSopenharmony_ci fprintf(stderr, "\n"); 4986f08c3bdfSopenharmony_ci exit(1); 4987f08c3bdfSopenharmony_ci } 4988f08c3bdfSopenharmony_ci 4989f08c3bdfSopenharmony_ci switch (s->value) { 4990f08c3bdfSopenharmony_ci case C_DEFAULT: 4991f08c3bdfSopenharmony_ci Data_Fill = doio_pat_fill; 4992f08c3bdfSopenharmony_ci Data_Check = doio_pat_check; 4993f08c3bdfSopenharmony_ci break; 4994f08c3bdfSopenharmony_ci default: 4995f08c3bdfSopenharmony_ci fprintf(stderr, 4996f08c3bdfSopenharmony_ci "%s%s: Unrecognised -C arg '%s' %d", 4997f08c3bdfSopenharmony_ci Prog, TagName, s->string, s->value); 4998f08c3bdfSopenharmony_ci exit(1); 4999f08c3bdfSopenharmony_ci } 5000f08c3bdfSopenharmony_ci break; 5001f08c3bdfSopenharmony_ci 5002f08c3bdfSopenharmony_ci case 'd': /* delay between i/o ops */ 5003f08c3bdfSopenharmony_ci parse_delay(optarg); 5004f08c3bdfSopenharmony_ci break; 5005f08c3bdfSopenharmony_ci 5006f08c3bdfSopenharmony_ci case 'e': 5007f08c3bdfSopenharmony_ci if (Npes > 1 && Nprocs > 1) { 5008f08c3bdfSopenharmony_ci fprintf(stderr, 5009f08c3bdfSopenharmony_ci "%s%s: Warning - Program is a multi-pe application - exec option is ignored.\n", 5010f08c3bdfSopenharmony_ci Prog, TagName); 5011f08c3bdfSopenharmony_ci } 5012f08c3bdfSopenharmony_ci e_opt++; 5013f08c3bdfSopenharmony_ci break; 5014f08c3bdfSopenharmony_ci 5015f08c3bdfSopenharmony_ci case 'h': 5016f08c3bdfSopenharmony_ci help(stdout); 5017f08c3bdfSopenharmony_ci exit(0); 5018f08c3bdfSopenharmony_ci break; 5019f08c3bdfSopenharmony_ci 5020f08c3bdfSopenharmony_ci case 'k': 5021f08c3bdfSopenharmony_ci k_opt++; 5022f08c3bdfSopenharmony_ci break; 5023f08c3bdfSopenharmony_ci 5024f08c3bdfSopenharmony_ci case 'm': 5025f08c3bdfSopenharmony_ci Message_Interval = strtol(optarg, &cp, 10); 5026f08c3bdfSopenharmony_ci if (*cp != '\0' || Message_Interval < 0) { 5027f08c3bdfSopenharmony_ci fprintf(stderr, 5028f08c3bdfSopenharmony_ci "%s%s: Illegal -m arg (%s): Must be an integer >= 0\n", 5029f08c3bdfSopenharmony_ci Prog, TagName, optarg); 5030f08c3bdfSopenharmony_ci exit(1); 5031f08c3bdfSopenharmony_ci } 5032f08c3bdfSopenharmony_ci m_opt++; 5033f08c3bdfSopenharmony_ci break; 5034f08c3bdfSopenharmony_ci 5035f08c3bdfSopenharmony_ci case 'M': /* memory allocation types */ 5036f08c3bdfSopenharmony_ci#ifndef CRAY 5037f08c3bdfSopenharmony_ci nmemargs = string_to_tokens(optarg, memargs, 32, ","); 5038f08c3bdfSopenharmony_ci for (ma = 0; ma < nmemargs; ma++) { 5039f08c3bdfSopenharmony_ci parse_memalloc(memargs[ma]); 5040f08c3bdfSopenharmony_ci } 5041f08c3bdfSopenharmony_ci /*dump_memalloc(); */ 5042f08c3bdfSopenharmony_ci#else 5043f08c3bdfSopenharmony_ci fprintf(stderr, 5044f08c3bdfSopenharmony_ci "%s%s: Error: -M isn't supported on this platform\n", 5045f08c3bdfSopenharmony_ci Prog, TagName); 5046f08c3bdfSopenharmony_ci exit(1); 5047f08c3bdfSopenharmony_ci#endif 5048f08c3bdfSopenharmony_ci M_opt++; 5049f08c3bdfSopenharmony_ci break; 5050f08c3bdfSopenharmony_ci 5051f08c3bdfSopenharmony_ci case 'N': 5052f08c3bdfSopenharmony_ci sprintf(TagName, "(%.39s)", optarg); 5053f08c3bdfSopenharmony_ci break; 5054f08c3bdfSopenharmony_ci 5055f08c3bdfSopenharmony_ci case 'n': 5056f08c3bdfSopenharmony_ci Nprocs = strtol(optarg, &cp, 10); 5057f08c3bdfSopenharmony_ci if (*cp != '\0' || Nprocs < 1) { 5058f08c3bdfSopenharmony_ci fprintf(stderr, 5059f08c3bdfSopenharmony_ci "%s%s: Illegal -n arg (%s): Must be integer > 0\n", 5060f08c3bdfSopenharmony_ci Prog, TagName, optarg); 5061f08c3bdfSopenharmony_ci exit(E_USAGE); 5062f08c3bdfSopenharmony_ci } 5063f08c3bdfSopenharmony_ci 5064f08c3bdfSopenharmony_ci if (Npes > 1 && Nprocs > 1) { 5065f08c3bdfSopenharmony_ci fprintf(stderr, 5066f08c3bdfSopenharmony_ci "%s%s: Program has been built as a multi-pe app. -n1 is the only nprocs value allowed\n", 5067f08c3bdfSopenharmony_ci Prog, TagName); 5068f08c3bdfSopenharmony_ci exit(E_SETUP); 5069f08c3bdfSopenharmony_ci } 5070f08c3bdfSopenharmony_ci n_opt++; 5071f08c3bdfSopenharmony_ci break; 5072f08c3bdfSopenharmony_ci 5073f08c3bdfSopenharmony_ci case 'r': 5074f08c3bdfSopenharmony_ci Release_Interval = strtol(optarg, &cp, 10); 5075f08c3bdfSopenharmony_ci if (*cp != '\0' || Release_Interval < 0) { 5076f08c3bdfSopenharmony_ci fprintf(stderr, 5077f08c3bdfSopenharmony_ci "%s%s: Illegal -r arg (%s): Must be integer >= 0\n", 5078f08c3bdfSopenharmony_ci Prog, TagName, optarg); 5079f08c3bdfSopenharmony_ci exit(E_USAGE); 5080f08c3bdfSopenharmony_ci } 5081f08c3bdfSopenharmony_ci 5082f08c3bdfSopenharmony_ci r_opt++; 5083f08c3bdfSopenharmony_ci break; 5084f08c3bdfSopenharmony_ci 5085f08c3bdfSopenharmony_ci case 'w': 5086f08c3bdfSopenharmony_ci Write_Log = optarg; 5087f08c3bdfSopenharmony_ci w_opt++; 5088f08c3bdfSopenharmony_ci break; 5089f08c3bdfSopenharmony_ci 5090f08c3bdfSopenharmony_ci case 'v': 5091f08c3bdfSopenharmony_ci v_opt++; 5092f08c3bdfSopenharmony_ci break; 5093f08c3bdfSopenharmony_ci 5094f08c3bdfSopenharmony_ci case 'V': 5095f08c3bdfSopenharmony_ci if (strcasecmp(optarg, "sync") == 0) { 5096f08c3bdfSopenharmony_ci Validation_Flags = O_SYNC; 5097f08c3bdfSopenharmony_ci } else if (strcasecmp(optarg, "buffered") == 0) { 5098f08c3bdfSopenharmony_ci Validation_Flags = 0; 5099f08c3bdfSopenharmony_ci#ifdef CRAY 5100f08c3bdfSopenharmony_ci } else if (strcasecmp(optarg, "parallel") == 0) { 5101f08c3bdfSopenharmony_ci Validation_Flags = O_PARALLEL; 5102f08c3bdfSopenharmony_ci } else if (strcasecmp(optarg, "ldraw") == 0) { 5103f08c3bdfSopenharmony_ci Validation_Flags = O_LDRAW; 5104f08c3bdfSopenharmony_ci } else if (strcasecmp(optarg, "raw") == 0) { 5105f08c3bdfSopenharmony_ci Validation_Flags = O_RAW; 5106f08c3bdfSopenharmony_ci#endif 5107f08c3bdfSopenharmony_ci#ifdef sgi 5108f08c3bdfSopenharmony_ci } else if (strcasecmp(optarg, "direct") == 0) { 5109f08c3bdfSopenharmony_ci Validation_Flags = O_DIRECT; 5110f08c3bdfSopenharmony_ci#endif 5111f08c3bdfSopenharmony_ci } else { 5112f08c3bdfSopenharmony_ci if (sscanf 5113f08c3bdfSopenharmony_ci (optarg, "%i%c", &Validation_Flags, 5114f08c3bdfSopenharmony_ci &cc) != 1) { 5115f08c3bdfSopenharmony_ci fprintf(stderr, 5116f08c3bdfSopenharmony_ci "%s: Invalid -V argument (%s) - must be a decimal, hex, or octal\n", 5117f08c3bdfSopenharmony_ci Prog, optarg); 5118f08c3bdfSopenharmony_ci fprintf(stderr, 5119f08c3bdfSopenharmony_ci " number, or one of the following strings: 'sync',\n"); 5120f08c3bdfSopenharmony_ci fprintf(stderr, 5121f08c3bdfSopenharmony_ci " 'buffered', 'parallel', 'ldraw', or 'raw'\n"); 5122f08c3bdfSopenharmony_ci exit(E_USAGE); 5123f08c3bdfSopenharmony_ci } 5124f08c3bdfSopenharmony_ci } 5125f08c3bdfSopenharmony_ci V_opt++; 5126f08c3bdfSopenharmony_ci break; 5127f08c3bdfSopenharmony_ci case 'U': 5128f08c3bdfSopenharmony_ci tok = strtok(optarg, ","); 5129f08c3bdfSopenharmony_ci while (tok != NULL) { 5130f08c3bdfSopenharmony_ci for (s = Upanic_Args; s->string != NULL; s++) 5131f08c3bdfSopenharmony_ci if (strcmp(s->string, tok) == 0) 5132f08c3bdfSopenharmony_ci break; 5133f08c3bdfSopenharmony_ci 5134f08c3bdfSopenharmony_ci if (s->string == NULL) { 5135f08c3bdfSopenharmony_ci fprintf(stderr, 5136f08c3bdfSopenharmony_ci "%s%s: Illegal -U arg (%s). Must be one of: ", 5137f08c3bdfSopenharmony_ci Prog, TagName, tok); 5138f08c3bdfSopenharmony_ci 5139f08c3bdfSopenharmony_ci for (s = Upanic_Args; s->string != NULL; 5140f08c3bdfSopenharmony_ci s++) 5141f08c3bdfSopenharmony_ci fprintf(stderr, "%s ", 5142f08c3bdfSopenharmony_ci s->string); 5143f08c3bdfSopenharmony_ci 5144f08c3bdfSopenharmony_ci fprintf(stderr, "\n"); 5145f08c3bdfSopenharmony_ci 5146f08c3bdfSopenharmony_ci exit(1); 5147f08c3bdfSopenharmony_ci } 5148f08c3bdfSopenharmony_ci 5149f08c3bdfSopenharmony_ci Upanic_Conditions |= s->value; 5150f08c3bdfSopenharmony_ci tok = strtok(NULL, ","); 5151f08c3bdfSopenharmony_ci } 5152f08c3bdfSopenharmony_ci 5153f08c3bdfSopenharmony_ci U_opt++; 5154f08c3bdfSopenharmony_ci break; 5155f08c3bdfSopenharmony_ci 5156f08c3bdfSopenharmony_ci case '?': 5157f08c3bdfSopenharmony_ci usage(stderr); 5158f08c3bdfSopenharmony_ci exit(E_USAGE); 5159f08c3bdfSopenharmony_ci break; 5160f08c3bdfSopenharmony_ci } 5161f08c3bdfSopenharmony_ci } 5162f08c3bdfSopenharmony_ci 5163f08c3bdfSopenharmony_ci /* 5164f08c3bdfSopenharmony_ci * Supply defaults 5165f08c3bdfSopenharmony_ci */ 5166f08c3bdfSopenharmony_ci 5167f08c3bdfSopenharmony_ci if (!C_opt) { 5168f08c3bdfSopenharmony_ci Data_Fill = doio_pat_fill; 5169f08c3bdfSopenharmony_ci Data_Check = doio_pat_check; 5170f08c3bdfSopenharmony_ci } 5171f08c3bdfSopenharmony_ci 5172f08c3bdfSopenharmony_ci if (!U_opt) 5173f08c3bdfSopenharmony_ci Upanic_Conditions = 0; 5174f08c3bdfSopenharmony_ci 5175f08c3bdfSopenharmony_ci if (!n_opt) 5176f08c3bdfSopenharmony_ci Nprocs = 1; 5177f08c3bdfSopenharmony_ci 5178f08c3bdfSopenharmony_ci if (!r_opt) 5179f08c3bdfSopenharmony_ci Release_Interval = DEF_RELEASE_INTERVAL; 5180f08c3bdfSopenharmony_ci 5181f08c3bdfSopenharmony_ci if (!M_opt) { 5182f08c3bdfSopenharmony_ci Memalloc[Nmemalloc].memtype = MEM_DATA; 5183f08c3bdfSopenharmony_ci Memalloc[Nmemalloc].flags = 0; 5184f08c3bdfSopenharmony_ci Memalloc[Nmemalloc].name = NULL; 5185f08c3bdfSopenharmony_ci Memalloc[Nmemalloc].space = NULL; 5186f08c3bdfSopenharmony_ci Nmemalloc++; 5187f08c3bdfSopenharmony_ci } 5188f08c3bdfSopenharmony_ci 5189f08c3bdfSopenharmony_ci /* 5190f08c3bdfSopenharmony_ci * Initialize input stream 5191f08c3bdfSopenharmony_ci */ 5192f08c3bdfSopenharmony_ci 5193f08c3bdfSopenharmony_ci if (argc == optind) { 5194f08c3bdfSopenharmony_ci Infile = NULL; 5195f08c3bdfSopenharmony_ci } else { 5196f08c3bdfSopenharmony_ci Infile = argv[optind++]; 5197f08c3bdfSopenharmony_ci } 5198f08c3bdfSopenharmony_ci 5199f08c3bdfSopenharmony_ci if (argc != optind) { 5200f08c3bdfSopenharmony_ci usage(stderr); 5201f08c3bdfSopenharmony_ci exit(E_USAGE); 5202f08c3bdfSopenharmony_ci } 5203f08c3bdfSopenharmony_ci 5204f08c3bdfSopenharmony_ci return 0; 5205f08c3bdfSopenharmony_ci} 5206f08c3bdfSopenharmony_ci 5207f08c3bdfSopenharmony_ci/* 5208f08c3bdfSopenharmony_ci * Parse memory allocation types 5209f08c3bdfSopenharmony_ci * 5210f08c3bdfSopenharmony_ci * Types are: 5211f08c3bdfSopenharmony_ci * Data 5212f08c3bdfSopenharmony_ci * T3E-shmem:blksize[:nblks] 5213f08c3bdfSopenharmony_ci * SysV-shmem:shmid:blksize:nblks 5214f08c3bdfSopenharmony_ci * if shmid is "private", use IPC_PRIVATE 5215f08c3bdfSopenharmony_ci * and nblks is not required 5216f08c3bdfSopenharmony_ci * 5217f08c3bdfSopenharmony_ci * mmap:flags:filename:blksize[:nblks] 5218f08c3bdfSopenharmony_ci * flags are one of: 5219f08c3bdfSopenharmony_ci * p - private (MAP_PRIVATE) 5220f08c3bdfSopenharmony_ci * a - private, MAP_AUTORESRV 5221f08c3bdfSopenharmony_ci * l - local (MAP_LOCAL) 5222f08c3bdfSopenharmony_ci * s - shared (nblks required) 5223f08c3bdfSopenharmony_ci * 5224f08c3bdfSopenharmony_ci * plus any of: 5225f08c3bdfSopenharmony_ci * f - fixed address (MAP_FIXED) 5226f08c3bdfSopenharmony_ci * A - use an address without MAP_FIXED 5227f08c3bdfSopenharmony_ci * a - autogrow (map once at startup) 5228f08c3bdfSopenharmony_ci * 5229f08c3bdfSopenharmony_ci * mmap:flags:devzero 5230f08c3bdfSopenharmony_ci * mmap /dev/zero (shared not allowd) 5231f08c3bdfSopenharmony_ci * maps the first 4096 bytes of /dev/zero 5232f08c3bdfSopenharmony_ci * 5233f08c3bdfSopenharmony_ci * - put a directory at the beginning of the shared 5234f08c3bdfSopenharmony_ci * regions saying what pid has what region. 5235f08c3bdfSopenharmony_ci * DIRMAGIC 5236f08c3bdfSopenharmony_ci * BLKSIZE 5237f08c3bdfSopenharmony_ci * NBLKS 5238f08c3bdfSopenharmony_ci * nblks worth of directories - 1 int pids 5239f08c3bdfSopenharmony_ci */ 5240f08c3bdfSopenharmony_ci#ifndef CRAY 5241f08c3bdfSopenharmony_civoid parse_memalloc(char *arg) 5242f08c3bdfSopenharmony_ci{ 5243f08c3bdfSopenharmony_ci char *allocargs[NMEMALLOC]; 5244f08c3bdfSopenharmony_ci int nalloc; 5245f08c3bdfSopenharmony_ci struct memalloc *M; 5246f08c3bdfSopenharmony_ci 5247f08c3bdfSopenharmony_ci if (Nmemalloc >= NMEMALLOC) { 5248f08c3bdfSopenharmony_ci doio_fprintf(stderr, "Error - too many memory types (%d).\n", 5249f08c3bdfSopenharmony_ci Nmemalloc); 5250f08c3bdfSopenharmony_ci return; 5251f08c3bdfSopenharmony_ci } 5252f08c3bdfSopenharmony_ci 5253f08c3bdfSopenharmony_ci M = &Memalloc[Nmemalloc]; 5254f08c3bdfSopenharmony_ci 5255f08c3bdfSopenharmony_ci nalloc = string_to_tokens(arg, allocargs, 32, ":"); 5256f08c3bdfSopenharmony_ci if (!strcmp(allocargs[0], "data")) { 5257f08c3bdfSopenharmony_ci M->memtype = MEM_DATA; 5258f08c3bdfSopenharmony_ci M->flags = 0; 5259f08c3bdfSopenharmony_ci M->name = NULL; 5260f08c3bdfSopenharmony_ci M->space = NULL; 5261f08c3bdfSopenharmony_ci Nmemalloc++; 5262f08c3bdfSopenharmony_ci if (nalloc >= 2) { 5263f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'p')) 5264f08c3bdfSopenharmony_ci M->flags |= MEMF_MPIN; 5265f08c3bdfSopenharmony_ci } 5266f08c3bdfSopenharmony_ci } else if (!strcmp(allocargs[0], "mmap")) { 5267f08c3bdfSopenharmony_ci /* mmap:flags:filename[:size] */ 5268f08c3bdfSopenharmony_ci M->memtype = MEM_MMAP; 5269f08c3bdfSopenharmony_ci M->flags = 0; 5270f08c3bdfSopenharmony_ci M->space = NULL; 5271f08c3bdfSopenharmony_ci if (nalloc >= 1) { 5272f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'p')) 5273f08c3bdfSopenharmony_ci M->flags |= MEMF_PRIVATE; 5274f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'a')) 5275f08c3bdfSopenharmony_ci M->flags |= MEMF_AUTORESRV; 5276f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'l')) 5277f08c3bdfSopenharmony_ci M->flags |= MEMF_LOCAL; 5278f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 's')) 5279f08c3bdfSopenharmony_ci M->flags |= MEMF_SHARED; 5280f08c3bdfSopenharmony_ci 5281f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'f')) 5282f08c3bdfSopenharmony_ci M->flags |= MEMF_FIXADDR; 5283f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'A')) 5284f08c3bdfSopenharmony_ci M->flags |= MEMF_ADDR; 5285f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'G')) 5286f08c3bdfSopenharmony_ci M->flags |= MEMF_AUTOGROW; 5287f08c3bdfSopenharmony_ci 5288f08c3bdfSopenharmony_ci if (strchr(allocargs[1], 'U')) 5289f08c3bdfSopenharmony_ci M->flags |= MEMF_FILE; 5290f08c3bdfSopenharmony_ci } else { 5291f08c3bdfSopenharmony_ci M->flags |= MEMF_PRIVATE; 5292f08c3bdfSopenharmony_ci } 5293f08c3bdfSopenharmony_ci 5294f08c3bdfSopenharmony_ci if (nalloc > 2) { 5295f08c3bdfSopenharmony_ci if (!strcmp(allocargs[2], "devzero")) { 5296f08c3bdfSopenharmony_ci M->name = "/dev/zero"; 5297f08c3bdfSopenharmony_ci if (M->flags & 5298f08c3bdfSopenharmony_ci ((MEMF_PRIVATE | MEMF_LOCAL) == 0)) 5299f08c3bdfSopenharmony_ci M->flags |= MEMF_PRIVATE; 5300f08c3bdfSopenharmony_ci } else { 5301f08c3bdfSopenharmony_ci M->name = allocargs[2]; 5302f08c3bdfSopenharmony_ci } 5303f08c3bdfSopenharmony_ci } else { 5304f08c3bdfSopenharmony_ci M->name = "/dev/zero"; 5305f08c3bdfSopenharmony_ci if (M->flags & ((MEMF_PRIVATE | MEMF_LOCAL) == 0)) 5306f08c3bdfSopenharmony_ci M->flags |= MEMF_PRIVATE; 5307f08c3bdfSopenharmony_ci } 5308f08c3bdfSopenharmony_ci Nmemalloc++; 5309f08c3bdfSopenharmony_ci 5310f08c3bdfSopenharmony_ci } else if (!strcmp(allocargs[0], "shmem")) { 5311f08c3bdfSopenharmony_ci /* shmem:shmid:size */ 5312f08c3bdfSopenharmony_ci M->memtype = MEM_SHMEM; 5313f08c3bdfSopenharmony_ci M->flags = 0; 5314f08c3bdfSopenharmony_ci M->space = NULL; 5315f08c3bdfSopenharmony_ci if (nalloc >= 2) { 5316f08c3bdfSopenharmony_ci M->name = allocargs[1]; 5317f08c3bdfSopenharmony_ci } else { 5318f08c3bdfSopenharmony_ci M->name = NULL; 5319f08c3bdfSopenharmony_ci } 5320f08c3bdfSopenharmony_ci if (nalloc >= 3) { 5321f08c3bdfSopenharmony_ci sscanf(allocargs[2], "%i", &M->nblks); 5322f08c3bdfSopenharmony_ci } else { 5323f08c3bdfSopenharmony_ci M->nblks = 0; 5324f08c3bdfSopenharmony_ci } 5325f08c3bdfSopenharmony_ci if (nalloc >= 4) { 5326f08c3bdfSopenharmony_ci if (strchr(allocargs[3], 'p')) 5327f08c3bdfSopenharmony_ci M->flags |= MEMF_MPIN; 5328f08c3bdfSopenharmony_ci } 5329f08c3bdfSopenharmony_ci 5330f08c3bdfSopenharmony_ci Nmemalloc++; 5331f08c3bdfSopenharmony_ci } else { 5332f08c3bdfSopenharmony_ci doio_fprintf(stderr, "Error - unknown memory type '%s'.\n", 5333f08c3bdfSopenharmony_ci allocargs[0]); 5334f08c3bdfSopenharmony_ci exit(1); 5335f08c3bdfSopenharmony_ci } 5336f08c3bdfSopenharmony_ci} 5337f08c3bdfSopenharmony_ci 5338f08c3bdfSopenharmony_civoid dump_memalloc(void) 5339f08c3bdfSopenharmony_ci{ 5340f08c3bdfSopenharmony_ci int ma; 5341f08c3bdfSopenharmony_ci char *mt; 5342f08c3bdfSopenharmony_ci 5343f08c3bdfSopenharmony_ci if (Nmemalloc == 0) { 5344f08c3bdfSopenharmony_ci printf("No memory allocation strategies devined\n"); 5345f08c3bdfSopenharmony_ci return; 5346f08c3bdfSopenharmony_ci } 5347f08c3bdfSopenharmony_ci 5348f08c3bdfSopenharmony_ci for (ma = 0; ma < Nmemalloc; ma++) { 5349f08c3bdfSopenharmony_ci switch (Memalloc[ma].memtype) { 5350f08c3bdfSopenharmony_ci case MEM_DATA: 5351f08c3bdfSopenharmony_ci mt = "data"; 5352f08c3bdfSopenharmony_ci break; 5353f08c3bdfSopenharmony_ci case MEM_SHMEM: 5354f08c3bdfSopenharmony_ci mt = "shmem"; 5355f08c3bdfSopenharmony_ci break; 5356f08c3bdfSopenharmony_ci case MEM_MMAP: 5357f08c3bdfSopenharmony_ci mt = "mmap"; 5358f08c3bdfSopenharmony_ci break; 5359f08c3bdfSopenharmony_ci default: 5360f08c3bdfSopenharmony_ci mt = "unknown"; 5361f08c3bdfSopenharmony_ci break; 5362f08c3bdfSopenharmony_ci } 5363f08c3bdfSopenharmony_ci printf("mstrat[%d] = %d %s\n", ma, Memalloc[ma].memtype, mt); 5364f08c3bdfSopenharmony_ci printf("\tflags=%#o name='%s' nblks=%d\n", 5365f08c3bdfSopenharmony_ci Memalloc[ma].flags, 5366f08c3bdfSopenharmony_ci Memalloc[ma].name, Memalloc[ma].nblks); 5367f08c3bdfSopenharmony_ci } 5368f08c3bdfSopenharmony_ci} 5369f08c3bdfSopenharmony_ci 5370f08c3bdfSopenharmony_ci#endif /* !CRAY */ 5371f08c3bdfSopenharmony_ci 5372f08c3bdfSopenharmony_ci/* 5373f08c3bdfSopenharmony_ci * -d <op>:<time> - doio inter-operation delay 5374f08c3bdfSopenharmony_ci * currently this permits ONE type of delay between operations. 5375f08c3bdfSopenharmony_ci */ 5376f08c3bdfSopenharmony_ci 5377f08c3bdfSopenharmony_civoid parse_delay(char *arg) 5378f08c3bdfSopenharmony_ci{ 5379f08c3bdfSopenharmony_ci char *delayargs[NMEMALLOC]; 5380f08c3bdfSopenharmony_ci int ndelay; 5381f08c3bdfSopenharmony_ci struct smap *s; 5382f08c3bdfSopenharmony_ci 5383f08c3bdfSopenharmony_ci ndelay = string_to_tokens(arg, delayargs, 32, ":"); 5384f08c3bdfSopenharmony_ci if (ndelay < 2) { 5385f08c3bdfSopenharmony_ci doio_fprintf(stderr, 5386f08c3bdfSopenharmony_ci "Illegal delay arg (%s). Must be operation:time\n", 5387f08c3bdfSopenharmony_ci arg); 5388f08c3bdfSopenharmony_ci exit(1); 5389f08c3bdfSopenharmony_ci } 5390f08c3bdfSopenharmony_ci for (s = delaymap; s->string != NULL; s++) 5391f08c3bdfSopenharmony_ci if (!strcmp(s->string, delayargs[0])) 5392f08c3bdfSopenharmony_ci break; 5393f08c3bdfSopenharmony_ci if (s->string == NULL) { 5394f08c3bdfSopenharmony_ci fprintf(stderr, 5395f08c3bdfSopenharmony_ci "Illegal Delay arg (%s). Must be one of: ", arg); 5396f08c3bdfSopenharmony_ci 5397f08c3bdfSopenharmony_ci for (s = delaymap; s->string != NULL; s++) 5398f08c3bdfSopenharmony_ci fprintf(stderr, "%s ", s->string); 5399f08c3bdfSopenharmony_ci fprintf(stderr, "\n"); 5400f08c3bdfSopenharmony_ci exit(1); 5401f08c3bdfSopenharmony_ci } 5402f08c3bdfSopenharmony_ci 5403f08c3bdfSopenharmony_ci delayop = s->value; 5404f08c3bdfSopenharmony_ci 5405f08c3bdfSopenharmony_ci sscanf(delayargs[1], "%i", &delaytime); 5406f08c3bdfSopenharmony_ci 5407f08c3bdfSopenharmony_ci if (ndelay > 2) { 5408f08c3bdfSopenharmony_ci fprintf(stderr, "Warning: extra delay arguments ignored.\n"); 5409f08c3bdfSopenharmony_ci } 5410f08c3bdfSopenharmony_ci} 5411f08c3bdfSopenharmony_ci 5412f08c3bdfSopenharmony_ci/* 5413f08c3bdfSopenharmony_ci * Usage clause - obvious 5414f08c3bdfSopenharmony_ci */ 5415f08c3bdfSopenharmony_ci 5416f08c3bdfSopenharmony_ciint usage(FILE * stream) 5417f08c3bdfSopenharmony_ci{ 5418f08c3bdfSopenharmony_ci /* 5419f08c3bdfSopenharmony_ci * Only do this if we are on vpe 0, to avoid seeing it from every 5420f08c3bdfSopenharmony_ci * process in the application. 5421f08c3bdfSopenharmony_ci */ 5422f08c3bdfSopenharmony_ci 5423f08c3bdfSopenharmony_ci if (Npes > 1 && Vpe != 0) { 5424f08c3bdfSopenharmony_ci return 0; 5425f08c3bdfSopenharmony_ci } 5426f08c3bdfSopenharmony_ci 5427f08c3bdfSopenharmony_ci fprintf(stream, 5428f08c3bdfSopenharmony_ci "usage%s: %s [-aekv] [-m message_interval] [-n nprocs] [-r release_interval] [-w write_log] [-V validation_ftype] [-U upanic_cond] [infile]\n", 5429f08c3bdfSopenharmony_ci TagName, Prog); 5430f08c3bdfSopenharmony_ci return 0; 5431f08c3bdfSopenharmony_ci} 5432f08c3bdfSopenharmony_ci 5433f08c3bdfSopenharmony_civoid help(FILE * stream) 5434f08c3bdfSopenharmony_ci{ 5435f08c3bdfSopenharmony_ci /* 5436f08c3bdfSopenharmony_ci * Only the app running on vpe 0 gets to issue help - this prevents 5437f08c3bdfSopenharmony_ci * everybody in the application from doing this. 5438f08c3bdfSopenharmony_ci */ 5439f08c3bdfSopenharmony_ci 5440f08c3bdfSopenharmony_ci if (Npes > 1 && Vpe != 0) { 5441f08c3bdfSopenharmony_ci return; 5442f08c3bdfSopenharmony_ci } 5443f08c3bdfSopenharmony_ci 5444f08c3bdfSopenharmony_ci usage(stream); 5445f08c3bdfSopenharmony_ci fprintf(stream, "\n"); 5446f08c3bdfSopenharmony_ci fprintf(stream, 5447f08c3bdfSopenharmony_ci "\t-a abort - kill all doio processes on data compare\n"); 5448f08c3bdfSopenharmony_ci fprintf(stream, 5449f08c3bdfSopenharmony_ci "\t errors. Normally only the erroring process exits\n"); 5450f08c3bdfSopenharmony_ci fprintf(stream, "\t-C data-pattern-type \n"); 5451f08c3bdfSopenharmony_ci fprintf(stream, 5452f08c3bdfSopenharmony_ci "\t Available data patterns are:\n"); 5453f08c3bdfSopenharmony_ci fprintf(stream, "\t default - repeating pattern\n"); 5454f08c3bdfSopenharmony_ci fprintf(stream, "\t-d Operation:Time Inter-operation delay.\n"); 5455f08c3bdfSopenharmony_ci fprintf(stream, "\t Operations are:\n"); 5456f08c3bdfSopenharmony_ci fprintf(stream, 5457f08c3bdfSopenharmony_ci "\t select:time (1 second=1000000)\n"); 5458f08c3bdfSopenharmony_ci fprintf(stream, "\t sleep:time (1 second=1)\n"); 5459f08c3bdfSopenharmony_ci#ifdef sgi 5460f08c3bdfSopenharmony_ci fprintf(stream, 5461f08c3bdfSopenharmony_ci "\t sginap:time (1 second=CLK_TCK=100)\n"); 5462f08c3bdfSopenharmony_ci#endif 5463f08c3bdfSopenharmony_ci fprintf(stream, "\t alarm:time (1 second=1)\n"); 5464f08c3bdfSopenharmony_ci fprintf(stream, 5465f08c3bdfSopenharmony_ci "\t-e Re-exec children before entering the main\n"); 5466f08c3bdfSopenharmony_ci fprintf(stream, 5467f08c3bdfSopenharmony_ci "\t loop. This is useful for spreading\n"); 5468f08c3bdfSopenharmony_ci fprintf(stream, 5469f08c3bdfSopenharmony_ci "\t procs around on multi-pe systems.\n"); 5470f08c3bdfSopenharmony_ci fprintf(stream, 5471f08c3bdfSopenharmony_ci "\t-k Lock file regions during writes using fcntl()\n"); 5472f08c3bdfSopenharmony_ci fprintf(stream, 5473f08c3bdfSopenharmony_ci "\t-v Verify writes - this is done by doing a buffered\n"); 5474f08c3bdfSopenharmony_ci fprintf(stream, 5475f08c3bdfSopenharmony_ci "\t read() of the data if file io was done, or\n"); 5476f08c3bdfSopenharmony_ci fprintf(stream, 5477f08c3bdfSopenharmony_ci "\t an ssread()of the data if sds io was done\n"); 5478f08c3bdfSopenharmony_ci#ifndef CRAY 5479f08c3bdfSopenharmony_ci fprintf(stream, 5480f08c3bdfSopenharmony_ci "\t-M Data buffer allocation method\n"); 5481f08c3bdfSopenharmony_ci fprintf(stream, "\t alloc-type[,type]\n"); 5482f08c3bdfSopenharmony_ci#ifdef sgi 5483f08c3bdfSopenharmony_ci fprintf(stream, "\t data:flags\n"); 5484f08c3bdfSopenharmony_ci fprintf(stream, "\t p - mpin buffer\n"); 5485f08c3bdfSopenharmony_ci fprintf(stream, "\t shmem:shmid:size:flags\n"); 5486f08c3bdfSopenharmony_ci fprintf(stream, "\t p - mpin buffer\n"); 5487f08c3bdfSopenharmony_ci#else 5488f08c3bdfSopenharmony_ci fprintf(stream, "\t data\n"); 5489f08c3bdfSopenharmony_ci fprintf(stream, "\t shmem:shmid:size\n"); 5490f08c3bdfSopenharmony_ci#endif /* sgi */ 5491f08c3bdfSopenharmony_ci fprintf(stream, "\t mmap:flags:filename\n"); 5492f08c3bdfSopenharmony_ci fprintf(stream, "\t p - private\n"); 5493f08c3bdfSopenharmony_ci#ifdef sgi 5494f08c3bdfSopenharmony_ci fprintf(stream, "\t s - shared\n"); 5495f08c3bdfSopenharmony_ci fprintf(stream, "\t l - local\n"); 5496f08c3bdfSopenharmony_ci fprintf(stream, "\t a - autoresrv\n"); 5497f08c3bdfSopenharmony_ci fprintf(stream, "\t G - autogrow\n"); 5498f08c3bdfSopenharmony_ci#else 5499f08c3bdfSopenharmony_ci fprintf(stream, 5500f08c3bdfSopenharmony_ci "\t s - shared (shared file must exist\n"), 5501f08c3bdfSopenharmony_ci fprintf(stream, 5502f08c3bdfSopenharmony_ci "\t and have needed length)\n"); 5503f08c3bdfSopenharmony_ci#endif 5504f08c3bdfSopenharmony_ci fprintf(stream, 5505f08c3bdfSopenharmony_ci "\t f - fixed address (not used)\n"); 5506f08c3bdfSopenharmony_ci fprintf(stream, 5507f08c3bdfSopenharmony_ci "\t a - specify address (not used)\n"); 5508f08c3bdfSopenharmony_ci fprintf(stream, 5509f08c3bdfSopenharmony_ci "\t U - Unlink file when done\n"); 5510f08c3bdfSopenharmony_ci fprintf(stream, 5511f08c3bdfSopenharmony_ci "\t The default flag is private\n"); 5512f08c3bdfSopenharmony_ci fprintf(stream, "\n"); 5513f08c3bdfSopenharmony_ci#endif /* !CRAY */ 5514f08c3bdfSopenharmony_ci fprintf(stream, 5515f08c3bdfSopenharmony_ci "\t-m message_interval Generate a message every 'message_interval'\n"); 5516f08c3bdfSopenharmony_ci fprintf(stream, 5517f08c3bdfSopenharmony_ci "\t requests. An interval of 0 suppresses\n"); 5518f08c3bdfSopenharmony_ci fprintf(stream, 5519f08c3bdfSopenharmony_ci "\t messages. The default is 0.\n"); 5520f08c3bdfSopenharmony_ci fprintf(stream, "\t-N tagname Tag name, for Monster.\n"); 5521f08c3bdfSopenharmony_ci fprintf(stream, "\t-n nprocs # of processes to start up\n"); 5522f08c3bdfSopenharmony_ci fprintf(stream, 5523f08c3bdfSopenharmony_ci "\t-r release_interval Release all memory and close\n"); 5524f08c3bdfSopenharmony_ci fprintf(stream, 5525f08c3bdfSopenharmony_ci "\t files every release_interval operations.\n"); 5526f08c3bdfSopenharmony_ci fprintf(stream, 5527f08c3bdfSopenharmony_ci "\t By default procs never release memory\n"); 5528f08c3bdfSopenharmony_ci fprintf(stream, 5529f08c3bdfSopenharmony_ci "\t or close fds unless they have to.\n"); 5530f08c3bdfSopenharmony_ci fprintf(stream, 5531f08c3bdfSopenharmony_ci "\t-V validation_ftype The type of file descriptor to use for doing data\n"); 5532f08c3bdfSopenharmony_ci fprintf(stream, 5533f08c3bdfSopenharmony_ci "\t validation. validation_ftype may be an octal,\n"); 5534f08c3bdfSopenharmony_ci fprintf(stream, 5535f08c3bdfSopenharmony_ci "\t hex, or decimal number representing the open()\n"); 5536f08c3bdfSopenharmony_ci fprintf(stream, 5537f08c3bdfSopenharmony_ci "\t flags, or may be one of the following strings:\n"); 5538f08c3bdfSopenharmony_ci fprintf(stream, 5539f08c3bdfSopenharmony_ci "\t 'buffered' - validate using bufferd read\n"); 5540f08c3bdfSopenharmony_ci fprintf(stream, 5541f08c3bdfSopenharmony_ci "\t 'sync' - validate using O_SYNC read\n"); 5542f08c3bdfSopenharmony_ci#ifdef sgi 5543f08c3bdfSopenharmony_ci fprintf(stream, 5544f08c3bdfSopenharmony_ci "\t 'direct - validate using O_DIRECT read'\n"); 5545f08c3bdfSopenharmony_ci#endif 5546f08c3bdfSopenharmony_ci#ifdef CRAY 5547f08c3bdfSopenharmony_ci fprintf(stream, 5548f08c3bdfSopenharmony_ci "\t 'ldraw' - validate using O_LDRAW read\n"); 5549f08c3bdfSopenharmony_ci fprintf(stream, 5550f08c3bdfSopenharmony_ci "\t 'parallel' - validate using O_PARALLEL read\n"); 5551f08c3bdfSopenharmony_ci fprintf(stream, 5552f08c3bdfSopenharmony_ci "\t 'raw' - validate using O_RAW read\n"); 5553f08c3bdfSopenharmony_ci#endif 5554f08c3bdfSopenharmony_ci fprintf(stream, "\t By default, 'parallel'\n"); 5555f08c3bdfSopenharmony_ci fprintf(stream, 5556f08c3bdfSopenharmony_ci "\t is used if the write was done with O_PARALLEL\n"); 5557f08c3bdfSopenharmony_ci fprintf(stream, 5558f08c3bdfSopenharmony_ci "\t or 'buffered' for all other writes.\n"); 5559f08c3bdfSopenharmony_ci fprintf(stream, 5560f08c3bdfSopenharmony_ci "\t-w write_log File to log file writes to. The doio_check\n"); 5561f08c3bdfSopenharmony_ci fprintf(stream, 5562f08c3bdfSopenharmony_ci "\t program can reconstruct datafiles using the\n"); 5563f08c3bdfSopenharmony_ci fprintf(stream, 5564f08c3bdfSopenharmony_ci "\t write_log, and detect if a file is corrupt\n"); 5565f08c3bdfSopenharmony_ci fprintf(stream, 5566f08c3bdfSopenharmony_ci "\t after all procs have exited.\n"); 5567f08c3bdfSopenharmony_ci fprintf(stream, 5568f08c3bdfSopenharmony_ci "\t-U upanic_cond Comma separated list of conditions that will\n"); 5569f08c3bdfSopenharmony_ci fprintf(stream, 5570f08c3bdfSopenharmony_ci "\t cause a call to upanic(PA_PANIC).\n"); 5571f08c3bdfSopenharmony_ci fprintf(stream, 5572f08c3bdfSopenharmony_ci "\t 'corruption' -> upanic on bad data comparisons\n"); 5573f08c3bdfSopenharmony_ci fprintf(stream, 5574f08c3bdfSopenharmony_ci "\t 'iosw' ---> upanic on unexpected async iosw\n"); 5575f08c3bdfSopenharmony_ci fprintf(stream, 5576f08c3bdfSopenharmony_ci "\t 'rval' ---> upanic on unexpected syscall rvals\n"); 5577f08c3bdfSopenharmony_ci fprintf(stream, 5578f08c3bdfSopenharmony_ci "\t 'all' ---> all of the above\n"); 5579f08c3bdfSopenharmony_ci fprintf(stream, "\n"); 5580f08c3bdfSopenharmony_ci fprintf(stream, 5581f08c3bdfSopenharmony_ci "\tinfile Input stream - default is stdin - must be a list\n"); 5582f08c3bdfSopenharmony_ci fprintf(stream, 5583f08c3bdfSopenharmony_ci "\t of io_req structures (see doio.h). Currently\n"); 5584f08c3bdfSopenharmony_ci fprintf(stream, 5585f08c3bdfSopenharmony_ci "\t only the iogen program generates the proper\n"); 5586f08c3bdfSopenharmony_ci fprintf(stream, "\t format\n"); 5587f08c3bdfSopenharmony_ci} 5588