(file) Return to Cimom.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2