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