2007-02-14 01:40:09 +00:00
/*
* dispatch . c : ( De - ) marshall wire messages to driver functions .
*
* Copyright ( C ) 2006 , 2007 Red Hat , Inc .
* Copyright ( C ) 2006 Daniel P . Berrange
*
* 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
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
2007-02-14 15:42:55 +00:00
# include <config.h>
2007-02-14 01:40:09 +00:00
# include <limits.h>
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <sys/utsname.h>
# include <libvirt/virterror.h>
# include "internal.h"
# include "driver.h"
# include "dispatch.h"
static int qemudDispatchFailure ( struct qemud_server * server ATTRIBUTE_UNUSED ,
struct qemud_client * client ATTRIBUTE_UNUSED ,
struct qemud_packet * out ) {
out - > header . type = QEMUD_PKT_FAILURE ;
out - > header . dataSize = sizeof ( out - > data . failureReply ) ;
out - > data . failureReply . code = server - > errorCode ;
strcpy ( out - > data . failureReply . message , server - > errorMessage ) ;
return 0 ;
}
static int qemudDispatchGetVersion ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = 0 )
return - 1 ;
int version = qemudGetVersion ( server ) ;
if ( version < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_GET_VERSION ;
out - > header . dataSize = sizeof ( out - > data . getVersionReply ) ;
out - > data . getVersionReply . version = version ;
}
return 0 ;
}
static int qemudDispatchGetNodeInfo ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
struct utsname info ;
if ( in - > header . dataSize ! = 0 )
return - 1 ;
if ( uname ( & info ) < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
return 0 ;
}
if ( qemudGetCPUInfo ( & out - > data . getNodeInfoReply . cpus ,
& out - > data . getNodeInfoReply . mhz ,
& out - > data . getNodeInfoReply . nodes ,
& out - > data . getNodeInfoReply . sockets ,
& out - > data . getNodeInfoReply . cores ,
& out - > data . getNodeInfoReply . threads ) < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
return 0 ;
}
if ( qemudGetMemInfo ( & out - > data . getNodeInfoReply . memory ) < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
return 0 ;
}
out - > header . type = QEMUD_PKT_GET_NODEINFO ;
out - > header . dataSize = sizeof ( out - > data . getNodeInfoReply ) ;
strncpy ( out - > data . getNodeInfoReply . model , info . machine , sizeof ( out - > data . getNodeInfoReply . model ) ) ;
out - > data . getNodeInfoReply . model [ sizeof ( out - > data . getNodeInfoReply . model ) - 1 ] = ' \0 ' ;
return 0 ;
}
static int qemudDispatchListDomains ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
int i , ndomains , domains [ QEMUD_MAX_NUM_DOMAINS ] ;
if ( in - > header . dataSize ! = 0 )
return - 1 ;
ndomains = qemudListDomains ( server ,
domains ,
QEMUD_MAX_NUM_DOMAINS ) ;
if ( ndomains < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_LIST_DOMAINS ;
out - > header . dataSize = sizeof ( out - > data . listDomainsReply ) ;
for ( i = 0 ; i < ndomains ; i + + ) {
out - > data . listDomainsReply . domains [ i ] = domains [ i ] ;
}
out - > data . listDomainsReply . numDomains = ndomains ;
}
return 0 ;
}
static int qemudDispatchNumDomains ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = 0 )
return - 1 ;
int ndomains = qemudNumDomains ( server ) ;
if ( ndomains < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NUM_DOMAINS ;
out - > header . dataSize = sizeof ( out - > data . numDomainsReply ) ;
out - > data . numDomainsReply . numDomains = ndomains ;
}
return 0 ;
}
static int qemudDispatchDomainCreate ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainCreateRequest ) )
return - 1 ;
in - > data . domainCreateRequest . xml [ QEMUD_MAX_XML_LEN - 1 ] = ' \0 ' ;
struct qemud_vm * vm = qemudDomainCreate ( server , in - > data . domainCreateRequest . xml ) ;
if ( ! vm ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_CREATE ;
out - > header . dataSize = sizeof ( out - > data . domainCreateReply ) ;
2007-02-14 17:05:55 +00:00
out - > data . domainCreateReply . id = vm - > id ;
memcpy ( out - > data . domainCreateReply . uuid , vm - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
strncpy ( out - > data . domainCreateReply . name , vm - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 01:40:09 +00:00
out - > data . domainCreateReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchDomainLookupByID ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainLookupByIDRequest ) )
return - 1 ;
struct qemud_vm * vm = qemudFindVMByID ( server , in - > data . domainLookupByIDRequest . id ) ;
if ( ! vm ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_LOOKUP_BY_ID ;
out - > header . dataSize = sizeof ( out - > data . domainLookupByIDReply ) ;
2007-02-14 17:05:55 +00:00
memcpy ( out - > data . domainLookupByIDReply . uuid , vm - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
strncpy ( out - > data . domainLookupByIDReply . name , vm - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 01:40:09 +00:00
out - > data . domainLookupByIDReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchDomainLookupByUUID ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainLookupByUUIDRequest ) )
return - 1 ;
struct qemud_vm * vm = qemudFindVMByUUID ( server , in - > data . domainLookupByUUIDRequest . uuid ) ;
if ( ! vm ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_LOOKUP_BY_UUID ;
out - > header . dataSize = sizeof ( out - > data . domainLookupByUUIDReply ) ;
2007-02-14 17:05:55 +00:00
out - > data . domainLookupByUUIDReply . id = vm - > id ;
strncpy ( out - > data . domainLookupByUUIDReply . name , vm - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 01:40:09 +00:00
out - > data . domainLookupByUUIDReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchDomainLookupByName ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainLookupByNameRequest ) )
return - 1 ;
/* Paranoia NULL termination */
in - > data . domainLookupByNameRequest . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
struct qemud_vm * vm = qemudFindVMByName ( server , in - > data . domainLookupByNameRequest . name ) ;
if ( ! vm ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_LOOKUP_BY_NAME ;
out - > header . dataSize = sizeof ( out - > data . domainLookupByNameReply ) ;
2007-02-14 17:05:55 +00:00
out - > data . domainLookupByNameReply . id = vm - > id ;
memcpy ( out - > data . domainLookupByNameReply . uuid , vm - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
2007-02-14 01:40:09 +00:00
}
return 0 ;
}
static int qemudDispatchDomainSuspend ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainSuspendRequest ) )
return - 1 ;
int ret = qemudDomainSuspend ( server , in - > data . domainSuspendRequest . id ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_SUSPEND ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchDomainResume ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainResumeRequest ) )
return - 1 ;
int ret = qemudDomainResume ( server , in - > data . domainResumeRequest . id ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_RESUME ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchDomainDestroy ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainDestroyRequest ) )
return - 1 ;
2007-02-23 08:41:23 +00:00
if ( qemudDomainDestroy ( server , in - > data . domainDestroyRequest . id ) < 0 ) {
2007-02-14 01:40:09 +00:00
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_DESTROY ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchDomainGetInfo ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
int runstate ;
unsigned long long cpuTime ;
unsigned long memory ;
unsigned long maxmem ;
unsigned int nrVirtCpu ;
if ( in - > header . dataSize ! = sizeof ( in - > data . domainGetInfoRequest ) )
return - 1 ;
int ret = qemudDomainGetInfo ( server , in - > data . domainGetInfoRequest . uuid ,
& runstate ,
& cpuTime ,
& maxmem ,
& memory ,
& nrVirtCpu ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_GET_INFO ;
out - > header . dataSize = sizeof ( out - > data . domainGetInfoReply ) ;
out - > data . domainGetInfoReply . runstate = runstate ;
out - > data . domainGetInfoReply . cpuTime = cpuTime ;
out - > data . domainGetInfoReply . maxmem = maxmem ;
out - > data . domainGetInfoReply . memory = memory ;
out - > data . domainGetInfoReply . nrVirtCpu = nrVirtCpu ;
}
return 0 ;
}
static int qemudDispatchDomainSave ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainSaveRequest ) )
return - 1 ;
/* Paranoia NULL termination */
in - > data . domainSaveRequest . file [ PATH_MAX - 1 ] = ' \0 ' ;
int ret = qemudDomainSave ( server ,
in - > data . domainSaveRequest . id ,
in - > data . domainSaveRequest . file ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_SAVE ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchDomainRestore ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
int id ;
if ( in - > header . dataSize ! = sizeof ( in - > data . domainRestoreRequest ) )
return - 1 ;
/* Paranoia null termination */
in - > data . domainRestoreRequest . file [ PATH_MAX - 1 ] = ' \0 ' ;
id = qemudDomainRestore ( server , in - > data . domainRestoreRequest . file ) ;
if ( id < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_RESTORE ;
out - > header . dataSize = sizeof ( out - > data . domainRestoreReply ) ;
out - > data . domainRestoreReply . id = id ;
}
return 0 ;
}
static int qemudDispatchDumpXML ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
int ret ;
if ( in - > header . dataSize ! = sizeof ( in - > data . domainDumpXMLRequest ) )
return - 1 ;
ret = qemudDomainDumpXML ( server ,
in - > data . domainDumpXMLRequest . uuid ,
out - > data . domainDumpXMLReply . xml ,
QEMUD_MAX_XML_LEN ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DUMP_XML ;
out - > header . dataSize = sizeof ( out - > data . domainDumpXMLReply ) ;
}
return 0 ;
}
static int qemudDispatchListDefinedDomains ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
char * * names ;
int i , ndomains ;
if ( in - > header . dataSize ! = 0 )
return - 1 ;
if ( ! ( names = malloc ( sizeof ( char * ) * QEMUD_MAX_NUM_DOMAINS ) ) )
return - 1 ;
for ( i = 0 ; i < QEMUD_MAX_NUM_DOMAINS ; i + + ) {
names [ i ] = out - > data . listDefinedDomainsReply . domains [ i ] ;
}
ndomains = qemudListDefinedDomains ( server ,
names ,
QEMUD_MAX_NUM_DOMAINS ) ;
free ( names ) ;
if ( ndomains < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_LIST_DEFINED_DOMAINS ;
out - > header . dataSize = sizeof ( out - > data . listDefinedDomainsReply ) ;
out - > data . listDefinedDomainsReply . numDomains = ndomains ;
}
return 0 ;
}
static int qemudDispatchNumDefinedDomains ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = 0 )
return - 1 ;
int ndomains = qemudNumDefinedDomains ( server ) ;
if ( ndomains < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NUM_DEFINED_DOMAINS ;
out - > header . dataSize = sizeof ( out - > data . numDefinedDomainsReply ) ;
out - > data . numDefinedDomainsReply . numDomains = ndomains ;
}
return 0 ;
}
static int qemudDispatchDomainStart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
2007-02-23 08:41:23 +00:00
struct qemud_vm * vm ;
2007-02-14 01:40:09 +00:00
if ( in - > header . dataSize ! = sizeof ( in - > data . domainStartRequest ) )
return - 1 ;
2007-02-23 08:41:23 +00:00
if ( ! ( vm = qemudDomainStart ( server , in - > data . domainStartRequest . uuid ) ) ) {
2007-02-14 01:40:09 +00:00
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_START ;
out - > header . dataSize = sizeof ( out - > data . domainStartReply ) ;
2007-02-14 17:05:55 +00:00
out - > data . domainStartReply . id = vm - > id ;
2007-02-14 01:40:09 +00:00
}
return 0 ;
}
static int qemudDispatchDomainDefine ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainDefineRequest ) )
return - 1 ;
in - > data . domainDefineRequest . xml [ QEMUD_MAX_XML_LEN - 1 ] = ' \0 ' ;
struct qemud_vm * vm = qemudDomainDefine ( server , in - > data . domainDefineRequest . xml ) ;
if ( ! vm ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_DEFINE ;
out - > header . dataSize = sizeof ( out - > data . domainDefineReply ) ;
2007-02-14 17:05:55 +00:00
memcpy ( out - > data . domainDefineReply . uuid , vm - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
strncpy ( out - > data . domainDefineReply . name , vm - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 01:40:09 +00:00
out - > data . domainDefineReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchDomainUndefine ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . domainUndefineRequest ) )
return - 1 ;
int ret = qemudDomainUndefine ( server , in - > data . domainUndefineRequest . uuid ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_UNDEFINE ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
2007-02-14 15:54:10 +00:00
static int qemudDispatchNumNetworks ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = 0 )
return - 1 ;
int nnetworks = qemudNumNetworks ( server ) ;
if ( nnetworks < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NUM_NETWORKS ;
out - > header . dataSize = sizeof ( out - > data . numNetworksReply ) ;
out - > data . numNetworksReply . numNetworks = nnetworks ;
}
return 0 ;
}
static int qemudDispatchListNetworks ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
char * * names ;
int i ;
if ( in - > header . dataSize ! = 0 )
return - 1 ;
if ( ! ( names = malloc ( sizeof ( char * ) * QEMUD_MAX_NUM_NETWORKS ) ) )
return - 1 ;
for ( i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i + + ) {
names [ i ] = out - > data . listNetworksReply . networks [ i ] ;
}
int nnetworks = qemudListNetworks ( server ,
names ,
QEMUD_MAX_NUM_NETWORKS ) ;
free ( names ) ;
if ( nnetworks < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_LIST_NETWORKS ;
out - > header . dataSize = sizeof ( out - > data . listNetworksReply ) ;
out - > data . listNetworksReply . numNetworks = nnetworks ;
}
return 0 ;
}
static int qemudDispatchNumDefinedNetworks ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = 0 )
return - 1 ;
int nnetworks = qemudNumDefinedNetworks ( server ) ;
if ( nnetworks < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NUM_DEFINED_NETWORKS ;
out - > header . dataSize = sizeof ( out - > data . numDefinedNetworksReply ) ;
out - > data . numDefinedNetworksReply . numNetworks = nnetworks ;
}
return 0 ;
}
static int qemudDispatchListDefinedNetworks ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
char * * names ;
int i ;
if ( in - > header . dataSize ! = 0 )
return - 1 ;
if ( ! ( names = malloc ( sizeof ( char * ) * QEMUD_MAX_NUM_NETWORKS ) ) )
return - 1 ;
for ( i = 0 ; i < QEMUD_MAX_NUM_NETWORKS ; i + + ) {
names [ i ] = out - > data . listDefinedNetworksReply . networks [ i ] ;
}
int nnetworks = qemudListDefinedNetworks ( server ,
names ,
QEMUD_MAX_NUM_NETWORKS ) ;
free ( names ) ;
if ( nnetworks < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_LIST_DEFINED_NETWORKS ;
out - > header . dataSize = sizeof ( out - > data . listDefinedNetworksReply ) ;
out - > data . listDefinedNetworksReply . numNetworks = nnetworks ;
}
return 0 ;
}
static int qemudDispatchNetworkLookupByName ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkLookupByNameRequest ) )
return - 1 ;
/* Paranoia NULL termination */
in - > data . networkLookupByNameRequest . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
struct qemud_network * network = qemudFindNetworkByName ( server , in - > data . networkLookupByNameRequest . name ) ;
if ( ! network ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_LOOKUP_BY_NAME ;
out - > header . dataSize = sizeof ( out - > data . networkLookupByNameReply ) ;
2007-02-15 16:00:16 +00:00
memcpy ( out - > data . networkLookupByNameReply . uuid , network - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
2007-02-14 15:54:10 +00:00
}
return 0 ;
}
static int qemudDispatchNetworkLookupByUUID ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkLookupByUUIDRequest ) )
return - 1 ;
struct qemud_network * network = qemudFindNetworkByUUID ( server , in - > data . networkLookupByUUIDRequest . uuid ) ;
if ( ! network ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID ;
out - > header . dataSize = sizeof ( out - > data . networkLookupByUUIDReply ) ;
2007-02-15 16:00:16 +00:00
strncpy ( out - > data . networkLookupByUUIDReply . name , network - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 15:54:10 +00:00
out - > data . networkLookupByUUIDReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchNetworkCreate ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkCreateRequest ) )
return - 1 ;
in - > data . networkCreateRequest . xml [ QEMUD_MAX_XML_LEN - 1 ] = ' \0 ' ;
struct qemud_network * network = qemudNetworkCreate ( server , in - > data . networkCreateRequest . xml ) ;
if ( ! network ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_CREATE ;
out - > header . dataSize = sizeof ( out - > data . networkCreateReply ) ;
2007-02-15 16:00:16 +00:00
memcpy ( out - > data . networkCreateReply . uuid , network - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
strncpy ( out - > data . networkCreateReply . name , network - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 15:54:10 +00:00
out - > data . networkCreateReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchNetworkDefine ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkDefineRequest ) )
return - 1 ;
in - > data . networkDefineRequest . xml [ QEMUD_MAX_XML_LEN - 1 ] = ' \0 ' ;
struct qemud_network * network = qemudNetworkDefine ( server , in - > data . networkDefineRequest . xml ) ;
if ( ! network ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_DEFINE ;
out - > header . dataSize = sizeof ( out - > data . networkDefineReply ) ;
2007-02-15 16:00:16 +00:00
memcpy ( out - > data . networkDefineReply . uuid , network - > def - > uuid , QEMUD_UUID_RAW_LEN ) ;
strncpy ( out - > data . networkDefineReply . name , network - > def - > name , QEMUD_MAX_NAME_LEN - 1 ) ;
2007-02-14 15:54:10 +00:00
out - > data . networkDefineReply . name [ QEMUD_MAX_NAME_LEN - 1 ] = ' \0 ' ;
}
return 0 ;
}
static int qemudDispatchNetworkUndefine ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkUndefineRequest ) )
return - 1 ;
int ret = qemudNetworkUndefine ( server , in - > data . networkUndefineRequest . uuid ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_UNDEFINE ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchNetworkStart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
2007-02-23 08:41:23 +00:00
struct qemud_network * network ;
2007-02-14 15:54:10 +00:00
if ( in - > header . dataSize ! = sizeof ( in - > data . networkStartRequest ) )
return - 1 ;
2007-02-23 08:41:23 +00:00
if ( ! ( network = qemudNetworkStart ( server , in - > data . networkStartRequest . uuid ) ) ) {
2007-02-14 15:54:10 +00:00
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_START ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchNetworkDestroy ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkDestroyRequest ) )
return - 1 ;
2007-02-23 08:41:23 +00:00
if ( qemudNetworkDestroy ( server , in - > data . networkDestroyRequest . uuid ) < 0 ) {
2007-02-14 15:54:10 +00:00
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_DESTROY ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchNetworkDumpXML ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkDumpXMLRequest ) )
return - 1 ;
int ret = qemudNetworkDumpXML ( server ,
in - > data . networkDumpXMLRequest . uuid ,
out - > data . networkDumpXMLReply . xml , QEMUD_MAX_XML_LEN ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_DUMP_XML ;
out - > header . dataSize = sizeof ( out - > data . networkDumpXMLReply ) ;
}
return 0 ;
}
2007-02-14 16:20:38 +00:00
static int qemudDispatchNetworkGetBridgeName ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
if ( in - > header . dataSize ! = sizeof ( in - > data . networkGetBridgeNameRequest ) )
return - 1 ;
int ret = qemudNetworkGetBridgeName ( server ,
in - > data . networkDumpXMLRequest . uuid ,
out - > data . networkGetBridgeNameReply . ifname , QEMUD_MAX_IFNAME_LEN ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_GET_BRIDGE_NAME ;
out - > header . dataSize = sizeof ( out - > data . networkGetBridgeNameReply ) ;
}
return 0 ;
}
2007-02-23 09:03:25 +00:00
static int qemudDispatchDomainGetAutostart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out )
{
int ret ;
int autostart ;
if ( in - > header . dataSize ! = sizeof ( in - > data . domainGetAutostartRequest ) )
return - 1 ;
autostart = 0 ;
ret = qemudDomainGetAutostart ( server ,
in - > data . domainGetAutostartRequest . uuid ,
& autostart ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_GET_AUTOSTART ;
out - > header . dataSize = sizeof ( out - > data . networkGetAutostartReply ) ;
out - > data . networkGetAutostartReply . autostart = ( autostart ! = 0 ) ;
}
return 0 ;
}
static int qemudDispatchDomainSetAutostart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out )
{
int ret ;
if ( in - > header . dataSize ! = sizeof ( in - > data . domainSetAutostartRequest ) )
return - 1 ;
ret = qemudDomainSetAutostart ( server ,
in - > data . domainGetAutostartRequest . uuid ,
in - > data . domainSetAutostartRequest . autostart ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_DOMAIN_SET_AUTOSTART ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
static int qemudDispatchNetworkGetAutostart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out )
{
int ret ;
int autostart ;
if ( in - > header . dataSize ! = sizeof ( in - > data . networkGetAutostartRequest ) )
return - 1 ;
autostart = 0 ;
ret = qemudNetworkGetAutostart ( server ,
in - > data . networkGetAutostartRequest . uuid ,
& autostart ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_GET_AUTOSTART ;
out - > header . dataSize = sizeof ( out - > data . networkGetAutostartReply ) ;
out - > data . networkGetAutostartReply . autostart = ( autostart ! = 0 ) ;
}
return 0 ;
}
static int qemudDispatchNetworkSetAutostart ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out )
{
int ret ;
if ( in - > header . dataSize ! = sizeof ( in - > data . networkSetAutostartRequest ) )
return - 1 ;
ret = qemudNetworkSetAutostart ( server ,
in - > data . networkGetAutostartRequest . uuid ,
in - > data . networkSetAutostartRequest . autostart ) ;
if ( ret < 0 ) {
if ( qemudDispatchFailure ( server , client , out ) < 0 )
return - 1 ;
} else {
out - > header . type = QEMUD_PKT_NETWORK_SET_AUTOSTART ;
out - > header . dataSize = 0 ;
}
return 0 ;
}
2007-02-14 01:40:09 +00:00
typedef int ( * clientFunc ) ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) ;
/* One per message type recorded in qemud_packet_type enum */
clientFunc funcsTransmitRW [ QEMUD_PKT_MAX ] = {
NULL , /* FAILURE code */
qemudDispatchGetVersion ,
qemudDispatchGetNodeInfo ,
qemudDispatchListDomains ,
qemudDispatchNumDomains ,
qemudDispatchDomainCreate ,
qemudDispatchDomainLookupByID ,
qemudDispatchDomainLookupByUUID ,
qemudDispatchDomainLookupByName ,
qemudDispatchDomainSuspend ,
qemudDispatchDomainResume ,
qemudDispatchDomainDestroy ,
qemudDispatchDomainGetInfo ,
qemudDispatchDomainSave ,
qemudDispatchDomainRestore ,
qemudDispatchDumpXML ,
qemudDispatchListDefinedDomains ,
qemudDispatchNumDefinedDomains ,
qemudDispatchDomainStart ,
qemudDispatchDomainDefine ,
2007-02-14 15:54:10 +00:00
qemudDispatchDomainUndefine ,
qemudDispatchNumNetworks ,
qemudDispatchListNetworks ,
qemudDispatchNumDefinedNetworks ,
qemudDispatchListDefinedNetworks ,
qemudDispatchNetworkLookupByUUID ,
qemudDispatchNetworkLookupByName ,
qemudDispatchNetworkCreate ,
qemudDispatchNetworkDefine ,
qemudDispatchNetworkUndefine ,
qemudDispatchNetworkStart ,
qemudDispatchNetworkDestroy ,
qemudDispatchNetworkDumpXML ,
2007-02-14 16:20:38 +00:00
qemudDispatchNetworkGetBridgeName ,
2007-02-23 09:03:25 +00:00
qemudDispatchDomainGetAutostart ,
qemudDispatchDomainSetAutostart ,
qemudDispatchNetworkGetAutostart ,
qemudDispatchNetworkSetAutostart ,
2007-02-14 01:40:09 +00:00
} ;
clientFunc funcsTransmitRO [ QEMUD_PKT_MAX ] = {
NULL , /* FAILURE code */
qemudDispatchGetVersion ,
qemudDispatchGetNodeInfo ,
qemudDispatchListDomains ,
qemudDispatchNumDomains ,
NULL ,
qemudDispatchDomainLookupByID ,
qemudDispatchDomainLookupByUUID ,
qemudDispatchDomainLookupByName ,
NULL ,
NULL ,
NULL ,
qemudDispatchDomainGetInfo ,
NULL ,
NULL ,
qemudDispatchDumpXML ,
qemudDispatchListDefinedDomains ,
qemudDispatchNumDefinedDomains ,
NULL ,
NULL ,
NULL ,
2007-02-14 15:54:10 +00:00
qemudDispatchNumNetworks ,
qemudDispatchListNetworks ,
qemudDispatchNumDefinedNetworks ,
qemudDispatchListDefinedNetworks ,
qemudDispatchNetworkLookupByUUID ,
qemudDispatchNetworkLookupByName ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
qemudDispatchNetworkDumpXML ,
2007-02-14 16:20:38 +00:00
qemudDispatchNetworkGetBridgeName ,
2007-02-23 09:03:25 +00:00
qemudDispatchDomainGetAutostart ,
NULL ,
qemudDispatchNetworkGetAutostart ,
NULL ,
2007-02-14 01:40:09 +00:00
} ;
/*
* Returns - 1 if message processing failed - eg , illegal header sizes ,
* a memory error dealing with stuff , or any other bad stuff which
* should trigger immediate client disconnect
*
* Return 0 if message processing succeeded . NB , this does not mean
* the operation itself succeeded - success / failure of the operation
* is recorded by the return message type - either it matches the
* incoming type , or is QEMUD_PKT_FAILURE
*/
int qemudDispatch ( struct qemud_server * server , struct qemud_client * client ,
struct qemud_packet * in , struct qemud_packet * out ) {
clientFunc * funcs ;
unsigned int type = in - > header . type ;
2007-02-16 18:30:55 +00:00
qemudDebug ( " > Dispatching request %d readonly ? %d " , type , client - > readonly ) ;
2007-02-14 01:40:09 +00:00
server - > errorCode = 0 ;
server - > errorMessage [ 0 ] = ' \0 ' ;
memset ( out , 0 , sizeof ( struct qemud_packet ) ) ;
if ( type > = QEMUD_PKT_MAX ) {
2007-02-16 18:30:55 +00:00
qemudDebug ( " Illegal request type " ) ;
2007-02-14 01:40:09 +00:00
return - 1 ;
}
if ( type = = QEMUD_PKT_FAILURE ) {
2007-02-16 18:30:55 +00:00
qemudDebug ( " Illegal request type " ) ;
2007-02-14 01:40:09 +00:00
return - 1 ;
}
if ( client - > readonly )
funcs = funcsTransmitRO ;
else
funcs = funcsTransmitRW ;
if ( ! funcs [ type ] ) {
2007-02-16 18:30:55 +00:00
qemudDebug ( " Illegal operation requested " ) ;
2007-02-14 01:40:09 +00:00
qemudReportError ( server , VIR_ERR_OPERATION_DENIED , NULL ) ;
qemudDispatchFailure ( server , client , out ) ;
} else {
if ( ( funcs [ type ] ) ( server , client , in , out ) < 0 ) {
2007-02-16 18:30:55 +00:00
qemudDebug ( " Dispatch failed " ) ;
2007-02-14 01:40:09 +00:00
return - 1 ;
}
}
2007-02-16 18:30:55 +00:00
qemudDebug ( " < Returning reply %d (%d bytes) " ,
2007-02-14 01:40:09 +00:00
out - > header . type ,
out - > header . dataSize ) ;
return 0 ;
}
/*
* Local variables :
* indent - tabs - mode : nil
* c - indent - level : 4
* c - basic - offset : 4
* tab - width : 4
* End :
*/