From b2116c3a40e690798bfb8c26c59dc3fdbd374ddf96dd6b45658399b8ed342425 Mon Sep 17 00:00:00 2001 From: Mark Post Date: Mon, 27 Apr 2020 18:53:16 +0000 Subject: [PATCH] Accepting request 798379 from home:markkp:branches:hardware - Upgraded to version 2.1.0 (bsc#1170410) Changes: - New attributes in support of secure boot in all final layers: * qc_has_secure * qc_secure Note: Changed src column indicator from 'o' to 'F' to summarize firmware-related data - Recognize IBM z15 midrange models Bug fixes: - qc_open(): Memory leaks on errors - Removed obsolete qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch. OBS-URL: https://build.opensuse.org/request/show/798379 OBS-URL: https://build.opensuse.org/package/show/hardware/qclib?expand=0&rev=26 --- ...t-for-secure-boot-related-attributes.patch | 873 ------------------ qclib-2.0.1.tgz | 3 - qclib-2.1.0.tgz | 3 + qclib.changes | 15 + qclib.spec | 3 +- 5 files changed, 19 insertions(+), 878 deletions(-) delete mode 100644 qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch delete mode 100644 qclib-2.0.1.tgz create mode 100644 qclib-2.1.0.tgz diff --git a/qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch b/qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch deleted file mode 100644 index 0265b08..0000000 --- a/qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch +++ /dev/null @@ -1,873 +0,0 @@ -commit 11c01ad586bbf242ab9b929cb3beabb4783da4ee -Author: Stefan Raspl -Date: Sat Feb 22 14:04:12 2020 -0700 - - Add new attributes in support of secure boot in all final layers - - Per a request from SUSE, adding the two attributes that will indicate - whether secure boot is available and in use. SUSE was actually only asking - for one of the attributes, but figured it really makes sense to have both. - Note that we will ever get the values for the final layer, as documented in - the README entry. Otherwise, we would need to have the values provided via - e.g. STHYI for further layers - which is currently not architectured. - Might lead to some confusion, when the topmost layer indicates support, - but the lower layers have no info available. Was thinking about post- - processing the data into lower layers, but that won't work at all: In case - secure boot is available but not set, we cannot know at which of the lower - layers things broke. - - Signed-off-by: Stefan Raspl - -diff --git a/Makefile b/Makefile -index cff31899..376a5a51 100644 ---- a/Makefile -+++ b/Makefile -@@ -7,8 +7,8 @@ VERSION = 2.0.x - VERSION = 2.0.1 - VERM = $(shell echo $(VERSION) | cut -d '.' -f 1) - CFLAGS ?= -g -Wall -O2 --CFILES = query_capacity.c query_capacity_data.c query_capacity_sysinfo.c query_capacity_ocf.c \ -- query_capacity_hypfs.c query_capacity_sthyi.c -+CFILES = query_capacity.c query_capacity_data.c query_capacity_sysinfo.c \ -+ query_capacity_sysfs.c query_capacity_hypfs.c query_capacity_sthyi.c - OBJECTS = $(patsubst %.c,%.o,$(CFILES)) - .SUFFIXES: .o .c - -diff --git a/README b/README -index 2521d604..49d6fec2 100644 ---- a/README -+++ b/README -@@ -27,9 +27,9 @@ by: - Instruction'. - * hypfs file system - for more information, refer to 'Device Drivers, - Features, and Commands', chapter 'S/390 hypervisor file system'. -- * Firmware interface /sys/firmware/ocf - for more information, refer to -- 'Device Drivers, Features, and Commands', chapter 'Identifying the z -- Systems hardware'. -+ * Firmware and other interfaces as made available through sysfs. For more -+ information, refer to 'Device Drivers, Features, and Commands', chapter -+ 'Identifying the z Systems hardware'. - - Please refer to: - http://www.ibm.com/developerworks/linux/linux390/qclib.html -diff --git a/qc_test.c b/qc_test.c -index 8a1db825..a83ae199 100644 ---- a/qc_test.c -+++ b/qc_test.c -@@ -77,6 +77,8 @@ const char *attr2char(enum qc_attr_id id) { - case qc_capping: return "qc_capping"; - case qc_capping_num: return "qc_capping_num"; - case qc_mobility_enabled: return "qc_mobility_enabled"; -+ case qc_has_secure: return "qc_has_secure"; -+ case qc_secure: return "qc_secure"; - case qc_has_multiple_cpu_types: return "qc_has_multiple_cpu_types"; - case qc_cp_dispatch_limithard: return "qc_cp_dispatch_limithard"; - case qc_ifl_dispatch_limithard: return "qc_ifl_dispatch_limithard"; -@@ -476,7 +478,7 @@ void print_cec_information(void *hdl, int layer, int indent) { - print_string_attr(hdl, qc_layer_category, "n/a", layer, indent); - print_int_attr(hdl, qc_layer_type_num, "n/a", layer, indent); - print_int_attr(hdl, qc_layer_category_num, "n/a", layer, indent); -- print_string_attr(hdl, qc_layer_name, "O V", layer, indent); -+ print_string_attr(hdl, qc_layer_name, "F V", layer, indent); - print_string_attr(hdl, qc_manufacturer, "S V", layer, indent); - print_string_attr(hdl, qc_type, "S V", layer, indent); - print_string_attr(hdl, qc_type_name, "S ", layer, indent); -@@ -551,6 +553,8 @@ void print_lpar_information(void *hdl, int layer, int indent) { - print_string_attr(hdl, qc_partition_char, "S ", layer, indent); - print_int_attr(hdl, qc_partition_char_num, "S ", layer, indent); - print_int_attr(hdl, qc_adjustment, "S ", layer, indent); -+ print_int_attr(hdl, qc_has_secure, "F ", layer, indent); -+ print_int_attr(hdl, qc_secure, "F ", layer, indent); - - print_break(); - print_int_attr(hdl, qc_num_core_total, "S ", layer, indent); -@@ -717,6 +721,8 @@ void print_zoszcxserver_information(void *hdl, int layer, int indent) { - print_string_attr(hdl, qc_layer_name, "S V", layer, indent); - print_string_attr(hdl, qc_capping, " H ", layer, indent); - print_int_attr(hdl, qc_capping_num, " H ", layer, indent); -+ print_int_attr(hdl, qc_has_secure, "F ", layer, indent); -+ print_int_attr(hdl, qc_secure, "F ", layer, indent); - - print_break(); - print_int_attr(hdl, qc_num_cpu_total, "S V", layer, indent); -@@ -759,6 +765,9 @@ void print_zvmguest_information(void *hdl, int layer, int indent) { - print_string_attr(hdl, qc_layer_name, "S V", layer, indent); - print_string_attr(hdl, qc_capping, " H ", layer, indent); - print_int_attr(hdl, qc_capping_num, " H ", layer, indent); -+ print_int_attr(hdl, qc_mobility_enabled, " V", layer, indent); -+ print_int_attr(hdl, qc_has_secure, "F ", layer, indent); -+ print_int_attr(hdl, qc_secure, "F ", layer, indent); - - print_break(); - print_int_attr(hdl, qc_num_cpu_total, "S V", layer, indent); -@@ -791,7 +800,6 @@ void print_zvmguest_information(void *hdl, int layer, int indent) { - print_int_attr(hdl, qc_ziip_capped_capacity, " V", layer, indent); - - print_break(); -- print_int_attr(hdl, qc_mobility_enabled, " V", layer, indent); - print_int_attr(hdl, qc_has_multiple_cpu_types, " V", layer, indent); - - // check an attribute that only exists at a different layer -@@ -835,6 +843,8 @@ void print_kvmguest_information(void *hdl, int layer, int indent) { - print_string_attr(hdl, qc_layer_name, "S ", layer, indent); - print_string_attr(hdl, qc_layer_extended_name, "S ", layer, indent); - print_string_attr(hdl, qc_layer_uuid, "S ", layer, indent); -+ print_int_attr(hdl, qc_has_secure, "F ", layer, indent); -+ print_int_attr(hdl, qc_secure, "F ", layer, indent); - - print_break(); - print_int_attr(hdl, qc_num_cpu_total, "S ", layer, indent); -diff --git a/query_capacity.c b/query_capacity.c -index 3a109520..644508da 100644 ---- a/query_capacity.c -+++ b/query_capacity.c -@@ -679,7 +679,8 @@ fail: - - static void *_qc_open(struct qc_handle *hdl, int *rc) { - // sysinfo needs to be handled first, or our LGM check later on will have loopholes -- struct qc_data_src *src, *sources[] = {&sysinfo, &ocf, &hypfs, &sthyi, NULL}; -+ // sysfs needs to be handled last, as part of the attributes apply to top-most layer only -+ struct qc_data_src *src, *sources[] = {&sysinfo, &hypfs, &sthyi, &sysfs, NULL}; - struct qc_handle *lparhdl; - int i; - -@@ -907,7 +908,7 @@ static struct qc_handle *qc_get_layer_handle(void *config, int layer) { - } - - static int qc_is_attr_id_valid(enum qc_attr_id id) { -- return id <= qc_num_ziip_threads; -+ return id <= qc_secure; - } - - int qc_get_attribute_string(void *cfg, enum qc_attr_id id, int layer, const char **value) { -diff --git a/query_capacity.h b/query_capacity.h -index 5786a9b2..69d71d6e 100644 ---- a/query_capacity.h -+++ b/query_capacity.h -@@ -21,7 +21,7 @@ - * what layers. The letter encoding in the '\c Src' column describes how the - * value is gained: - * - **S**: Provided by \c /proc/sysinfo, which is present in all Linux on z flavors. -- * - **O**: Provided by \c /sys/firmware/ocf. Available in Linux kernel 3.0 or higher. -+ * - **F**: Provided by firmware as made available through the \c sysfs filesystem. - * - **H**: Provided by hypfs, which is (preferably) available through \c debugfs at - * \c /sys/kernel/debug/s390_hypfs, or \c s390_hypfs (typically mounted at - * \c /sys/hypervisor/s390). -@@ -86,11 +86,11 @@ - * #qc_layer_category_num | int | | Hardcoded to \c #QC_LAYER_CAT_HOST - * #qc_layer_type |string| | Hardcoded to \c "CEC" - * #qc_layer_category |string| | Hardcoded to \c "HOST" -- * #qc_layer_name |string|O V| CPC name of machine -+ * #qc_layer_name |string|F V| CPC name of machine. Available in Linux kernel 3.0 or higher. - * #qc_manufacturer |string|S V| \n - * #qc_type |string|S V| \n - * #qc_type_name |string|S  | \n -- * #qc_type_family | int |S  | \n -+ * #qc_type_family | int |S  | \n - * #qc_model_capacity |string|S  | \n - * #qc_model |string|S  | \n - * #qc_sequence_code |string|S V| \n -@@ -143,6 +143,8 @@ - * #qc_partition_char |string|S  | \n - * #qc_partition_char_num | int |S  | \n - * #qc_adjustment | int |S  | \n -+ * #qc_has_secure | int |F  | \n -+ * #qc_secure | int |F  | \n - * #qc_num_core_total | int |S| Total number of CPs and IFLs configured in the LPARs activation profile - * #qc_num_core_configured | int |S  | Note: \b [5] - * #qc_num_core_standby | int |S  | Operational cores that require add'l configuration within the LPAR image to become usable
Note: \b [5] -@@ -225,6 +227,9 @@ - * #qc_layer_name |string|S V| Userid of guest - * #qc_capping |string| H| \n - * #qc_capping_num | int | H| \n -+ * #qc_mobility_enabled | int |  V| \n -+ * #qc_has_secure | int |F  | \n -+ * #qc_secure | int |F  | \n - * #qc_num_cpu_total | int |S V| Sum of #qc_num_cpu_configured, #qc_num_cpu_standby and #qc_num_cpu_reserved, or #qc_num_cpu_dedicated and #qc_num_cpu_shared - * #qc_num_cpu_configured | int |S  | \n - * #qc_num_cpu_standby | int |S  | \n -@@ -240,7 +245,6 @@ - * #qc_num_ziip_total | int |  V| Sum of #qc_num_ziip_dedicated and #qc_num_ziip_shared
Reported in unit of CPUs - * #qc_num_ziip_dedicated | int |  V| Reported in unit of CPUs - * #qc_num_ziip_shared | int |  V| Reported in unit of CPUs -- * #qc_mobility_enabled | int |  V| \n - * #qc_has_multiple_cpu_types | int |  V| \n - * #qc_cp_dispatch_limithard | int |  V| \n - * #qc_cp_dispatch_type | int |  V| Only set in presence of CPs -@@ -300,6 +304,8 @@ - * #qc_layer_name |string|S V| Userid of guest - * #qc_capping |string| H| \n - * #qc_capping_num | int | H| \n -+ * #qc_has_secure | int |F  | \n -+ * #qc_secure | int |F  | \n - * #qc_num_cpu_total | int |S V| Sum of #qc_num_cpu_configured, #qc_num_cpu_standby and #qc_num_cpu_reserved, or #qc_num_cpu_dedicated and #qc_num_cpu_shared - * #qc_num_cpu_configured | int |S  | \n - * #qc_num_cpu_standby | int |S  | \n -@@ -349,6 +355,8 @@ - * #qc_layer_name |string|S  | Guest name truncated to 8 characters
Note: \b [1] - * #qc_layer_extended_name |string|S  | Guest name with up to 256 characters
Note: Requires Linux kernel 3.19 or higher, [1] - * #qc_layer_uuid |string|S  | Note: Requires Linux kernel 3.19 or higher -+ * #qc_has_secure | int |F  | \n -+ * #qc_secure | int |F  | \n - * #qc_num_cpu_total | int |S  | Sum of #qc_num_cpu_configured, #qc_num_cpu_standby and #qc_num_cpu_reserved, or #qc_num_cpu_dedicated and #qc_num_cpu_shared - * #qc_num_cpu_configured | int |S  | \n - * #qc_num_cpu_standby | int |S  | \n -@@ -533,6 +541,14 @@ enum qc_attr_id { - /** Deprecated, see #qc_mobility_enabled */ - qc_mobility_eligible = 32, - #endif -+ /** Indicates whether secure boot is available to the entity. -+ Requires Linux kernel 5.3 or later. -+ Note: This attribute is only ever available for the topmost layer. */ -+ qc_has_secure = 77, -+ /** Indicates whether entity was booted using the secure boot feature -+ Requires Linux kernel 5.3 or later. -+ Note: This attribute is only ever available for the topmost layer. */ -+ qc_secure = 78, - /** Model identifier, see \c STSI instruction in [2] */ - qc_model = 33, - /** Model capacity of machine, see \c STSI instruction in [2] */ -diff --git a/query_capacity_data.c b/query_capacity_data.c -index 9147703f..afc2b5f6 100644 ---- a/query_capacity_data.c -+++ b/query_capacity_data.c -@@ -122,6 +122,8 @@ struct qc_lpar { - char layer_extended_name[QC_LEN_LAYER_EXTENDED_NAME]; - char layer_uuid[QC_LEN_LAYER_UUID]; - int adjustment; -+ int has_secure; -+ int secure; - int num_core_total; - int num_core_configured; - int num_core_standby; -@@ -201,6 +203,9 @@ struct qc_zvm_guest { - char layer_name[QC_LEN_LAYER_NAME]; - char capping[QC_LEN_CAPPING]; - int capping_num; -+ int mobility_enabled; -+ int has_secure; -+ int secure; - int num_cpu_total; - int num_cpu_configured; - int num_cpu_standby; -@@ -216,7 +221,6 @@ struct qc_zvm_guest { - int num_ziip_total; - int num_ziip_dedicated; - int num_ziip_shared; -- int mobility_enabled; - int has_multiple_cpu_types; - int cp_dispatch_limithard; - int cp_dispatch_type; -@@ -273,6 +277,8 @@ struct qc_zos_zcx_server { - char layer_name[QC_LEN_LAYER_NAME]; - char capping[QC_LEN_CAPPING]; - int capping_num; -+ int has_secure; -+ int secure; - int num_cpu_total; - int num_cpu_configured; - int num_cpu_standby; -@@ -320,6 +326,8 @@ struct qc_kvm_guest { - char layer_name[QC_LEN_LAYER_NAME]; - char layer_extended_name[QC_LEN_LAYER_EXTENDED_NAME]; - char layer_uuid[QC_LEN_LAYER_UUID]; -+ int has_secure; -+ int secure; - int num_cpu_total; - int num_cpu_configured; - int num_cpu_standby; -@@ -408,6 +416,8 @@ static struct qc_attr lpar_attrs[] = { - {qc_layer_extended_name, string, offsetof(struct qc_lpar, layer_extended_name)}, - {qc_layer_uuid, string, offsetof(struct qc_lpar, layer_uuid)}, - {qc_adjustment, integer, offsetof(struct qc_lpar, adjustment)}, -+ {qc_has_secure, integer, offsetof(struct qc_lpar, has_secure)}, -+ {qc_secure, integer, offsetof(struct qc_lpar, secure)}, - {qc_num_core_total, integer, offsetof(struct qc_lpar, num_core_total)}, - {qc_num_core_configured, integer, offsetof(struct qc_lpar, num_core_configured)}, - {qc_num_core_standby, integer, offsetof(struct qc_lpar, num_core_standby)}, -@@ -547,6 +557,9 @@ static struct qc_attr zvm_guest_attrs[] = { - {qc_layer_name, string, offsetof(struct qc_zvm_guest, layer_name)}, - {qc_capping, string, offsetof(struct qc_zvm_guest, capping)}, - {qc_capping_num, integer, offsetof(struct qc_zvm_guest, capping_num)}, -+ {qc_mobility_enabled, integer, offsetof(struct qc_zvm_guest, mobility_enabled)}, -+ {qc_has_secure, integer, offsetof(struct qc_zvm_guest, has_secure)}, -+ {qc_secure, integer, offsetof(struct qc_zvm_guest, secure)}, - {qc_num_cpu_total, integer, offsetof(struct qc_zvm_guest, num_cpu_total)}, - {qc_num_cpu_configured, integer, offsetof(struct qc_zvm_guest, num_cpu_configured)}, - {qc_num_cpu_standby, integer, offsetof(struct qc_zvm_guest, num_cpu_standby)}, -@@ -562,7 +575,6 @@ static struct qc_attr zvm_guest_attrs[] = { - {qc_num_ziip_total, integer, offsetof(struct qc_zvm_guest, num_ziip_total)}, - {qc_num_ziip_dedicated, integer, offsetof(struct qc_zvm_guest, num_ziip_dedicated)}, - {qc_num_ziip_shared, integer, offsetof(struct qc_zvm_guest, num_ziip_shared)}, -- {qc_mobility_enabled, integer, offsetof(struct qc_zvm_guest, mobility_enabled)}, - {qc_has_multiple_cpu_types, integer, offsetof(struct qc_zvm_guest, has_multiple_cpu_types)}, - {qc_cp_dispatch_limithard, integer, offsetof(struct qc_zvm_guest, cp_dispatch_limithard)}, - {qc_cp_capped_capacity, integer, offsetof(struct qc_zvm_guest, cp_capped_capacity)}, -@@ -584,6 +596,8 @@ static struct qc_attr zos_zcx_server_attrs[] = { - {qc_layer_name, string, offsetof(struct qc_zos_zcx_server, layer_name)}, - {qc_capping, string, offsetof(struct qc_zos_zcx_server, capping)}, - {qc_capping_num, integer, offsetof(struct qc_zos_zcx_server, capping_num)}, -+ {qc_has_secure, integer, offsetof(struct qc_zos_zcx_server, has_secure)}, -+ {qc_secure, integer, offsetof(struct qc_zos_zcx_server, secure)}, - {qc_num_cpu_total, integer, offsetof(struct qc_zos_zcx_server, num_cpu_total)}, - {qc_num_cpu_configured, integer, offsetof(struct qc_zos_zcx_server, num_cpu_configured)}, - {qc_num_cpu_standby, integer, offsetof(struct qc_zos_zcx_server, num_cpu_standby)}, -@@ -614,6 +628,8 @@ static struct qc_attr kvm_guest_attrs[] = { - {qc_layer_name, string, offsetof(struct qc_kvm_guest, layer_name)}, - {qc_layer_extended_name, string, offsetof(struct qc_kvm_guest, layer_extended_name)}, - {qc_layer_uuid, string, offsetof(struct qc_kvm_guest, layer_uuid)}, -+ {qc_has_secure, integer, offsetof(struct qc_kvm_guest, has_secure)}, -+ {qc_secure, integer, offsetof(struct qc_kvm_guest, secure)}, - {qc_num_cpu_total, integer, offsetof(struct qc_kvm_guest, num_cpu_total)}, - {qc_num_cpu_configured, integer, offsetof(struct qc_kvm_guest, num_cpu_configured)}, - {qc_num_cpu_standby, integer, offsetof(struct qc_kvm_guest, num_cpu_standby)}, -@@ -681,6 +697,8 @@ const char *qc_attr_id_to_char(struct qc_handle *hdl, enum qc_attr_id id) { - case qc_capping: return "capping"; - case qc_capping_num: return "capping_num"; - case qc_mobility_enabled: return "mobility_enabled"; -+ case qc_has_secure: return "has_secure"; -+ case qc_secure: return "secure"; - case qc_has_multiple_cpu_types: return "has_multiple_cpu_types"; - case qc_cp_dispatch_limithard: return "cp_dispatch_limithard"; - case qc_ifl_dispatch_limithard: return "ifl_dispatch_limithard"; -@@ -1073,6 +1091,12 @@ struct qc_handle *qc_get_root_handle(struct qc_handle *hdl) { - return hdl ? hdl->root : NULL; - } - -+struct qc_handle *qc_get_top_handle(struct qc_handle *hdl) { -+ for (; hdl->next != NULL; hdl = hdl->next); -+ -+ return hdl; -+} -+ - struct qc_handle *qc_get_prev_handle(struct qc_handle *hdl) { - struct qc_handle *prev_hdl = NULL; - -diff --git a/query_capacity_int.h b/query_capacity_int.h -index 6e11c103..f2109916 100644 ---- a/query_capacity_int.h -+++ b/query_capacity_int.h -@@ -21,7 +21,7 @@ - #define STR_BUF_SIZE 257 - - #define ATTR_SRC_SYSINFO 'S' --#define ATTR_SRC_OCF 'O' -+#define ATTR_SRC_SYSFS 'F' - #define ATTR_SRC_HYPFS 'H' - #define ATTR_SRC_STHYI 'V' - #define ATTR_SRC_POSTPROC 'P' // Note: Post-processed attributes can have multiple origins - would be -@@ -60,7 +60,7 @@ struct qc_data_src { - char *priv; - }; - --extern struct qc_data_src sysinfo, ocf, hypfs, sthyi; -+extern struct qc_data_src sysinfo, sysfs, hypfs, sthyi; - - /* Utility functions */ - int qc_ebcdic_to_ascii(struct qc_handle *hdl, char *inbuf, size_t insz); -@@ -74,6 +74,7 @@ struct qc_handle *qc_get_cec_handle(struct qc_handle *hdl); - struct qc_handle *qc_get_lpar_handle(struct qc_handle *hdl); - struct qc_handle *qc_get_root_handle(struct qc_handle *hdl); - struct qc_handle *qc_get_prev_handle(struct qc_handle *hdl); -+struct qc_handle *qc_get_top_handle(struct qc_handle *hdl); - - /* Debugging-related functions and variables */ - extern long qc_dbg_level; -diff --git a/query_capacity_ocf.c b/query_capacity_ocf.c -deleted file mode 100644 -index 3f5d2a12..00000000 ---- a/query_capacity_ocf.c -+++ /dev/null -@@ -1,135 +0,0 @@ --/* Copyright IBM Corp. 2016 */ -- --#define _GNU_SOURCE --#include --#include --#include -- --#include "query_capacity_data.h" -- -- --#define FILE_CPC_NAME "/sys/firmware/ocf/cpc_name" -- -- --static void qc_ocf_dump(struct qc_handle *hdl, char *data) { -- char *path = NULL; -- FILE *fp; -- int rc; -- -- qc_debug(hdl, "Dump ocf\n"); -- qc_debug_indent_inc(); -- if (!data) -- goto out; -- if (asprintf(&path, "%s/ocf", qc_dbg_dump_dir) == -1) { -- qc_debug(hdl, "Error: Mem alloc failure, cannot dump sysinfo\n"); -- goto out_err; -- } -- if (mkdir(path, 0700) == -1) { -- qc_debug(hdl, "Error: Could not create directory for ocf dump: %s\n", strerror(errno)); -- goto out_err; -- } -- free(path); -- if (asprintf(&path, "%s/ocf/cpc_name", qc_dbg_dump_dir) == -1) { -- qc_debug(hdl, "Error: Mem alloc failure, cannot dump sysinfo\n"); -- goto out_err; -- } -- if ((fp = fopen(path, "w")) == NULL) { -- qc_debug(hdl, "Error: Failed to open %s to write ocf dump\n", path); -- goto out_err; -- } -- rc = fprintf(fp, "%s", data); -- fclose(fp); -- if (rc < 0) { -- qc_debug(hdl, "Error: Failed to write dump to '%s'\n", path); -- goto out_err; -- } -- goto out; -- --out_err: -- qc_mark_dump_incomplete(hdl, "ocf"); --out: -- free(path); -- qc_debug_indent_dec(); -- -- return; --} -- --static int qc_ocf_open(struct qc_handle *hdl, char **data) { -- char *fname = NULL; -- int rc = 0; -- size_t n; -- FILE *fp; -- -- qc_debug(hdl, "Retrieve ocf data\n"); -- qc_debug_indent_inc(); -- *data = NULL; -- if (qc_dbg_use_dump) { -- qc_debug(hdl, "Read ocf from dump\n"); -- if (asprintf(&fname, "%s/ocf/cpc_name", qc_dbg_use_dump) == -1) { -- qc_debug(hdl, "Error: Mem alloc failed, cannot open dump\n"); -- rc = -1; -- goto out; -- } -- } else -- qc_debug(hdl, "Read ocf from " FILE_CPC_NAME "\n"); -- -- if (access(fname ? fname : FILE_CPC_NAME, F_OK)) { -- qc_debug(hdl, "No ocf data available\n"); -- goto out; -- } -- fp = fopen(fname ? fname : FILE_CPC_NAME, "r"); -- if (!fp) { -- qc_debug(hdl, "Error: Failed to open file '%s': %s\n", -- fname ? fname : FILE_CPC_NAME, strerror(errno)); -- rc = -2; -- goto out; -- } -- rc = getline(data, &n, fp); -- fclose(fp); -- if (rc == -1) { -- qc_debug(hdl, "Error: Failed to read content: %s\n", strerror(errno)); -- *data = NULL; -- rc = -3; -- goto out; -- } -- rc = 0; -- if (strcmp(*data, "\n") == 0 || **data == '\0') { -- qc_debug(hdl, FILE_CPC_NAME " contains no data, discarding\n"); -- free(*data); -- *data = NULL; -- goto out; -- } -- --out: -- free(fname); -- qc_debug(hdl, "Done reading ocf data\n"); -- qc_debug_indent_dec(); -- -- return rc; --} -- --static void qc_ocf_close(struct qc_handle *hdl, char *data) { -- free(data); --} -- --static int qc_ocf_process(struct qc_handle *hdl, char *data) { -- qc_debug(hdl, "Process ocf\n"); -- qc_debug_indent_inc(); -- if (!data) { -- qc_debug(hdl, "No ocf data, skipping\n"); -- goto out; -- } -- if (qc_set_attr_string(hdl->root, qc_layer_name, data, ATTR_SRC_OCF)) -- qc_debug(hdl, "Error: Failed to set CEC name to %s\n", data); --out: -- qc_debug_indent_dec(); -- -- return 0; --} -- --struct qc_data_src ocf = {qc_ocf_open, -- qc_ocf_process, -- qc_ocf_dump, -- qc_ocf_close, -- NULL, -- NULL}; -diff --git a/query_capacity_sysfs.c b/query_capacity_sysfs.c -new file mode 100644 -index 00000000..8594d950 ---- /dev/null -+++ b/query_capacity_sysfs.c -@@ -0,0 +1,351 @@ -+/* Copyright IBM Corp. 2020 */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+ -+#include "query_capacity_data.h" -+ -+ -+#define SYSFS_NA 0 -+#define SYSFS_AVAILABLE 1 -+ -+#define FILE_CPC_NAME "/sys/firmware/ocf/cpc_name" -+#define FILE_SEC_IPL_HAS_SEC "/sys/firmware/ipl/has_secure" -+#define FILE_SEC_IPL_SEC "/sys/firmware/ipl/secure" -+ -+static const char *sysfs_dirs[] = {"/sys", -+ "/sys/firmware", -+ "/sys/firmware/ocf", -+ "/sys/firmware/ipl", -+ NULL -+ }; -+ -+struct sysfs_priv { -+ int avail; -+ char *cpc_name; // NULL if n/a -+ int has_secure; // <0 if n/a -+ int secure; // <0 if n/a -+}; -+ -+static int qc_sysfs_mkpath(struct qc_handle *hdl, const char *a, const char *b, char **path) { -+ free(*path); -+ *path = NULL; -+ -+ if (asprintf(path, "%s/%s", a, b) == -1) { -+ qc_debug(hdl, "Error: Mem alloc failed\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/** Create directory structure that we need for our dumps - if we don't have any content later on, -+ then there simply won't be any files in there */ -+static int qc_sysfs_create_dump_dirs(struct qc_handle *hdl) { -+ char *path = NULL; -+ int rc = -1, i; -+ -+ for (i = 0; sysfs_dirs[i]; ++i) { -+ if (qc_sysfs_mkpath(hdl, qc_dbg_dump_dir, sysfs_dirs[i], &path)) -+ goto out; -+ if (mkdir(path, 0700) == -1) { -+ qc_debug(hdl, "Error: Could not create directory %s for sysfs dump: %s\n", path, strerror(errno)); -+ goto out; -+ } -+ } -+ rc = 0; -+ -+out: -+ free(path); -+ -+ return rc; -+} -+ -+static FILE *qc_sysfs_open_dump_file(struct qc_handle *hdl, const char* file) { -+ char *path = NULL; -+ FILE *fp = NULL; -+ -+ if (qc_sysfs_mkpath(hdl, qc_dbg_dump_dir, file, &path)) -+ goto out; -+ if ((fp = fopen(path, "w")) == NULL) { -+ qc_debug(hdl, "Error: Failed to open '%s' to write sysfs dump\n", path); -+ goto out; -+ } -+ -+out: -+ free(path); -+ -+ return fp; -+} -+ -+static int qc_sysfs_dump_file_char(struct qc_handle *hdl, const char* file, const char *val) { -+ FILE *fp; -+ int rc; -+ -+ if (!val) { -+ qc_debug(hdl, "No data for '%s', skipping\n", file); -+ return 0; -+ } -+ fp = qc_sysfs_open_dump_file(hdl, file); -+ if (!fp) -+ return -1; -+ rc = fprintf(fp, "%s", val); -+ fclose(fp); -+ if (rc < 0) { -+ qc_debug(hdl, "Error: Failed to write dump to '%s'\n", file); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int qc_sysfs_dump_file_int(struct qc_handle *hdl, const char* file, int val) { -+ FILE *fp; -+ int rc; -+ -+ if (val < 0) { -+ qc_debug(hdl, "No data for '%s', skipping\n", file); -+ return 0; -+ } -+ fp = qc_sysfs_open_dump_file(hdl, file); -+ if (!fp) -+ return -1; -+ rc = fprintf(fp, "%d", val); -+ fclose(fp); -+ if (rc < 0) { -+ qc_debug(hdl, "Error: Failed to write dump to '%s'\n", file); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void qc_sysfs_dump(struct qc_handle *hdl, char *data) { -+ struct sysfs_priv *p; -+ -+ qc_debug(hdl, "Dump sysfs\n"); -+ qc_debug_indent_inc(); -+ if (!data) -+ goto out; -+ p = (struct sysfs_priv *)data; -+ if (qc_sysfs_create_dump_dirs(hdl)) { -+ qc_debug(hdl, "Error: Failed to create directory structure\n"); -+ goto out_err; -+ } -+ if (qc_sysfs_dump_file_char(hdl, FILE_CPC_NAME, p->cpc_name) || -+ qc_sysfs_dump_file_int(hdl, FILE_SEC_IPL_HAS_SEC, p->has_secure) || -+ qc_sysfs_dump_file_int(hdl, FILE_SEC_IPL_SEC, p->secure)) -+ goto out_err; -+ qc_debug(hdl, "sysfs data dumped to '%s%s'\n", qc_dbg_dump_dir, *sysfs_dirs); -+ goto out; -+ -+out_err: -+ qc_mark_dump_incomplete(hdl, "sysfs"); -+out: -+ qc_debug_indent_dec(); -+ -+ return; -+} -+ -+static int qc_sysfs_is_old_dump_format(struct qc_handle *hdl) { -+ char *fname = NULL; -+ int rc = -1; -+ -+ if (qc_sysfs_mkpath(hdl, qc_dbg_use_dump, "ocf", &fname)) -+ goto out; -+ if (access(fname, F_OK) == 0) { -+ qc_debug(hdl, "Old ocf-based dump format\n"); -+ rc = 1; -+ goto out; -+ } -+ rc = 0; -+out: -+ free(fname); -+ -+ return rc; -+} -+ -+/** On success, returns 0 on success and filles data with respective file content. -+ Returns >0 if file is not available, and <0 on error. */ -+static int qc_sysfs_get_file_content(struct qc_handle *hdl, char *file, char **content) { -+ FILE *fp = NULL; -+ size_t n; -+ int rc; -+ -+ if (access(file, F_OK)) { -+ qc_debug(hdl, "File '%s' not available\n", file); -+ *content = NULL; -+ return 1; -+ } -+ fp = fopen(file, "r"); -+ if (!fp) { -+ qc_debug(hdl, "Error: Failed to open file '%s': %s\n", file, strerror(errno)); -+ return -1; -+ } -+ rc = getline(content, &n, fp); -+ fclose(fp); -+ if (rc == -1) { -+ qc_debug(hdl, "Error: Failed to read content of '%s': %s\n", file, strerror(errno)); -+ *content = NULL; -+ return -2; -+ } -+ rc = 0; -+ if (strcmp(*content, "\n") == 0 || **content == '\0') { -+ qc_debug(hdl, "'%s' contains no data, discarding\n", file); -+ free(*content); -+ *content = NULL; -+ return 2; -+ } -+ qc_debug(hdl, "Read file %s\n", file); -+ -+ return 0; -+} -+ -+/** Handle numeric attributes */ -+static int qc_sysfs_num_attr(struct qc_handle *hdl, char *file, int *attr) { -+ char *content = NULL; -+ int rc; -+ -+ rc = qc_sysfs_get_file_content(hdl, file, &content); -+ if (rc) { -+ *attr = -1; -+ if (rc > 0) -+ rc = 0; -+ goto out; -+ } -+ *attr = atoi(content); -+ if (*attr < 0) { -+ // we're not prepared to handle negative values (yet) -+ qc_debug(hdl, "Negative content for '%s': %s\n", file, content); -+ rc = -1; -+ } -+ -+out: -+ free(content); -+ -+ return rc; -+} -+ -+static struct sysfs_priv *qc_sysfs_init_data(struct qc_handle *hdl, char **data) { -+ struct sysfs_priv *p; -+ -+ if ((*data = malloc(sizeof(struct sysfs_priv))) == NULL) { -+ qc_debug(hdl, "Error: Failed to allocate private data for sysfs\n"); -+ return NULL; -+ } -+ p = (struct sysfs_priv *)*data; -+ memset(p, 0, sizeof(struct sysfs_priv)); -+ p->avail = SYSFS_NA; -+ p->has_secure = -1; -+ p->secure = -1; -+ -+ return p; -+} -+ -+static int qc_sysfs_open(struct qc_handle *hdl, char **data) { -+ struct sysfs_priv *p; -+ char *path = NULL; -+ int rc = 0, lrc; -+ -+ qc_debug(hdl, "Retrieve sysfs data\n"); -+ qc_debug_indent_inc(); -+ p = qc_sysfs_init_data(hdl, data); -+ if (!p) { -+ rc = -1; -+ goto out; -+ } -+ if (qc_dbg_use_dump) { -+ qc_debug(hdl, "Read sysfs from dump\n"); -+ if (qc_sysfs_is_old_dump_format(hdl)) { -+ // Note: previously, we had a directory called 'ocf' where only one piece of data was -+ // residing. But we have switched over to a more general sys directory instead. -+ qc_debug(hdl, "Old, ocf-based format\n"); -+ if (qc_sysfs_mkpath(hdl, qc_dbg_use_dump, "ocf/cpc_name", &path)) { -+ rc = -1; -+ goto out; -+ } -+ lrc = qc_sysfs_get_file_content(hdl, path, &p->cpc_name); -+ if (lrc != 0) { -+ rc = (lrc < 0 ? -1 : 0); -+ goto out; -+ } -+ p->avail = SYSFS_AVAILABLE; -+ } else { -+ qc_debug(hdl, "New, sysfs-based format\n"); -+ if (qc_sysfs_mkpath(hdl, qc_dbg_use_dump, FILE_CPC_NAME, &path) || -+ qc_sysfs_get_file_content(hdl, path, &p->cpc_name) < 0 || -+ qc_sysfs_mkpath(hdl, qc_dbg_use_dump, FILE_SEC_IPL_HAS_SEC, &path) || -+ qc_sysfs_num_attr(hdl, path, &p->has_secure) || -+ qc_sysfs_mkpath(hdl, qc_dbg_use_dump, FILE_SEC_IPL_SEC, &path) || -+ qc_sysfs_num_attr(hdl, path, &p->secure)) -+ rc = -1; -+ else -+ p->avail = SYSFS_AVAILABLE; -+ } -+ } else { -+ qc_debug(hdl, "Read sysfs from system\n"); -+ if (qc_sysfs_get_file_content(hdl, FILE_CPC_NAME, &p->cpc_name) < 0 || -+ qc_sysfs_num_attr(hdl, FILE_SEC_IPL_HAS_SEC, &p->has_secure) || -+ qc_sysfs_num_attr(hdl, FILE_SEC_IPL_SEC, &p->secure)) -+ rc = -1; -+ else -+ p->avail = SYSFS_AVAILABLE; -+ } -+ -+out: -+ qc_debug(hdl, "Done reading sysfs data\n"); -+ qc_debug_indent_dec(); -+ free(path); -+ -+ return rc; -+} -+ -+static void qc_sysfs_close(struct qc_handle *hdl, char *data) { -+ struct sysfs_priv *p = (struct sysfs_priv *)data; -+ -+ if (p) { -+ free(p->cpc_name); -+ free(data); -+ } -+} -+ -+static int qc_sysfs_process(struct qc_handle *hdl, char *data) { -+ struct sysfs_priv *p = (struct sysfs_priv *)data; -+ int rc = 0; -+ -+ qc_debug(hdl, "Process sysfs\n"); -+ qc_debug_indent_inc(); -+ if (!p) { -+ qc_debug(hdl, "No sysfs data, skipping\n"); -+ goto out; -+ } -+ -+ // Set CEC layer attribute -+ if ((p->cpc_name && qc_set_attr_string(hdl->root, qc_layer_name, p->cpc_name, ATTR_SRC_SYSFS))) { -+ rc = -1; -+ goto out; -+ } -+ -+ // Set top layer attributes. -+ // Note: This implies that all top layers must feature these attributes! -+ hdl = qc_get_top_handle(hdl); -+ if ((p->has_secure >= 0 && qc_set_attr_int(hdl, qc_has_secure, p->has_secure, ATTR_SRC_SYSFS)) || -+ (p->secure >= 0 && qc_set_attr_int(hdl, qc_secure, p->secure, ATTR_SRC_SYSFS))) { -+ rc = -1; -+ goto out; -+ } -+ -+out: -+ qc_debug_indent_dec(); -+ -+ return rc; -+} -+ -+struct qc_data_src sysfs = {qc_sysfs_open, -+ qc_sysfs_process, -+ qc_sysfs_dump, -+ qc_sysfs_close, -+ NULL, -+ NULL}; diff --git a/qclib-2.0.1.tgz b/qclib-2.0.1.tgz deleted file mode 100644 index 4f7320c..0000000 --- a/qclib-2.0.1.tgz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f4ad708795fe26511a1311a37377d2a95133b480a723e66ed64f05ff94182bb0 -size 86657 diff --git a/qclib-2.1.0.tgz b/qclib-2.1.0.tgz new file mode 100644 index 0000000..f2c03fc --- /dev/null +++ b/qclib-2.1.0.tgz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6f534bcbc496023965fa421987a0a556d72fde50f74146902022fda5d73f488 +size 88622 diff --git a/qclib.changes b/qclib.changes index 36cc8de..60f3205 100644 --- a/qclib.changes +++ b/qclib.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Mon Apr 27 18:42:51 UTC 2020 - Mark Post + +- Upgraded to version 2.1.0 (bsc#1170410) + Changes: + - New attributes in support of secure boot in all final layers: + * qc_has_secure + * qc_secure + Note: Changed src column indicator from 'o' to 'F' to summarize + firmware-related data + - Recognize IBM z15 midrange models + Bug fixes: + - qc_open(): Memory leaks on errors +- Removed obsolete qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch. + ------------------------------------------------------------------- Tue Mar 3 19:38:58 UTC 2020 - Mark Post diff --git a/qclib.spec b/qclib.spec index 4547e65..672be45 100644 --- a/qclib.spec +++ b/qclib.spec @@ -17,7 +17,7 @@ Name: qclib -Version: 2.0.1 +Version: 2.1.0 Release: 0 Summary: Query Capacity library License: BSD-3-Clause @@ -26,7 +26,6 @@ URL: http://www.ibm.com/developerworks/linux/linux390/qclib.html Source: %{name}-%{version}.tgz Source1: %{name}-rpmlintrc Patch1: qclib.makefile.libdir.patch -Patch2: qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch BuildRequires: doxygen BuildRequires: gcc-c++ ExclusiveArch: s390 s390x