Details : Don't put liblustre clients into the ping_evictor list, so
they will not be evicted by the pinger ever.
+Severity : enhancement
+Bugzilla : 6902
+Description: Add ability to evict clients by NID from MDS>
+Details : By echoing "nid:$NID" string into
+ /proc/fs/lustre/mds/.../evict_client client with nid that equals to
+ $NID would be instantly evicted from this MDS and from all active
+ OSTs connected to it.
+
2005-08-08 Cluster File Systems, Inc. <info@clusterfs.com>
* version 1.4.4
* bug fixes
/* buf should be len PTL_NALFMT_SIZE */
char *obd_export_nid2str(struct obd_export *exp, char *buf);
+int obd_export_evict_by_nid(struct obd_device *obd, char *nid);
+int obd_export_evict_by_uuid(struct obd_device *obd, char *uuid);
+
/* config.c */
int class_process_config(struct lustre_cfg *lcfg);
int class_attach(struct lustre_cfg *lcfg);
if (ip == 0)
get_random_bytes(&ip, sizeof(ip));
pid = getpid() & 0xffffffff;
- tcpnal_mynid = ((uint64_t)ip << 32) | pid;
+ tcpnal_mynid = ((uint64_t)pid << 32) | ip;
in.s_addr = htonl(ip);
- CDEBUG(D_RPCTRACE | D_VFSTRACE, "TCPNAL NID: %016Lx (%s:%u)\n",
- (long long)tcpnal_mynid, inet_ntoa(in), pid);
+ CDEBUG(D_RPCTRACE | D_VFSTRACE, "TCPNAL NID: %016Lx (%u:%s)\n",
+ (long long)tcpnal_mynid, pid, inet_ntoa(in));
#else
pid_t pid;
uint32_t ip;
RETURN(rc);
}
+ if (KEY_IS("evict_by_nid")) {
+ for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+ /* OST was disconnected or is inactive */
+ if (!lov->tgts[i].ltd_exp || !lov->tgts[i].active)
+ continue;
+
+ err = obd_set_info(lov->tgts[i].ltd_exp, keylen, key,
+ vallen, val);
+ if (!rc)
+ rc = err;
+ }
+ RETURN(rc);
+ }
+
if (KEY_IS("mds_conn") || KEY_IS("unlinked")) {
if (vallen != 0)
RETURN(-EINVAL);
return snprintf(page, count, "%s\n",obd->u.mds.mds_vfsmnt->mnt_devname);
}
+static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct obd_device *obd = data;
+ struct mds_obd *mds = &obd->u.mds;
+ char tmpbuf[sizeof(struct obd_uuid)];
+ int rc;
+
+ sscanf(buffer, "%40s", tmpbuf);
+
+ if (strncmp(tmpbuf, "nid:", 4) != 0) {
+ return lprocfs_wr_evict_client(file, buffer, count, data);
+ }
+
+ obd_export_evict_by_nid(obd, tmpbuf+4);
+
+ rc = obd_set_info(mds->mds_osc_exp, strlen("evict_by_nid"),
+ "evict_by_nid", strlen(tmpbuf+4) + 1, tmpbuf+4);
+ if (rc)
+ CERROR("Failed to evict nid %s from OSTs\n", tmpbuf+4);
+
+ return count;
+}
+
static int lprocfs_wr_group_info(struct file *file, const char *buffer,
unsigned long count, void *data)
{
{ "fstype", lprocfs_rd_fstype, 0, 0 },
{ "mntdev", lprocfs_mds_rd_mntdev, 0, 0 },
{ "recovery_status", lprocfs_obd_rd_recovery_status, 0, 0 },
- { "evict_client", 0, lprocfs_wr_evict_client, 0 },
+ { "evict_client", 0, lprocfs_mds_wr_evict_client, 0 },
{ "num_exports", lprocfs_rd_num_exports, 0, 0 },
#ifdef HAVE_QUOTA_SUPPORT
{ "quota_bunit_sz", lprocfs_mds_rd_bunit, lprocfs_mds_wr_bunit, 0 },
return ipbuf;
}
+
+int obd_export_evict_by_nid(struct obd_device *obd, char *nid)
+{
+ struct obd_export *doomed_exp = NULL;
+ struct list_head *p;
+ int exports_evicted = 0;
+
+search_again:
+ spin_lock(&obd->obd_dev_lock);
+ list_for_each(p, &obd->obd_exports) {
+ char ipbuf[PTL_NALFMT_SIZE];
+
+ doomed_exp = list_entry(p, struct obd_export, exp_obd_chain);
+ obd_export_nid2str(doomed_exp, ipbuf);
+
+ if (strcmp(ipbuf, nid) == 0) {
+ class_export_get(doomed_exp);
+ break;
+ }
+ doomed_exp = NULL;
+ }
+ spin_unlock(&obd->obd_dev_lock);
+
+ if (doomed_exp == NULL) {
+ goto out;
+ } else {
+ CERROR("evicting %s at adminstrative request\n",
+ doomed_exp->exp_client_uuid.uuid);
+ class_fail_export(doomed_exp);
+ class_export_put(doomed_exp);
+ exports_evicted++;
+ goto search_again;
+ }
+
+out:
+ if (!exports_evicted)
+ CERROR("can't disconnect %s: no exports found\n", nid);
+ return exports_evicted;
+}
+EXPORT_SYMBOL(obd_export_evict_by_nid);
+
+int obd_export_evict_by_uuid(struct obd_device *obd, char *uuid)
+{
+ struct obd_export *doomed_exp = NULL;
+ struct list_head *p;
+ struct obd_uuid doomed;
+ int exports_evicted = 0;
+
+ obd_str2uuid(&doomed, uuid);
+
+ spin_lock(&obd->obd_dev_lock);
+ list_for_each(p, &obd->obd_exports) {
+ doomed_exp = list_entry(p, struct obd_export, exp_obd_chain);
+
+ if (obd_uuid_equals(&doomed, &doomed_exp->exp_client_uuid)) {
+ class_export_get(doomed_exp);
+ break;
+ }
+ doomed_exp = NULL;
+ }
+ spin_unlock(&obd->obd_dev_lock);
+
+ if (doomed_exp == NULL) {
+ CERROR("can't disconnect %s: no exports found\n", uuid);
+ } else {
+ CERROR("evicting %s at adminstrative request\n",
+ doomed_exp->exp_client_uuid.uuid);
+ class_fail_export(doomed_exp);
+ class_export_put(doomed_exp);
+ exports_evicted++;
+ }
+
+ return exports_evicted;
+}
+EXPORT_SYMBOL(obd_export_evict_by_uuid);
struct obd_device *obd = exp->exp_obd;
struct obd_import *imp = class_exp2cliimp(exp);
struct llog_ctxt *ctxt;
- int rc, size = keylen;
- char *bufs[1] = {key};
+ int rc, size[2] = {keylen, vallen};
+ char *bufs[2] = {key, val};
ENTRY;
OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_SHUTDOWN, 10);
RETURN(0);
}
- if (!KEY_IS("mds_conn"))
+ if (!KEY_IS("mds_conn") && !KEY_IS("evict_by_nid"))
RETURN(-EINVAL);
- req = ptlrpc_prep_req(imp, OST_SET_INFO, 1, &size, bufs);
+ req = ptlrpc_prep_req(imp, OST_SET_INFO, 2, &size, bufs);
if (req == NULL)
RETURN(-ENOMEM);
static int ost_set_info(struct obd_export *exp, struct ptlrpc_request *req)
{
- char *key;
- int keylen, rc = 0;
+ char *key, *val;
+ int keylen, vallen, rc = 0;
ENTRY;
key = lustre_msg_buf(req->rq_reqmsg, 0, 1);
DEBUG_REQ(D_HA, req, "no set_info key");
RETURN(-EFAULT);
}
- keylen = req->rq_reqmsg->buflens[0];
+ keylen = lustre_msg_buflen(req->rq_reqmsg,0);
rc = lustre_pack_reply(req, 0, NULL, NULL);
if (rc)
RETURN(rc);
- rc = obd_set_info(exp, keylen, key, 0, NULL);
+ if (KEY_IS("evict_by_nid")) {
+ val = lustre_msg_buf(req->rq_reqmsg, 1, 1);
+ vallen = lustre_msg_buflen(req->rq_reqmsg,1);
+
+ if (val)
+ obd_export_evict_by_nid(exp->exp_obd, val);
+
+ GOTO(out, rc = 0);
+ }
+
+ rc = obd_set_info(exp, keylen, key, vallen, val);
+out:
req->rq_repmsg->status = 0;
RETURN(rc);
}
unsigned long count, void *data)
{
struct obd_device *obd = data;
- struct obd_export *doomed_exp = NULL;
- struct obd_uuid doomed;
- struct list_head *p;
- char tmpbuf[sizeof(doomed)];
+ char tmpbuf[sizeof(struct obd_uuid)];
sscanf(buffer, "%40s", tmpbuf);
- obd_str2uuid(&doomed, tmpbuf);
-
- spin_lock(&obd->obd_dev_lock);
- list_for_each(p, &obd->obd_exports) {
- doomed_exp = list_entry(p, struct obd_export, exp_obd_chain);
- if (obd_uuid_equals(&doomed, &doomed_exp->exp_client_uuid)) {
- class_export_get(doomed_exp);
- break;
- }
- doomed_exp = NULL;
- }
- spin_unlock(&obd->obd_dev_lock);
- if (doomed_exp == NULL) {
- CERROR("can't disconnect %s: no export found\n", doomed.uuid);
- } else {
- CERROR("evicting %s at adminstrative request\n", doomed.uuid);
- class_fail_export(doomed_exp);
- class_export_put(doomed_exp);
- }
+ obd_export_evict_by_uuid(obd, tmpbuf);
+
return count;
}
EXPORT_SYMBOL(lprocfs_wr_evict_client);