Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=81f10c1d1e844dd3ad991…
Commit: 81f10c1d1e844dd3ad9918a31a0d7c00fed36c94
Parent: f188c9e40319d00a3d5bd59f1d01016325935da6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Oct 31 08:54:33 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Oct 31 08:54:33 2022 -0500
vgchange systemid: use tag or select
The command can do this but the command defs
were missing the annotation to allow it.
---
tools/command-lines.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index ec61d3b7d..4bbafd05d 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1766,7 +1766,8 @@ IO: --ignoreskippedcluster
ID: vgchange_refresh
DESC: Reactivate LVs using the latest metadata.
-vgchange --systemid String VG
+vgchange --systemid String VG|Tag|Select
+OO: --select String
ID: vgchange_systemid
DESC: Change the system ID of a VG.
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=94dde5769984c5ede211d…
Commit: 94dde5769984c5ede211d122cc7392a26f8dbef4
Parent: 736547e7bb306236e1ea6f4d8d9185ee0ab69638
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 20 10:46:51 2022 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Thu Oct 20 15:10:35 2022 -0500
lvmdbusd: Handle PV signature copy
If something manually copies a PV signature to a block device we will
miss it. Handle this case too.
---
daemons/lvmdbusd/udevwatch.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/daemons/lvmdbusd/udevwatch.py b/daemons/lvmdbusd/udevwatch.py
index 237ff17e8..7ee7c9d1c 100644
--- a/daemons/lvmdbusd/udevwatch.py
+++ b/daemons/lvmdbusd/udevwatch.py
@@ -59,9 +59,13 @@ def filter_event(action, device):
if 'ID_FS_TYPE' in device:
fs_type_new = device['ID_FS_TYPE']
if 'LVM' in fs_type_new:
- # Let's skip udev events for LVM devices as we should be handling them
- # with the dbus notifications.
- pass
+ # If we get a lvm related udev event for a block device
+ # we don't know about, it's either a pvcreate which we
+ # would handle with the dbus notification or something
+ # copied a pv signature onto a block device, this is
+ # required to catch the latter.
+ if not cfg.om.get_object_by_lvm_id(device['DEVNAME']):
+ refresh = True
elif fs_type_new == '':
# Check to see if the device was one we knew about
if 'DEVNAME' in device:
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=736547e7bb306236e1ea6…
Commit: 736547e7bb306236e1ea6f4d8d9185ee0ab69638
Parent: 8a1c73ddbe35be24cde02f77bac7e3b8b6d92242
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 20 12:48:40 2022 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Thu Oct 20 15:10:35 2022 -0500
lvmdbustest: Add test for copy signature
Add test to ensure we detect when a PV signature is copied to a block
device.
---
test/dbus/lvmdbustest.py | 71 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 60 insertions(+), 11 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index f158da571..9582fe674 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -8,7 +8,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
+import os
import signal
# noinspection PyUnresolvedReferences
import subprocess
@@ -2394,6 +2394,30 @@ class TestDbusService(unittest.TestCase):
return False
return True
+ def _block_present_absent(self, block_device, present=False):
+ start = time.time()
+ keep_looping = True
+ while keep_looping and time.time() < start + 3:
+ if present:
+ if (self._lookup(block_device) != "/"):
+ keep_looping = False
+ else:
+ if (self._lookup(block_device) == "/"):
+ keep_looping = False
+
+ if keep_looping:
+ print("Daemon failed to update")
+ else:
+ print("Note: Time for udev update = %f" % (time.time() - start))
+ if present:
+ rc = self._lookup(block_device)
+ self.assertNotEqual(rc, '/')
+ return True
+ else:
+ rc = self._lookup(block_device)
+ self.assertEqual(rc, '/')
+ return True
+
def test_wipefs(self):
# Ensure we update the status of the daemon if an external process clears a PV
pv = self.objs[PV_INT][0]
@@ -2404,21 +2428,46 @@ class TestDbusService(unittest.TestCase):
if wipe_result:
# Need to wait a bit before the daemon will reflect the change
- start = time.time()
- found = True
- while found and time.time() < start + 10:
- if (self._lookup(pv_device_path) == "/"):
- found = False
-
- print("Note: Time for udev update = %f" % (time.time() - start))
- # Make sure that the service no longer has it
- rc = self._lookup(pv_device_path)
- self.assertEqual(rc, '/')
+ self._block_present_absent(pv_device_path, False)
# Put it back
pv_object_path = self._pv_create(pv_device_path)
self.assertNotEqual(pv_object_path, '/')
+ @staticmethod
+ def _write_signature(device, data=None):
+ fd = os.open(device, os.O_RDWR|os.O_EXCL|os.O_NONBLOCK)
+ existing = os.read(fd, 1024)
+ os.lseek(fd, 0, os.SEEK_SET)
+
+ if data is None:
+ data_copy = bytearray(existing)
+ # Clear lvm signature
+ data_copy[536:536+9] = bytearray(8)
+ os.write(fd, data_copy)
+ else:
+ os.write(fd, data)
+ os.sync()
+ os.close(fd)
+ return existing
+
+ def test_copy_signature(self):
+ # Ensure we update the state of the daemon if an external process copies
+ # a pv signature onto a block device
+ pv = self.objs[PV_INT][0]
+ pv_device_path = pv.Pv.Name
+
+ try:
+ existing = TestDbusService._write_signature(pv_device_path, None)
+ if self._block_present_absent(pv_device_path, False):
+ TestDbusService._write_signature(pv_device_path, existing)
+ self._block_present_absent(pv_device_path, True)
+ finally:
+ # Ensure we put the PV back for sure.
+ rc = self._lookup(pv_device_path)
+ if rc == "/":
+ self._pv_create(pv_device_path)
+
class AggregateResults(object):
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8a1c73ddbe35be24cde02…
Commit: 8a1c73ddbe35be24cde02f77bac7e3b8b6d92242
Parent: 5a6ae2d4d8e65452bbdddd9a3cbd317e142fb9f1
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Oct 18 12:30:09 2022 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Thu Oct 20 15:10:35 2022 -0500
lvmdbusd: Always leverage udev
Previously we utilized udev until we got a dbus notification from lvm
command line tools. This however misses the case where something outside
of lvm clears the signatures on a block device and we fail to refresh the
state of the daemon. Change the behavior so we always monitor udev events,
but ignore those udev events that pertain to lvm members.
Note: --udev command line option no longer does anything and simply
outputs a message that it's no longer used.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967171
---
daemons/lvmdbusd/main.py | 3 ++-
daemons/lvmdbusd/manager.py | 6 ------
daemons/lvmdbusd/udevwatch.py | 20 +++++++++++++-------
3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py
index 662d7569f..e869bcec3 100644
--- a/daemons/lvmdbusd/main.py
+++ b/daemons/lvmdbusd/main.py
@@ -125,7 +125,8 @@ def process_args():
# Add udev watching
if args.use_udev:
# Make sure this msg ends up in the journal, so we know
- log_msg('Utilizing udev to trigger updates')
+ log_msg('The --udev option is no longer supported,'
+ 'the daemon always uses a combination of dbus notify from lvm tools and udev')
return args
diff --git a/daemons/lvmdbusd/manager.py b/daemons/lvmdbusd/manager.py
index 9c41f0fc3..c6fb11d76 100644
--- a/daemons/lvmdbusd/manager.py
+++ b/daemons/lvmdbusd/manager.py
@@ -203,12 +203,6 @@ class Manager(AutomatedProperties):
in_signature='s', out_signature='i')
def ExternalEvent(self, command):
utils.log_debug("ExternalEvent %s" % command)
- # If a user didn't explicitly specify udev, we will turn it off now.
- if not cfg.args.use_udev:
- if udevwatch.remove():
- utils.log_msg("ExternalEvent received, disabling "
- "udev monitoring")
- # We are dependent on external events now to stay current!
r = RequestEntry(
-1, Manager._external_event, (command,), None, None, False)
cfg.worker_q.put(r)
diff --git a/daemons/lvmdbusd/udevwatch.py b/daemons/lvmdbusd/udevwatch.py
index f9b3e4ad1..237ff17e8 100644
--- a/daemons/lvmdbusd/udevwatch.py
+++ b/daemons/lvmdbusd/udevwatch.py
@@ -52,20 +52,26 @@ def filter_event(action, device):
# when appropriate.
refresh = False
+ # Ignore everything but change
+ if action != 'change':
+ return
+
if 'ID_FS_TYPE' in device:
fs_type_new = device['ID_FS_TYPE']
-
if 'LVM' in fs_type_new:
- refresh = True
+ # Let's skip udev events for LVM devices as we should be handling them
+ # with the dbus notifications.
+ pass
elif fs_type_new == '':
# Check to see if the device was one we knew about
if 'DEVNAME' in device:
- found = cfg.om.get_object_by_lvm_id(device['DEVNAME'])
- if found:
+ if cfg.om.get_object_by_lvm_id(device['DEVNAME']):
refresh = True
-
- if 'DM_LV_NAME' in device:
- refresh = True
+ else:
+ # This handles the wipefs -a path
+ if not refresh and 'DEVNAME' in device:
+ if cfg.om.get_object_by_lvm_id(device['DEVNAME']):
+ refresh = True
if refresh:
udev_add()
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5a6ae2d4d8e65452bbddd…
Commit: 5a6ae2d4d8e65452bbdddd9a3cbd317e142fb9f1
Parent: 0f56c1ad1262857961aff7b5a0ae6593a3de8db3
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Oct 18 12:26:14 2022 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Thu Oct 20 15:10:35 2022 -0500
lvmdbustest: Add test for wipefs
Ensure that if an external program or user calles wipefs on a PV that we
correctly update the state of the daemon.
---
test/dbus/lvmdbustest.py | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index 41ee2fd1b..f158da571 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -2385,6 +2385,40 @@ class TestDbusService(unittest.TestCase):
finally:
set_exec_mode(g_lvm_shell)
+ @staticmethod
+ def _wipe_it(block_device):
+ cmd = ["/usr/sbin/wipefs", '-a', block_device]
+ config = Popen(cmd, stdout=PIPE, stderr=PIPE, close_fds=True, env=os.environ)
+ config.communicate()
+ if config.returncode != 0:
+ return False
+ return True
+
+ def test_wipefs(self):
+ # Ensure we update the status of the daemon if an external process clears a PV
+ pv = self.objs[PV_INT][0]
+ pv_device_path = pv.Pv.Name
+
+ wipe_result = TestDbusService._wipe_it(pv_device_path)
+ self.assertTrue(wipe_result)
+
+ if wipe_result:
+ # Need to wait a bit before the daemon will reflect the change
+ start = time.time()
+ found = True
+ while found and time.time() < start + 10:
+ if (self._lookup(pv_device_path) == "/"):
+ found = False
+
+ print("Note: Time for udev update = %f" % (time.time() - start))
+ # Make sure that the service no longer has it
+ rc = self._lookup(pv_device_path)
+ self.assertEqual(rc, '/')
+
+ # Put it back
+ pv_object_path = self._pv_create(pv_device_path)
+ self.assertNotEqual(pv_object_path, '/')
+
class AggregateResults(object):
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0f56c1ad1262857961aff…
Commit: 0f56c1ad1262857961aff7b5a0ae6593a3de8db3
Parent: 04097d9f620b5e22ae8fe2884110249116f3dab5
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 19 12:46:45 2022 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 19 14:22:12 2022 -0500
lvmnotify.c: Check to see if dbus daemon is running
The lvm dbus daemon will auto activate on dbus API calls. To
prevent the dbus daemon starting when lvm command line tools are
being used we will check to see if the daemon is running first.
If the daemon is not running, we will not notify the daemon.
For this check to work it requires the changes done previously
with commit: 3fdf4493481ff8baae2ac5416dce6d05b69e6b28
Reviewed-by: David Teigland <teigland(a)redhat.com>
---
lib/notify/lvmnotify.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/lib/notify/lvmnotify.c b/lib/notify/lvmnotify.c
index e24b0acb1..7ac74d755 100644
--- a/lib/notify/lvmnotify.c
+++ b/lib/notify/lvmnotify.c
@@ -15,17 +15,79 @@
#define LVM_DBUS_DESTINATION "com.redhat.lvmdbus1"
#define LVM_DBUS_PATH "/com/redhat/lvmdbus1/Manager"
#define LVM_DBUS_INTERFACE "com.redhat.lvmdbus1.Manager"
+#define LVM_DBUS_LOCK_FILE "/var/lock/lvm/lvmdbusd"
+#define LVM_DBUS_LOCK_FILE_ENV_KEY "LVM_DBUSD_LOCKFILE"
#define SD_BUS_SYSTEMD_NO_SUCH_UNIT_ERROR "org.freedesktop.systemd1.NoSuchUnit"
#define SD_BUS_DBUS_SERVICE_UNKNOWN_ERROR "org.freedesktop.DBus.Error.ServiceUnknown"
#ifdef NOTIFYDBUS_SUPPORT
#include <systemd/sd-bus.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
int lvmnotify_is_supported(void)
{
return 1;
}
+static int lvmdbusd_running(void)
+{
+ int fd = 0;
+ int rc = 0;
+ int errno_cpy = 0;
+ int running = 0;
+ const char *lockfile = NULL;
+
+ /*
+ * lvm dbusd uses a lock file with a lock on it, thus to determine if the daemon is running
+ * requires that you attempt to lock the file as well. Thus the existence of the file does
+ * not mean it's running, but the absence of the file does indicate it's not running.
+ *
+ * See lvmdbusd for more details.
+ */
+
+ lockfile = getenv(LVM_DBUS_LOCK_FILE_ENV_KEY);
+ if (!lockfile) {
+ lockfile = LVM_DBUS_LOCK_FILE;
+ }
+
+ errno = 0;
+ fd = open(lockfile, O_RDWR);
+ if (-1 == fd) {
+ errno_cpy = errno;
+ if (errno_cpy == ENOENT) {
+ return 0;
+ } else {
+ /* Safest option is to return running when we encounter unexpected errors */
+ log_debug_dbus("Unexpected errno: %d on lockfile open, returning running", errno_cpy);
+ return 1;
+ }
+ }
+
+ /* Need to ensure we close lock FD now */
+ errno = 0;
+ rc = lockf(fd, F_TLOCK|F_TEST, 0);
+ if (-1 != rc) {
+ /* Not locked, thus not running */
+ running = 0;
+ } else {
+ errno_cpy = errno;
+ if (errno_cpy == EACCES || errno_cpy == EAGAIN) {
+ /* Locked, so daemon is running */
+ running = 1;
+ } else {
+ log_debug_dbus("Unexpected errno: %d on lockf, returning running", errno_cpy);
+ running = 1 ;
+ }
+ }
+
+ close(fd);
+ return running;
+}
+
+
void lvmnotify_send(struct cmd_context *cmd)
{
static const char _dbus_notification_failed_msg[] = "D-Bus notification failed";
@@ -43,6 +105,12 @@ void lvmnotify_send(struct cmd_context *cmd)
cmd->lv_notify = 0;
cmd->pv_notify = 0;
+ /* If lvmdbusd isn't running, don't notify as you will start it as it will auto activate */
+ if (!lvmdbusd_running()) {
+ log_debug_dbus("dbus damon not running, not notifying");
+ return;
+ }
+
cmd_name = get_cmd_name();
ret = sd_bus_open_system(&bus);
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4f4554164b6fec7a92c21…
Commit: 4f4554164b6fec7a92c21d1230b0abb6316db1b5
Parent: 908555459f0abbcda687882439589209528e1dc0
Author: corubba <corubba(a)gmx.de>
AuthorDate: Wed Oct 12 09:19:01 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Oct 12 09:19:01 2022 -0500
lvmlockd: Fix sanlock lvmlock lv size calculation
The number of extents for the sanlock lvmlock lv is calculated using
integer division, which rounds towards zero. With a physical extent size
of 129M, instead of the requested 256M the lv is only 129M (1 extent).
With any physical extent size greater than 256M the lv creation fails
because the number of extents is zero.
This is fixed by replacing the integer division with a division macro
that rounds up and thus guarantees that the size of the lv will always
be equal or greater than the requested size. Using the examples above, a
pes of 129M will result in a 258M lv (2 extents), pes of 300M in a 300M
lv (1 extent).
The re-calculation of the lv size in bytes and megabytes is only so the
debug output shows the correct values. The size in mb there is still
not byte-perfect-accurate, but good enough for a human-readable estimate;
and the exact size in bytes and extents is right next to it.
Signed-off-by: corubba <corubba(a)gmx.de>
---
lib/locking/lvmlockd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 2ef0900d4..7f8150365 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -513,9 +513,11 @@ static int _create_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
lv_size_bytes = num_mb * ONE_MB_IN_BYTES; /* size of sanlock LV in bytes */
extent_bytes = vg->extent_size * SECTOR_SIZE; /* size of one extent in bytes */
- total_extents = lv_size_bytes / extent_bytes; /* number of extents in sanlock LV */
+ total_extents = dm_div_up(lv_size_bytes, extent_bytes); /* number of extents in sanlock LV */
lp.extents = total_extents;
+ lv_size_bytes = total_extents * extent_bytes;
+ num_mb = lv_size_bytes / ONE_MB_IN_BYTES;
log_debug("Creating lvmlock LV for sanlock with size %um %ub %u extents", num_mb, lv_size_bytes, lp.extents);
dm_list_init(&lp.tags);