[libvirt] [PATCH v3 0/5] introduce support for an embedded driver mode
by Daniel P. Berrangé
This is a followup to:
https://www.redhat.com/archives/libvir-list/2019-May/msg00467.html
https://www.redhat.com/archives/libvir-list/2019-December/msg00050.html
This series implements support for an embedded driver mode for libvirt,
with initial support in the QEMU and secrets drivers.
In this mode of operation, the driver stores all its config and state
under a private directory tree. See the individual patches for the
illustrated directory hierarchy used.
The intent of this embedded mode is to suit cases where the application
is using virtualization as a building block for some functionality, as
opposed to running traditional "full OS" builds.
The long time posterchild example would be libguestfs, while a more
recent example could be Kata containers.
The general principal in enabling this embedded mode is that the
functionality available should be identical to that seen when the
driver is running inside libvirtd. This is achieved by loading the
exact same driver .so module as libvirtd would load, and simply
configuring it with a different directory layout.
The result of this is that when running in embedded mode, the driver
can still talk to other secondary drivers running inside libvirtd
if desired. This is useful, for example, to connect a VM to the
default virtual network.
The secondary drivers can be made to operate in embedded mode as
well, however, this will require some careful consideration for each
driver to ensure they don't clash with each other. Thus in this series
only the secret driver is enabled for embedded mode. This is required
to enable use of VMs with encrypted disks, or authenticated network
block storage.
In this series we introduce a new command line tool 'virt-qemu-run'
which is a really simple tool for launching a VM in embedded mode.
I'm not entirely sure whether we should provide this as an official
supported tool in this way, or merely put it into the 'examples'
directory as demo-ware.
With testing of the virt-qemu-run tool we can immediately see what the
next important thing to tackle is: performance. We have not really cared
too much about the startup performance of libvirtd as this is a one time
cost when the mgmt application connects. We did none the less cache
capabilities because probing caps for 30 QEMU binaries takes a long time.
Even with this caching it takes an unacceptably long time to start a VM
in embedded mode. About 100 ms to open the embedded QEMU driver,
assuming pre-cached capabilies - ~2 seconds if not cached and all 30
QEMU targets are present. Then about 300 ms to actually start the QEMU
guest.
IOW, about 400 ms to get QEMU running. NB this is measuring time from
launching the virt-run-qemu program, to the point at which the API call
'virDomainCreate' returns control. This has both libvirt & QEMU overhead
in & I don't have clear figures to distinguish, but I can see a 40 ms
delay between issuing the 'qmp_capabilities' call and getting a reply,
which is QEMU startup overead.
This is a i440fx based QEMU with a general purpose virtio-pci config
(disk, net, etc) tyupical for running a full OS. I've not tried any
kind of optimized QEMU config with microvm.
I've already started on measuring & optimizing & identified several key
areas that can be addressed, but it is all ultimately about not doing
work before we need the answers from that work (which often means we
will never do the work at all).
For example, we shouldn't probe all 30 QEMU's upfront. If the app is
only going to create an x86_64 KVM guest we should only care about that
1 QEMU. This is painful because parsing any guest XML requires a
virCapsPtr which in turn causes probing of every QEMU binary. I've got
in progress patches to eliminate virCapsPtr almost entirely and work
directly with the virQEMUCapsPtr instead.
It is possible we'll want to use a different file format for storing
the cached QEMU capabilities, and the CPU feature/model info. Parsing
this XML is a non-negligible time sink. A binary format is likely way
quicker, especially if its designed to be just mmap'able for direct
read. To be investigated...
We shouldn't probe for whether host PM suspend is possible unless
someone wants that info, or tries to issue that API call.
After starting QEMU we spend 150-200 ms issuing a massive number of
qom-get calls to check whether QEMU enabled each individual CPU feature
flag. We only need this info if someone asks for the live XML or we
intend to live migrate etc. So we shouldn't issue these qom-get calls in
the "hot path" of QEMU startup. It can be done later in a non-time
critical point. Also the QEMU API for this is horribly inefficient to
require so many qom-get calls.
There's more but I won't talk about it now. Suffice to say that I think
we can get libvirt overhead down to less than 100 ms fairly easily and
probably even down to less than 50 ms without much effort.
The exact figure will depend on what libvirt features you want enabled,
and how much work we want/need to put into optimization. We'll want to
fix the really gross mistakes & slow downs, but we'll want guidance from
likely users as to their VM startup targets to decide how much work
needs investing.
This optimization will ultimately help non-embedded QEMU mode too,
making it faster to respond & start.
Changed in v3:
- Rebased to master
- Merge some simple acked patches
Changed in v2:
- Use a simplified directory layout for embedded mode. Previously we
just put a dir prefix onto the normal paths. This has the downside
that the embedded drivers paths are needlessly different for
privileged vs unprivileged user. It also results in very long paths
which can be a problem for the UNIX socket name length limits.
- Also ported the secret driver to support embedded mode
- Check to validate that the event loop is registered.
- Add virt-qemu-run tool for embedded usage.
- Added docs for the qemu & secret driver explaining embedded mode
Daniel P. Berrangé (5):
libvirt: pass a directory path into drivers for embedded usage
libvirt: support an "embed" URI path selector for opening drivers
qemu: add support for running QEMU driver in embedded mode
secrets: add support for running secret driver in embedded mode
qemu: introduce a new "virt-qemu-run" program
build-aux/syntax-check.mk | 2 +-
docs/Makefile.am | 5 +
docs/drivers.html.in | 1 +
docs/drvqemu.html.in | 84 +++++++
docs/drvsecret.html.in | 82 ++++++
docs/manpages/index.rst | 1 +
docs/manpages/virt-qemu-run.rst | 114 +++++++++
libvirt.spec.in | 2 +
src/Makefile.am | 1 +
src/driver-state.h | 2 +
src/driver.h | 2 +
src/interface/interface_backend_netcf.c | 7 +
src/interface/interface_backend_udev.c | 7 +
src/libvirt.c | 93 ++++++-
src/libvirt_internal.h | 4 +-
src/libxl/libxl_driver.c | 7 +
src/lxc/lxc_driver.c | 8 +
src/network/bridge_driver.c | 7 +
src/node_device/node_device_hal.c | 7 +
src/node_device/node_device_udev.c | 7 +
src/nwfilter/nwfilter_driver.c | 7 +
src/qemu/Makefile.inc.am | 13 +
src/qemu/qemu_conf.c | 38 ++-
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 21 +-
src/qemu/qemu_process.c | 15 +-
src/qemu/qemu_shim.c | 322 ++++++++++++++++++++++++
src/remote/remote_daemon.c | 1 +
src/remote/remote_driver.c | 1 +
src/secret/secret_driver.c | 41 ++-
src/storage/storage_driver.c | 7 +
src/vz/vz_driver.c | 7 +
tests/domaincapstest.c | 2 +-
tests/testutilsqemu.c | 3 +-
34 files changed, 901 insertions(+), 26 deletions(-)
create mode 100644 docs/drvsecret.html.in
create mode 100644 docs/manpages/virt-qemu-run.rst
create mode 100644 src/qemu/qemu_shim.c
--
2.23.0
4 years, 11 months
[libvirt] [PATCH 00/19] qemu: Add support for backups in combination with snapshots
by Peter Krempa
IMPORTANT:
This does NOT add support for merging the bitmaps during block jobs, so
manual deletion of snapshots will corrupt the incremental metadata!.
Allow combining snapshots and backups. During a snapshot we create a
bitmap for any active persistent bitmap to continue tracking the bitmaps
properly (as qemu doesn't support creating a dirty bitmap from the
allocation map). This also means that it works only for an active VM
since there also isn't a way to do it via qemu-img.
Thus a workaround is to start a VM as paused if this is required for
offline VMs.
We also now can merge bitmaps accross the backing chains.
You can fetch the changes at:
git fetch https://gitlab.com/pipo.sk/libvirt.git backup-snapshots
Peter Krempa (19):
virsh: Add QMP command wrapping for 'qemu-monitor-command'
virsh: Allow extracting 'return' section of QMP command in
'qemu-monitor-command'
qemu: monitor: Extract data about dirty-bimaps in
qemuMonitorBlockGetNamedNodeData
qemu: monitor: Extract internals of
qemuMonitorJSONBlockGetNamedNodeData
tests: qemublock: Add test for bitmap detection
tests: qemublocktest: Add a syntetic test case for bitmap detection
qemu: Check for explicit failure of qemuBlockSnapshotAddBlockdev
qemu: snapshot: Fold formatting of snapshot transaction into prepare
func
qemu: monitor: Add 'granularity' parameter for block-dirty-bitmap-add
qemu: snapshot: Propagate active bitmaps through external snapshots
tests: qemublock: Add test case for detecting bitmaps as we create
snapshots
qemu: backup: Return 'def' instead of 'obj' from
qemuBackupBeginCollectIncrementalCheckpoints
qemu: backup: Extract calculations of bitmaps to merge for incremental
backup
qemu: backup: Propagate bitmap metadata into
qemuBackupDiskPrepareOneBitmapsChain
qemu: backup: Export qemuBackupDiskPrepareOneBitmapsChain for tests
tests: qemublock: Add testing of bitmap merging for incremental
backups
qemu: block: Introduce qemuBlockNamedNodeDataGetBitmapByName
qemu: backup: Merge bitmaps accross the backing chain
tests: qemublock: Add tests for cross-snapshot incremental backups
docs/manpages/virsh.rst | 27 +-
src/qemu/qemu_backup.c | 145 ++-
src/qemu/qemu_backup.h | 7 +
src/qemu/qemu_block.c | 32 +
src/qemu/qemu_block.h | 5 +
src/qemu/qemu_checkpoint.c | 2 +-
src/qemu/qemu_driver.c | 84 +-
src/qemu/qemu_monitor.c | 6 +-
src/qemu/qemu_monitor.h | 18 +-
src/qemu/qemu_monitor_json.c | 96 +-
src/qemu/qemu_monitor_json.h | 6 +-
tests/qemublocktest.c | 241 +++++
.../backupmerge/basic-deep-out.json | 22 +
.../backupmerge/basic-flat-out.json | 6 +
.../backupmerge/basic-intermediate-out.json | 10 +
.../backupmerge/snapshot-deep-out.json | 38 +
.../backupmerge/snapshot-flat-out.json | 6 +
.../snapshot-intermediate-out.json | 14 +
tests/qemublocktestdata/bitmap/basic.json | 117 +++
tests/qemublocktestdata/bitmap/basic.out | 6 +
tests/qemublocktestdata/bitmap/snapshots.json | 836 ++++++++++++++++++
tests/qemublocktestdata/bitmap/snapshots.out | 14 +
tests/qemublocktestdata/bitmap/synthetic.json | 118 +++
tests/qemublocktestdata/bitmap/synthetic.out | 6 +
tests/qemumonitorjsontest.c | 2 +-
tools/virsh-domain.c | 76 +-
26 files changed, 1845 insertions(+), 95 deletions(-)
create mode 100644 tests/qemublocktestdata/backupmerge/basic-deep-out.json
create mode 100644 tests/qemublocktestdata/backupmerge/basic-flat-out.json
create mode 100644 tests/qemublocktestdata/backupmerge/basic-intermediate-out.json
create mode 100644 tests/qemublocktestdata/backupmerge/snapshot-deep-out.json
create mode 100644 tests/qemublocktestdata/backupmerge/snapshot-flat-out.json
create mode 100644 tests/qemublocktestdata/backupmerge/snapshot-intermediate-out.json
create mode 100644 tests/qemublocktestdata/bitmap/basic.json
create mode 100644 tests/qemublocktestdata/bitmap/basic.out
create mode 100644 tests/qemublocktestdata/bitmap/snapshots.json
create mode 100644 tests/qemublocktestdata/bitmap/snapshots.out
create mode 100644 tests/qemublocktestdata/bitmap/synthetic.json
create mode 100644 tests/qemublocktestdata/bitmap/synthetic.out
--
2.23.0
4 years, 11 months
[libvirt] [PATCH v3] driver: Include source as a flag to virDomainGetHostname
by Julio Faracco
There is a lots of possibilities to retrieve hostname information from
domain. Libvirt could use lease information from dnsmasq to get current
hostname too. QEMU supports QEMU-agent but it can use lease source. See
'domifaddr' as an example.
This commit still adds lease options for QEMU. It will get the first
hostname available from domain networks.
This case, QEMU driver has a default section inside switch to keep
compatibility. So, if someone call 'domhostname' without specifying
source, it will get the default option. Some other drivers like LXC and
OpenVZ supports only one type, virCheckFlags will handle this case.
Signed-off-by: Julio Faracco <jcfaracco(a)gmail.com>
---
v1-v2: Moving sources into flags.
v2-v3: Applying Michal's suggestions.
---
docs/manpages/virsh.rst | 7 ++-
include/libvirt/libvirt-domain.h | 5 ++
src/lxc/lxc_driver.c | 78 ++++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 76 +++++++++++++++++++++++++++----
tools/virsh-completer-domain.c | 17 +++++++
tools/virsh-completer-domain.h | 4 ++
tools/virsh-domain.c | 26 ++++++++++-
7 files changed, 201 insertions(+), 12 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index fea0527caf..ba483d4d00 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -1797,10 +1797,15 @@ domhostname
.. code-block::
- domhostname domain
+ domhostname domain [--source lease|agent]
Returns the hostname of a domain, if the hypervisor makes it available.
+The *--source* argument specifies what data source to use for the
+hostnames, currently 'lease' to read DHCP leases or 'agent' to query
+the guest OS via an agent. If unspecified, driver returns the default
+method available (some drivers support only one type of source).
+
domid
-----
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index e60003978a..666c1875cc 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4833,6 +4833,11 @@ typedef struct _virTypedParameter virMemoryParameter;
*/
typedef virMemoryParameter *virMemoryParameterPtr;
+typedef enum {
+ VIR_DOMAIN_GET_HOSTNAME_LEASE = (1 << 0), /* Parse DHCP lease file */
+ VIR_DOMAIN_GET_HOSTNAME_AGENT = (1 << 1), /* Query qemu guest agent */
+} virDomainGetHostnameFlags;
+
typedef enum {
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE = 0, /* Parse DHCP lease file */
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT = 1, /* Query qemu guest agent */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 780c6ed4a2..2dac730e70 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -5291,6 +5291,83 @@ lxcDomainGetCPUStats(virDomainPtr dom,
}
+static char *
+lxcDomainGetHostname(virDomainPtr dom,
+ unsigned int flags)
+{
+ virLXCDriverPtr driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ char macaddr[VIR_MAC_STRING_BUFLEN];
+ g_autoptr(virConnect) conn = NULL;
+ virNetworkDHCPLeasePtr *leases = NULL;
+ int n_leases;
+ size_t i, j;
+ char *hostname = NULL;
+
+ virCheckFlags(VIR_DOMAIN_GET_HOSTNAME_LEASE, NULL);
+
+ if (!(vm = lxcDomObjFromDomain(dom)))
+ return NULL;
+
+ if (virDomainGetHostnameEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (virLXCDomainObjBeginJob(driver, vm, LXC_JOB_QUERY) < 0)
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0)
+ goto endjob;
+
+ if (!(conn = virGetConnectNetwork()))
+ goto endjob;
+
+ for (i = 0; i < vm->def->nnets; i++) {
+ g_autoptr(virNetwork) network = NULL;
+
+ if (vm->def->nets[i]->type != VIR_DOMAIN_NET_TYPE_NETWORK)
+ continue;
+
+ virMacAddrFormat(&(vm->def->nets[i]->mac), macaddr);
+ network = virNetworkLookupByName(conn,
+ vm->def->nets[i]->data.network.name);
+
+ if (!network)
+ goto endjob;
+
+ if ((n_leases = virNetworkGetDHCPLeases(network, macaddr,
+ &leases, 0)) < 0)
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("There is no available hostname %d"),
+ flags);
+
+ for (j = 0; j < n_leases; j++) {
+ virNetworkDHCPLeasePtr lease = leases[j];
+ if (lease->hostname) {
+ hostname = g_strdup(lease->hostname);
+
+ for (j = 0; j < n_leases; j++)
+ virNetworkDHCPLeaseFree(leases[j]);
+
+ VIR_FREE(leases);
+
+ goto endjob;
+ }
+
+ virNetworkDHCPLeaseFree(lease);
+ }
+
+ VIR_FREE(leases);
+ }
+
+ endjob:
+ virLXCDomainObjEndJob(driver, vm);
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return hostname;
+}
+
+
static int
lxcNodeGetFreePages(virConnectPtr conn,
unsigned int npages,
@@ -5436,6 +5513,7 @@ static virHypervisorDriver lxcHypervisorDriver = {
.domainSetMetadata = lxcDomainSetMetadata, /* 1.1.3 */
.domainGetMetadata = lxcDomainGetMetadata, /* 1.1.3 */
.domainGetCPUStats = lxcDomainGetCPUStats, /* 1.2.2 */
+ .domainGetHostname = lxcDomainGetHostname, /* 6.0.0 */
.nodeGetMemoryParameters = lxcNodeGetMemoryParameters, /* 0.10.2 */
.nodeSetMemoryParameters = lxcNodeSetMemoryParameters, /* 0.10.2 */
.domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ec8faf384c..d8ed859f70 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20280,9 +20280,19 @@ qemuDomainGetHostname(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
qemuAgentPtr agent;
+ char macaddr[VIR_MAC_STRING_BUFLEN];
+ g_autoptr(virConnect) conn = NULL;
+ virNetworkDHCPLeasePtr *leases = NULL;
+ int n_leases;
+ size_t i, j;
char *hostname = NULL;
- virCheckFlags(0, NULL);
+ virCheckFlags(VIR_DOMAIN_GET_HOSTNAME_LEASE |
+ VIR_DOMAIN_GET_HOSTNAME_AGENT, NULL);
+
+ VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_GET_HOSTNAME_LEASE,
+ VIR_DOMAIN_GET_HOSTNAME_AGENT,
+ NULL);
if (!(vm = qemuDomainObjFromDomain(dom)))
return NULL;
@@ -20290,18 +20300,66 @@ qemuDomainGetHostname(virDomainPtr dom,
if (virDomainGetHostnameEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
- if (qemuDomainObjBeginAgentJob(driver, vm, QEMU_AGENT_JOB_QUERY) < 0)
- goto cleanup;
-
if (virDomainObjCheckActive(vm) < 0)
goto endjob;
- if (!qemuDomainAgentAvailable(vm, true))
- goto endjob;
+ switch (flags) {
+ default:
+ case VIR_DOMAIN_GET_HOSTNAME_AGENT:
+ if (qemuDomainObjBeginAgentJob(driver, vm, QEMU_AGENT_JOB_QUERY) < 0)
+ goto cleanup;
- agent = qemuDomainObjEnterAgent(vm);
- ignore_value(qemuAgentGetHostname(agent, &hostname));
- qemuDomainObjExitAgent(vm, agent);
+ if (!qemuDomainAgentAvailable(vm, true))
+ goto endjob;
+
+ agent = qemuDomainObjEnterAgent(vm);
+ ignore_value(qemuAgentGetHostname(agent, &hostname));
+ qemuDomainObjExitAgent(vm, agent);
+
+ break;
+ case VIR_DOMAIN_GET_HOSTNAME_LEASE:
+ if (!(conn = virGetConnectNetwork()))
+ goto endjob;
+
+ for (i = 0; i < vm->def->nnets; i++) {
+ g_autoptr(virNetwork) network = NULL;
+
+ if (vm->def->nets[i]->type != VIR_DOMAIN_NET_TYPE_NETWORK)
+ continue;
+
+ virMacAddrFormat(&(vm->def->nets[i]->mac), macaddr);
+ network = virNetworkLookupByName(conn,
+ vm->def->nets[i]->data.network.name);
+
+ if (!network)
+ goto endjob;
+
+ if ((n_leases = virNetworkGetDHCPLeases(network, macaddr,
+ &leases, 0)) < 0)
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("There is no available hostname %d"),
+ flags);
+
+ for (j = 0; j < n_leases; j++) {
+ virNetworkDHCPLeasePtr lease = leases[j];
+ if (lease->hostname) {
+ hostname = g_strdup(lease->hostname);
+
+ for (j = 0; j < n_leases; j++)
+ virNetworkDHCPLeaseFree(leases[j]);
+
+ VIR_FREE(leases);
+
+ goto endjob;
+ }
+
+ virNetworkDHCPLeaseFree(lease);
+ }
+
+ VIR_FREE(leases);
+ }
+ break;
+ }
endjob:
qemuDomainObjEndAgentJob(vm);
diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c
index 0311ee50d0..67e67d485a 100644
--- a/tools/virsh-completer-domain.c
+++ b/tools/virsh-completer-domain.c
@@ -296,3 +296,20 @@ virshDomainShutdownModeCompleter(vshControl *ctl,
return virshCommaStringListComplete(mode, modes);
}
+
+
+char **
+virshDomainGetHosnameSourcesCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int flags)
+{
+ const char *sources[] = {"lease", "agent", NULL};
+ const char *source = NULL;
+
+ virCheckFlags(0, NULL);
+
+ if (vshCommandOptStringQuiet(ctl, cmd, "source", &source) < 0)
+ return NULL;
+
+ return virshCommaStringListComplete(source, sources);
+}
diff --git a/tools/virsh-completer-domain.h b/tools/virsh-completer-domain.h
index 083ab327cc..ad1b37a255 100644
--- a/tools/virsh-completer-domain.h
+++ b/tools/virsh-completer-domain.h
@@ -53,3 +53,7 @@ char ** virshDomainDeviceAliasCompleter(vshControl *ctl,
char ** virshDomainShutdownModeCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
+
+char ** virshDomainGetHosnameSourcesCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int flags);
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 9d4cdd26dd..73e6780116 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -11743,6 +11743,11 @@ static const vshCmdInfo info_domhostname[] = {
static const vshCmdOptDef opts_domhostname[] = {
VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE),
+ {.name = "source",
+ .type = VSH_OT_STRING,
+ .flags = VSH_OFLAG_NONE,
+ .completer = virshDomainGetHosnameSourcesCompleter,
+ .help = N_("address source: 'lease' or 'agent'")},
{.name = NULL}
};
@@ -11752,21 +11757,38 @@ cmdDomHostname(vshControl *ctl, const vshCmd *cmd)
char *hostname;
virDomainPtr dom;
bool ret = false;
+ const char *sourcestr = NULL;
+ int flags = 0; /* Use default value. Drivers can have its own default. */
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
- hostname = virDomainGetHostname(dom, 0);
+ if (vshCommandOptStringReq(ctl, cmd, "source", &sourcestr) < 0)
+ goto error;
+
+ if (sourcestr) {
+ if (STREQ(sourcestr, "lease")) {
+ flags |= VIR_DOMAIN_GET_HOSTNAME_LEASE;
+ } else if (STREQ(sourcestr, "agent")) {
+ flags |= VIR_DOMAIN_GET_HOSTNAME_AGENT;
+ } else {
+ vshError(ctl, _("Unknown data source '%s'"), sourcestr);
+ goto error;
+ }
+ }
+
+ hostname = virDomainGetHostname(dom, flags);
if (hostname == NULL) {
vshError(ctl, "%s", _("failed to get hostname"));
goto error;
}
vshPrint(ctl, "%s\n", hostname);
+
+ VIR_FREE(hostname);
ret = true;
error:
- VIR_FREE(hostname);
virshDomainFree(dom);
return ret;
}
--
2.20.1
4 years, 11 months
[libvirt] [PATCH 0/5] introduce support for CPU dies in host/guest topology
by Daniel P. Berrangé
Latest generation CPUs (CascadeLake-AP) support a new topology level
known as a 'die', sitting between a socket and a core.
QEMU supports this with -smp arg since 4.1.0
Linux can report this via /sys/devices/system/cpu/cpuNNN/topology
via 'die_id' and 'die_cpus' and 'die_cpus_list' files since 5.2
This series adds support for <topology> in guest XML to have a new
'dies' parameter, passed to QEMU, which defaults to '1' if omitted.
It extends host capabilities so that NUMA topology reports a new
'die_id' attribute
We can't expand 'virNodeInfoPtr' struct to have a die field, so
this will remain forever reporting 'cores' as being 'dies * cores'.
The <topology> in host capabilities XML is an interesting question.
If we are strict with our API semantics we would *not* add a 'dies'
parameter with any value other than '1' to <topology> in the host
capabilities. If we reported a value other than 1, then any existing
apps which multiple sockets*cores*threads will get the wrong total
CPU count.
We already know <topology> is broken by design for asymetric
hardware, so we could simply document that it will forever be broken
wrt to CPU dies too. In this case we might be better to not even
report 'dies=1', just leave out the attr entirely.
Interestingly though, <topology> is already more broken than it
should be. For a VM with -smp 12,sockets=2,dies=3,cores=2,threads=1
it is reporting <topology sockets=1 dies=1 cores=12 threads=1>.
It should at least do <topology sockets=2 dies=1 cores=6 threads=1>.
I suspect the presence of dies is confusing the really incredibly
horrible logic in virHostCPUGetInfoLinux. This will also impact
virNodeInfoPtr data.
So even if we don't report dies, I think we still have a bug that
needs fixing here for the coarse node topology.
I'm also confused about what I see with EPYC. IIUC, it was supposed
to use the 'dies' concept, but in machines I've tested, Linux never
reports die count other than 1. Perhaps only certain EPYC CPU
models or generations use 'dies', or perhaps Linux isn't reporting
correctly for EPYC, or perhaps I'm mislead into believeing it uses
dies.
Anyway, the upshot is I've not found any real hardware to test this
series on. I've tested it only inside a QEMU guest with the suitable
-smp arg to fake dies.
Daniel P. Berrangé (5):
conf: add support for specifying CPU "dies" parameter
conf: remove unused virCapabilitiesSetHostCPU method
qemu: add support for specifying CPU "dies" topology parameter
hostcpu: add support for reporting die_id in NUMA topology
tests: add host CPU data files for validating die_id
docs/formatcaps.html.in | 2 +-
docs/formatdomain.html.in | 14 +-
docs/schemas/capability.rng | 3 +
docs/schemas/cputypes.rng | 5 +
src/bhyve/bhyve_command.c | 5 +
src/conf/capabilities.c | 26 +-
src/conf/capabilities.h | 7 +-
src/conf/cpu_conf.c | 18 +-
src/conf/cpu_conf.h | 1 +
src/conf/domain_conf.c | 3 +-
src/cpu/cpu.c | 1 +
src/libvirt_linux.syms | 1 +
src/libvirt_private.syms | 1 -
src/libxl/libxl_capabilities.c | 1 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 12 +-
src/util/virhostcpu.c | 16 +
src/util/virhostcpu.h | 1 +
src/vmx/vmx.c | 7 +
.../x86_64-host+guest,model486-result.xml | 2 +-
.../x86_64-host+guest,models-result.xml | 2 +-
.../cputestdata/x86_64-host+guest-result.xml | 2 +-
tests/cputestdata/x86_64-host+guest.xml | 2 +-
.../x86_64-host+host-model-nofallback.xml | 2 +-
...t-Haswell-noTSX+Haswell,haswell-result.xml | 2 +-
...ell-noTSX+Haswell-noTSX,haswell-result.xml | 2 +-
...ost-Haswell-noTSX+Haswell-noTSX-result.xml | 2 +-
.../x86_64-host-worse+guest-result.xml | 2 +-
.../caps_4.1.0.x86_64.xml | 1 +
.../caps_4.2.0.aarch64.xml | 1 +
.../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 +
.../qemucapabilitiesdata/caps_4.2.0.s390x.xml | 1 +
.../caps_4.2.0.x86_64.xml | 1 +
.../ppc64-modern-bulk-result-conf.xml | 2 +-
.../ppc64-modern-bulk-result-live.xml | 2 +-
.../ppc64-modern-individual-result-conf.xml | 2 +-
.../ppc64-modern-individual-result-live.xml | 2 +-
.../x86-modern-bulk-result-conf.xml | 2 +-
.../x86-modern-bulk-result-live.xml | 2 +-
.../x86-modern-individual-add-result-conf.xml | 2 +-
.../x86-modern-individual-add-result-live.xml | 2 +-
.../x86-old-bulk-result-conf.xml | 2 +-
.../x86-old-bulk-result-live.xml | 2 +-
.../cpu-hotplug-granularity.xml | 2 +-
.../qemuxml2argvdata/cpu-hotplug-startup.xml | 2 +-
tests/qemuxml2argvdata/cpu-numa-disjoint.xml | 2 +-
.../qemuxml2argvdata/cpu-numa-disordered.xml | 2 +-
tests/qemuxml2argvdata/cpu-numa-memshared.xml | 2 +-
.../cpu-numa-no-memory-element.xml | 2 +-
tests/qemuxml2argvdata/cpu-numa1.xml | 2 +-
tests/qemuxml2argvdata/cpu-numa2.xml | 2 +-
tests/qemuxml2argvdata/cpu-numa3.xml | 2 +-
tests/qemuxml2argvdata/cpu-topology1.xml | 2 +-
tests/qemuxml2argvdata/cpu-topology2.xml | 2 +-
tests/qemuxml2argvdata/cpu-topology3.xml | 2 +-
.../fd-memory-no-numa-topology.xml | 2 +-
.../fd-memory-numa-topology.xml | 2 +-
.../fd-memory-numa-topology2.xml | 2 +-
.../fd-memory-numa-topology3.xml | 2 +-
.../graphics-spice-timeout.xml | 2 +-
.../hugepages-nvdimm.x86_64-latest.args | 2 +-
tests/qemuxml2argvdata/hugepages-nvdimm.xml | 2 +-
...memory-default-hugepage.x86_64-latest.args | 2 +-
.../memfd-memory-default-hugepage.xml | 2 +-
.../memfd-memory-numa.x86_64-latest.args | 2 +-
tests/qemuxml2argvdata/memfd-memory-numa.xml | 2 +-
tests/qemuxml2argvdata/memory-align-fail.xml | 2 +-
.../memory-hotplug-dimm-addr.xml | 2 +-
.../qemuxml2argvdata/memory-hotplug-dimm.xml | 2 +-
...y-hotplug-nvdimm-access.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm-access.xml | 2 +-
...ry-hotplug-nvdimm-align.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm-align.xml | 2 +-
...ry-hotplug-nvdimm-label.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm-label.xml | 2 +-
...ory-hotplug-nvdimm-pmem.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm-pmem.xml | 2 +-
...hotplug-nvdimm-readonly.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm-readonly.xml | 2 +-
.../memory-hotplug-nvdimm.x86_64-latest.args | 2 +-
.../memory-hotplug-nvdimm.xml | 2 +-
tests/qemuxml2argvdata/memory-hotplug.xml | 2 +-
.../numad-auto-memory-vcpu-cpuset.xml | 2 +-
...to-memory-vcpu-no-cpuset-and-placement.xml | 2 +-
.../numad-auto-vcpu-no-numatune.xml | 2 +-
...d-auto-vcpu-static-numatune-no-nodeset.xml | 2 +-
.../numad-auto-vcpu-static-numatune.xml | 2 +-
.../numad-static-memory-auto-vcpu.xml | 2 +-
.../numad-static-vcpu-no-numatune.xml | 2 +-
tests/qemuxml2argvdata/numad.xml | 2 +-
.../numatune-auto-nodeset-invalid.xml | 2 +-
.../numatune-memory-invalid-nodeset.xml | 2 +-
tests/qemuxml2argvdata/numatune-memory.xml | 2 +-
.../pci-expander-bus-bad-machine.xml | 2 +-
tests/qemuxml2argvdata/pci-expander-bus.xml | 2 +-
.../pcie-expander-bus-bad-bus.xml | 2 +-
.../pcie-expander-bus-bad-machine.xml | 2 +-
tests/qemuxml2argvdata/pcie-expander-bus.xml | 2 +-
.../pseries-default-phb-numa-node.xml | 2 +-
.../pseries-phb-numa-node.xml | 2 +-
tests/qemuxml2argvdata/smp-dies.args | 29 ++
tests/qemuxml2argvdata/smp-dies.xml | 33 ++
tests/qemuxml2argvdata/smp.xml | 2 +-
tests/qemuxml2argvtest.c | 1 +
.../qemuxml2xmloutdata/cpu-numa-disjoint.xml | 2 +-
.../cpu-numa-disordered.xml | 2 +-
.../qemuxml2xmloutdata/cpu-numa-memshared.xml | 2 +-
.../cpu-numa-no-memory-element.xml | 2 +-
tests/qemuxml2xmloutdata/cpu-numa1.xml | 2 +-
tests/qemuxml2xmloutdata/cpu-numa2.xml | 2 +-
.../graphics-spice-timeout.xml | 2 +-
.../memory-hotplug-dimm.xml | 2 +-
tests/qemuxml2xmloutdata/memory-hotplug.xml | 2 +-
.../numad-auto-memory-vcpu-cpuset.xml | 2 +-
...to-memory-vcpu-no-cpuset-and-placement.xml | 2 +-
.../numad-auto-vcpu-no-numatune.xml | 2 +-
.../numad-static-vcpu-no-numatune.xml | 2 +-
tests/qemuxml2xmloutdata/pci-expander-bus.xml | 2 +-
.../qemuxml2xmloutdata/pcie-expander-bus.xml | 2 +-
.../pseries-phb-numa-node.xml | 2 +-
tests/qemuxml2xmloutdata/smp.xml | 2 +-
.../linux-basic-dies/system/cpu | 1 +
.../linux-basic-dies/system/node | 1 +
.../vircaps2xmldata/vircaps-aarch64-basic.xml | 32 +-
.../vircaps-x86_64-basic-dies.xml | 35 ++
.../vircaps2xmldata/vircaps-x86_64-basic.xml | 32 +-
.../vircaps2xmldata/vircaps-x86_64-caches.xml | 16 +-
.../vircaps-x86_64-resctrl-cdp.xml | 24 +-
.../vircaps-x86_64-resctrl-cmt.xml | 24 +-
.../vircaps-x86_64-resctrl-fake-feature.xml | 24 +-
.../vircaps-x86_64-resctrl-skx-twocaches.xml | 2 +-
.../vircaps-x86_64-resctrl-skx.xml | 2 +-
.../vircaps-x86_64-resctrl.xml | 24 +-
tests/vircaps2xmltest.c | 1 +
.../cpu/cpu0/topology/core_cpus | 1 +
.../cpu/cpu0/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu0/topology/core_id | 1 +
.../cpu/cpu0/topology/core_siblings | 1 +
.../cpu/cpu0/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu0/topology/die_cpus | 1 +
.../cpu/cpu0/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu0/topology/die_id | 1 +
.../cpu/cpu0/topology/package_cpus | 1 +
.../cpu/cpu0/topology/package_cpus_list | 1 +
.../cpu/cpu0/topology/physical_package_id | 1 +
.../cpu/cpu0/topology/thread_siblings | 1 +
.../cpu/cpu0/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu1/online | 1 +
.../cpu/cpu1/topology/core_cpus | 1 +
.../cpu/cpu1/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu1/topology/core_id | 1 +
.../cpu/cpu1/topology/core_siblings | 1 +
.../cpu/cpu1/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu1/topology/die_cpus | 1 +
.../cpu/cpu1/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu1/topology/die_id | 1 +
.../cpu/cpu1/topology/package_cpus | 1 +
.../cpu/cpu1/topology/package_cpus_list | 1 +
.../cpu/cpu1/topology/physical_package_id | 1 +
.../cpu/cpu1/topology/thread_siblings | 1 +
.../cpu/cpu1/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu10/online | 1 +
.../cpu/cpu10/topology/core_cpus | 1 +
.../cpu/cpu10/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu10/topology/core_id | 1 +
.../cpu/cpu10/topology/core_siblings | 1 +
.../cpu/cpu10/topology/core_siblings_list | 1 +
.../cpu/cpu10/topology/die_cpus | 1 +
.../cpu/cpu10/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu10/topology/die_id | 1 +
.../cpu/cpu10/topology/package_cpus | 1 +
.../cpu/cpu10/topology/package_cpus_list | 1 +
.../cpu/cpu10/topology/physical_package_id | 1 +
.../cpu/cpu10/topology/thread_siblings | 1 +
.../cpu/cpu10/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu11/online | 1 +
.../cpu/cpu11/topology/core_cpus | 1 +
.../cpu/cpu11/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu11/topology/core_id | 1 +
.../cpu/cpu11/topology/core_siblings | 1 +
.../cpu/cpu11/topology/core_siblings_list | 1 +
.../cpu/cpu11/topology/die_cpus | 1 +
.../cpu/cpu11/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu11/topology/die_id | 1 +
.../cpu/cpu11/topology/package_cpus | 1 +
.../cpu/cpu11/topology/package_cpus_list | 1 +
.../cpu/cpu11/topology/physical_package_id | 1 +
.../cpu/cpu11/topology/thread_siblings | 1 +
.../cpu/cpu11/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu2/online | 1 +
.../cpu/cpu2/topology/core_cpus | 1 +
.../cpu/cpu2/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu2/topology/core_id | 1 +
.../cpu/cpu2/topology/core_siblings | 1 +
.../cpu/cpu2/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu2/topology/die_cpus | 1 +
.../cpu/cpu2/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu2/topology/die_id | 1 +
.../cpu/cpu2/topology/package_cpus | 1 +
.../cpu/cpu2/topology/package_cpus_list | 1 +
.../cpu/cpu2/topology/physical_package_id | 1 +
.../cpu/cpu2/topology/thread_siblings | 1 +
.../cpu/cpu2/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu3/online | 1 +
.../cpu/cpu3/topology/core_cpus | 1 +
.../cpu/cpu3/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu3/topology/core_id | 1 +
.../cpu/cpu3/topology/core_siblings | 1 +
.../cpu/cpu3/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu3/topology/die_cpus | 1 +
.../cpu/cpu3/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu3/topology/die_id | 1 +
.../cpu/cpu3/topology/package_cpus | 1 +
.../cpu/cpu3/topology/package_cpus_list | 1 +
.../cpu/cpu3/topology/physical_package_id | 1 +
.../cpu/cpu3/topology/thread_siblings | 1 +
.../cpu/cpu3/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu4/online | 1 +
.../cpu/cpu4/topology/core_cpus | 1 +
.../cpu/cpu4/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu4/topology/core_id | 1 +
.../cpu/cpu4/topology/core_siblings | 1 +
.../cpu/cpu4/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu4/topology/die_cpus | 1 +
.../cpu/cpu4/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu4/topology/die_id | 1 +
.../cpu/cpu4/topology/package_cpus | 1 +
.../cpu/cpu4/topology/package_cpus_list | 1 +
.../cpu/cpu4/topology/physical_package_id | 1 +
.../cpu/cpu4/topology/thread_siblings | 1 +
.../cpu/cpu4/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu5/online | 1 +
.../cpu/cpu5/topology/core_cpus | 1 +
.../cpu/cpu5/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu5/topology/core_id | 1 +
.../cpu/cpu5/topology/core_siblings | 1 +
.../cpu/cpu5/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu5/topology/die_cpus | 1 +
.../cpu/cpu5/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu5/topology/die_id | 1 +
.../cpu/cpu5/topology/package_cpus | 1 +
.../cpu/cpu5/topology/package_cpus_list | 1 +
.../cpu/cpu5/topology/physical_package_id | 1 +
.../cpu/cpu5/topology/thread_siblings | 1 +
.../cpu/cpu5/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu6/online | 1 +
.../cpu/cpu6/topology/core_cpus | 1 +
.../cpu/cpu6/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu6/topology/core_id | 1 +
.../cpu/cpu6/topology/core_siblings | 1 +
.../cpu/cpu6/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu6/topology/die_cpus | 1 +
.../cpu/cpu6/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu6/topology/die_id | 1 +
.../cpu/cpu6/topology/package_cpus | 1 +
.../cpu/cpu6/topology/package_cpus_list | 1 +
.../cpu/cpu6/topology/physical_package_id | 1 +
.../cpu/cpu6/topology/thread_siblings | 1 +
.../cpu/cpu6/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu7/online | 1 +
.../cpu/cpu7/topology/core_cpus | 1 +
.../cpu/cpu7/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu7/topology/core_id | 1 +
.../cpu/cpu7/topology/core_siblings | 1 +
.../cpu/cpu7/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu7/topology/die_cpus | 1 +
.../cpu/cpu7/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu7/topology/die_id | 1 +
.../cpu/cpu7/topology/package_cpus | 1 +
.../cpu/cpu7/topology/package_cpus_list | 1 +
.../cpu/cpu7/topology/physical_package_id | 1 +
.../cpu/cpu7/topology/thread_siblings | 1 +
.../cpu/cpu7/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu8/online | 1 +
.../cpu/cpu8/topology/core_cpus | 1 +
.../cpu/cpu8/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu8/topology/core_id | 1 +
.../cpu/cpu8/topology/core_siblings | 1 +
.../cpu/cpu8/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu8/topology/die_cpus | 1 +
.../cpu/cpu8/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu8/topology/die_id | 1 +
.../cpu/cpu8/topology/package_cpus | 1 +
.../cpu/cpu8/topology/package_cpus_list | 1 +
.../cpu/cpu8/topology/physical_package_id | 1 +
.../cpu/cpu8/topology/thread_siblings | 1 +
.../cpu/cpu8/topology/thread_siblings_list | 1 +
.../linux-with-die/cpu/cpu9/online | 1 +
.../cpu/cpu9/topology/core_cpus | 1 +
.../cpu/cpu9/topology/core_cpus_list | 1 +
.../linux-with-die/cpu/cpu9/topology/core_id | 1 +
.../cpu/cpu9/topology/core_siblings | 1 +
.../cpu/cpu9/topology/core_siblings_list | 1 +
.../linux-with-die/cpu/cpu9/topology/die_cpus | 1 +
.../cpu/cpu9/topology/die_cpus_list | 1 +
.../linux-with-die/cpu/cpu9/topology/die_id | 1 +
.../cpu/cpu9/topology/package_cpus | 1 +
.../cpu/cpu9/topology/package_cpus_list | 1 +
.../cpu/cpu9/topology/physical_package_id | 1 +
.../cpu/cpu9/topology/thread_siblings | 1 +
.../cpu/cpu9/topology/thread_siblings_list | 1 +
.../virhostcpudata/linux-with-die/cpu/online | 1 +
.../virhostcpudata/linux-with-die/cpu/present | 1 +
.../linux-with-die/node/node0/cpu0 | 1 +
.../linux-with-die/node/node0/cpu1 | 1 +
.../linux-with-die/node/node0/cpu10 | 1 +
.../linux-with-die/node/node0/cpu11 | 1 +
.../linux-with-die/node/node0/cpu2 | 1 +
.../linux-with-die/node/node0/cpu3 | 1 +
.../linux-with-die/node/node0/cpu4 | 1 +
.../linux-with-die/node/node0/cpu5 | 1 +
.../linux-with-die/node/node0/cpu6 | 1 +
.../linux-with-die/node/node0/cpu7 | 1 +
.../linux-with-die/node/node0/cpu8 | 1 +
.../linux-with-die/node/node0/cpu9 | 1 +
.../linux-with-die/node/node0/cpulist | 1 +
.../virhostcpudata/linux-with-die/node/online | 1 +
.../linux-with-die/node/possible | 1 +
.../linux-x86_64-with-die.cpuinfo | 324 ++++++++++++++++++
.../linux-x86_64-with-die.expected | 1 +
tests/virhostcputest.c | 1 +
.../vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml | 2 +-
.../vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml | 2 +-
324 files changed, 887 insertions(+), 228 deletions(-)
create mode 100644 tests/qemuxml2argvdata/smp-dies.args
create mode 100644 tests/qemuxml2argvdata/smp-dies.xml
create mode 120000 tests/vircaps2xmldata/linux-basic-dies/system/cpu
create mode 120000 tests/vircaps2xmldata/linux-basic-dies/system/node
create mode 100644 tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu0/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu1/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu10/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu11/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu2/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu3/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu4/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu5/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu6/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu7/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu8/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/core_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/die_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/package_cpus_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/physical_package_id
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/cpu9/topology/thread_siblings_list
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/online
create mode 100644 tests/virhostcpudata/linux-with-die/cpu/present
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu0
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu1
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu10
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu11
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu2
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu3
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu4
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu5
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu6
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu7
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu8
create mode 120000 tests/virhostcpudata/linux-with-die/node/node0/cpu9
create mode 100644 tests/virhostcpudata/linux-with-die/node/node0/cpulist
create mode 100644 tests/virhostcpudata/linux-with-die/node/online
create mode 100644 tests/virhostcpudata/linux-with-die/node/possible
create mode 100644 tests/virhostcpudata/linux-x86_64-with-die.cpuinfo
create mode 100644 tests/virhostcpudata/linux-x86_64-with-die.expected
--
2.23.0
4 years, 11 months
[libvirt] [jenkins-ci PATCH v3 0/7] Add support for gtk-vnc builds
by Daniel P. Berrangé
Support gtk-vnc and make virt-viewer depend on it
I sent this months ago & forgot to push it. Re-sending just in
case something has invalidated any patches. I've at least added
the newer distros
This time with gdk-pixbuf added and previous suggested fixes
Daniel P. Berrangé (7):
mappings: add libgcrypt
mappings: add PulseAudio
mappings: add gdk-pixbuf
guests: pull in deps for gtk-vnc project
projects: add gtk-vnc project
projects: make virt-viewer depend on gtk-vnc jobs
mappings: remove gtk-vnc2
guests/host_vars/libvirt-centos-7/main.yml | 1 +
guests/host_vars/libvirt-centos-8/main.yml | 1 +
guests/host_vars/libvirt-debian-10/main.yml | 1 +
guests/host_vars/libvirt-debian-9/main.yml | 1 +
guests/host_vars/libvirt-debian-sid/main.yml | 1 +
guests/host_vars/libvirt-fedora-30/main.yml | 3 ++
guests/host_vars/libvirt-fedora-31/main.yml | 1 +
.../host_vars/libvirt-fedora-rawhide/main.yml | 1 +
guests/host_vars/libvirt-freebsd-11/main.yml | 1 +
guests/host_vars/libvirt-freebsd-12/main.yml | 1 +
.../libvirt-freebsd-current/main.yml | 1 +
guests/host_vars/libvirt-ubuntu-1604/main.yml | 1 +
guests/host_vars/libvirt-ubuntu-1804/main.yml | 1 +
guests/playbooks/build/jobs/defaults.yml | 3 ++
.../build/projects/gtk-vnc+mingw32.yml | 12 ++++++
.../build/projects/gtk-vnc+mingw64.yml | 12 ++++++
guests/playbooks/build/projects/gtk-vnc.yml | 19 +++++++++
guests/vars/mappings.yml | 42 +++++++++++++------
guests/vars/projects/gtk-vnc+mingw32.yml | 7 ++++
guests/vars/projects/gtk-vnc+mingw64.yml | 7 ++++
guests/vars/projects/gtk-vnc.yml | 12 ++++++
guests/vars/projects/virt-viewer+mingw32.yml | 1 -
guests/vars/projects/virt-viewer+mingw64.yml | 1 -
guests/vars/projects/virt-viewer.yml | 1 -
jenkins/jobs/defaults.yaml | 3 ++
jenkins/projects/gtk-vnc+mingw32.yaml | 12 ++++++
jenkins/projects/gtk-vnc+mingw64.yaml | 12 ++++++
jenkins/projects/gtk-vnc.yaml | 15 +++++++
jenkins/projects/virt-viewer+mingw32.yaml | 4 +-
jenkins/projects/virt-viewer+mingw64.yaml | 4 +-
jenkins/projects/virt-viewer.yaml | 4 +-
31 files changed, 167 insertions(+), 19 deletions(-)
create mode 100644 guests/playbooks/build/projects/gtk-vnc+mingw32.yml
create mode 100644 guests/playbooks/build/projects/gtk-vnc+mingw64.yml
create mode 100644 guests/playbooks/build/projects/gtk-vnc.yml
create mode 100644 guests/vars/projects/gtk-vnc+mingw32.yml
create mode 100644 guests/vars/projects/gtk-vnc+mingw64.yml
create mode 100644 guests/vars/projects/gtk-vnc.yml
create mode 100644 jenkins/projects/gtk-vnc+mingw32.yaml
create mode 100644 jenkins/projects/gtk-vnc+mingw64.yaml
create mode 100644 jenkins/projects/gtk-vnc.yaml
--
2.23.0
4 years, 11 months
[libvirt] [PATCH v3 00/11] esx: various improvements
by Pino Toscano
- fix a bug in the esx VI generator
- implement connectListAllStoragePools, so
virConnectListAllStoragePools() works
- implement connectListAllNetworks, so virConnectListAllNetworks()
works
- implement storagePoolListAllVolumes, so virStoragePoolListAllVolumes()
works
- implement domainGetHostname, so virDomainGetHostname() works
- implement domainInterfaceAddresses only for
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, so
virDomainInterfaceAddresses() partially works
- improve virErrorNumber for some virReportError() calls
TODO:
- handle the comments in v2 about esxStoragePoolListAllVolumes()
Changes from v2:
- pushed patches reviewed with no changes required
- integrated the Reviewed-By in patches that required very minor
changes, will push them on request
- fixed bool/size_t error/count handling
- bumped API version numbers to 6.0.0
- fixed a bug in the esx VI generator
- implemented domainGetHostname
- implemented domainInterfaceAddresses
Pino Toscano (11):
esx: implement connectListAllStoragePools
esx: implement connectListAllNetworks
esx: split datastorePathToStorageVol helper
esx: split scsilunToStorageVol helper
esx: implement storagePoolListAllVolumes
esx: improve some of the virErrorNumber used
esx: implement domainGetHostname
esx: generator: fix free of elements in lists
esx: generator: add GuestNicInfo object
esx: implement domainInterfaceAddresses
docs: document implemented APIs in esx
docs/drvesx.html.in | 7 +
docs/news.xml | 14 ++
scripts/esx_vi_generator.py | 27 +++-
src/esx/esx_driver.c | 220 ++++++++++++++++++++++++++++
src/esx/esx_network_driver.c | 68 ++++++++-
src/esx/esx_storage_backend_iscsi.c | 202 +++++++++++++++++++++----
src/esx/esx_storage_backend_vmfs.c | 220 ++++++++++++++++++++++++++--
src/esx/esx_storage_driver.c | 84 +++++++++++
src/esx/esx_util.c | 4 +-
src/esx/esx_vi.c | 36 ++---
src/esx/esx_vi_generator.input | 54 +++++++
11 files changed, 862 insertions(+), 74 deletions(-)
--
2.24.1
4 years, 11 months
[libvirt] [PATCH] Remove phyp driver
by Cole Robinson
The phyp driver was added in 2009 and does not appear to have had any
real feature change since 2011. There's virtually no evidence online
of users actually using it. IMO it's time to kill it.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
I raised this in 3.5 years ago:
https://www.redhat.com/archives/libvir-list/2016-April/msg01060.html
Not much on phyp/ side has changed since then, except dozens of dev
patches transitioning the code forward.
That mail also mentions xenapi and hyperv. hyperv saw signs of life
afterwards and is still around. xenapi has been removed, along with uml.
Considering the amount of code transitions we are currently undergoing
(gnulib, glib, memory auto cleanup, etc), phyp/ will probably have an
uptick of dev energy in the medium term. Let's bite the bullet and
remove it!
docs/aclpolkit.html.in | 4 -
docs/api.html.in | 2 +-
docs/drivers.html.in | 1 -
docs/drvphyp.html.in | 50 -
docs/schemas/capability.rng | 3 +-
docs/schemas/domaincommon.rng | 2 +-
libvirt.spec.in | 11 +-
m4/virt-driver-phyp.m4 | 48 -
mingw-libvirt.spec.in | 7 -
po/POTFILES.in | 1 -
src/Makefile.am | 1 -
src/README | 1 -
src/libvirt.c | 10 -
src/phyp/Makefile.inc.am | 21 -
src/phyp/phyp_driver.c | 3739 ---------------------------------
src/phyp/phyp_driver.h | 24 -
16 files changed, 4 insertions(+), 3921 deletions(-)
delete mode 100644 docs/drvphyp.html.in
delete mode 100644 m4/virt-driver-phyp.m4
delete mode 100644 src/phyp/Makefile.inc.am
delete mode 100644 src/phyp/phyp_driver.c
delete mode 100644 src/phyp/phyp_driver.h
diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in
index 4a8877d5e7..04cb39006a 100644
--- a/docs/aclpolkit.html.in
+++ b/docs/aclpolkit.html.in
@@ -365,10 +365,6 @@
<td>openvz</td>
<td>OPENVZ</td>
</tr>
- <tr>
- <td>phyp</td>
- <td>PHYP</td>
- </tr>
<tr>
<td>qemu</td>
<td>QEMU</td>
diff --git a/docs/api.html.in b/docs/api.html.in
index 288b9ecf88..85b196417a 100644
--- a/docs/api.html.in
+++ b/docs/api.html.in
@@ -330,7 +330,7 @@
daemon through the <a href="remote.html">remote</a> driver via an
<a href="internals/rpc.html">RPC</a>. Some hypervisors do support
client-side connections and responses, such as Test, OpenVZ, VMware,
- Power VM (phyp), VirtualBox (vbox), ESX, Hyper-V, Xen, and Virtuozzo.
+ VirtualBox (vbox), ESX, Hyper-V, Xen, and Virtuozzo.
The libvirtd daemon service is started on the host at system boot
time and can also be restarted at any time by a properly privileged
user, such as root. The libvirtd daemon uses the same libvirt API
diff --git a/docs/drivers.html.in b/docs/drivers.html.in
index 4539eedbcd..8743301ebd 100644
--- a/docs/drivers.html.in
+++ b/docs/drivers.html.in
@@ -34,7 +34,6 @@
<li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>
<li><strong><a href="drvxen.html">Xen</a></strong></li>
<li><strong><a href="drvhyperv.html">Microsoft Hyper-V</a></strong></li>
- <li><strong><a href="drvphyp.html">IBM PowerVM (phyp)</a></strong></li>
<li><strong><a href="drvvirtuozzo.html">Virtuozzo</a></strong></li>
<li><strong><a href="drvbhyve.html">Bhyve</a></strong> - The BSD Hypervisor</li>
</ul>
diff --git a/docs/drvphyp.html.in b/docs/drvphyp.html.in
deleted file mode 100644
index 8e0b43c869..0000000000
--- a/docs/drvphyp.html.in
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <h1>IBM PowerVM hypervisor driver (phyp)</h1>
- <ul id="toc"></ul>
- <p>
- The IBM PowerVM driver can manage both HMC and IVM PowerVM
- guests. VIOS connections are tunneled through HMC.
- </p>
-
-
- <h2><a id="project">Project Links</a></h2>
- <ul>
- <li>
- The <a href="http://www-03.ibm.com/systems/power/software/virtualization/index.html">IBM
- PowerVM</a> hypervisor
- </li>
- </ul>
-
-
- <h2><a id="uri">Connections to the PowerVM driver</a></h2>
- <p>
- Some example remote connection URIs for the driver are:
- </p>
-<pre>
-phyp://user@hmc/system (HMC connection)
-phyp://user@ivm/system (IVM connection)
-</pre>
- <p>
- <strong>Note</strong>: In contrast to other drivers, the
- PowerVM (or phyp) driver is a client-side-only driver,
- internally using ssh to connect to the specified hmc or ivm
- server. Therefore, the <a href="remote.html">remote transport
- mechanism</a> provided by the remote driver and libvirtd will
- not work, and you cannot use URIs like
- <code>phyp+ssh://example.com</code>.
- </p>
-
-
- <h3><a id="uriformat">URI Format</a></h3>
- <p>
- URIs have this general form (<code>[...]</code> marks an
- optional part, <code>{...|...}</code> marks a mandatory choice).
- </p>
-<pre>
-phyp://[username@]{hmc|ivm}/managed_system
-</pre>
-
-</body></html>
diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
index 26d313d652..91ee523116 100644
--- a/docs/schemas/capability.rng
+++ b/docs/schemas/capability.rng
@@ -408,8 +408,7 @@
<element name='os_type'>
<choice>
<value>xen</value> <!-- Xen 3.0 pv -->
- <value>linux</value> <!-- same as 'xen' - meant to be legacy,
- but is also used by phyp driver -->
+ <value>linux</value> <!-- same as 'xen' - meant to be legacy -->
<value>hvm</value> <!-- unmodified OS -->
<value>exe</value> <!-- For container based virt -->
<value>uml</value> <!-- user mode linux; NOT USED ANYMORE -->
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index e964773f5e..7238d19268 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -216,7 +216,7 @@
<value>vmware</value>
<value>hyperv</value>
<value>vbox</value>
- <value>phyp</value>
+ <value>phyp</value> <!-- NOT USED ANYMORE -->
<value>vz</value>
<value>bhyve</value>
</choice>
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 249a4b5425..5055750d2d 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -54,7 +54,6 @@
# Then the hypervisor drivers that run outside libvirtd, in libvirt.so
%define with_openvz 0%{!?_without_openvz:1}
%define with_vmware 0%{!?_without_vmware:1}
-%define with_phyp 0%{!?_without_phyp:1}
%define with_esx 0%{!?_without_esx:1}
%define with_hyperv 0%{!?_without_hyperv:1}
@@ -136,7 +135,6 @@
%if 0%{?rhel}
%define with_openvz 0
%define with_vbox 0
- %define with_phyp 0
%define with_vmware 0
%define with_libxl 0
%define with_hyperv 0
@@ -366,7 +364,7 @@ BuildRequires: libcap-ng-devel >= 0.5.0
%if %{with_fuse}
BuildRequires: fuse-devel >= 2.8.6
%endif
-%if %{with_phyp} || %{with_libssh2}
+%if %{with_libssh2}
BuildRequires: libssh2-devel >= 1.3.0
%endif
@@ -1036,12 +1034,6 @@ exit 1
%define arg_libxl --without-libxl
%endif
-%if %{with_phyp}
- %define arg_phyp --with-phyp
-%else
- %define arg_phyp --without-phyp
-%endif
-
%if %{with_esx}
%define arg_esx --with-esx
%else
@@ -1164,7 +1156,6 @@ cd %{_vpath_builddir}
--with-sasl \
--with-polkit \
--with-libvirtd \
- %{?arg_phyp} \
%{?arg_esx} \
%{?arg_hyperv} \
%{?arg_vmware} \
diff --git a/m4/virt-driver-phyp.m4 b/m4/virt-driver-phyp.m4
deleted file mode 100644
index 7861bf24e1..0000000000
--- a/m4/virt-driver-phyp.m4
+++ /dev/null
@@ -1,48 +0,0 @@
-dnl The Phyp driver
-dnl
-dnl Copyright (C) 2016 Red Hat, Inc.
-dnl
-dnl This library is free software; you can redistribute it and/or
-dnl modify it under the terms of the GNU Lesser General Public
-dnl License as published by the Free Software Foundation; either
-dnl version 2.1 of the License, or (at your option) any later version.
-dnl
-dnl This library is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-dnl Lesser General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU Lesser General Public
-dnl License along with this library. If not, see
-dnl <http://www.gnu.org/licenses/>.
-dnl
-
-AC_DEFUN([LIBVIRT_DRIVER_ARG_PHYP], [
- LIBVIRT_ARG_WITH_FEATURE([PHYP], [PHYP], [check])
-])
-
-AC_DEFUN([LIBVIRT_DRIVER_CHECK_PHYP], [
- AC_REQUIRE([LIBVIRT_CHECK_SSH2])
-
- if test "$with_phyp" != "no"; then
- if test "$with_ssh2" = "no" ; then
- if test "$with_phyp" = "check"; then
- with_phyp=no
- else
- AC_MSG_ERROR([libssh2 is required for Phyp driver])
- fi
- else
- with_phyp=yes
- fi
- fi
-
- if test "$with_phyp" = "yes"; then
- AC_DEFINE_UNQUOTED([WITH_PHYP], 1, [whether IBM HMC / IVM driver is enabled])
- fi
-
- AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"])
-])
-
-AC_DEFUN([LIBVIRT_DRIVER_RESULT_PHYP], [
- LIBVIRT_RESULT([PHYP], [$with_phyp])
-])
diff --git a/mingw-libvirt.spec.in b/mingw-libvirt.spec.in
index f6da67ab52..94d88e2edc 100644
--- a/mingw-libvirt.spec.in
+++ b/mingw-libvirt.spec.in
@@ -19,7 +19,6 @@
# The mingw build is client only. Set up defaults for hypervisor drivers
# that talk via a native remote protocol, and for which prereq mingw
# libraries exist.
-%define with_phyp 0%{!?_without_phyp:1}
%define with_esx 0%{!?_without_esx:1}
# missing libwsman, so can't build hyper-v
%define with_hyperv 0%{!?_without_hyperv:0}
@@ -28,7 +27,6 @@
# RHEL ships ESX but not PowerHypervisor, HyperV, or libxenserver (xenapi)
%if 0%{?rhel}
- %define with_phyp 0
%define with_xenapi 0
%define with_hyperv 0
%endif
@@ -140,10 +138,6 @@ echo "This RPM requires Fedora >= %{min_fedora}"
exit 1
%endif
-%if ! %{with_phyp}
- %define _without_phyp --without-phyp
-%endif
-
%if ! %{with_esx}
%define _without_esx --without-esx
%endif
@@ -176,7 +170,6 @@ autoreconf -if
--without-sasl \
--without-polkit \
--without-libvirtd \
- %{?_without_phyp} \
%{?_without_esx} \
%{?_without_hyperv} \
--without-vmware \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c26ac9497d..faf173584e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -137,7 +137,6 @@
@SRCDIR(a)/src/openvz/openvz_conf.c
@SRCDIR(a)/src/openvz/openvz_driver.c
@SRCDIR(a)/src/openvz/openvz_util.c
-@SRCDIR(a)/src/phyp/phyp_driver.c
@SRCDIR(a)/src/qemu/qemu_agent.c
@SRCDIR(a)/src/qemu/qemu_alias.c
@SRCDIR(a)/src/qemu/qemu_backup.c
diff --git a/src/Makefile.am b/src/Makefile.am
index cd01796d67..f3d4c28c6d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -109,7 +109,6 @@ include logging/Makefile.inc.am
include locking/Makefile.inc.am
include admin/Makefile.inc.am
include rpc/Makefile.inc.am
-include phyp/Makefile.inc.am
include test/Makefile.inc.am
include esx/Makefile.inc.am
include hyperv/Makefile.inc.am
diff --git a/src/README b/src/README
index a2260fda68..0c4d3b58c7 100644
--- a/src/README
+++ b/src/README
@@ -30,7 +30,6 @@ Then there are the hypervisor implementations:
* hyperv/ - Microsoft Hyper-V support using WinRM
* lxc/ - Linux Native Containers
* openvz/ - OpenVZ containers using cli tools
- * phyp/ - IBM Power Hypervisor using CLI tools over SSH
* qemu/ - QEMU / KVM using qemu CLI/monitor
* remote/ - Generic libvirt native RPC client
* test/ - A "mock" driver for testing
diff --git a/src/libvirt.c b/src/libvirt.c
index 9d783761e6..c741ebe311 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -72,9 +72,6 @@
#ifdef WITH_VMWARE
# include "vmware/vmware_driver.h"
#endif
-#ifdef WITH_PHYP
-# include "phyp/phyp_driver.h"
-#endif
#ifdef WITH_ESX
# include "esx/esx_driver.h"
#endif
@@ -290,10 +287,6 @@ virGlobalInit(void)
if (vmwareRegister() == -1)
goto error;
#endif
-#ifdef WITH_PHYP
- if (phypRegister() == -1)
- goto error;
-#endif
#ifdef WITH_ESX
if (esxRegister() == -1)
goto error;
@@ -959,9 +952,6 @@ virConnectOpenInternal(const char *name,
if (STREQ(virConnectDriverTab[i]->hypervisorDriver->name, "remote") &&
ret->uri != NULL &&
(
-#ifndef WITH_PHYP
- STRCASEEQ(ret->uri->scheme, "phyp") ||
-#endif
#ifndef WITH_ESX
STRCASEEQ(ret->uri->scheme, "vpx") ||
STRCASEEQ(ret->uri->scheme, "esx") ||
diff --git a/src/phyp/Makefile.inc.am b/src/phyp/Makefile.inc.am
deleted file mode 100644
index af556e8589..0000000000
--- a/src/phyp/Makefile.inc.am
+++ /dev/null
@@ -1,21 +0,0 @@
-# vim: filetype=automake
-
-PHYP_DRIVER_SOURCES = \
- phyp/phyp_driver.c \
- phyp/phyp_driver.h \
- $(NULL)
-
-DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(PHYP_DRIVER_SOURCES))
-EXTRA_DIST += $(PHYP_DRIVER_SOURCES)
-
-if WITH_PHYP
-noinst_LTLIBRARIES += libvirt_driver_phyp.la
-libvirt_la_BUILT_LIBADD += libvirt_driver_phyp.la
-libvirt_driver_phyp_la_LIBADD = $(SSH2_LIBS)
-libvirt_driver_phyp_la_CFLAGS = \
- $(SSH2_CFLAGS) \
- -I$(srcdir)/conf \
- $(AM_CFLAGS) \
- $(NULL)
-libvirt_driver_phyp_la_SOURCES = $(PHYP_DRIVER_SOURCES)
-endif WITH_PHYP
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
deleted file mode 100644
index 6bd37a6925..0000000000
--- a/src/phyp/phyp_driver.c
+++ /dev/null
@@ -1,3739 +0,0 @@
-/*
- * Copyright (C) 2010-2015 Red Hat, Inc.
- * Copyright IBM Corp. 2009
- *
- * phyp_driver.c: ssh layer to access Power Hypervisors
- *
- * 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/>.
- */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <libssh2.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <domain_event.h>
-#include <poll.h>
-
-#include "internal.h"
-#include "virauth.h"
-#include "datatypes.h"
-#include "virbuffer.h"
-#include "viralloc.h"
-#include "virlog.h"
-#include "driver.h"
-#include "virerror.h"
-#include "viruuid.h"
-#include "domain_conf.h"
-#include "storage_conf.h"
-#include "virfile.h"
-#include "interface_conf.h"
-#include "phyp_driver.h"
-#include "virstring.h"
-
-#define VIR_FROM_THIS VIR_FROM_PHYP
-
-VIR_LOG_INIT("phyp.phyp_driver");
-
-#define LPAR_EXEC_ERR (-1)
-#define SSH_CONN_ERR (-2) /* error while trying to connect to remote host */
-#define SSH_CMD_ERR (-3) /* error while trying to execute the remote cmd */
-
-/* This is the lpar (domain) struct that relates
- * the ID with UUID generated by the API
- * */
-typedef struct _lpar lpar_t;
-typedef lpar_t *lparPtr;
-struct _lpar {
- unsigned char uuid[VIR_UUID_BUFLEN];
- int id;
-};
-
-/* Struct that holds how many lpars (domains) we're
- * handling and a pointer to an array of lpar structs
- * */
-typedef struct _uuid_table uuid_table_t;
-typedef uuid_table_t *uuid_tablePtr;
-struct _uuid_table {
- size_t nlpars;
- lparPtr *lpars;
-};
-
-/* This is the main structure of the driver
- * */
-typedef struct _phyp_driver phyp_driver_t;
-typedef phyp_driver_t *phyp_driverPtr;
-struct _phyp_driver {
- LIBSSH2_SESSION *session;
- int sock;
-
- uuid_tablePtr uuid_table;
- virCapsPtr caps;
- virDomainXMLOptionPtr xmlopt;
- int vios_id;
-
- /* system_type:
- * 0 = hmc
- * 127 = ivm
- * */
- int system_type;
- char *managed_system;
-};
-
-/*
- * URI: phyp://user@[hmc|ivm]/managed_system
- * */
-
-enum {
- HMC = 0,
- PHYP_IFACENAME_SIZE = 24,
- PHYP_MAC_SIZE = 12,
-};
-
-static int
-waitsocket(int socket_fd, LIBSSH2_SESSION * session)
-{
- struct pollfd fds[1];
- int dir;
-
- memset(fds, 0, sizeof(fds));
- fds[0].fd = socket_fd;
-
- /* now make sure we wait in the correct direction */
- dir = libssh2_session_block_directions(session);
-
- if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
- fds[0].events |= POLLIN;
-
- if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
- fds[0].events |= POLLOUT;
-
- return poll(fds, G_N_ELEMENTS(fds), -1);
-}
-
-/* this function is the layer that manipulates the ssh channel itself
- * and executes the commands on the remote machine */
-static char *phypExec(LIBSSH2_SESSION *, const char *, int *, virConnectPtr)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
- ATTRIBUTE_NONNULL(4);
-static char *
-phypExec(LIBSSH2_SESSION *session, const char *cmd, int *exit_status,
- virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_CHANNEL *channel;
- virBuffer tex_ret = VIR_BUFFER_INITIALIZER;
- char *buffer = NULL;
- size_t buffer_size = 16384;
- int exitcode;
- int bytecount = 0;
- int sock = phyp_driver->sock;
- int rc = 0;
-
- if (VIR_ALLOC_N(buffer, buffer_size) < 0)
- return NULL;
-
- /* Exec non-blocking on the remove host */
- while ((channel = libssh2_channel_open_session(session)) == NULL &&
- libssh2_session_last_error(session, NULL, NULL, 0) ==
- LIBSSH2_ERROR_EAGAIN) {
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto err;
- }
- }
-
- if (channel == NULL)
- goto err;
-
- while ((rc = libssh2_channel_exec(channel, cmd)) ==
- LIBSSH2_ERROR_EAGAIN) {
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto err;
- }
- }
-
- if (rc != 0)
- goto err;
-
- for (;;) {
- /* loop until we block */
- do {
- rc = libssh2_channel_read(channel, buffer, buffer_size);
- if (rc > 0) {
- bytecount += rc;
- virBufferAdd(&tex_ret, buffer, -1);
- }
- }
- while (rc > 0);
-
- /* this is due to blocking that would occur otherwise so we loop on
- * this condition */
- if (rc == LIBSSH2_ERROR_EAGAIN) {
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto err;
- }
- } else {
- break;
- }
- }
-
- exitcode = 127;
-
- while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto err;
- }
- }
-
- if (rc == 0)
- exitcode = libssh2_channel_get_exit_status(channel);
-
- (*exit_status) = exitcode;
- libssh2_channel_free(channel);
- channel = NULL;
- VIR_FREE(buffer);
-
- return virBufferContentAndReset(&tex_ret);
-
- err:
- (*exit_status) = SSH_CMD_ERR;
- virBufferFreeAndReset(&tex_ret);
- VIR_FREE(buffer);
- return NULL;
-}
-
-/* Convenience wrapper function */
-static char *phypExecBuffer(LIBSSH2_SESSION *, virBufferPtr buf, int *,
- virConnectPtr, bool) ATTRIBUTE_NONNULL(1)
- ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
-static char *
-phypExecBuffer(LIBSSH2_SESSION *session, virBufferPtr buf, int *exit_status,
- virConnectPtr conn, bool strip_newline)
-{
- char *cmd;
- char *ret;
-
- cmd = virBufferContentAndReset(buf);
- ret = phypExec(session, cmd, exit_status, conn);
- VIR_FREE(cmd);
- if (ret && *exit_status == 0 && strip_newline) {
- char *nl = strchr(ret, '\n');
- if (nl)
- *nl = '\0';
- }
- return ret;
-}
-
-/* Convenience wrapper function */
-static int phypExecInt(LIBSSH2_SESSION *, virBufferPtr, virConnectPtr, int *)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
-static int
-phypExecInt(LIBSSH2_SESSION *session, virBufferPtr buf, virConnectPtr conn,
- int *result)
-{
- char *str;
- int ret;
- char *char_ptr;
-
- str = phypExecBuffer(session, buf, &ret, conn, true);
- if (!str || ret) {
- VIR_FREE(str);
- return -1;
- }
- ret = virStrToLong_i(str, &char_ptr, 10, result);
- if (ret == 0 && *char_ptr)
- VIR_WARN("ignoring suffix during integer parsing of '%s'", str);
- VIR_FREE(str);
- return ret;
-}
-
-static int
-phypGetSystemType(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *ret = NULL;
- int exit_status = 0;
-
- ret = phypExec(session, "lshmc -V", &exit_status, conn);
-
- VIR_FREE(ret);
- return exit_status;
-}
-
-static int
-phypGetVIOSPartitionID(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int id = -1;
- char *managed_system = phyp_driver->managed_system;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAddLit(&buf, " -r lpar -F lpar_id,lpar_env"
- "|sed -n '/vioserver/ {\n s/,.*$//\n p\n}'");
- phypExecInt(session, &buf, conn, &id);
- return id;
-}
-
-
-static virCapsPtr
-phypCapsInit(void)
-{
- virCapsPtr caps;
- virCapsGuestPtr guest;
-
- if ((caps = virCapabilitiesNew(virArchFromHost(),
- false, false)) == NULL)
- goto no_memory;
-
- /* Some machines have problematic NUMA topology causing
- * unexpected failures. We don't want to break the QEMU
- * driver in this scenario, so log errors & carry on
- */
- if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
- goto no_memory;
-
- if (virCapabilitiesInitCaches(caps) < 0)
- VIR_WARN("Failed to get host CPU cache info");
-
- if ((guest = virCapabilitiesAddGuest(caps,
- VIR_DOMAIN_OSTYPE_LINUX,
- caps->host.arch,
- NULL, NULL, 0, NULL)) == NULL)
- goto no_memory;
-
- if (virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_PHYP,
- NULL, NULL, 0, NULL) == NULL)
- goto no_memory;
-
- return caps;
-
- no_memory:
- virObjectUnref(caps);
- return NULL;
-}
-
-/* This is a generic function that won't be used directly by
- * libvirt api. The function returns the number of domains
- * in different states: Running, Not Activated and all:
- *
- * type: 0 - Running
- * 1 - Not Activated
- * * - All
- * */
-static int
-phypConnectNumOfDomainsGeneric(virConnectPtr conn, unsigned int type)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int ndom = -1;
- char *managed_system = phyp_driver->managed_system;
- const char *state;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (type == 0) {
- state = "|grep Running";
- } else if (type == 1) {
- if (system_type == HMC) {
- state = "|grep \"Not Activated\"";
- } else {
- state = "|grep \"Open Firmware\"";
- }
- } else {
- state = " ";
- }
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -F lpar_id,state %s |grep -c '^[0-9][0-9]*'",
- state);
- phypExecInt(session, &buf, conn, &ndom);
- return ndom;
-}
-
-/* This is a generic function that won't be used directly by
- * libvirt api. The function returns the ids of domains
- * in different states: Running, and all:
- *
- * type: 0 - Running
- * 1 - all
- * */
-static int
-phypConnectListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
- unsigned int type)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- int got = -1;
- char *ret = NULL;
- char *line, *next_line;
- const char *state;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (type == 0)
- state = "|grep Running";
- else
- state = " ";
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -F lpar_id,state %s | sed -e 's/,.*$//'",
- state);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- /* I need to parse the textual return in order to get the ids */
- line = ret;
- got = 0;
- while (*line && got < nids) {
- if (virStrToLong_i(line, &next_line, 10, &ids[got]) == -1) {
- VIR_ERROR(_("Cannot parse number from '%s'"), line);
- got = -1;
- goto cleanup;
- }
- got++;
- line = next_line;
- while (*line == '\n')
- line++; /* skip \n */
- }
-
- cleanup:
- VIR_FREE(ret);
- return got;
-}
-
-static int
-phypUUIDTable_WriteFile(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- size_t i = 0;
- int fd = -1;
- char local_file[] = "./uuid_table";
-
- if ((fd = creat(local_file, 0755)) == -1)
- goto err;
-
- for (i = 0; i < uuid_table->nlpars; i++) {
- if (safewrite(fd, &uuid_table->lpars[i]->id,
- sizeof(uuid_table->lpars[i]->id)) !=
- sizeof(uuid_table->lpars[i]->id)) {
- VIR_ERROR(_("Unable to write information to local file."));
- goto err;
- }
-
- if (safewrite(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) !=
- VIR_UUID_BUFLEN) {
- VIR_ERROR(_("Unable to write information to local file."));
- goto err;
- }
- }
-
- if (VIR_CLOSE(fd) < 0) {
- virReportSystemError(errno, _("Could not close %s"),
- local_file);
- goto err;
- }
- return 0;
-
- err:
- VIR_FORCE_CLOSE(fd);
- return -1;
-}
-
-static int
-phypUUIDTable_Push(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- LIBSSH2_CHANNEL *channel = NULL;
- struct stat local_fileinfo;
- char buffer[1024];
- int rc = 0;
- FILE *f = NULL;
- size_t nread, sent;
- char *ptr;
- char local_file[] = "./uuid_table";
- char *remote_file = NULL;
- int ret = -1;
-
- remote_file = g_strdup_printf("/home/%s/libvirt_uuid_table",
- NULLSTR(conn->uri->user));
-
- if (stat(local_file, &local_fileinfo) == -1) {
- VIR_WARN("Unable to stat local file.");
- goto cleanup;
- }
-
- if (!(f = fopen(local_file, "rb"))) {
- VIR_WARN("Unable to open local file.");
- goto cleanup;
- }
-
- do {
- channel =
- libssh2_scp_send(session, remote_file,
- 0x1FF & local_fileinfo.st_mode,
- (unsigned long)local_fileinfo.st_size);
-
- if ((!channel) && (libssh2_session_last_errno(session) !=
- LIBSSH2_ERROR_EAGAIN))
- goto cleanup;
- } while (!channel);
-
- do {
- nread = fread(buffer, 1, sizeof(buffer), f);
- if (nread <= 0) {
- if (feof(f)) {
- /* end of file */
- break;
- } else {
- VIR_ERROR(_("Failed to read from %s"), local_file);
- goto cleanup;
- }
- }
- ptr = buffer;
- sent = 0;
-
- do {
- /* write the same data over and over, until error or completion */
- rc = libssh2_channel_write(channel, ptr, nread);
- if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */
- continue;
- } else if (rc > 0) {
- /* rc indicates how many bytes were written this time */
- sent += rc;
- }
- ptr += sent;
- nread -= sent;
- } while (rc > 0 && sent < nread);
- } while (1);
-
- ret = 0;
-
- cleanup:
- VIR_FREE(remote_file);
- if (channel) {
- libssh2_channel_send_eof(channel);
- libssh2_channel_wait_eof(channel);
- libssh2_channel_wait_closed(channel);
- libssh2_channel_free(channel);
- channel = NULL;
- }
- VIR_FORCE_FCLOSE(f);
- return ret;
-}
-
-static int
-phypUUIDTable_RemLpar(virConnectPtr conn, int id)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- size_t i = 0;
-
- for (i = 0; i <= uuid_table->nlpars; i++) {
- if (uuid_table->lpars[i]->id == id) {
- uuid_table->lpars[i]->id = -1;
- memset(uuid_table->lpars[i]->uuid, 0, VIR_UUID_BUFLEN);
- }
- }
-
- if (phypUUIDTable_WriteFile(conn) == -1)
- goto err;
-
- if (phypUUIDTable_Push(conn) == -1)
- goto err;
-
- return 0;
-
- err:
- return -1;
-}
-
-static int
-phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- lparPtr item = NULL;
-
- if (VIR_ALLOC(item) < 0)
- goto err;
-
- item->id = id;
- memcpy(item->uuid, uuid, VIR_UUID_BUFLEN);
-
- if (VIR_APPEND_ELEMENT_COPY(uuid_table->lpars, uuid_table->nlpars, item) < 0)
- goto err;
-
- if (phypUUIDTable_WriteFile(conn) == -1)
- goto err;
-
- if (phypUUIDTable_Push(conn) == -1)
- goto err;
-
- return 0;
-
- err:
- VIR_FREE(item);
- return -1;
-}
-
-static int
-phypUUIDTable_ReadFile(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- size_t i = 0;
- int fd = -1;
- char local_file[] = "./uuid_table";
- int rc = 0;
- int id;
-
- if ((fd = open(local_file, O_RDONLY)) == -1) {
- VIR_WARN("Unable to read information from local file.");
- goto err;
- }
-
- /* Creating a new data base and writing to local file */
- if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) {
- for (i = 0; i < uuid_table->nlpars; i++) {
-
- rc = read(fd, &id, sizeof(int));
- if (rc == sizeof(int)) {
- if (VIR_ALLOC(uuid_table->lpars[i]) < 0)
- goto err;
- uuid_table->lpars[i]->id = id;
- } else {
- VIR_WARN
- ("Unable to read from information from local file.");
- goto err;
- }
-
- rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN);
- if (rc != VIR_UUID_BUFLEN) {
- VIR_WARN("Unable to read information from local file.");
- goto err;
- }
- }
- }
-
- VIR_FORCE_CLOSE(fd);
- return 0;
-
- err:
- VIR_FORCE_CLOSE(fd);
- return -1;
-}
-
-static int
-phypUUIDTable_Pull(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- LIBSSH2_CHANNEL *channel = NULL;
- struct stat fileinfo;
- char buffer[1024];
- int rc = 0;
- int fd = -1;
- int got = 0;
- int amount = 0;
- int total = 0;
- int sock = 0;
- char local_file[] = "./uuid_table";
- char *remote_file = NULL;
- int ret = -1;
-
- remote_file = g_strdup_printf("/home/%s/libvirt_uuid_table",
- NULLSTR(conn->uri->user));
-
- /* Trying to stat the remote file. */
- do {
- channel = libssh2_scp_recv(session, remote_file, &fileinfo);
-
- if (!channel) {
- if (libssh2_session_last_errno(session) !=
- LIBSSH2_ERROR_EAGAIN) {
- goto cleanup;
- } else {
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto cleanup;
- }
- }
- }
- } while (!channel);
-
- /* Creating a new data base based on remote file */
- if ((fd = creat(local_file, 0755)) == -1)
- goto cleanup;
-
- /* Request a file via SCP */
- while (got < fileinfo.st_size) {
- do {
- amount = sizeof(buffer);
-
- if ((fileinfo.st_size - got) < amount)
- amount = fileinfo.st_size - got;
-
- rc = libssh2_channel_read(channel, buffer, amount);
- if (rc > 0) {
- if (safewrite(fd, buffer, rc) != rc)
- VIR_WARN
- ("Unable to write information to local file.");
-
- got += rc;
- total += rc;
- }
- } while (rc > 0);
-
- if ((rc == LIBSSH2_ERROR_EAGAIN)
- && (got < fileinfo.st_size)) {
- /* this is due to blocking that would occur otherwise
- * so we loop on this condition */
-
- /* now we wait */
- if (waitsocket(sock, session) < 0 && errno != EINTR) {
- virReportSystemError(errno, "%s",
- _("unable to wait on libssh2 socket"));
- goto cleanup;
- }
- continue;
- }
- break;
- }
- if (VIR_CLOSE(fd) < 0) {
- virReportSystemError(errno, _("Could not close %s"),
- local_file);
- goto cleanup;
- }
-
- ret = 0;
-
- cleanup:
- if (channel) {
- libssh2_channel_send_eof(channel);
- libssh2_channel_wait_eof(channel);
- libssh2_channel_wait_closed(channel);
- libssh2_channel_free(channel);
- channel = NULL;
- }
- VIR_FORCE_CLOSE(fd);
- return ret;
-}
-
-static int
-phypUUIDTable_Init(virConnectPtr conn)
-{
- uuid_tablePtr uuid_table = NULL;
- phyp_driverPtr phyp_driver;
- int nids_numdomains = 0;
- int nids_listdomains = 0;
- int *ids = NULL;
- size_t i = 0;
- int ret = -1;
- bool table_created = false;
-
- if ((nids_numdomains = phypConnectNumOfDomainsGeneric(conn, 2)) < 0)
- goto cleanup;
-
- if (VIR_ALLOC_N(ids, nids_numdomains) < 0)
- goto cleanup;
-
- if ((nids_listdomains =
- phypConnectListDomainsGeneric(conn, ids, nids_numdomains, 1)) < 0)
- goto cleanup;
-
- /* exit early if there are no domains */
- if (nids_numdomains == 0 && nids_listdomains == 0) {
- ret = 0;
- goto cleanup;
- }
- if (nids_numdomains != nids_listdomains) {
- VIR_ERROR(_("Unable to determine number of domains."));
- goto cleanup;
- }
-
- phyp_driver = conn->privateData;
- uuid_table = phyp_driver->uuid_table;
- uuid_table->nlpars = nids_listdomains;
-
- /* try to get the table from server */
- if (phypUUIDTable_Pull(conn) == -1) {
- /* file not found in the server, creating a new one */
- table_created = true;
- if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) {
- for (i = 0; i < uuid_table->nlpars; i++) {
- if (VIR_ALLOC(uuid_table->lpars[i]) < 0)
- goto cleanup;
- uuid_table->lpars[i]->id = ids[i];
-
- if (virUUIDGenerate(uuid_table->lpars[i]->uuid) < 0)
- VIR_WARN("Unable to generate UUID for domain %d",
- ids[i]);
- }
- } else {
- goto cleanup;
- }
-
- if (phypUUIDTable_WriteFile(conn) == -1)
- goto cleanup;
-
- if (phypUUIDTable_Push(conn) == -1)
- goto cleanup;
- } else {
- if (phypUUIDTable_ReadFile(conn) == -1)
- goto cleanup;
- }
-
- ret = 0;
-
- cleanup:
- if (ret < 0 && table_created) {
- for (i = 0; i < uuid_table->nlpars; i++)
- VIR_FREE(uuid_table->lpars[i]);
- VIR_FREE(uuid_table->lpars);
- }
- VIR_FREE(ids);
- return ret;
-}
-
-static void
-phypUUIDTable_Free(uuid_tablePtr uuid_table)
-{
- size_t i;
-
- if (uuid_table == NULL)
- return;
-
- for (i = 0; i < uuid_table->nlpars; i++)
- VIR_FREE(uuid_table->lpars[i]);
-
- VIR_FREE(uuid_table->lpars);
- VIR_FREE(uuid_table);
-}
-
-#define SPECIALCHARACTER_CASES \
- case '&': case ';': case '`': case '@': case '"': case '|': case '*': \
- case '?': case '~': case '<': case '>': case '^': case '(': case ')': \
- case '[': case ']': case '{': case '}': case '$': case '%': case '#': \
- case '\\': case '\n': case '\r': case '\t':
-
-static bool
-contains_specialcharacters(const char *src)
-{
- size_t len = strlen(src);
- size_t i = 0;
-
- if (len == 0)
- return false;
-
- for (i = 0; i < len; i++) {
- switch (src[i]) {
- SPECIALCHARACTER_CASES
- return true;
- default:
- continue;
- }
- }
-
- return false;
-}
-
-static char *
-escape_specialcharacters(const char *src)
-{
- size_t len = strlen(src);
- size_t i = 0, j = 0;
- char *dst;
-
- if (len == 0)
- return NULL;
-
- if (VIR_ALLOC_N(dst, len + 1) < 0)
- return NULL;
-
- for (i = 0; i < len; i++) {
- switch (src[i]) {
- SPECIALCHARACTER_CASES
- continue;
- default:
- dst[j] = src[i];
- j++;
- }
- }
-
- dst[j] = '\0';
-
- return dst;
-}
-
-static LIBSSH2_SESSION *
-openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
- int *internal_socket)
-{
- LIBSSH2_SESSION *session;
- const char *hostname = conn->uri->server;
- char *username = NULL;
- char *password = NULL;
- int sock = -1;
- int rc;
- struct addrinfo *ai = NULL, *cur;
- struct addrinfo hints;
- int ret;
- char *pubkey = NULL;
- char *pvtkey = NULL;
- char *userhome = virGetUserDirectory();
- struct stat pvt_stat, pub_stat;
-
- if (userhome == NULL)
- goto err;
-
- pubkey = g_strdup_printf("%s/.ssh/id_rsa.pub", userhome);
-
- pvtkey = g_strdup_printf("%s/.ssh/id_rsa", userhome);
-
- if (conn->uri->user != NULL) {
- username = g_strdup(conn->uri->user);
- } else {
- if (!(username = virAuthGetUsername(conn, auth, "ssh", NULL,
- conn->uri->server)))
- goto err;
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = 0;
-
- ret = getaddrinfo(hostname, "22", &hints, &ai);
- if (ret != 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Error while getting %s address info"), hostname);
- goto err;
- }
-
- cur = ai;
- while (cur != NULL) {
- sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
- if (sock >= 0) {
- if (connect(sock, cur->ai_addr, cur->ai_addrlen) == 0) {
- freeaddrinfo(ai);
- goto connected;
- }
- VIR_FORCE_CLOSE(sock);
- }
- cur = cur->ai_next;
- }
-
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failed to connect to %s"), hostname);
- freeaddrinfo(ai);
- goto err;
-
- connected:
-
- (*internal_socket) = sock;
-
- /* Create a session instance */
- session = libssh2_session_init();
- if (!session)
- goto err;
-
- /* tell libssh2 we want it all done non-blocking */
- libssh2_session_set_blocking(session, 0);
-
- while ((rc = libssh2_session_startup(session, sock)) ==
- LIBSSH2_ERROR_EAGAIN);
- if (rc) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Failure establishing SSH session."));
- goto disconnect;
- }
-
- /* Trying authentication by pubkey */
- if (stat(pvtkey, &pvt_stat) || stat(pubkey, &pub_stat)) {
- rc = LIBSSH2_ERROR_SOCKET_NONE;
- goto keyboard_interactive;
- }
-
- while ((rc =
- libssh2_userauth_publickey_fromfile(session, username,
- pubkey,
- pvtkey,
- NULL)) ==
- LIBSSH2_ERROR_EAGAIN);
-
- keyboard_interactive:
- if (rc == LIBSSH2_ERROR_SOCKET_NONE
- || rc == LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED
- || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
-
- if (!(password = virAuthGetPassword(conn, auth, "ssh", username,
- conn->uri->server)))
- goto disconnect;
-
- while ((rc =
- libssh2_userauth_password(session, username,
- password)) ==
- LIBSSH2_ERROR_EAGAIN);
-
- if (rc) {
- virReportError(VIR_ERR_AUTH_FAILED,
- "%s", _("Authentication failed"));
- goto disconnect;
- } else {
- goto exit;
- }
-
- } else if (rc == LIBSSH2_ERROR_NONE) {
- goto exit;
-
- } else if (rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_SOCKET_SEND
- || rc == LIBSSH2_ERROR_SOCKET_TIMEOUT) {
- goto err;
- }
-
- disconnect:
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
- err:
- VIR_FORCE_CLOSE(sock);
- VIR_FREE(userhome);
- VIR_FREE(pubkey);
- VIR_FREE(pvtkey);
- VIR_FREE(username);
- VIR_FREE(password);
- return NULL;
-
- exit:
- VIR_FREE(userhome);
- VIR_FREE(pubkey);
- VIR_FREE(pvtkey);
- VIR_FREE(username);
- VIR_FREE(password);
- return session;
-}
-
-
-static int
-phypDomainDefPostParse(virDomainDefPtr def,
- unsigned int parseFlags G_GNUC_UNUSED,
- void *opaque,
- void *parseOpaque G_GNUC_UNUSED)
-{
- phyp_driverPtr driver = opaque;
- if (!virCapabilitiesDomainSupported(driver->caps, def->os.type,
- def->os.arch,
- def->virtType))
- return -1;
-
- return 0;
-}
-
-
-static int
-phypDomainDeviceDefPostParse(virDomainDeviceDefPtr dev G_GNUC_UNUSED,
- const virDomainDef *def G_GNUC_UNUSED,
- unsigned int parseFlags G_GNUC_UNUSED,
- void *opaque G_GNUC_UNUSED,
- void *parseOpaque G_GNUC_UNUSED)
-{
- return 0;
-}
-
-
-virDomainDefParserConfig virPhypDriverDomainDefParserConfig = {
- .devicesPostParseCallback = phypDomainDeviceDefPostParse,
- .domainPostParseCallback = phypDomainDefPostParse,
- .features = VIR_DOMAIN_DEF_FEATURE_NAME_SLASH,
-};
-
-
-static virDrvOpenStatus
-phypConnectOpen(virConnectPtr conn,
- virConnectAuthPtr auth,
- virConfPtr conf G_GNUC_UNUSED,
- unsigned int flags)
-{
- LIBSSH2_SESSION *session = NULL;
- int internal_socket = -1;
- uuid_tablePtr uuid_table = NULL;
- phyp_driverPtr phyp_driver = NULL;
- char *char_ptr;
- char *managed_system = NULL;
-
- virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
-
- if (VIR_ALLOC(phyp_driver) < 0)
- goto failure;
-
- phyp_driver->sock = -1;
-
- if (VIR_ALLOC(uuid_table) < 0)
- goto failure;
-
- if (conn->uri->path[0] != '\0') {
- /* need to shift one byte in order to remove the first "/" of URI component */
- managed_system = g_strdup(conn->uri->path + (conn->uri->path[0] == '/'));
-
- /* here we are handling only the first component of the path,
- * so skipping the second:
- * */
- char_ptr = strchr(managed_system, '/');
-
- if (char_ptr)
- *char_ptr = '\0';
-
- if (contains_specialcharacters(conn->uri->path)) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s",
- _("Error parsing 'path'. Invalid characters."));
- goto failure;
- }
- }
-
- if ((session = openSSHSession(conn, auth, &internal_socket)) == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Error while opening SSH session."));
- goto failure;
- }
-
- phyp_driver->session = session;
- phyp_driver->sock = internal_socket;
-
- uuid_table->nlpars = 0;
- uuid_table->lpars = NULL;
-
- if (conn->uri->path)
- phyp_driver->managed_system = managed_system;
-
- phyp_driver->uuid_table = uuid_table;
- if ((phyp_driver->caps = phypCapsInit()) == NULL)
- goto failure;
-
- virPhypDriverDomainDefParserConfig.priv = phyp_driver;
- if (!(phyp_driver->xmlopt = virDomainXMLOptionNew(&virPhypDriverDomainDefParserConfig,
- NULL, NULL, NULL, NULL)))
- goto failure;
-
- conn->privateData = phyp_driver;
-
- if ((phyp_driver->system_type = phypGetSystemType(conn)) == -1)
- goto failure;
-
- if (phypUUIDTable_Init(conn) == -1)
- goto failure;
-
- if (phyp_driver->system_type == HMC) {
- if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1)
- goto failure;
- }
-
- return VIR_DRV_OPEN_SUCCESS;
-
- failure:
- VIR_FREE(managed_system);
-
- if (phyp_driver != NULL) {
- virObjectUnref(phyp_driver->caps);
- virObjectUnref(phyp_driver->xmlopt);
- VIR_FREE(phyp_driver);
- }
-
- phypUUIDTable_Free(uuid_table);
-
- if (session != NULL) {
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
- }
-
- VIR_FORCE_CLOSE(internal_socket);
-
- return VIR_DRV_OPEN_ERROR;
-}
-
-static int
-phypConnectClose(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
-
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
-
- virObjectUnref(phyp_driver->caps);
- virObjectUnref(phyp_driver->xmlopt);
- phypUUIDTable_Free(phyp_driver->uuid_table);
- VIR_FREE(phyp_driver->managed_system);
- VIR_FORCE_CLOSE(phyp_driver->sock);
- VIR_FREE(phyp_driver);
- return 0;
-}
-
-
-static int
-phypConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED)
-{
- /* Phyp uses an SSH tunnel, so is always encrypted */
- return 1;
-}
-
-
-static int
-phypConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED)
-{
- /* Phyp uses an SSH tunnel, so is always secure */
- return 1;
-}
-
-
-static int
-phypConnectIsAlive(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- /* XXX we should be able to do something better but this is simple, safe,
- * and good enough for now. In worst case, the function will return true
- * even though the connection is not alive.
- */
- if (phyp_driver->session)
- return 1;
- else
- return 0;
-}
-
-
-static int
-phypDomainIsUpdated(virDomainPtr conn G_GNUC_UNUSED)
-{
- return 0;
-}
-
-/* return the lpar_id given a name and a managed system name */
-static int
-phypGetLparID(LIBSSH2_SESSION * session, const char *managed_system,
- const char *name, virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- int lpar_id = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " --filter lpar_names=%s -F lpar_id", name);
- phypExecInt(session, &buf, conn, &lpar_id);
- return lpar_id;
-}
-
-/* return the lpar name given a lpar_id and a managed system name */
-static char *
-phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
- unsigned int lpar_id, virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " --filter lpar_ids=%d -F name", lpar_id);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-
-/* Search into the uuid_table for a lpar_uuid given a lpar_id
- * and a managed system name
- *
- * return: 0 - record found
- * -1 - not found
- * */
-static int
-phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- lparPtr *lpars = uuid_table->lpars;
- size_t i = 0;
-
- for (i = 0; i < uuid_table->nlpars; i++) {
- if (lpars[i]->id == lpar_id) {
- memcpy(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN);
- return 0;
- }
- }
-
- return -1;
-}
-
-/*
- * type:
- * 0 - maxmem
- * 1 - memory
- * */
-static unsigned long
-phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
- int type)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int memory = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (type != 1 && type != 0)
- return 0;
-
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r mem --level lpar -F %s --filter lpar_ids=%d",
- type ? "curr_mem" : "curr_max_mem", lpar_id);
- phypExecInt(session, &buf, conn, &memory);
- return memory;
-}
-
-static unsigned long
-phypGetLparCPUGeneric(virConnectPtr conn, const char *managed_system,
- int lpar_id, int type)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int vcpus = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r proc --level lpar -F %s --filter lpar_ids=%d",
- type ? "curr_max_procs" : "curr_procs", lpar_id);
- phypExecInt(session, &buf, conn, &vcpus);
- return vcpus;
-}
-
-static unsigned long
-phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
-{
- return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 0);
-}
-
-static int
-phypDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
-{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- char *managed_system = phyp_driver->managed_system;
-
- if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
- virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
- return -1;
- }
-
- return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
-}
-
-static int
-phypDomainGetMaxVcpus(virDomainPtr dom)
-{
- return phypDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE |
- VIR_DOMAIN_VCPU_MAXIMUM));
-}
-
-static int
-phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
- const char *lpar_name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int remote_slot = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r virtualio --rsubtype scsi -F "
- "remote_slot_num --filter lpar_names=%s", lpar_name);
- phypExecInt(session, &buf, conn, &remote_slot);
- return remote_slot;
-}
-
-/* XXX - is this needed? */
-static char *phypGetBackingDevice(virConnectPtr, const char *, char *)
- G_GNUC_UNUSED;
-static char *
-phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
- char *lpar_name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *ret = NULL;
- int remote_slot = 0;
- int exit_status = 0;
- char *char_ptr;
- char *backing_device = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if ((remote_slot =
- phypGetRemoteSlot(conn, managed_system, lpar_name)) == -1)
- return NULL;
-
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r virtualio --rsubtype scsi -F "
- "backing_devices --filter slots=%d", remote_slot);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- /* here is a little trick to deal returns of this kind:
- *
- * 0x8100000000000000//lv01
- *
- * the information we really need is only lv01, so we
- * need to skip a lot of things on the string.
- * */
- char_ptr = strchr(ret, '/');
-
- if (char_ptr) {
- char_ptr++;
- if (char_ptr[0] == '/')
- char_ptr++;
- else
- goto cleanup;
-
- backing_device = g_strdup(char_ptr);
- } else {
- backing_device = g_steal_pointer(&ret);
- }
-
- char_ptr = strchr(backing_device, '\n');
-
- if (char_ptr)
- *char_ptr = '\0';
-
- cleanup:
- VIR_FREE(ret);
-
- return backing_device;
-}
-
-static char *
-phypGetLparProfile(virConnectPtr conn, int lpar_id)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r prof --filter lpar_ids=%d -F name|head -n 1",
- lpar_id);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-static int
-phypGetVIOSNextSlotNumber(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- char *profile = NULL;
- int slot = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (!(profile = phypGetLparProfile(conn, vios_id))) {
- VIR_ERROR(_("Unable to get VIOS profile name."));
- return -1;
- }
-
- virBufferAddLit(&buf, "lssyscfg");
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
-
- virBufferAsprintf(&buf, " -r prof --filter "
- "profile_names=%s -F virtual_eth_adapters,"
- "virtual_opti_pool_id,virtual_scsi_adapters,"
- "virtual_serial_adapters|sed -e 's/\"//g' -e "
- "'s/,/\\n/g'|sed -e 's/\\(^[0-9][0-9]\\*\\).*$/\\1/'"
- "|sort|tail -n 1", profile);
- if (phypExecInt(session, &buf, conn, &slot) < 0)
- return -1;
- return slot + 1;
-}
-
-static int
-phypCreateServerSCSIAdapter(virConnectPtr conn)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- char *profile = NULL;
- int slot = 0;
- char *vios_name = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (!
- (vios_name =
- phypGetLparNAME(session, managed_system, vios_id, conn))) {
- VIR_ERROR(_("Unable to get VIOS name"));
- goto cleanup;
- }
-
- if (!(profile = phypGetLparProfile(conn, vios_id))) {
- VIR_ERROR(_("Unable to get VIOS profile name."));
- goto cleanup;
- }
-
- if ((slot = phypGetVIOSNextSlotNumber(conn)) == -1) {
- VIR_ERROR(_("Unable to get free slot number"));
- goto cleanup;
- }
-
- /* Listing all the virtual_scsi_adapter interfaces, the new adapter must
- * be appended to this list
- * */
- virBufferAddLit(&buf, "lssyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r prof --filter lpar_ids=%d,profile_names=%s"
- " -F virtual_scsi_adapters|sed -e s/\\\"//g",
- vios_id, profile);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- /* Here I change the VIOS configuration to append the new adapter
- * with the free slot I got with phypGetVIOSNextSlotNumber.
- * */
- virBufferAddLit(&buf, "chsyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r prof -i 'name=%s,lpar_id=%d,"
- "\"virtual_scsi_adapters=%s,%d/server/any/any/1\"'",
- vios_name, vios_id, ret, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- /* Finally I add the new scsi adapter to VIOS using the same slot
- * I used in the VIOS configuration.
- * */
- virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
- vios_name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- result = 0;
-
- cleanup:
- VIR_FREE(profile);
- VIR_FREE(vios_name);
- VIR_FREE(ret);
-
- return result;
-}
-
-static char *
-phypGetVIOSFreeSCSIAdapter(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAddLit(&buf, "lsmap -all -field svsa backing -fmt , ");
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed '/,[^.*]/d; s/,//g; q'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-
-static int
-phypDomainAttachDeviceFlags(virDomainPtr domain,
- const char *xml,
- unsigned int flags)
-{
- int result = -1;
- virConnectPtr conn = domain->conn;
- phyp_driverPtr phyp_driver = domain->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- char *scsi_adapter = NULL;
- int slot = 0;
- char *vios_name = NULL;
- char *profile = NULL;
- virDomainDeviceDefPtr dev = NULL;
- virDomainDefPtr def = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *domain_name = NULL;
-
- virCheckFlags(0, -1);
-
- if (!(def = virDomainDefNew()))
- goto cleanup;
-
- domain_name = escape_specialcharacters(domain->name);
-
- if (domain_name == NULL)
- goto cleanup;
-
- def->os.type = VIR_DOMAIN_OSTYPE_LINUX;
-
- dev = virDomainDeviceDefParse(xml, def, NULL, NULL,
- VIR_DOMAIN_DEF_PARSE_INACTIVE);
- if (!dev)
- goto cleanup;
-
- if (!
- (vios_name =
- phypGetLparNAME(session, managed_system, vios_id, conn))) {
- VIR_ERROR(_("Unable to get VIOS name"));
- goto cleanup;
- }
-
- /* First, let's look for a free SCSI Adapter
- * */
- if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) {
- /* If not found, let's create one.
- * */
- if (phypCreateServerSCSIAdapter(conn) == -1) {
- VIR_ERROR(_("Unable to create new virtual adapter"));
- goto cleanup;
- } else {
- if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) {
- VIR_ERROR(_("Unable to create new virtual adapter"));
- goto cleanup;
- }
- }
- }
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "mkvdev -vdev %s -vadapter %s",
- virDomainDiskGetSource(dev->data.disk), scsi_adapter);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- if (!(profile = phypGetLparProfile(conn, domain->id))) {
- VIR_ERROR(_("Unable to get VIOS profile name."));
- goto cleanup;
- }
-
- /* Let's get the slot number for the adapter we just created
- * */
- virBufferAddLit(&buf, "lshwres -r virtualio --rsubtype scsi");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " slot_num,backing_device|grep %s|cut -d, -f1",
- virDomainDiskGetSource(dev->data.disk));
- if (phypExecInt(session, &buf, conn, &slot) < 0)
- goto cleanup;
-
- /* Listing all the virtual_scsi_adapter interfaces, the new adapter must
- * be appended to this list
- * */
- virBufferAddLit(&buf, "lssyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r prof --filter lpar_ids=%d,profile_names=%s"
- " -F virtual_scsi_adapters|sed -e 's/\"//g'",
- vios_id, profile);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- /* Here I change the LPAR configuration to append the new adapter
- * with the new slot we just created
- * */
- virBufferAddLit(&buf, "chsyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r prof -i 'name=%s,lpar_id=%d,"
- "\"virtual_scsi_adapters=%s,%d/client/%d/%s/0\"'",
- domain_name, domain->id, ret, slot,
- vios_id, vios_name);
- if (phypExecInt(session, &buf, conn, &slot) < 0)
- goto cleanup;
-
- /* Finally I add the new scsi adapter to VIOS using the same slot
- * I used in the VIOS configuration.
- * */
- virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
- domain_name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL) {
- VIR_ERROR(_
- ("Possibly you don't have IBM Tools installed in your LPAR."
- "Contact your support to enable this feature."));
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
- virDomainDeviceDefFree(dev);
- virDomainDefFree(def);
- VIR_FREE(vios_name);
- VIR_FREE(scsi_adapter);
- VIR_FREE(profile);
- VIR_FREE(domain_name);
-
- return result;
-}
-
-static int
-phypDomainAttachDevice(virDomainPtr domain, const char *xml)
-{
- return phypDomainAttachDeviceFlags(domain, xml, 0);
-}
-
-static char *
-phypStorageVolGetKey(virConnectPtr conn, const char *name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lslv %s -field lvid", name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed -e 's/^LV IDENTIFIER://' -e 's/ //g'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-static char *
-phypGetStoragePoolDevice(virConnectPtr conn, char *name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lssp -detail -sp %s -field name", name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed '1d; s/ //g'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-static unsigned long int
-phypGetStoragePoolSize(virConnectPtr conn, char *name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int sp_size = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lssp -detail -sp %s -field size", name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed '1d; s/ //g'");
- phypExecInt(session, &buf, conn, &sp_size);
- return sp_size;
-}
-
-static char *
-phypBuildVolume(virConnectPtr conn, const char *lvname, const char *spname,
- unsigned int capacity)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int vios_id = phyp_driver->vios_id;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *key = NULL;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "mklv -lv %s %s %d", lvname, spname, capacity);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0) {
- VIR_ERROR(_("Unable to create Volume: %s"), NULLSTR(ret));
- goto cleanup;
- }
-
- key = phypStorageVolGetKey(conn, lvname);
-
- cleanup:
- VIR_FREE(ret);
-
- return key;
-}
-
-static virStorageVolPtr
-phypStorageVolLookupByName(virStoragePoolPtr pool, const char *volname)
-{
- char *key;
- virStorageVolPtr vol;
-
- key = phypStorageVolGetKey(pool->conn, volname);
-
- if (key == NULL)
- return NULL;
-
- vol = virGetStorageVol(pool->conn, pool->name, volname, key, NULL, NULL);
-
- VIR_FREE(key);
-
- return vol;
-}
-
-static virStorageVolPtr
-phypStorageVolCreateXML(virStoragePoolPtr pool,
- const char *xml, unsigned int flags)
-{
- virCheckFlags(0, NULL);
-
- virStorageVolPtr vol = NULL;
- virStorageVolPtr dup_vol = NULL;
- char *key = NULL;
- g_autoptr(virStorageVolDef) voldef = NULL;
- g_autoptr(virStoragePoolDef) spdef = NULL;
-
- if (VIR_ALLOC(spdef) < 0)
- return NULL;
-
- /* Filling spdef manually
- * */
- if (pool->name != NULL) {
- spdef->name = pool->name;
- } else {
- VIR_ERROR(_("Unable to determine storage pool's name."));
- goto err;
- }
-
- if (memcpy(spdef->uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) {
- VIR_ERROR(_("Unable to determine storage pool's uuid."));
- goto err;
- }
-
- if ((spdef->capacity =
- phypGetStoragePoolSize(pool->conn, pool->name)) == -1) {
- VIR_ERROR(_("Unable to determine storage pools's size."));
- goto err;
- }
-
- /* Information not available */
- spdef->allocation = 0;
- spdef->available = 0;
-
- spdef->source.ndevice = 1;
-
- /*XXX source adapter not working properly, should show hdiskX */
- if ((spdef->source.adapter.data.scsi_host.name =
- phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) {
- VIR_ERROR(_("Unable to determine storage pools's source adapter."));
- goto err;
- }
-
- if ((voldef = virStorageVolDefParseString(spdef, xml, 0)) == NULL) {
- VIR_ERROR(_("Error parsing volume XML."));
- goto err;
- }
-
- /* checking if this name already exists on this system */
- if ((dup_vol = phypStorageVolLookupByName(pool, voldef->name)) != NULL) {
- VIR_ERROR(_("StoragePool name already exists."));
- virObjectUnref(dup_vol);
- goto err;
- }
-
- /* The key must be NULL, the Power Hypervisor creates a key
- * in the moment you create the volume.
- * */
- if (voldef->key) {
- VIR_ERROR(_("Key must be empty, Power Hypervisor will create one for you."));
- goto err;
- }
-
- if (!voldef->target.capacity) {
- VIR_ERROR(_("Capacity cannot be empty."));
- goto err;
- }
-
- key = phypBuildVolume(pool->conn, voldef->name, spdef->name,
- voldef->target.capacity);
-
- if (key == NULL)
- goto err;
-
- if ((vol =
- virGetStorageVol(pool->conn, pool->name, voldef->name,
- key, NULL, NULL)) == NULL)
- goto err;
-
- VIR_FREE(key);
-
- return vol;
-
- err:
- VIR_FREE(key);
- virObjectUnref(vol);
- return NULL;
-}
-
-static char *
-phypStorageVolGetPhysicalVolumeByStoragePool(virStorageVolPtr vol, char *sp)
-{
- virConnectPtr conn = vol->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lssp -detail -sp %s -field pvname", sp);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed 1d");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0)
- VIR_FREE(ret);
- return ret;
-}
-
-static virStorageVolPtr
-phypStorageVolLookupByPath(virConnectPtr conn, const char *volname)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- char *key = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- virStorageVolPtr vol = NULL;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lslv %s -field vgname", volname);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- key = phypStorageVolGetKey(conn, volname);
-
- if (key == NULL)
- goto cleanup;
-
- vol = virGetStorageVol(conn, ret, volname, key, NULL, NULL);
-
- cleanup:
- VIR_FREE(ret);
- VIR_FREE(key);
-
- return vol;
-}
-
-static int
-phypGetStoragePoolUUID(virConnectPtr conn, unsigned char *uuid,
- const char *name)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lsdev -dev %s -attr vgserial_id", name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed '1,2d'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- if (memcpy(uuid, ret, VIR_UUID_BUFLEN) == NULL)
- goto cleanup;
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static virStoragePoolPtr
-phypStoragePoolLookupByName(virConnectPtr conn, const char *name)
-{
- unsigned char uuid[VIR_UUID_BUFLEN];
-
- if (phypGetStoragePoolUUID(conn, uuid, name) == -1)
- return NULL;
-
- return virGetStoragePool(conn, name, uuid, NULL, NULL);
-}
-
-static char *
-phypStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
-{
- virStorageVolDef voldef;
- virStoragePoolDef pool;
- virStoragePoolPtr sp;
- char *xml = NULL;
-
- virCheckFlags(0, NULL);
-
- memset(&voldef, 0, sizeof(virStorageVolDef));
- memset(&pool, 0, sizeof(virStoragePoolDef));
-
- sp = phypStoragePoolLookupByName(vol->conn, vol->pool);
-
- if (!sp)
- goto cleanup;
-
- if (sp->name != NULL) {
- pool.name = sp->name;
- } else {
- VIR_ERROR(_("Unable to determine storage sp's name."));
- goto cleanup;
- }
-
- if (memcpy(pool.uuid, sp->uuid, VIR_UUID_BUFLEN) == NULL) {
- VIR_ERROR(_("Unable to determine storage sp's uuid."));
- goto cleanup;
- }
-
- if ((pool.capacity = phypGetStoragePoolSize(sp->conn, sp->name)) == -1) {
- VIR_ERROR(_("Unable to determine storage sps's size."));
- goto cleanup;
- }
-
- /* Information not available */
- pool.allocation = 0;
- pool.available = 0;
-
- pool.source.ndevice = 1;
-
- if ((pool.source.adapter.data.scsi_host.name =
- phypGetStoragePoolDevice(sp->conn, sp->name)) == NULL) {
- VIR_ERROR(_("Unable to determine storage sps's source adapter."));
- goto cleanup;
- }
-
- if (vol->name != NULL) {
- voldef.name = vol->name;
- } else {
- VIR_ERROR(_("Unable to determine storage pool's name."));
- goto cleanup;
- }
-
- voldef.key = g_strdup(vol->key);
-
- voldef.type = VIR_STORAGE_POOL_LOGICAL;
-
- xml = virStorageVolDefFormat(&pool, &voldef);
-
- VIR_FREE(voldef.key);
-
- cleanup:
- virObjectUnref(sp);
- return xml;
-}
-
-/* The Volume Group path here will be treated as suggested in the
- * email on the libvirt mailling list. As soon as I can't get the
- * path for every volume, the path will be a representation in
- * the form:
- *
- * /physical_volume/storage_pool/logical_volume
- *
- * */
-static char *
-phypStorageVolGetPath(virStorageVolPtr vol)
-{
- virConnectPtr conn = vol->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- char *ret = NULL;
- char *path = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *pv;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lslv %s -field vgname", vol->name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAsprintf(&buf,
- "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- pv = phypStorageVolGetPhysicalVolumeByStoragePool(vol, ret);
-
- if (!pv)
- goto cleanup;
-
- path = g_strdup_printf("/%s/%s/%s", pv, ret, vol->name);
-
- cleanup:
- VIR_FREE(ret);
- VIR_FREE(path);
-
- return path;
-}
-
-static int
-phypStoragePoolListVolumes(virStoragePoolPtr pool, char **const volumes,
- int nvolumes)
-{
- bool success = false;
- virConnectPtr conn = pool->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- int got = 0;
- size_t i;
- char *ret = NULL;
- char *volumes_list = NULL;
- char *char_ptr = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "lsvg -lv %s -field lvname", pool->name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|sed '1,2d'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- /* I need to parse the textual return in order to get the volumes */
- if (exit_status < 0 || ret == NULL) {
- goto cleanup;
- } else {
- volumes_list = ret;
-
- while (got < nvolumes) {
- char_ptr = strchr(volumes_list, '\n');
-
- if (char_ptr) {
- *char_ptr = '\0';
- volumes[got++] = g_strdup(volumes_list);
- char_ptr++;
- volumes_list = char_ptr;
- } else {
- break;
- }
- }
- }
-
- success = true;
-
- cleanup:
- if (!success) {
- for (i = 0; i < got; i++)
- VIR_FREE(volumes[i]);
-
- got = -1;
- }
- VIR_FREE(ret);
- return got;
-}
-
-static int
-phypStoragePoolNumOfVolumes(virStoragePoolPtr pool)
-{
- virConnectPtr conn = pool->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int nvolumes = -1;
- char *managed_system = phyp_driver->managed_system;
- int vios_id = phyp_driver->vios_id;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
- virBufferAsprintf(&buf, "lsvg -lv %s -field lvname", pool->name);
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- virBufferAddLit(&buf, "|grep -c '^.*$'");
- if (phypExecInt(session, &buf, conn, &nvolumes) < 0)
- return -1;
-
- /* We need to remove 2 line from the header text output */
- return nvolumes - 2;
-}
-
-static int
-phypStoragePoolDestroy(virStoragePoolPtr pool)
-{
- int result = -1;
- virConnectPtr conn = pool->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int vios_id = phyp_driver->vios_id;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "rmsp %s", pool->name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0) {
- VIR_ERROR(_("Unable to destroy Storage Pool: %s"), NULLSTR(ret));
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static int
-phypBuildStoragePool(virConnectPtr conn, virStoragePoolDefPtr def)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virStoragePoolSource source = def->source;
- int vios_id = phyp_driver->vios_id;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (source.adapter.type != VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Only 'scsi_host' adapter is supported"));
- goto cleanup;
- }
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAsprintf(&buf, "mksp -f %schild %s", def->name,
- source.adapter.data.scsi_host.name);
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0) {
- VIR_ERROR(_("Unable to create Storage Pool: %s"), NULLSTR(ret));
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-
-}
-
-static int
-phypConnectNumOfStoragePools(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- int nsp = -1;
- char *managed_system = phyp_driver->managed_system;
- int vios_id = phyp_driver->vios_id;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAddLit(&buf, "lsvg");
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
-
- virBufferAddLit(&buf, "|grep -c '^.*$'");
- phypExecInt(session, &buf, conn, &nsp);
- return nsp;
-}
-
-static int
-phypConnectListStoragePools(virConnectPtr conn, char **const pools, int npools)
-{
- bool success = false;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- int got = 0;
- size_t i;
- char *ret = NULL;
- char *storage_pools = NULL;
- char *char_ptr = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (system_type == HMC)
- virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
- managed_system, vios_id);
-
- virBufferAddLit(&buf, "lsvg");
-
- if (system_type == HMC)
- virBufferAddChar(&buf, '\'');
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- /* I need to parse the textual return in order to get the storage pools */
- if (exit_status < 0 || ret == NULL) {
- goto cleanup;
- } else {
- storage_pools = ret;
-
- while (got < npools) {
- char_ptr = strchr(storage_pools, '\n');
-
- if (char_ptr) {
- *char_ptr = '\0';
- pools[got++] = g_strdup(storage_pools);
- char_ptr++;
- storage_pools = char_ptr;
- } else {
- break;
- }
- }
- }
-
- success = true;
-
- cleanup:
- if (!success) {
- for (i = 0; i < got; i++)
- VIR_FREE(pools[i]);
-
- got = -1;
- }
- VIR_FREE(ret);
- return got;
-}
-
-static virStoragePoolPtr
-phypStoragePoolLookupByUUID(virConnectPtr conn,
- const unsigned char *uuid)
-{
- virStoragePoolPtr sp = NULL;
- int npools = 0;
- int gotpools = 0;
- char **pools = NULL;
- size_t i = 0;
- unsigned char *local_uuid = NULL;
-
- if (VIR_ALLOC_N(local_uuid, VIR_UUID_BUFLEN) < 0)
- goto err;
-
- if ((npools = phypConnectNumOfStoragePools(conn)) == -1)
- goto err;
-
- if (VIR_ALLOC_N(pools, npools) < 0)
- goto err;
-
- if ((gotpools = phypConnectListStoragePools(conn, pools, npools)) == -1)
- goto err;
-
- if (gotpools != npools) {
- virReportOOMError();
- goto err;
- }
-
- for (i = 0; i < gotpools; i++) {
- if (phypGetStoragePoolUUID(conn, local_uuid, pools[i]) == -1)
- continue;
-
- if (!memcmp(local_uuid, uuid, VIR_UUID_BUFLEN)) {
- sp = virGetStoragePool(conn, pools[i], uuid, NULL, NULL);
- VIR_FREE(local_uuid);
- VIR_FREE(pools);
-
- if (sp)
- return sp;
- else
- goto err;
- }
- }
-
- err:
- VIR_FREE(local_uuid);
- VIR_FREE(pools);
- return NULL;
-}
-
-static virStoragePoolPtr
-phypStoragePoolCreateXML(virConnectPtr conn,
- const char *xml, unsigned int flags)
-{
- virCheckFlags(0, NULL);
-
- virStoragePoolDefPtr def = NULL;
- virStoragePoolPtr dup_sp = NULL;
- virStoragePoolPtr sp = NULL;
-
- if (!(def = virStoragePoolDefParseString(xml)))
- goto err;
-
- /* checking if this name already exists on this system */
- if ((dup_sp = phypStoragePoolLookupByName(conn, def->name)) != NULL) {
- VIR_WARN("StoragePool name already exists.");
- virObjectUnref(dup_sp);
- goto err;
- }
-
- /* checking if ID or UUID already exists on this system */
- if ((dup_sp = phypStoragePoolLookupByUUID(conn, def->uuid)) != NULL) {
- VIR_WARN("StoragePool uuid already exists.");
- virObjectUnref(dup_sp);
- goto err;
- }
-
- if ((sp = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL)) == NULL)
- goto err;
-
- if (phypBuildStoragePool(conn, def) == -1)
- goto err;
-
- return sp;
-
- err:
- virStoragePoolDefFree(def);
- virObjectUnref(sp);
- return NULL;
-}
-
-static char *
-phypStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
-{
- virCheckFlags(0, NULL);
-
- virStoragePoolDef def;
- memset(&def, 0, sizeof(virStoragePoolDef));
-
- if (pool->name != NULL) {
- def.name = pool->name;
- } else {
- VIR_ERROR(_("Unable to determine storage pool's name."));
- goto err;
- }
-
- if (memcpy(def.uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) {
- VIR_ERROR(_("Unable to determine storage pool's uuid."));
- goto err;
- }
-
- if ((def.capacity =
- phypGetStoragePoolSize(pool->conn, pool->name)) == -1) {
- VIR_ERROR(_("Unable to determine storage pools's size."));
- goto err;
- }
-
- /* Information not available */
- def.allocation = 0;
- def.available = 0;
-
- def.source.ndevice = 1;
-
- /*XXX source adapter not working properly, should show hdiskX */
- if ((def.source.adapter.data.scsi_host.name =
- phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) {
- VIR_ERROR(_("Unable to determine storage pools's source adapter."));
- goto err;
- }
-
- return virStoragePoolDefFormat(&def);
-
- err:
- return NULL;
-}
-
-static int
-phypInterfaceDestroy(virInterfacePtr iface,
- unsigned int flags)
-{
- virCheckFlags(0, -1);
-
- phyp_driverPtr phyp_driver = iface->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int exit_status = 0;
- int slot_num = 0;
- int lpar_id = 0;
- char *ret = NULL;
- int rv = -1;
-
- /* Getting the remote slot number */
-
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth --level lpar "
- " -F mac_addr,slot_num|"
- " sed -n '/%s/ s/^.*,//p'", iface->mac);
- if (phypExecInt(session, &buf, iface->conn, &slot_num) < 0)
- goto cleanup;
-
- /* Getting the remote slot number */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth --level lpar "
- " -F mac_addr,lpar_id|"
- " sed -n '/%s/ s/^.*,//p'", iface->mac);
- if (phypExecInt(session, &buf, iface->conn, &lpar_id) < 0)
- goto cleanup;
-
- /* excluding interface */
- virBufferAddLit(&buf, "chhwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth"
- " --id %d -o r -s %d", lpar_id, slot_num);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, iface->conn, false);
-
- if (exit_status < 0 || ret != NULL)
- goto cleanup;
-
- rv = 0;
-
- cleanup:
- VIR_FREE(ret);
- return rv;
-}
-
-static virInterfacePtr
-phypInterfaceDefineXML(virConnectPtr conn, const char *xml,
- unsigned int flags)
-{
- virCheckFlags(0, NULL);
-
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int exit_status = 0;
- int slot = 0;
- char *ret = NULL;
- char name[PHYP_IFACENAME_SIZE];
- char mac[PHYP_MAC_SIZE];
- virInterfaceDefPtr def;
- virInterfacePtr result = NULL;
-
- if (!(def = virInterfaceDefParseString(xml)))
- goto cleanup;
-
- /* Now need to get the next free slot number */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype slot --level slot"
- " -Fslot_num --filter lpar_names=%s"
- " |sort|tail -n 1", def->name);
- if (phypExecInt(session, &buf, conn, &slot) < 0)
- goto cleanup;
-
- /* The next free slot itself: */
- slot++;
-
- /* Now adding the new network interface */
- virBufferAddLit(&buf, "chhwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth"
- " -p %s -o a -s %d -a port_vlan_id=1,"
- "ieee_virtual_eth=0", def->name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret != NULL)
- goto cleanup;
-
- /* Need to sleep a little while to wait for the HMC to
- * complete the execution of the command.
- * */
- sleep(1);
-
- /* Getting the new interface name */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype slot --level slot"
- " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; "
- "s/^.*drc_name=//'", def->name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL) {
- /* roll back and excluding interface if error*/
- virBufferAddLit(&buf, "chhwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth"
- " -p %s -o r -s %d", def->name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
- goto cleanup;
- }
-
- memcpy(name, ret, PHYP_IFACENAME_SIZE-1);
-
- /* Getting the new interface mac addr */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- "-r virtualio --rsubtype eth --level lpar "
- " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; "
- "s/^.*mac_addr=//'", def->name, slot);
- VIR_FREE(ret);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- memcpy(mac, ret, PHYP_MAC_SIZE-1);
-
- result = virGetInterface(conn, name, mac);
-
- cleanup:
- VIR_FREE(ret);
- virInterfaceDefFree(def);
- return result;
-}
-
-static virInterfacePtr
-phypInterfaceLookupByName(virConnectPtr conn, const char *name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int exit_status = 0;
- char *ret = NULL;
- int slot = 0;
- int lpar_id = 0;
- char mac[PHYP_MAC_SIZE];
- virInterfacePtr result = NULL;
-
- /*Getting the slot number for the interface */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype slot --level slot "
- " -F drc_name,slot_num |"
- " sed -n '/%s/ s/^.*,//p'", name);
- if (phypExecInt(session, &buf, conn, &slot) < 0)
- goto cleanup;
-
- /*Getting the lpar_id for the interface */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype slot --level slot "
- " -F drc_name,lpar_id |"
- " sed -n '/%s/ s/^.*,//p'", name);
- if (phypExecInt(session, &buf, conn, &lpar_id) < 0)
- goto cleanup;
-
- /*Getting the interface mac */
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth --level lpar "
- " -F lpar_id,slot_num,mac_addr|"
- " sed -n '/%d,%d/ s/^.*,//p'", lpar_id, slot);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- memcpy(mac, ret, PHYP_MAC_SIZE-1);
-
- result = virGetInterface(conn, name, ret);
-
- cleanup:
- VIR_FREE(ret);
- return result;
-}
-
-static int
-phypInterfaceIsActive(virInterfacePtr iface)
-{
- phyp_driverPtr phyp_driver = iface->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int state = -1;
-
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- " -r virtualio --rsubtype eth --level lpar "
- " -F mac_addr,state |"
- " sed -n '/%s/ s/^.*,//p'", iface->mac);
- phypExecInt(session, &buf, iface->conn, &state);
- return state;
-}
-
-static int
-phypConnectListInterfaces(virConnectPtr conn, char **const names, int nnames)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int vios_id = phyp_driver->vios_id;
- int exit_status = 0;
- int got = 0;
- size_t i;
- char *ret = NULL;
- char *networks = NULL;
- char *char_ptr = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- bool success = false;
-
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r virtualio --rsubtype slot --level slot|"
- " sed '/eth/!d; /lpar_id=%d/d; s/^.*drc_name=//g'",
- vios_id);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- /* I need to parse the textual return in order to get the network
- * interfaces */
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- networks = ret;
-
- while (got < nnames) {
- char_ptr = strchr(networks, '\n');
-
- if (char_ptr) {
- *char_ptr = '\0';
- names[got++] = g_strdup(networks);
- char_ptr++;
- networks = char_ptr;
- } else {
- break;
- }
- }
-
- cleanup:
- if (!success) {
- for (i = 0; i < got; i++)
- VIR_FREE(names[i]);
- }
- VIR_FREE(ret);
- return got;
-}
-
-static int
-phypConnectNumOfInterfaces(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- int system_type = phyp_driver->system_type;
- int vios_id = phyp_driver->vios_id;
- int nnets = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lshwres ");
- if (system_type == HMC)
- virBufferAsprintf(&buf, "-m %s ", managed_system);
-
- virBufferAsprintf(&buf,
- "-r virtualio --rsubtype eth --level lpar|"
- "grep -v lpar_id=%d|grep -c lpar_name", vios_id);
- phypExecInt(session, &buf, conn, &nnets);
- return nnets;
-}
-
-static int
-phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *ret = NULL;
- int exit_status = 0;
- char *managed_system = phyp_driver->managed_system;
- int state = VIR_DOMAIN_NOSTATE;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -F state --filter lpar_ids=%d", lpar_id);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- if (STREQ(ret, "Running"))
- state = VIR_DOMAIN_RUNNING;
- else if (STREQ(ret, "Not Activated"))
- state = VIR_DOMAIN_SHUTOFF;
- else if (STREQ(ret, "Shutting Down"))
- state = VIR_DOMAIN_SHUTDOWN;
-
- cleanup:
- VIR_FREE(ret);
- return state;
-}
-
-/* XXX - is this needed? */
-static int phypDiskType(virConnectPtr, char *) G_GNUC_UNUSED;
-static int
-phypDiskType(virConnectPtr conn, char *backing_device)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *ret = NULL;
- int exit_status = 0;
- char *managed_system = phyp_driver->managed_system;
- int vios_id = phyp_driver->vios_id;
- int disk_type = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "viosvrcmd");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -p %d -c \"lssp -field name type "
- "-fmt , -all|sed -n '/%s/ {\n s/^.*,//\n p\n}'\"",
- vios_id, backing_device);
- ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
-
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
-
- if (STREQ(ret, "LVPOOL"))
- disk_type = VIR_STORAGE_TYPE_BLOCK;
- else if (STREQ(ret, "FBPOOL"))
- disk_type = VIR_STORAGE_TYPE_FILE;
-
- cleanup:
- VIR_FREE(ret);
- return disk_type;
-}
-
-static int
-phypConnectNumOfDefinedDomains(virConnectPtr conn)
-{
- return phypConnectNumOfDomainsGeneric(conn, 1);
-}
-
-static int
-phypConnectNumOfDomains(virConnectPtr conn)
-{
- return phypConnectNumOfDomainsGeneric(conn, 0);
-}
-
-static int
-phypConnectListDomains(virConnectPtr conn, int *ids, int nids)
-{
- return phypConnectListDomainsGeneric(conn, ids, nids, 0);
-}
-
-static int
-phypConnectListDefinedDomains(virConnectPtr conn, char **const names, int nnames)
-{
- bool success = false;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- int got = 0;
- size_t i;
- char *ret = NULL;
- char *domains = NULL;
- char *char_ptr = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAddLit(&buf, " -F name,state"
- "|sed -n '/Not Activated/ {\n s/,.*$//\n p\n}'");
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- /* I need to parse the textual return in order to get the domains */
- if (exit_status < 0 || ret == NULL) {
- goto cleanup;
- } else {
- domains = ret;
-
- while (got < nnames) {
- char_ptr = strchr(domains, '\n');
-
- if (char_ptr) {
- *char_ptr = '\0';
- names[got++] = g_strdup(domains);
- char_ptr++;
- domains = char_ptr;
- } else {
- break;
- }
- }
- }
-
- success = true;
-
- cleanup:
- if (!success) {
- for (i = 0; i < got; i++)
- VIR_FREE(names[i]);
-
- got = -1;
- }
- VIR_FREE(ret);
- return got;
-}
-
-static virDomainPtr
-phypDomainLookupByName(virConnectPtr conn, const char *lpar_name)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int lpar_id = 0;
- char *managed_system = phyp_driver->managed_system;
- unsigned char lpar_uuid[VIR_UUID_BUFLEN];
-
- lpar_id = phypGetLparID(session, managed_system, lpar_name, conn);
- if (lpar_id == -1)
- return NULL;
-
- if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
- return NULL;
-
- return virGetDomain(conn, lpar_name, lpar_uuid, lpar_id);
-}
-
-static virDomainPtr
-phypDomainLookupByID(virConnectPtr conn, int lpar_id)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virDomainPtr dom = NULL;
- char *managed_system = phyp_driver->managed_system;
- unsigned char lpar_uuid[VIR_UUID_BUFLEN];
-
- char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id,
- conn);
-
- if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
- goto cleanup;
-
- dom = virGetDomain(conn, lpar_name, lpar_uuid, lpar_id);
-
- cleanup:
- VIR_FREE(lpar_name);
-
- return dom;
-}
-
-static char *
-phypDomainGetXMLDesc(virDomainPtr dom, unsigned int flags)
-{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virDomainDef def;
- char *managed_system = phyp_driver->managed_system;
- unsigned long long memory;
- unsigned int vcpus;
-
- virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
-
- memset(&def, 0, sizeof(virDomainDef));
-
- def.virtType = VIR_DOMAIN_VIRT_PHYP;
- def.id = dom->id;
-
- char *lpar_name = phypGetLparNAME(session, managed_system, def.id,
- dom->conn);
-
- if (lpar_name == NULL) {
- VIR_ERROR(_("Unable to determine domain's name."));
- goto err;
- }
-
- if (phypGetLparUUID(def.uuid, dom->id, dom->conn) == -1) {
- VIR_ERROR(_("Unable to generate random uuid."));
- goto err;
- }
-
- if ((memory = phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
- VIR_ERROR(_("Unable to determine domain's max memory."));
- goto err;
- }
-
- virDomainDefSetMemoryTotal(&def, memory);
-
- if ((def.mem.cur_balloon =
- phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
- VIR_ERROR(_("Unable to determine domain's memory."));
- goto err;
- }
-
- if ((vcpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
- VIR_ERROR(_("Unable to determine domain's CPU."));
- goto err;
- }
-
- if (virDomainDefSetVcpusMax(&def, vcpus, phyp_driver->xmlopt) < 0)
- goto err;
-
- if (virDomainDefSetVcpus(&def, vcpus) < 0)
- goto err;
-
- return virDomainDefFormat(&def, phyp_driver->xmlopt,
- virDomainDefFormatConvertXMLFlags(flags));
-
- err:
- return NULL;
-}
-
-static int
-phypDomainResume(virDomainPtr dom)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "chsysstate");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r lpar -o on --id %d -f %s",
- dom->id, dom->name);
- ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false);
-
- if (exit_status < 0)
- goto cleanup;
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static int
-phypDomainReboot(virDomainPtr dom, unsigned int flags)
-{
- int result = -1;
- virConnectPtr conn = dom->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virCheckFlags(0, -1);
-
- virBufferAddLit(&buf, "chsysstate");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf,
- " -r lpar -o shutdown --id %d --immed --restart",
- dom->id);
- ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false);
-
- if (exit_status < 0)
- goto cleanup;
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static int
-phypDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
-{
- int result = -1;
- virConnectPtr conn = dom->conn;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virCheckFlags(0, -1);
-
- virBufferAddLit(&buf, "chsysstate");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r lpar -o shutdown --id %d", dom->id);
- ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false);
-
- if (exit_status < 0)
- goto cleanup;
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static int
-phypDomainShutdown(virDomainPtr dom)
-{
- return phypDomainShutdownFlags(dom, 0);
-}
-
-static int
-phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
-{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- char *managed_system = phyp_driver->managed_system;
-
- info->state = phypGetLparState(dom->conn, dom->id);
-
- if ((info->maxMem =
- phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0)
- VIR_WARN("Unable to determine domain's max memory.");
-
- if ((info->memory =
- phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0)
- VIR_WARN("Unable to determine domain's memory.");
-
- if ((info->nrVirtCpu =
- phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
- VIR_WARN("Unable to determine domain's CPU.");
-
- return 0;
-}
-
-static int
-phypDomainGetState(virDomainPtr dom,
- int *state,
- int *reason,
- unsigned int flags)
-{
- virCheckFlags(0, -1);
-
- *state = phypGetLparState(dom->conn, dom->id);
- if (reason)
- *reason = 0;
-
- return 0;
-}
-
-static int
-phypDomainDestroyFlags(virDomainPtr dom,
- unsigned int flags)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virCheckFlags(0, -1);
-
- virBufferAddLit(&buf, "rmsyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r lpar --id %d", dom->id);
- ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false);
-
- if (exit_status < 0)
- goto cleanup;
-
- if (phypUUIDTable_RemLpar(dom->conn, dom->id) == -1)
- goto cleanup;
-
- dom->id = -1;
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static int
-phypDomainDestroy(virDomainPtr dom)
-{
- return phypDomainDestroyFlags(dom, 0);
-}
-
-static int
-phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
-{
- int result = -1;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (!def->mem.cur_balloon) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Field <currentMemory> on the domain XML file is "
- "missing or has invalid value"));
- goto cleanup;
- }
-
- if (!virDomainDefGetMemoryInitial(def)) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Field <memory> on the domain XML file is missing or "
- "has invalid value"));
- goto cleanup;
- }
-
- if (def->ndisks < 1) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Domain XML must contain at least one <disk> element."));
- goto cleanup;
- }
-
- if (!virDomainDiskGetSource(def->disks[0])) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("Field <src> under <disk> on the domain XML file is "
- "missing."));
- goto cleanup;
- }
-
- virBufferAddLit(&buf, "mksyscfg");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -r lpar -p %s -i min_mem=%lld,desired_mem=%lld,"
- "max_mem=%lld,desired_procs=%u,virtual_scsi_adapters=%s",
- def->name, def->mem.cur_balloon,
- def->mem.cur_balloon,
- virDomainDefGetMemoryInitial(def),
- virDomainDefGetVcpus(def),
- virDomainDiskGetSource(def->disks[0]));
- ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
-
- if (exit_status < 0) {
- VIR_ERROR(_("Unable to create LPAR. Reason: '%s'"), NULLSTR(ret));
- goto cleanup;
- }
-
- if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) {
- VIR_ERROR(_("Unable to add LPAR to the table"));
- goto cleanup;
- }
-
- result = 0;
-
- cleanup:
- VIR_FREE(ret);
-
- return result;
-}
-
-static virDomainPtr
-phypDomainCreateXML(virConnectPtr conn,
- const char *xml, unsigned int flags)
-{
- virCheckFlags(0, NULL);
-
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- virDomainDefPtr def = NULL;
- virDomainPtr dom = NULL;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- lparPtr *lpars = uuid_table->lpars;
- size_t i = 0;
- char *managed_system = phyp_driver->managed_system;
- unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
-
- virCheckFlags(VIR_DOMAIN_START_VALIDATE, NULL);
-
- if (flags & VIR_DOMAIN_START_VALIDATE)
- parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
-
- if (!(def = virDomainDefParseString(xml,
- phyp_driver->xmlopt,
- NULL,
- parse_flags)))
- goto err;
-
- /* checking if this name already exists on this system */
- if (phypGetLparID(session, managed_system, def->name, conn) != -1) {
- VIR_WARN("LPAR name already exists.");
- goto err;
- }
-
- /* checking if ID or UUID already exists on this system */
- for (i = 0; i < uuid_table->nlpars; i++) {
- if (lpars[i]->id == def->id || lpars[i]->uuid == def->uuid) {
- VIR_WARN("LPAR ID or UUID already exists.");
- goto err;
- }
- }
-
- if ((dom = virGetDomain(conn, def->name, def->uuid, def->id)) == NULL)
- goto err;
-
- if (phypBuildLpar(conn, def) == -1)
- goto err;
-
- if (phypDomainResume(dom) == -1)
- goto err;
-
- return dom;
-
- err:
- virDomainDefFree(def);
- virObjectUnref(dom);
- return NULL;
-}
-
-static char *
-phypConnectGetCapabilities(virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
-
- return virCapabilitiesFormatXML(phyp_driver->caps);
-}
-
-static int
-phypDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
- unsigned int flags)
-{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *ret = NULL;
- char operation;
- unsigned long ncpus = 0;
- unsigned int amount = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (flags != VIR_DOMAIN_VCPU_LIVE) {
- virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
- return -1;
- }
-
- if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
- return 0;
-
- if (nvcpus > phypDomainGetMaxVcpus(dom)) {
- VIR_ERROR(_("You are trying to set a number of CPUs bigger than "
- "the max possible."));
- return 0;
- }
-
- if (ncpus > nvcpus) {
- operation = 'r';
- amount = nvcpus - ncpus;
- } else if (ncpus < nvcpus) {
- operation = 'a';
- amount = nvcpus - ncpus;
- } else {
- return 0;
- }
-
- virBufferAddLit(&buf, "chhwres -r proc");
- if (system_type == HMC)
- virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " --id %d -o %c --procunits %d 2>&1 |sed "
- "-e 's/^.*\\([0-9][0-9]*.[0-9][0-9]*\\).*$/\\1/'",
- dom->id, operation, amount);
- ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false);
-
- if (exit_status < 0) {
- VIR_ERROR(_
- ("Possibly you don't have IBM Tools installed in your LPAR."
- " Contact your support to enable this feature."));
- }
-
- VIR_FREE(ret);
- return 0;
-
-}
-
-static int
-phypDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
-{
- return phypDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE);
-}
-
-static int
-phypDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
-{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = phyp_driver->session;
- char *managed_system = phyp_driver->managed_system;
- char *lpar_name = NULL;
- int ret = -1;
-
- virCheckFlags(0, -1);
-
- lpar_name = phypGetLparNAME(session, managed_system, dom->id, dom->conn);
-
- if (lpar_name == NULL) {
- VIR_ERROR(_("Unable to determine domain's name."));
- goto cleanup;
- }
-
- ret = 0;
-
- cleanup:
- VIR_FREE(lpar_name);
- return ret;
-}
-
-static virHypervisorDriver phypHypervisorDriver = {
- .name = "PHYP",
- .connectOpen = phypConnectOpen, /* 0.7.0 */
- .connectClose = phypConnectClose, /* 0.7.0 */
- .connectGetCapabilities = phypConnectGetCapabilities, /* 0.7.3 */
- .connectListDomains = phypConnectListDomains, /* 0.7.0 */
- .connectNumOfDomains = phypConnectNumOfDomains, /* 0.7.0 */
- .domainCreateXML = phypDomainCreateXML, /* 0.7.3 */
- .domainLookupByID = phypDomainLookupByID, /* 0.7.0 */
- .domainLookupByName = phypDomainLookupByName, /* 0.7.0 */
- .domainResume = phypDomainResume, /* 0.7.0 */
- .domainShutdown = phypDomainShutdown, /* 0.7.0 */
- .domainShutdownFlags = phypDomainShutdownFlags, /* 5.6.0 */
- .domainReboot = phypDomainReboot, /* 0.9.1 */
- .domainDestroy = phypDomainDestroy, /* 0.7.3 */
- .domainDestroyFlags = phypDomainDestroyFlags, /* 0.9.4 */
- .domainGetInfo = phypDomainGetInfo, /* 0.7.0 */
- .domainGetState = phypDomainGetState, /* 0.9.2 */
- .domainSetVcpus = phypDomainSetVcpus, /* 0.7.3 */
- .domainSetVcpusFlags = phypDomainSetVcpusFlags, /* 0.8.5 */
- .domainGetVcpusFlags = phypDomainGetVcpusFlags, /* 0.8.5 */
- .domainGetMaxVcpus = phypDomainGetMaxVcpus, /* 0.7.3 */
- .domainGetXMLDesc = phypDomainGetXMLDesc, /* 0.7.0 */
- .connectListDefinedDomains = phypConnectListDefinedDomains, /* 0.7.0 */
- .connectNumOfDefinedDomains = phypConnectNumOfDefinedDomains, /* 0.7.0 */
- .domainAttachDevice = phypDomainAttachDevice, /* 0.8.2 */
- .domainAttachDeviceFlags = phypDomainAttachDeviceFlags, /* 5.6.0 */
- .connectIsEncrypted = phypConnectIsEncrypted, /* 0.7.3 */
- .connectIsSecure = phypConnectIsSecure, /* 0.7.3 */
- .domainIsUpdated = phypDomainIsUpdated, /* 0.8.6 */
- .connectIsAlive = phypConnectIsAlive, /* 0.9.8 */
- .domainHasManagedSaveImage = phypDomainHasManagedSaveImage, /* 1.2.13 */
-};
-
-static virStorageDriver phypStorageDriver = {
- .connectNumOfStoragePools = phypConnectNumOfStoragePools, /* 0.8.2 */
- .connectListStoragePools = phypConnectListStoragePools, /* 0.8.2 */
- .storagePoolLookupByName = phypStoragePoolLookupByName, /* 0.8.2 */
- .storagePoolLookupByUUID = phypStoragePoolLookupByUUID, /* 0.8.2 */
- .storagePoolCreateXML = phypStoragePoolCreateXML, /* 0.8.2 */
- .storagePoolDestroy = phypStoragePoolDestroy, /* 0.8.2 */
- .storagePoolGetXMLDesc = phypStoragePoolGetXMLDesc, /* 0.8.2 */
- .storagePoolNumOfVolumes = phypStoragePoolNumOfVolumes, /* 0.8.2 */
- .storagePoolListVolumes = phypStoragePoolListVolumes, /* 0.8.2 */
-
- .storageVolLookupByName = phypStorageVolLookupByName, /* 0.8.2 */
- .storageVolLookupByPath = phypStorageVolLookupByPath, /* 0.8.2 */
- .storageVolCreateXML = phypStorageVolCreateXML, /* 0.8.2 */
- .storageVolGetXMLDesc = phypStorageVolGetXMLDesc, /* 0.8.2 */
- .storageVolGetPath = phypStorageVolGetPath, /* 0.8.2 */
-};
-
-static virInterfaceDriver phypInterfaceDriver = {
- .connectNumOfInterfaces = phypConnectNumOfInterfaces, /* 0.9.1 */
- .connectListInterfaces = phypConnectListInterfaces, /* 0.9.1 */
- .interfaceLookupByName = phypInterfaceLookupByName, /* 0.9.1 */
- .interfaceDefineXML = phypInterfaceDefineXML, /* 0.9.1 */
- .interfaceDestroy = phypInterfaceDestroy, /* 0.9.1 */
- .interfaceIsActive = phypInterfaceIsActive /* 0.9.1 */
-};
-
-static virConnectDriver phypConnectDriver = {
- .remoteOnly = true,
- .uriSchemes = (const char *[]){ "phyp", NULL },
- .hypervisorDriver = &phypHypervisorDriver,
- .interfaceDriver = &phypInterfaceDriver,
- .storageDriver = &phypStorageDriver,
-};
-
-int
-phypRegister(void)
-{
- return virRegisterConnectDriver(&phypConnectDriver,
- false);
-}
diff --git a/src/phyp/phyp_driver.h b/src/phyp/phyp_driver.h
deleted file mode 100644
index d7076e3697..0000000000
--- a/src/phyp/phyp_driver.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2010, 2013 Red Hat, Inc.
- * Copyright IBM Corp. 2009
- *
- * phyp_driver.c: ssh layer to access Power Hypervisors
- *
- * 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/>.
- */
-
-#pragma once
-
-int phypRegister(void);
--
2.23.0
4 years, 11 months
[libvirt] Xen + libvirt + TPM
by Arthur Borsboom
Hello,
I am trying to get TPM 2.0 pass through to work with Xen and libvirt, but I
can't get it to work.
According to the following sites both Xen and libirt have TPM 2.0 support.
https://wiki.xen.org/wiki/Virtual_Trusted_Platform_Module_(vTPM)
https://libvirt.org/formatdomain.html#elementsTpm
However, when I add a TPM device to a VM (by virt-manager), the VM guest
XML does contain the TPM configuration, but the VM guest (linux) does not
show any TPM device.
Also, when looking in /var/log/libvirt/libxl/vmguest.log there is no
mention of tpm in the (converted libvirt XML to libxl) vm structure.
Is this because libvirt only supports TPM with QEMU?
If so, are there any development plans for TPM support with XEN?
Is there a workaround for the time being?
Best regards,
Arthur Borsboom.
4 years, 11 months
[libvirt] [PATCH 0/2] qemu_firmware: Try to autofill for old style UEFI specification
by Michal Privoznik
See 2/2 for info.
Michal Prívozník (2):
qemu_firmware: Pass virDomainDef into qemuFirmwareFillDomain()
qemu_firmware: Try to autofill for old style UEFI specification
src/qemu/qemu_firmware.c | 90 +++++++++++++++++++++++++++++++++-------
src/qemu/qemu_firmware.h | 2 +-
src/qemu/qemu_process.c | 2 +-
3 files changed, 78 insertions(+), 16 deletions(-)
--
2.24.1
4 years, 11 months
[libvirt] [jenkins-ci PATCH 0/2] CentOS fixes
by Fabiano Fidêncio
This series consists in two simple patches:
- Mention CentOS8 as a valid OS version;
- Only install OpenVZ on CentOS 7;
Fabiano Fidêncio (2):
guests: Mention CentOS8 as a valid OS version
guests: Only install OpenVZ on CentOS 7
guests/playbooks/update/tasks/base.yml | 1 +
guests/vars/mappings.yml | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
--
2.23.0
4 years, 12 months