4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2015, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/llog_test.c
38 * Author: Phil Schwan <phil@clusterfs.com>
39 * Author: Mikhail Pershin <mike.pershin@intel.com>
42 #define DEBUG_SUBSYSTEM S_CLASS
44 #include <linux/module.h>
45 #include <linux/init.h>
47 #include <obd_class.h>
48 #include <lustre_fid.h>
49 #include <lustre_log.h>
51 /* This is slightly more than the number of records that can fit into a
52 * single llog file, because the llog_log_header takes up some of the
53 * space in the first block that cannot be used for the bitmap. */
54 #define LLOG_TEST_RECNUM (LLOG_MIN_CHUNK_SIZE * 8)
56 static int llog_test_rand;
57 static struct obd_uuid uuid = { .uuid = "test_uuid" };
58 static struct llog_logid cat_logid;
60 struct llog_mini_rec {
61 struct llog_rec_hdr lmr_hdr;
62 struct llog_rec_tail lmr_tail;
63 } __attribute__((packed));
65 static int verify_handle(char *test, struct llog_handle *llh, int num_recs)
71 for (i = 0; i < LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr); i++) {
72 if (ext2_test_bit(i, LLOG_HDR_BITMAP(llh->lgh_hdr))) {
78 /* check the llog is sane at first, llh_count and lgh_last_idx*/
79 if (llh->lgh_hdr->llh_count != active_recs) {
80 CERROR("%s: handle->count is %d, but there are %d recs found\n",
81 test, llh->lgh_hdr->llh_count, active_recs);
85 if (llh->lgh_last_idx != LLOG_HDR_TAIL(llh->lgh_hdr)->lrt_index ||
86 (!(llh->lgh_hdr->llh_flags & LLOG_F_IS_CAT) &&
87 llh->lgh_last_idx < last_idx)) {
88 CERROR("%s: lgh_last_idx is %d (%d in the header), last found %d\n",
89 test, llh->lgh_last_idx,
90 LLOG_HDR_TAIL(llh->lgh_hdr)->lrt_index, last_idx);
94 /* finally checks against expected value from the caller */
95 if (active_recs != num_recs) {
96 CERROR("%s: expected %d active recs after write, found %d\n",
97 test, num_recs, active_recs);
104 /* Test named-log create/open, close */
105 static int llog_test_1(const struct lu_env *env,
106 struct obd_device *obd, char *name)
108 struct llog_handle *llh;
109 struct llog_ctxt *ctxt;
115 CWARN("1a: create a log with name: %s\n", name);
116 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
119 rc = llog_open_create(env, ctxt, &llh, NULL, name);
121 CERROR("1a: llog_create with name %s failed: %d\n", name, rc);
124 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, &uuid);
126 CERROR("1a: can't init llog handle: %d\n", rc);
130 rc = verify_handle("1", llh, 1);
132 CWARN("1b: close newly-created log\n");
134 rc2 = llog_close(env, llh);
136 CERROR("1b: close log %s failed: %d\n", name, rc2);
145 static int test_2_cancel_cb(const struct lu_env *env, struct llog_handle *llh,
146 struct llog_rec_hdr *rec, void *data)
148 return LLOG_DEL_RECORD;
151 /* Test named-log reopen; returns opened log on success */
152 static int llog_test_2(const struct lu_env *env, struct obd_device *obd,
153 char *name, struct llog_handle **llh)
155 struct llog_ctxt *ctxt;
156 struct llog_handle *lgh;
157 struct llog_logid logid;
159 struct llog_mini_rec lmr;
163 CWARN("2a: re-open a log with name: %s\n", name);
164 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
167 rc = llog_open(env, ctxt, llh, NULL, name, LLOG_OPEN_EXISTS);
169 CERROR("2a: re-open log with name %s failed: %d\n", name, rc);
173 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &uuid);
175 CERROR("2a: can't init llog handle: %d\n", rc);
176 GOTO(out_close_llh, rc);
179 rc = verify_handle("2", *llh, 1);
181 GOTO(out_close_llh, rc);
183 CWARN("2b: create a log without specified NAME & LOGID\n");
184 rc = llog_open_create(env, ctxt, &lgh, NULL, NULL);
186 CERROR("2b: create log failed\n");
187 GOTO(out_close_llh, rc);
189 rc = llog_init_handle(env, lgh, LLOG_F_IS_PLAIN, &uuid);
191 CERROR("2b: can't init llog handle: %d\n", rc);
197 lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
198 lmr.lmr_hdr.lrh_type = 0xf02f02;
200 /* Check llog header values are correct after record add/cancel */
201 CWARN("2b: write 1 llog records, check llh_count\n");
202 rc = llog_write(env, lgh, &lmr.lmr_hdr, LLOG_NEXT_IDX);
206 /* in-memory values after record addition */
207 rc = verify_handle("2b", lgh, 2);
211 /* re-open llog to read on-disk values */
212 llog_close(env, lgh);
214 CWARN("2c: re-open the log by LOGID and verify llh_count\n");
215 rc = llog_open(env, ctxt, &lgh, &logid, NULL, LLOG_OPEN_EXISTS);
217 CERROR("2c: re-open log by LOGID failed\n");
218 GOTO(out_close_llh, rc);
221 rc = llog_init_handle(env, lgh, LLOG_F_IS_PLAIN, &uuid);
223 CERROR("2c: can't init llog handle: %d\n", rc);
227 /* check values just read from disk */
228 rc = verify_handle("2c", lgh, 2);
232 rc = llog_process(env, lgh, test_2_cancel_cb, NULL, NULL);
236 /* in-memory values */
237 rc = verify_handle("2c", lgh, 1);
241 /* re-open llog to get on-disk values */
242 llog_close(env, lgh);
244 rc = llog_open(env, ctxt, &lgh, &logid, NULL, LLOG_OPEN_EXISTS);
246 CERROR("2c: re-open log by LOGID failed\n");
247 GOTO(out_close_llh, rc);
250 rc = llog_init_handle(env, lgh, LLOG_F_IS_PLAIN, &uuid);
252 CERROR("2c: can't init llog handle: %d\n", rc);
256 /* on-disk values after llog re-open */
257 rc = verify_handle("2c", lgh, 1);
261 CWARN("2d: destroy this log\n");
262 rc = llog_destroy(env, lgh);
264 CERROR("2d: destroy log failed\n");
266 llog_close(env, lgh);
269 llog_close(env, *llh);
276 static int test_3_rec_num;
277 static off_t test_3_rec_off;
278 static int test_3_paddings;
279 static int test_3_start_idx;
283 * - check lgh_cur_offset correctness
284 * - check record index consistency
285 * - modify each record in-place
286 * - add new record during *last_idx processing
288 static int test3_check_n_add_cb(const struct lu_env *env,
289 struct llog_handle *lgh,
290 struct llog_rec_hdr *rec, void *data)
292 struct llog_gen_rec *lgr = (struct llog_gen_rec *)rec;
293 int *last_rec = data;
294 unsigned cur_idx = test_3_start_idx + test_3_rec_num;
297 if (lgh->lgh_hdr->llh_flags & LLOG_F_IS_FIXSIZE) {
298 LASSERT(lgh->lgh_hdr->llh_size > 0);
299 if (lgh->lgh_cur_offset != lgh->lgh_hdr->llh_hdr.lrh_len +
300 (cur_idx - 1) * lgh->lgh_hdr->llh_size)
301 CERROR("Wrong record offset in cur_off: %llu, should be %u\n",
303 lgh->lgh_hdr->llh_hdr.lrh_len +
304 (cur_idx - 1) * lgh->lgh_hdr->llh_size);
306 size_t chunk_size = lgh->lgh_hdr->llh_hdr.lrh_len;
308 /* For variable size records the start offset is unknown, trust
309 * the first value and check others are consistent with it. */
310 if (test_3_rec_off == 0)
311 test_3_rec_off = lgh->lgh_cur_offset;
313 if (lgh->lgh_cur_offset != test_3_rec_off) {
314 __u64 tmp = lgh->lgh_cur_offset;
316 /* there can be padding record */
317 if ((do_div(tmp, chunk_size) == 0) &&
318 (lgh->lgh_cur_offset - test_3_rec_off <
319 rec->lrh_len + LLOG_MIN_REC_SIZE)) {
320 test_3_rec_off = lgh->lgh_cur_offset;
323 CERROR("Wrong record offset in cur_off: %llu"
324 ", should be %lld (rec len %u)\n",
326 (long long)test_3_rec_off,
330 test_3_rec_off += rec->lrh_len;
333 cur_idx += test_3_paddings;
334 if (cur_idx != rec->lrh_index)
335 CERROR("Record with wrong index was read: %u, expected %u\n",
336 rec->lrh_index, cur_idx);
338 /* modify all records in place */
339 lgr->lgr_gen.conn_cnt = rec->lrh_index;
340 rc = llog_write(env, lgh, rec, rec->lrh_index);
342 CERROR("cb_test_3: cannot modify record while processing\n");
344 /* Add new record to the llog at *last_rec position one by one to
345 * check that last block is re-read during processing */
346 if (cur_idx == *last_rec || cur_idx == (*last_rec + 1)) {
347 rc = llog_write(env, lgh, rec, LLOG_NEXT_IDX);
349 CERROR("cb_test_3: cannot add new record while "
357 /* Check in-place modifications were done for all records*/
358 static int test3_check_cb(const struct lu_env *env, struct llog_handle *lgh,
359 struct llog_rec_hdr *rec, void *data)
361 struct llog_gen_rec *lgr = (struct llog_gen_rec *)rec;
363 if (lgr->lgr_gen.conn_cnt != rec->lrh_index) {
364 CERROR("cb_test_3: record %u is not modified\n",
372 static int llog_test3_process(const struct lu_env *env,
373 struct llog_handle *lgh,
374 llog_cb_t cb, int start)
376 struct llog_process_cat_data cd;
377 int last_idx; /* new record will be injected here */
380 CWARN("test3: processing records from index %d to the end\n",
382 cd.lpcd_first_idx = start - 1;
383 cd.lpcd_last_idx = 0;
384 test_3_rec_num = test_3_paddings = 0;
385 last_idx = lgh->lgh_last_idx;
386 rc = llog_process(env, lgh, cb, &last_idx, &cd);
389 CWARN("test3: total %u records processed with %u paddings\n",
390 test_3_rec_num, test_3_paddings);
391 return test_3_rec_num;
394 /* Test plain llog functionality */
395 static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
396 struct llog_handle *llh)
399 struct llog_rec_hdr *hdr = (void *)buf;
401 int num_recs = 1; /* 1 for the header */
406 hdr->lrh_len = sizeof(struct llog_gen_rec);
407 hdr->lrh_type = LLOG_GEN_REC;
408 llh->lgh_hdr->llh_size = sizeof(struct llog_gen_rec);
409 llh->lgh_hdr->llh_flags |= LLOG_F_IS_FIXSIZE;
411 /* Fill the llog with 64-bytes records, use 1023 records,
412 * so last chunk will be partially full. Don't change this
413 * value until record size is changed.
415 CWARN("3a: write 1023 fixed-size llog records\n");
416 for (i = 0; i < 1023; i++) {
417 rc = llog_write(env, llh, hdr, LLOG_NEXT_IDX);
419 CERROR("3a: write 1023 records failed at #%d: %d\n",
426 rc = verify_handle("3a", llh, num_recs);
431 * Test fixed-size records processing:
432 * - search the needed index
433 * - go through all records from that index
434 * - check all indices are growing monotonically and exist
435 * - modify each record
437 * NB: test3_check_n_add adds two new records while processing
438 * after last record. There were 1023 records created so the last chunk
439 * misses exactly one record. Therefore one of new records will be
440 * the last in the current chunk and second causes the new chunk to be
444 test_3_start_idx = 501;
446 rc = llog_test3_process(env, llh, test3_check_n_add_cb,
451 /* extra record is created during llog_process() */
452 if (rc != expected) {
453 CERROR("3a: process total %d records but expect %d\n",
460 /* test modification in place */
461 rc = llog_test3_process(env, llh, test3_check_cb, test_3_start_idx);
465 if (rc != expected) {
466 CERROR("3a: process total %d records but expect %d\n",
471 CWARN("3b: write 566 variable size llog records\n");
473 /* Drop llh_size to 0 to mark llog as variable-size and write
474 * header to make this change permanent. */
475 llh->lgh_hdr->llh_flags &= ~LLOG_F_IS_FIXSIZE;
476 llog_write(env, llh, &llh->lgh_hdr->llh_hdr, LLOG_HEADER_IDX);
478 hdr->lrh_type = OBD_CFG_REC;
480 /* there are 1025 64-bytes records in llog already,
481 * the last chunk contains single record, i.e. 64 bytes.
482 * Each pair of variable size records is 200 bytes, so
483 * we will have the following distribution per chunks:
484 * block 1: 64 + 80(80/120) + 80 + 48(pad) = 81 iterations
485 * block 2: 80(120/80) + 120 + 72(pad) = 81 itereations
486 * block 3: 80(80/120) + 80 + 112(pad) = 81 iterations
487 * -- the same as block 2 again and so on.
488 * block 7: 80(80/120) = 80 iterations and 192 bytes remain
489 * Total 6 * 81 + 80 = 566 itereations.
490 * Callback will add another 120 bytes in the end of the last chunk
491 * and another 120 bytes will cause padding (72 bytes) plus 120
492 * bytes in the new block.
494 for (i = 0; i < 566; i++) {
500 rc = llog_write(env, llh, hdr, LLOG_NEXT_IDX);
502 CERROR("3b: write 566 records failed at #%d: %d\n",
509 rc = verify_handle("3b", llh, num_recs);
513 test_3_start_idx = 1026;
515 rc = llog_test3_process(env, llh, test3_check_n_add_cb,
520 if (rc != expected) {
521 CERROR("3b: process total %d records but expect %d\n",
528 /* test modification in place */
529 rc = llog_test3_process(env, llh, test3_check_cb, test_3_start_idx);
533 if (rc != expected) {
534 CERROR("3b: process total %d records but expect %d\n",
539 CWARN("3c: write records with variable size until BITMAP_SIZE, "
541 while (num_recs < LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr)) {
542 if ((num_recs % 2) == 0)
547 rc = llog_write(env, llh, hdr, LLOG_NEXT_IDX);
551 CERROR("3c: write recs failed at #%d: %d\n",
559 CWARN("3c: write record more than BITMAP size!\n");
562 CWARN("3c: wrote %d more records before end of llog is reached\n",
565 rc = verify_handle("3c", llh, num_recs);
570 /* Test catalogue additions */
571 static int llog_test_4(const struct lu_env *env, struct obd_device *obd)
573 struct llog_handle *cath;
575 int rc, rc2, i, buflen;
576 struct llog_mini_rec lmr;
577 struct llog_cookie cookie;
578 struct llog_ctxt *ctxt;
581 struct llog_rec_hdr *rec;
585 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
588 lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
589 lmr.lmr_hdr.lrh_type = 0xf00f00;
591 sprintf(name, "%x", llog_test_rand + 1);
592 CWARN("4a: create a catalog log with name: %s\n", name);
593 rc = llog_open_create(env, ctxt, &cath, NULL, name);
595 CERROR("4a: llog_create with name %s failed: %d\n", name, rc);
596 GOTO(ctxt_release, rc);
598 rc = llog_init_handle(env, cath, LLOG_F_IS_CAT, &uuid);
600 CERROR("4a: can't init llog handle: %d\n", rc);
605 cat_logid = cath->lgh_id;
607 CWARN("4b: write 1 record into the catalog\n");
608 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, &cookie);
610 CERROR("4b: write 1 catalog record failed at: %d\n", rc);
614 rc = verify_handle("4b", cath, 2);
618 rc = verify_handle("4b", cath->u.chd.chd_current_log, num_recs);
622 CWARN("4c: cancel 1 log record\n");
623 rc = llog_cat_cancel_records(env, cath, 1, &cookie);
625 CERROR("4c: cancel 1 catalog based record failed: %d\n", rc);
630 rc = verify_handle("4c", cath->u.chd.chd_current_log, num_recs);
634 CWARN("4d: write %d more log records\n", LLOG_TEST_RECNUM);
635 for (i = 0; i < LLOG_TEST_RECNUM; i++) {
636 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
638 CERROR("4d: write %d records failed at #%d: %d\n",
639 LLOG_TEST_RECNUM, i + 1, rc);
645 /* make sure new plain llog appears */
646 rc = verify_handle("4d", cath, 3);
650 CWARN("4e: add 5 large records, one record per block\n");
651 buflen = LLOG_MIN_CHUNK_SIZE;
652 OBD_ALLOC(buf, buflen);
654 GOTO(out, rc = -ENOMEM);
655 for (i = 0; i < 5; i++) {
657 rec->lrh_len = buflen;
658 rec->lrh_type = OBD_CFG_REC;
659 rc = llog_cat_add(env, cath, rec, NULL);
661 CERROR("4e: write 5 records failed at #%d: %d\n",
668 OBD_FREE(buf, buflen);
670 CWARN("4f: put newly-created catalog\n");
671 rc2 = llog_cat_close(env, cath);
673 CERROR("4: close log %s failed: %d\n", name, rc2);
682 static int cat_counter;
684 static int cat_print_cb(const struct lu_env *env, struct llog_handle *llh,
685 struct llog_rec_hdr *rec, void *data)
687 struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
688 struct lu_fid fid = {0};
690 if (rec->lrh_type != LLOG_LOGID_MAGIC) {
691 CERROR("invalid record in catalog\n");
695 logid_to_fid(&lir->lid_id, &fid);
697 CWARN("seeing record at index %d - "DFID" in log "DFID"\n",
698 rec->lrh_index, PFID(&fid),
699 PFID(lu_object_fid(&llh->lgh_obj->do_lu)));
706 static int plain_counter;
708 static int plain_print_cb(const struct lu_env *env, struct llog_handle *llh,
709 struct llog_rec_hdr *rec, void *data)
711 struct lu_fid fid = {0};
713 if (!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN)) {
714 CERROR("log is not plain\n");
718 logid_to_fid(&llh->lgh_id, &fid);
720 CDEBUG(D_INFO, "seeing record at index %d in log "DFID"\n",
721 rec->lrh_index, PFID(&fid));
728 static int cancel_count;
730 static int llog_cancel_rec_cb(const struct lu_env *env,
731 struct llog_handle *llh,
732 struct llog_rec_hdr *rec, void *data)
734 struct llog_cookie cookie;
736 if (!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN)) {
737 CERROR("log is not plain\n");
741 cookie.lgc_lgl = llh->lgh_id;
742 cookie.lgc_index = rec->lrh_index;
744 llog_cat_cancel_records(env, llh->u.phd.phd_cat_handle, 1, &cookie);
746 if (cancel_count == LLOG_TEST_RECNUM)
747 RETURN(-LLOG_EEMPTY);
751 /* Test log and catalogue processing */
752 static int llog_test_5(const struct lu_env *env, struct obd_device *obd)
754 struct llog_handle *llh = NULL;
757 struct llog_mini_rec lmr;
758 struct llog_ctxt *ctxt;
762 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
765 lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
766 lmr.lmr_hdr.lrh_type = 0xf00f00;
768 CWARN("5a: re-open catalog by id\n");
769 rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
771 CERROR("5a: llog_create with logid failed: %d\n", rc);
775 rc = llog_init_handle(env, llh, LLOG_F_IS_CAT, &uuid);
777 CERROR("5a: can't init llog handle: %d\n", rc);
781 CWARN("5b: print the catalog entries.. we expect 2\n");
783 rc = llog_process(env, llh, cat_print_cb, "test 5", NULL);
785 CERROR("5b: process with cat_print_cb failed: %d\n", rc);
788 if (cat_counter != 2) {
789 CERROR("5b: %d entries in catalog\n", cat_counter);
790 GOTO(out, rc = -EINVAL);
793 CWARN("5c: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
795 rc = llog_cat_process(env, llh, llog_cancel_rec_cb, "foobar", 0, 0);
796 if (rc != -LLOG_EEMPTY) {
797 CERROR("5c: process with llog_cancel_rec_cb failed: %d\n", rc);
801 CWARN("5c: print the catalog entries.. we expect 1\n");
803 rc = llog_process(env, llh, cat_print_cb, "test 5", NULL);
805 CERROR("5c: process with cat_print_cb failed: %d\n", rc);
808 if (cat_counter != 1) {
809 CERROR("5c: %d entries in catalog\n", cat_counter);
810 GOTO(out, rc = -EINVAL);
813 CWARN("5d: add 1 record to the log with many canceled empty pages\n");
814 rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL);
816 CERROR("5d: add record to the log with many canceled empty "
821 CWARN("5e: print plain log entries.. expect 6\n");
823 rc = llog_cat_process(env, llh, plain_print_cb, "foobar", 0, 0);
825 CERROR("5e: process with plain_print_cb failed: %d\n", rc);
828 if (plain_counter != 6) {
829 CERROR("5e: found %d records\n", plain_counter);
830 GOTO(out, rc = -EINVAL);
833 CWARN("5f: print plain log entries reversely.. expect 6\n");
835 rc = llog_cat_reverse_process(env, llh, plain_print_cb, "foobar");
837 CERROR("5f: reversely process with plain_print_cb failed: "
841 if (plain_counter != 6) {
842 CERROR("5f: found %d records\n", plain_counter);
843 GOTO(out, rc = -EINVAL);
847 CWARN("5g: close re-opened catalog\n");
848 rc2 = llog_cat_close(env, llh);
850 CERROR("5g: close log %s failed: %d\n", name, rc2);
860 /* Test client api; open log by name and process */
861 static int llog_test_6(const struct lu_env *env, struct obd_device *obd,
864 struct obd_device *mgc_obd;
865 struct llog_ctxt *ctxt;
866 struct obd_uuid *mgs_uuid;
867 struct obd_export *exp;
868 struct obd_uuid uuid = { "LLOG_TEST6_UUID" };
869 struct llog_handle *llh = NULL;
870 struct llog_ctxt *nctxt;
873 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
875 mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid;
877 CWARN("6a: re-open log %s using client API\n", name);
878 mgc_obd = class_find_client_obd(mgs_uuid, LUSTRE_MGC_NAME, NULL);
879 if (mgc_obd == NULL) {
880 CERROR("6a: no MGC devices connected to %s found.\n",
882 GOTO(ctxt_release, rc = -ENOENT);
885 rc = obd_connect(NULL, &exp, mgc_obd, &uuid,
886 NULL /* obd_connect_data */, NULL);
887 if (rc != -EALREADY) {
888 CERROR("6a: connect on connected MGC (%s) failed to return"
889 " -EALREADY\n", mgc_obd->obd_name);
892 GOTO(ctxt_release, rc = -EINVAL);
895 nctxt = llog_get_context(mgc_obd, LLOG_CONFIG_REPL_CTXT);
896 rc = llog_open(env, nctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
898 CERROR("6a: llog_open failed %d\n", rc);
902 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
904 CERROR("6a: llog_init_handle failed %d\n", rc);
908 plain_counter = 1; /* llog header is first record */
909 CWARN("6b: process log %s using client API\n", name);
910 rc = llog_process(env, llh, plain_print_cb, NULL, NULL);
912 CERROR("6b: llog_process failed %d\n", rc);
913 CWARN("6b: processed %d records\n", plain_counter);
915 rc = verify_handle("6b", llh, plain_counter);
919 plain_counter = 1; /* llog header is first record */
920 CWARN("6c: process log %s reversely using client API\n", name);
921 rc = llog_reverse_process(env, llh, plain_print_cb, NULL, NULL);
923 CERROR("6c: llog_reverse_process failed %d\n", rc);
924 CWARN("6c: processed %d records\n", plain_counter);
926 rc = verify_handle("6c", llh, plain_counter);
931 rc2 = llog_close(env, llh);
933 CERROR("6: llog_close failed: rc = %d\n", rc2);
938 llog_ctxt_put(nctxt);
945 struct llog_rec_hdr lrh; /* common header */
946 struct llog_logid_rec llr; /* LLOG_LOGID_MAGIC */
947 struct llog_unlink64_rec lur; /* MDS_UNLINK64_REC */
948 struct llog_setattr64_rec lsr64; /* MDS_SETATTR64_REC */
949 struct llog_size_change_rec lscr; /* OST_SZ_REC */
950 struct llog_changelog_rec lcr; /* CHANGELOG_REC */
951 struct llog_changelog_user_rec lcur; /* CHANGELOG_USER_REC */
952 struct llog_gen_rec lgr; /* LLOG_GEN_REC */
955 static int test_7_print_cb(const struct lu_env *env, struct llog_handle *llh,
956 struct llog_rec_hdr *rec, void *data)
958 struct lu_fid fid = {0};
960 logid_to_fid(&llh->lgh_id, &fid);
962 CDEBUG(D_OTHER, "record type %#x at index %d in log "DFID"\n",
963 rec->lrh_type, rec->lrh_index, PFID(&fid));
969 static int test_7_cancel_cb(const struct lu_env *env, struct llog_handle *llh,
970 struct llog_rec_hdr *rec, void *data)
973 /* test LLOG_DEL_RECORD is working */
974 return LLOG_DEL_RECORD;
977 static int llog_test_7_sub(const struct lu_env *env, struct llog_ctxt *ctxt)
979 struct llog_handle *llh;
980 int rc = 0, i, process_count;
985 rc = llog_open_create(env, ctxt, &llh, NULL, NULL);
987 CERROR("7_sub: create log failed\n");
991 rc = llog_init_handle(env, llh,
992 LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY,
995 CERROR("7_sub: can't init llog handle: %d\n", rc);
998 for (i = 0; i < LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr); i++) {
999 rc = llog_write(env, llh, &llog_records.lrh, LLOG_NEXT_IDX);
1000 if (rc == -ENOSPC) {
1002 } else if (rc < 0) {
1003 CERROR("7_sub: write recs failed at #%d: %d\n",
1005 GOTO(out_close, rc);
1009 if (rc != -ENOSPC) {
1010 CWARN("7_sub: write record more than BITMAP size!\n");
1011 GOTO(out_close, rc = -EINVAL);
1014 rc = verify_handle("7_sub", llh, num_recs + 1);
1016 CERROR("7_sub: verify handle failed: %d\n", rc);
1017 GOTO(out_close, rc);
1019 if (num_recs < LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr) - 1)
1020 CWARN("7_sub: records are not aligned, written %d from %u\n",
1021 num_recs, LLOG_HDR_BITMAP_SIZE(llh->lgh_hdr) - 1);
1024 rc = llog_process(env, llh, test_7_print_cb, "test 7", NULL);
1026 CERROR("7_sub: llog process failed: %d\n", rc);
1027 GOTO(out_close, rc);
1029 process_count = plain_counter;
1030 if (process_count != num_recs) {
1031 CERROR("7_sub: processed %d records from %d total\n",
1032 process_count, num_recs);
1033 GOTO(out_close, rc = -EINVAL);
1037 rc = llog_reverse_process(env, llh, test_7_cancel_cb, "test 7", NULL);
1038 if (rc && rc != LLOG_DEL_PLAIN) {
1039 CERROR("7_sub: reverse llog process failed: %d\n", rc);
1040 GOTO(out_close, rc);
1042 if (process_count != plain_counter) {
1043 CERROR("7_sub: Reverse/direct processing found different"
1044 "number of records: %d/%d\n",
1045 plain_counter, process_count);
1046 GOTO(out_close, rc = -EINVAL);
1048 if (llog_exist(llh)) {
1049 CERROR("7_sub: llog exists but should be zapped\n");
1050 GOTO(out_close, rc = -EEXIST);
1053 rc = verify_handle("7_sub", llh, 1);
1056 llog_destroy(env, llh);
1057 llog_close(env, llh);
1061 /* Test all llog records writing and processing */
1062 static int llog_test_7(const struct lu_env *env, struct obd_device *obd)
1064 struct llog_ctxt *ctxt;
1069 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
1071 CWARN("7a: test llog_logid_rec\n");
1072 llog_records.llr.lid_hdr.lrh_len = sizeof(llog_records.llr);
1073 llog_records.llr.lid_tail.lrt_len = sizeof(llog_records.llr);
1074 llog_records.llr.lid_hdr.lrh_type = LLOG_LOGID_MAGIC;
1076 rc = llog_test_7_sub(env, ctxt);
1078 CERROR("7a: llog_logid_rec test failed\n");
1082 CWARN("7b: test llog_unlink64_rec\n");
1083 llog_records.lur.lur_hdr.lrh_len = sizeof(llog_records.lur);
1084 llog_records.lur.lur_tail.lrt_len = sizeof(llog_records.lur);
1085 llog_records.lur.lur_hdr.lrh_type = MDS_UNLINK64_REC;
1087 rc = llog_test_7_sub(env, ctxt);
1089 CERROR("7b: llog_unlink_rec test failed\n");
1093 CWARN("7c: test llog_setattr64_rec\n");
1094 llog_records.lsr64.lsr_hdr.lrh_len = sizeof(llog_records.lsr64);
1095 llog_records.lsr64.lsr_tail.lrt_len = sizeof(llog_records.lsr64);
1096 llog_records.lsr64.lsr_hdr.lrh_type = MDS_SETATTR64_REC;
1098 rc = llog_test_7_sub(env, ctxt);
1100 CERROR("7c: llog_setattr64_rec test failed\n");
1104 CWARN("7d: test llog_size_change_rec\n");
1105 llog_records.lscr.lsc_hdr.lrh_len = sizeof(llog_records.lscr);
1106 llog_records.lscr.lsc_tail.lrt_len = sizeof(llog_records.lscr);
1107 llog_records.lscr.lsc_hdr.lrh_type = OST_SZ_REC;
1109 rc = llog_test_7_sub(env, ctxt);
1111 CERROR("7d: llog_size_change_rec test failed\n");
1115 CWARN("7e: test llog_changelog_rec\n");
1116 /* Direct access to cr_do_not_use: peculiar case for this test */
1117 llog_records.lcr.cr_hdr.lrh_len = sizeof(llog_records.lcr);
1118 llog_records.lcr.cr_do_not_use.lrt_len = sizeof(llog_records.lcr);
1119 llog_records.lcr.cr_hdr.lrh_type = CHANGELOG_REC;
1121 rc = llog_test_7_sub(env, ctxt);
1123 CERROR("7e: llog_changelog_rec test failed\n");
1127 CWARN("7f: test llog_changelog_user_rec\n");
1128 llog_records.lcur.cur_hdr.lrh_len = sizeof(llog_records.lcur);
1129 llog_records.lcur.cur_tail.lrt_len = sizeof(llog_records.lcur);
1130 llog_records.lcur.cur_hdr.lrh_type = CHANGELOG_USER_REC;
1132 rc = llog_test_7_sub(env, ctxt);
1134 CERROR("7f: llog_changelog_user_rec test failed\n");
1138 CWARN("7g: test llog_gen_rec\n");
1139 llog_records.lgr.lgr_hdr.lrh_len = sizeof(llog_records.lgr);
1140 llog_records.lgr.lgr_tail.lrt_len = sizeof(llog_records.lgr);
1141 llog_records.lgr.lgr_hdr.lrh_type = LLOG_GEN_REC;
1143 rc = llog_test_7_sub(env, ctxt);
1145 CERROR("7g: llog_size_change_rec test failed\n");
1149 llog_ctxt_put(ctxt);
1153 static int llog_truncate(const struct lu_env *env, struct dt_object *o)
1157 struct dt_device *d;
1162 d = lu2dt_dev(o->do_lu.lo_dev);
1165 rc = dt_attr_get(env, o, &la);
1169 CDEBUG(D_OTHER, "original size %llu\n", la.la_size);
1170 rc = sizeof(struct llog_log_hdr) + sizeof(struct llog_mini_rec);
1171 if (la.la_size < rc) {
1172 CERROR("too small llog: %llu\n", la.la_size);
1176 /* drop 2 records */
1177 la.la_size = la.la_size - (sizeof(struct llog_mini_rec) * 2);
1178 la.la_valid = LA_SIZE;
1180 th = dt_trans_create(env, d);
1182 RETURN(PTR_ERR(th));
1184 rc = dt_declare_attr_set(env, o, &la, th);
1188 rc = dt_declare_punch(env, o, la.la_size, OBD_OBJECT_EOF, th);
1190 rc = dt_trans_start_local(env, d, th);
1194 rc = dt_punch(env, o, la.la_size, OBD_OBJECT_EOF, th);
1198 rc = dt_attr_set(env, o, &la, th);
1203 dt_trans_stop(env, d, th);
1208 static int test_8_cb(const struct lu_env *env, struct llog_handle *llh,
1209 struct llog_rec_hdr *rec, void *data)
1215 static int llog_test_8(const struct lu_env *env, struct obd_device *obd)
1217 struct llog_handle *llh = NULL;
1221 struct llog_mini_rec lmr;
1222 struct llog_ctxt *ctxt;
1223 struct dt_object *obj = NULL;
1227 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
1230 lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
1231 lmr.lmr_hdr.lrh_type = 0xf00f00;
1233 CWARN("8a: fill the first plain llog\n");
1234 rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
1236 CERROR("8a: llog_create with logid failed: %d\n", rc);
1240 rc = llog_init_handle(env, llh, LLOG_F_IS_CAT, &uuid);
1242 CERROR("8a: can't init llog handle: %d\n", rc);
1247 rc = llog_cat_process(env, llh, test_8_cb, "foobar", 0, 0);
1249 CERROR("5a: process with test_8_cb failed: %d\n", rc);
1252 orig_counter = plain_counter;
1254 for (i = 0; i < 100; i++) {
1255 rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL);
1257 CERROR("5a: add record failed\n");
1262 /* grab the current plain llog, we'll corrupt it later */
1263 obj = llh->u.chd.chd_current_log->lgh_obj;
1265 lu_object_get(&obj->do_lu);
1266 CWARN("8a: pin llog "DFID"\n", PFID(lu_object_fid(&obj->do_lu)));
1268 rc2 = llog_cat_close(env, llh);
1270 CERROR("8a: close log %s failed: %d\n", name, rc2);
1276 CWARN("8b: fill the second plain llog\n");
1277 rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
1279 CERROR("8b: llog_create with logid failed: %d\n", rc);
1283 rc = llog_init_handle(env, llh, LLOG_F_IS_CAT, &uuid);
1285 CERROR("8b: can't init llog handle: %d\n", rc);
1289 for (i = 0; i < 100; i++) {
1290 rc = llog_cat_add(env, llh, &lmr.lmr_hdr, NULL);
1292 CERROR("8b: add record failed\n");
1296 CWARN("8b: second llog "DFID"\n",
1297 PFID(lu_object_fid(&llh->u.chd.chd_current_log->lgh_obj->do_lu)));
1299 rc2 = llog_cat_close(env, llh);
1301 CERROR("8b: close log %s failed: %d\n", name, rc2);
1307 CWARN("8c: drop two records from the first plain llog\n");
1308 llog_truncate(env, obj);
1310 CWARN("8d: count survived records\n");
1311 rc = llog_open(env, ctxt, &llh, &cat_logid, NULL, LLOG_OPEN_EXISTS);
1313 CERROR("8d: llog_create with logid failed: %d\n", rc);
1317 rc = llog_init_handle(env, llh, LLOG_F_IS_CAT, &uuid);
1319 CERROR("8d: can't init llog handle: %d\n", rc);
1324 rc = llog_cat_process(env, llh, test_8_cb, "foobar", 0, 0);
1326 CERROR("8d: process with test_8_cb failed: %d\n", rc);
1330 if (orig_counter + 200 - 2 != plain_counter) {
1331 CERROR("found %d records (expected %d)\n", plain_counter,
1332 orig_counter + 200 - 2);
1337 CWARN("8d: close re-opened catalog\n");
1338 rc2 = llog_cat_close(env, llh);
1340 CERROR("8d: close log %s failed: %d\n", name, rc2);
1345 llog_ctxt_put(ctxt);
1348 lu_object_put(env, &obj->do_lu);
1353 static int llog_test_9_sub(const struct lu_env *env, struct llog_ctxt *ctxt)
1355 struct llog_handle *llh;
1361 rc = llog_open_create(env, ctxt, &llh, NULL, NULL);
1363 CERROR("9_sub: create log failed\n");
1367 rc = llog_init_handle(env, llh,
1368 LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY,
1371 CERROR("9_sub: can't init llog handle: %d\n", rc);
1372 GOTO(out_close, rc);
1375 logid_to_fid(&llh->lgh_id, &fid);
1376 fid_to_logid(&fid, &llog_records.llr.lid_id);
1377 rc = llog_write(env, llh, &llog_records.lrh, LLOG_NEXT_IDX);
1379 CERROR("9_sub: write recs failed at #1: %d\n", rc);
1380 GOTO(out_close, rc);
1382 CWARN("9_sub: record type %x in log "DFID_NOBRACE"\n",
1383 llog_records.lrh.lrh_type, PFID(&fid));
1385 llog_close(env, llh);
1389 /* Prepare different types of llog records for llog_reader test*/
1390 static int llog_test_9(const struct lu_env *env, struct obd_device *obd)
1392 struct llog_ctxt *ctxt;
1397 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
1399 CWARN("9a: test llog_logid_rec\n");
1400 llog_records.llr.lid_hdr.lrh_len = sizeof(llog_records.llr);
1401 llog_records.llr.lid_tail.lrt_len = sizeof(llog_records.llr);
1402 llog_records.llr.lid_hdr.lrh_type = LLOG_LOGID_MAGIC;
1404 rc = llog_test_9_sub(env, ctxt);
1406 CERROR("9a: llog_logid_rec test failed\n");
1410 CWARN("9b: test llog_obd_cfg_rec\n");
1411 llog_records.lscr.lsc_hdr.lrh_len = sizeof(llog_records.lscr);
1412 llog_records.lscr.lsc_tail.lrt_len = sizeof(llog_records.lscr);
1413 llog_records.lscr.lsc_hdr.lrh_type = OBD_CFG_REC;
1415 rc = llog_test_9_sub(env, ctxt);
1417 CERROR("9b: llog_obd_cfg_rec test failed\n");
1421 CWARN("9c: test llog_changelog_rec\n");
1422 /* Direct access to cr_do_not_use: peculiar case for this test */
1423 llog_records.lcr.cr_hdr.lrh_len = sizeof(llog_records.lcr);
1424 llog_records.lcr.cr_do_not_use.lrt_len = sizeof(llog_records.lcr);
1425 llog_records.lcr.cr_hdr.lrh_type = CHANGELOG_REC;
1427 rc = llog_test_9_sub(env, ctxt);
1429 CERROR("9c: llog_changelog_rec test failed\n");
1433 CWARN("9d: test llog_changelog_user_rec\n");
1434 llog_records.lcur.cur_hdr.lrh_len = sizeof(llog_records.lcur);
1435 llog_records.lcur.cur_tail.lrt_len = sizeof(llog_records.lcur);
1436 llog_records.lcur.cur_hdr.lrh_type = CHANGELOG_USER_REC;
1438 rc = llog_test_9_sub(env, ctxt);
1440 CERROR("9d: llog_changelog_user_rec test failed\n");
1445 llog_ctxt_put(ctxt);
1449 /* test catalog wrap around */
1450 static int llog_test_10(const struct lu_env *env, struct obd_device *obd)
1452 struct llog_handle *cath;
1454 int rc, rc2, i, enospc, eok;
1455 struct llog_mini_rec lmr;
1456 struct llog_ctxt *ctxt;
1459 struct dt_device *dt;
1463 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
1466 lmr.lmr_hdr.lrh_len = lmr.lmr_tail.lrt_len = LLOG_MIN_REC_SIZE;
1467 lmr.lmr_hdr.lrh_type = 0xf00f00;
1469 snprintf(name, sizeof(name), "%x", llog_test_rand + 2);
1470 CWARN("10a: create a catalog log with name: %s\n", name);
1471 rc = llog_open_create(env, ctxt, &cath, NULL, name);
1473 CERROR("10a: llog_create with name %s failed: %d\n", name, rc);
1474 GOTO(ctxt_release, rc);
1476 rc = llog_init_handle(env, cath, LLOG_F_IS_CAT, &uuid);
1478 CERROR("10a: can't init llog handle: %d\n", rc);
1482 cat_logid = cath->lgh_id;
1483 dt = lu2dt_dev(cath->lgh_obj->do_lu.lo_dev);
1485 /* sync device to commit all recent LLOG changes to disk and avoid
1486 * to consume a huge space with delayed journal commit callbacks
1487 * particularly on low memory nodes or VMs */
1488 rc = dt_sync(env, dt);
1490 CERROR("10c: sync failed: %d\n", rc);
1494 /* force catalog wrap for 5th plain LLOG */
1495 cfs_fail_loc = CFS_FAIL_SKIP|OBD_FAIL_CAT_RECORDS;
1498 CWARN("10b: write %d log records\n", LLOG_TEST_RECNUM);
1499 for (i = 0; i < LLOG_TEST_RECNUM; i++) {
1500 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
1502 CERROR("10b: write %d records failed at #%d: %d\n",
1503 LLOG_TEST_RECNUM, i + 1, rc);
1508 /* make sure 2 new plain llog appears in catalog (+1 with hdr) */
1509 rc = verify_handle("10b", cath, 3);
1513 /* sync device to commit all recent LLOG changes to disk and avoid
1514 * to consume a huge space with delayed journal commit callbacks
1515 * particularly on low memory nodes or VMs */
1516 rc = dt_sync(env, dt);
1518 CERROR("10b: sync failed: %d\n", rc);
1522 CWARN("10c: write %d more log records\n", 2 * LLOG_TEST_RECNUM);
1523 for (i = 0; i < 2 * LLOG_TEST_RECNUM; i++) {
1524 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
1526 CERROR("10c: write %d records failed at #%d: %d\n",
1527 2*LLOG_TEST_RECNUM, i + 1, rc);
1532 /* make sure 2 new plain llog appears in catalog (+1 with hdr) */
1533 rc = verify_handle("10c", cath, 5);
1537 /* sync device to commit all recent LLOG changes to disk and avoid
1538 * to consume a huge space with delayed journal commit callbacks
1539 * particularly on low memory nodes or VMs */
1540 rc = dt_sync(env, dt);
1542 CERROR("10c: sync failed: %d\n", rc);
1546 /* fill last allocated plain LLOG and reach -ENOSPC condition
1547 * because no slot available in Catalog */
1550 CWARN("10c: write %d more log records\n", LLOG_TEST_RECNUM);
1551 for (i = 0; i < LLOG_TEST_RECNUM; i++) {
1552 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
1553 if (rc && rc != -ENOSPC) {
1554 CERROR("10c: write %d records failed at #%d: %d\n",
1555 LLOG_TEST_RECNUM, i + 1, rc);
1558 /* after last added plain LLOG has filled up, all new
1559 * records add should fail with -ENOSPC */
1560 if (rc == -ENOSPC) {
1568 if ((enospc == 0) && (enospc+eok != LLOG_TEST_RECNUM)) {
1569 CERROR("10c: all last records adds should have failed with"
1571 GOTO(out, rc = -EINVAL);
1574 CWARN("10c: wrote %d records then %d failed with ENOSPC\n", eok,
1577 /* make sure no new record in Catalog */
1578 rc = verify_handle("10c", cath, 5);
1582 /* Catalog should have reached its max size for test */
1583 rc = dt_attr_get(env, cath->lgh_obj, &la);
1585 CERROR("10c: failed to get catalog attrs: %d\n", rc);
1588 cat_max_size = la.la_size;
1590 /* cancel all 1st plain llog records to empty it, this will also cause
1591 * its catalog entry to be freed for next forced wrap in 10e */
1592 CWARN("10d: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
1594 rc = llog_cat_process(env, cath, llog_cancel_rec_cb, "foobar", 0, 0);
1595 if (rc != -LLOG_EEMPTY) {
1596 CERROR("10d: process with llog_cancel_rec_cb failed: %d\n", rc);
1597 /* need to indicate error if for any reason LLOG_TEST_RECNUM is
1604 CWARN("10d: print the catalog entries.. we expect 3\n");
1606 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1608 CERROR("10d: process with cat_print_cb failed: %d\n", rc);
1611 if (cat_counter != 3) {
1612 CERROR("10d: %d entries in catalog\n", cat_counter);
1613 GOTO(out, rc = -EINVAL);
1616 /* verify one down in catalog (+1 with hdr) */
1617 rc = verify_handle("10d", cath, 4);
1621 /* sync device to commit all recent LLOG changes to disk and avoid
1622 * to consume a huge space with delayed journal commit callbacks
1623 * particularly on low memory nodes or VMs */
1624 rc = dt_sync(env, dt);
1626 CERROR("10d: sync failed: %d\n", rc);
1632 CWARN("10e: write %d more log records\n", LLOG_TEST_RECNUM);
1633 for (i = 0; i < LLOG_TEST_RECNUM; i++) {
1634 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
1635 if (rc && rc != -ENOSPC) {
1636 CERROR("10e: write %d records failed at #%d: %d\n",
1637 LLOG_TEST_RECNUM, i + 1, rc);
1640 /* after last added plain LLOG has filled up, all new
1641 * records add should fail with -ENOSPC */
1642 if (rc == -ENOSPC) {
1650 if ((enospc == 0) && (enospc+eok != LLOG_TEST_RECNUM)) {
1651 CERROR("10e: all last records adds should have failed with"
1653 GOTO(out, rc = -EINVAL);
1656 CWARN("10e: wrote %d records then %d failed with ENOSPC\n", eok,
1659 CWARN("10e: print the catalog entries.. we expect 4\n");
1661 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1663 CERROR("10d: process with cat_print_cb failed: %d\n", rc);
1666 if (cat_counter != 4) {
1667 CERROR("10d: %d entries in catalog\n", cat_counter);
1668 GOTO(out, rc = -EINVAL);
1671 /* make sure 1 new plain llog appears in catalog (+1 with hdr) */
1672 rc = verify_handle("10e", cath, 5);
1676 /* verify catalog has wrap around */
1677 if (cath->lgh_last_idx > cath->lgh_hdr->llh_cat_idx) {
1678 CERROR("10e: catalog failed to wrap around\n");
1679 GOTO(out, rc = -EINVAL);
1682 rc = dt_attr_get(env, cath->lgh_obj, &la);
1684 CERROR("10e: failed to get catalog attrs: %d\n", rc);
1688 if (la.la_size != cat_max_size) {
1689 CERROR("10e: catalog size has changed after it has wrap around,"
1690 " current size = %llu, expected size = %llu\n",
1691 la.la_size, cat_max_size);
1692 GOTO(out, rc = -EINVAL);
1694 CWARN("10e: catalog successfully wrap around, last_idx %d, first %d\n",
1695 cath->lgh_last_idx, cath->lgh_hdr->llh_cat_idx);
1697 /* sync device to commit all recent LLOG changes to disk and avoid
1698 * to consume a huge space with delayed journal commit callbacks
1699 * particularly on low memory nodes or VMs */
1700 rc = dt_sync(env, dt);
1702 CERROR("10e: sync failed: %d\n", rc);
1706 /* cancel more records to free one more slot in Catalog
1707 * see if it is re-allocated when adding more records */
1708 CWARN("10f: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
1710 rc = llog_cat_process(env, cath, llog_cancel_rec_cb, "foobar", 0, 0);
1711 if (rc != -LLOG_EEMPTY) {
1712 CERROR("10f: process with llog_cancel_rec_cb failed: %d\n", rc);
1713 /* need to indicate error if for any reason LLOG_TEST_RECNUM is
1720 CWARN("10f: print the catalog entries.. we expect 3\n");
1722 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1724 CERROR("10f: process with cat_print_cb failed: %d\n", rc);
1727 if (cat_counter != 3) {
1728 CERROR("10f: %d entries in catalog\n", cat_counter);
1729 GOTO(out, rc = -EINVAL);
1732 /* verify one down in catalog (+1 with hdr) */
1733 rc = verify_handle("10f", cath, 4);
1737 /* sync device to commit all recent LLOG changes to disk and avoid
1738 * to consume a huge space with delayed journal commit callbacks
1739 * particularly on low memory nodes or VMs */
1740 rc = dt_sync(env, dt);
1742 CERROR("10f: sync failed: %d\n", rc);
1748 CWARN("10f: write %d more log records\n", LLOG_TEST_RECNUM);
1749 for (i = 0; i < LLOG_TEST_RECNUM; i++) {
1750 rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL);
1751 if (rc && rc != -ENOSPC) {
1752 CERROR("10f: write %d records failed at #%d: %d\n",
1753 LLOG_TEST_RECNUM, i + 1, rc);
1756 /* after last added plain LLOG has filled up, all new
1757 * records add should fail with -ENOSPC */
1758 if (rc == -ENOSPC) {
1766 if ((enospc == 0) && (enospc+eok != LLOG_TEST_RECNUM)) {
1767 CERROR("10f: all last records adds should have failed with"
1769 GOTO(out, rc = -EINVAL);
1772 CWARN("10f: wrote %d records then %d failed with ENOSPC\n", eok,
1775 /* make sure 1 new plain llog appears in catalog (+1 with hdr) */
1776 rc = verify_handle("10f", cath, 5);
1780 /* verify lgh_last_idx = llh_cat_idx = 2 now */
1781 if (cath->lgh_last_idx != cath->lgh_hdr->llh_cat_idx ||
1782 cath->lgh_last_idx != 2) {
1783 CERROR("10f: lgh_last_idx = %d vs 2, llh_cat_idx = %d vs 2\n",
1784 cath->lgh_last_idx, cath->lgh_hdr->llh_cat_idx);
1785 GOTO(out, rc = -EINVAL);
1788 rc = dt_attr_get(env, cath->lgh_obj, &la);
1790 CERROR("10f: failed to get catalog attrs: %d\n", rc);
1794 if (la.la_size != cat_max_size) {
1795 CERROR("10f: catalog size has changed after it has wrap around,"
1796 " current size = %llu, expected size = %llu\n",
1797 la.la_size, cat_max_size);
1798 GOTO(out, rc = -EINVAL);
1801 /* sync device to commit all recent LLOG changes to disk and avoid
1802 * to consume a huge space with delayed journal commit callbacks
1803 * particularly on low memory nodes or VMs */
1804 rc = dt_sync(env, dt);
1806 CERROR("10f: sync failed: %d\n", rc);
1810 /* will llh_cat_idx also successfully wrap ? */
1812 /* cancel all records in the plain LLOGs referenced by 2 last indexes in
1815 /* cancel more records to free one more slot in Catalog */
1816 CWARN("10g: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
1818 rc = llog_cat_process(env, cath, llog_cancel_rec_cb, "foobar", 0, 0);
1819 if (rc != -LLOG_EEMPTY) {
1820 CERROR("10g: process with llog_cancel_rec_cb failed: %d\n", rc);
1821 /* need to indicate error if for any reason LLOG_TEST_RECNUM is
1828 CWARN("10g: print the catalog entries.. we expect 3\n");
1830 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1832 CERROR("10g: process with cat_print_cb failed: %d\n", rc);
1835 if (cat_counter != 3) {
1836 CERROR("10g: %d entries in catalog\n", cat_counter);
1837 GOTO(out, rc = -EINVAL);
1840 /* verify one down in catalog (+1 with hdr) */
1841 rc = verify_handle("10g", cath, 4);
1845 /* sync device to commit all recent LLOG changes to disk and avoid
1846 * to consume a huge space with delayed journal commit callbacks
1847 * particularly on low memory nodes or VMs */
1848 rc = dt_sync(env, dt);
1850 CERROR("10g: sync failed: %d\n", rc);
1854 /* cancel more records to free one more slot in Catalog */
1855 CWARN("10g: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
1857 rc = llog_cat_process(env, cath, llog_cancel_rec_cb, "foobar", 0, 0);
1858 if (rc != -LLOG_EEMPTY) {
1859 CERROR("10g: process with llog_cancel_rec_cb failed: %d\n", rc);
1860 /* need to indicate error if for any reason LLOG_TEST_RECNUM is
1867 CWARN("10g: print the catalog entries.. we expect 2\n");
1869 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1871 CERROR("10g: process with cat_print_cb failed: %d\n", rc);
1874 if (cat_counter != 2) {
1875 CERROR("10g: %d entries in catalog\n", cat_counter);
1876 GOTO(out, rc = -EINVAL);
1879 /* verify one down in catalog (+1 with hdr) */
1880 rc = verify_handle("10g", cath, 3);
1884 /* verify lgh_last_idx = 2 and llh_cat_idx = 0 now */
1885 if (cath->lgh_hdr->llh_cat_idx != 0 ||
1886 cath->lgh_last_idx != 2) {
1887 CERROR("10g: lgh_last_idx = %d vs 2, llh_cat_idx = %d vs 0\n",
1888 cath->lgh_last_idx, cath->lgh_hdr->llh_cat_idx);
1889 GOTO(out, rc = -EINVAL);
1892 /* sync device to commit all recent LLOG changes to disk and avoid
1893 * to consume a huge space with delayed journal commit callbacks
1894 * particularly on low memory nodes or VMs */
1895 rc = dt_sync(env, dt);
1897 CERROR("10g: sync failed: %d\n", rc);
1901 /* cancel more records to free one more slot in Catalog */
1902 CWARN("10g: Cancel %d records, see one log zapped\n", LLOG_TEST_RECNUM);
1904 rc = llog_cat_process(env, cath, llog_cancel_rec_cb, "foobar", 0, 0);
1905 if (rc != -LLOG_EEMPTY) {
1906 CERROR("10g: process with llog_cancel_rec_cb failed: %d\n", rc);
1907 /* need to indicate error if for any reason LLOG_TEST_RECNUM is
1914 CWARN("10g: print the catalog entries.. we expect 1\n");
1916 rc = llog_process(env, cath, cat_print_cb, "test 10", NULL);
1918 CERROR("10g: process with cat_print_cb failed: %d\n", rc);
1921 if (cat_counter != 1) {
1922 CERROR("10g: %d entries in catalog\n", cat_counter);
1923 GOTO(out, rc = -EINVAL);
1926 /* verify one down in catalog (+1 with hdr) */
1927 rc = verify_handle("10g", cath, 2);
1931 /* verify lgh_last_idx = 2 and llh_cat_idx = 1 now */
1932 if (cath->lgh_hdr->llh_cat_idx != 1 ||
1933 cath->lgh_last_idx != 2) {
1934 CERROR("10g: lgh_last_idx = %d vs 2, llh_cat_idx = %d vs 1\n",
1935 cath->lgh_last_idx, cath->lgh_hdr->llh_cat_idx);
1936 GOTO(out, rc = -EINVAL);
1939 CWARN("10g: llh_cat_idx has also successfully wrapped!\n");
1945 CWARN("10: put newly-created catalog\n");
1946 rc2 = llog_cat_close(env, cath);
1948 CERROR("10: close log %s failed: %d\n", name, rc2);
1953 llog_ctxt_put(ctxt);
1957 /* -------------------------------------------------------------------------
1958 * Tests above, boring obd functions below
1959 * ------------------------------------------------------------------------- */
1960 static int llog_run_tests(const struct lu_env *env, struct obd_device *obd)
1962 struct llog_handle *llh = NULL;
1963 struct llog_ctxt *ctxt;
1968 ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT);
1971 sprintf(name, "%x", llog_test_rand);
1973 rc = llog_test_1(env, obd, name);
1975 GOTO(cleanup_ctxt, rc);
1977 rc = llog_test_2(env, obd, name, &llh);
1979 GOTO(cleanup_ctxt, rc);
1981 rc = llog_test_3(env, obd, llh);
1985 rc = llog_test_4(env, obd);
1989 rc = llog_test_5(env, obd);
1993 rc = llog_test_6(env, obd, name);
1997 rc = llog_test_7(env, obd);
2001 rc = llog_test_8(env, obd);
2005 rc = llog_test_9(env, obd);
2009 rc = llog_test_10(env, obd);
2014 err = llog_destroy(env, llh);
2016 CERROR("cleanup: llog_destroy failed: %d\n", err);
2017 llog_close(env, llh);
2021 llog_ctxt_put(ctxt);
2025 static int llog_test_cleanup(struct obd_device *obd)
2027 struct obd_device *tgt;
2033 rc = lu_env_init(&env, LCT_LOCAL | LCT_MG_THREAD);
2037 tgt = obd->obd_lvfs_ctxt.dt->dd_lu_dev.ld_obd;
2038 rc = llog_cleanup(&env, llog_get_context(tgt, LLOG_TEST_ORIG_CTXT));
2040 CERROR("failed to llog_test_llog_finish: %d\n", rc);
2045 static int llog_test_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
2047 struct obd_device *tgt;
2048 struct llog_ctxt *ctxt;
2049 struct dt_object *o;
2051 struct lu_context test_session;
2056 if (lcfg->lcfg_bufcount < 2) {
2057 CERROR("requires a TARGET OBD name\n");
2061 if (lcfg->lcfg_buflens[1] < 1) {
2062 CERROR("requires a TARGET OBD name\n");
2067 tgt = class_name2obd(lustre_cfg_string(lcfg, 1));
2068 if (!tgt || !tgt->obd_attached || !tgt->obd_set_up) {
2069 CERROR("target device not attached or not set up (%s)\n",
2070 lustre_cfg_string(lcfg, 1));
2074 rc = lu_env_init(&env, LCT_LOCAL | LCT_MG_THREAD);
2078 rc = lu_context_init(&test_session, LCT_SERVER_SESSION);
2080 GOTO(cleanup_env, rc);
2081 test_session.lc_thread = (struct ptlrpc_thread *)current;
2082 lu_context_enter(&test_session);
2083 env.le_ses = &test_session;
2085 CWARN("Setup llog-test device over %s device\n",
2086 lustre_cfg_string(lcfg, 1));
2088 OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt);
2089 obd->obd_lvfs_ctxt.dt = lu2dt_dev(tgt->obd_lu_dev);
2091 rc = llog_setup(&env, tgt, &tgt->obd_olg, LLOG_TEST_ORIG_CTXT, tgt,
2094 GOTO(cleanup_session, rc);
2096 /* use MGS llog dir for tests */
2097 ctxt = llog_get_context(tgt, LLOG_CONFIG_ORIG_CTXT);
2100 llog_ctxt_put(ctxt);
2102 ctxt = llog_get_context(tgt, LLOG_TEST_ORIG_CTXT);
2105 llog_ctxt_put(ctxt);
2107 llog_test_rand = cfs_rand();
2109 rc = llog_run_tests(&env, tgt);
2111 llog_test_cleanup(obd);
2113 lu_context_exit(&test_session);
2114 lu_context_fini(&test_session);
2120 static struct obd_ops llog_obd_ops = {
2121 .o_owner = THIS_MODULE,
2122 .o_setup = llog_test_setup,
2123 .o_cleanup = llog_test_cleanup,
2126 static int __init llog_test_init(void)
2128 return class_register_type(&llog_obd_ops, NULL, true, NULL,
2132 static void __exit llog_test_exit(void)
2134 class_unregister_type("llog_test");
2137 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
2138 MODULE_DESCRIPTION("Lustre Log test module");
2139 MODULE_VERSION(LUSTRE_VERSION_STRING);
2140 MODULE_LICENSE("GPL");
2142 module_init(llog_test_init);
2143 module_exit(llog_test_exit);