remove qubes-core-libs files - moved to separate repository
This commit is contained in:
parent
e0ca1a5674
commit
f4c37be03a
1
Makefile
1
Makefile
@ -3,7 +3,6 @@ RPMS_DIR=rpm/
|
|||||||
VERSION_DOM0 := $(shell cat version_dom0)
|
VERSION_DOM0 := $(shell cat version_dom0)
|
||||||
VERSION_VAIO_FIXES := $(shell cat version_vaio_fixes)
|
VERSION_VAIO_FIXES := $(shell cat version_vaio_fixes)
|
||||||
VERSION_VM := $(shell cat version_vm)
|
VERSION_VM := $(shell cat version_vm)
|
||||||
VERSION_LIBS := $(shell cat version_libs)
|
|
||||||
|
|
||||||
DIST_DOM0 ?= fc18
|
DIST_DOM0 ?= fc18
|
||||||
|
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
#
|
|
||||||
# The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
#
|
|
||||||
# Copyright (C) 2010 Joanna Rutkowska <joanna@invisiblethingslab.com>
|
|
||||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
%{!?version: %define version %(cat version_libs)}
|
|
||||||
|
|
||||||
Name: qubes-core-libs
|
|
||||||
Version: %{version}
|
|
||||||
Release: 1%{dist}
|
|
||||||
|
|
||||||
Summary: Qubes core libraries
|
|
||||||
License: GPL v2 only
|
|
||||||
Group: Development/Sources
|
|
||||||
Group: Qubes
|
|
||||||
Vendor: Invisible Things Lab
|
|
||||||
URL: http://www.qubes-os.org
|
|
||||||
Obsoletes: qubes-core-appvm-libs
|
|
||||||
Obsoletes: qubes-core-vm-libs
|
|
||||||
BuildRequires: xen-devel
|
|
||||||
|
|
||||||
%define _builddir %(pwd)
|
|
||||||
|
|
||||||
%description
|
|
||||||
The Qubes core libraries for installation inside a Qubes Dom0 and VM.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
# we operate on the current directory, so no need to unpack anything
|
|
||||||
# symlink is to generate useful debuginfo packages
|
|
||||||
rm -f %{name}-%{version}
|
|
||||||
ln -sf . %{name}-%{version}
|
|
||||||
%setup -T -D
|
|
||||||
|
|
||||||
%build
|
|
||||||
(cd u2mfn; make)
|
|
||||||
(cd vchan; make -f Makefile.linux)
|
|
||||||
|
|
||||||
%install
|
|
||||||
install -D -m 0644 vchan/libvchan.h $RPM_BUILD_ROOT/usr/include/libvchan.h
|
|
||||||
install -D -m 0644 u2mfn/u2mfnlib.h $RPM_BUILD_ROOT/usr/include/u2mfnlib.h
|
|
||||||
install -D -m 0644 u2mfn/u2mfn-kernel.h $RPM_BUILD_ROOT/usr/include/u2mfn-kernel.h
|
|
||||||
|
|
||||||
install -D vchan/libvchan.so $RPM_BUILD_ROOT/%{_libdir}/libvchan.so
|
|
||||||
install -D u2mfn/libu2mfn.so $RPM_BUILD_ROOT/%{_libdir}/libu2mfn.so
|
|
||||||
|
|
||||||
%clean
|
|
||||||
rm -rf $RPM_BUILD_ROOT
|
|
||||||
rm -f %{name}-%{version}
|
|
||||||
|
|
||||||
%files
|
|
||||||
%{_libdir}/libvchan.so
|
|
||||||
%{_libdir}/libu2mfn.so
|
|
||||||
|
|
||||||
%package devel
|
|
||||||
Summary: Include files for qubes core libraries
|
|
||||||
License: GPL v2 only
|
|
||||||
Group: Development/Sources
|
|
||||||
Obsoletes: qubes-core-appvm-devel
|
|
||||||
Obsoletes: qubes-core-vm-devel
|
|
||||||
|
|
||||||
%description devel
|
|
||||||
|
|
||||||
%files devel
|
|
||||||
/usr/include/libvchan.h
|
|
||||||
/usr/include/u2mfnlib.h
|
|
||||||
/usr/include/u2mfn-kernel.h
|
|
1
u2mfn/.gitignore
vendored
1
u2mfn/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
libu2mfn.so
|
|
@ -1,33 +0,0 @@
|
|||||||
#
|
|
||||||
# The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
#
|
|
||||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
CFLAGS=-g -Wall
|
|
||||||
all: libu2mfn.so
|
|
||||||
|
|
||||||
libu2mfn.so : u2mfnlib.o
|
|
||||||
gcc -shared -o libu2mfn.so u2mfnlib.o
|
|
||||||
u2mfnlib.o: u2mfnlib.c
|
|
||||||
gcc -fPIC -Wall -g -c u2mfnlib.c
|
|
||||||
clean:
|
|
||||||
rm -f *.o *so *~ libu2mfn.so
|
|
||||||
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <linux/ioctl.h>
|
|
||||||
|
|
||||||
#define U2MFN_MAGIC 0xf5 // See ioctl-number.txt in kernel docs
|
|
||||||
|
|
||||||
#define U2MFN_GET_MFN_FOR_PAGE _IOW (U2MFN_MAGIC, 1, int)
|
|
||||||
#define U2MFN_GET_LAST_MFN _IO (U2MFN_MAGIC, 2)
|
|
@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "u2mfn-kernel.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int u2mfn_fd = -1;
|
|
||||||
|
|
||||||
int u2mfn_get_fd()
|
|
||||||
{
|
|
||||||
return open("/proc/u2mfn", O_RDWR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_fd()
|
|
||||||
{
|
|
||||||
if (u2mfn_fd == -1)
|
|
||||||
u2mfn_fd = u2mfn_get_fd();
|
|
||||||
if (u2mfn_fd < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int u2mfn_get_mfn_for_page_with_fd(int fd, long va, int *mfn)
|
|
||||||
{
|
|
||||||
*mfn = ioctl(fd, U2MFN_GET_MFN_FOR_PAGE, va);
|
|
||||||
if (*mfn == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int u2mfn_get_mfn_for_page(long va, int *mfn)
|
|
||||||
{
|
|
||||||
if (get_fd())
|
|
||||||
return -1;
|
|
||||||
return u2mfn_get_mfn_for_page_with_fd(u2mfn_fd, va, mfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
int u2mfn_get_last_mfn_with_fd(int fd, int *mfn)
|
|
||||||
{
|
|
||||||
*mfn = ioctl(fd, U2MFN_GET_LAST_MFN, 0);
|
|
||||||
if (*mfn == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int u2mfn_get_last_mfn(int *mfn)
|
|
||||||
{
|
|
||||||
if (get_fd())
|
|
||||||
return -1;
|
|
||||||
return u2mfn_get_last_mfn_with_fd(u2mfn_fd, mfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *u2mfn_alloc_kpage_with_fd(int fd)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
ret =
|
|
||||||
mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *u2mfn_alloc_kpage()
|
|
||||||
{
|
|
||||||
if (get_fd())
|
|
||||||
return MAP_FAILED;
|
|
||||||
return u2mfn_alloc_kpage_with_fd(u2mfn_fd);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int u2mfn_get_fd();
|
|
||||||
int u2mfn_get_mfn_for_page(long va, int *mfn) ;
|
|
||||||
int u2mfn_get_mfn_for_page_with_fd(int fd, long va, int *mfn) ;
|
|
||||||
int u2mfn_get_last_mfn(int *mfn) ;
|
|
||||||
int u2mfn_get_last_mfn_with_fd(int fd, int *mfn) ;
|
|
||||||
char *u2mfn_alloc_kpage(void);
|
|
||||||
char *u2mfn_alloc_kpage_with_fd(int fd);
|
|
1
vchan/.gitignore
vendored
1
vchan/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
libvchan.so
|
|
@ -1,39 +0,0 @@
|
|||||||
#
|
|
||||||
# The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
#
|
|
||||||
# Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
CFLAGS=-g -Wall -I../u2mfn
|
|
||||||
all: libvchan.so
|
|
||||||
|
|
||||||
libvchan.so : init.o io.o
|
|
||||||
gcc -shared -o libvchan.so init.o io.o -L ../u2mfn -lu2mfn
|
|
||||||
init.o: init.c
|
|
||||||
gcc -fPIC -Wall -g -c init.c
|
|
||||||
io.o: io.c
|
|
||||||
gcc -fPIC -Wall -g -c io.c
|
|
||||||
node: node.o libvchan.so
|
|
||||||
gcc -g -o node node.o -L. -lvchan -lxenctrl -lxenstore
|
|
||||||
node-select: node-select.o libvchan.so
|
|
||||||
gcc -g -o node-select node-select.o -L. -lvchan -lxenctrl -lxenstore
|
|
||||||
clean:
|
|
||||||
rm -f *.o *so *~ client server node node-select
|
|
||||||
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
#
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
460
vchan/init.c
460
vchan/init.c
@ -1,460 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WINNT
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <xenctrl.h>
|
|
||||||
#include <unistd.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 QREXEC_RING_V2
|
|
||||||
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;
|
|
||||||
int u2mfn_fd;
|
|
||||||
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
|
|
||||||
u2mfn_fd = u2mfn_get_fd();
|
|
||||||
if (u2mfn_fd < 0)
|
|
||||||
return -1;
|
|
||||||
ring = (struct vchan_interface *) u2mfn_alloc_kpage_with_fd (u2mfn_fd);
|
|
||||||
|
|
||||||
if (ring == MAP_FAILED)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (u2mfn_get_last_mfn_with_fd (u2mfn_fd, &mfn) < 0)
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return fill_ctrl(ctrl, ring, mfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
creates event channel;
|
|
||||||
creates "ring-ref" and "event-channel" xenstore entries;
|
|
||||||
waits for connection to event channel from the peer
|
|
||||||
*/
|
|
||||||
static int server_interface_init(struct libvchan *ctrl, int devno)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
struct xs_handle *xs;
|
|
||||||
char buf[64];
|
|
||||||
char ref[16];
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
|
||||||
xc_evtchn *evfd;
|
|
||||||
#else
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
|
||||||
evfd = xc_evtchn_open(NULL, 0);
|
|
||||||
if (!evfd)
|
|
||||||
goto fail;
|
|
||||||
#else
|
|
||||||
evfd = xc_evtchn_open();
|
|
||||||
if (evfd < 0)
|
|
||||||
goto fail;
|
|
||||||
#endif
|
|
||||||
ctrl->evfd = evfd;
|
|
||||||
// the following hardcoded 0 is the peer domain id
|
|
||||||
port = xc_evtchn_bind_unbound_port(evfd, 0);
|
|
||||||
if (port < 0)
|
|
||||||
goto fail2;
|
|
||||||
ctrl->evport = port;
|
|
||||||
ctrl->devno = devno;
|
|
||||||
|
|
||||||
#ifdef QREXEC_RING_V2
|
|
||||||
snprintf(buf, sizeof buf, "device/vchan/%d/version", devno);
|
|
||||||
if (!xs_write(xs, 0, buf, "2", strlen("2")))
|
|
||||||
goto fail2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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)))
|
|
||||||
goto fail2;
|
|
||||||
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)))
|
|
||||||
goto fail2;
|
|
||||||
// do not block in stubdom and windows - libvchan_server_handle_connected will be
|
|
||||||
// called on first input
|
|
||||||
#ifndef ASYNC_INIT
|
|
||||||
// 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:
|
|
||||||
if (ret)
|
|
||||||
xc_evtchn_close(evfd);
|
|
||||||
fail:
|
|
||||||
xs_daemon_close(xs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define dir_select(dir1, dir2) \
|
|
||||||
ctrl->wr_cons = &ctrl->ring->cons_##dir1; \
|
|
||||||
ctrl->wr_prod = &ctrl->ring->prod_##dir1; \
|
|
||||||
ctrl->rd_cons = &ctrl->ring->cons_##dir2; \
|
|
||||||
ctrl->rd_prod = &ctrl->ring->prod_##dir2; \
|
|
||||||
ctrl->wr_ring = ctrl->ring->buf_##dir1; \
|
|
||||||
ctrl->rd_ring = ctrl->ring->buf_##dir2; \
|
|
||||||
ctrl->wr_ring_size = sizeof(ctrl->ring->buf_##dir1); \
|
|
||||||
ctrl->rd_ring_size = sizeof(ctrl->ring->buf_##dir2)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Run in AppVM (any domain).
|
|
||||||
Release resources used by vchan link. Should be used after
|
|
||||||
libvchan_close() to clean connection shutdown, but can be used alone in
|
|
||||||
recovery case.
|
|
||||||
\param ctrl connection to cleanup
|
|
||||||
\returns -1 on failure (errno for details), 0 on success
|
|
||||||
*/
|
|
||||||
int libvchan_cleanup(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
if (!ctrl)
|
|
||||||
return 0;
|
|
||||||
if (!ctrl->is_server)
|
|
||||||
return 0;
|
|
||||||
/* do not wait flush remaining queue to allow use libvchan_cleanup for
|
|
||||||
* recovery situation. If someone want clean close, should call
|
|
||||||
* libvchan_close() first.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (!ctrl->ring->server_closed)
|
|
||||||
libvchan_close(ctrl);
|
|
||||||
#endif
|
|
||||||
if (xc_evtchn_unbind(ctrl->evfd, ctrl->evport) < 0)
|
|
||||||
return -1;
|
|
||||||
xc_evtchn_close(ctrl->evfd);
|
|
||||||
#ifdef QREXEC_RING_V2
|
|
||||||
/* not implemented yet, need to store gntmem_handle from ring_init somewhere */
|
|
||||||
assert(0);
|
|
||||||
/* in case of disabled assertions */
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
#else /* QREXEC_RING_V2 */
|
|
||||||
#ifdef CONFIG_STUBDOM
|
|
||||||
free(ctrl->ring);
|
|
||||||
#else /* CONFIG_STUBDOM */
|
|
||||||
munmap(ctrl->ring, 4096);
|
|
||||||
/* FIXME: leak of u2mfn_fd, check u2mfnlib.c */
|
|
||||||
#endif /* CONFIG_STUBDOM */
|
|
||||||
#endif /* QREXEC_RING_V2 */
|
|
||||||
free(ctrl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Run in AppVM (any domain).
|
|
||||||
Sleeps until the connection is established. (unless in stubdom)
|
|
||||||
\param devno something like a well-known port.
|
|
||||||
\returns NULL on failure, handle on success
|
|
||||||
*/
|
|
||||||
struct libvchan *libvchan_server_init(int devno)
|
|
||||||
{
|
|
||||||
struct libvchan *ctrl =
|
|
||||||
(struct libvchan *) malloc(sizeof(struct libvchan));
|
|
||||||
if (!ctrl)
|
|
||||||
return 0;
|
|
||||||
if (ring_init(ctrl))
|
|
||||||
return 0;;
|
|
||||||
if (server_interface_init(ctrl, devno))
|
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
We want the same code for read/write functions, regardless whether
|
|
||||||
we are client, or server. Thus, we do not access buf_in nor buf_out
|
|
||||||
buffers directly. Instead, in *_init functions, the dir_select
|
|
||||||
macro assigns proper values to wr* and rd* pointers, so that they
|
|
||||||
point to correct one out of buf_in or buf_out related fields.
|
|
||||||
*/
|
|
||||||
dir_select(in, out);
|
|
||||||
ctrl->is_server = 1;
|
|
||||||
return ctrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int libvchan_server_handle_connected(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
struct xs_handle *xs;
|
|
||||||
char buf[64];
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
#ifdef WINNT
|
|
||||||
xs = xs_domain_open();
|
|
||||||
#else
|
|
||||||
xs = xs_daemon_open();
|
|
||||||
#endif
|
|
||||||
if (!xs) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef WINNT
|
|
||||||
// clear the pending flag
|
|
||||||
xc_evtchn_pending(ctrl->evfd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "device/vchan/%d", ctrl->devno);
|
|
||||||
xs_rm(xs, 0, buf);
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
fail2:
|
|
||||||
if (ret)
|
|
||||||
xc_evtchn_close(ctrl->evfd);
|
|
||||||
#endif
|
|
||||||
xs_daemon_close(xs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef WINNT
|
|
||||||
|
|
||||||
/**
|
|
||||||
retrieves ring-ref and event-channel numbers from xenstore (if
|
|
||||||
they don't exist, return error, because nobody seems to listen);
|
|
||||||
map the ring, connect the event channel
|
|
||||||
*/
|
|
||||||
static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
unsigned int len;
|
|
||||||
struct xs_handle *xs;
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
|
||||||
xc_interface *xcfd;
|
|
||||||
xc_gnttab *xcg;
|
|
||||||
#else
|
|
||||||
int xcfd;
|
|
||||||
int xcg;
|
|
||||||
#endif
|
|
||||||
char buf[64];
|
|
||||||
char *ref;
|
|
||||||
int version;
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
|
||||||
xc_evtchn *evfd;
|
|
||||||
#else
|
|
||||||
int evfd;
|
|
||||||
#endif
|
|
||||||
int remote_port;
|
|
||||||
xs = xs_daemon_open();
|
|
||||||
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);
|
|
||||||
ref = xs_read(xs, 0, buf, &len);
|
|
||||||
if (!ref)
|
|
||||||
goto fail;
|
|
||||||
ctrl->ring_ref = atoi(ref);
|
|
||||||
free(ref);
|
|
||||||
if (!ctrl->ring_ref)
|
|
||||||
goto fail;
|
|
||||||
snprintf(buf, sizeof buf,
|
|
||||||
"/local/domain/%d/device/vchan/%d/event-channel", domain,
|
|
||||||
devno);
|
|
||||||
ref = xs_read(xs, 0, buf, &len);
|
|
||||||
if (!ref)
|
|
||||||
goto fail;
|
|
||||||
remote_port = atoi(ref);
|
|
||||||
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;
|
|
||||||
#else
|
|
||||||
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);
|
|
||||||
xc_interface_close(xcfd);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
xcg = xc_gnttab_open(NULL, 0);
|
|
||||||
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
|
|
||||||
evfd = xc_evtchn_open(NULL, 0);
|
|
||||||
if (!evfd)
|
|
||||||
goto fail;
|
|
||||||
#else
|
|
||||||
evfd = xc_evtchn_open();
|
|
||||||
if (evfd < 0)
|
|
||||||
goto fail;
|
|
||||||
#endif
|
|
||||||
ctrl->evfd = evfd;
|
|
||||||
ctrl->evport =
|
|
||||||
xc_evtchn_bind_interdomain(evfd, domain, remote_port);
|
|
||||||
if (ctrl->evport < 0 || xc_evtchn_notify(evfd, ctrl->evport))
|
|
||||||
xc_evtchn_close(evfd);
|
|
||||||
else
|
|
||||||
ret = 0;
|
|
||||||
fail:
|
|
||||||
xs_daemon_close(xs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Run on the client side of connection (currently, must be dom0).
|
|
||||||
\returns NULL on failure (e.g. noone listening), handle on success
|
|
||||||
*/
|
|
||||||
struct libvchan *libvchan_client_init(int domain, int devno)
|
|
||||||
{
|
|
||||||
struct libvchan *ctrl =
|
|
||||||
(struct libvchan *) malloc(sizeof(struct libvchan));
|
|
||||||
if (!ctrl)
|
|
||||||
return 0;
|
|
||||||
if (client_interface_init(ctrl, domain, devno))
|
|
||||||
return 0;
|
|
||||||
// See comment in libvchan_server_init
|
|
||||||
dir_select(out, in);
|
|
||||||
ctrl->is_server = 0;
|
|
||||||
return ctrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Windows domains can not be dom0
|
|
||||||
|
|
||||||
struct libvchan *libvchan_client_init(int domain, int devno)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
208
vchan/io.c
208
vchan/io.c
@ -1,208 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libvchan.h"
|
|
||||||
|
|
||||||
#ifndef WINNT
|
|
||||||
#include <xenctrl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
\return How much data is immediately available for reading
|
|
||||||
*/
|
|
||||||
int libvchan_data_ready(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
return *ctrl->rd_prod - *ctrl->rd_cons;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\return How much space is available for writing, without blocking
|
|
||||||
*/
|
|
||||||
int libvchan_buffer_space(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
return ctrl->wr_ring_size - (*ctrl->wr_prod - *ctrl->wr_cons);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_notify(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
return xc_evtchn_notify(ctrl->evfd, ctrl->evport);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns nonzero if the peer has closed connection
|
|
||||||
int libvchan_is_eof(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
if (ctrl->is_server) {
|
|
||||||
if (ctrl->ring->client_closed)
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
if (ctrl->ring->server_closed) {
|
|
||||||
ctrl->ring->client_closed = 1;
|
|
||||||
do_notify(ctrl);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// waits for the peer to do any action
|
|
||||||
/**
|
|
||||||
\return -1 return value means peer has closed
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef WINNT
|
|
||||||
int libvchan_wait(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = xc_evtchn_pending_with_flush(ctrl->evfd);
|
|
||||||
// I don't know how to avoid evtchn ring buffer overflow without
|
|
||||||
// introducing any race condition (in qrexec-agent code). Because of that,
|
|
||||||
// handle overflow with ring reset - because we just received some events
|
|
||||||
// (overflow means ring full, so some events was recorded...) the reset
|
|
||||||
// isn't critical here - always after libvchan_wait we check if there is
|
|
||||||
// something to read from the vchan
|
|
||||||
if (ret == -1 && GetLastError() == ERROR_IO_DEVICE)
|
|
||||||
ret = xc_evtchn_reset(ctrl->evfd);
|
|
||||||
if (ret!=-1 && xc_evtchn_unmask(ctrl->evfd, ctrl->evport))
|
|
||||||
return -1;
|
|
||||||
if (ret!=-1 && libvchan_is_eof(ctrl))
|
|
||||||
return -1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
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))
|
|
||||||
return -1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
may sleep (only if no buffer space available);
|
|
||||||
may write less data than requested;
|
|
||||||
returns the amount of data processed, -1 on error or peer close
|
|
||||||
*/
|
|
||||||
int libvchan_write(struct libvchan *ctrl, const char *data, int size)
|
|
||||||
{
|
|
||||||
int avail, avail_contig;
|
|
||||||
int real_idx;
|
|
||||||
while ((avail = libvchan_buffer_space(ctrl)) == 0)
|
|
||||||
if (libvchan_wait(ctrl) < 0)
|
|
||||||
return -1;
|
|
||||||
if (avail > size)
|
|
||||||
avail = size;
|
|
||||||
real_idx = (*ctrl->wr_prod) & (ctrl->wr_ring_size - 1);
|
|
||||||
avail_contig = ctrl->wr_ring_size - real_idx;
|
|
||||||
if (avail_contig < avail)
|
|
||||||
avail = avail_contig;
|
|
||||||
memcpy(ctrl->wr_ring + real_idx, data, avail);
|
|
||||||
*ctrl->wr_prod += avail;
|
|
||||||
if (do_notify(ctrl) < 0)
|
|
||||||
return -1;
|
|
||||||
return avail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
may sleep (only if no data is available for reading);
|
|
||||||
may return less data than requested;
|
|
||||||
returns the amount of data processed, -1 on error or peer close
|
|
||||||
*/
|
|
||||||
int libvchan_read(struct libvchan *ctrl, char *data, int size)
|
|
||||||
{
|
|
||||||
int avail, avail_contig;
|
|
||||||
int real_idx;
|
|
||||||
while ((avail = libvchan_data_ready(ctrl)) == 0)
|
|
||||||
if (libvchan_wait(ctrl) < 0)
|
|
||||||
return -1;
|
|
||||||
if (avail > size)
|
|
||||||
avail = size;
|
|
||||||
real_idx = (*ctrl->rd_cons) & (ctrl->rd_ring_size - 1);
|
|
||||||
avail_contig = ctrl->rd_ring_size - real_idx;
|
|
||||||
if (avail_contig < avail)
|
|
||||||
avail = avail_contig;
|
|
||||||
memcpy(data, ctrl->rd_ring + real_idx, avail);
|
|
||||||
*ctrl->rd_cons += avail;
|
|
||||||
if (do_notify(ctrl) < 0)
|
|
||||||
return -1;
|
|
||||||
return avail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Wait fot the writes to finish, then notify the peer of closing
|
|
||||||
On server side, it waits for the peer to acknowledge
|
|
||||||
*/
|
|
||||||
int libvchan_close(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
while (*ctrl->wr_prod != *ctrl->wr_cons)
|
|
||||||
if (libvchan_wait(ctrl) < 0)
|
|
||||||
return -1;
|
|
||||||
if (ctrl->is_server) {
|
|
||||||
ctrl->ring->server_closed = 1;
|
|
||||||
do_notify(ctrl);
|
|
||||||
while (!ctrl->ring->client_closed
|
|
||||||
&& libvchan_wait(ctrl) == 0);
|
|
||||||
} else {
|
|
||||||
ctrl->ring->client_closed = 1;
|
|
||||||
do_notify(ctrl);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The fd to use for select() set
|
|
||||||
EVTCHN libvchan_fd_for_select(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
return xc_evtchn_fd(ctrl->evfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unmasks event channel; must be called before calling select(), and only then
|
|
||||||
void libvchan_prepare_to_select(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
xc_evtchn_unmask(ctrl->evfd, ctrl->evport);
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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 /* WINNT */
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int EVTCHN;
|
|
||||||
#endif /* WINNT */
|
|
||||||
|
|
||||||
/* config vchan features */
|
|
||||||
#ifdef WINNT
|
|
||||||
#define QREXEC_RING_V2
|
|
||||||
#define ASYNC_INIT
|
|
||||||
#endif /* WINNT */
|
|
||||||
#ifdef CONFIG_STUBDOM
|
|
||||||
#define ASYNC_INIT
|
|
||||||
#endif /* CONFIG_STUBDOM */
|
|
||||||
|
|
||||||
#include <xenctrl.h>
|
|
||||||
typedef uint32_t VCHAN_RING_IDX;
|
|
||||||
|
|
||||||
/// struct vchan_interface is placed in memory shared between domains
|
|
||||||
struct vchan_interface {
|
|
||||||
// One buffer for each data direction
|
|
||||||
char buf_in[1024];
|
|
||||||
char buf_out[2048];
|
|
||||||
// standard consumer/producer interface, one pair per buffer
|
|
||||||
VCHAN_RING_IDX cons_in, prod_in, cons_out, prod_out;
|
|
||||||
uint32_t debug;
|
|
||||||
int client_closed, server_closed;
|
|
||||||
};
|
|
||||||
/// struct libvchan is a control structure, passed to all library calls
|
|
||||||
struct libvchan {
|
|
||||||
struct vchan_interface *ring;
|
|
||||||
uint32_t ring_ref;
|
|
||||||
/// descriptor to event channel interface
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
|
||||||
xc_evtchn *evfd;
|
|
||||||
#else
|
|
||||||
EVTCHN 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;
|
|
||||||
int is_server;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct libvchan *libvchan_server_init(int devno);
|
|
||||||
|
|
||||||
struct libvchan *libvchan_client_init(int domain, int devno);
|
|
||||||
|
|
||||||
int libvchan_server_handle_connected(struct libvchan *ctrl);
|
|
||||||
int libvchan_write(struct libvchan *ctrl, const 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);
|
|
||||||
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);
|
|
||||||
|
|
||||||
int libvchan_cleanup(struct libvchan *ctrl);
|
|
||||||
|
|
||||||
#endif /* _LIBVCHAN_H */
|
|
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libvchan.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
int libvchan_write_all(struct libvchan *ctrl, char *buf, int size)
|
|
||||||
{
|
|
||||||
int written = 0;
|
|
||||||
int ret;
|
|
||||||
while (written < size) {
|
|
||||||
ret = libvchan_write(ctrl, buf + written, size - written);
|
|
||||||
if (ret <= 0) {
|
|
||||||
perror("write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
written += ret;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_all(int fd, char *buf, int size)
|
|
||||||
{
|
|
||||||
int written = 0;
|
|
||||||
int ret;
|
|
||||||
while (written < size) {
|
|
||||||
ret = write(fd, buf + written, size - written);
|
|
||||||
if (ret <= 0) {
|
|
||||||
perror("write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
written += ret;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void usage()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage:\n\tnode-select server nodeid\n"
|
|
||||||
"or\n" "\tnode-select client domainid nodeid\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUFSIZE 5000
|
|
||||||
char buf[BUFSIZE];
|
|
||||||
|
|
||||||
/**
|
|
||||||
Simple libvchan application, both client and server.
|
|
||||||
Both sides may write and read, both from the libvchan and from
|
|
||||||
stdin/stdout (just like netcat). More code is required to avoid
|
|
||||||
deadlock when both sides write, and noone reads.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int libvchan_fd;
|
|
||||||
struct libvchan *ctrl = 0;
|
|
||||||
if (argc < 3)
|
|
||||||
usage();
|
|
||||||
if (!strcmp(argv[1], "server"))
|
|
||||||
ctrl = libvchan_server_init(atoi(argv[2]));
|
|
||||||
else if (!strcmp(argv[1], "client"))
|
|
||||||
ctrl = libvchan_client_init(atoi(argv[2]), atoi(argv[3]));
|
|
||||||
else
|
|
||||||
usage();
|
|
||||||
if (!ctrl) {
|
|
||||||
perror("libvchan_*_init");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
libvchan_fd = libvchan_fd_for_select(ctrl);
|
|
||||||
for (;;) {
|
|
||||||
fd_set rfds;
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(0, &rfds);
|
|
||||||
FD_SET(libvchan_fd, &rfds);
|
|
||||||
// libvchan_prepare_to_select(ctrl);
|
|
||||||
ret = select(libvchan_fd + 1, &rfds, NULL, NULL, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
perror("select");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (libvchan_is_eof(ctrl))
|
|
||||||
exit(0);
|
|
||||||
if (FD_ISSET(libvchan_fd, &rfds))
|
|
||||||
// we don't care about the result, but we need to do the read to
|
|
||||||
// clear libvchan_fd pendind state
|
|
||||||
libvchan_wait(ctrl);
|
|
||||||
while (libvchan_data_ready(ctrl) > 0) {
|
|
||||||
ret = libvchan_read(ctrl, buf, BUFSIZE);
|
|
||||||
if (ret < 0)
|
|
||||||
exit(0);
|
|
||||||
write_all(1, buf, ret);
|
|
||||||
}
|
|
||||||
if (FD_ISSET(0, &rfds)) {
|
|
||||||
ret = read(0, buf, BUFSIZE);
|
|
||||||
if (ret == 0) {
|
|
||||||
libvchan_close(ctrl);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if (ret < 0) {
|
|
||||||
perror("read 0");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
// libvchan_write_all can block; so if both sides write a lot,
|
|
||||||
// we can deadlock. Need higher level solution; would libvchan_write be ok ?
|
|
||||||
libvchan_write_all(ctrl, buf, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
157
vchan/node.c
157
vchan/node.c
@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* The Qubes OS Project, http://www.qubes-os.org
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Rafal Wojtczuk <rafal@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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "libvchan.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
int libvchan_write_all(struct libvchan *ctrl, char *buf, int size)
|
|
||||||
{
|
|
||||||
int written = 0;
|
|
||||||
int ret;
|
|
||||||
while (written < size) {
|
|
||||||
ret = libvchan_write(ctrl, buf + written, size - written);
|
|
||||||
if (ret <= 0) {
|
|
||||||
perror("write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
written += ret;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_all(int fd, char *buf, int size)
|
|
||||||
{
|
|
||||||
int written = 0;
|
|
||||||
int ret;
|
|
||||||
while (written < size) {
|
|
||||||
ret = write(fd, buf + written, size - written);
|
|
||||||
if (ret <= 0) {
|
|
||||||
perror("write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
written += ret;
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "usage:\n\tnode server [read|write] nodeid\n"
|
|
||||||
"or\n" "\tnode client [read|write] domainid nodeid\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUFSIZE 5000
|
|
||||||
char buf[BUFSIZE];
|
|
||||||
void reader(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
for (;;) {
|
|
||||||
size = rand() % (BUFSIZE - 1) + 1;
|
|
||||||
size = libvchan_read(ctrl, buf, size);
|
|
||||||
fprintf(stderr, "#");
|
|
||||||
if (size < 0) {
|
|
||||||
perror("read vchan");
|
|
||||||
libvchan_close(ctrl);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (size == 0)
|
|
||||||
break;
|
|
||||||
size = write_all(1, buf, size);
|
|
||||||
if (size < 0) {
|
|
||||||
perror("stdout write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (size == 0) {
|
|
||||||
perror("write size=0?\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void writer(struct libvchan *ctrl)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
for (;;) {
|
|
||||||
size = rand() % (BUFSIZE - 1) + 1;
|
|
||||||
size = read(0, buf, size);
|
|
||||||
if (size < 0) {
|
|
||||||
perror("read stdin");
|
|
||||||
libvchan_close(ctrl);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (size == 0)
|
|
||||||
break;
|
|
||||||
size = libvchan_write_all(ctrl, buf, size);
|
|
||||||
fprintf(stderr, "#");
|
|
||||||
if (size < 0) {
|
|
||||||
perror("vchan write");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (size == 0) {
|
|
||||||
perror("write size=0?\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Simple libvchan application, both client and server.
|
|
||||||
One side does writing, the other side does reading; both from
|
|
||||||
standard input/output fds.
|
|
||||||
*/
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int seed = time(0);
|
|
||||||
struct libvchan *ctrl = 0;
|
|
||||||
int wr;
|
|
||||||
if (argc < 4)
|
|
||||||
usage();
|
|
||||||
if (!strcmp(argv[2], "read"))
|
|
||||||
wr = 0;
|
|
||||||
else if (!strcmp(argv[2], "write"))
|
|
||||||
wr = 1;
|
|
||||||
else
|
|
||||||
usage();
|
|
||||||
if (!strcmp(argv[1], "server"))
|
|
||||||
ctrl = libvchan_server_init(atoi(argv[3]));
|
|
||||||
else if (!strcmp(argv[1], "client"))
|
|
||||||
ctrl = libvchan_client_init(atoi(argv[3]), atoi(argv[4]));
|
|
||||||
else
|
|
||||||
usage();
|
|
||||||
if (!ctrl) {
|
|
||||||
perror("libvchan_*_init");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
srand(seed);
|
|
||||||
fprintf(stderr, "seed=%d\n", seed);
|
|
||||||
if (wr)
|
|
||||||
writer(ctrl);
|
|
||||||
else
|
|
||||||
reader(ctrl);
|
|
||||||
libvchan_close(ctrl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
TARGETNAME=libvchan
|
|
||||||
TARGETTYPE=LIBRARY
|
|
||||||
TARGETPATH=..\win\libs
|
|
||||||
|
|
||||||
#BUILD_PASS0_CONSUMES=gntmem evtchn xenstore
|
|
||||||
#BUILD_PASS0_PRODUCES=vchan
|
|
||||||
|
|
||||||
USE_MSVCRT=1
|
|
||||||
|
|
||||||
DLLDEF=libvchan.def
|
|
||||||
|
|
||||||
INCLUDES=$(INCLUDES); \
|
|
||||||
..\win\include;\
|
|
||||||
|
|
||||||
SOURCES=io.c init.c
|
|
||||||
|
|
||||||
TARGETLIBS=\
|
|
||||||
$(SDK_LIB_PATH)\setupapi.lib \
|
|
||||||
$(SDK_LIB_PATH)\kernel32.lib
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
2.1.1
|
|
Loading…
Reference in New Issue
Block a user