diff --git a/iiod/iiod.c b/iiod/iiod.c index 3478126ca..2cdf0356a 100644 --- a/iiod/iiod.c +++ b/iiod/iiod.c @@ -37,6 +37,11 @@ #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) +static int start_iiod(const char *uri, const char *ffs_mountpoint, + const char *uart_params, bool debug, bool interactive, + bool use_aio, uint16_t port, unsigned int nb_pipes, + int ep0_fd); + struct client_data { int fd; bool debug; @@ -131,6 +136,14 @@ static void sig_handler(int sig) thread_pool_stop(main_thread_pool); } +static bool restart_usr1; + +static void sig_handler_usr1(int sig) +{ + restart_usr1 = true; + thread_pool_stop(main_thread_pool); +} + static int main_interactive(struct iio_context *ctx, bool verbose, bool use_aio, const void *xml_zstd, size_t xml_zstd_len) { @@ -376,15 +389,12 @@ int main(int argc, char **argv) long nb_pipes = 3, val; char *end; const char *arg = "local:"; - struct iio_context *ctx; int c, option_index = 0; char *ffs_mountpoint = NULL; char *uart_params = NULL; char err_str[1024]; - void *xml_zstd; - size_t xml_zstd_len = 0; uint16_t port = IIOD_PORT; - int ret; + int ret, ep0_fd = 0; while ((c = getopt_long(argc, argv, "+hVdDiaF:n:s:p:u:", options, &option_index)) != -1) { @@ -459,40 +469,79 @@ int main(int argc, char **argv) } } - ctx = iio_create_context_from_uri(arg); - - if (!ctx) { + main_thread_pool = thread_pool_new(); + if (!main_thread_pool) { iio_strerror(errno, err_str, sizeof(err_str)); - IIO_ERROR("Unable to create local context: %s\n", err_str); + IIO_ERROR("Unable to create thread pool: %s\n", err_str); return EXIT_FAILURE; } - xml_zstd = get_xml_zstd_data(ctx, &xml_zstd_len); + if (WITH_IIOD_USBD && ffs_mountpoint) { + ret = init_usb_daemon(ffs_mountpoint, nb_pipes); + if (ret < 0) { + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Unable to init USB: %s\n", err_str); - main_thread_pool = thread_pool_new(); - if (!main_thread_pool) { - iio_strerror(errno, err_str, sizeof(err_str)); - IIO_ERROR("Unable to create thread pool: %s\n", err_str); - ret = EXIT_FAILURE; - goto out_destroy_context; + thread_pool_destroy(main_thread_pool); + return EXIT_FAILURE; + } + + ep0_fd = ret; } set_handler(SIGHUP, sig_handler); set_handler(SIGPIPE, sig_handler); set_handler(SIGINT, sig_handler); set_handler(SIGTERM, sig_handler); + set_handler(SIGUSR1, sig_handler_usr1); + + do { + thread_pool_restart(main_thread_pool); + restart_usr1 = false; + + ret = start_iiod(arg, ffs_mountpoint, uart_params, debug, + interactive, use_aio, port, nb_pipes, ep0_fd); + } while (!ret && restart_usr1); + + thread_pool_destroy(main_thread_pool); + + if (WITH_IIOD_USBD && ffs_mountpoint) + close(ep0_fd); + + return ret; +} + +static int start_iiod(const char *uri, const char *ffs_mountpoint, + const char *uart_params, bool debug, bool interactive, + bool use_aio, uint16_t port, unsigned int nb_pipes, + int ep0_fd) +{ + struct iio_context *ctx; + char err_str[1024]; + void *xml_zstd; + size_t xml_zstd_len = 0; + int ret; + + ctx = iio_create_context_from_uri(uri); + if (!ctx) { + iio_strerror(errno, err_str, sizeof(err_str)); + IIO_ERROR("Unable to create local context: %s\n", err_str); + return EXIT_FAILURE; + } + + xml_zstd = get_xml_zstd_data(ctx, &xml_zstd_len); if (WITH_IIOD_USBD && ffs_mountpoint) { /* We pass use_aio == true directly, this is ensured to be true * by the CMake script. */ ret = start_usb_daemon(ctx, ffs_mountpoint, - debug, true, (unsigned int) nb_pipes, + debug, true, (unsigned int) nb_pipes, ep0_fd, main_thread_pool, xml_zstd, xml_zstd_len); if (ret) { iio_strerror(-ret, err_str, sizeof(err_str)); IIO_ERROR("Unable to start USB daemon: %s\n", err_str); ret = EXIT_FAILURE; - goto out_destroy_thread_pool; + goto out_free_xml_data; } } @@ -504,7 +553,7 @@ int main(int argc, char **argv) iio_strerror(-ret, err_str, sizeof(err_str)); IIO_ERROR("Unable to start serial daemon: %s\n", err_str); ret = EXIT_FAILURE; - goto out_destroy_thread_pool; + goto out_thread_pool_stop; } } @@ -513,16 +562,13 @@ int main(int argc, char **argv) else ret = main_server(ctx, debug, xml_zstd, xml_zstd_len, port); +out_thread_pool_stop: /* * In case we got here through an error in the main thread make sure all * the worker threads are signaled to shutdown. */ - -out_destroy_thread_pool: thread_pool_stop_and_wait(main_thread_pool); - thread_pool_destroy(main_thread_pool); - -out_destroy_context: +out_free_xml_data: free(xml_zstd); iio_context_destroy(ctx); diff --git a/iiod/ops.h b/iiod/ops.h index add7437b1..d03eee44f 100644 --- a/iiod/ops.h +++ b/iiod/ops.h @@ -92,9 +92,10 @@ void interpreter(struct iio_context *ctx, int fd_in, int fd_out, bool verbose, bool is_socket, bool is_usb, bool use_aio, struct thread_pool *pool, const void *xml_zstd, size_t xml_zstd_len); +int init_usb_daemon(const char *ffs, unsigned int nb_pipes); int start_usb_daemon(struct iio_context *ctx, const char *ffs, bool debug, bool use_aio, unsigned int nb_pipes, - struct thread_pool *pool, + int ep0_fd, struct thread_pool *pool, const void *xml_zstd, size_t xml_zstd_len); int start_serial_daemon(struct iio_context *ctx, const char *uart_params, bool debug, struct thread_pool *pool, diff --git a/iiod/usbd.c b/iiod/usbd.c index 3385f5b53..93889ccfc 100644 --- a/iiod/usbd.c +++ b/iiod/usbd.c @@ -217,7 +217,6 @@ static void usbd_main(struct thread_pool *pool, void *d) thread_pool_destroy(pdata->pool[i]); } - close(pdata->ep0_fd); free(pdata->ffs); free(pdata->pool); free(pdata); @@ -328,14 +327,34 @@ static int write_header(int fd, unsigned int nb_pipes) return 0; } +int init_usb_daemon(const char *ffs, unsigned int nb_pipes) +{ + char buf[256]; + int ep0_fd, ret; + + snprintf(buf, sizeof(buf), "%s/ep0", ffs); + + ep0_fd = open(buf, O_RDWR); + if (ep0_fd < 0) { + return -errno; + } + + ret = write_header(ep0_fd, nb_pipes); + if (ret < 0) { + close(ep0_fd); + return ret; + } + + return ep0_fd; +} + int start_usb_daemon(struct iio_context *ctx, const char *ffs, bool debug, bool use_aio, unsigned int nb_pipes, - struct thread_pool *pool, + int ep0_fd, struct thread_pool *pool, const void *xml_zstd, size_t xml_zstd_len) { struct usbd_pdata *pdata; unsigned int i; - char buf[256]; int ret; pdata = zalloc(sizeof(*pdata)); @@ -356,18 +375,6 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs, goto err_free_pdata_pool; } - snprintf(buf, sizeof(buf), "%s/ep0", ffs); - - pdata->ep0_fd = open(buf, O_RDWR); - if (pdata->ep0_fd < 0) { - ret = -errno; - goto err_free_ffs; - } - - ret = write_header(pdata->ep0_fd, nb_pipes); - if (ret < 0) - goto err_close_ep0; - for (i = 0; i < nb_pipes; i++) { pdata->pool[i] = thread_pool_new(); if (!pdata->pool[i]) { @@ -381,6 +388,7 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs, pdata->use_aio = use_aio; pdata->xml_zstd = xml_zstd; pdata->xml_zstd_len = xml_zstd_len; + pdata->ep0_fd = ep0_fd; ret = thread_pool_add_thread(pool, usbd_main, pdata, "usbd_main_thd"); if (!ret) @@ -393,9 +401,6 @@ int start_usb_daemon(struct iio_context *ctx, const char *ffs, if (pdata->pool[i]) thread_pool_destroy(pdata->pool[i]); } -err_close_ep0: - close(pdata->ep0_fd); -err_free_ffs: free(pdata->ffs); err_free_pdata_pool: free(pdata->pool);