diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index b49e2cdcab..3e8361b121 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -19,7 +19,7 @@ XL_OBJS = xl.o xl_cmdimpl.o xl_cmdtable.o xl_sxp.o xl_utils.o
 XL_OBJS += xl_tmem.o xl_parse.o xl_cpupool.o xl_flask.o
 XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o
 XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cd.o xl_mem.o
-XL_OBJS += xl_psr.o xl_info.o xl_console.o
+XL_OBJS += xl_psr.o xl_info.o xl_console.o xl_misc.o
 
 $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
 $(XL_OBJS): CFLAGS += $(CFLAGS_XL)
diff --git a/tools/xl/xl_cmdimpl.c b/tools/xl/xl_cmdimpl.c
index d32e7fe6f1..7851fc03d4 100644
--- a/tools/xl/xl_cmdimpl.c
+++ b/tools/xl/xl_cmdimpl.c
@@ -222,74 +222,6 @@ release_lock:
     return rc;
 }
 
-static int do_daemonize(char *name, const char *pidfile)
-{
-    char *fullname;
-    pid_t child1;
-    int nullfd, ret = 0;
-
-    child1 = xl_fork(child_waitdaemon, "domain monitoring daemonizing child");
-    if (child1) {
-        ret = child_report(child_waitdaemon);
-        if (ret) goto out;
-        ret = 1;
-        goto out;
-    }
-
-    postfork();
-
-    ret = libxl_create_logfile(ctx, name, &fullname);
-    if (ret) {
-        LOG("failed to open logfile %s: %s",fullname,strerror(errno));
-        exit(-1);
-    }
-
-    CHK_SYSCALL(logfile = open(fullname, O_WRONLY|O_CREAT|O_APPEND, 0644));
-    free(fullname);
-    assert(logfile >= 3);
-
-    CHK_SYSCALL(nullfd = open("/dev/null", O_RDONLY));
-    assert(nullfd >= 3);
-
-    dup2(nullfd, 0);
-    dup2(logfile, 1);
-    dup2(logfile, 2);
-
-    close(nullfd);
-
-    CHK_SYSCALL(daemon(0, 1));
-
-    if (pidfile) {
-        int fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
-        char *pid = NULL;
-
-        if (fd == -1) {
-            perror("Unable to open pidfile");
-            exit(1);
-        }
-
-        if (asprintf(&pid, "%ld\n", (long)getpid()) == -1) {
-            perror("Formatting pid");
-            exit(1);
-        }
-
-        if (write(fd, pid, strlen(pid)) < 0) {
-            perror("Writing pid");
-            exit(1);
-        }
-
-        if (close(fd) < 0) {
-            perror("Closing pidfile");
-            exit(1);
-        }
-
-        free(pid);
-    }
-
-out:
-    return ret;
-}
-
 static void reload_domain_config(uint32_t domid,
                                  libxl_domain_config *d_config)
 {
@@ -1192,14 +1124,6 @@ static void reboot_domain(uint32_t domid, libxl_evgen_domain_death **deathw,
     }
 }
 
-static void core_dump_domain(uint32_t domid, const char *filename)
-{
-    int rc;
-
-    rc=libxl_domain_core_dump(ctx, domid, filename, NULL);
-    if (rc) { fprintf(stderr,"core dump failed (rc=%d)\n",rc);exit(EXIT_FAILURE); }
-}
-
 #ifndef LIBXL_HAVE_NO_SUSPEND_RESUME
 static void save_domain_core_begin(uint32_t domid,
                                    const char *override_config_file,
@@ -1991,18 +1915,6 @@ int main_migrate(int argc, char **argv)
 }
 #endif
 
-int main_dump_core(int argc, char **argv)
-{
-    int opt;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "dump-core", 2) {
-        /* No options */
-    }
-
-    core_dump_domain(xfind_domain(argv[optind]), argv[optind + 1]);
-    return EXIT_SUCCESS;
-}
-
 int main_pause(int argc, char **argv)
 {
     int opt;
@@ -2220,246 +2132,6 @@ int main_create(int argc, char **argv)
     return 0;
 }
 
-extern void printf_info(enum output_format output_format,
-                        int domid,
-                        libxl_domain_config *d_config, FILE *fh);
-int main_config_update(int argc, char **argv)
-{
-    uint32_t domid;
-    const char *filename = NULL;
-    char *extra_config = NULL;
-    void *config_data = 0;
-    int config_len = 0;
-    libxl_domain_config d_config;
-    int opt, rc;
-    int debug = 0;
-    static struct option opts[] = {
-        {"defconfig", 1, 0, 'f'},
-        COMMON_LONG_OPTS
-    };
-
-    if (argc < 2) {
-        fprintf(stderr, "xl config-update requires a domain argument\n");
-        help("config-update");
-        exit(1);
-    }
-
-    fprintf(stderr, "WARNING: xl now has better capability to manage domain configuration, "
-            "avoid using this command when possible\n");
-
-    domid = xfind_domain(argv[1]);
-    argc--; argv++;
-
-    if (argv[1] && argv[1][0] != '-' && !strchr(argv[1], '=')) {
-        filename = argv[1];
-        argc--; argv++;
-    }
-
-    SWITCH_FOREACH_OPT(opt, "dqf:", opts, "config_update", 0) {
-    case 'd':
-        debug = 1;
-        break;
-    case 'f':
-        filename = optarg;
-        break;
-    }
-
-    for (; optind < argc; optind++) {
-        if (strchr(argv[optind], '=') != NULL) {
-            xstring_realloc_append(&extra_config, argv[optind]);
-            xstring_realloc_append(&extra_config, "\n");
-        } else if (!filename) {
-            filename = argv[optind];
-        } else {
-            help("create");
-            free(extra_config);
-            return 2;
-        }
-    }
-    if (filename) {
-        free(config_data);  config_data = 0;
-        rc = libxl_read_file_contents(ctx, filename,
-                                      &config_data, &config_len);
-        if (rc) { fprintf(stderr, "Failed to read config file: %s: %s\n",
-                           filename, strerror(errno));
-                  free(extra_config); return ERROR_FAIL; }
-        if (extra_config && strlen(extra_config)) {
-            if (config_len > INT_MAX - (strlen(extra_config) + 2 + 1)) {
-                fprintf(stderr, "Failed to attach extra configuration\n");
-                exit(1);
-            }
-            /* allocate space for the extra config plus two EOLs plus \0 */
-            config_data = realloc(config_data, config_len
-                + strlen(extra_config) + 2 + 1);
-            if (!config_data) {
-                fprintf(stderr, "Failed to realloc config_data\n");
-                exit(1);
-            }
-            config_len += sprintf(config_data + config_len, "\n%s\n",
-                extra_config);
-        }
-    } else {
-        fprintf(stderr, "Config file not specified\n");
-        exit(1);
-    }
-
-    libxl_domain_config_init(&d_config);
-
-    parse_config_data(filename, config_data, config_len, &d_config);
-
-    if (debug || dryrun_only)
-        printf_info(default_output_format, -1, &d_config, stdout);
-
-    if (!dryrun_only) {
-        fprintf(stderr, "setting dom%u configuration\n", domid);
-        rc = libxl_userdata_store(ctx, domid, "xl",
-                                   config_data, config_len);
-        if (rc) {
-            fprintf(stderr, "failed to update configuration\n");
-            exit(1);
-        }
-    }
-
-    libxl_domain_config_dispose(&d_config);
-
-    free(config_data);
-    free(extra_config);
-    return 0;
-}
-
-static void button_press(uint32_t domid, const char *b)
-{
-    libxl_trigger trigger;
-
-    if (!strcmp(b, "power")) {
-        trigger = LIBXL_TRIGGER_POWER;
-    } else if (!strcmp(b, "sleep")) {
-        trigger = LIBXL_TRIGGER_SLEEP;
-    } else {
-        fprintf(stderr, "%s is an invalid button identifier\n", b);
-        exit(EXIT_FAILURE);
-    }
-
-    libxl_send_trigger(ctx, domid, trigger, 0);
-}
-
-int main_button_press(int argc, char **argv)
-{
-    int opt;
-
-    fprintf(stderr, "WARNING: \"button-press\" is deprecated. "
-            "Please use \"trigger\"\n");
-
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "button-press", 2) {
-        /* No options */
-    }
-
-    button_press(xfind_domain(argv[optind]), argv[optind + 1]);
-
-    return 0;
-}
-
-int main_rename(int argc, char **argv)
-{
-    uint32_t domid;
-    int opt;
-    const char *dom, *new_name;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "rename", 2) {
-        /* No options */
-    }
-
-    dom = argv[optind++];
-    new_name = argv[optind];
-
-    domid = xfind_domain(dom);
-    if (libxl_domain_rename(ctx, domid, common_domname, new_name)) {
-        fprintf(stderr, "Can't rename domain '%s'.\n", dom);
-        return 1;
-    }
-
-    return 0;
-}
-
-int main_trigger(int argc, char **argv)
-{
-    uint32_t domid;
-    int opt;
-    char *endptr = NULL;
-    int vcpuid = 0;
-    const char *trigger_name = NULL;
-    libxl_trigger trigger;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "trigger", 2) {
-        /* No options */
-    }
-
-    domid = xfind_domain(argv[optind++]);
-
-    trigger_name = argv[optind++];
-    if (libxl_trigger_from_string(trigger_name, &trigger)) {
-        fprintf(stderr, "Invalid trigger \"%s\"\n", trigger_name);
-        return EXIT_FAILURE;
-    }
-
-    if (argv[optind]) {
-        vcpuid = strtol(argv[optind], &endptr, 10);
-        if (vcpuid == 0 && !strcmp(endptr, argv[optind])) {
-            fprintf(stderr, "Invalid vcpuid, using default vcpuid=0.\n\n");
-        }
-    }
-
-    libxl_send_trigger(ctx, domid, trigger, vcpuid);
-
-    return EXIT_SUCCESS;
-}
-
-
-int main_sysrq(int argc, char **argv)
-{
-    uint32_t domid;
-    int opt;
-    const char *sysrq = NULL;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "sysrq", 2) {
-        /* No options */
-    }
-
-    domid = xfind_domain(argv[optind++]);
-
-    sysrq = argv[optind];
-
-    if (sysrq[1] != '\0') {
-        fprintf(stderr, "Invalid sysrq.\n\n");
-        help("sysrq");
-        return EXIT_FAILURE;
-    }
-
-    libxl_send_sysrq(ctx, domid, sysrq[0]);
-
-    return EXIT_SUCCESS;
-}
-
-int main_debug_keys(int argc, char **argv)
-{
-    int opt;
-    char *keys;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "debug-keys", 1) {
-        /* No options */
-    }
-
-    keys = argv[optind];
-
-    if (libxl_send_debug_keys(ctx, keys)) {
-        fprintf(stderr, "cannot send debug keys: %s\n", keys);
-        return EXIT_FAILURE;
-    }
-
-    return EXIT_SUCCESS;
-}
-
 #ifndef LIBXL_HAVE_NO_SUSPEND_RESUME
 int main_remus(int argc, char **argv)
 {
@@ -2611,68 +2283,6 @@ int main_remus(int argc, char **argv)
 }
 #endif
 
-int main_devd(int argc, char **argv)
-{
-    int ret = 0, opt = 0, daemonize = 1;
-    const char *pidfile = NULL;
-    static const struct option opts[] = {
-        {"pidfile", 1, 0, 'p'},
-        COMMON_LONG_OPTS,
-        {0, 0, 0, 0}
-    };
-
-    SWITCH_FOREACH_OPT(opt, "Fp:", opts, "devd", 0) {
-    case 'F':
-        daemonize = 0;
-        break;
-    case 'p':
-        pidfile = optarg;
-        break;
-    }
-
-    if (daemonize) {
-        ret = do_daemonize("xldevd", pidfile);
-        if (ret) {
-            ret = (ret == 1) ? 0 : ret;
-            goto out;
-        }
-    }
-
-    libxl_device_events_handler(ctx, 0);
-
-out:
-    return ret;
-}
-
-int main_qemu_monitor_command(int argc, char **argv)
-{
-    int opt;
-    uint32_t domid;
-    char *cmd;
-    char *output;
-    int ret;
-
-    SWITCH_FOREACH_OPT(opt, "", NULL, "qemu-monitor-command", 2) {
-        /* No options */
-    }
-
-    domid = xfind_domain(argv[optind]);
-    cmd = argv[optind + 1];
-
-    if (argc - optind > 2) {
-        fprintf(stderr, "Invalid arguments.\n");
-        return EXIT_FAILURE;
-    }
-
-    ret = libxl_qemu_monitor_command(ctx, domid, cmd, &output);
-    if (!ret && output) {
-        printf("%s\n", output);
-        free(output);
-    }
-
-    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/xl/xl_misc.c b/tools/xl/xl_misc.c
new file mode 100644
index 0000000000..0bf337d8f7
--- /dev/null
+++ b/tools/xl/xl_misc.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2009-2017 Citrix Ltd and other contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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 Lesser General Public License for more details.
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+
+#include <libxl.h>
+#include <libxl_utils.h>
+#include <libxlutil.h>
+
+#include "xl.h"
+#include "xl_utils.h"
+#include "xl_parse.h"
+
+extern const char *common_domname;
+
+static void button_press(uint32_t domid, const char *b)
+{
+    libxl_trigger trigger;
+
+    if (!strcmp(b, "power")) {
+        trigger = LIBXL_TRIGGER_POWER;
+    } else if (!strcmp(b, "sleep")) {
+        trigger = LIBXL_TRIGGER_SLEEP;
+    } else {
+        fprintf(stderr, "%s is an invalid button identifier\n", b);
+        exit(EXIT_FAILURE);
+    }
+
+    libxl_send_trigger(ctx, domid, trigger, 0);
+}
+
+int main_button_press(int argc, char **argv)
+{
+    int opt;
+
+    fprintf(stderr, "WARNING: \"button-press\" is deprecated. "
+            "Please use \"trigger\"\n");
+
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "button-press", 2) {
+        /* No options */
+    }
+
+    button_press(xfind_domain(argv[optind]), argv[optind + 1]);
+
+    return 0;
+}
+
+int main_rename(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    const char *dom, *new_name;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "rename", 2) {
+        /* No options */
+    }
+
+    dom = argv[optind++];
+    new_name = argv[optind];
+
+    domid = xfind_domain(dom);
+    if (libxl_domain_rename(ctx, domid, common_domname, new_name)) {
+        fprintf(stderr, "Can't rename domain '%s'.\n", dom);
+        return 1;
+    }
+
+    return 0;
+}
+
+int main_trigger(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    char *endptr = NULL;
+    int vcpuid = 0;
+    const char *trigger_name = NULL;
+    libxl_trigger trigger;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "trigger", 2) {
+        /* No options */
+    }
+
+    domid = xfind_domain(argv[optind++]);
+
+    trigger_name = argv[optind++];
+    if (libxl_trigger_from_string(trigger_name, &trigger)) {
+        fprintf(stderr, "Invalid trigger \"%s\"\n", trigger_name);
+        return EXIT_FAILURE;
+    }
+
+    if (argv[optind]) {
+        vcpuid = strtol(argv[optind], &endptr, 10);
+        if (vcpuid == 0 && !strcmp(endptr, argv[optind])) {
+            fprintf(stderr, "Invalid vcpuid, using default vcpuid=0.\n\n");
+        }
+    }
+
+    libxl_send_trigger(ctx, domid, trigger, vcpuid);
+
+    return EXIT_SUCCESS;
+}
+
+int main_sysrq(int argc, char **argv)
+{
+    uint32_t domid;
+    int opt;
+    const char *sysrq = NULL;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "sysrq", 2) {
+        /* No options */
+    }
+
+    domid = xfind_domain(argv[optind++]);
+
+    sysrq = argv[optind];
+
+    if (sysrq[1] != '\0') {
+        fprintf(stderr, "Invalid sysrq.\n\n");
+        help("sysrq");
+        return EXIT_FAILURE;
+    }
+
+    libxl_send_sysrq(ctx, domid, sysrq[0]);
+
+    return EXIT_SUCCESS;
+}
+
+int main_debug_keys(int argc, char **argv)
+{
+    int opt;
+    char *keys;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "debug-keys", 1) {
+        /* No options */
+    }
+
+    keys = argv[optind];
+
+    if (libxl_send_debug_keys(ctx, keys)) {
+        fprintf(stderr, "cannot send debug keys: %s\n", keys);
+        return EXIT_FAILURE;
+    }
+
+    return EXIT_SUCCESS;
+}
+
+int main_devd(int argc, char **argv)
+{
+    int ret = 0, opt = 0, daemonize = 1;
+    const char *pidfile = NULL;
+    static const struct option opts[] = {
+        {"pidfile", 1, 0, 'p'},
+        COMMON_LONG_OPTS,
+        {0, 0, 0, 0}
+    };
+
+    SWITCH_FOREACH_OPT(opt, "Fp:", opts, "devd", 0) {
+    case 'F':
+        daemonize = 0;
+        break;
+    case 'p':
+        pidfile = optarg;
+        break;
+    }
+
+    if (daemonize) {
+        ret = do_daemonize("xldevd", pidfile);
+        if (ret) {
+            ret = (ret == 1) ? 0 : ret;
+            goto out;
+        }
+    }
+
+    libxl_device_events_handler(ctx, 0);
+
+out:
+    return ret;
+}
+
+int main_qemu_monitor_command(int argc, char **argv)
+{
+    int opt;
+    uint32_t domid;
+    char *cmd;
+    char *output;
+    int ret;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "qemu-monitor-command", 2) {
+        /* No options */
+    }
+
+    domid = xfind_domain(argv[optind]);
+    cmd = argv[optind + 1];
+
+    if (argc - optind > 2) {
+        fprintf(stderr, "Invalid arguments.\n");
+        return EXIT_FAILURE;
+    }
+
+    ret = libxl_qemu_monitor_command(ctx, domid, cmd, &output);
+    if (!ret && output) {
+        printf("%s\n", output);
+        free(output);
+    }
+
+    return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+static void core_dump_domain(uint32_t domid, const char *filename)
+{
+    int rc;
+
+    rc=libxl_domain_core_dump(ctx, domid, filename, NULL);
+    if (rc) { fprintf(stderr,"core dump failed (rc=%d)\n",rc);exit(EXIT_FAILURE); }
+}
+
+int main_dump_core(int argc, char **argv)
+{
+    int opt;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "dump-core", 2) {
+        /* No options */
+    }
+
+    core_dump_domain(xfind_domain(argv[optind]), argv[optind + 1]);
+    return EXIT_SUCCESS;
+}
+
+extern void printf_info(enum output_format output_format,
+                        int domid,
+                        libxl_domain_config *d_config, FILE *fh);
+int main_config_update(int argc, char **argv)
+{
+    uint32_t domid;
+    const char *filename = NULL;
+    char *extra_config = NULL;
+    void *config_data = 0;
+    int config_len = 0;
+    libxl_domain_config d_config;
+    int opt, rc;
+    int debug = 0;
+    static struct option opts[] = {
+        {"defconfig", 1, 0, 'f'},
+        COMMON_LONG_OPTS
+    };
+
+    if (argc < 2) {
+        fprintf(stderr, "xl config-update requires a domain argument\n");
+        help("config-update");
+        exit(1);
+    }
+
+    fprintf(stderr, "WARNING: xl now has better capability to manage domain configuration, "
+            "avoid using this command when possible\n");
+
+    domid = xfind_domain(argv[1]);
+    argc--; argv++;
+
+    if (argv[1] && argv[1][0] != '-' && !strchr(argv[1], '=')) {
+        filename = argv[1];
+        argc--; argv++;
+    }
+
+    SWITCH_FOREACH_OPT(opt, "dqf:", opts, "config_update", 0) {
+    case 'd':
+        debug = 1;
+        break;
+    case 'f':
+        filename = optarg;
+        break;
+    }
+
+    for (; optind < argc; optind++) {
+        if (strchr(argv[optind], '=') != NULL) {
+            xstring_realloc_append(&extra_config, argv[optind]);
+            xstring_realloc_append(&extra_config, "\n");
+        } else if (!filename) {
+            filename = argv[optind];
+        } else {
+            help("create");
+            free(extra_config);
+            return 2;
+        }
+    }
+    if (filename) {
+        free(config_data);  config_data = 0;
+        rc = libxl_read_file_contents(ctx, filename,
+                                      &config_data, &config_len);
+        if (rc) { fprintf(stderr, "Failed to read config file: %s: %s\n",
+                           filename, strerror(errno));
+                  free(extra_config); return ERROR_FAIL; }
+        if (extra_config && strlen(extra_config)) {
+            if (config_len > INT_MAX - (strlen(extra_config) + 2 + 1)) {
+                fprintf(stderr, "Failed to attach extra configuration\n");
+                exit(1);
+            }
+            /* allocate space for the extra config plus two EOLs plus \0 */
+            config_data = realloc(config_data, config_len
+                + strlen(extra_config) + 2 + 1);
+            if (!config_data) {
+                fprintf(stderr, "Failed to realloc config_data\n");
+                exit(1);
+            }
+            config_len += sprintf(config_data + config_len, "\n%s\n",
+                extra_config);
+        }
+    } else {
+        fprintf(stderr, "Config file not specified\n");
+        exit(1);
+    }
+
+    libxl_domain_config_init(&d_config);
+
+    parse_config_data(filename, config_data, config_len, &d_config);
+
+    if (debug || dryrun_only)
+        printf_info(default_output_format, -1, &d_config, stdout);
+
+    if (!dryrun_only) {
+        fprintf(stderr, "setting dom%u configuration\n", domid);
+        rc = libxl_userdata_store(ctx, domid, "xl",
+                                   config_data, config_len);
+        if (rc) {
+            fprintf(stderr, "failed to update configuration\n");
+            exit(1);
+        }
+    }
+
+    libxl_domain_config_dispose(&d_config);
+
+    free(config_data);
+    free(extra_config);
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/xl/xl_utils.c b/tools/xl/xl_utils.c
index e0b4cb2547..e3ae1b8bf5 100644
--- a/tools/xl/xl_utils.c
+++ b/tools/xl/xl_utils.c
@@ -14,8 +14,11 @@
 
 #define _GNU_SOURCE
 
+#include <fcntl.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <libxl.h>
@@ -248,6 +251,73 @@ void print_bitmap(uint8_t *map, int maplen, FILE *stream)
     }
 }
 
+int do_daemonize(char *name, const char *pidfile)
+{
+    char *fullname;
+    pid_t child1;
+    int nullfd, ret = 0;
+
+    child1 = xl_fork(child_waitdaemon, "domain monitoring daemonizing child");
+    if (child1) {
+        ret = child_report(child_waitdaemon);
+        if (ret) goto out;
+        ret = 1;
+        goto out;
+    }
+
+    postfork();
+
+    ret = libxl_create_logfile(ctx, name, &fullname);
+    if (ret) {
+        LOG("failed to open logfile %s: %s",fullname,strerror(errno));
+        exit(-1);
+    }
+
+    CHK_SYSCALL(logfile = open(fullname, O_WRONLY|O_CREAT|O_APPEND, 0644));
+    free(fullname);
+    assert(logfile >= 3);
+
+    CHK_SYSCALL(nullfd = open("/dev/null", O_RDONLY));
+    assert(nullfd >= 3);
+
+    dup2(nullfd, 0);
+    dup2(logfile, 1);
+    dup2(logfile, 2);
+
+    close(nullfd);
+
+    CHK_SYSCALL(daemon(0, 1));
+
+    if (pidfile) {
+        int fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
+        char *pid = NULL;
+
+        if (fd == -1) {
+            perror("Unable to open pidfile");
+            exit(1);
+        }
+
+        if (asprintf(&pid, "%ld\n", (long)getpid()) == -1) {
+            perror("Formatting pid");
+            exit(1);
+        }
+
+        if (write(fd, pid, strlen(pid)) < 0) {
+            perror("Writing pid");
+            exit(1);
+        }
+
+        if (close(fd) < 0) {
+            perror("Closing pidfile");
+            exit(1);
+        }
+
+        free(pid);
+    }
+
+out:
+    return ret;
+}
 
 /*
  * Local variables:
diff --git a/tools/xl/xl_utils.h b/tools/xl/xl_utils.h
index 2786f7c3cd..a159287f5e 100644
--- a/tools/xl/xl_utils.h
+++ b/tools/xl/xl_utils.h
@@ -145,6 +145,7 @@ uint32_t xfind_domain(const char *p) __attribute__((warn_unused_result));
 
 void print_bitmap(uint8_t *map, int maplen, FILE *stream);
 
+int do_daemonize(char *name, const char *pidfile);
 #endif /* XL_UTILS_H */
 
 /*
