[PATCH] qemu_extdevice: Add a comment into qemuExtDevicesSetupCgroup()
by Michal Privoznik
The way setting up CGroups for external helpers work, is:
qemuExtDevicesHasDevice() is called first to determine whether
there is a helper process running, the CGroup controller is
created and then qemuExtDevicesSetupCgroup() is called to place
helpers into the CGroup. But when one reads just
qemuExtDevicesSetupCgroup() it's easy to miss this hidden logic.
Therefore, add a warning at the beginning of the function.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_extdevice.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 47e97f3565..1c397972e4 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -331,6 +331,9 @@ qemuExtDevicesSetupCgroup(virQEMUDriver *driver,
virDomainDef *def = vm->def;
size_t i;
+ /* Don't forget to adjust qemuExtDevicesHasDevice() accordingly.
+ * Otherwise, this function might not be called at all. */
+
if (qemuDBusSetupCgroup(driver, vm, cgroup) < 0)
return -1;
--
2.39.1
1 year, 10 months
wiki.libvirt.org replacement
by Peter Krempa
https://gitlab.com/libvirt/libvirt-wiki/-/merge_requests/1
Hi,
in order to ease editing of the libvirt wiki, remove the need for
registering users and remove the need to run PHP in an openshift instance
I've decided to contents of the libvirt wiki into a staticaly generated
page using (almost) the same approach we use to generate the libvirt web
pages from rST documents in the repo.
All articles were converted into rST files [1] and images linked from
currently existing articles were dowloaded.
Advantages:
- same workflow as with editing the libvirt pages
- gitlab still provides a web editor
- local editing for users who hate web
- no need to deal with user registration
- no need to run PHP in openshift
- we still keep separate space for docs which don't really belong into the
main repo
- even if we decide to kill-off the wiki eventually the valuable content
will be easier to port to the kbase as it'll be in rST
- the conversion fixed many orphaned pages
Disadvantages:
- all links will be broken [2]
- changes will need to be reviewed/approved
- low quality/obsolete content is forward-ported as I didn't review
anything
- the build script is in bash (This obviously can be changed if somebody
cares more than I do.)
The generator is based on a cleaned up page.xsl and other assets from
libvirt's repo and the check-html-references script [3] to validate linking.
The new wiki can for now be browsed from artifacts of the pipeline job that
I've used to test it:
https://pipo.sk.gitlab.io/-/libvirt-wiki/-/jobs/3771076975/artifacts/webs...
(I know my username is unfortunate to contain a dot which breaks the
certificate)
If somebody wishes to see the extremely ugly conversion scripts:
https://gitlab.com/pipo.sk/libvirt-wiki/-/commit/fe36e37d3580a76ca18e5123...
[1] The conversion was done using a collection of ugly scripts and pandoc.
Unfortunately markdown-eque formats have the issue of not really having
strict rules and in certain cases the tools used to process them not
implementing them correctly. This meant that the least painful was actually
the coversion from HTML!!! and not the internal mediawiki format.
[2] If we really want to preserve links I can modify the script to generate
a list of redirects for the webserver, but I really doubt that preserving
links has value. Additionally some content was moved to the knowledge base,
so I really want to just delete it from the wiki, so breaking links is a
feature.
[3] It uses the version after the last patchset:
https://listman.redhat.com/archives/libvir-list/2023-February/237785.html
1 year, 10 months
[PATCH 0/9] Improve docs web reference checker
by Peter Krempa
Improve the checker tool to also track orphaned pages and check presence
and usage of images. In addition to that this series fixes handful of
instances of the problems that the script caught.
This series adds two documents:
- docs/logos/README.rst (converted into docs/logos/index.html)
The page shows all logos which libvirt has. It's now linked from the
docs page.
https://pipo.sk.gitlab.io/-/libvirt/-/jobs/3770134533/artifacts/website/l...
- docs/golang.rst
The page ties together the 4 go module pages we have which were not
linked and is linked from docs.html
https://pipo.sk.gitlab.io/-/libvirt/-/jobs/3770134533/artifacts/website/g...
Peter Krempa (9):
docs: XSL: Add source document name as custom data attribute for
<html>
scripts: check-html-references: Rename --prefix to --webroot and make
it mandatory
scripts: check-html-references: Improve error messages and don't mess
with relative paths
docs: manpages: Add missing manpages to index
docs: Add sub-page for all golang modules
scripts: check-html-references: Detect pages that are not linked to
kbase: eventloop: Fix path to referenced images
docs: logos: Turn 'README' into rST, generate an index and link to
images
scripts: check-html-refernces: Add checking for image file usage
docs/docs.rst | 5 +-
docs/golang.rst | 21 +++
docs/kbase/internals/eventloop.rst | 4 +-
docs/logos/README | 98 --------------
docs/logos/README.rst | 166 ++++++++++++++++++++++++
docs/logos/meson.build | 47 +++++++
docs/manpages/index.rst | 3 +
docs/meson.build | 3 +-
docs/page.xsl | 2 +-
scripts/check-html-references.py | 198 +++++++++++++++++++++++------
10 files changed, 406 insertions(+), 141 deletions(-)
create mode 100644 docs/golang.rst
delete mode 100644 docs/logos/README
create mode 100644 docs/logos/README.rst
--
2.39.1
1 year, 10 months
[PATCH 0/3] Virtlogd fixes
by Peter Krempa
Please see individual patches for justification.
Peter Krempa (3):
rpc: client: Don't check return value of virNetMessageNew
rpc: Don't warn about "max_client_requests" in single-threaded daemons
virLogCleanerShutdown: Don't call g_regex_unref on NULL regex
src/logging/log_cleaner.c | 3 +--
src/remote/libvirtd.conf.in | 1 +
src/rpc/virnetserverclient.c | 14 ++++++--------
3 files changed, 8 insertions(+), 10 deletions(-)
--
2.39.1
1 year, 10 months
there is no PCIe device after command "virsh nodedev-list"
by Martin Bayern
Hello,
I don't know if this is the right email list for this question, let me try.
I experienced a problem when I want to assign PCIe VF to my VMs, I can
use "lspci" to list the VF PCIe, even PF PCIe, but the command " virsh
nodedev-list"
doesn't print any PCIe bus device. I tried using "virsh edit --domain "
command and added the PCIe bus to the XML file, but when I start the VM,
the error message
shows an internal error, there is an invalid link to the device.
Meanwhile, I use virt-manager to see if I can add a PCIe host device,
but the host device shows "no device available".
my system is ARM64 based Nvidia platform, I have enabled IOMMU in the
kernel. do you know how can I figure out the root cause? is this the
ARM64 kernel issue or something else??
I posted this issue also in Nvidia forum:
https://forums.developer.nvidia.com/t/nvidia-orin-pcie-device-there-is-no...
thanks so much for your suggestions.
Martin
1 year, 10 months
[libvirt PATCH] qemu: allow passt to self-daemonize
by Laine Stump
I initially had the passt process being started in an identical
fashion to the slirp-helper - libvirt was daemonizing the new process
and recording its pid in a pidfile. The problem with this is that,
since it is daemonized immediately, any startup error in passt happens
after the daemonization, and thus isn't seen by libvirt - libvirt
believes that the process has started successfully and continues on
its merry way. The result was that sometimes a guest would be started,
but there would be no passt process for qemu to use for network
traffic.
Instead, we should be starting passt in the same manner we start
dnsmasq - we just exec it as normal (along with a request that passt
create the pidfile, which is just another option on the passt
commandline) and wait for the child process to exit; passt then has a
chance to parse its commandline and complete all the setup prior to
daemonizing itself; if it encounters an error and exits with a non-0
code, libvirt will see the code and know about the failure. We can
then grab the output from stderr, log that so the "user" has some idea
of what went wrong, and then fail the guest startup.
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
src/qemu/qemu_passt.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c
index 0f09bf3db8..f640a69c00 100644
--- a/src/qemu/qemu_passt.c
+++ b/src/qemu/qemu_passt.c
@@ -141,24 +141,23 @@ qemuPasstStart(virDomainObj *vm,
g_autofree char *passtSocketName = qemuPasstCreateSocketPath(vm, net);
g_autoptr(virCommand) cmd = NULL;
g_autofree char *pidfile = qemuPasstCreatePidFilename(vm, net);
+ g_autofree char *errbuf = NULL;
char macaddr[VIR_MAC_STRING_BUFLEN];
size_t i;
pid_t pid = (pid_t) -1;
int exitstatus = 0;
int cmdret = 0;
- VIR_AUTOCLOSE errfd = -1;
cmd = virCommandNew(PASST);
virCommandClearCaps(cmd);
- virCommandSetPidFile(cmd, pidfile);
- virCommandSetErrorFD(cmd, &errfd);
- virCommandDaemonize(cmd);
+ virCommandSetErrorBuffer(cmd, &errbuf);
virCommandAddArgList(cmd,
"--one-off",
"--socket", passtSocketName,
"--mac-addr", virMacAddrFormat(&net->mac, macaddr),
+ "--pid", pidfile,
NULL);
if (net->mtu) {
@@ -264,7 +263,7 @@ qemuPasstStart(virDomainObj *vm,
if (cmdret < 0 || exitstatus != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not start 'passt'. exitstatus: %d"), exitstatus);
+ _("Could not start 'passt': %s"), errbuf);
goto error;
}
--
2.39.1
1 year, 10 months
Plans for the next release
by Jiri Denemark
We are getting close to the next release of libvirt. To aim for the
release on Mar 01 I suggest entering the freeze on Wednesday Feb 22 and
tagging RC2 on Monday Feb 27.
I hope this works for everyone.
Jirka
1 year, 10 months
[PATCH] feature: Ceph rbd create with data pool attributes set support.
by Guozhonghua
In some cases, we may use another pool to store the data and one pool to
store the meta data of the rbd vol, so it is to use another interface to
create the rbd vol, rbd_create4, required.
This patch add the feature with xml configure is like as below:
<source>
<host name='xxx.xxx.xxx.xxx' port='6789'/>
<host name='xxx.xxx.xxx.xxx' port='6789'/>
<name>rbd_pool</name>
<auth type='ceph' username='user_name'>
<secret uuid='972327af-360b-4a68-9b0f-99dec10a05dc'/>
</auth>
<rbdimageoption format='x' feature='x' order='x' stripeunit='x' stripecount='x' journalorder='x' journalpool='x' featureset='x' featureclear='x' datapool='x' flatten='x' cloneformat=' mirrorimagemode=''/>
</source>
Here we add one item rbdimageoption to set the attributions used when
create rbd vol.
If the option is not set, then the origin interface rbd_create is
called as before.
Signed-off-by: Guozhonghua <guozh88(a)chinatelecom.cn>
---
src/conf/storage_conf.c | 205 ++++++++++++++++++++++++++++++
src/conf/storage_conf.h | 33 +++++
src/storage/storage_backend_rbd.c | 123 +++++++++++++++++-
3 files changed, 358 insertions(+), 3 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index f5a9636ce2..ac6c700ac1 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -461,6 +461,14 @@ virStoragePoolSourceDeviceClear(virStoragePoolSourceDevice *dev)
}
+void
+virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option)
+{
+ VIR_FREE(rbd_image_option->journal_pool);
+ VIR_FREE(rbd_image_option->data_pool);
+}
+
+
void
virStoragePoolSourceClear(virStoragePoolSource *source)
{
@@ -484,6 +492,7 @@ virStoragePoolSourceClear(virStoragePoolSource *source)
VIR_FREE(source->vendor);
VIR_FREE(source->product);
VIR_FREE(source->protocolVer);
+ virRbdImageOptionClear(&source->rbdImageOptions);
}
@@ -514,6 +523,131 @@ virStoragePoolDefFree(virStoragePoolDef *def)
}
+int
+virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt)
+{
+ VIR_XPATH_NODE_AUTORESTORE(ctxt)
+ char *val = NULL;
+
+ ctxt->node = node;
+
+ rbd_image_option->format = -1;
+ if ((val = virXMLPropString(node, "format"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->format) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->feature = -1;
+ if ((val = virXMLPropString(node, "feature"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->order = -1;
+ if ((val = virXMLPropString(node, "order"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->order) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->stripe_unit = -1;
+ if ((val = virXMLPropString(node, "stripeunit"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->stripe_unit) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->stripe_count = -1;
+ if ((val = virXMLPropString(node, "stripecount"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->stripe_count) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->journal_order = -1;
+ if ((val = virXMLPropString(node, "journalorder"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->journal_order) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->journal_splay_width = -1;
+ if ((val = virXMLPropString(node, "journalsplaywidth"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->journal_splay_width) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->journal_pool = virXMLPropString(node, "journalpool");
+
+ rbd_image_option->feature_set = -1;
+ if ((val = virXMLPropString(node, "featureset"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature_set) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->feature_clear = -1;
+ if ((val = virXMLPropString(node, "featureclear"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->feature_clear) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->data_pool = virXMLPropString(node, "datapool");
+
+ rbd_image_option->flatten = -1;
+ if ((val = virXMLPropString(node, "flatten"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->flatten) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->clone_format = -1;
+ if ((val = virXMLPropString(node, "cloneformat"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->clone_format) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ rbd_image_option->mirror_image_mode = -1;
+ if ((val = virXMLPropString(node, "mirrorimagemode"))) {
+ if (virStrToLong_l(val, NULL, 10, &rbd_image_option->mirror_image_mode) < 0)
+ goto cleanup;
+ VIR_FREE(val);
+ }
+
+ return 0;
+cleanup:
+ VIR_FREE(val);
+ return -1;
+}
+
+
+ void
+ virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option)
+ {
+ rbd_image_option->format = -1;
+ rbd_image_option->feature = -1;
+ rbd_image_option->order = -1;
+ rbd_image_option->stripe_unit = -1;
+ rbd_image_option->stripe_count = -1;
+ rbd_image_option->journal_order = -1;
+ rbd_image_option->journal_splay_width = -1;
+ rbd_image_option->journal_pool = NULL;
+ rbd_image_option->feature_set = -1;
+ rbd_image_option->feature_clear = -1;
+ rbd_image_option->data_pool = NULL;
+ rbd_image_option->flatten = -1;
+ rbd_image_option->clone_format = -1;
+ rbd_image_option->mirror_image_mode = -1;
+ }
+
+
static int
virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
virStoragePoolSource *source,
@@ -522,6 +656,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
{
xmlNodePtr authnode;
xmlNodePtr adapternode;
+ xmlNodePtr rbdimageoption;
int nsource;
size_t i;
virStoragePoolOptions *options;
@@ -633,6 +768,13 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
source->auth = g_steal_pointer(&authdef);
}
+ if ((rbdimageoption = virXPathNode("./rbdimageoption", ctxt))) {
+ if (virRbdImageOptionParseXML(&source->rbdImageOptions, rbdimageoption, ctxt) < 0)
+ goto cleanup;
+ } else {
+ virRbdImageOptionDefaultSet(&source->rbdImageOptions);
+ }
+
/* Option protocol version string (NFSvN) */
if ((source->protocolVer = virXPathString("string(./protocol/@ver)", ctxt))) {
if ((source->format != VIR_STORAGE_POOL_NETFS_NFS) &&
@@ -988,6 +1130,67 @@ virStoragePoolDefParse(const char *xmlStr,
}
+static void
+virRbdImageOptionFormat(virBufferPtr buf,
+ virRbdImageOptionsPtr rbdImageOptions)
+{
+ // not set the rbd image options.
+ if (rbdImageOptions->format < 0 && rbdImageOptions->feature < 0 && rbdImageOptions->order < 0
+ && rbdImageOptions->stripe_unit < 0 && rbdImageOptions->stripe_count < 0 && rbdImageOptions->journal_order < 0
+ && rbdImageOptions->journal_splay_width < 0 && (rbdImageOptions->journal_pool != NULL) && rbdImageOptions->feature_set < 0
+ && rbdImageOptions->feature_clear < 0 && (rbdImageOptions->data_pool != NULL) && rbdImageOptions->flatten < 0
+ && rbdImageOptions->clone_format < 0 && rbdImageOptions->mirror_image_mode < 0)
+ return;
+
+ virBufferAsprintf(buf, "<rbdimageoption");
+
+ if (rbdImageOptions->format >= 0)
+ virBufferAsprintf(buf, " format='%ld'", rbdImageOptions->format);
+
+ if (rbdImageOptions->feature >= 0)
+ virBufferAsprintf(buf, " feature='%ld'", rbdImageOptions->feature);
+
+ if (rbdImageOptions->order >= 0)
+ virBufferAsprintf(buf, " order='%ld'", rbdImageOptions->order);
+
+ if (rbdImageOptions->stripe_unit >= 0)
+ virBufferAsprintf(buf, " stripeunit='%ld'", rbdImageOptions->stripe_unit);
+
+ if (rbdImageOptions->stripe_count >= 0)
+ virBufferAsprintf(buf, " stripecount='%ld'", rbdImageOptions->stripe_count);
+
+ if (rbdImageOptions->journal_order >= 0)
+ virBufferAsprintf(buf, " journalorder='%ld'", rbdImageOptions->journal_order);
+
+ if (rbdImageOptions->journal_splay_width >= 0)
+ virBufferAsprintf(buf, " journalsplaywidth='%ld'", rbdImageOptions->journal_splay_width);
+
+ if (rbdImageOptions->journal_pool)
+ virBufferAsprintf(buf, " journalpool='%s'", rbdImageOptions->journal_pool);
+
+ if (rbdImageOptions->feature_set >= 0)
+ virBufferAsprintf(buf, " featureset='%ld'", rbdImageOptions->feature_set);
+
+ if (rbdImageOptions->feature_clear >= 0)
+ virBufferAsprintf(buf, " featureclear='%ld'", rbdImageOptions->feature_clear);
+
+ if (rbdImageOptions->data_pool)
+ virBufferAsprintf(buf, " datapool='%s'", rbdImageOptions->data_pool);
+
+ if (rbdImageOptions->flatten >= 0)
+ virBufferAsprintf(buf, " flatten='%ld'", rbdImageOptions->flatten);
+
+ if (rbdImageOptions->clone_format >= 0)
+ virBufferAsprintf(buf, " cloneformat='%ld'", rbdImageOptions->clone_format);
+
+ if (rbdImageOptions->mirror_image_mode >= 0)
+ virBufferAsprintf(buf, " mirrorimagemode='%ld'", rbdImageOptions->mirror_image_mode);
+
+ virBufferAsprintf(buf, "/>\n");
+}
+
+
+
static int
virStoragePoolSourceFormat(virBuffer *buf,
virStoragePoolOptions *options,
@@ -1066,6 +1269,8 @@ virStoragePoolSourceFormat(virBuffer *buf,
virBufferEscapeString(buf, "<vendor name='%s'/>\n", src->vendor);
virBufferEscapeString(buf, "<product name='%s'/>\n", src->product);
+ virRbdImageOptionFormat(buf, &src->rbdImageOptions);
+
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</source>\n");
return 0;
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index fc67957cfe..377ea1cfe2 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -175,6 +175,25 @@ struct _virStoragePoolFeatures {
virTristateBool cow;
};
+typedef struct _virRbdImageOptions virRbdImageOptions;
+typedef virRbdImageOptions *virRbdImageOptionsPtr;
+struct _virRbdImageOptions {
+ int64_t format;
+ int64_t feature;
+ int64_t order;
+ int64_t stripe_unit;
+ int64_t stripe_count;
+ int64_t journal_order;
+ int64_t journal_splay_width;
+ char *journal_pool;
+ int64_t feature_set;
+ int64_t feature_clear;
+ char *data_pool;
+ int64_t flatten;
+ int64_t clone_format;
+ int64_t mirror_image_mode;
+};
+
typedef struct _virStoragePoolSource virStoragePoolSource;
struct _virStoragePoolSource {
@@ -214,6 +233,9 @@ struct _virStoragePoolSource {
/* Protocol version value for netfs */
char *protocolVer;
+
+ /* RBD Image Options definition. */
+ virRbdImageOptions rbdImageOptions;
};
typedef struct _virStoragePoolTarget virStoragePoolTarget;
@@ -314,6 +336,9 @@ virStoragePoolSaveConfig(const char *configFile,
void
virStorageVolDefFree(virStorageVolDef *def);
+void
+virRbdImageOptionClear(virRbdImageOptionsPtr rbd_image_option);
+
void
virStoragePoolSourceClear(virStoragePoolSource *source);
@@ -326,6 +351,14 @@ virStoragePoolSourceFree(virStoragePoolSource *source);
void
virStoragePoolDefFree(virStoragePoolDef *def);
+int
+virRbdImageOptionParseXML(virRbdImageOptionsPtr rbd_image_option,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt);
+
+void
+virRbdImageOptionDefaultSet(virRbdImageOptionsPtr rbd_image_option);
+
virStoragePoolSource *
virStoragePoolDefParseSourceString(const char *srcSpec,
int pool_type);
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 05b2c43f79..29c651cbcd 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -878,10 +878,127 @@ virStorageBackendRBDCreateVol(virStoragePoolObj *pool,
}
static int virStorageBackendRBDCreateImage(rados_ioctx_t io,
- char *name, long capacity)
+ char *name, long capacity, virStoragePoolDefPtr def)
{
int order = 0;
- return rbd_create(io, name, capacity, &order);
+ int ret = -1;
+ rbd_image_options_t image_options;
+
+ if (def->source.rbdImageOptions.format < 0 && def->source.rbdImageOptions.feature < 0
+ && def->source.rbdImageOptions.order < 0 && def->source.rbdImageOptions.stripe_unit < 0
+ && def->source.rbdImageOptions.stripe_count < 0 && def->source.rbdImageOptions.journal_order < 0
+ && def->source.rbdImageOptions.journal_splay_width < 0 && (def->source.rbdImageOptions.journal_pool != NULL)
+ && def->source.rbdImageOptions.feature_set < 0 && def->source.rbdImageOptions.feature_clear < 0
+ && (def->source.rbdImageOptions.data_pool != NULL) && def->source.rbdImageOptions.flatten < 0
+ && def->source.rbdImageOptions.clone_format < 0 && def->source.rbdImageOptions.mirror_image_mode < 0) {
+ VIR_DEBUG("Creating RBD image %s, without data pool, with size %lu", name, capacity);
+ return rbd_create(io, name, capacity, &order);
+ }
+
+ rbd_image_options_create(&image_options);
+
+ if (def->source.rbdImageOptions.format >= 0) {
+ VIR_DEBUG("Set rbd image option format:%d, %lu", RBD_IMAGE_OPTION_FORMAT, def->source.rbdImageOptions.format);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_FORMAT,
+ (uint64_t)def->source.rbdImageOptions.format);
+ }
+
+ if (def->source.rbdImageOptions.feature >= 0) {
+ VIR_DEBUG("Set rbd image option features:%d, %lu", RBD_IMAGE_OPTION_FEATURES, def->source.rbdImageOptions.feature);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_FEATURES,
+ (uint64_t)def->source.rbdImageOptions.feature);
+ }
+
+ if (def->source.rbdImageOptions.order >= 0) {
+ VIR_DEBUG("Set rbd image option order:%d, %lu", RBD_IMAGE_OPTION_ORDER, def->source.rbdImageOptions.order);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_ORDER,
+ (uint64_t)def->source.rbdImageOptions.order);
+ }
+
+ if (def->source.rbdImageOptions.stripe_unit >= 0) {
+ VIR_DEBUG("Set rbd image option stripe_unit:%d, %lu", RBD_IMAGE_OPTION_STRIPE_UNIT, def->source.rbdImageOptions.stripe_unit);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_STRIPE_UNIT,
+ (uint64_t)def->source.rbdImageOptions.stripe_unit);
+ }
+
+ if (def->source.rbdImageOptions.stripe_count >= 0) {
+ VIR_DEBUG("Set rbd image option stipe_count:%d, %lu", RBD_IMAGE_OPTION_STRIPE_COUNT, def->source.rbdImageOptions.stripe_count);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_STRIPE_COUNT,
+ (uint64_t)def->source.rbdImageOptions.stripe_count);
+ }
+
+ if (def->source.rbdImageOptions.journal_order >= 0) {
+ VIR_DEBUG("Set rbd image option journal_order:%d, %lu", RBD_IMAGE_OPTION_JOURNAL_ORDER, def->source.rbdImageOptions.journal_order);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_JOURNAL_ORDER,
+ (uint64_t)def->source.rbdImageOptions.journal_order);
+ }
+
+ if (def->source.rbdImageOptions.journal_splay_width >= 0) {
+ VIR_DEBUG("Set rbd image option journal_splay_width:%d, %lu", RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH, def->source.rbdImageOptions.journal_splay_width);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_JOURNAL_SPLAY_WIDTH,
+ (uint64_t)def->source.rbdImageOptions.journal_splay_width);
+ }
+
+ if (def->source.rbdImageOptions.journal_pool != NULL) {
+ VIR_DEBUG("Set rbd image option journal_pool:%d, %s", RBD_IMAGE_OPTION_JOURNAL_POOL, def->source.rbdImageOptions.journal_pool);
+ rbd_image_options_set_string(image_options,
+ RBD_IMAGE_OPTION_JOURNAL_POOL,
+ def->source.rbdImageOptions.journal_pool);
+ }
+
+ if (def->source.rbdImageOptions.feature_set >= 0) {
+ VIR_DEBUG("Set rbd image option feature_set:%d, %lu", RBD_IMAGE_OPTION_FEATURES_SET, def->source.rbdImageOptions.feature_set);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_FEATURES_SET,
+ (uint64_t)def->source.rbdImageOptions.feature_set);
+ }
+
+ if (def->source.rbdImageOptions.feature_clear >= 0) {
+ VIR_DEBUG("Set rbd image option feature_clear:%d, %lu", RBD_IMAGE_OPTION_FEATURES_CLEAR, def->source.rbdImageOptions.feature_clear);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_FEATURES_CLEAR,
+ (uint64_t)def->source.rbdImageOptions.feature_clear);
+ }
+
+ if (def->source.rbdImageOptions.data_pool != NULL) {
+ VIR_DEBUG("Set rbd image option data_pool:%d, %s", RBD_IMAGE_OPTION_DATA_POOL, def->source.rbdImageOptions.data_pool);
+ rbd_image_options_set_string(image_options,
+ RBD_IMAGE_OPTION_DATA_POOL,
+ def->source.rbdImageOptions.data_pool);
+ }
+
+ if (def->source.rbdImageOptions.flatten >= 0) {
+ VIR_DEBUG("Set rbd image option flatten:%d, %lu", RBD_IMAGE_OPTION_FLATTEN, def->source.rbdImageOptions.flatten);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_FLATTEN,
+ (uint64_t)def->source.rbdImageOptions.flatten);
+ }
+
+ if (def->source.rbdImageOptions.clone_format >= 0) {
+ VIR_DEBUG("Set rbd image option clone_format:%d, %lu", RBD_IMAGE_OPTION_CLONE_FORMAT, def->source.rbdImageOptions.clone_format);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_CLONE_FORMAT,
+ (uint64_t)def->source.rbdImageOptions.clone_format);
+ }
+
+ if (def->source.rbdImageOptions.mirror_image_mode >= 0) {
+ VIR_DEBUG("Set rbd image option mirror_image_mode:%d, %lu", RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE, def->source.rbdImageOptions.mirror_image_mode);
+ rbd_image_options_set_uint64(image_options,
+ RBD_IMAGE_OPTION_MIRROR_IMAGE_MODE,
+ (uint64_t)def->source.rbdImageOptions.mirror_image_mode);
+ }
+
+ ret = rbd_create4(io, name, capacity, image_options);
+ VIR_DEBUG("Creating RBD image %s, with size:%lu, ret:%d", name, capacity, ret);
+ rbd_image_options_destroy(image_options);
+ return ret;
}
static int
@@ -920,7 +1037,7 @@ virStorageBackendRBDBuildVol(virStoragePoolObj *pool,
goto cleanup;
if (virStorageBackendRBDCreateImage(ptr->ioctx, vol->name,
- vol->target.capacity) < 0) {
+ vol->target.capacity, def) < 0) {
virReportSystemError(errno, _("failed to create volume '%s/%s'"),
def->source.name, vol->name);
goto cleanup;
--
2.29.1.windows.1
1 year, 10 months
Re: [PATCH 1/2] log: Add separate debug option for logging invalid memory accesses
by Philippe Mathieu-Daudé
On 13/2/23 18:17, Peter Xu wrote:
> On Mon, Feb 13, 2023 at 05:34:04PM +0100, BALATON Zoltan wrote:
>> On Mon, 13 Feb 2023, Peter Xu wrote:
>>> On Mon, Feb 13, 2023 at 03:47:42PM +0100, BALATON Zoltan wrote:
>>>> On Mon, 13 Feb 2023, Peter Xu wrote:
>>>>> On Mon, Feb 13, 2023 at 12:41:29PM +0100, Thomas Huth wrote:
>>>>>> On 07/02/2023 17.33, BALATON Zoltan wrote:
>>>>>>> On Tue, 31 Jan 2023, BALATON Zoltan wrote:
>>>>>>>> On Thu, 19 Jan 2023, BALATON Zoltan wrote:
>>>>>>>>> Currently -d guest_errors enables logging of different invalid actions
>>>>>>>>> by the guest such as misusing hardware, accessing missing features or
>>>>>>>>> invalid memory areas. The memory access logging can be quite verbose
>>>>>>>>> which obscures the other messages enabled by this debug switch so
>>>>>>>>> separate it by adding a new -d memaccess option to make it possible to
>>>>>>>>> control it independently of other guest error logs.
>>>>>>>>>
>>>>>>>>> Signed-off-by: BALATON Zoltan <balaton(a)eik.bme.hu>
>>>>>>>>
>>>>>>>> Ping? Could somebody review and pick it up please?
>>>>>>>
>>>>>>> Ping?
>>>>>>
>>>>>> Patch makes sense to me and looks fine, so:
>>>>>>
>>>>>> Reviewed-by: Thomas Huth <thuth(a)redhat.com>
>>>>>>
>>>>>> ... I think this should go via one of the "Memory API" maintainers branches?
>>>>>> Paolo? Peter? David?
>>>>>
>>>>> Paolo normally does the pull, I assume that'll still be the case. The
>>>>> patch looks good to me if Phil's comment will be addressed on merging with
>>>>> the old mask, which makes sense to me:
>>>>
>>>> Keeping the old mask kind of defies the purpose. I've tried to explain that
>>>> in the commit message but now that two of you did not get it maybe that
>>>> message needs to be clarified instead?
>>>
>>> I think it's clear enough. My fault to not read carefully into the
>>> message, sorry.
>>>
>>> However, could you explain why a memory_region_access_valid() failure
>>> shouldn't belong to LOG_GUEST_ERROR?
>>>
>>> commit e54eba1986f6c4bac2951e7f90a849cd842e25e4
>>> Author: Peter Maydell <peter.maydell(a)linaro.org>
>>> Date: Thu Oct 18 14:11:35 2012 +0100
>>>
>>> qemu-log: Add new log category for guest bugs
>>>
>>> Add a new category for device models to log guest behaviour
>>> which is likely to be a guest bug of some kind (accessing
>>> nonexistent registers, reading 32 bit wide registers with
>>> a byte access, etc). Making this its own log category allows
>>> those who care (mostly guest OS authors) to see the complaints
>>> without bothering most users.
>>>
>>> Such an illegal memory access is definitely a suitable candidate of guest
>>> misbehave to me.
>>
>> Problem is that a lot of machines have unimplemented hardware that are valid
>> on real machine but we don't model them so running guests which access these
>> generate constant flow of unassigned memory access log which obscures the
>> actual guest_errors when an modelled device is accessed in unexpected ways.
>> For an example you can try booting MorphOS on mac99,via=pmu as described
>> here: http://zero.eik.bme.hu/~balaton/qemu/amiga/#morphos
>> (or the pegasos2 command too). We could add dummy registers to silence these
>> but I think it's better to either implement it correctly or leave it
>> unimplemented so we don't hide errors by the dummy implementation.
>>
>>> Not to mention Phil always have a good point that you may be violating
>>> others using guest_error already so what they wanted to capture can
>>> misterious going away without noticing, even if it may service your goal.
>>> IOW it's a slight ABI and I think we ned justification to break it.
>>
>> Probably this should be documented in changelog or do we need depracation
>> for a debug option meant for developers mostly? I did not think so. Also I
>> can't think of other way to solve this without changing what guest_erorrs do
>> unless we change the name of that flag as well. Also not that when this was
>> originally added it did not contain mem access logs as those were controlled
>> by a define in memory.c until Philippe changed it and added them to
>> guest_errors. So in a way I want the previous functionality back.
>
> I see, thanks.
>
> Indeed it's only a debug option, so I don't know whether the abi needs the
> attention here.
>
> I quickly looked at all the masks and afaict this is really a special and
> very useful one that if I'm a cloud provider I can run some script trying
> to capture those violations using this bit to identify suspecious guests.
>
> So I think it would still be great to not break it if possible, IMHO.
>
> Since currently I don't see an immediate limitation of having qemu log mask
> being a single bit for each of the entry, one way to satisfy your need (and
> also keep the old behavior, iiuc), is to make guest_errors a sugar syntax
> to cover 2 bits. It shouldn't be complicated at all, I assume:
>
> +/* This covers the generic guest errors besides memory violations */
> #define LOG_GUEST_ERROR (1 << 11)
>
> +/*
> + * This covers the guest errors on memory violations; see LOG_GUEST_ERROR
> + * for generic guest errors.
> + */
> +#define LOG_GUEST_ERROR_MEM (1 << 21)
> +#define LOG_GUEST_ERROR_ALL (LOG_GUEST_ERROR | LOG_GUEST_ERROR_MEM)
>
> - { LOG_GUEST_ERROR, "guest_errors",
> + { LOG_GUEST_ERROR_ALL, "guest_errors",
>
> Then somehow squashed with your changes. It'll make "guest_errors" not
> exactly matching the name of LOG_* but I think it may not be a big concern.
Thanks Peter for having a look. Cc'ing libvir-list@ to see if this
change could have an impact. If no one else object I'm OK to take the
patch as is, except if you (Peter) want the description to be reworded.
Regards,
Phil.
1 year, 10 months
[PATCH] test: Introduce chxml2xmltest
by Michal Privoznik
Whilst reviewing a patch upstream (that ended up as
v9.0.0-200-g092176e5ec), I realized we don't have a single
xml2xml test for CH driver. Well, introduce the test with one
simple test case for now.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
We could also benefit from xml2arg test, but I'll leave that for future
ourselves.
tests/chxml2xmlin/basic.xml | 30 ++++++++++++++
tests/chxml2xmlout/basic.xml | 1 +
tests/chxml2xmltest.c | 77 ++++++++++++++++++++++++++++++++++++
tests/meson.build | 6 +++
4 files changed, 114 insertions(+)
create mode 100644 tests/chxml2xmlin/basic.xml
create mode 120000 tests/chxml2xmlout/basic.xml
create mode 100644 tests/chxml2xmltest.c
diff --git a/tests/chxml2xmlin/basic.xml b/tests/chxml2xmlin/basic.xml
new file mode 100644
index 0000000000..911aa7c621
--- /dev/null
+++ b/tests/chxml2xmlin/basic.xml
@@ -0,0 +1,30 @@
+<domain type='kvm'>
+ <name>cloudhypervisor</name>
+ <uuid>4dea22b3-1d52-d8f3-2516-782e98ab3fa0</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ <kernel>hypervisor-fw</kernel>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/local/bin/cloud-hypervisor</emulator>
+ <disk type='file' device='disk'>
+ <source file='disk.raw'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <interface type='ethernet'>
+ <mac address='52:54:00:5c:e4:84'/>
+ <model type='virtio'/>
+ </interface>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ </devices>
+</domain>
diff --git a/tests/chxml2xmlout/basic.xml b/tests/chxml2xmlout/basic.xml
new file mode 120000
index 0000000000..eb8df546aa
--- /dev/null
+++ b/tests/chxml2xmlout/basic.xml
@@ -0,0 +1 @@
+../chxml2xmlin/basic.xml
\ No newline at end of file
diff --git a/tests/chxml2xmltest.c b/tests/chxml2xmltest.c
new file mode 100644
index 0000000000..97b485dc4a
--- /dev/null
+++ b/tests/chxml2xmltest.c
@@ -0,0 +1,77 @@
+#include <config.h>
+
+#include <testutils.h>
+
+#include "ch/ch_conf.h"
+
+struct testInfo {
+ const char *name;
+ virCHDriver *driver;
+ testCompareDomXML2XMLResult expectResult;
+};
+
+typedef enum {
+ FLAG_IS_DIFFERENT = 1 << 0,
+ FLAG_EXPECT_FAILURE = 1 << 1,
+} virBhyveXMLToXMLTestFlags;
+
+static int
+testCompareXMLToXMLHelper(const void *data)
+{
+ const struct testInfo *info = data;
+ g_autofree char *xml_in = NULL;
+ g_autofree char *xml_out = NULL;
+
+ xml_in = g_strdup_printf("%s/chxml2xmlin/%s.xml",
+ abs_srcdir, info->name);
+ xml_out = g_strdup_printf("%s/chxml2xmlout/%s.xml",
+ abs_srcdir, info->name);
+
+ return testCompareDomXML2XMLFiles(NULL, info->driver->xmlopt,
+ xml_in, xml_out, false, 0,
+ info->expectResult);
+}
+
+static int
+mymain(void)
+{
+ int ret = 0;
+ virCHDriver *driver = NULL;
+
+ driver = g_new0(virCHDriver, 1);
+
+ if (!(driver->caps = virCHDriverCapsInit())) {
+ fprintf(stderr, "unable to initialize driver capabilities\n");
+ goto cleanup;
+ }
+
+ if (!(driver->xmlopt = chDomainXMLConfInit(driver))) {
+ fprintf(stderr, "unable to initialize driver XMLOPT\n");
+ goto cleanup;
+ }
+
+#define DO_TEST_FULL(name, expectResult) \
+ do { \
+ const struct testInfo info = {name, driver, expectResult}; \
+ if (virTestRun("CH XML-2-XML " name, \
+ testCompareXMLToXMLHelper, &info) < 0) \
+ ret = -1; \
+ } while (0)
+
+#define DO_TEST(name) \
+ DO_TEST_FULL(name, TEST_COMPARE_DOM_XML2XML_RESULT_SUCCESS)
+
+#define DO_TEST_FAIL_PARSE(name) \
+ DO_TEST_FULL(name, TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE)
+
+ DO_TEST("basic");
+
+ cleanup:
+ virObjectUnref(driver->xmlopt);
+ virObjectUnref(driver->caps);
+ g_free(driver);
+
+ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIR_TEST_MAIN(mymain)
diff --git a/tests/meson.build b/tests/meson.build
index 3365dce307..15b049c6ac 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -347,6 +347,12 @@ if conf.has('WITH_BHYVE')
]
endif
+if conf.has('WITH_CH')
+ tests += [
+ { 'name': 'chxml2xmltest', 'link_with': [ ch_driver_impl ] },
+ ]
+endif
+
if conf.has('WITH_ESX')
tests += [
{ 'name': 'esxutilstest', 'deps': [ esx_dep ] },
--
2.39.1
1 year, 10 months