From 1aa7292716ea6bf5ec7caf71d204703c6f5b6a6e Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Tue, 21 Apr 2015 11:16:35 -0500
Subject: [PATCH 28/51] Reduce the number of udev settle calls when handling
 uevents.

There are several settle calls left intact because I'm not sure how
to handle those situations otherwise. These generally involve running
a command and having it create or remove device nodes for devices
other than the one we're operating on, eg: dmraid activate, iscsi
discovery. We'll have to work through those with some experimentation.
---
 blivet/deviceaction.py      | 31 +++++++++++++++++--------------
 blivet/devices/lvm.py       |  4 +++-
 blivet/devices/md.py        |  8 +++++++-
 blivet/devices/partition.py |  6 ++++--
 blivet/devices/storage.py   | 14 +++++++++-----
 blivet/formats/disklabel.py |  6 ++++--
 blivet/formats/fs.py        |  3 ++-
 blivet/udev.py              |  6 ++++--
 8 files changed, 50 insertions(+), 28 deletions(-)

diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
index a2c2cda..0845df0 100644
--- a/blivet/deviceaction.py
+++ b/blivet/deviceaction.py
@@ -27,6 +27,7 @@ from . import udev
 from .util import get_current_entropy
 from .devices import StorageDevice
 from .devices import PartitionDevice
+from .flags import flags
 from .formats import getFormat, luks
 from parted import partitionFlag, PARTITION_LBA
 from .i18n import _, N_
@@ -570,19 +571,20 @@ class ActionCreateFormat(DeviceAction):
         self.device.format.create(device=self.device.path,
                                   options=self.device.formatArgs)
 
-        # Get the UUID now that the format is created
-        udev.settle()
-        self.device.updateSysfsPath()
-        info = udev.get_device(self.device.sysfsPath)
-        # only do this if the format has a device known to udev
-        # (the format might not have a normal device at all)
-        if info:
-            if self.device.format.type != "btrfs":
-                self.device.format.uuid = udev.device_get_uuid(info)
-            self.device.deviceLinks = udev.device_get_symlinks(info)
-        elif self.device.format.type != "tmpfs":
-            # udev lookup failing is a serious issue for anything other than tmpfs
-            log.error("udev lookup failed for device: %s", self.device)
+        if not flags.uevents:
+            # Get the UUID now that the format is created
+            udev.settle()
+            self.device.updateSysfsPath()
+            info = udev.get_device(self.device.sysfsPath)
+            # only do this if the format has a device known to udev
+            # (the format might not have a normal device at all)
+            if info:
+                if self.device.format.type != "btrfs":
+                    self.device.format.uuid = udev.device_get_uuid(info)
+                self.device.deviceLinks = udev.device_get_symlinks(info)
+            elif self.device.format.type != "tmpfs":
+                # udev lookup failing is a serious issue for anything other than tmpfs
+                log.error("udev lookup failed for device: %s", self.device)
 
         if callbacks and callbacks.create_format_post:
             msg = _("Created %(type)s on %(device)s") % {"type": self.device.format.type, "device": self.device.path}
@@ -653,7 +655,8 @@ class ActionDestroyFormat(DeviceAction):
         status = self.device.status
         self.device.setup(orig=True)
         self.format.destroy()
-        udev.settle()
+        if not flags.uevents:
+            udev.settle()
         if not status:
             self.device.teardown()
 
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index acc51e1..7a94078 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -31,6 +31,7 @@ from ..devicelibs import lvm
 
 from .. import errors
 from .. import util
+from ..flags import flags
 from ..formats import getFormat
 from ..storage_log import log_method_call
 from .. import udev
@@ -901,7 +902,8 @@ class LVMSnapShotBase(object):
         except errors.FSError:
             pass
 
-        udev.settle()
+        if not flags.uevents:
+            udev.settle()
         blockdev.lvm.lvsnapshotmerge(self.vg.name, self.lvname) # pylint: disable=no-member
 
 
diff --git a/blivet/devices/md.py b/blivet/devices/md.py
index f7499cf..b6c9d8e 100644
--- a/blivet/devices/md.py
+++ b/blivet/devices/md.py
@@ -470,6 +470,11 @@ class MDRaidArrayDevice(ContainerDevice, RaidDevice):
             self.metadataVersion = "1.0"
 
     def _postCreate(self):
+        if flags.uevents:
+            # All of the below will be handled by uevent handlers if they are
+            # enabled.
+            return super(MDRaidArrayDevice._postCreate())
+
         # this is critical since our status method requires a valid sysfs path
         self.exists = True  # this is needed to run updateSysfsPath
         self.updateSysfsPath()
@@ -493,7 +498,8 @@ class MDRaidArrayDevice(ContainerDevice, RaidDevice):
         blockdev.md.create(self.path, level, disks, spares,
                            version=self.metadataVersion,
                            bitmap=self.createBitmap)
-        udev.settle()
+        if not flags.uevents:
+            udev.settle()
 
     def _remove(self, member):
         self.setup()
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
index ae5bb26..6898266 100644
--- a/blivet/devices/partition.py
+++ b/blivet/devices/partition.py
@@ -568,7 +568,8 @@ class PartitionDevice(StorageDevice):
             # If a udev device is created with the watch option, then
             # a change uevent is synthesized and we need to wait for
             # things to settle.
-            udev.settle()
+            if flags.uevents:
+                udev.settle()
 
     def _create(self):
         """ Create the device. """
@@ -705,7 +706,8 @@ class PartitionDevice(StorageDevice):
     def _postDestroy(self):
         super(PartitionDevice, self)._postDestroy()
         if isinstance(self.disk, DMDevice):
-            udev.settle()
+            if not flags.uevents:
+                udev.settle()
             # self.exists has been unset, so don't use self.status
             if os.path.exists(self.path):
                 try:
diff --git a/blivet/devices/storage.py b/blivet/devices/storage.py
index 3c47818..a7fee09 100644
--- a/blivet/devices/storage.py
+++ b/blivet/devices/storage.py
@@ -385,8 +385,10 @@ class StorageDevice(Device):
 
         event_sync.reset()
         event_sync.notify()
-        udev.settle()
-        self.updateSysfsPath()
+        if not flags.uevents:
+            udev.settle()
+            self.updateSysfsPath()
+
         # the device may not be set up when we want information about it later
         if self._size == Size(0):
             self.updateSize()
@@ -410,7 +412,8 @@ class StorageDevice(Device):
         if self.format.exists:
             self.format.teardown()
 
-        udev.settle()
+        if not flags.uevents:
+            udev.settle()
 
         self.controlSync.stopping = True
         return True
@@ -511,8 +514,9 @@ class StorageDevice(Device):
         event_sync.notify() # notify event handler we're done post-processing
 
         self.setup()
-        self.updateSysfsPath()
-        udev.settle()
+        if not flags.uevents:
+            self.updateSysfsPath()
+            udev.settle()
 
         self._updateNetDevMountOption()
 
diff --git a/blivet/formats/disklabel.py b/blivet/formats/disklabel.py
index 5481a40..beb3eed 100644
--- a/blivet/formats/disklabel.py
+++ b/blivet/formats/disklabel.py
@@ -275,7 +275,8 @@ class DiskLabel(DeviceFormat):
         else:
             self.updateOrigPartedDisk()
         finally:
-            udev.settle()
+            if not flags.uevents:
+                udev.settle()
             if notify:
                 timeout = 2 if err else None
                 self.eventSync.wait(timeout=timeout)
@@ -293,7 +294,8 @@ class DiskLabel(DeviceFormat):
             raise DiskLabelCommitError(msg)
         else:
             self.updateOrigPartedDisk()
-            udev.settle()
+            if not flags.uevents:
+                udev.settle()
             self.eventSync.wait()
         finally:
             self.eventSync.reset()
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index fa756f1..3d9c463 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -740,7 +740,8 @@ class FS(DeviceFormat):
         if not os.path.exists(mountpoint):
             raise FSError("mountpoint does not exist")
 
-        udev.settle()
+        if not flags.uevents:
+            udev.settle()
         return True
 
     def _teardown(self, **kwargs):
diff --git a/blivet/udev.py b/blivet/udev.py
index 95356f2..ce72619 100644
--- a/blivet/udev.py
+++ b/blivet/udev.py
@@ -47,7 +47,8 @@ def get_device(sysfs_path):
     return dev
 
 def get_devices(subsystem="block"):
-    settle()
+    if not flags.uevents:
+        settle()
     return [d for d in global_udev.list_devices(subsystem=subsystem)
                         if not __is_blacklisted_blockdev(d.sys_name)]
 
@@ -65,7 +66,8 @@ def trigger(subsystem=None, action="add", name=None):
         argv.append("--sysname-match=%s" % name)
 
     util.run_program(["udevadm"] + argv)
-    settle()
+    if not flags.uevents:
+        settle()
 
 def resolve_devspec(devspec):
     if not devspec:
-- 
2.1.0

