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.
42 #include <vppinfra/error.h>
43 #include <vppinfra/os.h>
44 #include <vppinfra/bitmap.h>
45 #include <vppinfra/unix.h>
46 #include <vppinfra/format.h>
48 #include <vppinfra/linux/sysfs.h>
50 #elif defined(__FreeBSD__)
51 #define _WANT_FREEBSD_BITSET
52 #include <sys/cdefs.h>
53 #include <sys/param.h>
54 #include <sys/types.h>
55 #include <sys/cpuset.h>
56 #include <sys/domainset.h>
57 #include <sys/sysctl.h>
61 #include <sys/types.h>
62 #include <sys/uio.h> /* writev */
64 #include <stdio.h> /* for sprintf */
67 __clib_export __thread uword __os_thread_index = 0;
68 __clib_export __thread uword __os_numa_index = 0;
71 clib_file_n_bytes (char *file, uword * result)
75 if (stat (file, &s) < 0)
76 return clib_error_return_unix (0, "stat `%s'", file);
78 if (S_ISREG (s.st_mode))
83 return /* no error */ 0;
87 clib_file_read_contents (char *file, u8 * result, uword n_bytes)
91 clib_error_t *error = 0;
94 if ((fd = open (file, 0)) < 0)
95 return clib_error_return_unix (0, "open `%s'", file);
102 if ((n_read = read (fd, v + n_done, n_left)) < 0)
104 error = clib_error_return_unix (0, "open `%s'", file);
119 clib_error_return (0,
120 " `%s' expected to read %wd bytes; read only %wd",
121 file, n_bytes, n_bytes - n_left);
130 __clib_export clib_error_t *
131 clib_file_contents (char *file, u8 ** result)
134 clib_error_t *error = 0;
137 if ((error = clib_file_n_bytes (file, &n_bytes)))
141 vec_resize (v, n_bytes);
143 error = clib_file_read_contents (file, v, n_bytes);
154 clib_file_get_resolved_basename (char *fmt, ...)
157 char *p, buffer[PATH_MAX];
162 link = va_format (0, fmt, &va);
166 r = readlink ((char *) link, buffer, sizeof (buffer) - 1);
174 while (p > buffer && p[-1] != '/')
178 vec_add1 (s, p++[0]);
185 unix_proc_file_contents (char *file, u8 ** result)
191 /* Unfortunately, stat(/proc/XXX) returns zero... */
192 fd = open (file, O_RDONLY);
195 return clib_error_return_unix (0, "open `%s'", file);
197 vec_validate (rv, 4095);
201 bytes = read (fd, rv + pos, 4096);
206 return clib_error_return_unix (0, "read '%s'", file);
211 vec_set_len (rv, pos);
215 vec_validate (rv, pos + 4095);
222 void os_panic (void) __attribute__ ((weak));
230 void os_exit (int) __attribute__ ((weak));
238 void os_puts (u8 * string, uword string_length, uword is_error)
239 __attribute__ ((weak));
242 os_puts (u8 * string, uword string_length, uword is_error)
244 int cpu = os_get_thread_index ();
245 int nthreads = os_get_nthreads ();
247 int fd = is_error ? 2 : 1;
248 struct iovec iovs[2];
253 snprintf (buf, sizeof (buf), "%d: ", cpu);
255 iovs[n_iovs].iov_base = buf;
256 iovs[n_iovs].iov_len = strlen (buf);
260 iovs[n_iovs].iov_base = string;
261 iovs[n_iovs].iov_len = string_length;
264 if (writev (fd, iovs, n_iovs) < 0)
268 __clib_export __clib_weak void
269 os_out_of_memory (void)
274 __clib_export __clib_weak uword
275 os_get_nthreads (void)
280 __clib_export clib_bitmap_t *
281 os_get_online_cpu_core_bitmap ()
284 return clib_sysfs_read_bitmap ("/sys/devices/system/cpu/online");
290 __clib_export clib_bitmap_t *
291 os_get_cpu_affinity_bitmap (int pid)
296 uword *affinity_cpus;
298 clib_bitmap_alloc (affinity_cpus, sizeof (cpu_set_t));
299 clib_bitmap_zero (affinity_cpus);
301 __CPU_ZERO_S (sizeof (cpu_set_t), &cpuset);
303 ret = sched_getaffinity (0, sizeof (cpu_set_t), &cpuset);
307 clib_bitmap_free (affinity_cpus);
311 for (index = 0; index < sizeof (cpu_set_t); index++)
312 if (__CPU_ISSET_S (index, sizeof (cpu_set_t), &cpuset))
313 clib_bitmap_set (affinity_cpus, index, 1);
314 return affinity_cpus;
315 #elif defined(__FreeBSD__)
319 if (cpuset_getaffinity (CPU_LEVEL_CPUSET, CPU_WHICH_CPUSET, -1,
320 sizeof (mask), &mask) != 0)
322 clib_bitmap_free (r);
326 for (int bit = 0; bit < CPU_SETSIZE; bit++)
327 clib_bitmap_set (r, bit, CPU_ISSET (bit, &mask));
335 __clib_export clib_bitmap_t *
336 os_get_online_cpu_node_bitmap ()
339 return clib_sysfs_read_bitmap ("/sys/devices/system/node/online");
340 #elif defined(__FreeBSD__)
345 if (cpuset_getdomain (CPU_LEVEL_CPUSET, CPU_WHICH_CPUSET, -1,
346 sizeof (domain), &domain, &policy) != 0)
348 clib_bitmap_free (r);
352 for (int bit = 0; bit < CPU_SETSIZE; bit++)
353 clib_bitmap_set (r, bit, CPU_ISSET (bit, &domain));
359 __clib_export clib_bitmap_t *
360 os_get_cpu_on_node_bitmap (int node)
363 return clib_sysfs_read_bitmap ("/sys/devices/system/node/node%u/cpulist",
370 __clib_export clib_bitmap_t *
371 os_get_cpu_with_memory_bitmap ()
374 return clib_sysfs_read_bitmap ("/sys/devices/system/node/has_memory");
381 os_get_cpu_phys_core_id (int cpu_id)
389 format (0, "/sys/devices/system/cpu/cpu%u/topology/core_id%c", cpu_id, 0);
390 err = clib_sysfs_read ((char *) p, "%d", &core_id);
394 clib_error_free (err);
409 ssize_t sz = readlink ("/proc/self/exe", tmp, sizeof (tmp));
414 char tmp[MAXPATHLEN];
415 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
416 size_t sz = MAXPATHLEN;
418 if (sysctl (mib, 4, tmp, &sz, NULL, 0) == -1)
421 vec_add (rv, tmp, sz);
426 * fd.io coding-style-patch-verification: ON
429 * eval: (c-set-style "gnu")