From 63bd163f2fe0c885ec93004609635c7bdf945253 Mon Sep 17 00:00:00 2001 From: niu Date: Wed, 10 Dec 2003 10:13:55 +0000 Subject: [PATCH] b: 1991 r: Peter lfs catinfo Fetching logs information from client node. Now keywords include: config and deletions. Others will be added in future. --- lustre/include/linux/lustre_idl.h | 1 + lustre/include/linux/lustre_lib.h | 1 + lustre/include/linux/lustre_log.h | 3 + lustre/include/linux/lustre_net.h | 1 + lustre/llite/dir.c | 43 ++++++++ lustre/mds/handler.c | 5 + lustre/obdclass/llog_lvfs.c | 1 + lustre/ptlrpc/llog_server.c | 227 ++++++++++++++++++++++++++++++++++++++ lustre/ptlrpc/ptlrpc_module.c | 1 + lustre/utils/lfs.c | 46 ++++++++ lustre/utils/liblustreapi.c | 41 +++++++ 11 files changed, 370 insertions(+) diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 368f35c..4b6ad12 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -957,6 +957,7 @@ enum llogd_rpc_ops { LLOG_ORIGIN_HANDLE_WRITE_REC = 504, LLOG_ORIGIN_HANDLE_CLOSE = 505, LLOG_ORIGIN_CONNECT = 506, + LLOG_CATINFO = 507, /* for lfs catinfo */ }; struct llogd_body { diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index b95e847..41dfe21 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -448,6 +448,7 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_LLOG_CANCEL _IOWR('f', 193, long) #define OBD_IOC_LLOG_REMOVE _IOWR('f', 194, long) #define OBD_IOC_LLOG_CHECK _IOWR('f', 195, long) +#define OBD_IOC_LLOG_CATINFO _IOWR('f', 196, long) #define ECHO_IOC_GET_STRIPE _IOWR('f', 200, long) #define ECHO_IOC_SET_STRIPE _IOWR('f', 201, long) diff --git a/lustre/include/linux/lustre_log.h b/lustre/include/linux/lustre_log.h index ad60e1b..c3ff249 100644 --- a/lustre/include/linux/lustre_log.h +++ b/lustre/include/linux/lustre_log.h @@ -170,6 +170,9 @@ struct llog_operations { /* XXX add 2 more: commit callbacks and llog recovery functions */ }; +/* llog_lvfs.c */ +int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, + char *name, int count, struct llog_logid *idarray); extern struct llog_operations llog_lvfs_ops; diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index bf6aefc..9d50fda 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -572,6 +572,7 @@ int llog_origin_handle_next_block(struct ptlrpc_request *req); int llog_origin_handle_read_header(struct ptlrpc_request *req); int llog_origin_handle_close(struct ptlrpc_request *req); int llog_origin_handle_cancel(struct ptlrpc_request *req); +int llog_catinfo(struct ptlrpc_request *req); /* ptlrpc/llog_client.c */ extern struct llog_operations llog_client_ops; diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 05dfb09..8fdffb4 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -521,6 +521,49 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, obd_ioctl_freedata(buf, len); return rc; } + case OBD_IOC_LLOG_CATINFO: { + struct ptlrpc_request *req = NULL; + char *buf = NULL; + int rc, len = 0; + char *bufs[2], *str; + int lens[2], size; + + rc = obd_ioctl_getdata(&buf, &len, (void *)arg); + if (rc) + RETURN(rc); + data = (void *)buf; + + if (!data->ioc_inlbuf1) { + obd_ioctl_freedata(buf, len); + RETURN(-EINVAL); + } + + lens[0] = data->ioc_inllen1; + bufs[0] = data->ioc_inlbuf1; + if (data->ioc_inllen2) { + lens[1] = data->ioc_inllen2; + bufs[1] = data->ioc_inlbuf2; + } else { + lens[1] = 0; + bufs[1] = NULL; + } + size = data->ioc_plen1; + req = ptlrpc_prep_req(sbi2mdc(sbi)->cl_import, LLOG_CATINFO, + 2, lens, bufs); + if (!req) + GOTO(out_catinfo, rc = -ENOMEM); + req->rq_replen = lustre_msg_size(1, &size); + + rc = ptlrpc_queue_wait(req); + str = lustre_msg_string(req->rq_repmsg, 0, data->ioc_plen1); + if (!rc) + rc = copy_to_user(data->ioc_pbuf1, str, + data->ioc_plen1); + ptlrpc_req_finished(req); + out_catinfo: + obd_ioctl_freedata(buf, len); + RETURN(rc); + } default: return obd_iocontrol(cmd, sbi->ll_osc_exp,0,NULL,(void *)arg); } diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 82e16ac..28d8c21 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -1184,6 +1184,11 @@ int mds_handle(struct ptlrpc_request *req) OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0); rc = llog_origin_handle_close(req); break; + case LLOG_CATINFO: + DEBUG_REQ(D_INODE, req, "llog catinfo"); + OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0); + rc = llog_catinfo(req); + break; default: req->rq_status = -ENOTSUPP; rc = ptlrpc_error(req); diff --git a/lustre/obdclass/llog_lvfs.c b/lustre/obdclass/llog_lvfs.c index a5a94eb..5eb2922 100644 --- a/lustre/obdclass/llog_lvfs.c +++ b/lustre/obdclass/llog_lvfs.c @@ -594,6 +594,7 @@ int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd, rc = filp_close(file, 0); RETURN(rc); } +EXPORT_SYMBOL(llog_get_cat_list); /* writes the cat list */ int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd, diff --git a/lustre/ptlrpc/llog_server.c b/lustre/ptlrpc/llog_server.c index 742b545..645a32e 100644 --- a/lustre/ptlrpc/llog_server.c +++ b/lustre/ptlrpc/llog_server.c @@ -281,3 +281,230 @@ int llog_origin_handle_cancel(struct ptlrpc_request *req) } EXPORT_SYMBOL(llog_origin_handle_cancel); #endif + +static int llog_catinfo_config(struct obd_device *obd, char *buf, int buf_len, + char *client) +{ + struct mds_obd *mds = &obd->u.mds; + struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + struct obd_run_ctxt saved; + struct llog_handle *handle = NULL; + char name[4][64]; + int rc, i, l, remains = buf_len; + char *out = buf; + + if (ctxt == NULL || mds == NULL) + RETURN(-EOPNOTSUPP); + + push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL); + + sprintf(name[0], "%s", mds->mds_profile); + sprintf(name[1], "%s-clean", mds->mds_profile); + sprintf(name[2], "%s", client); + sprintf(name[3], "%s-clean", client); + + for (i = 0; i < 4; i++) { + int index, uncanceled = 0; + rc = llog_create(ctxt, &handle, NULL, name[i]); + if (rc) + GOTO(out_pop, rc); + rc = llog_init_handle(handle, 0, NULL); + if (rc) { + llog_close(handle); + GOTO(out_pop, rc = -ENOENT); + } + + for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index ++) { + if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap)) + uncanceled++; + } + + l = snprintf(out, remains, "[Log Name]: %s\nLog Size: "LPD64"\n" + "Last Index: %d\nUncanceled Records: %d\n\n", + name[i], + handle->lgh_file->f_dentry->d_inode->i_size, + handle->lgh_last_idx, + uncanceled); + out += l; + remains -= l; + + llog_close(handle); + if (remains <= 0) + break; + } +out_pop: + pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL); + RETURN(rc); +} + +struct cb_data { + struct llog_ctxt *ctxt; + char *out; + int remains; + int init; +}; + +static int llog_catinfo_cb(struct llog_handle *cat, + struct llog_rec_hdr *rec, void *data) +{ + static char *out = NULL; + static int remains = 0; + struct llog_ctxt *ctxt; + struct llog_handle *handle; + struct llog_logid *logid; + struct llog_logid_rec *lir; + int l, rc, index, count = 0; + struct cb_data *cbd = (struct cb_data*)data; + + if (cbd->init) { + out = cbd->out; + remains = cbd->remains; + cbd->init = 0; + } + ctxt = cbd->ctxt; + + if (!(cat->lgh_hdr->llh_flags & cpu_to_le32(LLOG_F_IS_CAT))) + RETURN(-EINVAL); + + lir = (struct llog_logid_rec *)rec; + logid = &lir->lid_id; + rc = llog_create(ctxt, &handle, logid, NULL); + if (rc) + RETURN(-EINVAL); + rc = llog_init_handle(handle, 0, NULL); + if (rc) + GOTO(out_close, rc); + + for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) { + if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap)) + count++; + } + + l = snprintf(out, remains, "\t[Log ID]: #"LPX64"#"LPX64"#%08x\n" + "\tLog Size: "LPD64"\n\tLast Index: %d\n" + "\tUncanceled Records: %d\n", + logid->lgl_oid, logid->lgl_ogr, logid->lgl_ogen, + handle->lgh_file->f_dentry->d_inode->i_size, + handle->lgh_last_idx, count); + out += l; + remains -= l; + cbd->out = out; + cbd->remains = remains; + if (remains <= 0) { + CWARN("Not enough memory\n"); + rc = -ENOMEM; + } + +out_close: + llog_close(handle); + RETURN(rc); +} + +static int llog_catinfo_deletions(struct obd_device *obd, char *buf, + int buf_len) +{ + struct mds_obd *mds = &obd->u.mds; + struct llog_handle *handle; + struct obd_run_ctxt saved; + int size, i, count; + struct llog_logid *idarray, *id; + char name[32] = "CATLIST"; + int rc; + struct cb_data data; + struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + + if (ctxt == NULL || mds == NULL) + RETURN(-EOPNOTSUPP); + + count = mds->mds_lov_desc.ld_tgt_count; + size = sizeof(*idarray) * count; + + OBD_ALLOC(idarray, size); + if (!idarray) + RETURN(-ENOMEM); + memset(idarray, 0, size); + + rc = llog_get_cat_list(obd, obd, name, count, idarray); + if (rc) + GOTO(out_free, rc); + + push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL); + + id = idarray; + data.ctxt = ctxt; + data.out = buf; + data.remains = buf_len; + for (i = 0; i < count; i++) { + int l, index, uncanceled = 0; + rc = llog_create(ctxt, &handle, id, NULL); + if (rc) + GOTO(out_pop, rc); + rc = llog_init_handle(handle, 0, NULL); + if (rc) { + llog_close(handle); + GOTO(out_pop, rc = -ENOENT); + } + for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index++) { + if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap)) + uncanceled++; + } + l = snprintf(data.out, data.remains, + "\n[Catlog ID]: #"LPX64"#"LPX64"#%08x " + "[Log Count]: %d\n", + id->lgl_oid, id->lgl_ogr, id->lgl_ogen, + uncanceled); + + data.out += l; + data.remains -= l; + data.init = 1; + + llog_process(handle, llog_catinfo_cb, &data); + llog_close(handle); + + if (data.remains <= 0) + break; + } +out_pop: + pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_ctxt, NULL); +out_free: + OBD_FREE(idarray, size); + RETURN(rc); +} + +int llog_catinfo(struct ptlrpc_request *req) +{ + struct obd_export *exp = req->rq_export; + struct obd_device *obd = exp->exp_obd; + char *keyword; + char *buf, *reply; + int rc, buf_len = LLOG_CHUNK_SIZE; + + OBD_ALLOC(buf, buf_len); + if (buf == NULL) + return -ENOMEM; + memset(buf, 0, buf_len); + + keyword = lustre_msg_string(req->rq_reqmsg, 0, 0); + + if (strcmp(keyword, "config") == 0) { + char *client = lustre_msg_string(req->rq_reqmsg, 1, 0); + rc = llog_catinfo_config(obd, buf, buf_len, client); + } else if (strcmp(keyword, "deletions") == 0) { + rc = llog_catinfo_deletions(obd, buf, buf_len); + } else { + rc = -EOPNOTSUPP; + } + + rc = lustre_pack_reply(req, 1, &buf_len, NULL); + if (rc) + GOTO(out_free, rc = -ENOMEM); + + reply = lustre_msg_buf(req->rq_repmsg, 0, buf_len); + if (strlen(buf) == 0) + sprintf(buf, "%s", "No log informations\n"); + memcpy(reply, buf, buf_len); + +out_free: + OBD_FREE(buf, buf_len); + return rc; +} diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index 1268c37..492d108 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -203,6 +203,7 @@ EXPORT_SYMBOL(llog_origin_handle_next_block); EXPORT_SYMBOL(llog_origin_handle_read_header); EXPORT_SYMBOL(llog_origin_handle_close); EXPORT_SYMBOL(llog_client_ops); +EXPORT_SYMBOL(llog_catinfo); MODULE_AUTHOR("Cluster File Systems, Inc. "); MODULE_DESCRIPTION("Lustre Request Processor and Lock Management"); diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index f403706..8f20c8e 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -43,6 +43,7 @@ extern int op_create_file(char *name, long stripe_size, int stripe_offset, extern int op_find(char *path, struct obd_uuid *obduuid, int recursive, int verbose, int quiet); extern int op_check(int type_num, char **obd_type_p, char *dir); +extern int op_catinfo(char *dir, char *keyword, char *node_name); /* all functions */ static int lfs_setstripe(int argc, char **argv); @@ -50,6 +51,7 @@ static int lfs_find(int argc, char **argv); static int lfs_getstripe(int argc, char **argv); static int lfs_osts(int argc, char **argv); static int lfs_check(int argc, char **argv); +static int lfs_catinfo(int argc, char **argv); /* all avaialable commands */ command_t cmdlist[] = { @@ -68,6 +70,11 @@ command_t cmdlist[] = { {"check", lfs_check, 0, "blah...\n" "usage: check "}, + {"catinfo", lfs_catinfo, 0, + "Show information of specified type logs.\n" + "usage: catinfo [node name]" + "keywords are one of followings: config, deletions.\n" + "client node name must be provided when use keyword config."}, {"osts", lfs_osts, 0, "osts"}, {"help", Parser_help, 0, "help"}, {"exit", Parser_quit, 0, "quit"}, @@ -284,6 +291,45 @@ static int lfs_check(int argc, char **argv) } +static int lfs_catinfo(int argc, char **argv) +{ + FILE *fp; + struct mntent *mnt = NULL; + int rc; + + if (argc < 2 || (!strcmp(argv[1],"config") && argc < 3)) + return CMD_HELP; + + if (strcmp(argv[1], "config") && strcmp(argv[1], "deletions")) + return CMD_HELP; + + fp = setmntent(MOUNTED, "r"); + if (fp == NULL) { + fprintf(stderr, "setmntent(%s): %s:", MOUNTED, + strerror(errno)); + } else { + mnt = getmntent(fp); + while (feof(fp) == 0 && ferror(fp) == 0) { + if (strcmp(mnt->mnt_type, "lustre_lite") == 0) + break; + mnt = getmntent(fp); + } + endmntent(fp); + } + + if (mnt) { + if (argc == 3) + rc = op_catinfo(mnt->mnt_dir, argv[1], argv[2]); + else + rc = op_catinfo(mnt->mnt_dir, argv[1], NULL); + } else { + fprintf(stderr, "no lustre_lite mounted.\n"); + rc = -1; + } + + return rc; +} + int main(int argc, char **argv) { int rc; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 7ea801c..cb07fa4 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -531,3 +531,44 @@ int op_check(int type_num, char **obd_type, char *dir) #undef MAX_STRING_SIZE +int op_catinfo(char *dir, char *keyword, char *node_name) +{ + char raw[OBD_MAX_IOCTL_BUFFER]; + char out[LLOG_CHUNK_SIZE]; + char *buf = raw; + struct obd_ioctl_data data; + char key[30]; + DIR *root; + int rc; + + sprintf(key, "%s", keyword); + memset(raw, 0, sizeof(buf)); + memset(out, 0, sizeof(out)); + data.ioc_inlbuf1 = key; + data.ioc_inllen1 = strlen(key) + 1; + if (node_name) { + data.ioc_inlbuf2 = node_name; + data.ioc_inllen2 = strlen(node_name) + 1; + } + data.ioc_pbuf1 = out; + data.ioc_plen1 = sizeof(out); + rc = obd_ioctl_pack(&data, &buf, sizeof(raw)); + if (rc) + return rc; + + root = opendir(dir); + if (root == NULL) { + err_msg("open %s failed", dir); + return errno; + } + + rc = ioctl(dirfd(root), OBD_IOC_LLOG_CATINFO, buf); + if (rc) + err_msg("ioctl OBD_IOC_CATINFO failed"); + else + fprintf(stdout, "%s", data.ioc_pbuf1); + + closedir(root); + return rc; +} + -- 1.8.3.1