geopmdpy(7) – global extensible open power manager python daemon package

Description

This document describes the Python APIs provided by the geopmdpy package.

Synopsis

geopmdpy.access

Implementation for the geopmaccess command line tool.

class geopmdpy.access.Access(geopm_proxy)

Bases: object

Extension to the GEOPM D-Bus proxy to support the geopmaccess command line interface.

edited_names(is_control, group)
get_all_controls()

Call GEOPM D-Bus API and return all supported control names

Returns a human readable list of all controls available on the system. The returned string has one control name on each line, and is in sorted order. The PlatformGetAllAccess D-Bus API of the io.github.geopm interface is used.

Returns:

All available controls, one on each line, in sorted order

Return type:

str

get_all_signals()

Call GEOPM D-Bus API and return all supported signal names

Returns a human readable list of all signals available on the platform. The returned string has one signal name on each line, and is in sorted order. The PlatformGetAllAccess D-Bus API of the io.github.geopm interface is used.

Returns:

All available signals, one on each line, in sorted order

Return type:

str

get_group_controls(group)

Call GEOPM D-Bus API and return the group’s control access list

Returns a human readable list of the controls that are enabled. The returned string has one control name on each line, and is in sorted order.

The default control access list is returned if the group provided is the empty string. If the group provided is not empty then the list of controls that are enabled for the specified Unix group is returned.

A user process accessing the GEOPM D-Bus APIs is restricted to the combination of the default access list and the access list for all groups that the user belongs to. The results from querying a specific Unix group with this method do not reflect the default access list that is enabled for all users.

The PlatformGetGroupAccess D-Bus API of the io.github.geopm interface is called.

Parameters:

group (str) – Unix group name to get access list for. Gets the default control access list if group provided is ‘’: the empty string.

Returns:

Access list of controls, one on each line, in sorted order.

Return type:

str

get_group_signals(group)

Call GEOPM D-Bus API and return the group’s signal access list

Returns a human readable list of the signals that are enabled. The returned string has one signal name on each line, and is in sorted order.

The default signal access list is returned if the group provided is the empty string. If the group provided is not empty then the list of signals that are enabled for the specified Unix group is returned.

A user process accessing the GEOPM D-Bus APIs is restricted to the combination of the default access list and the access list for all groups that the user belongs to. The results from querying a specific Unix group with this method do not reflect the default access list that is enabled for all users.

The Platforms D-Bus API of the io.github.geopm interface is called.

Parameters:

group (str) – Unix group name to get access list for. Gets the default signal access list if group provided is ‘’: the empty string.

Returns:

Access list of signals, one on each line, in sorted order.

Return type:

str

get_msr_safe_allowlist()

Generate an allowlist for msr-safe

Generates the minimal msr-safe allowlist required for GEOPM to access all the expected signals and controls.

Returns:

msr-safe allowlist string.

Return type:

str

get_user_controls()

Call GEOPM D-Bus API and return user allowed control names

Returns a human readable list of user allowed controls on the platform. The returned string has one control name on each line, and is in sorted order. The PlatformGetAllAccess D-Bus API of the io.github.geopm interface is used.

Returns:

User allowed controls, one on each line, in sorted order

Return type:

str

get_user_signals()

Call GEOPM D-Bus API and return user allowed signal names

Returns a human readable list of user allowed signal names on the platform. The returned string has one signal name on each line, and is in sorted order. The PlatformGetAllAccess D-Bus API of the io.github.geopm interface is used.

Returns:

User allowed signals, one on each line, in sorted order

Return type:

str

read_names(fid)

Returns list names from user

Parse list of signals or controls from standard input or edit existing list.

run(is_write, is_all, is_control, group, is_default, is_delete, is_dry_run, is_force, is_edit, is_log, is_msr_safe)

Execute geopmaccess command line interface

The inputs to this method are parsed from the command line interface of geopmaccess. All of the features of the geopmaccess tool are implemented with this method.

Parameters:
  • is_write (bool) – True if user requested to write to the access lists, False if it is a read operation.

  • is_all (bool) – True if the user requested that all available signals or controls be printed as opposed to one of the access lists.

  • is_control (bool) – True if the user requested to read or write the control access lists.

  • group (str) – If is_all is not specified, the group determines which access list will be read or written. If the group is the empty string then the default access list is used, otherwise the parameter specifies the Unix group.

  • is_default (bool) – True if the default user access list should be printed rather than the calling process’ access list.

  • is_delete (bool) – True to remove an access list file.

  • is_dry_run (bool) – True to run error checking without file modification

  • is_force (bool) – True if error checking is disabled

  • is_log (bool) – True if log user requested a log of requests since service restart

  • is_msr_safe (bool) – True if user requested msr-safe allowlist

set_group_controls(group, controls, is_dry_run, is_force)

Call GEOPM D-Bus API to set control access

Sets the control access list for a group while leaving the signal access list unchanged. The user must be ‘root’ to perform this operation. The PlatformGetGroupAccess D-Bus API of the io.github.geopm interface is used.

Parameters:
  • group (str) – Unix group name to set access list for. The call sets the default control access list if group provided is ‘’.

  • controls (list(str)) – List of all control names that are allowed for the group or for the defaults.

  • is_dry_run (bool) – True to run error checking without file modification

  • is_force (bool) – True if error checking is disabled

Raises:

RuntimeError – The user is not root, the group provided is invalid, or any of the provided control names are not supported.

set_group_signals(group, signals, is_dry_run, is_force)

Call GEOPM D-Bus API to set signal access

Sets the signal access list for a group while leaving the control access list unchanged. The user must be ‘root’ to perform this operation. The PlatformGetGroupAccess D-Bus API of the io.github.geopm interface is used.

Parameters:
  • group (str) – Unix group name to set access list for. The call sets the default signal access list if group provided is ‘’.

  • signals (list(str)) – List of all signal names that are allowed for the group or for the defaults.

  • is_dry_run (bool) – True to run error checking without file modification

  • is_force (bool) – True if error checking is disabled

Raises:

RuntimeError – The user is not root, the group provided is invalid, or any of the provided signal names are not supported.

class geopmdpy.access.DirectAccessProxy

Bases: object

A proxy for access-related GEOPM service interactions that attempts in-process operations instead of issuing D-Bus calls.

PlatformGetAllAccess()
PlatformGetGroupAccess(group)
PlatformGetUserAccess(**call_info)
PlatformSetGroupAccess(group, allowed_signals, allowed_controls, **call_info)
PlatformSetGroupAccessControls(group, allowed_controls, **call_info)
PlatformSetGroupAccessSignals(group, allowed_signals, **call_info)
geopmdpy.access.main()

Access management for the GEOPM Service.

Command line tool for reading and writing the access management lists for the GEOPM Service signals and controls.

geopmdpy.dbus_xml

The GEOPM DBus API enables a client to make measurements from the hardware platform and set hardware control parameters. Fine grained permissions management for both measurements (signals) and controls is configurable by system administrators.

geopmdpy.dbus_xml.geopm_dbus_xml(TopoService=None, PlatformService=None)

geopmdpy.loop

Classes to support timer based loops

class geopmdpy.loop.PIDTimedLoop(pid, period, num_period=None)

Bases: TimedLoop

wait(timeout)

Wait for timeout seconds or until pid ends

Parameters:

timeout (float) – Target interval for the loop execution in units of seconds.

Raises:

StopIteration – When last call to wait termintated due to the process ending

class geopmdpy.loop.TimedLoop(period, num_period=None)

Bases: object

Object that can be iterated over to run a timed loop

Use in a for loop to execute a fixed number of timed delays. The overhead time for executing what is inside of the loop is accounted for. Calls to time.sleep() are made to delay until the targeted end time for each iteration.

Example

>>> from time import time
>>> time_0 = time()
>>> for index in TimedLoop(0.1, 10):
...     print(f'{index}: {time() - time_0}')
...
0: 0.0008680820465087891
1: 0.10126090049743652
2: 0.20174455642700195
3: 0.30123186111450195
4: 0.4010961055755615
5: 0.5020360946655273
6: 0.6011238098144531
7: 0.7011349201202393
8: 0.8020164966583252
9: 0.9015650749206543
10: 1.0021190643310547
wait(timeout)

Pass-through to time.sleep()

Parameters:

timeout (float) – Target interval for the loop execution in units of seconds.

geopmdpy.error

geopmdpy.error.message(err_number)

Return the error message associated with the error code. Positive error codes are interpreted as system error numbers, and negative error codes are interpreted as GEOPM error numbers.

Parameters:

err_number (int) – Error code to be interpreted.

Returns:

Error message associated with error code.

Return type:

str

geopmdpy.pio

The pio module provides python bindings for the geopm_pio(3) C interfaces. This interface provides an abstraction for reading signals and writing controls from system components.

geopmdpy.pio.adjust(control_idx, setting)

Updates the cached value of a single control.

The particular control that is modified is determined by the control index provided. The control index is the value that was returned when push_control() was called. The value for this control is updated so that the next call to write_batch() will write the setting to the platform.

Parameters:
  • control_idx (int) – Index returned by a previous call to the push_control() function.

  • setting (float) – Value for control to be set on next call to write_batch().

geopmdpy.pio.control_description(control_name)

Get a description of a control.

A description should include the units of the control along with other descriptive text. An exception is raised if any error occurs.

Parameters:

control_name (str) – Name of control.

Returns:

Control description string.

Return type:

str

geopmdpy.pio.control_domain_type(control_name)

Get the domain type that is native for a control.

Controls cannot be set at a finer granularity than the native domain, and such requests will result in a raised exception. When a request is made to write a control at a courser domain than the native domain, the same control value will be set for all sub-domains of the requested domain.

Parameters:

control_name (str) – name of control to query

Returns:

One of the geopmdpy.topo.DOMAIN_* integers corresponding

to a domain type. This can be converted into a domain name with the geopmdpy.topo.domain_name() function.

Return type:

int

geopmdpy.pio.control_names()

Get all available controls.

A user can choose from any of the control names returned to pass as a parameter to other pio module functions that take a control_name as input.

Returns:

All available control names in sorted order.

Return type:

list(str)

geopmdpy.pio.format_signal(signal, format_type)

Convert a signal into a string representation

All signals have a format enum that describes how to format a value that was read. This format enum can be queried with the signal_info() function and passed as the format type parameter.

Parameters:
  • signal (float) – The value of a signal that was read.

  • format_type (int) – The geopm::string_format_e enum value defined in Helper.hpp that describes how to format the value.

Returns:

String representation of the signal value.

Return type:

str

Raises:

RuntimeError – Unable to format the value.

geopmdpy.pio.push_control(control_name, domain_type, domain_idx)

Push a control onto the stack of batch access controls.

The return value is an index that can be passed to the adjust() function which will update the internal state used to store batch controls. Subsequent calls to the write_batch() function access the control values in the internal state and write the values to the hardware. A distinct control index will be returned for each unique combination of input parameters. All controls must be pushed onto the stack prior to the first call to the adjust() or read_batch() functions. After calls to adjust() or read_batch() have been made, controls may be pushed again only after calling reset() and before calling adjust() or read_batch() again. Attempts to push a control onto the stack after the first call to adjust() or read_batch() (and without calling reset()) or attempts to push a control_name that is not a value provided by the control_names() function will result in a raised exception.

Parameters:
  • control_name (str) – Name of the control to be written.

  • domain_type (int or str) – One of the domain types provided by the geopmdpy.topo module or the name associated with a domain type (e.g. ‘cpu’ or ‘board’).

  • domain_idx (int) – Index of domain to write to.

Returns:

Control index that can be passed to the adjust() function prior to a call to the write_batch() function.

Return type:

int

geopmdpy.pio.push_signal(signal_name, domain_type, domain_idx)

Push a signal onto the stack of batch access signals.

Subsequent calls to the read_batch() function will read the signal and update the internal state used to store batch signals. The function returns an index that can be passed to the sample() function to access the signal value stored in the internal state from the last update. A distinct signal index will be returned for each unique combination of input parameters. All signals must be pushed onto the stack prior to the fist call to read_batch() or adjust(). After calls to read_batch() or adjust() have been made, signals may be pushed again only after calling reset() and before calling read_batch() or adjust() again. Attempts to push a signal onto the stack after the first call to read_batch() or read_batch() (and without calling reset()) or attempts to push a signal_name that is not provided by signal_names() will result in a raised exception.

Parameters:
  • signal_name (str) – Name of the signal to be read.

  • domain_type (int or str) – One of the domain types provided by the geopmdpy.topo module or the name associated with a domain type (e.g. ‘cpu’ or ‘board’).

  • domain_idx (int) – Index of domain to read from.

Returns:

Signal index that can be passed to the sample() function

after the read_batch() function has been called.

Return type:

int

geopmdpy.pio.read_batch()

Read all pushed signals from the platform.

The next calls to sample() will reflect the updated data.

geopmdpy.pio.read_signal(signal_name, domain_type, domain_idx)

Read a signal value from platform.

Select a signal by name and read the current value from the domain type and index specified. The read signal is returned as a floating point number in SI units. The signal name can be any returned by the signal_names() function.

Parameters:
  • signal_name (str) – Name of the signal to be read.

  • domain_type (int or str) – One of the domain types provided by the geopmdpy.topo module or the name associated with a domain type (e.g. ‘cpu’ or ‘board’).

  • domain_idx (int) – Index of domain to read from.

Returns:

The value of the signal read in SI units.

Return type:

float

geopmdpy.pio.reset()

Reset the GEOPM platform interface.

Resetting the GEOPM platform interface will cause the internal PlatformIO instance to be released/deleted and reconstructed. As a result, any signals and controls that had been pushed will be cleared, any batch servers that had been started will be stopped, and all registered IOGroups will be reset.

geopmdpy.pio.restore_control()

Restore the state recorded by the last call to save_control().

All previous changes made through write_control() or write_batch() are reverted to their previous settings.

Raises:

RuntimeError – Failure to restore all control values.

geopmdpy.pio.restore_control_dir(save_dir)

Restore the state recorded to the save directory

The save directory will have been created by the last call to save_control_dir(save_dir) so that all subsequent changes made through write_control() or write_batch() are reverted to their previous settings.

Parameters:

save_dir (str) – Output directory where each IOGroup has created a save file.

Raises:

RuntimeError – Failure to restore all control values.

geopmdpy.pio.sample(signal_idx)

Samples cached value of a single signal.

This function returns one of the values that was read in the last call to read_batch(). The particular signal returned is determined by the signal index provided. This signal index is the value that was returned when push_signal() was called.

Parameters:

signal_idx (int) – Index returned by a previous call to the push_signal() function.

Returns:

Value of signal read when read_batch() function was

last called.

Return type:

float

geopmdpy.pio.save_control()

Save the state of all controls.

Any subsequent changes made through write_control() or write_batch() will be reverted with a call to restore_control(). The control settings are stored in memory managed by GEOPM.

Raises:

RuntimeError – Failure to save all control values.

geopmdpy.pio.save_control_dir(save_dir)

Save the state of all controls to files in the save directory.

Any subsequent changes made through write_control() or write_batch() will be reverted with a call to restore_control_dir(save_dir). The control settings are stored in files named after each IOGroup that is loaded.

Parameters:

save_dir (str) – Output directory where each IOGroup creates a save file.

Raises:

RuntimeError – Failure to save all control values.

geopmdpy.pio.signal_description(signal_name)

Get a description of a signal.

A description should include the units of the signal and the aggregation function along with other descriptive text. An exception is raised if any error occurs.

Parameters:

signal_name (str) – Name of signal.

Returns:

Signal description string.

Return type:

str

geopmdpy.pio.signal_domain_type(signal_name)

Get the domain type that is native for a signal.

Signals cannot be sampled at a finer granularity than the native domain, and such requests will result in a raised exception. When a request is made to read a signal at a courser domain than the native domain, the signal will be read at the native granularity for all sub-domains of the requested domain and the returned result will be aggregated from the values read. The result can be converted into a domain name with the topo.domain_name() function.

Parameters:

signal_name (str) – name of signal to query

Returns:

One of the geopmdpy.topo.DOMAIN_* integers corresponding

to a domain type.

Return type:

int

geopmdpy.pio.signal_info(signal_name)

Get information about a signal

Query the integer enum values that give information about the named signal. There are three integers returned which correspond to the the aggregation type, the format method, and the behavior of the signal.

The aggregation type is one of the the geopm::Agg::m_type_e enum values defined in Agg.hpp. The format method is one of the geopm::string_format_e enum values defined in Helper.hpp. The behavior is one of the geopm::IOGroup::m_signal_behavior_e enum values defined in IOGroup.hpp.

Parameters:

signal_name (str) – Name of the signal to query.

Returns:

The aggregation type, format type, and

behavior type enum values associated with the signal.

Return type:

tuple(int, int, int)

Raises:

RuntimeError – Query of signal name failed.

geopmdpy.pio.signal_names()

Get all available signals.

A user can choose from any of the signal names returned to pass as a parameter to other pio module functions that take a signal_name as input.

Returns:

All available signal names in sorted order.

Return type:

list(str)

geopmdpy.pio.start_batch_server(client_pid, signal_config, control_config)

Start a batch server to interface with a client thread

Create a new process to interact with the client thread using the GEOPM batch server protocol. The created server will be enabled to read the configured signals and write the configured controls based on requests made by the client thread after the server is running. Each configuration is a list of tuples that specify the name of the signal or control, the domain type, and domain index. This call to start the batch server will block until the server is up and ready to respond to client requests through the GEOPM batch server protocol.

Parameters:
  • client_pid (int) – Linux PID of the thread that will interact with the batch server.

  • signal_config (list((str, int, int))) – List of requested signals where each tuple represents (signal_name, domain_type, domain_idx).

  • control_config (list((str, int, int))) – List of requested controlss where each tuple represents (control_name, domain_type, domain_idx).

Returns:

The server PID and the string key used by the

client thread to initiate the GEOPM batch server protocol.

Return type:

tuple(int, str)

Raises:

RuntimeError – Failure to start the batch server.

geopmdpy.pio.stop_batch_server(server_pid)

Stop a currently running batch server

End a batch server process that was created with a call to start_batch_server(). This will end the server process, and the client will not be able to use the GEOPM batch server protocol unless it starts a new server.

Parameters:

server_pid (int) – Linux PID of the created batch server. This is the value of the first element of the tuple returned by the start_batch_server() function.

Raises:

RuntimeError – Failure to stop the batch server.

geopmdpy.pio.write_batch()

Write all pushed controls to the platform.

The values provided to previous calls to adjust() are written to the platform.

geopmdpy.pio.write_control(control_name, domain_type, domain_idx, setting)

Write a control value to the platform.

Select a control by name and write a new setting for the domain type and index specified. The written control is a floating point number in SI units. The control name can be any returned by the control_names() function.

Parameters:
  • control_name (str) – Name of the control to be written.

  • domain_type (int or str) – One of the domain types provided by the geopmdpy.topo module or the name associated with a domain type (e.g. ‘cpu’ or ‘board’).

  • domain_idx (int) – Index of domain to write to.

  • setting (float) – Value of the control to be written.

geopmdpy.schemas

geopmdpy.service

Module containing the implementations of the DBus interfaces exposed by geopmd.

class geopmdpy.service.GEOPMService

Bases: object

The dasbus service object that is published.

Object used by dasbus to map GEOPM service DBus APIs to their implementation. A GEOPMService object is published by geopmd using the publish_object() method of dasbus.SystemMessageBus class which enables the GEOPM service.

The GEOPMService methods are named after the DBus API they provide within the io.github.geopm DBus namespace. The parameter type conversion is configured with the __dbus_xml__ class member.

The implementation for each method is a pass-through call to a member object method. These member objects do not have an explicit dasbus dependency which facilitates unit testing.

PlatformCloseSession(**call_info)
PlatformCloseSessionAdmin(client_pid, **call_info)
PlatformGetAllAccess()
PlatformGetControlInfo(control_names)
PlatformGetGroupAccess(group, **call_info)
PlatformGetProfilePids(profile_name)
PlatformGetSignalInfo(signal_names)
PlatformGetUserAccess(**call_info)
PlatformLockControl(**call_info)
PlatformOpenSession(**call_info)
PlatformPopProfileRegionNames(profile_name)
PlatformReadSignal(signal_name, domain, domain_idx, **call_info)
PlatformRestoreControl(**call_info)
PlatformSetGroupAccess(group, allowed_signals, allowed_controls, **call_info)
PlatformSetGroupAccessControls(group, allowed_controls, **call_info)
PlatformSetGroupAccessSignals(group, allowed_signals, **call_info)
PlatformStartBatch(signal_config, control_config, **call_info)
PlatformStartProfile(profile_name, **call_info)
PlatformStopBatch(server_pid, **call_info)
PlatformStopProfile(region_names, **call_info)
PlatformUnlockControl(**call_info)
PlatformWriteControl(control_name, domain, domain_idx, setting, **call_info)
TopoGetCache()
topo_rm_cache()

Remove an existing topo cache file if it exists

class geopmdpy.service.PlatformService

Bases: object

Provides the concrete implementation for all of the GEOPM DBus interfaces that use PlatformIO. This class is used by the GEOPMService class that maps DBus interfaces to their implementations.

check_client(client_pid)

Called by GLib periodically to monitor if a PID is active

GLib queries check_client() to see if the process is still alive.

This method gets triggered upon abnormal termination of the session, such as when the client process unexpectedly crashes or ends without closing all sessions.

close_session(client_pid)

Close an active session for the client process.

After closing a session, the client process is required to call open_session() again before using any of the client-facing member functions.

Closing an active session will remove the record of which signals and controls the client process has access to; thus, this record is updated to reflect changes to the policy when the next session is opened by the process.

When closing a write-mode session, the control values that were recorded when the session was promoted to write-mode are restored.

A client PID may attempt to open a session multiple times and this is tracked with a reference count as described in the documentation for opening a session. In this case, calls to close the session will not actually release the resources associated with the session until the reference count falls to zero.

A RuntimeError is raised if the client_pid does not have an open session.

Parameters:

client_pid (int) – Linux PID of the client thread

close_session_admin(client_pid)

Close an active session for the client process completely.

This administrative function is used to forcibly close an active session regardless of the client’s reference count. Similarly, if a client process PID is no longer active, but an open session exists, this implementation is used to release the session resources.

When closing a write-mode session, the control values that were recorded when the session was promoted to write-mode are restored. A RuntimeError is raised if the client_pid does not have an open session.

Parameters:

client_pid (int) – Linux PID of the client thread

get_all_access()

Get all of the signals and controls that the service supports.

Returns the list of all signals and controls supported by the service. The lists returned are independent of the access controls; therefore, calling get_all_access() is equivalent to calling get_user_access() for a user with CAP_SYSADMIN.

Returns:

All supported signals and controls, in sorted order.

Return type:

list(str), list(str)

get_control_info(control_names)

For each specified control name, return a tuple of information.

The caller provides a list of control names. This method returns a list of the same length which consists of a tuple of information for each control.

The method will raise a RuntimeError if any of the requested control names are not supported by the service.

Parameters:

control_names (list(str)) – List of control names to query

Returns:

name (str): The control name specified by the caller

description (str): A human-readable description of the

effect of setting the control.

domain_type (int): One of the geopmpy.topo.DOMAIN_*

integers corresponding to a domain type that is the finest available granularity for the control.

Return type:

list(tuple((str), (str), (int)))

get_group_access(group)

Get the signal and control access lists

Read the list of allowed signals and controls for the specified group. If the group is None or the empty string then the default lists of allowed signals and controls are returned.

The values are securely read from files located in /etc/geopm using the secure_read_file() interface.

If no secure file exist for the specified group, then two empty lists are returned.

Parameters:

group (str) – Name of group

Returns:

Signal and control allowed lists, both in sorted order.

Return type:

list(str), list(str)

Raises:

RuntimeError – The group name is not valid on the system.

get_profile_pids(profile_name)

Get PIDs associated with an application

Called by a profiling thread to find all PIDs associated with a named application.

Parameters:

profile_name (str) – Name of application that PID supports

Returns:

All PID associated with profile_name or empty

list if profile_name is not registered.

Return type:

list(int)

get_signal_info(signal_names)

For each specified signal name, return a tuple of information.

The caller provides a list of signal names. This method returns a list of the same length which consists of a tuple of information for each signal.

The method will raise a RuntimeError if any of the requested signal names are not supported by the service.

Parameters:

signal_names (list(str)) – List of signal names to query

Returns:

name (str): The signal name specified by the caller

description (str): A human-readable description of

what the signal measures.

domain_type (int): One of the geopmpy.topo.DOMAIN_*

integers corresponding to a domain type where the signal is natively supported.

aggregation (int): One of the geopm::Agg::m_type_e

enum values defined in Agg.hpp that specifies how to aggregate the signal over domains.

format_type (int): One of the geopm::string_format_e

enum values defined in Helper.hpp that specifies how to convert the signal value to a human readable string.

behavior (int): One of the

IOGroup::m_signal_behavior_e enum values that specifies how the signal changes over time.

Return type:

list(tuple((str), (str), (int), (int), (int), (int)))

get_user_access(user, client_pid)

Get the list of all of the signals and controls that are accessible to the specified user.

Returns the default access lists that apply to all non-root users if the empty string is provided.

All available signals and controls are returned if the caller specifies the a pid with CAP_SYSADMIN. A RuntimeError is raised if the user does not exist on the system.

When a user requests a signal or control through one of the other PlatformService methods, they are restricted to the union of the default allowed lists and the allowed lists for all Unix groups that the user belongs to. These combined lists are what this method returns.

Parameters:
  • user (str) – Which Unix user name to query; if the empty string is provided, the default allowed list is returned.

  • client_pid (int) – Linux PID of the client thread opening the session.

Returns:

Signal and control allowed lists, both in sorted order.

Return type:

list(str), list(str)

Raises:

RuntimeError – The user does not exist.

lock_control()

Block all write-mode sessions.

A call to this method will end any currently running write-mode session and block the creation of any new write-mode sessions. Use the unlock_control() method to enable write-mode sessions to begin again.

Calls to this method through the DBus interface will be blocked for all non-root users due to the rules established by the “io.github.geopm.conf” DBus configuration file.

Until write-mode sessions are re-enabled, any calls to write_control() or calls to start_batch() with a non-empty control_config parameter will raise a RuntimeError.

The default system configuration may be updated by the system administrator while write-mode is locked. For instance, the system administrator may use the geopmwrite command-line tool as user root between calls to lock_control() and unlock_control(). These changes will be reflected by the save/restore executed by the service for the next client write-mode session after the controls are unlocked.

No action is taken and no error is raised if controls are already disabled when this method is called.

open_session(user, client_pid)

Open a new session for the client thread.

The creation of a session is the first step that a client thread makes to interact with the GEOPM service. Each Linux thread has a unique PID, and this PID can be associated with at most one GEOPM service session. The session is ended by passing the client PID to the close_session() method. The session will also be ended if the client thread terminates for any reason.

The client PID may attempt to open a new session multiple times. In this case a reference count records the number of calls to open the session by the client PID. Each call to open a session is expected to be paired with a call to close the session. When the reference count falls to zero, all resources associated with the session are released.

Incrementing the reference count is an abstraction for the client. The client itself cannot have more than a single open connection at once, so when requesting a new session, other than incrementing the counter, nothing else happens.

All sessions are opened in read-mode, and may later be promoted to write-mode. This promotion will occur with the first successful call requiring access to controls. This includes any calls to write_control() or calls to start_batch() with a non-empty control_config. These calls will fail if there is an active write-mode session opened by another thread.

Prior to being promoted to write-mode, the current value for all controls that are supported by the GEOPM service will be recorded. This record enables the service to restore all controls when the write-mode session ends.

Permissions for the session’s access to signals and controls are determined based on the policy for the user when the session is first opened. Calling the set_group_access() method to alter the policy will not affect active sessions.

Parameters:
  • user (str) – Unix user name that owns the client thread opening the session.

  • client_pid (int) – Linux PID of the client thread opening the session.

pop_profile_region_names(profile_name)

Get region names associated with an application

Called by a profiling thread to find all region names associated with a named application.

Parameters:

profile_name (str) – Name of application that PID supports

Returns:

All region names associated with profile_name

or empty list if profile_name is not registered.

Return type:

list(str)

read_signal(client_pid, signal_name, domain, domain_idx)

Read a signal from a particular domain.

Select a signal by name and read the current value from the domain type and index specified. The value is returned as a floating point number in SI units.

A RuntimeError is raised if the client_pid does not have an open session or if the client does not have permission to read the signal from the specified domain.

A RuntimeError is raised if the requested signal is not supported, the domain is invalid or the domain index is out of range.

Parameters:
  • client_pid (int) – Linux PID of the client thread.

  • signal_name (str) – Name of the signal to read.

  • domain (int) – One of the geopmpy.topo.DOMAIN_* integers corresponding to a domain type to read from.

  • domain_idx (int) – Specifies the particular domain index to read from.

Returns:

The value of the signal in SI units.

Return type:

(float)

restore_control(client_pid)

Restore all controls recorded at the start of a session.

For the session associated to the given process, restore the state of all controls, which is recorded at the beginning of the session.

Raises:

RuntimeError – If client_pid does not have an open session or if a different client currently has an open session in write mode

set_group_access(group, allowed_signals, allowed_controls)

Set signals and controls in the allowed lists

Write the list of allowed signals and controls for the specified group. If the group is None or the empty string then the default lists of allowed signals and controls are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_signals (list(str)) – Signal names that are allowed

  • allowed_controls (list(str)) – Control names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

set_group_access_controls(group, allowed_controls)

Set controls in the allowed lists

Write the list of allowed controls for the specified group. If the group is None or the empty string then the default lists of allowed control are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_controls (list(str)) – Control names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

set_group_access_signals(group, allowed_signals)

Set signals in the allowed lists

Write the list of allowed signals for the specified group. If the group is None or the empty string then the default lists of allowed signal are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_signals (list(str)) – Signal names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

start_batch(client_pid, signal_config, control_config)

Start a batch server to support a client session.

Configure the signals and controls that will be enabled by the batch server and start the server process. The server enables fast access for the signals and controls that are configured by the caller. These are configured by specifying a name, domain and domain index for each of the signals and controls that the server will support.

After a batch server is successfully created, the client will interact with the batch server though PlatformIO interfaces that do not go over DBus. That is, once access is established by DBus, a faster protocol can be safely used.

The batch server does not enable features beyond those of the read_signal() or write_control() methods; it simply provides a much higher performance interface.

A RuntimeError is raised if the client does not have permission to read or write any of configured signals or controls or if the client_pid does not have an open session. The server process will not be created if any error occurs.

Parameters:
  • client_pid (int) – Linux PID of the client thread

  • signal_config (list(tuple((int), (int), (str))) –

    domain_type (int): One of the geopmpy.topo.DOMAIN_*

    integers corresponding to a domain type to read from.

    domain_idx (int): Specifies the particular domain

    index to read from.

    signal_name (str): The name of the signal to read.

  • control_config (list(tuple((int), (int), (str))) –

    domain_type (int): One of the geopmpy.topo.DOMAIN_*

    integers corresponding to a domain type to write to.

    domain_idx (int): Specifies the particular domain

    index to write to.

    control_name (str): The name of the control to write.

Returns:

server_pid (int): The Linux PID of the batch server process.

server_key (str): A unique identifier enabling the

server/client connection across inter-process shared memory.

Return type:

tuple(int, str)

start_profile(user, client_pid, profile_name)

Begin profiling a user PID

Called by a thread to enable profiling as part of a named application.

Parameters:
  • user (str) – Unix user name that owns the client thread opening the session.

  • client_pid (int) – Linux PID of the client thread opening the session.

  • profile_name (str) – Name of application that PID supports

stop_batch(client_pid, server_pid)

End a batch server previously started by the client.

Terminate the batch server process and free up all resources associated with the batch server. Any future calls by the client to interfaces that require the batch server will result in errors.

The batch server will also be terminated if the client session that created the server terminates for any reason.

A RuntimeError will be raised if the specified server PID was not previously created by the client’s call to start_batch(), or if the batch server has already been closed for any reason.

Parameters:
  • client_pid (int) – Linux PID of the client thread.

  • server_pid (int) – Linux PID of a batch server process returned by a previous call to start_batch().

stop_profile(client_pid, region_names)

Stop profiling a user PID

Called by a thread to end profiling as part of a named application.

Parameters:
  • client_pid (int) – Linux PID of the client thread opening the session.

  • region_names (list(str)) – Names of all regions entered.

unlock_control()

Unblock access to create new write-mode sessions.

A call to this method will re-enable write-mode sessions to be created after they were previously disabled by a call to lock_control().

Although new sessions may be created after a call to unlock_control(), write-mode sessions that were ended due to previous calls to lock_control() will remain closed.

No action is taken and no error is raised if controls are already enabled when this method is called.

write_control(client_pid, control_name, domain, domain_idx, setting)

Write a control value to a particular domain.

Select a control by name and write a new setting for the domain type and index specified. The written control setting is a floating point number in SI units.

A RuntimeError is raised if the client_pid does not have an open session, or if the client does not have permission to write the control to the specified domain.

A RuntimeError is raised if a different client currently has an open write-mode session.

A RuntimeError is raised if the requested control is not supported, the domain is invalid or the domain index is out of range.

Parameters:
  • client_pid (int) – Linux PID of the client thread.

  • control_name (str) – The name of the control to write.

  • domain (int) – One of the geopmpy.topo.DOMAIN_* integers corresponding to a domain type to written to.

  • domain_idx (int) – Specifies the particular domain index to write to.

  • setting (float) – Value of the control to be written.

class geopmdpy.service.TopoService(topo=<module 'geopmdpy.topo' from '/home/cmcantal/Git/geopm/geopmdpy/geopmdpy/topo.py'>)

Bases: object

Provides the concrete implementation for all of the GEOPM DBus interfaces that use PlatformTopo. This class is used by the GEOPMService class that maps DBus interfaces to their implementations.

get_cache()

Return the contents of the PlatformTopo cache file.

Create the PlatformTopo cache file if it does not exist and then return the contents of the file as a string. This provides all the information required to associate all domains with CPUs.

Returns:

Contents of the topology cache file that defines

the system topology.

Return type:

(str)

rm_cache()

Remove an existing cache file if it exists

geopmdpy.session

Implementation for the geopmsession command line tool

class geopmdpy.session.ReadRequestQueue(request_stream)

Bases: RequestQueue

get_formats()

Get formatting enum values for the parsed read requests

Returns:

The geopm::string_format_e enum value for each

read request.

Return type:

list(int)

parse_requests(request_stream)

Parse input stream and return list of read requests

Parse a user supplied stream into a list of tuples representing read requests. The tuples are of the form (signal_name, domain_type, domain_idx) and are parsed one from each line of the stream. Each of the values in the stream is separated by white space.

Each signal_name should match one of the signal names provided by the service. The domain_type is specified as the name string, i.e one of the following strings: “board”, “package”, “core”, “cpu”, “memory”, “package_integrated_memory”, “nic”, “package_integrated_nic”, “gpu”, “package_integrated_gpu”. The domain index is a positive integer indexing the specific domain.

Parameters:

request_stream (IO) – Input stream to parse for read requests

Returns:

List of request tuples. Each

request comprises a signal name, domain type, and domain index.

Return type:

list((str, int, int))

Raises:

RuntimeError – Line from stream does not split into three words and is also not a comment or empty line.

query_formats(signal_names)

Get the format type for each signal name

Returns a list of geopm::string_format_e integers that determine how each signal value is formatted as a string.

Parameters:

signal_names (list(str)) – List of signal names to query.

Returns:

List of geopm::string_format_e integers, one for each signal name in input list.

Return type:

list(int)

class geopmdpy.session.RequestQueue

Bases: object

Object derived from user input that provides request information

The geopmsession command line tool parses requests for reading from standard input. The RequestQueue object holds the logic for parsing the input stream upon construction. The resulting object may be iterated upon to retrieve the requested signals that the user would like to read. The Request object also provides the enum used to format signal values into strings.

get_names()

Get the signal or control names from each request

Returns:

The name of the signal or control associated

with each user request.

Return type:

list(str)

iterate_stream(request_stream)

Iterate over a stream of requests

This is a generator function that will filter out comment lines and trailing white space from the input stream. It can be used to iterate over a request stream from the user for either a read or write mode session.

Parameters:

request_stream (IO) – Stream containing requests from user.

Returns:

Iterate over filtered lines of the

request_stream

Return type:

Generator[str]

class geopmdpy.session.Session

Bases: object

Object responsible for creating a GEOPM batch read session

This object’s run() method is the main entry point for geopmsession command line tool. The inputs to run() are derived from the command line options provided by the user.

The Session object depends on the RequestQueue object to parse the input request buffer from the user. The Session object also depends on the loop.TimedLoop object when executing a periodic read session.

check_read_args(run_time, period)

Check that the run time and period are valid for a read session

Parameters:
  • run_time (float) – Time duration of the session open in seconds.

  • period (float) – The user specified period between samples in units of seconds.

Raises:

RuntimeError – The period is greater than the total time or either is negative.

format_signals(signals, signal_format)

Format a list of signal values for printing

Parameters:
  • signals (list(float)) – Values to be printed

  • signal_format (list(int)) – The geopm::format_string_e enum value describing the formatting for each signal provided.

Returns:

Ready-to-print line of formatted values

Return type:

str

run(run_time, period, pid, print_header, request_stream=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>, out_stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)

“Create a GEOPM session with values parsed from the command line

The implementation for the geopmsession command line tool. The inputs to this method are derived from the parsed command line provided by the user.

Parameters:
  • run_time (float) – Time duration of the session in seconds.

  • period (float) – Time interval for each line of output for. Value must be zero for a write mode session.

  • pid (int or None) – If not None, stop monitoring when the given process finishes.

  • print_header (bool) – Whether to print a row of headers before printing CSV data.

  • request_stream (IO) – Input from user describing the requests to read.

  • out_stream (IO) – Stream where output from will be printed.

run_read(requests, duration, period, pid, out_stream)

Run a read mode session

Periodically read the requested signals. A line of text will be printed to the output stream for each period of time. The line will contain a comma separated list of the read values, one for each request.

Only one read of the requests is made if the period is zero. If the period is non-zero then the requested signals are read periodically. The first read is immediate, and then a delay of period seconds elapses until the next sample is made. These periodic reads are executed and printed until the duration of time specified has been met or exceeded.

Parameters:
  • requests (ReadRequestQueue) – Request object parsed from user input.

  • duration (float) – The user specified minimum length of time for the samples to span in units of seconds.

  • period (float) – The user specified period between samples in units of seconds.

  • pid (int or None) – If not None, stop monitoring when the given process finishes.

  • out_stream (IO) – Object with write() method where output will be printed (typically sys.stdout).

geopmdpy.session.main()

Command line interface for the geopm service batch read features.

This command can be used to read signals by opening a session with the geopm service.

geopmdpy.system_files

Manage system files used by the geopm service

Provides secure interfaces for manipulating the files in

/run/geopm

that enable the service to be restarted and

/etc/geopm

where the access lists are located. These interfaces provide guarantees about the security of these system files, and an abstraction for updating the contents.

class geopmdpy.system_files.AccessLists(config_path)

Bases: object

Class that manages the access list files

get_all_access()

Get all of the signals and controls that the service supports.

Returns the list of all signals and controls supported by the service. The lists returned are independent of the access controls; therefore, calling get_all_access() is equivalent to calling get_user_access() for a process with CAP_SYSADMIN.

Returns:

All supported signals and controls, in sorted order.

Return type:

list(str), list(str)

get_group_access(group)

Get the signal and control access lists

Read the list of allowed signals and controls for the specified group. If the group is None or the empty string then the default lists of allowed signals and controls are returned.

The values are securely read from files located in /etc/geopm using the secure_read_file() interface.

If no secure file exist for the specified group, then two empty lists are returned.

Parameters:

group (str) – Name of group

Returns:

Signal and control allowed lists, in sorted order.

Return type:

list(str)), list(str)

Raises:

RuntimeError – The group name is not valid on the system.

get_user_access(user, client_pid)

Get the list of all of the signals and controls that are accessible to the specified user.

Returns the default access lists that apply to all non-root users if the empty string is provided.

All available signals and controls are returned if the caller provides a pid with CAP_SYSADMIN. A RuntimeError is raised if the user does not exist on the system.

When a user requests a signal or control through one of the other PlatformService methods, they are restricted to the union of the default allowed lists and the allowed lists for all Unix groups that the user belongs to. These combined lists are what this method returns.

Parameters:
  • user (str) – Which Unix user name to query; if the empty string is provided, the default allowed list is returned.

  • client_pid (int) – Linux PID to query

Returns:

Signal and control allowed lists, in sorted order.

Return type:

list(str), list(str)

Raises:

RuntimeError – The user does not exist.

set_group_access(group, allowed_signals, allowed_controls)

Set signals and controls in the allowed lists

Write the list of allowed signals and controls for the specified group. If the group is None or the empty string then the default lists of allowed signals and controls are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_signals (list(str)) – Signal names that are allowed

  • allowed_controls (list(str)) – Control names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

set_group_access_controls(group, allowed_controls)

Set controls in the allowed lists

Write the list of allowed controls for the specified group. If the group is None or the empty string then the default lists of allowed controls are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_controls (list(str)) – Control names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

set_group_access_signals(group, allowed_signals)

Set signals in the allowed lists

Write the list of allowed signals for the specified group. If the group is None or the empty string then the default lists of allowed signals are updated.

The values are securely written atomically to files located in /etc/geopm using the secure_make_dirs() and secure_make_file() interfaces.

Parameters:
  • group (str) – Name of group

  • allowed_signals (list(str)) – Signal names that are allowed

Raises:

RuntimeError – The group name is not valid on the system.

class geopmdpy.system_files.ActiveSessions(run_path)

Bases: object

Class that manages the session files for the service

The state about active sessions opened with geopmd by a client processes is stored in files in /run/geopm. These files are loaded when the geopmd process starts. The files are modified each time a client opens a session, closes a session, requests write permission, or starts a batch server. The class is responsible for managing file access permissions, and atomic file creation.

The session files are stored in JSON format and follow the GEOPM_ACTIVE_SESSIONS_SCHEMA documented in the geopmdpy.schemas module.

add_client(client_pid, signals, controls, watch_id)

Add a new client session to be tracked

Create a new session file that contains the JSON data provided as the call parameters in a format that conforms to the session file schema.

This file will be created atomically such that if this method is interrupted before the session file is ready to be used, then no file will be present that matches load pattern below.

/run/geopm/session-*.json

The session file is created without the JSON object property “batch_server” specified. This properties may be modified by the set_batch_server() method after the client is added.

This operation creates the session file atomically, but does not modify the session properties nor the session file if the client PID already has an open session.

Parameters:
  • client_pid (int) – Linux PID that opened the session

  • signals (list(str)) – List of signal names that are allowed to be read by the client

  • controls (list(str)) – List of control names that are allowed to be written by the client

  • watch_id (int) – The watch ID handle returned by GLib for tracking that the PID is active

check_client_active(client_pid, msg='')

Raise an exception if a PID does not have an active session

Parameters:
  • client_pid (int) – Linux PID to query

  • msg (str) – The operation that was attempted which requires an active session. Used in error message

Raises:

RuntimeError – Operation not allowed without an open session

decrement_reference_count(client_pid)

Decrement the reference_count value by one

This method is called when an independent component of the client calls close_session() and the connection is still open. For example when there are multiple independent components using that open connection, and one of them wants to close the session, we just decrement the reference count, we do not close the connection, as that would impact the other independent components which are using the connection.

Parameters:

client_pid (int) – Linux PID that opened the session

Raises:

RuntimeError – Client does not have an open session

get_batch_server(client_pid)

Query the batch server for the client session

In the case where the client has an open batch server, this method returns the Linux PID of the batch server. If there is no active batch server then None is returned.

Parameters:

client_pid (int) – Linux PID that opened the session

Returns:

The Linux PID of the batch server or None

Return type:

int

Raises:

RuntimeError – Client does not have an open session

get_clients()

Get list of the client PID values for all active sessions

Creates a list of the PID values for all active session clients.

Returns:

The Linux PID values for all active clients in sorted order.

Return type:

list(int)

get_controls(client_pid)

Query all control names that are available

Creates a list of all control names that are available to the session opened by the client PID.

Parameters:

client_pid (int) – Linux PID that opened the session

Returns:

Control name access list in sorted order for the session

Return type:

list(str)

Raises:

RuntimeError – Client does not have an open session

get_profile_pids(profile_name)
get_reference_count(client_pid)

Query the reference count for the client session.

The reference count is basically just an abstraction for the client. The client itself cannot have more than a single open session at once, since there is a one to one mapping between client pid and open sessions, and lifetime of our session is coupled to the lifetime of the connection.

The reference count is used when in the client process, we have independent components, which all may request that same connection as a kind of shared resource. We want to provide that same connection as a singleton, and keep track of how many independent components have access to that same connection as a resource, in order to know when to deallocate that resource when all these components have disconnected from the session.

Parameters:

client_pid (int) – Linux PID that opened the session

Returns:

The reference count

Return type:

int

Raises:

RuntimeError – Client does not have an open session

get_signals(client_pid)

Query all signal names that are available

Creates a list of all signal names that are available to the session opened by the client PID.

Parameters:

client_pid (int) – Linux PID that opened the session

Returns:

Signal name access list in sorted order for the session

Return type:

list(str)

Raises:

RuntimeError – Client does not have an open session

get_watch_id(client_pid)

Query for the GLib watch ID for tracking the session lifetime

The watch ID is not valid in the case where the geopmd process restarts. When a new geopmd process starts it will read files that contain watch ID values, however, the set_watch_id() method must be called with an updated watch ID for each active client session when geopmd starts.

Parameters:

client_pid (int) – Linux PID that opened the session

Returns:

GLib watch ID to track the session lifetime

Return type:

int

Raises:

RuntimeError – Client does not have an open session

increment_reference_count(client_pid)

Increment the reference_count value by one

This method is called when a new independent component calls open_session() a subsequent time after the connection has already been opened.

Parameters:

client_pid (int) – Linux PID that opened the session

Raises:

RuntimeError – Client does not have an open session

is_client_active(client_pid)

Query if a Linux PID currently has an active session

If a session file matching the client_pid exists, but the file was not parsed or created by geopmd, then a warning message is printed to syslog and the file is renamed. The warning message will display the user and group permissions of the file being deleted. In this case False is returned.

Parameters:

client_pid (int) – Linux PID to query

Returns:

True if the PID has an open session, False otherwise

Return type:

bool

Raises:
pop_profile_region_names(profile_name)
remove_batch_server(client_pid)

Remove the record for the batch server supporting a client session

This method is used to remove the record of a batch server after it is closed.

Parameters:

client_pid (int) – Linux PID that opened the session

Raises:

RuntimeError – Client does not have an open session

remove_client(client_pid)

Delete the record of an active session

Remove the client session file and delete the state associated with the client. Future requests about this client PID will raise an exception until another call to add_client() is made, although repeated calls to remove_client() for the same PID do not result in an error.

Parameters:

client_pid (int) – Linux PID that opened the session

set_batch_server(client_pid, batch_pid)

Set the Linux PID of the batch server supporting a client session

This method is used to store the PID after a batch server is created.

Parameters:
  • client_pid (int) – Linux PID that opened the session

  • batch_pid (int) – Linux PID of the batch server created for the client session

Raises:

RuntimeError – Client does not have an open session

set_reference_count(client_pid, reference_count)

Set the reference count for the session

This method is used whenever we want to update the reference_count to reflect the number of independent components that have connected to the session.

Parameters:
  • client_pid (int) – Linux PID that opened the session

  • reference_count (int) – The new reference count value

Raises:

RuntimeError – Client does not have an open session

set_watch_id(client_pid, watch_id)

Set the GLib watch ID for tracking the session lifetime

Store the GLib watch ID after registering the callback with GLib.timeout_add().

Parameters:
  • client_pid (int) – Linux PID that opened the session

  • watch_id (int) – GLib watch ID returned by the GLib.timeout_add() method

Raises:

RuntimeError – Client does not have an open session

start_profile(client_pid, profile_name)
stop_profile(client_pid, region_names, do_update=True)
geopmdpy.system_files.GEOPM_SERVICE_CONFIG_PATH_PERM = 448

Default permissions for the GEOPM service config path

geopmdpy.system_files.GEOPM_SERVICE_RUN_PATH_PERM = 457

Default permissions for the GEOPM service run path

exception geopmdpy.system_files.InvalidClientError(message)

Bases: Exception

class geopmdpy.system_files.WriteLock(run_path)

Bases: object

Class for interacting with control lock file

This class provides the interface to query and set the PID that owns the GEOPM Service control write lock. The state of this lock is stored in the file path:

/run/geopm/CONTROL_LOCK

This file is empty when the lock is free, and contains the PID of the controlling process when the lock is held. The class manages the advisory lock to serialize any attempts read or write the file. Additionally the class checks that the lock file is a regular file with restricted permissions. Manipulations of the control lock file should be done exclusively with the WriteLock object to insure that the advisory lock is effective.

try_lock(pid=None)

Get the PID that holds the lock or set lock

Returns the PID that currently holds the lock. If the user specifies a PID and the lock is not held by another process, then the lock will be assigned, and the input pid will be returned. The user must check the return value to determine if a request to assign the lock was successful, an error is not raised if the lock is held by another PID.

None is returned if the write lock is not held by any active session and the user does not specify a pid.

Parameters:

pid (int) – The PID to assign the lock

Returns:

The PID of the session that holds the write lock upon return

or None if the write lock is not held

Return type:

int

unlock(pid)

Release the write lock

Release the write lock from ownership by a specified PID. If the lock is not currently assigned to the specified PID, then a RuntimeError is raised.

Parameters:

pid (int) – The PID that the lock is assigned to

Raises:

RuntimeError – The specified PID does not currently hold the lock

geopmdpy.system_files.get_config_path()

Get the GEOPM config path, which may be a legacy path from earlier GEOPM releases, or may be the current release’s config path. If neither path exists yet or if both paths exist, use the current config path. Emit a warning if the legacy path exists.

geopmdpy.system_files.has_cap_sys_admin(pid)
geopmdpy.system_files.is_log_request(request)
geopmdpy.system_files.is_secure_file(path, fid)

Query if file descriptor may be safely read

After opening a file this function is called to determine if the file descriptor is a regular file owned by the calling process user and group with restricted permissions (i.e. mode 0o600). If these conditions are not met then a warning message is printed and the file is renamed to a path of the form <PATH>-<UUID>-INVALID.

Parameters:
  • path (str) – The file path that was passed to open()

  • fid (IO) – File descriptor returned by open()

Returns:

True if regular file with restricted permissions

Return type:

bool

geopmdpy.system_files.is_secure_path(path)

Query if path may be opened safely

Check if path exists, and refers to a regular file that is not a link. A warning message is printed if the path is a link, a directory or is not a regular file and the file is renamed to a path of the form <PATH>-<UUID>-INVALID.

Parameters:

path (str) – The file path

Returns:

True if the path is a regular file and not a link

Return type:

bool

geopmdpy.system_files.secure_make_dirs(path, perm_mode=448)

Securely create a directory

When the path does not exist a directory is created with permissions 0o700 by default along with all required parent directories.

The security of this path is verified if the path exists. An existing path is considered to be secure only if all of the following conditions are met:

  • The path is a regular directory

  • The path is not a link

  • The path is accessible the the caller

  • The path is a directory owned by the calling process uid

  • The path is a directory owned by the calling process gid

  • The permissions for the directory are 0o700 by default

If the existing path is determined to be insecure, a warning is printed to syslog and the existing file will be renamed to <path>-<UUID>-INVALID so that it may be audited later, but not used. The warning message will display the reason why the directory was not secure. A new directory with the specified path will be created in place of the renamed file.

This function will simply return when the directory already exists and is considered secure.

Parameters:

path (str) – The path were the directory is created

geopmdpy.system_files.secure_make_file(path, contents)

Securely and atomically create a file containing a string

The file is created by first writing the output to a temporary file with restricted permissions (mode 0o600) within the same directory, and then renaming the file after it is closed.

The rename operation is atomic, and will overwrite any existing file located in the specified path (unless it is a directory, in which case an excaption will be raised). The permissions on the output file are mode 0o600 with uid and gid matching the process values.

The temporary file has the prefix tmp.. This file may persist if the program exits abruptly.

Parameters:
  • path (str) – The path where the file is created

  • contents (str) – The contents of the created file

Raises:

IsADirectoryError – The provided path already exists and is a directory

geopmdpy.system_files.secure_read_file(path)

Securely read a file into a string

The security of this path is verified after the file is opened. An existing path is considered to be secure only if all of the following conditions are met:

  • The path is a regular file

  • The path is not a link

  • The path is accessible the the caller

  • The path is a file owned by the calling process uid

  • The path is a file owned by the calling process gid

  • The permissions for the file are 0o600

If the existing path is determined to be insecure, a warning is printed to syslog and the existing file will be renamed to <path>-<UUID>-INVALID so that it may be audited later, but not used. The warning message will display the reason why the file was not secure and None is returned.

If the path points to an existing file that is determined to be secure then the contents of the file are returned.

Parameters:

path (str) – The path where the file is created

Returns:

The contents of the file if file was opened, None if couldn’t open file

Return type:

str

geopmdpy.topo

geopmdpy.topo.create_cache()

Create a cache file for the platform topology if one does not exist. This cache file will be used by any calls to the other functions in the topo module as well as any use of the GEOPM runtime. File permissions of the cache file are set to “-rw-r–r–”, i.e. 644. The path for the cache file is /run/geopm/geopm-topo-cache. If this file is older than the last boot it will be regenerated. If the file exists but has improper permissions is will be regenerated. If the file has been created since the last boot with the correct permissions, no operation will be performed. To force the creation of a new cache file call os.unlink(‘/run/geopm/geopm-topo-cache’) prior to calling this function.

geopmdpy.topo.domain_idx(domain, cpu_idx)

Get the index of the domain that is local to a specific Linux logical CPU. The return value will be greater than or equal to zero and less than the value returned by num_domain(domain). An exception is raised if either input is out of range or invalid.

Parameters:
  • domain (int or str) – The domain type from one of topo.DOMAIN_* integer values or a domain name string.

  • cpu_idx (int) – The Linux logical CPU that is associated with the returned domain type.

Returns:

Domain index associated with the specified logical CPU.

Return type:

int

geopmdpy.topo.domain_name(domain)

Get the domain name corresponding to the domain type specified. If domain is a string, a check is done that the string is a valid domain type and then the input string is returned. This is the inverse of the domain_type() function.

Parameters:

domain (int or str) – The domain type from one of topo.DOMAIN_* integer values or a domain name string.

Returns:

Domain name string associated with input.

Return type:

str

geopmdpy.topo.domain_nested(inner_domain, outer_domain, outer_idx)

Get a list of all inner domains nested within a specified outer domain. An exception is raised if the inner domain is not within the outer domain or if the index is out of range.

Parameters:
  • inner_domain (int or str) – The inner domain type from one of topo.DOMAIN_* integer values or a domain name string.

  • outer_domain (int or str) – The outer domain type from one of topo.DOMAIN_* integer values or a domain name string.

  • outer_idx (int) – Index of the outer domain that is queried.

Returns:

The inner domain indices that are contained

within the specified outer domain.

Return type:

list[int]

geopmdpy.topo.domain_type(domain)

Returns the domain type that is associated with the provided domain string. If domain is of integer type, a check is done that it is a valid topo.DOMAIN_* value and then the input value is returned. This is the inverse of the domain_name() function. If domain is a string that does not match any of the valid domain names, or if domain is an integer that is out of range an exception is raised.

Parameters:

domain (str or int) – A domain name string or the domain type from one of topo.DOMAIN_* integer values.

Returns:

A domain type matching one of the topo.DOMAIN_* values

associated with the input.

Return type:

int

geopmdpy.topo.num_domain(domain)

Get the number of domains available on the system of a specific domain type. If the domain is valid, but there are no domains of that type on the system, the return value is zero. Invalid domain specification will result in a raised exception.

Parameters:

domain (int or str) – The domain type from one of topo.DOMAIN_* integer values or a domain name string.

Returns:

The number of domains of the specified type available on

the system.

Return type:

int

geopmdpy.version

geopmdpy.version.get_version()

See Also

geopmpy(7), geopm_daemon(3), geopm::Daemon(3)