Cleanup, and fix decoding of TypedParams.
This commit is contained in:
		@@ -23,11 +23,14 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: make these an argument
 | 
					// TODO: make these an argument
 | 
				
			||||||
const lvPath = "../../../libvirt"
 | 
					 | 
				
			||||||
const protoPath = "src/remote/remote_protocol.x"
 | 
					const protoPath = "src/remote/remote_protocol.x"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	fmt.Println("Generating golang bindings for libvirt")
 | 
						lvPath := os.Getenv("LIBVIRT_SOURCE")
 | 
				
			||||||
 | 
						if lvPath == "" {
 | 
				
			||||||
 | 
							fmt.Println("set $LIBVIRT_SOURCE to point to the root of the libvirt sources and retry")
 | 
				
			||||||
 | 
							os.Exit(1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	lvFile := path.Join(lvPath, protoPath)
 | 
						lvFile := path.Join(lvPath, protoPath)
 | 
				
			||||||
	rdr, err := os.Open(lvFile)
 | 
						rdr, err := os.Open(lvFile)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,10 +14,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package lvgen
 | 
					package lvgen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The libvirt API is divided into several categories. (Gallia est omnis divisa
 | 
					 | 
				
			||||||
// in partes tres.) The generator will output code for each category in a
 | 
					 | 
				
			||||||
// package underneath the go-libvirt directory.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
@@ -29,30 +25,6 @@ import (
 | 
				
			|||||||
	"unicode/utf8"
 | 
						"unicode/utf8"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var keywords = map[string]int{
 | 
					 | 
				
			||||||
	"hyper":    HYPER,
 | 
					 | 
				
			||||||
	"int":      INT,
 | 
					 | 
				
			||||||
	"short":    SHORT,
 | 
					 | 
				
			||||||
	"char":     CHAR,
 | 
					 | 
				
			||||||
	"bool":     BOOL,
 | 
					 | 
				
			||||||
	"case":     CASE,
 | 
					 | 
				
			||||||
	"const":    CONST,
 | 
					 | 
				
			||||||
	"default":  DEFAULT,
 | 
					 | 
				
			||||||
	"double":   DOUBLE,
 | 
					 | 
				
			||||||
	"enum":     ENUM,
 | 
					 | 
				
			||||||
	"float":    FLOAT,
 | 
					 | 
				
			||||||
	"opaque":   OPAQUE,
 | 
					 | 
				
			||||||
	"string":   STRING,
 | 
					 | 
				
			||||||
	"struct":   STRUCT,
 | 
					 | 
				
			||||||
	"switch":   SWITCH,
 | 
					 | 
				
			||||||
	"typedef":  TYPEDEF,
 | 
					 | 
				
			||||||
	"union":    UNION,
 | 
					 | 
				
			||||||
	"unsigned": UNSIGNED,
 | 
					 | 
				
			||||||
	"void":     VOID,
 | 
					 | 
				
			||||||
	"program":  PROGRAM,
 | 
					 | 
				
			||||||
	"version":  VERSION,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ConstItem stores an const's symbol and value from the parser. This struct is
 | 
					// ConstItem stores an const's symbol and value from the parser. This struct is
 | 
				
			||||||
// also used for enums.
 | 
					// also used for enums.
 | 
				
			||||||
type ConstItem struct {
 | 
					type ConstItem struct {
 | 
				
			||||||
@@ -77,6 +49,8 @@ type Generator struct {
 | 
				
			|||||||
	Typedefs []Typedef
 | 
						Typedefs []Typedef
 | 
				
			||||||
	// Unions holds all the discriminated unions.
 | 
						// Unions holds all the discriminated unions.
 | 
				
			||||||
	Unions []Union
 | 
						Unions []Union
 | 
				
			||||||
 | 
						// UnionMap is a map of the unions we find for quick searching.
 | 
				
			||||||
 | 
						UnionMap map[string]int
 | 
				
			||||||
	// Procs holds all the discovered libvirt procedures.
 | 
						// Procs holds all the discovered libvirt procedures.
 | 
				
			||||||
	Procs []Proc
 | 
						Procs []Proc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -104,6 +78,9 @@ var goEquivTypes = map[string]string{
 | 
				
			|||||||
	// requires us to ditch the typedef that would otherwise be generated.
 | 
						// requires us to ditch the typedef that would otherwise be generated.
 | 
				
			||||||
	"NonnullString": "string",
 | 
						"NonnullString": "string",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: Get rid of these. They're only needed because we lose information
 | 
				
			||||||
 | 
						// that the parser has (the parser knows it has emitted a go type), and then
 | 
				
			||||||
 | 
						// we capitalize types to make them public.
 | 
				
			||||||
	"String":  "string",
 | 
						"String":  "string",
 | 
				
			||||||
	"Int":     "int",
 | 
						"Int":     "int",
 | 
				
			||||||
	"Uint":    "uint",
 | 
						"Uint":    "uint",
 | 
				
			||||||
@@ -122,7 +99,8 @@ var goEquivTypes = map[string]string{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// These defines are from libvirt-common.h. They should be fetched from there,
 | 
					// These defines are from libvirt-common.h. They should be fetched from there,
 | 
				
			||||||
// but for now they're hardcoded here.
 | 
					// but for now they're hardcoded here. (These are the discriminant values for
 | 
				
			||||||
 | 
					// TypedParams.)
 | 
				
			||||||
var lvTypedParams = map[string]uint32{
 | 
					var lvTypedParams = map[string]uint32{
 | 
				
			||||||
	"VIR_TYPED_PARAM_INT":     1,
 | 
						"VIR_TYPED_PARAM_INT":     1,
 | 
				
			||||||
	"VIR_TYPED_PARAM_UINT":    2,
 | 
						"VIR_TYPED_PARAM_UINT":    2,
 | 
				
			||||||
@@ -222,6 +200,7 @@ var CurrentCase *Case
 | 
				
			|||||||
// generation.
 | 
					// generation.
 | 
				
			||||||
func Generate(proto io.Reader) error {
 | 
					func Generate(proto io.Reader) error {
 | 
				
			||||||
	Gen.StructMap = make(map[string]int)
 | 
						Gen.StructMap = make(map[string]int)
 | 
				
			||||||
 | 
						Gen.UnionMap = make(map[string]int)
 | 
				
			||||||
	lexer, err := NewLexer(proto)
 | 
						lexer, err := NewLexer(proto)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -257,6 +236,8 @@ func Generate(proto io.Reader) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// genGo is called when the parsing is done; it generates the golang output
 | 
				
			||||||
 | 
					// files using templates.
 | 
				
			||||||
func genGo(constFile, procFile io.Writer) error {
 | 
					func genGo(constFile, procFile io.Writer) error {
 | 
				
			||||||
	t, err := template.ParseFiles("constants.tmpl")
 | 
						t, err := template.ParseFiles("constants.tmpl")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -273,18 +254,6 @@ func genGo(constFile, procFile io.Writer) error {
 | 
				
			|||||||
	if err := t.Execute(procFile, Gen); err != nil {
 | 
						if err := t.Execute(procFile, Gen); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Now generate the wrappers for libvirt's various public API functions.
 | 
					 | 
				
			||||||
	// for _, c := range Gen.Enums {
 | 
					 | 
				
			||||||
	// This appears to be the name of a libvirt procedure, so sort it into
 | 
					 | 
				
			||||||
	// the right list based on the next part of its name.
 | 
					 | 
				
			||||||
	// segs := camelcase.Split(c.Name)
 | 
					 | 
				
			||||||
	// if len(segs) < 3 || segs[0] != "Proc" {
 | 
					 | 
				
			||||||
	// 	continue
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
	//category := segs[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//fmt.Println(segs)
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -297,7 +266,7 @@ func constNameTransform(name string) string {
 | 
				
			|||||||
	decamelize := strings.ContainsRune(name, '_')
 | 
						decamelize := strings.ContainsRune(name, '_')
 | 
				
			||||||
	nn := strings.TrimPrefix(name, "REMOTE_")
 | 
						nn := strings.TrimPrefix(name, "REMOTE_")
 | 
				
			||||||
	if decamelize {
 | 
						if decamelize {
 | 
				
			||||||
		nn = fromSnakeToCamel(nn, true)
 | 
							nn = fromSnakeToCamel(nn)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	nn = fixAbbrevs(nn)
 | 
						nn = fixAbbrevs(nn)
 | 
				
			||||||
	return nn
 | 
						return nn
 | 
				
			||||||
@@ -307,7 +276,7 @@ func identifierTransform(name string) string {
 | 
				
			|||||||
	decamelize := strings.ContainsRune(name, '_')
 | 
						decamelize := strings.ContainsRune(name, '_')
 | 
				
			||||||
	nn := strings.TrimPrefix(name, "remote_")
 | 
						nn := strings.TrimPrefix(name, "remote_")
 | 
				
			||||||
	if decamelize {
 | 
						if decamelize {
 | 
				
			||||||
		nn = fromSnakeToCamel(nn, true)
 | 
							nn = fromSnakeToCamel(nn)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		nn = publicize(nn)
 | 
							nn = publicize(nn)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -337,10 +306,10 @@ func publicize(name string) string {
 | 
				
			|||||||
// are omitted.
 | 
					// are omitted.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// ex: "PROC_DOMAIN_GET_METADATA" -> "ProcDomainGetMetadata"
 | 
					// ex: "PROC_DOMAIN_GET_METADATA" -> "ProcDomainGetMetadata"
 | 
				
			||||||
func fromSnakeToCamel(s string, public bool) string {
 | 
					func fromSnakeToCamel(s string) string {
 | 
				
			||||||
	buf := make([]rune, 0, len(s))
 | 
						buf := make([]rune, 0, len(s))
 | 
				
			||||||
	// Start rune may be either upper or lower case.
 | 
						// Start rune will be upper case - we generate all public symbols.
 | 
				
			||||||
	hump := public
 | 
						hump := true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, r := range s {
 | 
						for _, r := range s {
 | 
				
			||||||
		if r == '_' {
 | 
							if r == '_' {
 | 
				
			||||||
@@ -496,8 +465,8 @@ func StartStruct(name string) {
 | 
				
			|||||||
// the now-complete struct definition to the generator's list.
 | 
					// the now-complete struct definition to the generator's list.
 | 
				
			||||||
func AddStruct() {
 | 
					func AddStruct() {
 | 
				
			||||||
	st := *CurrentStruct.pop()
 | 
						st := *CurrentStruct.pop()
 | 
				
			||||||
 | 
						Gen.StructMap[st.Name] = len(Gen.Structs)
 | 
				
			||||||
	Gen.Structs = append(Gen.Structs, st)
 | 
						Gen.Structs = append(Gen.Structs, st)
 | 
				
			||||||
	Gen.StructMap[st.Name] = len(Gen.Structs) - 1
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// StartTypedef is called when the parser finds a typedef.
 | 
					// StartTypedef is called when the parser finds a typedef.
 | 
				
			||||||
@@ -516,6 +485,7 @@ func StartUnion(name string) {
 | 
				
			|||||||
// pointer. We handle unions by declaring an interface for the union type, and
 | 
					// pointer. We handle unions by declaring an interface for the union type, and
 | 
				
			||||||
// adding methods to each of the cases so that they satisfy the interface.
 | 
					// adding methods to each of the cases so that they satisfy the interface.
 | 
				
			||||||
func AddUnion() {
 | 
					func AddUnion() {
 | 
				
			||||||
 | 
						Gen.UnionMap[CurrentUnion.Name] = len(Gen.Unions)
 | 
				
			||||||
	Gen.Unions = append(Gen.Unions, *CurrentUnion)
 | 
						Gen.Unions = append(Gen.Unions, *CurrentUnion)
 | 
				
			||||||
	CurrentUnion = nil
 | 
						CurrentUnion = nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -532,7 +502,7 @@ func StartCase(dvalue string) {
 | 
				
			|||||||
	if ix := strings.LastIndexByte(caseName, '_'); ix != -1 {
 | 
						if ix := strings.LastIndexByte(caseName, '_'); ix != -1 {
 | 
				
			||||||
		caseName = caseName[ix+1:]
 | 
							caseName = caseName[ix+1:]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	caseName = fromSnakeToCamel(caseName, true)
 | 
						caseName = fromSnakeToCamel(caseName)
 | 
				
			||||||
	dv, ok := lvTypedParams[dvalue]
 | 
						dv, ok := lvTypedParams[dvalue]
 | 
				
			||||||
	if ok {
 | 
						if ok {
 | 
				
			||||||
		dvalue = strconv.FormatUint(uint64(dv), 10)
 | 
							dvalue = strconv.FormatUint(uint64(dv), 10)
 | 
				
			||||||
@@ -587,11 +557,11 @@ func AddFixedArray(identifier, itype, len string) {
 | 
				
			|||||||
// Variable-length arrays are prefixed with a 32-bit unsigned length, and may
 | 
					// Variable-length arrays are prefixed with a 32-bit unsigned length, and may
 | 
				
			||||||
// also have a maximum length specified.
 | 
					// also have a maximum length specified.
 | 
				
			||||||
func AddVariableArray(identifier, itype, len string) {
 | 
					func AddVariableArray(identifier, itype, len string) {
 | 
				
			||||||
	// FIXME: This ignores the length restriction, so as of now we can't check
 | 
						// This code ignores the length restriction (array<MAXLEN>), so as of now we
 | 
				
			||||||
	// to make sure that we're not exceeding that restriction when we fill in
 | 
						// can't check to make sure that we're not exceeding that restriction when
 | 
				
			||||||
	// message buffers. That may not matter, if libvirt's checking is careful
 | 
						// we fill in message buffers. That may not matter, if libvirt's checking is
 | 
				
			||||||
	// enough. This could be handled with a map, however.
 | 
						// careful enough.
 | 
				
			||||||
	atype := fmt.Sprintf("[]%v", itype)
 | 
						atype := "[]" + itype
 | 
				
			||||||
	// Handle strings specially. In the rpcgen definition a string is specified
 | 
						// Handle strings specially. In the rpcgen definition a string is specified
 | 
				
			||||||
	// as a variable-length array, either with or without a max length. We want
 | 
						// as a variable-length array, either with or without a max length. We want
 | 
				
			||||||
	// these to be go strings, so we'll just remove the array specifier.
 | 
						// these to be go strings, so we'll just remove the array specifier.
 | 
				
			||||||
@@ -608,3 +578,13 @@ func checkIdentifier(i string) string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return i
 | 
						return i
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetUnion returns the type information for a union. If the provided type name
 | 
				
			||||||
 | 
					// isn't a union, the second return value will be false.
 | 
				
			||||||
 | 
					func (decl *Decl) GetUnion() Union {
 | 
				
			||||||
 | 
						ix, ok := Gen.UnionMap[decl.Type]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							return Gen.Unions[ix]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return Union{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,16 @@
 | 
				
			|||||||
package lvgen
 | 
					package lvgen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This file contains the instructions for regenerating the libvirt bindings.
 | 
				
			||||||
 | 
					// We do this by parsing the remote_protocol.x file included in the libvirt
 | 
				
			||||||
 | 
					// sources. Bindings will be generated if you run `go generate` in this
 | 
				
			||||||
 | 
					// directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Before running `go generate`:
 | 
				
			||||||
 | 
					// 1) Make sure goyacc is installed from golang.org/x/tools (you can use this
 | 
				
			||||||
 | 
					//    command: `go get golang.org/x/tools/...`)
 | 
				
			||||||
 | 
					// 2) Set the environment variable LIBVIRT_SOURCE to point to the top level
 | 
				
			||||||
 | 
					//    directory containing the version of libvirt for which you want to generate
 | 
				
			||||||
 | 
					//    bindings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//go:generate goyacc sunrpc.y
 | 
					//go:generate goyacc sunrpc.y
 | 
				
			||||||
//go:generate go run gen/main.go
 | 
					//go:generate go run gen/main.go
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,31 @@ const eof = -1
 | 
				
			|||||||
// runes.
 | 
					// runes.
 | 
				
			||||||
var oneRuneTokens = `{}[]<>(),=;:*`
 | 
					var oneRuneTokens = `{}[]<>(),=;:*`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var keywords = map[string]int{
 | 
				
			||||||
 | 
						"hyper":    HYPER,
 | 
				
			||||||
 | 
						"int":      INT,
 | 
				
			||||||
 | 
						"short":    SHORT,
 | 
				
			||||||
 | 
						"char":     CHAR,
 | 
				
			||||||
 | 
						"bool":     BOOL,
 | 
				
			||||||
 | 
						"case":     CASE,
 | 
				
			||||||
 | 
						"const":    CONST,
 | 
				
			||||||
 | 
						"default":  DEFAULT,
 | 
				
			||||||
 | 
						"double":   DOUBLE,
 | 
				
			||||||
 | 
						"enum":     ENUM,
 | 
				
			||||||
 | 
						"float":    FLOAT,
 | 
				
			||||||
 | 
						"opaque":   OPAQUE,
 | 
				
			||||||
 | 
						"string":   STRING,
 | 
				
			||||||
 | 
						"struct":   STRUCT,
 | 
				
			||||||
 | 
						"switch":   SWITCH,
 | 
				
			||||||
 | 
						"typedef":  TYPEDEF,
 | 
				
			||||||
 | 
						"union":    UNION,
 | 
				
			||||||
 | 
						"unsigned": UNSIGNED,
 | 
				
			||||||
 | 
						"void":     VOID,
 | 
				
			||||||
 | 
						"program":  PROGRAM,
 | 
				
			||||||
 | 
						"version":  VERSION,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// item is a lexeme, or what the lexer returns to the parser.
 | 
				
			||||||
type item struct {
 | 
					type item struct {
 | 
				
			||||||
	typ          int
 | 
						typ          int
 | 
				
			||||||
	val          string
 | 
						val          string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ package libvirt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/davecgh/go-xdr/xdr2"
 | 
						"github.com/davecgh/go-xdr/xdr2"
 | 
				
			||||||
	"github.com/digitalocean/go-libvirt/internal/constants"
 | 
						"github.com/digitalocean/go-libvirt/internal/constants"
 | 
				
			||||||
@@ -42,10 +43,64 @@ type {{$casetype}} struct {
 | 
				
			|||||||
	{{.Name}} {{.Type}}
 | 
						{{.Name}} {{.Type}}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func New{{$casetype}}(v {{.Type}}) *{{$casetype}} { return &{{$casetype}}{DVal: {{.DiscriminantVal}}, {{.Name}}: v} }
 | 
					func New{{$casetype}}(v {{.Type}}) *{{$casetype}} { return &{{$casetype}}{DVal: {{.DiscriminantVal}}, {{.Name}}: v} }
 | 
				
			||||||
 | 
					func Decode{{$casetype}}(dec *xdr.Decoder) (*{{$casetype}}, error) {
 | 
				
			||||||
 | 
						var v {{.Type}}
 | 
				
			||||||
 | 
						_, err := dec.Decode(&v)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return New{{$casetype}}(v), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
func (c *{{$casetype}}) Get() interface{} { return c.{{.Name}} }
 | 
					func (c *{{$casetype}}) Get() interface{} { return c.{{.Name}} }
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
{{- end}}
 | 
					{{- end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Generate this.
 | 
				
			||||||
 | 
					func decodeTypedParams(dec *xdr.Decoder) ([]TypedParam, error) {
 | 
				
			||||||
 | 
						count, _, err := dec.DecodeInt()
 | 
				
			||||||
 | 
						params := make([]TypedParam, count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for ix := int32(0); ix < count; ix++ {
 | 
				
			||||||
 | 
							name, _, err := dec.DecodeString()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ptype, _, err := dec.DecodeInt()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var tpv TypedParamValue
 | 
				
			||||||
 | 
							switch ptype {
 | 
				
			||||||
 | 
							case 1:	// TypedParamValueInt
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueInt(dec)
 | 
				
			||||||
 | 
							case 2: // TypedParamValueUint
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueUint(dec)
 | 
				
			||||||
 | 
							case 3: // TypedParamValueLlong
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueLlong(dec)
 | 
				
			||||||
 | 
							case 4: // TypedParamValueUllong
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueUllong(dec)
 | 
				
			||||||
 | 
							case 5: // TypedParamValueDouble
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueDouble(dec)
 | 
				
			||||||
 | 
							case 6: // TypedParamValueBoolean
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueBoolean(dec)
 | 
				
			||||||
 | 
							case 7: // TypedParamValueString
 | 
				
			||||||
 | 
								tpv, err = DecodeTypedParamValueString(dec)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								err = fmt.Errorf("invalid parameter type %v", ptype)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							params[ix] = TypedParam{name, tpv}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return params, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Procedures:
 | 
					// Procedures:
 | 
				
			||||||
{{range .Procs}}
 | 
					{{range .Procs}}
 | 
				
			||||||
func (l *Libvirt) {{.Name}}({{range $ix, $arg := .Args}}{{if $ix}}, {{end}}{{.Name}} {{.Type}}{{end}}) ({{range .Ret}}r{{.Name}} {{.Type}}, {{end}}err error) {
 | 
					func (l *Libvirt) {{.Name}}({{range $ix, $arg := .Args}}{{if $ix}}, {{end}}{{.Name}} {{.Type}}{{end}}) ({{range .Ret}}r{{.Name}} {{.Type}}, {{end}}err error) {
 | 
				
			||||||
@@ -72,16 +127,21 @@ func (l *Libvirt) {{.Name}}({{range $ix, $arg := .Args}}{{if $ix}}, {{end}}{{.Na
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
{{if .RetStruct}}
 | 
					{{if .RetStruct}}
 | 
				
			||||||
	result := {{.RetStruct}}{}
 | 
						// Return value unmarshaling
 | 
				
			||||||
	rdr := bytes.NewReader(r.Payload)
 | 
						rdr := bytes.NewReader(r.Payload)
 | 
				
			||||||
	dec := xdr.NewDecoder(rdr)
 | 
						dec := xdr.NewDecoder(rdr)
 | 
				
			||||||
	_, err = dec.Decode(&result)
 | 
					{{range .Ret}}	// {{.Name}}: {{.Type}}
 | 
				
			||||||
 | 
					{{if eq .Type "[]TypedParam"}}	// {{.Name}}
 | 
				
			||||||
 | 
						r{{.Name}}, err = decodeTypedParams(dec)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					{{else}}	_, err = dec.Decode(&r{{.Name}})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
{{range .Ret}}	r{{.Name}} = result.{{.Name}}
 | 
					 | 
				
			||||||
{{end}}{{end}}
 | 
					{{end}}{{end}}
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1982
									
								
								libvirt.gen.go
									
									
									
									
									
								
							
							
						
						
									
										1982
									
								
								libvirt.gen.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										164
									
								
								libvirt.go
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								libvirt.go
									
									
									
									
									
								
							@@ -1398,39 +1398,13 @@ func (l *Libvirt) SetBlockIOTune(dom string, disk string, limits ...BlockLimit)
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSetBlockIoTune
 | 
						params := make([]TypedParam, len(limits))
 | 
				
			||||||
	payload := struct {
 | 
						for ix, limit := range limits {
 | 
				
			||||||
		Domain Domain
 | 
					 | 
				
			||||||
		Disk   string
 | 
					 | 
				
			||||||
		Params []TypedParam
 | 
					 | 
				
			||||||
		Flags  DomainAffectFlags
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		Domain: d,
 | 
					 | 
				
			||||||
		Disk:   disk,
 | 
					 | 
				
			||||||
		Flags:  FlagDomainAffectLive,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, limit := range limits {
 | 
					 | 
				
			||||||
		tpval := NewTypedParamValueUllong(limit.Value)
 | 
							tpval := NewTypedParamValueUllong(limit.Value)
 | 
				
			||||||
		tp := &TypedParam{Field: limit.Name, Value: tpval}
 | 
							params[ix] = TypedParam{Field: limit.Name, Value: tpval}
 | 
				
			||||||
		payload.Params = append(payload.Params, *tp)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf, err := encode(&payload)
 | 
						return l.DomainSetBlockIOTune(*d, disk, params, FlagDomainAffectLive)
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resp, err := l.request(constants.ProcDomainSetBlockIOTune, constants.Program, &buf)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r := <-resp
 | 
					 | 
				
			||||||
	if r.Status != StatusOK {
 | 
					 | 
				
			||||||
		return decodeError(r.Payload)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetBlockIOTune returns a slice containing the current block I/O tunables for
 | 
					// GetBlockIOTune returns a slice containing the current block I/O tunables for
 | 
				
			||||||
@@ -1441,77 +1415,91 @@ func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error)
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	payload := struct {
 | 
						lims, _, err := l.DomainGetBlockIOTune(*d, disk, 32, FlagTypedParamStringOkay)
 | 
				
			||||||
		Domain     Domain
 | 
					 | 
				
			||||||
		Disk       []string
 | 
					 | 
				
			||||||
		ParamCount uint32
 | 
					 | 
				
			||||||
		Flags      DomainAffectFlags
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		Domain:     d,
 | 
					 | 
				
			||||||
		Disk:       []string{disk},
 | 
					 | 
				
			||||||
		ParamCount: 32,
 | 
					 | 
				
			||||||
		Flags:      FlagTypedParamStringOkay,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf, err := encode(&payload)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// payload := struct {
 | 
				
			||||||
	resp, err := l.request(constants.ProcDomainGetBlockIOTune, constants.Program, &buf)
 | 
						// 	Domain     Domain
 | 
				
			||||||
	if err != nil {
 | 
						// 	Disk       []string
 | 
				
			||||||
		return nil, err
 | 
						// 	ParamCount uint32
 | 
				
			||||||
	}
 | 
						// 	Flags      DomainAffectFlags
 | 
				
			||||||
 | 
						// }{
 | 
				
			||||||
	r := <-resp
 | 
						// 	Domain:     d,
 | 
				
			||||||
	if r.Status != StatusOK {
 | 
						// 	Disk:       []string{disk},
 | 
				
			||||||
		return nil, decodeError(r.Payload)
 | 
						// 	ParamCount: 32,
 | 
				
			||||||
	}
 | 
						// 	Flags:      FlagTypedParamStringOkay,
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// buf, err := encode(&payload)
 | 
				
			||||||
 | 
						// if err != nil {
 | 
				
			||||||
 | 
						// 	return nil, err
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// resp, err := l.request(constants.ProcDomainGetBlockIOTune, constants.Program, &buf)
 | 
				
			||||||
 | 
						// if err != nil {
 | 
				
			||||||
 | 
						// 	return nil, err
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// r := <-resp
 | 
				
			||||||
 | 
						// if r.Status != StatusOK {
 | 
				
			||||||
 | 
						// 	return nil, decodeError(r.Payload)
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var limits []BlockLimit
 | 
						var limits []BlockLimit
 | 
				
			||||||
	rdr := bytes.NewReader(r.Payload)
 | 
						// rdr := bytes.NewReader(r.Payload)
 | 
				
			||||||
	dec := xdr.NewDecoder(rdr)
 | 
						// dec := xdr.NewDecoder(rdr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// find out how many params were returned
 | 
						// find out how many params were returned
 | 
				
			||||||
	paramCount, _, err := dec.DecodeInt()
 | 
						// paramCount, _, err := dec.DecodeInt()
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		return nil, err
 | 
						// 	return nil, err
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// now decode each of the returned TypedParams. To do this we read the field
 | 
						// now decode each of the returned TypedParams. To do this we read the field
 | 
				
			||||||
	// name and type, then use the type information to decode the value.
 | 
						// name and type, then use the type information to decode the value.
 | 
				
			||||||
	for param := int32(0); param < paramCount; param++ {
 | 
						for _, lim := range lims {
 | 
				
			||||||
		// Get the field name
 | 
							var l BlockLimit
 | 
				
			||||||
		name, _, err := dec.DecodeString()
 | 
							name := lim.Field
 | 
				
			||||||
		if err != nil {
 | 
							switch lim.Value.Get().(type) {
 | 
				
			||||||
			return nil, err
 | 
							case uint64:
 | 
				
			||||||
 | 
								l = BlockLimit{Name: name, Value: lim.Value.Get().(uint64)}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// ...and the type
 | 
							limits = append(limits, l)
 | 
				
			||||||
		ptype, _, err := dec.DecodeInt()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Now we can read the actual value.
 | 
						// for param := int32(0); param < paramCount; param++ {
 | 
				
			||||||
		switch ptype {
 | 
						// 	// Get the field name
 | 
				
			||||||
		case TypeParamULLong:
 | 
						// 	name, _, err := dec.DecodeString()
 | 
				
			||||||
			var val uint64
 | 
						// 	if err != nil {
 | 
				
			||||||
			_, err = dec.Decode(&val)
 | 
						// 		return nil, err
 | 
				
			||||||
			if err != nil {
 | 
						// 	}
 | 
				
			||||||
				return nil, err
 | 
						// 	// ...and the type
 | 
				
			||||||
			}
 | 
						// 	ptype, _, err := dec.DecodeInt()
 | 
				
			||||||
			lim := BlockLimit{name, val}
 | 
						// 	if err != nil {
 | 
				
			||||||
			limits = append(limits, lim)
 | 
						// 		return nil, err
 | 
				
			||||||
		case TypeParamString:
 | 
						// 	}
 | 
				
			||||||
			var val string
 | 
						//
 | 
				
			||||||
			_, err = dec.Decode(&val)
 | 
						// 	// Now we can read the actual value.
 | 
				
			||||||
			if err != nil {
 | 
						// 	switch ptype {
 | 
				
			||||||
				return nil, err
 | 
						// 	case TypeParamULLong:
 | 
				
			||||||
			}
 | 
						// 		var val uint64
 | 
				
			||||||
			// This routine doesn't currently return strings. As of libvirt 3+,
 | 
						// 		_, err = dec.Decode(&val)
 | 
				
			||||||
			// there's one string here, `group_name`.
 | 
						// 		if err != nil {
 | 
				
			||||||
		}
 | 
						// 			return nil, err
 | 
				
			||||||
	}
 | 
						// 		}
 | 
				
			||||||
 | 
						// 		lim := BlockLimit{name, val}
 | 
				
			||||||
 | 
						// 		limits = append(limits, lim)
 | 
				
			||||||
 | 
						// 	case TypeParamString:
 | 
				
			||||||
 | 
						// 		var val string
 | 
				
			||||||
 | 
						// 		_, err = dec.Decode(&val)
 | 
				
			||||||
 | 
						// 		if err != nil {
 | 
				
			||||||
 | 
						// 			return nil, err
 | 
				
			||||||
 | 
						// 		}
 | 
				
			||||||
 | 
						// 		// This routine doesn't currently return strings. As of libvirt 3+,
 | 
				
			||||||
 | 
						// 		// there's one string here, `group_name`.
 | 
				
			||||||
 | 
						// 	}
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return limits, nil
 | 
						return limits, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user