@@ -20,6 +20,8 @@
#include "libxl_internal.h"
#include "libxl_arch.h"
+#include <pwd.h>
+
#include <xc_dom.h>
#include <xenguest.h>
#include <xen/hvm/hvm_info_table.h>
@@ -388,6 +390,83 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
return 0;
}
+/* return 1 if the user was found, 0 if it was not, -1 on error */
+static int dm_runas_helper(libxl__gc *gc, const char *username)
+{
+ struct passwd pwd, *user = NULL;
+ char *buf = NULL;
+ long buf_size;
+ int ret;
+
+ buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (buf_size < 0) {
+ LOGE(ERROR, "sysconf(_SC_GETPW_R_SIZE_MAX) returned error %ld",
+ buf_size);
+ return ERROR_FAIL;
+ }
+
+ while (1) {
+ buf = libxl__realloc(gc, buf, buf_size);
+ ret = getpwnam_r(username, &pwd, buf, buf_size, &user);
+ if (ret == ERANGE) {
+ buf_size += 128;
+ continue;
+ }
+ if (ret != 0)
+ return ERROR_FAIL;
+ if (user != NULL)
+ return 1;
+ return 0;
+ }
+}
+
+static int domcreate_setdefault_dm_user(libxl__gc *gc,
+ libxl__domain_create_state *dcs)
+{
+ /* convenience aliases */
+ libxl_domain_config *const d_config = dcs->guest_config;
+ libxl_domain_build_info *const b_info = &d_config->b_info;
+ const uint32_t domid = dcs->guest_domid;
+
+ int rc;
+ const char *user;
+
+ if (b_info->device_model_user)
+ /* already set, good-oh */
+ return 0;
+
+ if (!(b_info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ !libxl_defbool_val(b_info->device_model_stubdomain)))
+ /* we're not going to run it anyway */
+ return 0;
+
+ user = GCSPRINTF("%s%d", LIBXL_QEMU_USER_BASE, domid);
+
+ rc = dm_runas_helper(gc, user);
+ if (rc < 0) goto error;
+ if (rc > 0) goto found;
+
+ user = LIBXL_QEMU_USER_SHARED;
+ rc = dm_runas_helper(gc, user);
+ if (rc < 0) goto error;
+ if (rc > 0) {
+ LOG(WARN, "Could not find user %s%d, falling back to %s",
+ LIBXL_QEMU_USER_BASE, domid, LIBXL_QEMU_USER_SHARED);
+ goto found;
+ }
+
+ LOG(WARN, "Could not find user %s%d or %s, starting QEMU as root",
+ LIBXL_QEMU_USER_BASE, domid, LIBXL_QEMU_USER_SHARED);
+ user = "root";
+
+ found:
+ b_info->device_model_user = libxl__strdup(NOGC, user);
+ return 0;
+
+ error:
+ return rc;
+}
+
static void init_console_info(libxl__gc *gc,
libxl__device_console *console,
int dev_num)
@@ -970,6 +1049,11 @@ static void domcreate_dm_support_checked(libxl__egc *egc,
if (rc) goto out;
+ /* config defaults which depend on dm support etc. */
+
+ rc = domcreate_setdefault_dm_user(gc, dcs);
+ if (rc) goto out;
+
dcs->bl.ao = ao;
libxl_device_disk *bootdisk =
d_config->num_disks > 0 ? &d_config->disks[0] : NULL;
@@ -21,8 +21,6 @@
#include <xc_dom.h>
#include <xen/hvm/e820.h>
-#include <sys/types.h>
-#include <pwd.h>
static const char *libxl_tapif_script(libxl__gc *gc)
{
@@ -728,36 +726,6 @@ libxl__detect_gfx_passthru_kind(libxl__gc *gc,
return LIBXL_GFX_PASSTHRU_KIND_DEFAULT;
}
-/* return 1 if the user was found, 0 if it was not, -1 on error */
-static int libxl__dm_runas_helper(libxl__gc *gc, const char *username)
-{
- struct passwd pwd, *user = NULL;
- char *buf = NULL;
- long buf_size;
- int ret;
-
- buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buf_size < 0) {
- LOGE(ERROR, "sysconf(_SC_GETPW_R_SIZE_MAX) returned error %ld",
- buf_size);
- return ERROR_FAIL;
- }
-
- while (1) {
- buf = libxl__realloc(gc, buf, buf_size);
- ret = getpwnam_r(username, &pwd, buf, buf_size, &user);
- if (ret == ERANGE) {
- buf_size += 128;
- continue;
- }
- if (ret != 0)
- return ERROR_FAIL;
- if (user != NULL)
- return 1;
- return 0;
- }
-}
-
static int libxl__build_device_model_args_new(libxl__gc *gc,
const char *dm, int guest_domid,
int emuid,
@@ -777,10 +745,9 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
const char *keymap = dm_keymap(guest_config);
char *machinearg;
flexarray_t *dm_args, *dm_envs;
- int i, connection, devid, ret;
+ int i, connection, devid;
uint64_t ram_size;
const char *path, *chardev;
- char *user = NULL;
dm_args = flexarray_make(gc, 16, 1);
dm_envs = flexarray_make(gc, 16, 1);
@@ -1263,33 +1230,8 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
break;
}
- if (b_info->device_model_user) {
- user = b_info->device_model_user;
- goto end_search;
- }
-
- user = GCSPRINTF("%s%d", LIBXL_QEMU_USER_BASE, guest_domid);
- ret = libxl__dm_runas_helper(gc, user);
- if (ret < 0)
- return ret;
- if (ret > 0)
- goto end_search;
-
- user = LIBXL_QEMU_USER_SHARED;
- ret = libxl__dm_runas_helper(gc, user);
- if (ret < 0)
- return ret;
- if (ret > 0) {
- LOG(WARN, "Could not find user %s%d, falling back to %s",
- LIBXL_QEMU_USER_BASE, guest_domid, LIBXL_QEMU_USER_SHARED);
- goto end_search;
- }
-
- user = NULL;
- LOG(WARN, "Could not find user %s, starting QEMU as root",
- LIBXL_QEMU_USER_SHARED);
+ char *const user = b_info->device_model_user;
-end_search:
if (user != NULL && strcmp(user, "root")) {
flexarray_append(dm_args, "-runas");
flexarray_append(dm_args, user);
Move the dm user defaulting from libxl__build_device_model_args_new earlier in domain create. We now do it just after the dm support check has finished. Convey the result to the dm args constructor in the b_info, ie in the supplied config. So, the application's supplied config is filled in with the chosen user, as for other defaults. Also: - slightly improve one of the warning messages - change the moved code to use `rc' (following CODING_STYLE) rather than `ret' - change the moved code to use `domid' rather than `guest_domid' like most of the rest of domain create - change the name of the (static) user selection function. Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com> CC: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- v6: New patch --- tools/libxl/libxl_create.c | 84 ++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_dm.c | 62 ++------------------------------ 2 files changed, 86 insertions(+), 60 deletions(-)