2019-07-14 13:24:38 +03:00
/*
* virsh - completer - host . c : virsh completer callbacks related to host
*
* Copyright ( C ) 2019 Red Hat , Inc .
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library . If not , see
* < http : //www.gnu.org/licenses/>.
*/
# include <config.h>
# include "virsh-completer-host.h"
# include "virsh.h"
# include "virstring.h"
# include "virxml.h"
# include "virutil.h"
2021-06-15 03:38:23 +03:00
# include "virsh-host.h"
2022-04-02 13:31:45 +03:00
# include "conf/domain_conf.h"
2022-04-02 13:31:46 +03:00
# include "virarch.h"
2019-07-14 13:24:38 +03:00
static char *
virshPagesizeNodeToString ( xmlNodePtr node )
{
2019-10-15 16:16:31 +03:00
g_autofree char * pagesize = NULL ;
g_autofree char * unit = NULL ;
2019-07-14 13:24:38 +03:00
unsigned long long byteval = 0 ;
const char * suffix = NULL ;
double size = 0 ;
char * ret ;
pagesize = virXMLPropString ( node , " size " ) ;
unit = virXMLPropString ( node , " unit " ) ;
if ( virStrToLong_ull ( pagesize , NULL , 10 , & byteval ) < 0 )
return NULL ;
2022-03-30 14:54:50 +03:00
if ( virScaleInteger ( & byteval , unit , 1024 , ULLONG_MAX ) < 0 )
2019-07-14 13:24:38 +03:00
return NULL ;
size = vshPrettyCapacity ( byteval , & suffix ) ;
2019-10-22 16:26:14 +03:00
ret = g_strdup_printf ( " %.0f%s " , size , suffix ) ;
2019-07-14 13:24:38 +03:00
return ret ;
}
char * *
virshAllocpagesPagesizeCompleter ( vshControl * ctl ,
2019-10-14 15:44:29 +03:00
const vshCmd * cmd G_GNUC_UNUSED ,
2019-07-14 13:24:38 +03:00
unsigned int flags )
{
2019-10-15 15:47:50 +03:00
g_autoptr ( xmlXPathContext ) ctxt = NULL ;
2021-03-11 10:16:13 +03:00
virshControl * priv = ctl - > privData ;
2020-08-03 00:30:17 +03:00
int npages = 0 ;
2019-10-15 16:16:31 +03:00
g_autofree xmlNodePtr * pages = NULL ;
2019-10-15 15:47:50 +03:00
g_autoptr ( xmlDoc ) doc = NULL ;
2019-07-14 13:24:38 +03:00
size_t i = 0 ;
const char * cellnum = NULL ;
bool cellno = vshCommandOptBool ( cmd , " cellno " ) ;
2019-10-15 16:16:31 +03:00
g_autofree char * path = NULL ;
g_autofree char * cap_xml = NULL ;
2020-12-01 11:21:32 +03:00
g_auto ( GStrv ) tmp = NULL ;
2019-07-14 13:24:38 +03:00
virCheckFlags ( 0 , NULL ) ;
if ( ! priv - > conn | | virConnectIsAlive ( priv - > conn ) < = 0 )
return NULL ;
if ( ! ( cap_xml = virConnectGetCapabilities ( priv - > conn ) ) )
return NULL ;
if ( ! ( doc = virXMLParseStringCtxt ( cap_xml , _ ( " capabilities " ) , & ctxt ) ) )
return NULL ;
if ( cellno & & vshCommandOptStringQuiet ( ctl , cmd , " cellno " , & cellnum ) > 0 ) {
2019-10-22 16:26:14 +03:00
path = g_strdup_printf ( " /capabilities/host/topology/cells/cell[@id= \" %s \" ]/pages " ,
cellnum ) ;
2019-07-14 13:24:38 +03:00
} else {
2019-10-22 16:26:14 +03:00
path = g_strdup ( " /capabilities/host/cpu/pages " ) ;
2019-07-14 13:24:38 +03:00
}
npages = virXPathNodeSet ( path , ctxt , & pages ) ;
if ( npages < = 0 )
return NULL ;
2020-09-14 17:24:44 +03:00
tmp = g_new0 ( char * , npages + 1 ) ;
2019-07-14 13:24:38 +03:00
for ( i = 0 ; i < npages ; i + + ) {
if ( ! ( tmp [ i ] = virshPagesizeNodeToString ( pages [ i ] ) ) )
return NULL ;
}
2019-10-17 11:10:10 +03:00
return g_steal_pointer ( & tmp ) ;
2019-07-14 13:24:38 +03:00
}
char * *
virshCellnoCompleter ( vshControl * ctl ,
2019-10-14 15:44:29 +03:00
const vshCmd * cmd G_GNUC_UNUSED ,
2019-07-14 13:24:38 +03:00
unsigned int flags )
{
2019-10-15 15:47:50 +03:00
g_autoptr ( xmlXPathContext ) ctxt = NULL ;
2021-03-11 10:16:13 +03:00
virshControl * priv = ctl - > privData ;
2020-08-03 00:30:17 +03:00
int ncells = 0 ;
2019-10-15 16:16:31 +03:00
g_autofree xmlNodePtr * cells = NULL ;
2019-10-15 15:47:50 +03:00
g_autoptr ( xmlDoc ) doc = NULL ;
2019-07-14 13:24:38 +03:00
size_t i = 0 ;
2019-10-15 16:16:31 +03:00
g_autofree char * cap_xml = NULL ;
2020-12-01 11:21:32 +03:00
g_auto ( GStrv ) tmp = NULL ;
2019-07-14 13:24:38 +03:00
virCheckFlags ( 0 , NULL ) ;
if ( ! priv - > conn | | virConnectIsAlive ( priv - > conn ) < = 0 )
return NULL ;
if ( ! ( cap_xml = virConnectGetCapabilities ( priv - > conn ) ) )
return NULL ;
if ( ! ( doc = virXMLParseStringCtxt ( cap_xml , _ ( " capabilities " ) , & ctxt ) ) )
return NULL ;
ncells = virXPathNodeSet ( " /capabilities/host/topology/cells/cell " , ctxt , & cells ) ;
if ( ncells < = 0 )
return NULL ;
2020-09-14 17:24:44 +03:00
tmp = g_new0 ( char * , ncells + 1 ) ;
2019-07-14 13:24:38 +03:00
for ( i = 0 ; i < ncells ; i + + ) {
if ( ! ( tmp [ i ] = virXMLPropString ( cells [ i ] , " id " ) ) )
return NULL ;
}
2019-10-17 11:10:10 +03:00
return g_steal_pointer ( & tmp ) ;
2019-07-14 13:24:38 +03:00
}
2020-11-10 12:50:53 +03:00
char * *
virshNodeCpuCompleter ( vshControl * ctl ,
const vshCmd * cmd G_GNUC_UNUSED ,
unsigned int flags )
{
2021-03-11 10:16:13 +03:00
virshControl * priv = ctl - > privData ;
2020-12-01 11:21:32 +03:00
g_auto ( GStrv ) tmp = NULL ;
2020-11-10 12:50:53 +03:00
size_t i ;
int cpunum ;
size_t offset = 0 ;
unsigned int online ;
g_autofree unsigned char * cpumap = NULL ;
virCheckFlags ( 0 , NULL ) ;
if ( ( cpunum = virNodeGetCPUMap ( priv - > conn , & cpumap , & online , 0 ) ) < 0 )
return NULL ;
tmp = g_new0 ( char * , online + 1 ) ;
for ( i = 0 ; i < cpunum ; i + + ) {
if ( VIR_CPU_USED ( cpumap , i ) = = 0 )
continue ;
tmp [ offset + + ] = g_strdup_printf ( " %zu " , i ) ;
}
return g_steal_pointer ( & tmp ) ;
}
2021-06-15 03:38:23 +03:00
char * *
virshNodeSuspendTargetCompleter ( vshControl * ctl G_GNUC_UNUSED ,
const vshCmd * cmd G_GNUC_UNUSED ,
unsigned int flags )
{
virCheckFlags ( 0 , NULL ) ;
2022-03-12 07:41:56 +03:00
return virshEnumComplete ( VIR_NODE_SUSPEND_TARGET_LAST ,
virshNodeSuspendTargetTypeToString ) ;
2021-06-15 03:38:23 +03:00
}
2022-04-02 13:31:45 +03:00
char * *
virshDomainVirtTypeCompleter ( vshControl * ctl G_GNUC_UNUSED ,
const vshCmd * cmd G_GNUC_UNUSED ,
unsigned int flags )
{
virCheckFlags ( 0 , NULL ) ;
return virshEnumComplete ( VIR_DOMAIN_VIRT_LAST ,
virDomainVirtTypeToString ) ;
}
2022-04-02 13:31:46 +03:00
char * *
virshArchCompleter ( vshControl * ctl G_GNUC_UNUSED ,
const vshCmd * cmd G_GNUC_UNUSED ,
unsigned int flags )
{
virCheckFlags ( 0 , NULL ) ;
return virshEnumComplete ( VIR_ARCH_LAST ,
( const char * ( * ) ( int ) ) virArchToString ) ;
}
2022-10-06 18:12:24 +03:00
char * *
virshCPUModelCompleter ( vshControl * ctl ,
const vshCmd * cmd ,
unsigned int flags )
{
virshControl * priv = ctl - > privData ;
const char * virttype = NULL ;
const char * emulator = NULL ;
const char * arch = NULL ;
const char * machine = NULL ;
g_autofree char * domcaps = NULL ;
g_autoptr ( xmlDoc ) xml = NULL ;
g_autoptr ( xmlXPathContext ) ctxt = NULL ;
g_autofree xmlNodePtr * nodes = NULL ;
g_auto ( GStrv ) models = NULL ;
int nmodels = 0 ;
size_t i ;
virCheckFlags ( 0 , NULL ) ;
if ( 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 NULL ;
if ( ! priv - > conn | | virConnectIsAlive ( priv - > conn ) < = 0 )
return NULL ;
if ( ! ( domcaps = virConnectGetDomainCapabilities ( priv - > conn , emulator , arch ,
machine , virttype , 0 ) ) )
return NULL ;
if ( ! ( xml = virXMLParseStringCtxt ( domcaps , _ ( " domain capabilities " ) , & ctxt ) ) )
return NULL ;
nmodels = virXPathNodeSet ( " /domainCapabilities/cpu/mode[@name='custom']/model " ,
ctxt , & nodes ) ;
if ( nmodels < = 0 )
return NULL ;
models = g_new0 ( char * , nmodels + 1 ) ;
for ( i = 0 ; i < nmodels ; i + + )
models [ i ] = virXMLNodeContentString ( nodes [ i ] ) ;
return g_steal_pointer ( & models ) ;
}