From 6e28d3406df06435bea26b465baf97c259942920 Mon Sep 17 00:00:00 2001 From: Venky Shankar Date: Tue, 29 Mar 2022 09:18:06 -0400 Subject: [PATCH] mount.ceph: remove `ms_mode' mount option when switching to old-syntax ... and switch to using v1 addresses (if users haven't specified those explicitly). kernel versions <5.11 do not understand `ms_mode' mount option which would result in mount failure. Fixes: http://tracker.ceph.com/issues/55110 Signed-off-by: Venky Shankar --- src/mount/mount.ceph.c | 65 ++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/src/mount/mount.ceph.c b/src/mount/mount.ceph.c index 5a63111a6bade..1aeac83dcc345 100644 --- a/src/mount/mount.ceph.c +++ b/src/mount/mount.ceph.c @@ -21,7 +21,7 @@ bool verboseflag = false; bool fakeflag = false; bool skip_mtab_flag = false; -bool v2_addrs = false; +bool v2_addrs = true; bool no_fallback = false; bool ms_mode_specified = false; bool mon_addr_specified = false; @@ -203,6 +203,10 @@ static int parse_old_dev(const char *dev_str, struct ceph_mount_info *cmi, cmi->cmi_mons = strndup(dev_str, len); if (!cmi->cmi_mons) return -ENOMEM; + mon_addr_specified = true; + } else { + /* reset mon_addr=<> mount option */ + mon_addr_specified = false; } mount_path++; @@ -298,11 +302,9 @@ static int parse_new_dev(const char *dev_str, struct ceph_mount_info *cmi, } /* new-style dev - force using v2 addrs first */ - if (!ms_mode_specified && !mon_addr_specified) { - v2_addrs = true; - append_opt("ms_mode", CEPH_DEFAULT_V2_MS_MODE, cmi, - opt_pos); - } + if (!ms_mode_specified && !mon_addr_specified) + append_opt("ms_mode", CEPH_DEFAULT_V2_MS_MODE, cmi, + opt_pos); cmi->format = MOUNT_DEV_FORMAT_NEW; return 0; @@ -323,8 +325,12 @@ static int parse_dev(const char *dev_str, struct ceph_mount_info *cmi, return ret; } -/* resolve monitor host and record in option string */ -static int finalize_src(struct ceph_mount_info *cmi, int *opt_pos) +/* resolve monitor host and optionally record in option string. + * use opt_pos to determine if the caller wants to record the + * resolved address in mount option (c.f., mount_old_device_format). + */ +static int finalize_src(struct ceph_mount_info *cmi, int *opt_pos, + char **resolved_addr) { char *src; size_t len = strlen(cmi->cmi_mons); @@ -337,8 +343,13 @@ static int finalize_src(struct ceph_mount_info *cmi, int *opt_pos) if (!src) return -1; - resolved_mon_addr_as_mount_opt(src); - append_opt("mon_addr", src, cmi, opt_pos); + mount_ceph_debug("mount.ceph: resolved to: \"%s\"\n", src); + if (opt_pos) { + resolved_mon_addr_as_mount_opt(src); + append_opt("mon_addr", src, cmi, opt_pos); + } else if (resolved_addr) { + *resolved_addr = strdup(src); + } free(src); return 0; } @@ -765,7 +776,7 @@ static int mount_old_device_format(const char *node, struct ceph_mount_info *cmi int r; int len = 0; int pos = 0; - char *mon_addr; + char *mon_addr = NULL; char *rsrc = NULL; r = remove_opt(cmi, "mon_addr", &mon_addr); @@ -774,6 +785,30 @@ static int mount_old_device_format(const char *node, struct ceph_mount_info *cmi return -EINVAL; } + /* if we reach here and still have a v2 addr, we'd need to + * refresh with v1 addrs, since we'll be not passing ms_mode + * with the old syntax. + */ + if (v2_addrs && !ms_mode_specified && !mon_addr_specified) { + mount_ceph_debug("mount.ceph: switching to using v1 address with old syntax\n"); + v2_addrs = false; + free(mon_addr); + free(cmi->cmi_mons); + mon_addr = NULL; + cmi->cmi_mons = NULL; + fetch_config_info(cmi); + if (!cmi->cmi_mons) { + fprintf(stderr, "unable to determine (v1) mon addresses\n"); + return -EINVAL; + } + r = finalize_src(cmi, NULL, &mon_addr); + if (r) { + fprintf(stderr, "failed to resolve (v1) mon addresses\n"); + return -EINVAL; + } + remove_opt(cmi, "ms_mode", NULL); + } + pos = strlen(cmi->cmi_opts); if (cmi->cmi_fsname) append_opt("mds_namespace", cmi->cmi_fsname, cmi, &pos); @@ -836,10 +871,10 @@ static int do_mount(const char *dev, const char *node, bool fallback = true; /* no v2 addresses available via config - try v1 addresses */ - if (!cmi->cmi_mons && + if (v2_addrs && + !cmi->cmi_mons && !ms_mode_specified && - !mon_addr_specified && - cmi->format == MOUNT_DEV_FORMAT_NEW) { + !mon_addr_specified) { mount_ceph_debug("mount.ceph: switching to using v1 address\n"); v2_addrs = false; fetch_config_info(cmi); @@ -852,7 +887,7 @@ static int do_mount(const char *dev, const char *node, } pos = strlen(cmi->cmi_opts); - retval = finalize_src(cmi, &pos); + retval = finalize_src(cmi, &pos, NULL); if (retval) { fprintf(stderr, "failed to resolve source\n"); return -EINVAL; -- 2.39.5