Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements #36

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 54 additions & 3 deletions src/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ dump_rules(void)
printf("default\n");
else if (rule->cmd == ALLOW)
printf("allow\n");
else if (rule->cmd == RUNNING)
printf("running\n");
else if (rule->cmd == DENY)
printf("deny\n");
printf(" pos %d\n", rule->pos);
Expand Down Expand Up @@ -255,8 +257,26 @@ vm_matches_rule(rule_t *rule, vm_t *vm)
return true;
}

static bool
rule_vm_running(rule_t *rule)
{
vm_t *vm;

/* If no VM UUID, then we never match */
if (rule->vm_uuid == NULL)
return false;

/* Lookup the VM */
vm = vm_lookup_by_uuid(rule->vm_uuid);
if (vm == NULL)
return false;

/* Is the vm running */
return vm->domid > 0;
}

static rule_t*
rule_lookup(device_t *device, enum command cmd)
_rule_lookup(device_t *device, enum command cmd, bool check_vm_running)
{
struct list_head *pos;
rule_t *rule;
Expand All @@ -265,13 +285,32 @@ rule_lookup(device_t *device, enum command cmd)
rule = list_entry(pos, rule_t, list);
if (rule->cmd == cmd &&
device_matches_rule(rule, device)) {
return rule;
if (check_vm_running) {
if (rule_vm_running(rule)) {
return rule;
}
/* continue */
} else {
return rule;
}
}
}

return NULL;
}

static rule_t *
rule_lookup(device_t *device, enum command cmd)
{
return _rule_lookup(device, cmd, false);
}

static rule_t *
rule_lookup_running(device_t *device, enum command cmd)
{
return _rule_lookup(device, cmd, true);
}

static rule_t*
sticky_lookup(device_t *device)
{
Expand All @@ -284,6 +323,12 @@ default_lookup(device_t *device)
return rule_lookup(device, DEFAULT);
}

static rule_t*
running_lookup(device_t *device)
{
return rule_lookup_running(device, RUNNING);
}

void
policy_add_rule(rule_t *new_rule)
{
Expand Down Expand Up @@ -550,6 +595,8 @@ policy_auto_assign_new_device(device_t *device)
rule = sticky_lookup(device);
if (rule == NULL)
rule = default_lookup(device);
if (rule == NULL)
rule = running_lookup(device);
if (rule != NULL) {
vm = vm_lookup_by_uuid(rule->vm_uuid);
} else {
Expand Down Expand Up @@ -603,7 +650,7 @@ policy_auto_assign_devices_to_new_vm(vm_t *vm)
* assign all devices that match the rule to the VM */
list_for_each_safe(pos, tmp, &rules.list) {
rule = list_entry(pos, rule_t, list);
if ((rule->cmd == ALWAYS || rule->cmd == DEFAULT) &&
if ((rule->cmd == ALWAYS || rule->cmd == DEFAULT || rule->cmd == RUNNING) &&
rule->vm_uuid != NULL && /* NULL vm_uuid means dom0, means no assignment */
!strcmp(rule->vm_uuid, vm->uuid)) {
list_for_each(device_pos, &devices.list) {
Expand Down Expand Up @@ -671,6 +718,7 @@ policy_parse_command_string(const char* cmd)
if (strcasecmp(cmd, "always") == 0) return ALWAYS;
if (strcasecmp(cmd, "default") == 0) return DEFAULT;
if (strcasecmp(cmd, "deny") == 0) return DENY;
if (strcasecmp(cmd, "running") == 0) return RUNNING;

return UNKNOWN;
}
Expand All @@ -690,6 +738,9 @@ policy_parse_command_enum(enum command cmd)
case DEFAULT:
strcpy(command, "default");
break;
case RUNNING:
strcpy(command, "running");
break;
default:
strcpy(command, "deny");
break;
Expand Down
1 change: 1 addition & 0 deletions src/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ enum command {
ALWAYS, /**< Always plug device to VM. implies ALLOW */
DEFAULT, /**< Plug device to VM by default, implies ALLOW */
ALLOW, /**< Allow device to be plugged to VM */
RUNNING, /**< Plug device into running VM */
DENY, /**< Deny device to be plugged to VM */
UNKNOWN /**< Unknown command, usually due to input parsing */
};
Expand Down
1 change: 1 addition & 0 deletions src/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ typedef struct {
struct list_head list; /**< Linux-kernel-style list item */
int domid; /**< VM domid */
char *uuid; /**< VM UUID */
bool emulate; /**< Use stubdom for emulated passthrough */
} vm_t;

/**
Expand Down
31 changes: 30 additions & 1 deletion src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ vm_add(const int domid, const char *uuid)
struct list_head *pos;
vm_t *vm;
char *new_uuid;
char path[64];
char *pvaddons_version = NULL;
gboolean pvaddons = true;
gboolean force_emulate = false;

/* The UUID may have "_"s instead of "-"s, like in the xenmgr dbus reply.
Fix this while duplicating the UUID. */
Expand All @@ -134,10 +138,35 @@ vm_add(const int domid, const char *uuid)
}
}

xd_log(LOG_DEBUG, "Adding vm, domid=%d, uuid=%s", domid, new_uuid);
snprintf(path, sizeof(path), "/vm/%s", new_uuid);
for (char *p = path; *p; p++) {
if (*p == '-') {
*p = '_';
}
}

if (!property_get_com_citrix_xenclient_xenmgr_vm_pv_addons_(g_xcbus, XENMGR, path, &pvaddons)) {
xd_log(LOG_ERR, "Error retrieving pvaddon status: %s %d", new_uuid, domid);
}

if (!property_get_com_citrix_xenclient_xenmgr_vm_pv_addons_version_(g_xcbus, XENMGR, path, &pvaddons_version)) {
xd_log(LOG_ERR, "Error retrieving pvaddon version: %s %d", new_uuid, domid);
pvaddons_version = NULL;
}

if (pvaddons_version && strcmp(pvaddons_version, "force-emulate") == 0) {
xd_log(LOG_INFO, "Forcing emulation: %s %d", new_uuid, domid);
force_emulate = true;
}

free(pvaddons_version);

xd_log(LOG_DEBUG, "Adding vm, domid=%d, uuid=%s pvaddons=%d force_emulate=%d",
domid, new_uuid, pvaddons, force_emulate);
vm = malloc(sizeof(vm_t));
vm->domid = domid;
vm->uuid = new_uuid;
vm->emulate = force_emulate || !pvaddons;
list_add(&vm->list, &vms.list);

return vm;
Expand Down
17 changes: 17 additions & 0 deletions src/xenstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,24 @@ xenstore_dom_read(unsigned int domid, const char *format, ...)
int
xenstore_get_dominfo(int domid, dominfo_t *di)
{
char *stubdomid;
int stubid = 0;
vm_t *vm;

di->di_domid = domid;

vm = vm_lookup(domid);
if (vm && vm->emulate) {
stubdomid = xenstore_dom_read(domid, "image/device-model-domid");
if (stubdomid) {
stubid = strtol(stubdomid, NULL, 0);
free(stubdomid);
}
if (stubid > 0 && stubid < DOMID_FIRST_RESERVED) {
di->di_domid = stubid;
}
}

di->di_dompath = xs_get_domain_path(xs_handle, di->di_domid);
if (!di->di_dompath) {
xd_log(LOG_ERR, "Could not get domain %d path from xenstore", domid);
Expand Down