/* * FCP adapter trace facility * * Common utility functions to handle message structs * * Copyright IBM Corp. 2008, 2017 * * s390-tools is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ #include #include #include #include "ziomon_msg_tools.h" #include "ziomon_util.h" #include "ziomon_zfcpdd.h" #include "blkiomon.h" extern const char *toolname; void conv_blkiomon_v2_to_v3(struct message *msg) { struct blkiomon_stat_v2 stat_v2 = *(struct blkiomon_stat_v2*)msg->data; struct blkiomon_stat *stat = msg->data; stat->device = stat_v2.device; stat->size_r = stat_v2.size_r; stat->size_w = stat_v2.size_w; stat->d2c_r = stat_v2.d2c_r; stat->d2c_w = stat_v2.d2c_w; stat->thrput_r = stat_v2.thrput_r; stat->thrput_w = stat_v2.thrput_w; stat->bidir = stat_v2.bidir; } void conv_msg_data_to_BE(struct message *msg, const struct file_header *hdr) { if (msg->type == hdr->msgid_utilization) conv_overall_result_to_BE(msg->data); else if (msg->type == hdr->msgid_ioerr) conv_ioerr_data_to_BE(msg->data); else if (msg->type == hdr->msgid_blkiomon) blkiomon_conv_to_BE(msg->data); else if (msg->type == hdr->msgid_zfcpdd) conv_dstat_to_BE(msg->data); else fprintf(stderr, "%s: Unknown message encountered\n", toolname); } void conv_msg_data_from_BE(struct message *msg, const struct file_header *hdr) { if (msg->type == hdr->msgid_utilization) conv_overall_result_from_BE(msg->data); else if (msg->type == hdr->msgid_ioerr) conv_ioerr_data_from_BE(msg->data); else if (msg->type == hdr->msgid_blkiomon) blkiomon_conv_from_BE(msg->data); else if (msg->type == hdr->msgid_zfcpdd) conv_dstat_from_BE(msg->data); else fprintf(stderr,"%s: Unknown message encountered\n", toolname); } void conv_aggr_data_msg_data_to_BE(struct aggr_data *hdr) { __u64 i; if (hdr->util_aggr) conv_overall_result_to_BE(hdr->util_aggr->data); if (hdr->ioerr_aggr) conv_ioerr_data_to_BE(hdr->ioerr_aggr->data); for (i=0; inum_blkiomon; ++i) blkiomon_conv_to_BE(hdr->blkio_aggr[i]->data); for (i=0; inum_zfcpdd; ++i) conv_dstat_to_BE(hdr->zfcpdd_aggr[i]->data); } void conv_aggr_data_msg_data_from_BE(struct aggr_data *hdr) { __u64 i; if (hdr->util_aggr) conv_overall_result_from_BE(hdr->util_aggr->data); if (hdr->ioerr_aggr) conv_ioerr_data_from_BE(hdr->ioerr_aggr->data); for (i=0; inum_blkiomon; ++i) blkiomon_conv_to_BE(hdr->blkio_aggr[i]->data); for (i=0; inum_zfcpdd; ++i) conv_dstat_from_BE(hdr->zfcpdd_aggr[i]->data); } void copy_msg(struct message *src, struct message **tgt) { *tgt = malloc(sizeof(struct message)); (*tgt)->type = src->type; (*tgt)->length = src->length; (*tgt)->data = malloc(src->length); memcpy((*tgt)->data, src->data, src->length); } time_t get_timestamp_from_BE_msg(const struct message *msg) { time_t timestamp = get_timestamp_from_msg(msg); swap_64(timestamp); return timestamp; } time_t get_timestamp_from_msg(const struct message *msg) { return *(__u64*)(msg->data); } static void aggregate_blkiomon(struct aggr_data *agg_data, struct message *msg) { __u64 i; struct message **tmp; struct blkiomon_stat *stat = msg->data; for (i = 0; i < agg_data->num_blkiomon; ++i) if ((((struct blkiomon_stat*)(agg_data->blkio_aggr[i]->data))->device) == stat->device) break; if (i >= agg_data->num_blkiomon) { /* messages for this device not aggregated yet - add a new entry */ tmp = agg_data->blkio_aggr; ++(agg_data->num_blkiomon); agg_data->blkio_aggr = malloc(agg_data->num_blkiomon * sizeof(struct message*)); for (i = 0; i < agg_data->num_blkiomon - 1; ++i) agg_data->blkio_aggr[i] = tmp[i]; copy_msg(msg, &agg_data->blkio_aggr[i]); free(tmp); } else blkiomon_stat_merge(agg_data->blkio_aggr[i]->data, msg->data); } static void aggregate_zfcpdd(struct aggr_data *agg_data, struct message *msg) { __u64 i; struct message **tmp; struct zfcpdd_dstat *stat = msg->data; for (i = 0; i < agg_data->num_zfcpdd; ++i) if ((((struct zfcpdd_dstat*)(agg_data->zfcpdd_aggr[i]->data))->device) == stat->device) break; if (i >= agg_data->num_zfcpdd) { /* messages for this device not aggregated yet - add a new entry */ tmp = agg_data->zfcpdd_aggr; ++(agg_data->num_zfcpdd); agg_data->zfcpdd_aggr = malloc(agg_data->num_zfcpdd * sizeof(struct message*)); for (i = 0; i < agg_data->num_zfcpdd - 1; ++i) agg_data->zfcpdd_aggr[i] = tmp[i]; copy_msg(msg, &agg_data->zfcpdd_aggr[i]); free(tmp); } else aggregate_dstat(msg->data, agg_data->zfcpdd_aggr[i]->data); } int add_to_agg(struct aggr_data *agg_data, struct message *msg, const struct file_header *f_hdr) { assert(agg_data->magic == DATA_MGR_MAGIC_AGGR); conv_msg_data_from_BE(msg, f_hdr); if (msg->type == f_hdr->msgid_utilization) { if (agg_data->util_aggr) aggregate_utilization_data(msg->data, agg_data->util_aggr->data); else copy_msg(msg, &agg_data->util_aggr); } else if (msg->type == f_hdr->msgid_ioerr) { if (agg_data->ioerr_aggr) aggregate_ioerr_data(msg->data, agg_data->ioerr_aggr->data); else copy_msg(msg, &agg_data->ioerr_aggr); } else if (msg->type == f_hdr->msgid_blkiomon) aggregate_blkiomon(agg_data, msg); else if (msg->type == f_hdr->msgid_zfcpdd) aggregate_zfcpdd(agg_data, msg); else { fprintf(stderr, "%s: Unknown msg id: %d," " discarding\n", toolname, msg->type); return -1; } agg_data->end_time = get_timestamp_from_msg(msg); if (agg_data->begin_time == 0) agg_data->begin_time = agg_data->end_time; return 0; }