From 9e06caed7f1bcf90adc6feba2214382b48f87002 Mon Sep 17 00:00:00 2001 From: Yue Zhu Date: Thu, 19 Sep 2019 17:06:41 -0400 Subject: [PATCH] Add ability for go-ceph to send a command to one of the PGs --- vendor/github.com/ceph/go-ceph/rados/conn.go | 58 +++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/vendor/github.com/ceph/go-ceph/rados/conn.go b/vendor/github.com/ceph/go-ceph/rados/conn.go index 3dfb30b..e0e955a 100644 --- a/vendor/github.com/ceph/go-ceph/rados/conn.go +++ b/vendor/github.com/ceph/go-ceph/rados/conn.go @@ -5,9 +5,11 @@ package rados // #include import "C" -import "unsafe" -import "bytes" -import "fmt" +import ( + "bytes" + "fmt" + "unsafe" +) // ClusterStat represents Ceph cluster statistics. type ClusterStat struct { @@ -326,3 +328,53 @@ func (c *Conn) monCommand(args, inputBuffer []byte) (buffer []byte, info string, return } + +// PGCommand sends a command to one of the PGs +func (c *Conn) PGCommand(pgid, args []byte) (buffer []byte, info string, err error) { + return c.pgCommand(pgid, args, nil) +} + +// PGCommand sends a command to one of the PGs, with an input buffer +func (c *Conn) PGCommandWithInputBuffer(pgid, args, inputBuffer []byte) (buffer []byte, info string, err error) { + return c.pgCommand(pgid, args, inputBuffer) +} + +func (c *Conn) pgCommand(pgid, args, inputBuffer []byte) (buffer []byte, info string, err error) { + name := C.CString(string(pgid)) + argv := C.CString(string(args)) + defer C.free(unsafe.Pointer(name)) + defer C.free(unsafe.Pointer(argv)) + + var ( + outs, outbuf *C.char + outslen, outbuflen C.size_t + ) + inbuf := C.CString(string(inputBuffer)) + inbufLen := len(inputBuffer) + defer C.free(unsafe.Pointer(inbuf)) + + ret := C.rados_pg_command(c.cluster, + name, + &argv, 1, + inbuf, // bulk input (e.g. crush map) + C.size_t(inbufLen), // length inbuf + &outbuf, // buffer + &outbuflen, // buffer length + &outs, // status string + &outslen) + + if outslen > 0 { + info = C.GoStringN(outs, C.int(outslen)) + C.free(unsafe.Pointer(outs)) + } + if outbuflen > 0 { + buffer = C.GoBytes(unsafe.Pointer(outbuf), C.int(outbuflen)) + C.free(unsafe.Pointer(outbuf)) + } + if ret != 0 { + err = RadosError(int(ret)) + return nil, info, err + } + + return +}