Commit 6c92590d authored by Christian Mohrbacher's avatar Christian Mohrbacher

updated to release 6.2

parent 7083e88c
......@@ -71,6 +71,8 @@ cd build
echo "mkdir RPM_BUILD_ROOT (${RPM_BUILD_ROOT})"
mkdir -p ${RPM_BUILD_ROOT}/usr/include
cp -a ../include/beegfs ${RPM_BUILD_ROOT}/usr/include/
mkdir -p ${RPM_BUILD_ROOT}/usr/share/doc/%NAME%/examples/
cp -a dist/usr/share/doc/%NAME%/examples/* ${RPM_BUILD_ROOT}/usr/share/doc/%NAME%/examples/
%post
......@@ -79,4 +81,4 @@ cp -a ../include/beegfs ${RPM_BUILD_ROOT}/usr/include/
%files
%defattr(-,root,root)
/usr/include/*
/usr/share/doc/%NAME%/examples/*
......@@ -36,6 +36,8 @@ install: build
# manual installation
mkdir -p ${DEB_BUILD_ROOT}/usr/include
cp -a ../include/beegfs ${DEB_BUILD_ROOT}/usr/include/
mkdir -p ${DEB_BUILD_ROOT}/usr/share/doc/__NAME__/examples/
cp -a dist/usr/share/doc/__NAME__/examples/* ${DEB_BUILD_ROOT}/usr/share/doc/__NAME__/examples/
# Build architecture-independent files here.
binary-indep:
......
#include <beegfs/beegfs.h>
#include <dirent.h>
#include <errno.h>
#include <iostream>
#include <libgen.h>
#include <stdlib.h>
static const mode_t MODE_FLAG = S_IRWXU | S_IRGRP | S_IROTH;
static const unsigned numtargets = 8;
static const unsigned chunksize = 1048576; // 1 Mebibyte
int main(int argc, char** argv)
{
// check if a path to the file is provided
if(argc != 2)
{
std::cout << "Usage: " << argv[0] << " $PATH_TO_FILE" << std::endl;
exit(-1);
}
std::string file(argv[1]);
std::string fileName(basename(argv[1]) );
std::string parentDirectory(dirname(argv[1]) );
// check if we got a file name from the given path
if(fileName.empty() )
{
std::cout << "Can not get file name from given path: " << file << std::endl;
exit(-1);
}
// check if we got the parent directory path from the given path
if(parentDirectory.empty() )
{
std::cout << "Can not get parent directory path from given path: " << file << std::endl;
exit(-1);
}
// open the directory to get a directory stream
DIR* parentDir = opendir(parentDirectory.c_str() );
if(parentDir == NULL)
{
std::cout << "Can not get directory stream of directory: " << parentDirectory << " errno: " << errno << std::endl;
exit(-1);
}
// get a fd of the parent directory
int fd = dirfd(parentDir);
if(fd == -1)
{
std::cout << "Can not get fd from directory: " << parentDirectory << " errno: " << errno << std::endl;
exit(-1);
}
// check if the parent directory is located on a BeeGFS, because the striping API works only on a BeeGFS
// if the ioctl is used on a other filesystem everything can happens
bool isBeegfs = beegfs_testIsBeeGFS(fd);
if(!isBeegfs)
{
std::cout << "The given file is not located on an BeeGFS: " << file << std::endl;
exit(-1);
}
// create the file with the given stripe pattern
bool isFileCreated = beegfs_createFile(fd, fileName.c_str(), MODE_FLAG, numtargets, chunksize);
if(isFileCreated)
{
std::cout << "File successful created: " << file << std::endl;
}
else
{
std::cout << "Can not create file: " << file << " errno: " << errno << std::endl;
exit(-1);
}
}
#include <beegfs/beegfs.h>
#include <errno.h>
#include <iostream>
#include <stdlib.h>
static const mode_t MODE_FLAG = S_IRWXU | S_IRGRP | S_IROTH;
static const int OPEN_FLAGS = O_RDWR;
int main(int argc, char** argv)
{
// check if a path to the file is provided
if(argc != 2)
{
std::cout << "Usage: " << argv[0] << " $PATH_TO_FILE" << std::endl;
exit(-1);
}
std::string file(argv[1]);
// open the provided file
int fd = open(file.c_str(), OPEN_FLAGS, MODE_FLAG);
if(fd == -1)
{
std::cout << "Open: can not open file: " << file << " errno: " << errno << std::endl;
exit(-1);
}
// check if the file is located on a BeeGFS, because the striping API works only on a BeeGFS
// if the ioctl is used on a other filesystem everything can happens
bool isBeegfs = beegfs_testIsBeeGFS(fd);
if(!isBeegfs)
{
std::cout << "The given file is not located on an BeeGFS: " << file << std::endl;
exit(-1);
}
unsigned outPatternType = 0;
unsigned outChunkSize = 0;
uint16_t outNumTargets = 0;
// retrive the stripe pattern of the file and print them to the console
bool stripeInfoRetVal = beegfs_getStripeInfo(fd, &outPatternType, &outChunkSize, &outNumTargets);
if(stripeInfoRetVal)
{
std::string patternType;
switch(outPatternType)
{
case BEEGFS_STRIPEPATTERN_RAID0:
patternType = "RAID0";
break;
case BEEGFS_STRIPEPATTERN_RAID10:
patternType = "RAID10";
break;
case BEEGFS_STRIPEPATTERN_BUDDYMIRROR:
patternType = "BUDDYMIRROR";
break;
default:
patternType = "INVALID";
}
std::cout << "Strip pattern of file: " << file << std::endl;
std::cout << "+ Type: " << patternType << std::endl;
std::cout << "+ Chunksize: " << outChunkSize << " Byte" << std::endl;
std::cout << "+ Number of storage targets: " << outNumTargets << std::endl;
std::cout << "+ Storage targets:" << std::endl;
// get the targets which are used for the file and print them to the console
for (int targetIndex = 0; targetIndex < outNumTargets; targetIndex++)
{
struct BeegfsIoctl_GetStripeTargetV2_Arg outTargetInfo;
bool stripeTargetRetVal = beegfs_getStripeTargetV2(fd, targetIndex, &outTargetInfo);
if(stripeTargetRetVal)
{
if(outPatternType == BEEGFS_STRIPEPATTERN_BUDDYMIRROR)
{
std::cout << " + " << outTargetInfo.targetOrGroup << " @ " << outTargetInfo.primaryTarget << " @ " << outTargetInfo.primaryNodeStrID << " [ID: "<< outTargetInfo.primaryNodeID << "]" << std::endl;
std::cout << " + " << outTargetInfo.targetOrGroup << " @ " << outTargetInfo.secondaryTarget << " @ " << outTargetInfo.secondaryNodeStrID << " [ID: "<< outTargetInfo.secondaryNodeID << "]" << std::endl;
}
else
{
std::cout << " + " << outTargetInfo.targetOrGroup << " @ " << outTargetInfo.primaryNodeStrID << " [ID: "<< outTargetInfo.primaryNodeID << "]" << std::endl;
}
}
else
{
std::cout << "Can not get stripe targets of file: " << file << std::endl;
exit(-1);
}
}
}
else
{
std::cout << "Can not get stripe info of file: " << file << std::endl;
exit(-1);
}
}
......@@ -32,7 +32,7 @@ tar czf $BUILD/buildroot/SOURCES/${NAME}-${BEEGFS_VERSION}.tgz --exclude=build
cd $BUILD
sed -e "s#%BEEGFS_OPENTK_PATH%#$BEEGFS_OPENTK_PATH#" \
-e "s#%BEEGFS_COMMON_PATH%#$BEEGFS_COMMON_PATH#" \
-e "s/%NAME%/$NAME/" \
-e "s/%NAME%/$NAME/g" \
-e "s/%BEEGFS_VERSION%/$BEEGFS_VERSION/" \
-e "s/%BUILDARCH%/$BUILDARCH/" \
${SPEC_FILE}.in > ${SPEC_FILE}
......
......@@ -3,6 +3,8 @@
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#define BEEGFS_IOCTL_CFG_MAX_PATH 4096 // max path length for config file
#define BEEGFS_IOCTL_TEST_STRING "_FhGFS_" /* copied to user space by BEEGFS_IOC_TEST_IS_BEEGFS to
......
......@@ -128,18 +128,12 @@ TICPP_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/ticpp
MONGOOSE_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/mongoose
BOOST_INC_PATH ?= $(BEEGFS_THIRDPARTY_PATH)/source/boost/
ifneq ($(target_arch),)
STRIP := $(target_arch)-strip
AR := $(target_arch)-ar
CC := $(target_arch)-gcc
CXX := $(target_arch)-g++
endif
SHELL := /bin/bash
STRIP ?= strip
CXX ?= g++
AR ?= ar
AR := ar
# if -T is supported by ar, use it. thin archives are quicker to create and maintain.
ifeq ($(shell ar -TM 2>&1 <<<""),)
AR += -T
......
......@@ -45,6 +45,8 @@ logNumRotatedFiles = 2
logStdFile = /var/log/beegfs-admon.log
mailEnabled = false
mailSmtpSendType = socket
mailSendmailPath = sendmail
mailCheckIntervalTimeSec = 30
mailMinDownTimeSec = 10
mailRecipient =
......@@ -210,6 +212,23 @@ tuneNumWorkers = 4
# from the admon GUI.
# Default: false
# [mailSmtpSendType]
# How to send the email to an smtp server.
# Values:
# * socket: use a socket to send the mails to an SMTP server without user authentication.
# * sendmail: use the installed and configured sendmail program to send mails. The sendmail
# binary should be accessible by the default binary search path of the system.
# Note: Use sendmail if a encrypted connection to the SMTP server and/or user authentication is
# required.
# Default: socket
# [mailSendmailPath]
# The path to the sendmail binary. This configuration is only required when mailSmtpSendType is set
# to sendmail.
# Note: If the binary is accessible by the default binary search path of the system the default
# configuration works.
# Default: sendmail
# [mailCheckIntervalTimeSec]
# Amount of time to check for new events which must be notified in seconds.
# Default: 30
......
......@@ -2,8 +2,16 @@
#include <program/Program.h>
#include "Config.h"
#include <sys/stat.h>
#define CONFIG_DEFAULT_CFGFILENAME "/etc/beegfs/beegfs-admon.conf"
#define SMTPSENDTYPE_SOCKET "socket"
#define SMTPSENDTYPE_SENDMAIL "sendmail"
Config::Config(int argc, char** argv) throw(InvalidConfigException) : AbstractConfig(argc, argv)
{
......@@ -20,7 +28,7 @@ void Config::loadDefaults(bool addDashes)
AbstractConfig::loadDefaults();
// re-definitions
configMapRedefine("cfgFile", "" /*createDefaultCfgFilename()*/ );
configMapRedefine("cfgFile", "");
configMapRedefine("connUseRDMA", "false"); // overrides abstract config
// own definitions
......@@ -44,6 +52,8 @@ void Config::loadDefaults(bool addDashes)
configMapRedefine("clearDatabase", "false");
configMapRedefine("mailEnabled", "false");
configMapRedefine("mailSmtpSendType", SMTPSENDTYPE_SOCKET);
configMapRedefine("mailSendmailPath", MAIL_SENDMAIL_DEFAULT_PATH);
configMapRedefine("mailSmtpServer", "");
configMapRedefine("mailSender", "");
configMapRedefine("mailRecipient", "");
......@@ -105,6 +115,12 @@ void Config::applyConfigMap(bool enableException, bool addDashes) throw(InvalidC
if(iter->first == std::string("mailEnabled") )
mailEnabled = StringTk::strToBool(iter->second);
else
if(iter->first == std::string("mailSmtpSendType") )
mailSmtpSendType = iter->second;
else
if(iter->first == std::string("mailSendmailPath") )
mailSendmailPath = iter->second;
else
if(iter->first == std::string("mailSmtpServer") )
mailSmtpServer = iter->second;
else
......@@ -148,6 +164,8 @@ void Config::initImplicitVals() throw(InvalidConfigException)
{
// connAuthHash
AbstractConfig::initConnAuthHash(connAuthFile, &connAuthHash);
initMailerConfig();
}
std::string Config::createDefaultCfgFilename()
......@@ -187,3 +205,41 @@ void Config::resetMgmtdDaemon()
mutexLock.unlock();
}
/**
* Converts the given parameter mailSmtpSendType into a enum value SmtpSendType_... and checks if
* the sendmail path is valid.
*
* @throws InvalidConfigException If the mailSmtpSendType is invalid or the sendmail path is not
* valid.
*/
void Config::initMailerConfig()
{
if(this->mailSmtpSendType == SMTPSENDTYPE_SOCKET)
{
this->mailSmtpSendTypeNum = SmtpSendType_SOCKET;
}
else
if(this->mailSmtpSendType == SMTPSENDTYPE_SENDMAIL)
{
this->mailSmtpSendTypeNum = SmtpSendType_SENDMAIL;
// the default must be overridden by an empty string
if(mailSendmailPath.empty() )
throw InvalidConfigException("Path to sendmail path is empty.");
// a path to the sendmail binary was given which is not the default path
if(mailSendmailPath != MAIL_SENDMAIL_DEFAULT_PATH)
{
struct stat statBuffer;
int statRetVal = stat(mailSendmailPath.c_str(), &statBuffer);
if(statRetVal)
throw InvalidConfigException("Stat of given sendmail path failed: " + mailSendmailPath +
" ; Errno: " + System::getErrString() );
}
}
else
{ // invalid chooser specified
throw InvalidConfigException("Invalid SMTP send type specified: " + mailSmtpSendType);
}
}
#ifndef CONFIG_H_
#define CONFIG_H_
#include <common/app/config/AbstractConfig.h>
#define MAIL_SENDMAIL_DEFAULT_PATH "sendmail"
enum SmtpSendType
{
SmtpSendType_SOCKET = 0,
SmtpSendType_SENDMAIL = 1,
};
class Config : public AbstractConfig
{
public:
......@@ -40,6 +53,9 @@ class Config : public AbstractConfig
// eMail notification which overrides the runtime configuration
bool mailEnabled;
std::string mailSmtpSendType;
SmtpSendType mailSmtpSendTypeNum; // auto-generated based on mailSmtpSendType
std::string mailSendmailPath;
std::string mailSmtpServer;
std::string mailSender;
std::string mailRecipient;
......@@ -53,6 +69,7 @@ class Config : public AbstractConfig
virtual void applyConfigMap(bool enableException, bool addDashes)
throw(InvalidConfigException);
virtual void initImplicitVals() throw(InvalidConfigException);
void initMailerConfig();
std::string createDefaultCfgFilename();
......@@ -196,6 +213,16 @@ class Config : public AbstractConfig
return mailEnabled;
}
SmtpSendType getMailSmtpSendType()
{
return mailSmtpSendTypeNum;
}
std::string getMailSendmailPath()
{
return mailSendmailPath;
}
std::string getMailSmtpServer()
{
return mailSmtpServer;
......
......@@ -7,6 +7,8 @@ void RuntimeConfig::setDefaults()
gethostname(localHost, 256);
// setting defaults
mailEnabled = false;
mailSmtpSendTypeNum = SmtpSendType_SOCKET;
mailSendmailPath = MAIL_SENDMAIL_DEFAULT_PATH;
mailSender = "beegfs_admon@" + std::string(localHost);
mailRecipient = "";
mailSmtpServer = "";
......
......@@ -8,17 +8,6 @@
class RuntimeConfig
{
private:
Config *cfg;
bool mailEnabled;
std::string mailSender;
std::string mailRecipient;
std::string mailSmtpServer;
int mailMinDownTimeSec;
int mailResendMailTimeMin;
std::string scriptPath;
void setDefaults();
public:
RuntimeConfig(Config *cfg)
{
......@@ -26,6 +15,10 @@ class RuntimeConfig
setDefaults();
}
virtual ~RuntimeConfig()
{
}
bool getMailEnabled()
{
if (cfg->isMailConfigOverrideActive())
......@@ -40,6 +33,34 @@ class RuntimeConfig
this->mailEnabled = mailEnabled;
}
SmtpSendType getMailSmtpSendType()
{
if (cfg->isMailConfigOverrideActive())
{
return cfg->getMailSmtpSendType();
}
return mailSmtpSendTypeNum;
}
void setMailSmtpSendType(SmtpSendType mailSmtpSendType)
{
this->mailSmtpSendTypeNum = mailSmtpSendType;
}
std::string getMailSendmailPath()
{
if (cfg->isMailConfigOverrideActive())
{
return cfg->getMailSendmailPath();
}
return mailSendmailPath;
}
void setMailSendmailPath(std::string mailSendmailPath)
{
this->mailSendmailPath = mailSendmailPath;
}
std::string getMailSender()
{
if (cfg->isMailConfigOverrideActive())
......@@ -130,18 +151,21 @@ class RuntimeConfig
{
(*outMap)["mailEnabled"] = "false";
}
(*outMap)["mailSmtpSendTypeNum"] = StringTk::intToStr(mailSmtpSendTypeNum);
(*outMap)["mailSendmailPath"] = mailSendmailPath;
(*outMap)["mailSender"] = mailSender;
(*outMap)["mailRecipient"] = mailRecipient;
(*outMap)["mailSmtpServer"] = mailSmtpServer;
(*outMap)["mailMinDownTimeSec"] = StringTk::intToStr(mailMinDownTimeSec);
(*outMap)["mailResendMailTimeMin"] = StringTk::intToStr(mailResendMailTimeMin);
(*outMap)["scriptPath"] = scriptPath;
}
void importAsMap(std::map<std::string, std::string> *inMap)
{
mailEnabled = StringTk::strToBool((*inMap)["mailEnabled"]);
mailSmtpSendTypeNum = (SmtpSendType) StringTk::strToInt( (*inMap)["mailSmtpSendTypeNum"]);
mailSendmailPath = (*inMap)["mailSendmailPath"];
mailSender = (*inMap)["mailSender"];
mailRecipient = (*inMap)["mailRecipient"];
mailSmtpServer = (*inMap)["mailSmtpServer"];
......@@ -150,9 +174,20 @@ class RuntimeConfig
scriptPath = (*inMap)["scriptPath"];
}
virtual ~RuntimeConfig()
{
}
private:
Config *cfg;
bool mailEnabled;
SmtpSendType mailSmtpSendTypeNum;
std::string mailSendmailPath;
std::string mailSender;
std::string mailRecipient;
std::string mailSmtpServer;
int mailMinDownTimeSec;
int mailResendMailTimeMin;
std::string scriptPath;
void setDefaults();
};
#endif /* RUNTIMECONFIG_H_ */
This diff is collapsed.
......@@ -29,8 +29,7 @@ class Mailer : public PThread
Mailer() : PThread("Mailer"), log("Mailer") {};
virtual ~Mailer() {};
static int sendMail(const std::string& smtpServerName, const std::string& sender,
const std::string& recipient, const std::string& subject, const std::string& msg);
int sendMail(const std::string& subject, const std::string& msg);
bool addDownNode(NumNodeID nodeNumID, std::string nodeID, NodeType nodeType);
......@@ -85,6 +84,11 @@ class Mailer : public PThread
void notifyDownNodes();
void notifyBackUpNodes();
int sendMailSocket(const std::string& smtpServerName, const std::string& sender,
const std::string& recipient, const std::string& subject, const std::string& msg);
int sendMailSystem(const std::string& sender, const std::string& recipient,
const std::string& subject, const std::string& msg);
public:
// public inliners
......
......@@ -1540,6 +1540,8 @@ void xmlhelper::mailNotification(struct mg_connection *conn,
{
std::string change = webtk::getVar(conn, "change", "false", postBuf, postBufLen);
std::string mailEnabled = webtk::getVar(conn, "mailEnabled", "false", postBuf, postBufLen);
std::string sendType = webtk::getVar(conn, "sendType", "", postBuf, postBufLen);
std::string sendMailPath = webtk::getVar(conn, "sendmailPath", "", postBuf, postBufLen);
std::string smtpServer = webtk::getVar(conn, "smtpServer", "", postBuf, postBufLen);
std::string sender = webtk::getVar(conn, "sender", "", postBuf, postBufLen);
std::string recipient = webtk::getVar(conn, "recipient", "", postBuf, postBufLen);
......@@ -1571,18 +1573,70 @@ void xmlhelper::mailNotification(struct mg_connection *conn,
log->log(Log_ERR, __func__, "Authentication for admin user failed.");
}
else
if(enableMail && ( sender.empty() || recipient.empty() ) )
else if(enableMail && ( sender.empty() || recipient.empty() ||
( (StringTk::strToInt(sendType) == SmtpSendType_SOCKET) && smtpServer.empty() ) ||
( (StringTk::strToInt(sendType) == SmtpSendType_SENDMAIL) && sendMailPath.empty() ) ) )
{
bool notFirstEmptyValue = false;
std::string errorMessage = "Could not write new config. Please be aware that if you"
"activate eMail support, you MUST specify a ";
if(sender.empty() )
{
errorMessage.append("sender");
notFirstEmptyValue = true;
}
if(recipient.empty() )
{
if(notFirstEmptyValue)
{
errorMessage.append(", recipient");
}
else
{
errorMessage.append("recipient");
notFirstEmptyValue = true;
}
}
if( (StringTk::strToInt(sendType) == SmtpSendType_SOCKET) && smtpServer.empty() )
{
if(notFirstEmptyValue)
{
errorMessage.append(", SMTP Server");
}
else
{
errorMessage.append("SMTP Server");
notFirstEmptyValue = true;
}
}
if( (StringTk::strToInt(sendType) == SmtpSendType_SENDMAIL) && sendMailPath.empty() )
{
if(notFirstEmptyValue)
{
errorMessage.append(", path to sendmail");
}
else
{
errorMessage.append("path to sendmail");
}
}
errorMessage.append(".");
TiXmlElement *entryElement = new TiXmlElement("entry");
entryElement->LinkEndChild(new TiXmlText(
"Could not write new config. Please be aware that if you activate eMail support, "
"you MUST specify a sender and a recipient.") );
entryElement->LinkEndChild(new TiXmlText(errorMessage) );
errorElement->LinkEndChild(entryElement);
}
else
{
runtimeCfg->setMailEnabled(enableMail);
runtimeCfg->setMailSmtpSendType( (SmtpSendType)StringTk::strToInt(sendType) );
runtimeCfg->setMailSendmailPath(sendMailPath);
runtimeCfg->setMailSmtpServer(smtpServer);
runtimeCfg->setMailSender(sender);
runtimeCfg->setMailRecipient(recipient);
......@@ -1625,21 +1679,30 @@ void xmlhelper::mailNotification(struct mg_connection *conn,
}
rootElement->LinkEndChild(overrideActiveElement);
TiXmlElement *sendTypeElement = new TiXmlElement("sendType");
sendTypeElement->LinkEndChild(new TiXmlText(
StringTk::intToStr(runtimeCfg->getMailSmtpSendType() ) ) );
rootElement->LinkEndChild(sendTypeElement);
TiXmlElement *sendmailPathElement = new TiXmlElement("sendmailPath");
sendmailPathElement->LinkEndChild(new TiXmlText(runtimeCfg->getMailSendmailPath() ) );
rootElement->LinkEndChild(sendmailPathElement);
TiXmlElement *smtpElement = new TiXmlElement("smtpServer");
smtpElement->LinkEndChild(new TiXmlText(runtimeCfg->getMailSmtpServer()));
smtpElement->LinkEndChild(new TiXmlText(runtimeCfg->getMailSmtpServer() ) );
rootElement->LinkEndChild(smtpElement);
TiXmlElement *senderElement = new TiXmlElement("sender");
senderElement->LinkEndChild(new TiXmlText(runtimeCfg->getMailSender()));
senderElement->LinkEndChild(new TiXmlText(runtimeCfg->getMailSender() ) );
rootElement->LinkEndChild(senderElement);