This splits commands of storage pool group into virsh-pool.c, The helpers not for common use are moved too. Standard copyright is added for the new file. * tools/virsh.c: Remove commands for storage storage pool and a few helpers. (vshCommandOptVol, vshCommandOptVolBy). * tools/virsh-pool.c: New file, filled with commands of storage pool group and its helpers. --- tools/virsh-pool.c | 1415 +++++++++++++++++++++++++++++++++++++++++++ tools/virsh.c | 1690 +++++----------------------------------------------- 2 files changed, 1556 insertions(+), 1549 deletions(-) create mode 100644 tools/virsh-pool.c diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c new file mode 100644 index 0000000..6a1208f --- /dev/null +++ b/tools/virsh-pool.c @@ -0,0 +1,1415 @@ +/* + * virsh-pool.c: Commands to manage storage pool + * + * Copyright (C) 2005, 2007-2012 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/>. + * + * Daniel Veillard <veillard@xxxxxxxxxx> + * Karel Zak <kzak@xxxxxxxxxx> + * Daniel P. Berrange <berrange@xxxxxxxxxx> + * + */ + +/* default is lookup by Name and UUID */ +#define vshCommandOptPool(_ctl, _cmd, _optname, _name) \ + vshCommandOptPoolBy(_ctl, _cmd, _optname, _name, \ + VSH_BYUUID|VSH_BYNAME) + +static virStoragePoolPtr +vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, + const char **name, int flag) +{ + virStoragePoolPtr pool = NULL; + const char *n = NULL; + + if (vshCommandOptString(cmd, optname, &n) <= 0) + return NULL; + + vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", + cmd->def->name, optname, n); + + if (name) + *name = n; + + /* try it by UUID */ + if ((flag & VSH_BYUUID) && strlen(n) == VIR_UUID_STRING_BUFLEN-1) { + vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool UUID\n", + cmd->def->name, optname); + pool = virStoragePoolLookupByUUIDString(ctl->conn, n); + } + /* try it by NAME */ + if (pool == NULL && (flag & VSH_BYNAME)) { + vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool NAME\n", + cmd->def->name, optname); + pool = virStoragePoolLookupByName(ctl->conn, n); + } + + if (!pool) + vshError(ctl, _("failed to get pool '%s'"), n); + + return pool; +} + +/* + * "pool-autostart" command + */ +static const vshCmdInfo info_pool_autostart[] = { + {"help", N_("autostart a pool")}, + {"desc", + N_("Configure a pool to be automatically started at boot.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_autostart[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {"disable", VSH_OT_BOOL, 0, N_("disable autostarting")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolAutostart(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + const char *name; + int autostart; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + autostart = !vshCommandOptBool(cmd, "disable"); + + if (virStoragePoolSetAutostart(pool, autostart) < 0) { + if (autostart) + vshError(ctl, _("failed to mark pool %s as autostarted"), name); + else + vshError(ctl, _("failed to unmark pool %s as autostarted"), name); + virStoragePoolFree(pool); + return false; + } + + if (autostart) + vshPrint(ctl, _("Pool %s marked as autostarted\n"), name); + else + vshPrint(ctl, _("Pool %s unmarked as autostarted\n"), name); + + virStoragePoolFree(pool); + return true; +} + +/* + * "pool-create" command + */ +static const vshCmdInfo info_pool_create[] = { + {"help", N_("create a pool from an XML file")}, + {"desc", N_("Create a pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_create[] = { + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, + N_("file containing an XML pool description")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + const char *from = NULL; + bool ret = true; + char *buffer; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (vshCommandOptString(cmd, "file", &from) <= 0) + return false; + + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) + return false; + + pool = virStoragePoolCreateXML(ctl->conn, buffer, 0); + VIR_FREE(buffer); + + if (pool != NULL) { + vshPrint(ctl, _("Pool %s created from %s\n"), + virStoragePoolGetName(pool), from); + virStoragePoolFree(pool); + } else { + vshError(ctl, _("Failed to create pool from %s"), from); + ret = false; + } + return ret; +} + +/* + * XML Building helper for pool-define-as and pool-create-as + */ +static const vshCmdOptDef opts_pool_X_as[] = { + {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the pool")}, + {"print-xml", VSH_OT_BOOL, 0, N_("print XML document, but don't define/create")}, + {"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("type of the pool")}, + {"source-host", VSH_OT_DATA, 0, N_("source-host for underlying storage")}, + {"source-path", VSH_OT_DATA, 0, N_("source path for underlying storage")}, + {"source-dev", VSH_OT_DATA, 0, N_("source device for underlying storage")}, + {"source-name", VSH_OT_DATA, 0, N_("source name for underlying storage")}, + {"target", VSH_OT_DATA, 0, N_("target for underlying storage")}, + {"source-format", VSH_OT_STRING, 0, N_("format for underlying storage")}, + {NULL, 0, 0, NULL} +}; + +static int buildPoolXML(const vshCmd *cmd, const char **retname, char **xml) { + + const char *name = NULL, *type = NULL, *srcHost = NULL, *srcPath = NULL, + *srcDev = NULL, *srcName = NULL, *srcFormat = NULL, *target = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (vshCommandOptString(cmd, "name", &name) <= 0) + goto cleanup; + if (vshCommandOptString(cmd, "type", &type) <= 0) + goto cleanup; + + if (vshCommandOptString(cmd, "source-host", &srcHost) < 0 || + vshCommandOptString(cmd, "source-path", &srcPath) < 0 || + vshCommandOptString(cmd, "source-dev", &srcDev) < 0 || + vshCommandOptString(cmd, "source-name", &srcName) < 0 || + vshCommandOptString(cmd, "source-format", &srcFormat) < 0 || + vshCommandOptString(cmd, "target", &target) < 0) { + vshError(NULL, "%s", _("missing argument")); + goto cleanup; + } + + virBufferAsprintf(&buf, "<pool type='%s'>\n", type); + virBufferAsprintf(&buf, " <name>%s</name>\n", name); + if (srcHost || srcPath || srcDev || srcFormat || srcName) { + virBufferAddLit(&buf, " <source>\n"); + + if (srcHost) + virBufferAsprintf(&buf, " <host name='%s'/>\n", srcHost); + if (srcPath) + virBufferAsprintf(&buf, " <dir path='%s'/>\n", srcPath); + if (srcDev) + virBufferAsprintf(&buf, " <device path='%s'/>\n", srcDev); + if (srcFormat) + virBufferAsprintf(&buf, " <format type='%s'/>\n", srcFormat); + if (srcName) + virBufferAsprintf(&buf, " <name>%s</name>\n", srcName); + + virBufferAddLit(&buf, " </source>\n"); + } + if (target) { + virBufferAddLit(&buf, " <target>\n"); + virBufferAsprintf(&buf, " <path>%s</path>\n", target); + virBufferAddLit(&buf, " </target>\n"); + } + virBufferAddLit(&buf, "</pool>\n"); + + if (virBufferError(&buf)) { + vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); + return false; + } + + *xml = virBufferContentAndReset(&buf); + *retname = name; + return true; + +cleanup: + virBufferFreeAndReset(&buf); + return false; +} + +/* + * "pool-create-as" command + */ +static const vshCmdInfo info_pool_create_as[] = { + {"help", N_("create a pool from a set of args")}, + {"desc", N_("Create a pool.")}, + {NULL, NULL} +}; + +static bool +cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + const char *name; + char *xml; + bool printXML = vshCommandOptBool(cmd, "print-xml"); + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!buildPoolXML(cmd, &name, &xml)) + return false; + + if (printXML) { + vshPrint(ctl, "%s", xml); + VIR_FREE(xml); + } else { + pool = virStoragePoolCreateXML(ctl->conn, xml, 0); + VIR_FREE(xml); + + if (pool != NULL) { + vshPrint(ctl, _("Pool %s created\n"), name); + virStoragePoolFree(pool); + } else { + vshError(ctl, _("Failed to create pool %s"), name); + return false; + } + } + return true; +} + +/* + * "pool-define" command + */ +static const vshCmdInfo info_pool_define[] = { + {"help", N_("define (but don't start) a pool from an XML file")}, + {"desc", N_("Define a pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_define[] = { + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containing an XML pool description")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDefine(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + const char *from = NULL; + bool ret = true; + char *buffer; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (vshCommandOptString(cmd, "file", &from) <= 0) + return false; + + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) + return false; + + pool = virStoragePoolDefineXML(ctl->conn, buffer, 0); + VIR_FREE(buffer); + + if (pool != NULL) { + vshPrint(ctl, _("Pool %s defined from %s\n"), + virStoragePoolGetName(pool), from); + virStoragePoolFree(pool); + } else { + vshError(ctl, _("Failed to define pool from %s"), from); + ret = false; + } + return ret; +} + +/* + * "pool-define-as" command + */ +static const vshCmdInfo info_pool_define_as[] = { + {"help", N_("define a pool from a set of args")}, + {"desc", N_("Define a pool.")}, + {NULL, NULL} +}; + +static bool +cmdPoolDefineAs(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + const char *name; + char *xml; + bool printXML = vshCommandOptBool(cmd, "print-xml"); + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!buildPoolXML(cmd, &name, &xml)) + return false; + + if (printXML) { + vshPrint(ctl, "%s", xml); + VIR_FREE(xml); + } else { + pool = virStoragePoolDefineXML(ctl->conn, xml, 0); + VIR_FREE(xml); + + if (pool != NULL) { + vshPrint(ctl, _("Pool %s defined\n"), name); + virStoragePoolFree(pool); + } else { + vshError(ctl, _("Failed to define pool %s"), name); + return false; + } + } + return true; +} + +/* + * "pool-build" command + */ +static const vshCmdInfo info_pool_build[] = { + {"help", N_("build a pool")}, + {"desc", N_("Build a given pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_build[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {"no-overwrite", VSH_OT_BOOL, 0, N_("do not overwrite an existing pool of this type")}, + {"overwrite", VSH_OT_BOOL, 0, N_("overwrite any existing data")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name; + unsigned int flags = 0; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (vshCommandOptBool(cmd, "no-overwrite")) { + flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; + } + + if (vshCommandOptBool(cmd, "overwrite")) { + flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; + } + + if (virStoragePoolBuild(pool, flags) == 0) { + vshPrint(ctl, _("Pool %s built\n"), name); + } else { + vshError(ctl, _("Failed to build pool %s"), name); + ret = false; + } + + virStoragePoolFree(pool); + + return ret; +} + +/* + * "pool-destroy" command + */ +static const vshCmdInfo info_pool_destroy[] = { + {"help", N_("destroy (stop) a pool")}, + {"desc", + N_("Forcefully stop a given pool. Raw data in the pool is untouched")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_destroy[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDestroy(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (virStoragePoolDestroy(pool) == 0) { + vshPrint(ctl, _("Pool %s destroyed\n"), name); + } else { + vshError(ctl, _("Failed to destroy pool %s"), name); + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-delete" command + */ +static const vshCmdInfo info_pool_delete[] = { + {"help", N_("delete a pool")}, + {"desc", N_("Delete a given pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_delete[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDelete(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (virStoragePoolDelete(pool, 0) == 0) { + vshPrint(ctl, _("Pool %s deleted\n"), name); + } else { + vshError(ctl, _("Failed to delete pool %s"), name); + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-refresh" command + */ +static const vshCmdInfo info_pool_refresh[] = { + {"help", N_("refresh a pool")}, + {"desc", N_("Refresh a given pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_refresh[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolRefresh(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (virStoragePoolRefresh(pool, 0) == 0) { + vshPrint(ctl, _("Pool %s refreshed\n"), name); + } else { + vshError(ctl, _("Failed to refresh pool %s"), name); + ret = false; + } + virStoragePoolFree(pool); + + return ret; +} + +/* + * "pool-dumpxml" command + */ +static const vshCmdInfo info_pool_dumpxml[] = { + {"help", N_("pool information in XML")}, + {"desc", N_("Output the pool information as an XML dump to stdout.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_dumpxml[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {"inactive", VSH_OT_BOOL, 0, N_("show inactive defined XML")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + bool inactive = vshCommandOptBool(cmd, "inactive"); + unsigned int flags = 0; + char *dump; + + if (inactive) + flags |= VIR_STORAGE_XML_INACTIVE; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) + return false; + + dump = virStoragePoolGetXMLDesc(pool, flags); + if (dump != NULL) { + vshPrint(ctl, "%s", dump); + VIR_FREE(dump); + } else { + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-list" command + */ +static const vshCmdInfo info_pool_list[] = { + {"help", N_("list pools")}, + {"desc", N_("Returns list of pools.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_list[] = { + {"inactive", VSH_OT_BOOL, 0, N_("list inactive pools")}, + {"all", VSH_OT_BOOL, 0, N_("list inactive & active pools")}, + {"details", VSH_OT_BOOL, 0, N_("display extended details for pools")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + virStoragePoolInfo info; + char **poolNames = NULL; + int i, ret; + bool functionReturn; + int numActivePools = 0, numInactivePools = 0, numAllPools = 0; + size_t stringLength = 0, nameStrLength = 0; + size_t autostartStrLength = 0, persistStrLength = 0; + size_t stateStrLength = 0, capStrLength = 0; + size_t allocStrLength = 0, availStrLength = 0; + struct poolInfoText { + char *state; + char *autostart; + char *persistent; + char *capacity; + char *allocation; + char *available; + }; + struct poolInfoText *poolInfoTexts = NULL; + + /* Determine the options passed by the user */ + bool all = vshCommandOptBool(cmd, "all"); + bool details = vshCommandOptBool(cmd, "details"); + bool inactive = vshCommandOptBool(cmd, "inactive"); + bool active = !inactive || all; + inactive |= all; + + /* Check the connection to libvirtd daemon is still working */ + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + /* Retrieve the number of active storage pools */ + if (active) { + numActivePools = virConnectNumOfStoragePools(ctl->conn); + if (numActivePools < 0) { + vshError(ctl, "%s", _("Failed to list active pools")); + return false; + } + } + + /* Retrieve the number of inactive storage pools */ + if (inactive) { + numInactivePools = virConnectNumOfDefinedStoragePools(ctl->conn); + if (numInactivePools < 0) { + vshError(ctl, "%s", _("Failed to list inactive pools")); + return false; + } + } + + /* Determine the total number of pools to list */ + numAllPools = numActivePools + numInactivePools; + + /* Allocate memory for arrays of storage pool names and info */ + poolNames = vshCalloc(ctl, numAllPools, sizeof(*poolNames)); + poolInfoTexts = + vshCalloc(ctl, numAllPools, sizeof(*poolInfoTexts)); + + /* Retrieve a list of active storage pool names */ + if (active) { + if (virConnectListStoragePools(ctl->conn, + poolNames, numActivePools) < 0) { + vshError(ctl, "%s", _("Failed to list active pools")); + VIR_FREE(poolInfoTexts); + VIR_FREE(poolNames); + return false; + } + } + + /* Add the inactive storage pools to the end of the name list */ + if (inactive) { + if (virConnectListDefinedStoragePools(ctl->conn, + &poolNames[numActivePools], + numInactivePools) < 0) { + vshError(ctl, "%s", _("Failed to list inactive pools")); + VIR_FREE(poolInfoTexts); + VIR_FREE(poolNames); + return false; + } + } + + /* Sort the storage pool names */ + qsort(poolNames, numAllPools, sizeof(*poolNames), vshNameSorter); + + /* Collect the storage pool information for display */ + for (i = 0; i < numAllPools; i++) { + int autostart = 0, persistent = 0; + + /* Retrieve a pool object, looking it up by name */ + virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, + poolNames[i]); + if (!pool) { + VIR_FREE(poolNames[i]); + continue; + } + + /* Retrieve the autostart status of the pool */ + if (virStoragePoolGetAutostart(pool, &autostart) < 0) + poolInfoTexts[i].autostart = vshStrdup(ctl, _("no autostart")); + else + poolInfoTexts[i].autostart = vshStrdup(ctl, autostart ? + _("yes") : _("no")); + + /* Retrieve the persistence status of the pool */ + if (details) { + persistent = virStoragePoolIsPersistent(pool); + vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n", + persistent); + if (persistent < 0) + poolInfoTexts[i].persistent = vshStrdup(ctl, _("unknown")); + else + poolInfoTexts[i].persistent = vshStrdup(ctl, persistent ? + _("yes") : _("no")); + + /* Keep the length of persistent string if longest so far */ + stringLength = strlen(poolInfoTexts[i].persistent); + if (stringLength > persistStrLength) + persistStrLength = stringLength; + } + + /* Collect further extended information about the pool */ + if (virStoragePoolGetInfo(pool, &info) != 0) { + /* Something went wrong retrieving pool info, cope with it */ + vshError(ctl, "%s", _("Could not retrieve pool information")); + poolInfoTexts[i].state = vshStrdup(ctl, _("unknown")); + if (details) { + poolInfoTexts[i].capacity = vshStrdup(ctl, _("unknown")); + poolInfoTexts[i].allocation = vshStrdup(ctl, _("unknown")); + poolInfoTexts[i].available = vshStrdup(ctl, _("unknown")); + } + } else { + /* Decide which state string to display */ + if (details) { + /* --details option was specified, we're using detailed state + * strings */ + switch (info.state) { + case VIR_STORAGE_POOL_INACTIVE: + poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); + break; + case VIR_STORAGE_POOL_BUILDING: + poolInfoTexts[i].state = vshStrdup(ctl, _("building")); + break; + case VIR_STORAGE_POOL_RUNNING: + poolInfoTexts[i].state = vshStrdup(ctl, _("running")); + break; + case VIR_STORAGE_POOL_DEGRADED: + poolInfoTexts[i].state = vshStrdup(ctl, _("degraded")); + break; + case VIR_STORAGE_POOL_INACCESSIBLE: + poolInfoTexts[i].state = vshStrdup(ctl, _("inaccessible")); + break; + } + + /* Create the pool size related strings */ + if (info.state == VIR_STORAGE_POOL_RUNNING || + info.state == VIR_STORAGE_POOL_DEGRADED) { + double val; + const char *unit; + + /* Create the capacity output string */ + val = prettyCapacity(info.capacity, &unit); + ret = virAsprintf(&poolInfoTexts[i].capacity, + "%.2lf %s", val, unit); + if (ret < 0) { + /* An error occurred creating the string, return */ + goto asprintf_failure; + } + + /* Create the allocation output string */ + val = prettyCapacity(info.allocation, &unit); + ret = virAsprintf(&poolInfoTexts[i].allocation, + "%.2lf %s", val, unit); + if (ret < 0) { + /* An error occurred creating the string, return */ + goto asprintf_failure; + } + + /* Create the available space output string */ + val = prettyCapacity(info.available, &unit); + ret = virAsprintf(&poolInfoTexts[i].available, + "%.2lf %s", val, unit); + if (ret < 0) { + /* An error occurred creating the string, return */ + goto asprintf_failure; + } + } else { + /* Capacity related information isn't available */ + poolInfoTexts[i].capacity = vshStrdup(ctl, _("-")); + poolInfoTexts[i].allocation = vshStrdup(ctl, _("-")); + poolInfoTexts[i].available = vshStrdup(ctl, _("-")); + } + + /* Keep the length of capacity string if longest so far */ + stringLength = strlen(poolInfoTexts[i].capacity); + if (stringLength > capStrLength) + capStrLength = stringLength; + + /* Keep the length of allocation string if longest so far */ + stringLength = strlen(poolInfoTexts[i].allocation); + if (stringLength > allocStrLength) + allocStrLength = stringLength; + + /* Keep the length of available string if longest so far */ + stringLength = strlen(poolInfoTexts[i].available); + if (stringLength > availStrLength) + availStrLength = stringLength; + } else { + /* --details option was not specified, only active/inactive + * state strings are used */ + if (info.state == VIR_STORAGE_POOL_INACTIVE) + poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); + else + poolInfoTexts[i].state = vshStrdup(ctl, _("active")); + } + } + + /* Keep the length of name string if longest so far */ + stringLength = strlen(poolNames[i]); + if (stringLength > nameStrLength) + nameStrLength = stringLength; + + /* Keep the length of state string if longest so far */ + stringLength = strlen(poolInfoTexts[i].state); + if (stringLength > stateStrLength) + stateStrLength = stringLength; + + /* Keep the length of autostart string if longest so far */ + stringLength = strlen(poolInfoTexts[i].autostart); + if (stringLength > autostartStrLength) + autostartStrLength = stringLength; + + /* Free the pool object */ + virStoragePoolFree(pool); + } + + /* If the --details option wasn't selected, we output the pool + * info using the fixed string format from previous versions to + * maintain backward compatibility. + */ + + /* Output basic info then return if --details option not selected */ + if (!details) { + /* Output old style header */ + vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), + _("Autostart")); + vshPrintExtra(ctl, "-----------------------------------------\n"); + + /* Output old style pool info */ + for (i = 0; i < numAllPools; i++) { + vshPrint(ctl, "%-20s %-10s %-10s\n", + poolNames[i], + poolInfoTexts[i].state, + poolInfoTexts[i].autostart); + } + + /* Cleanup and return */ + functionReturn = true; + goto cleanup; + } + + /* We only get here if the --details option was selected. */ + + /* Use the length of name header string if it's longest */ + stringLength = strlen(_("Name")); + if (stringLength > nameStrLength) + nameStrLength = stringLength; + + /* Use the length of state header string if it's longest */ + stringLength = strlen(_("State")); + if (stringLength > stateStrLength) + stateStrLength = stringLength; + + /* Use the length of autostart header string if it's longest */ + stringLength = strlen(_("Autostart")); + if (stringLength > autostartStrLength) + autostartStrLength = stringLength; + + /* Use the length of persistent header string if it's longest */ + stringLength = strlen(_("Persistent")); + if (stringLength > persistStrLength) + persistStrLength = stringLength; + + /* Use the length of capacity header string if it's longest */ + stringLength = strlen(_("Capacity")); + if (stringLength > capStrLength) + capStrLength = stringLength; + + /* Use the length of allocation header string if it's longest */ + stringLength = strlen(_("Allocation")); + if (stringLength > allocStrLength) + allocStrLength = stringLength; + + /* Use the length of available header string if it's longest */ + stringLength = strlen(_("Available")); + if (stringLength > availStrLength) + availStrLength = stringLength; + + /* Display the string lengths for debugging. */ + vshDebug(ctl, VSH_ERR_DEBUG, "Longest name string = %lu chars\n", + (unsigned long) nameStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest state string = %lu chars\n", + (unsigned long) stateStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest autostart string = %lu chars\n", + (unsigned long) autostartStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest persistent string = %lu chars\n", + (unsigned long) persistStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest capacity string = %lu chars\n", + (unsigned long) capStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest allocation string = %lu chars\n", + (unsigned long) allocStrLength); + vshDebug(ctl, VSH_ERR_DEBUG, "Longest available string = %lu chars\n", + (unsigned long) availStrLength); + + /* Create the output template. Each column is sized according to + * the longest string. + */ + char *outputStr; + ret = virAsprintf(&outputStr, + "%%-%lus %%-%lus %%-%lus %%-%lus %%%lus %%%lus %%%lus\n", + (unsigned long) nameStrLength, + (unsigned long) stateStrLength, + (unsigned long) autostartStrLength, + (unsigned long) persistStrLength, + (unsigned long) capStrLength, + (unsigned long) allocStrLength, + (unsigned long) availStrLength); + if (ret < 0) { + /* An error occurred creating the string, return */ + goto asprintf_failure; + } + + /* Display the header */ + vshPrint(ctl, outputStr, _("Name"), _("State"), _("Autostart"), + _("Persistent"), _("Capacity"), _("Allocation"), _("Available")); + for (i = nameStrLength + stateStrLength + autostartStrLength + + persistStrLength + capStrLength + + allocStrLength + availStrLength + + 12; i > 0; i--) + vshPrintExtra(ctl, "-"); + vshPrintExtra(ctl, "\n"); + + /* Display the pool info rows */ + for (i = 0; i < numAllPools; i++) { + vshPrint(ctl, outputStr, + poolNames[i], + poolInfoTexts[i].state, + poolInfoTexts[i].autostart, + poolInfoTexts[i].persistent, + poolInfoTexts[i].capacity, + poolInfoTexts[i].allocation, + poolInfoTexts[i].available); + } + + /* Cleanup and return */ + functionReturn = true; + goto cleanup; + +asprintf_failure: + + /* Display an appropriate error message then cleanup and return */ + switch (errno) { + case ENOMEM: + /* Couldn't allocate memory */ + vshError(ctl, "%s", _("Out of memory")); + break; + default: + /* Some other error */ + vshError(ctl, _("virAsprintf failed (errno %d)"), errno); + } + functionReturn = false; + +cleanup: + + /* Safely free the memory allocated in this function */ + for (i = 0; i < numAllPools; i++) { + /* Cleanup the memory for one pool info structure */ + VIR_FREE(poolInfoTexts[i].state); + VIR_FREE(poolInfoTexts[i].autostart); + VIR_FREE(poolInfoTexts[i].persistent); + VIR_FREE(poolInfoTexts[i].capacity); + VIR_FREE(poolInfoTexts[i].allocation); + VIR_FREE(poolInfoTexts[i].available); + VIR_FREE(poolNames[i]); + } + + /* Cleanup the memory for the initial arrays*/ + VIR_FREE(poolInfoTexts); + VIR_FREE(poolNames); + + /* Return the desired value */ + return functionReturn; +} + +/* + * "find-storage-pool-sources-as" command + */ +static const vshCmdInfo info_find_storage_pool_sources_as[] = { + {"help", N_("find potential storage pool sources")}, + {"desc", N_("Returns XML <sources> document.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_find_storage_pool_sources_as[] = { + {"type", VSH_OT_DATA, VSH_OFLAG_REQ, + N_("type of storage pool sources to find")}, + {"host", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional host to query")}, + {"port", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional port to query")}, + {"initiator", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional initiator IQN to use for query")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) +{ + const char *type = NULL, *host = NULL; + char *srcSpec = NULL; + char *srcList; + const char *initiator = NULL; + + if (vshCommandOptString(cmd, "type", &type) <= 0 || + vshCommandOptString(cmd, "host", &host) < 0 || + vshCommandOptString(cmd, "initiator", &initiator) < 0) { + vshError(ctl,"%s", _("missing argument")); + return false; + } + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (host) { + const char *port = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (vshCommandOptString(cmd, "port", &port) < 0) { + vshError(ctl, "%s", _("missing argument")); + virBufferFreeAndReset(&buf); + return false; + } + virBufferAddLit(&buf, "<source>\n"); + virBufferAsprintf(&buf, " <host name='%s'", host); + if (port) + virBufferAsprintf(&buf, " port='%s'", port); + virBufferAddLit(&buf, "/>\n"); + if (initiator) { + virBufferAddLit(&buf, " <initiator>\n"); + virBufferAsprintf(&buf, " <iqn name='%s'/>\n", initiator); + virBufferAddLit(&buf, " </initiator>\n"); + } + virBufferAddLit(&buf, "</source>\n"); + if (virBufferError(&buf)) { + vshError(ctl, "%s", _("Out of memory")); + return false; + } + srcSpec = virBufferContentAndReset(&buf); + } + + srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); + VIR_FREE(srcSpec); + if (srcList == NULL) { + vshError(ctl, _("Failed to find any %s pool sources"), type); + return false; + } + vshPrint(ctl, "%s", srcList); + VIR_FREE(srcList); + + return true; +} + +/* + * "find-storage-pool-sources" command + */ +static const vshCmdInfo info_find_storage_pool_sources[] = { + {"help", N_("discover potential storage pool sources")}, + {"desc", N_("Returns XML <sources> document.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_find_storage_pool_sources[] = { + {"type", VSH_OT_DATA, VSH_OFLAG_REQ, + N_("type of storage pool sources to discover")}, + {"srcSpec", VSH_OT_DATA, VSH_OFLAG_NONE, + N_("optional file of source xml to query for pools")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolDiscoverSources(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) +{ + const char *type = NULL, *srcSpecFile = NULL; + char *srcSpec = NULL, *srcList; + + if (vshCommandOptString(cmd, "type", &type) <= 0) + return false; + + if (vshCommandOptString(cmd, "srcSpec", &srcSpecFile) < 0) { + vshError(ctl, "%s", _("missing option")); + return false; + } + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (srcSpecFile && virFileReadAll(srcSpecFile, VIRSH_MAX_XML_FILE, &srcSpec) < 0) + return false; + + srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); + VIR_FREE(srcSpec); + if (srcList == NULL) { + vshError(ctl, _("Failed to find any %s pool sources"), type); + return false; + } + vshPrint(ctl, "%s", srcList); + VIR_FREE(srcList); + + return true; +} + +/* + * "pool-info" command + */ +static const vshCmdInfo info_pool_info[] = { + {"help", N_("storage pool information")}, + {"desc", N_("Returns basic information about the storage pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_info[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolInfo(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolInfo info; + virStoragePoolPtr pool; + int autostart = 0; + int persistent = 0; + bool ret = true; + char uuid[VIR_UUID_STRING_BUFLEN]; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) + return false; + + vshPrint(ctl, "%-15s %s\n", _("Name:"), virStoragePoolGetName(pool)); + + if (virStoragePoolGetUUIDString(pool, &uuid[0])==0) + vshPrint(ctl, "%-15s %s\n", _("UUID:"), uuid); + + if (virStoragePoolGetInfo(pool, &info) == 0) { + double val; + const char *unit; + switch (info.state) { + case VIR_STORAGE_POOL_INACTIVE: + vshPrint(ctl, "%-15s %s\n", _("State:"), + _("inactive")); + break; + case VIR_STORAGE_POOL_BUILDING: + vshPrint(ctl, "%-15s %s\n", _("State:"), + _("building")); + break; + case VIR_STORAGE_POOL_RUNNING: + vshPrint(ctl, "%-15s %s\n", _("State:"), + _("running")); + break; + case VIR_STORAGE_POOL_DEGRADED: + vshPrint(ctl, "%-15s %s\n", _("State:"), + _("degraded")); + break; + case VIR_STORAGE_POOL_INACCESSIBLE: + vshPrint(ctl, "%-15s %s\n", _("State:"), + _("inaccessible")); + break; + } + + /* Check and display whether the pool is persistent or not */ + persistent = virStoragePoolIsPersistent(pool); + vshDebug(ctl, VSH_ERR_DEBUG, "Pool persistent flag value: %d\n", + persistent); + if (persistent < 0) + vshPrint(ctl, "%-15s %s\n", _("Persistent:"), _("unknown")); + else + vshPrint(ctl, "%-15s %s\n", _("Persistent:"), persistent ? _("yes") : _("no")); + + /* Check and display whether the pool is autostarted or not */ + virStoragePoolGetAutostart(pool, &autostart); + vshDebug(ctl, VSH_ERR_DEBUG, "Pool autostart flag value: %d\n", + autostart); + if (autostart < 0) + vshPrint(ctl, "%-15s %s\n", _("Autostart:"), _("no autostart")); + else + vshPrint(ctl, "%-15s %s\n", _("Autostart:"), autostart ? _("yes") : _("no")); + + if (info.state == VIR_STORAGE_POOL_RUNNING || + info.state == VIR_STORAGE_POOL_DEGRADED) { + val = prettyCapacity(info.capacity, &unit); + vshPrint(ctl, "%-15s %2.2lf %s\n", _("Capacity:"), val, unit); + + val = prettyCapacity(info.allocation, &unit); + vshPrint(ctl, "%-15s %2.2lf %s\n", _("Allocation:"), val, unit); + + val = prettyCapacity(info.available, &unit); + vshPrint(ctl, "%-15s %2.2lf %s\n", _("Available:"), val, unit); + } + } else { + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-name" command + */ +static const vshCmdInfo info_pool_name[] = { + {"help", N_("convert a pool UUID to pool name")}, + {"desc", ""}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_name[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolName(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, + VSH_BYUUID))) + return false; + + vshPrint(ctl, "%s\n", virStoragePoolGetName(pool)); + virStoragePoolFree(pool); + return true; +} + +/* + * "pool-start" command + */ +static const vshCmdInfo info_pool_start[] = { + {"help", N_("start a (previously defined) inactive pool")}, + {"desc", N_("Start a pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_start[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name or uuid of the inactive pool")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolStart(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name = NULL; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (virStoragePoolCreate(pool, 0) == 0) { + vshPrint(ctl, _("Pool %s started\n"), name); + } else { + vshError(ctl, _("Failed to start pool %s"), name); + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-undefine" command + */ +static const vshCmdInfo info_pool_undefine[] = { + {"help", N_("undefine an inactive pool")}, + {"desc", N_("Undefine the configuration for an inactive pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_undefine[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolUndefine(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + bool ret = true; + const char *name; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + return false; + + if (virStoragePoolUndefine(pool) == 0) { + vshPrint(ctl, _("Pool %s has been undefined\n"), name); + } else { + vshError(ctl, _("Failed to undefine pool %s"), name); + ret = false; + } + + virStoragePoolFree(pool); + return ret; +} + +/* + * "pool-uuid" command + */ +static const vshCmdInfo info_pool_uuid[] = { + {"help", N_("convert a pool name to pool UUID")}, + {"desc", ""}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_uuid[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolUuid(vshControl *ctl, const vshCmd *cmd) +{ + virStoragePoolPtr pool; + char uuid[VIR_UUID_STRING_BUFLEN]; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return false; + + if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, + VSH_BYNAME))) + return false; + + if (virStoragePoolGetUUIDString(pool, uuid) != -1) + vshPrint(ctl, "%s\n", uuid); + else + vshError(ctl, "%s", _("failed to get pool UUID")); + + virStoragePoolFree(pool); + return true; +} + +/* + * "pool-edit" command + */ +static const vshCmdInfo info_pool_edit[] = { + {"help", N_("edit XML configuration for a storage pool")}, + {"desc", N_("Edit the XML configuration for a storage pool.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_pool_edit[] = { + {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, + {NULL, 0, 0, NULL} +}; + +static bool +cmdPoolEdit(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virStoragePoolPtr pool = NULL; + virStoragePoolPtr pool_edited = NULL; + unsigned int flags = VIR_STORAGE_XML_INACTIVE; + char *tmp_desc = NULL; + + if (!vshConnectionUsability(ctl, ctl->conn)) + goto cleanup; + + pool = vshCommandOptPool(ctl, cmd, "pool", NULL); + if (pool == NULL) + goto cleanup; + + /* Some old daemons don't support _INACTIVE flag */ + if (!(tmp_desc = virStoragePoolGetXMLDesc(pool, flags))) { + if (last_error->code == VIR_ERR_INVALID_ARG) { + flags &= ~VIR_STORAGE_XML_INACTIVE; + virFreeError(last_error); + last_error = NULL; + } else { + goto cleanup; + } + } else { + VIR_FREE(tmp_desc); + } + +#define EDIT_GET_XML virStoragePoolGetXMLDesc(pool, flags) +#define EDIT_NOT_CHANGED \ + vshPrint(ctl, _("Pool %s XML configuration not changed.\n"), \ + virStoragePoolGetName(pool)); \ + ret = true; goto edit_cleanup; +#define EDIT_DEFINE \ + (pool_edited = virStoragePoolDefineXML(ctl->conn, doc_edited, 0)) +#define EDIT_FREE \ + if (pool_edited) \ + virStoragePoolFree(pool_edited); +#include "virsh-edit.c" + + vshPrint(ctl, _("Pool %s XML configuration edited.\n"), + virStoragePoolGetName(pool_edited)); + + ret = true; + + cleanup: + if (pool) + virStoragePoolFree(pool); + if (pool_edited) + virStoragePoolFree(pool_edited); + + return ret; +} diff --git a/tools/virsh.c b/tools/virsh.c index ac8ad09..7a30871 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -364,14 +364,6 @@ static virInterfacePtr vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *c vshCommandOptInterfaceBy(_ctl, _cmd, NULL, _name, \ VSH_BYMAC|VSH_BYNAME) -static virStoragePoolPtr vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, - const char *optname, const char **name, int flag); - -/* default is lookup by Name and UUID */ -#define vshCommandOptPool(_ctl, _cmd, _optname, _name) \ - vshCommandOptPoolBy(_ctl, _cmd, _optname, _name, \ - VSH_BYUUID|VSH_BYNAME) - static virSecretPtr vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name); @@ -2863,1548 +2855,250 @@ static const vshCmdInfo info_nwfilter_dumpxml[] = { {NULL, NULL} }; -static const vshCmdOptDef opts_nwfilter_dumpxml[] = { - {"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd) -{ - virNWFilterPtr nwfilter; - bool ret = true; - char *dump; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL))) - return false; - - dump = virNWFilterGetXMLDesc(nwfilter, 0); - if (dump != NULL) { - vshPrint(ctl, "%s", dump); - VIR_FREE(dump); - } else { - ret = false; - } - - virNWFilterFree(nwfilter); - return ret; -} - -/* - * "nwfilter-list" command - */ -static const vshCmdInfo info_nwfilter_list[] = { - {"help", N_("list network filters")}, - {"desc", N_("Returns list of network filters.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_nwfilter_list[] = { - {NULL, 0, 0, NULL} -}; - -static bool -cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) -{ - int numfilters, i; - char **names; - char uuid[VIR_UUID_STRING_BUFLEN]; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - numfilters = virConnectNumOfNWFilters(ctl->conn); - if (numfilters < 0) { - vshError(ctl, "%s", _("Failed to list network filters")); - return false; - } - - names = vshMalloc(ctl, sizeof(char *) * numfilters); - - if ((numfilters = virConnectListNWFilters(ctl->conn, names, - numfilters)) < 0) { - vshError(ctl, "%s", _("Failed to list network filters")); - VIR_FREE(names); - return false; - } - - qsort(&names[0], numfilters, sizeof(char *), vshNameSorter); - - vshPrintExtra(ctl, "%-36s %-20s \n", _("UUID"), _("Name")); - vshPrintExtra(ctl, - "----------------------------------------------------------------\n"); - - for (i = 0; i < numfilters; i++) { - virNWFilterPtr nwfilter = - virNWFilterLookupByName(ctl->conn, names[i]); - - /* this kind of work with networks is not atomic operation */ - if (!nwfilter) { - VIR_FREE(names[i]); - continue; - } - - virNWFilterGetUUIDString(nwfilter, uuid); - vshPrint(ctl, "%-36s %-20s\n", - uuid, - virNWFilterGetName(nwfilter)); - virNWFilterFree(nwfilter); - VIR_FREE(names[i]); - } - - VIR_FREE(names); - return true; -} - - -/* - * "nwfilter-edit" command - */ -static const vshCmdInfo info_nwfilter_edit[] = { - {"help", N_("edit XML configuration for a network filter")}, - {"desc", N_("Edit the XML configuration for a network filter.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_nwfilter_edit[] = { - {"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdNWFilterEdit(vshControl *ctl, const vshCmd *cmd) -{ - bool ret = false; - virNWFilterPtr nwfilter = NULL; - virNWFilterPtr nwfilter_edited = NULL; - - if (!vshConnectionUsability(ctl, ctl->conn)) - goto cleanup; - - nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL); - if (nwfilter == NULL) - goto cleanup; - -#define EDIT_GET_XML virNWFilterGetXMLDesc(nwfilter, 0) -#define EDIT_NOT_CHANGED \ - vshPrint(ctl, _("Network filter %s XML " \ - "configuration not changed.\n"), \ - virNWFilterGetName(nwfilter)); \ - ret = true; goto edit_cleanup; -#define EDIT_DEFINE \ - (nwfilter_edited = virNWFilterDefineXML(ctl->conn, doc_edited)) -#define EDIT_FREE \ - if (nwfilter_edited) \ - virNWFilterFree(nwfilter); -#include "virsh-edit.c" - - vshPrint(ctl, _("Network filter %s XML configuration edited.\n"), - virNWFilterGetName(nwfilter_edited)); - - ret = true; - -cleanup: - if (nwfilter) - virNWFilterFree(nwfilter); - if (nwfilter_edited) - virNWFilterFree(nwfilter_edited); - - return ret; -} - - -/**************************************************************************/ -/* - * "pool-autostart" command - */ -static const vshCmdInfo info_pool_autostart[] = { - {"help", N_("autostart a pool")}, - {"desc", - N_("Configure a pool to be automatically started at boot.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_autostart[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {"disable", VSH_OT_BOOL, 0, N_("disable autostarting")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolAutostart(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - const char *name; - int autostart; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; - - autostart = !vshCommandOptBool(cmd, "disable"); - - if (virStoragePoolSetAutostart(pool, autostart) < 0) { - if (autostart) - vshError(ctl, _("failed to mark pool %s as autostarted"), name); - else - vshError(ctl, _("failed to unmark pool %s as autostarted"), name); - virStoragePoolFree(pool); - return false; - } - - if (autostart) - vshPrint(ctl, _("Pool %s marked as autostarted\n"), name); - else - vshPrint(ctl, _("Pool %s unmarked as autostarted\n"), name); - - virStoragePoolFree(pool); - return true; -} - -/* - * "pool-create" command - */ -static const vshCmdInfo info_pool_create[] = { - {"help", N_("create a pool from an XML file")}, - {"desc", N_("Create a pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_create[] = { - {"file", VSH_OT_DATA, VSH_OFLAG_REQ, - N_("file containing an XML pool description")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - const char *from = NULL; - bool ret = true; - char *buffer; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (vshCommandOptString(cmd, "file", &from) <= 0) - return false; - - if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) - return false; - - pool = virStoragePoolCreateXML(ctl->conn, buffer, 0); - VIR_FREE(buffer); - - if (pool != NULL) { - vshPrint(ctl, _("Pool %s created from %s\n"), - virStoragePoolGetName(pool), from); - virStoragePoolFree(pool); - } else { - vshError(ctl, _("Failed to create pool from %s"), from); - ret = false; - } - return ret; -} - - -/* - * "nodedev-create" command - */ -static const vshCmdInfo info_node_device_create[] = { - {"help", N_("create a device defined " - "by an XML file on the node")}, - {"desc", N_("Create a device on the node. Note that this " - "command creates devices on the physical host " - "that can then be assigned to a virtual machine.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_node_device_create[] = { - {"file", VSH_OT_DATA, VSH_OFLAG_REQ, - N_("file containing an XML description of the device")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd) -{ - virNodeDevicePtr dev = NULL; - const char *from = NULL; - bool ret = true; - char *buffer; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (vshCommandOptString(cmd, "file", &from) <= 0) - return false; - - if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) - return false; - - dev = virNodeDeviceCreateXML(ctl->conn, buffer, 0); - VIR_FREE(buffer); - - if (dev != NULL) { - vshPrint(ctl, _("Node device %s created from %s\n"), - virNodeDeviceGetName(dev), from); - virNodeDeviceFree(dev); - } else { - vshError(ctl, _("Failed to create node device from %s"), from); - ret = false; - } - - return ret; -} - - -/* - * "nodedev-destroy" command - */ -static const vshCmdInfo info_node_device_destroy[] = { - {"help", N_("destroy (stop) a device on the node")}, - {"desc", N_("Destroy a device on the node. Note that this " - "command destroys devices on the physical host")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_node_device_destroy[] = { - {"name", VSH_OT_DATA, VSH_OFLAG_REQ, - N_("name of the device to be destroyed")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd) -{ - virNodeDevicePtr dev = NULL; - bool ret = true; - const char *name = NULL; - - if (!vshConnectionUsability(ctl, ctl->conn)) { - return false; - } - - if (vshCommandOptString(cmd, "name", &name) <= 0) - return false; - - dev = virNodeDeviceLookupByName(ctl->conn, name); - - if (virNodeDeviceDestroy(dev) == 0) { - vshPrint(ctl, _("Destroyed node device '%s'\n"), name); - } else { - vshError(ctl, _("Failed to destroy node device '%s'"), name); - ret = false; - } - - virNodeDeviceFree(dev); - return ret; -} - - -/* - * XML Building helper for pool-define-as and pool-create-as - */ -static const vshCmdOptDef opts_pool_X_as[] = { - {"name", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name of the pool")}, - {"print-xml", VSH_OT_BOOL, 0, N_("print XML document, but don't define/create")}, - {"type", VSH_OT_DATA, VSH_OFLAG_REQ, N_("type of the pool")}, - {"source-host", VSH_OT_DATA, 0, N_("source-host for underlying storage")}, - {"source-path", VSH_OT_DATA, 0, N_("source path for underlying storage")}, - {"source-dev", VSH_OT_DATA, 0, N_("source device for underlying storage")}, - {"source-name", VSH_OT_DATA, 0, N_("source name for underlying storage")}, - {"target", VSH_OT_DATA, 0, N_("target for underlying storage")}, - {"source-format", VSH_OT_STRING, 0, N_("format for underlying storage")}, - {NULL, 0, 0, NULL} -}; - -static int buildPoolXML(const vshCmd *cmd, const char **retname, char **xml) { - - const char *name = NULL, *type = NULL, *srcHost = NULL, *srcPath = NULL, - *srcDev = NULL, *srcName = NULL, *srcFormat = NULL, *target = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (vshCommandOptString(cmd, "name", &name) <= 0) - goto cleanup; - if (vshCommandOptString(cmd, "type", &type) <= 0) - goto cleanup; - - if (vshCommandOptString(cmd, "source-host", &srcHost) < 0 || - vshCommandOptString(cmd, "source-path", &srcPath) < 0 || - vshCommandOptString(cmd, "source-dev", &srcDev) < 0 || - vshCommandOptString(cmd, "source-name", &srcName) < 0 || - vshCommandOptString(cmd, "source-format", &srcFormat) < 0 || - vshCommandOptString(cmd, "target", &target) < 0) { - vshError(NULL, "%s", _("missing argument")); - goto cleanup; - } - - virBufferAsprintf(&buf, "<pool type='%s'>\n", type); - virBufferAsprintf(&buf, " <name>%s</name>\n", name); - if (srcHost || srcPath || srcDev || srcFormat || srcName) { - virBufferAddLit(&buf, " <source>\n"); - - if (srcHost) - virBufferAsprintf(&buf, " <host name='%s'/>\n", srcHost); - if (srcPath) - virBufferAsprintf(&buf, " <dir path='%s'/>\n", srcPath); - if (srcDev) - virBufferAsprintf(&buf, " <device path='%s'/>\n", srcDev); - if (srcFormat) - virBufferAsprintf(&buf, " <format type='%s'/>\n", srcFormat); - if (srcName) - virBufferAsprintf(&buf, " <name>%s</name>\n", srcName); - - virBufferAddLit(&buf, " </source>\n"); - } - if (target) { - virBufferAddLit(&buf, " <target>\n"); - virBufferAsprintf(&buf, " <path>%s</path>\n", target); - virBufferAddLit(&buf, " </target>\n"); - } - virBufferAddLit(&buf, "</pool>\n"); - - if (virBufferError(&buf)) { - vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); - return false; - } - - *xml = virBufferContentAndReset(&buf); - *retname = name; - return true; - -cleanup: - virBufferFreeAndReset(&buf); - return false; -} - -/* - * "pool-create-as" command - */ -static const vshCmdInfo info_pool_create_as[] = { - {"help", N_("create a pool from a set of args")}, - {"desc", N_("Create a pool.")}, - {NULL, NULL} -}; - -static bool -cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - const char *name; - char *xml; - bool printXML = vshCommandOptBool(cmd, "print-xml"); - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!buildPoolXML(cmd, &name, &xml)) - return false; - - if (printXML) { - vshPrint(ctl, "%s", xml); - VIR_FREE(xml); - } else { - pool = virStoragePoolCreateXML(ctl->conn, xml, 0); - VIR_FREE(xml); - - if (pool != NULL) { - vshPrint(ctl, _("Pool %s created\n"), name); - virStoragePoolFree(pool); - } else { - vshError(ctl, _("Failed to create pool %s"), name); - return false; - } - } - return true; -} - - -/* - * "pool-define" command - */ -static const vshCmdInfo info_pool_define[] = { - {"help", N_("define (but don't start) a pool from an XML file")}, - {"desc", N_("Define a pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_define[] = { - {"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("file containing an XML pool description")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolDefine(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - const char *from = NULL; - bool ret = true; - char *buffer; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (vshCommandOptString(cmd, "file", &from) <= 0) - return false; - - if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) - return false; - - pool = virStoragePoolDefineXML(ctl->conn, buffer, 0); - VIR_FREE(buffer); - - if (pool != NULL) { - vshPrint(ctl, _("Pool %s defined from %s\n"), - virStoragePoolGetName(pool), from); - virStoragePoolFree(pool); - } else { - vshError(ctl, _("Failed to define pool from %s"), from); - ret = false; - } - return ret; -} - - -/* - * "pool-define-as" command - */ -static const vshCmdInfo info_pool_define_as[] = { - {"help", N_("define a pool from a set of args")}, - {"desc", N_("Define a pool.")}, - {NULL, NULL} -}; - -static bool -cmdPoolDefineAs(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - const char *name; - char *xml; - bool printXML = vshCommandOptBool(cmd, "print-xml"); - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!buildPoolXML(cmd, &name, &xml)) - return false; - - if (printXML) { - vshPrint(ctl, "%s", xml); - VIR_FREE(xml); - } else { - pool = virStoragePoolDefineXML(ctl->conn, xml, 0); - VIR_FREE(xml); - - if (pool != NULL) { - vshPrint(ctl, _("Pool %s defined\n"), name); - virStoragePoolFree(pool); - } else { - vshError(ctl, _("Failed to define pool %s"), name); - return false; - } - } - return true; -} - - -/* - * "pool-build" command - */ -static const vshCmdInfo info_pool_build[] = { - {"help", N_("build a pool")}, - {"desc", N_("Build a given pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_build[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {"no-overwrite", VSH_OT_BOOL, 0, N_("do not overwrite an existing pool of this type")}, - {"overwrite", VSH_OT_BOOL, 0, N_("overwrite any existing data")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - const char *name; - unsigned int flags = 0; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; - - if (vshCommandOptBool(cmd, "no-overwrite")) { - flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE; - } - - if (vshCommandOptBool(cmd, "overwrite")) { - flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE; - } - - if (virStoragePoolBuild(pool, flags) == 0) { - vshPrint(ctl, _("Pool %s built\n"), name); - } else { - vshError(ctl, _("Failed to build pool %s"), name); - ret = false; - } - - virStoragePoolFree(pool); - - return ret; -} - -/* - * "pool-destroy" command - */ -static const vshCmdInfo info_pool_destroy[] = { - {"help", N_("destroy (stop) a pool")}, - {"desc", - N_("Forcefully stop a given pool. Raw data in the pool is untouched")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_destroy[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolDestroy(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - const char *name; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; - - if (virStoragePoolDestroy(pool) == 0) { - vshPrint(ctl, _("Pool %s destroyed\n"), name); - } else { - vshError(ctl, _("Failed to destroy pool %s"), name); - ret = false; - } - - virStoragePoolFree(pool); - return ret; -} - - -/* - * "pool-delete" command - */ -static const vshCmdInfo info_pool_delete[] = { - {"help", N_("delete a pool")}, - {"desc", N_("Delete a given pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_delete[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolDelete(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - const char *name; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; - - if (virStoragePoolDelete(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s deleted\n"), name); - } else { - vshError(ctl, _("Failed to delete pool %s"), name); - ret = false; - } - - virStoragePoolFree(pool); - return ret; -} - - -/* - * "pool-refresh" command - */ -static const vshCmdInfo info_pool_refresh[] = { - {"help", N_("refresh a pool")}, - {"desc", N_("Refresh a given pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_refresh[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolRefresh(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - const char *name; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; - - if (virStoragePoolRefresh(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s refreshed\n"), name); - } else { - vshError(ctl, _("Failed to refresh pool %s"), name); - ret = false; - } - virStoragePoolFree(pool); - - return ret; -} - - -/* - * "pool-dumpxml" command - */ -static const vshCmdInfo info_pool_dumpxml[] = { - {"help", N_("pool information in XML")}, - {"desc", N_("Output the pool information as an XML dump to stdout.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_dumpxml[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {"inactive", VSH_OT_BOOL, 0, N_("show inactive defined XML")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - bool inactive = vshCommandOptBool(cmd, "inactive"); - unsigned int flags = 0; - char *dump; - - if (inactive) - flags |= VIR_STORAGE_XML_INACTIVE; - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) - return false; - - dump = virStoragePoolGetXMLDesc(pool, flags); - if (dump != NULL) { - vshPrint(ctl, "%s", dump); - VIR_FREE(dump); - } else { - ret = false; - } - - virStoragePoolFree(pool); - return ret; -} - - -/* - * "pool-list" command - */ -static const vshCmdInfo info_pool_list[] = { - {"help", N_("list pools")}, - {"desc", N_("Returns list of pools.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_list[] = { - {"inactive", VSH_OT_BOOL, 0, N_("list inactive pools")}, - {"all", VSH_OT_BOOL, 0, N_("list inactive & active pools")}, - {"details", VSH_OT_BOOL, 0, N_("display extended details for pools")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) -{ - virStoragePoolInfo info; - char **poolNames = NULL; - int i, ret; - bool functionReturn; - int numActivePools = 0, numInactivePools = 0, numAllPools = 0; - size_t stringLength = 0, nameStrLength = 0; - size_t autostartStrLength = 0, persistStrLength = 0; - size_t stateStrLength = 0, capStrLength = 0; - size_t allocStrLength = 0, availStrLength = 0; - struct poolInfoText { - char *state; - char *autostart; - char *persistent; - char *capacity; - char *allocation; - char *available; - }; - struct poolInfoText *poolInfoTexts = NULL; - - /* Determine the options passed by the user */ - bool all = vshCommandOptBool(cmd, "all"); - bool details = vshCommandOptBool(cmd, "details"); - bool inactive = vshCommandOptBool(cmd, "inactive"); - bool active = !inactive || all; - inactive |= all; - - /* Check the connection to libvirtd daemon is still working */ - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - /* Retrieve the number of active storage pools */ - if (active) { - numActivePools = virConnectNumOfStoragePools(ctl->conn); - if (numActivePools < 0) { - vshError(ctl, "%s", _("Failed to list active pools")); - return false; - } - } - - /* Retrieve the number of inactive storage pools */ - if (inactive) { - numInactivePools = virConnectNumOfDefinedStoragePools(ctl->conn); - if (numInactivePools < 0) { - vshError(ctl, "%s", _("Failed to list inactive pools")); - return false; - } - } - - /* Determine the total number of pools to list */ - numAllPools = numActivePools + numInactivePools; - - /* Allocate memory for arrays of storage pool names and info */ - poolNames = vshCalloc(ctl, numAllPools, sizeof(*poolNames)); - poolInfoTexts = - vshCalloc(ctl, numAllPools, sizeof(*poolInfoTexts)); - - /* Retrieve a list of active storage pool names */ - if (active) { - if (virConnectListStoragePools(ctl->conn, - poolNames, numActivePools) < 0) { - vshError(ctl, "%s", _("Failed to list active pools")); - VIR_FREE(poolInfoTexts); - VIR_FREE(poolNames); - return false; - } - } - - /* Add the inactive storage pools to the end of the name list */ - if (inactive) { - if (virConnectListDefinedStoragePools(ctl->conn, - &poolNames[numActivePools], - numInactivePools) < 0) { - vshError(ctl, "%s", _("Failed to list inactive pools")); - VIR_FREE(poolInfoTexts); - VIR_FREE(poolNames); - return false; - } - } - - /* Sort the storage pool names */ - qsort(poolNames, numAllPools, sizeof(*poolNames), vshNameSorter); - - /* Collect the storage pool information for display */ - for (i = 0; i < numAllPools; i++) { - int autostart = 0, persistent = 0; - - /* Retrieve a pool object, looking it up by name */ - virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, - poolNames[i]); - if (!pool) { - VIR_FREE(poolNames[i]); - continue; - } - - /* Retrieve the autostart status of the pool */ - if (virStoragePoolGetAutostart(pool, &autostart) < 0) - poolInfoTexts[i].autostart = vshStrdup(ctl, _("no autostart")); - else - poolInfoTexts[i].autostart = vshStrdup(ctl, autostart ? - _("yes") : _("no")); - - /* Retrieve the persistence status of the pool */ - if (details) { - persistent = virStoragePoolIsPersistent(pool); - vshDebug(ctl, VSH_ERR_DEBUG, "Persistent flag value: %d\n", - persistent); - if (persistent < 0) - poolInfoTexts[i].persistent = vshStrdup(ctl, _("unknown")); - else - poolInfoTexts[i].persistent = vshStrdup(ctl, persistent ? - _("yes") : _("no")); - - /* Keep the length of persistent string if longest so far */ - stringLength = strlen(poolInfoTexts[i].persistent); - if (stringLength > persistStrLength) - persistStrLength = stringLength; - } - - /* Collect further extended information about the pool */ - if (virStoragePoolGetInfo(pool, &info) != 0) { - /* Something went wrong retrieving pool info, cope with it */ - vshError(ctl, "%s", _("Could not retrieve pool information")); - poolInfoTexts[i].state = vshStrdup(ctl, _("unknown")); - if (details) { - poolInfoTexts[i].capacity = vshStrdup(ctl, _("unknown")); - poolInfoTexts[i].allocation = vshStrdup(ctl, _("unknown")); - poolInfoTexts[i].available = vshStrdup(ctl, _("unknown")); - } - } else { - /* Decide which state string to display */ - if (details) { - /* --details option was specified, we're using detailed state - * strings */ - switch (info.state) { - case VIR_STORAGE_POOL_INACTIVE: - poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); - break; - case VIR_STORAGE_POOL_BUILDING: - poolInfoTexts[i].state = vshStrdup(ctl, _("building")); - break; - case VIR_STORAGE_POOL_RUNNING: - poolInfoTexts[i].state = vshStrdup(ctl, _("running")); - break; - case VIR_STORAGE_POOL_DEGRADED: - poolInfoTexts[i].state = vshStrdup(ctl, _("degraded")); - break; - case VIR_STORAGE_POOL_INACCESSIBLE: - poolInfoTexts[i].state = vshStrdup(ctl, _("inaccessible")); - break; - } - - /* Create the pool size related strings */ - if (info.state == VIR_STORAGE_POOL_RUNNING || - info.state == VIR_STORAGE_POOL_DEGRADED) { - double val; - const char *unit; - - /* Create the capacity output string */ - val = prettyCapacity(info.capacity, &unit); - ret = virAsprintf(&poolInfoTexts[i].capacity, - "%.2lf %s", val, unit); - if (ret < 0) { - /* An error occurred creating the string, return */ - goto asprintf_failure; - } - - /* Create the allocation output string */ - val = prettyCapacity(info.allocation, &unit); - ret = virAsprintf(&poolInfoTexts[i].allocation, - "%.2lf %s", val, unit); - if (ret < 0) { - /* An error occurred creating the string, return */ - goto asprintf_failure; - } - - /* Create the available space output string */ - val = prettyCapacity(info.available, &unit); - ret = virAsprintf(&poolInfoTexts[i].available, - "%.2lf %s", val, unit); - if (ret < 0) { - /* An error occurred creating the string, return */ - goto asprintf_failure; - } - } else { - /* Capacity related information isn't available */ - poolInfoTexts[i].capacity = vshStrdup(ctl, _("-")); - poolInfoTexts[i].allocation = vshStrdup(ctl, _("-")); - poolInfoTexts[i].available = vshStrdup(ctl, _("-")); - } - - /* Keep the length of capacity string if longest so far */ - stringLength = strlen(poolInfoTexts[i].capacity); - if (stringLength > capStrLength) - capStrLength = stringLength; - - /* Keep the length of allocation string if longest so far */ - stringLength = strlen(poolInfoTexts[i].allocation); - if (stringLength > allocStrLength) - allocStrLength = stringLength; - - /* Keep the length of available string if longest so far */ - stringLength = strlen(poolInfoTexts[i].available); - if (stringLength > availStrLength) - availStrLength = stringLength; - } else { - /* --details option was not specified, only active/inactive - * state strings are used */ - if (info.state == VIR_STORAGE_POOL_INACTIVE) - poolInfoTexts[i].state = vshStrdup(ctl, _("inactive")); - else - poolInfoTexts[i].state = vshStrdup(ctl, _("active")); - } - } - - /* Keep the length of name string if longest so far */ - stringLength = strlen(poolNames[i]); - if (stringLength > nameStrLength) - nameStrLength = stringLength; - - /* Keep the length of state string if longest so far */ - stringLength = strlen(poolInfoTexts[i].state); - if (stringLength > stateStrLength) - stateStrLength = stringLength; - - /* Keep the length of autostart string if longest so far */ - stringLength = strlen(poolInfoTexts[i].autostart); - if (stringLength > autostartStrLength) - autostartStrLength = stringLength; - - /* Free the pool object */ - virStoragePoolFree(pool); - } - - /* If the --details option wasn't selected, we output the pool - * info using the fixed string format from previous versions to - * maintain backward compatibility. - */ - - /* Output basic info then return if --details option not selected */ - if (!details) { - /* Output old style header */ - vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), - _("Autostart")); - vshPrintExtra(ctl, "-----------------------------------------\n"); - - /* Output old style pool info */ - for (i = 0; i < numAllPools; i++) { - vshPrint(ctl, "%-20s %-10s %-10s\n", - poolNames[i], - poolInfoTexts[i].state, - poolInfoTexts[i].autostart); - } - - /* Cleanup and return */ - functionReturn = true; - goto cleanup; - } - - /* We only get here if the --details option was selected. */ - - /* Use the length of name header string if it's longest */ - stringLength = strlen(_("Name")); - if (stringLength > nameStrLength) - nameStrLength = stringLength; - - /* Use the length of state header string if it's longest */ - stringLength = strlen(_("State")); - if (stringLength > stateStrLength) - stateStrLength = stringLength; - - /* Use the length of autostart header string if it's longest */ - stringLength = strlen(_("Autostart")); - if (stringLength > autostartStrLength) - autostartStrLength = stringLength; - - /* Use the length of persistent header string if it's longest */ - stringLength = strlen(_("Persistent")); - if (stringLength > persistStrLength) - persistStrLength = stringLength; - - /* Use the length of capacity header string if it's longest */ - stringLength = strlen(_("Capacity")); - if (stringLength > capStrLength) - capStrLength = stringLength; - - /* Use the length of allocation header string if it's longest */ - stringLength = strlen(_("Allocation")); - if (stringLength > allocStrLength) - allocStrLength = stringLength; - - /* Use the length of available header string if it's longest */ - stringLength = strlen(_("Available")); - if (stringLength > availStrLength) - availStrLength = stringLength; - - /* Display the string lengths for debugging. */ - vshDebug(ctl, VSH_ERR_DEBUG, "Longest name string = %lu chars\n", - (unsigned long) nameStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest state string = %lu chars\n", - (unsigned long) stateStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest autostart string = %lu chars\n", - (unsigned long) autostartStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest persistent string = %lu chars\n", - (unsigned long) persistStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest capacity string = %lu chars\n", - (unsigned long) capStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest allocation string = %lu chars\n", - (unsigned long) allocStrLength); - vshDebug(ctl, VSH_ERR_DEBUG, "Longest available string = %lu chars\n", - (unsigned long) availStrLength); - - /* Create the output template. Each column is sized according to - * the longest string. - */ - char *outputStr; - ret = virAsprintf(&outputStr, - "%%-%lus %%-%lus %%-%lus %%-%lus %%%lus %%%lus %%%lus\n", - (unsigned long) nameStrLength, - (unsigned long) stateStrLength, - (unsigned long) autostartStrLength, - (unsigned long) persistStrLength, - (unsigned long) capStrLength, - (unsigned long) allocStrLength, - (unsigned long) availStrLength); - if (ret < 0) { - /* An error occurred creating the string, return */ - goto asprintf_failure; - } - - /* Display the header */ - vshPrint(ctl, outputStr, _("Name"), _("State"), _("Autostart"), - _("Persistent"), _("Capacity"), _("Allocation"), _("Available")); - for (i = nameStrLength + stateStrLength + autostartStrLength - + persistStrLength + capStrLength - + allocStrLength + availStrLength - + 12; i > 0; i--) - vshPrintExtra(ctl, "-"); - vshPrintExtra(ctl, "\n"); - - /* Display the pool info rows */ - for (i = 0; i < numAllPools; i++) { - vshPrint(ctl, outputStr, - poolNames[i], - poolInfoTexts[i].state, - poolInfoTexts[i].autostart, - poolInfoTexts[i].persistent, - poolInfoTexts[i].capacity, - poolInfoTexts[i].allocation, - poolInfoTexts[i].available); - } - - /* Cleanup and return */ - functionReturn = true; - goto cleanup; - -asprintf_failure: - - /* Display an appropriate error message then cleanup and return */ - switch (errno) { - case ENOMEM: - /* Couldn't allocate memory */ - vshError(ctl, "%s", _("Out of memory")); - break; - default: - /* Some other error */ - vshError(ctl, _("virAsprintf failed (errno %d)"), errno); - } - functionReturn = false; - -cleanup: - - /* Safely free the memory allocated in this function */ - for (i = 0; i < numAllPools; i++) { - /* Cleanup the memory for one pool info structure */ - VIR_FREE(poolInfoTexts[i].state); - VIR_FREE(poolInfoTexts[i].autostart); - VIR_FREE(poolInfoTexts[i].persistent); - VIR_FREE(poolInfoTexts[i].capacity); - VIR_FREE(poolInfoTexts[i].allocation); - VIR_FREE(poolInfoTexts[i].available); - VIR_FREE(poolNames[i]); - } - - /* Cleanup the memory for the initial arrays*/ - VIR_FREE(poolInfoTexts); - VIR_FREE(poolNames); - - /* Return the desired value */ - return functionReturn; -} - -/* - * "find-storage-pool-sources-as" command - */ -static const vshCmdInfo info_find_storage_pool_sources_as[] = { - {"help", N_("find potential storage pool sources")}, - {"desc", N_("Returns XML <sources> document.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_find_storage_pool_sources_as[] = { - {"type", VSH_OT_DATA, VSH_OFLAG_REQ, - N_("type of storage pool sources to find")}, - {"host", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional host to query")}, - {"port", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional port to query")}, - {"initiator", VSH_OT_DATA, VSH_OFLAG_NONE, N_("optional initiator IQN to use for query")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) -{ - const char *type = NULL, *host = NULL; - char *srcSpec = NULL; - char *srcList; - const char *initiator = NULL; - - if (vshCommandOptString(cmd, "type", &type) <= 0 || - vshCommandOptString(cmd, "host", &host) < 0 || - vshCommandOptString(cmd, "initiator", &initiator) < 0) { - vshError(ctl,"%s", _("missing argument")); - return false; - } - - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - - if (host) { - const char *port = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (vshCommandOptString(cmd, "port", &port) < 0) { - vshError(ctl, "%s", _("missing argument")); - virBufferFreeAndReset(&buf); - return false; - } - virBufferAddLit(&buf, "<source>\n"); - virBufferAsprintf(&buf, " <host name='%s'", host); - if (port) - virBufferAsprintf(&buf, " port='%s'", port); - virBufferAddLit(&buf, "/>\n"); - if (initiator) { - virBufferAddLit(&buf, " <initiator>\n"); - virBufferAsprintf(&buf, " <iqn name='%s'/>\n", initiator); - virBufferAddLit(&buf, " </initiator>\n"); - } - virBufferAddLit(&buf, "</source>\n"); - if (virBufferError(&buf)) { - vshError(ctl, "%s", _("Out of memory")); - return false; - } - srcSpec = virBufferContentAndReset(&buf); - } - - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); - VIR_FREE(srcSpec); - if (srcList == NULL) { - vshError(ctl, _("Failed to find any %s pool sources"), type); - return false; - } - vshPrint(ctl, "%s", srcList); - VIR_FREE(srcList); - - return true; -} - - -/* - * "find-storage-pool-sources" command - */ -static const vshCmdInfo info_find_storage_pool_sources[] = { - {"help", N_("discover potential storage pool sources")}, - {"desc", N_("Returns XML <sources> document.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_find_storage_pool_sources[] = { - {"type", VSH_OT_DATA, VSH_OFLAG_REQ, - N_("type of storage pool sources to discover")}, - {"srcSpec", VSH_OT_DATA, VSH_OFLAG_NONE, - N_("optional file of source xml to query for pools")}, +static const vshCmdOptDef opts_nwfilter_dumpxml[] = { + {"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")}, {NULL, 0, 0, NULL} }; static bool -cmdPoolDiscoverSources(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) +cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd) { - const char *type = NULL, *srcSpecFile = NULL; - char *srcSpec = NULL, *srcList; - - if (vshCommandOptString(cmd, "type", &type) <= 0) - return false; - - if (vshCommandOptString(cmd, "srcSpec", &srcSpecFile) < 0) { - vshError(ctl, "%s", _("missing option")); - return false; - } + virNWFilterPtr nwfilter; + bool ret = true; + char *dump; if (!vshConnectionUsability(ctl, ctl->conn)) return false; - if (srcSpecFile && virFileReadAll(srcSpecFile, VIRSH_MAX_XML_FILE, &srcSpec) < 0) + if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL))) return false; - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); - VIR_FREE(srcSpec); - if (srcList == NULL) { - vshError(ctl, _("Failed to find any %s pool sources"), type); - return false; + dump = virNWFilterGetXMLDesc(nwfilter, 0); + if (dump != NULL) { + vshPrint(ctl, "%s", dump); + VIR_FREE(dump); + } else { + ret = false; } - vshPrint(ctl, "%s", srcList); - VIR_FREE(srcList); - return true; + virNWFilterFree(nwfilter); + return ret; } - /* - * "pool-info" command + * "nwfilter-list" command */ -static const vshCmdInfo info_pool_info[] = { - {"help", N_("storage pool information")}, - {"desc", N_("Returns basic information about the storage pool.")}, +static const vshCmdInfo info_nwfilter_list[] = { + {"help", N_("list network filters")}, + {"desc", N_("Returns list of network filters.")}, {NULL, NULL} }; -static const vshCmdOptDef opts_pool_info[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, +static const vshCmdOptDef opts_nwfilter_list[] = { {NULL, 0, 0, NULL} }; static bool -cmdPoolInfo(vshControl *ctl, const vshCmd *cmd) +cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { - virStoragePoolInfo info; - virStoragePoolPtr pool; - int autostart = 0; - int persistent = 0; - bool ret = true; + int numfilters, i; + char **names; char uuid[VIR_UUID_STRING_BUFLEN]; if (!vshConnectionUsability(ctl, ctl->conn)) return false; - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) + numfilters = virConnectNumOfNWFilters(ctl->conn); + if (numfilters < 0) { + vshError(ctl, "%s", _("Failed to list network filters")); return false; + } - vshPrint(ctl, "%-15s %s\n", _("Name:"), virStoragePoolGetName(pool)); - - if (virStoragePoolGetUUIDString(pool, &uuid[0])==0) - vshPrint(ctl, "%-15s %s\n", _("UUID:"), uuid); + names = vshMalloc(ctl, sizeof(char *) * numfilters); - if (virStoragePoolGetInfo(pool, &info) == 0) { - double val; - const char *unit; - switch (info.state) { - case VIR_STORAGE_POOL_INACTIVE: - vshPrint(ctl, "%-15s %s\n", _("State:"), - _("inactive")); - break; - case VIR_STORAGE_POOL_BUILDING: - vshPrint(ctl, "%-15s %s\n", _("State:"), - _("building")); - break; - case VIR_STORAGE_POOL_RUNNING: - vshPrint(ctl, "%-15s %s\n", _("State:"), - _("running")); - break; - case VIR_STORAGE_POOL_DEGRADED: - vshPrint(ctl, "%-15s %s\n", _("State:"), - _("degraded")); - break; - case VIR_STORAGE_POOL_INACCESSIBLE: - vshPrint(ctl, "%-15s %s\n", _("State:"), - _("inaccessible")); - break; - } + if ((numfilters = virConnectListNWFilters(ctl->conn, names, + numfilters)) < 0) { + vshError(ctl, "%s", _("Failed to list network filters")); + VIR_FREE(names); + return false; + } - /* Check and display whether the pool is persistent or not */ - persistent = virStoragePoolIsPersistent(pool); - vshDebug(ctl, VSH_ERR_DEBUG, "Pool persistent flag value: %d\n", - persistent); - if (persistent < 0) - vshPrint(ctl, "%-15s %s\n", _("Persistent:"), _("unknown")); - else - vshPrint(ctl, "%-15s %s\n", _("Persistent:"), persistent ? _("yes") : _("no")); - - /* Check and display whether the pool is autostarted or not */ - virStoragePoolGetAutostart(pool, &autostart); - vshDebug(ctl, VSH_ERR_DEBUG, "Pool autostart flag value: %d\n", - autostart); - if (autostart < 0) - vshPrint(ctl, "%-15s %s\n", _("Autostart:"), _("no autostart")); - else - vshPrint(ctl, "%-15s %s\n", _("Autostart:"), autostart ? _("yes") : _("no")); + qsort(&names[0], numfilters, sizeof(char *), vshNameSorter); - if (info.state == VIR_STORAGE_POOL_RUNNING || - info.state == VIR_STORAGE_POOL_DEGRADED) { - val = prettyCapacity(info.capacity, &unit); - vshPrint(ctl, "%-15s %2.2lf %s\n", _("Capacity:"), val, unit); + vshPrintExtra(ctl, "%-36s %-20s \n", _("UUID"), _("Name")); + vshPrintExtra(ctl, + "----------------------------------------------------------------\n"); - val = prettyCapacity(info.allocation, &unit); - vshPrint(ctl, "%-15s %2.2lf %s\n", _("Allocation:"), val, unit); + for (i = 0; i < numfilters; i++) { + virNWFilterPtr nwfilter = + virNWFilterLookupByName(ctl->conn, names[i]); - val = prettyCapacity(info.available, &unit); - vshPrint(ctl, "%-15s %2.2lf %s\n", _("Available:"), val, unit); + /* this kind of work with networks is not atomic operation */ + if (!nwfilter) { + VIR_FREE(names[i]); + continue; } - } else { - ret = false; + + virNWFilterGetUUIDString(nwfilter, uuid); + vshPrint(ctl, "%-36s %-20s\n", + uuid, + virNWFilterGetName(nwfilter)); + virNWFilterFree(nwfilter); + VIR_FREE(names[i]); } - virStoragePoolFree(pool); - return ret; + VIR_FREE(names); + return true; } /* - * "pool-name" command + * "nwfilter-edit" command */ -static const vshCmdInfo info_pool_name[] = { - {"help", N_("convert a pool UUID to pool name")}, - {"desc", ""}, +static const vshCmdInfo info_nwfilter_edit[] = { + {"help", N_("edit XML configuration for a network filter")}, + {"desc", N_("Edit the XML configuration for a network filter.")}, {NULL, NULL} }; -static const vshCmdOptDef opts_pool_name[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool uuid")}, +static const vshCmdOptDef opts_nwfilter_edit[] = { + {"nwfilter", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network filter name or uuid")}, {NULL, 0, 0, NULL} }; static bool -cmdPoolName(vshControl *ctl, const vshCmd *cmd) +cmdNWFilterEdit(vshControl *ctl, const vshCmd *cmd) { - virStoragePoolPtr pool; + bool ret = false; + virNWFilterPtr nwfilter = NULL; + virNWFilterPtr nwfilter_edited = NULL; if (!vshConnectionUsability(ctl, ctl->conn)) - return false; - if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, - VSH_BYUUID))) - return false; - - vshPrint(ctl, "%s\n", virStoragePoolGetName(pool)); - virStoragePoolFree(pool); - return true; -} - - -/* - * "pool-start" command - */ -static const vshCmdInfo info_pool_start[] = { - {"help", N_("start a (previously defined) inactive pool")}, - {"desc", N_("Start a pool.")}, - {NULL, NULL} -}; + goto cleanup; -static const vshCmdOptDef opts_pool_start[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("name or uuid of the inactive pool")}, - {NULL, 0, 0, NULL} -}; + nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL); + if (nwfilter == NULL) + goto cleanup; -static bool -cmdPoolStart(vshControl *ctl, const vshCmd *cmd) -{ - virStoragePoolPtr pool; - bool ret = true; - const char *name = NULL; +#define EDIT_GET_XML virNWFilterGetXMLDesc(nwfilter, 0) +#define EDIT_NOT_CHANGED \ + vshPrint(ctl, _("Network filter %s XML " \ + "configuration not changed.\n"), \ + virNWFilterGetName(nwfilter)); \ + ret = true; goto edit_cleanup; +#define EDIT_DEFINE \ + (nwfilter_edited = virNWFilterDefineXML(ctl->conn, doc_edited)) +#define EDIT_FREE \ + if (nwfilter_edited) \ + virNWFilterFree(nwfilter); +#include "virsh-edit.c" - if (!vshConnectionUsability(ctl, ctl->conn)) - return false; + vshPrint(ctl, _("Network filter %s XML configuration edited.\n"), + virNWFilterGetName(nwfilter_edited)); - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) - return false; + ret = true; - if (virStoragePoolCreate(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s started\n"), name); - } else { - vshError(ctl, _("Failed to start pool %s"), name); - ret = false; - } +cleanup: + if (nwfilter) + virNWFilterFree(nwfilter); + if (nwfilter_edited) + virNWFilterFree(nwfilter_edited); - virStoragePoolFree(pool); return ret; } /* - * "pool-undefine" command + * "nodedev-create" command */ -static const vshCmdInfo info_pool_undefine[] = { - {"help", N_("undefine an inactive pool")}, - {"desc", N_("Undefine the configuration for an inactive pool.")}, +static const vshCmdInfo info_node_device_create[] = { + {"help", N_("create a device defined " + "by an XML file on the node")}, + {"desc", N_("Create a device on the node. Note that this " + "command creates devices on the physical host " + "that can then be assigned to a virtual machine.")}, {NULL, NULL} }; -static const vshCmdOptDef opts_pool_undefine[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, +static const vshCmdOptDef opts_node_device_create[] = { + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, + N_("file containing an XML description of the device")}, {NULL, 0, 0, NULL} }; static bool -cmdPoolUndefine(vshControl *ctl, const vshCmd *cmd) +cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd) { - virStoragePoolPtr pool; + virNodeDevicePtr dev = NULL; + const char *from = NULL; bool ret = true; - const char *name; + char *buffer; if (!vshConnectionUsability(ctl, ctl->conn)) return false; - if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) + if (vshCommandOptString(cmd, "file", &from) <= 0) + return false; + + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - if (virStoragePoolUndefine(pool) == 0) { - vshPrint(ctl, _("Pool %s has been undefined\n"), name); + dev = virNodeDeviceCreateXML(ctl->conn, buffer, 0); + VIR_FREE(buffer); + + if (dev != NULL) { + vshPrint(ctl, _("Node device %s created from %s\n"), + virNodeDeviceGetName(dev), from); + virNodeDeviceFree(dev); } else { - vshError(ctl, _("Failed to undefine pool %s"), name); + vshError(ctl, _("Failed to create node device from %s"), from); ret = false; } - virStoragePoolFree(pool); return ret; } /* - * "pool-uuid" command + * "nodedev-destroy" command */ -static const vshCmdInfo info_pool_uuid[] = { - {"help", N_("convert a pool name to pool UUID")}, - {"desc", ""}, +static const vshCmdInfo info_node_device_destroy[] = { + {"help", N_("destroy (stop) a device on the node")}, + {"desc", N_("Destroy a device on the node. Note that this " + "command destroys devices on the physical host")}, {NULL, NULL} }; -static const vshCmdOptDef opts_pool_uuid[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name")}, +static const vshCmdOptDef opts_node_device_destroy[] = { + {"name", VSH_OT_DATA, VSH_OFLAG_REQ, + N_("name of the device to be destroyed")}, {NULL, 0, 0, NULL} }; static bool -cmdPoolUuid(vshControl *ctl, const vshCmd *cmd) +cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd) { - virStoragePoolPtr pool; - char uuid[VIR_UUID_STRING_BUFLEN]; + virNodeDevicePtr dev = NULL; + bool ret = true; + const char *name = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl, ctl->conn)) { return false; + } - if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, - VSH_BYNAME))) + if (vshCommandOptString(cmd, "name", &name) <= 0) return false; - if (virStoragePoolGetUUIDString(pool, uuid) != -1) - vshPrint(ctl, "%s\n", uuid); - else - vshError(ctl, "%s", _("failed to get pool UUID")); + dev = virNodeDeviceLookupByName(ctl->conn, name); - virStoragePoolFree(pool); - return true; + if (virNodeDeviceDestroy(dev) == 0) { + vshPrint(ctl, _("Destroyed node device '%s'\n"), name); + } else { + vshError(ctl, _("Failed to destroy node device '%s'"), name); + ret = false; + } + + virNodeDeviceFree(dev); + return ret; } /* @@ -5582,75 +4276,6 @@ cmdNetworkEdit(vshControl *ctl, const vshCmd *cmd) } /* - * "pool-edit" command - */ -static const vshCmdInfo info_pool_edit[] = { - {"help", N_("edit XML configuration for a storage pool")}, - {"desc", N_("Edit the XML configuration for a storage pool.")}, - {NULL, NULL} -}; - -static const vshCmdOptDef opts_pool_edit[] = { - {"pool", VSH_OT_DATA, VSH_OFLAG_REQ, N_("pool name or uuid")}, - {NULL, 0, 0, NULL} -}; - -static bool -cmdPoolEdit(vshControl *ctl, const vshCmd *cmd) -{ - bool ret = false; - virStoragePoolPtr pool = NULL; - virStoragePoolPtr pool_edited = NULL; - unsigned int flags = VIR_STORAGE_XML_INACTIVE; - char *tmp_desc = NULL; - - if (!vshConnectionUsability(ctl, ctl->conn)) - goto cleanup; - - pool = vshCommandOptPool(ctl, cmd, "pool", NULL); - if (pool == NULL) - goto cleanup; - - /* Some old daemons don't support _INACTIVE flag */ - if (!(tmp_desc = virStoragePoolGetXMLDesc(pool, flags))) { - if (last_error->code == VIR_ERR_INVALID_ARG) { - flags &= ~VIR_STORAGE_XML_INACTIVE; - virFreeError(last_error); - last_error = NULL; - } else { - goto cleanup; - } - } else { - VIR_FREE(tmp_desc); - } - -#define EDIT_GET_XML virStoragePoolGetXMLDesc(pool, flags) -#define EDIT_NOT_CHANGED \ - vshPrint(ctl, _("Pool %s XML configuration not changed.\n"), \ - virStoragePoolGetName(pool)); \ - ret = true; goto edit_cleanup; -#define EDIT_DEFINE \ - (pool_edited = virStoragePoolDefineXML(ctl->conn, doc_edited, 0)) -#define EDIT_FREE \ - if (pool_edited) \ - virStoragePoolFree(pool_edited); -#include "virsh-edit.c" - - vshPrint(ctl, _("Pool %s XML configuration edited.\n"), - virStoragePoolGetName(pool_edited)); - - ret = true; - - cleanup: - if (pool) - virStoragePoolFree(pool); - if (pool_edited) - virStoragePoolFree(pool_edited); - - return ret; -} - -/* * "quit" command */ static const vshCmdInfo info_quit[] = { @@ -8205,41 +6830,6 @@ vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, return iface; } -static virStoragePoolPtr -vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, - const char **name, int flag) -{ - virStoragePoolPtr pool = NULL; - const char *n = NULL; - - if (vshCommandOptString(cmd, optname, &n) <= 0) - return NULL; - - vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n", - cmd->def->name, optname, n); - - if (name) - *name = n; - - /* try it by UUID */ - if ((flag & VSH_BYUUID) && strlen(n) == VIR_UUID_STRING_BUFLEN-1) { - vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool UUID\n", - cmd->def->name, optname); - pool = virStoragePoolLookupByUUIDString(ctl->conn, n); - } - /* try it by NAME */ - if (pool == NULL && (flag & VSH_BYNAME)) { - vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as pool NAME\n", - cmd->def->name, optname); - pool = virStoragePoolLookupByName(ctl->conn, n); - } - - if (!pool) - vshError(ctl, _("failed to get pool '%s'"), n); - - return pool; -} - static virSecretPtr vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name) { @@ -9706,6 +8296,8 @@ static const vshCmdDef domMonitoringCmds[] = { {NULL, NULL, NULL, NULL, 0} }; +#include "virsh-pool.c" + static const vshCmdDef storagePoolCmds[] = { {"find-storage-pool-sources-as", cmdPoolDiscoverSourcesAs, opts_find_storage_pool_sources_as, info_find_storage_pool_sources_as, 0}, -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list