/*add mds num here for real mds and cache mds create
FIXME later will be totally fixed by b_cmd*/
int mds_num;
+ struct lprocfs_stats *mds_counters;
int mds_config_version;
char *mds_lmv_name;
char name[MAX_STRING_SIZE + 1];
int err, id;
struct lprocfs_stats *svc_stats = NULL;
+ struct proc_dir_entry *mdc_symlink, *osc_symlink;
struct proc_dir_entry *entry;
ENTRY;
LASSERT(obd->obd_type != NULL);
LASSERT(obd->obd_type->typ_name != NULL);
- snprintf(name, MAX_STRING_SIZE, "%s/common_name",
- obd->obd_type->typ_name);
- lvars[0].read_fptr = lprocfs_rd_name;
- err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
- if (err)
- goto out;
-
- snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
- lvars[0].read_fptr = lprocfs_rd_uuid;
- err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
- if (err)
+ snprintf(name, MAX_STRING_SIZE, "../../%s/%s",
+ obd->obd_type->typ_name, obd->obd_name);
+ mdc_symlink = proc_symlink(obd->obd_type->typ_name, sbi->ll_proc_root,
+ name);
+ if (mdc_symlink == NULL) {
+ err = -ENOMEM;
goto out;
+ }
/* OSC */
obd = class_name2obd(osc);
LASSERT(obd->obd_type != NULL);
LASSERT(obd->obd_type->typ_name != NULL);
- snprintf(name, MAX_STRING_SIZE, "%s/common_name",
- obd->obd_type->typ_name);
- lvars[0].read_fptr = lprocfs_rd_name;
- err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
- if (err)
- goto out;
+ snprintf(name, MAX_STRING_SIZE, "../../%s/%s",
+ obd->obd_type->typ_name, obd->obd_name);
+ osc_symlink = proc_symlink(obd->obd_type->typ_name, sbi->ll_proc_root,
+ name);
+ if (osc_symlink == NULL)
+ err = -ENOMEM;
+
- snprintf(name, MAX_STRING_SIZE, "%s/uuid", obd->obd_type->typ_name);
- lvars[0].read_fptr = lprocfs_rd_uuid;
- err = lprocfs_add_vars(sbi->ll_proc_root, lvars, obd);
out:
if (err) {
if (svc_stats)
return 1;
}
+/* lproc_lmv.c */
+extern struct file_operations lmv_proc_target_fops;
+
#endif
#ifdef __KERNEL__
struct proc_dir_entry *entry;
- entry = create_proc_entry("target_obd", 0444, dev->obd_proc_entry);
+ entry = create_proc_entry("target_obd_status", 0444,
+ dev->obd_proc_entry);
if (entry == NULL)
RETURN(-ENOMEM);
- /* entry->proc_fops = &lmv_proc_target_fops; */
+ entry->proc_fops = &lmv_proc_target_fops;
entry->data = dev;
#endif
}
{
struct lmv_obd *lmv = &obd->u.lmv;
struct obd_export *exp;
+ struct proc_dir_entry *lmv_proc_dir;
int rc;
ENTRY;
lmv->exp = exp;
sema_init(&lmv->init_sem, 1);
+ lmv_proc_dir = lprocfs_register("target_obds", obd->obd_proc_entry,
+ NULL, NULL);
+ if (IS_ERR(lmv_proc_dir)) {
+ CERROR("could not register /proc/fs/lustre/%s/%s/target_obds.",
+ obd->obd_type->typ_name, obd->obd_name);
+ lmv_proc_dir = NULL;
+ }
+
+
RETURN(0);
}
}
/* Performs a check if passed obd is connected. If no - connect it. */
+#define MAX_STRING_SIZE 128
int lmv_check_connect(struct obd_device *obd)
{
struct lmv_obd *lmv = &obd->u.lmv;
struct obd_uuid *cluuid;
struct lmv_tgt_desc *tgts;
+ struct proc_dir_entry *lmv_proc_dir;
struct obd_export *exp;
int rc, rc2, i;
CERROR("Target %s not set up\n", tgts->uuid.uuid);
GOTO(out_disc, rc = -EINVAL);
}
-
- rc = obd_connect(&conn, tgt_obd, &lmv_osc_uuid, lmv->connect_flags);
+
+ rc = obd_connect(&conn, tgt_obd, &lmv_osc_uuid,
+ lmv->connect_flags);
if (rc) {
CERROR("Target %s connect error %d\n",
tgts->uuid.uuid, rc);
obd_init_ea_size(tgts->ltd_exp, lmv->max_easize,
lmv->max_cookiesize);
-
+
rc = obd_register_observer(tgt_obd, obd);
if (rc) {
CERROR("Target %s register_observer error %d\n",
lmv->desc.ld_active_tgt_count++;
tgts->active = 1;
-
+
CDEBUG(D_OTHER, "connected to %s(%s) successfully (%d)\n",
tgt_obd->obd_name, tgt_obd->obd_uuid.uuid,
atomic_read(&obd->obd_refcount));
+
+ lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+ if (lmv_proc_dir) {
+ struct obd_device *mdc_obd = class_conn2obd(&conn);
+ struct proc_dir_entry *mdc_symlink;
+ char name[MAX_STRING_SIZE + 1];
+
+ LASSERT(mdc_obd != NULL);
+ LASSERT(mdc_obd->obd_type != NULL);
+ LASSERT(mdc_obd->obd_type->typ_name != NULL);
+ name[MAX_STRING_SIZE] = '\0';
+ snprintf(name, MAX_STRING_SIZE, "../../../%s/%s",
+ mdc_obd->obd_type->typ_name,
+ mdc_obd->obd_name);
+ mdc_symlink = proc_symlink(mdc_obd->obd_name,
+ lmv_proc_dir, name);
+ if (mdc_symlink == NULL) {
+ CERROR("could not register LMV target "
+ "/proc/fs/lustre/%s/%s/target_obds/%s.",
+ obd->obd_type->typ_name, obd->obd_name,
+ mdc_obd->obd_name);
+ lprocfs_remove(lmv_proc_dir);
+ lmv_proc_dir = NULL;
+ }
+ }
}
lmv_set_timeouts(obd);
{
struct obd_device *obd = class_exp2obd(exp);
struct lmv_obd *lmv = &obd->u.lmv;
+ struct proc_dir_entry *lmv_proc_dir;
int rc, i;
ENTRY;
if (lmv->refcount != 0)
goto out_local;
+ lmv_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+ struct obd_device *mdc_obd;
+
if (lmv->tgts[i].ltd_exp == NULL)
continue;
+ mdc_obd = class_exp2obd(lmv->tgts[i].ltd_exp);
+ if (lmv_proc_dir) {
+ struct proc_dir_entry *mdc_symlink;
+
+ mdc_symlink = lprocfs_srch(lmv_proc_dir, mdc_obd->obd_name);
+ if (mdc_symlink) {
+ lprocfs_remove(mdc_symlink);
+ } else {
+ CERROR("/proc/fs/lustre/%s/%s/target_obds/%s missing.",
+ obd->obd_type->typ_name, obd->obd_name,
+ mdc_obd->obd_name);
+ }
+ }
+
if (obd->obd_no_recov) {
/* Pass it on to our clients.
* XXX This should be an argument to disconnect,
lmv->tgts[i].ltd_exp = NULL;
}
+ if (lmv_proc_dir) {
+ lprocfs_remove(lmv_proc_dir);
+ } else {
+ CERROR("/proc/fs/lustre/%s/%s/target_obds missing.",
+ obd->obd_type->typ_name, obd->obd_name);
+ }
+
+
out_local:
/* this is the case when no real connection is established by
* lmv_check_connect(). */
/* time to drop cached attrs for dirobj */
obj = lock->l_ast_data;
if (obj) {
- CDEBUG(D_OTHER, "cancel %s on %lu/%lu, master %lu/%lu/%lu\n",
- lock->l_resource->lr_name.name[3] == 1 ? "LOOKUP" : "UPDATE",
- (unsigned long)lock->l_resource->lr_name.name[0],
- (unsigned long)lock->l_resource->lr_name.name[1],
- (unsigned long)obj->fid.mds, (unsigned long)obj->fid.id,
- (unsigned long)obj->fid.generation);
+ CDEBUG(D_OTHER, "cancel %s on "LPU64"/"LPU64
+ ", master %u/"LPU64"/%u\n",
+ lock->l_resource->lr_name.name[3] == 1 ?
+ "LOOKUP" : "UPDATE",
+ lock->l_resource->lr_name.name[0],
+ lock->l_resource->lr_name.name[1], obj->fid.mds,
+ obj->fid.id, obj->fid.generation);
lmv_put_obj(obj);
}
break;
struct lov_tgt_desc *tgt;
struct obd_export *exp;
int rc, rc2, i;
+ struct proc_dir_entry *lov_proc_dir;
ENTRY;
rc = class_connect(conn, obd, cluuid);
RETURN (0);
out_disc:
+ if (lov_proc_dir)
+ lprocfs_remove(lov_proc_dir);
+
while (i-- > 0) {
struct obd_uuid uuid;
--tgt;
struct obd_device *obd = class_exp2obd(exp);
struct lov_obd *lov = &obd->u.lov;
struct lov_tgt_desc *tgt;
+ struct proc_dir_entry *lov_proc_dir;
int rc, i;
ENTRY;
if (lov->refcount != 0)
goto out_local;
+ lov_proc_dir = lprocfs_register("target_obds", obd->obd_proc_entry,
+ NULL, NULL);
+ if (IS_ERR(lov_proc_dir)) {
+ CERROR("could not register /proc/fs/lustre/%s/%s/target_obds.",
+ obd->obd_type->typ_name, obd->obd_name);
+ lov_proc_dir = NULL;
+ }
+
for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) {
if (tgt->ltd_exp)
lov_disconnect_obd(obd, tgt, flags);
}
+ lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
+ if (lov_proc_dir) {
+ lprocfs_remove(lov_proc_dir);
+ } else {
+ CERROR("/proc/fs/lustre/%s/%s/target_obds missing.",
+ obd->obd_type->typ_name, obd->obd_name);
+ }
+
out_local:
rc = class_disconnect(exp, 0);
#ifdef __KERNEL__
struct proc_dir_entry *entry;
- entry = create_proc_entry("target_obd", 0444,
+ entry = create_proc_entry("target_obd_status", 0444,
dev->obd_proc_entry);
if (entry == NULL) {
rc = -ENOMEM;
/* Swab now, before anyone looks inside the request */
+ MDS_UPDATE_COUNTER((&obd->u.mds), MDS_GETATTR_NAME_COUNT);
+
body = lustre_swab_reqbuf(req, offset, sizeof(*body),
lustre_swab_mds_body);
if (body == NULL) {
RETURN (-EFAULT);
}
+ MDS_UPDATE_COUNTER(mds, MDS_GETATTR_COUNT);
+
uc.luc_fsuid = body->fsuid;
uc.luc_fsgid = body->fsgid;
uc.luc_cap = body->capability;
GOTO(out, rc);
}
+ MDS_UPDATE_COUNTER((&obd->u.mds), MDS_STATFS_COUNT);
+
/* We call this so that we can cache a bit - 1 jiffie worth */
rc = mds_obd_statfs(obd, lustre_msg_buf(req->rq_repmsg, 0, size),
jiffies - HZ);
"mds_ldlm_client", &obd->obd_ldlm_client);
obd->obd_replayable = 1;
+ mds->mds_counters = lprocfs_alloc_mds_counters();
+
rc = mds_postsetup(obd);
if (rc)
GOTO(err_fs, rc);
ldlm_namespace_free(obd->obd_namespace, flags & OBD_OPT_FORCE);
+ if (mds->mds_counters) {
+ lprocfs_free_mds_counters(mds->mds_counters);
+ }
+
spin_lock_bh(&obd->obd_processing_task_lock);
if (obd->obd_recovering) {
target_cancel_recovery_timer(obd);
struct lprocfs_vars lprocfs_mdt_obd_vars[] = { {0} };
struct lprocfs_vars lprocfs_mdt_module_vars[] = { {0} };
+atomic_t * lprocfs_alloc_mds_counters()
+{
+ return NULL;
+}
+void lprocfs_free_mds_counters(atomic_t *ptr)
+{
+ return;
+}
+
#else
+struct ll_mdscounters_opcode {
+ __u32 opcode;
+ const char *opname;
+} ll_mdscounters_opcode_table[MDS_LAST_OPC_COUNT] = {
+ { MDS_OPEN_COUNT, "mds_open" },
+ { MDS_CREATE_COUNT, "mds_create" },
+ { MDS_CLOSE_COUNT, "mds_close" },
+ { MDS_LINK_COUNT, "mds_link" },
+ { MDS_UNLINK_COUNT, "mds_unlink" },
+ { MDS_GETATTR_COUNT, "mds_getattr" },
+ { MDS_GETATTR_NAME_COUNT, "mds_getattr_name" },
+ { MDS_SETATTR_COUNT, "mds_setattr" },
+ { MDS_RENAME_COUNT, "mds_rename" },
+ { MDS_STATFS_COUNT, "mds_statfs" },
+};
+
+const char* ll_mds_count_opcode2str(__u32 opcode)
+{
+ __u32 offset = opcode;
+
+ LASSERT(offset < MDS_LAST_OPC_COUNT);
+ LASSERT(ll_mdscounters_opcode_table[offset].opcode == opcode);
+ return ll_mdscounters_opcode_table[offset].opname;
+}
+
+struct lprocfs_stats * lprocfs_alloc_mds_counters()
+{
+ struct lprocfs_stats *counters;
+ int i;
+
+ counters = lprocfs_alloc_stats(MDS_LAST_OPC_COUNT);
+
+ for (i = 0; i < MDS_LAST_OPC_COUNT; i ++) {
+ lprocfs_counter_init(counters, i, 0,
+ (char *)ll_mds_count_opcode2str(i), "reqs");
+ }
+ return counters;
+}
+
+void lprocfs_free_mds_counters(struct lprocfs_stats *ptr)
+{
+ lprocfs_free_stats(ptr);
+}
+
static int lprocfs_mds_rd_mntdev(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
return len + n;
}
+static int lprocfs_rd_mds_counters(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct obd_device* obd = (struct obd_device *)data;
+ int len = 0, n, i, j;
+ struct lprocfs_counter t, ret = { .lc_min = ~(__u64)0 };
+ struct lprocfs_stats *stats;
+ struct timeval now;
+
+ LASSERT(obd != NULL);
+ if (obd->u.mds.mds_counters == NULL)
+ return 0;
+
+ do_gettimeofday(&now);
+
+ n = snprintf(page, count, "%-25s %lu.%lu secs.usecs\n",
+ "snapshot_time", now.tv_sec, now.tv_usec);
+ page += n; len +=n; count -=n;
+
+ stats = obd->u.mds.mds_counters;
+
+ *eof = 1;
+ for (i = 0; i < MDS_LAST_OPC_COUNT; i ++) {
+ ret.lc_count = 0;
+ for (j = 0; j < num_online_cpus(); j++) {
+ struct lprocfs_counter *percpu_cntr =
+ &(stats->ls_percpu[j])->lp_cntr[i];
+ int centry;
+ do {
+ centry =
+ atomic_read(&percpu_cntr->lc_cntl.la_entry);
+ t.lc_count = percpu_cntr->lc_count;
+ } while (centry !=
+ atomic_read(&percpu_cntr->lc_cntl.la_entry) &&
+ centry !=
+ atomic_read(&percpu_cntr->lc_cntl.la_exit));
+ ret.lc_count += t.lc_count;
+ }
+ n = snprintf(page, count, "%-25s "LPU64" \n",
+ ll_mds_count_opcode2str(i), ret.lc_count);
+ page += n; len +=n; count -=n;
+ }
+ return (len);
+}
+
static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer,
unsigned long count, void *data)
{
{ "evict_client", 0, lprocfs_mds_wr_evict_client, 0 },
{ "config_update", 0, lprocfs_mds_wr_config_update, 0 },
{ "num_exports", lprocfs_rd_num_exports, 0, 0 },
+ { "counters", lprocfs_rd_mds_counters, 0, 0 },
{ 0 }
};
{ 0 }
};
+
#endif
struct lprocfs_static_vars lprocfs_array_vars[] = { {lprocfs_mds_module_vars,
return req->rq_export->exp_obd;
}
+typedef enum {
+ MDS_OPEN_COUNT = 0,
+ MDS_CREATE_COUNT = 1,
+ MDS_CLOSE_COUNT = 2,
+ MDS_LINK_COUNT = 3,
+ MDS_UNLINK_COUNT = 4,
+ MDS_GETATTR_COUNT = 5,
+ MDS_GETATTR_NAME_COUNT = 6,
+ MDS_SETATTR_COUNT = 7,
+ MDS_RENAME_COUNT = 8,
+ MDS_STATFS_COUNT = 9,
+ MDS_LAST_OPC_COUNT = 10
+} mds_counters_t;
+
+struct lprocfs_stats * lprocfs_alloc_mds_counters(void);
+void lprocfs_free_mds_counters(struct lprocfs_stats *ptr);
+
+#ifndef LPROCFS
+#define MDS_UPDATE_COUNTER(mds, opcode) do {} while (0)
+#else
+
+#define MDS_UPDATE_COUNTER(mds, opcode) \
+ LASSERT( opcode < MDS_LAST_OPC_COUNT); \
+ LASSERT( mds->mds_counters != NULL); \
+ lprocfs_counter_incr(mds->mds_counters, opcode);
+#endif
+
/* mds/mds_reint.c */
int enqueue_ordered_locks(struct obd_device *obd, struct ldlm_res_id *p1_res_id,
struct lustre_handle *p1_lockh, int p1_lock_mode,
MDS_CHECK_RESENT(req, reconstruct_open(rec, offset, req, child_lockh));
+ MDS_UPDATE_COUNTER(mds, MDS_OPEN_COUNT);
+
/* Step 0: If we are passed a fid, then we assume the client already
* opened this file and is only replaying the RPC, so we open the
* inode by fid (at some large expense in security). */
CERROR("error on parent setattr: rc = %d\n", rc);
acc_mode = 0; /* Don't check for permissions */
+ if (rc == 0) {
+ MDS_UPDATE_COUNTER(mds, MDS_CREATE_COUNT);
+ }
}
LASSERT(!mds_inode_is_orphan(dchild->d_inode));
obd->u.mds.mds_max_cookiesize};
ENTRY;
+ MDS_UPDATE_COUNTER((&obd->u.mds), MDS_CLOSE_COUNT);
+
rc = lustre_pack_reply(req, 3, repsize, NULL);
if (rc) {
CERROR("lustre_pack_reply: rc = %d\n", rc);
req->rq_repmsg->buflens[2]);
}
+
body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_mds_body);
if (body == NULL) {
CERROR("Can't unpack body\n");
MDS_CHECK_RESENT(req, reconstruct_reint_setattr(rec, offset, req));
+ MDS_UPDATE_COUNTER(mds, MDS_SETATTR_COUNT);
+
if (rec->ur_iattr.ia_valid & ATTR_FROM_OPEN) {
de = mds_fid2dentry(mds, rec->ur_fid1, NULL);
if (IS_ERR(de))
MDS_CHECK_RESENT(req, reconstruct_reint_create(rec, offset, req));
+
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE))
GOTO(cleanup, rc = -ESTALE);
body = lustre_msg_buf(req->rq_repmsg, offset, sizeof (*body));
mds_pack_inode2fid(obd, &body->fid1, inode);
mds_pack_inode2body(obd, body, inode);
+ if (rc == 0) {
+ MDS_UPDATE_COUNTER(mds, MDS_CREATE_COUNT);
+ }
}
EXIT;
req->rq_repmsg->buflens[offset + 2]);
}
+ MDS_UPDATE_COUNTER(mds, MDS_UNLINK_COUNT);
+
+
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK))
GOTO(cleanup, rc = -ENOENT);
MDS_CHECK_RESENT(req, mds_reconstruct_generic(req));
+ MDS_UPDATE_COUNTER(mds, MDS_LINK_COUNT);
+
+
// memset(tgt_dir_lockh, 0, 2*sizeof(tgt_dir_lockh[0]));
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_LINK))
GOTO(cleanup, rc = -ENOENT);
req->rq_repmsg->buflens[2]);
}
+ MDS_UPDATE_COUNTER(mds, MDS_RENAME_COUNT);
+
if (rec->ur_namelen == 1) {
rc = mds_reint_rename_create_name(rec, offset, req);
RETURN(rc);