LXC domains with long file-backed filesystem path fail to start when
the backing image path is longer than LO_NAME_SIZE (64 bytes, 63 characters
plus NUL).
When long file path is passed, virFileLoopDeviceAssociate() -> virStrcpy() fails
and user gets missleading error and domain fails to start.
Example:
<filesystem type='file' accessmode='passthrough'>
<driver type='loop' format='raw'/>
<source
file='/root/demoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.raw'/>
<target dir='/'/>
</filesystem>
To match losetup behavior we copy the path with virStrcpy() and allow truncation
of lo_file_name only if needed, while still calling open() on the unchanged
path.
Finally log VIR_WARN when the path is expected to be truncated. But still report
VIR_ERR_INTERNAL_ERROR for all other virStrcpy() failures.
Fixes: https://gitlab.com/libvirt/libvirt/-/work_items/63
Signed-off-by: Radoslaw Smigielski <[email protected]>
---
src/util/virfile.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/util/virfile.c b/src/util/virfile.c
index a0c6cb804862..ae33deb8d223 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -995,11 +995,18 @@ int virFileLoopDeviceAssociate(const char *file,
lo.lo_flags = LO_FLAGS_AUTOCLEAR;
- /* Set backing file name for LOOP_GET_STATUS64 queries */
+ /* lo_file_name is loop device name, max length is LO_NAME_SIZE bytes.
+ * Truncate loop device name if file path is longer than LO_NAME_SIZE,
+ * and still use the full path to open backing file. */
if (virStrcpy((char *) lo.lo_file_name, file, LO_NAME_SIZE) < 0) {
- virReportSystemError(errno,
- _("Unable to set backing file %1$s"), file);
- goto cleanup;
+ if (strlen(file) >= LO_NAME_SIZE) {
+ VIR_WARN("Loop backing device name %s truncated to %d bytes.",
+ file, LO_NAME_SIZE);
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to set loop lo_file_name for %1$s"),
file);
+ goto cleanup;
+ }
}
if ((fsfd = open(file, O_RDWR)) < 0) {
--
2.54.0