Hello community,

here is the log from the commit of package lvm2 for openSUSE:Factory checked in 
at 2014-04-05 16:50:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lvm2 (Old)
 and      /work/SRC/openSUSE:Factory/.lvm2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lvm2"

Changes:
--------
--- /work/SRC/openSUSE:Factory/lvm2/lvm2.changes        2014-02-25 
16:41:21.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.lvm2.new/lvm2.changes   2014-04-05 
16:50:18.000000000 +0200
@@ -1,0 +2,25 @@
+Tue Mar 25 09:08:16 UTC 2014 - dmzh...@suse.com
+
+- backport more patches from slesp3(bnc#831518)
+  scm support:
+    add_scm_support.patch
+  mirrored log fix:
+    do_not_read_from_mirrors_have_failed_devices.diff
+    avoid_reading_failed_dev_in_mirrored_log.diff
+    mirrored_log_fixed_when_double_fault_occurs.diff
+    device_is_usable_mem_leak.diff
+  clvmd:
+    clmvd-fix-decriptor-leak-on-restart.patch
+    clvmd-Avoid-a-3-way-deadlock-in-dead-client-cleanup.patch
+    clvmd-Fix-node-up-down-handing-in-corosync-module.patch
+    0001-clvmd-avoid-logging-in-signal-handler.patch
+  fate#314367, missing patch
+    lvconvert-cluster-mirrored-disk-failed.patch
+  other fix:
+    pvmove_support_clustered_vg.diff
+    suppress_format1_size_warning.diff
+    display-dm-name-for-lv-name.diff
+  no longer needed patches:
+    autoactivate-lvmetad-with-generator.patch
+
+-------------------------------------------------------------------

Old:
----
  autoactivate-lvmetad-with-generator.patch

New:
----
  0001-clvmd-avoid-logging-in-signal-handler.patch
  add_scm_support.patch
  avoid_reading_failed_dev_in_mirrored_log.diff
  clmvd-fix-decriptor-leak-on-restart.patch
  clvmd-Avoid-a-3-way-deadlock-in-dead-client-cleanup.patch
  clvmd-Fix-node-up-down-handing-in-corosync-module.patch
  device_is_usable_mem_leak.diff
  display-dm-name-for-lv-name.diff
  do_not_read_from_mirrors_have_failed_devices.diff
  lvconvert-cluster-mirrored-disk-failed.patch
  mirrored_log_fixed_when_double_fault_occurs.diff
  pvmove_support_clustered_vg.diff
  suppress_format1_size_warning.diff

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ lvm2.spec ++++++
--- /var/tmp/diff_new_pack.kSLzIV/_old  2014-04-05 16:50:20.000000000 +0200
+++ /var/tmp/diff_new_pack.kSLzIV/_new  2014-04-05 16:50:20.000000000 +0200
@@ -25,6 +25,7 @@
 BuildRequires:  libselinux-devel
 BuildRequires:  libudev-devel
 BuildRequires:  readline-devel
+BuildRequires:  systemd-rpm-macros
 BuildRequires:  pkgconfig(udev)
 Requires:       device-mapper >= 1.02.25
 Provides:       lvm
@@ -37,17 +38,11 @@
 Source:         ftp://sources.redhat.com/pub/%{name}/LVM2.%{version}.tgz
 Source42:       ftp://sources.redhat.com/pub/%{name}/LVM2.%{version}.tgz.asc
 Source1:        lvm.conf
-#Source2:        boot.lvm
 Source4:        mkinitrd-lvm2-setup.sh
 Source5:        mkinitrd-lvm2-boot.sh
-#Source6:        64-lvm2.rules
-#Source7:        collect_lvm
 Source8:        clvmd.ocf
 Source10:       cmirrord.ocf
-#Source12:       mkinitrd-devmapper-setup.sh
-#Source13:       mkinitrd-devmapper-boot.sh
 Source14:       baselibs.conf
-#Source15:       lvm2-activation.service
 Source16:       csm-converter.tar.gz
 
 Patch:          improve_probing.diff
@@ -60,6 +55,9 @@
 
 Patch20:        support-drbd-filter.diff
 Patch22:        handle_extended_devt.diff
+#suse
+Patch23:        display-dm-name-for-lv-name.diff
+
 Patch66:        device-mapper-type_punning.diff
 Patch67:        lvm-path.patch
 
@@ -67,24 +65,41 @@
 Patch68:        make-mirror-legs-on-different-tag-pvs.patch
 Patch69:        improve-mirror-legs-on-different-tag-pvs.patch
 
-#fate#314367
-Patch70:        cluster_support_mirrord_log.diff
-
 #upstream
 Patch71:        make_raid1_default.diff
 #suppress warning
 Patch72:        suppress_locking_failer_message.patch
+#upstream
 Patch73:        remove-fedora-systemd.patch
 
-#bnc#862076
-Patch74:        autoactivate-lvmetad-with-generator.patch
-
 #fate#315092
 Patch75:        cmirrord_improvment_performance.patch
 
 #bnc#862076
 Patch76:        0001-lvmetad-Init-lazily-to-avoid-socket-access-on-config.patch
 
+#fate#314367
+Patch77:        cluster_support_mirrord_log.diff
+Patch78:        lvconvert-cluster-mirrored-disk-failed.patch
+
+Patch79:        add_scm_support.patch
+
+#upstream backport
+Patch80:        do_not_read_from_mirrors_have_failed_devices.diff
+Patch81:        avoid_reading_failed_dev_in_mirrored_log.diff
+Patch82:        mirrored_log_fixed_when_double_fault_occurs.diff
+Patch83:        device_is_usable_mem_leak.diff
+
+#forward-port from sle11
+Patch84:        suppress_format1_size_warning.diff
+Patch85:        pvmove_support_clustered_vg.diff
+
+#upstream
+Patch86:        clmvd-fix-decriptor-leak-on-restart.patch
+Patch87:        clvmd-Fix-node-up-down-handing-in-corosync-module.patch
+Patch88:        clvmd-Avoid-a-3-way-deadlock-in-dead-client-cleanup.patch
+Patch89:        0001-clvmd-avoid-logging-in-signal-handler.patch
+
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 # Not a real replacement but we drop evms
 Provides:       evms = 2.5.5
@@ -115,17 +130,29 @@
 %patch13 -p1
 %patch20 -p1
 %patch22 -p1
+%patch23 -p1
 %patch66 -p1
 %patch67 -p1
 %patch68 -p1
 %patch69 -p1
-%patch70 -p1
 %patch71 -p1
 %patch72 -p1
 %patch73 -p1
-%patch74 -p1
 %patch75 -p1
 %patch76 -p1
+%patch77 -p1
+%patch78 -p1
+%patch79 -p1
+%patch80 -p1
+%patch81 -p1
+%patch82 -p1
+%patch83 -p1
+%patch84 -p1
+%patch85 -p1
+%patch86 -p1
+%patch87 -p1
+%patch88 -p1
+%patch89 -p1
 
 %build
 #set path so that thin_check can be found
@@ -221,17 +248,18 @@
 popd
 
 %post
-%service_add_post blk-availability.service lvm2-monitor.service 
lvm2-lvmetad.socket
-/usr/bin/systemctl enable lvm2-lvmetad.socket
-[ -x /sbin/mkinitrd ] && /sbin/mkinitrd
 /sbin/ldconfig
+[ -x /sbin/mkinitrd ] && /sbin/mkinitrd
+%service_add_post blk-availability.service lvm2-monitor.service
+%service_add_post lvm2-lvmetad.socket
 
 %preun
 %service_del_preun blk-availability.service lvm2-monitor.service 
lvm2-lvmetad.service lvm2-lvmetad.socket
 
 %postun
-[ -x /sbin/mkinitrd ] && /sbin/mkinitrd
 /sbin/ldconfig
+[ -x /sbin/mkinitrd ] && /sbin/mkinitrd
+%service_del_postun lvm2-lvmetad.service
 
 %files
 %defattr(-,root,root)

++++++ 0001-clvmd-avoid-logging-in-signal-handler.patch ++++++
>From 5070ffbca7b16e4139b3da72bdff0c9add517351 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabe...@redhat.com>
Date: Wed, 17 Apr 2013 23:16:30 +0200
Subject: [PATCH] clvmd: avoid logging in signal handler

debuglog in the main thread.
---
 daemons/clvmd/clvmd.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index c649bbe..a64bd54 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -874,6 +874,7 @@ static void main_loop(int local_sock, int cmd_timeout)
                        int saved_errno = errno;
 
                        reread_config = 0;
+                       DEBUGLOG("got SIGHUP\n");
                        if (clops->reread_config)
                                clops->reread_config();
                        errno = saved_errno;
@@ -982,6 +983,8 @@ static void main_loop(int local_sock, int cmd_timeout)
 
       closedown:
        clops->cluster_closedown();
+       if (quit)
+               DEBUGLOG("SIGTERM received\n");
 }
 
 static __attribute__ ((noreturn)) void wait_for_child(int c_pipe, int timeout)
@@ -2253,14 +2256,12 @@ static void sigusr2_handler(int sig)
 
 static void sigterm_handler(int sig)
 {
-       DEBUGLOG("SIGTERM received\n");
        quit = 1;
        return;
 }
 
 static void sighup_handler(int sig)
 {
-        DEBUGLOG("got SIGHUP\n");
        reread_config = 1;
 }
 
-- 
1.8.4.5


++++++ add_scm_support.patch ++++++
filters: add scm devices

Fix this:
pvcreate /dev/scma
 Device /dev/scma not found (or ignored by filtering).

Upstream via:
        9602e68 filters: add scm devices

Signed-off-by: Sebastian Ott <seb...@linux.vnet.ibm.com>
---
 lib/filters/device-types.h |    1 +
 1 file changed, 1 insertion(+)

--- a/lib/filters/device-types.h
+++ b/lib/filters/device-types.h
@@ -56,5 +56,6 @@ static const device_info_t _device_info[
        {"blkext", 1},          /* Extended device partitions */
        {"fio", 16},            /* Fusion */
        {"mtip32xx", 16},       /* Micron PCIe SSDs */
+       {"scm", 8},             /* Storage Class Memory (IBM S/390) */
        {"", 0}
 };

++++++ avoid_reading_failed_dev_in_mirrored_log.diff ++++++
commit b248ba0a396d7fc9a459eea02cfdc70b33ce3441
Author: Jonathan Brassow <jbras...@redhat.com>
Date:   Thu Oct 25 00:42:45 2012 -0500

    mirror:  Avoid reading mirrors with failed devices in mirrored log
    
    Commit 9fd7ac7d035f0b2f8dcc3cb19935eb181816bd76 did not handle mirrors
    that contained mirrored logs.  This is because the status line of the
    mirror does not give an indication of the health of the mirrored log,
    as you can see here:
            [root@bp-01 lvm2]# dmsetup status vg-lv vg-lv_mlog
            vg-lv: 0 409600 mirror 2 253:6 253:7 400/400 1 AA 3 disk 253:5 A
            vg-lv_mlog: 0 8192 mirror 2 253:3 253:4 7/8 1 AD 1 core
    Thus, the possibility for LVM commands to hang still persists when mirror
    have mirrored logs.  I discovered this while performing some testing that
    does polling with 'pvs' while doing I/O and killing devices.  The 'pvs'
    managed to get between the mirrored log device failure and the attempt
    by dmeventd to repair it.  The result was a very nasty block in LVM
    commands that is very difficult to remove - even for someone who knows
    what is going on.  Thus, it is absolutely essential that the log of a
    mirror be recursively checked for mirror devices which may be failed
    as well.
    
    Despite what the code comment says in the aforementioned commit...
    + * _mirrored_transient_status().  FIXME: It is unable to handle mirrors
    + * with mirrored logs because it does not have a way to get the status of
    + * the mirror that forms the log, which could be blocked.
    ... it is possible to get the status of the log because the log device
    major/minor is given to us by the status output of the top-level mirror.
    We can use that to query the log device for any DM status and see if it
    is a mirror that needs to be bypassed.  This patch does just that and is
    now able to avoid reading from mirrors that have failed devices in a
    mirrored log.

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 6cc57d0..40f719e 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -139,6 +139,7 @@ static int _info_run(const char *name, const char *dlid, 
struct dm_info *info,
  * _parse_mirror_status
  * @mirror_status_string
  * @image_health:  return for allocated copy of image health characters
+ * @log_device: return for 'dev_t' of log device
  * @log_health: NULL if corelog, otherwise alloc'ed log health char
  *
  * This function takes the mirror status string, breaks it up and returns
@@ -149,8 +150,10 @@ static int _info_run(const char *name, const char *dlid, 
struct dm_info *info,
  * Returns: 1 on success, 0 on failure
  */
 static int _parse_mirror_status(char *mirror_status_str,
-                               char **images_health, char **log_health)
+                               char **images_health,
+                               dev_t *log_dev, char **log_health)
 {
+       int major, minor;
        char *p = NULL;
        char **args, **log_args;
        unsigned num_devs, log_argc;
@@ -174,10 +177,14 @@ static int _parse_mirror_status(char *mirror_status_str,
                return_0;
 
        *log_health = NULL;
-       if (!strcmp(log_args[0], "disk") &&
-           !(*log_health = dm_strdup(log_args[2])))
-               return_0;
-
+       *log_dev = 0;
+       if (!strcmp(log_args[0], "disk")) {
+               if (!(*log_health = dm_strdup(log_args[2])))
+                       return_0;
+               if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2)
+                       return_0;
+               *log_dev = MKDEV((dev_t)major, minor);
+       }
        if (!(*images_health = dm_strdup(args[2 + num_devs])))
                return_0;
 
@@ -199,9 +206,7 @@ static int _parse_mirror_status(char *mirror_status_str,
  * attempting to read a mirror, a circular dependency would be created.)
  *
  * This function is a slimmed-down version of lib/mirror/mirrored.c:
- * _mirrored_transient_status().  FIXME: It is unable to handle mirrors
- * with mirrored logs because it does not have a way to get the status of
- * the mirror that forms the log, which could be blocked.
+ * _mirrored_transient_status().
  *
  * If a failed device is detected in the status string, then it must be
  * determined if 'block_on_error' or 'handle_errors' was used when
@@ -217,23 +222,17 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
                                          char *mirror_status_str)
 {
        unsigned i, check_for_blocking = 0;
+       dev_t log_dev;
        char *images_health, *log_health;
-
        uint64_t s,l;
        char *params, *target_type = NULL;
        void *next = NULL;
        struct dm_task *dmt;
 
        if (!_parse_mirror_status(mirror_status_str,
-                                 &images_health, &log_health))
+                                 &images_health, &log_dev, &log_health))
                goto_out;
 
-       if (log_health && (log_health[0] != 'A')) {
-               log_debug("%s: Mirror log device marked as failed",
-                         dev_name(dev));
-               check_for_blocking = 1;
-       }
-
        for (i = 0; images_health[i]; i++)
                if (images_health[i] != 'A') {
                        log_debug("%s: Mirror image %d marked as failed",
@@ -241,6 +240,29 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
                        check_for_blocking = 1;
                }
 
+       if (!check_for_blocking && log_dev) {
+               if (log_health[0] != 'A') {
+                       log_debug("%s: Mirror log device marked as failed",
+                                 dev_name(dev));
+                       check_for_blocking = 1;
+               } else {
+                       struct device *tmp_dev;
+                       char buf[16];
+
+                       if (dm_snprintf(buf, sizeof(buf), "%d:%d",
+                                       (int)MAJOR(log_dev),
+                                       (int)MINOR(log_dev)) < 0)
+                               goto_out;
+
+                       if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 1)))
+                               goto_out;
+
+                       tmp_dev->dev = log_dev;
+                       if (!device_is_usable(tmp_dev))
+                               goto_out;
+               }
+       }
+
        if (!check_for_blocking)
                return 0;
 
++++++ clmvd-fix-decriptor-leak-on-restart.patch ++++++
>From 7b1315411f1de73801fd38f264ca507ae3807e53 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabe...@redhat.com>
Date: Tue, 6 Aug 2013 16:07:50 +0200
Subject: [PATCH] clmvd: fix decriptor leak on restart

Do not leave descriptor used for dup2() openned.
---
 daemons/clvmd/clvmd.c | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/daemons/clvmd/clvmd.c b/daemons/clvmd/clvmd.c
index f05776f..eaa75ca 100644
--- a/daemons/clvmd/clvmd.c
+++ b/daemons/clvmd/clvmd.c
@@ -1085,6 +1085,10 @@ static void be_daemon(int timeout)
                log_error("Error setting terminal FDs to /dev/null: %m");
                exit(5);
        }
+       if ((devnull > STDERR_FILENO) && close(devnull)) {
+               log_sys_error("close", "/dev/null");
+               exit(7);
+       }
        if (chdir("/")) {
                log_error("Error setting current directory to /: %m");
                exit(6);
-- 
1.8.4.5

++++++ clvmd-Avoid-a-3-way-deadlock-in-dead-client-cleanup.patch ++++++
>From 25bed9968155f43ef0b8832383ef711e7ae1685d Mon Sep 17 00:00:00 2001
From: Petr Rockai <proc...@redhat.com>
Date: Mon, 9 Sep 2013 00:01:44 +0200
Subject: [PATCH] clvmd: Avoid a 3-way deadlock in dead-client cleanup.

---
 daemons/clvmd/clvmd.c | 177 +++++++++++++++++++++++++++-----------------------
 daemons/clvmd/clvmd.h |   1 +
 2 files changed, 96 insertions(+), 82 deletions(-)

Index: LVM2.2.02.98/daemons/clvmd/clvmd.c
===================================================================
--- LVM2.2.02.98.orig/daemons/clvmd/clvmd.c     2014-03-18 16:14:07.237654914 
+0800
+++ LVM2.2.02.98/daemons/clvmd/clvmd.c  2014-03-18 16:14:07.272654866 +0800
@@ -120,6 +120,7 @@ static void *pre_and_post_thread(void *a
 static int send_message(void *buf, int msglen, const char *csid, int fd,
                        const char *errtext);
 static int read_from_local_sock(struct local_client *thisfd);
+static int cleanup_zombie(struct local_client *thisfd);
 static int process_local_command(struct clvm_header *msg, int msglen,
                                 struct local_client *client,
                                 unsigned short xid);
@@ -694,6 +695,7 @@ static int local_rendezvous_callback(str
                newfd->bits.localsock.sent_out = FALSE;
                newfd->bits.localsock.threadid = 0;
                newfd->bits.localsock.finished = 0;
+               newfd->bits.localsock.cleanup_needed = 0;
                newfd->bits.localsock.pipe_client = NULL;
                newfd->bits.localsock.private = NULL;
                newfd->bits.localsock.all_success = 1;
@@ -884,7 +886,7 @@ static void main_loop(int local_sock, in
                        for (thisfd = &local_client_head; thisfd != NULL;
                             thisfd = thisfd->next) {
 
-                               if (thisfd->removeme) {
+                               if (thisfd->removeme && 
!cleanup_zombie(thisfd)) {
                                        struct local_client *free_fd;
                                        lastfd->next = thisfd->next;
                                        free_fd = thisfd;
@@ -911,7 +913,6 @@ static void main_loop(int local_sock, in
 
                                        /* Got error or EOF: Remove it from the 
list safely */
                                        if (ret <= 0) {
-                                               struct local_client *free_fd;
                                                int type = thisfd->type;
 
                                                /* If the cluster socket shuts 
down, so do we */
@@ -921,12 +922,7 @@ static void main_loop(int local_sock, in
 
                                                DEBUGLOG("ret == %d, errno = 
%d. removing client\n",
                                                         ret, errno);
-                                               lastfd->next = thisfd->next;
-                                               free_fd = thisfd;
-                                               safe_close(&(free_fd->fd));
-
-                                               /* Queue cleanup, this also 
frees the client struct */
-                                               add_to_lvmqueue(free_fd, NULL, 
0, NULL);
+                                               thisfd->removeme = 1;
                                                break;
                                        }
 
@@ -1089,6 +1085,95 @@ static void be_daemon(int timeout)
 
 }
 
+static int cleanup_zombie(struct local_client *thisfd)
+{
+       int *status;
+
+       if (thisfd->type != LOCAL_SOCK)
+               return 0;
+
+       if (!thisfd->bits.localsock.cleanup_needed)
+               return 0;
+
+       DEBUGLOG("EOF on local socket: inprogress=%d\n",
+                thisfd->bits.localsock.in_progress);
+
+       thisfd->bits.localsock.finished = 1;
+
+       /* If the client went away in mid command then tidy up */
+       if (thisfd->bits.localsock.in_progress) {
+               pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
+               if (pthread_mutex_trylock(&thisfd->bits.localsock.mutex))
+                       goto bail;
+               thisfd->bits.localsock.state = POST_COMMAND;
+               pthread_cond_signal(&thisfd->bits.localsock.cond);
+               pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
+
+               /* Free any unsent buffers */
+               free_reply(thisfd);
+       }
+
+       /* Kill the subthread & free resources */
+       if (thisfd->bits.localsock.threadid) {
+               DEBUGLOG("Waiting for child thread\n");
+               pthread_mutex_lock(&thisfd->bits.localsock.mutex);
+               thisfd->bits.localsock.state = PRE_COMMAND;
+               pthread_cond_signal(&thisfd->bits.localsock.cond);
+               pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
+
+               if ((errno = pthread_join(thisfd->bits.localsock.threadid,
+                                         (void **) &status)))
+                       log_sys_error("pthread_join", "");
+
+               DEBUGLOG("Joined child thread\n");
+
+               thisfd->bits.localsock.threadid = 0;
+               pthread_cond_destroy(&thisfd->bits.localsock.cond);
+               pthread_mutex_destroy(&thisfd->bits.localsock.mutex);
+
+               /* Remove the pipe client */
+               if (thisfd->bits.localsock.pipe_client != NULL) {
+                       struct local_client *newfd;
+                       struct local_client *lastfd = NULL;
+                       struct local_client *free_fd = NULL;
+
+                       (void) close(thisfd->bits.localsock.pipe_client->fd);   
/* Close pipe */
+                       (void) close(thisfd->bits.localsock.pipe);
+
+                       /* Remove pipe client */
+                       for (newfd = &local_client_head; newfd != NULL;
+                            newfd = newfd->next) {
+                               if (thisfd->bits.localsock.
+                                   pipe_client == newfd) {
+                                       thisfd->bits.localsock.
+                                           pipe_client = NULL;
+
+                                       lastfd->next = newfd->next;
+                                       free_fd = newfd;
+                                       newfd->next = lastfd;
+                                       free(free_fd);
+                                       break;
+                               }
+                               lastfd = newfd;
+                       }
+               }
+       }
+
+       /* Free the command buffer */
+       free(thisfd->bits.localsock.cmd);
+
+       /* Clear out the cross-link */
+       if (thisfd->bits.localsock.pipe_client != NULL)
+               thisfd->bits.localsock.pipe_client->bits.pipe.client =
+                   NULL;
+
+       safe_close(&(thisfd->fd));
+       thisfd->bits.localsock.cleanup_needed = 0;
+       return 0;
+bail:
+       return 1;
+}
+
 /* Called when we have a read from the local socket.
    was in the main loop but it's grown up and is a big girl now */
 static int read_from_local_sock(struct local_client *thisfd)
@@ -1106,80 +1191,8 @@ static int read_from_local_sock(struct l
 
        /* EOF or error on socket */
        if (len <= 0) {
-               int *status;
-
-               DEBUGLOG("EOF on local socket: inprogress=%d\n",
-                        thisfd->bits.localsock.in_progress);
-
-               thisfd->bits.localsock.finished = 1;
-
-               /* If the client went away in mid command then tidy up */
-               if (thisfd->bits.localsock.in_progress) {
-                       pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
-                       pthread_mutex_lock(&thisfd->bits.localsock.mutex);
-                       thisfd->bits.localsock.state = POST_COMMAND;
-                       pthread_cond_signal(&thisfd->bits.localsock.cond);
-                       pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
-
-                       /* Free any unsent buffers */
-                       free_reply(thisfd);
-               }
-
-               /* Kill the subthread & free resources */
-               if (thisfd->bits.localsock.threadid) {
-                       DEBUGLOG("Waiting for child thread\n");
-                       pthread_mutex_lock(&thisfd->bits.localsock.mutex);
-                       thisfd->bits.localsock.state = PRE_COMMAND;
-                       pthread_cond_signal(&thisfd->bits.localsock.cond);
-                       pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
-
-                       if ((errno = 
pthread_join(thisfd->bits.localsock.threadid,
-                                                 (void **) &status)))
-                               log_sys_error("pthread_join", "");
-
-                       DEBUGLOG("Joined child thread\n");
-
-                       thisfd->bits.localsock.threadid = 0;
-                       pthread_cond_destroy(&thisfd->bits.localsock.cond);
-                       pthread_mutex_destroy(&thisfd->bits.localsock.mutex);
-
-                       /* Remove the pipe client */
-                       if (thisfd->bits.localsock.pipe_client != NULL) {
-                               struct local_client *newfd;
-                               struct local_client *lastfd = NULL;
-                               struct local_client *free_fd = NULL;
-
-                               (void) 
close(thisfd->bits.localsock.pipe_client->fd);   /* Close pipe */
-                               (void) close(thisfd->bits.localsock.pipe);
-
-                               /* Remove pipe client */
-                               for (newfd = &local_client_head; newfd != NULL;
-                                    newfd = newfd->next) {
-                                       if (thisfd->bits.localsock.
-                                           pipe_client == newfd) {
-                                               thisfd->bits.localsock.
-                                                   pipe_client = NULL;
-
-                                               lastfd->next = newfd->next;
-                                               free_fd = newfd;
-                                               newfd->next = lastfd;
-                                               free(free_fd);
-                                               break;
-                                       }
-                                       lastfd = newfd;
-                               }
-                       }
-               }
-
-               /* Free the command buffer */
-               free(thisfd->bits.localsock.cmd);
-
-               /* Clear out the cross-link */
-               if (thisfd->bits.localsock.pipe_client != NULL)
-                       thisfd->bits.localsock.pipe_client->bits.pipe.client =
-                           NULL;
-
-               safe_close(&(thisfd->fd));
+               thisfd->bits.localsock.cleanup_needed = 1;
+               cleanup_zombie(thisfd); /* we ignore errors here */
                return 0;
        } else {
                int comms_pipe[2];
Index: LVM2.2.02.98/daemons/clvmd/clvmd.h
===================================================================
--- LVM2.2.02.98.orig/daemons/clvmd/clvmd.h     2012-10-15 22:24:58.000000000 
+0800
+++ LVM2.2.02.98/daemons/clvmd/clvmd.h  2014-03-18 16:14:07.272654866 +0800
@@ -53,6 +53,7 @@ struct localsock_bits {
        int finished;           /* Flag to tell subthread to exit */
        int all_success;        /* Set to 0 if any node (or the pre_command)
                                   failed */
+       int cleanup_needed;     /* helper for cleanup_zombie */
        struct local_client *pipe_client;
        pthread_t threadid;
        enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
++++++ clvmd-Fix-node-up-down-handing-in-corosync-module.patch ++++++
>From 431eda63cc0ebff7c62dacb313cabcffbda6573a Mon Sep 17 00:00:00 2001
From: Christine Caulfield <ccaul...@redhat.com>
Date: Mon, 23 Sep 2013 13:23:00 +0100
Subject: [PATCH] clvmd: Fix node up/down handing in corosync module

The corosync cluster interface for clvmd did not correctly
deal with node up/down events so that when a node was removed
from the cluster clvmd would prevent remote operations
from happening, as it thought the node was up but not
running clvmd.

This patch fixes that code by simplifying the case to node
being  up or down - which was the original intention
and is supported by pacemaker and CPG in the higher layers.

Signed-off-by: Christine Caulfield <ccaul...@redhat.com>
---
 daemons/clvmd/clvmd-corosync.c | 31 ++++---------------------------
 2 files changed, 5 insertions(+), 27 deletions(-)

diff --git a/daemons/clvmd/clvmd-corosync.c b/daemons/clvmd/clvmd-corosync.c
index d85ec1e..9092c8a 100644
--- a/daemons/clvmd/clvmd-corosync.c
+++ b/daemons/clvmd/clvmd-corosync.c
@@ -89,7 +89,7 @@ quorum_callbacks_t quorum_callbacks = {
 
 struct node_info
 {
-       enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
+       enum {NODE_DOWN, NODE_CLVMD} state;
        int nodeid;
 };
 
@@ -255,26 +255,6 @@ static void corosync_cpg_confchg_callback(cpg_handle_t 
handle,
                        ninfo->state = NODE_DOWN;
        }
 
-       for (i=0; i<member_list_entries; i++) {
-               if (member_list[i].nodeid == 0) continue;
-               ninfo = dm_hash_lookup_binary(node_hash,
-                               (char *)&member_list[i].nodeid,
-                               COROSYNC_CSID_LEN);
-               if (!ninfo) {
-                       ninfo = malloc(sizeof(struct node_info));
-                       if (!ninfo) {
-                               break;
-                       }
-                       else {
-                               ninfo->nodeid = member_list[i].nodeid;
-                               dm_hash_insert_binary(node_hash,
-                                               (char *)&ninfo->nodeid,
-                                               COROSYNC_CSID_LEN, ninfo);
-                       }
-               }
-               ninfo->state = NODE_CLVMD;
-       }
-
        num_nodes = member_list_entries;
 }
 
@@ -440,7 +420,6 @@ static int _cluster_do_node_callback(struct local_client 
*master_client,
 {
        struct dm_hash_node *hn;
        struct node_info *ninfo;
-       int somedown = 0;
 
        dm_hash_iterate(hn, node_hash)
        {
@@ -452,12 +431,10 @@ static int _cluster_do_node_callback(struct local_client 
*master_client,
                DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
                         ninfo->state);
 
-               if (ninfo->state != NODE_DOWN)
-                       callback(master_client, csid, ninfo->state == 
NODE_CLVMD);
-               if (ninfo->state != NODE_CLVMD)
-                       somedown = -1;
+               if (ninfo->state == NODE_CLVMD)
+                       callback(master_client, csid, 1);
        }
-       return somedown;
+       return 0;
 }
 
 /* Real locking */
-- 
1.8.4.5

++++++ device_is_usable_mem_leak.diff ++++++
commit ec49f07b0dc89720f4a74a1212e106990099d2d6
Author: Zdenek Kabelac <zkabe...@redhat.com>
Date:   Thu Dec 6 23:37:21 2012 +0100

    mirrors: fix leak in device_is_usable mirror check
    
    Function _ignore_blocked_mirror_devices was not release
    allocated strings images_health and log_health.
    
    In error paths it was also not releasing dm_task structure.
    
    Swaped return code of _ignore_blocked_mirror_devices and
    use 1 as success.
    
    In _parse_mirror_status use log_error if memory allocation
    fails and few more errors so they are no going unnoticed
    as debug messages.
    
    On error path always clear return values and free strings.
    
    For dev_create_file  use cache mem pool to avoid memleak.

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 40f719e..3f74c2d 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -158,6 +158,10 @@ static int _parse_mirror_status(char *mirror_status_str,
        char **args, **log_args;
        unsigned num_devs, log_argc;
 
+       *images_health = NULL;
+       *log_health = NULL;
+       *log_dev = 0;
+
        if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
            !(num_devs = (unsigned) atoi(p)))
                /* On errors, we must assume the mirror is to be avoided */
@@ -176,19 +180,31 @@ static int _parse_mirror_status(char *mirror_status_str,
                                     log_argc, 0, log_args) < log_argc)
                return_0;
 
-       *log_health = NULL;
-       *log_dev = 0;
        if (!strcmp(log_args[0], "disk")) {
-               if (!(*log_health = dm_strdup(log_args[2])))
-                       return_0;
-               if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2)
-                       return_0;
+               if (!(*log_health = dm_strdup(log_args[2]))) {
+                       log_error("Allocation of log string failed.");
+                       return 0;
+               }
+               if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2) {
+                       log_error("Parsing of log's major minor failed.");
+                       goto out;
+               }
                *log_dev = MKDEV((dev_t)major, minor);
        }
-       if (!(*images_health = dm_strdup(args[2 + num_devs])))
-               return_0;
+
+       if (!(*images_health = dm_strdup(args[2 + num_devs]))) {
+               log_error("Allocation of images string failed.");
+               goto out;
+       }
 
        return 1;
+
+out:
+       dm_free(*log_health);
+       *log_health = NULL;
+       *log_dev = 0;
+
+       return 0;
 }
 
 /*
@@ -227,11 +243,12 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
        uint64_t s,l;
        char *params, *target_type = NULL;
        void *next = NULL;
-       struct dm_task *dmt;
+       struct dm_task *dmt = NULL;
+       int r = 0;
 
        if (!_parse_mirror_status(mirror_status_str,
                                  &images_health, &log_dev, &log_health))
-               goto_out;
+               return_0;
 
        for (i = 0; images_health[i]; i++)
                if (images_health[i] != 'A') {
@@ -254,7 +271,7 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
                                        (int)MINOR(log_dev)) < 0)
                                goto_out;
 
-                       if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 1)))
+                       if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 0)))
                                goto_out;
 
                        tmp_dev->dev = log_dev;
@@ -263,8 +280,10 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
                }
        }
 
-       if (!check_for_blocking)
-               return 0;
+       if (!check_for_blocking) {
+               r = 1;
+               goto out;
+       }
 
        /*
         * We avoid another system call if we can, but if a device is
@@ -293,16 +312,19 @@ static int _ignore_blocked_mirror_devices(struct device 
*dev,
                            strstr(params, "handle_errors")) {
                                log_debug("%s: I/O blocked to mirror device",
                                          dev_name(dev));
-                               return 1;
+                               goto out;
                        }
                }
        } while (next);
-       dm_task_destroy(dmt);
-
-       return 0;
 
+       r = 1;
 out:
-       return 1;
+       if (dmt)
+               dm_task_destroy(dmt);
+       dm_free(log_health);
+       dm_free(images_health);
+
+       return r;
 }
 
 int device_is_usable(struct device *dev)
@@ -356,7 +378,7 @@ int device_is_usable(struct device *dev)
                                          &target_type, &params);
 
                if (target_type && !strcmp(target_type, "mirror") &&
-                   _ignore_blocked_mirror_devices(dev, start, length, params)) 
{
+                   !_ignore_blocked_mirror_devices(dev, start, length, 
params)) {
                        log_debug("%s: Mirror device %s not usable.",
                                  dev_name(dev), name);
                        goto out;
++++++ display-dm-name-for-lv-name.diff ++++++
---
 lib/config/defaults.h |    1 +
 lib/display/display.c |   14 ++++++++++----
 lib/display/display.h |    1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

Index: LVM2.2.02.98/lib/display/display.c
===================================================================
--- LVM2.2.02.98.orig/lib/display/display.c     2012-10-15 22:24:58.000000000 
+0800
+++ LVM2.2.02.98/lib/display/display.c  2014-03-20 12:24:55.761578040 +0800
@@ -535,10 +535,16 @@ int lvdisplay_full(struct cmd_context *c
                          lv->vg->cmd->dev_dir, lv->vg->name, lv->name);
        else if (lv_is_visible(lv)) {
                /* Thin pool does not have /dev/vg/name link */
-               if (!lv_is_thin_pool(lv))
-                       log_print("LV Path                %s%s/%s",
-                                 lv->vg->cmd->dev_dir,
-                                 lv->vg->name, lv->name);
+               if (!lv_is_thin_pool(lv)) {
+                       if (find_config_tree_bool(cmd, 
"global/display_dm_name_for_lv_name",
+                                                 
DEFAULT_DISPLAY_DM_NAME_FOR_LV_NAME)) {
+                               log_print("LV Path                
%smapper/%s-%s", lv->vg->cmd->dev_dir,
+                                         lv->vg->name, lv->name);
+                       } else {
+                               log_print("LV Path                %s%s/%s", 
lv->vg->cmd->dev_dir,
+                                         lv->vg->name, lv->name);
+                       }
+               }
                log_print("LV Name                %s", lv->name);
        } else
                log_print("Internal LV Name       %s", lv->name);
Index: LVM2.2.02.98/lib/display/display.h
===================================================================
--- LVM2.2.02.98.orig/lib/display/display.h     2014-03-20 12:24:30.403397837 
+0800
+++ LVM2.2.02.98/lib/display/display.h  2014-03-20 12:24:55.761578040 +0800
@@ -18,6 +18,7 @@
 
 #include "metadata-exported.h"
 #include "locking.h"
+#include "defaults.h"
 
 #include <stdint.h>
 
Index: LVM2.2.02.98/lib/config/defaults.h
===================================================================
--- LVM2.2.02.98.orig/lib/config/defaults.h     2014-03-20 12:24:30.403397837 
+0800
+++ LVM2.2.02.98/lib/config/defaults.h  2014-03-20 12:25:27.958815335 +0800
@@ -31,6 +31,7 @@
 #define DEFAULT_PROC_DIR "/proc"
 #define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1
 #define DEFAULT_SYSFS_SCAN 1
+#define DEFAULT_DISPLAY_DM_NAME_FOR_LV_NAME 0
 #define DEFAULT_MD_COMPONENT_DETECTION 1
 #define DEFAULT_MD_CHUNK_ALIGNMENT 1
 #define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
++++++ do_not_read_from_mirrors_have_failed_devices.diff ++++++
commit 9fd7ac7d035f0b2f8dcc3cb19935eb181816bd76
Author: Jonathan Brassow <jbras...@redhat.com>
Date:   Tue Oct 23 23:10:33 2012 -0500

    mirror:  Avoid reading from mirrors that have failed devices
    
    Addresses: rhbz855398 (Allow VGs to be built on cluster mirrors),
               and other issues.
    
    The LVM code attempts to avoid reading labels from devices that are
    suspended to try to avoid situations that may cause the commands to
    block indefinitely.  When scanning devices, 'ignore_suspended_devices'
    can be set so the code (lib/activate/dev_manager.c:device_is_usable())
    checks any DM devices it finds and avoids them if they are suspended.
    
    The mirror target has an additional mechanism that can cause I/O to
    be blocked.  If a device in a mirror fails, all I/O will be blocked
    by the kernel until a new table (a linear target or a mirror with
    replacement devices) is loaded.  The mirror indicates that this condition
    has happened by marking a 'D' for the faulty device in its status
    output.  This condition must also be checked by 'device_is_usable()' to
    avoid the possibility of blocking LVM commands indefinitely due to an
    attempt to read the blocked mirror for labels.
    
    Until now, mirrors were avoided if the 'ignore_suspended_devices'
    condition was set.  This check seemed to suggest, "if we are concerned
    about suspended devices, then let's ignore mirrors altogether just
    in case".  This is insufficient and doesn't solve any problems.  All
    devices that are suspended are already avoided if
    'ignore_suspended_devices' is set; and if a mirror is blocking because
    of an error condition, it will block the LVM command regardless of the
    setting of that variable.
    
    Rather than avoiding mirrors whenever 'ignore_suspended_devices' is
    set, this patch causes mirrors to be avoided whenever they are blocking
    due to an error.  (As mentioned above, the case where a DM device is
    suspended is already covered.)  This solves a number of issues that weren't
    handled before.  For example, pvcreate (or any command that does a
    pv_read or vg_read, which eventually call device_is_usable()) will be
    protected from blocked mirrors regardless of how
    'ignore_suspended_devices' is set.  Additionally, a mirror that is
    neither suspended nor blocking is /allowed/ to be read regardless
    of how 'ignore_suspended_devices' is set.  (The latter point being the
    source of the fix for rhbz855398.)

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 31c1c27..6cc57d0 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -135,6 +135,154 @@ static int _info_run(const char *name, const char *dlid, 
struct dm_info *info,
        return r;
 }
 
+/*
+ * _parse_mirror_status
+ * @mirror_status_string
+ * @image_health:  return for allocated copy of image health characters
+ * @log_health: NULL if corelog, otherwise alloc'ed log health char
+ *
+ * This function takes the mirror status string, breaks it up and returns
+ * its components.  For now, we only return the health characters.  This
+ * is an internal function.  If there are more things we want to return
+ * later, we can do that then.
+ *
+ * Returns: 1 on success, 0 on failure
+ */
+static int _parse_mirror_status(char *mirror_status_str,
+                               char **images_health, char **log_health)
+{
+       char *p = NULL;
+       char **args, **log_args;
+       unsigned num_devs, log_argc;
+
+       if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
+           !(num_devs = (unsigned) atoi(p)))
+               /* On errors, we must assume the mirror is to be avoided */
+               return_0;
+
+       p += strlen(p) + 1;
+       args = alloca((num_devs + 5) * sizeof(char *));
+
+       if ((unsigned)dm_split_words(p, num_devs + 4, 0, args) < num_devs + 4)
+               return_0;
+
+       log_argc = (unsigned) atoi(args[3 + num_devs]);
+       log_args = alloca(log_argc * sizeof(char *));
+
+       if ((unsigned)dm_split_words(args[3 + num_devs] + strlen(args[3 + 
num_devs]) + 1,
+                                    log_argc, 0, log_args) < log_argc)
+               return_0;
+
+       *log_health = NULL;
+       if (!strcmp(log_args[0], "disk") &&
+           !(*log_health = dm_strdup(log_args[2])))
+               return_0;
+
+       if (!(*images_health = dm_strdup(args[2 + num_devs])))
+               return_0;
+
+       return 1;
+}
+
+/*
+ * ignore_blocked_mirror_devices
+ * @dev
+ * @start
+ * @length
+ * @mirror_status_str
+ *
+ * When a DM 'mirror' target is created with 'block_on_error' or
+ * 'handle_errors', it will block I/O if there is a device failure
+ * until the mirror is reconfigured.  Thus, LVM should never attempt
+ * to read labels from a mirror that has a failed device.  (LVM
+ * commands are issued to repair mirrors; and if LVM is blocked
+ * attempting to read a mirror, a circular dependency would be created.)
+ *
+ * This function is a slimmed-down version of lib/mirror/mirrored.c:
+ * _mirrored_transient_status().  FIXME: It is unable to handle mirrors
+ * with mirrored logs because it does not have a way to get the status of
+ * the mirror that forms the log, which could be blocked.
+ *
+ * If a failed device is detected in the status string, then it must be
+ * determined if 'block_on_error' or 'handle_errors' was used when
+ * creating the mirror.  This info can only be determined from the mirror
+ * table.  The 'dev', 'start', 'length' trio allow us to correlate the
+ * 'mirror_status_str' with the correct device table in order to check
+ * for blocking.
+ *
+ * Returns: 1 if mirror should be ignored, 0 if safe to use
+ */
+static int _ignore_blocked_mirror_devices(struct device *dev,
+                                         uint64_t start, uint64_t length,
+                                         char *mirror_status_str)
+{
+       unsigned i, check_for_blocking = 0;
+       char *images_health, *log_health;
+
+       uint64_t s,l;
+       char *params, *target_type = NULL;
+       void *next = NULL;
+       struct dm_task *dmt;
+
+       if (!_parse_mirror_status(mirror_status_str,
+                                 &images_health, &log_health))
+               goto_out;
+
+       if (log_health && (log_health[0] != 'A')) {
+               log_debug("%s: Mirror log device marked as failed",
+                         dev_name(dev));
+               check_for_blocking = 1;
+       }
+
+       for (i = 0; images_health[i]; i++)
+               if (images_health[i] != 'A') {
+                       log_debug("%s: Mirror image %d marked as failed",
+                                 dev_name(dev), i);
+                       check_for_blocking = 1;
+               }
+
+       if (!check_for_blocking)
+               return 0;
+
+       /*
+        * We avoid another system call if we can, but if a device is
+        * dead, we have no choice but to look up the table too.
+        */
+       if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
+               goto_out;
+
+       if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
+               goto_out;
+
+       if (activation_checks() && !dm_task_enable_checks(dmt))
+               goto_out;
+
+       if (!dm_task_run(dmt))
+               goto_out;
+
+       do {
+               next = dm_get_next_target(dmt, next, &s, &l,
+                                         &target_type, &params);
+               if ((s == start) && (l == length)) {
+                       if (strcmp(target_type, "mirror"))
+                               goto_out;
+
+                       if (strstr(params, "block_on_error") ||
+                           strstr(params, "handle_errors")) {
+                               log_debug("%s: I/O blocked to mirror device",
+                                         dev_name(dev));
+                               return 1;
+                       }
+               }
+       } while (next);
+       dm_task_destroy(dmt);
+
+       return 0;
+
+out:
+       return 1;
+}
+
 int device_is_usable(struct device *dev)
 {
        struct dm_task *dmt;
@@ -180,15 +328,15 @@ int device_is_usable(struct device *dev)
                goto out;
        }
 
-       /* FIXME Also check for mirror block_on_error and mpath no paths */
-       /* For now, we exclude all mirrors */
-
+       /* FIXME Also check for mpath no paths */
        do {
                next = dm_get_next_target(dmt, next, &start, &length,
                                          &target_type, &params);
-               /* Skip if target type doesn't match */
-               if (target_type && !strcmp(target_type, "mirror") && 
ignore_suspended_devices()) {
-                       log_debug("%s: Mirror device %s not usable.", 
dev_name(dev), name);
+
+               if (target_type && !strcmp(target_type, "mirror") &&
+                   _ignore_blocked_mirror_devices(dev, start, length, params)) 
{
+                       log_debug("%s: Mirror device %s not usable.",
+                                 dev_name(dev), name);
                        goto out;
                }
 
++++++ lvconvert-cluster-mirrored-disk-failed.patch ++++++
Index: LVM2.2.02.98/daemons/clvmd/lvm-functions.c
===================================================================
--- LVM2.2.02.98.orig/daemons/clvmd/lvm-functions.c
+++ LVM2.2.02.98/daemons/clvmd/lvm-functions.c
@@ -418,11 +418,13 @@ static int do_resume_lv(char *resource,
        int oldmode, origin_only, exclusive, revert;
 
        /* Is it open ? */
+       /*
        oldmode = get_current_lock(resource);
        if (oldmode == -1 && (command & LCK_CLUSTER_VG)) {
                DEBUGLOG("do_resume_lv, lock not already held\n");
-               return 0;       /* We don't need to do anything */
+               return 0;
        }
+       */
        origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
        exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
        revert = (lock_flags & LCK_REVERT_MODE) ? 1 : 0;
@@ -442,11 +444,13 @@ static int do_suspend_lv(char *resource,
        unsigned exclusive;
 
        /* Is it open ? */
+       /*
        oldmode = get_current_lock(resource);
        if (oldmode == -1 && (command & LCK_CLUSTER_VG)) {
                DEBUGLOG("do_suspend_lv, lock not already held\n");
-               return 0; /* Not active, so it's OK */
+               return 0;
        }
+       */
 
        exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
 
++++++ mirrored_log_fixed_when_double_fault_occurs.diff ++++++
commit 54c73b7723713f43413584d59ca0bdd42c1d8241
Author: Jonathan Brassow <jbras...@redhat.com>
Date:   Wed Nov 14 14:58:47 2012 -0600

    mirror:  Mirrored log should be fixed before mirror when double fault occurs
    
    This patch is intended to fix bug 825323 - FS turns read-only during a 
double
    fault of a mirror leg and mirrored log's leg at the same time.  It only
    affects a 2-way mirror with a mirrored log.  3+-way mirrors and mirrors
    without a mirrored log are not affected.
    
    The problem resulted from the fact that the top level mirror was not
    using 'noflush' when suspending before its "down-convert".  When a
    mirror image fails, the bios are queue until a suspend is recieved.  If
    it is a 'noflush' suspend, the bios can be safely requeued in the DM
    core.  If 'noflush' is not used, the bios must be pushed through the
    target and if a device is failed for a mirror, that means issuing an
    error.  When an error is received by a file system, it results in it
    turning read-only (depending on the FS).
    
    Part of the problem was is due to the nature of the stacking involved in
    using a mirror as a mirror's log.  When an image in each fail, the top
    level mirror stalls because it is waiting for a log flush.  The other
    stalls waiting for corrective action.  When the repair command is issued,
    the entire stacked arrangement is collapsed to a linear LV.  The log
    flush then fails (somewhat uncleanly) and the top-level mirror is suspended
    without 'noflush' because it is a linear device.
    
    This patch allows the log to be repaired first, which in turn allows the
    top-level mirror's log flush to complete cleanly.  The top-level mirror
    is then secondarily reduced to a linear device - at which time this mirror
    is suspended properly with 'noflush'.

diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index f23fc4b..27d8181 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1341,10 +1341,6 @@ int mirror_remove_missing(struct cmd_context *cmd,
        if (!(failed_pvs = _failed_pv_list(lv->vg)))
                return_0;
 
-       /* No point in keeping a log if the result is not a mirror */
-       if (_failed_mirrors_count(lv) + 1 >= lv_mirror_count(lv))
-               log_count = 0;
-
         if (force && _failed_mirrors_count(lv) == lv_mirror_count(lv)) {
                log_error("No usable images left in %s.", lv->name);
                return lv_remove_with_dependencies(cmd, lv, DONT_PROMPT, 0);
@@ -1363,8 +1359,8 @@ int mirror_remove_missing(struct cmd_context *cmd,
                               _is_partial_lv, NULL, 0))
                return 0;
 
-       if (!_lv_update_log_type(cmd, NULL, lv, failed_pvs,
-                                log_count))
+       if (lv_is_mirrored(lv) &&
+           !_lv_update_log_type(cmd, NULL, lv, failed_pvs, log_count))
                return 0;
 
        if (!_reload_lv(cmd, lv->vg, lv))
++++++ pvmove_support_clustered_vg.diff ++++++
---
 lib/activate/activate.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

--- LVM2.2.02.98.orig/lib/activate/activate.c
+++ LVM2.2.02.98/lib/activate/activate.c
@@ -569,6 +569,26 @@ int module_present(struct cmd_context *c
        return ret;
 }
 
+/* 0 on not running, 1 on running */
+static int check_cmirrord()
+{
+       int fd;
+       int ret = 0;
+       struct flock lock;
+       if (( fd = open("/var/run/cmirrord.pid", O_WRONLY)) >= 0)
+       {
+               lock.l_type = F_WRLCK;
+               lock.l_start = 0;
+               lock.l_whence = SEEK_SET;
+               lock.l_len = 0;
+               if (fcntl(fd, F_SETLK, &lock) < 0) {
+                       ret = 1;
+               }
+               close(fd);
+       }
+       return ret;
+}
+
 int target_present(struct cmd_context *cmd, const char *target_name,
                   int use_modprobe)
 {
@@ -577,6 +597,16 @@ int target_present(struct cmd_context *c
        if (!activation())
                return 0;
 
+       if (!strncmp(target_name, "log-userspace", 13)) {
+               /*
+                  When the target_name is log-userspace, it also means
+                  we need cmirrord daemon running. It doesn't work alone.
+                */
+               if (!check_cmirrord())
+                       log_error("cmirrord is required, but not running now.");
+                       return_0;
+       }
+
 #ifdef MODPROBE_CMD
        if (use_modprobe) {
                if (target_version(target_name, &maj, &min, &patchlevel))
++++++ suppress_format1_size_warning.diff ++++++
---
 lib/format1/import-export.c   |    2 +-
 lib/format_text/import_vsn1.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- LVM2.2.02.98.orig/lib/format1/import-export.c
+++ LVM2.2.02.98/lib/format1/import-export.c
@@ -104,7 +104,7 @@ int import_pv(const struct format_type *
                        log_error("%s: Couldn't get size.", pv_dev_name(pv));
                        return 0;
                }
-               log_verbose("Fixing up missing format1 size (%s) "
+               log_debug("Fixing up missing format1 size (%s) "
                            "for PV %s", display_size(fmt->cmd, pv->size),
                            pv_dev_name(pv));
                if (vg) {
--- LVM2.2.02.98.orig/lib/format_text/import_vsn1.c
+++ LVM2.2.02.98/lib/format_text/import_vsn1.c
@@ -262,7 +262,7 @@ static int _read_pv(struct format_instan
                        log_error("%s: Couldn't get size.", pv_dev_name(pv));
                        return 0;
                }
-               log_verbose("Fixing up missing size (%s) "
+               log_debug("Fixing up missing size (%s) "
                            "for PV %s", display_size(fid->fmt->cmd, pv->size),
                            pv_dev_name(pv));
                size = pv->pe_count * (uint64_t) vg->extent_size + pv->pe_start;
-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to