⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	need_free = 0;	hdrsize = HDR_NORMAL_SZ;	is_hmac = 0;	recsize = sizeof(LOGP);	if (CRYPTO_ON(dbenv)) {		hdrsize = HDR_CRYPTO_SZ;		recsize = sizeof(LOGP);		recsize += db_cipher->adj_size(recsize);		is_hmac = 1;	}	if ((ret = __os_calloc(dbenv, 1, recsize + hdrsize, &tmp)) != 0)		return (ret);	need_free = 1;	hdr = (HDR *)tmp;	persist = (LOGP *)(tmp + hdrsize);	/* Try to read the header. */	if ((ret = __os_read(dbenv, &fh, tmp, recsize + hdrsize, &nw)) != 0 ||	    nw != recsize + hdrsize) {		if (ret == 0)			status = DB_LV_INCOMPLETE;		else			/*			 * The error was a fatal read error, not just an			 * incompletely initialized log file.			 */			__db_err(dbenv, "Ignoring log file: %s: %s",			    fname, db_strerror(ret));		(void)__os_closehandle(dbenv, &fh);		goto err;	}	(void)__os_closehandle(dbenv, &fh);	/*	 * Now we have to validate the persistent record.  We have	 * several scenarios we have to deal with:	 *	 * 1.  User has crypto turned on:	 *	- They're reading an old, unencrypted log file	 *	  .  We will fail the record size match check below.	 *	- They're reading a current, unencrypted log file	 *	  .  We will fail the record size match check below.	 *	- They're reading an old, encrypted log file [NOT YET]	 *	  .  After decryption we'll fail the version check.  [NOT YET]	 *	- They're reading a current, encrypted log file	 *	  .  We should proceed as usual.	 * 2.  User has crypto turned off:	 *	- They're reading an old, unencrypted log file	 *	  .  We will fail the version check.	 *	- They're reading a current, unencrypted log file	 *	  .  We should proceed as usual.	 *	- They're reading an old, encrypted log file [NOT YET]	 *	  .  We'll fail the magic number check (it is encrypted).	 *	- They're reading a current, encrypted log file	 *	  .  We'll fail the magic number check (it is encrypted).	 */	if (CRYPTO_ON(dbenv)) {		/*		 * If we are trying to decrypt an unencrypted log		 * we can only detect that by having an unreasonable		 * data length for our persistent data.		 */		if ((hdr->len - hdrsize) != sizeof(LOGP)) {			__db_err(dbenv, "log record size mismatch");			goto err;		}		/* Check the checksum and decrypt. */		if ((ret = __db_check_chksum(dbenv, db_cipher, &hdr->chksum[0],		    (u_int8_t *)persist, hdr->len - hdrsize, is_hmac)) != 0) {			__db_err(dbenv, "log record checksum mismatch");			goto err;		}		if ((ret = db_cipher->decrypt(dbenv, db_cipher->data,		    &hdr->iv[0], (u_int8_t *)persist, hdr->len - hdrsize)) != 0)			goto err;	}	/* Validate the header. */	if (persist->magic != DB_LOGMAGIC) {		__db_err(dbenv,		    "Ignoring log file: %s: magic number %lx, not %lx",		    fname, (u_long)persist->magic, (u_long)DB_LOGMAGIC);		ret = EINVAL;		goto err;	}	/*	 * Set our status code to indicate whether the log file	 * belongs to an unreadable or readable old version;  leave it	 * alone if and only if the log file version is the current one.	 */	if (persist->version > DB_LOGVERSION) {		/* This is a fatal error--the log file is newer than DB. */		__db_err(dbenv,		    "Ignoring log file: %s: unsupported log version %lu",		    fname, (u_long)persist->version);		ret = EINVAL;		goto err;	} else if (persist->version < DB_LOGOLDVER) {		status = DB_LV_OLD_UNREADABLE;		/*		 * We don't want to set persistent info based on an		 * unreadable region, so jump to "err".		 */		goto err;	} else if (persist->version < DB_LOGVERSION)		status = DB_LV_OLD_READABLE;	/*	 * Only if we have a current log do we verify the checksum.	 * We could not check the checksum before checking the magic	 * and version because old log hdrs have the length and checksum	 * in a different location.	 */	if (!CRYPTO_ON(dbenv) && ((ret = __db_check_chksum(dbenv,	    db_cipher, &hdr->chksum[0], (u_int8_t *)persist,	    hdr->len - hdrsize, is_hmac)) != 0)) {		__db_err(dbenv, "log record checksum mismatch");		goto err;	}	/*	 * If the log is readable so far and we're doing system initialization,	 * set the region's persistent information based on the headers.	 *	 * Always set the current log file size.  Only set the next log file's	 * size if the application hasn't set it already.	 *	 * XXX	 * Always use the persistent header's mode, regardless of what was set	 * in the current environment.  We've always done it this way, but it's	 * probably a bug -- I can't think of a way not-changing the mode would	 * be a problem, though.	 */	if (set_persist) {		region = dblp->reginfo.primary;		region->log_size = persist->log_size;		if (region->log_nsize == 0)			region->log_nsize = persist->log_size;		region->persist.mode = persist->mode;	}err:	__os_free(dbenv, fname);	if (need_free)		__os_free(dbenv, tmp);	*statusp = status;	return (ret);}/* * __log_dbenv_refresh -- *	Clean up after the log system on a close or failed open.  Called only * from __dbenv_refresh.  (Formerly called __log_close.) * * PUBLIC: int __log_dbenv_refresh __P((DB_ENV *)); */int__log_dbenv_refresh(dbenv)	DB_ENV *dbenv;{	DB_LOG *dblp;	int ret, t_ret;	dblp = dbenv->lg_handle;	/* We may have opened files as part of XA; if so, close them. */	F_SET(dblp, DBLOG_RECOVER);	ret = __dbreg_close_files(dbenv);	/* Discard the per-thread lock. */	if (dblp->mutexp != NULL)		__db_mutex_free(dbenv, &dblp->reginfo, dblp->mutexp);	/* Detach from the region. */	if ((t_ret =	    __db_r_detach(dbenv, &dblp->reginfo, 0)) != 0 && ret == 0)		ret = t_ret;	/* Close open files, release allocated memory. */	if (F_ISSET(&dblp->lfh, DB_FH_VALID) &&	    (t_ret = __os_closehandle(dbenv, &dblp->lfh)) != 0 && ret == 0)		ret = t_ret;	if (dblp->dbentry != NULL)		__os_free(dbenv, dblp->dbentry);	__os_free(dbenv, dblp);	dbenv->lg_handle = NULL;	return (ret);}/* * __log_stat -- *	Return log statistics. * * PUBLIC: int __log_stat __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); */int__log_stat(dbenv, statp, flags)	DB_ENV *dbenv;	DB_LOG_STAT **statp;	u_int32_t flags;{	DB_LOG *dblp;	DB_LOG_STAT *stats;	LOG *region;	int ret;	PANIC_CHECK(dbenv);	ENV_REQUIRES_CONFIG(dbenv,	    dbenv->lg_handle, "DB_ENV->log_stat", DB_INIT_LOG);	*statp = NULL;	if ((ret = __db_fchk(dbenv,	    "DB_ENV->log_stat", flags, DB_STAT_CLEAR)) != 0)		return (ret);	dblp = dbenv->lg_handle;	region = dblp->reginfo.primary;	if ((ret = __os_umalloc(dbenv, sizeof(DB_LOG_STAT), &stats)) != 0)		return (ret);	/* Copy out the global statistics. */	R_LOCK(dbenv, &dblp->reginfo);	*stats = region->stat;	if (LF_ISSET(DB_STAT_CLEAR))		memset(&region->stat, 0, sizeof(region->stat));	stats->st_magic = region->persist.magic;	stats->st_version = region->persist.version;	stats->st_mode = region->persist.mode;	stats->st_lg_bsize = region->buffer_size;	stats->st_lg_size = region->log_nsize;	stats->st_region_wait = dblp->reginfo.rp->mutex.mutex_set_wait;	stats->st_region_nowait = dblp->reginfo.rp->mutex.mutex_set_nowait;	if (LF_ISSET(DB_STAT_CLEAR)) {		dblp->reginfo.rp->mutex.mutex_set_wait = 0;		dblp->reginfo.rp->mutex.mutex_set_nowait = 0;	}	stats->st_regsize = dblp->reginfo.rp->size;	stats->st_cur_file = region->lsn.file;	stats->st_cur_offset = region->lsn.offset;	stats->st_disk_file = region->s_lsn.file;	stats->st_disk_offset = region->s_lsn.offset;	R_UNLOCK(dbenv, &dblp->reginfo);	*statp = stats;	return (0);}/* * __log_get_cached_ckp_lsn -- *	Retrieve any last checkpoint LSN that we may have found on startup. * * PUBLIC: void __log_get_cached_ckp_lsn __P((DB_ENV *, DB_LSN *)); */void__log_get_cached_ckp_lsn(dbenv, ckp_lsnp)	DB_ENV *dbenv;	DB_LSN *ckp_lsnp;{	DB_LOG *dblp;	LOG *lp;	dblp = (DB_LOG *)dbenv->lg_handle;	lp = (LOG *)dblp->reginfo.primary;	R_LOCK(dbenv, &dblp->reginfo);	*ckp_lsnp = lp->cached_ckp_lsn;	R_UNLOCK(dbenv, &dblp->reginfo);}/* * __log_region_size -- *	Return the amount of space needed for the log region. *	Make the region large enough to hold txn_max transaction *	detail structures  plus some space to hold thread handles *	and the beginning of the shalloc region and anything we *	need for mutex system resource recording. */static size_t__log_region_size(dbenv)	DB_ENV *dbenv;{	size_t s;	s = dbenv->lg_regionmax + dbenv->lg_bsize;#ifdef HAVE_MUTEX_SYSTEM_RESOURCES	if (F_ISSET(dbenv, DB_ENV_THREAD))		s += sizeof(REGMAINT) + LG_MAINT_SIZE;#endif	return (s);}/* * __log_region_destroy *	Destroy any region maintenance info. * * PUBLIC: void __log_region_destroy __P((DB_ENV *, REGINFO *)); */void__log_region_destroy(dbenv, infop)	DB_ENV *dbenv;	REGINFO *infop;{	__db_shlocks_destroy(infop, (REGMAINT *)R_ADDR(infop,	    ((LOG *)R_ADDR(infop, infop->rp->primary))->maint_off));	COMPQUIET(dbenv, NULL);	COMPQUIET(infop, NULL);}/* * __log_vtruncate *	This is a virtual truncate.  We set up the log indicators to * make everyone believe that the given record is the last one in the * log.  Returns with the next valid LSN (i.e., the LSN of the next * record to be written). This is used in replication to discard records * in the log file that do not agree with the master. * * PUBLIC: int __log_vtruncate __P((DB_ENV *, DB_LSN *, DB_LSN *)); */int__log_vtruncate(dbenv, lsn, ckplsn)	DB_ENV *dbenv;	DB_LSN *lsn, *ckplsn;{	DBT log_dbt;	DB_FH fh;	DB_LOG *dblp;	DB_LOGC *logc;	DB_LSN end_lsn;	LOG *lp;	u_int32_t bytes, c_len;	int fn, ret, t_ret;	char *fname;	/* Need to find out the length of this soon-to-be-last record. */	if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0)		return (ret);	memset(&log_dbt, 0, sizeof(log_dbt));	ret = logc->get(logc, lsn, &log_dbt, DB_SET);	c_len = logc->c_len;	if ((t_ret = logc->close(logc, 0)) != 0 && ret == 0)		ret = t_ret;	if (ret != 0)		return (ret);	/* Now do the truncate. */	dblp = (DB_LOG *)dbenv->lg_handle;	lp = (LOG *)dblp->reginfo.primary;	R_LOCK(dbenv, &dblp->reginfo);	end_lsn = lp->lsn;	lp->lsn = *lsn;	lp->len = c_len;	lp->lsn.offset += lp->len;	/*	 * I am going to assume that the number of bytes written since	 * the last checkpoint doesn't exceed a 32-bit number.	 */	DB_ASSERT(lp->lsn.file >= ckplsn->file);	bytes = 0;	if (ckplsn->file != lp->lsn.file) {		bytes = lp->log_size - ckplsn->offset;		if (lp->lsn.file > ckplsn->file + 1)			bytes += lp->log_size *			    (lp->lsn.file - ckplsn->file - 1);		bytes += lp->lsn.offset;	} else		bytes = lp->lsn.offset - ckplsn->offset;	lp->stat.st_wc_mbytes += bytes / MEGABYTE;	lp->stat.st_wc_bytes += bytes % MEGABYTE;	/*	 * If the saved lsn is greater than our new end of log, reset it	 * to our current end of log.	 */	if (log_compare(&lp->s_lsn, lsn) > 0)		lp->s_lsn = lp->lsn;	/*	 * If the new end of log is in the middle of the buffer,	 * don't change the w_off or f_lsn.  If the new end is	 * before the w_off then reset w_off and f_lsn to the new	 * end of log.	 */	if (lp->w_off >= lp->lsn.offset) {		lp->f_lsn = lp->lsn;		lp->w_off = lp->lsn.offset;		lp->b_off = 0;	} else		lp->b_off = lp->lsn.offset - lp->w_off;	ZERO_LSN(lp->waiting_lsn);	lp->ready_lsn = lp->lsn;	lp->wait_recs = 0;	lp->rcvd_recs = 0;	/* Now throw away any extra log files that we have around. */	for (fn = lp->lsn.file + 1;; fn++) {		if (__log_name(dblp, fn, &fname, &fh, DB_OSO_RDONLY) != 0) {			__os_free(dbenv, fname);			break;		}		(void)__os_closehandle(dbenv, &fh);		ret = __os_unlink(dbenv, fname);		__os_free(dbenv, fname);		if (ret != 0)			goto err;	}	/* Truncate the log to the new point. */	if ((ret = __log_zero(dbenv, &lp->lsn, &end_lsn)) != 0)		goto err;err:	R_UNLOCK(dbenv, &dblp->reginfo);	return (ret);}/* * __log_is_outdated -- *	Used by the replication system to identify if a client's logs * are too old.  The log represented by dbenv is compared to the file * number passed in fnum.  If the log file fnum does not exist and is * lower-numbered than the current logs, the we return *outdatedp non * zero, else we return it 0. * * PUBLIC: int __log_is_outdated __P((DB_ENV *dbenv, * PUBLIC:     u_int32_t fnum, int *outdatedp)); */int__log_is_outdated(dbenv, fnum, outdatedp)	DB_ENV *dbenv;	u_int32_t fnum;	int *outdatedp;{	DB_LOG *dblp;	LOG *lp;	char *name;	int ret;	u_int32_t cfile;	dblp = dbenv->lg_handle;	*outdatedp = 0;	if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0)		return (ret);	/* If the file exists, we're just fine. */	if (__os_exists(name, NULL) == 0)		goto out;	/*	 * It didn't exist, decide if the file number is too big or	 * too little.  If it's too little, then we need to indicate	 * that the LSN is outdated.	 */	R_LOCK(dbenv, &dblp->reginfo);	lp = (LOG *)dblp->reginfo.primary;	cfile = lp->lsn.file;	R_UNLOCK(dbenv, &dblp->reginfo);	if (cfile > fnum)		*outdatedp = 1;out:	__os_free(dbenv, name);	return (ret);}/* * __log_zero -- *	Zero out the tail of a log after a truncate. */static int__log_zero(dbenv, from_lsn, to_lsn)	DB_ENV *dbenv;	DB_LSN *from_lsn, *to_lsn;{	char *lname;	DB_LOG *dblp;	LOG *lp;	int ret;	size_t nbytes, len, nw;	u_int8_t buf[4096];	u_int32_t mbytes, bytes;	dblp = dbenv->lg_handle;	lp = (LOG *)dblp->reginfo.primary;	lname = NULL;	if (dblp->lfname != lp->lsn.file) {		if (F_ISSET(&dblp->lfh, DB_FH_VALID))			(void)__os_closehandle(dbenv, &dblp->lfh);		dblp->lfname = lp->lsn.file;	}	if (from_lsn->file != to_lsn->file) {		/* We removed some log files; have to 0 to end of file. */		if (!F_ISSET(&dblp->lfh, DB_FH_VALID) && (ret =		    __log_name(dblp, dblp->lfname, &lname, &dblp->lfh, 0)) != 0)			return (ret);		if ((ret = __os_ioinfo(dbenv,		    NULL, &dblp->lfh, &mbytes, &bytes, NULL)) != 0)			goto err;		len = mbytes * MEGABYTE + bytes - from_lsn->offset;	} else if (to_lsn->offset <= from_lsn->offset)		return (0);	else		len = to_lsn->offset = from_lsn->offset;	memset(buf, 0, sizeof(buf));	/* Initialize the write position. */	if (!F_ISSET(&dblp->lfh, DB_FH_VALID) &&	    (ret = __log_name(dblp, dblp->lfname, &lname, &dblp->lfh, 0)) != 0)		goto err;	if ((ret = __os_seek(dbenv,	    &dblp->lfh, 0, 0, from_lsn->offset, 0, DB_OS_SEEK_SET)) != 0)		return (ret);	while (len > 0) {		nbytes = len > sizeof(buf) ? sizeof(buf) : len;		if ((ret =		    __os_write(dbenv, &dblp->lfh, buf, nbytes, &nw)) != 0)			return (ret);		len -= nbytes;	}err:	if (lname != NULL)		__os_free(dbenv, lname);	return (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -