XRootD
XrdMain.cc
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* X r d M a i n . c c */
4 /* */
5 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 /* This is the XRootd server. The syntax is:
31 
32  xrootd [options]
33 
34  options: [-b] [-c <fname>] [-d] [-h] [-l <fname>] [-p <port>] [<oth>]
35 
36 Where:
37  -b forces background execution.
38 
39  -c specifies the configuration file. This may also come from the
40  XrdCONFIGFN environmental variable.
41 
42  -d Turns on debugging mode (equivalent to xrd.trace all)
43 
44  -h Displays usage line and exits.
45 
46  -l Specifies location of the log file. This may also come from the
47  XrdOucLOGFILE environmental variable or from the oofs layer. By
48  By default, error messages go to standard error.
49 
50  -p Is the port to use either as a service name or an actual port number.
51  The default port is 1094.
52 
53  <oth> Are other protocol specific options.
54 
55 */
56 
57 /******************************************************************************/
58 /* i n c l u d e f i l e s */
59 /******************************************************************************/
60 
61 #include <unistd.h>
62 #include <cctype>
63 #include <cerrno>
64 #include <cstdint>
65 #include <signal.h>
66 #include <cstdlib>
67 #include <cstring>
68 #include <strings.h>
69 #include <cstdio>
70 #include <sys/param.h>
71 
72 #include "Xrd/XrdConfig.hh"
73 #include "Xrd/XrdInet.hh"
74 #include "Xrd/XrdLink.hh"
75 #include "Xrd/XrdProtLoad.hh"
76 #include "Xrd/XrdScheduler.hh"
77 
78 #include "XrdSys/XrdSysError.hh"
79 #include "XrdSys/XrdSysHeaders.hh"
80 #include "XrdSys/XrdSysPthread.hh"
81 #include "XrdSys/XrdSysUtils.hh"
82 
83 /******************************************************************************/
84 /* L o c a l C l a s s e s */
85 /******************************************************************************/
86 
87 class XrdMain : XrdJob
88 {
89 public:
90 
94 int thePort;
96 
97 void DoIt() {XrdLink *newlink;
98  if ((newlink = theNet->Accept(0, -1, theSem)))
99  newlink->setProtocol(theProt, true);
100  }
101 
102  XrdMain() : XrdJob("main accept"), theSem(0), theProt(0),
103  theNet(0), thePort(0) {}
104  XrdMain(XrdInet *nP) : XrdJob("main accept"), theSem(0),
105  theProt(0), theNet(nP), thePort(nP->Port()) {}
106  ~XrdMain() {}
107 };
108 
110 
111 /******************************************************************************/
112 /* E x t e r n a l T h r e a d I n t e r f a c e s */
113 /******************************************************************************/
114 
115 void *mainAccept(void *parg)
116 { XrdMain *Parms = (XrdMain *)parg;
117  XrdScheduler *mySched = Parms->Config.ProtInfo.Sched;
118  XrdProtLoad ProtSelect(Parms->thePort);
119  XrdSysSemaphore accepted(0);
120 
121 // Complete the parms
122 //
123  Parms->theSem = &accepted;
124  Parms->theProt = (XrdProtocol *)&ProtSelect;
125 
126 // Simply schedule new accepts
127 //
128  while(1) {mySched->Schedule((XrdJob *)Parms);
129  accepted.Wait();
130  }
131 
132  return (void *)0;
133 }
134 
135 /******************************************************************************/
136 /* m a i n A d m i n */
137 /******************************************************************************/
138 
139 void *mainAdmin(void *parg)
140 { XrdMain *Parms = (XrdMain *)parg;
141  XrdInet *NetADM = Parms->theNet;
142  XrdLink *newlink;
143 // static XrdProtocol_Admin ProtAdmin;
144  int ProtAdmin;
145 
146 // At this point we should be able to accept new connections. Noe that we don't
147 // support admin connections as of yet so the following code is superflous.
148 //
149  while(1) if ((newlink = NetADM->Accept()))
150  {newlink->setProtocol((XrdProtocol *)&ProtAdmin);
151  newlink->setProtName("xrdadmin");
152  Parms->Config.ProtInfo.Sched->Schedule((XrdJob *)newlink);
153  }
154  return (void *)0;
155 }
156 
157 /******************************************************************************/
158 /* m a i n */
159 /******************************************************************************/
160 
161 int main(int argc, char *argv[])
162 {
163  XrdMain Main;
164  pthread_t tid;
165  char buff[128];
166  int i, retc;
167 
168 // Set TZ environment variable to read the system timezone from /etc/localtime
169 // if it is not already set, to avoid race conditions between localtime_r() and
170 // mktime() during the multi-threaded phase of the initialization.
171 
172  if (access("/etc/localtime", R_OK) == 0)
173  setenv("TZ", ":/etc/localtime", /* overwrite */ false);
174 
175 // Call tzset() early to ensure thread-safety of localtime_r() and mktime().
176  tzset();
177 
178 // Turn off sigpipe and host a variety of others before we start any threads
179 //
181 
182 // Set the default stack size here. Note that on modern Linux the default
183 // stack size is set at about 8MB. We force a lower limit to not have a huge
184 // virtual address space mostly for core file debugging purposes.
185 //
186  if (sizeof(long) > 4) XrdSysThread::setStackSize((size_t)2097152, true);
187  else XrdSysThread::setStackSize((size_t)1048576, true);
188 
189 // Process configuration file
190 //
191  if (Main.Config.Configure(argc, argv)) _exit(1);
192 
193 // Start the admin thread if an admin network is defined
194 //
195  if (Main.Config.NetADM && (retc = XrdSysThread::Run(&tid, mainAdmin,
196  (void *)new XrdMain(Main.Config.NetADM),
197  XRDSYSTHREAD_BIND, "Admin handler")))
198  {Main.Config.ProtInfo.eDest->Emsg("main", retc, "create admin thread");
199  _exit(3);
200  }
201 
202 // At this point we should be able to accept new connections. Spawn a
203 // thread for each network except the first. The main thread will handle
204 // that network as some implementations require a main active thread.
205 //
206  for (i = 1; i < (int)Main.Config.NetTCP.size(); i++)
207  if (Main.Config.NetTCP[i])
208  {XrdMain *Parms = new XrdMain(Main.Config.NetTCP[i]);
209  sprintf(buff, "Port %d handler", Parms->thePort);
210 //??? if (Parms->theNet == Main.Config.NetTCP[XrdProtLoad::ProtoMax])
211 // Parms->thePort = -(Parms->thePort);
212  if ((retc = XrdSysThread::Run(&tid, mainAccept, (void *)Parms,
213  XRDSYSTHREAD_BIND, strdup(buff))))
214  {Main.Config.ProtInfo.eDest->Emsg("main", retc, "create", buff);
215  _exit(3);
216  }
217  }
218 
219 // Finally, start accepting connections on the main port
220 //
221  Main.theNet = Main.Config.NetTCP[0];
222  Main.thePort = Main.Config.NetTCP[0]->Port();
223  mainAccept((void *)&Main);
224 
225 // We should never get here
226 //
227  pthread_exit(0);
228 }
int main(int argc, char *argv[])
Definition: XrdMain.cc:161
void * mainAdmin(void *parg)
Definition: XrdMain.cc:139
void * mainAccept(void *parg)
Definition: XrdMain.cc:115
int access(const char *path, int amode)
#define XRDSYSTHREAD_BIND
XrdProtocol_Config ProtInfo
Definition: XrdConfig.hh:58
XrdInet * NetADM
Definition: XrdConfig.hh:59
std::vector< XrdInet * > NetTCP
Definition: XrdConfig.hh:60
int Configure(int argc, char **argv)
Definition: XrdConfig.cc:318
XrdLink * Accept(int opts=0, int timeout=-1, XrdSysSemaphore *theSem=0)
Definition: XrdInet.cc:72
Definition: XrdJob.hh:43
XrdInet * theNet
Definition: XrdMain.cc:93
int thePort
Definition: XrdMain.cc:94
~XrdMain()
Definition: XrdMain.cc:106
void DoIt()
Definition: XrdMain.cc:97
static XrdConfig Config
Definition: XrdMain.cc:95
XrdSysSemaphore * theSem
Definition: XrdMain.cc:91
XrdProtocol * theProt
Definition: XrdMain.cc:92
XrdMain(XrdInet *nP)
Definition: XrdMain.cc:104
XrdMain()
Definition: XrdMain.cc:102
XrdScheduler * Sched
Definition: XrdProtocol.hh:64
XrdSysError * eDest
Definition: XrdProtocol.hh:61
void Schedule(XrdJob *jp)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
static void setStackSize(size_t stsz, bool force=false)
static bool SigBlock()
Definition: XrdSysUtils.cc:188