Skip to content
This repository has been archived by the owner on Nov 9, 2020. It is now read-only.

Commit

Permalink
Updates vmci_client C library for DLL generation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
venilnoronha committed Jun 20, 2017
1 parent 6289773 commit c4a14c5
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 42 deletions.
66 changes: 24 additions & 42 deletions esx_service/vmci/vmci_client.c
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>
#include <assert.h>

#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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

//
Expand Down Expand Up @@ -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)
{
Expand Down
20 changes: 20 additions & 0 deletions esx_service/vmci/vmci_client.def
Original file line number Diff line number Diff line change
@@ -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
71 changes: 71 additions & 0 deletions esx_service/vmci/vmci_client.h
Original file line number Diff line number Diff line change
@@ -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 <stdlib.h>
#include <errno.h>
#include <stdint.h>

#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
// <ans> 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);

0 comments on commit c4a14c5

Please sign in to comment.