Skip to content

Commit

Permalink
zname & zhypinfo: Add initial versions
Browse files Browse the repository at this point in the history
Adding two new commands zname and zhypinfo to print information about
IBM Z hardware and virtualization layers respectively.
The commands are being held rather simple and basic to have a fast start.
Future extensions will be based on user feedback.
zname might replace some of the tools distributors came up with on their
own, while zhypinfo was actively asked for in a discussion on the Marist
mailing list.

Signed-off-by: Stefan Raspl <[email protected]>
  • Loading branch information
Stefan Raspl committed Nov 25, 2020
1 parent a135780 commit 67bf5ac
Show file tree
Hide file tree
Showing 12 changed files with 605 additions and 17 deletions.
17 changes: 16 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ DOC = $(call cmd," DOC ",$@)doxygen
TAR = $(call cmd," TAR ",$@)tar
GEN = $(call cmd," GEN ",$@)grep

all: libqc.a libqc.so.$(VERSION) qc_test qc_test-sh
INSTALL_FLAGS_BIN = -g $(GROUP) -o $(OWNER) -m755
INSTALL_FLAGS_MAN = -g $(GROUP) -o $(OWNER) -m644
INSTALL_FLAGS_LIB = -g $(GROUP) -o $(OWNER) -m755

all: libqc.a libqc.so.$(VERSION) qc_test qc_test-sh zname zhypinfo

hcpinfbk_qclib.h: hcpinfbk.h
$(GEN) -ve "^#pragma " $< > $@ # strip off z/VM specific pragmas
Expand All @@ -43,6 +47,12 @@ libqc.so.$(VERSION): $(OBJECTS)
-rm libqc.so.$(VERM) 2>/dev/null
ln -s libqc.so.$(VERSION) libqc.so.$(VERM)

zname: zname.c zhypinfo.h libqc.so.$(VERSION)
$(CC) $(CFLAGS) -L. $< -o $@ libqc.so.$(VERSION)

zhypinfo: zhypinfo.c zhypinfo.h libqc.so.$(VERSION)
$(CC) $(CFLAGS) -L. $< -o $@ libqc.so.$(VERSION)

qc_test: qc_test.c libqc.a
$(CC) $(CFLAGS) -static $< -L. -lqc -o $@

Expand Down Expand Up @@ -70,6 +80,10 @@ install: libqc.a libqc.so.$(VERSION)
install -Dm 755 libqc.so.$(VERSION) $(DESTDIR)/usr/lib64/libqc.so.$(VERSION)
ln -sr $(DESTDIR)/usr/lib64/libqc.so.$(VERSION) $(DESTDIR)/usr/lib64/libqc.so.$(VERM)
ln -sr $(DESTDIR)/usr/lib64/libqc.so.$(VERSION) $(DESTDIR)/usr/lib64/libqc.so
install -Dm 755 zname $(DESTDIR)/usr/bin/zname
install -Dm 755 zhypinfo $(DESTDIR)/usr/bin/zhypinfo
install -Dm 644 zname.8 $(DESTDIR)/usr/share/man8/zname.8
install -Dm 644 zhypinfo.8 $(DESTDIR)/usr/share/man8/zhypinfo.8
install -Dm 644 query_capacity.h $(DESTDIR)/usr/include/query_capacity.h
install -Dm 644 README $(DESTDIR)/$(DOCDIR)/qclib/README
install -Dm 644 LICENSE $(DESTDIR)/$(DOCDIR)/qclib/LICENSE
Expand All @@ -86,3 +100,4 @@ clean:
echo " CLEAN"
rm -f $(OBJECTS) libqc.a libqc.so.$(VERSION) qc_test qc_test-sh hcpinfbk_qclib.h
rm -rf html libqc.so.$(VERM)
rm -rf zname zhypinfo
3 changes: 3 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,11 @@ Release History:

2.1.x (tbd)
Changes:
- Add new tools zname and zhypinfo

Bug fixes:
- KVM hosts in mixed mode LPARs indicated both, CPs and IFLs, while only
CPs are actually used

2.1.0 (2020-04-20)
Changes:
Expand Down
6 changes: 3 additions & 3 deletions qc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -872,17 +872,17 @@ int get_handle(void **hdl, int *layers, int quiet) {
*hdl = qc_open(&rc);
if (rc < 0) {
if (!quiet)
printf("Error: Could not open configuration, rc=%d\n", rc);
printf("Error: Could not open capacity data, rc=%d\n", rc);
return 1;
}
if (rc > 0) {
if (!quiet)
printf("Warning: Configuration could not be opened completely, rc=%d\n", rc);
printf("Warning: Capacity data inconsistent, try again later (rc=%d)\n", rc);
return 2;
}
if (!*hdl) {
if (!quiet)
printf("Error: Could not open configuration\n");
printf("Error: Capacity data returned invalid handle, rc=%d\n", rc);
return 3;
}
*layers = qc_get_num_layers(*hdl, &rc);
Expand Down
60 changes: 51 additions & 9 deletions query_capacity.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright IBM Corp. 2013, 2019 */
/* Copyright IBM Corp. 2013, 2020 */

#define _GNU_SOURCE

Expand Down Expand Up @@ -629,7 +629,7 @@ static int qc_post_process_LPAR(struct qc_handle *hdl) {

static int qc_post_process_KVM_host(struct qc_handle *hdl) {
struct qc_handle *parent = qc_get_prev_handle(hdl);
int *num_conf, rc;
int *num_conf, rc, *cps, *ifls;

qc_debug(hdl, "Fill KVM host layer\n");
qc_debug_indent_inc();
Expand All @@ -647,13 +647,25 @@ static int qc_post_process_KVM_host(struct qc_handle *hdl) {
num_conf = qc_get_attr_value_int(parent, qc_num_core_configured);
if (!num_conf)
num_conf = qc_get_attr_value_int(parent, qc_num_cpu_configured);
rc |= !num_conf ||
qc_set_attr_int(hdl, qc_num_core_total, *num_conf, ATTR_SRC_POSTPROC) ||
qc_copy_attr_value_rename(hdl, qc_num_core_dedicated, parent, qc_num_cpu_dedicated) ||
qc_copy_attr_value_rename(hdl, qc_num_core_shared, parent, qc_num_cpu_shared) ||
qc_copy_attr_value(hdl, parent, qc_num_ifl_total) ||
qc_copy_attr_value(hdl, parent, qc_num_ifl_dedicated) ||
qc_copy_attr_value(hdl, parent, qc_num_ifl_shared);
if (!num_conf)
rc = 1;
if (!rc) {
rc |= qc_set_attr_int(hdl, qc_num_core_total, *num_conf, ATTR_SRC_POSTPROC) ||
qc_copy_attr_value_rename(hdl, qc_num_core_dedicated, parent, qc_num_cpu_dedicated) ||
qc_copy_attr_value_rename(hdl, qc_num_core_shared, parent, qc_num_cpu_shared);
cps = qc_get_attr_value_int(parent, qc_num_cp_total);
ifls = qc_get_attr_value_int(parent, qc_num_cp_total);
if (cps && ifls && *cps && *ifls) {
// mixed-mode LPARs use CPs only!
rc |= qc_set_attr_int(hdl, qc_num_ifl_total, 0, ATTR_SRC_POSTPROC) ||
qc_set_attr_int(hdl, qc_num_ifl_dedicated, 0, ATTR_SRC_POSTPROC) ||
qc_set_attr_int(hdl, qc_num_ifl_shared, 0, ATTR_SRC_POSTPROC);
} else {
rc |= qc_copy_attr_value(hdl, parent, qc_num_ifl_total) ||
qc_copy_attr_value(hdl, parent, qc_num_ifl_dedicated) ||
qc_copy_attr_value(hdl, parent, qc_num_ifl_shared);
}
}

qc_debug_indent_dec();

Expand Down Expand Up @@ -1032,3 +1044,33 @@ int qc_get_attribute_float(void *cfg, enum qc_attr_id id, int layer, float *valu

return rc;
}

static void qc_start_object(int *jindent, int layer) {
printf("%*s\"Layer %d\": {\n", *jindent, "", layer);
*jindent += 2;
}
static void qc_end_object(int *jindent, int final) {
*jindent -= 2;
printf("%*s}%s\n", *jindent, "", (final ? "" : ","));
}

void qc_export_json(void *cfg) {
struct qc_handle *hdl = (struct qc_handle *)cfg;
int jindent = 0; // indent for json output
int i;

if (!hdl)
return;

printf("{\n");
jindent += 2;
for (hdl = hdl->root, i = 0; hdl != NULL; hdl = hdl->next, i++) {
qc_start_object(&jindent, i);
qc_print_attrs_json(hdl, jindent);
qc_end_object(&jindent, hdl->next == NULL);
}

printf("}\n");

return;
}
12 changes: 9 additions & 3 deletions query_capacity.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ int qc_get_num_layers(void *hdl, int *rc);
* - 1: LPAR layer information, etc.
* @param value Return parameter returning the string attribute's value or NULL
* in case of an error.
@return Indicating validity of the queried attribute as follows:
* @return Indicating validity of the queried attribute as follows:
* - >0 attribute is valid
* - 0 attribute exists but is not set
* - <0 an error occurred retrieving the attribute
Expand All @@ -739,7 +739,7 @@ int qc_get_attribute_string(void *hdl, enum qc_attr_id id, int layer, const char
* - 1: LPAR layer information, etc.
* @param value Return parameter returning the string attribute's value or undefined
* in case of an error.
@return Indicating validity of the queried attribute as follows:
* @return Indicating validity of the queried attribute as follows:
* - >0 attribute is valid
* - 0 attribute exists but is not set
* - <0 an error occurred retrieving the attribute
Expand All @@ -762,11 +762,17 @@ int qc_get_attribute_int(void *hdl, enum qc_attr_id id, int layer, int *value);
* - 1: LPAR layer information, etc.
* @param value Return parameter returning the float attribute's value or undefined
* in case of an error.indicating validity as follows:
@return Indicating validity of the queried attribute as follows:
* @return Indicating validity of the queried attribute as follows:
* - >0 attribute is valid
* - 0 attribute exists but is not set
* - <0 an error occurred retrieving the attribute
*/
int qc_get_attribute_float(void *hdl, enum qc_attr_id id, int layer, float *value);

/**
* Prints the internal data in JSON format to stdout.
* @param hdl Handle of the configuration to use.
*/
void qc_export_json(void *hdl);

#endif
26 changes: 25 additions & 1 deletion query_capacity_data.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright IBM Corp. 2013, 2019 */
/* Copyright IBM Corp. 2013, 2020 */

#include "query_capacity_data.h"

Expand Down Expand Up @@ -1168,3 +1168,27 @@ char qc_get_attr_value_src_float(struct qc_handle *hdl, enum qc_attr_id id) {
char qc_get_attr_value_src_string(struct qc_handle *hdl, enum qc_attr_id id) {
return qc_get_attr_value_src(hdl, id, string);
}

void qc_print_attrs_json(struct qc_handle *hdl, int indent) {
struct qc_attr *attr;
void *val;

for (attr = hdl->attr_list; attr->offset >= 0; attr++) {
if ((val = qc_get_attr_value(hdl, attr->id, attr->type)) == NULL)
printf("%*s\"%s\": null", indent, "", qc_attr_id_to_char(hdl, attr->id));
else {
switch (attr->type) {
case integer:
printf("%*s\"%s\": \"%d\"", indent, "", qc_attr_id_to_char(hdl, attr->id), *(int*)val);
break;
case floatingpoint:
printf("%*s\"%s\": \"%f\"", indent, "", qc_attr_id_to_char(hdl, attr->id), *(float*)val);
break;
case string:
printf("%*s\"%s\": \"%s\"", indent, "", qc_attr_id_to_char(hdl, attr->id), (char*)val);
break;
}
}
printf("%s\n", (attr + 1)->offset >= 0 ? "," : "");
}
}
3 changes: 3 additions & 0 deletions query_capacity_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ char *qc_get_attr_value_string(struct qc_handle *hdl, enum qc_attr_id id);
char qc_get_attr_value_src_int(struct qc_handle *hdl, enum qc_attr_id id);
char qc_get_attr_value_src_float(struct qc_handle *hdl, enum qc_attr_id id);
char qc_get_attr_value_src_string(struct qc_handle *hdl, enum qc_attr_id id);

// print all attributes in the list in json format
void qc_print_attrs_json(struct qc_handle *hdl, int indent);
#endif
70 changes: 70 additions & 0 deletions zhypinfo.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.\" Copyright IBM Corp. 2020
.\" ----------------------------------------------------------------------

.TH ZHYPINFO 8 "September 2020" "qclib" "System Administration Commands"

.SH NAME
zhypinfo \- Print information about virtualization layers on IBM Z.

.SH SYNOPSIS

.B zhypinfo [OPTION]

.SH Description
.B zhypinfo
prints information about virtualization layers on IBM Z in a
tabular format.
.P
.B Notes
.IP \[bu] 2
Not all information might be available, and unavailable
data is indicated by a dash '-'.
.IP \[bu]
Some environments might map certain CPU types to CPUs of other
types, including specialty engines.
.IP \[bu]
CPU Pools can define fractions of logical CPUs.


.SH OUTPUT
.SS "#"
Index number of the respective layer.
.SS "Layer_Type"
Type of virtualization layer.
.SS "Lvl"
Virtualization level, where each layer of category 'HOST' constitutes a
new level.
.SS "Categ"
Cathegory the virtualization layer belongs to.
.SS "Name"
Name of the respective entity.
.SS "IFLs"
Number of logical IFLs defined for the layer.
.SS "CPs"
Number of logical CPs defined for the layer.
.SS "Total"
Sum of logical CPUs in the layer.


.SH OPTIONS
.TP
.BR "\-h, \-\-help"
Print usage information and exit.
.TP
.BR "\-j, \-\-json"
Dump all available data in JSON format. Known limitation: No character set
conversion or proper escaping is performed.
.TP
.BR "\-l, \-\-layers"
Print number of layers.
.TP
.BR "\-L, \-\-levels"
Print number of virtualization levels.

.SH RETURN CODES
Successful \fBzhypinfo\fR commands return 0.
If an error occurs, \fBzhypinfo\fR writes a message to stderr and
completes with a return code other than 0.
.P
.SH SEE ALSO
.BR zname (8)
Loading

0 comments on commit 67bf5ac

Please sign in to comment.