从Quagga到DCE的处理流程

Helper是Quagga的抓手,而Application是具体的实现。这从HOWTO_create_a_traffic_generator可以看出来。

QuaggaHelper 使用了DceApplicationHelper

ApplicationContainer
QuaggaHelper::InstallPriv (Ptr<Node> node)
{
  DceApplicationHelper process;
  ApplicationContainer apps;

  Ptr<QuaggaConfig> zebra_conf = node->GetObject<QuaggaConfig> ();
  if (!zebra_conf)
    {
      zebra_conf = new QuaggaConfig ();
      node->AggregateObject (zebra_conf);
    }
  GenerateConfigZebra (node);
  process.SetBinary ("zebra");
  process.AddArguments ("-f", zebra_conf->GetFilename ());
  process.AddArguments ("-i", "/usr/local/etc/zebra.pid");
  process.SetStackSize (1 << 16);
  apps.Add (process.Install (node));
  apps.Get (0)->SetStartTime (Seconds (1.0 + 0.01 * node->GetId ()));
  node->AddApplication (apps.Get (0));

  Ptr<OspfConfig> ospf_conf = node->GetObject<OspfConfig> ();
  // OSPF
  if (ospf_conf)
    {

而后者的实现中使用了DceApplication

ApplicationContainer
DceApplicationHelper::InstallInNode (Ptr<Node> node)
{
  NS_LOG_FUNCTION (this);
  ApplicationContainer apps;
      Ptr<DceApplication> dce = CreateObject<DceApplication> ();
      dce->SetBinary (m_filename);
      dce->SetStackSize (m_stackSize);
      dce->SetArguments (m_args);
      dce->SetEnvironment (m_envs);
      dce->SetStdinFile (m_stdinFilename);
      dce->SetUid (m_uid);
      dce->SetEuid (m_euid);
      if (!m_finishedCallback.IsNull ())
        {
          dce->SetFinishedCallback (m_finishedCallback);
        }
      node->AddApplication (dce);
      apps.Add (dce);

  return apps;
}

DceApplication的启动如下,

void
DceApplication::StartApplication (void)
{
  NS_LOG_FUNCTION (this);

  Ptr<Node> node = GetNode ();
  Ptr<DceManager> manager = node->GetObject<DceManager> ();
  if (manager == 0)
    {
      NS_FATAL_ERROR ("You forgot to aggregate a DceManager to node=" << node->GetId ());
    }
  if (m_stackSize != 0)
    {
      m_pid = manager->Start (m_filename, m_stdinFilename, m_stackSize, m_args,
                              m_envs, m_uid, m_euid, m_gid, m_egid);
    }
  else
    {
      m_pid = manager->Start (m_filename, m_stdinFilename, m_args, m_envs,
                              m_uid, m_euid, m_gid, m_egid);
    }
  if (!m_finishedCallback.IsNull ())
    {
      manager->SetFinishedCallback (m_pid, m_finishedCallback);
    }
  m_dceStarted (m_pid);
}

启动程序又调用到DceManager


uint16_t
DceManager::Start (std::string name, std::string stdinfilename, std::vector<std::string> args,
                   std::vector<std::pair<std::string,std::string> > envs,
                   uid_t uid, uid_t euid, uid_t gid, uid_t egid)
{
  NS_LOG_FUNCTION (this << name << args.size ());
  struct Process *process = CreateProcess (name, stdinfilename, args, envs, 0);
  process->ruid = uid;
  process->euid = euid;
  process->rgid = gid;
  process->egid = egid;
  struct Thread *thread = CreateThread (process);
  Task *task = TaskManager::Current ()->Start (&DceManager::DoStartProcess, thread);
  task->SetContext (thread);
  task->SetSwitchNotifier (&DceManager::TaskSwitch, process);
  thread->task = task;
  return process->pid;
}

启动进程即
DceManager::DoStartProcess

此后代码会一直走到

Manager::LoadMain


你可能感兴趣的:(从Quagga到DCE的处理流程)