static void dl_iterator_test(void) { printsln((String)__func__); List ac; ac = dl_of_string("1, 2, 3, 4, 5"); // various ways of iterating a list: ListIterator iter = l_iterator(ac); while (l_has_next(iter)) { double i = dl_next(&iter); printiln(i); } // DoubleListNode *first = (DoubleListNode*)ac->first; for (DoubleListNode *node = ac->first; node != NULL; node = node->next) { double d = node->value; printiln(d); } #if 0 while (iter = dl_next(iter)) { double d = dl_current(iter); printiln(d); } for (DoubleListIterator iter = dl_iterator(ac); dl_has_current(iter); iter = dl_next(iter)) { double d = dl_current(iter); printiln(d); } #endif l_free(ac); }
int GC_unregister_disappearing_link(void * * link) { struct disappearing_link *curr_dl, *prev_dl; size_t index; DCL_LOCK_STATE; LOCK(); index = HASH2(link, log_dl_table_size); if (((word)link & (ALIGNMENT-1))) goto out; prev_dl = 0; curr_dl = dl_head[index]; while (curr_dl != 0) { if (curr_dl -> dl_hidden_link == HIDE_POINTER(link)) { if (prev_dl == 0) { dl_head[index] = dl_next(curr_dl); } else { dl_set_next(prev_dl, dl_next(curr_dl)); } GC_dl_entries--; UNLOCK(); # ifdef DBG_HDRS_ALL dl_set_next(curr_dl, 0); # else GC_free((void *)curr_dl); # endif return(1); } prev_dl = curr_dl; curr_dl = dl_next(curr_dl); } out: UNLOCK(); return(0); }
void policyline(char *line, char *type) { struct pol_rule *pr; char *w; if (config_rules_end == NULL) config_rules_end = &config_rules; pr = xmalloc(sizeof(*pr)); pr->type = type; pr->rule = NULL; for (w = dl_next(line); w != line ; w = dl_next(w)) { if (try_rule(w, rule_path, &pr->rule)) config_rules_has_path = 1; else if (! try_rule(w, rule_type, &pr->rule) && ! try_rule(w, pol_metadata, &pr->rule) && ! try_rule(w, pol_act, &pr->rule) && ! try_rule(w, pol_domain, &pr->rule) && ! try_rule(w, pol_auto, &pr->rule)) pr_err("policy rule %s unrecognised and ignored\n", w); } pr->next = config_rules; config_rules = pr; }
void programline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) if (alert_program == NULL) alert_program = xstrdup(w); }
void mailline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) if (alert_email == NULL) alert_email = xstrdup(w); }
int dllist_test() { struct mynode *mn[NUM_NODES]; LPDL_NODE node; struct mynode *data; /* *insert */ int i = 0; Debug_Message(LOG_FULL, "insert node from 1 to NUM_NODES(32): \n"); for (; i < NUM_NODES; i++) { mn[i] = (struct mynode *)malloc(sizeof(struct mynode)); mn[i]->string = (char *)malloc(sizeof(char) * 4); sprintf(mn[i]->string, "%d", i); dll_insert(&mytree, mn[i]); } /* *search */ Debug_Message(LOG_FULL, "search all nodes: \n"); for (node = dl_first(&mytree); node; node = dl_next(node)) { struct mynode *data; container_of(data, node, struct mynode, node); Debug_Message(LOG_TEST, "key = %s\n", data->string); } /* *delete */ Debug_Message(LOG_FULL, "delete node 0: \n"); data = dll_search(&mytree, "0"); if (data) { dl_remove_node(&data->node, &mytree); dll_free(data); } /* *delete again*/ Debug_Message(LOG_FULL, "delete node 10: \n"); data = dll_search(&mytree, "10"); if (data) { dl_remove_node(&data->node, &mytree); dll_free(data); } /* *delete once again*/ Debug_Message(LOG_FULL, "delete node 31: \n"); data = dll_search(&mytree, "31"); if (data) { dl_remove_node(&data->node, &mytree); dll_free(data); } /* *search again*/ Debug_Message(LOG_FULL, "search again:\n"); for (node = dl_first(&mytree); node; node = dl_next(node)) { struct mynode *data; container_of(data, node, struct mynode, node); Debug_Message(LOG_TEST,"key = %s\n", data->string); } return 0; }
void free_line(char *line) { char *w; for (w=dl_next(line); w != line; w=dl_next(line)) { dl_del(w); dl_free(w); } dl_free(line); }
void programline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) { if (alert_program == NULL) alert_program = strdup(w); else fprintf(stderr, Name ": excess program on PROGRAM line: %s - ignored\n", w); } }
void homehostline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) { if (home_host == NULL) home_host = strdup(w); else fprintf(stderr, Name ": excess host name on HOMEHOST line: %s - ignored\n", w); } }
void mailline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) { if (alert_email == NULL) alert_email = strdup(w); else fprintf(stderr, Name ": excess address on MAIL line: %s - ignored\n", w); } }
/* Moves a link. Assume the lock is held. */ STATIC int GC_move_disappearing_link_inner( struct dl_hashtbl_s *dl_hashtbl, void **link, void **new_link) { struct disappearing_link *curr_dl, *prev_dl, *new_dl; size_t curr_index, new_index; word curr_hidden_link; word new_hidden_link; /* Find current link. */ curr_index = HASH2(link, dl_hashtbl -> log_size); curr_hidden_link = GC_HIDE_POINTER(link); prev_dl = NULL; for (curr_dl = dl_hashtbl -> head[curr_index]; curr_dl; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == curr_hidden_link) break; prev_dl = curr_dl; } if (NULL == curr_dl) { return GC_NOT_FOUND; } if (link == new_link) { return GC_SUCCESS; /* Nothing to do. */ } /* link found; now check new_link not present. */ new_index = HASH2(new_link, dl_hashtbl -> log_size); new_hidden_link = GC_HIDE_POINTER(new_link); for (new_dl = dl_hashtbl -> head[new_index]; new_dl; new_dl = dl_next(new_dl)) { if (new_dl -> dl_hidden_link == new_hidden_link) { /* Target already registered; bail. */ return GC_DUPLICATE; } } /* Remove from old, add to new, update link. */ if (NULL == prev_dl) { dl_hashtbl -> head[curr_index] = dl_next(curr_dl); } else { dl_set_next(prev_dl, dl_next(curr_dl)); } curr_dl -> dl_hidden_link = new_hidden_link; dl_set_next(curr_dl, dl_hashtbl -> head[new_index]); dl_hashtbl -> head[new_index] = curr_dl; return GC_SUCCESS; }
void homehostline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) { if (strcasecmp(w, "<ignore>")==0) require_homehost = 0; else if (home_host == NULL) { if (strcasecmp(w, "<none>")==0) home_host = xstrdup(""); else home_host = xstrdup(w); } } }
void mailfromline(char *line) { char *w; for (w=dl_next(line); w != line ; w=dl_next(w)) { if (alert_mail_from == NULL) alert_mail_from = strdup(w); else { char *t= NULL; asprintf(&t, "%s %s", alert_mail_from, w); free(alert_mail_from); alert_mail_from = t; } } }
void release_all_dls(ASI asi) { ASI de_asi; DE de, tmp_de; DL dl, tmp_dl; dl = asi_dl_list(asi); while (dl) { tmp_dl = dl_next(dl); de = dl_de_list(dl); while (de) { tmp_de = de_next(de); if (de_ans_subst(de) == NULL) { /* is NDE */ remove_pnde(subg_nde_list(de_subgoal(de)), de_pnde(de)); } else { de_asi = Delay(de_ans_subst(de)); remove_pnde(asi_pdes(de_asi), de_pnde(de)); } release_entry(de, released_des, de_next); de = tmp_de; /* next DE */ } /* while (de) */ release_entry(dl, released_dls, dl_next); dl = tmp_dl; /* next DL */ } }
void GC_dump_finalization(void) { struct disappearing_link * curr_dl; struct finalizable_object * curr_fo; ptr_t real_ptr, real_link; int dl_size = (log_dl_table_size == -1 ) ? 0 : (1 << log_dl_table_size); int fo_size = (log_fo_table_size == -1 ) ? 0 : (1 << log_fo_table_size); int i; GC_printf("Disappearing links:\n"); for (i = 0; i < dl_size; i++) { for (curr_dl = dl_head[i]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { real_ptr = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_obj); real_link = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_link); GC_printf("Object: %p, Link:%p\n", real_ptr, real_link); } } GC_printf("Finalizers:\n"); for (i = 0; i < fo_size; i++) { for (curr_fo = fo_head[i]; curr_fo != 0; curr_fo = fo_next(curr_fo)) { real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); GC_printf("Finalizable object: %p\n", real_ptr); } } }
int GC_general_register_disappearing_link(void * * link, void * obj) { struct disappearing_link *curr_dl; size_t index; struct disappearing_link * new_dl; DCL_LOCK_STATE; if ((word)link & (ALIGNMENT-1)) ABORT("Bad arg to GC_general_register_disappearing_link"); # ifdef THREADS LOCK(); # endif if (log_dl_table_size == -1 || GC_dl_entries > ((word)1 << log_dl_table_size)) { GC_grow_table((struct hash_chain_entry ***)(&dl_head), &log_dl_table_size); if (GC_print_stats) { GC_log_printf("Grew dl table to %u entries\n", (1 << log_dl_table_size)); } } index = HASH2(link, log_dl_table_size); curr_dl = dl_head[index]; for (curr_dl = dl_head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == HIDE_POINTER(link)) { curr_dl -> dl_hidden_obj = HIDE_POINTER(obj); # ifdef THREADS UNLOCK(); # endif return(1); } } new_dl = (struct disappearing_link *) GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); if (0 == new_dl) { # ifdef THREADS UNLOCK(); # endif new_dl = (struct disappearing_link *) GC_oom_fn(sizeof(struct disappearing_link)); if (0 == new_dl) { GC_finalization_failures++; return(2); } /* It's not likely we'll make it here, but ... */ # ifdef THREADS LOCK(); # endif } new_dl -> dl_hidden_obj = HIDE_POINTER(obj); new_dl -> dl_hidden_link = HIDE_POINTER(link); dl_set_next(new_dl, dl_head[index]); dl_head[index] = new_dl; GC_dl_entries++; # ifdef THREADS UNLOCK(); # endif return(0); }
void devline(char *line) { char *w; struct conf_dev *cd; for (w=dl_next(line); w != line; w=dl_next(w)) { if (w[0] == '/' || strcasecmp(w, "partitions") == 0) { cd = malloc(sizeof(*cd)); cd->name = strdup(w); cd->next = cdevlist; cdevlist = cd; } else { fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n", w); } } }
void devline(char *line) { char *w; struct conf_dev *cd; for (w=dl_next(line); w != line; w=dl_next(w)) { if (w[0] == '/' || strcasecmp(w, "partitions") == 0 || strcasecmp(w, "containers") == 0) { cd = xmalloc(sizeof(*cd)); cd->name = xstrdup(w); cd->next = cdevlist; cdevlist = cd; } else { pr_err("unreconised word on DEVICE line: %s\n", w); } } }
static xsbBool remove_dl_from_dl_list(DL dl, ASI asi) { DL current = asi_dl_list(asi); DL prev_dl = NULL; #ifdef DEBUG_DELAYVAR fprintf(stddbg, ">>>> start remove_dl_from_dl_list()\n"); #endif while (current != dl) { prev_dl = current; current = dl_next(current); } if (prev_dl == NULL) /* to remove the first DL */ asi_dl_list(asi) = dl_next(current); else dl_next(prev_dl) = dl_next(current); release_entry(current, released_dls, dl_next); return (NULL != asi_dl_list(asi)); }
static int released_dl_num(void) { int i = 0; DL p; p = released_dls; while (p != NULL) { i++; p = dl_next(p); } return(i); }
/* Assume the lock is held. */ GC_INLINE struct disappearing_link *GC_unregister_disappearing_link_inner( struct dl_hashtbl_s *dl_hashtbl, void **link) { struct disappearing_link *curr_dl; struct disappearing_link *prev_dl = NULL; size_t index = HASH2(link, dl_hashtbl->log_size); for (curr_dl = dl_hashtbl -> head[index]; curr_dl; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { /* Remove found entry from the table. */ if (NULL == prev_dl) { dl_hashtbl -> head[index] = dl_next(curr_dl); } else { dl_set_next(prev_dl, dl_next(curr_dl)); } dl_hashtbl -> entries--; break; } prev_dl = curr_dl; } return curr_dl; }
static void pol_merge_part(struct dev_policy **pol, struct rule *rule, char *part) { /* copy any name assignments from rule into pol, appending * -part to any domain. The string with -part appended is * stored with the rule so it has a lifetime to match * the rule. */ struct rule *r; char *metadata = NULL; for (r = rule; r ; r = r->next) if (r->name == pol_metadata) metadata = r->value; for (r = rule; r ; r = r->next) { if (r->name == pol_act) pol_new(pol, r->name, r->value, metadata); else if (r->name == pol_domain) { char *dom; int len; if (r->dups == NULL) r->dups = dl_head(); len = strlen(r->value); for (dom = dl_next(r->dups); dom != r->dups; dom = dl_next(dom)) if (strcmp(dom+len+1, part)== 0) break; if (dom == r->dups) { char *newdom = dl_strndup( r->value, len + 1 + strlen(part)); strcat(strcat(newdom, "-"), part); dl_add(r->dups, newdom); dom = newdom; } pol_new(pol, r->name, dom, metadata); } } }
STATIC void GC_dump_finalization_links(struct dl_hashtbl_s* dl_hashtbl) { struct disappearing_link * curr_dl; ptr_t real_ptr, real_link; size_t dl_size = dl_hashtbl -> log_size == -1 ? 0 : 1 << dl_hashtbl -> log_size; size_t i; for (i = 0; i < dl_size; i++) { for (curr_dl = dl_hashtbl -> head[i]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { real_ptr = GC_REVEAL_POINTER(curr_dl -> dl_hidden_obj); real_link = GC_REVEAL_POINTER(curr_dl -> dl_hidden_link); GC_printf("Object: %p, Link:%p\n", real_ptr, real_link); } } }
int ReleaseCache(INT h) { LPCACHE_NODE pNode = GNull; LPCACHE_NODE pFree = GNull; LPCACHE_HANDLE handle = (LPCACHE_HANDLE)h; LPDL_NODE node; int ret = 0; if (handle == GNull) { return -1; } node = dl_first(&(handle->mDLRoot)); while (node) { container_of(pNode, node, CACHE_NODE, mDLNode); node = dl_next(node); cache_data_release(&(pNode->mData)); GMemFree(pNode); } GMemFree(handle); return ret; }
/* and invoke finalizers. */ void GC_finalize(void) { struct disappearing_link * curr_dl, * prev_dl, * next_dl; struct finalizable_object * curr_fo, * prev_fo, * next_fo; ptr_t real_ptr, real_link; size_t i; size_t dl_size = (log_dl_table_size == -1 ) ? 0 : (1 << log_dl_table_size); size_t fo_size = (log_fo_table_size == -1 ) ? 0 : (1 << log_fo_table_size); /* Make disappearing links disappear */ for (i = 0; i < dl_size; i++) { curr_dl = dl_head[i]; prev_dl = 0; while (curr_dl != 0) { real_ptr = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_obj); real_link = (ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_link); if (!GC_is_marked(real_ptr)) { *(word *)real_link = 0; next_dl = dl_next(curr_dl); if (prev_dl == 0) { dl_head[i] = next_dl; } else { dl_set_next(prev_dl, next_dl); } GC_clear_mark_bit((ptr_t)curr_dl); GC_dl_entries--; curr_dl = next_dl; } else { prev_dl = curr_dl; curr_dl = dl_next(curr_dl); } } } /* Mark all objects reachable via chains of 1 or more pointers */ /* from finalizable objects. */ GC_ASSERT(GC_mark_state == MS_NONE); for (i = 0; i < fo_size; i++) { for (curr_fo = fo_head[i]; curr_fo != 0; curr_fo = fo_next(curr_fo)) { GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object)); real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); if (!GC_is_marked(real_ptr)) { GC_MARKED_FOR_FINALIZATION(real_ptr); GC_MARK_FO(real_ptr, curr_fo -> fo_mark_proc); if (GC_is_marked(real_ptr)) { WARN("Finalization cycle involving %lx\n", real_ptr); } } } } /* Enqueue for finalization all objects that are still */ /* unreachable. */ GC_bytes_finalized = 0; for (i = 0; i < fo_size; i++) { curr_fo = fo_head[i]; prev_fo = 0; while (curr_fo != 0) { real_ptr = (ptr_t)REVEAL_POINTER(curr_fo -> fo_hidden_base); if (!GC_is_marked(real_ptr)) { if (!GC_java_finalization) { GC_set_mark_bit(real_ptr); } /* Delete from hash table */ next_fo = fo_next(curr_fo); if (prev_fo == 0) { fo_head[i] = next_fo; } else { fo_set_next(prev_fo, next_fo); } GC_fo_entries--; /* Add to list of objects awaiting finalization. */ fo_set_next(curr_fo, GC_finalize_now); GC_finalize_now = curr_fo; /* unhide object pointer so any future collections will */ /* see it. */ curr_fo -> fo_hidden_base = (word) REVEAL_POINTER(curr_fo -> fo_hidden_base); GC_bytes_finalized += curr_fo -> fo_object_size + sizeof(struct finalizable_object); GC_ASSERT(GC_is_marked(GC_base((ptr_t)curr_fo))); curr_fo = next_fo; } else { prev_fo = curr_fo; curr_fo = fo_next(curr_fo); } } } if (GC_java_finalization) { /* make sure we mark everything reachable from objects finalized using the no_order mark_proc */ for (curr_fo = GC_finalize_now; curr_fo != NULL; curr_fo = fo_next(curr_fo)) { real_ptr = (ptr_t)curr_fo -> fo_hidden_base; if (!GC_is_marked(real_ptr)) { if (curr_fo -> fo_mark_proc == GC_null_finalize_mark_proc) { GC_MARK_FO(real_ptr, GC_normal_finalize_mark_proc); } if (curr_fo -> fo_mark_proc != GC_unreachable_finalize_mark_proc) { GC_set_mark_bit(real_ptr); } } } /* now revive finalize-when-unreachable objects reachable from other finalizable objects */ if (need_unreachable_finalization) { curr_fo = GC_finalize_now; prev_fo = 0; while (curr_fo != 0) { next_fo = fo_next(curr_fo); if (curr_fo -> fo_mark_proc == GC_unreachable_finalize_mark_proc) { real_ptr = (ptr_t)curr_fo -> fo_hidden_base; if (!GC_is_marked(real_ptr)) { GC_set_mark_bit(real_ptr); } else { if (prev_fo == 0) GC_finalize_now = next_fo; else fo_set_next(prev_fo, next_fo); curr_fo -> fo_hidden_base = (word) HIDE_POINTER(curr_fo -> fo_hidden_base); GC_bytes_finalized -= curr_fo -> fo_object_size + sizeof(struct finalizable_object); i = HASH2(real_ptr, log_fo_table_size); fo_set_next (curr_fo, fo_head[i]); GC_fo_entries++; fo_head[i] = curr_fo; curr_fo = prev_fo; } } prev_fo = curr_fo; curr_fo = next_fo; } } } /* Remove dangling disappearing links. */ for (i = 0; i < dl_size; i++) { curr_dl = dl_head[i]; prev_dl = 0; while (curr_dl != 0) { real_link = GC_base((ptr_t)REVEAL_POINTER(curr_dl -> dl_hidden_link)); if (real_link != 0 && !GC_is_marked(real_link)) { next_dl = dl_next(curr_dl); if (prev_dl == 0) { dl_head[i] = next_dl; } else { dl_set_next(prev_dl, next_dl); } GC_clear_mark_bit((ptr_t)curr_dl); GC_dl_entries--; curr_dl = next_dl; } else { prev_dl = curr_dl; curr_dl = dl_next(curr_dl); } } } }
void autoline(char *line) { char *w; char *seen; int super_cnt; char *dflt = auto_yes; int homehost = 0; int i; if (auto_seen) return; auto_seen = 1; /* Parse the 'auto' line creating policy statements for the 'auto' policy. * * The default is 'yes' but the 'auto' line might over-ride that. * Words in the line are processed in order with the first * match winning. * word can be: * +version - that version can be assembled * -version - that version cannot be auto-assembled * yes or +all - any other version can be assembled * no or -all - no other version can be assembled. * homehost - any array associated by 'homehost' to this * host can be assembled. * * Thus: * +ddf -0.90 homehost -all * will auto-assemble any ddf array, no 0.90 array, and * any other array (imsm, 1.x) if and only if it is identified * as belonging to this host. * * We translate that to policy by creating 'auto=yes' when we see * a '+version' line, 'auto=no' if we see '-version' before 'homehost', * or 'auto=homehost' if we see '-version' after 'homehost'. * When we see yes, no, +all or -all we stop and any version that hasn't * been seen gets an appropriate auto= entry. */ /* If environment variable MDADM_CONF_AUTO is defined, then * it is prepended to the auto line. This allow a script * to easily disable some metadata types. */ w = getenv("MDADM_CONF_AUTO"); if (w && *w) { char *l = xstrdup(w); char *head = line; w = strtok(l, " \t"); while (w) { char *nw = dl_strdup(w); dl_insert(head, nw); head = nw; w = strtok(NULL, " \t"); } free(l); } for (super_cnt = 0; superlist[super_cnt]; super_cnt++) ; seen = xcalloc(super_cnt, 1); for (w = dl_next(line); w != line ; w = dl_next(w)) { char *val; if (strcasecmp(w, "yes") == 0) { dflt = auto_yes; break; } if (strcasecmp(w, "no") == 0) { if (homehost) dflt = auto_homehost; else dflt = auto_no; break; } if (strcasecmp(w, "homehost") == 0) { homehost = 1; continue; } if (w[0] == '+') val = auto_yes; else if (w[0] == '-') { if (homehost) val = auto_homehost; else val = auto_no; } else continue; if (strcasecmp(w+1, "all") == 0) { dflt = val; break; } for (i = 0; superlist[i]; i++) { const char *version = superlist[i]->name; if (strcasecmp(w+1, version) == 0) break; /* 1 matches 1.x, 0 matches 0.90 */ if (version[1] == '.' && strlen(w+1) == 1 && w[1] == version[0]) break; /* 1.anything matches 1.x */ if (strcmp(version, "1.x") == 0 && strncmp(w+1, "1.", 2) == 0) break; } if (superlist[i] == NULL) /* ignore this word */ continue; if (seen[i]) /* already know about this metadata */ continue; policy_add(rule_policy, pol_auto, val, pol_metadata, superlist[i]->name, NULL); seen[i] = 1; } for (i = 0; i < super_cnt; i++) if (!seen[i]) policy_add(rule_policy, pol_auto, dflt, pol_metadata, superlist[i]->name, NULL); free(seen); }
void arrayline(char *line) { char *w; struct mddev_ident mis; struct mddev_ident *mi; mis.uuid_set = 0; mis.super_minor = UnSet; mis.level = UnSet; mis.raid_disks = UnSet; mis.spare_disks = 0; mis.devices = NULL; mis.devname = NULL; mis.spare_group = NULL; mis.autof = 0; mis.next = NULL; mis.st = NULL; mis.bitmap_fd = -1; mis.bitmap_file = NULL; mis.name[0] = 0; mis.container = NULL; mis.member = NULL; for (w=dl_next(line); w!=line; w=dl_next(w)) { if (w[0] == '/' || strchr(w, '=') == NULL) { /* This names the device, or is '<ignore>'. * The rules match those in create_mddev. * 'w' must be: * /dev/md/{anything} * /dev/mdNN * /dev/md_dNN * <ignore> * or anything that doesn't start '/' or '<' */ if (strcasecmp(w, "<ignore>") == 0 || strncmp(w, "/dev/md/", 8) == 0 || (w[0] != '/' && w[0] != '<') || (strncmp(w, "/dev/md", 7) == 0 && is_number(w+7)) || (strncmp(w, "/dev/md_d", 9) == 0 && is_number(w+9)) ) { /* This is acceptable */; if (mis.devname) pr_err("only give one " "device per ARRAY line: %s and %s\n", mis.devname, w); else mis.devname = w; }else { pr_err("%s is an invalid name for " "an md device - ignored.\n", w); } } else if (strncasecmp(w, "uuid=", 5)==0 ) { if (mis.uuid_set) pr_err("only specify uuid once, %s ignored.\n", w); else { if (parse_uuid(w+5, mis.uuid)) mis.uuid_set = 1; else pr_err("bad uuid: %s\n", w); } } else if (strncasecmp(w, "super-minor=", 12)==0 ) { if (mis.super_minor != UnSet) pr_err("only specify super-minor once, %s ignored.\n", w); else { char *endptr; int minor = strtol(w+12, &endptr, 10); if (w[12]==0 || endptr[0]!=0 || minor < 0) pr_err("invalid super-minor number: %s\n", w); else mis.super_minor = minor; } } else if (strncasecmp(w, "name=", 5)==0) { if (mis.name[0]) pr_err("only specify name once, %s ignored.\n", w); else if (strlen(w+5) > 32) pr_err("name too long, ignoring %s\n", w); else strcpy(mis.name, w+5); } else if (strncasecmp(w, "bitmap=", 7) == 0) { if (mis.bitmap_file) pr_err("only specify bitmap file once. %s ignored\n", w); else mis.bitmap_file = xstrdup(w+7); } else if (strncasecmp(w, "devices=", 8 ) == 0 ) { if (mis.devices) pr_err("only specify devices once (use a comma separated list). %s ignored\n", w); else mis.devices = xstrdup(w+8); } else if (strncasecmp(w, "spare-group=", 12) == 0 ) { if (mis.spare_group) pr_err("only specify one spare group per array. %s ignored.\n", w); else mis.spare_group = xstrdup(w+12); } else if (strncasecmp(w, "level=", 6) == 0 ) { /* this is mainly for compatability with --brief output */ mis.level = map_name(pers, w+6); } else if (strncasecmp(w, "disks=", 6) == 0 ) { /* again, for compat */ mis.raid_disks = atoi(w+6); } else if (strncasecmp(w, "num-devices=", 12) == 0 ) { /* again, for compat */ mis.raid_disks = atoi(w+12); } else if (strncasecmp(w, "spares=", 7) == 0 ) { /* for warning if not all spares present */ mis.spare_disks = atoi(w+7); } else if (strncasecmp(w, "metadata=", 9) == 0) { /* style of metadata on the devices. */ int i; for(i=0; superlist[i] && !mis.st; i++) mis.st = superlist[i]->match_metadata_desc(w+9); if (!mis.st) pr_err("metadata format %s unknown, ignored.\n", w+9); } else if (strncasecmp(w, "auto=", 5) == 0 ) { /* whether to create device special files as needed */ mis.autof = parse_auto(w+5, "auto type", 0); } else if (strncasecmp(w, "member=", 7) == 0) { /* subarray within a container */ mis.member = xstrdup(w+7); } else if (strncasecmp(w, "container=", 10) == 0) { /* the container holding this subarray. Either a device name * or a uuid */ mis.container = xstrdup(w+10); } else { pr_err("unrecognised word on ARRAY line: %s\n", w); } } if (mis.uuid_set == 0 && mis.devices == NULL && mis.super_minor == UnSet && mis.name[0] == 0 && (mis.container == NULL || mis.member == NULL)) pr_err("ARRAY line %s has no identity information.\n", mis.devname); else { mi = xmalloc(sizeof(*mi)); *mi = mis; mi->devname = mis.devname ? xstrdup(mis.devname) : NULL; mi->next = NULL; *mddevlp = mi; mddevlp = &mi->next; } }
int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust, struct supertype *forcest) { /* Read the raid superblock from a device and * display important content. * * If cannot be found, print reason: too small, bad magic * * Print: * version, ctime, level, size, raid+spare+ * prefered minor * uuid * * utime, state etc * * If (brief) gather devices for same array and just print a mdadm.conf line including devices= * if devlist==NULL, use conf_get_devs() */ int fd; void *super = NULL; int rv = 0; int err = 0; struct array { void *super; struct supertype *st; struct mdinfo info; struct mddev_ident_s ident; void *devs; struct array *next; int spares; } *arrays = NULL; for (; devlist ; devlist=devlist->next) { struct supertype *st = forcest; fd = dev_open(devlist->devname, O_RDONLY); if (fd < 0) { if (!scan) fprintf(stderr,Name ": cannot open %s: %s\n", devlist->devname, strerror(errno)); err = 1; } else { if (!st) st = guess_super(fd); if (st) err = st->ss->load_super(st, fd, &super, (brief||scan)?NULL:devlist->devname); else { if (!brief) fprintf(stderr, Name ": No md superblock detected on %s.\n", devlist->devname); err = 1; } close(fd); } if (err) { rv = 1; continue; } if (SparcAdjust) st->ss->update_super(NULL, super, "sparc2.2", devlist->devname, 0); /* Ok, its good enough to try, though the checksum could be wrong */ if (brief) { struct array *ap; char *d; for (ap=arrays; ap; ap=ap->next) { if (st->ss == ap->st->ss && st->ss->compare_super(&ap->super, super)==0) break; } if (!ap) { ap = malloc(sizeof(*ap)); ap->super = super; ap->devs = dl_head(); ap->next = arrays; ap->spares = 0; ap->st = st; arrays = ap; st->ss->getinfo_super(&ap->info, &ap->ident, super); } else { st->ss->getinfo_super(&ap->info, &ap->ident, super); free(super); } if (!(ap->info.disk.state & MD_DISK_SYNC)) ap->spares++; d = dl_strdup(devlist->devname); dl_add(ap->devs, d); } else { printf("%s:\n",devlist->devname); st->ss->examine_super(super); free(super); } } if (brief) { struct array *ap; for (ap=arrays; ap; ap=ap->next) { char sep='='; char *d; ap->st->ss->brief_examine_super(ap->super); if (ap->spares) printf(" spares=%d", ap->spares); if (brief > 1) { printf(" devices"); for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) { printf("%c%s", sep, d); sep=','; } } free(ap->super); /* FIXME free ap */ if (ap->spares || brief > 1) printf("\n"); } } return rv; }
void arrayline(char *line) { char *w; struct mddev_ident_s mis; mddev_ident_t mi; mis.uuid_set = 0; mis.super_minor = UnSet; mis.level = UnSet; mis.raid_disks = UnSet; mis.spare_disks = UnSet; mis.devices = NULL; mis.devname = NULL; mis.spare_group = NULL; mis.autof = 0; mis.next = NULL; mis.st = NULL; mis.bitmap_fd = -1; mis.name[0] = 0; for (w=dl_next(line); w!=line; w=dl_next(w)) { if (w[0] == '/') { if (mis.devname) fprintf(stderr, Name ": only give one device per ARRAY line: %s and %s\n", mis.devname, w); else mis.devname = w; } else if (strncasecmp(w, "uuid=", 5)==0 ) { if (mis.uuid_set) fprintf(stderr, Name ": only specify uuid once, %s ignored.\n", w); else { if (parse_uuid(w+5, mis.uuid)) mis.uuid_set = 1; else fprintf(stderr, Name ": bad uuid: %s\n", w); } } else if (strncasecmp(w, "super-minor=", 12)==0 ) { if (mis.super_minor != UnSet) fprintf(stderr, Name ": only specify super-minor once, %s ignored.\n", w); else { char *endptr; mis.super_minor= strtol(w+12, &endptr, 10); if (w[12]==0 || endptr[0]!=0 || mis.super_minor < 0) { fprintf(stderr, Name ": invalid super-minor number: %s\n", w); mis.super_minor = UnSet; } } } else if (strncasecmp(w, "name=", 5)==0) { if (mis.name[0]) fprintf(stderr, Name ": only specify name once, %s ignored.\n", w); else if (strlen(w+5) > 32) fprintf(stderr, Name ": name too long, ignoring %s\n", w); else strcpy(mis.name, w+5); } else if (strncasecmp(w, "devices=", 8 ) == 0 ) { if (mis.devices) fprintf(stderr, Name ": only specify devices once (use a comma separated list). %s ignored\n", w); else mis.devices = strdup(w+8); } else if (strncasecmp(w, "spare-group=", 12) == 0 ) { if (mis.spare_group) fprintf(stderr, Name ": only specify one spare group per array. %s ignored.\n", w); else mis.spare_group = strdup(w+12); } else if (strncasecmp(w, "level=", 6) == 0 ) { /* this is mainly for compatability with --brief output */ mis.level = map_name(pers, w+6); } else if (strncasecmp(w, "disks=", 6) == 0 ) { /* again, for compat */ mis.raid_disks = atoi(w+6); } else if (strncasecmp(w, "num-devices=", 12) == 0 ) { /* again, for compat */ mis.raid_disks = atoi(w+12); } else if (strncasecmp(w, "spares=", 7) == 0 ) { /* for warning if not all spares present */ mis.spare_disks = atoi(w+7); } else if (strncasecmp(w, "metadata=", 9) == 0) { /* style of metadata on the devices. */ int i; for(i=0; superlist[i] && !mis.st; i++) mis.st = superlist[i]->match_metadata_desc(w+9); if (!mis.st) fprintf(stderr, Name ": metadata format %s unknown, ignored.\n", w+9); } else if (strncasecmp(w, "auto=", 5) == 0 ) { /* whether to create device special files as needed */ if (strcasecmp(w+5, "no")==0) mis.autof = 0; else if (strcasecmp(w+5,"yes")==0 || strcasecmp(w+5,"md")==0) mis.autof = -1; else { /* There might be digits, and maybe a hyphen, at the end */ char *e = w+5 + strlen(w+5); int num = 4; int len; while (e > w+5 && isdigit(e[-1])) e--; if (*e) { num = atoi(e); if (num <= 0) num = 1; } if (e > w+5 && e[-1] == '-') e--; len = e - (w+5); if ((len == 3 && strncasecmp(w+5,"mdp",3)==0) || (len == 1 && strncasecmp(w+5,"p",1)==0) || (len >= 4 && strncasecmp(w+5,"part",4)==0)) mis.autof = num; else fprintf(stderr, Name ": auto type of \"%s\" ignored for %s\n", w+5, mis.devname?mis.devname:"unlabeled-array"); } } else { fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n", w); } } if (mis.devname == NULL) fprintf(stderr, Name ": ARRAY line with no device\n"); else if (mis.uuid_set == 0 && mis.devices == NULL && mis.super_minor == UnSet && mis.name[0] == 0) fprintf(stderr, Name ": ARRAY line %s has no identity information.\n", mis.devname); else { mi = malloc(sizeof(*mi)); *mi = mis; mi->devname = strdup(mis.devname); mi->next = NULL; *mddevlp = mi; mddevlp = &mi->next; } }
STATIC int GC_register_disappearing_link_inner( struct dl_hashtbl_s *dl_hashtbl, void **link, const void *obj, const char *tbl_log_name) { struct disappearing_link *curr_dl; size_t index; struct disappearing_link * new_dl; DCL_LOCK_STATE; LOCK(); GC_ASSERT(obj != NULL && GC_base_C(obj) == obj); if (dl_hashtbl -> log_size == -1 || dl_hashtbl -> entries > ((word)1 << dl_hashtbl -> log_size)) { GC_grow_table((struct hash_chain_entry ***)&dl_hashtbl -> head, &dl_hashtbl -> log_size); GC_COND_LOG_PRINTF("Grew %s table to %u entries\n", tbl_log_name, 1 << (unsigned)dl_hashtbl -> log_size); } index = HASH2(link, dl_hashtbl -> log_size); for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); UNLOCK(); return GC_DUPLICATE; } } new_dl = (struct disappearing_link *) GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); if (0 == new_dl) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); new_dl = (struct disappearing_link *) (*oom_fn)(sizeof(struct disappearing_link)); if (0 == new_dl) { return GC_NO_MEMORY; } /* It's not likely we'll make it here, but ... */ LOCK(); /* Recalculate index since the table may grow. */ index = HASH2(link, dl_hashtbl -> log_size); /* Check again that our disappearing link not in the table. */ for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); UNLOCK(); # ifndef DBG_HDRS_ALL /* Free unused new_dl returned by GC_oom_fn() */ GC_free((void *)new_dl); # endif return GC_DUPLICATE; } } } new_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); new_dl -> dl_hidden_link = GC_HIDE_POINTER(link); dl_set_next(new_dl, dl_hashtbl -> head[index]); dl_hashtbl -> head[index] = new_dl; dl_hashtbl -> entries++; UNLOCK(); return GC_SUCCESS; }