Spdk/module/bdev/longhorn/bdev_longhorn_rebuild_rpc.c
Keith Lucas 7cda68ff38 Cleanup log messages.
Signed-off-by: Keith Lucas <keith.lucas@suse.com>
2022-04-05 17:41:49 -04:00

443 lines
14 KiB
C

#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include "spdk/stdinc.h"
#include "spdk/rpc.h"
#include "spdk/util.h"
#include "spdk/uuid.h"
#include "spdk/string.h"
#include "spdk/log.h"
#include "spdk/jsonrpc.h"
#include "spdk/env.h"
#include "spdk/init.h"
#include "spdk/thread.h"
#include "bdev_longhorn_rebuild.h"
#include "bdev_longhorn_remote_sync.h"
#include "bdev_longhorn_sync_client.h"
#include "bdev_longhorn_lvol.h"
#include "spdk_internal/lvolstore.h"
#include "../lvol/vbdev_lvol.h"
struct rpc_lvol_list_children {
char *name;
};
static const struct spdk_json_object_decoder rpc_lvol_list_children_decoders[] = {
{"name", offsetof(struct rpc_lvol_list_children, name), spdk_json_decode_string, true},
};
struct longhorn_child_blob_context {
struct spdk_json_write_ctx *w;
struct spdk_jsonrpc_request *request;
};
static void longhorn_child_blob_info(struct longhorn_blob_info *info, void *cb_arg) {
struct longhorn_child_blob_context *ctx = cb_arg;
uint64_t i;
if (info) {
spdk_json_write_object_begin(ctx->w);
spdk_json_write_named_string(ctx->w, "name", info->name);
spdk_json_write_named_uint64(ctx->w, "num_clusters", info->num_clusters);
spdk_json_write_named_uint32(ctx->w, "allocated_clusters", info->allocated_clusters);
spdk_json_write_named_array_begin(ctx->w, "active_clusters");
for (i = 0; i < info->allocated_clusters; ++i) {
spdk_json_write_uint32(ctx->w, info->table[i]);
}
spdk_json_write_array_end(ctx->w);
spdk_json_write_object_end(ctx->w);
} else {
spdk_json_write_array_end(ctx->w);
spdk_json_write_object_end(ctx->w);
spdk_jsonrpc_end_result(ctx->request, ctx->w);
free(ctx);
}
}
static void
rpc_bdev_lvol_list_children(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_lvol_list_children req = {NULL};
struct spdk_json_write_ctx *w;
struct spdk_bdev *bdev = NULL;
struct spdk_lvol *lvol = NULL;
struct longhorn_child_blob_context *ctx = NULL;
if (spdk_json_decode_object(params, rpc_lvol_list_children_decoders,
SPDK_COUNTOF(rpc_lvol_list_children_decoders),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
if (!req.name) {
spdk_jsonrpc_send_error_response(request, -EINVAL,
"Name must be provided");
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_object_begin(w);
bdev = spdk_bdev_get_by_name(req.name);
if (bdev != NULL) {
lvol = vbdev_lvol_get_from_bdev(bdev);
if (lvol != NULL) {
spdk_json_write_named_string(w, "name", req.name);
spdk_json_write_named_uint64(w, "cluster_size", lvol->lvol_store->blobstore->cluster_sz);
spdk_json_write_named_uint32(w, "io_unit_size", lvol->lvol_store->blobstore->io_unit_size);
spdk_json_write_named_array_begin(w, "snapshots");
ctx = calloc(1, sizeof(*ctx));
ctx->w = w;
ctx->request = request;
longhorn_get_blob_info(lvol->lvol_store->blobstore, lvol->blob_id, longhorn_child_blob_info, ctx);
#if 0
while (parent_id != SPDK_BLOBID_INVALID) {
spdk_json_write_uint64(w, parent_id);
parent_id = spdk_blob_get_parent_snapshot(lvol->lvol_store->blobstore, parent_id);
}
#endif
//spdk_json_write_array_end(w);
}
}
#if 0
spdk_json_write_object_end(w);
spdk_jsonrpc_end_result(request, w);
#endif
}
SPDK_RPC_REGISTER("lvol_list_children", rpc_bdev_lvol_list_children, SPDK_RPC_RUNTIME)
struct rpc_lvol_list_children_remote {
char *address;
uint16_t *port;
char *name;
};
static const struct spdk_json_object_decoder rpc_lvol_list_children_remote_decoders[] = {
{"address", offsetof(struct rpc_lvol_list_children_remote, address), spdk_json_decode_string, true},
{"port", offsetof(struct rpc_lvol_list_children_remote, port), spdk_json_decode_uint16, true},
{"name", offsetof(struct rpc_lvol_list_children_remote, name), spdk_json_decode_string, true},
};
static void
rpc_bdev_lvol_list_children_remote(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_lvol_list_children_remote req = {NULL};
struct spdk_json_write_ctx *w;
if (spdk_json_decode_object(params, rpc_lvol_list_children_remote_decoders,
SPDK_COUNTOF(rpc_lvol_list_children_remote_decoders),
&req)) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
bdev_longhorn_get_children_remote(req.address, req.port, req.name);
}
struct rpc_lvol_rebuild_remote {
char *address;
uint16_t *port;
char *name;
char *remote_prefix;
char *lvs;
};
static const struct spdk_json_object_decoder rpc_lvol_rebuild_remote_decoders[] = {
{"address", offsetof(struct rpc_lvol_rebuild_remote, address), spdk_json_decode_string, true},
{"port", offsetof(struct rpc_lvol_rebuild_remote, port), spdk_json_decode_uint16, true},
{"name", offsetof(struct rpc_lvol_rebuild_remote, name), spdk_json_decode_string, true},
{"remote_prefix", offsetof(struct rpc_lvol_rebuild_remote, remote_prefix), spdk_json_decode_string, true},
{"lvs", offsetof(struct rpc_lvol_rebuild_remote, lvs), spdk_json_decode_string, true},
};
static void
rpc_bdev_lvol_rebuild_remote(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_lvol_rebuild_remote req = {NULL};
struct spdk_json_write_ctx *w;
struct spdk_lvol_store *lvs;
if (spdk_json_decode_object(params, rpc_lvol_rebuild_remote_decoders,
SPDK_COUNTOF(rpc_lvol_rebuild_remote_decoders),
&req)) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
lvs = longhorn_get_lvol_store_by_name(req.lvs);
bdev_longhorn_rebuild_remote(req.address, req.port, req.name, req.remote_prefix, lvs);
}
SPDK_RPC_REGISTER("lvol_rebuild_remote", rpc_bdev_lvol_rebuild_remote, SPDK_RPC_RUNTIME)
struct rpc_lvol_import {
char *name;
char *lvs;
char *file;
};
static const struct spdk_json_object_decoder rpc_lvol_import_decoders[] = {
{"name", offsetof(struct rpc_lvol_import, name), spdk_json_decode_string, true},
{"lvs", offsetof(struct rpc_lvol_import, lvs), spdk_json_decode_string, true},
{"file", offsetof(struct rpc_lvol_import, file), spdk_json_decode_string, true},
};
static void
rpc_bdev_lvol_import(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_lvol_import req = {NULL};
struct spdk_json_write_ctx *w;
if (spdk_json_decode_object(params, rpc_lvol_import_decoders,
SPDK_COUNTOF(rpc_lvol_import_decoders),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
//free_rpc_construct_malloc(&req);
return;
}
if (!req.name) {
spdk_jsonrpc_send_error_response(request, -EINVAL,
"Name must be provided");
}
if (!req.file) {
spdk_jsonrpc_send_error_response(request, -EINVAL,
"Name must be provided");
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_string(w, req.name);
spdk_json_write_string(w, req.file);
spdk_json_write_string(w, req.lvs);
spdk_jsonrpc_end_result(request, w);
bdev_longhorn_import(req.name, req.lvs, req.file);
}
SPDK_RPC_REGISTER("lvol_import", rpc_bdev_lvol_import, SPDK_RPC_RUNTIME)
struct rpc_tcp_json_server {
char *address;
uint16_t port;
};
static const struct spdk_json_object_decoder rpc_tcp_json_server_decoders[] = {
{"address", offsetof(struct rpc_tcp_json_server, address), spdk_json_decode_string, true},
{"port", offsetof(struct rpc_tcp_json_server, port), spdk_json_decode_uint16, true},
};
struct tcp_server_entry {
struct sockaddr_in addr;
struct spdk_jsonrpc_server *server;
struct spdk_poller *poller;
TAILQ_ENTRY(tcp_server_entry) entries;
};
static TAILQ_HEAD(, tcp_server_entry) tcp_servers = TAILQ_HEAD_INITIALIZER(tcp_servers);
static int
tcp_server_poll(void *arg)
{
struct tcp_server_entry *entry = arg;
spdk_jsonrpc_server_poll(entry->server);
return SPDK_POLLER_BUSY;
}
static void
rpc_create_tcp_json_server(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_tcp_json_server req = {NULL};
struct tcp_server_entry *entry;
if (spdk_json_decode_object(params, rpc_tcp_json_server_decoders,
SPDK_COUNTOF(rpc_tcp_json_server_decoders),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
printf("%s:%d\n", req.address, req.port);
entry = calloc(1, sizeof(struct tcp_server_entry));
inet_aton(req.address, &entry->addr.sin_addr);
entry->addr.sin_port = htons(req.port);
entry->addr.sin_family = AF_INET;
entry->server = spdk_jsonrpc_server_listen(AF_INET, 0, &entry->addr,
sizeof(struct sockaddr_in),
spdk_rpc_handler);
entry->poller = SPDK_POLLER_REGISTER(tcp_server_poll, entry, 4000);
TAILQ_INSERT_TAIL(&tcp_servers, entry, entries);
spdk_jsonrpc_send_bool_response(request, true);
}
SPDK_RPC_REGISTER("tcp_json_server", rpc_create_tcp_json_server, SPDK_RPC_RUNTIME)
struct rpc_link_lvols {
char *child;
char *parent;
};
static const struct spdk_json_object_decoder rpc_link_lvols_decoder[] = {
{"child", offsetof(struct rpc_link_lvols, child), spdk_json_decode_string, true},
{"parent", offsetof(struct rpc_link_lvols, parent), spdk_json_decode_string, true},
};
static void
rpc_lvol_link(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{
struct rpc_link_lvols req = {NULL};
if (spdk_json_decode_object(params, rpc_link_lvols_decoder,
SPDK_COUNTOF(rpc_link_lvols_decoder),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
printf("%s:%s\n", req.child, req.parent);
bdev_longhorn_link(req.child, req.parent);
}
SPDK_RPC_REGISTER("link_lvols", rpc_lvol_link, SPDK_RPC_RUNTIME)
struct rpc_tcp_sync_server {
char *address;
uint16_t port;
char *lvs;
};
static const struct spdk_json_object_decoder rpc_tcp_sync_server_decoders[] = {
{"address", offsetof(struct rpc_tcp_sync_server, address), spdk_json_decode_string, true},
{"port", offsetof(struct rpc_tcp_sync_server, port), spdk_json_decode_uint16, true},
{"lvs", offsetof(struct rpc_tcp_sync_server, lvs), spdk_json_decode_string, true},
};
static void
rpc_create_tcp_sync_server(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_tcp_sync_server req = {NULL};
struct spdk_lvol_store *lvs;
if (spdk_json_decode_object(params, rpc_tcp_sync_server_decoders,
SPDK_COUNTOF(rpc_tcp_sync_server_decoders),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
lvs = longhorn_get_lvol_store_by_name(req.lvs);
longhorn_remote_sync_server(req.address, req.port, lvs);
spdk_jsonrpc_send_bool_response(request, true);
}
SPDK_RPC_REGISTER("tcp_sync_server", rpc_create_tcp_sync_server, SPDK_RPC_RUNTIME)
struct rpc_sync_client {
char *address;
uint16_t port;
uint64_t blob_id;
char *lvs;
};
static const struct spdk_json_object_decoder rpc_sync_client_decoders[] = {
{"address", offsetof(struct rpc_sync_client, address), spdk_json_decode_string, true},
{"port", offsetof(struct rpc_sync_client, port), spdk_json_decode_uint16, true},
{"blob_id", offsetof(struct rpc_sync_client, blob_id), spdk_json_decode_uint64, true},
{"lvs", offsetof(struct rpc_sync_client, lvs), spdk_json_decode_string, true},
};
static void
rpc_create_sync_client(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_sync_client req = {NULL};
struct spdk_lvol_store *lvs;
if (spdk_json_decode_object(params, rpc_sync_client_decoders,
SPDK_COUNTOF(rpc_sync_client_decoders),
&req)) {
SPDK_DEBUGLOG(bdev_malloc, "spdk_json_decode_object failed\n");
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
return;
}
lvs = longhorn_get_lvol_store_by_name(req.lvs);
longhorn_sync_client(req.address, req.port, req.blob_id, lvs);
}
SPDK_RPC_REGISTER("sync_client", rpc_create_sync_client, SPDK_RPC_RUNTIME)