[PATCHv2] lxc: truncate LOOP_GET_STATUS64.lo_file_name for long loop backing paths
From: Radoslaw Smigielski <rsmigiel@redhat.com> LXC domains using a file-backed filesystem with the loop driver fail to start when the backing image path is longer than LO_NAME_SIZE (64 bytes, 63 characters plus NUL). virFileLoopDeviceAssociate() treated a failed virStrcpy() into loop_info64.lo_file_name as fatal and reported a misleading virReportSystemError(errno, ...), so users saw errors such as "Unable to set backing file ...: Success" or ENOENT even when the file existed. The kernel only stores a short name in lo_file_name for LOOP_SET_STATUS64 metadata. The backing file is opened by full path. Copy the path with virStrcpy(), allow truncation into lo_file_name, and mark truncation with '*' at LO_NAME_SIZE - 2 to match losetup behavior. Log truncation at debug level only. XML example that failed before this change: <filesystem type='file' accessmode='passthrough'> <driver type='loop' format='raw'/> <source file='/root/demoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.raw'/> <target dir='/'/> </filesystem> Fixes: https://gitlab.com/libvirt/libvirt/-/work_items/63 Signed-off-by: Radoslaw Smigielski <rsmigiel@redhat.com> --- src/util/virfile.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index a0c6cb804862..443d0ed9adab 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -995,11 +995,15 @@ 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; + /* virStrcpy() only returns -1 on truncation. Mark truncation with + * asterisk at position LO_NAME_SIZE-2 to match losetup behavior. */ + lo.lo_file_name[LO_NAME_SIZE - 2] = '*'; + VIR_DEBUG("lo_file_name for '%s' truncated to %d bytes in loop metadata", + file, LO_NAME_SIZE); } if ((fsfd = open(file, O_RDWR)) < 0) { -- 2.54.0
participants (1)
-
Radoslaw Smigielski