Hi Alin, thanks a lot for the review. On the device name for the create file system call we need to use the following definition from the interface header file: #define OVS_DEVICE_NAME_USER TEXT("\\\\.\\OpenvSwitchDevice") This is its purpose.
There is no GetLastError() for Linux. Good catch! I'll fix the typo and will send a new patch soon. Eitan -----Original Message----- From: Alin Serdean [mailto:aserd...@cloudbasesolutions.com] Sent: Thursday, September 04, 2014 11:43 PM To: Eitan Eliahu; dev@openvswitch.org Subject: RE: [ovs-dev] [PATCH v1] Windows NetLink Socket - Support for asynchronous event notification Hi Eitan, #else sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { + int last_error = GetLastError(); The above breaks linux build. You could leave last_error outside and use it wherever appropriate. #define OVS_DEVICE_NAME_NT L"\\Device\\OpenvSwitchDevice" in OvsDpInterfaceExt.h is different from sock->handle = CreateFile(TEXT("\\\\.\\OpenVSwitchDevice"). We should also include the file instead of hardcode it in the future. pend_io_request can be included in nl_sock_wait but that is just a preference. Beside spacing issues near createfile and some spelling "structure event associated" I thing this patch is good to go. Thanks, Alin. -----Mesaj original----- De la: dev [mailto:dev-boun...@openvswitch.org] În numele Eitan Eliahu Trimis: Thursday, September 4, 2014 1:24 PM Către: dev@openvswitch.org Subiect: [ovs-dev] [PATCH v1] Windows NetLink Socket - Support for asynchronous event notification We keep an outstanding, out of band, I/O request in the driver at all time. Once an event generated the driver queues the event message, completes the pending I/O and unblocks the calling thread through setting the event in the overlapped structure n the NL socket. The thread will read all all event messages synchronous through the call of nl_sock_recv() Signed-off-by: Eitan Eliahu elia...@vmware.com --- datapath-windows/include/OvsDpInterfaceExt.h | 1 + lib/netlink-socket.c | 82 ++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h index 73dfcbe..ab2088a 100644 --- a/datapath-windows/include/OvsDpInterfaceExt.h +++ b/datapath-windows/include/OvsDpInterfaceExt.h @@ -70,6 +70,7 @@ /* Commands available under the OVS_WIN_CONTROL_FAMILY. */ enum ovs_win_control_cmd { OVS_CTRL_CMD_WIN_GET_PID, + OVS_CTRL_CMD_WIN_PEND_REQ }; #endif /* __OVS_DP_INTERFACE_EXT_H_ */ diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index a6be186..4b535f0 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -80,6 +80,7 @@ static int get_sock_pid_from_kernel(struct nl_sock *sock); struct nl_sock { #ifdef _WIN32 HANDLE handle; + OVERLAPPED overlapped; #else int fd; #endif @@ -139,21 +140,30 @@ nl_sock_create(int protocol, struct nl_sock **sockp) sock = xmalloc(sizeof *sock); #ifdef _WIN32 - sock->handle = CreateFileA("\\\\.\\OpenVSwitchDevice", + sock->handle = CreateFile(TEXT("\\\\.\\OpenVSwitchDevice"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - - int last_error = GetLastError(); + FILE_FLAG_OVERLAPPED, NULL); if (sock->handle == INVALID_HANDLE_VALUE) { + int last_error = GetLastError(); + VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); + goto error; + } + + memset(&sock->overlapped, 0, sizeof sock->overlapped); + sock->overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (sock->overlapped.hEvent == NULL) { + int last_error = GetLastError(); VLOG_ERR("fcntl: %s", ovs_strerror(last_error)); goto error; } + #else sock->fd = socket(AF_NETLINK, SOCK_RAW, protocol); if (sock->fd < 0) { + int last_error = GetLastError(); VLOG_ERR("fcntl: %s", ovs_strerror(errno)); goto error; } @@ -221,6 +231,9 @@ error: } } #ifdef _WIN32 + if (sock->overlapped.hEvent) { + CloseHandle(sock->overlapped.hEvent); + } if (sock->handle != INVALID_HANDLE_VALUE) { CloseHandle(sock->handle); } @@ -248,6 +261,9 @@ nl_sock_destroy(struct nl_sock *sock) { if (sock) { #ifdef _WIN32 + if (sock->overlapped.hEvent) { + CloseHandle(sock->overlapped.hEvent); + } CloseHandle(sock->handle); #else close(sock->fd); @@ -1040,12 +1056,70 @@ nl_dump_done(struct nl_dump *dump) return status == EOF ? 0 : status; } +#ifdef _WIN32 +/* Pend an I/O request in the driver. The driver completes the I/O +whenever +* an event or a packet is ready to be read. Once the I/O is completed +* the overlapped structure event assocaited with the pending I/O will +be set */ static int pend_io_request(const struct nl_sock *sock) { + struct ofpbuf request; + uint64_t request_stub[128]; + struct ovs_header *ovs_header; + struct nlmsghdr *nlmsg; + uint32_t seq; + int retval; + int error; + DWORD bytes; + OVERLAPPED *overlapped = &sock->overlapped; + + int ovs_msg_size = sizeof (struct nlmsghdr) + sizeof (struct genlmsghdr) + + sizeof (struct ovs_header); + + ofpbuf_use_stub(&request, request_stub, sizeof request_stub); + + seq = nl_sock_allocate_seq(sock, 1); + nl_msg_put_genlmsghdr(&request, 0, OVS_WIN_NL_CTRL_FAMILY_ID, 0, + OVS_CTRL_CMD_WIN_PEND_REQ, OVS_WIN_CONTROL_VERSION); + nlmsg = nl_msg_nlmsghdr(&request); + nlmsg->nlmsg_seq = seq; + + ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header); + ovs_header->dp_ifindex = 0; + + if (!DeviceIoControl(sock->handle, OVS_IOCTL_WRITE, + ofpbuf_data(&request), ofpbuf_size(&request), + NULL, 0, &bytes, overlapped)) { + error = GetLastError(); + /* Check if the I/O got pended */ + if (error != ERROR_IO_INCOMPLETE && error != ERROR_IO_PENDING) { + VLOG_ERR("nl_sock_wait failed - %s\n", ovs_format_message(error)); + retval = EINVAL; + goto done; + } + } + else { + /* The I/O was completed synchronously */ + poll_immediate_wake(); + } + retval = 0; + +done: + ofpbuf_uninit(&request); + return retval; +} +#endif /* _WIN32 */ + /* Causes poll_block() to wake up when any of the specified 'events' (which is * a OR'd combination of POLLIN, POLLOUT, etc.) occur on 'sock'. */ void nl_sock_wait(const struct nl_sock *sock, short int events) { #ifdef _WIN32 + if (sock->overlapped.Internal != STATUS_PENDING) { + pend_io_request(sock); + } poll_fd_wait(sock->handle, events); #else poll_fd_wait(sock->fd, events); -- 1.9.4.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org https://urldefense.proofpoint.com/v1/url?u=http://openvswitch.org/mailman/listinfo/dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=yTvML8OxA42Jb6ViHe7fUXbvPVOYDPVq87w43doxtlY%3D%0A&m=LYg6l7lSsHTL5W%2BH0g0oMZ8o8rUgZUKPezGzHX53B%2F8%3D%0A&s=92988d0e5a9448edb96cc3b8780b5f630ef1ec7837bdd345fe5d3bf74cff46e6 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev