UFSSwapLogParser.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "Debug.h"
11 #include "md5.h"
12 #include "StoreSwapLogData.h"
13 #include "swap_log_op.h"
14 #include "UFSSwapLogParser.h"
15 
16 #if HAVE_SYS_STAT_H
17 #include <sys/stat.h>
18 #endif
19 
24 {
25 public:
29  char op;
31  time_t timestamp;
32  time_t lastref;
33  time_t expires;
34  time_t lastmod;
35  uint32_t swap_file_sz;
36  uint16_t refcount;
37  uint16_t flags;
38  unsigned char key[SQUID_MD5_DIGEST_LENGTH];
39  };
42  }
44  bool ReadRecord(StoreSwapLogData &swapData) {
47 
48  assert(log);
49 
50  if (fread(&readData, bytes, 1, log) != 1) {
51  return false;
52  }
53  swapData.op = readData.op;
54  swapData.swap_filen = readData.swap_filen;
55  swapData.timestamp = readData.timestamp;
56  swapData.lastref = readData.lastref;
57  swapData.expires = readData.expires;
58  swapData.lastmod = readData.lastmod;
59  swapData.swap_file_sz = readData.swap_file_sz;
60  swapData.refcount = readData.refcount;
61  swapData.flags = readData.flags;
62  memcpy(swapData.key, readData.key, SQUID_MD5_DIGEST_LENGTH);
63  return true;
64  }
65 };
66 
69 {
70 public:
71  UFSSwapLogParser_v2(FILE *fp): Fs::Ufs::UFSSwapLogParser(fp) {
72  record_size = sizeof(StoreSwapLogData);
73  }
74  bool ReadRecord(StoreSwapLogData &swapData) {
75  assert(log);
76  return fread(&swapData, sizeof(StoreSwapLogData), 1, log) == 1;
77  }
78 };
79 
82 {
83  StoreSwapLogHeader header;
84 
85  assert(fp);
86 
87  if (fread(&header, sizeof(StoreSwapLogHeader), 1, fp) != 1)
88  return NULL;
89 
90  if (header.op != SWAP_LOG_VERSION) {
91  debugs(47, DBG_IMPORTANT, "Old swap file detected...");
92  fseek(fp, 0, SEEK_SET);
93  return new UFSSwapLogParser_v1_32bs(fp); // Um. 32-bits except time_t, and can't determine that.
94  }
95 
96  debugs(47, 2, "Swap file version: " << header.version);
97 
98  if (header.version == 1) {
99  if (fseek(fp, header.record_size, SEEK_SET) != 0)
100  return NULL;
101 
102  debugs(47, DBG_IMPORTANT, "Rejecting swap file v1 to avoid cache " <<
103  "index corruption. Forcing a full cache index rebuild. " <<
104  "See Squid bug #3441.");
105  return NULL;
106 
107 #if UNUSED_CODE
108  // baseline
109  // 32-bit sfileno
110  // native time_t (hopefully 64-bit)
111  // 64-bit file size
112  if (header.record_size == sizeof(StoreSwapLogData)) {
113  debugs(47, DBG_IMPORTANT, "Version 1 of swap file with LFS support detected... ");
114  return new UFSSwapLogParser_v1(fp);
115  }
116 
117  // which means we have a 3-way grid of permutations to import (yuck!)
118  // 1) sfileno 32-bit / 64-bit (64-bit was broken)
119  // 2) time_t 32-bit / 64-bit
120  // 3) size_t 32-bit / 64-bit (32-bit was pre-LFS)
121 
122  // 32-bit systems...
123  // only LFS (size_t) differs from baseline
124  if (header.record_size == sizeof(struct UFSSwapLogParser_v1_32bs::StoreSwapLogDataOld)) {
125  debugs(47, DBG_IMPORTANT, "Version 1 (32-bit) swap file without LFS support detected... ");
126  return new UFSSwapLogParser_v1_32bs(fp);
127  }
128  // LFS (size_t) and timestamps (time_t) differs from baseline
129  if (header.record_size == sizeof(struct UFSSwapLogParser_v1_32bst::StoreSwapLogDataOld)) {
130  debugs(47, DBG_IMPORTANT, "Version 1 (32-bit) swap file with short timestamps and without LFS support detected... ");
131  return new UFSSwapLogParser_v1_32bst(fp);
132  }
133  // No downgrade for 64-bit timestamps to 32-bit.
134 
135  // 64-bit systems
136  // sfileno was 64-bit for a some builds
137  if (header.record_size == sizeof(struct UFSSwapLogParser_v1_64bfn::StoreSwapLogDataOld)) {
138  debugs(47, DBG_IMPORTANT, "Version 1 (64-bit) swap file with broken sfileno detected... ");
139  return new UFSSwapLogParser_v1_64bfn(fp);
140  }
141  // NP: 64-bit system with 32-bit size_t/time_t are not handled.
142 
143  debugs(47, DBG_IMPORTANT, "WARNING: The swap file has wrong format!... ");
144  debugs(47, DBG_IMPORTANT, "NOTE: Cannot safely downgrade caches to short (32-bit) timestamps.");
145  return NULL;
146 #endif
147  }
148 
149  if (header.version >= 2) {
150  if (!header.sane()) {
151  debugs(47, DBG_IMPORTANT, "ERROR: Corrupted v" << header.version <<
152  " swap file header.");
153  return NULL;
154  }
155 
156  if (fseek(fp, header.record_size, SEEK_SET) != 0)
157  return NULL;
158 
159  if (header.version == 2)
160  return new UFSSwapLogParser_v2(fp);
161  }
162 
163  // TODO: v3: write to disk in network-order bytes for the larger fields?
164 
165  debugs(47, DBG_IMPORTANT, "Unknown swap file version: " << header.version);
166  return NULL;
167 }
168 
169 int
171 {
172  struct stat sb;
173 
174  if (log_entries >= 0)
175  return log_entries;
176 
177  if (log && record_size && 0 == fstat(fileno(log), &sb)) {
178  log_entries = sb.st_size/record_size;
179  return log_entries;
180  }
181 
182  return 0;
183 }
184 
unsigned char key[SQUID_MD5_DIGEST_LENGTH]
#define assert(EX)
Definition: assert.h:17
void log(char *format,...)
bool ReadRecord(StoreSwapLogData &swapData)
static UFSSwapLogParser * GetUFSSwapLogParser(FILE *fp)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:123
unsigned char key[SQUID_MD5_DIGEST_LENGTH]
#define DBG_IMPORTANT
Definition: Debug.h:45
#define SQUID_MD5_DIGEST_LENGTH
Definition: md5.h:66
FILE * fp
Definition: membanger.c:35
SwappedTime timestamp
signed_int32_t sfileno
Definition: forward.h:22
bool sane() const
consistency self-check: whether the data appears to make sense
swap.state v2 log parser
bool ReadRecord(StoreSwapLogData &swapData)
Convert the on-disk 32-bit format to our current format while reading.
#define NULL
Definition: types.h:166

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors