2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 Copyright (c) 2005 Eliot Dresselhaus
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #include <vppinfra/error.h>
39 #include <vppinfra/os.h>
40 #include <vppinfra/bitmap.h>
41 #include <vppinfra/unix.h>
42 #include <vppinfra/format.h>
44 #include <vppinfra/linux/sysfs.h>
48 #include <sys/types.h>
49 #include <sys/syscall.h>
50 #include <sys/uio.h> /* writev */
52 #include <stdio.h> /* for sprintf */
55 __clib_export __thread uword __os_thread_index = 0;
56 __clib_export __thread uword __os_numa_index = 0;
59 clib_file_n_bytes (char *file, uword * result)
63 if (stat (file, &s) < 0)
64 return clib_error_return_unix (0, "stat `%s'", file);
66 if (S_ISREG (s.st_mode))
71 return /* no error */ 0;
75 clib_file_read_contents (char *file, u8 * result, uword n_bytes)
79 clib_error_t *error = 0;
82 if ((fd = open (file, 0)) < 0)
83 return clib_error_return_unix (0, "open `%s'", file);
90 if ((n_read = read (fd, v + n_done, n_left)) < 0)
92 error = clib_error_return_unix (0, "open `%s'", file);
107 clib_error_return (0,
108 " `%s' expected to read %wd bytes; read only %wd",
109 file, n_bytes, n_bytes - n_left);
118 __clib_export clib_error_t *
119 clib_file_contents (char *file, u8 ** result)
122 clib_error_t *error = 0;
125 if ((error = clib_file_n_bytes (file, &n_bytes)))
129 vec_resize (v, n_bytes);
131 error = clib_file_read_contents (file, v, n_bytes);
142 clib_file_get_resolved_basename (char *fmt, ...)
145 char *p, buffer[PATH_MAX];
150 link = va_format (0, fmt, &va);
154 r = readlink ((char *) link, buffer, sizeof (buffer) - 1);
162 while (p > buffer && p[-1] != '/')
166 vec_add1 (s, p++[0]);
173 unix_proc_file_contents (char *file, u8 ** result)
179 /* Unfortunately, stat(/proc/XXX) returns zero... */
180 fd = open (file, O_RDONLY);
183 return clib_error_return_unix (0, "open `%s'", file);
185 vec_validate (rv, 4095);
189 bytes = read (fd, rv + pos, 4096);
194 return clib_error_return_unix (0, "read '%s'", file);
199 vec_set_len (rv, pos);
203 vec_validate (rv, pos + 4095);
210 void os_panic (void) __attribute__ ((weak));
218 void os_exit (int) __attribute__ ((weak));
226 void os_puts (u8 * string, uword string_length, uword is_error)
227 __attribute__ ((weak));
230 os_puts (u8 * string, uword string_length, uword is_error)
232 int cpu = os_get_thread_index ();
233 int nthreads = os_get_nthreads ();
235 int fd = is_error ? 2 : 1;
236 struct iovec iovs[2];
241 snprintf (buf, sizeof (buf), "%d: ", cpu);
243 iovs[n_iovs].iov_base = buf;
244 iovs[n_iovs].iov_len = strlen (buf);
248 iovs[n_iovs].iov_base = string;
249 iovs[n_iovs].iov_len = string_length;
252 if (writev (fd, iovs, n_iovs) < 0)
256 __clib_export __clib_weak void
257 os_out_of_memory (void)
262 __clib_export __clib_weak uword
263 os_get_nthreads (void)
268 __clib_export clib_bitmap_t *
269 os_get_online_cpu_core_bitmap ()
272 return clib_sysfs_read_bitmap ("/sys/devices/system/cpu/online");
278 __clib_export clib_bitmap_t *
279 os_get_cpu_affinity_bitmap (int pid)
284 uword *affinity_cpus;
286 clib_bitmap_alloc (affinity_cpus, sizeof (cpu_set_t));
287 clib_bitmap_zero (affinity_cpus);
289 __CPU_ZERO_S (sizeof (cpu_set_t), &cpuset);
291 ret = syscall (SYS_sched_getaffinity, 0, sizeof (cpu_set_t), &cpuset);
295 clib_bitmap_free (affinity_cpus);
299 for (index = 0; index < sizeof (cpu_set_t); index++)
300 if (__CPU_ISSET_S (index, sizeof (cpu_set_t), &cpuset))
301 clib_bitmap_set (affinity_cpus, index, 1);
302 return affinity_cpus;
308 __clib_export clib_bitmap_t *
309 os_get_online_cpu_node_bitmap ()
312 return clib_sysfs_read_bitmap ("/sys/devices/system/node/online");
317 __clib_export clib_bitmap_t *
318 os_get_cpu_on_node_bitmap (int node)
321 return clib_sysfs_read_bitmap ("/sys/devices/system/node/node%u/cpulist",
328 __clib_export clib_bitmap_t *
329 os_get_cpu_with_memory_bitmap ()
332 return clib_sysfs_read_bitmap ("/sys/devices/system/node/has_memory");
339 os_get_cpu_phys_core_id (int cpu_id)
347 format (0, "/sys/devices/system/cpu/cpu%u/topology/core_id%c", cpu_id, 0);
348 err = clib_sysfs_read ((char *) p, "%d", &core_id);
352 clib_error_free (err);
362 * fd.io coding-style-patch-verification: ON
365 * eval: (c-set-style "gnu")