summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2013-07-23 08:40:24 +0200
committerMartin Pitt <martinpitt@gnome.org>2013-07-23 08:53:39 +0200
commitd83dd01a0a1df6198ee08954da1c033b88a1004b (patch)
treec45ba8baee97402a7feed99b7b59da5e3e23baf0
parent6ef22df7ba03c7d4e4f101a916d9cd1c8d20e2f4 (diff)
Add support for udev's hwdb
udev recently gained a hardware database that is intended to replace large udev rule files such as the one shipped with media-player-info. This should give a significant (>50%) speed-up in the processing of usb add events. Add support for converting mpi to hwdb (where applicable), and restrict the mpi2udev tool to only output the entries that cannot be represented in the hwdb format. mpi2udev.py now must be called with "hwdb" or "udev" as first argument. Stop shipping the .hwdb and .rules files in tarballs as they are not static any more. Which variant to build is now determined by configure (udev >= 196). This now needs python2 to build, so add check for it to configure.ac. Co-Authored-By: Martin Pitt <martin.pitt@ubuntu.com>
-rw-r--r--configure.ac8
-rw-r--r--media-players/Makefile.am16
-rw-r--r--tools/Makefile.am2
-rwxr-xr-xtools/mpi2hwdb.py83
-rwxr-xr-xtools/mpi2udev.py53
-rwxr-xr-xtools/udev-syntax-check.py2
6 files changed, 143 insertions, 21 deletions
diff --git a/configure.ac b/configure.ac
index a0db0b0..ab239f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,6 +11,14 @@ if test "${ac_with_udevdir}" = ""; then
ac_with_udevdir=`$PKG_CONFIG --variable=udevdir udev`
fi
+# supports hwdb?
+AM_CONDITIONAL([HAVE_HWDB], [pkg-config --atleast-version=196 udev])
+
+AC_CHECK_PROG([PYTHON], [python2], [python2])
+if test "x$PYTHON" = "x"; then
+ AC_MSG_ERROR([python2 not found])
+fi
+
AC_MSG_NOTICE([installing udev rules in ${ac_with_udevdir}/rules.d])
AC_SUBST([UDEV_DIR],[${ac_with_udevdir}])
diff --git a/media-players/Makefile.am b/media-players/Makefile.am
index 140ab97..5e6e36a 100644
--- a/media-players/Makefile.am
+++ b/media-players/Makefile.am
@@ -4,9 +4,19 @@ dist_mpi_DATA = $(shell find $(top_srcdir)/media-players -name "*.mpi" -printf
udevrulesdir = $(UDEV_DIR)/rules.d
dist_udevrules_DATA = 40-usb-media-players.rules
40-usb-media-players.rules: $(dist_mpi_DATA) $(top_srcdir)/tools/mpi2udev.py
- $(top_srcdir)/tools/mpi2udev.py $(dist_mpi_DATA) > 40-usb-media-players.rules
+if HAVE_HWDB
+ $(top_srcdir)/tools/mpi2udev.py hwdb $(dist_mpi_DATA) > 40-usb-media-players.rules
+else
+ $(top_srcdir)/tools/mpi2udev.py udev $(dist_mpi_DATA) > 40-usb-media-players.rules
+endif
$(top_srcdir)/tools/udev-syntax-check.py 40-usb-media-players.rules
+if HAVE_HWDB
+udevhwdbdir = $(UDEV_DIR)/hwdb.d
+dist_udevhwdb_DATA = 20-usb-media-players.hwdb
+20-usb-media-players.hwdb: $(dist_mpi_DATA) $(top_srcdir)/tools/mpi2hwdb.py
+ $(top_srcdir)/tools/mpi2hwdb.py $(dist_mpi_DATA) > 20-usb-media-players.hwdb
+endif
+
clean-local:
- -rm -f 40-usb-media-players.rules
-EXTRA_DIST = 40-usb-media-players.rules
+ rm -f 40-usb-media-players.rules 20-usb-media-players.hwdb
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 35f9744..a29bd80 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1 +1 @@
-EXTRA_DIST = COPYING fdi2mpi.py mpi2udev.py udev-syntax-check.py
+EXTRA_DIST = COPYING fdi2mpi.py mpi2udev.py mpi2hwdb.py udev-syntax-check.py
diff --git a/tools/mpi2hwdb.py b/tools/mpi2hwdb.py
new file mode 100755
index 0000000..64942e6
--- /dev/null
+++ b/tools/mpi2hwdb.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python2
+# Generate hwdb file from music player identification (.mpi) files
+#
+# (C) 2009 Canonical Ltd.
+# (C) 2013 Tom Gundersen <teg@jklm.no>
+# Author: Tom Gundersen <teg@jklm.no>
+#
+# 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 is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+import sys, ConfigParser, os.path
+
+def parse_mpi(mpi):
+ '''Print hwdb file for given ConfigParser object.'''
+
+ cp = ConfigParser.RawConfigParser()
+ assert cp.read(mpi)
+
+ # if we have more info than just idVendor+idProduct we need to use an udev rule,
+ # so don't write an hwdb entry
+ for name in ['usbvendor', 'usbproduct', 'usbmodel', 'usbmanufacturer']:
+ try:
+ cp.get('Device', name)
+ return
+ except ConfigParser.NoOptionError:
+ continue
+
+ try:
+ m = cp.get('Device', 'product')
+ print '#', m
+ except ConfigParser.NoOptionError:
+ pass
+
+ try:
+ usbids = {}
+ for usbid in cp.get('Device', 'devicematch').split(';'):
+ if len(usbid.split(':')) != 3:
+ continue
+ (subsystem, vid, pid) = usbid.split(':')
+ if subsystem != "usb":
+ continue
+ if usbids.has_key(vid):
+ usbids[vid].append(pid)
+ else:
+ usbids[vid] = [ pid ]
+
+ for vid, pids in usbids.iteritems():
+ for pid in pids:
+ print 'usb:v%sp%s*\n'% (vid.upper(), pid.upper()),
+ print ' ID_MEDIA_PLAYER=%s\n' % os.path.splitext(os.path.basename(mpi))[0],
+
+ # do we have an icon?
+ try:
+ icon = cp.get('Device', 'icon')
+ # breaks media player detection : https://bugs.launchpad.net/ubuntu/+source/gvfs/+bug/657609
+ #print ' UDISKS_PRESENTATION_ICON_NAME=%s\n' % icon,
+ except ConfigParser.NoOptionError:
+ pass
+
+ # terminate line
+ print
+
+ except ConfigParser.NoOptionError:
+ pass
+
+#
+# main
+#
+
+# parse MPI files
+for f in sys.argv[1:]:
+ parse_mpi(f)
diff --git a/tools/mpi2udev.py b/tools/mpi2udev.py
index fa89c2c..3357d3f 100755
--- a/tools/mpi2udev.py
+++ b/tools/mpi2udev.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python2
# Generate udev rules from music player identification (.mpi) files
#
# (C) 2009 Canonical Ltd.
@@ -30,24 +30,27 @@ mpi2udev = {
'usbmanufacturer': 'ATTRS{manufacturer}=="%s"',
}
-def parse_mpi(mpi):
+def parse_mpi(mpi, hwdb):
'''Print udev rule for given ConfigParser object.'''
cp = ConfigParser.RawConfigParser()
assert cp.read(mpi)
- try:
- m = cp.get('Device', 'product')
- print '#', m
- except ConfigParser.NoOptionError:
- pass
+ rule = ''
+
for name in ['usbvendor', 'usbproduct', 'usbmodel', 'usbmanufacturer']:
try:
value = cp.get('Device', name)
- print mpi2udev[name] % value, ',',
+ rule += mpi2udev[name] % value + ', '
except ConfigParser.NoOptionError:
continue
+
+ # if using hwdb and no info other than idVendor+idProduct was found, we don't need to write
+ # an udev rule
+ if hwdb and not rule:
+ return
+
try:
usbids = {}
for usbid in cp.get('Device', 'devicematch').split(';'):
@@ -62,22 +65,32 @@ def parse_mpi(mpi):
usbids[vid] = [ pid ]
for vid, pids in usbids.iteritems():
- print 'ATTRS{idVendor}=="%s" , ATTRS{idProduct}=="%s"'% (vid, '|'.join(pids)), ',',
- print 'ENV{ID_MEDIA_PLAYER}="%s"' % os.path.splitext(os.path.basename(mpi))[0],
+ rule += 'ATTRS{idVendor}=="%s", ATTRS{idProduct}=="%s"'% (vid, '|'.join(pids)) + ', '
+ except ConfigParser.NoOptionError:
+ pass
+
+ # if no information was found, don't write a rule at all
+ if not rule:
+ return
+ try:
+ m = cp.get('Device', 'product')
+ print '#', m
except ConfigParser.NoOptionError:
- print 'ENV{ID_MEDIA_PLAYER}="%s"' % os.path.splitext(os.path.basename(mpi))[0],
+ pass
+
+ rule += 'ENV{ID_MEDIA_PLAYER}="%s"' % os.path.splitext(os.path.basename(mpi))[0]
# do we have an icon?
try:
icon = cp.get('Device', 'icon')
# breaks media player detection : https://bugs.launchpad.net/ubuntu/+source/gvfs/+bug/657609
- # print ', ENV{UDISKS_PRESENTATION_ICON_NAME}="%s"' % icon,
+ # rule += ', ENV{UDISKS_PRESENTATION_ICON_NAME}="%s"' % icon
except ConfigParser.NoOptionError:
pass
- # terminate rule line
- print
+ # print out the rule
+ print rule + '\n'
#
# main
@@ -96,9 +109,17 @@ GOTO="media_player_end"
LABEL="media_player_start"
'''
+# the first argument should be "hwdb" or "udev"
+hwdb = False
+if sys.argv[1] == 'hwdb':
+ hwdb = True
+elif sys.argv[1] != 'udev':
+ sys.stderr.write('Unknown mode %s. Must be "hwdb" or "udev".\n' % sys.argv[1])
+ sys.exit(1)
+
# parse MPI files
-for f in sys.argv[1:]:
- parse_mpi(f)
+for f in sys.argv[2:]:
+ parse_mpi(f, hwdb)
# udev rules footer
print '\nLABEL="media_player_end"'
diff --git a/tools/udev-syntax-check.py b/tools/udev-syntax-check.py
index 8f949fa..89739c9 100755
--- a/tools/udev-syntax-check.py
+++ b/tools/udev-syntax-check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python2
# Simple udev rules syntax checker
#
# (C) 2010 Canonical Ltd.