Update for new vchan API

This commit is contained in:
Marek Marczykowski 2013-04-22 05:21:52 +02:00 committed by Marek Marczykowski-Górecki
parent 5d68e2cc70
commit 95839ddab5
2 changed files with 45 additions and 21 deletions

View File

@ -1,7 +1,6 @@
CC=gcc CC=gcc
CFLAGS+=-I. -g -Wall -Wextra -Werror -pie -fPIC CFLAGS+=-I. -g -Wall -Wextra -Werror -pie -fPIC `pkg-config --cflags vchan-$(BACKEND_VMM)`
XENLIBS=-lvchan -lxenstore -lxenctrl LIBS=`pkg-config --libs vchan-$(BACKEND_VMM)` -lqrexec-utils
LIBS=$(XENLIBS) -lqrexec-utils
all: qrexec-agent qrexec-client-vm all: qrexec-agent qrexec-client-vm
qrexec-daemon: qrexec-daemon.o qrexec-daemon: qrexec-daemon.o

View File

@ -32,6 +32,7 @@
#include <grp.h> #include <grp.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "qrexec.h" #include "qrexec.h"
#include <libvchan.h>
#include "libqrexec-utils.h" #include "libqrexec-utils.h"
enum fdtype { enum fdtype {
@ -66,16 +67,25 @@ struct _process_fd process_fd[MAX_FDS];
/* indexed by client id, which is descriptor number of a client in daemon */ /* indexed by client id, which is descriptor number of a client in daemon */
struct _client_info client_info[MAX_FDS]; struct _client_info client_info[MAX_FDS];
libvchan_t *vchan;
int trigger_fd; int trigger_fd;
int passfd_socket; int passfd_socket;
int meminfo_write_started = 0; int meminfo_write_started = 0;
void do_exec(const char *cmd); void do_exec(const char *cmd);
void handle_vchan_error(const char *op) {
fprintf(stderr, "Error while vchan %s, exiting\n", op);
exit(1);
}
void init() void init()
{ {
peer_server_init(REXEC_PORT); /* FIXME: This 0 is remote domain ID */
vchan = libvchan_server_init(0, REXEC_PORT, 4096, 4096);
if (!vchan)
handle_vchan_error("server_init");
umask(0); umask(0);
mkfifo(QREXEC_AGENT_TRIGGER_PATH, 0666); mkfifo(QREXEC_AGENT_TRIGGER_PATH, 0666);
passfd_socket = get_server_socket(QREXEC_AGENT_FDPASS_PATH); passfd_socket = get_server_socket(QREXEC_AGENT_FDPASS_PATH);
@ -83,6 +93,10 @@ void init()
trigger_fd = trigger_fd =
open(QREXEC_AGENT_TRIGGER_PATH, O_RDONLY | O_NONBLOCK); open(QREXEC_AGENT_TRIGGER_PATH, O_RDONLY | O_NONBLOCK);
register_exec_func(do_exec); register_exec_func(do_exec);
/* wait for qrexec daemon */
while (!libvchan_is_open(vchan))
libvchan_wait(vchan);
} }
void wake_meminfo_writer() { void wake_meminfo_writer() {
@ -154,7 +168,8 @@ void handle_just_exec(int len)
char buf[len]; char buf[len];
int fdn, pid; int fdn, pid;
read_all_vchan_ext(buf, len); if (libvchan_recv(vchan, buf, len) < 0)
handle_vchan_error("read");
switch (pid = fork()) { switch (pid = fork()) {
case -1: case -1:
perror("fork"); perror("fork");
@ -203,7 +218,8 @@ void handle_exec(int client_id, int len)
char buf[len]; char buf[len];
int pid, stdin_fd, stdout_fd, stderr_fd; int pid, stdin_fd, stdout_fd, stderr_fd;
read_all_vchan_ext(buf, len); if (libvchan_recv(vchan, buf, len) < 0)
handle_vchan_error("read");
do_fork_exec(buf, &pid, &stdin_fd, &stdout_fd, &stderr_fd); do_fork_exec(buf, &pid, &stdin_fd, &stdout_fd, &stderr_fd);
@ -218,7 +234,8 @@ void handle_connect_existing(int client_id, int len)
{ {
int stdin_fd, stdout_fd, stderr_fd; int stdin_fd, stdout_fd, stderr_fd;
char buf[len]; char buf[len];
read_all_vchan_ext(buf, len); if (libvchan_recv(vchan, buf, len) < 0)
handle_vchan_error("read");
sscanf(buf, "%d %d %d", &stdin_fd, &stdout_fd, &stderr_fd); sscanf(buf, "%d %d %d", &stdin_fd, &stdout_fd, &stderr_fd);
create_info_about_client(client_id, -1, stdin_fd, stdout_fd, create_info_about_client(client_id, -1, stdin_fd, stdout_fd,
stderr_fd); stderr_fd);
@ -239,8 +256,10 @@ void send_exit_code(int client_id, int status)
s_hdr.type = MSG_AGENT_TO_SERVER_EXIT_CODE; s_hdr.type = MSG_AGENT_TO_SERVER_EXIT_CODE;
s_hdr.client_id = client_id; s_hdr.client_id = client_id;
s_hdr.len = sizeof status; s_hdr.len = sizeof status;
write_all_vchan_ext(&s_hdr, sizeof s_hdr); if (libvchan_send(vchan, &s_hdr, sizeof(s_hdr)) < 0)
write_all_vchan_ext(&status, sizeof(status)); handle_vchan_error("write hdr");
if (libvchan_send(vchan, &status, sizeof(status)) < 0)
handle_vchan_error("write status");
fprintf(stderr, "send exit code %d for client_id %d pid %d\n", fprintf(stderr, "send exit code %d for client_id %d pid %d\n",
status, client_id, client_info[client_id].pid); status, client_id, client_info[client_id].pid);
} }
@ -296,7 +315,8 @@ void handle_input(int client_id, int len)
{ {
char buf[len]; char buf[len];
read_all_vchan_ext(buf, len); if (libvchan_recv(vchan, buf, len) < 0)
handle_vchan_error("read");
if (!client_info[client_id].pid || client_info[client_id].stdin_fd == -1) if (!client_info[client_id].pid || client_info[client_id].stdin_fd == -1)
return; return;
@ -312,7 +332,7 @@ void handle_input(int client_id, int len)
} }
switch (write_stdin switch (write_stdin
(client_info[client_id].stdin_fd, client_id, buf, len, (vchan, client_info[client_id].stdin_fd, client_id, buf, len,
&client_info[client_id].buffer)) { &client_info[client_id].buffer)) {
case WRITE_STDIN_OK: case WRITE_STDIN_OK:
break; break;
@ -341,7 +361,8 @@ void set_blocked_outerr(int client_id, int val)
void handle_server_data() void handle_server_data()
{ {
struct server_header s_hdr; struct server_header s_hdr;
read_all_vchan_ext(&s_hdr, sizeof s_hdr); if (libvchan_recv(vchan, &s_hdr, sizeof(s_hdr)) < 0)
handle_vchan_error("read s_hdr");
// fprintf(stderr, "got %x %x %x\n", s_hdr.type, s_hdr.client_id, // fprintf(stderr, "got %x %x %x\n", s_hdr.type, s_hdr.client_id,
// s_hdr.len); // s_hdr.len);
@ -384,7 +405,7 @@ void handle_process_data(int fd)
int ret; int ret;
unsigned int len; unsigned int len;
len = buffer_space_vchan_ext(); len = libvchan_buffer_space(vchan);
if (len <= sizeof s_hdr) if (len <= sizeof s_hdr)
return; return;
@ -402,8 +423,10 @@ void handle_process_data(int fd)
} }
s_hdr.len = ret; s_hdr.len = ret;
if (ret >= 0) { if (ret >= 0) {
write_all_vchan_ext(&s_hdr, sizeof s_hdr); if (libvchan_send(vchan, &s_hdr, sizeof(s_hdr)) < 0)
write_all_vchan_ext(buf, ret); handle_vchan_error("write hdr");
if (libvchan_send(vchan, buf, ret) < 0)
handle_vchan_error("write buf");
} }
if (ret == 0) { if (ret == 0) {
int client_id = process_fd[fd].client_id; int client_id = process_fd[fd].client_id;
@ -501,7 +524,7 @@ void flush_client_data_agent(int client_id)
{ {
struct _client_info *info = &client_info[client_id]; struct _client_info *info = &client_info[client_id];
switch (flush_client_data switch (flush_client_data
(info->stdin_fd, client_id, &info->buffer)) { (vchan, info->stdin_fd, client_id, &info->buffer)) {
case WRITE_STDIN_OK: case WRITE_STDIN_OK:
info->is_blocked = 0; info->is_blocked = 0;
if (info->is_close_after_flush_needed) { if (info->is_close_after_flush_needed) {
@ -550,8 +573,10 @@ void handle_trigger_io()
ret = read(trigger_fd, &params, sizeof(params)); ret = read(trigger_fd, &params, sizeof(params));
if (ret == sizeof(params)) { if (ret == sizeof(params)) {
s_hdr.type = MSG_AGENT_TO_SERVER_TRIGGER_CONNECT_EXISTING; s_hdr.type = MSG_AGENT_TO_SERVER_TRIGGER_CONNECT_EXISTING;
write_all_vchan_ext(&s_hdr, sizeof s_hdr); if (libvchan_send(vchan, &s_hdr, sizeof(s_hdr)) < 0)
write_all_vchan_ext(&params, sizeof params); handle_vchan_error("write hdr");
if (libvchan_send(vchan, &params, sizeof(params)) < 0)
handle_vchan_error("write params");
} }
// trigger_fd is nonblock - so no need to reopen // trigger_fd is nonblock - so no need to reopen
// not really, need to reopen at EOF // not really, need to reopen at EOF
@ -581,17 +606,17 @@ int main()
if (child_exited) if (child_exited)
reap_children(); reap_children();
max = fill_fds_for_select(&rdset, &wrset); max = fill_fds_for_select(&rdset, &wrset);
if (buffer_space_vchan_ext() <= if (libvchan_buffer_space(vchan) <=
sizeof(struct server_header)) sizeof(struct server_header))
FD_ZERO(&rdset); FD_ZERO(&rdset);
wait_for_vchan_or_argfd(max, &rdset, &wrset); wait_for_vchan_or_argfd(vchan, max, &rdset, &wrset);
sigprocmask(SIG_UNBLOCK, &chld_set, NULL); sigprocmask(SIG_UNBLOCK, &chld_set, NULL);
if (FD_ISSET(passfd_socket, &rdset)) if (FD_ISSET(passfd_socket, &rdset))
handle_new_passfd(); handle_new_passfd();
while (read_ready_vchan_ext()) while (libvchan_data_ready(vchan))
handle_server_data(); handle_server_data();
if (FD_ISSET(trigger_fd, &rdset)) if (FD_ISSET(trigger_fd, &rdset))