[ovs-dev] [bug14616 2/5] worker: Do not use poll_block() in worker_send_iovec().

Ethan Jackson ethan at nicira.com
Fri Jan 11 01:31:17 UTC 2013


Acked-by: Ethan Jackson <ethan at nicira.com>


On Thu, Jan 10, 2013 at 5:23 PM, Ben Pfaff <blp at nicira.com> wrote:

> The following call stack was possible:
>
>     poll_block()
>         -> vlog
>             -> worker_send_iovec()
>                 -> poll_block()
>
> which caused corruption because poll_block() is not reentrant.
>
> Bug #14616.
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
>  lib/worker.c |   20 +++++++++++++++++---
>  1 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/lib/worker.c b/lib/worker.c
> index f2b896e..b281d70 100644
> --- a/lib/worker.c
> +++ b/lib/worker.c
> @@ -1,4 +1,4 @@
> -/* Copyright (c) 2012 Nicira, Inc.
> +/* Copyright (c) 2012, 2013 Nicira, Inc.
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -198,6 +198,7 @@ worker_send_iovec(const struct iovec iovs[], size_t
> n_iovs,
>      size_t sent = 0;
>
>      for (;;) {
> +        struct pollfd pfd;
>          int error;
>
>          /* Try to send the rest of the request. */
> @@ -210,8 +211,21 @@ worker_send_iovec(const struct iovec iovs[], size_t
> n_iovs,
>          /* Process replies to avoid deadlock. */
>          worker_run();
>
> -        poll_fd_wait(client_sock, POLLIN | POLLOUT);
> -        poll_block();
> +        /* Wait for 'client_sock' to become ready before trying again.  We
> +         * can't use poll_block() because it sometimes calls into vlog,
> which
> +         * calls indirectly into worker_send_iovec().  To be usable here,
> +         * poll_block() would therefore need to be reentrant, but it isn't
> +         * (calling it recursively causes memory corruption and an
> eventual
> +         * crash). */
> +        pfd.fd = client_sock;
> +        pfd.events = POLLIN | POLLOUT;
> +        do {
> +            error = poll(&pfd, 1, -1) < 0 ? errno : 0;
> +        } while (error == EINTR);
> +        if (error) {
> +            worker_broke();
> +            VLOG_ABORT("poll failed (%s)", strerror(error));
> +        }
>      }
>  }
>
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openvswitch.org/pipermail/ovs-dev/attachments/20130110/14519728/attachment-0003.html>


More information about the dev mailing list