xref: /openbmc/qemu/backends/hostmem-file.c (revision 3e246da2c3f85298b52f8a1154b832acf36aa656)
152330e1aSPaolo Bonzini /*
252330e1aSPaolo Bonzini  * QEMU Host Memory Backend for hugetlbfs
352330e1aSPaolo Bonzini  *
452330e1aSPaolo Bonzini  * Copyright (C) 2013-2014 Red Hat Inc
552330e1aSPaolo Bonzini  *
652330e1aSPaolo Bonzini  * Authors:
752330e1aSPaolo Bonzini  *   Paolo Bonzini <pbonzini@redhat.com>
852330e1aSPaolo Bonzini  *
952330e1aSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2 or later.
1052330e1aSPaolo Bonzini  * See the COPYING file in the top-level directory.
1152330e1aSPaolo Bonzini  */
120b8fa32fSMarkus Armbruster 
139c058332SPeter Maydell #include "qemu/osdep.h"
14da34e65cSMarkus Armbruster #include "qapi/error.h"
15a4de8552SJunyan He #include "qemu/error-report.h"
160b8fa32fSMarkus Armbruster #include "qemu/module.h"
17b85ea5faSPeter Maydell #include "qemu/madvise.h"
1852330e1aSPaolo Bonzini #include "sysemu/hostmem.h"
1952330e1aSPaolo Bonzini #include "qom/object_interfaces.h"
20db1015e9SEduardo Habkost #include "qom/object.h"
21e92666b0SDavid Hildenbrand #include "qapi/visitor.h"
22e92666b0SDavid Hildenbrand #include "qapi/qapi-visit-common.h"
2352330e1aSPaolo Bonzini 
248063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE)
2552330e1aSPaolo Bonzini 
2652330e1aSPaolo Bonzini 
2752330e1aSPaolo Bonzini struct HostMemoryBackendFile {
2852330e1aSPaolo Bonzini     HostMemoryBackend parent_obj;
29dbcb8981SPaolo Bonzini 
3052330e1aSPaolo Bonzini     char *mem_path;
3198376843SHaozhong Zhang     uint64_t align;
324b870dc4SAlexander Graf     uint64_t offset;
33a4de8552SJunyan He     bool discard_data;
34a4de8552SJunyan He     bool is_pmem;
3586635aa4SStefan Hajnoczi     bool readonly;
36e92666b0SDavid Hildenbrand     OnOffAuto rom;
3752330e1aSPaolo Bonzini };
3852330e1aSPaolo Bonzini 
39fdb63cf3SPhilippe Mathieu-Daudé static bool
file_backend_memory_alloc(HostMemoryBackend * backend,Error ** errp)4052330e1aSPaolo Bonzini file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
4152330e1aSPaolo Bonzini {
425c7ba877SIgor Mammedov #ifndef CONFIG_POSIX
435c7ba877SIgor Mammedov     error_setg(errp, "backend '%s' not supported on this host",
445c7ba877SIgor Mammedov                object_get_typename(OBJECT(backend)));
45fdb63cf3SPhilippe Mathieu-Daudé     return false;
465c7ba877SIgor Mammedov #else
4752330e1aSPaolo Bonzini     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
482d7a1eb6SPhilippe Mathieu-Daudé     g_autofree gchar *name = NULL;
499181fb70SDavid Hildenbrand     uint32_t ram_flags;
5052330e1aSPaolo Bonzini 
5152330e1aSPaolo Bonzini     if (!backend->size) {
5252330e1aSPaolo Bonzini         error_setg(errp, "can't create backend with size 0");
53fdb63cf3SPhilippe Mathieu-Daudé         return false;
5452330e1aSPaolo Bonzini     }
5552330e1aSPaolo Bonzini     if (!fb->mem_path) {
56c2cb2b04SJan Kiszka         error_setg(errp, "mem-path property not set");
57fdb63cf3SPhilippe Mathieu-Daudé         return false;
5852330e1aSPaolo Bonzini     }
59314aec4aSStefan Hajnoczi 
60e92666b0SDavid Hildenbrand     switch (fb->rom) {
61e92666b0SDavid Hildenbrand     case ON_OFF_AUTO_AUTO:
62e92666b0SDavid Hildenbrand         /* Traditionally, opening the file readonly always resulted in ROM. */
63e92666b0SDavid Hildenbrand         fb->rom = fb->readonly ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
64e92666b0SDavid Hildenbrand         break;
65e92666b0SDavid Hildenbrand     case ON_OFF_AUTO_ON:
66e92666b0SDavid Hildenbrand         if (!fb->readonly) {
67e92666b0SDavid Hildenbrand             error_setg(errp, "property 'rom' = 'on' is not supported with"
68e92666b0SDavid Hildenbrand                        " 'readonly' = 'off'");
69fdb63cf3SPhilippe Mathieu-Daudé             return false;
70e92666b0SDavid Hildenbrand         }
71e92666b0SDavid Hildenbrand         break;
72e92666b0SDavid Hildenbrand     case ON_OFF_AUTO_OFF:
73e92666b0SDavid Hildenbrand         if (fb->readonly && backend->share) {
74e92666b0SDavid Hildenbrand             error_setg(errp, "property 'rom' = 'off' is incompatible with"
75e92666b0SDavid Hildenbrand                        " 'readonly' = 'on' and 'share' = 'on'");
76fdb63cf3SPhilippe Mathieu-Daudé             return false;
77e92666b0SDavid Hildenbrand         }
78e92666b0SDavid Hildenbrand         break;
79e92666b0SDavid Hildenbrand     default:
80fdb63cf3SPhilippe Mathieu-Daudé         g_assert_not_reached();
81e92666b0SDavid Hildenbrand     }
82e92666b0SDavid Hildenbrand 
83*5d9a9a61SMichal Privoznik     backend->aligned = true;
84fa0cb34dSMarc-André Lureau     name = host_memory_backend_get_name(backend);
859181fb70SDavid Hildenbrand     ram_flags = backend->share ? RAM_SHARED : 0;
86e92666b0SDavid Hildenbrand     ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
87e92666b0SDavid Hildenbrand     ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
889181fb70SDavid Hildenbrand     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
8937662d85SXiaoyao Li     ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
909181fb70SDavid Hildenbrand     ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
91b0182e53SSteve Sistare     ram_flags |= RAM_NAMED_FILE;
92fdb63cf3SPhilippe Mathieu-Daudé     return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
939181fb70SDavid Hildenbrand                                             backend->size, fb->align, ram_flags,
945c52a219SDavid Hildenbrand                                             fb->mem_path, fb->offset, errp);
9552330e1aSPaolo Bonzini #endif
9652330e1aSPaolo Bonzini }
9752330e1aSPaolo Bonzini 
get_mem_path(Object * o,Error ** errp)9852330e1aSPaolo Bonzini static char *get_mem_path(Object *o, Error **errp)
9952330e1aSPaolo Bonzini {
10052330e1aSPaolo Bonzini     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
10152330e1aSPaolo Bonzini 
10252330e1aSPaolo Bonzini     return g_strdup(fb->mem_path);
10352330e1aSPaolo Bonzini }
10452330e1aSPaolo Bonzini 
set_mem_path(Object * o,const char * str,Error ** errp)10552330e1aSPaolo Bonzini static void set_mem_path(Object *o, const char *str, Error **errp)
10652330e1aSPaolo Bonzini {
10752330e1aSPaolo Bonzini     HostMemoryBackend *backend = MEMORY_BACKEND(o);
10852330e1aSPaolo Bonzini     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
10952330e1aSPaolo Bonzini 
1106f4c60e4SPeter Xu     if (host_memory_backend_mr_inited(backend)) {
11121d16836SZhang Yi         error_setg(errp, "cannot change property 'mem-path' of %s",
11221d16836SZhang Yi                    object_get_typename(o));
11352330e1aSPaolo Bonzini         return;
11452330e1aSPaolo Bonzini     }
11552330e1aSPaolo Bonzini     g_free(fb->mem_path);
11652330e1aSPaolo Bonzini     fb->mem_path = g_strdup(str);
11752330e1aSPaolo Bonzini }
11852330e1aSPaolo Bonzini 
file_memory_backend_get_discard_data(Object * o,Error ** errp)11911ae6ed8SEduardo Habkost static bool file_memory_backend_get_discard_data(Object *o, Error **errp)
12011ae6ed8SEduardo Habkost {
12111ae6ed8SEduardo Habkost     return MEMORY_BACKEND_FILE(o)->discard_data;
12211ae6ed8SEduardo Habkost }
12311ae6ed8SEduardo Habkost 
file_memory_backend_set_discard_data(Object * o,bool value,Error ** errp)12411ae6ed8SEduardo Habkost static void file_memory_backend_set_discard_data(Object *o, bool value,
12511ae6ed8SEduardo Habkost                                                Error **errp)
12611ae6ed8SEduardo Habkost {
12711ae6ed8SEduardo Habkost     MEMORY_BACKEND_FILE(o)->discard_data = value;
12811ae6ed8SEduardo Habkost }
12911ae6ed8SEduardo Habkost 
file_memory_backend_get_align(Object * o,Visitor * v,const char * name,void * opaque,Error ** errp)13098376843SHaozhong Zhang static void file_memory_backend_get_align(Object *o, Visitor *v,
13198376843SHaozhong Zhang                                           const char *name, void *opaque,
13298376843SHaozhong Zhang                                           Error **errp)
13398376843SHaozhong Zhang {
13498376843SHaozhong Zhang     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
13598376843SHaozhong Zhang     uint64_t val = fb->align;
13698376843SHaozhong Zhang 
13798376843SHaozhong Zhang     visit_type_size(v, name, &val, errp);
13898376843SHaozhong Zhang }
13998376843SHaozhong Zhang 
file_memory_backend_set_align(Object * o,Visitor * v,const char * name,void * opaque,Error ** errp)14098376843SHaozhong Zhang static void file_memory_backend_set_align(Object *o, Visitor *v,
14198376843SHaozhong Zhang                                           const char *name, void *opaque,
14298376843SHaozhong Zhang                                           Error **errp)
14398376843SHaozhong Zhang {
14498376843SHaozhong Zhang     HostMemoryBackend *backend = MEMORY_BACKEND(o);
14598376843SHaozhong Zhang     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
14698376843SHaozhong Zhang     uint64_t val;
14798376843SHaozhong Zhang 
14898376843SHaozhong Zhang     if (host_memory_backend_mr_inited(backend)) {
149dcfe4805SMarkus Armbruster         error_setg(errp, "cannot change property '%s' of %s", name,
150dcfe4805SMarkus Armbruster                    object_get_typename(o));
151dcfe4805SMarkus Armbruster         return;
15298376843SHaozhong Zhang     }
15398376843SHaozhong Zhang 
154668f62ecSMarkus Armbruster     if (!visit_type_size(v, name, &val, errp)) {
155dcfe4805SMarkus Armbruster         return;
15698376843SHaozhong Zhang     }
15798376843SHaozhong Zhang     fb->align = val;
15898376843SHaozhong Zhang }
15998376843SHaozhong Zhang 
file_memory_backend_get_offset(Object * o,Visitor * v,const char * name,void * opaque,Error ** errp)1604b870dc4SAlexander Graf static void file_memory_backend_get_offset(Object *o, Visitor *v,
1614b870dc4SAlexander Graf                                           const char *name, void *opaque,
1624b870dc4SAlexander Graf                                           Error **errp)
1634b870dc4SAlexander Graf {
1644b870dc4SAlexander Graf     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
1654b870dc4SAlexander Graf     uint64_t val = fb->offset;
1664b870dc4SAlexander Graf 
1674b870dc4SAlexander Graf     visit_type_size(v, name, &val, errp);
1684b870dc4SAlexander Graf }
1694b870dc4SAlexander Graf 
file_memory_backend_set_offset(Object * o,Visitor * v,const char * name,void * opaque,Error ** errp)1704b870dc4SAlexander Graf static void file_memory_backend_set_offset(Object *o, Visitor *v,
1714b870dc4SAlexander Graf                                           const char *name, void *opaque,
1724b870dc4SAlexander Graf                                           Error **errp)
1734b870dc4SAlexander Graf {
1744b870dc4SAlexander Graf     HostMemoryBackend *backend = MEMORY_BACKEND(o);
1754b870dc4SAlexander Graf     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
1764b870dc4SAlexander Graf     uint64_t val;
1774b870dc4SAlexander Graf 
1784b870dc4SAlexander Graf     if (host_memory_backend_mr_inited(backend)) {
1794b870dc4SAlexander Graf         error_setg(errp, "cannot change property '%s' of %s", name,
1804b870dc4SAlexander Graf                    object_get_typename(o));
1814b870dc4SAlexander Graf         return;
1824b870dc4SAlexander Graf     }
1834b870dc4SAlexander Graf 
1844b870dc4SAlexander Graf     if (!visit_type_size(v, name, &val, errp)) {
1854b870dc4SAlexander Graf         return;
1864b870dc4SAlexander Graf     }
1874b870dc4SAlexander Graf     fb->offset = val;
1884b870dc4SAlexander Graf }
1894b870dc4SAlexander Graf 
190def835f0SMichal Privoznik #ifdef CONFIG_LIBPMEM
file_memory_backend_get_pmem(Object * o,Error ** errp)191a4de8552SJunyan He static bool file_memory_backend_get_pmem(Object *o, Error **errp)
192a4de8552SJunyan He {
193a4de8552SJunyan He     return MEMORY_BACKEND_FILE(o)->is_pmem;
194a4de8552SJunyan He }
195a4de8552SJunyan He 
file_memory_backend_set_pmem(Object * o,bool value,Error ** errp)196a4de8552SJunyan He static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
197a4de8552SJunyan He {
198a4de8552SJunyan He     HostMemoryBackend *backend = MEMORY_BACKEND(o);
199a4de8552SJunyan He     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
200a4de8552SJunyan He 
201a4de8552SJunyan He     if (host_memory_backend_mr_inited(backend)) {
20287dc3ce6SZhang Yi         error_setg(errp, "cannot change property 'pmem' of %s.",
20387dc3ce6SZhang Yi                    object_get_typename(o));
204a4de8552SJunyan He         return;
205a4de8552SJunyan He     }
206a4de8552SJunyan He 
207a4de8552SJunyan He     fb->is_pmem = value;
208a4de8552SJunyan He }
209def835f0SMichal Privoznik #endif /* CONFIG_LIBPMEM */
210a4de8552SJunyan He 
file_memory_backend_get_readonly(Object * obj,Error ** errp)21186635aa4SStefan Hajnoczi static bool file_memory_backend_get_readonly(Object *obj, Error **errp)
21286635aa4SStefan Hajnoczi {
21386635aa4SStefan Hajnoczi     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
21486635aa4SStefan Hajnoczi 
21586635aa4SStefan Hajnoczi     return fb->readonly;
21686635aa4SStefan Hajnoczi }
21786635aa4SStefan Hajnoczi 
file_memory_backend_set_readonly(Object * obj,bool value,Error ** errp)21886635aa4SStefan Hajnoczi static void file_memory_backend_set_readonly(Object *obj, bool value,
21986635aa4SStefan Hajnoczi                                              Error **errp)
22086635aa4SStefan Hajnoczi {
22186635aa4SStefan Hajnoczi     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
22286635aa4SStefan Hajnoczi     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
22386635aa4SStefan Hajnoczi 
22486635aa4SStefan Hajnoczi     if (host_memory_backend_mr_inited(backend)) {
22586635aa4SStefan Hajnoczi         error_setg(errp, "cannot change property 'readonly' of %s.",
22686635aa4SStefan Hajnoczi                    object_get_typename(obj));
22786635aa4SStefan Hajnoczi         return;
22886635aa4SStefan Hajnoczi     }
22986635aa4SStefan Hajnoczi 
23086635aa4SStefan Hajnoczi     fb->readonly = value;
23186635aa4SStefan Hajnoczi }
23286635aa4SStefan Hajnoczi 
file_memory_backend_get_rom(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)233e92666b0SDavid Hildenbrand static void file_memory_backend_get_rom(Object *obj, Visitor *v,
234e92666b0SDavid Hildenbrand                                         const char *name, void *opaque,
235e92666b0SDavid Hildenbrand                                         Error **errp)
236e92666b0SDavid Hildenbrand {
237e92666b0SDavid Hildenbrand     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
238e92666b0SDavid Hildenbrand     OnOffAuto rom = fb->rom;
239e92666b0SDavid Hildenbrand 
240e92666b0SDavid Hildenbrand     visit_type_OnOffAuto(v, name, &rom, errp);
241e92666b0SDavid Hildenbrand }
242e92666b0SDavid Hildenbrand 
file_memory_backend_set_rom(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)243e92666b0SDavid Hildenbrand static void file_memory_backend_set_rom(Object *obj, Visitor *v,
244e92666b0SDavid Hildenbrand                                         const char *name, void *opaque,
245e92666b0SDavid Hildenbrand                                         Error **errp)
246e92666b0SDavid Hildenbrand {
247e92666b0SDavid Hildenbrand     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
248e92666b0SDavid Hildenbrand     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
249e92666b0SDavid Hildenbrand 
250e92666b0SDavid Hildenbrand     if (host_memory_backend_mr_inited(backend)) {
251e92666b0SDavid Hildenbrand         error_setg(errp, "cannot change property '%s' of %s.", name,
252e92666b0SDavid Hildenbrand                    object_get_typename(obj));
253e92666b0SDavid Hildenbrand         return;
254e92666b0SDavid Hildenbrand     }
255e92666b0SDavid Hildenbrand 
256e92666b0SDavid Hildenbrand     visit_type_OnOffAuto(v, name, &fb->rom, errp);
257e92666b0SDavid Hildenbrand }
258e92666b0SDavid Hildenbrand 
file_backend_unparent(Object * obj)25911ae6ed8SEduardo Habkost static void file_backend_unparent(Object *obj)
26011ae6ed8SEduardo Habkost {
26111ae6ed8SEduardo Habkost     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
26211ae6ed8SEduardo Habkost     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
26311ae6ed8SEduardo Habkost 
26411ae6ed8SEduardo Habkost     if (host_memory_backend_mr_inited(backend) && fb->discard_data) {
26511ae6ed8SEduardo Habkost         void *ptr = memory_region_get_ram_ptr(&backend->mr);
26611ae6ed8SEduardo Habkost         uint64_t sz = memory_region_size(&backend->mr);
26711ae6ed8SEduardo Habkost 
26811ae6ed8SEduardo Habkost         qemu_madvise(ptr, sz, QEMU_MADV_REMOVE);
26911ae6ed8SEduardo Habkost     }
27011ae6ed8SEduardo Habkost }
27111ae6ed8SEduardo Habkost 
27252330e1aSPaolo Bonzini static void
file_backend_class_init(ObjectClass * oc,void * data)273026ac483SEduardo Habkost file_backend_class_init(ObjectClass *oc, void *data)
27452330e1aSPaolo Bonzini {
275026ac483SEduardo Habkost     HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
276026ac483SEduardo Habkost 
277026ac483SEduardo Habkost     bc->alloc = file_backend_memory_alloc;
27811ae6ed8SEduardo Habkost     oc->unparent = file_backend_unparent;
279026ac483SEduardo Habkost 
28011ae6ed8SEduardo Habkost     object_class_property_add_bool(oc, "discard-data",
281d2623129SMarkus Armbruster         file_memory_backend_get_discard_data, file_memory_backend_set_discard_data);
282026ac483SEduardo Habkost     object_class_property_add_str(oc, "mem-path",
283d2623129SMarkus Armbruster         get_mem_path, set_mem_path);
28498376843SHaozhong Zhang     object_class_property_add(oc, "align", "int",
28598376843SHaozhong Zhang         file_memory_backend_get_align,
28698376843SHaozhong Zhang         file_memory_backend_set_align,
287d2623129SMarkus Armbruster         NULL, NULL);
2884b870dc4SAlexander Graf     object_class_property_add(oc, "offset", "int",
2894b870dc4SAlexander Graf         file_memory_backend_get_offset,
2904b870dc4SAlexander Graf         file_memory_backend_set_offset,
2914b870dc4SAlexander Graf         NULL, NULL);
2924b870dc4SAlexander Graf     object_class_property_set_description(oc, "offset",
2934b870dc4SAlexander Graf         "Offset into the target file (ex: 1G)");
294def835f0SMichal Privoznik #ifdef CONFIG_LIBPMEM
295a4de8552SJunyan He     object_class_property_add_bool(oc, "pmem",
296d2623129SMarkus Armbruster         file_memory_backend_get_pmem, file_memory_backend_set_pmem);
297def835f0SMichal Privoznik #endif
29886635aa4SStefan Hajnoczi     object_class_property_add_bool(oc, "readonly",
29986635aa4SStefan Hajnoczi         file_memory_backend_get_readonly,
30086635aa4SStefan Hajnoczi         file_memory_backend_set_readonly);
301e92666b0SDavid Hildenbrand     object_class_property_add(oc, "rom", "OnOffAuto",
302e92666b0SDavid Hildenbrand         file_memory_backend_get_rom, file_memory_backend_set_rom, NULL, NULL);
303e92666b0SDavid Hildenbrand     object_class_property_set_description(oc, "rom",
304e92666b0SDavid Hildenbrand         "Whether to create Read Only Memory (ROM)");
30552330e1aSPaolo Bonzini }
30652330e1aSPaolo Bonzini 
file_backend_instance_finalize(Object * o)307bc78a013SMarc-André Lureau static void file_backend_instance_finalize(Object *o)
308bc78a013SMarc-André Lureau {
309bc78a013SMarc-André Lureau     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
310bc78a013SMarc-André Lureau 
311bc78a013SMarc-André Lureau     g_free(fb->mem_path);
312bc78a013SMarc-André Lureau }
313bc78a013SMarc-André Lureau 
31452330e1aSPaolo Bonzini static const TypeInfo file_backend_info = {
31552330e1aSPaolo Bonzini     .name = TYPE_MEMORY_BACKEND_FILE,
31652330e1aSPaolo Bonzini     .parent = TYPE_MEMORY_BACKEND,
31752330e1aSPaolo Bonzini     .class_init = file_backend_class_init,
318bc78a013SMarc-André Lureau     .instance_finalize = file_backend_instance_finalize,
31952330e1aSPaolo Bonzini     .instance_size = sizeof(HostMemoryBackendFile),
32052330e1aSPaolo Bonzini };
32152330e1aSPaolo Bonzini 
register_types(void)32252330e1aSPaolo Bonzini static void register_types(void)
32352330e1aSPaolo Bonzini {
32452330e1aSPaolo Bonzini     type_register_static(&file_backend_info);
32552330e1aSPaolo Bonzini }
32652330e1aSPaolo Bonzini 
32752330e1aSPaolo Bonzini type_init(register_types);
328