darshan-dxt-parser.c 9.48 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 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
 * 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"

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;
40
    struct darshan_name_record_ref *ref, *tmp_ref;
41 42 43 44 45 46 47 48 49 50 51
    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;
    char *mod_buf = NULL;

52
    if (argc != 2)
53 54 55 56 57
        usage(argv[0]);

    filename = argv[1];

    fd = darshan_log_open(filename);
58
    if (!fd)
59 60 61 62
        return(-1);

    /* read darshan job info */
    ret = darshan_log_get_job(fd, &job);
63
    if (ret < 0)
64 65 66 67 68 69 70
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* get the original command line for this job */
    ret = darshan_log_get_exe(fd, tmp_string);
71
    if (ret < 0)
72 73 74 75 76 77 78
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* get the mount information for this log */
    ret = darshan_log_get_mounts(fd, &mnt_data_array, &mount_count);
79
    if (ret < 0)
80 81 82 83 84 85 86
    {
        darshan_log_close(fd);
        return(-1);
    }

    /* read hash of darshan records */
    ret = darshan_log_get_namehash(fd, &name_hash);
87 88 89 90 91
    if (ret < 0)
    {
        darshan_log_close(fd);
        return(-1);
    }
92 93 94 95

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

96
    if (fd->comp_type == DARSHAN_ZLIB_COMP)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
        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);
119
    if (job.end_time >= job.start_time)
120 121
        run_time = job.end_time - job.start_time + 1;
    printf("# run time: %" PRId64 "\n", run_time);
122
    for (token = strtok_r(job.metadata, "\n", &save);
123
        token != NULL;
124
        token = strtok_r(NULL, "\n", &save))
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    {
        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);
149
    for (i = 0; i < DARSHAN_MAX_MODS; i++)
150
    {
151
        if (fd->mod_map[i].len)
152 153 154 155 156 157 158 159 160
        {
            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");
161
    for (i = 0; i < mount_count; i++)
162 163 164 165 166 167 168 169 170 171 172 173
    {
        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;
    }

174
    for (i = 0; i < DARSHAN_MAX_MODS; i++)
175
    {
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
        struct darshan_base_record *base_rec;

        /* check each module for any data */
        if (fd->mod_map[i].len == 0)
            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;
        }

        if (i == DXT_POSIX_MOD || i == DXT_MPIIO_MOD) {
            printf("\n# ***************************************************\n");
            printf("# %s module data\n", darshan_module_names[i]);
            printf("# ***************************************************\n");
        }
Shane Snyder's avatar
Shane Snyder committed
194 195
        else if (i != DARSHAN_LUSTRE_MOD)
            continue;
196

197 198 199 200 201 202 203
        /* print warning if this module only stored partial data */
        if(DARSHAN_MOD_FLAG_ISSET(fd->partial_flag, i))
            printf("\n# *WARNING*: The %s module contains incomplete data!\n"
                   "#            This happens when a module runs out of\n"
                   "#            memory to store new record data.\n",
                   darshan_module_names[i]);

204
        /* loop over each of this module's records and print them */
205 206
        while(1)
        {
207 208 209 210 211 212 213 214 215 216 217
            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));
Shane Snyder's avatar
Shane Snyder committed
218 219 220

                HASH_ADD(hlink, lustre_rec_hash, rec->base_rec.id,
                        sizeof(darshan_record_id), lustre_rec_ref);
221 222 223
            } else {
                ret = mod_logutils[i]->log_get_record(fd, (void **)&mod_buf);
            }
224

225
            if (ret < 1)
226
            {
227
                if (ret == -1)
228
                {
229 230
                    fprintf(stderr, "Error: failed to parse %s module record.\n",
                        darshan_module_names[i]);
231 232 233 234
                    goto cleanup;
                }
                break;
            }
235

236 237
            if(i == DARSHAN_LUSTRE_MOD) continue;

238
            base_rec = (struct darshan_base_record *)mod_buf;
239

240 241 242 243 244
            /* get the pathname for this record */
            HASH_FIND(hlink, name_hash, &(base_rec->id),
                    sizeof(darshan_record_id), ref);

            if (ref)
245
            {
246
                rec_name = ref->name_record->name;
247

248 249
                /* get mount point and fs type associated with this record */
                for (j = 0; j < mount_count; j++)
250
                {
251 252
                    if(strncmp(mnt_data_array[j].mnt_path, rec_name,
                        strlen(mnt_data_array[j].mnt_path)) == 0)
253
                    {
254 255 256
                        mnt_pt = mnt_data_array[j].mnt_path;
                        fs_type = mnt_data_array[j].mnt_type;
                        break;
257 258 259 260
                    }
                }
            }

261 262 263 264
            if (!mnt_pt)
                mnt_pt = "UNKNOWN";
            if (!fs_type)
                fs_type = "UNKNOWN";
265

266 267 268 269 270 271
            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,
272
                        mnt_pt, fs_type, lustre_rec_ref);
273 274 275
            } else if (i == DXT_MPIIO_MOD){
                dxt_log_print_mpiio_file(mod_buf, rec_name,
                        mnt_pt, fs_type);
276 277
            }

278 279
            free(mod_buf);
            mod_buf = NULL;
280 281 282 283 284
        }
    }

    ret = 0;

285
cleanup:
286 287 288
    darshan_log_close(fd);

    /* free record hash data */
289
    HASH_ITER(hlink, name_hash, ref, tmp_ref)
290
    {
291 292 293
        HASH_DELETE(hlink, name_hash, ref);
        free(ref->name_record);
        free(ref);
294 295 296 297
    }

    /* free lustre record data */
    HASH_ITER(hlink, lustre_rec_hash, lustre_rec_ref, tmp_lustre_rec_ref)
298
    {   
299 300 301
        HASH_DELETE(hlink, lustre_rec_hash, lustre_rec_ref);
        free(lustre_rec_ref->rec);
        free(lustre_rec_ref);
302
    } 
303 304

    /* free mount info */
305
    if (mount_count > 0)
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
    {
        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
 */