3 Replies - 228 Views - Last Post: 05 September 2019 - 06:54 PM Rate Topic: -----

#1 Ashok_AKG   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-September 19

cgroup fails with cgroup_attach_task ()

Posted 04 September 2019 - 06:55 PM

1. cgroup fails when I set "sched_setscheduler" to SCHED_FIFO and SCHED_RR.
 sched_setscheduler(0, SCHED_FIFO, &sp) 

In case of SCHED_OTHER no problem.
Attached the sample code for reference. Execute with Root Privilege/sudo.

Error Result:
sudo ./setscheduler
Scheduling Priority [Minimums : Maximums]
SCHED_FIFO = [ 1 : 99 ]
SCHED_RR = [ 1 : 99 ]
SCHED_OTHER= [ 0 : 0 ]
********************************************************************************
Process priority is: 0
The sched_param schedule priority is: 0
The current scheduling policy is: SCHED_OTHER
Attempting to switch process to new scheduling......
********************************************************************************
Success cgroup_create_cgroup
Success SetCpuLimitation
Success SetMemoryLimitation
Success cgroup_create_cgroup
**Failed cgroup_attach_task
********************************************************************************
Process priority is: 0
The sched_param schedule priority is: 50
The current scheduling policy is: SCHED_FIFO

Test completed successfully!

2. Is there any issue with the sample code.
or am I missing anything in environment setup.
Environment:
Ubuntu : 16.04 LTS
Gcc : gcc (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010
cgroup lib : libcgroup-dev (0.41-7ubuntu1).
cgroup-bin : cgroup-bin (0.41-7ubuntu1)


Mod: The code..
#include <stdio.h> /* For printf(...)*/
#include <stdlib.h> /* For exit() */
#include <errno.h> /* For the errno definition and all of the error state macros */
#include <string.h> /* For memset() */
#include <unistd.h>
#include <cstdint>
#include <sched.h> /* for all SCHED_/sched_ calls */
#include <sys/resource.h> /* for getpriority() */
#include <libcgroup.h>

/* Defines _POSIX_PRIORITY_SCHEDULING if this system has all of the scheduling system calls */
#include <unistd.h>

#ifdef _POSIX_PRIORITY_SCHEDULING
static const int have_sched_prio = 1;
#else
static const int have_sched_prio = 0;
#endif /* _POSIX_PRIORITY_SCHEDULING */

/* For mapping sched_policy integer -> corresponding string name.  The #defines
 * can be found by looking in /usr/include/sched.h and following #includes
 * until you find the SCHED_* definitions.
 */
const static int SCHED_POLICY_MAX = 3;
const char *sched_policies[] = {
    "SCHED_OTHER",
    "SCHED_FIFO",
    "SCHED_RR",
    "SCHED_BATCH"
};

void print_process_prio(pid_t pid)
{
    /* Get the proirity of this process. This is the NON-REALTIME priority.
     *   http://linux.die.net/man/2/getpriority
     */
    /* This can return -1 as a legitimate value, so first clear errno
     * and make sure to check it after the call.
     */
    errno = 0;
    int this_prio = getpriority(PRIO_PROCESS, pid);
    if ((this_prio == -1) && (errno)) {
        perror("Syscall getpriority failed");
    } else {
        printf("Process priority is: %i\n", this_prio);
    }
}

void print_sched_type(pid_t pid)
{
    int policy = sched_getscheduler(pid);
    if (policy < 0) {
        perror("Syscall sched_getscheduler() had problems");
        return;
    }
    if (policy > SCHED_POLICY_MAX) {
        printf("Syscall sched_getscheduler() returned a policy number greater than allowed!\n");
        return;
    }
    printf("The current scheduling policy is: %s\n", sched_policies[policy]);
}

void print_sched_priority(pid_t pid)
{
    /* Get and inspect the scheduling parameters.  This can contain realtime relevant
     * information if this process is operating with SCHED_FIFO
     */
    struct sched_param param;
    if (sched_getparam(pid, &param) < 0) {
        perror("Syscall sched_getparam barfed");
    } else {
        printf("The sched_param schedule priority is: %i\n", param.sched_priority);
    }
}

void hline(void)
{
    char str[82];
    memset(str, '*', 80);
    str[80] = '\n';
    str[81] = '\0';
    printf("%s", str);
}

bool SetCpuLimitation(cgroup* group, uint64_t cpuUs)
{
    // set cpu default limits
    cgroup_controller* cpuController = cgroup_add_controller(group, "cpu");
    if (!cpuController) {
        printf("[EM] cgroup Resource group [EM] cpu controller cannot be added ");        
        return false;
    }
    /// @note
    /// Current period is 100 microsecond
    int ret = cgroup_add_value_uint64(cpuController, "cpu.cfs_period_us", 100 * 1000);

    if (ret)
    {
        printf("[EM] cgroup Resource group [EM] cannot add value to cpu.cfs_period_us");
    }

    ret = cgroup_add_value_uint64(cpuController, "cpu.cfs_quota_us", cpuUs);

    if (ret)
    {
        printf("[EM] cgroup Resource group [EM] cannot add value to cpu.cfs_quota_us");
    }

    return true;
}

bool SetMemoryLimitation(cgroup* group, uint64_t memoryByte)
{
    cgroup_controller* memoryController = cgroup_add_controller(group, "memory");
    if (!memoryController) {
        printf("[EM] cgroup Resource group [EM] memory controller cannot be added ");
        return false;
    }

    int ret = cgroup_add_value_int64(memoryController, "memory.limit_in_bytes", static_cast<int64_t>(memoryByte));
    if (ret) {
        printf("[EM] cgroup Resource group [EM] cannot add value to memory.limit_in_bytes");
    }    

    return true;
}

bool createnewgroup()
{
    struct cgroup *foo = cgroup_new_cgroup("cgp");
	if (!SetCpuLimitation(foo, 90 * 1000))
    {
		printf("**Failed SetCpuLimitation\n");
        cgroup_free(&foo);
        return false;
    } else {
        printf(" Success SetCpuLimitation\n");
    }

    if (!SetMemoryLimitation(foo, 500000000))
    {
		printf("**Failed SetMemoryLimitation\n");
        cgroup_free(&foo);
        return false;
    } else {
        printf(" Success SetMemoryLimitation\n");
    }
	int ret = cgroup_create_cgroup(foo, 1);
    if (ret)
    {
        printf("**Failed cgroup_create_cgroup\n");
        return false;
    }else{
        printf(" Success cgroup_create_cgroup \n");
    }
	int ret_1 = cgroup_attach_task(foo);
    cgroup_free(&foo);
    if (ret_1)
    {
        printf("**Failed cgroup_attach_task \n");
        //return false;
    } else {
        printf(" Success cgroup_attach_task \n");
    }
}

int main(int argc, char *argv[])
{
    if (!have_sched_prio) {
        printf("This system does not have POSIX process priority scheduling!\n");
        exit(1);
    }

    /* Get the minimum and maxminum schedule priorities */
    int min_prio_FIFO = sched_get_priority_min(SCHED_FIFO);
    int max_prio_FIFO = sched_get_priority_max(SCHED_FIFO);

    int min_prio_RR = sched_get_priority_min(SCHED_RR);
    int max_prio_RR = sched_get_priority_max(SCHED_RR);

    int min_prio_OTHER = sched_get_priority_min(SCHED_OTHER);
    int max_prio_OTHER = sched_get_priority_max(SCHED_OTHER);

    printf("Scheduling Priority [Minimums : Maximums]\n"
           "        SCHED_FIFO = [ %i      :  %i ]\n"
           "        SCHED_RR   = [ %i      :  %i ]\n"
           "        SCHED_OTHER= [ %i      :  %i ]\n",
           min_prio_FIFO,
           max_prio_FIFO,
           min_prio_RR,
           max_prio_RR,
           min_prio_OTHER,
           max_prio_OTHER);

    hline();
    print_process_prio(0);
    print_sched_priority(0);
    print_sched_type(0);

    printf("Attempting to switch process to new scheduling......\n");
    hline();
    struct sched_param sp;
    memset(&sp, 0, sizeof(sp));
    // sp.sched_priority = 0;                            // OTHER Min:0 Max:0 - set always 0.
    // if (sched_setscheduler(0, SCHED_OTHER, &sp) < 0)  // SCHED_OTHER
    sp.sched_priority = 50;                              // FIFO/RR Min:0 Max:99
    // if (sched_setscheduler(0, SCHED_RR, &sp) < 0) 
    if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) 
    {
        perror("Problem setting scheduling policy"); // probably need rtprio rule in /etc/security/limits.conf)
        exit(1);
    }

    int ret = cgroup_init();
    if(ret)
    {
        printf("**Failed cgroup_create_cgroup \n");
        return false;
    } else {
        printf(" Success cgroup_create_cgroup \n");
    }
    createnewgroup();
    hline();
    print_process_prio(0);
    print_sched_priority(0);
    print_sched_type(0);

    printf("\nTest completed successfully!\n");
}
:code:

Attached File(s)


This post has been edited by modi123_1: 04 September 2019 - 07:35 PM


Is This A Good Question/Topic? 0
  • +

Replies To: cgroup fails with cgroup_attach_task ()

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7020
  • View blog
  • Posts: 23,840
  • Joined: 05-May 12

Re: cgroup fails with cgroup_attach_task ()

Posted 04 September 2019 - 08:51 PM

It might help you (and us) if you told us what the value of ret_1 was when you detected that your call to cgroup_attach_task() failed. As far as I know, most OS APIs don't just return a random number for error codes, but rather the numbers have specific meanings.

Anyway, most of the Linux 3.7+ sources I've stumbled across using Google suggest that cgroup_attach_task() takes two parameters, not just one. Perhaps the sample code you have is out of date?
Was This Post Helpful? 0
  • +
  • -

#3 Ashok_AKG   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 03-September 19

Re: cgroup fails with cgroup_attach_task ()

Posted 04 September 2019 - 09:52 PM

Error Code Information:
**Failed cgroup_attach_task : 50016
cgroup_attach_task Error description is : Unknown error 50016

I could find one argument for cgroup_attach_task in tasks.h header.
/usr/include/libcgroup/tasks.h
 int cgroup_attach_task(struct cgroup *cgroup); 


I tired the below , getting same error.
 int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid);


Perhaps the sample code you have is out of date?

No, Am using cgroup in my library which is throwing same error.
Am trying to execute simple sample to check the exact issue.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7020
  • View blog
  • Posts: 23,840
  • Joined: 05-May 12

Re: cgroup fails with cgroup_attach_task ()

Posted 05 September 2019 - 06:54 PM

So based on this documentation for the flavor of cgroup_attach_task() that takes one parameter, 50016 is ECGOTHER. The details on that error has this to say about it:

Quote

ECGOTHER
Represents error coming from other libraries like glibc.

libcgroup users need to check cgroup_get_last_errno() upon encountering this error.

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1