Hello community, here is the log from the commit of package qclib for openSUSE:Factory checked in at 2017-12-13 11:55:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qclib (Old) and /work/SRC/openSUSE:Factory/.qclib.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qclib" Wed Dec 13 11:55:45 2017 rev:3 rq:555781 version:1.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/qclib/qclib.changes 2017-12-06 08:53:44.087646993 +0100 +++ /work/SRC/openSUSE:Factory/.qclib.new/qclib.changes 2017-12-13 11:55:47.272152916 +0100 @@ -1,0 +2,5 @@ +Fri Dec 8 22:07:04 UTC 2017 - [email protected] + +- Added qclib-sles15-fix-mismatch-case-with-STHYI.patch (bsc#1071687). + +------------------------------------------------------------------- New: ---- qclib-sles15-fix-mismatch-case-with-STHYI.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qclib.spec ++++++ --- /var/tmp/diff_new_pack.34mkCs/_old 2017-12-13 11:55:48.432096921 +0100 +++ /var/tmp/diff_new_pack.34mkCs/_new 2017-12-13 11:55:48.432096921 +0100 @@ -26,6 +26,7 @@ Source: %{name}-%{version}.tgz Source1: %{name}-rpmlintrc Patch1: qclib.makefile.libdir.patch +Patch2: qclib-sles15-fix-mismatch-case-with-STHYI.patch BuildRequires: doxygen BuildRequires: gcc-c++ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -96,6 +97,7 @@ %prep %setup -q %patch1 -p1 +%patch2 -p1 %build MYCFLAGS=$(grep ^CFLAGS Makefile | cut -f2 -d=) ++++++ qclib-sles15-fix-mismatch-case-with-STHYI.patch ++++++ commit 13d7aafb0cb8946880abbb73725b0340bec1cd3a Author: Stefan Raspl <[email protected]> Date: Fri Dec 8 22:11:29 2017 +0100 STHYI: Fix mismatch case with STHYI and /proc/sysinfo data Reported via Bz162324. Symptom was that qclib wouldn't work on a z/VM 5.4. Analysis revealed that although the STHYI instruction wasn't available, the newly added STHYI syscall would work, but (as intended) reported only layers up to LPAR. In contrast, /proc/sysinfo would report all layers, including the z/VM layer. Some detection logic kicked in and reported an error. The problem was rooted in a bizarr combination of multiple glitches: * An (unnecessary) extra handling for z/VM that was previously added would raise an error on mismatching layer counts in STHYI and /proc/sysinfo. This was to detect cases with more than 3 levels of nested virtualization. But the check just was for mismatching counts and didn't check for the 3 layers reported by STHYI at all. * Furthermore, the check mentioned above was unnecessary to begin with: When STHYI reports data for 3 VM layers, and /proc/sysinfo for more, then the extra layers will simply not get any data from STHYI - no harm done. * STHYI in KVM worked like a charm ever since, though it is supposed to fail with the same error as z/VM since STHYI in KVM (and likewise the syscall in LPARs) cannot report data beyond the LPAR layer - it should result in the same mismatch that z/VM experienced. However, the respective routines would only ever consider VM layers in z/VM and ignore the ones in KVM! Hence all layers beyond LPAR wouldn't be accounted for on KVM! To fix, we're ripping out the extra check, and rewrite the remaining code to handle z/VM and KVM alike. Furthermore, we rename "STHYI@VM" to "STHYI instruction", and "STHYI@LPAR" to "STHYI syscall" for improved clarity. diff --git a/query_capacity_sthyi.c b/query_capacity_sthyi.c index b3bd9e8..688062f 100644 --- a/query_capacity_sthyi.c +++ b/query_capacity_sthyi.c @@ -91,16 +91,16 @@ static int qc_sthyi_lpar(struct qc_handle *hdl, struct sthyi_priv *priv) { #ifdef __NR_s390_sthyi sthyi = __NR_s390_sthyi #endif - qc_debug(hdl, "Try STHYI@LPAR\n"); + qc_debug(hdl, "Try STHYI syscall\n"); if (syscall(sthyi, 0, priv->data, &cc, 0) || cc) { if (errno == ENOSYS) { - qc_debug(hdl, "STHYI@LPAR is not available\n"); + qc_debug(hdl, "STHYI syscall is not available\n"); return 0; } - qc_debug(hdl, "Error: STHYI@LPAR execution failed: errno='%s', cc=%" PRIu64 "\n", strerror(errno), cc); + qc_debug(hdl, "Error: STHYI syscall execution failed: errno='%s', cc=%" PRIu64 "\n", strerror(errno), cc); return -1; } - qc_debug(hdl, "STHYI@LPAR succeeded\n"); + qc_debug(hdl, "STHYI syscall succeeded\n"); priv->avail = STHYI_AVAILABLE; #endif @@ -281,25 +281,15 @@ static int qc_parse_sthyi_guest(struct qc_handle *gst, struct inf0gst *guest) { return 0; } -static int qc_get_num_vm_layers(struct qc_handle *hdl, int *rc) { - int i; - - for (hdl = hdl->root, i = 0; hdl != NULL; hdl = hdl->next) { - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR) - i++; - } - - return i; -} - /* Returns pointer to the n-th hypervisor handle. num starts at 0, and handles are returned in sequence from handle linked list */ static struct qc_handle *qc_get_HV_layer(struct qc_handle *hdl, int num) { struct qc_handle *h = hdl; - int i; + int i, type; for (hdl = hdl->root, i = 0, num++; hdl != NULL; hdl = hdl->next) { - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR && ++i == num) + type = *(int *)(hdl->layer); + if ((type == QC_LAYER_TYPE_ZVM_HYPERVISOR || type == QC_LAYER_TYPE_KVM_HYPERVISOR) && ++i == num) return hdl; } qc_debug(h, "Error: Couldn't find HV layer %d, only %d layer(s) found\n", num, i); @@ -309,7 +299,7 @@ static struct qc_handle *qc_get_HV_layer(struct qc_handle *hdl, int num) { static int qc_sthyi_process(struct qc_handle *hdl, char *buf) { struct sthyi_priv *priv = (struct sthyi_priv *)buf; - int no_hyp_gst, num_vm_layers, i, rc = 0; + int no_hyp_gst, i, rc = 0; struct inf0gst *guest[INF0YGMX]; struct inf0hyp *hv[INF0YGMX]; struct inf0par *partition; @@ -371,30 +361,14 @@ static int qc_sthyi_process(struct qc_handle *hdl, char *buf) { goto out; } - num_vm_layers = qc_get_num_vm_layers(hdl, &rc); - if (rc != 0) { - rc = -2; - goto out; - } - - if (num_vm_layers != no_hyp_gst) { - /* STHYI doesn't support more than 3rd level z/VM */ - qc_debug(hdl, "Error: /proc/sysinfo reported %d layers, but STHYI only " - "covers %d\n", num_vm_layers, no_hyp_gst); - rc = -6; - goto out; - } - for (i = 0; i < no_hyp_gst; i++) { if ((hdl = qc_get_HV_layer(hdl, i)) == NULL) { rc = -7; goto out; } - if (*(int *)(hdl->layer) == QC_LAYER_TYPE_ZVM_HYPERVISOR) { - if (qc_parse_sthyi_hypervisor(hdl, hv[i]) || qc_parse_sthyi_guest(hdl->next, guest[i])) { - rc = -9; - goto out; - } + if (qc_parse_sthyi_hypervisor(hdl, hv[i]) || qc_parse_sthyi_guest(hdl->next, guest[i])) { + rc = -9; + goto out; } } out: @@ -508,15 +482,15 @@ static int qc_sthyi_open(struct qc_handle *hdl, char **buf) { /* There is no way for us to check programmatically whether we're in an LPAR or in a VM, so we simply try out both */ if (qc_is_sthyi_available_vm(hdl)) { - qc_debug(hdl, "Executing STHYI@VM\n"); + qc_debug(hdl, "Executing STHYI instruction\n"); /* we assume we are not relocated at this spot, between STFLE and STHYI */ if (qc_sthyi_vm(priv)) { - qc_debug(hdl, "Error: STHYI@VM execution failed\n"); + qc_debug(hdl, "Error: STHYI instruction execution failed\n"); rc = -3; goto out; } } else { - qc_debug(hdl, "STHYI@VM is not available\n"); + qc_debug(hdl, "STHYI instruction is not available\n"); rc = qc_sthyi_lpar(hdl, priv); } }
