Example #1
0
static struct share_acct *
get_sacct(const char *acct_name, const char *user_list)
{
    char name[128];
    uint32_t shares;
    int cc;
    int n;
    struct share_acct *sacct;
    char *p;
    char *p0;

    p0 = p = strdup(user_list);
    /* If we don't find account name
     * in the user list make sure we
     * return NULL and not random memory.
     */
    sacct = NULL;

    cc = sscanf(p, "%s%u%n", name, &shares, &n);
    if (cc == EOF) {
        _free_(p);
        return NULL;
    }

    /* default can have users all
     * or explicitly named users
     */
    if (strcmp(name, "default") == 0) {
        sacct = make_sacct(acct_name, shares);
        goto pryc;
    }

    /* Match the user in the user_list
     */
    while (1) {

        cc = sscanf(p, "%s%u%n", name, &shares, &n);
        if (cc == EOF)
            break;
        if (strcmp(name, acct_name) != 0) {
            p = p + n;
            continue;
        }
        sacct = make_sacct(name, shares);
        break;
    }

pryc:
    _free_(p0);
    return sacct;
}
Example #2
0
/* parse_user_shares()
 *
 * parse user_shares[[g, 1] [e,1]]
 */
static link_t *
parse_user_shares(const char *user_shares)
{
    link_t *l;
    char *p;
    char *u;
    int cc;
    int n;
    struct share_acct *sacct;
    uint32_t sum_shares;
    linkiter_t iter;

    u = strdup(user_shares);
    assert(u);

    p = strchr(u, '[');
    *p++ = 0;

    tokenize(p);

    l = make_link();
    sum_shares = 0;

    while (1 ) {
        char name[128];
        uint32_t shares;

        cc = sscanf(p, "%s%u%n", name, &shares, &n);
        if (cc == EOF)
            break;
        if (cc != 2)
            goto bail;
        p = p + n;

        sacct = make_sacct(name, shares);
        assert(sacct);

        sum_shares = sum_shares + sacct->shares;

        enqueue_link(l, sacct);
    }

    traverse_init(l, &iter);
    while ((sacct = traverse_link(&iter))) {
        sacct->dshares = (double)sacct->shares/(double)sum_shares;
    }

    _free_(u);
    return l;

bail:

    _free_(u);
    traverse_init(l, &iter);
    while ((sacct = traverse_link(&iter)))
        free_sacct(sacct);
    fin_link(l);

    return NULL;
}
Example #3
0
/* sshare_make_tree()
 * In this function we match the user_shares as configured
 * in the queue file with the groups configured in lsb.users.
 * The fairshare configuration in the queues can be such
 * that they don't match for example:
 *
 * FAIRSHARE = USER_SHARES[[crock ,2] [zebra, 1]]
 * FAIRSHARE = USER_SHARES[[all, 1]]
 *
 * in these cases the shares are specified for users
 * directly and no groups are involved.
 */
struct tree_ *sshare_make_tree(const char *user_shares,
                               uint32_t num_grp,
                               struct group_acct *grp)
{
    struct tree_ *t;
    link_t *l;
    link_t *stack;
    linkiter_t iter;
    struct share_acct *sacct;
    struct tree_node_ *n;
    struct tree_node_ *root;

    n = NULL;
    stack = make_link();
    t = tree_init("");
    /* root summarizes all the tree counters
     */
    t->root->data = make_sacct("/", 1);
    root = NULL;

    /* First parse the user shares and make
     * the first level of the tree
     */
    l = parse_user_shares(user_shares);

z:
    if (root)
        l = parse_group_member(n->name, num_grp, grp);
    else
        root = t->root;

    if (l == NULL) {
        free_sacct(t->root->data);
        fin_link(stack);
        tree_free(t, free_sacct);
        return NULL;
    }

    traverse_init(l, &iter);
    while ((sacct = traverse_link(&iter))) {

        n = calloc(1, sizeof(struct tree_node_));
        /* dup() the name as later we free both
         * the tree node and the share account
         */
        n->name = strdup(sacct->name);

        n = tree_insert_node(root, n);
        enqueue_link(stack, n);
        n->data = sacct;
    }

    /* Sort by shares so the tree
     * is always sorted by share
     * priority
     */
    sort_siblings(root, node_cmp);

    fin_link(l);

    n = pop_link(stack);
    if (n) {
        root = n;
        goto z;
    }

    fin_link(stack);

    n = t->root;
    while ((n = tree_next_node(n))) {
        char buf[BUFSIZ];
        /* Create the hash table of nodes and their
         * immediate parent.
         */
        sacct = n->data;
        if (n->child == NULL) {
            /* all and default are synonyms as they
             * both indicate a user that is not explicitly
             * defined.
             */
            if (strcasecmp(sacct->name, "all") == 0
                || strcasecmp(sacct->name, "default") == 0) {
                sacct->options |= SACCT_USER_ALL;
            }
            sacct->options |= SACCT_USER;
            sprintf(buf, "%s/%s", n->parent->name, n->name);
            hash_install(t->node_tab, buf, n, NULL);
        } else {
            sacct->options |= SACCT_GROUP;
        }
        sprintf(buf, "%s", n->name);
        hash_install(t->node_tab, buf, n, NULL);
        print_node(n, t);
    }

    traverse_init(t->leafs, &iter);
    while ((n = traverse_link(&iter)))
        print_node(n, t);

    /* Fairshare tree is built and sorted
     * by decreasing shares, the scheduler
     * algorithm will fill it up with
     * slots from now on.
     */
    tree_walk2(t, print_node);
    sort_tree_by_shares(t);

    return t;
}