mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c922b105b | ||
|
|
4b19b9d950 | ||
|
|
cee4bb4995 | ||
|
|
c98d8e7629 | ||
|
|
96084339f5 | ||
|
|
f8d5b4b341 | ||
|
|
5806c4e1f4 | ||
|
|
9d199e06cb | ||
|
|
f7425a08d1 | ||
|
|
f6a97902c3 | ||
|
|
962af1a90e | ||
|
|
46dadc8cc4 | ||
|
|
9c8d117cc2 | ||
|
|
d7b3196286 | ||
|
|
b6c30404bc | ||
|
|
6d15850480 | ||
|
|
858da9af57 | ||
|
|
a7373674bf | ||
|
|
613353cd33 | ||
|
|
f6e932e0fd | ||
|
|
7e31c425c9 | ||
|
|
6c4171b775 | ||
|
|
0b0960254e | ||
|
|
4d2c9267c2 | ||
|
|
7ea0dfdc17 | ||
|
|
2d3aac1241 | ||
|
|
c7fd515790 | ||
|
|
7a4ec55d77 | ||
|
|
63ff07ba38 | ||
|
|
26d7eed0aa | ||
|
|
e0034eddbf | ||
|
|
0e3034c0f6 | ||
|
|
686262fdcd | ||
|
|
2379fd8a58 | ||
|
|
3552a27ae6 | ||
|
|
39106ba760 |
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,6 +1,32 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
|
||||
* __v2.34.0 (2024-08-01)__
|
||||
|
||||
For Linux kernel version: 6.10
|
||||
|
||||
Changes of existing tools:
|
||||
- ap_tools/ap-check: Add support for vfio-ap dynamic configuration
|
||||
- dbginfo.sh: Update/Add additional DASD data collection
|
||||
- dumpconf: Add new parameter 'SCP_DATA' for SCSI/NVMe/ECKD dump devices
|
||||
- libutil: Make formatted meta-data configurable
|
||||
- s390-tools: Replace 'which' with built-in 'command -v'
|
||||
- zdump/dfi_elf: Support core dumps of vr-kernels
|
||||
|
||||
Bug Fixes:
|
||||
- chzdev: Fix warning about failed ATTR writes by udev
|
||||
- rust/pv: Try again if first CRL-URI is invalid
|
||||
- rust/pvattest: Add short option for --arpk
|
||||
- zdump: Fix 'zgetdump -i' ioctl error on s390 formatted dump file
|
||||
|
||||
* __v2.33.1 (2024-05-28)__
|
||||
|
||||
For Linux kernel version: 6.9
|
||||
|
||||
Bug Fixes:
|
||||
- s390-tools: Fix formatting and typos in README.md
|
||||
- s390-tools: Fix release string
|
||||
|
||||
* __v2.33.0 (2024-05-27)__
|
||||
|
||||
For Linux kernel version: 6.9
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
3t90-tools
|
||||
s390-tools
|
||||
==========
|
||||
|
||||
The s390-tools package contains the source tree of a set of user space
|
||||
@@ -44,7 +44,7 @@ Package contents
|
||||
* genprotimg:
|
||||
Create a protected virtualization image.
|
||||
|
||||
* udev rules:
|
||||
* udev rules:
|
||||
- 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/.
|
||||
- 57-osasnmpd.rules: udev rules for osasnmpd.
|
||||
- 60-readahead.rules: udev rules to set increased "default max readahead".
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <json-c/json.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -27,21 +28,33 @@
|
||||
|
||||
#include "ap-check.h"
|
||||
|
||||
/* The supported mdevctl callout version */
|
||||
#define MDEVCTL_CAP_VERSION 2
|
||||
|
||||
static const struct mdevctl_action mdevctl_action_table[NUM_MDEVCTL_ACTIONS] = {
|
||||
{MDEVCTL_ACTION_DEFINE, "define"},
|
||||
{MDEVCTL_ACTION_LIST, "list"},
|
||||
{MDEVCTL_ACTION_MODIFY, "modify"},
|
||||
{MDEVCTL_ACTION_START, "start"},
|
||||
{MDEVCTL_ACTION_STOP, "stop"},
|
||||
{MDEVCTL_ACTION_TYPES, "types"},
|
||||
{MDEVCTL_ACTION_UNDEFINE, "undefine"},
|
||||
{MDEVCTL_ACTION_ATTRIBUTES, "attributes"}
|
||||
{MDEVCTL_ACTION_ATTRIBUTES, "attributes"},
|
||||
{MDEVCTL_ACTION_CAPABILITIES, "capabilities"}
|
||||
/*
|
||||
* Note: the following actions are known to exist but currently ignored:
|
||||
* {MDEVCTL_ACTION_LIST, "list"},
|
||||
* {MDEVCTL_ACTION_TYPES, "types"}
|
||||
*/
|
||||
};
|
||||
|
||||
static const struct mdevctl_event mdevctl_event_table[NUM_MDEVCTL_EVENTS] = {
|
||||
{MDEVCTL_EVENT_PRE, "pre"},
|
||||
{MDEVCTL_EVENT_POST, "post"},
|
||||
{MDEVCTL_EVENT_GET, "get"}
|
||||
{MDEVCTL_EVENT_GET, "get"},
|
||||
{MDEVCTL_EVENT_LIVE, "live"}
|
||||
/*
|
||||
* Note: the following events are known to exist but currently ignored:
|
||||
* {MDEVCTL_EVENT_NOTIFY, "notify"},
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -596,6 +609,94 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ap_check_active(struct ap_check_anchor *anc)
|
||||
{
|
||||
int rc, rc2;
|
||||
|
||||
/* Ensure device with control domains also has usage domains */
|
||||
if (util_list_is_empty(anc->dev->domains) &&
|
||||
!util_list_is_empty(anc->dev->controls)) {
|
||||
fprintf(stderr, "At least one usage domain must be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check against all other active vfio-ap devices */
|
||||
rc = check_other_mdevs_sysfs(anc);
|
||||
/* Check against the system sysfs values for apmask/aqmask */
|
||||
rc2 = check_sysfs_mask_conflicts(anc);
|
||||
/* If either hit an error, reflect this */
|
||||
rc = rc != 0 ? rc : rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ap_do_dynamic_config(struct ap_check_anchor *anc)
|
||||
{
|
||||
char *adapters, *domains, *controls, *path, *attr;
|
||||
int asize, dsize, csize, size;
|
||||
int rc = 0;
|
||||
FILE *f;
|
||||
|
||||
adapters = vfio_ap_device_get_adapter_mask(anc->dev, &asize);
|
||||
domains = vfio_ap_device_get_domain_mask(anc->dev, &dsize);
|
||||
controls = vfio_ap_device_get_control_mask(anc->dev, &csize);
|
||||
|
||||
if (!adapters || !domains || !controls) {
|
||||
fprintf(stderr, "Failed to read device config\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The 'ap_config' command takes a comma-delimited list of the 3 masks
|
||||
* combined. Each mask size includes a terminating character, two of
|
||||
* which will be replaced by commas and the final replaced by a
|
||||
* newline, which ap_config seems to require at the end of the input.
|
||||
* Add one to ensure room for a null termination.
|
||||
*/
|
||||
size = asize + dsize + csize + 1;
|
||||
attr = util_zalloc(size);
|
||||
|
||||
/* Use the 3 masks to generate a 'ap_config' command */
|
||||
rc = snprintf(attr, size, "%s,%s,%s\n", adapters, domains, controls);
|
||||
|
||||
if (rc < size - 1) {
|
||||
fprintf(stderr, "Error creating ap_config command\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Apply the new configuration to the active device */
|
||||
path = path_get_vfio_ap_attr(anc->uuid, "ap_config");
|
||||
f = fopen(path, "w");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Error opening ap_config\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
rc = fputs(attr, f);
|
||||
fclose(f);
|
||||
|
||||
if (rc == EOF)
|
||||
fprintf(stderr, "Error writing to ap_config\n");
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (!adapters)
|
||||
free(adapters);
|
||||
if (!domains)
|
||||
free(domains);
|
||||
if (!controls)
|
||||
free(controls);
|
||||
if (!path)
|
||||
free(path);
|
||||
if (!attr)
|
||||
free(attr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if defining the specified device is a valid operation.
|
||||
* mdevctl can reach us for a DEFINE under the following circumstances:
|
||||
@@ -647,6 +748,50 @@ static int ap_check_handle_modify(struct ap_check_anchor *anc)
|
||||
return ap_check_changes(anc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if modifying the active device is a valid operation.
|
||||
* This is similar to STARTing a device, in that the requested modifications
|
||||
* cannot conflict with the active configuration. LIVE MODIFY can only be
|
||||
* handled if the ap_config attribute is available in the vfio-ap driver.
|
||||
*/
|
||||
static int ap_check_handle_live_modify(struct ap_check_anchor *anc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ap_get_lock_callout();
|
||||
if (rc) {
|
||||
fprintf(stderr, "Failed to acquire configuration lock %d\n",
|
||||
rc);
|
||||
return -1;
|
||||
}
|
||||
anc->cleanup_lock = true;
|
||||
|
||||
if (vfio_ap_read_device_config(NULL, anc->dev) != 0) {
|
||||
fprintf(stderr, "Failed to read device config\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(anc->dev->type, anc->type) != 0) {
|
||||
fprintf(stderr, "Invalid mdev_type: %s\n", anc->dev->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!vfio_ap_need_dynamic_config(anc->dev)) {
|
||||
fprintf(stderr, "vfio-ap module does not support ap_config for live modification");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the new configuration would cause conflicts */
|
||||
rc = ap_check_active(anc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Attempt to perform the dynamic configuration */
|
||||
rc = ap_do_dynamic_config(anc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if starting the specified device is a valid operation.
|
||||
* mdevctl can reach us for a START under the following circumstances:
|
||||
@@ -665,7 +810,7 @@ static int ap_check_handle_modify(struct ap_check_anchor *anc)
|
||||
*/
|
||||
static int ap_check_handle_start(struct ap_check_anchor *anc)
|
||||
{
|
||||
int rc = 0, rc2;
|
||||
int rc = 0;
|
||||
|
||||
/* Can only start a device if vfio_ap is built-in or loaded */
|
||||
if (!util_path_is_dir(VFIO_AP_PATH)) {
|
||||
@@ -694,20 +839,7 @@ static int ap_check_handle_start(struct ap_check_anchor *anc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure device with control domains also has usage domains */
|
||||
if (util_list_is_empty(anc->dev->domains) &&
|
||||
!util_list_is_empty(anc->dev->controls)) {
|
||||
fprintf(stderr, "At least one usage domain must be specified\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check against all other active vfio-ap devices */
|
||||
rc = check_other_mdevs_sysfs(anc);
|
||||
/* Check against the system sysfs values for apmask/aqmask */
|
||||
rc2 = check_sysfs_mask_conflicts(anc);
|
||||
/* If either hit an error, reflect this */
|
||||
rc = rc != 0 ? rc : rc2;
|
||||
rc = ap_check_active(anc);
|
||||
|
||||
/* If successful, lock must remain held until post callout */
|
||||
if (rc == 0)
|
||||
@@ -886,6 +1018,122 @@ static int ap_check_handle_get_attributes(struct ap_check_anchor *anc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the target 'attr' is in the 's' array, add it to the 't' array.
|
||||
*/
|
||||
static void json_add_attr(json_object *t, json_object *s, const char *attr)
|
||||
{
|
||||
size_t vlen, alen = strlen(attr);
|
||||
const char *val;
|
||||
json_object *o;
|
||||
int i, num;
|
||||
|
||||
num = json_object_array_length(s);
|
||||
for (i = 0; i < num; i++) {
|
||||
o = json_object_array_get_idx(s, i);
|
||||
val = json_object_get_string(o);
|
||||
vlen = strlen(val);
|
||||
if (alen == vlen && strncasecmp(attr, val, alen) == 0) {
|
||||
json_object_array_add(t, json_object_new_string(val));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a JSON-formatted list of capability information that this script
|
||||
* supports and return it to the caller via stdout. An example of what the
|
||||
* output should look like (without the newlines):
|
||||
* {
|
||||
* "supports": {
|
||||
* "version": 2,
|
||||
* "actions": ["define",
|
||||
* "modify",
|
||||
* "start",
|
||||
* "stop",
|
||||
* "undefine",
|
||||
* "attributes",
|
||||
* "capabilities"],
|
||||
* "events": ["pre",
|
||||
* "post",
|
||||
* "get",
|
||||
* "live"]
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
static int ap_check_handle_get_capabilities(void)
|
||||
{
|
||||
json_object *root, *csup, *cver, *cact, *cev, *cap, *caps, *o;
|
||||
int i, rc = 0;
|
||||
|
||||
root = json_object_from_fd(STDIN_FILENO);
|
||||
|
||||
if (!root) {
|
||||
fprintf(stderr, "No capabilities provided\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!json_object_object_get_ex(root, "provides", &csup)) {
|
||||
fprintf(stderr, "No supported capabilities provided\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!json_object_object_get_ex(csup, "version", &cver)) {
|
||||
fprintf(stderr, "No version provided in capabilities\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!json_object_object_get_ex(csup, "actions", &cact)) {
|
||||
fprintf(stderr, "No actions provided in capabilities\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!json_object_object_get_ex(csup, "events", &cev)) {
|
||||
fprintf(stderr, "No events provided in capabilities\n");
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advertise the subset of supported capabilities from the list
|
||||
* provided on stdin.
|
||||
*/
|
||||
|
||||
cap = json_object_new_object();
|
||||
caps = json_object_new_object();
|
||||
json_object_object_add(cap, "supports", caps);
|
||||
/*
|
||||
* Currently we always advertise a fixed version, but we may need to
|
||||
* revisit this if we increase MDEVCTL_CAP_VERSION in the future (e.g.
|
||||
* how to handle ap-check having a greater supported version than
|
||||
* what mdevctl reports)
|
||||
*/
|
||||
o = json_object_new_int(MDEVCTL_CAP_VERSION);
|
||||
json_object_object_add(caps, "version", o);
|
||||
|
||||
o = json_object_new_array();
|
||||
for (i = 0; i < NUM_MDEVCTL_ACTIONS; i++)
|
||||
json_add_attr(o, cact, mdevctl_action_table[i].action);
|
||||
json_object_object_add(caps, "actions", o);
|
||||
|
||||
o = json_object_new_array();
|
||||
for (i = 0; i < NUM_MDEVCTL_EVENTS; i++)
|
||||
json_add_attr(o, cev, mdevctl_event_table[i].event);
|
||||
json_object_object_add(caps, "events", o);
|
||||
|
||||
/* Return supported capabilities JSON on stdout */
|
||||
printf("%s\n", json_object_to_json_string(cap));
|
||||
|
||||
json_object_put(cap);
|
||||
|
||||
out:
|
||||
json_object_put(root);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine which mdevctl action is being checked and handle accordingly.
|
||||
*/
|
||||
@@ -911,8 +1159,6 @@ static int ap_check_handle_action(struct ap_check_anchor *anc)
|
||||
case MDEVCTL_ACTION_UNDEFINE:
|
||||
rc = ap_check_handle_undefine(anc);
|
||||
break;
|
||||
case MDEVCTL_ACTION_LIST:
|
||||
case MDEVCTL_ACTION_TYPES:
|
||||
default:
|
||||
/* Ignore some actions including unknown ones */
|
||||
break;
|
||||
@@ -937,6 +1183,19 @@ static int ap_check_handle_action(struct ap_check_anchor *anc)
|
||||
case MDEVCTL_ACTION_ATTRIBUTES:
|
||||
rc = ap_check_handle_get_attributes(anc);
|
||||
break;
|
||||
case MDEVCTL_ACTION_CAPABILITIES:
|
||||
rc = ap_check_handle_get_capabilities();
|
||||
break;
|
||||
default:
|
||||
/* Ignore some actions including unknown ones */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MDEVCTL_EVENT_LIVE:
|
||||
switch (anc->action) {
|
||||
case MDEVCTL_ACTION_MODIFY:
|
||||
rc = ap_check_handle_live_modify(anc);
|
||||
break;
|
||||
default:
|
||||
/* Ignore some actions including unknown ones */
|
||||
break;
|
||||
|
||||
@@ -24,6 +24,7 @@ enum mdevctl_action_id {
|
||||
MDEVCTL_ACTION_TYPES,
|
||||
MDEVCTL_ACTION_UNDEFINE,
|
||||
MDEVCTL_ACTION_ATTRIBUTES,
|
||||
MDEVCTL_ACTION_CAPABILITIES,
|
||||
/* UNKNOWN must always be the last in the list */
|
||||
MDEVCTL_ACTION_UNKNOWN,
|
||||
};
|
||||
@@ -38,6 +39,7 @@ enum mdevctl_event_id {
|
||||
MDEVCTL_EVENT_PRE = 0,
|
||||
MDEVCTL_EVENT_POST,
|
||||
MDEVCTL_EVENT_GET,
|
||||
MDEVCTL_EVENT_LIVE,
|
||||
MDEVCTL_EVENT_UNKNOWN,
|
||||
};
|
||||
#define NUM_MDEVCTL_EVENTS MDEVCTL_EVENT_UNKNOWN
|
||||
|
||||
@@ -951,7 +951,7 @@ static void set_record_extension(struct file *f, int *record, off_t addr,
|
||||
|
||||
if (f->record_scan_state != RSS_DATA_BLOCK_STARTED &&
|
||||
f->record_scan_state != RSS_DATA_BLOCK_EXT)
|
||||
DIE("%s: interal error\n", __func__);
|
||||
DIE("%s: internal error\n", __func__);
|
||||
|
||||
BUG(*record >= f->fst->nr_records);
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ endif
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION := 2
|
||||
RELEASE := 32
|
||||
RELEASE := 34
|
||||
PATCHLEVEL := 0
|
||||
DISTRELEASE := build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
#
|
||||
# Dump on ECKD device (DASD)
|
||||
#
|
||||
#ON_PANIC=dump
|
||||
#DUMP_TYPE=eckd
|
||||
#DEVICE=0.0.1004
|
||||
#BOOTPROG=0
|
||||
#BR_CHR=auto
|
||||
# ON_PANIC=dump
|
||||
# DUMP_TYPE=eckd
|
||||
# DEVICE=0.0.1004
|
||||
# BOOTPROG=0
|
||||
# BR_CHR=auto
|
||||
|
||||
#
|
||||
# Dump on fcp device (SCSI Disk)
|
||||
|
||||
@@ -58,6 +58,8 @@ struct os_info {
|
||||
uint8_t reserved[3804];
|
||||
} __packed;
|
||||
|
||||
STATIC_ASSERT(sizeof(struct os_info) == 4096)
|
||||
|
||||
/*
|
||||
* Return 0 in case of valid os_info
|
||||
* Return -EOS_INFO_MISSING if os_info address is not page aligned or page is
|
||||
|
||||
@@ -72,6 +72,7 @@ char *path_get_ap_udev(void);
|
||||
void vfio_ap_parse_matrix(struct vfio_ap_device *dev, char *matrix);
|
||||
void vfio_ap_sort_matrix_results(struct vfio_ap_device *dev);
|
||||
void vfio_ap_parse_control(struct vfio_ap_device *dev, char *control);
|
||||
bool vfio_ap_need_dynamic_config(struct vfio_ap_device *dev);
|
||||
|
||||
/* Functions for reading JSON device config */
|
||||
int vfio_ap_read_device_config(const char *path, struct vfio_ap_device *dev);
|
||||
@@ -87,6 +88,9 @@ bool ap_read_udev_masks(char *path, char *ap, char *aq, bool *read_ap,
|
||||
bool *read_aq);
|
||||
void ap_mask_to_list(char *mask, struct util_list *list);
|
||||
void ap_list_remove_all(struct util_list *list);
|
||||
char *vfio_ap_device_get_adapter_mask(struct vfio_ap_device *dev, int *size);
|
||||
char *vfio_ap_device_get_domain_mask(struct vfio_ap_device *dev, int *size);
|
||||
char *vfio_ap_device_get_control_mask(struct vfio_ap_device *dev, int *size);
|
||||
|
||||
/* Lock Functions */
|
||||
int ap_get_lock(void);
|
||||
|
||||
@@ -723,14 +723,14 @@ static void check_exists(const char *path, const char *attr)
|
||||
|
||||
snprintf(fpath, sizeof(fpath), "/sys/firmware/%s", path);
|
||||
if (access(fpath, F_OK) != 0)
|
||||
ERR_EXIT("System does not allow to set %s", attr);
|
||||
ERR_EXIT("System does not allow one to set %s", attr);
|
||||
}
|
||||
|
||||
static void write_str_optional(char *string, char *file, int exit_on_fail,
|
||||
const char *attr)
|
||||
{
|
||||
if (write_str_errno(string, file) && exit_on_fail)
|
||||
ERR_EXIT("System does not allow to set %s", attr);
|
||||
ERR_EXIT("System does not allow one to set %s", attr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
prog_name=`basename $0`
|
||||
guest_name=${USER:-`whoami 2>/dev/null`}
|
||||
terminal=lnxhvc0
|
||||
iucvconn=`which iucvconn 2>/dev/null`
|
||||
iucvconn=`command -v iucvconn 2>/dev/null`
|
||||
|
||||
__error() {
|
||||
printf "$prog_name: $@\n" >&2
|
||||
|
||||
144
libap/ap.c
144
libap/ap.c
@@ -33,6 +33,9 @@
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/util_udev.h"
|
||||
|
||||
static const char default_mask[AP_MASK_SIZE] =
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
/*
|
||||
* Return sysfs path to a bus attribute
|
||||
* Note: caller is responsible for freeing the returned string
|
||||
@@ -118,6 +121,37 @@ static void modify_device_attr(struct util_list *list, char *value)
|
||||
vfio_ap_node_remove_dupes(list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass a comma-delimited string of masks (adapters,domains,controls) and
|
||||
* for each ON bit in these masks add the associated ID to the device
|
||||
* lists.
|
||||
*/
|
||||
static void modify_device_ap_config(struct vfio_ap_device *dev,
|
||||
char *value)
|
||||
{
|
||||
char *mask, *adapters, *domains, *controls;
|
||||
|
||||
mask = util_strdup(value);
|
||||
|
||||
adapters = strtok(mask, ",");
|
||||
domains = strtok(NULL, ",");
|
||||
controls = strtok(NULL, ",");
|
||||
util_assert((!strtok(NULL, ",")) && adapters && domains && controls,
|
||||
"Invalid ap_config attribute encountered %s", value);
|
||||
|
||||
/*
|
||||
* ap_config overwrites the current list of adapters, domains and
|
||||
* control domains. Clear the current lists before generating new ones
|
||||
* based upon the input mask values.
|
||||
*/
|
||||
ap_list_remove_all(dev->adapters);
|
||||
ap_list_remove_all(dev->domains);
|
||||
ap_list_remove_all(dev->controls);
|
||||
ap_mask_to_list(adapters, dev->adapters);
|
||||
ap_mask_to_list(domains, dev->domains);
|
||||
ap_mask_to_list(controls, dev->controls);
|
||||
}
|
||||
|
||||
static void load_attr_to_device(struct vfio_ap_device *dev, char *attr,
|
||||
const char *value)
|
||||
{
|
||||
@@ -129,6 +163,8 @@ static void load_attr_to_device(struct vfio_ap_device *dev, char *attr,
|
||||
modify_device_attr(dev->domains, v);
|
||||
else if (strcmp(attr, "assign_control_domain") == 0)
|
||||
modify_device_attr(dev->controls, v);
|
||||
else if (strcmp(attr, "ap_config") == 0)
|
||||
modify_device_ap_config(dev, v);
|
||||
|
||||
free(v);
|
||||
}
|
||||
@@ -416,6 +452,28 @@ void vfio_ap_parse_control(struct vfio_ap_device *dev, char *control)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified device is currently active. If so, see if
|
||||
* it is enabled for dynamic configuration support.
|
||||
*
|
||||
* @param[in] dev Vfio-ap struct
|
||||
*
|
||||
* @retval True Device is active and enabled for dynamic config
|
||||
* @retval False Device is not active OR no dynamic config support
|
||||
*/
|
||||
bool vfio_ap_need_dynamic_config(struct vfio_ap_device *dev)
|
||||
{
|
||||
char *attr = path_get_vfio_ap_attr(dev->uuid, "ap_config");
|
||||
|
||||
if (!attr)
|
||||
return false;
|
||||
|
||||
if (!util_path_is_readable(attr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JSONC
|
||||
|
||||
/**
|
||||
@@ -692,7 +750,7 @@ void ap_mask_to_list(char *mask, struct util_list *list)
|
||||
*/
|
||||
void ap_list_remove_all(struct util_list *list)
|
||||
{
|
||||
struct ap_node *node;
|
||||
struct vfio_ap_node *node;
|
||||
|
||||
while (!util_list_is_empty(list)) {
|
||||
node = util_list_start(list);
|
||||
@@ -715,6 +773,90 @@ static unsigned int random_delay(void)
|
||||
return AP_LOCK_DELAY_US + (rand() % AP_LOCK_VARIANCE_US);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mask of assigned adapters for the specified vfio_ap device.
|
||||
* Note: caller is responsible for freeing the returned string
|
||||
*
|
||||
* @param[in] dev Vfio-ap struct to get adapter mask from
|
||||
* @param[in, out] size Size of mask buffer returned
|
||||
*
|
||||
* @retval != 0 Adapter mask (hex string)
|
||||
* @retval 0 Failed to generate a mask
|
||||
*/
|
||||
char *vfio_ap_device_get_adapter_mask(struct vfio_ap_device *dev, int *size)
|
||||
{
|
||||
struct vfio_ap_node *node;
|
||||
char *mask;
|
||||
|
||||
if (!dev || !size)
|
||||
return NULL;
|
||||
|
||||
mask = util_strdup(default_mask);
|
||||
*size = AP_MASK_SIZE;
|
||||
|
||||
util_list_iterate(dev->adapters, node) {
|
||||
ap_set_bit(node->id, mask, true);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mask of assigned domains for the specified vfio_ap device.
|
||||
* Note: caller is responsible for freeing the returned string
|
||||
*
|
||||
* @param[in] dev Vfio-ap struct to get domain mask from
|
||||
* @param[in, out] size Size of mask buffer returned
|
||||
*
|
||||
* @retval != 0 Domain mask (hex string)
|
||||
* @retval 0 Failed to generate a mask
|
||||
*/
|
||||
char *vfio_ap_device_get_domain_mask(struct vfio_ap_device *dev, int *size)
|
||||
{
|
||||
struct vfio_ap_node *node;
|
||||
char *mask;
|
||||
|
||||
if (!dev || !size)
|
||||
return NULL;
|
||||
|
||||
mask = util_strdup(default_mask);
|
||||
*size = AP_MASK_SIZE;
|
||||
|
||||
util_list_iterate(dev->domains, node) {
|
||||
ap_set_bit(node->id, mask, true);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mask of assigned control domains for the specified vfio_ap device.
|
||||
* Note: caller is responsible for freeing the returned string
|
||||
*
|
||||
* @param[in] dev Vfio-ap struct to get control domain mask from
|
||||
* @param[in, out] size Size of mask buffer returned
|
||||
*
|
||||
* @retval != 0 Control domain mask (hex string)
|
||||
* @retval 0 Failed to generate a mask
|
||||
*/
|
||||
char *vfio_ap_device_get_control_mask(struct vfio_ap_device *dev, int *size)
|
||||
{
|
||||
struct vfio_ap_node *node;
|
||||
char *mask;
|
||||
|
||||
if (!dev || !size)
|
||||
return NULL;
|
||||
|
||||
mask = util_strdup(default_mask);
|
||||
*size = AP_MASK_SIZE;
|
||||
|
||||
util_list_iterate(dev->controls, node) {
|
||||
ap_set_bit(node->id, mask, true);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the ap config lock using this Process ID
|
||||
*
|
||||
|
||||
@@ -1084,8 +1084,6 @@ int kmip_connection_new(const struct kmip_conn_config *config,
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
default:
|
||||
kmip_debug(debug, "Invalid encoding: %d", config->encoding);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -89,7 +89,7 @@ int kmip_decode_xml(const xmlNode *xml, struct kmip_node *parent,
|
||||
} else {
|
||||
n->type = kmip_type_by_name_or_hex(type_attr);
|
||||
if (n->type == 0) {
|
||||
kmip_debug(debug, "Unknown 'type' in JSON object: '%s'",
|
||||
kmip_debug(debug, "Unknown 'type' in XML object: '%s'",
|
||||
type_attr);
|
||||
rc = -EBADMSG;
|
||||
goto out;
|
||||
@@ -361,7 +361,7 @@ int kmip_encode_xml(const struct kmip_node *node, xmlNode **xml, bool debug)
|
||||
while (element != NULL) {
|
||||
rc = kmip_encode_xml(element, &elem_xml, debug);
|
||||
if (rc != 0) {
|
||||
kmip_debug(debug, "kmip_encode_json failed");
|
||||
kmip_debug(debug, "kmip_encode_xml failed");
|
||||
goto out;
|
||||
}
|
||||
if (xmlAddChild(ret_xml, elem_xml) == NULL) {
|
||||
|
||||
@@ -710,6 +710,14 @@ static void csv_map(struct obj_t *UNUSED(obj), unsigned int mflags,
|
||||
free(qval);
|
||||
}
|
||||
|
||||
static bool hide_meta_env(void)
|
||||
{
|
||||
char *v;
|
||||
|
||||
v = secure_getenv("FMT_NOMETA");
|
||||
return (v && strcmp(v, "1") == 0);
|
||||
}
|
||||
|
||||
void util_fmt_init(FILE *fd, enum util_fmt_t type, unsigned int flags,
|
||||
int api_level)
|
||||
{
|
||||
@@ -719,7 +727,7 @@ void util_fmt_init(FILE *fd, enum util_fmt_t type, unsigned int flags,
|
||||
f.fileno = fileno(fd);
|
||||
f.hide_prefix = (flags & FMT_NOPREFIX);
|
||||
f.hide_inval = !(flags & FMT_KEEPINVAL);
|
||||
f.hide_meta = (flags & FMT_NOMETA);
|
||||
f.hide_meta = (flags & FMT_NOMETA) || hide_meta_env();
|
||||
f.quote_all = (flags & FMT_QUOTEALL);
|
||||
f.do_filter = (flags & FMT_FILTER);
|
||||
f.do_warn = (flags & FMT_WARN);
|
||||
|
||||
@@ -80,6 +80,10 @@ Cylinder, Head and Record) or "auto".
|
||||
\fB - BR_LBA:\fR
|
||||
Boot record logical block address.
|
||||
|
||||
.TP
|
||||
\fB - SCP_DATA:\fR
|
||||
SCP data for SCSI, NVMe and ECKD dump devices.
|
||||
|
||||
.TP
|
||||
\fB - VMCMD_1, VMCMD_2 ... VMCMD_8:\fR
|
||||
Up to eight CP commands, which are executed in case of a kernel panic
|
||||
|
||||
@@ -127,7 +127,7 @@ echo "$cmd: Copying kexec"
|
||||
# Install both binary and required shared libraries
|
||||
OLDPATH=$PATH
|
||||
PATH=$OLDPATH:/sbin:/usr/sbin
|
||||
kexec_bin=$(which kexec)
|
||||
kexec_bin=$(command -v kexec)
|
||||
kexec_sos=$(sharedobjs $kexec_bin)
|
||||
PATH=$OLDPATH
|
||||
|
||||
|
||||
@@ -302,8 +302,8 @@ pub fn x509_dist_points(cert: &X509Ref) -> Vec<String> {
|
||||
/// Searches for CRL Distribution points and downloads the CRL. Stops after the first successful
|
||||
/// download.
|
||||
///
|
||||
/// Error if something bad(=unexpected) happens (not bad: CRL not available at link, unexpected
|
||||
/// format) Other issues are mapped to Ok(None)
|
||||
/// Error if something bad(=unexpected) happens
|
||||
/// CRL not available at all URIs and unexpected format at all URIs are mapped to Ok(None)
|
||||
#[cfg(not(test))]
|
||||
pub fn download_first_crl_from_x509(cert: &X509Ref) -> Result<Option<Vec<openssl::x509::X509Crl>>> {
|
||||
use crate::utils::read_crls;
|
||||
@@ -333,6 +333,7 @@ pub fn download_first_crl_from_x509(cert: &X509Ref) -> Result<Option<Vec<openssl
|
||||
}
|
||||
match read_crls(&handle.get_ref().0) {
|
||||
Err(_) => continue,
|
||||
Ok(crl) if crl.is_empty() => continue,
|
||||
Ok(crl) => return Ok(Some(crl)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ pub struct ApqnInfoEp11 {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ApqnInfoCca {
|
||||
pub serialnr: String,
|
||||
pub mkvp_aes: String, // may be an empty string if no MK set
|
||||
@@ -129,6 +130,7 @@ pub struct ApqnInfoCca {
|
||||
pub enum ApqnInfo {
|
||||
Accel(ApqnInfoAccel),
|
||||
Ep11(ApqnInfoEp11),
|
||||
#[allow(dead_code)]
|
||||
Cca(ApqnInfoCca),
|
||||
}
|
||||
|
||||
@@ -262,6 +264,7 @@ impl ApqnInfo {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Apqn {
|
||||
#[allow(dead_code)]
|
||||
pub name: String,
|
||||
pub card: u32,
|
||||
pub domain: u32,
|
||||
|
||||
@@ -75,7 +75,7 @@ Write the generated request to FILE.
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
\-\-arpk <FILE>
|
||||
\-a, \-\-arpk <FILE>
|
||||
.RS 4
|
||||
Save the protection key as unencrypted GCM-AES256 key in FILE Do not publish
|
||||
this key, otherwise your attestation is compromised.
|
||||
|
||||
@@ -45,7 +45,7 @@ must start at a page boundary.
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
\-\-arpk <FILE>
|
||||
\-a, \-\-arpk <FILE>
|
||||
.RS 4
|
||||
Use FILE as the protection key to decrypt the request Do not publish this key,
|
||||
otherwise your attestation is compromised. Delete this key after verification.
|
||||
|
||||
@@ -97,7 +97,7 @@ pub struct CreateAttOpt {
|
||||
/// Save the protection key as unencrypted GCM-AES256 key in FILE
|
||||
///
|
||||
/// Do not publish this key, otherwise your attestation is compromised.
|
||||
#[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||
pub arpk: String,
|
||||
|
||||
/// Specify-additional data for the request.
|
||||
@@ -222,7 +222,7 @@ pub struct VerifyOpt {
|
||||
///
|
||||
/// Do not publish this key, otherwise your attestation is compromised.
|
||||
/// Delete this key after verification.
|
||||
#[arg(long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||
pub arpk: String,
|
||||
|
||||
/// Define the output format.
|
||||
|
||||
@@ -259,6 +259,7 @@ readonly LOGFILE="${WORKPATH}dbginfo.log"
|
||||
readonly OUTPUT_FILE_BRIDGE="${WORKPATH}network.out"
|
||||
readonly OUTPUT_FILE_CMD="${WORKPATH}runtime.out"
|
||||
readonly OUTPUT_FILE_COREDUMPCTL="${WORKPATH}coredump.out" # separate file needed
|
||||
readonly OUTPUT_FILE_DASD="${WORKPATH}dasd.out"
|
||||
readonly OUTPUT_FILE_DOCKER="${WORKPATH}docker_runtime.out"
|
||||
readonly OUTPUT_FILE_ETHTOOL="${WORKPATH}network.out"
|
||||
readonly OUTPUT_FILE_HYPTOP="${WORKPATH}runtime.out"
|
||||
@@ -296,6 +297,7 @@ ALL_STEPS="\
|
||||
collect_kvm\
|
||||
collect_container\
|
||||
collect_nvme\
|
||||
collect_dasd\
|
||||
collect_logfiles\
|
||||
post_processing\
|
||||
create_package\
|
||||
@@ -491,7 +493,7 @@ CMDS="uname -a\
|
||||
# Z device subsystem commands (first commands in non alphabetical order)
|
||||
CMDS="${CMDS}\
|
||||
:lschp\
|
||||
:lscss\
|
||||
:lscss --vpm\
|
||||
:lszdev\
|
||||
:find /dev -print0 | sort -z | xargs -0 -n 10 ls -ld\
|
||||
:lspci -t\
|
||||
@@ -1233,6 +1235,26 @@ collect_nvme() {
|
||||
fi
|
||||
}
|
||||
|
||||
########################################
|
||||
collect_dasd() {
|
||||
local device
|
||||
|
||||
if type dasdview >/dev/null; then
|
||||
pr_collect_output "DASD storage"
|
||||
call_run_command "lsdasd" "${OUTPUT_FILE_DASD}" # duplicate as file header
|
||||
for device in /dev/dasd*; do
|
||||
if [ -b $device ]; then
|
||||
call_run_command "dasdview -i $device" "${OUTPUT_FILE_DASD}"
|
||||
call_run_command "dasdview -t info $device" "${OUTPUT_FILE_DASD}"
|
||||
else
|
||||
echo "$device is no block device" >> ${OUTPUT_FILE_DASD}
|
||||
fi
|
||||
done
|
||||
else
|
||||
pr_skip "dasdview: not available"
|
||||
fi
|
||||
}
|
||||
|
||||
########################################
|
||||
collect_kvm() {
|
||||
local cmd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH DBGINFO.SH 8 "01 2024" "s390-tools"
|
||||
.TH DBGINFO.SH 8 "07 2024" "s390-tools"
|
||||
|
||||
.SH NAME
|
||||
dbginfo.sh \- collect runtime, configuration and trace information
|
||||
@@ -65,57 +65,59 @@ Hardware platform = s390x
|
||||
.br
|
||||
Runtime environment = z/VM - DPM: NO
|
||||
.br
|
||||
Kernel version = 5.14.0 (5.14.0-162.6.1.el9_1.s390x)
|
||||
Kernel version = 5.14.0 (5.14.0-427.13.1.el9_4.s390x)
|
||||
.br
|
||||
OS version / distro = Red Hat Enterprise Linux 9.1 (Plow)
|
||||
OS version / distro = Red Hat Enterprise Linux 9.4 (Plow)
|
||||
.br
|
||||
Date and time of info = 2023-12-22-11-43-08
|
||||
Date and time of info = 2024-07-11-11-11-11
|
||||
.PP
|
||||
1 of 19: Collecting sysfs
|
||||
1 of 20: Collecting sysfs
|
||||
.PP
|
||||
2 of 19: Collecting procfs
|
||||
2 of 20: Collecting procfs
|
||||
.PP
|
||||
3 of 19: Collecting config files
|
||||
3 of 20: Collecting config files
|
||||
.PP
|
||||
4 of 19: Collecting initrd config files
|
||||
4 of 20: Collecting initrd config files
|
||||
.PP
|
||||
5 of 19: Collecting command output
|
||||
5 of 20: Collecting command output
|
||||
.PP
|
||||
6 of 19: Collecting hyptop for z/VM - 5s output
|
||||
6 of 20: Collecting hyptop for z/VM - 5s output
|
||||
.PP
|
||||
7 of 19: Collecting z/VM output
|
||||
7 of 20: Collecting z/VM output
|
||||
.PP
|
||||
8 of 19: Collecting network output
|
||||
8 of 20: Collecting network output
|
||||
.PP
|
||||
9 of 19: Collecting osa oat output
|
||||
9 of 20: Collecting osa oat output
|
||||
.PP
|
||||
10 of 19: Collecting ethtool output
|
||||
10 of 20: Collecting ethtool output
|
||||
.PP
|
||||
11 of 19: Collecting Trafic Control output
|
||||
11 of 20: Collecting Trafic Control output
|
||||
.PP
|
||||
12 of 19: Collecting bridge output
|
||||
12 of 20: Collecting bridge output
|
||||
.PP
|
||||
13 of 19: Skip OpenVSwitch: ovs-vsctl not available
|
||||
13 of 20: Skip OpenVSwitch: ovs-vsctl not available
|
||||
.PP
|
||||
14 of 19: Skip KVM: no virsh command
|
||||
14 of 20: Skip KVM: no virsh command
|
||||
.PP
|
||||
15 of 19: Collecting container host output
|
||||
15 of 20: Collecting container host output
|
||||
.PP
|
||||
Kubernetes ...
|
||||
.br
|
||||
16 of 19: Collecting NVME storage output
|
||||
16 of 20: Collecting NVME storage output
|
||||
.PP
|
||||
17 of 19: Collecting log files
|
||||
17 of 20: Collecting DASD storage output
|
||||
.PP
|
||||
18 of 20: Collecting log files
|
||||
.PP
|
||||
0 logfiles over 50 MB
|
||||
.PP
|
||||
18 of 19: Postprocessing
|
||||
19 of 20: Postprocessing
|
||||
.PP
|
||||
19 of 19: Finalizing: Creating archive with collected data
|
||||
20 of 20: Finalizing: Creating archive with collected data
|
||||
.PP
|
||||
Collected data was saved to:
|
||||
.br
|
||||
>> /data\-collection/DBGINFO\-2023\-12\-22\-11\-43\-08\-host\-012345.tgz <<
|
||||
>> /data\-collection/DBGINFO\-2024\-07\-11\-11\-11\-11\-host\-012345.tgz <<
|
||||
.br
|
||||
Please review all collected data before sending to your service organization.
|
||||
.SH HINTS
|
||||
|
||||
@@ -50,7 +50,7 @@ check_environment()
|
||||
|
||||
if [ "$(cat /proc/filesystems|grep sysfs)" = "" ]; then
|
||||
pr_error "no sysfs found"
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SYSFSDIR=$(cat /proc/mounts|awk '$3=="sysfs"{print $2; exit}')
|
||||
@@ -184,7 +184,8 @@ verify_ccw_dump_device()
|
||||
#------------------------------------------------------------------------------
|
||||
# Helper function to check a device string.
|
||||
#------------------------------------------------------------------------------
|
||||
function CheckDeviceString() {
|
||||
check_device_string()
|
||||
{
|
||||
local X
|
||||
|
||||
X=$(
|
||||
@@ -222,7 +223,7 @@ function CheckDeviceString() {
|
||||
|
||||
setup_ccw_device()
|
||||
{
|
||||
DEV="$(CheckDeviceString $DEVICE)"
|
||||
DEV="$(check_device_string $DEVICE)"
|
||||
if [ "$DEV" != "" ]; then
|
||||
echo $DEV > $1/ccw/device
|
||||
else
|
||||
@@ -234,7 +235,7 @@ setup_ccw_device()
|
||||
|
||||
setup_eckd_device()
|
||||
{
|
||||
DEV="$(CheckDeviceString $DEVICE)"
|
||||
DEV="$(check_device_string $DEVICE)"
|
||||
if [ "$DEV" != "" ]; then
|
||||
echo $DEV > $1/eckd/device
|
||||
else
|
||||
@@ -252,11 +253,18 @@ setup_eckd_device()
|
||||
pr_error "ERROR: Invalid BR_CHR '$BR_CHR'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
if [ -e $1/eckd/scp_data ]; then
|
||||
echo -n "$SCP_DATA" > $1/eckd/scp_data 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid SCP_DATA '$SCP_DATA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_fcp_device()
|
||||
{
|
||||
DEV="$(CheckDeviceString $DEVICE)"
|
||||
DEV="$(check_device_string $DEVICE)"
|
||||
if [ "$DEV" != "" ]; then
|
||||
echo $DEV > $1/fcp/device
|
||||
else
|
||||
@@ -284,6 +292,13 @@ setup_fcp_device()
|
||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
if [ -e $1/fcp/scp_data ]; then
|
||||
echo -n "$SCP_DATA" > $1/fcp/scp_data 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid SCP_DATA '$SCP_DATA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_nss_device()
|
||||
@@ -313,6 +328,13 @@ setup_nvme_device()
|
||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
if [ -e $1/nvme/scp_data ]; then
|
||||
echo -n "$SCP_DATA" > $1/nvme/scp_data 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid SCP_DATA '$SCP_DATA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_reipl()
|
||||
@@ -428,6 +450,10 @@ print_fcp_device()
|
||||
pr_info "bootprog: $BOOTPROG"
|
||||
BR_LBA=$(cat $1/fcp/br_lba) || RETVAL=1
|
||||
pr_info "br_lba..: $BR_LBA"
|
||||
if [ -e $1/fcp/scp_data ]; then
|
||||
SCP_DATA=$(cat $1/fcp/scp_data) || RETVAL=1
|
||||
pr_info "scp_data: $SCP_DATA"
|
||||
fi
|
||||
}
|
||||
|
||||
print_ccw_device()
|
||||
@@ -444,6 +470,10 @@ print_eckd_device()
|
||||
pr_info "br_chr..: $BR_CHR"
|
||||
BOOTPROG=$(cat $1/eckd/bootprog) || RETVAL=1
|
||||
pr_info "bootprog: $BOOTPROG"
|
||||
if [ -e $1/eckd/scp_data ]; then
|
||||
SCP_DATA=$(cat $1/eckd/scp_data) || RETVAL=1
|
||||
pr_info "scp_data: $SCP_DATA"
|
||||
fi
|
||||
}
|
||||
|
||||
print_nvme_device()
|
||||
@@ -456,6 +486,10 @@ print_nvme_device()
|
||||
pr_info "bootprog: $BOOTPROG"
|
||||
BR_LBA=$(cat $1/nvme/br_lba) || RETVAL=1
|
||||
pr_info "br_lba..: $BR_LBA"
|
||||
if [ -e $1/nvme/scp_data ]; then
|
||||
SCP_DATA=$(cat $1/nvme/scp_data) || RETVAL=1
|
||||
pr_info "scp_data: $SCP_DATA"
|
||||
fi
|
||||
}
|
||||
|
||||
print_nss_name()
|
||||
|
||||
@@ -283,7 +283,7 @@ static void tape390_crypt_parse_opts(struct tape390_crypt *info, int argc,
|
||||
"%s: No device specified.\n",prog_name);
|
||||
if (optind + 1 < argc)
|
||||
ERRMSG_EXIT(EXIT_MISUSE,
|
||||
"%s: More than one device speficied.\n",prog_name);
|
||||
"%s: More than one device specified.\n",prog_name);
|
||||
strcpy(info->devname, argv[optind]);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,6 @@ extern struct devtype ap_devtype;
|
||||
extern struct subtype ap_subtype;
|
||||
extern struct namespace ap_namespace;
|
||||
|
||||
struct ap_node {
|
||||
struct util_list_node node;
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
struct mdev_cb_data {
|
||||
struct util_list *adapters;
|
||||
struct util_list *domains;
|
||||
|
||||
@@ -86,7 +86,7 @@ By default lszdev displays information from both the active and the persistent
|
||||
configuration, and, if available, from the auto-configuration.
|
||||
.PP
|
||||
.SS Output Format
|
||||
In list format, lszdev uses values with the following meaning for the persistent colums (PERS):
|
||||
In list format, lszdev uses values with the following meaning for the persistent columns (PERS):
|
||||
|
||||
.B yes
|
||||
.CL A persistent, non-site specific configuration exists; No site specific configurations available.
|
||||
|
||||
@@ -53,18 +53,18 @@ static void ap_mask_list_changes(const char *source, const char *target,
|
||||
struct util_list *adds, struct util_list *subs)
|
||||
{
|
||||
int i;
|
||||
struct ap_node *node;
|
||||
struct vfio_ap_node *node;
|
||||
|
||||
for (i = 0; i <= AP_MAX_MASK_VALUE; i++) {
|
||||
if (ap_test_bit(i, source)) {
|
||||
if (!ap_test_bit(i, target)) {
|
||||
node = misc_malloc(sizeof(struct ap_node));
|
||||
node = misc_malloc(sizeof(struct vfio_ap_node));
|
||||
node->id = i;
|
||||
util_list_add_tail(subs, node);
|
||||
}
|
||||
} else {
|
||||
if (ap_test_bit(i, target)) {
|
||||
node = misc_malloc(sizeof(struct ap_node));
|
||||
node = misc_malloc(sizeof(struct vfio_ap_node));
|
||||
node->id = i;
|
||||
util_list_add_tail(adds, node);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ static bool ap_validate_mask_input(char *mask, const char *input,
|
||||
* Translate the mask value into a list of additions/removals for later
|
||||
* conflict analysis.
|
||||
*/
|
||||
util_list_init(adds, struct ap_node, node);
|
||||
util_list_init(adds, struct vfio_ap_node, node);
|
||||
ap_mask_list_changes(mask, newmask, adds, subs);
|
||||
strcpy(mask, newmask);
|
||||
goto out;
|
||||
@@ -948,8 +948,8 @@ static exit_code_t ap_check_mask_changes(config_t config,
|
||||
struct util_list all_ap;
|
||||
struct util_list all_aq;
|
||||
|
||||
util_list_init(&all_ap, struct ap_node, node);
|
||||
util_list_init(&all_aq, struct ap_node, node);
|
||||
util_list_init(&all_ap, struct vfio_ap_node, node);
|
||||
util_list_init(&all_aq, struct vfio_ap_node, node);
|
||||
|
||||
/* Validate the mask changes against existing vfio-ap devices */
|
||||
if (SCOPE_ACTIVE(config) && (!util_list_is_empty(add_ap) ||
|
||||
@@ -996,14 +996,14 @@ static exit_code_t ap_devtype_write_settings(struct devtype *dt,
|
||||
exit_code_t rc = EXIT_OK;
|
||||
/* No kernel or module parameters exist for AP device driver. */
|
||||
|
||||
util_list_init(&add_ap, struct ap_node, node);
|
||||
util_list_init(&add_aq, struct ap_node, node);
|
||||
util_list_init(&sub_ap, struct ap_node, node);
|
||||
util_list_init(&sub_aq, struct ap_node, node);
|
||||
util_list_init(&add_p_ap, struct ap_node, node);
|
||||
util_list_init(&add_p_aq, struct ap_node, node);
|
||||
util_list_init(&sub_p_ap, struct ap_node, node);
|
||||
util_list_init(&sub_p_aq, struct ap_node, node);
|
||||
util_list_init(&add_ap, struct vfio_ap_node, node);
|
||||
util_list_init(&add_aq, struct vfio_ap_node, node);
|
||||
util_list_init(&sub_ap, struct vfio_ap_node, node);
|
||||
util_list_init(&sub_aq, struct vfio_ap_node, node);
|
||||
util_list_init(&add_p_ap, struct vfio_ap_node, node);
|
||||
util_list_init(&add_p_aq, struct vfio_ap_node, node);
|
||||
util_list_init(&sub_p_ap, struct vfio_ap_node, node);
|
||||
util_list_init(&sub_p_aq, struct vfio_ap_node, node);
|
||||
write_ap = write_aq = write_udev = false;
|
||||
|
||||
rc = ap_get_lock();
|
||||
|
||||
@@ -251,11 +251,12 @@ exit_code_t udev_ccwgroup_write_device(struct device *dev, bool autoconf)
|
||||
fprintf(fd, "# Generated by chzdev\n");
|
||||
|
||||
/* Triggers. */
|
||||
fprintf(fd, "ACTION==\"add\", SUBSYSTEM==\"drivers\", "
|
||||
fprintf(fd, "ACTION!=\"add|change\", GOTO=\"%s\"\n", end_label);
|
||||
fprintf(fd, "SUBSYSTEM==\"drivers\", "
|
||||
"KERNEL==\"%s\", GOTO=\"%s\"\n", drv, group_label);
|
||||
for (i = 0; i < devid.num; i++) {
|
||||
chan_id = ccw_devid_to_str(&devid.devid[i]);
|
||||
fprintf(fd, "ACTION==\"add\", SUBSYSTEM==\"ccw\", "
|
||||
fprintf(fd, "SUBSYSTEM==\"ccw\", "
|
||||
"KERNEL==\"%s\", DRIVER==\"%s\", "
|
||||
"GOTO=\"%s\"\n", chan_id, drv, group_label);
|
||||
free(chan_id);
|
||||
@@ -275,7 +276,19 @@ exit_code_t udev_ccwgroup_write_device(struct device *dev, bool autoconf)
|
||||
end_label);
|
||||
free(chan_id);
|
||||
}
|
||||
fprintf(fd, "ATTR{[drivers/ccwgroup:%s]group}=\"", drv);
|
||||
|
||||
/* Parallel execution of the ccwgroup devices udev rule can lead to
|
||||
* udevadm warnings. To prevent this, serialize the execution.
|
||||
*/
|
||||
fprintf(fd, "\n# Note: Serialize add events on different devices to"
|
||||
" change event on single\n# base device to prevent duplicate"
|
||||
" concurrent grouping attempts\n");
|
||||
|
||||
/* The new change uevent should be generated to the base-device only */
|
||||
chan_id = ccw_devid_to_str(&devid.devid[0]);
|
||||
fprintf(fd, "ACTION==\"add\", ATTR{[ccw/%s]uevent}=\"change\"\n", chan_id);
|
||||
fprintf(fd, "ACTION==\"change\", ATTR{[drivers/ccwgroup:%s]group}=\"", drv);
|
||||
free(chan_id);
|
||||
for (i = 0; i < devid.num; i++) {
|
||||
chan_id = ccw_devid_to_str(&devid.devid[i]);
|
||||
fprintf(fd, "%s%s", i > 0 ? "," : "", chan_id);
|
||||
|
||||
@@ -695,6 +695,8 @@ static void kdump_select_prod_init(void)
|
||||
unsigned long prefix, ptr, count, tv_sec, i;
|
||||
struct timeval timeval;
|
||||
|
||||
util_log_print(UTIL_LOG_TRACE, "DFI kdump production system dump initialization\n");
|
||||
|
||||
if (g.opts.select_specified && !l.kdump_base)
|
||||
ERR_EXIT("The \"--select\" option is not possible with this "
|
||||
"dump");
|
||||
@@ -712,9 +714,10 @@ static void kdump_select_prod_init(void)
|
||||
}
|
||||
dfi_cpu_info_init(DFI_CPU_CONTENT_ALL);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (dfi_mem_virt_read(ptr + i * sizeof(long), &prefix,
|
||||
if (dfi_mem_virt_read(dfi_vm_vtop(ptr) + i * sizeof(long), &prefix,
|
||||
sizeof(prefix)))
|
||||
continue;
|
||||
prefix = dfi_vm_vtop(prefix);
|
||||
if (prefix == 0)
|
||||
continue;
|
||||
if (prefix % 0x1000)
|
||||
@@ -736,7 +739,7 @@ static void utsname_init(void)
|
||||
|
||||
if (dfi_vmcoreinfo_symbol(&ptr, "init_uts_ns"))
|
||||
return;
|
||||
if (dfi_mem_virt_read(ptr, buf, sizeof(buf)))
|
||||
if (dfi_mem_virt_read(dfi_vm_vtop(ptr), buf, sizeof(buf)))
|
||||
return;
|
||||
utsname = memchr(buf, 'L', sizeof(buf) - sizeof(*utsname));
|
||||
if (!utsname)
|
||||
|
||||
@@ -30,10 +30,6 @@ int pt_load_add(const struct zg_fh *fh, const Elf64_Phdr *phdr, void **data,
|
||||
__func__, phdr->p_paddr, phdr->p_vaddr, phdr->p_offset, phdr->p_filesz,
|
||||
phdr->p_memsz);
|
||||
|
||||
if (phdr->p_paddr != phdr->p_vaddr) {
|
||||
STDERR("Dump file \"%s\" is a user space core dump\n", fh->path);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (phdr->p_memsz == 0)
|
||||
return -EINVAL;
|
||||
if (phdr->p_offset + phdr->p_filesz > zg_size(fh))
|
||||
|
||||
@@ -439,6 +439,10 @@ void dfi_mem_unmap(u64 start, u64 size)
|
||||
struct dfi_mem_chunk *mem_chunk, *tmp;
|
||||
u64 end = start + size - 1;
|
||||
|
||||
util_log_print(UTIL_LOG_TRACE,
|
||||
"DFI mem unmap start 0x%016lx, size 0x%016lx\n",
|
||||
start, size);
|
||||
|
||||
util_list_iterate_safe(&l.mem_virt.chunk_list, mem_chunk, tmp) {
|
||||
/*
|
||||
* Chunk not hit?
|
||||
@@ -504,6 +508,10 @@ void dfi_mem_unmap(u64 start, u64 size)
|
||||
*/
|
||||
void dfi_mem_map(u64 start, u64 size, u64 start_phys)
|
||||
{
|
||||
util_log_print(UTIL_LOG_TRACE,
|
||||
"DFI mem map start 0x%016lx, size 0x%016lx, base 0x%016lx\n",
|
||||
start, size, start_phys);
|
||||
|
||||
if (mem_range_mapped(start, size)) {
|
||||
dfi_mem_map_print(false);
|
||||
ABORT("Map request for already mapped region (%llx/%llx/%llx)",
|
||||
|
||||
@@ -346,11 +346,19 @@ int dfi_s390_init_gen(bool extended)
|
||||
l.extended = extended;
|
||||
if (read_s390_hdr() != 0)
|
||||
return -ENODEV;
|
||||
zg_ioctl(g.fh, BLKSSZGET, &l.blk_size, "BLKSSZGET", ZG_CHECK);
|
||||
if (!extended)
|
||||
if (!extended) {
|
||||
rc = mem_chunks_add();
|
||||
else
|
||||
} else {
|
||||
/*
|
||||
* A device block size is required for a decompression of
|
||||
* s390_ext dump with compressed dump segments.
|
||||
* Since dumps in s390_ext format can reside on DASD partition
|
||||
* only, bail out upon ioctl error on BLKSSZGET.
|
||||
*/
|
||||
if (zg_ioctl(g.fh, BLKSSZGET, &l.blk_size, "BLKSSZGET", ZG_CHECK_NONE))
|
||||
return -ENODEV;
|
||||
rc = mem_chunks_add_ext();
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = df_s390_cpu_info_add(&l.hdr, l.hdr.mem_size);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "dfi_mem_chunk.h"
|
||||
#include "dfi_vmcoreinfo.h"
|
||||
|
||||
#include "boot/os_info.h"
|
||||
|
||||
#ifdef __s390x__
|
||||
#define LC_VMCORE_INFO 0xe0c
|
||||
#else
|
||||
@@ -27,26 +29,14 @@
|
||||
#endif
|
||||
|
||||
#define LC_OS_INFO 0xe18
|
||||
#define OS_INFO_MAGIC 0x4f53494e464f535aULL /* OSINFOSZ */
|
||||
|
||||
struct os_info {
|
||||
u64 magic;
|
||||
u32 csum;
|
||||
u16 version_major;
|
||||
u16 version_minor;
|
||||
u64 crashkernel_addr;
|
||||
u64 crashkernel_size;
|
||||
u64 vmcoreinfo_addr;
|
||||
u64 vmcoreinfo_size;
|
||||
u32 vmcoreinfo_csum;
|
||||
u64 reipl_block_addr;
|
||||
u64 reipl_block_size;
|
||||
u32 reipl_block_csum;
|
||||
u64 init_fn_addr;
|
||||
u64 init_fn_size;
|
||||
u32 init_fn_csum;
|
||||
u8 reserved[4004];
|
||||
} __packed;
|
||||
struct vm_info {
|
||||
u64 identity_base;
|
||||
u64 kaslr_offset;
|
||||
u64 kaslr_offset_phys;
|
||||
u64 amode31_start;
|
||||
u64 amode31_end;
|
||||
};
|
||||
|
||||
/*
|
||||
* File local static data
|
||||
@@ -54,6 +44,7 @@ struct os_info {
|
||||
static struct {
|
||||
char *vmcoreinfo;
|
||||
struct os_info *os_info;
|
||||
struct vm_info *vm_info;
|
||||
} l;
|
||||
|
||||
static u32 os_info_csum(struct os_info *os_info)
|
||||
@@ -71,6 +62,7 @@ static struct os_info *os_info_get(void)
|
||||
|
||||
if (dfi_mem_virt_read(LC_OS_INFO, &addr, sizeof(addr)))
|
||||
return NULL;
|
||||
util_log_print(UTIL_LOG_DEBUG, "DFI osinfo addr: 0x%016lx\n", addr);
|
||||
if (addr % 0x1000)
|
||||
return NULL;
|
||||
if (dfi_mem_virt_read(addr, &os_info, sizeof(os_info)))
|
||||
@@ -79,9 +71,46 @@ static struct os_info *os_info_get(void)
|
||||
return NULL;
|
||||
if (os_info.csum != os_info_csum(&os_info))
|
||||
return NULL;
|
||||
|
||||
util_log_print(UTIL_LOG_DEBUG, "DFI found valid osinfo!\n");
|
||||
return &os_info;
|
||||
}
|
||||
|
||||
static struct vm_info *vm_info_get(void)
|
||||
{
|
||||
static struct vm_info vm_info = { 0 };
|
||||
|
||||
util_log_print(UTIL_LOG_TRACE, "DFI read vm_info\n");
|
||||
|
||||
vm_info.identity_base = l.os_info->entry[OS_INFO_IDENTITY_BASE].val;
|
||||
if (vm_info.identity_base == 0)
|
||||
return NULL;
|
||||
vm_info.kaslr_offset = l.os_info->entry[OS_INFO_KASLR_OFFSET].val;
|
||||
vm_info.kaslr_offset_phys = l.os_info->entry[OS_INFO_KASLR_OFF_PHYS].val;
|
||||
vm_info.amode31_start = l.os_info->entry[OS_INFO_AMODE31_START].val;
|
||||
vm_info.amode31_end = l.os_info->entry[OS_INFO_AMODE31_END].val;
|
||||
|
||||
return &vm_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert virual address in the dump to the physical address using
|
||||
* vm_info data derived from os_info
|
||||
*/
|
||||
u64 dfi_vm_vtop(u64 vaddr)
|
||||
{
|
||||
if (!l.vm_info)
|
||||
return vaddr;
|
||||
if (vaddr < LOWCORE_SIZE)
|
||||
return vaddr;
|
||||
if ((vaddr < l.vm_info->amode31_end) &&
|
||||
(vaddr >= l.vm_info->amode31_start))
|
||||
return vaddr;
|
||||
if (vaddr < l.vm_info->kaslr_offset)
|
||||
return vaddr - l.vm_info->identity_base;
|
||||
return vaddr - l.vm_info->kaslr_offset + l.vm_info->kaslr_offset_phys;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize vmcoreinfo
|
||||
*/
|
||||
@@ -94,11 +123,13 @@ void dfi_vmcoreinfo_init(void)
|
||||
util_log_print(UTIL_LOG_TRACE, "DFI vmcoreinfo initialization\n");
|
||||
|
||||
l.os_info = os_info_get();
|
||||
if (l.os_info)
|
||||
l.vm_info = vm_info_get();
|
||||
|
||||
if (l.os_info && l.os_info->vmcoreinfo_size) {
|
||||
if (l.os_info && l.os_info->entry[OS_INFO_VMCOREINFO].size) {
|
||||
util_log_print(UTIL_LOG_DEBUG, "DFI found valid osinfo\n");
|
||||
addr = l.os_info->vmcoreinfo_addr;
|
||||
size = l.os_info->vmcoreinfo_size;
|
||||
addr = l.os_info->entry[OS_INFO_VMCOREINFO].addr;
|
||||
size = l.os_info->entry[OS_INFO_VMCOREINFO].size;
|
||||
} else {
|
||||
if (dfi_mem_virt_read(LC_VMCORE_INFO, &addr, sizeof(addr)))
|
||||
return;
|
||||
@@ -175,6 +206,7 @@ static int vmcoreinfo_item_ulong(unsigned long *val, const char *fmt,
|
||||
int rc;
|
||||
|
||||
rc = vmcoreinfo_item(str, sizeof(str), fmt, sym);
|
||||
util_log_print(UTIL_LOG_DEBUG, "DFI vmcoreinfo symbol %s : %s\n", sym, str);
|
||||
if (rc)
|
||||
return rc;
|
||||
*val = strtoul(str, NULL, base);
|
||||
|
||||
@@ -16,5 +16,6 @@ int dfi_vmcoreinfo_offset(unsigned long *offs, const char *sym);
|
||||
int dfi_vmcoreinfo_size(unsigned long *size, const char *sym);
|
||||
int dfi_vmcoreinfo_length(unsigned long *len, const char *sym);
|
||||
int dfi_vmcoreinfo_val(unsigned long *val, const char *sym);
|
||||
u64 dfi_vm_vtop(u64 vaddr);
|
||||
|
||||
#endif /* DFI_VMCOREINFO_H */
|
||||
|
||||
@@ -35,7 +35,7 @@ zfcpdump_part: zfcpdump.o zfcpdump_part.o
|
||||
|
||||
$(ZFCPDUMP_INITRD): cpioinit zfcpdump_part
|
||||
$(CPIOINIT) zfcpdump_part > $@.tmp
|
||||
$(GZIP) -f $@.tmp
|
||||
$(GZIP) -f -n $@.tmp
|
||||
$(MV) $@.tmp.gz $(ZFCPDUMP_INITRD)
|
||||
|
||||
scripts: $(INSTALL_SCRIPTS)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -294,32 +293,38 @@ static int copy_table_init(int fd, struct copy_table *table)
|
||||
*/
|
||||
static int copy_table_entry_write(int fdin, int fdout,
|
||||
const struct copy_table_entry *entry,
|
||||
unsigned long offset)
|
||||
unsigned long disk_offset)
|
||||
{
|
||||
unsigned long buf_size, bytes_left, off;
|
||||
void *map;
|
||||
static unsigned char buf[COPY_BUF_SIZE];
|
||||
unsigned long bytes_left, count;
|
||||
ssize_t bytes_read, bytes_written;
|
||||
|
||||
if (entry->size == 0)
|
||||
return 0;
|
||||
off = entry->off;
|
||||
bytes_left = entry->size;
|
||||
if (lseek(fdout, entry->off + offset, SEEK_SET) < 0)
|
||||
if (bytes_left == 0)
|
||||
return 0;
|
||||
if (lseek(fdin, entry->off, SEEK_SET) < 0)
|
||||
return -1;
|
||||
if (lseek(fdout, disk_offset + entry->off, SEEK_SET) < 0)
|
||||
return -1;
|
||||
PRINT_TRACE("Write dump: vmcore offset=0x%016lx disk offset=0x%016lx bytes=0x%016lx\n",
|
||||
entry->off, disk_offset + entry->off, bytes_left);
|
||||
while (bytes_left > 0) {
|
||||
buf_size = MIN(COPY_BUF_SIZE, bytes_left);
|
||||
map = mmap(0, buf_size, PROT_READ, MAP_SHARED, fdin, off);
|
||||
if (map == (void *)-1) {
|
||||
PRINT_PERR("Mapping failed\n");
|
||||
count = MIN(COPY_BUF_SIZE, bytes_left);
|
||||
bytes_read = read(fdin, buf, count);
|
||||
if (bytes_read < 0) {
|
||||
PRINT_PERR("Read from /proc/vmcore failed: offset=0x%016lx bytes=0x%016lx\n",
|
||||
entry->off + entry->size - bytes_left, count);
|
||||
return -1;
|
||||
}
|
||||
if (write(fdout, map, buf_size) < 0) {
|
||||
PRINT_PERR("Write to partition failed\n");
|
||||
bytes_written = write(fdout, buf, bytes_read);
|
||||
if (bytes_written < 0) {
|
||||
PRINT_PERR("Write to partition failed: offset=0x%016lx bytes=0x%016lx\n",
|
||||
disk_offset + entry->off + entry->size - bytes_left,
|
||||
bytes_read);
|
||||
return -1;
|
||||
}
|
||||
munmap(map, buf_size);
|
||||
bytes_left -= buf_size;
|
||||
off += buf_size;
|
||||
show_progress(buf_size);
|
||||
bytes_left -= bytes_written;
|
||||
show_progress(bytes_written);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -667,8 +667,7 @@ function check_free_space_mileage() {
|
||||
|
||||
|
||||
function check_blktrace() {
|
||||
which blktrace >/dev/null 2>&1;
|
||||
if [ $? -ne 0 ]; then
|
||||
if ! command -v blktrace >/dev/null 2>&1; then
|
||||
echo "$WRP_TOOLNAME: Could not find blktrace. Please make sure that the blktrace package is installed and matches the level in the documentation.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
@@ -196,7 +196,7 @@ int add_to_agg(struct aggr_data *agg_data, struct message *msg,
|
||||
else if (msg->type == f_hdr->msgid_zfcpdd)
|
||||
aggregate_zfcpdd(agg_data, msg);
|
||||
else {
|
||||
fprintf(stderr, "%s: Unknow msg id: %d,"
|
||||
fprintf(stderr, "%s: Unknown msg id: %d,"
|
||||
" discarding\n", toolname, msg->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,6 @@ static inline int target_parameters_are_set(struct job_target_data *td)
|
||||
|
||||
int job_get(int argc, char* argv[], struct job_data** data);
|
||||
void job_free(struct job_data* job);
|
||||
void free_target_data(struct job_target_data *td);
|
||||
int type_from_target(char *target, disk_type_t *type);
|
||||
int check_job_dump_images(struct job_dump_data* dump, char* name);
|
||||
int check_job_images_ngdump(struct job_dump_data* dump, char* name);
|
||||
|
||||
@@ -304,6 +304,7 @@ static int add_component_file_range(struct install_set *bis,
|
||||
address_t load_address,
|
||||
size_t trailer, void *component,
|
||||
int add_files,
|
||||
struct job_target_data *target,
|
||||
int comp_id, int menu_idx,
|
||||
int program_table_id)
|
||||
{
|
||||
@@ -338,15 +339,8 @@ static int add_component_file_range(struct install_set *bis,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Make sure that file is on target device.
|
||||
* For this, retrieve info of the underlying disk without
|
||||
* any user hints
|
||||
*/
|
||||
struct job_target_data tmp = {.source = source_unknown};
|
||||
|
||||
rc = disk_get_info_from_file(filename, &tmp, &file_info);
|
||||
free_target_data(&tmp);
|
||||
/* Make sure file is on correct device */
|
||||
rc = disk_get_info_from_file(filename, target, &file_info);
|
||||
if (rc)
|
||||
return -1;
|
||||
if (file_info->device != bis->info->device) {
|
||||
@@ -383,11 +377,12 @@ write_segment_table:
|
||||
static int add_component_file(struct install_set *bis, const char *filename,
|
||||
address_t load_address, size_t trailer,
|
||||
void *component, int add_files,
|
||||
int comp_id, int menu_idx, int program_table_id)
|
||||
struct job_target_data *target, int comp_id,
|
||||
int menu_idx, int program_table_id)
|
||||
{
|
||||
return add_component_file_range(bis, filename, NULL, load_address,
|
||||
trailer, component, add_files,
|
||||
comp_id, menu_idx,
|
||||
target, comp_id, menu_idx,
|
||||
program_table_id);
|
||||
}
|
||||
|
||||
@@ -549,7 +544,8 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
bool add_envblk, struct job_envblk_data *envblk,
|
||||
struct job_ipl_data *ipl, disk_blockptr_t *program,
|
||||
int verbose, int add_files, component_header_type type,
|
||||
int is_secure, int menu_idx, int program_table_id)
|
||||
struct job_target_data *target, int is_secure,
|
||||
int menu_idx, int program_table_id)
|
||||
{
|
||||
struct signature_header sig_head;
|
||||
size_t ramdisk_size, image_size;
|
||||
@@ -671,7 +667,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
/* Add stage 3 loader to bootmap */
|
||||
rc = add_component_file(bis, ZIPL_STAGE3_PATH, STAGE3_LOAD_ADDRESS,
|
||||
signature_size, VOID_ADD(table, offset), 1,
|
||||
COMPONENT_ID_LOADER, menu_idx,
|
||||
target, COMPONENT_ID_LOADER, menu_idx,
|
||||
program_table_id);
|
||||
if (rc) {
|
||||
error_text("Could not add internal loader file '%s'",
|
||||
@@ -749,7 +745,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
|
||||
rc = add_component_file(bis, ipl->common.image, ipl->common.image_addr,
|
||||
signature_size, VOID_ADD(table, offset),
|
||||
add_files, COMPONENT_ID_KERNEL_IMAGE,
|
||||
add_files, target, COMPONENT_ID_KERNEL_IMAGE,
|
||||
menu_idx, program_table_id);
|
||||
if (rc) {
|
||||
error_text("Could not add image file '%s'", ipl->common.image);
|
||||
@@ -809,7 +805,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
ipl->common.ramdisk_addr,
|
||||
signature_size,
|
||||
VOID_ADD(table, offset),
|
||||
add_files, COMPONENT_ID_RAMDISK,
|
||||
add_files, target, COMPONENT_ID_RAMDISK,
|
||||
menu_idx, program_table_id);
|
||||
if (rc) {
|
||||
error_text("Could not add ramdisk '%s'",
|
||||
@@ -865,7 +861,7 @@ static int add_ipl_program(struct install_set *bis, char *filename,
|
||||
rc = add_component_file_range(bis, filename, ®,
|
||||
ipl->envblk_addr, 0,
|
||||
VOID_ADD(table, offset),
|
||||
0,
|
||||
0, target,
|
||||
COMPONENT_ID_ENVBLK,
|
||||
menu_idx,
|
||||
program_table_id);
|
||||
@@ -897,6 +893,7 @@ static int add_segment_program(struct install_set *bis,
|
||||
struct job_segment_data *segment,
|
||||
disk_blockptr_t *program, int verbose,
|
||||
int add_files, component_header_type type,
|
||||
struct job_target_data *target,
|
||||
int program_table_id)
|
||||
{
|
||||
void *table;
|
||||
@@ -916,7 +913,7 @@ static int add_segment_program(struct install_set *bis,
|
||||
printf(" segment file......: %s\n", segment->segment);
|
||||
|
||||
rc = add_component_file(bis, segment->segment, segment->segment_addr, 0,
|
||||
VOID_ADD(table, offset), add_files,
|
||||
VOID_ADD(table, offset), add_files, target,
|
||||
COMPONENT_ID_SEGMENT_FILE, 0 /* menu_idx */,
|
||||
program_table_id);
|
||||
if (rc) {
|
||||
@@ -999,7 +996,7 @@ static int add_dump_program(struct install_set *bis, struct job_data *job,
|
||||
ipl.common.parmline = dump->common.parmline;
|
||||
ipl.common.parm_addr = dump->common.parm_addr;
|
||||
return add_ipl_program(bis, NULL, false, NULL, &ipl, program,
|
||||
verbose, 1, type, SECURE_BOOT_DISABLED,
|
||||
verbose, 1, type, target, SECURE_BOOT_DISABLED,
|
||||
0 /* menu_idx */, program_table_id);
|
||||
}
|
||||
|
||||
@@ -1044,7 +1041,8 @@ static int build_program_table(struct job_data *job,
|
||||
true, &job->envblk, &job->data.ipl,
|
||||
&table[0], verbose || job->command_line,
|
||||
job->add_files, component_header,
|
||||
job->is_secure, 0, program_table_id);
|
||||
&job->target, job->is_secure, 0,
|
||||
program_table_id);
|
||||
break;
|
||||
case job_segment:
|
||||
if (bis->print_details) {
|
||||
@@ -1057,7 +1055,7 @@ static int build_program_table(struct job_data *job,
|
||||
rc = add_segment_program(bis, &job->data.segment, &table[0],
|
||||
verbose || job->command_line,
|
||||
job->add_files, COMPONENT_HEADER_IPL,
|
||||
program_table_id);
|
||||
&job->target, program_table_id);
|
||||
break;
|
||||
case job_dump_partition:
|
||||
/* Only useful for a partition dump that uses a dump kernel*/
|
||||
@@ -1116,7 +1114,7 @@ static int build_program_table(struct job_data *job,
|
||||
&table[job->data.menu.entry[i].pos],
|
||||
verbose || job->command_line,
|
||||
job->add_files, component_header,
|
||||
is_secure, i,
|
||||
&job->target, is_secure, i,
|
||||
program_table_id);
|
||||
break;
|
||||
case job_print_usage:
|
||||
|
||||
@@ -528,9 +528,6 @@ static int disk_set_info_complete(struct job_target_data *td,
|
||||
* config file, or special "target options" of zipl tool.
|
||||
* If target parameters were specified by user, then the step 1 above
|
||||
* is skipped.
|
||||
|
||||
* To exclude any user assumptions about the DEVICE, this function
|
||||
* should be called with TD pointing to a zeroed structure.
|
||||
*
|
||||
* DEVICE: logical, or physical device, optionally formated with a
|
||||
* file system.
|
||||
|
||||
@@ -370,7 +370,8 @@ get_command_line(int argc, char* argv[], struct command_line* line)
|
||||
}
|
||||
|
||||
|
||||
void free_target_data(struct job_target_data *data)
|
||||
static void
|
||||
free_target_data(struct job_target_data* data)
|
||||
{
|
||||
free(data->bootmap_dir);
|
||||
free(data->targetbase);
|
||||
|
||||
@@ -908,7 +908,7 @@ static const struct util_opt configure_options[] = {
|
||||
"server's certificate. For self signed EKMF Web server "
|
||||
"certificates, this is the default. Use option "
|
||||
"'--tls-pin-server-cert' to ensure the self signed "
|
||||
"certificate's authenticity explicitely. CA signed "
|
||||
"certificate's authenticity explicitly. CA signed "
|
||||
"EKMF Web server certificates are verified by default. "
|
||||
"This option disables the verification.",
|
||||
.command = KMS_COMMAND_CONFIGURE,
|
||||
|
||||
@@ -1382,7 +1382,7 @@ static int _keystore_lock_repository(struct keystore *keystore)
|
||||
if (fchown(keystore->lock_fd, geteuid(),
|
||||
keystore->owner) != 0) {
|
||||
rc = -errno;
|
||||
warnx("chown faild on file '%s': %s", lock_file_name,
|
||||
warnx("chown failed on file '%s': %s", lock_file_name,
|
||||
strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ a software RAID can transparently re-integrate the recovered device. For
|
||||
example, after a failure and recovery, a software RAID can resync a stroage
|
||||
device or a network interface can be re-integrated in a bond. In contrast to
|
||||
a complete shut down, the device driver remains active and informs higher
|
||||
layers of both the occurence of an error state and the eventual recovery.
|
||||
layers of both the occurrence of an error state and the eventual recovery.
|
||||
.PP
|
||||
.
|
||||
.OD deconfigure "" "DEVICE"
|
||||
|
||||
Reference in New Issue
Block a user