dom0: vchan version for stubdom
This commit is contained in:
parent
277cdd9173
commit
0c811322c5
36
vchan/Makefile.stubdom
Normal file
36
vchan/Makefile.stubdom
Normal file
@ -0,0 +1,36 @@
|
||||
#
|
||||
# The Qubes OS Project, http://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2012 Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
#
|
||||
|
||||
# Assume it is placed as xen-root/tools/vchan
|
||||
|
||||
XEN_ROOT = ../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
CFLAGS+=-Wall -I$(XEN_ROOT)/tools/libxc -DCONFIG_STUBDOM
|
||||
all: libvchan.a
|
||||
|
||||
libvchan.a: init.o io.o
|
||||
$(AR) rc $@ $^
|
||||
|
||||
clean:
|
||||
rm -f *.o *so *~ client server node node-select
|
||||
|
||||
|
87
vchan/init.c
87
vchan/init.c
@ -19,6 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -29,25 +32,38 @@
|
||||
#include <xenctrl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <mm.h>
|
||||
#include "libvchan.h"
|
||||
#ifndef CONFIG_STUBDOM
|
||||
#include "../u2mfn/u2mfnlib.h"
|
||||
#endif
|
||||
|
||||
static int ring_init(struct libvchan *ctrl)
|
||||
{
|
||||
int u2mfn = open("/proc/u2mfn", O_RDONLY);
|
||||
int mfn;
|
||||
struct vchan_interface *ring;
|
||||
#ifdef CONFIG_STUBDOM
|
||||
ring = (struct vchan_interface *) memalign(XC_PAGE_SIZE, sizeof(*ring));
|
||||
|
||||
if (!ring)
|
||||
return -1;
|
||||
|
||||
|
||||
mfn = virtual_to_mfn(ring);
|
||||
#else
|
||||
int u2mfn = open("/proc/u2mfn", O_RDONLY);
|
||||
ring = (struct vchan_interface *) u2mfn_alloc_kpage ();
|
||||
|
||||
if (ring == MAP_FAILED)
|
||||
return -1;
|
||||
|
||||
ctrl->ring = ring;
|
||||
if (u2mfn_get_last_mfn (&mfn) < 0)
|
||||
return -1;
|
||||
|
||||
ctrl->ring_ref = mfn;
|
||||
close(u2mfn);
|
||||
#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;
|
||||
@ -65,13 +81,18 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
||||
struct xs_handle *xs;
|
||||
char buf[64];
|
||||
char ref[16];
|
||||
/* XXX temp hack begin */
|
||||
char *domid_s;
|
||||
int domid = 0;
|
||||
unsigned int len;
|
||||
/* XXX temp hack end */
|
||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||
xc_evtchn *evfd;
|
||||
#else
|
||||
int evfd;
|
||||
#endif
|
||||
evtchn_port_or_error_t port;
|
||||
xs = xs_domain_open();
|
||||
xs = xs_daemon_open();
|
||||
if (!xs) {
|
||||
return ret;
|
||||
}
|
||||
@ -90,20 +111,41 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
||||
if (port < 0)
|
||||
goto fail2;
|
||||
ctrl->evport = port;
|
||||
ctrl->devno = devno;
|
||||
|
||||
// stubdom debug HACK XXX
|
||||
domid_s = xs_read(xs, 0, "domid", &len);
|
||||
if (domid_s)
|
||||
domid = atoi(domid_s);
|
||||
|
||||
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)))
|
||||
#ifdef CONFIG_STUBDOM
|
||||
// TEMP HACK XXX FIXME goto fail2;
|
||||
fprintf(stderr, "xenstore-write /local/domain/%d/%s %s\n", domid, buf, ref);
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
snprintf(ref, sizeof ref, "%d", ctrl->evport);
|
||||
snprintf(buf, sizeof buf, "device/vchan/%d/event-channel", devno);
|
||||
if (!xs_write(xs, 0, buf, ref, strlen(ref)))
|
||||
#ifdef CONFIG_STUBDOM
|
||||
// TEMP HACK XXX FIXME goto fail2;
|
||||
fprintf(stderr, "xenstore-write /local/domain/%d/%s %s\n", domid, buf, ref);
|
||||
#else
|
||||
goto fail2;
|
||||
#endif
|
||||
// do not block in stubdom - libvchan_server_handle_connected will be
|
||||
// called on first input
|
||||
#ifndef CONFIG_STUBDOM
|
||||
// wait for the peer to arrive
|
||||
if (xc_evtchn_pending(evfd) == -1)
|
||||
goto fail2;
|
||||
xc_evtchn_unmask(ctrl->evfd, ctrl->evport);
|
||||
snprintf(buf, sizeof buf, "device/vchan/%d", devno);
|
||||
xs_rm(xs, 0, buf);
|
||||
#endif
|
||||
|
||||
ret = 0;
|
||||
fail2:
|
||||
@ -130,7 +172,7 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
||||
|
||||
/**
|
||||
Run in AppVM (any domain).
|
||||
Sleeps until the connection is established.
|
||||
Sleeps until the connection is established. (unless in stubdom)
|
||||
\param devno something like a well-known port.
|
||||
\returns NULL on failure, handle on success
|
||||
*/
|
||||
@ -156,6 +198,39 @@ struct libvchan *libvchan_server_init(int devno)
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
int libvchan_server_handle_connected(struct libvchan *ctrl)
|
||||
{
|
||||
struct xs_handle *xs;
|
||||
char buf[64];
|
||||
int ret = -1;
|
||||
int libvchan_fd;
|
||||
fd_set rfds;
|
||||
|
||||
xs = xs_daemon_open();
|
||||
if (!xs) {
|
||||
return ret;
|
||||
}
|
||||
// clear the pending flag
|
||||
xc_evtchn_pending(ctrl->evfd);
|
||||
|
||||
snprintf(buf, sizeof buf, "device/vchan/%d", ctrl->devno);
|
||||
xs_rm(xs, 0, buf);
|
||||
|
||||
ret = 0;
|
||||
|
||||
#if 0
|
||||
fail2:
|
||||
if (ret)
|
||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||
xc_evtchn_close(ctrl->evfd);
|
||||
#else
|
||||
close(ctrl->evfd);
|
||||
#endif
|
||||
#endif
|
||||
xs_daemon_close(xs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
retrieves ring-ref and event-channel numbers from xenstore (if
|
||||
they don't exist, return error, because nobody seems to listen);
|
||||
|
19
vchan/io.c
19
vchan/io.c
@ -22,6 +22,8 @@
|
||||
#include "libvchan.h"
|
||||
#include <xenctrl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
/**
|
||||
\return How much data is immediately available for reading
|
||||
*/
|
||||
@ -67,7 +69,24 @@ int libvchan_is_eof(struct libvchan *ctrl)
|
||||
int libvchan_wait(struct libvchan *ctrl)
|
||||
{
|
||||
int ret;
|
||||
#ifndef CONFIG_STUBDOM
|
||||
ret = xc_evtchn_pending(ctrl->evfd);
|
||||
#else
|
||||
int vchan_fd = libvchan_fd_for_select(ctrl);
|
||||
fd_set rfds;
|
||||
|
||||
libvchan_prepare_to_select(ctrl);
|
||||
while ((ret = xc_evtchn_pending(ctrl->evfd)) < 0) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(0, &rfds);
|
||||
FD_SET(vchan_fd, &rfds);
|
||||
ret = select(vchan_fd + 1, &rfds, NULL, NULL, NULL);
|
||||
if (ret < 0 && errno != EINTR) {
|
||||
perror("select");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ret!=-1 && xc_evtchn_unmask(ctrl->evfd, ctrl->evport))
|
||||
return -1;
|
||||
if (ret!=-1 && libvchan_is_eof(ctrl))
|
||||
|
@ -19,6 +19,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBVCHAN_H
|
||||
#define _LIBVCHAN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <xenctrl.h>
|
||||
typedef uint32_t VCHAN_RING_IDX;
|
||||
@ -44,6 +47,7 @@ struct libvchan {
|
||||
int evfd;
|
||||
#endif
|
||||
int evport;
|
||||
int devno;
|
||||
VCHAN_RING_IDX *wr_cons, *wr_prod, *rd_cons, *rd_prod;
|
||||
char *rd_ring, *wr_ring;
|
||||
int rd_ring_size, wr_ring_size;
|
||||
@ -51,6 +55,7 @@ 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);
|
||||
|
||||
@ -63,3 +68,5 @@ int 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);
|
||||
|
||||
#endif /* _LIBVCHAN_H */
|
||||
|
Loading…
Reference in New Issue
Block a user