Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4b4d19e3aa1da061…
Commit: 4b4d19e3aa1da061fed35edb979e1ca2a29fb7ed
Parent: cd468b6218fc5c46e98ee0061010724c298c312c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Nov 3 12:10:45 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Nov 3 12:43:09 2016 +0100
dmeventd: separate dm and dmeventd logging
Ensure different logging function for dmeventd.c logging
and dm and lvm library.
We can recognize we want to show every log_info() and
log_notice() message from dmeventd.c code while not
exposing those from libdm/libdevmapper-event
Also switch to use log with errno - it's not changing
anything and doesn't bring any more features yet to dmeventd
logging but we just properly pass dm_errno_or_class properly
through the whole code stack for possible future use
(i.e. support of class logging for dmeventd).
---
WHATS_NEW_DM | 1 +
daemons/dmeventd/dmeventd.c | 23 +++++++++++++++++++----
daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c | 2 +-
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 73a5171..d2d44ac 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.136 -
======================================
+ Make log messages from dm and lvm library differnt from dmeventd.
Notice and Info messages are again logged from dmeventd and its plugins.
Dmeventd now also respects DM_ABORT_ON_INTERNAL_ERRORS as libdm based tool.
Report as non default dm logging also when logging with errno was changed.
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 6024e56..58922ac 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -99,13 +99,28 @@ static time_t _idle_since = 0;
static char **_initial_registrations = 0;
/* FIXME Make configurable at runtime */
-__attribute__((format(printf, 4, 5)))
+
+/* All libdm messages */
+__attribute__((format(printf, 5, 6)))
+static void _libdm_log(int level, const char *file, int line,
+ int dm_errno_or_class, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ dm_event_log("#dm", level, file, line, dm_errno_or_class, format, ap);
+ va_end(ap);
+}
+
+/* All dmeventd messages */
+#undef LOG_MESG
+#define LOG_MESG(l, f, ln, e, x...) _dmeventd_log(l, f, ln, e, ## x)
+__attribute__((format(printf, 5, 6)))
static void _dmeventd_log(int level, const char *file, int line,
- const char *format, ...)
+ int dm_errno_or_class, const char *format, ...)
{
va_list ap;
va_start(ap, format);
- dm_event_log("dm", level, file, line, 0, format, ap);
+ dm_event_log("dmeventd", level, file, line, dm_errno_or_class, format, ap);
va_end(ap);
}
@@ -2191,7 +2206,7 @@ int main(int argc, char *argv[])
openlog("dmeventd", LOG_PID, LOG_DAEMON);
dm_event_log_set(_debug_level, _use_syslog);
- dm_log_init(_dmeventd_log);
+ dm_log_with_errno_init(_libdm_log);
(void) dm_prepare_selinux_context(DMEVENTD_PIDFILE, S_IFREG);
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
diff --git a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
index f36feb4..0cca98f 100644
--- a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
+++ b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
@@ -32,7 +32,7 @@ static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
-DM_EVENT_LOG_FN("lvm")
+DM_EVENT_LOG_FN("#lvm")
static void _lvm2_print_log(int level, const char *file, int line,
int dm_errno_or_class, const char *msg)
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=33dd1f7747ecb4e1…
Commit: 33dd1f7747ecb4e16fb807af6673592d1b0d4c3d
Parent: e50d434a353efac7d4947c7deeaf7cfd773ea6e1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Nov 2 14:40:12 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Nov 3 12:43:09 2016 +0100
dmeventd: abort on internal error
Provide same support for DM_ABORT_ON_INTERNAL_ERRORS we do have
with default libdm logging as dmeventd is libdm based tool.
---
WHATS_NEW_DM | 1 +
daemons/dmeventd/libdevmapper-event.c | 10 ++++++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 8cf0e05..fa77d10 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.136 -
======================================
+ Dmeventd now also respects DM_ABORT_ON_INTERNAL_ERRORS as libdm based tool.
Report as non default dm logging also when logging with errno was changed.
Use log_level() macro to consistently decode message log level in dmeventd.
Still produce output when dmsetup dependency tree building finds dev missing.
diff --git a/daemons/dmeventd/libdevmapper-event.c b/daemons/dmeventd/libdevmapper-event.c
index 8c21537..12173fd 100644
--- a/daemons/dmeventd/libdevmapper-event.c
+++ b/daemons/dmeventd/libdevmapper-event.c
@@ -865,6 +865,7 @@ void dm_event_log(const char *subsys, int level, const char *file,
int line, int dm_errno_or_class,
const char *format, va_list ap)
{
+ static int _abort_on_internal_errors = -1;
static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER;
static time_t start = 0;
const char *indent = "";
@@ -926,6 +927,15 @@ void dm_event_log(const char *subsys, int level, const char *file,
}
pthread_mutex_unlock(&_log_mutex);
+
+ if (_abort_on_internal_errors < 0)
+ /* Set when env DM_ABORT_ON_INTERNAL_ERRORS is not "0" */
+ _abort_on_internal_errors =
+ strcmp(getenv("DM_ABORT_ON_INTERNAL_ERRORS") ? : "0", "0");
+
+ if (_abort_on_internal_errors &&
+ !strncmp(format, INTERNAL_ERROR, sizeof(INTERNAL_ERROR) - 1))
+ abort();
}
#if 0 /* left out for now */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=96118a2508e1cd3a…
Commit: 96118a2508e1cd3aaf5ba7a0129ff8ecc7ac4af2
Parent: 95abadd13c468b56612c1966d28daddfdeee6e2e
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Nov 2 14:14:56 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Nov 2 16:39:13 2016 -0500
lvmdbusd: Stop using threads for job wait
Instead of creating a thread to handle the case where a client
is calling job.Wait, we will utilize a timer. This significantly
reduces the number of threads that get created and destroyed while
the service is running.
---
daemons/lvmdbusd/background.py | 29 +-------------
daemons/lvmdbusd/job.py | 83 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 81 insertions(+), 31 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index e8b42fe..0220b97 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -12,8 +12,7 @@ import subprocess
from . import cfg
from .cmdhandler import options_to_cli_args
import dbus
-from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug, \
- mt_async_result
+from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug
import traceback
import os
@@ -184,29 +183,3 @@ def add(command, reporting_job):
with _rlock:
_thread_list.append(t)
-
-def wait_thread(job, timeout, cb, cbe):
- # We need to put the wait on it's own thread, so that we don't block the
- # entire dbus queue processing thread
- try:
- mt_async_result(cb, job.state.Wait(timeout))
- except Exception as e:
- mt_async_result(cbe, "Wait exception: %s" % str(e))
- return 0
-
-
-def add_wait(job, timeout, cb, cbe):
-
- if timeout == 0:
- # Users are basically polling, do not create thread
- mt_async_result(cb, job.Complete)
- else:
- t = threading.Thread(
- target=wait_thread,
- name="thread job.Wait: %s" % job.dbus_object_path(),
- args=(job, timeout, cb, cbe)
- )
-
- t.start()
- with _rlock:
- _thread_list.append(t)
diff --git a/daemons/lvmdbusd/job.py b/daemons/lvmdbusd/job.py
index 1158370..81048a6 100644
--- a/daemons/lvmdbusd/job.py
+++ b/daemons/lvmdbusd/job.py
@@ -8,12 +8,54 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from .automatedproperties import AutomatedProperties
-from .utils import job_obj_path_generate
+from .utils import job_obj_path_generate, mt_async_result, log_debug
from . import cfg
from .cfg import JOB_INTERFACE
import dbus
import threading
-from . import background
+from gi.repository import GLib
+
+
+# Class that handles a client waiting for something to be complete. We either
+# get a timeout or the operation is done.
+class WaitingClient(object):
+
+ # A timeout occurred
+ @staticmethod
+ def _timeout(wc):
+ with wc.rlock:
+ if wc.in_use:
+ wc.in_use = False
+ # Remove ourselves from waiting client
+ wc.job_state.remove_waiting_client(wc)
+ wc.timer_id = -1
+ mt_async_result(wc.cb, wc.job_state.Complete)
+ wc.job_state = None
+
+ def __init__(self, job_state, tmo, cb, cbe):
+ self.rlock = threading.RLock()
+ self.job_state = job_state
+ self.cb = cb
+ self.cbe = cbe
+ self.in_use = True # Indicates if object is in play
+ self.timer_id = -1
+ if tmo > 0:
+ self.timer_id = GLib.timeout_add_seconds(
+ tmo, WaitingClient._timeout, self)
+
+ # The job finished before the timer popped and we are being notified that
+ # it's done
+ def notify(self):
+ with self.rlock:
+ if self.in_use:
+ self.in_use = False
+ # Clear timer
+ if self.timer_id != -1:
+ GLib.source_remove(self.timer_id)
+ self.timer_id = -1
+
+ mt_async_result(self.cb, self.job_state.Complete)
+ self.job_state = None
# noinspection PyPep8Naming
@@ -27,6 +69,7 @@ class JobState(object):
self._cond = threading.Condition(self.rlock)
self._ec = 0
self._stderr = ''
+ self._waiting_clients = []
# This is an lvm command that is just taking too long and doesn't
# support background operation
@@ -58,6 +101,7 @@ class JobState(object):
self._complete = value
self._percent = 100
self._cond.notify_all()
+ self.notify_waiting_clients()
@property
def GetError(self):
@@ -101,6 +145,35 @@ class JobState(object):
return self._request.result()
return '/'
+ def add_waiting_client(self, client):
+ with self.rlock:
+ # Avoid race condition where it goes complete before we get added
+ # to the list of waiting clients
+ if self.Complete:
+ client.notify()
+ else:
+ self._waiting_clients.append(client)
+
+ def remove_waiting_client(self, client):
+ # If a waiting client timer pops before the job is done we will allow
+ # the client to remove themselves from the list. As we have a lock
+ # here and a lock in the waiting client too, and they can be obtained
+ # in different orders, a dead lock can occur.
+ # As this remove is really optional, we will try to acquire the lock
+ # and remove. If we are unsuccessful it's not fatal, we just delay
+ # the time when the objects can be garbage collected by python
+ if self.rlock.acquire(False):
+ try:
+ self._waiting_clients.remove(client)
+ finally:
+ self.rlock.release()
+
+ def notify_waiting_clients(self):
+ with self.rlock:
+ for c in self._waiting_clients:
+ c.notify()
+
+ self._waiting_clients = []
# noinspection PyPep8Naming
class Job(AutomatedProperties):
@@ -155,7 +228,11 @@ class Job(AutomatedProperties):
out_signature='b',
async_callbacks=('cb', 'cbe'))
def Wait(self, timeout, cb, cbe):
- background.add_wait(self, timeout, cb, cbe)
+ if timeout == 0 or self.state.Complete:
+ cb(dbus.Boolean(self.state.Complete))
+ else:
+ self.state.add_waiting_client(
+ WaitingClient(self.state, timeout, cb, cbe))
@property
def Result(self):
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=68e7d3496517a70e…
Commit: 68e7d3496517a70e50edaceff906ad1da23821a6
Parent: 4585785613320f2400b5645a47375308f1ee5289
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Nov 2 16:29:52 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Nov 2 16:29:52 2016 -0500
pvscan: fix autoactivation of exported VG
pvscan --cache -aay was activating LVs in exported VGs
when it should not.
It appears that this was a regression from commit 9b640c36841
"pvscan: use process_each_vg for autoactivate".
---
tools/pvscan.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index f5367e4..e2b0a83 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -194,6 +194,9 @@ static int _pvscan_autoactivate_single(struct cmd_context *cmd, const char *vg_n
if (vg_is_clustered(vg))
return ECMD_PROCESSED;
+ if (vg_is_exported(vg))
+ return ECMD_PROCESSED;
+
if (is_lockd_type(vg->lock_type))
return ECMD_PROCESSED;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4585785613320f24…
Commit: 4585785613320f2400b5645a47375308f1ee5289
Parent: a9651adc84210d88828f9c3c82a0f382a899a650
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Nov 1 16:41:30 2016 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Nov 1 16:52:51 2016 +0100
blkdeactivate: deactivate dev stack if dev on top already unmounted
If blkdeactivate finds out that the device on top of device stack
is already unmounted, it still proceeds with device stack deactivation
underneath now.
This situation can happen if blkdeactivate is started and the mount
point is unmounted in parallel by chance (so when blkdeactivate
gets the the actual umount call, the device is not mounted anymore).
Before, the blkdeactivate added such device to skip list which caused
all the stack underneath to be skipped too on deactivation. Now, we
proceed just as if blkdeactivate did the umount itself.
For example, in the example below, the vg-lvol0 is mounted on /mnt/test
when blkdeactivate is called, but it gets unmounted in parallel later
on when blkdeactivate gets to the actual umount call.
Before this patch (vg-lvol0 underneath not deactivated):
$ blkdeactivate -u
Deactivating block devices:
[UMOUNT]: unmounting vg-lvol0 (dm-2) mounted on /mnt/test... skipping
With this patch applied (vg-lvol0 underneath still deactivated):
$ blkdeactivate -u
Deactivating block devices:
[UMOUNT]: unmounting vg-lvol0 (dm-2) mounted on /mnt/test... already unmounted
[LVM]: deactivating Logical Volume vg/lvol0... done
---
WHATS_NEW | 1 +
scripts/blkdeactivate.sh.in | 5 ++++-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 49af38a..311f3b6 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.167 -
======================================
+ Fix blkdeactivate to deactivate dev stack if dev on top already unmounted.
Prevent non-synced raid1 repair unless --force
Prevent raid4 creation/conversion on non-supporting kernels
Add direct striped -> raid4 conversion
diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in
index 50ea2d1..443af9c 100644
--- a/scripts/blkdeactivate.sh.in
+++ b/scripts/blkdeactivate.sh.in
@@ -34,6 +34,7 @@ TOOL=blkdeactivate
DEV_DIR='/dev'
SYS_BLK_DIR='/sys/block'
+MOUNTPOINT="/bin/mountpoint"
UMOUNT="/bin/umount"
DMSETUP="@sbindir@/dmsetup"
LVM="@sbindir@/lvm"
@@ -157,9 +158,11 @@ device_umount_one() {
echo -n " [UMOUNT]: unmounting $name ($kname) mounted on $mnt... "
if eval $UMOUNT $UMOUNT_OPTS "$(printf "%s" "$mnt")" $OUT $ERR; then
echo "done"
- else
+ elif $MOUNTPOINT -q "$mnt"; then
echo "skipping"
add_device_to_skip_list
+ else
+ echo "already unmounted"
fi
else
echo " [SKIP]: unmount of $name ($kname) mounted on $mnt"