This source file includes following definitions.
- pcmk__procfs_process_info
- pcmk__procfs_pid_of
- pcmk__procfs_num_cores
- pcmk__procfs_pid2path
- pcmk__procfs_has_pids
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #ifndef _GNU_SOURCE
13 # define _GNU_SOURCE
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <dirent.h>
22 #include <ctype.h>
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 static int
40 pcmk__procfs_process_info(const struct dirent *entry, char *name, pid_t *pid)
41 {
42 int fd, local_pid;
43 FILE *file;
44 struct stat statbuf;
45 char procpath[128] = { 0 };
46
47
48
49
50
51
52 local_pid = atoi(entry->d_name);
53 if ((local_pid <= 0) || (strlen(entry->d_name) > 114)) {
54 return -1;
55 }
56 if (pid) {
57 *pid = (pid_t) local_pid;
58 }
59
60
61 strcpy(procpath, "/proc/");
62 strcat(procpath, entry->d_name);
63 fd = open(procpath, O_RDONLY);
64 if (fd < 0 ) {
65 return -1;
66 }
67 if (fstat(fd, &statbuf) < 0) {
68 close(fd);
69 return -1;
70 }
71 close(fd);
72
73
74 if (!S_ISDIR(statbuf.st_mode)) {
75 return -1;
76 }
77
78
79
80
81
82 if (name != NULL) {
83 strcat(procpath, "/status");
84 file = fopen(procpath, "r");
85 if (!file) {
86 return -1;
87 }
88 if (fscanf(file, "Name:\t%15[^\n]", name) != 1) {
89 fclose(file);
90 return -1;
91 }
92 name[15] = 0;
93 fclose(file);
94 }
95
96 return 0;
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110 pid_t
111 pcmk__procfs_pid_of(const char *name)
112 {
113 DIR *dp;
114 struct dirent *entry;
115 pid_t pid = 0;
116 char entry_name[64] = { 0 };
117
118 dp = opendir("/proc");
119 if (dp == NULL) {
120 crm_notice("Can not read /proc directory to track existing components");
121 return 0;
122 }
123
124 while ((entry = readdir(dp)) != NULL) {
125 if ((pcmk__procfs_process_info(entry, entry_name, &pid) == pcmk_rc_ok)
126 && pcmk__str_eq(entry_name, name, pcmk__str_casei)
127 && (pcmk__pid_active(pid, NULL) == pcmk_rc_ok)) {
128
129 crm_info("Found %s active as process %lld", name, (long long) pid);
130 break;
131 }
132 pid = 0;
133 }
134 closedir(dp);
135 return pid;
136 }
137
138
139
140
141
142
143
144 unsigned int
145 pcmk__procfs_num_cores(void)
146 {
147 int cores = 0;
148 FILE *stream = NULL;
149
150
151 stream = fopen("/proc/stat", "r");
152 if (stream == NULL) {
153 crm_perror(LOG_INFO, "Could not open /proc/stat");
154 } else {
155 char buffer[2048];
156
157 while (fgets(buffer, sizeof(buffer), stream)) {
158 if (pcmk__starts_with(buffer, "cpu") && isdigit(buffer[3])) {
159 ++cores;
160 }
161 }
162 fclose(stream);
163 }
164 return cores? cores : 1;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178 int
179 pcmk__procfs_pid2path(pid_t pid, char path[], size_t path_size)
180 {
181 #if HAVE_LINUX_PROCFS
182 char procfs_exe_path[PATH_MAX];
183 ssize_t link_rc;
184
185 if (snprintf(procfs_exe_path, PATH_MAX, "/proc/%lld/exe",
186 (long long) pid) >= PATH_MAX) {
187 return ENAMETOOLONG;
188 }
189
190 link_rc = readlink(procfs_exe_path, path, path_size - 1);
191 if (link_rc < 0) {
192 return errno;
193 } else if (link_rc >= (path_size - 1)) {
194 return ENAMETOOLONG;
195 }
196
197 path[link_rc] = '\0';
198 return pcmk_rc_ok;
199 #else
200 return EOPNOTSUPP;
201 #endif
202 }
203
204
205
206
207
208
209
210 bool
211 pcmk__procfs_has_pids(void)
212 {
213 #if HAVE_LINUX_PROCFS
214 static bool have_pids = false;
215 static bool checked = false;
216
217 if (!checked) {
218 char path[PATH_MAX];
219
220 have_pids = pcmk__procfs_pid2path(getpid(), path, sizeof(path)) == pcmk_rc_ok;
221 checked = true;
222 }
223 return have_pids;
224 #else
225 return false;
226 #endif
227 }