Example #1
0
static void analyze_message(hs_analysis_thread* at)
{
  hs_sandbox* sb = NULL;
  bool sample = at->plugins->sample;
  int ret;

  pthread_mutex_lock(&at->list_lock);
  for (int i = 0; i < at->list_cap; ++i) {
    if (!at->list[i]) continue;
    sb = at->list[i]->sb;

    ret = 0;
    struct timespec ts, ts1;

    if (at->msg->msg) { // non idle/empty message
      if (sample) clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
      at->matched = hs_eval_message_matcher(sb->mm, at->msg);
      if (sample) {
        clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1);
        hs_update_running_stats(&sb->stats.mm, hs_timespec_delta(&ts, &ts1));
      }
      if (at->matched) {
        ret = hs_process_message(sb->lsb, NULL);
        if (sample) {
          clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
          hs_update_running_stats(&sb->stats.pm, hs_timespec_delta(&ts1,
                                                                   &ts));
        }

        ++sb->stats.pm_cnt;
        if (ret < 0) {
          ++sb->stats.pm_failures;
        }
      }
    }

    if (ret <= 0 && sb->ticker_interval
        && at->current_t >= sb->next_timer_event) {
      clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
      ret = hs_timer_event(sb->lsb, at->current_t);
      clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1);
      hs_update_running_stats(&sb->stats.te, hs_timespec_delta(&ts, &ts1));
      sb->next_timer_event = at->current_t + sb->ticker_interval;
    }

    if (ret > 0) terminate_sandbox(at, i);
  }
  pthread_mutex_unlock(&at->list_lock);
}
Example #2
0
static int output_message(hs_output_plugin* p)
{
  int ret = 0, te_ret = 0;
  bool sample = p->sample;
  time_t current_t = time(NULL);
  p->matched = false;

  struct timespec ts, ts1;
  double delta = 0;
  size_t sequence_id = 0;

  if (p->msg->msg) { // non idle/empty message
    double mmdelta = 0;
    if (sample) clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
    p->matched = hs_eval_message_matcher(p->sb->mm, p->msg);
    if (sample) {
      clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1);
      mmdelta = hs_timespec_delta(&ts, &ts1);
    }
    if (p->matched) {
      if (p->async_len) {
        sequence_id = p->sb->stats.pm_cnt + 1;
        int i = sequence_id % p->async_len;
        p->async_cp[i].input.id = p->cur.input.id;
        p->async_cp[i].input.offset = p->cur.input.offset;
        p->async_cp[i].analysis.id = p->cur.analysis.id;
        p->async_cp[i].analysis.offset = p->cur.analysis.offset;
      }
      ret = hs_process_message(p->sb->lsb, (void*)(sequence_id));
      if (sample) {
        clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
        delta = hs_timespec_delta(&ts1, &ts);
      }
      if (ret <= 0) {
        pthread_mutex_lock(&p->cp_lock);
        switch (ret) {
        case 0: // sent
          ++p->sb->stats.pm_cnt;
          p->batching = false;
          break;
        case -1: // failure
          ++p->sb->stats.pm_cnt;
          ++p->sb->stats.pm_failures;
          break;
        case -2: // skip
          ++p->sb->stats.pm_cnt;
          break;
        case -3: // retry
          break;
        case -5: // async update
          if (!p->async_len) {
            lsb_terminate(p->sb->lsb, "cannot use async checkpointing without"
                          " a configured buffer");
            ret = 1;
          }
          // fall thru
        case -4: // batching
          ++p->sb->stats.pm_cnt;
          p->batching = true;
          break;
        default:
          lsb_terminate(p->sb->lsb, "invalid process_message return status");
          ret = 1;
          break;
        }

        // update the stats
        if (sample) {
          hs_update_running_stats(&p->sb->stats.mm, mmdelta);
          hs_update_running_stats(&p->sb->stats.pm, delta);
          p->sample = false;
          mmdelta = 0;
        }
        p->sb->stats.cur_memory = lsb_usage(p->sb->lsb, LSB_UT_MEMORY,
                                            LSB_US_CURRENT);
        p->sb->stats.max_memory = lsb_usage(p->sb->lsb, LSB_UT_MEMORY,
                                            LSB_US_MAXIMUM);
        p->sb->stats.max_output = lsb_usage(p->sb->lsb, LSB_UT_OUTPUT,
                                            LSB_US_MAXIMUM);
        p->sb->stats.max_instructions = lsb_usage(p->sb->lsb,
                                                  LSB_UT_INSTRUCTION,
                                                  LSB_US_MAXIMUM);
        pthread_mutex_unlock(&p->cp_lock);

        if (ret == -1) {
          const char* err = lsb_get_error(p->sb->lsb);
          if (strlen(err) > 0) {
            hs_log(g_module, 4, "file: %s received: %d %s", p->sb->name, ret,
                   lsb_get_error(p->sb->lsb));
          }
        }
      }
    }

    // advance the checkpoint if not batching/async
    if (ret <= 0 && !p->batching) {
      pthread_mutex_lock(&p->cp_lock);
      p->cp.input.id = p->cur.input.id;
      p->cp.input.offset = p->cur.input.offset;
      p->cp.analysis.id = p->cur.analysis.id;
      p->cp.analysis.offset = p->cur.analysis.offset;
      pthread_mutex_unlock(&p->cp_lock);
    }

    if (mmdelta) {
      pthread_mutex_lock(&p->cp_lock);
      hs_update_running_stats(&p->sb->stats.mm, mmdelta);
      p->sample = false;
      pthread_mutex_unlock(&p->cp_lock);
    }
  }

  if (ret <= 0 && p->sb->ticker_interval
      && current_t >= p->sb->next_timer_event) {
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
    te_ret = hs_timer_event(p->sb->lsb, current_t);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts1);

    delta = hs_timespec_delta(&ts, &ts1);
    pthread_mutex_lock(&p->cp_lock);
    hs_update_running_stats(&p->sb->stats.te, delta);
    pthread_mutex_unlock(&p->cp_lock);

    p->sb->next_timer_event = current_t + p->sb->ticker_interval;
  }

  if (ret > 0 || te_ret > 0) {
    hs_log(g_module, 3, "terminated: %s msg: %s", p->sb->name,
           lsb_get_error(p->sb->lsb));
    return 1;
  }
  return ret;
}