nbd

package
v0.0.0-...-9abaa2f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2017 License: MIT Imports: 32 Imported by: 3

Documentation

Index

Constants

View Source
const (
	ENV_CONFFILE = "_GONBDSERVER_CONFFILE"
	ENV_PIDFILE  = "_GONBDSERVER_PIDFILE"
)
View Source
const (
	NBD_CMD_READ         = 0
	NBD_CMD_WRITE        = 1
	NBD_CMD_DISC         = 2
	NBD_CMD_FLUSH        = 3
	NBD_CMD_TRIM         = 4
	NBD_CMD_WRITE_ZEROES = 5
	NBD_CMD_CLOSE        = 7
)

NBD commands

View Source
const (
	NBD_CMD_FLAG_FUA = uint16(1 << 0)
	NBD_CMD_MAY_TRIM = uint16(1 << 1)
	NBD_CMD_FLAG_DF  = uint16(1 << 2)
)

NBD command flags

View Source
const (
	NBD_FLAG_HAS_FLAGS         = uint16(1 << 0)
	NBD_FLAG_READ_ONLY         = uint16(1 << 1)
	NBD_FLAG_SEND_FLUSH        = uint16(1 << 2)
	NBD_FLAG_SEND_FUA          = uint16(1 << 3)
	NBD_FLAG_ROTATIONAL        = uint16(1 << 4)
	NBD_FLAG_SEND_TRIM         = uint16(1 << 5)
	NBD_FLAG_SEND_WRITE_ZEROES = uint16(1 << 6)
	NBD_FLAG_SEND_DF           = uint16(1 << 7)
	NBD_FLAG_SEND_CLOSE        = uint16(1 << 8)
)

NBD negotiation flags

View Source
const (
	NBD_MAGIC                  = 0x4e42444d41474943
	NBD_REQUEST_MAGIC          = 0x25609513
	NBD_REPLY_MAGIC            = 0x67446698
	NBD_CLISERV_MAGIC          = 0x00420281861253
	NBD_OPTS_MAGIC             = 0x49484156454F5054
	NBD_REP_MAGIC              = 0x3e889045565a9
	NBD_STRUCTURED_REPLY_MAGIC = 0x668e33ef
)

NBD magic numbers

View Source
const (
	NBD_OPT_EXPORT_NAME      = 1
	NBD_OPT_ABORT            = 2
	NBD_OPT_LIST             = 3
	NBD_OPT_PEEK_EXPORT      = 4
	NBD_OPT_STARTTLS         = 5
	NBD_OPT_INFO             = 6
	NBD_OPT_GO               = 7
	NBD_OPT_STRUCTURED_REPLY = 8
)

NBD options

View Source
const (
	NBD_REP_ACK                 = uint32(1)
	NBD_REP_SERVER              = uint32(2)
	NBD_REP_INFO                = uint32(3)
	NBD_REP_FLAG_ERROR          = uint32(1 << 31)
	NBD_REP_ERR_UNSUP           = uint32(1 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_POLICY          = uint32(2 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_INVALID         = uint32(3 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_PLATFORM        = uint32(4 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_TLS_REQD        = uint32(5 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_UNKNOWN         = uint32(6 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_SHUTDOWN        = uint32(7 | NBD_REP_FLAG_ERROR)
	NBD_REP_ERR_BLOCK_SIZE_REQD = uint32(8 | NBD_REP_FLAG_ERROR)
)

NBD option reply types

View Source
const (
	NBD_REPLY_TYPE_NONE         = 0
	NBD_REPLY_TYPE_ERROR        = 1
	NBD_REPLY_TYPE_ERROR_OFFSET = 2
	NBD_REPLY_TYPE_OFFSET_DATA  = 3
	NBD_REPLY_TYPE_OFFSET_HOLE  = 4
)

NBD reply types

View Source
const (
	NBD_FLAG_FIXED_NEWSTYLE = 1 << 0
	NBD_FLAG_NO_ZEROES      = 1 << 1
)

NBD hanshake flags

View Source
const (
	NBD_FLAG_C_FIXED_NEWSTYLE = 1 << 0
	NBD_FLAG_C_NO_ZEROES      = 1 << 1
)

NBD client flags

View Source
const (
	NBD_EPERM     = 1
	NBD_EIO       = 5
	NBD_ENOMEM    = 12
	NBD_EINVAL    = 22
	NBD_ENOSPC    = 28
	NBD_EOVERFLOW = 75
)

NBD errors

View Source
const (
	NBD_INFO_EXPORT      = 0
	NBD_INFO_NAME        = 1
	NBD_INFO_DESCRIPTION = 2
	NBD_INFO_BLOCK_SIZE  = 3
)

NBD info types

View Source
const (
	CMDT_CHECK_LENGTH_OFFSET     = 1 << iota // length and offset must be valid
	CMDT_REQ_PAYLOAD                         // request carries a payload
	CMDT_REQ_FAKE_PAYLOAD                    // request does not carry a payload, but we'll make a zero payload up
	CMDT_REP_PAYLOAD                         // reply carries a payload
	CMDT_CHECK_NOT_READ_ONLY                 // not valid on read-only media
	CMDT_SET_DISCONNECT_RECEIVED             // a disconnect - don't process any further commands
)

Our internal flags to characterize commands

View Source
const (
	NBD_DEFAULT_PORT = 10809
)

NBD default port

View Source
const (
	NBD_REPLY_FLAG_DONE = 1 << 0
)

NBD reply flags

Variables

View Source
var BackendMap map[string]func(ctx context.Context, e *ExportConfig) (Backend, error) = make(map[string]func(ctx context.Context, e *ExportConfig) (Backend, error))

BackendMap is a map between backends and the generator function for them

A map specifying each command

View Source
var DefaultWorkers = 5

Default number of workers

Functions

func GetBackendNames

func GetBackendNames() []string

func NbdError

func NbdError(err error) uint32

NbdError translates an error returned by golang into an NBD error

This function could do with some serious work!

func RegisterBackend

func RegisterBackend(name string, generator func(ctx context.Context, e *ExportConfig) (Backend, error))

func Run

func Run(control *Control)

func RunConfig

func RunConfig(control *Control)

RunConfig - this is effectively the main entry point of the program

We parse the config, then start each of the listeners, restarting them when we get SIGHUP, but being sure not to kill the sessions

func StartServer

func StartServer(parentCtx context.Context, sessionParentCtx context.Context, sessionWaitGroup *sync.WaitGroup, logger *log.Logger, s ServerConfig)

Startserver starts a single server.

A parent context is given in which the listener runs, as well as a session context in which the sessions (connections) themselves run. This enables the sessions to be retained when the listener is cancelled on a SIGHUP

Types

type AioFileBackend

type AioFileBackend struct {
	// contains filtered or unexported fields
}

AioFileBackend implements Backend

func (*AioFileBackend) Close

func (afb *AioFileBackend) Close(ctx context.Context) error

Close implements Backend.Close

func (*AioFileBackend) Flush

func (afb *AioFileBackend) Flush(ctx context.Context) error

Flush implements Backend.Flush

func (*AioFileBackend) Geometry

func (afb *AioFileBackend) Geometry(ctx context.Context) (uint64, uint64, uint64, uint64, error)

Size implements Backend.Size

func (*AioFileBackend) HasFlush

func (afb *AioFileBackend) HasFlush(ctx context.Context) bool

Size implements Backend.HasFua

func (*AioFileBackend) HasFua

func (afb *AioFileBackend) HasFua(ctx context.Context) bool

Size implements Backend.HasFua

func (*AioFileBackend) ReadAt

func (afb *AioFileBackend) ReadAt(ctx context.Context, b []byte, offset int64) (int, error)

ReadAt implements Backend.ReadAt

func (*AioFileBackend) TrimAt

func (afb *AioFileBackend) TrimAt(ctx context.Context, length int, offset int64) (int, error)

TrimAt implements Backend.TrimAt

func (*AioFileBackend) WriteAt

func (afb *AioFileBackend) WriteAt(ctx context.Context, b []byte, offset int64, fua bool) (int, error)

WriteAt implements Backend.WriteAt

type Backend

type Backend interface {
	WriteAt(ctx context.Context, b []byte, offset int64, fua bool) (int, error) // write data b at offset, with force unit access optional
	ReadAt(ctx context.Context, b []byte, offset int64) (int, error)            // read to b at offset
	TrimAt(ctx context.Context, length int, offset int64) (int, error)          // trim
	Flush(ctx context.Context) error                                            // flush
	Close(ctx context.Context) error                                            // close
	Geometry(ctx context.Context) (uint64, uint64, uint64, uint64, error)       // size, minimum BS, preferred BS, maximum BS
	HasFua(ctx context.Context) bool                                            // does the driver support FUA?
	HasFlush(ctx context.Context) bool                                          // does the driver support flush?
}

Backend is an interface implemented by the various backend drivers

func NewAioFileBackend

func NewAioFileBackend(ctx context.Context, ec *ExportConfig) (Backend, error)

Generate a new aio backend

func NewFileBackend

func NewFileBackend(ctx context.Context, ec *ExportConfig) (Backend, error)

Generate a new file backend

func NewRbdBackend

func NewRbdBackend(ctx context.Context, ec *ExportConfig) (Backend, error)

Generate a new file backend

type Config

type Config struct {
	Servers []ServerConfig // array of server configs
	Logging LogConfig      // Configuration for logging
}

Config holds the config that applies to all servers (currently just logging), and an array of server configs

func ParseConfig

func ParseConfig() (*Config, error)

ParseConfig parses the YAML configuration provided

func (*Config) GetLogger

func (c *Config) GetLogger() (*log.Logger, io.Closer, error)

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection holds the details for each connection

func (*Connection) Dispatch

func (c *Connection) Dispatch(ctx context.Context, n int)

Dispatch is the goroutine used to process received items, passing the reply to the transmit goroutine

one of these is run for each worker

func (*Connection) FreeMemory

func (c *Connection) FreeMemory(ctx context.Context, mem [][]byte)

Get memory for a particular length

func (*Connection) GetMemory

func (c *Connection) GetMemory(ctx context.Context, length uint64) [][]byte

Get memory for a particular length

func (*Connection) Kill

func (c *Connection) Kill(ctx context.Context)

Kill kills a connection. This safely ensures the kill channel is closed if it isn't already, which will kill all the goroutines

func (*Connection) Negotiate

func (c *Connection) Negotiate(ctx context.Context) error

Negotiate negotiates a connection

func (*Connection) Receive

func (c *Connection) Receive(ctx context.Context)

Receive is the goroutine that handles decoding conncetion data from the socket

func (*Connection) ReturnMemory

func (c *Connection) ReturnMemory(ctx context.Context)

periodically return all memory under the low water mark back to the OS

func (*Connection) Serve

func (c *Connection) Serve(parentCtx context.Context)

Serve negotiates, then starts all the goroutines for processing a connection, then waits for them to be ended

func (*Connection) Transmit

func (c *Connection) Transmit(ctx context.Context)

Transmit is the goroutine run to transmit the processed requests (now replies)

func (*Connection) ZeroMemory

func (c *Connection) ZeroMemory(ctx context.Context, mem [][]byte)

Zero memory

type ConnectionParameters

type ConnectionParameters struct {
	ConnectionTimeout time.Duration // maximum time to complete negotiation
}

ConnectionParameters holds parameters for each inbound connection

type Control

type Control struct {
	// contains filtered or unexported fields
}

type DeadlineListener

type DeadlineListener interface {
	SetDeadline(t time.Time) error
	net.Listener
}

An listener type that does what we want

type DriverParametersConfig

type DriverParametersConfig map[string]string

DriverConfig is an arbitrary map of other parameters in string format

type Export

type Export struct {
	// contains filtered or unexported fields
}

Details of an export

type ExportConfig

type ExportConfig struct {
	Name               string                 // name of the export
	Description        string                 // description of export
	Driver             string                 // name of the driver
	ReadOnly           bool                   // true of the export should be opened readonly
	Workers            int                    // number of concurrent workers
	TlsOnly            bool                   // true if the export should only be served over TLS
	MinimumBlockSize   uint64                 // minimum block size
	PreferredBlockSize uint64                 // preferred block size
	MaximumBlockSize   uint64                 // maximum block size
	DriverParameters   DriverParametersConfig `yaml:",inline"` // driver parameters. These are an arbitrary map. Inline means they go aside teh foregoing
}

ExportConfig holds the config for one exported item

type FileBackend

type FileBackend struct {
	// contains filtered or unexported fields
}

FileBackend implements Backend

func (*FileBackend) Close

func (fb *FileBackend) Close(ctx context.Context) error

Close implements Backend.Close

func (*FileBackend) Flush

func (fb *FileBackend) Flush(ctx context.Context) error

Flush implements Backend.Flush

func (*FileBackend) Geometry

func (fb *FileBackend) Geometry(ctx context.Context) (uint64, uint64, uint64, uint64, error)

Size implements Backend.Size

func (*FileBackend) HasFlush

func (fb *FileBackend) HasFlush(ctx context.Context) bool

Size implements Backend.HasFua

func (*FileBackend) HasFua

func (fb *FileBackend) HasFua(ctx context.Context) bool

Size implements Backend.HasFua

func (*FileBackend) ReadAt

func (fb *FileBackend) ReadAt(ctx context.Context, b []byte, offset int64) (int, error)

ReadAt implements Backend.ReadAt

func (*FileBackend) TrimAt

func (fb *FileBackend) TrimAt(ctx context.Context, length int, offset int64) (int, error)

TrimAt implements Backend.TrimAt

func (*FileBackend) WriteAt

func (fb *FileBackend) WriteAt(ctx context.Context, b []byte, offset int64, fua bool) (int, error)

WriteAt implements Backend.WriteAt

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

A single listener on a given net.Conn address

func NewListener

func NewListener(logger *log.Logger, s ServerConfig) (*Listener, error)

NewListener returns a new listener object

func (*Listener) Listen

func (l *Listener) Listen(parentCtx context.Context, sessionParentCtx context.Context, sessionWaitGroup *sync.WaitGroup)

Listen listens on an given address for incoming connections

When sessions come in they are started on a separate context (sessionParentCtx), so that the listener can be killed without killing the sessions

type LogConfig

type LogConfig struct {
	File           string // a file to log to
	FileMode       string // file mode
	SyslogFacility string // a syslog facility name - set to enable syslog
	Date           bool   // log the date - i.e. log.Ldate
	Time           bool   // log the time - i.e. log.Ltime
	Microseconds   bool   // log microseconds - i.e. log.Lmicroseconds
	UTC            bool   // log time in URC - i.e. LUTC
	SourceFile     bool   // log source file - i.e. Lshortfile
}

LogConfig specifies configuration for logging

type RbdBackend

type RbdBackend struct {
	// contains filtered or unexported fields
}

RbdBackend implements Backend

func (*RbdBackend) Close

func (rb *RbdBackend) Close(ctx context.Context) error

Close implements Backend.Close

func (*RbdBackend) Flush

func (rb *RbdBackend) Flush(ctx context.Context) error

Flush implements Backend.Flush

func (*RbdBackend) Geometry

func (rb *RbdBackend) Geometry(ctx context.Context) (uint64, uint64, uint64, uint64, error)

Size implements Backend.Size

func (*RbdBackend) HasFlush

func (rb *RbdBackend) HasFlush(ctx context.Context) bool

Size implements Backend.HasFua

func (*RbdBackend) HasFua

func (rb *RbdBackend) HasFua(ctx context.Context) bool

Size implements Backend.HasFua

func (*RbdBackend) ReadAt

func (rb *RbdBackend) ReadAt(ctx context.Context, b []byte, offset int64) (int, error)

ReadAt implements Backend.ReadAt

func (*RbdBackend) TrimAt

func (rb *RbdBackend) TrimAt(ctx context.Context, length int, offset int64) (int, error)

TrimAt implements Backend.TrimAt

func (*RbdBackend) WriteAt

func (rb *RbdBackend) WriteAt(ctx context.Context, b []byte, offset int64, fua bool) (int, error)

WriteAt implements Backend.WriteAt

type Request

type Request struct {
	// contains filtered or unexported fields
}

Request is an internal structure for propagating requests through the channels

type ServerConfig

type ServerConfig struct {
	Protocol        string         // protocol it should listen on (in net.Conn form)
	Address         string         // address to listen on
	DefaultExport   string         // name of default export
	Exports         []ExportConfig // array of configurations of exported items
	Tls             TlsConfig      // TLS configuration
	DisableNoZeroes bool           // Disable NoZereos extension
}

ServerConfig holds the config that applies to each server (i.e. listener)

type SyslogWriter

type SyslogWriter struct {
	// contains filtered or unexported fields
}

SyslogWriter is a WriterCloser that logs to syslog with an extracted priority

func NewSyslogWriter

func NewSyslogWriter(facility string) (*SyslogWriter, error)

Create a new syslog writer

func (*SyslogWriter) Close

func (s *SyslogWriter) Close() error

Close the channel

func (*SyslogWriter) Write

func (s *SyslogWriter) Write(p []byte) (n int, err error)

Write to the syslog, removing the prefix and setting the appropriate level

type TlsConfig

type TlsConfig struct {
	KeyFile    string // path to TLS key file
	CertFile   string // path to TLS cert file
	ServerName string // server name
	CaCertFile string // path to certificate file
	ClientAuth string // client authentication strategy
	MinVersion string // minimum TLS version
	MaxVersion string // maximum TLS version
}

TlsConfig has the configuration for TLS

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL