1 karl 1.60 //%2006////////////////////////////////////////////////////////////////////////
|
2 mday 1.1 //
|
3 karl 1.51 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.49 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.51 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.53 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.60 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mday 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 kumpf 1.41 //
|
21 mday 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Day (mdday@us.ibm.com)
33 //
|
34 joyce.j 1.52 // Modified By: Josephine Eskaline Joyce (jojustin@in.ibm.com) for PEP#101
|
35 mday 1.1 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include "Cimom.h"
39
|
40 chip 1.6 #include <iostream>
|
41 kumpf 1.33 #include <Pegasus/Common/Constants.h>
|
42 kumpf 1.31 #include <Pegasus/Common/Tracer.h>
|
43 konrad.r 1.58 #include <Pegasus/Common/MessageLoader.h>
|
44 joyce.j 1.52 #include <Pegasus/Common/AutoPtr.h>
|
45 mday 1.1
46 PEGASUS_NAMESPACE_BEGIN
47
|
48 chip 1.6 PEGASUS_USING_STD;
49
|
50 mday 1.15 const Uint32 CIMOM_Q_ID = 1;
51
|
52 mday 1.26 Uint32 module_capabilities::async = 0x00000001;
53 Uint32 module_capabilities::remote = 0x00000002;
54 Uint32 module_capabilities::trusted = 0x00000004;
55 Uint32 module_capabilities::paused = 0x00000008;
56 Uint32 module_capabilities::stopped = 0x00000010;
57 Uint32 module_capabilities::module_controller = 0x00000020;
|
58 mday 1.12
|
59 mday 1.1
60
|
61 david.dillard 1.54 const String & message_module::get_name() const { return _name ; }
62 Uint32 message_module::get_capabilities() const { return _capabilities ; }
63 Uint32 message_module::get_mask() const { return _mask ; }
64 Uint32 message_module::get_queue() const { return _q_id ; }
|
65 mday 1.1 void message_module::put_name(String & name) { _name.clear(); _name = name; }
66 void message_module::put_capabilities(Uint32 capabilities) { _capabilities = capabilities; }
67 void message_module::put_mask(Uint32 mask) { _mask = mask; }
68 void message_module::put_queue(Uint32 queue) { _q_id = queue; }
69
70
71 Boolean message_module::operator ==(Uint32 q) const
72 {
73 if(this->_q_id == q)
74 return true;
75 return false;
76 }
77
|
78 chip 1.6 Boolean message_module::operator == (const message_module *mm) const
|
79 mday 1.1 {
80 if(this == mm)
81 return true;
82 return false;
83 }
84
85
|
86 chip 1.6 Boolean message_module::operator == (const String & name ) const
|
87 mday 1.1 {
88 if(name == this->_name)
89 return true;
90 return false;
|
91 chip 1.6
|
92 mday 1.1 }
93
94 Boolean message_module::operator == (const message_module & mm) const
95 {
|
96 kumpf 1.46 if(this == &mm)
|
97 mday 1.1 return true;
98 if( _name == mm._name )
99 if ( _capabilities == mm._capabilities)
100 if(_mask == mm._mask)
101 if(_q_id == mm._q_id)
102 return true;
|
103 chip 1.6
|
104 mday 1.1 return false;
|
105 chip 1.6
|
106 mday 1.1 }
107
108 Boolean message_module::operator == (const void *key) const
109 {
110 return operator == ( (*(reinterpret_cast<const message_module *>(key) ) ) );
111 }
112
113 AtomicInt cimom::_xid(0);
114
|
115 mday 1.5 Boolean cimom::route_async(AsyncOpNode *op)
116 {
117
|
118 mday 1.11
|
119 mike 1.59 if( _die.get()> 0 )
|
120 mday 1.11 return false;
121
|
122 mike 1.59 if( _routed_queue_shutdown.get() > 0 )
|
123 mday 1.5 return false;
|
124 mday 1.11
|
125 mday 1.9 _routed_ops.insert_last_wait(op);
|
126 mday 1.7
|
127 mday 1.5 return true;
|
128 chip 1.6
|
129 mday 1.5 }
130
|
131 david.dillard 1.54 void cimom::_shutdown_routed_queue()
|
132 mday 1.10 {
|
133 mday 1.11
|
134 mike 1.59 if (_routed_queue_shutdown.get() > 0 )
|
135 mday 1.11 return ;
136
|
137 joyce.j 1.52 AutoPtr<AsyncIoctl> msg(new AsyncIoctl(get_xid(),
|
138 mday 1.11 0,
139 CIMOM_Q_ID,
140 CIMOM_Q_ID,
141 true,
142 AsyncIoctl::IO_CLOSE,
143 0,
|
144 joyce.j 1.52 0));
|
145 mday 1.11 msg->op = get_cached_op();
|
146 mday 1.35
147 msg->op->_flags |= ASYNC_OPFLAGS_FIRE_AND_FORGET;
148 msg->op->_flags &= ~(ASYNC_OPFLAGS_CALLBACK | ASYNC_OPFLAGS_SAFE_CALLBACK
149 | ASYNC_OPFLAGS_SIMPLE_STATUS);
150 msg->op->_state &= ~ASYNC_OPSTATE_COMPLETE;
151 msg->op->_op_dest = _global_this;
|
152 joyce.j 1.52 msg->op->_request.insert_first(msg.get());
|
153 mday 1.35
|
154 mday 1.11 _routed_ops.insert_last_wait(msg->op);
|
155 mday 1.35 _routing_thread.join();
|
156 joyce.j 1.52 msg.release();
|
157 mday 1.10
158 }
159
|
160 mday 1.5
161 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL cimom::_routing_proc(void *parm)
162 {
163
164 Thread *myself = reinterpret_cast<Thread *>(parm);
165 cimom *dispatcher = reinterpret_cast<cimom *>(myself->get_parm());
|
166 mday 1.10 AsyncOpNode *op = 0;
167
|
168 mike 1.59 while( dispatcher->_die.get() == 0 )
|
169 mday 1.5 {
|
170 mday 1.10 try
171 {
|
172 mday 1.11 op = dispatcher->_routed_ops.remove_first_wait();
|
173 mday 1.10 }
174 catch(ListClosed & )
175 {
|
176 mday 1.9 break;
|
177 mday 1.10 }
|
178 mday 1.7
|
179 mday 1.10 if (op == 0 )
|
180 mday 1.5 {
|
181 mday 1.11 break;
|
182 mday 1.5 }
|
183 mday 1.10 else
|
184 mday 1.5 {
|
185 mday 1.12 Uint32 capabilities = 0;
186 Uint32 code = 0;
187
|
188 mday 1.16
189 // ATTN: optimization
190 // <<< Sun Feb 17 18:26:39 2002 mdd >>>
191 // once the opnode is enqueued on the cimom's list, the cimom owns it
192 // and no one is allowed to write to it but the cimom.
193 // services are only allowed to read status bits
194 // this can eliminate the need for the lock/unlock
195 // unles reading/writing status bits
196
|
197 mday 1.10 op->lock();
|
198 mday 1.18 MessageQueue *dest_q = op->_op_dest;
199 Uint32 dest_qid = dest_q->getQueueId();
|
200 mday 1.10 op->unlock();
201
202 Boolean accepted = false;
203
|
204 mday 1.18 if(dest_qid == CIMOM_Q_ID )
|
205 mday 1.10 {
|
206 mday 1.11 dispatcher->_handle_cimom_op(op, myself, dispatcher);
|
207 mday 1.10 accepted = true;
208 }
209 else
210 {
|
211 mday 1.16 // ATTN: optimization
212 // <<< Sun Feb 17 18:29:26 2002 mdd >>>
213 // this lock/loop/unlock is really just a safety check to ensure
214 // the service is registered with the meta dispatcher.
215 // if speed is an issue we can remove this lookup
216 // because we have converted to MessageQueueService from
|
217 mday 1.21 // MessageQueue, and because we register in the constructor,
|
218 mday 1.16 // the safety check is unecessary
|
219 mday 1.18 //
220 // << Tue Feb 19 11:40:37 2002 mdd >>
|
221 mday 1.21 // moved the lookup to sendwait/nowait/forget/forward functions.
|
222 mday 1.16
|
223 mday 1.19 MessageQueueService *dest_svc = 0;
224
225 if ( dest_q->get_capabilities() & module_capabilities::async)
226 {
227 dest_svc= static_cast<MessageQueueService *>(dest_q);
228 }
|
229 mday 1.12
|
230 mday 1.18 if(dest_svc != 0)
|
231 mday 1.5 {
|
232 mday 1.19 if( dest_svc->get_capabilities() & module_capabilities::paused ||
233 dest_svc->get_capabilities() & module_capabilities::stopped )
|
234 mday 1.12 {
235 // the target is stopped or paused
236 // unless the message is a start or resume
|
237 mday 1.16 // just handle it from here.
|
238 mday 1.18 op->lock();
239 AsyncRequest *request = static_cast<AsyncRequest *>(op->_request.next(0));
240 op->unlock();
241 code = request->getType();
242
243 if (code != async_messages::CIMSERVICE_START &&
244 code != async_messages::CIMSERVICE_RESUME )
|
245 mday 1.12 {
|
246 mday 1.19 if ( dest_svc->get_capabilities() & module_capabilities::paused )
|
247 mday 1.18 dispatcher->_make_response(request, async_results::CIM_PAUSED);
248 else
249 dispatcher->_make_response(request, async_results::CIM_STOPPED);
250 accepted = true;
|
251 mday 1.12 }
|
252 mday 1.18 else // deliver the start or resume message
|
253 mike 1.59 if (dest_svc->_die.get() == 0)
|
254 mday 1.18 accepted = dest_svc->accept_async(op);
|
255 mday 1.12 }
|
256 mday 1.14 else
|
257 mike 1.59 if (dest_svc->_die.get() == 0)
|
258 mday 1.18 accepted = dest_svc->accept_async(op);
|
259 mday 1.5 }
|
260 mday 1.10 if ( accepted == false )
261 {
|
262 mday 1.18 // set completion code to NAK and flag completed
263 _complete_op_node(op, ASYNC_OPSTATE_COMPLETE,
264 ASYNC_OPFLAGS_SIMPLE_STATUS,
265 async_results::CIM_NAK);
|
266 mday 1.10 }
|
267 mday 1.7 }
|
268 mday 1.42
|
269 mday 1.5 }
|
270 mday 1.7 } // loop
|
271 kumpf 1.57
|
272 mday 1.5 return(0);
273 }
274
275
|
276 mday 1.1
|
277 david.dillard 1.54 cimom::cimom()
|
278 kumpf 1.33 : MessageQueue(PEGASUS_QUEUENAME_METADISPATCHER, true, CIMOM_Q_ID ),
|
279 chip 1.6 _modules(true),
|
280 mday 1.1 _recycle(true),
|
281 mday 1.24 _routed_ops(true, 0),
|
282 mday 1.7 _internal_ops(true),
|
283 mday 1.5 _routing_thread( _routing_proc, this, false),
|
284 mday 1.10 _die(0), _routed_queue_shutdown(0)
|
285 chip 1.6 {
|
286 mday 1.19 _capabilities |= module_capabilities::async;
287
|
288 mday 1.18 _global_this = static_cast<cimom *>(MessageQueue::lookup(CIMOM_Q_ID));
289
|
290 mday 1.1 pegasus_gettimeofday(&_last_module_change);
291 _default_op_timeout.tv_sec = 30;
292 _default_op_timeout.tv_usec = 100;
|
293 konrad.r 1.58 ThreadStatus tr = PEGASUS_THREAD_OK;
294 while ( (tr = _routing_thread.run()) != PEGASUS_THREAD_OK)
|
295 kumpf 1.50 {
|
296 konrad.r 1.58 if (tr == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
297 pegasus_yield();
298 else
299 throw Exception(MessageLoaderParms("Common.Cimom.NOT_ENOUGH_THREADS",
300 "Cannot allocate thread for Cimom class"));
|
301 kumpf 1.50 }
|
302 chip 1.6
|
303 mday 1.1 }
304
305
|
306 david.dillard 1.54 Uint32 cimom::get_xid()
|
307 mday 1.1 {
308 _xid++;
|
309 mike 1.59 return _xid.get();
|
310 mday 1.1 }
311
|
312 david.dillard 1.54 cimom::~cimom()
|
313 mday 1.1 {
|
314 mday 1.2
315 // send STOP messages to all modules
316 // shutdown legacy queues; e.g., cim operation dispatcher etc.
|
317 mday 1.1 _die++;
|
318 mike 1.59 if (_routed_queue_shutdown.get() == 0 )
|
319 mday 1.10 _routed_ops.shutdown_queue();
|
320 mday 1.5 _routing_thread.join();
|
321 kumpf 1.45
322 while (_modules.count())
323 {
324 delete _modules.remove_first();
325 }
|
326 mday 1.7 _modules.empty_list();
327
|
328 mday 1.1 return;
329 }
|
330 mday 1.12
|
331 mday 1.16 void cimom::_make_response(Message *req, Uint32 code)
|
332 mday 1.12 {
|
333 mday 1.16
334 if ( ! (req->getMask() & message_mask::ha_async) )
335 {
336 // legacy message, just delete
337 delete req;
338 return;
339 }
340
341 if( (static_cast<AsyncRequest *>(req))->op->_flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
342 {
343 // destructor empties request list
344 delete (static_cast<AsyncRequest *>(req))->op;
345 return;
346 }
347
|
348 joyce.j 1.52 AutoPtr<AsyncReply> reply ;
|
349 mday 1.16 if ( ! ((static_cast<AsyncRequest *>(req))->op->_flags & ASYNC_OPFLAGS_SIMPLE_STATUS) )
350 {
|
351 joyce.j 1.52 reply.reset(new AsyncReply(async_messages::REPLY,
|
352 mday 1.16 req->getKey(),
353 req->getRouting(),
354 0,
355 (static_cast<AsyncRequest *>(req))->op,
356 code,
357 (static_cast<AsyncRequest *>(req))->resp,
|
358 joyce.j 1.52 false));
|
359 mday 1.16 }
|
360 mday 1.27 else
|
361 mday 1.16 (static_cast<AsyncRequest *>(req))->op->_completion_code = code;
|
362 mday 1.27 // sender does not want a reply message, just the
363 // _completion_code field in the AsyncOpNode.
364
|
365 mday 1.16
|
366 joyce.j 1.52 _completeAsyncResponse(static_cast<AsyncRequest *>(req), reply.get(), ASYNC_OPSTATE_COMPLETE, 0 );
367 reply.release();
|
368 mday 1.12 }
|
369 mday 1.5
|
370 chip 1.6 void cimom::_completeAsyncResponse(AsyncRequest *request,
371 AsyncReply *reply,
372 Uint32 state,
|
373 mday 1.5 Uint32 flag)
|
374 mday 1.1 {
|
375 kumpf 1.31 PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,
376 "cimom::_completeAsyncResponse");
377
|
378 mday 1.16 PEGASUS_ASSERT(request != 0);
|
379 chip 1.6
|
380 kumpf 1.32 Boolean haveLock = false;
381
|
382 mday 1.5 AsyncOpNode *op = request->op;
|
383 mday 1.1 op->lock();
|
384 kumpf 1.32 haveLock = true;
|
385 mday 1.19
|
386 mday 1.34 if ( (op->_flags & ASYNC_OPFLAGS_CALLBACK ||
387 op->_flags & ASYNC_OPFLAGS_SAFE_CALLBACK ) &&
388 (! (op->_flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)) )
|
389 mday 1.27 {
390 op->unlock();
|
391 kumpf 1.32 haveLock = false;
|
392 mday 1.27 if ( (reply != 0) && (false == op->_response.exists(reinterpret_cast<void *>(reply))) )
393 op->_response.insert_last(reply);
394 _complete_op_node(op, state, flag, (reply ? reply->result : 0 ));
|
395 mday 1.44 return;
|
396 mday 1.27 }
397
398
|
399 mday 1.19 if( op->_flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
400 {
401
402 // destructor empties request list
403 op->unlock();
|
404 kumpf 1.32 haveLock = false;
|
405 mday 1.19
|
406 mday 1.37 op->release();
|
407 mday 1.43 _global_this->cache_op(op);
|
408 mday 1.37
|
409 kumpf 1.31 PEG_METHOD_EXIT();
|
410 mday 1.19 return;
411 }
412
|
413 mday 1.17 op->_state |= (state | ASYNC_OPSTATE_COMPLETE);
|
414 mday 1.5 op->_flags |= flag;
415 gettimeofday(&(op->_updated), NULL);
|
416 mday 1.19 if ( op->_flags & ASYNC_OPFLAGS_SIMPLE_STATUS )
417 {
|
418 mday 1.20 PEGASUS_ASSERT(reply != 0 );
419
|
420 mday 1.19 op->_completion_code = reply->result;
|
421 kumpf 1.31 PEG_METHOD_EXIT();
|
422 mday 1.19 delete reply;
423 }
424 else
425 {
426 if ( (reply != 0) && (false == op->_response.exists(reinterpret_cast<void *>(reply))) )
427 op->_response.insert_last(reply);
428 }
429
|
430 kumpf 1.32 if (haveLock)
431 {
432 op->unlock();
433 haveLock = false;
434 }
|
435 mday 1.7 op->_client_sem.signal();
|
436 kumpf 1.31 PEG_METHOD_EXIT();
|
437 mday 1.1 }
438
|
439 mday 1.18 cimom *cimom::_global_this;
440
441
442 void cimom::_default_callback(AsyncOpNode *op, MessageQueue *q, void *ptr)
443 {
444 PEGASUS_ASSERT(op != 0 && q != 0);
|
445 mday 1.22 return;
|
446 mday 1.18 }
447
448
449 void cimom::_complete_op_node(AsyncOpNode *op, Uint32 state, Uint32 flag, Uint32 code)
450 {
451
452 Uint32 flags;
453
454 op->lock();
455
456 op->_completion_code = code;
457 op->_state |= (state | ASYNC_OPSTATE_COMPLETE);
458 flags = (op->_flags |= flag);
459 op->unlock();
460 if ( flags & ASYNC_OPFLAGS_FIRE_AND_FORGET )
461 {
462 delete op;
463 return;
464 }
465
|
466 mday 1.34 if ( (flags & ASYNC_OPFLAGS_CALLBACK) && (! (flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)))
|
467 mday 1.18 {
|
468 mday 1.47
469 // << Wed Oct 8 12:29:32 2003 mdd >>
470 // check to see if the response queue is stopped or paused
471 if( op->_callback_response_q == 0 ||
472 op->_callback_response_q->get_capabilities() & module_capabilities::paused ||
473 op->_callback_response_q->get_capabilities() & module_capabilities::stopped )
474 {
475 // delete, respondent is paused or stopped
476 delete op;
477 return;
478 }
479
|
480 mday 1.22 // send this node to the response queue
481 op->_op_dest = op->_callback_response_q;
482 _global_this->route_async(op);
|
483 mday 1.18 return;
484 }
|
485 mday 1.34 if((flags & ASYNC_OPFLAGS_SAFE_CALLBACK ) && (! (flags & ASYNC_OPFLAGS_PSEUDO_CALLBACK)))
486 {
|
487 konrad.r 1.55 op->_op_dest = op->_callback_response_q;
488 _global_this->route_async(op);
|
489 mday 1.34 return;
490 }
|
491 mday 1.18 op->_client_sem.signal();
492 return;
493 }
494
|
495 mday 1.1
|
496 david.dillard 1.54 void cimom::handleEnqueue()
|
497 mday 1.1 {
498
499 Message* msg = dequeue();
|
500 chip 1.6
|
501 mday 1.1 if (!msg)
502 return;
|
503 chip 1.6
|
504 mday 1.1 return;
505 }
506
|
507 chip 1.6
|
508 mday 1.11 void cimom::_handle_cimom_op(AsyncOpNode *op, Thread *thread, MessageQueue *queue)
|
509 mday 1.1 {
|
510 mday 1.5 if(op == 0)
|
511 mday 1.1 return;
|
512 mday 1.18
513 // ATTN: optimization << Tue Feb 19 11:33:21 2002 mdd >>
514 // do away with the lock/unlock
|
515 mday 1.9 op->lock();
516 Message *msg = op->_request.next(0);
517 op->unlock();
518
|
519 mday 1.5 if ( msg == 0 )
520 return;
|
521 chip 1.6
|
522 mday 1.5 Boolean accepted = false;
|
523 chip 1.6
|
524 mday 1.1 Uint32 mask = msg->getMask();
525 Uint32 type = msg->getType();
|
526 mday 1.18 if ( ! (mask & message_mask::ha_async) )
527 {
528 _make_response(msg, async_results::CIM_NAK);
529 }
|
530 mday 1.25 op->_thread_ptr = thread;
531 op->_service_ptr = queue;
|
532 mday 1.18
|
533 mday 1.5 if( mask & message_mask::ha_request)
|
534 mday 1.1 {
|
535 mday 1.11 op->processing();
|
536 mday 1.5 accepted = true;
|
537 chip 1.6
|
538 mday 1.5 if( type == async_messages::REGISTER_CIM_SERVICE )
539 register_module(static_cast<RegisterCimService *>(msg));
540 else if ( type == async_messages::UPDATE_CIM_SERVICE )
541 update_module(static_cast<UpdateCimService *>(msg ));
542 else if ( type == async_messages::IOCTL )
543 ioctl(static_cast<AsyncIoctl *>(msg));
544 else if ( type == async_messages::FIND_SERVICE_Q )
545 find_service_q(static_cast<FindServiceQueue *>(msg));
546 else if (type == async_messages::ENUMERATE_SERVICE)
547 enumerate_service(static_cast<EnumerateService *>(msg));
|
548 mday 1.28 else if (type == async_messages::FIND_MODULE_IN_SERVICE)
549 _find_module_in_service(static_cast<FindModuleInService *>(msg));
550 else if (type == async_messages::REGISTERED_MODULE)
551 _registered_module_in_service(static_cast<RegisteredModule *>(msg));
552 else if (type == async_messages::DEREGISTERED_MODULE)
553 _deregistered_module_in_service(static_cast<DeRegisteredModule *>(msg));
|
554 mday 1.5 }
555 if ( accepted == false )
556 {
|
557 mday 1.17 _make_response(msg, async_results::CIM_NAK);
|
558 mday 1.1 }
|
559 chip 1.6
|
560 mday 1.1 }
561
562
563 void cimom::register_module(RegisterCimService *msg)
564 {
565 // first see if the module is already registered
566 Uint32 result = async_results::OK;
567
|
568 chip 1.6
|
569 mday 1.1 if( 0 != get_module_q(msg->name))
570 result = async_results::MODULE_ALREADY_REGISTERED;
|
571 chip 1.6 else
|
572 mday 1.1 {
|
573 chip 1.6
|
574 joyce.j 1.52 AutoPtr<message_module> new_mod(new message_module(msg->name,
|
575 chip 1.6 msg->capabilities,
576 msg->mask,
|
577 joyce.j 1.52 msg->queue));
578 if(new_mod.get() == 0 )
|
579 mday 1.1 result = async_results::INTERNAL_ERROR;
580 else
581 {
582 try
583 {
|
584 joyce.j 1.52 _modules.insert_first(new_mod.get());
|
585 mday 1.1 }
586 catch(IPCException&)
587 {
588 result = async_results::INTERNAL_ERROR;
|
589 joyce.j 1.52 new_mod.reset();
|
590 mday 1.1 }
591 }
|
592 joyce.j 1.52 new_mod.release();
|
593 mday 1.1 }
|
594 chip 1.6
|
595 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply(async_messages::REPLY,
|
596 mday 1.1 msg->getKey(),
597 msg->getRouting(),
|
598 chip 1.6 0,
|
599 mday 1.1 msg->op,
|
600 chip 1.6 result,
601 msg->resp,
|
602 joyce.j 1.52 msg->block));
|
603 chip 1.6
604 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
605 joyce.j 1.52 reply.get(),
|
606 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
607 mday 1.5 0);
|
608 joyce.j 1.52 reply.release();
|
609 mday 1.1 return;
610 }
611
612
|
613 mday 1.3 void cimom::deregister_module(Uint32 quid)
614 {
615
616 _modules.lock();
|
617 chip 1.6
|
618 mday 1.3 message_module *temp = _modules.next(0);
619 while( temp != 0 )
620 {
621 if (temp->_q_id == quid)
622 {
623 _modules.remove_no_lock(temp);
624 break;
625 }
626 temp = _modules.next(temp);
627 }
628 _modules.unlock();
|
629 mday 1.1 }
630
631
632 void cimom::update_module(UpdateCimService *msg )
633 {
634 Uint32 result = async_results::MODULE_NOT_FOUND;
|
635 chip 1.6
|
636 mday 1.1 _modules.lock();
637 message_module *temp = _modules.next(0);
638 while( temp != 0 )
639 {
640 if(temp->_q_id == msg->queue )
641 {
642 temp->_capabilities = msg->capabilities;
643 temp->_mask = msg->mask;
644 gettimeofday(&(temp->_heartbeat), NULL);
645 result = async_results::OK;
646 break;
647 }
648 temp = _modules.next(temp);
649 }
|
650 mday 1.14 _modules.unlock();
|
651 mday 1.1
|
652 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply(async_messages::REPLY,
|
653 chip 1.6 msg->getKey(),
|
654 mday 1.1 msg->getRouting(),
|
655 chip 1.6 0,
656 msg->op,
657 result,
|
658 mday 1.1 msg->resp,
|
659 joyce.j 1.52 msg->block));
|
660 chip 1.6 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
661 joyce.j 1.52 reply.get(),
|
662 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
663 mday 1.5 0);
|
664 joyce.j 1.52 reply.release();
|
665 mday 1.3 return;
|
666 mday 1.1 }
667
668
669 void cimom::ioctl(AsyncIoctl *msg)
670 {
671
|
672 mday 1.11 switch(msg->ctl)
673 {
674 case AsyncIoctl::IO_CLOSE:
675 {
676 // save my bearings
|
677 mday 1.25 Thread *myself = msg->op->_thread_ptr;
678 cimom *service = static_cast<cimom *>(msg->op->_service_ptr);
|
679 mday 1.11
680 // respond to this message.
|
681 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply( async_messages::REPLY,
|
682 mday 1.11 msg->getKey(),
683 msg->getRouting(),
684 0,
685 msg->op,
686 async_results::OK,
687 msg->resp,
|
688 joyce.j 1.52 msg->block));
|
689 mday 1.11 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
690 joyce.j 1.52 reply.get(),
|
691 mday 1.11 ASYNC_OPSTATE_COMPLETE,
692 0);
|
693 joyce.j 1.52 reply.release();
|
694 mday 1.11 // ensure we do not accept any further messages
695
696 // ensure we don't recurse on IO_CLOSE
|
697 mike 1.59 if( _routed_queue_shutdown.get() > 0 )
|
698 mday 1.11 break;
699
700 // set the closing flag
701 service->_routed_queue_shutdown = 1;
702 // empty out the queue
703 while( 1 )
704 {
705 AsyncOpNode *operation;
706 try
707 {
708 operation = service->_routed_ops.remove_first();
709 }
710 catch(IPCException & )
711 {
712 break;
713 }
714 if( operation )
715 {
716 service->_handle_cimom_op(operation, myself, service);
717 }
718 else
719 mday 1.11 break;
720 } // message processing loop
|
721 chip 1.6
|
722 mday 1.11 // shutdown the AsyncDQueue
723 service->_routed_ops.shutdown_queue();
724 // exit the thread !
|
725 kumpf 1.57 _die++;
|
726 mday 1.11 return;
727 }
728
729 default:
730 {
731 Uint32 result = _ioctl(msg->ctl, msg->intp, msg->voidp);
|
732 joyce.j 1.52 AutoPtr<AsyncReply> reply(new AsyncReply( async_messages::REPLY,
|
733 mday 1.11 msg->getKey(),
734 msg->getRouting(),
735 0,
736 msg->op,
737 result,
738 msg->resp,
|
739 joyce.j 1.52 msg->block));
|
740 mday 1.11 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
741 joyce.j 1.52 reply.get(),
|
742 mday 1.11 ASYNC_OPSTATE_COMPLETE,
743 0);
|
744 joyce.j 1.52 reply.release();
|
745 mday 1.11 }
746 }
|
747 mday 1.1 }
748
749
750 Uint32 cimom::_ioctl(Uint32 code, Uint32 int_param, void *pointer_param)
751 {
752 return async_results::OK;
753 }
754
755 // fill an array with queue IDs of as many registered services
756 // as match the request message parameters
757 void cimom::find_service_q(FindServiceQueue *msg)
758 {
759
|
760 chip 1.6
|
761 mday 1.1 Array<Uint32> found;
|
762 chip 1.6
|
763 mday 1.1 _modules.lock();
764 message_module *ret = _modules.next( 0 );
765 while( ret != 0 )
766 {
767 if( msg->name.size() > 0 )
768 {
769 if( msg->name != ret->_name )
770 {
771 ret = _modules.next(ret);
772 continue;
773 }
774 }
775
776 if(msg->capabilities != 0 )
777 {
778 if (! msg->capabilities & ret->_capabilities)
779 {
780 ret = _modules.next(ret);
781 continue;
782 }
783 }
784 mday 1.1 if(msg->mask != 0 )
785 {
786 if ( ! msg->mask & ret->_mask )
787 {
788 ret = _modules.next(ret);
789 continue;
790 }
791 }
|
792 chip 1.6
793 // if we get to here, we "found" this service
|
794 mday 1.1
795 found.append(ret->_q_id);
796 ret = _modules.next(ret);
797 }
798 _modules.unlock();
799
|
800 joyce.j 1.52 AutoPtr<FindServiceQueueResult> reply(
|
801 chip 1.6 new FindServiceQueueResult( msg->getKey(),
802 msg->getRouting(),
803 msg->op,
804 async_results::OK,
805 msg->resp,
806 msg->block,
|
807 joyce.j 1.52 found));
|
808 mday 1.5
|
809 chip 1.6 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
810 joyce.j 1.52 reply.get(),
|
811 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
812 mday 1.5 0);
|
813 joyce.j 1.52 reply.release();
|
814 mday 1.1 return;
815 }
816
817
|
818 chip 1.6 // given a service Queue ID, return all registation data for
819 // that service
|
820 mday 1.1 void cimom::enumerate_service(EnumerateService *msg)
821 {
822
|
823 joyce.j 1.52 AutoPtr<EnumerateServiceResponse> reply;
|
824 mday 1.1 _modules.lock();
825 message_module *ret = _modules.next( 0 );
|
826 chip 1.6
|
827 mday 1.1 while( ret != 0 )
828 {
829 if( ret->_q_id == msg->qid )
830 {
|
831 joyce.j 1.52 reply.reset(new EnumerateServiceResponse(msg->getKey(),
|
832 chip 1.6 msg->getRouting(),
833 msg->op,
834 async_results::OK,
835 msg->resp,
836 msg->block,
837 ret->_name,
838 ret->_capabilities,
839 ret->_mask,
|
840 joyce.j 1.52 ret->_q_id));
|
841 mday 1.1 break;
842 }
843 ret = _modules.next(ret);
844 }
845 _modules.unlock();
|
846 chip 1.6
|
847 joyce.j 1.52 if(reply.get() == 0 )
|
848 mday 1.1 {
|
849 joyce.j 1.52 reply.reset(new EnumerateServiceResponse(msg->getKey(),
|
850 chip 1.6 msg->getRouting(),
851 msg->op,
852 async_results::MODULE_NOT_FOUND,
853 msg->resp,
854 msg->block,
855 String(),
|
856 joyce.j 1.52 0, 0, 0));
|
857 mday 1.1 }
|
858 chip 1.6
859 _completeAsyncResponse(static_cast<AsyncRequest *>(msg),
|
860 joyce.j 1.52 reply.get(),
|
861 chip 1.6 ASYNC_OPSTATE_COMPLETE,
|
862 mday 1.5 0);
|
863 joyce.j 1.52 reply.release();
|
864 mday 1.5
|
865 mday 1.1 return;
866 }
867
868 Uint32 cimom::get_module_q(const String & name)
869 {
870 _modules.lock();
871 message_module *ret = _modules.next( 0 );
872 while( ret != 0 )
873 {
874 if (ret->_name == name)
875 break;
876 ret = _modules.next(ret);
877 }
878
879 _modules.unlock();
880 if(ret != 0 )
881 return ret->_q_id;
882 else
883 return 0 ;
884 }
885
886 mday 1.1
887
888 // returns true if the list of registered modules changes since the parameter
889 Boolean cimom::moduleChange(struct timeval last)
890 {
|
891 chip 1.6 if( (last.tv_sec >= _last_module_change.tv_sec))
|
892 mday 1.1 if(last.tv_usec >= _last_module_change.tv_usec )
893 return false;
894 return true;
895 }
896
897
|
898 david.dillard 1.54 Uint32 cimom::getModuleCount()
|
899 mday 1.1 {
900 return _modules.count();
901 }
902
|
903 david.dillard 1.54 Uint32 cimom::getModuleIDs(Uint32 *ids, Uint32 count)
|
904 mday 1.1 {
905
906 if(ids == 0)
907 return 0;
|
908 chip 1.6
|
909 mday 1.1 message_module *temp = 0;
910 _modules.lock();
911 temp = _modules.next(temp);
912 while( temp != 0 && count > 0 )
913 {
914 *ids = temp->_q_id;
915 ids++;
916 count--;
917 temp = _modules.next(temp);
918 }
919 _modules.unlock();
920
921 while( count > 0 )
922 {
923 *ids = 0;
924 ids++;
925 count--;
926 }
|
927 chip 1.6
|
928 mday 1.1 return _modules.count();
929 }
930
|
931 david.dillard 1.54 AsyncOpNode *cimom::get_cached_op()
|
932 mday 1.1 {
|
933 mday 1.11
|
934 joyce.j 1.52 AutoPtr<AsyncOpNode> op(new AsyncOpNode());
|
935 mday 1.11
936 op->_state = ASYNC_OPSTATE_UNKNOWN;
937 op->_flags = ASYNC_OPFLAGS_SINGLE | ASYNC_OPFLAGS_NORMAL | ASYNC_OPFLAGS_META_DISPATCHER;
938
|
939 joyce.j 1.52 return op.release();
|
940 mday 1.1 }
941
|
942 david.dillard 1.54 void cimom::cache_op(AsyncOpNode *op)
|
943 mday 1.1 {
944 PEGASUS_ASSERT(op->read_state() & ASYNC_OPSTATE_RELEASED );
|
945 mday 1.3 delete op;
|
946 mday 1.1 }
947
948 void cimom::set_default_op_timeout(const struct timeval *buffer)
949 {
950 if (buffer != 0)
951 {
952 _default_op_timeout.tv_sec = buffer->tv_sec;
953 _default_op_timeout.tv_usec = buffer->tv_usec;
954 }
955 return;
956 }
957
|
958 chip 1.6 void cimom::get_default_op_timeout(struct timeval *timeout) const
|
959 mday 1.1 {
960 if (timeout != 0)
961 {
962 timeout->tv_sec = _default_op_timeout.tv_sec;
963 timeout->tv_usec = _default_op_timeout.tv_usec;
964 }
965 return;
966 }
|
967 mday 1.27
968 void cimom::_registered_module_in_service(RegisteredModule *msg)
969 {
970 Uint32 result = async_results::MODULE_NOT_FOUND;
971
972 _modules.lock();
973 message_module *ret = _modules.next( 0 );
974 while( ret != 0 )
975 {
976 if (ret->_q_id == msg->resp)
977 {
978 // see if the module is already registered
979 Uint32 i = 0;
980 for( ; i < ret->_modules.size() ; i++ )
981 {
|
982 mday 1.28 if( ret->_modules[i] == msg->_module )
|
983 mday 1.27 {
984 result = async_results::MODULE_ALREADY_REGISTERED;;
985 break;
986 }
987 }
988 if ( result != async_results::MODULE_ALREADY_REGISTERED)
989 {
990 ret->_modules.append(msg->_module);
991 result = async_results::OK;
992 }
993 break;
994 }
995 ret = _modules.next(ret);
996 }
997 _modules.unlock();
998 _make_response(msg, result);
999 }
1000
1001 void cimom::_deregistered_module_in_service(DeRegisteredModule *msg)
1002 {
1003 Uint32 result = async_results::MODULE_NOT_FOUND;
1004 mday 1.27
1005 _modules.lock();
1006 message_module *ret = _modules.next( 0 );
1007 while( ret != 0 )
1008 {
1009 if (ret->_q_id == msg->resp)
1010 {
1011 Uint32 i = 0;
1012 for( ; i < ret->_modules.size() ; i++ )
1013 {
1014 if( ret->_modules[i] == msg->_module )
1015 {
1016 ret->_modules.remove(i);
1017 result = async_results::OK;
1018 break;
1019 }
1020 }
1021 }
1022 ret = _modules.next(ret);
1023 }
1024 _modules.unlock();
1025 mday 1.27 _make_response(msg, result);
1026 }
1027
1028 void cimom::_find_module_in_service(FindModuleInService *msg)
1029 {
1030 Uint32 result = async_results::MODULE_NOT_FOUND;
1031 Uint32 q_id = 0;
1032
1033 _modules.lock();
1034 message_module *ret = _modules.next( 0 );
1035 while( ret != 0 )
1036 {
|
1037 mday 1.28 if ( ret->get_capabilities() & module_capabilities::module_controller)
|
1038 mday 1.27 {
|
1039 mday 1.28 // see if the module is in this service
1040 Uint32 i = 0;
1041 for( ; i < ret->_modules.size() ; i++ )
|
1042 mday 1.27 {
|
1043 mday 1.28 if( ret->_modules[i] == msg->_module )
1044 {
1045 result = async_results::OK;
1046 q_id = ret->_q_id;
|
1047 mday 1.27 break;
|
1048 mday 1.28 }
|
1049 mday 1.27 }
1050 }
1051 ret = _modules.next(ret);
1052 }
1053 _modules.unlock();
1054
1055 FindModuleInServiceResponse *response =
1056 new FindModuleInServiceResponse(msg->getRouting(),
1057 msg->getKey(),
1058 msg->op,
1059 result,
1060 msg->resp,
1061 msg->block,
1062 q_id);
1063
1064 _complete_op_node(msg->op,
1065 ASYNC_OPSTATE_COMPLETE,
1066 0,
1067 result);
1068 }
1069
1070 mday 1.27
|
1071 mday 1.1
1072 PEGASUS_NAMESPACE_END
1073
1074
1075
|