Applied new-hotplug.patch from OE
authorAndreas Oberritter <obi@opendreambox.org>
Thu, 21 Oct 2010 21:51:51 +0000 (21:51 +0000)
committerAndreas Oberritter <obi@opendreambox.org>
Tue, 16 Nov 2010 15:08:51 +0000 (16:08 +0100)
lib/python/Components/Harddisk.py
lib/python/Plugins/SystemPlugins/Hotplug/plugin.py

index 7f83756..0f1a8fc 100644 (file)
@@ -15,17 +15,17 @@ def readFile(filename):
        file.close()
        return data
 
        file.close()
        return data
 
-class Harddisk:
-       DEVTYPE_UDEV = 0
-       DEVTYPE_DEVFS = 1
+DEVTYPE_UDEV = 0
+DEVTYPE_DEVFS = 1
 
 
+class Harddisk:
        def __init__(self, device):
                self.device = device
 
                if access("/dev/.udev", 0):
        def __init__(self, device):
                self.device = device
 
                if access("/dev/.udev", 0):
-                       self.type = self.DEVTYPE_UDEV
+                       self.type = DEVTYPE_UDEV
                elif access("/dev/.devfsd", 0):
                elif access("/dev/.devfsd", 0):
-                       self.type = self.DEVTYPE_DEVFS
+                       self.type = DEVTYPE_DEVFS
                else:
                        print "Unable to determine structure of /dev"
 
                else:
                        print "Unable to determine structure of /dev"
 
@@ -37,11 +37,11 @@ class Harddisk:
                self.disk_path = ''
                self.phys_path = path.realpath(self.sysfsPath('device'))
 
                self.disk_path = ''
                self.phys_path = path.realpath(self.sysfsPath('device'))
 
-               if self.type == self.DEVTYPE_UDEV:
+               if self.type == DEVTYPE_UDEV:
                        self.dev_path = '/dev/' + self.device
                        self.disk_path = self.dev_path
 
                        self.dev_path = '/dev/' + self.device
                        self.disk_path = self.dev_path
 
-               elif self.type == self.DEVTYPE_DEVFS:
+               elif self.type == DEVTYPE_DEVFS:
                        tmp = readFile(self.sysfsPath('dev')).split(':')
                        s_major = int(tmp[0])
                        s_minor = int(tmp[1])
                        tmp = readFile(self.sysfsPath('dev')).split(':')
                        s_major = int(tmp[0])
                        s_minor = int(tmp[1])
@@ -64,9 +64,9 @@ class Harddisk:
                return self.device < ob.device
 
        def partitionPath(self, n):
                return self.device < ob.device
 
        def partitionPath(self, n):
-               if self.type == self.DEVTYPE_UDEV:
+               if self.type == DEVTYPE_UDEV:
                        return self.dev_path + n
                        return self.dev_path + n
-               elif self.type == self.DEVTYPE_DEVFS:
+               elif self.type == DEVTYPE_DEVFS:
                        return self.dev_path + '/part' + n
 
        def sysfsPath(self, filename):
                        return self.dev_path + '/part' + n
 
        def sysfsPath(self, filename):
@@ -79,9 +79,9 @@ class Harddisk:
 
        def bus(self):
                # CF (7025 specific)
 
        def bus(self):
                # CF (7025 specific)
-               if self.type == self.DEVTYPE_UDEV:
+               if self.type == DEVTYPE_UDEV:
                        ide_cf = False  # FIXME
                        ide_cf = False  # FIXME
-               elif self.type == self.DEVTYPE_DEVFS:
+               elif self.type == DEVTYPE_DEVFS:
                        ide_cf = self.device[:2] == "hd" and "host0" not in self.dev_path
 
                internal = "pci" in self.phys_path
                        ide_cf = self.device[:2] == "hd" and "host0" not in self.dev_path
 
                internal = "pci" in self.phys_path
@@ -142,7 +142,7 @@ class Harddisk:
 
        def numPartitions(self):
                numPart = -1
 
        def numPartitions(self):
                numPart = -1
-               if self.type == self.DEVTYPE_UDEV:
+               if self.type == DEVTYPE_UDEV:
                        try:
                                devdir = listdir('/dev')
                        except OSError:
                        try:
                                devdir = listdir('/dev')
                        except OSError:
@@ -151,7 +151,7 @@ class Harddisk:
                                if filename.startswith(self.device):
                                        numPart += 1
 
                                if filename.startswith(self.device):
                                        numPart += 1
 
-               elif self.type == self.DEVTYPE_DEVFS:
+               elif self.type == DEVTYPE_DEVFS:
                        try:
                                idedir = listdir(self.dev_path)
                        except OSError:
                        try:
                                idedir = listdir(self.dev_path)
                        except OSError:
@@ -413,24 +413,38 @@ class Partition:
                                return True
                return False
 
                                return True
                return False
 
-DEVICEDB =  \
+DEVICEDB_SR = \
        {"dm8000":
                {
        {"dm8000":
                {
-                       # dm8000:
-                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": "Front USB Slot",
-                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": "Back, upper USB Slot",
-                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": "Back, lower USB Slot",
-                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host1/target1:0:0/1:0:0:0": "DVD Drive",
+                       "/devices/pci0000:01/0000:01:00.0/host0/target0:0:0/0:0:0:0": _("DVD Drive"),
+                       "/devices/pci0000:01/0000:01:00.0/host1/target1:0:0/1:0:0:0": _("DVD Drive"),
+                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host3/target3:0:0/3:0:0:0": _("DVD Drive"),
+               },
+       "dm800":
+       {
+       },
+       "dm7025":
+       {
+       }
+       }
+
+DEVICEDB = \
+       {"dm8000":
+               {
+                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": _("Front USB Slot"),
+                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": _("Back, upper USB Slot"),
+                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": _("Back, lower USB Slot"),
+                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": _("Front USB Slot"),
+                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/": _("Internal USB Slot"),
+                       "/devices/platform/brcm-ohci-1.1/usb4/4-1/4-1:1.0/": _("Internal USB Slot"),
                },
        "dm800":
        {
                },
        "dm800":
        {
-               # dm800:
                "/devices/platform/brcm-ehci.0/usb1/1-2/1-2:1.0": "Upper USB Slot",
                "/devices/platform/brcm-ehci.0/usb1/1-1/1-1:1.0": "Lower USB Slot",
        },
        "dm7025":
        {
                "/devices/platform/brcm-ehci.0/usb1/1-2/1-2:1.0": "Upper USB Slot",
                "/devices/platform/brcm-ehci.0/usb1/1-1/1-1:1.0": "Lower USB Slot",
        },
        "dm7025":
        {
-               # dm7025:
                "/devices/pci0000:00/0000:00:14.1/ide1/1.0": "CF Card Slot", #hdc
                "/devices/pci0000:00/0000:00:14.1/ide0/0.0": "Internal Harddisk"
        }
                "/devices/pci0000:00/0000:00:14.1/ide1/1.0": "CF Card Slot", #hdc
                "/devices/pci0000:00/0000:00:14.1/ide0/0.0": "Internal Harddisk"
        }
@@ -441,6 +455,7 @@ class HarddiskManager:
                self.hdd = [ ]
                self.cd = ""
                self.partitions = [ ]
                self.hdd = [ ]
                self.cd = ""
                self.partitions = [ ]
+               self.devices_scanned_on_init = [ ]
 
                self.on_partition_list_change = CList()
 
 
                self.on_partition_list_change = CList()
 
@@ -508,24 +523,23 @@ class HarddiskManager:
        def enumerateBlockDevices(self):
                print "enumerating block devices..."
                for blockdev in listdir("/sys/block"):
        def enumerateBlockDevices(self):
                print "enumerating block devices..."
                for blockdev in listdir("/sys/block"):
-                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(blockdev)
-                       print "found block device '%s':" % blockdev, 
-                       if error:
-                               print "error querying properties"
-                       elif blacklisted:
-                               print "blacklisted"
-                       elif not medium_found:
-                               print "no medium"
-                       else:
-                               print "ok, removable=%s, cdrom=%s, partitions=%s, device=%s" % (removable, is_cdrom, partitions, blockdev)
-
-                               self.addHotplugPartition(blockdev)
-                               for part in partitions:
-                                       self.addHotplugPartition(part)
+                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.addHotplugPartition(blockdev)
+                       if not error and not blacklisted:
+                               if medium_found:
+                                       for part in partitions:
+                                               self.addHotplugPartition(part)
+                               self.devices_scanned_on_init.append((blockdev, removable, is_cdrom, medium_found))
 
        def getAutofsMountpoint(self, device):
                return "/autofs/%s/" % (device)
 
 
        def getAutofsMountpoint(self, device):
                return "/autofs/%s/" % (device)
 
+       def is_hard_mounted(self, device):
+               mounts = file('/proc/mounts').read().split('\n')
+               for x in mounts:
+                       if x.find('/autofs') == -1 and x.find(device) != -1:
+                               return True
+               return False
+
        def addHotplugPartition(self, device, physdev = None):
                if not physdev:
                        dev, part = self.splitDeviceName(device)
        def addHotplugPartition(self, device, physdev = None):
                if not physdev:
                        dev, part = self.splitDeviceName(device)
@@ -535,22 +549,36 @@ class HarddiskManager:
                                physdev = dev
                                print "couldn't determine blockdev physdev for device", device
 
                                physdev = dev
                                print "couldn't determine blockdev physdev for device", device
 
-               # device is the device name, without /dev
-               # physdev is the physical device path, which we (might) use to determine the userfriendly name
-               description = self.getUserfriendlyDeviceName(device, physdev)
+               error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
+               print "found block device '%s':" % device,
 
 
-               p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device)
-               self.partitions.append(p)
-               self.on_partition_list_change("add", p)
+               if blacklisted:
+                       print "blacklisted"
+               else:
+                       if error:
+                               print "error querying properties"
+                       elif not medium_found:
+                               print "no medium"
+                       else:
+                               print "ok, removable=%s, cdrom=%s, partitions=%s" % (removable, is_cdrom, partitions)
+
+                       l = len(device)
+                       if l:
+                               # see if this is a harddrive
+                               if not device[l-1].isdigit() and not removable and not is_cdrom:
+                                       self.hdd.append(Harddisk(device))
+                                       self.hdd.sort()
+                                       SystemInfo["Harddisk"] = len(self.hdd) > 0
+
+                               if (not removable or medium_found) and not self.is_hard_mounted(device):
+                                       # device is the device name, without /dev
+                                       # physdev is the physical device path, which we (might) use to determine the userfriendly name
+                                       description = self.getUserfriendlyDeviceName(device, physdev)
+                                       p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device)
+                                       self.partitions.append(p)
+                                       self.on_partition_list_change("add", p)
 
 
-               # see if this is a harddrive
-               l = len(device)
-               if l and not device[l-1].isdigit():
-                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
-                       if not blacklisted and not removable and not is_cdrom and medium_found:
-                               self.hdd.append(Harddisk(device))
-                               self.hdd.sort()
-                               SystemInfo["Harddisk"] = len(self.hdd) > 0
+               return error, blacklisted, removable, is_cdrom, partitions, medium_found
 
        def removeHotplugPartition(self, device):
                mountpoint = self.getAutofsMountpoint(device)
 
        def removeHotplugPartition(self, device):
                mountpoint = self.getAutofsMountpoint(device)
@@ -608,15 +636,23 @@ class HarddiskManager:
        def getUserfriendlyDeviceName(self, dev, phys):
                dev, part = self.splitDeviceName(dev)
                description = "External Storage %s" % dev
        def getUserfriendlyDeviceName(self, dev, phys):
                dev, part = self.splitDeviceName(dev)
                description = "External Storage %s" % dev
+               have_model_descr = False
                try:
                        description = readFile("/sys" + phys + "/model")
                try:
                        description = readFile("/sys" + phys + "/model")
+                       have_model_descr = True
                except IOError, s:
                        print "couldn't read model: ", s
                from Tools.HardwareInfo import HardwareInfo
                except IOError, s:
                        print "couldn't read model: ", s
                from Tools.HardwareInfo import HardwareInfo
-               for physdevprefix, pdescription in DEVICEDB.get(HardwareInfo().device_name,{}).items():
+               if dev.find('sr') == 0 and dev[2].isdigit():
+                       devicedb = DEVICEDB_SR
+               else:
+                       devicedb = DEVICEDB
+               for physdevprefix, pdescription in devicedb.get(HardwareInfo().device_name,{}).items():
                        if phys.startswith(physdevprefix):
                        if phys.startswith(physdevprefix):
-                               description = pdescription
-
+                               if have_model_descr:
+                                       description = pdescription + ' - ' + description
+                               else:
+                                       description = pdescription
                # not wholedisk and not partition 1
                if part and part != 1:
                        description += " (Partition %d)" % part
                # not wholedisk and not partition 1
                if part and part != 1:
                        description += " (Partition %d)" % part
index b19007c..1f379f1 100644 (file)
 from Plugins.Plugin import PluginDescriptor
 from Plugins.Plugin import PluginDescriptor
-from twisted.internet.protocol import Protocol, Factory
-from twisted.internet import reactor
 from Components.Harddisk import harddiskmanager
 from Components.Harddisk import harddiskmanager
+from Tools.Directories import fileExists
 
 hotplugNotifier = [ ]
 
 hotplugNotifier = [ ]
+bdpoll = None
 
 
-class Hotplug(Protocol):
-       def connectionMade(self):
-               self.received = ""
+def processHotplugData(self, v):
+       print "hotplug:", v
+       action = v.get("ACTION")
+       device = v.get("DEVPATH")
+       physdevpath = v.get("PHYSDEVPATH")
+       media_state = v.get("X_E2_MEDIA_STATUS")
 
 
-       def dataReceived(self, data):
-               self.received += data
+       dev = device.split('/')[-1]
 
 
-       def connectionLost(self, reason):
-               data = self.received.split('\0')[:-1]
+       if action is not None and action == "add":
+               error, blacklisted, removable, is_cdrom, partitions, medium_found = harddiskmanager.addHotplugPartition(dev, physdevpath)
+               if bdpoll and removable or is_cdrom:
+                       bdpoll.addDevice(dev, is_cdrom, medium_found)
+       elif action is not None and action == "remove":
+               if bdpoll:
+                       bdpoll.removeDevice(dev)
+               harddiskmanager.removeHotplugPartition(dev)
+       elif media_state is not None:
+               if media_state == '1':
+                       harddiskmanager.removeHotplugPartition(dev)
+                       harddiskmanager.addHotplugPartition(dev, physdevpath)
+               elif media_state == '0':
+                       harddiskmanager.removeHotplugPartition(dev)
 
 
-               v = {}
+       for callback in hotplugNotifier:
+               try:
+                       callback(dev, action or media_state)
+               except AttributeError:
+                       hotplugNotifier.remove(callback)
 
 
-               for x in data:
-                       i = x.find('=')
-                       var, val = x[:i], x[i+1:]
-                       v[var] = val
+CDROM_DRIVE_STATUS = 0x5326
+CDROM_MEDIA_CHANGED = 0x5325
+CDSL_CURRENT = ((int)(~0>>1))
+CDS_NO_INFO = 0
+CDS_NO_DISC = 1
+CDS_TRAY_OPEN = 2
+CDS_DRIVE_NOT_READY = 3
+CDS_DISC_OK = 4
+ENOMEDIUM = 159
+IOC_NRBITS = 8
+IOC_NRSHIFT = 0
+IOC_TYPESHIFT = (IOC_NRSHIFT+IOC_NRBITS)
+BLKRRPART = ((0x12<<IOC_TYPESHIFT) | (95<<IOC_NRSHIFT))
 
 
-               print "hotplug:", v
+def autostart(reason, **kwargs):
+       if reason == 0:
+               print "starting hotplug handler"
 
 
-               action = v.get("ACTION")
-               device = v.get("DEVPATH")
-               physdevpath = v.get("PHYSDEVPATH")
-               media_state = v.get("X_E2_MEDIA_STATUS")
+               if fileExists('/dev/.udev'):
+                       global netlink
+                       global bdpoll
+                       from enigma import eSocketNotifier, eTimer, ePythonMessagePump
+                       import socket
+                       from select import POLLIN, POLLPRI
 
 
-               dev = device.split('/')[-1]
+                       class Netlink:
+                               def __init__(self):
+                                       self.netlink = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, 15)
+                                       self.netlink.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
+                                       self.netlink.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
+                                       self.netlink.bind((0, 1))
+                                       self.sn = eSocketNotifier(self.netlink.fileno(), POLLIN|POLLPRI)
+                                       self.sn.callback.append(self.dataAvail)
 
 
-               if action is not None and action == "add":
-                       harddiskmanager.addHotplugPartition(dev, physdevpath)
-               elif action is not None and action == "remove":
-                       harddiskmanager.removeHotplugPartition(dev)
-               elif media_state is not None:
-                       if media_state == '1':
-                               harddiskmanager.removeHotplugPartition(dev)
-                               harddiskmanager.addHotplugPartition(dev, physdevpath)
-                       elif media_state == '0':
-                               harddiskmanager.removeHotplugPartition(dev)
-               
-               for callback in hotplugNotifier:
-                       try:
-                               callback(dev, action or media_state)
-                       except AttributeError:
-                               hotplugNotifier.remove(callback)
+                               def dataAvail(self, what):
+                                       received = self.netlink.recvfrom(16384)
+#                                      print "HOTPLUG(%d):" %(what), received
 
 
-def autostart(reason, **kwargs):
-       if reason == 0:
-               print "starting hotplug handler"
-               factory = Factory()
-               factory.protocol = Hotplug
+                                       data = received[0].split('\0')[:-1]
+                                       v = {}
+
+                                       for x in data:
+                                               i = x.find('=')
+                                               var, val = x[:i], x[i+1:]
+                                               v[var] = val
+
+                                       if v['SUBSYSTEM'] == 'block' and v['ACTION'] in ('add', 'remove'):
+                                               processHotplugData(self, v)
+
+                       from threading import Thread, Semaphore, Lock
+
+                       class ThreadQueue:
+                               def __init__(self):
+                                       self.__list = [ ]
+                                       self.__lock = Lock()
+
+                               def push(self, val):
+                                       list = self.__list
+                                       lock = self.__lock
+                                       lock.acquire()
+                                       list.append(val)
+                                       lock.release()
+
+                               def pop(self):
+                                       list = self.__list
+                                       lock = self.__lock
+                                       lock.acquire()
+                                       ret = list[0]
+                                       del list[0]
+                                       lock.release()
+                                       return ret
 
 
-               try:
                        import os
                        import os
-                       os.remove("/tmp/hotplug.socket")
-               except OSError:
-                       pass
+                       import errno
+                       import fcntl
+
+                       class BDPoll(Thread):
+                               CHECK_INTERVAL = 2000
+                               MSG_MEDIUM_REMOVED = 1
+                               MSG_MEDIUM_INSERTED = 2
+                               MSG_POLL_FINISHED = 4
+                               def __init__(self):
+                                       Thread.__init__(self)
+                                       self.__sema = Semaphore(0)
+                                       self.__lock = Lock()
+                                       self.running = False
+                                       self.devices_to_poll = { }
+                                       self.messages = ThreadQueue()
+                                       self.checkTimer = eTimer()
+                                       self.checkTimer.callback.append(self.timeout)
+                                       self.checkTimer.start(BDPoll.CHECK_INTERVAL, True)
+                                       self.mp = ePythonMessagePump()
+                                       self.mp.recv_msg.get().append(self.gotThreadMsg)
+                                       self.start()
+
+                               def gotThreadMsg(self, msg):
+                                       msg = self.messages.pop()
+                                       if msg[0] == BDPoll.MSG_MEDIUM_REMOVED:
+                                               print "MSG_MEDIUM_REMOVED"
+                                               harddiskmanager.removeHotplugPartition(msg[1])
+                                       elif msg[0] == BDPoll.MSG_MEDIUM_INSERTED:
+                                               print "MSG_MEDIUM_INSERTED"
+                                               harddiskmanager.addHotplugPartition(msg[1])
+                                       elif msg[0] == BDPoll.MSG_POLL_FINISHED:
+                                               self.checkTimer.start(BDPoll.CHECK_INTERVAL, True)
+
+                               def timeout(self):
+                                       self.__sema.release() # start bdpoll loop in thread
+
+                               def is_mounted(self, dev):
+                                       mounts = file('/proc/mounts').read()
+                                       return mounts.find(dev) != -1
+
+                               def run(self):
+                                       sema = self.__sema
+                                       lock = self.__lock
+                                       messages = self.messages
+                                       mp = self.mp
+                                       self.running = True
+                                       while self.running:
+                                               sema.acquire()
+                                               self.__lock.acquire()
+                                               devices_to_poll = self.devices_to_poll.items()
+                                               self.__lock.release()
+                                               devices_to_poll_processed = [ ]
+                                               for device, state in devices_to_poll:
+                                                       got_media = False
+                                                       is_cdrom, prev_media_state = state
+                                                       if is_cdrom:
+                                                               try:
+                                                                       fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK | os.O_EXCL)
+                                                               except OSError, err:
+                                                                       if err.errno == errno.EBUSY:
+                                                                               print "open cdrom exclusive failed:",
+                                                                               if not self.is_mounted(device):
+                                                                                       print "not mounted"
+                                                                                       continue
+                                                                               try:
+                                                                                       print "mounted... try non exclusive"
+                                                                                       fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK)
+                                                                               except OSError, err:
+                                                                                       print "open cdrom not exclusive failed", os.strerror(err.errno)
+                                                                                       continue
+                                                               #here the fs must be valid!
+                                                               try:
+                                                                       ret = fcntl.ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)
+                                                               except IOError, err:
+                                                                       print "ioctl CDROM_DRIVE_STATUS failed", os.strerror(err.errno)
+                                                               else:
+                                                                       if ret in (CDS_NO_INFO, CDS_NO_DISC, CDS_TRAY_OPEN, CDS_DRIVE_NOT_READY):
+                                                                               pass
+                                                                       elif ret == CDS_DISC_OK:
+                                                                               #todo new kernels support events to userspace event on media change
+                                                                               #but not 2.6.18.... see hotplug-ng bdpoll.c
+                                                                               got_media = True
+                                                               os.close(fd)
+                                                       else:
+                                                               try:
+                                                                       fd = os.open("/dev/" + device, os.O_RDONLY)
+                                                               except OSError, err:
+                                                                       if err.errno == ENOMEDIUM:
+                                                                               pass
+                                                                       else:
+                                                                               print "open non cdrom failed", os.strerror(err.errno)
+                                                                               continue
+                                                               else:
+                                                                       got_media = True
+                                                                       os.close(fd)
+                                                       if prev_media_state:
+                                                               if not got_media:
+                                                                       print "media removal detected on", device
+                                                                       try:
+                                                                               fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK)
+                                                                       except OSError, err:
+                                                                               print "open device for blkrrpart ioctl failed", os.strerror(err.errno)
+                                                                       else:
+                                                                               try:
+                                                                                       fcntl.ioctl(fd, BLKRRPART)
+                                                                               except IOError, err:
+                                                                                       print "ioctl BLKRRPART failed", os.strerror(err.errno)
+                                                                               os.close(fd)
+                                                       else:
+                                                               if got_media:
+                                                                       print "media insertion detected on", device
+                                                       devices_to_poll_processed.append((device, is_cdrom, got_media))
+                                               self.__lock.acquire()
+                                               for device, is_cdrom, state in devices_to_poll_processed:
+                                                       old_state = self.devices_to_poll.get(device)
+                                                       if old_state is not None and old_state[1] != state:
+                                                               msg = state and BDPoll.MSG_MEDIUM_INSERTED or BDPoll.MSG_MEDIUM_REMOVED
+                                                               self.devices_to_poll[device] = (is_cdrom, state)
+                                                               messages.push((msg, device))
+                                                               mp.send(0)
+
+                                               self.__lock.release()
+                                               messages.push((self.MSG_POLL_FINISHED,))
+                                               mp.send(0)
+
+                               def addDevice(self, device, is_cdrom, inserted):
+                                       self.__lock.acquire()
+                                       if device in self.devices_to_poll:
+                                               print "device", device, "already in bdpoll"
+                                       else:
+                                               print "add device", device, "to bdpoll current state:",
+                                               if inserted:
+                                                       print "medium inserted"
+                                               else:
+                                                       print "medium removed"
+                                               self.devices_to_poll[device] = (is_cdrom, inserted)
+                                       self.__lock.release()
+
+                               def removeDevice(self, device):
+                                       self.__lock.acquire()
+                                       if device in self.devices_to_poll:
+                                               print "device", device, "removed from bdpoll"
+                                               del self.devices_to_poll[device]
+                                       else:
+                                               print "try to del not exist device", device, "from bdpoll"
+                                       self.__lock.release()
+
+                       netlink = Netlink()
+                       bdpoll = BDPoll()
+                       for blockdev, removable, is_cdrom, medium_found in harddiskmanager.devices_scanned_on_init:
+                               if removable or is_cdrom:
+                                       bdpoll.addDevice(blockdev, is_cdrom, medium_found)
+               else:
+                       from twisted.internet.protocol import Protocol, Factory
+                       from twisted.internet import reactor
+
+                       try:
+                               import os
+                               os.remove("/tmp/hotplug.socket")
+                       except OSError:
+                               pass
+
+                       class Hotplug(Protocol):
+                               def connectionMade(self):
+                                       print "HOTPLUG connection!"
+                                       self.received = ""
+
+                               def dataReceived(self, data):
+                                       print "hotplug:", data
+                                       self.received += data
+                                       print "complete", self.received
+
+                               def connectionLost(self, reason):
+                                       print "HOTPLUG connection lost!"
+                                       data = self.received.split('\0')[:-1]
+                                       v = {}
+
+                                       for x in data:
+                                               i = x.find('=')
+                                               var, val = x[:i], x[i+1:]
+                                               v[var] = val
+
+                                       processHotplugData(self, v)
 
 
-               reactor.listenUNIX("/tmp/hotplug.socket", factory)
+                       factory = Factory()
+                       factory.protocol = Hotplug
+                       reactor.listenUNIX("/tmp/hotplug.socket", factory)
 
 def Plugins(**kwargs):
        return PluginDescriptor(name = "Hotplug", description = "listens to hotplug events", where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)
 
 def Plugins(**kwargs):
        return PluginDescriptor(name = "Hotplug", description = "listens to hotplug events", where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)