/* now the session stuff */ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { pid_t pid; int ctrl, ret; char *user_name; struct passwd *pwd; D(("called.")); ctrl = _pam_parse(pamh, argc, argv); ret = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (user_name == NULL || ret != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "open_session - error recovering" "username"); return PAM_SESSION_ERR; } pwd = pam_modutil_getpwnam(pamh, user_name); if (!pwd) { if (ctrl & PAM_DEBUG_ARG) pam_syslog(pamh, LOG_ERR, "open_session username" " '%s' does not exist", user_name); return PAM_SESSION_ERR; } D(("user name is %s", user_name)); /* Initialize libcg */ ret = cgroup_init(); if (ret) { if (ctrl & PAM_DEBUG_ARG) pam_syslog(pamh, LOG_ERR, "libcgroup initialization" " failed"); return PAM_SESSION_ERR; } D(("Initialized libcgroup successfuly.")); /* Determine the pid of the task */ pid = getpid(); /* Note: We are using default gid here. Is there a way to determine * under what egid service will be provided? */ ret = cgroup_change_cgroup_uid_gid(pwd->pw_uid, pwd->pw_gid, pid); if (ret) { if (ctrl & PAM_DEBUG_ARG) pam_syslog(pamh, LOG_ERR, "Change of cgroup for process" " with username %s failed.\n", user_name); return PAM_SESSION_ERR; } if (ctrl & PAM_DEBUG_ARG) pam_syslog(pamh, LOG_DEBUG, "Changed cgroup for process %d" " with username %s.\n", pid, user_name); return PAM_SUCCESS; }
/* * Initialized the statistics information. */ int init_stats() { int i = 0; /* Initialize the cgroup. */ if (cgroup_init()) { fprintf(stderr, "cgvmstat: initialize the cgroup failed.\n"); printf("error: Initialize the cgroup failed.\n"); uninit_stats(); return -1; } if (init_group_lists(&mem_groups)) { fprintf(stderr, "cgvmstat: initialize the memory group lists failed.\n", CG_CPUSET); printf("error: Initialize the memory group lists failed.\n"); uninit_stats(); return -1; } if (!(avg_cpuset_stats = (struct cpuset_stats*) malloc( sizeof(struct cpuset_stats)))) { fprintf(stderr, "cgiostat: malloc the result of cpuset stats failed.\n"); printf("error: Malloc the result of cpuset stats failed.\n"); uninit_stats(); return -1; } memset(avg_cpuset_stats, 0, sizeof(struct cpuset_stats)); return 0; }
/* display all controllers attached to the given hierarchy */ static int print_all_controllers_in_hierarchy(const char *tname, int hierarchy, int flags) { int ret = 0; void *handle; struct controller_data info; int first = 1; cont_name_t cont_names; cont_name_t cont_name; /* * Initialize libcgroup and intentionally ignore its result, * no mounted controller is valid use case. */ (void) cgroup_init(); ret = cgroup_get_all_controller_begin(&handle, &info); if ((ret != 0) && (ret != ECGEOF)) { fprintf(stderr, "cannot read controller data: %s\n", cgroup_strerror(ret)); return ret; } while (ret != ECGEOF) { /* controller is in the hierrachy */ if (info.hierarchy != hierarchy) goto next; if (first) { /* the first controller in the hierarchy */ memset(cont_name, 0, FILENAME_MAX); strncpy(cont_name, info.name, FILENAME_MAX-1); memset(cont_names, 0, FILENAME_MAX); strncpy(cont_names, info.name, FILENAME_MAX-1); first = 0; } else { /* the next controller in the hierarchy */ strncat(cont_names, ",", FILENAME_MAX-1); strncat(cont_names, info.name, FILENAME_MAX-1); } next: ret = cgroup_get_all_controller_next(&handle, &info); if (ret && ret != ECGEOF) goto end; } ret = print_controller_mount(cont_name, flags, cont_names, hierarchy); end: cgroup_get_all_controller_end(&handle); if (ret == ECGEOF) ret = 0; return ret; }
/** * Tests the cgroup_init_cgroup() api under different scenarios * @param retcode error code in case any error is expected from api * @param i the test number */ void test_cgroup_init(int retcode, int i) { int retval; retval = cgroup_init(); if (retval == retcode) message(i, PASS, "init()\t", retval, info[NOMESSAGE]); else message(i, FAIL, "init()", retval, info[NOMESSAGE]); }
/* * Initialized the statistics information. */ int init_stats() { int i = 0; /* Initialize the cgroup. */ if (cgroup_init()) { fprintf(stderr, "cgiostat: initialize the cgroup failed.\n"); printf("error: Initialize the cgroup failed.\n"); uninit_stats(); return -1; } if (init_group_lists(&mem_groups)) { fprintf(stderr, "cgiostat: initialize the memory group lists failed.\n", CG_MEMORY); printf("error: Initialize the memory group lists failed.\n"); uninit_stats(); return -1; } return 0; }
static void cgroup_child_init(apr_pool_t *pool, server_rec *server) { cgroup *mygroup; int ret; cgroup_config *cgconf = ap_get_module_config(server->module_config, &cgroup_module); if ((ret = cgroup_init()) > 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, server, "Could not initialize CGroups: %s", cgroup_strerror(ret)); } else if ((mygroup = cgroup_new_cgroup(cgconf->default_cgroup)) == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, server, "Cannot allocate CGroup %s resources: %s", cgconf->default_cgroup, cgroup_strerror(ret)); } else if ((ret = cgroup_get_cgroup(mygroup)) > 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, server, "Cannot get CGroup %s: %s", cgconf->default_cgroup, cgroup_strerror(ret)); } else if ((ret = cgroup_attach_task(mygroup)) > 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, server, "Cannot assign to CGroup %s: %s", cgconf->default_cgroup, cgroup_strerror(ret)); } else { cg_enabled = 1; cgroup_free(&mygroup); } }
/* * Assumes the cgroup is already mounted at /cgroup/memory/a * * Assumes some processes are already in the cgroup * * Assumes it is the memory controller is mounted in at that * point */ int main() { int size; pid_t *pids; int ret; int i; ret = cgroup_init(); if (ret) { printf("FAIL: cgroup_init failed with %s\n", cgroup_strerror(ret)); exit(3); } ret = cgroup_get_procs("a", "memory", &pids, &size); if (ret) { printf("FAIL: cgroup_get_procs failed with %s\n", cgroup_strerror(ret)); exit(3); } for (i = 0; i < size; i++) printf("%u\n", pids[i]); return 0; }
asmlinkage void __init start_kernel(void) { char * command_line; extern struct kernel_param __start___param[], __stop___param[]; smp_setup_processor_id(); /* * Need to run as early as possible, to initialize the * lockdep hash: */ unwind_init(); lockdep_init(); cgroup_init_early(); local_irq_disable(); early_boot_irqs_off(); early_init_irq_lock_class(); /* * Interrupts are still disabled. Do necessary setups, then * enable them */ lock_kernel(); tick_init(); boot_cpu_init(); page_address_init(); printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); setup_command_line(command_line); unwind_setup(); setup_per_cpu_areas(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() * time - but meanwhile we still have a functioning scheduler. */ sched_init(); /* * Disable preemption - early bootup scheduling is extremely * fragile until we cpu_idle() for the first time. */ preempt_disable(); build_all_zonelists(); page_alloc_init(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); parse_early_param(); parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); if (!irqs_disabled()) { printk(KERN_WARNING "start_kernel(): bug: interrupts were " "enabled *very* early, fixing it\n"); local_irq_disable(); } sort_main_extable(); trap_init(); rcu_init(); init_IRQ(); pidhash_init(); init_timers(); hrtimers_init(); softirq_init(); timekeeping_init(); time_init(); profile_init(); if (!irqs_disabled()) printk("start_kernel(): bug: interrupts were enabled early\n"); early_boot_irqs_on(); local_irq_enable(); /* * HACK ALERT! This is early. We're enabling the console before * we've done PCI setups etc, and console_init() must be aware of * this. But we do want output early, in case something goes wrong. */ console_init(); if (panic_later) panic(panic_later, panic_param); lockdep_info(); /* * Need to run this when irqs are enabled, because it wants * to self-test [hard/soft]-irqs on/off lock inversion bugs * too: */ locking_selftest(); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start < min_low_pfn << PAGE_SHIFT) { printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT); initrd_start = 0; } #endif vfs_caches_init_early(); cpuset_init_early(); mem_init(); kmem_cache_init(); setup_per_cpu_pageset(); numa_policy_init(); if (late_time_init) late_time_init(); calibrate_delay(); /* * CS370: Adding code to check for "printme" parameter */ if (printme) printk("\nHello World from Me!\n"); pidmap_init(); pgtable_cache_init(); prio_tree_init(); anon_vma_init(); #ifdef CONFIG_X86 if (efi_enabled) efi_enter_virtual_mode(); #endif fork_init(num_physpages); proc_caches_init(); buffer_init(); unnamed_dev_init(); key_init(); security_init(); vfs_caches_init(num_physpages); radix_tree_init(); signals_init(); /* rootfs populating might need page-writeback */ page_writeback_init(); #ifdef CONFIG_PROC_FS proc_root_init(); #endif cgroup_init(); cpuset_init(); taskstats_init_early(); delayacct_init(); check_bugs(); acpi_early_init(); /* before LAPIC and SMP init */ /* Do the rest non-__init'ed, we're now alive */ rest_init(); }
int main(int argc, char** argv) { static struct option longopts[] = { { "daemonize", no_argument, NULL, 'd' }, { "cgroup", required_argument, NULL, 'g' }, { "pidfile", required_argument, NULL, 'p'}, { "restart_on_crash", no_argument, NULL, 'r'}, { "verbose", no_argument, NULL, 'v'}, { NULL, 0, NULL, 0} }; int cl; char* event_command; char* event_control_path; char* oom_control_path; char* pidfile = NULL; uint64_t efdcounter; struct sigaction sa; int flag; assert(argc > 1); exit_flag = 0; restart_flag = 0; char daemon_flag = 0; char restart_on_crash_flg = 0; struct cgroup_context cgc; char verbose_log = 0; cgc.cgroup_name = NULL; int ch; while((ch = getopt_long(argc, argv, "rvdg:p:", longopts, NULL)) != -1) { switch(ch) { case 'd': daemon_flag = 1; break; case 'g': asprintf(&cgc.cgroup_name, "%s", optarg); break; case 'p': asprintf(&pidfile, "%s", optarg); break; case 'r': restart_on_crash_flg = 1; break; case 'v': verbose_log = 1; break; default: break; } } if(cgc.cgroup_name == NULL) { slog(LOG_ALERT, "FATAL: No cgroup specified, exiting"); abort(); } if(daemon_flag) { if(daemon(0,0) == -1) { slog(LOG_ALERT, "FATAL: failed to daemonize!"); abort(); } if(pidfile) { pid_t pid = getpid(); FILE* f = fopen(pidfile, "w"); if(!f) { slog(LOG_ALERT, "FATAL: Failed to write to pidfile"); abort(); } fprintf(f, "%d", pid); fclose(f); free(pidfile); pidfile = NULL; } } cgc.efd = eventfd(0,0); assert(cgc.efd != -1); cgroup_init(); cgroup_get_subsys_mount_point("memory", &((cgc.cgroup_path))); cgroup_get_subsys_mount_point("freezer", &((cgc.freezer_path))); cgc.purgatory = cgroup_new_cgroup("purgatory"); cgroup_add_controller(cgc.purgatory, "freezer"); cgroup_create_cgroup(cgc.purgatory,1); char* purgatory_freeze_path; FILE* freezer_fd; asprintf(&purgatory_freeze_path, "/%s/purgatory/freezer.state", cgc.freezer_path); freezer_fd = fopen(purgatory_freeze_path,"w"); fprintf(freezer_fd, "FROZEN"); fclose(freezer_fd); free(purgatory_freeze_path); asprintf(&event_control_path, "/%s/%s/cgroup.event_control", cgc.cgroup_path, cgc.cgroup_name); cgc.ecfd = open(event_control_path, O_WRONLY); if(cgc.ecfd < 0) { slog(LOG_ALERT, "FATAL: failed to open cgroup event control: %s\n", event_control_path); perror("cgroup.event_control"); } asprintf(&oom_control_path, "/%s/%s/memory.oom_control", cgc.cgroup_path, cgc.cgroup_name); cgc.oomfd = open(oom_control_path, O_RDONLY); if(!(cgc.oomfd >=0)) { slog(LOG_ALERT, "FATAL: Failed to open oom_control"); abort(); } cl = asprintf(&event_command, "%d %d", cgc.efd, cgc.oomfd); write(cgc.ecfd, event_command, cl); free(event_control_path); free(event_command); free(oom_control_path); setjmp(exit_stack); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NOMASK; sa.sa_handler = exit_handler; sigaction(SIGINT, &sa, NULL); if(restart_on_crash_flg) //optionally make an effort to handle crashes { sa.sa_handler = crash_handler; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGABRT, &sa, NULL); } if(restart_flag < 2) //try to handle recursive faults { stop_oomkiller(&cgc); while(!exit_flag) { read(cgc.efd, &efdcounter, sizeof(uint64_t)); flag = 0; //stop killing if the task list is empty (shouldn't happen) if(verbose_log) log_process_table(); //dump process list to syslog while(is_oom(&cgc) && flag >= 0) { flag = find_victim(&cgc); usleep(100); //give processes a chance to die } } cgroup_delete_cgroup(cgc.purgatory, 0); start_oomkiller(&cgc); close(cgc.oomfd); close(cgc.ecfd); } if(restart_flag) { char* args[argc+1]; int i; for(i=0;i<argc;i++) { asprintf(&(args[i]), "%s", argv[i]); } args[argc] = NULL; execv(argv[0], args); } }
int main(int argc, char *argv[]) { int ret = 0, i; int cg_specified = 0; int flag_child = 0; uid_t uid; gid_t gid; pid_t pid; int c; struct cgroup_group_spec *cgroup_list[CG_HIER_MAX]; memset(cgroup_list, 0, sizeof(cgroup_list)); while ((c = getopt_long(argc, argv, "+g:sh", longopts, NULL)) > 0) { switch (c) { case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, CG_HIER_MAX); if (ret) { fprintf(stderr, "cgroup controller and path" "parsing failed\n"); return -1; } cg_specified = 1; break; case 's': flag_child |= CGROUP_DAEMON_UNCHANGE_CHILDREN; break; case 'h': usage(0, argv[0]); exit(0); default: usage(1, argv[0]); exit(1); } } /* Executable name */ if (!argv[optind]) { usage(1, argv[0]); exit(1); } /* Initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "libcgroup initialization failed: %s\n", cgroup_strerror(ret)); return ret; } /* Just for debugging purposes. */ uid = geteuid(); gid = getegid(); cgroup_dbg("My euid and eguid is: %d,%d\n", (int) uid, (int) gid); uid = getuid(); gid = getgid(); pid = getpid(); ret = cgroup_register_unchanged_process(pid, flag_child); if (ret) { fprintf(stderr, "registration of process failed\n"); return ret; } /* * 'cgexec' command file needs the root privilege for executing * a cgroup_register_unchanged_process() by using unix domain * socket, and an euid/egid should be changed to the executing user * from a root user. */ if (setresuid(uid, uid, uid)) { fprintf(stderr, "%s", strerror(errno)); return -1; } if (setresgid(gid, gid, gid)) { fprintf(stderr, "%s", strerror(errno)); return -1; } if (cg_specified) { /* * User has specified the list of control group and * controllers * */ for (i = 0; i < CG_HIER_MAX; i++) { if (!cgroup_list[i]) break; ret = cgroup_change_cgroup_path(cgroup_list[i]->path, pid, (const char*const*) cgroup_list[i]->controllers); if (ret) { fprintf(stderr, "cgroup change of group failed\n"); return ret; } } } else { /* Change the cgroup by determining the rules based on uid */ ret = cgroup_change_cgroup_flags(uid, gid, argv[optind], pid, 0); if (ret) { fprintf(stderr, "cgroup change of group failed\n"); return ret; } } /* Now exec the new process */ ret = execvp(argv[optind], &argv[optind]); if (ret == -1) { fprintf(stderr, "%s", strerror(errno)); return -1; } return 0; }
static int corosync_move_to_root_cgroup(void) { int res = -1; #ifdef HAVE_LIBCGROUP int cg_ret; struct cgroup *root_cgroup = NULL; struct cgroup_controller *root_cpu_cgroup_controller = NULL; char *current_cgroup_path = NULL; cg_ret = cgroup_init(); if (cg_ret) { log_printf(LOGSYS_LEVEL_WARNING, "Unable to initialize libcgroup: %s ", cgroup_strerror(cg_ret)); goto exit_res; } cg_ret = cgroup_get_current_controller_path(getpid(), "cpu", ¤t_cgroup_path); if (cg_ret) { log_printf(LOGSYS_LEVEL_WARNING, "Unable to get current cpu cgroup path: %s ", cgroup_strerror(cg_ret)); goto exit_res; } if (strcmp(current_cgroup_path, "/") == 0) { log_printf(LOGSYS_LEVEL_DEBUG, "Corosync is already in root cgroup path"); res = 0; goto exit_res; } root_cgroup = cgroup_new_cgroup("/"); if (root_cgroup == NULL) { log_printf(LOGSYS_LEVEL_WARNING, "Can't create root cgroup"); goto exit_res; } root_cpu_cgroup_controller = cgroup_add_controller(root_cgroup, "cpu"); if (root_cpu_cgroup_controller == NULL) { log_printf(LOGSYS_LEVEL_WARNING, "Can't create root cgroup cpu controller"); goto exit_res; } cg_ret = cgroup_attach_task(root_cgroup); if (cg_ret) { log_printf(LOGSYS_LEVEL_WARNING, "Can't attach task to root cgroup: %s ", cgroup_strerror(cg_ret)); goto exit_res; } cg_ret = cgroup_get_current_controller_path(getpid(), "cpu", ¤t_cgroup_path); if (cg_ret) { log_printf(LOGSYS_LEVEL_WARNING, "Unable to get current cpu cgroup path: %s ", cgroup_strerror(cg_ret)); goto exit_res; } if (strcmp(current_cgroup_path, "/") == 0) { log_printf(LOGSYS_LEVEL_NOTICE, "Corosync successfully moved to root cgroup"); res = 0; } else { log_printf(LOGSYS_LEVEL_WARNING, "Can't move Corosync to root cgroup"); } exit_res: if (root_cgroup != NULL) { cgroup_free(&root_cgroup); } /* * libcgroup doesn't define something like cgroup_fini so there is no way how to clean * it's cache. It has to be called when libcgroup authors decide to implement it. */ #endif return (res); }
int main(int argc, char *argv[]) { /* Patch to the log file */ const char *logp = NULL; /* Syslog facility */ int facility = 0; /* Verbose level */ int verbosity = 2; /* For catching signals */ struct sigaction sa; /* Should we daemonize? */ unsigned char daemon = 1; /* Return codes */ int ret = 0; struct passwd *pw; struct group *gr; /* Command line arguments */ const char *short_options = "hvqf:s::ndQu:g:"; struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {"quiet", no_argument, NULL, 'q'}, {"logfile", required_argument, NULL, 'f'}, {"syslog", optional_argument, NULL, 's'}, {"nodaemon", no_argument, NULL, 'n'}, {"debug", no_argument, NULL, 'd'}, {"nolog", no_argument, NULL, 'Q'}, {"socket-user", required_argument, NULL, 'u'}, {"socket-group", required_argument, NULL, 'g'}, {NULL, 0, NULL, 0} }; /* Make sure the user is root. */ if (getuid() != 0) { fprintf(stderr, "Error: Only root can start/stop the control" " group rules engine daemon\n"); ret = 1; goto finished; } while (1) { int c; c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) break; switch (c) { case 'h': /* --help */ usage(stdout, "Help:\n"); ret = 0; goto finished; case 'v': /* --verbose */ verbosity++; break; case 'q': /* --quiet */ verbosity--; break; case 'Q': /* --nolog */ verbosity = 0; break; case 'f': /* --logfile=<filename> */ logp = optarg; break; case 's': /* --syslog=[facility] */ if (optarg) { facility = cgre_parse_syslog_facility(optarg); if (facility == 0) { fprintf(stderr, "Unknown syslog facility: %s\n", optarg); ret = 2; goto finished; } } else { facility = LOG_DAEMON; } break; case 'n': /* --no-fork */ daemon = 0; break; case 'd': /* --debug */ /* same as -vvn */ daemon = 0; verbosity = 4; logp = "-"; break; case 'u': /* --socket-user */ pw = getpwnam(optarg); if (pw == NULL) { usage(stderr, "Cannot find user %s", optarg); ret = 3; goto finished; } socket_user = pw->pw_uid; cgroup_dbg("Using socket user %s id %d\n", optarg, (int)socket_user); break; case 'g': /* --socket-group */ gr = getgrnam(optarg); if (gr == NULL) { usage(stderr, "Cannot find group %s", optarg); ret = 3; goto finished; } socket_group = gr->gr_gid; cgroup_dbg("Using socket group %s id %d\n", optarg, (int)socket_group); break; default: usage(stderr, ""); ret = 2; goto finished; } } /* Initialize libcgroup. */ if ((ret = cgroup_init()) != 0) { fprintf(stderr, "Error: libcgroup initialization failed, %s\n", cgroup_strerror(ret)); goto finished; } /* Ask libcgroup to load the configuration rules. */ if ((ret = cgroup_init_rules_cache()) != 0) { fprintf(stderr, "Error: libcgroup failed to initialize rules" "cache from %s. %s\n", CGRULES_CONF_FILE, cgroup_strerror(ret)); goto finished; } /* Now, start the daemon. */ ret = cgre_start_daemon(logp, facility, daemon, verbosity); if (ret < 0) { fprintf(stderr, "Error: Failed to launch the daemon, %s\n", cgroup_strerror(ret)); goto finished; } /* * Set up the signal handler to reload the cached rules upon reception * of a SIGUSR2 signal. */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = &cgre_flash_rules; sigemptyset(&sa.sa_mask); if ((ret = sigaction(SIGUSR2, &sa, NULL))) { flog(LOG_ERR, "Failed to set up signal handler for SIGUSR2." " Error: %s", strerror(errno)); goto finished; } /* * Set up the signal handler to catch SIGINT and SIGTERM so that we * can exit gracefully. */ sa.sa_handler = &cgre_catch_term; ret = sigaction(SIGINT, &sa, NULL); ret |= sigaction(SIGTERM, &sa, NULL); if (ret) { flog(LOG_ERR, "Failed to set up the signal handler. Error:" " %s", strerror(errno)); goto finished; } /* Print the configuration to the log file, or stdout. */ if (logfile && loglevel >= LOG_INFO) cgroup_print_rules_config(logfile); flog(LOG_NOTICE, "Started the CGroup Rules Engine Daemon."); /* We loop endlesly in this function, unless we encounter an error. */ ret = cgre_create_netlink_socket_process_msg(); finished: if (logfile && logfile != stdout) fclose(logfile); return ret; }
int main(int argc, char *argv[]) { int ret = 0; int i, j; int c; int flags = 0; int final_ret = 0; int counter = 0; int max = 0; struct ext_cgroup_record *ecg_list = NULL; int skip; struct cgroup_group_spec **cgroup_list = NULL; struct cgroup *cgroup; struct cgroup_controller *cgc; /* initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "%s: " "libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret)); goto err; } cgroup_list = calloc(argc, sizeof(struct cgroup_group_spec *)); if (cgroup_list == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); ret = -1; goto err; } ecg_list = calloc(argc, sizeof(struct ext_cgroup_record *)); if (cgroup_list == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); ret = -1; goto err; } /* * Parse arguments */ while ((c = getopt_long(argc, argv, "rhg:", long_options, NULL)) > 0) { switch (c) { case 'r': flags |= CGFLAG_DELETE_RECURSIVE; break; case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], optarg); ret = -1; goto err; } break; case 'h': usage(0, argv[0]); ret = 0; goto err; default: usage(1, argv[0]); ret = -1; goto err; } } /* parse groups on command line */ for (i = optind; i < argc; i++) { ret = parse_cgroup_spec(cgroup_list, argv[i], argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], argv[i]); ret = -1; goto err; } } /* for each cgroup to be deleted */ for (i = 0; i < argc; i++) { if (!cgroup_list[i]) break; /* create the new cgroup structure */ cgroup = cgroup_new_cgroup(cgroup_list[i]->path); if (!cgroup) { ret = ECGFAIL; fprintf(stderr, "%s: can't create new cgroup: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* add controllers to the cgroup */ j = 0; while (cgroup_list[i]->controllers[j]) { skip = 0; /* * save controller name, cg name and hierarchy number * to determine whether we should skip adding controller */ if (counter == max) { /* * there is not enough space to store them, * create it */ max = max + argc; ecg_list = (struct ext_cgroup_record *) realloc(ecg_list, max * sizeof(struct ext_cgroup_record)); if (!ecg_list) { fprintf(stderr, "%s: ", argv[0]); fprintf(stderr, "not enough memory\n"); final_ret = -1; goto err; } } strncpy(ecg_list[counter].controller, cgroup_list[i]->controllers[j], FILENAME_MAX); ecg_list[counter].controller[FILENAME_MAX - 1] = '\0'; strncpy(ecg_list[counter].name, cgroup_list[i]->path, FILENAME_MAX); ecg_list[counter].name[FILENAME_MAX - 1] = '\0'; ret = skip_add_controller(counter, &skip, ecg_list); if (ret) goto err; if (skip) { /* don't add the controller, goto next one */ goto next; } cgc = cgroup_add_controller(cgroup, cgroup_list[i]->controllers[j]); if (!cgc) { ret = ECGFAIL; fprintf(stderr, "%s: " "controller %s can't be added\n", argv[0], cgroup_list[i]->controllers[j]); cgroup_free(&cgroup); goto err; } next: counter++; j++; } ret = cgroup_delete_cgroup_ext(cgroup, flags); /* * Remember the errors and continue, try to remove all groups. */ if (ret != 0) { fprintf(stderr, "%s: cannot remove group '%s': %s\n", argv[0], cgroup->name, cgroup_strerror(ret)); final_ret = ret; } cgroup_free(&cgroup); } ret = final_ret; err: if (ecg_list) free(ecg_list); if (cgroup_list) { for (i = 0; i < argc; i++) { if (cgroup_list[i]) cgroup_free_group_spec(cgroup_list[i]); } free(cgroup_list); } return ret; }
int main(int argc, char *argv[]) { int ret = 0; int i, j; int c; static struct option long_opts[] = { {"help", no_argument, NULL, 'h'}, {"task", required_argument, NULL, 't'}, {"admin", required_argument, NULL, 'a'}, {"", required_argument, NULL, 'g'}, {"dperm", required_argument, NULL, 'd'}, {"fperm", required_argument, NULL, 'f' }, {"tperm", required_argument, NULL, 's' }, {0, 0, 0, 0}, }; uid_t tuid = CGRULE_INVALID, auid = CGRULE_INVALID; gid_t tgid = CGRULE_INVALID, agid = CGRULE_INVALID; struct cgroup_group_spec **cgroup_list; struct cgroup *cgroup; struct cgroup_controller *cgc; /* approximation of max. numbers of groups that will be created */ int capacity = argc; /* permission variables */ mode_t dir_mode = NO_PERMS; mode_t file_mode = NO_PERMS; mode_t tasks_mode = NO_PERMS; int dirm_change = 0; int filem_change = 0; /* no parametr on input */ if (argc < 2) { usage(1, argv[0]); return -1; } cgroup_list = calloc(capacity, sizeof(struct cgroup_group_spec *)); if (cgroup_list == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); ret = -1; goto err; } /* parse arguments */ while ((c = getopt_long(argc, argv, "a:t:g:hd:f:s:", long_opts, NULL)) > 0) { switch (c) { case 'h': usage(0, argv[0]); ret = 0; goto err; case 'a': /* set admin uid/gid */ if (parse_uid_gid(optarg, &auid, &agid, argv[0])) goto err; break; case 't': /* set task uid/gid */ if (parse_uid_gid(optarg, &tuid, &tgid, argv[0])) goto err; break; case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, capacity); if (ret) { fprintf(stderr, "%s: " "cgroup controller and path" "parsing failed (%s)\n", argv[0], argv[optind]); ret = -1; goto err; } break; case 'd': dirm_change = 1; ret = parse_mode(optarg, &dir_mode, argv[0]); break; case 'f': filem_change = 1; ret = parse_mode(optarg, &file_mode, argv[0]); break; case 's': filem_change = 1; ret = parse_mode(optarg, &tasks_mode, argv[0]); break; default: usage(1, argv[0]); ret = -1; goto err; } } /* no cgroup name */ if (argv[optind]) { fprintf(stderr, "%s: " "wrong arguments (%s)\n", argv[0], argv[optind]); ret = -1; goto err; } /* initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "%s: " "libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* for each new cgroup */ for (i = 0; i < capacity; i++) { if (!cgroup_list[i]) break; /* create the new cgroup structure */ cgroup = cgroup_new_cgroup(cgroup_list[i]->path); if (!cgroup) { ret = ECGFAIL; fprintf(stderr, "%s: can't add new cgroup: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* set uid and gid for the new cgroup based on input options */ ret = cgroup_set_uid_gid(cgroup, tuid, tgid, auid, agid); if (ret) goto err; /* add controllers to the new cgroup */ j = 0; while (cgroup_list[i]->controllers[j]) { cgc = cgroup_add_controller(cgroup, cgroup_list[i]->controllers[j]); if (!cgc) { ret = ECGINVAL; fprintf(stderr, "%s: " "controller %s can't be add\n", argv[0], cgroup_list[i]->controllers[j]); cgroup_free(&cgroup); goto err; } j++; } /* all variables set so create cgroup */ if (dirm_change | filem_change) cgroup_set_permissions(cgroup, dir_mode, file_mode, tasks_mode); ret = cgroup_create_cgroup(cgroup, 0); if (ret) { fprintf(stderr, "%s: " "can't create cgroup %s: %s\n", argv[0], cgroup->name, cgroup_strerror(ret)); cgroup_free(&cgroup); goto err; } cgroup_free(&cgroup); } err: if (cgroup_list) { for (i = 0; i < capacity; i++) { if (cgroup_list[i]) cgroup_free_group_spec(cgroup_list[i]); } free(cgroup_list); } return ret; }
int main(int argc, char *argv[]) { int ret = 0; int i, j; int c; int flags = 0; int final_ret = 0; struct cgroup_group_spec **cgroup_list = NULL; struct cgroup *cgroup; struct cgroup_controller *cgc; /* initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "%s: " "libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret)); goto err; } cgroup_list = calloc(argc, sizeof(struct cgroup_group_spec *)); if (cgroup_list == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); ret = -1; goto err; } /* * Parse arguments */ while ((c = getopt_long(argc, argv, "rhg:", long_options, NULL)) > 0) { switch (c) { case 'r': flags |= CGFLAG_DELETE_RECURSIVE; break; case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], optarg); ret = -1; goto err; } break; case 'h': usage(0, argv[0]); ret = 0; goto err; default: usage(1, argv[0]); ret = -1; goto err; } } /* parse groups on command line */ for (i = optind; i < argc; i++) { ret = parse_cgroup_spec(cgroup_list, argv[i], argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], argv[i]); ret = -1; goto err; } } /* for each cgroup to be deleted */ for (i = 0; i < argc; i++) { if (!cgroup_list[i]) break; /* create the new cgroup structure */ cgroup = cgroup_new_cgroup(cgroup_list[i]->path); if (!cgroup) { ret = ECGFAIL; fprintf(stderr, "%s: can't create new cgroup: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* add controllers to the cgroup */ j = 0; while (cgroup_list[i]->controllers[j]) { cgc = cgroup_add_controller(cgroup, cgroup_list[i]->controllers[j]); if (!cgc) { ret = ECGFAIL; fprintf(stderr, "%s: " "controller %s can't be added\n", argv[0], cgroup_list[i]->controllers[j]); cgroup_free(&cgroup); goto err; } j++; } ret = cgroup_delete_cgroup_ext(cgroup, flags); /* * Remember the errors and continue, try to remove all groups. */ if (ret != 0) { fprintf(stderr, "%s: cannot remove group '%s': %s\n", argv[0], cgroup->name, cgroup_strerror(ret)); final_ret = ret; } cgroup_free(&cgroup); } ret = final_ret; err: if (cgroup_list) { for (i = 0; i < argc; i++) { if (cgroup_list[i]) cgroup_free_group_spec(cgroup_list[i]); } free(cgroup_list); } return ret; }
asmlinkage void __init start_kernel(void) { char * command_line; extern struct kernel_param __start___param[], __stop___param[]; smp_setup_processor_id(); /* * Need to run as early as possible, to initialize the * lockdep hash: */ lockdep_init(); debug_objects_early_init(); /* * Set up the the initial canary ASAP: */ boot_init_stack_canary(); cgroup_init_early(); local_irq_disable(); early_boot_irqs_off(); early_init_irq_lock_class(); /* * Interrupts are still disabled. Do necessary setups, then * enable them */ lock_kernel(); tick_init(); boot_cpu_init(); page_address_init(); printk(KERN_NOTICE "%s", linux_banner); setup_arch(&command_line); mm_init_owner(&init_mm, &init_task); setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ build_all_zonelists(NULL); page_alloc_init(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); //[email protected] 2011.11.14 begin //support lcd compatible //reviewed by [email protected] #if defined(CONFIG_LCD_DRV_ALL) char *p = strstr(boot_command_line, "lcd="); if (p) { lcd_drv_index = p[4] - 'A'; printk("lcd index = %d", lcd_drv_index); } #endif //[email protected] 2011.11.14 end parse_early_param(); parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); /* * These use large bootmem allocations and must precede * kmem_cache_init() */ pidhash_init(); vfs_caches_init_early(); sort_main_extable(); trap_init(); mm_init(); /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() * time - but meanwhile we still have a functioning scheduler. */ sched_init(); /* * Disable preemption - early bootup scheduling is extremely * fragile until we cpu_idle() for the first time. */ preempt_disable(); if (!irqs_disabled()) { printk(KERN_WARNING "start_kernel(): bug: interrupts were " "enabled *very* early, fixing it\n"); local_irq_disable(); } rcu_init(); radix_tree_init(); /* init some links before init_ISA_irqs() */ early_irq_init(); init_IRQ(); prio_tree_init(); init_timers(); hrtimers_init(); softirq_init(); timekeeping_init(); time_init(); profile_init(); if (!irqs_disabled()) printk(KERN_CRIT "start_kernel(): bug: interrupts were " "enabled early\n"); early_boot_irqs_on(); local_irq_enable(); /* Interrupts are enabled now so all GFP allocations are safe. */ gfp_allowed_mask = __GFP_BITS_MASK; kmem_cache_init_late(); /* * HACK ALERT! This is early. We're enabling the console before * we've done PCI setups etc, and console_init() must be aware of * this. But we do want output early, in case something goes wrong. */ console_init(); if (panic_later) panic(panic_later, panic_param); lockdep_info(); /* * Need to run this when irqs are enabled, because it wants * to self-test [hard/soft]-irqs on/off lock inversion bugs * too: */ locking_selftest(); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " "disabling it.\n", page_to_pfn(virt_to_page((void *)initrd_start)), min_low_pfn); initrd_start = 0; } #endif page_cgroup_init(); enable_debug_pagealloc(); kmemtrace_init(); kmemleak_init(); debug_objects_mem_init(); idr_init_cache(); setup_per_cpu_pageset(); numa_policy_init(); if (late_time_init) late_time_init(); sched_clock_init(); calibrate_delay(); pidmap_init(); anon_vma_init(); #ifdef CONFIG_X86 if (efi_enabled) efi_enter_virtual_mode(); #endif thread_info_cache_init(); cred_init(); fork_init(totalram_pages); proc_caches_init(); buffer_init(); key_init(); security_init(); dbg_late_init(); vfs_caches_init(totalram_pages); signals_init(); /* rootfs populating might need page-writeback */ page_writeback_init(); #ifdef CONFIG_PROC_FS proc_root_init(); #endif cgroup_init(); cpuset_init(); taskstats_init_early(); delayacct_init(); check_bugs(); acpi_early_init(); /* before LAPIC and SMP init */ sfi_init_late(); ftrace_init(); /* Do the rest non-__init'ed, we're now alive */ rest_init(); }
int container_init(void) { return cgroup_init(); }