コード例 #1
0
ファイル: redo_lock.hpp プロジェクト: shambakey1/rstm_r5
 /**
  * Just a performance optimization. Sometimes it makes sense to verify a log
  * when we are inserting a new entry. We combine this into one operation so
  * that we don't iterate through the log twice.
  *
  * As opposed to the simple insert function, this /does/ check to see if the
  * object has already been inserted. In the case where the object already
  * exists and is current, we don't add it again.
  *
  * If the verification fails we'll abort
  *
  * @param shared  The address of the object that we read from.
  * @param version The version of the object that we read.
  *
  * @throws        stm::RollBack
  */
 void insertAndVerifyReads(Object* shared, unsigned long version) {
   assert(shared);
   for (ReadLog::iterator i = reads.begin(), e = reads.end(); i != e; ++i) {
     if (!isCurrent(i->shared, i->version))
       abort();
     if (shared == i->shared)
       return;
   }
   reads.insert(ReadLogEntry(shared, version));
 }
コード例 #2
0
ClassAdLog::ClassAdLog(const char *filename,int max_historical_logs_arg) : table(CLASSAD_LOG_HASHTABLE_SIZE, hashFunction)
{
	log_filename_buf = filename;
	active_transaction = NULL;
	m_nondurable_level = 0;

	this->max_historical_logs = max_historical_logs_arg;
	historical_sequence_number = 1;
	m_original_log_birthdate = time(NULL);

	int log_fd = safe_open_wrapper_follow(logFilename(), O_RDWR | O_CREAT | O_LARGEFILE, 0600);
	if (log_fd < 0) {
		EXCEPT("failed to open log %s, errno = %d", logFilename(), errno);
	}

	log_fp = fdopen(log_fd, "r+");
	if (log_fp == NULL) {
		EXCEPT("failed to fdopen log %s, errno = %d", logFilename(), errno);
	}


	// Read all of the log records
	LogRecord		*log_rec;
	unsigned long count = 0;
	bool is_clean = true; // was cleanly closed (until we find out otherwise)
	bool requires_successful_cleaning = false;
	long long next_log_entry_pos = 0;
    long long curr_log_entry_pos = 0;
	while ((log_rec = ReadLogEntry(log_fp, 1+count, InstantiateLogEntry)) != 0) {
        curr_log_entry_pos = next_log_entry_pos;
		next_log_entry_pos = ftell(log_fp);
		count++;
		switch (log_rec->get_op_type()) {
        case CondorLogOp_Error:
            // this is defensive, ought to be caught in InstantiateLogEntry()
            EXCEPT("ERROR: transaction record %lu was bad (byte offset %lld)\n", count, curr_log_entry_pos);
            break;
		case CondorLogOp_BeginTransaction:
			// this file contains transactions, so it must not
			// have been cleanly shut down
			is_clean = false;
			if (active_transaction) {
				dprintf(D_ALWAYS, "Warning: Encountered nested transactions in %s, "
						"log may be bogus...", filename);
			} else {
				active_transaction = new Transaction();
			}
			delete log_rec;
			break;
		case CondorLogOp_EndTransaction:
			if (!active_transaction) {
				dprintf(D_ALWAYS, "Warning: Encountered unmatched end transaction in %s, "
						"log may be bogus...", filename);
			} else {
				active_transaction->Commit(NULL, (void *)&table); // commit in memory only
				delete active_transaction;
				active_transaction = NULL;
			}
			delete log_rec;
			break;
		case CondorLogOp_LogHistoricalSequenceNumber:
			if(count != 1) {
				dprintf(D_ALWAYS, "Warning: Encountered historical sequence number after first log entry (entry number = %ld)\n",count);
			}
			historical_sequence_number = ((LogHistoricalSequenceNumber *)log_rec)->get_historical_sequence_number();
			m_original_log_birthdate = ((LogHistoricalSequenceNumber *)log_rec)->get_timestamp();
			delete log_rec;
			break;
		default:
			if (active_transaction) {
				active_transaction->AppendLog(log_rec);
			} else {
				log_rec->Play((void *)&table);
				delete log_rec;
			}
		}
	}
	long long final_log_entry_pos = ftell(log_fp);
	if( next_log_entry_pos != final_log_entry_pos ) {
		// The log file has a broken line at the end so we _must_
		// _not_ write anything more into this log.
		// (Alternately, we could try to clear out the broken entry
		// and continue writing into this file, but since we are about to
		// rotate the log anyway, we may as well just require the rotation
		// to be successful.  In the case where rotation fails, we will
		// probably soon fail to write to the log file anyway somewhere else.)
		dprintf(D_ALWAYS,"Detected unterminated log entry in ClassAd Log %s."
				" Forcing rotation.\n", logFilename());
		requires_successful_cleaning = true;
	}
	if (active_transaction) {	// abort incomplete transaction
		delete active_transaction;
		active_transaction = NULL;

		if( !requires_successful_cleaning ) {
			// For similar reasons as with broken log entries above,
			// we need to force rotation.
			dprintf(D_ALWAYS,"Detected unterminated transaction in ClassAd Log"
					"%s. Forcing rotation.\n", logFilename());
			requires_successful_cleaning = true;
		}
	}
	if(!count) {
		log_rec = new LogHistoricalSequenceNumber( historical_sequence_number, m_original_log_birthdate );
		if (log_rec->Write(log_fp) < 0) {
			EXCEPT("write to %s failed, errno = %d", logFilename(), errno);
		}
	}
	if( !is_clean || requires_successful_cleaning ) {
		if( !TruncLog() && requires_successful_cleaning ) {
			EXCEPT("Failed to rotate ClassAd log %s.\n", logFilename());
		}
	}
}
コード例 #3
0
ファイル: logging.c プロジェクト: strm/cdt316-lab2
int LogHandler(char cmd, int id_in, varList **commands, int *id_out) {
	int ret = 0;
	FILE *post_file = NULL;
	FILE *pre_file = NULL;
	char *post_log = NULL;
	char *pre_log = NULL;
	int post_log_len = strlen(LOG_PATH) + strlen(LOG_POST_NAME) + strlen(DB_GLOBAL) + 1;
	int pre_log_len = strlen(LOG_PATH) + strlen(LOG_PRE_NAME) + strlen(DB_GLOBAL) + 1;

	post_log = (char *)malloc(sizeof(char *) * post_log_len);
	pre_log = (char *)malloc(sizeof(char *) * pre_log_len);

	strncpy(post_log, LOG_PATH, post_log_len);
	strncat(post_log, DB_GLOBAL, post_log_len);
	strncat(post_log, LOG_POST_NAME, post_log_len);

	strncpy(pre_log, LOG_PATH, pre_log_len);
	strncat(pre_log, DB_GLOBAL, pre_log_len);
	strncat(pre_log, LOG_PRE_NAME, pre_log_len);

	switch (cmd){
		case LOG_WRITE_PRE:
			debug_out(4, "log: In LOG_WRITE_PRE\n");
			pre_file = fopen(pre_log, "a");
			if(pre_file != NULL)
				debug_out(4, "log: Opened file '%s'\n", pre_log);
			else
			{
				debug_out(4, "log: Could not open file '%s'\n", pre_log);
				ret = -1;
				break;
			}
			WriteLogEntry(pre_file, id_in, *commands);
			debug_out(4, "log: logentry written to file\n");
			break;
		case LOG_WRITE_POST:
			debug_out(4, "log: In LOG_WRITE_POST\n");
			post_file = fopen(post_log, "a");
			if(post_file != NULL)
				debug_out(4, "log: Opened file '%s'\n", post_log);
			else {
				debug_out(4, "log: Could not open file '%s'\n", post_log);
				ret = -1;
				break;
			}
			WriteLogEntry(post_file, id_in, *commands);
			debug_out(4, "log: logentry written to file\n");
			break;
		case LOG_READ_POST:
			post_file = fopen(post_log, "r");
			if(post_file != NULL) {
				if(ReadLogEntry(&post_file, &id_in, commands) == -1) {
					*id_out = LOG_NO_ID;
					ret = -1;
				}
			}
			break;
		case LOG_READ_PRE:
			pre_file = fopen(pre_log, "r");
			if(pre_file != NULL) {
				if(ReadLogEntry(&pre_file, &id_in, commands) == -1) {
					*id_out = LOG_NO_ID;
					ret = -1;
				}
			}
			break;
		case LOG_LAST_ID:
			if(id_out != NULL) {
				ret = GetLastId(pre_log, post_log, id_out);
			}
			else
				ret = -1;
			break;
		case LOG_GET_NEXT_PRE_ID:
			if(id_out != NULL)
				*id_out = GetNextId(pre_log, id_in);
			else
				ret = -1;
			break;
		case LOG_GET_NEXT_POST_ID:
			if(id_out != NULL)
				*id_out = GetNextId(post_log, id_in);
			else
				ret = -1;
			break;
		case LOG_CHECK_ID:
			break;
		default:
			ret = -1;
			break;
	}
	if(pre_file) {
		fclose(pre_file);
	}
	if(post_file) {
		fclose(post_file);
	}

	return ret;
}