Date: Fri, 2 Dec 2005 15:31:30 GMT From: soc-bushman <soc-bushman@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87650 for review Message-ID: <200512021531.jB2FVTKd061465@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87650 Change 87650 by soc-bushman@soc-bushman_stinger on 2005/12/02 15:30:40 some minor bugfixes in the daemon now user can't invalidate the cachename, that performs actual lookups some profiling and debugging was made - errors in addrinfo and ipnode marshalling/unmarshalling functions were fixed Affected files ... .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/Makefile#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#17 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.c#9 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.h#9 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/Makefile.inc#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.c#9 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.h#9 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.c#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.h#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.c#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.h#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.c#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.h#12 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.c#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.h#16 edit .. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/startup/cached#11 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getaddrinfo.c#6 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/name6.c#8 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nscache.c#8 edit .. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nsdispatch.c#13 edit Differences ... ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/Makefile#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#17 (text+ko) ==== @@ -8,9 +8,9 @@ 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} ${LIBUTIL} -LDADD+=${LIBM} ${LIBPTHREAD} ${LIBUTIL} +CFLAGS+= -DCONFIG_PATH="\"${PREFIX}/etc/cached.conf\"" -pthread -pg +DPADD+=${LIBM} ${LIBUTIL} +LDADD+=${LIBM} ${LIBUTIL} LDFLAGS+= -Xlinker --export-dynamic FILESGROUPS=STARTUP CONF ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.c#9 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agent.h#9 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/Makefile.inc#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.c#9 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/group.h#9 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.c#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/hosts.h#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.c#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/passwd.h#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.c#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/agents/services.h#12 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#16 (text+ko) ==== @@ -70,7 +70,7 @@ }; static struct timeval s_time; -static pthread_rwlock_t s_time_lock = PTHREAD_RWLOCK_INITIALIZER; +static pthread_rwlock_t s_time_lock; static pthread_t s_time_thread; static void accept_connection(struct kevent *, struct runtime_env *, @@ -117,6 +117,8 @@ int res; TRACE_IN(init_global_timer); + pthread_rwlock_init(&s_time_lock, NULL); + memset(&s_time, 0, sizeof(struct timeval)); res = pthread_create(&s_time_thread, NULL, get_time_thread, NULL); TRACE_OUT(init_global_timer); @@ -286,7 +288,7 @@ uid_t euid; gid_t egid; - + TRACE_IN(accept_connection); fd = accept(event_data->ident, NULL, NULL); if (fd == -1) { @@ -316,6 +318,8 @@ EV_SET(&eventlist[1], fd, EVFILT_READ, EV_ADD | EV_ONESHOT, NOTE_LOWAT, qstate->kevent_watermark, qstate); res = kevent(env->queue, eventlist, 2, NULL, 0, &timeout); + if (res < 0) + LOG_ERR_2("accept_connection", "kevent error"); TRACE_OUT(accept_connection); } @@ -516,8 +520,6 @@ struct query_state *qstate; TRACE_IN(process_timer_event); - LOG_MSG_2("process_timer_event", "timer event received - " - "abandoning request"); qstate = (struct query_state *)event_data->udata; destroy_query_state(qstate); close(event_data->ident); @@ -544,7 +546,7 @@ for (;;) { nevents = kevent(env->queue, NULL, 0, eventlist, eventlist_size, NULL); - + LOG_ERR_2("KEVENT", "KEVENT %d", nevents); /* * we can only receive 1 event on success */ @@ -556,13 +558,13 @@ for (i = 0; i < event_data->data; ++i) accept_connection(event_data, env, config); - EV_SET(eventlist, s_runtime_env->sockfd, - EVFILT_READ, EV_ADD | EV_ONESHOT, - 0, 0, 0); - memset(&timeout, 0, - sizeof(struct timespec)); - kevent(s_runtime_env->queue, eventlist, - 1, NULL, 0, &timeout); + EV_SET(eventlist, s_runtime_env->sockfd, + EVFILT_READ, EV_ADD | EV_ONESHOT, + 0, 0, 0); + memset(&timeout, 0, + sizeof(struct timespec)); + kevent(s_runtime_env->queue, eventlist, + 1, NULL, 0, &timeout); } else { switch (event_data->filter) { @@ -617,9 +619,15 @@ void get_time_func(struct timeval *time) { - pthread_rwlock_rdlock(&s_time_lock); + struct timespec res; +/* pthread_rwlock_rdlock(&s_time_lock); memcpy(time, &s_time, sizeof(struct timeval)); - pthread_rwlock_unlock(&s_time_lock); + pthread_rwlock_unlock(&s_time_lock);*/ + memset(&res, 0, sizeof(struct timespec)); + clock_gettime(CLOCK_UPTIME, &res); + + time->tv_sec = res.tv_sec; + time->tv_usec = 0; } /* @@ -745,12 +753,12 @@ memset(&connection_params, 0, sizeof(struct cached_connection_params)); connection_params.socket_path = DEFAULT_SOCKET_PATH; - connection = open_cached_connection(&connection_params); + 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, + result = cached_transform__(connection, user_config_entry_name, TT_USER); if (result != 0) LOG_MSG_1("main", @@ -766,7 +774,7 @@ errx(EXIT_FAILURE, "Only root can initiate " "global cache transformation."); - result = cached_transform(connection, + result = cached_transform__(connection, global_config_entry_name, TT_ALL); if (result != 0) LOG_MSG_1("main", @@ -778,7 +786,7 @@ "succeeded"); } - close_cached_connection(connection); + close_cached_connection__(connection); free(user_config_entry_name); free(global_config_entry_name); ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#16 (text+ko) ==== @@ -108,7 +108,6 @@ { struct configuration_entry *retval; size_t size; - pthread_mutexattr_t attr; int res; TRACE_IN(create_configuration_entry); @@ -117,54 +116,41 @@ assert(negative_params != NULL); assert(mp_params != NULL); - - res = pthread_mutexattr_init(&attr); - if (res != 0) { - TRACE_OUT(create_configuration_entry); - return (NULL); - } - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - retval = (struct configuration_entry *)malloc( sizeof(struct configuration_entry)); assert(retval != NULL); memset(retval, 0, sizeof(struct configuration_entry)); - res = pthread_mutex_init(&retval->positive_cache_lock, &attr); + res = pthread_mutex_init(&retval->positive_cache_lock, NULL); if (res != 0) { free(retval); - pthread_mutexattr_destroy(&attr); LOG_ERR_2("create_configuration_entry", "can't create positive cache lock"); TRACE_OUT(create_configuration_entry); return (NULL); } - res = pthread_mutex_init(&retval->negative_cache_lock, &attr); + res = pthread_mutex_init(&retval->negative_cache_lock, NULL); if (res != 0) { pthread_mutex_destroy(&retval->positive_cache_lock); free(retval); - pthread_mutexattr_destroy(&attr); LOG_ERR_2("create_configuration_entry", "can't create negative cache lock"); TRACE_OUT(create_configuration_entry); return (NULL); } - res = pthread_mutex_init(&retval->mp_cache_lock, &attr); + res = pthread_mutex_init(&retval->mp_cache_lock, NULL); if (res != 0) { pthread_mutex_destroy(&retval->positive_cache_lock); pthread_mutex_destroy(&retval->negative_cache_lock); free(retval); - pthread_mutexattr_destroy(&attr); LOG_ERR_2("create_configuration_entry", "can't create negative cache lock"); TRACE_OUT(create_configuration_entry); return (NULL); } - pthread_mutexattr_destroy(&attr); - memcpy(&retval->positive_cache_params, positive_params, sizeof(struct common_cache_entry_params)); memcpy(&retval->negative_cache_params, negative_params, ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#16 (text+ko) ==== @@ -30,8 +30,8 @@ #define TRACE_WANTED 32 -/*#ifndef NDEBUG*/ -#if 0 +#ifndef NDEBUG +//#if 0 #define TRACE_IN(x) __trace_in(#x, __FILE__, __LINE__) #define TRACE_POINT() __trace_point(__FILE__, __LINE__) #define TRACE_MSG(x) __trace_msg(x, __FILE__, __LINE__) ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#16 (text+ko) ==== @@ -304,6 +304,7 @@ qstate->process_func = on_mp_read_session_response_write1; qstate->kevent_watermark = sizeof(int); qstate->kevent_filter = EVFILT_WRITE; + TRACE_OUT(on_mp_read_session_request_process); return (0); } @@ -319,6 +320,7 @@ &qstate->response); result = qstate->write_func(qstate, &c_mp_rs_response->error_code, sizeof(int)); + if (result != sizeof(int)) { LOG_ERR_3("on_mp_read_session_response_write1", "write failed"); ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.c#16 (text+ko) ==== @@ -647,6 +647,7 @@ read_response = get_cache_read_response(&qstate->response); read_request = get_cache_read_request(&qstate->request); + LOG_ERR_2("READ","READ %s", read_request->entry); qstate->config_entry = configuration_find_entry( s_configuration, read_request->entry); if (qstate->config_entry == NULL) { @@ -939,6 +940,7 @@ { struct cache_transform_request *transform_request; struct cache_transform_response *transform_response; + struct configuration_entry *config_entry; size_t i, size; TRACE_IN(on_transform_request_process); @@ -948,12 +950,15 @@ switch (transform_request->transformation_type) { case TT_USER: - if (transform_request->entry == NULL) { + if (transform_request->entry == NULL) { size = configuration_get_entries_size(s_configuration); - for (i = 0; i < size; ++i) { - clear_config_entry_part(configuration_get_entry( - s_configuration, i), qstate->eid_str, - qstate->eid_str_length); + for (i = 0; i < size; ++i) { + config_entry = configuration_get_entry( + s_configuration, i); + + if (config_entry->perform_actual_lookups == 0) + clear_config_entry_part(config_entry, + qstate->eid_str, qstate->eid_str_length); } } else { qstate->config_entry = configuration_find_entry( @@ -968,6 +973,15 @@ goto fin; } + if (qstate->config_entry->perform_actual_lookups != 0) { + LOG_ERR_2("transform_request", + "can't transform the cache entry %s" + ", because it ised for actual lookups", + transform_request->entry); + transform_response->error_code = -1; + goto fin; + } + clear_config_entry_part(qstate->config_entry, qstate->eid_str, qstate->eid_str_length); } @@ -1122,7 +1136,7 @@ return (-1); } - result = recv(qstate->sockfd, buf, nbytes, 0); + result = read(qstate->sockfd, buf, nbytes); if ((result == -1) || (result < nbytes)) qstate->socket_failed = 1; @@ -1144,7 +1158,7 @@ return (-1); } - result = send(qstate->sockfd, buf, nbytes, 0); + result = write(qstate->sockfd, buf, nbytes); if ((result == -1) || (result < nbytes)) qstate->socket_failed = 1; ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.c#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.h#16 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/startup/cached#11 (text+ko) ==== ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getaddrinfo.c#6 (text+ko) ==== @@ -1637,10 +1637,9 @@ desired_size = sizeof(size_t); ai_size = 0; for (cai = ai; cai != NULL; cai = cai->ai_next) { - desired_size = sizeof(struct addrinfo) + cai->ai_addrlen + - sizeof(size_t); + desired_size += sizeof(struct addrinfo) + cai->ai_addrlen; if (cai->ai_canonname != NULL) - desired_size += strlen(cai->ai_canonname) + 1; + desired_size += strlen(cai->ai_canonname); ++ai_size; } @@ -1670,9 +1669,6 @@ memcpy(p, cai->ai_canonname, size); p += size + 1; - } else { - memset(p, 0, sizeof(size_t)); - p += sizeof(size_t); } } @@ -1697,20 +1693,23 @@ for (ai_i = 0; ai_i < ai_size; ++ai_i) { memcpy(&new_ai, p, sizeof(struct addrinfo)); p += sizeof(struct addrinfo); - size = new_ai.ai_addrlen + sizeof(struct addrinfo) + _ALIGNBYTES; + size = new_ai.ai_addrlen + sizeof(struct addrinfo) + + _ALIGNBYTES; sentinel = (struct addrinfo *)malloc(size); memset(sentinel, 0, size); memcpy(sentinel, &new_ai, sizeof(struct addrinfo)); - sentinel->ai_addr = (struct sockaddr *)_ALIGN(sentinel + + sentinel->ai_addr = (struct sockaddr *)_ALIGN((char *)sentinel + sizeof(struct addrinfo)); + memcpy(sentinel->ai_addr, p, new_ai.ai_addrlen); p += new_ai.ai_addrlen; - memcpy(&size, p, sizeof(size_t)); - p += sizeof(size_t); - if (size > 0) { + if (new_ai.ai_canonname != NULL) { + memcpy(&size, p, sizeof(size_t)); + p += sizeof(size_t); + sentinel->ai_canonname = (char *)malloc(size + 1); memset(sentinel->ai_canonname, 0, size + 1); ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/name6.c#8 (text+ko) ==== @@ -469,17 +469,13 @@ int err; ht = &new_ht; - orig_buf = buffer; memcpy(ht, buffer, sizeof(struct hostent)); memcpy(&p, buffer + sizeof(struct hostent), sizeof(char *)); - orig_buf = (char *)_ALIGN(orig_buf); - memcpy(orig_buf, buffer + sizeof(struct hostent) + sizeof(char *) + - _ALIGN(p) - (size_t)p, - buffer_size - sizeof(struct hostent) - sizeof(char *) - - _ALIGN(p) + (size_t)p); - p = (char *)_ALIGN(p); + orig_buf = buffer + sizeof(struct hostent) + sizeof(char *) + + _ALIGN(p) - (size_t)p; + p = (char *)_ALIGN(p); NS_APPLY_OFFSET(ht->h_name, orig_buf, p, char *); ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nscache.c#8 (text+ko) ==== @@ -314,6 +314,7 @@ } else res = 0; } else { + free(buffer); close_cached_mp_read_session(rs); rs = INVALID_CACHED_MP_READ_SESSION; cache_info->set_mp_rs_func(rs); ==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nsdispatch.c#13 (text+ko) ==== @@ -684,7 +684,7 @@ #ifdef NS_CACHING if ((cache_data_p != NULL) && - (result & NS_NOTFOUND) && (cache_flag == 0)) { + (result & (NS_NOTFOUND | NS_SUCCESS)) && (cache_flag == 0)) { va_start(ap, defaults); if (result == NS_SUCCESS) { if (cache_data.info->id_func != NULL)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200512021531.jB2FVTKd061465>
