Hello community, here is the log from the commit of package qclib for openSUSE:Leap:15.2 checked in at 2020-05-04 08:22:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/qclib (Old) and /work/SRC/openSUSE:Leap:15.2/.qclib.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qclib" Mon May 4 08:22:27 2020 rev:26 rq:799255 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/qclib/qclib.changes 2020-03-13 10:55:42.912363666 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.qclib.new.2738/qclib.changes 2020-05-04 08:22:28.308340647 +0200 @@ -1,0 +2,15 @@ +Mon Apr 27 18:42:51 UTC 2020 - Mark Post <[email protected]> + +- 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. + +------------------------------------------------------------------- Old: ---- qclib-2.0.1-add-support-for-secure-boot-related-attributes.patch qclib-2.0.1.tgz New: ---- qclib-2.1.0.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qclib.spec ++++++ --- /var/tmp/diff_new_pack.eV7kE6/_old 2020-05-04 08:22:28.604341281 +0200 +++ /var/tmp/diff_new_pack.eV7kE6/_new 2020-05-04 08:22:28.604341281 +0200 @@ -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 @@ 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 ++++++ qclib-2.0.1.tgz -> qclib-2.1.0.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/Makefile new/qclib-2.1.0/Makefile --- old/qclib-2.0.1/Makefile 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/Makefile 2020-04-20 12:58:24.000000000 +0200 @@ -4,11 +4,11 @@ # major : Backwards compatible changes to the API # minor : Additions leaving the API unmodified # bugfix: Bugfixes only -VERSION = 2.0.1 +VERSION = 2.1.0 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/README new/qclib-2.1.0/README --- old/qclib-2.0.1/README 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/README 2020-04-20 12:58:24.000000000 +0200 @@ -27,9 +27,9 @@ 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 @@ -93,7 +93,19 @@ Release History: ================ -2.0.1 +2.1.0 (2020-04-20) + 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 + +2.0.1 (2020-01-07) Changes: - Retry up to three times when a live guest migration is detected @@ -103,7 +115,7 @@ qc_num_cpu_* attributes. - qc_dump: Handle non-writable /tmp -2.0.0 +2.0.0 (2019-11-11) Changes: - Add support for z/OS Container Extensions (zCX) - New attributes in layer CEC: @@ -119,13 +131,13 @@ - Disabled v1 compatibility functionality per default. To re-enable, activate CONFIG_V1_COMPATIBILITY in query_capacity.h. -1.4.1 +1.4.1 (2018-06-25) Bug fixes: - qc_dump: Don't abort the dump in case qc_test fails. - Attributes qc_cp_weight_capping and qc_ifl_weight_capping were set even when initial capping was not set in the LPAR's activation profile. -1.4.0 +1.4.0 (2018-04-10) Changes: - Added SMT support by properly differentiating between cores and CPUs. I.e. switched from qc_num_cpu_* to qc_num_core_* attributes in layers @@ -156,14 +168,14 @@ not. It therefore reports all cores as configured, which can be wrong. -1.3.1 +1.3.1 (2018-01-18) Bug fixes: - Security: Fix PATH attack vulnerability when dumping (see QC_DEBUG=2) - STHYI: Add fallback for pre-glibc 2.16 (not using getauxval()) - Handle mismatching STHYI and /proc/sysinfo layer counts - On LPAR, fix incomplete dump of binary hypfs when textual hypfs is mounted -1.3.0 +1.3.0 (2017-10-27) Changes: - Added STHYI support in LPAR - Added new env variable QC_DEBUG_FILE (see qc_open()) @@ -180,7 +192,7 @@ - Logs: Fix month in timestamp (was off by 1) - qc_test: Fix flags for qc_layer_name in QC_LAYER_TYPE_ZVM_HYPERVISOR -1.2.0 +1.2.0 (2016-06-10) Changes: - Removed source [S] for attributes qc_num_cpu_dedicated and qc_num_cpu_shared in LPAR layer for consistency @@ -203,7 +215,7 @@ - Display all values in attribute qc_partition_char in case of multiple - Set qc_cp_dispatch_type in presence of CPs only -1.1.0 +1.1.0 (2016-02-15) Changes: - Makefile: Added targets 'clean' and 'install' - qc_test: Support command line options @@ -219,7 +231,7 @@ - Consistency checks: Fixed wrong positive - Fixed source indicators in log -1.0.0 +1.0.0 (2015-08-28) Changes: - Introduced new API, replacing the previous one - Renamed the following attributes for consistency: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/qc_test.c new/qclib-2.1.0/qc_test.c --- old/qclib-2.0.1/qc_test.c 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/qc_test.c 2020-04-20 12:58:24.000000000 +0200 @@ -77,6 +77,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity.c new/qclib-2.1.0/query_capacity.c --- old/qclib-2.0.1/query_capacity.c 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/query_capacity.c 2020-04-20 12:58:24.000000000 +0200 @@ -111,7 +111,7 @@ goto out_err; } } - qc_debug(NULL, "This is qclib v2.0.1, level 831726bb, date 2020-01-07 20:45:22 +0100\n"); + qc_debug(NULL, "This is qclib v2.1.0, level 3877f257, date 2020-04-15 22:20:26 +0200\n"); } return 0; @@ -196,8 +196,6 @@ if (access(qc_dbg_use_dump, R_OK | X_OK) == -1) { qc_debug(NULL, "Error: Dump usage requested, but path '%s' " "not accessible: %s\n", qc_dbg_use_dump, strerror(errno)); - free(qc_dbg_use_dump); - qc_dbg_use_dump = NULL; rc = 2; goto out_err; } @@ -226,6 +224,8 @@ // Nothing we can do about this except to disable debug messages to prevent further damage free(qc_dbg_dump_dir); qc_dbg_dump_dir = NULL; + free(qc_dbg_use_dump); + qc_dbg_use_dump = NULL; free(path); return rc; @@ -297,6 +297,56 @@ return rc; } +static int qc_hdl_register(struct qc_handle *hdl) { + struct qc_reg_hdl *entry; + + entry = malloc(sizeof(struct qc_reg_hdl)); + if (!entry) { + qc_debug(hdl, "Error: Failed register hdl\n"); + return -1; + } + entry->hdl = hdl; + if (qc_hdls) + entry->next = qc_hdls; + else + entry->next = NULL; + qc_hdls = entry; + + return 0; +} + +static void qc_hdl_unregister(struct qc_handle *hdl) { + struct qc_reg_hdl *entry, *prev = NULL; + + for (entry = qc_hdls; entry != NULL; prev = entry, entry = entry->next) { + if (entry->hdl == hdl) { + if (prev && entry->next) + prev->next = entry->next; + else if (!prev) + qc_hdls = entry->next; + else + prev->next = NULL; + free(entry); + break; + } + } + return; +} + +static int qc_hdl_verify(struct qc_handle *hdl, const char *func) { + struct qc_reg_hdl *entry; + + if (!hdl) + return -1; + for (entry = qc_hdls; entry != NULL; entry = entry->next) { + if (entry->hdl == hdl) + return 0; + } + qc_debug(NULL, "Error: %s() called with unknown handle %p\n", func, hdl); + + return -1; +} + // De-alloc hdl, leaving out the actual handle static void qc_hdl_reinit(struct qc_handle *hdl) { struct qc_handle *ptr = hdl, *arg = hdl; @@ -313,6 +363,7 @@ free(ptr); ptr = hdl; } + qc_hdl_unregister(arg); } /** Verifies that either a and (b or c), or none are set. I.e. if only one of the attributes is set, then that's an error */ @@ -496,31 +547,33 @@ }; static struct qc_mtype mtypes[] = { - {4381, "IBM 4381", NULL}, - {3090, "IBM 3090", NULL}, - {9221, "IBM S/390 9221", NULL}, - {9021, "IBM ES/9000 9021", NULL}, - {2003, "IBM S/390 Multiprise 2000", NULL}, - {3000, "IBM S/390 StarterPak 3000", NULL}, - {9672, "IBM S/390 9672", NULL}, - {2066, "IBM zSeries 800", NULL}, - {2064, "IBM zSeries 900", NULL}, - {2086, "IBM zSeries 890", NULL}, - {2084, "IBM zSeries 990", NULL}, - {2096, "IBM System z9 BC", NULL}, - {2094, "IBM System z9 EC", NULL}, - {2098, "IBM System z10 BC", NULL}, - {2097, "IBM System z10 EC", NULL}, - {2818, "IBM zEnterprise 114", NULL}, - {2817, "IBM zEnterprise 196", NULL}, - {2827, "IBM zEnterprise EC12", NULL}, - {2828, "IBM zEnterprise BC12", NULL}, - {2965, "IBM z13s", "IBM LinuxONE Rockhopper"}, - {2964, "IBM z13", "IBM LinuxONE Emperor"}, - {3907, "IBM z14 ZR1", "IBM LinuxONE Rockhopper II"}, - {3906, "IBM z14", "IBM LinuxONE Emperor II"}, - {8561, "IBM z15", "IBM LinuxONE III"}, - {0, NULL, NULL} + // IBM Z LinuxONE + {4381, "IBM 4381", NULL}, + {3090, "IBM 3090", NULL}, + {9221, "IBM S/390 9221", NULL}, + {9021, "IBM ES/9000 9021", NULL}, + {2003, "IBM S/390 Multiprise 2000", NULL}, + {3000, "IBM S/390 StarterPak 3000", NULL}, + {9672, "IBM S/390 9672", NULL}, + {2066, "IBM zSeries 800", NULL}, + {2064, "IBM zSeries 900", NULL}, + {2086, "IBM zSeries 890", NULL}, + {2084, "IBM zSeries 990", NULL}, + {2096, "IBM System z9 BC", NULL}, + {2094, "IBM System z9 EC", NULL}, + {2098, "IBM System z10 BC", NULL}, + {2097, "IBM System z10 EC", NULL}, + {2818, "IBM zEnterprise 114", NULL}, + {2817, "IBM zEnterprise 196", NULL}, + {2827, "IBM zEnterprise EC12", NULL}, + {2828, "IBM zEnterprise BC12", NULL}, + {2965, "IBM z13s", "IBM LinuxONE Rockhopper"}, + {2964, "IBM z13", "IBM LinuxONE Emperor"}, + {3907, "IBM z14 ZR1", "IBM LinuxONE Rockhopper II"}, + {3906, "IBM z14", "IBM LinuxONE Emperor II"}, + {8561, "IBM z15", "IBM LinuxONE III"}, + {8562, "IBM z15 Model T02", "IBM LinuxONE III Model LT2"}, + {0, NULL, NULL} }; static int qc_post_process_ziip_thrds(struct qc_handle *hdl) { @@ -679,7 +732,8 @@ 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; @@ -747,62 +801,15 @@ // Close all data sources for (i = 0; (src = sources[i]) != NULL; i++) src->close(hdl, src->priv); + if (hdl) + // nothing else we can do if registration fails + qc_hdl_register(hdl); qc_debug(hdl, "Return rc=%d\n", *rc); qc_debug_indent_dec(); return hdl; } -static int qc_register_hdl(struct qc_handle *hdl) { - struct qc_reg_hdl *entry; - - entry = malloc(sizeof(struct qc_reg_hdl)); - if (!entry) { - qc_debug(hdl, "Error: Failed register hdl\n"); - return -1; - } - entry->hdl = hdl; - if (qc_hdls) - entry->next = qc_hdls; - else - entry->next = NULL; - qc_hdls = entry; - - return 0; -} - -static int qc_verify_hdl(struct qc_handle *hdl, const char *func) { - struct qc_reg_hdl *entry; - - if (!hdl) - return -1; - for (entry = qc_hdls; entry != NULL; entry = entry->next) { - if (entry->hdl == hdl) - return 0; - } - qc_debug(NULL, "Error: %s() called with unknown handle %p\n", func, hdl); - - return -1; -} - -static void qc_unregister_hdl(struct qc_handle *hdl) { - struct qc_reg_hdl *entry, *prev = NULL; - - for (entry = qc_hdls; entry != NULL; prev = entry, entry = entry->next) { - if (entry->hdl == hdl) { - if (prev && entry->next) - prev->next = entry->next; - else if (!prev) - qc_hdls = entry->next; - else - prev->next = NULL; - free(entry); - break; - } - } - return; -} - void *qc_open(int *rc) { struct qc_handle *hdl = NULL; char *s, *end; @@ -848,8 +855,6 @@ } if (*rc > 0) qc_debug(hdl, "Error: Unable to retrieve consistent data, giving up\n"); - if (*rc == 0) - *rc = qc_register_hdl(hdl); out: qc_debug(hdl, "Return %p, rc=%d\n", *rc ? NULL : hdl, *rc); @@ -863,14 +868,13 @@ } void qc_close(void *hdl) { - if (qc_verify_hdl(hdl, "qc_close")) + if (qc_hdl_verify(hdl, "qc_close")) return; qc_debug(hdl, "qc_close()\n"); qc_debug_indent_inc(); qc_debug_deinit(hdl); qc_hdl_reinit(hdl); - qc_unregister_hdl(hdl); free(hdl); qc_debug_indent_dec(); @@ -879,7 +883,7 @@ int qc_get_num_layers(void *cfg, int *rc) { struct qc_handle *hdl = cfg; - if (qc_verify_hdl(hdl, "qc_get_num_layers")) { + if (qc_hdl_verify(hdl, "qc_get_num_layers")) { *rc = -EFAULT; return *rc; } @@ -907,7 +911,7 @@ } 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) { @@ -915,7 +919,7 @@ int rc; *value = NULL; - if (qc_verify_hdl(cfg, "qc_get_attribute_string")) + if (qc_hdl_verify(cfg, "qc_get_attribute_string")) return -4; hdl = qc_get_layer_handle(cfg, layer); qc_debug(cfg, "qc_get_attribute_string(attr=%d, layer=%d)\n", id, layer); @@ -952,7 +956,7 @@ int rc; *value = -EINVAL; - if (qc_verify_hdl(cfg, "qc_get_attribute_int")) + if (qc_hdl_verify(cfg, "qc_get_attribute_int")) return -4; hdl = qc_get_layer_handle(cfg, layer); qc_debug(cfg, "qc_get_attribute_int(attr=%d, layer=%d)\n", id, layer); @@ -994,7 +998,7 @@ int rc; *value = -EINVAL; - if (qc_verify_hdl(cfg, "qc_get_attribute_float")) + if (qc_hdl_verify(cfg, "qc_get_attribute_float")) return -4; hdl = qc_get_layer_handle(cfg, layer); qc_debug(cfg, "qc_get_attribute_float(attr=%d, layer=%d)\n", id, layer); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity.h new/qclib-2.1.0/query_capacity.h --- old/qclib-2.0.1/query_capacity.h 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/query_capacity.h 2020-04-20 12:58:24.000000000 +0200 @@ -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|<CODE>O V</CODE>| CPC name of machine + * #qc_layer_name |string|<CODE>F V</CODE>| CPC name of machine. Available in Linux kernel 3.0 or higher. * #qc_manufacturer |string|<CODE>S V</CODE>| \n * #qc_type |string|<CODE>S V</CODE>| \n * #qc_type_name |string|<CODE>S </CODE>| \n - * #qc_type_family | int |<CODE>S </CODE>| \n + * #qc_type_family | int |<CODE>S </CODE>| \n * #qc_model_capacity |string|<CODE>S </CODE>| \n * #qc_model |string|<CODE>S </CODE>| \n * #qc_sequence_code |string|<CODE>S V</CODE>| \n @@ -143,6 +143,8 @@ * #qc_partition_char |string|<CODE>S </CODE>| \n * #qc_partition_char_num | int |<CODE>S </CODE>| \n * #qc_adjustment | int |<CODE>S </CODE>| \n + * #qc_has_secure | int |<CODE>F </CODE>| \n + * #qc_secure | int |<CODE>F </CODE>| \n * #qc_num_core_total | int |<CODE>S</CODE>| Total number of CPs and IFLs configured in the LPARs activation profile * #qc_num_core_configured | int |<CODE>S </CODE>| <b>Note</b>: \b [5] * #qc_num_core_standby | int |<CODE>S </CODE>| Operational cores that require add'l configuration within the LPAR image to become usable<br><b>Note</b>: \b [5] @@ -225,6 +227,9 @@ * #qc_layer_name |string|<CODE>S V</CODE>| Userid of guest * #qc_capping |string|<CODE> H</CODE>| \n * #qc_capping_num | int |<CODE> H</CODE>| \n + * #qc_mobility_enabled | int |<CODE> V</CODE>| \n + * #qc_has_secure | int |<CODE>F </CODE>| \n + * #qc_secure | int |<CODE>F </CODE>| \n * #qc_num_cpu_total | int |<CODE>S V</CODE>| 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 |<CODE>S </CODE>| \n * #qc_num_cpu_standby | int |<CODE>S </CODE>| \n @@ -240,7 +245,6 @@ * #qc_num_ziip_total | int |<CODE> V</CODE>| Sum of #qc_num_ziip_dedicated and #qc_num_ziip_shared<br>Reported in unit of CPUs * #qc_num_ziip_dedicated | int |<CODE> V</CODE>| Reported in unit of CPUs * #qc_num_ziip_shared | int |<CODE> V</CODE>| Reported in unit of CPUs - * #qc_mobility_enabled | int |<CODE> V</CODE>| \n * #qc_has_multiple_cpu_types | int |<CODE> V</CODE>| \n * #qc_cp_dispatch_limithard | int |<CODE> V</CODE>| \n * #qc_cp_dispatch_type | int |<CODE> V</CODE>| Only set in presence of CPs @@ -300,6 +304,8 @@ * #qc_layer_name |string|<CODE>S V</CODE>| Userid of guest * #qc_capping |string|<CODE> H</CODE>| \n * #qc_capping_num | int |<CODE> H</CODE>| \n + * #qc_has_secure | int |<CODE>F </CODE>| \n + * #qc_secure | int |<CODE>F </CODE>| \n * #qc_num_cpu_total | int |<CODE>S V</CODE>| 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 |<CODE>S </CODE>| \n * #qc_num_cpu_standby | int |<CODE>S </CODE>| \n @@ -349,6 +355,8 @@ * #qc_layer_name |string|<CODE>S </CODE>| Guest name truncated to 8 characters<br><b>Note</b>: \b [1] * #qc_layer_extended_name |string|<CODE>S </CODE>| Guest name with up to 256 characters<br><b>Note</b>: Requires Linux kernel 3.19 or higher, [1] * #qc_layer_uuid |string|<CODE>S </CODE>| <b>Note</b>: Requires Linux kernel 3.19 or higher + * #qc_has_secure | int |<CODE>F </CODE>| \n + * #qc_secure | int |<CODE>F </CODE>| \n * #qc_num_cpu_total | int |<CODE>S </CODE>| 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 |<CODE>S </CODE>| \n * #qc_num_cpu_standby | int |<CODE>S </CODE>| \n @@ -533,6 +541,14 @@ /** 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity_data.c new/qclib-2.1.0/query_capacity_data.c --- old/qclib-2.0.1/query_capacity_data.c 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/query_capacity_data.c 2020-04-20 12:58:24.000000000 +0200 @@ -122,6 +122,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ {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 @@ {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 @@ {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 @@ {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 @@ {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 @@ 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 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity_int.h new/qclib-2.1.0/query_capacity_int.h --- old/qclib-2.0.1/query_capacity_int.h 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/query_capacity_int.h 2020-04-20 12:58:24.000000000 +0200 @@ -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 @@ 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_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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity_ocf.c new/qclib-2.1.0/query_capacity_ocf.c --- old/qclib-2.0.1/query_capacity_ocf.c 2020-01-08 22:26:50.000000000 +0100 +++ new/qclib-2.1.0/query_capacity_ocf.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,135 +0,0 @@ -/* Copyright IBM Corp. 2016 */ - -#define _GNU_SOURCE -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qclib-2.0.1/query_capacity_sysfs.c new/qclib-2.1.0/query_capacity_sysfs.c --- old/qclib-2.0.1/query_capacity_sysfs.c 1970-01-01 01:00:00.000000000 +0100 +++ new/qclib-2.1.0/query_capacity_sysfs.c 2020-04-20 12:58:24.000000000 +0200 @@ -0,0 +1,351 @@ +/* Copyright IBM Corp. 2020 */ + +#define _GNU_SOURCE +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +#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};
