Seems reasonable to have all command wrappers in the same place
v2:
Dont move SetInherit
v3:
Comment spelling fix
Adjust WARN0 comment
Remove spurious #include movement
Don't include sys/types.h
Combine virExec enums
Signed-off-by: Cole Robinson <crobinso@redhat.com>
Coverity detected that options was being set by strdup but never
freed. But why even bother with an options variable? The options
parameter never changes! Leak present since commit 44948f5b (0.7.0).
This function could probably be rewritten to take better advantage
of virCommand, but that is more invasive.
* src/storage/storage_backend_fs.c
(virStorageBackendFileSystemMount): Avoid wasted strdup, and
guarantee proper cleanup on all paths.
Since directories can be used for <filesystem> passthrough, they are
basically storage volumes.
v2:
Skip ., .., lost+found dirs
v3:
Use gnulib last_component
v4:
Use gnulib "dirname.h", not system <dirname.h>
Don't skip lost+found
Currently a single storage volume with a broken backing file will disable the
whole storage pool. This can happen when the backing file is on some
unavailable network storage or if the backing volume is deleted, while the
storage volumes using it remain.
Since the storage pool can not be re-activated, re-creating the missing
or deleting the now useless volumes using libvirt only is not possible.
Fixing this is a little bit tricky:
1. virStorageBackendProbeTarget() only detects the missing backing file,
if the backing file format is not explicitly specified. If the
backing file is created using
kvm-img create -f qcow2 -o backing_fmt=qcow2,backing_file=... ...
no error is detected at this stage.
The new return code -3 signals that the backing file could not be
opened.
2. The backingStore.format must be >= 0, since values < 0 would break
virStorageVolTargetDefFormat() when dumping the XML data such as
<format type='...'/>
Because of this the format is faked as VIR_STORAGE_FILE_RAW.
3. virStorageBackendUpdateVolTargetInfo() always opens the backing file
and thus always detects a missing backing file.
Since it "only" updates the capacity, allocation, owner, group, mode
and SELinux label, just ignore errors at this stage, print an error
message and continue.
4. Using vol-dump on a broken volume still doesn't work, but at least
vol-destroy and pool-refresh do work now.
To reproduce:
dir=$(mktemp -d)
virsh pool-create-as tmp dir '' '' '' '' "$dir"
virsh vol-create-as --format qcow2 tmp back 1G
virsh vol-create-as --format qcow2 --backing-vol-format qcow2 --backing-vol back tmp cow 1G
virsh vol-delete --pool tmp back
virsh pool-refresh tmp
After the last step, the pool will be gone (because it was not persistent). As
long as the now broken image stays in the directory, you will not be able to
re-create or re-start the pool.
Signed-off-by: Philipp Hahn <hahn@univention.de>
If there is a dangling symbolic link in filesystem pool, the pool
will fail to start or refresh, this patch is to fix it by ignoring
it with a warning log.
When libvirt starts up all storage pools default to the inactive
state, even if the underlying storage is already active on the
host. This introduces a new API into the internal storage backend
drivers that checks whether a storage pool is already active. If
the pool is active at libvirtd startup, the volume list will be
immediately populated.
* src/storage/storage_backend.h: New internal API for checking
storage pool state
* src/storage/storage_driver.c: Check whether a pool is active
upon driver startup
* src/storage/storage_backend_fs.c, src/storage/storage_backend_iscsi.c,
src/storage/storage_backend_logical.c, src/storage/storage_backend_mpath.c,
src/storage/storage_backend_scsi.c: Add checks for pool state
Similarly to deprecating close(), I am now deprecating fclose() and
introduce VIR_FORCE_FCLOSE() and VIR_FCLOSE(). Also, fdopen() is replaced with
VIR_FDOPEN().
Most of the files are opened in read-only mode, so usage of
VIR_FORCE_CLOSE() seemed appropriate. Others that are opened in write
mode already had the fclose()< 0 check and I converted those to
VIR_FCLOSE()< 0.
I did not find occurrences of possible double-closed files on the way.
Using automated replacement with sed and editing I have now replaced all
occurrences of close() with VIR_(FORCE_)CLOSE() except for one, of
course. Some replacements were straight forward, others I needed to pay
attention. I hope I payed attention in all the right places... Please
have a look. This should have at least solved one more double-close
error.
Found by clang. Clang complained that virStorageBackendProbeTarget
could dereference NULL if backingStoreFormat was NULL, but since all
callers passed a valid pointer, I added attributes instead of null
checks.
* src/storage/storage_backend.c
(virStorageBackendQEMUImgBackingFormat): Kill dead store.
* src/storage/storage_backend_fs.c (virStorageBackendProbeTarget):
Likewise. Skip null checks, by adding attributes.
virDirCreate also previously returned 0 on success and errno on
failure. This makes it fit the recommended convention of returning 0
on success, -errno (ie a negative number) on failure.
The storage volume lookup code was probing for the backing store
format, instead of using the format extracted from the file
itself. This meant it could report in accurate information. If
a format is included in the file, then use that in preference,
with probing as a fallback.
* src/storage/storage_backend_fs.c: Use extracted backing store
format
Require the disk image to be passed into virStorageFileGetMetadata.
If this is set to VIR_STORAGE_FILE_AUTO, then the format will be
resolved using probing. This makes it easier to control when
probing will be used
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata.
* src/storage/storage_backend_fs.c: Probe for disk format before
calling virStorageFileGetMetadata.
* src/util/storage_file.h, src/util/storage_file.c: Remove format
from virStorageFileMeta struct & require it to be passed into
method.
If a directory pool contains pipes or sockets, a pool start can fail or hang:
https://bugzilla.redhat.com/show_bug.cgi?id=589577
We already try to avoid these special files, but only attempt after
opening the path, which is where the problems lie. Unify volume opening
into helper functions, which use the proper open() flags to avoid error,
followed by fstat to validate storage mode.
Previously, virStorageBackendUpdateVolTargetInfoFD attempted to enforce the
storage mode check, but allowed callers to detect this case and silently
continue. In practice, only the FS backend was using this feature, the rest
were treating unknown mode as an error condition. Unfortunately the InfoFD
function wasn't raising an error message here, so error reporting was
busted.
This patch adds 2 functions: virStorageBackendVolOpen, and
virStorageBackendVolOpenModeSkip. The latter retains the original opt out
semantics, the former now throws an explicit error.
This patch maintains the previous volume mode checks: allowing specific
modes for specific pool types requires a bit of surgery, since VolOpen
is called through several different helper functions.
v2: Use ATTRIBUTE_NONNULL. Drop stat check, just open with
O_NONBLOCK|O_NOCTTY.
v3: Move mode check logic back to VolOpen. Use 2 VolOpen functions with
different error semantics.
v4: Make second VolOpen function more extensible. Didn't opt to change
FS backend defaults, this can just be to fix the original bug.
v5: Prefix default flags with VIR_, use ATTRIBUTE_RETURN_CHECK
* src/storage/storage_backend_fs.c (virStorageBackendFileSystemMount):
Clang was not smart enough, and mistakenly reported that "options"
could be used uninitialized. Initialize it.
This allows the config to have a setting that means "leave it alone",
eg when building a pool where the directory already exists the user
may want the current uid/gid of the directory left intact. This
actually gets us back to older behavior - before recent changes to the
pool building code, we weren't as insistent about honoring the uid/gid
settings in the XML, and virt-manager was taking advantage of this
behavior.
As a side benefit, removing calls to getuid/getgid from the XML
parsing functions also seems like a good idea. And having a default
that is different from a common/useful value (0 == root) is a good
thing in general, as it removes ambiguity from decisions (at least one
place in the code was checking for (perms.uid == 0) to see if a
special uid was requested).
Note that this will only affect newly created pools and volumes. Due
to the way that the XML is parsed, then formatted for newly created
volumes, all existing pools/volumes already have an explicit uid and
gid set.
src/conf/storage_conf.c: Remove calls to setuid/setgid for default values
of uid/gid, and set them to -1 instead
src/storage/storage_backend.c:
src/storage/storage_backend_fs.c:
Make account for the new default values of perms.uid
and perms.gid.
Create the filesystem on the partition used by the pool
* configure.ac: check for mkfs availability
* libvirt.spec.in: add extra require on util-linux for mkfs
* src/storage/storage_backend_fs.c: run mkfs with the expected
fs type when creating a filesystem pool
It turns out it is also useful to be able to perform other operations
on a file created while running as a different uid (eg, write things
to that file), and possibly to do this to a file that already
exists. This patch adds an optional hook function to the renamed (for
more accuracy of purpose) virFileOperation; the hook will be called
after the file has been opened (possibly created) and gid/mode
checked/set, before closing it.
As with the other operations on the file, if the VIR_FILE_OP_AS_UID
flag is set, this hook function will be called in the context of a
child process forked from the process that called virFileOperation.
The implication here is that, while all data in memory is available to
this hook function, any modification to that data will not be seen by
the caller - the only indication in memory of what happened in the
hook will be the return value (which the hook should set to 0 on
success, or one of the standard errno values on failure).
Another piece of making the function more flexible was to add an
"openflags" argument. This arg should contain exactly the flags to be
passed to open(2), eg O_RDWR | O_EXCL, etc.
In the process of adding the hook to virFileOperation, I also realized
that the bits to fix up file owner/group/mode settings after creation
were being done in the parent process, which could fail, so I moved
them to the child process where they should be.
* src/util/util.[ch]: rename and rework virFileCreate-->virFileOperation,
and redo flags in virDirCreate
* storage/storage_backend.c, storage/storage_backend_fs.c: update the
calls to virFileOperation/virDirCreate to reflect changes in the API,
but don't yet take advantage of the hook.
The virConnectPtr is no longer required for error reporting since
that is recorded in a thread local. Remove use of virConnectPtr
from all APIs in storage_conf.{h,c} and storage_encryption_conf.{h,c}
and update all callers to match
Previously the uid/gid/mode in the xml was ignored when creating new
storage pool directories. This commit attempts to honor the requested
permissions, and spits out an error if it can't.
Note that when creating the directory, the rest of the path leading up
to the final element is created using current uid/gid/mode, and the
final element gets the settings from xml. It is NOT an error for the
directory to already exist; in this case, the perms for the existing
directory are just set (if necessary).
* src/storage/storage_backend_fs.c: update the virStorageBackendFileSystemBuild
function to check the directory hierarchy separately then create the
leaf directory with the right attributes
In order to avoid problems trying to chown files that were created by
root on a root-squashing nfs server, fork a new process that setuid's
to the desired uid before creating the file. (It's only done this way
if the pool containing the new volume is of type 'netfs', otherwise
the old method of creating the file followed by chown() is used.)
This changes the semantics of the "create_func" slightly - previously
it was assumed that this function just created the file, then the
caller would chown it to the desired uid. Now, create_func does both
operations.
There are multiple functions that can take on the role of create_func:
createFileDir - previously called mkdir(), now calls virDirCreate().
virStorageBackendCreateRaw - previously called open(),
now calls virFileCreate().
virStorageBackendCreateQemuImg - use virRunWithHook() to setuid/gid.
virStorageBackendCreateQcowCreate - same.
virStorageBackendCreateBlockFrom - preserve old behavior (but attempt
chown when necessary even if not root)
* src/storage/storage_backend.[ch] src/storage/storage_backend_disk.c
src/storage/storage_backend_fs.c src/storage/storage_backend_logical.c
src/storage/storage_driver.c: change the create_func implementations,
also propagate the pool information to be able to detect NETFS ones.
* src/storage/storage_backend_fs.c (virStorageBackendFileSystemRefresh):
Correct parentheses. The documented intent is to ignore non-regular
files, yet due to a parenthesization error all errors were handled
that way.
This patch removes the call to vol update after the volume build completes.
The update call is currently meaningless anyway because the vol build is passed
a copy of the definition, so the update result is thrown away. More
importantly, if the user specified a selinux label for the volume, the update
call results in a double free of the label
* src/storage/storage_backend_fs.c: remove the update call
* src/storage/storage_backend_fs.c: virStorageBackendFileSystemDelete
was incorrectly calling unlink() in an attempt to remove a directory.
It should be calling rmdir() instead.
Finally, we get to the point of all this.
Move virStorageGetMetadataFromFD() to virStorageFileGetMetadataFromFD()
and move to src/util/storage_file.[ch]
There's no functional changes in this patch, just code movement
* src/storage/storage_backend_fs.c: move code from here ...
* src/util/storage_file.[ch]: ... to here
* src/libvirt_private.syms: export virStorageFileGetMetadataFromFD()
Introduce a metadata structure and make virStorageGetMetadataFromFD()
fill it in.
* src/util/storage_file.h: add virStorageFileMetadata
* src/backend/storage_backend_fs.c: virStorageGetMetadataFromFD() now
fills in the virStorageFileMetadata structure
Prepare the code probing a file's format and associated metadata for
moving into libvirt_util.
* src/storage/storage_backend_fs.c: re-factor the format and metadata
probing code in preparation for moving it
Rename virStorageVolFormatFileSystem to virStorageFileFormat and
move to src/util/storage_file.[ch]
* src/Makefile.am: add src/util/storage_file.[ch]
* src/conf/storage_conf.[ch]: move enum from here ...
* src/util/storage_file.[ch]: .. to here
* src/libvirt_private.syms: update To/FromString exports
* src/storage/storage_backend.c, src/storage/storage_backend_fs.c,
src/vbox/vbox_tmpl.c: update for above changes