mirror of
https://git.proxmox.com/git/librados2-perl
synced 2025-10-04 09:47:09 +00:00

By passing back all return values from the Ceph API (RADOS.xs) to Perl we are more flexible to make more than just the data available further up the stack. These values are: * return code * status message (can contain useful information) * data The Ceph API interaction happens in a child process. We need to en- and decode the returned hash in JSON to pass it between the child and parent process. RADOS.pm::mon_command now returns not just the data, but all information as a hash ref. Therefore dependent packages (pve-manager, pve-storage) need to adapt. Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
177 lines
3.3 KiB
Plaintext
177 lines
3.3 KiB
Plaintext
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
|
|
#include "ppport.h"
|
|
|
|
#include <rados/librados.h>
|
|
|
|
#define DEBUG_RADOS 0
|
|
|
|
#define DPRINTF(fmt, ...)\
|
|
do { if (DEBUG_RADOS) { printf("debug: " fmt, ## __VA_ARGS__); } } while (0)
|
|
|
|
MODULE = PVE::RADOS PACKAGE = PVE::RADOS
|
|
|
|
rados_t
|
|
pve_rados_create(user)
|
|
SV *user
|
|
PROTOTYPE: $
|
|
CODE:
|
|
{
|
|
char *u = NULL;
|
|
rados_t clu = NULL;
|
|
|
|
if (SvOK(user)) {
|
|
u = SvPV_nolen(user);
|
|
}
|
|
|
|
int ret = rados_create(&clu, u);
|
|
|
|
if (ret == 0)
|
|
RETVAL = clu;
|
|
else {
|
|
die("rados_create failed - %s\n", strerror(-ret));
|
|
RETVAL = NULL;
|
|
}
|
|
}
|
|
OUTPUT: RETVAL
|
|
|
|
void
|
|
pve_rados_conf_set(cluster, key, value)
|
|
rados_t cluster
|
|
char *key
|
|
char *value
|
|
PROTOTYPE: $$$
|
|
CODE:
|
|
{
|
|
DPRINTF("pve_rados_conf_set %s = %s\n", key, value);
|
|
|
|
int res = rados_conf_set(cluster, key, value);
|
|
if (res < 0) {
|
|
die("rados_conf_set failed - %s\n", strerror(-res));
|
|
}
|
|
}
|
|
|
|
void
|
|
pve_rados_conf_read_file(cluster, path)
|
|
rados_t cluster
|
|
SV *path
|
|
PROTOTYPE: $$
|
|
CODE:
|
|
{
|
|
char *p = NULL;
|
|
|
|
if (SvOK(path)) {
|
|
p = SvPV_nolen(path);
|
|
}
|
|
|
|
DPRINTF("pve_rados_conf_read_file %s\n", p);
|
|
|
|
int res = rados_conf_read_file(cluster, p);
|
|
if (res < 0) {
|
|
die("rados_conf_read_file failed - %s\n", strerror(-res));
|
|
}
|
|
}
|
|
|
|
void
|
|
pve_rados_connect(cluster)
|
|
rados_t cluster
|
|
PROTOTYPE: $
|
|
CODE:
|
|
{
|
|
DPRINTF("pve_rados_connect\n");
|
|
|
|
int res = rados_connect(cluster);
|
|
if (res < 0) {
|
|
die("rados_connect failed - %s\n", strerror(-res));
|
|
}
|
|
}
|
|
|
|
void
|
|
pve_rados_shutdown(cluster)
|
|
rados_t cluster
|
|
PROTOTYPE: $
|
|
CODE:
|
|
{
|
|
DPRINTF("pve_rados_shutdown");
|
|
rados_shutdown(cluster);
|
|
}
|
|
|
|
HV *
|
|
pve_rados_mon_command(cluster, cmds)
|
|
rados_t cluster
|
|
AV *cmds
|
|
PROTOTYPE: $$
|
|
CODE:
|
|
{
|
|
const char *cmd[64];
|
|
size_t cmdlen = 0;
|
|
|
|
char *outbuf =NULL;
|
|
size_t outbuflen = 0;
|
|
char *outs = NULL;
|
|
size_t outslen = 0;
|
|
|
|
SV *arg;
|
|
|
|
while ((arg = av_pop(cmds)) && (arg != &PL_sv_undef)) {
|
|
if (cmdlen >= 63) {
|
|
die("too many arguments");
|
|
}
|
|
cmd[cmdlen] = SvPV_nolen(arg);
|
|
DPRINTF("pve_rados_mon_command%zd %s\n", cmdlen, cmd[cmdlen]);
|
|
cmdlen++;
|
|
}
|
|
|
|
int ret = rados_mon_command(
|
|
cluster,
|
|
cmd,
|
|
cmdlen,
|
|
NULL,
|
|
0,
|
|
&outbuf,
|
|
&outbuflen,
|
|
&outs,
|
|
&outslen
|
|
);
|
|
|
|
HV * rh = (HV *)sv_2mortal((SV *)newHV());
|
|
|
|
(void)hv_store(rh, "return_code", 11, newSViv(ret), 0);
|
|
(void)hv_store(rh, "status_message", 14, newSVpv(outs, outslen), 0);
|
|
(void)hv_store(rh, "data", 4, newSVpv(outbuf, outbuflen), 0);
|
|
RETVAL = rh;
|
|
|
|
rados_buffer_free(outbuf);
|
|
rados_buffer_free(outs);
|
|
}
|
|
OUTPUT: RETVAL
|
|
|
|
HV *
|
|
pve_rados_cluster_stat(cluster)
|
|
rados_t cluster
|
|
PROTOTYPE: $
|
|
CODE:
|
|
{
|
|
struct rados_cluster_stat_t result;
|
|
|
|
DPRINTF("pve_rados_cluster_stat");
|
|
|
|
int ret = rados_cluster_stat(cluster, &result);
|
|
|
|
if(ret != 0) {
|
|
warn("rados_cluster_stat failed (ret=%d)\n", ret);
|
|
XSRETURN_UNDEF;
|
|
}
|
|
HV * rh = (HV *)sv_2mortal((SV *)newHV());
|
|
|
|
(void)hv_store(rh, "kb", 2, newSViv(result.kb), 0);
|
|
(void)hv_store(rh, "kb_used", 7, newSViv(result.kb_used), 0);
|
|
(void)hv_store(rh, "kb_avail", 8, newSViv(result.kb_avail), 0);
|
|
(void)hv_store(rh, "num_objects", 11, newSViv(result.num_objects), 0);
|
|
|
|
RETVAL = rh;
|
|
}
|
|
OUTPUT: RETVAL
|