qemu: tpm: do not update profile name for transient domains
[libvirt.git] / tools / virsh-util.c
blobab350f0326d408f43289460a5eafd125e1286d68
1 /*
2 * virsh-util.c: helpers for virsh
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
19 #include <config.h>
21 #include "virsh-util.h"
23 #include "virfile.h"
24 #include "virstring.h"
25 #include "virxml.h"
27 static virDomainPtr
28 virshLookupDomainInternal(vshControl *ctl,
29 const char *cmdname,
30 const char *name,
31 unsigned int flags)
33 virDomainPtr dom = NULL;
34 int id;
35 virshControl *priv = ctl->privData;
37 virCheckFlags(VIRSH_BYID | VIRSH_BYUUID | VIRSH_BYNAME, NULL);
39 /* try it by ID */
40 if (flags & VIRSH_BYID) {
41 if (virStrToLong_i(name, NULL, 10, &id) == 0 && id >= 0) {
42 vshDebug(ctl, VSH_ERR_DEBUG, "%s: <domain> looks like ID\n",
43 cmdname);
44 dom = virDomainLookupByID(priv->conn, id);
48 /* try it by UUID */
49 if (!dom && (flags & VIRSH_BYUUID) &&
50 strlen(name) == VIR_UUID_STRING_BUFLEN-1) {
51 vshDebug(ctl, VSH_ERR_DEBUG, "%s: <domain> trying as domain UUID\n",
52 cmdname);
53 dom = virDomainLookupByUUIDString(priv->conn, name);
56 /* try it by NAME */
57 if (!dom && (flags & VIRSH_BYNAME)) {
58 vshDebug(ctl, VSH_ERR_DEBUG, "%s: <domain> trying as domain NAME\n",
59 cmdname);
60 dom = virDomainLookupByName(priv->conn, name);
63 vshResetLibvirtError();
65 if (!dom)
66 vshError(ctl, _("failed to get domain '%1$s'"), name);
68 return dom;
72 virDomainPtr
73 virshLookupDomainBy(vshControl *ctl,
74 const char *name,
75 unsigned int flags)
77 return virshLookupDomainInternal(ctl, "unknown", name, flags);
81 virDomainPtr
82 virshCommandOptDomainBy(vshControl *ctl,
83 const vshCmd *cmd,
84 const char **name,
85 unsigned int flags)
87 const char *n = NULL;
88 const char *optname = "domain";
90 if (vshCommandOptString(ctl, cmd, optname, &n) < 0)
91 return NULL;
93 vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n",
94 cmd->def->name, optname, n);
96 if (name)
97 *name = n;
99 return virshLookupDomainInternal(ctl, cmd->def->name, n, flags);
103 virDomainPtr
104 virshCommandOptDomain(vshControl *ctl,
105 const vshCmd *cmd,
106 const char **name)
108 return virshCommandOptDomainBy(ctl, cmd, name,
109 VIRSH_BYID | VIRSH_BYUUID | VIRSH_BYNAME);
114 virshDomainState(vshControl *ctl,
115 virDomainPtr dom,
116 int *reason)
118 virDomainInfo info;
119 virshControl *priv = ctl->privData;
121 if (reason)
122 *reason = -1;
124 if (!priv->useGetInfo) {
125 int state;
126 if (virDomainGetState(dom, &state, reason, 0) < 0) {
127 if (virGetLastErrorCode() == VIR_ERR_NO_SUPPORT)
128 priv->useGetInfo = true;
129 else
130 return -1;
131 } else {
132 return state;
136 /* fall back to virDomainGetInfo if virDomainGetState is not supported */
137 if (virDomainGetInfo(dom, &info) < 0)
138 return -1;
139 return info.state;
144 virshStreamSink(virStreamPtr st G_GNUC_UNUSED,
145 const char *bytes,
146 size_t nbytes,
147 void *opaque)
149 virshStreamCallbackData *cbData = opaque;
151 return safewrite(cbData->fd, bytes, nbytes);
156 virshStreamSource(virStreamPtr st G_GNUC_UNUSED,
157 char *bytes,
158 size_t nbytes,
159 void *opaque)
161 virshStreamCallbackData *cbData = opaque;
162 int fd = cbData->fd;
164 return saferead(fd, bytes, nbytes);
169 virshStreamSourceSkip(virStreamPtr st G_GNUC_UNUSED,
170 long long offset,
171 void *opaque)
173 virshStreamCallbackData *cbData = opaque;
174 int fd = cbData->fd;
176 if (lseek(fd, offset, SEEK_CUR) == (off_t) -1)
177 return -1;
179 return 0;
184 virshStreamSkip(virStreamPtr st G_GNUC_UNUSED,
185 long long offset,
186 void *opaque)
188 virshStreamCallbackData *cbData = opaque;
189 off_t cur;
191 if (cbData->isBlock) {
192 g_autofree char * buf = NULL;
193 const size_t buflen = 1 * 1024 * 1024; /* 1MiB */
195 /* While for files it's enough to lseek() and ftruncate() to create
196 * a hole which would emulate zeroes on read(), for block devices
197 * we have to write zeroes to read() zeroes. And we have to write
198 * @got bytes of zeroes. Do that in smaller chunks though.*/
200 buf = g_new0(char, buflen);
202 while (offset) {
203 size_t count = MIN(offset, buflen);
204 ssize_t r;
206 if ((r = safewrite(cbData->fd, buf, count)) < 0)
207 return -1;
209 offset -= r;
211 } else {
212 if ((cur = lseek(cbData->fd, offset, SEEK_CUR)) == (off_t) -1)
213 return -1;
215 if (ftruncate(cbData->fd, cur) < 0)
216 return -1;
219 return 0;
224 virshStreamInData(virStreamPtr st G_GNUC_UNUSED,
225 int *inData,
226 long long *offset,
227 void *opaque)
229 virshStreamCallbackData *cbData = opaque;
230 vshControl *ctl = cbData->ctl;
231 int fd = cbData->fd;
233 if (cbData->isBlock) {
234 /* Block devices are always in data section by definition. The
235 * @sectionLen is slightly more tricky. While we could try and get
236 * how much bytes is there left until EOF, we can pretend there is
237 * always X bytes left and let the saferead() below hit EOF (which
238 * is then handled gracefully anyway). Worst case scenario, this
239 * branch is called more than once.
240 * X was chosen to be 1MiB but it has ho special meaning. */
241 *inData = 1;
242 *offset = 1 * 1024 * 1024;
243 } else {
244 if (virFileInData(fd, inData, offset) < 0) {
245 vshError(ctl, "%s", _("Unable to get current position in stream"));
246 return -1;
250 return 0;
254 void
255 virshDomainFree(virDomainPtr dom)
257 if (!dom)
258 return;
260 vshSaveLibvirtHelperError();
261 virDomainFree(dom); /* sc_prohibit_obj_free_apis_in_virsh */
265 void
266 virshDomainCheckpointFree(virDomainCheckpointPtr chk)
268 if (!chk)
269 return;
271 vshSaveLibvirtHelperError();
272 virDomainCheckpointFree(chk); /* sc_prohibit_obj_free_apis_in_virsh */
276 void
277 virshDomainSnapshotFree(virDomainSnapshotPtr snap)
279 if (!snap)
280 return;
282 vshSaveLibvirtHelperError();
283 virDomainSnapshotFree(snap); /* sc_prohibit_obj_free_apis_in_virsh */
287 void
288 virshInterfaceFree(virInterfacePtr iface)
290 if (!iface)
291 return;
293 vshSaveLibvirtHelperError();
294 virInterfaceFree(iface); /* sc_prohibit_obj_free_apis_in_virsh */
298 void
299 virshNetworkFree(virNetworkPtr network)
301 if (!network)
302 return;
304 vshSaveLibvirtHelperError();
305 virNetworkFree(network); /* sc_prohibit_obj_free_apis_in_virsh */
309 void
310 virshNodeDeviceFree(virNodeDevicePtr device)
312 if (!device)
313 return;
315 vshSaveLibvirtHelperError();
316 virNodeDeviceFree(device); /* sc_prohibit_obj_free_apis_in_virsh */
320 void
321 virshNWFilterFree(virNWFilterPtr nwfilter)
323 if (!nwfilter)
324 return;
326 vshSaveLibvirtHelperError();
327 virNWFilterFree(nwfilter); /* sc_prohibit_obj_free_apis_in_virsh */
331 void
332 virshSecretFree(virSecretPtr secret)
334 if (!secret)
335 return;
337 vshSaveLibvirtHelperError();
338 virSecretFree(secret); /* sc_prohibit_obj_free_apis_in_virsh */
342 void
343 virshStoragePoolFree(virStoragePoolPtr pool)
345 if (!pool)
346 return;
348 vshSaveLibvirtHelperError();
349 virStoragePoolFree(pool); /* sc_prohibit_obj_free_apis_in_virsh */
353 void
354 virshStorageVolFree(virStorageVolPtr vol)
356 if (!vol)
357 return;
359 vshSaveLibvirtHelperError();
360 virStorageVolFree(vol); /* sc_prohibit_obj_free_apis_in_virsh */
365 void
366 virshStreamFree(virStreamPtr stream)
368 if (!stream)
369 return;
371 vshSaveLibvirtHelperError();
372 virStreamFree(stream); /* sc_prohibit_obj_free_apis_in_virsh */
377 virshDomainGetXMLFromDom(vshControl *ctl,
378 virDomainPtr dom,
379 unsigned int flags,
380 xmlDocPtr *xml,
381 xmlXPathContextPtr *ctxt)
383 g_autofree char *desc = NULL;
385 if (!(desc = virDomainGetXMLDesc(dom, flags))) {
386 vshError(ctl, _("Failed to get domain description xml"));
387 return -1;
390 *xml = virXMLParseStringCtxt(desc, _("(domain_definition)"), ctxt);
392 if (!(*xml)) {
393 vshError(ctl, _("Failed to parse domain description xml"));
394 return -1;
397 return 0;
402 virshNetworkGetXMLFromNet(vshControl *ctl,
403 virNetworkPtr net,
404 unsigned int flags,
405 xmlDocPtr *xml,
406 xmlXPathContextPtr *ctxt)
408 g_autofree char *desc = NULL;
410 if (!(desc = virNetworkGetXMLDesc(net, flags))) {
411 vshError(ctl, _("Failed to get network description xml"));
412 return -1;
415 *xml = virXMLParseStringCtxt(desc, _("(network_definition)"), ctxt);
417 if (!(*xml)) {
418 vshError(ctl, _("Failed to parse network description xml"));
419 return -1;
422 return 0;
427 virshDomainGetXML(vshControl *ctl,
428 const vshCmd *cmd,
429 unsigned int flags,
430 xmlDocPtr *xml,
431 xmlXPathContextPtr *ctxt)
433 virDomainPtr dom;
434 int ret;
436 if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
437 return -1;
439 ret = virshDomainGetXMLFromDom(ctl, dom, flags, xml, ctxt);
441 virshDomainFree(dom);
443 return ret;
447 VIR_ENUM_IMPL(virshDomainBlockJob,
448 VIR_DOMAIN_BLOCK_JOB_TYPE_LAST,
449 N_("Unknown job"),
450 N_("Block Pull"),
451 N_("Block Copy"),
452 N_("Block Commit"),
453 N_("Active Block Commit"),
454 N_("Backup"),
458 const char *
459 virshDomainBlockJobToString(int type)
461 const char *str = virshDomainBlockJobTypeToString(type);
462 return str ? _(str) : _("Unknown job");
465 bool
466 virshDumpXML(vshControl *ctl,
467 const char *xml,
468 const char *url,
469 const char *xpath,
470 bool wrap)
472 g_autoptr(xmlDoc) doc = NULL;
473 g_autoptr(xmlXPathContext) ctxt = NULL;
474 g_autofree xmlNodePtr *nodes = NULL;
475 int nnodes = 0;
476 size_t i;
478 if (xpath == NULL) {
479 vshPrint(ctl, "%s", xml);
480 return true;
483 doc = virXMLParseStringCtxtWithIndent(xml, url, &ctxt);
484 if (!doc)
485 return false;
487 if ((nnodes = virXPathNodeSet(xpath, ctxt, &nodes)) < 0) {
488 return false;
491 if (wrap) {
492 g_autoptr(xmlDoc) newdoc = xmlNewDoc((xmlChar *)"1.0");
493 xmlNodePtr newroot = xmlNewNode(NULL, (xmlChar *)"nodes");
494 g_autofree char *xmlbit = NULL;
496 xmlDocSetRootElement(newdoc, newroot);
498 for (i = 0; i < nnodes; i++) {
499 g_autoptr(xmlNode) copy = xmlDocCopyNode(nodes[i], newdoc, 1);
500 if (!xmlAddChild(newroot, copy))
501 return false;
503 copy = NULL;
506 xmlbit = virXMLNodeToString(doc, newroot);
507 vshPrint(ctl, "%s\n", xmlbit);
508 } else {
509 for (i = 0; i < nnodes; i++) {
510 g_autofree char *xmlbit = virXMLNodeToString(doc, nodes[i]);
511 vshPrint(ctl, "%s\n", xmlbit);
515 return true;