diff --git a/docs/drvnodedev.rst b/docs/drvnodedev.rst index 115d52ca02..b455fa67a4 100644 --- a/docs/drvnodedev.rst +++ b/docs/drvnodedev.rst @@ -23,7 +23,8 @@ NPIV) `__). Persistent virtual devices are managed with ``virsh nodedev-define`` and ``virsh nodedev-undefine``. Persistent devices can be configured to start manually or automatically using ``virsh nodedev-autostart``. Inactive devices -can be made active with ``virsh nodedev-start``. +can be made active with ``virsh nodedev-start``. ``virsh nodedev-update`` +allows to modify devices (:since:`Since 10.1.0`). Transient virtual devices are started and stopped with the commands ``virsh nodedev-create`` and ``virsh nodedev-destroy``. @@ -278,6 +279,7 @@ covers the following features: - display device details ( :since:`Since 3.4.0` ) - create transient mediated devices ( :since:`Since 6.5.0` ) - define persistent mediated devices ( :since:`Since 7.3.0` ) +- update mediated devices ( :since:`Since 10.1.0` ) Because mediated devices are instantiated from vendor specific templates, simply called 'types', information describing these types is contained within the diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index bc0ad6542b..8224aec8c3 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -5331,6 +5331,25 @@ If *--validate* is specified, validates the format of the XML document against an internal RNG schema. +nodedev-update +-------------- + +**Syntax:** + +:: + + nodedev-update device FILE [[--live] [--config] | [--current]] + +Update a device on the host. *device* can be either device name or wwn pair +in "wwnn,wwpn" format (only works for vHBA currently). *file* +contains xml for a top-level description of the node device. +*--current* can be either or both of *live* and *config*, depends on +the hypervisor's implementation. +Both *--live* and *--config* flags may be given, but *--current* is +exclusive. If no flag is specified, behavior is different depending +on hypervisor. + + nodedev-destroy --------------- diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 5942c43689..3f7896dd9a 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -1299,6 +1299,101 @@ cmdNodeDeviceInfo(vshControl *ctl, const vshCmd *cmd) } +/* + * "nodedev-update" command + */ +static const vshCmdInfo info_node_device_update[] = { + {.name = "help", + .data = N_("Update a active and/or inactive node device") + }, + {.name = "desc", + .data = N_("Updates the configuration of a node device") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_node_device_update[] = { + {.name = "device", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("device name or wwn pair in 'wwnn,wwpn' format"), + .completer = virshNodeDeviceNameCompleter, + }, + VIRSH_COMMON_OPT_FILE(N_("file containing an XML description " + "of the device")), + VIRSH_COMMON_OPT_CONFIG(N_("affect next node device startup")), + VIRSH_COMMON_OPT_LIVE(N_("affect running node device")), + VIRSH_COMMON_OPT_CURRENT(N_("affect current state of node device")), + {.name = NULL} +}; + +static bool +cmdNodeDeviceUpdate(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + g_autoptr(virshNodeDevice) device = NULL; + const char *device_value = NULL; + const char *from = NULL; + g_autofree char *xml = NULL; + bool config = vshCommandOptBool(cmd, "config"); + bool live = vshCommandOptBool(cmd, "live"); + unsigned int flags = VIR_NODE_DEVICE_UPDATE_AFFECT_CURRENT; + + VSH_EXCLUSIVE_OPTIONS("current", "live"); + VSH_EXCLUSIVE_OPTIONS("current", "config"); + + if (vshCommandOptStringReq(ctl, cmd, "device", &device_value) < 0) + return false; + + device = vshFindNodeDevice(ctl, device_value); + + if (!device) + return false; + + if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) + goto cleanup; + + if (virFileReadAll(from, VSH_MAX_XML_FILE, &xml) < 0) + goto cleanup; + + if (config) + flags |= VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG; + if (live) + flags |= VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE; + + if (virNodeDeviceUpdate(device, xml, flags) < 0) { + vshError(ctl, _("Failed to update node device %1$s from '%2$s'"), + virNodeDeviceGetName(device), from); + goto cleanup; + } + + if (config) { + if (live) { + vshPrintExtra(ctl, + _("Updated node device %1$s persistent config and live state"), + virNodeDeviceGetName(device)); + } else { + vshPrintExtra(ctl, + _("Updated node device %1$s persistent config"), + virNodeDeviceGetName(device)); + } + } else if (live) { + vshPrintExtra(ctl, _("Updated node device %1$s live state"), + virNodeDeviceGetName(device)); + } else if (virNodeDeviceIsActive(device)) { + vshPrintExtra(ctl, _("Updated node device %1$s live state"), + virNodeDeviceGetName(device)); + } else { + vshPrintExtra(ctl, _("Updated node device %1$s persistent config"), + virNodeDeviceGetName(device)); + } + + ret = true; + cleanup: + vshReportError(ctl); + return ret; +} + const vshCmdDef nodedevCmds[] = { {.name = "nodedev-create", @@ -1383,5 +1478,11 @@ const vshCmdDef nodedevCmds[] = { .info = info_node_device_info, .flags = 0 }, + {.name = "nodedev-update", + .handler = cmdNodeDeviceUpdate, + .opts = opts_node_device_update, + .info = info_node_device_update, + .flags = 0 + }, {.name = NULL} };