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

📄 store_rebuild.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
static voidstoreRebuildADirectory(void *unused){    int count;    rebuild_dir *d;    rebuild_dir **D;    if ((d = RebuildState.rebuild_dir) == NULL) {	storeRebuildComplete();	return;    }    count = d->rebuild_func(d);    RebuildState.rebuild_dir = d->next;    if (count < 0) {	xfree(d);    } else {	for (D = &RebuildState.rebuild_dir; *D; D = &(*D)->next);	*D = d;	d->next = NULL;    }    if (opt_foreground_rebuild)	storeRebuildADirectory(NULL);    else	eventAdd("storeRebuild", storeRebuildADirectory, NULL, 0.0, 1);}#if TEMP_UNUSED_CODEstatic voidstoreConvertFile(const cache_key * key,    int file_number,    size_t swap_file_sz,    time_t expires,    time_t timestamp,    time_t lastref,    time_t lastmod,    u_short refcount,    u_short flags,    int clean){    int fd_r, fd_w;    int hdr_len, x, y;    LOCAL_ARRAY(char, swapfilename, SQUID_MAXPATHLEN);    LOCAL_ARRAY(char, copybuf, DISK_PAGE_SIZE);    char *buf;    tlv *tlv_list;    StoreEntry e;    e.key = key;    e.swap_file_sz = swap_file_sz;    e.expires = expires;    e.lastref = lastref;    e.refcount = refcount;    e.flag = flags;    storeSwapFullPath(file_number, swapfilename);    fd_r = file_open(swapfilename, O_RDONLY, NULL, NULL, NULL);    if (fd_r < 0)	return;    safeunlink(swapfilename, 1);    fd_w = file_open(swapfilename, O_CREAT | O_WRONLY | O_TRUNC, NULL, NULL, NULL);    tlv_list = storeSwapMetaBuild(&e);    buf = storeSwapMetaPack(tlv_list, &hdr_len);    x = write(fd_w, buf, hdr_len);    while (x > 0) {	y = read(fd_r, copybuf, DISK_PAGE_SIZE);	x = write(fd_w, copybuf, y);    }    file_close(fd_r);    file_close(fd_w);    xfree(buf);    storeSwapTLVFree(tlv_list);}#endifstatic intstoreGetNextFile(rebuild_dir * d, int *sfileno, int *size){    int fd = -1;    int used = 0;    debug(20, 3) ("storeGetNextFile: flag=%d, %d: /%02X/%02X\n",	d->flag,	d->dirn,	d->curlvl1,	d->curlvl2);    if (d->done)	return -2;    while (fd < 0 && d->done == 0) {	fd = -1;	if (0 == d->flag) {	/* initialize, open first file */	    d->done = 0;	    d->curlvl1 = 0;	    d->curlvl2 = 0;	    d->in_dir = 0;	    d->flag = 1;	    assert(Config.cacheSwap.n_configured > 0);	}	if (0 == d->in_dir) {	/* we need to read in a new directory */	    snprintf(d->fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X",		Config.cacheSwap.swapDirs[d->dirn].path,		d->curlvl1, d->curlvl2);	    if (d->flag && d->td != NULL)		closedir(d->td);	    d->td = opendir(d->fullpath);	    if (d->td == NULL) {		debug(50, 1) ("storeGetNextFile: opendir: %s: %s\n",		    d->fullpath, xstrerror());	    } else {		d->entry = readdir(d->td);	/* skip . and .. */		d->entry = readdir(d->td);		if (d->entry == NULL && errno == ENOENT)		    debug(20, 1) ("storeGetNextFile: directory does not exist!.\n");		debug(20, 3) ("storeGetNextFile: Directory %s\n", d->fullpath);	    }	}	if (d->td != NULL && (d->entry = readdir(d->td)) != NULL) {	    d->in_dir++;	    if (sscanf(d->entry->d_name, "%x", &d->fn) != 1) {		debug(20, 3) ("storeGetNextFile: invalid %s\n",		    d->entry->d_name);		continue;	    }	    if (!storeFilenoBelongsHere(d->fn, d->dirn, d->curlvl1, d->curlvl2)) {		debug(20, 3) ("storeGetNextFile: %08X does not belong in %d/%d/%d\n",		    d->fn, d->dirn, d->curlvl1, d->curlvl2);		continue;	    }	    d->fn = storeDirProperFileno(d->dirn, d->fn);	    used = storeDirMapBitTest(d->fn);	    if (used) {		debug(20, 3) ("storeGetNextFile: Locked, continuing with next.\n");		continue;	    }	    snprintf(d->fullfilename, SQUID_MAXPATHLEN, "%s/%s",		d->fullpath, d->entry->d_name);	    debug(20, 3) ("storeGetNextFile: Opening %s\n", d->fullfilename);	    fd = file_open(d->fullfilename, O_RDONLY, NULL, NULL, NULL);	    if (fd < 0)		debug(50, 1) ("storeGetNextFile: %s: %s\n", d->fullfilename, xstrerror());	    continue;	    store_open_disk_fd++;	}	d->in_dir = 0;	if (++d->curlvl2 < Config.cacheSwap.swapDirs[d->dirn].l2)	    continue;	d->curlvl2 = 0;	if (++d->curlvl1 < Config.cacheSwap.swapDirs[d->dirn].l1)	    continue;	d->curlvl1 = 0;	d->done = 1;    }    *sfileno = d->fn;    return fd;}/* Add a new object to the cache with empty memory copy and pointer to disk * use to rebuild store from disk. */static StoreEntry *storeAddDiskRestore(const cache_key * key,    int file_number,    size_t swap_file_sz,    time_t expires,    time_t timestamp,    time_t lastref,    time_t lastmod,    u_num32 refcount,    u_short flags,    int clean){    StoreEntry *e = NULL;    debug(20, 5) ("StoreAddDiskRestore: %s, fileno=%08X\n", storeKeyText(key), file_number);    /* if you call this you'd better be sure file_number is not      * already in use! */    e = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);    e->store_status = STORE_OK;    storeSetMemStatus(e, NOT_IN_MEMORY);    e->swap_status = SWAPOUT_DONE;    e->swap_file_number = file_number;    e->swap_file_sz = swap_file_sz;    e->lock_count = 0;    e->refcount = 0;    e->lastref = lastref;    e->timestamp = timestamp;    e->expires = expires;    e->lastmod = lastmod;    e->refcount = refcount;    e->flags = flags;    EBIT_SET(e->flags, ENTRY_CACHABLE);    EBIT_CLR(e->flags, RELEASE_REQUEST);    EBIT_CLR(e->flags, KEY_PRIVATE);    e->ping_status = PING_NONE;    EBIT_CLR(e->flags, ENTRY_VALIDATED);    storeDirMapBitSet(e->swap_file_number);    storeHashInsert(e, key);	/* do it after we clear KEY_PRIVATE */    return e;}static voidstoreCleanup(void *datanotused){    static int bucketnum = -1;    static int validnum = 0;    static int store_errors = 0;    StoreEntry *e;    hash_link *link_ptr = NULL;    hash_link *link_next = NULL;    if (++bucketnum >= store_hash_buckets) {	debug(20, 1) ("  Completed Validation Procedure\n");	debug(20, 1) ("  Validated %d Entries\n", validnum);	debug(20, 1) ("  store_swap_size = %dk\n", store_swap_size);	store_rebuilding = 0;	if (opt_store_doublecheck)	    assert(store_errors == 0);	if (store_digest)	    storeDigestNoteStoreReady();	return;    }    link_next = hash_get_bucket(store_table, bucketnum);    while (NULL != (link_ptr = link_next)) {	link_next = link_ptr->next;	e = (StoreEntry *) link_ptr;	if (EBIT_TEST(e->flags, ENTRY_VALIDATED))	    continue;	/*	 * Calling storeRelease() has no effect because we're	 * still in 'store_rebuilding' state	 */	if (e->swap_file_number < 0)	    continue;	if (opt_store_doublecheck) {	    struct stat sb;	    if (stat(storeSwapFullPath(e->swap_file_number, NULL), &sb) < 0) {		store_errors++;		debug(20, 0) ("storeCleanup: MISSING SWAP FILE\n");		debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);		debug(20, 0) ("storeCleanup: PATH %s\n",		    storeSwapFullPath(e->swap_file_number, NULL));		storeEntryDump(e, 0);		continue;	    }	    if (e->swap_file_sz != sb.st_size) {		store_errors++;		debug(20, 0) ("storeCleanup: SIZE MISMATCH\n");		debug(20, 0) ("storeCleanup: FILENO %08X\n", e->swap_file_number);		debug(20, 0) ("storeCleanup: PATH %s\n",		    storeSwapFullPath(e->swap_file_number, NULL));		debug(20, 0) ("storeCleanup: ENTRY SIZE: %d, FILE SIZE: %d\n",		    e->swap_file_sz, (int) sb.st_size);		storeEntryDump(e, 0);		continue;	    }	}	EBIT_SET(e->flags, ENTRY_VALIDATED);	/* Only set the file bit if we know its a valid entry */	/* otherwise, set it in the validation procedure */	storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);	if ((++validnum & 0xFFFF) == 0)	    debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);    }    eventAdd("storeCleanup", storeCleanup, NULL, 0.0, 1);}voidstoreValidate(StoreEntry * e, STVLDCB * callback, void *callback_data, void *tag){    valid_ctrl_t *ctrlp;    char *path;    struct stat *sb;#if !USE_ASYNC_IO    int x;#endif    assert(!EBIT_TEST(e->flags, ENTRY_VALIDATED));    if (e->swap_file_number < 0) {	EBIT_CLR(e->flags, ENTRY_VALIDATED);	callback(callback_data, 0, 0);	return;    }    path = storeSwapFullPath(e->swap_file_number, NULL);    sb = xmalloc(sizeof(struct stat));    ctrlp = xmalloc(sizeof(valid_ctrl_t));    ctrlp->sb = sb;    ctrlp->e = e;    ctrlp->callback = callback;    ctrlp->callback_data = callback_data;#if USE_ASYNC_IO    aioStat(path, sb, storeValidateComplete, ctrlp, tag);#else    /*     * When evaluating the actual arguments in a function call, the order     * in which the arguments and the function expression are evaluated is     * not specified;     */    x = stat(path, sb);    storeValidateComplete(-1, ctrlp, x, errno);#endif    return;}static voidstoreValidateComplete(int fd, void *data, int retcode, int errcode){    valid_ctrl_t *ctrlp = data;    struct stat *sb = ctrlp->sb;    StoreEntry *e = ctrlp->e;    char *path;    if (retcode == -2 && errcode == -2) {	xfree(sb);	xfree(ctrlp);	ctrlp->callback(ctrlp->callback_data, retcode, errcode);	return;    }    if (retcode < 0 && errcode == EWOULDBLOCK) {	path = storeSwapFullPath(e->swap_file_number, NULL);	retcode = stat(path, sb);    }    if (retcode < 0 || sb->st_size == 0 || sb->st_size != e->swap_file_sz) {	EBIT_CLR(e->flags, ENTRY_VALIDATED);    } else {	EBIT_SET(e->flags, ENTRY_VALIDATED);	storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, 1);    }    errno = errcode;    ctrlp->callback(ctrlp->callback_data, retcode, errcode);    xfree(sb);    xfree(ctrlp);}/* meta data recreated from disk image in swap directory */static voidstoreRebuildComplete(void){    time_t r;    time_t stop;    stop = squid_curtime;    r = stop - RebuildState.start;    debug(20, 1) ("Finished rebuilding storage disk.\n");    debug(20, 1) ("  %7d Entries read from previous logfile.\n",	RebuildState.linecount);    debug(20, 1) ("  %7d Entries scanned from swap files.\n",	RebuildState.statcount);    debug(20, 1) ("  %7d Invalid entries.\n", RebuildState.invalid);    debug(20, 1) ("  %7d With invalid flags.\n", RebuildState.badflags);    debug(20, 1) ("  %7d Objects loaded.\n", RebuildState.objcount);    debug(20, 1) ("  %7d Objects expired.\n", RebuildState.expcount);    debug(20, 1) ("  %7d Objects cancelled.\n", RebuildState.cancelcount);    debug(20, 1) ("  %7d Duplicate URLs purged.\n", RebuildState.dupcount);    debug(20, 1) ("  %7d Swapfile clashes avoided.\n", RebuildState.clashcount);    debug(20, 1) ("  Took %d seconds (%6.1f objects/sec).\n",	r > 0 ? (int) r : 0,	(double) RebuildState.objcount / (r > 0 ? r : 1));    debug(20, 1) ("Beginning Validation Procedure\n");    eventAdd("storeCleanup", storeCleanup, NULL, 0.0, 1);}voidstoreRebuildStart(void){    rebuild_dir *d;    int clean = 0;    int zero = 0;    FILE *fp;    int i;    memset(&RebuildState, '\0', sizeof(RebuildState));    RebuildState.start = squid_curtime;    for (i = 0; i < Config.cacheSwap.n_configured; i++) {	d = xcalloc(1, sizeof(rebuild_dir));	d->dirn = i;	d->speed = opt_foreground_rebuild ? 1 << 30 : 50;	/*	 * If the swap.state file exists in the cache_dir, then	 * we'll use storeRebuildFromSwapLog(), otherwise we'll	 * use storeRebuildFromDirectory() to open up each file	 * and suck in the meta data.	 */	fp = storeDirOpenTmpSwapLog(i, &clean, &zero);	if (fp == NULL || zero) {	    if (fp != NULL)		fclose(fp);	    d->rebuild_func = storeRebuildFromDirectory;	} else {	    d->rebuild_func = storeRebuildFromSwapLog;	    d->log = fp;	    d->clean = clean;	}	d->next = RebuildState.rebuild_dir;	RebuildState.rebuild_dir = d;	if (!clean)	    RebuildState.need_to_validate = 1;	debug(20, 1) ("Rebuilding storage in Cache Dir #%d (%s)\n",	    i, clean ? "CLEAN" : "DIRTY");    }    eventAdd("storeRebuild", storeRebuildADirectory, NULL, 0.0, 1);}

⌨️ 快捷键说明

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