From 01fb7055ead0cbe15c17e8d4b04dd96e0a7e7f5e Mon Sep 17 00:00:00 2001 From: Matthew Arnold Date: Mon, 28 Sep 2020 20:01:22 +0000 Subject: [PATCH] Tweak nbdkit-1.22.0 for CDI build --- nbdkit.go | 569 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.go | 75 +++++++ wrappers.go | 196 ++++++++++++++++++ wrappers.h | 57 ++++++ 4 files changed, 897 insertions(+) create mode 100644 nbdkit.go create mode 100644 utils.go create mode 100644 wrappers.go create mode 100644 wrappers.h diff --git a/nbdkit.go b/nbdkit.go new file mode 100644 index 0000000..fdad135 --- /dev/null +++ b/nbdkit.go @@ -0,0 +1,569 @@ +/* Go helper functions. + * Copyright (C) 2013-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +package nbdkit + +/* +#cgo LDFLAGS: -lnbdkit +#cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-in-object-files + +#include +#include +#include + +#define NBDKIT_API_VERSION 2 +#include +#include "wrappers.h" +*/ +import "C" + +import ( + "fmt" + "reflect" + "syscall" + "unsafe" +) + +// The plugin may raise errors by returning this struct (instead of nil). +type PluginError struct { + Errmsg string // string (passed to nbdkit_error) + Errno syscall.Errno // errno (optional, use 0 if not available) +} + +func (e PluginError) String() string { + if e.Errno != 0 { + return e.Errmsg + } else { + return fmt.Sprintf("%s (errno %d)", e.Errmsg, e.Errno) + } +} + +func (e PluginError) Error() string { + return e.String() +} + +// Flags and other constants. +const ( + ThreadModelSerializeConnections = uint32(C.NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS) + ThreadModelSerializeAllRequests = uint32(C.NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) + ThreadModelSerializeRequests = uint32(C.NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS) + ThreadModelParallel = uint32(C.NBDKIT_THREAD_MODEL_PARALLEL) + + FlagMayTrim = uint32(C.NBDKIT_FLAG_MAY_TRIM) + FlagFUA = uint32(C.NBDKIT_FLAG_FUA) + FlagReqOne = uint32(C.NBDKIT_FLAG_REQ_ONE) + FlagFastZero = uint32(C.NBDKIT_FLAG_FAST_ZERO) + + FUANone = uint32(C.NBDKIT_FUA_NONE) + FUAEmulate = uint32(C.NBDKIT_FUA_EMULATE) + FUANative = uint32(C.NBDKIT_FUA_NATIVE) + + CacheNone = uint32(C.NBDKIT_CACHE_NONE) + CacheEmulate = uint32(C.NBDKIT_CACHE_EMULATE) + CacheNative = uint32(C.NBDKIT_CACHE_NATIVE) + + ExtentHole = uint32(C.NBDKIT_EXTENT_HOLE) + ExtentZero = uint32(C.NBDKIT_EXTENT_ZERO) + + // This is not defined by the header, but by this file. It + // might be useful for plugins to know this (even though they + // probably wouldn't be source-compatible with other API + // versions) so we expose it to golang code. + APIVersion = uint32(C.NBDKIT_API_VERSION) +) + +// The plugin interface. +type PluginInterface interface { + Load() + Unload() + + DumpPlugin() + + Config(key string, value string) error + ConfigComplete() error + GetReady() error + + PreConnect(readonly bool) error + Open(readonly bool) (ConnectionInterface, error) // required +} + +// The client connection interface. +type ConnectionInterface interface { + GetSize() (uint64, error) // required + IsRotational() (bool, error) + CanMultiConn() (bool, error) + + PRead(buf []byte, offset uint64, flags uint32) error // required + + // NB: PWrite will NOT be called unless CanWrite returns true. + CanWrite() (bool, error) + PWrite(buf []byte, offset uint64, flags uint32) error + + // NB: Flush will NOT be called unless CanFlush returns true. + CanFlush() (bool, error) + Flush(flags uint32) error + + // NB: Trim will NOT be called unless CanTrim returns true. + CanTrim() (bool, error) + Trim(count uint32, offset uint64, flags uint32) error + + // NB: Zero will NOT be called unless CanZero returns true. + CanZero() (bool, error) + Zero(count uint32, offset uint64, flags uint32) error + + Close() +} + +// Default implementations for plugin interface methods. +type Plugin struct{} +type Connection struct{} + +func (p *Plugin) Load() { +} + +func (p *Plugin) Unload() { +} + +func (p *Plugin) DumpPlugin() { +} + +func (p *Plugin) Config(key string, value string) error { + return nil +} + +func (p *Plugin) ConfigComplete() error { + return nil +} + +func (p *Plugin) GetReady() error { + return nil +} + +func (p *Plugin) PreConnect(readonly bool) error { + return nil +} + +func (p *Plugin) Open(readonly bool) (ConnectionInterface, error) { + panic("plugin must implement Open()") +} + +func (c *Connection) Close() { +} + +func (c *Connection) GetSize() (uint64, error) { + panic("plugin must implement GetSize()") +} + +func (c *Connection) CanWrite() (bool, error) { + return false, nil +} + +func (c *Connection) CanFlush() (bool, error) { + return false, nil +} + +func (c *Connection) IsRotational() (bool, error) { + return false, nil +} + +func (c *Connection) CanTrim() (bool, error) { + return false, nil +} + +func (c *Connection) CanZero() (bool, error) { + return false, nil +} + +func (c *Connection) CanMultiConn() (bool, error) { + return false, nil +} + +func (c *Connection) PRead(buf []byte, offset uint64, flags uint32) error { + panic("plugin must implement PRead()") +} + +func (c *Connection) PWrite(buf []byte, offset uint64, flags uint32) error { + panic("plugin CanWrite returns true, but no PWrite() function") +} + +func (c *Connection) Flush(flags uint32) error { + panic("plugin CanFlush returns true, but no Flush() function") +} + +func (c *Connection) Trim(count uint32, offset uint64, flags uint32) error { + panic("plugin CanTrim returns true, but no Trim() function") +} + +func (c *Connection) Zero(count uint32, offset uint64, flags uint32) error { + panic("plugin CanZero returns true, but no Zero() function") +} + +// The implementation of the user plugin. +var pluginImpl PluginInterface +var nextConnectionId uintptr +var connectionMap map[uintptr]ConnectionInterface + +// Callbacks from the server. These translate C to Go and back. + +func set_error(err error) { + perr, ok := err.(PluginError) + if ok { + if perr.Errno != 0 { + SetError(perr.Errno) + } + Error(perr.Errmsg) + } else { + Error(err.Error()) + } +} + +//export implLoad +func implLoad() { + pluginImpl.Load() +} + +//export implUnload +func implUnload() { + pluginImpl.Unload() +} + +//export implDumpPlugin +func implDumpPlugin() { + pluginImpl.DumpPlugin() +} + +//export implConfig +func implConfig(key *C.char, value *C.char) C.int { + err := pluginImpl.Config(C.GoString(key), C.GoString(value)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implConfigComplete +func implConfigComplete() C.int { + err := pluginImpl.ConfigComplete() + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implGetReady +func implGetReady() C.int { + err := pluginImpl.GetReady() + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implPreConnect +func implPreConnect(c_readonly C.int) C.int { + readonly := false + if c_readonly != 0 { + readonly = true + } + err := pluginImpl.PreConnect(readonly) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implOpen +func implOpen(c_readonly C.int) unsafe.Pointer { + readonly := false + if c_readonly != 0 { + readonly = true + } + h, err := pluginImpl.Open(readonly) + if err != nil { + set_error(err) + return nil + } + id := nextConnectionId + nextConnectionId++ + connectionMap[id] = h + return unsafe.Pointer(id) +} + +func getConn(handle unsafe.Pointer) ConnectionInterface { + id := uintptr(handle) + h, ok := connectionMap[id] + if !ok { + panic(fmt.Sprintf("connection %d was not open", id)) + } + return h +} + +//export implClose +func implClose(handle unsafe.Pointer) { + h := getConn(handle) + h.Close() + id := uintptr(handle) + delete(connectionMap, id) +} + +//export implGetSize +func implGetSize(handle unsafe.Pointer) C.int64_t { + h := getConn(handle) + size, err := h.GetSize() + if err != nil { + set_error(err) + return -1 + } + return C.int64_t(size) +} + +//export implCanWrite +func implCanWrite(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.CanWrite() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implCanFlush +func implCanFlush(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.CanFlush() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implIsRotational +func implIsRotational(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.IsRotational() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implCanTrim +func implCanTrim(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.CanTrim() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implCanZero +func implCanZero(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.CanZero() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implCanMultiConn +func implCanMultiConn(handle unsafe.Pointer) C.int { + h := getConn(handle) + b, err := h.CanMultiConn() + if err != nil { + set_error(err) + return -1 + } + if b { + return 1 + } else { + return 0 + } +} + +//export implPRead +func implPRead(handle unsafe.Pointer, c_buf unsafe.Pointer, + count C.uint32_t, offset C.uint64_t, flags C.uint32_t) C.int { + h := getConn(handle) + // https://github.com/golang/go/issues/13656 + // https://stackoverflow.com/a/25776046 + hdr := reflect.SliceHeader{ + Data: uintptr(c_buf), + Len: int(count), + Cap: int(count), + } + buf := *(*[]byte)(unsafe.Pointer(&hdr)) + err := h.PRead(buf, uint64(offset), uint32(flags)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implPWrite +func implPWrite(handle unsafe.Pointer, c_buf unsafe.Pointer, + count C.uint32_t, offset C.uint64_t, flags C.uint32_t) C.int { + h := getConn(handle) + // https://github.com/golang/go/issues/13656 + // https://stackoverflow.com/a/25776046 + hdr := reflect.SliceHeader{ + Data: uintptr(c_buf), + Len: int(count), + Cap: int(count), + } + buf := *(*[]byte)(unsafe.Pointer(&hdr)) + err := h.PWrite(buf, uint64(offset), uint32(flags)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implFlush +func implFlush(handle unsafe.Pointer, flags C.uint32_t) C.int { + h := getConn(handle) + err := h.Flush(uint32(flags)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implTrim +func implTrim(handle unsafe.Pointer, + count C.uint32_t, offset C.uint64_t, flags C.uint32_t) C.int { + h := getConn(handle) + err := h.Trim(uint32(count), uint64(offset), uint32(flags)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +//export implZero +func implZero(handle unsafe.Pointer, + count C.uint32_t, offset C.uint64_t, flags C.uint32_t) C.int { + h := getConn(handle) + err := h.Zero(uint32(count), uint64(offset), uint32(flags)) + if err != nil { + set_error(err) + return -1 + } + return 0 +} + +// Called from C plugin_init function. +func PluginInitialize(name string, impl PluginInterface) unsafe.Pointer { + // Initialize the connection map. Note that connection IDs + // must start counting from 1 since we must never return what + // looks like a NULL pointer to the C code. + connectionMap = make(map[uintptr]ConnectionInterface) + nextConnectionId = 1 + + pluginImpl = impl + + plugin := C.struct_nbdkit_plugin{} + + // Set up the hidden plugin fields as for C. + struct_size := C.ulong(unsafe.Sizeof(plugin)) + plugin._struct_size = struct_size + plugin._api_version = C.NBDKIT_API_VERSION + plugin._thread_model = C.NBDKIT_THREAD_MODEL_PARALLEL + + // Set up the other fields. + plugin.name = C.CString(name) + plugin.load = (*[0]byte)(C.wrapper_load) + plugin.unload = (*[0]byte)(C.wrapper_unload) + plugin.dump_plugin = (*[0]byte)(C.wrapper_dump_plugin) + plugin.config = (*[0]byte)(C.wrapper_config) + plugin.config_complete = (*[0]byte)(C.wrapper_config_complete) + plugin.get_ready = (*[0]byte)(C.wrapper_get_ready) + plugin.preconnect = (*[0]byte)(C.wrapper_preconnect) + plugin.open = (*[0]byte)(C.wrapper_open) + plugin.close = (*[0]byte)(C.wrapper_close) + plugin.get_size = (*[0]byte)(C.wrapper_get_size) + plugin.can_write = (*[0]byte)(C.wrapper_can_write) + plugin.can_flush = (*[0]byte)(C.wrapper_can_flush) + plugin.is_rotational = (*[0]byte)(C.wrapper_is_rotational) + plugin.can_trim = (*[0]byte)(C.wrapper_can_trim) + plugin.can_zero = (*[0]byte)(C.wrapper_can_zero) + plugin.can_multi_conn = (*[0]byte)(C.wrapper_can_multi_conn) + plugin.pread = (*[0]byte)(C.wrapper_pread) + plugin.pwrite = (*[0]byte)(C.wrapper_pwrite) + plugin.flush = (*[0]byte)(C.wrapper_flush) + plugin.trim = (*[0]byte)(C.wrapper_trim) + plugin.zero = (*[0]byte)(C.wrapper_zero) + + // Golang plugins don't preserve errno correctly. + plugin.errno_is_preserved = 0 + + // Return a newly malloced copy of the struct. This must be + // globally available to the C code in the server, so it is + // never freed. + p := (*C.struct_nbdkit_plugin)(C.malloc(struct_size)) + *p = plugin + return unsafe.Pointer(p) +} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..0fb6922 --- /dev/null +++ b/utils.go @@ -0,0 +1,75 @@ +/* cgo wrappers. + * Copyright (C) 2013-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +package nbdkit + +/* +#cgo LDFLAGS: -lnbdkit + +#define NBDKIT_API_VERSION 2 +#include + +// cgo cannot call varargs functions. +void +_nbdkit_debug (const char *s) +{ + nbdkit_debug ("%s", s); +} + +// cgo cannot call varargs functions. +void +_nbdkit_error (const char *s) +{ + nbdkit_error ("%s", s); +} +*/ +import "C" +import "syscall" + +// Utility functions. + +func Debug(s string) { + C._nbdkit_debug(C.CString(s)) +} + +// This function is provided but plugins would rarely need to call +// this explicitly since returning an error from a plugin callback +// will call it implicitly. +func Error(s string) { + C._nbdkit_error(C.CString(s)) +} + +// Same applies as for Error(). Callers should not usually need to +// call this. +func SetError(err syscall.Errno) { + C.nbdkit_set_error(C.int(err)) +} diff --git a/wrappers.go b/wrappers.go new file mode 100644 index 0000000..d7bd58d --- /dev/null +++ b/wrappers.go @@ -0,0 +1,196 @@ +/* cgo wrappers. + * Copyright (C) 2013-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +package nbdkit + +/* +#cgo LDFLAGS: -lnbdkit + +#include +#include + +#define NBDKIT_API_VERSION 2 +#include +#include "wrappers.h" + +extern void implLoad (); +void +wrapper_load (void) +{ + implLoad (); +} + +extern void implUnload (); +void +wrapper_unload (void) +{ + implUnload (); +} + +extern void implDumpPlugin (); +void +wrapper_dump_plugin (void) +{ + implDumpPlugin (); +} + +extern int implConfig (); +int +wrapper_config (const char *key, const char *value) +{ + return implConfig (key, value); +} + +extern int implConfigComplete (); +int +wrapper_config_complete (void) +{ + return implConfigComplete (); +} + +extern int implGetReady (); +int +wrapper_get_ready (void) +{ + return implGetReady (); +} + +extern int implPreConnect (); +int +wrapper_preconnect (int readonly) +{ + return implPreConnect (readonly); +} + +extern void *implOpen (); +void * +wrapper_open (int readonly) +{ + return implOpen (readonly); +} + +extern void implClose (); +void +wrapper_close (void *handle) +{ + return implClose (handle); +} + +extern int64_t implGetSize (); +int64_t +wrapper_get_size (void *handle) +{ + return implGetSize (handle); +} + +extern int implCanWrite (); +int +wrapper_can_write (void *handle) +{ + return implCanWrite (handle); +} + +extern int implCanFlush (); +int +wrapper_can_flush (void *handle) +{ + return implCanFlush (handle); +} + +extern int implIsRotational (); +int +wrapper_is_rotational (void *handle) +{ + return implIsRotational (handle); +} + +extern int implCanTrim (); +int +wrapper_can_trim (void *handle) +{ + return implCanTrim (handle); +} + +extern int implCanZero (); +int +wrapper_can_zero (void *handle) +{ + return implCanZero (handle); +} + +extern int implCanMultiConn (); +int +wrapper_can_multi_conn (void *handle) +{ + return implCanMultiConn (handle); +} + +extern int implPRead (); +int +wrapper_pread (void *handle, void *buf, + uint32_t count, uint64_t offset, uint32_t flags) +{ + return implPRead (handle, buf, count, offset, flags); +} + +extern int implPWrite (); +int +wrapper_pwrite (void *handle, const void *buf, + uint32_t count, uint64_t offset, uint32_t flags) +{ + return implPWrite (handle, buf, count, offset, flags); +} + +extern int implFlush (); +int +wrapper_flush (void *handle, uint32_t flags) +{ + return implFlush (handle, flags); +} + +extern int implTrim (); +int +wrapper_trim (void *handle, + uint32_t count, uint64_t offset, uint32_t flags) +{ + return implTrim (handle, count, offset, flags); +} + +extern int implZero (); +int +wrapper_zero (void *handle, + uint32_t count, uint64_t offset, uint32_t flags) +{ + return implZero (handle, count, offset, flags); +} +*/ +import "C" diff --git a/wrappers.h b/wrappers.h new file mode 100644 index 0000000..522b7a9 --- /dev/null +++ b/wrappers.h @@ -0,0 +1,57 @@ +/* cgo wrappers. + * Copyright (C) 2013-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern void wrapper_load (); +extern void wrapper_unload (); +extern void wrapper_dump_plugin (); +extern int wrapper_config (const char *key, const char *value); +extern int wrapper_config_complete (void); +extern int wrapper_get_ready (void); +extern int wrapper_preconnect (int readonly); +extern void * wrapper_open (int readonly); +extern void wrapper_close (void *handle); +extern int64_t wrapper_get_size (void *handle); +extern int wrapper_can_write (void *handle); +extern int wrapper_can_flush (void *handle); +extern int wrapper_is_rotational (void *handle); +extern int wrapper_can_trim (void *handle); +extern int wrapper_can_zero (void *handle); +extern int wrapper_can_multi_conn (void *handle); +extern int wrapper_pread (void *handle, void *buf, + uint32_t count, uint64_t offset, uint32_t flags); +extern int wrapper_pwrite (void *handle, const void *buf, + uint32_t count, uint64_t offset, uint32_t flags); +extern int wrapper_flush (void *handle, uint32_t flags); +extern int wrapper_trim (void *handle, + uint32_t count, uint64_t offset, uint32_t flags); +extern int wrapper_zero (void *handle, + uint32_t count, uint64_t offset, uint32_t flags);