Fix dolby patch
[vuplus_openembedded] / recipes / enigma2 / enigma2 / new-hotplug.patch
1 --- a/lib/python/Components/Harddisk.py
2 +++ b/lib/python/Components/Harddisk.py
3 @@ -11,17 +11,17 @@ def readFile(filename):
4         file.close()
5         return data
6  
7 -class Harddisk:
8 -       DEVTYPE_UDEV = 0
9 -       DEVTYPE_DEVFS = 1
10 +DEVTYPE_UDEV = 0
11 +DEVTYPE_DEVFS = 1
12  
13 +class Harddisk:
14         def __init__(self, device):
15                 self.device = device
16  
17                 if access("/dev/.udev", 0):
18 -                       self.type = self.DEVTYPE_UDEV
19 +                       self.type = DEVTYPE_UDEV
20                 elif access("/dev/.devfsd", 0):
21 -                       self.type = self.DEVTYPE_DEVFS
22 +                       self.type = DEVTYPE_DEVFS
23                 else:
24                         print "Unable to determine structure of /dev"
25  
26 @@ -33,11 +33,11 @@ class Harddisk:
27                 self.disk_path = ''
28                 self.phys_path = path.realpath(self.sysfsPath('device'))
29  
30 -               if self.type == self.DEVTYPE_UDEV:
31 +               if self.type == DEVTYPE_UDEV:
32                         self.dev_path = '/dev/' + self.device
33                         self.disk_path = self.dev_path
34  
35 -               elif self.type == self.DEVTYPE_DEVFS:
36 +               elif self.type == DEVTYPE_DEVFS:
37                         tmp = readFile(self.sysfsPath('dev')).split(':')
38                         s_major = int(tmp[0])
39                         s_minor = int(tmp[1])
40 @@ -60,9 +60,9 @@ class Harddisk:
41                 return self.device < ob.device
42  
43         def partitionPath(self, n):
44 -               if self.type == self.DEVTYPE_UDEV:
45 +               if self.type == DEVTYPE_UDEV:
46                         return self.dev_path + n
47 -               elif self.type == self.DEVTYPE_DEVFS:
48 +               elif self.type == DEVTYPE_DEVFS:
49                         return self.dev_path + '/part' + n
50  
51         def sysfsPath(self, filename):
52 @@ -75,9 +75,9 @@ class Harddisk:
53  
54         def bus(self):
55                 # CF (7025 specific)
56 -               if self.type == self.DEVTYPE_UDEV:
57 +               if self.type == DEVTYPE_UDEV:
58                         ide_cf = False  # FIXME
59 -               elif self.type == self.DEVTYPE_DEVFS:
60 +               elif self.type == DEVTYPE_DEVFS:
61                         ide_cf = self.device[:2] == "hd" and "host0" not in self.dev_path
62  
63                 internal = "pci" in self.phys_path
64 @@ -136,7 +136,7 @@ class Harddisk:
65  
66         def numPartitions(self):
67                 numPart = -1
68 -               if self.type == self.DEVTYPE_UDEV:
69 +               if self.type == DEVTYPE_UDEV:
70                         try:
71                                 devdir = listdir('/dev')
72                         except OSError:
73 @@ -145,7 +145,7 @@ class Harddisk:
74                                 if filename.startswith(self.device):
75                                         numPart += 1
76  
77 -               elif self.type == self.DEVTYPE_DEVFS:
78 +               elif self.type == DEVTYPE_DEVFS:
79                         try:
80                                 idedir = listdir(self.dev_path)
81                         except OSError:
82 @@ -394,24 +394,38 @@ class Partition:
83                                 return True
84                 return False
85  
86 -DEVICEDB =  \
87 +DEVICEDB_SR = \
88         {"dm8000":
89                 {
90 -                       # dm8000:
91 -                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": "Front USB Slot",
92 -                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": "Back, upper USB Slot",
93 -                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": "Back, lower USB Slot",
94 -                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host1/target1:0:0/1:0:0:0": "DVD Drive",
95 +                       "/devices/pci0000:01/0000:01:00.0/host0/target0:0:0/0:0:0:0": _("DVD Drive"),
96 +                       "/devices/pci0000:01/0000:01:00.0/host1/target1:0:0/1:0:0:0": _("DVD Drive"),
97 +                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host3/target3:0:0/3:0:0:0": _("DVD Drive"),
98 +               },
99 +       "dm800":
100 +       {
101 +       },
102 +       "dm7025":
103 +       {
104 +       }
105 +       }
106 +
107 +DEVICEDB = \
108 +       {"dm8000":
109 +               {
110 +                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": _("Front USB Slot"),
111 +                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": _("Back, upper USB Slot"),
112 +                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": _("Back, lower USB Slot"),
113 +                       "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": _("Front USB Slot"),
114 +                       "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/": _("Internal USB Slot"),
115 +                       "/devices/platform/brcm-ohci-1.1/usb4/4-1/4-1:1.0/": _("Internal USB Slot"),
116                 },
117         "dm800":
118         {
119 -               # dm800:
120                 "/devices/platform/brcm-ehci.0/usb1/1-2/1-2:1.0": "Upper USB Slot",
121                 "/devices/platform/brcm-ehci.0/usb1/1-1/1-1:1.0": "Lower USB Slot",
122         },
123         "dm7025":
124         {
125 -               # dm7025:
126                 "/devices/pci0000:00/0000:00:14.1/ide1/1.0": "CF Card Slot", #hdc
127                 "/devices/pci0000:00/0000:00:14.1/ide0/0.0": "Internal Harddisk"
128         }
129 @@ -422,6 +436,7 @@ class HarddiskManager:
130                 self.hdd = [ ]
131                 self.cd = ""
132                 self.partitions = [ ]
133 +               self.devices_scanned_on_init = [ ]
134  
135                 self.on_partition_list_change = CList()
136  
137 @@ -489,24 +504,23 @@ class HarddiskManager:
138         def enumerateBlockDevices(self):
139                 print "enumerating block devices..."
140                 for blockdev in listdir("/sys/block"):
141 -                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(blockdev)
142 -                       print "found block device '%s':" % blockdev, 
143 -                       if error:
144 -                               print "error querying properties"
145 -                       elif blacklisted:
146 -                               print "blacklisted"
147 -                       elif not medium_found:
148 -                               print "no medium"
149 -                       else:
150 -                               print "ok, removable=%s, cdrom=%s, partitions=%s, device=%s" % (removable, is_cdrom, partitions, blockdev)
151 -
152 -                               self.addHotplugPartition(blockdev)
153 -                               for part in partitions:
154 -                                       self.addHotplugPartition(part)
155 +                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.addHotplugPartition(blockdev)
156 +                       if not error and not blacklisted:
157 +                               if medium_found:
158 +                                       for part in partitions:
159 +                                               self.addHotplugPartition(part)
160 +                               self.devices_scanned_on_init.append((blockdev, removable, is_cdrom, medium_found))
161  
162         def getAutofsMountpoint(self, device):
163                 return "/autofs/%s/" % (device)
164  
165 +       def is_hard_mounted(self, device):
166 +               mounts = file('/proc/mounts').read().split('\n')
167 +               for x in mounts:
168 +                       if x.find('/autofs') == -1 and x.find(device) != -1:
169 +                               return True
170 +               return False
171 +
172         def addHotplugPartition(self, device, physdev = None):
173                 if not physdev:
174                         dev, part = self.splitDeviceName(device)
175 @@ -516,22 +530,36 @@ class HarddiskManager:
176                                 physdev = dev
177                                 print "couldn't determine blockdev physdev for device", device
178  
179 -               # device is the device name, without /dev
180 -               # physdev is the physical device path, which we (might) use to determine the userfriendly name
181 -               description = self.getUserfriendlyDeviceName(device, physdev)
182 +               error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
183 +               print "found block device '%s':" % device,
184  
185 -               p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device)
186 -               self.partitions.append(p)
187 -               self.on_partition_list_change("add", p)
188 +               if blacklisted:
189 +                       print "blacklisted"
190 +               else:
191 +                       if error:
192 +                               print "error querying properties"
193 +                       elif not medium_found:
194 +                               print "no medium"
195 +                       else:
196 +                               print "ok, removable=%s, cdrom=%s, partitions=%s" % (removable, is_cdrom, partitions)
197 +
198 +                       l = len(device)
199 +                       if l:
200 +                               # see if this is a harddrive
201 +                               if not device[l-1].isdigit() and not removable and not is_cdrom:
202 +                                       self.hdd.append(Harddisk(device))
203 +                                       self.hdd.sort()
204 +                                       SystemInfo["Harddisk"] = len(self.hdd) > 0
205 +
206 +                               if (not removable or medium_found) and not self.is_hard_mounted(device):
207 +                                       # device is the device name, without /dev
208 +                                       # physdev is the physical device path, which we (might) use to determine the userfriendly name
209 +                                       description = self.getUserfriendlyDeviceName(device, physdev)
210 +                                       p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True, device = device)
211 +                                       self.partitions.append(p)
212 +                                       self.on_partition_list_change("add", p)
213  
214 -               # see if this is a harddrive
215 -               l = len(device)
216 -               if l and not device[l-1].isdigit():
217 -                       error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
218 -                       if not blacklisted and not removable and not is_cdrom and medium_found:
219 -                               self.hdd.append(Harddisk(device))
220 -                               self.hdd.sort()
221 -                               SystemInfo["Harddisk"] = len(self.hdd) > 0
222 +               return error, blacklisted, removable, is_cdrom, partitions, medium_found
223  
224         def removeHotplugPartition(self, device):
225                 mountpoint = self.getAutofsMountpoint(device)
226 @@ -589,15 +617,23 @@ class HarddiskManager:
227         def getUserfriendlyDeviceName(self, dev, phys):
228                 dev, part = self.splitDeviceName(dev)
229                 description = "External Storage %s" % dev
230 +               have_model_descr = False
231                 try:
232                         description = readFile("/sys" + phys + "/model")
233 +                       have_model_descr = True
234                 except IOError, s:
235                         print "couldn't read model: ", s
236                 from Tools.HardwareInfo import HardwareInfo
237 -               for physdevprefix, pdescription in DEVICEDB.get(HardwareInfo().device_name,{}).items():
238 +               if dev.find('sr') == 0 and dev[2].isdigit():
239 +                       devicedb = DEVICEDB_SR
240 +               else:
241 +                       devicedb = DEVICEDB
242 +               for physdevprefix, pdescription in devicedb.get(HardwareInfo().device_name,{}).items():
243                         if phys.startswith(physdevprefix):
244 -                               description = pdescription
245 -
246 +                               if have_model_descr:
247 +                                       description = pdescription + ' - ' + description
248 +                               else:
249 +                                       description = pdescription
250                 # not wholedisk and not partition 1
251                 if part and part != 1:
252                         description += " (Partition %d)" % part
253 --- a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py
254 +++ b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py
255 @@ -1,66 +1,300 @@
256  from Plugins.Plugin import PluginDescriptor
257 -from twisted.internet.protocol import Protocol, Factory
258 -from twisted.internet import reactor
259  from Components.Harddisk import harddiskmanager
260 +from Tools.Directories import fileExists
261  
262  hotplugNotifier = [ ]
263 +bdpoll = None
264  
265 -class Hotplug(Protocol):
266 -       def connectionMade(self):
267 -               self.received = ""
268 +def processHotplugData(self, v):
269 +       print "hotplug:", v
270 +       action = v.get("ACTION")
271 +       device = v.get("DEVPATH")
272 +       physdevpath = v.get("PHYSDEVPATH")
273 +       media_state = v.get("X_E2_MEDIA_STATUS")
274  
275 -       def dataReceived(self, data):
276 -               self.received += data
277 +       dev = device.split('/')[-1]
278  
279 -       def connectionLost(self, reason):
280 -               data = self.received.split('\0')[:-1]
281 +       if action is not None and action == "add":
282 +               error, blacklisted, removable, is_cdrom, partitions, medium_found = harddiskmanager.addHotplugPartition(dev, physdevpath)
283 +               if bdpoll and removable or is_cdrom:
284 +                       bdpoll.addDevice(dev, is_cdrom, medium_found)
285 +       elif action is not None and action == "remove":
286 +               if bdpoll:
287 +                       bdpoll.removeDevice(dev)
288 +               harddiskmanager.removeHotplugPartition(dev)
289 +       elif media_state is not None:
290 +               if media_state == '1':
291 +                       harddiskmanager.removeHotplugPartition(dev)
292 +                       harddiskmanager.addHotplugPartition(dev, physdevpath)
293 +               elif media_state == '0':
294 +                       harddiskmanager.removeHotplugPartition(dev)
295  
296 -               v = {}
297 +       for callback in hotplugNotifier:
298 +               try:
299 +                       callback(dev, action or media_state)
300 +               except AttributeError:
301 +                       hotplugNotifier.remove(callback)
302  
303 -               for x in data:
304 -                       i = x.find('=')
305 -                       var, val = x[:i], x[i+1:]
306 -                       v[var] = val
307 +CDROM_DRIVE_STATUS = 0x5326
308 +CDROM_MEDIA_CHANGED = 0x5325
309 +CDSL_CURRENT = ((int)(~0>>1))
310 +CDS_NO_INFO = 0
311 +CDS_NO_DISC = 1
312 +CDS_TRAY_OPEN = 2
313 +CDS_DRIVE_NOT_READY = 3
314 +CDS_DISC_OK = 4
315 +ENOMEDIUM = 159
316 +IOC_NRBITS = 8
317 +IOC_NRSHIFT = 0
318 +IOC_TYPESHIFT = (IOC_NRSHIFT+IOC_NRBITS)
319 +BLKRRPART = ((0x12<<IOC_TYPESHIFT) | (95<<IOC_NRSHIFT))
320  
321 -               print "hotplug:", v
322 +def autostart(reason, **kwargs):
323 +       if reason == 0:
324 +               print "starting hotplug handler"
325  
326 -               action = v.get("ACTION")
327 -               device = v.get("DEVPATH")
328 -               physdevpath = v.get("PHYSDEVPATH")
329 -               media_state = v.get("X_E2_MEDIA_STATUS")
330 +               if fileExists('/dev/.udev'):
331 +                       global netlink
332 +                       global bdpoll
333 +                       from enigma import eSocketNotifier, eTimer, ePythonMessagePump
334 +                       import socket
335 +                       from select import POLLIN, POLLPRI
336  
337 -               dev = device.split('/')[-1]
338 +                       class Netlink:
339 +                               def __init__(self):
340 +                                       self.netlink = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, 15)
341 +                                       self.netlink.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
342 +                                       self.netlink.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
343 +                                       self.netlink.bind((0, 1))
344 +                                       self.sn = eSocketNotifier(self.netlink.fileno(), POLLIN|POLLPRI)
345 +                                       self.sn.callback.append(self.dataAvail)
346  
347 -               if action is not None and action == "add":
348 -                       harddiskmanager.addHotplugPartition(dev, physdevpath)
349 -               elif action is not None and action == "remove":
350 -                       harddiskmanager.removeHotplugPartition(dev)
351 -               elif media_state is not None:
352 -                       if media_state == '1':
353 -                               harddiskmanager.removeHotplugPartition(dev)
354 -                               harddiskmanager.addHotplugPartition(dev, physdevpath)
355 -                       elif media_state == '0':
356 -                               harddiskmanager.removeHotplugPartition(dev)
357 -               
358 -               for callback in hotplugNotifier:
359 -                       try:
360 -                               callback(dev, action or media_state)
361 -                       except AttributeError:
362 -                               hotplugNotifier.remove(callback)
363 +                               def dataAvail(self, what):
364 +                                       received = self.netlink.recvfrom(16384)
365 +#                                      print "HOTPLUG(%d):" %(what), received
366  
367 -def autostart(reason, **kwargs):
368 -       if reason == 0:
369 -               print "starting hotplug handler"
370 -               factory = Factory()
371 -               factory.protocol = Hotplug
372 +                                       data = received[0].split('\0')[:-1]
373 +                                       v = {}
374 +
375 +                                       for x in data:
376 +                                               i = x.find('=')
377 +                                               var, val = x[:i], x[i+1:]
378 +                                               v[var] = val
379 +
380 +                                       if v['SUBSYSTEM'] == 'block' and v['ACTION'] in ('add', 'remove'):
381 +                                               processHotplugData(self, v)
382 +
383 +                       from threading import Thread, Semaphore, Lock
384 +
385 +                       class ThreadQueue:
386 +                               def __init__(self):
387 +                                       self.__list = [ ]
388 +                                       self.__lock = Lock()
389 +
390 +                               def push(self, val):
391 +                                       list = self.__list
392 +                                       lock = self.__lock
393 +                                       lock.acquire()
394 +                                       list.append(val)
395 +                                       lock.release()
396 +
397 +                               def pop(self):
398 +                                       list = self.__list
399 +                                       lock = self.__lock
400 +                                       lock.acquire()
401 +                                       ret = list[0]
402 +                                       del list[0]
403 +                                       lock.release()
404 +                                       return ret
405  
406 -               try:
407                         import os
408 -                       os.remove("/tmp/hotplug.socket")
409 -               except OSError:
410 -                       pass
411 +                       import errno
412 +                       import fcntl
413 +
414 +                       class BDPoll(Thread):
415 +                               CHECK_INTERVAL = 2000
416 +                               MSG_MEDIUM_REMOVED = 1
417 +                               MSG_MEDIUM_INSERTED = 2
418 +                               MSG_POLL_FINISHED = 4
419 +                               def __init__(self):
420 +                                       Thread.__init__(self)
421 +                                       self.__sema = Semaphore(0)
422 +                                       self.__lock = Lock()
423 +                                       self.running = False
424 +                                       self.devices_to_poll = { }
425 +                                       self.messages = ThreadQueue()
426 +                                       self.checkTimer = eTimer()
427 +                                       self.checkTimer.callback.append(self.timeout)
428 +                                       self.checkTimer.start(BDPoll.CHECK_INTERVAL, True)
429 +                                       self.mp = ePythonMessagePump()
430 +                                       self.mp.recv_msg.get().append(self.gotThreadMsg)
431 +                                       self.start()
432 +
433 +                               def gotThreadMsg(self, msg):
434 +                                       msg = self.messages.pop()
435 +                                       if msg[0] == BDPoll.MSG_MEDIUM_REMOVED:
436 +                                               print "MSG_MEDIUM_REMOVED"
437 +                                               harddiskmanager.removeHotplugPartition(msg[1])
438 +                                       elif msg[0] == BDPoll.MSG_MEDIUM_INSERTED:
439 +                                               print "MSG_MEDIUM_INSERTED"
440 +                                               harddiskmanager.addHotplugPartition(msg[1])
441 +                                       elif msg[0] == BDPoll.MSG_POLL_FINISHED:
442 +                                               self.checkTimer.start(BDPoll.CHECK_INTERVAL, True)
443 +
444 +                               def timeout(self):
445 +                                       self.__sema.release() # start bdpoll loop in thread
446 +
447 +                               def is_mounted(self, dev):
448 +                                       mounts = file('/proc/mounts').read()
449 +                                       return mounts.find(dev) != -1
450 +
451 +                               def run(self):
452 +                                       sema = self.__sema
453 +                                       lock = self.__lock
454 +                                       messages = self.messages
455 +                                       mp = self.mp
456 +                                       self.running = True
457 +                                       while self.running:
458 +                                               sema.acquire()
459 +                                               self.__lock.acquire()
460 +                                               devices_to_poll = self.devices_to_poll.items()
461 +                                               self.__lock.release()
462 +                                               devices_to_poll_processed = [ ]
463 +                                               for device, state in devices_to_poll:
464 +                                                       got_media = False
465 +                                                       is_cdrom, prev_media_state = state
466 +                                                       if is_cdrom:
467 +                                                               try:
468 +                                                                       fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK | os.O_EXCL)
469 +                                                               except OSError, err:
470 +                                                                       if err.errno == errno.EBUSY:
471 +                                                                               print "open cdrom exclusive failed:",
472 +                                                                               if not self.is_mounted(device):
473 +                                                                                       print "not mounted"
474 +                                                                                       continue
475 +                                                                               try:
476 +                                                                                       print "mounted... try non exclusive"
477 +                                                                                       fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK)
478 +                                                                               except OSError, err:
479 +                                                                                       print "open cdrom not exclusive failed", os.strerror(err.errno)
480 +                                                                                       continue
481 +                                                               #here the fs must be valid!
482 +                                                               try:
483 +                                                                       ret = fcntl.ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)
484 +                                                               except IOError, err:
485 +                                                                       print "ioctl CDROM_DRIVE_STATUS failed", os.strerror(err.errno)
486 +                                                               else:
487 +                                                                       if ret in (CDS_NO_INFO, CDS_NO_DISC, CDS_TRAY_OPEN, CDS_DRIVE_NOT_READY):
488 +                                                                               pass
489 +                                                                       elif ret == CDS_DISC_OK:
490 +                                                                               #todo new kernels support events to userspace event on media change
491 +                                                                               #but not 2.6.18.... see hotplug-ng bdpoll.c
492 +                                                                               got_media = True
493 +                                                               os.close(fd)
494 +                                                       else:
495 +                                                               try:
496 +                                                                       fd = os.open("/dev/" + device, os.O_RDONLY)
497 +                                                               except OSError, err:
498 +                                                                       if err.errno == ENOMEDIUM:
499 +                                                                               pass
500 +                                                                       else:
501 +                                                                               print "open non cdrom failed", os.strerror(err.errno)
502 +                                                                               continue
503 +                                                               else:
504 +                                                                       got_media = True
505 +                                                                       os.close(fd)
506 +                                                       if prev_media_state:
507 +                                                               if not got_media:
508 +                                                                       print "media removal detected on", device
509 +                                                                       try:
510 +                                                                               fd = os.open("/dev/" + device, os.O_RDONLY | os.O_NONBLOCK)
511 +                                                                       except OSError, err:
512 +                                                                               print "open device for blkrrpart ioctl failed", os.strerror(err.errno)
513 +                                                                       else:
514 +                                                                               try:
515 +                                                                                       fcntl.ioctl(fd, BLKRRPART)
516 +                                                                               except IOError, err:
517 +                                                                                       print "ioctl BLKRRPART failed", os.strerror(err.errno)
518 +                                                                               os.close(fd)
519 +                                                       else:
520 +                                                               if got_media:
521 +                                                                       print "media insertion detected on", device
522 +                                                       devices_to_poll_processed.append((device, is_cdrom, got_media))
523 +                                               self.__lock.acquire()
524 +                                               for device, is_cdrom, state in devices_to_poll_processed:
525 +                                                       old_state = self.devices_to_poll.get(device)
526 +                                                       if old_state is not None and old_state[1] != state:
527 +                                                               msg = state and BDPoll.MSG_MEDIUM_INSERTED or BDPoll.MSG_MEDIUM_REMOVED
528 +                                                               self.devices_to_poll[device] = (is_cdrom, state)
529 +                                                               messages.push((msg, device))
530 +                                                               mp.send(0)
531 +
532 +                                               self.__lock.release()
533 +                                               messages.push((self.MSG_POLL_FINISHED,))
534 +                                               mp.send(0)
535 +
536 +                               def addDevice(self, device, is_cdrom, inserted):
537 +                                       self.__lock.acquire()
538 +                                       if device in self.devices_to_poll:
539 +                                               print "device", device, "already in bdpoll"
540 +                                       else:
541 +                                               print "add device", device, "to bdpoll current state:",
542 +                                               if inserted:
543 +                                                       print "medium inserted"
544 +                                               else:
545 +                                                       print "medium removed"
546 +                                               self.devices_to_poll[device] = (is_cdrom, inserted)
547 +                                       self.__lock.release()
548 +
549 +                               def removeDevice(self, device):
550 +                                       self.__lock.acquire()
551 +                                       if device in self.devices_to_poll:
552 +                                               print "device", device, "removed from bdpoll"
553 +                                               del self.devices_to_poll[device]
554 +                                       else:
555 +                                               print "try to del not exist device", device, "from bdpoll"
556 +                                       self.__lock.release()
557 +
558 +                       netlink = Netlink()
559 +                       bdpoll = BDPoll()
560 +                       for blockdev, removable, is_cdrom, medium_found in harddiskmanager.devices_scanned_on_init:
561 +                               if removable or is_cdrom:
562 +                                       bdpoll.addDevice(blockdev, is_cdrom, medium_found)
563 +               else:
564 +                       from twisted.internet.protocol import Protocol, Factory
565 +                       from twisted.internet import reactor
566 +
567 +                       try:
568 +                               import os
569 +                               os.remove("/tmp/hotplug.socket")
570 +                       except OSError:
571 +                               pass
572 +
573 +                       class Hotplug(Protocol):
574 +                               def connectionMade(self):
575 +                                       print "HOTPLUG connection!"
576 +                                       self.received = ""
577 +
578 +                               def dataReceived(self, data):
579 +                                       print "hotplug:", data
580 +                                       self.received += data
581 +                                       print "complete", self.received
582 +
583 +                               def connectionLost(self, reason):
584 +                                       print "HOTPLUG connection lost!"
585 +                                       data = self.received.split('\0')[:-1]
586 +                                       v = {}
587 +
588 +                                       for x in data:
589 +                                               i = x.find('=')
590 +                                               var, val = x[:i], x[i+1:]
591 +                                               v[var] = val
592 +
593 +                                       processHotplugData(self, v)
594  
595 -               reactor.listenUNIX("/tmp/hotplug.socket", factory)
596 +                       factory = Factory()
597 +                       factory.protocol = Hotplug
598 +                       reactor.listenUNIX("/tmp/hotplug.socket", factory)
599  
600  def Plugins(**kwargs):
601         return PluginDescriptor(name = "Hotplug", description = "listens to hotplug events", where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart)