Apache Mesos
freebsd.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_OS_FREEBSD_HPP__
14 #define __STOUT_OS_FREEBSD_HPP__
15 
16 // This file contains FreeBSD-only OS utilities.
17 #ifndef __FreeBSD__
18 #error "stout/os/freebsd.hpp is only available on FreeBSD systems."
19 #endif
20 
21 #include <sys/types.h>
22 #include <sys/user.h>
23 #include <unistd.h>
24 
25 #include <stout/os/pagesize.hpp>
26 #include <stout/os/sysctl.hpp>
27 
28 namespace os {
29 
31 {
32  // KERN_PROC_PID fails for zombies, so we fetch the whole process table and
33  // find our process manually.
34 
35  const Try<std::vector<kinfo_proc>> kinfos =
36  os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL).table();
37 
38  if (kinfos.isError()) {
39  return Error("Failed to retrieve process table via sysctl: " +
40  kinfos.error());
41  }
42 
43  foreach (const kinfo_proc& kinfo, kinfos.get()) {
44  if (kinfo.ki_pid == pid) {
45  size_t pagesize = os::pagesize();
46  return Process(kinfo.ki_pid,
47  kinfo.ki_ppid,
48  kinfo.ki_pgid,
49  kinfo.ki_sid,
50  kinfo.ki_rssize * pagesize,
51  kinfo.ki_rusage.ru_utime,
52  kinfo.ki_rusage.ru_stime,
53  kinfo.ki_comm,
54  kinfo.ki_stat == SZOMB);
55  }
56  }
57 
58  return None();
59 }
60 
61 
63 {
64  std::set<pid_t> result;
65 
66  const Try<std::vector<kinfo_proc>> kinfos =
67  os::sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL).table();
68 
69  foreach (const kinfo_proc& kinfo, kinfos.get()) {
70  result.insert(kinfo.ki_pid);
71  }
72 
73  return result;
74 }
75 
76 
77 // Returns the total size of main and free memory.
79 {
80  Memory memory;
81 
82  const Try<int64_t> physicalMemory = os::sysctl(CTL_HW, HW_PHYSMEM).integer();
83  if (physicalMemory.isError()) {
84  return Error(physicalMemory.error());
85  }
86  memory.total = Bytes(physicalMemory.get());
87 
88  const size_t pageSize = os::pagesize();
89 
90  unsigned int freeCount;
91  size_t freeCountLength = sizeof(freeCount);
92  if (sysctlbyname(
93  "vm.stats.vm.v_free_count",
94  &freeCount,
95  &freeCountLength,
96  nullptr,
97  0) != 0) {
98  return ErrnoError();
99  }
100 
101  unsigned int inactiveCount;
102  size_t inactiveCountLength = sizeof(inactiveCount);
103  if (sysctlbyname(
104  "vm.stats.vm.v_inactive_count",
105  &inactiveCount,
106  &inactiveCountLength,
107  nullptr,
108  0) != 0) {
109  return ErrnoError();
110  }
111 
112  memory.free = Bytes((freeCount + inactiveCount) * pageSize);
113 
114  int totalBlocks = 0;
115  int usedBlocks = 0;
116 
117  int mib[3];
118  size_t mibSize = 2;
119  if (::sysctlnametomib("vm.swap_info", mib, &mibSize) != 0) {
120  return ErrnoError();
121  }
122 
123  // FreeBSD supports multiple swap devices. Here we sum across all of them.
124  struct xswdev xswd;
125  size_t xswdSize = sizeof(xswd);
126  for (int ndev = 0; ; ndev++) {
127  mib[mibSize] = ndev;
128 
129  if (::sysctl(mib, 3, &xswd, &xswdSize, nullptr, 0) != 0) {
130  if (errno == ENOENT) {
131  break;
132  }
133  return ErrnoError();
134  }
135 
136  totalBlocks += xswd.xsw_nblks;
137  usedBlocks += xswd.xsw_used;
138  }
139 
140  memory.totalSwap = Bytes(totalBlocks * pageSize);
141  memory.freeSwap = Bytes((totalBlocks - usedBlocks) * pageSize);
142 
143  return memory;
144 }
145 
146 } // namespace os {
147 
148 #endif
Definition: errorbase.hpp:36
T & get()&
Definition: try.hpp:80
Definition: check.hpp:33
size_t pagesize()
Definition: pagesize.hpp:24
Definition: errorbase.hpp:50
Definition: posix_signalhandler.hpp:23
Definition: check.hpp:30
Bytes freeSwap
Definition: os.hpp:39
DWORD pid_t
Definition: windows.hpp:181
Definition: process.hpp:32
Table table(const Option< size_t > &length=None()) const
Definition: sysctl.hpp:229
Bytes totalSwap
Definition: os.hpp:38
Integer integer() const
Definition: sysctl.hpp:182
static Try error(const E &e)
Definition: try.hpp:43
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Definition: os.hpp:34
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:78
Bytes total
Definition: os.hpp:36
Definition: sysctl.hpp:59
Definition: bytes.hpp:30
Try< Memory > memory()
Definition: freebsd.hpp:78
Bytes free
Definition: os.hpp:37
Try< std::set< pid_t > > pids()
Definition: freebsd.hpp:62