/* * resync raid */ int meta_raid_resync( mdsetname_t *sp, mdname_t *raidnp, daddr_t size, md_error_t *ep ) { char *miscname; md_resync_ioctl_t ri; /* should have a set */ assert(sp != NULL); assert(sp->setno == MD_MIN2SET(meta_getminor(raidnp->dev))); /* make sure we have a raid */ if ((miscname = metagetmiscname(raidnp, ep)) == NULL) return (-1); if (strcmp(miscname, MD_RAID) != 0) { return (mdmderror(ep, MDE_NOT_RAID, meta_getminor(raidnp->dev), raidnp->cname)); } /* start resync */ (void) memset(&ri, 0, sizeof (ri)); MD_SETDRIVERNAME(&ri, MD_RAID, sp->setno); ri.ri_mnum = meta_getminor(raidnp->dev); ri.ri_copysize = size; if (metaioctl(MD_IOCSETSYNC, &ri, &ri.mde, raidnp->cname) != 0) return (mdstealerror(ep, &ri.mde)); /* return success */ return (0); }
int md_probe_ioctl(mdnamelist_t *nlp, int ndevs, char *drvname, boolean_e verbose) { mdnamelist_t *p; mdname_t *np; md_probedev_t probe_ioc, *iocp; int i, retval = 0; /* * Allocate space for all the metadevices and fill in * the minor numbers. */ memset(&probe_ioc, 0, sizeof (probe_ioc)); iocp = &probe_ioc; if ((iocp->mnum_list = (uintptr_t)calloc(ndevs, sizeof (minor_t))) == 0) { monitord_print(0, "md_probe_ioctl: calloc"); return (-1); } (void) strcpy(iocp->test_name, MD_PROBE_OPEN_T); MD_SETDRIVERNAME(&probe_ioc, drvname, sp->setno); if (verbose == True) { monitord_print(6, "\n\nmd_probe_ioctl: %s: %s\n", (strcmp(sp->setname, MD_LOCAL_NAME) == 0) ? gettext("local_set") : sp->setname, iocp->md_driver.md_drivername); } iocp->nmdevs = ndevs; if (verbose == True) monitord_print(6, "...ndevs 0x%x\n", ndevs); for (p = nlp, i = 0; p; p = p->next, i++) { np = p->namep; ((minor_t *)(uintptr_t)iocp->mnum_list)[i] = meta_getminor(np->dev); if (verbose == True) monitord_print(6, "...%s 0x%lx\n", np->cname, ((minor_t *)(uintptr_t)iocp->mnum_list)[i]); } if (issue_ioctl == True) { if (metaioctl(MD_IOCPROBE_DEV, iocp, &(iocp->mde), NULL) != 0) retval = -1; } return (retval); }
static void metahalt() { mdsetname_t *sp; md_error_t status = mdnullerror; (void) init_metalib(); if ((sp = metasetname(MD_LOCAL_NAME, &status)) == NULL) { return; } if (meta_lock(sp, TRUE, &status)) { return; } if (metaioctl(MD_HALT, NULL, &status, NULL) != 0) { debug_printf("metahalt(): errno %d\n", status.info.md_error_info_t_u.sys_error.errnum); } (void) meta_unlock(sp, &status); reset_metalib(&status); }
/* * grow generic device */ int meta_concat_generic( mdsetname_t *sp, mdname_t *namep, u_longlong_t big_or_little, md_error_t *ep ) { md_grow_params_t mgp; char *miscname; /* should have a set */ assert(sp != NULL); assert(sp->setno == MD_MIN2SET(meta_getminor(namep->dev))); /* get type */ if ((miscname = metagetmiscname(namep, ep)) == NULL) return (-1); /* grow device */ (void) memset(&mgp, 0, sizeof (mgp)); if (big_or_little & MD_64BIT_META_DEV) mgp.options = MD_CRO_64BIT; else mgp.options = MD_CRO_32BIT; mgp.mnum = meta_getminor(namep->dev); MD_SETDRIVERNAME(&mgp, miscname, sp->setno); if (metaioctl(MD_IOCGROW, &mgp, &mgp.mde, namep->cname) != 0) return (mdstealerror(ep, &mgp.mde)); /* clear cache */ meta_invalidate_name(namep); /* return success */ return (0); }
/* ARGSUSED */ int main(void) { int i; int mdmn_door_handle; pid_t pid; int size; md_error_t ep = mdnullerror; struct rlimit rl; /* * 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); openlog("mddoors", LOG_PID, LOG_DAEMON); /* here beginneth the daemonizing code */ pid = fork(); if (pid < 0) { syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot fork")); exit(1); } if (pid) { exit(0); } /* * Only one daemon can run at a time. * If another instance is already running, this is not an error. */ if ((pid = enter_daemon_lock()) != getpid()) { exit(0); } rl.rlim_max = 0; (void) getrlimit(RLIMIT_NOFILE, &rl); if ((size = rl.rlim_max) == 0) { syslog(LOG_DAEMON | LOG_ERR, gettext("Cannot getrlimit")); exit(1); } for (i = 0; i < size; i++) { if (i == daemon_lock_fd) continue; (void) close(i); } i = open("/dev/null", 2); (void) dup2(i, 1); (void) dup2(i, 2); (void) setsid(); /* here endeth the daemonizing code */ /* Block out the usual signals so we don't get killed unintentionally */ (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTERM, SIG_IGN); (void) atexit(daemon_cleanup); /* Resume any previously blocked resync */ meta_mirror_resync_unblock_all(); /* * At this point we are single threaded. * We give mdmn_send_message() a chance to initialize safely. */ (void) mdmn_send_message(0, 0, 0, 0, 0, 0, 0, 0); /* setup the door handle */ mdmn_door_handle = door_create(door2rpc, NULL, DOOR_REFUSE_DESC | DOOR_NO_CANCEL); if (mdmn_door_handle == -1) { perror(gettext("door_create failed")); syslog(LOG_DAEMON | LOG_ERR, gettext("door_create failed")); exit(1); } if (metaioctl(MD_MN_SET_DOORH, &mdmn_door_handle, &ep, "mddoors") != 0) { syslog(LOG_DAEMON | LOG_DEBUG, gettext( "Couldn't set door handle")); exit(1); } (void) pause(); syslog(LOG_DAEMON | LOG_ERR, gettext( "Unexpected exit from pause()")); return (1); }
int main(int argc, char **argv) { char c; char *sname = MD_LOCAL_NAME; mddevopts_t options = 0; md_error_t status = mdnullerror; md_error_t *ep = &status; mdsetname_t *sp = NULL; mdsetname_t *local_sp = NULL; char *argname; int todo = 0; int ret = 0; int md_upgd_stat = 0; int error; md_set_desc *sd; /* * 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 ((sdssc_bind_library() == SDSSC_OKAY) && (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY, &error) == SDSSC_PROXY_DONE)) exit(error); openlog("metadevadm", LOG_ODELAY, LOG_USER); /* initialize */ if (md_init(argc, argv, 0, 1, ep) != 0 || meta_check_root(ep) != 0) { closelog(); mde_perror(ep, ""); md_exit(sp, 1); } /* parse args */ optind = 1; opterr = 1; while ((c = getopt(argc, argv, "vlhnrs:u:")) != -1) { switch (c) { case 'v': options |= DEV_VERBOSE; break; case 'n': options |= DEV_NOACTION; break; case 'r': options |= DEV_RELOAD; todo = 1; break; case 's': sname = optarg; break; case 'u': todo = 1; options |= DEV_UPDATE; argname = optarg; if (argname == NULL) { usage("metadevadm"); closelog(); md_exit(sp, 0); } break; case 'l': options |= DEV_LOG; break; case 'h': default: usage("metadevadm"); closelog(); md_exit(sp, 0); } } if ((sp = metasetname(sname, ep)) == NULL) { mde_perror(ep, ""); closelog(); md_exit(sp, 1); } if (!metaislocalset(sp)) { if ((sd = metaget_setdesc(sp, ep)) == NULL) { mde_perror(ep, ""); closelog(); md_exit(sp, 1); } if (MD_MNSET_DESC(sd)) { (void) printf("%s\n", gettext("metadevadm cannot be " "run on multi-owner disksets\n")); closelog(); md_exit(sp, 0); } } if ((options & DEV_VERBOSE) && (todo != 1)) { usage("metadevadm"); closelog(); md_exit(sp, 0); } if ((options & DEV_NOACTION) && (todo != 1)) { usage("metadevadm"); closelog(); md_exit(sp, 0); } if (todo == 0) { usage("metadevadm"); closelog(); md_exit(sp, 0); } if ((local_sp = metasetname(MD_LOCAL_NAME, ep)) == NULL) { mde_perror(ep, ""); closelog(); md_exit(local_sp, 1); } /* lock the local set */ if (meta_lock(local_sp, TRUE, ep) != 0) { mde_perror(ep, ""); closelog(); md_exit(local_sp, 1); } /* grab set lock */ if (meta_lock(sp, TRUE, ep)) { mde_perror(ep, ""); closelog(); md_exit(local_sp, 1); } /* check for ownership */ if (meta_check_ownership(sp, ep) != 0) { /* * If the set is not owned by this node then only update the * local set's replica. */ options |= DEV_LOCAL_SET; } /* * check for upgrade. If upgrade in progress then just exit. */ if (metaioctl(MD_UPGRADE_STAT, &md_upgd_stat, ep, NULL) != 0) { mde_perror(ep, ""); closelog(); (void) meta_unlock(sp, ep); md_exit(local_sp, 1); } if (md_upgd_stat == 0) { ret = meta_fixdevid(sp, options, argname, ep); if (ret == METADEVADM_ERR) { /* * If the call failed, for a DEV_RELOAD still need to * update the .conf file to provide the latest devid * information so exit later. */ if (options & DEV_UPDATE) { closelog(); (void) meta_unlock(sp, ep); md_exit(local_sp, 1); } } } /* * Sync replica list in kernel to replica list in conf files. * This will update driver name and minor number in conf file * if reload was run. Will update device id in conf file if * update was run. */ meta_sync_db_locations(sp, ep); closelog(); (void) meta_unlock(sp, ep); md_exit(local_sp, ret); return (0); }