2012-07-23 10:37:50 +04:00
/*
* virsh - host . c : Commands in " Host and Hypervisor " group .
*
2014-06-19 19:21:08 +04:00
* Copyright ( C ) 2005 , 2007 - 2014 Red Hat , Inc .
2012-07-23 10:37:50 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2012-09-21 02:30:55 +04:00
* License along with this library . If not , see
2012-07-23 10:37:50 +04:00
* < http : //www.gnu.org/licenses/>.
*/
2012-08-21 00:01:45 +04:00
# include <config.h>
# include "virsh-host.h"
2020-02-24 00:45:34 +03:00
# include "virsh.h"
2012-08-21 00:01:45 +04:00
# include <libxml/parser.h>
# include <libxml/xpath.h>
# include "internal.h"
2014-06-05 15:16:00 +04:00
# include "virbitmap.h"
2012-12-12 22:06:53 +04:00
# include "viralloc.h"
2012-12-13 22:13:21 +04:00
# include "virxml.h"
2013-04-03 14:36:23 +04:00
# include "virstring.h"
2018-04-26 11:35:51 +03:00
# include "virfile.h"
2019-04-01 13:14:26 +03:00
# include "virenum.h"
2012-08-21 00:01:45 +04:00
2012-07-23 10:37:50 +04:00
/*
* " capabilities " command
*/
static const vshCmdInfo info_capabilities [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " capabilities " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns capabilities of hypervisor/driver. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdCapabilities ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
char * caps ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
if ( ( caps = virConnectGetCapabilities ( priv - > conn ) ) = = NULL ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " failed to get capabilities " ) ) ;
return false ;
}
vshPrint ( ctl , " %s \n " , caps ) ;
VIR_FREE ( caps ) ;
return true ;
}
2014-06-25 19:56:20 +04:00
/*
* " domcapabilities " command
*/
static const vshCmdInfo info_domcapabilities [ ] = {
{ . name = " help " ,
. data = N_ ( " domain capabilities " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns capabilities of emulator with respect to host and libvirt. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_domcapabilities [ ] = {
{ . name = " virttype " ,
. type = VSH_OT_STRING ,
. help = N_ ( " virtualization type (/domain/@type) " ) ,
} ,
{ . name = " emulatorbin " ,
. type = VSH_OT_STRING ,
. help = N_ ( " path to emulator binary (/domain/devices/emulator) " ) ,
} ,
{ . name = " arch " ,
. type = VSH_OT_STRING ,
. help = N_ ( " domain architecture (/domain/os/type/@arch) " ) ,
} ,
{ . name = " machine " ,
. type = VSH_OT_STRING ,
. help = N_ ( " machine type (/domain/os/type/@machine) " ) ,
} ,
{ . name = NULL }
} ;
static bool
cmdDomCapabilities ( vshControl * ctl , const vshCmd * cmd )
{
bool ret = false ;
char * caps = NULL ;
const char * virttype = NULL ;
const char * emulatorbin = NULL ;
const char * arch = NULL ;
const char * machine = NULL ;
const unsigned int flags = 0 ; /* No flags so far */
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2014-06-25 19:56:20 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " virttype " , & virttype ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " emulatorbin " , & emulatorbin ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " arch " , & arch ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " machine " , & machine ) < 0 )
return ret ;
2015-06-15 19:53:58 +03:00
caps = virConnectGetDomainCapabilities ( priv - > conn , emulatorbin ,
2014-06-25 19:56:20 +04:00
arch , machine , virttype , flags ) ;
if ( ! caps ) {
vshError ( ctl , " %s " , _ ( " failed to get emulator capabilities " ) ) ;
goto cleanup ;
}
vshPrint ( ctl , " %s \n " , caps ) ;
ret = true ;
cleanup :
VIR_FREE ( caps ) ;
return ret ;
}
2012-07-23 10:37:50 +04:00
/*
* " freecell " command
*/
static const vshCmdInfo info_freecell [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " NUMA free memory " )
} ,
{ . name = " desc " ,
. data = N_ ( " display available free memory for the NUMA cell. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static const vshCmdOptDef opts_freecell [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " cellno " ,
. type = VSH_OT_INT ,
2018-05-25 10:12:37 +03:00
. completer = virshCellnoCompleter ,
2013-01-14 18:18:32 +04:00
. help = N_ ( " NUMA cell number " )
} ,
{ . name = " all " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " show free memory for all NUMA cells " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
cmdFreecell ( vshControl * ctl , const vshCmd * cmd )
{
2013-03-07 13:36:08 +04:00
bool ret = false ;
int cell = - 1 ;
unsigned long long memory = 0 ;
2012-07-23 10:37:50 +04:00
xmlNodePtr * nodes = NULL ;
unsigned long nodes_cnt ;
unsigned long * nodes_id = NULL ;
unsigned long long * nodes_free = NULL ;
2013-03-07 13:36:08 +04:00
bool all = vshCommandOptBool ( cmd , " all " ) ;
bool cellno = vshCommandOptBool ( cmd , " cellno " ) ;
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-07-23 10:37:50 +04:00
char * cap_xml = NULL ;
xmlDocPtr xml = NULL ;
xmlXPathContextPtr ctxt = NULL ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2013-03-07 13:36:08 +04:00
VSH_EXCLUSIVE_OPTIONS_VAR ( all , cellno ) ;
2012-07-23 10:37:50 +04:00
2015-06-02 12:17:29 +03:00
if ( cellno & & vshCommandOptInt ( ctl , cmd , " cellno " , & cell ) < 0 )
2013-03-07 13:36:08 +04:00
return false ;
2012-07-23 10:37:50 +04:00
2013-03-07 13:36:08 +04:00
if ( all ) {
2015-06-15 19:53:58 +03:00
if ( ! ( cap_xml = virConnectGetCapabilities ( priv - > conn ) ) ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " unable to get node capabilities " ) ) ;
goto cleanup ;
}
xml = virXMLParseStringCtxt ( cap_xml , _ ( " (capabilities) " ) , & ctxt ) ;
if ( ! xml ) {
vshError ( ctl , " %s " , _ ( " unable to get node capabilities " ) ) ;
goto cleanup ;
}
2013-03-07 13:36:08 +04:00
2012-07-23 10:37:50 +04:00
nodes_cnt = virXPathNodeSet ( " /capabilities/host/topology/cells/cell " ,
ctxt , & nodes ) ;
if ( nodes_cnt = = - 1 ) {
vshError ( ctl , " %s " , _ ( " could not get information about "
" NUMA topology " ) ) ;
goto cleanup ;
}
nodes_free = vshCalloc ( ctl , nodes_cnt , sizeof ( * nodes_free ) ) ;
nodes_id = vshCalloc ( ctl , nodes_cnt , sizeof ( * nodes_id ) ) ;
for ( i = 0 ; i < nodes_cnt ; i + + ) {
unsigned long id ;
char * val = virXMLPropString ( nodes [ i ] , " id " ) ;
2017-03-27 15:17:42 +03:00
if ( virStrToLong_ulp ( val , NULL , 10 , & id ) ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " conversion from string failed " ) ) ;
VIR_FREE ( val ) ;
goto cleanup ;
}
VIR_FREE ( val ) ;
2014-01-20 15:27:29 +04:00
nodes_id [ i ] = id ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetCellsFreeMemory ( priv - > conn , & ( nodes_free [ i ] ) ,
2013-03-07 13:36:08 +04:00
id , 1 ) ! = 1 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , _ ( " failed to get free memory for NUMA node "
" number: %lu " ) , id ) ;
goto cleanup ;
}
}
for ( cell = 0 ; cell < nodes_cnt ; cell + + ) {
vshPrint ( ctl , " %5lu: %10llu KiB \n " , nodes_id [ cell ] ,
( nodes_free [ cell ] / 1024 ) ) ;
memory + = nodes_free [ cell ] ;
}
vshPrintExtra ( ctl , " -------------------- \n " ) ;
vshPrintExtra ( ctl , " %5s: %10llu KiB \n " , _ ( " Total " ) , memory / 1024 ) ;
} else {
2013-03-07 13:36:08 +04:00
if ( cellno ) {
2015-06-15 19:53:58 +03:00
if ( virNodeGetCellsFreeMemory ( priv - > conn , & memory , cell , 1 ) ! = 1 )
2012-07-23 10:37:50 +04:00
goto cleanup ;
2013-03-07 13:36:08 +04:00
vshPrint ( ctl , " %d: %llu KiB \n " , cell , ( memory / 1024 ) ) ;
2012-07-23 10:37:50 +04:00
} else {
2015-06-15 19:53:58 +03:00
if ( ( memory = virNodeGetFreeMemory ( priv - > conn ) ) = = 0 )
2012-07-23 10:37:50 +04:00
goto cleanup ;
vshPrint ( ctl , " %s: %llu KiB \n " , _ ( " Total " ) , ( memory / 1024 ) ) ;
2013-03-07 13:36:08 +04:00
}
2012-07-23 10:37:50 +04:00
}
2013-03-07 13:36:08 +04:00
ret = true ;
2012-07-23 10:37:50 +04:00
2014-03-25 10:53:59 +04:00
cleanup :
2012-07-23 10:37:50 +04:00
xmlXPathFreeContext ( ctxt ) ;
xmlFreeDoc ( xml ) ;
VIR_FREE ( nodes ) ;
VIR_FREE ( nodes_free ) ;
VIR_FREE ( nodes_id ) ;
VIR_FREE ( cap_xml ) ;
2013-03-07 13:36:08 +04:00
return ret ;
2012-07-23 10:37:50 +04:00
}
2014-06-09 19:56:43 +04:00
/*
* " freepages " command
*/
static const vshCmdInfo info_freepages [ ] = {
{ . name = " help " ,
2014-08-21 07:19:53 +04:00
. data = N_ ( " NUMA free pages " )
2014-06-09 19:56:43 +04:00
} ,
{ . name = " desc " ,
2014-08-21 07:19:53 +04:00
. data = N_ ( " display available free pages for the NUMA cell. " )
2014-06-09 19:56:43 +04:00
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_freepages [ ] = {
{ . name = " cellno " ,
. type = VSH_OT_INT ,
2018-05-25 10:12:37 +03:00
. completer = virshCellnoCompleter ,
2014-06-09 19:56:43 +04:00
. help = N_ ( " NUMA cell number " )
} ,
{ . name = " pagesize " ,
. type = VSH_OT_INT ,
2018-05-24 16:11:12 +03:00
. completer = virshAllocpagesPagesizeCompleter ,
2014-06-19 19:21:08 +04:00
. help = N_ ( " page size (in kibibytes) " )
2014-06-09 19:56:43 +04:00
} ,
{ . name = " all " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " show free pages for all NUMA cells " )
} ,
{ . name = NULL }
} ;
2015-07-02 11:21:50 +03:00
static int
vshPageSizeSorter ( const void * a , const void * b )
{
unsigned int pa = * ( unsigned int * ) a ;
unsigned int pb = * ( unsigned int * ) b ;
return pa - pb ;
}
2014-06-09 19:56:43 +04:00
static bool
cmdFreepages ( vshControl * ctl , const vshCmd * cmd )
{
bool ret = false ;
unsigned int npages ;
unsigned int * pagesize = NULL ;
2014-09-22 14:14:26 +04:00
unsigned long long bytes = 0 ;
unsigned int kibibytes = 0 ;
2014-06-09 19:56:43 +04:00
int cell ;
unsigned long long * counts = NULL ;
size_t i , j ;
xmlNodePtr * nodes = NULL ;
int nodes_cnt ;
char * cap_xml = NULL ;
xmlDocPtr doc = NULL ;
xmlXPathContextPtr ctxt = NULL ;
bool all = vshCommandOptBool ( cmd , " all " ) ;
bool cellno = vshCommandOptBool ( cmd , " cellno " ) ;
2014-09-22 14:14:26 +04:00
bool pagesz = vshCommandOptBool ( cmd , " pagesize " ) ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2014-06-09 19:56:43 +04:00
VSH_EXCLUSIVE_OPTIONS_VAR ( all , cellno ) ;
2015-06-02 12:17:29 +03:00
if ( vshCommandOptScaledInt ( ctl , cmd , " pagesize " , & bytes , 1024 , UINT_MAX ) < 0 )
2014-09-22 14:14:26 +04:00
goto cleanup ;
kibibytes = VIR_DIV_UP ( bytes , 1024 ) ;
2014-06-09 19:56:43 +04:00
if ( all ) {
2015-06-15 19:53:58 +03:00
if ( ! ( cap_xml = virConnectGetCapabilities ( priv - > conn ) ) ) {
2014-06-09 19:56:43 +04:00
vshError ( ctl , " %s " , _ ( " unable to get node capabilities " ) ) ;
goto cleanup ;
}
if ( ! ( doc = virXMLParseStringCtxt ( cap_xml , _ ( " capabilities " ) , & ctxt ) ) ) {
vshError ( ctl , " %s " , _ ( " unable to parse node capabilities " ) ) ;
goto cleanup ;
}
2014-09-22 14:14:26 +04:00
if ( ! pagesz ) {
nodes_cnt = virXPathNodeSet ( " /capabilities/host/cpu/pages " , ctxt , & nodes ) ;
2014-06-09 19:56:43 +04:00
2014-09-22 14:14:26 +04:00
if ( nodes_cnt < = 0 ) {
2015-07-02 11:21:50 +03:00
/* Some drivers don't export page sizes under the
* XPath above . Do another trick to get them . */
nodes_cnt = virXPathNodeSet ( " /capabilities/host/topology/cells/cell/pages " ,
ctxt , & nodes ) ;
if ( nodes_cnt < = 0 ) {
vshError ( ctl , " %s " , _ ( " could not get information about "
" supported page sizes " ) ) ;
goto cleanup ;
}
2014-09-22 14:14:26 +04:00
}
2014-06-09 19:56:43 +04:00
2014-09-22 14:14:26 +04:00
pagesize = vshCalloc ( ctl , nodes_cnt , sizeof ( * pagesize ) ) ;
2014-06-09 19:56:43 +04:00
2014-09-22 14:14:26 +04:00
for ( i = 0 ; i < nodes_cnt ; i + + ) {
char * val = virXMLPropString ( nodes [ i ] , " size " ) ;
2017-03-27 15:17:42 +03:00
if ( virStrToLong_uip ( val , NULL , 10 , & pagesize [ i ] ) < 0 ) {
2014-09-22 14:14:26 +04:00
vshError ( ctl , _ ( " unable to parse page size: %s " ) , val ) ;
VIR_FREE ( val ) ;
goto cleanup ;
}
2014-06-09 19:56:43 +04:00
VIR_FREE ( val ) ;
}
2015-07-02 11:21:50 +03:00
/* Here, if we've done the trick few lines above,
* @ pagesize array will contain duplicates . We should
* remove them otherwise not very nice output will be
* produced . */
qsort ( pagesize , nodes_cnt , sizeof ( * pagesize ) , vshPageSizeSorter ) ;
for ( i = 0 ; i < nodes_cnt - 1 ; ) {
if ( pagesize [ i ] = = pagesize [ i + 1 ] ) {
memmove ( pagesize + i , pagesize + i + 1 ,
( nodes_cnt - i + 1 ) * sizeof ( * pagesize ) ) ;
nodes_cnt - - ;
} else {
i + + ;
}
}
2014-09-22 14:14:26 +04:00
npages = nodes_cnt ;
VIR_FREE ( nodes ) ;
} else {
pagesize = vshMalloc ( ctl , sizeof ( * pagesize ) ) ;
pagesize [ 0 ] = kibibytes ;
npages = 1 ;
2014-06-09 19:56:43 +04:00
}
2014-06-19 19:21:08 +04:00
counts = vshCalloc ( ctl , npages , sizeof ( * counts ) ) ;
2014-06-09 19:56:43 +04:00
nodes_cnt = virXPathNodeSet ( " /capabilities/host/topology/cells/cell " ,
ctxt , & nodes ) ;
for ( i = 0 ; i < nodes_cnt ; i + + ) {
char * val = virXMLPropString ( nodes [ i ] , " id " ) ;
if ( virStrToLong_i ( val , NULL , 10 , & cell ) < 0 ) {
vshError ( ctl , _ ( " unable to parse numa node id: %s " ) , val ) ;
VIR_FREE ( val ) ;
goto cleanup ;
}
VIR_FREE ( val ) ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetFreePages ( priv - > conn , npages , pagesize ,
2014-06-09 19:56:43 +04:00
cell , 1 , counts , 0 ) < 0 )
goto cleanup ;
vshPrint ( ctl , _ ( " Node %d: \n " ) , cell ) ;
2014-11-13 17:20:51 +03:00
for ( j = 0 ; j < npages ; j + + )
2014-06-09 19:56:43 +04:00
vshPrint ( ctl , " %uKiB: %lld \n " , pagesize [ j ] , counts [ j ] ) ;
vshPrint ( ctl , " %c " , ' \n ' ) ;
}
} else {
if ( ! cellno ) {
vshError ( ctl , " %s " , _ ( " missing cellno argument " ) ) ;
goto cleanup ;
}
2015-06-02 12:17:29 +03:00
if ( vshCommandOptInt ( ctl , cmd , " cellno " , & cell ) < 0 )
2014-06-09 19:56:43 +04:00
goto cleanup ;
if ( cell < - 1 ) {
2014-09-22 14:14:26 +04:00
vshError ( ctl , " %s " ,
_ ( " cell number must be non-negative integer or -1 " ) ) ;
2014-06-09 19:56:43 +04:00
goto cleanup ;
}
2014-09-22 14:14:26 +04:00
if ( ! pagesz ) {
vshError ( ctl , " %s " , _ ( " missing pagesize argument " ) ) ;
2014-06-09 19:56:43 +04:00
goto cleanup ;
}
2014-09-22 14:14:26 +04:00
2014-06-09 19:56:43 +04:00
/* page size is expected in kibibytes */
2014-06-19 19:21:08 +04:00
pagesize = vshMalloc ( ctl , sizeof ( * pagesize ) ) ;
2014-09-22 14:14:26 +04:00
pagesize [ 0 ] = kibibytes ;
2014-06-09 19:56:43 +04:00
counts = vshMalloc ( ctl , sizeof ( * counts ) ) ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetFreePages ( priv - > conn , 1 , pagesize ,
cell , 1 , counts , 0 ) < 0 )
2014-06-09 19:56:43 +04:00
goto cleanup ;
vshPrint ( ctl , " %uKiB: %lld \n " , * pagesize , counts [ 0 ] ) ;
}
ret = true ;
cleanup :
xmlXPathFreeContext ( ctxt ) ;
xmlFreeDoc ( doc ) ;
VIR_FREE ( cap_xml ) ;
VIR_FREE ( nodes ) ;
VIR_FREE ( counts ) ;
VIR_FREE ( pagesize ) ;
return ret ;
}
2014-09-17 17:53:42 +04:00
/*
* " allocpages " command
*/
static const vshCmdInfo info_allocpages [ ] = {
{ . name = " help " ,
. data = N_ ( " Manipulate pages pool size " )
} ,
{ . name = " desc " ,
. data = N_ ( " Allocate or free some pages in the pool for NUMA cell. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_allocpages [ ] = {
{ . name = " pagesize " ,
. type = VSH_OT_INT ,
. flags = VSH_OFLAG_REQ ,
2018-05-21 14:53:44 +03:00
. completer = virshAllocpagesPagesizeCompleter ,
2014-09-17 17:53:42 +04:00
. help = N_ ( " page size (in kibibytes) " )
} ,
{ . name = " pagecount " ,
. type = VSH_OT_INT ,
. flags = VSH_OFLAG_REQ ,
. help = N_ ( " page count " )
} ,
{ . name = " cellno " ,
. type = VSH_OT_INT ,
2018-05-25 10:12:37 +03:00
. completer = virshCellnoCompleter ,
2014-09-17 17:53:42 +04:00
. help = N_ ( " NUMA cell number " )
} ,
{ . name = " add " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " instead of setting new pool size add pages to it " )
} ,
{ . name = " all " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " set on all NUMA cells " )
} ,
{ . name = NULL }
} ;
static bool
cmdAllocpages ( vshControl * ctl , const vshCmd * cmd )
{
bool ret = false ;
bool add = vshCommandOptBool ( cmd , " add " ) ;
bool all = vshCommandOptBool ( cmd , " all " ) ;
bool cellno = vshCommandOptBool ( cmd , " cellno " ) ;
int startCell = - 1 ;
int cellCount = 1 ;
unsigned int pageSizes [ 1 ] ;
unsigned long long pageCounts [ 1 ] , tmp ;
unsigned int flags = 0 ;
char * cap_xml = NULL ;
xmlDocPtr xml = NULL ;
xmlXPathContextPtr ctxt = NULL ;
xmlNodePtr * nodes = NULL ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2014-09-17 17:53:42 +04:00
VSH_EXCLUSIVE_OPTIONS_VAR ( all , cellno ) ;
2015-06-02 12:17:29 +03:00
if ( cellno & & vshCommandOptInt ( ctl , cmd , " cellno " , & startCell ) < 0 )
2014-09-17 17:53:42 +04:00
return false ;
2015-06-02 12:17:29 +03:00
if ( vshCommandOptScaledInt ( ctl , cmd , " pagesize " , & tmp , 1024 , UINT_MAX ) < 0 )
2014-09-17 17:53:42 +04:00
return false ;
pageSizes [ 0 ] = VIR_DIV_UP ( tmp , 1024 ) ;
2015-06-02 12:17:29 +03:00
if ( vshCommandOptULongLong ( ctl , cmd , " pagecount " , & pageCounts [ 0 ] ) < 0 )
2014-09-17 17:53:42 +04:00
return false ;
flags | = add ? VIR_NODE_ALLOC_PAGES_ADD : VIR_NODE_ALLOC_PAGES_SET ;
if ( all ) {
unsigned long nodes_cnt ;
size_t i ;
2015-06-15 19:53:58 +03:00
if ( ! ( cap_xml = virConnectGetCapabilities ( priv - > conn ) ) ) {
2014-09-17 17:53:42 +04:00
vshError ( ctl , " %s " , _ ( " unable to get node capabilities " ) ) ;
goto cleanup ;
}
xml = virXMLParseStringCtxt ( cap_xml , _ ( " (capabilities) " ) , & ctxt ) ;
if ( ! xml ) {
vshError ( ctl , " %s " , _ ( " unable to get node capabilities " ) ) ;
goto cleanup ;
}
nodes_cnt = virXPathNodeSet ( " /capabilities/host/topology/cells/cell " ,
ctxt , & nodes ) ;
if ( nodes_cnt = = - 1 ) {
vshError ( ctl , " %s " , _ ( " could not get information about "
" NUMA topology " ) ) ;
goto cleanup ;
}
for ( i = 0 ; i < nodes_cnt ; i + + ) {
unsigned long id ;
char * val = virXMLPropString ( nodes [ i ] , " id " ) ;
2017-03-27 15:17:42 +03:00
if ( virStrToLong_ulp ( val , NULL , 10 , & id ) ) {
2014-09-17 17:53:42 +04:00
vshError ( ctl , " %s " , _ ( " conversion from string failed " ) ) ;
VIR_FREE ( val ) ;
goto cleanup ;
}
VIR_FREE ( val ) ;
2015-06-15 19:53:58 +03:00
if ( virNodeAllocPages ( priv - > conn , 1 , pageSizes ,
2014-09-17 17:53:42 +04:00
pageCounts , id , 1 , flags ) < 0 )
goto cleanup ;
}
} else {
2015-06-15 19:53:58 +03:00
if ( virNodeAllocPages ( priv - > conn , 1 , pageSizes , pageCounts ,
2014-09-17 17:53:42 +04:00
startCell , cellCount , flags ) < 0 )
goto cleanup ;
}
ret = true ;
cleanup :
xmlXPathFreeContext ( ctxt ) ;
xmlFreeDoc ( xml ) ;
VIR_FREE ( nodes ) ;
VIR_FREE ( cap_xml ) ;
return ret ;
}
2013-09-09 06:14:22 +04:00
/*
* " maxvcpus " command
*/
static const vshCmdInfo info_maxvcpus [ ] = {
{ . name = " help " ,
. data = N_ ( " connection vcpu maximum " )
} ,
{ . name = " desc " ,
. data = N_ ( " Show maximum number of virtual CPUs for guests on this connection. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_maxvcpus [ ] = {
{ . name = " type " ,
. type = VSH_OT_STRING ,
. help = N_ ( " domain type " )
} ,
{ . name = NULL }
} ;
static bool
cmdMaxvcpus ( vshControl * ctl , const vshCmd * cmd )
{
const char * type = NULL ;
2016-09-07 11:55:42 +03:00
int vcpus = - 1 ;
char * caps = NULL ;
xmlDocPtr xml = NULL ;
xmlXPathContextPtr ctxt = NULL ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2016-09-07 11:55:42 +03:00
bool ret = false ;
2013-09-09 06:14:22 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " type " , & type ) < 0 )
return false ;
2016-09-07 11:55:42 +03:00
if ( ( caps = virConnectGetDomainCapabilities ( priv - > conn , NULL , NULL , NULL ,
type , 0 ) ) ) {
if ( ! ( xml = virXMLParseStringCtxt ( caps , _ ( " (domainCapabilities) " ) , & ctxt ) ) )
goto cleanup ;
ignore_value ( virXPathInt ( " string(./vcpu[1]/@max) " , ctxt , & vcpus ) ) ;
} else {
vshResetLibvirtError ( ) ;
}
if ( vcpus < 0 & & ( vcpus = virConnectGetMaxVcpus ( priv - > conn , type ) ) < 0 )
goto cleanup ;
2013-09-09 06:14:22 +04:00
vshPrint ( ctl , " %d \n " , vcpus ) ;
2016-09-07 11:55:42 +03:00
ret = true ;
2013-09-09 06:14:22 +04:00
2016-09-07 11:55:42 +03:00
cleanup :
xmlXPathFreeContext ( ctxt ) ;
xmlFreeDoc ( xml ) ;
VIR_FREE ( caps ) ;
return ret ;
2013-09-09 06:14:22 +04:00
}
2012-07-23 10:37:50 +04:00
/*
* " nodeinfo " command
*/
static const vshCmdInfo info_nodeinfo [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " node information " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns basic information about the node. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdNodeinfo ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
virNodeInfo info ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
if ( virNodeGetInfo ( priv - > conn , & info ) < 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " 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 ) ;
2015-07-10 12:05:07 +03:00
if ( info . mhz )
vshPrint ( ctl , " %-20s %d MHz \n " , _ ( " CPU frequency: " ) , info . mhz ) ;
2012-07-23 10:37:50 +04:00
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 KiB \n " , _ ( " Memory size: " ) , info . memory ) ;
return true ;
}
2012-10-16 18:05:13 +04:00
/*
* " nodecpumap " command
*/
static const vshCmdInfo info_node_cpumap [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " node cpu map " )
} ,
{ . name = " desc " ,
. data = N_ ( " Displays the node's total number of CPUs, the number of "
" online CPUs and the list of online CPUs. " )
} ,
{ . name = NULL }
2012-10-16 18:05:13 +04:00
} ;
2014-06-05 15:16:00 +04:00
static const vshCmdOptDef opts_node_cpumap [ ] = {
{ . name = " pretty " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " return human readable output " )
} ,
{ . name = NULL }
} ;
2012-10-16 18:05:13 +04:00
static bool
2019-10-14 15:44:29 +03:00
cmdNodeCpuMap ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-10-16 18:05:13 +04:00
{
int cpu , cpunum ;
unsigned char * cpumap = NULL ;
unsigned int online ;
2014-06-05 15:16:00 +04:00
bool pretty = vshCommandOptBool ( cmd , " pretty " ) ;
2012-10-16 18:05:13 +04:00
bool ret = false ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-10-16 18:05:13 +04:00
2015-06-15 19:53:58 +03:00
cpunum = virNodeGetCPUMap ( priv - > conn , & cpumap , & online , 0 ) ;
2012-10-16 18:05:13 +04:00
if ( cpunum < 0 ) {
vshError ( ctl , " %s " , _ ( " Unable to get cpu map " ) ) ;
goto cleanup ;
}
vshPrint ( ctl , " %-15s %d \n " , _ ( " CPUs present: " ) , cpunum ) ;
vshPrint ( ctl , " %-15s %d \n " , _ ( " CPUs online: " ) , online ) ;
vshPrint ( ctl , " %-15s " , _ ( " CPU map: " ) ) ;
2014-06-05 15:16:00 +04:00
if ( pretty ) {
2017-08-23 10:05:41 +03:00
char * str = virBitmapDataFormat ( cpumap , VIR_CPU_MAPLEN ( cpunum ) ) ;
2014-06-05 15:16:00 +04:00
if ( ! str )
goto cleanup ;
vshPrint ( ctl , " %s " , str ) ;
VIR_FREE ( str ) ;
} else {
for ( cpu = 0 ; cpu < cpunum ; cpu + + )
vshPrint ( ctl , " %c " , VIR_CPU_USED ( cpumap , cpu ) ? ' y ' : ' - ' ) ;
}
2012-10-16 18:05:13 +04:00
vshPrint ( ctl , " \n " ) ;
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2012-10-16 18:05:13 +04:00
VIR_FREE ( cpumap ) ;
return ret ;
}
2012-07-23 10:37:50 +04:00
/*
* " nodecpustats " command
*/
static const vshCmdInfo info_nodecpustats [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " Prints cpu stats of the node. " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns cpu stats of the node, in nanoseconds. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static const vshCmdOptDef opts_node_cpustats [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " cpu " ,
. type = VSH_OT_INT ,
. help = N_ ( " prints specified cpu statistics only. " )
} ,
{ . name = " percent " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " prints by percentage during 1 second. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
2014-02-04 13:06:54 +04:00
typedef enum {
2015-06-15 19:53:58 +03:00
VIRSH_CPU_USER ,
VIRSH_CPU_SYSTEM ,
VIRSH_CPU_IDLE ,
VIRSH_CPU_IOWAIT ,
VIRSH_CPU_INTR ,
VIRSH_CPU_USAGE ,
VIRSH_CPU_LAST
} virshCPUStats ;
VIR_ENUM_DECL ( virshCPUStats ) ;
2019-03-16 21:20:32 +03:00
VIR_ENUM_IMPL ( virshCPUStats ,
VIRSH_CPU_LAST ,
2014-02-04 13:06:54 +04:00
VIR_NODE_CPU_STATS_USER ,
VIR_NODE_CPU_STATS_KERNEL ,
VIR_NODE_CPU_STATS_IDLE ,
VIR_NODE_CPU_STATS_IOWAIT ,
VIR_NODE_CPU_STATS_INTR ,
VIR_NODE_CPU_STATS_UTILIZATION ) ;
2015-06-15 19:53:58 +03:00
const char * virshCPUOutput [ ] = {
2014-02-24 22:08:39 +04:00
N_ ( " user: " ) ,
N_ ( " system: " ) ,
N_ ( " idle: " ) ,
N_ ( " iowait: " ) ,
N_ ( " intr: " ) ,
N_ ( " usage: " )
2014-02-04 13:06:54 +04:00
} ;
2012-07-23 10:37:50 +04:00
static bool
cmdNodeCpuStats ( vshControl * ctl , const vshCmd * cmd )
{
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i , j ;
2012-07-23 10:37:50 +04:00
bool flag_percent = vshCommandOptBool ( cmd , " percent " ) ;
int cpuNum = VIR_NODE_CPU_STATS_ALL_CPUS ;
virNodeCPUStatsPtr params ;
int nparams = 0 ;
bool ret = false ;
2015-06-15 19:53:58 +03:00
unsigned long long cpu_stats [ VIRSH_CPU_LAST ] = { 0 } ;
bool present [ VIRSH_CPU_LAST ] = { false } ;
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-02 12:17:29 +03:00
if ( vshCommandOptInt ( ctl , cmd , " cpu " , & cpuNum ) < 0 )
2012-07-23 10:37:50 +04:00
return false ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetCPUStats ( priv - > conn , cpuNum , NULL , & nparams , 0 ) ! = 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " ,
_ ( " Unable to get number of cpu stats " ) ) ;
return false ;
}
if ( nparams = = 0 ) {
/* nothing to output */
return true ;
}
memset ( cpu_stats , 0 , sizeof ( cpu_stats ) ) ;
params = vshCalloc ( ctl , nparams , sizeof ( * params ) ) ;
for ( i = 0 ; i < 2 ; i + + ) {
2015-06-15 19:53:58 +03:00
if ( virNodeGetCPUStats ( priv - > conn , cpuNum , params , & nparams , 0 ) ! = 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " Unable to get node cpu stats " ) ) ;
goto cleanup ;
}
for ( j = 0 ; j < nparams ; j + + ) {
2015-06-15 19:53:58 +03:00
int field = virshCPUStatsTypeFromString ( params [ j ] . field ) ;
2014-02-04 13:06:54 +04:00
if ( field < 0 )
continue ;
if ( i = = 0 ) {
cpu_stats [ field ] = params [ j ] . value ;
present [ field ] = true ;
} else if ( present [ field ] ) {
cpu_stats [ field ] = params [ j ] . value - cpu_stats [ field ] ;
2012-07-23 10:37:50 +04:00
}
}
2015-06-15 19:53:58 +03:00
if ( present [ VIRSH_CPU_USAGE ] | | ! flag_percent )
2012-07-23 10:37:50 +04:00
break ;
2014-02-04 13:06:54 +04:00
sleep ( 1 ) ;
2012-07-23 10:37:50 +04:00
}
if ( ! flag_percent ) {
2015-06-15 19:53:58 +03:00
for ( i = 0 ; i < VIRSH_CPU_USAGE ; i + + ) {
2014-02-04 13:06:54 +04:00
if ( present [ i ] ) {
2015-06-15 19:53:58 +03:00
vshPrint ( ctl , " %-15s %20llu \n " , _ ( virshCPUOutput [ i ] ) ,
2014-02-04 13:06:54 +04:00
cpu_stats [ i ] ) ;
}
2012-07-23 10:37:50 +04:00
}
} else {
2015-06-15 19:53:58 +03:00
if ( present [ VIRSH_CPU_USAGE ] ) {
vshPrint ( ctl , " %-15s %5.1llu%% \n " ,
_ ( " usage: " ) , cpu_stats [ VIRSH_CPU_USAGE ] ) ;
vshPrint ( ctl , " %-15s %5.1llu%% \n " ,
_ ( " idle: " ) , 100 - cpu_stats [ VIRSH_CPU_USAGE ] ) ;
2014-02-04 13:06:54 +04:00
} else {
double usage , total_time = 0 ;
2015-06-15 19:53:58 +03:00
for ( i = 0 ; i < VIRSH_CPU_USAGE ; i + + )
2014-02-04 13:06:54 +04:00
total_time + = cpu_stats [ i ] ;
2015-06-15 19:53:58 +03:00
usage = ( cpu_stats [ VIRSH_CPU_USER ] + cpu_stats [ VIRSH_CPU_SYSTEM ] )
/ total_time * 100 ;
2012-07-23 10:37:50 +04:00
vshPrint ( ctl , " %-15s %5.1lf%% \n " , _ ( " usage: " ) , usage ) ;
2015-06-15 19:53:58 +03:00
for ( i = 0 ; i < VIRSH_CPU_USAGE ; i + + ) {
2014-02-04 13:06:54 +04:00
if ( present [ i ] ) {
2015-06-15 19:53:58 +03:00
vshPrint ( ctl , " %-15s %5.1lf%% \n " , _ ( virshCPUOutput [ i ] ) ,
2014-02-04 13:06:54 +04:00
cpu_stats [ i ] / total_time * 100 ) ;
}
}
2012-07-23 10:37:50 +04:00
}
}
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2012-07-23 10:37:50 +04:00
VIR_FREE ( params ) ;
return ret ;
}
/*
* " nodememstats " command
*/
static const vshCmdInfo info_nodememstats [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " Prints memory stats of the node. " )
} ,
{ . name = " desc " ,
. data = N_ ( " Returns memory stats of the node, in kilobytes. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static const vshCmdOptDef opts_node_memstats [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " cell " ,
. type = VSH_OT_INT ,
. help = N_ ( " prints specified cell statistics only. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
cmdNodeMemStats ( vshControl * ctl , const vshCmd * cmd )
{
int nparams = 0 ;
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-07-23 10:37:50 +04:00
int cellNum = VIR_NODE_MEMORY_STATS_ALL_CELLS ;
virNodeMemoryStatsPtr params = NULL ;
bool ret = false ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-02 12:17:29 +03:00
if ( vshCommandOptInt ( ctl , cmd , " cell " , & cellNum ) < 0 )
2012-07-23 10:37:50 +04:00
return false ;
/* get the number of memory parameters */
2015-06-15 19:53:58 +03:00
if ( virNodeGetMemoryStats ( priv - > conn , cellNum , NULL , & nparams , 0 ) ! = 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " ,
_ ( " Unable to get number of memory stats " ) ) ;
goto cleanup ;
}
if ( nparams = = 0 ) {
/* nothing to output */
ret = true ;
goto cleanup ;
}
/* now go get all the memory parameters */
params = vshCalloc ( ctl , nparams , sizeof ( * params ) ) ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetMemoryStats ( priv - > conn , cellNum , params , & nparams , 0 ) ! = 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " Unable to get memory stats " ) ) ;
goto cleanup ;
}
for ( i = 0 ; i < nparams ; i + + )
vshPrint ( ctl , " %-7s: %20llu KiB \n " , params [ i ] . field , params [ i ] . value ) ;
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2012-07-23 10:37:50 +04:00
VIR_FREE ( params ) ;
return ret ;
}
/*
* " nodesuspend " command
*/
static const vshCmdInfo info_nodesuspend [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " suspend the host node for a given time duration " )
} ,
{ . name = " desc " ,
. data = N_ ( " Suspend the host node for a given time duration "
2014-01-22 09:56:47 +04:00
" and attempt to resume thereafter. " )
2013-02-07 19:25:10 +04:00
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static const vshCmdOptDef opts_node_suspend [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " target " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
2014-01-22 09:56:47 +04:00
. help = N_ ( " mem(Suspend-to-RAM), disk(Suspend-to-Disk), "
" hybrid(Hybrid-Suspend) " )
2013-01-14 18:18:32 +04:00
} ,
{ . name = " duration " ,
. type = VSH_OT_INT ,
. flags = VSH_OFLAG_REQ ,
. help = N_ ( " Suspend duration in seconds, at least 60 " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
cmdNodeSuspend ( vshControl * ctl , const vshCmd * cmd )
{
const char * target = NULL ;
unsigned int suspendTarget ;
long long duration ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2013-01-21 20:17:19 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " target " , & target ) < 0 )
2012-07-23 10:37:50 +04:00
return false ;
2015-06-02 12:17:29 +03:00
if ( vshCommandOptLongLong ( ctl , cmd , " duration " , & duration ) < 0 )
2012-07-23 10:37:50 +04:00
return false ;
2014-09-03 23:39:21 +04:00
if ( STREQ ( target , " mem " ) ) {
2012-07-23 10:37:50 +04:00
suspendTarget = VIR_NODE_SUSPEND_TARGET_MEM ;
2014-09-03 23:39:21 +04:00
} else if ( STREQ ( target , " disk " ) ) {
2012-07-23 10:37:50 +04:00
suspendTarget = VIR_NODE_SUSPEND_TARGET_DISK ;
2014-09-03 23:39:21 +04:00
} else if ( STREQ ( target , " hybrid " ) ) {
2012-07-23 10:37:50 +04:00
suspendTarget = VIR_NODE_SUSPEND_TARGET_HYBRID ;
2014-09-03 23:39:21 +04:00
} else {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " Invalid target " ) ) ;
return false ;
}
2012-11-30 22:43:40 +04:00
if ( duration < 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " Invalid duration " ) ) ;
return false ;
}
2015-06-15 19:53:58 +03:00
if ( virNodeSuspendForDuration ( priv - > conn , suspendTarget , duration , 0 ) < 0 ) {
2012-07-23 10:37:50 +04:00
vshError ( ctl , " %s " , _ ( " The host was not suspended " ) ) ;
return false ;
}
return true ;
}
/*
* " sysinfo " command
*/
static const vshCmdInfo info_sysinfo [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " print the hypervisor sysinfo " )
} ,
{ . name = " desc " ,
. data = N_ ( " output an XML string for the hypervisor sysinfo, if available " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdSysinfo ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
char * sysinfo ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
sysinfo = virConnectGetSysinfo ( priv - > conn , 0 ) ;
2012-07-23 10:37:50 +04:00
if ( sysinfo = = NULL ) {
vshError ( ctl , " %s " , _ ( " failed to get sysinfo " ) ) ;
return false ;
}
vshPrint ( ctl , " %s " , sysinfo ) ;
VIR_FREE ( sysinfo ) ;
return true ;
}
/*
* " hostname " command
*/
static const vshCmdInfo info_hostname [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " print the hypervisor hostname " )
} ,
{ . name = " desc " ,
. data = " "
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdHostname ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
char * hostname ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
hostname = virConnectGetHostname ( priv - > conn ) ;
2012-07-23 10:37:50 +04:00
if ( hostname = = NULL ) {
vshError ( ctl , " %s " , _ ( " failed to get hostname " ) ) ;
return false ;
}
2012-10-17 13:23:12 +04:00
vshPrint ( ctl , " %s \n " , hostname ) ;
2012-07-23 10:37:50 +04:00
VIR_FREE ( hostname ) ;
return true ;
}
/*
* " uri " command
*/
static const vshCmdInfo info_uri [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " print the hypervisor canonical URI " )
} ,
{ . name = " desc " ,
. data = " "
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdURI ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
char * uri ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
uri = virConnectGetURI ( priv - > conn ) ;
2012-07-23 10:37:50 +04:00
if ( uri = = NULL ) {
vshError ( ctl , " %s " , _ ( " failed to get URI " ) ) ;
return false ;
}
vshPrint ( ctl , " %s \n " , uri ) ;
VIR_FREE ( uri ) ;
return true ;
}
2018-04-30 15:47:54 +03:00
/* Extracts the CPU definition XML strings from a file which may contain either
* - just the CPU definitions ,
2018-05-05 00:46:55 +03:00
* - domain XMLs ,
* - capabilities XMLs , or
* - domain capabilities XMLs .
2018-04-30 15:47:54 +03:00
*
* Returns NULL terminated string list .
*/
static char * *
vshExtractCPUDefXMLs ( vshControl * ctl ,
const char * xmlFile )
{
char * * cpus = NULL ;
char * buffer = NULL ;
char * xmlStr = NULL ;
xmlDocPtr xml = NULL ;
xmlXPathContextPtr ctxt = NULL ;
xmlNodePtr * nodes = NULL ;
2018-11-22 18:28:56 +03:00
char * doc ;
2018-04-30 15:47:54 +03:00
size_t i ;
int n ;
if ( virFileReadAll ( xmlFile , VSH_MAX_XML_FILE , & buffer ) < 0 )
goto error ;
2018-11-22 18:28:56 +03:00
/* Strip possible XML declaration */
if ( STRPREFIX ( buffer , " <?xml " ) & & ( doc = strstr ( buffer , " ?> " ) ) )
doc + = 2 ;
else
doc = buffer ;
2019-10-22 16:26:14 +03:00
xmlStr = g_strdup_printf ( " <container>%s</container> " , doc ) ;
2018-04-30 15:47:54 +03:00
if ( ! ( xml = virXMLParseStringCtxt ( xmlStr , xmlFile , & ctxt ) ) )
goto error ;
n = virXPathNodeSet ( " /container/cpu| "
" /container/domain/cpu| "
2018-05-05 00:46:55 +03:00
" /container/capabilities/host/cpu| "
" /container/domainCapabilities/cpu/ "
" mode[@name='host-model' and @supported='yes'] " ,
2018-04-30 15:47:54 +03:00
ctxt , & nodes ) ;
if ( n < 0 )
goto error ;
if ( n = = 0 ) {
vshError ( ctl , _ ( " File '%s' does not contain any <cpu> element or "
2018-05-05 00:46:55 +03:00
" valid domain XML, host capabilities XML, or "
" domain capabilities XML " ) , xmlFile ) ;
2018-04-30 15:47:54 +03:00
goto error ;
}
cpus = vshCalloc ( ctl , n + 1 , sizeof ( const char * ) ) ;
for ( i = 0 ; i < n ; i + + ) {
2018-05-05 00:46:55 +03:00
/* If the user provided domain capabilities XML, we need to replace
* < mode . . . > element with < cpu > . */
if ( xmlStrEqual ( nodes [ i ] - > name , BAD_CAST " mode " ) ) {
xmlNodeSetName ( nodes [ i ] , ( const xmlChar * ) " cpu " ) ;
while ( nodes [ i ] - > properties ) {
if ( xmlRemoveProp ( nodes [ i ] - > properties ) < 0 ) {
vshError ( ctl ,
_ ( " Cannot extract CPU definition from domain "
" capabilities XML " ) ) ;
goto error ;
}
}
}
2018-04-30 15:47:54 +03:00
if ( ! ( cpus [ i ] = virXMLNodeToString ( xml , nodes [ i ] ) ) ) {
vshSaveLibvirtError ( ) ;
goto error ;
}
}
cleanup :
VIR_FREE ( buffer ) ;
VIR_FREE ( xmlStr ) ;
xmlFreeDoc ( xml ) ;
xmlXPathFreeContext ( ctxt ) ;
VIR_FREE ( nodes ) ;
return cpus ;
error :
2020-08-02 20:36:03 +03:00
g_strfreev ( cpus ) ;
2018-04-30 15:47:54 +03:00
goto cleanup ;
}
2018-04-26 11:35:51 +03:00
/*
* " cpu-compare " command
*/
static const vshCmdInfo info_cpu_compare [ ] = {
{ . name = " help " ,
. data = N_ ( " compare host CPU with a CPU described by an XML file " )
} ,
{ . name = " desc " ,
. data = N_ ( " compare CPU with host CPU " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_cpu_compare [ ] = {
VIRSH_COMMON_OPT_FILE ( N_ ( " file containing an XML CPU description " ) ) ,
{ . name = " error " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " report error if CPUs are incompatible " )
} ,
{ . name = NULL }
} ;
static bool
cmdCPUCompare ( vshControl * ctl , const vshCmd * cmd )
{
const char * from = NULL ;
bool ret = false ;
int result ;
2018-04-30 15:47:54 +03:00
char * * cpus = NULL ;
2018-04-26 11:35:51 +03:00
unsigned int flags = 0 ;
virshControlPtr priv = ctl - > privData ;
if ( vshCommandOptBool ( cmd , " error " ) )
flags | = VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE ;
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & from ) < 0 )
return false ;
2018-04-30 15:47:54 +03:00
if ( ! ( cpus = vshExtractCPUDefXMLs ( ctl , from ) ) )
2018-04-26 11:35:51 +03:00
return false ;
2018-04-30 15:47:54 +03:00
result = virConnectCompareCPU ( priv - > conn , cpus [ 0 ] , flags ) ;
2018-04-26 11:35:51 +03:00
switch ( result ) {
case VIR_CPU_COMPARE_INCOMPATIBLE :
vshPrint ( ctl , _ ( " CPU described in %s is incompatible with host CPU \n " ) ,
from ) ;
goto cleanup ;
break ;
case VIR_CPU_COMPARE_IDENTICAL :
vshPrint ( ctl , _ ( " CPU described in %s is identical to host CPU \n " ) ,
from ) ;
break ;
case VIR_CPU_COMPARE_SUPERSET :
vshPrint ( ctl , _ ( " Host CPU is a superset of CPU described in %s \n " ) ,
from ) ;
break ;
case VIR_CPU_COMPARE_ERROR :
default :
vshError ( ctl , _ ( " Failed to compare host CPU with %s " ) , from ) ;
goto cleanup ;
}
ret = true ;
cleanup :
2020-08-02 20:36:03 +03:00
g_strfreev ( cpus ) ;
2018-04-26 11:35:51 +03:00
return ret ;
}
/*
* " cpu-baseline " command
*/
static const vshCmdInfo info_cpu_baseline [ ] = {
{ . name = " help " ,
. data = N_ ( " compute baseline CPU " )
} ,
{ . name = " desc " ,
. data = N_ ( " Compute baseline CPU for a set of given CPUs. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_cpu_baseline [ ] = {
VIRSH_COMMON_OPT_FILE ( N_ ( " file containing XML CPU descriptions " ) ) ,
{ . name = " features " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " Show features that are part of the CPU model type " )
} ,
{ . name = " migratable " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " Do not include features that block migration " )
} ,
{ . name = NULL }
} ;
static bool
cmdCPUBaseline ( vshControl * ctl , const vshCmd * cmd )
{
const char * from = NULL ;
bool ret = false ;
char * result = NULL ;
char * * list = NULL ;
unsigned int flags = 0 ;
virshControlPtr priv = ctl - > privData ;
if ( vshCommandOptBool ( cmd , " features " ) )
flags | = VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES ;
if ( vshCommandOptBool ( cmd , " migratable " ) )
flags | = VIR_CONNECT_BASELINE_CPU_MIGRATABLE ;
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & from ) < 0 )
return false ;
2018-04-30 15:47:54 +03:00
if ( ! ( list = vshExtractCPUDefXMLs ( ctl , from ) ) )
2018-04-26 11:35:51 +03:00
return false ;
2018-04-30 15:47:54 +03:00
result = virConnectBaselineCPU ( priv - > conn , ( const char * * ) list ,
virStringListLength ( ( const char * * ) list ) ,
flags ) ;
2018-04-26 11:35:51 +03:00
if ( result ) {
vshPrint ( ctl , " %s " , result ) ;
ret = true ;
}
VIR_FREE ( result ) ;
2020-08-02 20:36:03 +03:00
g_strfreev ( list ) ;
2018-04-26 11:35:51 +03:00
return ret ;
}
2013-09-23 13:46:03 +04:00
/*
* " cpu-models " command
*/
static const vshCmdInfo info_cpu_models [ ] = {
{ . name = " help " ,
. data = N_ ( " CPU models " )
} ,
{ . name = " desc " ,
. data = N_ ( " Get the CPU models for an arch. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_cpu_models [ ] = {
{ . name = " arch " ,
. type = VSH_OT_DATA ,
. flags = VSH_OFLAG_REQ ,
. help = N_ ( " architecture " )
} ,
{ . name = NULL }
} ;
static bool
cmdCPUModelNames ( vshControl * ctl , const vshCmd * cmd )
{
char * * models ;
size_t i ;
int nmodels ;
const char * arch = NULL ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2013-09-23 13:46:03 +04:00
if ( vshCommandOptStringReq ( ctl , cmd , " arch " , & arch ) < 0 )
return false ;
2015-06-15 19:53:58 +03:00
nmodels = virConnectGetCPUModelNames ( priv - > conn , arch , & models , 0 ) ;
2013-09-23 13:46:03 +04:00
if ( nmodels < 0 ) {
vshError ( ctl , " %s " , _ ( " failed to get CPU model names " ) ) ;
return false ;
}
2016-06-14 12:12:49 +03:00
if ( nmodels = = 0 ) {
vshPrintExtra ( ctl , " %s \n " , _ ( " all CPU models are accepted " ) ) ;
} else {
for ( i = 0 ; i < nmodels ; i + + ) {
vshPrint ( ctl , " %s \n " , models [ i ] ) ;
VIR_FREE ( models [ i ] ) ;
}
2013-09-23 13:46:03 +04:00
}
VIR_FREE ( models ) ;
return true ;
}
2012-07-23 10:37:50 +04:00
/*
* " version " command
*/
static const vshCmdInfo info_version [ ] = {
2013-02-07 19:25:10 +04:00
{ . name = " help " ,
. data = N_ ( " show version " )
} ,
{ . name = " desc " ,
. data = N_ ( " Display the system version information. " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static const vshCmdOptDef opts_version [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " daemon " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " report daemon version too " )
} ,
{ . name = NULL }
2012-07-23 10:37:50 +04:00
} ;
static bool
2019-10-14 15:44:29 +03:00
cmdVersion ( vshControl * ctl , const vshCmd * cmd G_GNUC_UNUSED )
2012-07-23 10:37:50 +04:00
{
unsigned long hvVersion ;
const char * hvType ;
unsigned long libVersion ;
unsigned long includeVersion ;
unsigned long apiVersion ;
unsigned long daemonVersion ;
int ret ;
unsigned int major ;
unsigned int minor ;
unsigned int rel ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-07-23 10:37:50 +04:00
2015-06-15 19:53:58 +03:00
hvType = virConnectGetType ( priv - > conn ) ;
2012-07-23 10:37:50 +04:00
if ( hvType = = NULL ) {
vshError ( ctl , " %s " , _ ( " failed to get hypervisor type " ) ) ;
return false ;
}
includeVersion = LIBVIR_VERSION_NUMBER ;
major = includeVersion / 1000000 ;
includeVersion % = 1000000 ;
minor = includeVersion / 1000 ;
rel = includeVersion % 1000 ;
2012-06-22 17:16:44 +04:00
vshPrint ( ctl , _ ( " Compiled against library: libvirt %d.%d.%d \n " ) ,
2012-07-23 10:37:50 +04:00
major , minor , rel ) ;
ret = virGetVersion ( & libVersion , hvType , & apiVersion ) ;
if ( ret < 0 ) {
vshError ( ctl , " %s " , _ ( " failed to get the library version " ) ) ;
return false ;
}
major = libVersion / 1000000 ;
libVersion % = 1000000 ;
minor = libVersion / 1000 ;
rel = libVersion % 1000 ;
2012-06-22 17:16:44 +04:00
vshPrint ( ctl , _ ( " Using library: libvirt %d.%d.%d \n " ) ,
2012-07-23 10:37:50 +04:00
major , minor , rel ) ;
major = apiVersion / 1000000 ;
apiVersion % = 1000000 ;
minor = apiVersion / 1000 ;
rel = apiVersion % 1000 ;
vshPrint ( ctl , _ ( " Using API: %s %d.%d.%d \n " ) , hvType ,
major , minor , rel ) ;
2015-06-15 19:53:58 +03:00
ret = virConnectGetVersion ( priv - > conn , & hvVersion ) ;
2012-07-23 10:37:50 +04:00
if ( ret < 0 ) {
vshError ( ctl , " %s " , _ ( " failed to get the hypervisor version " ) ) ;
return false ;
}
if ( hvVersion = = 0 ) {
vshPrint ( ctl ,
_ ( " Cannot extract running %s hypervisor version \n " ) , hvType ) ;
} else {
major = hvVersion / 1000000 ;
hvVersion % = 1000000 ;
minor = hvVersion / 1000 ;
rel = hvVersion % 1000 ;
vshPrint ( ctl , _ ( " Running hypervisor: %s %d.%d.%d \n " ) ,
hvType , major , minor , rel ) ;
}
if ( vshCommandOptBool ( cmd , " daemon " ) ) {
2015-06-15 19:53:58 +03:00
ret = virConnectGetLibVersion ( priv - > conn , & daemonVersion ) ;
2012-07-23 10:37:50 +04:00
if ( ret < 0 ) {
vshError ( ctl , " %s " , _ ( " failed to get the daemon version " ) ) ;
} else {
major = daemonVersion / 1000000 ;
daemonVersion % = 1000000 ;
minor = daemonVersion / 1000 ;
rel = daemonVersion % 1000 ;
vshPrint ( ctl , _ ( " Running against daemon: %d.%d.%d \n " ) ,
major , minor , rel ) ;
}
}
return true ;
}
2012-07-23 11:19:04 +04:00
2012-09-14 18:42:18 +04:00
static const vshCmdInfo info_node_memory_tune [ ] = {
{ " help " , N_ ( " Get or set node memory parameters " ) } ,
2013-01-24 23:40:51 +04:00
{ " desc " , N_ ( " Get or set node memory parameters \n "
2012-09-14 18:42:18 +04:00
" To get the memory parameters, use following command: \n \n "
" virsh # node-memory-tune " ) } ,
{ NULL , NULL }
} ;
static const vshCmdOptDef opts_node_memory_tune [ ] = {
2013-01-14 18:18:32 +04:00
{ . name = " shm-pages-to-scan " ,
. type = VSH_OT_INT ,
. help = N_ ( " number of pages to scan before the shared memory service "
" goes to sleep " )
} ,
{ . name = " shm-sleep-millisecs " ,
. type = VSH_OT_INT ,
. help = N_ ( " number of millisecs the shared memory service should "
" sleep before next scan " )
} ,
{ . name = " shm-merge-across-nodes " ,
. type = VSH_OT_INT ,
. help = N_ ( " Specifies if pages from different numa nodes can be merged " )
} ,
{ . name = NULL }
2012-09-14 18:42:18 +04:00
} ;
static bool
cmdNodeMemoryTune ( vshControl * ctl , const vshCmd * cmd )
{
virTypedParameterPtr params = NULL ;
int nparams = 0 ;
2013-01-16 03:10:38 +04:00
int maxparams = 0 ;
2012-09-14 18:42:18 +04:00
unsigned int flags = 0 ;
2013-01-16 03:10:38 +04:00
unsigned int value ;
2012-09-14 18:42:18 +04:00
bool ret = false ;
2012-11-28 18:11:07 +04:00
int rc = - 1 ;
Convert 'int i' to 'size_t i' in tools/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2015-06-15 19:53:58 +03:00
virshControlPtr priv = ctl - > privData ;
2012-09-14 18:42:18 +04:00
2015-06-02 12:17:28 +03:00
if ( ( rc = vshCommandOptUInt ( ctl , cmd , " shm-pages-to-scan " , & value ) ) < 0 ) {
2013-01-16 03:10:38 +04:00
goto cleanup ;
2012-11-28 18:11:07 +04:00
} else if ( rc > 0 ) {
2013-01-16 03:10:38 +04:00
if ( virTypedParamsAddUInt ( & params , & nparams , & maxparams ,
VIR_NODE_MEMORY_SHARED_PAGES_TO_SCAN ,
value ) < 0 )
goto save_error ;
2012-09-14 18:42:18 +04:00
}
2015-06-02 12:17:28 +03:00
if ( ( rc = vshCommandOptUInt ( ctl , cmd , " shm-sleep-millisecs " , & value ) ) < 0 ) {
2013-01-16 03:10:38 +04:00
goto cleanup ;
2012-11-28 18:11:07 +04:00
} else if ( rc > 0 ) {
2013-01-16 03:10:38 +04:00
if ( virTypedParamsAddUInt ( & params , & nparams , & maxparams ,
VIR_NODE_MEMORY_SHARED_SLEEP_MILLISECS ,
value ) < 0 )
goto save_error ;
2012-09-14 18:42:18 +04:00
}
2015-06-02 12:17:28 +03:00
if ( ( rc = vshCommandOptUInt ( ctl , cmd , " shm-merge-across-nodes " , & value ) ) < 0 ) {
2013-01-16 03:10:38 +04:00
goto cleanup ;
2012-11-28 18:11:07 +04:00
} else if ( rc > 0 ) {
2013-01-16 03:10:38 +04:00
if ( virTypedParamsAddUInt ( & params , & nparams , & maxparams ,
VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES ,
value ) < 0 )
goto save_error ;
2012-11-28 18:11:07 +04:00
}
2012-10-12 12:25:42 +04:00
2012-09-14 18:42:18 +04:00
if ( nparams = = 0 ) {
/* Get the number of memory parameters */
2015-06-15 19:53:58 +03:00
if ( virNodeGetMemoryParameters ( priv - > conn , NULL , & nparams , flags ) ! = 0 ) {
2012-09-14 18:42:18 +04:00
vshError ( ctl , " %s " ,
_ ( " Unable to get number of memory parameters " ) ) ;
goto cleanup ;
}
if ( nparams = = 0 ) {
ret = true ;
goto cleanup ;
}
/* Now go get all the memory parameters */
params = vshCalloc ( ctl , nparams , sizeof ( * params ) ) ;
2015-06-15 19:53:58 +03:00
if ( virNodeGetMemoryParameters ( priv - > conn , params , & nparams , flags ) ! = 0 ) {
2012-09-14 18:42:18 +04:00
vshError ( ctl , " %s " , _ ( " Unable to get memory parameters " ) ) ;
goto cleanup ;
}
/* XXX: Need to sort the returned params once new parameter
* fields not of shared memory are added .
*/
vshPrint ( ctl , _ ( " Shared memory: \n " ) ) ;
for ( i = 0 ; i < nparams ; i + + ) {
char * str = vshGetTypedParamValue ( ctl , & params [ i ] ) ;
vshPrint ( ctl , " \t %-15s %s \n " , params [ i ] . field , str ) ;
VIR_FREE ( str ) ;
}
} else {
2015-06-15 19:53:58 +03:00
if ( virNodeSetMemoryParameters ( priv - > conn , params , nparams , flags ) ! = 0 )
2012-09-14 18:42:18 +04:00
goto error ;
}
2013-01-16 03:10:38 +04:00
ret = true ;
2014-03-25 10:53:59 +04:00
cleanup :
2013-01-16 03:10:38 +04:00
virTypedParamsFree ( params , nparams ) ;
2012-09-14 18:42:18 +04:00
return ret ;
2014-03-25 10:53:59 +04:00
save_error :
2013-01-16 03:10:38 +04:00
vshSaveLibvirtError ( ) ;
2014-03-25 10:53:59 +04:00
error :
2012-09-14 18:42:18 +04:00
vshError ( ctl , " %s " , _ ( " Unable to change memory parameters " ) ) ;
goto cleanup ;
}
2018-04-30 15:48:03 +03:00
/*
* " hypervisor-cpu-compare " command
*/
static const vshCmdInfo info_hypervisor_cpu_compare [ ] = {
{ . name = " help " ,
. data = N_ ( " compare a CPU with the CPU created by a hypervisor on the host " )
} ,
{ . name = " desc " ,
. data = N_ ( " compare CPU with hypervisor CPU " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_hypervisor_cpu_compare [ ] = {
VIRSH_COMMON_OPT_FILE ( N_ ( " file containing an XML CPU description " ) ) ,
{ . name = " virttype " ,
. type = VSH_OT_STRING ,
. help = N_ ( " virtualization type (/domain/@type) " ) ,
} ,
{ . name = " emulator " ,
. type = VSH_OT_STRING ,
. help = N_ ( " path to emulator binary (/domain/devices/emulator) " ) ,
} ,
{ . name = " arch " ,
. type = VSH_OT_STRING ,
. help = N_ ( " CPU architecture (/domain/os/type/@arch) " ) ,
} ,
{ . name = " machine " ,
. type = VSH_OT_STRING ,
. help = N_ ( " machine type (/domain/os/type/@machine) " ) ,
} ,
{ . name = " error " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " report error if CPUs are incompatible " )
} ,
{ . name = NULL }
} ;
static bool
cmdHypervisorCPUCompare ( vshControl * ctl ,
const vshCmd * cmd )
{
const char * from = NULL ;
const char * virttype = NULL ;
const char * emulator = NULL ;
const char * arch = NULL ;
const char * machine = NULL ;
bool ret = false ;
int result ;
char * * cpus = NULL ;
unsigned int flags = 0 ;
virshControlPtr priv = ctl - > privData ;
if ( vshCommandOptBool ( cmd , " error " ) )
flags | = VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE ;
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & from ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " virttype " , & virttype ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " emulator " , & emulator ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " arch " , & arch ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " machine " , & machine ) < 0 )
return false ;
if ( ! ( cpus = vshExtractCPUDefXMLs ( ctl , from ) ) )
return false ;
result = virConnectCompareHypervisorCPU ( priv - > conn , emulator , arch ,
machine , virttype , cpus [ 0 ] , flags ) ;
switch ( result ) {
case VIR_CPU_COMPARE_INCOMPATIBLE :
vshPrint ( ctl ,
_ ( " CPU described in %s is incompatible with the CPU provided "
" by hypervisor on the host \n " ) ,
from ) ;
goto cleanup ;
break ;
case VIR_CPU_COMPARE_IDENTICAL :
vshPrint ( ctl ,
_ ( " CPU described in %s is identical to the CPU provided by "
" hypervisor on the host \n " ) ,
from ) ;
break ;
case VIR_CPU_COMPARE_SUPERSET :
vshPrint ( ctl ,
_ ( " The CPU provided by hypervisor on the host is a superset "
" of CPU described in %s \n " ) ,
from ) ;
break ;
case VIR_CPU_COMPARE_ERROR :
default :
vshError ( ctl , _ ( " Failed to compare hypervisor CPU with %s " ) , from ) ;
goto cleanup ;
}
ret = true ;
cleanup :
2020-08-02 20:36:03 +03:00
g_strfreev ( cpus ) ;
2018-04-30 15:48:03 +03:00
return ret ;
}
2018-05-07 16:10:52 +03:00
/*
* " hypervisor-cpu-baseline " command
*/
static const vshCmdInfo info_hypervisor_cpu_baseline [ ] = {
{ . name = " help " ,
. data = N_ ( " compute baseline CPU usable by a specific hypervisor " )
} ,
{ . name = " desc " ,
. data = N_ ( " Compute baseline CPU for a set of given CPUs. The result "
" will be tailored to the specified hypervisor. " )
} ,
{ . name = NULL }
} ;
static const vshCmdOptDef opts_hypervisor_cpu_baseline [ ] = {
VIRSH_COMMON_OPT_FILE ( N_ ( " file containing XML CPU descriptions " ) ) ,
{ . name = " virttype " ,
. type = VSH_OT_STRING ,
. help = N_ ( " virtualization type (/domain/@type) " ) ,
} ,
{ . name = " emulator " ,
. type = VSH_OT_STRING ,
. help = N_ ( " path to emulator binary (/domain/devices/emulator) " ) ,
} ,
{ . name = " arch " ,
. type = VSH_OT_STRING ,
. help = N_ ( " CPU architecture (/domain/os/type/@arch) " ) ,
} ,
{ . name = " machine " ,
. type = VSH_OT_STRING ,
. help = N_ ( " machine type (/domain/os/type/@machine) " ) ,
} ,
{ . name = " features " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " Show features that are part of the CPU model type " )
} ,
{ . name = " migratable " ,
. type = VSH_OT_BOOL ,
. help = N_ ( " Do not include features that block migration " )
} ,
{ . name = NULL }
} ;
static bool
cmdHypervisorCPUBaseline ( vshControl * ctl ,
const vshCmd * cmd )
{
const char * from = NULL ;
const char * virttype = NULL ;
const char * emulator = NULL ;
const char * arch = NULL ;
const char * machine = NULL ;
bool ret = false ;
char * result = NULL ;
char * * list = NULL ;
unsigned int flags = 0 ;
virshControlPtr priv = ctl - > privData ;
if ( vshCommandOptBool ( cmd , " features " ) )
flags | = VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES ;
if ( vshCommandOptBool ( cmd , " migratable " ) )
flags | = VIR_CONNECT_BASELINE_CPU_MIGRATABLE ;
if ( vshCommandOptStringReq ( ctl , cmd , " file " , & from ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " virttype " , & virttype ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " emulator " , & emulator ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " arch " , & arch ) < 0 | |
vshCommandOptStringReq ( ctl , cmd , " machine " , & machine ) < 0 )
return false ;
if ( ! ( list = vshExtractCPUDefXMLs ( ctl , from ) ) )
return false ;
result = virConnectBaselineHypervisorCPU ( priv - > conn , emulator , arch ,
machine , virttype ,
( const char * * ) list ,
virStringListLength ( ( const char * * ) list ) ,
flags ) ;
if ( result ) {
vshPrint ( ctl , " %s " , result ) ;
ret = true ;
}
VIR_FREE ( result ) ;
2020-08-02 20:36:03 +03:00
g_strfreev ( list ) ;
2018-05-07 16:10:52 +03:00
return ret ;
}
2012-08-21 00:01:45 +04:00
const vshCmdDef hostAndHypervisorCmds [ ] = {
2014-09-17 17:53:42 +04:00
{ . name = " allocpages " ,
. handler = cmdAllocpages ,
. opts = opts_allocpages ,
2014-09-27 02:57:22 +04:00
. info = info_allocpages ,
2014-09-17 17:53:42 +04:00
. flags = 0
} ,
2013-02-07 19:25:10 +04:00
{ . name = " capabilities " ,
. handler = cmdCapabilities ,
. opts = NULL ,
. info = info_capabilities ,
. flags = 0
} ,
2018-04-26 11:35:51 +03:00
{ . name = " cpu-baseline " ,
. handler = cmdCPUBaseline ,
. opts = opts_cpu_baseline ,
. info = info_cpu_baseline ,
. flags = 0
} ,
{ . name = " cpu-compare " ,
. handler = cmdCPUCompare ,
. opts = opts_cpu_compare ,
. info = info_cpu_compare ,
. flags = 0
} ,
2013-09-23 13:46:03 +04:00
{ . name = " cpu-models " ,
. handler = cmdCPUModelNames ,
. opts = opts_cpu_models ,
. info = info_cpu_models ,
. flags = 0
} ,
2014-06-25 19:56:20 +04:00
{ . name = " domcapabilities " ,
. handler = cmdDomCapabilities ,
. opts = opts_domcapabilities ,
. info = info_domcapabilities ,
. flags = 0
} ,
2013-02-07 19:25:10 +04:00
{ . name = " freecell " ,
. handler = cmdFreecell ,
. opts = opts_freecell ,
. info = info_freecell ,
. flags = 0
} ,
2014-06-09 19:56:43 +04:00
{ . name = " freepages " ,
. handler = cmdFreepages ,
. opts = opts_freepages ,
. info = info_freepages ,
. flags = 0
} ,
2013-02-07 19:25:10 +04:00
{ . name = " hostname " ,
. handler = cmdHostname ,
. opts = NULL ,
. info = info_hostname ,
. flags = 0
} ,
2018-05-07 16:10:52 +03:00
{ . name = " hypervisor-cpu-baseline " ,
. handler = cmdHypervisorCPUBaseline ,
. opts = opts_hypervisor_cpu_baseline ,
. info = info_hypervisor_cpu_baseline ,
. flags = 0
} ,
2018-04-30 15:48:03 +03:00
{ . name = " hypervisor-cpu-compare " ,
. handler = cmdHypervisorCPUCompare ,
. opts = opts_hypervisor_cpu_compare ,
. info = info_hypervisor_cpu_compare ,
. flags = 0
} ,
2013-09-09 06:14:22 +04:00
{ . name = " maxvcpus " ,
. handler = cmdMaxvcpus ,
. opts = opts_maxvcpus ,
. info = info_maxvcpus ,
. flags = 0
} ,
2013-02-07 19:25:10 +04:00
{ . name = " node-memory-tune " ,
. handler = cmdNodeMemoryTune ,
. opts = opts_node_memory_tune ,
. info = info_node_memory_tune ,
. flags = 0
} ,
{ . name = " nodecpumap " ,
. handler = cmdNodeCpuMap ,
2014-06-05 15:16:00 +04:00
. opts = opts_node_cpumap ,
2013-02-07 19:25:10 +04:00
. info = info_node_cpumap ,
. flags = 0
} ,
{ . name = " nodecpustats " ,
. handler = cmdNodeCpuStats ,
. opts = opts_node_cpustats ,
. info = info_nodecpustats ,
. flags = 0
} ,
{ . name = " nodeinfo " ,
. handler = cmdNodeinfo ,
. opts = NULL ,
. info = info_nodeinfo ,
. flags = 0
} ,
{ . name = " nodememstats " ,
. handler = cmdNodeMemStats ,
. opts = opts_node_memstats ,
. info = info_nodememstats ,
. flags = 0
} ,
{ . name = " nodesuspend " ,
. handler = cmdNodeSuspend ,
. opts = opts_node_suspend ,
. info = info_nodesuspend ,
. flags = 0
} ,
{ . name = " sysinfo " ,
. handler = cmdSysinfo ,
. opts = NULL ,
. info = info_sysinfo ,
. flags = 0
} ,
{ . name = " uri " ,
. handler = cmdURI ,
. opts = NULL ,
. info = info_uri ,
. flags = 0
} ,
{ . name = " version " ,
. handler = cmdVersion ,
. opts = opts_version ,
. info = info_version ,
. flags = 0
} ,
{ . name = NULL }
2012-07-23 11:19:04 +04:00
} ;