diff --git a/internal/linux/filesystem.go b/internal/linux/filesystem.go index 093fdbee11c..03c09d841d2 100644 --- a/internal/linux/filesystem.go +++ b/internal/linux/filesystem.go @@ -42,6 +42,16 @@ func DetectFilesystem(path string) (string, error) { return FSTypeToName(int32(fs.Type)) } +// IsNFS returns true if the path exists and is on a NFS mount. +func IsNFS(path string) bool { + backingFs, err := DetectFilesystem(path) + if err != nil { + return false + } + + return backingFs == "nfs" +} + // FSTypeToName returns the name of the given fs type. // The fsType is from the Type field of unix.Statfs_t. We use int32 so that this function behaves the same on both // 32bit and 64bit platforms by requiring any 64bit FS types to be overflowed before being passed in. They will diff --git a/shared/archive/archive.go b/shared/archive/archive.go index ea6063af716..8e03846673f 100644 --- a/shared/archive/archive.go +++ b/shared/archive/archive.go @@ -15,6 +15,7 @@ import ( "golang.org/x/sys/unix" + "github.com/lxc/incus/v6/internal/linux" "github.com/lxc/incus/v6/shared/ioprogress" "github.com/lxc/incus/v6/shared/logger" "github.com/lxc/incus/v6/shared/subprocess" @@ -200,6 +201,13 @@ func Unpack(file string, path string, blockBackend bool, maxMemory int64, tracke } } + // NFS 4.2 can support xattrs, but not security.xattr. + if linux.IsNFS(path) { + logger.Warn("Unpack: destination path is NFS, disabling non-user xatttr unpacking", logger.Ctx{"file": file, "command": command, "extension": extension, "path": path, "args": args}) + + args = append(args, "-user-xattrs") + } + args = append(args, file) } else { return fmt.Errorf("Unsupported image format: %s", extension)