// send an async message to a service asynchronously Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle, Uint32 msg_handle, Uint32 destination_q, AsyncRequest *message, void *callback_parm) { //printf("verifying handle %p, controller at %p \n", &handle, this); if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); if (message->op == NULL) { message->op = get_op(); message->op->put_request(message); } callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle), callback_parm); message->setRouting(msg_handle); message->resp = getQueueId(); message->block = false; message->dest = destination_q; return SendAsync(message->op, destination_q, _async_handleEnqueue, this, cb); }
/* Test named-log create/open, close */ static int llog_test_1(struct obd_device *obd, char *name) { struct llog_handle *llh; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); int rc; int rc2; ENTRY; CWARN("1a: create a log with name: %s\n", name); LASSERT(ctxt); rc = llog_create(ctxt, &llh, NULL, name); if (rc) { CERROR("1a: llog_create with name %s failed: %d\n", name, rc); llog_ctxt_put(ctxt); RETURN(rc); } llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid); if ((rc = verify_handle("1", llh, 1))) GOTO(out, rc); out: CWARN("1b: close newly-created log\n"); rc2 = llog_close(llh); llog_ctxt_put(ctxt); if (rc2) { CERROR("1b: close log %s failed: %d\n", name, rc2); if (rc == 0) rc = rc2; } RETURN(rc); }
bool FileSystem::writeLine(int handle, const std::string &line) { if (!verify_handle(handle)) return false; *file_table[handle] << line << "\n"; return true; }
// send a message to a module within another service asynchronously Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle, Uint32 msg_handle, Uint32 destination_q, const String & destination_module, AsyncRequest *message, void *callback_parm) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); AsyncOpNode *op = get_op(); AsyncModuleOperationStart *request = new AsyncModuleOperationStart(msg_handle, op, destination_q, getQueueId(), true, destination_module, message); request->dest = destination_q; callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle), callback_parm); return SendAsync(op, destination_q, _async_handleEnqueue, this, cb); }
void FileSystem::close(int handle) { if (!verify_handle(handle)) return; delete file_table[handle]; file_table[handle] = NULL; }
void ModuleController::async_thread_exec(const pegasus_module & handle, PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *thread_func)(void *), void *parm) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); _async_thread_exec(thread_func, parm); }
// sendwait to another service AsyncReply * ModuleController::ModuleSendWait(const pegasus_module & handle, Uint32 destination_q, AsyncRequest *request) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); return _send_wait(destination_q, request); }
Boolean ModuleController::ModuleSendForget(const pegasus_module & handle, Uint32 destination_q, AsyncRequest *message) { if(false == verify_handle(const_cast<pegasus_module *>( &handle))) throw(Permission(pegasus_thread_self())); return _send_forget(destination_q, message); }
bool FileSystem::readLine(int handle, std::string &line) { if (!verify_handle(handle)) return false; std::getline(*file_table[handle], line); if (!*file_table[handle]) return false; return true; }
// given a name, find a service's queue id Uint32 ModuleController::find_service(const pegasus_module & handle, const String & name) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle)) ) throw Permission(pegasus_thread_self()); Array<Uint32> services; Base::find_services(name, 0, 0, &services); return( services[0]); }
/* Test named-log reopen; returns opened log on success */ static int llog_test_2(struct obd_device *obd, char *name, struct llog_handle **llh) { struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); int rc; ENTRY; CWARN("2a: re-open a log with name: %s\n", name); rc = llog_create(ctxt, llh, NULL, name); if (rc) { CERROR("2a: re-open log with name %s failed: %d\n", name, rc); GOTO(out, rc); } llog_init_handle(*llh, LLOG_F_IS_PLAIN, &uuid); if ((rc = verify_handle("2", *llh, 1))) GOTO(out, rc); #if 0 CWARN("2b: create a log without specified NAME & LOGID\n"); rc = llog_create(ctxt, &loghandle, NULL, NULL); if (rc) { CERROR("2b: create log failed\n"); GOTO(out, rc); } llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid); logid = loghandle->lgh_id; llog_close(loghandle); CWARN("2b: re-open the log by LOGID\n"); rc = llog_create(ctxt, &loghandle, &logid, NULL); if (rc) { CERROR("2b: re-open log by LOGID failed\n"); GOTO(out, rc); } llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid); CWARN("2b: destroy this log\n"); rc = llog_destroy(loghandle); if (rc) { CERROR("2b: destroy log failed\n"); GOTO(out, rc); } llog_free_handle(loghandle); #endif out: llog_ctxt_put(ctxt); RETURN(rc); }
pegasus_module * ModuleController::get_module_reference(const pegasus_module & my_handle, const String & module_name) { if ( false == verify_handle(const_cast<pegasus_module *>(&my_handle))) throw(Permission(pegasus_thread_self())); pegasus_module *module, *ref = NULL; _module_lock lock(&_modules); module = _modules.next(0); while(module != NULL) { if(module->get_name() == module_name) { ref = new pegasus_module(*module); break; } module = _modules.next(module); } return ref; }
Uint32 ModuleController::find_module_in_service(const pegasus_module & handle, const String & name) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); Uint32 result = 0 ; AutoPtr<FindModuleInService> request(new FindModuleInService(get_next_xid(), 0, true, _meta_dispatcher->getQueueId(), name)); request->dest = _meta_dispatcher->getQueueId(); AutoPtr<FindModuleInServiceResponse> response(static_cast<FindModuleInServiceResponse *>(SendWait(request.get()))); if( response.get() != NULL) result = response->_module_service_queue; return result; }
/* Test named-log create/open, close */ static int llog_test_1(const struct lu_env *env, struct obd_device *obd, char *name) { struct llog_handle *llh; struct llog_ctxt *ctxt; int rc; int rc2; CWARN("1a: create a log with name: %s\n", name); ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); rc = llog_open_create(env, ctxt, &llh, NULL, name); if (rc) { CERROR("1a: llog_create with name %s failed: %d\n", name, rc); GOTO(out, rc); } rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, &uuid); if (rc) { CERROR("1a: can't init llog handle: %d\n", rc); GOTO(out_close, rc); } rc = verify_handle("1", llh, 1); CWARN("1b: close newly-created log\n"); out_close: rc2 = llog_close(env, llh); if (rc2) { CERROR("1b: close log %s failed: %d\n", name, rc2); if (rc == 0) rc = rc2; } out: llog_ctxt_put(ctxt); return rc; }
static int llog_test_7_sub(const struct lu_env *env, struct llog_ctxt *ctxt) { struct llog_handle *llh; int rc = 0, i, process_count; int num_recs = 0; rc = llog_open_create(env, ctxt, &llh, NULL, NULL); if (rc) { CERROR("7_sub: create log failed\n"); return rc; } rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY, &uuid); if (rc) { CERROR("7_sub: can't init llog handle: %d\n", rc); GOTO(out_close, rc); } for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr); i++) { rc = llog_write(env, llh, &llog_records.lrh, NULL, 0, NULL, -1); if (rc == -ENOSPC) { break; } else if (rc < 0) { CERROR("7_sub: write recs failed at #%d: %d\n", i + 1, rc); GOTO(out_close, rc); } num_recs++; } if (rc != -ENOSPC) { CWARN("7_sub: write record more than BITMAP size!\n"); GOTO(out_close, rc = -EINVAL); } rc = verify_handle("7_sub", llh, num_recs + 1); if (rc) { CERROR("7_sub: verify handle failed: %d\n", rc); GOTO(out_close, rc); } if (num_recs < LLOG_BITMAP_SIZE(llh->lgh_hdr) - 1) CWARN("7_sub: records are not aligned, written %d from %u\n", num_recs, LLOG_BITMAP_SIZE(llh->lgh_hdr) - 1); plain_counter = 0; rc = llog_process(env, llh, test_7_print_cb, "test 7", NULL); if (rc) { CERROR("7_sub: llog process failed: %d\n", rc); GOTO(out_close, rc); } process_count = plain_counter; if (process_count != num_recs) { CERROR("7_sub: processed %d records from %d total\n", process_count, num_recs); GOTO(out_close, rc = -EINVAL); } plain_counter = 0; rc = llog_reverse_process(env, llh, test_7_cancel_cb, "test 7", NULL); if (rc) { CERROR("7_sub: reverse llog process failed: %d\n", rc); GOTO(out_close, rc); } if (process_count != plain_counter) { CERROR("7_sub: Reverse/direct processing found different" "number of records: %d/%d\n", plain_counter, process_count); GOTO(out_close, rc = -EINVAL); } if (llog_exist(llh)) { CERROR("7_sub: llog exists but should be zapped\n"); GOTO(out_close, rc = -EEXIST); } rc = verify_handle("7_sub", llh, 1); out_close: if (rc) llog_destroy(env, llh); llog_close(env, llh); return rc; }
/* Test client api; open log by name and process */ static int llog_test_6(const struct lu_env *env, struct obd_device *obd, char *name) { struct obd_device *mgc_obd; struct llog_ctxt *ctxt; struct obd_uuid *mgs_uuid; struct obd_export *exp; struct obd_uuid uuid = { "LLOG_TEST6_UUID" }; struct llog_handle *llh = NULL; struct llog_ctxt *nctxt; int rc, rc2; ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); mgs_uuid = &ctxt->loc_exp->exp_obd->obd_uuid; 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("6a: 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("6a: connect on connected MGC (%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_open(env, nctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); if (rc) { CERROR("6a: llog_open failed %d\n", rc); GOTO(nctxt_put, rc); } rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); if (rc) { CERROR("6a: llog_init_handle failed %d\n", rc); GOTO(parse_out, rc); } plain_counter = 1; /* llog header is first record */ CWARN("6b: process log %s using client API\n", name); rc = llog_process(env, llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6b: llog_process failed %d\n", rc); CWARN("6b: processed %d records\n", plain_counter); rc = verify_handle("6b", llh, plain_counter); if (rc) GOTO(parse_out, rc); plain_counter = 1; /* llog header is first record */ CWARN("6c: process log %s reversely using client API\n", name); rc = llog_reverse_process(env, llh, plain_print_cb, NULL, NULL); if (rc) CERROR("6c: llog_reverse_process failed %d\n", rc); CWARN("6c: processed %d records\n", plain_counter); rc = verify_handle("6c", llh, plain_counter); if (rc) GOTO(parse_out, rc); parse_out: rc2 = llog_close(env, llh); if (rc2) { CERROR("6: llog_close failed: rc = %d\n", rc2); if (rc == 0) rc = rc2; } nctxt_put: llog_ctxt_put(nctxt); ctxt_release: llog_ctxt_put(ctxt); return rc; }
/* Test catalogue additions */ static int llog_test_4(const struct lu_env *env, struct obd_device *obd) { struct llog_handle *cath; char name[10]; int rc, rc2, i, buflen; struct llog_mini_rec lmr; struct llog_cookie cookie; struct llog_ctxt *ctxt; int num_recs = 0; char *buf; struct llog_rec_hdr rec; 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; sprintf(name, "%x", llog_test_rand + 1); CWARN("4a: create a catalog log with name: %s\n", name); rc = llog_open_create(env, ctxt, &cath, NULL, name); if (rc) { CERROR("4a: llog_create with name %s failed: %d\n", name, rc); GOTO(ctxt_release, rc); } rc = llog_init_handle(env, cath, LLOG_F_IS_CAT, &uuid); if (rc) { CERROR("4a: can't init llog handle: %d\n", rc); GOTO(out, rc); } num_recs++; cat_logid = cath->lgh_id; CWARN("4b: write 1 record into the catalog\n"); rc = llog_cat_add(env, 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++; rc = verify_handle("4b", cath, 2); if (rc) GOTO(out, rc); rc = verify_handle("4b", cath->u.chd.chd_current_log, num_recs); if (rc) GOTO(out, rc); CWARN("4c: cancel 1 log record\n"); rc = llog_cat_cancel_records(env, cath, 1, &cookie); if (rc) { CERROR("4c: cancel 1 catalog based record failed: %d\n", rc); GOTO(out, rc); } num_recs--; rc = verify_handle("4c", cath->u.chd.chd_current_log, num_recs); if (rc) GOTO(out, rc); CWARN("4d: write %d more log records\n", LLOG_TEST_RECNUM); for (i = 0; i < LLOG_TEST_RECNUM; i++) { rc = llog_cat_add(env, cath, &lmr.lmr_hdr, NULL, NULL); if (rc) { CERROR("4d: write %d records failed at #%d: %d\n", LLOG_TEST_RECNUM, i + 1, rc); GOTO(out, rc); } num_recs++; } /* make sure new plain llog appears */ rc = verify_handle("4d", cath, 3); if (rc) GOTO(out, rc); 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(env, cath, &rec, NULL, buf); if (rc) { CERROR("4e: write 5 records failed at #%d: %d\n", i + 1, rc); GOTO(out_free, rc); } num_recs++; } out_free: OBD_FREE(buf, buflen); out: CWARN("4f: put newly-created catalog\n"); rc2 = llog_cat_close(env, cath); if (rc2) { CERROR("4: close log %s failed: %d\n", name, rc2); if (rc == 0) rc = rc2; } ctxt_release: llog_ctxt_put(ctxt); return rc; }
/* Test record writing, single and in bulk */ static int llog_test_3(const struct lu_env *env, struct obd_device *obd, struct llog_handle *llh) { struct llog_gen_rec lgr; int rc, i; int num_recs = 1; /* 1 for the header */ lgr.lgr_hdr.lrh_len = lgr.lgr_tail.lrt_len = sizeof(lgr); lgr.lgr_hdr.lrh_type = LLOG_GEN_REC; CWARN("3a: write one create_rec\n"); rc = llog_write(env, llh, &lgr.lgr_hdr, NULL, 0, NULL, -1); num_recs++; if (rc < 0) { CERROR("3a: write one log record failed: %d\n", rc); return rc; } rc = verify_handle("3a", llh, num_recs); if (rc) return rc; CWARN("3b: write 10 cfg log records with 8 bytes bufs\n"); for (i = 0; i < 10; i++) { struct llog_rec_hdr hdr; char buf[8]; hdr.lrh_len = 8; hdr.lrh_type = OBD_CFG_REC; memset(buf, 0, sizeof(buf)); rc = llog_write(env, llh, &hdr, NULL, 0, buf, -1); if (rc < 0) { CERROR("3b: write 10 records failed at #%d: %d\n", i + 1, rc); return rc; } num_recs++; } rc = verify_handle("3b", llh, num_recs); if (rc) return rc; CWARN("3c: write 1000 more log records\n"); for (i = 0; i < 1000; i++) { rc = llog_write(env, llh, &lgr.lgr_hdr, NULL, 0, NULL, -1); if (rc < 0) { CERROR("3c: write 1000 records failed at #%d: %d\n", i + 1, rc); return rc; } num_recs++; } rc = verify_handle("3c", llh, num_recs); if (rc) return rc; CWARN("3d: write log more than BITMAP_SIZE, return -ENOSPC\n"); for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr) + 1; i++) { struct llog_rec_hdr hdr; char buf_even[24]; char buf_odd[32]; memset(buf_odd, 0, sizeof(buf_odd)); memset(buf_even, 0, sizeof(buf_even)); if ((i % 2) == 0) { hdr.lrh_len = 24; hdr.lrh_type = OBD_CFG_REC; rc = llog_write(env, llh, &hdr, NULL, 0, buf_even, -1); } else { hdr.lrh_len = 32; hdr.lrh_type = OBD_CFG_REC; rc = llog_write(env, llh, &hdr, NULL, 0, buf_odd, -1); } if (rc == -ENOSPC) { break; } else if (rc < 0) { CERROR("3d: write recs failed at #%d: %d\n", i + 1, rc); return rc; } num_recs++; } if (rc != -ENOSPC) { CWARN("3d: write record more than BITMAP size!\n"); return -EINVAL; } CWARN("3d: wrote %d more records before end of llog is reached\n", num_recs); rc = verify_handle("3d", llh, num_recs); return rc; }
/* Test named-log reopen; returns opened log on success */ static int llog_test_2(const struct lu_env *env, struct obd_device *obd, char *name, struct llog_handle **llh) { struct llog_ctxt *ctxt; struct llog_handle *loghandle; struct llog_logid logid; int rc; CWARN("2a: re-open a log with name: %s\n", name); ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); rc = llog_open(env, ctxt, llh, NULL, name, LLOG_OPEN_EXISTS); if (rc) { CERROR("2a: re-open log with name %s failed: %d\n", name, rc); GOTO(out_put, rc); } rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &uuid); if (rc) { CERROR("2a: can't init llog handle: %d\n", rc); GOTO(out_close_llh, rc); } rc = verify_handle("2", *llh, 1); if (rc) GOTO(out_close_llh, rc); /* XXX: there is known issue with tests 2b, MGS is not able to create * anonymous llog, exit now to allow following tests run. * It is fixed in upcoming llog over OSD code */ GOTO(out_put, rc); CWARN("2b: create a log without specified NAME & LOGID\n"); rc = llog_open_create(env, ctxt, &loghandle, NULL, NULL); if (rc) { CERROR("2b: create log failed\n"); GOTO(out_close_llh, rc); } rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, &uuid); if (rc) { CERROR("2b: can't init llog handle: %d\n", rc); GOTO(out_close, rc); } logid = loghandle->lgh_id; llog_close(env, loghandle); CWARN("2c: re-open the log by LOGID\n"); rc = llog_open(env, ctxt, &loghandle, &logid, NULL, LLOG_OPEN_EXISTS); if (rc) { CERROR("2c: re-open log by LOGID failed\n"); GOTO(out_close_llh, rc); } rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, &uuid); if (rc) { CERROR("2c: can't init llog handle: %d\n", rc); GOTO(out_close, rc); } CWARN("2b: destroy this log\n"); rc = llog_destroy(env, loghandle); if (rc) CERROR("2d: destroy log failed\n"); out_close: llog_close(env, loghandle); out_close_llh: if (rc) llog_close(env, *llh); out_put: llog_ctxt_put(ctxt); return rc; }
void FileSystem::flush(int handle) { if (!verify_handle(handle)) return; file_table[handle]->flush(); }
/* Test record writing, single and in bulk */ static int llog_test_3(const struct lu_env *env, struct obd_device *obd, struct llog_handle *llh) { struct llog_gen_rec lgr; int rc, i; int num_recs = 1; /* 1 for the header */ ENTRY; lgr.lgr_hdr.lrh_len = lgr.lgr_tail.lrt_len = sizeof(lgr); lgr.lgr_hdr.lrh_type = LLOG_GEN_REC; CWARN("3a: write one create_rec\n"); rc = llog_write(env, llh, &lgr.lgr_hdr, LLOG_NEXT_IDX); num_recs++; if (rc < 0) { CERROR("3a: write one log record failed: %d\n", rc); RETURN(rc); } rc = verify_handle("3a", llh, num_recs); if (rc) RETURN(rc); CWARN("3c: write 1000 more log records\n"); for (i = 0; i < 1000; i++) { rc = llog_write(env, llh, &lgr.lgr_hdr, LLOG_NEXT_IDX); if (rc < 0) { CERROR("3c: write 1000 records failed at #%d: %d\n", i + 1, rc); RETURN(rc); } num_recs++; } rc = verify_handle("3c", llh, num_recs); if (rc) RETURN(rc); CWARN("3d: write records with variable size until BITMAP_SIZE, " "return -ENOSPC\n"); for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr) + 1; i++) { char buf[64]; struct llog_rec_hdr *hdr = (void *)&buf; memset(buf, 0, sizeof buf); if ((i % 2) == 0) hdr->lrh_len = 40; else hdr->lrh_len = 64; hdr->lrh_type = OBD_CFG_REC; rc = llog_write(env, llh, hdr, LLOG_NEXT_IDX); if (rc == -ENOSPC) { break; } else if (rc < 0) { CERROR("3d: write recs failed at #%d: %d\n", i + 1, rc); RETURN(rc); } num_recs++; } if (rc != -ENOSPC) { CWARN("3d: write record more than BITMAP size!\n"); RETURN(-EINVAL); } CWARN("3d: wrote %d more records before end of llog is reached\n", num_recs); rc = verify_handle("3d", llh, num_recs); RETURN(rc); }
/* Test record writing, single and in bulk */ static int llog_test_3(struct obd_device *obd, struct llog_handle *llh) { struct llog_create_rec lcr; int rc, i; int num_recs = 1; /* 1 for the header */ ENTRY; lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = sizeof(lcr); lcr.lcr_hdr.lrh_type = OST_SZ_REC; CWARN("3a: write one create_rec\n"); rc = llog_write_rec(llh, &lcr.lcr_hdr, NULL, 0, NULL, -1); num_recs++; if (rc) { CERROR("3a: write one log record failed: %d\n", rc); RETURN(rc); } if ((rc = verify_handle("3a", llh, num_recs))) RETURN(rc); CWARN("3b: write 10 cfg log records with 8 bytes bufs\n"); for (i = 0; i < 10; i++) { struct llog_rec_hdr hdr; char buf[8]; hdr.lrh_len = 8; hdr.lrh_type = OBD_CFG_REC; memset(buf, 0, sizeof buf); rc = llog_write_rec(llh, &hdr, NULL, 0, buf, -1); if (rc) { CERROR("3b: write 10 records failed at #%d: %d\n", i + 1, rc); RETURN(rc); } num_recs++; if ((rc = verify_handle("3c", llh, num_recs))) RETURN(rc); } if ((rc = verify_handle("3b", llh, num_recs))) RETURN(rc); CWARN("3c: write 1000 more log records\n"); for (i = 0; i < 1000; i++) { rc = llog_write_rec(llh, &lcr.lcr_hdr, NULL, 0, NULL, -1); if (rc) { CERROR("3c: write 1000 records failed at #%d: %d\n", i + 1, rc); RETURN(rc); } num_recs++; if ((rc = verify_handle("3b", llh, num_recs))) RETURN(rc); } if ((rc = verify_handle("3c", llh, num_recs))) RETURN(rc); CWARN("3d: write log more than BITMAP_SIZE, return -ENOSPC\n"); for (i = 0; i < LLOG_BITMAP_SIZE(llh->lgh_hdr) + 1; i++) { struct llog_rec_hdr hdr; char buf_even[24]; char buf_odd[32]; memset(buf_odd, 0, sizeof buf_odd); memset(buf_even, 0, sizeof buf_even); if ((i % 2) == 0) { hdr.lrh_len = 24; hdr.lrh_type = OBD_CFG_REC; rc = llog_write_rec(llh, &hdr, NULL, 0, buf_even, -1); } else { hdr.lrh_len = 32; hdr.lrh_type = OBD_CFG_REC; rc = llog_write_rec(llh, &hdr, NULL, 0, buf_odd, -1); } if (rc) { if (rc == -ENOSPC) { break; } else { CERROR("3c: write recs failed at #%d: %d\n", i + 1, rc); RETURN(rc); } } num_recs++; } if (rc != -ENOSPC) { CWARN("3d: write record more than BITMAP size!\n"); RETURN(-EINVAL); } if ((rc = verify_handle("3d", llh, num_recs))) RETURN(rc); RETURN(rc); }
/* 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); }