darshan-dxt-parser.c 9.82 KB
Newer Older
1
/*
2
 * Copyright (C) 2015 University of Chicago.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * See COPYRIGHT notice in top-level directory.
 *
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <time.h>
#include <stdlib.h>
#include <getopt.h>
#include <assert.h>

#include "uthash-1.9.2/src/uthash.h"

#include "darshan-logutils.h"

extern void dxt_logutils_cleanup();
24
extern void dxt_log_print_posix_file(void *file_rec, char *file_name,
25
        char *mnt_pt, char *fs_type, struct lustre_record_ref *ref);
26 27
extern void dxt_log_print_mpiio_file(void *file_rec, char *file_name,
        char *mnt_pt, char *fs_type);
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

int usage (char *exename)
{
    fprintf(stderr, "Usage: %s <filename>\n", exename);

    exit(1);
}

int main(int argc, char **argv)
{
    int ret;
    int i, j;
    char *filename;
    char *comp_str;
    char tmp_string[4096] = {0};
    darshan_fd fd;
    struct darshan_job job;
    struct darshan_name_record_ref *name_hash = NULL;
46
    struct darshan_name_record_ref *ref, *tmp_ref;
47 48 49 50 51 52 53 54 55
    int mount_count;
    struct darshan_mnt_info *mnt_data_array;
    time_t tmp_time = 0;
    int64_t run_time = 0;
    char *token;
    char *save;
    char buffer[DARSHAN_JOB_METADATA_LEN];
    struct lustre_record_ref *lustre_rec_ref, *tmp_lustre_rec_ref;
    struct lustre_record_ref *lustre_rec_hash = NULL;
56
    int empty_mods = 0;
57 58
    char *mod_buf = NULL;

59
    if (argc != 2)
60 61 62 63 64
        usage(argv[0]);

    filename = argv[1];

    fd = darshan_log_open(filename);
65
    if (!fd)
66 67 68 69
        return(-1);

    /* read darshan job info */
    ret = darshan_log_get_job(fd, &job);
70
    if (ret < 0)
71 72 73 74 75 76 77
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* get the original command line for this job */
    ret = darshan_log_get_exe(fd, tmp_string);
78
    if (ret < 0)
79 80 81 82 83 84 85
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* get the mount information for this log */
    ret = darshan_log_get_mounts(fd, &mnt_data_array, &mount_count);
86
    if (ret < 0)
87 88 89 90 91 92 93
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* read hash of darshan records */
    ret = darshan_log_get_namehash(fd, &name_hash);
94 95 96 97 98
    if (ret < 0)
    {
        darshan_log_close(fd);
        return(-1);
    }
99 100 101 102

    /* print any warnings related to this log file version */
    darshan_log_print_version_warnings(fd->version);

103
    if (fd->comp_type == DARSHAN_ZLIB_COMP)
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        comp_str = "ZLIB";
    else if (fd->comp_type == DARSHAN_BZIP2_COMP)
        comp_str = "BZIP2";
    else if (fd->comp_type == DARSHAN_NO_COMP)
        comp_str = "NONE";
    else
        comp_str = "UNKNOWN";

    /* print job summary */
    printf("# darshan log version: %s\n", fd->version);
    printf("# compression method: %s\n", comp_str);
    printf("# exe: %s\n", tmp_string);
    printf("# uid: %" PRId64 "\n", job.uid);
    printf("# jobid: %" PRId64 "\n", job.jobid);
    printf("# start_time: %" PRId64 "\n", job.start_time);
    tmp_time += job.start_time;
    printf("# start_time_asci: %s", ctime(&tmp_time));
    printf("# end_time: %" PRId64 "\n", job.end_time);
    tmp_time = 0;
    tmp_time += job.end_time;
    printf("# end_time_asci: %s", ctime(&tmp_time));
    printf("# nprocs: %" PRId64 "\n", job.nprocs);
126
    if (job.end_time >= job.start_time)
127 128
        run_time = job.end_time - job.start_time + 1;
    printf("# run time: %" PRId64 "\n", run_time);
129
    for (token = strtok_r(job.metadata, "\n", &save);
130
        token != NULL;
131
        token = strtok_r(NULL, "\n", &save))
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
    {
        char *key;
        char *value;
        /* NOTE: we intentionally only split on the first = character.
         * There may be additional = characters in the value portion
         * (for example, when storing mpi-io hints).
         */
        strcpy(buffer, token);
        key = buffer;
        value = index(buffer, '=');
        if(!value)
            continue;
        /* convert = to a null terminator to split key and value */
        value[0] = '\0';
        value++;
        printf("# metadata: %s = %s\n", key, value);
    }

    /* print breakdown of each log file region's contribution to file size */
    printf("\n# log file regions\n");
    printf("# -------------------------------------------------------\n");
    printf("# header: %zu bytes (uncompressed)\n", sizeof(struct darshan_header));
    printf("# job data: %zu bytes (compressed)\n", fd->job_map.len);
    printf("# record table: %zu bytes (compressed)\n", fd->name_map.len);
156
    for (i = 0; i < DARSHAN_MAX_MODS; i++)
157
    {
158
        if (fd->mod_map[i].len)
159 160 161 162 163 164 165 166 167
        {
            printf("# %s module: %zu bytes (compressed), ver=%d\n",
                darshan_module_names[i], fd->mod_map[i].len, fd->mod_ver[i]);
        }
    }

    /* print table of mounted file systems */
    printf("\n# mounted file systems (mount point and fs type)\n");
    printf("# -------------------------------------------------------\n");
168
    for (i = 0; i < mount_count; i++)
169 170 171 172 173 174 175 176 177 178 179 180
    {
        printf("# mount entry:\t%s\t%s\n", mnt_data_array[i].mnt_path,
            mnt_data_array[i].mnt_type);
    }

    /* just exit if there is no DXT data in this log file */
    if(fd->mod_map[DXT_POSIX_MOD].len == 0 && fd->mod_map[DXT_MPIIO_MOD].len == 0)
    {
        printf("\n# no DXT module data available for this Darshan log.\n");
        goto cleanup;
    }

181 182 183 184 185 186
    mod_buf = malloc(DEF_MOD_BUF_SIZE);
    if (!mod_buf) {
        goto cleanup;
    }

    for (i = 0; i < DARSHAN_MAX_MODS; i++)
187
    {
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
        struct darshan_base_record *base_rec;

        /* check each module for any data */
        if (fd->mod_map[i].len == 0)
        {
            empty_mods++;
            continue;
        }
        /* skip modules with no logutil definitions */
        else if (!mod_logutils[i])
        {
            fprintf(stderr, "Warning: no log utility handlers defined "
                "for module %s, SKIPPING.\n", darshan_module_names[i]);
            continue;
        }

        /* this module has data to be parsed and printed */
        memset(mod_buf, 0, DEF_MOD_BUF_SIZE);

        if (i == DXT_POSIX_MOD || i == DXT_MPIIO_MOD) {
            printf("\n# ***************************************************\n");
            printf("# %s module data\n", darshan_module_names[i]);
            printf("# ***************************************************\n");
        }

        /* loop over each of this module's records and print them */
214 215
        while(1)
        {
216 217 218 219 220 221 222 223 224 225 226 227 228 229
            char *mnt_pt = NULL;
            char *fs_type = NULL;
            char *rec_name = NULL;

            if (i == DARSHAN_LUSTRE_MOD) {
                lustre_rec_ref = malloc(sizeof(*lustre_rec_ref));
                assert(lustre_rec_ref);
                memset(lustre_rec_ref, 0, sizeof(*lustre_rec_ref));

                ret = mod_logutils[i]->log_get_record(fd,
                        (void **)&(lustre_rec_ref->rec));
            } else {
                ret = mod_logutils[i]->log_get_record(fd, (void **)&mod_buf);
            }
230

231
            if (ret < 1)
232
            {
233
                if (ret == -1)
234
                {
235 236
                    fprintf(stderr, "Error: failed to parse %s module record.\n",
                        darshan_module_names[i]);
237 238 239 240
                    goto cleanup;
                }
                break;
            }
241 242

            if (i == DARSHAN_LUSTRE_MOD) {
243
                HASH_ADD(hlink, lustre_rec_hash, rec->base_rec.id,
244
                        sizeof(darshan_record_id), lustre_rec_ref);
245 246
            }

247 248
            if ((i != DXT_POSIX_MOD) && (i != DXT_MPIIO_MOD))
                continue;
249

250
            base_rec = (struct darshan_base_record *)mod_buf;
251

252 253 254 255 256
            /* get the pathname for this record */
            HASH_FIND(hlink, name_hash, &(base_rec->id),
                    sizeof(darshan_record_id), ref);

            if (ref)
257
            {
258
                rec_name = ref->name_record->name;
259

260 261
                /* get mount point and fs type associated with this record */
                for (j = 0; j < mount_count; j++)
262
                {
263 264
                    if(strncmp(mnt_data_array[j].mnt_path, rec_name,
                        strlen(mnt_data_array[j].mnt_path)) == 0)
265
                    {
266 267 268
                        mnt_pt = mnt_data_array[j].mnt_path;
                        fs_type = mnt_data_array[j].mnt_type;
                        break;
269 270 271 272
                    }
                }
            }

273 274 275 276
            if (!mnt_pt)
                mnt_pt = "UNKNOWN";
            if (!fs_type)
                fs_type = "UNKNOWN";
277

278 279 280 281 282 283
            if (i == DXT_POSIX_MOD) {
                /* look for corresponding lustre record and print DXT data */
                HASH_FIND(hlink, lustre_rec_hash, &(base_rec->id),
                        sizeof(darshan_record_id), lustre_rec_ref);

                dxt_log_print_posix_file(mod_buf, rec_name,
284
                        mnt_pt, fs_type, lustre_rec_ref);
285 286 287 288
            } else if (i == DXT_MPIIO_MOD){
                dxt_log_print_mpiio_file(mod_buf, rec_name,
                        mnt_pt, fs_type);
            
289 290
            }

291
            memset(mod_buf, 0, DEF_MOD_BUF_SIZE);
292 293 294
        }
    }

295 296
    if (empty_mods == DARSHAN_MAX_MODS)
        printf("\n# no module data available.\n");
297 298
    ret = 0;

299 300
    /* DXT */
    dxt_logutils_cleanup();
301

302
cleanup:
303
    darshan_log_close(fd);
304
    free(mod_buf);
305 306

    /* free record hash data */
307
    HASH_ITER(hlink, name_hash, ref, tmp_ref)
308
    {
309 310 311
        HASH_DELETE(hlink, name_hash, ref);
        free(ref->name_record);
        free(ref);
312 313 314 315
    }

    /* free lustre record data */
    HASH_ITER(hlink, lustre_rec_hash, lustre_rec_ref, tmp_lustre_rec_ref)
316
    {   
317 318 319
        HASH_DELETE(hlink, lustre_rec_hash, lustre_rec_ref);
        free(lustre_rec_ref->rec);
        free(lustre_rec_ref);
320
    } 
321 322

    /* free mount info */
323
    if (mount_count > 0)
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    {
        free(mnt_data_array);
    }

    return(ret);
}

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */