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

📄 store_dir_diskd.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (fd < 0) {	debug(50, 1) ("%s: %s\n", swaplog_path, xstrerror());	fatal("storeDiskdDirCloseTmpSwapLog: Failed to open swap log.");    }    safe_free(swaplog_path);    safe_free(new_path);    diskdinfo->swaplog_fd = fd;    debug(47, 3) ("Cache Dir #%d log opened on FD %d\n", sd->index, fd);}static voidstoreSwapLogDataFree(void *s){    memFree(s, MEM_SWAP_LOG_DATA);}static voidstoreDiskdWriteSwapLogheader(int fd){    storeSwapLogHeader *hdr = memAllocate(MEM_SWAP_LOG_DATA);    hdr->op = SWAP_LOG_VERSION;    hdr->version = 1;    hdr->record_size = sizeof(storeSwapLogData);    /* The header size is a full log record to keep some level of backward     * compatibility even if the actual header is smaller     */    file_write(fd,	-1,	hdr,	sizeof(storeSwapLogData),	NULL,	NULL,	(FREE *) storeSwapLogDataFree);}static FILE *storeDiskdDirOpenTmpSwapLog(SwapDir * sd, int *clean_flag, int *zero_flag){    diskdinfo_t *diskdinfo = sd->fsdata;    char *swaplog_path = xstrdup(storeDiskdDirSwapLogFile(sd, NULL));    char *clean_path = xstrdup(storeDiskdDirSwapLogFile(sd, ".last-clean"));    char *new_path = xstrdup(storeDiskdDirSwapLogFile(sd, ".new"));    struct stat log_sb;    struct stat clean_sb;    FILE *fp;    int fd;    if (stat(swaplog_path, &log_sb) < 0) {	debug(47, 1) ("Cache Dir #%d: No log file\n", sd->index);	safe_free(swaplog_path);	safe_free(clean_path);	safe_free(new_path);	return NULL;    }    *zero_flag = log_sb.st_size == 0 ? 1 : 0;    /* close the existing write-only FD */    if (diskdinfo->swaplog_fd >= 0)	file_close(diskdinfo->swaplog_fd);    /* open a write-only FD for the new log */    fd = file_open(new_path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);    if (fd < 0) {	debug(50, 1) ("%s: %s\n", new_path, xstrerror());	fatal("storeDirOpenTmpSwapLog: Failed to open swap log.");    }    diskdinfo->swaplog_fd = fd;    storeDiskdWriteSwapLogheader(fd);    /* open a read-only stream of the old log */    fp = fopen(swaplog_path, "rb");    if (fp == NULL) {	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());	fatal("Failed to open swap log for reading");    }    memset(&clean_sb, '\0', sizeof(struct stat));    if (stat(clean_path, &clean_sb) < 0)	*clean_flag = 0;    else if (clean_sb.st_mtime < log_sb.st_mtime)	*clean_flag = 0;    else	*clean_flag = 1;    safeunlink(clean_path, 1);    safe_free(swaplog_path);    safe_free(clean_path);    safe_free(new_path);    return fp;}struct _clean_state {    char *cur;    char *new;    char *cln;    char *outbuf;    int outbuf_offset;    int fd;    RemovalPolicyWalker *walker;};#define CLEAN_BUF_SZ 16384/* * Begin the process to write clean cache state.  For DISKD this means * opening some log files and allocating write buffers.  Return 0 if * we succeed, and assign the 'func' and 'data' return pointers. */static intstoreDiskdDirWriteCleanStart(SwapDir * sd){    struct _clean_state *state = xcalloc(1, sizeof(*state));#if HAVE_FCHMOD    struct stat sb;#endif    sd->log.clean.write = NULL;    sd->log.clean.state = NULL;    state->new = xstrdup(storeDiskdDirSwapLogFile(sd, ".clean"));    state->cur = xstrdup(storeDiskdDirSwapLogFile(sd, NULL));    state->cln = xstrdup(storeDiskdDirSwapLogFile(sd, ".last-clean"));    state->outbuf = xcalloc(CLEAN_BUF_SZ, 1);    state->outbuf_offset = 0;    state->walker = sd->repl->WalkInit(sd->repl);    unlink(state->cln);    state->fd = file_open(state->new, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);    if (state->fd < 0) {	xfree(state->new);	xfree(state->cur);	xfree(state->cln);	xfree(state);	return -1;    }    debug(20, 3) ("storeDirWriteCleanLogs: opened %s, FD %d\n",	state->new, state->fd);    storeDiskdWriteSwapLogheader(state->fd);#if HAVE_FCHMOD    if (stat(state->cur, &sb) == 0)	fchmod(state->fd, sb.st_mode);#endif    sd->log.clean.write = storeDiskdDirWriteCleanEntry;    sd->log.clean.state = state;    return 0;}/* * Get the next entry that is a candidate for clean log writing */const StoreEntry *storeDiskdDirCleanLogNextEntry(SwapDir * sd){    const StoreEntry *entry = NULL;    struct _clean_state *state = sd->log.clean.state;    if (state->walker)	entry = state->walker->Next(state->walker);    return entry;}/* * "write" an entry to the clean log file. */static voidstoreDiskdDirWriteCleanEntry(SwapDir * sd, const StoreEntry * e){    storeSwapLogData s;    static size_t ss = sizeof(storeSwapLogData);    struct _clean_state *state = sd->log.clean.state;    memset(&s, '\0', ss);    s.op = (char) SWAP_LOG_ADD;    s.swap_filen = e->swap_filen;    s.timestamp = e->timestamp;    s.lastref = e->lastref;    s.expires = e->expires;    s.lastmod = e->lastmod;    s.swap_file_sz = e->swap_file_sz;    s.refcount = e->refcount;    s.flags = e->flags;    xmemcpy(&s.key, e->hash.key, MD5_DIGEST_CHARS);    xmemcpy(state->outbuf + state->outbuf_offset, &s, ss);    state->outbuf_offset += ss;    /* buffered write */    if (state->outbuf_offset + ss > CLEAN_BUF_SZ) {	if (FD_WRITE_METHOD(state->fd, state->outbuf, state->outbuf_offset) < 0) {	    debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n",		state->new, xstrerror());	    debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n");	    file_close(state->fd);	    state->fd = -1;	    unlink(state->new);	    safe_free(state);	    sd->log.clean.state = NULL;	    sd->log.clean.write = NULL;	    return;	}	state->outbuf_offset = 0;    }}static voidstoreDiskdDirWriteCleanDone(SwapDir * sd){    struct _clean_state *state = sd->log.clean.state;    if (NULL == state)	return;    if (state->fd < 0)	return;    state->walker->Done(state->walker);    if (FD_WRITE_METHOD(state->fd, state->outbuf, state->outbuf_offset) < 0) {	debug(50, 0) ("storeDirWriteCleanLogs: %s: write: %s\n",	    state->new, xstrerror());	debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile "	    "not replaced.\n");	file_close(state->fd);	state->fd = -1;	unlink(state->new);    }    safe_free(state->outbuf);    /*     * You can't rename open files on Microsoft "operating systems"     * so we have to close before renaming.     */    storeDiskdDirCloseSwapLog(sd);    /* rename */    if (state->fd >= 0) {#ifdef _SQUID_OS2_	file_close(state->fd);	state->fd = -1;#endif	xrename(state->new, state->cur);    }    /* touch a timestamp file if we're not still validating */    if (store_dirs_rebuilding)	(void) 0;    else if (state->fd < 0)	(void) 0;    else	file_close(file_open(state->cln, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY));    /* close */    safe_free(state->cur);    safe_free(state->new);    safe_free(state->cln);    if (state->fd >= 0)	file_close(state->fd);    state->fd = -1;    safe_free(state);    sd->log.clean.state = NULL;    sd->log.clean.write = NULL;}static voidstoreDiskdDirSwapLog(const SwapDir * sd, const StoreEntry * e, int op){    diskdinfo_t *diskdinfo = sd->fsdata;    storeSwapLogData *s = memAllocate(MEM_SWAP_LOG_DATA);    s->op = (char) op;    s->swap_filen = e->swap_filen;    s->timestamp = e->timestamp;    s->lastref = e->lastref;    s->expires = e->expires;    s->lastmod = e->lastmod;    s->swap_file_sz = e->swap_file_sz;    s->refcount = e->refcount;    s->flags = e->flags;    xmemcpy(s->key, e->hash.key, MD5_DIGEST_CHARS);    file_write(diskdinfo->swaplog_fd,	-1,	s,	sizeof(storeSwapLogData),	NULL,	NULL,	(FREE *) storeSwapLogDataFree);}static voidstoreDiskdDirNewfs(SwapDir * sd){    debug(47, 3) ("Creating swap space in %s\n", sd->path);    storeDiskdDirCreateDirectory(sd->path, 0);    storeDiskdDirCreateSwapSubDirs(sd);}static intrev_int_sort(const void *A, const void *B){    const int *i1 = A;    const int *i2 = B;    return *i2 - *i1;}static intstoreDiskdDirClean(int swap_index){    DIR *dp = NULL;    struct dirent *de = NULL;    LOCAL_ARRAY(char, p1, MAXPATHLEN + 1);    LOCAL_ARRAY(char, p2, MAXPATHLEN + 1);#if USE_TRUNCATE    struct stat sb;#endif    int files[20];    int swapfileno;    int fn;			/* same as swapfileno, but with dirn bits set */    int n = 0;    int k = 0;    int N0, N1, N2;    int D0, D1, D2;    SwapDir *SD;    diskdinfo_t *diskdinfo;    N0 = n_diskd_dirs;    D0 = diskd_dir_index[swap_index % N0];    SD = &Config.cacheSwap.swapDirs[D0];    diskdinfo = SD->fsdata;    N1 = diskdinfo->l1;    D1 = (swap_index / N0) % N1;    N2 = diskdinfo->l2;    D2 = ((swap_index / N0) / N1) % N2;    snprintf(p1, SQUID_MAXPATHLEN, "%s/%02X/%02X",	Config.cacheSwap.swapDirs[D0].path, D1, D2);    debug(36, 3) ("storeDirClean: Cleaning directory %s\n", p1);    dp = opendir(p1);    if (dp == NULL) {	if (errno == ENOENT) {	    debug(36, 0) ("storeDirClean: WARNING: Creating %s\n", p1);	    if (mkdir(p1, 0777) == 0)		return 0;	}	debug(50, 0) ("storeDirClean: %s: %s\n", p1, xstrerror());	safeunlink(p1, 1);	return 0;    }    while ((de = readdir(dp)) != NULL && k < 20) {	if (sscanf(de->d_name, "%X", &swapfileno) != 1)	    continue;	fn = swapfileno;	/* XXX should remove this cruft ! */	if (storeDiskdDirValidFileno(SD, fn, 1))	    if (storeDiskdDirMapBitTest(SD, fn))		if (storeDiskdFilenoBelongsHere(fn, D0, D1, D2))		    continue;#if USE_TRUNCATE	if (!stat(de->d_name, &sb))	    if (sb.st_size == 0)		continue;#endif	files[k++] = swapfileno;    }    closedir(dp);    if (k == 0)	return 0;    qsort(files, k, sizeof(int), rev_int_sort);    if (k > 10)	k = 10;    for (n = 0; n < k; n++) {	debug(36, 3) ("storeDirClean: Cleaning file %08X\n", files[n]);	snprintf(p2, MAXPATHLEN + 1, "%s/%08X", p1, files[n]);#if USE_TRUNCATE	truncate(p2, 0);#else	safeunlink(p2, 0);#endif	statCounter.swap.files_cleaned++;    }    debug(36, 3) ("Cleaned %d unused files from %s\n", k, p1);    return k;}static voidstoreDiskdDirCleanEvent(void *unused){    static int swap_index = 0;    int i;    int j = 0;    int n = 0;    /*     * Assert that there are DISKD cache_dirs configured, otherwise     * we should never be called.     */    assert(n_diskd_dirs);    if (NULL == diskd_dir_index) {	SwapDir *sd;	diskdinfo_t *diskdinfo;	/*	 * Initialize the little array that translates DISKD cache_dir	 * number into the Config.cacheSwap.swapDirs array index.	 */	diskd_dir_index = xcalloc(n_diskd_dirs, sizeof(*diskd_dir_index));	for (i = 0, n = 0; i < Config.cacheSwap.n_configured; i++) {	    sd = &Config.cacheSwap.swapDirs[i];	    if (!storeDiskdDirIs(sd))		continue;	    diskd_dir_index[n++] = i;	    diskdinfo = sd->fsdata;	    j += (diskdinfo->l1 * diskdinfo->l2);	}	assert(n == n_diskd_dirs);	/*	 * Start the storeDiskdDirClean() swap_index with a random	 * value.  j equals the total number of DISKD level 2	 * swap directories	 */	swap_index = (int) (squid_random() % j);    }    if (0 == store_dirs_rebuilding) {	n = storeDiskdDirClean(swap_index);	swap_index++;    }    eventAdd("storeDirClean", storeDiskdDirCleanEvent, NULL,	15.0 * exp(-0.25 * n), 1);}static intstoreDiskdDirIs(SwapDir * sd){    if (strncmp(sd->type, "diskd", 3) == 0)	return 1;    return 0;}/* * Does swapfile number 'fn' belong in cachedir #F0, * level1 dir #F1, level2 dir #F2? */static intstoreDiskdFilenoBelongsHere(int fn, int F0, int F1, int F2){    int D1, D2;    int L1, L2;    int filn = fn;    diskdinfo_t *diskdinfo;    assert(F0 < Config.cacheSwap.n_configured);    diskdinfo = Config.cacheSwap.swapDirs[F0].fsdata;    L1 = diskdinfo->l1;    L2 = diskdinfo->l2;    D1 = ((filn / L2) / L2) % L1;    if (F1 != D1)	return 0;    D2 = (filn / L2) % L2;    if (F2 != D2)	return 0;    return 1;}int

⌨️ 快捷键说明

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