summaryrefslogtreecommitdiff
path: root/usr/src/cmd/avs/dsw/iiboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/avs/dsw/iiboot.c')
-rw-r--r--usr/src/cmd/avs/dsw/iiboot.c684
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);
-}