diff options
Diffstat (limited to 'usr/src/cmd/avs/dsw/iiboot.c')
-rw-r--r-- | usr/src/cmd/avs/dsw/iiboot.c | 684 |
1 files changed, 0 insertions, 684 deletions
diff --git a/usr/src/cmd/avs/dsw/iiboot.c b/usr/src/cmd/avs/dsw/iiboot.c deleted file mode 100644 index 4886ecfd68..0000000000 --- a/usr/src/cmd/avs/dsw/iiboot.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#include <sys/param.h> -#include <errno.h> -#include <limits.h> -#include <fcntl.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> -#include <ctype.h> - -#include <sys/nsctl/cfg.h> - -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> - -#include <sys/nsctl/dsw.h> -#include <sys/nskernd.h> - -#define MAX_PROCESSES 64 - -int parseopts(int, char **, int *); -int read_resume_cfg(); -int read_suspend_cfg(); -void iiboot_usage(void); -extern char *basename(char *); - -dsw_config_t *resume_list = 0; -dsw_ioctl_t *suspend_list = 0; -int n_structs; -char *program; -char *cfg_cluster_tag = NULL; - -volatile int fork_cnt; -volatile int fork_rc; - -static void -iiboot_msg(char *prefix, spcs_s_info_t *status, char *string, va_list ap) -{ - if (status) { - (void) fprintf(stderr, "II: %s\n", prefix); - spcs_s_report(*status, stderr); - spcs_s_ufree(status); - } else { - (void) fprintf(stderr, "%s: %s: ", program, prefix); - } - - if (string && *string != '\0') { - (void) vfprintf(stderr, string, ap); - } - - (void) fprintf(stderr, "\n"); -} - -static void -iiboot_err(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - iiboot_msg(gettext("Error"), status, string, ap); - - va_end(ap); - exit(1); -} - -static void -iiboot_warn(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - iiboot_msg(gettext("warning"), status, string, ap); - - va_end(ap); -} - -/* ARGSUSED */ -static void -sigchld(int sig) -{ - int wait_loc = 0; - - (void) wait(&wait_loc); - if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0)) { - ; - /*EMPTY*/ - } else { - fork_rc = WEXITSTATUS(wait_loc); - } - - if (fork_cnt > 0) - --fork_cnt; -} - - -int -#ifdef lint -iiboot_lintmain(int argc, char *argv[]) -#else -main(int argc, char *argv[]) -#endif -{ - int pairs; - pid_t pid = 0; - int flag = 0; - int i, j; - int rc; - int ioctl_fd; - void *ioarg; - dsw_ioctl_t *ii_iop, ii_suspend; - dsw_list_t args = {0}; - dsw_config_t *ii_cfgp, *lp = NULL; - spcs_s_info_t ustatus; - int max_processes = MAX_PROCESSES; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("ii"); - - program = strdup(basename(argv[0])); - - if ((ioctl_fd = open(DSWDEV, O_RDWR, 0)) == -1) { - spcs_log("ii", NULL, "iiboot open %s failed, errno %d", - DSWDEV, errno); - iiboot_err(NULL, - gettext("Failed to open Point-in-Time Copy control " - "device")); - } - - if (parseopts(argc, argv, &flag)) - return (1); - - if (flag == DSWIOC_RESUME) - pairs = read_resume_cfg(); - else - pairs = -1; - - if (pairs == 0) { -#ifdef DEBUG - iiboot_err(NULL, - gettext("Config contains no Point-in-Time Copy sets")); -#endif - return (0); - } - - if (cfg_cluster_tag == NULL && flag != DSWIOC_RESUME) { - if (ioctl(ioctl_fd, DSWIOC_SHUTDOWN, 0) < 0) { - spcs_log("ii", &ustatus, "iiboot shutdown failed"); - iiboot_err(NULL, gettext("SHUTDOWN ioctl error")); - } - return (0); - } else if (cfg_cluster_tag != NULL && flag == DSWIOC_SUSPEND) { - bzero(&ii_suspend, sizeof (dsw_ioctl_t)); - ii_suspend.status = spcs_s_ucreate(); - ii_suspend.flags = CV_IS_CLUSTER; - (void) strncpy(ii_suspend.shadow_vol, cfg_cluster_tag, - DSW_NAMELEN); - rc = ioctl(ioctl_fd, flag, &ii_suspend); - if ((rc) && (errno != DSW_ECNOTFOUND)) { - spcs_log("ii", &ii_suspend.status, - "iiboot resume cluster %s failed", cfg_cluster_tag); - iiboot_err(&ii_suspend.status, gettext("ioctl error")); - spcs_s_ufree(&ii_suspend.status); - return (-1); - } - spcs_s_ufree(&ii_suspend.status); - return (0); - - } else if ((cfg_cluster_tag != NULL) && (flag == DSWIOC_RESUME)) { - /* - * If we are running in a Sun Cluster, this is a resume - * operation, get a list of all shadow volumes, where the - * shadow volumes match the shadows of the sets being resumed - */ - rc = ioctl(ioctl_fd, DSWIOC_LISTLEN, &args); - if (rc == -1) { - spcs_log("ii", NULL, - "iiboot get LIST failed, errno %d", errno); - iiboot_err(NULL, - gettext("Failed to get LIST of Point-in-Time " - "sets")); - return (-1); - } - - args.status = spcs_s_ucreate(); - args.list_used = 0; - args.list_size = rc + 4; - lp = args.list = (dsw_config_t *) - malloc(args.list_size * sizeof (dsw_config_t)); - if (args.list == NULL) { - iiboot_err(NULL, - gettext("Failed to allocate memory")); - } - if (ioctl(ioctl_fd, DSWIOC_LIST, &args) == -1) { - spcs_log("ii", &args.status, "Failed to get LIST"); - iiboot_err(&args.status, gettext("ioctl error")); - } - spcs_s_ufree(&args.status); - - /* Remove all elements that are not in the resume list */ - for (j = args.list_used; j; j--) { - for (i = 0; i < pairs; i++) { - if (strcmp(lp->shadow_vol, - resume_list[i].shadow_vol) == 0) { - if (strlen(lp->cluster_tag) == 0) { - lp++; - break; - } - } - } - if (i != pairs) - continue; - (void) memmove(lp, lp + 1, j * sizeof (dsw_config_t)); - args.list_used--; - } - } - - (void) sigset(SIGCHLD, sigchld); - fork_cnt = fork_rc = 0; - for (i = 0; i < pairs; i++) { - ustatus = spcs_s_ucreate(); - if (flag == DSWIOC_RESUME) { - ioarg = (void *) (ii_cfgp = (resume_list + i)); - ii_cfgp->status = ustatus; - pid = fork(); - } else { - ioarg = (void *) (ii_iop = (suspend_list + i)); - ii_iop->status = ustatus; - } - while (pid == -1) { /* error forking */ - perror("fork"); - - /* back off on the max processes and try again */ - --max_processes; - if (fork_cnt > 0) { - (void) pause(); - } - pid = fork(); - } - - if (pid > 0) { /* this is parent process */ - ++fork_cnt; - while (fork_cnt > MAX_PROCESSES) { - (void) pause(); - } - continue; - } - - rc = ioctl(ioctl_fd, flag, ioarg); - if (rc == SPCS_S_ERROR) { - if (flag == DSWIOC_RESUME) - spcs_log("ii", &ustatus, - "iiboot resume %s failed", - ii_cfgp->shadow_vol); - else - spcs_log("ii", &ustatus, - "iiboot suspend %s failed", - ii_iop->shadow_vol); - iiboot_err(&ustatus, gettext("ioctl error")); - } - /* Resuming child */ - spcs_s_ufree(&ustatus); - if (flag == DSWIOC_RESUME) - exit(0); - } - - /* - * Allow all processes to finish up before exiting - * Set rc for success - */ - while (fork_cnt > 0) { - (void) alarm(60); /* wake up in 60 secs just in case */ - (void) pause(); - } - (void) alarm(0); - - /* Disable duplicate shadows that were part of the implicit join */ - if ((j = args.list_used) != 0) { - int setno; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF], sn[CFG_MAX_BUF]; - CFGFILE *cfg; - char *mst, *shd, *ctag; - pid_t pid = fork(); - - if (pid == -1) { - iiboot_err(NULL, gettext("Failed to fork")); - return (errno); - } else if (pid > 0) { - return (0); /* Parent, OK exit */ - } - - for (j = args.list_used, lp = args.list; j; j--, lp++) { - setno = 0; - while (++setno) { - - /* - * Open the configuration database - */ - if (!(cfg = cfg_open(""))) { - iiboot_err(NULL, gettext("Failed to open dscfg")); - return (-1); - } - - /* Sooner or later, this lock will be free */ - while (!cfg_lock(cfg, CFG_WRLOCK)) - (void) sleep(2); - - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - cfg_close(cfg); - break; - } - - /* For imported shadows, master must be special tag */ - mst = strtok(buf, " "); /* master */ - shd = strtok(NULL, " "); /* shadow */ - (void) strtok(NULL, " "); /* bitmap */ - (void) strtok(NULL, " "); /* mode */ - (void) strtok(NULL, " "); /* overflow */ - ctag = strtok(NULL, " "); /* cnode */ - - /* - * For this record to be processed, the shadow volume - * name must match and the cluster tag must be blank - */ - if (strcmp(lp->shadow_vol, shd) || strcmp(ctag, "-")) { - cfg_close(cfg); - continue; - } - - /* Derrive local cluster tag */ - if (cfg_l_dgname(lp->shadow_vol, sn, sizeof (sn))) - ctag = sn; - else - iiboot_err(NULL, gettext( - "Failed to device group for shadow %s"), - lp->shadow_vol); - - /* disable master volume if not imported */ - if (strcmp(mst, II_IMPORTED_SHADOW)) - if (cfg_vol_disable(cfg, mst, cfg_cluster_tag, - "ii") < 0) - iiboot_err(NULL, gettext( - "SV disable of master failed")); - - /* - * Delete the Imported Shadow set - */ - if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { - iiboot_err(NULL, gettext( - "Failed to delete Imported shadow %s"), - lp->shadow_vol); - } - - /* - * SV disable shadow volume - */ - if (cfg_vol_disable(cfg, shd, NULL, "ii") < 0) - iiboot_err(NULL, gettext( - "SV disable of shadow failed")); - - /* - * Commit the delete - */ - (void) cfg_commit(cfg); - cfg_close(cfg); - - /* - * Open the configuration database - */ - if (!(cfg = cfg_open(""))) { - iiboot_err(NULL, gettext("Failed to open dscfg")); - return (-1); - } - - /* Sooner or later, this lock will be free */ - while (!cfg_lock(cfg, CFG_WRLOCK)) - (void) sleep(2); - - /* Set cluster tag for Shadow volume */ - (void) cfg_vol_enable(cfg, shd, ctag, "ii"); - - - /* - * Commit the delete - */ - (void) cfg_commit(cfg); - cfg_close(cfg); - } - } - } - return (fork_rc); -} - -static int -set_is_offline(char *cflags) -{ - unsigned int flags; - int conv; - - if (!cflags || !*cflags) - return (0); - - /* convert flags to an int */ - conv = sscanf(cflags, "%x", &flags); - return ((conv == 1) && ((flags & DSW_OFFLINE) != 0)); -} - -/* - * read_resume_cfg() - * - * DESCRIPTION: Read the relevant config info via libcfg - * - * Outputs: - * int i Number of Point-in-Time Copy sets - * - * Side Effects: The 0 to i-1 entries in the resume_list are filled. - * - */ - -int -read_resume_cfg() -{ - CFGFILE *cfg; - int i; - char *buf, **entry, *mst, *shd, *bmp, *ctag, *opt, *ptr; - int valid_sets; - dsw_config_t *p; - static int offset = sizeof (NSKERN_II_BMP_OPTION); - - spcs_log("ii", NULL, "iiboot resume cluster tag %s", - cfg_cluster_tag ? cfg_cluster_tag : "<none>"); - if ((cfg = cfg_open("")) == NULL) { - spcs_log("ii", NULL, "iiboot cfg_open failed, errno %d", - errno); - iiboot_err(NULL, gettext("Error opening config")); - } - - cfg_resource(cfg, cfg_cluster_tag); - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("ii", NULL, "iiboot CFG_RDLOCK failed, errno %d", - errno); - iiboot_err(NULL, gettext("Error locking config")); - } - - /* Determine number of set, if zero return 0 */ - if ((n_structs = cfg_get_section(cfg, &entry, "ii")) == 0) - return (0); - - resume_list = calloc(n_structs, sizeof (*resume_list)); - if (resume_list == NULL) { - spcs_log("ii", NULL, "iiboot resume realloc failed, errno %d", - errno); - iiboot_err(NULL, gettext("Resume realloc failed")); - } - - valid_sets = 0; - p = resume_list; - for (i = 0; i < n_structs; i++) { - buf = entry[i]; - mst = strtok(buf, " "); - shd = strtok(NULL, " "); - bmp = strtok(NULL, " "); - (void) strtok(NULL, " "); /* mode */ - (void) strtok(NULL, " "); /* overflow */ - ctag = strtok(NULL, " "); /* ctag */ - if (ctag) - ctag += strspn(ctag, "-"); - opt = strtok(NULL, " "); - - if (!mst || !shd || !bmp) - break; - - /* If cluster tags don't match, skip record */ - if ((cfg_cluster_tag && strcmp(ctag, cfg_cluster_tag)) || - (!cfg_cluster_tag && strlen(ctag))) { - free(buf); - continue; - } - - ptr = strstr(opt, NSKERN_II_BMP_OPTION "="); - if (ptr && set_is_offline(ptr + offset)) { - free(buf); - continue; - } - - (void) strncpy(p->master_vol, mst, DSW_NAMELEN); - (void) strncpy(p->shadow_vol, shd, DSW_NAMELEN); - (void) strncpy(p->bitmap_vol, bmp, DSW_NAMELEN); - if (ctag) - (void) strncpy(p->cluster_tag, ctag, DSW_NAMELEN); - free(buf); - ++p; - ++valid_sets; - } - - while (i < n_structs) - free(entry[i++]); - if (entry) - free(entry); - - cfg_close(cfg); - return (valid_sets); -} - -/* - * read_suspend_cfg() - * - * DESCRIPTION: Read the relevant config info via libcfg - * - * Outputs: - * int i Number of Point-in-Time Copy sets - * - * Side Effects: The 0 to i-1 entries in the suspend_list are filled. - * - */ - -int -read_suspend_cfg() -{ - int rc; - CFGFILE *cfg; - int i; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int setnumber; - dsw_ioctl_t *p; - - spcs_log("ii", NULL, "iiboot suspend cluster tag %s", - cfg_cluster_tag ? cfg_cluster_tag : "<none>"); - - if (cfg_cluster_tag == NULL) { - return (1); - } - - if ((cfg = cfg_open("")) == NULL) { - spcs_log("ii", NULL, "iiboot cfg_open failed, errno %d", - errno); - iiboot_err(NULL, gettext("Error opening config")); - } - - cfg_resource(cfg, cfg_cluster_tag); - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("ii", NULL, "iiboot CFG_RDLOCK failed, errno %d", - errno); - iiboot_err(NULL, gettext("Error locking config")); - } - - - /*CSTYLED*/ - for (i = 0; ; i++) { - setnumber = i + 1; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "ii.set%d", setnumber); - rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); - if (rc < 0) - break; - if (n_structs < setnumber) { - n_structs += 2; - suspend_list = realloc(suspend_list, - sizeof (*suspend_list) * n_structs); - if (suspend_list == NULL) { - spcs_log("ii", NULL, - "iiboot suspend realloc failed, errno %d", - errno); - iiboot_err(NULL, gettext("Suspend realloc failed")); - } - } - p = suspend_list + i; - - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - setnumber); - (void) cfg_get_cstring(cfg, key, p->shadow_vol, DSW_NAMELEN); - - } - - cfg_close(cfg); - return (i); -} - - -int -parseopts(argc, argv, flag) -int argc; -char **argv; -int *flag; -{ - int errflag = 0; - int Cflag = 0; - char c; - char inval = 0; - - while ((c = getopt(argc, argv, "hrsC:")) != -1) { - switch (c) { - case 'C': - if (Cflag) { - iiboot_warn(NULL, - gettext("-C specified multiple times")); - iiboot_usage(); - return (-1); - } - - Cflag++; - cfg_cluster_tag = (optarg[0] == '-') ? NULL : optarg; - break; - - case 'h': - iiboot_usage(); - exit(0); - /* NOTREACHED */ - - case 'r': - if (*flag) - inval = 1; - *flag = DSWIOC_RESUME; - break; - case 's': - if (*flag) - inval = 1; - *flag = DSWIOC_SUSPEND; - break; - case '?': - errflag++; - } - } - - if (inval) { - iiboot_warn(NULL, gettext("Invalid argument combination")); - errflag = 1; - } - - if (!*flag || errflag) { - iiboot_usage(); - return (-1); - } - - return (0); -} - -void -iiboot_usage() -{ - (void) fprintf(stderr, gettext("usage:\n")); - (void) fprintf(stderr, - gettext("\t%s -r [-C tag]\t\tresume\n"), program); - (void) fprintf(stderr, - gettext("\t%s -s [-C tag]\t\tsuspend\n"), program); - (void) fprintf(stderr, gettext("\t%s -h\t\t\tthis help message\n"), - program); -} |