~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/common/portlib/NdbDaemon.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include "NdbDaemon.h"
 
18
 
 
19
#define NdbDaemon_ErrorSize 500
 
20
long NdbDaemon_DaemonPid = 0;
 
21
int NdbDaemon_ErrorCode = 0;
 
22
char NdbDaemon_ErrorText[NdbDaemon_ErrorSize] = "";
 
23
 
 
24
int
 
25
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
 
26
{
 
27
  int lockfd = -1, logfd = -1, n;
 
28
  char buf[64];
 
29
 
 
30
  (void)flags; /* remove warning for unused parameter */
 
31
 
 
32
  /* Check that we have write access to lock file */
 
33
  assert(lockfile != NULL);
 
34
  lockfd = open(lockfile, O_CREAT|O_RDWR, 0644);
 
35
  if (lockfd == -1) {
 
36
    NdbDaemon_ErrorCode = errno;
 
37
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
38
        "%s: open for write failed: %s", lockfile, strerror(errno));
 
39
    return -1;
 
40
  }
 
41
  /* Read any old pid from lock file */
 
42
  buf[0] = 0;
 
43
  n = read(lockfd, buf, sizeof(buf));
 
44
  if (n < 0) {
 
45
    NdbDaemon_ErrorCode = errno;
 
46
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
47
        "%s: read failed: %s", lockfile, strerror(errno));
 
48
    return -1;
 
49
  }
 
50
  NdbDaemon_DaemonPid = atol(buf);
 
51
  if (lseek(lockfd, 0, SEEK_SET) == -1) {
 
52
    NdbDaemon_ErrorCode = errno;
 
53
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
54
        "%s: lseek failed: %s", lockfile, strerror(errno));
 
55
    return -1;
 
56
  }
 
57
#ifdef F_TLOCK
 
58
  /* Test for lock before becoming daemon */
 
59
  if (lockf(lockfd, F_TLOCK, 0) == -1) 
 
60
  {
 
61
    if (errno == EACCES || errno == EAGAIN) {   /* results may vary */
 
62
      snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
63
               "%s: already locked by pid=%ld", lockfile, NdbDaemon_DaemonPid);
 
64
      return -1;
 
65
    }
 
66
    NdbDaemon_ErrorCode = errno;
 
67
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
68
        "%s: lock test failed: %s", lockfile, strerror(errno));
 
69
    return -1;
 
70
  }
 
71
#endif
 
72
  /* Test open log file before becoming daemon */
 
73
  if (logfile != NULL) {
 
74
    logfd = open(logfile, O_CREAT|O_WRONLY|O_APPEND, 0644);
 
75
    if (logfd == -1) {
 
76
      NdbDaemon_ErrorCode = errno;
 
77
      snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
78
          "%s: open for write failed: %s", logfile, strerror(errno));
 
79
      return -1;
 
80
    }
 
81
  }
 
82
#ifdef F_TLOCK
 
83
  if (lockf(lockfd, F_ULOCK, 0) == -1) 
 
84
  {
 
85
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
86
             "%s: fail to unlock", lockfile);
 
87
    return -1;
 
88
  }
 
89
#endif
 
90
  
 
91
  /* Fork */
 
92
  n = fork();
 
93
  if (n == -1) {
 
94
    NdbDaemon_ErrorCode = errno;
 
95
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
96
        "fork failed: %s", strerror(errno));
 
97
    return -1;
 
98
  }
 
99
  /* Exit if we are the parent */
 
100
  if (n != 0) {
 
101
    exit(0);
 
102
  }
 
103
  /* Running in child process */
 
104
  NdbDaemon_DaemonPid = getpid();
 
105
  /* Lock the lock file (likely to succeed due to test above) */
 
106
  if (lockf(lockfd, F_LOCK, 0) == -1) {
 
107
    NdbDaemon_ErrorCode = errno;
 
108
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
109
        "%s: lock failed: %s", lockfile, strerror(errno));
 
110
    return -1;
 
111
  }
 
112
  /* Become process group leader */
 
113
  if (setsid() == -1) {
 
114
    NdbDaemon_ErrorCode = errno;
 
115
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
116
        "setsid failed: %s", strerror(errno));
 
117
    return -1;
 
118
  }
 
119
  /* Write pid to lock file */
 
120
  if (ftruncate(lockfd, 0) == -1) {
 
121
    NdbDaemon_ErrorCode = errno;
 
122
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
123
        "%s: ftruncate failed: %s", lockfile, strerror(errno));
 
124
    return -1;
 
125
  }
 
126
  sprintf(buf, "%ld\n", NdbDaemon_DaemonPid);
 
127
  n = strlen(buf);
 
128
  if (write(lockfd, buf, n) != n) {
 
129
    NdbDaemon_ErrorCode = errno;
 
130
    snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
131
        "%s: write failed: %s", lockfile, strerror(errno));
 
132
    return -1;
 
133
  }
 
134
  /* Do input/output redirections (assume fd 0,1,2 not in use) */
 
135
  close(0);
 
136
  open("/dev/null", O_RDONLY);
 
137
  if (logfile != 0) {
 
138
    dup2(logfd, 1);
 
139
    dup2(logfd, 2);
 
140
    close(logfd);
 
141
  }
 
142
  /* Success */
 
143
  return 0;
 
144
}
 
145
 
 
146
#if 0
 
147
int
 
148
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
 
149
{
 
150
  /* Fail */
 
151
  snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
 
152
           "Daemon mode not implemented");
 
153
  return -1;
 
154
}
 
155
#endif
 
156
 
 
157
#ifdef NDB_DAEMON_TEST
 
158
 
 
159
int
 
160
main()
 
161
{
 
162
  if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
 
163
    fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
 
164
    return 1;
 
165
  }
 
166
  sleep(10);
 
167
  return 0;
 
168
}
 
169
 
 
170
#endif