Date: Sun, 06 Feb 2011 00:42:31 +0200 From: Mikolaj Golub <to.my.trociny@gmail.com> To: Pawel Jakub Dawidek <pjd@FreeBSD.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r218044 - head/sbin/hastd Message-ID: <8662syrtm0.fsf@kopusha.home.net> In-Reply-To: <201101282156.p0SLulCc001547@svn.freebsd.org> (Pawel Jakub Dawidek's message of "Fri, 28 Jan 2011 21:56:47 %2B0000 (UTC)") References: <201101282156.p0SLulCc001547@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 28 Jan 2011 21:56:47 +0000 (UTC) Pawel Jakub Dawidek wrote: PJD> Author: pjd PJD> Date: Fri Jan 28 21:56:47 2011 PJD> New Revision: 218044 PJD> URL: http://svn.freebsd.org/changeset/base/218044 PJD> Log: PJD> Add function to assert that the only descriptors we have open are the ones PJD> we expect to be open. Also assert that they point at expected type. PJD> PJD> Because openlog(3) API is unable to tell us descriptor number it is using, we PJD> have to close syslog socket, remember assert message in local buffer and if we PJD> fail on assertion, reopen syslog socket and log the message. PJD> PJD> MFC after: 1 week PJD> Modified: PJD> head/sbin/hastd/hastd.c PJD> head/sbin/hastd/hastd.h PJD> Modified: head/sbin/hastd/hastd.c PJD> ============================================================================== PJD> --- head/sbin/hastd/hastd.c Fri Jan 28 21:52:37 2011 (r218043) PJD> +++ head/sbin/hastd/hastd.c Fri Jan 28 21:56:47 2011 (r218044) PJD> @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); PJD> #include <sys/param.h> PJD> #include <sys/linker.h> PJD> #include <sys/module.h> PJD> +#include <sys/stat.h> PJD> #include <sys/wait.h> PJD> PJD> #include <assert.h> PJD> @@ -119,6 +120,146 @@ descriptors_cleanup(struct hast_resource PJD> pjdlog_fini(); PJD> } PJD> PJD> +static const char * PJD> +dtype2str(mode_t mode) PJD> +{ PJD> + PJD> + if (S_ISBLK(mode)) PJD> + return ("block device"); PJD> + else if (S_ISCHR(mode)) PJD> + return ("character device"); PJD> + else if (S_ISDIR(mode)) PJD> + return ("directory"); PJD> + else if (S_ISFIFO(mode)) PJD> + return ("pipe or FIFO"); PJD> + else if (S_ISLNK(mode)) PJD> + return ("symbolic link"); PJD> + else if (S_ISREG(mode)) PJD> + return ("regular file"); PJD> + else if (S_ISSOCK(mode)) PJD> + return ("socket"); PJD> + else if (S_ISWHT(mode)) PJD> + return ("whiteout"); PJD> + else PJD> + return ("unknown"); PJD> +} PJD> + PJD> +void PJD> +descriptors_assert(const struct hast_resource *res, int pjdlogmode) PJD> +{ PJD> + char msg[256]; PJD> + struct stat sb; PJD> + long maxfd; PJD> + bool isopen; PJD> + mode_t mode; PJD> + int fd; PJD> + PJD> + /* PJD> + * At this point descriptor to syslog socket is closed, so if we want PJD> + * to log assertion message, we have to first store it in 'msg' local PJD> + * buffer and then open syslog socket and log it. PJD> + */ PJD> + msg[0] = '\0'; PJD> + PJD> + maxfd = sysconf(_SC_OPEN_MAX); PJD> + if (maxfd < 0) { PJD> + pjdlog_errno(LOG_WARNING, "sysconf(_SC_OPEN_MAX) failed"); As it is commented above :-) syslog socket is closed so we can't call pjdlog_errno() here. PJD> + maxfd = 16384; PJD> + } PJD> + for (fd = 0; fd <= maxfd; fd++) { PJD> + if (fstat(fd, &sb) == 0) { PJD> + isopen = true; PJD> + mode = sb.st_mode; PJD> + } else if (errno == EBADF) { PJD> + isopen = false; PJD> + mode = 0; PJD> + } else { PJD> + isopen = true; /* silence gcc */ PJD> + mode = 0; /* silence gcc */ PJD> + snprintf(msg, sizeof(msg), PJD> + "Unable to fstat descriptor %d: %s", fd, PJD> + strerror(errno)); Shouldn't it break here? PJD> + } PJD> + if (fd == STDIN_FILENO || fd == STDOUT_FILENO || PJD> + fd == STDERR_FILENO) { PJD> + if (!isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (%s) is closed, but should be open.", PJD> + fd, (fd == STDIN_FILENO ? "stdin" : PJD> + (fd == STDOUT_FILENO ? "stdout" : "stderr"))); PJD> + break; PJD> + } PJD> + } else if (fd == proto_descriptor(res->hr_event)) { PJD> + if (!isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (event) is closed, but should be open.", PJD> + fd); PJD> + break; PJD> + } PJD> + if (!S_ISSOCK(mode)) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (event) is %s, but should be %s.", PJD> + fd, dtype2str(mode), dtype2str(S_IFSOCK)); PJD> + break; PJD> + } PJD> + } else if (fd == proto_descriptor(res->hr_ctrl)) { PJD> + if (!isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (ctrl) is closed, but should be open.", PJD> + fd); PJD> + break; PJD> + } PJD> + if (!S_ISSOCK(mode)) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (ctrl) is %s, but should be %s.", PJD> + fd, dtype2str(mode), dtype2str(S_IFSOCK)); PJD> + break; PJD> + } PJD> + } else if (res->hr_role == HAST_ROLE_SECONDARY && PJD> + fd == proto_descriptor(res->hr_remotein)) { PJD> + if (!isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (remote in) is closed, but should be open.", PJD> + fd); PJD> + break; PJD> + } PJD> + if (!S_ISSOCK(mode)) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (remote in) is %s, but should be %s.", PJD> + fd, dtype2str(mode), dtype2str(S_IFSOCK)); PJD> + break; PJD> + } PJD> + } else if (res->hr_role == HAST_ROLE_SECONDARY && PJD> + fd == proto_descriptor(res->hr_remoteout)) { PJD> + if (!isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (remote out) is closed, but should be open.", PJD> + fd); PJD> + break; PJD> + } PJD> + if (!S_ISSOCK(mode)) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d (remote out) is %s, but should be %s.", PJD> + fd, dtype2str(mode), dtype2str(S_IFSOCK)); PJD> + break; PJD> + } PJD> + } else { PJD> + if (isopen) { PJD> + snprintf(msg, sizeof(msg), PJD> + "Descriptor %d is open (%s), but should be closed.", PJD> + fd, dtype2str(mode)); PJD> + break; PJD> + } PJD> + } PJD> + } PJD> + if (msg[0] != '\0') { PJD> + pjdlog_init(pjdlogmode); PJD> + pjdlog_prefix_set("[%s] (%s) ", res->hr_name, PJD> + role2str(res->hr_role)); PJD> + PJDLOG_ABORT("%s", msg); PJD> + } PJD> +} PJD> + PJD> static void PJD> child_exit_log(unsigned int pid, int status) PJD> { PJD> Modified: head/sbin/hastd/hastd.h PJD> ============================================================================== PJD> --- head/sbin/hastd/hastd.h Fri Jan 28 21:52:37 2011 (r218043) PJD> +++ head/sbin/hastd/hastd.h Fri Jan 28 21:56:47 2011 (r218044) PJD> @@ -44,6 +44,7 @@ extern bool sigexit_received; PJD> extern struct pidfh *pfh; PJD> PJD> void descriptors_cleanup(struct hast_resource *res); PJD> +void descriptors_assert(const struct hast_resource *res, int pjdlogmode); PJD> PJD> void hastd_primary(struct hast_resource *res); PJD> void hastd_secondary(struct hast_resource *res, struct nv *nvin); PJD> _______________________________________________ PJD> svn-src-all@freebsd.org mailing list PJD> http://lists.freebsd.org/mailman/listinfo/svn-src-all PJD> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" -- Mikolaj Golub
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8662syrtm0.fsf>