tools: add a new xen 9pfs daemon

Add "xen-9pfsd", a new 9pfs daemon meant to support infrastructure
domains (e.g. xenstore-stubdom) to access files in dom0.

For now only add the code needed for starting the daemon and
registering it with Xenstore via a new "libxl/xen-9pfs/state" node by
writing the "running" state to it.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jason Andryuk <jandryuk@gmail.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
This commit is contained in:
Juergen Gross authored and Andrew Cooper committed 2024-02-15 16:24:39 +00:00
1 parent c4d6802d33
commit c3e583b01b
4 files changed
+187

No files matched your search

+1
View File
@@ -0,0 +1 @@
/xen-9pfsd
+38
View File
@@ -0,0 +1,38 @@
#
# tools/9pfsd/Makefile
#
XEN_ROOT = $(CURDIR)/../..
include $(XEN_ROOT)/tools/Rules.mk
CFLAGS += $(PTHREAD_CFLAGS)
LDFLAGS += $(PTHREAD_LDFLAGS)
TARGETS := xen-9pfsd
XEN-9PFSD_OBJS = xen-9pfsd.o
$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenstore)
$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxenevtchn)
$(XEN-9PFSD_OBJS): CFLAGS += $(CFLAGS_libxengnttab)
xen-9pfsd: LDLIBS += $(call xenlibs-ldlibs,store evtchn gnttab)
.PHONY: all
all: $(TARGETS)
xen-9pfsd: $(XEN-9PFSD_OBJS)
$(CC) $(LDFLAGS) -o $@ $(XEN-9PFSD_OBJS) $(LDLIBS) $(APPEND_LDFLAGS)
.PHONY: install
install: all
$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC_BIN)
for i in $(TARGETS); do $(INSTALL_PROG) $$i $(DESTDIR)$(LIBEXEC_BIN); done
.PHONY: uninstall
uninstall:
for i in $(TARGETS); do rm -f $(DESTDIR)$(LIBEXEC_BIN)/$$i; done
.PHONY: clean
clean:
$(RM) *.o $(TARGETS) $(DEPS_RM)
distclean: clean
+147
View File
@@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* xen-9pfsd - Xen 9pfs daemon
*
* Copyright (C) 2024 Juergen Gross <jgross@suse.com>
*
* Daemon to enable guests to access a directory of the dom0 file system.
* Access is made via the 9pfs protocol (xen-9pfsd acts as a PV 9pfs backend).
*
* Usage: xen-9pfsd
*
* xen-9pfsd does NOT support writing any links (neither soft links nor hard
* links), and it is accepting only canonicalized file paths in order to
* avoid the possibility to "escape" from the guest specific directory.
*
* The backend device string is "xen_9pfs", the tag used for mounting the
* 9pfs device is "Xen".
*
* As an additional security measure the maximum file space used by the guest
* can be limited by the backend Xenstore node "max-size" specifying the size
* in MBytes. This size includes the size of the root directory of the guest.
*/
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <xenevtchn.h>
#include <xengnttab.h>
#include <xenstore.h>
static volatile bool stop_me;
static bool daemon_running;
static struct xs_handle *xs;
static xengnttab_handle *xg;
static xenevtchn_handle *xe;
static void handle_stop(int sig)
{
stop_me = true;
}
static void close_all(void)
{
if ( daemon_running )
xs_rm(xs, XBT_NULL, "libxl/xen-9pfs");
if ( xe )
xenevtchn_close(xe);
if ( xg )
xengnttab_close(xg);
if ( xs )
xs_close(xs);
closelog();
}
static void do_err(const char *msg)
{
syslog(LOG_ALERT, "%s, errno = %d, %s", msg, errno, strerror(errno));
close_all();
exit(1);
}
static void xen_connect(void)
{
xs_transaction_t t;
char *val;
unsigned int len;
xs = xs_open(0);
if ( xs == NULL )
do_err("xs_open() failed");
xg = xengnttab_open(NULL, 0);
if ( xg == NULL )
do_err("xengnttab_open() failed");
xe = xenevtchn_open(NULL, 0);
if ( xe == NULL )
do_err("xenevtchn_open() failed");
while ( true )
{
t = xs_transaction_start(xs);
if ( t == XBT_NULL )
do_err("xs_transaction_start() failed");
val = xs_read(xs, t, "libxl/xen-9pfs/state", &len);
if ( val )
{
free(val);
xs_transaction_end(xs, t, true);
syslog(LOG_INFO, "daemon already running");
close_all();
exit(0);
}
if ( !xs_write(xs, t, "libxl/xen-9pfs/state", "running",
strlen("running")) )
{
xs_transaction_end(xs, t, true);
do_err("xs_write() failed writing state");
}
if ( xs_transaction_end(xs, t, false) )
break;
if ( errno != EAGAIN )
do_err("xs_transaction_end() failed");
}
daemon_running = true;
}
int main(int argc, char *argv[])
{
struct sigaction act = { .sa_handler = handle_stop, };
int syslog_mask = LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_ERR) |
LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ALERT) |
LOG_MASK(LOG_EMERG);
umask(027);
if ( getenv("XEN_9PFSD_VERBOSE") )
syslog_mask |= LOG_MASK(LOG_NOTICE) | LOG_MASK(LOG_INFO);
openlog("xen-9pfsd", LOG_CONS, LOG_DAEMON);
setlogmask(syslog_mask);
sigemptyset(&act.sa_mask);
sigaction(SIGHUP, &act, NULL);
xen_connect();
while ( !stop_me )
{
sleep(60);
}
close_all();
return 0;
}
+1
View File
@@ -32,6 +32,7 @@ SUBDIRS-y += xenpmd
SUBDIRS-$(CONFIG_GOLANG) += golang
SUBDIRS-y += xl
SUBDIRS-y += helpers
SUBDIRS-y += 9pfsd
SUBDIRS-$(CONFIG_X86) += xenpaging
SUBDIRS-$(CONFIG_X86) += debugger
SUBDIRS-$(CONFIG_TESTS) += tests
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.