Used Watch API for block devices
This commit is contained in:
		
							parent
							
								
									4d9b848895
								
							
						
					
					
						commit
						9470f69be8
					
				| @ -72,6 +72,8 @@ def umount_device(dev_mount_path): | |||||||
| def fill_devs_list(dialog): | def fill_devs_list(dialog): | ||||||
|     dialog.dev_combobox.clear() |     dialog.dev_combobox.clear() | ||||||
|     dialog.dev_combobox.addItem("None") |     dialog.dev_combobox.addItem("None") | ||||||
|  |      | ||||||
|  |     dialog.blk_manager.blk_lock.acquire() | ||||||
|     for a in dialog.blk_manager.attached_devs: |     for a in dialog.blk_manager.attached_devs: | ||||||
|         if dialog.blk_manager.attached_devs[a]['attached_to']['vm'] == dialog.vm.name : |         if dialog.blk_manager.attached_devs[a]['attached_to']['vm'] == dialog.vm.name : | ||||||
|             att = a + " " + unicode(dialog.blk_manager.attached_devs[a]['size']) + " " + dialog.blk_manager.attached_devs[a]['desc'] |             att = a + " " + unicode(dialog.blk_manager.attached_devs[a]['size']) + " " + dialog.blk_manager.attached_devs[a]['desc'] | ||||||
| @ -79,6 +81,8 @@ def fill_devs_list(dialog): | |||||||
|     for a in dialog.blk_manager.free_devs: |     for a in dialog.blk_manager.free_devs: | ||||||
|         att = a + " " + unicode(dialog.blk_manager.free_devs[a]['size']) + " " + dialog.blk_manager.free_devs[a]['desc'] |         att = a + " " + unicode(dialog.blk_manager.free_devs[a]['size']) + " " + dialog.blk_manager.free_devs[a]['desc'] | ||||||
|         dialog.dev_combobox.addItem(att, QVariant(a)) |         dialog.dev_combobox.addItem(att, QVariant(a)) | ||||||
|  |     dialog.blk_manager.blk_lock.release() | ||||||
|  | 
 | ||||||
|     dialog.dev_combobox.setCurrentIndex(0) #current selected is null "" |     dialog.dev_combobox.setCurrentIndex(0) #current selected is null "" | ||||||
|     dialog.prev_dev_idx = 0 |     dialog.prev_dev_idx = 0 | ||||||
|     dialog.dir_line_edit.clear() |     dialog.dir_line_edit.clear() | ||||||
| @ -107,6 +111,7 @@ def dev_combobox_activated(dialog, idx): | |||||||
|     if dialog.dev_combobox.currentText() != "None":   #An existing device chosen  |     if dialog.dev_combobox.currentText() != "None":   #An existing device chosen  | ||||||
|         dev_name = str(dialog.dev_combobox.itemData(idx).toString()) |         dev_name = str(dialog.dev_combobox.itemData(idx).toString()) | ||||||
| 
 | 
 | ||||||
|  |         dialog.blk_manager.blk_lock.acquire() | ||||||
|         if dev_name in dialog.blk_manager.free_devs: |         if dev_name in dialog.blk_manager.free_devs: | ||||||
|             if dev_name.startswith(dialog.vm.name):       # originally attached to dom0 |             if dev_name.startswith(dialog.vm.name):       # originally attached to dom0 | ||||||
|                 dev_path = "/dev/"+dev_name.split(":")[1] |                 dev_path = "/dev/"+dev_name.split(":")[1] | ||||||
| @ -118,6 +123,7 @@ def dev_combobox_activated(dialog, idx): | |||||||
|         if dev_name in dialog.blk_manager.attached_devs:       #is attached to dom0 |         if dev_name in dialog.blk_manager.attached_devs:       #is attached to dom0 | ||||||
|             assert dialog.blk_manager.attached_devs[dev_name]['attached_to']['vm'] == dialog.vm.name |             assert dialog.blk_manager.attached_devs[dev_name]['attached_to']['vm'] == dialog.vm.name | ||||||
|             dev_path = "/dev/" + dialog.blk_manager.attached_devs[dev_name]['attached_to']['frontend'] |             dev_path = "/dev/" + dialog.blk_manager.attached_devs[dev_name]['attached_to']['frontend'] | ||||||
|  |         dialog.blk_manager.blk_lock.release() | ||||||
| 
 | 
 | ||||||
|         #check if device mounted |         #check if device mounted | ||||||
|         dialog.dev_mount_path = check_if_mounted(dev_path) |         dialog.dev_mount_path = check_if_mounted(dev_path) | ||||||
|  | |||||||
| @ -557,9 +557,14 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
|         self.setupUi(self) |         self.setupUi(self) | ||||||
|         self.toolbar = self.toolBar |         self.toolbar = self.toolBar | ||||||
|          |          | ||||||
|  |         self.qubes_watch = qubesutils.QubesWatch() | ||||||
|         self.qvm_collection = QubesVmCollection() |         self.qvm_collection = QubesVmCollection() | ||||||
|         self.blk_manager = QubesBlockDevicesManager(self.qvm_collection) |         self.blk_manager = QubesBlockDevicesManager(self.qvm_collection) | ||||||
|          |         self.qubes_watch.setup_block_watch(self.blk_manager.block_devs_event) | ||||||
|  |         self.blk_watch_thread = threading.Thread(target=self.qubes_watch.watch_loop) | ||||||
|  |         self.blk_watch_thread.daemon = True | ||||||
|  |         self.blk_watch_thread.start() | ||||||
|  | 
 | ||||||
|         self.connect(self.table, SIGNAL("itemSelectionChanged()"), self.table_selection_changed) |         self.connect(self.table, SIGNAL("itemSelectionChanged()"), self.table_selection_changed) | ||||||
|          |          | ||||||
|         self.table.setColumnWidth(0, self.column_width) |         self.table.setColumnWidth(0, self.column_width) | ||||||
| @ -794,8 +799,10 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
|             rows_with_blk = None |             rows_with_blk = None | ||||||
|             if update_devs == True: |             if update_devs == True: | ||||||
|                 rows_with_blk = [] |                 rows_with_blk = [] | ||||||
|  |                 self.blk_manager.blk_lock.acquire() | ||||||
|                 for d in self.blk_manager.attached_devs: |                 for d in self.blk_manager.attached_devs: | ||||||
|                     rows_with_blk.append( self.blk_manager.attached_devs[d]['attached_to']['vm']) |                     rows_with_blk.append( self.blk_manager.attached_devs[d]['attached_to']['vm']) | ||||||
|  |                 self.blk_manager.blk_lock.release() | ||||||
| 
 | 
 | ||||||
|             if self.counter % 3 == 0 or out_of_schedule: |             if self.counter % 3 == 0 or out_of_schedule: | ||||||
|                 (self.last_measure_time, self.last_measure_results) = \ |                 (self.last_measure_time, self.last_measure_results) = \ | ||||||
| @ -843,7 +850,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
| 
 | 
 | ||||||
|   |   | ||||||
|     def update_block_devices(self): |     def update_block_devices(self): | ||||||
|         res, msg = self.blk_manager.update() |         res, msg = self.blk_manager.check_for_updates() | ||||||
|         if msg != None and len(msg) > 0: |         if msg != None and len(msg) > 0: | ||||||
|             str = "\n".join(msg) |             str = "\n".join(msg) | ||||||
|             trayIcon.showMessage ("Qubes Manager", str, msecs=5000) |             trayIcon.showMessage ("Qubes Manager", str, msecs=5000) | ||||||
| @ -1304,6 +1311,8 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
|         else: |         else: | ||||||
|             self.blk_menu.clear() |             self.blk_menu.clear() | ||||||
|             self.blk_menu.setEnabled(True) |             self.blk_menu.setEnabled(True) | ||||||
|  | 
 | ||||||
|  |             self.blk_manager.blk_lock.acquire() | ||||||
|             if len(self.blk_manager.attached_devs) > 0 : |             if len(self.blk_manager.attached_devs) > 0 : | ||||||
|                 for d in self.blk_manager.attached_devs: |                 for d in self.blk_manager.attached_devs: | ||||||
|                     if self.blk_manager.attached_devs[d]['attached_to']['vm'] == vm.name: |                     if self.blk_manager.attached_devs[d]['attached_to']['vm'] == vm.name: | ||||||
| @ -1319,6 +1328,8 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
|                     action = self.blk_menu.addAction(QIcon(":/add.png"), str) |                     action = self.blk_menu.addAction(QIcon(":/add.png"), str) | ||||||
|                     action.setData(QVariant(d)) |                     action.setData(QVariant(d)) | ||||||
| 
 | 
 | ||||||
|  |             self.blk_manager.blk_lock.release() | ||||||
|  | 
 | ||||||
|             if self.blk_menu.isEmpty(): |             if self.blk_menu.isEmpty(): | ||||||
|                 self.blk_menu.setEnabled(False) |                 self.blk_menu.setEnabled(False) | ||||||
|   |   | ||||||
| @ -1328,10 +1339,13 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow): | |||||||
|     def attach_dettach_device_triggered(self, action): |     def attach_dettach_device_triggered(self, action): | ||||||
|         dev = str(action.data().toString()) |         dev = str(action.data().toString()) | ||||||
|         vm = self.get_selected_vm() |         vm = self.get_selected_vm() | ||||||
|  | 
 | ||||||
|  |         self.blk_manager.blk_lock.acquire() | ||||||
|         if dev in self.blk_manager.attached_devs: |         if dev in self.blk_manager.attached_devs: | ||||||
|             self.blk_manager.detach_device(vm, dev) |             self.blk_manager.detach_device(vm, dev) | ||||||
|         else: |         else: | ||||||
|             self.blk_manager.attach_device(vm, dev) |             self.blk_manager.attach_device(vm, dev) | ||||||
|  |         self.blk_manager.blk_lock.release() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class QubesBlockDevicesManager(): | class QubesBlockDevicesManager(): | ||||||
| @ -1344,43 +1358,75 @@ class QubesBlockDevicesManager(): | |||||||
|         self.current_attached = {} |         self.current_attached = {} | ||||||
|         self.devs_changed = False |         self.devs_changed = False | ||||||
| 
 | 
 | ||||||
|  |         self.last_update_time = time.time() | ||||||
|  |         self.blk_state_changed = True | ||||||
|  |         self.msg = [] | ||||||
|  |         self.check_counter = 0 | ||||||
|  |         self.blk_lock = threading.Lock() | ||||||
|  | 
 | ||||||
|  |         self.update() | ||||||
|  | 
 | ||||||
|  |     def block_devs_event(self, xid): | ||||||
|  |         now = time.time() | ||||||
|  |         #don't update more often than 1/10 s | ||||||
|  |         if now - self.last_update_time >= 0.1: | ||||||
|  |             self.last_update_time = now | ||||||
|  | 
 | ||||||
|  |             self.blk_lock.acquire() | ||||||
|  | 
 | ||||||
|  |             self.blk_state_changed = True | ||||||
|  | 
 | ||||||
|  |             self.blk_lock.release() | ||||||
|  | 
 | ||||||
|  |     def check_for_updates(self): | ||||||
|  |         self.blk_lock.acquire() | ||||||
|  | 
 | ||||||
|  |         ret = (self.blk_state_changed, self.msg) | ||||||
|  |          | ||||||
|  |         if self.blk_state_changed == True: | ||||||
|  |             self.check_counter += 1 | ||||||
|  |              | ||||||
|  |             self.update() | ||||||
|  |             ret = (self.blk_state_changed, self.msg) | ||||||
|  |              | ||||||
|  |             #let the update last for 3 manager-update cycles | ||||||
|  |             if self.check_counter == 3: | ||||||
|  |                 self.check_counter = 0 | ||||||
|  |                 self.blk_state_changed = False | ||||||
|  |         self.msg = []             | ||||||
|  | 
 | ||||||
|  |         self.blk_lock.release() | ||||||
|  | 
 | ||||||
|  |         return ret | ||||||
|  |              | ||||||
|  |              | ||||||
|     def update(self): |     def update(self): | ||||||
|         blk = qubesutils.block_list() |         blk = qubesutils.block_list() | ||||||
|         msg = [] |  | ||||||
|         for b in blk: |         for b in blk: | ||||||
|             att = qubesutils.block_check_attached(None, blk[b]['device'], backend_xid = blk[b]['xid']) |             att = qubesutils.block_check_attached(None, blk[b]['device'], backend_xid = blk[b]['xid']) | ||||||
|             if b in self.current_blk: |             if b in self.current_blk: | ||||||
|                 if blk[b] == self.current_blk[b]: |                 if blk[b] == self.current_blk[b]: | ||||||
|                     if self.current_attached[b] != att: #devices the same, sth with attaching changed |                     if self.current_attached[b] != att: #devices the same, sth with attaching changed | ||||||
|                         self.current_attached[b] = att |                         self.current_attached[b] = att | ||||||
|                         self.devs_changed = True |  | ||||||
|                 else:   #device changed ?! |                 else:   #device changed ?! | ||||||
|                     self.current_blk[b] = blk[b] |                     self.current_blk[b] = blk[b] | ||||||
|                     self.current_attached[b] = att |                     self.current_attached[b] = att | ||||||
|                     self.devs_changed = True |  | ||||||
|             else: #new device |             else: #new device | ||||||
|                 self.current_blk[b] = blk[b] |                 self.current_blk[b] = blk[b] | ||||||
|                 self.current_attached[b] = att |                 self.current_attached[b] = att | ||||||
|                 self.devs_changed = True |                 self.msg.append("Attached new device: {0}".format(blk[b]['device'])) | ||||||
|                 msg.append("Attached new device: {0}".format(blk[b]['device'])) |  | ||||||
| 
 | 
 | ||||||
|         to_delete = [] |         to_delete = [] | ||||||
|         for b in self.current_blk: #remove devices that are not there anymore |         for b in self.current_blk: #remove devices that are not there anymore | ||||||
|             if b not in blk: |             if b not in blk: | ||||||
|                 to_delete.append(b) |                 to_delete.append(b) | ||||||
|                 self.devs_changed = True |                 self.msg.append("Detached device: {0}".format(self.current_blk[b]['device'])) | ||||||
|                 msg.append("Detached device: {0}".format(self.current_blk[b]['device'])) |  | ||||||
| 
 | 
 | ||||||
|         for d in to_delete: |         for d in to_delete: | ||||||
|             del self.current_blk[d] |             del self.current_blk[d] | ||||||
|             del self.current_attached[d] |             del self.current_attached[d] | ||||||
| 
 | 
 | ||||||
|         if self.devs_changed == True: |         self.__update_blk_entries__() | ||||||
|             self.devs_changed = False |  | ||||||
|             self.__update_blk_entries__() |  | ||||||
|             return True, msg |  | ||||||
|         else: |  | ||||||
|             return False, None |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def __update_blk_entries__(self): |     def __update_blk_entries__(self): | ||||||
| @ -1408,16 +1454,12 @@ class QubesBlockDevicesManager(): | |||||||
|         backend_vm = self.qvm_collection.get_vm_by_name(backend_vm_name) |         backend_vm = self.qvm_collection.get_vm_by_name(backend_vm_name) | ||||||
|         trayIcon.showMessage ("Qubes Manager", "{0} - attaching {1}".format(vm.name, dev), msecs=3000) |         trayIcon.showMessage ("Qubes Manager", "{0} - attaching {1}".format(vm.name, dev), msecs=3000) | ||||||
|         qubesutils.block_attach(vm, backend_vm, dev_id) |         qubesutils.block_attach(vm, backend_vm, dev_id) | ||||||
|         self.devs_changed = True |  | ||||||
|        |        | ||||||
|     def detach_device(self, vm, dev_name): |     def detach_device(self, vm, dev_name): | ||||||
|         dev_id = self.attached_devs[dev_name]['attached_to']['devid'] |         dev_id = self.attached_devs[dev_name]['attached_to']['devid'] | ||||||
|         vm_xid = self.attached_devs[dev_name]['attached_to']['xid'] |         vm_xid = self.attached_devs[dev_name]['attached_to']['xid'] | ||||||
|         trayIcon.showMessage ("Qubes Manager", "{0} - detaching {1}".format(vm.name, dev_name), msecs=3000) |         trayIcon.showMessage ("Qubes Manager", "{0} - detaching {1}".format(vm.name, dev_name), msecs=3000) | ||||||
|         qubesutils.block_detach(None, dev_id, vm_xid) |         qubesutils.block_detach(None, dev_id, vm_xid) | ||||||
|         self.devs_changed = True |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class QubesTrayIcon(QSystemTrayIcon): | class QubesTrayIcon(QSystemTrayIcon): | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Agnieszka Kostrzewa
						Agnieszka Kostrzewa