*
*/
-#include "common/config.h"
-#include "common/debug.h"
#include "common/errno.h"
#include <errno.h>
+#include <sstream>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
-#define dout_prefix *_dout
+using std::ostringstream;
-int run_cmd(const char *cmd, ...)
+std::string run_cmd(const char *cmd, ...)
{
- int ret;
std::vector <const char *> arr;
va_list ap;
va_start(ap, cmd);
va_end(ap);
arr.push_back(NULL);
- ret = fork();
- if (ret == -1) {
+ int fret = fork();
+ if (fret == -1) {
int err = errno;
- derr << "run_cmd(" << cmd << "): unable to fork(): " << cpp_strerror(err)
- << dendl;
- return -1;
+ ostringstream oss;
+ oss << "run_cmd(" << cmd << "): unable to fork(): " << cpp_strerror(err);
+ return oss.str();
}
- else if (ret == 0) {
+ else if (fret == 0) {
// execvp doesn't modify its arguments, so the const-cast here is safe.
execvp(cmd, (char * const*)&arr[0]);
_exit(127);
}
int status;
- while (waitpid(ret, &status, 0) == -1) {
+ while (waitpid(fret, &status, 0) == -1) {
int err = errno;
if (err == EINTR)
continue;
- derr << "run_cmd(" << cmd << "): waitpid error: "
- << cpp_strerror(err) << dendl;
- return -1;
+ ostringstream oss;
+ oss << "run_cmd(" << cmd << "): waitpid error: "
+ << cpp_strerror(err);
+ return oss.str();
}
if (WIFEXITED(status)) {
- return WEXITSTATUS(status);
+ int wexitstatus = WEXITSTATUS(status);
+ if (wexitstatus != 0) {
+ ostringstream oss;
+ oss << "run_cmd(" << cmd << "): exited with status " << wexitstatus;
+ return oss.str();
+ }
+ return "";
}
else if (WIFSIGNALED(status)) {
- derr << "run_cmd(" << cmd << "): terminated by signal" << dendl;
- return -1;
+ ostringstream oss;
+ oss << "run_cmd(" << cmd << "): terminated by signal";
+ return oss.str();
}
- derr << "run_cmd(" << cmd << "): terminated by unknown mechanism" << dendl;
- return -1;
+ ostringstream oss;
+ oss << "run_cmd(" << cmd << "): terminated by unknown mechanism";
+ return oss.str();
}
#ifndef CEPH_COMMON_RUN_CMD_H
#define CEPH_COMMON_RUN_CMD_H
+#include <string>
+
//
// Fork a command and run it. The shell will not be invoked and shell
// expansions will not be done.
// Example:
// run_cmd("rm", "-rf", "foo", NULL)
//
-int run_cmd(const char *cmd, ...);
+// Returns an empty string on success, and an error string otherwise.
+//
+std::string run_cmd(const char *cmd, ...);
#endif
#include <sys/stat.h>
#include <sys/types.h>
-#define dout_prefix *_dout
-
void install_sighandler(int signum, signal_handler_t handler, int flags)
{
int ret;
int MonitorStore::mkfs()
{
- int ret = run_cmd("rm", "-rf", dir.c_str(), (char*)NULL);
- if (ret) {
+ std::string ret = run_cmd("rm", "-rf", dir.c_str(), (char*)NULL);
+ if (!ret.empty()) {
derr << "MonitorStore::mkfs: failed to remove " << dir
<< ": rm returned " << ret << dendl;
- return ret;
+ return -EIO;
}
ret = run_cmd("mkdir", "-p", dir.c_str(), (char*)NULL);
- if (ret) {
+ if (!ret.empty()) {
derr << "MonitorStore::mkfs: failed to mkdir -p " << dir
<< ": mkdir returned " << ret << dendl;
- return ret;
+ return -EIO;
}
dout(0) << "created monfs at " << dir.c_str() << " for "
continue;
ostringstream oss;
oss << old_dir.str().c_str() << "/" << de->d_name;
- int ret = run_cmd("rm", "-rf", oss.str().c_str(), (char*)NULL);
- if (ret) {
+ std::string ret = run_cmd("rm", "-rf", oss.str().c_str(), (char*)NULL);
+ if (!ret.empty()) {
derr << "FileStore::wipe_subvol: failed to remove " << oss.str() << ": "
<< "error " << ret << dendl;
::closedir(dir);
- return ret;
+ return -EIO;
}
}
::closedir(dir);
if (!g_conf->filestore_dev.empty()) {
dout(0) << "mounting" << dendl;
- ret = run_cmd("mount", g_conf->filestore_dev.c_str(), (char*)NULL);
- if (ret) {
+ std::string mret = run_cmd("mount", g_conf->filestore_dev.c_str(), (char*)NULL);
+ if (!mret.empty()) {
derr << "FileStore::mkfs: failed to mount g_conf->filestore_dev "
- << "'" << g_conf->filestore_dev << "'. Error code " << ret << dendl;
+ << "'" << g_conf->filestore_dev << "'. " << mret << dendl;
+ ret = -EIO;
goto out;
}
}
ASSERT_GE(fd, 0);
::close(fd);
- int ret = run_cmd("touch", temp_file_name, (char*)NULL);
- ASSERT_EQ(ret, 0);
+ std::string ret = run_cmd("touch", temp_file_name, (char*)NULL);
+ ASSERT_EQ(ret, "");
ASSERT_EQ(access(temp_file_name, R_OK), 0);
ret = run_cmd("rm", "-f", temp_file_name, (char*)NULL);
- ASSERT_EQ(ret, 0);
+ ASSERT_EQ(ret, "");
ASSERT_NE(access(temp_file_name, R_OK), 0);
}