1
2 /*
3 * dmucs_host.cc: a DmucsHost is a representation of a compilation host.
4 *
5 * Copyright (C) 2005, 2006 Victor T. Norman
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #include "dmucs.h"
23 #include "dmucs_dprop.h"
24 #include "dmucs_host.h"
25 #include "dmucs_db.h"
26 #include "dmucs_hosts_file.h"
27 #include "dmucs_host_state.h"
28 #include "dmucs_resolve.h"
29 #include <stdio.h>
30 #include <netdb.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <sys/socket.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39
DmucsHost(const struct in_addr & ipAddr,const DmucsDprop dprop,const int numCpus,const int powerIndex)40 DmucsHost::DmucsHost(const struct in_addr &ipAddr,
41 const DmucsDprop dprop,
42 const int numCpus, const int powerIndex) :
43 ipAddr_(ipAddr), dprop_(dprop), ncpus_(numCpus), pindex_(powerIndex),
44 ldavg1_(0), ldavg5_(0), ldavg10_(0),
45 lastUpdate_(0)
46 {
47 state_ = DmucsHostStateAvail::getInstance();
48 }
49
50
51 DmucsHost *
createHost(const struct in_addr & ipAddr,const DmucsDprop dprop,const std::string & hostsInfoFile)52 DmucsHost::createHost(const struct in_addr &ipAddr,
53 const DmucsDprop dprop,
54 const std::string &hostsInfoFile)
55 {
56 /*
57 * Read the hosts file, and find the entry in it for this host.
58 */
59 DmucsHostsFile *hostsFile = DmucsHostsFile::getInstance(hostsInfoFile);
60 int numCpus = 1;
61 int powerIndex = 1;
62 hostsFile->getDataForHost(ipAddr, &numCpus, &powerIndex);
63 DmucsHost *newHost = new DmucsHost(ipAddr, dprop, numCpus, powerIndex);
64
65 DmucsDb::getInstance()->addNewHost(newHost);
66
67 return newHost;
68 }
69
70 const int
getStateAsInt() const71 DmucsHost::getStateAsInt() const
72 {
73 return state_->asInt();
74 }
75
76 int
getTier() const77 DmucsHost::getTier() const
78 {
79 return calcTier(ldavg1_, ldavg5_, ldavg10_, pindex_);
80 }
81
82 int
calcTier(float ldavg1,float ldavg5,float ldavg10,int pindex) const83 DmucsHost::calcTier(float ldavg1, float ldavg5, float ldavg10,
84 int pindex) const
85 {
86 if (ldavg1 < 0.9) {
87 return pindex;
88 } else if (ldavg5 < 0.7) {
89 return pindex;
90 } else if (ldavg10 < 0.8) {
91 return pindex - 1;
92 } else {
93 return 0; // 0 means don't use this host.
94 }
95 }
96
97
98 void
updateTier(float ldAvg1,float ldAvg5,float ldAvg10)99 DmucsHost::updateTier(float ldAvg1, float ldAvg5, float ldAvg10)
100 {
101 ldAvg1 /= (float) ncpus_;
102 ldAvg5 /= (float) ncpus_;
103 ldAvg10 /= (float) ncpus_;
104 int newTier = calcTier(ldAvg1, ldAvg5, ldAvg10, pindex_);
105 int oldTier = getTier();
106
107 if (newTier != oldTier) {
108 DMUCS_DEBUG((stderr, "oldTier %d, newTier %d\n", oldTier, newTier));
109 if (newTier == 0) {
110 /* This host is completely overloaded: remove the CPU objects
111 from their current tier, and move this host object to the
112 overloaded state. */
113 overloaded();
114 ldavg1_ = ldAvg1; ldavg5_ = ldAvg5; ldavg10_ = ldAvg10;
115 } else if (oldTier == 0) {
116 /* This host was overloaded, but now it is not.
117 Move the cpu objects from one tier to another. */
118 DmucsDb::getInstance()->moveCpus(this, oldTier, newTier);
119 ldavg1_ = ldAvg1; ldavg5_ = ldAvg5; ldavg10_ = ldAvg10;
120 } else {
121 /* Move the cpu objects from one tier to another. */
122 DmucsDb::getInstance()->moveCpus(this, oldTier, newTier);
123 ldavg1_ = ldAvg1; ldavg5_ = ldAvg5; ldavg10_ = ldAvg10;
124 }
125 } else {
126 ldavg1_ = ldAvg1; ldavg5_ = ldAvg5; ldavg10_ = ldAvg10;
127 }
128 lastUpdate_ = time(0);
129 }
130
131
132
133 void
avail()134 DmucsHost::avail()
135 {
136 state_->avail(this);
137 }
138
139
140 void
unavail()141 DmucsHost::unavail()
142 {
143 state_->unavail(this);
144 }
145
146
147 void
silent()148 DmucsHost::silent()
149 {
150 state_->silent(this);
151 }
152
153
154 void
overloaded()155 DmucsHost::overloaded()
156 {
157 state_->overloaded(this);
158 }
159
160
161 void
changeState(DmucsHostState * state)162 DmucsHost::changeState(DmucsHostState *state)
163 {
164 state_ = state;
165 state_->addToDb(this);
166 }
167
168
169 bool
seemsDown() const170 DmucsHost::seemsDown() const
171 {
172 return (time(0) - lastUpdate_ > DMUCS_HOST_SILENT_TIME);
173 }
174
175
176 bool
isUnavailable() const177 DmucsHost::isUnavailable() const
178 {
179 return (state_->asInt() == STATUS_UNAVAILABLE);
180 }
181
182 bool
isSilent() const183 DmucsHost::isSilent() const
184 {
185 return (state_->asInt() == STATUS_SILENT);
186 }
187
188 bool
isOverloaded() const189 DmucsHost::isOverloaded() const
190 {
191 return (state_->asInt() == STATUS_OVERLOADED);
192 }
193
194
195 void
dump()196 DmucsHost::dump()
197 {
198 fprintf(stderr,
199 "Host: %20.20s Dprop: %8.8s State: %s Pindex: %d Ncpus %d\n",
200 inet_ntoa(ipAddr_), dprop2cstr(dprop_), state_->dump(),
201 pindex_, ncpus_);
202 }
203
204
205 const std::string &
getName()206 DmucsHost::getName()
207 {
208 if (! resolvedName_.empty()) {
209 return resolvedName_;
210 }
211
212 return getHostName(resolvedName_, ipAddr_);
213 }
214
215
216 /*
217 * Given in IP address, find the host in the host database. If its name has
218 * already been found, then return it. Otherwise, resolve it and store it
219 * in the host and return the string.
220 */
221 std::string
resolveIp2Name(unsigned int ipAddr,DmucsDprop dprop)222 DmucsHost::resolveIp2Name(unsigned int ipAddr, DmucsDprop dprop)
223 {
224 /* Search for DmucsHost, based on Ip Address */
225 struct in_addr c;
226 c.s_addr = ipAddr;
227 return DmucsDb::getInstance()->getHost(c, dprop)->getName();
228 }
229