Whamcloud - gitweb
LU-7845 obd: add 'network' client mount option 92/19792/24
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 26 Apr 2016 09:01:00 +0000 (11:01 +0200)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 17 Dec 2016 05:40:14 +0000 (05:40 +0000)
Add a 'network' mount option on client side. All connections made by
the client must be on the LNet network specified in the 'network'
option.

This option can be useful in case of several Lustre client mount
points on the same node, with each mount point using a different
network. It is also interesting when running Lustre clients from
containers, by restricting each container to a specific network.

This new option is added by tampering with two config commands:
- setup: add a fourth parameter, which is the net to restrict
  connections to. This parameter will be passed down to
  ptlrpc_uuid_to_peer() so that client only connects to peers on the
  restricted network.
- add_conn: skip this command if uuid to connect to is not on
  restricted network.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Ica7ab6ebe7c2c9e7b0409b615e90d9271c31e92f
Reviewed-on: https://review.whamcloud.com/19792
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Doug Oucharek <doug.s.oucharek@intel.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/doc/mount.lustre.8
lustre/include/lustre_disk.h
lustre/include/lustre_net.h
lustre/ldlm/ldlm_lib.c
lustre/obdclass/obd_config.c
lustre/obdclass/obd_mount.c
lustre/ptlrpc/client.c
lustre/ptlrpc/events.c

index a31adcc..5c309e8 100644 (file)
@@ -112,6 +112,14 @@ Keys are inserted into the KEY_SPEC_SESSION_KEYRING keyring with a description
 containing "lustre:" and a suffix which depends on whether the context of the
 mount command is for an MGS, MDT/OST, or client.
 This option is only available when built with --enable-gss.
+.TP
+.BI network= net
+Limit connections from the client to be on the network NID specified by 'net'.
+'net' designates a single network NID, like 'o2ib2' or 'tcp1'.
+This option can be useful in case of several Lustre client mount
+points on the same node, with each mount point using a different
+network. It is also interesting when running Lustre clients from
+containers, by restricting each container to a specific network.
 .PP
 In addition to the standard mount options and backing disk type
 (e.g. ext3) options listed in
index e221485..eff2b48 100644 (file)
@@ -239,6 +239,7 @@ struct lustre_mount_data {
        __u32  *lmd_exclude;    /* array of OSTs to ignore */
        char   *lmd_mgs;        /* MGS nid */
        char   *lmd_osd_type;   /* OSD type */
+       char   *lmd_nidnet;     /* network to restrict this client to */
 };
 
 #define LMD_FLG_SERVER         0x0001  /* Mounting a server */
index e2fe882..c57b21e 100644 (file)
@@ -2084,7 +2084,8 @@ void ptlrpc_request_committed(struct ptlrpc_request *req, int force);
 void ptlrpc_init_client(int req_portal, int rep_portal, char *name,
                         struct ptlrpc_client *);
 void ptlrpc_cleanup_client(struct obd_import *imp);
-struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid);
+struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid,
+                                                   lnet_nid_t nid4refnet);
 
 int ptlrpc_queue_wait(struct ptlrpc_request *req);
 int ptlrpc_replay_req(struct ptlrpc_request *req);
index 3726f18..b916701 100644 (file)
 static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
                            int priority, int create)
 {
-        struct ptlrpc_connection *ptlrpc_conn;
-        struct obd_import_conn *imp_conn = NULL, *item;
-        int rc = 0;
-        ENTRY;
+       struct ptlrpc_connection *ptlrpc_conn;
+       struct obd_import_conn *imp_conn = NULL, *item;
+       lnet_nid_t nid4refnet = LNET_NID_ANY;
+       int rc = 0;
+       ENTRY;
 
-        if (!create && !priority) {
-                CDEBUG(D_HA, "Nothing to do\n");
-                RETURN(-EINVAL);
-        }
+       if (!create && !priority) {
+               CDEBUG(D_HA, "Nothing to do\n");
+               RETURN(-EINVAL);
+       }
 
-        ptlrpc_conn = ptlrpc_uuid_to_connection(uuid);
-        if (!ptlrpc_conn) {
-                CDEBUG(D_HA, "can't find connection %s\n", uuid->uuid);
-                RETURN (-ENOENT);
-        }
+       if (imp->imp_connection &&
+           imp->imp_connection->c_remote_uuid.uuid[0] == 0)
+               /* nid4refnet is used to restrict network connections */
+               nid4refnet = imp->imp_connection->c_self;
+       ptlrpc_conn = ptlrpc_uuid_to_connection(uuid, nid4refnet);
+       if (!ptlrpc_conn) {
+               CDEBUG(D_HA, "can't find connection %s\n", uuid->uuid);
+               RETURN(-ENOENT);
+       }
 
-        if (create) {
-                OBD_ALLOC(imp_conn, sizeof(*imp_conn));
-                if (!imp_conn) {
-                        GOTO(out_put, rc = -ENOMEM);
-                }
-        }
+       if (create) {
+               OBD_ALLOC(imp_conn, sizeof(*imp_conn));
+               if (!imp_conn)
+                       GOTO(out_put, rc = -ENOMEM);
+       }
 
        spin_lock(&imp->imp_lock);
        list_for_each_entry(item, &imp->imp_conn_list, oic_item) {
-                if (obd_uuid_equals(uuid, &item->oic_uuid)) {
-                        if (priority) {
+               if (obd_uuid_equals(uuid, &item->oic_uuid)) {
+                       if (priority) {
                                list_del(&item->oic_item);
                                list_add(&item->oic_item,
-                                             &imp->imp_conn_list);
-                                item->oic_last_attempt = 0;
-                        }
-                        CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",
-                               imp, imp->imp_obd->obd_name, uuid->uuid,
-                               (priority ? ", moved to head" : ""));
+                                        &imp->imp_conn_list);
+                               item->oic_last_attempt = 0;
+                       }
+                       CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",
+                              imp, imp->imp_obd->obd_name, uuid->uuid,
+                              (priority ? ", moved to head" : ""));
                        spin_unlock(&imp->imp_lock);
-                        GOTO(out_free, rc = 0);
-                }
-        }
+                       GOTO(out_free, rc = 0);
+               }
+       }
        /* No existing import connection found for \a uuid. */
-        if (create) {
-                imp_conn->oic_conn = ptlrpc_conn;
-                imp_conn->oic_uuid = *uuid;
-                imp_conn->oic_last_attempt = 0;
-                if (priority)
+       if (create) {
+               imp_conn->oic_conn = ptlrpc_conn;
+               imp_conn->oic_uuid = *uuid;
+               imp_conn->oic_last_attempt = 0;
+               if (priority)
                        list_add(&imp_conn->oic_item, &imp->imp_conn_list);
-                else
+               else
                        list_add_tail(&imp_conn->oic_item,
-                                          &imp->imp_conn_list);
-                CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",
-                       imp, imp->imp_obd->obd_name, uuid->uuid,
-                       (priority ? "head" : "tail"));
-        } else {
+                                     &imp->imp_conn_list);
+               CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",
+                      imp, imp->imp_obd->obd_name, uuid->uuid,
+                      (priority ? "head" : "tail"));
+       } else {
                spin_unlock(&imp->imp_lock);
                GOTO(out_free, rc = -ENOENT);
        }
 
        spin_unlock(&imp->imp_lock);
-        RETURN(0);
+       RETURN(0);
 out_free:
-        if (imp_conn)
-                OBD_FREE(imp_conn, sizeof(*imp_conn));
+       if (imp_conn)
+               OBD_FREE(imp_conn, sizeof(*imp_conn));
 out_put:
-        ptlrpc_connection_put(ptlrpc_conn);
-        RETURN(rc);
+       ptlrpc_connection_put(ptlrpc_conn);
+       RETURN(rc);
 }
 
 int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid)
@@ -256,6 +260,7 @@ static int osc_on_mdt(char *obdname)
  * 1 - client UUID
  * 2 - server UUID
  * 3 - inactive-on-startup
+ * 4 - restrictive net
  */
 int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
 {
@@ -266,6 +271,8 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
        char *name = obddev->obd_type->typ_name;
        enum ldlm_ns_type ns_type = LDLM_NS_TYPE_UNKNOWN;
        char *cli_name = lustre_cfg_buf(lcfg, 0);
+       struct ptlrpc_connection fake_conn = { .c_self = 0,
+                                              .c_remote_uuid.uuid[0] = 0 };
        int rc;
        ENTRY;
 
@@ -453,11 +460,26 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
                LUSTRE_CFG_BUFLEN(lcfg, 1));
         class_import_put(imp);
 
-        rc = client_import_add_conn(imp, &server_uuid, 1);
-        if (rc) {
-                CERROR("can't add initial connection\n");
-                GOTO(err_import, rc);
-        }
+       if (lustre_cfg_buf(lcfg, 4)) {
+               __u32 refnet = libcfs_str2net(lustre_cfg_string(lcfg, 4));
+
+               if (refnet == LNET_NIDNET(LNET_NID_ANY)) {
+                       rc = -EINVAL;
+                       CERROR("%s: bad mount option 'network=%s': rc = %d\n",
+                              obddev->obd_name, lustre_cfg_string(lcfg, 4),
+                              rc);
+                       GOTO(err_import, rc);
+               }
+               fake_conn.c_self = LNET_MKNID(refnet, 0);
+               imp->imp_connection = &fake_conn;
+       }
+
+       rc = client_import_add_conn(imp, &server_uuid, 1);
+       if (rc) {
+               CERROR("can't add initial connection\n");
+               GOTO(err_import, rc);
+       }
+       imp->imp_connection = NULL;
 
        cli->cl_import = imp;
        /* cli->cl_max_mds_easize updated by mdc_init_ea_size() */
index 485545f..ad2f518 100644 (file)
@@ -1583,6 +1583,7 @@ int class_config_llog_handler(const struct lu_env *env,
                                lcfg->lcfg_command = LCFG_LOV_ADD_INA;
                }
 
+               lustre_cfg_bufs_reset(&bufs, NULL);
                lustre_cfg_bufs_init(&bufs, lcfg);
 
                if (cfg->cfg_instance &&
@@ -1625,6 +1626,48 @@ int class_config_llog_handler(const struct lu_env *env,
                                                   cfg->cfg_obdname);
                }
 
+               /* Add net info to setup command
+                * if given on command line.
+                * So config log will be:
+                * [0]: client name
+                * [1]: client UUID
+                * [2]: server UUID
+                * [3]: inactive-on-startup
+                * [4]: restrictive net
+                */
+               if (cfg && cfg->cfg_sb && s2lsi(cfg->cfg_sb) &&
+                   !IS_SERVER(s2lsi(cfg->cfg_sb))) {
+                       struct lustre_sb_info *lsi = s2lsi(cfg->cfg_sb);
+                       char *nidnet = lsi->lsi_lmd->lmd_nidnet;
+
+                       if (lcfg->lcfg_command == LCFG_SETUP &&
+                           lcfg->lcfg_bufcount != 2 && nidnet) {
+                               CDEBUG(D_CONFIG, "Adding net %s info to setup "
+                                      "command for client %s\n", nidnet,
+                                      lustre_cfg_string(lcfg, 0));
+                               lustre_cfg_bufs_set_string(&bufs, 4, nidnet);
+                       }
+               }
+
+               /* Skip add_conn command if uuid is
+                * not on restricted net */
+               if (cfg && cfg->cfg_sb && s2lsi(cfg->cfg_sb) &&
+                   !IS_SERVER(s2lsi(cfg->cfg_sb))) {
+                       struct lustre_sb_info *lsi = s2lsi(cfg->cfg_sb);
+                       char *uuid_str = lustre_cfg_string(lcfg, 1);
+
+                       if (lcfg->lcfg_command == LCFG_ADD_CONN &&
+                           lsi->lsi_lmd->lmd_nidnet &&
+                           LNET_NIDNET(libcfs_str2nid(uuid_str)) !=
+                           libcfs_str2net(lsi->lsi_lmd->lmd_nidnet)) {
+                               CDEBUG(D_CONFIG, "skipping add_conn for %s\n",
+                                      uuid_str);
+                               rc = 0;
+                               /* No processing! */
+                               break;
+                       }
+               }
+
                lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
                if (lcfg_new == NULL)
                        GOTO(out, rc = -ENOMEM);
@@ -1632,8 +1675,8 @@ int class_config_llog_handler(const struct lu_env *env,
                lcfg_new->lcfg_num   = lcfg->lcfg_num;
                lcfg_new->lcfg_flags = lcfg->lcfg_flags;
 
-                /* XXX Hack to try to remain binary compatible with
-                 * pre-newconfig logs */
+               /* XXX Hack to try to remain binary compatible with
+                * pre-newconfig logs */
                if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
                    (lcfg->lcfg_nid >> 32) == 0) {
                        __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
@@ -1658,7 +1701,7 @@ int class_config_llog_handler(const struct lu_env *env,
        }
        default:
                CERROR("Unknown llog record type %#x encountered\n",
-                       rec->lrh_type);
+                      rec->lrh_type);
                break;
        }
 out:
index 90be44b..96eefa8 100644 (file)
@@ -629,6 +629,9 @@ static int lustre_free_lsi(struct super_block *sb)
                                 strlen(lsi->lsi_lmd->lmd_osd_type) + 1);
                if (lsi->lsi_lmd->lmd_params != NULL)
                        OBD_FREE(lsi->lsi_lmd->lmd_params, 4096);
+               if (lsi->lsi_lmd->lmd_nidnet != NULL)
+                       OBD_FREE(lsi->lsi_lmd->lmd_nidnet,
+                               strlen(lsi->lsi_lmd->lmd_nidnet) + 1);
 
                OBD_FREE_PTR(lsi->lsi_lmd);
        }
@@ -974,6 +977,31 @@ static int lmd_parse_mgssec(struct lustre_mount_data *lmd, char *ptr)
         return 0;
 }
 
+static int lmd_parse_network(struct lustre_mount_data *lmd, char *ptr)
+{
+       char   *tail;
+       int     length;
+
+       if (lmd->lmd_nidnet != NULL) {
+               OBD_FREE(lmd->lmd_nidnet, strlen(lmd->lmd_nidnet) + 1);
+               lmd->lmd_nidnet = NULL;
+       }
+
+       tail = strchr(ptr, ',');
+       if (tail == NULL)
+               length = strlen(ptr);
+       else
+               length = tail - ptr;
+
+       OBD_ALLOC(lmd->lmd_nidnet, length + 1);
+       if (lmd->lmd_nidnet == NULL)
+               return -ENOMEM;
+
+       memcpy(lmd->lmd_nidnet, ptr, length);
+       lmd->lmd_nidnet[length] = '\0';
+       return 0;
+}
+
 static int lmd_parse_string(char **handle, char *ptr)
 {
        char   *tail;
@@ -1131,68 +1159,70 @@ static int lmd_parse_nidlist(char *buf, char **endh)
 static int lmd_parse(char *options, struct lustre_mount_data *lmd)
 {
        char *s1, *s2, *s3, *devname = NULL;
-        struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
-        int rc = 0;
-        ENTRY;
+       struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
+       int rc = 0;
+       ENTRY;
 
-        LASSERT(lmd);
-        if (!options) {
-                LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that "
-                                   "/sbin/mount.lustre is installed.\n");
-                RETURN(-EINVAL);
-        }
+       LASSERT(lmd);
+       if (!options) {
+               LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that "
+                                  "/sbin/mount.lustre is installed.\n");
+               RETURN(-EINVAL);
+       }
 
-        /* Options should be a string - try to detect old lmd data */
-        if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) {
-                LCONSOLE_ERROR_MSG(0x163, "You're using an old version of "
-                                   "/sbin/mount.lustre.  Please install "
-                                   "version %s\n", LUSTRE_VERSION_STRING);
-                RETURN(-EINVAL);
-        }
-        lmd->lmd_magic = LMD_MAGIC;
+       /* Options should be a string - try to detect old lmd data */
+       if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) {
+               LCONSOLE_ERROR_MSG(0x163, "You're using an old version of "
+                                  "/sbin/mount.lustre.  Please install "
+                                  "version %s\n", LUSTRE_VERSION_STRING);
+               RETURN(-EINVAL);
+       }
+       lmd->lmd_magic = LMD_MAGIC;
 
        OBD_ALLOC(lmd->lmd_params, LMD_PARAMS_MAXLEN);
        if (lmd->lmd_params == NULL)
                RETURN(-ENOMEM);
        lmd->lmd_params[0] = '\0';
 
-        /* Set default flags here */
+       /* Set default flags here */
 
-        s1 = options;
-        while (*s1) {
-                int clear = 0;
-                int time_min = OBD_RECOVERY_TIME_MIN;
+       s1 = options;
+       while (*s1) {
+               int clear = 0;
+               int time_min = OBD_RECOVERY_TIME_MIN;
 
-                /* Skip whitespace and extra commas */
-                while (*s1 == ' ' || *s1 == ',')
-                        s1++;
+               /* Skip whitespace and extra commas */
+               while (*s1 == ' ' || *s1 == ',')
+                       s1++;
                s3 = s1;
 
-                /* Client options are parsed in ll_options: eg. flock,
-                   user_xattr, acl */
-
-                /* Parse non-ldiskfs options here. Rather than modifying
-                   ldiskfs, we just zero these out here */
-                if (strncmp(s1, "abort_recov", 11) == 0) {
-                        lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
-                        clear++;
-                } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
-                        lmd->lmd_recovery_time_soft = max_t(int,
-                                simple_strtoul(s1 + 19, NULL, 10), time_min);
-                        clear++;
-                } else if (strncmp(s1, "recovery_time_hard=", 19) == 0) {
-                        lmd->lmd_recovery_time_hard = max_t(int,
-                                simple_strtoul(s1 + 19, NULL, 10), time_min);
-                        clear++;
-                } else if (strncmp(s1, "noir", 4) == 0) {
-                        lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
-                        clear++;
-                } else if (strncmp(s1, "nosvc", 5) == 0) {
-                        lmd->lmd_flags |= LMD_FLG_NOSVC;
-                        clear++;
-                } else if (strncmp(s1, "nomgs", 5) == 0) {
-                        lmd->lmd_flags |= LMD_FLG_NOMGS;
-                        clear++;
+               /* Client options are parsed in ll_options: eg. flock,
+                  user_xattr, acl */
+
+               /* Parse non-ldiskfs options here. Rather than modifying
+                  ldiskfs, we just zero these out here */
+               if (strncmp(s1, "abort_recov", 11) == 0) {
+                       lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
+                       clear++;
+               } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
+                       lmd->lmd_recovery_time_soft =
+                               max_t(int, simple_strtoul(s1 + 19, NULL, 10),
+                                     time_min);
+                       clear++;
+               } else if (strncmp(s1, "recovery_time_hard=", 19) == 0) {
+                       lmd->lmd_recovery_time_hard =
+                               max_t(int, simple_strtoul(s1 + 19, NULL, 10),
+                                     time_min);
+                       clear++;
+               } else if (strncmp(s1, "noir", 4) == 0) {
+                       lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
+                       clear++;
+               } else if (strncmp(s1, "nosvc", 5) == 0) {
+                       lmd->lmd_flags |= LMD_FLG_NOSVC;
+                       clear++;
+               } else if (strncmp(s1, "nomgs", 5) == 0) {
+                       lmd->lmd_flags |= LMD_FLG_NOMGS;
+                       clear++;
                } else if (strncmp(s1, "noscrub", 7) == 0) {
                        lmd->lmd_flags |= LMD_FLG_NOSCRUB;
                        clear++;
@@ -1209,9 +1239,9 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                                goto invalid;
                        s3 = s2;
                        clear++;
-                } else if (strncmp(s1, "writeconf", 9) == 0) {
-                        lmd->lmd_flags |= LMD_FLG_WRITECONF;
-                        clear++;
+               } else if (strncmp(s1, "writeconf", 9) == 0) {
+                       lmd->lmd_flags |= LMD_FLG_WRITECONF;
+                       clear++;
                } else if (strncmp(s1, "update", 6) == 0) {
                        lmd->lmd_flags |= LMD_FLG_UPDATE;
                        clear++;
@@ -1221,17 +1251,17 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                } else if (strncmp(s1, "noprimnode", 10) == 0) {
                        lmd->lmd_flags |= LMD_FLG_NO_PRIMNODE;
                        clear++;
-                } else if (strncmp(s1, "mgssec=", 7) == 0) {
-                        rc = lmd_parse_mgssec(lmd, s1 + 7);
-                        if (rc)
-                                goto invalid;
-                        clear++;
-                /* ost exclusion list */
-                } else if (strncmp(s1, "exclude=", 8) == 0) {
-                        rc = lmd_make_exclusion(lmd, s1 + 7);
-                        if (rc)
-                                goto invalid;
-                        clear++;
+               } else if (strncmp(s1, "mgssec=", 7) == 0) {
+                       rc = lmd_parse_mgssec(lmd, s1 + 7);
+                       if (rc)
+                               goto invalid;
+                       clear++;
+                       /* ost exclusion list */
+               } else if (strncmp(s1, "exclude=", 8) == 0) {
+                       rc = lmd_make_exclusion(lmd, s1 + 7);
+                       if (rc)
+                               goto invalid;
+                       clear++;
                } else if (strncmp(s1, "mgs", 3) == 0) {
                        /* We are an MGS */
                        lmd->lmd_flags |= LMD_FLG_MGS;
@@ -1269,36 +1299,41 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                        if (rc)
                                goto invalid;
                        clear++;
-                }
-                /* Linux 2.4 doesn't pass the device, so we stuck it at the
-                   end of the options. */
-                else if (strncmp(s1, "device=", 7) == 0) {
-                        devname = s1 + 7;
-                        /* terminate options right before device.  device
-                           must be the last one. */
-                        *s1 = '\0';
-                        break;
-                }
+               }
+               /* Linux 2.4 doesn't pass the device, so we stuck it at the
+                  end of the options. */
+               else if (strncmp(s1, "device=", 7) == 0) {
+                       devname = s1 + 7;
+                       /* terminate options right before device.  device
+                          must be the last one. */
+                       *s1 = '\0';
+                       break;
+               } else if (strncmp(s1, "network=", 8) == 0) {
+                       rc = lmd_parse_network(lmd, s1 + 8);
+                       if (rc)
+                               goto invalid;
+                       clear++;
+               }
 
                /* Find next opt */
                s2 = strchr(s3, ',');
-                if (s2 == NULL) {
-                        if (clear)
-                                *s1 = '\0';
-                        break;
-                }
-                s2++;
-                if (clear)
-                        memmove(s1, s2, strlen(s2) + 1);
-                else
-                        s1 = s2;
-        }
+               if (s2 == NULL) {
+                       if (clear)
+                               *s1 = '\0';
+                       break;
+               }
+               s2++;
+               if (clear)
+                       memmove(s1, s2, strlen(s2) + 1);
+               else
+                       s1 = s2;
+       }
 
-        if (!devname) {
-                LCONSOLE_ERROR_MSG(0x164, "Can't find the device name "
-                                   "(need mount option 'device=...')\n");
-                goto invalid;
-        }
+       if (!devname) {
+               LCONSOLE_ERROR_MSG(0x164, "Can't find the device name "
+                                  "(need mount option 'device=...')\n");
+               goto invalid;
+       }
 
        s1 = strstr(devname, ":/");
        if (s1) {
@@ -1327,39 +1362,50 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                        OBD_ALLOC(lmd->lmd_fileset, s2 - s1 + 2);
                        if (lmd->lmd_fileset == NULL) {
                                OBD_FREE(lmd->lmd_profile,
-                                       strlen(lmd->lmd_profile) + 1);
+                                        strlen(lmd->lmd_profile) + 1);
                                RETURN(-ENOMEM);
                        }
                        strncat(lmd->lmd_fileset, s1, s2 - s1 + 1);
                }
+       } else {
+               /* server mount */
+               if (lmd->lmd_nidnet != NULL) {
+                       /* 'network=' mount option forbidden for server */
+                       OBD_FREE(lmd->lmd_nidnet, strlen(lmd->lmd_nidnet) + 1);
+                       lmd->lmd_nidnet = NULL;
+                       rc = -EINVAL;
+                       CERROR("%s: option 'network=' not allowed for Lustre "
+                              "servers: rc = %d\n", devname, rc);
+                       RETURN(rc);
+               }
        }
 
-        /* Freed in lustre_free_lsi */
-        OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
-        if (!lmd->lmd_dev)
-                RETURN(-ENOMEM);
-        strcpy(lmd->lmd_dev, devname);
-
-        /* Save mount options */
-        s1 = options + strlen(options) - 1;
-        while (s1 >= options && (*s1 == ',' || *s1 == ' '))
-                *s1-- = 0;
-        if (*options != 0) {
-                /* Freed in lustre_free_lsi */
-                OBD_ALLOC(lmd->lmd_opts, strlen(options) + 1);
-                if (!lmd->lmd_opts)
-                        RETURN(-ENOMEM);
-                strcpy(lmd->lmd_opts, options);
-        }
+       /* Freed in lustre_free_lsi */
+       OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
+       if (!lmd->lmd_dev)
+               RETURN(-ENOMEM);
+       strncpy(lmd->lmd_dev, devname, strlen(devname)+1);
+
+       /* Save mount options */
+       s1 = options + strlen(options) - 1;
+       while (s1 >= options && (*s1 == ',' || *s1 == ' '))
+               *s1-- = 0;
+       if (*options != 0) {
+               /* Freed in lustre_free_lsi */
+               OBD_ALLOC(lmd->lmd_opts, strlen(options) + 1);
+               if (!lmd->lmd_opts)
+                       RETURN(-ENOMEM);
+               strncpy(lmd->lmd_opts, options, strlen(options)+1);
+       }
 
-        lmd_print(lmd);
-        lmd->lmd_magic = LMD_MAGIC;
+       lmd_print(lmd);
+       lmd->lmd_magic = LMD_MAGIC;
 
-        RETURN(rc);
+       RETURN(rc);
 
 invalid:
-        CERROR("Bad mount options %s\n", options);
-        RETURN(-EINVAL);
+       CERROR("Bad mount options %s\n", options);
+       RETURN(-EINVAL);
 }
 
 struct lustre_mount_data2 {
index 8d2e01b..c5d0150 100644 (file)
@@ -79,31 +79,33 @@ EXPORT_SYMBOL(ptlrpc_init_client);
 /**
  * Return PortalRPC connection for remore uud \a uuid
  */
-struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid)
+struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid,
+                                                   lnet_nid_t nid4refnet)
 {
-        struct ptlrpc_connection *c;
-        lnet_nid_t                self;
-        lnet_process_id_t         peer;
-        int                       err;
+       struct ptlrpc_connection *c;
+       lnet_nid_t                self;
+       lnet_process_id_t         peer;
+       int                       err;
 
        /* ptlrpc_uuid_to_peer() initializes its 2nd parameter
         * before accessing its values. */
        /* coverity[uninit_use_in_call] */
-        err = ptlrpc_uuid_to_peer(uuid, &peer, &self);
-        if (err != 0) {
-                CNETERR("cannot find peer %s!\n", uuid->uuid);
-                return NULL;
-        }
+       peer.nid = nid4refnet;
+       err = ptlrpc_uuid_to_peer(uuid, &peer, &self);
+       if (err != 0) {
+               CNETERR("cannot find peer %s!\n", uuid->uuid);
+               return NULL;
+       }
 
-        c = ptlrpc_connection_get(peer, self, uuid);
-        if (c) {
-                memcpy(c->c_remote_uuid.uuid,
-                       uuid->uuid, sizeof(c->c_remote_uuid.uuid));
-        }
+       c = ptlrpc_connection_get(peer, self, uuid);
+       if (c) {
+               memcpy(c->c_remote_uuid.uuid,
+                      uuid->uuid, sizeof(c->c_remote_uuid.uuid));
+       }
 
-        CDEBUG(D_INFO, "%s -> %p\n", uuid->uuid, c);
+       CDEBUG(D_INFO, "%s -> %p\n", uuid->uuid, c);
 
-        return c;
+       return c;
 }
 
 /**
index 3855b3b..13aed57 100644 (file)
@@ -497,43 +497,47 @@ static void ptlrpc_master_callback(lnet_event_t *ev)
 int ptlrpc_uuid_to_peer (struct obd_uuid *uuid,
                          lnet_process_id_t *peer, lnet_nid_t *self)
 {
-        int               best_dist = 0;
-        __u32             best_order = 0;
-        int               count = 0;
-        int               rc = -ENOENT;
-        int               dist;
-        __u32             order;
-        lnet_nid_t        dst_nid;
-        lnet_nid_t        src_nid;
+       int               best_dist = 0;
+       __u32             best_order = 0;
+       int               count = 0;
+       int               rc = -ENOENT;
+       int               dist;
+       __u32             order;
+       lnet_nid_t        dst_nid;
+       lnet_nid_t        src_nid;
 
        peer->pid = LNET_PID_LUSTRE;
 
-        /* Choose the matching UUID that's closest */
-        while (lustre_uuid_to_peer(uuid->uuid, &dst_nid, count++) == 0) {
-                dist = LNetDist(dst_nid, &src_nid, &order);
-                if (dist < 0)
-                        continue;
+       /* Choose the matching UUID that's closest */
+       while (lustre_uuid_to_peer(uuid->uuid, &dst_nid, count++) == 0) {
+               if (peer->nid != LNET_NID_ANY && LNET_NIDADDR(peer->nid) == 0 &&
+                   LNET_NIDNET(dst_nid) != LNET_NIDNET(peer->nid))
+                       continue;
 
-                if (dist == 0) {                /* local! use loopback LND */
-                        peer->nid = *self = LNET_MKNID(LNET_MKNET(LOLND, 0), 0);
-                        rc = 0;
-                        break;
-                }
+               dist = LNetDist(dst_nid, &src_nid, &order);
+               if (dist < 0)
+                       continue;
 
-                if (rc < 0 ||
-                    dist < best_dist ||
-                    (dist == best_dist && order < best_order)) {
-                        best_dist = dist;
-                        best_order = order;
+               if (dist == 0) {                /* local! use loopback LND */
+                       peer->nid = *self = LNET_MKNID(LNET_MKNET(LOLND, 0), 0);
+                       rc = 0;
+                       break;
+               }
 
-                        peer->nid = dst_nid;
-                        *self = src_nid;
-                        rc = 0;
-                }
-        }
+               if (rc < 0 ||
+                   dist < best_dist ||
+                   (dist == best_dist && order < best_order)) {
+                       best_dist = dist;
+                       best_order = order;
 
-        CDEBUG(D_NET,"%s->%s\n", uuid->uuid, libcfs_id2str(*peer));
-        return rc;
+                       peer->nid = dst_nid;
+                       *self = src_nid;
+                       rc = 0;
+               }
+       }
+
+       CDEBUG(D_NET, "%s->%s\n", uuid->uuid, libcfs_id2str(*peer));
+       return rc;
 }
 
 void ptlrpc_ni_fini(void)