bool DirectorCore::buildProcessMap(void) noexcept
{
  // search existing processes for those we should be managing (not 100% foolproof)
  process_state_t state;
  std::set<pid_t> pidlist;
  const pid_t thispid = posix::getpid();
  if(proclist(pidlist) == posix::success_response)
  {
    for(pid_t pid : pidlist)
    {
      posix::memset(reinterpret_cast<void*>(&state), 0, sizeof(state));
      if(procstat(pid, state) && // if get process state works AND
         (!state.parent_process_id || state.parent_process_id == thispid)) // process has unknown parent process OR director is the parent process
        for(const std::string& config : getConfigList()) // try each config
          if(getConfigValue(config, "/Process/Executable") == state.executable) // if the executable matches
          {
            m_process_map[config]->add(thispid, pid); // claim this as a managed process
            posix::memset(reinterpret_cast<void*>(&state), 0, sizeof(state)); // wipe process state for safety
            for(pid_t childpid : pidlist)
              if(procstat(childpid, state) && // if get process state works AND
                 state.parent_process_id == pid) // process is a child of this parent pid
                m_process_map[config]->add(pid, childpid); // claim this as a managed process
          }
    }
    return true;
  }
  return false;
}
Exemple #2
0
bool ProxyHost(EDF *pEDF)
{
   debug(DEBUGLEVEL_INFO, "ProxyHost entry\n");

#ifndef FreeBSD
   int iPID = 0, iPPID = 0, iSession = 0, iPrevSession = 0;
   struct utmp *pEntry = NULL;

   // printf("tty %s\n", ttyname(0));

   // szHost[0] = '\0';
   // if(utmpscan(-1, szHost) == false)
   pEntry = utmpscan(-1);
   if(pEntry == NULL)
   {
      // Couldn't find this process

      debug(DEBUGLEVEL_ERR, "ProxyHost exit false, utmpscan failed\n");
      return false;
   }

   debug(DEBUGLEVEL_INFO, "ProxyHost host '%s'\n", pEntry->ut_host);
   if(strchr(pEntry->ut_host, ':') != NULL)
   {
      debug(DEBUGLEVEL_INFO, "ProxyHost parent check\n");

      iPID = getppid();
      while(iPID != 0 && procstat(iPID, &iPPID, &iSession) == true)
      {
         debug(DEBUGLEVEL_INFO, "ProxyHost %d (parent %d, session %d)\n", iPID, iPPID, iSession);
         if(iPrevSession == iSession)
         {
            // szHost[0] = '\0';
            pEntry = utmpscan(iSession);
            ProxyHostEntry(pEDF, pEntry);

            iPID = 0;
         }
         else
         {
            iPrevSession = iSession;
            iPID = iPPID;
         }
      }
   }
   else
   {
      ProxyHostEntry(pEDF, pEntry);
   }
#endif

   debug(DEBUGLEVEL_INFO, "ProxyHost exit true\n");
   return true;
}
Exemple #3
0
static void
register_child(pid_t parent, pid_t child)
{
    embht_table *ht = get_pid_table(parent, 1);
    embht_entry *ent;
    struct procstat pstb;

    assert(ht);

    if ( procstat(child, &pstb) != 0 ) {
        fprintf(stderr, "Orphand: procstat(%d) failed with %d,%d\n",
                child, pstb.lib_error, pstb.sys_error);
        return;
    }

    ent = embht_fetchi(ht, child, 1);
    *(uint64_t*)(ent->u_value.value) = pstb.pst_starttime;
}
Exemple #4
0
int
photoproc(struct tstat *tasklist, int maxtask)
{
	static int			firstcall = 1;
	static unsigned long long	bootepoch;

	register struct tstat	*curtask;

	FILE		*fp;
	DIR		*dirp;
	struct dirent	*entp;
	char		origdir[1024];
	int		tval=0;

	/*
	** one-time initialization stuff
	*/
	if (firstcall)
	{
		/*
		** check if this kernel offers io-statistics per task
		*/
		regainrootprivs();

		if ( (fp = fopen("/proc/1/io", "r")) )
		{
			supportflags |= IOSTAT;
			fclose(fp);
		}

		if (! droprootprivs())
			cleanstop(42);

		/*
 		** find epoch time of boot moment
		*/
		bootepoch = getboot();

		firstcall = 0;
	}

	/*
	** probe if the netatop module and (optionally) the
	** netatopd daemon are active
	*/
	regainrootprivs();

	netatop_probe();

	if (! droprootprivs())
		cleanstop(42);

	/*
	** read all subdirectory-names below the /proc directory
	*/
	if ( getcwd(origdir, sizeof origdir) == NULL)
		cleanstop(53);

	if ( chdir("/proc") == -1)
		cleanstop(53);

	dirp = opendir(".");

	while ( (entp = readdir(dirp)) && tval < maxtask )
	{
		/*
		** skip non-numerical names
		*/
		if (!isdigit(entp->d_name[0]))
			continue;

		/*
		** change to the process' subdirectory
		*/
		if ( chdir(entp->d_name) != 0 )
			continue;

		/*
 		** gather process-level information
		*/
		curtask	= tasklist+tval;

		if ( !procstat(curtask, bootepoch, 1)) /* from /proc/pid/stat */
		{
			if ( chdir("..") == -1);
			continue;
		}

		if ( !procstatus(curtask) )	    /* from /proc/pid/status  */
		{
			if ( chdir("..") == -1);
			continue;
		}

		if ( !procio(curtask) )		    /* from /proc/pid/io      */
		{
			if ( chdir("..") == -1);
			continue;
		}

		proccmd(curtask);		    /* from /proc/pid/cmdline */

		// read network stats from netatop
		netatop_gettask(curtask->gen.tgid, 'g', curtask);

		tval++;		/* increment for process-level info */

		/*
 		** if needed (when number of threads is larger than 0):
		**   read and fill new entries with thread-level info
		*/
		if (curtask->gen.nthr > 1)
		{
			DIR		*dirtask;
			struct dirent	*tent;

			curtask->gen.nthrrun  = 0;
			curtask->gen.nthrslpi = 0;
			curtask->gen.nthrslpu = 0;
			
			/*
			** open underlying task directory
			*/
			if ( chdir("task") == 0 )
			{
				dirtask = opendir(".");
	
				while ((tent=readdir(dirtask)) && tval<maxtask)
				{
					struct tstat *curthr = tasklist+tval;

					/*
					** change to the thread's subdirectory
					*/
					if ( tent->d_name[0] == '.'  ||
					     chdir(tent->d_name) != 0 )
						continue;

					if ( !procstat(curthr, bootepoch, 0))
					{
						if ( chdir("..") == -1);
						continue;
					}
			
					if ( !procstatus(curthr) )
					{
						if ( chdir("..") == -1);
						continue;
					}

					if ( !procio(curthr) )
					{
						if ( chdir("..") == -1);
						continue;
					}

					switch (curthr->gen.state)
					{
	   		   		   case 'R':
						curtask->gen.nthrrun  += 1;
						break;
	   		   		   case 'S':
						curtask->gen.nthrslpi += 1;
						break;
	   		   		   case 'D':
						curtask->gen.nthrslpu += 1;
						break;
					}

					curthr->gen.nthr = 1;

					// read network stats from netatop
					netatop_gettask(curthr->gen.pid, 't',
									curthr);

					// all stats read now
					tval++;	    /* increment thread-level */
					if ( chdir("..") == -1); /* thread */
				}

				closedir(dirtask);
				if ( chdir("..") == -1); /* leave task */
			}
		}

		if ( chdir("..") == -1); /* leave process-level directry */
	}

	closedir(dirp);

	if ( chdir(origdir) == -1)
		cleanstop(53);

	return tval;
}
Exemple #5
0
static void
sweep(void)
{
    embht_iterator parents_iter;
    embht_iterinit(Server.ht, &parents_iter);

    while (embht_iternext(&parents_iter)) {
        embht_table *children_ht;
        embht_entry *children_hb;
        embht_iterator child_iter;
        struct procstat pstb;

        children_hb = embht_itercur(&parents_iter);
        pid_t parent_pid = children_hb->key.u_kdata.kd32;
        children_ht = children_hb->u_value.ptr;

        DEBUG("Checking children of %d", parent_pid);

        if (parent_pid < 1) {
            ERROR("Found a parent with a PID < 1");
            goto GT_CLEAN_PARENT;
        }

        if (kill(parent_pid, 0) == 0) {
            DEBUG("Parent still alive");
            continue;
        } else {
            int old_errno = errno;
            if (old_errno != ESRCH) {
                WARN("Couldn't determine whether %d is alive: %s",
                     parent_pid,
                     strerror(old_errno));
                goto GT_CLEAN_PARENT;
            }
        }

        embht_iterinit(children_ht, &child_iter);
        while (embht_iternext(&child_iter)) {

            uint64_t child_start =
                    *(uint64_t*)(embht_itercur(&child_iter)->u_value.value);

            pid_t child_pid = embht_itercur(&child_iter)->key.u_kdata.kd32;

            if (child_pid < 1) {
                continue;
            }

            if (procstat(child_pid, &pstb) != 0) {
                fprintf(stderr, "procstat(%d) (%d,%d)\n",
                        child_pid, pstb.lib_error, pstb.sys_error);
                continue;
            }

            if (pstb.pst_starttime != child_start) {
                INFO("PID %d found but start times differ", child_pid);
                continue;
            }

            INFO("Dead parent %d: Killing %d", parent_pid, child_pid);
            kill(child_pid, Server.default_signum);
        }

        GT_CLEAN_PARENT:
        if (children_ht) {
            embht_destroy(children_ht);
        }
        embht_iterdel(&parents_iter);
    }
}
Exemple #6
0
int
main(int argc, char *argv[])
{
	int ch, interval, tmp;
	int i;
	struct kinfo_proc *p;
	struct procstat *prstat, *cprstat;
	long l;
	pid_t pid;
	char *dummy;
	char *nlistf, *memf;
	const char *xocontainer;
	int cnt;

	interval = 0;
	memf = nlistf = NULL;
	argc = xo_parse_args(argc, argv);
	xocontainer = "basic";

	while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrsStvw:x")) != -1) {
		switch (ch) {
		case 'C':
			Cflag++;
			break;

		case 'H':
			Hflag++;
			break;

		case 'M':
			memf = optarg;
			break;
		case 'N':
			nlistf = optarg;
			break;
		case 'S':
			Sflag++;
			xocontainer = "cs";
			break;
		case 'a':
			aflag++;
			break;

		case 'b':
			bflag++;
			xocontainer = "binary";
			break;

		case 'c':
			cflag++;
			xocontainer = "arguments";
			break;

		case 'e':
			eflag++;
			xocontainer = "environment";
			break;

		case 'f':
			fflag++;
			xocontainer = "files";
			break;

		case 'i':
			iflag++;
			xocontainer = "signals";
			break;

		case 'j':
			jflag++;
			xocontainer = "thread_signals";
			break;

		case 'k':
			kflag++;
			xocontainer = "kstack";
			break;

		case 'l':
			lflag++;
			xocontainer = "rlimit";
			break;

		case 'n':
			nflag++;
			break;

		case 'h':
			hflag++;
			break;

		case 'r':
			rflag++;
			xocontainer = "rusage";
			break;

		case 's':
			sflag++;
			xocontainer = "credentials";
			break;

		case 't':
			tflag++;
			xocontainer = "threads";
			break;

		case 'v':
			vflag++;
			xocontainer = "vm";
			break;

		case 'w':
			l = strtol(optarg, &dummy, 10);
			if (*dummy != '\0')
				usage();
			if (l < 1 || l > INT_MAX)
				usage();
			interval = l;
			break;

		case 'x':
			xflag++;
			xocontainer = "auxv";
			break;

		case '?':
		default:
			usage();
		}

	}
	argc -= optind;
	argv += optind;

	/* We require that either 0 or 1 mode flags be set. */
	tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) +
	    lflag + rflag + sflag + tflag + vflag + xflag + Sflag;
	if (!(tmp == 0 || tmp == 1))
		usage();

	/* We allow -k to be specified up to twice, but not more. */
	if (kflag > 2)
		usage();

	/* Must specify either the -a flag or a list of pids. */
	if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
		usage();

	/* Only allow -C with -f. */
	if (Cflag && !fflag)
		usage();

	if (memf != NULL)
		prstat = procstat_open_kvm(nlistf, memf);
	else
		prstat = procstat_open_sysctl();
	if (prstat == NULL)
		xo_errx(1, "procstat_open()");
	do {
		xo_set_version(PROCSTAT_XO_VERSION);
		xo_open_container("procstat");
		xo_open_container(xocontainer);

		if (aflag) {
			p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
			if (p == NULL)
				xo_errx(1, "procstat_getprocs()");
			kinfo_proc_sort(p, cnt);
			for (i = 0; i < cnt; i++) {
				procstat(prstat, &p[i]);

				/* Suppress header after first process. */
				hflag = 1;
				xo_flush();
			}
			procstat_freeprocs(prstat, p);
		}
		for (i = 0; i < argc; i++) {
			l = strtol(argv[i], &dummy, 10);
			if (*dummy == '\0') {
				if (l < 0)
					usage();
				pid = l;

				p = procstat_getprocs(prstat, KERN_PROC_PID,
				    pid, &cnt);
				if (p == NULL)
					xo_errx(1, "procstat_getprocs()");
				if (cnt != 0)
					procstat(prstat, p);
				procstat_freeprocs(prstat, p);
			} else {
				cprstat = procstat_open_core(argv[i]);
				if (cprstat == NULL) {
					warnx("procstat_open()");
					continue;
				}
				p = procstat_getprocs(cprstat, KERN_PROC_PID,
				    -1, &cnt);
				if (p == NULL)
					xo_errx(1, "procstat_getprocs()");
				if (cnt != 0)
					procstat(cprstat, p);
				procstat_freeprocs(cprstat, p);
				procstat_close(cprstat);
			}
			/* Suppress header after first process. */
			hflag = 1;
		}

		xo_close_container(xocontainer);
		xo_close_container("procstat");
		xo_finish();
		if (interval)
			sleep(interval);
	} while (interval);

	procstat_close(prstat);

	exit(0);
}
Exemple #7
0
int
main(int argc, char *argv[])
{
    int ch, interval, tmp;
    int i;
    struct kinfo_proc *p;
    struct procstat *prstat, *cprstat;
    long l;
    pid_t pid;
    char *dummy;
    char *nlistf, *memf;
    int cnt;

    interval = 0;
    memf = nlistf = NULL;
    while ((ch = getopt(argc, argv, "CHLM:N:ORSXabcefijklhrstvw:x")) != -1) {
        switch (ch) {
        case 'C':
            Cflag++;
            break;

        case 'L':
            Lflag++;
            break;

        case 'H':
            Hflag++;
            break;

        case 'M':
            memf = optarg;
            break;

        case 'N':
            nlistf = optarg;
            break;

        case 'O':
            Oflag++;
            break;

        case 'R':
            Rflag++;
            break;

        case 'S':
            Sflag++;
            break;

        case 'X':
            Xflag++;
            break;

        case 'a':
            aflag++;
            break;

        case 'b':
            bflag++;
            break;

        case 'c':
            cflag++;
            break;

        case 'e':
            eflag++;
            break;

        case 'f':
            fflag++;
            break;

        case 'i':
            iflag++;
            break;

        case 'j':
            jflag++;
            break;

        case 'k':
            kflag++;
            break;

        case 'l':
            lflag++;
            break;

        case 'n':
            nflag++;
            break;

        case 'h':
            hflag++;
            break;

        case 'r':
            rflag++;
            break;

        case 's':
            sflag++;
            break;

        case 't':
            tflag++;
            break;

        case 'v':
            vflag++;
            break;

        case 'w':
            l = strtol(optarg, &dummy, 10);
            if (*dummy != '\0')
                usage();
            if (l < 1 || l > INT_MAX)
                usage();
            interval = l;
            break;

        case 'x':
            xflag++;
            break;

        case '?':
        default:
            usage();
        }

    }
    argc -= optind;
    argv += optind;

    /* We require that either 0 or 1 mode flags be set. */
    tmp = Lflag + Oflag + Rflag + Sflag + bflag + cflag + eflag + fflag +
          iflag + jflag + (kflag ? 1 : 0) + lflag + rflag + sflag + tflag +
          vflag + xflag;
    if (!(tmp == 0 || tmp == 1))
        usage();

    /* We allow -k to be specified up to twice, but not more. */
    if (kflag > 2)
        usage();

    /* Must specify either the -a flag or a list of pids. */
    if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
        usage();

    /* Only allow -C with -f. */
    if (Cflag && !fflag)
        usage();

    /* Only allow -X with -S and -R. */
    if (Xflag && !(Sflag || Rflag))
        usage();

    if (memf != NULL)
        prstat = procstat_open_kvm(nlistf, memf);
    else
        prstat = procstat_open_sysctl();
    if (prstat == NULL)
        errx(1, "procstat_open()");
    do {
        if (aflag) {
            p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
            if (p == NULL)
                errx(1, "procstat_getprocs()");
            kinfo_proc_sort(p, cnt);
            for (i = 0; i < cnt; i++) {
                procstat(prstat, &p[i]);

                /* Suppress header after first process. */
                hflag = 1;
            }
            procstat_freeprocs(prstat, p);
        }
        for (i = 0; i < argc; i++) {
            l = strtol(argv[i], &dummy, 10);
            if (*dummy == '\0') {
                if (l < 0)
                    usage();
                pid = l;

                p = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt);
                if (p == NULL)
                    errx(1, "procstat_getprocs()");
                if (cnt != 0)
                    procstat(prstat, p);
                procstat_freeprocs(prstat, p);
            } else {
                cprstat = procstat_open_core(argv[i]);
                if (cprstat == NULL) {
                    warnx("procstat_open()");
                    continue;
                }
                p = procstat_getprocs(cprstat, KERN_PROC_PID,
                                      -1, &cnt);
                if (p == NULL)
                    errx(1, "procstat_getprocs()");
                if (cnt != 0)
                    procstat(cprstat, p);
                procstat_freeprocs(cprstat, p);
                procstat_close(cprstat);
            }
            /* Suppress header after first process. */
            hflag = 1;
        }
        if (interval)
            sleep(interval);
    } while (interval);
    procstat_close(prstat);
    exit(0);
}