mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
This commit is based on the s390-tools-1.39.0 version. Changes on top of s390-tools-1.39.0: - Add MIT license to all source files - Add LICENSE file - Transform REAMDE to README.md (markdown) - Add AUTHORS.md file - Add CONTRIBUTING.md file - Move changelog from README to CHANGELOG.md file Reviewed-by: Stefan Haberland <sth@linux.vnet.ibm.com> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
235 lines
7.3 KiB
C
235 lines
7.3 KiB
C
/*
|
|
* FCP adapter trace utility
|
|
*
|
|
* Data access library
|
|
*
|
|
* 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 <linux/types.h>
|
|
#include <stdio.h>
|
|
|
|
#ifndef ZIOMON_DACC_H
|
|
#define ZIOMON_DACC_H
|
|
|
|
|
|
|
|
#define DATA_MGR_MAGIC 0x64616d67
|
|
#define DATA_MGR_MAGIC_AGGR 0x61676772
|
|
#define DATA_MGR_V2 2u
|
|
#define DATA_MGR_V3 3u
|
|
|
|
|
|
/**
|
|
* Library to access the data files.
|
|
* Does not perform any endianness conversions.
|
|
* Assumes that messages are provided in BE.
|
|
*/
|
|
|
|
|
|
/**
|
|
* Message as handled by this library.
|
|
* NOTE: The very first entry of the data member _must_ be
|
|
* a timestamp of type __u64!!!
|
|
*/
|
|
struct message {
|
|
__u32 length; /* length of the message,
|
|
excluding the 'length' and 'type' attributes.
|
|
Or, in other word, length of 'data' */
|
|
__u32 type;
|
|
void *data;
|
|
} __attribute__ ((packed));
|
|
|
|
/**
|
|
* Preview version of a message. Has timestamp included,
|
|
* but not the actual content.
|
|
*/
|
|
struct message_preview {
|
|
__u32 length; /* length of the message in Bytes,
|
|
excluding the 'length' and 'type' attributes.
|
|
Or, in other word, length of 'data' */
|
|
__u32 type;
|
|
__u64 timestamp;
|
|
__u32 is_blkiomon_v2; /* message is a v2 blkiomon msg */
|
|
long pos; /* position in file where msg starts */
|
|
};
|
|
|
|
#define DACC_FILE_EXT_LOG ".log"
|
|
struct file_header {
|
|
__u32 magic;
|
|
__u32 version;
|
|
__u64 size_limit;
|
|
__u64 end_time; /* AUTOSET
|
|
timestamp of last message,
|
|
set automatically by API */
|
|
__u64 first_msg_offset; /* AUTOSET
|
|
offset of first message. 0 if all
|
|
messages in sequence, fseek-able offset otherwise.
|
|
Set automatically by API. */
|
|
__u32 interval_length;
|
|
/* In case you wonder why the msg-ids are dynamic at all:
|
|
blkiomon was/is an external tool, which would not have been accepted
|
|
with a fixed msg-id. So since the blkiomon msg id is dynamic, everyone
|
|
has to do it dynamic. We *could* have used the wrapper-script ziomon
|
|
to assign a fixed msg-id for blkiomon, but went all the way instead.
|
|
*/
|
|
__u32 msgid_utilization;
|
|
__u32 msgid_ioerr;
|
|
__u32 msgid_blkiomon;
|
|
__u32 msgid_zfcpdd;
|
|
|
|
/* NOT WRITTEN TO DISK!!! */
|
|
/* Since we might move messages from .log to .agg in a round-robin
|
|
* fashion, it is not trivial to get the timestamp of the first message
|
|
* in .log - each time we write a new message, we would have to read
|
|
* the next one and rewind again.
|
|
* Hence we figure this one out only when we open a finished .log file,
|
|
* but do not actually write it to disk.
|
|
*/
|
|
__u64 begin_time;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
#define DACC_AGGR_FILE_HDR_LEN 40
|
|
#define DACC_FILE_EXT_AGG ".agg"
|
|
struct aggr_data {
|
|
__u32 magic;
|
|
__u32 version;
|
|
__u64 begin_time; /* start time of aggregated data */
|
|
__u64 end_time; /* timestamp of latest message */
|
|
__u64 num_zfcpdd; /* number of zfcpdd messages */
|
|
__u64 num_blkiomon; /* number of blkiomon messages */
|
|
struct message *util_aggr;
|
|
struct message **blkio_aggr;
|
|
struct message *ioerr_aggr;
|
|
struct message **zfcpdd_aggr; /* multiple msgs */
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/**
|
|
* Write the initial file header and forward to place where first message would
|
|
* go init_size gives the total size of the header block in the file.
|
|
* fp is assumed to have been opened.
|
|
*/
|
|
int init_file(FILE *fp, struct file_header *f_hdr, long version);
|
|
|
|
|
|
/**
|
|
* Open an existing .log file and read its header.
|
|
* Returns <0 in case of error, >0 if file doesn't exist.
|
|
* 'filename' is assumed to NOT carry the .log extension.
|
|
* ONLY USE IF YOU KNOW WHAT YOU DO, i.e. in case you want to access
|
|
* the as-is data. Anyone else should rather use open_data().
|
|
* NOTE: Use close_log_file() when finished! */
|
|
int open_log_file(FILE **fp, const char *filename, struct file_header *fhdr);
|
|
|
|
|
|
/**
|
|
* Must be called to close fp and reset internals */
|
|
void close_log_file(FILE *fp);
|
|
|
|
/**
|
|
* Open the data files. This function will not only open the .log and .agg
|
|
* files, but also
|
|
* - read and aggregate the first few messages from .log in case they are
|
|
* missing in the 'agg' data to complete the respective frame.
|
|
* - adjust the boundaries of both, .log and .agg so that .agg has the
|
|
* complete content of the last frame it scratched upon and the next message
|
|
* read from .log will be the first message of the first frame not in .agg
|
|
* Returns <0 in case of error, >0 if file doesn't exist.
|
|
* 'filename' is assumed to NOT carry the .log or .agg extension.
|
|
* Note that, consistent with all other API calls, the messages inside 'agg'
|
|
* are still in BE format!
|
|
* NOTE: Use close_data_files() when finished! */
|
|
int open_data_files(FILE **fp, const char *filename, struct file_header *fhdr,
|
|
struct aggr_data **agg);
|
|
|
|
|
|
/**
|
|
* Must be called to close fp and reset internals */
|
|
void close_data_files(FILE *fp);
|
|
|
|
/**
|
|
* Put a message into the file. Will automatically wrap around.
|
|
* If existing messages have to be deleted to add the new message,
|
|
* the messages that were overwritten are returned via del_msgs and num_del_msgs.
|
|
* del_msgs must be free'd, and the messages within have to be discarded
|
|
* and free'd.
|
|
* via discard_msg()
|
|
* fp is assumed to have been opened.
|
|
*/
|
|
int add_msg(FILE *fp, struct message *msg, struct file_header *f_hdr,
|
|
struct message ***del_msgs, int *num_del_msgs);
|
|
|
|
/**
|
|
* Retrieve the next message from the file. Note that the returned message has
|
|
* to be discarded!
|
|
* Returns 0 if successful, >0 if end of file reached, <0 in case of error.
|
|
* fp is assumed to have been opened.
|
|
*/
|
|
int get_next_msg(FILE *fp, struct message *msg, struct file_header *f_hdr);
|
|
|
|
/**
|
|
* Retrieve preview of next message from the file.
|
|
* Note that fp will be forwarded to the next message!
|
|
* If you want the actual message, use get_complete_msg().
|
|
* If you want to stay at the message, use rewind_to().
|
|
* Returns 0 if successful, >0 if end of file reached, <0 in case of error.
|
|
* fp is assumed to have been opened.
|
|
*/
|
|
int get_next_msg_preview(FILE *fp, struct message_preview *msg,
|
|
struct file_header *f_hdr);
|
|
|
|
/**
|
|
* Rewinds to the start of the provided message preview.
|
|
* Handy in case you could not process the message preview on the
|
|
* first time and want to make sure that you read it again next time. */
|
|
void rewind_to(FILE *fp, struct message_preview *msg);
|
|
|
|
/**
|
|
* Get complete message for a preview. Rewinds back to where it was at.
|
|
*/
|
|
int get_complete_msg(FILE *fp, struct message_preview *msg_prev,
|
|
struct message *msg);
|
|
|
|
/**
|
|
* Frees the alloc'd portion of a message.
|
|
*/
|
|
void discard_msg(struct message *msg);
|
|
|
|
/**
|
|
* Initialize.
|
|
*/
|
|
void init_aggr_data_struct(struct aggr_data *data);
|
|
|
|
/**
|
|
* Open an existing .agg file and read its header.
|
|
* Returns <0 in case of error, >0 if file doesn't exist.
|
|
* 'filename' is assumed to NOT carry the .log extension.
|
|
* ONLY USE IF YOU KNOW WHAT YOU DO, i.e. in case you want to access
|
|
* the as-is data. Anyone else should rather use open_data().
|
|
* NOTE: Use close_agg_file() when finished! */
|
|
int open_agg_file(FILE **fp, const char *filename, struct aggr_data *agg);
|
|
|
|
/**
|
|
* Must be called to close fp and reset internals */
|
|
void close_agg_file(FILE *fp);
|
|
|
|
/**
|
|
* Frees the alloc'd portion of the struct.
|
|
*/
|
|
void discard_aggr_data_struct(struct aggr_data *data);
|
|
|
|
/**
|
|
* Write aggregated data to file.
|
|
* fp is assumed to have been opened.
|
|
*/
|
|
int write_aggr_file(FILE *fp, struct aggr_data *data);
|
|
|
|
|
|
#endif
|
|
|