Hello all!
I've included a patch which reloads acl-files when they have changed.
It is against squid-1.1.16 and my squids are running with this patch
for several days now (before that, it ran on 1.1.8 for several weeks ...)
I am reloading a large acl file with ~3000 entires 2-3 times a day.
But: Why not give squid a configure-interface like innd. squid would
wait on one end of a named pipe and then a simple program, maybe called
"ctlsquid" (from ctlinnd) could write simple commands like "reload acls"
to this pipe.
That's all!
And here's the patch:
diff -c squid-1.1.16/src/acl.c squid-1.1.16.1/src/acl.c
*** squid-1.1.16/src/acl.c Thu Apr 24 21:43:17 1997
--- squid-1.1.16.1/src/acl.c Mon Sep 1 09:25:46 1997
***************
*** 56,61 ****
--- 56,65 ----
static int aclFromFile = 0;
static FILE *aclFile;
+ /* These two to transport info from strtokFile to aclParseAclLine */
+ time_t aclfile_last_read_st_mtime = 0;
+ char *aclfile_last_read_filename = NULL;
+
static void aclDestroyAclList _PARAMS((struct _acl_list * list));
static void aclDestroyTimeList _PARAMS((struct _acl_time_data * data));
static int aclMatchAclList _PARAMS((const struct _acl_list *, aclCheck_t *));
***************
*** 104,109 ****
--- 108,114 ----
strtokFile(void)
{
char *t, *fn;
+ struct stat filestat;
LOCAL_ARRAY(char, buf, 256);
strtok_again:
***************
*** 120,130 ****
--- 125,142 ----
return (NULL);
}
aclFromFile = 1;
+ if(stat(fn, &filestat)) {
+ debug(28,0, "strtokFile: %s: cannot stat\n", fn);
+ } else {
+ aclfile_last_read_st_mtime = filestat.st_mtime;
+ aclfile_last_read_filename = xstrdup(fn);
+ }
} else {
return (t);
}
}
/* aclFromFile */
+ read_again:
if (fgets(buf, 256, aclFile) == NULL) {
/* stop reading from file */
fclose(aclFile);
***************
*** 135,140 ****
--- 147,157 ----
/* skip leading and trailing white space */
t += strspn(buf, w_space);
t[strcspn(t, w_space)] = '\0';
+ if(*t == '#') /* Allow comments */
+ goto read_again;
+ if(strlen(t) == 0) /* Allow blank lines */
+ goto read_again;
+
return (t);
}
}
***************
*** 654,659 ****
--- 671,685 ----
debug_trap("Bad ACL type");
break;
}
+
+ if(aclfile_last_read_st_mtime) {
+ A->aclfile_st_mtime = aclfile_last_read_st_mtime;
+ aclfile_last_read_st_mtime = 0;
+ A->aclfile_filename = xstrdup(aclfile_last_read_filename);
+ safe_free(aclfile_last_read_filename);
+ A->aclfile_last_checked = squid_curtime;
+ }
+
if (!new_acl)
return;
if (A->data == NULL) {
***************
*** 1047,1055 ****
--- 1073,1170 ----
const request_t *r = checklist->request;
const ipcache_addrs *ia = NULL;
const char *fqdn = NULL;
+ char *my_cfgline;
int k;
+ struct stat filestat;
+
if (!acl)
return 0;
+
+ if(acl->aclfile_last_checked && (squid_curtime - acl->aclfile_last_checked) > Config.aclfile_CheckInterval) {
+ debug(28,2, "aclMatchAcl: checking if aclfile \"%s\" has changed\n", acl->aclfile_filename);
+ if(stat(acl->aclfile_filename, &filestat)) {
+ debug(28,0, "aclMatchAcl: cannot stat \"%s\"\n", acl->aclfile_filename);
+ } else {
+ if(filestat.st_mtime > acl->aclfile_st_mtime) {
+ debug(28,1, "aclMatchAcl: re-reading aclfile \"%s\"\n", acl->aclfile_filename);
+
+ /* Reinitialize strtok */
+ my_cfgline = xstrdup(acl->cfgline);
+ strtok(my_cfgline, w_space); /* acl */
+ strtok(NULL, w_space); /* name */
+ strtok(NULL, w_space); /* type */
+
+ /* Delete old acl->data and re-read it */
+ switch (acl->type) {
+ case ACL_SRC_IP:
+ case ACL_DST_IP:
+ #if defined (USE_SPLAY_TREE)
+ splay_destroy(acl->data, xfree);
+ #elif defined(USE_BIN_TREE)
+ aclDestroyTree(acl->data);
+ #else /* LINKED LIST */
+ aclDestroyIpList(acl->data);
+ #endif
+ acl->data = NULL;
+ aclParseIpList(&acl->data);
+ break;
+ case ACL_DST_DOMAIN:
+ case ACL_SRC_DOMAIN:
+ #if defined(USE_SPLAY_TREE)
+ splay_destroy(acl->data, xfree);
+ #elif defined(USE_BIN_TREE)
+ aclDestroyTree(acl->data);
+ #else /* LINKED LIST */
+ wordlistDestroy((wordlist **) & acl->data);
+ #endif
+ acl->data = NULL;
+ aclParseDomainList(&acl->data);
+ break;
+ case ACL_USER:
+ wordlistDestroy((wordlist **) & acl->data);
+ Config.identLookup = 1;
+ acl->data = NULL;
+ aclParseWordList(&acl->data);
+ break;
+ case ACL_TIME:
+ aclDestroyTimeList(acl->data);
+ acl->data = NULL;
+ aclParseTimeSpec(&acl->data);
+ break;
+ case ACL_URL_REGEX:
+ case ACL_URLPATH_REGEX:
+ case ACL_BROWSER:
+ aclDestroyRegexList(acl->data);
+ acl->data = NULL;
+ aclParseRegexList(&acl->data, 0);
+ break;
+ case ACL_URL_PORT:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseIntlist(&acl->data);
+ break;
+ case ACL_PROTO:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseProtoList(&acl->data);
+ case ACL_METHOD:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseMethodList(&acl->data);
+ break;
+ case ACL_NONE:
+ default:
+ fatal_dump("aclDestroyAcls: Found ACL_NONE?");
+ break;
+ }
+ xfree(my_cfgline);
+
+ acl->aclfile_st_mtime = filestat.st_mtime;
+ }
+ acl->aclfile_last_checked = squid_curtime;
+ }
+ }
+
debug(28, 3, "aclMatchAcl: checking '%s'\n", acl->cfgline);
switch (acl->type) {
case ACL_SRC_IP:
diff -c squid-1.1.16/src/acl.h squid-1.1.16.1/src/acl.h
*** squid-1.1.16/src/acl.h Thu Feb 20 22:03:10 1997
--- squid-1.1.16.1/src/acl.h Mon Sep 1 10:02:07 1997
***************
*** 96,101 ****
--- 96,104 ----
squid_acl type;
void *data;
char *cfgline;
+ char *aclfile_filename;
+ time_t aclfile_last_checked;
+ time_t aclfile_st_mtime;
struct _acl *next;
};
diff -c squid-1.1.16/src/cache_cf.c squid-1.1.16.1/src/cache_cf.c
*** squid-1.1.16/src/cache_cf.c Thu Aug 21 21:17:04 1997
--- squid-1.1.16.1/src/cache_cf.c Mon Sep 1 09:31:03 1997
***************
*** 209,215 ****
--- 209,217 ----
#define DefaultOptionsClientDb 1 /* default on */
#define DefaultOptionsQueryIcmp 0 /* default off */
+ #define DefaultAclFileCheckInterval 300
+
int httpd_accel_mode = 0; /* for fast access */
const char *DefaultSwapDir = DEFAULT_SWAP_DIR;
const char *DefaultConfigFile = DEFAULT_CONFIG_FILE;
***************
*** 1143,1148 ****
--- 1145,1153 ----
else if (!strcmp(token, "acl"))
aclParseAclLine();
+ else if (!strcmp(token, "aclfile_checkinterval"))
+ parseIntegerValue(&Config.aclfile_CheckInterval);
+
else if (!strcmp(token, "deny_info"))
aclParseDenyInfoLine(&DenyInfoList);
***************
*** 1611,1616 ****
--- 1620,1626 ----
Config.Options.anonymizer = DefaultOptionsAnonymizer;
Config.Options.icp_hit_stale = DefaultOptionsIcpHitStale;
Config.Options.enable_purge = DefaultOptionsEnablePurge;
+ Config.aclfile_CheckInterval = DefaultAclFileCheckInterval;
Config.Options.client_db = DefaultOptionsClientDb;
Config.Options.query_icmp = DefaultOptionsQueryIcmp;
#ifdef RELOAD_INTO_IMS
diff -c squid-1.1.16/src/cache_cf.h squid-1.1.16.1/src/cache_cf.h
*** squid-1.1.16/src/cache_cf.h Thu Aug 7 22:49:23 1997
--- squid-1.1.16.1/src/cache_cf.h Mon Sep 1 09:33:23 1997
***************
*** 282,287 ****
--- 283,289 ----
int reload_into_ims;
#endif /* RELOAD_INTO_IMS */
} Options;
+ int aclfile_CheckInterval;
char *fake_ua;
};
diff -c squid-1.1.16/src/squid.conf.pre.in squid-1.1.16.1/src/squid.conf.pre.in
*** squid-1.1.16/src/squid.conf.pre.in Thu Aug 7 22:38:02 1997
--- squid-1.1.16.1/src/squid.conf.pre.in Mon Sep 1 09:39:43 1997
***************
*** 1166,1171 ****
--- 1166,1180 ----
#
#http_anonymizer off
+ # TAG: aclfile_checkinterval
+ # If you are using config files for your acls, these files
+ # are checked for changes after this interval.
+ # If the modification time has changed, they are reloaded.
+ #
+ # default are 300 seconds
+ #aclfile_checkinterval 300
+
+
# TAG: fake_user_agent
# If you use the paranoid http_anonymizer setting, Squid will strip
# your User-agent string from the request. Some Web servers will
Received on Tue Jul 29 2003 - 13:15:43 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:11:25 MST