w_rc_t sthread_t::pread(int fd, void *buf, int n, fileoff_t pos) { fd -= fd_base; if (fd < 0 || fd >= (int)open_max || !_disks[fd]) return RC(stBADFD); INC_STH_STATS(read); int done = 0; w_rc_t e; errno = 0; e = _disks[fd]->pread(buf, n, pos, done); if (!e.is_error() && done != n) { e = RC2(stSHORTIO, done); } return e; }
w_rc_t get_archived_log_file ( const char *filename, ss_m::partition_number_t num) { fprintf(stdout, "\n**************************************** RECOVER %s : %d\n", filename, num ); dump(); w_rc_t rc; static char O[smlevel_0::max_devname<<1]; strcat(O, filename); strcat(O, ".bak"); static char N[smlevel_0::max_devname<<1]; strcat(N, filename); int e = ::rename(O, N); if(e != 0) { fprintf(stdout, "Could not move %s to %s: error : %d %s\n", O, N, e, strerror(errno)); rc = RC2(smlevel_0::eOUTOFLOGSPACE, errno); } dump(); fprintf(stdout, "recovered ... OK!\n\n"); fprintf(stdout, "This recovery of the log file will enable us to finish the abort.\n"); fprintf(stdout, "It will not continue the device/volume set up.\n"); fprintf(stdout, "Expect an error message and stack trace about that:\n\n"); return rc; }
w_rc_t out_of_log_space ( xct_i* iter, xct_t *& xd, smlevel_0::fileoff_t curr, smlevel_0::fileoff_t thresh, const char *filename ) { static int calls=0; calls++; w_rc_t rc; fprintf(stdout, "\n**************************************** %d\n", calls); dump(); fprintf(stdout, "Called out_of_log_space with curr %lld thresh %lld, file %s\n", (long long) curr, (long long) thresh, filename); { w_ostrstream o; o << xd->tid() << endl; fprintf(stdout, "called with xct %s\n" , o.c_str()); } xd->log_warn_disable(); iter->never_mind(); // release the mutex { w_ostrstream o; static sm_stats_info_t curr; W_DO( ssm->gather_stats(curr)); o << curr.sm.log_bytes_generated << ends; fprintf(stdout, "stats: log_bytes_generated %s\n" , o.c_str()); } lsn_t target; { w_ostrstream o; o << "Active xcts: " << xct_t::num_active_xcts() << " "; tid_t old = xct_t::oldest_tid(); o << "Oldest transaction: " << old; xct_t *x = xct_t::look_up(old); if(x==NULL) { fprintf(stdout, "Could not find %s\n", o.c_str()); W_FATAL(fcINTERNAL); } target = x->first_lsn(); o << " First lsn: " << x->first_lsn(); o << " Last lsn: " << x->last_lsn(); fprintf(stdout, "%s\n" , o.c_str()); } if(calls > 3) { // See what happens... static tid_t aborted_tid; if(aborted_tid == xd->tid()) { w_ostrstream o; o << aborted_tid << endl; fprintf(stdout, "Multiple calls with same victim! : %s total calls %d\n", o.c_str(), calls); W_FATAL(smlevel_0::eINTERNAL); } aborted_tid = xd->tid(); fprintf(stdout, "\n\n******************************** ABORTING\n\n"); return RC(smlevel_0::eUSERABORT); // sm will abort this guy } fprintf(stdout, "\n\n******************************** ARCHIVING \n\n"); fprintf(stdout, "Move aside log file log.%d to log.%d.bak\n", target.file(), target.file()); static char O[smlevel_0::max_devname<<1]; strcat(O, filename); static char N[smlevel_0::max_devname<<1]; strcat(N, filename); strcat(N, ".bak"); int e = ::rename(O, N); if(e != 0) { fprintf(stdout, "Could not move %s to %s: error : %d %s\n", O, N, e, strerror(errno)); if(errno == ENOENT) { fprintf(stdout, "Ignored error.\n\n"); return RCOK; // just to ignore these. } fprintf(stdout, "Returning eOUTOFLOGSPACE.\n\n"); rc = RC2(smlevel_0::eOUTOFLOGSPACE, errno); } else { dump(); fprintf(stdout, "archived ... OK\n\n"); W_COERCE(ss_m::log_file_was_archived(filename)); } return rc; }