diff --git a/docs/usb_moded-doc.txt b/docs/usb_moded-doc.txt index ea0192d..96ac11b 100644 --- a/docs/usb_moded-doc.txt +++ b/docs/usb_moded-doc.txt @@ -192,9 +192,9 @@ In case you need some program to be started along some mode the appsync option provides this option. Only condition is that it can be activated by dbus and that (preferably) it will notify usb_moded that it is ready by ready_method call on the session bus. -Systemd and upstart are also supported. This ready method call is just calling the regular usb_moded interface, but now on the session bus, with as argument the program name as defined in the config file. +Systemd and upstart are also supported. To achieve this you need to have a config file in /etc/usb-moded/run. Best practice would be giving it a descriptive name followed by .ini @@ -231,6 +231,10 @@ each of them after the module has been loaded and keep track if they have been s It will warn you if that failed. This works together with an optional softconnect option that will need kernel support. +These services will start before the whole setup for the usb is done. In case the application +only works after everything has been set up, you can start the application at the end by adding +post = 1 to configuration. + Dynamic modes ------------- diff --git a/src/usb_moded-appsync.c b/src/usb_moded-appsync.c index f1c34c5..068402a 100644 --- a/src/usb_moded-appsync.c +++ b/src/usb_moded-appsync.c @@ -140,6 +140,7 @@ static struct list_elem *read_file(const gchar *filename) log_debug("Upstart control = %d\n", list_item->upstart); list_item->systemd = g_key_file_get_integer(settingsfile, APP_INFO_ENTRY, APP_INFO_SYSTEMD_KEY, NULL); log_debug("Systemd control = %d\n", list_item->systemd); + list_item->post = g_key_file_get_integer(settingsfile, APP_INFO_ENTRY, APP_INFO_POST, NULL); cleanup: @@ -157,6 +158,7 @@ static struct list_elem *read_file(const gchar *filename) return list_item; } + /* @return 0 on succes, 1 if there is a failure */ int activate_sync(const char *mode) { @@ -218,6 +220,12 @@ int activate_sync(const char *mode) struct list_elem *data = iter->data; if(!strcmp(mode, data->mode)) { + /* launch items marked as post, will be launched after usb is up */ + if(data->post) + { + mark_active(data->name); + continue; + } log_debug("launching app %s\n", data->name); if(data->systemd) { @@ -243,7 +251,7 @@ int activate_sync(const char *mode) mark_active(data->name); #ifdef APP_SYNC_DBUS else - if(usb_moded_dbus_app_launch(data->launch)) + if(!usb_moded_dbus_app_launch(data->launch)) mark_active(data->name); else goto error; @@ -259,6 +267,71 @@ int activate_sync(const char *mode) return(1); } +int activate_sync_post(const char *mode) +{ + GList *iter; + + log_debug("activate post sync"); + + if( sync_list == 0 ) + { + log_debug("No sync list! skipping post sync\n"); + return 0; + } + +#ifdef APP_SYNC_DBUS + /* check dbus initialisation, skip dbus activated services if this fails */ + if(!usb_moded_app_sync_init()) + { + log_debug("dbus setup failed => skipping dbus launched apps \n"); + no_dbus = 1; + } +#endif /* APP_SYNC_DBUS */ + + /* go through list and launch apps */ + for( iter = sync_list; iter; iter = g_list_next(iter) ) + { + struct list_elem *data = iter->data; + if(!strcmp(mode, data->mode)) + { + /* launch only items marked as post, others are already running */ + if(!data->post) + continue; + log_debug("launching app %s\n", data->name); + if(data->systemd) + { + if(systemd_control_service(data->name, SYSTEMD_START)) + goto error; + } +#ifdef UPSTART + else if(data->upstart) + { + if(upstart_control_job(data->name, UPSTART_START)) + goto error; + } +#endif /* UPSTART */ + else if(data->launch) + { + /* skipping if dbus session bus is not available, + or not compiled in */ + if(no_dbus) + continue; +#ifdef APP_SYNC_DBUS + else + if(usb_moded_dbus_app_launch(data->launch != 0)) + goto error; +#endif /* APP_SYNC_DBUS */ + } + } + } + + return(0); + +error: + log_warning("Error launching a service!\n"); + return(1); +} + int mark_active(const gchar *name) { int ret = -1; // assume name not found diff --git a/src/usb_moded-appsync.h b/src/usb_moded-appsync.h index 91e3345..b139ad4 100644 --- a/src/usb_moded-appsync.h +++ b/src/usb_moded-appsync.h @@ -27,6 +27,7 @@ #define APP_INFO_LAUNCH_KEY "launch" #define APP_INFO_UPSTART_KEY "upstart" #define APP_INFO_SYSTEMD_KEY "systemd" +#define APP_INFO_POST "post" /** * keep all the needed info together for launching an app @@ -40,11 +41,13 @@ typedef struct list_elem int active; /* marker to check if the app has started sucessfully */ int upstart; /* marker to know if we start it with upstart or not */ int systemd; /* marker to know if we start it with systemd or not */ + int post; /* marker to indicate when to start the app */ /*@}*/ }list_elem; void readlist(void); int activate_sync(const char *mode); +int activate_sync_post(const char *mode); int mark_active(const gchar *name); int appsync_stop(void); void free_appsync_list(void); diff --git a/src/usb_moded-modesetting.c b/src/usb_moded-modesetting.c index 618bd16..d4b8bf3 100644 --- a/src/usb_moded-modesetting.c +++ b/src/usb_moded-modesetting.c @@ -358,7 +358,10 @@ int set_dynamic_mode(void) #ifdef APP_SYNC if(data->appsync) if(activate_sync(data->mode_name)) /* returns 1 on error */ + { + log_debug("Appsync failure"); return(1); + } #endif /* make sure things are disabled before changing functionality */ if(data->softconnect_disconnect) @@ -403,6 +406,8 @@ int set_dynamic_mode(void) usb_network_up(data); #endif /* DEBIAN */ } + if(data->appsync) + activate_sync_post(data->mode_name); return(0); } diff --git a/src/usb_moded-network.c b/src/usb_moded-network.c index 975bbb0..5bc5ab9 100644 --- a/src/usb_moded-network.c +++ b/src/usb_moded-network.c @@ -165,6 +165,7 @@ static int write_udhcpd_conf(ipforward_data *ipforward, struct mode_list_elem *d free(ipend); free((char*)ip); fclose(conffile); + log_debug("/etc/udhcpd.conf written.\n"); return(0); }