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

Commit 6305a3b4 authored by Douglas Fuller's avatar Douglas Fuller Committed by Ilya Dryomov
Browse files

libceph: support for blacklisting clients



Reuse ceph_mon_generic_request infrastructure for sending monitor
commands.  In particular, add support for 'blacklist add' to prevent
other, non-responsive clients from making further updates.

Signed-off-by: default avatarDouglas Fuller <dfuller@redhat.com>
[idryomov@gmail.com: refactor, misc fixes throughout]
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarMike Christie <mchristi@redhat.com>
Reviewed-by: default avatarAlex Elder <elder@linaro.org>
parent d4ed4a53
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -138,6 +138,9 @@ struct ceph_dir_layout {
#define CEPH_MSG_POOLOP_REPLY           48
#define CEPH_MSG_POOLOP                 49

/* mon commands */
#define CEPH_MSG_MON_COMMAND            50
#define CEPH_MSG_MON_COMMAND_ACK        51

/* osd */
#define CEPH_MSG_OSD_MAP                41
@@ -176,6 +179,14 @@ struct ceph_mon_statfs_reply {
	struct ceph_statfs st;
} __attribute__ ((packed));

struct ceph_mon_command {
	struct ceph_mon_request_header monhdr;
	struct ceph_fsid fsid;
	__le32 num_strs;         /* always 1 */
	__le32 str_len;
	char str[];
} __attribute__ ((packed));

struct ceph_osd_getmap {
	struct ceph_mon_request_header monhdr;
	struct ceph_fsid fsid;
+3 −0
Original line number Diff line number Diff line
@@ -141,6 +141,9 @@ int ceph_monc_get_version(struct ceph_mon_client *monc, const char *what,
int ceph_monc_get_version_async(struct ceph_mon_client *monc, const char *what,
				ceph_monc_callback_t cb, u64 private_data);

int ceph_monc_blacklist_add(struct ceph_mon_client *monc,
			    struct ceph_entity_addr *client_addr);

extern int ceph_monc_open_session(struct ceph_mon_client *monc);

extern int ceph_monc_validate_auth(struct ceph_mon_client *monc);
+82 −0
Original line number Diff line number Diff line
@@ -835,6 +835,83 @@ int ceph_monc_get_version_async(struct ceph_mon_client *monc, const char *what,
}
EXPORT_SYMBOL(ceph_monc_get_version_async);

static void handle_command_ack(struct ceph_mon_client *monc,
			       struct ceph_msg *msg)
{
	struct ceph_mon_generic_request *req;
	void *p = msg->front.iov_base;
	void *const end = p + msg->front_alloc_len;
	u64 tid = le64_to_cpu(msg->hdr.tid);

	dout("%s msg %p tid %llu\n", __func__, msg, tid);

	ceph_decode_need(&p, end, sizeof(struct ceph_mon_request_header) +
							    sizeof(u32), bad);
	p += sizeof(struct ceph_mon_request_header);

	mutex_lock(&monc->mutex);
	req = lookup_generic_request(&monc->generic_request_tree, tid);
	if (!req) {
		mutex_unlock(&monc->mutex);
		return;
	}

	req->result = ceph_decode_32(&p);
	__finish_generic_request(req);
	mutex_unlock(&monc->mutex);

	complete_generic_request(req);
	return;

bad:
	pr_err("corrupt mon_command ack, tid %llu\n", tid);
	ceph_msg_dump(msg);
}

int ceph_monc_blacklist_add(struct ceph_mon_client *monc,
			    struct ceph_entity_addr *client_addr)
{
	struct ceph_mon_generic_request *req;
	struct ceph_mon_command *h;
	int ret = -ENOMEM;
	int len;

	req = alloc_generic_request(monc, GFP_NOIO);
	if (!req)
		goto out;

	req->request = ceph_msg_new(CEPH_MSG_MON_COMMAND, 256, GFP_NOIO, true);
	if (!req->request)
		goto out;

	req->reply = ceph_msg_new(CEPH_MSG_MON_COMMAND_ACK, 512, GFP_NOIO,
				  true);
	if (!req->reply)
		goto out;

	mutex_lock(&monc->mutex);
	register_generic_request(req);
	h = req->request->front.iov_base;
	h->monhdr.have_version = 0;
	h->monhdr.session_mon = cpu_to_le16(-1);
	h->monhdr.session_mon_tid = 0;
	h->fsid = monc->monmap->fsid;
	h->num_strs = cpu_to_le32(1);
	len = sprintf(h->str, "{ \"prefix\": \"osd blacklist\", \
		                 \"blacklistop\": \"add\", \
				 \"addr\": \"%pISpc/%u\" }",
		      &client_addr->in_addr, le32_to_cpu(client_addr->nonce));
	h->str_len = cpu_to_le32(len);
	send_generic_request(monc, req);
	mutex_unlock(&monc->mutex);

	ret = wait_generic_request(req);
out:
	put_generic_request(req);
	return ret;
}
EXPORT_SYMBOL(ceph_monc_blacklist_add);

/*
 * Resend pending generic requests.
 */
@@ -1139,6 +1216,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
		handle_get_version_reply(monc, msg);
		break;

	case CEPH_MSG_MON_COMMAND_ACK:
		handle_command_ack(monc, msg);
		break;

	case CEPH_MSG_MON_MAP:
		ceph_monc_handle_map(monc, msg);
		break;
@@ -1178,6 +1259,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
		m = ceph_msg_get(monc->m_subscribe_ack);
		break;
	case CEPH_MSG_STATFS_REPLY:
	case CEPH_MSG_MON_COMMAND_ACK:
		return get_generic_reply(con, hdr, skip);
	case CEPH_MSG_AUTH_REPLY:
		m = ceph_msg_get(monc->m_auth_reply);