Whamcloud - gitweb
LU-473 llite: improve error for 2.x cli + 1.8 srv
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 29 Jun 2011 20:36:25 +0000 (14:36 -0600)
committerOleg Drokin <green@whamcloud.com>
Fri, 19 Aug 2011 16:58:38 +0000 (12:58 -0400)
Improve the error message printed to the console when a 2.x client
is trying to mount a 1.8 filesystem.  More specifically, have the 2.x
client check whether the MDS supports the OBD_CONNECT_FID and
OBD_CONNECT_FULL20 flags, without which the client will not be able
to cope.  The 2.x client also does not understand the RPC structure
of 1.8 servers (mdt_body, mdt_rec, etc), but this is harder to check.

For a 2.x server, the client will configure an LMV device, so
exp_connect_flags will be zero, but in that case we also know the
server is running 2.x.

Change-Id: I935571aa0623f9311ddf0545904230721d2fad32
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/1036
Tested-by: Hudson
Reviewed-by: Yu Jian <yujian@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre/lustre_idl.h
lustre/include/obd_class.h
lustre/llite/llite_lib.c
lustre/obdclass/lprocfs_status.c
lustre/ptlrpc/import.c

index d04bba4..fcba9a1 100644 (file)
@@ -1113,7 +1113,7 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
 
 #define MDT_CONNECT_SUPPORTED  (OBD_CONNECT_RDONLY | OBD_CONNECT_VERSION | \
                                 OBD_CONNECT_ACL | OBD_CONNECT_XATTR | \
 
 #define MDT_CONNECT_SUPPORTED  (OBD_CONNECT_RDONLY | OBD_CONNECT_VERSION | \
                                 OBD_CONNECT_ACL | OBD_CONNECT_XATTR | \
-                                OBD_CONNECT_IBITS | OBD_CONNECT_JOIN | \
+                                OBD_CONNECT_IBITS | \
                                 OBD_CONNECT_NODEVOH | OBD_CONNECT_ATTRFID | \
                                 OBD_CONNECT_CANCELSET | OBD_CONNECT_AT | \
                                 OBD_CONNECT_RMT_CLIENT | \
                                 OBD_CONNECT_NODEVOH | OBD_CONNECT_ATTRFID | \
                                 OBD_CONNECT_CANCELSET | OBD_CONNECT_AT | \
                                 OBD_CONNECT_RMT_CLIENT | \
@@ -1140,6 +1140,10 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
 #define MGS_CONNECT_SUPPORTED  (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
                                 OBD_CONNECT_FULL20)
 
 #define MGS_CONNECT_SUPPORTED  (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
                                 OBD_CONNECT_FULL20)
 
+/* Features required for this version of the client to work with server */
+#define CLIENT_CONNECT_MDT_REQD (OBD_CONNECT_IBITS | OBD_CONNECT_FID | \
+                                 OBD_CONNECT_FULL20)
+
 #define OBD_OCD_VERSION(major,minor,patch,fix) (((major)<<24) + ((minor)<<16) +\
                                                 ((patch)<<8) + (fix))
 #define OBD_OCD_VERSION_MAJOR(version) ((int)((version)>>24)&255)
 #define OBD_OCD_VERSION(major,minor,patch,fix) (((major)<<24) + ((minor)<<16) +\
                                                 ((patch)<<8) + (fix))
 #define OBD_OCD_VERSION_MAJOR(version) ((int)((version)>>24)&255)
index db4cc06..198b10a 100644 (file)
@@ -100,6 +100,7 @@ char *obd_export_nid2str(struct obd_export *exp);
 
 int obd_export_evict_by_nid(struct obd_device *obd, const char *nid);
 int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid);
 
 int obd_export_evict_by_nid(struct obd_device *obd, const char *nid);
 int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid);
+int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep);
 
 int obd_zombie_impexp_init(void);
 void obd_zombie_impexp_stop(void);
 
 int obd_zombie_impexp_init(void);
 void obd_zombie_impexp_stop(void);
@@ -945,11 +946,11 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp)
 static inline int obd_connect(const struct lu_env *env,
                               struct obd_export **exp,struct obd_device *obd,
                               struct obd_uuid *cluuid,
 static inline int obd_connect(const struct lu_env *env,
                               struct obd_export **exp,struct obd_device *obd,
                               struct obd_uuid *cluuid,
-                              struct obd_connect_data *d,
+                              struct obd_connect_data *data,
                               void *localdata)
 {
         int rc;
                               void *localdata)
 {
         int rc;
-        __u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition
+        __u64 ocf = data ? data->ocd_connect_flags : 0; /* for post-condition
                                                    * check */
         ENTRY;
 
                                                    * check */
         ENTRY;
 
@@ -957,10 +958,10 @@ static inline int obd_connect(const struct lu_env *env,
         OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(obd, connect);
 
         OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP);
         OBD_COUNTER_INCREMENT(obd, connect);
 
-        rc = OBP(obd, connect)(env, exp, obd, cluuid, d, localdata);
+        rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata);
         /* check that only subset is granted */
         /* check that only subset is granted */
-        LASSERT(ergo(d != NULL,
-                     (d->ocd_connect_flags & ocf) == d->ocd_connect_flags));
+        LASSERT(ergo(data != NULL, (data->ocd_connect_flags & ocf) ==
+                                    data->ocd_connect_flags));
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
index abff420..a0b5027 100644 (file)
@@ -207,10 +207,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
 
         /* indicate the features supported by this client */
         data->ocd_connect_flags = OBD_CONNECT_IBITS    | OBD_CONNECT_NODEVOH  |
 
         /* indicate the features supported by this client */
         data->ocd_connect_flags = OBD_CONNECT_IBITS    | OBD_CONNECT_NODEVOH  |
-                                  OBD_CONNECT_JOIN     | OBD_CONNECT_ATTRFID  |
+                                  OBD_CONNECT_ATTRFID  |
                                   OBD_CONNECT_VERSION  | OBD_CONNECT_BRW_SIZE |
                                   OBD_CONNECT_MDS_CAPA | OBD_CONNECT_OSS_CAPA |
                                   OBD_CONNECT_VERSION  | OBD_CONNECT_BRW_SIZE |
                                   OBD_CONNECT_MDS_CAPA | OBD_CONNECT_OSS_CAPA |
-                                  OBD_CONNECT_CANCELSET| OBD_CONNECT_FID      |
+                                  OBD_CONNECT_CANCELSET | OBD_CONNECT_FID     |
                                   OBD_CONNECT_AT       | OBD_CONNECT_LOV_V3   |
                                   OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR    |
                                   OBD_CONNECT_FULL20   | OBD_CONNECT_64BITHASH;
                                   OBD_CONNECT_AT       | OBD_CONNECT_LOV_V3   |
                                   OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR    |
                                   OBD_CONNECT_FULL20   | OBD_CONNECT_64BITHASH;
@@ -279,6 +279,30 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
         if (err)
                 GOTO(out_md_fid, err);
 
         if (err)
                 GOTO(out_md_fid, err);
 
+        /* This needs to be after statfs to ensure connect has finished.
+         * Note that "data" does NOT contain the valid connect reply.
+         * If connecting to a 1.8 server there will be no LMV device, so
+         * we can access the MDC export directly and exp_connect_flags will
+         * be non-zero, but if accessing an upgraded 2.1 server it will
+         * have the correct flags filled in.
+         * XXX: fill in the LMV exp_connect_flags from MDC(s). */
+        valid = sbi->ll_md_exp->exp_connect_flags & CLIENT_CONNECT_MDT_REQD;
+        if (sbi->ll_md_exp->exp_connect_flags != 0 &&
+            valid != CLIENT_CONNECT_MDT_REQD) {
+                char *buf;
+
+                OBD_ALLOC_WAIT(buf, CFS_PAGE_SIZE);
+                obd_connect_flags2str(buf, CFS_PAGE_SIZE,
+                                      valid ^ CLIENT_CONNECT_MDT_REQD, ",");
+                LCONSOLE_ERROR_MSG(0x170, "Server %s does not support "
+                                   "feature(s) needed for correct operation "
+                                   "of this client (%s). Please upgrade "
+                                   "server or downgrade client.\n",
+                                   sbi->ll_md_exp->exp_obd->obd_name, buf);
+                OBD_FREE(buf, CFS_PAGE_SIZE);
+                GOTO(out_md, err = -EPROTO);
+        }
+
         size = sizeof(*data);
         err = obd_get_info(sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
                            KEY_CONN_DATA,  &size, data, NULL);
         size = sizeof(*data);
         err = obd_get_info(sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
                            KEY_CONN_DATA,  &size, data, NULL);
index 4758cc5..eed7097 100644 (file)
@@ -813,7 +813,7 @@ static const char *obd_connect_names[] = {
         NULL
 };
 
         NULL
 };
 
-static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
+int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
 {
         __u64 mask = 1;
         int i, ret = 0;
 {
         __u64 mask = 1;
         int i, ret = 0;
@@ -829,6 +829,7 @@ static int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
                                 ret ? sep : "", flags & ~(mask - 1));
         return ret;
 }
                                 ret ? sep : "", flags & ~(mask - 1));
         return ret;
 }
+EXPORT_SYMBOL(obd_connect_flags2str);
 
 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
                       int *eof, void *data)
 
 int lprocfs_rd_import(char *page, char **start, off_t off, int count,
                       int *eof, void *data)
index 0934764..6188cc4 100644 (file)
@@ -987,13 +987,14 @@ finish:
                         /* Sigh, some compilers do not like #ifdef in the middle
                            of macro arguments */
 #ifdef __KERNEL__
                         /* Sigh, some compilers do not like #ifdef in the middle
                            of macro arguments */
 #ifdef __KERNEL__
-                        const char *older =
-                                "older. Consider upgrading this client";
+                        const char *older = "older. Consider upgrading server "
+                                            "or downgrading client";
 #else
 #else
-                        const char *older =
-                                "older. Consider recompiling this application";
+                        const char *older = "older. Consider recompiling this "
+                                            "application";
 #endif
 #endif
-                        const char *newer = "newer than client version";
+                        const char *newer = "newer than client version. "
+                                            "Consider upgrading client";
 
                         LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) "
                                       "is much %s (%s)\n",
 
                         LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) "
                                       "is much %s (%s)\n",