/* make_leafs() */ static void make_leafs(struct tree_ *t) { struct tree_node_ *n; while(pop_link(t->leafs)) ; n = t->root; while ((n = tree_next_node(n))) { if (n->child == NULL) { enqueue_link(t->leafs, n); } } }
/* 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; }