darshan-posix.c 42.7 KB
Newer Older
1 2 3 4 5
/*
 *  (C) 2009 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

6
#include "darshan-runtime-config.h"
7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <search.h>
#include <assert.h>
21
#include <libgen.h>
22
#include <limits.h>
Philip Carns's avatar
Philip Carns committed
23
#include <aio.h>
24 25
#define __USE_GNU
#include <pthread.h>
26 27

#include "darshan.h"
28
#include "darshan-core.h"
29

30
#ifndef HAVE_OFF64_T
31 32
typedef int64_t off64_t;
#endif
33 34 35
#ifndef HAVE_AIOCB64
#define aiocb64 aiocb
#endif
36

37 38 39 40 41
#define DARSHAN_FORWARD_DECL(name,ret,args) \
  extern ret __real_ ## name args;

#define DARSHAN_DECL(__name) __wrap_ ## __name

42 43 44 45
#define MAP_OR_FAIL(func)

#define DARSHAN_MPI_CALL(func) func

46 47 48 49 50 51 52 53 54 55 56 57
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(close, int, (int fd));
DARSHAN_FORWARD_DECL(write, ssize_t, (int fd, const void *buf, size_t count));
DARSHAN_FORWARD_DECL(read, ssize_t, (int fd, void *buf, size_t count));
DARSHAN_FORWARD_DECL(lseek, off_t, (int fd, off_t offset, int whence));
DARSHAN_FORWARD_DECL(lseek64, off64_t, (int fd, off64_t offset, int whence));
DARSHAN_FORWARD_DECL(pread, ssize_t, (int fd, void *buf, size_t count, off_t offset));
DARSHAN_FORWARD_DECL(pread64, ssize_t, (int fd, void *buf, size_t count, off64_t offset));
DARSHAN_FORWARD_DECL(pwrite, ssize_t, (int fd, const void *buf, size_t count, off_t offset));
58
DARSHAN_FORWARD_DECL(pwrite64, ssize_t, (int fd, const void *buf, size_t count, off64_t offset));
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
DARSHAN_FORWARD_DECL(readv, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
DARSHAN_FORWARD_DECL(writev, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
DARSHAN_FORWARD_DECL(__fxstat, int, (int vers, int fd, struct stat *buf));
DARSHAN_FORWARD_DECL(__fxstat64, int, (int vers, int fd, struct stat64 *buf));
DARSHAN_FORWARD_DECL(__lxstat, int, (int vers, const char* path, struct stat *buf));
DARSHAN_FORWARD_DECL(__lxstat64, int, (int vers, const char* path, struct stat64 *buf));
DARSHAN_FORWARD_DECL(__xstat, int, (int vers, const char* path, struct stat *buf));
DARSHAN_FORWARD_DECL(__xstat64, int, (int vers, const char* path, struct stat64 *buf));
DARSHAN_FORWARD_DECL(mmap, void*, (void *addr, size_t length, int prot, int flags, int fd, off_t offset));
DARSHAN_FORWARD_DECL(mmap64, void*, (void *addr, size_t length, int prot, int flags, int fd, off64_t offset));
DARSHAN_FORWARD_DECL(fopen, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(fopen64, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(fclose, int, (FILE *fp));
DARSHAN_FORWARD_DECL(fread, size_t, (void *ptr, size_t size, size_t nmemb, FILE *stream));
DARSHAN_FORWARD_DECL(fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *stream));
DARSHAN_FORWARD_DECL(fseek, int, (FILE *stream, long offset, int whence));
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
Philip Carns's avatar
Philip Carns committed
77
DARSHAN_FORWARD_DECL(aio_read, int, (struct aiocb *aiocbp));
78
DARSHAN_FORWARD_DECL(aio_read64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
79
DARSHAN_FORWARD_DECL(aio_write, int, (struct aiocb *aiocbp));
80
DARSHAN_FORWARD_DECL(aio_write64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
81
DARSHAN_FORWARD_DECL(lio_listio, int, (int mode, struct aiocb *const aiocb_list[], int nitems, struct sigevent *sevp));
82
DARSHAN_FORWARD_DECL(lio_listio64, int, (int mode, struct aiocb64 *const aiocb_list[], int nitems, struct sigevent *sevp));
Philip Carns's avatar
Philip Carns committed
83
DARSHAN_FORWARD_DECL(aio_return, ssize_t, (struct aiocb *aiocbp));
84
DARSHAN_FORWARD_DECL(aio_return64, ssize_t, (struct aiocb64 *aiocbp));
85

86
pthread_mutex_t cp_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
87
static struct stat64 cp_stat_buf;
88

89 90 91 92
/* struct to track information about aio operations in flight */
struct darshan_aio_tracker
{
    double tm1;
93
    void *aiocbp;
94 95 96
    struct darshan_aio_tracker* next;
};

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
/* these are paths that we will not trace */
static char* exclusions[] = {
"/etc/",
"/dev/",
"/usr/",
"/bin/",
"/boot/",
"/lib/",
"/opt/",
"/sbin/",
"/sys/",
"/proc/",
NULL
};

112 113 114
static int posix_mod_registered = 0;
static struct darshan_module_funcs posix_mod_funcs = 
{
115

116 117
};
static int posix_runtime_mem_limit = 0;
118

119 120 121 122 123 124
#define DARSHAN_REGISTER_POSIX_MOD() do{ \
    if (!posix_mod_registered) { \
        darshan_core_register_module("POSIX", &posix_mod_funcs, &posix_runtime_mem_limit); \
        posix_mod_registered = 1; \
    } \
} while(0)
125

126 127
static double posix_wtime(void);
static void cp_access_counter(struct darshan_file_runtime* file, ssize_t size,     enum cp_counter_type type);
128 129
static void darshan_aio_tracker_add(int fd, void *aiocbp);
static struct darshan_aio_tracker* darshan_aio_tracker_del(int fd, void *aiocbp);
130

131
#if 0
Philip Carns's avatar
Philip Carns committed
132
#define CP_RECORD_WRITE(__ret, __fd, __count, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
133
    size_t stride; \
Philip Carns's avatar
Philip Carns committed
134
    int64_t this_offset; \
135 136
    int64_t file_alignment; \
    struct darshan_file_runtime* file; \
137
    double __elapsed = __tm2-__tm1; \
138 139 140
    if(__ret < 0) break; \
    file = darshan_file_by_fd(__fd); \
    if(!file) break; \
Philip Carns's avatar
Philip Carns committed
141 142 143 144
    if(__pwrite_flag) \
        this_offset = __pwrite_offset; \
    else \
        this_offset = file->offset; \
145
    file_alignment = CP_VALUE(file, CP_FILE_ALIGNMENT); \
Philip Carns's avatar
Philip Carns committed
146
    if(this_offset > file->last_byte_written) \
147
        CP_INC(file, CP_SEQ_WRITES, 1); \
Philip Carns's avatar
Philip Carns committed
148
    if(this_offset == (file->last_byte_written + 1)) \
149
        CP_INC(file, CP_CONSEC_WRITES, 1); \
Philip Carns's avatar
Philip Carns committed
150
    if(this_offset > 0 && this_offset > file->last_byte_written \
151
        && file->last_byte_written != 0) \
Philip Carns's avatar
Philip Carns committed
152
        stride = this_offset - file->last_byte_written - 1; \
153 154
    else \
        stride = 0; \
Philip Carns's avatar
Philip Carns committed
155 156 157
    file->last_byte_written = this_offset + __ret - 1; \
    file->offset = this_offset + __ret; \
    CP_MAX(file, CP_MAX_BYTE_WRITTEN, (this_offset + __ret -1)); \
158 159 160 161 162 163 164 165 166
    CP_INC(file, CP_BYTES_WRITTEN, __ret); \
    if(__stream_flag) \
        CP_INC(file, CP_POSIX_FWRITES, 1); \
    else \
        CP_INC(file, CP_POSIX_WRITES, 1); \
    CP_BUCKET_INC(file, CP_SIZE_WRITE_0_100, __ret); \
    cp_access_counter(file, stride, CP_COUNTER_STRIDE); \
    if(!__aligned) \
        CP_INC(file, CP_MEM_NOT_ALIGNED, 1); \
Philip Carns's avatar
Philip Carns committed
167
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
168 169 170 171 172
        CP_INC(file, CP_FILE_NOT_ALIGNED, 1); \
    cp_access_counter(file, __ret, CP_COUNTER_ACCESS); \
    if(file->last_io_type == CP_READ) \
        CP_INC(file, CP_RW_SWITCHES, 1); \
    file->last_io_type = CP_WRITE; \
173
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
174 175 176
    if(CP_F_VALUE(file, CP_F_WRITE_START_TIMESTAMP) == 0) \
        CP_F_SET(file, CP_F_WRITE_START_TIMESTAMP, __tm1); \
    CP_F_SET(file, CP_F_WRITE_END_TIMESTAMP, __tm2); \
177 178 179
    if(CP_F_VALUE(file, CP_F_MAX_WRITE_TIME) < __elapsed){ \
        CP_F_SET(file, CP_F_MAX_WRITE_TIME, __elapsed); \
        CP_SET(file, CP_MAX_WRITE_TIME_SIZE, __ret); } \
180 181
} while(0)

182
#define CP_RECORD_READ(__ret, __fd, __count, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
183
    size_t stride; \
184
    int64_t this_offset; \
185 186
    struct darshan_file_runtime* file; \
    int64_t file_alignment; \
187
    double __elapsed = __tm2-__tm1; \
188 189 190
    if(__ret < 0) break; \
    file = darshan_file_by_fd(__fd); \
    if(!file) break; \
191 192 193 194
    if(__pread_flag)\
        this_offset = __pread_offset; \
    else \
        this_offset = file->offset; \
195
    file_alignment = CP_VALUE(file, CP_FILE_ALIGNMENT); \
196
    if(this_offset > file->last_byte_read) \
197
        CP_INC(file, CP_SEQ_READS, 1); \
198
    if(this_offset == (file->last_byte_read + 1)) \
199
        CP_INC(file, CP_CONSEC_READS, 1); \
200
    if(this_offset > 0 && this_offset > file->last_byte_read \
201
        && file->last_byte_read != 0) \
202
        stride = this_offset - file->last_byte_read - 1; \
203 204
    else \
        stride = 0; \
205 206 207
    file->last_byte_read = this_offset + __ret - 1; \
    CP_MAX(file, CP_MAX_BYTE_READ, (this_offset + __ret -1)); \
    file->offset = this_offset + __ret; \
208 209 210 211 212 213 214 215 216
    CP_INC(file, CP_BYTES_READ, __ret); \
    if(__stream_flag)\
        CP_INC(file, CP_POSIX_FREADS, 1); \
    else\
        CP_INC(file, CP_POSIX_READS, 1); \
    CP_BUCKET_INC(file, CP_SIZE_READ_0_100, __ret); \
    cp_access_counter(file, stride, CP_COUNTER_STRIDE); \
    if(!__aligned) \
        CP_INC(file, CP_MEM_NOT_ALIGNED, 1); \
Philip Carns's avatar
Philip Carns committed
217
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
218 219 220 221 222
        CP_INC(file, CP_FILE_NOT_ALIGNED, 1); \
    cp_access_counter(file, __ret, CP_COUNTER_ACCESS); \
    if(file->last_io_type == CP_WRITE) \
        CP_INC(file, CP_RW_SWITCHES, 1); \
    file->last_io_type = CP_READ; \
223
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_read_end, CP_F_POSIX_READ_TIME); \
224 225 226
    if(CP_F_VALUE(file, CP_F_READ_START_TIMESTAMP) == 0) \
        CP_F_SET(file, CP_F_READ_START_TIMESTAMP, __tm1); \
    CP_F_SET(file, CP_F_READ_END_TIMESTAMP, __tm2); \
227 228 229
    if(CP_F_VALUE(file, CP_F_MAX_READ_TIME) < __elapsed){ \
        CP_F_SET(file, CP_F_MAX_READ_TIME, __elapsed); \
        CP_SET(file, CP_MAX_READ_TIME_SIZE, __ret); } \
230 231
} while(0)

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
#define CP_LOOKUP_RECORD_STAT(__path, __statbuf, __tm1, __tm2) do { \
    char* exclude; \
    int tmp_index = 0; \
    struct darshan_file_runtime* file; \
    while((exclude = exclusions[tmp_index])) { \
        if(!(strncmp(exclude, __path, strlen(exclude)))) \
            break; \
        tmp_index++; \
    } \
    if(exclude) break; \
    file = darshan_file_by_name(__path); \
    if (file) \
    { \
        CP_RECORD_STAT(file, __statbuf, __tm1, __tm2); \
    } \
} while(0)

    
250
#define CP_RECORD_STAT(__file, __statbuf, __tm1, __tm2) do { \
251
    if(!CP_VALUE((__file), CP_POSIX_STATS) && !CP_VALUE((__file), CP_POSIX_OPENS)){ \
252 253 254 255
        CP_SET((__file), CP_FILE_ALIGNMENT, (__statbuf)->st_blksize); \
        CP_SET((__file), CP_SIZE_AT_OPEN, (__statbuf)->st_size); \
    }\
    (__file)->log_file->rank = my_rank; \
256
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
257 258 259
    CP_INC(__file, CP_POSIX_STATS, 1); \
} while(0)

Philip Carns's avatar
Philip Carns committed
260
#ifdef __CP_STAT_AT_OPEN
261
#define CP_STAT_FILE(_f, _p, _r) do { \
262
    if(!CP_VALUE((_f), CP_POSIX_STATS) && !CP_VALUE((_f), CP_POSIX_OPENS)){ \
263
        if(fstat64(_r, &cp_stat_buf) == 0) { \
Philip Carns's avatar
Philip Carns committed
264 265 266 267 268 269
            CP_SET(_f, CP_FILE_ALIGNMENT, cp_stat_buf.st_blksize); \
            CP_SET(_f, CP_SIZE_AT_OPEN, cp_stat_buf.st_size); \
        }\
    }\
}while(0)
#else
270
#define CP_STAT_FILE(_f, _p, _r) do { }while(0)
Philip Carns's avatar
Philip Carns committed
271
#endif
272
#endif
Philip Carns's avatar
Philip Carns committed
273

274 275 276 277 278 279 280 281 282 283 284
#define CP_RECORD_OPEN(__ret, __path, __mode, __stream_flag, __tm1, __tm2) do { \
    struct darshan_file_runtime* file; \
    char* exclude; \
    int tmp_index = 0; \
    if(__ret < 0) break; \
    while((exclude = exclusions[tmp_index])) { \
        if(!(strncmp(exclude, __path, strlen(exclude)))) \
            break; \
        tmp_index++; \
    } \
    if(exclude) break; \
285
    file = darshan_file_by_name_setfd(__path, __ret); \
286
    if(!file) break; \
287
    CP_STAT_FILE(file, __path, __ret); \
288 289 290 291 292 293 294 295 296 297 298
    file->log_file->rank = my_rank; \
    if(__mode) \
        CP_SET(file, CP_MODE, __mode); \
    file->offset = 0; \
    file->last_byte_written = 0; \
    file->last_byte_read = 0; \
    if(__stream_flag)\
        CP_INC(file, CP_POSIX_FOPENS, 1); \
    else \
        CP_INC(file, CP_POSIX_OPENS, 1); \
    if(CP_F_VALUE(file, CP_F_OPEN_TIMESTAMP) == 0) \
Philip Carns's avatar
Philip Carns committed
299
        CP_F_SET(file, CP_F_OPEN_TIMESTAMP, __tm1); \
300
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
301 302
} while (0)

303
#if 0
304
int DARSHAN_DECL(close)(int fd)
305 306 307 308 309 310
{
    struct darshan_file_runtime* file;
    int tmp_fd = fd;
    double tm1, tm2;
    int ret;

311 312
    MAP_OR_FAIL(close);

313 314
    DARSHAN_REGISTER_POSIX_MOD();

315 316 317 318 319 320 321 322 323 324
    tm1 = darshan_wtime();
    ret = __real_close(fd);
    tm2 = darshan_wtime();

    CP_LOCK();
    file = darshan_file_by_fd(tmp_fd);
    if(file)
    {
        file->last_byte_written = 0;
        file->last_byte_read = 0;
325
        CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
326
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
327
        darshan_file_close_fd(tmp_fd);
328 329 330 331 332 333
    }
    CP_UNLOCK();

    return(ret);
}

334
int DARSHAN_DECL(fclose)(FILE *fp)
335 336 337 338 339 340
{
    struct darshan_file_runtime* file;
    int tmp_fd = fileno(fp);
    double tm1, tm2;
    int ret;

341 342
    MAP_OR_FAIL(fclose);

343 344
    DARSHAN_REGISTER_POSIX_MOD();

345 346 347 348 349 350 351 352 353 354
    tm1 = darshan_wtime();
    ret = __real_fclose(fp);
    tm2 = darshan_wtime();
    
    CP_LOCK();
    file = darshan_file_by_fd(tmp_fd);
    if(file)
    {
        file->last_byte_written = 0;
        file->last_byte_read = 0;
355
        CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
356
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
357
        darshan_file_close_fd(tmp_fd);
358 359 360 361 362 363 364
    }
    CP_UNLOCK();

    return(ret);
}


365
int DARSHAN_DECL(fsync)(int fd)
366 367 368 369 370
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

371 372
    MAP_OR_FAIL(fsync);

373 374
    DARSHAN_REGISTER_POSIX_MOD();

375 376 377 378 379 380 381 382 383 384 385
    tm1 = darshan_wtime();
    ret = __real_fsync(fd);
    tm2 = darshan_wtime();

    if(ret < 0)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
386
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
387 388 389 390 391 392 393
        CP_INC(file, CP_POSIX_FSYNCS, 1);
    }
    CP_UNLOCK();

    return(ret);
}

394
int DARSHAN_DECL(fdatasync)(int fd)
395 396 397 398 399
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

400 401
    MAP_OR_FAIL(fdatasync);

402 403
    DARSHAN_REGISTER_POSIX_MOD();

404 405 406 407 408 409 410 411 412 413
    tm1 = darshan_wtime();
    ret = __real_fdatasync(fd);
    tm2 = darshan_wtime();
    if(ret < 0)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
414
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
415 416 417 418 419 420 421 422
        CP_INC(file, CP_POSIX_FDSYNCS, 1);
    }
    CP_UNLOCK();

    return(ret);
}


423
void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
424 425 426 427 428
    int fd, off64_t offset)
{
    void* ret;
    struct darshan_file_runtime* file;

429 430
    MAP_OR_FAIL(mmap64);

431 432
    DARSHAN_REGISTER_POSIX_MOD();

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
    ret = __real_mmap64(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
        CP_INC(file, CP_POSIX_MMAPS, 1);
    }
    CP_UNLOCK();

    return(ret);
}


449
void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
450 451 452 453 454
    int fd, off_t offset)
{
    void* ret;
    struct darshan_file_runtime* file;

455 456
    MAP_OR_FAIL(mmap);

457 458
    DARSHAN_REGISTER_POSIX_MOD();

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
    ret = __real_mmap(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
        CP_INC(file, CP_POSIX_MMAPS, 1);
    }
    CP_UNLOCK();

    return(ret);
}

474
int DARSHAN_DECL(creat)(const char* path, mode_t mode)
475 476 477 478
{
    int ret;
    double tm1, tm2;

479 480
    MAP_OR_FAIL(creat);

481 482
    DARSHAN_REGISTER_POSIX_MOD();

483 484 485 486 487 488 489 490 491 492 493
    tm1 = darshan_wtime();
    ret = __real_creat(path, mode);
    tm2 = darshan_wtime();

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

494
int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
495 496 497 498
{
    int ret;
    double tm1, tm2;

499 500
    MAP_OR_FAIL(creat64);

501 502
    DARSHAN_REGISTER_POSIX_MOD();

503 504 505 506 507 508 509 510 511 512 513
    tm1 = darshan_wtime();
    ret = __real_creat64(path, mode);
    tm2 = darshan_wtime();

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

514
int DARSHAN_DECL(open64)(const char* path, int flags, ...)
515 516 517 518 519
{
    int mode = 0;
    int ret;
    double tm1, tm2;

520 521
    MAP_OR_FAIL(open64);

522 523
    DARSHAN_REGISTER_POSIX_MOD();

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    if (flags & O_CREAT) 
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

        tm1 = darshan_wtime();
        ret = __real_open64(path, flags, mode);
        tm2 = darshan_wtime();
    }
    else
    {
        tm1 = darshan_wtime();
        ret = __real_open64(path, flags);
        tm2 = darshan_wtime();
    }

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}
548
#endif
549

550
int DARSHAN_DECL(open)(const char *path, int flags, ...)
551 552 553 554 555
{
    int mode = 0;
    int ret;
    double tm1, tm2;

556 557
    MAP_OR_FAIL(open);

558 559
    DARSHAN_REGISTER_POSIX_MOD();
#if 0
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
    if (flags & O_CREAT) 
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

        tm1 = darshan_wtime();
        ret = __real_open(path, flags, mode);
        tm2 = darshan_wtime();
    }
    else
    {
        tm1 = darshan_wtime();
        ret = __real_open(path, flags);
        tm2 = darshan_wtime();
    }

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();
581
#endif
582 583 584 585

    return(ret);
}

586
#if 0
587
FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
588 589 590 591 592
{
    FILE* ret;
    int fd;
    double tm1, tm2;

593 594
    MAP_OR_FAIL(fopen64);

595 596
    DARSHAN_REGISTER_POSIX_MOD();

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
    tm1 = darshan_wtime();
    ret = __real_fopen64(path, mode);
    tm2 = darshan_wtime();
    if(ret == 0)
        fd = -1;
    else
        fd = fileno(ret);

    CP_LOCK();
    CP_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

612
FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
613 614 615 616 617
{
    FILE* ret;
    int fd;
    double tm1, tm2;

618 619
    MAP_OR_FAIL(fopen);

620 621
    DARSHAN_REGISTER_POSIX_MOD();

622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    tm1 = darshan_wtime();
    ret = __real_fopen(path, mode);
    tm2 = darshan_wtime();
    if(ret == 0)
        fd = -1;
    else
        fd = fileno(ret);

    CP_LOCK();
    CP_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

637
int DARSHAN_DECL(__xstat64)(int vers, const char *path, struct stat64 *buf)
638 639 640 641
{
    int ret;
    double tm1, tm2;

642 643
    MAP_OR_FAIL(__xstat64);

644 645
    DARSHAN_REGISTER_POSIX_MOD();

646 647 648 649 650 651 652
    tm1 = darshan_wtime();
    ret = __real___xstat64(vers, path, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
653
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
654 655 656 657 658
    CP_UNLOCK();

    return(ret);
}

659
int DARSHAN_DECL(__lxstat64)(int vers, const char *path, struct stat64 *buf)
660 661 662 663
{
    int ret;
    double tm1, tm2;

664 665
    MAP_OR_FAIL(__lxstat64);

666 667
    DARSHAN_REGISTER_POSIX_MOD();

668 669 670 671 672 673 674
    tm1 = darshan_wtime();
    ret = __real___lxstat64(vers, path, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
675
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
676 677 678 679 680
    CP_UNLOCK();

    return(ret);
}

681
int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
682 683 684 685 686
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

687 688
    MAP_OR_FAIL(__fxstat64);

689 690
    DARSHAN_REGISTER_POSIX_MOD();

691 692 693 694 695 696 697 698 699 700 701 702 703 704
    tm1 = darshan_wtime();
    ret = __real___fxstat64(vers, fd, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    /* skip logging if this was triggered internally */
    if(buf == &cp_stat_buf)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
705
        CP_RECORD_STAT(file, buf, tm1, tm2);
706 707 708 709 710 711 712
    }
    CP_UNLOCK();

    return(ret);
}


713
int DARSHAN_DECL(__xstat)(int vers, const char *path, struct stat *buf)
714 715 716 717
{
    int ret;
    double tm1, tm2;

718 719
    MAP_OR_FAIL(__xstat);

720 721
    DARSHAN_REGISTER_POSIX_MOD();

722 723 724 725 726 727 728
    tm1 = darshan_wtime();
    ret = __real___xstat(vers, path, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
729
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
730 731 732 733 734
    CP_UNLOCK();

    return(ret);
}

735
int DARSHAN_DECL(__lxstat)(int vers, const char *path, struct stat *buf)
736 737 738 739
{
    int ret;
    double tm1, tm2;

740 741
    MAP_OR_FAIL(__lxstat);

742 743
    DARSHAN_REGISTER_POSIX_MOD();

744 745 746 747 748 749 750
    tm1 = darshan_wtime();
    ret = __real___lxstat(vers, path, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
751
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
752 753 754 755 756
    CP_UNLOCK();

    return(ret);
}

757
int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
758 759 760 761 762
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

763 764
    MAP_OR_FAIL(__fxstat);

765 766
    DARSHAN_REGISTER_POSIX_MOD();

767 768 769 770 771 772 773
    tm1 = darshan_wtime();
    ret = __real___fxstat(vers, fd, buf);
    tm2 = darshan_wtime();
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    /* skip logging if this was triggered internally */
774
    if((void*)buf == (void*)&cp_stat_buf)
775 776 777 778 779 780
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
781
        CP_RECORD_STAT(file, buf, tm1, tm2);
782 783 784 785 786 787
    }
    CP_UNLOCK();

    return(ret);
}

788
ssize_t DARSHAN_DECL(pread64)(int fd, void *buf, size_t count, off64_t offset)
789 790 791 792 793
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

794 795
    MAP_OR_FAIL(pread64);

796 797
    DARSHAN_REGISTER_POSIX_MOD();

798
    if((unsigned long)buf % darshan_mem_alignment == 0)
799 800 801 802 803 804
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_pread64(fd, buf, count, offset);
    tm2 = darshan_wtime();
    CP_LOCK();
805
    CP_RECORD_READ(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
806 807 808 809
    CP_UNLOCK();
    return(ret);
}

810
ssize_t DARSHAN_DECL(pread)(int fd, void *buf, size_t count, off_t offset)
811 812 813 814 815
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

816 817
    MAP_OR_FAIL(pread);

818 819
    DARSHAN_REGISTER_POSIX_MOD();

820
    if((unsigned long)buf % darshan_mem_alignment == 0)
821 822 823 824 825 826
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_pread(fd, buf, count, offset);
    tm2 = darshan_wtime();
    CP_LOCK();
827
    CP_RECORD_READ(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
828 829 830 831 832
    CP_UNLOCK();
    return(ret);
}


833
ssize_t DARSHAN_DECL(pwrite)(int fd, const void *buf, size_t count, off_t offset)
834 835 836 837 838
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

839 840
    MAP_OR_FAIL(pwrite);

841 842
    DARSHAN_REGISTER_POSIX_MOD();

843
    if((unsigned long)buf % darshan_mem_alignment == 0)
844 845 846 847 848 849
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_pwrite(fd, buf, count, offset);
    tm2 = darshan_wtime();
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
850
    CP_RECORD_WRITE(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
851 852 853 854
    CP_UNLOCK();
    return(ret);
}

855
ssize_t DARSHAN_DECL(pwrite64)(int fd, const void *buf, size_t count, off64_t offset)
856 857 858 859 860
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

861 862
    MAP_OR_FAIL(pwrite64);

863 864
    DARSHAN_REGISTER_POSIX_MOD();

865
    if((unsigned long)buf % darshan_mem_alignment == 0)
866 867 868 869 870 871
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_pwrite64(fd, buf, count, offset);
    tm2 = darshan_wtime();
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
872
    CP_RECORD_WRITE(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
873 874 875 876
    CP_UNLOCK();
    return(ret);
}

877
ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
878 879 880 881 882 883
{
    ssize_t ret;
    int aligned_flag = 1;
    int i;
    double tm1, tm2;

884 885
    MAP_OR_FAIL(readv);

886 887
    DARSHAN_REGISTER_POSIX_MOD();

888 889
    for(i=0; i<iovcnt; i++)
    {
890
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
891 892 893 894 895 896 897
            aligned_flag = 0;
    }

    tm1 = darshan_wtime();
    ret = __real_readv(fd, iov, iovcnt);
    tm2 = darshan_wtime();
    CP_LOCK();
898
    CP_RECORD_READ(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
899 900 901 902
    CP_UNLOCK();
    return(ret);
}

903
ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
904 905 906 907 908 909
{
    ssize_t ret;
    int aligned_flag = 1;
    int i;
    double tm1, tm2;

910 911
    MAP_OR_FAIL(writev);

912 913
    DARSHAN_REGISTER_POSIX_MOD();

914 915
    for(i=0; i<iovcnt; i++)
    {
916
        if(!((unsigned long)iov[i].iov_base % darshan_mem_alignment == 0))
917 918 919 920 921 922 923
            aligned_flag = 0;
    }

    tm1 = darshan_wtime();
    ret = __real_writev(fd, iov, iovcnt);
    tm2 = darshan_wtime();
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
924
    CP_RECORD_WRITE(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
925 926 927 928
    CP_UNLOCK();
    return(ret);
}

929
size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
930 931 932 933 934
{
    size_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

935 936
    MAP_OR_FAIL(fread);

937 938
    DARSHAN_REGISTER_POSIX_MOD();

939
    if((unsigned long)ptr % darshan_mem_alignment == 0)
940 941 942 943 944 945 946
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_fread(ptr, size, nmemb, stream);
    tm2 = darshan_wtime();
    CP_LOCK();
    if(ret > 0)
947
        CP_RECORD_READ(size*ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
948
    else
949
        CP_RECORD_READ(ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
950 951 952 953
    CP_UNLOCK();
    return(ret);
}

954
ssize_t DARSHAN_DECL(read)(int fd, void *buf, size_t count)
955 956 957 958 959
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

960 961
    MAP_OR_FAIL(read);

962 963
    DARSHAN_REGISTER_POSIX_MOD();

964
    if((unsigned long)buf % darshan_mem_alignment == 0)
965 966 967 968 969 970
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_read(fd, buf, count);
    tm2 = darshan_wtime();
    CP_LOCK();
971
    CP_RECORD_READ(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
972 973 974 975
    CP_UNLOCK();
    return(ret);
}

976
ssize_t DARSHAN_DECL(write)(int fd, const void *buf, size_t count)
977 978 979 980 981
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

982 983
    MAP_OR_FAIL(write);

984 985
    DARSHAN_REGISTER_POSIX_MOD();

986
    if((unsigned long)buf % darshan_mem_alignment == 0)
987 988 989 990 991 992
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_write(fd, buf, count);
    tm2 = darshan_wtime();
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
993
    CP_RECORD_WRITE(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
994 995 996 997
    CP_UNLOCK();
    return(ret);
}

998
size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream)
999 1000 1001 1002 1003
{
    size_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

1004 1005
    MAP_OR_FAIL(fwrite);

1006 1007
    DARSHAN_REGISTER_POSIX_MOD();

1008
    if((unsigned long)ptr % darshan_mem_alignment == 0)
1009 1010 1011 1012 1013 1014 1015
        aligned_flag = 1;

    tm1 = darshan_wtime();
    ret = __real_fwrite(ptr, size, nmemb, stream);
    tm2 = darshan_wtime();
    CP_LOCK();
    if(ret > 0)
Philip Carns's avatar
Philip Carns committed
1016
        CP_RECORD_WRITE(size*ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
1017
    else
Philip Carns's avatar
Philip Carns committed
1018
        CP_RECORD_WRITE(ret, fileno(stream), 0, 0, 0, aligned_flag, 1, tm1, tm2);
1019 1020 1021 1022
    CP_UNLOCK();
    return(ret);
}

1023
off64_t DARSHAN_DECL(lseek64)(int fd, off64_t offset, int whence)
1024
{
Philip Carns's avatar
Philip Carns committed
1025
    off64_t ret;
1026 1027 1028
    struct darshan_file_runtime* file;
    double tm1, tm2;

1029 1030
    MAP_OR_FAIL(lseek64);

1031 1032
    DARSHAN_REGISTER_POSIX_MOD();

1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
    tm1 = darshan_wtime();
    ret = __real_lseek64(fd, offset, whence);
    tm2 = darshan_wtime();
    if(ret >= 0)
    {
        CP_LOCK();
        file = darshan_file_by_fd(fd);
        if(file)
        {
            file->offset = ret;
1043
            CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
1044 1045 1046 1047 1048 1049 1050
            CP_INC(file, CP_POSIX_SEEKS, 1);
        }
        CP_UNLOCK();
    }
    return(ret);
}

1051
off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
1052 1053 1054 1055 1056
{
    off_t ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

1057 1058
    MAP_OR_FAIL(lseek);

1059 1060
    DARSHAN_REGISTER_POSIX_MOD();

1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
    tm1 = darshan_wtime();
    ret = __real_lseek(fd, offset, whence);
    tm2 = darshan_wtime();
    if(ret >= 0)
    {
        CP_LOCK();
        file = darshan_file_by_fd(fd);
        if(file)
        {
            file->offset = ret;
1071
            CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
1072 1073 1074 1075 1076 1077 1078
            CP_INC(file, CP_POSIX_SEEKS, 1);
        }
        CP_UNLOCK();
    }
    return(ret);
}

1079
ssize_t DARSHAN_DECL(aio_return64)(struct aiocb64 *aiocbp)
Philip Carns's avatar
Philip Carns committed
1080 1081
{
    int ret;
1082 1083 1084
    double tm2;
    struct darshan_aio_tracker *tmp;
    int aligned_flag = 0;
Philip Carns's avatar
Philip Carns committed
1085 1086 1087

    MAP_OR_FAIL(aio_return64);

1088 1089
    DARSHAN_REGISTER_POSIX_MOD();

Philip Carns's avatar
Philip Carns committed
1090
    ret = __real_aio_return64(aiocbp);
1091
    tm2 = darshan_wtime();
1092
    tmp = darshan_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
1093 1094 1095 1096 1097 1098

    if(tmp)
    {
        if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
            aligned_flag = 1;
        CP_LOCK();
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
        if(aiocbp->aio_lio_opcode == LIO_WRITE)
        {
            CP_RECORD_WRITE(ret, aiocbp->aio_fildes, aiocbp->aio_nbytes,
                1, aiocbp->aio_offset, aligned_flag, 0, tmp->tm1, tm2);
        }
        if(aiocbp->aio_lio_opcode == LIO_READ)
        {
            CP_RECORD_READ(ret, aiocbp->aio_fildes, aiocbp->aio_nbytes,
                1, aiocbp->aio_offset, aligned_flag, 0, tmp->tm1, tm2);
        }
1109 1110 1111
        CP_UNLOCK();
        free(tmp);
    }
Philip Carns's avatar
Philip Carns committed
1112 1113 1114 1115 1116 1117 1118

    return(ret);
}

ssize_t DARSHAN_DECL(aio_return)(struct aiocb *aiocbp)
{
    int ret;
1119 1120 1121
    double tm2;
    struct darshan_aio_tracker *tmp;
    int aligned_flag = 0;
Philip Carns's avatar
Philip Carns committed
1122 1123 1124

    MAP_OR_FAIL(aio_return);

1125 1126
    DARSHAN_REGISTER_POSIX_MOD();

Philip Carns's avatar
Philip Carns committed
1127
    ret = __real_aio_return(aiocbp);
1128
    tm2 = darshan_wtime();
1129
    tmp = darshan_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140

    if(tmp)
    {
        if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
            aligned_flag = 1;
        CP_LOCK();
        CP_RECORD_WRITE(ret, aiocbp->aio_fildes, aiocbp->aio_nbytes,
            1, aiocbp->aio_offset, aligned_flag, 0, tmp->tm1, tm2);
        CP_UNLOCK();
        free(tmp);
    }
Philip Carns's avatar
Philip Carns committed
1141 1142 1143 1144 1145 1146 1147 1148

    return(ret);
}