Exemple #1
0
void LightProcess::Initialize(const std::string &prefix, int count,
                              const std::vector<int> &inherited_fds) {
  if (prefix.empty() || count <= 0) {
    return;
  }

  if (Available()) {
    // already initialized
    return;
  }

  g_procs.reset(new LightProcess[count]);
  g_procsCount = count;

  auto afdt_filename = folly::sformat("{}.{}", prefix, getpid());

  // remove the possible leftover
  remove(afdt_filename.c_str());

  afdt_error_t err = AFDT_ERROR_T_INIT;
  auto afdt_lid = afdt_listen(afdt_filename.c_str(), &err);
  if (afdt_lid < 0) {
    Logger::Warning("Unable to afdt_listen to %s: %d %s",
                    afdt_filename.c_str(),
                    errno, folly::errnoStr(errno).c_str());
    return;
  }

  SCOPE_EXIT {
    ::close(afdt_lid);
    remove(afdt_filename.c_str());
  };

  for (int i = 0; i < count; i++) {
    if (!g_procs[i].initShadow(afdt_lid, afdt_filename, i, inherited_fds)) {
      for (int j = 0; j < i; j++) {
        g_procs[j].closeShadow();
      }
      g_procs.reset();
      g_procsCount = 0;
      break;
    }
  }

  if (!s_handlerInited) {
    struct sigaction sa;
    struct sigaction old_sa;
    sa.sa_sigaction = &LightProcess::SigChldHandler;
    sa.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
    if (sigaction(SIGCHLD, &sa, &old_sa) != 0) {
      Logger::Error("Couldn't install SIGCHLD handler");
      abort();
    }
    s_handlerInited = true;
  }
}
int afdt_create_server(
    const char* fname,
    struct event_base* eb,
    afdt_request_handler_t request_handler,
    afdt_post_handler_t post_handler,
    afdt_error_handler_t error_handler,
    void** out_close_handle,
    void* userdata
) {
    int ret;

    struct afdt_error_t err = AFDT_ERROR_T_INIT;
    err.phase = AFDT_CREATE_SERVER;


    struct ev_arg* ev_userdata = malloc(sizeof(*ev_userdata));
    if (ev_userdata == NULL) {
        set_error(&err, AFDT_MALLOC, "");
        error_handler(&err, userdata);
        return -1;
    }
    ev_userdata->eb = eb;
    ev_userdata->request_handler = request_handler;
    ev_userdata->response_handler = NULL;
    ev_userdata->post_handler = post_handler;
    ev_userdata->error_handler = error_handler;
    ev_userdata->afdt_userdata = userdata;


    ret = afdt_listen(fname, &err);
    if (ret < 0) {
        goto destruct;
    }
    int acceptfd = ret;

    enum afdt_operation err_op = AFDT_NO_OPERATION;
    event_set(&ev_userdata->ev, acceptfd, EV_READ | EV_PERSIST, server_handle_accept_read, ev_userdata);
    ret = event_bsa(eb, &ev_userdata->ev, NULL, &err_op);
    if (ret < 0) {
        set_error(&err, err_op, "");
        goto destruct;
    }

    if (out_close_handle != NULL) {
        *out_close_handle = ev_userdata;
    }
    return 0;

destruct:
    error_handler(&err, userdata);
    free(ev_userdata);
    return ret;
}
Exemple #3
0
bool LightProcess::initShadow(const std::string &prefix, int id,
                              const std::vector<int> &inherited_fds) {
  Lock lock(m_procMutex);

  std::ostringstream os;
  os << prefix << "." << getpid() << "." << id;
  m_afdtFilename = os.str();

  // remove the possible leftover
  remove(m_afdtFilename.c_str());

  afdt_error_t err;
  m_afdt_lfd = afdt_listen(m_afdtFilename.c_str(), &err);
  if (m_afdt_lfd < 0) {
    Logger::Warning("Unable to afdt_listen to %s: %d %s",
                    m_afdtFilename.c_str(),
                    errno, folly::errnoStr(errno).c_str());
    return false;
  }

  CPipe p1, p2;
  if (!p1.open() || !p2.open()) {
    Logger::Warning("Unable to create pipe: %d %s", errno,
                    folly::errnoStr(errno).c_str());
    return false;
  }

  pid_t child = fork();
  if (child == 0) {
    // child
    pid_t sid = setsid();
    if (sid < 0) {
      Logger::Warning("Unable to setsid");
      exit(-1);
    }
    m_afdt_fd = afdt_connect(m_afdtFilename.c_str(), &err);
    if (m_afdt_fd < 0) {
      Logger::Warning("Unable to afdt_connect, filename %s: %d %s",
                      m_afdtFilename.c_str(),
                      errno, folly::errnoStr(errno).c_str());
      exit(-1);
    }
    int fd1 = p1.detachOut();
    int fd2 = p2.detachIn();
    p1.close();
    p2.close();

    // don't hold on to previous light processes' pipes, inherited
    // fds, or the afdt listening socket
    for (int i = 0; i < id; i++) {
      g_procs[i].closeFiles();
    }
    close_fds(inherited_fds);
    ::close(m_afdt_lfd);

    runShadow(fd1, fd2);
  } else if (child < 0) {
    // failed
    Logger::Warning("Unable to fork lightly: %d %s", errno,
                    folly::errnoStr(errno).c_str());
    return false;
  } else {
    // parent
    m_fin = fdopen(p2.detachOut(), "r");
    m_fout = fdopen(p1.detachIn(), "w");
    m_shadowProcess = child;

    sockaddr addr;
    socklen_t addrlen = sizeof(addr);
    m_afdt_fd = accept(m_afdt_lfd, &addr, &addrlen);
    if (m_afdt_fd < 0) {
      Logger::Warning("Unable to establish afdt connection: %d %s",
                      errno, folly::errnoStr(errno).c_str());
      closeShadow();
      return false;
    }
  }
  return true;
}