From 44c5d6f3a0239ec1ab0fd3c98ba2141942488bdc Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 9 Jul 2003 10:10:11 +0000 Subject: [PATCH] Fix cached_path to be local to jcr + fixed idcache git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@629 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/bacula.h | 1 + bacula/src/findlib/create_file.c | 28 ++-- bacula/src/jcr.h | 2 + bacula/src/lib/idcache.c | 197 ++++++++------------------ bacula/src/lib/jcr.c | 7 + bacula/src/lib/protos.h | 233 ++++++++++++++++--------------- bacula/src/version.h | 4 +- 7 files changed, 200 insertions(+), 272 deletions(-) diff --git a/bacula/src/bacula.h b/bacula/src/bacula.h index ba6c5a2620..6814485c05 100644 --- a/bacula/src/bacula.h +++ b/bacula/src/bacula.h @@ -72,6 +72,7 @@ #include #endif #include +#include #include #include #include diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index c947cecf1c..2900f998d9 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -39,7 +39,7 @@ #endif static int separate_path_and_file(JCR *jcr, char *fname, char *ofile); -static int path_already_seen(char *path, int pnl); +static int path_already_seen(JCR *jcr, char *path, int pnl); /* @@ -144,7 +144,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) savechr = attr->ofname[pnl]; attr->ofname[pnl] = 0; /* terminate path */ - if (!path_already_seen(attr->ofname, pnl)) { + if (!path_already_seen(jcr, attr->ofname, pnl)) { Dmsg1(50, "Make path %s\n", attr->ofname); /* * If we need to make the directory, ensure that it is with @@ -171,9 +171,8 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) } Dmsg1(50, "Create file: %s\n", attr->ofname); if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) { - Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: %d ERR=%s\n"), + Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, berror(bfd)); - return CF_ERROR; } return CF_EXTRACT; @@ -310,26 +309,19 @@ static int separate_path_and_file(JCR *jcr, char *fname, char *ofile) return pnl; } -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - /* * Primitive caching of path to prevent recreating a pathname * each time as long as we remain in the same directory. */ -static int path_already_seen(char *path, int pnl) +static int path_already_seen(JCR *jcr, char *path, int pnl) { - static int cached_pnl = 0; - static char cached_path[1000]; - - P(mutex); - if (cached_pnl == pnl && strcmp(path, cached_path) == 0) { - V(mutex); - return 1; + if (!jcr->cached_path) { + jcr->cached_path = get_pool_memory(PM_FNAME); } - if (pnl < (int)(sizeof(cached_path)-1)) { - strcpy(cached_path, path); - cached_pnl = pnl; + if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) { + return 1; } - V(mutex); + pm_strcpy(&jcr->cached_path, path); + jcr->cached_pnl = pnl; return 0; } diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index e8b293d1ed..4e8159172a 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -119,6 +119,8 @@ struct JCR { uint32_t ClientId; /* Client associated with Job */ char *where; /* prefix to restore files to */ int prefix_links; /* Prefix links with Where path */ + int cached_pnl; /* cached path length */ + POOLMEM *cached_path; /* cached path */ /* Daemon specific part of JCR */ /* This should be empty in the library */ diff --git a/bacula/src/lib/idcache.c b/bacula/src/lib/idcache.c index 749343579d..96f253bd10 100644 --- a/bacula/src/lib/idcache.c +++ b/bacula/src/lib/idcache.c @@ -15,197 +15,116 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NEEDED 1 -#ifdef NEEDED - -#include - -#include -#include -#include -#include -#include - -#if defined(STDC_HEADERS) || defined(HAVE_STRING_H) -#include -#else -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifndef _POSIX_VERSION -struct passwd *getpwuid (); -struct passwd *getpwnam (); -struct group *getgrgid (); -struct group *getgrnam (); -#endif - -#define xstrdup strdup -#define xmalloc malloc -//char *xmalloc (); -//char *xstrdup (); - -struct userid -{ - union - { +#include "bacula.h" + +struct userid { + union { uid_t u; gid_t g; - } id; + } id; char *name; struct userid *next; }; -static struct userid *user_alist; - - +static struct userid *user_alist = NULL; +/* Use the same struct as for userids. */ +static struct userid *group_alist = NULL; -/* The members of this list have names not in the local passwd file. */ -static struct userid *nouser_alist; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* Translate UID to a login name or a stringified number, with cache. */ -char *getuser (uid_t uid) +char *getuser(uid_t uid) { register struct userid *tail; struct passwd *pwent; char usernum_string[20]; - for (tail = user_alist; tail; tail = tail->next) - if (tail->id.u == uid) + P(mutex); + for (tail = user_alist; tail; tail = tail->next) { + if (tail->id.u == uid) { + V(mutex); return tail->name; + } + } - pwent = getpwuid (uid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); + pwent = getpwuid(uid); + tail = (struct userid *)malloc(sizeof (struct userid)); tail->id.u = uid; - if (pwent == 0) { - sprintf (usernum_string, "%u", (unsigned) uid); - tail->name = xstrdup (usernum_string); + if (pwent == 0 || strcmp(pwent->pw_name, "????????") == 0) { + sprintf(usernum_string, "%u", (uint32_t)uid); + tail->name = bstrdup(usernum_string); } else { - tail->name = xstrdup (pwent->pw_name); + tail->name = bstrdup(pwent->pw_name); } /* Add to the head of the list, so most recently used is first. */ tail->next = user_alist; user_alist = tail; + V(mutex); return tail->name; } -/* Translate USER to a UID, with cache. - Return NULL if there is no such user. - (We also cache which user names have no passwd entry, - so we don't keep looking them up.) */ - -uid_t * -getuidbyname (char *user) +void free_getuser_cache() { register struct userid *tail; - struct passwd *pwent; - for (tail = user_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return &tail->id.u; - - for (tail = nouser_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *user && !strcmp (tail->name, user)) - return 0; - - pwent = getpwnam (user); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (user); - - /* Add to the head of the list, so most recently used is first. */ - if (pwent) - { - tail->id.u = pwent->pw_uid; - tail->next = user_alist; - user_alist = tail; - return &tail->id.u; - } - - tail->next = nouser_alist; - nouser_alist = tail; - return 0; + P(mutex); + for (tail = user_alist; tail; ) { + struct userid *otail = tail; + free(tail->name); + tail = tail->next; + free(otail); + } + V(mutex); } -/* Use the same struct as for userids. */ -static struct userid *group_alist; -static struct userid *nogroup_alist; + /* Translate GID to a group name or a stringified number, with cache. */ - -char * -getgroup (gid_t gid) +char *getgroup(gid_t gid) { register struct userid *tail; struct group *grent; char groupnum_string[20]; - for (tail = group_alist; tail; tail = tail->next) - if (tail->id.g == gid) + P(mutex); + for (tail = group_alist; tail; tail = tail->next) { + if (tail->id.g == gid) { + V(mutex); return tail->name; + } + } - grent = getgrgid (gid); - tail = (struct userid *) xmalloc (sizeof (struct userid)); + grent = getgrgid(gid); + tail = (struct userid *)malloc(sizeof (struct userid)); tail->id.g = gid; - if (grent == 0) - { - sprintf (groupnum_string, "%u", (unsigned int) gid); - tail->name = xstrdup (groupnum_string); - } - else - tail->name = xstrdup (grent->gr_name); + if (grent == 0 || strcmp(grent->gr_name, "????????") == 0) { + sprintf (groupnum_string, "%u", (uint32_t)gid); + tail->name = bstrdup(groupnum_string); + } else { + tail->name = bstrdup(grent->gr_name); + } /* Add to the head of the list, so most recently used is first. */ tail->next = group_alist; group_alist = tail; + V(mutex); return tail->name; } -/* Translate GROUP to a UID, with cache. - Return NULL if there is no such group. - (We also cache which group names have no group entry, - so we don't keep looking them up.) */ - -gid_t * -getgidbyname (char *group) +void free_getgroup_cache() { register struct userid *tail; - struct group *grent; - for (tail = group_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return &tail->id.g; - - for (tail = nogroup_alist; tail; tail = tail->next) - /* Avoid a function call for the most common case. */ - if (*tail->name == *group && !strcmp (tail->name, group)) - return 0; - - grent = getgrnam (group); - - tail = (struct userid *) xmalloc (sizeof (struct userid)); - tail->name = xstrdup (group); - - /* Add to the head of the list, so most recently used is first. */ - if (grent) - { - tail->id.g = grent->gr_gid; - tail->next = group_alist; - group_alist = tail; - return &tail->id.g; - } - - tail->next = nogroup_alist; - nogroup_alist = tail; - return 0; + P(mutex); + for (tail = group_alist; tail; ) { + struct userid *otail = tail; + free(tail->name); + tail = tail->next; + free(otail); + } + V(mutex); } -#endif diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 5e84ab179b..ece158bd71 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -160,6 +160,13 @@ static void free_common_jcr(JCR *jcr) free(jcr->where); jcr->where = NULL; } + if (jcr->cached_path) { + free_pool_memory(jcr->cached_path); + jcr->cached_path = NULL; + jcr->cached_pnl = 0; + } + free_getuser_cache(); + free_getgroup_cache(); free(jcr); } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 130656d3d1..f65a361b9f 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -26,159 +26,166 @@ struct JCR; /* attr.c */ -ATTR *new_attr(); -void free_attr(ATTR *attr); -int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr); -void build_attr_output_fnames(JCR *jcr, ATTR *attr); -void print_ls_output(JCR *jcr, ATTR *attr); +ATTR *new_attr(); +void free_attr(ATTR *attr); +int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr); +void build_attr_output_fnames(JCR *jcr, ATTR *attr); +void print_ls_output(JCR *jcr, ATTR *attr); /* base64.c */ -void base64_init (void); -int to_base64 (intmax_t value, char *where); -int from_base64 (intmax_t *value, char *where); -int bin_to_base64 (char *buf, char *bin, int len); +void base64_init (void); +int to_base64 (intmax_t value, char *where); +int from_base64 (intmax_t *value, char *where); +int bin_to_base64 (char *buf, char *bin, int len); /* bsys.c */ -char *bstrncpy (char *dest, const char *src, int maxlen); -char *bstrncat (char *dest, const char *src, int maxlen); -void *b_malloc (char *file, int line, size_t size); +char *bstrncpy (char *dest, const char *src, int maxlen); +char *bstrncat (char *dest, const char *src, int maxlen); +void *b_malloc (char *file, int line, size_t size); #ifndef DEBUG -void *bmalloc (size_t size); +void *bmalloc (size_t size); #endif -void *brealloc (void *buf, size_t size); -void *bcalloc (size_t size1, size_t size2); -int bsnprintf (char *str, size_t size, const char *format, ...); -int bvsnprintf (char *str, size_t size, const char *format, va_list ap); -int pool_sprintf (char *pool_buf, char *fmt, ...); -void create_pid_file (char *dir, char *progname, int port); -int delete_pid_file (char *dir, char *progname, int port); -void drop (char *uid, char *gid); -int bmicrosleep (time_t sec, long msec); -char *bfgets (char *s, int size, FILE *fd); +void *brealloc (void *buf, size_t size); +void *bcalloc (size_t size1, size_t size2); +int bsnprintf (char *str, size_t size, const char *format, ...); +int bvsnprintf (char *str, size_t size, const char *format, va_list ap); +int pool_sprintf (char *pool_buf, char *fmt, ...); +void create_pid_file (char *dir, char *progname, int port); +int delete_pid_file (char *dir, char *progname, int port); +void drop (char *uid, char *gid); +int bmicrosleep (time_t sec, long msec); +char *bfgets (char *s, int size, FILE *fd); #ifndef HAVE_STRTOLL -long long int strtoll (const char *ptr, char **endptr, int base); +long long int strtoll (const char *ptr, char **endptr, int base); #endif /* bnet.c */ -int32_t bnet_recv (BSOCK *bsock); -int bnet_send (BSOCK *bsock); -int bnet_fsend (BSOCK *bs, char *fmt, ...); -int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); -int bnet_sig (BSOCK *bs, int sig); -int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has); -int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need); -BSOCK * bnet_connect (JCR *jcr, int retry_interval, - int max_retry_time, char *name, char *host, char *service, - int port, int verbose); -void bnet_close (BSOCK *bsock); -BSOCK * init_bsock (JCR *jcr, int sockfd, char *who, char *ip, int port); -BSOCK * dup_bsock (BSOCK *bsock); -void term_bsock (BSOCK *bsock); -char * bnet_strerror (BSOCK *bsock); -char * bnet_sig_to_ascii (BSOCK *bsock); -int bnet_wait_data (BSOCK *bsock, int sec); -int bnet_wait_data_intr (BSOCK *bsock, int sec); -int bnet_despool (BSOCK *bsock); -int is_bnet_stop (BSOCK *bsock); -int is_bnet_error (BSOCK *bsock); -void bnet_suppress_error_messages(BSOCK *bsock, int flag); +int32_t bnet_recv (BSOCK *bsock); +int bnet_send (BSOCK *bsock); +int bnet_fsend (BSOCK *bs, char *fmt, ...); +int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); +int bnet_sig (BSOCK *bs, int sig); +int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has); +int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need); +BSOCK * bnet_connect (JCR *jcr, int retry_interval, + int max_retry_time, char *name, char *host, char *service, + int port, int verbose); +void bnet_close (BSOCK *bsock); +BSOCK * init_bsock (JCR *jcr, int sockfd, char *who, char *ip, int port); +BSOCK * dup_bsock (BSOCK *bsock); +void term_bsock (BSOCK *bsock); +char * bnet_strerror (BSOCK *bsock); +char * bnet_sig_to_ascii (BSOCK *bsock); +int bnet_wait_data (BSOCK *bsock, int sec); +int bnet_wait_data_intr (BSOCK *bsock, int sec); +int bnet_despool (BSOCK *bsock); +int is_bnet_stop (BSOCK *bsock); +int is_bnet_error (BSOCK *bsock); +void bnet_suppress_error_messages(BSOCK *bsock, int flag); /* bget_msg.c */ -int bget_msg(BSOCK *sock); +int bget_msg(BSOCK *sock); /* bpipe.c */ -BPIPE * open_bpipe(char *prog, int wait, char *mode); -int close_wpipe(BPIPE *bpipe); -int close_bpipe(BPIPE *bpipe); +BPIPE * open_bpipe(char *prog, int wait, char *mode); +int close_wpipe(BPIPE *bpipe); +int close_bpipe(BPIPE *bpipe); /* cram-md5.c */ int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need); int cram_md5_auth(BSOCK *bs, char *password, int ssl_need); void hmac_md5(uint8_t* text, int text_len, uint8_t* key, - int key_len, uint8_t *hmac); + int key_len, uint8_t *hmac); /* crc32.c */ uint32_t bcrc32(uint8_t *buf, int len); /* daemon.c */ -void daemon_start (); +void daemon_start (); /* edit.c */ -uint64_t str_to_uint64(char *str); -int64_t str_to_int64(char *str); -char * edit_uint64_with_commas (uint64_t val, char *buf); -char * add_commas (char *val, char *buf); -char * edit_uint64 (uint64_t val, char *buf); -int duration_to_utime (char *str, utime_t *value); -int size_to_uint64(char *str, int str_len, uint64_t *rtn_value); -char *edit_utime (utime_t val, char *buf); -int is_a_number (const char *num); -int is_an_integer (const char *n); +uint64_t str_to_uint64(char *str); +int64_t str_to_int64(char *str); +char * edit_uint64_with_commas (uint64_t val, char *buf); +char * add_commas (char *val, char *buf); +char * edit_uint64 (uint64_t val, char *buf); +int duration_to_utime (char *str, utime_t *value); +int size_to_uint64(char *str, int str_len, uint64_t *rtn_value); +char *edit_utime (utime_t val, char *buf); +int is_a_number (const char *num); +int is_an_integer (const char *n); /* lex.c */ -LEX * lex_close_file (LEX *lf); -LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error); -int lex_get_char (LEX *lf); -void lex_unget_char (LEX *lf); -char * lex_tok_to_str (int token); -int lex_get_token (LEX *lf, int expect); +LEX * lex_close_file (LEX *lf); +LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error); +int lex_get_char (LEX *lf); +void lex_unget_char (LEX *lf); +char * lex_tok_to_str (int token); +int lex_get_token (LEX *lf, int expect); /* message.c */ -void my_name_is (int argc, char *argv[], char *name); -void init_msg (JCR *jcr, MSGS *msg); -void term_msg (void); -void close_msg (JCR *jcr); -void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code); -void rem_msg_dest (MSGS *msg, int dest, int type, char *where); -void Jmsg (JCR *jcr, int type, int level, char *fmt, ...); -void dispatch_message (JCR *jcr, int type, int level, char *buf); -void init_console_msg (char *wd); -void free_msgs_res (MSGS *msgs); -int open_spool_file (JCR *jcr, BSOCK *bs); -int close_spool_file (JCR *jcr, BSOCK *bs); +void my_name_is (int argc, char *argv[], char *name); +void init_msg (JCR *jcr, MSGS *msg); +void term_msg (void); +void close_msg (JCR *jcr); +void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code); +void rem_msg_dest (MSGS *msg, int dest, int type, char *where); +void Jmsg (JCR *jcr, int type, int level, char *fmt, ...); +void dispatch_message (JCR *jcr, int type, int level, char *buf); +void init_console_msg (char *wd); +void free_msgs_res (MSGS *msgs); +int open_spool_file (JCR *jcr, BSOCK *bs); +int close_spool_file (JCR *jcr, BSOCK *bs); /* bnet_server.c */ -void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, - void *handle_client_request(void *bsock)); -void bnet_server (int port, void handle_client_request(BSOCK *bsock)); -int net_connect (int port); -BSOCK * bnet_bind (int port); -BSOCK * bnet_accept (BSOCK *bsock, char *who); +void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq, + void *handle_client_request(void *bsock)); +void bnet_server (int port, void handle_client_request(BSOCK *bsock)); +int net_connect (int port); +BSOCK * bnet_bind (int port); +BSOCK * bnet_accept (BSOCK *bsock, char *who); + +/* idcache.c */ +char *getuser(uid_t uid); +void free_getuser_cache(); +char *getgroup (gid_t gid); +void free_getgroup_cache(); + /* signal.c */ -void init_signals (void terminate(int sig)); -void init_stack_dump (void); +void init_signals (void terminate(int sig)); +void init_stack_dump (void); /* scan.c */ -void strip_trailing_junk (char *str); -void strip_trailing_slashes (char *dir); -int skip_spaces (char **msg); -int skip_nonspaces (char **msg); -int fstrsch (char *a, char *b); -int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, - char **argk, char **argv, int max_args); -char *next_arg(char **s); +void strip_trailing_junk (char *str); +void strip_trailing_slashes (char *dir); +int skip_spaces (char **msg); +int skip_nonspaces (char **msg); +int fstrsch (char *a, char *b); +int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, + char **argk, char **argv, int max_args); +char *next_arg(char **s); /* util.c */ -int is_buf_zero (char *buf, int len); -void lcase (char *str); -void bash_spaces (char *str); -void unbash_spaces (char *str); -char * encode_time (time_t time, char *buf); -char * encode_mode (mode_t mode, char *buf); -int do_shell_expansion (char *name, int name_len); -void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); -void pm_strcat (POOLMEM **pm, char *str); -void pm_strcpy (POOLMEM **pm, char *str); -int run_program (char *prog, int wait, POOLMEM *results); -char * job_type_to_str (int type); -char * job_status_to_str (int stat); -char * job_level_to_str (int level); -void make_session_key (char *key, char *seed, int mode); -POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to); -void set_working_directory(char *wd); +int is_buf_zero (char *buf, int len); +void lcase (char *str); +void bash_spaces (char *str); +void unbash_spaces (char *str); +char * encode_time (time_t time, char *buf); +char * encode_mode (mode_t mode, char *buf); +int do_shell_expansion (char *name, int name_len); +void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen); +void pm_strcat (POOLMEM **pm, char *str); +void pm_strcpy (POOLMEM **pm, char *str); +int run_program (char *prog, int wait, POOLMEM *results); +char * job_type_to_str (int type); +char * job_status_to_str (int stat); +char * job_level_to_str (int level); +void make_session_key (char *key, char *seed, int mode); +POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to); +void set_working_directory(char *wd); /* watchdog.c */ diff --git a/bacula/src/version.h b/bacula/src/version.h index fdd19be1f9..344dc34f64 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.31" #define VSTRING "1" -#define BDATE "07 Jul 2003" -#define LSMDATE "07Jul03" +#define BDATE "08 Jul 2003" +#define LSMDATE "08Jul03" /* Debug flags */ #define DEBUG 1 -- 2.39.5