From c4a14c5307d835749aed76fcf151e74546ab15e0 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Mon, 12 Jun 2017 13:24:57 -0700 Subject: [PATCH] Updates vmci_client C library for DLL generation esx_vmdkcmd.go uses CGO for making vmci_client calls to communicate with the VMDKOps service on ESXi. By default, CGO supports gcc, which creates compatibility issues on Windows, because, the vmci_client implementation depends on libraries provided by Microsoft Build Tools. This commit enables exporting of the vmci_client library as a Windows DLL, which can then be used with the regular MinGW-w64 gcc on Windows for making calls via CGO. * Extracted header file from vmci_client.c * Updated vmci_client impl to support Winsock * Added vmci_client.def for DLL export --- esx_service/vmci/vmci_client.c | 66 +++++++++++------------------ esx_service/vmci/vmci_client.def | 20 +++++++++ esx_service/vmci/vmci_client.h | 71 ++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 esx_service/vmci/vmci_client.def create mode 100644 esx_service/vmci/vmci_client.h diff --git a/esx_service/vmci/vmci_client.c b/esx_service/vmci/vmci_client.c index 931fd6b41..58e6dadb6 100644 --- a/esx_service/vmci/vmci_client.c +++ b/esx_service/vmci/vmci_client.c @@ -1,4 +1,4 @@ -// Copyright 2016 VMware, Inc. All Rights Reserved. +// Copyright 2016-2017 VMware, Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,52 +18,16 @@ // // Called mainly from Go code. // -// API: Exposes only Vmci_GetReply. The call is blocking. +// API: Exposes Vmci_GetReply and Vmci_FreeBuf. The calls are blocking. // +// For details on _WIN32 specific handling, please refer to the following link: +// https://pubs.vmware.com/vsphere-65/topic/com.vmware.vmci.pg.doc/vsockStreams.5.4.html // #include -#include -#include -#include #include -#include "vmci_sockets.h" -#include "connection_types.h" - -#define ERR_BUF_LEN 512 - -// operations status. 0 is OK -typedef int be_sock_status; - -// -// Booking structure for opened VMCI / vSocket -// -typedef struct { - int sock_id; // socket id for socket APIs - struct sockaddr_vm addr; // held here for bookkeeping and reporting -} be_sock_id; - -// -// Protocol message structure: request and reply -// - -typedef struct be_request { - uint32_t mlen; // length of message (including trailing \0) - const char *msg; // null-terminated immutable JSON string. -} be_request; - -#define MAXBUF 1024 * 1024 // Safety limit. We do not expect json string > 1M -#define MAX_CLIENT_PORT 1023 // Last privileged port -#define START_CLIENT_PORT 100 // Where to start client port - -// Retry entire range on bind failures -#define BIND_RETRY_COUNT (MAX_CLIENT_PORT - START_CLIENT_PORT) - -typedef struct be_answer { - char *buf; // response buffer - char errBuf[ERR_BUF_LEN]; // error response buffer -} be_answer; +#include "vmci_client.h" // // Interface for communication to "command execution" server. @@ -171,6 +135,17 @@ dummy_get_reply(be_sock_id *id, be_request *r, be_answer* a) static be_sock_status vsock_init(be_sock_id *id, int cid, int port) { + #ifdef _WIN32 + WORD versionRequested = MAKEWORD(2, 2); + WSADATA wsaData; + int wsaErr = WSAStartup(versionRequested, &wsaData); + if (wsaErr != 0) { + printf(stderr, "vsock_init: (%d) could not register with Winsock DLL.\n", wsaErr); + errno = wsaErr; + return CONN_FAILURE; + } + #endif + static int round_robin = START_CLIENT_PORT; // Round robin client bind port int ret; int af; // family id @@ -316,7 +291,11 @@ vsock_get_reply(be_sock_id *s, be_request *r, be_answer* a) static void vsock_release(be_sock_id *id) { - close(id->sock_id); + #ifdef _WIN32 + closesocket(id->sock_id); + #else + close(id->sock_id); + #endif } // @@ -366,6 +345,9 @@ Vmci_GetReply(int port, const char* json_request, const char* be_name, return host_request(be, &req, ans, ESX_VMCI_CID, port); } +// +// Frees a be_answer instance. +// void Vmci_FreeBuf(be_answer *ans) { diff --git a/esx_service/vmci/vmci_client.def b/esx_service/vmci/vmci_client.def new file mode 100644 index 000000000..a21d7c467 --- /dev/null +++ b/esx_service/vmci/vmci_client.def @@ -0,0 +1,20 @@ +; Copyright 2017 VMware, Inc. All Rights Reserved. +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; +; This file defines the APIs exported by the vmci_client.dll. +; Only Vmci_GetReply and Vmci_FreeBuf functions are exported. + +EXPORTS + Vmci_GetReply + Vmci_FreeBuf diff --git a/esx_service/vmci/vmci_client.h b/esx_service/vmci/vmci_client.h new file mode 100644 index 000000000..aba5e08dc --- /dev/null +++ b/esx_service/vmci/vmci_client.h @@ -0,0 +1,71 @@ +// Copyright 2017 VMware, Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// +// VMCI sockets communication - client side. +// +// API: Exposes Vmci_GetReply and Vmci_FreeBuf. +// + +#include +#include +#include + +#include "vmci_sockets.h" +#include "connection_types.h" + +#define ERR_BUF_LEN 512 +#define MAXBUF 1024 * 1024 // Safety limit. We do not expect json string > 1M +#define MAX_CLIENT_PORT 1023 // Last privileged port +#define START_CLIENT_PORT 100 // Where to start client port +#define BIND_RETRY_COUNT (MAX_CLIENT_PORT - START_CLIENT_PORT) // Retry entire range on bind failures + +// Operations status. 0 is OK +typedef int be_sock_status; + +// +// Booking structure for opened VMCI / vSocket +// +typedef struct { + int sock_id; // socket id for socket APIs + struct sockaddr_vm addr; // held here for bookkeeping and reporting +} be_sock_id; + +// +// Protocol message structure: request and reply +// +typedef struct be_request { + uint32_t mlen; // length of message (including trailing \0) + const char *msg; // null-terminated immutable JSON string. +} be_request; + +typedef struct be_answer { + char *buf; // response buffer + char errBuf[ERR_BUF_LEN]; // error response buffer +} be_answer; + +// +// Entry point for vsocket requests. +// Returns NULL for success, -1 for err, and sets errno if needed +// is allocated upstairs +// +const be_sock_status +Vmci_GetReply(int port, const char* json_request, const char* be_name, be_answer* ans); + +// +// Frees a be_answer instance. +// +void +Vmci_FreeBuf(be_answer *ans);