#!/usr/bin/python ########################################################################### # displayconfig-hwprobe.py - description # # ------------------------------ # # begin : Sun Jan 22 2006 # # copyright : (C) 2006 by Simon Edwards # # email : simon@simonzone.com # # # ########################################################################### # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ########################################################################### # This program should be run during boot time. It quickly examines the # graphics cards (read: PCI devices) in the computer and compares they to # the list in the file $hardware_info_filename. If the two lists differ # then the Debian package manager is automatically called to regenerate # /etc/X11/xorg.conf. This hopefully should mean that people can swap gfx # cards in and out and always have a system that will run Xorg. (even # though the config will be most likely be suboptimal. Suboptimal is better # than no X server). import ScanPCI import os import syslog import select hardware_info_filename = "/var/lib/guidance/guidance-gfxhardware-snapshot" data_file_dir = "/usr/share/apps/guidance/" def main(): # Scan the PCI bus. pci_bus = ScanPCI.PCIBus(data_file_dir) pci_bus.detect() # Stuff our device info in to a string. hardware_config = "" for pci_device in pci_bus.devices: if pci_device.isGfxCard(): hardware_config += "PCI:%i:%i:%i Vendor:%x Device:%x Subvendor:%x Subdevice:%x\n" % \ (pci_device.pci_bus, pci_device.pci_device, pci_device.pci_function, pci_device.vendor, pci_device.device, pci_device.subvendor, pci_device.subdevice) # Read in the old gfx hardware info in. previous_hardware = None try: fhandle = open(hardware_info_filename) previous_hardware = fhandle.read() fhandle.close() except IOError: previous_hardware = None if previous_hardware is not None and previous_hardware!=hardware_config: # Run dpkg and configure the new hardware. syslog.syslog(syslog.LOG_INFO, "Graphics card hardware has changed. Reconfiguring xorg.conf using 'dpkg-reconfigure xserver-xorg'.") cmd = ['dpkg-reconfigure','xserver-xorg'] environ = os.environ.copy() environ['DEBIAN_FRONTEND'] = 'noninteractive' #os.spawnvpe(os.P_WAIT, 'dpkg-reconfigure', cmd, environ) result = ExecWithCapture('/usr/sbin/dpkg-reconfigure', cmd, 0, '/', 0,1, -1, environ) for line in result.split('\n'): syslog.syslog(syslog.LOG_INFO,"dpkg-reconfigure:"+line) # [21:18] you are brave indeed # [21:21] I figured some kind of non-interactive "dpkg-reconfigure xorg" might be enough. # [21:22] yep if previous_hardware is None or previous_hardware!=hardware_config: syslog.syslog(syslog.LOG_INFO, "Writing graphics card hardware list to "+hardware_info_filename) # Write out the gfx hardware info tmp_filename = hardware_info_filename + ".tmp" fhandle = open(tmp_filename,'w') fhandle.write(hardware_config) fhandle.close() os.rename(tmp_filename, hardware_info_filename) ############################################################################ def ExecWithCapture(command, argv, searchPath = 0, root = '/', stdin = 0, catchfd = 1, closefd = -1, environ = None): if not os.access(root + command, os.X_OK) and not searchPath: raise RuntimeError, command + " can not be run" (read, write) = os.pipe() childpid = os.fork() if (not childpid): if (root and root != '/'): os.chroot(root) os.dup2(write, catchfd) os.close(write) os.close(read) if closefd != -1: os.close(closefd) if stdin: os.dup2(stdin, 0) os.close(stdin) # Replace the environment if environ is not None: os.environ.clear() os.environ.update(environ) if searchPath: os.execvp(command, argv) else: os.execv(command, argv) sys.exit(1) os.close(write) rc = "" s = "1" while s: select.select([read], [], []) s = os.read(read, 1000) rc = rc + s os.close(read) try: os.waitpid(childpid, 0) except OSError, (errno, msg): print __name__, "waitpid:", msg return rc main()