linux/net/ceph/mon_client.c

// SPDX-License-Identifier: GPL-2.0
#include <linux/ceph/ceph_debug.h>

#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/sched.h>

#include <linux/ceph/ceph_features.h>
#include <linux/ceph/mon_client.h>
#include <linux/ceph/libceph.h>
#include <linux/ceph/debugfs.h>
#include <linux/ceph/decode.h>
#include <linux/ceph/auth.h>

/*
 * Interact with Ceph monitor cluster.  Handle requests for new map
 * versions, and periodically resend as needed.  Also implement
 * statfs() and umount().
 *
 * A small cluster of Ceph "monitors" are responsible for managing critical
 * cluster configuration and state information.  An odd number (e.g., 3, 5)
 * of cmon daemons use a modified version of the Paxos part-time parliament
 * algorithm to manage the MDS map (mds cluster membership), OSD map, and
 * list of clients who have mounted the file system.
 *
 * We maintain an open, active session with a monitor at all times in order to
 * receive timely MDSMap updates.  We periodically send a keepalive byte on the
 * TCP socket to ensure we detect a failure.  If the connection does break, we
 * randomly hunt for a new monitor.  Once the connection is reestablished, we
 * resend any outstanding requests.
 */

static const struct ceph_connection_operations mon_con_ops;

static int __validate_auth(struct ceph_mon_client *monc);

static int decode_mon_info(void **p, void *end, bool msgr2,
			   struct ceph_entity_addr *addr)
{}

/*
 * Decode a monmap blob (e.g., during mount).
 *
 * Assume MonMap v3 (i.e. encoding with MONNAMES and MONENC).
 */
static struct ceph_monmap *ceph_monmap_decode(void **p, void *end, bool msgr2)
{}

/*
 * return true if *addr is included in the monmap.
 */
int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
{}

/*
 * Send an auth request.
 */
static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len)
{}

/*
 * Close monitor session, if any.
 */
static void __close_session(struct ceph_mon_client *monc)
{}

/*
 * Pick a new monitor at random and set cur_mon.  If we are repicking
 * (i.e. cur_mon is already set), be sure to pick a different one.
 */
static void pick_new_mon(struct ceph_mon_client *monc)
{}

/*
 * Open a session with a new monitor.
 */
static void __open_session(struct ceph_mon_client *monc)
{}

static void reopen_session(struct ceph_mon_client *monc)
{}

void ceph_monc_reopen_session(struct ceph_mon_client *monc)
{}

static void un_backoff(struct ceph_mon_client *monc)
{}

/*
 * Reschedule delayed work timer.
 */
static void __schedule_delayed(struct ceph_mon_client *monc)
{}

const char *ceph_sub_str[] =;

/*
 * Send subscribe request for one or more maps, according to
 * monc->subs.
 */
static void __send_subscribe(struct ceph_mon_client *monc)
{}

static void handle_subscribe_ack(struct ceph_mon_client *monc,
				 struct ceph_msg *msg)
{}

/*
 * Register interest in a map
 *
 * @sub: one of CEPH_SUB_*
 * @epoch: X for "every map since X", or 0 for "just the latest"
 */
static bool __ceph_monc_want_map(struct ceph_mon_client *monc, int sub,
				 u32 epoch, bool continuous)
{}

bool ceph_monc_want_map(struct ceph_mon_client *monc, int sub, u32 epoch,
			bool continuous)
{}
EXPORT_SYMBOL();

/*
 * Keep track of which maps we have
 *
 * @sub: one of CEPH_SUB_*
 */
static void __ceph_monc_got_map(struct ceph_mon_client *monc, int sub,
				u32 epoch)
{}

void ceph_monc_got_map(struct ceph_mon_client *monc, int sub, u32 epoch)
{}
EXPORT_SYMBOL();

void ceph_monc_renew_subs(struct ceph_mon_client *monc)
{}
EXPORT_SYMBOL();

/*
 * Wait for an osdmap with a given epoch.
 *
 * @epoch: epoch to wait for
 * @timeout: in jiffies, 0 means "wait forever"
 */
int ceph_monc_wait_osdmap(struct ceph_mon_client *monc, u32 epoch,
			  unsigned long timeout)
{}
EXPORT_SYMBOL();

/*
 * Open a session with a random monitor.  Request monmap and osdmap,
 * which are waited upon in __ceph_open_session().
 */
int ceph_monc_open_session(struct ceph_mon_client *monc)
{}
EXPORT_SYMBOL();

static void ceph_monc_handle_map(struct ceph_mon_client *monc,
				 struct ceph_msg *msg)
{}

/*
 * generic requests (currently statfs, mon_get_version)
 */
DEFINE_RB_FUNCS()

static void release_generic_request(struct kref *kref)
{}

static void put_generic_request(struct ceph_mon_generic_request *req)
{}

static void get_generic_request(struct ceph_mon_generic_request *req)
{}

static struct ceph_mon_generic_request *
alloc_generic_request(struct ceph_mon_client *monc, gfp_t gfp)
{}

static void register_generic_request(struct ceph_mon_generic_request *req)
{}

static void send_generic_request(struct ceph_mon_client *monc,
				 struct ceph_mon_generic_request *req)
{}

static void __finish_generic_request(struct ceph_mon_generic_request *req)
{}

static void finish_generic_request(struct ceph_mon_generic_request *req)
{}

static void complete_generic_request(struct ceph_mon_generic_request *req)
{}

static void cancel_generic_request(struct ceph_mon_generic_request *req)
{}

static int wait_generic_request(struct ceph_mon_generic_request *req)
{}

static struct ceph_msg *get_generic_reply(struct ceph_connection *con,
					 struct ceph_msg_header *hdr,
					 int *skip)
{}

/*
 * statfs
 */
static void handle_statfs_reply(struct ceph_mon_client *monc,
				struct ceph_msg *msg)
{}

/*
 * Do a synchronous statfs().
 */
int ceph_monc_do_statfs(struct ceph_mon_client *monc, u64 data_pool,
			struct ceph_statfs *buf)
{}
EXPORT_SYMBOL();

static void handle_get_version_reply(struct ceph_mon_client *monc,
				     struct ceph_msg *msg)
{}

static struct ceph_mon_generic_request *
__ceph_monc_get_version(struct ceph_mon_client *monc, const char *what,
			ceph_monc_callback_t cb, u64 private_data)
{}

/*
 * Send MMonGetVersion and wait for the reply.
 *
 * @what: one of "mdsmap", "osdmap" or "monmap"
 */
int ceph_monc_get_version(struct ceph_mon_client *monc, const char *what,
			  u64 *newest)
{}
EXPORT_SYMBOL();

/*
 * Send MMonGetVersion,
 *
 * @what: one of "mdsmap", "osdmap" or "monmap"
 */
int ceph_monc_get_version_async(struct ceph_mon_client *monc, const char *what,
				ceph_monc_callback_t cb, u64 private_data)
{}
EXPORT_SYMBOL();

static void handle_command_ack(struct ceph_mon_client *monc,
			       struct ceph_msg *msg)
{}

static __printf(2, 0)
int do_mon_command_vargs(struct ceph_mon_client *monc, const char *fmt,
			 va_list ap)
{}

static __printf(2, 3)
int do_mon_command(struct ceph_mon_client *monc, const char *fmt, ...)
{}

int ceph_monc_blocklist_add(struct ceph_mon_client *monc,
			    struct ceph_entity_addr *client_addr)
{}
EXPORT_SYMBOL();

/*
 * Resend pending generic requests.
 */
static void __resend_generic_request(struct ceph_mon_client *monc)
{}

/*
 * Delayed work.  If we haven't mounted yet, retry.  Otherwise,
 * renew/retry subscription as needed (in case it is timing out, or we
 * got an ENOMEM).  And keep the monitor connection alive.
 */
static void delayed_work(struct work_struct *work)
{}

/*
 * On startup, we build a temporary monmap populated with the IPs
 * provided by mount(2).
 */
static int build_initial_monmap(struct ceph_mon_client *monc)
{}

int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
{}
EXPORT_SYMBOL();

void ceph_monc_stop(struct ceph_mon_client *monc)
{}
EXPORT_SYMBOL();

static void finish_hunting(struct ceph_mon_client *monc)
{}

static void finish_auth(struct ceph_mon_client *monc, int auth_err,
			bool was_authed)
{}

static void handle_auth_reply(struct ceph_mon_client *monc,
			      struct ceph_msg *msg)
{}

static int __validate_auth(struct ceph_mon_client *monc)
{}

int ceph_monc_validate_auth(struct ceph_mon_client *monc)
{}
EXPORT_SYMBOL();

static int mon_get_auth_request(struct ceph_connection *con,
				void *buf, int *buf_len,
				void **authorizer, int *authorizer_len)
{}

static int mon_handle_auth_reply_more(struct ceph_connection *con,
				      void *reply, int reply_len,
				      void *buf, int *buf_len,
				      void **authorizer, int *authorizer_len)
{}

static int mon_handle_auth_done(struct ceph_connection *con,
				u64 global_id, void *reply, int reply_len,
				u8 *session_key, int *session_key_len,
				u8 *con_secret, int *con_secret_len)
{}

static int mon_handle_auth_bad_method(struct ceph_connection *con,
				      int used_proto, int result,
				      const int *allowed_protos, int proto_cnt,
				      const int *allowed_modes, int mode_cnt)
{}

/*
 * handle incoming message
 */
static void mon_dispatch(struct ceph_connection *con, struct ceph_msg *msg)
{}

/*
 * Allocate memory for incoming message
 */
static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
				      struct ceph_msg_header *hdr,
				      int *skip)
{}

/*
 * If the monitor connection resets, pick a new monitor and resubmit
 * any pending requests.
 */
static void mon_fault(struct ceph_connection *con)
{}

/*
 * We can ignore refcounting on the connection struct, as all references
 * will come from the messenger workqueue, which is drained prior to
 * mon_client destruction.
 */
static struct ceph_connection *mon_get_con(struct ceph_connection *con)
{}

static void mon_put_con(struct ceph_connection *con)
{}

static const struct ceph_connection_operations mon_con_ops =;