Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 38 additions & 39 deletions contextual-classifier/ContextualClassifier.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// SPDX-License-Identifier: BSD-3-Clause-Clear

#include <algorithm>
#include <chrono>
#include <string>
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <dirent.h>
#include <fstream>
#include <pthread.h>
#include <sstream>
#include <string>
#include <dirent.h>
#include <algorithm>
#include <pthread.h>

#include "Utils.h"
#include "UrmPlatformAL.h"
#include "Request.h"
#include "Logger.h"
#include "Request.h"
#include "Inference.h"
#include "Extensions.h"
#include "AuxRoutines.h"
#include "UrmPlatformAL.h"
#include "SignalRegistry.h"
#include "RestuneInternal.h"
#include "ContextualClassifier.h"
#include "ClientGarbageCollector.h"
#include "RestuneInternal.h"
#include "SignalRegistry.h"
#include "Extensions.h"
#include "Inference.h"

#define CLASSIFIER_TAG "CONTEXTUAL_CLASSIFIER"
#define CLASSIFIER_CONFIGS_DIR "/etc/urm/classifier/"
Expand Down Expand Up @@ -55,7 +55,7 @@ static ContextualClassifier *gClassifier = nullptr;
static const int32_t pendingQueueControlSize = 30;

ContextualClassifier::ContextualClassifier() {
mInference = GetInferenceObject();
this->mInference = GetInferenceObject();
}

void ContextualClassifier::untuneRequestHelper(int64_t handle) {
Expand All @@ -81,7 +81,7 @@ void ContextualClassifier::untuneRequestHelper(int64_t handle) {

} catch(const std::exception& e) {
LOGE(CLASSIFIER_TAG,
"Failed to move per-app threads to cgroup, Error: " + std::string(e.what()));
"Failed to create untune request, Error: " + std::string(e.what()));
}
}

Expand Down Expand Up @@ -153,24 +153,24 @@ ContextualClassifier::~ContextualClassifier() {
}

ErrCode ContextualClassifier::Init() {
LOGI(CLASSIFIER_TAG, "Classifier module init.");
LOGI(CLASSIFIER_TAG, "Classifier module init");

this->LoadIgnoredProcesses();

// Single worker thread for classification
this->mClassifierMain = std::thread(&ContextualClassifier::ClassifierMain, this);

if (this->mNetLinkComm.connect() == -1) {
LOGE(CLASSIFIER_TAG, "Failed to connect to netlink socket.");
if(this->mNetLinkComm.connect() == -1) {
LOGE(CLASSIFIER_TAG, "Failed to connect to netlink socket");
return RC_SOCKET_OP_FAILURE;
}

if (this->mNetLinkComm.setListen(true) == -1) {
LOGE(CLASSIFIER_TAG, "Failed to set proc event listener.");
if(this->mNetLinkComm.setListen(true) == -1) {
LOGE(CLASSIFIER_TAG, "Failed to set proc event listener");
mNetLinkComm.closeSocket();
return RC_SOCKET_OP_FAILURE;
}
LOGI(CLASSIFIER_TAG, "Now listening for process events.");
LOGI(CLASSIFIER_TAG, "Now listening for process events");

this->mNetlinkThread = std::thread(&ContextualClassifier::HandleProcEv, this);
return RC_SUCCESS;
Expand All @@ -179,27 +179,25 @@ ErrCode ContextualClassifier::Init() {
ErrCode ContextualClassifier::Terminate() {
LOGI(CLASSIFIER_TAG, "Classifier module terminate.");

if (this->mNetLinkComm.getSocket() != -1) {
if(this->mNetLinkComm.getSocket() != -1) {
this->mNetLinkComm.setListen(false);
}

{
std::unique_lock<std::mutex> lock(this->mQueueMutex);
this->mNeedExit = true;
// Clear any pending PIDs so the worker doesn't see stale entries
while (!this->mPendingEv.empty()) {
this->mPendingEv.pop();
}
std::unique_lock<std::mutex> lock(this->mQueueMutex);
this->mNeedExit = true;
// Clear any pending PIDs so the worker doesn't see stale entries
while(!this->mPendingEv.empty()) {
this->mPendingEv.pop();
}
this->mQueueCond.notify_all();

this->mNetLinkComm.closeSocket();

if (this->mNetlinkThread.joinable()) {
if(this->mNetlinkThread.joinable()) {
this->mNetlinkThread.join();
}

if (this->mClassifierMain.joinable()) {
if(this->mClassifierMain.joinable()) {
this->mClassifierMain.join();
}

Expand Down Expand Up @@ -267,7 +265,7 @@ void ContextualClassifier::ClassifierMain() {

// Step 4:
// Configure any per-app config specified signals.
this->configureAssociatedAppSignals(ev.pid, ev.tgid, comm);
this->configureAppSignals(ev.pid, ev.tgid, comm);

// Step 5: If the post processing block exists, call it
// It might provide us a more specific sigID or sigType
Expand Down Expand Up @@ -296,7 +294,7 @@ void ContextualClassifier::ClassifierMain() {
}
}

int ContextualClassifier::HandleProcEv() {
int32_t ContextualClassifier::HandleProcEv() {
pthread_setname_np(pthread_self(), "urmNetlinkListener");
int32_t rc = 0;

Expand Down Expand Up @@ -363,12 +361,13 @@ int32_t ContextualClassifier::ClassifyProcess(pid_t processPid,
uint32_t &ctxDetails) {
(void)processTgid;
(void)ctxDetails;

CC_TYPE context = CC_APP;

// Check if the process is still alive
if(!AuxRoutines::fileExists(COMM(processPid))) {
LOGD(CLASSIFIER_TAG,
"Skipping inference, process is dead: "+ comm);
"Skipping inference, process is dead: " + comm);
return CC_IGNORE;
}

Expand Down Expand Up @@ -403,6 +402,7 @@ void ContextualClassifier::ApplyActions(uint32_t sigId,
void ContextualClassifier::RemoveActions(pid_t processPid, pid_t processTgid) {
(void)processPid;
(void)processTgid;

return;
}

Expand Down Expand Up @@ -459,7 +459,7 @@ void ContextualClassifier::LoadIgnoredProcesses() {
}
}
}
LOGI(CLASSIFIER_TAG, "Loaded filter processes.");
LOGI(CLASSIFIER_TAG, "Loaded filter processes");
}

int8_t ContextualClassifier::shouldProcBeIgnored(int32_t evType, pid_t pid) {
Expand Down Expand Up @@ -543,10 +543,9 @@ void ContextualClassifier::MoveAppThreadsToCGroup(pid_t incomingPID,
}
}

void ContextualClassifier::configureAssociatedAppSignals(
pid_t incomingPID,
pid_t incomingTID,
const std::string& comm) {
void ContextualClassifier::configureAppSignals(pid_t incomingPID,
pid_t incomingTID,
const std::string& comm) {
try {
// Configure any associated signal
AppConfig* appConfig = AppConfigs::getInstance()->getAppConfig(comm);
Expand Down Expand Up @@ -574,20 +573,20 @@ void ContextualClassifier::configureAssociatedAppSignals(
}
} catch(const std::exception& e) {
LOGE(CLASSIFIER_TAG,
"Failed to move per-app threads to cgroup, Error: " + std::string(e.what()));
"Failed to acquire per-app config signal, Error: " + std::string(e.what()));
}
}

// Public C interface exported from the contextual-classifier shared library.
// These are what the URM module entrypoints will call.
extern "C" ErrCode cc_init(void) {
extern "C" ErrCode ccInit(void) {
if(gClassifier == nullptr) {
gClassifier = new ContextualClassifier();
}
return gClassifier->Init();
}

extern "C" ErrCode cc_terminate(void) {
extern "C" ErrCode ccTerminate(void) {
if(gClassifier != nullptr) {
ErrCode opStatus = gClassifier->Terminate();
delete gClassifier;
Expand Down
8 changes: 4 additions & 4 deletions contextual-classifier/ContextualClassifierInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ static ErrCode init(void *arg = nullptr) {

dlerror();

g_cc_init = reinterpret_cast<cc_init_fn>(dlsym(g_cc_handle, "cc_init"));
g_cc_init = reinterpret_cast<cc_init_fn>(dlsym(g_cc_handle, "ccInit"));
const char *err = dlerror();
if (err != nullptr || !g_cc_init) {
LOGE(CLASSIFIER_TAG,
format_string("Failed to resolve cc_init in %s: %s", so_name,
format_string("Failed to resolve ccInit in %s: %s", so_name,
err ? err : "unknown"));
dlclose(g_cc_handle);
g_cc_handle = nullptr;
Expand All @@ -60,11 +60,11 @@ static ErrCode init(void *arg = nullptr) {
return RC_SUCCESS;
}

g_cc_term = reinterpret_cast<cc_term_fn>(dlsym(g_cc_handle, "cc_terminate"));
g_cc_term = reinterpret_cast<cc_term_fn>(dlsym(g_cc_handle, "ccTerminate"));
err = dlerror();
if (err != nullptr || !g_cc_term) {
LOGE(CLASSIFIER_TAG,
format_string("Failed to resolve cc_terminate in %s: %s", so_name,
format_string("Failed to resolve ccTerminate in %s: %s", so_name,
err ? err : "unknown"));
dlclose(g_cc_handle);
g_cc_handle = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion contextual-classifier/Include/ContextualClassifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class ContextualClassifier {
const std::string& comm,
int32_t cgroupIdentifier);

void configureAssociatedAppSignals(pid_t incomingPID,
void configureAppSignals(pid_t incomingPID,
pid_t incomingTID,
const std::string& comm);

Expand Down
46 changes: 28 additions & 18 deletions contextual-classifier/NetLinkComm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,39 @@
#include "NetLinkComm.h"
#include "ContextualClassifier.h"

#define CLASSIFIER_TAG "NetLinkComm"
#define CLASSIFIER_TAG "CLASSIFIER_NETLINK"
#define PROCP_THRESH 50

static pid_t getParent(pid_t pid) {
std::string statusFile = "/proc/" + std::to_string(pid) + "/status";
std::ifstream file(statusFile);
std::string line;
static int8_t procHasControlTerminal(pid_t pid) {
std::string procStatPath = STAT(pid);
std::string stat = AuxRoutines::readFromFile(procStatPath);
if(stat.empty()) {
return false;
}

if(!file.is_open()) {
return 0;
// Find the closing ')' of the comm field.
size_t pos = stat.rfind(')');
if(pos == std::string::npos) {
return false;
}

while(std::getline(file, line)) {
if(line.rfind("PPid:", 0) == 0) {
std::istringstream iss(line);
std::string label;
pid_t parentPid;
iss >> label >> parentPid;
return parentPid;
}
// Start parsing right after ')' and skip any spaces.
pos++;
while(pos < stat.size() && stat[pos] == ' ') {
pos++;
}
if(pos >= stat.size()) {
return false;
}

return 0;
std::istringstream statStream(stat.substr(pos));

char state = '\0';
int64_t ppid = 0, pgrp = 0, session = 0, ttyNr = 0;
statStream >> state >> ppid >> pgrp >> session >> ttyNr;

// For daemon / system services, tty number (controlling terminal) will be 0.
return (ttyNr != 0);
}

NetLinkComm::NetLinkComm() {
Expand Down Expand Up @@ -148,7 +158,7 @@ int32_t NetLinkComm::recvEvent(ProcEvent &ev) {
ev.type = CC_APP_OPEN;

rc = CC_APP_OPEN;
if(!AuxRoutines::fileExists(COMM(ev.pid)) || (getParent(ev.pid) <= PROCP_THRESH)) {
if(!AuxRoutines::fileExists(COMM(ev.pid)) || !procHasControlTerminal(ev.pid)) {
rc = ev.type = CC_IGNORE;
}
break;
Expand All @@ -159,7 +169,7 @@ int32_t NetLinkComm::recvEvent(ProcEvent &ev) {
ev.type = CC_APP_CLOSE;

rc = CC_APP_CLOSE;
if(!AuxRoutines::fileExists(COMM(ev.pid)) || (getParent(ev.pid) <= PROCP_THRESH)) {
if(!AuxRoutines::fileExists(COMM(ev.pid)) || !procHasControlTerminal(ev.pid)) {
rc = ev.type = CC_IGNORE;
}
break;
Expand Down
1 change: 1 addition & 0 deletions modula/Common/Include/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ typedef void (*MessageReceivedCallback)(int32_t, MsgForwardInfo*);
#define COMM_S(pidstr) ("/proc/" + pidstr + "/comm")
#define STATUS(pid) ("/proc/" + std::to_string(pid) + "/status")
#define CMDLINE(pid) ("/proc/" + std::to_string(pid) + "/cmdline")
#define STAT(pid) ("/proc/" + std::to_string(pid) + "/stat")

#define CONCAT_IMPL(a, b) a##b
#define CONCAT(a, b) CONCAT_IMPL(a, b)
Expand Down
Loading