static int mdd_changelog_llog_init(const struct lu_env *env, struct mdd_device *mdd) { struct obd_device *obd = mdd2obd_dev(mdd); struct llog_ctxt *ctxt = NULL, *uctxt = NULL; int rc; ENTRY; /* LU-2844 mdd setup failure should not cause umount oops */ if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CHANGELOG_INIT)) RETURN(-EIO); OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); obd->obd_lvfs_ctxt.dt = mdd->mdd_bottom; rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_ORIG_CTXT, obd, &changelog_orig_logops); if (rc) { CERROR("%s: changelog llog setup failed: rc = %d\n", obd->obd_name, rc); RETURN(rc); } ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); LASSERT(ctxt); rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL, CHANGELOG_CATALOG); if (rc) GOTO(out_cleanup, rc); rc = llog_cat_init_and_process(env, ctxt->loc_handle); if (rc) GOTO(out_close, rc); rc = llog_cat_reverse_process(env, ctxt->loc_handle, changelog_init_cb, mdd); if (rc < 0) { CERROR("%s: changelog init failed: rc = %d\n", obd->obd_name, rc); GOTO(out_close, rc); } CDEBUG(D_IOCTL, "changelog starting index="LPU64"\n", mdd->mdd_cl.mc_index); /* setup user changelog */ rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CHANGELOG_USER_ORIG_CTXT, obd, &changelog_orig_logops); if (rc) { CERROR("%s: changelog users llog setup failed: rc = %d\n", obd->obd_name, rc); GOTO(out_close, rc); } uctxt = llog_get_context(obd, LLOG_CHANGELOG_USER_ORIG_CTXT); LASSERT(ctxt); rc = llog_open_create(env, uctxt, &uctxt->loc_handle, NULL, CHANGELOG_USERS); if (rc) GOTO(out_ucleanup, rc); uctxt->loc_handle->lgh_logops->lop_add = llog_cat_add_rec; uctxt->loc_handle->lgh_logops->lop_declare_add = llog_cat_declare_add_rec; rc = llog_cat_init_and_process(env, uctxt->loc_handle); if (rc) GOTO(out_uclose, rc); rc = llog_cat_reverse_process(env, uctxt->loc_handle, changelog_user_init_cb, mdd); if (rc < 0) { CERROR("%s: changelog user init failed: rc = %d\n", obd->obd_name, rc); GOTO(out_uclose, rc); } /* If we have registered users, assume we want changelogs on */ if (mdd->mdd_cl.mc_lastuser > 0) { rc = mdd_changelog_on(env, mdd, 1); if (rc < 0) GOTO(out_uclose, rc); } llog_ctxt_put(ctxt); llog_ctxt_put(uctxt); RETURN(0); out_uclose: llog_cat_close(env, uctxt->loc_handle); out_ucleanup: llog_cleanup(env, uctxt); out_close: llog_cat_close(env, ctxt->loc_handle); out_cleanup: llog_cleanup(env, ctxt); return rc; }
/* Test log and catalogue processing */ static int llog_test_5(const struct lu_env *env, struct obd_device *obd) { struct llog_handle *llh = NULL; char name[10]; int rc, rc2; struct llog_mini_rec lmr; struct llog_ctxt *ctxt; ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE; lmr.lmr_hdr.lrh_type = 0xf00f00; CWARN("5a: re-open catalog by id\n"); rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS); if (rc) { CERROR("5a: llog_create with logid failed: %d\n", rc); GOTO(out_put, rc); } rc = llog_init_handle(env, llh, LLOG_F_IS_CAT, &uuid); if (rc) { CERROR("5a: can't init llog handle: %d\n", rc); GOTO(out, rc); } CWARN("5b: print the catalog entries.. we expect 2\n"); cat_counter = 0; rc = llog_process(env, llh, cat_print_cb, "test 5", NULL); if (rc) { CERROR("5b: process with cat_print_cb failed: %d\n", rc); GOTO(out, rc); } if (cat_counter != 2) { CERROR("5b: %d entries in catalog\n", cat_counter); GOTO(out, rc = -EINVAL); } CWARN("5c: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM); cancel_count = 0; rc = llog_cat_process(env, llh, llog_cancel_rec_cb, "foobar", 0, 0); if (rc != -LLOG_EEMPTY) { CERROR("5c: process with cat_cancel_cb failed: %d\n", rc); GOTO(out, rc); } CWARN("5c: print the catalog entries.. we expect 1\n"); cat_counter = 0; rc = llog_process(env, llh, cat_print_cb, "test 5", NULL); if (rc) { CERROR("5c: process with cat_print_cb failed: %d\n", rc); GOTO(out, rc); } if (cat_counter != 1) { CERROR("5c: %d entries in catalog\n", cat_counter); GOTO(out, rc = -EINVAL); } CWARN("5d: add 1 record to the log with many canceled empty pages\n"); rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL, NULL); if (rc) { CERROR("5d: add record to the log with many canceled empty " "pages failed\n"); GOTO(out, rc); } CWARN("5e: print plain log entries.. expect 6\n"); plain_counter = 0; rc = llog_cat_process(env, llh, plain_print_cb, "foobar", 0, 0); if (rc) { CERROR("5e: process with plain_print_cb failed: %d\n", rc); GOTO(out, rc); } if (plain_counter != 6) { CERROR("5e: found %d records\n", plain_counter); GOTO(out, rc = -EINVAL); } CWARN("5f: print plain log entries reversely.. expect 6\n"); plain_counter = 0; rc = llog_cat_reverse_process(env, llh, plain_print_cb, "foobar"); if (rc) { CERROR("5f: reversely process with plain_print_cb failed:" "%d\n", rc); GOTO(out, rc); } if (plain_counter != 6) { CERROR("5f: found %d records\n", plain_counter); GOTO(out, rc = -EINVAL); } out: CWARN("5g: close re-opened catalog\n"); rc2 = llog_cat_close(env, llh); if (rc2) { CERROR("5g: close log %s failed: %d\n", name, rc2); if (rc == 0) rc = rc2; } out_put: llog_ctxt_put(ctxt); return rc; }
/* Test log and catalogue processing */ static int llog_test_5(struct obd_device *obd) { struct llog_handle *llh = NULL; char name[10]; int rc; struct llog_mini_rec lmr; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); ENTRY; lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE; lmr.lmr_hdr.lrh_type = 0xf00f00; CWARN("5a: re-open catalog by id\n"); rc = llog_create(ctxt, &llh, &cat_logid, NULL); if (rc) { CERROR("5a: llog_create with logid failed: %d\n", rc); GOTO(out, rc); } llog_init_handle(llh, LLOG_F_IS_CAT, &uuid); CWARN("5b: print the catalog entries.. we expect 2\n"); rc = llog_process(llh, cat_print_cb, "test 5", NULL); if (rc) { CERROR("5b: process with cat_print_cb failed: %d\n", rc); GOTO(out, rc); } CWARN("5c: Cancel 40000 records, see one log zapped\n"); rc = llog_cat_process(llh, llog_cancel_rec_cb, "foobar", 0, 0); if (rc != -4711) { CERROR("5c: process with cat_cancel_cb failed: %d\n", rc); GOTO(out, rc); } CWARN("5d: add 1 record to the log with many canceled empty pages\n"); rc = llog_cat_add_rec(llh, &lmr.lmr_hdr, NULL, NULL); if (rc) { CERROR("5d: add record to the log with many canceled empty\ pages failed\n"); GOTO(out, rc); } CWARN("5b: print the catalog entries.. we expect 1\n"); rc = llog_process(llh, cat_print_cb, "test 5", NULL); if (rc) { CERROR("5b: process with cat_print_cb failed: %d\n", rc); GOTO(out, rc); } CWARN("5e: print plain log entries.. expect 6\n"); rc = llog_cat_process(llh, plain_print_cb, "foobar", 0, 0); if (rc) { CERROR("5e: process with plain_print_cb failed: %d\n", rc); GOTO(out, rc); } CWARN("5f: print plain log entries reversely.. expect 6\n"); rc = llog_cat_reverse_process(llh, plain_print_cb, "foobar"); if (rc) { CERROR("5f: reversely process with plain_print_cb failed: %d\n", rc); GOTO(out, rc); } out: CWARN("5: close re-opened catalog\n"); if (llh) rc = llog_cat_put(llh); if (rc) CERROR("1b: close log %s failed: %d\n", name, rc); llog_ctxt_put(ctxt); RETURN(rc); }