Пример #1
0
static int mdd_changelog_users_seq_show(struct seq_file *m, void *data)
{
    struct lu_env		 env;
    struct mdd_device	*mdd = m->private;
    struct llog_ctxt	*ctxt;
    __u64			 cur;
    int			 rc;

    ctxt = llog_get_context(mdd2obd_dev(mdd),
                            LLOG_CHANGELOG_USER_ORIG_CTXT);
    if (ctxt == NULL)
        return -ENXIO;
    LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

    rc = lu_env_init(&env, LCT_LOCAL);
    if (rc) {
        llog_ctxt_put(ctxt);
        return rc;
    }

    spin_lock(&mdd->mdd_cl.mc_lock);
    cur = mdd->mdd_cl.mc_index;
    spin_unlock(&mdd->mdd_cl.mc_lock);

    seq_printf(m, "current index: %llu\n", cur);
    seq_printf(m, "%-5s %s\n", "ID", "index");

    llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb,
                     m, 0, 0);

    lu_env_fini(&env);
    llog_ctxt_put(ctxt);
    return 0;
}
Пример #2
0
static int mdd_changelog_user_purge(const struct lu_env *env,
                                    struct mdd_device *mdd, int id,
                                    long long endrec)
{
        struct mdd_changelog_user_data data;
        struct llog_ctxt *ctxt;
        int rc;
        ENTRY;

        CDEBUG(D_IOCTL, "Purge request: id=%d, endrec=%lld\n", id, endrec);

        data.mcud_id = id;
        data.mcud_minid = 0;
        data.mcud_minrec = 0;
        data.mcud_usercount = 0;
        data.mcud_endrec = endrec;
	spin_lock(&mdd->mdd_cl.mc_lock);
	endrec = mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);
        if ((data.mcud_endrec == 0) ||
            ((data.mcud_endrec > endrec) &&
             (data.mcud_endrec != MCUD_UNREGISTER)))
                data.mcud_endrec = endrec;

        ctxt = llog_get_context(mdd2obd_dev(mdd),
				LLOG_CHANGELOG_USER_ORIG_CTXT);
        if (ctxt == NULL)
                return -ENXIO;

        LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

	rc = llog_cat_process(env, ctxt->loc_handle,
			      mdd_changelog_user_purge_cb, (void *)&data,
			      0, 0);
        if ((rc >= 0) && (data.mcud_minrec > 0)) {
                CDEBUG(D_IOCTL, "Purging changelog entries up to "LPD64
                       ", referenced by "CHANGELOG_USER_PREFIX"%d\n",
                       data.mcud_minrec, data.mcud_minid);
		rc = mdd_changelog_llog_cancel(env, mdd, data.mcud_minrec);
        } else {
                CWARN("Could not determine changelog records to purge; rc=%d\n",
                      rc);
        }

        llog_ctxt_put(ctxt);

        if (!data.mcud_found) {
                CWARN("No entry for user %d.  Last changelog reference is "
                      LPD64" by changelog user %d\n", data.mcud_id,
                      data.mcud_minrec, data.mcud_minid);
               rc = -ENOENT;
        }

        if (!rc && data.mcud_usercount == 0)
                /* No more users; turn changelogs off */
                rc = mdd_changelog_on(env, mdd, 0);

        RETURN (rc);
}
Пример #3
0
static int lprocfs_rd_changelog_users(char *page, char **start, off_t off,
                                      int count, int *eof, void *data)
{
	struct lu_env		 env;
	struct mdd_device	*mdd = data;
	struct llog_ctxt	*ctxt;
	struct cucb_data	 cucb;
	__u64			 cur;
	int			 rc;

        *eof = 1;

        ctxt = llog_get_context(mdd2obd_dev(mdd),
				LLOG_CHANGELOG_USER_ORIG_CTXT);
        if (ctxt == NULL)
                return -ENXIO;
        LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

	rc = lu_env_init(&env, LCT_LOCAL);
	if (rc) {
		llog_ctxt_put(ctxt);
		return rc;
	}

	spin_lock(&mdd->mdd_cl.mc_lock);
	cur = mdd->mdd_cl.mc_index;
	spin_unlock(&mdd->mdd_cl.mc_lock);

        cucb.count = count;
        cucb.page = page;
        cucb.idx = 0;

        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
                              "current index: "LPU64"\n", cur);

        cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx,
                              "%-5s %s\n", "ID", "index");

	llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb,
			 &cucb, 0, 0);

	lu_env_fini(&env);
	llog_ctxt_put(ctxt);
	return cucb.idx;
}
Пример #4
0
static int llog_changelog_cancel(struct llog_ctxt *ctxt,
                                 struct lov_stripe_md *lsm, int count,
                                 struct llog_cookie *cookies, int flags)
{
        struct llog_handle *cathandle = ctxt->loc_handle;
        int rc;
        ENTRY;

        /* This should only be called with the catalog handle */
        LASSERT(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

        rc = llog_cat_process(cathandle, llog_changelog_cancel_cb,
                              (void *)cookies, 0, 0);
        if (rc >= 0)
                /* 0 or 1 means we're done */
                rc = 0;
        else
                CERROR("cancel idx %u of catalog "LPX64" rc=%d\n",
                       cathandle->lgh_last_idx, cathandle->lgh_id.lgl_oid, rc);

        RETURN(rc);
}
Пример #5
0
static int llog_changelog_cancel(const struct lu_env *env,
				 struct llog_ctxt *ctxt,
				 struct llog_cookie *cookies, int flags)
{
	struct llog_handle	*cathandle = ctxt->loc_handle;
	int			 rc;

	ENTRY;

	/* This should only be called with the catalog handle */
	LASSERT(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);

	rc = llog_cat_process(env, cathandle, llog_changelog_cancel_cb,
			      (void *)cookies, 0, 0);
	if (rc >= 0)
		/* 0 or 1 means we're done */
		rc = 0;
	else
		CERROR("%s: cancel idx %u of catalog "DOSTID" rc=%d\n",
		       ctxt->loc_obd->obd_name, cathandle->lgh_last_idx,
		       POSTID(&cathandle->lgh_id.lgl_oi), rc);

	RETURN(rc);
}
Пример #6
0
/* 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;
}
Пример #7
0
/* 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);
}
Пример #8
0
static int llog_test_8(const struct lu_env *env, struct obd_device *obd)
{
	struct llog_handle	*llh = NULL;
	char			 name[10];
	int			 rc, rc2, i;
	int			 orig_counter;
	struct llog_mini_rec	 lmr;
	struct llog_ctxt	*ctxt;
	struct dt_object	*obj = NULL;

	ENTRY;

	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("8a: fill the first plain llog\n");
	rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("8a: 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("8a: can't init llog handle: %d\n", rc);
		GOTO(out, rc);
	}

	plain_counter = 0;
	rc = llog_cat_process(env, llh, test_8_cb, "foobar", 0, 0);
	if (rc != 0) {
		CERROR("5a: process with test_8_cb failed: %d\n", rc);
		GOTO(out, rc);
	}
	orig_counter = plain_counter;

	for (i = 0; i < 100; i++) {
		rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL);
		if (rc) {
			CERROR("5a: add record failed\n");
			GOTO(out, rc);
		}
	}

	/* grab the current plain llog, we'll corrupt it later */
	obj = llh->u.chd.chd_current_log->lgh_obj;
	LASSERT(obj);
	lu_object_get(&obj->do_lu);
	CWARN("8a: pin llog "DFID"\n", PFID(lu_object_fid(&obj->do_lu)));

	rc2 = llog_cat_close(env, llh);
	if (rc2) {
		CERROR("8a: close log %s failed: %d\n", name, rc2);
		if (rc == 0)
			rc = rc2;
		GOTO(out_put, rc);
	}

	CWARN("8b: fill the second plain llog\n");
	rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("8b: 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("8b: can't init llog handle: %d\n", rc);
		GOTO(out, rc);
	}

	for (i = 0; i < 100; i++) {
		rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL);
		if (rc) {
			CERROR("8b: add record failed\n");
			GOTO(out, rc);
		}
	}
	CWARN("8b: second llog "DFID"\n",
		PFID(lu_object_fid(&llh->u.chd.chd_current_log->lgh_obj->do_lu)));

	rc2 = llog_cat_close(env, llh);
	if (rc2) {
		CERROR("8b: close log %s failed: %d\n", name, rc2);
		if (rc == 0)
			rc = rc2;
		GOTO(out_put, rc);
	}

	CWARN("8c: drop two records from the first plain llog\n");
	llog_truncate(env, obj);

	CWARN("8d: count survived records\n");
	rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
	if (rc) {
		CERROR("8d: 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("8d: can't init llog handle: %d\n", rc);
		GOTO(out, rc);
	}

	plain_counter = 0;
	rc = llog_cat_process(env, llh, test_8_cb, "foobar", 0, 0);
	if (rc != 0) {
		CERROR("8d: process with test_8_cb failed: %d\n", rc);
		GOTO(out, rc);
	}

	if (orig_counter + 200 - 2 != plain_counter) {
		CERROR("found %d records (expected %d)\n", plain_counter,
		       orig_counter + 200 - 2);
		rc = -EIO;
	}

out:
	CWARN("8d: close re-opened catalog\n");
	rc2 = llog_cat_close(env, llh);
	if (rc2) {
		CERROR("8d: close log %s failed: %d\n", name, rc2);
		if (rc == 0)
			rc = rc2;
	}
out_put:
	llog_ctxt_put(ctxt);

	if (obj != NULL)
		lu_object_put(env, &obj->do_lu);

	RETURN(rc);
}