Merge ~fheimes/ubuntu/+source/s390-tools:s390-tools-sru-lp1903984-focal into ubuntu/+source/s390-tools:ubuntu/focal-devel

Proposed by Frank Heimes
Status: Merged
Merge reported by: Frank Heimes
Merged at revision: 2e2fee8f9b265c8eeb192b9085dd28eb0a43956f
Proposed branch: ~fheimes/ubuntu/+source/s390-tools:s390-tools-sru-lp1903984-focal
Merge into: ubuntu/+source/s390-tools:ubuntu/focal-devel
Diff against target: 1194 lines (+1160/-0)
5 files modified
debian/changelog (+17/-0)
debian/patches/s390-tools-sru-lp1902179-focal.patch (+689/-0)
debian/patches/s390-tools-sru-lp1903984-focal.patch (+49/-0)
debian/patches/s390-tools-sru-lp1908371-focal.patch (+402/-0)
debian/patches/series (+3/-0)
Reviewer Review Type Date Requested Status
Lukas Märdian (community) Approve
Review via email: mp+396775@code.launchpad.net

Description of the change

debian/patches/s390-tools-lp1903984-focal.patch
  zcryptstats: Fix handling of partial results with many domains
  - zconf/zcrypt/zcryptstats.c: code fix to pass the correct next-domain
    to the subsequent CHSC call of a partial response

debian/patches/s390-tools-sru-lp1908371-focal.patch:
  zipl command isn't working correctly in combination with the -M
  (respectively --mvdump) option.

debian/patches/s390-tools-sru-lp1902179-focal
  zcryptstats: Fix handling of partial results with many domains

Test build is available here:
https://launchpad.net/~fheimes/+archive/ubuntu/lp1903984-1908371-1902179

To post a comment you must log in.
Revision history for this message
Lukas Märdian (slyon) wrote :

Hi Frank, thank you very much for preparing this SRU! I like your extensive DEP-3 headers. I double-checked that the package builds with all new patches applied in Focal. Also, I checked it against the referenced upstream patches. I found some slight divergence there, mentioned inline.

Could you please comment on why we need to modify the upstream commit at those places, or alternatively adopt to the same changeset upstream applied? I'd like to stay as close to upstream as possible, so we won't have problems applying additional patches in the future.

Cheers,
  Lukas

review: Needs Information
Revision history for this message
Frank Heimes (fheimes) wrote :

The issue with the i Makefile (pl_tools/Makefile) especially the duplicate line "libs = $(rootdir)/libutil/libutil.a" is an artifact of a former (Ubuntu-) patch that was applied to focal.
It's not in H/devel, nor in G, but was introduced with 795d2c9 (which is Head -19).

Revision history for this message
Frank Heimes (fheimes) wrote :

Regarding the "enum target_type target_type;" line,
this line was indeed in the past commented like this:
 enum target_type target_type; /* CCW, FCP, NSS or NODE */
and with the expansion of the target types by target_type NVMe, the comment was changed to:
 enum target_type target_type; /* CCW,FCP,NVME,NSS or NODE */
and this is also upstream the case - and indeed unusual, because other comments follow the form:
/* CCW, FCP, NVME, NSS */
(means <comma><space>)
I assume that the NVME support was added by a different IBM developer, hence the different style.
Since I simply picked the upstream commit and applied it (w/o any adjustments), this little difference in style was transferred, too.

Revision history for this message
Lukas Märdian (slyon) wrote :

Okay, so as discussed on a side-channel, we're refreshing the path "debian/patches/s390-tools-sru-lp1902179-focal.patch" a bit, not to introduce any extra delta vs upstream.

See this MP for reference: https://code.launchpad.net/~slyon/ubuntu/+source/s390-tools/+git/s390-tools/+merge/396905

Build of the package with refreshed patch confirmed: https://launchpad.net/~slyon/+archive/ubuntu/testing/+build/20935925

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 33febaf..402dbc6 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,20 @@
6+s390-tools (2.12.0-0ubuntu3.2) focal; urgency=medium
7+
8+ * debian/patches/s390-tools-sru-lp1903984-focal.patch
9+ zcryptstats: Fix handling of partial results with many domains
10+ Thanks to Ingo Franzki (LP: #1903984)
11+ * debian/patches/s390-tools-sru-lp1908371-focal.patch:
12+ zipl command isn't working correctly in combination with the -M
13+ (respectively --mvdump) option.
14+ cherry-picking 4 commits from s390-tools v2.15.1 to v2.14
15+ Thanks to Stefan Haberland and Sven Schnelle (LP: #1908371)
16+ * debian/patches/s390-tools-sru-lp1902179-focal.patch:
17+ Enabling IPL (boot) from NVMe devices by adding 2 upstream commits
18+ from s390-tools v2.13/2.14 as backports to this v2.12 base.
19+ Thanks to Jason J. Herne (LP: #1902179)
20+
21+ -- Frank Heimes <frank.heimes@canonical.com> Fri, 22 Jan 2021 15:52:19 +0100
22+
23 s390-tools (2.12.0-0ubuntu3.1) focal; urgency=medium
24
25 * debian/patches/0082-*.patch .. 0111-*.patch (LP: #1892350)
26diff --git a/debian/patches/s390-tools-sru-lp1902179-focal.patch b/debian/patches/s390-tools-sru-lp1902179-focal.patch
27new file mode 100644
28index 0000000..91c2dcf
29--- /dev/null
30+++ b/debian/patches/s390-tools-sru-lp1902179-focal.patch
31@@ -0,0 +1,689 @@
32+Description: Enabling IPL (boot) from NVMe devices in focal
33+ These three patches are needed to enable IPL (boot on s390x) from NVMe devices
34+ They are already upstream and in the groovy and hirsute versions of the s390-tools.
35+ A cherry pick wasn't cleanly possible, hence these backports that are based on:
36+ 1b65b23b4398 "zipl: Support nvme devices" (went in v2.13.0)
37+ 0472b5ea5c97 "ipl-tools: Add nvme device support to lsreipl/chreipl" (went in v2.14.0)
38+Author: Jason J. Herne <jjherne@linux.ibm.com>
39+Origin: backports of:
40+ https://github.com/ibm-s390-tools/s390-tools/commit/1b65b23b43985cb8a1da2ef399ec6def31bbcc69
41+ https://github.com/ibm-s390-tools/s390-tools/commit/0472b5ea5c97f2c59a938deebe53b7f27e8a9a32
42+Bug: IBM Bugzilla 188732
43+Bug-IBM: https://bugs.launchpad.net/bugs/1902179
44+Forwarded: not-needed
45+Applied-Upstream: >= 2.14.0
46+Reviewed-by: Frank Heimes <frank.heimes@canonical.com>
47+Last-Update: 2021-01-22
48+---
49+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
50+--- a/ipl_tools/cmd_chreipl.c
51++++ b/ipl_tools/cmd_chreipl.c
52+@@ -28,12 +28,14 @@
53+ TT_FCP,
54+ TT_NSS,
55+ TT_NODE,
56++ TT_NVME,
57+ };
58+
59+ enum reipl_type {
60+ REIPL_FCP,
61+ REIPL_CCW,
62+- REIPL_NSS
63++ REIPL_NSS,
64++ REIPL_NVME,
65+ };
66+
67+ static const char *const usage_chreipl =
68+@@ -41,6 +43,7 @@
69+ "\n"
70+ " chreipl [ccw] [-d] <DEVICE> [OPTIONS]\n"
71+ " chreipl [fcp] [-d] <DEVICE> [-w] <WWPN> [-l] <LUN> [OPTIONS]\n"
72++" chreipl nvme [-i] <FID> [-s] <NSID> [OPTIONS]\n"
73+ " chreipl [node] <NODE|DIR> [OPTIONS]\n"
74+ " chreipl nss [-n] <NAME> [OPTIONS]\n"
75+ " chreipl [-h] [-v]\n"
76+@@ -48,6 +51,7 @@
77+ "The following re-IPL targets are supported:\n"
78+ " ccw IPL from CCW device\n"
79+ " fcp IPL from FCP device\n"
80++" nvme IPL from NVME device\n"
81+ " nss IPL from NSS\n"
82+ " node IPL from device specified by device node or directory\n"
83+ "\n"
84+@@ -68,6 +72,12 @@
85+ " -b, --bootprog <BPROG> Bootprog specification\n"
86+ " -L, --loadparm <PARM> Loadparm specification\n"
87+ "\n"
88++"Options for nvme target:\n"
89++" -i, --fid <FUNCTION_ID> PCI Function ID of NVME IPL device (hex)\n"
90++" -s --nsid <NAMESPACE_ID> Namespace ID of NVME IPL device (decimal, default 1)\n"
91++" -b, --bootprog <BPROG> Bootprog specification\n"
92++" -L, --loadparm <PARM> Loadparm specification\n"
93++"\n"
94+ "Options for nss target:\n"
95+ " -n, --name <NAME> Identifier of the NSS\n"
96+ "\n"
97+@@ -84,6 +94,10 @@
98+ char lun[20]; /* 18 character +0x" */
99+ int lun_set;
100+ char busid[10]; /* Bus ID e.g. 0.0.4711 */
101++ int fid_set;
102++ char fid[FID_MAX_LEN];
103++ int nsid_set;
104++ char nsid[11]; /* 10 decimal chars + null */
105+ int busid_set;
106+ char dev[15]; /* Device (e.g. dasda) */
107+ int dev_set;
108+@@ -92,10 +106,10 @@
109+ char bootparms[4096];
110+ int bootparms_set;
111+ int force_set;
112+- enum target_type target_type; /* CCW, FCP, NSS or NODE */
113++ enum target_type target_type; /* CCW, FCP, NVME, NSS or NODE */
114+ int target_type_set;
115+ int target_type_auto_mode;
116+- enum reipl_type reipl_type; /* CCW, FCP, NSS */
117++ enum reipl_type reipl_type; /* CCW, FCP, NVME, NSS */
118+ } l;
119+
120+ static void __noreturn print_usage_chreipl_exit(void)
121+@@ -226,6 +240,34 @@
122+ l.wwpn_set = 1;
123+ }
124+
125++static void set_nvme_nsid(const char *nsid)
126++{
127++ unsigned long long nsid_tmp;
128++ char *endptr;
129++
130++ nsid_tmp = strtoull(nsid, &endptr, 10);
131++ if (*endptr)
132++ ERR_EXIT("NSID \"%s\" is not a decimal number", nsid);
133++ snprintf(l.nsid, sizeof(l.nsid), "%08llu", nsid_tmp);
134++ l.nsid_set = 1;
135++}
136++
137++static void set_nvme_fid(const char *fid)
138++{
139++ unsigned long long fid_tmp;
140++ char *endptr;
141++
142++ fid_tmp = strtoull(fid, &endptr, 16);
143++ if (*endptr)
144++ ERR_EXIT("FID \"%s\" is not a hexadecimal number", fid);
145++ snprintf(l.fid, sizeof(l.fid), "0x%08llx", fid_tmp);
146++ l.fid_set = 1;
147++
148++ /* nsid defaults to 1, if not already set */
149++ if (!l.nsid_set)
150++ set_nvme_nsid("1");
151++}
152++
153+ static void parse_fcp_args(char *nargv[], int nargc)
154+ {
155+ /*
156+@@ -245,6 +287,28 @@
157+ set_lun(nargv[2]);
158+ }
159+
160++static void parse_nvme_args(char *nargv[], int nargc)
161++{
162++ /*
163++ * we might be called like this:
164++ * chreipl nvme 0x13 1
165++ */
166++ if (l.busid_set || l.fid_set || l.nsid_set || l.dev_set)
167++ ERR_EXIT("Use either options or positional parameters");
168++ if (nargc > 2)
169++ ERR_EXIT("Too many arguments specified for \"nvme\" re-IPL "
170++ "type");
171++ else if (nargc < 1)
172++ ERR_EXIT("The \"nvme\" re-IPL type requires function id, and "
173++ "optional namespace id");
174++ set_nvme_fid(nargv[0]);
175++
176++ if (nargc == 2)
177++ set_nvme_nsid(nargv[1]);
178++ else
179++ set_nvme_nsid("1");
180++}
181++
182+ static void parse_ccw_args(char *nargv[], int nargc)
183+ {
184+ /*
185+@@ -285,6 +349,13 @@
186+ dev_name[i] = 0;
187+ }
188+
189++static void dev_from_part_nvme(char *dev_name)
190++{
191++ char *delim = strrchr(dev_name, 'p');
192++ if (delim)
193++ *delim = 0;
194++}
195++
196+ static int set_reipl_type(const char *dev_name)
197+ {
198+ if (strncmp(dev_name, "dasd", strlen("dasd")) == 0 ||
199+@@ -292,11 +363,18 @@
200+ l.reipl_type = REIPL_CCW;
201+ else if (strncmp(dev_name, "sd", strlen("sd")) == 0)
202+ l.reipl_type = REIPL_FCP;
203++ else if (strncmp(dev_name, "nvme", strlen("nvme")) == 0)
204++ l.reipl_type = REIPL_NVME;
205+ else
206+ return -1;
207+
208+ util_strlcpy(l.dev, dev_name, sizeof(l.dev));
209+- dev_from_part(l.dev);
210++
211++ if (l.reipl_type == REIPL_NVME)
212++ dev_from_part_nvme(l.dev);
213++ else
214++ dev_from_part(l.dev);
215++
216+ l.dev_set = 1;
217+ return 0;
218+ }
219+@@ -399,6 +477,9 @@
220+ case TT_FCP:
221+ parse_fcp_args(nargv, nargc);
222+ break;
223++ case TT_NVME:
224++ parse_nvme_args(nargv, nargc);
225++ break;
226+ case TT_CCW:
227+ parse_ccw_args(nargv, nargc);
228+ break;
229+@@ -420,6 +501,14 @@
230+ "and LUN");
231+ }
232+
233++static void check_nvme_opts(void)
234++{
235++ if (l.nss_name_set || l.wwpn_set || l.lun_set || l.busid_set)
236++ ERR_EXIT("Invalid option for \"nvme\" target specified");
237++ if (!(l.fid_set && l.nsid_set))
238++ ERR_EXIT("The \"nvme\" target requires FID, and optional NSID");
239++}
240++
241+ static void check_ccw_opts(void)
242+ {
243+ if (l.bootprog_set || l.lun_set || l.wwpn_set || l.nss_name_set)
244+@@ -469,6 +558,8 @@
245+ { "device", required_argument, NULL, 'd' },
246+ { "lun", required_argument, NULL, 'l' },
247+ { "wwpn", required_argument, NULL, 'w' },
248++ { "fid", required_argument, NULL, 'i' },
249++ { "nsid", required_argument, NULL, 's' },
250+ { "loadparm", required_argument, NULL, 'L' },
251+ { "name", required_argument, NULL, 'n' },
252+ { "bootparms", required_argument, NULL, 'p' },
253+@@ -476,7 +567,7 @@
254+ { "version", no_argument, NULL, 'v' },
255+ { NULL, 0, NULL, 0 }
256+ };
257+- static const char optstr[] = "hcd:vw:l:fL:b:n:p:";
258++ static const char optstr[] = "hcd:vw:l:fL:b:n:p:i:s:";
259+
260+ /* dont run without any argument */
261+ if (argc == 1)
262+@@ -488,6 +579,8 @@
263+ set_target_type(TT_CCW, 0);
264+ else if (strcmp(argv[1], "nss") == 0)
265+ set_target_type(TT_NSS, 0);
266++ else if (strcmp(argv[1], "nvme") == 0)
267++ set_target_type(TT_NVME, 0);
268+ else if (strcmp(argv[1], "node") == 0)
269+ set_target_type(TT_NODE, 0);
270+ else
271+@@ -500,9 +593,15 @@
272+ case 'd':
273+ set_device(optarg);
274+ break;
275++ case 'i':
276++ set_nvme_fid(optarg);
277++ break;
278+ case 'l':
279+ set_lun(optarg);
280+ break;
281++ case 's':
282++ set_nvme_nsid(optarg);
283++ break;
284+ case 'w':
285+ set_wwpn(optarg);
286+ break;
287+@@ -650,6 +749,40 @@
288+ print_fcp(0, 0);
289+ }
290+
291++static void chreipl_nvme(void)
292++{
293++ check_nvme_opts();
294++
295++ if (!nvme_is_device(l.fid, l.nsid) && !l.force_set) {
296++ ERR_EXIT("Could not find NVME device with fid %s and nsid %s",
297++ l.fid, l.nsid);
298++ }
299++ check_exists("reipl/nvme/fid", "\"nvme\" re-IPL target");
300++
301++ if (l.bootparms_set && strlen(l.bootparms) > BOOTPARMS_FCP_MAX) {
302++ ERR_EXIT("Maximum boot parameter length exceeded (%zu/%u)",
303++ strlen(l.bootparms), BOOTPARMS_FCP_MAX);
304++ }
305++
306++ write_str_optional(l.loadparm, "reipl/nvme/loadparm", l.loadparm_set,
307++ "loadparm");
308++ write_str_optional(l.bootparms, "reipl/nvme/scp_data", l.bootparms_set,
309++ "boot parameters");
310++ write_str(l.fid, "reipl/nvme/fid");
311++ write_str(l.nsid, "reipl/nvme/nsid");
312++ /*
313++ * set the boot record logical block address. Master boot
314++ * record. It is always 0 for Linux
315++ */
316++ write_str("0", "reipl/nvme/br_lba");
317++ if (!l.bootprog_set)
318++ sprintf(l.bootprog, "0");
319++ write_str(l.bootprog, "reipl/nvme/bootprog");
320++ write_str("nvme", "reipl/reipl_type");
321++
322++ print_nvme(0, 0);
323++}
324++
325+ static void chreipl_nss(void)
326+ {
327+ check_nss_opts();
328+@@ -690,6 +823,13 @@
329+ l.busid_set = 1;
330+ chreipl_fcp();
331+ break;
332++ case REIPL_NVME:
333++ nvme_fid_get(l.dev, l.fid);
334++ l.fid_set = 1;
335++ nvme_nsid_get(l.dev, l.nsid);
336++ l.nsid_set = 1;
337++ chreipl_nvme();
338++ break;
339+ default:
340+ ERR_EXIT("Internal error: chreipl_node");
341+ }
342+@@ -705,6 +845,9 @@
343+ case TT_FCP:
344+ chreipl_fcp();
345+ break;
346++ case TT_NVME:
347++ chreipl_nvme();
348++ break;
349+ case TT_NSS:
350+ chreipl_nss();
351+ break;
352+--- a/ipl_tools/cmd_lsreipl.c
353++++ b/ipl_tools/cmd_lsreipl.c
354+@@ -81,6 +81,35 @@
355+ print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
356+ }
357+
358++void print_nvme(int show_ipl, int dump)
359++{
360++ char *dir = show_ipl ? "ipl" : "reipl/nvme";
361++ char *path_bootparms = show_ipl ? "/sys/firmware/ipl/scp_data" :
362++ "/sys/firmware/reipl/nvme/scp_data";
363++ char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
364++ "/sys/firmware/reipl/nvme/loadparm";
365++ char loadparm[9], loadparm_path[PATH_MAX];
366++
367++ if (dump)
368++ printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl));
369++ else
370++ printf("%-12s nvme\n", get_ipl_banner(show_ipl));
371++
372++ print_fw_str("FID: %s\n", dir, "fid");
373++ print_fw_str("NSID: %s\n", dir, "nsid");
374++ print_fw_str("bootprog: %s\n", dir, "bootprog");
375++ print_fw_str("br_lba: %s\n", dir, "br_lba");
376++ if (access(path_loadparm, R_OK) == 0) {
377++ sprintf(loadparm_path, "%s/%s", dir, "loadparm");
378++ read_fw_str(loadparm, loadparm_path, sizeof(loadparm));
379++ if (strcmp(loadparm, " ") == 0)
380++ loadparm[0] = 0;
381++ printf("Loadparm: \"%s\"\n", loadparm);
382++ }
383++ if (access(path_bootparms, R_OK) == 0)
384++ print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
385++}
386++
387+ void print_ccw(int show_ipl)
388+ {
389+ char loadparm[9], loadparm_path[PATH_MAX];
390+@@ -149,6 +178,10 @@
391+ print_fcp(l.ipl_set, 0);
392+ else if (strcmp(reipl_type_str, "fcp_dump") == 0)
393+ print_fcp(l.ipl_set, 1);
394++ else if (strcmp(reipl_type_str, "nvme") == 0)
395++ print_nvme(l.ipl_set, 0);
396++ else if (strcmp(reipl_type_str, "nvme_dump") == 0)
397++ print_nvme(l.ipl_set, 1);
398+ else if (strcmp(reipl_type_str, "ccw") == 0)
399+ print_ccw(l.ipl_set);
400+ else if (strcmp(reipl_type_str, "nss") == 0)
401+--- a/ipl_tools/ipl_tools.h
402++++ b/ipl_tools/ipl_tools.h
403+@@ -43,6 +43,7 @@
404+
405+ extern void print_ccw(int show_ipl);
406+ extern void print_fcp(int show_ipl, int dump);
407++extern void print_nvme(int show_ipl, int dump);
408+ extern void print_nss(int show_ipl);
409+
410+ /*
411+@@ -71,6 +72,16 @@
412+ extern void fcp_busid_get(const char *device, char *devno);
413+
414+ /*
415++ * NVME
416++ */
417++#define FID_MAX_LEN 11 /* 8 characters + 0x + null */
418++#define NVME_PATH_MAX (PATH_MAX + NAME_MAX + 1)
419++
420++extern void nvme_fid_get(const char *device, char *fid);
421++extern void nvme_nsid_get(const char *device, char *nsid);
422++int nvme_is_device(char *fid_str, char *nsid_str);
423++
424++/*
425+ * CCW
426+ */
427+ extern int ccw_is_device(const char *devno);
428+--- a/ipl_tools/Makefile
429++++ b/ipl_tools/Makefile
430+@@ -6,7 +6,7 @@
431+
432+ libs = $(rootdir)/libutil/libutil.a
433+
434+-objects = main.o ccw.o fcp.o system.o shutdown.o \
435++objects = main.o ccw.o fcp.o nvme.o system.o shutdown.o \
436+ cmd_lsshut.o cmd_chshut.o cmd_lsreipl.o cmd_chreipl.o proc.o
437+
438+ chreipl: $(objects) $(libs)
439+@@ -40,4 +40,3 @@
440+ $(DESTDIR)$(MANDIR)/man8
441+
442+ .PHONY: all install clean
443+-
444+--- a/ipl_tools/man/chreipl.8
445++++ b/ipl_tools/man/chreipl.8
446+@@ -39,6 +39,9 @@
447+ .RB "- " fcp :
448+ Specify a FCP device for reboot
449+ .TP
450++.RB "- " nvme :
451++Specify an NVMe device for reboot
452++.TP
453+ .RB "- " nss :
454+ Specify a named saved system (NSS) for reboot
455+ .TP
456+@@ -118,6 +121,11 @@
457+ append kernel parameter "mem=" to restrict memory to 512 MB:
458+
459+ \fB# chreipl 0.0.1700 0x500507630300c562 0x401040b300000000 -p "mem=512M"\fP
460++
461++4. Next time reboot from the NVMe device with function id 0x13, namespace 1:
462++
463++\fB# chreipl nvme 0x13 1
464++
465+ .SH ccw
466+ Use the ccw re-IPL target for DASD devices that are accessed by the hardware
467+ using channel command word (CCW) channels.
468+@@ -192,6 +200,44 @@
469+ .br
470+
471+ \fB# chreipl fcp -d 0.0.1700 -w 0x5005076... -l 0x401040b3... -b 2\fP
472++.SH nvme
473++Use the nvme re-IPL target for specifying an NVMe disk for reboot.
474++.TP
475++.BR "\-i" " or " "\-\-fid"
476++PCI Function ID of NVME IPL device (hex).
477++
478++.TP
479++.BR "\-s" " or " "\-\-nsid"
480++Namespace ID of the NVME IPL device (decimal, default 1).
481++
482++.TP
483++.BR "\-b" " or " "\-\-bootprog"
484++Specifies an entry in the boot configuration by defining the IPL boot
485++program selector. If omitted, '0' will be used.
486++
487++.TP
488++.BR "\-L" " or " "\-\-loadparm"
489++The loadparm for the nvme re-IPL target is not used to control the boot
490++configuration that is defined by the
491++.BR zipl (8)
492++boot menu. Instead it can be used to control higher level boot loaders
493++like GRUB. For more details refer to distribution specific documentation.
494++
495++.PP
496++\fBExamples:\fP
497++.br
498++
499++1. Next time reboot from the NVMe disk with function-id 0x13 and namespace 1:
500++.br
501++
502++\fB# chreipl nvme 0x13 1\fP
503++.br
504++
505++2. Use same configuration as (1) but choose boot program selector 2 and
506++use options instead of positional parameters:
507++.br
508++
509++\fB# chreipl nvme -i 0x13 -s 1 -b 2\fP
510+ .SH nss
511+ Use the nss re-IPL target to specify z/VM named saved systems (NSS) for
512+ reboot.
513+@@ -206,7 +252,7 @@
514+
515+ \fB# chreipl nss LINUX1\fP
516+ .SH node
517+-You can identify DASD or SCSI re-IPL devices indirectly through a device
518++You can identify DASD or SCSI, or NVMe re-IPL devices indirectly through a device
519+ node or directory. The chreipl tool then determines the information
520+ that you would otherwise have to specify with the ccw or fcp target.
521+ .PP
522+@@ -229,6 +275,11 @@
523+
524+ \fB# chreipl node /mnt/boot\fP
525+
526++4. Next time reboot from the NVMe device represented by /dev/nvme0n1
527++.br
528++
529++\fB# chreipl node /dev/nvme0n1\fP
530++
531+ .SH SEE ALSO
532+ .BR lsreipl (8),
533+ .BR zipl (8),
534+--- /dev/null
535++++ b/ipl_tools/nvme.c
536+@@ -0,0 +1,169 @@
537++/*
538++ * ipl_tools - Linux for System z reipl and shutdown tools
539++ *
540++ * NVMe device functions
541++ *
542++ * Copyright IBM Corp. 2020
543++ *
544++ * s390-tools is free software; you can redistribute it and/or modify
545++ * it under the terms of the MIT license. See LICENSE for details.
546++ */
547++#include <sys/types.h>
548++#include <dirent.h>
549++#include <limits.h>
550++#include <stdlib.h>
551++#include <unistd.h>
552++
553++#include "lib/util_libc.h"
554++#include "lib/util_file.h"
555++#include "ipl_tools.h"
556++
557++/*
558++ * Return the fid of a device
559++ */
560++void nvme_fid_get(const char *device, char *fid)
561++{
562++ char path[PATH_MAX], buf[FID_MAX_LEN];
563++
564++ snprintf(path, PATH_MAX, "/sys/block/%s/device/device/function_id",
565++ device);
566++ if (util_file_read_line(buf, FID_MAX_LEN, path))
567++ ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
568++
569++ util_strlcpy(fid, buf, FID_MAX_LEN);
570++}
571++/*
572++ * Return the nsid of a device
573++ */
574++void nvme_nsid_get(const char *device, char *nsid)
575++{
576++ char path[PATH_MAX], buf[FID_MAX_LEN];
577++
578++ snprintf(path, PATH_MAX, "/sys/block/%s/nsid", device);
579++ if (util_file_read_line(buf, FID_MAX_LEN, path))
580++ ERR_EXIT_ERRNO("Could not read from \"%s\"", path);
581++
582++ util_strlcpy(nsid, buf, FID_MAX_LEN);
583++}
584++
585++static int next_entry(DIR *dir, char *in_path, char *out_path,
586++ unsigned char entry_type)
587++{
588++ struct dirent *dirent;
589++ char temp_path[NVME_PATH_MAX];
590++
591++ while ((dirent = readdir(dir)) != NULL) {
592++ if (strcmp(dirent->d_name, ".") == 0 ||
593++ strcmp(dirent->d_name, "..") == 0 ||
594++ dirent->d_type != entry_type)
595++ continue;
596++
597++ /* Resolve the symlink, if needed */
598++ if (dirent->d_type == DT_LNK) {
599++ snprintf(temp_path, sizeof(temp_path), "%s/%s", in_path,
600++ dirent->d_name);
601++ if (!realpath(temp_path, out_path))
602++ ERR_EXIT_ERRNO("Could not resolve link %s",
603++ temp_path);
604++ return 1;
605++ }
606++
607++ snprintf(out_path, NVME_PATH_MAX, "%s/%s", in_path,
608++ dirent->d_name);
609++ return 1;
610++ }
611++ return 0;
612++}
613++
614++static int nvme_getdev_by_fid(char *fidstr, char *devpath)
615++{
616++ char temp_path[PATH_MAX+19], real_path[PATH_MAX];
617++ char *sys_path = "/sys/class/nvme";
618++ u_int64_t target_fid, curfid;
619++ DIR *dir;
620++ char *end;
621++ int rc = -1;
622++
623++ target_fid = strtoul(fidstr, &end, 16);
624++ if (*end)
625++ ERR_EXIT("Invalid function_id given %s", fidstr);
626++
627++ dir = opendir(sys_path);
628++ if (!dir)
629++ ERR_EXIT("Could not open %s", sys_path);
630++
631++ errno = 0;
632++ while (next_entry(dir, sys_path, real_path, DT_LNK)) {
633++ snprintf(temp_path, sizeof(temp_path), "%s/%s", real_path,
634++ "device/function_id");
635++ if (access(temp_path, F_OK))
636++ continue;
637++
638++ if (util_file_read_ul(&curfid, 16, temp_path))
639++ ERR_EXIT("Invalid function_id found in %s", temp_path);
640++
641++ if (curfid == target_fid) {
642++ strncpy(devpath, real_path, PATH_MAX);
643++ rc = 0;
644++ break;
645++ }
646++ }
647++
648++ closedir(dir);
649++ return rc;
650++}
651++
652++static int nvme_getdev_by_nsid(char *nsid_str, char *path, char *dev_path)
653++{
654++ char full_path[NVME_PATH_MAX+1], nsid_path[sizeof(full_path)+5];
655++ char *end;
656++ u_int64_t nsid, curnsid;
657++ DIR *dir;
658++
659++ nsid = strtoul(nsid_str, &end, 10);
660++ if (*end)
661++ ERR_EXIT_ERRNO("Invalid namespace id given %s", nsid_str);
662++
663++ dir = opendir(path);
664++ if (!dir)
665++ ERR_EXIT_ERRNO("Could not open %s", path);
666++
667++ errno = 0;
668++ while (next_entry(dir, path, full_path, DT_DIR)) {
669++ snprintf(nsid_path, sizeof(nsid_path), "%s/%s", full_path,
670++ "nsid");
671++ if (access(nsid_path, F_OK))
672++ continue;
673++
674++ if (util_file_read_ul(&curnsid, 10, nsid_path))
675++ ERR_EXIT("Invalid namespace id found in %s", nsid_path);
676++
677++ if (curnsid == nsid) {
678++ strncpy(dev_path, full_path, NVME_PATH_MAX+1);
679++ closedir(dir);
680++ return 0;
681++ }
682++ }
683++ closedir(dir);
684++ return -1;
685++}
686++
687++static int nvme_getdev(char *fid_str, char *nsid_str, char *dev_path)
688++{
689++ char path_tmp[NVME_PATH_MAX];
690++
691++ if (nvme_getdev_by_fid(fid_str, path_tmp))
692++ return -1;
693++
694++ return nvme_getdev_by_nsid(nsid_str, path_tmp, dev_path);
695++}
696++
697++/*
698++ * Check if the specified fid and nsid leads to a valid nvme device
699++ */
700++int nvme_is_device(char *fid_str, char *nsid_str)
701++{
702++ char path_tmp[NVME_PATH_MAX+1];
703++
704++ return !(nvme_getdev(fid_str, nsid_str, path_tmp));
705++}
706+--- a/zipl/src/disk.c
707++++ b/zipl/src/disk.c
708+@@ -421,6 +421,12 @@
709+ data->device = stats.st_rdev;
710+ data->partnum = 0;
711+ }
712++ /* NVMe path, driver name is 'blkext' */
713++ } else if (strcmp(data->drv_name, "blkext") == 0) {
714++ data->devno = -1;
715++ data->type = disk_type_scsi;
716++ data->partnum = stats.st_rdev & SCSI_PARTN_MASK;
717++ data->device = stats.st_rdev & ~SCSI_PARTN_MASK;
718+ } else {
719+ /* Driver name is unknown */
720+ error_reason("Unsupported device driver '%s'", data->drv_name);
721diff --git a/debian/patches/s390-tools-sru-lp1903984-focal.patch b/debian/patches/s390-tools-sru-lp1903984-focal.patch
722new file mode 100644
723index 0000000..fc4952f
724--- /dev/null
725+++ b/debian/patches/s390-tools-sru-lp1903984-focal.patch
726@@ -0,0 +1,49 @@
727+Description: zcryptstats fails
728+ The zcryptstats tool reports data for only the last two domain IDs.
729+ Further, it hangs if one collect data for a complete crypto card,
730+ and then one has to kill the ssh session to get back.
731+ Patch/commit is:
732+ cf2311f cf2311f1f1de17435b49ba8c8697be91705ba031
733+ "zcryptstats: Fix handling of partial results with many domains"
734+ - zconf/zcrypt/zcryptstats.c: code fix to pass the correct next-domain
735+ to the subsequent CHSC call of a partial response
736+Author: Ingo Franzki <ifranzki@linux.ibm.com>
737+Origin: https://github.com/ibm-s390-tools/s390-tools/commit/cf2311f1f1de17435b49ba8c8697be91705ba031
738+Bug-IBM: IBM Bugzilla 189183
739+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1903984
740+Forwarded: not-needed
741+Applied-Upstream: upstream accepted with > v2.15.1
742+Reviewed-by: Frank Heimes <frank.heimes@canonical.com>
743+Last-Update: 2021-01-19
744+---
745+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
746+--- a/zconf/zcrypt/zcryptstats.c
747++++ b/zconf/zcrypt/zcryptstats.c
748+@@ -1178,8 +1178,14 @@
749+ scdmd_area.request.header.code = 0x102d;
750+ scdmd_area.request.header.length =
751+ sizeof(struct chsc_scdmd_request);
752+- scdmd_area.request.first_drid.ap_index = card;
753+- scdmd_area.request.first_drid.domain_index = g.min_domain;
754++ if (scdmd_area.response.p) {
755++ scdmd_area.request.first_drid =
756++ scdmd_area.response.crid;
757++ } else {
758++ scdmd_area.request.first_drid.ap_index = card;
759++ scdmd_area.request.first_drid.domain_index =
760++ g.min_domain;
761++ }
762+ scdmd_area.request.last_drid.ap_index = card;
763+ scdmd_area.request.last_drid.domain_index = g.max_domain;
764+ scdmd_area.request.s = 1;
765+@@ -1217,10 +1223,6 @@
766+ rc = process_apqn_measurement_data(&scdmd_area);
767+ if (rc != 0)
768+ break;
769+-
770+- if (scdmd_area.response.p)
771+- scdmd_area.request.first_drid =
772+- scdmd_area.response.crid;
773+ } while (scdmd_area.response.p);
774+
775+ return rc;
776diff --git a/debian/patches/s390-tools-sru-lp1908371-focal.patch b/debian/patches/s390-tools-sru-lp1908371-focal.patch
777new file mode 100644
778index 0000000..7ba3725
779--- /dev/null
780+++ b/debian/patches/s390-tools-sru-lp1908371-focal.patch
781@@ -0,0 +1,402 @@
782+Description: The zipl command doesn't work correctly in combination with the -M
783+ (respectively --mvdump) option. There is an error with the preparation of
784+ multi-volume dumps, since the bus-ID for the first disk partition that is
785+ listed in file dump_conf (DEVLIST) isn't found.
786+ - include/lib/util_sys.h: declaration of new util_sys_* functions
787+ - include/lib/util_file.h: declaration of two new util_file_read_* functions
788+ - libutil/util_sys.c: implementation of new util_sys_* functions;
789+ getting minor and major device number now based on base device
790+ and prechecking if base device available util_file_read_* functions
791+ - libutil/util_file.c: implementation of two new
792+ - zipl/src/disk.c: removing blkext_* function set and changing code to
793+ use the new util_sys_* functions
794+Author: Stefan Haberland <sth@linux.ibm.com>, Sven Schnelle <svens@linux.ibm.com>
795+Origin: https://github.com/ibm-s390-tools/s390-tools/commit/fa7a4dafa3d89b2e8787de102e4362e895d44b05
796+ https://github.com/ibm-s390-tools/s390-tools/commit/aa8c2945cc7b047c626e75817c6a3e3924413023
797+ https://github.com/ibm-s390-tools/s390-tools/commit/6802b86414b48c4f118da09c7bf7ee142a459fa0
798+ https://github.com/ibm-s390-tools/s390-tools/commit/37348ef662a7052dae798e500ca8c9b769fff3e6
799+Bug-IBM: IBM Bugzilla 187221
800+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1908371
801+Forwarded: not-needed
802+Applied-Upstream: >= v2.15.1
803+Reviewed-by: Frank Heimes <frank.heimes@canonical.com>
804+Last-Update: 2020-12-22
805+---
806+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
807+--- a/include/lib/util_file.h
808++++ b/include/lib/util_file.h
809+@@ -12,8 +12,10 @@
810+ #define LIB_UTIL_FILE_H
811+
812+ int util_file_read_line(char *str, size_t size, const char *fmt, ...);
813++int util_file_read_i(int *val, int base, const char *fmt, ...);
814+ int util_file_read_l(long *val, int base, const char *fmt, ...);
815+ int util_file_read_ll(long long *val, int base, const char *fmt, ...);
816++int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...);
817+ int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
818+ int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
819+
820+--- a/include/lib/util_sys.h
821++++ b/include/lib/util_sys.h
822+@@ -12,6 +12,11 @@
823+ #ifndef LIB_UTIL_SYS_H
824+ #define LIB_UTIL_SYS_H
825+
826++#include <stdbool.h>
827++
828+ int util_sys_get_dev_addr(const char *dev, char *addr);
829++bool util_sys_dev_is_partition(dev_t dev);
830++int util_sys_get_partnum(dev_t dev);
831++int util_sys_get_base_dev(dev_t dev, dev_t *base_dev);
832+
833+ #endif /** LIB_UTIL_SYS_H @} */
834+--- a/libutil/util_file.c
835++++ b/libutil/util_file.c
836+@@ -282,6 +282,44 @@
837+ }
838+
839+ /**
840++ * Read a file and convert it to signed int according to given base
841++ *
842++ * @param[out] val Buffer for value
843++ * @param[in] base Base for conversion, either 8, 10, or 16
844++ * @param[in] fmt Format string for generation of the path name
845++ * @param[in] ... Parameters for format string
846++ *
847++ * @retval 0 Integer has been read correctly
848++ * @retval -1 Error while reading file
849++ */
850++int util_file_read_i(int *val, int base, const char *fmt, ...)
851++{
852++ char path[PATH_MAX], buf[512];
853++ va_list ap;
854++ int count;
855++
856++ /* Construct the file name */
857++ UTIL_VSPRINTF(path, fmt, ap);
858++
859++ if (file_gets(buf, sizeof(buf), path))
860++ return -1;
861++ switch (base) {
862++ case 8:
863++ count = sscanf(buf, "%do", val);
864++ break;
865++ case 10:
866++ count = sscanf(buf, "%dd", val);
867++ break;
868++ case 16:
869++ count = sscanf(buf, "%dx", val);
870++ break;
871++ default:
872++ util_panic("Invalid base: %d\n", base);
873++ }
874++ return (count == 1) ? 0 : -1;
875++}
876++
877++/**
878+ * Read a file and convert it to signed long according to given base
879+ *
880+ * @param[out] val Buffer for value
881+@@ -353,6 +391,44 @@
882+ break;
883+ default:
884+ util_panic("Invalid base: %d\n", base);
885++ }
886++ return (count == 1) ? 0 : -1;
887++}
888++
889++/**
890++ * Read a file and convert it to unsigned int according to given base
891++ *
892++ * @param[out] val Buffer for value
893++ * @param[in] base Base for conversion, either 8, 10, or 16
894++ * @param[in] fmt Format string for generation of the path name
895++ * @param[in] ... Parameters for format string
896++ *
897++ * @retval 0 Integer has been read correctly
898++ * @retval -1 Error while reading file
899++ */
900++int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
901++{
902++ char path[PATH_MAX], buf[512];
903++ va_list ap;
904++ int count;
905++
906++ /* Construct the file name */
907++ UTIL_VSPRINTF(path, fmt, ap);
908++
909++ if (file_gets(buf, sizeof(buf), path))
910++ return -1;
911++ switch (base) {
912++ case 8:
913++ count = sscanf(buf, "%uo", val);
914++ break;
915++ case 10:
916++ count = sscanf(buf, "%uu", val);
917++ break;
918++ case 16:
919++ count = sscanf(buf, "%ux", val);
920++ break;
921++ default:
922++ util_panic("Invalid base: %d\n", base);
923+ }
924+ return (count == 1) ? 0 : -1;
925+ }
926+--- a/libutil/util_sys.c
927++++ b/libutil/util_sys.c
928+@@ -11,17 +11,114 @@
929+
930+ #include <err.h>
931+ #include <errno.h>
932++#include <linux/fs.h>
933+ #include <stdlib.h>
934++#include <stdio.h>
935+ #include <string.h>
936+ #include <sys/stat.h>
937+ #include <sys/sysmacros.h>
938+ #include <unistd.h>
939+
940++#include "lib/util_file.h"
941++#include "lib/util_libc.h"
942+ #include "lib/util_path.h"
943+ #include "lib/util_sys.h"
944+
945+ /* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
946+ #define READLINK_SIZE 256
947++#define PAGE_SIZE 4096
948++
949++/**
950++ * Return the partition number of a given partition.
951++ *
952++ * @param[in] dev Device node of interest
953++ *
954++ * @retval int Partition number of the device
955++ * @retval -1 Error when trying to read the partition number.
956++ */
957++int util_sys_get_partnum(dev_t dev)
958++{
959++ int partnum = -1;
960++ char *path;
961++
962++ path = util_path_sysfs("dev/block/%u:%u/partition",
963++ major(dev), minor(dev));
964++ if (util_file_read_i(&partnum, 10, path)) {
965++ warnx("Could not read from path '%s'", path);
966++ goto out;
967++ }
968++ if (partnum <= 0) {
969++ warnx("Bad partition number in '%s'", path);
970++ partnum = -1;
971++ goto out;
972++ }
973++
974++out:
975++ free(path);
976++ return partnum;
977++}
978++
979++/**
980++ * Determine if the given device is a partition.
981++ *
982++ * @param[in] dev Device node of interest
983++ *
984++ * @retval true Device is partition
985++ * @retval false Device is not a partition
986++ */
987++bool util_sys_dev_is_partition(dev_t dev)
988++{
989++ bool is_part;
990++ char *path;
991++
992++ path = util_path_sysfs("dev/block/%u:%u/partition",
993++ major(dev), minor(dev));
994++ is_part = util_path_exists(path);
995++ free(path);
996++
997++ return is_part;
998++}
999++
1000++/**
1001++ * Determine base device
1002++ *
1003++ * This function determines the base device \p base_dev of a given
1004++ * device \p dev. If \p dev is a base device, \p base_dev becomes \p dev.
1005++ *
1006++ * @param[in] dev Device node of interest
1007++ * @param[out] base_dev Identified base device
1008++ *
1009++ * @retval 0 Success
1010++ * @retval -1 Error while reading device information or
1011++ * constructed path
1012++ */
1013++int util_sys_get_base_dev(dev_t dev, dev_t *base_dev)
1014++{
1015++ int base_major, base_minor;
1016++ char buf[PAGE_SIZE];
1017++ char *path;
1018++
1019++ /* check if the device already is a base device */
1020++ if (!util_sys_dev_is_partition(dev)) {
1021++ *base_dev = makedev(major(dev), minor(dev));
1022++ return 0;
1023++ }
1024++ path = util_path_sysfs("dev/block/%d:%d/../dev",
1025++ major(dev), minor(dev));
1026++ if (util_file_read_line(buf, sizeof(buf), path)) {
1027++ warnx("Could not read from path '%s'", path);
1028++ free(path);
1029++ return -1;
1030++ }
1031++ free(path);
1032++ if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
1033++ warn("Could not parse major:minor from string '%s'", buf);
1034++ return -1;
1035++ }
1036++ *base_dev = makedev(base_major, base_minor);
1037++
1038++ return 0;
1039++}
1040+
1041+ /**
1042+ * Identify device address
1043+@@ -44,13 +141,17 @@
1044+ unsigned int maj, min;
1045+ struct stat s;
1046+ ssize_t len;
1047++ dev_t base;
1048+ char *path;
1049+
1050+ if (stat(dev, &s) != 0)
1051+ return -1;
1052+
1053+- maj = major(s.st_rdev);
1054+- min = minor(s.st_rdev);
1055++ if (util_sys_get_base_dev(s.st_rdev, &base))
1056++ return -1;
1057++
1058++ maj = major(base);
1059++ min = minor(base);
1060+
1061+ if (S_ISBLK(s.st_mode))
1062+ path = util_path_sysfs("dev/block/%u:%u/device", maj, min);
1063+--- a/zipl/src/disk.c
1064++++ b/zipl/src/disk.c
1065+@@ -25,6 +25,7 @@
1066+ #include <linux/fiemap.h>
1067+
1068+ #include "lib/util_proc.h"
1069++#include "lib/util_sys.h"
1070+
1071+ #include "disk.h"
1072+ #include "error.h"
1073+@@ -89,88 +90,6 @@
1074+ return 0;
1075+ }
1076+
1077+-static int blkext_get_partnum(dev_t dev)
1078+-{
1079+- char path[PATH_MAX], *buf;
1080+- int dev_major, dev_minor, partnum = -1;
1081+-
1082+- dev_major = major(dev);
1083+- dev_minor = minor(dev);
1084+- snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
1085+- dev_major, dev_minor);
1086+-
1087+- if (misc_read_special_file(path, &buf, NULL, 1)) {
1088+- error_text("Could not read from path '%s'", path);
1089+- return -1;
1090+- }
1091+-
1092+- partnum = atoi(buf);
1093+- free(buf);
1094+- if (partnum < 0) {
1095+- error_text("Bad partition number in '%s'", path);
1096+- return -1;
1097+- }
1098+-
1099+- return partnum;
1100+-}
1101+-
1102+-static int blkext_is_base_device(dev_t dev)
1103+-{
1104+- int dev_major, dev_minor;
1105+- char path[PATH_MAX];
1106+- struct stat stats;
1107+-
1108+- dev_major = major(dev);
1109+- dev_minor = minor(dev);
1110+-
1111+- snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
1112+- dev_major, dev_minor);
1113+- return (stat(path, &stats));
1114+-}
1115+-
1116+-static int blkext_get_base_dev(dev_t dev, dev_t *base_dev)
1117+-{
1118+- int base_major, base_minor;
1119+- char dev_path[PATH_MAX], base_path[PATH_MAX];
1120+- char *temp_path, *buf;
1121+-
1122+- misc_asprintf(&temp_path, "/sys/dev/block/%d:%d", major(dev), minor(dev));
1123+- if (!realpath(temp_path, dev_path)) {
1124+- error_reason(strerror(errno));
1125+- error_text("Could not resolve link %s", temp_path);
1126+- free(temp_path);
1127+- return -1;
1128+- }
1129+- free(temp_path);
1130+-
1131+- misc_asprintf(&temp_path, "%s/..", dev_path);
1132+- if (!realpath(temp_path, base_path)) {
1133+- error_reason(strerror(errno));
1134+- error_text("Could not resolve path %s", temp_path);
1135+- free(temp_path);
1136+- return -1;
1137+- }
1138+- free(temp_path);
1139+-
1140+- misc_asprintf(&temp_path, "%s/dev", base_path);
1141+- if (misc_read_special_file(temp_path, &buf, NULL, 1)) {
1142+- error_text("Could not read from path '%s'", temp_path);
1143+- free(temp_path);
1144+- return -1;
1145+- }
1146+- free(temp_path);
1147+-
1148+- if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
1149+- error_text("Could not parse major:minor from string '%s'", buf);
1150+- free(buf);
1151+- return -1;
1152+- }
1153+-
1154+- free(buf);
1155+- *base_dev = makedev(base_major, base_minor);
1156+- return 0;
1157+-}
1158+-
1159+ /* Return non-zero for ECKD type. */
1160+ int
1161+ disk_is_eckd(disk_type_t type)
1162+@@ -492,15 +411,15 @@
1163+ data->devno = -1;
1164+ data->type = disk_type_scsi;
1165+
1166+- if (blkext_is_base_device(stats.st_rdev)) {
1167+- data->device = stats.st_rdev;
1168+- data->partnum = 0;
1169+- } else {
1170+- if (blkext_get_base_dev(stats.st_rdev, &data->device))
1171++ if (util_sys_dev_is_partition(stats.st_rdev)) {
1172++ if (util_sys_get_base_dev(stats.st_rdev, &data->device))
1173+ goto out_close;
1174+- data->partnum = blkext_get_partnum(stats.st_rdev);
1175++ data->partnum = util_sys_get_partnum(stats.st_rdev);
1176+ if (data->partnum == -1)
1177+ goto out_close;
1178++ } else {
1179++ data->device = stats.st_rdev;
1180++ data->partnum = 0;
1181+ }
1182+ } else {
1183+ /* Driver name is unknown */
1184diff --git a/debian/patches/series b/debian/patches/series
1185index e779db8..894d113 100644
1186--- a/debian/patches/series
1187+++ b/debian/patches/series
1188@@ -110,3 +110,6 @@ f742ed73e1db99dc04b821a1f9aa4a852584e4d8.patch
1189 0110-zipl-stage3-correctly-handle-diag308-response-code.patch
1190 0111-zipl-fix-incorrect-setup-of-stage3-flags.patch
1191 0112-cpumf-lscpumf.pl-displays-raw-event-number-incorrect.patch
1192+s390-tools-sru-lp1903984-focal.patch
1193+s390-tools-sru-lp1908371-focal.patch
1194+s390-tools-sru-lp1902179-focal.patch

Subscribers

People subscribed via source and target branches