static void confirm_common(directive_t * d) { if (d->values[2] != NULL) d->nd->u.common.perm = parse_perm(d->values[2]); if (d->values[3] != NULL) d->nd->u.common.owner = get_string(d->values[3]); }
void sg_xmlcfg::load_bbparms(const bpt::iptree& pt, bool enable_hidden) { gpenv& env_mgr = gpenv::instance(); boost::char_separator<char> sep(" \t\b"); int i; try { memset(&bbparms, '\0', sizeof(sg_bbparms_t)); bbparms.magic = VERSION; bbparms.bbrelease = SGRELEASE; int current = time(0); BOOST_FOREACH(const bpt::iptree::value_type& v, pt.get_child("servicegalaxy")) { if (v.first != "cluster") continue; const bpt::iptree& v_pt = v.second; if (enable_hidden) { bbparms.bbversion = get_value(v_pt, "bbversion", current); bbparms.sgversion = get_value(v_pt, "sgversion", current); } else { bbparms.bbversion = current; bbparms.sgversion = current; } string clstid; env_mgr.expand_var(clstid, v_pt.get<string>("clstid")); try { bbparms.ipckey = boost::lexical_cast<int>(clstid); } catch (exception& ex) { throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstid invalid, {1}.") % ex.what()).str(SGLOCALE)); } if (bbparms.ipckey <= 0 || bbparms.ipckey >= (1 << MCHIDSHIFT)) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstid is invalid, should be positive but less than {1}.") % (1 << MCHIDSHIFT)).str(SGLOCALE)); bbparms.uid = get_value(v_pt, "uid", ::getuid()); bbparms.gid = get_value(v_pt, "gid", ::getgid()); parse_perm(get_value(v_pt, "perm", string("")), bbparms.perm, "cluster.perm"); bbparms.options = SGLAN; // default to LAN mode bbparms.ldbal = DFLT_LDBAL; string options = get_value(v_pt, "options", string("")); tokenizer options_tokens(options, sep); for (tokenizer::iterator iter = options_tokens.begin(); iter != options_tokens.end(); ++iter) { string str = *iter; if (strcasecmp(str.c_str(), "LAN") == 0) bbparms.options |= SGLAN; else if (strcasecmp(str.c_str(), "MIGALLOWED") == 0) bbparms.options |= SGMIGALLOWED; else if (strcasecmp(str.c_str(), "HA") == 0) bbparms.options |= SGHA; else if (strcasecmp(str.c_str(), "ACCSTATS") == 0) bbparms.options |= SGACCSTATS; else if (strcasecmp(str.c_str(), "CLEXITL") == 0) bbparms.options |= SGCLEXITL; else if (strcasecmp(str.c_str(), "AA") == 0) bbparms.options |= SGAA; else if (strcasecmp(str.c_str(), "RR") == 0) bbparms.ldbal = LDBAL_RR; else if (strcasecmp(str.c_str(), "RT") == 0) bbparms.ldbal = LDBAL_RT; } i = 0; string master = v_pt.get<string>("master"); tokenizer master_tokens(master, sep); for (tokenizer::iterator iter = master_tokens.begin(); iter != master_tokens.end(); ++iter) { string str = *iter; if (str.length() > MAX_IDENT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.master too long for master node.")).str(SGLOCALE)); strcpy(bbparms.master[i++], str.c_str()); if (i > MAX_MASTERS) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.master too many masters.")).str(SGLOCALE)); } bbparms.current = get_value(v_pt, "curid", 0); if (bbparms.current < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.curid must be zero or positive.")).str(SGLOCALE)); bbparms.maxpes = get_value(v_pt, "maxnodes", DFLT_MAXNODES); if (bbparms.maxpes <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxnodes must be positive.")).str(SGLOCALE)); bbparms.maxnodes = get_value(v_pt, "maxnets", DFLT_MAXNETS); if (bbparms.maxnodes <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxnets must be positive.")).str(SGLOCALE)); bbparms.maxaccsrs = get_value(v_pt, "maxclts", DFLT_MAXCLTS); if (bbparms.maxaccsrs <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxclts must be positive.")).str(SGLOCALE)); bbparms.maxques = get_value(v_pt, "maxques", DFLT_MAXQUES); if (bbparms.maxques <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxques must be positive.")).str(SGLOCALE)); bbparms.maxsgt = get_value(v_pt, "maxpgs", DFLT_MAXPGS); if (bbparms.maxsgt <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxpgs must be positive.")).str(SGLOCALE)); bbparms.maxsvrs = get_value(v_pt, "maxprocs", DFLT_MAXPROCS); if (bbparms.maxsvrs <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxprocs must be positive.")).str(SGLOCALE)); bbparms.maxsvcs = get_value(v_pt, "maxops", DFLT_MAXOPS); if (bbparms.maxsvcs <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxops must be positive.")).str(SGLOCALE)); bbparms.quebkts = get_value(v_pt, "quebkts", DFLT_QUEBKTS); if (bbparms.quebkts <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.quebkts must be positive.")).str(SGLOCALE)); bbparms.sgtbkts = get_value(v_pt, "pgbkts", DFLT_PGBKTS); if (bbparms.sgtbkts <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.pgbkts must be positive.")).str(SGLOCALE)); bbparms.svrbkts = get_value(v_pt, "procbkts", DFLT_PROCBKTS); if (bbparms.svrbkts <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.procbkts must be positive.")).str(SGLOCALE)); bbparms.svcbkts = get_value(v_pt, "opbkts", DFLT_OPBKTS); if (bbparms.svcbkts <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.opbkts must be positive.")).str(SGLOCALE)); bbparms.scan_unit = get_value(v_pt, "polltime", DFLT_POLLTIME); if (bbparms.scan_unit < 6) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.polltime must be at least 6.")).str(SGLOCALE)); bbparms.sanity_scan = get_value(v_pt, "robustint", DFLT_ROBUSTINT); if (bbparms.sanity_scan <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.robustint must be positive.")).str(SGLOCALE)); bbparms.stack_size = get_value(v_pt, "stacksize", DFLT_STACKSIZE); if (bbparms.stack_size <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.stacksize must be positive.")).str(SGLOCALE)); bbparms.max_num_msg = get_value(v_pt, "msgmnb", DFLT_MSGMNB); if (bbparms.max_num_msg <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.msgmnb must be positive.")).str(SGLOCALE)); bbparms.max_msg_size = get_value(v_pt, "msgmax", DFLT_MSGMAX); if (bbparms.max_msg_size <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.msgmax must be positive.")).str(SGLOCALE)); bbparms.cmprs_limit = get_value(v_pt, "cmprslimit", DFLT_CMPRSLIMIT); if (bbparms.cmprs_limit < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.cmprslimit must be zero or positive.")).str(SGLOCALE)); bbparms.remedy = get_value(v_pt, "costfix", DFLT_COSTFIX); if (bbparms.remedy < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.costfix must be zero or positive.")).str(SGLOCALE)); bbparms.max_open_queues = get_value(v_pt, "nfiles", DFLT_NFILES); if (bbparms.max_open_queues <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.nfiles must be positive.")).str(SGLOCALE)); bbparms.block_time = get_value(v_pt, "blktime", DFLT_BLKTIME); if (bbparms.block_time <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.blktime must be positive.")).str(SGLOCALE)); bbparms.dbbm_wait = get_value(v_pt, "clstwait", DFLT_CLSTWAIT); if (bbparms.dbbm_wait <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstwait must be positive.")).str(SGLOCALE)); bbparms.bbm_query = get_value(v_pt, "mngrquery", DFLT_MNGRQUERY); if (bbparms.bbm_query < bbparms.sanity_scan) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.mngrquery must be no less than robustint.")).str(SGLOCALE)); bbparms.init_wait = get_value(v_pt, "initwait", DFLT_INITWAIT); if (bbparms.init_wait <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.initwait must be positive.")).str(SGLOCALE)); } } catch (bpt::ptree_bad_data& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section cluster failure, {1} ({2})") % ex.what() % ex.data<string>()).str(SGLOCALE)); } catch (bpt::ptree_error& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section cluster failure, {1}") % ex.what()).str(SGLOCALE)); } }
void sg_xmlcfg::load_svrents(const bpt::iptree& pt) { boost::char_separator<char> sep(" \t\b"); gpenv& env_mgr = gpenv::instance(); try { BOOST_FOREACH(const bpt::iptree::value_type& v, pt.get_child("servicegalaxy.processes")) { if (v.first != "process") continue; const bpt::iptree& v_pt = v.second; sg_svrent_t item; memset(&item, '\0', sizeof(sg_svrent_t)); item.sparms.rqparms.options = RESTARTABLE; item.bparms.flags = 0; string options = get_value(v_pt, "options", string("")); tokenizer options_tokens(options, sep); for (tokenizer::iterator iter = options_tokens.begin(); iter != options_tokens.end(); ++iter) { string str = *iter; if (strcasecmp(str.c_str(), "NONRESTART ") == 0) item.sparms.rqparms.options &= ~RESTARTABLE; else if (strcasecmp(str.c_str(), "REPLYQ") == 0) item.bparms.flags |= BF_REPLYQ; else if (strcasecmp(str.c_str(), "PRESERVE_FD") == 0) item.bparms.flags |= BF_PRESERVE_FD; } item.sparms.rqparms.grace = get_value(v_pt, "rstint", DFLT_RSTINT); if (item.sparms.rqparms.grace <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.rstint must be positive.")).str(SGLOCALE)); item.sparms.rqparms.maxgen = get_value(v_pt, "maxrst", std::numeric_limits<int>::max()); if (item.sparms.rqparms.maxgen <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.maxrst must be positive.")).str(SGLOCALE)); string lqname = get_value(v_pt, "lqname", string("")); if (lqname.length() > MAX_IDENT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.lqname is too long.")).str(SGLOCALE)); strcpy(item.sparms.rqparms.saddr, lqname.c_str()); string exitcmd = get_value(v_pt, "exitcmd", string("")); if (exitcmd.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.exitcmd is too long.")).str(SGLOCALE)); strcpy(item.sparms.rqparms.rcmd, exitcmd.c_str()); string procname = v_pt.get<string>("procname"); if (procname.empty() || procname.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.procname is empty or too long.")).str(SGLOCALE)); strcpy(item.sparms.rqparms.filename, procname.c_str()); item.sparms.svrproc.svrid = v_pt.get<int>("prcid"); if (item.sparms.svrproc.svrid <= MAX_RESERVED_PRCID) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.prcid must be no less than {1}.") % MAX_RESERVED_PRCID).str(SGLOCALE)); parse_perm(get_value(v_pt, "rqperm", string("")), item.sparms.rqperm, "processes.process.rqperm"); parse_perm(get_value(v_pt, "rpperm", string("")), item.sparms.rpperm, "processes.process.rpperm"); item.sparms.sequence = get_value(v_pt, "priority", 0); if (item.sparms.sequence < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.priority must be zero or positive.")).str(SGLOCALE)); item.bparms.bootmin = get_value(v_pt, "min", 1); if (item.bparms.bootmin < 0 || item.bparms.bootmin > 1000) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.min must be between 0 and 1000.")).str(SGLOCALE)); item.sparms.svridmax = get_value(v_pt, "max", 1); if (item.sparms.svridmax < 1 || item.sparms.svridmax > 1000) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.max must be between 1 and 1000.")).str(SGLOCALE)); if (item.bparms.bootmin > item.sparms.svridmax) item.sparms.svridmax = item.sparms.svrproc.svrid + item.bparms.bootmin - 1; else item.sparms.svridmax += item.sparms.svrproc.svrid - 1; item.sparms.max_num_msg = get_value(v_pt, "msgmnb", 0); if (item.sparms.max_num_msg < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.msgmnb must be zero or positive.")).str(SGLOCALE)); item.sparms.max_msg_size = get_value(v_pt, "msgmax", 0); if (item.sparms.max_msg_size < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.msgmax must be zero or positive.")).str(SGLOCALE)); item.sparms.cmprs_limit = get_value(v_pt, "cmprslimit", 0); if (item.sparms.cmprs_limit < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.cmprslimit must be zero or positive.")).str(SGLOCALE)); item.sparms.remedy = get_value(v_pt, "costfix", 0); if (item.sparms.remedy < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.costfix must be zero or positive.")).str(SGLOCALE)); string pgname = get_value(v_pt, "pgname", string("")); if (pgname.length() > MAX_IDENT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.pgname is too long.")).str(SGLOCALE)); strcpy(item.sparms.sgname, pgname.c_str()); if (item.sparms.sgname[0] == '\0') { item.sparms.svrproc.grpid = DFLT_PGID; } else { bool found = false; BOOST_FOREACH(const sg_sgent_t& v, sgents) { if (v.sgname == pgname) { item.sparms.svrproc.grpid = v.grpid; found = true; } } if (!found) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: Can't find process group for {1}") % pgname).str(SGLOCALE)); } // TGWS需要独立的应答队列 if (strcmp(item.sparms.rqparms.filename, "sgtgws") == 0) SGP->_SGP_boot_flags |= BF_REPLYQ; string args; env_mgr.expand_var(args, get_value(v_pt, "args", string("-A"))); if (args.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.args is too long.")).str(SGLOCALE)); strcpy(item.bparms.clopt, args.c_str()); string profile; env_mgr.expand_var(profile, get_value(v_pt, "profile", string(""))); if (profile.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.profile is too long.")).str(SGLOCALE)); strcpy(item.bparms.envfile, profile.c_str()); BOOST_FOREACH(const sg_svrent_t& v, svrents) { if (v.sparms.svrproc.grpid == item.sparms.svrproc.grpid && ((v.sparms.svrproc.svrid <= item.sparms.svrproc.svrid && v.sparms.svridmax >= item.sparms.svrproc.svrid) || (v.sparms.svrproc.svrid <= item.sparms.svridmax && v.sparms.svridmax >= item.sparms.svridmax))) throw sg_exception(__FILE__, __LINE__, SGEPROTO, 0, (_("ERROR: duplicate process entry.")).str(SGLOCALE)); } svrents.push_back(item); } } catch (bpt::ptree_bad_data& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section processes failure, {1} ({2})") % ex.what() % ex.data<string>()).str(SGLOCALE)); } catch (bpt::ptree_error& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section processes failure, {1}") % ex.what()).str(SGLOCALE)); } }
void sg_xmlcfg::load_mchents(const bpt::iptree& pt) { gpenv& env_mgr = gpenv::instance(); try { BOOST_FOREACH(const bpt::iptree::value_type& v, pt.get_child("servicegalaxy.nodes")) { if (v.first != "node") continue; const bpt::iptree& v_pt = v.second; sg_mchent_t item; memset(&item, '\0', sizeof(sg_mchent_t)); string hostname = v_pt.get<string>("hostname"); if (hostname.length() > MAX_IDENT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.hostname is too long.")).str(SGLOCALE)); strcpy(item.pmid, hostname.c_str()); string hostid = v_pt.get<string>("hostid"); if (hostid.length() > MAX_IDENT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.hostid is too long.")).str(SGLOCALE)); strcpy(item.lmid, hostid.c_str()); string sgroot; env_mgr.expand_var(sgroot, v_pt.get<string>("sgroot")); if (sgroot.length() > MAX_SGROOT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.sgroot is too long.")).str(SGLOCALE)); strcpy(item.sgdir, sgroot.c_str()); string approot; env_mgr.expand_var(approot, v_pt.get<string>("approot")); if (approot.length() > MAX_APPROOT) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.approot is too long.")).str(SGLOCALE)); strcpy(item.appdir, approot.c_str()); string sgprofile; env_mgr.expand_var(sgprofile, v_pt.get<string>("sgprofile")); if (sgprofile.length() > MAX_SGCONFIG) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.sgprofile is too long.")).str(SGLOCALE)); strcpy(item.sgconfig, sgprofile.c_str()); string args; env_mgr.expand_var(args, get_value(v_pt, "args", string(""))); if (args.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.args is too long.")).str(SGLOCALE)); strcpy(item.clopt, args.c_str()); string profile; env_mgr.expand_var(profile, get_value(v_pt, "profile", string(""))); if (profile.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.profile is too long.")).str(SGLOCALE)); strcpy(item.envfile, profile.c_str()); string logname; env_mgr.expand_var(logname, get_value(v_pt, "logname", string(""))); if (logname.length() > MAX_LSTRING) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.logname is too long.")).str(SGLOCALE)); strcpy(item.ulogpfx, logname.c_str()); item.maxaccsrs = get_value(v_pt, "maxclts", 0); if (item.maxaccsrs < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.maxclts must be zero or positive.")).str(SGLOCALE)); parse_perm(get_value(v_pt, "perm", string("")), item.perm, "nodes.node.perm"); item.uid = get_value(v_pt, "uid", 0); if (item.uid < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.uid must be zero or positive.")).str(SGLOCALE)); item.gid = get_value(v_pt, "gid", 0); if (item.gid < 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.gid must be zero or positive.")).str(SGLOCALE)); item.netload = get_value(v_pt, "netcost", DFLT_NETCOST); if (item.netload <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.netcost must be positive.")).str(SGLOCALE)); item.maxconn = get_value(v_pt, "maxconn", DFLT_MAXCONN); if (item.maxconn <= 0) throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: nodes.node.maxconn must be positive.")).str(SGLOCALE)); BOOST_FOREACH(const sg_mchent_t& v, mchents) { if (strcmp(v.pmid, item.pmid) == 0 || strcmp(v.lmid, item.lmid) == 0) throw sg_exception(__FILE__, __LINE__, SGEPROTO, 0, (_("ERROR: duplicate node entry.")).str(SGLOCALE)); } mchents.push_back(item); } } catch (bpt::ptree_bad_data& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section nodes failure, {1} ({2})") % ex.what() % ex.data<string>()).str(SGLOCALE)); } catch (bpt::ptree_error& ex) { throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section nodes failure, {1}") % ex.what()).str(SGLOCALE)); } }
/* * load_groups() * Given GID, perhaps add some more abilities */ static void load_groups(struct uinfo *u) { FILE *fp; char buf[128]; char *p; int nperm = 1; /* * Read group file */ if ((fp = fopen(_PATH_GROUP, "r")) == 0) { return; } while (fgets(buf, sizeof(buf), fp)) { /* * Leave if there's no more slots to fill */ if (nperm >= PROCPERMS) { break; } /* * Get rid of trailing \n, skip to GID field */ buf[strlen(buf)-1] = '\0'; p = strchr(buf, ':'); if (p == 0) { break; } ++p; /* * Compare GID to our own GID */ if (atoi(p) != u->u_gid) { continue; } /* * Match. Move to first of n ability fields */ p = strchr(p, ':'); if (p == 0) { break; } ++p; /* * While there are more fields, add them to the user */ while (p) { char *q; /* * Null-terminate current, record next */ q = strchr(p, ':'); if (q) { *q++ = '\0'; } /* * Parse permission into struct */ parse_perm(&u->u_perms[nperm], p); u->u_perms[nperm].perm_uid = u->u_uid; /* * Advance to next */ nperm += 1; p = q; } /* * Assume there's only one entry for a given * GID. */ break; } fclose(fp); }
/* * fillin() * Given account record, fill in uinfo struct */ static void fillin(char *rec, struct uinfo *u) { char *p; extern void zero_ids(); /* * Default to something harmless */ u->u_uid = u->u_gid = 2; strcpy(u->u_passwd, "*"); strcpy(u->u_home, DEFHOME); strcpy(u->u_shell, _PATH_DEFAULT_SHELL); strcpy(u->u_env, _PATH_ENV); zero_ids(u->u_perms, PROCPERMS); /* * Password */ p = strchr(rec, ':'); if (p) { *p++ = '\0'; } strcpy(u->u_passwd, rec); if ((rec = p) == 0) { return; } /* * UID */ u->u_uid = atoi(rec); rec = strchr(rec, ':'); if (rec == 0) { return; } rec++; /* * GID */ u->u_gid = atoi(rec); rec = strchr(rec, ':'); if (rec == 0) { return; } rec++; /* * Skip name */ rec = strchr(rec, ':'); if (rec == 0) { return; } rec++; /* * Parse permission string */ p = strchr(rec, ':'); if (p) { *p++ = '\0'; } parse_perm(&u->u_perms[0], rec); u->u_perms[0].perm_uid = u->u_uid; if ((rec = p) == 0) { return; } /* * If there are further groups to be added because of * GID, add them here. */ load_groups(u); /* * Parse home */ p = strchr(rec, ':'); if (p) { *p++ = '\0'; } strcpy(u->u_home, rec); if ((rec = p) == 0) { return; } /* * Parse environment */ p = strchr(rec, ':'); if (p) { *p++ = '\0'; } strcpy(u->u_env, rec); if ((rec = p) == 0) { return; } /* * The rest is the shell */ strcpy(u->u_shell, rec); }
int main(int argc, char *argv[]) { char cmdline[256]; char *prefix; size_t prefix_len; int (*compfn)(const void *a, const void *b); pm_kernel_t *ker; pm_process_t *proc; pid_t *pids; size_t num_procs; pm_map_t **maps; size_t num_maps; pm_memusage_t map_usage; struct library_info *li, **lis; struct mapping_info *mi, **mis; struct process_info *pi; size_t i, j; int error; int perm; bool all; uint64_t required_flags; uint64_t flags_mask; bool has_swap = false; signal(SIGPIPE, SIG_IGN); compfn = &sort_by_pss; order = -1; prefix = NULL; prefix_len = 0; opterr = 0; perm = 0; all = false; required_flags = 0; flags_mask = 0; while (1) { int c; const struct option longopts[] = { {"all", 0, 0, 'a'}, {"cached", 0, 0, 'c'}, {"nocached", 0, 0, 'C'}, {"ksm", 0, 0, 'k'}, {"help", 0, 0, 'h'}, {"pss", 0, 0, 'p'}, {"uss", 0, 0, 'u'}, {"vss", 0, 0, 'v'}, {"rss", 0, 0, 'r'}, {"swap", 0, 0, 's'}, {"reverse", 0, 0, 'R'}, {"path", required_argument, 0, 'P'}, {"perm", required_argument, 0, 'm'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "acChkm:pP:uvrsR", longopts, NULL); if (c < 0) { break; } /* Alphabetical cases */ switch (c) { case 'a': all = true; break; case 'c': required_flags = 0; flags_mask = PM_PAGE_SWAPBACKED; break; case 'C': required_flags = PM_PAGE_SWAPBACKED; flags_mask = PM_PAGE_SWAPBACKED; break; case 'k': required_flags = PM_PAGE_KSM; flags_mask = PM_PAGE_KSM; break; case 'h': usage(argv[0]); exit(EXIT_SUCCESS); case 'm': perm = parse_perm(optarg); break; case 'p': compfn = &sort_by_pss; break; case 'P': prefix = optarg; prefix_len = strlen(prefix); break; case 'u': compfn = &sort_by_uss; break; case 'v': compfn = &sort_by_vss; break; case 'r': compfn = &sort_by_rss; break; case 's': compfn = &sort_by_swap; break; case 'R': order *= -1; break; case '?': fprintf(stderr, "Invalid argument \"%s\".\n", argv[optind - 1]); usage(argv[0]); exit(EXIT_FAILURE); default: abort(); } } argc -= optind; argv += optind; libraries = malloc(INIT_LIBRARIES * sizeof(struct library_info *)); libraries_count = 0; libraries_size = INIT_LIBRARIES; error = pm_kernel_create(&ker); if (error) { fprintf(stderr, "Error initializing kernel interface -- " "does this kernel have pagemap?\n"); exit(EXIT_FAILURE); } error = pm_kernel_pids(ker, &pids, &num_procs); if (error) { fprintf(stderr, "Error listing processes.\n"); exit(EXIT_FAILURE); } for (i = 0; i < num_procs; i++) { error = pm_process_create(ker, pids[i], &proc); if (error) { fprintf(stderr, "warning: could not create process interface for %d\n", pids[i]); continue; } pi = get_process(pids[i]); error = pm_process_maps(proc, &maps, &num_maps); if (error) { fprintf(stderr, "Error listing maps for process %d.\n", proc->pid); exit(EXIT_FAILURE); } for (j = 0; j < num_maps; j++) { if (prefix && (strncmp(pm_map_name(maps[j]), prefix, prefix_len))) continue; if (perm && (pm_map_flags(maps[j]) & PM_MAP_PERMISSIONS) != perm) continue; li = get_library(pm_map_name(maps[j]), all); if (!li) continue; mi = get_mapping(li, pi); error = pm_map_usage_flags(maps[j], &map_usage, flags_mask, required_flags); if (error) { fprintf(stderr, "Error getting map memory usage of " "map %s in process %d.\n", pm_map_name(maps[j]), proc->pid); exit(EXIT_FAILURE); } if (map_usage.swap) { has_swap = true; } pm_memusage_add(&mi->usage, &map_usage); pm_memusage_add(&li->total_usage, &map_usage); } } printf(" %6s %6s %6s %6s %6s ", "RSStot", "VSS", "RSS", "PSS", "USS"); if (has_swap) { printf(" %6s ", "Swap"); } printf("Name/PID\n"); fflush(stdout); qsort(libraries, libraries_count, sizeof(libraries[0]), &licmp); for (i = 0; i < libraries_count; i++) { li = libraries[i]; printf("%6zdK %6s %6s %6s %6s ", li->total_usage.pss / 1024, "", "", "", ""); if (has_swap) { printf(" %6s ", ""); } printf("%s\n", li->name); fflush(stdout); qsort(li->mappings, li->mappings_count, sizeof(li->mappings[0]), compfn); for (j = 0; j < li->mappings_count; j++) { mi = li->mappings[j]; pi = mi->proc; printf( " %6s %6zdK %6zdK %6zdK %6zdK ", "", mi->usage.vss / 1024, mi->usage.rss / 1024, mi->usage.pss / 1024, mi->usage.uss / 1024); if (has_swap) { printf("%6zdK ", mi->usage.swap / 1024); } printf(" %s [%d]\n", pi->cmdline, pi->pid); } printf("\n"); fflush(stdout); } return 0; }
static int parse_perm_line(struct identity_downcall_data *data, char *line, size_t size) { char uid_str[size]; char nid_str[size]; char perm_str[size]; lnet_nid_t nid; __u32 perm, noperm; int rc, i; if (data->idd_nperms >= N_PERMS_MAX) { errlog("permission count %d > max %d\n", data->idd_nperms, N_PERMS_MAX); return -1; } rc = sscanf(line, "%s %s %s", nid_str, uid_str, perm_str); if (rc != 3) { errlog("can't parse line %s\n", line); return -1; } if (!match_uid(data->idd_uid, uid_str)) return 0; if (!strcmp(nid_str, "*")) { nid = LNET_NID_ANY; } else { nid = libcfs_str2nid(nid_str); if (nid == LNET_NID_ANY) { errlog("can't parse nid %s\n", nid_str); return -1; } } if (parse_perm(&perm, &noperm, perm_str)) { errlog("invalid perm %s\n", perm_str); return -1; } /* merge the perms with the same nid. * * If there is LNET_NID_ANY in data->idd_perms[i].pdd_nid, * it must be data->idd_perms[0].pdd_nid, and act as default perm. */ if (nid != LNET_NID_ANY) { int found = 0; /* search for the same nid */ for (i = data->idd_nperms - 1; i >= 0; i--) { if (data->idd_perms[i].pdd_nid == nid) { data->idd_perms[i].pdd_perm = (data->idd_perms[i].pdd_perm | perm) & ~noperm; found = 1; break; } } /* NOT found, add to tail */ if (!found) { data->idd_perms[data->idd_nperms].pdd_nid = nid; data->idd_perms[data->idd_nperms].pdd_perm = perm & ~noperm; data->idd_nperms++; } } else { if (data->idd_nperms > 0) { /* the first one isn't LNET_NID_ANY, need exchange */ if (data->idd_perms[0].pdd_nid != LNET_NID_ANY) { data->idd_perms[data->idd_nperms].pdd_nid = data->idd_perms[0].pdd_nid; data->idd_perms[data->idd_nperms].pdd_perm = data->idd_perms[0].pdd_perm; data->idd_perms[0].pdd_nid = LNET_NID_ANY; data->idd_perms[0].pdd_perm = perm & ~noperm; data->idd_nperms++; } else { /* only fix LNET_NID_ANY item */ data->idd_perms[0].pdd_perm = (data->idd_perms[0].pdd_perm | perm) & ~noperm; } } else { /* it is the first one, only add to head */ data->idd_perms[0].pdd_nid = LNET_NID_ANY; data->idd_perms[0].pdd_perm = perm & ~noperm; data->idd_nperms = 1; } } return 0; }