Compare commits

...

7 Commits

Author SHA1 Message Date
Vincent Batts 7b1f8fc8be
gomod: fix the project name
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2023-02-16 14:44:50 +00:00
Matthew Arnold 8b11b56685 Update latest nbdkit bindings. 2021-04-05 14:19:09 +00:00
Matthew Arnold 8112e93376
Try to not fail job on empty directories. 2021-01-18 14:22:38 -05:00
Matthew Arnold fd424f6985
Update README.md 2020-11-23 20:23:28 -05:00
Matthew Arnold 710be3402d Update latest nbdkit bindings. 2020-09-28 20:01:35 +00:00
Matthew Arnold 9d15554eb8
Add automatic update workflow. 2020-09-28 15:59:35 -04:00
Matthew Arnold 79817a4a3f Add license and README. 2020-09-28 14:43:50 -04:00
8 changed files with 1045 additions and 0 deletions

108
.github/workflows/update.yml vendored Normal file
View File

@ -0,0 +1,108 @@
name: Update
on:
schedule:
- cron: '0 14 * * 1'
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install xmllint
run: |
sudo apt-get update
sudo apt-get install libxml2-utils
- name: Update nbdkit bindings from libguestfs.org releases
run: |
#!/usr/bin/env bash
RELEASES=$(curl --silent https://download.libguestfs.org/nbdkit/ | xmllint --html --noblanks --xpath "/html/body/table/tr[td/img/@alt = '[DIR]']/td[a/.]/a/text()" -)
git config --global user.email "marnold@redhat.com"
git config --global user.name "Matthew Arnold"
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git pull --all --set-upstream
for release in ${RELEASES}
do
release=${release%?}
TARBALLS=$(curl --silent https://download.libguestfs.org/nbdkit/$release/ | xmllint --html --noblanks --xpath "/html/body/table/tr/td[contains(a/@href, '.tar.gz') and not(contains(a/@href, '.tar.gz.sig'))]/a/@href" -) || true
for tarball in ${TARBALLS}
do
IFS=\"$IFS read href tarball suffix <<< $tarball # Intentionally overwrite tarball
IFS="-.$IFS" read nbdkit major minor build suffix <<< $tarball
if (($major \* 100000000 + $minor \* 10000 + $build \< 100190009))
then # Go bindings added in 1.19.9
echo Ignoring release older than 1.19.9: $release/$tarball
echo
continue
fi
latestrelease=$release
version=$major.$minor.$build
tag=v$major.$minor.$build
echo Branch: $release Tar: $tarball Tag: $tag
if git rev-parse --verify $tag
then
echo Already present in repository: $tag
else
if ! (git rev-parse --verify $release || git rev-parse --verify origin/$release)
then
echo Creating new branch: $release
root=$(git rev-list --max-parents=0 HEAD)
git checkout $root
git checkout -b $release
else
echo Checking out existing branch: $release
git checkout $release
fi
echo Updating $release branch with new version $version
curl --silent https://download.libguestfs.org/nbdkit/$release/$tarball | tar -xzv --strip-components=6 nbdkit-$version/plugins/golang/src/libguestfs.org/nbdkit/
rm -f .gitignore
git add --all
git diff-index --quiet HEAD || git commit -m "Import nbdkit-$version"
git tag $tag
fi
if git rev-parse --verify $tag-cdi
then
echo Already present in repository: $tag-cdi
else
if ! (git rev-parse --verify $release-cdi || git rev-parse --verify origin/$release-cdi)
then
echo Creating new branch: $release-cdi
root=$(git rev-list --max-parents=0 HEAD)
git checkout $root
git checkout -b $release-cdi
else
echo Checking out existing branch: $release-cdi
git checkout $release-cdi
fi
git checkout $tag ./
find . -type f -name '*.go' -exec sed -i 's/#cgo pkg-config: nbdkit/#cgo LDFLAGS: -lnbdkit/g' {} +
git add --all
git diff-index --quiet HEAD || git commit -m "Tweak nbdkit-$version for CDI build"
git tag $tag-cdi
fi
echo
echo
done
done
latest=$(tail -n 1 <<< $latestrelease)
git checkout main
if git rev-parse --verify $latestrelease
then
echo Copy newest bindings from local $latest
git checkout $latest ./
elif git rev-parse --verify origin/$latestrelease
then
echo Copy newest bindings from remote $latest
git checkout origin/$latest ./
else
echo Latest branch not present in local or remote? Check libguestfs.org for unpopulated directory.
fi
git diff-index --quiet HEAD || git commit -m "Update latest nbdkit bindings."
git push --all -u
git push --tags

30
LICENSE Normal file
View File

@ -0,0 +1,30 @@
nbdkit
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.

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# go-nbdkit
Importable Golang bindings for nbdkit, extracted from official libguestfs.org releases.
This repository includes all the auto-generated golang files from the official libguestfs.org releases of nbdkit, so that the bindings can be imported with `go.mod` or `go get`. This is intended as a temporary measure to allow [CDI](https://github.com/kubevirt/containerized-data-importer) to make use of nbdkit plugins for functional tests.
Requires a minimum of nbdkit version 1.20.

4
go.mod Normal file
View File

@ -0,0 +1,4 @@
module git.batts.cloud/vbatts/go-nbdkit
// First version of golang with working module support.
go 1.13

569
nbdkit.go Normal file
View File

@ -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 pkg-config: nbdkit
#cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-in-object-files
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define NBDKIT_API_VERSION 2
#include <nbdkit-plugin.h>
#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 = C.uint64_t(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(C.size_t(struct_size)))
*p = plugin
return unsafe.Pointer(p)
}

75
utils.go Normal file
View File

@ -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 pkg-config: nbdkit
#define NBDKIT_API_VERSION 2
#include <nbdkit-plugin.h>
// 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))
}

196
wrappers.go Normal file
View File

@ -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 pkg-config: nbdkit
#include <stdio.h>
#include <stdlib.h>
#define NBDKIT_API_VERSION 2
#include <nbdkit-plugin.h>
#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"

57
wrappers.h Normal file
View File

@ -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);