Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-27584: New addition of vSockets to the python socket module #2489

Merged
merged 8 commits into from
Sep 6, 2017
Merged

bpo-27584: New addition of vSockets to the python socket module #2489

merged 8 commits into from
Sep 6, 2017

Conversation

caavery
Copy link
Contributor

@caavery caavery commented Jun 29, 2017

Support for AF_VSOCK on Linux only

https://bugs.python.org/issue27584

@caavery
Copy link
Contributor Author

caavery commented Jun 29, 2017

The patch is also in Issue number 27584 along with a README file that explains how to setup the environment for tests.

case AF_VSOCK:
{
struct sockaddr_vm *a = (struct sockaddr_vm *) addr;
return Py_BuildValue("II", a->svm_cid, a->svm_port);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the line failing in the Travis. https://travis-ci.org/python/cpython/jobs/248412030#L2063

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have the proper headers.
checking for linux/vm_sockets.h... no

So it looks like my checking for HAVE_LINUX_VM_SOCKETS_H is faulty.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so please update that, and push in your branch, the bots will pick up the changes and will test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've restored the original aclocal.m4 and fixed the issues you pointed out.

Thank you for your review,

Cathy

aclocal.m4 Outdated
@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*-
# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using an old version here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have an older version installed. automake-1.13.4-3.el7.noarch I can upgrade that.

So do I make the corrections and ask for another pull?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just update this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebased my code to remove my patch. Is rebasing and pushing an acceptable way to make changes? Or do I need to add a new commit each time?

Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to remove the aclocal.m4 from my patch.

Copy link
Member

@berkerpeksag berkerpeksag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR. Could you please add your name to Misc/ACKS?

@@ -75,12 +94,20 @@ 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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use a shorter version:

return getCid() is not None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is get_cid acceptable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry wrong comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this syntax. It looks like return the cid if it is not None or do nothing and continue. getCid will return an integer or None. I want to translate that into return True or False in _have_socket_vsock().

Copy link
Contributor

@musically-ut musically-ut Jul 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caavery read @berkerpeksag's suggestion as a contraction of the following:

    foo = getCid is not None
    return foo

foo will contain a boolean value which will be returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's what I was trying to say. Sorry for being unclear!

And +1 for renaming it to get_cid, thanks!

@@ -191,7 +218,6 @@ def setUp(self):
except OSError:
self.skipTest('unable to bind RDS socket')


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't make unrelated cosmetic changes.

@@ -5627,6 +5734,10 @@ def test_main():
tests.extend([BasicRDSTest, RDSTest])
tests.append(LinuxKernelCryptoAPI)
tests.extend([
BasicVSOCKTest,
ThreadedVSOCKSocketStreamTest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: Please add trailing comma.

@@ -44,6 +46,23 @@
except ImportError:
_socket = None

def getCid():
import struct
import fcntl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to check if fcntl is available on the platform.

@@ -149,6 +149,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is off here:

- :const:`AF_VSOCK` allows [...]
  their hosts. [...]

  Availability: Linux >= 4.8. QEMU >= 2.8.

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to mention QEMU here? I'd say just document kernel version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I thought it would be better informationally to have it in but if it is not acceptable I can remove it.

@@ -149,6 +149,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: (CID, port) -> ``(CID, port)``

@@ -44,6 +46,23 @@
except ImportError:
_socket = None

def getCid():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: Can we use an under_score name here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is get_cid acceptable?

"This test can only be run on a virtual guest.")
class ThreadedVSOCKSocketStreamTest(unittest.TestCase, ThreadableTest):

def __init__(self, methodName = 'runTest'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: No need to add spaces around =.

methodName= 'runTest'

Same for line 411:

methodName=methodName

@berkerpeksag
Copy link
Member

berkerpeksag commented Jul 7, 2017

Looks like your branch contains additional commits and unfortunately it makes code review harder. Could you rebase your branch against current master? You might find https://devguide.python.org/gitbootcamp/#syncing-with-upstream helpful.

@caavery
Copy link
Contributor Author

caavery commented Jul 7, 2017

@berkerpeksag

So you want me to sync my github branch bpo-27584 with the upstream cpython branch? Is that correct? I'm just a little unclear as to what you are asking.

Cathy

@caavery
Copy link
Contributor Author

caavery commented Jul 7, 2017

@berkerpeksag

Or do you want me to rebase both my master ( fork of upstream ) and my bpo-27584 branch?

Thanks again

@berkerpeksag
Copy link
Member

So you want me to sync my github branch bpo-27584 with the upstream cpython branch? Is that correct?

Correct. Your branch bpo-27584 now contains 34 commits and 30 of them are unrelated to the vSockets feature as you can see at https://github.com/python/cpython/pull/2489/files (the reason is probably this merge commit)

@caavery
Copy link
Contributor Author

caavery commented Jul 7, 2017

@berkerpeksag

Sorry I seem to have an issue.
git fetch upstream
git rebase upstream/master

Python Dev~/caavery.github/cpython# git push origin bpo-27584
To git@github.com:caavery/cpython.git
! [rejected] bpo-27584 -> bpo-27584 (non-fast-forward)
error: failed to push some refs to 'git@github.com:caavery/cpython.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

@caavery
Copy link
Contributor Author

caavery commented Jul 7, 2017

@berkerpeksag

Sorry this is my first time with github and working with remote branches. I just forced the push into my branch bpo-27584. My branch says that 'This branch is 4 commits ahead of python:master. ' which is what I think you wanted.

@berkerpeksag
Copy link
Member

My branch says that 'This branch is 4 commits ahead of python:master. ' which is what I think you wanted.

Looks great, thanks! I will try to take another look at the patch while we wait for Kushal's review.

@caavery
Copy link
Contributor Author

caavery commented Jul 19, 2017

@kushaldas

Is there anything else I should be doing? The patches have passed all tests so far and I have addressed all the issues raised.

Thanks,

Cathy

@@ -149,6 +149,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't there be space after coma? (CID, port).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that got accidentally deleted.

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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that vsockets originated with VMWare, add a note that they are available in that environment also?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit more complicated. The availability in a particular linux kernel depends on the implementation.
virtio-vsock is Linux >= 4.8. QEMU >= 2.8.
vmci_transport is Linux >= 3.9
Should I just change it to when it first appeared which is v3.9?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant availability when running under the VMWare hypervisor. As for the kernel, to keep it simple, whichever version supplies full functionality with both qemu and vmware.

Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments.

You also have to add the vsock struct to typedef union sock_addr in socketmodule.h.

Please use blurb to add a news entry, too.

def get_cid():
if fcntl is None:
return None
if not os.path.exists("/dev/vsock"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite this block with proper context manager. You can skip the os.path.exists check, too.

try:
    with open(...) as f:
        r = fcntl.ioctl(f, socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID, "    ")
except OSError:
    return None
else:
    return struct.unpack("I", r)[0]

socklen_t flagsize = sizeof flag;
#ifdef AF_VSOCK
if (s->sock_family == AF_VSOCK) {
uint64_t vflag = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been starring at this block for a minute until I realized that it handles uint64_t instead of int. Please add a comment that this block that explains the difference.

(void *)&vflag, &flagsize);
if (res < 0)
return s->errorhandler();
return PyLong_FromLong(vflag);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an uint64_t, you have to use PyLong_FromUnsignedLong().

#ifdef HAVE_LINUX_VM_SOCKETS_H
# include <linux/vm_sockets.h>
# ifndef AF_VSOCK
# define AF_VSOCK 40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?

@bedevere-bot
Copy link

A Python core developer, tiran, has requested some changes be
made to your pull request before we can consider merging it. If you
could please address their requests along with any other requests in
other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment
on this pull request containing the phrase I didn't expect the Spanish Inquisition!
I will then notify tiran along with any other core developers
who have left a review that you're ready for them to take another look
at this pull request.

@caavery
Copy link
Contributor Author

caavery commented Aug 25, 2017

I didn't expect the Spanish Inquisition!

@bedevere-bot
Copy link

Nobody expects the Spanish Inquisition!

@kushaldas, @tiran: please review the changes made to this pull request.

Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are almost there!

#ifdef HAVE_LINUX_VM_SOCKETS_H
# include <linux/vm_sockets.h>
#else
# undef AF_VSOCK
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think #undef AF_VSOCK is necessary. Please remove it.

Copy link
Contributor Author

@caavery caavery Aug 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be there. In the case that vm_sockets.h is not available in include/linux which is the case on the last build bot run. Not all of the bots have the newer kernel.That way the code dependent on vm_sockets.h (AF_VSOCK) will not try to compile.

checking for linux/vm_sockets.h... no

This is also the way its done it at the top of socketmodule.h with AF_NETLINK

I also noticed AF_CAN was not adding the #undef AF_CAN in socketmodule.h so I renamed linux/can.h, ran configure and make and sure enough any code conditionally compiling under #ifdef AF_CAN in socketmodule.c failed.

@@ -193,6 +199,9 @@ typedef union sock_addr {
#ifdef HAVE_SOCKADDR_ALG
struct sockaddr_alg alg;
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be consistent and use #ifdef AF_VSOCK in all places.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I didn't expect the Spanish Inquisition!. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@caavery
Copy link
Contributor Author

caavery commented Aug 26, 2017

OK there seems to be a problem with the build now. I'll address it next week. Thanks.

@tiran
Copy link
Member

tiran commented Aug 28, 2017

You were right, either #undef AF_VSOCK is required or you have to replace all #ifdef AF_VSOCK with #ifdef HAVE_LINUX_VM_SOCKETS_H. The address family and the VM socket struct are defined in different header files. AF_VSOCK can be present w/o linux/vm_sockets.h.

@caavery
Copy link
Contributor Author

caavery commented Sep 5, 2017

I didn't expect the Spanish Inquisition!

@bedevere-bot
Copy link

Nobody expects the Spanish Inquisition!

@kushaldas, @tiran: please review the changes made to this pull request.

Fixed syntax and naming problems.
Fixed #ifdef AF_VSOCK checking
Restored original aclocal.m4
Added checking for fcntl and thread modules.
Fixed white space error
Added back comma in (CID, port).
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.
Minor cleanup.
Put back #undef AF_VSOCK as it is  necessary when vm_sockets.h is not installed.
Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@vstinner
Copy link
Member

FYI I wrote PR gh-119463 to skip the tests if get_cid() returns VMADDR_CID_ANY. Apparently, the Linux kernel 6.9 changed /dev/vsock device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.