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

📄 store_dir_coss.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * $Id: store_dir_coss.c,v 1.65 2006/10/26 20:00:21 serassio Exp $ * * DEBUG: section 47    Store COSS Directory Routines * AUTHOR: Eric Stern * * SQUID Web Proxy Cache          http://www.squid-cache.org/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from *  the Internet community; see the CONTRIBUTORS file for full *  details.   Many organizations have provided support for Squid's *  development; see the SPONSORS file for full details.  Squid is *  Copyrighted (C) 2001 by the Regents of the University of *  California; see the COPYRIGHT file for full details.  Squid *  incorporates software developed and/or copyrighted by other *  sources; see the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#if HAVE_AIO_H#include <aio.h>#endif#include "async_io.h"#include "store_coss.h"#if USE_AUFSOPS#include "../aufs/async_io.h"#endif#define STORE_META_BUFSZ 4096#define HITONLY_BUFS 2int max_coss_dir_size = 0;static int last_coss_pick_index = -1;int coss_initialised = 0;MemPool *coss_state_pool = NULL;MemPool *coss_index_pool = NULL;MemPool *coss_realloc_pool = NULL;MemPool *coss_op_pool = NULL;typedef struct _RebuildState RebuildState;struct _RebuildState {    SwapDir *sd;    int n_read;    FILE *log;    int report_interval;    int report_current;    struct {	unsigned int clean:1;    } flags;    struct _store_rebuild_data counts;    struct {	int new;	int reloc;	int fresher;	int unknown;    } cosscounts;};static char *storeCossDirSwapLogFile(SwapDir *, const char *);static void storeCossDirRebuild(SwapDir * sd);static void storeCossDirCloseTmpSwapLog(SwapDir * sd);static FILE *storeCossDirOpenTmpSwapLog(SwapDir *, int *, int *);static STLOGOPEN storeCossDirOpenSwapLog;static STINIT storeCossDirInit;static STLOGCLEANSTART storeCossDirWriteCleanStart;static STLOGCLEANNEXTENTRY storeCossDirCleanLogNextEntry;static STLOGCLEANWRITE storeCossDirWriteCleanEntry;static STLOGCLEANDONE storeCossDirWriteCleanDone;static STLOGCLOSE storeCossDirCloseSwapLog;static STLOGWRITE storeCossDirSwapLog;static STNEWFS storeCossDirNewfs;static STCHECKOBJ storeCossDirCheckObj;static STCHECKLOADAV storeCossDirCheckLoadAv;static STFREE storeCossDirShutdown;static STFSPARSE storeCossDirParse;static STFSRECONFIGURE storeCossDirReconfigure;static STDUMP storeCossDirDump;static STCALLBACK storeCossDirCallback;static void storeCossDirParseBlkSize(SwapDir *, const char *, const char *, int);static void storeCossDirParseOverwritePct(SwapDir *, const char *, const char *, int);static void storeCossDirParseMaxWaste(SwapDir *, const char *, const char *, int);static void storeCossDirParseMemOnlyBufs(SwapDir *, const char *, const char *, int);static void storeCossDirParseMaxFullBufs(SwapDir *, const char *, const char *, int);static void storeCossDirDumpBlkSize(StoreEntry *, const char *, SwapDir *);static void storeCossDirDumpOverwritePct(StoreEntry *, const char *, SwapDir *);static void storeCossDirDumpMaxWaste(StoreEntry *, const char *, SwapDir *);static void storeCossDirDumpMemOnlyBufs(StoreEntry *, const char *, SwapDir *);static void storeCossDirDumpMaxFullBufs(StoreEntry *, const char *, SwapDir *);static OBJH storeCossStats;static void storeDirCoss_StartDiskRebuild(RebuildState * rb);/* The "only" externally visible function */STSETUP storeFsSetup_coss;static struct cache_dir_option options[] ={    {"block-size", storeCossDirParseBlkSize, storeCossDirDumpBlkSize},    {"overwrite-percent", storeCossDirParseOverwritePct, storeCossDirDumpOverwritePct},    {"max-stripe-waste", storeCossDirParseMaxWaste, storeCossDirDumpMaxWaste},    {"membufs", storeCossDirParseMemOnlyBufs, storeCossDirDumpMemOnlyBufs},    {"maxfullbufs", storeCossDirParseMaxFullBufs, storeCossDirDumpMaxFullBufs},    {NULL, NULL}};struct _coss_stats coss_stats;char const *stripePath(SwapDir * sd){    CossInfo *cs = (CossInfo *) sd->fsdata;    char pathtmp[SQUID_MAXPATHLEN];    struct stat st;    if (!cs->stripe_path) {	strcpy(pathtmp, sd->path);	if (stat(sd->path, &st) == 0) {	    if (S_ISDIR(st.st_mode))		strcat(pathtmp, "/stripe");	} else	    fatalf("stripePath: Cannot stat %s.", sd->path);	cs->stripe_path = xstrdup(pathtmp);    }    return cs->stripe_path;}static char *storeCossDirSwapLogFile(SwapDir * sd, const char *ext){    LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);    LOCAL_ARRAY(char, pathtmp, SQUID_MAXPATHLEN);    LOCAL_ARRAY(char, digit, 32);    char *pathtmp2;    struct stat st;    if (Config.Log.swap) {	xstrncpy(pathtmp, sd->path, SQUID_MAXPATHLEN - 64);	pathtmp2 = pathtmp;	while ((pathtmp2 = strchr(pathtmp2, '/')) != NULL)	    *pathtmp2 = '.';	while (strlen(pathtmp) && pathtmp[strlen(pathtmp) - 1] == '.')	    pathtmp[strlen(pathtmp) - 1] = '\0';	for (pathtmp2 = pathtmp; *pathtmp2 == '.'; pathtmp2++);	snprintf(path, SQUID_MAXPATHLEN - 64, Config.Log.swap, pathtmp2);	if (strncmp(path, Config.Log.swap, SQUID_MAXPATHLEN - 64) == 0) {	    strcat(path, ".");	    snprintf(digit, 32, "%02d", sd->index);	    strncat(path, digit, 3);	}    } else {	if (stat(sd->path, &st) == 0) {	    if (S_ISDIR(st.st_mode)) {		xstrncpy(path, sd->path, SQUID_MAXPATHLEN - 64);		strcat(path, "/swap.state");	    } else		fatal("storeCossDirSwapLogFile: 'cache_swap_log' is needed in your COSS configuration.");	} else	    fatalf("storeCossDirSwapLogFile: Cannot stat %s.", sd->path);    }    if (ext)	strncat(path, ext, 16);    return path;}static voidstoreCossDirOpenSwapLog(SwapDir * sd){    CossInfo *cs = (CossInfo *) sd->fsdata;    char *path;    int fd;    path = storeCossDirSwapLogFile(sd, NULL);    fd = file_open(path, O_WRONLY | O_CREAT | O_BINARY);    if (fd < 0) {	debug(79, 1) ("%s: %s\n", path, xstrerror());	fatal("storeCossDirOpenSwapLog: Failed to open swap log.");    }    debug(79, 3) ("Cache COSS Dir #%d log opened on FD %d\n", sd->index, fd);    cs->swaplog_fd = fd;}static voidstoreCossDirCloseSwapLog(SwapDir * sd){    CossInfo *cs = (CossInfo *) sd->fsdata;    if (cs->swaplog_fd < 0)	/* not open */	return;    file_close(cs->swaplog_fd);    debug(79, 3) ("Cache COSS Dir #%d log closed on FD %d\n",	sd->index, cs->swaplog_fd);    cs->swaplog_fd = -1;}static voidstoreCossDirInit(SwapDir * sd){    CossInfo *cs = (CossInfo *) sd->fsdata;    /* COSS is pretty useless without 64 bit file offsets */    if (sizeof(off_t) < 8) {	fatalf("COSS will not function without large file support (off_t is %d bytes long. Please reconsider recompiling squid with --with-large-files\n", (int) sizeof(off_t));    }#if USE_AUFSOPS    aioInit();    squidaio_init();#else    a_file_setupqueue(&cs->aq);#endif    cs->fd = file_open(stripePath(sd), O_RDWR | O_CREAT | O_BINARY);    if (cs->fd < 0) {	debug(79, 1) ("%s: %s\n", stripePath(sd), xstrerror());	fatal("storeCossDirInit: Failed to open a COSS file.");    }    storeCossDirOpenSwapLog(sd);    storeCossDirRebuild(sd);    n_coss_dirs++;    /*     * fs.blksize is normally determined by calling statvfs() etc,     * but we just set it here.  It is used in accounting the     * total store size, and is reported in cachemgr 'storedir'     * page.     */    sd->fs.blksize = 1 << cs->blksz_bits;    comm_quick_poll_required();}voidstoreCossRemove(SwapDir * sd, StoreEntry * e){    CossInfo *cs = (CossInfo *) sd->fsdata;    int stripe;#if 0    debug(1, 1) ("storeCossRemove: %x: %d/%d\n", e, (int) e->swap_dirn, (e) e->swap_filen);#endif    CossIndexNode *coss_node = e->repl.data;    /* Do what the LRU and HEAP repl policies do.. */    if (e->repl.data == NULL) {	return;    }    assert(sd->index == e->swap_dirn);    assert(e->swap_filen >= 0);    e->repl.data = NULL;    stripe = storeCossFilenoToStripe(cs, e->swap_filen);    dlinkDelete(&coss_node->node, &cs->stripes[stripe].objlist);    memPoolFree(coss_index_pool, coss_node);    cs->count -= 1;}voidstoreCossAdd(SwapDir * sd, StoreEntry * e, int curstripe){    CossInfo *cs = (CossInfo *) sd->fsdata;    CossStripe *cstripe = &cs->stripes[curstripe];    CossIndexNode *coss_node = memPoolAlloc(coss_index_pool);    assert(!e->repl.data);    assert(sd->index == e->swap_dirn);    /* Make sure the object exists in the current stripe, it should do! */    assert(curstripe == storeCossFilenoToStripe(cs, e->swap_filen));    e->repl.data = coss_node;    dlinkAddTail(e, &coss_node->node, &cstripe->objlist);    cs->count += 1;}static voidstoreCossRebuildComplete(void *data){    RebuildState *rb = data;    SwapDir *SD = rb->sd;    CossInfo *cs = SD->fsdata;    storeCossStartMembuf(SD);    store_dirs_rebuilding--;    storeCossDirCloseTmpSwapLog(SD);    storeRebuildComplete(&rb->counts);    debug(47, 1) ("COSS: %s: Rebuild Completed\n", stripePath(SD));    cs->rebuild.rebuilding = 0;    debug(47, 1) ("  %d objects scanned, %d objects relocated, %d objects fresher, %d objects ignored\n",	rb->counts.scancount, rb->cosscounts.reloc, rb->cosscounts.fresher, rb->cosscounts.unknown);    cbdataFree(rb);}CBDATA_TYPE(RebuildState);static voidstoreCossDirRebuild(SwapDir * sd){    RebuildState *rb;    int clean = 0;    int zero = 0;    FILE *fp;    CBDATA_INIT_TYPE(RebuildState);    rb = cbdataAlloc(RebuildState);    rb->sd = sd;    rb->flags.clean = (unsigned int) clean;    fp = storeCossDirOpenTmpSwapLog(sd, &clean, &zero);    fclose(fp);    debug(20, 1) ("Rebuilding COSS storage in %s (DIRTY)\n", stripePath(sd));    store_dirs_rebuilding++;    storeDirCoss_StartDiskRebuild(rb);}static voidstoreCossDirCloseTmpSwapLog(SwapDir * sd){    CossInfo *cs = (CossInfo *) sd->fsdata;    char *swaplog_path = xstrdup(storeCossDirSwapLogFile(sd, NULL));    char *new_path = xstrdup(storeCossDirSwapLogFile(sd, ".new"));    int fd;    file_close(cs->swaplog_fd);    if (xrename(new_path, swaplog_path) < 0) {	fatal("storeCossDirCloseTmpSwapLog: rename failed");    }    fd = file_open(swaplog_path, O_WRONLY | O_CREAT | O_BINARY);    if (fd < 0) {	debug(50, 1) ("%s: %s\n", swaplog_path, xstrerror());	fatal("storeCossDirCloseTmpSwapLog: Failed to open swap log.");    }    safe_free(swaplog_path);    safe_free(new_path);    cs->swaplog_fd = fd;    debug(47, 3) ("Cache COSS Dir #%d log opened on FD %d\n", sd->index, fd);}static FILE *storeCossDirOpenTmpSwapLog(SwapDir * sd, int *clean_flag, int *zero_flag){    CossInfo *cs = (CossInfo *) sd->fsdata;    char *swaplog_path = xstrdup(storeCossDirSwapLogFile(sd, NULL));    char *clean_path = xstrdup(storeCossDirSwapLogFile(sd, ".last-clean"));    char *new_path = xstrdup(storeCossDirSwapLogFile(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 COSS 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 (cs->swaplog_fd >= 0)	file_close(cs->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.");    }    cs->swaplog_fd = 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)

⌨️ 快捷键说明

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