Re: [Nbd] [PATCH 3/5] nbd-server: fix setup_serve() to report errors
- To: Tuomas Jorma Juhani Räsänen <tuomasjjrasanen@...1258...>
- Cc: nbd-general@lists.sourceforge.net
- Subject: Re: [Nbd] [PATCH 3/5] nbd-server: fix setup_serve() to report errors
- From: Wouter Verhelst <w@...112...>
- Date: Sat, 12 Jan 2013 12:43:15 +0100
- Message-id: <20130112114315.GP25658@...3...>
- In-reply-to: <20130111215421.GA5556@...1259...>
- References: <20130111215421.GA5556@...1259...>
On Fri, Jan 11, 2013 at 11:54:21PM +0200, Tuomas Jorma Juhani Räsänen wrote:
> This commit changes setup_serve() to report its errors via GError object
> to its caller. It also add resource deallocation code to return points
> to free all local resources correctly. Note that, the previous version
> of the setup_serve() did not free its resources properly on error, but
> just called functions which terminated the process. This was techincally
> a leak, but without any practical significance due to immediate process
> termination. However, now that error handling (process termination) is
> separeted from error reporting, we must deallocate/free all locally
> allocated resources correctly on errors.
>
> Signed-off-by: Tuomas Jorma Juhani Räsänen <tuomasjjrasanen@...1261...>
> ---
> nbd-server.c | 73 +++++++++++++++++++++++++++++++++++++++++++---------------
> 1 file changed, 54 insertions(+), 19 deletions(-)
>
> diff --git a/nbd-server.c b/nbd-server.c
> index 87f63fc..be65ebb 100644
> --- a/nbd-server.c
> +++ b/nbd-server.c
> @@ -2392,12 +2392,11 @@ int dosockopts(const int socket, GError **const gerror) {
> *
> * @param serve the server we want to connect.
> **/
> -int setup_serve(SERVER *serve) {
> +int setup_serve(SERVER *const serve, GError **const gerror) {
> struct addrinfo hints;
> struct addrinfo *ai = NULL;
> gchar *port = NULL;
> int e;
> - GError *gerror = NULL;
>
> /* Without this, it's possible that socket == 0, even if it's
> * not initialized at all. And that would be wrong because 0 is
> @@ -2432,10 +2431,12 @@ int setup_serve(SERVER *serve) {
> g_free(port);
>
> if(e != 0) {
> - fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(e));
> - serve->socket = -1;
> - freeaddrinfo(ai);
> - exit(EXIT_FAILURE);
> + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_GAI,
> + "failed to open an export socket: "
> + "failed to get address info: %s",
> + gai_strerror(e));
> + freeaddrinfo(ai);
> + return -1;
> }
Same here, obviously.
> if(serve->socket_family == AF_UNSPEC)
> @@ -2449,23 +2450,46 @@ int setup_serve(SERVER *serve) {
> ai->ai_family = AF_INET6_SDP;
> }
> #endif
> - if ((serve->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
> - err("socket: %m");
> -
> - if (dosockopts(serve->socket, &gerror) == -1) {
> - msg(LOG_ERR, "failed to open export-specific socket: %s",
> - gerror->message);
> - g_clear_error(&gerror);
> - exit(EXIT_FAILURE);
> + if ((serve->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
> + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_SOCKET,
> + "failed to open an export socket: "
> + "failed to create a socket: %s",
> + strerror(errno));
> + freeaddrinfo(ai);
> + return -1;
> + }
> +
> + if (dosockopts(serve->socket, gerror) == -1) {
> + g_prefix_error(gerror, "failed to open an export socket: ");
> + close(serve->socket);
> + serve->socket = -1;
> + freeaddrinfo(ai);
> + return -1;
> }
>
> DEBUG("Waiting for connections... bind, ");
> e = bind(serve->socket, ai->ai_addr, ai->ai_addrlen);
> - if (e != 0 && errno != EADDRINUSE)
> - err("bind: %m");
> + if (e != 0 && errno != EADDRINUSE) {
> + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_BIND,
> + "failed to open an export socket: "
> + "failed to bind an address to a socket: %s",
> + strerror(errno));
> + close(serve->socket);
> + serve->socket = -1;
> + freeaddrinfo(ai);
> + return -1;
> + }
> DEBUG("listen, ");
> - if (listen(serve->socket, 1) < 0)
> - err("listen: %m");
> + if (listen(serve->socket, 1) < 0) {
> + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_BIND,
> + "failed to open an export socket: "
> + "failed to start listening on a socket: %s",
> + strerror(errno));
> + close(serve->socket);
> + serve->socket = -1;
> + freeaddrinfo(ai);
> + return -1;
> + }
>
> freeaddrinfo (ai);
> if(serve->servename) {
> @@ -2551,7 +2575,18 @@ void setup_servers(GArray *const servers, const gchar *const modernaddr,
> int want_modern=0;
>
> for(i=0;i<servers->len;i++) {
> - want_modern |= setup_serve(&(g_array_index(servers, SERVER, i)));
> + GError *gerror = NULL;
> + SERVER *server = &g_array_index(servers, SERVER, i);
> + int ret;
> +
> + ret = setup_serve(server, &gerror);
> + if (ret == -1) {
> + msg(LOG_ERR, "failed to setup servers: %s",
> + gerror->message);
> + g_clear_error(&gerror);
> + exit(EXIT_FAILURE);
> + }
> + want_modern |= ret;
> }
> if(want_modern) {
> GError *gerror = NULL;
> --
> 1.7.10.4
>
>
> ------------------------------------------------------------------------------
> Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and
> much more. Get web development skills now with LearnDevNow -
> 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
> SALE $99.99 this month only -- learn more at:
> http://p.sf.net/sfu/learnmore_122812
> _______________________________________________
> Nbd-general mailing list
> Nbd-general@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nbd-general
--
Copyshops should do vouchers. So that next time some bureaucracy requires you
to mail a form in triplicate, you can mail it just once, add a voucher, and
save on postage.
Reply to: