[libvirt] [PATCH 2/2] Updated & fixed OpenNebula driver, libvirt-0.6.2

"Abel Míguez Rodríguez" amiguezr at pdi.ucm.es
Wed Apr 22 15:05:56 UTC 2009


[PATCH 2/2] ONE Driver source files

Thanks,

-------------------------------------------------------------------------------------
src/opennebula/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);

char* xmlOneTemplate(virConnectPtr conn,virDomainDefPtr def);

#define oneError(conn, dom, code, fmt...)                                  \
        virReportErrorHelper(conn, VIR_FROM_ONE, code, __FILE__,           \
                               __FUNCTION__, __LINE__, fmt)

#endif /* ONE_CONF_H */


---------------------------------------------------------------------------------------------------------
src/opennebula/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"
#include "buf.h"
#include "memory.h"
#include "util.h"

#define VIR_FROM_THIS VIR_FROM_ONE
/* --------------------------------------------------------------------------------- */

/**
 * 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",
                                         "i686",
                                         32,
                                         NULL,
                                         NULL,
                                         0,
                                         NULL)) == NULL)
    {
        goto no_memory;
    }

    if (virCapabilitiesAddGuestDomain(guest,
                                      "one",
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
    {
        goto no_memory;
    }


	if ((guest = virCapabilitiesAddGuest(caps,
                                         "hvm",
                                         "x86_64",
                                         64,
                                         NULL,
                                         NULL,
                                         0,
                                         NULL)) == NULL)
    {
        goto no_memory;
    }

    if (virCapabilitiesAddGuestDomain(guest,
                                      "one",
                                      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,
                one_driver_t*    driver ATTRIBUTE_UNUSED,
                virDomainObjPtr  vm)
{
    char* templ;
    int   oneid;
		
    if((templ=xmlOneTemplate(conn,vm->def))==NULL )
		return -1;

    if( (oneid=c_oneAllocateTemplate(templ))<0 ){
        oneError(conn, NULL, VIR_ERR_OPERATION_FAILED,
                     "Error submitting virtual machine to OpenNebula");
		VIR_FREE(templ);
		return -1;
    }

    VIR_FREE(templ);
    return oneid;
}
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */

/**
 * xmlOneTemplate Generate an OpenNebula template to deploy a VM from libvirt
 * internal Domain definition.
 * @param def  Internal libvirt Domain definition
 * @return OpenNebula VM template.
 */

char* xmlOneTemplate(virConnectPtr conn,virDomainDefPtr def)
{	
  	int i;
	virBuffer buf= VIR_BUFFER_INITIALIZER;
	virBufferVSprintf(&buf,"#OpenNebula Template automatically generated by libvirt\nNAME = %s\nCPU = %ld\nMEMORY = %ld\n",
						def->name,
						def->vcpus,
						(def->maxmem)/1024);
	
    /*Optional Booting OpenNebula Information:*/
  	if( def->os.kernel ){
        virBufferVSprintf(&buf,"OS=[ kernel = \"%s\"",def->os.kernel);
        if(def->os.initrd)
			virBufferVSprintf(&buf,",\n    initrd = \"%s\"",def->os.initrd);
        if(def->os.cmdline)
        	virBufferVSprintf(&buf,",\n    kernel_cmd = \"%s\"",def->os.cmdline);
        if(def->os.root)
        	virBufferVSprintf(&buf,",\n    root  = \"%s\"",def->os.root);
        
	virBufferAddLit(&buf," ]\n");
    }
    /* set Disks & NICS */
    for(i=0 ; i<def->ndisks ; i++){		
		// missing source is only allowed at cdrom and floppy 
		if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_DISK){
			virBufferVSprintf(&buf, "DISK=[ type = disk,\n"
									"	source = \"%s\",\n",
					                def->disks[i]->src);
 		}
		else if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_CDROM){
			virBufferAddLit(&buf,  "DISK=[ type = cdrom,\n"); 
			if(def->disks[i]->src) virBufferVSprintf(&buf, "	source = \"%s\",\n",def->disks[i]->src);
		}
		else if(def->disks[i]->device==VIR_DOMAIN_DISK_DEVICE_FLOPPY){
			virBufferAddLit(&buf,  "DISK=[ type = floppy,\n");
			if(def->disks[i]->src) virBufferVSprintf(&buf, "	source = \"%s\",\n",def->disks[i]->src);
		}

		virBufferVSprintf(&buf, "	target = \"%s\",\n"
								"	readonly =",
								def->disks[i]->dst);

		if(def->disks[i]->readonly) 
			virBufferAddLit(&buf,"\"yes\"]\n");
		else 
			virBufferAddLit(&buf,"\"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:
              virBufferVSprintf(&buf,"NIC=[ bridge =\"%s\",\n",def->nets[i]->data.bridge.brname);
              
							if(def->nets[i]->ifname)
								virBufferVSprintf(&buf,"      target =\"%s\",\n",def->nets[i]->ifname);
								
							virBufferVSprintf(&buf,"      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:						
              virBufferVSprintf(&buf,"NIC=[ network=\"%s\"",def->nets[i]->data.network.name);
							if(def->nets[i]->ifname)
								virBufferVSprintf(&buf,",\n      target =\"%s\"",def->nets[i]->ifname);
							virBufferAddLit(&buf," ]\n");	
							break;

			default: break;
        }				
    }
		
    if(def->graphics!=NULL){
			if(def->graphics->type==VIR_DOMAIN_GRAPHICS_TYPE_VNC){
				virBufferAddLit(&buf,"GRAPHICS = [\n  type = \"vnc\"");
				
				if(def->graphics->data.vnc.listenAddr!=NULL)
					virBufferVSprintf(&buf,",\n  listen = \"%s\"",def->graphics->data.vnc.listenAddr);	
			
				if(def->graphics->data.vnc.autoport==0)
					virBufferVSprintf(&buf,",\n  port = \"%d\"",def->graphics->data.vnc.port);
			
				if(def->graphics->data.vnc.passwd!=NULL)
					virBufferVSprintf(&buf,",\n  passwd = \"%s\"",def->graphics->data.vnc.passwd);	
					
				virBufferAddLit(&buf," ]\n");		
			
			}		
			else //graphics.type==VIR_DOMAIN_GRAPHICS_TYPE_SDL
				virBufferAddLit(&buf,"GRAPHICS = [\n  type = \"sdl\" ]\n");
		
		}
    if (virBufferError(&buf))
        goto no_memory;

    return virBufferContentAndReset(&buf);

 no_memory:
    virReportOOMError(conn);
    char* tmp = virBufferContentAndReset(&buf);
    VIR_FREE(tmp);
    return NULL;
}; 


--------------------------------------------------------------------------------------------------------
src/opennebula/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>
#include <OneClient.h>

int oneRegister(void);

#endif /* ONE_DRIVER_H */





--------------------------------------------------------------------------------------------------------
src/opennebula/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"

#define VIR_FROM_THIS VIR_FROM_ONE

static int oneStartup(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) {
            virReportOOMError(conn);
            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++){
        virDomainObjLock(driver->domains.objs[i]);
        if (virDomainIsActive(driver->domains.objs[i]))
            ids[got++] = driver->domains.objs[i]->def->id;
        virDomainObjUnlock(driver->domains.objs[i]);
    }
    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++){
        virDomainObjLock(driver->domains.objs[i]);
        if (virDomainIsActive(driver->domains.objs[i]))
            n++;
        virDomainObjUnlock(driver->domains.objs[i]);
	}
    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++) {
		virDomainObjLock(driver->domains.objs[i]);
        if (!virDomainIsActive(driver->domains.objs[i])) {
            if (!(names[got++] = strdup(driver->domains.objs[i]->def->name))) {
                virReportOOMError(conn);
				virDomainObjUnlock(driver->domains.objs[i]);
                goto cleanup;
            }
        }
        virDomainObjUnlock(driver->domains.objs[i]);
    }
    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++){
        virDomainObjLock(driver->domains.objs[i]);
        if (!virDomainIsActive(driver->domains.objs[i]))
            n++;
        virDomainObjUnlock(driver->domains.objs[i]);
	}
    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, dom, VIR_ERR_INVALID_DOMAIN,
                 "no domain with matching uuid");
        goto return_point;
    }

    if (!vm->persistent) {
        oneError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
                 "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,dom, VIR_ERR_INVALID_DOMAIN,
                 "%s", _("no domain with matching uuid"));
        return -1;
    }

    if(gettimeofday(&tv,NULL)<0) {
        oneError(dom->conn,dom, 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,dom, 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;
   
    oneDriverLock(driver);
    vm = virDomainFindByName(&driver->domains, dom->name);

    if (!vm) {
        oneError(conn, dom, 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 = NULL;
    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;
            goto return_point;
        }
        oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
                "Wrong state to perform action");
        goto return_point;
    }
    oneError(dom->conn,dom, VIR_ERR_INVALID_DOMAIN,
                 _("no domain with id %d"), dom->id);
        goto return_point;

    if (!vm->persistent) {
        virDomainRemoveInactive(&driver->domains, vm); 
        vm = NULL;
    }
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, dom, VIR_ERR_INVALID_DOMAIN,
                 "no domain with id %d", dom->id);
        goto return_point;
    }
    if(c_oneCancel(vm->pid)) {
    /* VM not running, delete the instance at ONE DB */
      if(c_oneFinalize(vm->pid)){
        oneError(dom->conn, dom, VIR_ERR_OPERATION_FAILED,
                "Wrong state to perform action");
        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, dom, VIR_ERR_OPERATION_FAILED,
                 "Wrong state to perform action");
        goto return_point;
    }
    oneError(dom->conn,dom,VIR_ERR_OPERATION_FAILED,
             "domain is not running");
    } else {
        oneError(dom->conn, dom, 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, dom, VIR_ERR_OPERATION_FAILED,
                      "Wrong state to perform action");
            goto return_point;
        } 
        oneError(dom->conn,dom,VIR_ERR_OPERATION_FAILED,
                 "domain is not paused ");
    } else {
        oneError(dom->conn, dom, 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){

    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(virDomainPtr domain ATTRIBUTE_UNUSED, int *autostart)
{
	autostart=0;
    return 0;
}

static char*  oneGetCapabilities(virConnectPtr conn){
	one_driver_t* privconn=conn->privateData;
    char *xml;
    oneDriverLock(privconn);
    if ((xml = virCapabilitiesFormatXML(privconn->caps)) == NULL)
        virReportOOMError(conn);
    oneDriverUnlock(privconn);
    return xml;
}
/* 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, /* getMaxVcpus */
    NULL, /* nodeGetInfo */
    oneGetCapabilities, /* 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 */
    NULL, /* nodeDeviceDettach; */
    NULL, /* nodeDeviceReAttach; */
    NULL, /* nodeDeviceReset; */
};
    
static virStateDriver oneStateDriver = {
    .initialize = oneStartup,
    .cleanup    = oneShutdown,
    .active     = oneActive,
};


int oneRegister(void)
{
    virRegisterDriver(&oneDriver);
    virRegisterStateDriver(&oneStateDriver);
    return 0;
}




Abel Míguez Rodríguez
----
 Distributed System Architecture Group  
 (http://dsa-research.org)

 GridWay, http://www.gridway.org
 OpenNEbula, http://www.opennebula.org




-------------- next part --------------
A non-text attachment was scrubbed...
Name: driver_sources.tar
Type: application/x-tar
Size: 40960 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20090422/8367e632/attachment-0001.tar>


More information about the libvir-list mailing list