diff --git a/SOURCES/python-pyudev-0.15-load-libudev-in-context.patch b/SOURCES/python-pyudev-0.15-load-libudev-in-context.patch
new file mode 100644
index 0000000..4b559e2
--- /dev/null
+++ b/SOURCES/python-pyudev-0.15-load-libudev-in-context.patch
@@ -0,0 +1,653 @@
+diff --git a/pyudev/_libudev.py b/pyudev/_libudev.py
+index efc27c9..7d97d35 100644
+--- a/pyudev/_libudev.py
++++ b/pyudev/_libudev.py
+@@ -284,6 +284,3 @@ def load_udev_library():
+                 if errorchecker:
+                     func.errcheck = errorchecker
+     return libudev
+-
+-
+-libudev = load_udev_library()
+diff --git a/pyudev/_util.py b/pyudev/_util.py
+index a99da08..c11b0b2 100644
+--- a/pyudev/_util.py
++++ b/pyudev/_util.py
+@@ -33,7 +33,6 @@ import os
+ import sys
+ import stat
+ 
+-from pyudev._libudev import libudev
+ 
+ if sys.version_info[0] == 2:
+     from pyudev._py2util import *
+@@ -101,7 +100,7 @@ def string_to_bool(value):
+     return value == '1'
+ 
+ 
+-def udev_list_iterate(entry):
++def udev_list_iterate(libudev, entry):
+     """
+     Iteration helper for udev list entry objects.
+ 
+diff --git a/pyudev/core.py b/pyudev/core.py
+index 83d2c7c..5017d80 100644
+--- a/pyudev/core.py
++++ b/pyudev/core.py
+@@ -35,7 +35,7 @@ except ImportError:
+     from pyudev._compat import check_output
+ 
+ from pyudev.device import Device
+-from pyudev._libudev import libudev
++from pyudev._libudev import load_udev_library
+ from pyudev._util import (ensure_unicode_string, ensure_byte_string,
+                           udev_list_iterate, property_value_to_bytes)
+ 
+@@ -89,10 +89,11 @@ class Context(object):
+         """
+         Create a new context.
+         """
+-        self._as_parameter_ = libudev.udev_new()
++        self._libudev = load_udev_library()
++        self._as_parameter_ = self._libudev.udev_new()
+ 
+     def __del__(self):
+-        libudev.udev_unref(self)
++        self._libudev.udev_unref(self)
+ 
+     @property
+     def sys_path(self):
+@@ -102,7 +103,7 @@ class Context(object):
+         The mount point can be overwritten using the environment variable
+         :envvar:`SYSFS_PATH`.  Use this for testing purposes.
+         """
+-        return ensure_unicode_string(libudev.udev_get_sys_path(self))
++        return ensure_unicode_string(self._libudev.udev_get_sys_path(self))
+ 
+     @property
+     def device_path(self):
+@@ -111,7 +112,7 @@ class Context(object):
+ 
+         This can be overridden in the udev configuration.
+         """
+-        return ensure_unicode_string(libudev.udev_get_dev_path(self))
++        return ensure_unicode_string(self._libudev.udev_get_dev_path(self))
+ 
+     @property
+     def run_path(self):
+@@ -123,7 +124,7 @@ class Context(object):
+ 
+         .. versionadded:: 0.10
+         """
+-        return ensure_unicode_string(libudev.udev_get_run_path(self))
++        return ensure_unicode_string(self._libudev.udev_get_run_path(self))
+ 
+     @property
+     def log_priority(self):
+@@ -142,11 +143,11 @@ class Context(object):
+ 
+         .. versionadded:: 0.9
+         """
+-        return libudev.udev_get_log_priority(self)
++        return self._libudev.udev_get_log_priority(self)
+ 
+     @log_priority.setter
+     def log_priority(self, value):
+-        libudev.udev_set_log_priority(self, value)
++        self._libudev.udev_set_log_priority(self, value)
+ 
+     def list_devices(self, **kwargs):
+         """
+@@ -205,10 +206,11 @@ class Enumerator(object):
+         if not isinstance(context, Context):
+             raise TypeError('Invalid context object')
+         self.context = context
+-        self._as_parameter_ = libudev.udev_enumerate_new(context)
++        self._as_parameter_ = context._libudev.udev_enumerate_new(context)
++        self._libudev = context._libudev
+ 
+     def __del__(self):
+-        libudev.udev_enumerate_unref(self)
++        self._libudev.udev_enumerate_unref(self)
+ 
+     def match(self, **kwargs):
+         """
+@@ -265,9 +267,9 @@ class Enumerator(object):
+ 
+         Return the instance again.
+         """
+-        match = (libudev.udev_enumerate_add_match_subsystem
++        match = (self._libudev.udev_enumerate_add_match_subsystem
+                  if not nomatch else
+-                 libudev.udev_enumerate_add_nomatch_subsystem)
++                 self._libudev.udev_enumerate_add_nomatch_subsystem)
+         match(self, ensure_byte_string(subsystem))
+         return self
+ 
+@@ -281,7 +283,7 @@ class Enumerator(object):
+ 
+         .. versionadded:: 0.8
+         """
+-        libudev.udev_enumerate_add_match_sysname(
++        self._libudev.udev_enumerate_add_match_sysname(
+             self, ensure_byte_string(sys_name))
+         return self
+ 
+@@ -301,7 +303,7 @@ class Enumerator(object):
+ 
+         Return the instance again.
+         """
+-        libudev.udev_enumerate_add_match_property(
++        self._libudev.udev_enumerate_add_match_property(
+             self, ensure_byte_string(property), property_value_to_bytes(value))
+         return self
+ 
+@@ -332,9 +334,9 @@ class Enumerator(object):
+ 
+         Return the instance again.
+         """
+-        match = (libudev.udev_enumerate_add_match_sysattr
++        match = (self._libudev.udev_enumerate_add_match_sysattr
+                  if not nomatch else
+-                 libudev.udev_enumerate_add_nomatch_sysattr)
++                 self._libudev.udev_enumerate_add_nomatch_sysattr)
+         match(self, ensure_byte_string(attribute),
+               property_value_to_bytes(value))
+         return self
+@@ -351,7 +353,7 @@ class Enumerator(object):
+ 
+         .. versionadded:: 0.6
+         """
+-        libudev.udev_enumerate_add_match_tag(self, ensure_byte_string(tag))
++        self._libudev.udev_enumerate_add_match_tag(self, ensure_byte_string(tag))
+         return self
+ 
+     def match_is_initialized(self):
+@@ -372,7 +374,7 @@ class Enumerator(object):
+ 
+         .. versionadded:: 0.8
+         """
+-        libudev.udev_enumerate_add_match_is_initialized(self)
++        self._libudev.udev_enumerate_add_match_is_initialized(self)
+         return self
+ 
+     def match_parent(self, parent):
+@@ -389,7 +391,7 @@ class Enumerator(object):
+ 
+         .. versionadded:: 0.13
+         """
+-        libudev.udev_enumerate_add_match_parent(self, parent)
++        self._libudev.udev_enumerate_add_match_parent(self, parent)
+         return self
+ 
+     def __iter__(self):
+@@ -398,7 +400,7 @@ class Enumerator(object):
+ 
+         Yield :class:`Device` objects.
+         """
+-        libudev.udev_enumerate_scan_devices(self)
+-        entry = libudev.udev_enumerate_get_list_entry(self)
+-        for name, _ in udev_list_iterate(entry):
++        self._libudev.udev_enumerate_scan_devices(self)
++        entry = self._libudev.udev_enumerate_get_list_entry(self)
++        for name, _ in udev_list_iterate(self._libudev, entry):
+             yield Device.from_sys_path(self.context, name)
+diff --git a/pyudev/device.py b/pyudev/device.py
+index f9a4325..d5ae3da 100644
+--- a/pyudev/device.py
++++ b/pyudev/device.py
+@@ -32,7 +32,6 @@ import os
+ from collections import Mapping, Container, Iterable
+ from datetime import timedelta
+ 
+-from pyudev._libudev import libudev
+ from pyudev._util import (ensure_byte_string, ensure_unicode_string,
+                           udev_list_iterate, string_to_bool,
+                           get_device_type)
+@@ -219,7 +218,7 @@ class Device(Mapping):
+            Raise :exc:`DeviceNotFoundAtPathError` instead of
+            :exc:`NoSuchDeviceError`
+         """
+-        device = libudev.udev_device_new_from_syspath(
++        device = context._libudev.udev_device_new_from_syspath(
+             context, ensure_byte_string(sys_path))
+         if not device:
+             raise DeviceNotFoundAtPathError(sys_path)
+@@ -247,7 +246,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.5
+         """
+-        device = libudev.udev_device_new_from_subsystem_sysname(
++        device = context._libudev.udev_device_new_from_subsystem_sysname(
+             context, ensure_byte_string(subsystem),
+             ensure_byte_string(sys_name))
+         if not device:
+@@ -295,7 +294,7 @@ class Device(Mapping):
+         if type not in ('char', 'block'):
+             raise ValueError('Invalid type: {0!r}. Must be one of "char" '
+                              'or "block".'.format(type))
+-        device = libudev.udev_device_new_from_devnum(
++        device = context._libudev.udev_device_new_from_devnum(
+             context, ensure_byte_string(type[0]), number)
+         if not device:
+             raise DeviceNotFoundByNumberError(type, number)
+@@ -360,7 +359,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.6
+         """
+-        device = libudev.udev_device_new_from_environment(context)
++        device = context._libudev.udev_device_new_from_environment(context)
+         if not device:
+             raise DeviceNotFoundInEnvironmentError()
+         return cls(context, device)
+@@ -368,9 +367,10 @@ class Device(Mapping):
+     def __init__(self, context, _device):
+         self.context = context
+         self._as_parameter_ = _device
++        self._libudev = context._libudev
+ 
+     def __del__(self):
+-        libudev.udev_device_unref(self)
++        self._libudev.udev_device_unref(self)
+ 
+     def __repr__(self):
+         return 'Device({0.sys_path!r})'.format(self)
+@@ -381,12 +381,12 @@ class Device(Mapping):
+         The parent :class:`Device` or ``None``, if there is no parent
+         device.
+         """
+-        parent = libudev.udev_device_get_parent(self)
++        parent = self._libudev.udev_device_get_parent(self)
+         if not parent:
+             return None
+         # the parent device is not referenced, thus forcibly acquire a
+         # reference
+-        return Device(self.context, libudev.udev_device_ref(parent))
++        return Device(self.context, self._libudev.udev_device_ref(parent))
+ 
+     @property
+     def children(self):
+@@ -432,12 +432,12 @@ class Device(Mapping):
+         subsystem = ensure_byte_string(subsystem)
+         if device_type is not None:
+             device_type = ensure_byte_string(device_type)
+-        parent = libudev.udev_device_get_parent_with_subsystem_devtype(
++        parent = self._libudev.udev_device_get_parent_with_subsystem_devtype(
+             self, subsystem, device_type)
+         if not parent:
+             return None
+         # parent device is not referenced, thus forcibly acquire a reference
+-        return Device(self.context, libudev.udev_device_ref(parent))
++        return Device(self.context, self._libudev.udev_device_ref(parent))
+ 
+     def traverse(self):
+         """
+@@ -458,7 +458,8 @@ class Device(Mapping):
+         Absolute path of this device in ``sysfs`` including the ``sysfs``
+         mount point as unicode string.
+         """
+-        return ensure_unicode_string(libudev.udev_device_get_syspath(self))
++        return ensure_unicode_string(
++            self._libudev.udev_device_get_syspath(self))
+ 
+     @property
+     def device_path(self):
+@@ -470,21 +471,24 @@ class Device(Mapping):
+         mount point.  However, the path is absolute and starts with a slash
+         ``'/'``.
+         """
+-        return ensure_unicode_string(libudev.udev_device_get_devpath(self))
++        return ensure_unicode_string(
++            self._libudev.udev_device_get_devpath(self))
+ 
+     @property
+     def subsystem(self):
+         """
+         Name of the subsystem this device is part of as unicode string.
+         """
+-        return ensure_unicode_string(libudev.udev_device_get_subsystem(self))
++        return ensure_unicode_string(
++            self._libudev.udev_device_get_subsystem(self))
+ 
+     @property
+     def sys_name(self):
+         """
+         Device file name inside ``sysfs`` as unicode string.
+         """
+-        return ensure_unicode_string(libudev.udev_device_get_sysname(self))
++        return ensure_unicode_string(
++            self._libudev.udev_device_get_sysname(self))
+ 
+     @property
+     def sys_number(self):
+@@ -508,7 +512,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.11
+         """
+-        number = libudev.udev_device_get_sysnum(self)
++        number = self._libudev.udev_device_get_sysnum(self)
+         if number is not None:
+             return ensure_unicode_string(number)
+ 
+@@ -529,7 +533,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.10
+         """
+-        device_type = libudev.udev_device_get_devtype(self)
++        device_type = self._libudev.udev_device_get_devtype(self)
+         if device_type is not None:
+             return ensure_unicode_string(device_type)
+ 
+@@ -541,7 +545,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.5
+         """
+-        driver = libudev.udev_device_get_driver(self)
++        driver = self._libudev.udev_device_get_driver(self)
+         if driver:
+             return ensure_unicode_string(driver)
+ 
+@@ -563,7 +567,7 @@ class Device(Mapping):
+            this property is not necessary equal to the ``filename`` given to
+            :meth:`from_device_file()`.
+         """
+-        node = libudev.udev_device_get_devnode(self)
++        node = self._libudev.udev_device_get_devnode(self)
+         if node:
+             return ensure_unicode_string(node)
+ 
+@@ -591,7 +595,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.11
+         """
+-        return libudev.udev_device_get_devnum(self)
++        return self._libudev.udev_device_get_devnum(self)
+ 
+     @property
+     def is_initialized(self):
+@@ -614,7 +618,7 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.8
+         """
+-        return bool(libudev.udev_device_get_is_initialized(self))
++        return bool(self._libudev.udev_device_get_is_initialized(self))
+ 
+     @property
+     def time_since_initialized(self):
+@@ -631,7 +635,8 @@ class Device(Mapping):
+ 
+         .. versionadded:: 0.8
+         """
+-        microseconds = libudev.udev_device_get_usec_since_initialized(self)
++        microseconds = self._libudev.udev_device_get_usec_since_initialized(
++            self)
+         return timedelta(microseconds=microseconds)
+ 
+     @property
+@@ -650,8 +655,8 @@ class Device(Mapping):
+         The property provides access to all such symbolic links, which were
+         created by UDev for this device.
+         """
+-        devlinks = libudev.udev_device_get_devlinks_list_entry(self)
+-        for name, _ in udev_list_iterate(devlinks):
++        devlinks = self._libudev.udev_device_get_devlinks_list_entry(self)
++        for name, _ in udev_list_iterate(self._libudev, devlinks):
+             yield ensure_unicode_string(name)
+ 
+     @property
+@@ -713,19 +718,16 @@ class Device(Mapping):
+         Return a generator yielding the names of all properties of this
+         device as unicode strings.
+         """
+-        properties = libudev.udev_device_get_properties_list_entry(self)
+-        for name, _ in udev_list_iterate(properties):
++        properties = self._libudev.udev_device_get_properties_list_entry(self)
++        for name, _ in udev_list_iterate(self._libudev, properties):
+             yield ensure_unicode_string(name)
+ 
+     def __len__(self):
+         """
+         Return the amount of properties defined for this device as integer.
+         """
+-        properties = libudev.udev_device_get_properties_list_entry(self)
+-        i = 0
+-        for i, _ in enumerate(udev_list_iterate(properties), start=1):
+-            pass
+-        return i
++        properties = self._libudev.udev_device_get_properties_list_entry(self)
++        return sum(1 for _ in udev_list_iterate(self._libudev, properties))
+ 
+     def __getitem__(self, property):
+         """
+@@ -738,7 +740,7 @@ class Device(Mapping):
+         :exc:`~exceptions.KeyError`, if the given property is not defined
+         for this device.
+         """
+-        value = libudev.udev_device_get_property_value(
++        value = self._libudev.udev_device_get_property_value(
+             self, ensure_byte_string(property))
+         if value is None:
+             raise KeyError(property)
+@@ -814,14 +816,17 @@ class Tags(Iterable, Container):
+     def __init__(self, device):
+         self.device = device
+ 
+-    if hasattr(libudev, 'udev_device_has_tag'):
+-        def _has_tag(self, tag):
+-            return bool(libudev.udev_device_has_tag(
++    def _has_tag(self, tag):
++        if hasattr(self._libudev, 'udev_device_has_tag'):
++            return bool(self._libudev.udev_device_has_tag(
+                 self.device, ensure_byte_string(tag)))
+-    else:
+-        def _has_tag(self, tag):
++        else:
+             return any(t == tag for t in self)
+ 
++    @property
++    def _libudev(self):
++        return self.device._libudev
++
+     def __contains__(self, tag):
+         """
+         Check for existence of ``tag``.
+@@ -839,8 +844,8 @@ class Tags(Iterable, Container):
+ 
+         Yield each tag as unicode string.
+         """
+-        tags = libudev.udev_device_get_tags_list_entry(self.device)
+-        for tag, _ in udev_list_iterate(tags):
++        tags = self._libudev.udev_device_get_tags_list_entry(self.device)
++        for tag, _ in udev_list_iterate(self._libudev, tags):
+             yield ensure_unicode_string(tag)
+ 
+ 
+@@ -876,29 +881,26 @@ class Attributes(Mapping):
+ 
+     def __init__(self, device):
+         self.device = device
++        self._libudev = device._libudev
+ 
+-    if hasattr(libudev, 'udev_device_get_sysattr_list_entry'):
+-        @property
+-        def _attributes(self):
+-            attrs = libudev.udev_device_get_sysattr_list_entry(self.device)
+-            for attribute, _ in udev_list_iterate(attrs):
++    def _get_attributes(self):
++        if hasattr(self._libudev, 'udev_device_get_sysattr_list_entry'):
++            attrs = self._libudev.udev_device_get_sysattr_list_entry(
++                self.device)
++            for attribute, _ in udev_list_iterate(self._libudev, attrs):
+                 yield ensure_unicode_string(attribute)
+-    else:
+-        @property
+-        def _attributes(self):
++        else:
+             sys_path = self.device.sys_path
+-            return (fn for fn in os.listdir(sys_path) if
+-                    _is_attribute_file(os.path.join(sys_path, fn)) and
+-                    fn in self)
++            for filename in os.listdir(sys_path):
++                filepath = os.path.join(sys_path, filename)
++                if _is_attribute_file(filepath):
++                    yield filename
+ 
+     def __len__(self):
+         """
+         Return the amount of attributes defined.
+         """
+-        i = 0
+-        for i, _ in enumerate(self._attributes, start=1):
+-            pass
+-        return i
++        return sum(1 for _ in self._get_attributes())
+ 
+     def __iter__(self):
+         """
+@@ -906,10 +908,10 @@ class Attributes(Mapping):
+ 
+         Yield each attribute name as unicode string.
+         """
+-        return self._attributes
++        return self._get_attributes()
+ 
+     def __contains__(self, attribute):
+-        value = libudev.udev_device_get_sysattr_value(
++        value = self._libudev.udev_device_get_sysattr_value(
+             self.device, ensure_byte_string(attribute))
+         return value is not None
+ 
+@@ -924,7 +926,7 @@ class Attributes(Mapping):
+         :exc:`~exceptions.KeyError`, if the given attribute is not defined
+         for this device.
+         """
+-        value = libudev.udev_device_get_sysattr_value(
++        value = self._libudev.udev_device_get_sysattr_value(
+             self.device, ensure_byte_string(attribute))
+         if value is None:
+             raise KeyError(attribute)
+diff --git a/pyudev/monitor.py b/pyudev/monitor.py
+index 8153ecc..6a51564 100644
+--- a/pyudev/monitor.py
++++ b/pyudev/monitor.py
+@@ -36,7 +36,6 @@ import select
+ from threading import Thread
+ from contextlib import closing
+ 
+-from pyudev._libudev import libudev
+ from pyudev._util import ensure_byte_string, ensure_unicode_string, reraise
+ 
+ from pyudev.core import Device
+@@ -82,6 +81,7 @@ class Monitor(object):
+         self.context = context
+         self._as_parameter_ = monitor_p
+         self._socket_path = socket_path
++        self._libudev = context._libudev
+ 
+     def _reraise_with_socket_path(self):
+         _, exc_value, traceback = sys.exc_info()
+@@ -89,7 +89,7 @@ class Monitor(object):
+         reraise(exc_value, traceback)
+ 
+     def __del__(self):
+-        libudev.udev_monitor_unref(self)
++        self._libudev.udev_monitor_unref(self)
+ 
+     @classmethod
+     def from_netlink(cls, context, source='udev'):
+@@ -117,7 +117,7 @@ class Monitor(object):
+         if source not in ('kernel', 'udev'):
+             raise ValueError('Invalid source: {0!r}. Must be one of "udev" '
+                              'or "kernel"'.format(source))
+-        monitor = libudev.udev_monitor_new_from_netlink(
++        monitor = context._libudev.udev_monitor_new_from_netlink(
+             context, ensure_byte_string(source))
+         if not monitor:
+             raise EnvironmentError('Could not create udev monitor')
+@@ -140,7 +140,7 @@ class Monitor(object):
+         socket.  Raise :exc:`~exceptions.EnvironmentError`, if the creation of
+         the monitor failed.
+         """
+-        monitor = libudev.udev_monitor_new_from_socket(
++        monitor = context._libudev.udev_monitor_new_from_socket(
+             context, ensure_byte_string(socket_path))
+         if not monitor:
+             raise EnvironmentError('Could not create monitor for socket: '
+@@ -154,7 +154,7 @@ class Monitor(object):
+         This is really a real file descriptor ;), which can be watched and
+         :func:`select.select`\ ed.
+         """
+-        return libudev.udev_monitor_get_fd(self)
++        return self._libudev.udev_monitor_get_fd(self)
+ 
+     def filter_by(self, subsystem, device_type=None):
+         """
+@@ -179,9 +179,9 @@ class Monitor(object):
+         subsystem = ensure_byte_string(subsystem)
+         if device_type:
+             device_type = ensure_byte_string(device_type)
+-        libudev.udev_monitor_filter_add_match_subsystem_devtype(
++        self._libudev.udev_monitor_filter_add_match_subsystem_devtype(
+             self, subsystem, device_type)
+-        libudev.udev_monitor_filter_update(self)
++        self._libudev.udev_monitor_filter_update(self)
+ 
+     def filter_by_tag(self, tag):
+         """
+@@ -202,9 +202,9 @@ class Monitor(object):
+         .. versionchanged:: 0.15
+            This method can also be after :meth:`enable_receiving()` now
+         """
+-        libudev.udev_monitor_filter_add_match_tag(
++        self._libudev.udev_monitor_filter_add_match_tag(
+             self, ensure_byte_string(tag))
+-        libudev.udev_monitor_filter_update(self)
++        self._libudev.udev_monitor_filter_update(self)
+ 
+     def remove_filter(self):
+         """
+@@ -223,8 +223,8 @@ class Monitor(object):
+ 
+         .. versionadded:: 0.15
+         """
+-        libudev.udev_monitor_filter_remove(self)
+-        libudev.udev_monitor_filter_update(self)
++        self._libudev.udev_monitor_filter_remove(self)
++        self._libudev.udev_monitor_filter_update(self)
+ 
+     def enable_receiving(self):
+         """
+@@ -240,7 +240,7 @@ class Monitor(object):
+            monitor.
+         """
+         try:
+-            libudev.udev_monitor_enable_receiving(self)
++            self._libudev.udev_monitor_enable_receiving(self)
+         except EnvironmentError:
+             self._reraise_with_socket_path()
+ 
+@@ -272,7 +272,7 @@ class Monitor(object):
+         .. _python-prctl: http://packages.python.org/python-prctl
+         """
+         try:
+-            libudev.udev_monitor_set_receive_buffer_size(self, size)
++            self._libudev.udev_monitor_set_receive_buffer_size(self, size)
+         except EnvironmentError:
+             self._reraise_with_socket_path()
+ 
+@@ -301,13 +301,13 @@ class Monitor(object):
+         read.
+         """
+         try:
+-            device_p = libudev.udev_monitor_receive_device(self)
++            device_p = self._libudev.udev_monitor_receive_device(self)
+         except EnvironmentError:
+             self._reraise_with_socket_path()
+         if not device_p:
+             raise EnvironmentError('Could not receive device')
+         action = ensure_unicode_string(
+-            libudev.udev_device_get_action(device_p))
++            self._libudev.udev_device_get_action(device_p))
+         return action, Device(self.context, device_p)
+ 
+     def __iter__(self):
diff --git a/SOURCES/python-pyudev-0.15-retry-interrupted-calls.patch b/SOURCES/python-pyudev-0.15-retry-interrupted-calls.patch
new file mode 100644
index 0000000..f9650ba
--- /dev/null
+++ b/SOURCES/python-pyudev-0.15-retry-interrupted-calls.patch
@@ -0,0 +1,81 @@
+diff --git a/pyudev/_util.py b/pyudev/_util.py
+index 266b161..3ce82b2 100644
+--- a/pyudev/_util.py
++++ b/pyudev/_util.py
+@@ -32,6 +32,7 @@
+ import os
+ import sys
+ import stat
++import errno
+ 
+ 
+ if sys.version_info[0] == 2:
+@@ -141,3 +142,37 @@ def get_device_type(filename):
+         return 'block'
+     else:
+         raise ValueError('not a device file: {0!r}'.format(filename))
++
++
++def eintr_retry_call(func, *args, **kwargs):
++    """
++    Handle interruptions to an interruptible system call.
++
++    Run an interruptible system call in a loop and retry if it raises EINTR.
++    The signal calls that may raise EINTR prior to Python 3.5 are listed in
++    PEP 0475.  Any calls to these functions must be wrapped in eintr_retry_call
++    in order to handle EINTR returns in older versions of Python.
++
++    This function is safe to use under Python 3.5 and newer since the wrapped
++    function will simply return without raising EINTR.
++
++    This function is based on _eintr_retry_call in python's subprocess.py.
++    """
++
++    # select.error inherits from Exception instead of OSError in Python 2
++    import select
++
++    while True:
++        try:
++            return func(*args, **kwargs)
++        except (OSError, IOError, select.error) as e:
++            # If this is not an IOError or OSError, it's the old select.error
++            # type, which means that the errno is only accessible via subscript
++            if isinstance(e, (OSError, IOError)):
++                error_code = e.errno
++            else:
++                error_code = e.args[0]
++
++            if error_code == errno.EINTR:
++                continue
++            raise
+diff --git a/pyudev/monitor.py b/pyudev/monitor.py
+index b1eb71c..d87dc2c 100644
+--- a/pyudev/monitor.py
++++ b/pyudev/monitor.py
+@@ -36,7 +36,7 @@ import select
+ from threading import Thread
+ from contextlib import closing
+ 
+-from pyudev._util import ensure_byte_string, ensure_unicode_string, reraise
++from pyudev._util import ensure_byte_string, ensure_unicode_string, reraise, eintr_retry_call
+ 
+ from pyudev.core import Device
+ 
+@@ -328,7 +328,7 @@ class Monitor(object):
+         with closing(select.epoll()) as notifier:
+             notifier.register(self, select.EPOLLIN)
+             while True:
+-                events = notifier.poll()
++                events = eintr_retry_call(notifier.poll)
+                 for event in events:
+                     yield self.receive_device()
+ 
+@@ -399,7 +399,7 @@ class MonitorObserver(Thread):
+             # and on the monitor
+             notifier.register(self.monitor, select.EPOLLIN)
+             while True:
+-                for fd, _ in notifier.poll():
++                for fd, _ in eintr_retry_call(notifier.poll):
+                     if fd == self._stop_event_source:
+                         # in case of a stop event, close our pipe side, and
+                         # return from the thread
diff --git a/SPECS/python-pyudev.spec b/SPECS/python-pyudev.spec
index 06e4b72..9a43a69 100644
--- a/SPECS/python-pyudev.spec
+++ b/SPECS/python-pyudev.spec
@@ -2,13 +2,16 @@
 
 Name:             python-pyudev
 Version:          0.15
-Release:          7%{?dist}.1
+Release:          9%{?dist}
 Summary:          A libudev binding
 Group:            Development/Languages
 License:          LGPLv2+
 URL:              http://pypi.python.org/pypi/pyudev
 Source0:          http://pypi.python.org/packages/source/p/pyudev/pyudev-0.15.tar.gz
 BuildArch:        noarch
+Patch0:           python-pyudev-0.15-load-libudev-in-context.patch
+# backported from upstream
+Patch1:           python-pyudev-0.15-retry-interrupted-calls.patch
 Requires:         systemd-libs
 BuildRequires:    python-devel python-setuptools systemd-devel
 
@@ -28,9 +31,11 @@ officially supported.
 
 %prep
 %setup -q -n %{modname}-%{version}
+%patch0 -p1
+%patch1 -p1
 
 %build
-%{__python} setup.py build 
+%{__python} setup.py build
 
 %install
 %{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT
@@ -43,9 +48,15 @@ officially supported.
 
 
 %changelog
-* Thu Dec  3 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 0.15-7.1
+* Wed Mar 22 2017 Jaroslav Škarvada <jskarvad@redhat.com> - 0.15-9
+- The libudev library loaded in context to workaround cleanup problems
+  Resolves: rhbz#1252833
+- Retry interrupted calls
+  Resolves: rhbz#1108921
+
+* Thu Dec  3 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 0.15-8
 - Added systemd-libs requirement for libudev
-  Resolves: rhbz#1291562
+  Resolves: rhbz#1287461
 
 * Thu Apr  9 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 0.15-7
 - Dropped unneeded explicit dependencies