From a91a8c83128e97668fd8cde86cd7780b7bd13485 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Mon, 22 Apr 2013 05:08:09 +0200 Subject: [PATCH] Update for new vchan API, remove code not needed anymore Remove some vchan wrappers, which are not necessary now. --- qrexec-lib/Makefile | 3 +- qrexec-lib/libqrexec-utils.h | 13 +-- qrexec-lib/txrx-vchan.c | 183 +---------------------------------- qrexec-lib/write-stdin.c | 11 ++- 4 files changed, 17 insertions(+), 193 deletions(-) diff --git a/qrexec-lib/Makefile b/qrexec-lib/Makefile index c9b5fe7..d068260 100644 --- a/qrexec-lib/Makefile +++ b/qrexec-lib/Makefile @@ -1,6 +1,5 @@ CC=gcc -CFLAGS+=-I. -g -Wall -Wextra -Werror -pie -fPIC -XENLIBS=-lxenctrl -lxenstore -lvchan +CFLAGS+=-I. -g -Wall -Wextra -Werror -pie -fPIC `pkg-config --cflags vchan-$(BACKEND_VMM)` COMMONIOALL=ioall.o SO_VER=1 LDFLAGS=-shared diff --git a/qrexec-lib/libqrexec-utils.h b/qrexec-lib/libqrexec-utils.h index 06dca2b..6feeb44 100644 --- a/qrexec-lib/libqrexec-utils.h +++ b/qrexec-lib/libqrexec-utils.h @@ -21,6 +21,7 @@ */ #include +#include struct buffer { char *data; @@ -40,15 +41,9 @@ void *buffer_data(struct buffer *b); void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd, int *stderr_fd); -int peer_server_init(int port); -char *peer_client_init(int dom, int port); -void wait_for_vchan_or_argfd(int max, fd_set * rdset, fd_set * wrset); -unsigned int read_ready_vchan_ext(void); +void wait_for_vchan_or_argfd(libvchan_t *vchan, int max, fd_set * rdset, fd_set * wrset); int read_all(int fd, void *buf, int size); -int read_all_vchan_ext(void *buf, int size); int write_all(int fd, const void *buf, int size); -int write_all_vchan_ext(const void *buf, int size); -unsigned int buffer_space_vchan_ext(void); void fix_fds(int fdin, int fdout, int fderr); void set_nonblock(int fd); void set_block(int fd); @@ -62,8 +57,8 @@ enum { WRITE_STDIN_ERROR }; -int flush_client_data(int fd, int client_id, struct buffer *buffer); -int write_stdin(int fd, int client_id, const char *data, int len, +int flush_client_data(libvchan_t *vchan, int fd, int client_id, struct buffer *buffer); +int write_stdin(libvchan_t *vchan, int fd, int client_id, const char *data, int len, struct buffer *buffer); void set_nonblock(int fd); int fork_and_flush_stdin(int fd, struct buffer *buffer); diff --git a/qrexec-lib/txrx-vchan.c b/qrexec-lib/txrx-vchan.c index 2f976eb..6d372df 100644 --- a/qrexec-lib/txrx-vchan.c +++ b/qrexec-lib/txrx-vchan.c @@ -23,103 +23,10 @@ #include #include #include +#include #include -#ifdef USE_XENSTORE_H -#include -#else -#include -#endif -#include -static struct libvchan *ctrl; -static int is_server; -int write_all_vchan_ext(const void *buf, int size) -{ - int written = 0; - int ret; - - while (written < size) { - ret = - libvchan_write(ctrl, (const char *) buf + written, - size - written); - if (ret <= 0) { - perror("write"); - exit(1); - } - written += ret; - } -// fprintf(stderr, "sent %d bytes\n", size); - return size; -} - - -int read_all_vchan_ext(void *buf, int size) -{ - int written = 0; - int ret; - while (written < size) { - ret = - libvchan_read(ctrl, (char *) buf + written, - size - written); - if (ret == 0) { - fprintf(stderr, "EOF\n"); - exit(1); - } - if (ret < 0) { - perror("read"); - exit(1); - } - written += ret; - } -// fprintf(stderr, "read %d bytes\n", size); - return size; -} - -unsigned int read_ready_vchan_ext() -{ - int ready = libvchan_data_ready(ctrl); - if (ready < 0) { - fprintf(stderr, "libvchan_data_ready returned invalid size\n"); - exit(1); - } - return ready; -} - -unsigned int buffer_space_vchan_ext() -{ - int space = libvchan_buffer_space(ctrl); - if (space < 0) { - fprintf(stderr, "libvchan_buffer_space returned invalid size\n"); - exit(1); - } - return space; -} - -// if the remote domain is destroyed, we get no notification -// thus, we check for the status periodically - -#ifdef XENCTRL_HAS_XC_INTERFACE -static xc_interface *xc_handle = NULL; -#else -static int xc_handle = -1; -#endif -void slow_check_for_libvchan_is_eof(struct libvchan *ctrl) -{ - struct evtchn_status evst; - evst.port = ctrl->evport; - evst.dom = DOMID_SELF; - if (xc_evtchn_status(xc_handle, &evst)) { - perror("xc_evtchn_status"); - exit(1); - } - if (evst.status != EVTCHNSTAT_interdomain) { - fprintf(stderr, "event channel disconnected\n"); - exit(0); - } -} - - -int wait_for_vchan_or_argfd_once(int max, fd_set * rdset, fd_set * wrset) +int wait_for_vchan_or_argfd_once(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset) { int vfd, ret; struct timespec tv = { 1, 100000000 }; @@ -145,12 +52,10 @@ int wait_for_vchan_or_argfd_once(int max, fd_set * rdset, fd_set * wrset) } } - if (libvchan_is_eof(ctrl)) { + if (!libvchan_is_open(ctrl)) { fprintf(stderr, "libvchan_is_eof\n"); exit(0); } - if (!is_server && ret == 0) - slow_check_for_libvchan_is_eof(ctrl); if (FD_ISSET(vfd, rdset)) // the following will never block; we need to do this to // clear libvchan_fd pending state @@ -158,90 +63,12 @@ int wait_for_vchan_or_argfd_once(int max, fd_set * rdset, fd_set * wrset) return ret; } -void wait_for_vchan_or_argfd(int max, fd_set * rdset, fd_set * wrset) +void wait_for_vchan_or_argfd(libvchan_t *ctrl, int max, fd_set * rdset, fd_set * wrset) { fd_set r = *rdset, w = *wrset; do { *rdset = r; *wrset = w; } - while (wait_for_vchan_or_argfd_once(max, rdset, wrset) == 0); -} - -int peer_server_init(int port) -{ - is_server = 1; - ctrl = libvchan_server_init(port); - if (!ctrl) { - perror("libvchan_server_init"); - exit(1); - } - return 0; -} - -char *peer_client_init(int dom, int port) -{ - struct xs_handle *xs; - char buf[64]; - char *name; - char *dummy, *dummy2; - unsigned int len = 0; - char devbuf[128]; - char dombuf[128]; - unsigned int count; - char **vec; - -// double_buffered = 1; // writes to vchan are buffered, nonblocking -// double_buffer_init(); - xs = xs_daemon_open(); - if (!xs) { - perror("xs_daemon_open"); - exit(1); - } - snprintf(buf, sizeof(buf), "/local/domain/%d/name", dom); - name = xs_read(xs, 0, buf, &len); - if (!name) { - perror("xs_read domainname"); - exit(1); - } - snprintf(devbuf, sizeof(devbuf), - "/local/domain/%d/device/vchan/%d/event-channel", dom, - port); - snprintf(dombuf, sizeof(dombuf), "/local/domain/%d", dom); - xs_watch(xs, devbuf, devbuf); - do { - vec = xs_read_watch(xs, &count); - if (vec) - free(vec); - len = 0; - dummy = xs_read(xs, 0, devbuf, &len); - if (dummy) - free(dummy); - else { - /* check if domain still alive */ - dummy2 = xs_read(xs, 0, dombuf, &len); - if (!dummy2) { - fprintf(stderr, "domain dead\n"); - exit(1); - } - free(dummy2); - } - } - while (!dummy || !len); // wait for the server to create xenstore entries - xs_daemon_close(xs); - - // now client init should succeed; "while" is redundant - while (!(ctrl = libvchan_client_init(dom, port))); - -#ifdef XENCTRL_HAS_XC_INTERFACE - xc_handle = xc_interface_open(NULL, 0, 0); - if (!xc_handle) { -#else - xc_handle = xc_interface_open(); - if (xc_handle < 0) { -#endif - perror("xc_interface_open"); - exit(1); - } - return name; + while (wait_for_vchan_or_argfd_once(ctrl, max, rdset, wrset) == 0); } diff --git a/qrexec-lib/write-stdin.c b/qrexec-lib/write-stdin.c index 3bd5922..4aed9dd 100644 --- a/qrexec-lib/write-stdin.c +++ b/qrexec-lib/write-stdin.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "qrexec.h" #include "libqrexec-utils.h" @@ -32,7 +33,7 @@ There is buffered data in "buffer" for client id "client_id", and select() reports that "fd" is writable. Write as much as possible to fd, if all sent, notify the peer that this client's pipe is no longer full. */ -int flush_client_data(int fd, int client_id, struct buffer *buffer) +int flush_client_data(libvchan_t *vchan, int fd, int client_id, struct buffer *buffer) { int ret; int len; @@ -57,7 +58,8 @@ int flush_client_data(int fd, int client_id, struct buffer *buffer) s_hdr.type = MSG_XON; s_hdr.client_id = client_id; s_hdr.len = 0; - write_all_vchan_ext(&s_hdr, sizeof s_hdr); + if (libvchan_send(vchan, (char*)&s_hdr, sizeof s_hdr) < 0) + return WRITE_STDIN_ERROR; return WRITE_STDIN_OK; } } @@ -69,7 +71,7 @@ Write "len" bytes from "data" to "fd". If not all written, buffer the rest to "buffer", and notify the peer that the client "client_id" pipe is full via MSG_XOFF message. */ -int write_stdin(int fd, int client_id, const char *data, int len, +int write_stdin(libvchan_t *vchan, int fd, int client_id, const char *data, int len, struct buffer *buffer) { int ret; @@ -97,7 +99,8 @@ int write_stdin(int fd, int client_id, const char *data, int len, s_hdr.type = MSG_XOFF; s_hdr.client_id = client_id; s_hdr.len = 0; - write_all_vchan_ext(&s_hdr, sizeof s_hdr); + if (libvchan_send(vchan, (char*)&s_hdr, sizeof s_hdr) < 0) + return WRITE_STDIN_ERROR; return WRITE_STDIN_BUFFERED; }