forked from phdeniel/nfs-ganesha
-
Notifications
You must be signed in to change notification settings - Fork 1
/
nfs_reaper_thread.c
116 lines (100 loc) · 4.08 KB
/
nfs_reaper_thread.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* ---------------------------------------
*/
/**
* nfs_reaper_thread.c : check for expired clients and whack them.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _SOLARIS
#include "solaris_port.h"
#endif
#include <pthread.h>
#include <unistd.h>
#include "log.h"
#include "stuff_alloc.h"
#include "nfs4.h"
#include "sal_functions.h"
#include "nfs_proto_functions.h"
#include "nfs_core.h"
#include "log.h"
unsigned int reaper_delay = 10;
void *reaper_thread(void *unused)
{
hash_table_t *ht = ht_client_id;
struct rbt_head *head_rbt;
hash_data_t *pdata = NULL;
int i, v4;
struct rbt_node *pn;
nfs_client_id_t *clientp;
#ifndef _NO_BUDDY_SYSTEM
if((i = BuddyInit(&nfs_param.buddy_param_admin)) != BUDDY_SUCCESS) {
/* Failed init */
LogFatal(COMPONENT_MAIN,
"Memory manager could not be initialized");
}
LogInfo(COMPONENT_MAIN, "Memory manager successfully initialized");
#endif
SetNameFunction("reaper_thr");
while(1) {
/* Initial wait */
/* TODO: should this be configurable? */
/* sleep(nfs_param.core_param.reaper_delay); */
sleep(reaper_delay);
LogFullDebug(COMPONENT_MAIN,
"NFS reaper : now checking clients");
/* For each bucket of the hashtable */
for(i = 0; i < ht->parameter.index_size; i++) {
head_rbt = &(ht->array_rbt[i]);
restart:
/* acquire mutex */
P_w(&(ht->array_lock[i]));
/* go through all entries in the red-black-tree*/
RBT_LOOP(head_rbt, pn) {
pdata = RBT_OPAQ(pn);
clientp =
(nfs_client_id_t *)pdata->buffval.pdata;
/*
* little hack: only want to reap v4 clients
* 4.1 initializess this field to '1'
*/
v4 = (clientp->create_session_sequence == 0);
if (clientp->confirmed != EXPIRED_CLIENT_ID &&
nfs4_is_lease_expired(clientp) && v4) {
V_w(&(ht->array_lock[i]));
LogDebug(COMPONENT_MAIN,
"NFS reaper: expire client %s",
clientp->client_name);
nfs_client_id_expire(clientp);
goto restart;
}
if (clientp->confirmed == EXPIRED_CLIENT_ID) {
LogDebug(COMPONENT_MAIN,
"reaper: client %s already expired",
clientp->client_name);
}
RBT_INCREMENT(pn);
}
V_w(&(ht->array_lock[i]));
}
} /* while ( 1 ) */
return NULL;
}