Whamcloud - gitweb
LU-14668 lnet: add 'force' option to lnetctl peer del 49/50149/5
authorSerguei Smirnov <ssmirnov@whamcloud.com>
Mon, 27 Feb 2023 23:41:19 +0000 (15:41 -0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 8 Mar 2023 03:29:08 +0000 (03:29 +0000)
Add --force option to 'lnetctl peer del' command.
If the peer has primary NID locked, this option allows
for the peer to be deleted manually:
lnetctl peer del --prim_nid <nid> --force

Add --prim_lock option to 'lnetctl peer add' command.
If specified, the primary NID of the peer is locked
such that it is going to be the NID used to identify
the peer in communications with Lustre layer.

Test-Parameters: trivial
Signed-off-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Change-Id: Ia6001856cfbce7b0c3288cff9b244b569d259647
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50149
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/include/lnet/lib-lnet.h
lnet/include/uapi/linux/lnet/lnet-dlc.h
lnet/lnet/api-ni.c
lnet/lnet/peer.c
lnet/utils/lnetconfig/liblnetconfig.c
lnet/utils/lnetconfig/liblnetconfig.h
lnet/utils/lnetctl.c
lustre/doc/lnetctl.8
lustre/tests/sanity-lnet.sh

index de3aa44..218f496 100644 (file)
@@ -1029,8 +1029,10 @@ void lnet_peer_clr_pref_rtrs(struct lnet_peer_ni *lpni);
 int lnet_peer_add_pref_rtr(struct lnet_peer_ni *lpni, struct lnet_nid *nid);
 int lnet_peer_ni_set_non_mr_pref_nid(struct lnet_peer_ni *lpni,
                                     struct lnet_nid *nid);
-int lnet_user_add_peer_ni(struct lnet_nid *key_nid, struct lnet_nid *nid, bool mr);
-int lnet_del_peer_ni(struct lnet_nid *key_nid, struct lnet_nid *nid);
+int lnet_user_add_peer_ni(struct lnet_nid *key_nid, struct lnet_nid *nid,
+                         bool mr, bool lock_prim);
+int lnet_del_peer_ni(struct lnet_nid *key_nid, struct lnet_nid *nid,
+                    int force);
 int lnet_get_peer_info(struct lnet_ioctl_peer_cfg *cfg, void __user *bulk);
 int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid,
                          char alivness[LNET_MAX_STR_LEN],
index 186003d..a1f4bfe 100644 (file)
@@ -306,7 +306,9 @@ struct lnet_ioctl_peer_cfg {
        struct libcfs_ioctl_hdr prcfg_hdr;
        lnet_nid_t prcfg_prim_nid;
        lnet_nid_t prcfg_cfg_nid;
-       __u32 prcfg_count;
+       __u32 prcfg_count;      /* ADD_PEER_NI: used for 'lock_prim' option
+                                * DEL_PEER_NI: used for 'force' option
+                                */
        __u32 prcfg_mr;
        __u32 prcfg_state;
        __u32 prcfg_size;
index cb068b0..4d95812 100644 (file)
@@ -4317,7 +4317,8 @@ LNetCtl(unsigned int cmd, void *arg)
                mutex_lock(&the_lnet.ln_api_mutex);
                lnet_nid4_to_nid(cfg->prcfg_prim_nid, &prim_nid);
                lnet_nid4_to_nid(cfg->prcfg_cfg_nid, &nid);
-               rc = lnet_user_add_peer_ni(&prim_nid, &nid, cfg->prcfg_mr);
+               rc = lnet_user_add_peer_ni(&prim_nid, &nid, cfg->prcfg_mr,
+                                          cfg->prcfg_count == 1);
                mutex_unlock(&the_lnet.ln_api_mutex);
                return rc;
        }
@@ -4333,7 +4334,8 @@ LNetCtl(unsigned int cmd, void *arg)
                lnet_nid4_to_nid(cfg->prcfg_prim_nid, &prim_nid);
                lnet_nid4_to_nid(cfg->prcfg_cfg_nid, &nid);
                rc = lnet_del_peer_ni(&prim_nid,
-                                     &nid);
+                                     &nid,
+                                     cfg->prcfg_count);
                mutex_unlock(&the_lnet.ln_api_mutex);
                return rc;
        }
index 0a32194..168507e 100644 (file)
@@ -1989,9 +1989,12 @@ __must_hold(&the_lnet.ln_api_mutex)
        return lnet_peer_add_nid(lp, nid, flags);
 }
 
-int lnet_user_add_peer_ni(struct lnet_nid *prim_nid, struct lnet_nid *nid, bool mr)
+int lnet_user_add_peer_ni(struct lnet_nid *prim_nid, struct lnet_nid *nid,
+                         bool mr, bool lock_prim)
 {
-       return lnet_add_peer_ni(prim_nid, nid, mr, LNET_PEER_CONFIGURED);
+       int fl = LNET_PEER_CONFIGURED | (LNET_PEER_LOCK_PRIMARY * lock_prim);
+
+       return lnet_add_peer_ni(prim_nid, nid, mr, fl);
 }
 
 static int
@@ -2040,7 +2043,8 @@ lnet_reset_peer(struct lnet_peer *lp)
  * being modified/deleted by a different thread.
  */
 int
-lnet_del_peer_ni(struct lnet_nid *prim_nid, struct lnet_nid *nid)
+lnet_del_peer_ni(struct lnet_nid *prim_nid, struct lnet_nid *nid,
+                int force)
 {
        struct lnet_peer *lp;
        struct lnet_peer_ni *lpni;
@@ -2072,7 +2076,7 @@ lnet_del_peer_ni(struct lnet_nid *prim_nid, struct lnet_nid *nid)
        lnet_net_unlock(LNET_LOCK_EX);
 
        if (LNET_NID_IS_ANY(nid) || nid_same(nid, &lp->lp_primary_nid)) {
-               if (lp->lp_state & LNET_PEER_LOCK_PRIMARY) {
+               if (!force && lp->lp_state & LNET_PEER_LOCK_PRIMARY) {
                        CERROR("peer %s created by Lustre. Must preserve primary NID, but will remove other NIDs\n",
                               libcfs_nidstr(&lp->lp_primary_nid));
                        return lnet_reset_peer(lp);
index 9c42ff3..967af40 100644 (file)
@@ -631,7 +631,7 @@ int lustre_lnet_discover_nid(char *ping_nids, int force, int seq_no,
 }
 
 static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
-                                          bool is_mr, __u32 cmd,
+                                          bool is_mr, int option, __u32 cmd,
                                           char *cmd_type, char *err_str)
 {
        struct lnet_ioctl_peer_cfg data;
@@ -646,6 +646,7 @@ static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
                data.prcfg_mr = is_mr;
                data.prcfg_prim_nid = nidlist[0];
                data.prcfg_cfg_nid = LNET_NID_ANY;
+               data.prcfg_count = option;
 
                rc = dispatch_peer_ni_cmd(cmd, &data, err_str, cmd_type);
 
@@ -661,6 +662,7 @@ static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
                data.prcfg_mr = is_mr;
                data.prcfg_prim_nid = nidlist[0];
                data.prcfg_cfg_nid = nidlist[nid_idx];
+               data.prcfg_count = option;
 
                rc = dispatch_peer_ni_cmd(cmd, &data, err_str, cmd_type);
 
@@ -676,6 +678,7 @@ static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
                LIBCFS_IOC_INIT_V2(data, prcfg_hdr);
                data.prcfg_prim_nid = nidlist[0];
                data.prcfg_cfg_nid = LNET_NID_ANY;
+               data.prcfg_count = option;
 
                rc = dispatch_peer_ni_cmd(cmd, &data, err_str, cmd_type);
        }
@@ -685,8 +688,8 @@ static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
 
 static int
 lustre_lnet_mod_peer_nidlist(lnet_nid_t pnid, lnet_nid_t *lnet_nidlist,
-                            int cmd, int num_nids, bool is_mr, int seq_no,
-                            struct cYAML **err_rc)
+                            int cmd, int num_nids, bool is_mr, int option,
+                            int seq_no, struct cYAML **err_rc)
 {
        int rc = LUSTRE_CFG_RC_NO_ERR;
        char err_str[LNET_MAX_STR_LEN];
@@ -707,8 +710,8 @@ lustre_lnet_mod_peer_nidlist(lnet_nid_t pnid, lnet_nid_t *lnet_nidlist,
                                                (num_nids - 1));
 
        rc = lustre_lnet_handle_peer_nidlist(lnet_nidlist2,
-                                            num_nids, is_mr, ioc_cmd,
-                                            cmd_str, err_str);
+                                            num_nids, is_mr, option,
+                                            ioc_cmd, cmd_str, err_str);
 out:
        if (lnet_nidlist2)
                free(lnet_nidlist2);
@@ -735,8 +738,8 @@ replace_sep(char *str, char sep, char newsep)
        }
 }
 
-int lustre_lnet_modify_peer(char *prim_nid, char *nids, bool is_mr,
-                           int cmd, int seq_no, struct cYAML **err_rc)
+int lustre_lnet_modify_peer(char *prim_nid, char *nids, bool is_mr, int cmd,
+                           int option, int seq_no, struct cYAML **err_rc)
 {
        int num_nids, rc;
        char err_str[LNET_MAX_STR_LEN] = "Error";
@@ -775,7 +778,7 @@ int lustre_lnet_modify_peer(char *prim_nid, char *nids, bool is_mr,
 
        rc = lustre_lnet_mod_peer_nidlist(pnid, lnet_nidlist,
                                          cmd, num_nids, is_mr,
-                                         -1, err_rc);
+                                         option, -1, err_rc);
 
 out:
        if (rc != LUSTRE_CFG_RC_NO_ERR)
@@ -4851,6 +4854,7 @@ static int handle_yaml_peer_common(struct cYAML *tree, struct cYAML **show_rc,
        struct cYAML *seq_no, *prim_nid, *mr, *peer_nis;
        lnet_nid_t lnet_nidlist[LNET_MAX_NIDS_PER_PEER];
        lnet_nid_t pnid = LNET_NID_ANY;
+       int force = 0;
 
        seq_no = cYAML_get_object_item(tree, "seq_no");
        seqn = seq_no ? seq_no->cy_valueint : -1;
@@ -4917,8 +4921,8 @@ static int handle_yaml_peer_common(struct cYAML *tree, struct cYAML **show_rc,
        }
 
        rc = lustre_lnet_mod_peer_nidlist(pnid, lnet_nidlist, cmd,
-                                         num_nids, mr_value, seqn,
-                                         err_rc);
+                                         num_nids, mr_value, force,
+                                         seqn, err_rc);
 
 failed:
        if (nidstr)
index 32a985f..69ceca1 100644 (file)
@@ -678,11 +678,12 @@ int lustre_lnet_reset_stats(int seq_no, struct cYAML **err_rc);
  *     nids - a comma separated string of nids
  *     is_mr - Specifies whether this peer is MR capable.
  *     cmd - CONFIG or DELETE
+ *     force - whether force-deleting a peer with locked primary nid
  *     seq_no - sequence number of the command
  *     err_rc - YAML structure of the resultant return code
  */
-int lustre_lnet_modify_peer(char *prim_nid, char *nids, bool is_mr,
-                           int cmd, int seq_no, struct cYAML **err_rc);
+int lustre_lnet_modify_peer(char *prim_nid, char *nids, bool is_mr, int cmd,
+                           int force, int seq_no, struct cYAML **err_rc);
 
 /*
  * lustre_lnet_show_peer
index f908cd8..72ed1a3 100644 (file)
@@ -266,12 +266,14 @@ command_t peer_cmds[] = {
         "\t--prim_nid: Primary NID of the peer.\n"
         "\t--nid: one or more peer NIDs\n"
         "\t--non_mr: create this peer as not Multi-Rail capable\n"
-        "\t--ip2nets: specify a range of nids per peer"},
+        "\t--ip2nets: specify a range of nids per peer\n"
+        "\t--lock_prim: lock primary nid\n"},
        {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
         "\t--prim_nid: Primary NID of the peer.\n"
         "\t--nid: list of NIDs to remove. If none provided,\n"
         "\t       peer is deleted\n"
-        "\t--ip2nets: specify a range of nids per peer"},
+        "\t--ip2nets: specify a range of nids per peer\n"
+        "\t--force: force-delete locked primary NID\n"},
        {"show", jt_show_peer, 0, "show peer information\n"
         "\t--nid: NID of peer to filter on.\n"
         "\t--verbose: display detailed output per peer."
@@ -2844,12 +2846,15 @@ static int jt_peer_nid_common(int argc, char **argv, int cmd)
        char *prim_nid = NULL, *nidstr = NULL;
        char err_str[LNET_MAX_STR_LEN] = "Error";
        struct cYAML *err_rc = NULL;
+       int force_lock = 0;
 
-       const char *const short_opts = "k:mn:";
+       const char *const short_opts = "k:m:n:f:l";
        const struct option long_opts[] = {
        { .name = "prim_nid",   .has_arg = required_argument,   .val = 'k' },
        { .name = "non_mr",     .has_arg = no_argument,         .val = 'm' },
        { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
+       { .name = "force",      .has_arg = no_argument,         .val = 'f' },
+       { .name = "lock_prim",  .has_arg = no_argument,         .val = 'l' },
        { .name = NULL } };
 
        rc = check_cmd(peer_cmds, "peer", "add", 2, argc, argv);
@@ -2874,6 +2879,22 @@ static int jt_peer_nid_common(int argc, char **argv, int cmd)
                        }
                        is_mr = false;
                        break;
+               case 'f':
+                       if (cmd == LNETCTL_ADD_CMD) {
+                               rc = LUSTRE_CFG_RC_BAD_PARAM;
+                               snprintf(err_str, LNET_MAX_STR_LEN,
+                                        "Unrecognized option '-%c'", opt);
+                       }
+                       force_lock = 1;
+                       break;
+               case 'l':
+                       if (cmd == LNETCTL_DEL_CMD) {
+                               rc = LUSTRE_CFG_RC_BAD_PARAM;
+                               snprintf(err_str, LNET_MAX_STR_LEN,
+                                        "Unrecognized option '-%c'", opt);
+                       }
+                       force_lock = 1;
+                       break;
                case '?':
                        print_help(peer_cmds, "peer",
                                   cmd == LNETCTL_ADD_CMD ? "add" : "del");
@@ -2883,7 +2904,7 @@ static int jt_peer_nid_common(int argc, char **argv, int cmd)
        }
 
        rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
-                                    -1, &err_rc);
+                                    force_lock, -1, &err_rc);
        if (rc != LUSTRE_CFG_RC_NO_ERR)
                goto out;
 
index 381ecea..0d1b712 100644 (file)
@@ -125,6 +125,9 @@ Configure an LNET peer with at least one supplied NID\.  The primary NID must be
 \-\-non_mr: create this peer as not Multi-Rail capable\.
 .
 .br
+\-\-lock_prim: lock primary NID of the peer for the purpose of identification with Lustre\.
+.
+.br
 
 .TP
 \fBlnetctl peer\fR del
@@ -139,6 +142,9 @@ Delete a peer NID.  The primary NID must be specified.  If the removed NID is th
 \-\-prim_nid: Primary NID of the peer\.
 .
 .br
+\-\-force: optional, use to delete a peer with primary NID locked\.
+.
+.br
 
 .TP
 \fBlnetctl peer\fR show
index ca65bba..e8e332a 100755 (executable)
@@ -925,6 +925,24 @@ EOF
 }
 run_test 25 "Delete all secondary nids from peer (tcp, gni and o2ib)"
 
+test_26() {
+       reinit_dlc || return $?
+
+       do_lnetctl peer add --prim_nid 1.1.1.1@tcp --lock_prim ||
+               error "Peer add with --lock_prim option failed $?"
+       do_lnetctl peer del --prim_nid 1.1.1.1@tcp ||
+               error "Peer del failed $?"
+       $LNETCTL peer show --nid 1.1.1.1@tcp | grep -q 1.1.1.1@tcp ||
+               error "1.1.1.1@tcp is not listed"
+       do_lnetctl peer del --prim_nid 1.1.1.1@tcp --force ||
+               error "Peer del --force failed $?"
+       do_lnetctl peer show --nid 1.1.1.1@tcp &&
+               error "failed to delete 1.1.1.1@tcp"
+
+       return 0
+}
+run_test 26 "Delete peer with primary nid locked"
+
 test_99a() {
        reinit_dlc || return $?