#At file:///C:/w/repo/bug45447/ based on revid:magnus.blaudd@stripped
3003 jack andrews 2009-09-15
sorry, i have to merge
added:
storage/ndb/src/cw/cpcd/CMakeLists.txt
modified:
storage/ndb/CMakeLists.txt
storage/ndb/src/CMakeLists.txt
storage/ndb/src/common/util/Parser.cpp
storage/ndb/src/cw/cpcd/CPCD.cpp
storage/ndb/src/cw/cpcd/CPCD.hpp
storage/ndb/src/cw/cpcd/Process.cpp
storage/ndb/src/cw/cpcd/common.cpp
storage/ndb/src/cw/cpcd/main.cpp
=== modified file 'storage/ndb/CMakeLists.txt'
--- a/storage/ndb/CMakeLists.txt 2008-10-09 09:40:16 +0000
+++ b/storage/ndb/CMakeLists.txt 2009-09-15 10:02:46 +0000
@@ -27,4 +27,7 @@ ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(tools)
ADD_SUBDIRECTORY(test)
+IF(WITH_NDB_TEST)
+ADD_SUBDIRECTORY(src/cw/cpcd)
+ENDIF()
ADD_SUBDIRECTORY(docs)
=== modified file 'storage/ndb/src/CMakeLists.txt'
--- a/storage/ndb/src/CMakeLists.txt 2008-08-20 13:22:29 +0000
+++ b/storage/ndb/src/CMakeLists.txt 2009-09-15 10:02:46 +0000
@@ -20,7 +20,6 @@ ADD_SUBDIRECTORY(ndbapi)
ADD_SUBDIRECTORY(kernel)
ADD_SUBDIRECTORY(mgmclient)
ADD_SUBDIRECTORY(mgmsrv)
-ADD_SUBDIRECTORY(cw)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/ndb/include
{CMAKE_SOURCE_DIR}/include)
=== modified file 'storage/ndb/src/common/util/Parser.cpp'
--- a/storage/ndb/src/common/util/Parser.cpp 2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/common/util/Parser.cpp 2009-09-15 10:02:46 +0000
@@ -123,16 +123,14 @@ static
bool
split(char * buf, char ** name, char ** value){
- * value = strchr(buf, ':');
- if(* value == 0)
- * value = strchr(buf, '=');
-
+ for (*value=buf; **value; (*value)++)
+ if (**value == ':' || **value == '=' )
+ break;
- if(* value == 0){
+ if(**value == 0) {
return false;
}
- (* value)[0] = 0;
- * value = (* value + 1);
+ *(*value)++ = 0;
* name = buf;
trim(* name);
=== added file 'storage/ndb/src/cw/cpcd/CMakeLists.txt'
--- a/storage/ndb/src/cw/cpcd/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/cw/cpcd/CMakeLists.txt 2009-09-15 10:02:46 +0000
@@ -0,0 +1,43 @@
+# Copyright (C) 2007 MySQL AB
+#
+# 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; version 2 of the License.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+INCLUDE(${CMAKE_SOURCE_DIR}/storage/ndb/config/type_ndbapi.cmake)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/ndb/src/ndbapi
+ ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmapi
+ ${CMAKE_SOURCE_DIR}/storage/ndb/src/common/mgmcommon
+ ${CMAKE_SOURCE_DIR}/storage/ndb/include/portlib
+ ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmclient
+ ${CMAKE_SOURCE_DIR}/sql)
+
+LINK_LIBRARIES(ndbmgmclient
+ ndbclient
+ dbug
+ mysys
+ strings
+ ndbgeneral
+ ndbportlib
+ ${NDB_SCI_LIBS})
+
+ADD_EXECUTABLE(cpcd
+ APIService.cpp
+ CPCD.cpp
+ Monitor.cpp
+ Process.cpp
+ common.cpp
+ main.cpp)
+# TARGET_LINK_LIBRARIES(cpcd ndbconf)
+
+ADD_EXECUTABLE(cpcd-t cpcd_t.cpp)
=== modified file 'storage/ndb/src/cw/cpcd/CPCD.cpp'
--- a/storage/ndb/src/cw/cpcd/CPCD.cpp 2009-06-11 12:28:55 +0000
+++ b/storage/ndb/src/cw/cpcd/CPCD.cpp 2009-09-15 10:02:46 +0000
@@ -26,6 +26,12 @@
#include <NdbMutex.h>
#include "common.hpp"
+#ifdef _WIN32
+#include <windows.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <direct.h>
+#endif
extern const ParserRow<CPCDAPISession> commands[];
@@ -229,10 +235,11 @@ CPCD::notifyChanges() {
#ifdef _WIN32
static int link(const char* from_file, const char* to_file)
{
- BOOL fail_if_exists = TRUE;
- if (CopyFile(from_file, to_file, fail_if_exists) != 0)
+ if(!CreateHardLink(to_file,from_file,0))
{
/* "On error, -1 is returned" */
+ DWORD le=GetLastError();
+ assert(le==ERROR_ALREADY_EXISTS);
return -1;
}
/* "On success, zero is returned" */
@@ -244,6 +251,7 @@ static int link(const char* from_file, c
/* Must be called with m_processlist locked */
bool
CPCD::saveProcessList(){
+ char *cwd=getcwd(0,0);
char newfile[PATH_MAX+4];
char oldfile[PATH_MAX+4];
char curfile[PATH_MAX];
@@ -259,7 +267,7 @@ CPCD::saveProcessList(){
if(f == NULL) {
/* XXX What should be done here? */
logger.critical("Cannot open `%s': %s\n", newfile, strerror(errno));
- return false;
+ goto error;
}
for(size_t i = 0; i<m_processes.size(); i++){
@@ -293,23 +301,35 @@ CPCD::saveProcessList(){
*/
/* Remove an old config file if it exists */
- unlink(oldfile);
-
- if(link(curfile, oldfile) != 0) /* make a backup of the running config */
- logger.error("Cannot rename '%s' -> '%s'", curfile, oldfile);
- else {
- if(unlink(curfile) != 0) { /* remove the running config file */
- logger.critical("Cannot remove file '%s'", curfile);
- return false;
+ struct stat buf;
+ if(!stat(oldfile,&buf))
+ if(unlink(oldfile)!=0) {
+ logger.critical("Cannot remove file '%s' from '%s'", oldfile, cwd);
+ assert(errno==EACCES||errno==ENOENT);
+ logger.critical(errno==EACCES?" EACES":" ENOENT");
+ goto error;
+ }
+ if(!stat(curfile,&buf)) {
+ if(link(curfile, oldfile)) { /* make a backup of the running config */
+ assert(0);
+ logger.error("Cannot rename '%s' -> '%s' from '%s'", curfile, oldfile, cwd);
+ }
+ else {
+ if(unlink(curfile) != 0) { /* remove the running config file */
+ assert(0);
+ char *err = strerror(errno);
+ logger.critical("Cannot remove file '%s' from '%s'", curfile, cwd);
+ goto error;
+ }
}
}
if(link(newfile, curfile) != 0) { /* put the new config file in place */
printf("-->%d\n", __LINE__);
- logger.critical("Cannot rename '%s' -> '%s': %s",
- curfile, newfile, strerror(errno));
- return false;
+ logger.critical("Cannot rename '%s' -> '%s' from '%s': %s",
+ curfile, newfile, cwd, strerror(errno));
+ goto error;
}
/* XXX Ideally we would fsync() the directory here, but I'm not sure if
@@ -322,6 +342,10 @@ CPCD::saveProcessList(){
logger.info("Process list saved as '%s'", curfile);
return true;
+error:
+ if(cwd)
+ free(cwd);
+ return false;
}
bool
@@ -362,6 +386,7 @@ CPCD::loadProcessList(){
CPCDAPISession sess(f, *this);
sess.loadFile();
+ fclose(f);
loadingProcessList = false;
size_t i;
=== modified file 'storage/ndb/src/cw/cpcd/CPCD.hpp'
--- a/storage/ndb/src/cw/cpcd/CPCD.hpp 2009-06-11 12:28:55 +0000
+++ b/storage/ndb/src/cw/cpcd/CPCD.hpp 2009-09-15 10:02:46 +0000
@@ -27,13 +27,34 @@
#include <NdbCondition.h>
#include <BaseString.hpp>
-/* XXX Need to figure out how to do this for non-Unix systems */
-#define CPCD_DEFAULT_WORK_DIR "/var/run/ndb_cpcd"
+#ifdef _WIN32
+#include <my_global.h>
+#include <windows.h>
+typedef DWORD pid_t;
+#else
+typedef int pid_t;
+#endif
+const pid_t bad_pid = -1;
+
+inline bool BAD_PID(pid_t pid)
+{
+#ifdef _WIN32
+ return pid==bad_pid;
+#else
+ return pid<=1;
+#endif
+}
+
#define CPCD_DEFAULT_PROC_FILE "ndb_cpcd.conf"
#define CPCD_DEFAULT_TCP_PORT 1234
#define CPCD_DEFAULT_POLLING_INTERVAL 5 /* seconds */
+#ifndef _WIN32
+#define CPCD_DEFAULT_WORK_DIR "/var/run/ndb_cpcd"
#define CPCD_DEFAULT_CONFIG_FILE "/etc/ndb_cpcd.conf"
-
+#else
+#define CPCD_DEFAULT_WORK_DIR "c:\\tmp\\ndb_cpcd"
+#define CPCD_DEFAULT_CONFIG_FILE "c:\\tmp\\ndb_cpcd.conf"
+#endif
enum ProcessStatus {
STOPPED = 0,
STARTING = 1,
@@ -87,7 +108,7 @@ public:
* @brief Manages a process
*/
class Process {
- int m_pid;
+ pid_t m_pid;
public:
/**
* @brief Constructs and empty Process
@@ -232,7 +253,9 @@ public:
private:
class CPCD *m_cpcd;
+ int do_redir(int std_dups[3]);
void do_exec();
+ void do_spawn();
};
/**
=== modified file 'storage/ndb/src/cw/cpcd/Process.cpp'
--- a/storage/ndb/src/cw/cpcd/Process.cpp 2009-06-11 12:28:55 +0000
+++ b/storage/ndb/src/cw/cpcd/Process.cpp 2009-09-15 10:02:46 +0000
@@ -17,15 +17,22 @@
*/
#include <ndb_global.h>
-
+#ifdef _WIN32
+#include <process.h>
+#include <sys/stat.h>
+#include <io.h>
+#define require(x) if(!(x)) fprintf(stderr,"%s failed at %s:%d\n",#x,__FILE__,__LINE__), exit(99)
+#endif
#include <BaseString.hpp>
#include <InputStream.hpp>
-
#include "common.hpp"
#include "CPCD.hpp"
+#include <errno.h>
#ifndef _WIN32
#include <pwd.h>
+#else
+#include <direct.h>
#endif
#ifdef HAVE_GETRLIMIT
@@ -55,7 +62,7 @@ CPCD::Process::print(FILE * f){
CPCD::Process::Process(const Properties & props, class CPCD *cpcd) {
m_id = -1;
- m_pid = -1;
+ m_pid = bad_pid;
props.get("id", (Uint32 *) &m_id);
props.get("name", m_name);
props.get("group", m_group);
@@ -74,6 +81,9 @@ CPCD::Process::Process(const Properties
props.get("shutdown", m_shutdown_options);
m_status = STOPPED;
+#ifdef _WIN32
+ require(strcasecmp(m_type.c_str(), "temporary") == 0);
+#endif
if(strcasecmp(m_type.c_str(), "temporary") == 0){
m_processType = TEMPORARY;
} else {
@@ -108,12 +118,18 @@ CPCD::Process::monitor() {
bool
CPCD::Process::isRunning() {
- if(m_pid <= 1){
+ if(BAD_PID(m_pid)) {
//logger.critical("isRunning(%d) invalid pid: %d", m_id, m_pid);
return false;
}
/* Check if there actually exists a process with such a pid */
errno = 0;
+#ifdef _WIN32
+ if(!OpenProcess(PROCESS_ALL_ACCESS, 0, m_pid)) {
+ logger.critical("Not enough privileges to control pid %d\n", m_pid);
+ return false;
+ }
+#else
int s = kill((pid_t)-m_pid, 0); /* Sending "signal" 0 to a process only
* checkes if the process actually exists */
if(s != 0) {
@@ -131,11 +147,13 @@ CPCD::Process::isRunning() {
}
return false;
}
+#endif
return true;
}
int
CPCD::Process::readPid() {
+
if(m_pid != -1){
logger.critical("Reading pid while != -1(%d)", m_pid);
return m_pid;
@@ -167,6 +185,16 @@ CPCD::Process::readPid() {
return -1;
}
+#ifdef _WIN32
+inline int mkstemp(char *tmp)
+{
+ int fd;
+ _mktemp(tmp);
+ fd=_open(tmp, _O_CREAT|_O_RDWR|_O_TEXT|_O_TRUNC);
+ assert(!_chmod(tmp,_S_IREAD | _S_IWRITE));
+ return fd;
+}
+#endif
int
CPCD::Process::writePid(int pid) {
@@ -174,6 +202,7 @@ CPCD::Process::writePid(int pid) {
char filename[PATH_MAX*2+1];
FILE *f;
+ getcwd(filename,999);
BaseString::snprintf(tmpfilename, sizeof(tmpfilename), "tmp.XXXXXX");
BaseString::snprintf(filename, sizeof(filename), "%d", m_id);
@@ -193,6 +222,7 @@ CPCD::Process::writePid(int pid) {
fprintf(f, "%d", pid);
fclose(f);
+ IF_WIN(unlink(filename),0);
if(rename(tmpfilename, filename) == -1){
logger.error("Unable to rename from %s to %s", tmpfilename, filename);
return -1;
@@ -200,13 +230,33 @@ CPCD::Process::writePid(int pid) {
return 0;
}
+typedef Vector<BaseString> VBS;
static void
-setup_environment(const char *env) {
+setup_environment(const char *env, VBS *restore) {
char **p;
p = BaseString::argify("", env);
for(int i = 0; p[i] != NULL; i++){
- /*int res = */ putenv(p[i]);
+ if(!p[i][0])
+ continue;
+ if(restore) {
+ char *s = strdup(p[i]),*t;
+ *strchr(s,'=')=0;
+ BaseString bs;
+ t=getenv(s);
+ bs.assfmt("%s=%s",s,t?t:"");
+ restore->push_back(bs);
+ }
+ putenv(p[i]);
+ }
+}
+static int eq_to_eq(const char*s, const char*t)
+{
+ size_t i;
+ for(i=0;i<strlen(s);i++) {
+ if(s[i]=='=' && t[i]=='=')return i;
+ if(s[i]=='=')return -1;
}
+ return -1;
}
static
@@ -256,82 +306,121 @@ set_ulimit(const BaseString & pair){
return 0;
}
-void
-CPCD::Process::do_exec() {
- size_t i;
- setup_environment(m_env.c_str());
-
- char **argv = BaseString::argify(m_path.c_str(), m_args.c_str());
-
- if(strlen(m_cwd.c_str()) > 0) {
- int err = chdir(m_cwd.c_str());
- if(err == -1) {
- BaseString err;
- logger.error("%s: %s\n", m_cwd.c_str(), strerror(errno));
- _exit(1);
- }
- }
+inline int chdir(const char *dir)
+{
+ return _chdir(dir);
+}
- Vector<BaseString> ulimit;
- m_ulimit.split(ulimit);
- for(i = 0; i<ulimit.size(); i++){
- if(ulimit[i].trim().length() > 0 && set_ulimit(ulimit[i]) != 0){
+const int S_IRUSR = _S_IREAD, S_IWUSR = _S_IWRITE;
+int
+CPCD::Process::do_redir(int std_dups[3]) {
+ const char *nul = IF_WIN("nul:","/dev/null");
+ int fdnull = open(nul, O_RDWR, 0);
+ if(fdnull == -1) {
+ logger.error("Cannot open `%s': %s\n", nul, strerror(errno));
_exit(1);
- }
- }
-
- int fd = open("/dev/null", O_RDWR, 0);
- if(fd == -1) {
- logger.error("Cannot open `/dev/null': %s\n", strerror(errno));
- _exit(1);
}
BaseString * redirects[] = { &m_stdin, &m_stdout, &m_stderr };
- int fds[3];
+ int i, fd;
for(i = 0; i<3; i++){
+ std_dups[i] = dup(i);
if(redirects[i]->empty()){
#ifndef DEBUG
- dup2(fd, i);
+ dup2(fdnull, i);
#endif
continue;
}
-
+
if((* redirects[i]) == "2>&1" && i == 2){
- dup2(fds[1], 2);
+ dup2(1, 2);
continue;
- }
-
+ }
/**
* Make file
*/
- int flags = 0;
+ int flags = IF_WIN(_O_NOINHERIT, 0);
int mode = S_IRUSR | S_IWUSR ;
if(i == 0){
flags |= O_RDONLY;
} else {
flags |= O_WRONLY | O_CREAT | O_APPEND;
}
- int f = fds[i]= open(redirects[i]->c_str(), flags, mode);
- if(f == -1){
+ fd = open(redirects[i]->c_str(), flags, mode);
+ if(fd == -1){
logger.error("Cannot redirect %ld to/from '%s' : %s\n", i,
redirects[i]->c_str(), strerror(errno));
_exit(1);
}
- dup2(f, i);
+ dup2(fd, i);
+ close(fd);
+ }
+ close(fdnull);
+ return 0;
+}
+
+void
+CPCD::Process::do_spawn() {
+ do_exec();
+}
+void
+CPCD::Process::do_exec() {
+ size_t i;
+ char **argv = BaseString::argify(m_path.c_str(), m_args.c_str());
+#ifdef _WIN32
+ VBS restore;
+#endif
+ setup_environment(m_env.c_str(),IF_WIN(&restore,0));
+ int std_dups[3];
+ do_redir(std_dups);
+ if(strlen(m_cwd.c_str()) > 0) {
+ int err = chdir(m_cwd.c_str());
+ if(err == -1) {
+ BaseString err;
+ logger.error("%s: %s\n", m_cwd.c_str(), strerror(errno));
+ _exit(1);
+ }
+ }
+
+#ifndef _WIN32
+ Vector<BaseString> ulimit;
+ m_ulimit.split(ulimit);
+ for(i = 0; i<ulimit.size(); i++){
+ if(ulimit[i].trim().length() > 0 && set_ulimit(ulimit[i]) != 0){
+ _exit(1);
+ }
}
- /* Close all filedescriptors */
for(i = STDERR_FILENO+1; (int)i < getdtablesize(); i++)
close(i);
-
execv(m_path.c_str(), argv);
/* XXX If we reach this point, an error has occurred, but it's kind of hard
* to report it, because we've closed all files... So we should probably
* create a new logger here */
logger.error("Exec failed: %s\n", strerror(errno));
/* NOTREACHED */
+#else
+ /* Close all filedescriptors */
+ //_fcloseall();
+ HANDLE proc = (HANDLE)_spawnvp(_P_NOWAIT, m_path.c_str(), argv);
+ for(i=0;i<3;i++) {// reinstate std i/o
+ assert(!dup2(std_dups[i],i));
+ assert(!close(std_dups[i]));
+ }
+ for (i=0; i<restore.size(); i++)
+ putenv(restore[i].c_str());
+ int pid = GetProcessId(proc);
+ assert(pid);
+ writePid(pid);
+#endif
}
+#ifdef _WIN32
+inline void sched_yield()
+{
+ Sleep(100);
+}
+#endif
int
CPCD::Process::start() {
/* We need to fork() twice, so that the second child (grandchild?) can
@@ -352,6 +441,7 @@ CPCD::Process::start() {
int pid = -1;
switch(m_processType){
case TEMPORARY:{
+#ifndef _WIN32
/**
* Simple fork
* don't ignore child
@@ -375,8 +465,12 @@ CPCD::Process::start() {
logger.debug("Started temporary %d : pid=%d", m_id, pid);
break;
}
+#else
+ do_spawn();
+#endif
break;
}
+#ifndef _WIN32
case PERMANENT:{
/**
* PERMANENT
@@ -417,22 +511,21 @@ CPCD::Process::start() {
}
break;
}
+#endif
default:
logger.critical("Unknown process type");
return -1;
}
-
while(readPid() < 0){
sched_yield();
}
errno = 0;
- pid_t pgid = getpgid(pid);
+ pid_t pgid = IF_WIN(-1,getpgid(pid));
if(pgid != -1 && pgid != m_pid){
logger.error("pgid and m_pid don't match: %d %d (%d)", pgid, m_pid, pid);
}
-
if(isRunning()){
m_status = RUNNING;
return 0;
@@ -454,7 +547,7 @@ CPCD::Process::stop() {
return;
}
m_status = STOPPING;
-
+#ifndef _WIN32
errno = 0;
int signo= SIGTERM;
if(m_shutdown_options == "SIGKILL")
@@ -482,7 +575,7 @@ CPCD::Process::stop() {
break;
}
}
-
+#endif
m_pid = -1;
m_status = STOPPED;
}
=== modified file 'storage/ndb/src/cw/cpcd/common.cpp'
--- a/storage/ndb/src/cw/cpcd/common.cpp 2009-06-11 12:28:55 +0000
+++ b/storage/ndb/src/cw/cpcd/common.cpp 2009-09-15 10:02:46 +0000
@@ -32,6 +32,7 @@ int debug = 0;
Logger logger;
+#ifndef _WIN32
int
runas(const char * user){
if(user == 0 || strlen(user) == 0){
@@ -56,6 +57,7 @@ runas(const char * user){
}
return res;
}
+#endif
int
insert(const char * pair, Properties & p){
=== modified file 'storage/ndb/src/cw/cpcd/main.cpp'
--- a/storage/ndb/src/cw/cpcd/main.cpp 2009-06-11 12:28:55 +0000
+++ b/storage/ndb/src/cw/cpcd/main.cpp 2009-09-15 10:02:46 +0000
@@ -31,6 +31,7 @@
#include <logger/Logger.hpp>
#include <logger/FileLogHandler.hpp>
#include <logger/SysLogHandler.hpp>
+#include <logger/ConsoleLogHandler.hpp>
#include "common.hpp"
@@ -110,15 +111,17 @@ int main(int argc, char** argv){
logger.setCategory("ndb_cpcd");
logger.enable(Logger::LL_ALL);
-
+#ifdef _WIN32
+ debug=1;
+#endif
if(debug)
logger.createConsoleHandler();
-
+#ifndef _WIN32
if(user && runas(user) != 0){
logger.critical("Unable to change user: %s", user);
_exit(1);
}
-
+#endif
if(logfile != NULL){
BaseString tmp;
if(logfile[0] != '/')
@@ -126,10 +129,10 @@ int main(int argc, char** argv){
tmp.append(logfile);
logger.addHandler(new FileLogHandler(tmp.c_str()));
}
-
+#ifndef _WIN32
if(use_syslog)
logger.addHandler(new SysLogHandler());
-
+#endif
logger.info("Starting");
#if defined SIGPIPE && !defined _WIN32
Attachment: [text/bzr-bundle] bzr/jack@sun.com-20090915100246-6u7l0cb7az67yu9y.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-7.0 branch (jack:3003) | jack andrews | 15 Sep |