PERFORCE change 86904 for review
soc-bushman
soc-bushman at FreeBSD.org
Fri Nov 18 05:30:17 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=86904
Change 86904 by soc-bushman at soc-bushman_stinger on 2005/11/18 13:29:56
cache invalidation feature (with -i and -I command line arguments) was added
libpidfile is now used (through libutil)
all chages should be tested carefully
Affected files ...
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/Makefile#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#12 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/Makefile.inc#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.c#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.h#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.c#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.h#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.c#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.h#7 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.c#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.h#11 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/startup/cached#6 edit
Differences ...
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/Makefile#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#12 (text+ko) ====
@@ -5,11 +5,12 @@
MAN=cached.conf.5 cached.8
WARNS?=2
-SRCS= agent.c cached.c cachelib.c cacheplcs.c debug.c log.c config.c query.c\
- mp_ws_query.c mp_rs_query.c singletons.c protocol.c parser.c
+SRCS= agent.c cached.c cachedcli.c cachelib.c cacheplcs.c debug.c log.c \
+ config.c query.c mp_ws_query.c mp_rs_query.c singletons.c protocol.c \
+ parser.c
CFLAGS+= -DCONFIG_PATH="\"${PREFIX}/etc/cached.conf\""
-DPADD+=${LIBM} ${LIBPTHREAD}
-LDADD+=${LIBM} ${LIBPTHREAD}
+DPADD+=${LIBM} ${LIBPTHREAD} ${LIBUTIL}
+LDADD+=${LIBM} ${LIBPTHREAD} ${LIBUTIL}
LDFLAGS+= -Xlinker --export-dynamic
FILESGROUPS=STARTUP CONF
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.c#4 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.h#4 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/Makefile.inc#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.c#4 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.h#4 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.c#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.h#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.c#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.h#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.c#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.h#7 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#11 (text+ko) ====
@@ -29,10 +29,13 @@
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/time.h>
+#include <sys/param.h>
#include <sys/un.h>
#include <assert.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <libutil.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -44,6 +47,7 @@
#include "agents/group.h"
#include "agents/services.h"
#include "agents/hosts.h"
+#include "cachedcli.h"
#include "cachelib.h"
#include "config.h"
#include "debug.h"
@@ -53,7 +57,7 @@
#include "singletons.h"
#ifndef CONFIG_PATH
-#define CONFIG_PATH "/usr/local/etc/cached.conf"
+#define CONFIG_PATH "/etc/cached.conf"
#endif
#define DEFAULT_CONFIG_PATH "cached.conf"
@@ -86,7 +90,6 @@
static void process_timer_event(struct kevent *, struct runtime_env *,
struct configuration *);
static void *processing_thread(void *);
-static int write_pid_file(const char *);
static void usage(void);
void get_time_func(struct timeval *);
@@ -128,29 +131,6 @@
TRACE_OUT(destroy_global_timer);
}
-static int
-write_pid_file(const char *filename)
-{
- char *pid_string;
- FILE *pidfile;
-
- pidfile = fopen(filename, "w");
- if (pidfile == NULL) {
- LOG_ERR_2("write_pid_file", "can't write to pidfile %s",
- filename);
- return (-1);
- }
-
- asprintf(&pid_string,"%u",getpid());
- assert(pid_string != NULL);
-
- fwrite(pid_string,strlen(pid_string), 1, pidfile);
- free(pid_string);
- fclose(pidfile);
-
- return (0);
-}
-
static void
print_version_info(void)
{
@@ -162,7 +142,7 @@
static void
usage(void)
{
- fprintf(stderr,"usage: cached [-nst]\n");
+ fprintf(stderr,"usage: cached [-nstiId]\n");
exit(1);
}
@@ -190,9 +170,18 @@
* would be registered automatically during the queries.
*/
res = register_cache_entry(retval, (struct cache_entry_params *)
- &config_entry->positive_cache_params);
+ &config_entry->positive_cache_params);
+ config_entry->positive_cache_entry = find_cache_entry(retval,
+ config_entry->positive_cache_params.entry_name);
+ assert(config_entry->positive_cache_entry !=
+ INVALID_CACHE_ENTRY);
+
res = register_cache_entry(retval, (struct cache_entry_params *)
&config_entry->negative_cache_params);
+ config_entry->negative_cache_entry = find_cache_entry(retval,
+ config_entry->negative_cache_params.entry_name);
+ assert(config_entry->negative_cache_entry !=
+ INVALID_CACHE_ENTRY);
}
LOG_MSG_2("cache", "cache was successfully initialized");
@@ -642,6 +631,12 @@
int
main(int argc, char *argv[])
{
+ struct processing_thread_args *thread_args;
+ pthread_t *threads;
+
+ struct pidfh *pidfile;
+ pid_t pid;
+
char const *config_file;
char const *error_str;
int error_line;
@@ -650,9 +645,11 @@
int trace_mode_enabled;
int force_single_threaded;
int do_not_daemonize;
+ int clear_user_cache_entries, clear_all_cache_entries;
+ char *user_config_entry_name, *global_config_entry_name;
+ int show_statistics;
+ int daemon_mode, interactive_mode;
- struct processing_thread_args *thread_args;
- pthread_t *threads;
/* by default all debug messages are omitted */
TRACE_OFF();
@@ -664,7 +661,12 @@
trace_mode_enabled = 0;
force_single_threaded = 0;
do_not_daemonize = 0;
- while ((res = getopt(argc, argv, "nst")) != -1) {
+ clear_user_cache_entries = 0;
+ clear_all_cache_entries = 0;
+ show_statistics = 0;
+ user_config_entry_name = NULL;
+ global_config_entry_name = NULL;
+ while ((res = getopt(argc, argv, "nstdi:I:")) != -1) {
switch (res) {
case 'n':
do_not_daemonize = 1;
@@ -675,6 +677,22 @@
case 't':
trace_mode_enabled = 1;
break;
+ case 'i':
+ clear_user_cache_entries = 1;
+ if (optarg != NULL)
+ if (strcmp(optarg, "all") != 0)
+ user_config_entry_name = strdup(optarg);
+ break;
+ case 'I':
+ clear_all_cache_entries = 1;
+ if (optarg != NULL)
+ if (strcmp(optarg, "all") != 0)
+ global_config_entry_name =
+ strdup(optarg);
+ break;
+ case 'd':
+ show_statistics = 1;
+ break;
case '?':
default:
usage();
@@ -682,6 +700,92 @@
}
}
+ daemon_mode = do_not_daemonize | force_single_threaded |
+ trace_mode_enabled;
+ interactive_mode = clear_user_cache_entries | clear_all_cache_entries |
+ show_statistics;
+
+ if ((daemon_mode != 0) && (interactive_mode != 0)) {
+ LOG_ERR_1("main", "daemon mode and interactive_mode arguments "
+ "can't be used together");
+ usage();
+ }
+
+ if (interactive_mode != 0) {
+ FILE *pidfin = fopen(DEFAULT_PIDFILE_PATH, "r");
+ char pidbuf[256];
+
+ struct cached_connection_params connection_params;
+ cached_connection connection;
+
+ int result;
+
+ if (pidfin == NULL)
+ errx(EXIT_FAILURE, "There is no daemon running.");
+
+ memset(pidbuf, 0, sizeof(pidbuf));
+ fread(pidbuf, sizeof(pidbuf) - 1, 1, pidfin);
+ fclose(pidfin);
+
+ if (ferror(pidfin) != 0)
+ errx(EXIT_FAILURE, "Can't read from pidfile.");
+
+ if (sscanf(pidbuf, "%d", &pid) != 1)
+ errx(EXIT_FAILURE, "Invalid pidfile.");
+ LOG_MSG_1("main", "daemon PID is %d", pid);
+
+
+ memset(&connection_params, 0,
+ sizeof(struct cached_connection_params));
+ connection_params.socket_path = DEFAULT_SOCKET_PATH;
+ connection = open_cached_connection(&connection_params);
+ if (connection == INVALID_CACHED_CONNECTION)
+ errx(EXIT_FAILURE, "Can't connect to the daemon.");
+
+ if (clear_user_cache_entries != 0) {
+ result = cached_transform(connection,
+ user_config_entry_name, TT_USER);
+ if (result != 0)
+ LOG_MSG_1("main",
+ "user cache transformation failed");
+ else
+ LOG_MSG_1("main",
+ "user cache_transformation "
+ "succeeded");
+ }
+
+ if (clear_all_cache_entries != 0) {
+ if (geteuid() != 0)
+ errx(EXIT_FAILURE, "Only root can initiate "
+ "global cache transformation.");
+
+ result = cached_transform(connection,
+ global_config_entry_name, TT_ALL);
+ if (result != 0)
+ LOG_MSG_1("main",
+ "global cache transformation "
+ "failed");
+ else
+ LOG_MSG_1("main",
+ "global cache transformation "
+ "succeeded");
+ }
+
+ close_cached_connection(connection);
+
+ free(user_config_entry_name);
+ free(global_config_entry_name);
+ return (EXIT_SUCCESS);
+ }
+
+ pidfile = pidfile_open(DEFAULT_PIDFILE_PATH, 0600, &pid);
+ if (pidfile == NULL) {
+ if (errno == EEXIST)
+ errx(EXIT_FAILURE, "Daemon already running, pid: %d.",
+ pid);
+ warn("Cannot open or create pidfile");
+ }
+
if (trace_mode_enabled == 1)
TRACE_ON();
@@ -694,11 +798,14 @@
if (res != 0) {
LOG_ERR_1("main", "can't daemonize myself: %s",
strerror(errno));
+ pidfile_remove(pidfile);
goto fin;
} else
LOG_MSG_1("main", "successfully daemonized");
}
+ pidfile_write(pidfile);
+
/* global timer initialization */
res = init_global_timer();
if (res != 0) {
@@ -770,16 +877,8 @@
destroy_configuration(s_configuration);
destroy_cache_(s_cache);
return (-1);
- }
-
- /* writing PID file */
- res = write_pid_file(s_configuration->pidfile_path);
- if (res != 0) {
- LOG_ERR_1("main", "can't write the pid file into the %s",
- s_configuration->pidfile_path);
- goto fin;
- }
-
+ }
+
if (s_configuration->threads_num > 1) {
threads = (pthread_t *)malloc(sizeof(pthread_t) *
s_configuration->threads_num);
@@ -823,5 +922,6 @@
/* global timer destruction */
destroy_global_timer();
- return (0);
+ pidfile_remove(pidfile);
+ return (EXIT_SUCCESS);
}
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#11 (text+ko) ====
@@ -38,10 +38,9 @@
see them below.
.Pp
Each line specifies either an attribute and a value, or an attribute,
-a cachename and a value. Valid cachenames are passwd, groups, hosts,
-services, protocols and rpc. If you need to use some other cachename for
-your own needs (for example, if some third-party application uses nsswitch),
-you can simply use it without any restrictions.
+a cachename and a value. Usual cachenames are passwd, groups, hosts,
+services, protocols and rpc. You can also use any other cachename
+(for example, if some third-party application uses nsswitch).
.Pp
.Bl -tag -width Pair
.It Sy threads [value]
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#11 (text+ko) ====
@@ -61,6 +61,7 @@
int (*)(struct cache_common_entry_ *,
struct cache_policy_item_ *));
static int ht_items_cmp_func(const void *, const void *);
+static int ht_items_fixed_size_left_cmp_func(const void *, const void *);
static hashtable_index_t ht_item_hash_func(const void *, size_t);
/*
@@ -70,6 +71,8 @@
ht_items_cmp_func(const void *p1, const void *p2)
{
struct cache_ht_item_data_ *hp1, *hp2;
+ size_t min_size;
+ int result;
hp1 = (struct cache_ht_item_data_ *)p1;
hp2 = (struct cache_ht_item_data_ *)p2;
@@ -77,10 +80,46 @@
assert(hp1->key != NULL);
assert(hp2->key != NULL);
- if (hp1->key_size != hp2->key_size)
- return (-1);
+ if (hp1->key_size != hp2->key_size) {
+ min_size = (hp1->key_size < hp2->key_size) ? hp1->key_size :
+ hp2->key_size;
+ result = memcmp(hp1->key, hp2->key, min_size);
+
+ if (result == 0)
+ return ((hp1->key_size < hp2->key_size) ? -1 : 1);
+ else
+ return (result);
+ } else
+ return (memcmp(hp1->key, hp2->key, hp1->key_size));
+}
+
+static int
+ht_items_fixed_size_left_cmp_func(const void *p1, const void *p2)
+{
+ struct cache_ht_item_data_ *hp1, *hp2;
+ size_t min_size;
+ int result;
+
+ hp1 = (struct cache_ht_item_data_ *)p1;
+ hp2 = (struct cache_ht_item_data_ *)p2;
+
+ assert(hp1->key != NULL);
+ assert(hp2->key != NULL);
- return (memcmp(hp1->key, hp2->key, hp1->key_size));
+ if (hp1->key_size != hp2->key_size) {
+ min_size = (hp1->key_size < hp2->key_size) ? hp1->key_size :
+ hp2->key_size;
+ result = memcmp(hp1->key, hp2->key, min_size);
+
+ if (result == 0)
+ if (min_size == hp1->key_size)
+ return (0);
+ else
+ return ((hp1->key_size < hp2->key_size) ? -1 : 1);
+ else
+ return (result);
+ } else
+ return (memcmp(hp1->key, hp2->key, hp1->key_size));
}
static hashtable_index_t
@@ -361,6 +400,7 @@
HASHTABLE_ENTRY_REMOVE(cache_ht_, ht_item, ht_item_data);
free(ht_item_data->key);
free(ht_item_data->value);
+ free(ht_item_data);
--entry->items_size;
policy->destroy_item_func(item);
@@ -1105,44 +1145,89 @@
TRACE_OUT(close_cache_mp_read_session);
}
-/*
- * Transforms all cache entries, by applying the specified transformation.
- */
-int
-transform_cache(struct cache_ *the_cache,
- enum cache_transformation_t transformation)
-{
- int cur_retval;
- int retval;
- size_t i;
-
- retval = 0;
- for (i = 0; i < the_cache->entries_size; ++i) {
- cur_retval = transform_cache_entry(the_cache->entries[i],
- transformation);
- if ((cur_retval != 0) && (retval == 0))
- retval = -2;
-
- if ((cur_retval == 0) && (retval == -2))
- retval = -1;
- }
-
- return (retval);
-}
-
int
transform_cache_entry(struct cache_entry_ *entry,
enum cache_transformation_t transformation)
{
+ TRACE_IN(transform_cache_entry);
switch (transformation) {
case CTT_CLEAR:
clear_cache_entry(entry);
+ TRACE_OUT(transform_cache_entry);
return (0);
case CTT_FLUSH:
flush_cache_entry(entry);
+ TRACE_OUT(transform_cache_entry);
return (0);
default:
+ TRACE_OUT(transform_cache_entry);
return (-1);
+ }
+}
+
+int
+transform_cache_entry_part(struct cache_entry_ *entry,
+ enum cache_transformation_t transformation, const char *key_part,
+ size_t key_part_size, enum part_position_t part_position)
+{
+ struct cache_common_entry_ *common_entry;
+ struct cache_ht_item_ *ht_item;
+ struct cache_ht_item_data_ *ht_item_data, ht_key;
+
+ struct cache_policy_item_ *item, *connected_item;
+
+ TRACE_IN(transform_cache_entry_part);
+ if (entry->params->entry_type != CET_COMMON) {
+ TRACE_OUT(transform_cache_entry_part);
+ return (-1);
+ }
+
+ if (transformation != CTT_FLUSH) {
+ TRACE_OUT(transform_cache_entry_part);
+ return (-1);
+ }
+
+ memset(&ht_key, 0, sizeof(struct cache_ht_item_data_));
+ ht_key.key = (char *)key_part; /* can't avoid casting here */
+ ht_key.key_size = key_part_size;
+
+ common_entry = (struct cache_common_entry_ *)entry;
+ HASHTABLE_FOREACH(&(common_entry->items), ht_item) {
+ do {
+ ht_item_data = HASHTABLE_ENTRY_FIND_SPECIAL(cache_ht_,
+ ht_item, &ht_key,
+ ht_items_fixed_size_left_cmp_func);
+
+ if (ht_item_data != NULL) {
+ item = ht_item_data->fifo_policy_item;
+ connected_item = item->connected_item;
+
+
+ common_entry->policies[0]->remove_item_func(
+ common_entry->policies[0],
+ item);
+
+ HASHTABLE_ENTRY_REMOVE(cache_ht_, ht_item,
+ ht_item_data);
+ free(ht_item_data->key);
+ free(ht_item_data->value);
+ free(ht_item_data);
+ --common_entry->items_size;
+
+ common_entry->policies[0]->destroy_item_func(
+ item);
+ if (common_entry->policies_size == 2) {
+ common_entry->policies[1]->remove_item_func(
+ common_entry->policies[1],
+ connected_item);
+ common_entry->policies[1]->destroy_item_func(
+ connected_item);
+ }
+ }
+ } while (ht_item_data != NULL);
}
+
+ TRACE_OUT(transform_cache_entry_part);
+ return (0);
}
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#11 (text+ko) ====
@@ -57,6 +57,16 @@
CMPT_WRITE_SESSION
};
+/*
+ * When doing partial transformations of entries (which are applied for
+ * elements with keys, that contain specified buffer in its left or
+ * right part), this enum will show the needed position of the key part.
+ */
+enum part_position_t {
+ KPPT_LEFT,
+ KPPT_RIGHT
+};
+
/* num_levels attribute is obsolete, i think - user can always emulate it
* by using one entry.
* get_time_func is needed to have the clocks-independent counter
@@ -147,7 +157,7 @@
* user can specify another policy to be applied, when there are too
* many elements in the entry. So policies_size can be 1 or 2.
*/
- struct cache_policy_ ** policies;
+ struct cache_policy_ **policies;
size_t policies_size;
void (*get_time_func)(struct timeval *);
@@ -263,7 +273,8 @@
extern void close_cache_mp_read_session(cache_mp_read_session);
/* transformation routines */
-extern int transform_cache(cache, enum cache_transformation_t);
extern int transform_cache_entry(cache_entry, enum cache_transformation_t);
+extern int transform_cache_entry_part(cache_entry, enum cache_transformation_t,
+ const char *, size_t, enum part_position_t);
#endif
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#11 (text+ko) ====
@@ -48,6 +48,9 @@
static int configuration_entry_cmp(const void *, const void *);
static int configuration_entry_sort_cmp(const void *, const void *);
+static int configuration_entry_cache_mp_sort_cmp(const void *, const void *);
+static int configuration_entry_cache_mp_cmp(const void *, const void *);
+static int configuration_entry_cache_mp_part_cmp(const void *, const void *);
static struct configuration_entry *create_configuration_entry(const char *,
struct timeval const *, struct timeval const *,
struct common_cache_entry_params const *,
@@ -70,6 +73,31 @@
));
}
+static int
+configuration_entry_cache_mp_sort_cmp(const void *e1, const void *e2)
+{
+ return (strcmp((*((cache_entry *)e1))->params->entry_name,
+ (*((cache_entry *)e2))->params->entry_name
+ ));
+}
+
+static int
+configuration_entry_cache_mp_cmp(const void *e1, const void *e2)
+{
+ return (strcmp((const char *)e1,
+ (*((cache_entry *)e2))->params->entry_name
+ ));
+}
+
+static int
+configuration_entry_cache_mp_part_cmp(const void *e1, const void *e2)
+{
+ return (strncmp((const char *)e1,
+ (*((cache_entry *)e2))->params->entry_name,
+ strlen((const char *)e1)
+ ));
+}
+
static struct configuration_entry *
create_configuration_entry(const char *name,
struct timeval const *common_timeout,
@@ -248,7 +276,7 @@
}
if (config->entries_size == config->entries_capacity) {
- struct configuration_entry **new_entries;
+ struct configuration_entry **new_entries;
config->entries_capacity *= 2;
new_entries = (struct configuration_entry **)malloc(
@@ -308,6 +336,108 @@
return ((retval != NULL) ? *retval : NULL);
}
+/*
+ * All multipart cache entries are stored in the configuration_entry in the
+ * sorted array (sorted by names). The 3 functions below manage this array.
+ */
+
+int
+configuration_entry_add_mp_cache_entry(struct configuration_entry *config_entry,
+ cache_entry c_entry)
+{
+ cache_entry *new_mp_entries, *old_mp_entries;
+
+ TRACE_IN(configuration_entry_add_mp_cache_entry);
+ ++config_entry->mp_cache_entries_size;
+ new_mp_entries = (cache_entry *)malloc(sizeof(cache_entry) *
+ config_entry->mp_cache_entries_size);
+ assert(new_mp_entries != NULL);
+ new_mp_entries[0] = c_entry;
+ if (config_entry->mp_cache_entries_size - 1 > 0) {
+ memcpy(new_mp_entries + 1,
+ config_entry->mp_cache_entries,
+ config_entry->mp_cache_entries_size - 1);
+ }
+
+ old_mp_entries = config_entry->mp_cache_entries;
+ config_entry->mp_cache_entries = new_mp_entries;
+ free(old_mp_entries);
+
+ qsort(config_entry->mp_cache_entries,
+ config_entry->mp_cache_entries_size,
+ sizeof(cache_entry),
+ configuration_entry_cache_mp_sort_cmp);
+
+ TRACE_OUT(configuration_entry_add_mp_cache_entry);
+
+ return (0);
+}
+
+cache_entry
+configuration_entry_find_mp_cache_entry(
+ struct configuration_entry *config_entry, const char *mp_name)
+{
+ cache_entry *result;
+
+ TRACE_IN(configuration_entry_find_mp_cache_entry);
+ result = bsearch(mp_name, config_entry->mp_cache_entries,
+ config_entry->mp_cache_entries_size,
+ sizeof(cache_entry), configuration_entry_cache_mp_cmp);
+
+ if (result == NULL) {
+ TRACE_OUT(configuration_entry_find_mp_cache_entry);
+ return (NULL);
+ } else {
+ TRACE_OUT(configuration_entry_find_mp_cache_entry);
+ return (*result);
+ }
+}
+
+/*
+ * Searches for all multipart entries with names starting with mp_name.
+ * Needed for cache flushing.
+ */
+int
+configuration_entry_find_mp_cache_entries(
+ struct configuration_entry *config_entry, const char *mp_name,
+ cache_entry **start, cache_entry **finish)
+{
+ cache_entry *result;
+
+ TRACE_IN(configuration_entry_find_mp_cache_entries);
+ result = bsearch(mp_name, config_entry->mp_cache_entries,
+ config_entry->mp_cache_entries_size,
+ sizeof(cache_entry), configuration_entry_cache_mp_part_cmp);
+
+ if (result == NULL) {
+ TRACE_OUT(configuration_entry_find_mp_cache_entries);
+ return (-1);
+ }
+
+ *start = result;
+ *finish = result + 1;
+
+ while (*start != config_entry->mp_cache_entries) {
+ if (configuration_entry_cache_mp_part_cmp(mp_name, *start - 1) == 0)
+ *start = *start - 1;
+ else
+ break;
+ }
+
+ while (*finish != config_entry->mp_cache_entries +
+ config_entry->mp_cache_entries_size) {
+
+ if (configuration_entry_cache_mp_part_cmp(
+ mp_name, *finish) == 0)
+ *finish = *finish + 1;
+ else
+ break;
+ }
+
+ TRACE_OUT(configuration_entry_find_mp_cache_entries);
+ return (0);
+}
+
/*
* Configuration entry uses rwlock to handle access to its fields.
*/
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#11 (text+ko) ====
@@ -133,6 +133,15 @@
struct configuration *, size_t);
extern struct configuration_entry *configuration_find_entry(
struct configuration *, const char *);
+
+extern int configuration_entry_add_mp_cache_entry(struct configuration_entry *,
+ cache_entry);
+extern cache_entry configuration_entry_find_mp_cache_entry(
+ struct configuration_entry *,
+ const char *);
+extern int configuration_entry_find_mp_cache_entries(
+ struct configuration_entry *, const char *, cache_entry **,
+ cache_entry **);
extern void configuration_lock_rdlock(struct configuration *config);
extern void configuration_lock_wrlock(struct configuration *config);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#11 (text+ko) ====
@@ -145,7 +145,9 @@
hashtable_index_t name##_CALCULATE_HASH(struct name *, type *); \
void name##_ENTRY_STORE(struct entry_*, type *); \
type *name##_ENTRY_FIND(struct entry_*, type *); \
-void name##_ENTRY_REMOVE(struct entry_*, type *); \
+type *name##_ENTRY_FIND_SPECIAL(struct entry_ *, type *, \
+ int (*) (const void *, const void *)); \
+void name##_ENTRY_REMOVE(struct entry_*, type *);
/*
* Generates implementations of the hash table functions
@@ -177,6 +179,13 @@
the_entry->field.size, sizeof(type), CMP)); \
} \
\
+type *name##_ENTRY_FIND_SPECIAL(struct entry_ *the_entry, type *key, \
+ int (*compar) (const void *, const void *)) \
+{ \
+ return ((type *)bsearch(key, the_entry->field.values, \
+ the_entry->field.size, sizeof(type), compar)); \
+} \
+ \
void name##_ENTRY_REMOVE(struct entry_ *the_entry, type *del_elm) \
{ \
\
@@ -199,6 +208,9 @@
#define HASHTABLE_ENTRY_FIND(name, entry, key) \
(name##_ENTRY_FIND((entry), (key)))
+#define HASHTABLE_ENTRY_FIND_SPECIAL(name, entry, key, cmp) \
+ (name##_ENTRY_FIND_SPECIAL((entry), (key), (cmp)))
+
#define HASHTABLE_ENTRY_REMOVE(name, entry, del_elm) \
name##_ENTRY_REMOVE((entry), (del_elm))
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#11 (text+ko) ====
@@ -499,7 +499,7 @@
cache_entry register_new_mp_cache_entry(struct query_state *qstate,
const char *dec_cache_entry_name)
{
- cache_entry c_entry, *new_mp_entries, *old_mp_entries;
+ cache_entry c_entry;
char *en_bkp;
TRACE_IN(register_new_mp_cache_entry);
@@ -520,21 +520,9 @@
dec_cache_entry_name);
configuration_unlock(s_configuration);
- ++qstate->config_entry->mp_cache_entries_size;
- new_mp_entries = (cache_entry *)malloc(sizeof(cache_entry) *
- qstate->config_entry->mp_cache_entries_size);
- assert(new_mp_entries != NULL);
- new_mp_entries[0] = c_entry;
- if (qstate->config_entry->mp_cache_entries_size -1 > 0) {
- memcpy(new_mp_entries + 1,
- qstate->config_entry->mp_cache_entries,
- qstate->config_entry->mp_cache_entries_size - 1);
- }
-
- old_mp_entries = qstate->config_entry->mp_cache_entries;
- qstate->config_entry->mp_cache_entries = new_mp_entries;
- free(old_mp_entries);
-
+ configuration_entry_add_mp_cache_entry(qstate->config_entry,
+ c_entry);
+
configuration_unlock_entry(qstate->config_entry,
CELT_MULTIPART);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#11 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#11 (text+ko) ====
@@ -38,6 +38,7 @@
void
init_comm_element(struct comm_element *element, enum comm_element_t type)
{
+
TRACE_IN(init_comm_element);
memset(element, 0, sizeof(struct comm_element));
@@ -84,6 +85,8 @@
init_cache_mp_read_session_read_response(
&element->c_mp_rs_read_response);
break;
+ case CET_UNDEFINED:
+ break;
default:
LOG_ERR_2("init_comm_element", "invalid communication element");
TRACE_OUT(init_comm_element);
@@ -97,6 +100,7 @@
void
finalize_comm_element(struct comm_element *element)
{
+
TRACE_IN(finalize_comm_element);
switch (element->type) {
case CET_WRITE_REQUEST:
@@ -146,6 +150,8 @@
finalize_cache_mp_read_session_read_response(
&element->c_mp_rs_read_response);
break;
+ case CET_UNDEFINED:
+ break;
default:
break;
}
@@ -157,6 +163,7 @@
void
init_cache_write_request(struct cache_write_request *write_request)
{
+
TRACE_IN(init_cache_write_request);
memset(write_request, 0, sizeof(struct cache_write_request));
TRACE_OUT(init_cache_write_request);
@@ -165,6 +172,7 @@
void
finalize_cache_write_request(struct cache_write_request *write_request)
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list