python ctypes and sysctl
You are not providing the correct values to the sysctl function. Detailed information on the arguments of sysctl() can be found here.
Here are your errors:
- You have forgotten the nlen argument (second argument)
- The oldlenp argument is a pointer to the size, not directly the size
Here is the correct function (with minor improvement):
def posix_sysctl_long(name):
_mem = c_uint64(0)
_def = sysctl_names[name]
_arr = c_int * len(_def)
_name = _arr()
for i, v in enumerate(_def):
_name[i] = c_int(v)
_sz = c_size_t(sizeof(_mem))
result = libc.sysctl(_name, len(_def), byref(_mem), byref(_sz), None, c_size_t(0))
if result != 0:
raise Exception('sysctl returned with error %s' % result)
return _mem.value
In python how do I get the value of kern.module_path?
I think your best bet is the sysctl library: https://pypi.python.org/pypi/sysctl/0.1b2
Alternatively, you could use ctypes to interface directly with the C library. There's already a stackoverflow answer with an example of how to read sysctl values here: python ctypes and sysctl
(Obviously, if you wanted to set values, you would have to modify that ctypes example a little).
Garbage uint64 values from ctypes
In if_data64
, the ifi_baudrate
field should be c_uint64
instead of c_uint32
. Fixing this should align ifi_bytes
and ifo_bytes
to the correct offset. It's also missing the last field, ifi_lastchange
. This is an 8 byte timeval32
struct. All together, this explains why sdl
needed an extra 12 byte offset.
class timeval32(Structure):
_fields_ = [('tv_sec', c_int32),
('tv_usec', c_int32)]
class if_data64(Structure):
_pack_ = 4
_fields_ = [('ifi_type', c_ubyte),
('ifi_typelen', c_ubyte),
('ifi_physical', c_ubyte),
('ifi_addrlen', c_ubyte),
('ifi_hdrlen', c_ubyte),
('ifi_recvquota', c_ubyte),
('ifi_xmitquota', c_ubyte),
('ifi_unused1', c_ubyte),
('ifi_mtu', c_uint32),
('ifi_metric', c_uint32),
('ifi_baudrate', c_uint64), # was c_uint32
('ifi_ipackets', c_uint64),
('ifi_ierrors', c_uint64),
('ifi_opackets', c_uint64),
('ifi_oerrors', c_uint64),
('ifi_collisions', c_uint64),
('ifi_ibytes', c_uint64),
('ifi_obytes', c_uint64),
('ifi_imcasts', c_uint64),
('ifi_omcasts', c_uint64),
('ifi_iqdrops', c_uint64),
('ifi_noproto', c_uint64),
('ifi_recvtiming', c_uint32),
('ifi_xmittiming', c_uint32),
('ifi_lastchange', timeval32)] # was missing
Instead of using cast
with pointers, I'd write the loop using the from_buffer
method (Python 2.6+) and offsets.
buf_offset = 0
while buf_offset < sysctl_buf_len.value:
msg_offset = buf_offset
ifmsg = if_msghdr2.from_buffer(sysctl_buf, msg_offset)
buf_offset += ifmsg.ifm_msglen
if ifmsg.ifm_type != RTM_IFINFO2 or ifmsg.ifm_flags & IFF_LOOPBACK:
continue
sdl_offset = msg_offset + c_sizeof(if_msghdr2)
sdl = sockaddr_dl.from_buffer(sysctl_buf, sdl_offset)
if sdl.sdl_family != AF_LINK:
continue
print sdl.sdl_data[:sdl.sdl_nlen]
print ifmsg.ifm_data.ifi_ibytes, ifmsg.ifm_data.ifi_obytes
Why is multiprocessing copying my data if I don't touch it?
The problem was that by default Linux checks for the worst case memory usage, which can indeed exceed memory capacity. This is true even if the python language doesn't exposure the variables. You need to turn off "overcommit" system wide, to achieve the expected COW behavior.
sysctl `vm.overcommit_memory=2'
See https://www.kernel.org/doc/Documentation/vm/overcommit-accounting
Measuring elapsed time in python
You can use perf_counter
function of time module in Python Standard Library:
from datetime import timedelta
from time import perf_counter
startTime = perf_counter()
CallYourFunc()
finishedTime = perf_counter()
duration = timedelta(seconds=(finishedTime - startTime))
Related Topics
Groupby Weighted Average and Sum in Pandas Dataframe
Linux/Python: Encoding a Unicode String for Print
How to Disable Stdout Buffer When Running Shell
Saving Stdout from Subprocess.Popen to File, Plus Writing More Stuff to the File
Python 2.7 Cannot Import Pyqt4
Understanding Python Fork and Memory Allocation Errors
How to Send Input on Stdin to a Python Script Defined Inside a Makefile
Decrypt Chrome Linux Blob Encrypted Cookies in Python
Cannot Bind Numpad Minus Key on Linux with Tkinter
Mime.Hasimage()' Returns 'True' But 'Mime.Imagedata()' Returns 'None' on Linux