Files
s390-tools/zconf/chp/chpstat/cmg.c
Peter Oberparleiter cb77faeae7 chpstat: add tool to display channel-path statistics
Add a new tool named chpstat that can be used to view channel-path
statistics such as utilization and I/O throughput, and to query and
control the status of the channel-path statistics function.

Note: Channel-path statistics are only available on systems running in
      an LPAR or DPM partition.

When run without further options, data for all channel-paths is
displayed repeatedly with a 5 second delay in table format.

Example output:

      CHANNEL-PATH       UTILIZATION(%)   READ(B/s)  WRITE(B/s)
  ID TYP CMG SHR SPEED  PART TOTAL  BUS  PART TOTAL  PART TOTAL
  1d  25   2   1     -  7.16  7.50 7.50  129M  129M  0.00  161K
  21  1b   2   1   32G  0.00  0.00 0.00  0.00  0.00  0.00  0.00
  34  1b   2   1   32G  0.00  0.00 0.00  0.00  0.00  0.00  0.00
  61  25   2   1     -  0.00  0.01 0.00  0.00 2.00K  0.00  307K
  63  25   2   1     -  0.00  0.01 0.00  0.00  0.00  0.00  381K
  bd  11   2   1   10G     -     -    - 529.8 532.1 616.3 616.3

Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-05-27 16:52:27 +02:00

102 lines
1.8 KiB
C

/*
* Registry for CMG types
*
* Copyright IBM Corp. 2024
*
* 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 <err.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "cmg.h"
#include "misc.h"
#include "lib/util_libc.h"
static struct cmg_t **cmgs;
static unsigned int num_cmgs;
/* Register new CMG-object @cmg. */
void cmg_add(struct cmg_t *cmg)
{
unsigned int i;
for (i = 0; i < num_cmgs; i++) {
if (cmgs[i]->cmg == cmg->cmg)
errx(EXIT_RUNTIME, "Internal error: CMG %d registered "
"multiple times", cmg->cmg);
}
util_expand_array(&cmgs, &num_cmgs);
cmgs[num_cmgs - 1] = cmg;
}
void cmg_exit(void)
{
free(cmgs);
}
/* Return CMG-object for @cmg. */
struct cmg_t *cmg_get(int cmg)
{
unsigned int i;
for (i = 0; i < num_cmgs; i++) {
if (cmg == cmgs[i]->cmg)
return cmgs[i];
}
return NULL;
}
struct cmg_t *_cmg_get_by_index(unsigned int i)
{
return (i < num_cmgs) ? cmgs[i] : NULL;
}
void cmg_free_keys(char **keys)
{
int i;
if (!keys)
return;
for (i = 0; keys[i]; i++)
free(keys[i]);
free(keys);
}
void cmg_free_pairs(struct cmg_pair_t *pairs)
{
int i;
if (!pairs)
return;
for (i = 0; pairs[i].key; i++)
free(pairs[i].key);
free(pairs);
}
char **cmg_get_keys(struct cmg_t *cmg, int groups)
{
struct cmg_pair_t *pairs;
struct cmg_data_t data;
char **keys = NULL;
unsigned int i, num = 0;
/* Get key-value pairs for dummy data. */
memset(&data, 0, sizeof(data));
pairs = cmg->get_values(&data, groups);
/* Convert pair array to key array. */
for (i = 0; pairs[i].key; i++)
util_add_array(&keys, &num, util_strdup(pairs[i].key));
util_add_array(&keys, &num, NULL);
cmg_free_pairs(pairs);
return keys;
}