Lock around access to nc_file and netconfig_info ("ni"). The RPC
part of libc is still not thread safe but this would at least reduce the problems we have. PR: threads/118544 Submitted by: Changming Sun <snnn119 gmail com> MFC after: 2 weeks
This commit is contained in:
parent
2245fa69bb
commit
5f4faf74cb
@ -130,7 +130,11 @@ static struct netconfig *dup_ncp(struct netconfig *);
|
||||
|
||||
|
||||
static FILE *nc_file; /* for netconfig db */
|
||||
static pthread_mutex_t nc_file_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static struct netconfig_info ni = { 0, 0, NULL, NULL};
|
||||
static pthread_mutex_t ni_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
#define MAXNETCONFIGLINE 1000
|
||||
|
||||
@ -204,14 +208,24 @@ setnetconfig()
|
||||
* For multiple calls, i.e. nc_file is not NULL, we just return the
|
||||
* handle without reopening the netconfig db.
|
||||
*/
|
||||
mutex_lock(&ni_lock);
|
||||
ni.ref++;
|
||||
mutex_unlock(&ni_lock);
|
||||
|
||||
mutex_lock(&nc_file_lock);
|
||||
if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) {
|
||||
nc_vars->valid = NC_VALID;
|
||||
nc_vars->flag = 0;
|
||||
nc_vars->nc_configs = ni.head;
|
||||
mutex_unlock(&nc_file_lock);
|
||||
return ((void *)nc_vars);
|
||||
}
|
||||
mutex_unlock(&nc_file_lock);
|
||||
|
||||
mutex_lock(&ni_lock);
|
||||
ni.ref--;
|
||||
mutex_unlock(&ni_lock);
|
||||
|
||||
nc_error = NC_NONETCONFIG;
|
||||
free(nc_vars);
|
||||
return (NULL);
|
||||
@ -234,14 +248,18 @@ void *handlep;
|
||||
char *stringp; /* tmp string pointer */
|
||||
struct netconfig_list *list;
|
||||
struct netconfig *np;
|
||||
struct netconfig *result;
|
||||
|
||||
/*
|
||||
* Verify that handle is valid
|
||||
*/
|
||||
mutex_lock(&nc_file_lock);
|
||||
if (ncp == NULL || nc_file == NULL) {
|
||||
nc_error = NC_NOTINIT;
|
||||
mutex_unlock(&nc_file_lock);
|
||||
return (NULL);
|
||||
}
|
||||
mutex_unlock(&nc_file_lock);
|
||||
|
||||
switch (ncp->valid) {
|
||||
case NC_VALID:
|
||||
@ -255,7 +273,9 @@ void *handlep;
|
||||
*/
|
||||
if (ncp->flag == 0) { /* first time */
|
||||
ncp->flag = 1;
|
||||
mutex_lock(&ni_lock);
|
||||
ncp->nc_configs = ni.head;
|
||||
mutex_unlock(&ni_lock);
|
||||
if (ncp->nc_configs != NULL) /* entry already exist */
|
||||
return(ncp->nc_configs->ncp);
|
||||
}
|
||||
@ -268,7 +288,13 @@ void *handlep;
|
||||
* If we cannot find the entry in the list and is end of file,
|
||||
* we give up.
|
||||
*/
|
||||
if (ni.eof == 1) return(NULL);
|
||||
mutex_lock(&ni_lock);
|
||||
if (ni.eof == 1) {
|
||||
mutex_unlock(&ni_lock);
|
||||
return(NULL);
|
||||
}
|
||||
mutex_unlock(&ni_lock);
|
||||
|
||||
break;
|
||||
default:
|
||||
nc_error = NC_NOTINIT;
|
||||
@ -289,13 +315,18 @@ void *handlep;
|
||||
/*
|
||||
* Read a line from netconfig file.
|
||||
*/
|
||||
mutex_lock(&nc_file_lock);
|
||||
do {
|
||||
if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) {
|
||||
free(stringp);
|
||||
mutex_lock(&ni_lock);
|
||||
ni.eof = 1;
|
||||
mutex_unlock(&ni_lock);
|
||||
mutex_unlock(&nc_file_lock);
|
||||
return (NULL);
|
||||
}
|
||||
} while (*stringp == '#');
|
||||
mutex_unlock(&nc_file_lock);
|
||||
|
||||
list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list));
|
||||
if (list == NULL) {
|
||||
@ -325,6 +356,7 @@ void *handlep;
|
||||
* Reposition the current pointer of the handle to the last entry
|
||||
* in the list.
|
||||
*/
|
||||
mutex_lock(&ni_lock);
|
||||
if (ni.head == NULL) { /* first entry */
|
||||
ni.head = ni.tail = list;
|
||||
}
|
||||
@ -333,7 +365,9 @@ void *handlep;
|
||||
ni.tail = ni.tail->next;
|
||||
}
|
||||
ncp->nc_configs = ni.tail;
|
||||
return(ni.tail->ncp);
|
||||
result = ni.tail->ncp;
|
||||
mutex_unlock(&ni_lock);
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,7 +401,9 @@ void *handlep;
|
||||
nc_handlep->valid = NC_INVALID;
|
||||
nc_handlep->flag = 0;
|
||||
nc_handlep->nc_configs = NULL;
|
||||
mutex_lock(&ni_lock);
|
||||
if (--ni.ref > 0) {
|
||||
mutex_unlock(&ni_lock);
|
||||
free(nc_handlep);
|
||||
return(0);
|
||||
}
|
||||
@ -380,6 +416,8 @@ void *handlep;
|
||||
ni.eof = ni.ref = 0;
|
||||
ni.head = NULL;
|
||||
ni.tail = NULL;
|
||||
mutex_unlock(&ni_lock);
|
||||
|
||||
while (q) {
|
||||
p = q->next;
|
||||
if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups);
|
||||
@ -390,8 +428,11 @@ void *handlep;
|
||||
}
|
||||
free(nc_handlep);
|
||||
|
||||
mutex_lock(&nc_file_lock);
|
||||
fclose(nc_file);
|
||||
nc_file = NULL;
|
||||
mutex_unlock(&nc_file_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -427,15 +468,20 @@ getnetconfigent(netid)
|
||||
* If all the netconfig db has been read and placed into the list and
|
||||
* there is no match for the netid, return NULL.
|
||||
*/
|
||||
mutex_lock(&ni_lock);
|
||||
if (ni.head != NULL) {
|
||||
for (list = ni.head; list; list = list->next) {
|
||||
if (strcmp(list->ncp->nc_netid, netid) == 0) {
|
||||
mutex_unlock(&ni_lock);
|
||||
return(dup_ncp(list->ncp));
|
||||
}
|
||||
}
|
||||
if (ni.eof == 1) /* that's all the entries */
|
||||
if (ni.eof == 1) { /* that's all the entries */
|
||||
mutex_unlock(&ni_lock);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ni_lock);
|
||||
|
||||
|
||||
if ((file = fopen(NETCONFIG, "r")) == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user