mirror of
https://github.com/FeralInteractive/gamemode.git
synced 2025-06-07 16:17:23 +02:00
Implement supervisor features using new config variables
This allows direct control over who can make requests on behalf of other processes require_supervisor can also be used to allow a supervisor to take direct control of gamemode on the system (perhaps a GUI, or game launcher)
This commit is contained in:
parent
d60ac23daa
commit
1430c0b831
@ -94,6 +94,10 @@ struct GameModeConfig {
|
|||||||
long nv_perf_level;
|
long nv_perf_level;
|
||||||
long amd_core_clock_percentage;
|
long amd_core_clock_percentage;
|
||||||
long amd_mem_clock_percentage;
|
long amd_mem_clock_percentage;
|
||||||
|
|
||||||
|
long require_supervisor;
|
||||||
|
char supervisor_whitelist[CONFIG_LIST_MAX][CONFIG_VALUE_MAX];
|
||||||
|
char supervisor_blacklist[CONFIG_LIST_MAX][CONFIG_VALUE_MAX];
|
||||||
} values;
|
} values;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,6 +265,15 @@ static int inih_handler(void *user, const char *section, const char *name, const
|
|||||||
} else if (strcmp(name, "amd_mem_clock_percentage") == 0) {
|
} else if (strcmp(name, "amd_mem_clock_percentage") == 0) {
|
||||||
valid = get_long_value(name, value, &self->values.amd_mem_clock_percentage);
|
valid = get_long_value(name, value, &self->values.amd_mem_clock_percentage);
|
||||||
}
|
}
|
||||||
|
} else if (strcmp(section, "supervisor") == 0) {
|
||||||
|
/* Supervisor subsection */
|
||||||
|
if (strcmp(name, "supervisor_whitelist") == 0) {
|
||||||
|
valid = append_value_to_list(name, value, self->values.supervisor_whitelist);
|
||||||
|
} else if (strcmp(name, "supervisor_blacklist") == 0) {
|
||||||
|
valid = append_value_to_list(name, value, self->values.supervisor_blacklist);
|
||||||
|
} else if (strcmp(name, "require_supervisor") == 0) {
|
||||||
|
valid = get_long_value(name, value, &self->values.require_supervisor);
|
||||||
|
}
|
||||||
} else if (strcmp(section, "custom") == 0) {
|
} else if (strcmp(section, "custom") == 0) {
|
||||||
/* Custom subsection */
|
/* Custom subsection */
|
||||||
if (strcmp(name, "start") == 0) {
|
if (strcmp(name, "start") == 0) {
|
||||||
@ -568,3 +581,51 @@ DEFINE_CONFIG_GET(nv_mem_clock_mhz_offset)
|
|||||||
DEFINE_CONFIG_GET(nv_perf_level)
|
DEFINE_CONFIG_GET(nv_perf_level)
|
||||||
DEFINE_CONFIG_GET(amd_core_clock_percentage)
|
DEFINE_CONFIG_GET(amd_core_clock_percentage)
|
||||||
DEFINE_CONFIG_GET(amd_mem_clock_percentage)
|
DEFINE_CONFIG_GET(amd_mem_clock_percentage)
|
||||||
|
|
||||||
|
/*
|
||||||
|
char supervisor_whitelist[CONFIG_LIST_MAX][CONFIG_VALUE_MAX];
|
||||||
|
char supervisor_blacklist[CONFIG_LIST_MAX][CONFIG_VALUE_MAX];
|
||||||
|
*/
|
||||||
|
DEFINE_CONFIG_GET(require_supervisor)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the supervisor is whitelisted
|
||||||
|
*/
|
||||||
|
bool config_get_supervisor_whitelisted(GameModeConfig *self, const char *supervisor)
|
||||||
|
{
|
||||||
|
/* Take the read lock for the internal data */
|
||||||
|
pthread_rwlock_rdlock(&self->rwlock);
|
||||||
|
|
||||||
|
/* If the whitelist is empty then everything passes */
|
||||||
|
bool found = true;
|
||||||
|
if (self->values.supervisor_whitelist[0][0]) {
|
||||||
|
/*
|
||||||
|
* Check if the value is found in our whitelist
|
||||||
|
* Currently is a simple strstr check, but could be modified for wildcards etc.
|
||||||
|
*/
|
||||||
|
found = config_string_list_contains(supervisor, self->values.supervisor_whitelist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release the lock */
|
||||||
|
pthread_rwlock_unlock(&self->rwlock);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if the supervisor is blacklisted
|
||||||
|
*/
|
||||||
|
bool config_get_supervisor_blacklisted(GameModeConfig *self, const char *supervisor)
|
||||||
|
{
|
||||||
|
/* Take the read lock for the internal data */
|
||||||
|
pthread_rwlock_rdlock(&self->rwlock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the value is found in our whitelist
|
||||||
|
* Currently is a simple strstr check, but could be modified for wildcards etc.
|
||||||
|
*/
|
||||||
|
bool found = config_string_list_contains(supervisor, self->values.supervisor_blacklist);
|
||||||
|
|
||||||
|
/* release the lock */
|
||||||
|
pthread_rwlock_unlock(&self->rwlock);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
@ -141,3 +141,10 @@ long config_get_nv_mem_clock_mhz_offset(GameModeConfig *self);
|
|||||||
long config_get_nv_perf_level(GameModeConfig *self);
|
long config_get_nv_perf_level(GameModeConfig *self);
|
||||||
long config_get_amd_core_clock_percentage(GameModeConfig *self);
|
long config_get_amd_core_clock_percentage(GameModeConfig *self);
|
||||||
long config_get_amd_mem_clock_percentage(GameModeConfig *self);
|
long config_get_amd_mem_clock_percentage(GameModeConfig *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions to get supervisor config permissions
|
||||||
|
*/
|
||||||
|
long config_get_require_supervisor(GameModeConfig *self);
|
||||||
|
bool config_get_supervisor_whitelisted(GameModeConfig *self, const char *supervisor);
|
||||||
|
bool config_get_supervisor_blacklisted(GameModeConfig *self, const char *supervisor);
|
||||||
|
@ -504,13 +504,36 @@ int game_mode_context_query_status(GameModeContext *self, pid_t client)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Stub to register on behalf of caller
|
* Stub to register on behalf of caller
|
||||||
|
* TODO: long config_get_require_supervisor(GameModeConfig *self);
|
||||||
*/
|
*/
|
||||||
int game_mode_context_register_by_pid(GameModeContext *self, pid_t callerpid, pid_t gamepid)
|
int game_mode_context_register_by_pid(GameModeContext *self, pid_t callerpid, pid_t gamepid)
|
||||||
{
|
{
|
||||||
(void)self;
|
int status = 0;
|
||||||
(void)callerpid;
|
|
||||||
(void)gamepid;
|
/* Lookup the executable first */
|
||||||
return 0;
|
char *executable = game_mode_context_find_exe(callerpid);
|
||||||
|
if (!executable) {
|
||||||
|
status = -1;
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check our blacklist and whitelist */
|
||||||
|
if (!config_get_supervisor_whitelisted(self->config, executable)) {
|
||||||
|
LOG_MSG("Supervisor [%s] was rejected (not in whitelist)\n", executable);
|
||||||
|
status = -2;
|
||||||
|
goto error_cleanup;
|
||||||
|
} else if (config_get_supervisor_blacklisted(self->config, executable)) {
|
||||||
|
LOG_MSG("Supervisor [%s] was rejected (in blacklist)\n", executable);
|
||||||
|
status = -2;
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks cleared, try and register the game */
|
||||||
|
return game_mode_context_register(self, gamepid);
|
||||||
|
|
||||||
|
error_cleanup:
|
||||||
|
free(executable);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -518,10 +541,31 @@ int game_mode_context_register_by_pid(GameModeContext *self, pid_t callerpid, pi
|
|||||||
*/
|
*/
|
||||||
int game_mode_context_unregister_by_pid(GameModeContext *self, pid_t callerpid, pid_t gamepid)
|
int game_mode_context_unregister_by_pid(GameModeContext *self, pid_t callerpid, pid_t gamepid)
|
||||||
{
|
{
|
||||||
(void)self;
|
int status = 0;
|
||||||
(void)callerpid;
|
|
||||||
(void)gamepid;
|
/* Lookup the executable first */
|
||||||
return 0;
|
char *executable = game_mode_context_find_exe(callerpid);
|
||||||
|
if (!executable) {
|
||||||
|
status = -1;
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check our blacklist and whitelist */
|
||||||
|
if (!config_get_supervisor_whitelisted(self->config, executable)) {
|
||||||
|
LOG_MSG("Supervisor [%s] was rejected (not in whitelist)\n", executable);
|
||||||
|
status = -2;
|
||||||
|
goto error_cleanup;
|
||||||
|
} else if (config_get_supervisor_blacklisted(self->config, executable)) {
|
||||||
|
LOG_MSG("Supervisor [%s] was rejected (in blacklist)\n", executable);
|
||||||
|
status = -2;
|
||||||
|
goto error_cleanup;
|
||||||
|
}
|
||||||
|
/* Checks cleared, try and register the game */
|
||||||
|
return game_mode_context_unregister(self, gamepid);
|
||||||
|
|
||||||
|
error_cleanup:
|
||||||
|
free(executable);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,6 +61,16 @@ inhibit_screensaver=1
|
|||||||
;amd_core_clock_percentage=0
|
;amd_core_clock_percentage=0
|
||||||
;amd_mem_clock_percentage=0
|
;amd_mem_clock_percentage=0
|
||||||
|
|
||||||
|
[supervisor]
|
||||||
|
; This section controls the new gamemode functions gamemode_request_start_for and gamemode_request_end_for
|
||||||
|
; The whilelist and blacklist control which supervisor programs are allowed to make the above requests
|
||||||
|
;supervisor_whitelist=
|
||||||
|
;supervisor_blacklist=
|
||||||
|
|
||||||
|
; In case you want to allow a supervisor to take full control of gamemode, this option can be set
|
||||||
|
; This will only allow gamemode clients to be registered by using the above functions by a supervisor client
|
||||||
|
;require_supervisor=0
|
||||||
|
|
||||||
[custom]
|
[custom]
|
||||||
; Custom scripts (executed using the shell) when gamemode starts and ends
|
; Custom scripts (executed using the shell) when gamemode starts and ends
|
||||||
;start=notify-send "GameMode started"
|
;start=notify-send "GameMode started"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user