2005-11-10 19:12:31 +03:00
/*
2007-01-26 14:54:29 +03:00
* virsh . c : a Xen shell used to exercise the libvirt API
2005-11-10 19:12:31 +03:00
*
2007-11-08 19:14:12 +03:00
* Copyright ( C ) 2005 , 2007 Red Hat , Inc .
2005-11-10 19:12:31 +03:00
*
* See COPYING . LIB for the License of this software
*
* Daniel Veillard < veillard @ redhat . com >
2005-12-08 17:22:52 +03:00
* Karel Zak < kzak @ redhat . com >
2006-05-29 19:39:31 +04:00
* Daniel P . Berrange < berrange @ redhat . com >
*
2005-12-08 17:22:52 +03:00
*
* $ Id $
2005-11-10 19:12:31 +03:00
*/
2007-12-04 21:27:52 +03:00
# include "config.h"
2006-06-26 19:02:18 +04:00
# include "libvirt/libvirt.h"
# include "libvirt/virterror.h"
2005-11-10 19:12:31 +03:00
# include <stdio.h>
2005-12-08 13:23:34 +03:00
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
2005-12-01 19:35:42 +03:00
# include <unistd.h>
2007-05-23 19:09:19 +04:00
# include <errno.h>
2005-12-08 13:23:34 +03:00
# include <getopt.h>
2005-12-01 19:35:42 +03:00
# include <sys/types.h>
2005-12-08 17:22:52 +03:00
# include <sys/time.h>
2005-12-08 13:23:34 +03:00
# include <ctype.h>
2006-03-30 20:08:13 +04:00
# include <fcntl.h>
2006-09-29 20:23:27 +04:00
# include <locale.h>
2007-11-29 12:18:04 +03:00
# include <time.h>
2007-06-15 19:24:20 +04:00
# include <limits.h>
2007-06-05 16:06:08 +04:00
# include <assert.h>
2007-06-06 16:24:31 +04:00
# include <errno.h>
# include <sys/stat.h>
2007-08-21 14:08:12 +04:00
# include <inttypes.h>
2007-08-07 19:26:51 +04:00
# include <test.h>
2005-12-08 13:23:34 +03:00
2007-01-26 14:54:29 +03:00
# include <libxml/parser.h>
# include <libxml/tree.h>
# include <libxml/xpath.h>
2007-12-04 21:27:52 +03:00
# ifdef HAVE_READLINE_READLINE_H
2005-12-08 13:23:34 +03:00
# include <readline/readline.h>
# include <readline/history.h>
2007-12-04 21:27:52 +03:00
# endif
2005-12-08 13:23:34 +03:00
2005-12-08 18:08:46 +03:00
# include "internal.h"
2007-01-26 14:54:29 +03:00
# include "console.h"
2005-12-08 13:23:34 +03:00
static char * progname ;
# ifndef TRUE
# define TRUE 1
# define FALSE 0
# endif
# define VSH_PROMPT_RW "virsh # "
# define VSH_PROMPT_RO "virsh > "
# define GETTIMEOFDAY(T) gettimeofday(T, NULL)
# define DIFF_MSEC(T, U) \
( ( ( ( int ) ( ( T ) - > tv_sec - ( U ) - > tv_sec ) ) * 1000000.0 + \
( ( int ) ( ( T ) - > tv_usec - ( U ) - > tv_usec ) ) ) / 1000.0 )
2007-06-06 16:24:31 +04:00
/**
* The log configuration
*/
# define MSG_BUFFER 4096
# define SIGN_NAME "virsh"
# define DIR_MODE (S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) /* 0755 */
# define FILE_MODE (S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) /* 0644 */
# define LOCK_MODE (S_IWUSR | S_IRUSR) /* 0600 */
# define LVL_DEBUG "DEBUG"
# define LVL_INFO "INFO"
# define LVL_NOTICE "NOTICE"
# define LVL_WARNING "WARNING"
# define LVL_ERROR "ERROR"
/**
* vshErrorLevel :
*
* Indicates the level of an log message
*/
typedef enum {
VSH_ERR_DEBUG = 0 ,
VSH_ERR_INFO ,
VSH_ERR_NOTICE ,
VSH_ERR_WARNING ,
VSH_ERR_ERROR
} vshErrorLevel ;
2006-02-28 00:34:28 +03:00
/*
* The error handler for virtsh
*/
static void
2006-03-15 15:13:25 +03:00
virshErrorHandler ( void * unused , virErrorPtr error )
{
2006-02-28 00:34:28 +03:00
if ( ( unused ! = NULL ) | | ( error = = NULL ) )
return ;
/* Suppress the VIR_ERR_NO_XEN error which fails as non-root */
if ( ( error - > code = = VIR_ERR_NO_XEN ) | | ( error - > code = = VIR_ERR_OK ) )
return ;
virDefaultErrorFunc ( error ) ;
}
2005-12-08 13:23:34 +03:00
/*
* virsh command line grammar :
*
* command_line = < command > \ n | < command > ; < command > ; . . .
*
* command = < keyword > < option > < data >
*
* option = < bool_option > | < int_option > | < string_option >
* data = < string >
*
* bool_option = - - optionname
* int_option = - - optionname < number >
* string_option = - - optionname < string >
2007-02-07 16:50:18 +03:00
*
2006-01-25 12:46:22 +03:00
* keyword = [ a - zA - Z ]
* number = [ 0 - 9 ] +
* string = [ ^ [ : blank : ] ] | " [[:alnum:]] " $
2005-12-08 13:23:34 +03:00
*
*/
/*
2007-02-07 16:50:18 +03:00
* vshCmdOptType - command option type
2006-03-15 15:13:25 +03:00
*/
2005-12-08 13:23:34 +03:00
typedef enum {
2006-03-15 15:13:25 +03:00
VSH_OT_NONE = 0 , /* none */
VSH_OT_BOOL , /* boolean option */
VSH_OT_STRING , /* string option */
VSH_OT_INT , /* int option */
VSH_OT_DATA /* string data (as non-option) */
2005-12-08 13:23:34 +03:00
} vshCmdOptType ;
/*
* Command Option Flags
*/
2006-03-15 15:13:25 +03:00
# define VSH_OFLAG_NONE 0 /* without flags */
# define VSH_OFLAG_REQ (1 << 1) /* option required */
2005-12-08 13:23:34 +03:00
/* dummy */
typedef struct __vshControl vshControl ;
typedef struct __vshCmd vshCmd ;
/*
* vshCmdInfo - - information about command
*/
2006-03-15 15:13:25 +03:00
typedef struct {
const char * name ; /* name of information */
const char * data ; /* information */
2005-12-08 13:23:34 +03:00
} vshCmdInfo ;
/*
* vshCmdOptDef - command option definition
*/
2006-03-15 15:13:25 +03:00
typedef struct {
const char * name ; /* the name of option */
vshCmdOptType type ; /* option type */
int flag ; /* flags */
const char * help ; /* help string */
2005-12-08 13:23:34 +03:00
} vshCmdOptDef ;
/*
* vshCmdOpt - command options
*/
typedef struct vshCmdOpt {
2006-03-15 15:13:25 +03:00
vshCmdOptDef * def ; /* pointer to relevant option */
char * data ; /* allocated data */
struct vshCmdOpt * next ;
2005-12-08 13:23:34 +03:00
} vshCmdOpt ;
/*
* vshCmdDef - command definition
*/
2006-03-15 15:13:25 +03:00
typedef struct {
const char * name ;
int ( * handler ) ( vshControl * , vshCmd * ) ; /* command handler */
vshCmdOptDef * opts ; /* definition of command options */
vshCmdInfo * info ; /* details about command */
2005-12-08 13:23:34 +03:00
} vshCmdDef ;
/*
* vshCmd - parsed command
*/
typedef struct __vshCmd {
2006-03-15 15:13:25 +03:00
vshCmdDef * def ; /* command definition */
vshCmdOpt * opts ; /* list of command arguments */
struct __vshCmd * next ; /* next command */
2005-12-08 13:23:34 +03:00
} __vshCmd ;
/*
* vshControl
*/
typedef struct __vshControl {
2006-05-29 19:39:31 +04:00
char * name ; /* connection name */
2007-06-20 21:22:09 +04:00
virConnectPtr conn ; /* connection to hypervisor (MAY BE NULL) */
2006-03-15 15:13:25 +03:00
vshCmd * cmd ; /* the current command */
char * cmdstr ; /* string with command */
uid_t uid ; /* process owner */
int imode ; /* interactive mode? */
int quiet ; /* quiet mode */
int debug ; /* print debug messages? */
int timing ; /* print timing info? */
2007-03-08 16:48:22 +03:00
int readonly ; /* connect readonly (first time only, not
* during explicit connect command )
*/
2007-06-06 16:24:31 +04:00
char * logfile ; /* log file name */
int log_fd ; /* log file descriptor */
2005-12-08 13:23:34 +03:00
} __vshControl ;
2005-11-10 19:12:31 +03:00
2005-12-02 17:16:21 +03:00
2005-12-08 13:23:34 +03:00
static vshCmdDef commands [ ] ;
2007-03-19 17:20:30 +03:00
static void vshError ( vshControl * ctl , int doexit , const char * format , . . . )
ATTRIBUTE_FORMAT ( printf , 3 , 4 ) ;
2006-03-15 15:13:25 +03:00
static int vshInit ( vshControl * ctl ) ;
static int vshDeinit ( vshControl * ctl ) ;
static void vshUsage ( vshControl * ctl , const char * cmdname ) ;
2007-06-06 16:24:31 +04:00
static void vshOpenLogFile ( vshControl * ctl ) ;
static void vshOutputLogFile ( vshControl * ctl , int log_level , const char * format , va_list ap ) ;
static void vshCloseLogFile ( vshControl * ctl ) ;
2005-12-08 13:23:34 +03:00
2006-03-15 15:13:25 +03:00
static int vshParseArgv ( vshControl * ctl , int argc , char * * argv ) ;
2005-12-08 13:23:34 +03:00
2006-03-15 15:13:25 +03:00
static const char * vshCmddefGetInfo ( vshCmdDef * cmd , const char * info ) ;
2005-12-08 17:22:52 +03:00
static vshCmdDef * vshCmddefSearch ( const char * cmdname ) ;
2006-03-15 15:13:25 +03:00
static int vshCmddefHelp ( vshControl * ctl , const char * name , int withprog ) ;
2005-12-08 13:23:34 +03:00
2006-03-15 15:13:25 +03:00
static vshCmdOpt * vshCommandOpt ( vshCmd * cmd , const char * name ) ;
static int vshCommandOptInt ( vshCmd * cmd , const char * name , int * found ) ;
static char * vshCommandOptString ( vshCmd * cmd , const char * name ,
int * found ) ;
static int vshCommandOptBool ( vshCmd * cmd , const char * name ) ;
2006-05-29 19:39:31 +04:00
2007-02-14 18:44:58 +03:00
# define VSH_BYID (1 << 1)
# define VSH_BYUUID (1 << 2)
# define VSH_BYNAME (1 << 3)
2006-05-29 19:39:31 +04:00
static virDomainPtr vshCommandOptDomainBy ( vshControl * ctl , vshCmd * cmd ,
2007-02-07 16:50:18 +03:00
const char * optname , char * * name , int flag ) ;
2006-05-29 19:39:31 +04:00
/* default is lookup by Id, Name and UUID */
2007-02-07 16:50:18 +03:00
# define vshCommandOptDomain(_ctl, _cmd, _optname, _name) \
vshCommandOptDomainBy ( _ctl , _cmd , _optname , _name , \
2007-02-14 18:44:58 +03:00
VSH_BYID | VSH_BYUUID | VSH_BYNAME )
2007-02-14 19:53:55 +03:00
static virNetworkPtr vshCommandOptNetworkBy ( vshControl * ctl , vshCmd * cmd ,
const char * optname , char * * name , int flag ) ;
/* default is lookup by Name and UUID */
# define vshCommandOptNetwork(_ctl, _cmd, _optname, _name) \
vshCommandOptNetworkBy ( _ctl , _cmd , _optname , _name , \
VSH_BYUUID | VSH_BYNAME )
2007-11-08 21:00:52 +03:00
static void vshPrintExtra ( vshControl * ctl , const char * format , . . . )
ATTRIBUTE_FORMAT ( printf , 2 , 3 ) ;
static void vshDebug ( vshControl * ctl , int level , const char * format , . . . )
ATTRIBUTE_FORMAT ( printf , 3 , 4 ) ;
2006-05-29 19:39:31 +04:00
/* XXX: add batch support */
2006-05-22 18:38:33 +04:00
# define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
2005-12-08 13:23:34 +03:00
2005-12-08 17:22:52 +03:00
static const char * vshDomainStateToString ( int state ) ;
2006-08-07 18:35:20 +04:00
static const char * vshDomainVcpuStateToString ( int state ) ;
2006-03-15 15:13:25 +03:00
static int vshConnectionUsability ( vshControl * ctl , virConnectPtr conn ,
int showerror ) ;
2005-12-08 13:23:34 +03:00
2006-04-06 14:33:06 +04:00
static void * _vshMalloc ( vshControl * ctl , size_t sz , const char * filename , int line ) ;
# define vshMalloc(_ctl, _sz) _vshMalloc(_ctl, _sz, __FILE__, __LINE__)
static void * _vshCalloc ( vshControl * ctl , size_t nmemb , size_t sz , const char * filename , int line ) ;
# define vshCalloc(_ctl, _nmemb, _sz) _vshCalloc(_ctl, _nmemb, _sz, __FILE__, __LINE__)
2007-06-19 13:12:55 +04:00
static void * _vshRealloc ( vshControl * ctl , void * ptr , size_t sz , const char * filename , int line ) ;
# define vshRealloc(_ctl, _ptr, _sz) _vshRealloc(_ctl, _ptr, _sz, __FILE__, __LINE__)
2006-04-06 14:33:06 +04:00
static char * _vshStrdup ( vshControl * ctl , const char * s , const char * filename , int line ) ;
# define vshStrdup(_ctl, _s) _vshStrdup(_ctl, _s, __FILE__, __LINE__)
2007-02-14 18:44:58 +03:00
static int idsorter ( const void * a , const void * b ) {
const int * ia = ( const int * ) a ;
const int * ib = ( const int * ) b ;
if ( * ia > * ib )
return 1 ;
else if ( * ia < * ib )
return - 1 ;
return 0 ;
}
static int namesorter ( const void * a , const void * b ) {
const char * * sa = ( const char * * ) a ;
const char * * sb = ( const char * * ) b ;
return strcasecmp ( * sa , * sb ) ;
}
2005-12-08 13:23:34 +03:00
/* ---------------
* Commands
* - - - - - - - - - - - - - - -
*/
/*
2007-02-07 16:50:18 +03:00
* " help " command
2005-12-08 13:23:34 +03:00
*/
static vshCmdInfo info_help [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " help [<command>] " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " print help " ) } ,
{ " desc " , gettext_noop ( " Prints global help or command specific help. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
static vshCmdOptDef opts_help [ ] = {
2007-06-13 13:32:44 +04:00
{ " command " , VSH_OT_DATA , 0 , gettext_noop ( " name of command " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdHelp ( vshControl * ctl , vshCmd * cmd )
{
2005-12-08 17:22:52 +03:00
const char * cmdname = vshCommandOptString ( cmd , " command " , NULL ) ;
2005-12-08 13:23:34 +03:00
if ( ! cmdname ) {
vshCmdDef * def ;
2006-03-15 15:13:25 +03:00
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Commands: \n \n " ) ) ;
2006-03-15 15:13:25 +03:00
for ( def = commands ; def - > name ; def + + )
2006-05-22 18:38:33 +04:00
vshPrint ( ctl , " %-15s %s \n " , def - > name ,
2007-06-15 12:18:55 +04:00
N_ ( vshCmddefGetInfo ( def , " help " ) ) ) ;
2005-12-08 13:23:34 +03:00
return TRUE ;
}
return vshCmddefHelp ( ctl , cmdname , FALSE ) ;
}
2007-02-23 11:58:25 +03:00
/*
* " autostart " command
*/
static vshCmdInfo info_autostart [ ] = {
{ " syntax " , " autostart [--disable] <domain> " } ,
{ " help " , gettext_noop ( " autostart a domain " ) } ,
{ " desc " ,
gettext_noop ( " Configure a domain to be automatically started at boot. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_autostart [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " disable " , VSH_OT_BOOL , 0 , gettext_noop ( " disable autostarting " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdAutostart ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * name ;
int autostart ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
autostart = ! vshCommandOptBool ( cmd , " disable " ) ;
if ( virDomainSetAutostart ( dom , autostart ) < 0 ) {
2007-04-13 12:04:08 +04:00
if ( autostart )
vshError ( ctl , FALSE , _ ( " Failed to mark domain %s as autostarted " ) ,
name ) ;
else
vshError ( ctl , FALSE , _ ( " Failed to unmark domain %s as autostarted " ) ,
name ) ;
2007-02-23 11:58:25 +03:00
virDomainFree ( dom ) ;
return FALSE ;
}
2007-04-13 12:04:08 +04:00
if ( autostart )
vshPrint ( ctl , _ ( " Domain %s marked as autostarted \n " ) , name ) ;
else
vshPrint ( ctl , _ ( " Domain %s unmarked as autostarted \n " ) , name ) ;
2007-02-23 11:58:25 +03:00
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2007-02-23 11:58:25 +03:00
return TRUE ;
}
2005-12-08 13:23:34 +03:00
/*
2007-02-07 16:50:18 +03:00
* " connect " command
2005-12-08 13:23:34 +03:00
*/
static vshCmdInfo info_connect [ ] = {
2006-05-29 19:39:31 +04:00
{ " syntax " , " connect [name] [--readonly] " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " (re)connect to hypervisor " ) } ,
2006-03-15 15:13:25 +03:00
{ " desc " ,
2006-09-21 19:24:37 +04:00
gettext_noop ( " Connect to local hypervisor. This is built-in command after shell start up. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
static vshCmdOptDef opts_connect [ ] = {
2006-09-21 19:24:37 +04:00
{ " name " , VSH_OT_DATA , 0 , gettext_noop ( " hypervisor connection URI " ) } ,
{ " readonly " , VSH_OT_BOOL , 0 , gettext_noop ( " read-only connection " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdConnect ( vshControl * ctl , vshCmd * cmd )
{
2005-12-08 13:23:34 +03:00
int ro = vshCommandOptBool ( cmd , " readonly " ) ;
2007-02-07 16:50:18 +03:00
2005-12-08 13:23:34 +03:00
if ( ctl - > conn ) {
2006-03-15 15:13:25 +03:00
if ( virConnectClose ( ctl - > conn ) ! = 0 ) {
vshError ( ctl , FALSE ,
2006-09-21 19:24:37 +04:00
_ ( " Failed to disconnect from the hypervisor " ) ) ;
2005-12-08 13:23:34 +03:00
return FALSE ;
}
ctl - > conn = NULL ;
}
2007-02-07 16:50:18 +03:00
2006-05-29 19:39:31 +04:00
if ( ctl - > name )
free ( ctl - > name ) ;
2007-01-22 23:43:02 +03:00
ctl - > name = vshStrdup ( ctl , vshCommandOptString ( cmd , " name " , NULL ) ) ;
2006-05-29 19:39:31 +04:00
2007-03-08 16:48:22 +03:00
if ( ! ro ) {
2006-05-29 19:39:31 +04:00
ctl - > conn = virConnectOpen ( ctl - > name ) ;
2007-03-08 16:48:22 +03:00
ctl - > readonly = 0 ;
} else {
2006-05-29 19:39:31 +04:00
ctl - > conn = virConnectOpenReadOnly ( ctl - > name ) ;
2007-03-08 16:48:22 +03:00
ctl - > readonly = 1 ;
}
2005-12-08 13:23:34 +03:00
if ( ! ctl - > conn )
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to connect to the hypervisor " ) ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
return ctl - > conn ? TRUE : FALSE ;
}
2007-01-26 14:54:29 +03:00
/*
2007-02-07 16:50:18 +03:00
* " console " command
2007-01-26 14:54:29 +03:00
*/
static vshCmdInfo info_console [ ] = {
{ " syntax " , " console <domain> " } ,
{ " help " , gettext_noop ( " connect to the guest console " ) } ,
{ " desc " ,
gettext_noop ( " Connect the virtual serial console for the guest " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_console [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdConsole ( vshControl * ctl , vshCmd * cmd )
{
xmlDocPtr xml = NULL ;
xmlXPathObjectPtr obj = NULL ;
xmlXPathContextPtr ctxt = NULL ;
virDomainPtr dom ;
int ret = FALSE ;
char * doc ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
doc = virDomainGetXMLDesc ( dom , 0 ) ;
if ( ! doc )
2007-02-07 16:50:18 +03:00
goto cleanup ;
2007-01-26 14:54:29 +03:00
xml = xmlReadDoc ( ( const xmlChar * ) doc , " domain.xml " , NULL ,
2007-02-07 16:50:18 +03:00
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOWARNING ) ;
2007-01-26 14:54:29 +03:00
free ( doc ) ;
if ( ! xml )
goto cleanup ;
ctxt = xmlXPathNewContext ( xml ) ;
if ( ! ctxt )
goto cleanup ;
obj = xmlXPathEval ( BAD_CAST " string(/domain/devices/console/@tty) " , ctxt ) ;
if ( ( obj ! = NULL ) & & ( ( obj - > type = = XPATH_STRING ) & &
2007-02-07 16:50:18 +03:00
( obj - > stringval ! = NULL ) & & ( obj - > stringval [ 0 ] ! = 0 ) ) ) {
2007-01-28 22:47:36 +03:00
if ( vshRunConsole ( ( const char * ) obj - > stringval ) = = 0 )
2007-01-26 14:54:29 +03:00
ret = TRUE ;
} else {
vshPrintExtra ( ctl , _ ( " No console available for domain \n " ) ) ;
}
xmlXPathFreeObject ( obj ) ;
cleanup :
if ( ctxt )
xmlXPathFreeContext ( ctxt ) ;
if ( xml )
xmlFreeDoc ( xml ) ;
virDomainFree ( dom ) ;
return ret ;
}
2005-12-08 13:23:34 +03:00
/*
* " list " command
*/
static vshCmdInfo info_list [ ] = {
2007-01-23 15:28:38 +03:00
{ " syntax " , " list [--inactive | --all] " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " list domains " ) } ,
{ " desc " , gettext_noop ( " Returns list of domains. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
2006-08-30 18:32:32 +04:00
static vshCmdOptDef opts_list [ ] = {
2006-09-21 19:24:37 +04:00
{ " inactive " , VSH_OT_BOOL , 0 , gettext_noop ( " list inactive domains " ) } ,
{ " all " , VSH_OT_BOOL , 0 , gettext_noop ( " list inactive & active domains " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , 0 , 0 , NULL }
} ;
2005-12-08 13:23:34 +03:00
static int
2006-03-15 15:13:25 +03:00
cmdList ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
2006-08-30 18:32:32 +04:00
int inactive = vshCommandOptBool ( cmd , " inactive " ) ;
int all = vshCommandOptBool ( cmd , " all " ) ;
int active = ! inactive | | all ? 1 : 0 ;
int * ids = NULL , maxid = 0 , i ;
2007-03-07 00:55:44 +03:00
char * * names = NULL ;
2006-08-30 18:32:32 +04:00
int maxname = 0 ;
inactive | = all ;
2005-12-08 13:23:34 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2007-02-07 16:50:18 +03:00
2006-08-30 18:32:32 +04:00
if ( active ) {
2007-02-07 16:50:18 +03:00
maxid = virConnectNumOfDomains ( ctl - > conn ) ;
if ( maxid < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list active domains " ) ) ;
return FALSE ;
}
if ( maxid ) {
ids = vshMalloc ( ctl , sizeof ( int ) * maxid ) ;
if ( ( maxid = virConnectListDomains ( ctl - > conn , & ids [ 0 ] , maxid ) ) < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list active domains " ) ) ;
free ( ids ) ;
return FALSE ;
}
2007-02-14 18:44:58 +03:00
qsort ( & ids [ 0 ] , maxid , sizeof ( int ) , idsorter ) ;
2006-08-26 02:40:33 +04:00
}
2006-08-30 18:32:32 +04:00
}
if ( inactive ) {
2007-02-07 16:50:18 +03:00
maxname = virConnectNumOfDefinedDomains ( ctl - > conn ) ;
if ( maxname < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list inactive domains " ) ) ;
if ( ids )
free ( ids ) ;
return FALSE ;
2006-08-30 18:32:32 +04:00
}
2007-02-07 16:50:18 +03:00
if ( maxname ) {
names = vshMalloc ( ctl , sizeof ( char * ) * maxname ) ;
if ( ( maxname = virConnectListDefinedDomains ( ctl - > conn , names , maxname ) ) < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list inactive domains " ) ) ;
if ( ids )
free ( ids ) ;
free ( names ) ;
return FALSE ;
}
2006-09-03 21:34:04 +04:00
2007-02-14 18:44:58 +03:00
qsort ( & names [ 0 ] , maxname , sizeof ( char * ) , namesorter ) ;
2007-02-07 16:50:18 +03:00
}
2006-08-21 21:58:09 +04:00
}
2006-09-21 19:24:37 +04:00
vshPrintExtra ( ctl , " %3s %-20s %s \n " , _ ( " Id " ) , _ ( " Name " ) , _ ( " State " ) ) ;
2006-05-22 18:38:33 +04:00
vshPrintExtra ( ctl , " ---------------------------------- \n " ) ;
2006-03-15 15:13:25 +03:00
for ( i = 0 ; i < maxid ; i + + ) {
2005-12-08 13:23:34 +03:00
virDomainInfo info ;
virDomainPtr dom = virDomainLookupByID ( ctl - > conn , ids [ i ] ) ;
2007-02-23 11:58:25 +03:00
const char * state ;
2006-03-15 15:13:25 +03:00
/* this kind of work with domains is not atomic operation */
2005-12-08 13:23:34 +03:00
if ( ! dom )
continue ;
2007-02-23 11:58:25 +03:00
if ( virDomainGetInfo ( dom , & info ) < 0 )
state = _ ( " no state " ) ;
else
2007-06-15 12:18:55 +04:00
state = N_ ( vshDomainStateToString ( info . state ) ) ;
2006-03-15 15:13:25 +03:00
2006-05-22 18:38:33 +04:00
vshPrint ( ctl , " %3d %-20s %s \n " ,
2006-03-15 15:13:25 +03:00
virDomainGetID ( dom ) ,
virDomainGetName ( dom ) ,
2007-02-23 11:58:25 +03:00
state ) ;
2005-12-09 02:01:48 +03:00
virDomainFree ( dom ) ;
2005-12-08 13:23:34 +03:00
}
2006-08-30 18:32:32 +04:00
for ( i = 0 ; i < maxname ; i + + ) {
virDomainInfo info ;
virDomainPtr dom = virDomainLookupByName ( ctl - > conn , names [ i ] ) ;
2007-02-23 11:58:25 +03:00
const char * state ;
2006-08-30 18:32:32 +04:00
/* this kind of work with domains is not atomic operation */
2007-01-23 15:28:38 +03:00
if ( ! dom ) {
2007-02-07 16:50:18 +03:00
free ( names [ i ] ) ;
2006-08-30 18:32:32 +04:00
continue ;
2007-02-07 16:50:18 +03:00
}
2007-02-23 11:58:25 +03:00
if ( virDomainGetInfo ( dom , & info ) < 0 )
state = _ ( " no state " ) ;
else
2007-06-15 12:18:55 +04:00
state = N_ ( vshDomainStateToString ( info . state ) ) ;
2007-02-23 11:58:25 +03:00
vshPrint ( ctl , " %3s %-20s %s \n " , " - " , names [ i ] , state ) ;
2006-09-21 19:24:37 +04:00
2006-08-30 18:32:32 +04:00
virDomainFree ( dom ) ;
2007-02-07 16:50:18 +03:00
free ( names [ i ] ) ;
2006-08-30 18:32:32 +04:00
}
2006-08-26 02:40:33 +04:00
if ( ids )
free ( ids ) ;
2006-08-30 18:32:32 +04:00
if ( names )
free ( names ) ;
2005-12-08 13:23:34 +03:00
return TRUE ;
}
/*
2006-04-05 01:52:31 +04:00
* " domstate " command
2005-12-08 13:23:34 +03:00
*/
2006-04-05 01:52:31 +04:00
static vshCmdInfo info_domstate [ ] = {
{ " syntax " , " domstate <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " domain state " ) } ,
{ " desc " , gettext_noop ( " Returns state about a running domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
2006-04-05 01:52:31 +04:00
static vshCmdOptDef opts_domstate [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-04-05 01:52:31 +04:00
cmdDomstate ( vshControl * ctl , vshCmd * cmd )
2006-03-15 15:13:25 +03:00
{
2005-12-05 21:14:37 +03:00
virDomainInfo info ;
2005-12-08 13:23:34 +03:00
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
int ret = TRUE ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-05 21:14:37 +03:00
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
2005-12-08 13:23:34 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainGetInfo ( dom , & info ) = = 0 )
2006-05-22 18:38:33 +04:00
vshPrint ( ctl , " %s \n " ,
2007-06-15 12:18:55 +04:00
N_ ( vshDomainStateToString ( info . state ) ) ) ;
2005-12-08 13:23:34 +03:00
else
ret = FALSE ;
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2007-08-21 14:08:12 +04:00
/* "domblkstat" command
*/
static vshCmdInfo info_domblkstat [ ] = {
{ " syntax " , " domblkstat <domain> <dev> " } ,
{ " help " , gettext_noop ( " get device block stats for a domain " ) } ,
{ " desc " , gettext_noop ( " Get device block stats for a running domain. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_domblkstat [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " device " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " block device " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDomblkstat ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * name , * device ;
struct _virDomainBlockStats stats ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
if ( ! ( device = vshCommandOptString ( cmd , " device " , NULL ) ) )
return FALSE ;
if ( virDomainBlockStats ( dom , device , & stats , sizeof stats ) = = - 1 ) {
vshError ( ctl , FALSE , _ ( " Failed to get block stats %s %s " ) ,
name , device ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
if ( stats . rd_req > = 0 )
vshPrint ( ctl , " %s rd_req %lld \n " , device , stats . rd_req ) ;
if ( stats . rd_bytes > = 0 )
vshPrint ( ctl , " %s rd_bytes %lld \n " , device , stats . rd_bytes ) ;
if ( stats . wr_req > = 0 )
vshPrint ( ctl , " %s wr_req %lld \n " , device , stats . wr_req ) ;
if ( stats . wr_bytes > = 0 )
vshPrint ( ctl , " %s wr_bytes %lld \n " , device , stats . wr_bytes ) ;
if ( stats . errs > = 0 )
vshPrint ( ctl , " %s errs %lld \n " , device , stats . errs ) ;
virDomainFree ( dom ) ;
return TRUE ;
}
/* "domifstat" command
*/
static vshCmdInfo info_domifstat [ ] = {
{ " syntax " , " domifstat <domain> <dev> " } ,
{ " help " , gettext_noop ( " get network interface stats for a domain " ) } ,
{ " desc " , gettext_noop ( " Get network interface stats for a running domain. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_domifstat [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " interface " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " interface device " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDomIfstat ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * name , * device ;
struct _virDomainInterfaceStats stats ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
if ( ! ( device = vshCommandOptString ( cmd , " interface " , NULL ) ) )
return FALSE ;
if ( virDomainInterfaceStats ( dom , device , & stats , sizeof stats ) = = - 1 ) {
vshError ( ctl , FALSE , _ ( " Failed to get interface stats %s %s " ) ,
name , device ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
if ( stats . rx_bytes > = 0 )
vshPrint ( ctl , " %s rx_bytes %lld \n " , device , stats . rx_bytes ) ;
if ( stats . rx_packets > = 0 )
vshPrint ( ctl , " %s rx_packets %lld \n " , device , stats . rx_packets ) ;
if ( stats . rx_errs > = 0 )
vshPrint ( ctl , " %s rx_errs %lld \n " , device , stats . rx_errs ) ;
if ( stats . rx_drop > = 0 )
vshPrint ( ctl , " %s rx_drop %lld \n " , device , stats . rx_drop ) ;
if ( stats . tx_bytes > = 0 )
vshPrint ( ctl , " %s tx_bytes %lld \n " , device , stats . tx_bytes ) ;
if ( stats . tx_packets > = 0 )
vshPrint ( ctl , " %s tx_packets %lld \n " , device , stats . tx_packets ) ;
if ( stats . tx_errs > = 0 )
vshPrint ( ctl , " %s tx_errs %lld \n " , device , stats . tx_errs ) ;
if ( stats . tx_drop > = 0 )
vshPrint ( ctl , " %s tx_drop %lld \n " , device , stats . tx_drop ) ;
virDomainFree ( dom ) ;
return TRUE ;
}
2005-12-09 02:01:48 +03:00
/*
* " suspend " command
*/
static vshCmdInfo info_suspend [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " suspend <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " suspend a domain " ) } ,
{ " desc " , gettext_noop ( " Suspend a running domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-09 02:01:48 +03:00
} ;
static vshCmdOptDef opts_suspend [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-09 02:01:48 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdSuspend ( vshControl * ctl , vshCmd * cmd )
{
2005-12-09 02:01:48 +03:00
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
char * name ;
int ret = TRUE ;
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
2005-12-09 02:01:48 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainSuspend ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s suspended \n " ) , name ) ;
2005-12-09 02:01:48 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to suspend domain %s " ) , name ) ;
2005-12-09 02:01:48 +03:00
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2006-03-30 20:08:13 +04:00
/*
* " create " command
*/
static vshCmdInfo info_create [ ] = {
{ " syntax " , " create a domain from an XML <file> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " create a domain from an XML file " ) } ,
{ " desc " , gettext_noop ( " Create a domain. " ) } ,
2006-03-30 20:08:13 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_create [ ] = {
2007-06-15 12:18:55 +04:00
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " file containing an XML domain description " ) } ,
2006-03-30 20:08:13 +04:00
{ NULL , 0 , 0 , NULL }
} ;
2007-05-23 19:09:19 +04:00
/* Read in a whole file and return it as a string.
* If it fails , it logs an error and returns NULL .
* String must be freed by caller .
*/
static char *
readFile ( vshControl * ctl , const char * filename )
{
char * retval ;
int len = 0 , fd ;
if ( ( fd = open ( filename , O_RDONLY ) ) = = - 1 ) {
vshError ( ctl , FALSE , _ ( " Failed to open '%s': %s " ) ,
filename , strerror ( errno ) ) ;
return NULL ;
}
if ( ! ( retval = malloc ( len + 1 ) ) )
goto out_of_memory ;
while ( 1 ) {
char buffer [ 1024 ] ;
char * new ;
int ret ;
if ( ( ret = read ( fd , buffer , sizeof ( buffer ) ) ) = = 0 )
break ;
if ( ret = = - 1 ) {
if ( errno = = EINTR )
continue ;
vshError ( ctl , FALSE , _ ( " Failed to open '%s': read: %s " ) ,
filename , strerror ( errno ) ) ;
goto error ;
}
if ( ! ( new = realloc ( retval , len + ret + 1 ) ) )
goto out_of_memory ;
retval = new ;
memcpy ( retval + len , buffer , ret ) ;
len + = ret ;
}
retval [ len ] = ' \0 ' ;
return retval ;
out_of_memory :
vshError ( ctl , FALSE , _ ( " Error allocating memory: %s " ) ,
strerror ( errno ) ) ;
error :
if ( retval )
free ( retval ) ;
close ( fd ) ;
return NULL ;
}
2006-03-30 20:08:13 +04:00
static int
cmdCreate ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * from ;
int found ;
int ret = TRUE ;
2007-05-23 19:09:19 +04:00
char * buffer ;
2006-03-30 20:08:13 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found )
return FALSE ;
2007-05-23 19:09:19 +04:00
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
dom = virDomainCreateLinux ( ctl - > conn , buffer , 0 ) ;
free ( buffer ) ;
2006-03-30 20:08:13 +04:00
if ( dom ! = NULL ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s created from %s \n " ) ,
2006-03-30 20:08:13 +04:00
virDomainGetName ( dom ) , from ) ;
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2006-03-30 20:08:13 +04:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to create domain from %s " ) , from ) ;
2006-03-30 20:08:13 +04:00
ret = FALSE ;
}
return ret ;
}
2006-08-30 18:32:32 +04:00
/*
* " define " command
*/
static vshCmdInfo info_define [ ] = {
{ " syntax " , " define a domain from an XML <file> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " define (but don't start) a domain from an XML file " ) } ,
{ " desc " , gettext_noop ( " Define a domain. " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_define [ ] = {
2007-04-10 22:40:50 +04:00
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " file containing an XML domain description " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDefine ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * from ;
int found ;
int ret = TRUE ;
2007-05-23 19:09:19 +04:00
char * buffer ;
2006-08-30 18:32:32 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found )
return FALSE ;
2007-05-23 19:09:19 +04:00
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
dom = virDomainDefineXML ( ctl - > conn , buffer ) ;
free ( buffer ) ;
2006-08-30 18:32:32 +04:00
if ( dom ! = NULL ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s defined from %s \n " ) ,
2006-08-30 18:32:32 +04:00
virDomainGetName ( dom ) , from ) ;
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2006-08-30 18:32:32 +04:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to define domain from %s " ) , from ) ;
2006-08-30 18:32:32 +04:00
ret = FALSE ;
}
return ret ;
}
/*
* " undefine " command
*/
static vshCmdInfo info_undefine [ ] = {
{ " syntax " , " undefine <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " undefine an inactive domain " ) } ,
{ " desc " , gettext_noop ( " Undefine the configuration for an inactive domain. " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_undefine [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name or uuid " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdUndefine ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
int ret = TRUE ;
char * name ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
if ( virDomainUndefine ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s has been undefined \n " ) , name ) ;
2006-08-30 18:32:32 +04:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to undefine domain %s " ) , name ) ;
2006-08-30 18:32:32 +04:00
ret = FALSE ;
}
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2006-08-30 18:32:32 +04:00
return ret ;
}
/*
* " start " command
*/
static vshCmdInfo info_start [ ] = {
2007-01-23 15:28:38 +03:00
{ " syntax " , " start <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " start a (previously defined) inactive domain " ) } ,
{ " desc " , gettext_noop ( " Start a domain. " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_start [ ] = {
2006-09-21 19:24:37 +04:00
{ " name " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " name of the inactive domain " ) } ,
2006-08-30 18:32:32 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdStart ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2007-02-23 13:27:53 +03:00
if ( ! ( dom = vshCommandOptDomainBy ( ctl , cmd , " name " , NULL , VSH_BYNAME ) ) )
2006-08-30 18:32:32 +04:00
return FALSE ;
if ( virDomainGetID ( dom ) ! = ( unsigned int ) - 1 ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Domain is already active " ) ) ;
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2006-08-30 18:32:32 +04:00
return FALSE ;
}
if ( virDomainCreate ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s started \n " ) ,
2007-02-23 13:27:53 +03:00
virDomainGetName ( dom ) ) ;
2006-08-30 18:32:32 +04:00
} else {
2007-02-23 13:27:53 +03:00
vshError ( ctl , FALSE , _ ( " Failed to start domain %s " ) ,
virDomainGetName ( dom ) ) ;
2006-08-30 18:32:32 +04:00
ret = FALSE ;
}
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2006-08-30 18:32:32 +04:00
return ret ;
}
2006-01-20 13:00:08 +03:00
/*
* " save " command
*/
static vshCmdInfo info_save [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " save <domain> <file> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " save a domain state to a file " ) } ,
{ " desc " , gettext_noop ( " Save a running domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2006-01-20 13:00:08 +03:00
} ;
static vshCmdOptDef opts_save [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " where to save the data " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2006-01-20 13:00:08 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdSave ( vshControl * ctl , vshCmd * cmd )
{
2006-01-20 13:00:08 +03:00
virDomainPtr dom ;
char * name ;
char * to ;
int ret = TRUE ;
2006-03-15 15:13:25 +03:00
2006-01-20 13:00:08 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2006-01-25 12:46:22 +03:00
if ( ! ( to = vshCommandOptString ( cmd , " file " , NULL ) ) )
2006-01-20 13:00:08 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
2006-01-20 13:00:08 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainSave ( dom , to ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s saved to %s \n " ) , name , to ) ;
2006-01-20 13:00:08 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to save domain %s to %s " ) , name , to ) ;
2006-01-20 13:00:08 +03:00
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2006-01-20 13:00:08 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2007-06-05 16:06:08 +04:00
/*
* " schedinfo " command
*/
static vshCmdInfo info_schedinfo [ ] = {
2007-08-14 11:07:57 +04:00
{ " syntax " , " schedinfo <domain> " } ,
2007-06-05 16:06:08 +04:00
{ " help " , gettext_noop ( " show/set scheduler parameters " ) } ,
{ " desc " , gettext_noop ( " Show/Set scheduler parameters. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_schedinfo [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " weight " , VSH_OT_INT , VSH_OFLAG_NONE , gettext_noop ( " weight for XEN_CREDIT " ) } ,
{ " cap " , VSH_OT_INT , VSH_OFLAG_NONE , gettext_noop ( " cap for XEN_CREDIT " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdSchedinfo ( vshControl * ctl , vshCmd * cmd )
{
char * schedulertype ;
virDomainPtr dom ;
2007-08-21 15:53:52 +04:00
virSchedParameterPtr params = NULL ;
2007-06-05 16:06:08 +04:00
int i , ret ;
int nparams = 0 ;
int nr_inputparams = 0 ;
int inputparams = 0 ;
int weightfound = 0 ;
2007-11-08 21:07:02 +03:00
int weight = 0 ;
2007-06-05 16:06:08 +04:00
int capfound = 0 ;
2007-11-08 21:07:02 +03:00
int cap = 0 ;
2007-06-05 16:06:08 +04:00
char str_weight [ ] = " weight " ;
char str_cap [ ] = " cap " ;
2007-08-21 15:53:52 +04:00
int ret_val = FALSE ;
2007-06-05 16:06:08 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
/* Currently supports Xen Credit only */
2007-11-06 12:41:18 +03:00
if ( vshCommandOptBool ( cmd , " weight " ) ) {
weight = vshCommandOptInt ( cmd , " weight " , & weightfound ) ;
if ( ! weightfound ) {
vshError ( ctl , FALSE , _ ( " Invalid value of weight " ) ) ;
goto cleanup ;
} else {
nr_inputparams + + ;
}
}
if ( vshCommandOptBool ( cmd , " cap " ) ) {
cap = vshCommandOptInt ( cmd , " cap " , & capfound ) ;
if ( ! capfound ) {
vshError ( ctl , FALSE , _ ( " Invalid value of cap " ) ) ;
goto cleanup ;
} else {
nr_inputparams + + ;
}
}
2007-06-05 16:06:08 +04:00
params = vshMalloc ( ctl , sizeof ( virSchedParameter ) * nr_inputparams ) ;
2007-06-29 17:45:50 +04:00
if ( params = = NULL ) {
2007-08-21 15:53:52 +04:00
goto cleanup ;
2007-06-29 17:45:50 +04:00
}
2007-06-05 16:06:08 +04:00
if ( weightfound ) {
strncpy ( params [ inputparams ] . field , str_weight , sizeof ( str_weight ) ) ;
params [ inputparams ] . type = VIR_DOMAIN_SCHED_FIELD_UINT ;
params [ inputparams ] . value . ui = weight ;
inputparams + + ;
}
if ( capfound ) {
strncpy ( params [ inputparams ] . field , str_cap , sizeof ( str_cap ) ) ;
params [ inputparams ] . type = VIR_DOMAIN_SCHED_FIELD_UINT ;
params [ inputparams ] . value . ui = cap ;
inputparams + + ;
}
/* End Currently supports Xen Credit only */
assert ( inputparams = = nr_inputparams ) ;
/* Set SchedulerParameters */
if ( inputparams > 0 ) {
ret = virDomainSetSchedulerParameters ( dom , params , inputparams ) ;
2007-06-29 17:45:50 +04:00
if ( ret = = - 1 ) {
2007-08-21 15:53:52 +04:00
goto cleanup ;
2007-06-29 17:45:50 +04:00
}
2007-06-05 16:06:08 +04:00
}
free ( params ) ;
2007-08-21 15:53:52 +04:00
params = NULL ;
2007-06-05 16:06:08 +04:00
/* Print SchedulerType */
schedulertype = virDomainGetSchedulerType ( dom , & nparams ) ;
if ( schedulertype ! = NULL ) {
2007-06-13 13:32:44 +04:00
vshPrint ( ctl , " %-15s: %s \n " , _ ( " Scheduler " ) ,
2007-06-05 16:06:08 +04:00
schedulertype ) ;
free ( schedulertype ) ;
} else {
2007-06-13 13:32:44 +04:00
vshPrint ( ctl , " %-15s: %s \n " , _ ( " Scheduler " ) , _ ( " Unknown " ) ) ;
2007-08-21 15:53:52 +04:00
goto cleanup ;
2007-06-05 16:06:08 +04:00
}
/* Get SchedulerParameters */
params = vshMalloc ( ctl , sizeof ( virSchedParameter ) * nparams ) ;
2007-08-21 15:53:52 +04:00
if ( params = = NULL ) {
goto cleanup ;
}
2007-06-05 16:06:08 +04:00
for ( i = 0 ; i < nparams ; i + + ) {
params [ i ] . type = 0 ;
memset ( params [ i ] . field , 0 , sizeof params [ i ] . field ) ;
}
ret = virDomainGetSchedulerParameters ( dom , params , & nparams ) ;
2007-06-29 17:45:50 +04:00
if ( ret = = - 1 ) {
2007-08-21 15:53:52 +04:00
goto cleanup ;
2007-06-29 17:45:50 +04:00
}
2007-08-21 15:53:52 +04:00
ret_val = TRUE ;
2007-06-05 16:06:08 +04:00
if ( nparams ) {
for ( i = 0 ; i < nparams ; i + + ) {
switch ( params [ i ] . type ) {
case VIR_DOMAIN_SCHED_FIELD_INT :
printf ( " %-15s: %d \n " , params [ i ] . field , params [ i ] . value . i ) ;
break ;
case VIR_DOMAIN_SCHED_FIELD_UINT :
printf ( " %-15s: %u \n " , params [ i ] . field , params [ i ] . value . ui ) ;
break ;
case VIR_DOMAIN_SCHED_FIELD_LLONG :
printf ( " %-15s: %Ld \n " , params [ i ] . field , params [ i ] . value . l ) ;
break ;
case VIR_DOMAIN_SCHED_FIELD_ULLONG :
printf ( " %-15s: %Lu \n " , params [ i ] . field , params [ i ] . value . ul ) ;
break ;
case VIR_DOMAIN_SCHED_FIELD_DOUBLE :
printf ( " %-15s: %f \n " , params [ i ] . field , params [ i ] . value . d ) ;
break ;
case VIR_DOMAIN_SCHED_FIELD_BOOLEAN :
printf ( " %-15s: %d \n " , params [ i ] . field , params [ i ] . value . b ) ;
break ;
default :
printf ( " not implemented scheduler parameter type \n " ) ;
}
}
}
2007-08-21 15:53:52 +04:00
cleanup :
if ( params )
free ( params ) ;
2007-06-29 17:45:50 +04:00
virDomainFree ( dom ) ;
2007-08-21 15:53:52 +04:00
return ret_val ;
2007-06-05 16:06:08 +04:00
}
2006-01-20 13:00:08 +03:00
/*
* " restore " command
*/
static vshCmdInfo info_restore [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " restore a domain from <file> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " restore a domain from a saved state in a file " ) } ,
{ " desc " , gettext_noop ( " Restore a domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2006-01-20 13:00:08 +03:00
} ;
static vshCmdOptDef opts_restore [ ] = {
2006-09-21 19:24:37 +04:00
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " the state to restore " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2006-01-20 13:00:08 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdRestore ( vshControl * ctl , vshCmd * cmd )
{
2006-01-20 13:00:08 +03:00
char * from ;
int found ;
int ret = TRUE ;
2006-03-15 15:13:25 +03:00
2006-01-20 13:00:08 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found )
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainRestore ( ctl - > conn , from ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain restored from %s \n " ) , from ) ;
2006-01-20 13:00:08 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to restore domain from %s " ) , from ) ;
2006-01-20 13:00:08 +03:00
ret = FALSE ;
}
return ret ;
}
2006-11-22 20:48:29 +03:00
/*
* " dump " command
*/
static vshCmdInfo info_dump [ ] = {
{ " syntax " , " dump <domain> <file> " } ,
{ " help " , gettext_noop ( " dump the core of a domain to a file for analysis " ) } ,
{ " desc " , gettext_noop ( " Core dump a domain. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_dump [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " where to dump the core " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDump ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * name ;
char * to ;
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( to = vshCommandOptString ( cmd , " file " , NULL ) ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
if ( virDomainCoreDump ( dom , to , 0 ) = = 0 ) {
vshPrint ( ctl , _ ( " Domain %s dumpd to %s \n " ) , name , to ) ;
} else {
vshError ( ctl , FALSE , _ ( " Failed to core dump domain %s to %s " ) ,
name , to ) ;
ret = FALSE ;
}
virDomainFree ( dom ) ;
return ret ;
}
2005-12-09 02:01:48 +03:00
/*
* " resume " command
*/
static vshCmdInfo info_resume [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " resume <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " resume a domain " ) } ,
{ " desc " , gettext_noop ( " Resume a previously suspended domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-09 02:01:48 +03:00
} ;
static vshCmdOptDef opts_resume [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-09 02:01:48 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdResume ( vshControl * ctl , vshCmd * cmd )
{
2005-12-09 02:01:48 +03:00
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
int ret = TRUE ;
char * name ;
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
2005-12-09 02:01:48 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainResume ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s resumed \n " ) , name ) ;
2005-12-09 02:01:48 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to resume domain %s " ) , name ) ;
2005-12-09 02:01:48 +03:00
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2005-12-16 15:16:41 +03:00
/*
* " shutdown " command
*/
static vshCmdInfo info_shutdown [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " shutdown <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " gracefully shutdown a domain " ) } ,
{ " desc " , gettext_noop ( " Run shutdown in the target domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-16 15:16:41 +03:00
} ;
static vshCmdOptDef opts_shutdown [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-16 15:16:41 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdShutdown ( vshControl * ctl , vshCmd * cmd )
{
2005-12-16 15:16:41 +03:00
virDomainPtr dom ;
int ret = TRUE ;
char * name ;
2006-03-15 15:13:25 +03:00
2005-12-16 15:16:41 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainShutdown ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s is being shutdown \n " ) , name ) ;
2005-12-16 15:16:41 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to shutdown domain %s " ) , name ) ;
2005-12-16 15:16:41 +03:00
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2005-12-16 15:16:41 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2006-04-03 17:46:43 +04:00
/*
* " reboot " command
*/
static vshCmdInfo info_reboot [ ] = {
{ " syntax " , " reboot <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " reboot a domain " ) } ,
{ " desc " , gettext_noop ( " Run a reboot command in the target domain. " ) } ,
2006-04-03 17:46:43 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_reboot [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-04-03 17:46:43 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdReboot ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
int ret = TRUE ;
char * name ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
return FALSE ;
if ( virDomainReboot ( dom , 0 ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s is being rebooted \n " ) , name ) ;
2006-04-03 17:46:43 +04:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to reboot domain %s " ) , name ) ;
2006-04-03 17:46:43 +04:00
ret = FALSE ;
}
virDomainFree ( dom ) ;
return ret ;
}
2005-12-09 02:01:48 +03:00
/*
* " destroy " command
*/
static vshCmdInfo info_destroy [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " destroy <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " destroy a domain " ) } ,
{ " desc " , gettext_noop ( " Destroy a given domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-09 02:01:48 +03:00
} ;
static vshCmdOptDef opts_destroy [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-09 02:01:48 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdDestroy ( vshControl * ctl , vshCmd * cmd )
{
2005-12-09 02:01:48 +03:00
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
int ret = TRUE ;
char * name ;
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , & name ) ) )
2005-12-09 02:01:48 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
if ( virDomainDestroy ( dom ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Domain %s destroyed \n " ) , name ) ;
2005-12-09 02:01:48 +03:00
} else {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " Failed to destroy domain %s " ) , name ) ;
2005-12-09 02:01:48 +03:00
ret = FALSE ;
virDomainFree ( dom ) ;
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
return ret ;
}
/*
2006-04-04 18:37:32 +04:00
* " dominfo " command
2005-12-08 13:23:34 +03:00
*/
2006-04-04 18:37:32 +04:00
static vshCmdInfo info_dominfo [ ] = {
{ " syntax " , " dominfo <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " domain information " ) } ,
{ " desc " , gettext_noop ( " Returns basic information about the domain. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
2006-04-04 18:37:32 +04:00
static vshCmdOptDef opts_dominfo [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-04-04 18:37:32 +04:00
cmdDominfo ( vshControl * ctl , vshCmd * cmd )
2006-03-15 15:13:25 +03:00
{
2005-12-08 13:23:34 +03:00
virDomainInfo info ;
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
int ret = TRUE ;
2006-09-03 21:34:04 +04:00
unsigned int id ;
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 17:39:45 +03:00
char * str , uuid [ VIR_UUID_STRING_BUFLEN ] ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
2005-12-08 13:23:34 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
2006-09-03 21:34:04 +04:00
id = virDomainGetID ( dom ) ;
if ( id = = ( ( unsigned int ) - 1 ) )
2007-02-07 16:50:18 +03:00
vshPrint ( ctl , " %-15s %s \n " , _ ( " Id: " ) , " - " ) ;
2006-09-03 21:34:04 +04:00
else
2007-02-07 16:50:18 +03:00
vshPrint ( ctl , " %-15s %d \n " , _ ( " Id: " ) , id ) ;
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %s \n " , _ ( " Name: " ) , virDomainGetName ( dom ) ) ;
2006-05-22 18:38:33 +04:00
if ( virDomainGetUUIDString ( dom , & uuid [ 0 ] ) = = 0 )
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %s \n " , _ ( " UUID: " ) , uuid ) ;
2006-03-15 15:13:25 +03:00
if ( ( str = virDomainGetOSType ( dom ) ) ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %s \n " , _ ( " OS Type: " ) , str ) ;
2006-03-15 15:13:25 +03:00
free ( str ) ;
}
if ( virDomainGetInfo ( dom , & info ) = = 0 ) {
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %s \n " , _ ( " State: " ) ,
2007-06-15 12:18:55 +04:00
N_ ( vshDomainStateToString ( info . state ) ) ) ;
2006-03-15 15:13:25 +03:00
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %d \n " , _ ( " CPU(s): " ) , info . nrVirtCpu ) ;
2006-03-15 15:13:25 +03:00
if ( info . cpuTime ! = 0 ) {
2007-02-07 16:50:18 +03:00
double cpuUsed = info . cpuTime ;
2006-03-15 15:13:25 +03:00
2006-06-13 23:08:40 +04:00
cpuUsed / = 1000000000.0 ;
2006-03-15 15:13:25 +03:00
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , " %-15s %.1lfs \n " , _ ( " CPU time: " ) , cpuUsed ) ;
2005-12-08 13:23:34 +03:00
}
2006-03-15 15:13:25 +03:00
2007-03-15 17:27:09 +03:00
if ( info . maxMem ! = UINT_MAX )
vshPrint ( ctl , " %-15s %lu kB \n " , _ ( " Max memory: " ) ,
2006-03-15 15:13:25 +03:00
info . maxMem ) ;
2007-03-15 17:27:09 +03:00
else
vshPrint ( ctl , " %-15s %-15s \n " , _ ( " Max memory: " ) ,
_ ( " no limit " ) ) ;
2007-02-07 16:50:18 +03:00
vshPrint ( ctl , " %-15s %lu kB \n " , _ ( " Used memory: " ) ,
2006-03-15 15:13:25 +03:00
info . memory ) ;
2005-12-08 13:23:34 +03:00
} else {
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2005-12-09 02:01:48 +03:00
virDomainFree ( dom ) ;
2005-12-08 13:23:34 +03:00
return ret ;
}
2007-09-28 18:28:12 +04:00
/*
* " freecell " command
*/
static vshCmdInfo info_freecell [ ] = {
{ " syntax " , " freecell [<cellno>] " } ,
{ " help " , gettext_noop ( " NUMA free memory " ) } ,
{ " desc " , gettext_noop ( " display available free memory for the NUMA cell. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_freecell [ ] = {
{ " cellno " , VSH_OT_DATA , 0 , gettext_noop ( " NUMA cell number " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdFreecell ( vshControl * ctl , vshCmd * cmd )
{
int ret ;
int cell , cell_given ;
unsigned long long memory ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
cell = vshCommandOptInt ( cmd , " cellno " , & cell_given ) ;
if ( ! cell_given ) {
2007-09-30 17:22:16 +04:00
memory = virNodeGetFreeMemory ( ctl - > conn ) ;
} else {
ret = virNodeGetCellsFreeMemory ( ctl - > conn , & memory , cell , 1 ) ;
if ( ret ! = 1 )
return FALSE ;
2007-09-28 18:28:12 +04:00
}
if ( cell = = - 1 )
vshPrint ( ctl , " %s: %llu kB \n " , _ ( " Total " ) , memory ) ;
else
vshPrint ( ctl , " %d: %llu kB \n " , cell , memory ) ;
return TRUE ;
}
2006-08-07 18:35:20 +04:00
/*
* " vcpuinfo " command
*/
static vshCmdInfo info_vcpuinfo [ ] = {
{ " syntax " , " vcpuinfo <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " domain vcpu information " ) } ,
{ " desc " , gettext_noop ( " Returns basic information about the domain virtual CPUs. " ) } ,
2006-08-07 18:35:20 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_vcpuinfo [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-08-07 18:35:20 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdVcpuinfo ( vshControl * ctl , vshCmd * cmd )
{
virDomainInfo info ;
virDomainPtr dom ;
virNodeInfo nodeinfo ;
virVcpuInfoPtr cpuinfo ;
unsigned char * cpumap ;
int ncpus ;
size_t cpumaplen ;
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
if ( virNodeGetInfo ( ctl - > conn , & nodeinfo ) ! = 0 ) {
virDomainFree ( dom ) ;
2007-02-07 16:50:18 +03:00
return FALSE ;
2006-08-07 18:35:20 +04:00
}
if ( virDomainGetInfo ( dom , & info ) ! = 0 ) {
virDomainFree ( dom ) ;
return FALSE ;
}
2007-03-22 21:30:57 +03:00
cpuinfo = vshMalloc ( ctl , sizeof ( virVcpuInfo ) * info . nrVirtCpu ) ;
2006-08-07 18:35:20 +04:00
cpumaplen = VIR_CPU_MAPLEN ( VIR_NODEINFO_MAXCPUS ( nodeinfo ) ) ;
2007-03-22 21:30:57 +03:00
cpumap = vshMalloc ( ctl , info . nrVirtCpu * cpumaplen ) ;
2006-08-07 18:35:20 +04:00
2007-02-07 16:50:18 +03:00
if ( ( ncpus = virDomainGetVcpus ( dom ,
cpuinfo , info . nrVirtCpu ,
cpumap , cpumaplen ) ) > = 0 ) {
2006-08-07 18:35:20 +04:00
int n ;
2007-02-07 16:50:18 +03:00
for ( n = 0 ; n < ncpus ; n + + ) {
unsigned int m ;
vshPrint ( ctl , " %-15s %d \n " , _ ( " VCPU: " ) , n ) ;
vshPrint ( ctl , " %-15s %d \n " , _ ( " CPU: " ) , cpuinfo [ n ] . cpu ) ;
vshPrint ( ctl , " %-15s %s \n " , _ ( " State: " ) ,
2007-06-15 12:18:55 +04:00
N_ ( vshDomainVcpuStateToString ( cpuinfo [ n ] . state ) ) ) ;
2007-02-07 16:50:18 +03:00
if ( cpuinfo [ n ] . cpuTime ! = 0 ) {
double cpuUsed = cpuinfo [ n ] . cpuTime ;
cpuUsed / = 1000000000.0 ;
vshPrint ( ctl , " %-15s %.1lfs \n " , _ ( " CPU time: " ) , cpuUsed ) ;
}
vshPrint ( ctl , " %-15s " , _ ( " CPU Affinity: " ) ) ;
for ( m = 0 ; m < VIR_NODEINFO_MAXCPUS ( nodeinfo ) ; m + + ) {
vshPrint ( ctl , " %c " , VIR_CPU_USABLE ( cpumap , cpumaplen , n , m ) ? ' y ' : ' - ' ) ;
}
vshPrint ( ctl , " \n " ) ;
if ( n < ( ncpus - 1 ) ) {
vshPrint ( ctl , " \n " ) ;
}
}
2006-08-07 18:35:20 +04:00
} else {
2007-06-15 12:18:55 +04:00
if ( info . state = = VIR_DOMAIN_SHUTOFF ) {
vshError ( ctl , FALSE ,
_ ( " Domain shut off, virtual CPUs not present. " ) ) ;
}
2006-08-07 18:35:20 +04:00
ret = FALSE ;
}
free ( cpumap ) ;
free ( cpuinfo ) ;
virDomainFree ( dom ) ;
return ret ;
}
/*
* " vcpupin " command
*/
static vshCmdInfo info_vcpupin [ ] = {
2007-06-19 13:32:04 +04:00
{ " syntax " , " vcpupin <domain> <vcpu> <cpulist> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " control domain vcpu affinity " ) } ,
{ " desc " , gettext_noop ( " Pin domain VCPUs to host physical CPUs. " ) } ,
2006-08-07 18:35:20 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_vcpupin [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " vcpu " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " vcpu number " ) } ,
{ " cpulist " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " host cpu number(s) (comma separated) " ) } ,
2006-08-07 18:35:20 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdVcpupin ( vshControl * ctl , vshCmd * cmd )
{
virDomainInfo info ;
virDomainPtr dom ;
virNodeInfo nodeinfo ;
int vcpu ;
char * cpulist ;
int ret = TRUE ;
int vcpufound = 0 ;
unsigned char * cpumap ;
int cpumaplen ;
2007-06-19 13:32:04 +04:00
int i ;
enum { expect_num , expect_num_or_comma } state ;
2006-08-07 18:35:20 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
vcpu = vshCommandOptInt ( cmd , " vcpu " , & vcpufound ) ;
if ( ! vcpufound ) {
virDomainFree ( dom ) ;
return FALSE ;
}
if ( ! ( cpulist = vshCommandOptString ( cmd , " cpulist " , NULL ) ) ) {
virDomainFree ( dom ) ;
return FALSE ;
}
2007-02-07 16:50:18 +03:00
2006-08-07 18:35:20 +04:00
if ( virNodeGetInfo ( ctl - > conn , & nodeinfo ) ! = 0 ) {
virDomainFree ( dom ) ;
return FALSE ;
}
if ( virDomainGetInfo ( dom , & info ) ! = 0 ) {
virDomainFree ( dom ) ;
return FALSE ;
}
if ( vcpu > = info . nrVirtCpu ) {
virDomainFree ( dom ) ;
return FALSE ;
}
2007-06-19 13:32:04 +04:00
/* Check that the cpulist parameter is a comma-separated list of
* numbers and give an intelligent error message if not .
*/
if ( cpulist [ 0 ] = = ' \0 ' ) {
vshError ( ctl , FALSE , _ ( " cpulist: Invalid format. Empty string. " ) ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
state = expect_num ;
for ( i = 0 ; cpulist [ i ] ; i + + ) {
switch ( state ) {
case expect_num :
if ( ! isdigit ( cpulist [ i ] ) ) {
vshError ( ctl , FALSE , _ ( " cpulist: %s: Invalid format. Expecting digit at position %d (near '%c'). " ) , cpulist , i , cpulist [ i ] ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
state = expect_num_or_comma ;
break ;
case expect_num_or_comma :
if ( cpulist [ i ] = = ' , ' )
state = expect_num ;
else if ( ! isdigit ( cpulist [ i ] ) ) {
vshError ( ctl , FALSE , _ ( " cpulist: %s: Invalid format. Expecting digit or comma at position %d (near '%c'). " ) , cpulist , i , cpulist [ i ] ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
}
}
if ( state = = expect_num ) {
vshError ( ctl , FALSE , _ ( " cpulist: %s: Invalid format. Trailing comma at position %d. " ) , cpulist , i ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
2006-08-07 18:35:20 +04:00
cpumaplen = VIR_CPU_MAPLEN ( VIR_NODEINFO_MAXCPUS ( nodeinfo ) ) ;
2007-03-22 21:30:57 +03:00
cpumap = vshCalloc ( ctl , 1 , cpumaplen ) ;
2006-08-07 18:35:20 +04:00
do {
unsigned int cpu = atoi ( cpulist ) ;
if ( cpu < VIR_NODEINFO_MAXCPUS ( nodeinfo ) ) {
VIR_USE_CPU ( cpumap , cpu ) ;
2007-03-22 13:27:54 +03:00
} else {
vshError ( ctl , FALSE , _ ( " Physical CPU %d doesn't exist. " ) , cpu ) ;
free ( cpumap ) ;
virDomainFree ( dom ) ;
return FALSE ;
2006-08-07 18:35:20 +04:00
}
2007-06-15 17:44:19 +04:00
cpulist = strchr ( cpulist , ' , ' ) ;
2006-08-07 18:35:20 +04:00
if ( cpulist )
cpulist + + ;
} while ( cpulist ) ;
if ( virDomainPinVcpu ( dom , vcpu , cpumap , cpumaplen ) ! = 0 ) {
ret = FALSE ;
}
free ( cpumap ) ;
virDomainFree ( dom ) ;
return ret ;
}
2006-08-16 21:30:33 +04:00
/*
* " setvcpus " command
*/
static vshCmdInfo info_setvcpus [ ] = {
{ " syntax " , " setvcpus <domain> <count> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " change number of virtual CPUs " ) } ,
{ " desc " , gettext_noop ( " Change the number of virtual CPUs active in the guest domain. " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_setvcpus [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " count " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " number of virtual CPUs " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdSetvcpus ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
int count ;
2007-03-08 11:31:07 +03:00
int maxcpu ;
2006-08-16 21:30:33 +04:00
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
count = vshCommandOptInt ( cmd , " count " , & count ) ;
2007-08-15 14:18:33 +04:00
if ( count < = 0 ) {
2007-06-15 12:18:55 +04:00
vshError ( ctl , FALSE , _ ( " Invalid number of virtual CPUs. " ) ) ;
2006-08-16 21:30:33 +04:00
virDomainFree ( dom ) ;
return FALSE ;
}
2007-03-08 11:31:07 +03:00
maxcpu = virDomainGetMaxVcpus ( dom ) ;
2007-08-15 14:18:33 +04:00
if ( maxcpu < = 0 ) {
2007-03-08 11:31:07 +03:00
virDomainFree ( dom ) ;
return FALSE ;
}
if ( count > maxcpu ) {
2007-06-15 12:18:55 +04:00
vshError ( ctl , FALSE , _ ( " Too many virtual CPUs. " ) ) ;
2007-03-08 11:31:07 +03:00
virDomainFree ( dom ) ;
return FALSE ;
}
2006-08-16 21:30:33 +04:00
if ( virDomainSetVcpus ( dom , count ) ! = 0 ) {
ret = FALSE ;
}
virDomainFree ( dom ) ;
return ret ;
}
/*
* " setmemory " command
*/
static vshCmdInfo info_setmem [ ] = {
2007-04-02 15:56:38 +04:00
{ " syntax " , " setmem <domain> <kilobytes> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " change memory allocation " ) } ,
{ " desc " , gettext_noop ( " Change the current memory allocation in the guest domain. " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_setmem [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2007-04-02 15:56:38 +04:00
{ " kilobytes " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " number of kilobytes of memory " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdSetmem ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
2007-06-18 12:33:08 +04:00
virDomainInfo info ;
2007-04-02 15:56:38 +04:00
int kilobytes ;
2006-08-16 21:30:33 +04:00
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
2007-04-02 15:56:38 +04:00
kilobytes = vshCommandOptInt ( cmd , " kilobytes " , & kilobytes ) ;
if ( kilobytes < = 0 ) {
2006-08-16 21:30:33 +04:00
virDomainFree ( dom ) ;
2007-04-02 15:56:38 +04:00
vshError ( ctl , FALSE , _ ( " Invalid value of %d for memory size " ) , kilobytes ) ;
2006-08-16 21:30:33 +04:00
return FALSE ;
}
2007-06-18 12:33:08 +04:00
if ( virDomainGetInfo ( dom , & info ) ! = 0 ) {
virDomainFree ( dom ) ;
vshError ( ctl , FALSE , _ ( " Unable to verify MaxMemorySize " ) ) ;
return FALSE ;
}
if ( kilobytes > info . maxMem ) {
virDomainFree ( dom ) ;
vshError ( ctl , FALSE , _ ( " Invalid value of %d for memory size " ) , kilobytes ) ;
return FALSE ;
}
2007-04-02 15:56:38 +04:00
if ( virDomainSetMemory ( dom , kilobytes ) ! = 0 ) {
2006-08-16 21:30:33 +04:00
ret = FALSE ;
}
virDomainFree ( dom ) ;
return ret ;
}
/*
* " setmaxmem " command
*/
static vshCmdInfo info_setmaxmem [ ] = {
2007-04-02 15:56:38 +04:00
{ " syntax " , " setmaxmem <domain> <kilobytes> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " change maximum memory limit " ) } ,
{ " desc " , gettext_noop ( " Change the maximum memory allocation limit in the guest domain. " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_setmaxmem [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2007-04-10 22:40:50 +04:00
{ " kilobytes " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " maximum memory limit in kilobytes " ) } ,
2006-08-16 21:30:33 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdSetmaxmem ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
2007-06-18 12:33:08 +04:00
virDomainInfo info ;
2007-04-02 15:56:38 +04:00
int kilobytes ;
2006-08-16 21:30:33 +04:00
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
2007-04-02 15:56:38 +04:00
kilobytes = vshCommandOptInt ( cmd , " kilobytes " , & kilobytes ) ;
if ( kilobytes < = 0 ) {
2006-08-16 21:30:33 +04:00
virDomainFree ( dom ) ;
2007-04-02 15:56:38 +04:00
vshError ( ctl , FALSE , _ ( " Invalid value of %d for memory size " ) , kilobytes ) ;
2006-08-16 21:30:33 +04:00
return FALSE ;
}
2007-06-18 12:33:08 +04:00
if ( virDomainGetInfo ( dom , & info ) ! = 0 ) {
virDomainFree ( dom ) ;
vshError ( ctl , FALSE , _ ( " Unable to verify current MemorySize " ) ) ;
return FALSE ;
}
if ( kilobytes < info . memory ) {
if ( virDomainSetMemory ( dom , kilobytes ) ! = 0 ) {
virDomainFree ( dom ) ;
vshError ( ctl , FALSE , _ ( " Unable to shrink current MemorySize " ) ) ;
return FALSE ;
}
}
2007-04-02 15:56:38 +04:00
if ( virDomainSetMaxMemory ( dom , kilobytes ) ! = 0 ) {
2007-06-18 12:33:08 +04:00
vshError ( ctl , FALSE , _ ( " Unable to change MaxMemorySize " ) ) ;
2006-08-16 21:30:33 +04:00
ret = FALSE ;
}
virDomainFree ( dom ) ;
return ret ;
}
2006-04-04 18:37:32 +04:00
/*
* " nodeinfo " command
*/
static vshCmdInfo info_nodeinfo [ ] = {
{ " syntax " , " nodeinfo " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " node information " ) } ,
{ " desc " , gettext_noop ( " Returns basic information about the node. " ) } ,
2006-04-04 18:37:32 +04:00
{ NULL , NULL }
} ;
static int
cmdNodeinfo ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
virNodeInfo info ;
2006-09-21 19:24:37 +04:00
2006-04-04 18:37:32 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( virNodeGetInfo ( ctl - > conn , & info ) < 0 ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get node information " ) ) ;
return FALSE ;
}
vshPrint ( ctl , " %-20s %s \n " , _ ( " CPU model: " ) , info . model ) ;
vshPrint ( ctl , " %-20s %d \n " , _ ( " CPU(s): " ) , info . cpus ) ;
vshPrint ( ctl , " %-20s %d MHz \n " , _ ( " CPU frequency: " ) , info . mhz ) ;
vshPrint ( ctl , " %-20s %d \n " , _ ( " CPU socket(s): " ) , info . sockets ) ;
vshPrint ( ctl , " %-20s %d \n " , _ ( " Core(s) per socket: " ) , info . cores ) ;
vshPrint ( ctl , " %-20s %d \n " , _ ( " Thread(s) per core: " ) , info . threads ) ;
vshPrint ( ctl , " %-20s %d \n " , _ ( " NUMA cell(s): " ) , info . nodes ) ;
vshPrint ( ctl , " %-20s %lu kB \n " , _ ( " Memory size: " ) , info . memory ) ;
2006-04-04 18:37:32 +04:00
return TRUE ;
}
2007-03-15 20:24:56 +03:00
/*
* " capabilities " command
*/
static vshCmdInfo info_capabilities [ ] = {
{ " syntax " , " capabilities " } ,
{ " help " , gettext_noop ( " capabilities " ) } ,
{ " desc " , gettext_noop ( " Returns capabilities of hypervisor/driver. " ) } ,
{ NULL , NULL }
} ;
static int
cmdCapabilities ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
char * caps ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ( caps = virConnectGetCapabilities ( ctl - > conn ) ) = = NULL ) {
vshError ( ctl , FALSE , _ ( " failed to get capabilities " ) ) ;
return FALSE ;
}
vshPrint ( ctl , " %s \n " , caps ) ;
return TRUE ;
}
2005-12-13 19:22:05 +03:00
/*
* " dumpxml " command
*/
static vshCmdInfo info_dumpxml [ ] = {
2007-05-03 20:03:02 +04:00
{ " syntax " , " dumpxml <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " domain information in XML " ) } ,
2007-04-10 22:40:50 +04:00
{ " desc " , gettext_noop ( " Output the domain information as an XML dump to stdout. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-13 19:22:05 +03:00
} ;
static vshCmdOptDef opts_dumpxml [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-13 19:22:05 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdDumpXML ( vshControl * ctl , vshCmd * cmd )
{
2005-12-13 19:22:05 +03:00
virDomainPtr dom ;
2005-12-15 20:00:43 +03:00
int ret = TRUE ;
2005-12-13 19:22:05 +03:00
char * dump ;
2006-03-15 15:13:25 +03:00
2005-12-13 19:22:05 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2005-12-15 20:00:43 +03:00
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
2005-12-13 19:22:05 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
2005-12-13 19:22:05 +03:00
dump = virDomainGetXMLDesc ( dom , 0 ) ;
if ( dump ! = NULL ) {
printf ( " %s " , dump ) ;
free ( dump ) ;
} else {
ret = FALSE ;
}
2006-03-15 15:13:25 +03:00
2005-12-13 19:22:05 +03:00
virDomainFree ( dom ) ;
return ret ;
}
2005-12-08 13:23:34 +03:00
/*
2006-04-05 01:52:31 +04:00
* " domname " command
2005-12-08 13:23:34 +03:00
*/
2006-04-05 01:52:31 +04:00
static vshCmdInfo info_domname [ ] = {
2006-05-29 19:39:31 +04:00
{ " syntax " , " domname <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " convert a domain id or UUID to domain name " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
2006-04-05 01:52:31 +04:00
static vshCmdOptDef opts_domname [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain id or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-04-05 01:52:31 +04:00
cmdDomname ( vshControl * ctl , vshCmd * cmd )
2006-03-15 15:13:25 +03:00
{
2005-12-08 13:23:34 +03:00
virDomainPtr dom ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2007-02-07 16:50:18 +03:00
if ( ! ( dom = vshCommandOptDomainBy ( ctl , cmd , " domain " , NULL ,
2007-02-14 18:44:58 +03:00
VSH_BYID | VSH_BYUUID ) ) )
2005-12-08 13:23:34 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
2006-05-29 19:39:31 +04:00
vshPrint ( ctl , " %s \n " , virDomainGetName ( dom ) ) ;
virDomainFree ( dom ) ;
2005-12-08 13:23:34 +03:00
return TRUE ;
}
/*
2006-04-05 01:52:31 +04:00
* " domid " command
2005-12-08 13:23:34 +03:00
*/
2006-04-05 01:52:31 +04:00
static vshCmdInfo info_domid [ ] = {
2006-05-29 19:39:31 +04:00
{ " syntax " , " domid <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " convert a domain name or UUID to domain id " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
2006-04-05 01:52:31 +04:00
static vshCmdOptDef opts_domid [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name or uuid " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , 0 , 0 , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-04-05 01:52:31 +04:00
cmdDomid ( vshControl * ctl , vshCmd * cmd )
2006-03-15 15:13:25 +03:00
{
2005-12-05 14:16:07 +03:00
virDomainPtr dom ;
2006-09-03 21:34:04 +04:00
unsigned int id ;
2005-12-08 13:23:34 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2007-02-07 16:50:18 +03:00
if ( ! ( dom = vshCommandOptDomainBy ( ctl , cmd , " domain " , NULL ,
2007-02-14 18:44:58 +03:00
VSH_BYNAME | VSH_BYUUID ) ) )
2005-12-08 13:23:34 +03:00
return FALSE ;
2007-02-07 16:50:18 +03:00
2006-09-03 21:34:04 +04:00
id = virDomainGetID ( dom ) ;
if ( id = = ( ( unsigned int ) - 1 ) )
2007-02-07 16:50:18 +03:00
vshPrint ( ctl , " %s \n " , " - " ) ;
2006-09-03 21:34:04 +04:00
else
2007-02-07 16:50:18 +03:00
vshPrint ( ctl , " %d \n " , id ) ;
2006-05-29 19:39:31 +04:00
virDomainFree ( dom ) ;
return TRUE ;
}
2006-03-15 15:13:25 +03:00
2006-05-29 19:39:31 +04:00
/*
* " domuuid " command
*/
static vshCmdInfo info_domuuid [ ] = {
{ " syntax " , " domuuid <domain> " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " convert a domain name or id to domain UUID " ) } ,
2006-05-29 19:39:31 +04:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_domuuid [ ] = {
2006-09-21 19:24:37 +04:00
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain id or name " ) } ,
2006-05-29 19:39:31 +04:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDomuuid ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 17:39:45 +03:00
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
2006-05-29 19:39:31 +04:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
2005-12-08 13:23:34 +03:00
return FALSE ;
2006-09-21 19:24:37 +04:00
if ( ! ( dom = vshCommandOptDomainBy ( ctl , cmd , " domain " , NULL ,
2007-02-14 18:44:58 +03:00
VSH_BYNAME | VSH_BYID ) ) )
2006-05-29 19:39:31 +04:00
return FALSE ;
2006-09-21 19:24:37 +04:00
2006-05-29 19:39:31 +04:00
if ( virDomainGetUUIDString ( dom , uuid ) ! = - 1 )
vshPrint ( ctl , " %s \n " , uuid ) ;
else
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get domain UUID " ) ) ;
2005-12-08 13:23:34 +03:00
return TRUE ;
}
2007-08-21 13:31:12 +04:00
/*
* " migrate " command
*/
static vshCmdInfo info_migrate [ ] = {
{ " syntax " , " migrate [--live] <domain> <desturi> [<migrateuri>] " } ,
{ " help " , gettext_noop ( " migrate domain to another host " ) } ,
{ " desc " , gettext_noop ( " Migrate domain to another host. Add --live for live migration. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_migrate [ ] = {
{ " live " , VSH_OT_BOOL , 0 , gettext_noop ( " live migration " ) } ,
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " desturi " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " connection URI of the destination host " ) } ,
{ " migrateuri " , VSH_OT_DATA , 0 , gettext_noop ( " migration URI, usually can be omitted " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdMigrate ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom = NULL ;
const char * desturi ;
const char * migrateuri ;
int flags = 0 , found , ret = FALSE ;
virConnectPtr dconn = NULL ;
virDomainPtr ddom = NULL ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
desturi = vshCommandOptString ( cmd , " desturi " , & found ) ;
if ( ! found ) {
vshError ( ctl , FALSE , _ ( " migrate: Missing desturi " ) ) ;
goto done ;
}
migrateuri = vshCommandOptString ( cmd , " migrateuri " , & found ) ;
if ( ! found ) migrateuri = NULL ;
if ( vshCommandOptBool ( cmd , " live " ) )
flags | = VIR_MIGRATE_LIVE ;
/* Temporarily connect to the destination host. */
dconn = virConnectOpen ( desturi ) ;
if ( ! dconn ) goto done ;
/* Migrate. */
ddom = virDomainMigrate ( dom , dconn , flags , NULL , migrateuri , 0 ) ;
if ( ! ddom ) goto done ;
ret = TRUE ;
done :
if ( dom ) virDomainFree ( dom ) ;
if ( ddom ) virDomainFree ( ddom ) ;
if ( dconn ) virConnectClose ( dconn ) ;
return ret ;
}
2007-02-23 11:58:25 +03:00
/*
* " net-autostart " command
*/
static vshCmdInfo info_network_autostart [ ] = {
{ " syntax " , " net-autostart [--disable] <network> " } ,
{ " help " , gettext_noop ( " autostart a network " ) } ,
{ " desc " ,
gettext_noop ( " Configure a network to be automatically started at boot. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_autostart [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network name or uuid " ) } ,
{ " disable " , VSH_OT_BOOL , 0 , gettext_noop ( " disable autostarting " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkAutostart ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
char * name ;
int autostart ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetwork ( ctl , cmd , " network " , & name ) ) )
return FALSE ;
autostart = ! vshCommandOptBool ( cmd , " disable " ) ;
if ( virNetworkSetAutostart ( network , autostart ) < 0 ) {
2007-04-13 12:04:08 +04:00
if ( autostart )
vshError ( ctl , FALSE , _ ( " failed to mark network %s as autostarted " ) ,
name ) ;
else
vshError ( ctl , FALSE , _ ( " failed to unmark network %s as autostarted " ) ,
name ) ;
2007-02-23 11:58:25 +03:00
virNetworkFree ( network ) ;
return FALSE ;
}
2007-04-13 12:04:08 +04:00
if ( autostart )
vshPrint ( ctl , _ ( " Network %s marked as autostarted \n " ) , name ) ;
else
vshPrint ( ctl , _ ( " Network %s unmarked as autostarted \n " ) , name ) ;
2007-02-23 11:58:25 +03:00
return TRUE ;
}
2006-05-29 19:39:31 +04:00
2007-02-14 19:53:55 +03:00
/*
* " net-create " command
*/
static vshCmdInfo info_network_create [ ] = {
{ " syntax " , " create a network from an XML <file> " } ,
{ " help " , gettext_noop ( " create a network from an XML file " ) } ,
{ " desc " , gettext_noop ( " Create a network. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_create [ ] = {
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " file containing an XML network description " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkCreate ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
char * from ;
int found ;
int ret = TRUE ;
2007-05-23 19:09:19 +04:00
char * buffer ;
2007-02-14 19:53:55 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found )
return FALSE ;
2007-05-23 19:09:19 +04:00
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
network = virNetworkCreateXML ( ctl - > conn , buffer ) ;
free ( buffer ) ;
2007-02-14 19:53:55 +03:00
if ( network ! = NULL ) {
vshPrint ( ctl , _ ( " Network %s created from %s \n " ) ,
virNetworkGetName ( network ) , from ) ;
} else {
vshError ( ctl , FALSE , _ ( " Failed to create network from %s " ) , from ) ;
ret = FALSE ;
}
return ret ;
}
/*
* " net-define " command
*/
static vshCmdInfo info_network_define [ ] = {
{ " syntax " , " define a network from an XML <file> " } ,
{ " help " , gettext_noop ( " define (but don't start) a network from an XML file " ) } ,
{ " desc " , gettext_noop ( " Define a network. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_define [ ] = {
2007-04-10 22:40:50 +04:00
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " file containing an XML network description " ) } ,
2007-02-14 19:53:55 +03:00
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkDefine ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
char * from ;
int found ;
int ret = TRUE ;
2007-05-23 19:09:19 +04:00
char * buffer ;
2007-02-14 19:53:55 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found )
return FALSE ;
2007-05-23 19:09:19 +04:00
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
network = virNetworkDefineXML ( ctl - > conn , buffer ) ;
free ( buffer ) ;
2007-02-14 19:53:55 +03:00
if ( network ! = NULL ) {
vshPrint ( ctl , _ ( " Network %s defined from %s \n " ) ,
virNetworkGetName ( network ) , from ) ;
} else {
vshError ( ctl , FALSE , _ ( " Failed to define network from %s " ) , from ) ;
ret = FALSE ;
}
return ret ;
}
/*
* " net-destroy " command
*/
static vshCmdInfo info_network_destroy [ ] = {
{ " syntax " , " net-destroy <network> " } ,
{ " help " , gettext_noop ( " destroy a network " ) } ,
{ " desc " , gettext_noop ( " Destroy a given network. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_destroy [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network name, id or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkDestroy ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
int ret = TRUE ;
char * name ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetwork ( ctl , cmd , " network " , & name ) ) )
return FALSE ;
if ( virNetworkDestroy ( network ) = = 0 ) {
vshPrint ( ctl , _ ( " Network %s destroyed \n " ) , name ) ;
} else {
vshError ( ctl , FALSE , _ ( " Failed to destroy network %s " ) , name ) ;
ret = FALSE ;
virNetworkFree ( network ) ;
}
return ret ;
}
/*
* " net-dumpxml " command
*/
static vshCmdInfo info_network_dumpxml [ ] = {
2007-05-03 20:03:02 +04:00
{ " syntax " , " net-dumpxml <network> " } ,
2007-02-14 19:53:55 +03:00
{ " help " , gettext_noop ( " network information in XML " ) } ,
2007-04-10 22:40:50 +04:00
{ " desc " , gettext_noop ( " Output the network information as an XML dump to stdout. " ) } ,
2007-02-14 19:53:55 +03:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_dumpxml [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network name, id or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkDumpXML ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
int ret = TRUE ;
char * dump ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetwork ( ctl , cmd , " network " , NULL ) ) )
return FALSE ;
dump = virNetworkGetXMLDesc ( network , 0 ) ;
if ( dump ! = NULL ) {
printf ( " %s " , dump ) ;
free ( dump ) ;
} else {
ret = FALSE ;
}
virNetworkFree ( network ) ;
return ret ;
}
/*
* " net-list " command
*/
static vshCmdInfo info_network_list [ ] = {
{ " syntax " , " net-list [ --inactive | --all ] " } ,
{ " help " , gettext_noop ( " list networks " ) } ,
{ " desc " , gettext_noop ( " Returns list of networks. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_list [ ] = {
{ " inactive " , VSH_OT_BOOL , 0 , gettext_noop ( " list inactive networks " ) } ,
{ " all " , VSH_OT_BOOL , 0 , gettext_noop ( " list inactive & active networks " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkList ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
int inactive = vshCommandOptBool ( cmd , " inactive " ) ;
int all = vshCommandOptBool ( cmd , " all " ) ;
int active = ! inactive | | all ? 1 : 0 ;
int maxactive = 0 , maxinactive = 0 , i ;
2007-03-07 00:55:44 +03:00
char * * activeNames = NULL , * * inactiveNames = NULL ;
2007-02-14 19:53:55 +03:00
inactive | = all ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( active ) {
2007-02-20 21:25:46 +03:00
maxactive = virConnectNumOfNetworks ( ctl - > conn ) ;
if ( maxactive < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list active networks " ) ) ;
return FALSE ;
2007-02-14 19:53:55 +03:00
}
2007-02-20 21:25:46 +03:00
if ( maxactive ) {
2007-03-09 16:44:24 +03:00
activeNames = vshMalloc ( ctl , sizeof ( char * ) * maxactive ) ;
2007-02-20 21:25:46 +03:00
2007-03-09 16:44:24 +03:00
if ( ( maxactive = virConnectListNetworks ( ctl - > conn , activeNames ,
maxactive ) ) < 0 ) {
2007-02-20 21:25:46 +03:00
vshError ( ctl , FALSE , _ ( " Failed to list active networks " ) ) ;
free ( activeNames ) ;
return FALSE ;
}
2007-02-14 19:53:55 +03:00
2007-03-09 16:44:24 +03:00
qsort ( & activeNames [ 0 ] , maxactive , sizeof ( char * ) , namesorter ) ;
2007-02-20 21:25:46 +03:00
}
2007-02-14 19:53:55 +03:00
}
if ( inactive ) {
2007-02-20 21:25:46 +03:00
maxinactive = virConnectNumOfDefinedNetworks ( ctl - > conn ) ;
if ( maxinactive < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list inactive networks " ) ) ;
if ( activeNames )
free ( activeNames ) ;
return FALSE ;
2007-02-14 19:53:55 +03:00
}
2007-02-20 21:25:46 +03:00
if ( maxinactive ) {
inactiveNames = vshMalloc ( ctl , sizeof ( char * ) * maxinactive ) ;
if ( ( maxinactive = virConnectListDefinedNetworks ( ctl - > conn , inactiveNames , maxinactive ) ) < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to list inactive networks " ) ) ;
if ( activeNames )
free ( activeNames ) ;
free ( inactiveNames ) ;
return FALSE ;
}
2007-02-14 19:53:55 +03:00
2007-02-20 21:25:46 +03:00
qsort ( & inactiveNames [ 0 ] , maxinactive , sizeof ( char * ) , namesorter ) ;
}
2007-02-14 19:53:55 +03:00
}
2007-02-23 11:58:25 +03:00
vshPrintExtra ( ctl , " %-20s %-10s %-10s \n " , _ ( " Name " ) , _ ( " State " ) , _ ( " Autostart " ) ) ;
vshPrintExtra ( ctl , " ----------------------------------------- \n " ) ;
2007-02-14 19:53:55 +03:00
for ( i = 0 ; i < maxactive ; i + + ) {
virNetworkPtr network = virNetworkLookupByName ( ctl - > conn , activeNames [ i ] ) ;
2007-02-23 11:58:25 +03:00
const char * autostartStr ;
int autostart = 0 ;
2007-02-14 19:53:55 +03:00
/* this kind of work with networks is not atomic operation */
if ( ! network ) {
free ( activeNames [ i ] ) ;
continue ;
2007-02-20 21:25:46 +03:00
}
2007-02-14 19:53:55 +03:00
2007-02-23 11:58:25 +03:00
if ( virNetworkGetAutostart ( network , & autostart ) < 0 )
autostartStr = _ ( " no autostart " ) ;
else
autostartStr = autostart ? " yes " : " no " ;
vshPrint ( ctl , " %-20s %-10s %-10s \n " ,
virNetworkGetName ( network ) ,
_ ( " active " ) ,
autostartStr ) ;
2007-02-14 19:53:55 +03:00
virNetworkFree ( network ) ;
free ( activeNames [ i ] ) ;
}
for ( i = 0 ; i < maxinactive ; i + + ) {
virNetworkPtr network = virNetworkLookupByName ( ctl - > conn , inactiveNames [ i ] ) ;
2007-02-23 11:58:25 +03:00
const char * autostartStr ;
int autostart = 0 ;
2007-02-14 19:53:55 +03:00
/* this kind of work with networks is not atomic operation */
if ( ! network ) {
free ( inactiveNames [ i ] ) ;
continue ;
2007-02-20 21:25:46 +03:00
}
2007-02-14 19:53:55 +03:00
2007-02-23 11:58:25 +03:00
if ( virNetworkGetAutostart ( network , & autostart ) < 0 )
autostartStr = _ ( " no autostart " ) ;
else
autostartStr = autostart ? " yes " : " no " ;
vshPrint ( ctl , " %-20s %s %s \n " ,
inactiveNames [ i ] ,
_ ( " inactive " ) ,
autostartStr ) ;
2007-02-14 19:53:55 +03:00
virNetworkFree ( network ) ;
free ( inactiveNames [ i ] ) ;
}
if ( activeNames )
free ( activeNames ) ;
if ( inactiveNames )
free ( inactiveNames ) ;
return TRUE ;
}
/*
* " net-name " command
*/
static vshCmdInfo info_network_name [ ] = {
{ " syntax " , " net-name <network> " } ,
{ " help " , gettext_noop ( " convert a network UUID to network name " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_name [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkName ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetworkBy ( ctl , cmd , " network " , NULL ,
VSH_BYUUID ) ) )
return FALSE ;
vshPrint ( ctl , " %s \n " , virNetworkGetName ( network ) ) ;
virNetworkFree ( network ) ;
return TRUE ;
}
/*
* " net-start " command
*/
static vshCmdInfo info_network_start [ ] = {
{ " syntax " , " start <network> " } ,
{ " help " , gettext_noop ( " start a (previously defined) inactive network " ) } ,
{ " desc " , gettext_noop ( " Start a network. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_start [ ] = {
{ " name " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " name of the inactive network " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkStart ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
int ret = TRUE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2007-02-23 13:27:53 +03:00
if ( ! ( network = vshCommandOptNetworkBy ( ctl , cmd , " name " , NULL , VSH_BYNAME ) ) )
return FALSE ;
2007-02-14 19:53:55 +03:00
if ( virNetworkCreate ( network ) = = 0 ) {
vshPrint ( ctl , _ ( " Network %s started \n " ) ,
2007-02-23 13:27:53 +03:00
virNetworkGetName ( network ) ) ;
2007-02-14 19:53:55 +03:00
} else {
2007-02-23 13:27:53 +03:00
vshError ( ctl , FALSE , _ ( " Failed to start network %s " ) ,
virNetworkGetName ( network ) ) ;
2007-02-14 19:53:55 +03:00
ret = FALSE ;
}
return ret ;
}
/*
* " net-undefine " command
*/
static vshCmdInfo info_network_undefine [ ] = {
{ " syntax " , " net-undefine <network> " } ,
{ " help " , gettext_noop ( " undefine an inactive network " ) } ,
{ " desc " , gettext_noop ( " Undefine the configuration for an inactive network. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_undefine [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network name or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkUndefine ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
int ret = TRUE ;
char * name ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetwork ( ctl , cmd , " network " , & name ) ) )
return FALSE ;
if ( virNetworkUndefine ( network ) = = 0 ) {
vshPrint ( ctl , _ ( " Network %s has been undefined \n " ) , name ) ;
} else {
vshError ( ctl , FALSE , _ ( " Failed to undefine network %s " ) , name ) ;
ret = FALSE ;
}
return ret ;
}
/*
* " net-uuid " command
*/
static vshCmdInfo info_network_uuid [ ] = {
{ " syntax " , " net-uuid <network> " } ,
{ " help " , gettext_noop ( " convert a network name to network UUID " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_network_uuid [ ] = {
{ " network " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network name " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdNetworkUuid ( vshControl * ctl , vshCmd * cmd )
{
virNetworkPtr network ;
char uuid [ VIR_UUID_STRING_BUFLEN ] ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( network = vshCommandOptNetworkBy ( ctl , cmd , " network " , NULL ,
VSH_BYNAME ) ) )
return FALSE ;
if ( virNetworkGetUUIDString ( network , uuid ) ! = - 1 )
vshPrint ( ctl , " %s \n " , uuid ) ;
else
vshError ( ctl , FALSE , _ ( " failed to get network UUID " ) ) ;
return TRUE ;
}
2005-12-08 16:26:52 +03:00
/*
* " version " command
*/
static vshCmdInfo info_version [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " version " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " show version " ) } ,
{ " desc " , gettext_noop ( " Display the system version information. " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 16:26:52 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdVersion ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
2005-12-08 16:26:52 +03:00
unsigned long hvVersion ;
const char * hvType ;
2005-12-08 18:08:46 +03:00
unsigned long libVersion ;
unsigned long includeVersion ;
unsigned long apiVersion ;
int ret ;
unsigned int major ;
unsigned int minor ;
unsigned int rel ;
2005-12-08 16:26:52 +03:00
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
2006-03-15 15:13:25 +03:00
2005-12-08 16:26:52 +03:00
hvType = virConnectGetType ( ctl - > conn ) ;
if ( hvType = = NULL ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get hypervisor type " ) ) ;
2005-12-08 16:26:52 +03:00
return FALSE ;
}
2005-12-08 18:08:46 +03:00
includeVersion = LIBVIR_VERSION_NUMBER ;
major = includeVersion / 1000000 ;
includeVersion % = 1000000 ;
minor = includeVersion / 1000 ;
rel = includeVersion % 1000 ;
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Compiled against library: libvir %d.%d.%d \n " ) ,
2005-12-08 18:08:46 +03:00
major , minor , rel ) ;
ret = virGetVersion ( & libVersion , hvType , & apiVersion ) ;
if ( ret < 0 ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get the library version " ) ) ;
2005-12-08 18:08:46 +03:00
return FALSE ;
}
major = libVersion / 1000000 ;
libVersion % = 1000000 ;
minor = libVersion / 1000 ;
rel = libVersion % 1000 ;
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Using library: libvir %d.%d.%d \n " ) ,
2005-12-08 18:08:46 +03:00
major , minor , rel ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 18:08:46 +03:00
major = apiVersion / 1000000 ;
apiVersion % = 1000000 ;
minor = apiVersion / 1000 ;
rel = apiVersion % 1000 ;
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Using API: %s %d.%d.%d \n " ) , hvType ,
2005-12-08 18:08:46 +03:00
major , minor , rel ) ;
2006-03-15 15:13:25 +03:00
ret = virConnectGetVersion ( ctl - > conn , & hvVersion ) ;
2005-12-08 18:08:46 +03:00
if ( ret < 0 ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get the hypervisor version " ) ) ;
2005-12-08 16:26:52 +03:00
return FALSE ;
}
if ( hvVersion = = 0 ) {
2006-05-22 18:38:33 +04:00
vshPrint ( ctl ,
2006-09-21 19:24:37 +04:00
_ ( " Cannot extract running %s hypervisor version \n " ) , hvType ) ;
2005-12-08 16:26:52 +03:00
} else {
2005-12-08 18:08:46 +03:00
major = hvVersion / 1000000 ;
2005-12-08 16:26:52 +03:00
hvVersion % = 1000000 ;
2005-12-08 18:08:46 +03:00
minor = hvVersion / 1000 ;
rel = hvVersion % 1000 ;
2005-12-08 16:26:52 +03:00
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " Running hypervisor: %s %d.%d.%d \n " ) ,
2006-03-15 15:13:25 +03:00
hvType , major , minor , rel ) ;
2005-12-08 16:26:52 +03:00
}
return TRUE ;
}
2007-01-26 14:54:29 +03:00
/*
2007-06-26 15:42:46 +04:00
* " hostname " command
*/
static vshCmdInfo info_hostname [ ] = {
{ " syntax " , " hostname " } ,
{ " help " , gettext_noop ( " print the hypervisor hostname " ) } ,
{ NULL , NULL }
} ;
static int
cmdHostname ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
char * hostname ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
hostname = virConnectGetHostname ( ctl - > conn ) ;
if ( hostname = = NULL ) {
vshError ( ctl , FALSE , _ ( " failed to get hostname " ) ) ;
return FALSE ;
}
vshPrint ( ctl , " %s \n " , hostname ) ;
free ( hostname ) ;
return TRUE ;
}
/*
* " uri " command
*/
static vshCmdInfo info_uri [ ] = {
{ " syntax " , " uri " } ,
{ " help " , gettext_noop ( " print the hypervisor canonical URI " ) } ,
{ NULL , NULL }
} ;
static int
cmdURI ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
char * uri ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
uri = virConnectGetURI ( ctl - > conn ) ;
if ( uri = = NULL ) {
vshError ( ctl , FALSE , _ ( " failed to get URI " ) ) ;
return FALSE ;
}
vshPrint ( ctl , " %s \n " , uri ) ;
free ( uri ) ;
return TRUE ;
}
/*
* " vncdisplay " command
2007-01-26 14:54:29 +03:00
*/
static vshCmdInfo info_vncdisplay [ ] = {
{ " syntax " , " vncdisplay <domain> " } ,
{ " help " , gettext_noop ( " vnc display " ) } ,
2007-04-10 22:40:50 +04:00
{ " desc " , gettext_noop ( " Output the IP address and port number for the VNC display. " ) } ,
2007-01-26 14:54:29 +03:00
{ NULL , NULL }
} ;
static vshCmdOptDef opts_vncdisplay [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdVNCDisplay ( vshControl * ctl , vshCmd * cmd )
{
xmlDocPtr xml = NULL ;
xmlXPathObjectPtr obj = NULL ;
xmlXPathContextPtr ctxt = NULL ;
virDomainPtr dom ;
int ret = FALSE ;
int port = 0 ;
char * doc ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
doc = virDomainGetXMLDesc ( dom , 0 ) ;
if ( ! doc )
2007-02-07 16:50:18 +03:00
goto cleanup ;
2007-01-26 14:54:29 +03:00
xml = xmlReadDoc ( ( const xmlChar * ) doc , " domain.xml " , NULL ,
2007-02-07 16:50:18 +03:00
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOWARNING ) ;
2007-01-26 14:54:29 +03:00
free ( doc ) ;
if ( ! xml )
goto cleanup ;
ctxt = xmlXPathNewContext ( xml ) ;
if ( ! ctxt )
goto cleanup ;
obj = xmlXPathEval ( BAD_CAST " string(/domain/devices/graphics[@type='vnc']/@port) " , ctxt ) ;
if ( ( obj = = NULL ) | | ( obj - > type ! = XPATH_STRING ) | |
2007-02-07 16:50:18 +03:00
( obj - > stringval = = NULL ) | | ( obj - > stringval [ 0 ] = = 0 ) ) {
2007-01-26 14:54:29 +03:00
goto cleanup ;
}
2007-11-12 17:00:32 +03:00
if ( xstrtol_i ( ( const char * ) obj - > stringval , NULL , 10 , & port ) | | port < 0 )
2007-02-07 16:50:18 +03:00
goto cleanup ;
2007-01-26 14:54:29 +03:00
xmlXPathFreeObject ( obj ) ;
obj = xmlXPathEval ( BAD_CAST " string(/domain/devices/graphics[@type='vnc']/@listen) " , ctxt ) ;
if ( ( obj = = NULL ) | | ( obj - > type ! = XPATH_STRING ) | |
2007-03-02 17:22:33 +03:00
( obj - > stringval = = NULL ) | | ( obj - > stringval [ 0 ] = = 0 ) | |
! strcmp ( ( const char * ) obj - > stringval , " 0.0.0.0 " ) ) {
2007-01-26 14:54:29 +03:00
vshPrint ( ctl , " :%d \n " , port - 5900 ) ;
} else {
vshPrint ( ctl , " %s:%d \n " , ( const char * ) obj - > stringval , port - 5900 ) ;
}
xmlXPathFreeObject ( obj ) ;
obj = NULL ;
2007-08-29 11:47:09 +04:00
ret = TRUE ;
2007-01-26 14:54:29 +03:00
cleanup :
if ( obj )
2007-02-07 16:50:18 +03:00
xmlXPathFreeObject ( obj ) ;
2007-01-26 14:54:29 +03:00
if ( ctxt )
xmlXPathFreeContext ( ctxt ) ;
if ( xml )
xmlFreeDoc ( xml ) ;
virDomainFree ( dom ) ;
return ret ;
}
2007-07-26 12:41:16 +04:00
/*
* " ttyconsole " command
*/
static vshCmdInfo info_ttyconsole [ ] = {
{ " syntax " , " ttyconsole <domain> " } ,
{ " help " , gettext_noop ( " tty console " ) } ,
{ " desc " , gettext_noop ( " Output the device for the TTY console. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_ttyconsole [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdTTYConsole ( vshControl * ctl , vshCmd * cmd )
{
xmlDocPtr xml = NULL ;
xmlXPathObjectPtr obj = NULL ;
xmlXPathContextPtr ctxt = NULL ;
virDomainPtr dom ;
int ret = FALSE ;
char * doc ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
doc = virDomainGetXMLDesc ( dom , 0 ) ;
if ( ! doc )
goto cleanup ;
xml = xmlReadDoc ( ( const xmlChar * ) doc , " domain.xml " , NULL ,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOWARNING ) ;
free ( doc ) ;
if ( ! xml )
goto cleanup ;
ctxt = xmlXPathNewContext ( xml ) ;
if ( ! ctxt )
goto cleanup ;
obj = xmlXPathEval ( BAD_CAST " string(/domain/devices/console/@tty) " , ctxt ) ;
if ( ( obj = = NULL ) | | ( obj - > type ! = XPATH_STRING ) | |
( obj - > stringval = = NULL ) | | ( obj - > stringval [ 0 ] = = 0 ) ) {
goto cleanup ;
}
vshPrint ( ctl , " %s \n " , ( const char * ) obj - > stringval ) ;
cleanup :
if ( obj )
xmlXPathFreeObject ( obj ) ;
if ( ctxt )
xmlXPathFreeContext ( ctxt ) ;
if ( xml )
xmlFreeDoc ( xml ) ;
virDomainFree ( dom ) ;
return ret ;
}
2007-05-23 19:09:19 +04:00
/*
* " attach-device " command
*/
static vshCmdInfo info_attach_device [ ] = {
{ " syntax " , " attach-device <domain> <file> " } ,
{ " help " , gettext_noop ( " attach device from an XML file " ) } ,
{ " desc " , gettext_noop ( " Attach device from an XML <file>. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_attach_device [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " XML file " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdAttachDevice ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * from ;
char * buffer ;
int ret = TRUE ;
int found ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found ) {
virDomainFree ( dom ) ;
return FALSE ;
}
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
ret = virDomainAttachDevice ( dom , buffer ) ;
free ( buffer ) ;
if ( ret < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to attach device from %s " ) , from ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
virDomainFree ( dom ) ;
return TRUE ;
}
/*
* " detach-device " command
*/
static vshCmdInfo info_detach_device [ ] = {
{ " syntax " , " detach-device <domain> <file> " } ,
{ " help " , gettext_noop ( " detach device from an XML file " ) } ,
{ " desc " , gettext_noop ( " Detach device from an XML <file> " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_detach_device [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " file " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " XML file " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDetachDevice ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom ;
char * from ;
char * buffer ;
int ret = TRUE ;
int found ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
return FALSE ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
return FALSE ;
from = vshCommandOptString ( cmd , " file " , & found ) ;
if ( ! found ) {
virDomainFree ( dom ) ;
return FALSE ;
}
buffer = readFile ( ctl , from ) ;
if ( buffer = = NULL ) return FALSE ;
ret = virDomainDetachDevice ( dom , buffer ) ;
free ( buffer ) ;
if ( ret < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to detach device from %s " ) , from ) ;
virDomainFree ( dom ) ;
return FALSE ;
}
virDomainFree ( dom ) ;
return TRUE ;
}
2007-01-26 14:54:29 +03:00
2007-06-19 13:12:55 +04:00
/*
* " attach-interface " command
*/
static vshCmdInfo info_attach_interface [ ] = {
{ " syntax " , " attach-interface <domain> <type> <source> [--target <target>] [--mac <mac>] [--script <script>] " } ,
{ " help " , gettext_noop ( " attach network interface " ) } ,
{ " desc " , gettext_noop ( " Attach new network interface. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_attach_interface [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " type " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network interface type " ) } ,
{ " source " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " source of network interface " ) } ,
{ " target " , VSH_OT_DATA , 0 , gettext_noop ( " target network name " ) } ,
{ " mac " , VSH_OT_DATA , 0 , gettext_noop ( " MAC adress " ) } ,
{ " script " , VSH_OT_DATA , 0 , gettext_noop ( " script used to bridge network interface " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdAttachInterface ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom = NULL ;
char * mac , * target , * script , * type , * source ;
int typ , ret = FALSE ;
char * buf = NULL , * tmp = NULL ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
goto cleanup ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
goto cleanup ;
if ( ! ( type = vshCommandOptString ( cmd , " type " , NULL ) ) )
goto cleanup ;
source = vshCommandOptString ( cmd , " source " , NULL ) ;
target = vshCommandOptString ( cmd , " target " , NULL ) ;
mac = vshCommandOptString ( cmd , " mac " , NULL ) ;
script = vshCommandOptString ( cmd , " script " , NULL ) ;
/* check interface type */
if ( strcmp ( type , " network " ) = = 0 ) {
typ = 1 ;
} else if ( strcmp ( type , " bridge " ) = = 0 ) {
typ = 2 ;
} else {
vshError ( ctl , FALSE , _ ( " No support %s in command 'attach-interface' " ) , type ) ;
goto cleanup ;
}
/* Make XML of interface */
tmp = vshMalloc ( ctl , 1 ) ;
if ( ! tmp ) goto cleanup ;
buf = vshMalloc ( ctl , strlen ( type ) + 25 ) ;
if ( ! buf ) goto cleanup ;
sprintf ( buf , " <interface type='%s'> \n " , type ) ;
tmp = vshRealloc ( ctl , tmp , strlen ( source ) + 28 ) ;
if ( ! tmp ) goto cleanup ;
if ( typ = = 1 ) {
sprintf ( tmp , " <source network='%s'/> \n " , source ) ;
} else if ( typ = = 2 ) {
sprintf ( tmp , " <source bridge='%s'/> \n " , source ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
if ( target ! = NULL ) {
tmp = vshRealloc ( ctl , tmp , strlen ( target ) + 24 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <target dev='%s'/> \n " , target ) ;
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
}
if ( mac ! = NULL ) {
tmp = vshRealloc ( ctl , tmp , strlen ( mac ) + 25 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <mac address='%s'/> \n " , mac ) ;
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
}
if ( script ! = NULL ) {
tmp = vshRealloc ( ctl , tmp , strlen ( script ) + 25 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <script path='%s'/> \n " , script ) ;
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + 19 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , " </interface> \n " ) ;
if ( virDomainAttachDevice ( dom , buf ) )
goto cleanup ;
ret = TRUE ;
cleanup :
if ( dom )
virDomainFree ( dom ) ;
if ( buf )
free ( buf ) ;
if ( tmp )
free ( tmp ) ;
return ret ;
}
/*
* " detach-interface " command
*/
static vshCmdInfo info_detach_interface [ ] = {
{ " syntax " , " detach-interface <domain> <type> [--mac <mac>] " } ,
{ " help " , gettext_noop ( " detach network interface " ) } ,
{ " desc " , gettext_noop ( " Detach network interface. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_detach_interface [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " type " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " network interface type " ) } ,
{ " mac " , VSH_OT_DATA , 0 , gettext_noop ( " MAC adress " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDetachInterface ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom = NULL ;
xmlDocPtr xml = NULL ;
xmlXPathObjectPtr obj = NULL ;
xmlXPathContextPtr ctxt = NULL ;
xmlNodePtr cur = NULL ;
xmlChar * tmp_mac = NULL ;
xmlBufferPtr xml_buf = NULL ;
char * doc , * mac = NULL , * type ;
char buf [ 64 ] ;
int i = 0 , diff_mac , ret = FALSE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
goto cleanup ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
goto cleanup ;
if ( ! ( type = vshCommandOptString ( cmd , " type " , NULL ) ) )
goto cleanup ;
mac = vshCommandOptString ( cmd , " mac " , NULL ) ;
doc = virDomainGetXMLDesc ( dom , 0 ) ;
if ( ! doc )
goto cleanup ;
xml = xmlReadDoc ( ( const xmlChar * ) doc , " domain.xml " , NULL ,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOWARNING ) ;
free ( doc ) ;
if ( ! xml ) {
vshError ( ctl , FALSE , _ ( " Failed to get interface information " ) ) ;
goto cleanup ;
}
ctxt = xmlXPathNewContext ( xml ) ;
if ( ! ctxt ) {
vshError ( ctl , FALSE , _ ( " Failed to get interface information " ) ) ;
goto cleanup ;
}
sprintf ( buf , " /domain/devices/interface[@type='%s'] " , type ) ;
obj = xmlXPathEval ( BAD_CAST buf , ctxt ) ;
if ( ( obj = = NULL ) | | ( obj - > type ! = XPATH_NODESET ) | |
( obj - > nodesetval = = NULL ) | | ( obj - > nodesetval - > nodeNr = = 0 ) ) {
vshError ( ctl , FALSE , _ ( " No found interface whose type is %s " ) , type ) ;
goto cleanup ;
}
if ( ! mac )
goto hit ;
/* search mac */
for ( ; i < obj - > nodesetval - > nodeNr ; i + + ) {
cur = obj - > nodesetval - > nodeTab [ i ] - > children ;
while ( cur ! = NULL ) {
if ( cur - > type = = XML_ELEMENT_NODE & & xmlStrEqual ( cur - > name , BAD_CAST " mac " ) ) {
tmp_mac = xmlGetProp ( cur , BAD_CAST " address " ) ;
diff_mac = xmlStrcasecmp ( tmp_mac , BAD_CAST mac ) ;
xmlFree ( tmp_mac ) ;
if ( ! diff_mac ) {
goto hit ;
}
}
cur = cur - > next ;
}
}
vshError ( ctl , FALSE , _ ( " No found interface whose MAC address is %s " ) , mac ) ;
goto cleanup ;
hit :
xml_buf = xmlBufferCreate ( ) ;
if ( ! xml_buf ) {
vshError ( ctl , FALSE , _ ( " Failed to allocate memory " ) ) ;
goto cleanup ;
}
if ( xmlNodeDump ( xml_buf , xml , obj - > nodesetval - > nodeTab [ i ] , 0 , 0 ) < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to create XML " ) ) ;
goto cleanup ;
}
ret = virDomainDetachDevice ( dom , ( char * ) xmlBufferContent ( xml_buf ) ) ;
if ( ret ! = 0 )
ret = FALSE ;
else
ret = TRUE ;
cleanup :
if ( dom )
virDomainFree ( dom ) ;
if ( obj )
xmlXPathFreeObject ( obj ) ;
if ( ctxt )
xmlXPathFreeContext ( ctxt ) ;
if ( xml )
xmlFreeDoc ( xml ) ;
if ( xml_buf )
xmlBufferFree ( xml_buf ) ;
return ret ;
}
/*
* " attach-disk " command
*/
static vshCmdInfo info_attach_disk [ ] = {
{ " syntax " , " attach-disk <domain> <source> <target> [--driver <driver>] [--subdriver <subdriver>] [--type <type>] [--mode <mode>] " } ,
{ " help " , gettext_noop ( " attach disk device " ) } ,
{ " desc " , gettext_noop ( " Attach new disk device. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_attach_disk [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " source " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " source of disk device " ) } ,
{ " target " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " target of disk device " ) } ,
{ " driver " , VSH_OT_DATA , 0 , gettext_noop ( " driver of disk device " ) } ,
{ " subdriver " , VSH_OT_DATA , 0 , gettext_noop ( " subdriver of disk device " ) } ,
{ " type " , VSH_OT_DATA , 0 , gettext_noop ( " target device type " ) } ,
{ " mode " , VSH_OT_DATA , 0 , gettext_noop ( " mode of device reading and writing " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdAttachDisk ( vshControl * ctl , vshCmd * cmd )
{
virDomainPtr dom = NULL ;
char * source , * target , * driver , * subdriver , * type , * mode ;
int isFile = 0 , ret = FALSE ;
char * buf = NULL , * tmp = NULL ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
goto cleanup ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
goto cleanup ;
if ( ! ( source = vshCommandOptString ( cmd , " source " , NULL ) ) )
goto cleanup ;
if ( ! ( target = vshCommandOptString ( cmd , " target " , NULL ) ) )
goto cleanup ;
driver = vshCommandOptString ( cmd , " driver " , NULL ) ;
subdriver = vshCommandOptString ( cmd , " subdriver " , NULL ) ;
type = vshCommandOptString ( cmd , " type " , NULL ) ;
mode = vshCommandOptString ( cmd , " mode " , NULL ) ;
if ( type ) {
if ( strcmp ( type , " cdrom " ) & & strcmp ( type , " disk " ) ) {
vshError ( ctl , FALSE , _ ( " No support %s in command 'attach-disk' " ) , type ) ;
goto cleanup ;
}
}
if ( driver ) {
if ( ! strcmp ( driver , " file " ) | | ! strcmp ( driver , " tap " ) ) {
isFile = 1 ;
} else if ( strcmp ( driver , " phy " ) ) {
vshError ( ctl , FALSE , _ ( " No support %s in command 'attach-disk' " ) , driver ) ;
goto cleanup ;
}
}
if ( mode ) {
if ( strcmp ( mode , " readonly " ) & & strcmp ( mode , " shareable " ) ) {
vshError ( ctl , FALSE , _ ( " No support %s in command 'attach-disk' " ) , mode ) ;
goto cleanup ;
}
}
/* Make XML of disk */
tmp = vshMalloc ( ctl , 1 ) ;
if ( ! tmp ) goto cleanup ;
buf = vshMalloc ( ctl , 23 ) ;
if ( ! buf ) goto cleanup ;
if ( isFile ) {
sprintf ( buf , " <disk type='file' " ) ;
} else {
sprintf ( buf , " <disk type='block' " ) ;
}
if ( type ) {
tmp = vshRealloc ( ctl , tmp , strlen ( type ) + 13 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " device='%s'> \n " , type ) ;
} else {
tmp = vshRealloc ( ctl , tmp , 3 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " > \n " ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
if ( driver ) {
tmp = vshRealloc ( ctl , tmp , strlen ( driver ) + 22 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <driver name='%s' " , driver ) ;
} else {
tmp = vshRealloc ( ctl , tmp , 25 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <driver name='phy' " ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
if ( subdriver ) {
tmp = vshRealloc ( ctl , tmp , strlen ( subdriver ) + 12 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " type='%s'/> \n " , subdriver ) ;
} else {
tmp = vshRealloc ( ctl , tmp , 4 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " /> \n " ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
tmp = vshRealloc ( ctl , tmp , strlen ( source ) + 25 ) ;
if ( ! tmp ) goto cleanup ;
if ( isFile ) {
sprintf ( tmp , " <source file='%s'/> \n " , source ) ;
} else {
sprintf ( tmp , " <source dev='%s'/> \n " , source ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
tmp = vshRealloc ( ctl , tmp , strlen ( target ) + 24 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <target dev='%s'/> \n " , target ) ;
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
if ( mode ! = NULL ) {
tmp = vshRealloc ( ctl , tmp , strlen ( mode ) + 11 ) ;
if ( ! tmp ) goto cleanup ;
sprintf ( tmp , " <%s/> \n " , mode ) ;
buf = vshRealloc ( ctl , buf , strlen ( buf ) + strlen ( tmp ) + 1 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , tmp ) ;
}
buf = vshRealloc ( ctl , buf , strlen ( buf ) + 13 ) ;
if ( ! buf ) goto cleanup ;
strcat ( buf , " </disk> \n " ) ;
if ( virDomainAttachDevice ( dom , buf ) )
goto cleanup ;
ret = TRUE ;
cleanup :
if ( dom )
virDomainFree ( dom ) ;
if ( buf )
free ( buf ) ;
if ( tmp )
free ( tmp ) ;
return ret ;
}
/*
* " detach-disk " command
*/
static vshCmdInfo info_detach_disk [ ] = {
{ " syntax " , " detach-disk <domain> <target> " } ,
{ " help " , gettext_noop ( " detach disk device " ) } ,
{ " desc " , gettext_noop ( " Detach disk device. " ) } ,
{ NULL , NULL }
} ;
static vshCmdOptDef opts_detach_disk [ ] = {
{ " domain " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " domain name, id or uuid " ) } ,
{ " target " , VSH_OT_DATA , VSH_OFLAG_REQ , gettext_noop ( " target of disk device " ) } ,
{ NULL , 0 , 0 , NULL }
} ;
static int
cmdDetachDisk ( vshControl * ctl , vshCmd * cmd )
{
xmlDocPtr xml = NULL ;
xmlXPathObjectPtr obj = NULL ;
xmlXPathContextPtr ctxt = NULL ;
xmlNodePtr cur = NULL ;
xmlChar * tmp_tgt = NULL ;
xmlBufferPtr xml_buf = NULL ;
virDomainPtr dom = NULL ;
char * doc , * target ;
int i = 0 , diff_tgt , ret = FALSE ;
if ( ! vshConnectionUsability ( ctl , ctl - > conn , TRUE ) )
goto cleanup ;
if ( ! ( dom = vshCommandOptDomain ( ctl , cmd , " domain " , NULL ) ) )
goto cleanup ;
if ( ! ( target = vshCommandOptString ( cmd , " target " , NULL ) ) )
goto cleanup ;
doc = virDomainGetXMLDesc ( dom , 0 ) ;
if ( ! doc )
goto cleanup ;
xml = xmlReadDoc ( ( const xmlChar * ) doc , " domain.xml " , NULL ,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOWARNING ) ;
free ( doc ) ;
if ( ! xml ) {
vshError ( ctl , FALSE , _ ( " Failed to get disk information " ) ) ;
goto cleanup ;
}
ctxt = xmlXPathNewContext ( xml ) ;
if ( ! ctxt ) {
vshError ( ctl , FALSE , _ ( " Failed to get disk information " ) ) ;
goto cleanup ;
}
obj = xmlXPathEval ( BAD_CAST " /domain/devices/disk " , ctxt ) ;
if ( ( obj = = NULL ) | | ( obj - > type ! = XPATH_NODESET ) | |
( obj - > nodesetval = = NULL ) | | ( obj - > nodesetval - > nodeNr = = 0 ) ) {
vshError ( ctl , FALSE , _ ( " Failed to get disk information " ) ) ;
goto cleanup ;
}
/* search target */
for ( ; i < obj - > nodesetval - > nodeNr ; i + + ) {
cur = obj - > nodesetval - > nodeTab [ i ] - > children ;
while ( cur ! = NULL ) {
if ( cur - > type = = XML_ELEMENT_NODE & & xmlStrEqual ( cur - > name , BAD_CAST " target " ) ) {
tmp_tgt = xmlGetProp ( cur , BAD_CAST " dev " ) ;
diff_tgt = xmlStrEqual ( tmp_tgt , BAD_CAST target ) ;
xmlFree ( tmp_tgt ) ;
if ( diff_tgt ) {
goto hit ;
}
}
cur = cur - > next ;
}
}
vshError ( ctl , FALSE , _ ( " No found disk whose target is %s " ) , target ) ;
goto cleanup ;
hit :
xml_buf = xmlBufferCreate ( ) ;
if ( ! xml_buf ) {
vshError ( ctl , FALSE , _ ( " Failed to allocate memory " ) ) ;
goto cleanup ;
}
if ( xmlNodeDump ( xml_buf , xml , obj - > nodesetval - > nodeTab [ i ] , 0 , 0 ) < 0 ) {
vshError ( ctl , FALSE , _ ( " Failed to create XML " ) ) ;
goto cleanup ;
}
ret = virDomainDetachDevice ( dom , ( char * ) xmlBufferContent ( xml_buf ) ) ;
if ( ret ! = 0 )
ret = FALSE ;
else
ret = TRUE ;
cleanup :
if ( obj )
xmlXPathFreeObject ( obj ) ;
if ( ctxt )
xmlXPathFreeContext ( ctxt ) ;
if ( xml )
xmlFreeDoc ( xml ) ;
if ( xml_buf )
xmlBufferFree ( xml_buf ) ;
if ( dom )
virDomainFree ( dom ) ;
return ret ;
}
2005-12-08 13:23:34 +03:00
/*
* " quit " command
*/
static vshCmdInfo info_quit [ ] = {
2006-03-15 15:13:25 +03:00
{ " syntax " , " quit " } ,
2006-09-21 19:24:37 +04:00
{ " help " , gettext_noop ( " quit this interactive terminal " ) } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
static int
2006-03-15 15:13:25 +03:00
cmdQuit ( vshControl * ctl , vshCmd * cmd ATTRIBUTE_UNUSED )
{
2005-12-08 13:23:34 +03:00
ctl - > imode = FALSE ;
return TRUE ;
}
/*
* Commands
*/
static vshCmdDef commands [ ] = {
2007-06-20 21:22:09 +04:00
{ " help " , cmdHelp , opts_help , info_help } ,
{ " attach-device " , cmdAttachDevice , opts_attach_device , info_attach_device } ,
{ " attach-disk " , cmdAttachDisk , opts_attach_disk , info_attach_disk } ,
{ " attach-interface " , cmdAttachInterface , opts_attach_interface , info_attach_interface } ,
2007-02-23 11:58:25 +03:00
{ " autostart " , cmdAutostart , opts_autostart , info_autostart } ,
2007-03-15 20:24:56 +03:00
{ " capabilities " , cmdCapabilities , NULL , info_capabilities } ,
2006-03-15 15:13:25 +03:00
{ " connect " , cmdConnect , opts_connect , info_connect } ,
2007-01-26 14:54:29 +03:00
{ " console " , cmdConsole , opts_console , info_console } ,
2006-03-30 20:08:13 +04:00
{ " create " , cmdCreate , opts_create , info_create } ,
2006-08-30 18:32:32 +04:00
{ " start " , cmdStart , opts_start , info_start } ,
2006-04-05 01:52:31 +04:00
{ " destroy " , cmdDestroy , opts_destroy , info_destroy } ,
2007-06-20 21:22:09 +04:00
{ " detach-device " , cmdDetachDevice , opts_detach_device , info_detach_device } ,
{ " detach-disk " , cmdDetachDisk , opts_detach_disk , info_detach_disk } ,
{ " detach-interface " , cmdDetachInterface , opts_detach_interface , info_detach_interface } ,
2006-08-30 18:32:32 +04:00
{ " define " , cmdDefine , opts_define , info_define } ,
2006-04-05 01:52:31 +04:00
{ " domid " , cmdDomid , opts_domid , info_domid } ,
2006-05-29 19:39:31 +04:00
{ " domuuid " , cmdDomuuid , opts_domuuid , info_domuuid } ,
2006-04-04 18:37:32 +04:00
{ " dominfo " , cmdDominfo , opts_dominfo , info_dominfo } ,
2006-04-05 01:52:31 +04:00
{ " domname " , cmdDomname , opts_domname , info_domname } ,
{ " domstate " , cmdDomstate , opts_domstate , info_domstate } ,
2007-08-21 14:08:12 +04:00
{ " domblkstat " , cmdDomblkstat , opts_domblkstat , info_domblkstat } ,
{ " domifstat " , cmdDomIfstat , opts_domifstat , info_domifstat } ,
2006-03-15 15:13:25 +03:00
{ " dumpxml " , cmdDumpXML , opts_dumpxml , info_dumpxml } ,
2007-09-28 18:28:12 +04:00
{ " freecell " , cmdFreecell , opts_freecell , info_freecell } ,
2007-06-26 15:42:46 +04:00
{ " hostname " , cmdHostname , NULL , info_hostname } ,
2006-08-30 18:32:32 +04:00
{ " list " , cmdList , opts_list , info_list } ,
2007-08-21 13:31:12 +04:00
{ " migrate " , cmdMigrate , opts_migrate , info_migrate } ,
2007-02-23 11:58:25 +03:00
{ " net-autostart " , cmdNetworkAutostart , opts_network_autostart , info_network_autostart } ,
2007-02-14 19:53:55 +03:00
{ " net-create " , cmdNetworkCreate , opts_network_create , info_network_create } ,
{ " net-define " , cmdNetworkDefine , opts_network_define , info_network_define } ,
{ " net-destroy " , cmdNetworkDestroy , opts_network_destroy , info_network_destroy } ,
{ " net-dumpxml " , cmdNetworkDumpXML , opts_network_dumpxml , info_network_dumpxml } ,
{ " net-list " , cmdNetworkList , opts_network_list , info_network_list } ,
{ " net-name " , cmdNetworkName , opts_network_name , info_network_name } ,
{ " net-start " , cmdNetworkStart , opts_network_start , info_network_start } ,
{ " net-undefine " , cmdNetworkUndefine , opts_network_undefine , info_network_undefine } ,
{ " net-uuid " , cmdNetworkUuid , opts_network_uuid , info_network_uuid } ,
2006-04-05 01:52:31 +04:00
{ " nodeinfo " , cmdNodeinfo , NULL , info_nodeinfo } ,
{ " quit " , cmdQuit , NULL , info_quit } ,
{ " reboot " , cmdReboot , opts_reboot , info_reboot } ,
{ " restore " , cmdRestore , opts_restore , info_restore } ,
2006-03-15 15:13:25 +03:00
{ " resume " , cmdResume , opts_resume , info_resume } ,
{ " save " , cmdSave , opts_save , info_save } ,
2007-06-05 16:06:08 +04:00
{ " schedinfo " , cmdSchedinfo , opts_schedinfo , info_schedinfo } ,
2006-11-22 20:48:29 +03:00
{ " dump " , cmdDump , opts_dump , info_dump } ,
2006-03-15 15:13:25 +03:00
{ " shutdown " , cmdShutdown , opts_shutdown , info_shutdown } ,
2006-08-16 21:30:33 +04:00
{ " setmem " , cmdSetmem , opts_setmem , info_setmem } ,
{ " setmaxmem " , cmdSetmaxmem , opts_setmaxmem , info_setmaxmem } ,
{ " setvcpus " , cmdSetvcpus , opts_setvcpus , info_setvcpus } ,
2006-04-05 01:52:31 +04:00
{ " suspend " , cmdSuspend , opts_suspend , info_suspend } ,
2007-07-26 12:41:16 +04:00
{ " ttyconsole " , cmdTTYConsole , opts_ttyconsole , info_ttyconsole } ,
2006-08-30 18:32:32 +04:00
{ " undefine " , cmdUndefine , opts_undefine , info_undefine } ,
2007-06-26 15:42:46 +04:00
{ " uri " , cmdURI , NULL , info_uri } ,
2006-08-07 18:35:20 +04:00
{ " vcpuinfo " , cmdVcpuinfo , opts_vcpuinfo , info_vcpuinfo } ,
{ " vcpupin " , cmdVcpupin , opts_vcpupin , info_vcpupin } ,
2006-03-15 15:13:25 +03:00
{ " version " , cmdVersion , NULL , info_version } ,
2007-01-26 14:54:29 +03:00
{ " vncdisplay " , cmdVNCDisplay , opts_vncdisplay , info_vncdisplay } ,
2006-03-15 15:13:25 +03:00
{ NULL , NULL , NULL , NULL }
2005-12-08 13:23:34 +03:00
} ;
/* ---------------
* Utils for work with command definition
* - - - - - - - - - - - - - - -
*/
2005-12-08 17:22:52 +03:00
static const char *
2006-03-15 15:13:25 +03:00
vshCmddefGetInfo ( vshCmdDef * cmd , const char * name )
{
2005-12-08 13:23:34 +03:00
vshCmdInfo * info ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
for ( info = cmd - > info ; info & & info - > name ; info + + ) {
2006-03-15 15:13:25 +03:00
if ( strcmp ( info - > name , name ) = = 0 )
2005-12-08 13:23:34 +03:00
return info - > data ;
}
return NULL ;
}
static vshCmdOptDef *
2006-03-15 15:13:25 +03:00
vshCmddefGetOption ( vshCmdDef * cmd , const char * name )
{
2005-12-08 13:23:34 +03:00
vshCmdOptDef * opt ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
for ( opt = cmd - > opts ; opt & & opt - > name ; opt + + )
2006-03-15 15:13:25 +03:00
if ( strcmp ( opt - > name , name ) = = 0 )
2005-12-08 13:23:34 +03:00
return opt ;
return NULL ;
}
static vshCmdOptDef *
2006-03-15 15:13:25 +03:00
vshCmddefGetData ( vshCmdDef * cmd , int data_ct )
{
2005-12-08 13:23:34 +03:00
vshCmdOptDef * opt ;
2006-01-25 12:46:22 +03:00
for ( opt = cmd - > opts ; opt & & opt - > name ; opt + + ) {
2006-03-15 15:13:25 +03:00
if ( opt - > type = = VSH_OT_DATA ) {
if ( data_ct = = 0 )
2006-01-25 12:46:22 +03:00
return opt ;
else
data_ct - - ;
}
}
2005-12-08 13:23:34 +03:00
return NULL ;
}
2006-01-25 12:46:22 +03:00
/*
* Checks for required options
*/
2006-03-15 15:13:25 +03:00
static int
vshCommandCheckOpts ( vshControl * ctl , vshCmd * cmd )
2006-01-25 12:46:22 +03:00
{
vshCmdDef * def = cmd - > def ;
vshCmdOptDef * d ;
2006-03-15 15:13:25 +03:00
int err = 0 ;
2006-01-25 12:46:22 +03:00
for ( d = def - > opts ; d & & d - > name ; d + + ) {
if ( d - > flag & VSH_OFLAG_REQ ) {
vshCmdOpt * o = cmd - > opts ;
2006-03-15 15:13:25 +03:00
int ok = 0 ;
while ( o & & ok = = 0 ) {
2006-01-25 12:46:22 +03:00
if ( o - > def = = d )
2006-03-15 15:13:25 +03:00
ok = 1 ;
2006-01-25 12:46:22 +03:00
o = o - > next ;
}
if ( ! ok ) {
2006-03-15 15:13:25 +03:00
vshError ( ctl , FALSE ,
d - > type = = VSH_OT_DATA ?
2006-09-21 19:24:37 +04:00
_ ( " command '%s' requires <%s> option " ) :
2007-02-07 16:50:18 +03:00
_ ( " command '%s' requires --%s option " ) ,
2006-03-15 15:13:25 +03:00
def - > name , d - > name ) ;
2006-01-25 12:46:22 +03:00
err = 1 ;
}
2006-03-15 15:13:25 +03:00
2006-01-25 12:46:22 +03:00
}
}
return ! err ;
}
2005-12-08 13:23:34 +03:00
static vshCmdDef *
2006-03-15 15:13:25 +03:00
vshCmddefSearch ( const char * cmdname )
{
2005-12-08 13:23:34 +03:00
vshCmdDef * c ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
for ( c = commands ; c - > name ; c + + )
2006-03-15 15:13:25 +03:00
if ( strcmp ( c - > name , cmdname ) = = 0 )
2005-12-08 13:23:34 +03:00
return c ;
return NULL ;
}
static int
2006-03-15 15:13:25 +03:00
vshCmddefHelp ( vshControl * ctl , const char * cmdname , int withprog )
{
2005-12-08 13:23:34 +03:00
vshCmdDef * def = vshCmddefSearch ( cmdname ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! def ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " command '%s' doesn't exist " ) , cmdname ) ;
2006-03-15 15:13:25 +03:00
return FALSE ;
} else {
2005-12-08 13:23:34 +03:00
vshCmdOptDef * opt ;
2007-06-15 12:18:55 +04:00
const char * desc = N_ ( vshCmddefGetInfo ( def , " desc " ) ) ;
const char * help = N_ ( vshCmddefGetInfo ( def , " help " ) ) ;
2005-12-08 17:22:52 +03:00
const char * syntax = vshCmddefGetInfo ( def , " syntax " ) ;
2005-12-08 13:23:34 +03:00
2006-09-21 19:24:37 +04:00
fputs ( _ ( " NAME \n " ) , stdout ) ;
2006-03-15 15:13:25 +03:00
fprintf ( stdout , " %s - %s \n " , def - > name , help ) ;
2005-12-08 13:23:34 +03:00
if ( syntax ) {
2007-06-13 13:32:44 +04:00
fputs ( _ ( " \n SYNOPSIS \n " ) , stdout ) ;
2005-12-08 13:23:34 +03:00
if ( ! withprog )
fprintf ( stdout , " %s \n " , syntax ) ;
else
fprintf ( stdout , " %s %s \n " , progname , syntax ) ;
}
if ( desc ) {
2006-09-21 19:24:37 +04:00
fputs ( _ ( " \n DESCRIPTION \n " ) , stdout ) ;
2005-12-08 13:23:34 +03:00
fprintf ( stdout , " %s \n " , desc ) ;
}
if ( def - > opts ) {
2006-09-21 19:24:37 +04:00
fputs ( _ ( " \n OPTIONS \n " ) , stdout ) ;
2006-03-15 15:13:25 +03:00
for ( opt = def - > opts ; opt - > name ; opt + + ) {
2005-12-08 13:23:34 +03:00
char buf [ 256 ] ;
2006-03-15 15:13:25 +03:00
if ( opt - > type = = VSH_OT_BOOL )
2005-12-08 13:23:34 +03:00
snprintf ( buf , sizeof ( buf ) , " --%s " , opt - > name ) ;
2006-03-15 15:13:25 +03:00
else if ( opt - > type = = VSH_OT_INT )
2006-09-21 19:24:37 +04:00
snprintf ( buf , sizeof ( buf ) , _ ( " --%s <number> " ) , opt - > name ) ;
2006-03-15 15:13:25 +03:00
else if ( opt - > type = = VSH_OT_STRING )
2006-09-21 19:24:37 +04:00
snprintf ( buf , sizeof ( buf ) , _ ( " --%s <string> " ) , opt - > name ) ;
2006-03-15 15:13:25 +03:00
else if ( opt - > type = = VSH_OT_DATA )
2005-12-08 13:23:34 +03:00
snprintf ( buf , sizeof ( buf ) , " <%s> " , opt - > name ) ;
2006-03-15 15:13:25 +03:00
2007-06-15 12:18:55 +04:00
fprintf ( stdout , " %-15s %s \n " , buf , N_ ( opt - > help ) ) ;
2006-03-15 15:13:25 +03:00
}
2005-12-08 13:23:34 +03:00
}
fputc ( ' \n ' , stdout ) ;
}
return TRUE ;
}
/* ---------------
* Utils for work with runtime commands data
* - - - - - - - - - - - - - - -
*/
2006-03-15 15:13:25 +03:00
static void
vshCommandOptFree ( vshCmdOpt * arg )
{
2005-12-08 13:23:34 +03:00
vshCmdOpt * a = arg ;
2006-03-15 15:13:25 +03:00
while ( a ) {
2005-12-08 13:23:34 +03:00
vshCmdOpt * tmp = a ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
a = a - > next ;
if ( tmp - > data )
free ( tmp - > data ) ;
free ( tmp ) ;
}
}
static void
2006-03-15 15:13:25 +03:00
vshCommandFree ( vshCmd * cmd )
{
2005-12-08 13:23:34 +03:00
vshCmd * c = cmd ;
2006-03-15 15:13:25 +03:00
while ( c ) {
2005-12-08 13:23:34 +03:00
vshCmd * tmp = c ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
c = c - > next ;
if ( tmp - > opts )
vshCommandOptFree ( tmp - > opts ) ;
free ( tmp ) ;
}
}
/*
* Returns option by name
*/
static vshCmdOpt *
2006-03-15 15:13:25 +03:00
vshCommandOpt ( vshCmd * cmd , const char * name )
{
2005-12-08 13:23:34 +03:00
vshCmdOpt * opt = cmd - > opts ;
2006-03-15 15:13:25 +03:00
while ( opt ) {
if ( opt - > def & & strcmp ( opt - > def - > name , name ) = = 0 )
2005-12-08 13:23:34 +03:00
return opt ;
opt = opt - > next ;
}
return NULL ;
}
/*
* Returns option as INT
*/
static int
2006-03-15 15:13:25 +03:00
vshCommandOptInt ( vshCmd * cmd , const char * name , int * found )
{
2005-12-08 13:23:34 +03:00
vshCmdOpt * arg = vshCommandOpt ( cmd , name ) ;
2007-08-16 17:21:36 +04:00
int res = 0 , num_found = FALSE ;
char * end_p = NULL ;
2006-03-15 15:13:25 +03:00
2007-08-16 17:21:36 +04:00
if ( ( arg ! = NULL ) & & ( arg - > data ! = NULL ) ) {
res = strtol ( arg - > data , & end_p , 10 ) ;
2007-11-08 19:14:12 +03:00
if ( ( arg - > data = = end_p ) | | ( * end_p ! = 0 ) )
num_found = FALSE ;
else
num_found = TRUE ;
2007-08-16 17:21:36 +04:00
}
2005-12-08 13:23:34 +03:00
if ( found )
2007-08-16 17:21:36 +04:00
* found = num_found ;
2005-12-08 13:23:34 +03:00
return res ;
}
/*
* Returns option as STRING
*/
static char *
2006-03-15 15:13:25 +03:00
vshCommandOptString ( vshCmd * cmd , const char * name , int * found )
{
2005-12-08 13:23:34 +03:00
vshCmdOpt * arg = vshCommandOpt ( cmd , name ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( found )
* found = arg ? TRUE : FALSE ;
2006-01-25 12:46:22 +03:00
return arg & & arg - > data & & * arg - > data ? arg - > data : NULL ;
2005-12-08 13:23:34 +03:00
}
/*
* Returns TRUE / FALSE if the option exists
*/
static int
2006-03-15 15:13:25 +03:00
vshCommandOptBool ( vshCmd * cmd , const char * name )
{
2005-12-08 13:23:34 +03:00
return vshCommandOpt ( cmd , name ) ? TRUE : FALSE ;
}
2006-01-25 12:46:22 +03:00
2005-12-15 20:00:43 +03:00
static virDomainPtr
2006-05-29 19:39:31 +04:00
vshCommandOptDomainBy ( vshControl * ctl , vshCmd * cmd , const char * optname ,
2007-02-07 16:50:18 +03:00
char * * name , int flag )
2006-03-15 15:13:25 +03:00
{
2005-12-15 20:00:43 +03:00
virDomainPtr dom = NULL ;
2007-11-12 17:00:32 +03:00
char * n ;
2005-12-15 20:00:43 +03:00
int id ;
2006-03-15 15:13:25 +03:00
2005-12-15 20:00:43 +03:00
if ( ! ( n = vshCommandOptString ( cmd , optname , NULL ) ) ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " undefined domain name or id " ) ) ;
2006-03-15 15:13:25 +03:00
return NULL ;
2005-12-15 20:00:43 +03:00
}
2006-03-15 15:13:25 +03:00
2006-05-22 18:38:33 +04:00
vshDebug ( ctl , 5 , " %s: found option <%s>: %s \n " ,
2006-03-15 15:13:25 +03:00
cmd - > def - > name , optname , n ) ;
2005-12-15 20:00:43 +03:00
if ( name )
* name = n ;
2006-03-15 15:13:25 +03:00
2005-12-15 20:00:43 +03:00
/* try it by ID */
2007-02-14 18:44:58 +03:00
if ( flag & VSH_BYID ) {
2007-11-12 17:00:32 +03:00
if ( xstrtol_i ( n , NULL , 10 , & id ) = = 0 & & id > = 0 ) {
2006-05-29 19:39:31 +04:00
vshDebug ( ctl , 5 , " %s: <%s> seems like domain ID \n " ,
cmd - > def - > name , optname ) ;
dom = virDomainLookupByID ( ctl - > conn , id ) ;
}
2006-01-25 12:46:22 +03:00
}
2006-05-22 18:38:33 +04:00
/* try it by UUID */
2007-02-14 18:44:58 +03:00
if ( dom = = NULL & & ( flag & VSH_BYUUID ) & & strlen ( n ) = = VIR_UUID_STRING_BUFLEN - 1 ) {
2006-05-22 18:38:33 +04:00
vshDebug ( ctl , 5 , " %s: <%s> tring as domain UUID \n " ,
2007-02-07 16:50:18 +03:00
cmd - > def - > name , optname ) ;
2006-05-29 19:39:31 +04:00
dom = virDomainLookupByUUIDString ( ctl - > conn , n ) ;
2006-05-22 18:38:33 +04:00
}
2005-12-15 20:00:43 +03:00
/* try it by NAME */
2007-02-14 18:44:58 +03:00
if ( dom = = NULL & & ( flag & VSH_BYNAME ) ) {
2006-05-22 18:38:33 +04:00
vshDebug ( ctl , 5 , " %s: <%s> tring as domain NAME \n " ,
2006-03-15 15:13:25 +03:00
cmd - > def - > name , optname ) ;
2005-12-15 20:00:43 +03:00
dom = virDomainLookupByName ( ctl - > conn , n ) ;
2006-01-25 12:46:22 +03:00
}
2006-05-22 18:38:33 +04:00
2006-03-15 15:13:25 +03:00
if ( ! dom )
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " failed to get domain '%s' " ) , n ) ;
2006-03-15 15:13:25 +03:00
2005-12-15 20:00:43 +03:00
return dom ;
}
2007-02-14 19:53:55 +03:00
static virNetworkPtr
vshCommandOptNetworkBy ( vshControl * ctl , vshCmd * cmd , const char * optname ,
char * * name , int flag )
{
virNetworkPtr network = NULL ;
char * n ;
if ( ! ( n = vshCommandOptString ( cmd , optname , NULL ) ) ) {
vshError ( ctl , FALSE , _ ( " undefined network name " ) ) ;
return NULL ;
}
vshDebug ( ctl , 5 , " %s: found option <%s>: %s \n " ,
cmd - > def - > name , optname , n ) ;
if ( name )
* name = n ;
/* try it by UUID */
if ( network = = NULL & & ( flag & VSH_BYUUID ) & & strlen ( n ) = = VIR_UUID_STRING_BUFLEN - 1 ) {
vshDebug ( ctl , 5 , " %s: <%s> tring as network UUID \n " ,
cmd - > def - > name , optname ) ;
network = virNetworkLookupByUUIDString ( ctl - > conn , n ) ;
}
/* try it by NAME */
if ( network = = NULL & & ( flag & VSH_BYNAME ) ) {
vshDebug ( ctl , 5 , " %s: <%s> tring as network NAME \n " ,
cmd - > def - > name , optname ) ;
network = virNetworkLookupByName ( ctl - > conn , n ) ;
}
if ( ! network )
vshError ( ctl , FALSE , _ ( " failed to get network '%s' " ) , n ) ;
return network ;
}
2005-12-08 13:23:34 +03:00
/*
* Executes command ( s ) and returns return code from last command
*/
static int
2006-03-15 15:13:25 +03:00
vshCommandRun ( vshControl * ctl , vshCmd * cmd )
{
2005-12-08 13:23:34 +03:00
int ret = TRUE ;
2006-03-15 15:13:25 +03:00
while ( cmd ) {
2005-12-08 13:23:34 +03:00
struct timeval before , after ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ctl - > timing )
GETTIMEOFDAY ( & before ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
ret = cmd - > def - > handler ( ctl , cmd ) ;
if ( ctl - > timing )
GETTIMEOFDAY ( & after ) ;
2006-03-15 15:13:25 +03:00
if ( strcmp ( cmd - > def - > name , " quit " ) = = 0 ) /* hack ... */
2005-12-08 13:23:34 +03:00
return ret ;
if ( ctl - > timing )
2006-09-21 19:24:37 +04:00
vshPrint ( ctl , _ ( " \n (Time: %.3f ms) \n \n " ) ,
2006-03-15 15:13:25 +03:00
DIFF_MSEC ( & after , & before ) ) ;
else
2006-05-22 18:38:33 +04:00
vshPrintExtra ( ctl , " \n " ) ;
2005-12-08 13:23:34 +03:00
cmd = cmd - > next ;
}
return ret ;
}
/* ---------------
* Command string parsing
* - - - - - - - - - - - - - - -
*/
# define VSH_TK_ERROR -1
# define VSH_TK_NONE 0
# define VSH_TK_OPTION 1
# define VSH_TK_DATA 2
# define VSH_TK_END 3
2006-03-15 15:13:25 +03:00
static int
vshCommandGetToken ( vshControl * ctl , char * str , char * * end , char * * res )
{
2005-12-08 13:23:34 +03:00
int tk = VSH_TK_NONE ;
int quote = FALSE ;
int sz = 0 ;
char * p = str ;
char * tkstr = NULL ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
* end = NULL ;
2006-03-15 15:13:25 +03:00
2007-07-04 13:16:23 +04:00
while ( p & & * p & & ( * p = = ' ' | | * p = = ' \t ' ) )
2005-12-08 13:23:34 +03:00
p + + ;
2006-03-15 15:13:25 +03:00
if ( p = = NULL | | * p = = ' \0 ' )
2005-12-08 13:23:34 +03:00
return VSH_TK_END ;
2006-03-15 15:13:25 +03:00
if ( * p = = ' ; ' ) {
* end = + + p ; /* = \0 or begi of next command */
2005-12-08 13:23:34 +03:00
return VSH_TK_END ;
}
2006-03-15 15:13:25 +03:00
while ( * p ) {
2005-12-08 13:23:34 +03:00
/* end of token is blank space or ';' */
2007-07-04 13:16:23 +04:00
if ( ( quote = = FALSE & & ( * p = = ' ' | | * p = = ' \t ' ) ) | | * p = = ' ; ' )
2005-12-08 13:23:34 +03:00
break ;
2006-03-15 15:13:25 +03:00
2006-01-25 12:46:22 +03:00
/* end of option name could be '=' */
2006-03-15 15:13:25 +03:00
if ( tk = = VSH_TK_OPTION & & * p = = ' = ' ) {
p + + ; /* skip '=' */
2006-01-25 12:46:22 +03:00
break ;
}
2006-03-15 15:13:25 +03:00
if ( tk = = VSH_TK_NONE ) {
if ( * p = = ' - ' & & * ( p + 1 ) = = ' - ' & & * ( p + 2 )
& & isalnum ( ( unsigned char ) * ( p + 2 ) ) ) {
2005-12-08 13:23:34 +03:00
tk = VSH_TK_OPTION ;
2006-03-15 15:13:25 +03:00
p + = 2 ;
2005-12-08 13:23:34 +03:00
} else {
tk = VSH_TK_DATA ;
2006-03-15 15:13:25 +03:00
if ( * p = = ' " ' ) {
quote = TRUE ;
2005-12-08 13:23:34 +03:00
p + + ;
} else {
quote = FALSE ;
}
}
2006-03-15 15:13:25 +03:00
tkstr = p ; /* begin of token */
} else if ( quote & & * p = = ' " ' ) {
2005-12-08 13:23:34 +03:00
quote = FALSE ;
p + + ;
2006-03-15 15:13:25 +03:00
break ; /* end of "..." token */
2005-12-08 13:23:34 +03:00
}
p + + ;
sz + + ;
}
if ( quote ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " missing \" " ) ) ;
2005-12-08 13:23:34 +03:00
return VSH_TK_ERROR ;
}
2006-03-15 15:13:25 +03:00
if ( tkstr = = NULL | | * tkstr = = ' \0 ' | | p = = NULL )
2005-12-08 13:23:34 +03:00
return VSH_TK_END ;
2006-03-15 15:13:25 +03:00
if ( sz = = 0 )
2005-12-08 13:23:34 +03:00
return VSH_TK_END ;
2006-03-15 15:13:25 +03:00
2006-04-06 14:33:06 +04:00
* res = vshMalloc ( ctl , sz + 1 ) ;
2005-12-08 13:23:34 +03:00
memcpy ( * res , tkstr , sz ) ;
2006-03-15 15:13:25 +03:00
* ( * res + sz ) = ' \0 ' ;
2005-12-08 13:23:34 +03:00
* end = p ;
return tk ;
}
static int
2006-03-15 15:13:25 +03:00
vshCommandParse ( vshControl * ctl , char * cmdstr )
{
2005-12-08 13:23:34 +03:00
char * str ;
char * tkdata = NULL ;
vshCmd * clast = NULL ;
vshCmdOpt * first = NULL ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ctl - > cmd ) {
vshCommandFree ( ctl - > cmd ) ;
ctl - > cmd = NULL ;
}
2006-03-15 15:13:25 +03:00
if ( cmdstr = = NULL | | * cmdstr = = ' \0 ' )
2005-12-08 13:23:34 +03:00
return FALSE ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
str = cmdstr ;
2006-03-15 15:13:25 +03:00
while ( str & & * str ) {
2005-12-08 13:23:34 +03:00
vshCmdOpt * last = NULL ;
vshCmdDef * cmd = NULL ;
int tk = VSH_TK_NONE ;
2006-01-25 12:46:22 +03:00
int data_ct = 0 ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
first = NULL ;
2006-03-15 15:13:25 +03:00
while ( tk ! = VSH_TK_END ) {
2005-12-08 13:23:34 +03:00
char * end = NULL ;
vshCmdOptDef * opt = NULL ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
tkdata = NULL ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/* get token */
tk = vshCommandGetToken ( ctl , str , & end , & tkdata ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
str = end ;
2006-03-15 15:13:25 +03:00
if ( tk = = VSH_TK_END )
2005-12-08 13:23:34 +03:00
break ;
2006-03-15 15:13:25 +03:00
if ( tk = = VSH_TK_ERROR )
2005-12-08 13:23:34 +03:00
goto syntaxError ;
2006-03-15 15:13:25 +03:00
if ( cmd = = NULL ) {
2005-12-08 13:23:34 +03:00
/* first token must be command name */
2006-03-15 15:13:25 +03:00
if ( tk ! = VSH_TK_DATA ) {
vshError ( ctl , FALSE ,
2006-09-21 19:24:37 +04:00
_ ( " unexpected token (command name): '%s' " ) ,
2006-03-15 15:13:25 +03:00
tkdata ) ;
2005-12-08 13:23:34 +03:00
goto syntaxError ;
}
if ( ! ( cmd = vshCmddefSearch ( tkdata ) ) ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " unknown command: '%s' " ) , tkdata ) ;
2006-03-15 15:13:25 +03:00
goto syntaxError ; /* ... or ignore this command only? */
2005-12-08 13:23:34 +03:00
}
free ( tkdata ) ;
2006-03-15 15:13:25 +03:00
} else if ( tk = = VSH_TK_OPTION ) {
2005-12-08 13:23:34 +03:00
if ( ! ( opt = vshCmddefGetOption ( cmd , tkdata ) ) ) {
vshError ( ctl , FALSE ,
2006-09-21 19:24:37 +04:00
_ ( " command '%s' doesn't support option --%s " ) ,
2006-03-15 15:13:25 +03:00
cmd - > name , tkdata ) ;
2005-12-08 13:23:34 +03:00
goto syntaxError ;
}
2006-03-15 15:13:25 +03:00
free ( tkdata ) ; /* option name */
2005-12-08 13:23:34 +03:00
tkdata = NULL ;
if ( opt - > type ! = VSH_OT_BOOL ) {
/* option data */
tk = vshCommandGetToken ( ctl , str , & end , & tkdata ) ;
2006-03-15 15:13:25 +03:00
str = end ;
if ( tk = = VSH_TK_ERROR )
2005-12-08 13:23:34 +03:00
goto syntaxError ;
2006-03-15 15:13:25 +03:00
if ( tk ! = VSH_TK_DATA ) {
2005-12-08 13:23:34 +03:00
vshError ( ctl , FALSE ,
2006-09-21 19:24:37 +04:00
_ ( " expected syntax: --%s <%s> " ) ,
2006-03-15 15:13:25 +03:00
opt - > name ,
opt - > type = =
2006-09-21 19:24:37 +04:00
VSH_OT_INT ? _ ( " number " ) : _ ( " string " ) ) ;
2005-12-08 13:23:34 +03:00
goto syntaxError ;
}
}
2006-03-15 15:13:25 +03:00
} else if ( tk = = VSH_TK_DATA ) {
2006-01-25 12:46:22 +03:00
if ( ! ( opt = vshCmddefGetData ( cmd , data_ct + + ) ) ) {
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " unexpected data '%s' " ) , tkdata ) ;
2005-12-08 13:23:34 +03:00
goto syntaxError ;
}
}
if ( opt ) {
/* save option */
2006-04-06 14:33:06 +04:00
vshCmdOpt * arg = vshMalloc ( ctl , sizeof ( vshCmdOpt ) ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
arg - > def = opt ;
arg - > data = tkdata ;
arg - > next = NULL ;
tkdata = NULL ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! first )
first = arg ;
if ( last )
last - > next = arg ;
last = arg ;
2006-03-15 15:13:25 +03:00
2006-05-22 18:38:33 +04:00
vshDebug ( ctl , 4 , " %s: %s(%s): %s \n " ,
2006-03-15 15:13:25 +03:00
cmd - > name ,
opt - > name ,
2006-09-21 19:24:37 +04:00
tk = = VSH_TK_OPTION ? _ ( " OPTION " ) : _ ( " DATA " ) ,
2006-03-15 15:13:25 +03:00
arg - > data ) ;
2005-12-08 13:23:34 +03:00
}
if ( ! str )
break ;
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/* commad parsed -- allocate new struct for the command */
if ( cmd ) {
2006-04-06 14:33:06 +04:00
vshCmd * c = vshMalloc ( ctl , sizeof ( vshCmd ) ) ;
2006-03-30 16:14:40 +04:00
2005-12-08 13:23:34 +03:00
c - > opts = first ;
c - > def = cmd ;
c - > next = NULL ;
2007-05-29 17:55:19 +04:00
if ( ! vshCommandCheckOpts ( ctl , c ) ) {
if ( c ) free ( c ) ;
2006-01-25 12:46:22 +03:00
goto syntaxError ;
2007-05-29 17:55:19 +04:00
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! ctl - > cmd )
ctl - > cmd = c ;
if ( clast )
clast - > next = c ;
clast = c ;
}
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
return TRUE ;
2007-02-07 16:50:18 +03:00
syntaxError :
2005-12-08 13:23:34 +03:00
if ( ctl - > cmd )
vshCommandFree ( ctl - > cmd ) ;
if ( first )
vshCommandOptFree ( first ) ;
if ( tkdata )
free ( tkdata ) ;
2006-03-15 15:13:25 +03:00
return FALSE ;
2005-12-08 13:23:34 +03:00
}
/* ---------------
2007-02-07 16:50:18 +03:00
* Misc utils
2005-12-08 13:23:34 +03:00
* - - - - - - - - - - - - - - -
*/
2005-12-08 17:22:52 +03:00
static const char *
2006-03-15 15:13:25 +03:00
vshDomainStateToString ( int state )
{
2005-12-08 13:23:34 +03:00
switch ( state ) {
2007-02-07 16:50:18 +03:00
case VIR_DOMAIN_RUNNING :
return gettext_noop ( " running " ) ;
case VIR_DOMAIN_BLOCKED :
return gettext_noop ( " blocked " ) ;
case VIR_DOMAIN_PAUSED :
return gettext_noop ( " paused " ) ;
case VIR_DOMAIN_SHUTDOWN :
return gettext_noop ( " in shutdown " ) ;
case VIR_DOMAIN_SHUTOFF :
return gettext_noop ( " shut off " ) ;
case VIR_DOMAIN_CRASHED :
return gettext_noop ( " crashed " ) ;
default :
2007-09-29 22:16:26 +04:00
; /*FALLTHROUGH*/
2005-12-08 13:23:34 +03:00
}
2007-09-29 22:16:26 +04:00
return gettext_noop ( " no state " ) ; /* = dom0 state */
2005-12-08 13:23:34 +03:00
}
2006-08-07 18:35:20 +04:00
static const char *
vshDomainVcpuStateToString ( int state )
{
switch ( state ) {
2007-02-07 16:50:18 +03:00
case VIR_VCPU_OFFLINE :
return gettext_noop ( " offline " ) ;
case VIR_VCPU_BLOCKED :
return gettext_noop ( " blocked " ) ;
case VIR_VCPU_RUNNING :
return gettext_noop ( " running " ) ;
default :
2007-09-29 22:16:26 +04:00
; /*FALLTHROUGH*/
2006-08-07 18:35:20 +04:00
}
2007-09-29 22:16:26 +04:00
return gettext_noop ( " no state " ) ;
2006-08-07 18:35:20 +04:00
}
2005-12-08 13:23:34 +03:00
static int
2006-03-15 15:13:25 +03:00
vshConnectionUsability ( vshControl * ctl , virConnectPtr conn , int showerror )
{
2007-02-07 16:50:18 +03:00
/* TODO: use something like virConnectionState() to
* check usability of the connection
2005-12-08 13:23:34 +03:00
*/
if ( ! conn ) {
if ( showerror )
2006-09-21 19:24:37 +04:00
vshError ( ctl , FALSE , _ ( " no valid connection " ) ) ;
2005-12-08 13:23:34 +03:00
return FALSE ;
}
return TRUE ;
}
2006-05-22 18:38:33 +04:00
static void
vshDebug ( vshControl * ctl , int level , const char * format , . . . )
2006-03-15 15:13:25 +03:00
{
2006-05-22 18:38:33 +04:00
va_list ap ;
2007-06-06 16:24:31 +04:00
va_start ( ap , format ) ;
vshOutputLogFile ( ctl , VSH_ERR_DEBUG , format , ap ) ;
va_end ( ap ) ;
2006-05-22 18:38:33 +04:00
if ( level > ctl - > debug )
return ;
va_start ( ap , format ) ;
vfprintf ( stdout , format , ap ) ;
va_end ( ap ) ;
2005-12-08 13:23:34 +03:00
}
static void
2006-05-22 18:38:33 +04:00
vshPrintExtra ( vshControl * ctl , const char * format , . . . )
2006-03-15 15:13:25 +03:00
{
2005-12-08 13:23:34 +03:00
va_list ap ;
2006-03-15 15:13:25 +03:00
2006-05-22 18:38:33 +04:00
if ( ctl - > quiet = = TRUE )
2005-12-08 13:23:34 +03:00
return ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
va_start ( ap , format ) ;
2006-04-06 14:33:06 +04:00
vfprintf ( stdout , format , ap ) ;
2005-12-08 13:23:34 +03:00
va_end ( ap ) ;
}
2006-05-22 18:38:33 +04:00
2005-12-08 13:23:34 +03:00
static void
2006-03-15 15:13:25 +03:00
vshError ( vshControl * ctl , int doexit , const char * format , . . . )
{
2005-12-08 13:23:34 +03:00
va_list ap ;
2006-03-15 15:13:25 +03:00
2007-06-06 16:24:31 +04:00
va_start ( ap , format ) ;
vshOutputLogFile ( ctl , VSH_ERR_ERROR , format , ap ) ;
va_end ( ap ) ;
2005-12-08 13:23:34 +03:00
if ( doexit )
2006-09-21 19:24:37 +04:00
fprintf ( stderr , _ ( " %s: error: " ) , progname ) ;
2005-12-08 13:23:34 +03:00
else
2006-09-21 19:24:37 +04:00
fputs ( _ ( " error: " ) , stderr ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
va_start ( ap , format ) ;
vfprintf ( stderr , format , ap ) ;
va_end ( ap ) ;
fputc ( ' \n ' , stderr ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( doexit ) {
2006-04-06 14:33:06 +04:00
if ( ctl )
vshDeinit ( ctl ) ;
2005-12-08 13:23:34 +03:00
exit ( EXIT_FAILURE ) ;
}
}
2006-04-06 14:33:06 +04:00
static void *
_vshMalloc ( vshControl * ctl , size_t size , const char * filename , int line )
{
void * x ;
if ( ( x = malloc ( size ) ) )
return x ;
2006-09-21 19:24:37 +04:00
vshError ( ctl , TRUE , _ ( " %s: %d: failed to allocate %d bytes " ) ,
2007-02-07 16:50:18 +03:00
filename , line , ( int ) size ) ;
2006-04-06 14:33:06 +04:00
return NULL ;
}
static void *
_vshCalloc ( vshControl * ctl , size_t nmemb , size_t size , const char * filename , int line )
{
void * x ;
if ( ( x = calloc ( nmemb , size ) ) )
return x ;
2006-09-21 19:24:37 +04:00
vshError ( ctl , TRUE , _ ( " %s: %d: failed to allocate %d bytes " ) ,
2007-02-07 16:50:18 +03:00
filename , line , ( int ) ( size * nmemb ) ) ;
2006-04-06 14:33:06 +04:00
return NULL ;
}
2007-06-19 13:12:55 +04:00
static void *
_vshRealloc ( vshControl * ctl , void * ptr , size_t size , const char * filename , int line )
{
void * x ;
if ( ( x = realloc ( ptr , size ) ) )
return x ;
free ( ptr ) ;
vshError ( ctl , TRUE , _ ( " %s: %d: failed to allocate %d bytes " ) ,
filename , line , ( int ) size ) ;
return NULL ;
}
2006-04-06 14:33:06 +04:00
static char *
_vshStrdup ( vshControl * ctl , const char * s , const char * filename , int line )
{
char * x ;
2007-04-26 14:20:57 +04:00
if ( s = = NULL )
return ( NULL ) ;
2006-04-06 14:33:06 +04:00
if ( ( x = strdup ( s ) ) )
return x ;
2007-03-19 17:20:30 +03:00
vshError ( ctl , TRUE , _ ( " %s: %d: failed to allocate %lu bytes " ) ,
filename , line , ( unsigned long ) strlen ( s ) ) ;
2006-04-06 14:33:06 +04:00
return NULL ;
}
2005-12-08 13:23:34 +03:00
/*
2007-06-20 21:22:09 +04:00
* Initialize connection .
2005-12-08 13:23:34 +03:00
*/
static int
2006-03-15 15:13:25 +03:00
vshInit ( vshControl * ctl )
{
2005-12-08 13:23:34 +03:00
if ( ctl - > conn )
return FALSE ;
ctl - > uid = getuid ( ) ;
2006-03-15 15:13:25 +03:00
2007-06-06 16:24:31 +04:00
vshOpenLogFile ( ctl ) ;
2006-02-28 00:34:28 +03:00
/* set up the library error handler */
virSetErrorFunc ( NULL , virshErrorHandler ) ;
2006-03-15 15:13:25 +03:00
2007-03-08 16:48:22 +03:00
/* Force a non-root, Xen connection to readonly */
if ( ( ctl - > name = = NULL | |
! strcasecmp ( ctl - > name , " xen " ) ) & & ctl - > uid ! = 0 )
ctl - > readonly = 1 ;
2007-12-05 21:55:04 +03:00
ctl - > conn = virConnectOpenAuth ( ctl - > name ,
virConnectAuthPtrDefault ,
ctl - > readonly ? VIR_CONNECT_RO : 0 ) ;
2006-03-15 15:13:25 +03:00
2007-06-20 21:22:09 +04:00
/* This is not necessarily fatal. All the individual commands check
* vshConnectionUsability , except ones which don ' t need a connection
* such as " help " .
*/
2007-12-05 19:24:22 +03:00
if ( ! ctl - > conn ) {
2007-06-20 21:22:09 +04:00
vshError ( ctl , FALSE , _ ( " failed to connect to the hypervisor " ) ) ;
2007-12-05 19:24:22 +03:00
return FALSE ;
}
2005-12-08 13:23:34 +03:00
return TRUE ;
}
2007-06-06 16:24:31 +04:00
/**
* vshOpenLogFile :
*
* Open log file .
*/
static void
vshOpenLogFile ( vshControl * ctl )
{
struct stat st ;
if ( ctl - > logfile = = NULL )
return ;
/* check log file */
if ( stat ( ctl - > logfile , & st ) = = - 1 ) {
switch ( errno ) {
case ENOENT :
break ;
default :
vshError ( ctl , TRUE , _ ( " failed to get the log file information " ) ) ;
break ;
}
} else {
if ( ! S_ISREG ( st . st_mode ) ) {
vshError ( ctl , TRUE , _ ( " the log path is not a file " ) ) ;
}
}
/* log file open */
if ( ( ctl - > log_fd = open ( ctl - > logfile , O_WRONLY | O_APPEND | O_CREAT | O_SYNC , FILE_MODE ) ) < 0 ) {
vshError ( ctl , TRUE , _ ( " failed to open the log file. check the log file path " ) ) ;
}
}
/**
* vshOutputLogFile :
*
* Outputting an error to log file .
*/
static void
vshOutputLogFile ( vshControl * ctl , int log_level , const char * msg_format , va_list ap )
{
char msg_buf [ MSG_BUFFER ] ;
const char * lvl = " " ;
struct timeval stTimeval ;
struct tm * stTm ;
if ( ctl - > log_fd = = - 1 )
return ;
/**
* create log format
*
* [ YYYY . MM . DD HH : MM : SS SIGNATURE PID ] LOG_LEVEL message
*/
gettimeofday ( & stTimeval , NULL ) ;
stTm = localtime ( & stTimeval . tv_sec ) ;
snprintf ( msg_buf , sizeof ( msg_buf ) ,
" [%d.%02d.%02d %02d:%02d:%02d " ,
( 1900 + stTm - > tm_year ) ,
( 1 + stTm - > tm_mon ) ,
( stTm - > tm_mday ) ,
( stTm - > tm_hour ) ,
( stTm - > tm_min ) ,
( stTm - > tm_sec ) ) ;
snprintf ( msg_buf + strlen ( msg_buf ) , sizeof ( msg_buf ) - strlen ( msg_buf ) ,
" %s] " , SIGN_NAME ) ;
switch ( log_level ) {
case VSH_ERR_DEBUG :
lvl = LVL_DEBUG ;
break ;
case VSH_ERR_INFO :
lvl = LVL_INFO ;
break ;
case VSH_ERR_NOTICE :
lvl = LVL_INFO ;
break ;
case VSH_ERR_WARNING :
lvl = LVL_WARNING ;
break ;
case VSH_ERR_ERROR :
lvl = LVL_ERROR ;
break ;
default :
lvl = LVL_DEBUG ;
break ;
}
snprintf ( msg_buf + strlen ( msg_buf ) , sizeof ( msg_buf ) - strlen ( msg_buf ) ,
" %s " , lvl ) ;
vsnprintf ( msg_buf + strlen ( msg_buf ) , sizeof ( msg_buf ) - strlen ( msg_buf ) ,
msg_format , ap ) ;
if ( msg_buf [ strlen ( msg_buf ) - 1 ] ! = ' \n ' )
snprintf ( msg_buf + strlen ( msg_buf ) , sizeof ( msg_buf ) - strlen ( msg_buf ) , " \n " ) ;
/* write log */
if ( write ( ctl - > log_fd , msg_buf , strlen ( msg_buf ) ) = = - 1 ) {
vshCloseLogFile ( ctl ) ;
vshError ( ctl , FALSE , _ ( " failed to write the log file " ) ) ;
}
}
/**
* vshCloseLogFile :
*
* Close log file .
*/
static void
vshCloseLogFile ( vshControl * ctl )
{
/* log file close */
if ( ctl - > log_fd > = 0 ) {
2007-11-28 16:22:33 +03:00
if ( close ( ctl - > log_fd ) < 0 )
2007-11-28 17:22:30 +03:00
vshError ( ctl , FALSE , _ ( " %s: failed to write log file: %s " ) ,
2007-11-28 16:22:33 +03:00
ctl - > logfile ? ctl - > logfile : " ? " , strerror ( errno ) ) ;
2007-06-06 16:24:31 +04:00
ctl - > log_fd = - 1 ;
}
if ( ctl - > logfile ) {
free ( ctl - > logfile ) ;
ctl - > logfile = NULL ;
}
}
2007-12-06 13:24:52 +03:00
# ifdef USE_READLINE
2007-12-04 21:27:52 +03:00
2005-12-08 13:23:34 +03:00
/* -----------------
* Readline stuff
* - - - - - - - - - - - - - - - - -
*/
2007-02-07 16:50:18 +03:00
/*
2005-12-08 13:23:34 +03:00
* Generator function for command completion . STATE lets us
* know whether to start from scratch ; without any state
2007-02-07 16:50:18 +03:00
* ( i . e . STATE = = 0 ) , then we start at the top of the list .
2005-12-08 13:23:34 +03:00
*/
static char *
2006-03-15 15:13:25 +03:00
vshReadlineCommandGenerator ( const char * text , int state )
{
2005-12-08 13:23:34 +03:00
static int list_index , len ;
2005-12-08 17:22:52 +03:00
const char * name ;
2005-12-08 13:23:34 +03:00
/* If this is a new word to complete, initialize now. This
* includes saving the length of TEXT for efficiency , and
2007-02-07 16:50:18 +03:00
* initializing the index variable to 0.
2005-12-08 13:23:34 +03:00
*/
if ( ! state ) {
list_index = 0 ;
2006-03-15 15:13:25 +03:00
len = strlen ( text ) ;
2005-12-08 13:23:34 +03:00
}
/* Return the next name which partially matches from the
2007-02-07 16:50:18 +03:00
* command list .
2005-12-08 13:23:34 +03:00
*/
2005-12-08 17:22:52 +03:00
while ( ( name = commands [ list_index ] . name ) ) {
2005-12-08 13:23:34 +03:00
list_index + + ;
2006-03-15 15:13:25 +03:00
if ( strncmp ( name , text , len ) = = 0 )
2006-04-06 14:33:06 +04:00
return vshStrdup ( NULL , name ) ;
2005-12-08 13:23:34 +03:00
}
/* If no names matched, then return NULL. */
return NULL ;
}
static char *
2006-03-15 15:13:25 +03:00
vshReadlineOptionsGenerator ( const char * text , int state )
{
2005-12-08 13:23:34 +03:00
static int list_index , len ;
static vshCmdDef * cmd = NULL ;
2005-12-08 17:22:52 +03:00
const char * name ;
2005-12-08 13:23:34 +03:00
if ( ! state ) {
/* determine command name */
char * p ;
char * cmdname ;
if ( ! ( p = strchr ( rl_line_buffer , ' ' ) ) )
return NULL ;
2006-04-06 14:33:06 +04:00
cmdname = vshCalloc ( NULL , ( p - rl_line_buffer ) + 1 , 1 ) ;
2006-03-15 15:13:25 +03:00
memcpy ( cmdname , rl_line_buffer , p - rl_line_buffer ) ;
2005-12-08 13:23:34 +03:00
cmd = vshCmddefSearch ( cmdname ) ;
list_index = 0 ;
2006-03-15 15:13:25 +03:00
len = strlen ( text ) ;
2005-12-08 13:23:34 +03:00
free ( cmdname ) ;
}
if ( ! cmd )
return NULL ;
2006-03-15 15:13:25 +03:00
2007-02-27 18:35:50 +03:00
if ( ! cmd - > opts )
return NULL ;
2005-12-08 17:22:52 +03:00
while ( ( name = cmd - > opts [ list_index ] . name ) ) {
2005-12-08 13:23:34 +03:00
vshCmdOptDef * opt = & cmd - > opts [ list_index ] ;
char * res ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
list_index + + ;
2006-03-15 15:13:25 +03:00
2005-12-08 17:22:52 +03:00
if ( opt - > type = = VSH_OT_DATA )
2005-12-08 13:23:34 +03:00
/* ignore non --option */
continue ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( len > 2 ) {
2006-03-15 15:13:25 +03:00
if ( strncmp ( name , text + 2 , len - 2 ) )
2005-12-08 13:23:34 +03:00
continue ;
}
2006-04-06 14:33:06 +04:00
res = vshMalloc ( NULL , strlen ( name ) + 3 ) ;
2007-03-23 19:15:07 +03:00
snprintf ( res , strlen ( name ) + 3 , " --%s " , name ) ;
2005-12-08 13:23:34 +03:00
return res ;
}
/* If no names matched, then return NULL. */
return NULL ;
}
static char * *
2006-03-15 15:13:25 +03:00
vshReadlineCompletion ( const char * text , int start ,
int end ATTRIBUTE_UNUSED )
{
2005-12-08 13:23:34 +03:00
char * * matches = ( char * * ) NULL ;
2006-03-15 15:13:25 +03:00
if ( start = = 0 )
2005-12-08 13:23:34 +03:00
/* command name generator */
2006-03-15 15:13:25 +03:00
matches = rl_completion_matches ( text , vshReadlineCommandGenerator ) ;
2005-12-08 13:23:34 +03:00
else
/* commands options */
2006-03-15 15:13:25 +03:00
matches = rl_completion_matches ( text , vshReadlineOptionsGenerator ) ;
2005-12-08 13:23:34 +03:00
return matches ;
}
static void
2006-03-15 15:13:25 +03:00
vshReadlineInit ( void )
{
2005-12-08 13:23:34 +03:00
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = " virsh " ;
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = vshReadlineCompletion ;
}
2007-12-04 21:27:52 +03:00
static char *
vshReadline ( vshControl * ctl ATTRIBUTE_UNUSED , const char * prompt )
{
return readline ( prompt ) ;
}
2007-12-06 13:24:52 +03:00
# else /* !USE_READLINE */
2007-12-04 21:27:52 +03:00
static void
vshReadlineInit ( void )
{
/* empty */
}
static char *
vshReadline ( vshControl * ctl , const char * prompt )
{
char line [ 1024 ] ;
char * r ;
int len ;
fputs ( prompt , stdout ) ;
r = fgets ( line , sizeof line , stdin ) ;
if ( r = = NULL ) return NULL ; /* EOF */
/* Chomp trailing \n */
len = strlen ( r ) ;
if ( len > 0 & & r [ len - 1 ] = = ' \n ' )
r [ len - 1 ] = ' \0 ' ;
return vshStrdup ( ctl , r ) ;
}
2007-12-06 13:24:52 +03:00
# endif /* !USE_READLINE */
2007-12-04 21:27:52 +03:00
2005-12-08 13:23:34 +03:00
/*
* Deinitliaze virsh
*/
static int
2006-03-15 15:13:25 +03:00
vshDeinit ( vshControl * ctl )
{
2007-06-06 16:24:31 +04:00
vshCloseLogFile ( ctl ) ;
2007-12-01 18:45:25 +03:00
if ( ctl - > name )
free ( ctl - > name ) ;
2005-12-08 13:23:34 +03:00
if ( ctl - > conn ) {
2006-03-15 15:13:25 +03:00
if ( virConnectClose ( ctl - > conn ) ! = 0 ) {
ctl - > conn = NULL ; /* prevent recursive call from vshError() */
vshError ( ctl , TRUE ,
" failed to disconnect from the hypervisor " ) ;
2005-12-08 13:23:34 +03:00
}
}
2007-12-01 18:45:25 +03:00
virResetLastError ( ) ;
2005-12-08 13:23:34 +03:00
return TRUE ;
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/*
* Print usage
*/
static void
2006-03-15 15:13:25 +03:00
vshUsage ( vshControl * ctl , const char * cmdname )
{
2005-12-08 13:23:34 +03:00
vshCmdDef * cmd ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/* global help */
if ( ! cmdname ) {
2006-09-21 19:24:37 +04:00
fprintf ( stdout , _ ( " \n %s [options] [commands] \n \n "
2007-02-07 16:50:18 +03:00
" options: \n "
" -c | --connect <uri> hypervisor connection URI \n "
2007-03-08 16:48:22 +03:00
" -r | --readonly connect readonly \n "
2007-02-07 16:50:18 +03:00
" -d | --debug <num> debug level [0-5] \n "
" -h | --help this help \n "
" -q | --quiet quiet mode \n "
" -t | --timing print timing information \n "
2007-06-06 16:24:31 +04:00
" -l | --log <file> output logging to file \n "
2007-02-07 16:50:18 +03:00
" -v | --version program version \n \n "
" commands (non interactive mode): \n " ) , progname ) ;
2006-03-15 15:13:25 +03:00
for ( cmd = commands ; cmd - > name ; cmd + + )
fprintf ( stdout ,
2007-06-15 12:18:55 +04:00
" %-15s %s \n " , cmd - > name , N_ ( vshCmddefGetInfo ( cmd ,
2007-02-07 16:50:18 +03:00
" help " ) ) ) ;
2006-03-15 15:13:25 +03:00
fprintf ( stdout ,
2007-07-06 19:05:19 +04:00
_ ( " \n (specify help <command> for details about the command) \n \n " ) ) ;
2005-12-08 13:23:34 +03:00
return ;
}
if ( ! vshCmddefHelp ( ctl , cmdname , TRUE ) )
exit ( EXIT_FAILURE ) ;
}
/*
* argv [ ] : virsh [ options ] [ command ]
*
*/
static int
2006-03-15 15:13:25 +03:00
vshParseArgv ( vshControl * ctl , int argc , char * * argv )
{
2005-12-08 13:23:34 +03:00
char * last = NULL ;
int i , end = 0 , help = 0 ;
2006-03-15 15:13:25 +03:00
int arg , idx = 0 ;
2005-12-08 13:23:34 +03:00
struct option opt [ ] = {
2006-03-15 15:13:25 +03:00
{ " debug " , 1 , 0 , ' d ' } ,
{ " help " , 0 , 0 , ' h ' } ,
{ " quiet " , 0 , 0 , ' q ' } ,
{ " timing " , 0 , 0 , ' t ' } ,
{ " version " , 0 , 0 , ' v ' } ,
2006-05-29 19:39:31 +04:00
{ " connect " , 1 , 0 , ' c ' } ,
2007-03-08 16:48:22 +03:00
{ " readonly " , 0 , 0 , ' r ' } ,
2007-06-06 16:24:31 +04:00
{ " log " , 1 , 0 , ' l ' } ,
2005-12-08 13:23:34 +03:00
{ 0 , 0 , 0 , 0 }
2006-03-15 15:13:25 +03:00
} ;
2005-12-08 13:23:34 +03:00
if ( argc < 2 )
2005-12-08 17:22:52 +03:00
return TRUE ;
2006-03-15 15:13:25 +03:00
2006-01-25 12:46:22 +03:00
/* look for begin of the command, for example:
2005-12-08 13:23:34 +03:00
* . / virsh - - debug 5 - q command - - cmdoption
* < - - - ^ - - - >
* getopt ( ) stuff | command suff
*/
2006-03-15 15:13:25 +03:00
for ( i = 1 ; i < argc ; i + + ) {
2005-12-08 13:23:34 +03:00
if ( * argv [ i ] ! = ' - ' ) {
int valid = FALSE ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/* non "--option" argv, is it command? */
if ( last ) {
struct option * o ;
int sz = strlen ( last ) ;
2006-03-15 15:13:25 +03:00
for ( o = opt ; o - > name ; o + + ) {
2007-02-27 18:32:18 +03:00
if ( o - > has_arg = = 1 ) {
if ( sz = = 2 & & * ( last + 1 ) = = o - > val )
/* valid virsh short option */
valid = TRUE ;
else if ( sz > 2 & & strcmp ( o - > name , last + 2 ) = = 0 )
/* valid virsh long option */
valid = TRUE ;
}
2005-12-08 13:23:34 +03:00
}
}
if ( ! valid ) {
end = i ;
break ;
}
}
last = argv [ i ] ;
}
2007-09-29 22:16:26 +04:00
end = end ? end : argc ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
/* standard (non-command) options */
2007-06-06 16:24:31 +04:00
while ( ( arg = getopt_long ( end , argv , " d:hqtc:vrl: " , opt , & idx ) ) ! = - 1 ) {
2006-03-15 15:13:25 +03:00
switch ( arg ) {
2007-02-07 16:50:18 +03:00
case ' d ' :
ctl - > debug = atoi ( optarg ) ;
break ;
case ' h ' :
help = 1 ;
break ;
case ' q ' :
ctl - > quiet = TRUE ;
break ;
case ' t ' :
ctl - > timing = TRUE ;
break ;
case ' c ' :
ctl - > name = vshStrdup ( ctl , optarg ) ;
break ;
case ' v ' :
fprintf ( stdout , " %s \n " , VERSION ) ;
exit ( EXIT_SUCCESS ) ;
2007-03-08 16:48:22 +03:00
case ' r ' :
ctl - > readonly = TRUE ;
break ;
2007-06-06 16:24:31 +04:00
case ' l ' :
ctl - > logfile = vshStrdup ( ctl , optarg ) ;
break ;
2007-02-07 16:50:18 +03:00
default :
vshError ( ctl , TRUE ,
_ ( " unsupported option '-%c'. See --help. " ) , arg ) ;
break ;
2005-12-08 13:23:34 +03:00
}
}
if ( help ) {
/* global or command specific help */
vshUsage ( ctl , argc > end ? argv [ end ] : NULL ) ;
exit ( EXIT_SUCCESS ) ;
2006-03-15 15:13:25 +03:00
}
2005-12-08 13:23:34 +03:00
if ( argc > end ) {
/* parse command */
char * cmdstr ;
2006-03-15 15:13:25 +03:00
int sz = 0 , ret ;
2005-12-08 13:23:34 +03:00
ctl - > imode = FALSE ;
2006-03-15 15:13:25 +03:00
for ( i = end ; i < argc ; i + + )
sz + = strlen ( argv [ i ] ) + 1 ; /* +1 is for blank space between items */
2006-04-06 14:33:06 +04:00
cmdstr = vshCalloc ( ctl , sz + 1 , 1 ) ;
2006-03-15 15:13:25 +03:00
for ( i = end ; i < argc ; i + + ) {
2005-12-08 13:23:34 +03:00
strncat ( cmdstr , argv [ i ] , sz ) ;
sz - = strlen ( argv [ i ] ) ;
strncat ( cmdstr , " " , sz - - ) ;
}
2006-05-22 18:38:33 +04:00
vshDebug ( ctl , 2 , " command: \" %s \" \n " , cmdstr ) ;
2005-12-08 13:23:34 +03:00
ret = vshCommandParse ( ctl , cmdstr ) ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
free ( cmdstr ) ;
return ret ;
}
return TRUE ;
}
2006-03-15 15:13:25 +03:00
int
main ( int argc , char * * argv )
{
vshControl _ctl , * ctl = & _ctl ;
2006-08-26 02:40:33 +04:00
char * defaultConn ;
2005-12-08 13:23:34 +03:00
int ret = TRUE ;
2006-09-21 19:24:37 +04:00
if ( ! setlocale ( LC_ALL , " " ) ) {
perror ( " setlocale " ) ;
2007-02-07 16:50:18 +03:00
return - 1 ;
2006-09-21 19:24:37 +04:00
}
if ( ! bindtextdomain ( GETTEXT_PACKAGE , LOCALEBASEDIR ) ) {
perror ( " bindtextdomain " ) ;
2007-02-07 16:50:18 +03:00
return - 1 ;
2006-09-21 19:24:37 +04:00
}
if ( ! textdomain ( GETTEXT_PACKAGE ) ) {
perror ( " textdomain " ) ;
2007-02-07 16:50:18 +03:00
return - 1 ;
2006-09-21 19:24:37 +04:00
}
2006-03-15 15:13:25 +03:00
if ( ! ( progname = strrchr ( argv [ 0 ] , ' / ' ) ) )
2005-12-08 13:23:34 +03:00
progname = argv [ 0 ] ;
else
progname + + ;
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
memset ( ctl , 0 , sizeof ( vshControl ) ) ;
2006-03-15 15:13:25 +03:00
ctl - > imode = TRUE ; /* default is interactive mode */
2007-06-06 16:24:31 +04:00
ctl - > log_fd = - 1 ; /* Initialize log file descriptor */
2005-12-08 13:23:34 +03:00
2006-08-26 02:40:33 +04:00
if ( ( defaultConn = getenv ( " VIRSH_DEFAULT_CONNECT_URI " ) ) ) {
2007-02-07 16:50:18 +03:00
ctl - > name = strdup ( defaultConn ) ;
2006-08-26 02:40:33 +04:00
}
2007-12-01 18:45:25 +03:00
if ( ! vshParseArgv ( ctl , argc , argv ) ) {
vshDeinit ( ctl ) ;
2005-12-08 13:23:34 +03:00
exit ( EXIT_FAILURE ) ;
2007-12-01 18:45:25 +03:00
}
2006-03-15 15:13:25 +03:00
2007-12-01 18:45:25 +03:00
if ( ! vshInit ( ctl ) ) {
vshDeinit ( ctl ) ;
2005-12-08 13:23:34 +03:00
exit ( EXIT_FAILURE ) ;
2007-12-01 18:45:25 +03:00
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
if ( ! ctl - > imode ) {
2006-03-15 15:13:25 +03:00
ret = vshCommandRun ( ctl , ctl - > cmd ) ;
2005-12-01 19:35:42 +03:00
} else {
2005-12-08 13:23:34 +03:00
/* interactive mode */
if ( ! ctl - > quiet ) {
2006-05-22 18:38:33 +04:00
vshPrint ( ctl ,
2006-09-21 19:24:37 +04:00
_ ( " Welcome to %s, the virtualization interactive terminal. \n \n " ) ,
2006-03-15 15:13:25 +03:00
progname ) ;
2006-05-22 18:38:33 +04:00
vshPrint ( ctl ,
2006-09-21 19:24:37 +04:00
_ ( " Type: 'help' for help with commands \n "
2007-02-07 16:50:18 +03:00
" 'quit' to quit \n \n " ) ) ;
2005-12-08 13:23:34 +03:00
}
2005-12-08 17:22:52 +03:00
vshReadlineInit ( ) ;
2005-12-08 13:23:34 +03:00
do {
2006-03-15 15:13:25 +03:00
ctl - > cmdstr =
2007-12-04 21:27:52 +03:00
vshReadline ( ctl , ctl - > uid = = 0 ? VSH_PROMPT_RW : VSH_PROMPT_RO ) ;
2006-03-15 15:13:25 +03:00
if ( ctl - > cmdstr = = NULL )
break ; /* EOF */
2005-12-08 13:23:34 +03:00
if ( * ctl - > cmdstr ) {
2007-12-06 13:24:52 +03:00
# if USE_READLINE
2005-12-08 13:23:34 +03:00
add_history ( ctl - > cmdstr ) ;
2007-12-04 21:27:52 +03:00
# endif
2005-12-08 13:23:34 +03:00
if ( vshCommandParse ( ctl , ctl - > cmdstr ) )
vshCommandRun ( ctl , ctl - > cmd ) ;
}
free ( ctl - > cmdstr ) ;
ctl - > cmdstr = NULL ;
2006-03-15 15:13:25 +03:00
} while ( ctl - > imode ) ;
2005-12-08 13:23:34 +03:00
2006-03-15 15:13:25 +03:00
if ( ctl - > cmdstr = = NULL )
fputc ( ' \n ' , stdout ) ; /* line break after alone prompt */
2005-12-08 13:23:34 +03:00
}
2006-03-15 15:13:25 +03:00
2005-12-08 13:23:34 +03:00
vshDeinit ( ctl ) ;
exit ( ret ? EXIT_SUCCESS : EXIT_FAILURE ) ;
2005-11-10 19:12:31 +03:00
}
2005-12-08 13:23:34 +03:00
/*
* vim : set tabstop = 4 :
* vim : set shiftwidth = 4 :
* vim : set expandtab :
*/
2007-02-07 16:50:18 +03:00
/*
* Local variables :
* indent - tabs - mode : nil
* c - indent - level : 4
* c - basic - offset : 4
* tab - width : 4
* End :
*/