XRootD
Loading...
Searching...
No Matches
XrdCmsManTree.cc
Go to the documentation of this file.
1
/******************************************************************************/
2
/* */
3
/* X r d C m s M a n T r e e . c c */
4
/* */
5
/* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */
6
/* All Rights Reserved */
7
/* Produced by Andrew Hanushevsky for Stanford University under contract */
8
/* DE-AC02-76-SFO0515 with the Department of Energy */
9
/* */
10
/* This file is part of the XRootD software suite. */
11
/* */
12
/* XRootD is free software: you can redistribute it and/or modify it under */
13
/* the terms of the GNU Lesser General Public License as published by the */
14
/* Free Software Foundation, either version 3 of the License, or (at your */
15
/* option) any later version. */
16
/* */
17
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20
/* License for more details. */
21
/* */
22
/* You should have received a copy of the GNU Lesser General Public License */
23
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25
/* */
26
/* The copyright holder's institutional names and contributor's names may not */
27
/* be used to endorse or promote products derived from this software without */
28
/* specific prior written permission of the institution or contributor. */
29
/******************************************************************************/
30
31
#include <cstdio>
32
33
#include "
XProtocol/YProtocol.hh
"
34
35
#include "
XrdCms/XrdCmsManTree.hh
"
36
#include "
XrdCms/XrdCmsNode.hh
"
37
#include "
XrdCms/XrdCmsTrace.hh
"
38
39
using namespace
XrdCms
;
40
41
/******************************************************************************/
42
/* C o n s t r u c t o r */
43
/******************************************************************************/
44
45
XrdCmsManTree::XrdCmsManTree
(
int
maxC) : maxTMI(0), numConn(0), maxConn(maxC),
46
atRoot(0), conLevel(0), conNID(-1),
47
numWaiting(0), myStatus(
Active
)
48
{
49
snprintf(buff,
sizeof
(buff),
"%d"
, maxC);
50
}
51
52
/******************************************************************************/
53
/* A b o r t */
54
/******************************************************************************/
55
56
void
XrdCmsManTree::Abort
()
57
{
58
XrdSysMutexHelper
Monitor(myMutex);
59
60
// An abort may be issued to make sure no one is waiting to participate in
61
// tree construction. It's usually issued when the manager object has been
62
// permanently redirected.
63
//
64
if
(myStatus !=
Aborted
&& numWaiting)
65
{
for
(
int
i = 0; i < maxTMI; i++)
66
if
(tmInfo[i].Status ==
Waiting
) {tmInfo[i].Level = 0; Redrive(i);}
67
}
68
69
// Indicate we have aborted
70
//
71
myStatus =
Aborted
;
72
}
73
74
/******************************************************************************/
75
/* C o n n e c t */
76
/******************************************************************************/
77
78
int
XrdCmsManTree::Connect
(
int
nID,
XrdCmsNode
*nP)
79
{
80
static
CmsDiscRequest
discRequest = {{0,
kYR_disc
, 0, 0}};
81
XrdSysMutexHelper
Monitor(myMutex);
82
char
mybuff[16];
83
int
i;
84
85
// Rule 0: If we aborted tell the client to just stop doing this
86
//
87
if
(myStatus ==
Aborted
)
return
0;
88
89
// Rule 1: If we are already connected, thell the caller to disband the
90
// connection as we must have a connection to an interior node.
91
//
92
if
(myStatus ==
Connected
)
return
0;
93
numConn++;
94
tmInfo[nID].nodeP = nP;
95
96
// Rule 2: If we connected to a root node then consider ourselves connected
97
// only if all connections are to the root.
98
//
99
if
(tmInfo[nID].Level == 0)
100
{
if
(numConn == maxConn)
101
{myStatus =
Connected
; conLevel = 0; atRoot = 1;
102
Say
.Emsg(
"ManTree"
,
"Now connected to"
, buff,
"root node(s)"
);
103
}
104
tmInfo[nID].Status =
Connected
;
105
return
1;
106
}
107
108
// Rule 3: We connected to an interior node. Disband all other existing
109
// connections (these should only be to root nodes) and consider
110
// ourselves connected.
111
//
112
for
(i = 0; i < maxTMI; i++)
113
if
(i != nID && tmInfo[i].Status ==
Connected
)
114
{tmInfo[i].nodeP->Send((
char
*)&discRequest,
sizeof
(discRequest));
115
tmInfo[i].Status =
Pending
;
116
}
117
myStatus =
Connected
;
118
conLevel = tmInfo[nID].Level;
119
conNID = nID;
120
atRoot = 0;
121
122
// Document our connection configuration
123
//
124
snprintf(mybuff,
sizeof
(mybuff),
"%d"
, conLevel);
125
Say
.Emsg(
"ManTree"
,
"Now connected to supervisor at level"
, mybuff);
126
return
1;
127
}
128
129
/******************************************************************************/
130
/* D i s c */
131
/******************************************************************************/
132
133
void
XrdCmsManTree::Disc
(
int
nID)
134
{
135
136
// A connected caller has lost it's connection.
137
//
138
myMutex.Lock();
139
if
(tmInfo[nID].Status ==
Connected
|| tmInfo[nID].Status ==
Pending
)
140
numConn--;
141
tmInfo[nID].Status =
Active
;
142
if
(atRoot || (conLevel && conNID == nID)) myStatus =
Active
;
143
tmInfo[nID].nodeP = 0;
144
myMutex.UnLock();
145
}
146
147
/******************************************************************************/
148
/* R e g i s t e r */
149
/******************************************************************************/
150
151
int
XrdCmsManTree::Register
()
152
{
153
int
nID;
154
155
// Add this server to the tree table. Register is called only once and there
156
// can be no more than MTMax connections to a manager. Hence, we dispense with
157
// error checking (how optimistic :-)
158
//
159
myMutex.Lock();
160
tmInfo[maxTMI].Status=
Active
;
161
nID = maxTMI; maxTMI++;
162
myMutex.UnLock();
163
return
nID;
164
}
165
166
/******************************************************************************/
167
/* T r y i n g */
168
/******************************************************************************/
169
170
// This method arranges server connections to a manager to form a minimal B-Tree
171
// free of phantom arcs. The rule is simple, either all connections are to the
172
// root of tree or there is only one connection to an interior node. Because
173
// node discovery is non-determinstic, we must make sure that all root nodes
174
// are tried so as to discover the full set of supervisor nodes we can contact.
175
// This method returns True if the caller may continue at the indicated level
176
// and False if the caller should restart at the root node.
177
//
178
int
XrdCmsManTree::Trying
(
int
nID,
int
lvl)
179
{
180
int
i;
181
182
// Set the current status of the connection
183
//
184
myMutex.Lock();
185
tmInfo[nID].Level = lvl;
186
187
// Rule 0: If we aborted tell the client to just stop doing this
188
//
189
if
(myStatus ==
Aborted
)
return
-1;
190
191
// Rule 1: If we are already connected at level >0 then the caller must wait
192
//
193
if
(myStatus ==
Connected
&& conLevel > 0)
194
{Pause(nID);
195
return
(lvl == tmInfo[nID].Level);
196
}
197
198
// Rule 2: If the caller is trying level 0 then any waiting threads must be
199
// allowed to continue but forced to level 0. This allows us to discover
200
// all the supervisors connected to the root.
201
//
202
if
(!lvl)
203
{
if
(numWaiting)
204
{
for
(i = 0; i < maxTMI; i++)
205
if
(i != nID && tmInfo[i].Status ==
Waiting
)
206
{tmInfo[i].Level = 0; Redrive(i);}
207
}
208
myMutex.UnLock();
209
return
1;
210
}
211
212
// Rule 3: If the caller is trying at a non-zero level (interior node) and
213
// someone else is trying at a non-zero level, then the caller must
214
// wait.
215
//
216
for
(i = 0; i < maxTMI; i++)
217
if
(i != nID && tmInfo[i].Status ==
Active
&& tmInfo[i].Level)
break
;
218
if
(i < maxTMI) Pause(nID);
219
else
myMutex.UnLock();
220
221
// The caller may continue. Indicate whether the caller must restart at the
222
// root node. If the caller may continue trying to connect to an interior
223
// node then it's the only thread trying to do so.
224
//
225
return
(lvl == tmInfo[nID].Level);
226
}
XrdCmsManTree.hh
XrdCmsNode.hh
XrdCmsTrace.hh
YProtocol.hh
XrdCmsManTree::Connect
int Connect(int nID, XrdCmsNode *nP)
Definition
XrdCmsManTree.cc:78
XrdCmsManTree::Abort
void Abort()
Definition
XrdCmsManTree.cc:56
XrdCmsManTree::Register
int Register()
Definition
XrdCmsManTree.cc:151
XrdCmsManTree::Active
@ Active
Definition
XrdCmsManTree.hh:52
XrdCmsManTree::Waiting
@ Waiting
Definition
XrdCmsManTree.hh:52
XrdCmsManTree::Pending
@ Pending
Definition
XrdCmsManTree.hh:52
XrdCmsManTree::Aborted
@ Aborted
Definition
XrdCmsManTree.hh:52
XrdCmsManTree::Connected
@ Connected
Definition
XrdCmsManTree.hh:52
XrdCmsManTree::Disc
void Disc(int nID)
Definition
XrdCmsManTree.cc:133
XrdCmsManTree::XrdCmsManTree
XrdCmsManTree(int maxC)
Definition
XrdCmsManTree.cc:45
XrdCmsManTree::Trying
int Trying(int nID, int Lvl)
Definition
XrdCmsManTree.cc:178
XrdCmsNode
Definition
XrdCmsNode.hh:58
XrdSysMutexHelper
Definition
XrdSysPthread.hh:263
XrdCms
Definition
YProtocol.hh:78
XrdCms::Say
XrdSysError Say
Definition
XrdCmsManager.cc:62
XrdCms::kYR_disc
@ kYR_disc
Definition
YProtocol.hh:103
XrdCms::CmsDiscRequest
Definition
YProtocol.hh:212
XrdCms
XrdCmsManTree.cc
Generated by
1.14.0