static bool virshConnectionUsability(vshControl *ctl, virConnectPtr conn) { if (!conn || virConnectIsAlive(conn) == 0) { vshError(ctl, "%s", _("no valid connection")); return false; } /* The connection is considered dead only if * virConnectIsAlive() successfuly says so. */ vshResetLibvirtError(); return true; }
static virshNetworkListPtr virshNetworkListCollect(vshControl *ctl, unsigned int flags) { virshNetworkListPtr list = vshMalloc(ctl, sizeof(*list)); size_t i; int ret; char **names = NULL; virNetworkPtr net; bool success = false; size_t deleted = 0; int persistent; int autostart; int nActiveNets = 0; int nInactiveNets = 0; int nAllNets = 0; virshControlPtr priv = ctl->privData; /* try the list with flags support (0.10.2 and later) */ if ((ret = virConnectListAllNetworks(priv->conn, &list->nets, flags)) >= 0) { list->nnets = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; if (last_error && last_error->code == VIR_ERR_INVALID_ARG) { /* try the new API again but mask non-guaranteed flags */ unsigned int newflags = flags & (VIR_CONNECT_LIST_NETWORKS_ACTIVE | VIR_CONNECT_LIST_NETWORKS_INACTIVE); vshResetLibvirtError(); if ((ret = virConnectListAllNetworks(priv->conn, &list->nets, newflags)) >= 0) { list->nnets = ret; goto filter; } } /* there was an error during the first or second call */ vshError(ctl, "%s", _("Failed to list networks")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); /* Get the number of active networks */ if (!VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) { if ((nActiveNets = virConnectNumOfNetworks(priv->conn)) < 0) { vshError(ctl, "%s", _("Failed to get the number of active networks")); goto cleanup; } } /* Get the number of inactive networks */ if (!VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_INACTIVE)) { if ((nInactiveNets = virConnectNumOfDefinedNetworks(priv->conn)) < 0) { vshError(ctl, "%s", _("Failed to get the number of inactive networks")); goto cleanup; } } nAllNets = nActiveNets + nInactiveNets; if (nAllNets == 0) return list; names = vshMalloc(ctl, sizeof(char *) * nAllNets); /* Retrieve a list of active network names */ if (!VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) { if (virConnectListNetworks(priv->conn, names, nActiveNets) < 0) { vshError(ctl, "%s", _("Failed to list active networks")); goto cleanup; } } /* Add the inactive networks to the end of the name list */ if (!VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) || VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) { if (virConnectListDefinedNetworks(priv->conn, &names[nActiveNets], nInactiveNets) < 0) { vshError(ctl, "%s", _("Failed to list inactive networks")); goto cleanup; } } list->nets = vshMalloc(ctl, sizeof(virNetworkPtr) * (nAllNets)); list->nnets = 0; /* get active networks */ for (i = 0; i < nActiveNets; i++) { if (!(net = virNetworkLookupByName(priv->conn, names[i]))) continue; list->nets[list->nnets++] = net; } /* get inactive networks */ for (i = 0; i < nInactiveNets; i++) { if (!(net = virNetworkLookupByName(priv->conn, names[i]))) continue; list->nets[list->nnets++] = net; } /* truncate networks that weren't found */ deleted = nAllNets - list->nnets; filter: /* filter list the list if the list was acquired by fallback means */ for (i = 0; i < list->nnets; i++) { net = list->nets[i]; /* persistence filter */ if (VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT)) { if ((persistent = virNetworkIsPersistent(net)) < 0) { vshError(ctl, "%s", _("Failed to get network persistence info")); goto cleanup; } if (!((VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT) && persistent) || (VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_TRANSIENT) && !persistent))) goto remove_entry; } /* autostart filter */ if (VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART)) { if (virNetworkGetAutostart(net, &autostart) < 0) { vshError(ctl, "%s", _("Failed to get network autostart state")); goto cleanup; } if (!((VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART) && autostart) || (VSH_MATCH(VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART) && !autostart))) goto remove_entry; } /* the pool matched all filters, it may stay */ continue; remove_entry: /* the pool has to be removed as it failed one of the filters */ virNetworkFree(list->nets[i]); list->nets[i] = NULL; deleted++; } finished: /* sort the list */ if (list->nets && list->nnets) qsort(list->nets, list->nnets, sizeof(*list->nets), virshNetworkSorter); /* truncate the list if filter simulation deleted entries */ if (deleted) VIR_SHRINK_N(list->nets, list->nnets, deleted); success = true; cleanup: for (i = 0; i < nAllNets; i++) VIR_FREE(names[i]); VIR_FREE(names); if (!success) { virshNetworkListFree(list); list = NULL; } return list; }
static virshSecretListPtr virshSecretListCollect(vshControl *ctl, unsigned int flags) { virshSecretListPtr list = vshMalloc(ctl, sizeof(*list)); size_t i; int ret; virSecretPtr secret; bool success = false; size_t deleted = 0; int nsecrets = 0; char **uuids = NULL; virshControlPtr priv = ctl->privData; /* try the list with flags support (0.10.2 and later) */ if ((ret = virConnectListAllSecrets(priv->conn, &list->secrets, flags)) >= 0) { list->nsecrets = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; /* there was an error during the call */ vshError(ctl, "%s", _("Failed to list node secrets")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); if (flags) { vshError(ctl, "%s", _("Filtering is not supported by this libvirt")); goto cleanup; } nsecrets = virConnectNumOfSecrets(priv->conn); if (nsecrets < 0) { vshError(ctl, "%s", _("Failed to count secrets")); goto cleanup; } if (nsecrets == 0) return list; uuids = vshMalloc(ctl, sizeof(char *) * nsecrets); nsecrets = virConnectListSecrets(priv->conn, uuids, nsecrets); if (nsecrets < 0) { vshError(ctl, "%s", _("Failed to list secrets")); goto cleanup; } list->secrets = vshMalloc(ctl, sizeof(virSecretPtr) * (nsecrets)); list->nsecrets = 0; /* get the secrets */ for (i = 0; i < nsecrets; i++) { if (!(secret = virSecretLookupByUUIDString(priv->conn, uuids[i]))) continue; list->secrets[list->nsecrets++] = secret; } /* truncate secrets that weren't found */ deleted = nsecrets - list->nsecrets; finished: /* sort the list */ if (list->secrets && list->nsecrets) qsort(list->secrets, list->nsecrets, sizeof(*list->secrets), virshSecretSorter); /* truncate the list for not found secret objects */ if (deleted) VIR_SHRINK_N(list->secrets, list->nsecrets, deleted); success = true; cleanup: if (nsecrets > 0) { for (i = 0; i < nsecrets; i++) VIR_FREE(uuids[i]); VIR_FREE(uuids); } if (!success) { virshSecretListFree(list); list = NULL; } return list; }
static vshInterfaceListPtr vshInterfaceListCollect(vshControl *ctl, unsigned int flags) { vshInterfaceListPtr list = vshMalloc(ctl, sizeof(*list)); int i; int ret; char **activeNames = NULL; char **inactiveNames = NULL; virInterfacePtr iface; bool success = false; size_t deleted = 0; int nActiveIfaces = 0; int nInactiveIfaces = 0; int nAllIfaces = 0; /* try the list with flags support (0.10.2 and later) */ if ((ret = virConnectListAllInterfaces(ctl->conn, &list->ifaces, flags)) >= 0) { list->nifaces = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; /* there was an error during the first or second call */ vshError(ctl, "%s", _("Failed to list interfaces")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); if (flags & VIR_CONNECT_LIST_INTERFACES_ACTIVE) { nActiveIfaces = virConnectNumOfInterfaces(ctl->conn); if (nActiveIfaces < 0) { vshError(ctl, "%s", _("Failed to list active interfaces")); goto cleanup; } if (nActiveIfaces) { activeNames = vshMalloc(ctl, sizeof(char *) * nActiveIfaces); if ((nActiveIfaces = virConnectListInterfaces(ctl->conn, activeNames, nActiveIfaces)) < 0) { vshError(ctl, "%s", _("Failed to list active interfaces")); goto cleanup; } } } if (flags & VIR_CONNECT_LIST_INTERFACES_INACTIVE) { nInactiveIfaces = virConnectNumOfDefinedInterfaces(ctl->conn); if (nInactiveIfaces < 0) { vshError(ctl, "%s", _("Failed to list inactive interfaces")); goto cleanup; } if (nInactiveIfaces) { inactiveNames = vshMalloc(ctl, sizeof(char *) * nInactiveIfaces); if ((nInactiveIfaces = virConnectListDefinedInterfaces(ctl->conn, inactiveNames, nInactiveIfaces)) < 0) { vshError(ctl, "%s", _("Failed to list inactive interfaces")); goto cleanup; } } } nAllIfaces = nActiveIfaces + nInactiveIfaces; if (nAllIfaces == 0) { VIR_FREE(activeNames); VIR_FREE(inactiveNames); return list; } list->ifaces = vshMalloc(ctl, sizeof(virInterfacePtr) * (nAllIfaces)); list->nifaces = 0; /* get active interfaces */ for (i = 0; i < nActiveIfaces; i++) { if (!(iface = virInterfaceLookupByName(ctl->conn, activeNames[i]))) { vshResetLibvirtError(); continue; } list->ifaces[list->nifaces++] = iface; } /* get inactive interfaces */ for (i = 0; i < nInactiveIfaces; i++) { if (!(iface = virInterfaceLookupByName(ctl->conn, inactiveNames[i]))) { vshResetLibvirtError(); continue; } list->ifaces[list->nifaces++] = iface; } /* truncate interfaces that weren't found */ deleted = nAllIfaces - list->nifaces; finished: /* sort the list */ if (list->ifaces && list->nifaces) qsort(list->ifaces, list->nifaces, sizeof(*list->ifaces), vshInterfaceSorter); /* truncate the list if filter simulation deleted entries */ if (deleted) VIR_SHRINK_N(list->ifaces, list->nifaces, deleted); success = true; cleanup: for (i = 0; i < nActiveIfaces; i++) VIR_FREE(activeNames[i]); for (i = 0; i < nInactiveIfaces; i++) VIR_FREE(inactiveNames[i]); VIR_FREE(activeNames); VIR_FREE(inactiveNames); if (!success) { vshInterfaceListFree(list); list = NULL; } return list; }
int virshRunConsole(vshControl *ctl, virDomainPtr dom, const char *dev_name, unsigned int flags) { virConsolePtr con = NULL; virshControlPtr priv = ctl->privData; int ret = -1; struct sigaction old_sigquit; struct sigaction old_sigterm; struct sigaction old_sigint; struct sigaction old_sighup; struct sigaction old_sigpipe; struct sigaction sighandler = {.sa_handler = virConsoleHandleSignal, .sa_flags = SA_SIGINFO }; sigemptyset(&sighandler.sa_mask); /* Put STDIN into raw mode so that stuff typed does not echo to the screen * (the TTY reads will result in it being echoed back already), and also * ensure Ctrl-C, etc is blocked, and misc other bits */ if (vshTTYMakeRaw(ctl, true) < 0) goto resettty; if (!(con = virConsoleNew())) goto resettty; virObjectLock(con); /* Trap all common signals so that we can safely restore the original * terminal settings on STDIN before the process exits - people don't like * being left with a messed up terminal ! */ sigaction(SIGQUIT, &sighandler, &old_sigquit); sigaction(SIGTERM, &sighandler, &old_sigterm); sigaction(SIGINT, &sighandler, &old_sigint); sigaction(SIGHUP, &sighandler, &old_sighup); sigaction(SIGPIPE, &sighandler, &old_sigpipe); con->escapeChar = virshGetEscapeChar(priv->escapeChar); con->st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con->st) goto cleanup; if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0) goto cleanup; virObjectRef(con); if ((con->stdinWatch = virEventAddHandle(STDIN_FILENO, VIR_EVENT_HANDLE_READABLE, virConsoleEventOnStdin, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if ((con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if (virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, virObjectFreeCallback) < 0) { virObjectUnref(con); goto cleanup; } while (!con->quit) { if (virCondWait(&con->cond, &con->parent.lock) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to wait on console condition")); goto cleanup; } } if (con->error.code == VIR_ERR_OK) ret = 0; cleanup: virConsoleShutdown(con); if (ret < 0) { vshResetLibvirtError(); virSetError(&con->error); vshSaveLibvirtHelperError(); } virObjectUnlock(con); virObjectUnref(con); /* Restore original signal handlers */ sigaction(SIGQUIT, &old_sigquit, NULL); sigaction(SIGTERM, &old_sigterm, NULL); sigaction(SIGINT, &old_sigint, NULL); sigaction(SIGHUP, &old_sighup, NULL); sigaction(SIGPIPE, &old_sigpipe, NULL); resettty: /* Put STDIN back into the (sane?) state we found it in before starting */ vshTTYRestore(ctl); return ret; }
static vshNodeDeviceListPtr vshNodeDeviceListCollect(vshControl *ctl, char **capnames, int ncapnames, unsigned int flags) { vshNodeDeviceListPtr list = vshMalloc(ctl, sizeof(*list)); int i; int ret; virNodeDevicePtr device; bool success = false; size_t deleted = 0; int ndevices = 0; char **names = NULL; /* try the list with flags support (0.10.2 and later) */ if ((ret = virConnectListAllNodeDevices(ctl->conn, &list->devices, flags)) >= 0) { list->ndevices = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; /* there was an error during the call */ vshError(ctl, "%s", _("Failed to list node devices")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); ndevices = virNodeNumOfDevices(ctl->conn, NULL, 0); if (ndevices < 0) { vshError(ctl, "%s", _("Failed to count node devices")); goto cleanup; } if (ndevices == 0) return list; names = vshMalloc(ctl, sizeof(char *) * ndevices); ndevices = virNodeListDevices(ctl->conn, NULL, names, ndevices, 0); if (ndevices < 0) { vshError(ctl, "%s", _("Failed to list node devices")); goto cleanup; } list->devices = vshMalloc(ctl, sizeof(virNodeDevicePtr) * (ndevices)); list->ndevices = 0; /* get the node devices */ for (i = 0; i < ndevices ; i++) { if (!(device = virNodeDeviceLookupByName(ctl->conn, names[i]))) continue; list->devices[list->ndevices++] = device; } /* truncate domains that weren't found */ deleted = ndevices - list->ndevices; if (!capnames) goto finished; /* filter the list if the list was acquired by fallback means */ for (i = 0; i < list->ndevices; i++) { char **caps = NULL; int ncaps = 0; bool match = false; device = list->devices[i]; if ((ncaps = virNodeDeviceNumOfCaps(device)) < 0) { vshError(ctl, "%s", _("Failed to get capability numbers " "of the device")); goto cleanup; } caps = vshMalloc(ctl, sizeof(char *) * ncaps); if ((ncaps = virNodeDeviceListCaps(device, caps, ncaps)) < 0) { vshError(ctl, "%s", _("Failed to get capability names of the device")); VIR_FREE(caps); goto cleanup; } /* Check if the device's capability matches with provied * capabilities. */ int j, k; for (j = 0; j < ncaps; j++) { for (k = 0; k < ncapnames; k++) { if (STREQ(caps[j], capnames[k])) { match = true; break; } } } VIR_FREE(caps); if (!match) goto remove_entry; /* the device matched all filters, it may stay */ continue; remove_entry: /* the device has to be removed as it failed one of the filters */ virNodeDeviceFree(list->devices[i]); list->devices[i] = NULL; deleted++; } finished: /* sort the list */ if (list->devices && list->ndevices) qsort(list->devices, list->ndevices, sizeof(*list->devices), vshNodeDeviceSorter); /* truncate the list if filter simulation deleted entries */ if (deleted) VIR_SHRINK_N(list->devices, list->ndevices, deleted); success = true; cleanup: for (i = 0; i < ndevices; i++) VIR_FREE(names[i]); VIR_FREE(names); if (!success) { vshNodeDeviceListFree(list); list = NULL; } return list; }
virStorageVolPtr vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, const char *pooloptname, const char **name, unsigned int flags) { virStorageVolPtr vol = NULL; virStoragePoolPtr pool = NULL; const char *n = NULL, *p = NULL; virCheckFlags(VSH_BYUUID | VSH_BYNAME, NULL); if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0) return NULL; if (pooloptname != NULL && vshCommandOptStringReq(ctl, cmd, pooloptname, &p) < 0) return NULL; if (p) { if (!(pool = vshCommandOptPoolBy(ctl, cmd, pooloptname, name, flags))) return NULL; if (virStoragePoolIsActive(pool) != 1) { vshError(ctl, _("pool '%s' is not active"), p); virStoragePoolFree(pool); return NULL; } } vshDebug(ctl, VSH_ERR_DEBUG, "%s: found option <%s>: %s\n", cmd->def->name, optname, n); if (name) *name = n; /* try it by name */ if (pool && (flags & VSH_BYNAME)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol name\n", cmd->def->name, optname); vol = virStorageVolLookupByName(pool, n); } /* try it by key */ if (!vol && (flags & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol key\n", cmd->def->name, optname); vol = virStorageVolLookupByKey(ctl->conn, n); } /* try it by path */ if (!vol && (flags & VSH_BYUUID)) { vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as vol path\n", cmd->def->name, optname); vol = virStorageVolLookupByPath(ctl->conn, n); } if (!vol) { if (pool || !pooloptname) vshError(ctl, _("failed to get vol '%s'"), n); else vshError(ctl, _("failed to get vol '%s', specifying --%s " "might help"), n, pooloptname); } /* If the pool was specified, then make sure that the returned * volume is from the given pool */ if (pool && vol) { virStoragePoolPtr volpool = NULL; if ((volpool = virStoragePoolLookupByVolume(vol))) { if (STRNEQ(virStoragePoolGetName(volpool), virStoragePoolGetName(pool))) { vshResetLibvirtError(); vshError(ctl, _("Requested volume '%s' is not in pool '%s'"), n, virStoragePoolGetName(pool)); virStorageVolFree(vol); vol = NULL; } virStoragePoolFree(volpool); } } if (pool) virStoragePoolFree(pool); return vol; }
static vshStorageVolListPtr vshStorageVolListCollect(vshControl *ctl, virStoragePoolPtr pool, unsigned int flags) { vshStorageVolListPtr list = vshMalloc(ctl, sizeof(*list)); size_t i; char **names = NULL; virStorageVolPtr vol = NULL; bool success = false; size_t deleted = 0; int nvols = 0; int ret = -1; /* try the list with flags support (0.10.2 and later) */ if ((ret = virStoragePoolListAllVolumes(pool, &list->vols, flags)) >= 0) { list->nvols = ret; goto finished; } /* check if the command is actually supported */ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) goto fallback; /* there was an error during the call */ vshError(ctl, "%s", _("Failed to list volumes")); goto cleanup; fallback: /* fall back to old method (0.10.1 and older) */ vshResetLibvirtError(); /* Determine the number of volumes in the pool */ if ((nvols = virStoragePoolNumOfVolumes(pool)) < 0) { vshError(ctl, "%s", _("Failed to list storage volumes")); goto cleanup; } if (nvols == 0) { success = true; return list; } /* Retrieve the list of volume names in the pool */ names = vshCalloc(ctl, nvols, sizeof(*names)); if ((nvols = virStoragePoolListVolumes(pool, names, nvols)) < 0) { vshError(ctl, "%s", _("Failed to list storage volumes")); goto cleanup; } list->vols = vshMalloc(ctl, sizeof(virStorageVolPtr) * (nvols)); list->nvols = 0; /* get the vols */ for (i = 0; i < nvols; i++) { if (!(vol = virStorageVolLookupByName(pool, names[i]))) continue; list->vols[list->nvols++] = vol; } /* truncate the list for not found vols */ deleted = nvols - list->nvols; finished: /* sort the list */ if (list->vols && list->nvols) qsort(list->vols, list->nvols, sizeof(*list->vols), vshStorageVolSorter); if (deleted) VIR_SHRINK_N(list->vols, list->nvols, deleted); success = true; cleanup: if (nvols > 0) for (i = 0; i < nvols; i++) VIR_FREE(names[i]); VIR_FREE(names); if (!success) { vshStorageVolListFree(list); list = NULL; } return list; }