static int init_entries( mdsetname_t **spp, md_tab_t *tabp, mdcmdopts_t options, uint_t flags, bool_t called_thru_rpc, md_error_t *ep ) { uint_t cnt = 0; uint_t line; int rval = 0; int ret; /* for all matching entries, which haven't already been done */ for (line = 0; (line < tabp->nlines); ++line) { md_tab_line_t *linep = &tabp->lines[line]; char *uname = linep->argv[0]; /* see if already done */ if (linep->flags != DO_AGAIN) continue; /* clear the metadev/hsp caches between inits */ metaflushmetanames(); /* try it */ if ((called_thru_rpc == FALSE) && meta_is_mn_name(spp, uname, ep)) { /* * MN set, send command to all nodes * Note that is sp is NULL, meta_is_mn_name() derives * sp from linep->argv which is the metadevice arg */ ret = mn_send_command(spp, linep->argc, linep->argv, options, flags, linep->context, ep); } else { char *cname = NULL; cname = meta_name_getname(spp, uname, META_DEVICE, ep); if (cname == NULL) { mde_perror(ep, ""); mdclrerror(ep); } else { ret = meta_init_name(spp, linep->argc, linep->argv, cname, options, ep); Free(cname); if (ret != 0) { if (!(flags & MD_IGNORE_STDERR)) { mderrorextra(ep, linep->context); mde_perror(ep, ""); rval = -1; } mdclrerror(ep); } } } if (ret == 0) { linep->flags = IS_DONE; ++cnt; } } /* return success */ if (rval != 0) return (rval); return (cnt); }
/* * initialize named device or hotspare pool */ static int init_name( mdsetname_t **spp, int argc, char *argv[], mdcmdopts_t options, int called_thru_rpc, md_error_t *ep ) { md_tab_t *tabp = NULL; md_tab_line_t *linep = NULL; int rval = -1; int ret; char *uname = argv[0]; /* look in md.tab */ if (argc == 1) { /* get md.tab entries */ if ((tabp = meta_tab_parse(NULL, ep)) == NULL) { if (! mdissyserror(ep, ENOENT)) return (-1); } /* look in md.tab */ if ((linep = meta_tab_find(*spp, tabp, uname, TAB_MD_HSP)) != NULL) { argc = linep->argc; argv = linep->argv; } } if ((called_thru_rpc == FALSE) && meta_is_mn_name(spp, uname, ep)) { /* * MN set, send command to all nodes */ ret = mn_send_command(spp, argc, argv, options, MD_DISP_STDERR, NO_CONTEXT_STRING, ep); } else { char *cname = NULL; cname = meta_name_getname(spp, uname, META_DEVICE, ep); if (cname == NULL) { goto out; } /* check for ownership */ if (meta_check_ownership(*spp, ep) != 0) { Free(cname); goto out; } ret = meta_init_name(spp, argc, argv, cname, options, ep); Free(cname); } if (ret != 0) { if (linep != NULL) mderrorextra(ep, linep->context); goto out; } rval = 0; /* success */ /* cleanup, return error */ out: if (tabp != NULL) meta_tab_free(tabp); return (rval); }
/* * mainline. crack command line arguments. */ int main( int argc, char *argv[] ) { char *sname = MD_LOCAL_NAME; mdsetname_t *sp = NULL; int aflag = 0; int pflag = 0; int set_flag = 0; mdcmdopts_t options = (MDCMD_PRINT|MDCMD_DOIT); int c; md_error_t status = mdnullerror; md_error_t *ep = &status; int eval = 1; int error; bool_t called_thru_rpc = FALSE; char *cp; int mnset = FALSE; /* * Get the locale set up before calling any other routines * with messages to ouput. Just in case we're not in a build * environment, make sure that TEXT_DOMAIN gets set to * something. */ #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); if ((cp = strstr(argv[0], ".rpc_call")) == NULL) { if (sdssc_bind_library() == SDSSC_OKAY) if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY, &error) == SDSSC_PROXY_DONE) exit(error); } else { *cp = '\0'; /* cut off ".rpc_call" */ called_thru_rpc = TRUE; } /* initialize */ if (md_init(argc, argv, 0, 1, ep) != 0 || meta_check_root(ep) != 0) goto errout; /* parse args */ optind = 1; opterr = 1; while ((c = getopt(argc, argv, "hs:afrp?")) != -1) { switch (c) { case 'h': usage(sp, 0); break; case 's': sname = optarg; set_flag++; break; case 'a': ++aflag; options |= MDCMD_FORCE; break; case 'f': options |= MDCMD_FORCE; break; case 'r': options |= MDCMD_RECURSE | MDCMD_FORCE; break; case 'p': ++pflag; break; case '?': if (optopt == '?') usage(sp, 0); /*FALLTHROUGH*/ default: usage(sp, 1); break; } } argc -= optind; argv += optind; /* with mn sets if -a, set name must have been specified by -s */ if (called_thru_rpc && aflag && !set_flag) { md_eprintf(gettext( "-a parameter requires the use of -s in multi-node sets")); md_exit(sp, 1); } /* get set context */ if ((sp = metasetname(sname, ep)) == NULL) { mde_perror(ep, ""); md_exit(sp, 1); } if (called_thru_rpc) { /* Check if the device is open on all nodes */ options |= MDCMD_MN_OPEN_CHECK; } if (aflag) { /* clear all devices */ if (argc != 0) usage(sp, 1); /* * If a MN set, we will generate a series of individual * metaclear commands which will each grab the set lock. * Therefore do not grab the set lock now. */ if (!meta_is_mn_set(sp, ep)) { /* grab set lock */ if (meta_lock(sp, TRUE, ep)) goto errout; /* check for ownership */ if (meta_check_ownership(sp, ep) != 0) goto errout; } else { mnset = TRUE; } /* reset all devices in set */ if (meta_reset_all(sp, options, ep) != 0) { if (!mnset) mde_perror(ep, ""); } else eval = 0; } else { /* * We are dealing with either a single or multiple names. * The set for the command is either denoted by the -s option * or the set of the first name. */ if (argc <= 0) usage(sp, 1); if (meta_is_mn_name(&sp, argv[0], ep)) mnset = TRUE; eval = 0; for (; (argc > 0); --argc, ++argv) { char *cname; /* * If we are dealing with a MN set and we were not * called thru an rpc call, we are just to send this * command string to the master of the set and let it * deal with it. */ if (!called_thru_rpc && mnset) { /* get the canonical name */ if (pflag) { /* * If -p, set cname to the device * argument. */ cname = Strdup(argv[0]); } else { /* * For hotspares and metadevices, set * cname to the full name, * setname/hspxxx or setname/dxxx */ cname = meta_name_getname(&sp, argv[0], META_DEVICE, ep); if (cname == NULL) { mde_perror(ep, ""); eval = 1; continue; } } if (meta_mn_send_metaclear_command(sp, cname, options, pflag, ep) != 0) { eval = 1; } Free(cname); } else { if (pflag) { /* * clear all soft partitions on named * devices */ if (meta_sp_reset_component(sp, argv[0], options, ep) != 0) { mde_perror(ep, ""); eval = 1; continue; } } else { /* * get the canonical name and * setup sp if it has been * specified as part of the * metadevice/hsp name param */ cname = meta_name_getname(&sp, argv[0], META_DEVICE, ep); if (cname == NULL) { mde_perror(ep, ""); eval = 1; continue; } /* clear named devices */ if (clear_name(&sp, cname, options, ep) != 0) { mde_perror(ep, ""); eval = 1; Free(cname); continue; } Free(cname); } } } } /* update md.cf */ if (meta_update_md_cf(sp, ep) != 0) { mde_perror(ep, ""); eval = 1; } md_exit(sp, eval); errout: mde_perror(ep, ""); md_exit(sp, eval); /*NOTREACHED*/ return (eval); }