* [uml-devel] [PATCH] um: register with systemd-machined
@ 2014-09-13 14:03 Thomas Meyer
0 siblings, 0 replies; only message in thread
From: Thomas Meyer @ 2014-09-13 14:03 UTC (permalink / raw)
To: user-mode-linux-devel
Hi,
This patch registers an UML instance with systemd-machined.
You may need to modify the dbus policy to allow this request
in /etc/dbus-1/system.d/org.freedesktop.machine1.conf
Attached patch crashes the UML kernel, but I've know idea why!
Help is appreciated and feedback is welcome!
diff --git a/arch/um/Makefile b/arch/um/Makefile
index e4b1a96..e9e3dee 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -132,8 +132,10 @@ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
+LINK_DBUS = $(shell pkg-config --libs dbus-1)
+
# Used by link-vmlinux.sh which has special support for um link
-export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
+export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) $(LINK_DBUS)
# When cleaning we don't include .config, so we don't include
# TT or skas makefiles and don't clean skas_ptregs.h.
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 08eec0b..13f8f10 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -217,6 +217,7 @@ extern int helper_wait(int pid);
extern int umid_file_name(char *name, char *buf, int len);
extern int set_umid(char *name);
extern char *get_umid(void);
+extern char *get_uml_dir_realpath(void);
/* signal.c */
extern void timer_init(void);
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 08ff509..23559a3 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -5,16 +5,18 @@
obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
registers.o sigio.o signal.o start_up.o time.o tty.o \
- umid.o user_syms.o util.o drivers/ skas/
+ umid.o user_syms.o util.o drivers/ skas/ machined.o
obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
- tty.o umid.o util.o
+ tty.o umid.o util.o machined.o
HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \
echo -DHAVE_AIO_ABI )
CFLAGS_aio.o += $(HAVE_AIO_ABI)
+CFLAGS_machined.o += $(shell pkg-config --cflags dbus-1 )
+
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/machined.c b/arch/um/os-Linux/machined.c
new file mode 100644
index 0000000..d39e7b1
--- /dev/null
+++ b/arch/um/os-Linux/machined.c
@@ -0,0 +1,89 @@
+#include <dbus/dbus.h>
+#include <init.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <os.h>
+#include <string.h>
+
+static int machined_init(void) {
+
+ DBusMessageIter message_iter;
+ DBusMessageIter message_iter_array;
+
+ DBusError dbus_error = {};
+ dbus_bool_t dbus_rc = false;
+
+ DBusConnection *con = NULL;
+ DBusMessage* message = NULL, *reply_message = NULL;
+
+ char *root_dir = get_uml_dir_realpath();
+
+ char *arg_machine_name = NULL;
+ unsigned char arg_uuid[] = { };
+ dbus_uint32_t arg_pid = os_getpid();
+ char *arg_root_dir = root_dir ? "" : root_dir;
+ const char *arg_service = "uml";
+ const char *arg_class = "vm";
+
+#define SLEN 255
+ arg_machine_name = malloc(SLEN);
+ if(arg_machine_name == NULL) {
+ goto out;
+ }
+
+ snprintf(arg_machine_name, SLEN, "uml-uid=%i-umid=%s", getuid(), get_umid());
+
+ con = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if(con == NULL) {
+ printf("dbus_bus_get: no connection to system bus!\n");
+ goto out;
+ }
+
+ message = dbus_message_new_method_call(
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "CreateMachine");
+ if(message == NULL) {
+ printf("dbus_message_new_method_call: no machined manager found!\n");
+ goto out;
+ }
+
+ dbus_message_iter_init_append (message, &message_iter);
+ /* normal arguments */
+ dbus_rc = dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_STRING, &arg_machine_name);
+ dbus_rc &= dbus_message_iter_open_container(&message_iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &message_iter_array);
+ dbus_rc &= dbus_message_iter_append_fixed_array(&message_iter_array, DBUS_TYPE_BYTE, &arg_uuid, 0);
+ dbus_rc &= dbus_message_iter_close_container(&message_iter, &message_iter_array);
+ dbus_rc &= dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_STRING, &arg_service);
+ dbus_rc &= dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_STRING, &arg_class);
+ dbus_rc &= dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_UINT32, &arg_pid);
+ dbus_rc &= dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_STRING, &arg_root_dir);
+
+ /* append scope properties array */
+ dbus_rc &= dbus_message_iter_open_container(&message_iter, DBUS_TYPE_ARRAY, "(sv)", &message_iter_array);
+ /* ENHANCEME: fill in array of (sv) to control the scope unit */
+ dbus_rc &= dbus_message_iter_close_container(&message_iter, &message_iter_array);
+ if(dbus_rc != true) {
+ printf("DBusMessage: construction of message failed!\n");
+ goto out;
+ }
+
+ reply_message = dbus_connection_send_with_reply_and_block(con, message, -1, &dbus_error);
+ if(reply_message == NULL) {
+ printf("Failed to register with systemd-machined: %s\n", dbus_error.message);
+ goto out;
+ }
+
+out:
+ free(arg_machine_name);
+ free(root_dir);
+ dbus_connection_flush(con);
+ dbus_message_unref(message);
+ dbus_connection_unref(con);
+ return 0;
+}
+
+__uml_postsetup(machined_init);
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index c1dc892..aae05be 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <init.h>
#include <os.h>
+#include <stdbool.h>
#define UML_DIR "~/.uml/"
@@ -24,47 +25,55 @@ static char umid[UMID_LEN] = { 0 };
/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
static char *uml_dir = UML_DIR;
+static bool uml_dir_set = false;
+
+char* get_uml_dir_realpath(void) {
-static int __init make_uml_dir(void)
-{
char dir[512] = { '\0' };
- int len, err;
+ int len = 0;
+ char* uml_dir_real = NULL;
+ char *uml_dir_local = uml_dir;
- if (*uml_dir == '~') {
+ if (*uml_dir_local == '~') {
char *home = getenv("HOME");
- err = -ENOENT;
if (home == NULL) {
printk(UM_KERN_ERR "make_uml_dir : no value in "
"environment for $HOME\n");
goto err;
}
strlcpy(dir, home, sizeof(dir));
- uml_dir++;
+ uml_dir_local++;
}
- strlcat(dir, uml_dir, sizeof(dir));
+ strlcat(dir, uml_dir_local, sizeof(dir));
len = strlen(dir);
- if (len > 0 && dir[len - 1] != '/')
+ if (len > 0 && dir[len - 1] != '/') {
strlcat(dir, "/", sizeof(dir));
+ }
- err = -ENOMEM;
- uml_dir = malloc(strlen(dir) + 1);
- if (uml_dir == NULL) {
- printf("make_uml_dir : malloc failed, errno = %d\n", errno);
+ uml_dir_real = malloc(strlen(dir) + 1);
+ if (uml_dir_real == NULL) {
+ printf("get_uml_dir_realpath : malloc failed, errno = %d\n", errno);
goto err;
}
- strcpy(uml_dir, dir);
+ strcpy(uml_dir_real, dir);
+err:
+ return uml_dir_real;
+}
+
+static int __init make_uml_dir(void)
+{
+ int err = 0;
+ char* uml_dir_real = get_uml_dir_realpath();
- if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
- printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
+ if ((mkdir(uml_dir_real, 0777) < 0) && (errno != EEXIST)) {
+ printf("Failed to mkdir '%s': %s\n", uml_dir_real, strerror(errno));
err = -errno;
- goto err_free;
}
- return 0;
-
-err_free:
- free(uml_dir);
-err:
+ free(uml_dir_real);
+ if(uml_dir_set == true) {
+ free(uml_dir);
+ }
uml_dir = NULL;
return err;
}
@@ -128,18 +137,17 @@ out:
* this boot racing with a shutdown of the other UML
* In any of these cases, the directory isn't useful for anything else.
*
- * Boolean return: 1 if in use, 0 otherwise.
+ * Boolean return: true if in use, false otherwise.
*/
-static inline int is_umdir_used(char *dir)
+static inline bool is_umdir_used(char *dir)
{
char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
char pid[sizeof("nnnnn\0")], *end;
- int dead, fd, p, n, err;
+ int dead, fd, p, n;
n = snprintf(file, sizeof(file), "%s/pid", dir);
if (n >= sizeof(file)) {
printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
- err = -E2BIG;
goto out;
}
@@ -154,7 +162,6 @@ static inline int is_umdir_used(char *dir)
goto out;
}
- err = 0;
n = read(fd, pid, sizeof(pid));
if (n < 0) {
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
@@ -176,13 +183,13 @@ static inline int is_umdir_used(char *dir)
if ((kill(p, 0) == 0) || (errno != ESRCH)) {
printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
umid, p);
- return 1;
+ return true;
}
out_close:
close(fd);
out:
- return 0;
+ return false;
}
/*
@@ -350,6 +357,10 @@ char *get_umid(void)
static int __init set_uml_dir(char *name, int *add)
{
+ if(uml_dir_set == true) {
+ free(uml_dir);
+ }
+
if (*name == '\0') {
printf("uml_dir can't be an empty string\n");
return 0;
@@ -371,7 +382,7 @@ static int __init set_uml_dir(char *name, int *add)
return 0;
}
sprintf(uml_dir, "%s/", name);
-
+ uml_dir_set = true;
return 0;
}
------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2014-09-13 14:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-13 14:03 [uml-devel] [PATCH] um: register with systemd-machined Thomas Meyer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.