Message ID | 20230418225749.1049185-2-peterx@redhat.com |
---|---|
State | New |
Headers | show |
Series | migration/hostmem: Allow to fail early for postcopy on specific fs type | expand |
On Tue, Apr 18, 2023 at 06:57:47PM -0400, Peter Xu wrote: > Detect the file system for a memory-backend-file object and cache it within > the object if possible when CONFIG_LINUX (using statfs). > > Only support the two important types of memory (tmpfs, hugetlbfs) and keep > the rest as "unknown" for now. > > Signed-off-by: Peter Xu <peterx@redhat.com> > --- > backends/hostmem-file.c | 37 ++++++++++++++++++++++++++++++++++++- > include/sysemu/hostmem.h | 1 + > 2 files changed, 37 insertions(+), 1 deletion(-) > > diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c > index 25141283c4..2484e45a11 100644 > --- a/backends/hostmem-file.c > +++ b/backends/hostmem-file.c > @@ -18,13 +18,17 @@ > #include "sysemu/hostmem.h" > #include "qom/object_interfaces.h" > #include "qom/object.h" > +#ifdef CONFIG_LINUX > +#include <sys/vfs.h> > +#include <linux/magic.h> > +#endif > > OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) > > > struct HostMemoryBackendFile { > HostMemoryBackend parent_obj; > - > + __fsword_t fs_type; > char *mem_path; > uint64_t align; > bool discard_data; > @@ -52,6 +56,15 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) > return; > } > > +#ifdef CONFIG_LINUX > + struct statfs fs; > + if (!statfs(fb->mem_path, &fs)) { > + fb->fs_type = fs.f_type; > + } else { > + fb->fs_type = 0; > + } > +#endif > + > name = host_memory_backend_get_name(backend); > ram_flags = backend->share ? RAM_SHARED : 0; > ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; > @@ -181,6 +194,28 @@ static void file_backend_unparent(Object *obj) > } > } > > +const char *file_memory_backend_get_fs_type(Object *obj) > +{ > +#ifdef CONFIG_LINUX > + HostMemoryBackendFile *fb = (HostMemoryBackendFile *) > + object_dynamic_cast(obj, TYPE_MEMORY_BACKEND_FILE); > + > + if (!fb) { > + goto out; > + } > + > + switch (fb->fs_type) { > + case TMPFS_MAGIC: > + return "tmpfs"; > + case HUGETLBFS_MAGIC: > + return "hugetlbfs"; > + } > + > +out: > +#endif > + return "unknown"; > +} I rather feel this should be returning an enm, not strings, so the caller just does a plain equality test rather than string comparisons With regards, Daniel
On 19.04.23 00:57, Peter Xu wrote: > Detect the file system for a memory-backend-file object and cache it within > the object if possible when CONFIG_LINUX (using statfs). > > Only support the two important types of memory (tmpfs, hugetlbfs) and keep > the rest as "unknown" for now. > > Signed-off-by: Peter Xu <peterx@redhat.com> > --- > backends/hostmem-file.c | 37 ++++++++++++++++++++++++++++++++++++- > include/sysemu/hostmem.h | 1 + > 2 files changed, 37 insertions(+), 1 deletion(-) > > diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c > index 25141283c4..2484e45a11 100644 > --- a/backends/hostmem-file.c > +++ b/backends/hostmem-file.c > @@ -18,13 +18,17 @@ > #include "sysemu/hostmem.h" > #include "qom/object_interfaces.h" > #include "qom/object.h" > +#ifdef CONFIG_LINUX > +#include <sys/vfs.h> > +#include <linux/magic.h> > +#endif > > OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) > > > struct HostMemoryBackendFile { > HostMemoryBackend parent_obj; > - > + __fsword_t fs_type; > char *mem_path; > uint64_t align; > bool discard_data; > @@ -52,6 +56,15 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) > return; > } > > +#ifdef CONFIG_LINUX > + struct statfs fs; > + if (!statfs(fb->mem_path, &fs)) { > + fb->fs_type = fs.f_type; > + } else { > + fb->fs_type = 0; > + } > +#endif > + Instead of using statfs, why not implement something like qemu_fd_getpagesize(), that also relies on HUGETLBFS_MAGIC already, meaning size_t qemu_fd_type(int fd) which uses fstatfs() instead? As an abstraction, as Daniel suggests, use a new enum to return the type -- "0" meaning "unknown". Then you can even avoid the caching in hostmem code and simply call it directly from uffd code.
On Wed, Apr 19, 2023 at 09:28:21AM +0200, David Hildenbrand wrote: > On 19.04.23 00:57, Peter Xu wrote: > > Detect the file system for a memory-backend-file object and cache it within > > the object if possible when CONFIG_LINUX (using statfs). > > > > Only support the two important types of memory (tmpfs, hugetlbfs) and keep > > the rest as "unknown" for now. > > > > Signed-off-by: Peter Xu <peterx@redhat.com> > > --- > > backends/hostmem-file.c | 37 ++++++++++++++++++++++++++++++++++++- > > include/sysemu/hostmem.h | 1 + > > 2 files changed, 37 insertions(+), 1 deletion(-) > > > > diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c > > index 25141283c4..2484e45a11 100644 > > --- a/backends/hostmem-file.c > > +++ b/backends/hostmem-file.c > > @@ -18,13 +18,17 @@ > > #include "sysemu/hostmem.h" > > #include "qom/object_interfaces.h" > > #include "qom/object.h" > > +#ifdef CONFIG_LINUX > > +#include <sys/vfs.h> > > +#include <linux/magic.h> > > +#endif > > OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) > > struct HostMemoryBackendFile { > > HostMemoryBackend parent_obj; > > - > > + __fsword_t fs_type; > > char *mem_path; > > uint64_t align; > > bool discard_data; > > @@ -52,6 +56,15 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) > > return; > > } > > +#ifdef CONFIG_LINUX > > + struct statfs fs; > > + if (!statfs(fb->mem_path, &fs)) { > > + fb->fs_type = fs.f_type; > > + } else { > > + fb->fs_type = 0; > > + } > > +#endif > > + > > > Instead of using statfs, why not implement something like > qemu_fd_getpagesize(), that also relies on HUGETLBFS_MAGIC already, meaning > > size_t qemu_fd_type(int fd) > > which uses fstatfs() instead? As an abstraction, as Daniel suggests, use a > new enum to return the type -- "0" meaning "unknown". > > Then you can even avoid the caching in hostmem code and simply call it > directly from uffd code. Yeah, can do. I think it depends on whether this can also be useful for other users of a file memory backend object where the fd may not be on hand. So far this's indeed the only one that needs it, though, so I can switch. Thanks,
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index 25141283c4..2484e45a11 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -18,13 +18,17 @@ #include "sysemu/hostmem.h" #include "qom/object_interfaces.h" #include "qom/object.h" +#ifdef CONFIG_LINUX +#include <sys/vfs.h> +#include <linux/magic.h> +#endif OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) struct HostMemoryBackendFile { HostMemoryBackend parent_obj; - + __fsword_t fs_type; char *mem_path; uint64_t align; bool discard_data; @@ -52,6 +56,15 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) return; } +#ifdef CONFIG_LINUX + struct statfs fs; + if (!statfs(fb->mem_path, &fs)) { + fb->fs_type = fs.f_type; + } else { + fb->fs_type = 0; + } +#endif + name = host_memory_backend_get_name(backend); ram_flags = backend->share ? RAM_SHARED : 0; ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; @@ -181,6 +194,28 @@ static void file_backend_unparent(Object *obj) } } +const char *file_memory_backend_get_fs_type(Object *obj) +{ +#ifdef CONFIG_LINUX + HostMemoryBackendFile *fb = (HostMemoryBackendFile *) + object_dynamic_cast(obj, TYPE_MEMORY_BACKEND_FILE); + + if (!fb) { + goto out; + } + + switch (fb->fs_type) { + case TMPFS_MAGIC: + return "tmpfs"; + case HUGETLBFS_MAGIC: + return "hugetlbfs"; + } + +out: +#endif + return "unknown"; +} + static void file_backend_class_init(ObjectClass *oc, void *data) { diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 39326f1d4f..0354cffa6b 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -81,5 +81,6 @@ void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped); bool host_memory_backend_is_mapped(HostMemoryBackend *backend); size_t host_memory_backend_pagesize(HostMemoryBackend *memdev); char *host_memory_backend_get_name(HostMemoryBackend *backend); +const char *file_memory_backend_get_fs_type(Object *obj); #endif
Detect the file system for a memory-backend-file object and cache it within the object if possible when CONFIG_LINUX (using statfs). Only support the two important types of memory (tmpfs, hugetlbfs) and keep the rest as "unknown" for now. Signed-off-by: Peter Xu <peterx@redhat.com> --- backends/hostmem-file.c | 37 ++++++++++++++++++++++++++++++++++++- include/sysemu/hostmem.h | 1 + 2 files changed, 37 insertions(+), 1 deletion(-)