int parse_options(char *orig_options, int *flagp) { char *options = NULL; char *nextopt = NULL; char *opt = NULL; int ret = 0; options = calloc(strlen(orig_options) + 1, 1); if (options == NULL) { ret = ENOMEM; goto out; } *flagp = 0; nextopt = orig_options; while ((opt = strsep(&nextopt, ","))) { if (!*opt) { /* empty option */ continue; } if (strncmp(opt, "force", 5) == 0) { ++force; printf("force: %d\n", force); } else if (parse_one_option(opt, flagp) == 0) { /* pass this on as an option */ append_option(options, opt); } } strcpy(orig_options, options); free(options); out: return ret; }
static int mod_insert ( char *mod, int argc, char **argv ) { struct mod_list_t *tail = 0; struct mod_list_t *head = 0; int rc; // get dep list for module mod check_dep ( mod, &head, &tail ); if ( head && tail ) { if( argc ) { int i; // append module args for ( i = 0; i < argc; i++ ) head->m_options = append_option( head->m_options, argv[i] ); } // process tail ---> head if ((rc = mod_process ( tail, 1 )) != 0) { /* * In case of using udev, multiple instances of modprobe can be * spawned to load the same module (think of two same usb devices, * for example; or cold-plugging at boot time). Thus we shouldn't * fail if the module was loaded, and not by us. */ if (already_loaded (mod) ) rc = 0; } } else rc = 1; return rc; }
static int need_to_gc(void) { /* * Setting gc.auto to 0 or negative can disable the * automatic gc. */ if (gc_auto_threshold <= 0) return 0; /* * If there are too many loose objects, but not too many * packs, we run "repack -d -l". If there are too many packs, * we run "repack -A -d -l". Otherwise we tell the caller * there is no need. */ if (too_many_packs()) append_option(argv_repack, prune_expire && !strcmp(prune_expire, "now") ? "-a" : "-A", MAX_ADD); else if (!too_many_loose_objects()) return 0; if (run_hook(NULL, "pre-auto-gc", NULL)) return 0; return 1; }
static int mod_insert ( char *mod, int argc, char **argv ) { struct mod_list_t *tail = 0; struct mod_list_t *head = 0; int rc; // get dep list for module mod check_dep ( mod, &head, &tail ); if ( head && tail ) { if( argc ) { int i; // append module args for ( i = 0; i < argc; i++ ) head->m_options = append_option( head->m_options, argv[i] ); } // process tail ---> head rc = mod_process ( tail, 1 ); } else rc = 1; return rc; }
static int append_text(pmOptions *opts, char *buffer, size_t length) { pmLongOptions text = PMAPI_OPTIONS_TEXT(""); if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: append: '%s'\n", pmProgname, buffer); if ((text.message = strdup(buffer)) == NULL) __pmNoMem("append_text", length, PM_FATAL_ERR); return append_option(opts, &text); }
struct plugin_option *trace_util_read_plugin_options(void) { struct plugin_option_read option = { .options = NULL, }; append_option(&option, trace_ftrace_options, "ftrace", NULL); trace_util_load_plugins(NULL, ".so", read_options, &option); return option.options; }
static int read_options(struct pevent *pevent, const char *path, const char *file, void *data) { struct plugin_option_read *options = data; struct pevent_plugin_option *option; const char *alias; int unload = 0; char *plugin; void *handle; plugin = malloc(strlen(path) + strlen(file) + 2); if (!plugin) return -ENOMEM; strcpy(plugin, path); strcat(plugin, "/"); strcat(plugin, file); handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL); if (!handle) { warning("cound not load plugin '%s'\n%s\n", plugin, dlerror()); goto out_free; } alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME); if (!alias) alias = file; option = dlsym(handle, PEVENT_PLUGIN_OPTIONS_NAME); if (!option) { unload = 1; goto out_unload; } append_option(options, option, alias, handle); out_unload: if (unload) dlclose(handle); out_free: free(plugin); return 0; }
static int standard_options(pmOptions *opts, char *start) { pmLongOptions stock[] = { PMAPI_GENERAL_OPTIONS, PMOPT_SPECLOCAL, PMOPT_LOCALPMDA, PMOPT_HOSTSFILE, PMOPT_HOST_LIST, PMOPT_ARCHIVE_LIST, PMOPT_ARCHIVE_FOLIO, PMAPI_OPTIONS_END }; pmLongOptions *entry; entry = (start[1] == '-') ? search_long_options(stock, start + 2) : search_short_options(stock, (int)start[1]); if (entry) return append_option(opts, entry); fprintf(stderr, "%s: cannot find PCP option \"%s\", line %d ignored\n", pmProgname, start, lineno); return -EINVAL; }
struct parsed_option_list *iterate_short_opts(bfd *binary_bfd, const bfd_vma shortopts) { asection *shortopt_section = find_vma_section(binary_bfd, shortopts); // Prepare a list of options for this call struct parsed_option_list *options_found = NULL; size_t sec_size = bfd_get_section_size(shortopt_section); bfd_byte *section_data = (bfd_byte *) xmalloc (sec_size); bfd_get_section_contents(binary_bfd, shortopt_section, section_data, 0, sec_size); debug("Loading the contents of section %s (%ld bytes)\n", shortopt_section->name, sec_size); size_t shortopt_offset = (shortopts - shortopt_section->vma); info("shortopts live in section %s at offset %ld\n", shortopt_section->name, shortopt_offset); bfd_byte *optstring = §ion_data[shortopt_offset]; info("Short opts %s\n", optstring); unsigned int opt_idx = 0; while (0x0 != optstring[opt_idx]) { char opt_char[2] = {optstring[opt_idx], 0x0}; bool has_arg = false; // Does this option require an argument? if (':' == optstring[opt_idx+1]) { has_arg = false; opt_idx++; } options_found = append_option(options_found, opt_char, has_arg, ONE_DASH); opt_idx++; } free(section_data); return options_found; }
/* Add mgsnids from ldd params */ static int add_mgsnids(struct mount_opts *mop, char *options, const char *params) { char *ptr = (char *)params; char tmp, *sep; while ((ptr = strstr(ptr, PARAM_MGSNODE)) != NULL) { sep = strchr(ptr, ' '); if (sep != NULL) { tmp = *sep; *sep = '\0'; } append_option(options, ptr); mop->mo_have_mgsnid++; if (sep) { *sep = tmp; ptr = sep; } else { break; } } return 0; }
int cmd_gc(int argc, const char **argv, const char *prefix) { int prune = 0; int aggressive = 0; int auto_gc = 0; int quiet = 0; char buf[80]; struct option builtin_gc_options[] = { OPT_BOOLEAN(0, "prune", &prune, "prune unreferenced objects (deprecated)"), OPT_BOOLEAN(0, "aggressive", &aggressive, "be more thorough (increased runtime)"), OPT_BOOLEAN(0, "auto", &auto_gc, "enable auto-gc mode"), OPT_BOOLEAN('q', "quiet", &quiet, "suppress progress reports"), OPT_END() }; git_config(gc_config, NULL); if (pack_refs < 0) pack_refs = !is_bare_repository(); argc = parse_options(argc, argv, builtin_gc_options, builtin_gc_usage, 0); if (argc > 0) usage_with_options(builtin_gc_usage, builtin_gc_options); if (aggressive) { append_option(argv_repack, "-f", MAX_ADD); if (aggressive_window > 0) { sprintf(buf, "--window=%d", aggressive_window); append_option(argv_repack, buf, MAX_ADD); } } if (quiet) append_option(argv_repack, "-q", MAX_ADD); if (auto_gc) { /* * Auto-gc should be least intrusive as possible. */ if (!need_to_gc()) return 0; fprintf(stderr, "Auto packing your repository for optimum " "performance. You may also\n" "run \"git gc\" manually. See " "\"git help gc\" for more information.\n"); } else append_option(argv_repack, "-A", MAX_ADD); if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD)) return error(FAILED_RUN, argv_pack_refs[0]); if (run_command_v_opt(argv_reflog, RUN_GIT_CMD)) return error(FAILED_RUN, argv_reflog[0]); if (run_command_v_opt(argv_repack, RUN_GIT_CMD)) return error(FAILED_RUN, argv_repack[0]); argv_prune[2] = prune_expire; if (run_command_v_opt(argv_prune, RUN_GIT_CMD)) return error(FAILED_RUN, argv_prune[0]); if (run_command_v_opt(argv_rerere, RUN_GIT_CMD)) return error(FAILED_RUN, argv_rerere[0]); if (auto_gc && too_many_loose_objects()) warning("There are too many unreachable loose objects; " "run 'git prune' to remove them."); return 0; }
static int options(pmOptions *opts, char *buffer, size_t length) { char *start, *finish, *token; pmLongOptions option = { 0 }; /* * Two cases to deal with here - a "standard" option e.g. --host * which is presented as a single word (no description) OR a full * description of a command line option, in one of these forms: * * --label dump the archive label * --background=COLOR render background with given color * -d, --desc get and print metric description * -b=N, --batch=N fetch N metrics at a time * -L use a local context connection * -X=N offset resulting values by N units */ if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: parsing option: '%s'", pmProgname, buffer); start = skip_whitespace(skip_nonwhitespace(buffer)); finish = skip_nonwhitespace(start); if (start[0] != '-') { *finish = '\0'; return append_text(opts, buffer, length); } token = skip_whitespace(finish); *finish = '\0'; /* if a single word, this is the standard PCP option case - find it */ if (!token || *token == '\0') return standard_options(opts, start); /* handle the first two example cases above -- long option only */ if (start[1] == '-') { token = seek_character(start, '='); if (*token == '=') { *token = '\0'; /* e.g. --background=COLOR render ... */ token++; finish = skip_nonwhitespace(token); *finish = '\0'; if ((option.argname = strdup(token)) == NULL) __pmNoMem("argname", strlen(token), PM_FATAL_ERR); option.has_arg = 1; } /* else e.g. --label dump the archive label */ if ((option.long_opt = strdup(start + 2)) == NULL) __pmNoMem("longopt", strlen(start), PM_FATAL_ERR); token = skip_whitespace(finish + 1); if ((option.message = strdup(token)) == NULL) __pmNoMem("message", strlen(token), PM_FATAL_ERR); return append_option(opts, &option); } /* handle next two example cases above -- both long and short options */ token = seek_character(start, ','); if (*token == ',') { /* e.g. -b=N, --batch=N fetch N metrics at a time */ option.short_opt = (int)start[1]; /* move onto extracting --batch, [=N], and "fetch..." */ token++; /* move past the comma */ if (*token == '\0' && token - buffer < length) /* move past a null */ token++; token = skip_whitespace(token); if ((token = seek_character(token, '-')) == NULL || (token - buffer >= length) || (token[1] != '-')) { fprintf(stderr, "%s: expected long option at \"%s\", line %d ignored\n", pmProgname, token, lineno); return -EINVAL; } start = token + 2; /* skip double-dash */ if ((token = seek_character(start, '=')) != NULL && *token == '=') { *token++ = '\0'; option.has_arg = 1; /* now extract the argument name */ finish = skip_nonwhitespace(token); *finish = '\0'; if ((option.argname = strdup(token)) == NULL) __pmNoMem("argname", strlen(token), PM_FATAL_ERR); } else { finish = skip_nonwhitespace(start); *finish = '\0'; } if ((option.long_opt = strdup(start)) == NULL) __pmNoMem("longopt", strlen(start), PM_FATAL_ERR); start = skip_whitespace(finish + 1); if ((option.message = strdup(start)) == NULL) __pmNoMem("message", strlen(start), PM_FATAL_ERR); return append_option(opts, &option); } /* handle final two example cases above -- short options only */ if (isspace(start[1])) { fprintf(stderr, "%s: expected short option at \"%s\", line %d ignored\n", pmProgname, start, lineno); return -EINVAL; } option.long_opt = ""; option.short_opt = start[1]; if ((token = seek_character(start, '=')) != NULL && *token == '=') { *token++ = '\0'; option.has_arg = 1; /* now extract the argument name */ finish = skip_nonwhitespace(token); *finish = '\0'; if ((option.argname = strdup(token)) == NULL) __pmNoMem("argname", strlen(token), PM_FATAL_ERR); /* e.g. -X=N offset resulting values by N units */ start = skip_whitespace(finish + 2); } else { /* e.g. -L use a local context connection */ start = skip_whitespace(start + 3); } if ((option.message = strdup(start)) == NULL) __pmNoMem("message", strlen(start), PM_FATAL_ERR); return append_option(opts, &option); }
int cmd_gc(int argc, const char **argv, const char *prefix) { int aggressive = 0; int auto_gc = 0; int quiet = 0; char buf[80]; struct option builtin_gc_options[] = { OPT__QUIET(&quiet, "suppress progress reporting"), { OPTION_STRING, 0, "prune", &prune_expire, "date", "prune unreferenced objects", PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire }, OPT_BOOLEAN(0, "aggressive", &aggressive, "be more thorough (increased runtime)"), OPT_BOOLEAN(0, "auto", &auto_gc, "enable auto-gc mode"), OPT_END() }; if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_gc_usage, builtin_gc_options); git_config(gc_config, NULL); if (pack_refs < 0) pack_refs = !is_bare_repository(); argc = parse_options(argc, argv, prefix, builtin_gc_options, builtin_gc_usage, 0); if (argc > 0) usage_with_options(builtin_gc_usage, builtin_gc_options); if (aggressive) { append_option(argv_repack, "-f", MAX_ADD); append_option(argv_repack, "--depth=250", MAX_ADD); if (aggressive_window > 0) { sprintf(buf, "--window=%d", aggressive_window); append_option(argv_repack, buf, MAX_ADD); } } if (quiet) append_option(argv_repack, "-q", MAX_ADD); if (auto_gc) { /* * Auto-gc should be least intrusive as possible. */ if (!need_to_gc()) return 0; fprintf(stderr, "Auto packing the repository for optimum performance.%s\n", quiet ? "" : (" You may also\n" "run \"git gc\" manually. See " "\"git help gc\" for more information.")); } else append_option(argv_repack, prune_expire && !strcmp(prune_expire, "now") ? "-a" : "-A", MAX_ADD); if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD)) return error(FAILED_RUN, argv_pack_refs[0]); if (run_command_v_opt(argv_reflog, RUN_GIT_CMD)) return error(FAILED_RUN, argv_reflog[0]); if (run_command_v_opt(argv_repack, RUN_GIT_CMD)) return error(FAILED_RUN, argv_repack[0]); if (prune_expire) { argv_prune[2] = prune_expire; if (run_command_v_opt(argv_prune, RUN_GIT_CMD)) return error(FAILED_RUN, argv_prune[0]); } if (run_command_v_opt(argv_rerere, RUN_GIT_CMD)) return error(FAILED_RUN, argv_rerere[0]); if (auto_gc && too_many_loose_objects()) warning("There are too many unreachable loose objects; " "run 'git prune' to remove them."); return 0; }
void parse_args(int argc, char *argv[], address_pool *pool) { int c; opterr = 0; while ((c = getopt (argc, argv, "a:d:o:p:s:")) != -1) switch (c) { case 'a': // parse IP address pool { char *opt = strdup(optarg); char *sfirst = opt; char *slast = strchr(opt, ','); if (slast == NULL) usage("error: comma not present in option -a.", 1); *slast = '\0'; slast++; uint32_t *first, *last; if (parse_ip(sfirst, (void **)&first) != 4) usage("error: invalid first ip in address pool.", 1); if (parse_ip(slast, (void **)&last) != 4) usage("error: invalid last ip in address pool.", 1); pool->indexes.first = *first; pool->indexes.last = *last; pool->indexes.current = *first; free(first); free(last); free(opt); break; } case 'd': // network device to use { strncpy(pool->device, optarg, sizeof(pool->device)); break; } case 'o': // parse dhcp option { uint8_t id; char *opt = strdup(optarg); char *name = opt; char *value = strchr(opt, ','); if (value == NULL) usage("error: comma not present in option -o.", 1); *value = '\0'; value++; dhcp_option *option = calloc(1, sizeof(*option)); if((id = parse_option(option, name, value)) == 0) { char msg[128]; snprintf(msg, sizeof(msg), "error: invalid dhcp option specified: %s,%s", name, value); usage(msg, 1); } append_option(&pool->options, option); if(option->id == IP_ADDRESS_LEASE_TIME) pool->lease_time = ntohl(*((uint32_t *)option->data)); free(option); free(opt); break; } case 'p': // parse pending time { time_t *t; if(parse_long(optarg, (void **)&t) != 4) usage("error: invalid pending time.", 1); pool->pending_time = *t; free(t); break; } case 's': // static binding { char *opt = strdup(optarg); char *shw = opt; char *sip = strchr(opt, ','); if (sip == NULL) usage("error: comma not present in option -s.", 1); *sip = '\0'; sip++; uint32_t *ip; uint8_t *hw; if (parse_mac(shw, (void **)&hw) != 6) usage("error: invalid mac address in static binding.", 1); if (parse_ip(sip, (void **)&ip) != 4) usage("error: invalid ip in static binding.", 1); add_binding(&pool->bindings, *ip, hw, 6, 1); free(ip); free(hw); free(opt); } case '?': usage(NULL, 1); default: usage(NULL, 1); } if(optind >= argc) usage("error: server address not provided.", 1); uint32_t *ip; if (parse_ip(argv[optind], (void **)&ip) != 4) usage("error: invalid server address.", 1); pool->server_id = *ip; free(ip); }
int main(int argc, char *const argv[]) { struct mount_opts mop; char *options; int i, rc, flags; progname = strrchr(argv[0], '/'); progname = progname ? progname + 1 : argv[0]; set_defaults(&mop); rc = osd_init(); if (rc) return rc; rc = parse_opts(argc, argv, &mop); if (rc || version) return rc; if (verbose) { for (i = 0; i < argc; i++) printf("arg[%d] = %s\n", i, argv[i]); printf("source = %s (%s), target = %s\n", mop.mo_usource, mop.mo_source, mop.mo_target); printf("options = %s\n", mop.mo_orig_options); } options = malloc(MAXOPT); if (options == NULL) { fprintf(stderr, "can't allocate memory for options\n"); return -1; } strcpy(options, mop.mo_orig_options); rc = parse_options(&mop, options, &flags); if (rc) { fprintf(stderr, "%s: can't parse options: %s\n", progname, options); return(EINVAL); } if (!mop.mo_force) { rc = check_mtab_entry(mop.mo_usource, mop.mo_source, mop.mo_target, "lustre"); if (rc && !(flags & MS_REMOUNT)) { fprintf(stderr, "%s: according to %s %s is " "already mounted on %s\n", progname, MOUNTED, mop.mo_usource, mop.mo_target); return(EEXIST); } if (!rc && (flags & MS_REMOUNT)) { fprintf(stderr, "%s: according to %s %s is " "not already mounted on %s\n", progname, MOUNTED, mop.mo_usource, mop.mo_target); return(ENOENT); } } if (flags & MS_REMOUNT) mop.mo_nomtab++; rc = access(mop.mo_target, F_OK); if (rc) { rc = errno; fprintf(stderr, "%s: %s inaccessible: %s\n", progname, mop.mo_target, strerror(errno)); return rc; } if (!strstr(mop.mo_usource, ":/")) { rc = parse_ldd(mop.mo_source, &mop, options); if (rc) return rc; } /* In Linux 2.4, the target device doesn't get passed to any of our functions. So we'll stick it on the end of the options. */ append_option(options, "device="); strcat(options, mop.mo_source); if (verbose) printf("mounting device %s at %s, flags=%#x options=%s\n", mop.mo_source, mop.mo_target, flags, options); if (!strstr(mop.mo_usource, ":/") && osd_tune_lustre(mop.mo_source, &mop)) { if (verbose) fprintf(stderr, "%s: unable to set tunables for %s" " (may cause reduced IO performance)\n", argv[0], mop.mo_source); } if (!mop.mo_fake) { /* flags and target get to lustre_get_sb, but not lustre_fill_super. Lustre ignores the flags, but mount does not. */ for (i = 0, rc = -EAGAIN; i <= mop.mo_retry && rc != 0; i++) { rc = mount(mop.mo_source, mop.mo_target, "lustre", flags, (void *)options); if (rc == 0) { /* change label from <fsname>:<index> to * <fsname>-<index> to indicate the device has * been registered. only if the label is * supposed to be changed and target service * is supposed to start */ if (mop.mo_ldd.ldd_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) { if (mop.mo_nosvc == 0) (void)osd_label_lustre(&mop); } } else { if (verbose) { fprintf(stderr, "%s: mount %s at %s " "failed: %s retries left: " "%d\n", basename(progname), mop.mo_usource, mop.mo_target, strerror(errno), mop.mo_retry - i); } if (mop.mo_retry) { sleep(1 << max((i/2), 5)); } else { rc = errno; } } } } if (rc) { char *cli; rc = errno; cli = strrchr(mop.mo_usource, ':'); if (cli && (strlen(cli) > 2)) cli += 2; else cli = NULL; fprintf(stderr, "%s: mount %s at %s failed: %s\n", progname, mop.mo_usource, mop.mo_target, strerror(errno)); if (errno == EBUSY) fprintf(stderr, "Is the backend filesystem mounted?\n" "Check /etc/mtab and /proc/mounts\n"); if (errno == ENODEV) fprintf(stderr, "Are the lustre modules loaded?\n" "Check /etc/modprobe.conf and " "/proc/filesystems\n"); if (errno == ENOTBLK) fprintf(stderr, "Do you need -o loop?\n"); if (errno == ENOMEDIUM) fprintf(stderr, "This filesystem needs at least 1 OST\n"); if (errno == ENOENT) { fprintf(stderr, "Is the MGS specification correct?\n"); fprintf(stderr, "Is the filesystem name correct?\n"); fprintf(stderr, "If upgrading, is the copied client log" " valid? (see upgrade docs)\n"); } if (errno == EALREADY) fprintf(stderr, "The target service is already running." " (%s)\n", mop.mo_usource); if (errno == ENXIO) fprintf(stderr, "The target service failed to start " "(bad config log?) (%s). " "See /var/log/messages.\n", mop.mo_usource); if (errno == EIO) fprintf(stderr, "Is the MGS running?\n"); if (errno == EADDRINUSE) fprintf(stderr, "The target service's index is already " "in use. (%s)\n", mop.mo_usource); if (errno == EINVAL) { fprintf(stderr, "This may have multiple causes.\n"); if (cli) fprintf(stderr, "Is '%s' the correct filesystem" " name?\n", cli); fprintf(stderr, "Are the mount options correct?\n"); fprintf(stderr, "Check the syslog for more info.\n"); } /* May as well try to clean up loop devs */ if (strncmp(mop.mo_usource, "/dev/loop", 9) == 0) { char cmd[256]; int ret; sprintf(cmd, "/sbin/losetup -d %s", mop.mo_usource); if ((ret = system(cmd)) < 0) rc = errno; else if (ret > 0) rc = WEXITSTATUS(ret); } } else if (!mop.mo_nomtab) { rc = update_mtab_entry(mop.mo_usource, mop.mo_target, "lustre", mop.mo_orig_options, 0,0,0); } free(options); /* mo_usource should be freed, but we can rely on the kernel */ free(mop.mo_source); osd_fini(); return rc; }
static int parse_ldd(char *source, struct mount_opts *mop, char *options) { struct lustre_disk_data *ldd = &mop->mo_ldd; char *cur, *start; int rc; rc = osd_is_lustre(source, &ldd->ldd_mount_type); if (rc == 0) { fprintf(stderr, "%s: %s has not been formatted with mkfs.lustre" " or the backend filesystem type is not supported by " "this tool\n", progname, source); return ENODEV; } rc = osd_read_ldd(source, ldd); if (rc) { fprintf(stderr, "%s: %s failed to read permanent mount" " data: %s\n", progname, source, rc >= 0 ? strerror(rc) : ""); return rc; } if ((IS_MDT(ldd) || IS_OST(ldd)) && (ldd->ldd_flags & LDD_F_NEED_INDEX)) { fprintf(stderr, "%s: %s has no index assigned " "(probably formatted with old mkfs)\n", progname, source); return EINVAL; } if (ldd->ldd_flags & LDD_F_UPGRADE14) { fprintf(stderr, "%s: we cannot upgrade %s from this (very old) " "Lustre version\n", progname, source); return EINVAL; } if (ldd->ldd_flags & LDD_F_UPDATE) clear_update_ondisk(source, ldd); /* Since we never rewrite ldd, ignore temp flags */ ldd->ldd_flags &= ~(LDD_F_VIRGIN | LDD_F_WRITECONF); /* svname of the form lustre:OST1234 means never registered */ rc = strlen(ldd->ldd_svname); if (strcmp(ldd->ldd_svname, "MGS") != 0) { if (rc < 8) { fprintf(stderr, "%s: invalid name '%s'\n", progname, ldd->ldd_svname); return EINVAL; } else if (ldd->ldd_svname[rc - 8] == ':') { ldd->ldd_svname[rc - 8] = '-'; ldd->ldd_flags |= LDD_F_VIRGIN; } else if (ldd->ldd_svname[rc - 8] == '=') { ldd->ldd_svname[rc - 8] = '-'; ldd->ldd_flags |= LDD_F_WRITECONF; } } /* backend osd type */ append_option(options, "osd="); strcat(options, mt_type(ldd->ldd_mount_type)); append_option(options, ldd->ldd_mount_opts); if (!mop->mo_have_mgsnid) { /* Only use disk data if mount -o mgsnode=nid wasn't * specified */ if (ldd->ldd_flags & LDD_F_SV_TYPE_MGS) { append_option(options, "mgs"); mop->mo_have_mgsnid++; } else { add_mgsnids(mop, options, ldd->ldd_params); } } /* Better have an mgsnid by now */ if (!mop->mo_have_mgsnid) { fprintf(stderr, "%s: missing option mgsnode=<nid>\n", progname); return EINVAL; } if (ldd->ldd_flags & LDD_F_VIRGIN) append_option(options, "virgin"); if (ldd->ldd_flags & LDD_F_UPDATE) append_option(options, "update"); if (ldd->ldd_flags & LDD_F_WRITECONF) append_option(options, "writeconf"); if (ldd->ldd_flags & LDD_F_NO_PRIMNODE) append_option(options, "noprimnode"); /* prefix every lustre parameter with param= so that in-kernel * mount can recognize them properly and send to MGS at registration */ start = ldd->ldd_params; while (start && *start != '\0') { while (*start == ' ') start++; if (*start == '\0') break; cur = start; start = strchr(cur, ' '); if (start) { *start = '\0'; start++; } append_option(options, "param="); strcat(options, cur); } /* svname must be last option */ append_option(options, "svname="); strcat(options, ldd->ldd_svname); return 0; }
/* Replace options with subset of Lustre-specific options, and fill in mount flags */ int parse_options(struct mount_opts *mop, char *orig_options, int *flagp) { char *options, *opt, *nextopt, *arg, *val; options = calloc(strlen(orig_options) + 1, 1); *flagp = 0; nextopt = orig_options; while ((opt = strsep(&nextopt, ","))) { if (!*opt) /* empty option */ continue; /* Handle retries in a slightly different * manner */ arg = opt; val = strchr(opt, '='); /* please note that some ldiskfs mount options are also in the form * of param=value. We should pay attention not to remove those * mount options, see bug 22097. */ if (val && strncmp(arg, "md_stripe_cache_size", 20) == 0) { mop->mo_md_stripe_cache_size = atoi(val + 1); } else if (val && strncmp(arg, "retry", 5) == 0) { mop->mo_retry = atoi(val + 1); if (mop->mo_retry > MAX_RETRIES) mop->mo_retry = MAX_RETRIES; else if (mop->mo_retry < 0) mop->mo_retry = 0; } else if (val && strncmp(arg, "mgssec", 6) == 0) { append_option(options, opt); } else if (strncmp(arg, "nosvc", 5) == 0) { mop->mo_nosvc = 1; append_option(options, opt); } else if (strcmp(opt, "force") == 0) { /* XXX special check for 'force' option */ ++mop->mo_force; printf("force: %d\n", mop->mo_force); } else if (parse_one_option(opt, flagp) == 0) { /* pass this on as an option */ append_option(options, opt); } } #ifdef MS_STRICTATIME #if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(3, 2, 53, 0) /* * LU-1783 * In the future when upstream fixes land in all supported kernels * we should stop forcing MS_STRICTATIME in lustre mounts. * We override the kernel level default of MS_RELATIME for now * due to a kernel vfs level bug in atime updates that fails * to reset timestamps from the future. */ #warn "remove MS_STRICTATIME override if kernel updates atime from the future" #endif /* set strictatime to default if NOATIME or RELATIME not given explicit */ if (!(*flagp & (MS_NOATIME | MS_RELATIME))) *flagp |= MS_STRICTATIME; #endif strcpy(orig_options, options); free(options); return 0; }
/* * This function reads aliases and default module options from a configuration file * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). */ static void include_conf ( struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd ) { int continuation_line = 0; // alias parsing is not 100% correct (no correct handling of continuation lines within an alias) ! while ( reads ( fd, buffer, buflen)) { int l; char *p; p = strchr ( buffer, '#' ); if ( p ) *p = 0; l = strlen ( buffer ); while ( l && isspace ( buffer [l-1] )) { buffer [l-1] = 0; l--; } if ( l == 0 ) { continuation_line = 0; continue; } if ( !continuation_line ) { if (( strncmp ( buffer, "alias", 5 ) == 0 ) && isspace ( buffer [5] )) { char *alias, *mod; if ( parse_tag_value ( buffer + 6, &alias, &mod )) { /* handle alias as a module dependent on the aliased module */ if ( !*current ) { (*first) = (*current) = (struct dep_t *) xcalloc ( 1, sizeof ( struct dep_t )); } else { (*current)-> m_next = (struct dep_t *) xcalloc ( 1, sizeof ( struct dep_t )); (*current) = (*current)-> m_next; } (*current)-> m_name = bb_xstrdup ( alias ); (*current)-> m_isalias = 1; if (( strcmp ( mod, "off" ) == 0 ) || ( strcmp ( mod, "null" ) == 0 )) { (*current)-> m_depcnt = 0; (*current)-> m_deparr = 0; } else { (*current)-> m_depcnt = 1; (*current)-> m_deparr = xmalloc ( 1 * sizeof( char * )); (*current)-> m_deparr[0] = bb_xstrdup ( mod ); } (*current)-> m_next = 0; } } else if (( strncmp ( buffer, "options", 7 ) == 0 ) && isspace ( buffer [7] )) { char *mod, *opt; /* split the line in the module/alias name, and options */ if ( parse_tag_value ( buffer + 8, &mod, &opt )) { struct dep_t *dt; /* find the corresponding module */ for ( dt = *first; dt; dt = dt-> m_next ) { if ( strcmp ( dt-> m_name, mod ) == 0 ) break; } if ( dt ) { if ( ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS ) { char* new_opt = NULL; while( ( opt = parse_command_string( opt, &new_opt ) ) ) { dt-> m_options = append_option( dt-> m_options, new_opt ); } } else { dt-> m_options = append_option( dt-> m_options, opt ); } } } } else if (( strncmp ( buffer, "include", 7 ) == 0 ) && isspace ( buffer [7] )) { int fdi; char *filename = buffer + 8; while ( isspace ( *filename )) filename++; if (( fdi = open ( filename, O_RDONLY )) >= 0 ) { include_conf(first, current, buffer, buflen, fdi); close(fdi); } } } } }
struct parsed_option_list *iterate_long_opts(bfd *binary_bfd, const bfd_vma longopts) { asection *longopt_section = find_vma_section(binary_bfd, longopts); // Prepare a list of options for this call struct parsed_option_list *options_found = NULL; size_t sec_size = bfd_get_section_size(longopt_section); bfd_byte *section_data = (bfd_byte *) xmalloc (sec_size); bfd_get_section_contents(binary_bfd, longopt_section, section_data, 0, sec_size); debug("Loading the contents of section %s (%ld bytes)\n", longopt_section->name, sec_size); size_t longopt_offset = (longopts - longopt_section->vma); info("longopts live in section %s at offset %ld\n", longopt_section->name, longopt_offset); char *all_zeroes = alloca(sizeof(struct option)); memset(all_zeroes, 0x0, sizeof(struct option)); while (longopt_offset) { /* As per the man page for getopt_long(3), the last element in * the array of struct option elements has to be all zeroes */ if (0==memcmp(§ion_data[longopt_offset], all_zeroes, sizeof(struct option))) break; struct option *long_option = (struct option*) §ion_data[longopt_offset]; if (NULL==long_option->name) break; debug("struct option @ section offset %ld\t loaded into %016" PRIXPTR "\n", longopt_offset, (uintptr_t) long_option); // FIXME We're assuming that pointers hardcoded into the binary can // safely be cast into bfd_vma, which is unsafe // We can't assume member 'name' of the struct option will point to an // area in the same section of the ELF binary as the struct option // itself bfd_byte *option_name_section_data = NULL; asection *option_name_section = find_vma_section(binary_bfd, (bfd_vma) long_option->name); if (!option_name_section) break; debug("option name lives in section %s\n", option_name_section->name); if (option_name_section==longopt_section) { option_name_section_data = section_data; } else { size_t option_name_sec_size = bfd_get_section_size(option_name_section); option_name_section_data = (bfd_byte *) xmalloc (option_name_sec_size); bfd_get_section_contents(binary_bfd, option_name_section, option_name_section_data, 0, option_name_sec_size); } size_t name_offset = ( (bfd_vma)long_option->name - option_name_section->vma); debug("option name @ %016" PRIXPTR ": %s\n", (uintptr_t) long_option->name, &option_name_section_data[name_offset]); options_found = append_option(options_found, (const char*) &option_name_section_data[name_offset], (bool) (1==long_option->has_arg), TWO_DASH); if (option_name_section != longopt_section) free(option_name_section_data); longopt_offset += sizeof(struct option); } debug("Last struct option in array at offset %ld vma %016" PRIXPTR "\n", longopt_offset, longopt_section->vma+longopt_offset); free(section_data); return options_found; }
/* * This function reads aliases and default module options from a configuration file * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). */ static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd) { int continuation_line = 0; // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)! while (reads(fd, buffer, buflen)) { int l; *strchrnul(buffer, '#') = '\0'; l = strlen(buffer); while (l && isspace(buffer[l-1])) { buffer[l-1] = '\0'; l--; } if (l == 0) { continuation_line = 0; continue; } if (continuation_line) continue; if (is_conf_command(buffer, "alias")) { char *alias, *mod; if (parse_tag_value(buffer + 6, &alias, &mod)) { /* handle alias as a module dependent on the aliased module */ if (!*current) { (*first) = (*current) = xzalloc(sizeof(struct dep_t)); } else { (*current)->m_next = xzalloc(sizeof(struct dep_t)); (*current) = (*current)->m_next; } (*current)->m_name = xstrdup(alias); (*current)->m_isalias = 1; if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) { /*(*current)->m_depcnt = 0; - done by xzalloc */ /*(*current)->m_deparr = 0;*/ } else { (*current)->m_depcnt = 1; (*current)->m_deparr = xmalloc(sizeof(char *)); (*current)->m_deparr[0] = xstrdup(mod); } /*(*current)->m_next = NULL; - done by xzalloc */ } } else if (is_conf_command(buffer, "options")) { char *mod, *opt; /* split the line in the module/alias name, and options */ if (parse_tag_value(buffer + 8, &mod, &opt)) { struct dep_t *dt; /* find the corresponding module */ for (dt = *first; dt; dt = dt->m_next) { if (strcmp(dt->m_name, mod) == 0) break; } if (dt) { if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) { char* new_opt = NULL; while ((opt = parse_command_string(opt, &new_opt))) { dt->m_options = append_option(dt->m_options, new_opt); } } else { dt->m_options = append_option(dt->m_options, opt); } } } } else if (is_conf_command(buffer, "include")) { int fdi; char *filename; filename = skip_whitespace(buffer + 8); fdi = open(filename, O_RDONLY); if (fdi >= 0) { include_conf(first, current, buffer, buflen, fdi); close(fdi); } } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && (is_conf_command(buffer, "blacklist"))) { char *mod; struct dep_t *dt; mod = skip_whitespace(buffer + 10); for (dt = *first; dt; dt = dt->m_next) { if (strcmp(dt->m_name, mod) == 0) break; } if (dt) dt->m_isblacklisted = 1; } } /* while (reads(...)) */ }
/* * Builds the dependency list (aka stack) of a module. * head: the highest module in the stack (last to insmod, first to rmmod) * tail: the lowest module in the stack (first to insmod, last to rmmod) */ static void check_dep ( char *mod, struct mod_list_t **head, struct mod_list_t **tail ) { struct mod_list_t *find; struct dep_t *dt; struct mod_opt_t *opt = 0; char *path = 0; /* Search for the given module name amongst all dependency rules. * The module name in a dependency rule can be a shell pattern, * so try to match the given module name against such a pattern. * Of course if the name in the dependency rule is a plain string, * then we consider it a pattern, and matching will still work. */ for ( dt = depend; dt; dt = dt-> m_next ) { if ( fnmatch ( dt-> m_name, mod, 0 ) == 0) { break; } } if( !dt ) { bb_error_msg ("module %s not found.", mod); return; } // resolve alias names while ( dt-> m_isalias ) { if ( dt-> m_depcnt == 1 ) { struct dep_t *adt; for ( adt = depend; adt; adt = adt-> m_next ) { if ( strcmp ( adt-> m_name, dt-> m_deparr [0] ) == 0 ) break; } if ( adt ) { /* This is the module we are aliased to */ struct mod_opt_t *opts = dt-> m_options; /* Option of the alias are appended to the options of the module */ while( opts ) { adt-> m_options = append_option( adt-> m_options, opts-> m_opt_val ); opts = opts-> m_next; } dt = adt; } else { bb_error_msg ("module %s not found.", mod); return; } } else { bb_error_msg ("Bad alias %s", dt-> m_name); return; } } mod = dt-> m_name; path = dt-> m_path; opt = dt-> m_options; // search for duplicates for ( find = *head; find; find = find-> m_next ) { if ( !strcmp ( mod, find-> m_name )) { // found -> dequeue it if ( find-> m_prev ) find-> m_prev-> m_next = find-> m_next; else *head = find-> m_next; if ( find-> m_next ) find-> m_next-> m_prev = find-> m_prev; else *tail = find-> m_prev; break; // there can be only one duplicate } } if ( !find ) { // did not find a duplicate find = (struct mod_list_t *) xmalloc ( sizeof(struct mod_list_t)); find-> m_name = mod; find-> m_path = path; find-> m_options = opt; } // enqueue at tail if ( *tail ) (*tail)-> m_next = find; find-> m_prev = *tail; find-> m_next = 0; if ( !*head ) *head = find; *tail = find; if ( dt ) { int i; /* Add all dependable module for that new module */ for ( i = 0; i < dt-> m_depcnt; i++ ) check_dep ( dt-> m_deparr [i], head, tail ); } }