qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>
Subject: [Qemu-devel] [PATCH RFC 09/10] maint: add check for use of POSIX functions which are not reentrant safe
Date: Fri, 31 Jul 2015 17:31:02 +0100	[thread overview]
Message-ID: <1438360263-25445-10-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1438360263-25445-1-git-send-email-berrange@redhat.com>

Imports a rule from libvirt to make sure that for any POSIX
function which is not reentrant safe, the _r variant is used
in the source.

While it is entirely possible that many of the QEMU uses are
in fact safe, it is pretty difficult to prove that conclusively
due to the increasing use of 3rd party libraries. For features
like spice, glusterfs, rbd, iscsi these libraries may either be
used from QEMU non-main threads, or can be  secretly using threads
themselves behind QEMU's back.

Given this, the only safe thing todo is to forbid all use of the
non-reentrant safe POSIX functions. While Linux platforms have
long had the full set of _r variants, other OS may not be so lucky,
particularly Mingw32, so fixing this will require some portability
code on various platforms.

Since fixing the current QEMU usage is non-trivial, the check is
disabled for any functions QEMU currently relies on. IOW, this
check merely stops the current problem getting any worse. Future
work will have to look at fixing existing violations.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 Makefile.nonreentrant | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++
 cfg.mk                |  14 ++++++
 2 files changed, 134 insertions(+)
 create mode 100644 Makefile.nonreentrant

diff --git a/Makefile.nonreentrant b/Makefile.nonreentrant
new file mode 100644
index 0000000..687d39b
--- /dev/null
+++ b/Makefile.nonreentrant
@@ -0,0 +1,120 @@
+## Functions for sc_prohibit_nonreentrant  -*- makefile -*-
+##
+## Copyright (C) 2009-2010, 2013 Red Hat, Inc.
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+#
+# Generated by running the following on Fedora 9:
+#
+#  nm -D --defined-only /lib/libc.so.6  \
+#      | grep '_r$' \
+#      | awk '{print $3}' \
+#      | grep -v __ \
+#      | grep -v qsort \ # Red herring since we don't need to pass extra args to qsort comparator
+#      | grep -v readdir \ # This is safe as long as each DIR * instance is only used by one thread
+#      | sort \
+#      | uniq \
+#      | sed -e 's/_r//'
+#
+# Also manually add in all inet_* functions some of which
+# are not threadsafe and do not have _r variants. They are
+# all deprecated in favour of getnameinfo/getaddrinfo
+#
+
+# Current QEMU violations are commented out. Eventual goal
+# is to uncomment all these functions, once QEMU code is
+# fixed
+NON_REENTRANT =
+NON_REENTRANT += asctime
+NON_REENTRANT += ctime
+NON_REENTRANT += drand48
+NON_REENTRANT += ecvt
+NON_REENTRANT += erand48
+NON_REENTRANT += ether_aton
+NON_REENTRANT += ether_ntoa
+#NON_REENTRANT += fcvt
+NON_REENTRANT += fgetgrent
+NON_REENTRANT += fgetpwent
+NON_REENTRANT += fgetspent
+NON_REENTRANT += getaliasbyname
+NON_REENTRANT += getaliasent
+NON_REENTRANT += getdate
+NON_REENTRANT += getgrent
+NON_REENTRANT += getgrgid
+NON_REENTRANT += getgrnam
+NON_REENTRANT += gethostbyaddr
+NON_REENTRANT += gethostbyname2
+#NON_REENTRANT += gethostbyname
+NON_REENTRANT += gethostent
+NON_REENTRANT += getlogin
+#NON_REENTRANT += getmntent
+NON_REENTRANT += getnetbyaddr
+NON_REENTRANT += getnetbyname
+NON_REENTRANT += getnetent
+NON_REENTRANT += getnetgrent
+NON_REENTRANT += getprotobyname
+NON_REENTRANT += getprotobynumber
+NON_REENTRANT += getprotoent
+NON_REENTRANT += getpwent
+#NON_REENTRANT += getpwnam
+#NON_REENTRANT += getpwuid
+NON_REENTRANT += getrpcbyname
+NON_REENTRANT += getrpcbynumber
+NON_REENTRANT += getrpcent
+NON_REENTRANT += getservbyname
+NON_REENTRANT += getservbyport
+NON_REENTRANT += getservent
+NON_REENTRANT += getspent
+NON_REENTRANT += getspnam
+NON_REENTRANT += getutent
+NON_REENTRANT += getutid
+NON_REENTRANT += getutline
+#NON_REENTRANT += gmtime
+NON_REENTRANT += hcreate
+NON_REENTRANT += hdestroy
+NON_REENTRANT += hsearch
+NON_REENTRANT += initstate
+NON_REENTRANT += jrand48
+NON_REENTRANT += lcong48
+#NON_REENTRANT += localtime
+NON_REENTRANT += lrand48
+NON_REENTRANT += mrand48
+NON_REENTRANT += nrand48
+#NON_REENTRANT += ptsname
+NON_REENTRANT += qecvt
+NON_REENTRANT += qfcvt
+#NON_REENTRANT += random
+#NON_REENTRANT += rand
+NON_REENTRANT += seed48
+NON_REENTRANT += setstate
+NON_REENTRANT += sgetspent
+NON_REENTRANT += srand48
+#NON_REENTRANT += srandom
+#NON_REENTRANT += strerror
+#NON_REENTRANT += strtok
+NON_REENTRANT += tmpnam
+NON_REENTRANT += ttyname
+#NON_REENTRANT += inet_addr
+#NON_REENTRANT += inet_aton
+NON_REENTRANT += inet_lnaof
+NON_REENTRANT += inet_makeaddr
+NON_REENTRANT += inet_netof
+NON_REENTRANT += inet_network
+NON_REENTRANT += inet_nsap_addr
+NON_REENTRANT += inet_nsap_ntoa
+#NON_REENTRANT += inet_ntoa
+#NON_REENTRANT += inet_ntop
+#NON_REENTRANT += inet_pton
diff --git a/cfg.mk b/cfg.mk
index 39e4124..2f98c1a 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -128,6 +128,20 @@ sc_copyright_format:
 	halt='spell Red Hat as two words'				\
 	  $(_sc_search_regexp)
 
+# Use a subshell for each function, to give the optimal warning message.
+include $(srcdir)/Makefile.nonreentrant
+
+sc_prohibit_nonreentrant:
+	@for i in $(NON_REENTRANT) ; \
+        do \
+            (prohibit="\\<$$i *\\("                                     \
+             in_vc_files='\.[ch]$$'					\
+             halt="use $${i}_r, not $$i"                                \
+             $(_sc_search_regexp)                                       \
+            ) || fail=1;                                                \
+        done ; \
+        exit $$fail
+
 # We don't use this feature of maint.mk.
 prev_version_file = /dev/null
 
-- 
2.4.3

  parent reply	other threads:[~2015-07-31 16:31 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-31 16:30 [Qemu-devel] [PATCH RFC 00/10] Enable repository wide style checking Daniel P. Berrange
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 01/10] tests: import GNULIB's syntax-check infrastructure Daniel P. Berrange
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 02/10] maint: remove double semicolons in many files Daniel P. Berrange
2015-08-13 17:57   ` Peter Maydell
2015-08-14  8:32     ` Daniel P. Berrange
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 03/10] maint: remove / fix many doubled words Daniel P. Berrange
2015-08-03 16:10   ` Max Reitz
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 04/10] maint: remove unused include for assert.h Daniel P. Berrange
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 05/10] maint: remove unused include for dirent.h Daniel P. Berrange
2015-07-31 16:30 ` [Qemu-devel] [PATCH RFC 06/10] maint: remove unused include for signal.h Daniel P. Berrange
2015-07-31 16:31 ` [Qemu-devel] [PATCH RFC 07/10] maint: remove unused include for strings.h Daniel P. Berrange
2015-07-31 16:31 ` [Qemu-devel] [PATCH RFC 08/10] maint: avoid useless "if (foo) free(foo)" pattern Daniel P. Berrange
2015-07-31 16:31 ` Daniel P. Berrange [this message]
2015-07-31 16:31 ` [Qemu-devel] [PATCH RFC 10/10] maint: enable checking for qemu/osdep.h header usage Daniel P. Berrange
2015-08-13 17:53 ` [Qemu-devel] [PATCH RFC 00/10] Enable repository wide style checking Peter Maydell
2015-08-13 18:27   ` Eric Blake
2015-08-13 20:39     ` Peter Maydell
2015-08-14  9:57       ` Daniel P. Berrange
2015-08-14 10:30       ` Paul Eggert
2015-08-14 10:35         ` Peter Maydell

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=1438360263-25445-10-git-send-email-berrange@redhat.com \
    --to=berrange@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).