Compare commits

...

32 Commits

Author SHA1 Message Date
Jan Höppner
4c922b105b New release s390-tools-2.34.0
Signed-off by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 15:17:42 +02:00
Mikhail Zaslonko
4b19b9d950 zdump/dfi_s390: Get rid of device type check for s390_ext dump
Simplify ioctl error processing logic for "BLKSSZGET" operation.

Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Ingo Franzki
cee4bb4995 libkmipclient: Fix typo in debug message
Fix copy & paste error in debug message

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Ingo Franzki
c98d8e7629 libkmipclient: Remove superfluous break
A double break in a switch does not make any sense, remove it.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Joern Siglen
96084339f5 dbginfo.sh: update/add additional DASD collection
We changed lscss for more detailed output.
Adding use of dasdview for a detailed view on DASD storage.
This data will be collected in a separate file, as many DASDs might flood
the runtime.out
Also updated man pages as a new step is added

Reviewed-by: Stefan Hberland <sth@linux.ibm.com>
Signed-off-by: Joern Siglen <siglen@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Harald Freudenberger
f8d5b4b341 rust/pvapconfig: add dead_code pragmas to suppress warnings
The ap.rs code is already prepared for possible support
for CCA mode APQNs for the Secure Execution environment.
However, this patch marks these fields and structs with
pragma allow(dead_code) to prevent warnings during cargo
build of pvapconfig.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Matthew Rosato
5806c4e1f4 ap_tools/ap-check: implement get capabilities callout
Add a new action type 'capabilities' for the 'get' event.  This
will return a JSON list of events and actions that the callout
script recognizes and actually does something with.  It omits
events like 'notify' and actions like 'list' that ap-check
currently ignores.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:06 +02:00
Matthew Rosato
9d199e06cb ap_tools/ap-check: implement dynamic config during live modify
mdevctl introduces a new event type 'live' with action 'modify',
indicating that the specified configuration changes should be
made dynamically if possible.  Use this as a trigger to perform
dynamic configuration changes to the specified vfio-ap device
if it is active.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Matthew Rosato
f7425a08d1 ap_tools/ap-check: refactor active config checking
Create a single routine to perform conflict analysis for a
given device against the active configuration.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Matthew Rosato
f6a97902c3 libap: handle reading ap_config attribute
While unlikely, it is possible for a vfio-ap configuration JSON
to include the 'ap_config' attribute.  In this case, process it
by overwriting the current list of adapters, domains and control
domains for the associated vfio-ap device struct.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Matthew Rosato
962af1a90e libap: add routines to generate masks for vfio_ap_device
Add routines to generate mask values for the adapters, domains and
control domains for a specified vfio_ap_device struct.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Matthew Rosato
46dadc8cc4 libap: add routine to check for dynamic config support
For a given vfio-ap mdev, determine whether or not the device will
need dynamic config operations.  This boils down to whether or not
the device is currently active + whether or not the kernel is
detected to support dynamic config operations (via the
'ap_config' sysfs attribute).

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Matthew Rosato
9c8d117cc2 zdev: remove duplicate ap_node structure
There is already an identical vfio_ap_node defined in libap, use
that instead.  Also remove one awkard usage of struct ap_node in
libap.

Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-08-01 14:26:05 +02:00
Vineeth Vijayan
d7b3196286 zdev: fix warning about failed ATTR writes by udev
The qeth-udev-rule execution logs a warning as below in the journalfs.

Failed to write ATTR{/sys/bus/ccwgroup/drivers/qeth/group}, \
ignoring: Invalid argument

This occurs because the udev rule for qeth devices is triggered by
multiple ccw devices and can be invoked in parallel. This can lead to a
situation where each of the three parallel-running udev rules tries to
group the devices simultaneously. As a result, only the first rule
succeeds, while the others fail with an -EINVAL error because the CCW
devices have already been grouped.

To prevent this, schedule a new change uevent for the base device, which
will verify the sysfs before attempting the grouping. The change event is
triggered by all three devices, ensuring that the actual write to the
attribute occurs only once and only when the sysfs attribute is ready.

Hence the add events on different devices are serialized to change event
on the base device, which then prevent duplicate concurrent grouping
attempts.

Suggested-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-07-08 09:25:12 +02:00
Alexander Egorenkov
b6c30404bc zfcpdump: drop use of mmap() for /proc/vmcore
The function copy_table_entry_write() maps/unmaps /proc/vmcore for each
64kB of the file in order to write its content to a dump partition.
This requires a page allocation of order 2 in kernel (crst_table_alloc)
each time a mmap() syscall is performed and which cannot always be
fulfilled due to external memory fragmentation. And this in turn
results in a OOM kernel panic while writing /proc/vmcore content to
a dump partition. To make zfcpdump more robust in the face of such
problems with page allocations of order > 0, we use a simple file
read/write loop to transfer the content of /proc/vmcore to a dump
partition. This solution is less efficient (by not much) than the old
one with mmap() because it requires additional user space copy but
we trade off here efficiency for robustness which is more important
for zfcpdump.

We use a statically allocated buffer to read data into from /proc/vmcore
and write to a dump partition to avoid repeated use of the memory
mapping kernel path which would be required for a buffer allocated
dynamically at each entry of copy_table_entry_write().

Another possible and very convenient solution would be to use sendfile()
which would avoid any user space copies but, unfortunately, sendfile()
doesn't work with large /proc files.

Example of failed mmap() call for /proc/vmcore
==============================================

  [   26.568654] init invoked oom-killer: gfp_mask=0x40cc0(GFP_KERNEL|__GFP_COMP), order=2, oom_score_adj=0
  [   26.568665] CPU: 0 PID: 1 Comm: init Not tainted 6.9.0-20240504.rc6.git0.9986ea583f39.300.fc39.s390x+zfcpdump #1
  [   26.568668] Hardware name: IBM 3931 A01 704 (LPAR)
  [   26.568669] Call Trace:
  [   26.568671]  [<000003ffe03277c6>] dump_stack_lvl+0x76/0x98
  [   26.568676]  [<000003ffe00f15c8>] dump_header+0x58/0x2d0
  [   26.568680]  [<000003ffe00f219a>] out_of_memory+0x252/0x348
  [   26.568683]  [<000003ffe0132f3e>] __alloc_pages_slowpath.constprop.0+0x65e/0x7c0
  [   26.568686]  [<000003ffe01331a4>] __alloc_pages+0x104/0x128
  [   26.568688]  [<000003ffe001ab46>] crst_table_alloc+0x2e/0xa0
  [   26.568693]  [<000003ffe01164c4>] __pmd_alloc+0x24/0x160
  [   26.568696]  [<000003ffe0116650>] pmd_alloc+0x50/0x68
  [   26.568698]  [<000003ffe0117be4>] remap_pfn_range_notrack+0x194/0x310
  [   26.568701]  [<000003ffe0117d7c>] remap_pfn_range+0x1c/0x28
  [   26.568703]  [<000003ffe0015442>] remap_oldmem_pfn_range+0xb2/0x108
  [   26.568705]  [<000003ffe01a0544>] mmap_vmcore+0x414/0x448
  [   26.568707]  [<000003ffe01937c4>] proc_reg_mmap+0x84/0xa0
  [   26.568709]  [<000003ffe011f264>] mmap_region+0x22c/0x6f8
  [   26.568711]  [<000003ffe011fae8>] do_mmap+0x3b8/0x410
  [   26.568713]  [<000003ffe01015cc>] vm_mmap_pgoff+0x9c/0xe8
  [   26.568715]  [<000003ffe011d006>] ksys_mmap_pgoff+0x8e/0xb8
  [   26.568716]  [<000003ffe011d0f4>] __s390x_sys_old_mmap+0x74/0x90
  [   26.568718]  [<000003ffe0341a2a>] __do_syscall+0x1aa/0x220
  [   26.568720]  [<000003ffe03478b0>] system_call+0x70/0x98
  [   26.568724] Mem-Info:
  [   26.568725] active_anon:1 inactive_anon:12 isolated_anon:0
                  active_file:83590 inactive_file:93939 isolated_file:0
                  unevictable:201 dirty:17845 writeback:4
                  slab_reclaimable:4259 slab_unreclaimable:1482
                  mapped:174 shmem:0 pagetables:810
                  sec_pagetables:0 bounce:0
                  kernel_misc_reclaimable:0
                  free:2694 free_pcp:105 free_cma:0
  [   26.568729] Node 0 active_anon:4kB inactive_anon:48kB active_file:334360kB inactive_file:375756kB unevictable:804kB isolated(anon):0kB isolated(file):0kB mapped:696kB dirty:71380kB writeback:16kB shmem:0kB writeback_tmp:0kB kernel_stack:544kB pagetables:3240kB sec_pagetables:0kB all_unreclaimable? no
  [   26.568732] DMA free:10776kB boost:0kB min:3496kB low:4368kB high:5240kB reserved_highatomic:0KB active_anon:4kB inactive_anon:48kB active_file:334360kB inactive_file:375756kB unevictable:804kB writepending:71360kB present:786428kB managed:764664kB mlocked:0kB bounce:0kB free_pcp:420kB local_pcp:420kB free_cma:0kB
  [   26.568735] lowmem_reserve[]: 0 0 0
  [   26.568738] DMA: 1069*4kB (UH) 757*8kB (UH) 11*16kB (H) 6*32kB (H) 1*64kB (H) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 10764kB
  [   26.568747] 177773 total pagecache pages
  [   26.568748] 196607 pages RAM
  [   26.568748] 0 pages HighMem/MovableOnly
  [   26.568749] 5441 pages reserved
  [   26.568749] Tasks state (memory values in pages):
  [   26.568750] [  pid  ]   uid  tgid total_vm      rss rss_anon rss_file rss_shmem pgtables_bytes swapents oom_score_adj name
  [   26.568751] Out of memory and no killable processes...
  [   26.568752] Kernel panic - not syncing: System is deadlocked on memory
  [   26.568755] CPU: 0 PID: 1 Comm: init Not tainted 6.9.0-20240504.rc6.git0.9986ea583f39.300.fc39.s390x+zfcpdump #1
  [   26.568758] Hardware name: IBM 3931 A01 704 (LPAR)
  [   26.568759] Call Trace:
  [   26.568760]  [<000003ffe03277c6>] dump_stack_lvl+0x76/0x98
  [   26.568763]  [<000003ffe001f14e>] panic+0x10e/0x2e8
  [   26.568765]  [<000003ffe00f21c8>] out_of_memory+0x280/0x348
  [   26.568768]  [<000003ffe0132f3e>] __alloc_pages_slowpath.constprop.0+0x65e/0x7c0
  [   26.568771]  [<000003ffe01331a4>] __alloc_pages+0x104/0x128
  [   26.568773]  [<000003ffe001ab46>] crst_table_alloc+0x2e/0xa0
  [   26.568776]  [<000003ffe01164c4>] __pmd_alloc+0x24/0x160
  [   26.568779]  [<000003ffe0116650>] pmd_alloc+0x50/0x68
  [   26.568781]  [<000003ffe0117be4>] remap_pfn_range_notrack+0x194/0x310
  [   26.568784]  [<000003ffe0117d7c>] remap_pfn_range+0x1c/0x28
  [   26.568787]  [<000003ffe0015442>] remap_oldmem_pfn_range+0xb2/0x108
  [   26.568789]  [<000003ffe01a0544>] mmap_vmcore+0x414/0x448
  [   26.568791]  [<000003ffe01937c4>] proc_reg_mmap+0x84/0xa0
  [   26.568793]  [<000003ffe011f264>] mmap_region+0x22c/0x6f8
  [   26.568795]  [<000003ffe011fae8>] do_mmap+0x3b8/0x410
  [   26.568797]  [<000003ffe01015cc>] vm_mmap_pgoff+0x9c/0xe8
  [   26.568799]  [<000003ffe011d006>] ksys_mmap_pgoff+0x8e/0xb8
  [   26.568801]  [<000003ffe011d0f4>] __s390x_sys_old_mmap+0x74/0x90
  [   26.568803]  [<000003ffe0341a2a>] __do_syscall+0x1aa/0x220
  [   26.568805]  [<000003ffe03478b0>] system_call+0x70/0x98

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
6d15850480 zdump: Use os_info data to convert dump vaddr to paddr
For vr-kernel dumps use the offsets stored in os_info entries for
virt to phys address conversion when dump virtual address is to be
read, (e.g. vmcoreinfo symbols) using similar method as implemented
in crash-utility.
It is mainly required for reading "init_uts_ns" symbol and, in case
of crashed kdump, "lowcore_ptr" symbol along with a pointers to the
lowcore of every CPU.

Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
858da9af57 zdump: Use os_info.h from include/boot
Get rid of duplicate os_info definitions in dfi_vmcoreinfo.c

Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
a7373674bf include/boot/os_info: Add static assert for os_info size
Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
613353cd33 zdump/dfi_elf: Support core dumps of vr-kernels
Support vmcore based dumps (ngdump, zfcpdump) with uncoupled physical and
virtual addresses. For that we just remove p_paddr != p_vaddr sanity check
for elf load headers.

Acked-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Peter Oberparleiter
f6e932e0fd libutil: Make formatted meta-data configurable
Output generated using libutil's util_fmt_*() functions contains
meta-data such as hostname and time of invocation. When writing test
cases that compare expected and actual tool output, this run-time
variable information needs to be filtered out, resulting in increased
complexity.

To address this, add a global option to suppress meta-data output via
environment variable FMT_NOMETA. If set to '1', no meta-data will be
generated.

Example:

$ FMT_NOMETA=1 chpstat --format json

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Steffen Eiden
7e31c425c9 rust/pv: Try again if first CRL-URI is invalid
The previous implementation did stop after the first download was
successful, even if it did not contain a CRL. This behavior renders a
second, third, ... link as backup location useless as the code ignores
them if the URI e.g. contains a error message. That results in not
having a CRL and probably a failed certificate verification.

Fix this by trying again if the download was successful but did not
contain a CRL

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
6c4171b775 zdump/dfi_s390: Adjust device type check for s390_ext dump
In order to allow loop devices usage for DASD dump emulation in fvt-tests,
do not bail out on ZG_TYPE_DASD device type returned by zg_type() for
s390_ext dump.

Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Jan Höppner
0b0960254e s390-tools: Replace 'which' with built-in 'command -v'
There are still a few scripts using the 'which' command to determine
either the full path or the mere existence of an executable.
Some of these scripts might run in minimal environments where 'which' is
not available due to dependency restriction. 'which' is also considered
unreliable for historical implementation details.

Use the POSIX defined [1] built-in 'command -v' instead to reduce
package dependencies and improve reliability.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Alexander Egorenkov
4d2c9267c2 dumpconf: add new parameter 'SCP_DATA' for SCSI/NVMe/ECKD dump devices
The new parameter 'SCP_DATA' can be used to pass additional kernel cmdline
parameters to a stand-alone SCSI/NVMe/ECKD dumper for debugging purposes.

Configuration example
=====================

ON_PANIC=dump_reipl
DUMP_TYPE=fcp
DEVICE=0.0.4711
WWPN=0x5005076303004711
LUN=0x4711000000000000
BOOTPROG=0
BR_LBA=0
SCP_DATA="dump_debug=6 ignore_loglevel earlyprintk=sclp panic_print=3"

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Alexander Egorenkov
7ea0dfdc17 dumpconf: fix whitespace in sysconfig example for ECKD dump device
Make it conform with every other example.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Alexander Egorenkov
2d3aac1241 dumpconf: fix coding style of CheckDeviceString()
Make it conform with the naming style used for every other function in
this script.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Mikhail Zaslonko
c7fd515790 zdump: Fix 'zgetdump -i' ioctl error on s390 formatted dump file
When dump is copied to the filesystem in s390 format, follow on
'zgetdump -i' can fail with ioctl error:

  # zgetdump /dev/dasdb1 -f s390 dump.s390
  Format Info:
      Source: s390_ext
      Target: s390

  Copying dump:
      00000001 / 00008192 MB
      00003688 / 00008192 MB
      00006646 / 00008192 MB
      00008192 / 00008192 MB
  Success: Dump has been copied

  # zgetdump -iVVVV dump.s390

  zgetdump: Operation "BLKSSZGET" failed on "dump.s390" (Inappropriate ioctl for device)

Call ioctl(BLKSSZGET) only for s390_ext dump format (dump can be
stored on DASD partition only, not on the filesystem). For s390 format
a blocksize is not required for dump processing since s390 dump data is
not compressed.

Fixes: 271b809495 ("zdump/dfi_s390: Support reading compressed s390_ext dumps")
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Steffen Eiden
7a4ec55d77 rust/pvattest: Add short option for --arpk
pvattest-C had a -a option for --arpk which the Rust implementation
missed.
Add this short option.

Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Marc Hartmayer
63ff07ba38 Revert "zipl/src: Fix problems when target parameters are specified by user"
The commit fb0b6263d1 ("zipl/src: Fix problems when target parameters
are specified by user") breaks the case where the user has to provide
all target attributes via the zipl command line, because the target
device cannot be used to retrieve those attributes.

$ zipl -V --blsdir /tmp/tmp.xHmFUdgBCi/boot//loader/entries/ --config /tmp/tmp.dSv9MJ3svs
Looking for components in '/lib/s390-tools'
Using config file '/tmp/tmp.dSv9MJ3svs' (from command line)
Using BLS config file '/tmp/tmp.xHmFUdgBCi/boot//loader/entries//50_normal.conf'
Using BLS config file '/tmp/tmp.xHmFUdgBCi/boot//loader/entries//45_normal_swiotlb.conf'
Using BLS config file '/tmp/tmp.xHmFUdgBCi/boot//loader/entries//40_pv.conf'
Using BLS config file '/tmp/tmp.xHmFUdgBCi/boot//loader/entries//30_pv_reboot.conf'
Secure boot support: yes
Target device information
  Device..........................: 2b:00
  Device name.....................: nbd0 *)
  Device driver name..............: nbd
  Type............................: disk device
  Disk layout.....................: SCSI disk layout *)
  Geometry - start................: 2048 *)
  File system block size..........: 4096
  Physical block size.............: 512 *)
  Device size in physical blocks..: 2095071
  *) Data provided by user.
Building bootmap in '/tmp/tmp.xHmFUdgBCi/boot/'
Building menu 'zipl-automatic-menu'
Adding #1: IPL section 'Normal Guest' (default)
  initial ramdisk...: /tmp/tmp.xHmFUdgBCi/boot//ramdisk-s390x
  kernel image......: /tmp/tmp.xHmFUdgBCi/boot//vmlinux-s390x
zIPL environment block content:
Error: Could not add image file '/tmp/tmp.xHmFUdgBCi/boot//vmlinux-s390x': Could not get disk geometry

This reverts commit fb0b6263d1.

Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:24 +02:00
Frank Heimes
26d7eed0aa zfcpdump: Do not save timestamps when compressing
Having timestamps in gzip leads to lintian warning
'package-contains-timestamped-gzip' and will harm reproducible builds.
Gzip option '-n' avoids saving original file name and especially timestamps
by default.

Fixes: https://github.com/ibm-s390-linux/s390-tools/pull/169
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
[seiden@linux.ibm.com: Fix commit message]
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:13 +02:00
Frank Heimes
e0034eddbf s390-tools: Fix typos in code and man page files
Fix typos reported by (Debian) lintian.

Closes: https://github.com/ibm-s390-linux/s390-tools/pull/168
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
2024-06-24 16:23:09 +02:00
Jan Höppner
0e3034c0f6 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2024-05-28 08:26:36 +02:00
46 changed files with 735 additions and 181 deletions

View File

@@ -1,6 +1,24 @@
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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -32,8 +32,8 @@ endif
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
VERSION := 2
RELEASE := 33
PATCHLEVEL := 1
RELEASE := 34
PATCHLEVEL := 0
DISTRELEASE := build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
export S390_TOOLS_RELEASE

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
/*

View File

@@ -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

View File

@@ -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
*

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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)),
}
}

View File

@@ -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,

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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]);
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -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();

View File

@@ -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);

View File

@@ -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)

View File

@@ -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))

View File

@@ -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)",

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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, &reg,
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:

View File

@@ -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.

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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"