From 2f74e096e5d22fbb3cdadc6d7ef184ddb991cf23 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 19 Sep 2012 23:58:02 +0200 Subject: [PATCH] Fix the usbscsi port driver not working, this fixes many miniature (keychain) photo frames no longer being accessible --- libgphoto2-usbscsi.patch | 201 +++++++++++++++++++++++++++++++++++++++ libgphoto2.spec | 9 +- 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 libgphoto2-usbscsi.patch diff --git a/libgphoto2-usbscsi.patch b/libgphoto2-usbscsi.patch new file mode 100644 index 0000000..60308a0 --- /dev/null +++ b/libgphoto2-usbscsi.patch @@ -0,0 +1,201 @@ +usbscsi: Switch from lockdev to flock + +Currently there are 2 problems with the lockdev usage in usbscsi: +1) It breaks usbscsi completely due to a missing symbol when dlopening + usbscsi.so, which is caused by libgphoto2_port/usbscsi/Makefile-files not + adding $(SERIAL_LIBS) to usbscsi_la_LIBADD +2) lockdev uses /var/lock/lockdev, which by default is: + drwxrwxr-x. 2 root lock 40 Sep 19 22:49 /var/lock/lockdev + So despite our udev rules, gphoto using apps need to run as + root (or group lockdev) to be able to work with usbscsi port devices + +I've decided to fix 2) by moving to flock, lockdev makes sense for serial +ports, since other programs may be trying to access them at the same time, +for usbscsi however we only need to coordinate with other apps also using +libgphoto2, and flock then suffices, is much simpler and does not have +the rights issues of lockdev. This fix for 2), also fixes 1) by simply no +longer needing lockdev. + +Index: libgphoto2_port/usbscsi/linux.c +=================================================================== +--- libgphoto2_port/usbscsi/linux.c (revision 14108) ++++ libgphoto2_port/usbscsi/linux.c (working copy) +@@ -1,6 +1,6 @@ + /* SCSI commands to USB Mass storage devices port library for Linux + * +- * Copyright (c) 2010 Hans de Goede ++ * Copyright (c) 2010-2012 Hans de Goede + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by +@@ -19,6 +19,7 @@ + #include "config.h" + #include + ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ + #ifdef HAVE_LIMITS_H + # include + #endif ++#include + #include + #include + #ifdef HAVE_SYS_PARAM_H +@@ -40,9 +42,6 @@ + #ifdef HAVE_SCSI_SG_H + # include + #endif +-#ifdef HAVE_LOCKDEV +-# include +-#endif + + #include + #include +@@ -80,62 +79,37 @@ + } + + static int +-gp_port_usbscsi_lock (GPPort *port, const char *path) ++gp_port_usbscsi_lock (GPPort *port) + { +-#ifdef HAVE_LOCKDEV +- int pid; +- + gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi", +- "Trying to lock '%s'...", path); ++ "Trying to lock '%s'...", port->settings.usbscsi.path); + +- pid = dev_lock (path); +- if (pid) { +- if (port) { +- if (pid > 0) +- gp_port_set_error (port, _("Device '%s' is " +- "locked by pid %d"), path, pid); +- else +- gp_port_set_error (port, _("Device '%s' could " +- "not be locked (dev_lock returned " +- "%d)"), path, pid); ++ if (flock(port->pl->fd, LOCK_EX | LOCK_NB) != 0) { ++ switch (errno) { ++ case EWOULDBLOCK: ++ gp_port_set_error (port, ++ _("Device '%s' is locked by another app."), ++ port->settings.usbscsi.path); ++ return GP_ERROR_IO_LOCK; ++ default: ++ gp_port_set_error (port, ++ _("Failed to lock '%s' (%m)."), ++ port->settings.usbscsi.path); ++ return GP_ERROR_IO; + } +- return GP_ERROR_IO_LOCK; + } +-#else +-# ifdef __GCC__ +-# warning No locking library found. +-# warning You will run into problems if you use +-# warning gphoto2 with a usbscsi picframe in +-# warning combination with Konqueror (KDE) or Nautilus (GNOME). +-# warning This will *not* concern USB cameras. +-# endif +-#endif + + return GP_OK; + } + + static int +-gp_port_usbscsi_unlock (GPPort *port, const char *path) ++gp_port_usbscsi_unlock (GPPort *port) + { +-#ifdef HAVE_LOCKDEV +- int pid; +- +- pid = dev_unlock (path, 0); +- if (pid) { +- if (port) { +- if (pid > 0) +- gp_port_set_error (port, _("Device '%s' could " +- "not be unlocked as it is locked by " +- "pid %d."), path, pid); +- else +- gp_port_set_error (port, _("Device '%s' could " +- "not be unlocked (dev_unlock " +- "returned %d)"), path, pid); +- } +- return GP_ERROR_IO_LOCK; ++ if (flock(port->pl->fd, LOCK_UN) != 0) { ++ gp_port_set_error (port, _("Failed to unlock '%s' (%m)."), ++ port->settings.usbscsi.path); ++ return GP_ERROR_IO; + } +-#endif /* !HAVE_LOCKDEV */ +- + return GP_OK; + } + +@@ -271,34 +245,36 @@ + const int max_tries = 5; + const char *path = port->settings.usbscsi.path; + +- result = gp_port_usbscsi_lock (port, path); +- if (result != GP_OK) { +- for (i = 0; i < max_tries; i++) { +- result = gp_port_usbscsi_lock (port, path); +- if (result == GP_OK) +- break; +- gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi", +- "Failed to get a lock, trying again..."); +- sleep (1); +- } +- CHECK (result) +- } + port->pl->fd = open (path, O_RDWR); + if (port->pl->fd == -1) { +- gp_port_usbscsi_unlock (port, path); + gp_port_set_error (port, _("Failed to open '%s' (%m)."), path); + return GP_ERROR_IO; + } + +- return GP_OK; ++ result = gp_port_usbscsi_lock (port); ++ for (i = 0; i < max_tries && result == GP_ERROR_IO_LOCK; i++) { ++ gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi", ++ "Failed to get a lock, trying again..."); ++ sleep (1); ++ result = gp_port_usbscsi_lock (port); ++ } ++ if (result != GP_OK) { ++ close (port->pl->fd); ++ port->pl->fd = -1; ++ } ++ return result; + } + + static int + gp_port_usbscsi_close (GPPort *port) + { ++ int result; ++ + if (!port || port->pl->fd == -1) + return GP_OK; + ++ result = gp_port_usbscsi_unlock (port); ++ + if (close (port->pl->fd) == -1) { + gp_port_set_error (port, _("Could not close " + "'%s' (%m)."), port->settings.usbscsi.path); +@@ -306,10 +282,7 @@ + } + port->pl->fd = -1; + +- CHECK (gp_port_usbscsi_unlock (port, +- port->settings.usbscsi.path)) +- +- return GP_OK; ++ return result; + } + + static int gp_port_usbscsi_send_scsi_cmd (GPPort *port, int to_dev, char *cmd, diff --git a/libgphoto2.spec b/libgphoto2.spec index 5afde41..a8dfdc3 100644 --- a/libgphoto2.spec +++ b/libgphoto2.spec @@ -1,7 +1,7 @@ Summary: Library for accessing digital cameras Name: libgphoto2 Version: 2.5.0 -Release: 2%{?dist} +Release: 3%{?dist} # GPLV2+ for the main lib (due to exif.c) and most plugins, some plugins GPLv2 License: GPLv2+ and GPLv2 Group: Development/Libraries @@ -11,6 +11,8 @@ Patch1: gphoto2-pkgcfg.patch Patch2: gphoto2-storage.patch Patch3: gphoto2-ixany.patch Patch4: gphoto2-device-return.patch +# Bugfix from upstream svn, can be dropped with next rebase +Patch5: libgphoto2-usbscsi.patch Url: http://www.gphoto.org/ Requires: lockdev BuildRequires: libusb1-devel, libusb-devel >= 0.1.5 @@ -53,6 +55,7 @@ use libgphoto2. %patch2 -p1 -b .storage %patch3 -p1 -b .ixany %patch4 -p1 -b .device-return +%patch5 -p0 for i in AUTHORS COPYING libgphoto2_port/AUTHORS libgphoto2_port/COPYING.LIB `find -name 'README.*'`; do mv ${i} ${i}.old @@ -166,6 +169,10 @@ rm -rf "${RPM_BUILD_ROOT}" %{_mandir}/man3/* %changelog +* Wed Sep 19 2012 Hans de Goede 2.5.0-3 +- Fix the usbscsi port driver not working, this fixes many miniature + (keychain) photo frames no longer being accessible + * Thu Jul 19 2012 Fedora Release Engineering - 2.5.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild