From 0274da24f0eab4be7be12c5eef4a5aed45e966a4 Mon Sep 17 00:00:00 2001 From: green Date: Fri, 12 Aug 2005 12:00:25 +0000 Subject: [PATCH] Branch: b1_4 b=6902 r=adilger Evict clients by NID from both MDS and active OSTs --- lustre/ChangeLog | 8 +++++ lustre/include/linux/obd_class.h | 3 ++ lustre/liblustre/lutil.c | 6 ++-- lustre/lov/lov_obd.c | 14 ++++++++ lustre/mds/lproc_mds.c | 26 +++++++++++++- lustre/obdclass/genops.c | 75 ++++++++++++++++++++++++++++++++++++++++ lustre/osc/osc_request.c | 8 ++--- lustre/ost/ost_handler.c | 19 +++++++--- lustre/ptlrpc/lproc_ptlrpc.c | 26 ++------------ 9 files changed, 150 insertions(+), 35 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 9323d76..8d026b4 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -52,6 +52,14 @@ Description: liblustre clients evicted if not contacting servers 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. * version 1.4.4 * bug fixes diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index fe2b2c0..95c9d40 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -92,6 +92,9 @@ void ping_evictor_stop(void); /* 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); diff --git a/lustre/liblustre/lutil.c b/lustre/liblustre/lutil.c index 8eaacd5..a0aca4f 100644 --- a/lustre/liblustre/lutil.c +++ b/lustre/liblustre/lutil.c @@ -241,11 +241,11 @@ void liblustre_set_nal_nid() 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; diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 3226b18..1d98c64 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2046,6 +2046,20 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen, 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); diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c index 54949d7..6e10da2 100644 --- a/lustre/mds/lproc_mds.c +++ b/lustre/mds/lproc_mds.c @@ -46,6 +46,30 @@ static int lprocfs_mds_rd_mntdev(char *page, char **start, off_t off, int count, 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) { @@ -211,7 +235,7 @@ struct lprocfs_vars lprocfs_mds_obd_vars[] = { { "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 }, diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index a637106..a77c595e 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -1265,3 +1265,78 @@ char *obd_export_nid2str(struct obd_export *exp, char *ipbuf) 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); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 08276f7..6bf0e95 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2993,8 +2993,8 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, 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); @@ -3037,11 +3037,11 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, 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); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 5c18f74..9f43f5f 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -917,8 +917,8 @@ out: 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); @@ -926,13 +926,24 @@ static int ost_set_info(struct obd_export *exp, struct ptlrpc_request *req) 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); } diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 996d2d3..04cc661 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -463,32 +463,12 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer, 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); -- 1.8.3.1