Search code examples
pythonlinuxschedulingschedulersetuid

Linux group scheduling for user not being applied to setuid-ed process


On the 2.6.28-11 Linux kernel, I am using setpriority to bias the amount of cpu time different user processes receive. User 1 is to receive double the CPU power of user 2. Using Linux's setpriority, I have assigned user 2 a lower priority (higher in terms of nice values). When I run the exact same program via the shell with the computer under load, user 2's execution takes twice as long as user 1's. However, if I run the program as root, and then use setuid, seteuid, setgid, setegid, and setgroups to become user 2 (once again the computer is under load with the exact same program being run by user 1 in the same manner), the programs take the exact same amount of time to execute; User 2's process was not being scheduled any less than user 1's. How can I get around this? Do I need to set anything else for the scheduler to realize that the process is now part of a different user?

The program being run is in Python.


Solution

  • Right, this is the designed behavior, even if it's not what you want. You can update your own priority to match what you should have inherited, if you were started normally:

    /* C */
    #include <sys/resource.h>
    int proc_prio = getpriority(PRIO_PROCESS, getpid()),
        pgrp_prio = getpriority(PRIO_PGRP, getpgrp()),
        user_prio = getpriority(PRIO_USER, getuid());
    setpriority(PRIO_PROCESS, getpid(),
        proc_prio < pgrp_prio ? pgrp_prio < user_prio ? user_prio
                                                      : pgrp_prio
                              : proc_prio < user_prio ? user_prio
                                                      : proc_prio);
    
    # Python
    import ctypes
    import os
    PRIO_PROCESS, PRIO_PGRP, PRIO_USER = 0, 1, 2
    libc = ctypes.CDLL('libc.so.6')
    libc.setpriority(PRIO_PROCESS, os.getpid(),
        max(libc.getpriority(PRIO_PROCESS, os.getpid()),
            libc.getpriority(PRIO_PGRP, os.getpgrp()),
            libc.getpriority(PRIO_USER, os.getuid())))
    

    Or of course you could fix another process's priority, with appropriate privileges.