[libvirt] [PATCH 2/2] [ plain text ] OpenNebula driver, libvirt-0.6.1

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@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

On Wed, Mar 18, 2009 at 11:00:13PM +0100, "Abel M?guez Rodr?guez" wrote:
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.
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; }
What architectures does OpenNebular support ? I'm guessing i686 and x86_64 at least ? Since x86_64 supports running i686 guests, you may well want to register a second guest here for 'i686' arch, if you have a x86_64 host.
if (virCapabilitiesAddGuestDomain(guest, "hvm", NULL, NULL, 0, NULL) == NULL)
The guest domain is refering to the type of virtualization used, eg 'xen', 'qemu', 'kvm', etc. So 'hvm' is wrong in this context. Since OpenNebular will push out the vm to any host, with varying hypervisors, its probably best to just invent a generic domain called "one" here.
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);
Creating files in /tmp with predictable names is a real security flaw. Is there no way to create the VM without having to use a temporary file on disk ? eg, just do everything in memory ? If not, then at least use the mkstemp() function for creating the file more safely.
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; }
I think the last check in this if, should be against '->dst' rather than duplicating ->src again ? Also, I imagine you may also want to do something with device type, eg disk, vs cdrom, vs floppy.
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; }
You have a 'default:' block here that raises an error if any other type of network is requested, so the user sees they did something unsupported, rather than having their network silently ignored.
#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"
I don't think need the 'event.h' or 'cgroup.h' includes here, since you're not calling any of their functions.
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);
We no longer use VIR_ERR_NO_MEMORY directly - all those places should use 'virReportOOMError(conn)'. If you run 'make syntax-check' it will tell you all the places using VIR_ERR_NO_MEMORY that need to be changed
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; }
In all these 4 functions, to be thread-safe you need to call virDomainObjLock(driver->domains.objs[i]) before accessing the individual domain objects, and unlock it afterwards. Take a look at the qemu_driver.c file's equivalent methods for examples. Regards, Daniel -- |: 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 :|
participants (2)
-
"Abel Míguez Rodríguez"
-
Daniel P. Berrange