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>
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],
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;
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;
}
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;
}
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
* 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;
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);
}
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;
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);
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);
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);
}
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];
(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);
}
}
-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";
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)
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;
}
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)
* 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
"\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."
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);
}
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");
}
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;
\-\-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
\-\-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
}
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 $?