Skip to content

Commit

Permalink
iiod: Make startup (with Avahi) more robust.
Browse files Browse the repository at this point in the history
In certain embedded cases, iiod may start before networking or dbus is
fully alive on a system (like on Pluto and M2k).

This change ensures that when we are trying to connect to avahi, and
register on the network, we give things a few moments to stablize (re-trying)
before we fail.

tested on PlutoSDR, and Zedboard + FMCOMMS3

Signed-off-by: Robin Getz <[email protected]>
  • Loading branch information
rgetz committed Jun 9, 2020
1 parent 3cc5382 commit 6bbf792
Showing 1 changed file with 82 additions and 30 deletions.
112 changes: 82 additions & 30 deletions iiod/iiod.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,14 @@ static void __avahi_client_cb(AvahiClient *client,
create_services(client);
break;
case AVAHI_CLIENT_FAILURE:
IIO_ERROR("Avahi: Client failure: %s\n",
if (avahi_client_errno(client) != AVAHI_ERR_DISCONNECTED) {
IIO_ERROR("Avahi: Client failure: %s\n",
avahi_strerror(avahi_client_errno(client)));
client_free();
break;
}
IIO_INFO("Avahi: server disconnected\n");
avahi_client_free(client);
avahi.group = NULL;
avahi.client = client_new();
break;
case AVAHI_CLIENT_S_COLLISION:
Expand Down Expand Up @@ -253,8 +258,10 @@ static AvahiClient * client_new(void)
AvahiClient * client;

client = avahi_client_new(avahi_threaded_poll_get(avahi.poll),
0, __avahi_client_cb, NULL, &ret);
if (!client) {
AVAHI_CLIENT_NO_FAIL, __avahi_client_cb, NULL, &ret);

/* No Daemon is handled by the avahi_start thread */
if (!client && ret != AVAHI_ERR_NO_DAEMON) {
IIO_ERROR("Avahi: failure creating client: %s (%d)\n",
avahi_strerror(ret), ret);
}
Expand Down Expand Up @@ -322,41 +329,90 @@ static void create_services(AvahiClient *c)

#define IIOD_ON "iiod on "

static int start_avahi(void)
static void start_avahi_thd(struct thread_pool *pool, void *d)
{

struct pollfd pfd[2];
int ret = ENOMEM;
char label[AVAHI_LABEL_MAX];
char host[AVAHI_LABEL_MAX - sizeof(IIOD_ON)];
struct timespec ts;
ts.tv_nsec = 0;
ts.tv_sec = 1;

pfd[1].fd = thread_pool_get_poll_fd(main_thread_pool);
pfd[1].events = POLLIN;
pfd[1].revents = 0;

while(true) {
if (pfd[1].revents & POLLIN) /* STOP event */
break;

ret = gethostname(host, sizeof(host));
IIO_ERROR("host %s\n", host);
if (ret || !strncmp(host, "none", sizeof("none") - 1))
goto again;

ret = gethostname(host, sizeof(host));
if (!ret) {
iio_snprintf(label, sizeof(label), "%s%s", IIOD_ON, host);
} else {
iio_snprintf(label, sizeof(label), "iiod");
}

avahi.name = avahi_strdup(label);
if (!avahi.name)
return -ENOMEM;
if (!avahi.name)
avahi.name = avahi_strdup(label);
if (!avahi.name)
break;

avahi.poll = avahi_threaded_poll_new();
if (!avahi.poll) {
shutdown_avahi();
return -ENOMEM;
if (!avahi.poll)
avahi.poll = avahi_threaded_poll_new();
if (!avahi.poll) {
goto again;
}

if (!avahi.client)
avahi.client = client_new();
if (avahi.client)
break;
again:
IIO_INFO("Avahi didn't start, try again later\n");
nanosleep(&ts, NULL);
ts.tv_sec++;
/* If it hasn't started in 10 times over 60 seconds,
* it is not going to, so stop
*/
if (ts.tv_sec >= 11)
break;
}

avahi.client = client_new();
if (!avahi.client) {
if (avahi.client && avahi.poll) {
avahi_threaded_poll_start(avahi.poll);
IIO_INFO("Avahi: Started.\n");
} else {
shutdown_avahi();
return -ENOMEM;
IIO_INFO("Avahi: Failed to start.\n");
}
}

static void start_avahi(void)
{
int ret;
char err_str[1024];

avahi_threaded_poll_start(avahi.poll);
IIO_INFO("Avahi: Started.\n");
IIO_INFO("Attempting to start Avahi\n");

return 0;
}
avahi.poll = NULL;
avahi.client = NULL;
avahi.group = NULL;
avahi.name = NULL;

/* In case dbus, or avahi deamon are not started, we create a thread
* that tries a few times to attach, if it can't within the first
* minute, it gives up.
*/
ret = thread_pool_add_thread(main_thread_pool, start_avahi_thd, NULL, "avahi_thd");
if (ret) {
iio_strerror(ret, err_str, sizeof(err_str));
IIO_ERROR("Failed to create new Avahi thread: %s\n",
err_str);
}
}
static void stop_avahi(void)
{
shutdown_avahi();
Expand Down Expand Up @@ -441,9 +497,6 @@ static int main_server(struct iio_context *ctx, bool debug)
struct pollfd pfd[2];
char err_str[1024];
bool ipv6;
#ifdef HAVE_AVAHI
bool avahi_started;
#endif

IIO_INFO("Starting IIO Daemon version %u.%u.%s\n",
LIBIIO_VERSION_MAJOR, LIBIIO_VERSION_MINOR,
Expand Down Expand Up @@ -490,7 +543,7 @@ static int main_server(struct iio_context *ctx, bool debug)
}

#ifdef HAVE_AVAHI
avahi_started = !start_avahi();
start_avahi();
#endif

pfd[0].fd = fd;
Expand Down Expand Up @@ -580,8 +633,7 @@ static int main_server(struct iio_context *ctx, bool debug)

IIO_DEBUG("Cleaning up\n");
#ifdef HAVE_AVAHI
if (avahi_started)
stop_avahi();
stop_avahi();
#endif
close(fd);
return EXIT_SUCCESS;
Expand Down

0 comments on commit 6bbf792

Please sign in to comment.