From: Roman Khabibov <roman.habibov@tarantool.org> To: Sergey Ostanevich <sergos@tarantool.org> Cc: tarantool-patches@dev.tarantool.org, alexander.turenko@tarantool.org Subject: Re: [Tarantool-patches] [PATCH v2 1/2] coio/say: fix getaddrinfo error handling on macOS Date: Tue, 23 Jun 2020 16:27:18 +0300 [thread overview] Message-ID: <D47B8B9E-7694-4060-903C-C5492ED0D305@tarantool.org> (raw) In-Reply-To: <20200417093736.GB3110@tarantool.org> Hi! I decided to stay diag_log() as it is. I tried to use new diag_add() from the stacked diagnostics patch, but it don’t log this error. We have to log this error to print error message from getaddrinfo after panic with “say”. See the following reproducer: tarantool> socket = require('socket') --- ... tarantool> log = require('log') --- ... tarantool> fio = require('fio') --- ... tarantool> --- ... tarantool> path = fio.pathjoin(fio.cwd(), 'log_unix_socket_test.sock') --- ... tarantool> unix_socket = socket('AF_UNIX', 'SOCK_DGRAM', 0) --- ... tarantool> unix_socket:bind('unix/', path) --- - false ... tarantool> --- ... tarantool> opt = string.format("syslog:server=non_exists_hostname:%s,identity=tarantool", path) --- ... tarantool> box.cfg{log = opt, log_nonblock=true} SystemError getaddrinfo: nodename nor servname provided, or not known: Input/output error SystemError syslog logger: Input/output error: Input/output error failed to initialize logging subsystem If we remove diag_log(), we will lose getaddrinfo error in the log after panic. I didn’t add it to test, because once upon a time with Vova we decided that panic is hard to test, and it's not worth it. > On Apr 17, 2020, at 12:37, Sergey Ostanevich <sergos@tarantool.org> wrote: > >>>> Note: diag_log() in say.c was added, because otherwise it will be >>>> hid by the following diagnostic and it should be handled in a >>>> better way after #1148. Also, two diag_set() in >>> Please, notify owner of #1148 about follow-up that will be needed. >>> > > As I can see from #1148 comments, it is already closed. Can you address > the problem now with a new gh issue? > > Otherwise LGTM. > > Sergos > >>>> syslog_connect_unix() was added to avoid asserts in this >>>> diag_log(). >>>> >>>> Need for #4138 >>>> --- >>>> src/lib/core/coio_task.c | 2 +- >>>> src/lib/core/say.c | 12 ++++++++++-- >>>> test/unit/coio.cc | 29 ++++++++++++++++++++++++++++- >>>> test/unit/coio.result | 4 +++- >>>> 4 files changed, 42 insertions(+), 5 deletions(-) >>>> >>>> diff --git a/src/lib/core/coio_task.c b/src/lib/core/coio_task.c >>>> index 908b336ed..83f669d05 100644 >>>> --- a/src/lib/core/coio_task.c >>>> +++ b/src/lib/core/coio_task.c >>>> @@ -413,7 +413,7 @@ coio_getaddrinfo(const char *host, const char *port, >>>> return -1; /* timed out or cancelled */ >>>> >>>> /* Task finished */ >>>> - if (task->rc < 0) { >>>> + if (task->rc != 0) { >>>> /* getaddrinfo() failed */ >>>> errno = EIO; >>>> diag_set(SystemError, "getaddrinfo: %s", >>>> diff --git a/src/lib/core/say.c b/src/lib/core/say.c >>>> index 64a637c58..8ad88ad57 100644 >>>> --- a/src/lib/core/say.c >>>> +++ b/src/lib/core/say.c >>>> @@ -459,14 +459,17 @@ static inline int >>>> syslog_connect_unix(const char *path) >>>> { >>>> int fd = socket(PF_UNIX, SOCK_DGRAM, 0); >>>> - if (fd < 0) >>>> + if (fd < 0) { >>>> + diag_set(SystemError, "socket"); >>> This error message gives nothing. Please, describe the error behind it >>> using the strerror(errno) >>>> return -1; >>>> + } >>>> struct sockaddr_un un; >>>> memset(&un, 0, sizeof(un)); >>>> snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); >>>> un.sun_family = AF_UNIX; >>>> if (connect(fd, (struct sockaddr *) &un, sizeof(un)) != 0) { >>>> close(fd); >>>> + diag_set(SystemError, "connect"); >>> Ditto. >> @@ -465,13 +465,16 @@ static inline int >> syslog_connect_unix(const char *path) >> { >> int fd = socket(PF_UNIX, SOCK_DGRAM, 0); >> - if (fd < 0) >> + if (fd < 0) { >> + diag_set(SystemError, strerror(errno)); >> return -1; >> + } >> struct sockaddr_un un; >> memset(&un, 0, sizeof(un)); >> snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); >> un.sun_family = AF_UNIX; >> if (connect(fd, (struct sockaddr *) &un, sizeof(un)) != 0) { >> + diag_set(SystemError, strerror(errno)); >> close(fd); >> return -1; >> } >> >>>> return -1; >>>> } >>>> return fd; >>>> @@ -506,7 +509,7 @@ syslog_connect_remote(const char *server_address) >>>> hints.ai_protocol = IPPROTO_UDP; >>>> >>>> ret = getaddrinfo(remote, portnum, &hints, &inf); >>>> - if (ret < 0) { >>>> + if (ret != 0) { >>>> errno = EIO; >>>> diag_set(SystemError, "getaddrinfo: %s", >>>> gai_strerror(ret)); >>>> @@ -593,6 +596,11 @@ log_syslog_init(struct log *log, const char *init_str) >>>> say_free_syslog_opts(&opts); >>>> log->fd = log_syslog_connect(log); >>>> if (log->fd < 0) { >>>> + /* >>>> + * We need to log a diagnostics here until stacked >>>> + * diagnostics will be implemented (#1148). >>>> + */ >>>> + diag_log(); >>> Make a poniter about this in #1148 >> Ok. >> >>>> /* syslog indent is freed in atexit(). */ >>>> diag_set(SystemError, "syslog logger: %s", strerror(errno)); >>>> return -1; >>>> diff --git a/test/unit/coio.cc b/test/unit/coio.cc >>>> index bb8bd7131..957c58ede 100644 >>>> --- a/test/unit/coio.cc >>>> +++ b/test/unit/coio.cc >>>> @@ -72,7 +72,7 @@ static void >>>> test_getaddrinfo(void) >>>> { >>>> header(); >>>> - plan(1); >>>> + plan(3); >>>> const char *host = "127.0.0.1"; >>>> const char *port = "3333"; >>>> struct addrinfo *i; >>>> @@ -81,6 +81,33 @@ test_getaddrinfo(void) >>>> is(rc, 0, "getaddrinfo"); >>>> freeaddrinfo(i); >>>> >>>> + /* >>>> + * gh-4138: Check getaddrinfo() retval and diagnostics >>>> + * area. >>>> + */ >>>> + rc = coio_getaddrinfo("non_exists_hostname", port, NULL, &i, >>>> + 15768000000); >>>> + isnt(rc, 0, "getaddrinfo retval"); >>>> + const char *errmsg = diag_get()->last->errmsg; >>>> + const char *exp_errmsg_1 = "getaddrinfo: nodename nor servname provided" >>>> + ", or not known"; >>>> + const char *exp_errmsg_2 = "getaddrinfo: Servname not supported for " >>>> + "ai_socktype"; >>>> + const char *exp_errmsg_3 = "getaddrinfo: Name or service not known"; >>>> + const char *exp_errmsg_4 = "getaddrinfo: hostname nor servname provided" >>>> + ", or not known"; >>>> + const char *exp_errmsg_5 = "getaddrinfo: Temporary failure in name " >>>> + "resolution"; >>>> + const char *exp_errmsg_6 = "getaddrinfo: Name could not be resolved at " >>>> + "this time"; >>>> + bool is_match_with_exp = strcmp(errmsg, exp_errmsg_1) == 0 || >>>> + strcmp(errmsg, exp_errmsg_2) == 0 || >>>> + strcmp(errmsg, exp_errmsg_3) == 0 || >>>> + strcmp(errmsg, exp_errmsg_4) == 0 || >>>> + strcmp(errmsg, exp_errmsg_5) == 0 || >>>> + strcmp(errmsg, exp_errmsg_6) == 0; >>>> + is(is_match_with_exp, true, "getaddrinfo error message"); >>>> + >>> Why did you made such a test - you're not sure which one will be >>> triggered? Can you create a test that will check all possible errors? >> See Alexander answer. I added comments about the constants. >> >>>> /* >>>> * gh-4209: 0 timeout should not be a special value and >>>> * detach a task. Before a fix it led to segfault >>>> diff --git a/test/unit/coio.result b/test/unit/coio.result >>>> index 5019fa48a..90b567140 100644 >>>> --- a/test/unit/coio.result >>>> +++ b/test/unit/coio.result >>>> @@ -7,6 +7,8 @@ >>>> # call done with res 0 >>>> *** test_call_f: done *** >>>> *** test_getaddrinfo *** >>>> -1..1 >>>> +1..3 >>>> ok 1 - getaddrinfo >>>> +ok 2 - getaddrinfo retval >>>> +ok 3 - getaddrinfo error message >>>> *** test_getaddrinfo: done *** >>>> -- >>>> 2.21.0 (Apple Git-122) >> >> commit f17e3e73ae2689dd2ec1dcd94d699636f19f93a5 >> Author: Roman Khabibov <roman.habibov@tarantool.org> >> Date: Tue Jul 30 15:39:21 2019 +0300 >> >> coio/say: fix getaddrinfo error handling on macOS >> >> Before this patch, branch when getaddrinfo() returns error codes >> couldn't be reached on macOS, because they are greater than 0 on >> macOS (assumption "rc < 0" in commit ea1da04 is incorrect for >> macOS). >> >> Note: diag_log() in say.c was added, because otherwise it will be >> hid by the following diagnostic and it should be handled in a >> better way after #1148. Also, two diag_set() in >> syslog_connect_unix() was added to avoid asserts in this >> diag_log(). >> >> Need for #4138 >> >> diff --git a/src/lib/core/coio_task.c b/src/lib/core/coio_task.c >> index 908b336ed..83f669d05 100644 >> --- a/src/lib/core/coio_task.c >> +++ b/src/lib/core/coio_task.c >> @@ -413,7 +413,7 @@ coio_getaddrinfo(const char *host, const char *port, >> return -1; /* timed out or cancelled */ >> >> /* Task finished */ >> - if (task->rc < 0) { >> + if (task->rc != 0) { >> /* getaddrinfo() failed */ >> errno = EIO; >> diag_set(SystemError, "getaddrinfo: %s", >> diff --git a/src/lib/core/say.c b/src/lib/core/say.c >> index dd05285a6..0f8db4587 100644 >> --- a/src/lib/core/say.c >> +++ b/src/lib/core/say.c >> @@ -465,13 +465,16 @@ static inline int >> syslog_connect_unix(const char *path) >> { >> int fd = socket(PF_UNIX, SOCK_DGRAM, 0); >> - if (fd < 0) >> + if (fd < 0) { >> + diag_set(SystemError, strerror(errno)); >> return -1; >> + } >> struct sockaddr_un un; >> memset(&un, 0, sizeof(un)); >> snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); >> un.sun_family = AF_UNIX; >> if (connect(fd, (struct sockaddr *) &un, sizeof(un)) != 0) { >> + diag_set(SystemError, strerror(errno)); >> close(fd); >> return -1; >> } >> @@ -512,7 +515,7 @@ syslog_connect_remote(const char *server_address) >> hints.ai_protocol = IPPROTO_UDP; >> >> ret = getaddrinfo(remote, portnum, &hints, &inf); >> - if (ret < 0) { >> + if (ret != 0) { >> errno = EIO; >> diag_set(SystemError, "getaddrinfo: %s", >> gai_strerror(ret)); >> @@ -599,6 +602,11 @@ log_syslog_init(struct log *log, const char *init_str) >> say_free_syslog_opts(&opts); >> log->fd = log_syslog_connect(log); >> if (log->fd < 0) { >> + /* >> + * We need to log a diagnostics here until stacked >> + * diagnostics will be implemented (#1148). >> + */ >> + diag_log(); >> /* syslog indent is freed in atexit(). */ >> diag_set(SystemError, "syslog logger: %s", strerror(errno)); >> return -1; >> diff --git a/test/unit/coio.cc b/test/unit/coio.cc >> index bb8bd7131..69f78829c 100644 >> --- a/test/unit/coio.cc >> +++ b/test/unit/coio.cc >> @@ -72,7 +72,7 @@ static void >> test_getaddrinfo(void) >> { >> header(); >> - plan(1); >> + plan(3); >> const char *host = "127.0.0.1"; >> const char *port = "3333"; >> struct addrinfo *i; >> @@ -81,6 +81,39 @@ test_getaddrinfo(void) >> is(rc, 0, "getaddrinfo"); >> freeaddrinfo(i); >> >> + /* >> + * gh-4138: Check getaddrinfo() retval and diagnostics >> + * area. >> + */ >> + rc = coio_getaddrinfo("non_exists_hostname", port, NULL, &i, >> + 15768000000); >> + isnt(rc, 0, "getaddrinfo retval"); >> + const char *errmsg = diag_get()->last->errmsg; >> + /* EAI_NONAME */ >> + const char *exp_errmsg_1 = "getaddrinfo: nodename nor servname provided" >> + ", or not known"; >> + /* EAI_SERVICE */ >> + const char *exp_errmsg_2 = "getaddrinfo: Servname not supported for " >> + "ai_socktype"; >> + /* EAI_NONAME */ >> + const char *exp_errmsg_3 = "getaddrinfo: Name or service not known"; >> + /* EAI_NONAME */ >> + const char *exp_errmsg_4 = "getaddrinfo: hostname nor servname provided" >> + ", or not known"; >> + /* EAI_AGAIN */ >> + const char *exp_errmsg_5 = "getaddrinfo: Temporary failure in name " >> + "resolution"; >> + /* EAI_AGAIN */ >> + const char *exp_errmsg_6 = "getaddrinfo: Name could not be resolved at " >> + "this time"; >> + bool is_match_with_exp = strcmp(errmsg, exp_errmsg_1) == 0 || >> + strcmp(errmsg, exp_errmsg_2) == 0 || >> + strcmp(errmsg, exp_errmsg_3) == 0 || >> + strcmp(errmsg, exp_errmsg_4) == 0 || >> + strcmp(errmsg, exp_errmsg_5) == 0 || >> + strcmp(errmsg, exp_errmsg_6) == 0; >> + is(is_match_with_exp, true, "getaddrinfo error message"); >> + >> /* >> * gh-4209: 0 timeout should not be a special value and >> * detach a task. Before a fix it led to segfault >> diff --git a/test/unit/coio.result b/test/unit/coio.result >> index 5019fa48a..90b567140 100644 >> --- a/test/unit/coio.result >> +++ b/test/unit/coio.result >> @@ -7,6 +7,8 @@ >> # call done with res 0 >> *** test_call_f: done *** >> *** test_getaddrinfo *** >> -1..1 >> +1..3 >> ok 1 - getaddrinfo >> +ok 2 - getaddrinfo retval >> +ok 3 - getaddrinfo error message >> *** test_getaddrinfo: done *** >> >> commit cd5333e3acd35602e004a48eaefefd58dbd08cdd (HEAD) Author: Roman Khabibov <roman.habibov@tarantool.org> Date: Tue Jul 30 15:39:21 2019 +0300 coio/say: fix getaddrinfo error handling on macOS Before this patch, branch when getaddrinfo() returns error codes couldn't be reached on macOS, because they are greater than 0 on macOS (assumption "rc < 0" in commit ea1da04 is incorrect for macOS). Note: diag_log() in say.c was added, because otherwise it will be hid in the case of panic(). Also, two diag_set() in syslog_connect_unix() was added to avoid asserts in this diag_log(). Needed for #4138 diff --git a/src/lib/core/coio_task.c b/src/lib/core/coio_task.c index 908b336ed..83f669d05 100644 --- a/src/lib/core/coio_task.c +++ b/src/lib/core/coio_task.c @@ -413,7 +413,7 @@ coio_getaddrinfo(const char *host, const char *port, return -1; /* timed out or cancelled */ /* Task finished */ - if (task->rc < 0) { + if (task->rc != 0) { /* getaddrinfo() failed */ errno = EIO; diag_set(SystemError, "getaddrinfo: %s", diff --git a/src/lib/core/say.c b/src/lib/core/say.c index 791011e6f..9841ade25 100644 --- a/src/lib/core/say.c +++ b/src/lib/core/say.c @@ -485,13 +485,16 @@ static inline int syslog_connect_unix(const char *path) { int fd = socket(PF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) + if (fd < 0) { + diag_set(SystemError, strerror(errno)); return -1; + } struct sockaddr_un un; memset(&un, 0, sizeof(un)); snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); un.sun_family = AF_UNIX; if (connect(fd, (struct sockaddr *) &un, sizeof(un)) != 0) { + diag_set(SystemError, strerror(errno)); close(fd); return -1; } @@ -532,7 +535,7 @@ syslog_connect_remote(const char *server_address) hints.ai_protocol = IPPROTO_UDP; ret = getaddrinfo(remote, portnum, &hints, &inf); - if (ret < 0) { + if (ret != 0) { errno = EIO; diag_set(SystemError, "getaddrinfo: %s", gai_strerror(ret)); @@ -619,6 +622,7 @@ log_syslog_init(struct log *log, const char *init_str) say_free_syslog_opts(&opts); log->fd = log_syslog_connect(log); if (log->fd < 0) { + diag_log(); /* syslog indent is freed in atexit(). */ diag_set(SystemError, "syslog logger: %s", strerror(errno)); return -1; diff --git a/test/unit/coio.cc b/test/unit/coio.cc index bb8bd7131..69f78829c 100644 --- a/test/unit/coio.cc +++ b/test/unit/coio.cc @@ -72,7 +72,7 @@ static void test_getaddrinfo(void) { header(); - plan(1); + plan(3); const char *host = "127.0.0.1"; const char *port = "3333"; struct addrinfo *i; @@ -81,6 +81,39 @@ test_getaddrinfo(void) is(rc, 0, "getaddrinfo"); freeaddrinfo(i); + /* + * gh-4138: Check getaddrinfo() retval and diagnostics + * area. + */ + rc = coio_getaddrinfo("non_exists_hostname", port, NULL, &i, + 15768000000); + isnt(rc, 0, "getaddrinfo retval"); + const char *errmsg = diag_get()->last->errmsg; + /* EAI_NONAME */ + const char *exp_errmsg_1 = "getaddrinfo: nodename nor servname provided" + ", or not known"; + /* EAI_SERVICE */ + const char *exp_errmsg_2 = "getaddrinfo: Servname not supported for " + "ai_socktype"; + /* EAI_NONAME */ + const char *exp_errmsg_3 = "getaddrinfo: Name or service not known"; + /* EAI_NONAME */ + const char *exp_errmsg_4 = "getaddrinfo: hostname nor servname provided" + ", or not known"; + /* EAI_AGAIN */ + const char *exp_errmsg_5 = "getaddrinfo: Temporary failure in name " + "resolution"; + /* EAI_AGAIN */ + const char *exp_errmsg_6 = "getaddrinfo: Name could not be resolved at " + "this time"; + bool is_match_with_exp = strcmp(errmsg, exp_errmsg_1) == 0 || + strcmp(errmsg, exp_errmsg_2) == 0 || + strcmp(errmsg, exp_errmsg_3) == 0 || + strcmp(errmsg, exp_errmsg_4) == 0 || + strcmp(errmsg, exp_errmsg_5) == 0 || + strcmp(errmsg, exp_errmsg_6) == 0; + is(is_match_with_exp, true, "getaddrinfo error message"); + /* * gh-4209: 0 timeout should not be a special value and * detach a task. Before a fix it led to segfault diff --git a/test/unit/coio.result b/test/unit/coio.result index 5019fa48a..90b567140 100644 --- a/test/unit/coio.result +++ b/test/unit/coio.result @@ -7,6 +7,8 @@ # call done with res 0 *** test_call_f: done *** *** test_getaddrinfo *** -1..1 +1..3 ok 1 - getaddrinfo +ok 2 - getaddrinfo retval +ok 3 - getaddrinfo error message *** test_getaddrinfo: done ***
next prev parent reply other threads:[~2020-06-23 13:27 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-12 10:24 [Tarantool-patches] [PATCH v2 0/2] Return getaddrinfo() errors Roman Khabibov 2020-03-12 10:24 ` [Tarantool-patches] [PATCH v2 1/2] coio/say: fix getaddrinfo error handling on macOS Roman Khabibov 2020-03-29 8:51 ` Sergey Ostanevich 2020-03-29 9:12 ` Alexander Turenko 2020-04-06 2:07 ` Roman Khabibov 2020-04-17 9:37 ` Sergey Ostanevich 2020-04-24 11:32 ` Roman Khabibov 2020-06-23 13:27 ` Roman Khabibov [this message] 2020-07-23 14:12 ` Sergey Ostanevich 2020-07-28 9:26 ` Roman Khabibov 2020-04-26 17:20 ` Vladislav Shpilevoy 2020-03-12 10:24 ` [Tarantool-patches] [PATCH v2 2/2] lua: return getaddrinfo() errors Roman Khabibov 2020-03-29 9:07 ` Sergey Ostanevich 2020-03-29 9:25 ` Alexander Turenko 2020-04-06 2:08 ` Roman Khabibov 2020-04-16 10:27 ` Sergey Ostanevich 2020-04-24 11:42 ` Roman Khabibov 2020-04-24 17:18 ` Sergey Ostanevich 2020-04-26 3:16 ` Roman Khabibov 2020-04-26 15:46 ` Alexander Turenko 2020-04-26 16:26 ` Roman Khabibov 2020-07-13 9:51 ` sergos 2020-07-28 14:08 ` [Tarantool-patches] [PATCH v2 0/2] Return " Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=D47B8B9E-7694-4060-903C-C5492ED0D305@tarantool.org \ --to=roman.habibov@tarantool.org \ --cc=alexander.turenko@tarantool.org \ --cc=sergos@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 1/2] coio/say: fix getaddrinfo error handling on macOS' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox