mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.290 (3f098d9aV-utpH62PCMaflI0ggwCXQ)
Use ioctl rather than /proc/xeno/new_dom_data when creating a new domain.
This commit is contained in:
1 parent
cb43d25ee0
commit
6dd2ddc4aa
3 files changed
+115
-61
No files matched your search
+20
-25
@@ -12,6 +12,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hypervisor_defs.h"
|
||||
#include "dom0_ops.h"
|
||||
@@ -36,46 +39,36 @@ static void PERROR (char *message)
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
static dom0_newdomain_t * create_new_domain(long req_mem, char *name)
|
||||
static int create_new_domain(long req_mem, char *name)
|
||||
{
|
||||
dom0_newdomain_t * dom_data;
|
||||
char cmd_path[MAX_PATH];
|
||||
char dom_id_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
int id_fd;
|
||||
int dom_id;
|
||||
struct dom0_createdomain_args argbuf;
|
||||
|
||||
/* open the /proc command interface */
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
cmd_fd = open(cmd_path, O_RDWR);
|
||||
if(cmd_fd < 0){
|
||||
PERROR ("Could not open PROC_CMD interface");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dop.cmd = DOM0_CREATEDOMAIN;
|
||||
dop.u.newdomain.memory_kb = req_mem;
|
||||
strncpy (dop.u.newdomain.name, name, MAX_DOMAIN_NAME - 1);
|
||||
dop.u.newdomain.name[MAX_DOMAIN_NAME - 1] = 0;
|
||||
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
argbuf.kb_mem = req_mem;
|
||||
argbuf.name = name;
|
||||
dom_id = ioctl(cmd_fd, IOCTL_DOM0_CREATEDOMAIN, &argbuf);
|
||||
if (dom_id < 0) {
|
||||
PERROR("creating new domain");
|
||||
}
|
||||
close(cmd_fd);
|
||||
|
||||
sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/",
|
||||
PROC_DOM_DATA);
|
||||
while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
|
||||
dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
|
||||
read(id_fd, dom_data, sizeof(dom0_newdomain_t));
|
||||
close(id_fd);
|
||||
|
||||
return dom_data;
|
||||
return dom_id;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
dom0_newdomain_t * dom_data;
|
||||
int dom_id;
|
||||
|
||||
if (argv[0] != NULL)
|
||||
{
|
||||
@@ -88,11 +81,13 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!(dom_data = create_new_domain(atol(argv[1]), argv[2])))
|
||||
dom_id = create_new_domain(atol(argv[1]), argv[2]);
|
||||
|
||||
if(dom_id < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf (stdout, "%d\n", dom_data -> domain);
|
||||
fprintf (stdout, "%d\n", dom_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
#define MAX_CMD_LEN 256
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
|
||||
#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_NONE, 'x', 0, 0)
|
||||
|
||||
typedef struct dom0_newdomain_st
|
||||
{
|
||||
unsigned int domain; // return parameter
|
||||
@@ -112,4 +114,12 @@ typedef struct dom0_op_st
|
||||
} dom0_op_t;
|
||||
#endif
|
||||
|
||||
/* Arguments to the CREATEDOMAIN ioctl on /proc/xeno/dom0_cmd.
|
||||
Probably belongs in a Linux include file somewhere... */
|
||||
struct dom0_createdomain_args
|
||||
{
|
||||
unsigned int kb_mem;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -57,14 +57,20 @@ int direct_disc_unmap(unsigned long, unsigned long, int);
|
||||
|
||||
static unsigned char readbuf[1204];
|
||||
|
||||
static int cmd_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int dom0_cmd_read(struct file *fp, char *buf, size_t count, loff_t *off)
|
||||
{
|
||||
strcpy(page, readbuf);
|
||||
int copied, maxlen;
|
||||
if (count > 1024)
|
||||
count = 1024;
|
||||
maxlen = strlen(readbuf);
|
||||
if (count > maxlen)
|
||||
count = maxlen;
|
||||
copied = count - copy_to_user(buf, readbuf, count);
|
||||
*readbuf = '\0';
|
||||
*eof = 1;
|
||||
*start = page;
|
||||
return strlen(page);
|
||||
if (copied != count)
|
||||
return -EFAULT;
|
||||
else
|
||||
return copied;
|
||||
}
|
||||
|
||||
static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
|
||||
@@ -265,13 +271,11 @@ struct file_operations newdom_data_fops = {
|
||||
read: dom_data_read,
|
||||
};
|
||||
|
||||
static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
u_long count, void *data)
|
||||
static int dom0_cmd_write(struct file *file, const char *buffer, size_t size,
|
||||
loff_t *off)
|
||||
{
|
||||
dom0_op_t op;
|
||||
int ret = 0;
|
||||
struct proc_dir_entry * new_dom_id;
|
||||
dom0_newdomain_t * params;
|
||||
|
||||
copy_from_user(&op, buffer, sizeof(dom0_op_t));
|
||||
|
||||
@@ -285,34 +289,18 @@ static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
ret = HYPERVISOR_pt_update((void *)op.u.pgupdate.pgt_update_arr,
|
||||
op.u.pgupdate.num_pgt_updates);
|
||||
}
|
||||
else if (op.cmd == DOM0_CREATEDOMAIN)
|
||||
{
|
||||
/* This is now handled through an ioctl interface. Trying to
|
||||
do it this way means the /proc files for the new domain
|
||||
don't get created properly. */
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = HYPERVISOR_dom0_op(&op);
|
||||
|
||||
/* if new domain created, create proc entries */
|
||||
if(op.cmd == DOM0_CREATEDOMAIN) {
|
||||
create_proc_dom_entries(ret);
|
||||
|
||||
params = (dom0_newdomain_t *)kmalloc(sizeof(dom0_newdomain_t),
|
||||
GFP_KERNEL);
|
||||
params->memory_kb = op.u.newdomain.memory_kb;
|
||||
params->pg_head = op.u.newdomain.pg_head;
|
||||
params->num_vifs = op.u.newdomain.num_vifs;
|
||||
params->domain = op.u.newdomain.domain;
|
||||
|
||||
/* now notify user space of the new domain's id */
|
||||
new_dom_id = create_proc_entry("new_dom_data", 0600, xeno_base);
|
||||
if ( new_dom_id != NULL )
|
||||
{
|
||||
new_dom_id->owner = THIS_MODULE;
|
||||
new_dom_id->nlink = 1;
|
||||
new_dom_id->proc_fops = &newdom_data_fops;
|
||||
new_dom_id->data = (void *)params;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -384,7 +372,7 @@ static int xeno_domains_show(struct seq_file *s, void *v)
|
||||
di -> u.getdominfo.state,
|
||||
di -> u.getdominfo.hyp_events,
|
||||
di -> u.getdominfo.mcu_advance,
|
||||
di -> u.getdominfo.pg_head,
|
||||
(void *)di -> u.getdominfo.pg_head,
|
||||
di -> u.getdominfo.tot_pages,
|
||||
di -> u.getdominfo.name);
|
||||
|
||||
@@ -410,9 +398,70 @@ static struct file_operations proc_xeno_domains_operations = {
|
||||
release: seq_release,
|
||||
};
|
||||
|
||||
static int handle_dom0_cmd_createdomain(unsigned long data)
|
||||
{
|
||||
struct dom0_createdomain_args argbuf;
|
||||
int namelen;
|
||||
dom0_op_t op;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf))) {
|
||||
printk("fault getting argbuf.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
op.cmd = DOM0_CREATEDOMAIN;
|
||||
op.u.newdomain.domain = -666;
|
||||
op.u.newdomain.memory_kb = argbuf.kb_mem;
|
||||
op.u.newdomain.num_vifs = 0; /* Not used anymore, I hope... */
|
||||
namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
|
||||
if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1)) {
|
||||
printk("Fault getting domain name\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Error checking? The old code deosn't appear to do any, and I
|
||||
can't see where the return values are documented... */
|
||||
ret = HYPERVISOR_dom0_op(&op);
|
||||
|
||||
if (op.u.newdomain.domain == -666) {
|
||||
/* HACK: We use this to detect whether the create actually
|
||||
succeeded, because Xen doesn't appear to want to tell us... */
|
||||
|
||||
/* The only time I've actually got this to happen was when trying
|
||||
to crate a domain with more memory than is actually in the
|
||||
machine, so we guess the error code is ENOMEM. */
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Create proc entries */
|
||||
ret = op.u.newdomain.domain;
|
||||
create_proc_dom_entries(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long data)
|
||||
{
|
||||
printk("dom0_cmd ioctl command %x\n", cmd);
|
||||
switch (cmd) {
|
||||
case IOCTL_DOM0_CREATEDOMAIN:
|
||||
return handle_dom0_cmd_createdomain(data);
|
||||
default:
|
||||
printk("Unknown dom0_cmd ioctl!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
static struct file_operations dom0_cmd_file_ops = {
|
||||
read : dom0_cmd_read,
|
||||
write : dom0_cmd_write,
|
||||
ioctl : dom0_cmd_ioctl
|
||||
};
|
||||
|
||||
static int __init init_module(void)
|
||||
{
|
||||
@@ -422,12 +471,12 @@ static int __init init_module(void)
|
||||
/* xeno control interface */
|
||||
*readbuf = '\0';
|
||||
dom0_cmd_intf = create_proc_entry("dom0_cmd", 0600, xeno_base);
|
||||
|
||||
if ( dom0_cmd_intf != NULL )
|
||||
{
|
||||
dom0_cmd_intf->owner = THIS_MODULE;
|
||||
dom0_cmd_intf->nlink = 1;
|
||||
dom0_cmd_intf->read_proc = cmd_read_proc;
|
||||
dom0_cmd_intf->write_proc = cmd_write_proc;
|
||||
dom0_cmd_intf->proc_fops = &dom0_cmd_file_ops;
|
||||
}
|
||||
|
||||
/* domain list interface */
|
||||
|
||||