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 <rsmigiel@redhat.com> --- 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