// ---------------------------------------------------------------------- // File: ProcessInfo.hh // Author: Georgios Bitzes - CERN // ---------------------------------------------------------------------- /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2011 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #ifndef __PROCESS_INFO_HH__ #define __PROCESS_INFO_HH__ #include #include #include #include "Utils.hh" #include "auth/RmInfo.hh" typedef int64_t Jiffies; // Holds information about a specific process. // Stat information (pid, ppid, sid, starttime) must be present for such an // object to be considered non-empty. class ProcessInfo { public: ProcessInfo() : empty(true), pid(0), ppid(0), pgrp(0), sid(0), startTime(-1), flags(0) { } // Fill stat information as obtained from /proc//stat void fillStat(pid_t pid, pid_t ppid, pid_t pgrp, pid_t sid, Jiffies startTime, unsigned int flags) { if (!empty) { THROW("ProcessInfo stat information can only be filled once"); } empty = false; this->pid = pid; this->ppid = ppid; this->pgrp = pgrp; this->sid = sid; this->startTime = startTime; this->flags = flags; } bool isSameProcess(const ProcessInfo& other) { if (pid != other.pid || startTime != other.startTime) { return false; } return true; } // Fill cmdline information as obtained from /proc//cmdline void fillCmdline(const std::vector& contents) { cmd = contents; cmdStr = join(cmd, " "); } void fillExecutablePath(const std::string& path) { executablePath = path; } void fillRmInfo() { rmInfo = RmInfo(executablePath, cmd); } bool isEmpty() const { return empty; } pid_t getPid() const { return pid; } pid_t getParentId() const { return ppid; } pid_t getGroupLeader() const { return pgrp; } pid_t getSid() const { return sid; } Jiffies getStartTime() const { return startTime; } const std::vector& getCmd() const { return cmd; } std::string getCmdStr() const { return cmdStr; } unsigned int getFlags() const { return flags; } std::string getExecPath() const { return executablePath; } const RmInfo& getRmInfo() const { return rmInfo; } std::string getExe() const { return exe; } private: bool empty; RmInfo rmInfo; // TODO(gbitzes): Make these private once ProcessInfoProvider is implemented public: // from /proc//stat pid_t pid; pid_t ppid; pid_t pgrp; pid_t sid; Jiffies startTime; unsigned int flags; // from /proc//cmdline std::vector cmd; std::string cmdStr; // TODO(gbitzes): remove this eventually? std::string executablePath; std::string exe; // derived from /proc//exe }; // Parses the contents of /proc//stat, converting it to a ProcessInfo class ProcessInfoProvider { public: void inject(pid_t pid, const ProcessInfo& info); // retrieves information about a process from the kernel. // Does not fill cmdline, thus only reading a single file. bool retrieveBasic(pid_t pid, ProcessInfo& ret); // retrieves information about a process from the kernel, including cmdline. bool retrieveFull(pid_t pid, ProcessInfo& ret); static bool fromString(const std::string& stat, const std::string& cmd, ProcessInfo& ret); private: std::mutex mtx; std::map injections; std::atomic useInjectedData{false}; static bool parseStat(const std::string& stat, ProcessInfo& ret); static void parseCmdline(const std::string& cmdline, ProcessInfo& ret); static bool parseExec(pid_t pid, ProcessInfo& ret); }; #endif