| 105 | } |
| 106 | |
| 107 | gboolean |
| 108 | start_subsystem(struct crm_subsystem_s * the_subsystem) |
| 109 | { |
| 110 | pid_t pid; |
| 111 | struct stat buf; |
| 112 | int s_res; |
| 113 | unsigned int j; |
| 114 | struct rlimit oflimits; |
| 115 | const char *devnull = "/dev/null"; |
| 116 | |
| 117 | crm_info("Starting sub-system \"%s\"", the_subsystem->name); |
| 118 | |
| 119 | if (the_subsystem->pid > 0) { |
| 120 | crm_warn("Client %s already running as pid %d", |
| 121 | the_subsystem->name, (int)the_subsystem->pid); |
| 122 | |
| 123 | /* starting a started X is not an error */ |
| 124 | return TRUE; |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | * We want to ensure that the exec will succeed before |
| 129 | * we bother forking. |
| 130 | */ |
| 131 | |
| 132 | if (access(the_subsystem->path, F_OK | X_OK) != 0) { |
| 133 | crm_perror(LOG_ERR, "Cannot (access) exec %s", the_subsystem->path); |
| 134 | return FALSE; |
| 135 | } |
| 136 | |
| 137 | s_res = stat(the_subsystem->command, &buf); |
| 138 | if (s_res != 0) { |
| 139 | crm_perror(LOG_ERR, "Cannot (stat) exec %s", the_subsystem->command); |
| 140 | return FALSE; |
| 141 | } |
| 142 | |
| 143 | /* We need to fork so we can make child procs not real time */ |
| 144 | switch (pid = fork()) { |
| 145 | case -1: |
| 146 | crm_err("Cannot fork."); |
| 147 | return FALSE; |
| 148 | |
| 149 | default: /* Parent */ |
| 150 | g_child_watch_add(pid, crmdManagedChildDied, the_subsystem); |
| 151 | crm_trace("Client %s is has pid: %d", the_subsystem->name, pid); |
| 152 | the_subsystem->pid = pid; |
| 153 | return TRUE; |
| 154 | |
| 155 | case 0: /* Child */ |
| 156 | /* create a new process group to avoid |
| 157 | * being interupted by heartbeat |
| 158 | */ |
| 159 | setpgid(0, 0); |
| 160 | break; |
| 161 | } |
| 162 | |
| 163 | crm_debug("Executing \"%s (%s)\" (pid %d)", |
| 164 | the_subsystem->command, the_subsystem->name, (int)getpid()); |
no test coverage detected