def get_disks_xhci(self): """ Compare 1. the pci slot name of the devices using xhci 2. the pci slot name of the disks, which is usb3 disks in this case so far, to make sure the usb3 disk does be on the controller using xhci """ # LP: #1378724 udev_client = GUdev.Client() # Get a collection of all udev devices corresponding to block devices udev_devices = get_udev_block_devices(udev_client) # Get a collection of all udev devices corresponding to xhci devices udev_devices_xhci = get_udev_xhci_devices(udev_client) if platform.machine() in ("aarch64", "armv7l"): enumerator = GUdev.Enumerator(client=udev_client) udev_devices_xhci = [ device for device in enumerator.execute() if (device.get_driver() == 'xhci-hcd') ] for udev_device_xhci in udev_devices_xhci: pci_slot_name = udev_device_xhci.get_property('PCI_SLOT_NAME') xhci_devpath = udev_device_xhci.get_property('DEVPATH') for udev_device in udev_devices: devpath = udev_device.get_property('DEVPATH') if (self._compare_pci_slot_from_devpath( devpath, pci_slot_name)): self.rem_disks_xhci[udev_device.get_property( 'DEVNAME')] = 'xhci' if platform.machine() in ("aarch64", "armv7l"): if xhci_devpath in devpath: self.rem_disks_xhci[udev_device.get_property( 'DEVNAME')] = 'xhci' return self.rem_disks_xhci
def set_udev_properties(self, device, props): """Sets one or more udev properties for the 'device' identified by its serial number. Note that this overwrites previously set properties. Pass props=None to remove the rules. :type props: dict """ UDISKS_UDEV_RULES = "/run/udev/rules.d/99-udisks_test.rules" udev = GUdev.Client() dev = udev.query_by_device_file(device) serial = dev.get_property("ID_SERIAL") try: os.makedirs("/run/udev/rules.d/") except OSError: # already exists pass if props: rules = "" for i in props: rules += ', ENV{%s}="%s"' % (i, props[i]) self.write_file(UDISKS_UDEV_RULES, 'ENV{ID_SERIAL}=="%s"%s\n' % (serial, rules)) else: self.remove_file(UDISKS_UDEV_RULES, ignore_nonexistent=True) self.run_command("udevadm control --reload") uevent_path = os.path.join(dev.get_sysfs_path(), "uevent") self.write_file(uevent_path, "change\n") self.udev_settle() # FIXME: need to give udisksd some time to process the uevent time.sleep(1)
def do_activate(self): # Listen to uevent self.client = GUdev.Client(subsystems=["usb"]) self.client.connect("uevent", self.on_uevent) for device in self.client.query_by_subsystem("usb"): if self.look_for_brick(device): break #self.look_for_settings(self.settings) look_for_settings(self.settings) if not self.win: self.win = MindEdAppWin(self.filelist, application=self) else: # MindEd already running, brick file in file browser clicked for nth_file in self.filelist[1:]: if Path(nth_file).is_file(): # check is file already open document_uri = Path(nth_file).resolve().as_uri() pagecount = document_is_open(self.win, document_uri) LOGGER.debug('pagecount {}'.format(pagecount)) if pagecount: self.win.notebook.set_current_page(pagecount - 1) else: self.win.load_file_in_editor(document_uri) self.win.present()
def __init__(self): self.object = None self.bus = SystemBus() self.udev = GUdev.Client(subsystems=["usb/usb_device"]) self.udev.connect("uevent", self.uevent) self.loop = GLib.MainLoop() self.busname = self.bus.publish(BUSNAME, self)
def locker(init): config = os.path.join( BaseDirectory.save_config_path('cinnamon-udev-locker'), 'config.yml') try: with open(config) as f: conditions = yaml.load(f) except FileNotFoundError as e: logger.error('File not found {0}'.format(e.filename)) return except PermissionError as e: logger.error('Unable to read file: {0}'.format(e.filename)) return cs = CScreensaver.ScreenSaverProxy.new_for_bus_sync( Gio.BusType.SESSION, Gio.DBusProxyFlags.NONE, 'org.cinnamon.ScreenSaver', '/org/cinnamon/ScreenSaver', None) def lock(device): logger.info('Lock: {0}'.format(device)) cs.call_lock('{0} removed'.format( device.get_property('ID_MODEL_FROM_DATABASE'))) def wakeup(device): logger.info('Wakeup: {0}'.format(device)) cs.call_simulate_user_activity() actions = { 'lock': lock, 'wakeup': wakeup, } def match_device_properties(device, d): result = [ re.match(p, device.get_property(k)) for k, p in d.items() if device.has_property(k) ] return result and all(result) def event(client, action, device): if init: props = map(lambda k: '{0}: {1}'.format(k, device.get_property(k)), device.get_property_keys()) print('{0}:\n * {1}'.format(action, '\n * '.join(props))) return for condition in conditions: try: result = [ match_device_properties(device, d) for d in condition['devices'] ] if result and any(result): if action in condition: actions[condition[action]](device) except KeyError as e: logger.error('Invalid configuration') c = GUdev.Client(subsystems=[]) c.connect('uevent', event) GLib.MainLoop().run()
def __init__(self, application: Gtk.Application): self.udisks_client = UDisks.Client.new_sync() self.udisks_manager = self.udisks_client.get_manager() self.gio_volume_monitor = Gio.VolumeMonitor.get() self.gio_volume_monitor.connect("volume-changed", self.on_volume_changed) self.gio_volume_monitor.connect("volume-added", self.on_volume_added) self.gio_volume_monitor.connect("volume-removed", self.on_volume_removed) self.udev_client = GUdev.Client() self.mount_op_lock = Lock() self.builder = Gtk.Builder.new_from_file(MAIN_UI_FILE) self.builder.set_translation_domain(APP_NAME) self.builder.connect_signals(self) self.window = self.builder.get_object( "window") # type: Gtk.ApplicationWindow self.window.set_application(application) self.window.set_title("Unlock VeraCrypt Volumes") self.container_list = ContainerList() self.device_list = DeviceList() containers_frame = self.builder.get_object("containers_frame") containers_frame.add(self.container_list.list_box) devices_frame = self.builder.get_object("devices_frame") devices_frame.add(self.device_list.list_box) self.add_tcrypt_volumes() logger.debug("showing window") self.window.show_all() self.window.present()
def _get_modaliases(): '''Return a set of modalias HardwareIDs for available hardware.''' udev_client = GUdev.Client() hw = set() for subsystem in SUBSYSTEMS: for d in udev_client.query_by_subsystem(subsystem): if 'MODALIAS' in d.get_property_keys(): hw.add(HardwareID('modalias', d.get_property('MODALIAS'))) return hw
def __init__(self, system_bus, loop, action, devices, minimum_speed, memorycard, unmounted=False): # Store the desired minimum speed of the device in Mbit/s. The argument # is passed as the number of bits per second so let's fix that. self._desired_minimum_speed = minimum_speed / 10 ** 6 # Compute the allowed UDisks2.Drive.ConnectionBus value based on the # legacy arguments passed from the command line. self._desired_connection_buses = set([ map_udisks1_connection_bus(device) for device in devices]) # Check if we are explicitly looking for memory cards self._desired_memory_card = memorycard # Store information whether we also want detected, but unmounted # devices too self._allow_unmounted = unmounted # Store the desired "delta" direction depending on # whether we test for insertion or removal if action == "insert": self._desired_delta_dir = DELTA_DIR_PLUS elif action == "remove": self._desired_delta_dir = DELTA_DIR_MINUS else: raise ValueError("Unsupported action: {}".format(action)) # Store DBus bus object as we need to pass it to UDisks2 observer self._bus = system_bus # Store event loop object self._loop = loop # Setup UDisks2Observer class to track changes published by UDisks2 self._udisks2_observer = UDisks2Observer() # Set the initial value of reference_objects. # The actual value is only set once in check() self._reference_objects = None # As above, just initializing in init for sake of consistency self._is_reference = None # Setup UDisks2Model to know what the current state is. This is needed # when remove events are reported as they don't carry enough state for # the program to work correctly. Since UDisks2Model only applies the # changes _after_ processing the signals from UDisks2Observer we can # reliably check all of the properties of the removed object / device. self._udisks2_model = UDisks2Model(self._udisks2_observer) # Whenever anything changes call our local change handler # This handler always computes the full delta (versus the # reference state) and decides if we have a match or not self._udisks2_model.on_change.connect(self._on_change) # We may need an udev context for checking the speed of USB devices self._udev_client = GUdev.Client() # A snapshot of udev devices, set in check() self._reference_udev_devices = None # Assume the test passes, this is changed when timeout expires or when # an incorrect device gets inserted. self._error = False
def get_udev_xhci_devices(udev_client): """ Get a list of all devices on pci slots using xhci drivers """ # setup an enumerator so that we can list devices enumerator = GUdev.Enumerator(client=udev_client) # Iterate over pci devices only enumerator.add_match_subsystem('pci') devices = [ device for device in enumerator.execute() if (device.get_driver() == 'xhci_hcd')] # Sort the list, this is not needed but makes various debugging dumps # look better. devices.sort(key=lambda device: device.get_property('PCI_SLOT_NAME')) return devices
def set_udev_property(self, device, prop, value): udev = GUdev.Client() dev = udev.query_by_device_file(device) serial = dev.get_property("ID_SERIAL") try: os.makedirs("/run/udev/rules.d/") except OSError: # already exists pass self.write_file("/run/udev/rules.d/99-udisks_test.rules", 'ENV{ID_SERIAL}=="%s", ENV{%s}="%s"\n' % (serial, prop, value)) self.run_command("udevadm control --reload") uevent_path = os.path.join(dev.get_sysfs_path(), "uevent") self.write_file(uevent_path, "change\n") self.udev_settle() os.unlink("/run/udev/rules.d/99-udisks_test.rules") self.run_command("udevadm control --reload")
def get_udev_block_devices(udev_client): """ Get a list of all block devices Returns a list of GUdev.Device objects representing all block devices in the system. Virtual devices are filtered away using checkbox.heuristics.udev.is_virtual_device. """ # setup an enumerator so that we can list devices enumerator = GUdev.Enumerator(client=udev_client) # Iterate over block devices only enumerator.add_match_subsystem('block') # Convert the enumerator into a plain list and filter-away all # devices deemed virtual by the heuristic. devices = [ device for device in enumerator.execute() if not is_virtual_device(device.get_device_file())] # Sort the list, this is not needed but makes various debugging dumps # look better. devices.sort(key=lambda device: device.get_device_file()) return devices
def __init__(self): """ Create a new DVDFinder and attach to the udev system to listen for events. """ GObject.GObject.__init__(self) self.client = GUdev.Client(subsystems=["video4linux", "block"]) self.drives = {} self.capture_devices = {} for device in self.client.query_by_subsystem("video4linux"): block = device.get_device_file() self.capture_devices[block] = V4LDevice(device) for device in self.client.query_by_subsystem("block"): if device.has_property("ID_CDROM"): block = device.get_device_file() self.drives[block] = DVDDevice(device) self.client.connect("uevent", self.event)
def __init__(self, mainWindow): Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL) self.set_title(_("Create recording")) self.set_transient_for(mainWindow) self.set_destroy_with_parent(True) self.set_modal(True) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.player = None self.busSig1 = None self.busSig2 = None self.recordingTitle = None self.mode = None self.audioLevel = None self.opacityScale = None self.bus = None self.secondarySource = None self.primarySource = "Screen" self.primarySourceHeight = 0 self.primarySourceWidth = 0 self.secondarySourceHeight = 0 self.secondarySourceWidth = 0 # UI Elements for create recording dialog label = Gtk.Label(label=_("Recording name:"), halign=Gtk.Align.START) self.entry = Gtk.Entry() self.entry.connect( "activate", lambda entry: self.response(Gtk.ResponseType.ACCEPT)) self.primaryCombo = Gtk.ComboBoxText() self.primaryCombo.connect("changed", self.primary_capture_changed) self.primaryCombo.set_title("Primary Combo") self.primaryCombo.append_text("Screen") primaryComboLabel = Gtk.Label() primaryComboLabel.set_text(_("Primary capture:")) self.secondaryCombo = Gtk.ComboBoxText() self.secondaryCombo.connect("changed", self.secondary_capture_changed) self.secondaryCombo.set_title("Secondary Combo") #Add available video4linux devices self.uDevClient = GUdev.Client(subsystems=["video4linux"]) self.uDevClient.connect("uevent", self.devices_changed) devices = self.uDevClient.query_by_subsystem("video4linux") self.defaultSecondarySource = None for device in devices: deviceName = device.get_name() if self.defaultSecondarySource == None: self.defaultSecondarySource = "/dev/" + deviceName self.secondaryCombo.append_text(deviceName) self.primaryCombo.append_text(deviceName) self.secondaryCombo.append_text("None") secondaryComboLabel = Gtk.Label() secondaryComboLabel.set_text(_("Secondary capture:")) devicesBox = Gtk.HBox() devicesBox.pack_start(primaryComboLabel, False, False, 3) devicesBox.pack_start(self.primaryCombo, False, False, 3) self.samePrimaryAlert = Gtk.Image.new_from_icon_name( "dialog-warning", Gtk.IconSize.SMALL_TOOLBAR) devicesBox.pack_start(self.samePrimaryAlert, False, False, 3) devicesBox.pack_start(secondaryComboLabel, False, False, 3) devicesBox.pack_start(self.secondaryCombo, False, False, 3) self.sameSecondaryAlert = Gtk.Image.new_from_icon_name( "dialog-warning", Gtk.IconSize.SMALL_TOOLBAR) devicesBox.pack_start(self.sameSecondaryAlert, False, False, 3) self.playerWindow = Gtk.DrawingArea() self.playerWindow.set_size_request(VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT) self.playerWindow.connect("realize", self.player_window_realized) recordingNameBox = Gtk.VBox() recordingNameBox.set_spacing(8) recordingNameBox.pack_start(label, False, False, 0) recordingNameBox.pack_start(self.entry, False, False, 0) opacityScaleLabel = Gtk.Label() opacityScaleLabel.set_text(_("Opacity for secondary capture:")) opacityScaleLabel.set_halign(Gtk.Align.START) self.opacityScale = Gtk.HScale() self.opacityScale.set_range(0.2, 1.0) self.opacityScale.set_value(1.0) self.opacityScale.set_inverted(True) self.opacityScale.set_size_request(270, -1) self.opacityScale.set_draw_value(False) self.opacityScale.set_halign(Gtk.Align.START) self.opacityScale.set_valign(Gtk.Align.CENTER) self.opacityScale.connect("value-changed", self.alpha_adjust_changed) audioLabel = Gtk.Label() audioLabel.set_label(_("Audio level:")) audioLabel.set_halign(Gtk.Align.START) audioButton = Gtk.ToolButton() audioButton.set_tooltip_text(_("Audio settings")) audioButton.set_icon_name("audio-input-microphone") audioButton.connect("clicked", self.launch_audio_settings) audioButton.set_halign(Gtk.Align.END) audioButton.set_valign(Gtk.Align.CENTER) self.audioLevel = isrVUMeter.VUMeter() self.audioLevel.set_valign(Gtk.Align.CENTER) self.audioLevel.set_halign(Gtk.Align.START) # This is so readable! # attach (widget, left, top, width span, height span) settingsGrid = Gtk.Grid() settingsGrid.set_column_spacing(3) settingsGrid.attach(opacityScaleLabel, 0, 0, 1, 1) settingsGrid.attach(self.opacityScale, 0, 1, 1, 1) settingsGrid.attach(audioLabel, 1, 0, 1, 1) settingsGrid.attach(self.audioLevel, 1, 1, 1, 1) settingsGrid.attach(audioButton, 2, 1, 1, 1) buttonBox = Gtk.ButtonBox() buttonBox.set_spacing(5) buttonBox.set_layout(Gtk.ButtonBoxStyle.END) cancelButton = Gtk.Button.new_from_stock(Gtk.STOCK_CANCEL) cancelButton.connect("clicked", lambda button: self.hide()) self.startRecordButton = Gtk.Button.new_with_label( _("Start recording")) buttonBox.add(cancelButton) buttonBox.add(self.startRecordButton) contentArea = Gtk.VBox() contentArea.set_margin_bottom(8) contentArea.set_margin_left(8) contentArea.set_margin_right(8) contentArea.set_spacing(4) contentArea.set_margin_top(8) contentArea.add(recordingNameBox) contentArea.add(devicesBox) contentArea.add(self.playerWindow) contentArea.add(settingsGrid) contentArea.add(buttonBox) self.add(contentArea)
from email.mime.text import MIMEText from pulsectl import Pulse from galicaster.core import context gi.require_version('GUdev', '1.0') from gi.repository import GLib, GUdev # noqa conf = context.get_conf() dispatcher = context.get_dispatcher() logger = context.get_logger() recorder = context.get_recorder() pulse = Pulse('galicaster-plugin-unplugged') udev = GUdev.Client(subsystems=['usb']) def init(): Unplugged() class WatchedDevice(object): def __init__(self, device_name, device_info): self.name = device_name self.vendor_id = device_info.get('vendor_id') self.device_id = device_info.get('device_id') self.switch_on_connect = device_info.get('switch_on_connect') self.switch_on_disconnect = device_info.get('switch_on_disconnect') self._unplugged_since = False self.plugged_in
def _probe_disks_udisks2(self, bus): """ Internal method used to probe / discover available disks using udisks2 dbus interface using the provided dbus bus (presumably the system bus) """ # We'll need udisks2 and udev to get the data we need udisks2_observer = UDisks2Observer() udisks2_model = UDisks2Model(udisks2_observer) udisks2_observer.connect_to_bus(bus) udev_client = GUdev.Client() # Get a collection of all udev devices corresponding to block devices udev_devices = get_udev_block_devices(udev_client) # Get a collection of all udisks2 objects udisks2_objects = udisks2_model.managed_objects # Let's get a helper to simplify the loop below def iter_filesystems_on_block_devices(): """ Generate a collection of UDisks2 object paths that have both the filesystem and block device interfaces """ for udisks2_object_path, interfaces in udisks2_objects.items(): if (UDISKS2_FILESYSTEM_INTERFACE in interfaces and UDISKS2_BLOCK_INTERFACE in interfaces and UDISKS2_LOOP_INTERFACE not in interfaces): yield udisks2_object_path # We need to know about all IO candidates, # let's iterate over all the block devices reported by udisks2 for udisks2_object_path in iter_filesystems_on_block_devices(): # Get interfaces implemented by this object udisks2_object = udisks2_objects[udisks2_object_path] # Find the path of the udisks2 object that represents the drive # this object is a part of drive_object_path = ( udisks2_object[UDISKS2_BLOCK_INTERFACE]['Drive']) # Lookup the drive object, if any. This can fail when try: drive_object = udisks2_objects[drive_object_path] except KeyError: logging.error("Unable to locate drive associated with %s", udisks2_object_path) continue else: drive_props = drive_object[UDISKS2_DRIVE_INTERFACE] # Get the connection bus property from the drive interface of the # drive object. This is required to filter out the devices we don't # want to look at now. connection_bus = drive_props["ConnectionBus"] desired_connection_buses = set( [map_udisks1_connection_bus(device) for device in self.device]) # Skip devices that are attached to undesired connection buses if connection_bus not in desired_connection_buses: continue # Lookup the udev object that corresponds to this object try: udev_device = lookup_udev_device(udisks2_object, udev_devices) except LookupError: logging.error( "Unable to locate udev object that corresponds to: %s", udisks2_object_path) continue # Get the block device pathname, # to avoid the confusion, this is something like /dev/sdbX dev_file = udev_device.get_device_file() parent = self._find_parent(dev_file.replace('/dev/', '')) if parent and find_pkname_is_root_mountpoint(parent, self.lsblk): continue # Skip the EFI System Partition part_type = udisks2_object[UDISKS2_PARTITION_INTERFACE]['Type'] if part_type == ESP_GUID: continue # Get the list of mount points of this block device mount_points = ( udisks2_object[UDISKS2_FILESYSTEM_INTERFACE]['MountPoints']) # Get the speed of the interconnect that is associated with the # block device we're looking at. This is purely informational but # it is a part of the required API interconnect_speed = get_interconnect_speed(udev_device) if interconnect_speed: self.rem_disks_speed[dev_file] = (interconnect_speed * 10**6) else: self.rem_disks_speed[dev_file] = None # Ensure it is a media card reader if this was explicitly requested drive_is_reader = is_memory_card(drive_props['Vendor'], drive_props['Model'], drive_props['Media']) if self.memorycard and not drive_is_reader: continue # The if/else test below simply distributes the mount_point to the # appropriate variable, to keep the API requirements. It is # confusing as _memory_cards is variable is somewhat dummy. if mount_points: # XXX: Arbitrarily pick the first of the mount points mount_point = mount_points[0] self.rem_disks_memory_cards[dev_file] = mount_point self.rem_disks[dev_file] = mount_point else: self.rem_disks_memory_cards_nm[dev_file] = None self.rem_disks_nm[dev_file] = None
def get_devices(): """ Returns list of dictionaries with keys for every device in system (values are provide as example): 'bus' : 'pci' 'driver' : 'pcieport-driver' 'pciType' : '1' 'detached' : '0' 'class' : 'OTHER' 'desc' : 'Intel Corporation|5000 Series Chipset PCI Express x4 Port 2' """ # listen to uevents on all subsystems if gi_gudev: client = GUdev.Client() else: client = gudev.Client([""]) # FIX ME - change to None to list all devices once it is fixed in gudev devices = client.query_by_subsystem("pci") + client.query_by_subsystem( "usb") + client.query_by_subsystem( "block") + client.query_by_subsystem( "ccw") + client.query_by_subsystem("scsi") result = [] for device in devices: subsystem = device.get_subsystem() result_item = { 'bus': subsystem, 'driver': device.get_driver(), 'pciType': _clasify_pci_type(subsystem), 'detached': '0', # always zero? 'class': _clasify_class(device), 'desc': _get_device_desc(device), } if result_item['class'] is None: result_item['class'] = 'OTHER' if result_item['driver'] is None: result_item['driver'] = 'unknown' if subsystem == 'block': if device.has_property('ID_BUS'): result_item['bus'] = device.get_property('ID_BUS') result_item['device'] = device.get_name() if device.get_devtype() == 'partition': # do not report partitions, just whole disks continue if device.get_property('DM_NAME'): # LVM device continue if device.get_property('MAJOR') == '1': # ram device continue if device.get_property('MAJOR') == '7': # character devices for virtual console terminals continue # This is interpreted as Physical. But what to do with it? # result_item['prop1'] = '' # This is interpreted as Logical. But what to do with it? # result_item['prop2'] = '' elif subsystem == 'pci': pci_class = device.get_property('PCI_ID') if pci_class: (result_item['prop1'], result_item['prop2']) = pci_class.split(':') pci_subsys = device.get_property('PCI_SUBSYS_ID') if pci_subsys: (result_item['prop3'], result_item['prop4']) = pci_subsys.split(':') elif subsystem == 'usb': if device.has_property('ID_VENDOR_ID'): result_item['prop1'] = device.get_property('ID_VENDOR_ID') if device.has_property('ID_MODEL_ID'): result_item['prop2'] = device.get_property('ID_MODEL_ID') if device.has_property('ID_BUS') and device.get_property( 'ID_BUS') == 'scsi': if device.has_property('ID_PATH') or device.has_property( 'DEVPATH'): if device.has_property('ID_PATH'): path = device.get_property('ID_PATH') m = re.search('.*scsi-(\d+):(\d+):(\d+):(\d+)', path) else: # device.has_property('DEVPATH') path = device.get_property('DEVPATH') m = re.search('.*/(\d+):(\d+):(\d+):(\d+)/block/', path) if m: # do not fail, if regexp did not match result_item['prop1'] = m.group(1) # DEV_HOST result_item['prop2'] = m.group(2) # DEV_ID result_item['prop3'] = m.group(3) # DEV_CHANNEL result_item['prop4'] = m.group(4) # DEV_LUN result.append(result_item) return result
def __init__(self): Backend.__init__(self) logging.debug('FastbootBackend') self.client = GUdev.Client(subsystems=['usb'])
def _probe_disks_udisks2_cli(self): # First we will build up a db of udisks info by scraping the output # of the dump command # TODO: remove the snap prefix when the alias becomes available proc = subprocess.Popen(['udisks2.udisksctl', 'dump'], stdout=subprocess.PIPE) udisks_devices = {} current_bd = None current_interface = None while True: line = proc.stdout.readline().decode(sys.stdout.encoding) if line == '': break if line == '\n': current_bd = None current_interface = None if line.startswith('/org/freedesktop/UDisks2/'): path = line.strip() current_bd = os.path.basename(path).rstrip(':') udisks_devices[current_bd] = {} continue if current_bd is None: continue if line.startswith(' org.freedesktop'): current_interface = line.strip().rstrip(':') udisks_devices[current_bd][current_interface] = {} continue if current_interface is None: continue entry = ''.join(c for c in line if c not in '\n\t\' ') wanted_keys = ( 'Device:', 'Drive:', 'MountPoints:', 'Vendor:', 'ConnectionBus:', 'Model:', 'Media:', 'Type:', ) for key in wanted_keys: if entry.startswith(key): udisks_devices[current_bd][current_interface][key] = ( entry[len(key):]) # Now use the populated udisks structure to fill out the API used by # other _probe disks functions for device, interfaces in udisks_devices.items(): # iterate over udisks objects that have both filesystem and # block device interfaces if (UDISKS2_FILESYSTEM_INTERFACE in interfaces and UDISKS2_BLOCK_INTERFACE in interfaces): # To be an IO candidate there must be a drive object drive = interfaces[UDISKS2_BLOCK_INTERFACE].get('Drive:') if drive is None or drive == '/': continue drive_object = udisks_devices[os.path.basename(drive)] # Get the connection bus property from the drive interface of # the drive object. This is required to filter out the devices # we don't want to look at now. connection_bus = ( drive_object[UDISKS2_DRIVE_INTERFACE]['ConnectionBus:']) desired_connection_buses = set([ map_udisks1_connection_bus(device) for device in self.device ]) # Skip devices that are attached to undesired connection buses if connection_bus not in desired_connection_buses: continue dev_file = (interfaces[UDISKS2_BLOCK_INTERFACE].get('Device:')) parent = self._find_parent(dev_file.replace('/dev/', '')) if (parent and find_pkname_is_root_mountpoint( parent, self.lsblk)): continue # XXX: we actually only scrape the first one currently mount_point = (interfaces[UDISKS2_FILESYSTEM_INTERFACE].get( 'MountPoints:')) if mount_point == '': mount_point = None # We need to skip-non memory cards if we look for memory cards # and vice-versa so let's inspect the drive and use heuristics # to detect memory cards (a memory card reader actually) now. if self.memorycard != is_memory_card( drive_object[UDISKS2_DRIVE_INTERFACE]['Vendor:'], drive_object[UDISKS2_DRIVE_INTERFACE]['Model:'], drive_object[UDISKS2_DRIVE_INTERFACE]['Media:']): continue # Skip the EFI System Partition part_type = drive_object[UDISKS2_PARTITION_INTERFACE]['Type:'] if part_type == ESP_GUID: continue if mount_point is None: self.rem_disks_memory_cards_nm[dev_file] = None self.rem_disks_nm[dev_file] = None else: self.rem_disks_memory_cards[dev_file] = mount_point self.rem_disks[dev_file] = mount_point # Get the speed of the interconnect that is associated with the # block device we're looking at. This is purely informational # but it is a part of the required API udev_devices = get_udev_block_devices(GUdev.Client()) for udev_device in udev_devices: if udev_device.get_device_file() == dev_file: interconnect_speed = get_interconnect_speed( udev_device) if interconnect_speed: self.rem_disks_speed[dev_file] = ( interconnect_speed * 10**6) else: self.rem_disks_speed[dev_file] = None
def __on_change_uevent(gudev): _bdev_lock.acquire() for bdev in _block_devices: if bdev.syspath == gudev.get_sysfs_path(): bdev._gudev = gudev _bdev_lock.release() __notify_uevent_handlers("change", bdev) _bdev_lock.acquire() _bdev_lock.release() def __on_uevent(client, action, gudev): if action == "add": __on_add_uevent(gudev) if action == "remove": __on_remove_uevent(gudev) if action == "change": __on_change_uevent(gudev) # # Gudev.Client() doesn't take unicode on python2.7 which is probably a # bug, so use byte string for this case. # block = 'block' if sys.version_info[0] < 3: block = block.encode('ascii') __client = GUdev.Client(subsystems=[block]) __client.connect("uevent", __on_uevent) for gudev in __client.query_by_subsystem("block"): __on_add_uevent(gudev)
def __init__(self): if HAVE_GUDEV: self._uc = GUdev.Client() else: self._uc = None