Skip to content

Commit

Permalink
Add LKL (Linux Kernel as a Library) backend.
Browse files Browse the repository at this point in the history
Check out the LKL sources (https://github.com/lkl/linux) and compile
them by following the instructions in Documentation/lkl.txt.

Then add the following to the libguestfs configure command:

  ./configure --with-lkl=/path/to/linux

To use it, eg. from guestfish:

  export LIBGUESTFS_BACKEND=lkl
  export LIBGUESTFS_HV=$(pwd)/daemon/guestfsd-lkl
  ./run guestfish

To do:

 - Documentation.

 - Pass per-disk flags from library to daemon (on the command line).
   Currently all disks are opened for write, even if you specify
   the readonly flag.

 - Pass g->memsize from library to daemon.

 - Pass g->append from library to daemon.

 - Disable unsafe APIs.  Many APIs could never be supported by LKL,
   and are completely unsafe to use.  eg. guestfs_sh.  These must be
   disabled when HAVE_LKL=1 so the user cannot accidentally damage
   their host.
  • Loading branch information
rwmjones committed Nov 7, 2015
1 parent 3bf676b commit e38525f
Show file tree
Hide file tree
Showing 11 changed files with 629 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -122,6 +122,7 @@ Makefile.in
/daemon/guestfsd
/daemon/guestfsd.8
/daemon/guestfsd.exe
/daemon/guestfsd-lkl
/daemon/guestfs_protocol.c
/daemon/guestfs_protocol.h
/daemon/install-sh
Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Expand Up @@ -108,6 +108,9 @@ m4_include([m4/guestfs_qemu.m4])
dnl Miscellaneous libraries used by other programs.
m4_include([m4/guestfs_misc_libraries.m4])

dnl LKL (Linux Kernel Library)
m4_include([m4/guestfs_lkl.m4])

dnl Check for language bindings.
m4_include([m4/guestfs_ocaml.m4])
m4_include([m4/guestfs_perl.m4])
Expand Down
16 changes: 16 additions & 0 deletions daemon/Makefile.am
Expand Up @@ -218,6 +218,22 @@ guestfsd_CFLAGS = \
$(YAJL_CFLAGS) \
$(PCRE_CFLAGS)

if HAVE_LKL

# Compile guestfsd again, linked to liblkl.
bin_PROGRAMS = guestfsd-lkl

guestfsd_lkl_SOURCES = $(guestfsd_SOURCES)
guestfsd_lkl_LDADD = \
-L$(LKL_PATH)/tools/lkl/lib -llkl -lrt $(guestfsd_LDADD)
guestfsd_lkl_CPPFLAGS = \
$(guestfsd_CPPFLAGS) -DHAVE_LKL=1 -I$(LKL_PATH)/tools/lkl/include
guestfsd_lkl_CFLAGS = \
-pthread \
$(guestfsd_CFLAGS)

endif

# Manual pages and HTML files for the website.
if INSTALL_DAEMON
man_MANS = guestfsd.8
Expand Down
6 changes: 6 additions & 0 deletions daemon/daemon.h
Expand Up @@ -64,6 +64,12 @@ extern int xread (int sock, void *buf, size_t len)

extern char *mountable_to_string (const mountable_t *mountable);

#if HAVE_LKL
/* LKL disk IDs. */
extern int *disk_id;
extern size_t nr_disks;
#endif

/*-- in mount.c --*/

extern int mount_vfs_nochroot (const char *options, const char *vfstype,
Expand Down
59 changes: 58 additions & 1 deletion daemon/guestfsd.c
Expand Up @@ -32,6 +32,11 @@
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_LKL /* Wut? XXX */
#undef st_atime
#undef st_mtime
#undef st_ctime
#endif
#include <fcntl.h>
#include <signal.h>
#include <netdb.h>
Expand All @@ -47,6 +52,11 @@
# include <printf.h>
#endif

#ifdef HAVE_LKL
#include <lkl.h>
#include <lkl_host.h>
#endif

#include <augeas.h>

#include "sockets.h"
Expand Down Expand Up @@ -128,11 +138,21 @@ const char *program_name = "guestfsd";
/* Name of the virtio-serial channel. */
#define VIRTIO_SERIAL_CHANNEL "/dev/virtio-ports/org.libguestfs.channel.0"

#if HAVE_LKL
/* LKL disk IDs. */
int *disk_id;
size_t nr_disks;
#endif

static void
usage (void)
{
fprintf (stderr,
"guestfsd [-r] [-v|--verbose]\n");
"guestfsd [-r] [-v|--verbose]"
#if HAVE_LKL
" disk [disk ...]"
#endif
"\n");
}

int
Expand All @@ -152,6 +172,15 @@ main (int argc, char *argv[])
const char *channel = NULL;
int listen_mode = 0;

#if HAVE_LKL
/* XXX Safety check. Because large parts of the daemon haven't been
* ported to use LKL, refuse to run as root in case someone ends up
* trashing their host system by using some unported command.
*/
if (geteuid () == 0)
error (EXIT_FAILURE, 0, "refusing to run as root");
#endif

ignore_value (chdir ("/"));

if (winsock_init () == -1)
Expand Down Expand Up @@ -230,6 +259,32 @@ main (int argc, char *argv[])
}
}

#if HAVE_LKL
nr_disks = argc - optind;
disk_id = malloc (nr_disks * sizeof (int));
if (disk_id == NULL)
error (EXIT_FAILURE, errno, "malloc");

for (size_t i = 0; i < nr_disks; ++i, ++optind) {
union lkl_disk_backstore disk;

/* XXX Pass through readonly and other per-disk flags from library side. */

disk.fd = open (argv[optind], O_RDWR);
if (disk.fd == -1)
error (EXIT_FAILURE, errno, "open: %s", argv[optind]);
disk_id[i] = lkl_disk_add (disk);
if (disk_id[i] < 0)
error (EXIT_FAILURE, 0, "lkl_disk_add: %s: %s",
argv[optind], lkl_strerror (disk_id[i]));
}

/* XXX I assume the second parameter is memory size. Pass
* g->memsize setting through to the daemon.
*/
lkl_start_kernel (&lkl_host_ops, 100 * 1024 * 1024, "");
#endif

if (optind < argc) {
usage ();
exit (EXIT_FAILURE);
Expand Down Expand Up @@ -269,11 +324,13 @@ main (int argc, char *argv[])
_umask (0);
#endif

#ifndef HAVE_LKL
/* Make a private copy of /etc/lvm so we can change the config (see
* daemon/lvm-filter.c).
*/
if (!test_mode)
copy_lvm ();
#endif

/* Connect to virtio-serial channel. */
if (!channel)
Expand Down
49 changes: 49 additions & 0 deletions m4/guestfs_lkl.m4
@@ -0,0 +1,49 @@
# libguestfs
# Copyright (C) 2009-2015 Red Hat Inc.
#
# 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.

dnl LKL (Linux Kernel compiled as a Library).
dnl
dnl You have to use --with-lkl=/path/to/linux
dnl
dnl where '/path/to/linux' is the absolute path to the Linux sources
dnl (https://github.com/lkl/linux), compiled. See Documentation/lkl.txt
dnl for how to build LKL.

AC_MSG_CHECKING([for LKL (Linux Kernel Library)])
AC_ARG_WITH([lkl],
[AS_HELP_STRING([--with-lkl=/path/to/linux],
[build the LKL (Linux Kernel Library) backend])],
[
LKL_PATH="$withval"
# Does it contain the compiled static library?
if ! test -f "$LKL_PATH/tools/lkl/lib/liblkl.a"; then
AC_MSG_FAILURE([--with-lkl parameter does not point to compiled LKL])
fi
# Does it contain the header file?
if ! test -f "$LKL_PATH/tools/lkl/include/lkl.h"; then
AC_MSG_FAILURE([--with-lkl parameter does not point to LKL header file])
fi
],
[LKL_PATH=no])
AC_MSG_RESULT([$LKL_PATH])

AC_SUBST([LKL_PATH])

AM_CONDITIONAL([HAVE_LKL], [test "x$LKL_PATH" != "xno"])
1 change: 1 addition & 0 deletions po/POTFILES
Expand Up @@ -331,6 +331,7 @@ src/inspect.c
src/journal.c
src/launch-direct.c
src/launch-libvirt.c
src/launch-lkl.c
src/launch-uml.c
src/launch-unix.c
src/launch.c
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Expand Up @@ -112,6 +112,7 @@ libguestfs_la_SOURCES = \
launch.c \
launch-direct.c \
launch-libvirt.c \
launch-lkl.c \
launch-uml.c \
launch-unix.c \
libvirt-auth.c \
Expand Down
1 change: 1 addition & 0 deletions src/guestfs-internal.h
Expand Up @@ -915,6 +915,7 @@ void guestfs_int_init_direct_backend (void) __attribute__((constructor));
void guestfs_int_init_libvirt_backend (void) __attribute__((constructor));
#endif
void guestfs_int_init_uml_backend (void) __attribute__((constructor));
void guestfs_int_init_lkl_backend (void) __attribute__((constructor));
void guestfs_int_init_unix_backend (void) __attribute__((constructor));

/* guid.c */
Expand Down

0 comments on commit e38525f

Please sign in to comment.