[libvirt] Use posix_fallocate() to allocate disk space
by Amit Shah
These patches introduce safezero() to allocate chunks for a file and
write zeroes to them.
Not yet ready for merge; I don't understand the configure system yet
and don't know how to test for posix_fallocate() availability.
The second patch introduces a new variable, track_allocation_progress,
which perhaps belongs somewhere else.
Pointers for both these problems appreciated.
Thanks,
Amit
15 years, 8 months
[libvirt] [PATCH 2/2] [ plain text ] OpenNebula driver, libvirt-0.6.1
by "Abel Míguez Rodríguez"
> On Wed, Mar 18, 2009 at 01:52:56PM +0100, "Abel Míguez
> Rodríguez" wrote:
> Can you repost that from a normail mail client and without HTML
> formatting ... it's simply unreadable for me,
>
Of course, I repost the e-mail using plain text, but (right now) I have to use a web client.
Sorry for the inconvenience.
Thanks,
Abel
> thanks,
>
> Daniel
>
>
> --
> Daniel Veillard | libxml Gnome XML
> XSLT toolkit http://xmlsoft.org/
> daniel(a)veillard.com | Rpmfind RPM search engine
> http://rpmfind.net/http://veillard.com/ | virtualization
> library http://libvirt.org/
>
>> Hi all,
>> Here are listed the ONE driver's source code:
>> (I also attached the files to this email)
>> * one_conf.h
>> * one_conf.c
>> * one_driver.h
>> * one_driver.c
>> -----
>> Thanks,
>> Abel Míguez
source: one_conf.h
/*----------------------------------------------------------------------------------*/
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*-----------------------------------------------------------------------------------*/
#ifndef ONE_CONF_H
#define ONE_CONF_H
#include <config.h>
#include "internal.h"
#include "domain_conf.h"
#include "capabilities.h"
#include "threads.h"
struct one_driver{
virMutex lock;
virCapsPtr caps;
virDomainObjList domains;
int nextid;
};
typedef struct one_driver one_driver_t;
virCapsPtr oneCapsInit(void);
int oneSubmitVM(virConnectPtr conn ,one_driver_t* driver, virDomainObjPtr vm);
int xmlOneTemplate(virDomainDefPtr def, FILE* fd);
#define oneError(conn, dom, code, fmt...) \
virReportErrorHelper(conn, VIR_FROM_ONE, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
#endif /* ONE_CONF_H */
+++++++++++++++++++++++++++++
source: one_conf.c
/*----------------------------------------------------------------------------------*/
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*-----------------------------------------------------------------------------------*/
#include <config.h>
#include <sys/utsname.h>
#include "virterror_internal.h"
#include "one_conf.h"
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/**
* oneCapsInit initialize the driver capabilities
* @return a pointer to the driver capabilities NULL in case of error
*/
virCapsPtr oneCapsInit(void)
{
struct utsname utsname;
virCapsPtr caps;
virCapsGuestPtr guest;
uname(&utsname);
if ((caps = virCapabilitiesNew(utsname.machine,0,0)) == NULL)
{
goto no_memory;
}
virCapabilitiesSetMacPrefix(caps,(unsigned char[]){ 0x52, 0x54, 0x00 });
if ((guest = virCapabilitiesAddGuest(caps,
"hvm",
utsname.machine,
sizeof(int) == 4 ? 32 : 64,
NULL,
NULL,
0,
NULL)) == NULL)
{
goto no_memory;
}
if (virCapabilitiesAddGuestDomain(guest,
"hvm",
NULL,
NULL,
0,
NULL) == NULL)
{
goto no_memory;
}
return caps;
no_memory:
virCapabilitiesFree(caps);
return NULL;
}
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/**
* oneSubmitVM generates an OpenNebula description file and submits the new VM
* @param driver the OpenNebula driver
* @param vm the virtual machine pointer
* @return the OpenNebula ID for the new VM or -1 in case of error
*/
int oneSubmitVM(virConnectPtr conn ATTRIBUTE_UNUSED,
one_driver_t* driver,
virDomainObjPtr vm)
{
FILE* fd=NULL;
char path[256];
int oneid;
snprintf(path,256,"/tmp/one-%d",driver->nextid);
fd=fopen(path,"w");
if(fd==NULL)
{
perror("Creating a temporal description file:");
return -1;
}
if(xmlOneTemplate(vm->def,fd))
{
unlink(path);
fclose(fd);
return -1;
}
fclose(fd);
if( (oneid=c_oneAllocate(path))<0 )
{
oneError(conn, NULL, VIR_ERR_OPERATION_FAILED,
"Error submitting virtual machine to OpenNebula");
unlink(path);
return -1;
};
unlink(path);
return oneid;
};
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/**
* xmlOneTemplate Generate an OpenNebula template to deploy a VM from libvirt
* internal Domain definition.
* @param def Internal libvirt Domain definition
* @param fd ONE template file to create
* @return 0 if success
*/
int xmlOneTemplate(virDomainDefPtr def, FILE* fd)
{
char* buf;
int i;
fprintf(fd,"#OpenNebula Template automatically generated by libvirt\n");
fprintf(fd,"NAME = %s\n",def->name);
fprintf(fd,"CPU = %ld\n",(def->vcpus));
fprintf(fd,"MEMORY = %ld\n",(def->maxmem)/1024);
/*Optional Booting OpenNebula Information:*/
if( def->os.kernel )
{
fprintf(fd,"OS=[ kernel = \"%s\"",def->os.kernel);
if(def->os.initrd)
fprintf(fd,",\n initrd = \"%s\"",def->os.initrd);
if(def->os.cmdline)
fprintf(fd,",\n kernel_cmd = \"%s\"",def->os.cmdline);
if(def->os.root)
fprintf(fd,",\n root = \"%s\"",def->os.root);
fprintf(fd," ]\n");
}
/* set Disks & NICS */
for(i=0 ; i<def->ndisks ; i++)
{
if ( !def->disks[i] || !def->disks[i]->src || !def->disks[i]->src )
{
continue;
}
fprintf(fd, "DISK=[ source = \"%s\",\n"
" target = \"%s\",\n"
" readonly =",
def->disks[i]->src,
def->disks[i]->dst);
if(def->disks[i]->readonly)
fprintf(fd,"\"yes\"]\n");
else
fprintf(fd,"\"no\"]\n");
}
for(i=0 ; i< def->nnets ; i++)
{
if ( !def->nets[i] )
{
continue;
}
switch(def->nets[i]->type)
{
case VIR_DOMAIN_NET_TYPE_BRIDGE:
fprintf(fd,"NIC=[ bridge =\"%s\",\n",def->nets[i]->data.bridge.brname);
if(def->nets[i]->ifname)
{
fprintf(fd," target =\"%s\",\n",def->nets[i]->ifname);
}
fprintf(fd," mac =\"%02x:%02x:%02x:%02x:%02x:%02x\" ]\n",
def->nets[i]->mac[0],def->nets[i]->mac[1],
def->nets[i]->mac[2],def->nets[i]->mac[3],
def->nets[i]->mac[4],def->nets[i]->mac[5]);
break;
case VIR_DOMAIN_NET_TYPE_NETWORK:
fprintf(fd,"NIC=[ network=\"%s\" ]\n",def->nets[i]->data.network.name);
break;
}
}
return 0;
};
+++++++++++++++++++++++++++++
source: one_driver.h
/*---------------------------------------------------------------------------*/
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*---------------------------------------------------------------------------*/
#ifndef ONE_DRIVER_H
#define ONE_DRIVER_H
#include <config.h>
int oneRegister(void);
#endif /* ONE_DRIVER_H */
+++++++++++++++++++++++++++++
source: one_driver.c
/*---------------------------------------------------------------------------*/
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
* Complutense de Madrid (dsa-research.org)
*
* This library 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*---------------------------------------------------------------------------*/
#include <config.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/utsname.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/poll.h>
#include <unistd.h>
#include <wait.h>
#include <sys/time.h>
#include "virterror_internal.h"
#include "logging.h"
#include "datatypes.h"
#include "one_conf.h"
#include "one_driver.h"
#include "memory.h"
#include "util.h"
#include "bridge.h"
#include "veth.h"
#include "event.h"
#include "cgroup.h"
static int oneStart(void);
static int oneShutdown(void);
static int oneActive(void);
static void oneDriverLock(one_driver_t* driver)
{
virMutexLock(&driver->lock);
}
static void oneDriverUnlock(one_driver_t* driver)
{
virMutexUnlock(&driver->lock);
}
static one_driver_t *one_driver =NULL;
static virDrvOpenStatus oneOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED)
{
/* Verify uri was specified */
if (conn->uri == NULL) {
conn->uri = xmlParseURI("one:///");
if (!conn->uri) {
oneError(conn, NULL, VIR_ERR_NO_MEMORY, NULL);
return VIR_DRV_OPEN_ERROR;
}
} else if (conn->uri->scheme == NULL ||
STRNEQ(conn->uri->scheme, "one")) {
goto declineConnection;
}
conn->privateData = one_driver;
return VIR_DRV_OPEN_SUCCESS;
declineConnection:
return VIR_DRV_OPEN_DECLINED;
}
static int oneClose(virConnectPtr conn)
{
conn->privateData = NULL;
return 0;
}
static virDomainPtr oneDomainLookupByID(virConnectPtr conn,
int id)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainPtr dom = NULL;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm = virDomainFindByID(&driver->domains, id);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static virDomainPtr oneDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainPtr dom = NULL;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static virDomainPtr oneDomainLookupByName(virConnectPtr conn,
const char *name)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainObjPtr vm = NULL;
virDomainPtr dom=NULL;
oneDriverLock(driver);
vm = virDomainFindByName(&driver->domains, name);
oneDriverUnlock(driver);
if (!vm) {
oneError(conn, NULL, VIR_ERR_NO_DOMAIN, NULL);
goto return_point;
}
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm) {
virDomainObjUnlock(vm);
}
return dom;
}
static int oneListDomains(virConnectPtr conn, int *ids, int nids)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nids ; i++){
if (virDomainIsActive(driver->domains.objs[i]))
ids[got++] = driver->domains.objs[i]->def->id;
}
oneDriverUnlock(driver);
return got;
}
static int oneNumDomains(virConnectPtr conn)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++)
if (virDomainIsActive(driver->domains.objs[i]))
n++;
oneDriverUnlock(driver);
return n;
}
static int oneListDefinedDomains(virConnectPtr conn,
char **const names, int nnames) {
one_driver_t *driver = (one_driver_t *)conn->privateData;
int got = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count && got < nnames ; i++) {
if (!virDomainIsActive(driver->domains.objs[i])) {
if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
oneError(conn, NULL, VIR_ERR_NO_MEMORY,
"%s", _("failed to allocate space for VM name string"));
goto cleanup;
}
}
}
oneDriverUnlock(driver);
return got;
cleanup:
for (i = 0 ; i < got ; i++)
VIR_FREE(names[i]);
oneDriverUnlock(driver);
return -1;
}
static int oneNumDefinedDomains(virConnectPtr conn)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
int n = 0, i;
oneDriverLock(driver);
for (i = 0 ; i < driver->domains.count ; i++)
if (!virDomainIsActive(driver->domains.objs[i]))
n++;
oneDriverUnlock(driver);
return n;
}
static virDomainPtr oneDomainDefine(virConnectPtr conn, const char *xml)
{
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainDefPtr def;
virDomainObjPtr vm;
virDomainPtr dom=NULL;
oneDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
VIR_DOMAIN_XML_INACTIVE)))
goto return_point;
if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
virDomainDefFree(def);
goto return_point;
}
vm->def->id = -1;
vm->persistent = 1;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
virDomainObjUnlock(vm);
return_point:
oneDriverUnlock(driver);
return dom;
}
static int oneDomainUndefine(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
virDomainObjPtr vm = NULL;
int ret=-1;
oneDriverLock(driver);
vm =virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
oneError(dom->conn, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
goto return_point;
}
if (!vm->persistent) {
oneError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot undefine transient domain"));
goto return_point;
}
virDomainRemoveInactive(&driver->domains, vm);
ret=0;
return_point:
oneDriverUnlock(driver);
return ret;
}
static int oneDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
struct timeval tv;
virDomainObjPtr vm;
oneDriverLock(driver);
vm= virDomainFindByUUID(&driver->domains, dom->uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(dom->conn,NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return -1;
}
if(gettimeofday(&tv,NULL)<0) {
oneError(dom->conn,NULL, VIR_ERR_INTERNAL_ERROR,
"%s",_("getting time of day"));
virDomainObjUnlock(vm);
return -1;
}
if (!virDomainIsActive(vm)) {
info->cpuTime = 0;
} else {
char vm_info[257];
c_oneVmInfo(vm->pid,vm_info,256);
//State:
char* cptr = strstr(vm_info,"STATE");
cptr = index(cptr, ':');
cptr++;
int one_state=atoi(cptr);
switch(one_state) {
case 3: /** running */
if (vm->state!=VIR_DOMAIN_SHUTDOWN)
vm->state=VIR_DOMAIN_RUNNING;
break;
case 5: /** pause */
vm->state=VIR_DOMAIN_PAUSED;
break;
case 6: /** done */
vm->state=VIR_DOMAIN_SHUTOFF;
vm->def->id=-1;
break;
case 7: /** error */
vm->state=VIR_DOMAIN_CRASHED;
break;
default:
break;
};
//Memory:
cptr=strstr(vm_info,"MEMORY");
cptr=index(cptr,':');
cptr++;
vm->def->memory = atoi(cptr);
//run time:
cptr=strstr(vm_info,"START TIME");
cptr=index(cptr,':');
cptr++;
long starttime = atol(cptr);
info->cpuTime = (tv.tv_sec - starttime) *1000ll *1000ll *1000ll;
}
info->state = vm->state;
info->maxMem = vm->def->maxmem;
info->memory = vm->def->memory;
info->nrVirtCpu = vm->def->vcpus;
virDomainObjUnlock(vm);
return 0;
}
static char *oneGetOSType(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t *)dom->conn->privateData;
virDomainObjPtr vm = NULL;
oneDriverLock(driver);
vm =virDomainFindByUUID(&driver->domains, dom->uuid);
oneDriverUnlock(driver);
if (!vm) {
oneError(dom->conn, NULL, VIR_ERR_INVALID_DOMAIN,
"%s", _("no domain with matching uuid"));
return NULL;
}
virDomainObjUnlock(vm);
return strdup(vm->def->os.type);
}
static int oneDomainStart(virDomainPtr dom)
{
virConnectPtr conn = dom->conn;
one_driver_t *driver = (one_driver_t *)(conn->privateData);
virDomainObjPtr vm;
int ret = -1;
int oneid;
int rc;
char* logfile=NULL;
oneDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dom->name);
if (!vm) {
oneError(conn, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain named %s"), dom->name);
goto return_point;
}
if((oneid = oneSubmitVM(dom->conn,driver,vm)) < 0) {
goto return_point;
}
vm->pid=oneid;
vm->def->id=driver->nextid++;
vm->state=VIR_DOMAIN_BLOCKED;
ret=0;
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static virDomainPtr
oneDomainCreateAndStart(virConnectPtr conn,
const char *xml,
unsigned int flags ATTRIBUTE_UNUSED) {
one_driver_t *driver = (one_driver_t *)conn->privateData;
virDomainObjPtr vm;
virDomainDefPtr def;
virDomainPtr dom = NULL;
int oneid;
oneDriverLock(driver);
if (!(def = virDomainDefParseString(conn, driver->caps, xml,
VIR_DOMAIN_XML_INACTIVE)))
goto return_point;
vm = virDomainFindByName(&driver->domains, def->name);
if (vm) {
oneError(conn,NULL, VIR_ERR_OPERATION_FAILED,
_("Already an OpenNebula VM active with the name: \"%s\" id: %d "),
def->name,def->id);
goto return_point;
}
if (!(vm = virDomainAssignDef(conn, &driver->domains, def))) {
virDomainDefFree(def);
goto return_point;
}
if ((oneid = oneSubmitVM(conn, driver, vm)) < 0) {
virDomainRemoveInactive(&driver->domains, vm);
vm=NULL;
goto return_point;
}
vm->def->id=driver->nextid++;
vm->persistent=0;
vm->pid=oneid;
vm->state=VIR_DOMAIN_BLOCKED;
dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
if (dom) {
dom->id = vm->def->id;
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return dom;
}
static int oneDomainShutdown(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t*)dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if((vm=virDomainFindByID(&driver->domains, dom->id))) {
if(!(c_oneShutdown(vm->pid) ) ) {
vm->state=VIR_DOMAIN_SHUTDOWN;
ret= 0;
if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains, vm);
vm = NULL;
}
goto return_point;
}
oneError(dom->conn, NULL, VIR_ERR_OPERATION_FAILED,
"Domain Shutdown",NULL);
goto return_point;
}
oneError(dom->conn,NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with id %d"), dom->id);
goto return_point;
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static int oneDomainDestroy(virDomainPtr dom)
{
one_driver_t *driver = (one_driver_t*)dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
vm= virDomainFindByID(&driver->domains, dom->id);
if (!vm) {
oneError(dom->conn, NULL, VIR_ERR_INVALID_DOMAIN,
_("no domain with id %d"), dom->id);
goto return_point;
}
if(c_oneShutdown(vm->pid)) {
oneError(dom->conn, NULL, VIR_ERR_OPERATION_FAILED,
"Domain Shutdown",NULL);
goto return_point;
}
if(!vm->persistent) {
virDomainRemoveInactive(&driver->domains,vm);
vm=NULL;
}
ret=0;
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
}
static int oneDomainSuspend(virDomainPtr dom)
{
one_driver_t* driver=dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if ((vm=virDomainFindByID(&driver->domains,dom->id))){
if (vm->state == VIR_DOMAIN_RUNNING) {
if( !(c_oneSuspend(vm->pid)) ) {
vm->state=VIR_DOMAIN_PAUSED;
ret=0;
goto return_point;
}
oneError(dom->conn, NULL, VIR_ERR_OPERATION_FAILED,
"%s", "failed to pause domain");
goto return_point;
}
oneError(dom->conn,NULL,VIR_ERR_OPERATION_FAILED,
"%s", "domain is not running");
} else {
oneError(dom->conn, NULL, VIR_ERR_INVALID_DOMAIN,
"no domain with matching id %d", dom->id);
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
};
static int oneDomainResume(virDomainPtr dom)
{
one_driver_t* driver=dom->conn->privateData;
virDomainObjPtr vm;
int ret=-1;
oneDriverLock(driver);
if ((vm=virDomainFindByID(&driver->domains,dom->id))) {
if (vm->state == VIR_DOMAIN_PAUSED) {
if( !(c_oneResume(vm->pid)) ) {
vm->state=VIR_DOMAIN_RUNNING;
ret=0;
goto return_point;
}
oneError(dom->conn, NULL, VIR_ERR_OPERATION_FAILED,
"%s", "failed to resume ");
goto return_point;
}
oneError(dom->conn,NULL,VIR_ERR_OPERATION_FAILED,
"%s", " domain is not paused ");
} else {
oneError(dom->conn, NULL, VIR_ERR_INVALID_DOMAIN,
"no domain with matching id %d", dom->id);
}
return_point:
if(vm)
virDomainObjUnlock(vm);
oneDriverUnlock(driver);
return ret;
};
static int oneStartup(void){
int i;
if (VIR_ALLOC(one_driver) < 0) {
return -1;
}
if(virMutexInit(&one_driver->lock)<0){
VIR_FREE(one_driver);
return -1;
}
c_oneStart();
oneDriverLock(one_driver);
one_driver->nextid=1;
if ((one_driver->caps = oneCapsInit()) == NULL) {
oneDriverUnlock(one_driver);
VIR_FREE(one_driver);
return -1;
}
oneDriverUnlock(one_driver);
return 0;
}
static int oneShutdown(void){
if (one_driver == NULL)
return(-1);
oneDriverLock(one_driver);
virDomainObjListFree(&one_driver->domains);
virCapabilitiesFree(one_driver->caps);
oneDriverUnlock(one_driver);
virMutexDestroy(&one_driver->lock);
VIR_FREE(one_driver);
one_driver = NULL;
c_oneFree();
return 0;
}
static int oneActive(void){
unsigned int i;
int active = 0;
if (one_driver == NULL)
return(0);
oneDriverLock(one_driver);
for (i = 0 ; i < one_driver->domains.count ; i++) {
virDomainObjLock(one_driver->domains.objs[i]);
if (virDomainIsActive(one_driver->domains.objs[i]))
active = 1;
virDomainObjUnlock(one_driver->domains.objs[i]);
}
oneDriverUnlock(one_driver);
return active;
}
static int oneVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *hvVer)
{
*hvVer = 1;
return 0;
}
static int oneGetAutostart(virConnectPtr conn ATTRIBUTE_UNUSED)
{
return 0;
}
/* Function Tables */
static virDriver oneDriver = {
VIR_DRV_ONE, /* the number virDrvNo */
"ONE", /* the name of the driver */
oneOpen, /* open */
oneClose, /* close */
NULL, /* supports_feature */
NULL, /* type */
oneVersion, /* version */
NULL, /* getHostname */
NULL, /* getURI */
NULL, /* getMaxVcpus */
NULL, /* nodeGetInfo */
NULL, /* getCapabilities */
oneListDomains, /* listDomains */
oneNumDomains, /* numOfDomains */
oneDomainCreateAndStart, /* domainCreateXML */
oneDomainLookupByID, /* domainLookupByID */
oneDomainLookupByUUID, /* domainLookupByUUID */
oneDomainLookupByName, /* domainLookupByName */
oneDomainSuspend, /* domainSuspend */
oneDomainResume, /* domainResume */
oneDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
oneDomainDestroy, /* domainDestroy */
oneGetOSType, /* domainGetOSType */
NULL, /* domainGetMaxMemory */
NULL, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
oneDomainGetInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
NULL, /* domainDumpXML */
oneListDefinedDomains, /* listDefinedDomains */
oneNumDefinedDomains, /* numOfDefinedDomains */
oneDomainStart, /* domainCreate */
oneDomainDefine, /* domainDefineXML */
oneDomainUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
oneGetAutostart, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
NULL, /* domainMigratePrepare */
NULL, /* domainMigratePerform */
NULL, /* domainMigrateFinish */
NULL, /* domainBlockStats */
NULL, /* domainInterfaceStats */
NULL, /* domainBlockPeek */
NULL, /* domainMemoryPeek */
NULL, /* nodeGetCellsFreeMemory */
NULL, /* getFreeMemory */
NULL, /* domainEventRegister */
NULL, /* domainEventDeregister */
NULL, /* domainMigratePrepare2 */
NULL, /* domainMigrateFinish2 */
};
static virStateDriver oneStateDriver = {
.initialize = oneStartup,
.cleanup = oneShutdown,
.active = oneActive,
};
int oneRegister(void)
{
virRegisterDriver(&oneDriver);
virRegisterStateDriver(&oneStateDriver);
return 0;
}
----
Distributed System Architecture Group
(http://dsa-research.org)
GridWay, http://www.gridway.org
OpenNEbula, http://www.opennebula.org
15 years, 8 months
[libvirt] get domU hostname
by jim_marshall@msn.com
Hello,
Sorry if this has been asked before, I did some searches and came up empty. I am writing a tool to get data on Xen using libvirt everything is going great, however; I have a need to get the hostname of domU from the program running in dom0. Is this possible using libvirt?
Thanks
Jim
15 years, 8 months
[libvirt] java libvirt question
by Zvi Dubitzky
Hi
1)
I downloaded the libvirt-java-0.2.1 tar and try to build Java binding
to the libvirt library (configure , make , make install).
This is because I am running Ubuntu and presumably cannot use the fedora
.rpm
For either java-gcj (java version 1.5) or the java-6-openjdk (version
1.6) I do not get the java-dev having its bin components (java, javac,
javah, javadoc) under the same directory as the configure script wants (
gcj case : /usr/lib/jvm/java-1.5.0-gcj-../bin , openjdk case:
/usr/lib/jvm/java-6-openjdk/bin)
and the configure fails
Of course I am doing : ./configure
--with-java-home=/usr/lib/jvm/java-6-openjdk or similar for version 1.5
Any advice how to solve this problem ? in fact I do not find javac and
javah, javadoc after the install only the java, jar
2) the Java libvirt library from the downloads link is dated mid 2008 .
Does that have influence on bug fixing since then or this java libvirt
package is just for the client side and the server side is the most
updated C code so the date does not matter ?
thanks
Zvi Dubitzky
Virtualization and System Architecture Email:dubi@il.ibm.com
IBM Haifa Research Laboratory Phone: +972-4-8296182
Haifa, 31905, ISRAEL
15 years, 8 months
Re: [libvirt] [PATCH] Adding filesystem mount support for openVZ
by Anton Protopopov
2009/3/12 Daniel P. Berrange <berrange(a)redhat.com>
>
>> On Wed, Mar 11, 2009 at 05:42:20PM +0100, Florian Vichot wrote:
>> > Hi everyone,
>> >
>> > This patch is to allow using the "mount" type in the "filesystem" tag
>> > for OpenVZ domains.
>> >
>> > Example:
>> > ...
>> > <filesystem type='mount'>
>> > <source dir='/path/to/filesystem/directory/' />
>> > <target dir='/path/to/pivot/root/' />
>> > </filesystem>
>> > ...
>> >
>> > This is my first patch to an external project, so don't spare me if I
>> > got things wrong :)
>> >
>> > Also, I'm curious for suggestions as to how I could allow for the target
>> > not to be specified in the XML. Because in this case OpenVZ just makes a
>> > temporary pivot root in "/var/lib/vz/root/" and that is probably
>> > sufficient for most people, who might not want to have to explicitly
>> > create a pivot root somewhere, just for mounting the filesystem while
>> > it's running.
>>
>> Actually the <target dir="..."> means something a little different. This
>> refers to the mount point *within* the container. So for the root
>> filesystem
>> of the container it will be <target dir='/' />
>
> No, that patch does something different---it assumes that both <source dir>
> and <target dir>
> are paths within hardware node. If we denote <source dir> and <target dir>
> by the VE_PRIVATE
> and VE_ROOT correspondingly, we get the following picture.
>
> In OpenVZ there are VE_ROOT and VE_PRIVATE values for each container
> (they defined as VE_ROOT and VE_PRIVATE variables in container
> configuration file).
> The VE_PRIVATE defines the actual disposition of conatainer's
> root filesystem hierarchy. It can lie on it's own partition or be just a
> directory.
> When vzctl starts a container, it mounts a VE_PRIVATE "filesystem" to
> VE_ROOT
> mountpoint and then container starts to work in VE_ROOT chroot...
>
> So, yes, you are right - in this case we can always assume, that "target
> dir within container" is "/" :)
>
>
15 years, 8 months
[libvirt] Re: rawhide report: 20090318 changes
by Tomasz Torcz
On Wed, Mar 18, 2009 at 11:04:12AM +0000, Rawhide Report wrote:
> libvirt-0.6.1-5.fc11
> - Disable sound cards when running sVirt
May I ask what's the reason for this change?
--
Tomasz Torcz To co nierealne -- tutaj jest normalne.
xmpp: zdzichubg(a)chrome.pl Ziomale na życie mają tu patenty specjalne.
15 years, 8 months
[libvirt] I have no idea why the current version of libvirt works for anyone in enforcing mode.
by Daniel J Walsh
Libvirt is executing qemu requiring it to execute pulseaudio which would
require the folowing permissions,
#============= svirt_t ==============
allow svirt_t admin_home_t:dir setattr;
allow svirt_t admin_home_t:file { read write };
allow svirt_t pulseaudio_port_t:tcp_socket name_connect;
allow svirt_t svirt_tmpfs_t:file read;
allow svirt_t user_tmpfs_t:file read;
Since qemu(svirt_t) is not allowed these permissions, pulseaudio crashes
and qemu dies.
I believe you need to run without sound if you are running as root.
15 years, 8 months
[libvirt] PATCH: PCI device passthrough in Xen driver
by Daniel P. Berrange
This patch provides initial support for PCI device passthrough in
Xen, at time of boot. It does not (yet) implement device hotplug
for PCI, since it works in an annoyingly different way to device
hotplug of disks & nics. The patch has several aspects
- Refactors the pci.c file to make it easier to support both
Xen's pci-back.ko and upstream's pcistub.ko, which are almost
identical
- Add code to pci.c register the PCI device with 'new_slot' before
invoking 'bind', since pci-back.ko wants this extra step
- In xen_unified.c, add implmentations of APIs to dettach, reattach
and reset PCI devices - this just calls into shared pci.c code that
QEMU/KVM uses.
- In xend_internal.c implement SEXPR conversion.
- In xm_internal.c implement parsing of 'pci' config parameter
- Add lots of test cases
XenD only supports 'unmanaged' PCI devices - ie mgmt app is responsible
for detaching/reattaching PCI devices from/to host device drivers.
XenD itself won't automatically do this for us, though perhaps someone
might like to implement this as an optional feature for XenD, since it
is more convenient in some cases.
src/pci.c | 182 +++++++++++++--------
src/xen_unified.c | 122 ++++++++++++++
src/xend_internal.c | 232 +++++++++++++++++++++++++++
src/xm_internal.c | 156 ++++++++++++++++++
tests/sexpr2xmldata/sexpr2xml-pci-devs.sexpr | 2
tests/sexpr2xmldata/sexpr2xml-pci-devs.xml | 37 ++++
tests/sexpr2xmltest.c | 1
tests/xmconfigdata/test-pci-devs.cfg | 24 ++
tests/xmconfigdata/test-pci-devs.xml | 56 ++++++
tests/xmconfigtest.c | 1
tests/xml2sexprdata/xml2sexpr-pci-devs.sexpr | 1
tests/xml2sexprdata/xml2sexpr-pci-devs.xml | 33 +++
tests/xml2sexprtest.c | 1
13 files changed, 784 insertions(+), 64 deletions(-)
Daniel
Index: src/pci.c
===================================================================
RCS file: /data/cvs/libvirt/src/pci.c,v
retrieving revision 1.4
diff -u -p -r1.4 pci.c
--- src/pci.c 3 Mar 2009 17:00:18 -0000 1.4
+++ src/pci.c 16 Mar 2009 11:31:29 -0000
@@ -614,46 +614,80 @@ pciResetDevice(virConnectPtr conn, pciDe
return ret;
}
-static int
-pciBindDeviceToStub(virConnectPtr conn, pciDevice *dev, const char *stub_module)
+
+static void
+pciDriverDir(char *buf, size_t buflen, const char *driver)
{
- char stub_dir[PATH_MAX];
- char path[PATH_MAX];
+ snprintf(buf, buflen, PCI_SYSFS "drivers/%s", driver);
+}
- snprintf(stub_dir, sizeof(stub_dir), PCI_SYSFS "drivers/%s", stub_module);
+static void
+pciDriverFile(char *buf, size_t buflen, const char *driver, const char *file)
+{
+ snprintf(buf, buflen, PCI_SYSFS "drivers/%s/%s", driver, file);
+}
- /* Try loading the stub module if it isn't already loaded;
- * Do not return an error if the stub module is not available.
- */
- if (!virFileExists(stub_dir)) {
- const char *const modprobeargv[] = { MODPROBE, stub_module, NULL };
+static void
+pciDeviceFile(char *buf, size_t buflen, const char *device, const char *file)
+{
+ snprintf(buf, buflen, PCI_SYSFS "devices/%s/%s", device, file);
+}
+
+
+static const char *
+pciFindStubDriver(virConnectPtr conn)
+{
+ char drvpath[PATH_MAX];
+ int probed = 0;
- if (virRun(conn, modprobeargv, NULL) < 0) {
+recheck:
+ pciDriverDir(drvpath, sizeof(drvpath), "pci-stub");
+ if (virFileExists(drvpath))
+ return "pci-stub";
+ pciDriverDir(drvpath, sizeof(drvpath), "pciback");
+ if (virFileExists(drvpath))
+ return "pciback";
+
+ if (!probed) {
+ const char *const stubprobe[] = { MODPROBE, "pci-stub", NULL };
+ const char *const backprobe[] = { MODPROBE, "pciback", NULL };
+
+ probed = 1;
+ if (virRun(conn, stubprobe, NULL) < 0 &&
+ virRun(conn, backprobe, NULL) < 0) {
char ebuf[1024];
- VIR_WARN(_("modprobe %s failed: %s"), stub_module,
+ VIR_WARN(_("failed to load pci-stub or pciback drivers: %s"),
virStrerror(errno, ebuf, sizeof ebuf));
+ return 0;
}
+
+ goto recheck;
}
- if (!virFileExists(stub_dir)) {
- VIR_WARN(_("%s module not available, cannot bind device %s to it"),
- stub_module, dev->name);
- } else {
- /* Add the PCI device ID to the stub's dynamic ID table;
- * this is needed to allow us to bind the device to the stub.
- * Note: if the device is not currently bound to any driver,
- * stub will immediately be bound to the device. Also, note
- * that if a new device with this ID is hotplugged, or if a probe
- * is triggered for such a device, it will also be immediately
- * bound by the stub.
- */
- snprintf(path, sizeof(path), "%s/new_id", stub_dir);
- if (virFileWriteStr(path, dev->id) < 0) {
- virReportSystemError(conn, errno,
- _("Failed to add PCI device ID '%s' to %s"),
- dev->id, stub_module);
- return -1;
- }
+ return NULL;
+}
+
+
+static int
+pciBindDeviceToStub(virConnectPtr conn, pciDevice *dev, const char *driver)
+{
+ char drvdir[PATH_MAX];
+ char path[PATH_MAX];
+
+ /* Add the PCI device ID to the stub's dynamic ID table;
+ * this is needed to allow us to bind the device to the stub.
+ * Note: if the device is not currently bound to any driver,
+ * stub will immediately be bound to the device. Also, note
+ * that if a new device with this ID is hotplugged, or if a probe
+ * is triggered for such a device, it will also be immediately
+ * bound by the stub.
+ */
+ pciDriverFile(path, sizeof(path), driver, "new_id");
+ if (virFileWriteStr(path, dev->id) < 0) {
+ virReportSystemError(conn, errno,
+ _("Failed to add PCI device ID '%s' to %s"),
+ dev->id, driver);
+ return -1;
}
/* If the device is already bound to a driver, unbind it.
@@ -661,66 +695,79 @@ pciBindDeviceToStub(virConnectPtr conn,
* PCI device happens to be IDE controller for the disk hosting
* your root filesystem.
*/
- snprintf(path, sizeof(path),
- PCI_SYSFS "devices/%s/driver/unbind", dev->name);
+ pciDeviceFile(path, sizeof(path), dev->name, "driver/unbind");
if (virFileExists(path) && virFileWriteStr(path, dev->name) < 0) {
virReportSystemError(conn, errno,
_("Failed to unbind PCI device '%s'"), dev->name);
return -1;
}
- if (virFileExists(stub_dir)) {
- /* If the device isn't already bound to pci-stub, try binding it now.
- */
- snprintf(path, sizeof(path), PCI_SYSFS "devices/%s/driver", dev->name);
- if (!virFileLinkPointsTo(path, stub_dir)) {
- snprintf(path, sizeof(path), "%s/bind", stub_dir);
- if (virFileWriteStr(path, dev->name) < 0) {
- virReportSystemError(conn, errno,
- _("Failed to bind PCI device '%s' to %s"),
- dev->name, stub_module);
- return -1;
- }
+ /* If the device isn't already bound to pci-stub, try binding it now.
+ */
+ pciDriverDir(drvdir, sizeof(drvdir), driver);
+ pciDeviceFile(path, sizeof(path), dev->name, "driver");
+ if (!virFileLinkPointsTo(path, drvdir)) {
+ /* Xen's pciback.ko wants you to use new_slot first */
+ pciDriverFile(path, sizeof(path), driver, "new_slot");
+ if (virFileExists(path) && virFileWriteStr(path, dev->name) < 0) {
+ virReportSystemError(conn, errno,
+ _("Failed to add slot for PCI device '%s' to %s"),
+ dev->name, driver);
+ return -1;
}
- /* If 'remove_id' exists, remove the device id from pci-stub's dynamic
- * ID table so that 'drivers_probe' works below.
- */
- snprintf(path, sizeof(path), "%s/remove_id", stub_dir);
- if (virFileExists(path) && virFileWriteStr(path, dev->id) < 0) {
+ pciDriverFile(path, sizeof(path), driver, "bind");
+ if (virFileWriteStr(path, dev->name) < 0) {
virReportSystemError(conn, errno,
- _("Failed to remove PCI ID '%s' from %s"),
- dev->id, stub_module);
+ _("Failed to bind PCI device '%s' to %s"),
+ dev->name, driver);
return -1;
}
}
+ /* If 'remove_id' exists, remove the device id from pci-stub's dynamic
+ * ID table so that 'drivers_probe' works below.
+ */
+ pciDriverFile(path, sizeof(path), driver, "remove_id");
+ if (virFileExists(path) && virFileWriteStr(path, dev->id) < 0) {
+ virReportSystemError(conn, errno,
+ _("Failed to remove PCI ID '%s' from %s"),
+ dev->id, driver);
+ return -1;
+ }
+
return 0;
}
int
pciDettachDevice(virConnectPtr conn, pciDevice *dev)
{
- return pciBindDeviceToStub(conn, dev, "pci-stub");
+ const char *driver = pciFindStubDriver(conn);
+ if (!driver) {
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot find any PCI stub module"));
+ return -1;
+ }
+
+ return pciBindDeviceToStub(conn, dev, driver);
}
static int
-pciUnBindDeviceFromStub(virConnectPtr conn, pciDevice *dev, const char *stub_module)
+pciUnBindDeviceFromStub(virConnectPtr conn, pciDevice *dev, const char *driver)
{
- char stub_dir[PATH_MAX];
+ char drvdir[PATH_MAX];
char path[PATH_MAX];
- snprintf(stub_dir, sizeof(stub_dir), PCI_SYSFS "drivers/%s", stub_module);
-
/* If the device is bound to stub, unbind it.
*/
- snprintf(path, sizeof(path), PCI_SYSFS "devices/%s/driver", dev->name);
- if (virFileExists(stub_dir) && virFileLinkPointsTo(path, stub_dir)) {
- snprintf(path, sizeof(path), "%s/unbind", stub_dir);
+ pciDriverDir(drvdir, sizeof(drvdir), driver);
+ pciDeviceFile(path, sizeof(path), dev->name, "driver");
+ if (virFileExists(drvdir) && virFileLinkPointsTo(path, drvdir)) {
+ pciDriverFile(path, sizeof(path), driver, "unbind");
if (virFileWriteStr(path, dev->name) < 0) {
virReportSystemError(conn, errno,
_("Failed to bind PCI device '%s' to %s"),
- dev->name, stub_module);
+ dev->name, driver);
return -1;
}
}
@@ -730,8 +777,8 @@ pciUnBindDeviceFromStub(virConnectPtr co
* available, then re-probing would just cause the device to be
* re-bound to the stub.
*/
- snprintf(path, sizeof(path), "%s/remove_id", stub_dir);
- if (!virFileExists(stub_dir) || virFileExists(path)) {
+ pciDriverFile(path, sizeof(path), driver, "remove_id");
+ if (!virFileExists(drvdir) || virFileExists(path)) {
if (virFileWriteStr(PCI_SYSFS "drivers_probe", dev->name) < 0) {
virReportSystemError(conn, errno,
_("Failed to trigger a re-probe for PCI device '%s'"),
@@ -746,7 +793,14 @@ pciUnBindDeviceFromStub(virConnectPtr co
int
pciReAttachDevice(virConnectPtr conn, pciDevice *dev)
{
- return pciUnBindDeviceFromStub(conn, dev, "pci-stub");
+ const char *driver = pciFindStubDriver(conn);
+ if (!driver) {
+ pciReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot find any PCI stub module"));
+ return -1;
+ }
+
+ return pciUnBindDeviceFromStub(conn, dev, driver);
}
static char *
Index: src/xen_unified.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.c,v
retrieving revision 1.83
diff -u -p -r1.83 xen_unified.c
--- src/xen_unified.c 5 Feb 2009 16:03:11 -0000 1.83
+++ src/xen_unified.c 16 Mar 2009 11:31:29 -0000
@@ -43,6 +43,8 @@
#include "xml.h"
#include "util.h"
#include "memory.h"
+#include "node_device_conf.h"
+#include "pci.h"
#define VIR_FROM_THIS VIR_FROM_XEN
@@ -1420,6 +1422,123 @@ xenUnifiedDomainEventDeregister (virConn
return ret;
}
+
+static int
+xenUnifiedNodeDeviceGetPciInfo (virNodeDevicePtr dev,
+ unsigned *domain,
+ unsigned *bus,
+ unsigned *slot,
+ unsigned *function)
+{
+ virNodeDeviceDefPtr def = NULL;
+ virNodeDevCapsDefPtr cap;
+ char *xml = NULL;
+ int ret = -1;
+
+ xml = virNodeDeviceGetXMLDesc(dev, 0);
+ if (!xml)
+ goto out;
+
+ def = virNodeDeviceDefParseString(dev->conn, xml);
+ if (!def)
+ goto out;
+
+ cap = def->caps;
+ while (cap) {
+ if (cap->type == VIR_NODE_DEV_CAP_PCI_DEV) {
+ *domain = cap->data.pci_dev.domain;
+ *bus = cap->data.pci_dev.bus;
+ *slot = cap->data.pci_dev.slot;
+ *function = cap->data.pci_dev.function;
+ break;
+ }
+
+ cap = cap->next;
+ }
+
+ if (!cap) {
+ xenUnifiedError(dev->conn, VIR_ERR_INVALID_ARG,
+ _("device %s is not a PCI device"), dev->name);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ virNodeDeviceDefFree(def);
+ VIR_FREE(xml);
+ return ret;
+}
+
+static int
+xenUnifiedNodeDeviceDettach (virNodeDevicePtr dev)
+{
+ pciDevice *pci;
+ unsigned domain, bus, slot, function;
+ int ret = -1;
+
+ if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
+ return -1;
+
+ pci = pciGetDevice(dev->conn, domain, bus, slot, function);
+ if (!pci)
+ return -1;
+
+ if (pciDettachDevice(dev->conn, pci) < 0)
+ goto out;
+
+ ret = 0;
+out:
+ pciFreeDevice(dev->conn, pci);
+ return ret;
+}
+
+static int
+xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
+{
+ pciDevice *pci;
+ unsigned domain, bus, slot, function;
+ int ret = -1;
+
+ if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
+ return -1;
+
+ pci = pciGetDevice(dev->conn, domain, bus, slot, function);
+ if (!pci)
+ return -1;
+
+ if (pciReAttachDevice(dev->conn, pci) < 0)
+ goto out;
+
+ ret = 0;
+out:
+ pciFreeDevice(dev->conn, pci);
+ return ret;
+}
+
+static int
+xenUnifiedNodeDeviceReset (virNodeDevicePtr dev)
+{
+ pciDevice *pci;
+ unsigned domain, bus, slot, function;
+ int ret = -1;
+
+ if (xenUnifiedNodeDeviceGetPciInfo(dev, &domain, &bus, &slot, &function) < 0)
+ return -1;
+
+ pci = pciGetDevice(dev->conn, domain, bus, slot, function);
+ if (!pci)
+ return -1;
+
+ if (pciResetDevice(dev->conn, pci) < 0)
+ goto out;
+
+ ret = 0;
+out:
+ pciFreeDevice(dev->conn, pci);
+ return ret;
+}
+
+
/*----- Register with libvirt.c, and initialise Xen drivers. -----*/
/* The interface which we export upwards to libvirt.c. */
@@ -1481,6 +1600,9 @@ static virDriver xenUnifiedDriver = {
.getFreeMemory = xenUnifiedNodeGetFreeMemory,
.domainEventRegister = xenUnifiedDomainEventRegister,
.domainEventDeregister = xenUnifiedDomainEventDeregister,
+ .nodeDeviceDettach = xenUnifiedNodeDeviceDettach,
+ .nodeDeviceReAttach = xenUnifiedNodeDeviceReAttach,
+ .nodeDeviceReset = xenUnifiedNodeDeviceReset,
};
/**
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.253
diff -u -p -r1.253 xend_internal.c
--- src/xend_internal.c 10 Mar 2009 11:13:32 -0000 1.253
+++ src/xend_internal.c 16 Mar 2009 11:31:29 -0000
@@ -92,6 +92,11 @@ xenDaemonFormatSxprNet(virConnectPtr con
int xendConfigVersion,
int isAttach);
static int
+xenDaemonFormatSxprOnePCI(virConnectPtr conn,
+ virDomainHostdevDefPtr def,
+ virBufferPtr buf);
+
+static int
virDomainXMLDevID(virDomainPtr domain,
virDomainDeviceDefPtr dev,
char *class,
@@ -2145,6 +2150,131 @@ error:
return -1;
}
+/**
+ * xenDaemonParseSxprPCI
+ * @conn: connection
+ * @root: root sexpr
+ *
+ * This parses out block devices from the domain sexpr
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
+static int
+xenDaemonParseSxprPCI(virConnectPtr conn,
+ virDomainDefPtr def,
+ const struct sexpr *root)
+{
+ const struct sexpr *cur, *tmp = NULL, *node;
+ virDomainHostdevDefPtr dev = NULL;
+
+ /*
+ * With the (domain ...) block we have the following odd setup
+ *
+ * (device
+ * (pci
+ * (dev (domain 0x0000) (bus 0x00) (slot 0x1b) (func 0x0))
+ * (dev (domain 0x0000) (bus 0x00) (slot 0x13) (func 0x0))
+ * )
+ * )
+ *
+ * Normally there is one (device ...) block per device, but in
+ * wierd world of Xen PCI, once (device ...) covers multiple
+ * devices.
+ */
+
+ for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
+ node = cur->u.s.car;
+ if ((tmp = sexpr_lookup(node, "device/pci")) != NULL)
+ break;
+ }
+
+ if (!tmp)
+ return 0;
+
+ for (cur = tmp; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
+ const char *domain = NULL;
+ const char *bus = NULL;
+ const char *slot = NULL;
+ const char *func = NULL;
+ int domainID;
+ int busID;
+ int slotID;
+ int funcID;
+
+ node = cur->u.s.car;
+ if (!sexpr_lookup(node, "dev"))
+ continue;
+
+ if (!(domain = sexpr_node(node, "dev/domain"))) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing PCI domain"));
+ goto error;
+ }
+ if (!(bus = sexpr_node(node, "dev/bus"))) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing PCI bus"));
+ goto error;
+ }
+ if (!(slot = sexpr_node(node, "dev/slot"))) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing PCI slot"));
+ goto error;
+ }
+ if (!(func = sexpr_node(node, "dev/func"))) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing PCI func"));
+ goto error;
+ }
+
+ if (virStrToLong_i(domain, NULL, 0, &domainID) < 0) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse PCI domain '%s'"), domain);
+ goto error;
+ }
+ if (virStrToLong_i(bus, NULL, 0, &busID) < 0) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse PCI bus '%s'"), bus);
+ goto error;
+ }
+ if (virStrToLong_i(slot, NULL, 0, &slotID) < 0) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse PCI slot '%s'"), slot);
+ goto error;
+ }
+ if (virStrToLong_i(func, NULL, 0, &funcID) < 0) {
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse PCI func '%s'"), func);
+ goto error;
+ }
+
+ if (VIR_ALLOC(dev) < 0)
+ goto no_memory;
+
+ dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+ dev->managed = 0;
+ dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ dev->source.subsys.u.pci.domain = domainID;
+ dev->source.subsys.u.pci.bus = busID;
+ dev->source.subsys.u.pci.slot = slotID;
+ dev->source.subsys.u.pci.function = funcID;
+
+ if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0) {
+ goto no_memory;
+ }
+
+ def->hostdevs[def->nhostdevs++] = dev;
+ }
+
+ return 0;
+
+no_memory:
+ virReportOOMError(conn);
+
+error:
+ virDomainHostdevDefFree(dev);
+ return -1;
+}
+
/**
* xenDaemonParseSxpr:
@@ -2310,6 +2440,9 @@ xenDaemonParseSxpr(virConnectPtr conn,
if (xenDaemonParseSxprNets(conn, def, root) < 0)
goto error;
+ if (xenDaemonParseSxprPCI(conn, def, root) < 0)
+ goto error;
+
/* New style graphics device config */
if (xenDaemonParseSxprGraphicsNew(conn, def, root) < 0)
goto error;
@@ -3953,6 +4086,20 @@ xenDaemonAttachDevice(virDomainPtr domai
goto cleanup;
break;
+ case VIR_DOMAIN_DEVICE_HOSTDEV:
+ if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ if (xenDaemonFormatSxprOnePCI(domain->conn,
+ dev->data.hostdev,
+ &buf) < 0)
+ goto cleanup;
+ } else {
+ virXendError(domain->conn, VIR_ERR_NO_SUPPORT, "%s",
+ _("unsupported device type"));
+ goto cleanup;
+ }
+ break;
+
default:
virXendError(domain->conn, VIR_ERR_NO_SUPPORT, "%s",
_("unsupported device type"));
@@ -5263,6 +5410,85 @@ xenDaemonFormatSxprNet(virConnectPtr con
return 0;
}
+
+static void
+xenDaemonFormatSxprPCI(virDomainHostdevDefPtr def,
+ virBufferPtr buf)
+{
+ virBufferVSprintf(buf, "(dev (domain 0x%04x)(bus 0x%02x)(slot 0x%02x)(func 0x%x))",
+ def->source.subsys.u.pci.domain,
+ def->source.subsys.u.pci.bus,
+ def->source.subsys.u.pci.slot,
+ def->source.subsys.u.pci.function);
+}
+
+static int
+xenDaemonFormatSxprOnePCI(virConnectPtr conn,
+ virDomainHostdevDefPtr def,
+ virBufferPtr buf)
+{
+ if (def->managed) {
+ virXendError(conn, VIR_ERR_NO_SUPPORT, "%s",
+ _("managed PCI devices not supported with XenD"));
+ return -1;
+ }
+
+ virBufferAddLit(buf, "(pci ");
+ xenDaemonFormatSxprPCI(def, buf);
+ virBufferAddLit(buf, ")");
+
+ return 0;
+}
+
+static int
+xenDaemonFormatSxprAllPCI(virConnectPtr conn,
+ virDomainDefPtr def,
+ virBufferPtr buf)
+{
+ int hasPCI = 0;
+ int i;
+
+ for (i = 0 ; i < def->nhostdevs ; i++)
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ hasPCI = 1;
+
+ if (!hasPCI)
+ return 0;
+
+ /*
+ * With the (domain ...) block we have the following odd setup
+ *
+ * (device
+ * (pci
+ * (dev (domain 0x0000) (bus 0x00) (slot 0x1b) (func 0x0))
+ * (dev (domain 0x0000) (bus 0x00) (slot 0x13) (func 0x0))
+ * )
+ * )
+ *
+ * Normally there is one (device ...) block per device, but in
+ * wierd world of Xen PCI, once (device ...) covers multiple
+ * devices.
+ */
+
+ virBufferAddLit(buf, "(device (pci ");
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ if (def->hostdevs[i]->managed) {
+ virXendError(conn, VIR_ERR_NO_SUPPORT, "%s",
+ _("managed PCI devices not supported with XenD"));
+ return -1;
+ }
+
+ xenDaemonFormatSxprPCI(def->hostdevs[i], buf);
+ }
+ }
+ virBufferAddLit(buf, "))");
+
+ return 0;
+}
+
int
xenDaemonFormatSxprSound(virConnectPtr conn,
virDomainDefPtr def,
@@ -5529,6 +5755,9 @@ xenDaemonFormatSxpr(virConnectPtr conn,
&buf, hvm, xendConfigVersion, 0) < 0)
goto error;
+ if (xenDaemonFormatSxprAllPCI(conn, def, &buf) < 0)
+ goto error;
+
/* New style PV graphics config xen >= 3.0.4,
* or HVM graphics config xen >= 3.0.5 */
if ((xendConfigVersion >= XEND_CONFIG_MIN_VERS_PVFB_NEWCONF && !hvm) ||
@@ -5611,6 +5840,9 @@ virDomainXMLDevID(virDomainPtr domain,
strncpy(ref, xref, ref_len);
free(xref);
ref[ref_len - 1] = '\0';
+ } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
+ dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
} else {
virXendError(NULL, VIR_ERR_NO_SUPPORT,
"%s", _("hotplug of device type not supported"));
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.117
diff -u -p -r1.117 xm_internal.c
--- src/xm_internal.c 5 Feb 2009 16:03:11 -0000 1.117
+++ src/xm_internal.c 16 Mar 2009 11:31:29 -0000
@@ -673,6 +673,7 @@ xenXMDomainConfigParse(virConnectPtr con
virDomainDiskDefPtr disk = NULL;
virDomainNetDefPtr net = NULL;
virDomainGraphicsDefPtr graphics = NULL;
+ virDomainHostdevDefPtr hostdev = NULL;
int i;
const char *defaultArch, *defaultMachine;
@@ -1115,6 +1116,88 @@ xenXMDomainConfigParse(virConnectPtr con
}
}
+ list = virConfGetValue(conf, "pci");
+ if (list && list->type == VIR_CONF_LIST) {
+ list = list->list;
+ while (list) {
+ char domain[5];
+ char bus[3];
+ char slot[3];
+ char func[2];
+ char *key, *nextkey;
+ int domainID;
+ int busID;
+ int slotID;
+ int funcID;
+
+ domain[0] = bus[0] = slot[0] = func[0] = '\0';
+
+ if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
+ goto skippci;
+
+ /* pci=['0000:00:1b.0','0000:00:13.0'] */
+ key = list->str;
+ if (!(key = list->str))
+ goto skippci;
+ if (!(nextkey = strchr(key, ':')))
+ goto skippci;
+
+ if ((nextkey - key) > (sizeof(domain)-1))
+ goto skippci;
+
+ strncpy(domain, key, sizeof(domain));
+ domain[sizeof(domain)-1] = '\0';
+
+ key = nextkey + 1;
+ if (!(nextkey = strchr(key, ':')))
+ goto skippci;
+
+ strncpy(bus, key, sizeof(bus));
+ bus[sizeof(bus)-1] = '\0';
+
+ key = nextkey + 1;
+ if (!(nextkey = strchr(key, '.')))
+ goto skippci;
+
+ strncpy(slot, key, sizeof(slot));
+ slot[sizeof(slot)-1] = '\0';
+
+ key = nextkey + 1;
+ if (strlen(key) != 1)
+ goto skippci;
+
+ strncpy(func, key, sizeof(func));
+ func[sizeof(func)-1] = '\0';
+
+ if (virStrToLong_i(domain, NULL, 16, &domainID) < 0)
+ goto skippci;
+ if (virStrToLong_i(bus, NULL, 16, &busID) < 0)
+ goto skippci;
+ if (virStrToLong_i(slot, NULL, 16, &slotID) < 0)
+ goto skippci;
+ if (virStrToLong_i(func, NULL, 16, &funcID) < 0)
+ goto skippci;
+
+ if (VIR_ALLOC(hostdev) < 0)
+ goto cleanup;
+
+ hostdev->managed = 0;
+ hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ hostdev->source.subsys.u.pci.domain = domainID;
+ hostdev->source.subsys.u.pci.bus = busID;
+ hostdev->source.subsys.u.pci.slot = slotID;
+ hostdev->source.subsys.u.pci.function = funcID;
+
+ if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0)
+ goto no_memory;
+ def->hostdevs[def->nhostdevs++] = hostdev;
+ hostdev = NULL;
+
+ skippci:
+ list = list->next;
+ }
+ }
+
if (hvm) {
if (xenXMConfigGetString(conn, conf, "usbdevice", &str, NULL) < 0)
goto cleanup;
@@ -1939,6 +2022,76 @@ cleanup:
+static int
+xenXMDomainConfigFormatPCI(virConnectPtr conn,
+ virConfPtr conf,
+ virDomainDefPtr def)
+{
+
+ virConfValuePtr pciVal = NULL;
+ int hasPCI = 0;
+ int i;
+
+ for (i = 0 ; i < def->nhostdevs ; i++)
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ hasPCI = 1;
+
+ if (!hasPCI)
+ return 0;
+
+ if (VIR_ALLOC(pciVal) < 0)
+ return -1;
+
+ pciVal->type = VIR_CONF_LIST;
+ pciVal->list = NULL;
+
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ virConfValuePtr val, tmp;
+ char *buf;
+
+ if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
+ def->hostdevs[i]->source.subsys.u.pci.domain,
+ def->hostdevs[i]->source.subsys.u.pci.bus,
+ def->hostdevs[i]->source.subsys.u.pci.slot,
+ def->hostdevs[i]->source.subsys.u.pci.function) < 0)
+ goto error;
+
+ if (VIR_ALLOC(val) < 0) {
+ VIR_FREE(buf);
+ virReportOOMError(conn);
+ goto error;
+ }
+ val->type = VIR_CONF_STRING;
+ val->str = buf;
+ tmp = pciVal->list;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = val;
+ else
+ pciVal->list = val;
+ }
+ }
+
+ if (pciVal->list != NULL) {
+ int ret = virConfSetValue(conf, "pci", pciVal);
+ pciVal = NULL;
+ if (ret < 0)
+ return -1;
+ }
+ VIR_FREE(pciVal);
+
+ return 0;
+
+error:
+ virConfFreeValue(pciVal);
+ return -1;
+}
+
+
virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
virDomainDefPtr def) {
virConfPtr conf = NULL;
@@ -2260,6 +2413,9 @@ virConfPtr xenXMDomainConfigFormat(virCo
}
VIR_FREE(netVal);
+ if (xenXMDomainConfigFormatPCI(conn, conf, def) < 0)
+ goto cleanup;
+
if (hvm) {
if (def->nparallels) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
Index: tests/sexpr2xmltest.c
===================================================================
RCS file: /data/cvs/libvirt/tests/sexpr2xmltest.c,v
retrieving revision 1.36
diff -u -p -r1.36 sexpr2xmltest.c
--- tests/sexpr2xmltest.c 29 Jan 2009 17:02:00 -0000 1.36
+++ tests/sexpr2xmltest.c 16 Mar 2009 11:31:29 -0000
@@ -142,6 +142,7 @@ mymain(int argc, char **argv)
DO_TEST("net-e1000", "net-e1000", 2);
DO_TEST("bridge-ipaddr", "bridge-ipaddr", 3);
DO_TEST("no-source-cdrom", "no-source-cdrom", 2);
+ DO_TEST("pci-devs", "pci-devs", 2);
DO_TEST("fv-utc", "fv-utc", 1);
DO_TEST("fv-localtime", "fv-localtime", 1);
Index: tests/xmconfigtest.c
===================================================================
RCS file: /data/cvs/libvirt/tests/xmconfigtest.c,v
retrieving revision 1.26
diff -u -p -r1.26 xmconfigtest.c
--- tests/xmconfigtest.c 8 Jan 2009 19:52:15 -0000 1.26
+++ tests/xmconfigtest.c 16 Mar 2009 11:31:29 -0000
@@ -231,6 +231,7 @@ mymain(int argc, char **argv)
DO_TEST("escape-paths", 2);
DO_TEST("no-source-cdrom", 2);
+ DO_TEST("pci-devs", 2);
virCapabilitiesFree(caps);
Index: tests/xml2sexprtest.c
===================================================================
RCS file: /data/cvs/libvirt/tests/xml2sexprtest.c,v
retrieving revision 1.34
diff -u -p -r1.34 xml2sexprtest.c
--- tests/xml2sexprtest.c 23 Jan 2009 01:48:47 -0000 1.34
+++ tests/xml2sexprtest.c 16 Mar 2009 11:31:29 -0000
@@ -128,6 +128,7 @@ mymain(int argc, char **argv)
DO_TEST("net-e1000", "net-e1000", "pvtest", 2);
DO_TEST("bridge-ipaddr", "bridge-ipaddr", "pvtest", 2);
DO_TEST("no-source-cdrom", "no-source-cdrom", "test", 2);
+ DO_TEST("pci-devs", "pci-devs", "pvtest", 2);
DO_TEST("fv-utc", "fv-utc", "fvtest", 1);
DO_TEST("fv-localtime", "fv-localtime", "fvtest", 1);
Index: tests/sexpr2xmldata/sexpr2xml-pci-devs.sexpr
===================================================================
RCS file: tests/sexpr2xmldata/sexpr2xml-pci-devs.sexpr
diff -N tests/sexpr2xmldata/sexpr2xml-pci-devs.sexpr
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/sexpr2xmldata/sexpr2xml-pci-devs.sexpr 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1,2 @@
+(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test... ')))(device (pci (backend 0)(dev (domain 0x0001) (bus 0x0c) (slot 0x1b) (func 0x2))(dev (domain 0x0000) (bus 0x01) (slot 0x13) (func 0x0))))(device (vbd (dev 'xvda')(uname 'phy:/dev/MainVG/GuestVG')(mode 'w'))))
+
Index: tests/sexpr2xmldata/sexpr2xml-pci-devs.xml
===================================================================
RCS file: tests/sexpr2xmldata/sexpr2xml-pci-devs.xml
diff -N tests/sexpr2xmldata/sexpr2xml-pci-devs.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/sexpr2xmldata/sexpr2xml-pci-devs.xml 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1,37 @@
+<domain type='xen' id='6'>
+ <name>pvtest</name>
+ <uuid>596a5d21-71f4-8fb2-e068-e2386a5c413e</uuid>
+ <memory>430080</memory>
+ <currentMemory>430080</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type>linux</type>
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test... </cmdline>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='block' device='disk'>
+ <driver name='phy'/>
+ <source dev='/dev/MainVG/GuestVG'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0000' bus='0x01' slot='0x13' function='0x0'/>
+ </source>
+ </hostdev>
+ </devices>
+</domain>
Index: tests/xmconfigdata/test-pci-devs.cfg
===================================================================
RCS file: tests/xmconfigdata/test-pci-devs.cfg
diff -N tests/xmconfigdata/test-pci-devs.cfg
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/xmconfigdata/test-pci-devs.cfg 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1,24 @@
+name = "test"
+uuid = "cc2315e7-d26a-307a-438c-6d188ec4c09c"
+maxmem = 382
+memory = 350
+vcpus = 1
+builder = "hvm"
+kernel = "/usr/lib/xen/boot/hvmloader"
+boot = "c"
+pae = 1
+acpi = 1
+apic = 1
+localtime = 0
+on_poweroff = "destroy"
+on_reboot = "destroy"
+on_crash = "destroy"
+device_model = "/usr/lib/xen/bin/qemu-dm"
+sdl = 0
+vnc = 1
+vncunused = 1
+disk = [ "phy:/dev/sda8,hda,w", ",hdc:cdrom,r" ]
+vif = [ "mac=00:16:3e:0a:7b:39,bridge=xenbr0,type=ioemu" ]
+pci = [ "0001:0c:1b.2", "0000:01:13.0" ]
+parallel = "none"
+serial = "pty"
Index: tests/xmconfigdata/test-pci-devs.xml
===================================================================
RCS file: tests/xmconfigdata/test-pci-devs.xml
diff -N tests/xmconfigdata/test-pci-devs.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/xmconfigdata/test-pci-devs.xml 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1,56 @@
+<domain type='xen'>
+ <name>test</name>
+ <uuid>cc2315e7-d26a-307a-438c-6d188ec4c09c</uuid>
+ <memory>391168</memory>
+ <currentMemory>358400</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='xenfv'>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
+ <disk type='block' device='disk'>
+ <driver name='phy'/>
+ <source dev='/dev/sda8'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='block' device='cdrom'>
+ <driver name='phy'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:0a:7b:39'/>
+ <source bridge='xenbr0'/>
+ </interface>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='-1' autoport='yes'/>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0000' bus='0x01' slot='0x13' function='0x0'/>
+ </source>
+ </hostdev>
+ </devices>
+</domain>
Index: tests/xml2sexprdata/xml2sexpr-pci-devs.sexpr
===================================================================
RCS file: tests/xml2sexprdata/xml2sexpr-pci-devs.sexpr
diff -N tests/xml2sexprdata/xml2sexpr-pci-devs.sexpr
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/xml2sexprdata/xml2sexpr-pci-devs.sexpr 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1 @@
+(vm (name 'pvtest')(memory 420)(maxmem 420)(vcpus 2)(uuid '596a5d21-71f4-8fb2-e068-e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test... ')))(device (vbd (dev 'xvda')(uname 'phy:/dev/MainVG/GuestLV')(mode 'w')))(device (pci (dev (domain 0x0001)(bus 0x0c)(slot 0x1b)(func 0x2))(dev (domain 0x0000)(bus 0x01)(slot 0x13)(func 0x0)))))
\ No newline at end of file
Index: tests/xml2sexprdata/xml2sexpr-pci-devs.xml
===================================================================
RCS file: tests/xml2sexprdata/xml2sexpr-pci-devs.xml
diff -N tests/xml2sexprdata/xml2sexpr-pci-devs.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/xml2sexprdata/xml2sexpr-pci-devs.xml 16 Mar 2009 11:31:29 -0000
@@ -0,0 +1,33 @@
+<domain type='xen' id='15'>
+ <name>pvtest</name>
+ <uuid>596a5d2171f48fb2e068e2386a5c413e</uuid>
+ <os>
+ <type>linux</type>
+ <kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
+ <initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
+ <cmdline> method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test... </cmdline>
+ </os>
+ <memory>430080</memory>
+ <vcpu>2</vcpu>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <disk type='block' device='disk'>
+ <source dev='/dev/MainVG/GuestLV'/>
+ <target dev='xvda'/>
+ </disk>
+ <console tty='/dev/pts/4'/>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0001' bus='0x0c' slot='0x1b' function='0x2'/>
+ </source>
+ </hostdev>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <source>
+ <address domain='0x0000' bus='0x01' slot='0x13' function='0x0'/>
+ </source>
+ </hostdev>
+ </devices>
+</domain>
+
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
15 years, 8 months
[libvirt] Problem with the current svirt patch
by Daniel J Walsh
The current svirt patch relabels all disk to the image_t:MCS, which is
incorrect. Read Only Disks and Sharable Disks should not be labeled.
Also when libvirt is completed running the image it needs to relabel the
image back to something sane. Right now it is labeling everything
imagelabel:s0, including phisical disk partitions. I considered two
ways of labeling the "disk" back. We can either grab the label when
libvirt starts and change it back to this label when ever an image
completes or we can ask the system what the label should be.
(matcpathcon). I originally coded up the first, but quickly realized if
anything went wrong with libvirt labeling like a crash, the labels on
disk could be wrong. And libvirt would continuously set them to this
wrong label. With matchpathcon, libvirt will at least set them to
something sane.
So this patch Removes labeling of readonly and shared disks and restores
the images label to the system default when the image completes.
I would really like to get this in ASAP. Since currently libvirt is
relabeing the cdrom to virt_image_t when it is complete as well as
physical disks.
15 years, 8 months