]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/cache_cf.cc
Merge form trunk
[thirdparty/squid.git] / src / cache_cf.cc
index c2261fb9622d154798faf94c74fdef0f213ebbbf..5d5d8210097572df2de3eb9ed974b33d62b3759e 100644 (file)
@@ -48,8 +48,8 @@
 #endif
 #include "auth/Config.h"
 #include "auth/Scheme.h"
-#include "CacheManager.h"
 #include "ConfigParser.h"
+#include "CpuAffinityMap.h"
 #include "eui/Config.h"
 #if USE_SQUID_ESI
 #include "esi/Parser.h"
@@ -61,6 +61,7 @@
 #include "ip/tools.h"
 #include "log/Config.h"
 #include "MemBuf.h"
+#include "mgr/Registration.h"
 #include "Parsing.h"
 #include "ProtoPort.h"
 #include "rfc1738.h"
 #include <glob.h>
 #endif
 
+#if HAVE_LIMITS_H
+#include <limits>
+#endif
+
 #if USE_ADAPTATION
 static void parse_adaptation_service_set_type();
 static void parse_adaptation_service_chain_type();
@@ -139,7 +144,11 @@ static void parse_string(char **);
 static void default_all(void);
 static void defaults_if_none(void);
 static int parse_line(char *);
+static void parse_obsolete(const char *);
 static void parseBytesLine(size_t * bptr, const char *units);
+#if !USE_DNSSERVERS
+static void parseBytesLineSigned(ssize_t * bptr, const char *units);
+#endif
 static size_t parseBytesUnits(const char *unit);
 static void free_all(void);
 void requirePathnameExists(const char *name, const char *path);
@@ -181,6 +190,12 @@ static int check_null_https_port_list(const https_port_list *);
 static void parse_b_size_t(size_t * var);
 static void parse_b_int64_t(int64_t * var);
 
+static bool parseNamedIntList(const char *data, const String &name, Vector<int> &list);
+
+static void parse_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap);
+static void dump_CpuAffinityMap(StoreEntry *const entry, const char *const name, const CpuAffinityMap *const cpuAffinityMap);
+static void free_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap);
+
 static int parseOneConfigFile(const char *file_name, unsigned int depth);
 
 /*
@@ -521,7 +536,6 @@ int
 parseConfigFile(const char *file_name)
 {
     int err_count = 0;
-    CacheManager *manager=CacheManager::GetInstance();
 
     debugs(5, 4, HERE);
 
@@ -549,10 +563,10 @@ parseConfigFile(const char *file_name)
     }
 
     if (opt_send_signal == -1) {
-        manager->registerAction("config",
-                                "Current Squid Configuration",
-                                dump_config,
-                                1, 1);
+        Mgr::RegisterAction("config",
+                            "Current Squid Configuration",
+                            dump_config,
+                            1, 1);
     }
 
     return err_count;
@@ -651,12 +665,9 @@ configDoConfigure(void)
     else
         Config.appendDomainLen = 0;
 
-    if (Config.retry.maxtries > 10)
-        fatal("maximum_single_addr_tries cannot be larger than 10");
-
-    if (Config.retry.maxtries < 1) {
-        debugs(3, 0, "WARNING: resetting 'maximum_single_addr_tries to 1");
-        Config.retry.maxtries = 1;
+    if (Config.connect_retries > 10) {
+        debugs(0,DBG_CRITICAL, "WARNING: connect_retries cannot be larger than 10. Resetting to 10.");
+        Config.connect_retries = 10;
     }
 
     requirePathnameExists("MIME Config Table", Config.mimeTablePathname);
@@ -879,6 +890,24 @@ configDoConfigure(void)
 #endif
 }
 
+/** Parse a line containing an obsolete directive.
+ * To upgrade it where possible instead of just "Bungled config" for
+ * directives which cannot be marked as simply aliases of the some name.
+ * For example if the parameter order and content has changed.
+ * Or if the directive has been completely removed.
+ */
+void
+parse_obsolete(const char *name)
+{
+    // Directives which have been radically changed rather than removed
+    if (!strcmp(name, "url_rewrite_concurrency")) {
+        int cval;
+        parse_int(&cval);
+        debugs(3, DBG_CRITICAL, "WARNING: url_rewrite_concurrency upgrade overriding url_rewrite_children settings.");
+        Config.redirectChildren.concurrency = cval;
+    }
+}
+
 /* Parse a time specification from the config file.  Store the
  * result in 'tptr', after converting it to 'units' */
 static void
@@ -1035,6 +1064,52 @@ parseBytesLine(size_t * bptr, const char *units)
         self_destruct();
 }
 
+#if !USE_DNSSERVERS
+static void
+parseBytesLineSigned(ssize_t * bptr, const char *units)
+{
+    char *token;
+    double d;
+    int m;
+    int u;
+
+    if ((u = parseBytesUnits(units)) == 0) {
+        self_destruct();
+        return;
+    }
+
+    if ((token = strtok(NULL, w_space)) == NULL) {
+        self_destruct();
+        return;
+    }
+
+    if (strcmp(token, "none") == 0 || token[0] == '-' /* -N */) {
+        *bptr = -1;
+        return;
+    }
+
+    d = xatof(token);
+
+    m = u;                     /* default to 'units' if none specified */
+
+    if (0.0 == d)
+        (void) 0;
+    else if ((token = strtok(NULL, w_space)) == NULL)
+        debugs(3, 0, "WARNING: No units on '" <<
+               config_input_line << "', assuming " <<
+               d << " " <<  units  );
+    else if ((m = parseBytesUnits(token)) == 0) {
+        self_destruct();
+        return;
+    }
+
+    *bptr = static_cast<size_t>(m * d / u);
+
+    if (static_cast<double>(*bptr) * 2 != m * d / u * 2)
+        self_destruct();
+}
+#endif
+
 static size_t
 parseBytesUnits(const char *unit)
 {
@@ -1097,7 +1172,7 @@ free_acl(ACL ** ae)
     aclDestroyAcls(ae);
 }
 
-static void
+void
 dump_acl_list(StoreEntry * entry, ACLList * head)
 {
     ACLList *l;
@@ -1252,8 +1327,7 @@ parse_acl_tos(acl_tos ** head)
 {
     acl_tos *l;
     acl_tos **tail = head;     /* sane name below */
-    int tos;
-    char junk;
+    unsigned int tos;           /* Initially uint for strtoui. Casted to tos_t before return */
     char *token = strtok(NULL, w_space);
 
     if (!token) {
@@ -1261,12 +1335,7 @@ parse_acl_tos(acl_tos ** head)
         return;
     }
 
-    if (sscanf(token, "0x%x%c", &tos, &junk) != 1) {
-        self_destruct();
-        return;
-    }
-
-    if (tos < 0 || tos > 255) {
+    if (!xstrtoui(token, NULL, &tos, 0, std::numeric_limits<tos_t>::max())) {
         self_destruct();
         return;
     }
@@ -1275,7 +1344,7 @@ parse_acl_tos(acl_tos ** head)
 
     l = cbdataAlloc(acl_tos);
 
-    l->tos = tos;
+    l->tos = (tos_t)tos;
 
     aclParseAclList(LegacyParser, &l->aclList);
 
@@ -1296,6 +1365,78 @@ free_acl_tos(acl_tos ** head)
     }
 }
 
+#if defined(SO_MARK)
+
+CBDATA_TYPE(acl_nfmark);
+
+static void
+dump_acl_nfmark(StoreEntry * entry, const char *name, acl_nfmark * head)
+{
+    acl_nfmark *l;
+
+    for (l = head; l; l = l->next) {
+        if (l->nfmark > 0)
+            storeAppendPrintf(entry, "%s 0x%02X", name, l->nfmark);
+        else
+            storeAppendPrintf(entry, "%s none", name);
+
+        dump_acl_list(entry, l->aclList);
+
+        storeAppendPrintf(entry, "\n");
+    }
+}
+
+static void
+freed_acl_nfmark(void *data)
+{
+    acl_nfmark *l = static_cast<acl_nfmark *>(data);
+    aclDestroyAclList(&l->aclList);
+}
+
+static void
+parse_acl_nfmark(acl_nfmark ** head)
+{
+    acl_nfmark *l;
+    acl_nfmark **tail = head;  /* sane name below */
+    nfmark_t mark;
+    char *token = strtok(NULL, w_space);
+
+    if (!token) {
+        self_destruct();
+        return;
+    }
+
+    if (!xstrtoui(token, NULL, &mark, 0, std::numeric_limits<nfmark_t>::max())) {
+        self_destruct();
+        return;
+    }
+
+    CBDATA_INIT_TYPE_FREECB(acl_nfmark, freed_acl_nfmark);
+
+    l = cbdataAlloc(acl_nfmark);
+
+    l->nfmark = mark;
+
+    aclParseAclList(LegacyParser, &l->aclList);
+
+    while (*tail)
+        tail = &(*tail)->next;
+
+    *tail = l;
+}
+
+static void
+free_acl_nfmark(acl_nfmark ** head)
+{
+    while (*head) {
+        acl_nfmark *l = *head;
+        *head = l->next;
+        l->next = NULL;
+        cbdataFree(l);
+    }
+}
+#endif /* SO_MARK */
+
 CBDATA_TYPE(acl_size_t);
 
 static void
@@ -1405,6 +1546,48 @@ parse_delay_pool_access(DelayConfig * cfg)
 
 #endif
 
+#if DELAY_POOLS
+#include "ClientDelayConfig.h"
+/* do nothing - free_client_delay_pool_count is the magic free function.
+ * this is why client_delay_pool_count isn't just marked TYPE: ushort
+ */
+
+#define free_client_delay_pool_access(X)
+#define free_client_delay_pool_rates(X)
+#define dump_client_delay_pool_access(X, Y, Z)
+#define dump_client_delay_pool_rates(X, Y, Z)
+
+static void
+free_client_delay_pool_count(ClientDelayConfig * cfg)
+{
+    cfg->freePoolCount();
+}
+
+static void
+dump_client_delay_pool_count(StoreEntry * entry, const char *name, ClientDelayConfig &cfg)
+{
+    cfg.dumpPoolCount (entry, name);
+}
+
+static void
+parse_client_delay_pool_count(ClientDelayConfig * cfg)
+{
+    cfg->parsePoolCount();
+}
+
+static void
+parse_client_delay_pool_rates(ClientDelayConfig * cfg)
+{
+    cfg->parsePoolRates();
+}
+
+static void
+parse_client_delay_pool_access(ClientDelayConfig * cfg)
+{
+    cfg->parsePoolAccess(LegacyParser);
+}
+#endif
+
 #if USE_HTTP_VIOLATIONS
 static void
 dump_http_header_access(StoreEntry * entry, const char *name, header_mangler header[])
@@ -1635,6 +1818,18 @@ find_fstype(char *type)
 static void
 parse_cachedir(SquidConfig::_cacheSwap * swap)
 {
+    // The workers option must preceed cache_dir for the IamWorkerProcess check
+    // below to work. TODO: Redo IamWorkerProcess to work w/o Config and remove
+    if (KidIdentifier > 1 && Config.workers == 1) {
+        debugs(3, DBG_CRITICAL,
+               "FATAL: cache_dir found before the workers option. Reorder.");
+        self_destruct();
+    }
+
+    // Among all processes, only workers may need and can handle cache_dir.
+    if (!IamWorkerProcess())
+        return;
+
     char *type_str;
     char *path_str;
     RefCount<SwapDir> sd;
@@ -1917,7 +2112,6 @@ parse_peer(peer ** head)
             char *mode, *nextmode;
             for (mode = nextmode = tmp; mode; mode = nextmode) {
                 nextmode = strchr(mode, ',');
-                debugs(0,0,"HTCP mode '" << mode << "' next=" << nextmode);
                 if (nextmode)
                     *nextmode++ = '\0';
                 if (!strcasecmp(mode, "no-clr")) {
@@ -2062,7 +2256,7 @@ parse_peer(peer ** head)
 
     p->icp.version = ICP_VERSION_CURRENT;
 
-    p->test_fd = -1;
+    p->testing_now = false;
 
 #if USE_CACHE_DIGESTS
 
@@ -2736,6 +2930,14 @@ dump_b_size_t(StoreEntry * entry, const char *name, size_t var)
     storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR);
 }
 
+#if !USE_DNSSERVERS
+static void
+dump_b_ssize_t(StoreEntry * entry, const char *name, ssize_t var)
+{
+    storeAppendPrintf(entry, "%s %d %s\n", name, (int) var, B_BYTES_STR);
+}
+#endif
+
 #if UNUSED_CODE
 static void
 dump_kb_size_t(StoreEntry * entry, const char *name, size_t var)
@@ -2772,6 +2974,14 @@ parse_b_size_t(size_t * var)
     parseBytesLine(var, B_BYTES_STR);
 }
 
+#if !USE_DNSSERVERS
+static void
+parse_b_ssize_t(ssize_t * var)
+{
+    parseBytesLineSigned(var, B_BYTES_STR);
+}
+#endif
+
 #if UNUSED_CODE
 static void
 parse_kb_size_t(size_t * var)
@@ -2798,6 +3008,14 @@ free_size_t(size_t * var)
     *var = 0;
 }
 
+#if !USE_DNSSERVERS
+static void
+free_ssize_t(ssize_t * var)
+{
+    *var = 0;
+}
+#endif
+
 static void
 free_b_int64_t(int64_t * var)
 {
@@ -2805,6 +3023,7 @@ free_b_int64_t(int64_t * var)
 }
 
 #define free_b_size_t free_size_t
+#define free_b_ssize_t free_ssize_t
 #define free_kb_size_t free_size_t
 #define free_mb_size_t free_size_t
 #define free_gb_size_t free_size_t
@@ -3843,6 +4062,83 @@ free_access_log(customlog ** definitions)
     }
 }
 
+/// parses list of integers form name=N1,N2,N3,...
+static bool
+parseNamedIntList(const char *data, const String &name, Vector<int> &list)
+{
+    if (data && (strncmp(data, name.rawBuf(), name.size()) == 0)) {
+        data += name.size();
+        if (*data == '=') {
+            while (true) {
+                ++data;
+                int value = 0;
+                if (!StringToInt(data, value, &data, 10))
+                    break;
+                list.push_back(value);
+                if (*data == '\0' || *data != ',')
+                    break;
+            }
+        }
+    }
+    return data && *data == '\0';
+}
+
+static void
+parse_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap)
+{
+#if !HAVE_CPU_AFFINITY
+    debugs(3, DBG_CRITICAL, "FATAL: Squid built with no CPU affinity " <<
+           "support, do not set 'cpu_affinity_map'");
+    self_destruct();
+#endif /* HAVE_CPU_AFFINITY */
+
+    if (!*cpuAffinityMap)
+        *cpuAffinityMap = new CpuAffinityMap;
+
+    const char *const pToken = strtok(NULL, w_space);
+    const char *const cToken = strtok(NULL, w_space);
+    Vector<int> processes, cores;
+    if (!parseNamedIntList(pToken, "process_numbers", processes)) {
+        debugs(3, DBG_CRITICAL, "FATAL: bad 'process_numbers' parameter " <<
+               "in 'cpu_affinity_map'");
+        self_destruct();
+    } else if (!parseNamedIntList(cToken, "cores", cores)) {
+        debugs(3, DBG_CRITICAL, "FATAL: bad 'cores' parameter in " <<
+               "'cpu_affinity_map'");
+        self_destruct();
+    } else if (!(*cpuAffinityMap)->add(processes, cores)) {
+        debugs(3, DBG_CRITICAL, "FATAL: bad 'cpu_affinity_map'; " <<
+               "process_numbers and cores lists differ in length or " <<
+               "contain numbers <= 0");
+        self_destruct();
+    }
+}
+
+static void
+dump_CpuAffinityMap(StoreEntry *const entry, const char *const name, const CpuAffinityMap *const cpuAffinityMap)
+{
+    if (cpuAffinityMap) {
+        storeAppendPrintf(entry, "%s process_numbers=", name);
+        for (size_t i = 0; i < cpuAffinityMap->processes().size(); ++i) {
+            storeAppendPrintf(entry, "%s%i", (i ? "," : ""),
+                              cpuAffinityMap->processes()[i]);
+        }
+        storeAppendPrintf(entry, " cores=");
+        for (size_t i = 0; i < cpuAffinityMap->processes().size(); ++i) {
+            storeAppendPrintf(entry, "%s%i", (i ? "," : ""),
+                              cpuAffinityMap->cores()[i]);
+        }
+        storeAppendPrintf(entry, "\n");
+    }
+}
+
+static void
+free_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap)
+{
+    delete *cpuAffinityMap;
+    *cpuAffinityMap = NULL;
+}
+
 #if USE_ADAPTATION
 
 static void