vchan modifications for the Windows build.

This commit is contained in:
Alexander Tereshkin 2012-05-12 19:27:09 +04:00
parent 0f13ea2a84
commit 7ea3f4a792
4 changed files with 178 additions and 32 deletions

View File

@ -19,6 +19,8 @@
*
*/
#ifndef WINNT
#include <sys/types.h>
#include <sys/unistd.h>
#include <sys/stat.h>
@ -27,18 +29,66 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include <xs.h>
#include <string.h>
#include <xenctrl.h>
#include <unistd.h>
#include <stdlib.h>
#include "libvchan.h"
#ifndef CONFIG_STUBDOM
#include "../u2mfn/u2mfnlib.h"
#else
#include <mm.h>
#endif
#endif
#include <xs.h>
#include <stdio.h>
#include <stdlib.h>
#include "libvchan.h"
static int fill_ctrl(struct libvchan *ctrl, struct vchan_interface *ring, int ring_ref)
{
if (!ctrl || !ring)
return -1;
ctrl->ring = ring;
ctrl->ring_ref = ring_ref;
ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out =
0;
ring->server_closed = ring->client_closed = 0;
ring->debug = 0xaabbccdd;
return 0;
}
#ifdef WINNT
static int ring_init(struct libvchan *ctrl)
{
struct gntmem_handle* h;
grant_ref_t grants[1];
int result;
struct vchan_interface *ring;
h = gntmem_open();
if (h == INVALID_HANDLE_VALUE)
return -1;
gntmem_set_local_quota(h, 1);
gntmem_set_global_quota(h, 1);
memset(grants, 0, sizeof(grants));
ring = gntmem_grant_pages_to_domain(h, 0, 1, grants);
if (!ring) {
gntmem_close(h);
return -1;
}
return fill_ctrl(ctrl, ring, grants[0]);
}
#else
static int ring_init(struct libvchan *ctrl)
{
int mfn;
@ -61,14 +111,11 @@ static int ring_init(struct libvchan *ctrl)
return -1;
#endif
ctrl->ring = ring;
ctrl->ring_ref = mfn;
ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out =
0;
ring->server_closed = ring->client_closed = 0;
ring->debug = 0xaabbccdd;
return 0;
return fill_ctrl(ctrl, ring, mfn);
}
#endif
/**
creates event channel;
creates "ring-ref" and "event-channel" xenstore entries;
@ -86,12 +133,16 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
unsigned int len;
/* XXX temp hack end */
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_evtchn *evfd;
xc_evtchn *evfd;
#else
int evfd;
EVTCHN evfd;
#endif
evtchn_port_or_error_t port;
#ifdef WINNT
xs = xs_domain_open();
#else
xs = xs_daemon_open();
#endif
if (!xs) {
return ret;
}
@ -117,6 +168,10 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
if (domid_s)
domid = atoi(domid_s);
snprintf(buf, sizeof buf, "device/vchan/%d/version", devno);
if (!xs_write(xs, 0, buf, "2", strlen("2")))
goto fail2;
snprintf(ref, sizeof ref, "%d", ctrl->ring_ref);
snprintf(buf, sizeof buf, "device/vchan/%d/ring-ref", devno);
if (!xs_write(xs, 0, buf, ref, strlen(ref)))
@ -151,8 +206,12 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
if (ret)
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_evtchn_close(evfd);
#else
#ifdef WINNT
xc_evtchn_close(evfd);
#else
close(evfd);
#endif
#endif
fail:
xs_daemon_close(xs);
@ -197,6 +256,8 @@ struct libvchan *libvchan_server_init(int devno)
return ctrl;
}
#ifndef WINNT
int libvchan_server_handle_connected(struct libvchan *ctrl)
{
struct xs_handle *xs;
@ -241,14 +302,16 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
unsigned int len;
struct xs_handle *xs;
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_interface *xcfd;
xc_interface *xcfd;
#else
int xcfd;
#endif
int xcg;
char buf[64];
char *ref;
int version;
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_evtchn *evfd;
xc_evtchn *evfd;
#else
int evfd;
#endif
@ -257,6 +320,18 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
if (!xs) {
return ret;
}
version = 1;
snprintf(buf, sizeof buf,
"/local/domain/%d/device/vchan/%d/version", domain,
devno);
ref = xs_read(xs, 0, buf, &len);
if (ref) {
version = atoi(ref);
free(ref);
}
snprintf(buf, sizeof buf,
"/local/domain/%d/device/vchan/%d/ring-ref", domain,
devno);
@ -277,23 +352,40 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
free(ref);
if (!remote_port)
goto fail;
switch (version) {
case 1:
#ifdef XENCTRL_HAS_XC_INTERFACE
xcfd = xc_interface_open(NULL, NULL, 0);
if (!xcfd)
goto fail;
xcfd = xc_interface_open(NULL, NULL, 0);
if (!xcfd)
goto fail;
#else
xcfd = xc_interface_open();
if (xcfd < 0)
goto fail;
xcfd = xc_interface_open();
if (xcfd < 0)
goto fail;
#endif
ctrl->ring = (struct vchan_interface *)
xc_map_foreign_range(xcfd, domain, 4096,
PROT_READ | PROT_WRITE, ctrl->ring_ref);
ctrl->ring = (struct vchan_interface *)
xc_map_foreign_range(xcfd, domain, 4096,
PROT_READ | PROT_WRITE, ctrl->ring_ref);
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_interface_close(xcfd);
xc_interface_close(xcfd);
#else
close(xcfd);
close(xcfd);
#endif
break;
case 2:
xcg = xc_gnttab_open();
if (xcg < 0)
goto fail;
ctrl->ring = (struct vchan_interface *)
xc_gnttab_map_grant_ref(xcg, domain, ctrl->ring_ref, PROT_READ | PROT_WRITE);
xc_gnttab_close(xcg);
break;
default:
goto fail;
}
if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED)
goto fail;
#ifdef XENCTRL_HAS_XC_INTERFACE
@ -312,7 +404,7 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_evtchn_close(evfd);
#else
close(evfd);
close(evfd);
#endif
else
ret = 0;
@ -338,3 +430,19 @@ struct libvchan *libvchan_client_init(int domain, int devno)
ctrl->is_server = 0;
return ctrl;
}
#else
// Windows domains can not be dom0
int libvchan_server_handle_connected(struct libvchan *ctrl)
{
return -1;
}
struct libvchan *libvchan_client_init(int domain, int devno)
{
return NULL;
}
#endif

View File

@ -20,10 +20,15 @@
*/
#include "libvchan.h"
#ifndef WINNT
#include <xenctrl.h>
#include <string.h>
#include <errno.h>
#include <sys/select.h>
#endif
#include <string.h>
/**
\return How much data is immediately available for reading
*/
@ -166,7 +171,7 @@ int libvchan_close(struct libvchan *ctrl)
}
/// The fd to use for select() set
int libvchan_fd_for_select(struct libvchan *ctrl)
EVTCHN libvchan_fd_for_select(struct libvchan *ctrl)
{
return xc_evtchn_fd(ctrl->evfd);
}

View File

@ -22,7 +22,18 @@
#ifndef _LIBVCHAN_H
#define _LIBVCHAN_H
#ifdef WINNT
#include <windows.h>
#include <xen_gntmem.h>
#include <xs.h>
typedef HANDLE EVTCHN;
#define snprintf _snprintf
#else
#include <stdint.h>
typedef int EVTCHN;
#endif
#include <xenctrl.h>
typedef uint32_t VCHAN_RING_IDX;
@ -42,9 +53,9 @@ struct libvchan {
uint32_t ring_ref;
/// descriptor to event channel interface
#ifdef XENCTRL_HAS_XC_INTERFACE
xc_evtchn *evfd;
xc_evtchn *evfd;
#else
int evfd;
EVTCHN evfd;
#endif
int evport;
int devno;
@ -55,16 +66,16 @@ struct libvchan {
};
struct libvchan *libvchan_server_init(int devno);
int libvchan_server_handle_connected(struct libvchan *ctrl);
struct libvchan *libvchan_client_init(int domain, int devno);
int libvchan_server_handle_connected(struct libvchan *ctrl);
int libvchan_write(struct libvchan *ctrl, char *data, int size);
int libvchan_read(struct libvchan *ctrl, char *data, int size);
int libvchan_wait(struct libvchan *ctrl);
int libvchan_close(struct libvchan *ctrl);
void libvchan_prepare_to_select(struct libvchan *ctrl);
int libvchan_fd_for_select(struct libvchan *ctrl);
EVTCHN libvchan_fd_for_select(struct libvchan *ctrl);
int libvchan_is_eof(struct libvchan *ctrl);
int libvchan_data_ready(struct libvchan *ctrl);
int libvchan_buffer_space(struct libvchan *ctrl);

22
vchan/sources Normal file
View File

@ -0,0 +1,22 @@
TARGETNAME=libvchan
TARGETTYPE=LIBRARY
TARGETPATH=..\libs
#BUILD_PASS0_CONSUMES=gntmem evtchn xenstore
#BUILD_PASS0_PRODUCES=vchan
USE_MSVCRT=1
DLLDEF=libvchan.def
INCLUDES=$(INCLUDES); \
..\include;\
SOURCES=io.c init.c
TARGETLIBS=\
$(SDK_LIB_PATH)\setupapi.lib \
$(SDK_LIB_PATH)\kernel32.lib