diff --git a/SOURCES/0269-RHBZ-1804420-remove-kpartx-limit.patch b/SOURCES/0269-RHBZ-1804420-remove-kpartx-limit.patch new file mode 100644 index 0000000..03d64bd --- /dev/null +++ b/SOURCES/0269-RHBZ-1804420-remove-kpartx-limit.patch @@ -0,0 +1,272 @@ +--- + kpartx/lopart.c | 206 ++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 127 insertions(+), 79 deletions(-) + +Index: multipath-tools-130222/kpartx/lopart.c +=================================================================== +--- multipath-tools-130222.orig/kpartx/lopart.c ++++ multipath-tools-130222/kpartx/lopart.c +@@ -25,8 +25,9 @@ + #include + #include + #include ++#include ++#include + #include +-#include + #include + + #include "lopart.h" +@@ -96,97 +97,149 @@ is_loop_device (const char *device) + #define SIZE(a) (sizeof(a)/sizeof(a[0])) + + extern char * +-find_loop_by_file (const char * filename) ++find_loop_by_file(const char *filename) + { +- char dev[64]; +- char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" }; +- int i, j, fd; ++ DIR *dir; ++ struct dirent *dent; ++ char dev[64], *found = NULL, *p; ++ int fd, bytes_read; + struct stat statbuf; + struct loop_info loopinfo; ++ const char VIRT_BLOCK[] = "/sys/devices/virtual/block"; ++ char path[PATH_MAX]; ++ char bf_path[PATH_MAX]; ++ char backing_file[PATH_MAX]; + +- for (j = 0; j < SIZE(loop_formats); j++) { ++ dir = opendir(VIRT_BLOCK); ++ if (!dir) ++ return NULL; + +- for (i = 0; i < 256; i++) { +- sprintf (dev, loop_formats[j], i); ++ while ((dent = readdir(dir)) != NULL) { ++ if (strncmp(dent->d_name,"loop",4)) ++ continue; + +- if (stat (dev, &statbuf) != 0 || +- !S_ISBLK(statbuf.st_mode)) +- continue; ++ if (snprintf(path, PATH_MAX, "%s/%s/dev", VIRT_BLOCK, ++ dent->d_name) >= PATH_MAX) ++ continue; + +- fd = open (dev, O_RDONLY); ++ fd = open(path, O_RDONLY); ++ if (fd < 0) ++ continue; + +- if (fd < 0) +- break; ++ bytes_read = read(fd, dev, sizeof(dev) - 1); ++ if (bytes_read <= 0) { ++ close(fd); ++ continue; ++ } + +- if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) != 0) { +- close (fd); +- continue; +- } ++ close(fd); + +- if (0 == strcmp(filename, loopinfo.lo_name)) { +- close (fd); +- return xstrdup(dev); /*found */ +- } ++ dev[bytes_read] = '\0'; ++ p = strchr(dev, '\n'); ++ if (p != NULL) ++ *p = '\0'; ++ if (snprintf(path, PATH_MAX, "/dev/block/%s", dev) >= PATH_MAX) ++ continue; + ++ fd = open (path, O_RDONLY); ++ if (fd < 0) ++ continue; ++ ++ if (fstat (fd, &statbuf) != 0 || ++ !S_ISBLK(statbuf.st_mode)) { ++ close (fd); ++ continue; ++ } ++ ++ if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) != 0) { + close (fd); + continue; + } ++ ++ close (fd); ++ ++ if (0 == strcmp(filename, loopinfo.lo_name)) { ++ found = realpath(path, NULL); ++ break; ++ } ++ ++ /* ++ * filename is a realpath, while loopinfo.lo_name may hold just the ++ * basename. If that's the case, try to match filename against the ++ * backing_file entry for this loop entry ++ */ ++ if (snprintf(bf_path, PATH_MAX, "%s/%s/loop/backing_file", ++ VIRT_BLOCK, dent->d_name) >= PATH_MAX) ++ continue; ++ ++ fd = open(bf_path, O_RDONLY); ++ if (fd < 0) ++ continue; ++ ++ bytes_read = read(fd, backing_file, sizeof(backing_file) - 1); ++ if (bytes_read <= 0) { ++ close(fd); ++ continue; ++ } ++ ++ close(fd); ++ ++ backing_file[bytes_read-1] = '\0'; ++ ++ if (0 == strcmp(filename, backing_file)) { ++ found = realpath(path, NULL); ++ break; ++ } + } +- return NULL; ++ closedir(dir); ++ return found; + } + + extern char * +-find_unused_loop_device (void) ++find_unused_loop_device(void) + { +- /* Just creating a device, say in /tmp, is probably a bad idea - +- people might have problems with backup or so. +- So, we just try /dev/loop[0-7]. */ +- +- char dev[20]; +- char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" }; +- int i, j, fd, first = 0, somedev = 0, someloop = 0, loop_known = 0; ++ char dev[20], *next_loop_dev = NULL; ++ int fd, next_loop = 0, somedev = 0, someloop = 0, loop_known = 0; + struct stat statbuf; + struct loop_info loopinfo; + FILE *procdev; + +- if (stat("/dev/loop-control", &statbuf) == 0 && +- S_ISCHR(statbuf.st_mode)) { +- fd = open("/dev/loop-control", O_RDWR); +- if (fd >= 0) { +- first = ioctl(fd, LOOP_CTL_GET_FREE); +- close(fd); ++ while (next_loop_dev == NULL) { ++ if (stat("/dev/loop-control", &statbuf) == 0 && ++ S_ISCHR(statbuf.st_mode)) { ++ int next_loop_fd; ++ ++ next_loop_fd = open("/dev/loop-control", O_RDWR); ++ if (next_loop_fd < 0) ++ return NULL; ++ next_loop = ioctl(next_loop_fd, LOOP_CTL_GET_FREE); ++ close(next_loop_fd); ++ if (next_loop < 0) ++ return NULL; + } +- if (first < 0) +- first = 0; +- } +- for (j = 0; j < SIZE(loop_formats); j++) { +- +- for(i = first; i < 256; i++) { +- sprintf(dev, loop_formats[j], i); +- +- if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { +- somedev++; +- fd = open (dev, O_RDONLY); + +- if (fd >= 0) { ++ sprintf(dev, "/dev/loop%d", next_loop); + ++ fd = open (dev, O_RDONLY); ++ if (fd >= 0) { ++ if (fstat (fd, &statbuf) == 0 && ++ S_ISBLK(statbuf.st_mode)) { ++ somedev++; + if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0) +- someloop++; /* in use */ +- +- else if (errno == ENXIO) { +- close (fd); +- return xstrdup(dev);/* probably free */ +- } ++ someloop++; /* in use */ ++ else if (errno == ENXIO) ++ next_loop_dev = xstrdup(dev); + +- close (fd); + } +- ++ close (fd); ++ + /* continue trying as long as devices exist */ + continue; + } + break; +- } + } ++ if (next_loop_dev) ++ return next_loop_dev; + + /* Nothing found. Why not? */ + if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) { +@@ -209,29 +262,24 @@ find_unused_loop_device (void) + fprintf(stderr, "mount: could not find any device /dev/loop#"); + + else if (!someloop) { +- +- if (loop_known == 1) +- fprintf(stderr, +- "mount: Could not find any loop device.\n" +- " Maybe /dev/loop# has a wrong major number?"); +- +- else if (loop_known == -1) +- fprintf(stderr, +- "mount: Could not find any loop device, and, according to %s,\n" +- " this kernel does not know about the loop device.\n" +- " (If so, then recompile or `modprobe loop'.)", +- PROC_DEVICES); +- +- else +- fprintf(stderr, +- "mount: Could not find any loop device. Maybe this kernel does not know\n" +- " about the loop device (then recompile or `modprobe loop'), or\n" +- " maybe /dev/loop# has the wrong major number?"); +- ++ if (loop_known == 1) ++ fprintf(stderr, ++ "mount: Could not find any loop device.\n" ++ " Maybe /dev/loop# has a wrong major number?"); ++ else if (loop_known == -1) ++ fprintf(stderr, ++ "mount: Could not find any loop device, and, according to %s,\n" ++ " this kernel does not know about the loop device.\n" ++ " (If so, then recompile or `modprobe loop'.)", ++ PROC_DEVICES); ++ else ++ fprintf(stderr, ++ "mount: Could not find any loop device. Maybe this kernel does not know\n" ++ " about the loop device (then recompile or `modprobe loop'), or\n" ++ " maybe /dev/loop# has the wrong major number?"); + } else + fprintf(stderr, "mount: could not find any free loop device"); +- +- return 0; ++ return NULL; + } + + extern int diff --git a/SOURCES/0270-RHBZ-1775481-segfault-fix.patch b/SOURCES/0270-RHBZ-1775481-segfault-fix.patch new file mode 100644 index 0000000..c15be60 --- /dev/null +++ b/SOURCES/0270-RHBZ-1775481-segfault-fix.patch @@ -0,0 +1,51 @@ +--- + kpartx/devmapper.c | 3 ++- + libmultipath/devmapper.c | 7 ++++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/kpartx/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/kpartx/devmapper.c ++++ multipath-tools-130222/kpartx/devmapper.c +@@ -330,7 +330,8 @@ dm_get_map(int major, int minor, char * + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + +- if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) ++ if (params && ++ snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) + r = 0; + out: + dm_task_destroy(dmt); +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -461,6 +461,8 @@ dm_get_map(const char * name, unsigned l + /* Fetch 1st target */ + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); ++ if (!params) ++ goto out; + + if (size) + *size = length; +@@ -564,7 +566,8 @@ dm_get_status(char * name, char * outsta + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, &status); + +- if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) ++ if (status && ++ snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) + r = 0; + out: + if (r) +@@ -1525,6 +1528,8 @@ int dm_reassign_table(const char *name, + do { + next = dm_get_next_target(dmt, next, &start, &length, + &target, ¶ms); ++ if (!params || !target) ++ continue; + memset(buff, 0, PARAMS_SIZE); + strcpy(buff, params); + if (strcmp(target, TGT_MPATH) && strstr(params, old)) { diff --git a/SOURCES/0271-RHBZ-1806197-mpathconf-typo.patch b/SOURCES/0271-RHBZ-1806197-mpathconf-typo.patch new file mode 100644 index 0000000..a9bf727 --- /dev/null +++ b/SOURCES/0271-RHBZ-1806197-mpathconf-typo.patch @@ -0,0 +1,26 @@ +--- + multipath/multipath.conf.5 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -213,7 +213,7 @@ Default value is \fBconst\fR. + .RE + .TP + .B prio_args +-Arguments to pass to to the prio function. This only applies to certain ++Arguments to pass to the prio function. This only applies to certain + prioritizers + .RS + .TP 12 +@@ -228,7 +228,7 @@ regex can be of device name format Ex: + regex can be of the form + .I "host_wwnn:host_wwpn:target_wwnn:target_wwpn" + these values can be looked up through sysfs or by running +-.I mulitpathd show paths format "%N:%R:%n:%r" ++.I multipathd show paths format "%N:%R:%n:%r" + Ex: 0x200100e08ba0aea0:0x210100e08ba0aea0:.*:.* , .*:.*:iqn.2009-10.com.redhat.msp.lab.ask-06:.* + .TP + .B alua diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 02245ff..1b46e00 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 131%{?dist} +Release: 133%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -275,6 +275,9 @@ Patch0265: 0265-RHBZ-1721855-mpathpersist-speedup.patch Patch0266: 0266-RHBZ-1696817-fix-emc-checker.patch Patch0267: 0267-RHBZ-1661156-powermax-config.patch Patch0268: 0268-RHBZ-1721855-mpathpersist-fixes.patch +Patch0269: 0269-RHBZ-1804420-remove-kpartx-limit.patch +Patch0270: 0270-RHBZ-1775481-segfault-fix.patch +Patch0271: 0271-RHBZ-1806197-mpathconf-typo.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -630,6 +633,9 @@ device-mapper-multipath's libdmmp C API library %patch0266 -p1 %patch0267 -p1 %patch0268 -p1 +%patch0269 -p1 +%patch0270 -p1 +%patch0271 -p1 cp %{SOURCE1} . %build @@ -747,6 +753,17 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Mar 30 2020 Benjamin Marzinski 0.4.9-133 +- Add 0270-RHBZ-1775481-segfault-fix.patch + * Fix segfault related to missing dm device tables +- 0271-RHBZ-1806197-mpathconf-typo.patch +- Resolves: bz #1775481, #1806197 + +* Mon Mar 30 2020 Benjamin Marzinski 0.4.9-132 +- Add 0269-RHBZ-1804420-remove-kpartx-limit.patch + * Remove the 256 device limit, when searching loop devices with kpartx +- Resolves: bz #1804420 + * Tue Dec 10 2019 Benjamin Marzinski 0.4.9-131 - Modify 0268-RHBZ-1721855-mpathpersist-fixes.patch * The fix for 1721855 broke 1714506.