Beispiel #1
0
int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf("Please input file\n");
        return STAT_OK;
    }

    int i = 0;

    for (i = 1; i < argc; i++)
    {
        check_stat(argv[i]);
    }

    return STAT_OK;
}
void	execute_from_asked_dir(char *cmd, char **env, char *cmd_args)
{
	if (check_stat(cmd, 1))
		launch_process_from_asked_dir(cmd, cmd_args, env);
}
Beispiel #3
0
int handle_process(metric_type_t metric, task_option_t *options, char *id) {
  int keepalive = 0;
  uint16_t pid;
  char *pidfile, *runcmd;
  task_report_t report;
  init_task_report(&report, id, PROCESS, metric);

  // Pull out options.
  // FIXME: Need to go over this again to make sure all necessary validation of parameters
  // is performed.
  for (int i = 0; i < NOTGIOS_MAX_OPTIONS; i++) {
    task_option_t *option = &options[i];
    switch (option->type) {
      case KEEPALIVE:
        keepalive = strcmp(option->value, "TRUE") ? 0 : 1;
        break;
      case PIDFILE:
        pidfile = option->value;
        break;
      case RUNCMD:
        runcmd = option->value;
        break;
      case EMPTY:
        // User chose not to specify an option. This is fine, move on.
        break;
      default:
        // We've been passed a task containing invalid options. Shouldn't happen, but handle
        // it for debugging.
        sprintf(report.message, "FATAL CAUSE INVALID_TASK");
        lpush(&reports, &report);
        return NOTGIOS_GENERIC_ERROR;
    }
  }
  write_log(LOG_DEBUG, "Task %s: Finished parsing arguments for process task...\n", id);

  // Figure out process running/not running situation.
  if (keepalive) {
    FILE *file = fopen(pidfile, "w+");
    if (!file) {
      // We cannot write to the given pidfile path. Most likely the directory just
      // doesn't exist, but I'm defining this as an unrecoverable error, so send a message
      // to the frontend and remove the task.
      write_log(LOG_ERR, "Task %s: Pidfile inaccessible for keepalive process...\n", id);
      sprintf(report.message, "FATAL CAUSE NO_PIDFILE");
      lpush(&reports,  &report);
      return NOTGIOS_TASK_FATAL;
    }
    write_log(LOG_DEBUG, "Task %s: Successfully opened pidfile for keepalive process...\n", id);

    uint16_t *tmp_pid = hash_get(&children, id);
    if (tmp_pid) {
      write_log(LOG_DEBUG, "Task %s: Keepalive Process is already running...\n", id);
      pid = *tmp_pid;
      fprintf(file, "%hu", pid);
    } else {
      pid = fork();
      if (pid) {
        write_log(LOG_DEBUG, "Task %s: Forked...\n", id);
        uint16_t *pid_cpy = malloc(sizeof(uint16_t));
        *pid_cpy = pid;

        // Put the new pid into the children hash, update the pidfile, and just make
        // sure we aren't doing all of this for nothing.
        int retval = hash_put(&children, id, pid_cpy);
        fprintf(file, "%hu", pid);
        if (retval == HASH_FROZEN) return NOTGIOS_IN_SHUTDOWN;
      } else {
        int elem = 0;
        char *args[NOTGIOS_MAX_ARGS];
        memset(args, 0, sizeof(char *) * NOTGIOS_MAX_ARGS);

        // Just sleep for a tiny bit to make sure our pid got into the children table.
        // No validation has been done on the run command, so, odds are, it won't work
        // and exec will fail. If so, need to make sure our pid is in the children table
        // so that the SIGCHLD handler will know what to do with our exit status.
        sleep(0.1);

        // Get our base command and arguments.
        char *path = strtok(runcmd, "\t"), *arg;
        while ((arg = strtok(NULL, "\t")) && elem < NOTGIOS_MAX_ARGS) args[elem++] = arg;

        // Moment of truth!
        execv(path, args);
        exit(NOTGIOS_EXEC_FAILED);
      }
    }
    fclose(file);
  } else {
    uint16_t other_pid;
    FILE *file = fopen(pidfile, "r");
    if (file) {
      // We can access the file.
      int retval = fscanf(file, "%hu", &other_pid);
      fclose(file);
      write_log(LOG_DEBUG, "Task %s: Got pid for watched process...\n", id);

      if (retval && retval != EOF) {
        // We read the pid successfully.
        retval = kill(other_pid, 0);
        if (!retval) {
          // The process is running!
          write_log(LOG_DEBUG, "Task %s: Watched process is still running...\n", id);
          pid = other_pid;
        } else {
          // The process is not currently running, enqueue a report saying this, then return.
          write_log(LOG_ERR, "Task %s: Kill revealed watched process is not running...\n", id);
          sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING");
          lpush(&reports, &report);
          return NOTGIOS_SUCCESS;
        }
      } else {
        // The process is not currently running, enqueue a report saying this, then return.
        write_log(LOG_ERR, "Task %s: Pidfile not formatted correctly for watched process...\n", id);
        sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING");
        lpush(&reports, &report);
        return NOTGIOS_SUCCESS;
      }
    } else {
      // We can't access the file. I'm defining this as an unrecoverable error, so
      // send a message to the frontend, and then remove the task.
      write_log(LOG_ERR, "Task %s: Pidfile not accessible for watched process...\n", id);
      sprintf(report.message, "FATAL CAUSE NO_PIDFILE");
      lpush(&reports, &report);
      return NOTGIOS_TASK_FATAL;
    }
  }

  // Collect metrics.
  int retval;
  switch (metric) {
    case MEMORY:
      retval = process_memory_collect(pid, &report);
      if (retval == NOTGIOS_NOPROC && keepalive) {
        if (check_statm()) {
          // FIXME: This was written before the child handler was figured out. Could need to revisit this
          // after implementing the child handler.
          // Since we're keeping alive, this most likely means that the user gave us an invalid command.
          // Send an error message, and the frontend will eventually kill the task if necessary.
          write_log(LOG_ERR, "Task %s: Watched/Keepalive process is not running for collection...\n", id);
          sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING");
        } else {
          // We can't even read from /proc/self/statm, which should be guaranteed to work on any version of
          // linux that supports statm at all. Let the front end know that we're running on an unsupported
          // distro.
          RETURN_UNSUPPORTED_DISTRO(report, id);
        } 
      } else {
        write_log(LOG_DEBUG, "Task %s: Memory info collected...\n", id);
      }
      break;
    case CPU:
      retval = process_cpu_collect(pid, &report);
      if (retval == NOTGIOS_NOPROC) {
        if (check_stat()) {
          write_log(LOG_ERR, "Task %s: Watched/Keepalive process is not running for collection...\n", id);
          sprintf(report.message, "ERROR CAUSE PROC_NOT_RUNNING");
        } else {
          // We can't even read from /proc/self/stat, which means it either doesn't exist, or we don't
          // support the format it's using. Either way, we're done.
          RETURN_UNSUPPORTED_DISTRO(report, id);
        }
      } else if (retval == NOTGIOS_UNSUPP_DISTRO) {
        // Collection function encountered an error condition that suggests we're running on an
        // unsupported distro.
        RETURN_UNSUPPORTED_DISTRO(report, id);
      } else {
        write_log(LOG_DEBUG, "Task %s: CPU Time collected...\n", id);
      }
      break;
    case IO:
      // This is currently unimplemented.
      retval = process_io_collect(pid, &report);
      break;
    default:
      // We've been passed a task containing invalid options. Shouldn't happen, but handle it
      // for debugging.
      sprintf(report.message, "FATAL CAUSE INVALID_TASK");
      lpush(&reports, &report);
      return NOTGIOS_GENERIC_ERROR;
  }

  if (retval == NOTGIOS_UNSUPP_TASK) {
    write_log(LOG_DEBUG, "Task %s: Received an unsupported task. Removing...");
    sprintf(report.message, "FATAL CAUSE UNSUPPORTED_TASK");
    lpush(&reports, &report);
    return NOTGIOS_TASK_FATAL;
  }

  // Enqueue metrics for sending.
  write_log(LOG_DEBUG, "Task %s: Enqueuing report and returning...\n", id);
  lpush(&reports, &report);
  return NOTGIOS_SUCCESS;
}