Example #1
0
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 lvfs_run_ctxt  saved;
        struct llog_handle   *handle = NULL;
        char                  name[4][64];
        int                   rc, i, l, remains = buf_len;
        char                 *out = buf;
        ENTRY;

        if (ctxt == NULL || mds == NULL)
                GOTO(release_ctxt, rc = -ENODEV);

        push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_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: %llu\n"
                             "Last Index: %d\nUncanceled Records: %d\n\n",
                             name[i],
                             i_size_read(handle->lgh_file->f_dentry->d_inode),
                             handle->lgh_last_idx, uncanceled);
                out += l;
                remains -= l;

                llog_close(handle);
                if (remains <= 0)
                        break;
        }
        GOTO(out_pop, rc);
out_pop:
        pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
release_ctxt:
        llog_ctxt_put(ctxt);
        return rc;
}
Example #2
0
int llog_origin_handle_read_header(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct llog_log_hdr  *hdr;
        struct lvfs_run_ctxt  saved;
        struct llog_ctxt     *ctxt;
        __u32                 flags;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                RETURN(-ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        /*
         * llog_init_handle() reads the llog header
         */
        flags = body->lgd_llh_flags;
        rc = llog_init_handle(loghandle, flags, NULL);
        if (rc)
                GOTO(out_close, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR);
        *hdr = *loghandle->lgh_hdr;
        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
Example #3
0
int llog_origin_handle_destroy(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct lvfs_run_ctxt  saved;
        struct llog_logid    *logid = NULL;
        struct llog_ctxt     *ctxt;
        int                   rc;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        if (body->lgd_logid.lgl_oid > 0)
                logid = &body->lgd_logid;

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                RETURN(-ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        body->lgd_logid = loghandle->lgh_id;
        rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
        if (rc)
                GOTO(out_close, rc);
        rc = llog_destroy(loghandle);
        if (rc)
                GOTO(out_close, rc);
        llog_free_handle(loghandle);
        GOTO(out_close, rc);
out_close:
        if (rc)
                llog_close(loghandle);
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
Example #4
0
/**
 * Helper function to open llog or create it if doesn't exist.
 * It hides all transaction handling from caller.
 */
int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
		     struct llog_handle **res, struct llog_logid *logid,
		     char *name)
{
	struct dt_device	*d;
	struct thandle		*th;
	int			 rc;

	ENTRY;

	rc = llog_open(env, ctxt, res, logid, name, LLOG_OPEN_NEW);
	if (rc)
		RETURN(rc);

	if (llog_exist(*res))
		RETURN(0);

	LASSERT((*res)->lgh_obj != NULL);

	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, d);
	if (IS_ERR(th))
		GOTO(out, rc = PTR_ERR(th));

	/* Create update llog object synchronously, which
	 * happens during inialization process see
	 * lod_sub_prep_llog(), to make sure the update
	 * llog object is created before corss-MDT writing
	 * updates into the llog object */
	if (ctxt->loc_flags & LLOG_CTXT_FLAG_NORMAL_FID)
		th->th_sync = 1;

	th->th_wait_submit = 1;
	rc = llog_declare_create(env, *res, th);
	if (rc == 0) {
		rc = dt_trans_start_local(env, d, th);
		if (rc == 0)
			rc = llog_create(env, *res, th);
	}
	dt_trans_stop(env, d, th);
out:
	if (rc)
		llog_close(env, *res);
	RETURN(rc);
}
Example #5
0
File: llog.c Project: 19Dan01/linux
/**
 * Helper function to open llog or create it if doesn't exist.
 * It hides all transaction handling from caller.
 */
int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
		     struct llog_handle **res, struct llog_logid *logid,
		     char *name)
{
	struct dt_device	*d;
	struct thandle		*th;
	int			 rc;

	rc = llog_open(env, ctxt, res, logid, name, LLOG_OPEN_NEW);
	if (rc)
		return rc;

	if (llog_exist(*res))
		return 0;

	LASSERT((*res)->lgh_obj != NULL);

	d = lu2dt_dev((*res)->lgh_obj->do_lu.lo_dev);

	th = dt_trans_create(env, d);
	if (IS_ERR(th)) {
		rc = PTR_ERR(th);
		goto out;
	}

	rc = llog_declare_create(env, *res, th);
	if (rc == 0) {
		rc = dt_trans_start_local(env, d, th);
		if (rc == 0)
			rc = llog_create(env, *res, th);
	}
	dt_trans_stop(env, d, th);
out:
	if (rc)
		llog_close(env, *res);
	return rc;
}
Example #6
0
static int llog_test_7(struct obd_device *obd)
{
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        struct llog_handle *llh;
        struct llog_create_rec lcr;
        char name[10];
        int rc;
        ENTRY;

        sprintf(name, "%x", llog_test_rand+2);
        CWARN("7: create a log with name: %s\n", name);
        LASSERT(ctxt);

        rc = llog_create(ctxt, &llh, NULL, name);
        if (rc) {
                CERROR("7: llog_create with name %s failed: %d\n", name, rc);
                GOTO(ctxt_release, rc);
        }
        llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid);

        lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = sizeof(lcr);
        lcr.lcr_hdr.lrh_type = OST_SZ_REC;
        rc = llog_write_rec(llh,  &lcr.lcr_hdr, NULL, 0, NULL, -1);
        if (rc) {
                CERROR("7: write one log record failed: %d\n", rc);
                GOTO(ctxt_release, rc);
        }

        rc = llog_destroy(llh);
        if (rc)
                CERROR("7: llog_destroy failed: %d\n", rc);
        else
                llog_free_handle(llh);
ctxt_release:
        llog_ctxt_put(ctxt);
        RETURN(rc);
}
Example #7
0
int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data)
{
        struct llog_logid logid;
        int err = 0;
        struct llog_handle *handle = NULL;

        ENTRY;
        if (*data->ioc_inlbuf1 == '#') {
                err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
                if (err)
                        GOTO(out, err);
                err = llog_create(ctxt, &handle, &logid, NULL);
                if (err)
                        GOTO(out, err);
        } else if (*data->ioc_inlbuf1 == '$') {
                char *name = data->ioc_inlbuf1 + 1;
                err = llog_create(ctxt, &handle, NULL, name);
                if (err)
                        GOTO(out, err);
        } else {
                GOTO(out, err = -EINVAL);
        }

        err = llog_init_handle(handle, 0, NULL);
        if (err)
                GOTO(out_close, err = -ENOENT);

        switch (cmd) {
        case OBD_IOC_LLOG_INFO: {
                int l;
                int remains = data->ioc_inllen2 +
                        cfs_size_round(data->ioc_inllen1);
                char *out = data->ioc_bulk;

                l = snprintf(out, remains,
                             "logid:            #"LPX64"#"LPX64"#%08x\n"
                             "flags:            %x (%s)\n"
                             "records count:    %d\n"
                             "last index:       %d\n",
                             handle->lgh_id.lgl_oid, handle->lgh_id.lgl_oseq,
                             handle->lgh_id.lgl_ogen,
                             handle->lgh_hdr->llh_flags,
                             handle->lgh_hdr->llh_flags &
                             LLOG_F_IS_CAT ? "cat" : "plain",
                             handle->lgh_hdr->llh_count,
                             handle->lgh_last_idx);
                out += l;
                remains -= l;
                if (remains <= 0)
                        CERROR("not enough space for log header info\n");

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CHECK: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, llog_check_cb, data, NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                GOTO(out_close, err);
        }

        case OBD_IOC_LLOG_PRINT: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, class_config_dump_handler,data,NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                else
                        err = llog_process(handle, llog_print_cb, data, NULL);

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CANCEL: {
                struct llog_cookie cookie;
                struct llog_logid plain;
                char *endp;

                cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        GOTO(out_close, err = -EINVAL);

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                        cfs_down_write(&handle->lgh_lock);
                        err = llog_cancel_rec(handle, cookie.lgc_index);
                        cfs_up_write(&handle->lgh_lock);
                        GOTO(out_close, err);
                }

                err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
                if (err)
                        GOTO(out_close, err);
                cookie.lgc_lgl = plain;

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                err = llog_cat_cancel_records(handle, 1, &cookie);
                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_REMOVE: {
                struct llog_logid plain;

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
                        err = llog_destroy(handle);
                        if (!err)
                                llog_free_handle(handle);
                        GOTO(out, err);
                }

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                if (data->ioc_inlbuf2) {
                        /*remove indicate log from the catalog*/
                        err = str2logid(&plain, data->ioc_inlbuf2,
                                        data->ioc_inllen2);
                        if (err)
                                GOTO(out_close, err);
                        err = llog_remove_log(handle, &plain);
                } else {
                        /*remove all the log of the catalog*/
                        llog_process(handle, llog_delete_cb, NULL, NULL);
                }
                GOTO(out_close, err);
        }
        }

out_close:
        if (handle->lgh_hdr &&
            handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
                llog_cat_put(handle);
        else
                llog_close(handle);
out:
        RETURN(err);
}
Example #8
0
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 lvfs_run_ctxt saved;
        int size, i, count;
        struct llog_catid *idarray;
        char name[32] = CATLIST;
        struct cb_data data;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
        int rc;
        ENTRY;

        if (ctxt == NULL || mds == NULL)
                GOTO(release_ctxt, rc = -ENODEV);

        count = mds->mds_lov_desc.ld_tgt_count;
        size = sizeof(*idarray) * count;

        OBD_ALLOC_LARGE(idarray, size);
        if (!idarray)
                GOTO(release_ctxt, rc = -ENOMEM);

        cfs_mutex_lock(&obd->obd_olg.olg_cat_processing);
        rc = llog_get_cat_list(obd, name, 0, count, idarray);
        if (rc)
                GOTO(out_free, rc);

        push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);

        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, &idarray[i].lci_logid, 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",
                             idarray[i].lci_logid.lgl_oid,
                             idarray[i].lci_logid.lgl_oseq,
                             idarray[i].lci_logid.lgl_ogen, uncanceled);

                data.out += l;
                data.remains -= l;
                data.init = 1;

                llog_process(handle, llog_catinfo_cb, &data, NULL);
                llog_close(handle);

                if (data.remains <= 0)
                        break;
        }
        EXIT;
out_pop:
        pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL);
out_free:
        cfs_mutex_unlock(&obd->obd_olg.olg_cat_processing);
        OBD_FREE_LARGE(idarray, size);
release_ctxt:
        llog_ctxt_put(ctxt);
        return rc;
}
Example #9
0
int llog_origin_handle_prev_block(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct llogd_body    *repbody;
        struct obd_device    *disk_obd;
        struct lvfs_run_ctxt  saved;
        struct llog_ctxt     *ctxt;
        __u32                 flags;
        __u8                 *buf;
        void                 *ptr;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
        if (!buf)
                RETURN(-ENOMEM);

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL)
                GOTO(out_free, rc = -ENODEV);

        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL);
        if (rc)
                GOTO(out_pop, rc);

        flags = body->lgd_llh_flags;
        rc = llog_init_handle(loghandle, flags, NULL);
        if (rc)
                GOTO(out_close, rc);

        memset(buf, 0, LLOG_CHUNK_SIZE);
        rc = llog_prev_block(loghandle, body->lgd_index,
                             buf, LLOG_CHUNK_SIZE);
        if (rc)
                GOTO(out_close, rc);

        req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER,
                             LLOG_CHUNK_SIZE);
        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        *repbody = *body;

        ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA);
        memcpy(ptr, buf, LLOG_CHUNK_SIZE);
        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;

out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
out_free:
        OBD_FREE(buf, LLOG_CHUNK_SIZE);
        return rc;
}
Example #10
0
/* Test client api; open log by name and process */
static int llog_test_6(struct obd_device *obd, char *name)
{
        struct obd_device *mgc_obd;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        struct obd_uuid *mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;
        struct obd_export *exp;
        struct obd_uuid uuid = {"LLOG_TEST6_UUID"};
        struct llog_handle *llh = NULL;
        struct llog_ctxt *nctxt;
        int rc;

        CWARN("6a: re-open log %s using client API\n", name);
        mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
        if (mgc_obd == NULL) {
                CERROR("6: no MGC devices connected to %s found.\n",
                       mgs_uuid->uuid);
                GOTO(ctxt_release, rc = -ENOENT);
        }

        rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
                         NULL /* obd_connect_data */, NULL);
        if (rc != -EALREADY) {
                CERROR("6: connect on connected MDC (%s) failed to return"
                       " -EALREADY", mgc_obd->obd_name);
                if (rc == 0)
                        obd_disconnect(exp);
                GOTO(ctxt_release, rc = -EINVAL);
        }

        nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
        rc = llog_create(nctxt, &llh, NULL, name);
        if (rc) {
                CERROR("6: llog_create failed %d\n", rc);
                llog_ctxt_put(nctxt);
                GOTO(ctxt_release, rc);
        }

        rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
        if (rc) {
                CERROR("6: llog_init_handle failed %d\n", rc);
                GOTO(parse_out, rc);
        }

        rc = llog_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_process failed %d\n", rc);

        rc = llog_reverse_process(llh, plain_print_cb, NULL, NULL);
        if (rc)
                CERROR("6: llog_reverse_process failed %d\n", rc);

parse_out:
        rc = llog_close(llh);
        llog_ctxt_put(nctxt);
        if (rc) {
                CERROR("6: llog_close failed: rc = %d\n", rc);
        }
ctxt_release:
        llog_ctxt_put(ctxt);
        RETURN(rc);
}
Example #11
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);
}
Example #12
0
/* Test catalogue additions */
static int llog_test_4(struct obd_device *obd)
{
        struct llog_handle *cath;
        char name[10];
        int rc, i, buflen;
        struct llog_mini_rec lmr;
        struct llog_cookie cookie;
        struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
        int num_recs = 0;
        char *buf;
        struct llog_rec_hdr rec;

        ENTRY;

        lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
        lmr.lmr_hdr.lrh_type = 0xf00f00;

        sprintf(name, "%x", llog_test_rand+1);
        CWARN("4a: create a catalog log with name: %s\n", name);
        rc = llog_create(ctxt, &cath, NULL, name);
        if (rc) {
                CERROR("1a: llog_create with name %s failed: %d\n", name, rc);
                GOTO(out, rc);
        }
        llog_init_handle(cath, LLOG_F_IS_CAT, &uuid);
        num_recs++;
        cat_logid = cath->lgh_id;

        CWARN("4b: write 1 record into the catalog\n");
        rc = llog_cat_add_rec(cath, &lmr.lmr_hdr, &cookie, NULL);
        if (rc != 1) {
                CERROR("4b: write 1 catalog record failed at: %d\n", rc);
                GOTO(out, rc);
        }
        num_recs++;
        if ((rc = verify_handle("4b", cath, 2)))
                GOTO(ctxt_release, rc);

        if ((rc = verify_handle("4b", cath->u.chd.chd_current_log, num_recs)))
                GOTO(ctxt_release, rc);

        CWARN("4c: cancel 1 log record\n");
        rc = llog_cat_cancel_records(cath, 1, &cookie);
        if (rc) {
                CERROR("4c: cancel 1 catalog based record failed: %d\n", rc);
                GOTO(out, rc);
        }
        num_recs--;

        if ((rc = verify_handle("4c", cath->u.chd.chd_current_log, num_recs)))
                GOTO(ctxt_release, rc);

        CWARN("4d: write 40,000 more log records\n");
        for (i = 0; i < 40000; i++) {
                rc = llog_cat_add_rec(cath, &lmr.lmr_hdr, NULL, NULL);
                if (rc) {
                        CERROR("4d: write 40000 records failed at #%d: %d\n",
                               i + 1, rc);
                        GOTO(out, rc);
                }
                num_recs++;
        }

        CWARN("4e: add 5 large records, one record per block\n");
        buflen = LLOG_CHUNK_SIZE - sizeof(struct llog_rec_hdr)
                        - sizeof(struct llog_rec_tail);
        OBD_ALLOC(buf, buflen);
        if (buf == NULL)
                GOTO(out, rc = -ENOMEM);
        for (i = 0; i < 5; i++) {
                rec.lrh_len = buflen;
                rec.lrh_type = OBD_CFG_REC;
                rc = llog_cat_add_rec(cath, &rec, NULL, buf);
                if (rc) {
                        CERROR("4e: write 5 records failed at #%d: %d\n",
                               i + 1, rc);
                        OBD_FREE(buf, buflen);
                        GOTO(out, rc);
                }
                num_recs++;
        }
        OBD_FREE(buf, buflen);

 out:
        CWARN("4f: put newly-created catalog\n");
        rc = llog_cat_put(cath);
ctxt_release:
        llog_ctxt_put(ctxt);
        if (rc)
                CERROR("1b: close log %s failed: %d\n", name, rc);
        RETURN(rc);
}