From 2f7bdaa659ea27559c8eb84e04f5a4e52dfdea31 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Tue, 27 Jun 2017 17:12:20 -0400 Subject: [PATCH 1/8] bpo-27584: New addition of vSockets to the python socket module Support for AF_VSOCK on Linux only --- Doc/library/socket.rst | 20 ++++ Lib/test/test_socket.py | 113 +++++++++++++++++++- Modules/socketmodule.c | 93 ++++++++++++++++- Modules/socketmodule.h | 7 ++ aclocal.m4 | 226 +++++++++++++--------------------------- configure | 18 ++++ configure.ac | 6 ++ pyconfig.h.in | 3 + 8 files changed, 332 insertions(+), 154 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index c5064e92c2118b..6590eabd53e6e0 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -153,6 +153,14 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.6 +- :const:`AF_VSOCK` allows communication between virtual machines and + their hosts. The sockets are represented as a (CID, port) tuple + where the context ID or CID and port are integers. + + Availability: Linux >= 4.8. QEMU >= 2.8. + + .. versionadded:: 3.7 + - Certain other address families (:const:`AF_PACKET`, :const:`AF_CAN`) support specific representations. @@ -395,6 +403,18 @@ Constants .. versionadded:: 3.6 + +.. data:: AF_VSOCK + IOCTL_VM_SOCKETS_GET_LOCAL_CID + VMADDR* + SO_VM* + + Constants for Linux host/guest communication. + + Availability: Linux >= 4.8. + + .. versionadded:: 3.7 + .. data:: AF_LINK Availability: BSD, OSX. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 84234887747983..c08579ee167b6d 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -33,6 +33,8 @@ HOST = support.HOST MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') ## test unicode string and carriage return +VSOCKPORT = 1234 + try: import _thread as thread import threading @@ -44,6 +46,23 @@ except ImportError: _socket = None +def getCid(): + import struct + import fcntl + + if not os.path.exists("/dev/vsock"): + return None + try: + fd = open("/dev/vsock", "rb") + except: + return None + try: + r = fcntl.ioctl(fd, socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID, " ") + except: + fd.close() + return None + fd.close() + return struct.unpack("I", r)[0] def _have_socket_can(): """Check whether CAN sockets are supported on this host.""" @@ -85,6 +104,12 @@ def _have_socket_alg(): s.close() return True +def _have_socket_vsock(): + """Check whether AF_VSOCK sockets are supported on this host.""" + if (getCid() == None): + return False + return True + HAVE_SOCKET_CAN = _have_socket_can() HAVE_SOCKET_CAN_ISOTP = _have_socket_can_isotp() @@ -93,6 +118,8 @@ def _have_socket_alg(): HAVE_SOCKET_ALG = _have_socket_alg() +HAVE_SOCKET_VSOCK = _have_socket_vsock() + # Size in bytes of the int type SIZEOF_INT = array.array("i").itemsize @@ -203,7 +230,6 @@ def setUp(self): except OSError: self.skipTest('unable to bind RDS socket') - class ThreadableTest: """Threadable Test class @@ -387,6 +413,40 @@ def clientTearDown(self): self.cli = None ThreadableTest.clientTearDown(self) +@unittest.skipUnless(HAVE_SOCKET_VSOCK, + 'VSOCK sockets required for this test.') +@unittest.skipUnless(getCid() != 2, + "This test can only be run on a virtual guest.") +class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): + + def __init__(self, methodName = 'runTest'): + unittest.TestCase.__init__(self, methodName = methodName) + ThreadableTest.__init__(self) + + def setUp(self): + self.serv = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) + self.addCleanup(self.serv.close) + self.serv.bind((socket.VMADDR_CID_ANY, VSOCKPORT)) + self.serv.listen() + self.serverExplicitReady() + self.conn, self.connaddr = self.serv.accept() + self.addCleanup(self.conn.close) + + def clientSetUp(self): + time.sleep(0.1) + self.cli = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) + self.addCleanup(self.cli.close) + cid = getCid() + self.cli.connect((cid, VSOCKPORT)) + + def testStream(self): + msg = self.conn.recv(1024) + self.assertEqual(msg, MSG) + + def _testStream(self): + self.cli.send(MSG) + self.cli.close() + class SocketConnectedTest(ThreadedTCPSocketTest): """Socket tests for client-server connection. @@ -1874,6 +1934,53 @@ def _testCongestion(self): self.assertIn(self.serv, r) +@unittest.skipUnless(HAVE_SOCKET_VSOCK, + 'VSOCK sockets required for this test.') +class BasicVSOCKTest(unittest.TestCase): + + def testCrucialConstants(self): + socket.AF_VSOCK + + def testVSOCKConstants(self): + socket.SO_VM_SOCKETS_BUFFER_SIZE + socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE + socket.SO_VM_SOCKETS_BUFFER_MAX_SIZE + socket.VMADDR_CID_ANY + socket.VMADDR_PORT_ANY + socket.VMADDR_CID_HOST + socket.VM_SOCKETS_INVALID_VERSION + socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID + + def testCreateSocket(self): + with socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) as s: + pass + + def testSocketBufferSize(self): + with socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) as s: + orig_max = s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MAX_SIZE) + orig = s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_SIZE) + orig_min = s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE) + + s.setsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MAX_SIZE, orig_max * 2) + s.setsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_SIZE, orig * 2) + s.setsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE, orig_min * 2) + + self.assertEqual(orig_max * 2, + s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MAX_SIZE)) + self.assertEqual(orig * 2, + s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_SIZE)) + self.assertEqual(orig_min * 2, + s.getsockopt(socket.AF_VSOCK, + socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE)) + @unittest.skipUnless(thread, 'Threading required for this test.') class BasicTCPTest(SocketConnectedTest): @@ -5681,6 +5788,10 @@ def test_main(): tests.extend([BasicCANTest, CANTest]) tests.extend([BasicRDSTest, RDSTest]) tests.append(LinuxKernelCryptoAPI) + tests.extend([ + BasicVSOCKTest, + ThreadedVSOCKSocketStreamTest + ]) tests.extend([ CmsgMacroTests, SendmsgUDPTest, diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 37626e67cb0b60..209cf371bb6ba0 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1225,6 +1225,14 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif /* AF_NETLINK */ +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm *a = (struct sockaddr_vm *) addr; + return Py_BuildValue("II", a->svm_cid, a->svm_port); + } +#endif /* AF_VSOCK */ + #ifdef ENABLE_IPV6 case AF_INET6: { @@ -1586,6 +1594,32 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif +#if defined(AF_VSOCK) + case AF_VSOCK: + { + struct sockaddr_vm* addr; + int port, cid; + addr = (struct sockaddr_vm *)addr_ret; + memset(addr, 0, sizeof(struct sockaddr_vm)); + if (!PyTuple_Check(args)) { + PyErr_Format( + PyExc_TypeError, + "getsockaddrarg: " + "AF_VSOCK address must be tuple, not %.500s", + Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, "II:getsockaddrarg", &cid, &port)) + return 0; + addr->svm_family = s->sock_family; + addr->svm_port = port; + addr->svm_cid = cid; + *len_ret = sizeof(*addr); + return 1; + } +#endif + + #ifdef AF_RDS case AF_RDS: /* RDS sockets use sockaddr_in: fall-through */ @@ -2103,6 +2137,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) } #endif +#if defined(AF_VSOCK) + case AF_VSOCK: + { + *len_ret = sizeof (struct sockaddr_vm); + return 1; + } +#endif + #ifdef AF_RDS case AF_RDS: /* RDS sockets use sockaddr_in: fall-through */ @@ -2598,6 +2640,21 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) unsigned int optlen; PyObject *none; +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag; + /* setsockopt(level, opt, flag) */ + if (PyArg_ParseTuple(args, "iiK:setsockopt", + &level, &optname, &vflag)) { + // level should always be set to AF_VSOCK + res = setsockopt(s->sock_fd, level, optname, + (void*)&vflag, sizeof vflag); + goto done; + } + return NULL; + } +#endif + /* setsockopt(level, opt, flag) */ if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { @@ -2668,20 +2725,39 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) int res; PyObject *buf; socklen_t buflen = 0; + int flag = 0; + socklen_t flagsize; if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &buflen)) return NULL; if (buflen == 0) { - int flag = 0; - socklen_t flagsize = sizeof flag; +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + uint64_t vflag = 0; + flagsize = sizeof vflag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&vflag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromLong(vflag); + } +#endif + flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, (void *)&flag, &flagsize); if (res < 0) return s->errorhandler(); return PyLong_FromLong(flag); } +#ifdef AF_VSOCK + if (s->sock_family == AF_VSOCK) { + PyErr_SetString(PyExc_OSError, + "getsockopt string buffer not allowed"); + return NULL; + } +#endif if (buflen <= 0 || buflen > 1024) { PyErr_SetString(PyExc_OSError, "getsockopt buflen out of range"); @@ -6645,6 +6721,19 @@ PyInit__socket(void) PyModule_AddIntMacro(m, NETLINK_CRYPTO); #endif #endif /* AF_NETLINK */ + +#ifdef AF_VSOCK + PyModule_AddIntConstant(m, "AF_VSOCK", AF_VSOCK); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); + PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); + PyModule_AddIntConstant(m, "VMADDR_CID_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_PORT_ANY", 0xffffffff); + PyModule_AddIntConstant(m, "VMADDR_CID_HOST", 2); + PyModule_AddIntConstant(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); + PyModule_AddIntConstant(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); +#endif + #ifdef AF_ROUTE /* Alias to emulate 4.4BSD */ PyModule_AddIntMacro(m, AF_ROUTE); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 03f982b91083f3..4a5bbf497a8fa3 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -107,6 +107,13 @@ typedef int socklen_t; #define SOL_ALG 279 #endif +#ifdef HAVE_LINUX_VM_SOCKETS_H +#include +#ifndef AF_VSOCK +#define AF_VSOCK 40 +#endif +#endif + /* Linux 3.19 */ #ifndef ALG_SET_AEAD_ASSOCLEN #define ALG_SET_AEAD_ASSOCLEN 4 diff --git a/aclocal.m4 b/aclocal.m4 index 2a745e57466cae..7975ec79f72bcf 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.13.4 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -12,63 +12,32 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) -dnl -dnl Copyright © 2004 Scott James Remnant . -dnl Copyright © 2012-2015 Dan Nicholson -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a -dnl configuration script generated by Autoconf, you may include it under -dnl the same distribution terms that you use for the rest of that -dnl program. - -dnl PKG_PREREQ(MIN-VERSION) -dnl ----------------------- -dnl Since: 0.29 -dnl -dnl Verify that the version of the pkg-config macros are at least -dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's -dnl installed version of pkg-config, this checks the developer's version -dnl of pkg.m4 when generating configure. -dnl -dnl To ensure that this macro is defined, also add: -dnl m4_ifndef([PKG_PREREQ], -dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) -dnl -dnl See the "Since" comment for each macro you use to see what version -dnl of the macros you require. -m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) -m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, - [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) -])dnl PKG_PREREQ - -dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) -dnl ---------------------------------- -dnl Since: 0.16 -dnl -dnl Search for the pkg-config tool and set the PKG_CONFIG variable to -dnl first found in the path. Checks that the version of pkg-config found -dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is -dnl used since that's the first version where most current features of -dnl pkg-config existed. +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) @@ -90,19 +59,18 @@ if test -n "$PKG_CONFIG"; then PKG_CONFIG="" fi fi[]dnl -])dnl PKG_PROG_PKG_CONFIG - -dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------------------------------- -dnl Since: 0.18 -dnl -dnl Check to see whether a particular set of modules exists. Similar to -dnl PKG_CHECK_MODULES(), but does not set variables or print errors. -dnl -dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -dnl only at the first occurence in configure.ac, so if the first place -dnl it's called might be skipped (such as if it is within an "if", you -dnl have to call PKG_CHECK_EXISTS manually +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ @@ -112,10 +80,8 @@ m4_ifvaln([$3], [else $3])dnl fi]) -dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -dnl --------------------------------------------- -dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting -dnl pkg_failed based on the result. +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" @@ -127,11 +93,10 @@ m4_define([_PKG_CONFIG], else pkg_failed=untried fi[]dnl -])dnl _PKG_CONFIG +])# _PKG_CONFIG -dnl _PKG_SHORT_ERRORS_SUPPORTED -dnl --------------------------- -dnl Internal check to see if pkg-config supports short errors. +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -139,17 +104,19 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then else _pkg_short_errors_supported=no fi[]dnl -])dnl _PKG_SHORT_ERRORS_SUPPORTED - - -dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl -------------------------------------------------------------- -dnl Since: 0.4.0 -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES might not happen, you should be sure to include an -dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl @@ -203,40 +170,16 @@ else AC_MSG_RESULT([yes]) $3 fi[]dnl -])dnl PKG_CHECK_MODULES - +])# PKG_CHECK_MODULES -dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl --------------------------------------------------------------------- -dnl Since: 0.29 -dnl -dnl Checks for existence of MODULES and gathers its build flags with -dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags -dnl and VARIABLE-PREFIX_LIBS from --libs. -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to -dnl include an explicit call to PKG_PROG_PKG_CONFIG in your -dnl configure.ac. -AC_DEFUN([PKG_CHECK_MODULES_STATIC], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -_save_PKG_CONFIG=$PKG_CONFIG -PKG_CONFIG="$PKG_CONFIG --static" -PKG_CHECK_MODULES($@) -PKG_CONFIG=$_save_PKG_CONFIG[]dnl -])dnl PKG_CHECK_MODULES_STATIC - -dnl PKG_INSTALLDIR([DIRECTORY]) -dnl ------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable pkgconfigdir as the location where a module -dnl should install pkg-config .pc files. By default the directory is -dnl $libdir/pkgconfig, but the default can be changed by passing -dnl DIRECTORY. The user can override through the --with-pkgconfigdir -dnl parameter. +# PKG_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable pkgconfigdir as the location where a module +# should install pkg-config .pc files. By default the directory is +# $libdir/pkgconfig, but the default can be changed by passing +# DIRECTORY. The user can override through the --with-pkgconfigdir +# parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -247,18 +190,16 @@ AC_ARG_WITH([pkgconfigdir], AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -])dnl PKG_INSTALLDIR +]) dnl PKG_INSTALLDIR -dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) -dnl -------------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable noarch_pkgconfigdir as the location where a -dnl module should install arch-independent pkg-config .pc files. By -dnl default the directory is $datadir/pkgconfig, but the default can be -dnl changed by passing DIRECTORY. The user can override through the -dnl --with-noarch-pkgconfigdir parameter. +# PKG_NOARCH_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable noarch_pkgconfigdir as the location where a +# module should install arch-independent pkg-config .pc files. By +# default the directory is $datadir/pkgconfig, but the default can be +# changed by passing DIRECTORY. The user can override through the +# --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -269,22 +210,5 @@ AC_ARG_WITH([noarch-pkgconfigdir], AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -])dnl PKG_NOARCH_INSTALLDIR - - -dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------- -dnl Since: 0.28 -dnl -dnl Retrieves the value of the pkg-config variable for the given module. -AC_DEFUN([PKG_CHECK_VAR], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl - -_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -AS_VAR_COPY([$1], [pkg_cv_][$1]) - -AS_VAR_IF([$1], [""], [$5], [$4])dnl -])dnl PKG_CHECK_VAR +]) dnl PKG_NOARCH_INSTALLDIR diff --git a/configure b/configure index d2766bc435dd2f..cc17431bcd4ed0 100755 --- a/configure +++ b/configure @@ -8100,6 +8100,24 @@ fi done +for ac_header in linux/vm_sockets.h +do : + ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" " +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" +if test "x$ac_cv_header_linux_vm_sockets_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LINUX_VM_SOCKETS_H 1 +_ACEOF + +fi + +done + + # On Linux, can.h and can/raw.h require sys/socket.h for ac_header in linux/can.h linux/can/raw.h linux/can/bcm.h do : diff --git a/configure.ac b/configure.ac index 4ceeea8d89c652..1446d1ba0929c8 100644 --- a/configure.ac +++ b/configure.ac @@ -2097,6 +2097,12 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[ #endif ]) +AC_CHECK_HEADERS(linux/vm_sockets.h,,,[ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +]) + # On Linux, can.h and can/raw.h require sys/socket.h AC_CHECK_HEADERS(linux/can.h linux/can/raw.h linux/can/bcm.h,,,[ #ifdef HAVE_SYS_SOCKET_H diff --git a/pyconfig.h.in b/pyconfig.h.in index 2efd768a96a788..1e62125678e218 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -574,6 +574,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TIPC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_VM_SOCKETS_H + /* Define to 1 if you have the 'lockf' function and the F_LOCK macro. */ #undef HAVE_LOCKF From bec661231d9ca266e9469d12f57983f094d88bfd Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Wed, 5 Jul 2017 15:31:55 -0400 Subject: [PATCH 2/8] bpo-27584: Fixes for V2 Fixed syntax and naming problems. Fixed #ifdef AF_VSOCK checking Restored original aclocal.m4 --- Doc/library/socket.rst | 4 +- Lib/test/test_socket.py | 18 ++-- Misc/ACKS | 1 + Modules/socketmodule.h | 10 +- aclocal.m4 | 226 +++++++++++++++++++++++++++------------- 5 files changed, 169 insertions(+), 90 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 6590eabd53e6e0..d076666f11aa86 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -154,8 +154,8 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.6 - :const:`AF_VSOCK` allows communication between virtual machines and - their hosts. The sockets are represented as a (CID, port) tuple - where the context ID or CID and port are integers. + their hosts. The sockets are represented as a ``(CID,port)`` tuple + where the context ID or CID and port are integers. Availability: Linux >= 4.8. QEMU >= 2.8. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index c08579ee167b6d..7871d0aa2917a8 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -46,7 +46,7 @@ except ImportError: _socket = None -def getCid(): +def get_cid(): import struct import fcntl @@ -106,9 +106,8 @@ def _have_socket_alg(): def _have_socket_vsock(): """Check whether AF_VSOCK sockets are supported on this host.""" - if (getCid() == None): - return False - return True + ret = get_cid() is not None + return ret HAVE_SOCKET_CAN = _have_socket_can() @@ -230,6 +229,7 @@ def setUp(self): except OSError: self.skipTest('unable to bind RDS socket') + class ThreadableTest: """Threadable Test class @@ -415,12 +415,12 @@ def clientTearDown(self): @unittest.skipUnless(HAVE_SOCKET_VSOCK, 'VSOCK sockets required for this test.') -@unittest.skipUnless(getCid() != 2, +@unittest.skipUnless(get_cid() != 2, "This test can only be run on a virtual guest.") class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest): - def __init__(self, methodName = 'runTest'): - unittest.TestCase.__init__(self, methodName = methodName) + def __init__(self, methodName='runTest'): + unittest.TestCase.__init__(self, methodName=methodName) ThreadableTest.__init__(self) def setUp(self): @@ -436,7 +436,7 @@ def clientSetUp(self): time.sleep(0.1) self.cli = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) self.addCleanup(self.cli.close) - cid = getCid() + cid = get_cid() self.cli.connect((cid, VSOCKPORT)) def testStream(self): @@ -5790,7 +5790,7 @@ def test_main(): tests.append(LinuxKernelCryptoAPI) tests.extend([ BasicVSOCKTest, - ThreadedVSOCKSocketStreamTest + ThreadedVSOCKSocketStreamTest, ]) tests.extend([ CmsgMacroTests, diff --git a/Misc/ACKS b/Misc/ACKS index e1127bcc72b676..eadc5d34c4001b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -65,6 +65,7 @@ David Ascher Ammar Askar Chris AtLee Aymeric Augustin +Cathy Avery John Aycock Donovan Baarda Arne Babenhauserheide diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 4a5bbf497a8fa3..71d300c593ec00 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -108,10 +108,12 @@ typedef int socklen_t; #endif #ifdef HAVE_LINUX_VM_SOCKETS_H -#include -#ifndef AF_VSOCK -#define AF_VSOCK 40 -#endif +# include +# ifndef AF_VSOCK +# define AF_VSOCK 40 +# endif +#else +# undef AF_VSOCK #endif /* Linux 3.19 */ diff --git a/aclocal.m4 b/aclocal.m4 index 7975ec79f72bcf..2a745e57466cae 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.13.4 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -12,32 +12,63 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 1 (pkg-config-0.24) -# -# Copyright © 2004 Scott James Remnant . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) @@ -59,18 +90,19 @@ if test -n "$PKG_CONFIG"; then PKG_CONFIG="" fi fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -# only at the first occurence in configure.ac, so if the first place -# it's called might be skipped (such as if it is within an "if", you -# have to call PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ @@ -80,8 +112,10 @@ m4_ifvaln([$3], [else $3])dnl fi]) -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" @@ -93,10 +127,11 @@ m4_define([_PKG_CONFIG], else pkg_failed=untried fi[]dnl -])# _PKG_CONFIG +])dnl _PKG_CONFIG -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -104,19 +139,17 @@ if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then else _pkg_short_errors_supported=no fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl @@ -170,16 +203,40 @@ else AC_MSG_RESULT([yes]) $3 fi[]dnl -])# PKG_CHECK_MODULES +])dnl PKG_CHECK_MODULES + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC -# PKG_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable pkgconfigdir as the location where a module -# should install pkg-config .pc files. By default the directory is -# $libdir/pkgconfig, but the default can be changed by passing -# DIRECTORY. The user can override through the --with-pkgconfigdir -# parameter. + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -190,16 +247,18 @@ AC_ARG_WITH([pkgconfigdir], AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_INSTALLDIR +])dnl PKG_INSTALLDIR -# PKG_NOARCH_INSTALLDIR(DIRECTORY) -# ------------------------- -# Substitutes the variable noarch_pkgconfigdir as the location where a -# module should install arch-independent pkg-config .pc files. By -# default the directory is $datadir/pkgconfig, but the default can be -# changed by passing DIRECTORY. The user can override through the -# --with-noarch-pkgconfigdir parameter. +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], @@ -210,5 +269,22 @@ AC_ARG_WITH([noarch-pkgconfigdir], AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) -]) dnl PKG_NOARCH_INSTALLDIR +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR From c3027e5dd7355127d8a18189f2f392b39a52cf92 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Thu, 6 Jul 2017 14:26:37 -0400 Subject: [PATCH 3/8] bpo-27584: Fixes for V3 Added checking for fcntl and thread modules. --- Lib/test/test_socket.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 7871d0aa2917a8..02a84aca115ae1 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -47,9 +47,8 @@ _socket = None def get_cid(): - import struct - import fcntl - + if fcntl is None: + return None if not os.path.exists("/dev/vsock"): return None try: @@ -413,6 +412,8 @@ def clientTearDown(self): self.cli = None ThreadableTest.clientTearDown(self) +@unittest.skipIf(fcntl is None, "need fcntl") +@unittest.skipUnless(thread, 'Threading required for this test.') @unittest.skipUnless(HAVE_SOCKET_VSOCK, 'VSOCK sockets required for this test.') @unittest.skipUnless(get_cid() != 2, @@ -1933,7 +1934,8 @@ def _testCongestion(self): r, w, x = select.select([self.serv], [], [], 3.0) self.assertIn(self.serv, r) - + +@unittest.skipIf(fcntl is None, "need fcntl") @unittest.skipUnless(HAVE_SOCKET_VSOCK, 'VSOCK sockets required for this test.') class BasicVSOCKTest(unittest.TestCase): From d11a8db84242729da05c4d5bffe5228c91c4dfd6 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Thu, 6 Jul 2017 17:11:17 -0400 Subject: [PATCH 4/8] bpo-27584: Fixes for V4 Fixed white space error --- Lib/test/test_socket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 02a84aca115ae1..d34154d96d92dc 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1934,7 +1934,7 @@ def _testCongestion(self): r, w, x = select.select([self.serv], [], [], 3.0) self.assertIn(self.serv, r) - + @unittest.skipIf(fcntl is None, "need fcntl") @unittest.skipUnless(HAVE_SOCKET_VSOCK, 'VSOCK sockets required for this test.') From ce380ae3438a7b9bd5a1796e618fecebc45c06eb Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Thu, 17 Aug 2017 16:01:56 -0400 Subject: [PATCH 5/8] bpo-27584: Fixes for V5 Added back comma in (CID, port). --- Doc/library/socket.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index d076666f11aa86..83e1300acabb44 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -154,7 +154,7 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.6 - :const:`AF_VSOCK` allows communication between virtual machines and - their hosts. The sockets are represented as a ``(CID,port)`` tuple + their hosts. The sockets are represented as a ``(CID, port)`` tuple where the context ID or CID and port are integers. Availability: Linux >= 4.8. QEMU >= 2.8. From 0f653c65ff30396f69d499218699ef1d5a036fd3 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Thu, 24 Aug 2017 16:55:53 -0400 Subject: [PATCH 6/8] bpo-27584: Fixes for V6 Added news file. socket.rst now reflects first Linux introduction of AF_VSOCK. Fixed get_cid in test_socket.py. Replaced PyLong_FromLong with PyLong_FromUnsignedLong in socketmodule.c Got rid of extra AF_VSOCK #define. Added sockaddr_vm to sock_addr. --- Doc/library/socket.rst | 2 +- Lib/test/test_socket.py | 16 +++++----------- .../2017-08-24-14-03-14.bpo-27584.r11JHZ.rst | 2 ++ Modules/socketmodule.c | 6 +++--- Modules/socketmodule.h | 6 +++--- 5 files changed, 14 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-08-24-14-03-14.bpo-27584.r11JHZ.rst diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 83e1300acabb44..9accf7a14538b4 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -157,7 +157,7 @@ created. Socket addresses are represented as follows: their hosts. The sockets are represented as a ``(CID, port)`` tuple where the context ID or CID and port are integers. - Availability: Linux >= 4.8. QEMU >= 2.8. + Availability: Linux >= 3.9. .. versionadded:: 3.7 diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index d34154d96d92dc..50016ab615a23b 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -49,19 +49,13 @@ def get_cid(): if fcntl is None: return None - if not os.path.exists("/dev/vsock"): - return None - try: - fd = open("/dev/vsock", "rb") - except: - return None try: - r = fcntl.ioctl(fd, socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID, " ") - except: - fd.close() + with open("/dev/vsock", "rb") as f: + r = fcntl.ioctl(f, socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID, " ") + except OSError: return None - fd.close() - return struct.unpack("I", r)[0] + else: + return struct.unpack("I", r)[0] def _have_socket_can(): """Check whether CAN sockets are supported on this host.""" diff --git a/Misc/NEWS.d/next/Library/2017-08-24-14-03-14.bpo-27584.r11JHZ.rst b/Misc/NEWS.d/next/Library/2017-08-24-14-03-14.bpo-27584.r11JHZ.rst new file mode 100644 index 00000000000000..af4c583e186fbc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-08-24-14-03-14.bpo-27584.r11JHZ.rst @@ -0,0 +1,2 @@ +``AF_VSOCK`` has been added to the socket interface which allows +communication between virtual machines and their host. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 209cf371bb6ba0..a431e254d57c2a 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2642,7 +2642,7 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) #ifdef AF_VSOCK if (s->sock_family == AF_VSOCK) { - uint64_t vflag; + uint64_t vflag; // Must be set width of 64 bits /* setsockopt(level, opt, flag) */ if (PyArg_ParseTuple(args, "iiK:setsockopt", &level, &optname, &vflag)) { @@ -2735,13 +2735,13 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) if (buflen == 0) { #ifdef AF_VSOCK if (s->sock_family == AF_VSOCK) { - uint64_t vflag = 0; + uint64_t vflag = 0; // Must be set width of 64 bits flagsize = sizeof vflag; res = getsockopt(s->sock_fd, level, optname, (void *)&vflag, &flagsize); if (res < 0) return s->errorhandler(); - return PyLong_FromLong(vflag); + return PyLong_FromUnsignedLong(vflag); } #endif flagsize = sizeof flag; diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 71d300c593ec00..d82ea00e6a2dc7 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -109,9 +109,6 @@ typedef int socklen_t; #ifdef HAVE_LINUX_VM_SOCKETS_H # include -# ifndef AF_VSOCK -# define AF_VSOCK 40 -# endif #else # undef AF_VSOCK #endif @@ -202,6 +199,9 @@ typedef union sock_addr { #ifdef HAVE_SOCKADDR_ALG struct sockaddr_alg alg; #endif +#ifdef HAVE_LINUX_VM_SOCKETS_H + struct sockaddr_vm vm; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, From 42026f346c8a999643af1ae2e308b268fa417bc7 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Sat, 26 Aug 2017 17:49:26 -0400 Subject: [PATCH 7/8] bpo-27584: Fixes for V7 Minor cleanup. --- Doc/library/socket.rst | 2 +- Modules/socketmodule.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 9accf7a14538b4..42fd7ea0f0bd04 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -157,7 +157,7 @@ created. Socket addresses are represented as follows: their hosts. The sockets are represented as a ``(CID, port)`` tuple where the context ID or CID and port are integers. - Availability: Linux >= 3.9. + Availability: Linux >= 4.8 QEMU >= 2.8 ESX >= 4.0 ESX Workstation >= 6.5 .. versionadded:: 3.7 diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index d82ea00e6a2dc7..50eb3a7eca6f04 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -109,8 +109,6 @@ typedef int socklen_t; #ifdef HAVE_LINUX_VM_SOCKETS_H # include -#else -# undef AF_VSOCK #endif /* Linux 3.19 */ @@ -199,7 +197,7 @@ typedef union sock_addr { #ifdef HAVE_SOCKADDR_ALG struct sockaddr_alg alg; #endif -#ifdef HAVE_LINUX_VM_SOCKETS_H +#ifdef AF_VSOCK struct sockaddr_vm vm; #endif } sock_addr_t; From c3a94901c82a890c5a8a5f8c68b2ac5400ff1004 Mon Sep 17 00:00:00 2001 From: Cathy Avery Date: Tue, 5 Sep 2017 11:05:21 -0400 Subject: [PATCH 8/8] bpo-27584: Fixes for V8 Put back #undef AF_VSOCK as it is necessary when vm_sockets.h is not installed. --- Modules/socketmodule.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 50eb3a7eca6f04..03dbf18f7bd1a0 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -109,6 +109,8 @@ typedef int socklen_t; #ifdef HAVE_LINUX_VM_SOCKETS_H # include +#else +# undef AF_VSOCK #endif /* Linux 3.19 */