From: wessels <> Date: Wed, 4 Feb 1998 05:08:10 +0000 (+0000) Subject: Fixed swap meta for store_swapin.c and store_swapout.c X-Git-Tag: SQUID_3_0_PRE1~4193 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e3ef2b0996b961cbd8266a67cca585dc78ea5bec;p=thirdparty%2Fsquid.git Fixed swap meta for store_swapin.c and store_swapout.c Create store_log.c Made file_write() void Other misc I'm sure --- diff --git a/src/Makefile.in b/src/Makefile.in index c6ed5497ad..c0cfcb63d9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.118 1998/02/03 01:17:02 wessels Exp $ +# $Id: Makefile.in,v 1.119 1998/02/03 22:08:10 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -119,6 +119,7 @@ OBJS = \ store_client.o \ store_dir.o \ store_key_md5.o \ + store_log.o \ store_rebuild.o \ store_swapin.o \ store_swapmeta.o \ diff --git a/src/access_log.cc b/src/access_log.cc index 409728bb11..d54c85bb99 100644 --- a/src/access_log.cc +++ b/src/access_log.cc @@ -1,7 +1,7 @@ /* - * $Id: access_log.cc,v 1.20 1998/02/03 04:21:10 wessels Exp $ + * $Id: access_log.cc,v 1.21 1998/02/03 22:08:10 wessels Exp $ * * DEBUG: section 46 Access Log * AUTHOR: Duane Wessels @@ -201,7 +201,6 @@ accessLogOpen(const char *fname) void accessLogLog(AccessLogEntry * al) { - int x; int l; char *t; char *xbuf = NULL; @@ -243,15 +242,13 @@ accessLogLog(AccessLogEntry * al) safe_free(ereq); safe_free(erep); } - x = file_write(LogfileFD, + file_write(LogfileFD, -1, xstrdup(log_buf), l, NULL, NULL, xfree); - if (x != DISK_OK) - debug(46, 1) ("log_append: File write failed.\n"); safe_free(xbuf); } diff --git a/src/disk.cc b/src/disk.cc index aa84df18cc..804f3fadb5 100644 --- a/src/disk.cc +++ b/src/disk.cc @@ -1,6 +1,6 @@ /* - * $Id: disk.cc,v 1.98 1998/02/02 21:16:21 wessels Exp $ + * $Id: disk.cc,v 1.99 1998/02/03 22:08:11 wessels Exp $ * * DEBUG: section 6 Disk I/O Routines * AUTHOR: Harvest Derived @@ -355,7 +355,7 @@ diskHandleWriteComplete(void *data, int len, int errcode) /* write block to a file */ /* write back queue. Only one writer at a time. */ /* call a handle when writing is complete. */ -int +void file_write(int fd, off_t file_offset, char *ptr_to_buf, @@ -395,7 +395,6 @@ file_write(int fd, #endif EBIT_SET(F->flags, FD_WRITE_DAEMON); } - return DISK_OK; } diff --git a/src/globals.h b/src/globals.h index cede3cd5db..fa818cac07 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1,6 +1,6 @@ /* - * $Id: globals.h,v 1.30 1998/02/03 07:35:26 wessels Exp $ + * $Id: globals.h,v 1.31 1998/02/03 22:08:12 wessels Exp $ */ extern FILE *debug_log; /* NULL */ @@ -54,7 +54,6 @@ extern int icmp_sock; /* -1 */ extern int neighbors_do_private_keys; /* 1 */ extern int opt_accel_uses_host; /* 0 */ extern int opt_catch_signals; /* 1 */ -extern int opt_convert; /* 0 */ extern int opt_debug_stderr; /* 0 */ extern int opt_dns_tests; /* 1 */ extern int opt_foreground_rebuild; /* 0 */ @@ -101,6 +100,7 @@ extern double request_failure_ratio; /* 0.0 */ extern int store_hash_buckets; /* 0 */ extern hash_table *store_table; /* NULL */ extern size_t cacheKeySize; +extern dlink_list store_list; #ifdef HAVE_SYSLOG extern int _db_level; diff --git a/src/main.cc b/src/main.cc index 51486eae1b..3f7466733d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.210 1998/02/02 21:15:03 wessels Exp $ + * $Id: main.cc,v 1.211 1998/02/03 22:08:12 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -149,7 +149,6 @@ usage(void) " -v Print version.\n" " -z Create swap directories\n" " -C Do not catch fatal signals.\n" - " -c Convert store from <1.2.\n" " -D Disable initial DNS tests.\n" " -F Foreground fast store rebuild.\n" " -N No daemon mode.\n" @@ -167,7 +166,7 @@ mainParseOptions(int argc, char *argv[]) extern char *optarg; int c; - while ((c = getopt(argc, argv, "CDFNRVYXa:cdf:hk:m:su:vz?")) != -1) { + while ((c = getopt(argc, argv, "CDFNRVYXa:df:hk:m:su:vz?")) != -1) { switch (c) { case 'C': opt_catch_signals = 0; @@ -197,9 +196,6 @@ mainParseOptions(int argc, char *argv[]) case 'a': httpPortNumOverride = atoi(optarg); break; - case 'c': - opt_convert = 1; - break; case 'd': opt_debug_stderr = 1; break; @@ -377,9 +373,7 @@ mainReconfigure(void) serverConnectionsOpen(); if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy)) neighbors_open(theOutIcpConnection); -#if 0 storeDirOpenSwapLogs(); -#endif debug(1, 0) ("Ready to serve requests.\n"); } @@ -583,8 +577,8 @@ main(int argc, char **argv) } else if (rotate_pending) { icmpClose(); _db_rotate_log(); /* cache.log */ - storeWriteCleanLogs(1); - storeRotateLog(); /* store.log */ + storeDirWriteCleanLogs(1); + storeLogRotate(); /* store.log */ accessLogRotate(); /* access.log */ useragentRotateLog(); /* useragent.log */ icmpOpen(); diff --git a/src/protos.h b/src/protos.h index 891171697d..2a0473ee39 100644 --- a/src/protos.h +++ b/src/protos.h @@ -122,7 +122,7 @@ extern void _db_print(); extern int file_open(const char *path, int mode, FOCB *, void *callback_data, void *tag); extern void file_close(int fd); -extern int file_write(int, off_t, char *, int len, DWCB *, void *, FREE *); +extern void file_write(int, off_t, char *, int len, DWCB *, void *, FREE *); extern int file_read(int, char *, int, off_t, DRCB *, void *); extern int disk_init(void); extern int diskWriteIsComplete(int); @@ -413,14 +413,11 @@ extern void storeClientCopy(StoreEntry * e, STCB * callback, void *data); extern int storePendingNClients(const StoreEntry *); -extern int storeWriteCleanLogs(int reopen); extern HASHCMP urlcmp; extern EVH storeMaintainSwapSpace; extern void storeExpireNow(StoreEntry *); extern void storeReleaseRequest(StoreEntry *); -extern void storeRotateLog(void); extern off_t storeLowestMemReaderOffset(const StoreEntry *); -extern void storeCloseLog(void); extern void storeConfigure(void); extern void storeNegativeCache(StoreEntry *); extern void storeFreeMemory(void); @@ -433,7 +430,7 @@ extern time_t storeExpiredReferenceAge(void); extern void storeRegisterAbort(StoreEntry * e, STABH * cb, void *); extern void storeUnregisterAbort(StoreEntry * e); extern void storeMemObjectDump(MemObject * mem); -extern void storeEntryDump(StoreEntry * e); +extern void storeEntryDump(StoreEntry * e, int debug_lvl); extern const char *storeUrl(const StoreEntry *); extern void storeCreateMemObject(StoreEntry *, const char *, const char *); extern void storeCopyNotModifiedReplyHeaders(MemObject * O, MemObject * N); @@ -450,9 +447,16 @@ extern void storeAppendPrintf(StoreEntry *, const char *,...); #else extern void storeAppendPrintf(); #endif -extern void storeLog(int tag, const StoreEntry * e); extern int storeCheckCachable(StoreEntry * e); +/* + * store_log.c + */ +extern void storeLog(int tag, const StoreEntry * e); +extern void storeLogRotate(void); +extern void storeLogClose(void); +extern void storeLogOpen(void); + /* * store_key_*.c @@ -495,6 +499,9 @@ extern void storeDirUpdateSwapSize(int fn, size_t size, int sign); extern int storeDirProperFileno(int dirn, int fn); extern void storeCreateSwapDirectories(void); extern int storeVerifyCacheDirs(void); +extern int storeDirWriteCleanLogs(int reopen); +extern int storeDirValidFileno(int fn); + /* * store_swapmeta.c diff --git a/src/store.cc b/src/store.cc index 7db352ae1c..1718461f64 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.373 1998/02/03 07:35:28 wessels Exp $ + * $Id: store.cc,v 1.374 1998/02/03 22:08:14 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -110,14 +110,6 @@ #define STORE_IN_MEM_BUCKETS (229) -static char *storeLogTags[] = -{ - "CREATE", - "SWAPIN", - "SWAPOUT", - "RELEASE" -}; - const char *memStatusStr[] = { "NOT_IN_MEMORY", @@ -153,7 +145,9 @@ typedef struct lock_ctrl_t { StoreEntry *e; } lock_ctrl_t; -/* Static Functions */ +/* + * local function prototypes + */ static int storeCheckExpired(const StoreEntry *, int flag); static int storeEntryLocked(const StoreEntry *); static int storeEntryValidLength(const StoreEntry *); @@ -165,32 +159,20 @@ static void destroy_MemObjectData(MemObject *); static void destroy_StoreEntry(StoreEntry *); static void storePurgeMem(StoreEntry *); static void storeSetPrivateKey(StoreEntry *); -#if OLD_CODE -static STVLDCB storeCleanupComplete; -#endif static unsigned int getKeyCounter(void); static int storeKeepInMemory(const StoreEntry *); +/* + * local variables + */ static dlink_list inmem_list; -static dlink_list all_list; - static int store_pages_high = 0; static int store_pages_low = 0; - -/* current file name, swap file, use number as a filename */ static int store_swap_high = 0; static int store_swap_low = 0; -static int storelog_fd = -1; - -/* expiration parameters and stats */ static int store_maintain_rate; static int store_maintain_buckets; -#if OLD_CODE -/* outstanding cleanup validations */ -static int outvalid = 0; -#endif - static MemObject * new_MemObject(const char *url, const char *log_url) { @@ -273,59 +255,20 @@ storeHashInsert(StoreEntry * e, const cache_key * key) e, storeKeyText(key)); e->key = storeKeyDup(key); hash_join(store_table, (hash_link *) e); - dlinkAdd(e, &e->lru, &all_list); + dlinkAdd(e, &e->lru, &store_list); } static void storeHashDelete(StoreEntry * e) { hash_remove_link(store_table, (hash_link *) e); - dlinkDelete(&e->lru, &all_list); + dlinkDelete(&e->lru, &store_list); storeKeyFree(e->key); e->key = NULL; } /* -------------------------------------------------------------------------- */ -void -storeLog(int tag, const StoreEntry * e) -{ - LOCAL_ARRAY(char, logmsg, MAX_URL << 1); - MemObject *mem = e->mem_obj; - struct _http_reply *reply; - if (storelog_fd < 0) - return; - if (mem == NULL) - return; - if (mem->log_url == NULL) { - debug(20, 1) ("storeLog: NULL log_url for %s\n", mem->url); - storeMemObjectDump(mem); - mem->log_url = xstrdup(mem->url); - } - reply = mem->reply; - snprintf(logmsg, MAX_URL << 1, "%9d.%03d %-7s %08X %4d %9d %9d %9d %s %d/%d %s %s\n", - (int) current_time.tv_sec, - (int) current_time.tv_usec / 1000, - storeLogTags[tag], - e->swap_file_number, - reply->code, - (int) reply->date, - (int) reply->last_modified, - (int) reply->expires, - reply->content_type[0] ? reply->content_type : "unknown", - reply->content_length, - (int) (mem->inmem_hi - mem->reply->hdr_sz), - RequestMethodStr[mem->method], - mem->log_url); - file_write(storelog_fd, - -1, - xstrdup(logmsg), - strlen(logmsg), - NULL, - NULL, - xfree); -} - /* get rid of memory copy of the object */ /* Only call this if storeCheckPurgeMem(e) returns 1 */ @@ -347,8 +290,8 @@ void storeLockObject(StoreEntry * e) { if (e->lock_count++ == 0) { - dlinkDelete(&e->lru, &all_list); - dlinkAdd(e, &e->lru, &all_list); + dlinkDelete(&e->lru, &store_list); + dlinkAdd(e, &e->lru, &store_list); } debug(20, 3) ("storeLockObject: key '%s' count=%d\n", storeKeyText(e->key), (int) e->lock_count); @@ -713,7 +656,7 @@ storeMaintainSwapSpace(void *datanotused) return; } debug(20, 3) ("storeMaintainSwapSpace\n"); - for (m = all_list.tail; m; m = prev) { + for (m = store_list.tail; m; m = prev) { prev = m->prev; e = m->data; if (storeEntryLocked(e)) { @@ -889,16 +832,10 @@ storeInitHashValues(void) void storeInit(void) { - char *fname = NULL; storeInitHashValues(); store_table = hash_create(storeKeyHashCmp, store_hash_buckets, storeKeyHashHash); - if (strcmp((fname = Config.Log.store), "none") == 0) - storelog_fd = -1; - else - storelog_fd = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL); - if (storelog_fd < 0) - debug(20, 1) ("Store logging disabled\n"); + storeLogOpen(); if (storeVerifyCacheDirs() < 0) { xstrncpy(tmp_error_buf, "\tFailed to verify one of the swap directories, Check cache.log\n" @@ -907,15 +844,9 @@ storeInit(void) ERROR_BUF_SZ); fatal(tmp_error_buf); } - if (opt_convert) { - storeDirOpenSwapLogs(); - storeConvert(); - debug(0, 0) ("DONE Converting. Welcome to %s!\n", version_string); - storeDirCloseSwapLogs(); - exit(0); - } + storeDirOpenSwapLogs(); storeStartRebuildFromDisk(); - all_list.head = all_list.tail = NULL; + store_list.head = store_list.tail = NULL; inmem_list.head = inmem_list.tail = NULL; } @@ -945,212 +876,6 @@ urlcmp(const void *url1, const void *url2) return (strcmp(url1, url2)); } -/* - * storeWriteCleanLogs - * - * Writes a "clean" swap log file from in-memory metadata. - */ -#define CLEAN_BUF_SZ 16384 -int -storeWriteCleanLogs(int reopen) -{ - StoreEntry *e = NULL; - int *fd; - char *line; - int n = 0; - time_t start, stop, r; - struct stat sb; - char **cur; - char **new; - char **cln; - int dirn; - dlink_node *m; - int linelen; - char **outbufs; - int *outbuflens; - if (store_rebuilding) { - debug(20, 1) ("Not currently OK to rewrite swap log.\n"); - debug(20, 1) ("storeWriteCleanLogs: Operation aborted.\n"); - storeDirCloseSwapLogs(); - return 0; - } - debug(20, 1) ("storeWriteCleanLogs: Starting...\n"); - start = squid_curtime; - fd = xcalloc(Config.cacheSwap.n_configured, sizeof(int)); - cur = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); - new = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); - cln = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); - for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { - fd[dirn] = -1; - cur[dirn] = xstrdup(storeDirSwapLogFile(dirn, NULL)); - new[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".clean")); - cln[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".last-clean")); - unlink(new[dirn]); - unlink(cln[dirn]); - fd[dirn] = file_open(new[dirn], - O_WRONLY | O_CREAT | O_TRUNC, - NULL, - NULL, - NULL); - if (fd[dirn] < 0) { - debug(50, 0) ("storeWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); - continue; - } -#if HAVE_FCHMOD - if (stat(cur[dirn], &sb) == 0) - fchmod(fd[dirn], sb.st_mode); -#endif - } - line = xcalloc(1, CLEAN_BUF_SZ); - outbufs = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); - outbuflens = xcalloc(Config.cacheSwap.n_configured, sizeof(int)); - for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { - outbufs[dirn] = xcalloc(Config.cacheSwap.n_configured, CLEAN_BUF_SZ); - outbuflens[dirn] = 0; - } - for (m = all_list.tail; m; m = m->prev) { - e = m->data; - if (e->swap_file_number < 0) - continue; - if (e->swap_status != SWAPOUT_DONE) - continue; - if (e->object_len <= 0) - continue; - if (EBIT_TEST(e->flag, RELEASE_REQUEST)) - continue; - if (EBIT_TEST(e->flag, KEY_PRIVATE)) - continue; - dirn = storeDirNumber(e->swap_file_number); - assert(dirn < Config.cacheSwap.n_configured); - if (fd[dirn] < 0) - continue; - snprintf(line, CLEAN_BUF_SZ, "%08x %08x %08x %08x %08x %9d %6d %08x %s\n", - (int) e->swap_file_number, - (int) e->timestamp, - (int) e->lastref, - (int) e->expires, - (int) e->lastmod, - e->object_len, - e->refcount, - e->flag, - storeKeyText(e->key)); - linelen = strlen(line); - /* buffered write */ - if (linelen + outbuflens[dirn] > CLEAN_BUF_SZ - 2) { - if (write(fd[dirn], outbufs[dirn], outbuflens[dirn]) < 0) { - debug(50, 0) ("storeWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); - debug(20, 0) ("storeWriteCleanLogs: Current swap logfile not replaced.\n"); - file_close(fd[dirn]); - fd[dirn] = -1; - unlink(cln[dirn]); - continue; - } - outbuflens[dirn] = 0; - } - strcpy(outbufs[dirn] + outbuflens[dirn], line); - outbuflens[dirn] += linelen; - if ((++n & 0x3FFF) == 0) { - getCurrentTime(); - debug(20, 1) (" %7d lines written so far.\n", n); - } - } - safe_free(line); - /* flush */ - for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { - if (outbuflens[dirn] > 0) { - if (write(fd[dirn], outbufs[dirn], outbuflens[dirn]) < 0) { - debug(50, 0) ("storeWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); - debug(20, 0) ("storeWriteCleanLogs: Current swap logfile not replaced.\n"); - file_close(fd[dirn]); - fd[dirn] = -1; - unlink(cln[dirn]); - continue; - } - } - safe_free(outbufs[dirn]); - } - safe_free(outbufs); - safe_free(outbuflens); - /* close */ - for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { - file_close(fd[dirn]); - fd[dirn] = -1; - if (rename(new[dirn], cur[dirn]) < 0) { - debug(50, 0) ("storeWriteCleanLogs: rename failed: %s, %s -> %s\n", - xstrerror(), new[dirn], cur[dirn]); - } - } - storeDirCloseSwapLogs(); - if (reopen) - storeDirOpenSwapLogs(); - stop = squid_curtime; - r = stop - start; - debug(20, 1) (" Finished. Wrote %d lines.\n", n); - debug(20, 1) (" Took %d seconds (%6.1lf lines/sec).\n", - r > 0 ? r : 0, (double) n / (r > 0 ? r : 1)); - /* touch a timestamp file if we're not still validating */ - for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { - if (!store_rebuilding) - file_close(file_open(cln[dirn], - O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL)); - safe_free(cur[dirn]); - safe_free(new[dirn]); - safe_free(cln[dirn]); - } - safe_free(cur); - safe_free(new); - safe_free(cln); - safe_free(fd); - return n; -} -#undef CLEAN_BUF_SZ - -void -storeRotateLog(void) -{ - char *fname = NULL; - int i; - LOCAL_ARRAY(char, from, MAXPATHLEN); - LOCAL_ARRAY(char, to, MAXPATHLEN); -#ifdef S_ISREG - struct stat sb; -#endif - - if (storelog_fd > -1) { - file_close(storelog_fd); - storelog_fd = -1; - } - if ((fname = Config.Log.store) == NULL) - return; - if (strcmp(fname, "none") == 0) - return; -#ifdef S_ISREG - if (stat(fname, &sb) == 0) - if (S_ISREG(sb.st_mode) == 0) - return; -#endif - - debug(20, 1) ("storeRotateLog: Rotating.\n"); - - /* Rotate numbers 0 through N up one */ - for (i = Config.Log.rotateNumber; i > 1;) { - i--; - snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1); - snprintf(to, MAXPATHLEN, "%s.%d", fname, i); - rename(from, to); - } - /* Rotate the current log to .0 */ - if (Config.Log.rotateNumber > 0) { - snprintf(to, MAXPATHLEN, "%s.%d", fname, 0); - rename(fname, to); - } - storelog_fd = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL); - if (storelog_fd < 0) { - debug(50, 0) ("storeRotateLog: %s: %s\n", fname, xstrerror()); - debug(20, 1) ("Store logging disabled\n"); - } -} - static int storeKeepInMemory(const StoreEntry * e) { @@ -1204,13 +929,6 @@ storeExpiredReferenceAge(void) return age; } -void -storeCloseLog(void) -{ - if (storelog_fd >= 0) - file_close(storelog_fd); -} - void storeNegativeCache(StoreEntry * e) { @@ -1364,24 +1082,24 @@ storeMemObjectDump(MemObject * mem) } void -storeEntryDump(StoreEntry * e) +storeEntryDump(StoreEntry * e, int l) { - debug(20, 1) ("StoreEntry->key: %s\n", storeKeyText(e->key)); - debug(20, 1) ("StoreEntry->next: %p\n", e->next); - debug(20, 1) ("StoreEntry->mem_obj: %p\n", e->mem_obj); - debug(20, 1) ("StoreEntry->timestamp: %d\n", (int) e->timestamp); - debug(20, 1) ("StoreEntry->lastref: %d\n", (int) e->lastref); - debug(20, 1) ("StoreEntry->expires: %d\n", (int) e->expires); - debug(20, 1) ("StoreEntry->lastmod: %d\n", (int) e->lastmod); - debug(20, 1) ("StoreEntry->object_len: %d\n", e->object_len); - debug(20, 1) ("StoreEntry->refcount: %d\n", e->refcount); - debug(20, 1) ("StoreEntry->flag: %X\n", e->flag); - debug(20, 1) ("StoreEntry->swap_file_number: %d\n", (int) e->swap_file_number); - debug(20, 1) ("StoreEntry->lock_count: %d\n", (int) e->lock_count); - debug(20, 1) ("StoreEntry->mem_status: %d\n", (int) e->mem_status); - debug(20, 1) ("StoreEntry->ping_status: %d\n", (int) e->ping_status); - debug(20, 1) ("StoreEntry->store_status: %d\n", (int) e->store_status); - debug(20, 1) ("StoreEntry->swap_status: %d\n", (int) e->swap_status); + debug(20, l) ("StoreEntry->key: %s\n", storeKeyText(e->key)); + debug(20, l) ("StoreEntry->next: %p\n", e->next); + debug(20, l) ("StoreEntry->mem_obj: %p\n", e->mem_obj); + debug(20, l) ("StoreEntry->timestamp: %d\n", (int) e->timestamp); + debug(20, l) ("StoreEntry->lastref: %d\n", (int) e->lastref); + debug(20, l) ("StoreEntry->expires: %d\n", (int) e->expires); + debug(20, l) ("StoreEntry->lastmod: %d\n", (int) e->lastmod); + debug(20, l) ("StoreEntry->object_len: %d\n", e->object_len); + debug(20, l) ("StoreEntry->refcount: %d\n", e->refcount); + debug(20, l) ("StoreEntry->flag: %X\n", e->flag); + debug(20, l) ("StoreEntry->swap_file_number: %d\n", (int) e->swap_file_number); + debug(20, l) ("StoreEntry->lock_count: %d\n", (int) e->lock_count); + debug(20, l) ("StoreEntry->mem_status: %d\n", (int) e->mem_status); + debug(20, l) ("StoreEntry->ping_status: %d\n", (int) e->ping_status); + debug(20, l) ("StoreEntry->store_status: %d\n", (int) e->store_status); + debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status); } /* NOTE, this function assumes only two mem states */ diff --git a/src/store_client.cc b/src/store_client.cc index 9a7aac54dc..402257eda3 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -1,9 +1,15 @@ #include "squid.h" +/* + * NOTE: 'Header' refers to the swapfile metadata header. + * 'Body' refers to the swapfile body, which is the full + * HTTP reply (including HTTP headers and body). + */ +static DRCB storeClientReadBody; +static DRCB storeClientReadHeader; +static SIH storeClientFileOpened; static void storeClientCopy2(StoreEntry * e, store_client * sc); -static SIH storeClientCopyFileOpened; -static void storeClientCopyFileRead(store_client * sc); -static DRCB storeClientCopyHandleRead; +static void storeClientFileRead(store_client * sc); /* check if there is any client waiting for this object at all */ /* return 1 if there is at least one client */ @@ -151,7 +157,7 @@ storeClientCopy2(StoreEntry * e, store_client * sc) /* assert(sc->copy_offset == 0); */ if (sc->disk_op_in_progress == 0) { sc->disk_op_in_progress = 1; - storeSwapInStart(e, storeClientCopyFileOpened, sc); + storeSwapInStart(e, storeClientFileOpened, sc); } else { debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n"); } @@ -161,7 +167,7 @@ storeClientCopy2(StoreEntry * e, store_client * sc) assert(sc->type == STORE_DISK_CLIENT); if (sc->disk_op_in_progress == 0) { sc->disk_op_in_progress = 1; - storeClientCopyFileRead(sc); + storeClientFileRead(sc); } else { debug(20, 2) ("storeClientCopy2: Averted multiple fd operation\n"); } @@ -170,57 +176,118 @@ storeClientCopy2(StoreEntry * e, store_client * sc) } static void -storeClientCopyFileOpened(int fd, void *data) +storeClientFileOpened(int fd, void *data) { store_client *sc = data; STCB *callback = sc->callback; if (fd < 0) { - debug(20, 3) ("storeClientCopyFileOpened: failed\n"); + debug(20, 3) ("storeClientFileOpened: failed\n"); sc->disk_op_in_progress = 0; sc->callback = NULL; callback(sc->callback_data, sc->copy_buf, -1); return; } sc->swapin_fd = fd; - storeClientCopyFileRead(sc); + storeClientFileRead(sc); } static void -storeClientCopyFileRead(store_client * sc) +storeClientFileRead(store_client * sc) { + MemObject *mem = sc->mem; assert(sc->callback != NULL); - file_read(sc->swapin_fd, - sc->copy_buf, - sc->copy_size, - sc->copy_offset, - storeClientCopyHandleRead, - sc); + if (mem->swap_hdr_sz == 0) + file_read(sc->swapin_fd, + memAllocate(MEM_DISK_BUF, 1), + DISK_PAGE_SIZE, + 0, + storeClientReadHeader, + sc); + else + file_read(sc->swapin_fd, + sc->copy_buf, + sc->copy_size, + sc->copy_offset + mem->swap_hdr_sz, + storeClientReadBody, + sc); } static void -storeClientCopyHandleRead(int fd, const char *buf, int len, int flagnotused, void *data) +storeClientReadBody(int fd, const char *buf, int len, int flagnotused, void *data) { store_client *sc = data; - MemObject *mem = sc->mem; STCB *callback = sc->callback; - int hdr_len = 0; assert(sc->disk_op_in_progress != 0); sc->disk_op_in_progress = 0; assert(sc->callback != NULL); - debug(20, 3) ("storeClientCopyHandleRead: FD %d, len %d\n", fd, len); -#if USE_SWAP_HEADERS - /* XXX: BROKEN */ - if (sc->copy_offset == 0 && len > 0 && mem != NULL) { - hdr_len = storeGetMetaBuf(buf, mem); - memmove((char *) buf, (char *) (buf + hdr_len), len - hdr_len); - len -= hdr_len; - httpParseReplyHeaders(buf, mem->reply); - } -#endif + debug(20, 3) ("storeClientReadBody: FD %d, len %d\n", fd, len); sc->callback = NULL; callback(sc->callback_data, sc->copy_buf, len); } +static void +storeClientReadHeader(int fd, const char *buf, int len, int flagnotused, void *data) +{ + /* + * 'buf' should have been allocated by memAllocate(MEM_DISK_BUF) + */ + store_client *sc = data; + MemObject *mem = sc->mem; + STCB *callback = sc->callback; + int swap_hdr_sz = 0; + size_t body_sz; + size_t copy_sz; + tlv *tlv_list; + assert(sc->disk_op_in_progress != 0); + sc->disk_op_in_progress = 0; + assert(sc->callback != NULL); + debug(20, 3) ("storeClientReadHeader: FD %d, len %d\n", fd, len); + if (len < 0) { + debug(20, 3) ("storeClientReadHeader: FD %d: %s\n", fd, xstrerror()); + memFree(MEM_DISK_BUF, (void *) buf); + sc->callback = NULL; + callback(sc->callback_data, sc->copy_buf, len); + return; + } + tlv_list = storeSwapMetaUnpack(buf, &swap_hdr_sz); + if (tlv_list == NULL) { + debug(20, 1) ("storeClientReadHeader: failed to unpack meta data\n"); + memFree(MEM_DISK_BUF, (void *) buf); + sc->callback = NULL; + callback(sc->callback_data, sc->copy_buf, -1); + return; + } + /* + * XXX Here we should check the meta data and make sure we got + * the right object. + */ + mem->swap_hdr_sz = swap_hdr_sz; + /* + * If our last read got some data the client wants, then give + * it to them, otherwise schedule another read. + */ + body_sz = len - swap_hdr_sz; + if (sc->copy_offset < body_sz) { + /* + * we have (part of )what they want + */ + copy_sz = XMIN(sc->copy_size, body_sz); + debug(20,1)("storeClientReadHeader: copying %d bytes of body\n", + copy_sz); + xmemcpy(sc->copy_buf, buf+swap_hdr_sz, copy_sz); + memFree(MEM_DISK_BUF, (void *) buf); + sc->callback = NULL; + callback(sc->callback_data, sc->copy_buf, copy_sz); + return; + } + /* + * we don't have what the client wants, but at least we now + * know the swap header size. + */ + memFree(MEM_DISK_BUF, (void *) buf); + storeClientFileRead(sc); +} + int storeClientCopyPending(StoreEntry * e, void *data) { diff --git a/src/store_dir.cc b/src/store_dir.cc index ce56cc14e4..dc3d221c96 100644 --- a/src/store_dir.cc +++ b/src/store_dir.cc @@ -1,6 +1,6 @@ /* - * $Id: store_dir.cc,v 1.42 1998/02/02 21:15:09 wessels Exp $ + * $Id: store_dir.cc,v 1.43 1998/02/03 22:08:16 wessels Exp $ * * DEBUG: section 47 Store Directory Routines * AUTHOR: Duane Wessels @@ -97,7 +97,7 @@ storeSwapSubSubDir(int fn, char *fullpath) ((filn / Config.cacheSwap.swapDirs[dirn].l2) / Config.cacheSwap.swapDirs[dirn].l2) % Config.cacheSwap.swapDirs[dirn].l1, (filn / Config.cacheSwap.swapDirs[dirn].l2) % Config.cacheSwap.swapDirs[dirn].l2); #else - snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X/%08X", + snprintf(fullpath, SQUID_MAXPATHLEN, "%s/%02X/%02X", Config.cacheSwap.swapDirs[dirn].path, filn % Config.cacheSwap.swapDirs[dirn].l1, filn / Config.cacheSwap.swapDirs[dirn].l1 % Config.cacheSwap.swapDirs[dirn].l2); @@ -213,6 +213,20 @@ storeMostFreeSwapDir(void) return dirn; } +int +storeDirValidFileno(int fn) +{ + int dirn = fn >> SWAP_DIR_SHIFT; + int filn = fn & SWAP_FILE_MASK; + SwapDir *SD; + if (dirn > Config.cacheSwap.n_configured) + return 0; + SD = &Config.cacheSwap.swapDirs[dirn]; + if (filn > SD->map->max_n_files) + return 0; + return 1; +} + int storeDirMapBitTest(int fn) { @@ -468,3 +482,163 @@ storeDirStats(StoreEntry * sentry) 100.0 * SD->cur_size / SD->max_size); } } + +/* + * storeDirWriteCleanLogs + * + * Writes a "clean" swap log file from in-memory metadata. + */ +#define CLEAN_BUF_SZ 16384 +int +storeDirWriteCleanLogs(int reopen) +{ + StoreEntry *e = NULL; + int *fd; + char *line; + int n = 0; + time_t start, stop, r; + struct stat sb; + char **cur; + char **new; + char **cln; + int dirn; + dlink_node *m; + int linelen; + char **outbufs; + int *outbuflens; + if (store_rebuilding) { + debug(20, 1) ("Not currently OK to rewrite swap log.\n"); + debug(20, 1) ("storeDirWriteCleanLogs: Operation aborted.\n"); + storeDirCloseSwapLogs(); + return 0; + } + debug(20, 1) ("storeDirWriteCleanLogs: Starting...\n"); + start = squid_curtime; + fd = xcalloc(Config.cacheSwap.n_configured, sizeof(int)); + cur = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); + new = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); + cln = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); + for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { + fd[dirn] = -1; + cur[dirn] = xstrdup(storeDirSwapLogFile(dirn, NULL)); + new[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".clean")); + cln[dirn] = xstrdup(storeDirSwapLogFile(dirn, ".last-clean")); + unlink(new[dirn]); + unlink(cln[dirn]); + fd[dirn] = file_open(new[dirn], + O_WRONLY | O_CREAT | O_TRUNC, + NULL, + NULL, + NULL); + if (fd[dirn] < 0) { + debug(50, 0) ("storeDirWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); + continue; + } +#if HAVE_FCHMOD + if (stat(cur[dirn], &sb) == 0) + fchmod(fd[dirn], sb.st_mode); +#endif + } + line = xcalloc(1, CLEAN_BUF_SZ); + outbufs = xcalloc(Config.cacheSwap.n_configured, sizeof(char *)); + outbuflens = xcalloc(Config.cacheSwap.n_configured, sizeof(int)); + for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { + outbufs[dirn] = xcalloc(Config.cacheSwap.n_configured, CLEAN_BUF_SZ); + outbuflens[dirn] = 0; + } + for (m = store_list.tail; m; m = m->prev) { + e = m->data; + if (e->swap_file_number < 0) + continue; + if (e->swap_status != SWAPOUT_DONE) + continue; + if (e->object_len <= 0) + continue; + if (EBIT_TEST(e->flag, RELEASE_REQUEST)) + continue; + if (EBIT_TEST(e->flag, KEY_PRIVATE)) + continue; + dirn = storeDirNumber(e->swap_file_number); + assert(dirn < Config.cacheSwap.n_configured); + if (fd[dirn] < 0) + continue; + snprintf(line, CLEAN_BUF_SZ, "%08x %08x %08x %08x %08x %9d %6d %08x %s\n", + (int) e->swap_file_number, + (int) e->timestamp, + (int) e->lastref, + (int) e->expires, + (int) e->lastmod, + e->object_len, + e->refcount, + e->flag, + storeKeyText(e->key)); + linelen = strlen(line); + /* buffered write */ + if (linelen + outbuflens[dirn] > CLEAN_BUF_SZ - 2) { + if (write(fd[dirn], outbufs[dirn], outbuflens[dirn]) < 0) { + debug(50, 0) ("storeDirWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); + debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n"); + file_close(fd[dirn]); + fd[dirn] = -1; + unlink(cln[dirn]); + continue; + } + outbuflens[dirn] = 0; + } + strcpy(outbufs[dirn] + outbuflens[dirn], line); + outbuflens[dirn] += linelen; + if ((++n & 0x3FFF) == 0) { + getCurrentTime(); + debug(20, 1) (" %7d lines written so far.\n", n); + } + } + safe_free(line); + /* flush */ + for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { + if (outbuflens[dirn] > 0) { + if (write(fd[dirn], outbufs[dirn], outbuflens[dirn]) < 0) { + debug(50, 0) ("storeDirWriteCleanLogs: %s: %s\n", new[dirn], xstrerror()); + debug(20, 0) ("storeDirWriteCleanLogs: Current swap logfile not replaced.\n"); + file_close(fd[dirn]); + fd[dirn] = -1; + unlink(cln[dirn]); + continue; + } + } + safe_free(outbufs[dirn]); + } + safe_free(outbufs); + safe_free(outbuflens); + /* close */ + for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { + file_close(fd[dirn]); + fd[dirn] = -1; + if (rename(new[dirn], cur[dirn]) < 0) { + debug(50, 0) ("storeDirWriteCleanLogs: rename failed: %s, %s -> %s\n", + xstrerror(), new[dirn], cur[dirn]); + } + } + storeDirCloseSwapLogs(); + if (reopen) + storeDirOpenSwapLogs(); + stop = squid_curtime; + r = stop - start; + debug(20, 1) (" Finished. Wrote %d lines.\n", n); + debug(20, 1) (" Took %d seconds (%6.1lf lines/sec).\n", + r > 0 ? r : 0, (double) n / (r > 0 ? r : 1)); + /* touch a timestamp file if we're not still validating */ + for (dirn = 0; dirn < Config.cacheSwap.n_configured; dirn++) { + if (!store_rebuilding) + file_close(file_open(cln[dirn], + O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL)); + safe_free(cur[dirn]); + safe_free(new[dirn]); + safe_free(cln[dirn]); + } + safe_free(cur); + safe_free(new); + safe_free(cln); + safe_free(fd); + return n; +} +#undef CLEAN_BUF_SZ diff --git a/src/store_log.cc b/src/store_log.cc new file mode 100644 index 0000000000..a7756a9b0b --- /dev/null +++ b/src/store_log.cc @@ -0,0 +1,118 @@ +#include "squid.h" + +static char *storeLogTags[] = +{ + "CREATE", + "SWAPIN", + "SWAPOUT", + "RELEASE" +}; + +static int storelog_fd = -1; + +void +storeLog(int tag, const StoreEntry * e) +{ + LOCAL_ARRAY(char, logmsg, MAX_URL << 1); + MemObject *mem = e->mem_obj; + struct _http_reply *reply; + if (storelog_fd < 0) + return; + if (mem == NULL) + return; + if (mem->log_url == NULL) { + debug(20, 1) ("storeLog: NULL log_url for %s\n", mem->url); + storeMemObjectDump(mem); + mem->log_url = xstrdup(mem->url); + } + reply = mem->reply; + snprintf(logmsg, MAX_URL << 1, "%9d.%03d %-7s %08X %4d %9d %9d %9d %s %d/%d %s %s\n", + (int) current_time.tv_sec, + (int) current_time.tv_usec / 1000, + storeLogTags[tag], + e->swap_file_number, + reply->code, + (int) reply->date, + (int) reply->last_modified, + (int) reply->expires, + reply->content_type[0] ? reply->content_type : "unknown", + reply->content_length, + (int) (mem->inmem_hi - mem->reply->hdr_sz), + RequestMethodStr[mem->method], + mem->log_url); + file_write(storelog_fd, + -1, + xstrdup(logmsg), + strlen(logmsg), + NULL, + NULL, + xfree); +} + +void +storeLogRotate(void) +{ + char *fname = NULL; + int i; + LOCAL_ARRAY(char, from, MAXPATHLEN); + LOCAL_ARRAY(char, to, MAXPATHLEN); +#ifdef S_ISREG + struct stat sb; +#endif + + if (storelog_fd > -1) { + file_close(storelog_fd); + storelog_fd = -1; + } + if ((fname = Config.Log.store) == NULL) + return; + if (strcmp(fname, "none") == 0) + return; +#ifdef S_ISREG + if (stat(fname, &sb) == 0) + if (S_ISREG(sb.st_mode) == 0) + return; +#endif + + debug(20, 1) ("storeLogRotate: Rotating.\n"); + + /* Rotate numbers 0 through N up one */ + for (i = Config.Log.rotateNumber; i > 1;) { + i--; + snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", fname, i); + rename(from, to); + } + /* Rotate the current log to .0 */ + if (Config.Log.rotateNumber > 0) { + snprintf(to, MAXPATHLEN, "%s.%d", fname, 0); + rename(fname, to); + } + storelog_fd = file_open(fname, O_WRONLY | O_CREAT, NULL, NULL, NULL); + if (storelog_fd < 0) { + debug(50, 0) ("storeLogRotate: %s: %s\n", fname, xstrerror()); + debug(20, 1) ("Store logging disabled\n"); + } +} + +void +storeLogClose(void) +{ + if (storelog_fd >= 0) + file_close(storelog_fd); +} + +void +storeLogOpen(void) +{ + if (strcmp(Config.Log.store, "none") == 0) + storelog_fd = -1; + else + storelog_fd = file_open(Config.Log.store, + O_WRONLY | O_CREAT, + NULL, + NULL, + NULL); + if (storelog_fd < 0) + debug(20, 1) ("Store logging disabled\n"); +} diff --git a/src/store_rebuild.cc b/src/store_rebuild.cc index ef790eeb02..7256daba91 100644 --- a/src/store_rebuild.cc +++ b/src/store_rebuild.cc @@ -61,10 +61,10 @@ storeRebuildRawFile(void *data) debug(20, 1) ("storeRebuildRawFile: done!\n"); store_rebuilding = 0; return; - } else if (fd == 0) { + } else if (fd < 0) { continue; } - assert(fd > 0); + assert(fd > -1); /* lets get file stats here */ if (fstat(fd, &fst) < 0) { debug(20, 1) ("storeRebuildRawFile: fstat(FD %d): %s\n", @@ -92,6 +92,7 @@ storeRebuildRawFile(void *data) safeunlink(storeSwapFullPath(sfileno, NULL), 1); continue; } + debug(20,1)("storeRebuildRawFile: successful swap meta unpacking\n"); storeKeyFree(tmpe.key); memset(&tmpe, '\0', sizeof(StoreEntry)); for (t = tlv_list; t; t = t->next) { @@ -136,9 +137,8 @@ storeRebuildRawFile(void *data) storeRelease(e); /* release old entry */ RB->dupcount++; } - /* update store_swap_size */ RB->objcount++; - storeEntryDump(&tmpe); + storeEntryDump(&tmpe, 5); e = storeAddDiskRestore(tmpe.key, sfileno, (int) tmpe.object_len, @@ -235,15 +235,16 @@ storeGetNextFile(int *sfileno, int *size) static int dirn, curlvl1, curlvl2, flag, done, in_dir, fn; static struct dirent *entry; static DIR *td; - int fd = 0, used = 0; + int fd = -1; + int used = 0; LOCAL_ARRAY(char, fullfilename, SQUID_MAXPATHLEN); LOCAL_ARRAY(char, fullpath, SQUID_MAXPATHLEN); debug(20, 3) ("storeGetNextFile: flag=%d, %d: /%02X/%02X\n", flag, dirn, curlvl1, curlvl2); if (done) return -2; - while (!fd && !done) { - fd = 0; + while (fd < 0 && done == 0) { + fd = -1; if (!flag) { /* initialize, open first file */ done = dirn = curlvl1 = curlvl2 = in_dir = 0; flag = 1; diff --git a/src/store_swapin.cc b/src/store_swapin.cc index 649cf2ae4c..dbaa47fa44 100644 --- a/src/store_swapin.cc +++ b/src/store_swapin.cc @@ -58,7 +58,11 @@ storeSwapInValidateComplete(void *data, int retcode, int errcode) } ctrlp->path = xstrdup(storeSwapFullPath(e->swap_file_number, NULL)); debug(20, 3) ("storeSwapInValidateComplete: Opening %s\n", ctrlp->path); - file_open(ctrlp->path, O_RDONLY, storeSwapInFileOpened, ctrlp, ctrlp->callback_data); + file_open(ctrlp->path, + O_RDONLY, + storeSwapInFileOpened, + ctrlp, + ctrlp->callback_data); } void @@ -67,7 +71,6 @@ storeSwapInFileOpened(void *data, int fd, int errcode) swapin_ctrl_t *ctrlp = (swapin_ctrl_t *) data; StoreEntry *e = ctrlp->e; MemObject *mem = e->mem_obj; - struct stat sb; if (fd == -2 && errcode == -2) { xfree(ctrlp->path); xfree(ctrlp); @@ -76,23 +79,31 @@ storeSwapInFileOpened(void *data, int fd, int errcode) assert(mem != NULL); assert(e->mem_status == NOT_IN_MEMORY); assert(e->swap_status == SWAPOUT_WRITING || e->swap_status == SWAPOUT_DONE); - if (e->swap_status == SWAPOUT_DONE && (fd >= 0) && fstat(fd, &sb) == 0) - if (sb.st_size == 0 || sb.st_size != e->object_len) { - debug(20, 0) ("storeSwapInFileOpened: %s: Size mismatch: %d(fstat) != %d(object)\n", ctrlp->path, sb.st_size, e->object_len); - file_close(fd); - fd = -1; - } if (fd < 0) { - debug(20, 0) ("storeSwapInStartComplete: Failed for '%s' (%s)\n", mem->url, - ctrlp->path); + debug(20, 0) ("storeSwapInFileOpened: Failed '%s' for '%s'\n", + ctrlp->path, storeUrl(e)); /* Invoke a store abort that should free the memory object */ (ctrlp->callback) (-1, ctrlp->callback_data); xfree(ctrlp->path); xfree(ctrlp); return; } - debug(20, 5) ("storeSwapInStart: initialized swap file '%s' for '%s'\n", - ctrlp->path, mem->url); + /* + * We can't use fstat() to check file size here because of the + * metadata header. We have to parse the header first and find + * the header size. + */ +#if OLD_CODE + if (e->swap_status == SWAPOUT_DONE && fstat(fd, &sb) == 0) { + if (sb.st_size == 0 || sb.st_size != e->object_len) { + debug(20, 0) ("storeSwapInFileOpened: %s: Size mismatch: %d(fstat) != %d(object)\n", ctrlp->path, sb.st_size, e->object_len); + file_close(fd); + fd = -1; + } + } +#endif + debug(20, 5) ("storeSwapInFileOpened: initialized '%s' for '%s'\n", + ctrlp->path, storeUrl(e)); (ctrlp->callback) (fd, ctrlp->callback_data); xfree(ctrlp->path); xfree(ctrlp); diff --git a/src/store_swapmeta.cc b/src/store_swapmeta.cc index 269fc3aaa6..b9ae995256 100644 --- a/src/store_swapmeta.cc +++ b/src/store_swapmeta.cc @@ -39,15 +39,14 @@ storeSwapMetaBuild(StoreEntry * e) debug(20, 3) ("storeSwapMetaBuild: %s\n", url); T = storeSwapTLVAdd(STORE_META_KEY, e->key, cacheKeySize, T); T = storeSwapTLVAdd(STORE_META_STD, &e->timestamp, STORE_HDR_METASIZE, T); - T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url), T); + T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url)+1, T); return TLV; } char * storeSwapMetaPack(tlv * tlv_list, int *length) { - size_t buflen = 0; - int i; + int buflen = 0; tlv *t; off_t j = 0; char *buf; @@ -55,12 +54,12 @@ storeSwapMetaPack(tlv * tlv_list, int *length) buflen++; /* STORE_META_OK */ buflen += sizeof(int); /* size of header to follow */ for (t = tlv_list; t; t = t->next) - buflen += t->length + sizeof(char) + sizeof(int); + buflen += sizeof(char) + sizeof(int) + t->length; buflen++; /* STORE_META_END */ buf = xmalloc(buflen); buf[j++] = (char) STORE_META_OK; - i = (int) buflen - (sizeof(char) + sizeof(int)); - xmemcpy(&buf[j], &i, sizeof(int)); + xmemcpy(&buf[j], &buflen, sizeof(int)); + j += sizeof(int); for (t = tlv_list; t; t = t->next) { buf[j++] = (char) t->type; xmemcpy(&buf[j], &t->length, sizeof(int)); @@ -69,8 +68,8 @@ storeSwapMetaPack(tlv * tlv_list, int *length) j += t->length; } buf[j++] = (char) STORE_META_END; - assert(j == buflen); - *length = (int) buflen; + assert((int) j == buflen); + *length = buflen; return buf; } @@ -83,14 +82,13 @@ storeSwapMetaUnpack(const char *buf, int *hdr_len) int length; int buflen; off_t j = 0; - assert(buflen > (sizeof(char) + sizeof(int))); assert(buf != NULL); assert(hdr_len != NULL); if (buf[j++] != (char) STORE_META_OK) return NULL; xmemcpy(&buflen, &buf[j], sizeof(int)); j += sizeof(int); - assert(buflen > 0); + assert(buflen > (sizeof(char) + sizeof(int))); while (buflen - j > (sizeof(char) + sizeof(int))) { type = buf[j++]; xmemcpy(&length, &buf[j], sizeof(int)); @@ -104,6 +102,6 @@ storeSwapMetaUnpack(const char *buf, int *hdr_len) T = storeSwapTLVAdd(type, &buf[j], (size_t) length, T); j += length; } - *hdr_len = buflen + sizeof(char) + sizeof(int); + *hdr_len = buflen; return TLV; } diff --git a/src/store_swapout.cc b/src/store_swapout.cc index f4a9b5f565..a34419c619 100644 --- a/src/store_swapout.cc +++ b/src/store_swapout.cc @@ -6,7 +6,7 @@ typedef struct swapout_ctrl_t { StoreEntry *e; } swapout_ctrl_t; -static void storeSwapoutFileOpened(void *data, int fd, int errcode); +static FOCB storeSwapOutFileOpened; /* start swapping object to disk */ void @@ -27,7 +27,7 @@ storeSwapOutStart(StoreEntry * e) e->swap_status = SWAPOUT_OPENING; file_open(swapfilename, O_WRONLY | O_CREAT | O_TRUNC, - storeSwapoutFileOpened, + storeSwapOutFileOpened, ctrlp, e); } @@ -70,17 +70,18 @@ storeSwapOutHandle(int fdnotused, int flag, size_t len, void *data) #else assert(mem != NULL); #endif + assert(mem->swap_hdr_sz != 0); mem->swapout.done_offset += len; if (e->store_status == STORE_PENDING) { storeCheckSwapOut(e); return; - } else if (mem->swapout.done_offset < e->object_len + mem->swapout.hdr_len) { + } else if (mem->swapout.done_offset < e->object_len + mem->swap_hdr_sz) { storeCheckSwapOut(e); return; } /* swapping complete */ debug(20, 5) ("storeSwapOutHandle: SwapOut complete: '%s' to %s.\n", - mem->url, storeSwapFullPath(e->swap_file_number, NULL)); + storeUrl(e), storeSwapFullPath(e->swap_file_number, NULL)); e->swap_status = SWAPOUT_DONE; storeDirUpdateSwapSize(e->swap_file_number, e->object_len, 1); if (storeCheckCachable(e)) { @@ -101,11 +102,10 @@ storeCheckSwapOut(StoreEntry * e) size_t swapout_size; char *swap_buf; ssize_t swap_buf_len; - int x; int hdr_len = 0; assert(mem != NULL); /* should we swap something out to disk? */ - debug(20, 3) ("storeCheckSwapOut: %s\n", mem->url); + debug(20, 3) ("storeCheckSwapOut: %s\n", storeUrl(e)); debug(20, 3) ("storeCheckSwapOut: store_status = %s\n", storeStatusStr[e->store_status]); if (e->store_status == STORE_ABORTED) { @@ -169,29 +169,13 @@ storeCheckSwapOut(StoreEntry * e) if (e->swap_status == SWAPOUT_OPENING) return; assert(mem->swapout.fd > -1); - swap_buf = memAllocate(MEM_DISK_BUF, 1); - -#if USE_SWAP_HEADER - /* XXX: BROKEN */ - if (mem->swapout.queue_offset == 0) { - tlv = storeSwapMetaBuild(e); - hdr_buf = storeSwapMetaPack(tlv, &hdr_len); - } - if (swapout_size > STORE_SWAP_BUF - hdr_len) - swapout_size = STORE_SWAP_BUF - hdr_len; - swap_buf_len = stmemCopy(mem->data, - mem->swapout.queue_offset, - swap_buf + hdr_len, - swapout_size) + hdr_len; -#else if (swapout_size > STORE_SWAP_BUF) swapout_size = STORE_SWAP_BUF; + swap_buf = memAllocate(MEM_DISK_BUF, 1); swap_buf_len = stmemCopy(mem->data, mem->swapout.queue_offset, swap_buf, swapout_size); -#endif - if (swap_buf_len < 0) { debug(20, 1) ("stmemCopy returned %d for '%s'\n", swap_buf_len, storeKeyText(e->key)); /* XXX This is probably wrong--we should storeRelease()? */ @@ -208,14 +192,13 @@ storeCheckSwapOut(StoreEntry * e) debug(20, 3) ("storeCheckSwapOut: swapping out %d bytes from %d\n", swap_buf_len, mem->swapout.queue_offset); mem->swapout.queue_offset += swap_buf_len - hdr_len; - x = file_write(mem->swapout.fd, + file_write(mem->swapout.fd, -1, swap_buf, swap_buf_len, storeSwapOutHandle, e, memFreeDISK); - assert(x == DISK_OK); } void @@ -233,13 +216,16 @@ storeSwapOutFileClose(StoreEntry * e) } static void -storeSwapoutFileOpened(void *data, int fd, int errcode) +storeSwapOutFileOpened(void *data, int fd, int errcode) { swapout_ctrl_t *ctrlp = data; int oldswapstatus = ctrlp->oldswapstatus; char *swapfilename = ctrlp->swapfilename; StoreEntry *e = ctrlp->e; MemObject *mem; + int swap_hdr_sz = 0; + tlv *tlv_list; + char *buf; xfree(ctrlp); if (fd == -2 && errcode == -2) { /* Cancelled - Clean up */ xfree(swapfilename); @@ -247,7 +233,7 @@ storeSwapoutFileOpened(void *data, int fd, int errcode) } assert(e->swap_status == SWAPOUT_OPENING); if (fd < 0) { - debug(20, 0) ("storeSwapoutFileOpened: Unable to open swapfile: %s\n", + debug(20, 0) ("storeSwapOutFileOpened: Unable to open swapfile: %s\n", swapfilename); storeDirMapBitReset(e->swap_file_number); e->swap_file_number = -1; @@ -258,9 +244,19 @@ storeSwapoutFileOpened(void *data, int fd, int errcode) mem = e->mem_obj; mem->swapout.fd = (short) fd; e->swap_status = SWAPOUT_WRITING; - debug(20, 5) ("storeSwapoutFileOpened: Begin SwapOut '%s' to FD %d FILE %s.\n", - mem->url, fd, swapfilename); + debug(20, 5) ("storeSwapOutFileOpened: Begin SwapOut '%s' to FD %d '%s'\n", + storeUrl(e), fd, swapfilename); xfree(swapfilename); debug(20, 5) ("swap_file_number=%08X\n", e->swap_file_number); - storeCheckSwapOut(e); + tlv_list = storeSwapMetaBuild(e); + buf = storeSwapMetaPack(tlv_list, &swap_hdr_sz); + storeSwapTLVFree(tlv_list); + mem->swap_hdr_sz = (size_t) swap_hdr_sz; + file_write(mem->swapout.fd, + -1, + buf, + mem->swap_hdr_sz, + storeSwapOutHandle, + e, + xfree); } diff --git a/src/structs.h b/src/structs.h index 20686c8155..28452cba0d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -801,10 +801,9 @@ struct _MemObject { struct _store_client *clients; int nclients; struct { - off_t queue_offset; - off_t done_offset; + off_t queue_offset; /* relative to in-mem data */ + off_t done_offset; /* relative to swap file with meta headers! */ int fd; - size_t hdr_len; /* size of the swapfile header */ } swapout; struct _http_reply *reply; request_t *request; @@ -819,6 +818,7 @@ struct _MemObject { char *log_url; dlink_node lru; u_num32 reqnum; + size_t swap_hdr_sz; }; struct _StoreEntry { diff --git a/src/tools.cc b/src/tools.cc index 8865ed6443..c2ee43e6d7 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.144 1998/02/02 21:16:36 wessels Exp $ + * $Id: tools.cc,v 1.145 1998/02/03 22:08:20 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -316,7 +316,7 @@ death(int sig) signal(sig, SIG_DFL); #endif releaseServerSockets(); - storeWriteCleanLogs(0); + storeDirWriteCleanLogs(0); PrintRusage(); dumpMallocStats(); if (squid_curtime - SQUID_RELEASE_TIME < 864000) { @@ -387,10 +387,10 @@ normal_shutdown(void) #if !USE_ASYNC_IO unlinkdClose(); #endif - storeWriteCleanLogs(0); + storeDirWriteCleanLogs(0); PrintRusage(); dumpMallocStats(); - storeCloseLog(); + storeLogClose(); accessLogClose(); #if PURIFY configFreeMemory(); @@ -440,7 +440,7 @@ fatal(const char *message) * used in early initialization phases, long before we ever * get to the store log. */ if (!store_rebuilding) - storeWriteCleanLogs(0); + storeDirWriteCleanLogs(0); fatal_common(message); exit(1); } @@ -453,7 +453,7 @@ fatal_dump(const char *message) if (message) fatal_common(message); if (opt_catch_signals) - storeWriteCleanLogs(0); + storeDirWriteCleanLogs(0); abort(); }