forked from pool/s390-tools
87107bff8d
- Added s390-tools-sles15sp4-zdev-modify-the-lsblk-output-parser-in-lszdev.patch for bsc#1196255. Version 2.37+ of util-linux modified the output characters of lsblk,which breaks the parser function. - Added s390-tools-sles15sp4-zdev-Fix-path-resolution-for-multi-mount-point-file-.patch for bsc#1196254. Path resolution fails when a device provides multiple mount points such as, for example, when using btrfs subvolumes, or when mounting the same file system at multiple mount points. OBS-URL: https://build.opensuse.org/request/show/956861 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=127
170 lines
6.2 KiB
Diff
170 lines
6.2 KiB
Diff
Subject: [PATCH] [BZ 196440] zdev: Fix path resolution for multi-mount point file systems
|
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
|
|
Description: zdev: Fix path resolution for multi-mount point file systems
|
|
Symptom: Path resolution fails when a device provides multiple mount
|
|
points such as, for example, when using btrfs subvolumes, or
|
|
when mounting the same file system at multiple mount points.
|
|
Problem: The failure is caused by zdev relying on the MOUNTPOINT
|
|
attribute of lsblk's output which only contains a single
|
|
mount point.
|
|
Solution: Fix this by making use of lsblk's MOUNTPOINTS attribute that
|
|
contains the full list of mount points.
|
|
Reproduction: chzdev -f -e <dev_id_a> <dev_id_b> <dev_id_c>: In this case, if
|
|
the rootfs is soread across multiple devices, zdev adds only the
|
|
first device in to the initrd and the system does not boot.
|
|
Upstream-ID: 1faa5d2957eb82ab235778959d70a38062b7aa7d
|
|
Problem-ID: 196440
|
|
|
|
Upstream-Description:
|
|
|
|
zdev: Fix path resolution for multi-mount point file systems
|
|
|
|
zdev provides path resolution logic to determine which z-specific
|
|
devices contribute to the file system mounted at a specific mount point.
|
|
This logic is used by command-line option --by-path, but also to
|
|
determine the list of devices needed to enable the root file system.
|
|
|
|
Path resolution fails when a device provides multiple mount points such
|
|
as, for example, when using btrfs subvolumes, or when mounting the same
|
|
file system at multiple mount points. The failure is caused by zdev
|
|
relying on the MOUNTPOINT attribute of lsblk's output which only
|
|
contains a single mount point.
|
|
|
|
Fix this by making use of lsblk's MOUNTPOINTS attribute that contains
|
|
the full list of mount points. Note that MOUNTPOINTS was only introduced
|
|
with util-linux v2.37, therefore a fall-back to the old format is
|
|
needed.
|
|
|
|
Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/129
|
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
|
|
Reviewed-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Reported-by: Dan Horak <dan@danny.cz>
|
|
Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
|
|
|
|
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
|
Index: s390-tools-service/zdev/src/blkinfo.c
|
|
===================================================================
|
|
--- s390-tools-service.orig/zdev/src/blkinfo.c
|
|
+++ s390-tools-service/zdev/src/blkinfo.c
|
|
@@ -7,6 +7,7 @@
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
+#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
@@ -16,6 +17,7 @@
|
|
#include "misc.h"
|
|
|
|
#define LSBLK_CMDLINE "lsblk -P -o NAME,MAJ:MIN,FSTYPE,UUID,MOUNTPOINT,PKNAME 2>/dev/null"
|
|
+#define LSBLK_CMDLINE2 "lsblk -P -o NAME,MAJ:MIN,FSTYPE,UUID,MOUNTPOINTS,PKNAME 2>/dev/null"
|
|
|
|
struct blkinfo {
|
|
struct devnode *devnode;
|
|
@@ -82,6 +84,26 @@ void blkinfo_print(struct blkinfo *blkin
|
|
printf("%*sparent=%s\n", level, "", blkinfo->parent);
|
|
}
|
|
|
|
+/* Convert each occurrence of '\xnn' in @str to character with hex code <nn>. */
|
|
+static void hex_unescape(char *str)
|
|
+{
|
|
+ unsigned int c;
|
|
+
|
|
+ while ((str = strstr(str, "\\x"))) {
|
|
+ if (isxdigit(str[2]) && isxdigit(str[3]) &&
|
|
+ sscanf(str + 2, "%2x", &c) == 1) {
|
|
+ str[0] = (char)c;
|
|
+
|
|
+ /* Move remainder of str including nul behind <c>. */
|
|
+ memmove(str + /* <c> */ 1,
|
|
+ str + /* '\xnn' */ 4,
|
|
+ strlen(str + 4) + /* <nul> */ 1);
|
|
+ }
|
|
+
|
|
+ str++;
|
|
+ }
|
|
+}
|
|
+
|
|
static char *isolate_keyword(char **line_ptr, const char *keyword)
|
|
{
|
|
char *start, *end;
|
|
@@ -102,9 +124,11 @@ static char *isolate_keyword(char **line
|
|
return start;
|
|
}
|
|
|
|
-static struct blkinfo *blkinfo_from_line(char *line)
|
|
+static void add_blkinfos_from_line(struct util_list *blkinfos,
|
|
+ char *line)
|
|
{
|
|
- char *name, *majmin, *fstype, *uuid, *mountpoint, *parent;
|
|
+ char *name, *majmin, *fstype, *uuid, *mountpoint, *mountpoints, *parent;
|
|
+ struct blkinfo *blkinfo;
|
|
|
|
name = isolate_keyword(&line, "NAME=\"");
|
|
majmin = isolate_keyword(&line, "MAJ:MIN=\"");
|
|
@@ -113,21 +137,45 @@ static struct blkinfo *blkinfo_from_line
|
|
fstype = isolate_keyword(&line, "FSTYPE=\"");
|
|
uuid = isolate_keyword(&line, "UUID=\"");
|
|
mountpoint = isolate_keyword(&line, "MOUNTPOINT=\"");
|
|
+ mountpoints = isolate_keyword(&line, "MOUNTPOINTS=\"");
|
|
parent = isolate_keyword(&line, "PKNAME=\"");
|
|
|
|
- return blkinfo_new(name, majmin, fstype, uuid, mountpoint, parent);
|
|
+ if (!mountpoints) {
|
|
+ /* Handle old lsblk output format. */
|
|
+ blkinfo = blkinfo_new(name, majmin, fstype, uuid, mountpoint,
|
|
+ parent);
|
|
+ ptrlist_add(blkinfos, blkinfo);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* Restore newline mount point separator encoded as hex. */
|
|
+ hex_unescape(mountpoints);
|
|
+
|
|
+ /* Represent each mount point as a separate blkinfo to support
|
|
+ * resolution of multi-mount point file systems like btrfs
|
|
+ * subvolumes. */
|
|
+ while ((mountpoint = strsep(&mountpoints, "\n"))) {
|
|
+ blkinfo = blkinfo_new(name, majmin, fstype, uuid, mountpoint,
|
|
+ parent);
|
|
+ ptrlist_add(blkinfos, blkinfo);
|
|
+ }
|
|
}
|
|
|
|
static struct util_list *blkinfos_read(void)
|
|
{
|
|
char *output, *curr, *next;
|
|
struct util_list *blkinfos;
|
|
- struct blkinfo *blkinfo;
|
|
|
|
if (cached_blkinfos)
|
|
return cached_blkinfos;
|
|
|
|
- output = misc_read_cmd_output(LSBLK_CMDLINE, 0, 1);
|
|
+ output = misc_read_cmd_output(LSBLK_CMDLINE2, 0, 1);
|
|
+ if (output && !*output) {
|
|
+ /* No output might indicate no support for new lsblk command-
|
|
+ * line format - fall back to old format. */
|
|
+ free(output);
|
|
+ output = misc_read_cmd_output(LSBLK_CMDLINE, 0, 1);
|
|
+ }
|
|
if (!output)
|
|
return NULL;
|
|
|
|
@@ -136,9 +184,7 @@ static struct util_list *blkinfos_read(v
|
|
/* Iterate over each line. */
|
|
next = output;
|
|
while ((curr = strsep(&next, "\n"))) {
|
|
- blkinfo = blkinfo_from_line(curr);
|
|
- if (blkinfo)
|
|
- ptrlist_add(blkinfos, blkinfo);
|
|
+ add_blkinfos_from_line(blkinfos, curr);
|
|
}
|
|
|
|
free(output);
|