"enable_network",
"interactive",
"logging_callback",
+ "nice",
NULL
};
int enable_network = 0;
int interactive = 0;
PyObject* logging_callback = NULL;
+ int nice = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OppO", kwlist, &command, &environ,
- &enable_network, &interactive, &logging_callback))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OppOi", kwlist, &command, &environ,
+ &enable_network, &interactive, &logging_callback, &nice))
return NULL;
// Check if command is a list
pakfire_jail_set_log_callback(jail, __Pakfire_logging_callback, logging_callback);
}
+ // Set nice
+ if (nice) {
+ r = pakfire_jail_nice(jail, nice);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto ERROR;
+ }
+ }
+
PyObject* key = NULL;
PyObject* value = NULL;
Py_ssize_t p = 0;
int pakfire_jail_set_log_callback(struct pakfire_jail* jail,
pakfire_jail_log_callback callback, void* data);
+// Resource Limits
+int pakfire_jail_nice(struct pakfire_jail* jail, int nice);
+
// Environment
const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key);
int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value);
#include <sys/eventfd.h>
#include <sys/personality.h>
#include <sys/prctl.h>
+#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
// Flags
int flags;
+ // Resource Limits
+ int nice;
+
// Environment
char* env[ENVIRON_SIZE];
return jail->flags & flag;
}
+// Resource Limits
+
+PAKFIRE_EXPORT int pakfire_jail_nice(struct pakfire_jail* jail, int nice) {
+ // Check if nice level is in range
+ if (nice < -19 || nice > 20) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ // Store nice level
+ jail->nice = nice;
+
+ return 0;
+}
+
// Environment
// Returns the length of the environment
// XXX do we have to reconfigure logging here?
- DEBUG(jail->pakfire, "Launched child process in jail with PID %d\n", getpid());
+ // Fetch my own PID
+ pid_t pid = getpid();
+
+ DEBUG(jail->pakfire, "Launched child process in jail with PID %d\n", pid);
// Wait for the parent to finish initialization
r = pakfire_jail_wait_for_signal(jail, ctx->completed_fd);
}
}
+ // Set nice level
+ if (jail->nice) {
+ DEBUG(jail->pakfire, "Setting nice level to %d\n", jail->nice);
+
+ r = setpriority(PRIO_PROCESS, pid, jail->nice);
+ if (r) {
+ ERROR(jail->pakfire, "Could not set nice level: %m\n");
+ return 1;
+ }
+ }
+
// Reset open file limit (http://0pointer.net/blog/file-descriptor-limits.html)
r = pakfire_rlimit_reset_nofile(jail->pakfire);
if (r)
pakfire_jail_exec_script;
pakfire_jail_get_env;
pakfire_jail_import_env;
+ pakfire_jail_nice;
pakfire_jail_ref;
pakfire_jail_set_env;
pakfire_jail_set_log_callback;
self.pakfire.execute(["/command", "pid"], logging_callback=checkpid)
+ def test_nice(self):
+ self.pakfire.execute(["/command", "print-nice"], nice=5)
+
+ def test_nice_invalid_input(self):
+ """
+ Tries using an invalid nice value
+ """
+ with self.assertRaises(OSError):
+ self.pakfire.execute(["/command", "print-nice"], nice=100)
+
+
# This is an interactive test which cannot be performed automatically
#def test_shell(self):
# self.pakfire.execute(["/bin/bash", "-i"])
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
return 0;
}
+static int print_nice(int argc, char* argv[]) {
+ int nice = getpriority(PRIO_PROCESS, 0);
+
+ // Print the nice level
+ printf("%d\n", nice);
+
+ return 0;
+}
+
int main(int argc, char* argv[]) {
if (argc < 2) {
fprintf(stderr, "No command given\n");
else if (strcmp(command, "pid") == 0)
callback = pid;
+ // Print nice level
+ else if (strcmp(command, "print-nice") == 0)
+ callback = print_nice;
+
// Exit if no callback has been set
if (!callback) {
fprintf(stderr, "Unknown command: %s\n", command);