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

📄 store_dir_diskd.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: store_dir_diskd.c,v 1.85 2006/09/22 00:51:43 adrian Exp $ * * DEBUG: section 47    Store Directory Routines * AUTHOR: Duane Wessels * * 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"#include <sys/ipc.h>#include <sys/msg.h>#include <sys/shm.h>#include "store_diskd.h"#define DefaultLevelOneDirs     16#define DefaultLevelTwoDirs     256#define STORE_META_BDISKDZ 4096diskd_stats_t diskd_stats;typedef struct _RebuildState RebuildState;struct _RebuildState {    SwapDir *sd;    int n_read;    FILE *log;    int speed;    int curlvl1;    int curlvl2;    struct {	unsigned int need_to_validate:1;	unsigned int clean:1;	unsigned int init:1;    } flags;    int done;    int in_dir;    int fn;    struct dirent *entry;    DIR *td;    char fullpath[SQUID_MAXPATHLEN];    char fullfilename[SQUID_MAXPATHLEN];    struct _store_rebuild_data counts;};static int n_diskd_dirs = 0;static int *diskd_dir_index = NULL;MemPool *diskd_state_pool = NULL;static int diskd_initialised = 0;static char *storeDiskdDirSwapSubDir(SwapDir *, int subdirn);static int storeDiskdDirCreateDirectory(const char *path, int);static int storeDiskdDirVerifyCacheDirs(SwapDir *);static int storeDiskdDirVerifyDirectory(const char *path);static void storeDiskdDirCreateSwapSubDirs(SwapDir *);static char *storeDiskdDirSwapLogFile(SwapDir *, const char *);static EVH storeDiskdDirRebuildFromDirectory;static EVH storeDiskdDirRebuildFromSwapLog;static int storeDiskdDirGetNextFile(RebuildState *, sfileno *, int *size);static StoreEntry *storeDiskdDirAddDiskRestore(SwapDir * SD, const cache_key * key,    sfileno file_number,    squid_file_sz swap_file_sz,    time_t expires,    time_t timestamp,    time_t lastref,    time_t lastmod,    u_num32 refcount,    u_short flags,    int clean);static void storeDiskdDirRebuild(SwapDir * sd);static void storeDiskdDirCloseTmpSwapLog(SwapDir * sd);static FILE *storeDiskdDirOpenTmpSwapLog(SwapDir *, int *, int *);static STLOGOPEN storeDiskdDirOpenSwapLog;static STINIT storeDiskdDirInit;static STCHECKCONFIG storeDiskdCheckConfig;static STFREE storeDiskdDirFree;static STLOGCLEANSTART storeDiskdDirWriteCleanStart;static STLOGCLEANNEXTENTRY storeDiskdDirCleanLogNextEntry;static STLOGCLEANWRITE storeDiskdDirWriteCleanEntry;static STLOGCLEANDONE storeDiskdDirWriteCleanDone;static STLOGCLOSE storeDiskdDirCloseSwapLog;static STLOGWRITE storeDiskdDirSwapLog;static STNEWFS storeDiskdDirNewfs;static STDUMP storeDiskdDirDump;static STMAINTAINFS storeDiskdDirMaintain;static STCHECKOBJ storeDiskdDirCheckObj;static STCHECKLOADAV storeDiskdDirCheckLoadAv;static STREFOBJ storeDiskdDirRefObj;static STUNREFOBJ storeDiskdDirUnrefObj;static QS rev_int_sort;static int storeDiskdDirClean(int swap_index);static EVH storeDiskdDirCleanEvent;static int storeDiskdDirIs(SwapDir * sd);static int storeDiskdFilenoBelongsHere(int fn, int F0, int F1, int F2);static int storeDiskdCleanupDoubleCheck(SwapDir *, StoreEntry *);static void storeDiskdDirStats(SwapDir *, StoreEntry *);static void storeDiskdDirInitBitmap(SwapDir *);static int storeDiskdDirValidFileno(SwapDir *, sfileno, int);static void storeDiskdStats(StoreEntry * sentry);static void storeDiskdDirSync(SwapDir *);/* The only externally visible interface */STSETUP storeFsSetup_diskd;/* * These functions were ripped straight out of the heart of store_dir.c. * They assume that the given filenum is on a diskd partiton, which may or * may not be true..  * XXX this evilness should be tidied up at a later date! */static intstoreDiskdDirMapBitTest(SwapDir * SD, sfileno filn){    diskdinfo_t *diskdinfo;    diskdinfo = SD->fsdata;    return file_map_bit_test(diskdinfo->map, filn);}static voidstoreDiskdDirMapBitSet(SwapDir * SD, sfileno filn){    diskdinfo_t *diskdinfo;    diskdinfo = SD->fsdata;    file_map_bit_set(diskdinfo->map, filn);}voidstoreDiskdDirMapBitReset(SwapDir * SD, sfileno filn){    diskdinfo_t *diskdinfo;    diskdinfo = SD->fsdata;    /*      * We have to test the bit before calling file_map_bit_reset.     * file_map_bit_reset doesn't do bounds checking.  It assumes     * filn is a valid file number, but it might not be because     * the map is dynamic in size.  Also clearing an already clear     * bit puts the map counter of-of-whack.     */    if (file_map_bit_test(diskdinfo->map, filn))	file_map_bit_reset(diskdinfo->map, filn);}intstoreDiskdDirMapBitAllocate(SwapDir * SD){    diskdinfo_t *diskdinfo = SD->fsdata;    int fn;    fn = file_map_allocate(diskdinfo->map, diskdinfo->suggest);    file_map_bit_set(diskdinfo->map, fn);    diskdinfo->suggest = fn + 1;    return fn;}/* * Initialise the diskd bitmap * * If there already is a bitmap, and the numobjects is larger than currently * configured, we allocate a new bitmap and 'grow' the old one into it. */static voidstoreDiskdDirInitBitmap(SwapDir * sd){    diskdinfo_t *diskdinfo = sd->fsdata;    if (diskdinfo->map == NULL) {	/* First time */	diskdinfo->map = file_map_create();    } else if (diskdinfo->map->max_n_files) {	/* it grew, need to expand */	/* XXX We don't need it anymore .. */    }    /* else it shrunk, and we leave the old one in place */}static char *storeDiskdDirSwapSubDir(SwapDir * sd, int subdirn){    diskdinfo_t *diskdinfo = sd->fsdata;    LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN);    assert(0 <= subdirn && subdirn < diskdinfo->l1);    snprintf(fullfilename, SQUID_MAXPATHLEN, "%s/%02X", sd->path, subdirn);    return fullfilename;}static intstoreDiskdDirCreateDirectory(const char *path, int should_exist){    int created = 0;    struct stat st;    getCurrentTime();    if (0 == stat(path, &st)) {	if (S_ISDIR(st.st_mode)) {	    debug(20, should_exist ? 3 : 1) ("%s exists\n", path);	} else {	    fatalf("Swap directory %s is not a directory.", path);	}    } else if (0 == mkdir(path, 0755)) {	debug(20, should_exist ? 1 : 3) ("%s created\n", path);	created = 1;    } else {	fatalf("Failed to make swap directory %s: %s",	    path, xstrerror());    }    return created;}static intstoreDiskdDirVerifyDirectory(const char *path){    struct stat sb;    if (stat(path, &sb) < 0) {	debug(20, 0) ("%s: %s\n", path, xstrerror());	return -1;    }    if (S_ISDIR(sb.st_mode) == 0) {	debug(20, 0) ("%s is not a directory\n", path);	return -1;    }    return 0;}/* * This function is called by storeDiskdDirInit().  If this returns < 0, * then Squid exits, complains about swap directories not * existing, and instructs the admin to run 'squid -z' */static intstoreDiskdDirVerifyCacheDirs(SwapDir * sd){    diskdinfo_t *diskdinfo = sd->fsdata;    int j;    const char *path = sd->path;    if (storeDiskdDirVerifyDirectory(path) < 0)	return -1;    for (j = 0; j < diskdinfo->l1; j++) {	path = storeDiskdDirSwapSubDir(sd, j);	if (storeDiskdDirVerifyDirectory(path) < 0)	    return -1;    }    return 0;}static voidstoreDiskdDirCreateSwapSubDirs(SwapDir * sd){    diskdinfo_t *diskdinfo = sd->fsdata;    int i, k;    int should_exist;    LOCAL_ARRAY(char, name, MAXPATHLEN);    for (i = 0; i < diskdinfo->l1; i++) {	snprintf(name, MAXPATHLEN, "%s/%02X", sd->path, i);	if (storeDiskdDirCreateDirectory(name, 0))	    should_exist = 0;	else	    should_exist = 1;	debug(47, 1) ("Making directories in %s\n", name);	for (k = 0; k < diskdinfo->l2; k++) {	    snprintf(name, MAXPATHLEN, "%s/%02X/%02X", sd->path, i, k);	    storeDiskdDirCreateDirectory(name, should_exist);	}    }}static char *storeDiskdDirSwapLogFile(SwapDir * sd, const char *ext){    LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);    LOCAL_ARRAY(char, pathtmp, SQUID_MAXPATHLEN);    LOCAL_ARRAY(char, digit, 32);    char *pathtmp2;    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 {	xstrncpy(path, sd->path, SQUID_MAXPATHLEN - 64);	strcat(path, "/swap.state");    }    if (ext)	strncat(path, ext, 16);    return path;}static voidstoreDiskdDirOpenSwapLog(SwapDir * sd){    diskdinfo_t *diskdinfo = sd->fsdata;    char *path;    int fd;    path = storeDiskdDirSwapLogFile(sd, NULL);    fd = file_open(path, O_WRONLY | O_CREAT | O_BINARY);    if (fd < 0) {	debug(50, 1) ("%s: %s\n", path, xstrerror());	fatal("storeDiskdDirOpenSwapLog: Failed to open swap log.");    }    debug(47, 3) ("Cache Dir #%d log opened on FD %d\n", sd->index, fd);    diskdinfo->swaplog_fd = fd;    if (0 == n_diskd_dirs)	assert(NULL == diskd_dir_index);    n_diskd_dirs++;    assert(n_diskd_dirs <= Config.cacheSwap.n_configured);}static voidstoreDiskdDirCloseSwapLog(SwapDir * sd){    diskdinfo_t *diskdinfo = sd->fsdata;    if (diskdinfo->swaplog_fd < 0)	/* not open */	return;    file_close(diskdinfo->swaplog_fd);    debug(47, 3) ("Cache Dir #%d log closed on FD %d\n",	sd->index, diskdinfo->swaplog_fd);    diskdinfo->swaplog_fd = -1;    n_diskd_dirs--;    assert(n_diskd_dirs >= 0);    if (0 == n_diskd_dirs)	safe_free(diskd_dir_index);}static voidstoreDiskdCheckConfig(SwapDir * sd){    requirePathnameExists("diskd_program", Config.Program.diskd);    if (!opt_create_swap_dirs)	requirePathnameExists("cache_dir", sd->path);}static voiddiskdExited(int fd, void *unused){    fatal("diskd exited unexpectedly");}static voidstoreDiskdDirInit(SwapDir * sd){    static int started_clean_event = 0;    pid_t pid;    int i;    int ikey;    const char *args[5];    char skey1[32];    char skey2[32];    char skey3[32];    diskdinfo_t *diskdinfo = sd->fsdata;    static const char *errmsg =    "\tFailed to verify one of the swap directories, Check cache.log\n"    "\tfor details.  Run 'squid -z' to create swap directories\n"    "\tif needed, or if running Squid for the first time.";    ikey = (getpid() << 10) + (sd->index << 2);    ikey &= 0x7fffffff;    diskdinfo->smsgid = msgget((key_t) ikey, 0700 | IPC_CREAT);    if (diskdinfo->smsgid < 0) {	debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());	fatal("msgget failed");    }    diskdinfo->rmsgid = msgget((key_t) (ikey + 1), 0700 | IPC_CREAT);    if (diskdinfo->rmsgid < 0) {	debug(50, 0) ("storeDiskdInit: msgget: %s\n", xstrerror());	fatal("msgget failed");    }    diskdinfo->shm.nbufs = diskdinfo->magic2 * 1.3;    diskdinfo->shm.id = shmget((key_t) (ikey + 2),	diskdinfo->shm.nbufs * SHMBUF_BLKSZ, 0600 | IPC_CREAT);    if (diskdinfo->shm.id < 0) {	debug(50, 0) ("storeDiskdInit: shmget: %s\n", xstrerror());	fatal("shmget failed");    }    diskdinfo->shm.buf = shmat(diskdinfo->shm.id, NULL, 0);    if (diskdinfo->shm.buf == (void *) -1) {	debug(50, 0) ("storeDiskdInit: shmat: %s\n", xstrerror());	fatal("shmat failed");    }    diskdinfo->shm.inuse_map = xcalloc((diskdinfo->shm.nbufs + 7) / 8, 1);    diskd_stats.shmbuf_count += diskdinfo->shm.nbufs;    for (i = 0; i < diskdinfo->shm.nbufs; i++) {	CBIT_SET(diskdinfo->shm.inuse_map, i);	storeDiskdShmPut(sd, i * SHMBUF_BLKSZ);    }    snprintf(skey1, 32, "%d", ikey);    snprintf(skey2, 32, "%d", ikey + 1);    snprintf(skey3, 32, "%d", ikey + 2);    args[0] = "diskd";    args[1] = skey1;    args[2] = skey2;    args[3] = skey3;    args[4] = NULL;    pid = ipcCreate(IPC_STREAM,	Config.Program.diskd,	args,	"diskd",	&diskdinfo->rfd,	&diskdinfo->wfd,

⌨️ 快捷键说明

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