1 /*
2 * fca-mgr.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1997-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * fca-mgr.cc -- Helen J. Wang
36 * Edited by Yatin Chawathe: 04/29/97
37 */
38
39 #include "fc.h"
40 #include "fca-mgr.h"
41 #include "fca-pkt.h"
42 #include tclcl.h>
43
44
45
46 static class FCAMgrClass : public TclClass {
47 public:
48 FCAMgrClass() : TclClass("SRMAppMgr/FCA") {
49 //printf("Created FCAMgr class: %s\n", classname_);
50 }
51 TclObject* create (int /*argc*/, const char*const* /*argv*/) {
52 return (new FCAMgr());
53 }
54 } fcamgr;
55
56
57
58 FCARcvr *
59 FCAMgr::DefineRcvr(const srm_src &sid, int islocal)
60 {
61 Tcl::instance().evalf("%s define_rcvr %s %d", this->name(), (char*)sid,
62 islocal);
63 // Debug(dbgFCA, ("define_rcvr: %s", Tcl::instance().result()));
64 return ((FCARcvr*) TclObject::lookup(Tcl::instance().result()));
65 }
66
67
68 SRM_PacketHandler *
69 FCAMgr::new_source(const srm_src &sid, int islocal)
70 {
71 return DefineRcvr(sid, islocal);
72 }
73
74
75 void
76 FCAMgr::handle_request(const srm_src &sid, u_char *pb, int len)
77 {
78 Debug(dbgFCA, ("\nFCAMgr::handle_request: len = %d, %x@%x\n",
79 len, sid.ss_uid, sid.ss_addr));
80
81 FCARcvr *pRcvr = DefineRcvr(sid, 0);
82 if (pRcvr==NULL) {
83 Debug(dbgFCA, ("handle_request, cannot get a receiver"));
84 return;
85 }
86 FCA_Packet *pkt = FCA_Packet::New();
87 if (pkt->Extract(pb, len)==FALSE) {
88 Debug(dbgFCA, ("handle_request, cannot extract the packet"));
89 FCA_Packet::Delete(pkt);
90 return;
91 }
92 Debug(dbgFCA, ("FCAMgr::handle_request, rcvrObj = %s", pRcvr->name()));
93 Tcl::instance().evalf("%s handle_request %s", pRcvr->name(), pkt->name());
94 FCA_Packet::Delete(pkt);
95 Debug(dbgFCA, ("after calling Otcl handle_request"));
96 }
97
98
99 void
100 FCAMgr::handle_reply(const srm_src &sid, u_char *pb, int len)
101 {
102 Debug(dbgFCA, ("FCAMgr::handle_reply: len = %d, %x@%x", len,
103 sid.ss_uid, sid.ss_addr));
104
105 FCARcvr *pRcvr = DefineRcvr(sid, 0);
106 Debug(dbgFCA, ("FCAMgr::handle_reply, after getting rcvr"));
107 if (pRcvr==NULL) {
108 Debug(dbgFCA, ("FCAMgr::handle_reply: no rcvr can be found."));
109 return;
110 }
111 Debug(dbgFCA, ("FCAMgr::handle_reply, right before extracting reply"));
112 FCA_Packet *pkt = FCA_Packet::New();
113 if (pkt->Extract(pb, len)==FALSE) {
114 Debug (dbgFCA,
115 ("FCAMgr::handle_reply, unable to extract the repair reply"));
116 FCA_Packet::Delete(pkt);
117 return;
118 }
119 Debug(dbgFCA, ("Before calling OTcl handle_reply"));
120 Tcl::instance().evalf("%s handle_reply %s", pRcvr->name(), pkt->name());
121 Debug(dbgFCA, ("After calling OTcl handle_reply"));
122 FCA_Packet::Delete(pkt);
123 }
124
125
126 void
127 FCAMgr::handle_SA(const srm_src &sid, u_char *pb, int len)
128 {
129 Debug(dbgFCA, ("FCAMgr::handle_SA: len = %d", len));
130
131 FCARcvr *pRcvr = DefineRcvr(sid, 0);
132 if (pRcvr==NULL) {
133 Debug(dbgFCA, ("FCAMgr::handle_SA: canNOT find a receiver to handle SA"));
134 return;
135 }
136 FCA_Packet *pkt = FCA_Packet::New();
137 if (pkt->Extract(pb, len)==FALSE) {
138 FCA_Packet::Delete(pkt);
139 return;
140 }
141 Tcl::instance().evalf("%s handle_SA %s", pRcvr->name(), pkt->name());
142 FCA_Packet::Delete(pkt);
143 }
144
145
146 int
147 FCAMgr::periodic_update(u_char *pb)
148 {
149 int len = SRM_MTU;
150 //Debug(dbgFCA, ("FCAMgr::periodic_update: len = %d", len));
151
152 SRM_PacketHandler *local =
153 pSession_->source_manager()->first_local_source()->handler();
154 if (local==NULL) {
155 Debug(dbgFCA, ("No local source defined for FCAMgr"));
156 return 0;
157 }
158 FCA_Packet *pkt = FCA_Packet::New();
159 Tcl::instance().evalf("%s create_sa %s", local->name(), pkt->name());
160 if (pkt->Packetize(pb, len)==FALSE) {
161 FCA_Packet::Delete(pkt);
162 return 0;
163 }
164 FCA_Packet::Delete(pkt);
165 //Debug(dbgFCA, ("periodic_update contains %d bytes", len));
166 return len;
167 }
168
169
170 int
171 FCAMgr::next_ADU(u_char *pb, int len, srm_src &/*id*/, int &/*pkt_type*/,
172 int &next)
173 {
174 Debug(dbgFCA, ("FCAMgr::next_ADU: len = %d", len));
175
176 SRM_PacketHandler *local =
177 pSession_->source_manager()->first_local_source()->handler();
178 if (local==NULL) {
179 Debug(dbgFCA, ("No local source defined for FCAMgr"));
180 return 0;
181 }
182 Tcl::instance().evalf("%s next_ADU", local->name());
183
184 char *result = Tcl::instance().result();
185 if (strcmp(result, "")==0) return 0;
186
187 FCA_Packet *pkt = (FCA_Packet*) Tcl::instance().lookup(result);
188 if (pkt->Packetize(pb, len)==FALSE) {
189 FCA_Packet::Delete(pkt);
190 return 0;
191 }
192 FCA_Packet::Delete(pkt); // I am supposed to delete the packet, although
193 // it was created by Tcl
194 Debug(dbgFCA, ("next_ADU contains %d bytes:", len));
195 static char buffer[10000];
196 *buffer = '\0';
197 for (int i=0; i<len; i++) {
198 sprintf(buffer, "%s%02x ", buffer, pb[i]);
199 }
200 Debug(dbgFCA, ("%s", buffer));
201
202 Tcl::instance().evalf("%s more_ADU", local->name());
203 int more = atoi(Tcl::instance().result());
204 if (more!=0) next = 1;
205 return len;
206 }
207
208
209 int
210 FCAMgr::command(int argc, const char*const* argv)
211 {
212 if (argc==3) {
213 if (!strcmp(argv[1], "attach_session")) {
214 pSession_ = (SRM_Session*)TclObject::lookup(argv[2]);
215 if (!pSession_) {
216 Tcl::instance().
217 result("FCAMgr::command, Couldn't find session");
218 return TCL_ERROR;
219 }
220 return TCL_OK;
221 }
222 if (!strcmp(argv[1], "request_send")) {
223 //FCA_Packet *pkt = (FCA_Packet*)TclObject::lookup(argv[2]);
224 // ignore the packet for now; jsut call begin_xmit with a large
225 // value
226 pSession_->begin_xmit(SRM_MTU);
227 return TCL_OK;
228 }
229 }
230 if (!strcmp(argv[1], "sched_request")) {
231 Debug (dbgFCA, ("handing sched_request\n"));
232 SrcId sid;
233 char* rqtclobj = (char*) argv[2];
234 sid = argv[3];
235 Debug (dbgFCA, ("sched_request, rqtclobj = %s", rqtclobj));
236 FCARepairRequest *rqst =
237 (FCARepairRequest* ) TclObject::lookup(rqtclobj);
238 if (!rqst) {
239 Tcl::instance().result("C++ rqst obj doesn't exist");
240 Debug (dbgFCA, ("sched_request, rqst obj not found\n"));
241 return TCL_ERROR;
242 }
243 Debug (dbgFCA, ("sched_request, about to schedule the repair request\n"));
244 this->sched_request (rqst, sid);
245 return TCL_OK;
246 }
247
248 if (!strcmp(argv[1], "sched_reply")) {
249 Debug (dbgFCA, ("handing sched_reply\n"));
250 SrcId sid;
251 char* rpytclobj = (char*) argv[2];
252 sid = argv[3];
253 Debug (dbgFCA, ("sched_reply, replytclobj = %s", rpytclobj));
254 FCARepairReply *reply =
255 (FCARepairReply* ) TclObject::lookup(rpytclobj);
256 if (!reply) {
257 Tcl::instance().result("C++ reply obj doesn't exist");
258 Debug (dbgFCA, ("sched_reply, reply obj not found\n"));
259 return TCL_ERROR;
260 }
261 Debug (dbgFCA, ("sched_reply, about to schedule the repair reply\n"));
262 this->sched_reply (reply, sid);
263 return TCL_OK;
264 }
265
266 return SRM_AppMgr::command(argc, argv);
267 }
268
269
270
271
272
273 #if OLD
274
275 SrcId FCAMgr::getSrcId () {
276 SrcId sid;
277 sid.ss_uid = getuid();
278 sid.ss_addr = LookupLocalAddr();
279 return sid;
280 }
281
282 /* ignore pu_mod */
283 #DEFINE FLSTLEN 2 /* level 1 split */
284 #DEFINE FLEN 5 /* level 2 split */
285 #DEFINE HLDRLEN 2 /* level 3 split */
286 #DEFINE RQLEN 3 /* level 3 split */
287 /*
288 { numfls { {f1} {f2} ..} }
289 {f1} = { fid numhldrs { {h1} {h2} ... } numrqs { {rq1} {rq2} }}
290 {h1} = { uid addr }
291 {rq1} = { uid addr cmt }
292 */
293 /* fill in moderator periodic update */
294 /* <--: indicates packet filling activities */
295 int FCAMgr::pu_mod (u_char *buf) {
296 int returnval = 0;
297 Tcl& interp = Tcl::instance():
298 Tcl::instance().evalf ("%s pu_flstatus");
299 char* list = interp.result();
300 #ifdef FCDBG
301 fprintf (stderr, "FCAMgr::pu_mod: flstat list = %s \n", list);
302 #endif
303 Pkt_SA_2 *psa2 = new Pkt_SA_2;
304 /* level 1 split -- original list */
305 int cnt1; /* number of items in the list */
306 char** elts1; /* list elements */
307 Tcl_SplitList (interp, list, &cnt1, &elts1);
308 if (cnt1 != FLSTLEN)
309 fprintf (stderr,
310 "FCAMgr::pu_mod: list length mismatch at L1 split, cntr1 (%d)\n",
311 cnt1);
312 Pkt_SA_1 *ps = (Pkt_SA_1 *) buf; /* <-- */
313 u_int32_t numFls = strtoul(elts[0]);
314 ps->ps_numFls = host2net(numFls); /* <-- */
315
316 /* level 2 split -- floor list */
317 int flcnt;
318 char** fllist;
319 Tcl_SplitList (interp, elts1[1], &flcnt, &fllist);
320 if (flcnt != numFls)
321 fprintf (stderr, "FCAMgr::pu_mod, actual flcnt (%d) != numfls (%d) \n",
322 flcnt, numFls);
323
324 buf += sizeof (u_int32_t); /* <-- */
325 for (int i=0; i<flcnt; i++) {
326 /* for each floor list */
327 int numflfields;
328 char** flfields;
329 Tcl_SplitList(interp, fllist[i], &numflfields, &flfields);
330 if (numflfields != FLEN)
331 fprintf (stderr, "FCAMgr::pu_mod, wrong syntax from OTcl side\n");
332
333 Byte fid= atoi(flfields[0]);
334 (ps->aFlStatus[i]).ph_fid = fid; /* <-- */
335 (psa2->aFlRqs[i]).pf_fid = fid; /* <-- */
336 Byte numhldrs = atoi(fllist[1]);
337 (ps->aFlStatus[i]).ph_numHolders = numhldrs; /* <-- */
338 int holdercnt;
339 char** holderlist;
340 Tcl_SplitList(interp, flfields[2], &holdercnt, &holderlist);
341 if (holdercnt != numhldrs )
342 fprintf (stderr,
343 "FCAMgr::pu_mod, mismatch btwn actual holdercnt(%d) & numhldrs(%d) \n", holdercnt, numhldrs);
344
345 buf += sizeof (Pkt_FlStatus) - sizeof (SrcId);
346 for (int j=0; j<holdercnt; j++) {
347 /* level 3 split -- split each holder */
348 int numhldrfields;
349 char** holder;
350 Tcl_SplitList (interp, holderlist[j], &numhldrfields, &holder);
351 if (numhldrfields != 2)
352 fprintf (stderr,
353 "FCAMgr::pu_mod, holder contains %d fields instead of 2 (uid, addr)\n", numhldrfields);
354 SrcId sid;
355 unsigned long sid.ss_uid = strtoul(holder[0]);
356 unsigned long sid.ss_addr = strtoul(holder[1]);
357 host2net(sid, (ps->aFlStatus[i]).pf_holderids[j]); /* <-- */
358 buf += sizeof(SrcId);
359 }
360
361 u_int16_t numrqs = atoi(flfields[3]);
362 (psa2->aFlRqs[i]).pf_numRqsts = host2net(numrqs); /* <-- */
363 int psa2size = sizeof (Pkt_FlRqs) - sizeof (SrcId);
364 int rqcnt;
365 char** rqlist;
366 Tcl_SplitList(interp, flfields[4], &rqcnt, &rqlist);
367 if (rqcnt != numrqs )
368 fprintf (stderr,
369 "FCAMgr::pu_mod, mismatch btwn actual rqcnt(%d) & numrqs(%d) \n", rqcnt, numrqs);
370 for (int j=0; j<rqcnt; j++) {
371 /* level 3 split -- split each rqholder */
372 int numrqhldrfields;
373 char** rqholder;
374 Tcl_SplitList (interp, rqlist[j], &numrqhldrfields, &rqholder);
375 if (numrqhldrfields != 2)
376 fprintf (stderr,
377 "FCAMgr::pu_mod, holder contains %d fields instead of 2 (uid, addr)\n", numhldrfields);
378 SrcId sid;
379 unsigned long sid.ss_uid = strtoul(rqholder[0]);
380 unsigned long sid.ss_addr = strtoul(rqholder[1]);
381 host2net(sid, (psa2->aFlRqs[i]).pf_rqsids[j]); /* <-- */
382 psa2size += sizeof(SrcId);
383 }
384 }
385 memcpy (buf, psa2, psa2size); /* <-- */
386 }
387
388 /* fill in participant periodic update */
389 /*
390 int FCAMgr::pu_part (u_char *buf) {
391 int returnlen = 0;
392 Pkt_PSA *pp = (Pkt_PSA *) buf;
393 SrcId sid = this->getSrcId ();
394 host2net (sid, pp->prs_sid);
395 Tcl::instance().evalf("%s pu_topSeq", this->name);
396 unsigned long topseq = strtoul(Tcl::instance().result());
397 pp->prs_maxSn = host2net (topseq);
398 return (returnlen = sizeof (Pkt_PSA));
399 }
400 */
401 /* send out a periodicUpdate for SRM */
402 int FCAMgr::periodicUpdate(u_char *buf) {
403
404 Pkt_Hdr *ph = (Pkt_Hdr *) buf;
405 SrcId sid = this->getSrcId();
406 n_long ts = this->CurrTime();
407 host2net (sid, ph->srcid);
408 ph->ph_ts = host2net(ts);
409 ph->ph_version = host2net(0.1);
410
411 Pkt_SA *ps = (Pkt_SA *) (buf + sizeof(Pkt_Hdr));
412 Tcl::instance().evalf("%s pu_topSeq", this->name);
413 unsigned long topseq = strtoul(Tcl::instance().result());
414 /*
415 Tcl::instance().evalf("%s pu_topGrantSeq", this->name);
416 unsigned long topGrantSeq = strtoul(Tcl::instance().result());
417 */
418 Tcl::instance().evalf("%s pu_rqQsize", this->name);
419 unsigned long rqQsize = strtoul(Tcl::instance().result());
420 #ifdef FCDBG
421 fprintf (stderr, "FCAMgr::PeriodicUpdate, topseq (%lu), topgrantseq (%lu), rqQsize(%lu) \n", topseq, topGrantSeq, rqQsize);
422 #endif
423 ps->topSeq = host2net (topseq);
424 /* ps->topGrantSeq = host2net (topGrantSeq); */
425 ps->rqQsize = host2net (rqQsize);
426
427 }
428
429 int FCAMgr::command(int argc, const char*const* argv)
430 {
431 if (!strcmp(argv[1], "local_uid"))
432 Tcl::instance().resultf("%x", getuid());
433
434 if (!strcmp(argv[1], "local_addr")) {
435 Tcl::instance().resultf("%x", LookupLocalAddr());
436 }
437
438 if (!strcmp(argv[1],"attach_session")) {
439 SRM_Session* pSession = (SRM_Session*)TclObject::lookup(argv[2]);
440 if (!pSession) {
441 Tcl::instance().result("FCAMgr::command, Couldn't find session");
442 return TCL_ERROR;
443 }
444 SetSession(pSession);
445 }
446
447 if (!strcmp(argv[1], "sched_request")) {
448 Debug (dbgFCA, ("handing sched_request\n"));
449 SrcId sid;
450 sid = argv[2];
451 char* rqtclobj = argv[3];
452 FCARepairRequest *rqst =
453 (FCARepairRequest* ) TclObject::lookup(rqtclobj);
454 if (!rqst) {
455 Tcl::instance.resultf("C++ rqst obj doesn't exist");
456 Debug (dbgFCA, ("sched_request, rqst obj not found\n"));
457 }
458 Debug (dbgFCA, ("sched_request, about to schedule the repair request\n"));
459 this->sched_request (rqst, sid);
460 }
461
462 if (!strcmp(argv[1], "sched_reply")) {
463 if (argc != 5)
464 Tcl::instance.resultf ("syntax error: $mgr sched_reply $uid $addr $rpy");
465 SrcId sid;
466 sid.ss_uid = strtoul (argv[2]);
467 sid.ss_addr = strtoul (argv[3]);
468 char* rpytclobj = argv[4];
469 FCARqst *rpy = (FCAReply* ) TclObject::lookup(rpytclobj);
470 if (!rpy) {
471 Tcl::instance.resultf("C++ rqst obj doesn't exist");
472 fprintf (stderr, "FCAMgr::command - sched_reply, rpy obj not found\n");
473 }
474 this->sched_reply (rqst, sid);
475 }
476
477 return TCL_OK;
478 }
479
480 #endif
481
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.