зеркало из https://github.com/mozilla/Negatus.git
Bug 827999 - Use SD card for test root if present. r=wlach
This commit is contained in:
Родитель
df23111db7
Коммит
2ac5103443
1
Makefile
1
Makefile
|
@ -6,6 +6,7 @@ SRCS=\
|
|||
src/Buffer.cpp \
|
||||
src/BufferedSocket.cpp \
|
||||
src/CommandEventHandler.cpp \
|
||||
src/Config.cpp \
|
||||
src/EventHandler.cpp \
|
||||
src/Hash.cpp \
|
||||
src/HeartbeatEventHandler.cpp \
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "CommandEventHandler.h"
|
||||
#include "Config.h"
|
||||
#include "Hash.h"
|
||||
#include "Logger.h"
|
||||
#include "Logging.h"
|
||||
|
@ -235,32 +236,6 @@ CommandEventHandler::sendPrompt()
|
|||
}
|
||||
|
||||
|
||||
std::string
|
||||
CommandEventHandler::readTextFile(std::string path)
|
||||
{
|
||||
const char *cpath = path.c_str();
|
||||
|
||||
FILE *fp = fopen(cpath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Error on fopen: %s, with mode r.\n", cpath);
|
||||
return agentWarn("Cannot open file");
|
||||
}
|
||||
|
||||
char buffer[BUFSIZE];
|
||||
std::ostringstream output;
|
||||
|
||||
while (fgets(buffer, BUFSIZE, fp))
|
||||
output << std::string(buffer);
|
||||
|
||||
fclose(fp);
|
||||
std::string str = output.str();
|
||||
if (str.size())
|
||||
str.erase(str.size() - 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
CommandEventHandler::getFirstIntPos(char *str, int limit)
|
||||
{
|
||||
|
@ -277,6 +252,7 @@ CommandEventHandler::getFirstIntPos(char *str, int limit)
|
|||
std::string
|
||||
CommandEventHandler::joinPaths(std::string p1, std::string p2)
|
||||
{
|
||||
// FIXME: depends on POSIX-like paths
|
||||
if (p1[p1.length() - 1] == '/')
|
||||
p1 = p1.substr(0, p1.length() - 1);
|
||||
if (p2[0] == '/')
|
||||
|
@ -515,9 +491,12 @@ CommandEventHandler::uptime()
|
|||
std::string
|
||||
CommandEventHandler::uptimemillis()
|
||||
{
|
||||
std::string uptime_file = readTextFile("/proc/uptime");
|
||||
std::string uptimeStr;
|
||||
if (!readTextFile("/proc/uptime", uptimeStr))
|
||||
return agentWarn("could not read /proc/uptime");
|
||||
|
||||
double uptime;
|
||||
sscanf(&uptime_file[0], "%lf", &uptime);
|
||||
sscanf(&uptimeStr[0], "%lf", &uptime);
|
||||
uptime *= 1000;
|
||||
std::ostringstream out;
|
||||
out << (int) uptime;
|
||||
|
@ -529,7 +508,10 @@ CommandEventHandler::uptimemillis()
|
|||
std::string
|
||||
CommandEventHandler::screen()
|
||||
{
|
||||
return readTextFile("/sys/devices/virtual/graphics/fb0/modes");
|
||||
std::string out;
|
||||
if (!readTextFile("/sys/devices/virtual/graphics/fb0/modes", out))
|
||||
return agentWarn("could not read screen mode");
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
@ -557,14 +539,16 @@ CommandEventHandler::memory()
|
|||
std::string
|
||||
CommandEventHandler::power()
|
||||
{
|
||||
std::string capacity, status;
|
||||
if (!readTextFile("/sys/class/power_supply/battery/capacity", capacity))
|
||||
return agentWarn("could not read battery capacity");
|
||||
if (!readTextFile("/sys/class/power_supply/battery/status", status))
|
||||
return agentWarn("could not read battery status");
|
||||
|
||||
std::ostringstream ret;
|
||||
|
||||
ret << "Power status:" << ENDL;
|
||||
ret << "\tCurrent %: ";
|
||||
ret << readTextFile("/sys/class/power_supply/battery/capacity");
|
||||
ret << "\tStatus: ";
|
||||
ret << readTextFile("/sys/class/power_supply/battery/status");
|
||||
|
||||
ret << "\tCurrent %: " << capacity;
|
||||
ret << "\tStatus: " << status;
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
|
@ -687,7 +671,8 @@ CommandEventHandler::rebt(std::vector<std::string>& args)
|
|||
// store callback IP and PORT in REBOOT_FILE, if specified
|
||||
if (args.size() == 2)
|
||||
{
|
||||
FILE *f = fopen(REBOOT_FILE, "w");
|
||||
FILE *f = fopen(joinPaths(Config::instance()->mTestRoot,
|
||||
REBOOT_FILE).c_str(), "w");
|
||||
if (!f)
|
||||
return agentWarn("Could not write to reboot callback file");
|
||||
fprintf(f, "%s %s\n", args[0].c_str(), args[1].c_str());
|
||||
|
@ -863,7 +848,7 @@ CommandEventHandler::setutime(std::vector<std::string>& args)
|
|||
std::string
|
||||
CommandEventHandler::testroot(std::vector<std::string>& args)
|
||||
{
|
||||
return std::string(TESTROOT);
|
||||
return Config::instance()->mTestRoot;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
#include "BufferedSocket.h"
|
||||
#include "EventHandler.h"
|
||||
|
||||
|
||||
#define TESTROOT "/data/local"
|
||||
#define REBOOT_FILE "/data/local/.SUTAgent_rebt"
|
||||
#define REBOOT_FILE ".SUTAgent_rebt"
|
||||
|
||||
|
||||
class CommandEventHandler: public EventHandler
|
||||
|
@ -43,7 +41,6 @@ private:
|
|||
void sendPrompt();
|
||||
void do_rmdr(std::string path, std::ostringstream &out);
|
||||
|
||||
std::string readTextFile(std::string path);
|
||||
int getFirstIntPos(char *str, int limit);
|
||||
std::string joinPaths(std::string p1, std::string p2);
|
||||
bool checkDataEventHandler(PRPollDesc desc);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "Config.h"
|
||||
#include <iostream>
|
||||
#include <prerror.h>
|
||||
#include <prio.h>
|
||||
#include <string.h>
|
||||
#include "Shell.h"
|
||||
|
||||
Config* Config::mInstance = NULL;
|
||||
|
||||
Config::Config()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Config*
|
||||
Config::instance()
|
||||
{
|
||||
if (!mInstance)
|
||||
mInstance = new Config();
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Config::setTestRoot(std::string testRoot)
|
||||
{
|
||||
if (testRoot.empty())
|
||||
setDefaultTestRoot();
|
||||
else
|
||||
mTestRoot = testRoot;
|
||||
|
||||
PRFileInfo info;
|
||||
PRStatus st = PR_GetFileInfo(mTestRoot.c_str(), &info);
|
||||
if (st == PR_SUCCESS)
|
||||
{
|
||||
if (info.type != PR_FILE_DIRECTORY)
|
||||
std::cerr << "Test root " << mTestRoot
|
||||
<< " exists but is not a directory." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PR_MkDir(mTestRoot.c_str(), 0777) == PR_FAILURE)
|
||||
{
|
||||
std::cerr << "Failed to create test root " << mTestRoot
|
||||
<< ": " << PR_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Config::setDefaultTestRoot()
|
||||
{
|
||||
// FIXME: POSIX specific
|
||||
std::string mounts;
|
||||
if (readTextFile("/proc/mounts", mounts))
|
||||
{
|
||||
char mountsc[mounts.size()+1];
|
||||
strcpy(mountsc, mounts.c_str());
|
||||
char* line = strtok(mountsc, "\n");
|
||||
while (line)
|
||||
{
|
||||
char* beg = strchr(line, ' ');
|
||||
if (!beg)
|
||||
continue;
|
||||
beg++;
|
||||
char* end = strchr(beg, ' ');
|
||||
if (!end)
|
||||
continue;
|
||||
*end = 0;
|
||||
if (strcmp(beg, SD_CARD_MOUNT) == 0)
|
||||
{
|
||||
mTestRoot = TESTROOT_SD_CARD;
|
||||
break;
|
||||
}
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (mTestRoot.empty())
|
||||
mTestRoot = TESTROOT_NO_SD_CARD;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef negatus_config_h
|
||||
#define negatus_config_h
|
||||
|
||||
#include <string>
|
||||
|
||||
#define SD_CARD_MOUNT "/mnt/sdcard"
|
||||
#define TESTROOT_SD_CARD "/mnt/sdcard/test"
|
||||
#define TESTROOT_NO_SD_CARD "/data/local/tmp"
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
static Config* instance();
|
||||
std::string mTestRoot;
|
||||
|
||||
/* If testRoot is empty, use default, preferring attached SD card. */
|
||||
void setTestRoot(std::string testRoot);
|
||||
|
||||
private:
|
||||
static Config* mInstance;
|
||||
|
||||
Config();
|
||||
void setDefaultTestRoot();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -4,11 +4,10 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define DEBUG
|
||||
#include "CommandEventHandler.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Config.h"
|
||||
#include "CommandEventHandler.h"
|
||||
#include "Strings.h"
|
||||
|
||||
Logger* Logger::mInstance = NULL;
|
||||
PRLogModuleInfo* Logger::logModule = NULL;
|
||||
|
@ -16,19 +15,21 @@ PRLogModuleInfo* Logger::logModule = NULL;
|
|||
Logger::Logger()
|
||||
{
|
||||
logModule = PR_NewLogModule("NegatusLOG");
|
||||
std::string log_path = std::string(TESTROOT) + "/Negatus.log";
|
||||
std::string log_path = Config::instance()->mTestRoot + "/Negatus.log";
|
||||
PR_SetLogFile(log_path.c_str());
|
||||
PR_LOG(logModule, PR_LOG_ALWAYS, ("NegatusLOG init.\n"));
|
||||
}
|
||||
|
||||
|
||||
Logger*
|
||||
Logger::instance()
|
||||
{
|
||||
if (!mInstance)
|
||||
mInstance = new Logger();
|
||||
return mInstance;
|
||||
if (!mInstance)
|
||||
mInstance = new Logger();
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Logger::log(std::string msg) {
|
||||
PR_LOG(logModule, PR_LOG_ALWAYS, (msg.c_str()));
|
||||
|
|
19
src/Logger.h
19
src/Logger.h
|
@ -6,19 +6,20 @@
|
|||
#define negatus_logger_h
|
||||
|
||||
#include <prlog.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static Logger* instance();
|
||||
void log(std::string msg);
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static Logger* instance();
|
||||
void log(std::string msg);
|
||||
static std::string mTestRoot;
|
||||
|
||||
private:
|
||||
static Logger* mInstance;
|
||||
static PRLogModuleInfo* logModule;
|
||||
private:
|
||||
static Logger* mInstance;
|
||||
static PRLogModuleInfo* logModule;
|
||||
|
||||
Logger();
|
||||
Logger();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,17 +18,25 @@
|
|||
#include <prtypes.h>
|
||||
|
||||
#include "CommandEventHandler.h"
|
||||
#include "Config.h"
|
||||
#include "HeartbeatEventHandler.h"
|
||||
#include "Logger.h"
|
||||
#include "Strings.h"
|
||||
#include "Reactor.h"
|
||||
#include "SocketAcceptor.h"
|
||||
#include "Registration.h"
|
||||
#include "Shell.h"
|
||||
#include "SocketAcceptor.h"
|
||||
#include "Strings.h"
|
||||
|
||||
|
||||
// FIXME: This is not portable!
|
||||
#include <signal.h>
|
||||
|
||||
static const PLLongOpt longOpts[] = {
|
||||
{ "heartbeat", 'b', PR_TRUE },
|
||||
{ "testroot", 't', PR_TRUE },
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
bool wantToDie = false;
|
||||
|
||||
void signalHandler(int signal)
|
||||
|
@ -112,22 +120,36 @@ int main(int argc, char **argv)
|
|||
signal(SIGTERM, &signalHandler);
|
||||
signal(SIGINT, &signalHandler);
|
||||
signal(SIGHUP, &signalHandler);
|
||||
PRInt16 port = 20701;
|
||||
PRInt16 port = 20701, heartbeatPort = 20700;
|
||||
std::string testRoot;
|
||||
bool optionError = false;
|
||||
PLOptState* optState = PL_CreateOptState(argc, argv, "p:");
|
||||
std::ostringstream usageo;
|
||||
usageo << "Usage: " << argv[0]
|
||||
<< " [-p <port>] [--heartbeat <port>] [--testroot <testroot>]";
|
||||
std::string usage(usageo.str());
|
||||
PLOptState* optState = PL_CreateLongOptState(argc, argv, "hp:", longOpts);
|
||||
while (true)
|
||||
{
|
||||
PLOptStatus status = PL_GetNextOpt(optState);
|
||||
if (status == PL_OPT_BAD)
|
||||
{
|
||||
std::cerr << "Incorrect option(s). Usage: " << argv[0] << " [-p <port>]"
|
||||
<< std::endl;
|
||||
std::cerr << "Incorrect option(s). " << usage << std::endl;
|
||||
optionError = true;
|
||||
break;
|
||||
}
|
||||
else if (status == PL_OPT_OK)
|
||||
{
|
||||
if (optState->option == 'p')
|
||||
if (optState->option == 0 && optState->longOptIndex < 0)
|
||||
{
|
||||
// Ignore positional parameters.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (optState->longOption == 'h')
|
||||
{
|
||||
std::cout << usage << std::endl;
|
||||
}
|
||||
else if (optState->longOption == 'p')
|
||||
{
|
||||
port = PR_strtod(optState->value, NULL);
|
||||
if (port <= 0)
|
||||
|
@ -137,6 +159,18 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (optState->longOption == 'b')
|
||||
{
|
||||
heartbeatPort = PR_strtod(optState->value, NULL);
|
||||
if (heartbeatPort <= 0)
|
||||
{
|
||||
std::cerr << "Invalid heartbeat port number." << std::endl;
|
||||
optionError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (optState->longOption == 't')
|
||||
testRoot = std::string(optState->value);
|
||||
}
|
||||
else if (status == PL_OPT_EOL)
|
||||
break;
|
||||
|
@ -147,12 +181,14 @@ int main(int argc, char **argv)
|
|||
if (optionError)
|
||||
return 1;
|
||||
|
||||
Config::instance()->setTestRoot(testRoot);
|
||||
|
||||
PRNetAddr cmdAddr, heartbeatAddr;
|
||||
if(!setUpAcceptor(new CommandEventHandlerFactory(), "Command", port,
|
||||
cmdAddr))
|
||||
if (!setUpAcceptor(new CommandEventHandlerFactory(), "Command", port,
|
||||
cmdAddr))
|
||||
return 1;
|
||||
if(!setUpAcceptor(new HeartbeatEventHandlerFactory(), "Heartbeat", 20700,
|
||||
heartbeatAddr))
|
||||
if (!setUpAcceptor(new HeartbeatEventHandlerFactory(), "Heartbeat",
|
||||
heartbeatPort, heartbeatAddr))
|
||||
return 1;
|
||||
|
||||
dict reg_data = get_reg_data();
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "Subprocess.h"
|
||||
|
||||
#include "Shell.h"
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Logging.h"
|
||||
#include "Subprocess.h"
|
||||
|
||||
std::string
|
||||
id()
|
||||
|
@ -30,3 +32,31 @@ id()
|
|||
}
|
||||
return std::string("00:00:00:00:00:00");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
readTextFile(std::string path, std::string& contents)
|
||||
{
|
||||
const char *cpath = path.c_str();
|
||||
|
||||
FILE *fp = fopen(cpath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Error on fopen: %s, with mode r.\n", cpath);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[BUFSIZE];
|
||||
std::ostringstream output;
|
||||
|
||||
while (fgets(buffer, BUFSIZE, fp))
|
||||
output << std::string(buffer);
|
||||
|
||||
fclose(fp);
|
||||
std::string str = output.str();
|
||||
if (str.size())
|
||||
str.erase(str.size() - 1);
|
||||
contents = str;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
#include <string>
|
||||
|
||||
std::string id();
|
||||
bool readTextFile(std::string path, std::string& contents);
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче