Skip to content

Commit 1753dbc

Browse files
committed
iiod: Re-create IIO context when receiving USR1 signal
Handle USR1 as a signal that IIOD should re-create the IIO context. This allows support for hot-plugging IIO devices at runtime; the USR1 signal can then be sent from a udev script, for instance. Signed-off-by: Paul Cercueil <[email protected]>
1 parent f5f8422 commit 1753dbc

File tree

3 files changed

+94
-42
lines changed

3 files changed

+94
-42
lines changed

iiod/iiod.c

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
#define _STRINGIFY(x) #x
3838
#define STRINGIFY(x) _STRINGIFY(x)
3939

40+
static int start_iiod(const char *uri, const char *ffs_mountpoint,
41+
const char *uart_params, bool debug, bool interactive,
42+
bool use_aio, uint16_t port, unsigned int nb_pipes,
43+
int ep0_fd);
44+
4045
struct client_data {
4146
int fd;
4247
bool debug;
@@ -131,6 +136,14 @@ static void sig_handler(int sig)
131136
thread_pool_stop(main_thread_pool);
132137
}
133138

139+
static bool restart_usr1;
140+
141+
static void sig_handler_usr1(int sig)
142+
{
143+
restart_usr1 = true;
144+
thread_pool_stop(main_thread_pool);
145+
}
146+
134147
static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio,
135148
const void *xml_zstd, size_t xml_zstd_len)
136149
{
@@ -376,15 +389,12 @@ int main(int argc, char **argv)
376389
long nb_pipes = 3, val;
377390
char *end;
378391
const char *arg = "local:";
379-
struct iio_context *ctx;
380392
int c, option_index = 0;
381393
char *ffs_mountpoint = NULL;
382394
char *uart_params = NULL;
383395
char err_str[1024];
384-
void *xml_zstd;
385-
size_t xml_zstd_len = 0;
386396
uint16_t port = IIOD_PORT;
387-
int ret;
397+
int ret, ep0_fd = 0;
388398

389399
while ((c = getopt_long(argc, argv, "+hVdDiaF:n:s:p:u:",
390400
options, &option_index)) != -1) {
@@ -459,40 +469,79 @@ int main(int argc, char **argv)
459469
}
460470
}
461471

462-
ctx = iio_create_context_from_uri(arg);
463-
464-
if (!ctx) {
472+
main_thread_pool = thread_pool_new();
473+
if (!main_thread_pool) {
465474
iio_strerror(errno, err_str, sizeof(err_str));
466-
IIO_ERROR("Unable to create local context: %s\n", err_str);
475+
IIO_ERROR("Unable to create thread pool: %s\n", err_str);
467476
return EXIT_FAILURE;
468477
}
469478

470-
xml_zstd = get_xml_zstd_data(ctx, &xml_zstd_len);
479+
if (WITH_IIOD_USBD && ffs_mountpoint) {
480+
ret = init_usb_daemon(ffs_mountpoint, nb_pipes);
481+
if (ret < 0) {
482+
iio_strerror(errno, err_str, sizeof(err_str));
483+
IIO_ERROR("Unable to init USB: %s\n", err_str);
471484

472-
main_thread_pool = thread_pool_new();
473-
if (!main_thread_pool) {
474-
iio_strerror(errno, err_str, sizeof(err_str));
475-
IIO_ERROR("Unable to create thread pool: %s\n", err_str);
476-
ret = EXIT_FAILURE;
477-
goto out_destroy_context;
485+
thread_pool_destroy(main_thread_pool);
486+
return EXIT_FAILURE;
487+
}
488+
489+
ep0_fd = ret;
478490
}
479491

480492
set_handler(SIGHUP, sig_handler);
481493
set_handler(SIGPIPE, sig_handler);
482494
set_handler(SIGINT, sig_handler);
483495
set_handler(SIGTERM, sig_handler);
496+
set_handler(SIGUSR1, sig_handler_usr1);
497+
498+
do {
499+
thread_pool_restart(main_thread_pool);
500+
restart_usr1 = false;
501+
502+
ret = start_iiod(arg, ffs_mountpoint, uart_params, debug,
503+
interactive, use_aio, port, nb_pipes, ep0_fd);
504+
} while (!ret && restart_usr1);
505+
506+
thread_pool_destroy(main_thread_pool);
507+
508+
if (WITH_IIOD_USBD && ffs_mountpoint)
509+
close(ep0_fd);
510+
511+
return ret;
512+
}
513+
514+
static int start_iiod(const char *uri, const char *ffs_mountpoint,
515+
const char *uart_params, bool debug, bool interactive,
516+
bool use_aio, uint16_t port, unsigned int nb_pipes,
517+
int ep0_fd)
518+
{
519+
struct iio_context *ctx;
520+
char err_str[1024];
521+
void *xml_zstd;
522+
size_t xml_zstd_len = 0;
523+
int ret;
524+
525+
ctx = iio_create_context_from_uri(uri);
526+
if (!ctx) {
527+
iio_strerror(errno, err_str, sizeof(err_str));
528+
IIO_ERROR("Unable to create local context: %s\n", err_str);
529+
return EXIT_FAILURE;
530+
}
531+
532+
xml_zstd = get_xml_zstd_data(ctx, &xml_zstd_len);
484533

485534
if (WITH_IIOD_USBD && ffs_mountpoint) {
486535
/* We pass use_aio == true directly, this is ensured to be true
487536
* by the CMake script. */
488537
ret = start_usb_daemon(ctx, ffs_mountpoint,
489-
debug, true, (unsigned int) nb_pipes,
538+
debug, true, (unsigned int) nb_pipes, ep0_fd,
490539
main_thread_pool, xml_zstd, xml_zstd_len);
491540
if (ret) {
492541
iio_strerror(-ret, err_str, sizeof(err_str));
493542
IIO_ERROR("Unable to start USB daemon: %s\n", err_str);
494543
ret = EXIT_FAILURE;
495-
goto out_destroy_thread_pool;
544+
goto out_free_xml_data;
496545
}
497546
}
498547

@@ -504,7 +553,7 @@ int main(int argc, char **argv)
504553
iio_strerror(-ret, err_str, sizeof(err_str));
505554
IIO_ERROR("Unable to start serial daemon: %s\n", err_str);
506555
ret = EXIT_FAILURE;
507-
goto out_destroy_thread_pool;
556+
goto out_thread_pool_stop;
508557
}
509558
}
510559

@@ -513,16 +562,13 @@ int main(int argc, char **argv)
513562
else
514563
ret = main_server(ctx, debug, xml_zstd, xml_zstd_len, port);
515564

565+
out_thread_pool_stop:
516566
/*
517567
* In case we got here through an error in the main thread make sure all
518568
* the worker threads are signaled to shutdown.
519569
*/
520-
521-
out_destroy_thread_pool:
522570
thread_pool_stop_and_wait(main_thread_pool);
523-
thread_pool_destroy(main_thread_pool);
524-
525-
out_destroy_context:
571+
out_free_xml_data:
526572
free(xml_zstd);
527573
iio_context_destroy(ctx);
528574

iiod/ops.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,10 @@ void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose,
9292
bool is_socket, bool is_usb, bool use_aio, struct thread_pool *pool,
9393
const void *xml_zstd, size_t xml_zstd_len);
9494

95+
int init_usb_daemon(const char *ffs, unsigned int nb_pipes);
9596
int start_usb_daemon(struct iio_context *ctx, const char *ffs,
9697
bool debug, bool use_aio, unsigned int nb_pipes,
97-
struct thread_pool *pool,
98+
int ep0_fd, struct thread_pool *pool,
9899
const void *xml_zstd, size_t xml_zstd_len);
99100
int start_serial_daemon(struct iio_context *ctx, const char *uart_params,
100101
bool debug, struct thread_pool *pool,

iiod/usbd.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ static void usbd_main(struct thread_pool *pool, void *d)
217217
thread_pool_destroy(pdata->pool[i]);
218218
}
219219

220-
close(pdata->ep0_fd);
221220
free(pdata->ffs);
222221
free(pdata->pool);
223222
free(pdata);
@@ -328,14 +327,34 @@ static int write_header(int fd, unsigned int nb_pipes)
328327
return 0;
329328
}
330329

330+
int init_usb_daemon(const char *ffs, unsigned int nb_pipes)
331+
{
332+
char buf[256];
333+
int ep0_fd, ret;
334+
335+
snprintf(buf, sizeof(buf), "%s/ep0", ffs);
336+
337+
ep0_fd = open(buf, O_RDWR);
338+
if (ep0_fd < 0) {
339+
return -errno;
340+
}
341+
342+
ret = write_header(ep0_fd, nb_pipes);
343+
if (ret < 0) {
344+
close(ep0_fd);
345+
return ret;
346+
}
347+
348+
return ep0_fd;
349+
}
350+
331351
int start_usb_daemon(struct iio_context *ctx, const char *ffs,
332352
bool debug, bool use_aio, unsigned int nb_pipes,
333-
struct thread_pool *pool,
353+
int ep0_fd, struct thread_pool *pool,
334354
const void *xml_zstd, size_t xml_zstd_len)
335355
{
336356
struct usbd_pdata *pdata;
337357
unsigned int i;
338-
char buf[256];
339358
int ret;
340359

341360
pdata = zalloc(sizeof(*pdata));
@@ -356,18 +375,6 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs,
356375
goto err_free_pdata_pool;
357376
}
358377

359-
snprintf(buf, sizeof(buf), "%s/ep0", ffs);
360-
361-
pdata->ep0_fd = open(buf, O_RDWR);
362-
if (pdata->ep0_fd < 0) {
363-
ret = -errno;
364-
goto err_free_ffs;
365-
}
366-
367-
ret = write_header(pdata->ep0_fd, nb_pipes);
368-
if (ret < 0)
369-
goto err_close_ep0;
370-
371378
for (i = 0; i < nb_pipes; i++) {
372379
pdata->pool[i] = thread_pool_new();
373380
if (!pdata->pool[i]) {
@@ -381,6 +388,7 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs,
381388
pdata->use_aio = use_aio;
382389
pdata->xml_zstd = xml_zstd;
383390
pdata->xml_zstd_len = xml_zstd_len;
391+
pdata->ep0_fd = ep0_fd;
384392

385393
ret = thread_pool_add_thread(pool, usbd_main, pdata, "usbd_main_thd");
386394
if (!ret)
@@ -393,9 +401,6 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs,
393401
if (pdata->pool[i])
394402
thread_pool_destroy(pdata->pool[i]);
395403
}
396-
err_close_ep0:
397-
close(pdata->ep0_fd);
398-
err_free_ffs:
399404
free(pdata->ffs);
400405
err_free_pdata_pool:
401406
free(pdata->pool);

0 commit comments

Comments
 (0)