Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbd0c8bf authored by John Spray's avatar John Spray Committed by Sage Weil
Browse files

ceph: send client metadata to MDS



Implement version 2 of CEPH_MSG_CLIENT_SESSION syntax,
which includes additional client metadata to allow
the MDS to report on clients by user-sensible names
like hostname.

Signed-off-by: default avatarJohn Spray <john.spray@redhat.com>
Reviewed-by: default avatarYan, Zheng <zyan@redhat.com>
parent a4483e8a
Loading
Loading
Loading
Loading
+70 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/utsname.h>

#include "super.h"
#include "mds_client.h"
@@ -812,6 +813,74 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
	h = msg->front.iov_base;
	h->op = cpu_to_le32(op);
	h->seq = cpu_to_le64(seq);

	return msg;
}

/*
 * session message, specialization for CEPH_SESSION_REQUEST_OPEN
 * to include additional client metadata fields.
 */
static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u64 seq)
{
	struct ceph_msg *msg;
	struct ceph_mds_session_head *h;
	int i = -1;
	int metadata_bytes = 0;
	int metadata_key_count = 0;
	struct ceph_options *opt = mdsc->fsc->client->options;
	void *p;

	const char* metadata[3][2] = {
		{"hostname", utsname()->nodename},
		{"entity_id", opt->name ? opt->name : ""},
		{NULL, NULL}
	};

	/* Calculate serialized length of metadata */
	metadata_bytes = 4;  /* map length */
	for (i = 0; metadata[i][0] != NULL; ++i) {
		metadata_bytes += 8 + strlen(metadata[i][0]) +
			strlen(metadata[i][1]);
		metadata_key_count++;
	}

	/* Allocate the message */
	msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + metadata_bytes,
			   GFP_NOFS, false);
	if (!msg) {
		pr_err("create_session_msg ENOMEM creating msg\n");
		return NULL;
	}
	h = msg->front.iov_base;
	h->op = cpu_to_le32(CEPH_SESSION_REQUEST_OPEN);
	h->seq = cpu_to_le64(seq);

	/*
	 * Serialize client metadata into waiting buffer space, using
	 * the format that userspace expects for map<string, string>
	 */
	msg->hdr.version = 2;  /* ClientSession messages with metadata are v2 */

	/* The write pointer, following the session_head structure */
	p = msg->front.iov_base + sizeof(*h);

	/* Number of entries in the map */
	ceph_encode_32(&p, metadata_key_count);

	/* Two length-prefixed strings for each entry in the map */
	for (i = 0; metadata[i][0] != NULL; ++i) {
		size_t const key_len = strlen(metadata[i][0]);
		size_t const val_len = strlen(metadata[i][1]);

		ceph_encode_32(&p, key_len);
		memcpy(p, metadata[i][0], key_len);
		p += key_len;
		ceph_encode_32(&p, val_len);
		memcpy(p, metadata[i][1], val_len);
		p += val_len;
	}

	return msg;
}

@@ -835,7 +904,7 @@ static int __open_session(struct ceph_mds_client *mdsc,
	session->s_renew_requested = jiffies;

	/* send connect message */
	msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq);
	msg = create_session_open_msg(mdsc, session->s_seq);
	if (!msg)
		return -ENOMEM;
	ceph_con_send(&session->s_con, msg);