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