Re: [Entangle-devel] [patch] Port to FreeBSD: udev - devd (for automatic camera detection)

2014-11-14 Thread Alexey Dokuchaev
On Mon, Jul 08, 2013 at 08:47:44PM +0100, Daniel P. Berrange wrote:
 On Fri, Jul 05, 2013 at 08:18:59PM +0700, Alexey Dokuchaev wrote:
  On Fri, Jul 05, 2013 at 01:48:41PM +0100, Daniel P. Berrange wrote:
   On Fri, Jul 05, 2013 at 07:16:03PM +0700, Alexey Dokuchaev wrote:
[...]
What I need to do, is first to reestablish new connection to newly run
devd, and then g_io_channel_shutdown(...)/g_object_unref(oldsocket).
   
   IMHO the order you have here ought to be ok.
  
  My thinking the reason for calling devd_init() first, then cleaning up is
  because it takes certain time to devd to reappear and start serving again.
  In indication of this is a series of repeating failing connect() calls if
  perror()'ing them...  But I might be wrong.
 
 Yep, that sounds pretty likely indeed. If you get a failure to
 reconnect to devd, then you can use  g_timeout_add to re-schedule
 an attempt to connect 1 second later, or something like that.
 [...]

Hi Daniel,

Sorry I never had time to finish conversion to G* API, but nonetheless, the
FreeBSD port seems to work fine (and was recently updated to version 0.6.0).

May I ask you to augment Install it from your Linux distribution (others
coming soon) text on the http://entangle-photo.org/ to Linux/Unix (or,
if you prefer, Linux/BSD) and add the following install command line:

# pkg install entangle (FreeBSD)

to the Download block?  Thanks,

./danfe

___
Entangle-devel mailing list
Entangle-devel@gna.org
https://mail.gna.org/listinfo/entangle-devel


Re: [Entangle-devel] [patch] Port to FreeBSD: udev - devd (for automatic camera detection)

2013-07-08 Thread Daniel P. Berrange
On Fri, Jul 05, 2013 at 08:18:59PM +0700, Alexey Dokuchaev wrote:
 On Fri, Jul 05, 2013 at 01:48:41PM +0100, Daniel P. Berrange wrote:
  On Fri, Jul 05, 2013 at 07:16:03PM +0700, Alexey Dokuchaev wrote:
   [...]
   What I need to do, is first to reestablish new connection to newly run
   devd, and then g_io_channel_shutdown(...)/g_object_unref(oldsocket).
  
  IMHO the order you have here ought to be ok.
 
 My thinking the reason for calling devd_init() first, then cleaning up is
 because it takes sertain time to devd to reappear and start serving again.
 In indication of this is a series of repeating failing connect() calls if
 perror()'ing them...  But I might be wrong.

Yep, that sounds pretty likely indeed. If you get a failure to
reconnect to devd, then you can use  g_timeout_add to re-schedule
an attempt to connect 1 second later, or something like that.

 
  Can you send the code you currently have, so I can see the bigger
  picture of how you now have it written.
 
 Sure, attached is the current version of entangle-device-manager.c.

The code you have looks fine, so I think it just needs to try to
do the reschedule to reconnect attempt

Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

___
Entangle-devel mailing list
Entangle-devel@gna.org
https://mail.gna.org/listinfo/entangle-devel


Re: [Entangle-devel] [patch] Port to FreeBSD: udev - devd (for automatic camera detection)

2013-07-05 Thread Alexey Dokuchaev
On Thu, Jul 04, 2013 at 01:35:21PM +0100, Daniel P. Berrange wrote:
 Hmm, I'd have a slight preference for use of GIO's GSocket +
 GUnixSocketAddress APIs, rather than directly accessing the
 POSIX sockets APIs, if you're willing to rewrite to them.

I've attempted to replace POSIX socket/connect stuff with corresponding
g_* calls, but cannot figure out to properly handle devd(8) daemon
restarts.  It's easy when dealing with raw file descriptors, because IO
channel also works over them (not GSockets).  See my POSIX code below:

  +case G_IO_STATUS_EOF:
  +case G_IO_STATUS_AGAIN:
  +/*
  + * Apparently, devd(8) was reinited (restarted?).  Allocate
  + * new channel and teardown previous connection.
  + */
  +devd_init(manager);
  +if (manager-priv-efd  0) {
  +int old_efd = g_io_channel_unix_get_fd(source);
  +g_io_channel_shutdown(source, FALSE, NULL);
  +close(old_efd);
  +return FALSE;
  +}
  +break;

Now with GSocket, I'm no longer working with int fd, but with GSocket*
priv-ctx (I reused the same name as in Linux, since they both unrefed in
the same way, just differ in type).

If I replace it with something like this (to avoid caching priv-ctx),
once I issue service devd restart, autodetection stops working. :-(

  if (manager-priv-ctx) {
  g_io_channel_shutdown(source, FALSE, NULL);
  g_object_unref(manager-priv-ctx);
  }
  devd_init(manager);

What I need to do, is first to reestablish new connection to newly run
devd, and then g_io_channel_shutdown(...)/g_object_unref(oldsocket).

I'm not sure how to correctly emulate old_efd = g_io_channel_unix_get_fd(...)
to obtain underlying (old, stray) GSocket.  Any ideas how to correctly reopen
new socket, and *then* teardown old channel/socket in GIO words?

 configure is actually an auto-generated file. The master
 source is in  configure.ac You'll want to conditionalize
 the call to PKG_CHECK_MODULES([GUDEV], [gudev-1.0 = $GUDEV_REQUIRED])
 in that file instead.

OK, simple patch attached.  It also fixes one apparent typo.

./danfe
--- configure.ac.orig   2013-03-13 05:23:34.0 +0800
+++ configure.ac2013-07-05 18:45:32.0 +0800
@@ -30,8 +30,6 @@
 AC_SUBST(GTK_REQUIRED)
 GPHOTO2_REQUIRED=2.4.11
 AC_SUBST(GPHOTO2_REQUIRED)
-GUDEV_REQUIRED=145
-AC_SUBST(GUDEV_REQUIRED)
 DBUS_GLIB_REQUIRED=0.60
 AC_SUBST(DBUS_GLIB_REQUIRED)
 GOBJECT_INTROSPECTION_REQUIRED=0.9.3
@@ -61,7 +59,7 @@
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_LIBS)
 
-PKG_CHECK_MODULES([GIO], [glib-2.0 = $GIO_REQUIRED])
+PKG_CHECK_MODULES([GIO], [gio-2.0 = $GIO_REQUIRED])
 AC_SUBST(GIO_CFLAGS)
 AC_SUBST(GIO_LIBS)
 
@@ -102,9 +100,13 @@
   AC_DEFINE_UNQUOTED([HAVE_GPHOTO25], 1, [whether we're building libgphoto = 
2.5])
 fi
 
-PKG_CHECK_MODULES([GUDEV], [gudev-1.0 = $GUDEV_REQUIRED])
-AC_SUBST(GUDEV_CFLAGS)
-AC_SUBST(GUDEV_LIBS)
+if test `uname -s` = Linux; then
+  GUDEV_REQUIRED=145
+  AC_SUBST(GUDEV_REQUIRED)
+  PKG_CHECK_MODULES([GUDEV], [gudev-1.0 = $GUDEV_REQUIRED])
+  AC_SUBST(GUDEV_CFLAGS)
+  AC_SUBST(GUDEV_LIBS)
+fi
 
 PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1 = $DBUS_GLIB_REQUIRED])
 AC_SUBST(DBUS_GLIB_CFLAGS)
___
Entangle-devel mailing list
Entangle-devel@gna.org
https://mail.gna.org/listinfo/entangle-devel


Re: [Entangle-devel] [patch] Port to FreeBSD: udev - devd (for automatic camera detection)

2013-07-05 Thread Alexey Dokuchaev
On Fri, Jul 05, 2013 at 01:48:41PM +0100, Daniel P. Berrange wrote:
 On Fri, Jul 05, 2013 at 07:16:03PM +0700, Alexey Dokuchaev wrote:
  [...]
  What I need to do, is first to reestablish new connection to newly run
  devd, and then g_io_channel_shutdown(...)/g_object_unref(oldsocket).
 
 IMHO the order you have here ought to be ok.

My thinking the reason for calling devd_init() first, then cleaning up is
because it takes sertain time to devd to reappear and start serving again.
In indication of this is a series of repeating failing connect() calls if
perror()'ing them...  But I might be wrong.

 Can you send the code you currently have, so I can see the bigger
 picture of how you now have it written.

Sure, attached is the current version of entangle-device-manager.c.

./danfe
/*
 *  Entangle: Tethered Camera Control  Capture
 *
 *  Copyright (C) 2009-2012 Daniel P. Berrange
 *
 *  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 3 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, see http://www.gnu.org/licenses/.
 *
 */

#include config.h

#if defined(__FreeBSD__)
#include gio/gio.h
#include gio/gunixsocketaddress.h
#include glib.h
//#include unistd.h
#else
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#ifdef G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include gudev/gudev.h
#endif
#endif
#include string.h
#include stdio.h

#include entangle-debug.h
#include entangle-device-manager.h

#define ENTANGLE_DEVICE_MANAGER_GET_PRIVATE(obj)\
(G_TYPE_INSTANCE_GET_PRIVATE((obj), ENTANGLE_TYPE_DEVICE_MANAGER, 
EntangleDeviceManagerPrivate))

struct _EntangleDeviceManagerPrivate {
#if defined(__linux__)
GUdevClient
#elif defined(__FreeBSD__)
GSocket
#endif
*ctx;
};

G_DEFINE_TYPE(EntangleDeviceManager, entangle_device_manager, G_TYPE_OBJECT);


static void entangle_device_manager_finalize (GObject *object)
{
EntangleDeviceManager *manager = ENTANGLE_DEVICE_MANAGER(object);
EntangleDeviceManagerPrivate *priv = manager-priv;
ENTANGLE_DEBUG(Finalize manager);

if (priv-ctx)
g_object_unref(priv-ctx);

G_OBJECT_CLASS (entangle_device_manager_parent_class)-finalize (object);
}


static void entangle_device_manager_class_init(EntangleDeviceManagerClass 
*klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);

object_class-finalize = entangle_device_manager_finalize;

g_signal_new(device-added,
 G_TYPE_FROM_CLASS(klass),
 G_SIGNAL_RUN_FIRST,
 G_STRUCT_OFFSET(EntangleDeviceManagerClass, device_added),
 NULL, NULL,
 g_cclosure_marshal_VOID__STRING,
 G_TYPE_NONE,
 1,
 G_TYPE_STRING);

g_signal_new(device-removed,
 G_TYPE_FROM_CLASS(klass),
 G_SIGNAL_RUN_FIRST,
 G_STRUCT_OFFSET(EntangleDeviceManagerClass, device_removed),
 NULL, NULL,
 g_cclosure_marshal_VOID__STRING,
 G_TYPE_NONE,
 1,
 G_TYPE_STRING);


g_type_class_add_private(klass, sizeof(EntangleDeviceManagerPrivate));
}


#if defined(__linux__)
static void do_udev_event(GUdevClient *client G_GNUC_UNUSED,
  const char *action,
  GUdevDevice *dev,
  gpointer opaque)
{
EntangleDeviceManager *manager = opaque;
const gchar *sysfs;
const gchar *usbbus, *usbdev;
const gchar *devtype;
gchar *port;

if (strcmp(action, add) != 0 
strcmp(action, remove) != 0)
return;

devtype = g_udev_device_get_devtype(dev);
if ((devtype == NULL) ||
strcmp(devtype, usb_device) != 0)
return;

sysfs = g_udev_device_get_sysfs_path(dev);

usbbus = g_udev_device_get_property(dev, BUSNUM);
usbdev = g_udev_device_get_property(dev, DEVNUM);

if (sysfs == NULL ||
usbbus == NULL ||
usbdev == NULL)
return;

port = g_strdup_printf(usb:%s,%s, usbbus, usbdev);

ENTANGLE_DEBUG(%s device '%s' '%s', action, sysfs, port);

if (strcmp(action, add) == 0) {
g_signal_emit_by_name(manager, device-added, port);
} else {
g_signal_emit_by_name(manager, device-removed, port);
}
g_free(port);
}
#elif defined(__FreeBSD__)
static void devd_init(EntangleDeviceManager *manager);

static gboolean do_devd_event(GIOChannel *source,
  GIOCondition condition,
   

Re: [Entangle-devel] [patch] Port to FreeBSD: udev - devd (for automatic camera detection)

2013-07-04 Thread Daniel P. Berrange
On Thu, Jul 04, 2013 at 07:27:48PM +0700, Alexey Dokuchaev wrote:
 Hi there,
 
 I've recently discovered Entangle, but was a bit frustrated it's requires
 Linuxish udev for automatic camera detection.  I've disabled relevant
 checks in configure script, and patch two files.  Patch is attached, feel
 free to ask questions.  It should now work under both Linux and FreeBSD.


 --- src/backend/entangle-camera-list.c.orig   2013-03-13 05:23:35.0 
 +0800
 +++ src/backend/entangle-camera-list.c2013-07-04 17:58:15.0 
 +0800
 @@ -117,7 +117,7 @@ static void entangle_camera_list_finaliz
  }
  
  
 -static void entangle_camera_list_udev_event(EntangleDeviceManager *manager 
 G_GNUC_UNUSED,
 +static void entangle_camera_list_event(EntangleDeviceManager *manager 
 G_GNUC_UNUSED,
  char *port G_GNUC_UNUSED,
  gpointer opaque)
  {
 @@ -227,9 +227,9 @@ static void entangle_camera_list_init(En
  g_error(_(Cannot load gphoto2 ports));
  
  g_signal_connect(priv-devManager, device-added,
 - G_CALLBACK(entangle_camera_list_udev_event), list);
 + G_CALLBACK(entangle_camera_list_event), list);
  g_signal_connect(priv-devManager, device-removed,
 - G_CALLBACK(entangle_camera_list_udev_event), list);
 + G_CALLBACK(entangle_camera_list_event), list);
  
  entangle_camera_list_refresh(list, NULL);
  }
 --- src/backend/entangle-device-manager.c.orig2013-03-13 
 05:23:35.0 +0800
 +++ src/backend/entangle-device-manager.c 2013-07-04 20:02:19.0 
 +0800
 @@ -20,13 +20,19 @@
  
  #include config.h
  
 -#include string.h
 -#include stdio.h
 -
 +#if defined(__FreeBSD__)
 +#include sys/socket.h
 +#include sys/un.h
 +#include glib.h
 +#include unistd.h
 +#else
  #define G_UDEV_API_IS_SUBJECT_TO_CHANGE
  #ifdef G_UDEV_API_IS_SUBJECT_TO_CHANGE
  #include gudev/gudev.h
  #endif
 +#endif
 +#include string.h
 +#include stdio.h
  
  #include entangle-debug.h
  #include entangle-device-manager.h
 @@ -35,7 +41,11 @@
  (G_TYPE_INSTANCE_GET_PRIVATE((obj), ENTANGLE_TYPE_DEVICE_MANAGER, 
 EntangleDeviceManagerPrivate))
  
  struct _EntangleDeviceManagerPrivate {
 +#if defined(__linux__)
  GUdevClient *ctx;
 +#elif defined(__FreeBSD__)
 +int efd;
 +#endif
  };
  
  G_DEFINE_TYPE(EntangleDeviceManager, entangle_device_manager, G_TYPE_OBJECT);
 @@ -47,8 +57,13 @@ static void entangle_device_manager_fina
  EntangleDeviceManagerPrivate *priv = manager-priv;
  ENTANGLE_DEBUG(Finalize manager);
  
 +#if defined(__linux__)
  if (priv-ctx)
  g_object_unref(priv-ctx);
 +#elif defined(__FreeBSD__)
 +if (priv-efd)
 +close(priv-efd);
 +#endif
  
  G_OBJECT_CLASS (entangle_device_manager_parent_class)-finalize (object);
  }
 @@ -85,6 +100,7 @@ static void entangle_device_manager_clas
  }
  
  
 +#if defined(__linux__)
  static void do_udev_event(GUdevClient *client G_GNUC_UNUSED,
const char *action,
GUdevDevice *dev,
 @@ -126,6 +142,91 @@ static void do_udev_event(GUdevClient *c
  }
  g_free(port);
  }
 +#elif defined(__FreeBSD__)
 +static void devd_init(EntangleDeviceManager *manager);
 +
 +static gboolean do_devd_event(GIOChannel *source,
 +  GIOCondition condition,
 +  gpointer user_data)
 +{
 +EntangleDeviceManager *manager = user_data;
 +char *event, *cutoff;
 +gsize end;
 +GIOStatus status;
 +
 +status = g_io_channel_read_line(source, event, NULL, end, NULL);
 +
 +switch (status) {
 +case G_IO_STATUS_NORMAL:
 +event[end] = '\0';
 +if (strncmp(event + 1, ugen, 4))
 +break;
 +if (!(cutoff = strchr(event + 5, ' ')))
 +break;
 +*cutoff = '\0';
 +if (*event == '+') {
 +g_signal_emit_by_name(manager, device-added, event + 1);
 +} else if (*event == '-') {
 +g_signal_emit_by_name(manager, device-removed, event + 1);
 +}
 +g_free(event);
 +break;
 +case G_IO_STATUS_EOF:
 +case G_IO_STATUS_AGAIN:
 +/*
 + * Apparently, devd(8) was reinited (restarted?).  Allocate
 + * new channel and teardown previous connection.
 + */
 +devd_init(manager);
 +if (manager-priv-efd  0) {
 +int old_efd = g_io_channel_unix_get_fd(source);
 +g_io_channel_shutdown(source, FALSE, NULL);
 +close(old_efd);
 +return FALSE;
 +}
 +break;
 +case G_IO_STATUS_ERROR:
 +default:
 +/* XXX: what shall we do? */
 +break;
 +}
 +return TRUE;
 +}
 +
 +
 +static void devd_init(EntangleDeviceManager *manager)
 +{
 +EntangleDeviceManagerPrivate *priv = manager-priv;
 +struct sockaddr_un addr;
 +
 +priv-efd