When guestfs_impl_add_drive_opts is called outside CONFIG state, the
hotplug error path returns -1 without freeing the already-allocated
drv structure.
Co-authored-by: Claude Local LLM <noreply@anthropic.com>
When realpath() succeeds but subsequent operations fail, the
allocated path is leaked. Add free(ret) before returning -1
on both error paths.
Co-authored-by: Claude <norep@anthropic.com>
In rlc_insert and xac_insert (lib/fuse.c), both functions take
ownership of a parameter (link and xattrs respectively) but fail to
free it when their own malloc calls fail. Under memory pressure in a
long-running FUSE process, each failed cache insertion leaks the
owned resource.
Co-authored-by: Claude <nore@anthro.com>
The string allocated by generic_qmp_test via safe_strdup is passed to
parse_has_kvm but never freed afterwards, leaking memory on every KVM
capability check. Use CLEANUP_FREE to ensure automatic cleanup.
Co-authored-by: Claude <noreply@anthropic.com>
Qemu will refuse to start on some (all?) architectures if firmware
files are missing, or for other reasons, and complain to stderr. Those
messages should be made visible to the user as part of the error message.
Reimplement xfs_info by returning a hash table of values (rather than
a limited struct), and by writing it in OCaml with PCRE which makes
string parsing a lot simpler. This will now flexibly return all the
fields from the underlying xfs_info command, even (hopefully) future
fields.
Note the field values are returned as strings, because the actual
fields in xfs_info output are fairly random and free-form. There is a
trade off here between returning as much information as we can, and
requiring the user to do a bit of (simple) field parsing.
Fixes: https://issues.redhat.com/browse/RHEL-143673
Dan mentioned that there is a special machine type ("none") we can use
when querying for KVM. It has no CPU, memory, etc and does not run,
but you can still enable KVM for it.
Note we have to remove the -cpu parameter, otherwise qemu prints this
error:
qemu-kvm: apic-id property was not initialized properly
Updates: commit 5da8102f5f
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
When checking for QMP properties, we run a qemu command and interact
with the QMP console. However we also start the guest running (there
is no actual guest in this situation). This occasionally causes this
line to be printed:
libguestfs: generic_qmp_test: 3: {"timestamp": {"seconds": 1768823946, "microseconds": 898287}, "event": "GUEST_PANICKED", "data": {"action": "poweroff", "info": {"core": 0, "psw-addr": 0, "reason": "disabled-wait", "psw-mask": 562956395872256, "type": "s390"}}}\r\n
which confuses our parser.
As there is no reason to start the non-existent guest, add the -S
option which causes qemu to start up in a paused state.
For some reason this only happens on s390x but I think it could happen
on all architectures, so it may be a timing issue or something
particular about s390x firmware.
Commit 669eda1e24 ("lib/launch-direct.c: Simplify test for KVM, remove
qemu caching") made it so that failure of generic_qmp_test() will
cause launch to fail. However we still used debug messages to print
the error, so unless you have debugging enabled you wouldn't see any
error message if this function fails.
Updates: commit 669eda1e24
When iterating on commit 3c1554e7f2 ("lib: Add new app2_class field
for classifying applications") in early versions I was accidentally
passing NULL to match(). Unexpectedly this returned 1 (ie. matching).
This happened because we did not correctly handle other errors apart
from PCRE2_ERROR_NOMATCH from pcre2_match.
Emit a debug message when this happens, and return no match.
To test this I ran these commands, and there was no output:
$ make && LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 make check
$ find -name '*.log' | xargs grep 'match.*unexpected error'
Windows group policy objects (GPOs) are restrictions that can be added
by an administrator to Windows to lock down various operations. From
our point of view the ones that matter involve restricting the ability
to inject device drivers.
Previously virt-v2v detected group policy here:
9bb2e7d470/convert/convert_windows.ml (L69)
We would like to report group policy through the libguestfs API and
tools such as virt-inspector, so move the code that is used to detect
group policy to libguestfs. A new API is introduced that returns
whether group policy was found (only for Windows guests) during
inspection of the software registry.
Fixes: https://issues.redhat.com/browse/RHEL-125846
For McAfee VirusScan, the name is bogus and the display name is the
actual name:
<application>
<name>{CE15D1B6-19B6-4D4D-8F43-CF5D2C3356FF}</name>
<display_name>McAfee VirusScan Enterprise</display_name>
<version>8.8.04001</version>
<install_path>C:Program Files (x86)McAfeeVirusScan Enterprise\</install_path>
<publisher>McAfee, Inc.</publisher>
<url>http://www.mcafeesecurity.com/</url>
</application>
Simplify the existing ad hoc code so we just match name, display name
and publisher (if present) against all the virus scanning strings.
Existing virt-v2v code uses some simple heuristics for detecting
Windows anti-virus software:
7520185504/convert/windows.ml
Replicate exactly this code as a new field in the struct returned by
guestfs_inspect_get_applications2. Because of limitations with the
API, we must use one of the existing spare fields in the struct, and
it must have the same type (a string), so we are limited in the design
of this new API. I chose to return a primary classification for the
application, with the only classification possible so far being
"antivirus" (or "" if not). This allows the possibility of future
expansion of use of this field if we need to in future.
Fixes: https://issues.redhat.com/browse/RHEL-125846
If a user passes a custom hv, and uses add_libvirt_dom (like
in test820RHBZ912499.py) , this hits a bogus libvirt validation
check which rejects disabling svirt at both domain and disk level.
Work around it by skipping the redundant disk override when
svirt is disabled at the domain level.
Signed-off-by: Cole Robinson <crobinso@redhat.com>
On fedora, ./configure will set QEMU=qemu-kvm, but libvirt
domcaps will default to qemu-system-x86_64. The former is a symlink
to the latter, but libguestfs doesn't know that, so determines
the user requested a non-default hv override and changes some
settings as a result (like disabling svirt).
Check for the symlink case and consider it a non-custom config
if realpath matches libvirt's default
Signed-off-by: Cole Robinson <crobinso@redhat.com>
Add debugging about is_custom_hv result.
cache the initial call so we are only hitting the debug() once.
Signed-off-by: Cole Robinson <crobinso@redhat.com>
libvirt has DAC relabeled sockets for us for a decade, so we don't
need to do chowning here anymore
The chmod calls are still required, otherwise our created sockets
may be too permissive.
Update the comment to try and preserve the still relevant info,
though now it's a bit awkwardly placed.
Signed-off-by: Cole Robinson <crobinso@redhat.com>
https://bugzilla.redhat.com/2082806 is a private kernel bug (sigh) for
RHEL 8, where some missing backports caused 5-level page tables to
fail when qemu emulated them. This was fixed back in 2023, so let's
remove this workaround now.
On RHEL 10.2 aarch64 (only) we see:
$ echo '{ "execute": "qmp_capabilities" }' '{ "execute": "query-kvm" }' '{ "execute": "quit" }' | QEMU_AUDIO_DRV=none "/usr/libexec/qemu-kvm" -display none -machine "virt,accel=kvm:hvf:tcg" -qmp stdio
qemu-kvm: invalid accelerator hvf
qemu-kvm: falling back to KVM
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 1, "major": 9}, "package": "qemu-kvm-9.1.0-15.el10_0.4"}, "capabilities": ["oob"]}}
qemu-kvm: warning: CPU model cortex-a57-arm-cpu is deprecated -- use 'host' / 'max'
qemu-kvm: kvm_init_vcpu: kvm_arch_init_vcpu failed (0): Invalid argument
Unfortunately we cannot use guestfs_int_get_cpu_model (as that
requires us to already know if KVM is supported), so we just have to
guess that -cpu max will work, at least enough for QMP to work.
Fixes: https://issues.redhat.com/browse/RHEL-121076
Reported-by: Xiang Hua Chen
macOS macfuse has an extra options parameter for the setxattr and
getxattr FUSE callbacks. The possible options are documented below.
However the underlying libguestfs APIs don't allow us to act on these
flags, so we ignore them for now.
(from https://manp.gs/mac/2/setxattr)
XATTR_NOFOLLOW
do not follow symbolic links. setxattr() normally sets attributes
on the target of path if it is a symbolic link. With this option,
setxattr() will act on the link itself.
XATTR_NOFOLLOW_ANY
do not follow any symbolic links encountered during pathname
resolution. An error is returned if a symlink is encountered
before the last component of path.
XATTR_CREATE
fail if the named attribute already exists.
XATTR_REPLACE
fail if the named attribute does not exist. Failure to specify
XATTR_REPLACE or XATTR_CREATE allows creation and replacement.
Reported-by: Mohamed Akram
Fixes: https://github.com/libguestfs/libguestfs/issues/180
Related: https://github.com/macfuse/macfuse/issues/1065
Previously we tested if KVM was available, and cached that for the
qemu binary. I think this was actually wrong. For example, if the
machine restarts, then the cache is still around, but KVM might be
enabled or disabled because of a new host kernel.
In any case, let's radically simplify this.
Test for KVM on each run. Consequently we can remove all the qemu
test caching stuff as it is no longer used anywhere.
I also tightened up the code that runs the QMP query-kvm command, so
now any unexpected output will cause a runtime failure. This command
ought to work, and if it breaks we ought to know about it and fix it.
Previously we ran 'qemu -device ?' to list devices, using the output
to test if qemu supported particular devices. This was extensively
used in the past, but after recent commits there are no further users
of this code, so we can remove it all completely.
It's always a good idea to provide proper entropy to the libguestfs
appliance (eg. for any cryptographic operations). We already assume
virtio, so we can assume virtio-rng is present.
We no longer use the libvirt version anywhere, except when reporting
the version. Remove this from the handle.
Simplify the remaining code. In particular:
* don't bother parsing the libvirt version, just print what
virGetVersion gives us
* guestfs_int_version_from_libvirt is dead code, so it can be removed
Libvirt 9.0.0 was released in January 2023, and it seems safe to
assume that if you're enabling the non-default backend, you can at
least use a new version of libvirt.
If you're using new libvirt, might as well also assume passt is
available.
Previously we parsed qemu -help output to get the version of qemu and
to test for other features. After prior commits, this is no longer
done, so we can remove the qemu -help invocation and associated code
completely.
This function is now only used in one place, to print the version of
qemu in direct mode, when debugging is enabled.
Remove this function and replace with a direct command invocation
('qemu --version'). We only need to run this command when debugging
is enabled, and we copy all of the output to the debug channel.
I have made the assumption here that qemu -version does not try to
create a display device. (The previous invocation of qemu -help
actually ran 'qemu -display none -help' indicating that this was not
always the case.)
This is actually an improvement on before, since now we get to see the
full output of 'qemu --version'. The new output looks like:
libguestfs: begin testing qemu features
libguestfs: command: run: /usr/bin/qemu-kvm
libguestfs: command: run: \ -version
libguestfs: qemu: QEMU emulator version 10.1.0 (qemu-10.1.0-8.fc44)
libguestfs: qemu: Copyright (c) 2003-2025 Fabrice Bellard and the QEMU Project developers