1 /*
2 * virsh-completer-host.c: virsh completer callbacks related to host
3 *
4 * Copyright (C) 2019 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #include "virsh-completer-host.h"
24 #include "viralloc.h"
25 #include "virsh.h"
26 #include "virstring.h"
27 #include "virxml.h"
28 #include "virutil.h"
29 #include "virsh-host.h"
30
31 static char *
virshPagesizeNodeToString(xmlNodePtr node)32 virshPagesizeNodeToString(xmlNodePtr node)
33 {
34 g_autofree char *pagesize = NULL;
35 g_autofree char *unit = NULL;
36 unsigned long long byteval = 0;
37 const char *suffix = NULL;
38 double size = 0;
39 char *ret;
40
41 pagesize = virXMLPropString(node, "size");
42 unit = virXMLPropString(node, "unit");
43 if (virStrToLong_ull(pagesize, NULL, 10, &byteval) < 0)
44 return NULL;
45 if (virScaleInteger(&byteval, unit, 1024, UINT_MAX) < 0)
46 return NULL;
47 size = vshPrettyCapacity(byteval, &suffix);
48 ret = g_strdup_printf("%.0f%s", size, suffix);
49 return ret;
50 }
51
52 char **
virshAllocpagesPagesizeCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)53 virshAllocpagesPagesizeCompleter(vshControl *ctl,
54 const vshCmd *cmd G_GNUC_UNUSED,
55 unsigned int flags)
56 {
57 g_autoptr(xmlXPathContext) ctxt = NULL;
58 virshControl *priv = ctl->privData;
59 int npages = 0;
60 g_autofree xmlNodePtr *pages = NULL;
61 g_autoptr(xmlDoc) doc = NULL;
62 size_t i = 0;
63 const char *cellnum = NULL;
64 bool cellno = vshCommandOptBool(cmd, "cellno");
65 g_autofree char *path = NULL;
66 g_autofree char *cap_xml = NULL;
67 g_auto(GStrv) tmp = NULL;
68
69 virCheckFlags(0, NULL);
70
71 if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
72 return NULL;
73
74 if (!(cap_xml = virConnectGetCapabilities(priv->conn)))
75 return NULL;
76
77 if (!(doc = virXMLParseStringCtxt(cap_xml, _("capabilities"), &ctxt)))
78 return NULL;
79
80 if (cellno && vshCommandOptStringQuiet(ctl, cmd, "cellno", &cellnum) > 0) {
81 path = g_strdup_printf("/capabilities/host/topology/cells/cell[@id=\"%s\"]/pages",
82 cellnum);
83 } else {
84 path = g_strdup("/capabilities/host/cpu/pages");
85 }
86
87 npages = virXPathNodeSet(path, ctxt, &pages);
88 if (npages <= 0)
89 return NULL;
90
91 tmp = g_new0(char *, npages + 1);
92
93 for (i = 0; i < npages; i++) {
94 if (!(tmp[i] = virshPagesizeNodeToString(pages[i])))
95 return NULL;
96 }
97
98 return g_steal_pointer(&tmp);
99 }
100
101
102 char **
virshCellnoCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)103 virshCellnoCompleter(vshControl *ctl,
104 const vshCmd *cmd G_GNUC_UNUSED,
105 unsigned int flags)
106 {
107 g_autoptr(xmlXPathContext) ctxt = NULL;
108 virshControl *priv = ctl->privData;
109 int ncells = 0;
110 g_autofree xmlNodePtr *cells = NULL;
111 g_autoptr(xmlDoc) doc = NULL;
112 size_t i = 0;
113 g_autofree char *cap_xml = NULL;
114 g_auto(GStrv) tmp = NULL;
115
116 virCheckFlags(0, NULL);
117
118 if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
119 return NULL;
120
121 if (!(cap_xml = virConnectGetCapabilities(priv->conn)))
122 return NULL;
123
124 if (!(doc = virXMLParseStringCtxt(cap_xml, _("capabilities"), &ctxt)))
125 return NULL;
126
127 ncells = virXPathNodeSet("/capabilities/host/topology/cells/cell", ctxt, &cells);
128 if (ncells <= 0)
129 return NULL;
130
131 tmp = g_new0(char *, ncells + 1);
132
133 for (i = 0; i < ncells; i++) {
134 if (!(tmp[i] = virXMLPropString(cells[i], "id")))
135 return NULL;
136 }
137
138 return g_steal_pointer(&tmp);
139 }
140
141
142 char **
virshNodeCpuCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)143 virshNodeCpuCompleter(vshControl *ctl,
144 const vshCmd *cmd G_GNUC_UNUSED,
145 unsigned int flags)
146 {
147 virshControl *priv = ctl->privData;
148 g_auto(GStrv) tmp = NULL;
149 size_t i;
150 int cpunum;
151 size_t offset = 0;
152 unsigned int online;
153 g_autofree unsigned char *cpumap = NULL;
154
155 virCheckFlags(0, NULL);
156
157 if ((cpunum = virNodeGetCPUMap(priv->conn, &cpumap, &online, 0)) < 0)
158 return NULL;
159
160 tmp = g_new0(char *, online + 1);
161
162 for (i = 0; i < cpunum; i++) {
163 if (VIR_CPU_USED(cpumap, i) == 0)
164 continue;
165
166 tmp[offset++] = g_strdup_printf("%zu", i);
167 }
168
169 return g_steal_pointer(&tmp);
170 }
171
172
173 char **
virshNodeSuspendTargetCompleter(vshControl * ctl G_GNUC_UNUSED,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)174 virshNodeSuspendTargetCompleter(vshControl *ctl G_GNUC_UNUSED,
175 const vshCmd *cmd G_GNUC_UNUSED,
176 unsigned int flags)
177 {
178 char **ret = NULL;
179 size_t i;
180
181 virCheckFlags(0, NULL);
182
183 ret = g_new0(char *, VIR_NODE_SUSPEND_TARGET_LAST + 1);
184
185 for (i = 0; i < VIR_NODE_SUSPEND_TARGET_LAST; i++)
186 ret[i] = g_strdup(virshNodeSuspendTargetTypeToString(i));
187
188 return ret;
189 }
190