diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2018-08-07 16:46:21 -0700 |
---|---|---|
committer | Joshua M. Clulow <josh@sysmgr.org> | 2018-08-07 16:46:22 -0700 |
commit | cb41b9c565d4eec9e1f06e24d429696f59f2f07d (patch) | |
tree | ee8675f196c2ea84b5ac5c6f0dff8c9e5305f0ee /usr/src/cmd | |
parent | 0e986b9d87352cd82909c748e7f684afe0ed579f (diff) | |
download | illumos-joyent-cb41b9c565d4eec9e1f06e24d429696f59f2f07d.tar.gz |
9674 Let's scrap AVS/sdbc
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
Diffstat (limited to 'usr/src/cmd')
105 files changed, 1 insertions, 47421 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 996cd553a7..57644f077b 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -26,7 +26,7 @@ # Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2016 Toomas Soome <tsoome@me.com> -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2018 Nexenta Systems, Inc. # Copyright 2018 Gary Mills # @@ -68,7 +68,6 @@ COMMON_SUBDIRS= \ audio \ auths \ autopush \ - avs \ awk \ awk_xpg4 \ backup \ @@ -519,7 +518,6 @@ MSGSUBDIRS= \ auditset \ auths \ autopush \ - avs \ awk \ awk_xpg4 \ backup \ diff --git a/usr/src/cmd/avs/Makefile b/usr/src/cmd/avs/Makefile deleted file mode 100644 index 18c07e24d6..0000000000 --- a/usr/src/cmd/avs/Makefile +++ /dev/null @@ -1,74 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -include ../Makefile.cmd -include Makefile.com - -# general subdirectories - -MSGSUBDIRS= dsbitmap \ - dscfg \ - dscfglockd \ - dsstat \ - dsw \ - errgen \ - ncall \ - nsctl \ - rdc \ - sdbc \ - sv - -SUBDIRS = $(MSGSUBDIRS) svc - -all:= TARGET= all -install:= TARGET= install -clean:= TARGET= clean -clobber:= TARGET= clobber -lint:= TARGET= lint -_msg:= TARGET= _msg - -.KEEP_STATE: - -all clean clobber: $(SUBDIRS) - -_msg: $(MSGSUBDIRS) - -install: $(CLUSTERDIR) \ - $(CLUSTERLIBDIR) \ - $(CLUSTERSBINDIR) \ - $(CLUSTERLIBDSCFGDIR) \ - $(CLUSTERLIBDSCFGSTOPDIR) \ - $(CLUSTERLIBDSCFGSTARTDIR) \ - .WAIT \ - $(SUBDIRS) - -lint: $(SUBDIRS) - -$(CLUSTERDIR) $(CLUSTERLIBDIR) $(CLUSTERSBINDIR) $(CLUSTERLIBDSCFGDIR) $(CLUSTERLIBDSCFGSTOPDIR) $(CLUSTERLIBDSCFGSTARTDIR): - $(INS.dir) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: diff --git a/usr/src/cmd/avs/Makefile.com b/usr/src/cmd/avs/Makefile.com deleted file mode 100644 index b6ea49214b..0000000000 --- a/usr/src/cmd/avs/Makefile.com +++ /dev/null @@ -1,33 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/avs/Makefile.com -# -CLUSTERDIR = $(ROOT)/usr/cluster -CLUSTERSBINDIR = $(CLUSTERDIR)/sbin -CLUSTERLIBDIR = $(CLUSTERDIR)/lib -CLUSTERLIBDSCFGDIR = $(CLUSTERLIBDIR)/dscfg -CLUSTERLIBSTOPDIR = $(CLUSTERLIBDIR)/stop -CLUSTERLIBSTARTDIR = $(CLUSTERLIBDIR)/start -CLUSTERLIBDSCFGSTOPDIR = $(CLUSTERLIBDSCFGDIR)/stop -CLUSTERLIBDSCFGSTARTDIR = $(CLUSTERLIBDSCFGDIR)/start diff --git a/usr/src/cmd/avs/dsbitmap/Makefile b/usr/src/cmd/avs/dsbitmap/Makefile deleted file mode 100644 index 2b9380995e..0000000000 --- a/usr/src/cmd/avs/dsbitmap/Makefile +++ /dev/null @@ -1,76 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -DYNPROG= dsbitmap - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -dsbitmap := POBJS = dsbitmap.o - -OBJS= dsbitmap.o -SRCS= $(OBJS:%.o=%.c) -POFILE= $(OBJS:%.o=%.po) - -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-uninitialized -LDLIBS += -lunistat -ladm -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -ROOTLINK = $(ROOTUSRSBIN)/$(PROG) - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -install: all $(ROOTPROG) $(ROOTLINK) - -lint: lint_SRCS - -clean: - $(RM) *.o $(POFILE) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -check: $(PROG).c - $(CSTYLE) -pP $(SRCS:%=%) - -$(ROOTLINK): $(ROOTBIN)/$(PROG) $(ROOTUSRSBIN) - -$(RM) $@; $(LN) $(ROOTBIN)/$(PROG) $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/dsbitmap/dsbitmap.c b/usr/src/cmd/avs/dsbitmap/dsbitmap.c deleted file mode 100644 index 77c5be7c1f..0000000000 --- a/usr/src/cmd/avs/dsbitmap/dsbitmap.c +++ /dev/null @@ -1,436 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/dkio.h> -#include <sys/vtoc.h> -#include <sys/mkdev.h> -#ifdef DKIOCPARTITION -#include <sys/efi_partition.h> -#endif -#include <strings.h> -#include <stdarg.h> -#include <stdlib.h> -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> -#include <unistd.h> -#include <libgen.h> -#include <kstat.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/nsctl/dsw_dev.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_bitmap.h> - -enum { UNKNOWN = 0, SNDR, II }; - -static char *program; - -void -usage(void) -{ - (void) printf(gettext("usage: %s -h\n"), program); - (void) printf(gettext(" %s { -p | -r } data_volume " - "[bitmap_volume]\n"), program); - (void) printf(gettext(" -h : This usage message\n")); - (void) printf(gettext(" -p : Calculate size of Point in Time " - "bitmap\n")); - (void) printf(gettext(" -r : Calculate size of Remote Mirror " - "bitmap\n")); -} - - -static void -message(char *prefix, spcs_s_info_t *status, caddr_t string, va_list ap) -{ - (void) fprintf(stderr, "%s: %s: ", program, prefix); - (void) vfprintf(stderr, string, ap); - (void) fprintf(stderr, "\n"); - - if (status) { - spcs_s_report(*status, stderr); - spcs_s_ufree(status); - } -} - - -static void -error(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("error"), status, string, ap); - va_end(ap); - exit(1); -} - - -static void -warn(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("warning"), status, string, ap); - va_end(ap); -} - -#if defined(_LP64) - /* max value of a "long int" */ -#define ULONG_MAX 18446744073709551615UL -#else /* _ILP32 */ -#define ULONG_MAX 4294967295UL /* max of "unsigned long int" */ -#endif - -static uint64_t -get_partsize(char *partition) -{ -#ifdef DKIOCPARTITION - struct dk_cinfo dki_info; - struct partition64 p64; -#endif - struct vtoc vtoc; - uint64_t size; - int fd; - int rc; - - if ((fd = open(partition, O_RDONLY)) < 0) { - error(NULL, gettext("unable to open partition, %s: %s"), - partition, strerror(errno)); - /* NOTREACHED */ - } - - rc = read_vtoc(fd, &vtoc); - if (rc >= 0) { - size = (uint64_t)(ULONG_MAX & vtoc.v_part[rc].p_size); - return (size); - } -#ifdef DKIOCPARTITION - else if (rc != VT_ENOTSUP) { -#endif - error(NULL, - gettext("unable to read the vtoc from partition, %s: %s"), - partition, strerror(errno)); - /* NOTREACHED */ -#ifdef DKIOCPARTITION - } - - /* See if there is an EFI label */ - rc = ioctl(fd, DKIOCINFO, &dki_info); - if (rc < 0) { - error(NULL, gettext("unable to get controller info " - "from partition, %s: %s"), - partition, strerror(errno)); - /* NOTREACHED */ - } - - bzero(&p64, sizeof (p64)); - p64.p_partno = (uint_t)dki_info.dki_partition; - rc = ioctl(fd, DKIOCPARTITION, &p64); - if (rc >= 0) { - size = (uint64_t)p64.p_size; - return (size); - } else { - struct stat64 stb1, stb2; - struct dk_minfo dkm; - - /* - * See if the stat64 for ZFS's zvol matches - * this file descriptor's fstat64 data. - */ - if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 || - fstat64(fd, &stb2) != 0 || - !S_ISCHR(stb1.st_mode) || - !S_ISCHR(stb2.st_mode) || - major(stb1.st_rdev) != major(stb2.st_rdev)) { - error(NULL, - gettext("unable to read disk partition, %s: %s"), - partition, strerror(errno)); - /* NOTREACHED */ - } - - rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm); - if (rc >= 0) { - size = LE_64(dkm.dki_capacity) * - dkm.dki_lbsize / 512; - return (size); - } else { - error(NULL, gettext("unable to read EFI label " - "from partition, %s: %s"), - partition, strerror(errno)); - /* NOTREACHED */ - } - } - return (size); - -#endif /* DKIOCPARTITION */ -} - - -int -do_sndr(char *volume, char *bitmap) -{ - uint64_t vblocks; - uint64_t bblocks; - uint64_t bsize_bits; /* size of the bits alone */ - uint64_t bsize_simple; /* size of the simple bitmap */ - uint64_t bsize_diskq; /* size of the diskq bitmap, 8 bit refcnt */ - uint64_t bsize_diskq32; /* size of the diskq bitmap, 32 bit refcnt */ - int rc = 0; - - vblocks = get_partsize(volume); - if (bitmap) { - bblocks = get_partsize(bitmap); - } - - bsize_bits = BMAP_LOG_BYTES(vblocks); - bsize_bits = (bsize_bits + 511) / 512; - - bsize_simple = RDC_BITMAP_FBA + bsize_bits; - bsize_diskq = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE * bsize_bits); - bsize_diskq32 = RDC_BITMAP_FBA + bsize_bits + (BITS_IN_BYTE * - bsize_bits * sizeof (unsigned int)); - - (void) printf(gettext("Remote Mirror bitmap sizing\n\n")); - (void) printf(gettext("Data volume (%s) size: %llu blocks\n"), - volume, vblocks); - - (void) printf(gettext("Required bitmap volume size:\n")); - (void) printf(gettext(" Sync replication: %llu blocks\n"), - bsize_simple); - (void) printf(gettext(" Async replication with memory queue: " - "%llu blocks\n"), bsize_simple); - (void) printf(gettext(" Async replication with disk queue: " - "%llu blocks\n"), bsize_diskq); - (void) printf(gettext(" Async replication with disk queue and 32 bit " - "refcount: %llu blocks\n"), bsize_diskq32); - - if (bitmap) { - (void) printf("\n"); - (void) printf(gettext("Supplied bitmap volume %s " - "(%llu blocks)\n"), - bitmap, bblocks); - if (bblocks >= bsize_diskq32) { - (void) printf(gettext("is large enough for all " - "replication modes\n")); - } else if (bblocks >= bsize_diskq) { - (void) printf(gettext("is large enough for all " - "replication modes, but with restricted diskq " - "reference counts\n")); - } else if (bblocks >= bsize_simple) { - (void) printf(gettext( - "is large enough for: Sync and Async(memory) " - "replication modes only\n")); - rc = 3; - } else { - (void) printf(gettext( - "is not large enough for any replication modes\n")); - rc = 4; - } - } - - return (rc); -} - - -/* sizes in bytes */ -#define KILO (1024) -#define MEGA (KILO * KILO) -#define GIGA (MEGA * KILO) -#define TERA ((uint64_t)((uint64_t)GIGA * (uint64_t)KILO)) - -/* rounding function */ -#define roundup_2n(x, y) (((x) + ((y) - 1)) & (~y)) - -int -do_ii(char *volume, char *bitmap) -{ - const uint64_t int64_bits = sizeof (uint64_t) * BITS_IN_BYTE; - const uint64_t int32_bits = sizeof (uint32_t) * BITS_IN_BYTE; - const uint64_t terablocks = TERA / ((uint64_t)FBA_SIZE(1)); - uint64_t vblocks_phys, vblocks; - uint64_t bblocks; - uint64_t bsize_ind; /* indep and dep not compact */ - uint64_t bsize_cdep; /* compact dep */ - int rc = 0; - - vblocks_phys = get_partsize(volume); - if (bitmap) { - bblocks = get_partsize(bitmap); - } - - /* round up to multiple of DSW_SIZE blocks */ - vblocks = roundup_2n(vblocks_phys, DSW_SIZE); - bsize_ind = DSW_SHD_BM_OFFSET + (2 * DSW_BM_FBA_LEN(vblocks)); - bsize_cdep = bsize_ind; - bsize_cdep += DSW_BM_FBA_LEN(vblocks) * - ((vblocks < (uint64_t)(terablocks * DSW_SIZE)) ? - int32_bits : int64_bits); - - (void) printf(gettext("Point in Time bitmap sizing\n\n")); - (void) printf(gettext("Data volume (%s) size: %llu blocks\n"), - volume, vblocks_phys); - - (void) printf(gettext("Required bitmap volume size:\n")); - (void) printf(gettext(" Independent shadow: %llu blocks\n"), - bsize_ind); - (void) printf(gettext(" Full size dependent shadow: %llu blocks\n"), - bsize_ind); - (void) printf(gettext(" Compact dependent shadow: %llu blocks\n"), - bsize_cdep); - - if (bitmap) { - (void) printf("\n"); - (void) printf(gettext("Supplied bitmap volume %s " - "(%llu blocks)\n"), bitmap, bblocks); - - if (bblocks >= bsize_cdep) { - (void) printf(gettext("is large enough for all types " - "of shadow volume\n")); - } else if (bblocks >= bsize_ind) { - (void) printf(gettext("is large enough for: " - "Independent and full size dependent shadow " - "volumes only\n")); - rc = 6; - } else { - (void) printf(gettext("is not large enough for" - "any type of shadow volume\n")); - rc = 5; - } - } - - return (rc); -} - - -/* - * Return codes: - * 0 success (if bitmap was supplied it is large enough for all uses) - * 1 usage, programing, or access errors - * 2 unknown option supplied on command line - * 3 SNDR bitmap is not large enough for diskq usage - * 4 SNDR bitmap is not large enough for any usage - * 5 II bitmap is not large enough for any usage - * 6 II bitmap is not large enough for compact dependent usage - */ -int -main(int argc, char *argv[]) -{ - extern int optind; - char *volume, *bitmap; - int type = UNKNOWN; - int opt; - int rc = 0; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("dsbitmap"); - - program = strdup(basename(argv[0])); - - while ((opt = getopt(argc, argv, "hpr")) != EOF) { - switch (opt) { - case 'p': - if (type != UNKNOWN) { - warn(NULL, gettext( - "cannot specify -p with other options")); - usage(); - return (1); - } - type = II; - break; - - case 'r': - if (type != UNKNOWN) { - warn(NULL, gettext( - "cannot specify -r with other options")); - usage(); - return (1); - } - type = SNDR; - break; - - case 'h': - if (argc != 2) { - warn(NULL, gettext( - "cannot specify -h with other options")); - rc = 1; - } - usage(); - return (rc); - /* NOTREACHED */ - - default: - usage(); - return (2); - /* NOTREACHED */ - } - } - - if (type == UNKNOWN) { - warn(NULL, gettext("one of -p and -r must be specified")); - usage(); - return (1); - } - - if ((argc - optind) != 1 && (argc - optind) != 2) { - warn(NULL, gettext("incorrect number of arguments to %s"), - (type == SNDR) ? "-r" : "-p"); - usage(); - return (1); - } - - volume = argv[optind]; - if ((argc - optind) == 2) { - bitmap = argv[optind+1]; - } else { - bitmap = NULL; - } - - switch (type) { - case SNDR: - rc = do_sndr(volume, bitmap); - break; - - case II: - rc = do_ii(volume, bitmap); - break; - - default: - /* cannot happen */ - warn(NULL, gettext("one of -p and -r must be specified")); - rc = 1; - break; - } - - return (rc); -} diff --git a/usr/src/cmd/avs/dscfg/Makefile b/usr/src/cmd/avs/dscfg/Makefile deleted file mode 100644 index 9b4a1eff03..0000000000 --- a/usr/src/cmd/avs/dscfg/Makefile +++ /dev/null @@ -1,81 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -.KEEP_STATE: - -PROG = dscfg -SHFILES = dscfgadm -CLOBBERFILES = $(SHFILES) - -include ../../Makefile.cmd -include ../Makefile.com - - -LPROG = $(PROG:%=%.li) - -SUBDIRS= etc - -OBJS= dscfg.o - -CFLAGS += $(CCVERBOSE) -D_SYSCALL32 -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-address -LDLIBS += -ldscfg -lunistat -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_SYSCALL32 -LINTFLAGS += -erroff=E_NOP_ELSE_STMT -erroff=E_FUNC_SET_NOT_USED -LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2 -LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2 -LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2 -LINTDIR = $(KBASE)/lintdir -LFILE = $(LINTDIR)/dscfg.ln -ROOTLINK = $(ROOTUSRSBIN)/$(PROG) -ROOTSHLINK = $(ROOTUSRSBIN)/$(SHFILES) - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -all: $(SUBDIRS) $(PROG) $(SHFILES) - -install: $(SUBDIRS) all $(ROOTSHFILES) $(ROOTPROG) $(ROOTLINK) $(ROOTSHLINK) - -lint: $(SUBDIRS) lint_PROG - -clean: $(SUBDIRS) - $(RM) *.o - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTPROG) $@ - -$(ROOTSHLINK): $(ROOTUSRSBIN) $(ROOTSHFILES) - -$(RM) $@; $(LN) $(ROOTSHFILES) $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/dscfg/dscfg.c b/usr/src/cmd/avs/dscfg/dscfg.c deleted file mode 100644 index 6e1d583cc0..0000000000 --- a/usr/src/cmd/avs/dscfg/dscfg.c +++ /dev/null @@ -1,894 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/vtoc.h> -#include <sys/stat.h> -#include <stdio.h> -#include <sys/mnttab.h> -#include <errno.h> -#include <limits.h> -#include <fcntl.h> -#include <string.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <time.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> -#include <netdb.h> -#include <ctype.h> -#include <assert.h> - -#include <sys/nsctl/cfg_impl.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> - -#ifdef DEBUG -#include <sys/nsctl/dsw.h> -#endif - -#define DEFAULT_PARSER_LOC "/etc/dscfg_format" - -int Cflg; -int Dflg; -int Lflg; -int aflg; -int iflg; -int lflg; -int nflg; -int pflg; -int rflg; -int sflg; -int uflg; - -int verbose; -int noflags; -int errflg; -int mustcommit; -char *locname; /* config location from cfg_location */ -char *cmdname; - -#define MAX_FILENAME 80 - -char output_file[MAX_FILENAME]; /* specified output file */ -char altroot[MAX_FILENAME]; /* specifed root location */ -char config_file[MAX_FILENAME]; /* specified configuration file */ -char input_file[MAX_FILENAME]; /* specified input file */ -char logical_host[MAX_FILENAME]; /* specified cluster node */ -char device_group[MAX_FILENAME]; /* specified device group name */ - -#define IS_NOT_CLUSTER 1 -#define IS_CLUSTER 2 - -void cfg_invalidate_hsizes(int, const char *); -static int check_cluster(); - -void -usage(char *errmsg) -{ - if (errmsg) - (void) fprintf(stderr, "%s: %s\n", cmdname, errmsg); - (void) fprintf(stderr, - gettext("dscfg \t\t\t\tDisplay location of " - "local configuration database\n")); - (void) fprintf(stderr, gettext("dscfg -l -s path\t\t" - "List contents of configuration database\n")); - (void) fprintf(stderr, gettext( - "\t\t\t\tlocated at path specified\n")); - (void) fprintf(stderr, gettext("dscfg -i\t\t\t" - "Initialize configuration database\n")); - (void) fprintf(stderr, - gettext("dscfg -i -p " -#ifdef DEBUG -"[-n] " -#endif - "/etc/dscfg_format\tFormat configuration database\n")); - (void) fprintf(stderr, - gettext("dscfg -a file\t\t\tRestore configuration " - "database from file\n")); - (void) fprintf(stderr, gettext("\t\t\t\tspecified\n")); - (void) fprintf(stderr, - gettext("dscfg -l\t\t\tList contents of configuration database" - "\n")); - (void) fprintf(stderr, - gettext("dscfg -L\t\t\tDisplay configuration database's\n")); - (void) fprintf(stderr, gettext("\t\t\t\tlock status\n")); - (void) fprintf(stderr, gettext("dscfg -h\t\t\tUsage message\n")); - if (check_cluster() != IS_NOT_CLUSTER) { - (void) fprintf(stderr, gettext("\nSun Cluster Usage\n")); - (void) fprintf(stderr, gettext("******************\n")); - (void) fprintf(stderr, - gettext("dscfg -s path\t\t\tSet cluster " - "configuration database at DID\n")); - (void) fprintf(stderr, gettext("\t\t\t\tpath specified\n")); - (void) fprintf(stderr, gettext("dscfg -D device_group\t\t" - "Check status of cluster device group\n")); - (void) fprintf(stderr, gettext("dscfg -C -\t\t\t" - "Display location of cluster configuration\n")); - (void) fprintf(stderr, gettext("\t\t\t\tdatabase\n")); - (void) fprintf(stderr, gettext("dscfg -l -s DID_device\t\tList " - "the contents of cluster configuration\n")); - (void) fprintf(stderr, gettext("\t\t\t\tdatabase\n")); - (void) fprintf(stderr, gettext("dscfg -C - -i\t\t\tInitialize " - "cluster configuration database\n")); - (void) fprintf(stderr, gettext("dscfg -C - -i -p " - "/etc/dscfg_format Format cluster configuration database\n")); - (void) fprintf(stderr, gettext("dscfg -C - -a file\t\t" - "Restore cluster configuration database from\n")); - (void) fprintf(stderr, gettext("\t\t\t\tfile specified\n")); - (void) fprintf(stderr, gettext("dscfg -C - -l\t\t\t" - "List contents of local configuration database\n")); - (void) fprintf(stderr, gettext("dscfg -C device_group -l\t" - "List configuration database by device group\n")); - (void) fprintf(stderr, gettext("dscfg -C \"-\" -l\t\t\t" - "List configuration database excluding\n")); - (void) fprintf(stderr, gettext("\t\t\t\tdevice groups\n")); - } -} - -int -parse_parse_config(CFGFILE *cfg) -{ - FILE *fp; - char inbuf[CFG_MAX_BUF]; - char *buff; - int rc; - - /* - * Open parser config file, use default if none specified - */ - buff = (input_file[0]) ? input_file : DEFAULT_PARSER_LOC; - if ((fp = fopen(buff, "r")) == NULL) { - (void) fprintf(stderr, - gettext("parser config file (%s) not found\n"), buff); - return (-1); - } - - /* - * start at begining of configration database - */ - cfg_rewind(cfg, CFG_SEC_ALL); - - while (((buff = fgets(inbuf, (sizeof (inbuf) - 1), fp)) != NULL)) { - if (*buff == '#' || *buff == '%') - continue; - /* overwrite newline */ - buff[strlen(buff) - 1] = '\0'; - rc = cfg_update_parser_config(cfg, buff, CFG_PARSE_CONF); - if (rc < 0) { - (void) fprintf(stderr, - gettext("update parser config rc %d key %s\n"), - rc, buff); - (void) fclose(fp); - return (-1); - } - } - (void) fclose(fp); - return (1); -} - -void -parse_text_config(CFGFILE *cfg) -{ - FILE *fp; - char inbuf[CFG_MAX_BUF]; - char *buff; - char *key; - char *p; - int rc; - - if ((fp = fopen(input_file, "r")) == NULL) { - (void) fprintf(stderr, - gettext("Unable to open text config %s\n"), - input_file); - exit(2); - } - bzero(inbuf, sizeof (inbuf)); - cfg_rewind(cfg, CFG_SEC_CONF); - while (((buff = fgets(inbuf, (sizeof (inbuf) - 1), fp)) != NULL)) { - if (*buff == '#') - continue; - /* overwrite newline */ - buff[strlen(buff) - 1] = '\0'; - key = strtok(buff, ":"); - if (!key) { - continue; - } - p = &buff[strlen(key)+2]; - while (*p && isspace(*p)) { - ++p; - } - if (!*p) { - continue; - } - rc = cfg_put_cstring(cfg, key, p, strlen(p)); - if (rc < 0) { - (void) fprintf(stderr, - gettext("update text config failed rc %d key %s"), - rc, buff); - return; - } - bzero(inbuf, sizeof (inbuf)); - } - (void) fclose(fp); -} -void -dump_status(CFGFILE *cfg) -{ - cfp_t *cfp = FP_SUN_CLUSTER(cfg); - - /* - * WARNING will robinson - * The following is using a non-exported internal interface - * to libcfg - * You may not use any of the following fields in MS software - */ - if (!locname) - exit(2); - if (!verbose) - (void) printf("%s\n", locname); - else { -#ifdef DEBUG - (void) printf(gettext("Configuration location: %s\n"), locname); - (void) printf( - gettext("Header info:\n\t\t\tmagic: %x\tstate: %x\n"), - cfp->cf_head->h_magic, cfp->cf_head->h_state); - (void) printf( - gettext("Parser section:\t\t" - "Start: %x\tsize: %d offset: %d\n"), - cfp->cf_mapped, cfp->cf_head->h_parsesize, - cfp->cf_head->h_parseoff); - (void) printf( - gettext("Config section:\t\t" - "Start: %x\tsize:%d\tacsize: %d\n"), - cfp->cf_head->h_cparse, cfp->cf_head->h_csize, - cfp->cf_head->h_acsize); - (void) printf("\t\t\tccopy1: %s\tccopy2: %s\n", - cfp->cf_head->h_ccopy1, - cfp->cf_head->h_ccopy2); - (void) printf( - gettext("Sequence:\t\tseq1: %d\t\tseq2: %d\n"), - cfp->cf_head->h_seq1, cfp->cf_head->h_seq2); -#endif - } -} - -void -dump_lockstat(CFGFILE *cfg) -{ - pid_t pid; - CFGLOCK lock; - char ps_str[1024]; - - if (cfg_get_lock(cfg, &lock, &pid) == TRUE) { - (void) printf("%s %ld\n", - lock == CFG_RDLOCK ? - gettext("Read locked by process id") : - gettext("Write locked by process id"), - pid); - (void) sprintf(ps_str, "ps -p %ld", pid); - system(ps_str); - } else - (void) printf("%s\n", gettext("Not locked.")); -} - - -/* - * dump current configuration section to stdout - */ - -void -print_config(CFGFILE *cfg) -{ - time_t tloc = 0; - int set = 0; - char pconfig[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - char *cp, pbuf[CFG_MAX_BUF]; - FILE *fp; - int rc; - int end; - - (void) snprintf(pconfig, sizeof (pconfig), - "%s%s", altroot, DEFAULT_PARSER_LOC); - if ((fp = fopen(pconfig, "r")) == NULL) { - (void) fprintf(stderr, - gettext("dscfg: unable to open " - "parser configuration (%s): %s\n"), - pconfig, strerror(errno)); - exit(1); - } - - (void) time(&tloc); - (void) printf(gettext("# Consolidated Dataservice Configuration\n")); - (void) printf(gettext("# Do not edit out whitespace or dashes\n")); - (void) printf(gettext("# File created on: %s"), ctime(&tloc)); - - while (fgets(pbuf, (sizeof (pbuf) - 1), fp) != NULL) { - if (pbuf[0] == '#') { - /* comment */ - continue; - } - /* force a NULL terminator */ - pbuf[sizeof (pbuf) - 1] = '\0'; - - if (pbuf[0] == '%') { - /* - * descriptive text - * - print it (with comment leader) and move on - */ - (void) printf("#%s", &pbuf[1]); - continue; - } - - /* - * truncate the parser config in pbuf[] to just the tag - */ - cp = strchr(pbuf, '.'); - if (cp != NULL) { - *cp = '\0'; - } - - set = 1; - /*CONSTCOND*/ - while (1) { - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, - sizeof (key), "%s.set%d", pbuf, set); - rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); - if (rc < 0) { - break; - } - /* trim trailing space if necessary */ - end = strlen(buf) - 1; - if (buf[end] == ' ') - buf[end] = '\0'; - - (void) printf("%s:%s\n", pbuf, buf); - set++; - } - } - - (void) fclose(fp); -} - -int -make_new_config(const char *fileloc) -{ - int fd; - int rc; - int skip; - - char buf[CFG_MAX_BUF]; - /*CONSTCOND*/ - assert((sizeof (buf) % 512) == 0); - - bzero(buf, CFG_MAX_BUF); - - if ((fd = open(fileloc, O_RDWR | O_CREAT, 0640)) == -1) { - return (-1); - } - - /* if this is a device, we may have to skip the vtoc */ - if ((skip = cfg_shldskip_vtoc(fd, fileloc)) == -1) { - (void) fprintf(stderr, - gettext("dscfg: unable to read vtoc on (%s)\n"), - fileloc); - return (-1); - } else if (skip) { - do { - rc = lseek(fd, CFG_VTOC_SKIP, SEEK_SET); - } while (rc == -1 && errno == EINTR); - - if (rc == -1) { - (void) fprintf(stderr, gettext("dscfg: seek error")); - return (-1); - } - } - - do { - rc = write(fd, buf, sizeof (buf)); - } while (rc == -1 && errno == EINTR); - - close(fd); - - return ((rc < 0) ? 0 : 1); -} - -/* - * dscfg - * configure or return dataservice persistent configuration - * - * options - * -i initialize file for first time - * -l dump current configuration to stdout in ascii - * -a add - * -C node Set resource filter - * -p parser config specified input file - * -s set partition location or filename in default location - * -L print configuration lock status - * -u upgrade - * -r prepend bootdir to beginning of path for cfg_open - * no options status - * - * - */ -#ifdef lint -int -dscfg_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - CFGFILE *cfg; - extern char *optarg; - char *loc; - int offset = 0; - int rc; - char c; - int local; - int action_counts = 0; - - bzero(input_file, sizeof (input_file)); - (void) setlocale(LC_ALL, ""); - (void) textdomain("dscfg"); - logical_host[0] = '\0'; - cmdname = argv[0]; -#ifdef DEBUG - while ((c = getopt(argc, argv, "a:C:dD:ilLp:r:s:hvn")) != EOF) { -#else - while ((c = getopt(argc, argv, "a:C:dD:ilLp:r:s:h")) != EOF) { -#endif - switch (c) { - case 'a': - aflg++; - strcpy(input_file, optarg); - mustcommit++; - action_counts++; - break; - case 'C': - Cflg++; - strcpy(logical_host, optarg); - if (logical_host && *logical_host == '-') - if (argc == 3) - action_counts++; - break; - case 'D': - Dflg++; - strcpy(device_group, optarg); - action_counts++; - break; - case 'i': - iflg++; - mustcommit++; - action_counts++; - break; - case 'l': - lflg++; - action_counts++; - break; - case 'L': - Lflg++; - action_counts++; - break; - case 'p': - pflg++; - strcpy(input_file, optarg); - mustcommit++; - break; - case 's': - sflg++; - strcpy(config_file, optarg); - action_counts++; - break; - case 'h': - usage(NULL); - exit(0); - /*NOTREACHED*/ -#ifdef DEBUG - case 'v': - verbose++; - action_counts++; - break; -#endif -#ifdef UPGRADE - case 'u': - uflg++; - action_counts++; - break; -#endif - - case 'r': - rflg++; - strcpy(altroot, optarg); - break; - - case 'n': - nflg++; - break; - - default: - usage(NULL); - exit(1); - break; - }; - } - - switch (action_counts) { - case 0: - if (argc > 1) { - if (pflg) - usage(gettext( - "-p option must be used in conjunction with -i")); - else - usage(gettext("must specify an action flag")); - exit(1); - } - break; - case 1: - break; - case 2: - if (lflg && sflg) - break; - else { - usage(gettext("too many action flags")); - exit(1); - break; - } - default: - usage(gettext("too many action flags")); - exit(1); - break; - } - - if (argc == 1 || (argc == 2 && verbose) || (argc == 3 && (rflg|Cflg))) - noflags++; - - if (Dflg) { - /* - * Determine if the value specified is a device group - * that is active on this node - */ - char *other_node; - if ((cfg_issuncluster() > 0) && (strlen(device_group) > 0)) { - local = cfg_dgname_islocal(device_group, &other_node); - if (local == 0) - (void) fprintf(stderr, gettext( - "Device group %s active on %s\n"), - device_group, other_node); - else if (local == 1) - (void) fprintf(stderr, gettext( - "Device group %s active on this node\n"), - device_group); - else - (void) fprintf(stderr, gettext( - "Device group %s not found\n"), device_group); - return (local); - } else { - (void) fprintf(stderr, gettext( - "dscfg -D is only allowed in " - "Sun Cluster OE\n")); - return (0); - } - } - - if (sflg && !lflg) { - /* - * Only allow setting location on a non-sun cluster system - * if the cluster reference file is already present. - */ - struct stat dscfg_stat = {0}; - if (cfg_issuncluster() <= 0) { - if (stat(CFG_CLUSTER_LOCATION, &dscfg_stat) != 0) { - if (dscfg_stat.st_blocks == 0) { - (void) fprintf(stderr, gettext( - "dscfg -s is only allowed in " - "Sun Cluster OE\n")); - exit(1); - } - } - } - - spcs_log("dscfg", NULL, gettext("dscfg -s %s"), config_file); - locname = cfg_location(config_file, CFG_LOC_SET_CLUSTER, - rflg ? altroot : NULL); - if (locname == NULL) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(NULL)); - exit(1); - } else - exit(0); - - } else if (sflg && lflg) { - /* s used with l for temporarily peeking at a dscfg database */ - loc = config_file; - } else { - locname = cfg_location(NULL, - Cflg ? CFG_LOC_GET_CLUSTER : CFG_LOC_GET_LOCAL, - rflg ? altroot : NULL); - if (Cflg && (locname == NULL)) { - (void) fprintf(stderr, gettext( - "dscfg: cluster config not set: %s\n"), - cfg_error(NULL)); - return (1); - } - loc = rflg ? locname : NULL; - } - - /* - * the following hack forces the configuration file to initialize - */ - if (iflg && !pflg) { - int fild; - int c; - char buf[CFG_MAX_BUF] = {0}; - cfp_t *cfp; - - if (!nflg) { - (void) printf( - gettext("WARNING: This option will erase your " - "Availability Suite configuration\n")); - (void) printf( - gettext("Do you want to continue? (Y/N) [N] ")); - - c = getchar(); - switch (c) { - case 'y': - case 'Y': break; - case 'n': - case 'N': - case '\n': - (void) fprintf(stderr, gettext( - "dscfg: configuration not initialized\n")); - exit(1); - default: - (void) fprintf(stderr, gettext( - "dscfg: %d is not a valid response\n"), c); - exit(1); - } - } - - spcs_log("dscfg", NULL, gettext("dscfg -i")); - - if ((cfg = cfg_open(loc)) == NULL) { - /* this is not a good config, or non-existent so.. */ - if (!make_new_config(locname)) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(NULL)); - exit(1); - } - if ((cfg = cfg_open(loc)) == NULL) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(NULL)); - exit(1); - } - } - - /* - * Set cluster node if specified - */ - if (Cflg) - cfg_resource(cfg, logical_host); - - if (cfg_is_cfg(cfg) != 1) { - if (!make_new_config(locname)) { - (void) fprintf(stderr, gettext("dscfg: unable " - " to create new config \n")); - exit(1); - } - } - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(NULL)); - exit(1); - } - - cfp = FP_SUN_CLUSTER(cfg); - if ((fild = cfp->cf_fd) == 0) { - (void) fprintf(stderr, - gettext("dscfg: failure to access %s " - "configuration database: %s\n"), - (Cflg) ? gettext("cluster") : gettext("local"), - cfg_error(NULL)); - exit(1); - } - - if (cfg_shldskip_vtoc(fild, locname) > 0) - offset += CFG_VTOC_SKIP; - - lseek(fild, offset, SEEK_SET); - write(fild, buf, sizeof (buf)); - cfg_invalidate_hsizes(fild, locname); - - cfg_close(cfg); - exit(0); - } - - if (pflg && !iflg) { - usage(gettext("-p option must be used in conjunction with -i")); - exit(1); - - } - - if (uflg) { - char cmd[CFG_MAX_BUF]; - if (rflg) - (void) snprintf(cmd, sizeof (cmd), - "%s/usr/sbin/dscfg -r %s -l >" - " %s/var/tmp/.dscfg.bak", altroot, - altroot, altroot); - else - (void) snprintf(cmd, sizeof (cmd), - "/usr/sbin/dscfg -l >" - " /var/tmp/.dscfg.bak"); - - if (system(cmd) != 0) { - (void) fprintf(stderr, - "dscfg: unable to create backup\n"); - exit(1); - } - - if ((cfg = cfg_open(loc)) == NULL) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(NULL)); - exit(2); - } - - if (!cfg_lock(cfg, CFG_UPGRADE)) { - (void) fprintf(stderr, - gettext("dscfg: upgrade failed\n")); - cfg_close(cfg); - exit(1); - } - - cfg_close(cfg); - exit(0); - } - - if ((cfg = cfg_open(loc)) == NULL) { - (void) fprintf(stderr, gettext("dscfg: %s\n"), cfg_error(NULL)); - exit(2); - } - - /* - * Set cluster node if specified - */ - if (Cflg) - cfg_resource(cfg, logical_host); - - if ((!pflg) && (!noflags)) { - if (cfg_is_cfg(cfg) != 1) { - (void) fprintf(stderr, - gettext("dscfg: %s\n"), cfg_error(NULL)); - cfg_close(cfg); - exit(1); - } - } - - if (Lflg) { - dump_lockstat(cfg); - cfg_close(cfg); - exit(0); - } - - if (noflags) { - dump_status(cfg); - cfg_close(cfg); - exit(0); - } - - if (!cfg_lock(cfg, mustcommit? CFG_WRLOCK : CFG_RDLOCK)) { - (void) fprintf(stderr, gettext("cfg_lock: lock failed\n")); - cfg_close(cfg); - exit(1); - } - - if (lflg) { - print_config(cfg); - cfg_close(cfg); - exit(0); - } - - /* - * initialize configuration - */ - if (iflg) { - spcs_log("dscfg", NULL, gettext("dscfg -i -p %s"), input_file); - - if (!pflg) { - (void) fprintf(stderr, - gettext("dscfg: cannot init without " - "parser configuration file\n")); - cfg_close(cfg); - exit(1); - } else if (parse_parse_config(cfg) < 0) { - (void) fprintf(stderr, gettext("dscfg: cannot load " - "parser configuration file\n")); - cfg_close(cfg); - exit(1); - } - } - - /* - * read asci config file and write - */ - if (aflg) { - spcs_log("dscfg", NULL, gettext("dscfg -a %s"), input_file); - parse_text_config(cfg); - } - - if (mustcommit) { - rc = cfg_commit(cfg); - if (rc < 0) { - int sev = 0; - (void) fprintf(stderr, gettext("dscfg: %s\n"), - cfg_error(&sev)); - if (sev == CFG_EFATAL) { - cfg_close(cfg); - exit(2); - } - } - } - - cfg_close(cfg); - return (0); -} - -static int -check_cluster() -{ - static int is_cluster = -1; - int rc; - - if (is_cluster != -1) - return (is_cluster); - rc = cfg_iscluster(); - if (rc > 0) { - is_cluster = IS_CLUSTER; - return (is_cluster); - } else if (rc == 0) { - is_cluster = IS_NOT_CLUSTER; - return (is_cluster); - } else { - (void) fprintf(stderr, - gettext("dscfg: unable to determin environment\n")); - /*NOTREACHED*/ - } - - /* gcc */ - return (is_cluster); -} diff --git a/usr/src/cmd/avs/dscfg/dscfgadm.sh b/usr/src/cmd/avs/dscfg/dscfgadm.sh deleted file mode 100644 index 736a89b2a2..0000000000 --- a/usr/src/cmd/avs/dscfg/dscfgadm.sh +++ /dev/null @@ -1,1547 +0,0 @@ -#!/usr/bin/ksh -# 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. -# - -typeset -r PROG=$(basename $0) -typeset -r CTAG_NULL="-" - -# -# help message -# -help() -{ - $xopt - - cluster_configured - CLUSTER_CONFIGURED=$? - - echo "\ -usage: - $PROG - $PROG -i - $PROG -e [-r][-p] - $PROG -d [-r]" >&2 - if [ $CLUSTER_CONFIGURED -eq 1 ]; then - echo "\ - $PROG -s" >&2 - fi - - echo "\ - -i : display information on the Availability Suite services - -e : enable Availability Suite services (all, by default) - -d : disable Availability Suite services (all, by default) - -r : enable/disable Remote Mirror - -p : enable Point in Time Copy" >&2 - if [ $CLUSTER_CONFIGURED -eq 1 ]; then - echo "\ - -s : set the location of the cluster configuration database" >&2 - fi - echo "\ - -x : turn on script debugging (may be used with any valid option) - - When executed with no options or with nothing but -x, $PROG runs in - interactive fashion, allowing the user to initialize the local (and - if applicable, the cluster) configuration database, and to start the - Availability Suite services." >&2 - - exit 2 -} - -########################## SET GLOBAL VARIABLES ###################### - -# root directory -PKG_INSTALL_ROOT="" -export PKG_INSTALL_ROOT - -# set lib path -LD_LIBRARY_PATH=/usr/lib:/usr/lib -export LD_LIBRARY_PATH - -# set dscfg -DSCFG="/usr/sbin/dscfg" -export DSCFG - -# set parser config location -PCONFIG="/etc/dscfg_format" -export PCONFIG - -# set local dscfg location -export LOCAL_DSCFG="/etc/dscfg_local" - -# set cluster dscfg reference file -export CLUSTER_REF="/etc/dscfg_cluster" - -# a service that has a dependency on us -FS_LOCAL_SVC="svc:/system/filesystem/local" - -NODELIST="/tmp/nodelist" -DSCFGLOCKDCF="/etc/dscfg_lockdb" -DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" - -# SMF defines -MANIFEST_PATH=/lib/svc/manifest/system - -# SMF services (enable and disable) -SMF_ENABLE="nws_scm nws_sv nws_ii nws_rdc nws_rdcsyncd" -SMF_DISABLE="nws_rdcsyncd nws_rdc nws_ii nws_sv nws_scm" - -# state of each service -nws_scm_enabled=0 -nws_sv_enabled=0 -nws_ii_enabled=0 -nws_rdc_enabled=0 -nws_rdcsyncd_enabled=0 - -# set path -PATH=/usr/bin:/usr/sbin:/sbin/sh -export PATH - -# set architecture -ARCH=`uname -p` -export ARCH -OS_MINOR=`uname -r | cut -d '.' -f2` - -# number of sectors required for database -# 1024*1024*5.5/512 -REQUIRED=11264 - -# must set here, else seen as null in MAIN -VALID_DB_ENTERED=0 - -NO_ARGS=0 - -# for debugging -xopt= - -# set lengthy message here -CLUST_LOC_MESS="The current location is invalid for a Sun StorageTek \ -Data Services configuration database. Once a valid location is \ -entered (raw slice on \"did\" device), you may upgrade the existing \ -database to this new location - following the procedure outlined \ -in the Installation and Configuration Guide." - -########################## SET GLOBAL VARIABLES ###################### - - -########################## ERROR #################################### - -# called with optional error msg $1 -# prints basic guidelines for configuration of the database location -error() -{ - $xopt - - echo >&2 - echo "INSTALLATION ERROR" >&2 - echo "Error: $1" >&2 - echo >&2 - in_cluster - - if [ $? -eq 1 ]; then - echo "GENERAL INSTALLATION RULES:" >&2 - echo "\tBecause you are installing on a cluster," >&2 - echo "\tthe database must be located on a raw slice of a did device.">&2 - echo "\t e.g. /dev/did/rdsk/d17s1" >&2 - fi - # let? - MB=`expr $REQUIRED / 2 / 1024` - echo "\t$REQUIRED sectors ($MB MBs) are required for the database." >&2 -} - -########################## ERROR #################################### - -########################## ALL LOCATION TESTS ######################## - -# sets numerous environment variables describing the state of the system -get_system_state() -{ - $xopt - - valid_local_dscfg_exists - VALID_LOCAL_DB=$? - OLD_VALID_LOCAL_DB=$VALID_LOCAL_DB - - in_cluster - IN_CLUSTER=$? - - cluster_configured - CLUSTER_CONFIGURED=$? - - if [ $IN_CLUSTER = 1 ]; then - valid_cluster_dscfg_exists - VALID_CLUSTER_DB=$? - OLD_VALID_CLUSTER_DB=$VALID_CLUSTER_DB - else - VALID_CLUSTER_DB=0 - fi -} - -# Checks if in cluster -# returns 1 if in cluster, else 0 -# -in_cluster() -{ - $xopt - - if [ -x /usr/sbin/clinfo ]; then - clinfo - if [ $? -eq 0 ]; then - return 1 - else - return 0 - fi - else - return 0 - fi -} - -# checks if a system is configured as a cluster -# returns 1 if configured as a cluster, 0 if not -# -cluster_configured() -{ - $xopt - - if [ -f /etc/cluster/nodeid ]; then - return 1 - else - return 0 - fi -} - -# Check the list of Sun Cluster device groups known in the dscfg, determing -# if they are currently enabled on this Sun Cluster node. If so, fail allowing -# the system administator to scswitch them elsewhere. -# -check_device_groups() -{ - $xopt - - if [ $VALID_CLUSTER_DB == 1 ]; then - DEVICE_GROUPS=`$DSCFG -s $FILE_LOC -l 2>/dev/null | \ - grep "^dsvol:" | cut -d' ' -f3 | sort | uniq | xargs` - for x in $DEVICE_GROUPS - do - $DSCFG -D $x 2>/dev/null - if [ $? -eq 1 ] - then - IN_USE="$IN_USE $x" - fi - done - - if [ -n "$IN_USE" ] - then - print "The following Sun Cluster device groups are in use " - print "by Availability Suite on this node." - print "" - print "$IN_USE" - print "" - print "'scswitch' them to another Sun Cluster node before " - print "attempting to disable any data services." - return 1 - else - return 0 - fi - fi - - return 0 -} - -# checks to see if this is a char device in the -# /dev/did/rdsk directory returns 1 if so. -# -is_did_device() -{ - $xopt - - DID=`echo $1 | awk -F/ '{print $3}'` - RDSK=`echo $1 | awk -F/ '{print $4}'` - - if [ "did" = $DID -a "rdsk" = $RDSK -a -c $1 ]; then - return 1 - else - return 0 - fi -} - -# -# checks size of area for db location -# -check_size() -{ - $xopt - - # if in cluster look for d*s* - SLICE=`echo $1 | sed -n 's/.*d.*s\(.*\)/\1/p'` - - SECTORS=`prtvtoc $1 | tr -s ' '| grep "^ $SLICE " | awk '{print $5}'` - - if [ -z "$SECTORS" ]; then - echo "SLICE at $1 not found on this device" - return 0 - fi - - # if required size is greater than space available, then fail - if [ $REQUIRED -gt $SECTORS ]; then - return 0 - else - return 1 - fi -} - -# looks in dscfg_cluster reference file. if a location is configured, -# tests to see if it is a valid database. if so, returns 1 -# -valid_cluster_dscfg_exists() -{ - $xopt - - if [ -s $CLUSTER_REF ]; then - FILE_LOC=`head -1 $CLUSTER_REF` - contains_data $FILE_LOC - return $? - else - return 0 - fi -} - - -# checks for the existence of dscfg_local database, and if it exists, -# tests to see if it is a valid database. if so, returns 1 -# -valid_local_dscfg_exists() -{ - $xopt - - if [ -s $LOCAL_DSCFG ]; then - contains_data $LOCAL_DSCFG - return $? - else - return 0 - fi -} - -# used to test if a valid DS config database exists on machine already -# MAGIC_STRING is the top line in the config used in v3.1 & v3.2 -# -contains_data() -{ - $xopt - - # dscfg distinct strings, varies on the architecture - if [ $ARCH = "sparc" ] - then - MAGIC_STRING="MAGI" - elif [ $ARCH = "i386" ] - then - MAGIC_STRING="IGAM" - fi - - # Create a PID unique temporary file - TMP_FILE=/tmp/$$ - - # Write the first or 16th block (skipping over VTOC) to - # the TMP_FILE, then scan for the presence of the "MAGI" - # - for offset in 0 16 - do - if [ ! -z "$1" ]; then - dd if=$1 of=$TMP_FILE count=1 iseek=$offset 2>/dev/null - FILECONTENTS=`strings $TMP_FILE | head -1 2>/dev/null` - if [ `echo $FILECONTENTS | grep -c "$MAGIC_STRING"` -gt 0 ]; then - rm $TMP_FILE - return 1 - fi - fi - done - - rm $TMP_FILE - return 0 -} - -########################## ALL LOCATION TESTS ######################## - - -########################## MAIN FUNCTIONS ############################ - -# since location already has been set, asks what to do now? keeping -# it still checks the size (since an upgrade from 3.0 may still be -# occuring) and also checks if was an old cluster config on disallowed -# /dev/did/dsk directory -# -# returns: -# 0 if cluster location is invalid or the user does not want to keep it -# 1 if the location is valid and the user wants to keep it. -# -keep_it() -{ - $xopt - - NOTE="\nThe Sun StorageTek Data Services database configuration" - NOTE="$NOTE location has already been set." - echo $NOTE - - echo "\nCurrent location: $PKG_INSTALL_ROOT$FILE_LOC" - - QUEST="Would you like to preserve the existing configuration" - QUEST="$QUEST information at its current location? " - - ANS=`ckyorn -Qd n -p "$QUEST"` - - case $ANS in - y|Y|yes|YES|Yes) - #Since the user has said "yes I want to keep this current one" - #it may actually be a 3.x database, which only required 4.5mb - #space, so now will check that there is room to grow another 1mb" - check_location $FILE_LOC - if [ $? = 0 ]; then - error "$CLUST_LOC_MESS" - return 0 - else - OLD_FILE_LOC=$FILE_LOC - FILE_LOC=$NULL - return 1 - fi - ;; - *) - return 0 - ;; - esac -} - -# -# asks if user wants to keep existing db information, overwrite with -# a new db, or view the contents, and be asked again... -# returns: -# 0 if old location is bad -# 1 if old location is good -# -preserve_overwrite_maybe() -{ - $xopt - - echo "\nIt appears a valid database configuration exists here already." - - while true - do - SAFE_LOC=$FILE_LOC - - echo "\nWould you like to preserve this information and continue?" - echo "\ty - preserve current configuration" - echo "\tn - overwrite with new configuration" - echo "\tmaybe - view contents of current configuration" - - ANS=`ckkeywd -Q y n maybe` - case $ANS in - y) - check_location $FILE_LOC - if [ $? = 0 ]; then - error "$CLUST_LOC_MESS" - return 0 - else - $DSCFG -s "$FILE_LOC" -C $CTAG_NULL >/dev/null 2>&1 - OLD_FILE_LOC=$FILE_LOC - FILE_LOC=$NULL - return 1 - fi - ;; - n) - check_location $FILE_LOC - if [ $? = 0 ]; then - error "$CLUST_LOC_MESS" - return 0 - else - return 1 - fi - ;; - - maybe) - # print contents of this db config. - echo "\nContents of database configuration found at $SAFE_LOC are:" - $DSCFG -l -s "$FILE_LOC" | more - FILE_LOC=$SAFE_LOC - continue - ;; - esac - done -} - -# gets location from user -# -get_location() -{ - $xopt - - #Checks for absolute path name, and if file name and file doesn't - #exist, creates it. - echo "\n\n----------ENTER DATABASE CONFIGURATION LOCATION-----------------" - echo "Note: Please ensure this location meets all requirements specified" - echo "in the Availability Suite Installation Guide." - - FILE_LOC=`ckpath -artwQ -p "Enter location:"` - if [ $? = 1 ] - then - exit 1 - fi - - # allow non-root user to access for least privileges - chmod 666 $FILE_LOC -} - - -# -# tests for proper config -# -# returns: -# 0 if bad location -# 1 if good location -# -check_location() -{ - $xopt - - # set to FILE_LOC - LOCATION=$1 - - did_clust_msg="You are in cluster and $LOCATION is not valid DID device" - - # Set "actual file location" variable here to equal file location - # entered by user because getting here means contains_data was already - # successfully called before and now the two can equal each other for - # future testing. - - SAFE_LOC=$FILE_LOC - - if [ $IN_CLUSTER = 1 -o $CLUSTER_CONFIGURED = 1 ]; then - if [ -b "$LOCATION" ] || [ -c "$LOCATION" ]; then - is_did_device $LOCATION - if [ $? = 0 ]; then - error "$did_clust_msg" - return 0 - fi - else - error "$did_clust_msg" - return 0 - fi - else - echo "Location may not be changed in a non Sun Cluster OE." 2>&1 - return 0 - fi - - check_size $LOCATION - - if [ $? != 1 ]; then - error "$LOCATION does not meet minimum space requirement." - return 0 - else - return 1 - fi -} - -# -# Notifies the user that the SMF services are online, -# and gives him the option to disable the services before proceeding. If -# the services are not disabled, the program cannot proceed with setting -# a new dscfg location. -# -ask_to_disable() -{ - $xopt - - echo "\ -\nYour services must be disabled before a new configuration location is set.\n" - - QUEST="Would you like to disable the services now and continue with the" - QUEST="$QUEST Availability Suite setup? " - - ANS=`ckyorn -Qd n -p "$QUEST"` - - case $ANS - in y|Y|yes|YES|Yes) - return 1 - ;; - *) - return 0 - ;; - esac -} - -# -# Asks the user if he would like to enable the services now. If so, -# import them (if necessary) and enable them. -# -ask_to_enable() -{ - $xopt - - echo "\ -\nIf you would like to start using the Availability Suite immediately, you may -start the SMF services now. You may also choose to start the services later -using the $PROG -e command." - - QUEST="Would you like to start the services now? " - - ANS=`ckyorn -Qd n -p "$QUEST"` - - case $ANS - in y|Y|yes|YES|Yes) - return 1 - ;; - *) - return 0 - ;; - esac -} - -# -# display information about the system -# -display_info() -{ - $xopt - - typeset grp_error_flg=0 - typeset -L15 svc state en SVC="SERVICE" STATE="STATE" EN="ENABLED" - echo "$SVC\t$STATE\t$EN" - - for i in $SMF_ENABLE - do - is_imported $i - if [ $? = 1 ] - then - state=`svcprop -c -p restarter/state \ - svc:/system/${i}:default` - en=`svcprop -c -p general/enabled \ - svc:/system/${i}:default` - check_fs_local_grouping $i - if [ $? -ne 0 ] - then - svc="${i}***" - grp_error_flg=$((grp_error_flg + 1)) - else - svc=$i - fi - - echo "$svc\t$state\t$en" - fi - done - - print "\nAvailability Suite Configuration:" - printf "Local configuration database: " - if [ $VALID_LOCAL_DB = 1 ] - then - print "valid" - else - print "invalid" - fi - - if [ $CLUSTER_CONFIGURED = 1 ] - then - printf "cluster configuration database: " - if [ $VALID_CLUSTER_DB = 1 ] - then - print "valid" - print "cluster configuration location: ${FILE_LOC}" - else - print "invalid" - fi - fi - - if [ $grp_error_flg -gt 0 ] - then - typeset p - typeset p_has - if [ $grp_error_flg -gt 1 ] - then - p="s" - p_has="have" - else - p="" - p_has="has" - fi - - printf "\n*** Warning: The service$p above $p_has an incorrect " - printf "dependency. To repair the\n" - printf "problem, run \"dscfgadm\".\n" - fi -} - -# -# initialize the local configuration database (only called if none exists) -# returns 0 if successful, 1 if failed -# -initialize_local_db() -{ - $xopt - - echo "Could not find a valid local configuration database." - echo "Initializing local configuration database..." - echo y | ${DSCFG} -i > /dev/null 2>&1 - ${DSCFG} -i -p ${PCONFIG} > /dev/null 2>&1 - - # Make sure the new location is initialized properly - valid_local_dscfg_exists - VALID_LOCAL_DB=$? - if [ $VALID_LOCAL_DB != 1 ] - then - echo "Unable to initialize local configuration database" >&2 - return 1 - else - echo "Successfully initialized local configuration database" - fi - - return 0 -} - -# -# initialize the cluster configuration database, if necessary -# returns 0 if successful, 1 if failed -# -initialize_cluster_db() -{ - $xopt - - if [ ! -n "$FILE_LOC" ] - then - return 0 - fi - - echo "Initializing cluster configuration database..." - ${DSCFG} -s ${FILE_LOC} -C $CTAG_NULL > /dev/null 2>&1 - echo y | ${DSCFG} -i -C $CTAG_NULL > /dev/null 2>&1 - ${DSCFG} -i -p ${PCONFIG} -C $CTAG_NULL > /dev/null 2>&1 - - # make sure the cluster db is valid now - valid_cluster_dscfg_exists - VALID_CLUSTER_DB=$? - if [ $VALID_CLUSTER_DB != 1 ] - then - echo "Unable to initialize cluster configuration database" >&2 - return 1 - else - echo "Successfully initialized cluster configuration database" - fi - - return 0 - -} - -# -# prompt the user for a config location and set AVS to use that location -# -set_cluster_config() -{ - -$xopt - -REPEAT=0 -while [ $REPEAT -eq 0 ]; do - # See if user has entered location already, and it was an existing - # db. Retruns FILE_LOC value - if [ $VALID_DB_ENTERED = 1 ]; then - - # reset - VALID_DB_ENTERED=0 - preserve_overwrite_maybe - - # if 1, location passes, and FILE_LOC being passed to end, else - # set VALID_CLUSTER_DB to 0 since the "valid one" isn't valid anymore - # (bad size, etc) thereby when looping go straight to get_location - if [ $? = 1 ]; then - REPEAT=1 - continue - else - VALID_CLUSTER_DB=0 - continue - fi - fi - - # if 1, then valid db exists, now see what user wants to do - if [ $VALID_CLUSTER_DB = 1 ]; then - SAFE_LOC=$FILE_LOC - keep_it - - # if 0, then user can't or won't keep location. set PROMPT - # so we will get new location from user. - if [ $? = 0 ]; then - PROMPT=0 - else - PROMPT=1 - fi - fi - - # if either are 0, then user wants or needs new db as outlined in - # earlier comments - if [ $VALID_CLUSTER_DB = 0 ] || [ $PROMPT = 0 ]; then - # - # We cannot proceed if the services are running. Give the user - # a chance to stop the services. If he chooses not to, bail. - # - check_enabled - if [ $? = 1 ] - then - show_enabled - ask_to_disable - if [ $? = 0 ] - then - echo "A new configuration location was not set." - exit 1 - else - disable_services - if [ $? != 0 ] - then - exit 1 - fi - fi - - fi - - get_location - contains_data $FILE_LOC - - # if 1, then user entered an existsing db location, loop - # back to ask what to do with it - if [ $? = 1 ]; then - VALID_DB_ENTERED=1 - continue - else - check_location $FILE_LOC - - # if 0, that means location has failed, loop and - # get_location again - if [ $? = 0 ]; then - VALID_CLUSTER_DB=0 - continue - fi - # entered location passes tests - REPEAT=1 - continue - fi - else - # user wants to leave location where and how it is - # FILE_LOC being passed all the way to end - REPEAT=1 - continue - fi -done - -} - -########################## MAIN FUNCTIONS ############################ - -######################## SMF HELPER FUNCTIONS ######################## -# -# check if any SMF service is online (enabled) -# -check_enabled() -{ - $xopt - typeset ret=0 - typeset svc - - for svc in $SMF_ENABLE - do - is_enabled $svc - eval ${svc}_enabled=$? - ret=$((ret | ${svc}_enabled)) - done - - return $ret -} - -# -# Display which services are enabled. (Must be called after check_enabled) -# -show_enabled() -{ - $xopt - typeset svc - - echo "\nThe following Availability Suite services are enabled:" - - for svc in $SMF_ENABLE - do - if (( ${svc}_enabled == 1 )) - then - printf "$svc " - fi - done - - echo "" -} - - -# -# check if the given SMF service is online (enabled) -# -# $1: service name to check for -# -is_enabled() -{ - $xopt - typeset en - - is_imported $1 - if [ $? = 1 ] - then - en=`svcprop -c -p general/enabled svc:/system/${1}:default` - if [ $en = "true" ] - then - return 1 - fi - fi - - return 0 - -} - -# -# If necessary, flag no dependency check -# -no_depend_check() -{ - $xopt - typeset pid - typeset msg=0 - - if [ $OS_MINOR -lt 11 ] - then - if [ -f $DSCFG_DEPEND_NOCHK ] - then - pid=`cat $DSCFG_DEPEND_NOCHK` - echo "Another dscfgadm disable is in progress." - echo "Waiting for pid: $pid to terminate..." - - while [ -f $DSCFG_DEPEND_NOCHK ] - do - if (( msg && (msg % 6 == 0))) - then - printf "\nAnother dscfgadm disable " - printf "(pid: $pid) still appears to " - printf " be in progress.\n" - printf "If this is not the case, you " - printf "may remove " - printf "$DSCFG_DEPEND_NOCHK.\n" - fi - sleep 5 - msg=$((msg + 1)) - done - fi - - touch $DSCFG_DEPEND_NOCHK - echo $$ >> $DSCFG_DEPEND_NOCHK - fi -} - -# -# If necessary, remove the no dependency check flag -# -rm_no_depend_check() -{ - $xopt - if [ $OS_MINOR -lt 11 ] - then - rm -f $DSCFG_DEPEND_NOCHK - fi -} - -# -# set the filesystem/local dependency type and refresh -# -# $1: service name -# $2: either "require_all" or "optional_all" -# -set_fs_local_grouping() -{ - $xopt - typeset svc=$1 - typeset dep_group=$2 - - # set proper dependency type for fs-local - if [ $svc != nws_rdcsyncd ]; then - svccfg -s $FS_LOCAL_SVC setprop \ - ${svc}-local-fs/grouping=$dep_group - if [ $? -ne 0 ] - then - printf "command failed: svccfg -s $FS_LOCAL_SVC " - printf "setprop ${svc}-local-fs/grouping=$dep_group " - printf ">&2\n" - return 1 - fi - - # we need local-fs to know about the new grouping attributes - svcadm refresh ${FS_LOCAL_SVC}:default - if [ $? -ne 0 ] - then - print "Failed to refresh ${FS_LOCAL_SVC} >&2" - return 1 - fi - fi - - return 0 -} - -# -# check if the grouping dependency type for filesystem/local is correct -# -# input: -# $1: service name -# -# returns: -# 0 if the setting is correct -# 1 if the setting is incorrect -# outputs: sets CORRECT_GROUPING with the value of what the grouping should be. -# -check_fs_local_grouping() -{ - $xopt - typeset svc=$1 - typeset cur_grouping - - if [ $svc = nws_rdcsyncd ] - then - return 0 - fi - - # If it's not imported, we just return success, since we don't want - # further processing - is_imported $svc - if [ $? = 0 ] - then - return 0 - fi - - # get the current grouping value from the repository - cur_grouping=`svcprop -c -p ${svc}-local-fs/grouping $FS_LOCAL_SVC` - - # Figure out what the grouping should be (based on enabled status) - is_enabled $svc - if [ $? = 1 ] - then - CORRECT_GROUPING="require_all" - else - CORRECT_GROUPING="optional_all" - fi - - if [ "$cur_grouping" != "$CORRECT_GROUPING" ] - then - # grouping is incorrect - return 1 - else - # grouping is just fine - return 0 - fi -} - -# -# enable/disable the given SMF service. Also, update the filesystem-local -# dependency, if appropriate. -# -# $1: service name to check for -# $2: "enable" or "disable" -# -svc_operation() -{ - $xopt - typeset svc=$1 - typeset command=$2 - typeset enable_state - typeset dep_group - - # If disabling, then enable_state better be true, and we are - # transitioning to "option_all" grouping - if [ $command = "disable" ] - then - enable_state=1 - dep_group="optional_all" - - # If enabling, then enable_state better be false, and we are - # transitioning to "require_all" grouping - elif [ $command = "enable" ] - then - enable_state=0 - dep_group="require_all" - else - echo "invalid command: $command" >&2 - fi - - is_imported $svc - if [ $? = 1 ] - then - is_enabled $svc - if [ $? = $enable_state ] - then - if [ $enable_state -eq 1 ] - then - # we're doing a disable--remove hard dependency - set_fs_local_grouping $svc $dep_group - if [ $? -ne 0 ] - then - return 1 - fi - fi - - svcadm $command -s svc:/system/$svc - if [ $? != 0 ] - then - echo "$svc failed to $command" >&2 - return 1 - fi - - if [ $enable_state -eq 0 ] - then - # we just did an enable--create hard dependency - set_fs_local_grouping $svc $dep_group - if [ $? -ne 0 ] - then - return 1 - fi - fi - - else - echo "$svc service already ${command}d... skipping" - fi - fi - - return 0 -} - -# -# This chart summarizes the behavior of the -r and -p sub-options for the -# -e and -d options. -# There are 5 possible states, and 5 transitions out of each state. -# -# states: (vertical axis) -# ------- -# 0: no services enabled -# C: one or both core services enabled (illegal state) -# R: both core services and RM services enabled -# P: both core services and PITC service enabled -# A: all services enabled -# -# transitions: (horizontal axis) -# ------------ -# +/-a: enable/disable, respectively, with neither -r nor -p -# +/-r: enable/disable, respectively, with -r flag -# +p: enable with -p flag -# -# The result of the function is the next state after the action has been -# successfully performed. -# -# +a | -a | +r | -r | +p | -# ++----+----+----+----+----+ -# ++----+----+----+----+----+ -# 0 || A | 0* | R | 0* | P | -# --++----+----+----+----+----+ -# C || A* | 0* | R | 0 | P | -# --++----+----+----+----+----+ -# R || A* | 0* | R* | 0 | A | -# --++----+----+----+----+----+ -# P || A* | 0* | A* | P* | P* | -# --++----+----+----+----+----+ -# A || A* | 0 | A* | P | A* | -# --++----+----+----+----+----+ -# -# *: warning message is displayed, stating that a service is already -# enabled/disabled. -# - -# enable the SMF services needed for the Availability Suite -# -enable_services() -{ - $xopt - typeset svc - - # first, import them if they have not yet been imported - import_services - - # if neither r_flag nor p_flag is set, enable all services - if (( (r_flag | p_flag) == 0 )) - then - for svc in $SMF_ENABLE - do - if ! svc_operation $svc enable - then - return 1 - fi - done - else - # figure out which services are enabled - check_enabled - - # First, make sure both core services are enabled - for svc in nws_scm nws_sv - do - if (( ${svc}_enabled == 0 )) && \ - ! svc_operation $svc enable - then - return 1 - fi - done - - if ((p_flag)) - then - if ! svc_operation nws_ii enable - then - return 1 - fi - fi - - if ((r_flag)) - then - for svc in nws_rdc nws_rdcsyncd - do - if ! svc_operation $svc enable - then - return 1 - fi - done - fi - - fi - - return 0 -} - -# -# disable the SMF services needed for the Availability Suite -# -disable_services() -{ - $xopt - typeset svc - - check_device_groups - if [ $? == 1 ] - then - return 1 - fi - - # This flags the shutdown scripts to not check to make sure the - # services' dependents have been disabled. The flag must be removed - # before returning from this function. - no_depend_check - - # NB: p_flag is not allowed for disables. II should not be - # disabled if sndr is enabled. If rdc is not enabled, disabling just - # II is equivalent to disabling all the remaining services. - - # If no flags passed in, just disable everything - if (( r_flag == 0 )) - then - for svc in $SMF_DISABLE - do - if ! svc_operation $svc disable - then - rm_no_depend_check - return 1 - fi - done - - # Now that we've disable the services, lets unload them - # from the Solaris kernel - # - modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null - modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null - else - # we're disabling just rdc. If II is not already enabled, - # we disable core services, as well. - - # figure out which services are enabled - check_enabled - - for svc in nws_rdcsyncd nws_rdc - do - if ! svc_operation $svc disable - then - rm_no_depend_check - return 1 - fi - done - - if (( nws_ii_enabled == 0 )) - then - for svc in nws_sv nws_scm - do - if ((${svc}_enabled)) && \ - ! svc_operation $svc disable - then - rm_no_depend_check - return 1 - fi - done - fi - fi - - - rm_no_depend_check - return 0 -} - -# -# check if a service has been imported into the repository -# $1: service to check -# returns 1 if it is imported, 0 if it is not -# -is_imported() -{ - $xopt - - typeset svc=$1 - - svcprop -q -p general/entity_stability svc:/system/${svc} - if [ $? = 1 ] - then - return 0 - else - return 1 - fi -} - -# -# import the SMF services into the repository, if necessary -# -import_services() -{ - $xopt - typeset svc - - for svc in $SMF_ENABLE - do - import_service $svc - done -} - -# -# check to see if an SMF service is in the repository. If it is not, -# import it in. -# $1: name of service to import -# -import_service() -{ - $xopt - typeset svc=$1 - - is_imported $svc - if [ $? = 0 ] - then - if [ -f $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml ] - then - svccfg import $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml - - if [ $OS_MINOR -lt 11 ] - then - # workaround for 6221374--let local-fs know - # that it depends on us. - svcadm refresh ${FS_LOCAL_SVC}:default - fi - fi - fi -} - - -########################## MAIN ###################################### - -# getopt processing -enable=0 -disable=0 -set_location=0 -get_info=0 -r_flag=0 -p_flag=0 -while getopts "xedsirp" opt 2>/dev/null -do - case $opt in - \?) - help - ;; - e) - enable=1 - ;; - d) - disable=1 - ;; - x) - xopt="set -x" - set -x - ;; - s) - set_location=1 - ;; - i) - get_info=1 - ;; - r) - r_flag=1 - ;; - p) - p_flag=1 - ;; - esac -done - -# at most one option (besides -x) may be specified at a time -options_count=$((enable + disable + set_location + get_info)) -if [ $options_count -gt 1 ] -then - help -elif [ $options_count = 0 ] -then - NO_ARGS=1 -fi - -if (( ((r_flag + p_flag) > 0) && ((enable | disable) == 0) )) -then - echo "-r and -p options may only be used with -d or -e options" >&2 - return 1 -elif (( p_flag && disable )) -then - echo "The -p option may not be used with the -d option" >&2 - return 1 -fi - - - -# set all the system information variables -get_system_state - -# if we're enabling, we need to make sure we have a valid dscfg out there. -if [ $enable = 1 -a $VALID_LOCAL_DB != 1 ] -then - echo "Cannot find a valid configuration database" >&2 - return 1 -fi - -if [ $NO_ARGS = 1 ] -then - - # only initialize the database if necessary - if [ $VALID_LOCAL_DB = 1 ]; then - echo "Local configuration database is already initialized." - else - initialize_local_db - if [ $? != 0 ]; then - return 1 - fi - fi - - if [ $CLUSTER_CONFIGURED = 1 ] - then - if [ $VALID_CLUSTER_DB = 1 ]; then - printf "Cluster configuration database is already " - printf "initialized.\n" - else - # ask the user for a cluster database location - set_cluster_config - - # initialize the new db - initialize_cluster_db - if [ $? != 0 ]; then - return 1 - fi - fi - - fi - - # make sure that the local filesystem dependency type is correct - for svc in $SMF_ENABLE - do - check_fs_local_grouping $svc - if [ $? -ne 0 ] - then - # NOTE: check_fs_local_grouping sets CORRECT_GROUPING - # To avoid this issue in the future, always administer - # the services using dscfgadm. - printf "Warning: Fixing dependency for $svc.\n" - set_fs_local_grouping $svc $CORRECT_GROUPING - if [ $? -ne 0 ] - then - return 1 - fi - fi - done - - # give the user the chance to startup AVS services, if not started - check_enabled - if [ $? = 1 ]; then - if [ $OLD_VALID_LOCAL_DB = 0 ]; then - printf "WARNING: AVS services are running on a system " - printf "which had no valid configuration\ndatabase\n" - fi - show_enabled - else - ask_to_enable - if [ $? = 1 ]; then - enable_services - if [ $? != 0 ] - then - return 1 - fi - fi - fi - -elif [ $enable = 1 ] -then - enable_services - if [ $? != 0 ] - then - return 1 - fi - -elif [ $disable = 1 ] -then - disable_services - if [ $? != 0 ] - then - return 1 - fi - -elif [ $get_info = 1 ] -then - display_info - -elif [ $set_location = 1 ] -then - if [ $CLUSTER_CONFIGURED = 1 ] - then - # ask the user for a cluster database location - set_cluster_config - - # initialize the new db - initialize_cluster_db - if [ $? != 0 ]; then - return 1 - fi - else - echo "$PROG -s is only available on Sun Cluster OE systems" >&2 - return 1 - fi -fi - -return 0 - - -########################## MAIN ###################################### - diff --git a/usr/src/cmd/avs/dscfg/etc/Makefile b/usr/src/cmd/avs/dscfg/etc/Makefile deleted file mode 100644 index 725c36deac..0000000000 --- a/usr/src/cmd/avs/dscfg/etc/Makefile +++ /dev/null @@ -1,44 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -include ../../../Makefile.cmd - -ETCFILES = dscfg_format - -FILEMODE = 0744 - -ROOTETCFILES= $(ETCFILES:%=$(ROOTETC)/%) - -.KEEP_STATE: - -all: $(ETCFILES) - -install: $(ROOTETCFILES) - -clean: - -clobber: - -lint: - -FRC: diff --git a/usr/src/cmd/avs/dscfg/etc/dscfg_format b/usr/src/cmd/avs/dscfg/etc/dscfg_format deleted file mode 100644 index fec9d86d43..0000000000 --- a/usr/src/cmd/avs/dscfg/etc/dscfg_format +++ /dev/null @@ -1,72 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Default parser configuration file -# -# Lines starting `#' are comments, lines starting `%' are descriptive -# text to be printed by dscfg -l, all other lines are parser rules. -# -# Descriptive text should be directly above the parser rule it relates to. -# -% Availability Suite - dscfg configuration database -% -% Storage Cache Manager - scmadm -% threads csiz wrtcache filpat reserved1 niobuf ntdaemon fwrthru nofwrthru -scm.thread.size.write_cache.fill_pattern.reserved1.iobuf.tdemons.forced_wrthru.no_forced_wrthru -% -% Cache Hints - scmadm -% device wrthru nordcache -cache_hint.device.wrthru.nordcache -% -% Point-in-Time Copy - iiadm -% master shadow bitmap mode(D|I) [overflow] [device-group] [options] [group] -ii.master.shadow.bitmap.mode.overflow.cnode.options.group -% -% Remote Mirror (internal) SetId -% setid [device-group] -setid.value.cnode -% -% Remote Mirror - sndradm -% p_host p_dev p_bmp s_host s_dev s_bmp protocol(ip/fcal_device) mode \ -% [group] [device-group] [options] [diskq] -sndr.phost.primary.pbitmap.shost.secondary.sbitmap.type.mode.group.cnode.options.diskq -% -% Remote Mirror - Point-in-Time mapping -% SNDR-secondary II-shadow II-bitmap state [device-group] -ndr_ii.secondary.shadow.bitmap.state.cnode -% -% Bitmap filesystem to mount before other filesystems -% pathname_or_special_device [resource-group] -bitmaps.bitmap.cnode -% -% Storage volumes - svadm -% pathname [mode] [device-group] -sv.vol.mode.cnode -% -% Ncall Core -% nodeid [device-group] -ncallcore.nodeid.cnode -% -% DsVol - volume usage -% volume [device-group] users -dsvol.path.cnode.users diff --git a/usr/src/cmd/avs/dscfglockd/Makefile b/usr/src/cmd/avs/dscfglockd/Makefile deleted file mode 100644 index 3d7c3e008e..0000000000 --- a/usr/src/cmd/avs/dscfglockd/Makefile +++ /dev/null @@ -1,84 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -DYNPROG = dscfglockd dscfgcli - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -dscfglockd := POBJS = dscfglockd.o - -dscfgcli := POBJS = dscfgcli.o - -OBJS= dscfglockd.o dscfgcli.o -SRCS= $(OBJS:%.o=%.c) -POFILES= $(OBJS:%.o=%.po) - -dscfgcli := LDLIBS += -ldscfg -lnsl -dscfglockd := LDLIBS += -lunistat -ldscfg -lsocket -lnsl - -CFLAGS += $(CCVERBOSE) -D_RDC_ -D_SYSCALL32 -CERRWARN += -_gcc=-Wno-switch -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_RDC_ -D_SYSCALL32 -LINTFLAGS += -DDEBUG -erroff=E_SEC_SCANF_UNBOUNDED_COPY -LINTDIR = $(KBASE)/lintdir -POFILE = dscfglockd_all.po -LFILE = $(LINTDIR)/rdc.ln -ROOTLINK = $(ROOTLIB)/dscfglockd - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SUBDIRS) $(PROG) $(POFILES) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK) - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o $(POFILES) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(ROOTLINK): $(ROOTLIB) $(ROOTBIN)/dscfglockd - -$(RM) $@; $(LN) $(ROOTBIN)/dscfglockd $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/dscfglockd/dscfgcli.c b/usr/src/cmd/avs/dscfglockd/dscfgcli.c deleted file mode 100644 index 9fd71e8b98..0000000000 --- a/usr/src/cmd/avs/dscfglockd/dscfgcli.c +++ /dev/null @@ -1,149 +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 <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <ctype.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <locale.h> -#include <sys/nsctl/cfg.h> - -CFGFILE *cfg; -void cfg_lockd_stat(); -int tty; - -static void -test(int count) -{ - struct stat sb; - int i; - - if (count < 1) - count = 1; - for (i = 0; count-- > 0; i++) { - if (cfg_lock(cfg, CFG_RDLOCK) < 0) - (void) printf("CFG_RDLOCK error\n"); - else - (void) fstat(0, &sb); - - cfg_unlock(cfg); - (void) fstat(1, &sb); - - if (cfg_lock(cfg, CFG_RDLOCK) < 0) - (void) printf("CFG_RDLOCK error\n"); - else - (void) fstat(0, &sb); - - cfg_unlock(cfg); - (void) fstat(1, &sb); - - if (cfg_lock(cfg, CFG_WRLOCK) < 0) - (void) printf("CFG_WRLOCK error\n"); - else - (void) fstat(0, &sb); - - cfg_unlock(cfg); - (void) fstat(1, &sb); - - if (i > 0) { - if (i % 100 == 0) - (void) write(1, "+", 1); - if (i % 5000 == 0) - (void) write(1, "\n", 1); - } - } - (void) printf("\nTest complete\n"); -} - -static void -cmd_loop() -{ - char host[1024]; - char buffer[1024]; - int i; - - (void) gethostname(host, sizeof (host)); - for (;;) { - if (tty) - (void) printf(":%s: ", host); - (void) fgets(buffer, sizeof (buffer), stdin); - switch (tolower(buffer[0])) { - case 'p': - i = atoi(buffer + 1); - (void) sleep(i); - break; - case 'q': - exit(0); - break; - case 'r': - if (cfg_lock(cfg, CFG_RDLOCK) < 0) - (void) printf("CFG_RDLOCK error\n"); - break; - case 's': - cfg_lockd_stat(); - break; - case 't': - i = atoi(buffer + 1); - test(i); - break; - case 'u': - cfg_unlock(cfg); - break; - case 'w': - if (cfg_lock(cfg, CFG_WRLOCK) < 0) - (void) printf("CFG_WRLOCK error\n"); - break; - default: - (void) printf("don't understand %s\n", buffer); - break; - } - } -} - -static void -init() -{ - tty = isatty(0); - if (tty) - (void) printf("dscfglockd cli %s\n", "07/06/12"); - if ((cfg = cfg_open(NULL)) == NULL) { - perror("cfg_open"); - exit(1); - } -} - -int -main(void) -{ - init(); - cmd_loop(); - return (0); -} diff --git a/usr/src/cmd/avs/dscfglockd/dscfglockd.c b/usr/src/cmd/avs/dscfglockd/dscfglockd.c deleted file mode 100644 index 578c38f15e..0000000000 --- a/usr/src/cmd/avs/dscfglockd/dscfglockd.c +++ /dev/null @@ -1,1371 +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 <signal.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <fcntl.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/pathconf.h> -#include <netdir.h> -#include <netconfig.h> -#include <sys/sockio.h> -#include <net/if.h> -#include <sys/resource.h> -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <locale.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> - -#include <sys/nsctl/cfg.h> -#include <sys/nsctl/cfg_lockd.h> - -#ifdef DEBUG -#define DPF(m) if (debug) (void) fprintf m -#else -#define DPF(m) -#endif - -#ifdef TTY_MESSAGES -#define CLOSE_FD 3 -#else -#define CLOSE_FD 0 -#endif - -#define MAX_LOCKQ 1024 -#define MAX_DAEMONS 1024 -#define MAX_LOCAL 1024 -#define MAX_UNLOCK 32 -#define MAX_TIMEOUTS 3 -#define TIMEOUT_SECS 5 - -static char program[] = "dscfglockd"; -static int debug; -static int lstate; -static int msgtrace; -static FILE *debugfile = NULL; - -struct lock_req { - cfglockd_t type; /* read or write */ - pid_t pid; /* pid of read locker or local writer */ - daemonaddr_t remote; /* remote machine requesting write lock */ - int state; /* for write locks */ - int32_t order; /* who gets priority? */ -} lock_queue[MAX_LOCKQ]; - -struct unlock_s { - pid_t pid; /* pid of locker */ - uint8_t seq; /* seq number of last lock request */ -} unlock_buf[MAX_UNLOCK]; - -int next_req; -int32_t order; - -#define lock_wanted lock_queue[0] -long ticker = 1l; - -#define ALIVE 0x10 -#define READ_LOCK 0x11 -#define WRITE_LOCK 0x12 -#define UNLOCK 0x13 -#define GRANTED 0x14 - -int next_q; - -struct { - cfglockd_t type; - int nholders; - int state; - daemonaddr_t holder; - struct lockdaemon *remote_daemon; - pid_t holding_pid[MAX_LOCAL]; -} the_lock; - -daemonaddr_t thishost; -daemonaddr_t localhost; - -#define STATE_CLEAR 0 -#define STATE_ASKED 1 -#define STATE_OKAYED 2 -#define STATE_WANTS 3 -#define lockdaemon_dead(ldp) ((ticker - (ldp)->timeout) > MAX_TIMEOUTS) -#define CRIT_BEGIN() (void) sighold(SIGALRM) -#define CRIT_END() (void) sigrelse(SIGALRM) - -#define NORMAL_UNLOCK 0 -#define FORCE_UNLOCK 1 - -struct lockdaemon { - daemonaddr_t host; - int up; - long timeout; - int inuse; - int state; - int32_t order; -} daemon_list[MAX_DAEMONS]; - -unsigned short lock_port = CFG_SERVER_PORT; -int lock_soc = 0; -int pf_inet = PF_INET; -#define dp_addr(p) inet_ntoa(((struct sockaddr_in *)p)->sin_addr) - -#define MAXIFS 32 - -static char * -lockd_type(cfglockd_t type) -{ - switch (type) { - case LOCK_NOTLOCKED: return "NotLocked"; - case LOCK_READ: return "Read"; - case LOCK_WRITE: return "Write"; - case LOCK_LOCKED: return "Locked"; - case LOCK_LOCKEDBY: return "LockedBy"; - case LOCK_STAT: return "Stat"; - case LOCK_ACK: return "Ack"; - default: return "*unknown*"; - } -} - -static char * -lockd_state(int state) -{ - switch (state) { - case STATE_CLEAR: return "Clear"; - case STATE_ASKED: return "Asked"; - case STATE_OKAYED: return "Okayed"; - case STATE_WANTS: return "Wants"; - default: return "*unknown*"; - } -} - -static char * -lockd_msg(int message) -{ - switch (message) { - case ALIVE: return "Alive"; - case READ_LOCK: return "ReadLock"; - case WRITE_LOCK: return "WriteLock"; - case UNLOCK: return "Unlock"; - case GRANTED: return "Granted"; - default: return lockd_type((cfglockd_t)message); - } -} - -/* - * The following is stolen from autod_nfs.c - */ -static void -getmyaddrs(struct ifconf *ifc) -{ - int sock; - int numifs; - char *buf; - int family; - - ifc->ifc_buf = NULL; - ifc->ifc_len = 0; - -#ifdef AF_INET6 - family = AF_INET6; -#else - family = AF_INET; -#endif - if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) { -#ifdef DEBUG - perror("getmyaddrs(): socket"); -#endif - return; - } - - if (ioctl(sock, SIOCGIFNUM, (char *)&numifs) < 0) { -#ifdef DEBUG - perror("getmyaddrs(): SIOCGIFNUM"); -#endif - numifs = MAXIFS; - } - - buf = (char *)malloc(numifs * sizeof (struct ifreq)); - if (buf == NULL) { -#ifdef DEBUG - (void) fprintf(stderr, "getmyaddrs(): malloc failed\n"); -#endif - (void) close(sock); - return; - } - - ifc->ifc_buf = buf; - ifc->ifc_len = numifs * sizeof (struct ifreq); - - if (ioctl(sock, SIOCGIFCONF, (char *)ifc) < 0) { -#ifdef DEBUG - perror("getmyaddrs(): SIOCGIFCONF"); -#endif - } - - (void) close(sock); -} - -struct ifconf *ifc; - -static int -cmp_addr(daemonaddr_t *a, daemonaddr_t *b) -{ - int rc; - rc = memcmp(&(a->sin_addr), &(b->sin_addr), sizeof (a->sin_addr)); - DPF((stderr, "compare %s %hu with", dp_addr(a), a->sin_port)); - DPF((stderr, " %s %hu = %d\n", dp_addr(b), b->sin_port, rc)); - return (rc); -} - -static int -addr_is_holder(int32_t order) -{ - return ((the_lock.nholders > 0) && the_lock.remote_daemon != NULL && - (order == the_lock.remote_daemon->order)); -} - -static int -islocalhost(daemonaddr_t *host) -{ - int n; - struct sockaddr_in *s1, *s2; - struct ifreq *ifr; - int retval = 0; - - ifr = ifc->ifc_req; - n = ifc->ifc_len / sizeof (struct ifreq); - s1 = host; - s2 = NULL; - for (; n > 0; n--, ifr++) { - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - - /* LINTED pointer alignment */ - s2 = (struct sockaddr_in *)&ifr->ifr_addr; - - if (memcmp((char *)&s2->sin_addr, - (char *)&s1->sin_addr, sizeof (s1->sin_addr)) == 0) { - retval = 1; - /* it's me */ - break; - } - } - return (retval); -} - -static void -send_lockmsg(int cmd, pid_t pid, daemonaddr_t *dp, uint8_t seq) -{ - struct lock_msg message_buf; - int rc; - - if (msgtrace && debugfile) { - time_t t = time(0); - (void) fprintf(debugfile, "%19.19s send %-9.9s to %s\n", - ctime(&t), lockd_msg(cmd), dp_addr(dp)); - } - DPF((stderr, "send %d to %s port %hu\n", cmd, - dp_addr(dp), dp->sin_port)); - message_buf.message = cmd; - message_buf.pid = pid; - message_buf.order = order; - message_buf.seq = seq; - do { - rc = sendto(lock_soc, &message_buf, sizeof (message_buf), 0, - (struct sockaddr *)dp, sizeof (struct sockaddr)); - } while (rc == -1 && errno == EINTR); - if (rc == -1) - spcs_log("cfglockd", NULL, "sendto rc -1 errno %d", errno); -} - -/* - * send an alive message to all configured daemons so that they can tell - * us if they are holding a write lock. - */ - -static void -send_aliveall() -{ - struct lockdaemon *ldp; - int i; - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - send_lockmsg(ALIVE, (pid_t)0, &(ldp->host), 0); - } -} - -/* find the lock daemon structure for a give daemon address */ - -static struct lockdaemon * -find_lockdaemon(daemonaddr_t *d) -{ - struct lockdaemon *ldp; - int i; - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - if (cmp_addr(&(ldp->host), d) == 0) - return (ldp); - } - return (NULL); -} - -/* - * a messge has been received from daemon, note this and if the daemon - * was previously dead and we have the write lock tell it that we do. - */ - -static void -daemon_alive(daemonaddr_t *daemon, int32_t order) -{ - struct lockdaemon *ldp; - int i; - - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - if (cmp_addr(&(ldp->host), daemon) == 0) { - ldp->order = order; - ldp->timeout = ticker; - if (ldp->up == 0) { - spcs_log("cfglockd", NULL, - "daemon restarted on %s\n", - dp_addr(daemon)); - DPF((stderr, "daemon restarted on %s\n", - dp_addr(daemon))); - ldp->up = 1; - goto come_up; - } - return; - } - } - /* new daemon has announced itself */ - if (i < MAX_DAEMONS) { - DPF((stderr, "new daemon on %s\n", dp_addr(daemon))); - spcs_log("cfglockd", NULL, - "new daemon on %s\n", dp_addr(daemon)); - ldp->host = *daemon; - ldp->inuse = 1; - ldp->timeout = ticker; - ldp->order = order; - } else { - /* problem, more daemons than expected */ - i++; - } -come_up: - if (the_lock.type == LOCK_WRITE && the_lock.remote_daemon == NULL) - send_lockmsg(WRITE_LOCK, (pid_t)0, daemon, 0); -} - -static void -delete_queue_entry(struct lock_req *req) -{ - int i; - - for (i = (req - lock_queue); i++ < next_req; req++) - *req = *(req+1); - next_req--; -} - -static void -take_lock(int ackmessage) -{ - send_lockmsg(ackmessage, (pid_t)0, &lock_wanted.remote, 0); - delete_queue_entry(lock_queue); -} - -static void -check_for_write_lock() -{ - struct lockdaemon *ldp; - int i; - int wait = 0; - - DPF((stderr, "check for lock\n")); - if (lock_wanted.state != STATE_ASKED) - return; - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - if (ldp->up && ldp->state != STATE_OKAYED) { - wait = 1; - break; - } - } - if (wait == 0 && lock_wanted.type == LOCK_WRITE) { - the_lock.type = LOCK_WRITE; - the_lock.holding_pid[0] = lock_wanted.pid; - the_lock.nholders = 1; - the_lock.state = STATE_CLEAR; - take_lock(LOCK_LOCKED); - } -} - -static void -lock_granted(daemonaddr_t *da) -{ - struct lockdaemon *ldp; - - if ((ldp = find_lockdaemon(da)) != NULL) { - /* if we already own the lock, throw the msg away */ - if (the_lock.remote_daemon == NULL && - the_lock.type == LOCK_WRITE) { - return; - } - - /* - * If the current lock isn't a write lock and we're not - * asking for one - * -OR- - * The current lock is a write lock and it's not owned by us - * -THEN- - * send back an unlocked message. - */ - if ((the_lock.type != LOCK_WRITE && - the_lock.state != STATE_ASKED) || - (the_lock.type == LOCK_WRITE && - the_lock.remote_daemon != NULL)) { - send_lockmsg(UNLOCK, (pid_t)0, &(ldp->host), 0); - return; - } - ldp->state = STATE_OKAYED; - } - check_for_write_lock(); -} - -static int -try_lock() -{ - struct lockdaemon *ldp; - int i; - - switch (the_lock.type) { - case LOCK_READ: - if (lock_wanted.type == LOCK_READ) { - i = the_lock.nholders++; - the_lock.holding_pid[i] = lock_wanted.pid; - the_lock.state = STATE_CLEAR; - DPF((stderr, "increment read lockers to %d\n", - the_lock.nholders)); - take_lock(LOCK_LOCKED); - break; - } - /* write lock has to wait */ - break; - case LOCK_WRITE: - /* lock has to wait until write lock is cleared */ - break; - case LOCK_NOTLOCKED: - if (lock_wanted.type == LOCK_READ) { - DPF((stderr, "local locker, 1 lock holder\n")); - the_lock.holding_pid[0] = lock_wanted.pid; - the_lock.nholders = 1; - the_lock.type = LOCK_READ; - the_lock.state = STATE_CLEAR; - the_lock.remote_daemon = NULL; - take_lock(LOCK_LOCKED); - return (1); - } - if (islocalhost(&lock_wanted.remote)) { - DPF((stderr, "local locker, take write lock\n")); - /* tell everyone I'm locking */ - if (lock_wanted.state != STATE_ASKED) { - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; - i++, ldp++) { - if (ldp->inuse == 0) - break; - ldp->state = STATE_ASKED; - send_lockmsg(WRITE_LOCK, (pid_t)0, - &(ldp->host), 0); - } - } - lock_wanted.state = STATE_ASKED; - check_for_write_lock(); - the_lock.remote_daemon = NULL; - the_lock.state = STATE_ASKED; - return (0); - } else { - DPF((stderr, "remote locker, take write lock\n")); - the_lock.type = LOCK_WRITE; - the_lock.holder = lock_wanted.remote; - the_lock.nholders = 1; - the_lock.remote_daemon = - find_lockdaemon(&the_lock.holder); - the_lock.state = STATE_CLEAR; - /* okay to remote */ - take_lock(GRANTED); - } - break; - default: - DPF((stderr, "weird lock type held - %d\n", the_lock.type)); - the_lock.type = LOCK_NOTLOCKED; - break; - } - return (0); -} - -static void -process_queue() -{ - if (next_req < 1) - return; /* no locks queued */ - while (try_lock()) - ; -} - -static int -lock_sort(const void *a, const void *b) -{ - struct lock_req *left = (struct lock_req *)a; - struct lock_req *right = (struct lock_req *)b; - - return (left->order - right->order); -} - -static void -queue_lock(cfglockd_t type, struct lock_msg *msg, daemonaddr_t *addr) -{ - int i; - struct lock_req *lrp; - struct lockdaemon *ldp; - - /* first check if new lock matches current lock */ - if (the_lock.type == type && addr_is_holder(msg->order)) { - /* remote daemon missed locked message */ - send_lockmsg(GRANTED, (pid_t)0, addr, msg->seq); - return; - } - - /* next search queue to check for duplicate */ - for (i = 0, lrp = lock_queue; i++ < next_req; lrp++) { - if (lrp->type == type && lrp->pid == msg->pid && - cmp_addr(addr, &(lrp->remote)) == 0) - return; - - } - - /* - * It's a new lock request. Are we in the middle of - * obtaining one for ourselves? - */ - - if (the_lock.type == LOCK_NOTLOCKED && the_lock.state == STATE_ASKED) { - /* did a higher priority request just come in? */ - if (msg->order < order) { - /* requeue our request */ - the_lock.state = STATE_CLEAR; - lock_wanted.state = STATE_CLEAR; - - /* let the other lockds know */ - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; - i++, ldp++) { - if (ldp->inuse == 0) - break; - if (ldp->up && ldp->state == STATE_OKAYED) { - send_lockmsg(UNLOCK, (pid_t)0, - &(ldp->host), 0); - } - } - } - } - - - lrp = lock_queue; - lrp += (next_req++); - lrp->type = type; - lrp->pid = msg->pid; - lrp->state = STATE_CLEAR; - lrp->order = msg->order; - if (addr) { - lrp->remote = *addr; - } - - if (next_req > 1) - qsort(lock_queue, next_req, sizeof (lock_queue[0]), lock_sort); - - if (the_lock.type != LOCK_WRITE) - process_queue(); -} - -static void -lock_stat() -{ - char *lt = "Unknown"; - struct lockdaemon *ldp; - int i; - - switch (the_lock.type) { - case LOCK_NOTLOCKED: - lt = "not locked"; - break; - case LOCK_READ: - lt = "read locked"; - break; - case LOCK_WRITE: - lt = "write locked"; - break; - } - spcs_log("cfglockd", NULL, "Lock is %s (%d)", lt, the_lock.type); - spcs_log("cfglockd", NULL, "There are %d holders of the lock", - the_lock.nholders); - if (the_lock.nholders > 0) { - for (i = 0; i < the_lock.nholders; i++) - spcs_log("cfglockd", NULL, "holding_pid[%d] = %6d", i, - the_lock.holding_pid[i]); - } - spcs_log("cfglockd", NULL, "holder daemon was %s port %hu, remote %x", - dp_addr(&the_lock.holder), the_lock.holder.sin_port, - the_lock.remote_daemon); - spcs_log("cfglockd", NULL, "Lock queue, %d requests", next_req); - for (i = 0; i < next_req; i++) { - spcs_log("cfglockd", NULL, "request %d type %d order %d", i, - lock_queue[i].type, lock_queue[i].order); - spcs_log("cfglockd", NULL, " client %s port %hu, pid %d", - dp_addr(&lock_queue[i].remote), - lock_queue[i].remote.sin_port, lock_queue[i].pid); - } - spcs_log("cfglockd", NULL, "Daemon list"); - - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - spcs_log("cfglockd", NULL, "daemon %d, %s port %hu", i, - dp_addr(&ldp->host), ldp->host.sin_port); - spcs_log("cfglockd", NULL, - " up %d timeout %ld missed %d state %d\n", ldp->up, - ldp->timeout, ticker - ldp->timeout, ldp->state); - } -} - -static int -is_duplicate(cfglockd_t type, pid_t pid, uint8_t seq) -{ - struct unlock_s *bufp; - int i; - - if (!pid) { - return (0); - } - - for (i = 0, bufp = unlock_buf; bufp->pid && i < MAX_UNLOCK; - i++, bufp++) { - if (bufp->pid == pid && bufp->seq == seq) { - /* throw message away */ -#ifdef DEBUG - spcs_log("cfglockd", NULL, - "duplicate '%d' request received from %d", - type, pid); -#endif - return (1); - } - } - - /* add it to the list */ - bcopy(unlock_buf, &unlock_buf[ 1 ], - sizeof (unlock_buf) - sizeof (struct unlock_s)); - (*unlock_buf).pid = pid; - (*unlock_buf).seq = seq; - - return (0); -} - -static void -local_lock(cfglockd_t type, struct lock_msg *msg, daemonaddr_t *client) -{ - if (is_duplicate(type, msg->pid, msg->seq)) { - if (the_lock.remote_daemon == NULL && - (the_lock.type == LOCK_WRITE || - the_lock.type == LOCK_READ) && - the_lock.holding_pid[0] == msg->pid) { - send_lockmsg(LOCK_LOCKED, (pid_t)0, client, msg->seq); - } - } else { - queue_lock(type, msg, client); - } -} - -static void -remote_lock(struct sockaddr_in *remote, struct lock_msg *msg) -{ - /* make sure remote knows we are alive */ - send_lockmsg(ALIVE, (pid_t)0, remote, 0); - - /* clear out pid as it is meaningless on this node */ - msg->pid = (pid_t)0; - - queue_lock(LOCK_WRITE, msg, (daemonaddr_t *)remote); -} - -static void -unqueue_lock(daemonaddr_t *d, pid_t pid) -{ - int i; - struct lock_req *lrp, *xrp; - int diff; - - /* search queue to delete ungranted locks */ - for (i = 0, xrp = lrp = lock_queue; i++ < next_req; lrp++) { - *xrp = *lrp; - diff = 0; - if (pid != (pid_t)0 && lrp->pid != pid) - diff = 1; - if (d != NULL && cmp_addr(d, &(lrp->remote)) != 0) - diff = 1; - if (!diff) - continue; - - xrp++; - } - next_req = xrp - lock_queue; -} - -static void -xxunlock() -{ - DPF((stderr, "** UNLOCK **\n")); - the_lock.remote_daemon = NULL; - the_lock.type = LOCK_NOTLOCKED; - the_lock.nholders = 0; - the_lock.state = STATE_CLEAR; - process_queue(); -} - - -static void -local_unlock(pid_t pid, uint8_t seq, int method) -{ - struct lockdaemon *ldp; - int i; - - if (method == NORMAL_UNLOCK && is_duplicate(LOCK_NOTLOCKED, pid, seq)) { - return; - } - - if (the_lock.type == LOCK_READ) { - /* delete reference to pid of reading process */ - for (i = 0; i < the_lock.nholders; i++) { - if (the_lock.holding_pid[i] == pid) { - DPF((stderr, "decrement lockers from %d\n", - the_lock.nholders)); - --the_lock.nholders; - break; - } - } - for (; i < the_lock.nholders; i++) { - the_lock.holding_pid[i] = the_lock.holding_pid[i+1]; - } - if (the_lock.nholders > 0) - return; - } else { - /* LOCK_WRITE */ - if (pid != the_lock.holding_pid[0]) - return; - the_lock.holding_pid[0] = (pid_t)0; - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - if (ldp->up) - send_lockmsg(UNLOCK, (pid_t)0, &(ldp->host), 0); - } - } - xxunlock(); -} - -static void -remote_unlock(int32_t order, daemonaddr_t *d) -{ - int i; - struct lock_req *lrp; - - DPF((stderr, "remote unlock from %s ", dp_addr(d))); - DPF((stderr, "when %s holds lock\n", dp_addr(&the_lock.holder))); - - /* search queue to check for ungranted lock */ - for (i = 0, lrp = lock_queue; i++ < next_req; lrp++) { - if (lrp->type == LOCK_WRITE && - cmp_addr(d, &(lrp->remote)) == 0) { - delete_queue_entry(lrp); - return; - } - - } - if (addr_is_holder(order)) { - xxunlock(); - } -} - -static void -lockedby(daemonaddr_t *d, uint8_t seq) -{ - DPF((stderr, "lockby enquiry from %s ", dp_addr(d))); - switch (the_lock.type) { - case LOCK_NOTLOCKED: - send_lockmsg(LOCK_NOTLOCKED, (pid_t)0, d, seq); - break; - case LOCK_READ: - send_lockmsg(LOCK_READ, the_lock.holding_pid[0], d, seq); - break; - case LOCK_WRITE: - send_lockmsg(LOCK_WRITE, the_lock.holding_pid[0], d, seq); - break; - } -} - -/* ARGSUSED */ -static void -keepalive(int signo) -{ - int i; - struct lock_req *locker; - struct lockdaemon *ldp; - - DPF((stderr, "keepalive...\n")); - ticker++; - - /* - * tell any other daemon that has a lock request in our queue that - * this daemon is still alive. - */ - - for (i = 0, locker = lock_queue; i < next_req; i++, locker++) { - if (locker->pid == 0) /* remote lock request */ - send_lockmsg(ALIVE, (pid_t)0, &(locker->remote), 0); - } - - /* - * if a remote daemon holds the lock, check it is still alive and - * if the remote daemon is sent it a grant message in case the - * remote daemon missed our original grant. - */ - - if (the_lock.remote_daemon) { - if (lockdaemon_dead(the_lock.remote_daemon)) { - DPF((stderr, "lock owner died\n")); - the_lock.remote_daemon->up = 0; - xxunlock(); - } else { - send_lockmsg(GRANTED, (pid_t)0, &the_lock.holder, 0); - } - } - - /* - * check for response from daemons preventing this daemon - * from taking a write lock by not sending a grant message. - * if the remote daemon is alive send another lock request, - * otherwise mark it as dead. - * send alive message to any live remote daemons if this - * daemon has the write lock. - */ - if (lstate) { - (void) printf("\nlock: %s\n", lockd_type(the_lock.type)); - (void) printf(" no. holders: %d\n", the_lock.nholders); - (void) printf(" hold addr : %s\n", the_lock.remote_daemon? - dp_addr(the_lock.remote_daemon): "0.0.0.0"); - (void) printf(" holding pid:"); - for (i = 0; i < the_lock.nholders; i++) { - (void) printf(" %ld", the_lock.holding_pid[ i ]); - } - (void) printf("\n"); - } - for (i = 0, ldp = daemon_list; i < MAX_DAEMONS; i++, ldp++) { - if (ldp->inuse == 0) - break; - - if (lstate) { - (void) printf("%-15.15s ", dp_addr(&ldp->host)); - (void) printf("%-4.4s ", ldp->up? "up" : "down"); - (void) printf("%5ld ", ldp->timeout); - (void) printf("%-10.10s ", lockd_state(ldp->state)); - (void) printf("%6d\n", ldp->order); - } - - if (ldp->state == STATE_ASKED) { - if (lockdaemon_dead(ldp)) { - ldp->up = 0; - ldp->state = STATE_CLEAR; - continue; - } - send_lockmsg(WRITE_LOCK, (pid_t)0, &(ldp->host), 0); - continue; - } - if (the_lock.type == LOCK_WRITE && - the_lock.remote_daemon == NULL) - send_lockmsg(ALIVE, (pid_t)0, &(ldp->host), 0); - } -} - -static void -dispatch(struct lock_msg *mp, daemonaddr_t *host) -{ - int message = mp->message; - int localhost; - - localhost = islocalhost(host); - if (msgtrace && debugfile) { - time_t t = time(0); - if (localhost) { - (void) fprintf(debugfile, - "%19.19s recv %-9.9s from %s (%ld)\n", ctime(&t), - lockd_msg(message), dp_addr(host), mp->pid); - } else { - (void) fprintf(debugfile, - "%19.19s recv %-9.9s from %s order %d (%ld)\n", - ctime(&t), lockd_msg(message), dp_addr(host), - mp->order, mp->pid); - } - } - DPF((stderr, "received message %d\n", message)); - DPF((stderr, "from %s port %hu\n", dp_addr(host), host->sin_port)); - if (!localhost) - daemon_alive(host, mp->order); - else - mp->order = order; - switch (message) { - case ALIVE: - DPF((stderr, "received ALIVE %s\n", dp_addr(host))); - /* do nothing, general "not localhost" code above does this */ - break; - case UNLOCK: - DPF((stderr, "received UNLOCK\n")); - remote_unlock(mp->order, host); - break; - case GRANTED: - DPF((stderr, "received GRANTED\n")); - lock_granted(host); - break; - case WRITE_LOCK: - DPF((stderr, "received WRITE_LOCK\n")); - assert(!localhost); - remote_lock(host, mp); - break; - case READ_LOCK: - case LOCK_READ: - DPF((stderr, "received READ_LOCK\n")); - assert(localhost); - local_lock(LOCK_READ, mp, host); - break; - case LOCK_WRITE: - DPF((stderr, "received LOCK_WRITE\n")); - assert(localhost); - local_lock(LOCK_WRITE, mp, host); - break; - case LOCK_NOTLOCKED: - DPF((stderr, "received LOCK_NOTLOCKED\n")); - send_lockmsg(LOCK_ACK, (pid_t)0, host, mp->seq); - if (the_lock.type != LOCK_NOTLOCKED) { - local_unlock(mp->pid, mp->seq, NORMAL_UNLOCK); - } - break; - case LOCK_LOCKEDBY: - lockedby(host, mp->seq); - break; - case LOCK_STAT: - lock_stat(); - break; - case LOCK_ACK: - /* throw message away -- this is an error to receive */ - break; - } -} - -/* - * unqueue any locks asked for by pid and unlock any locks held by pid. - */ - -static void -purge_pid(pid_t pid) -{ - DPF((stderr, "purge locks for %ld\n", pid)); - unqueue_lock(NULL, pid); - if (the_lock.type != LOCK_NOTLOCKED) - local_unlock(pid, 0, FORCE_UNLOCK); -} - -/* - * Check for exit or exec of client processes. - * The lock protecting the processes pid in the lockfile will - * be removed by the kernel when a client exits or execs. - */ - -static void -check_for_dead() -{ - int i, x; - pid_t pid; - - for (i = 0; (x = cfg_filelock(i, 0)) != CFG_LF_EOF; i++) { - if (x == CFG_LF_AGAIN) - continue; /* can't take lock, must be still alive */ - cfg_readpid(i, &pid); - cfg_writepid(i, (pid_t)0); - (void) cfg_fileunlock(i); - if (pid != (pid_t)0) - purge_pid(pid); - } -} - -static void -build_daemon_list(char *cf_file, int exe) -{ - FILE *fp; - char host[1024]; - int port; - int i; - struct hostent *hp; - struct lockdaemon *ldp; - - if ((hp = gethostbyname("localhost")) == NULL) { - (void) fprintf(stderr, "%s: Can't find hostent for %s\n", - program, "localhost"); - spcs_log("cfglockd", NULL, "couldn't find localhost"); - exit(1); - } - - (void) memcpy(&(localhost.sin_addr.s_addr), *(hp->h_addr_list), - sizeof (localhost.sin_addr)); - if (cf_file == NULL) { - (void) endhostent(); - return; - } - if (exe) { - if ((fp = popen(cf_file, "r")) == NULL) { - perror(cf_file); - (void) fprintf(stderr, - "%s: Can't open config program\n", program); - spcs_log("cfglockd", NULL, "couldn't read config"); - exit(1); - } - } else { - if ((fp = fopen(cf_file, "r")) == NULL) { - perror(cf_file); - (void) fprintf(stderr, "%s: Can't open config file\n", - program); - spcs_log("cfglockd", NULL, "couldn't read config"); - exit(1); - } - } - ldp = daemon_list; - while ((i = fscanf(fp, "%s %d\n", host, &port)) != EOF) { - if (host[0] == '#') /* line starting with # are comments */ - continue; - if (i == 1) { - port = lock_port; - } else { - if (strcmp(host, "localhost") == 0) { - lock_port = port; - continue; - } - } - - if ((hp = gethostbyname(host)) == NULL) { - (void) fprintf(stderr, - "%s: Can't find hostent for %s\n", program, host); - continue; - } - - (void) memcpy(&(ldp->host.sin_addr.s_addr), *(hp->h_addr_list), - sizeof (ldp->host.sin_addr)); - DPF((stderr, "daemon: %s\t%s\n", - inet_ntoa(ldp->host.sin_addr), hp->h_name)); - if (islocalhost(&(ldp->host))) { - DPF((stderr, "is an alias for this host, skipping\n")); - continue; - } - ldp->host.sin_port = htons((short)port); - ldp->host.sin_family = hp->h_addrtype; - ldp->inuse = 1; - ldp->up = 1; - ldp++; - } - if (exe) - (void) pclose(fp); - else - (void) fclose(fp); - (void) endhostent(); -} - -static void -usage() -{ - (void) fprintf(stderr, - gettext("usage: %s [-d] [-f file]|[-e program]\n"), program); - exit(1); -} - -static void -unexpected(int sig) -{ - spcs_log("cfglockd", NULL, "pid %d unexpected signal %d, ignoring", - getpid(), sig); -} - -static void -term(int sig) -{ - (void) unlink(CFG_PIDFILE); - spcs_log("cfglockd", NULL, "pid %d terminate on signal %d", getpid(), - sig); - exit(0); -} - -static void -init(int argc, char *argv[]) -{ -#if defined(_SunOS_5_6) || defined(_SunOS_5_7) || defined(_SunOS_5_8) - struct rlimit rl; -#endif - int c, i, x; - int rc; - char *cp = NULL; - struct itimerval tv; - struct timeval tp; - socklen_t len = sizeof (thishost); - int exe = 0; - pid_t pid; - FILE *fp; - - lstate = (getenv("LOCKD_STATE") != NULL); - msgtrace = (getenv("LOCKD_MSG") != NULL); - - /* - * Fork off a child that becomes the daemon. - */ - -#ifndef TTY_MESSAGES - if ((rc = fork()) > 0) - exit(0); - else if (rc < 0) { - spcs_log("cfglockd", NULL, "can't fork %d", errno); - (void) fprintf(stderr, gettext("dscfglockd: cannot fork: %s\n"), - strerror(errno)); - exit(1); - } -#endif - - /* - * In child - become daemon. - */ - -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) - /* use closefrom(3C) from PSARC/2000/193 when possible */ - closefrom(CLOSE_FD); -#else - (void) getrlimit(RLIMIT_NOFILE, &rl); - for (i = CLOSE_FD; i < rl.rlim_max; i++) - (void) close(i); -#endif - -#ifdef DEBUG -#ifndef TTY_MESSAGES - (void) open("/dev/console", O_WRONLY|O_APPEND); - (void) dup(0); - (void) dup(0); -#endif -#endif - (void) close(0); - - if (msgtrace || lstate) { - debugfile = fopen("/var/tmp/dscfglockd.out", "a"); - if (debugfile) { - time_t t = time(0); - setbuf(debugfile, (char *)0); - (void) fprintf(debugfile, "%19.19s dscfglockd start\n", - ctime(&t)); - } - } - - (void) setpgrp(); - spcs_log("cfglockd", NULL, "new lock daemon, pid %d", getpid()); - - /* - * Catch as unexpected all signals apart from SIGTERM. - */ - - for (i = 1; i < _sys_nsig; i++) - (void) sigset(i, unexpected); - (void) sigset(SIGTERM, term); - - for (i = 0; (c = getopt(argc, argv, "df:e:")) != EOF; i++) { - switch (c) { - case 'd': - debug = 1; - break; - case 'e': - exe = 1; - if (cp) { - usage(); - } - cp = optarg; - break; - case 'f': - if (cp) { - usage(); - } - cp = optarg; - break; - default: - usage(); - break; - } - } - - ifc = (struct ifconf *)malloc(sizeof (struct ifconf)); - if (ifc == NULL) { - perror(CFG_PIDFILE); - DPF((stderr, "Can't open pid file\n")); - exit(1); - } - (void) memset((char *)ifc, 0, sizeof (struct ifconf)); - getmyaddrs(ifc); - - /* - * if (lockdaemonalive()) { - * (void) fprintf(stderr, "%s: %s\n", program, - * gettext("There is already a live lockdaemon")); - * exit(1); - * } - */ - if ((fp = fopen(CFG_PIDFILE, "w")) == NULL) { - perror(CFG_PIDFILE); - DPF((stderr, "Can't open pid file\n")); - exit(1); - } - (void) fprintf(fp, "%ld\n", getpid()); - (void) fclose(fp); - - /* order should be set to node number within cluster */ - order = cfg_iscluster(); - cfg_lfinit(); - - if (!order) { - (void) gettimeofday(&tp, NULL); - srand48(tp.tv_usec); - order = lrand48(); - if (debugfile) { - (void) fprintf(debugfile, "WARNING: order number " - "is 0 -- changing randomly to %d\n", order); - } - } - c = 0; - for (i = 0; (x = cfg_filelock(i, 0)) != CFG_LF_EOF; i++) { - if (x == CFG_LF_AGAIN) { - cfg_readpid(i, &pid); - if (c++ == 0) - spcs_log("cfglockd", NULL, - "init .dscfg.lck slot %d pid %d locked", - i, pid); - DPF((stderr, "client process %ld still alive\n", pid)); - continue; /* can't take lock, must be still alive */ - } - cfg_writepid(i, 0); - (void) cfg_fileunlock(i); - } - - tv.it_interval.tv_sec = TIMEOUT_SECS; - tv.it_interval.tv_usec = 0; - tv.it_value = tv.it_interval; - - bzero(unlock_buf, sizeof (unlock_buf)); - next_q = 0; - build_daemon_list(cp, exe); - if ((lock_soc = socket(pf_inet, SOCK_DGRAM, 0)) < 0) { - (void) fprintf(stderr, "%s: %s\n", program, - gettext("failed to create socket")); - perror("socket"); - spcs_log("cfglockd", NULL, "couldn't create socket"); - exit(1); - } - thishost.sin_family = AF_INET; - thishost.sin_addr.s_addr = INADDR_ANY; - thishost.sin_port = htons(lock_port); - rc = bind(lock_soc, (struct sockaddr *)&thishost, sizeof (thishost)); - if (rc < 0) { - perror("bind"); - spcs_log("cfglockd", NULL, "couldn't bind"); - exit(1); - } - if (getsockname(lock_soc, (struct sockaddr *)&thishost, &len) < 0) - perror("getsockname"); - send_aliveall(); - (void) sigset(SIGALRM, keepalive); - (void) setitimer(ITIMER_REAL, &tv, NULL); - /* - * wait 2 time outs before allowing a lock to find if someone else - * currently has the lock. - */ -} - -#ifdef lint -int -lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - struct lock_msg message_buf; - daemonaddr_t from; - int addrlen; - int rc; - int x = 1; /* kludge to stop warnings from compiler */ - - init(argc, argv); - CRIT_BEGIN(); - while (x) { - CRIT_END(); - addrlen = sizeof (from); - DPF((stderr, "begin recvfrom\n")); - rc = recvfrom(lock_soc, &message_buf, sizeof (message_buf), - 0, (struct sockaddr *)&from, &addrlen); - DPF((stderr, "end recvfrom rc = %d\n", rc)); - CRIT_BEGIN(); - if (rc == sizeof (message_buf)) - dispatch(&message_buf, &from); - else - check_for_write_lock(); - - /* if we own the lock, check to see if the process died */ - if (the_lock.type != LOCK_NOTLOCKED && - the_lock.remote_daemon == NULL) - check_for_dead(); - } - CRIT_END(); - return (0); -} diff --git a/usr/src/cmd/avs/dsstat/Makefile b/usr/src/cmd/avs/dsstat/Makefile deleted file mode 100644 index 8a865c34a7..0000000000 --- a/usr/src/cmd/avs/dsstat/Makefile +++ /dev/null @@ -1,91 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# - -DYNPROG = dsstat - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -SUBDIRS= - -dsstat := POBJS = dsstat.o ii_stats.o sndr_stats.o \ - sdbc_stats.o multi_stats.o common.o report.o - -OBJS= dsstat.o ii_stats.o sndr_stats.o sdbc_stats.o \ - multi_stats.o common.o report.o -SRCS= $(OBJS:%.o=%.c) - -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += -_gcc=-Wno-clobbered -LDLIBS += -lkstat -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY -LINTDIR = $(KBASE)/lintdir -POFILE = dsstat_all.po -POFILES = $(OBJS:%.o=%.po) -LFILE = $(LINTDIR)/dsstat.ln -ROOTLINK = $(ROOTUSRSBIN)/$(PROG) - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SUBDIRS) $(PROG) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK) - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTPROG) $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/dsstat/common.c b/usr/src/cmd/avs/dsstat/common.c deleted file mode 100644 index 45f8145591..0000000000 --- a/usr/src/cmd/avs/dsstat/common.c +++ /dev/null @@ -1,187 +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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <kstat.h> -#include <signal.h> -#include <setjmp.h> - -#include "sdbc_stats.h" -#include "report.h" -#include "common.h" - -static sigjmp_buf env; -static sig_atomic_t sig_raised = 0; -static void sig_handler(int); - -void -sig_handler(int sig) -{ - switch (sig) { - case SIGSEGV: - sig_raised = 1; - siglongjmp(env, sig); - default: - exit(sig); - } -} - -/* - * kstat_retrieve() - populate the ks_data field of the kstat_t structure - * - * This function is a user-land equivalent of a ks_snapshot - * - * parameters - * kstat_ctl_t *kc - kstat_ctl_t structure representing returned from - * kstat_open() - * kstat_t *ksp - kstat_t strcture to popluate ks_data into - * - * returns - * NULL pointer on failure - * kstat_t * structure on success - */ -kstat_t * -kstat_retrieve(kstat_ctl_t *kc, kstat_t *ksp) -{ - - kstat_t *rval; - kstat_named_t *knp; - char *end; - int i; - struct sigaction segv_act; /* default actions */ - - if (ksp == NULL) - return (NULL); - - if (ksp->ks_data == NULL && - kstat_read(kc, ksp, NULL) == -1) - return (NULL); - - rval = (kstat_t *)calloc(1, sizeof (*ksp)); - (void) memcpy(rval, ksp, sizeof (*ksp)); - - rval->ks_data = (void *) calloc(1, ksp->ks_data_size); - (void) memcpy(rval->ks_data, ksp->ks_data, - sizeof (kstat_named_t) * ksp->ks_ndata); - - /* special handling for variable length string KSTAT_DATA_STRING */ - knp = (kstat_named_t *)rval->ks_data; - end = (char *)(knp + ksp->ks_ndata); - for (i = 0; i < ksp->ks_ndata; i++, knp++) { - if (knp->data_type == KSTAT_DATA_STRING && - KSTAT_NAMED_STR_PTR(knp) != NULL) { - /* catch SIGSEGV (bug 6384130) */ - sig_raised = 0; - (void) sigaction(SIGSEGV, NULL, &segv_act); - (void) signal(SIGSEGV, sig_handler); - - (void) strncpy(end, KSTAT_NAMED_STR_PTR(knp), - KSTAT_NAMED_STR_BUFLEN(knp)); - KSTAT_NAMED_STR_PTR(knp) = end; - end += KSTAT_NAMED_STR_BUFLEN(knp); - - /* bug 6384130 */ - (void) sigsetjmp(env, 0); - if (sig_raised) { - bzero(end, KSTAT_NAMED_STR_BUFLEN(knp)); - KSTAT_NAMED_STR_PTR(knp) = end; - end += KSTAT_NAMED_STR_BUFLEN(knp); - } - (void) sigaction(SIGSEGV, &segv_act, NULL); - } - } - - return (rval); -} - -/* - * kstat_value() - retrieve value of a field in a kstat_named_t kstat. - * - * parameters - * kstat_t *ksp - kstat containing the field - * char *name - text string representing the field name - * - * returns - * void * - pointer to data retrieved - */ -void * -kstat_value(kstat_t *ksp, char *name) -{ - kstat_named_t *knm; - - if ((knm = kstat_data_lookup(ksp, name)) == NULL) - return (NULL); - - switch (knm->data_type) { - case KSTAT_DATA_CHAR : - return (knm->value.c); - case KSTAT_DATA_INT32 : - return (&knm->value.i32); - case KSTAT_DATA_UINT32 : - return (&knm->value.ui32); - case KSTAT_DATA_INT64 : - return (&knm->value.i64); - case KSTAT_DATA_UINT64 : - return (&knm->value.ui64); - case KSTAT_DATA_STRING : - return (KSTAT_NAMED_STR_PTR(knm)); - } - - return (NULL); -} - -/* - * kstat_free() - deallocated memory associated with a kstat - * - * paramters - * kstat_t ksp - kstat to be deallocated - * - * returns - * void - */ -void -kstat_free(kstat_t *ksp) -{ - if (ksp != NULL) { - if (ksp->ks_data != NULL) - free(ksp->ks_data); - free(ksp); - } -} - -uint32_t -kstat_delta(kstat_t *pksp, kstat_t *cksp, char *name) -{ - uint32_t *pv, *cv; - - pv = kstat_value(pksp, name); - cv = kstat_value(cksp, name); - - return (u32_delta(*pv, *cv)); -} diff --git a/usr/src/cmd/avs/dsstat/common.h b/usr/src/cmd/avs/dsstat/common.h deleted file mode 100644 index 79805f8569..0000000000 --- a/usr/src/cmd/avs/dsstat/common.h +++ /dev/null @@ -1,43 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _COMMON_H -#define _COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes */ -void *kstat_value(kstat_t *, char *); -kstat_t *kstat_retrieve(kstat_ctl_t *, kstat_t *); -void kstat_free(kstat_t *); -uint32_t kstat_delta(kstat_t *, kstat_t *, char *); - -#ifdef __cplusplus -} -#endif - -#endif /* _COMMON_H */ diff --git a/usr/src/cmd/avs/dsstat/dsstat.c b/usr/src/cmd/avs/dsstat/dsstat.c deleted file mode 100644 index a10ffc0a35..0000000000 --- a/usr/src/cmd/avs/dsstat/dsstat.c +++ /dev/null @@ -1,546 +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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <inttypes.h> -#include <locale.h> - -#include <kstat.h> - -#include "dsstat.h" -#include "multi_stats.h" - -/* Globals */ -int mode = 0; -int interval = 1; -int iterations = 1; -int zflag = 0; -int linesout = 0; - -short hflags = HEADERS_EXL; -short dflags = 0; -short rflags = 0; -vslist_t *vs_top = NULL; - -void -errout(char *msg) -{ - - (void) fprintf(stderr, msg); -} - -void -usage() -{ - errout(gettext( - "\ndsstat [-m <mode>[,<mode>]] [-f | -F] [-z] [-s <sets>] " - "[-r <flags>] \\\n[-d <flags>] [<interval> [<count>]]\n\n")); -} - -void -help() -{ - usage(); - - errout(gettext("\t" - "-d <flags> Specifies the statistics to be displayed\n\n")); - errout(gettext("\t" - " For 'cache' mode\n")); - errout(gettext("\t" - " Valid <flags> are 'rwfsdc', default <flags> are 'sf'\n")); - errout(gettext("\t" - " r=read, w=write, f=flags, s=summary,\n")); - errout(gettext("\t" - " only available for cache mode, need to combine with '-m'\n")); - errout(gettext("\t" - " d=destaged, c=write cancellations\n\n")); - errout(gettext("\t" - " For 'ii' mode;\n")); - errout(gettext("\t" - " Valid <flags> are 'rwtfps', default <flags> are 'sf'\n")); - errout(gettext("\t" - " r=read, w=write, t=timing, f=flags, p=percentages,\n")); - errout(gettext("\t" - " s=summary\n\n")); - errout(gettext("\t" - " For 'sndr' mode;\n")); - errout(gettext("\t" - " Valid <flags> are'rwtfpsq', default <flags> are 'spf'\n")); - errout(gettext("\t" - " r=read, w=write, t=timing, f=flags, p=percentages,\n")); - errout(gettext("\t" - " s=summary\n")); - errout(gettext("\t" - " only available for sndr mode, need to combine with '-m'\n")); - errout(gettext("\t" - " q=queue\n\n")); - errout(gettext("\t" - "-f prints field headers once for each iteration\n\n")); - errout(gettext("\t" - "-F prints field headers once, at the start of reporting\n\n")); - errout(gettext("\t" - "-h prints detailed usage message\n\n")); - errout(gettext("\t" - "-m <mode>[,<mode>] where mode is, 'cache', 'ii', or 'sndr'\n\n")); - errout(gettext("\t" - " Multiple modes may be specified as a comma separated list,\n")); - errout(gettext("\t" - " or multiple -m switches may be used.\n\n")); - errout(gettext("\t" - "-r <flags> specifies components to be reported\n\n")); - errout(gettext("\t" - " For 'cache' mode, this option is not used.\n\n")); - errout(gettext("\t" - " For 'ii' mode;\n")); - errout(gettext("\t" - " Valid <flags> are 'msbo', default <flags> are 'msbo'\n")); - errout(gettext("\t" - " m=master, s=shadow, b=bitmap, o=overflow\n\n")); - errout(gettext("\t" - " For 'sndr' mode;\n")); - errout(gettext("\t" - " Valid <flags> are 'nb', default <flags> are 'nb'\n")); - errout(gettext("\t" - " n=network, b=bitmap\n\n")); - errout(gettext("\t" - "-s <sets> outputs specified sets\n")); - errout(gettext("\t" - " Where <sets> is a comma delimited list of set names\n\n")); - errout(gettext("\t" - "-z suppress reports with zero value (no activity)\n\n")); - errout(gettext("\t" - "<interval> is the number of seconds between reports\n\n")); - errout(gettext("\t" - "<count> is the number of reports to be generated\n\n")); -} - -void -fail(int err, char *msg) -{ - errout(gettext("\ndsstat: ")); - errout(msg); - - usage(); - - errout(gettext("For detailed usage run \"dsstat -h\"\n")); - - exit(err); -} - -int -set_mode(char *user_modes) -{ - char *m; - int local_mode = 0; - - for (m = strtok(user_modes, ","); m != NULL; m = strtok(NULL, ",")) { - if (local_mode != 0) { - local_mode |= MULTI; - } - - if (strncasecmp("sndr", m, strlen(m)) == 0) { - local_mode |= SNDR; - continue; - } - - if (strncasecmp("ii", m, strlen(m)) == 0) { - local_mode |= IIMG; - continue; - } - - if (strncasecmp("cache", m, strlen(m)) == 0) { - local_mode |= SDBC; - continue; - } - - fail(DSSTAT_EINVAL, gettext("Invalid mode specified")); - } - - return (local_mode); -} - -short -set_dflags(char *flags) -{ - int index; - short user_dflags = 0; - - for (index = 0; index < strlen(flags); index++) { - switch (flags[index]) { - case 'r': - user_dflags |= READ; - break; - case 'w': - user_dflags |= WRITE; - break; - case 't': - user_dflags |= TIMING; - break; - case 'f': - user_dflags |= FLAGS; - break; - case 'p': - user_dflags |= PCTS; - break; - case 's': - user_dflags |= SUMMARY; - break; - case 'd': - user_dflags |= DESTAGED; - break; - case 'c': - user_dflags |= WRCANCEL; - break; - case 'h': - user_dflags |= RATIO; - break; - case 'q': - user_dflags |= ASYNC_QUEUE; - break; - default: - fail(DSSTAT_EINVAL, - gettext("Invalid display-flags set\n")); - } - } - - return (user_dflags); -} - -short -set_rflags(char *flags) -{ - int index; - short user_rflags = 0; - - for (index = 0; index < strlen(flags); index++) { - switch (flags[index]) { - case 'm': - user_rflags |= IIMG_MST; - break; - case 's': - user_rflags |= IIMG_SHD; - break; - case 'b': - user_rflags |= IIMG_BMP; - user_rflags |= SNDR_BMP; - break; - case 'o': - user_rflags |= IIMG_OVR; - break; - case 'n': - user_rflags |= SNDR_NET; - break; - default: - fail(DSSTAT_EINVAL, - gettext("Invalid report-flags set\n")); - } - } - - return (user_rflags); -} - -void -set_vol_list(char *list) -{ - vslist_t *pre; - vslist_t *newvol; - vslist_t *vslist; - char *volume; - - for (volume = strtok(list, ","); volume != NULL; - volume = strtok(NULL, ",")) { - int dup = 0; - char *vh = NULL; - char *vn = NULL; - - /* get user-specified set information */ - if ((vn = strchr(volume, ':')) == NULL) { - vn = volume; - } else { - *vn = '\0'; - vn++; - vh = volume; - } - - /* check for duplicates */ - dup = 0; - - for (vslist = vs_top; vslist != NULL; vslist = vslist->next) { - if (vslist->volhost && vh) { - if (strcmp(vslist->volhost, vh) == 0 && - strcmp(vslist->volname, vn) == 0) - dup = 1; - } else { - if (strcmp(vslist->volname, vn) == 0) - dup = 1; - } - - pre = vslist; - } - - if (dup) - continue; - - /* initialize new vslist record */ - newvol = (vslist_t *)calloc(1, sizeof (vslist_t)); - - newvol->volname = (char *)calloc((strlen(vn) + 1), - sizeof (char)); - (void) strcpy(newvol->volname, vn); - - if (vh == NULL) - goto save; - - newvol->volhost = (char *)calloc((strlen(vh) + 1), - sizeof (char)); - (void) strcpy(newvol->volhost, vh); - -save: - /* save record */ - if (vs_top == NULL) { - vslist = vs_top = newvol; - vslist->next = NULL; - continue; - } - - if (vslist == NULL) { - vslist = pre->next = newvol; - vslist->next = NULL; - continue; - } - } -} - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - - int c; - int error; - short user_dflags = 0; - short user_rflags = 0; - - /* Parse command line */ - while ((c = getopt(argc, argv, "d:fFhm:r:s:z")) != EOF) { - switch (c) { - case 'd': /* what to display */ - user_dflags = set_dflags(optarg); - break; - case 'f': - hflags = HEADERS_ATT; - break; - case 'F': - hflags = HEADERS_BOR; - break; - case 'h': /* usage */ - help(); - exit(0); - break; - case 'm': /* Mode */ - mode |= set_mode(optarg); - break; - case 'r': /* what to report on */ - user_rflags = set_rflags(optarg); - break; - case 's': - set_vol_list(optarg); - break; - case 'z': - zflag = 1; - break; - - default: - fail(DSSTAT_EINVAL, - "Invalid argument specified\n"); - } - } - - /* Parse additional arguments */ - if (optind < argc) { - if ((interval = atoi(argv[optind])) <= 0) { - fail(DSSTAT_EINVAL, - gettext("Invalid interval specified.\n")); - } else { - iterations = -1; - } - - optind++; - - if (optind < argc) { - if ((iterations = atoi(argv[optind])) <= 0) { - fail(DSSTAT_EINVAL, - gettext("Invalid count specified.\n")); - } - } - - optind++; - } - - if (optind < argc) { - fail(DSSTAT_EINVAL, - gettext("Too many parameters specified.\n")); - } - - if (mode == 0) - mode |= MULTI | IIMG | SNDR | SDBC; - - /* Select statistics to gather */ - if (mode & SNDR) { - if (! (mode & MULTI)) { - if (user_rflags & IIMG_BMP) - user_rflags ^= IIMG_BMP; - - if ((user_dflags | SNDR_DIS_MASK) != SNDR_DIS_MASK) { - fail(DSSTAT_EINVAL, gettext("Invalid " - "display-flags for RemoteMirror\n")); - } - - if ((user_rflags | SNDR_REP_MASK) != SNDR_REP_MASK) { - fail(DSSTAT_EINVAL, - gettext("Invalid report-flags for " - "Remote Mirror\n")); - } - } - - if ((mode & MULTI) && (user_dflags & ASYNC_QUEUE)) { - fail(DSSTAT_EINVAL, gettext("Remote Mirror async. queue" - "statistics can not be displayed with mutiple " - "modes.")); - } - - if (user_dflags) - dflags = user_dflags; - else - dflags |= (SUMMARY | PCTS | FLAGS | RATIO); - - if (user_rflags) - rflags = user_rflags; - else - rflags |= (SNDR_NET | SNDR_BMP); - } - - if (mode & IIMG) { - if (! (mode & MULTI)) { - if (user_rflags & SNDR_BMP) - user_rflags ^= SNDR_BMP; - - if ((user_dflags | IIMG_DIS_MASK) != IIMG_DIS_MASK) { - fail(DSSTAT_EINVAL, - gettext("Invalid display-flags for " - "Point-in-Time Copy\n")); - } - - if ((user_rflags | IIMG_REP_MASK) != IIMG_REP_MASK) { - fail(DSSTAT_EINVAL, - gettext("Invalid report-flags for " - "Point-in-Time Copy\n")); - } - } - - if (user_dflags) - dflags = user_dflags; - else - dflags |= (SUMMARY | PCTS | FLAGS | RATIO); - - if (user_rflags) - rflags = user_rflags; - else - rflags |= (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR); - } - - if (mode & SDBC) { - if (! (mode & MULTI)) { - if ((user_dflags | CACHE_DIS_MASK) != CACHE_DIS_MASK) { - fail(DSSTAT_EINVAL, gettext("Invalid " - "display-flags for CACHE\n")); - } - - if ((user_rflags | CACHE_REP_MASK) != CACHE_REP_MASK) { - fail(DSSTAT_EINVAL, gettext("Invalid " - "report-flags for CACHE\n")); - } - } else { - if ((user_dflags & DESTAGED) || (user_dflags & WRCANCEL)) { - if (user_dflags & DESTAGED) - fail(DSSTAT_EINVAL, gettext("Cache, destaged " - "statistics can not be displayed with mutiple " - "modes.")); - else - fail(DSSTAT_EINVAL, gettext("Cache, write " - "cancellations " - "statistics can not be displayed with mutiple " - "modes.")); - } - } - - if (user_dflags) - dflags = user_dflags; - else - if (mode & MULTI) - dflags |= (SUMMARY); - else - dflags |= (SUMMARY | FLAGS); - - if (user_rflags) - rflags = user_rflags; - else - rflags |= user_rflags; - } - - error = do_stats(); - - if (error == EAGAIN) { - fail(DSSTAT_NOSTAT, gettext("No statistics available for the " - "specified mode(s).\n")); - } - - if (error == EINVAL) { - fail(DSSTAT_EINVAL, - gettext("Invalid kstat format detected.\n")); - } - - if (error == ENOMEM) { - fail(DSSTAT_ENOMEM, - gettext("Unable to open kstat device for reading.\n")); - } - - if (error == -1) { - if (execv("/usr/sbin/dsstat", argv) != 0) { - fail(DSSTAT_EMAP, gettext("Kstat is invalid.\n")); - } - } - - if (error) { - fail(DSSTAT_EUNKNWN, gettext("An unknown error occured.\n")); - } - - return (0); -} diff --git a/usr/src/cmd/avs/dsstat/dsstat.h b/usr/src/cmd/avs/dsstat/dsstat.h deleted file mode 100644 index eb73bcd48c..0000000000 --- a/usr/src/cmd/avs/dsstat/dsstat.h +++ /dev/null @@ -1,111 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _DSSTAT_H -#define _DSSTAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct vslist_s -{ - char *volname; - char *volhost; - struct vslist_s *next; -} vslist_t; - -extern int mode; -extern int interval; -extern int iterations; -extern int zflag; -extern int linesout; -extern short hflags; -extern short dflags; -extern short rflags; -extern vslist_t *vs_top; - -/* kstat named character limit */ -#define NAMED_LEN 15 - -/* Mode */ -#define MULTI 0x01 -#define SNDR 0x02 -#define IIMG 0x04 -#define SDBC 0x08 - -/* Error codes */ -#define DSSTAT_SUCCESS 0 /* Success */ -#define DSSTAT_NOSTAT 1 /* No Statistics Avaiable */ -#define DSSTAT_EINVAL 2 /* Invalid Argument */ -#define DSSTAT_ENOMEM 3 /* No Memory Available To Get Statistics */ -#define DSSTAT_EUNKNWN 4 /* Unknown Error */ -#define DSSTAT_EMAP 5 /* Mapped kstat memory is invalid */ - -/* Report flags */ -#define IIMG_MST 0x01 -#define IIMG_SHD 0x02 -#define IIMG_BMP 0x04 -#define IIMG_OVR 0x08 - -#define SNDR_PRI 0x10 -#define SNDR_NET 0x20 -#define SNDR_BMP 0x40 - -/* Display flags */ -#define SUMMARY 0x01 -#define READ 0x02 -#define WRITE 0x04 -#define TIMING 0x08 -#define FLAGS 0x10 -#define PCTS 0x20 -#define DESTAGED 0x40 -#define WRCANCEL 0x80 -#define RATIO 0x100 -#define ASYNC_QUEUE 0x200 - -/* Flag masks */ -#define SNDR_REP_MASK (SNDR_PRI | SNDR_NET | SNDR_BMP) -#define SNDR_DIS_MASK (SUMMARY | READ | WRITE | TIMING | FLAGS | PCTS | \ - RATIO | ASYNC_QUEUE) - -#define IIMG_REP_MASK (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR) -#define IIMG_DIS_MASK (SUMMARY | READ | WRITE | TIMING | FLAGS | PCTS | RATIO) - -#define CACHE_REP_MASK 0 -#define CACHE_DIS_MASK (SUMMARY | READ | WRITE | FLAGS | DESTAGED | WRCANCEL) - -/* Field header defines */ -#define DISPLAY_LINES 19 -#define HEADERS_OUT 0x01 /* flag to show headers output for cycle */ -#define HEADERS_BOR 0x02 /* field headers at beginning of run */ -#define HEADERS_ATT 0x04 /* field headers all the time */ -#define HEADERS_EXL 0x08 /* field headers every X lines */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DSSTAT_H */ diff --git a/usr/src/cmd/avs/dsstat/ii_stats.c b/usr/src/cmd/avs/dsstat/ii_stats.c deleted file mode 100644 index e37ea891cb..0000000000 --- a/usr/src/cmd/avs/dsstat/ii_stats.c +++ /dev/null @@ -1,811 +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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <sys/mutex.h> - -#include <kstat.h> - -#include <sys/unistat/spcs_s.h> -#include <sys/nsctl/dsw.h> -#include "../../../uts/common/avs/ns/dsw/dsw_dev.h" -#include <sys/nsctl/dsw_dev.h> - -#include "sdbc_stats.h" -#include "ii_stats.h" - -#include "dsstat.h" -#include "common.h" -#include "report.h" - -static iistat_t *ii_top = NULL; - -void ii_add_stat(iistat_t *); -iistat_t *ii_del_stat(iistat_t *); - -int ii_value_check(iistat_t *iistat); -int ii_validate(kstat_t *ksp); -int ii_vol_selected(kstat_t *); - -/* - * ii_discover() - looks for new statistics to be monitored. - * Verifies that any statistics found are now already being - * monitored. - * - */ -int -ii_discover(kstat_ctl_t *kc) -{ - static int validated = 0; - - kstat_t *ksp; - - /* Loop on all kstats */ - for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { - char *kname; - iistat_t *cur; - iistat_t *iistat = NULL; - kstat_t *mst_ksp; - kstat_t *shd_ksp; - kstat_t *bmp_ksp; - kstat_t *ovr_ksp; - - /* Search for II set */ - if (strcmp(ksp->ks_class, II_KSTAT_CLASS) != 0) - continue; - - if (kstat_read(kc, ksp, NULL) == -1) - continue; - - /* - * Validate kstat structure - */ - if (! validated) { - if (ii_validate(ksp)) - return (EINVAL); - - validated++; - } - - /* - * Duplicate check - */ - for (cur = ii_top; cur != NULL; cur = cur->next) { - char *cur_vname, *tst_vname; - uint32_t cur_inst, tst_inst; - - cur_vname = cur->pre_set->ks_name; - cur_inst = cur->pre_set->ks_instance; - - tst_vname = ksp->ks_name; - tst_inst = ksp->ks_instance; - - if (strcmp(cur_vname, tst_vname) == 0 && - cur_inst == tst_inst) - goto next; - } - - /* - * Initialize new record - */ - iistat = (iistat_t *)calloc(1, sizeof (iistat_t)); - - /* - * Set kstat - */ - iistat->pre_set = kstat_retrieve(kc, ksp); - - if (iistat->pre_set == NULL) - goto next; - - iistat->collected |= GOT_SETSTAT; - - /* - * Master kstat - */ - kname = kstat_value(iistat->pre_set, DSW_SKSTAT_MSTIO); - - mst_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - iistat->pre_mst = kstat_retrieve(kc, mst_ksp); - - if (iistat->pre_mst == NULL) - goto next; - - iistat->collected |= GOT_MSTSTAT; - - /* - * Shadow kstat - */ - kname = kstat_value(iistat->pre_set, DSW_SKSTAT_SHDIO); - - shd_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - iistat->pre_shd = kstat_retrieve(kc, shd_ksp); - - if (iistat->pre_shd == NULL) - goto next; - - iistat->collected |= GOT_SHDSTAT; - - /* - * Bitmap kstat - */ - kname = kstat_value(iistat->pre_set, DSW_SKSTAT_BMPIO); - - bmp_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - iistat->pre_bmp = kstat_retrieve(kc, bmp_ksp); - - if (iistat->pre_bmp == NULL) - goto next; - - iistat->collected |= GOT_BMPSTAT; - - /* - * Overflow kstat - */ - kname = kstat_value(iistat->pre_set, DSW_SKSTAT_OVRIO); - - ovr_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - iistat->pre_ovr = kstat_retrieve(kc, ovr_ksp); - - if (iistat->pre_ovr == NULL) - goto next; - - iistat->collected |= GOT_OVRSTAT; - -next: - /* - * Check if we got a complete set of stats - */ - if (iistat == NULL) - continue; - - if (IIMG_COMPLETE(iistat->collected)) { - (void) ii_del_stat(iistat); - continue; - } - - /* - * Add to linked list - */ - ii_add_stat(iistat); - } - - if (ii_top == NULL) - return (EAGAIN); - - return (0); -} - -/* - * ii_update() - updates all of the statistics currently being monitored. - * - */ -int -ii_update(kstat_ctl_t *kc) -{ - iistat_t *cur; - - for (cur = ii_top; cur != NULL; cur = cur->next) { - char volname[KSTAT_STRLEN + 1]; - char *kname; - - kstat_t *ksp = NULL; - - cur->collected = 0; - - /* - * Age off old stats - */ - if (cur->cur_set != NULL) { - kstat_free(cur->pre_set); - kstat_free(cur->pre_mst); - kstat_free(cur->pre_shd); - kstat_free(cur->pre_bmp); - - cur->pre_set = cur->cur_set; - cur->pre_mst = cur->cur_mst; - cur->pre_shd = cur->cur_shd; - cur->pre_bmp = cur->cur_bmp; - - if (cur->cur_ovr != NULL) { - kstat_free(cur->pre_ovr); - cur->pre_ovr = cur->cur_ovr; - } - } - - /* - * Set kstat - */ - (void) strncpy(volname, cur->pre_set->ks_name, KSTAT_STRLEN); - volname[KSTAT_STRLEN] = '\0'; - - ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, volname); - - if ((cur->cur_set = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_SETSTAT; - - /* - * Validate set - */ - if (strcmp(cur->pre_set->ks_name, cur->cur_set->ks_name) != 0 || - cur->pre_set->ks_instance != cur->cur_set->ks_instance) - continue; - - /* - * Master kstat - */ - kname = kstat_value(cur->cur_set, DSW_SKSTAT_MSTIO); - - ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - - if ((cur->cur_mst = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_MSTSTAT; - - /* - * Shadow kstat - */ - kname = kstat_value(cur->cur_set, DSW_SKSTAT_SHDIO); - - ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - - if ((cur->cur_shd = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_SHDSTAT; - - /* - * Bitmap kstat - */ - kname = kstat_value(cur->pre_set, DSW_SKSTAT_BMPIO); - - ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - - if ((cur->cur_bmp = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_BMPSTAT; - - /* - * Overflow kstat - */ - kname = kstat_value(cur->cur_set, DSW_SKSTAT_OVRIO); - - ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname); - - if (ksp == NULL) { - if (cur->pre_ovr != NULL) { - kstat_free(cur->pre_ovr); - cur->pre_ovr = NULL; - } - if (cur->cur_ovr != NULL) { - kstat_free(cur->cur_ovr); - cur->cur_ovr = NULL; - } - continue; - } - - if (cur->pre_ovr == NULL) { - if ((cur->pre_ovr = kstat_retrieve(kc, ksp)) == NULL) - continue; - } else { - if ((cur->cur_ovr = kstat_retrieve(kc, ksp)) == NULL) - continue; - } - - cur->collected |= GOT_OVRSTAT; - } - - return (0); -} - -/* - * ii_report() - outputs statistics for the statistics currently being - * monitored. Deletes statistics for volumes that have been disabled. - * - */ -int -ii_report() -{ - uint32_t *flags; - int padsz = 0; - char pad[20] = {0}; - iistat_t *cur, *pre = NULL; - - if (ii_top == NULL) { - return (0); - } - - /* Create padding string for secondary report lines */ - if (dflags & FLAGS) { - padsz += STAT_HDR_SIZE; - padsz += STAT_HDR_SIZE; - } - - if (dflags & PCTS) - padsz += PCT_HDR_SIZE; - - if (padsz) { - char fmt[20]; - (void) sprintf(fmt, "%%%ds", padsz); - (void) sprintf(pad, fmt, ""); - } - - for (cur = ii_top; cur; /* CSTYLED */) { - int first = 1; - char data[20] = {0}; - - /* Check to see if this is this a complete */ - if (IIMG_COMPLETE(cur->collected)) { - char *c; - char vol[(NAMED_LEN * 4) + 1] = {0}; - int offset; - iistat_t *next; - - /* notify user of set being disabled */ - c = kstat_value(cur->pre_set, DSW_SKSTAT_SETA); - (void) strncpy(vol, c, NAMED_LEN); - c = kstat_value(cur->pre_set, DSW_SKSTAT_SETB); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->pre_set, DSW_SKSTAT_SETC); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->pre_set, DSW_SKSTAT_SETD); - (void) strncat(vol, c, NAMED_LEN); - - offset = strlen(vol) - NAMED_LEN; - - if (offset < 0) - offset = 0; - - (void) printf(DATA_C16, vol + offset); - (void) printf(" %s\n", II_DISABLED); - - /* free memory and remove stat from list */ - next = ii_del_stat(cur); - - if (! pre) - cur = ii_top = next; - else - cur = pre->next = next; - - continue; - } - - /* Check to see if the user specified this volume */ - if (! ii_vol_selected(cur->pre_set)) - goto next; - - /* Check to see if zflag applies */ - if (zflag && ii_value_check(cur) == 0) - goto next; - - /* Calculate flags */ - flags = kstat_value(cur->cur_set, DSW_SKSTAT_FLAGS); - - if (dflags & FLAGS) { - - char c[STAT_HDR_SIZE]; - char vtype[STAT_HDR_SIZE]; - char vstat[STAT_HDR_SIZE]; - - if (*flags & DSW_GOLDEN) - (void) strcpy(c, II_INDEPENDENT); - else - (void) strcpy(c, II_DEPENDENT); - - (void) sprintf(vtype, DATA_C2, c); - (void) strcat(data, vtype); - - if (*flags & DSW_COPYINGP) - (void) strcpy(c, II_COPYING); - else - (void) strcpy(c, NO_INFO); - - - (void) sprintf(vstat, DATA_C2, c); - (void) strcat(data, vstat); - } - - /* Calculate sync needed precentage */ - if (dflags & PCTS) { - char snpct[10]; - uint32_t *chkbits; - uint32_t *cpybits; - uint32_t *shdbits; - uint32_t *volsize; - float pct; - - cpybits = - kstat_value(cur->cur_set, DSW_SKSTAT_COPYBITS); - - shdbits = - kstat_value(cur->cur_set, DSW_SKSTAT_SHDBITS); - - volsize = - kstat_value(cur->cur_set, DSW_SKSTAT_SIZE); - - *volsize /= DSW_SIZE; - - chkbits = *cpybits >= *shdbits ? cpybits : shdbits; - - pct = ((float)*chkbits / *volsize) * 100.0; - - (void) sprintf(snpct, DATA_F62, pct); - - (void) strcat(data, snpct); - } - - /* Master statistics */ - if (rflags & IIMG_MST) { - char *c; - char vol[(NAMED_LEN * 4) + 1] = {0}; - int offset; - - c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTA); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTB); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTC); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTD); - (void) strncat(vol, c, NAMED_LEN); - - offset = strlen(vol) - NAMED_LEN; - - if (offset < 0) - offset = 0; - - header(); - (void) printf(DATA_C16, vol + offset); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, II_MASTER); - - if (*flags & DSW_MSTOFFLINE) { - (void) printf(" <<offline>>"); - linesout++; - } else { - io_report(cur->cur_mst, cur->pre_mst, - sdbc_getstat(vol + offset)); - } - - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } - - /* Shadow statistics */ - if (rflags & IIMG_SHD) { - char *c; - char vol[(NAMED_LEN * 4) + 1] = {0}; - int offset; - - c = kstat_value(cur->cur_set, DSW_SKSTAT_SETA); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_SETB); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_SETC); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_SETD); - (void) strncat(vol, c, NAMED_LEN); - - offset = strlen(vol) - NAMED_LEN; - - if (offset < 0) - offset = 0; - - header(); - (void) printf(DATA_C16, vol + offset); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, II_SHADOW); - - if (*flags & DSW_SHDOFFLINE) { - (void) printf(" <<offline>>"); - linesout++; - } else { - io_report(cur->cur_shd, cur->pre_shd, - sdbc_getstat(vol + offset)); - } - - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } - - /* Bitmap statistics */ - if (rflags & IIMG_BMP) { - char *c; - char vol[(NAMED_LEN * 4) + 1] = {0}; - int offset; - - c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPA); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPB); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPC); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPD); - (void) strncat(vol, c, NAMED_LEN); - - offset = strlen(vol) - NAMED_LEN; - - if (offset < 0) - offset = 0; - - header(); - (void) printf(DATA_C16, vol + offset); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, II_BITMAP); - - if (*flags & DSW_BMPOFFLINE) { - (void) printf(" <<offline>>"); - linesout++; - } else { - io_report(cur->cur_bmp, cur->pre_bmp, - sdbc_getstat(vol + offset)); - } - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } - - /* Overflow statistics */ - if (rflags & IIMG_OVR) { - char *c; - char msg[20] = {0}; - char vol[(NAMED_LEN * 4) + 1] = {0}; - int offset; - - if (cur->cur_ovr == NULL && cur->pre_ovr != NULL) - (void) strcpy(msg, " <<attached>>"); - - if (! (cur->collected & GOT_OVRSTAT)) - (void) strcpy(msg, " <<not attached>>"); - - c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRA); - (void) strncpy(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRB); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRC); - (void) strncat(vol, c, NAMED_LEN); - c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRD); - (void) strncat(vol, c, NAMED_LEN); - - offset = strlen(vol) - NAMED_LEN; - - if (offset < 0) - offset = 0; - - header(); - (void) printf(DATA_C16, vol + offset); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, II_OVERFLOW); - - if (strlen(msg)) { - (void) printf("%s\n", msg); - linesout++; - goto next; - } - - if (*flags & DSW_OVROFFLINE) { - (void) printf(" <<offline>>"); - linesout++; - } else { - io_report(cur->cur_ovr, cur->pre_ovr, - sdbc_getstat(vol + offset)); - } - - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } - - -next: - pre = cur; - cur = cur->next; - } - - return (0); -} - -/* - * ii_add_stat() - adds a fully populated iistat_t structure - * to the linked list of currently monitored kstats. The structure - * will be added in alphabetical order, using the volume name of - * the shadow volume as the key. - * - */ -void -ii_add_stat(iistat_t *iistat) -{ - - iistat_t *cur; - - if (ii_top == NULL) { - ii_top = iistat; - return; - } - - for (cur = ii_top; cur != NULL; cur = cur->next) { - if (strcmp(cur->pre_set->ks_name, - iistat->pre_set->ks_name) <= 0) { - /* - * If we get to the last item in the list, then just - * add this one to the end - */ - if (cur->next == NULL) { - cur->next = iistat; - return; - } - - if (strcmp(cur->next->pre_set->ks_name, - iistat->pre_set->ks_name) > 0) { - iistat->next = cur->next; - cur->next = iistat; - return; - } - } else { - if (cur == ii_top) - ii_top = iistat; - - iistat->next = cur; - - return; - } - } -} - -/* - * ii_del_stat() - deallocate memory for the structure being - * passed in. - * - * parameters - * iistat_t *iistat - structure to be deallocated - * - * returns - * iistat_t * - pointer to the "next" structures in the - * linked list. May be NULL if we are removing the last - * structure in the linked list. - * - */ -iistat_t * -ii_del_stat(iistat_t *iistat) -{ - - iistat_t *next = iistat->next; - - kstat_free(iistat->pre_set); - kstat_free(iistat->pre_mst); - kstat_free(iistat->pre_shd); - kstat_free(iistat->pre_bmp); - kstat_free(iistat->pre_ovr); - kstat_free(iistat->cur_set); - kstat_free(iistat->cur_mst); - kstat_free(iistat->cur_shd); - kstat_free(iistat->cur_bmp); - kstat_free(iistat->cur_ovr); - - free(iistat); - - return (next); -} - -int -ii_value_check(iistat_t *iistat) -{ - if (IIMG_COMPLETE(iistat->collected)) - return (1); - - if (io_value_check(iistat->pre_mst->ks_data, - iistat->cur_mst->ks_data)) { - return (1); - } - - if (io_value_check(iistat->pre_shd->ks_data, - iistat->cur_shd->ks_data)) { - return (1); - } - - if (io_value_check(iistat->pre_bmp->ks_data, - iistat->cur_bmp->ks_data)) { - return (1); - } - - if (iistat->pre_ovr && iistat->cur_ovr) { - if (io_value_check(iistat->pre_ovr->ks_data, - iistat->cur_ovr->ks_data)) { - return (1); - } - } - - return (0); -} - -int -ii_validate(kstat_t *ksp) -{ - if (! kstat_value(ksp, DSW_SKSTAT_MSTIO) || - ! kstat_value(ksp, DSW_SKSTAT_SHDIO) || - ! kstat_value(ksp, DSW_SKSTAT_BMPIO) || - ! kstat_value(ksp, DSW_SKSTAT_OVRIO) || - ! kstat_value(ksp, DSW_SKSTAT_FLAGS) || - ! kstat_value(ksp, DSW_SKSTAT_MSTA) || - ! kstat_value(ksp, DSW_SKSTAT_SETA) || - ! kstat_value(ksp, DSW_SKSTAT_BMPA) || - ! kstat_value(ksp, DSW_SKSTAT_OVRA) || - ! kstat_value(ksp, DSW_SKSTAT_SHDBITS) || - ! kstat_value(ksp, DSW_SKSTAT_COPYBITS) || - ! kstat_value(ksp, DSW_SKSTAT_SIZE)) - return (1); - - return (0); -} - -int -ii_vol_selected(kstat_t *ksp) -{ - vslist_t *vslist = vs_top; - - for (vslist = vs_top; vslist != NULL; vslist = vslist->next) { - char *vn; - int off = 0; - - vn = ksp->ks_name; - - if ((off = strlen(vn) - NAMED_LEN) <= 0) { - off = 0; - } - - if (strcmp(vslist->volname, &vn[off]) == 0) { - break; - } - } - - if (vs_top != NULL && vslist == NULL) { - return (0); - } else { - return (1); - } -} diff --git a/usr/src/cmd/avs/dsstat/ii_stats.h b/usr/src/cmd/avs/dsstat/ii_stats.h deleted file mode 100644 index 35307b4b95..0000000000 --- a/usr/src/cmd/avs/dsstat/ii_stats.h +++ /dev/null @@ -1,82 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _II_STATS_H -#define _II_STATS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define GOT_SETSTAT 0x01 -#define GOT_MSTSTAT 0x02 -#define GOT_SHDSTAT 0x04 -#define GOT_BMPSTAT 0x08 -#define GOT_OVRSTAT 0x10 - -#define GOT_COMPLETE_IIMG (GOT_SETSTAT|GOT_MSTSTAT|GOT_SHDSTAT|GOT_BMPSTAT) - -#define IIMG_COMPLETE(x) (((x) & (GOT_COMPLETE_IIMG)) != (GOT_COMPLETE_IIMG)) - -/* II strings */ -#define II_KSTAT_MODULE "ii" -#define II_KSTAT_CLASS "iiset" - -#define II_DISABLED "<<set disabled>>" -#define II_INDEPENDENT "I" -#define II_DEPENDENT "D" -#define II_COPYING "C" -#define II_MASTER "mst" -#define II_SHADOW "shd" -#define II_BITMAP "bmp" -#define II_OVERFLOW "ovr" - - -typedef struct iistat_s -{ - kstat_t *pre_set; - kstat_t *pre_mst; - kstat_t *pre_shd; - kstat_t *pre_bmp; - kstat_t *pre_ovr; - kstat_t *cur_set; - kstat_t *cur_mst; - kstat_t *cur_shd; - kstat_t *cur_bmp; - kstat_t *cur_ovr; - int collected; - struct iistat_s *next; -} iistat_t; - -/* Prototypes */ -int ii_discover(kstat_ctl_t *); -int ii_update(kstat_ctl_t *); -int ii_report(); - -#ifdef __cplusplus -} -#endif - -#endif /* _II_STATS_H */ diff --git a/usr/src/cmd/avs/dsstat/multi_stats.c b/usr/src/cmd/avs/dsstat/multi_stats.c deleted file mode 100644 index cac76d4cd6..0000000000 --- a/usr/src/cmd/avs/dsstat/multi_stats.c +++ /dev/null @@ -1,206 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <stdio.h> -#include <unistd.h> -#include <errno.h> - -#include <kstat.h> - -#include "ii_stats.h" -#include "sdbc_stats.h" -#include "sndr_stats.h" - -#include "multi_stats.h" - -#include "dsstat.h" -#include "common.h" -#include "report.h" - -/* - * do_stats() - called by main() to start monitoring - * - */ -int -do_stats() -{ - int error; - int pass; - - /* Collection/reporting loop */ - for (pass = 0; ; pass++) { /* CSTYLED */ - if (iterations != -1 && pass >= iterations) - return (0); - - error = discover(); - - if (error == ENOMEM || error == EINVAL) - return (error); - - if (error == EAGAIN && pass == 0) - return (error); - - (void) sleep(interval); - - if ((error = update()) != 0) - return (error); - - if (report()) - break; - } - - /* No stats on this system */ - return (EAGAIN); -} - -int -discover() -{ - int err = 0; - - int sdbc_err = 0; - int sndr_err = 0; - int ii_err = 0; - - kstat_ctl_t *kc; - - if ((kc = kstat_open()) == NULL) - return (ENOMEM); - - if (mode & SDBC) { - sdbc_err = sdbc_discover(kc); - err = sdbc_err; - if (sdbc_err && !(mode & MULTI)) - goto fail; - if (sdbc_err && (mode & MULTI) && sdbc_err != EAGAIN) - goto fail; - } - - if (mode & SNDR) { - sndr_err = sndr_discover(kc); - err = sndr_err; - if (sndr_err && !(mode & MULTI)) - goto fail; - if (sndr_err && (mode & MULTI) && sndr_err != EAGAIN) - goto fail; - } - - if (mode & IIMG) { - ii_err = ii_discover(kc); - err = ii_err; - if (ii_err && !(mode & MULTI)) - goto fail; - if (ii_err && ii_err != EAGAIN && (mode & MULTI)) - goto fail; - } - - (void) kstat_close(kc); - if (sdbc_err && sndr_err && ii_err) - return (err); - else - return (0); - -fail: - (void) kstat_close(kc); - return (err); -} - -int -update() -{ - int err = 0; - - int sdbc_err = 0; - int sndr_err = 0; - int ii_err = 0; - - kstat_ctl_t *kc; - - if ((kc = kstat_open()) == NULL) - goto fail; - - if (mode & SDBC) { - sdbc_err = sdbc_update(kc); - err = sdbc_err; - if (sdbc_err && !(mode & MULTI)) - goto fail; - if (sdbc_err && (mode & MULTI) && sdbc_err != EAGAIN) - goto fail; - } - - if (mode & SNDR) { - sndr_err = sndr_update(kc); - err = sndr_err; - if (sndr_err && !(mode & MULTI)) - goto fail; - if (sndr_err && (mode & MULTI) && sndr_err != EAGAIN) - goto fail; - } - - if (mode & IIMG) { - ii_err = ii_update(kc); - err = ii_err; - if (ii_err && !(mode & MULTI)) - goto fail; - if (ii_err && (mode & MULTI) && ii_err != EAGAIN) - goto fail; - } - - (void) kstat_close(kc); - if (sdbc_err && sndr_err && ii_err) - return (err); - else - return (0); - -fail: - (void) kstat_close(kc); - return (err); -} - -int -report() -{ - int err = 0; - - int sdbc_err = 0; - int sndr_err = 0; - int ii_err = 0; - - hflags &= (HEADERS_EXL | HEADERS_ATT | HEADERS_BOR); - - if (mode & SNDR) - if (sndr_err = sndr_report()) - err = sndr_err; - - if (mode & IIMG) - if (ii_err = ii_report()) - err = ii_err; - - if ((mode & SDBC) && !(mode & MULTI)) - if (sdbc_err = sdbc_report()) - err = sdbc_err; - - return (err); -} diff --git a/usr/src/cmd/avs/dsstat/multi_stats.h b/usr/src/cmd/avs/dsstat/multi_stats.h deleted file mode 100644 index 2c092d4fab..0000000000 --- a/usr/src/cmd/avs/dsstat/multi_stats.h +++ /dev/null @@ -1,43 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _MULTI_STATS_H -#define _MULTI_STATS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes */ -int do_stats(); -int discover(); -int update(); -int report(); - -#ifdef __cplusplus -} -#endif - -#endif /* _MULTI_STATS_H */ diff --git a/usr/src/cmd/avs/dsstat/report.c b/usr/src/cmd/avs/dsstat/report.c deleted file mode 100644 index 4b91c255d5..0000000000 --- a/usr/src/cmd/avs/dsstat/report.c +++ /dev/null @@ -1,439 +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 <stdio.h> -#include <string.h> - -#include <kstat.h> -#include <sys/inttypes.h> - -#include <nsctl.h> - -#include "dsstat.h" -#include "common.h" - -#include "sdbc_stats.h" -#include "report.h" - -extern short dflags; - -/* - * Return the number of ticks delta between two hrtime_t - * values. Attempt to cater for various kinds of overflow - * in hrtime_t - no matter how improbable. - */ -uint64_t -hrtime_delta(hrtime_t old, hrtime_t new) -{ - - uint64_t del; - - if ((new >= old) && (old >= 0L)) { - return (new - old); - } else { - /* - * We've overflowed the positive portion of an - * hrtime_t. - */ - if (new < 0L) { - /* - * The new value is negative. Handle the - * case where the old value is positive or - * negative. - */ - uint64_t n1; - uint64_t o1; - - n1 = -new; - - if (old > 0L) { - return (n1 - old); - } else { - o1 = -old; - del = n1 - o1; - return (del); - } - } else { - /* - * Either we've just gone from being negative - * to positive *or* the last entry was positive - * and the new entry is also positive but *less* - * than the old entry. This implies we waited - * quite a few days on a very fast system between - * iostat displays. - */ - if (old < 0L) { - uint64_t o2; - - o2 = -old; - del = UINT64_MAX - o2; - } else { - del = UINT64_MAX - old; - } - - del += new; - - return (del); - } - } -} - -/* - * Take the difference of an unsigned 32 - * bit int attempting to cater for - * overflow. - */ -uint32_t -u32_delta(uint32_t old, uint32_t new) -{ - - if (new >= old) - return (new - old); - else - return ((UINT32_MAX - old) + new + 1); -} - -/* - * Take the difference of an unsigned 64 - * bit int attempting to cater for - * overflow. - */ -uint64_t -u64_delta(uint64_t old, uint64_t new) -{ - - if (new >= old) - return (new - old); - else - return ((UINT64_MAX - old) + new + 1); -} - -/* - * io_report() - diffs and reports data contained in - * kstat_io_t structures. - * - * parameters - * kstat_io_t *cur - pointer to current data - * - * kstat_io_t *pre - pointer to data as it was - * at the beginning of an interval. - */ -void -io_report(kstat_t *cur_kstat, kstat_t *pre_kstat, sdbcstat_t *sdbcstat) -{ - sdbcvals_t vals; - - double rd_cnt, wr_cnt; - double rd_kb, wr_kb, hr_etime; - - double rtm, tps, avs, etime; - - kstat_io_t *cur = cur_kstat->ks_data; - kstat_io_t *pre = pre_kstat->ks_data; - - if (sdbcstat && - sdbc_getvalues(sdbcstat, &vals, (SDBC_KBYTES | SDBC_INTAVG))) - return; - - /* Time */ - hr_etime = hrtime_delta(pre_kstat->ks_snaptime, cur_kstat->ks_snaptime); - etime = hr_etime / (double)NANOSEC; - - /* Read count */ - rd_cnt = (double)u32_delta(pre->reads, cur->reads); - if (rd_cnt) rd_cnt /= etime; - - /* Bytes read */ - rd_kb = (double)u64_delta(pre->nread, cur->nread) / KILOBYTE; - if (rd_kb) rd_kb /= etime; - - /* Write count */ - wr_cnt = (double)u32_delta(pre->writes, cur->writes); - if (wr_cnt) wr_cnt /= etime; - - /* Bytes written */ - wr_kb = (double)u64_delta(pre->nwritten, cur->nwritten) / KILOBYTE; - if (wr_kb) wr_kb /= etime; - - /* Calculate service times */ - avs = (double)hrtime_delta(pre->rlentime, cur->rlentime) / hr_etime; - tps = (double)rd_cnt + wr_cnt; - - if (tps > 0) - rtm = (1000 / tps) * avs; - else - rtm = 0.0; - - /* Output */ - if (dflags & SUMMARY) { - if ((mode & MULTI) && (mode & SDBC)) { - if (sdbcstat) { - (void) printf(KPS_INF_FMT, - (float)vals.total_cache); - (void) printf(KPS_INF_FMT, - (float)vals.total_disk); - } else { - (void) printf(DATA_C6, NO_INFO); - (void) printf(KPS_INF_FMT, rd_kb + wr_kb); - } - } else - (void) printf(KPS_INF_FMT, rd_kb + wr_kb); - - (void) printf(TPS_INF_FMT, (uint32_t)(rd_cnt + wr_cnt)); - (void) printf(SVT_INF_FMT, rtm); - - goto done; - } - - if (dflags & READ) { - if ((mode & MULTI) && (mode & SDBC)) { - if (sdbcstat) { - (void) printf(KPS_INF_FMT, - (float)vals.cache_read); - (void) printf(KPS_INF_FMT, - (float)vals.disk_read); - } else { - (void) printf(DATA_C6, NO_INFO); - (void) printf(KPS_INF_FMT, rd_kb); - } - - } else - (void) printf(KPS_INF_FMT, rd_kb); - - (void) printf(TPS_INF_FMT, (uint32_t)rd_cnt); - } - - if (dflags & WRITE) { - if ((mode & MULTI) && (mode & SDBC)) { - if (sdbcstat) { - (void) printf(KPS_INF_FMT, - (float)vals.cache_write); - (void) printf(KPS_INF_FMT, - (float)vals.disk_write); - } else { - (void) printf(DATA_C6, NO_INFO); - (void) printf(KPS_INF_FMT, wr_kb); - } - - } else - (void) printf(KPS_INF_FMT, wr_kb); - - (void) printf(TPS_INF_FMT, (uint32_t)wr_cnt); - } - - if (dflags & TIMING) { - (void) printf(SVT_INF_FMT, rtm); - } - -done: - linesout++; -} - -int -io_value_check(kstat_io_t *pre, kstat_io_t *cur) -{ - if (u32_delta(pre->reads, cur->reads)) - return (1); - if (u32_delta(pre->writes, cur->writes)) - return (1); - - return (0); -} - -/* - * cd_report() - reports cache desriptor related statistics - * based on the dflags global variable - * - * parameters - * sdbcstat_t *sdbcstat - pointer to the cache structure - * to be reported on. - */ -void -cd_report(sdbcstat_t *sdbcstat) -{ - sdbcvals_t vals; - - /* Extract statistics, average for time */ - if (sdbc_getvalues(sdbcstat, &vals, (SDBC_KBYTES | SDBC_INTAVG))) - return; - - /* Output */ - if (rflags & MULTI) { - (void) printf(VOL_HDR_FMT, ""); - - if (dflags & FLAGS) { - (void) printf(STAT_HDR_FMT, ""); - (void) printf(STAT_HDR_FMT, ""); - } - - if (dflags & PCTS) - (void) printf(PCT_HDR_FMT, ""); - - if (dflags & SUMMARY) { - (void) printf(KPS_INF_FMT, (float)vals.total_cache); - (void) printf(DATA_C4, NO_INFO); - (void) printf(DATA_C4, NO_INFO); - (void) printf("\n"); - linesout++; - return; - } - - if (dflags & READ) { - (void) printf(KPS_INF_FMT, (float)vals.cache_read); - (void) printf(DATA_C4, NO_INFO); - } - - if (dflags & WRITE) { - (void) printf(KPS_INF_FMT, (float)vals.cache_write); - (void) printf(DATA_C4, NO_INFO); - } - - if (dflags & TIMING) { - (void) printf(DATA_C4, NO_INFO); - } - - linesout++; - (void) printf("\n"); - return; - } - - if (dflags & SUMMARY) { - (void) printf(DATA_I32, vals.total_cache); - (void) printf(DATA_I32, vals.total_disk); - (void) printf(HIT_INF_FMT, vals.cache_hit); - - linesout++; - (void) printf("\n"); - return; - } - - if (dflags & READ) { - (void) printf(DATA_I32, vals.cache_read); - (void) printf(DATA_I32, vals.disk_read); - (void) printf(HIT_INF_FMT, vals.read_hit); - } - - if (dflags & WRITE) { - (void) printf(DATA_I32, vals.cache_write); - (void) printf(DATA_I32, vals.disk_write); - (void) printf(HIT_INF_FMT, vals.write_hit); - } - - if (dflags & DESTAGED) - (void) printf(DATA_I32, vals.destaged); - - if (dflags & WRCANCEL) - (void) printf(DATA_I32, vals.write_cancellations); - - linesout++; - (void) printf("\n"); -} - -/* - * header() - outputs an appropriate header by referencing the - * global variables dflsgs and rflags - * - */ -void -header() -{ - if (hflags & HEADERS_EXL) - if ((linesout % DISPLAY_LINES) != 0) - return; - - if (hflags & HEADERS_BOR) - if (linesout != 0) - return; - - if (hflags & HEADERS_ATT) - if (hflags & HEADERS_OUT) - return; - else - hflags |= HEADERS_OUT; - - if (linesout) - (void) printf("\n"); - - (void) printf(VOL_HDR_FMT, SET_HDR_TXT); - - if (dflags & FLAGS) { - (void) printf(STAT_HDR_FMT, TYPE_HDR_TXT); - (void) printf(STAT_HDR_FMT, STAT_HDR_TXT); - } - - if (dflags & ASYNC_QUEUE) - (void) printf(STAT_HDR_FMT, QUEUE_HDR_TXT); - - if (dflags & PCTS) - (void) printf(PCT_HDR_FMT, PCT_HDR_TXT); - - (void) printf(ROLE_HDR_FMT, ROLE_HDR_TXT); - - if (dflags & ASYNC_QUEUE) { - (void) printf(TPS_HDR_FMT, QUEUE_ITEMS_TXT); - (void) printf(KPS_HDR_FMT, QUEUE_KBYTES_TXT); - (void) printf(TPS_HDR_FMT, QUEUE_ITEMS_HW_TXT); - (void) printf(KPS_HDR_FMT, QUEUE_KBYTES_HW_TXT); - } - - if (dflags & SUMMARY) { - if ((mode & MULTI) && (mode & SDBC)) { - (void) printf(KPS_HDR_FMT, CKPS_HDR_TXT); - (void) printf(KPS_HDR_FMT, DKPS_HDR_TXT); - } else - (void) printf(KPS_HDR_FMT, KPS_HDR_TXT); - (void) printf(TPS_HDR_FMT, TPS_HDR_TXT); - (void) printf(SVT_HDR_FMT, SVT_HDR_TXT); - - (void) printf("\n"); - - return; - } - - if (dflags & READ) { - if ((mode & MULTI) && (mode & SDBC)) { - (void) printf(KPS_HDR_FMT, CRKPS_HDR_TXT); - (void) printf(KPS_HDR_FMT, DRKPS_HDR_TXT); - } else - (void) printf(KPS_HDR_FMT, RKPS_HDR_TXT); - - (void) printf(TPS_HDR_FMT, RTPS_HDR_TXT); - } - - if (dflags & WRITE) { - if ((mode & MULTI) && (mode & SDBC)) { - (void) printf(KPS_HDR_FMT, CWKPS_HDR_TXT); - (void) printf(KPS_HDR_FMT, DWKPS_HDR_TXT); - } else - (void) printf(KPS_HDR_FMT, WKPS_HDR_TXT); - - (void) printf(TPS_HDR_FMT, WTPS_HDR_TXT); - } - - if (dflags & TIMING) - (void) printf(SVT_HDR_FMT, SVT_HDR_TXT); - - (void) printf("\n"); -} diff --git a/usr/src/cmd/avs/dsstat/report.h b/usr/src/cmd/avs/dsstat/report.h deleted file mode 100644 index 56f7a21cb8..0000000000 --- a/usr/src/cmd/avs/dsstat/report.h +++ /dev/null @@ -1,122 +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 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _REPORT_H -#define _REPORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes */ -uint64_t hrtime_delta(hrtime_t, hrtime_t); -uint32_t u32_delta(uint32_t, uint32_t); -uint64_t u64_delta(uint64_t, uint64_t); -void io_report(kstat_t *, kstat_t *, sdbcstat_t *); -int io_value_check(kstat_io_t *, kstat_io_t *); -void cd_report(sdbcstat_t *); -void header(); - -/* BEGIN CSTYLED */ -/* END CSTYLED */ - -#define VOL_HDR_FMT "%-16s" -#define VOL_HDR_SIZE 17 -#define SET_HDR_TXT "name" - -#define STAT_HDR_FMT "%3s" -#define STAT_HDR_SIZE 3 -#define STAT_HDR_TXT "s" -#define TYPE_HDR_TXT "t" - -#define ROLE_HDR_FMT "%5s" -#define ROLE_HDR_SIZE 5 -#define ROLE_INF_FMT " %4s" -#define ROLE_HDR_TXT "role" - -#define PCT_HDR_FMT "%7s" -#define PCT_HDR_SIZE 7 -#define PCT_INF_FMT " %6.2f" -#define SN_HDR_TXT "sn" -#define PCT_HDR_TXT "pct" - -#define KPS_HDR_FMT "%7s" -#define KPS_HDR_SIZE 7 -#define KPS_INF_FMT " %6.0f" -#define KPS_HDR_TXT "kps" -#define RKPS_HDR_TXT "rkps" -#define WKPS_HDR_TXT "wkps" -#define CKPS_HDR_TXT "ckps" -#define DKPS_HDR_TXT "dkps" -#define CRKPS_HDR_TXT "crkps" -#define CWKPS_HDR_TXT "cwkps" -#define DRKPS_HDR_TXT "drkps" -#define DWKPS_HDR_TXT "dwkps" - -#define TPS_HDR_FMT "%6s" -#define TPS_HDR_SIZE 6 -#define TPS_INF_FMT " %5u" -#define TPS_HDR_TXT "tps" -#define RTPS_HDR_TXT "rtps" -#define WTPS_HDR_TXT "wtps" - -#define SVT_HDR_FMT "%5s" -#define SVT_HDR_SIZE 5 -#define SVT_INF_FMT " %4.0f" -#define SVT_HDR_TXT "svt" - -#define HIT_HDR_FMT "%6s" -#define HIT_HDR_SIZE 6 -#define HIT_INF_FMT " %5.1f" -#define HIT_PAD_FMT " %5s" -#define HIT_HDR_TXT "hit" -#define RHIT_HDR_TXT "rhit" -#define WHIT_HDR_TXT "whit" - -#define QUEUE_HDR_TXT "q" -#define QUEUE_ITEMS_TXT "qi" -#define QUEUE_KBYTES_TXT "qk" -#define QUEUE_ITEMS_HW_TXT "qhwi" -#define QUEUE_KBYTES_HW_TXT "qhwk" - -#define NO_INFO "-" - -#define DATA_C16 "%-16s" -#define DATA_C2 " %2s" -#define DATA_C4 " %4s" -#define DATA_C5 " %5s" -#define DATA_C6 " %6s" -#define DATA_I32 " %6u" -#define DATA_I64 " %6llu" -#define DATA_F62 " %6.2f" -#define DATA_F60 " %6.0f" -#define DATA_F50 " %5.0f" -#define DATA_F40 " %4.0f" - -#ifdef __cplusplus -} -#endif - -#endif /* _REPORT_H */ diff --git a/usr/src/cmd/avs/dsstat/sdbc_stats.c b/usr/src/cmd/avs/dsstat/sdbc_stats.c deleted file mode 100644 index f1af1acdd0..0000000000 --- a/usr/src/cmd/avs/dsstat/sdbc_stats.c +++ /dev/null @@ -1,788 +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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <inttypes.h> - -#include <kstat.h> - -#include <sys/nsctl/nsctl.h> -#include <sys/nsctl/sd_bcache.h> - -#include "sdbc_stats.h" - -#include "dsstat.h" -#include "common.h" -#include "report.h" - -static sdbcstat_t *sdbc_top; -kstat_t *sdbc_global = NULL; - -void sdbc_header(); -int sdbc_value_check(sdbcstat_t *); -int sdbc_validate(kstat_t *); -uint32_t sdbc_getdelta(sdbcstat_t *, char *); - -void sdbc_addstat(sdbcstat_t *); -sdbcstat_t *sdbc_delstat(sdbcstat_t *); -void center(int, char *); - -/* - * sdbc_discover() - looks for new statistics to be monitored. - * Verifies that any statistics found are now already being - * monitored. - * - */ -int -sdbc_discover(kstat_ctl_t *kc) -{ - static int validated = 0; - - kstat_t *ksp; - - for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { - int kinst; - char kname[KSTAT_STRLEN + 1]; - sdbcstat_t *cur; - sdbcstat_t *sdbcstat = NULL; - kstat_t *io_ksp; - - if (strcmp(ksp->ks_module, SDBC_KSTAT_MODULE) != 0 || - strncmp(ksp->ks_name, SDBC_KSTAT_CDSTATS, 2) != 0) - continue; - - if (kstat_read(kc, ksp, NULL) == -1) - continue; - - /* - * Validate kstat structure - */ - if (! validated) { - if (sdbc_validate(ksp)) - return (EINVAL); - - validated++; - } - - /* - * Duplicate check - */ - for (cur = sdbc_top; cur; cur = cur->next) { - char *cur_vname, *tst_vname; - - cur_vname = kstat_value(cur->pre_set, - SDBC_CDKSTAT_VOL_NAME); - - tst_vname = kstat_value(ksp, - SDBC_CDKSTAT_VOL_NAME); - - if (strncmp(cur_vname, tst_vname, NAMED_LEN) == 0) - goto next; - } - - /* - * Initialize new record - */ - sdbcstat = (sdbcstat_t *)calloc(1, sizeof (sdbcstat_t)); - - kinst = ksp->ks_instance; - - /* - * Set kstat - */ - sdbcstat->pre_set = kstat_retrieve(kc, ksp); - - if (sdbcstat->pre_set == NULL) - goto next; - - sdbcstat->collected |= GOT_SET_KSTAT; - - /* - * I/O kstat - */ - (void) sprintf(kname, "%s%d", SDBC_IOKSTAT_CDSTATS, kinst); - - io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname); - sdbcstat->pre_io = kstat_retrieve(kc, io_ksp); - - if (sdbcstat->pre_io == NULL) - goto next; - - sdbcstat->collected |= GOT_IO_KSTAT; - -next: - /* - * Check if we got a complete set of stats - */ - if (sdbcstat == NULL) - continue; - - if (SDBC_COMPLETE(sdbcstat->collected)) { - (void) sdbc_delstat(sdbcstat); - continue; - } - - sdbc_addstat(sdbcstat); - } - - if (sdbc_top == NULL) - return (EAGAIN); - - return (0); -} - -/* - * sdbc_update() - updates all of the statistics currently being monitored. - * - */ -int -sdbc_update(kstat_ctl_t *kc) -{ - kstat_t *ksp; - sdbcstat_t *cur; - - /* Update global kstat information */ - ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, -1, SDBC_KSTAT_GSTATS); - - if (ksp == NULL) - return (EAGAIN); - - if (sdbc_global) - kstat_free(sdbc_global); - - sdbc_global = kstat_retrieve(kc, ksp); - - for (cur = sdbc_top; cur != NULL; cur = cur->next) { - int kinst; - char *kname, *cname, *pname; - - kstat_t *set_ksp, *io_ksp; - - cur->collected = 0; - - /* - * Age off old stats - */ - if (cur->cur_set != NULL) { - kstat_free(cur->pre_set); - kstat_free(cur->pre_io); - - cur->pre_set = cur->cur_set; - cur->pre_io = cur->cur_io; - } - - /* - * Update set kstat - */ - kinst = cur->pre_set->ks_instance; - kname = cur->pre_set->ks_name; - - set_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname); - - if ((cur->cur_set = kstat_retrieve(kc, set_ksp)) == NULL) - continue; - - cur->collected |= GOT_SET_KSTAT; - - /* - * Validate set - */ - pname = kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME); - cname = kstat_value(cur->cur_set, SDBC_CDKSTAT_VOL_NAME); - - if (strncmp(pname, cname, NAMED_LEN) != 0) - continue; - - /* - * Update I/O kstat - */ - kinst = cur->pre_io->ks_instance; - kname = cur->pre_io->ks_name; - - io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname); - - if ((cur->cur_io = kstat_retrieve(kc, io_ksp)) == NULL) - continue; - - cur->collected |= GOT_IO_KSTAT; - } - - return (0); -} - -/* - * sdbc_report() - outputs statistics for the statistics currently being - * monitored. Deletes statistics for volumes that have been disabled. - * - */ -int -sdbc_report() -{ - vslist_t *vslist = vs_top; - sdbcstat_t *cur, *pre = NULL; - - if (sdbc_top == NULL) - return (0); - - for (cur = sdbc_top; cur != NULL; ) { /* CSTYLED */ - static uint32_t linesout = 0; - uint32_t *offline; - - char volname[NAMED_LEN + 1]; - char rmode[STAT_HDR_SIZE]; - char wmode[STAT_HDR_SIZE]; - - /* Parse volume name */ - (void) strncpy(volname, kstat_value(cur->pre_set, - SDBC_CDKSTAT_VOL_NAME), NAMED_LEN); - volname[NAMED_LEN] = '\0'; - - /* Check to see if the user specified this volume */ - for (vslist = vs_top; vslist != NULL; vslist = vslist->next) - if (strcmp(volname, vslist->volname) == 0) - break; - - if (vs_top != NULL && vslist == NULL) - goto next; - - /* Check if volume is offline and zflag applies */ - if (zflag && sdbc_value_check(cur) == 0) - goto next; - - /* Output volume name */ - sdbc_header(); - - (void) printf(DATA_C16, volname); - - if (SDBC_COMPLETE(cur->collected)) { - sdbcstat_t *next = sdbc_delstat(cur); - - if (! pre) - cur = sdbc_top = next; - else - cur = pre->next = next; - - (void) printf(" <<volume disabled>>\n"); - continue; - } - - offline = kstat_value(cur->cur_set, SDBC_CDKSTAT_FAILED); - if (*offline) { - (void) printf(" <<volume offline>>\n"); - linesout++; - goto next; - } - - /* Type/status flags */ - if (dflags & FLAGS) { - - uint32_t *dhint, *nhint; - uint32_t hints; - - dhint = kstat_value(cur->cur_set, SDBC_CDKSTAT_CDHINTS); - nhint = kstat_value(sdbc_global, SDBC_GKSTAT_NODEHINTS); - - if (! nhint) - return (EINVAL); - - hints = *nhint; - hints &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU | - NSC_NOCACHE); - hints |= *dhint; - - if (hints & NSC_NOCACHE) - (void) strcpy(rmode, "D"); - else - (void) strcpy(rmode, "C"); - - if ((hints & NSC_FORCED_WRTHRU) || (hints & NSC_WRTHRU)) - (void) strcpy(wmode, "D"); - else - (void) strcpy(wmode, "C"); - - (void) printf(DATA_C2, rmode); - (void) printf(DATA_C2, wmode); - } - - /* Output set information */ - cd_report(cur); - -next: - pre = cur; - cur = cur->next; - } - - return (0); -} - -/* - * sdbc_header() - outputs an appropriate header by referencing the - * global variables dflsgs - * - */ -void -sdbc_header() -{ - int rcount = 0; - - if (hflags == HEADERS_EXL) - if ((linesout % DISPLAY_LINES) != 0) - return; - - if (hflags == HEADERS_BOR) - if (linesout != 0) - return; - - if (hflags & HEADERS_ATT) - if (hflags & HEADERS_OUT) - return; - else - hflags |= HEADERS_OUT; - - if (linesout) - (void) printf("\n"); - - /* first line header */ - if (! (dflags & SUMMARY) && dflags != FLAGS) { - - (void) printf(VOL_HDR_FMT, " "); - - if (dflags & FLAGS) { - (void) printf(STAT_HDR_FMT, " "); - (void) printf(STAT_HDR_FMT, " "); - } - - if (dflags & READ) { - int size; - - size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE; - center(size, "- read -"); - rcount++; - } - - if (dflags & WRITE) { - int size; - - size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE; - center(size, "- write -"); - rcount++; - } - - if (dflags != FLAGS) - (void) printf("\n"); - } - - /* second line header */ - (void) printf(VOL_HDR_FMT, "volume"); - - if (dflags & FLAGS) { - (void) printf(STAT_HDR_FMT, "rd"); - (void) printf(STAT_HDR_FMT, "wr"); - } - - if (dflags & SUMMARY) { - (void) printf(KPS_HDR_FMT, "ckps"); - (void) printf(KPS_HDR_FMT, "dkps"); - (void) printf(HIT_HDR_FMT, HIT_HDR_TXT); - - goto out; - } - - if (dflags & READ) { - (void) printf(KPS_HDR_FMT, "ckps"); - (void) printf(KPS_HDR_FMT, "dkps"); - (void) printf(HIT_HDR_FMT, RHIT_HDR_TXT); - } - - if (dflags & WRITE) { - (void) printf(KPS_HDR_FMT, "ckps"); - (void) printf(KPS_HDR_FMT, "dkps"); - (void) printf(HIT_HDR_FMT, WHIT_HDR_TXT); - } - - if (dflags & DESTAGED) - (void) printf(KPS_HDR_FMT, "dstg"); - - if (dflags & WRCANCEL) - (void) printf(KPS_HDR_FMT, "cwrl"); - -out: - (void) printf("\n"); -} - -/* - * sdbc_getstat() - find cache stat by name matching - * - * paraemters - * char *vn - the volume name to match against - * returns - * sdbcstat_t * - the matching strcture, NULL if not found - */ -sdbcstat_t * -sdbc_getstat(char *vn) -{ - sdbcstat_t *cur, *pre = NULL; - - for (cur = sdbc_top; cur; ) { /* CSTYLED */ - char *volname = - kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME); - - if (SDBC_COMPLETE(cur->collected)) { - sdbcstat_t *next = sdbc_delstat(cur); - - if (! pre) - cur = sdbc_top = next; - else - cur = pre->next = next; - - continue; - } - - if (strncmp(volname, vn, NAMED_LEN) == 0) - return (cur); - - pre = cur; - cur = cur->next; - } - - return (NULL); -} - -/* - * sdbc_addstat() - adds a fully populated sdbcstat_t structure - * to the linked list of currently monitored kstats. The structure - * will be added in alphabetical order, using the volume name as the - * key. - * - * parameters - * sdbcstat_t *sdbcstat - to be added to the list. - * - */ -void -sdbc_addstat(sdbcstat_t *sdbcstat) -{ - sdbcstat_t *cur; - - if (sdbc_top == NULL) { - sdbc_top = sdbcstat; - return; - } - - for (cur = sdbc_top; cur != NULL; cur = cur->next) { - char *cur_vname, *nxt_vname, *tst_vname; - - cur_vname = kstat_value(cur->pre_set, - SDBC_CDKSTAT_VOL_NAME); - tst_vname = kstat_value(sdbcstat->pre_set, - SDBC_CDKSTAT_VOL_NAME); - - if (strncmp(cur_vname, tst_vname, NAMED_LEN) > 0) { - if (cur == sdbc_top) - sdbc_top = sdbcstat; - - sdbcstat->next = cur; - - return; - } - - /* - * If we get to the last item in the list, then just - * add this one to the end - */ - if (cur->next == NULL) { - cur->next = sdbcstat; - return; - } - - nxt_vname = kstat_value(cur->next->pre_set, - SDBC_CDKSTAT_VOL_NAME); - - if (strncmp(nxt_vname, tst_vname, NAMED_LEN) > 0) { - sdbcstat->next = cur->next; - cur->next = sdbcstat; - return; - } - } -} - -/* - * sdbc_delstat() - deallocate memory for the structure being - * passed in. - * - * parameters - * sdbcstat_t *sdbcstat - structure to be deallocated - * - * returns - * sdbcstat_t * - pointer to the "next" structures in the - * linked list. May be NULL if we are removing the last - * structure in the linked list. - */ -sdbcstat_t * -sdbc_delstat(sdbcstat_t *sdbcstat) -{ - - sdbcstat_t *next = sdbcstat->next; - - kstat_free(sdbcstat->pre_set); - kstat_free(sdbcstat->pre_io); - kstat_free(sdbcstat->cur_set); - kstat_free(sdbcstat->cur_io); - - free(sdbcstat); - sdbcstat = NULL; - - return (next); -} - -/* - * sdbc_value_check() - Checks for activity, supports -z switch - * - * parameters - * sdbcstat_t *sdbcstat - structure to be checked - * - * returns - * 1 - activity - * 0 - no activity - */ -int -sdbc_value_check(sdbcstat_t *sdbcstat) -{ - if (SDBC_COMPLETE(sdbcstat->collected)) - return (1); - - if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ) != 0) - return (1); - - if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ) != 0) - return (1); - - if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE) != 0) - return (1); - - if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE) != 0) - return (1); - - if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS) != 0) - return (1); - - if (io_value_check(sdbcstat->pre_io->ks_data, - sdbcstat->cur_io->ks_data) != 0) - return (1); - - return (0); -} - -/* - * sdbc_validate() - validates the structure of the kstats by attempting to - * lookup fields used by this module - * - * parameters - * kstat_t *ksp - kstat to be examined - * - * returns - * 1 - one or more fields missing - * 0 - all fields present - */ -int -sdbc_validate(kstat_t *ksp) -{ - if (! kstat_value(ksp, SDBC_CDKSTAT_VOL_NAME) || - ! kstat_value(ksp, SDBC_CDKSTAT_FAILED) || - ! kstat_value(ksp, SDBC_CDKSTAT_CDHINTS) || - ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_READ) || - ! kstat_value(ksp, SDBC_CDKSTAT_DISK_READ) || - ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_WRITE) || - ! kstat_value(ksp, SDBC_CDKSTAT_DISK_WRITE) || - ! kstat_value(ksp, SDBC_CDKSTAT_DESTAGED) || - ! kstat_value(ksp, SDBC_CDKSTAT_WRCANCELNS)) - return (1); - - return (0); -} - -/* - * sdbc_getvalues() - populates a values structure with data obtained from the - * kstat - * - * parameters - * sdbcstat_t *sdbcstat - pointer to the structure containing the kstats - * sdbcvals_t *vals - pointer to the structure that will receive the values - * int flags - flags that describe adjustments made to the values - * - * returns - * 1 - failure - * 0 - success - */ -int -sdbc_getvalues(sdbcstat_t *sdbcstat, sdbcvals_t *vals, int flags) -{ - int divisor = 0; - int factors; - uint64_t hr_etime; - double etime; - - kstat_io_t *cur; - kstat_io_t *pre; - - if (sdbcstat == NULL) - return (1); - - cur = sdbcstat->cur_io->ks_data; - pre = sdbcstat->pre_io->ks_data; - - hr_etime = hrtime_delta(pre->rlastupdate, cur->rlastupdate); - etime = hr_etime / (double)NANOSEC; - - /* read data */ - vals->cache_read = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ)); - vals->disk_read = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ)); - - - vals->total_reads = vals->cache_read + vals->disk_read; - - if (vals->cache_read == 0) - vals->read_hit = 0.0; - else - vals->read_hit = - ((float)vals->cache_read / vals->total_reads) * 100.0; - - /* write data */ - vals->cache_write = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE)); - vals->disk_write = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE)); - - vals->total_writes = vals->cache_write + vals->disk_write; - - vals->destaged = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DESTAGED)); - - if (vals->cache_write == 0) - vals->write_hit = 0.0; - else - vals->write_hit = ((float)vals->cache_write / - (vals->total_writes - vals->destaged)) * 100.0; - - /* miscellaneous */ - vals->write_cancellations = - FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS)); - - vals->total_cache = vals->cache_read + vals->cache_write; - vals->total_disk = vals->disk_read + vals->disk_write; - - /* total cache hit calculation */ - vals->cache_hit = 0; - factors = 0; - - if (vals->cache_read != 0) { - vals->cache_hit += vals->read_hit; - factors++; - } - - if (vals->cache_write != 0) { - vals->cache_hit += vals->write_hit; - factors++; - } - - if (vals->cache_hit) - vals->cache_hit /= (float)factors; - - /* adjustments */ - divisor = 1; - - if (flags & SDBC_KBYTES) - divisor *= KILOBYTE; - if ((flags & SDBC_INTAVG) && (etime > 0)) - divisor *= etime; - - if (divisor != 1) { - vals->cache_read /= divisor; - vals->disk_read /= divisor; - vals->total_reads /= divisor; - - vals->cache_write /= divisor; - vals->disk_write /= divisor; - vals->total_writes /= divisor; - - vals->total_cache /= divisor; - vals->total_disk /= divisor; - - vals->destaged /= divisor; - vals->write_cancellations /= divisor; - } - - return (0); -} - -/* - * sdbc_getdelta() - calculates the difference between two kstat fields - * - * parameters - * sdbcstat_t *sdbcstat - the SDBC stat strcture containing the two fields - * char *name - the name of the fields - * returns - * uint32_t value of the differences adjusted for overflow of the data type - */ -uint32_t -sdbc_getdelta(sdbcstat_t *sdbcstat, char *name) -{ - uint32_t *cur_val; - uint32_t *pre_val; - - pre_val = kstat_value(sdbcstat->pre_set, name); - cur_val = kstat_value(sdbcstat->cur_set, name); - - return (u32_delta(*pre_val, *cur_val)); -} - -void -center(int size, char *hdr) -{ - int lpad = 0; - int rpad = 0; - char fmt[10]; - - if (size == 0) - return; - - if (strlen(hdr) < size) { - lpad = (size - strlen(hdr)) / 2; - - if (lpad * 2 < size) - lpad++; - - rpad = size - (lpad + strlen(hdr)); - } - -output: - (void) sprintf(fmt, "%%%ds%%s%%%ds", lpad, rpad); - (void) printf(fmt, " ", hdr, " "); -} diff --git a/usr/src/cmd/avs/dsstat/sdbc_stats.h b/usr/src/cmd/avs/dsstat/sdbc_stats.h deleted file mode 100644 index ed455a7099..0000000000 --- a/usr/src/cmd/avs/dsstat/sdbc_stats.h +++ /dev/null @@ -1,92 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SDBC_STATS_H -#define _SDBC_STATS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Internal flags to denote data collection status - */ -#define GOT_SET_KSTAT 0x01 -#define GOT_IO_KSTAT 0x02 -#define GOT_COMPLETE_SDBC (GOT_SET_KSTAT | GOT_IO_KSTAT) - -#define SDBC_COMPLETE(x) (((x) & (GOT_COMPLETE_SDBC)) != \ - (GOT_COMPLETE_SDBC)) - -#define SDBC_KBYTES 0x01 -#define SDBC_INTAVG 0x02 - -#define KILOBYTE 1024 - -typedef struct sdbcstat_s -{ - kstat_t *pre_set; - kstat_t *pre_io; - kstat_t *cur_set; - kstat_t *cur_io; - int collected; - struct sdbcstat_s *next; -} sdbcstat_t; - -typedef struct sdbcvals_t -{ - uint32_t cache_read; - uint32_t cache_write; - uint32_t total_cache; - - float cache_hit; - float read_hit; - float write_hit; - - uint32_t disk_read; - uint32_t disk_write; - uint32_t total_disk; - - uint32_t destaged; - uint32_t write_cancellations; - - uint32_t total_reads; - uint32_t total_writes; -} sdbcvals_t; - -extern kstat_t *sdbc_global; - -/* Prototypes */ -int sdbc_discover(kstat_ctl_t *); -int sdbc_update(kstat_ctl_t *); -int sdbc_report(); -sdbcstat_t *sdbc_getstat(char *); -int sdbc_getvalues(sdbcstat_t *, sdbcvals_t *, int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SDBC_STATS_H */ diff --git a/usr/src/cmd/avs/dsstat/sndr_stats.c b/usr/src/cmd/avs/dsstat/sndr_stats.c deleted file mode 100644 index 2d65ee2036..0000000000 --- a/usr/src/cmd/avs/dsstat/sndr_stats.c +++ /dev/null @@ -1,852 +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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <setjmp.h> - -#include <kstat.h> - -#include <sys/nsctl/rdc.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_bitmap.h> - -#include "sdbc_stats.h" -#include "sndr_stats.h" - -#include "dsstat.h" -#include "common.h" -#include "report.h" - -static sndrstat_t *sndr_top; - -void sndr_add_stat(sndrstat_t *); -sndrstat_t *sndr_del_stat(sndrstat_t *); - -int sndr_value_check(sndrstat_t *); -int sndr_validate(kstat_t *); -int sndr_strcmp(char *, char *); -int sndr_vol_selected(kstat_t *); - -void getType(kstat_t *, char *); -void getStat(kstat_t *, char *); -void getQueue(kstat_t *, char *); -void printQueueStats(int, kstat_t *); -float getSyncNeeded(kstat_t *); - -static void update_sighandler(int); -static void discover_sighandler(int); - -static sigjmp_buf update_env, discover_env; -static sig_atomic_t sig_raised = 0; -/* - * sndr_discover() - looks for new statistics to be monitored. - * Verifies that any statistics found are now already being - * monitored. - * - */ -int -sndr_discover(kstat_ctl_t *kc) -{ - static int validated = 0; - struct sigaction segv_act; - int rc = 0; - kstat_t *ksp; - - - (void) signal(SIGSEGV, discover_sighandler); - (void) sigaction(SIGSEGV, NULL, &segv_act); - - /* Loop on all kstats */ - for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { - int kinst; - char kname[KSTAT_STRLEN + 1]; - sndrstat_t *cur; - sndrstat_t *sndrstat = NULL; - kstat_t *bmp_ksp; - kstat_t *sec_ksp; - - /* Serach for SNDR set */ - if (strcmp(ksp->ks_module, RDC_KSTAT_MODULE) != 0 || - strcmp(ksp->ks_name, RDC_KSTAT_INFO) != 0) { - continue; - } - - if (kstat_read(kc, ksp, NULL) == -1) - continue; - - /* - * Validate kstat structure - */ - if (! validated) { - if (sndr_validate(ksp)) - return (EINVAL); - - validated++; - } - - /* - * Duplicate check - */ - for (cur = sndr_top; cur != NULL; cur = cur->next) { - char *cur_vname, *tst_vname; - uint32_t cur_inst, tst_inst; - - cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE); - cur_inst = cur->pre_set->ks_instance; - - tst_vname = kstat_value(ksp, RDC_IKSTAT_FILE); - tst_inst = ksp->ks_instance; - - if (strcmp(cur_vname, tst_vname) == 0 && - cur_inst == tst_inst) - goto next; - } - - /* - * Initialize new record - */ - sndrstat = (sndrstat_t *)calloc(1, sizeof (sndrstat_t)); - kinst = ksp->ks_instance; - - /* - * Set kstat - */ - sndrstat->pre_set = kstat_retrieve(kc, ksp); - - if (sndrstat->pre_set == NULL) - goto next; - - sndrstat->collected |= GOT_SET_KSTAT; - - /* - * Bitmap kstat - */ - (void) sprintf(kname, "%s%d", RDC_KSTAT_BMPNAME, kinst); - - bmp_ksp = kstat_lookup(kc, RDC_KSTAT_BMPNAME, kinst, kname); - sndrstat->pre_bmp = kstat_retrieve(kc, bmp_ksp); - - if (sndrstat->pre_bmp == NULL) - goto next; - - sndrstat->collected |= GOT_BMP_KSTAT; - - /* - * Secondary kstat - */ - (void) sprintf(kname, "%s%d", RDC_KSTAT_RDCNAME, kinst); - - sec_ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname); - sndrstat->pre_sec = kstat_retrieve(kc, sec_ksp); - - if (sndrstat->pre_sec == NULL) - goto next; - - sndrstat->collected |= GOT_SEC_KSTAT; - -next: - /* - * Check if we got a complete set of stats - */ - if (sndrstat == NULL) - continue; - - if (SNDR_COMPLETE(sndrstat->collected)) { - (void) sndr_del_stat(sndrstat); - continue; - } - - /* - * Add to linked list - */ - sndr_add_stat(sndrstat); - } - - (void) sigsetjmp(discover_env, 0); - if (sig_raised) { - sig_raised = 0; - rc = -1; - } - (void) sigaction(SIGSEGV, &segv_act, NULL); - - return (rc); -} - -void -discover_sighandler(int sig) -{ - switch (sig) { - case SIGSEGV: - sig_raised = 1; - siglongjmp(discover_env, sig); - default: - exit(sig); - } -} - -void -update_sighandler(int sig) -{ - switch (sig) { - case SIGSEGV: - sig_raised = 1; - siglongjmp(update_env, sig); - default: - exit(sig); - } -} - -/* - * sndr_update() - updates all of the statistics currently being monitored. - * - */ -int -sndr_update(kstat_ctl_t *kc) -{ - sndrstat_t *cur; - struct sigaction segv_act; - int rc = 0; - - (void) signal(SIGSEGV, update_sighandler); - (void) sigaction(SIGSEGV, NULL, &segv_act); - - for (cur = sndr_top; cur != NULL; cur = cur->next) { - int kinst; - char kname[KSTAT_STRLEN + 1]; - kstat_t *ksp = NULL; - char *cur_vname, *tst_vname; - - cur->collected = 0; - - /* - * Age off old stats - */ - if (cur->cur_set != NULL) { - kstat_free(cur->pre_set); - kstat_free(cur->pre_bmp); - kstat_free(cur->pre_sec); - - cur->pre_set = cur->cur_set; - cur->pre_bmp = cur->cur_bmp; - cur->pre_sec = cur->cur_sec; - } - - /* - * Set kstat - */ - (void) strncpy(kname, cur->pre_set->ks_name, KSTAT_STRLEN); - kname[KSTAT_STRLEN] = '\0'; - - kinst = cur->pre_set->ks_instance; - - ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname); - - if ((cur->cur_set = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_SET_KSTAT; - - /* - * Validate set - */ - cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE); - tst_vname = kstat_value(cur->cur_set, RDC_IKSTAT_FILE); - - if (strcmp(cur_vname, tst_vname) != 0) - continue; - - /* - * Bitmap kstat - */ - (void) sprintf(kname, "%s%d", RDC_KSTAT_BMPNAME, kinst); - - ksp = kstat_lookup(kc, RDC_KSTAT_BMPNAME, kinst, kname); - - if ((cur->cur_bmp = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_BMP_KSTAT; - - /* - * Secondary kstat - */ - (void) sprintf(kname, "%s%d", RDC_KSTAT_RDCNAME, kinst); - - ksp = kstat_lookup(kc, RDC_KSTAT_MODULE, kinst, kname); - - if ((cur->cur_sec = kstat_retrieve(kc, ksp)) == NULL) - continue; - - cur->collected |= GOT_SEC_KSTAT; - - } - - (void) sigsetjmp(update_env, 0); - if (sig_raised) { - sig_raised = 0; - rc = -1; - } - (void) sigaction(SIGSEGV, &segv_act, NULL); - - return (rc); -} - -/* - * sndr_report() - outputs statistics for the statistics currently being - * monitored. Deletes statistics for volumes that have been disabled. - * - */ -int -sndr_report() -{ - int padsz; - char pad[20] = ""; - sndrstat_t *cur, *pre = NULL; - - if (sndr_top == NULL) - return (0); - - /* Create padding string for secondary report lines */ - padsz = 0; - if (dflags & FLAGS) { - padsz += STAT_HDR_SIZE; - padsz += STAT_HDR_SIZE; - } - - if (dflags & ASYNC_QUEUE) - padsz += STAT_HDR_SIZE; - - if (dflags & PCTS) - padsz += PCT_HDR_SIZE; - - if (padsz) { - char fmt[20]; - (void) sprintf(fmt, "%%%ds", padsz); - (void) sprintf(pad, fmt, " "); - } - - for (cur = sndr_top; cur != NULL; ) { /*CSTYLED */ - int first = 1; - char data[20] = ""; - - /* Check to see if this is this a complete */ - if (SNDR_COMPLETE(cur->collected)) { - char *c; - char vn[NSC_MAXPATH + 1]; - sndrstat_t *next; - - /* notify user of set being disabled */ - c = kstat_value(cur->pre_set, RDC_IKSTAT_SECFILE); - (void) strncpy(vn, c, NSC_MAXPATH); - vn[NSC_MAXPATH] = '\0'; - - (void) printf(DATA_C16, vn); - (void) printf(" %s\n", RDC_DISABLED); - - next = sndr_del_stat(cur); - - /* free memory and remove stat from list */ - if (! pre) - cur = sndr_top = next; - else - cur = pre->next = next; - - continue; - } - - /* Check to see if the user specified this volume */ - if (! sndr_vol_selected(cur->pre_set)) - goto next; - - /* Check to see if zflag applies */ - if (zflag && sndr_value_check(cur) == 0) - goto next; - - /* Calculate flags */ - if (dflags & FLAGS) { - char c[STAT_HDR_SIZE]; - char vtype[STAT_HDR_SIZE]; - char vstat[STAT_HDR_SIZE]; - - getType(cur->cur_set, &c[0]); - (void) sprintf(vtype, DATA_C2, c); - (void) strcat(data, vtype); - - getStat(cur->cur_set, &c[0]); - (void) sprintf(vstat, DATA_C2, c); - (void) strcat(data, vstat); - } - - /* Async. queue statistics */ - if (dflags & ASYNC_QUEUE) { - char c[STAT_HDR_SIZE]; - char qtype[STAT_HDR_SIZE]; - - getQueue(cur->cur_set, &c[0]); - (void) sprintf(qtype, DATA_C2, c); - (void) strcat(data, qtype); - } - - /* Calculate sync needed percentages */ - if (dflags & PCTS) { - char snpct[10]; - - (void) sprintf(snpct, DATA_F62, - getSyncNeeded(cur->cur_set)); - (void) strcat(data, snpct); - } - - /* Output */ - if (rflags & SNDR_NET) { - char *c; - char type[STAT_HDR_SIZE]; - char vn[NAMED_LEN + 1]; - - getType(cur->cur_set, &type[0]); - - if (type[0] == 'S') { - c = kstat_value(cur->pre_set, - RDC_IKSTAT_FILE); - } else { - c = kstat_value(cur->pre_set, - RDC_IKSTAT_SECFILE); - } - - /* Only print last 15 characters */ - if (strlen(c) >= NAMED_LEN) { - c += strlen(c) - NAMED_LEN; - } - (void) strncpy(vn, c, NAMED_LEN); - vn[NAMED_LEN] = '\0'; - - header(); - (void) printf(DATA_C16, vn); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, RDC_SECONDARY); - - /* Async. queue statistics */ - if (dflags & ASYNC_QUEUE) - printQueueStats(first, cur->cur_set); - - io_report(cur->cur_sec, cur->pre_sec, - sdbc_getstat(vn)); - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } - - if (rflags & SNDR_BMP) { - char *c; - char vn[16]; - - c = kstat_value(cur->pre_set, RDC_IKSTAT_BITMAP); - - /* Only print last 15 characters */ - if (strlen(c) >= NAMED_LEN) { - c += strlen(c) - NAMED_LEN; - } - (void) strncpy(vn, c, NAMED_LEN); - vn[NAMED_LEN] = '\0'; - - header(); - (void) printf(DATA_C16, vn); - (void) printf("%s", data); - (void) printf(ROLE_INF_FMT, RDC_BITMAP); - - /* Async. queue statistics */ - if (dflags & ASYNC_QUEUE) - printQueueStats(first, cur->cur_set); - - io_report(cur->cur_bmp, cur->pre_bmp, - sdbc_getstat(vn)); - (void) printf("\n"); - - if (first) { - (void) strcpy(data, strlen(pad) > 0 ? pad : ""); - first = 0; - } - } -next: - pre = cur; - cur = cur->next; - } - - return (0); -} - -/* - * sndr_add_stat() - adds a fully populated sndrstat_t structure - * to the linked list of currently monitored kstats. The structure - * will be added in alphabetical order, using the volume name as the - * key. - * - * parameters - * sndrstat_t *sndrstat - to be added to the list. - * - */ -void -sndr_add_stat(sndrstat_t *sndrstat) -{ - - sndrstat_t *cur; - - if (sndr_top == NULL) { - sndr_top = sndrstat; - return; - } - - for (cur = sndr_top; cur != NULL; cur = cur->next) { - char *cur_vname, *nxt_vname, *tst_vname; - - cur_vname = kstat_value(cur->pre_set, RDC_IKSTAT_FILE); - tst_vname = kstat_value(sndrstat->pre_set, RDC_IKSTAT_FILE); - - if (strcmp(cur_vname, tst_vname) <= 0) { - /* - * If we get to the last item in the list, then just - * add this one to the end - */ - if (cur->next == NULL) { - cur->next = sndrstat; - return; - } - - nxt_vname = kstat_value(cur->next->pre_set, - RDC_IKSTAT_FILE); - - if (strcmp(nxt_vname, tst_vname) > 0) { - sndrstat->next = cur->next; - cur->next = sndrstat; - return; - } - } else { - if (cur == sndr_top) - sndr_top = sndrstat; - - sndrstat->next = cur; - - return; - } - } -} - -/* - * sndr_del_stat() - deallocate memory for the structure being - * passed in. - * - * parameters - * sndrstat_t *sndrstat - structure to be deallocated - * - * returns - * sndrstat_t * - pointer to the "next" structures in the - * linked list. May be NULL if we are removing the last - * structure in the linked list. - * - */ -sndrstat_t * -sndr_del_stat(sndrstat_t *sndrstat) -{ - - sndrstat_t *next = sndrstat->next; - - kstat_free(sndrstat->pre_set); - kstat_free(sndrstat->pre_bmp); - kstat_free(sndrstat->pre_sec); - kstat_free(sndrstat->cur_set); - kstat_free(sndrstat->cur_bmp); - kstat_free(sndrstat->cur_sec); - - free(sndrstat); - - return (next); -} - -/* - * sndr_value_check() - check to determine if any activity was registered - * on this volume by checking the previous stats vs. the current stats. - * - * parameters - * sndrstat_t *sndrstat - structure to be checked - * - * returns - * 0 - no activity - * 1 - activity - */ -int -sndr_value_check(sndrstat_t *sndrstat) -{ - if (SNDR_COMPLETE(sndrstat->collected)) - return (1); - - if (io_value_check(sndrstat->pre_bmp->ks_data, - sndrstat->cur_bmp->ks_data)) { - return (1); - } - - if (io_value_check(sndrstat->pre_sec->ks_data, - sndrstat->cur_sec->ks_data)) { - return (1); - } - - return (0); -} - -/* - * sndr_validate() - validates the fields required by dsstat exist in - * the kstat_t structure passed in. This check keeps dsstat from - * core dumping if the kstat_named_t structures change in any of the - * services that dsstat monitors. - * - * paramaters - * kstat_t *ksp - kstat_t structure to check. The ks_data field - * should have been populated with a call to kstat_read() - * - * returns - * 0 - all fields are contained in the kstat - * 1 - a field required by dsstat is not in the kstat - */ -int -sndr_validate(kstat_t *ksp) -{ - if (! kstat_value(ksp, RDC_IKSTAT_FILE) || - ! kstat_value(ksp, RDC_IKSTAT_FLAGS) || - ! kstat_value(ksp, RDC_IKSTAT_SYNCFLAGS) || - ! kstat_value(ksp, RDC_IKSTAT_BMPFLAGS) || - ! kstat_value(ksp, RDC_IKSTAT_VOLSIZE) || - ! kstat_value(ksp, RDC_IKSTAT_BITSSET) || - ! kstat_value(ksp, RDC_IKSTAT_QUEUE_TYPE) || - ! kstat_value(ksp, RDC_IKSTAT_ASYNC_ITEMS) || - ! kstat_value(ksp, RDC_IKSTAT_ASYNC_BLOCKS) || - ! kstat_value(ksp, RDC_IKSTAT_ASYNC_ITEM_HWM) || - ! kstat_value(ksp, RDC_IKSTAT_ASYNC_BLOCK_HWM)) - return (1); - - return (0); -} - -void -getType(kstat_t *ksp, char *vtype) -{ - uint32_t *set_flags; - - set_flags = kstat_value(ksp, RDC_IKSTAT_FLAGS); - - if (*set_flags & RDC_PRIMARY) - (void) strcpy(vtype, "P"); - else - (void) strcpy(vtype, "S"); -} - -void -getStat(kstat_t *ksp, char *vstat) -{ - uint32_t *set_flags; - uint32_t *syn_flags; - uint32_t *bmp_flags; - - set_flags = kstat_value(ksp, RDC_IKSTAT_FLAGS); - syn_flags = kstat_value(ksp, RDC_IKSTAT_SYNCFLAGS); - bmp_flags = kstat_value(ksp, RDC_IKSTAT_BMPFLAGS); - - (void) strcpy(vstat, "R"); - - if (*set_flags & RDC_SYNCING) { - if (*set_flags & RDC_SLAVE) - if (*set_flags & RDC_PRIMARY) - (void) strcpy(vstat, "RS"); - else - (void) strcpy(vstat, "SY"); - else - if (*set_flags & RDC_PRIMARY) - (void) strcpy(vstat, "SY"); - else - (void) strcpy(vstat, "RS"); - } - - if (*set_flags & RDC_LOGGING) { - (void) strcpy(vstat, "L"); - - if (*set_flags & RDC_QUEUING) - (void) strcpy(vstat, "Q"); - - if (*set_flags & RDC_DISKQ_FAILED) - (void) strcpy(vstat, "QF"); - - if (*syn_flags & RDC_SYNC_NEEDED) - (void) strcpy(vstat, "SN"); - - if (*syn_flags & RDC_RSYNC_NEEDED) - (void) strcpy(vstat, "RN"); - } - - if (*syn_flags & RDC_FCAL_FAILED) - (void) strcpy(vstat, "FF"); - - if (*bmp_flags & RDC_BMP_FAILED) - (void) strcpy(vstat, "BF"); - - if (*syn_flags & RDC_VOL_FAILED) - (void) strcpy(vstat, "VF"); -} - -void -getQueue(kstat_t *ksp, char *vqueue) -{ - char *qtype; - - (void) strcpy(vqueue, "-"); - - qtype = kstat_value(ksp, RDC_IKSTAT_QUEUE_TYPE); - - if (strcmp(qtype, "memory") == 0) - (void) strcpy(vqueue, "M"); - - if (strcmp(qtype, "disk") == 0) - (void) strcpy(vqueue, "D"); -} - -float -getSyncNeeded(kstat_t *ksp) -{ - uint32_t *volsize, *bitsset; - uint32_t bits, segs; - float pct; - - volsize = kstat_value(ksp, RDC_IKSTAT_VOLSIZE); - bitsset = kstat_value(ksp, RDC_IKSTAT_BITSSET); - - segs = FBA_TO_LOG_LEN(*volsize); - bits = *bitsset > 0 ? *bitsset : 0; - - pct = segs ? ((float)bits/(float)segs) : 0.0; - pct *= 100; - - return (pct); -} - -/* - * Special handling for compatibility. - * "dsstat -s <set>" allows set name to be the last 15 chars, - * due to 15 characters limit of old kstat information. - * - * return 0 if: - * 1) full and partial are same - * 2) partial is the last 15 chars of full - */ -int -sndr_strcmp(char *full, char *partial) -{ - char *f = full; - int rc; - - rc = strcmp(full, partial); - - if (rc != 0 && - (strlen(partial) == NAMED_LEN) && - (strlen(full) > NAMED_LEN)) { - f += strlen(full) - NAMED_LEN; - rc = strncmp(f, partial, NAMED_LEN); - } - - return (rc); -} - -int -sndr_vol_selected(kstat_t *ksp) -{ - vslist_t *vslist = vs_top; - - for (vslist = vs_top; vslist != NULL; vslist = vslist->next) { - char *vn; - char *vh; - - /* If no host specified, check local only */ - if (vslist->volhost == NULL) { - vn = kstat_value(ksp, RDC_IKSTAT_FILE); - - if (sndr_strcmp(vn, vslist->volname)) - continue; - else - break; - } - - /* Check primary */ - vn = kstat_value(ksp, RDC_IKSTAT_FILE); - vh = kstat_value(ksp, RDC_IKSTAT_PRIMARY_HOST); - - if (sndr_strcmp(vn, vslist->volname) == 0 && - sndr_strcmp(vh, vslist->volhost) == 0) - break; - - /* Check secondary */ - vn = kstat_value(ksp, RDC_IKSTAT_SECFILE); - vh = kstat_value(ksp, RDC_IKSTAT_SECONDARY_HOST); - - if (sndr_strcmp(vn, vslist->volname) == 0 && - sndr_strcmp(vh, vslist->volhost) == 0) - break; - } - - if (vs_top != NULL && vslist == NULL) - return (0); - - return (1); -} - -void -printQueueStats(int first, kstat_t *cur_set) -{ - uint32_t *val; - - if (! first) { - /* Filler for async. queue fields */ - (void) printf(TPS_HDR_FMT, NO_INFO); - (void) printf(KPS_HDR_FMT, NO_INFO); - (void) printf(TPS_HDR_FMT, NO_INFO); - (void) printf(KPS_HDR_FMT, NO_INFO); - - return; - } - - val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_ITEMS); - (void) printf(TPS_INF_FMT, *val); - - val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_BLOCKS); - (void) printf(KPS_INF_FMT, (float)(*val / 2)); - - val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_ITEM_HWM); - (void) printf(TPS_INF_FMT, *val); - - val = (uint32_t *)kstat_value(cur_set, RDC_IKSTAT_ASYNC_BLOCK_HWM); - (void) printf(KPS_INF_FMT, (float)(*val / 2)); -} diff --git a/usr/src/cmd/avs/dsstat/sndr_stats.h b/usr/src/cmd/avs/dsstat/sndr_stats.h deleted file mode 100644 index d5b730c96c..0000000000 --- a/usr/src/cmd/avs/dsstat/sndr_stats.h +++ /dev/null @@ -1,70 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SNDR_STATS_H -#define _SNDR_STATS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define GOT_SET_KSTAT 0x01 -#define GOT_BMP_KSTAT 0x02 -#define GOT_SEC_KSTAT 0x04 - -#define GOT_COMPLETE_SNDR (GOT_SET_KSTAT|GOT_BMP_KSTAT|GOT_SEC_KSTAT) - -#define SNDR_COMPLETE(x) (((x) & (GOT_COMPLETE_SNDR)) != (GOT_COMPLETE_SNDR)) - -/* SNDR strings */ -#define RDC_KSTAT_RDCNAME "sndr" -#define RDC_KSTAT_BMPNAME "sndrbmp" - -#define RDC_DISABLED "<<set disabled>>" -#define RDC_SECONDARY "net" -#define RDC_BITMAP "bmp" - -typedef struct sndrstat_s -{ - kstat_t *pre_set; - kstat_t *pre_bmp; - kstat_t *pre_sec; - kstat_t *cur_set; - kstat_t *cur_bmp; - kstat_t *cur_sec; - int collected; - struct sndrstat_s *next; -} sndrstat_t; - -/* Prototypes */ -int sndr_discover(kstat_ctl_t *); -int sndr_update(kstat_ctl_t *); -int sndr_report(); - -#ifdef __cplusplus -} -#endif - -#endif /* _SNDR_STATS_H */ diff --git a/usr/src/cmd/avs/dsw/Makefile b/usr/src/cmd/avs/dsw/Makefile deleted file mode 100644 index 7dced4b925..0000000000 --- a/usr/src/cmd/avs/dsw/Makefile +++ /dev/null @@ -1,102 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -include ../../Makefile.cmd -include ../Makefile.com - -DYNPROG = iiadm iiboot iicpbmp iicpshd - -PROG=$(DYNPROG) - -PROG1 = iiadm -PROG2 = iiboot -PROG3 = iicpbmp -PROG4 = iicpshd - -SUBDIRS= etc - -iiadm := POBJS = iiadm.o -iiboot := POBJS = iiboot.o -iicpbmp := POBJS = iicpbmp.o -iicpshd := POBJS = iicpshd.o - -iiadm := LDLIBS += -lnsctl -ldscfg -lunistat -lm -iiboot := LDLIBS += -ldscfg -lunistat -iicpbmp := LDLIBS += -ldscfg -lunistat -iicpshd := LDLIBS += -ldscfg -lunistat - -OBJS= iiadm.o iiboot.o iicpbmp.o iicpshd.o -POFILE = dsw_all.po -SRCS= $(OBJS:%.o=%.c) -POFILES= $(OBJS:%.o=%.po) - -CFLAGS += $(CCVERBOSE) -D_DSW_ -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_DSW_ -DDEBUG -LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-uninitialized - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SUBDIRS) $(PROG) $(POFILES) - -install: $(SUBDIRS) all $(ROOTPROG) - -$(RM) $(ROOT)/usr/sbin/$(PROG1) - -$(RM) $(ROOT)/usr/sbin/$(PROG2) - -$(RM) $(ROOT)/usr/sbin/$(PROG3) - -$(RM) $(ROOT)/usr/sbin/$(PROG4) - -$(SYMLINK) ../bin/$(PROG1) $(ROOT)/usr/sbin/$(PROG1) - -$(SYMLINK) ../bin/$(PROG2) $(ROOT)/usr/sbin/$(PROG2) - -$(SYMLINK) ../bin/$(PROG3) $(ROOT)/usr/sbin/$(PROG3) - -$(SYMLINK) ../bin/$(PROG4) $(ROOT)/usr/sbin/$(PROG4) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o $(POFILES) - -$(PROG): $(OBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/dsw/etc/Makefile b/usr/src/cmd/avs/dsw/etc/Makefile deleted file mode 100644 index c627f1cbb1..0000000000 --- a/usr/src/cmd/avs/dsw/etc/Makefile +++ /dev/null @@ -1,63 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -include ../../../Makefile.cmd -include ../../Makefile.com - - -SHFILES = ii ii.cluster -ROOTINIT_D = $(ROOTETC)/init.d -USRTOOL_D = $(ROOTUSRTOOLS) - -FILEMODE = 0744 - -ROOTINIT_DPROG = $(ROOTINIT_D)/ii -ROOTINIT_DPROG2= $(ROOTINIT_D)/ii.cluster - -.KEEP_STATE: - -all: $(SHFILES) - -install: $(ROOTINIT_DPROG) $(ROOTINIT_DPROG2) $(CLUSTERSBINDIR) $(ROOTLIBSVCMETHOD) - -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/20ii - -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/05ii - -$(RM) $(CLUSTERSBINDIR)/ii - -$(RM) $(ROOTLIBSVCMETHOD)/svc-ii - -$(SYMLINK) ../../../sbin/ii $(CLUSTERLIBDSCFGSTOPDIR)/20ii - -$(SYMLINK) ../../../sbin/ii $(CLUSTERLIBDSCFGSTARTDIR)/05ii - $(LN) $(ROOTINIT_D)/ii $(ROOTLIBSVCMETHOD)/svc-ii - $(CP) $(ROOTINIT_D)/ii.cluster $(CLUSTERSBINDIR)/ii - -$(ROOTINIT_DPROG): ii - $(INS.file) ii - -$(ROOTINIT_DPROG2): ii.cluster - $(INS.file) ii.cluster - -clean: - $(RM) $(SHFILES) - -clobber: clean - -lint: diff --git a/usr/src/cmd/avs/dsw/etc/ii.cluster.sh b/usr/src/cmd/avs/dsw/etc/ii.cluster.sh deleted file mode 100644 index 0be90c16a7..0000000000 --- a/usr/src/cmd/avs/dsw/etc/ii.cluster.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/ksh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CMD=/usr/sbin/iiboot -SVCS=/usr/bin/svcs -SVCS_NAME=system/nws_ii - -# Determine if SMF service is online -# -ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"` -if [ -z $ONLINE ] -then - echo "$SVCS_NAME not online" - exit 1 -fi - -if [[ -z "$2" ]] -then - opt=usage -else - opt=$1 -fi - -case $opt in -'start') - if [[ -x $CMD ]] - then - $CMD -C "$2" -r > /dev/null 2>&1 - fi - ;; - -'stop') - if [[ -x $CMD ]] - then - $CMD -C "$2" -s > /dev/null 2>&1 - fi - ;; - -*) - echo "usage: ii {start|stop} cluster_resource" - ;; -esac diff --git a/usr/src/cmd/avs/dsw/etc/ii.sh b/usr/src/cmd/avs/dsw/etc/ii.sh deleted file mode 100644 index b40fc2bad4..0000000000 --- a/usr/src/cmd/avs/dsw/etc/ii.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/sh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CMD=/usr/sbin/iiboot -IIADM=/usr/sbin/iiadm -SVCS=/usr/bin/svcs -DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" -OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2` - -. /lib/svc/share/smf_include.sh - -# Make sure prior SMF dependents are not 'online' -# $1 = name of SMF service to validate dependents -# -do_smf_depends () -{ - times=0 - count=1 - - if [ $OS_MINOR -ge 11 ] - then - return 0 - elif [ -f $DSCFG_DEPEND_NOCHK ] - then - for pid in `pgrep dscfgadm` - do - if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ] - then - return 0 - fi - done - elif [ `ps -ef | grep preremove | grep -c SUNWiiu` -gt 0 ] - then - return 0 - - fi - - while [ $count -ne 0 ] - do - count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l` - if [ $count -ne 0 ] - then - # Output banner after waiting first 5 seconds - # - if [ $times -eq 1 ] - then - echo "Waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - fi - - # Has it been longer then 5 minutes? (60 * 5 secs.) - # - if [ $times -eq 60 ] - then - echo "Error: Failed waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - exit $SMF_EXIT_ERR_FATAL - fi - - # Now sleep, giving other services time to stop - # - sleep 5 - times=`expr $times + 1` - fi - done - return 0 -} - - -CLINFO=/usr/sbin/clinfo - -rc=0 - -case $1 in -'start') - - COPT= - - if [ -x ${CMD} ] - then - if ${CLINFO} - then - # in cluster - look for local volumes only - COPT="-C -" - fi - - ${CMD} $COPT -r > /dev/null 2>&1 - rc=$? - fi - ;; -'stop') - if [ ! -r /dev/ii ] - then - exit $SMF_EXIT_OK - fi - - do_smf_depends "system/nws_ii" - - COPT= - - if [ -x ${CMD} ] - then - if ${CLINFO} - then - # in cluster - look for local volumes only - COPT="-C -" - fi - - ${CMD} $COPT -s > /dev/null 2>&1 - rc=$? - fi - ;; -*) - echo "usage: /etc/init.d/ii {start|stop} " - exit 1 - ;; -esac -if [ $rc -ne 0 ] -then - exit $SMF_MON_OFFLINE -else - exit $SMF_EXIT_OK -fi diff --git a/usr/src/cmd/avs/dsw/iiadm.c b/usr/src/cmd/avs/dsw/iiadm.c deleted file mode 100644 index dd49e10e4e..0000000000 --- a/usr/src/cmd/avs/dsw/iiadm.c +++ /dev/null @@ -1,4377 +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/time.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <values.h> -#include <locale.h> -#include <langinfo.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <strings.h> -#include <stdarg.h> -#include <ctype.h> -#include <math.h> -#include <sys/param.h> -#include <sys/mnttab.h> -#include <nsctl.h> -#include <netdb.h> -#include <search.h> - -#include <sys/nsctl/cfg.h> -#include <sys/nsctl/nsc_hash.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/nsctl/dsw_dev.h> /* for bit map header format */ - -#include <sys/nskernd.h> - -typedef struct mstcount_s { - int count; -} mstcount_t; -typedef struct shdvol_s { - char master[ DSW_NAMELEN ]; -} shdvol_t; -typedef struct grptag_s { - char ctag[ DSW_NAMELEN ]; -} grptag_t; -hash_node_t **volhash = NULL; - -#define DSW_TEXT_DOMAIN "II" - -#include <dlfcn.h> -#define RDC_LIB "/usr/lib/librdc.so.1" -static int (*self_check)(char *); - -/* - * Support for the special cluster tag "local" to be used with -C in a - * cluster for local volumes. - */ -#define II_LOCAL_TAG "local" - -#define II_NOT_CLUSTER 1 -#define II_CLUSTER 2 -#define II_CLUSTER_LCL 3 - -static char *cfg_cluster_tag = NULL; -static CFGFILE *cfg = NULL; - -void sigterm(int sig); - -#define SD_BIT_CLR(bmap, bit) (bmap &= ~(1 << bit)) -#define SD_BIT_ISSET(bmap, bit) ((bmap & (1 << bit)) != 0) - -#define MAX_LINE_SIZE 256 /* maximum characters per line in config file */ -#define MAX_GROUPS 1024 /* maximum number of groups to support */ -#define MAX_CLUSTERS 1024 /* maximum number of resource groups */ - -unsigned long bm_size; /* size in bytes of bitmap */ -unsigned long bm_actual; /* original number of bits in bitmap */ -int debug = 0; - -int dsw_fd; - -#define LD_II 0x00000001 -#define LD_DSVOLS 0x00000002 -#define LD_SVOLS 0x00000004 -#define LD_SHADOWS 0x00000008 - -static int reload_vols = 0; -static int config_locked = 0; -static int last_lock; - -/* - * names for do_copy() flags. - */ - -enum copy_update {Copy = 0, Update}; -enum copy_direction {ToShadow = 0, ToMaster}; -enum copy_wait {WaitForStart = 0, WaitForEnd}; - -char *cmdnam; - -unsigned char *allocate_bitmap(char *); -void usage(char *); -void enable(char *, char *, char *, char *); -int disable(char *); -void bitmap_op(char *, int, int, int, int); -void print_status(dsw_config_t *, int); -int abort_copy(char *); -int reset(char *); -int overflow(char *); -void iiversion(void); -int wait_for_copy(char *); -int export(char *); -void list_volumes(void); -void dsw_error(char *, spcs_s_info_t *); -void InitEnv(); -static void check_dg_is_local(char *dgname); -static int check_resource_group(char *volume); -static int check_diskgroup(char *path, char *result); -static int check_cluster(); -static void unload_ii_vols(); -static void load_ii_vols(CFGFILE *); -static int perform_autosv(); -static int is_exported(char *); -static void conform_name(char **); -static void do_attach(dsw_config_t *); -static int ii_lock(CFGFILE *, int); -static void verify_groupname(char *grp, int testDash); - -void dsw_list_clusters(char *); -void dsw_enable(int, char **); -void dsw_disable(int, char **); -void dsw_copy_to_shadow(int, char **); -void dsw_update_shadow(int, char **); -void dsw_copy_to_master(int, char **); -void dsw_update_master(int, char **); -void dsw_abort_copy(int, char **); -void dsw_display_status(int, char **); -void dsw_display_bitmap(int, char **); -void dsw_reset(int, char **); -void dsw_overflow(int, char **); -void dsw_version(int, char **); -void dsw_wait(int, char **); -void dsw_list_volumes(int, char **); -void dsw_list_group_volumes(); -void dsw_export(int, char **); -void dsw_import(int, char **); -void dsw_join(int, char **); -void dsw_attach(int, char **); -void dsw_detach(int, char **); -void dsw_params(int, char **); -void dsw_olist(int, char **); -void dsw_ostat(int, char **); -void dsw_move_2_group(int, char **); -void dsw_list_groups(); -void check_iishadow(char *); - -extern char *optarg; -extern int optind, opterr, optopt; - -int Aflg; -int Cflg; -int CLflg; -int Dflg; -int Eflg; -int Iflg; -int Jflg; -int Lflg; -int Oflg; -int Pflg; -int Qflg; -int Rflg; -int aflg; -int bflg; -int cflg; -int dflg; -int eflg; -int fflg; -int gflg; -int gLflg; -int hflg; -int iflg; -int lflg; -int mflg; -int nflg; -int pflg; -int uflg; -int vflg; -int wflg; - -int errflg; -#ifdef DEBUG -const char single_opts[] = - "a:b:c:d:e:f:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:"; -#else -/* no b or f flags */ -const char single_opts[] = "a:c:d:e:g:hilmnpu:vw:A:C:D:E:I:J:LO:PQ:R:"; -#endif -const char group_opts[] = "ac:de:ilmnpu:wA:C:DELPR"; -const char *opt_list = single_opts; - -char buf[CFG_MAX_BUF]; -char key[CFG_MAX_KEY]; -char last_overflow[DSW_NAMELEN]; -int setnumber; -char *group_name; -char **group_volumes; -enum copy_direction direction; -char *param_delay, *param_unit; -char *overflow_file; - -#ifdef lint -int -iiadm_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - int c; - int actions = 0; - int ac; - char *av[1024]; - - InitEnv(); - - (void) memset(av, 0, sizeof (av)); - cmdnam = argv[0]; - while ((c = getopt(argc, argv, opt_list)) != EOF) - switch (c) { - case 'c': - cflg++; - actions++; - if (strcmp(optarg, "m") == 0) { - av[0] = "copy_to_master"; - direction = ToMaster; - } else if (strcmp(optarg, "s") == 0) { - av[0] = "copy_to_shadow"; - direction = ToShadow; - } else { - errflg ++; - usage(gettext( - "must specify m or s with -c")); - } - ac = 2; - break; - case 'd': - dflg++; - actions++; - av[0] = "disable"; - av[1] = optarg; - ac = 2; - break; - case 'e': - eflg++; - actions++; - av[0] = "enable"; - if (strcmp(optarg, "ind") == 0) - av[4] = "independent"; - else if (strcmp(optarg, "dep") == 0) - av[4] = "dependent"; - else { - errflg ++; - usage(gettext( - "must specify ind or dep with -e")); - } - ac = 1; - break; - case 'g': - gflg++; - opt_list = group_opts; - group_name = optarg; - if (group_name && *group_name == '-') { - gLflg = (strcmp("-L", group_name) == 0); - if (gLflg) - actions++; - } - verify_groupname(group_name, !gLflg); - break; - case 'h': - hflg++; - actions++; - break; - case 'u': - uflg++; - actions++; - if (strcmp(optarg, "m") == 0) { - av[0] = "update_master"; - direction = ToMaster; - } else if (strcmp(optarg, "s") == 0) { - av[0] = "update_shadow"; - direction = ToShadow; - } else { - errflg ++; - usage(gettext( - "must specify m or s with -u")); - } - ac = 2; - break; - case 'i': - iflg++; - actions++; - av[0] = "display_status"; - break; - case 'l': - lflg++; - actions++; - av[0] = "list_config"; - ac = 1; - break; - case 'm': - mflg++; - actions++; - av[0] = "move_to_group"; - ac = 1; - break; - case 'n': - nflg++; - break; - case 'p': - pflg++; - break; - case 'b': - bflg++; - actions++; - av[0] = "display_bitmap"; - av[1] = optarg; - ac = 2; - break; - case 'a': - aflg++; - actions++; - av[0] = "abort_copy"; - av[1] = optarg; - ac = 2; - break; - case 'v': - vflg++; - actions++; - av[1] = "version"; - ac = 1; - break; - case 'w': - wflg++; - actions++; - av[0] = "wait"; - av[1] = optarg; - ac = 2; - break; - case 'A': - Aflg++; - actions++; - av[0] = "attach"; - av[1] = optarg; - ac = 2; - break; - case 'C': - Cflg++; - cfg_cluster_tag = optarg; - if (cfg_cluster_tag && *cfg_cluster_tag == '-') { - CLflg = (strcmp("-L", cfg_cluster_tag) == 0); - if (CLflg) - actions++; - } - break; - case 'D': - Dflg++; - actions++; - av[0] = "detach"; - av[1] = optarg; - ac = 2; - break; - case 'O': - Oflg++; - actions++; - av[0] = "overflow"; - av[1] = optarg; - ac = 2; - break; - case 'R': - Rflg++; - actions++; - av[0] = "reset"; - av[1] = optarg; - ac = 2; - break; - case 'E': - Eflg++; - actions++; - av[0] = "export"; - av[1] = optarg; - ac = 2; - break; - case 'I': - Iflg++; - actions++; - av[0] = "import"; - av[1] = optarg; - ac = 2; - break; - case 'J': - Jflg++; - actions++; - av[0] = "join"; - av[1] = optarg; - ac = 2; - break; - case 'P': - Pflg++; - actions++; - av[0] = "parameter"; - ac = 1; - break; - case 'L': - Lflg++; - actions++; - /* If -g group -L, force error */ - if (group_name) actions++; - av[0] = "LIST"; - ac = 1; - break; - case 'Q': - Qflg++; - actions++; - av[0] = "query"; - av[1] = optarg; - ac = 2; - break; - case '?': - errflg++; - break; - } - if (hflg) { - usage(NULL); - exit(0); - } - - if (errflg) - usage(gettext("unrecognized argument")); - switch (actions) { - case 0: - if (argc > 1) - usage(gettext("must specify an action flag")); - - /* default behavior is to list configuration */ - lflg++; av[0] = "list_config"; ac = 1; - break; - case 1: - break; - default: - usage(gettext("too many action flags")); - break; - } - - if (gflg && (Iflg || Jflg || Oflg || Qflg)) - usage(gettext("can't use a group with this option")); - if (!gflg && (mflg)) - usage(gettext("must use a group with this option")); - - /* - * Open configuration file. - */ - if ((cfg = cfg_open(NULL)) == NULL) { - perror("unable to access configuration"); - exit(2); - } - - /* - * Set write locking (CFG_WRLOCK) for: - * iiadm -e (enable) - * iiadm -d (disable) - * iiadm -A (attach overflow) - * iiadm -D (detach overflow) - * iiadm -g grp -m volume (move volume into group) - * iiadm -E (export shadow [needs to update dsvol section]) - * iiadm -I (import shadow [ditto]) - * iiadm -J (join shadow [ditto]) - * read locking (CFG_RDLOCK) for all other commands - */ - last_lock = (eflg || dflg || mflg || Aflg || Dflg || Eflg || Iflg || - Jflg)? CFG_WRLOCK : CFG_RDLOCK; - if (!cfg_lock(cfg, last_lock)) { - perror("unable to lock configuration"); - exit(2); - } - config_locked = 1; - - /* - * If we are in a cluster, set or derive a valid disk group - */ - switch (check_cluster()) { - case II_CLUSTER: - /* - * If in a Sun Cluster, can't Import an II shadow - * Must be done as -C local - */ - if (Iflg) - dsw_error(gettext( - "-I (import) only allowed as -C local"), NULL); - /*FALLTHRU*/ - case II_CLUSTER_LCL: - /* - * If a cluster tag was specified or derived, set it - */ - if (CLflg) { - dsw_list_clusters(argv[optind]); - cfg_close(cfg); - exit(0); - } else { - cfg_resource(cfg, cfg_cluster_tag); - } - break; - case II_NOT_CLUSTER: - if (cfg_cluster_tag != NULL) - dsw_error(gettext( - "-C is valid only in a Sun Cluster"), NULL); - break; - default: - dsw_error(gettext( - "Unexpected return from check_cluster()"), NULL); - } - - /* preload the ii config */ - load_ii_vols(cfg); - reload_vols |= LD_II; - - if (eflg) { - if (argc - optind != 3) - usage(gettext("must specify 3 volumes with -e")); - av[1] = argv[optind++]; - av[2] = argv[optind++]; - av[3] = argv[optind++]; - ac = 5; - dsw_enable(ac, av); - } else if (dflg) { - dsw_disable(ac, av); - } else if (uflg) { - if (argv[optind] == NULL && group_name == NULL) - usage(gettext("must specify volume with -u")); - for (c = 1; argv[optind] != NULL; optind++) - av[c++] = argv[optind]; - av[c] = NULL; - - if (direction == ToMaster) - dsw_update_master(ac, av); - else - dsw_update_shadow(ac, av); - } else if (iflg) { - if (argv[optind]) { - av[1] = argv[optind]; - ac = 2; - } else - ac = 1; - dsw_display_status(ac, av); - } else if (bflg) { - dsw_display_bitmap(ac, av); - } else if (cflg) { - if (argv[optind] == NULL && group_name == NULL) - usage(gettext("must specify volume with -c")); - for (c = 1; argv[optind] != NULL; optind++) - av[c++] = argv[optind]; - av[c] = NULL; - - if (direction == ToMaster) - dsw_copy_to_master(ac, av); - else - dsw_copy_to_shadow(ac, av); - } else if (aflg) { - dsw_abort_copy(ac, av); - } else if (Eflg) { - dsw_export(ac, av); - } else if (Iflg) { - if (argc - optind != 1) - usage(gettext("must specify 2 volumes with -I")); - av[2] = argv[optind++]; - ac = 3; - dsw_import(ac, av); - } else if (Aflg) { - if (group_name) { - if (argc - optind != 0) - usage(gettext("must specify overflow volume " \ - "when using groups with -A")); - ac = 2; - } else { - if (argc - optind != 1) - usage(gettext("specify 2 volumes with -A")); - ac = 3; - av[2] = argv[optind++]; - } - dsw_attach(ac, av); - } else if (Dflg) { - dsw_detach(ac, av); - } else if (Jflg) { - if (argc - optind != 1) - usage(gettext("must specify 2 volumes with -J")); - av[2] = argv[optind++]; - ac = 3; - dsw_join(ac, av); - } else if (Pflg) { - if (argc - optind == ((group_name) ? 0 : 1)) { - av[1] = argv[optind++]; - ac = (group_name) ? 0 : 2; - } else if (argc - optind == ((group_name) ? 2 : 3)) { - av[1] = argv[optind++]; - av[2] = argv[optind++]; - av[3] = argv[optind++]; - ac = (group_name) ? 2 : 4; - } else - usage(gettext( - "must specify delay, unit and shadow with -P")); - dsw_params(ac, av); - } else if (Oflg) { - dsw_overflow(ac, av); - } else if (Rflg) { - dsw_reset(ac, av); - } else if (vflg) { - dsw_version(ac, av); - } else if (wflg) { - dsw_wait(ac, av); - } else if (lflg) { - if ((gflg) && (!group_name)) - dsw_list_group_volumes(); - else - dsw_list_volumes(ac, av); - } else if (Lflg) { - dsw_olist(ac, av); - } else if (gLflg) { - dsw_list_groups(); - } else if (Qflg) { - dsw_ostat(ac, av); - } else if (mflg) { - if (argc - optind < 1) - usage(gettext("must specify one or more volumes")); - for (c = 1; argv[optind] != NULL; optind++) - av[c++] = argv[optind]; - av[c] = NULL; - dsw_move_2_group(ac, av); - } - if (cfg) - cfg_close(cfg); - - exit(0); - return (0); -} - -static int -ii_lock(CFGFILE *cfg, int locktype) -{ - last_lock = locktype; - return (cfg_lock(cfg, locktype)); -} - -static int -do_ioctl(int fd, int cmd, void *arg) -{ - int unlocked = 0; - int rc; - int save_errno; - - if (config_locked) { - switch (cmd) { - case DSWIOC_ENABLE: - case DSWIOC_RESUME: - case DSWIOC_SUSPEND: - case DSWIOC_COPY: - case DSWIOC_BITMAP: - case DSWIOC_DISABLE: - case DSWIOC_SHUTDOWN: - case DSWIOC_ABORT: - case DSWIOC_RESET: - case DSWIOC_OFFLINE: - case DSWIOC_WAIT: - case DSWIOC_ACOPY: - case DSWIOC_EXPORT: - case DSWIOC_IMPORT: - case DSWIOC_JOIN: - case DSWIOC_COPYP: - case DSWIOC_OATTACH: - case DSWIOC_ODETACH: - case DSWIOC_SBITSSET: - case DSWIOC_CBITSSET: - case DSWIOC_SEGMENT: - case DSWIOC_MOVEGRP: - case DSWIOC_CHANGETAG: - cfg_unlock(cfg); - unlocked = 1; - break; - - case DSWIOC_STAT: - case DSWIOC_VERSION: - case DSWIOC_LIST: - case DSWIOC_OCREAT: - case DSWIOC_OLIST: - case DSWIOC_OSTAT: - case DSWIOC_OSTAT2: - case DSWIOC_LISTLEN: - case DSWIOC_OLISTLEN: - case DSWIOC_CLIST: - case DSWIOC_GLIST: - break; - - default: - (void) fprintf(stderr, - "cfg locking needs to be set for %08x\n", cmd); - exit(1); - break; - } - } - if (unlocked) { - /* unload vol hashes */ - if (reload_vols & LD_II) - unload_ii_vols(); - if (reload_vols & LD_SHADOWS) - cfg_unload_shadows(); - if (reload_vols & LD_DSVOLS) - cfg_unload_dsvols(); - if (reload_vols & LD_SVOLS) - cfg_unload_svols(); - } - rc = ioctl(fd, cmd, arg); - save_errno = errno; - if (config_locked && unlocked) { - (void) cfg_lock(cfg, last_lock); - } - if (unlocked) { - /* reload vol hashes */ - if (reload_vols & LD_SVOLS) - (void) cfg_load_svols(cfg); - if (reload_vols & LD_DSVOLS) - (void) cfg_load_dsvols(cfg); - if (reload_vols & LD_SHADOWS) - (void) cfg_load_shadows(cfg); - if (reload_vols & LD_II) - load_ii_vols(cfg); - } - - errno = save_errno; - return (rc); -} - -static int -get_dsw_config(int setno, dsw_config_t *parms) -{ - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - - bzero(parms, sizeof (dsw_config_t)); - (void) snprintf(key, sizeof (key), "ii.set%d.master", setno); - if (cfg_get_cstring(cfg, key, parms->master_vol, DSW_NAMELEN) < 0) - return (-1); - - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", setno); - (void) cfg_get_cstring(cfg, key, parms->shadow_vol, DSW_NAMELEN); - - (void) snprintf(key, sizeof (key), "ii.set%d.bitmap", setno); - (void) cfg_get_cstring(cfg, key, parms->bitmap_vol, DSW_NAMELEN); - - (void) snprintf(key, sizeof (key), "ii.set%d.mode", setno); - (void) cfg_get_cstring(cfg, key, buf, sizeof (buf)); - if (strcmp(buf, "I") == 0) - parms->flag |= DSW_GOLDEN; - - (void) snprintf(key, sizeof (key), "ii.set%d.overflow", setno); - (void) cfg_get_cstring(cfg, key, last_overflow, DSW_NAMELEN); - - (void) snprintf(key, sizeof (key), "ii.set%d.group", setno); - (void) cfg_get_cstring(cfg, key, parms->group_name, DSW_NAMELEN); - - (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setno); - (void) cfg_get_cstring(cfg, key, parms->cluster_tag, DSW_NAMELEN); - return (0); -} - -static int -find_next_cf_line(char *volume, int next) -{ - dsw_config_t cf_line; - - for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0; - setnumber++) { - if (strncmp(volume, cf_line.master_vol, DSW_NAMELEN) == 0 || - strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0 || - strncmp(volume, cf_line.bitmap_vol, DSW_NAMELEN) == 0) - return (1); - } - return (0); -} -int -find_any_cf_line(char *volume) -{ - return (find_next_cf_line(volume, 1)); -} - -static int -find_next_shadow_line(char *volume, int next) -{ - dsw_config_t cf_line; - - for (setnumber = next; get_dsw_config(setnumber, &cf_line) == 0; - setnumber++) { - if (strncmp(volume, cf_line.shadow_vol, DSW_NAMELEN) == 0) - return (1); - } - return (0); -} -int -find_shadow_line(char *volume) -{ - return (find_next_shadow_line(volume, 1)); -} - -/* - * this function is designed to be called once, subsequent calls won't - * free memory allocated by earlier invocations. - */ -char * -get_overflow_list() -{ - dsw_aioctl_t *acopy_args; - int rc, num; - - num = do_ioctl(dsw_fd, DSWIOC_OLISTLEN, NULL); - if (num < 0) - dsw_error(gettext("Can't get overflow list length"), NULL); - - acopy_args = malloc(sizeof (dsw_aioctl_t) + num * DSW_NAMELEN); - if (acopy_args == NULL) - dsw_error(gettext("Can't get memory for list enquiry"), NULL); - - acopy_args->count = num; - acopy_args->flags = 0; - acopy_args->status = spcs_s_ucreate(); - - rc = do_ioctl(dsw_fd, DSWIOC_OLIST, acopy_args); - if (rc == -1) - dsw_error(gettext("Overflow list access failure"), - &acopy_args->status); - else - acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL; - - return (acopy_args->shadow_vol); -} - -/* - * this function is designed to be called once, subsequent calls won't - * free memory allocated by earlier invocations. - */ - -int -find_group_members(char *group) -{ - int nmembers = 0; - int vector_len = 0; - - group_volumes = NULL; - for (setnumber = 1; /*CSTYLED*/; setnumber++) { - (void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - if (strcmp(group, buf)) - continue; - - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - if (nmembers >= vector_len) { - vector_len += 10; - group_volumes = realloc(group_volumes, (1+vector_len) * - sizeof (char *)); - } - group_volumes[nmembers] = strdup(buf); - nmembers++; - } - if (group_volumes) - group_volumes[nmembers] = NULL; /* terminate list */ - return (nmembers); -} - -static int -find_next_matching_cf_line( - char *volume, dsw_config_t *conf, dsw_ioctl_t *io, int next) -{ - dsw_config_t config; - - if (!find_next_cf_line(volume, next)) { - return (0); - } - - if (conf == NULL) - conf = &config; - (void) get_dsw_config(setnumber, conf); - if (io) { - (void) strlcpy(io->shadow_vol, conf->shadow_vol, DSW_NAMELEN); - } - return (1); -} - -int -find_matching_cf_line(char *volume, dsw_config_t *conf, dsw_ioctl_t *io) -{ - return (find_next_matching_cf_line(volume, conf, io, 1)); -} - -int -find_shadow_config(char *volume, dsw_config_t *conf, dsw_ioctl_t *io) -{ - dsw_config_t *c, cf; - - if (io) { - bzero(io, sizeof (dsw_ioctl_t)); - } - c = conf ? conf : &cf; - setnumber = 1; - /* perform action for each line of the stored config file */ - for ((void) snprintf(key, sizeof (key), "ii.set%d.shadow", setnumber); - cfg_get_cstring(cfg, key, c->shadow_vol, DSW_NAMELEN) >= 0; - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - ++setnumber)) { - if (strncmp(volume, c->shadow_vol, DSW_NAMELEN) == 0) { - (void) get_dsw_config(setnumber, c); - - if (check_resource_group(c->bitmap_vol)) { - setnumber = 0; - continue; - } - - switch (check_cluster()) { - case II_CLUSTER: - if ((cfg_cluster_tag) && - (strcmp(cfg_cluster_tag, c->cluster_tag))) - continue; - break; - case II_CLUSTER_LCL: - if (strlen(c->cluster_tag)) - continue; - break; - } - - if (io) { - (void) strlcpy(io->shadow_vol, c->shadow_vol, - DSW_NAMELEN); - } - return (1); - } - } - return (0); -} - -void -add_cfg_entry(dsw_config_t *parms) -{ - /* insert the well-known fields first */ - (void) snprintf(buf, sizeof (buf), "%s %s %s %s", - parms->master_vol, parms->shadow_vol, parms->bitmap_vol, - (parms->flag & DSW_GOLDEN) ? "I" : "D"); - - if (cfg_put_cstring(cfg, "ii", buf, strlen(buf)) >= 0) { - /* if we have a group name, add it */ - if (group_name) { - if (find_any_cf_line(parms->shadow_vol)) { - (void) sprintf(buf, "ii.set%d.group", - setnumber); - if (cfg_put_cstring(cfg, buf, - group_name, strlen(group_name)) < 0) - perror("cfg_put_cstring"); - } - else - perror("cfg_location"); - } - - /* commit the record */ - (void) cfg_commit(cfg); - } - else - perror("cfg_put_string"); -} - -void -remove_iiset(int setno, char *shadow, int shd_exp) -{ - mstcount_t *mdata; - shdvol_t *sdata; - char sn[CFG_MAX_BUF]; - - if (perform_autosv()) { - if (volhash) { - unload_ii_vols(); - } - load_ii_vols(cfg); - if (cfg_load_dsvols(cfg) < 0 || cfg_load_svols(cfg) < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - - sdata = (shdvol_t *)nsc_lookup(volhash, shadow); - if (sdata) { - /* - * Handle the normal cases of disabling a set that is - * not an imported shadow volume - */ - if (strcmp(sdata->master, II_IMPORTED_SHADOW)) { - /* - * Handle multiple-shadows of single master - */ - mdata = (mstcount_t *) - nsc_lookup(volhash, sdata->master); - if ((mdata) && (mdata->count == 1)) { - if (cfg_vol_disable(cfg, sdata->master, - cfg_cluster_tag, "ii") < 0) - dsw_error(gettext( - "SV disable of master " - "failed"), - NULL); - } - } - - /* - * Handle disk group name of different shadow - */ - if (shd_exp) { - /* - * If shadow is exported, then do nothing - */ - /*EMPTY*/; - } else if (cfg_cluster_tag && - strcmp(cfg_cluster_tag, "") && - cfg_dgname(shadow, sn, sizeof (sn)) && - strlen(sn) && - strcmp(sn, cfg_cluster_tag)) { - /* reload disk group volumes */ - cfg_resource(cfg, sn); - cfg_unload_dsvols(); - cfg_unload_svols(); - (void) cfg_load_dsvols(cfg); - (void) cfg_load_svols(cfg); - if (cfg_vol_disable(cfg, shadow, sn, - "ii") < 0) { - dsw_error(gettext( - "SV disable of shadow " - "failed"), - NULL); - } - cfg_resource(cfg, cfg_cluster_tag); - } else { - if (cfg_vol_disable(cfg, shadow, - cfg_cluster_tag, "ii") < 0) - dsw_error(gettext( - "SV disable of shadow failed"), - NULL); - } - } - cfg_unload_svols(); - cfg_unload_dsvols(); - unload_ii_vols(); - reload_vols &= ~(LD_SVOLS | LD_DSVOLS | LD_II); - } - - (void) sprintf(key, "ii.set%d", setno); - if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { - perror("cfg_put_cstring"); - } - (void) cfg_commit(cfg); -} - -/* - * determine if we are running in a Sun Cluster Environment - */ -int -check_cluster() -{ - static int is_cluster = -1; - int rc; -#ifdef DEBUG - char *cdebug = getenv("II_SET_CLUSTER"); -#endif - - /* - * If this routine was previously called, just return results - */ - if (is_cluster != -1) - return (is_cluster); - - /* - * See if Sun Cluster was installed on this node - */ -#ifdef DEBUG - if (cdebug) rc = atoi(cdebug); - else -#endif - rc = cfg_iscluster(); - if (rc > 0) { - /* - * Determine if user specified -C local - */ - if ((cfg_cluster_tag == NULL) || - (strcmp(cfg_cluster_tag, II_LOCAL_TAG))) { - /* - * We're in a Sun Cluster, and no "-C local" - */ - is_cluster = II_CLUSTER; - } else { - /* - * We're in a Sun Cluster, but "-C local" was specified - */ - is_cluster = II_CLUSTER_LCL; - cfg_cluster_tag = ""; - } - return (is_cluster); - } else if (rc == 0) { - /* - * Not in a Sun Cluster - */ - is_cluster = II_NOT_CLUSTER; - return (is_cluster); - } else { - dsw_error(gettext("unable to ascertain environment"), NULL); - /*NOTREACHED*/ - } - - /* gcc */ - return (is_cluster); -} - -/* - * Determine if we need to set a cfg_resource based on this volume - */ -static int -check_resource_group(char *volume) -{ - char diskgroup[CFG_MAX_BUF]; - - /* - * If we are in a cluster, attempt to derive a new resource group - */ - -#ifdef DEBUG - if (getenv("II_SET_CLUSTER") || (check_cluster() == II_CLUSTER)) { -#else - if (check_cluster() == II_CLUSTER) { -#endif - if (check_diskgroup(volume, diskgroup)) { - if (cfg_cluster_tag == NULL) { - cfg_cluster_tag = strdup(diskgroup); - if (cfg_cluster_tag == NULL) - dsw_error(gettext( - "Memory allocation failure"), NULL); - cfg_resource(cfg, cfg_cluster_tag); - return (1); - } else { - /* - * Check dgname and cluster tag from -C are - * the same. - */ - if (strcmp(diskgroup, cfg_cluster_tag) != 0) { - char error_buffer[128]; - (void) snprintf(error_buffer, - sizeof (error_buffer), - gettext("-C (%s) does not match " - "disk group name (%s) for %s"), - cfg_cluster_tag, diskgroup, volume); - spcs_log("ii", NULL, error_buffer); - dsw_error(error_buffer, NULL); - } - } - } else if (cfg_cluster_tag == NULL) - dsw_error(gettext( - "Point-in-Time Copy volumes, that are not " - "in a device group which has been " - "registered with SunCluster, " - "require usage of \"-C\""), NULL); - } - return (0); -} - -static void -check_dg_is_local(char *dgname) -{ - char error_buffer[128]; - char *othernode; - int rc; - - /* - * check where this disk service is mastered - */ - rc = cfg_dgname_islocal(dgname, &othernode); - if (rc < 0) { - (void) snprintf(error_buffer, sizeof (error_buffer), - gettext("Unable to find disk service:%s"), dgname); - dsw_error(error_buffer, NULL); - } else if (rc == 0) { - (void) snprintf(error_buffer, sizeof (error_buffer), - gettext("disk service, %s, is active on node \"%s\"\n" - "Please re-issue the command on that node"), dgname, - othernode); - dsw_error(error_buffer, NULL); - } -} - -/* - * Carry out cluster based checks for a specified volume, or just - * global options. - */ -static int -check_diskgroup(char *path, char *result) -{ - char dgname[CFG_MAX_BUF]; - char error_buffer[128]; - -#ifdef DEBUG - char *override = getenv("II_CLUSTER_TAG"); - if (override) { - (void) strcpy(result, override); - return (1); - } -#endif - /* - * Check on path name, a returned NULL dgname is valid - */ - if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) { - (void) snprintf(error_buffer, sizeof (error_buffer), gettext( - "unable to determine disk group name for %s"), path); - dsw_error(error_buffer, NULL); - } - if (strcmp(dgname, "") == 0) - return (0); - - /* - * See if disk group is local to this node - */ - check_dg_is_local(dgname); - - /* - * Copy dgname into result - */ - (void) strcpy(result, dgname); - return (1); -} - -/* - * sigterm (): traps specified signal , usually termination one - */ -void -sigterm(int sig) -{ - spcs_log("ii", NULL, gettext("%s received signal %d"), cmdnam, sig); - exit(1); -} - -/* - * sigchild; reap child and collect status. - */ - -volatile pid_t dead_child; -int dead_stat; - -/*ARGSUSED*/ -void -sigchild(int sig) -{ - dead_child = wait(&dead_stat); -} - -/* - * InitEnv(): initializes environment - */ -void -InitEnv() -{ - (void) setlocale(LC_ALL, ""); - (void) textdomain(DSW_TEXT_DOMAIN); - -#ifndef DEBUG - (void) sigset(SIGHUP, sigterm); - (void) sigset(SIGINT, sigterm); - (void) sigset(SIGQUIT, sigterm); - (void) sigset(SIGILL, sigterm); - (void) sigset(SIGEMT, sigterm); - (void) sigset(SIGABRT, sigterm); - (void) sigset(SIGFPE, sigterm); - (void) sigset(SIGBUS, sigterm); - (void) sigset(SIGSEGV, sigterm); - (void) sigset(SIGTERM, sigterm); - (void) sigset(SIGPWR, sigterm); - (void) sigset(SIGSTOP, sigterm); - (void) sigset(SIGTSTP, sigterm); -#endif - - dsw_fd = open(DSWDEV, O_RDONLY); - if (dsw_fd < 0) { - perror(DSWDEV); - exit(1); - } - - (void) setsid(); -} - -/* - * print an error message, followed by decoded errno then exit. - */ -void -dsw_error(char *str, spcs_s_info_t *status) -{ - char *sp; - - (void) fprintf(stderr, "%s: %s:\n", cmdnam, str); - if (status == NULL) { - /* deflect ESRCH */ - if (ESRCH == errno) { - sp = "Set/volume not found"; - } else { - sp = strerror(errno); - } - (void) fprintf(stderr, "%s\n", sp ? sp : ""); - } else { - spcs_s_report(*status, stderr); - spcs_s_ufree(status); - } - if (cfg) - cfg_close(cfg); - exit(2); -} - - -#undef size - -void -free_bitmap(unsigned char *bitmap) -{ - free(bitmap); -} - - -int -get_bitmap(master_volume, shd_bitmap, copy_bitmap, size) - char *master_volume; - unsigned char *shd_bitmap; - unsigned char *copy_bitmap; - unsigned long size; -{ - dsw_bitmap_t parms; - - (void) strlcpy(parms.shadow_vol, master_volume, DSW_NAMELEN); - parms.shd_bitmap = shd_bitmap; - parms.shd_size = size; - parms.copy_bitmap = copy_bitmap; - parms.copy_size = size; - - return (do_ioctl(dsw_fd, DSWIOC_BITMAP, &parms)); -} - -unsigned char * -allocate_bitmap(char *shadow_volume) -{ - unsigned char *shd_bitmap; - unsigned char *copy_bitmap; - unsigned char *p; - unsigned char *q; - int i; - dsw_stat_t args; - int stat_flags; - - (void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN); - - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) - dsw_error(gettext("Stat failed"), &args.status); - - stat_flags = args.stat; - if (stat_flags & DSW_BMPOFFLINE) - return (NULL); - - bm_size = args.size; - bm_size = (bm_size + DSW_SIZE-1) / DSW_SIZE; - bm_actual = bm_size; - bm_size = (bm_size + DSW_BITS-1) / DSW_BITS; - spcs_s_ufree(&args.status); - - p = shd_bitmap = (unsigned char *) malloc(bm_size); - if (!shd_bitmap) { - perror(gettext("malloc bitmap")); - return (NULL); - } - - q = copy_bitmap = (unsigned char *) malloc(bm_size); - if (!copy_bitmap) { - perror(gettext("malloc bitmap")); - free(shd_bitmap); - return (NULL); - } - - (void) memset(shd_bitmap, 0, bm_size); - (void) memset(copy_bitmap, 0, bm_size); - - if (get_bitmap(shadow_volume, shd_bitmap, copy_bitmap, bm_size) < 0) { - free(copy_bitmap); - free(shd_bitmap); - return (NULL); - } - - /* - * "or" the copy and shadow bitmaps together to return a composite - * bitmap that contains the total set of differences between the - * volumes. - */ - for (i = bm_size; i-- > 0; /*CSTYLED*/) - *p++ |= *q++; - - free(copy_bitmap); - - return (shd_bitmap); -} - -/* - * print usage message and exit. - */ -void -usage(char *why) -{ - if (why) { - (void) fprintf(stderr, "%s: %s\n", cmdnam, why); - - (void) fprintf(stderr, "%s\n", - gettext("\nBrief summary:")); - (void) fprintf(stderr, "%s\n", - gettext("\t-e {ind|dep} master_vol shadow_vol " - "bitmap_vol")); - (void) fprintf(stderr, "%s\n", - gettext("\t-[cu {s|m}] volume_set")); - (void) fprintf(stderr, "%s\n", - gettext("\t-i all")); - (void) fprintf(stderr, "%s\n", - gettext("\t-[adDEilPRw] volume_set")); - (void) fprintf(stderr, "%s\n", - gettext("\t-g group_name [options]")); - (void) fprintf(stderr, "%s\n", - gettext("\t-C cluster_tag [options]")); - (void) fprintf(stderr, "%s\n", - gettext("\t-[hilLv]")); - (void) fprintf(stderr, "%s\n", - gettext("\t-[IJ] volume_set bitmap")); - (void) fprintf(stderr, "%s\n", - gettext("\t-A overflow_vol volume_set")); - (void) fprintf(stderr, "%s\n", - gettext("\t-[OQ] overflow_vol")); - (void) fprintf(stderr, "%s\n", - gettext("\t-P {delay} {units} volume_set")); - - /* assume we came here due to a user mistake */ - exit(1); - /* NOTREACHED */ - } else { - - (void) fprintf(stdout, "%s\n", - gettext("Point-in-Time Copy Administrator CLI options")); - (void) fprintf(stdout, "%s\n", - gettext("Usage summary:")); - (void) fprintf(stdout, "%s\n", - gettext("\t-e ind m s b\tenable independent master shadow " - "bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-e dep m s b\tenable dependent master shadow " - "bitmap")); - if (check_cluster() == II_CLUSTER) - (void) fprintf(stdout, "%s\n", - gettext("\t-ne ind m s b\tenable exportable master " - "shadow bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-d v\t\tdisable volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-u s v\t\tupdate shadow volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-u m v\t\tupdate master volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-c s v\t\tcopy to shadow volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-c m v\t\tcopy to master volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-a v\t\tabort copy volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-w v\t\twait volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-i v\t\tdisplay volume status")); - (void) fprintf(stdout, "%s\n", - gettext("\t-i all\t\tdisplay all volume status")); - (void) fprintf(stdout, "%s\n", - gettext("\t-l\t\tlist all volumes")); - (void) fprintf(stdout, "%s\n", - gettext("\t-R v\t\treset volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-A o v\t\tattach overflow to volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-D v\t\tdetach overflow from volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-L\t\tlist all overflow volumes")); - (void) fprintf(stdout, "%s\n", - gettext("\t-O o\t\tinitialize overflow")); - (void) fprintf(stdout, "%s\n", - gettext("\t-Q o\t\tquery status of overflow")); - (void) fprintf(stdout, "%s\n", - gettext("\t-E v\t\texport shadow volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-I v b\t\timport volume bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-J v b\t\tjoin volume bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-P d u v\tset copy delay/units for volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-P v\t\tget copy delay/units for volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-C tag\t\tcluster resource tag")); -#ifdef DEBUG - (void) fprintf(stdout, "%s\n", - gettext("\t-b v\t\tdisplay bitmap volume")); - (void) fprintf(stdout, "%s\n", - gettext("\t-f f\t\tuse private configuration file")); -#endif - (void) fprintf(stdout, "%s\n", - gettext("\t-v\t\tprint software versions")); - (void) fprintf(stdout, "%s\n", - gettext("\t-n\t\tperform action without question")); - (void) fprintf(stdout, "%s\n", - gettext("\t-p [-c|-u] {m|s}" - "enable PID locking on copy or update")); - (void) fprintf(stdout, "%s\n", - gettext("\t-p -w v\t\tdisable PID locking")); - (void) fprintf(stdout, "%s\n", - gettext("\t-h\t\tiiadm usage summary")); - (void) fprintf(stdout, "%s\n", - gettext("\nUsage summary for options that support " - "grouping (-g g):")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -e ind m s b group enable independent " - "master shadow bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -e dep m s b group enable dependent " - "master shadow bitmap")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -d\t\tdisable group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -u s\tupdate shadow for all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -u m\tupdate master for all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -c s\tcopy to shadow for all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -c m\tcopy to master for all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -a\t\tabort copy for all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -w\t\twait for all volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -i\t\tdisplay status of all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -l\t\tlist all volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g -L\t\tlist all groups")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -m v v\tmove one or more volumes into " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g \"\" -m v\tremove volume from group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -R\t\treset all volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -A o\tattach overflow to all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -D\t\tdetach overflow from all volumes in " - "group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -E\t\texport shadow volume for all " - "volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -P d u\tset copy delay/units for all " - "volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\t-g g -P\t\tget copy delay/units for all " - "volumes in group")); - (void) fprintf(stdout, "%s\n", - gettext("\nLegend summary:")); - (void) fprintf(stdout, "%s\n", - gettext("\tind\t\tindependent volume set")); - (void) fprintf(stdout, "%s\n", - gettext("\tdep\t\tdependent volume set")); - (void) fprintf(stdout, "%s\n", - gettext("\tall\t\tall configured volumes")); - (void) fprintf(stdout, "%s\n", - gettext("\tm\t\tmaster volume")); - (void) fprintf(stdout, "%s\n", - gettext("\ts\t\tshadow volume")); - (void) fprintf(stdout, "%s\n", - gettext("\tv\t\tshadow volume (reference name)")); - (void) fprintf(stdout, "%s\n", - gettext("\to\t\toverflow volume")); - (void) fprintf(stdout, "%s\n", - gettext("\tb\t\tbitmap volume")); -#ifdef DEBUG - (void) fprintf(stdout, "%s\n", - gettext("\tf\t\tconfiguration file name")); -#endif - (void) fprintf(stdout, "%s\n", - gettext("\td\t\tdelay tick interval")); - (void) fprintf(stdout, "%s\n", - gettext("\tu\t\tunit size")); - (void) fprintf(stdout, "%s\n", - gettext("\tg\t\tgroup name")); - - /* assume we came here because user request help text */ - exit(0); - /* NOTREACHED */ - } - -} - -static char yeschr[MAX_LINE_SIZE + 2]; -static char nochr[MAX_LINE_SIZE + 2]; - -static int -yes(void) -{ - int i, b; - char ans[MAX_LINE_SIZE + 1]; - - for (i = 0; /*CSTYLED*/; i++) { - b = getchar(); - if (b == '\n' || b == '\0' || b == EOF) { - if (i < MAX_LINE_SIZE) - ans[i] = 0; - break; - } - if (i < MAX_LINE_SIZE) - ans[i] = b; - } - if (i >= MAX_LINE_SIZE) { - i = MAX_LINE_SIZE; - ans[MAX_LINE_SIZE] = 0; - } - if ((i == 0) || (strncmp(yeschr, ans, i))) { - if (strncmp(nochr, ans, i) == 0) - return (0); - else if (strncmp(yeschr, ans, i) == 0) - return (1); - else { - (void) fprintf(stderr, "%s %s/%s\n", - gettext("You have to respond with"), - yeschr, nochr); - return (2); - } - } - return (1); -} - -static int -convert_int(char *str) -{ - int result, rc; - char *buf; - - buf = (char *)calloc(strlen(str) + 256, sizeof (char)); - rc = sscanf(str, "%d%s", &result, buf); - - if (rc != 1) { - (void) sprintf(buf, gettext("'%s' is not a valid number"), str); - /* dsw_error calls exit which frees 'buf' */ - errno = EINVAL; - dsw_error(buf, NULL); - } - free(buf); - - return (result); -} - -void -check_action(char *will_happen) -{ - int answer; - - if (nflg || !isatty(fileno(stdin))) - return; - (void) strncpy(yeschr, nl_langinfo(YESSTR), MAX_LINE_SIZE + 1); - (void) strncpy(nochr, nl_langinfo(NOSTR), MAX_LINE_SIZE + 1); - - /*CONSTCOND*/ - while (1) { - (void) printf("%s %s/%s ", will_happen, yeschr, nochr); - answer = yes(); - if (answer == 1 || answer == 0) - break; - } - if (answer == 1) - return; - exit(1); -} - -enum child_event {Status, CopyStart}; - -/* - * Wait for child process to get to some state, where some state may be: - * - * Status Set up the shadow enough so that it responds - * to status requests. - * CopyStart Start copy/update operations. - */ - -int -child_wait(pid_t child, enum child_event event, char *volume) -{ - dsw_stat_t args; - int rc; - - (void) strlcpy(args.shadow_vol, volume, DSW_NAMELEN); - - for (; dead_child != child; (void) sleep(1)) { - - /* poll shadow group with a status ioctl() */ - args.status = spcs_s_ucreate(); - errno = 0; - rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args); - - spcs_s_ufree(&args.status); - - if (event == Status) { - /* keep polling while we fail with DSW_ENOTFOUND */ - if (rc != -1 || errno != DSW_ENOTFOUND) - return (0); - } else { - /* event == CopyStart */ - if (rc == -1) { - return (1); /* something wrong */ - } - if (args.stat & DSW_COPYINGP) - return (0); /* copying underway */ - } - } - /* child died */ - if (WIFEXITED(dead_stat)) - return (WEXITSTATUS(dead_stat)); - else - return (1); -} - -int -mounted(char *t) -{ - int rdsk; - int i; - FILE *mntfp; - struct mnttab mntref; - struct mnttab mntent; - char target[DSW_NAMELEN]; - char *s; - - rdsk = i = 0; - for (s = target; i < DSW_NAMELEN && (*s = *t++); i++) { - if (*s == 'r' && rdsk == 0) - rdsk = 1; - else - s++; - } - *s = '\0'; - - mntref.mnt_special = target; - mntref.mnt_mountp = NULL; - mntref.mnt_fstype = NULL; - mntref.mnt_mntopts = NULL; - mntref.mnt_time = NULL; - - if ((mntfp = fopen("/etc/mnttab", "r")) == NULL) { - dsw_error(gettext("Can not check volume against mount table"), - NULL); - } - if (getmntany(mntfp, &mntent, &mntref) != -1) { - /* found something before EOF */ - (void) fclose(mntfp); - return (1); - } - (void) fclose(mntfp); - return (0); -} - -void -enable(char *master_volume, char *shadow_volume, - char *bitmap_volume, char *copy_type) -{ - dsw_config_t parms; - dsw_ioctl_t temp; - char *p; - int rc; - pid_t child; - spcs_s_info_t *sp_info; - struct stat mstat, sstat, bstat; - char mst_dg[DSW_NAMELEN] = {0}; - char shd_dg[DSW_NAMELEN] = {0}; - char bmp_dg[DSW_NAMELEN] = {0}; - int mvol_enabled; - char *altname; - grptag_t *gdata; - - bzero(&parms, sizeof (dsw_config_t)); - - if (strcmp(copy_type, "independent") == 0 || - strcmp(copy_type, gettext("independent")) == 0) - parms.flag = DSW_GOLDEN; - else if (strcmp(copy_type, "dependent") == 0 || - strcmp(copy_type, gettext("dependent")) == 0) - parms.flag = 0; - else - dsw_error(gettext("don't understand shadow type"), NULL); - - /* validate volume names */ - if (perform_autosv()) { - if (cfg_load_svols(cfg) < 0 || cfg_load_dsvols(cfg) < 0 || - cfg_load_shadows(cfg) < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - load_ii_vols(cfg); - reload_vols = LD_SVOLS | LD_DSVOLS | LD_SHADOWS | LD_II; - - /* see if it's been used before under a different name */ - conform_name(&master_volume); - conform_name(&shadow_volume); - rc = cfg_get_canonical_name(cfg, bitmap_volume, &altname); - if (rc < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - if (rc) { - errno = EBUSY; - dsw_error(gettext("Bitmap in use"), NULL); - } - } - - /* - * If not local, determine disk group names for volumes in II set - */ - switch (check_cluster()) { - case II_CLUSTER: - /* - * Check if none or all volumes are in a disk group - */ - rc = 0; - if (check_diskgroup(master_volume, mst_dg)) rc++; - if (check_diskgroup(shadow_volume, shd_dg)) rc++; - if (check_diskgroup(bitmap_volume, bmp_dg)) rc++; - if ((rc != 0) && (rc != 3)) - dsw_error(gettext( - "Not all Point-in-Time Copy volumes are " - "in a disk group"), NULL); - - /* - * If volumes are not in a disk group, but are in a - * cluster, then "-C <tag>", must be set - */ - if (rc == 0 && cfg_cluster_tag == NULL) - dsw_error(gettext( - "Point-in-Time Copy volumes, that are not " - "in a device group which has been " - "registered with SunCluster, " - "require usage of \"-C\""), NULL); - - /* - * the same disk group - * If -n, plus mst_dg==bmp_dg, then allow E/I/J in SunCluster - */ - if ((strcmp(mst_dg, bmp_dg)) || - (strcmp(mst_dg, shd_dg) && (!nflg))) - dsw_error(gettext( - "Volumes are not in same disk group"), NULL); - - /* - * Can never enable the same shadow twice, regardless of - * exportable shadow device group movement - */ - if (find_shadow_line(shadow_volume)) - dsw_error(gettext( - "Shadow volume is already configured"), NULL); - - /* - * Groups cannot span multiple clusters - */ - if (group_name && perform_autosv()) { - gdata = (grptag_t *)nsc_lookup(volhash, group_name); - if (gdata && - strncmp(gdata->ctag, mst_dg, DSW_NAMELEN) != 0) { - errno = EINVAL; - dsw_error(gettext("Group contains sets not " - "in the same cluster resource"), NULL); - } - } - - /* - * Check cluster tag and bitmap disk group - * set latter if different - */ - if (check_resource_group(bitmap_volume)) { - /* - * Unload and reload in the event cluster tag has - * changed - */ - if (perform_autosv()) { - unload_ii_vols(); - cfg_unload_shadows(); - cfg_unload_dsvols(); - cfg_unload_svols(); - if (cfg_load_svols(cfg) < 0 || - cfg_load_dsvols(cfg) < 0 || - cfg_load_shadows(cfg) < 0) { - dsw_error(gettext( - "Unable to parse config " - "file"), NULL); - } - load_ii_vols(cfg); - } - } - /* - * Copy cluster name into config - */ - (void) strncpy(parms.cluster_tag, cfg_cluster_tag, DSW_NAMELEN); - break; - - case II_CLUSTER_LCL: - /* ensure that the -C local won't interfere with the set */ - if (group_name && perform_autosv()) { - gdata = (grptag_t *)nsc_lookup(volhash, group_name); - if (gdata) { - if (strlen(gdata->ctag) != 0) { - errno = EINVAL; - dsw_error(gettext("Unable to put set " - "into -C local and specified " - "group"), NULL); - } - } - } - break; - } - - /* - * If we've got a group name, add it into the config - */ - if (group_name) { - (void) strncpy(parms.group_name, group_name, DSW_NAMELEN); - } - - /* - * Determine accessability of volumes - */ - if (stat(master_volume, &mstat) != 0) - dsw_error(gettext( - "Unable to access master volume"), NULL); - if (!S_ISCHR(mstat.st_mode)) - dsw_error(gettext( - "Master volume is not a character device"), NULL); - /* check the shadow_vol hasn't be used as SNDR secondary vol */ - check_iishadow(shadow_volume); - if (stat(shadow_volume, &sstat) != 0) - dsw_error(gettext( - "Unable to access shadow volume"), NULL); - if (!S_ISCHR(sstat.st_mode)) - dsw_error(gettext( - "Shadow volume is not a character device"), NULL); - if (mounted(shadow_volume)) { - errno = EBUSY; - dsw_error(gettext( - "Shadow volume is mounted, unmount it first"), NULL); - } - if (mstat.st_rdev == sstat.st_rdev) { - errno = EINVAL; - dsw_error(gettext( - "Master and shadow are the same device"), NULL); - } - if (stat(bitmap_volume, &bstat) != 0) { - dsw_error(gettext("Unable to access bitmap"), NULL); - } - if (!S_ISCHR(bstat.st_mode)) - dsw_error(gettext( - "Bitmap volume is not a character device"), NULL); - if (S_ISCHR(bstat.st_mode)) { - if (mstat.st_rdev == bstat.st_rdev) { - errno = EINVAL; - dsw_error(gettext( - "Master and bitmap are the same device"), NULL); - } else if (sstat.st_rdev == bstat.st_rdev) { - errno = EINVAL; - dsw_error(gettext( - "Shadow and bitmap are the same device"), NULL); - } - } - - (void) strncpy(parms.master_vol, master_volume, DSW_NAMELEN); - (void) strncpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN); - (void) strncpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN); - errno = 0; - parms.status = spcs_s_ucreate(); - - /* - * Check that none of the member volumes forms part of another - * InstantImage group. - * - * -- this check has been removed; it is done in the kernel instead - * -- PJW - */ - - /* - * Check against overflow volumes - */ - for (p = get_overflow_list(); *p != NULL; p += DSW_NAMELEN) { - if (strncmp(master_volume, p, DSW_NAMELEN) == 0) - dsw_error(gettext( - "Master volume is already an overflow volume"), - NULL); - else if (strncmp(shadow_volume, p, DSW_NAMELEN) == 0) - dsw_error(gettext( - "Shadow volume is already an overflow volume"), - NULL); - else if (strncmp(bitmap_volume, p, DSW_NAMELEN) == 0) - dsw_error(gettext( - "Bitmap volume is already an overflow volume"), - NULL); - } - - /* - * Make sure that the shadow volume is not already configured - */ - if (find_shadow_config(shadow_volume, NULL, &temp)) - dsw_error(gettext( - "Shadow volume is already configured"), NULL); - if (perform_autosv()) { - /* - * parse the dsvol entries to see if we need to place - * the master or shadow under SV control - */ - if (nsc_lookup(volhash, master_volume) == NULL) { - if (cfg_vol_enable(cfg, master_volume, cfg_cluster_tag, - "ii") < 0) { - dsw_error( - gettext("Cannot enable master volume"), - NULL); - } - mvol_enabled = 1; - } else { - mvol_enabled = 0; - } - if (nsc_lookup(volhash, shadow_volume) == NULL) { - if (nflg) { - cfg_resource(cfg, shd_dg); - rc = cfg_vol_enable(cfg, shadow_volume, - shd_dg, "ii"); - cfg_resource(cfg, cfg_cluster_tag); - } else { - rc = cfg_vol_enable(cfg, shadow_volume, - cfg_cluster_tag, "ii"); - } - if (rc < 0) { - if (mvol_enabled) { - if (cfg_vol_disable(cfg, - master_volume, cfg_cluster_tag, - "ii") < 0) - dsw_error(gettext( - "SV disable of master " - "failed"), - NULL); - } - dsw_error( - gettext("Cannot enable shadow volume"), - NULL); - } - } - unload_ii_vols(); - cfg_unload_shadows(); - cfg_unload_dsvols(); - cfg_unload_svols(); - reload_vols = 0; - } - - add_cfg_entry(&parms); - cfg_unlock(cfg); - config_locked = 0; - - (void) sigset(SIGCHLD, sigchild); - switch (child = fork()) { - - case (pid_t)-1: - dsw_error(gettext("Unable to fork"), NULL); - break; - - case 0: - rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms); - if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) { - /* - * Failed to enable shadow group, log problem and remove - * the shadow group from the config file. - */ - spcs_log("ii", &parms.status, - gettext("Enable failed %s %s %s (%s)"), - master_volume, shadow_volume, bitmap_volume, - parms.flag & DSW_GOLDEN ? - "independent" : "dependent"); - - if (!ii_lock(cfg, CFG_WRLOCK) || - !find_shadow_config(shadow_volume, NULL, &temp)) { - dsw_error(gettext( - "Enable failed, can't tidy up cfg"), - &parms.status); - } - config_locked = 1; - remove_iiset(setnumber, shadow_volume, 0); - dsw_error(gettext("Enable failed"), &parms.status); - } - - if (rc == -1) - sp_info = &parms.status; - else - sp_info = NULL; - spcs_log("ii", sp_info, gettext("Enabled %s %s %s (%s)"), - master_volume, shadow_volume, bitmap_volume, - parms.flag & DSW_GOLDEN ? "independent" : "dependent"); - spcs_s_ufree(&parms.status); - break; - - default: - exit(child_wait(child, Status, shadow_volume)); - break; - } -} - -int -reset(char *volume) -{ - dsw_ioctl_t args; - dsw_config_t parms; - int rc; - int wait_loc; - pid_t child = (pid_t)0; - enum copy_wait wait_action; - spcs_s_info_t *stat; - dsw_stat_t prev_stat; - int stat_flags; - static int unlocked = 0; - int do_enable = 0; - char key[CFG_MAX_KEY]; - char optval[CFG_MAX_BUF]; - unsigned int flags; - - wait_action = WaitForStart; - - if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) { - dsw_error(gettext("Unable to set locking on the configuration"), - NULL); - } - config_locked = 1; - if (!find_shadow_config(volume, &parms, &args)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - - cfg_unlock(cfg); - config_locked = 0; - unlocked = 1; - - spcs_log("ii", NULL, gettext("Start reset %s"), volume); - (void) strlcpy(prev_stat.shadow_vol, volume, DSW_NAMELEN); - prev_stat.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_STAT, &prev_stat) == -1) { - /* set is suspended, so we do the enable processing instead */ - do_enable = 1; - - /* first check to see whether the set was offline */ - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options", - setnumber); - if (!ii_lock(cfg, CFG_RDLOCK)) { - dsw_error(gettext("Unable to set locking on the " - "configuration"), NULL); - } - config_locked = 1; - unlocked = 0; - if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, - NSKERN_II_BMP_OPTION, optval, CFG_MAX_BUF) < 0) { - dsw_error(gettext("unable to read config file"), NULL); - } - cfg_unlock(cfg); - config_locked = 0; - unlocked = 1; - (void) sscanf(optval, "%x", &flags); - if ((flags & DSW_OFFLINE) == 0) { - /* set wasn't offline - don't reset */ - dsw_error(gettext("Set not offline, will not reset"), - NULL); - } - parms.status = spcs_s_ucreate(); - stat = &parms.status; - stat_flags = DSW_BMPOFFLINE; - } else { - args.status = spcs_s_ucreate(); - stat = &args.status; - stat_flags = prev_stat.stat; - } - spcs_s_ufree(&prev_stat.status); - - if (wait_action == WaitForStart) - (void) sigset(SIGCHLD, sigchild); - - switch (child = fork()) { - - case (pid_t)-1: - dsw_error(gettext("Unable to fork"), NULL); - break; - - case 0: - if (do_enable) { - rc = do_ioctl(dsw_fd, DSWIOC_ENABLE, &parms); - } else { - rc = do_ioctl(dsw_fd, DSWIOC_RESET, &args); - } - if (rc == -1 && errno != DSW_EABORTED && errno != DSW_EIO) { - spcs_log("ii", stat, gettext("Fail reset %s"), volume); - dsw_error(gettext("Reset shadow failed"), stat); - } - /* last_overflow is set during find_shadow_config */ - if (strlen(last_overflow) > 0 && - (stat_flags & (DSW_SHDOFFLINE | DSW_BMPOFFLINE)) != 0) { - /* reattach it */ - (void) strncpy(parms.bitmap_vol, last_overflow, - DSW_NAMELEN); - do_attach(&parms); - } - spcs_log("ii", stat, gettext("Finish reset %s"), volume); - spcs_s_ufree(stat); - - exit(0); - break; - default: - if (wait_action == WaitForStart) { - rc = child_wait(child, CopyStart, args.shadow_vol); - } else { /* wait_action == WaitForEnd */ - wait_loc = 0; - (void) wait(&wait_loc); - if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0)) - rc = 0; - else - rc = -1; - } - break; - } - /* if successful, remove flags entry from options field */ - if (rc >= 0) { - if (!ii_lock(cfg, CFG_WRLOCK)) { - dsw_error(gettext("Unable to set locking on the " - "configuration"), NULL); - } - config_locked = 1; - if (!find_shadow_config(volume, &parms, &args)) { - dsw_error(gettext("Volume is not in a Point-in-Time " - "Copy group"), NULL); - } - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.options", - setnumber); - if (cfg_del_option(cfg, CFG_SEC_CONF, key, NSKERN_II_BMP_OPTION) - < 0) { - dsw_error(gettext("Update of config failed"), NULL); - } - (void) cfg_commit(cfg); - cfg_unlock(cfg); - config_locked = 0; - } - - return (rc); -} - -int -overflow(char *volume) -{ - dsw_ioctl_t args; - int rc; - spcs_s_info_t *stat; - - check_action(gettext("Initialize this overflow volume?")); - if (find_matching_cf_line(volume, NULL, &args)) - dsw_error(gettext("Volume is part of a Point-in-Time Copy " - "group"), NULL); - args.status = spcs_s_ucreate(); - (void) strncpy(args.shadow_vol, volume, DSW_NAMELEN); - rc = do_ioctl(dsw_fd, DSWIOC_OCREAT, &args); - if (rc == -1) { - spcs_log("ii", &args.status, - gettext("Create overflow failed %s"), volume); - dsw_error(gettext("Create overflow failed"), &args.status); - } - if (rc == -1) - stat = &args.status; - else - stat = NULL; - spcs_log("ii", stat, gettext("Create overflow succeeded %s"), volume); - spcs_s_ufree(&args.status); - - return (0); -} - -void -bitmap_op(char *master_volume, int print_bitmap, int bitmap_percent, int used, - int is_compact) -{ - unsigned char *bitmap; - char *name; - int i, x, y; - unsigned j; - unsigned long n; - unsigned long percent; - - bitmap = allocate_bitmap(master_volume); - if (bitmap == NULL) - return; - - if (bitmap_percent) { - /* count the number of bits set in bitmap */ - for (i = n = 0; i < bm_size; i++) - for (j = (unsigned)bitmap[i]; j; j &= j -1) - n++; - if (is_compact) - (void) printf(gettext("Chunks in map: %d used: %d\n"), - used, n); - if (bm_actual < 100) { - percent = 0; - } else { - percent = (n * 100) / bm_actual; - } - (void) printf(gettext("Percent of bitmap set: %u\n"), percent); - percent = percent/100; - /* distinguish between 0.0000% and 0.n% of bitmap set */ - if (percent < 1) - (void) printf("\t(%s)\n", n > 0 ? - gettext("bitmap dirty") : gettext("bitmap clean")); - } - - if (print_bitmap) { - name = strrchr(master_volume, '/'); - if (name++ == NULL) - name = master_volume; - i = bm_size * 8; - x = (int)ceil(sqrt((double)i)); - x += (8 - (x % 8)); /* round up to nearest multiple of 8 */ - y = i / x; - if (y * x < i) - y++; - (void) printf("#define bm%s_width %d\n#define bm%s_height %d\n", - name, x, name, y); - (void) printf("#define bm%s_x_hot 0\n#define bm%s_y_hot 0\n", - name, name); - (void) printf("static char bm%s_bits[] = {\n", name); - for (i = 0; i < bm_size; i++) { - if (i % 12 == 0) - (void) printf("\n"); - (void) printf("0x%02x, ", bitmap[i]); - } - y = x * y; - for (; i < y; i++) { - if (i % 12 == 0) - (void) printf("\n"); - (void) printf("0x00, "); - } - (void) printf("\n};\n"); - } - - free_bitmap(bitmap); -} - -static int -validate_group_names(char **vol_list, char *group) -{ - ENTRY item, *found; - int i, rc, count; - dsw_aioctl_t *group_list; - char *ptr; - - if (group == NULL || *group == NULL) { - /* no group set, just count volume list */ - for (i = 0; *vol_list++ != NULL; i++) - ; - return (i); - } - - if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0) - dsw_error("DSWIOC_LISTLEN", NULL); - - group_list = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN); - if (group_list == NULL) - dsw_error(gettext("Failed to allocate memory"), NULL); - - bzero(group_list, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN); - group_list->count = count; - group_list->flags = 0; - group_list->status = spcs_s_ucreate(); - (void) strncpy(group_list->shadow_vol, group, DSW_NAMELEN); - - rc = do_ioctl(dsw_fd, DSWIOC_GLIST, group_list); - if (rc < 0) - dsw_error(gettext("Group list access failure"), - &group_list->status); - - group_list->shadow_vol[DSW_NAMELEN * group_list->count] = '\0'; - - /* create hash and enter all volumes into it */ - if (hcreate(group_list->count) == 0) - dsw_error(gettext("Failed to allocate memory"), NULL); - ptr = group_list->shadow_vol; - count = group_list->count; - i = 0; - while (i < count) { - ptr[ DSW_NAMELEN - 1 ] = '\0'; - item.key = ptr; - item.data = (void *) 0; - (void) hsearch(item, ENTER); - ++i; - ptr += DSW_NAMELEN; - } - - /* now compare the volume list with the hash */ - for (i = 0; vol_list[ i ]; i++) { - item.key = vol_list[ i ]; - found = hsearch(item, FIND); - if (!found) - dsw_error(gettext("Group config does not match kernel"), - NULL); - if (found->data != (void *) 0) - dsw_error(gettext("Duplicate volume specified"), NULL); - found->data = (void *) 1; - } - if (i != count) - dsw_error(gettext("Group config does not match kernel"), NULL); - - /* everything checks out */ - free(group_list); - hdestroy(); - - return (count); -} - -int -do_acopy(char **vol_list, enum copy_update update_mode, - enum copy_direction direction) -{ - dsw_aioctl_t *acopy_args; - dsw_ioctl_t copy_args; - dsw_config_t parms; - dsw_stat_t stat_s; - int i; - int rc; - int n_vols; - char *t; - char buf[1024]; - char *sp; - char *ppid; - - n_vols = validate_group_names(vol_list, group_name); - - acopy_args = calloc(sizeof (dsw_aioctl_t) + n_vols * DSW_NAMELEN, 1); - if (acopy_args == NULL) - dsw_error(gettext("Too many volumes given for update"), NULL); - - acopy_args->count = n_vols; - - acopy_args->flags = 0; - - if (update_mode == Update) - acopy_args->flags |= CV_BMP_ONLY; - if (direction == ToMaster) - acopy_args->flags |= CV_SHD2MST; - if (pflg) { - acopy_args->flags |= CV_LOCK_PID; -#ifdef DEBUG - ppid = getenv("IIADM_PPID"); - if (ppid) { - acopy_args->pid = atoi(ppid); - (void) fprintf(stderr, "(using %s for ppid)\n", ppid); - } else { - acopy_args->pid = getppid(); - } -#else - acopy_args->pid = getppid(); -#endif - } - - for (i = 0; i < n_vols; i++) { - if (!find_shadow_config(vol_list[i], &parms, ©_args)) - dsw_error(gettext("Volume is not in a Point-in-Time " - "group"), NULL); - if (direction == ToMaster) { - t = parms.master_vol; - } else { - t = parms.shadow_vol; - } - - if (mounted(t)) { - errno = EBUSY; - dsw_error(gettext("Target of copy/update is mounted, " - "unmount it first"), NULL); - } - - (void) strlcpy(stat_s.shadow_vol, parms.shadow_vol, - DSW_NAMELEN); - stat_s.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s); - spcs_s_ufree(&stat_s.status); - if (rc == -1) { - (void) sprintf(buf, - gettext("Shadow group %s is suspended"), - vol_list[i]); - dsw_error(buf, NULL); - } - - if (stat_s.stat & DSW_COPYINGP) { - (void) fprintf(stderr, "%s: %s\n", cmdnam, - gettext("Copy already in progress")); - exit(1); - } - } - acopy_args->status = spcs_s_ucreate(); - for (i = 0; i < n_vols; i++) { - spcs_log("ii", NULL, gettext("Atomic %s %s %s"), - update_mode == Update ? gettext("update") : gettext("copy"), - vol_list[i], - direction == ToMaster ? gettext("from shadow") : - gettext("to shadow")); - } - if (group_name == NULL || *group_name == NULL) { - sp = acopy_args->shadow_vol; - for (i = 0; i < n_vols; i++, sp += DSW_NAMELEN) - (void) strncpy(sp, vol_list[i], DSW_NAMELEN); - } else { - (void) strncpy(acopy_args->shadow_vol, group_name, DSW_NAMELEN); - acopy_args->flags |= CV_IS_GROUP; - } - rc = do_ioctl(dsw_fd, DSWIOC_ACOPY, acopy_args); - if (rc == -1) { - i = acopy_args->count; - if (i < 0 || i >= n_vols) { - spcs_log("ii", NULL, gettext("Atomic update failed")); - (void) sprintf(buf, gettext("Update failed")); - } else { - spcs_log("ii", NULL, - gettext("Atomic update of %s failed"), - vol_list[acopy_args->count]); - (void) sprintf(buf, gettext("Update of %s failed"), - vol_list[acopy_args->count]); - } - dsw_error(buf, &(acopy_args->status)); - } - return (rc); -} - -int -do_copy(char **vol_list, enum copy_update update_mode, - enum copy_direction direction, enum copy_wait wait_action) -{ - dsw_ioctl_t copy_args; - dsw_config_t parms; - dsw_stat_t stat_s; - int rc; - int wait_loc; - char *t; - char *volume; - pid_t child = (pid_t)0; - char *ppid; - - if (vol_list[0] && vol_list[1]) - return (do_acopy(vol_list, update_mode, direction)); - - volume = vol_list[0]; - if (!find_shadow_config(volume, &parms, ©_args)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - - cfg_unlock(cfg); - config_locked = 0; - copy_args.flags = 0; - - if (update_mode == Update) - copy_args.flags |= CV_BMP_ONLY; - if (direction == ToMaster) { - copy_args.flags |= CV_SHD2MST; - t = parms.master_vol; - } else { - t = parms.shadow_vol; - } - if (pflg) { - copy_args.flags |= CV_LOCK_PID; -#ifdef DEBUG - ppid = getenv("IIADM_PPID"); - if (ppid) { - copy_args.pid = atoi(ppid); - (void) fprintf(stderr, "(using %s for ppid)\n", ppid); - } else { - copy_args.pid = getppid(); - } -#else - copy_args.pid = getppid(); -#endif - } - - if (mounted(t)) { - errno = EBUSY; - dsw_error(gettext("Target of copy/update is mounted, " - "unmount it first"), NULL); - } - - (void) strlcpy(stat_s.shadow_vol, copy_args.shadow_vol, DSW_NAMELEN); - stat_s.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_STAT, &stat_s); - spcs_s_ufree(&stat_s.status); - if (rc == -1) - dsw_error(gettext("Shadow group suspended"), NULL); - - if (stat_s.stat & DSW_COPYINGP) { - (void) fprintf(stderr, "%s: %s\n", cmdnam, - gettext("Copy already in progress")); - exit(1); - } - - copy_args.status = spcs_s_ucreate(); - spcs_log("ii", NULL, gettext("Start %s %s %s"), - update_mode == Update ? gettext("update") : gettext("copy"), - volume, - direction == ToMaster ? gettext("from shadow") : - gettext("to shadow")); - - if (wait_action == WaitForStart) - (void) sigset(SIGCHLD, sigchild); - switch (child = fork()) { - - case (pid_t)-1: - dsw_error(gettext("Unable to fork"), - NULL); - break; - - case 0: - rc = do_ioctl(dsw_fd, DSWIOC_COPY, ©_args); - if (rc == -1) { - spcs_log("ii", ©_args.status, - gettext("Fail %s %s %s"), - update_mode == Update ? - gettext("update") : gettext("copy"), - volume, - direction == ToMaster ? - gettext("from shadow") : gettext("to shadow")); - dsw_error(gettext("Copy failed"), ©_args.status); - } - spcs_s_ufree(©_args.status); - spcs_log("ii", NULL, gettext("Finish %s %s %s"), - update_mode == Update ? gettext("update") : gettext("copy"), - volume, - direction == ToMaster ? gettext("from shadow") : - gettext("to shadow")); - - exit(0); - break; - default: - if (wait_action == WaitForStart) { - rc = child_wait(child, CopyStart, copy_args.shadow_vol); - } else { /* wait_action == WaitForEnd */ - wait_loc = 0; - (void) wait(&wait_loc); - if (WIFEXITED(wait_loc) && (WEXITSTATUS(wait_loc) == 0)) - rc = 0; - else - rc = 1; - } - break; - } - return (rc); -} - -void -print_status(dsw_config_t *conf, int in_config) -{ - dsw_stat_t args; - int stat_flags; - static int need_sep = 0; - time_t tmp_time; - - if (need_sep++ > 0) - (void) printf("--------------------------------------" - "----------------------------------------\n"); - (void) strlcpy(args.shadow_vol, conf->shadow_vol, DSW_NAMELEN); - if (in_config) { - (void) printf("%s: %s\n", - conf->master_vol, gettext("(master volume)")); - (void) printf("%s: %s\n", - conf->shadow_vol, gettext("(shadow volume)")); - (void) printf("%s: %s\n", - conf->bitmap_vol, gettext("(bitmap volume)")); - } - - /* - * Do special checking on the status of this volume in a Sun Cluster - */ - if (check_cluster() == II_CLUSTER) { - char dgname[CFG_MAX_BUF], *other_node; - - if (cfg_dgname(conf->bitmap_vol, dgname, sizeof (dgname))) { - if (strlen(dgname)) { - int rc = cfg_dgname_islocal(dgname, - &other_node); - - if (rc < 0) { - (void) printf(gettext( - "Suspended on this node, " - "not active elsewhere\n")); - return; - } else if (rc == 0) { - (void) printf(gettext( - "Suspended on this node, " - "active on %s\n"), other_node); - return; - } - } - } - } - - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) { - - /* Handle Not found or not in config */ - if (errno != DSW_ENOTFOUND || !in_config) - dsw_error(gettext("Stat failed"), &args.status); - - /* Just suspend */ - (void) printf(gettext("Suspended.\n")); - return; - } - - if (args.overflow_vol[0] != '\0') - (void) printf("%s: %s\n", args.overflow_vol, - gettext("(overflow volume)")); - - if (conf->group_name[0] != '\0') - (void) printf(gettext("Group name: %s\n"), - conf->group_name); - - if (conf->cluster_tag[0] != '\0') - (void) printf(gettext("Cluster tag: %s\n"), - conf->cluster_tag); - - stat_flags = args.stat; - spcs_s_ufree(&args.status); - if (stat_flags & DSW_GOLDEN) - (void) printf(gettext("Independent copy")); - else - (void) printf(gettext("Dependent copy")); - - if (stat_flags & DSW_TREEMAP) - (void) printf(gettext(", compacted shadow space")); - - if (stat_flags & DSW_COPYINGP) - (void) printf(gettext(", copy in progress")); - else if (stat_flags & DSW_COPYING) - (void) printf(gettext(", copy not active")); - - if (stat_flags & DSW_COPYINGM) - (void) printf(gettext(", copying master to shadow")); - - if (stat_flags & DSW_COPYINGS) - (void) printf(gettext(", copying shadow to master")); - - if (stat_flags & DSW_COPYINGX) - (void) printf(gettext(", abort of copy requested")); - - if (stat_flags & DSW_MSTOFFLINE) - (void) printf(gettext(", master volume offline")); - - if (stat_flags & DSW_SHDOFFLINE) - (void) printf(gettext(", shadow volume offline")); - - if (stat_flags & DSW_BMPOFFLINE) - (void) printf(gettext(", bitmap volume offline")); - - if (stat_flags & DSW_OVROFFLINE) - (void) printf(gettext(", overflow volume offline")); - - if (stat_flags & DSW_SHDEXPORT) - (void) printf(gettext(", shadow volume exported")); - - if (stat_flags & DSW_SHDIMPORT) - (void) printf(gettext(", shadow volume imported")); - - if (stat_flags & DSW_OVERFLOW) - (void) printf(gettext(", out of space")); - - if (stat_flags & DSW_VOVERFLOW) - (void) printf(gettext(", spilled into overflow volume")); - (void) printf("\n"); - - tmp_time = args.mtime; - if (tmp_time != 0) - (void) printf("%s %s", gettext("Latest modified time:"), - ctime(&tmp_time)); - else - (void) printf("%s\n", gettext("Latest modified time: unknown")); - - (void) printf("%s %8llu\n", gettext("Volume size:"), args.size); - if (args.shdsize != 0) { - (void) printf("%s %lld %s %lld\n", - gettext("Shadow chunks total:"), args.shdsize, - gettext("Shadow chunks used:"), args.shdused); - } - bitmap_op(args.shadow_vol, 0, 1, 0, 0); -} - -int -abort_copy(char *volume) -{ - dsw_ioctl_t args; - - if (!find_shadow_config(volume, NULL, &args)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_ABORT, &args) == -1) - dsw_error(gettext("Abort failed"), &args.status); - spcs_log("ii", NULL, gettext("Abort %s"), args.shadow_vol); - spcs_s_ufree(&args.status); - return (0); -} - -void -iiversion() -{ - dsw_version_t args; - - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_VERSION, &args) == -1) - dsw_error(gettext("Version failed"), &args.status); - spcs_s_ufree(&args.status); -#ifdef DEBUG - (void) printf(gettext("Point in Time Copy version %d.%d.%d.%d\n"), - args.major, args.minor, args.micro, args.baseline); -#else - if (args.micro) { - (void) printf(gettext("Point in Time Copy version %d.%d.%d\n"), - args.major, args.minor, args.micro); - } else { - (void) printf(gettext("Point in Time Copy version %d.%d\n"), - args.major, args.minor); - } -#endif -} - -void -list_volumes() -{ - dsw_list_t args; - int i, set, found; - dsw_config_t *lp; - ENTRY item, *ip; - dsw_config_t parms; - - if ((i = do_ioctl(dsw_fd, DSWIOC_LISTLEN, &args)) == -1) - dsw_error("DSWIOC_LISTLEN", NULL); - - args.status = spcs_s_ucreate(); - args.list_used = 0; - args.list_size = i + 4; - lp = args.list = (dsw_config_t *) - malloc(args.list_size * sizeof (dsw_config_t)); - - if (args.list == NULL) - dsw_error(gettext("Failed to allocate memory"), NULL); - if (do_ioctl(dsw_fd, DSWIOC_LIST, &args) == -1) - dsw_error(gettext("List failed"), &args.status); - spcs_s_ufree(&args.status); - - /* make a hashtable */ - if (args.list_used > 0) { - if (hcreate(args.list_used) == 0) { - dsw_error(gettext("Failed to allocate memory"), NULL); - /*NOTREACHED*/ - } - } - - /* populate the hashtable */ - for (i = 0; i < args.list_used; i++, lp++) { - item.key = lp->shadow_vol; - item.data = (char *)lp; - if (hsearch(item, ENTER) == NULL) { - dsw_error(gettext("Failed to allocate memory"), NULL); - /*NOTREACHED*/ - } - } - - /* perform action for each line of the stored config file */ - for (set = 1; get_dsw_config(set, &parms) == 0; set++) { - - /* Are there any II sets configured on this node? */ - if (args.list_used > 0) { - item.key = parms.shadow_vol; - - /* Is this volume configured on this node? */ - if (ip = hsearch(item, FIND)) { - - /* Handle Imported Shadows */ - /* LINTED alignment of cast ok */ - lp = (dsw_config_t *)ip->data; - if (strcmp(parms.master_vol, - II_IMPORTED_SHADOW)) - found = !(lp->flag & DSW_SHDIMPORT); - else - found = (lp->flag & DSW_SHDIMPORT); - } - else - found = FALSE; - } - else - found = FALSE; - - if ((cfg_cluster_tag) && - strcmp(cfg_cluster_tag, parms.cluster_tag)) - continue; - - if ((group_name) && strcmp(group_name, parms.group_name)) - continue; - - (void) printf("%s %.*s %.*s %.*s%s\n", - (parms.flag & DSW_GOLDEN) ? "ind" : "dep", - DSW_NAMELEN, parms.master_vol, - DSW_NAMELEN, parms.shadow_vol, - DSW_NAMELEN, parms.bitmap_vol, - found ? "" : gettext(" (suspended)")); - } - hdestroy(); - free(args.list); -} - -int -wait_for_copy(char *volume) -{ - dsw_ioctl_t parms; - int rc; - static int unlocked = 0; - char *ppid; - - if (unlocked && !ii_lock(cfg, CFG_RDLOCK)) { - dsw_error(gettext("Unable to set locking on the configuration"), - NULL); - } - config_locked = 1; - if (!find_shadow_config(volume, NULL, &parms)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - cfg_unlock(cfg); - config_locked = 0; - unlocked = 1; - - parms.status = spcs_s_ucreate(); - if (pflg) { -#ifdef DEBUG - ppid = getenv("IIADM_PPID"); - if (ppid) { - parms.pid = atoi(ppid); - (void) fprintf(stderr, "(using %s for ppid)\n", ppid); - } else { - parms.pid = (nflg) ? -1 : getppid(); - } -#else - parms.pid = (nflg) ? -1 : getppid(); -#endif - parms.flags |= CV_LOCK_PID; - } - - rc = do_ioctl(dsw_fd, DSWIOC_WAIT, &parms); - if (rc == -1) - dsw_error(gettext("Wait failed"), &parms.status); - spcs_s_ufree(&parms.status); - return (0); -} - -int -export(char *volume) -{ - dsw_ioctl_t parms; - dsw_config_t conf; - char *old_ctag, dgname[DSW_NAMELEN]; - int rc; - - if (!find_shadow_config(volume, &conf, &parms)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - if (mounted(volume)) - dsw_error(gettext("Can't export a mounted volume"), NULL); - - /* If this is an exportable shadow in the cluster, change ctag */ - if (strlen(conf.cluster_tag) && - (cfg_dgname(volume, dgname, sizeof (dgname)))) { - old_ctag = cfg_cluster_tag; - cfg_resource(cfg, cfg_cluster_tag = strdup(dgname)); - } else old_ctag = NULL; - - if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - reload_vols = LD_DSVOLS | LD_SHADOWS; - conform_name(&volume); - - spcs_log("ii", NULL, gettext("Export %s"), volume); - parms.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_EXPORT, &parms); - if (rc == -1) - dsw_error(gettext("Export failed"), &parms.status); - if (perform_autosv()) { - if (cfg_vol_disable(cfg, volume, cfg_cluster_tag, "ii") < 0) { - dsw_error(gettext("SV-disable failed"), NULL); - } - (void) cfg_commit(cfg); - } - - /* restore old cluster tag, if changed */ - if (old_ctag != NULL) - cfg_resource(cfg, cfg_cluster_tag = old_ctag); - - spcs_s_ufree(&parms.status); - return (0); -} - -int -detach(char *volume) -{ - dsw_ioctl_t parms; - int rc; - - if (!find_shadow_config(volume, NULL, &parms)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - parms.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_ODETACH, &parms); - if (rc == 0) { - /* remove overflow from cfg line */ - (void) sprintf(key, "ii.set%d.overflow", setnumber); - if (cfg_put_cstring(cfg, key, "-", 1) < 0) { - perror("cfg_put_cstring"); - } - (void) cfg_commit(cfg); - } else { - spcs_log("ii", NULL, gettext("Detach of overflow %s failed"), - parms.shadow_vol); - dsw_error(gettext("Failed to detach overflow volume"), - &parms.status); - } - return (rc); -} - -static void -can_disable(char *vol) -{ - dsw_stat_t args; - - if (mounted(vol)) { - (void) strlcpy(args.shadow_vol, vol, DSW_NAMELEN); - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) != -1 && - (args.stat & DSW_GOLDEN) == 0) { - errno = EBUSY; - dsw_error(gettext("Shadow Volume is currently mounted " - "and dependent on the master volume"), NULL); - } - spcs_s_ufree(&args.status); - } -} - -static void -clean_up_after_failed_disable(dsw_ioctl_t *parms) -{ - char **p; - dsw_stat_t args; - - for (p = group_volumes; *p; p++) { - (void) strlcpy(args.shadow_vol, *p, DSW_NAMELEN); - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) { - /* set was successfully disabled */ - if (find_shadow_config(*p, NULL, NULL)) - remove_iiset(setnumber, *p, 0); - } - spcs_s_ufree(&args.status); - } - - dsw_error(gettext("Some sets in the group failed to disable"), - &parms->status); -} - -int -dsw_group_or_single_disable(int argc, char *argv[]) -{ - int rc = 0; - char **p; - dsw_ioctl_t parms; - int flags = 0; - dsw_config_t conf; - int shd_exported = 0; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - if (group_name) { - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - for (p = group_volumes; *p; p++) { - can_disable(*p); - } - - (void) strncpy(parms.shadow_vol, group_name, DSW_NAMELEN); - if (*group_name) - flags = CV_IS_GROUP; - } else { - if (!find_shadow_config(argv[1], &conf, &parms)) { - dsw_error(gettext("Volume is not in a Point-in-Time " - "Copy group"), NULL); - } - - can_disable(argv[1]); - flags = 0; - } - - if (group_name && !*group_name) { - /* user typed iiadm -g "" -d */ - for (p = group_volumes; *p; p++) { - parms.status = spcs_s_ucreate(); - parms.flags = flags; - (void) strncpy(parms.shadow_vol, *p, DSW_NAMELEN); - rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms); - if (rc == -1 && errno != DSW_ENOTFOUND) - dsw_error(gettext("Disable failed"), - &parms.status); - if (!find_shadow_config(*p, NULL, NULL)) - dsw_error(gettext("Volume is not in a Point-in" - "-Time Copy group"), &parms.status); - remove_iiset(setnumber, *p, 0); - spcs_s_ufree(&parms.status); - spcs_log("ii", NULL, gettext("Disabled %s"), - parms.shadow_vol); - } - } else { - if (is_exported(conf.shadow_vol)) { - shd_exported = 1; - } - if ((strcmp(conf.master_vol, II_IMPORTED_SHADOW) == 0) && - is_exported(conf.shadow_vol)) { - dsw_error(gettext( - "Imported shadow not disabled"), NULL); - } - - parms.status = spcs_s_ucreate(); - parms.flags = flags; - rc = do_ioctl(dsw_fd, DSWIOC_DISABLE, &parms); - if (rc == -1 && errno != DSW_ENOTFOUND) { - if (errno == DSW_EDISABLE) { - /* - * one or more sets within the group - * couldn't disable - */ - clean_up_after_failed_disable(&parms); - } else { - dsw_error(gettext("Disable failed"), - &parms.status); - } - } - spcs_log("ii", NULL, gettext("Disabled %s"), parms.shadow_vol); - } - - - if (group_name && *group_name) { - for (p = group_volumes; *p; p++) { - if (!find_shadow_config(*p, NULL, NULL)) { - /* argh! */ - (void) fprintf(stderr, - gettext("Volume '%s' is not " - "in a Point-in-Time Copy group"), *p); - } else { - remove_iiset(setnumber, *p, 0); - } - } - } else if (!group_name) { - if (!find_shadow_config(argv[1], NULL, NULL)) { - /* argh! */ - dsw_error(gettext("Volume is not in a Point-in-Time " - "Copy group"), NULL); - } - - remove_iiset(setnumber, argv[1], shd_exported); - } - - return (0); -} - -int -dsw_group_or_single_op(int argc, char *argv[], int (*op)(char *)) -{ - int rc = 0; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - if (group_name) { - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - for (; *group_volumes; group_volumes++) - rc |= (*op)(*group_volumes); - } else { - rc = (*op)(argv[1]); - } - return (rc); -} - -void -dsw_list_clusters(char *cluster) -{ - dsw_aioctl_t *acopy_args; - int rc, i, count; - char *ptr; - - if ((count = do_ioctl(dsw_fd, DSWIOC_LISTLEN, NULL)) < 0) - dsw_error("DSWIOC_LISTLEN", NULL); - - acopy_args = malloc(sizeof (dsw_aioctl_t) + count * DSW_NAMELEN); - if (acopy_args == NULL) - dsw_error(gettext("Can't get memory for list enquiry"), NULL); - - bzero(acopy_args, sizeof (dsw_aioctl_t) + count * DSW_NAMELEN); - acopy_args->count = count; - acopy_args->flags = 0; - acopy_args->status = spcs_s_ucreate(); - if (cluster) - (void) strncpy(acopy_args->shadow_vol, cluster, DSW_NAMELEN); - - rc = do_ioctl(dsw_fd, DSWIOC_CLIST, acopy_args); - if (rc == -1) - dsw_error(gettext("Cluster list access failure"), - &acopy_args->status); - - acopy_args->shadow_vol[DSW_NAMELEN*acopy_args->count] = NULL; - - if (cluster) { - (void) printf(gettext("Sets in cluster resource group %s:\n"), - cluster); - } else { - (void) printf( - gettext("Currently configured resource groups\n")); - } - for (i = 0, ptr = acopy_args->shadow_vol; *ptr && - i < acopy_args->count; i++, ptr += DSW_NAMELEN) { - (void) printf(" %-64.64s\n", ptr); - } -} - -void -dsw_enable(int argc, char *argv[]) -{ - if (argc != 5) - usage(gettext("Incorrect number of arguments")); - - enable(argv[1], argv[2], argv[3], argv[4]); - exit(0); -} - - -void -dsw_disable(int argc, char *argv[]) -{ - (void) dsw_group_or_single_disable(argc, argv); - exit(0); -} - - -void -dsw_copy_to_shadow(int argc, char *argv[]) -{ - char **volume_list; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - if (group_name == NULL) - volume_list = ++argv; - else { - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - volume_list = group_volumes; - } - - exit(do_copy(volume_list, Copy, ToShadow, WaitForStart)); -} - - -void -dsw_update_shadow(int argc, char *argv[]) -{ - char **volume_list; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - if (group_name == NULL) - volume_list = ++argv; - else { - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - volume_list = group_volumes; - } - - exit(do_copy(volume_list, Update, ToShadow, WaitForStart)); -} - - -void -dsw_copy_to_master(int argc, char *argv[]) -{ - char **volume_list; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - if (group_name == NULL) { - volume_list = ++argv; - check_action(gettext("Overwrite master with shadow volume?")); - } else { - check_action(gettext("Overwrite every" - " master in this group with its shadow volume?")); - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - volume_list = group_volumes; - } - - exit(do_copy(volume_list, Copy, ToMaster, WaitForStart)); -} - - -void -dsw_update_master(int argc, char *argv[]) -{ - char **volume_list; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - if (group_name == NULL) { - volume_list = ++argv; - check_action(gettext("Overwrite master with shadow volume?")); - } else { - check_action(gettext("Overwrite every" - " master in this group with its shadow volume?")); - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - volume_list = group_volumes; - } - - exit(do_copy(volume_list, Update, ToMaster, WaitForStart)); -} - - -void -dsw_abort_copy(int argc, char *argv[]) -{ - exit(dsw_group_or_single_op(argc, argv, abort_copy)); -} - - -void -dsw_display_status(int argc, char *argv[]) -{ - dsw_config_t parms; - int in_config; - - if (argc != 2 && argc != 1) - usage(gettext("Incorrect number of arguments")); - - /* "iiadm -i" and "iiadm -i all" are equivalent */ - if (argc == 2 && strcmp("all", argv[1]) != 0) { - in_config = find_shadow_config(argv[1], &parms, NULL); - if (!in_config) { - (void) printf(gettext( - "Volume is not in configuration file\n"), NULL); - (void) fflush(stdout); - (void) strlcpy(parms.shadow_vol, argv[1], DSW_NAMELEN); - } - print_status(&parms, in_config); - } else if (group_name) { - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or " - "has no members"), NULL); - for (; *group_volumes; group_volumes++) { - in_config = find_shadow_config(*group_volumes, - &parms, NULL); - if (in_config) - print_status(&parms, in_config); - } - } else { - /* perform action for each line of the stored config file */ - for (setnumber = 1; - !get_dsw_config(setnumber, &parms); setnumber++) { - switch (check_cluster()) { - case II_CLUSTER: - if ((cfg_cluster_tag) && - (strcmp(cfg_cluster_tag, - parms.cluster_tag))) - continue; - break; - case II_CLUSTER_LCL: - if (strlen(parms.cluster_tag)) - continue; - break; - } - print_status(&parms, 1); - } - } - exit(0); -} - -void -dsw_display_bitmap(int argc, char *argv[]) -{ - dsw_config_t parms; - int in_config; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - in_config = find_shadow_config(argv[1], &parms, NULL); - if (!in_config) { - (void) printf(gettext( - "Volume is not in configuration file\n"), NULL); - (void) fflush(stdout); - (void) strlcpy(parms.master_vol, argv[1], DSW_NAMELEN); - } - - bitmap_op(parms.shadow_vol, 1, 0, 0, 0); - exit(0); -} - - -/*ARGSUSED*/ -void -dsw_version(int argc, char *argv[]) -{ - iiversion(); - exit(0); -} - -void -dsw_reset(int argc, char *argv[]) -{ - exit(dsw_group_or_single_op(argc, argv, reset)); -} - -void -dsw_overflow(int argc, char *argv[]) -{ - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - exit(overflow(argv[1])); -} - -void -dsw_wait(int argc, char *argv[]) -{ - exit(dsw_group_or_single_op(argc, argv, wait_for_copy)); -} - -/*ARGSUSED*/ -void -dsw_list_volumes(int argc, char *argv[]) -{ - if (argc != 1) - usage(gettext("Incorrect number of arguments")); - - list_volumes(); - exit(0); -} - -void -dsw_export(int argc, char *argv[]) -{ - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - exit(dsw_group_or_single_op(argc, argv, export)); -} - -void -dsw_detach(int argc, char *argv[]) -{ - (void) dsw_group_or_single_op(argc, argv, detach); - exit(0); -} - -void -import(char *shadow_volume, char *bitmap_volume) -{ - dsw_config_t parms = {0}; - int rc = 0; - char shd_dg[DSW_NAMELEN]; - char bmp_dg[DSW_NAMELEN]; - - /* - * If importing a shadow volume and the shadow volume is already - * configured, we only support this if we are in a Sun Cluster - * and the current user specified a cluster tag of -C local - */ - if (find_shadow_config(shadow_volume, &parms, NULL)) { - dsw_error(gettext("Can't import volume on same node"), NULL); - } - - switch (check_cluster()) { - case II_CLUSTER: - case II_CLUSTER_LCL: - (void) check_resource_group(shadow_volume); - if (cfg_cluster_tag) { /* check all volumes are in same dg */ - if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN) - == NULL) - dsw_error(gettext("Shadow volume not in a" - " disk group"), NULL); - if (cfg_dgname(bitmap_volume, bmp_dg, DSW_NAMELEN) - == NULL) - dsw_error(gettext("Bitmap volume not in a" - " disk group"), NULL); - if (strcmp(bmp_dg, shd_dg) != 0) - dsw_error(gettext("Bitmap volume not in" - " same disk group as shadow set members"), - NULL); - } - break; - case II_NOT_CLUSTER: - /* do nothing */ - break; - default: - dsw_error(gettext( - "Unexpected return from check_cluster()"), NULL); - } - - /* Local configuration volumes */ - if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - - reload_vols = LD_DSVOLS | LD_SHADOWS; - conform_name(&shadow_volume); - (void) strcpy(parms.master_vol, II_IMPORTED_SHADOW); - (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN); - (void) strlcpy(parms.bitmap_vol, bitmap_volume, DSW_NAMELEN); - parms.flag = DSW_GOLDEN; - - spcs_log("ii", NULL, gettext("Import %s %s"), - parms.shadow_vol, parms.bitmap_vol); - parms.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_IMPORT, &parms); - if (rc == -1) { - spcs_log("ii", NULL, gettext("Import failed %s %s"), - parms.shadow_vol, parms.bitmap_vol); - dsw_error(gettext("Import failed"), &parms.status); - } - if (perform_autosv()) { - if (cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii") - < 0) { - dsw_error(gettext("SV-enable failed"), NULL); - } - /* cfg_commit is called by add_cfg_entry below */ - } - spcs_s_ufree(&parms.status); - add_cfg_entry(&parms); -} - -void -dsw_import(int argc, char *argv[]) -{ - if (argc != 3) - usage(gettext("Incorrect number of arguments")); - import(argv[1], argv[2]); - - exit(0); -} - -void -join(char *shadow_volume, char *bitmap_file) -{ - dsw_ioctl_t shd; - dsw_config_t conf; - dsw_bitmap_t parms; - int rc = 0; - int size; - FILE *bmpfp; - uchar_t *shd_bitmap = 0; - ii_header_t header; - char dgname[DSW_NAMELEN]; - - if (!find_shadow_config(shadow_volume, &conf, &shd)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - - /* If this is an exportable shadow in the cluster, change ctag */ - if (strlen(conf.cluster_tag) && - (cfg_dgname(shadow_volume, dgname, sizeof (dgname)))) - cfg_resource(cfg, cfg_cluster_tag = strdup(dgname)); - - if (cfg_load_dsvols(cfg) < 0 || cfg_load_shadows(cfg) < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - reload_vols = LD_DSVOLS | LD_SHADOWS; - conform_name(&shadow_volume); - - if ((bmpfp = fopen(bitmap_file, "r")) == NULL) { - perror(bitmap_file); - (void) fprintf(stderr, - gettext("Can't open imported bitmap volume\n")); - exit(1); - } - - if (fread(&header, sizeof (header), 1, bmpfp) != 1) { - (void) fprintf(stderr, - gettext("Can't read imported bitmap volume\n")); - exit(1); - } - - /* See if this is a bitmap header */ - switch (header.ii_magic) { - case DSW_DIRTY: /* A copy of a enable bitmap volume */ - case DSW_CLEAN: - check_action(gettext("Use the never imported bitmap?")); - break; - case DSW_INVALID: /* A valid diskable secondary bitmap */ - break; - default: - (void) fprintf(stderr, - gettext("Secondary bitmap is not a valid bitmap volume\n")); - exit(1); - } - - size = FBA_SIZE(header.ii_copyfba - header.ii_shdfba); - if ((shd_bitmap = malloc(size)) == NULL) { - perror("malloc"); - exit(1); - } - - if (fseek(bmpfp, FBA_SIZE(header.ii_shdfba), SEEK_SET)) { - perror("fseek"); - exit(1); - } - - if (fread(shd_bitmap, 1, size, bmpfp) != size) { - (void) fprintf(stderr, - gettext("Can't read imported bitmap volume\n")); - exit(1); - } - - (void) fclose(bmpfp); - - (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN); - parms.shd_bitmap = shd_bitmap; - parms.shd_size = size; - parms.copy_bitmap = NULL; - parms.copy_size = 0; - - spcs_log("ii", NULL, gettext("Join %s %s"), - parms.shadow_vol, bitmap_file); - parms.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_JOIN, &parms); - if (rc == -1) { - spcs_log("ii", NULL, gettext("Join failed %s %s"), - parms.shadow_vol, bitmap_file); - dsw_error(gettext("Join failed"), &parms.status); - } - if (perform_autosv()) { - rc = cfg_vol_enable(cfg, shadow_volume, cfg_cluster_tag, "ii"); - if (rc < 0) { - dsw_error(gettext("SV-enable failed"), NULL); - } - (void) cfg_commit(cfg); - } - spcs_s_ufree(&parms.status); -} - -int -params(char *shadow_volume) -{ - char *delay = param_delay; - char *unit = param_unit; - dsw_copyp_t parms; - int rc = 0; - int get = 0; - int new_delay; - int new_unit; - - (void) strlcpy(parms.shadow_vol, shadow_volume, DSW_NAMELEN); - if (delay == NULL || unit == NULL) { - get = 1; - parms.copy_delay = -1; - parms.copy_unit = -1; - } else { - new_delay = parms.copy_delay = convert_int(delay); - new_unit = parms.copy_unit = convert_int(unit); - } - - parms.status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_COPYP, &parms); - if (rc == -1) { - (void) fprintf(stderr, - gettext("Parameter ranges are delay(%d - %d), " - "units(%d - %d)\n"), MIN_THROTTLE_DELAY, MAX_THROTTLE_DELAY, - MIN_THROTTLE_UNIT, MAX_THROTTLE_UNIT); - dsw_error(gettext("Set Copy Parameters failed"), &parms.status); - } - if (!get) - spcs_log("ii", NULL, gettext("Changed copy parameters %s from " - "%d %d to %d %d"), parms.shadow_vol, parms.copy_delay, - parms.copy_unit, new_delay, new_unit); - else - (void) printf(gettext("volume: %s\ncopy delay: %d\ncopy unit:" - " %d\n"), parms.shadow_vol, parms.copy_delay, - parms.copy_unit); - spcs_s_ufree(&parms.status); - return (0); -} - -static void -do_attach(dsw_config_t *parms) -{ - dsw_config_t io; - int rc; - int check = 0; - - spcs_log("ii", NULL, gettext("Attach %s %s"), - parms->shadow_vol, parms->bitmap_vol); - parms->status = spcs_s_ucreate(); - rc = do_ioctl(dsw_fd, DSWIOC_OATTACH, parms); - if (rc == -1) { - check = 1; - /* if overflow() fails, it calls dsw_error to exit */ - (void) overflow(parms->bitmap_vol); - } - spcs_s_ufree(&parms->status); - if (check == 1) { - if (!find_shadow_config(parms->shadow_vol, &io, NULL)) - dsw_error( - gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - (void) strlcpy(io.bitmap_vol, parms->bitmap_vol, DSW_NAMELEN); - io.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_OATTACH, &io) == -1) { - spcs_log("ii", NULL, gettext("Attach failed %s %s"), - io.shadow_vol, parms->bitmap_vol); - dsw_error(gettext("Attach failed"), &io.status); - } - spcs_s_ufree(&io.status); - } -} - -int -attach(char *shadow_volume) -{ - dsw_config_t parms; - dsw_stat_t args; - char shd_dg[DSW_NAMELEN]; - char ovr_dg[DSW_NAMELEN]; - - switch (check_cluster()) { - case II_CLUSTER: - case II_CLUSTER_LCL: - (void) check_resource_group(shadow_volume); - if (cfg_cluster_tag) { /* check all volumes are in same dg */ - if (cfg_dgname(shadow_volume, shd_dg, DSW_NAMELEN) - == NULL) - dsw_error(gettext("Shadow volume not in a" - " disk group"), NULL); - if (cfg_dgname(overflow_file, ovr_dg, DSW_NAMELEN) - == NULL) - dsw_error(gettext("Overflow volume not in a" - " disk group"), NULL); - if (strcmp(ovr_dg, shd_dg) != 0) - dsw_error(gettext("Overflow volume not in" - " same disk group as shadow set members"), - NULL); - } - break; - case II_NOT_CLUSTER: - /* do nothing */ - break; - default: - dsw_error(gettext( - "Unexpected return from check_cluster()"), NULL); - } - - /* assure that the overflow_file is not an II volume */ - if (find_any_cf_line(overflow_file)) - dsw_error(gettext( - "Overflow volume is already in a Point-in-Time Copy " - "group"), NULL); - - /* use find_shadow_config() to find setnumber */ - if (!find_shadow_config(shadow_volume, &parms, NULL)) - dsw_error(gettext("Volume is not in a Point-in-Time Copy " - "group"), NULL); - - /* can only attach an overflow volume to dependent, compact shadow */ - (void) strlcpy(args.shadow_vol, shadow_volume, DSW_NAMELEN); - - args.status = spcs_s_ucreate(); - if ((do_ioctl(dsw_fd, DSWIOC_STAT, &args) == -1) || - !(args.stat & DSW_TREEMAP)) - dsw_error(gettext("Not a compact dependent shadow"), NULL); - - /* bitmap_vol is overloaded */ - (void) strlcpy(parms.bitmap_vol, overflow_file, DSW_NAMELEN); - - do_attach(&parms); - - /* add overflow to cfg line */ - (void) sprintf(key, "ii.set%d.overflow", setnumber); - if (cfg_put_cstring(cfg, key, overflow_file, - strlen(overflow_file)) < 0) { - perror("cfg_put_cstring"); - } - (void) cfg_commit(cfg); - return (0); -} - -void -dsw_join(int argc, char *argv[]) -{ - if (argc != 3) - usage(gettext("Incorrect number of arguments")); - - join(argv[1], argv[2]); - exit(0); -} - -void -dsw_params(int argc, char *argv[]) -{ - if (argc != 4 && argc != 2 && argc != 0) - usage(gettext("Incorrect number of arguments")); - - if ((argc == 4) || (argc == 2)) { - param_delay = argv[1]; - param_unit = argv[2]; - if (argc == 4) { - argv[1] = argv[3]; - argv[2] = NULL; - } - } - exit(dsw_group_or_single_op(2, argv, params)); -} - -/*ARGSUSED*/ -void -dsw_attach(int argc, char *argv[]) -{ - overflow_file = argv[1]; - argv[1] = argv[2]; - (void) dsw_group_or_single_op(2, argv, attach); - exit(0); -} - -/*ARGSUSED*/ -void -dsw_olist(int argc, char *argv[]) -{ - char *sp, *overflow_list, **vol; - int count, i; - ENTRY item, *found; - char key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ]; - - overflow_list = get_overflow_list(); - - /* count entries */ - count = 0; - for (sp = overflow_list; *sp; sp += DSW_NAMELEN) { - ++count; - } - - /* create hash (adding room for suspended overflow volumes) */ - if (hcreate(count + 1024) == 0) { - dsw_error(gettext("Out of memory creating lookup table"), NULL); - /*NOTREACHED*/ - } - - if (count > 0) { - /* create memory to store copy of list */ - vol = (char **)calloc(count, sizeof (char *)); - if (!vol) { - dsw_error( - gettext("Out of memory creating lookup table"), - NULL); - /*NOTREACHED*/ - } - - /* fill hash */ - for (i = 0, sp = overflow_list; *sp; sp += DSW_NAMELEN, i++) { - - /* make copy of string */ - vol[ i ] = (char *)malloc(DSW_NAMELEN + 1); - (void) strlcpy(vol[ i ], sp, DSW_NAMELEN); - - item.key = vol[ i ]; - item.data = (char *)0; - (void) hsearch(item, ENTER); - } - } - - /* loop through config file entries */ - i = 0; - cfg_rewind(cfg, CFG_SEC_CONF); - - /*CONSTCOND*/ - while (1) { - ++i; - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d.overflow", i); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - - /* has this set got an overflow volume? */ - if (!*buf) { - continue; - } - - /* look up overflow in hash */ - item.key = buf; - if (count > 0 && (found = hsearch(item, FIND)) != NULL) { - if (0 == (int)found->data) { - (void) printf("%s\n", buf); - found->data = (char *)1; - (void) hsearch(*found, ENTER); - } - } else { - /* must be part of a suspended set */ - (void) printf("%s (attached to suspended set)\n", buf); - item.key = buf; - item.data = (char *)1; - (void) hsearch(item, ENTER); - } - } - - exit(0); -} - -void -dsw_ostat(int argc, char *argv[]) -{ - dsw_ostat_t args; - int stat_flags; - - if (argc != 2) - usage(gettext("Incorrect number of arguments")); - - (void) strlcpy(args.overflow_vol, argv[1], DSW_NAMELEN); - - args.status = spcs_s_ucreate(); - if (do_ioctl(dsw_fd, DSWIOC_OSTAT2, &args) == -1) - dsw_error(gettext("Stat failed"), &args.status); - spcs_s_ufree(&args.status); - - if ((args.hversion >= 1) && (args.hmagic == II_OMAGIC)) { - stat_flags = args.flags; - if (stat_flags & IIO_CNTR_INVLD) - (void) printf(gettext("Clean shutdown of volume " - "sets associated with overflow volume " - "did not occur.\n" - "Overflow counters will be inconsistent " - "until new point-in-time(s) are taken.\n")); - } - (void) printf(gettext("Total number of attached shadows: %d\n"), - args.drefcnt); - (void) printf(gettext("Number of currently attached shadows: %d\n"), - args.crefcnt); - (void) printf(gettext("Total number of chunks: %lld\n"), args.nchunks); - (void) printf(gettext("Number of chunks ever allocated: %lld\n"), - args.used); - (void) printf(gettext("Number of used chunks: %lld\n"), - (args.nchunks - args.unused)); - (void) printf(gettext("Number of unused chunks: %lld\n"), args.unused); - exit(0); -} - -/*ARGSUSED*/ -void -dsw_move_2_group(int argc, char *argv[]) -{ - dsw_config_t parms; - dsw_movegrp_t movegrp; - grptag_t *gdata; - int waserr = 0; - - /* handle move to NULL group, or group of all spaces or tabs */ - (void) strncpy(movegrp.new_group, group_name, DSW_NAMELEN); - if ((strlen(group_name) == 0) || (strcspn(group_name, " \t") == 0)) { - group_name = "-"; - bzero(movegrp.new_group, DSW_NAMELEN); - gdata = NULL; - } else { - /* get the ctag for this group (if any) */ - gdata = (grptag_t *)nsc_lookup(volhash, group_name); - } - - movegrp.status = spcs_s_ucreate(); - - for (++argv; *argv; argv++) { - if (!find_shadow_config(*argv, &parms, NULL)) - dsw_error(gettext("Volume is not in a Point-in-Time " - "Copy group"), NULL); - - /* ensure the ctag matches the group */ - if (gdata && *gdata->ctag) { - if (strncmp(parms.cluster_tag, gdata->ctag, - DSW_NAMELEN) != 0) { - (void) fprintf(stderr, "%s: %s %s %s\n", cmdnam, - gettext("unable to move set"), *argv, - gettext("into new group - cluster " - "resource mismatch")); - waserr = 1; - continue; - } - } - - /* move the set in the kernel */ - (void) strncpy(movegrp.shadow_vol, parms.shadow_vol, - DSW_NAMELEN); - if (do_ioctl(dsw_fd, DSWIOC_MOVEGRP, &movegrp) < 0) - dsw_error(gettext("Failed to move group in kernel"), - NULL); - - /* now update the config */ - (void) sprintf(key, "ii.set%d.group", setnumber); - if (cfg_put_cstring(cfg, key, group_name, - strlen(group_name)) < 0) { - perror("cfg_put_cstring"); - } - (void) cfg_commit(cfg); - } - spcs_s_ufree(&movegrp.status); - cfg_close(cfg); - exit(waserr); -} - -void -dsw_list_groups() -{ - FILE *pfp; - - if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) { - dsw_error(gettext("Can't open sort program"), NULL); - } - - (void) fflush(stdout); - for (setnumber = 1; /*CSTYLED*/; setnumber++) { - (void) snprintf(key, sizeof (key), "ii.set%d.group", setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - /* skip if shadow set is not in any group */ - if (strcmp(buf, "") == 0) - continue; - (void) fprintf(pfp, "%s\n", buf); - } - (void) pclose(pfp); -} - -void -dsw_list_group_volumes() -{ - FILE *pfp; - - if (find_group_members(group_name) < 1) - dsw_error(gettext("Group does not exist or has no members"), - NULL); - - if ((pfp = popen("/usr/bin/sort -u", "w")) == NULL) { - dsw_error(gettext("Can't open sort program"), NULL); - } - - (void) fflush(stdout); - for (; *group_volumes; group_volumes++) - (void) fprintf(pfp, "%s\n", *group_volumes); - (void) pclose(pfp); -} - -static void -load_ii_vols(CFGFILE *cfg) -{ - int set, entries; - char *mst, *shd, *buf, **entry; - char *ctag, *group; - mstcount_t *mdata; - shdvol_t *sdata; - grptag_t *gdata; - static int whinged = 0; - - if (volhash) { - return; - } - - volhash = nsc_create_hash(); - cfg_rewind(cfg, CFG_SEC_CONF); - entries = cfg_get_section(cfg, &entry, "ii"); - for (set = 1; set <= entries; set++) { - buf = entry[set - 1]; - - /* grab master volume name */ - mst = strtok(buf, " "); - if (!mst) { - free(buf); - break; - } - - /* grab shadow, group & cnode fields */ - shd = strtok(NULL, " "); - (void) strtok(NULL, " "); /* bitmap */ - (void) strtok(NULL, " "); /* mode */ - (void) strtok(NULL, " "); /* overflow */ - ctag = strtok(NULL, " "); /* cnode */ - (void) strtok(NULL, " "); /* options */ - group = strtok(NULL, " "); /* group */ - - /* Fix optional tags */ - if (ctag) - ctag += strspn(ctag, "-"); - if (group) - group += strspn(group, "-"); - - /* 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; - } - - /* master volume, may be duplicates */ - mdata = (mstcount_t *)nsc_lookup(volhash, mst); - if (mdata) { - ++mdata->count; - } else { - mdata = (mstcount_t *)malloc(sizeof (mstcount_t)); - mdata->count = 1; - (void) nsc_insert_node(volhash, mdata, mst); - } - - /* grab shadow volume name */ - sdata = (shdvol_t *)malloc(sizeof (shdvol_t)); - (void) strncpy(sdata->master, mst, DSW_NAMELEN); - (void) nsc_insert_node(volhash, sdata, shd); - - /* No need to continue if no groups or ctags */ - if (!group || !*group || !ctag || !*ctag) { - free(buf); - continue; - } - - gdata = (grptag_t *)nsc_lookup(volhash, group); - if (gdata) { - /* group already exists - check ctag */ - if (*ctag && - (strncmp(ctag, gdata->ctag, DSW_NAMELEN) != 0)) { - if (!whinged) { - (void) printf(gettext( - "Warning: multiple " - "cluster resource groups " - "defined within a single " - "I/O group\n")); - whinged = 1; - } - } - } else { - gdata = (grptag_t *)malloc(sizeof (grptag_t)); - (void) strncpy(gdata->ctag, ctag, DSW_NAMELEN); - (void) nsc_insert_node(volhash, gdata, group); - } - - free(buf); - } - - /* free up any leftovers */ - while (set < entries) - free(entry[set++]); - if (entries) - free(entry); -} - -static void -unload_ii_vols() -{ - nsc_remove_all(volhash, free); - volhash = 0; -} - -static int -perform_autosv() -{ - static int result; - static int calculated = 0; - int rc; - -#ifdef DEBUG - if (getenv("II_SET_CLUSTER")) - return (1); -#endif - - if (calculated) { - return (result); - } - - /* - * we only perform auto-sv if we're in a sun cluster or if - * we're on a standalone system. I.e. we don't do auto-sv on Harry - */ - rc = check_cluster(); - - if (II_NOT_CLUSTER == rc) { - result = 1; - } else { - result = cfg_issuncluster(); - } - - calculated = 1; - return (result); -} - -/* - * Returns true if set has had the shadow volume exported. - * Returns false if shadow volume is not exported, or set is suspended. - */ -static int -is_exported(char *set) -{ - dsw_stat_t args; - int rc; - - (void) strlcpy(args.shadow_vol, set, DSW_NAMELEN); - args.status = spcs_s_ucreate(); - - rc = do_ioctl(dsw_fd, DSWIOC_STAT, &args); - spcs_s_ufree(&args.status); - - if (-1 == rc) { - /* set must be suspended, or being disabled */ - return (0); - } - - return ((args.stat & DSW_SHDEXPORT) == DSW_SHDEXPORT); -} - -static void -conform_name(char **path) -{ - char *cfgname; - int rc = cfg_get_canonical_name(cfg, *path, &cfgname); - - if (rc < 0) { - dsw_error(gettext("Unable to parse config file"), NULL); - } - if (rc) { - (void) printf(" '%s'\n%s\n '%s'\n", *path, - gettext("is currently configured as"), cfgname); - check_action(gettext("Perform operation with indicated volume" - " name?")); - *path = cfgname; - /* - * NOTE: *path ought to be deallocated ('free(*path)') after - * we're done with it, but since this routine is called just - * before we exit, it doesn't really matter - */ - } -} - -/* - * verify_groupname(char *, int); - * - * Check the group name for the following rules: - * 1. The name does not start with a '-' - * 2. The name does not contain any space characters as defined by - * isspace(3C). - * If either of these rules are broken, error immediately. The check for a - * leading dash can be skipped if the 'testDash' argument is false. This is to - * allow for the '-g -L' functionality. - * - */ -static void -verify_groupname(char *grp, int testDash) -{ - int i; - - if (testDash && grp[0] == '-') { - errno = EINVAL; - dsw_error(gettext("group name cannot start with a '-'"), NULL); - } - - for (i = 0; grp[i] != '\0'; i++) { - if (isspace(grp[i])) { - errno = EINVAL; - dsw_error(gettext("group name cannot contain a space"), - NULL); - } - } -} - -void -check_iishadow(char *shadow_vol) { - int i; - int entries; - char **entry; - char *shost; - char *svol; - char *buf; - void *librdc; - - /* - * See if librdc is around - * If not, we can just return - */ - if (librdc = dlopen(RDC_LIB, RTLD_LAZY | RTLD_GLOBAL)) - self_check = (int (*)(char *)) dlsym(librdc, "self_check"); - else { - return; - } - - entry = NULL; - entries = cfg_get_section(cfg, &entry, "sndr"); - for (i = 0; i < entries; i++) { - buf = entry[i]; - - (void) strtok(buf, " "); /* phost */ - (void) strtok(NULL, " "); /* primary */ - (void) strtok(NULL, " "); /* pbitmap */ - shost = strtok(NULL, " "); /* shost */ - svol = strtok(NULL, " "); /* secondary */ - - if (self_check(shost) && (strcmp(shadow_vol, svol) == 0)) { - free(buf); - if (entries) - free(entry); - errno = EINVAL; - dsw_error(gettext( - "shadow volume is in use as SNDR secondary volume"), - NULL); - } - free(buf); - } - - (void) dlclose(librdc); - if (entries) - free(entry); -} 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); -} diff --git a/usr/src/cmd/avs/dsw/iicpbmp.c b/usr/src/cmd/avs/dsw/iicpbmp.c deleted file mode 100644 index 382759b3fa..0000000000 --- a/usr/src/cmd/avs/dsw/iicpbmp.c +++ /dev/null @@ -1,260 +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/time.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <values.h> -#include <locale.h> -#include <sys/stat.h> -#include <strings.h> -#include <stdarg.h> -#include <sys/param.h> -#include <nsctl.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/nsctl/dsw_dev.h> - -#define DSW_TEXT_DOMAIN "II" - -void iicpbmp_usage(); -void copybmp(char *, char *); -int find_bitmap_cfg(char *); - -extern int optind; - -char *cmdnam; - -extern char *optarg; -extern int optind, opterr, optopt; -int update_cfg = 1; -CFGFILE *cfg; -char shadow[DSW_NAMELEN]; -char buf[CFG_MAX_BUF]; -char key[CFG_MAX_KEY]; -int setnumber; - -#ifdef lint -int -iicpbmp_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - cmdnam = argv[0]; - - if (argc > 1) { - if (strcmp(argv[1], "-c") == 0) { - /* don't update cfg information */ - update_cfg = 0; - argc--; - argv++; - } - } - - if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */ - iicpbmp_usage(); - - if (update_cfg) { - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("Error opening config\n")); - exit(1); - } - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("ii", NULL, - "iicpbmp CFG_WRLOCK failed, errno %d", errno); - (void) fprintf(stderr, - gettext("Error locking config\n")); - exit(1); - } - } - - for (argv++; *argv != NULL; argv += 2) - copybmp(argv[0], argv[1]); - if (update_cfg) - cfg_close(cfg); - exit(0); - return (0); -} - -void -iicpbmp_usage() -{ - (void) fprintf(stderr, gettext("Usage:\n")); - (void) fprintf(stderr, - gettext("\tiicpbmp [-c] old_bitmap new_bitmap\n")); - exit(1); -} - -void -copybmp(char *old_bitmap, char *new_bitmap) -{ - int i; - int dsw_fd; - FILE *ifp, *ofp; - ii_header_t header; - char cp_buffer[256]; - dsw_stat_t args; - - dsw_fd = open(DSWDEV, O_RDONLY); - if (dsw_fd < 0) { - perror(DSWDEV); - exit(1); - } - if (*old_bitmap != '/' || *new_bitmap != '/') { - (void) fprintf(stderr, gettext("Both old and new bitmap " - "file names must begin with a /.\n")); - exit(1); - } - - if (strlen(new_bitmap) > DSW_NAMELEN) { - (void) fprintf(stderr, - gettext("New bitmap name is too long.\n")); - exit(1); - } - - if (update_cfg && find_bitmap_cfg(old_bitmap) == 0) { - perror(old_bitmap); - (void) fprintf(stderr, - gettext("Old bitmap not in existing cfg\n")); - exit(1); - } - - (void) strncpy(args.shadow_vol, shadow, DSW_NAMELEN); - args.shadow_vol[DSW_NAMELEN-1] = '\0'; - - args.status = spcs_s_ucreate(); - if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) { - (void) fprintf(stderr, gettext("Suspend the Point-in-Time Copy " - "set first\n")); - (void) close(dsw_fd); - exit(1); - } - - if ((ifp = fopen(old_bitmap, "r")) == NULL) { - perror(old_bitmap); - (void) fprintf(stderr, gettext("Can't open old bitmap file\n")); - exit(1); - } - - /* Check old header looks like an Point-in-Time Copy bitmap header */ - - if (fread(&header, sizeof (header), 1, ifp) != 1) { - (void) fprintf(stderr, gettext("Can't read old bitmap file\n")); - exit(1); - } - - if (header.ii_magic != DSW_CLEAN && header.ii_magic != DSW_DIRTY) { - (void) fprintf(stderr, gettext("%s is not a Point-in-Time Copy " - "bitmap.\n"), old_bitmap); - exit(1); - } - - if (strncmp(header.bitmap_vol, old_bitmap, DSW_NAMELEN) != 0) { - (void) fprintf(stderr, gettext( - "%s has Point-in-Time Copy bitmap magic number,\n" - "but does not contain correct data.\n"), old_bitmap); - exit(1); - } - - if ((ofp = fopen(new_bitmap, "w")) == NULL) { - perror(new_bitmap); - (void) fprintf(stderr, gettext("Can't open new bitmap file\n")); - exit(1); - } - - /* Set up new header */ - - (void) memset(header.bitmap_vol, 0, DSW_NAMELEN); - (void) strncpy(header.bitmap_vol, new_bitmap, DSW_NAMELEN); - - if (fwrite(&header, sizeof (header), 1, ofp) != 1) { - perror(new_bitmap); - (void) fprintf(stderr, - gettext("Can't write new bitmap header\n")); - exit(1); - } - - /* Copy the bitmap itself */ - - while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ifp)) - > 0) { - if (fwrite(cp_buffer, sizeof (char), i, ofp) != i) { - perror(gettext("Write new bitmap failed")); - break; - } - } - (void) fclose(ofp); - (void) fclose(ifp); - (void) close(dsw_fd); - if (update_cfg) { - (void) sprintf(key, "ii.set%d.bitmap", setnumber); - if (cfg_put_cstring(cfg, key, new_bitmap, strlen(new_bitmap)) - < 0) { - perror("cfg_put_cstring"); - } - (void) cfg_commit(cfg); - spcs_log("ii", NULL, - "iicpbmp copy bit map for %s from %s to %s", - shadow, old_bitmap, new_bitmap); - } -} - -/* - * find_bitmap_cfg() - * - */ - -int -find_bitmap_cfg(char *bitmap) -{ - for (setnumber = 1; ; setnumber++) { - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "ii.set%d.bitmap", - setnumber); - - if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) - return (0); - if (strcmp(buf, bitmap) == 0) { - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - setnumber); - (void) cfg_get_cstring(cfg, key, shadow, DSW_NAMELEN); - return (setnumber); - } - } -} diff --git a/usr/src/cmd/avs/dsw/iicpshd.c b/usr/src/cmd/avs/dsw/iicpshd.c deleted file mode 100644 index d34b3f41c5..0000000000 --- a/usr/src/cmd/avs/dsw/iicpshd.c +++ /dev/null @@ -1,358 +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/time.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <values.h> -#include <locale.h> -#include <sys/stat.h> -#include <strings.h> -#include <stdarg.h> -#include <sys/param.h> -#include <nsctl.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/nsctl/dsw_dev.h> /* for bitmap format */ - -#define DSW_TEXT_DOMAIN "II" -#define BITMAP_TOKEN "ii.set%d.bitmap" -#define SHADOW_TOKEN "ii.set%d.shadow" -#define SV_TOKEN "sv.set%d.vol" -#define DSVOL_TOKEN "dsvol.set%d.path" - -void iicpshd_usage(); -void copyshd(char *, char *); -int find_cfg_info(char *, char *); -int copy_shadow_vol(char *, char *); -void convert_to_blockdevice(); -int update_dscfg(char *); - -extern int optind; - -extern char *optarg; -extern int optind, opterr, optopt; -int copy_shadow = 1; -CFGFILE *cfg; -char real_bitmap[DSW_NAMELEN]; -char buf[CFG_MAX_BUF]; -char key[CFG_MAX_KEY]; -int set_number; -int sv_number; -int dsvol_number; - -#ifdef lint -int -iicpshd_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - if (argc > 1) { - if (strcmp(argv[1], "-s") == 0) { - /* don't copy shadow, only update dscfg and ii header */ - copy_shadow = 0; - argc--; - argv++; - } - } - - if (argc == 1 || (argc%2) == 0) /* must have pairs of filenames */ - iicpshd_usage(); - - /* open dscfg anyway */ - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, gettext("Error opening config\n")); - exit(1); - } - - for (argv++; *argv != NULL; argv += 2) - copyshd(argv[0], argv[1]); - - /* close dscfg */ - cfg_close(cfg); - exit(0); - return (0); -} - -void -iicpshd_usage() -{ - (void) fprintf(stderr, gettext("Usage:\n")); - (void) fprintf(stderr, - gettext("\tiicpshd [-s] old_shadow new_shadow\n")); - exit(1); -} - -void -copyshd(char *old_vol, char *new_vol) -{ - int dsw_fd; - FILE *ifp; - char header[FBA_SIZE(1) * DSW_CBLK_FBA]; - ii_header_t *hp; - dsw_stat_t args; - - /*LINTED pointer alignment*/ - hp = (ii_header_t *)&header; - - dsw_fd = open(DSWDEV, O_RDONLY); - if (dsw_fd < 0) { - perror(DSWDEV); - exit(1); - } - if (*old_vol != '/' || *new_vol != '/') { - (void) fprintf(stderr, gettext("Both old and new shadow " - "file names must begin with a /.\n")); - exit(1); - } - - if (strlen(new_vol) > DSW_NAMELEN) { - (void) fprintf(stderr, - gettext("New shadow name is to long.\n")); - exit(1); - } - - /* check old shadow is in dscfg */ - if (find_cfg_info(old_vol, SHADOW_TOKEN) == 0) { - (void) fprintf(stderr, - gettext("Old shadow not in existing cfg\n")); - exit(1); - } - - /* check ii set status, suspend if need */ - (void) strncpy(args.shadow_vol, old_vol, DSW_NAMELEN); - args.shadow_vol[DSW_NAMELEN-1] = '\0'; - args.status = spcs_s_ucreate(); - if (ioctl(dsw_fd, DSWIOC_STAT, &args) != -1) { - (void) fprintf(stderr, gettext("Suspend the Point-in-Time Copy " - "set first\n")); - (void) close(dsw_fd); - exit(1); - } - - if (copy_shadow) { - if (copy_shadow_vol(old_vol, new_vol) == 0) { - perror(gettext("Write new shadow failed")); - (void) close(dsw_fd); - exit(1); - } - } - if (find_cfg_info(old_vol, SV_TOKEN) == 0) { - (void) fprintf(stderr, - gettext("Old shadow not in existing cfg\n")); - exit(1); - } - if (find_cfg_info(old_vol, DSVOL_TOKEN) == 0) { - (void) fprintf(stderr, - gettext("Old shadow not in existing cfg\n")); - exit(1); - } - if (strstr(real_bitmap, "/rdsk/") == NULL) { - (void) fprintf(stderr, - gettext("%s is not a character device\n"), real_bitmap); - exit(1); - } - - /* use block device /dsk/ to update bitmap header */ - convert_to_blockdevice(); - - /* open bitmap by using update mode */ - if ((ifp = fopen(real_bitmap, "r+")) == NULL) { - (void) fprintf(stderr, gettext("Can't open bitmap file\n")); - exit(1); - } - - /* Check old header looks like an II bitmap header */ - if (fread(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) { - (void) fprintf(stderr, gettext("Can't read bitmap file\n")); - exit(1); - } - - if (hp->ii_magic != DSW_CLEAN && hp->ii_magic != DSW_DIRTY) { - (void) fprintf(stderr, - gettext("%s is not a Point-in-Time Copy " - "shadow.\n"), old_vol); - exit(1); - } - - if (strncmp(hp->shadow_vol, old_vol, DSW_NAMELEN) != 0) { - (void) fprintf(stderr, gettext("%s has Point-in-Time Copy " - "shadow magic number,\n" - "but does not contain correct data.\n"), old_vol); - exit(1); - } - - (void) memset(hp->shadow_vol, 0, DSW_NAMELEN); - (void) strncpy(hp->shadow_vol, new_vol, DSW_NAMELEN); - - /* reset the pointer position */ - rewind(ifp); - if (fwrite(&header, DSW_CBLK_FBA, FBA_SIZE(1), ifp) != FBA_SIZE(1)) { - perror(new_vol); - (void) fprintf(stderr, - gettext("Can't write new bitmap header\n")); - exit(1); - } - (void) fclose(ifp); - (void) close(dsw_fd); - if (update_dscfg(new_vol) == 0) { - (void) fprintf(stderr, gettext("Failed to update dscfg.\n")); - exit(1); - } else { - spcs_log("ii", NULL, - "iicpshd copy shadow from %s to %s", - old_vol, new_vol); - } -} - -/* - * find_cfg_info() - * - */ - -int -find_cfg_info(char *volume, char *token) -{ - int i; - /* get read lock */ - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("ii", NULL, - "iicpbmp CFG_RDLOCK failed, errno %d", errno); - (void) fprintf(stderr, gettext("Error locking config\n")); - exit(1); - } - for (i = 1; ; i++) { - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), token, i); - if (cfg_get_cstring(cfg, key, buf, DSW_NAMELEN) < 0) { - cfg_unlock(cfg); - return (0); - } - if (strcmp(buf, volume) == 0) { - if (strcmp(token, SHADOW_TOKEN) == 0) { - (void) snprintf(key, sizeof (key), - BITMAP_TOKEN, i); - (void) cfg_get_cstring(cfg, key, - real_bitmap, DSW_NAMELEN); - set_number = i; - } else if (strcmp(token, SV_TOKEN) == 0) { - sv_number = i; - } else if (strcmp(token, DSVOL_TOKEN) == 0) { - dsvol_number = i; - } - /* release read lock */ - cfg_unlock(cfg); - return (1); - } - } -} - -int -copy_shadow_vol(char *old_shadow, char *new_shadow) { - int i; - char cp_buffer[256]; - FILE *ishdfp, *oshdfp; - if ((ishdfp = fopen(old_shadow, "r")) == NULL) { - (void) fprintf(stderr, gettext("Can't open old shadow file\n")); - return (0); - } - if ((oshdfp = fopen(new_shadow, "w")) == NULL) { - (void) fprintf(stderr, gettext("Can't open new shadow file\n")); - return (0); - } - - /* Copy the shadow vol */ - while ((i = fread(cp_buffer, sizeof (char), sizeof (cp_buffer), ishdfp)) - > 0) { - if (fwrite(cp_buffer, sizeof (char), i, oshdfp) != i) { - (void) fclose(ishdfp); - (void) fclose(oshdfp); - return (0); - } - } - (void) fclose(ishdfp); - (void) fclose(oshdfp); - return (1); -} - -int -update_dscfg(char *new_shadow) { - - int len = strlen(new_shadow); - /* get write lock */ - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("ii", NULL, - "iicpbmp CFG_WRLOCK failed, errno %d", errno); - (void) fprintf(stderr, gettext("Error locking config\n")); - return (0); - } - (void) sprintf(key, SHADOW_TOKEN, set_number); - if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { - perror("cfg_put_cstring"); - return (0); - } - (void) sprintf(key, SV_TOKEN, sv_number); - if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { - perror("cfg_put_cstring"); - return (0); - } - (void) sprintf(key, DSVOL_TOKEN, dsvol_number); - if (cfg_put_cstring(cfg, key, new_shadow, len) < 0) { - perror("cfg_put_cstring"); - return (0); - } - (void) cfg_commit(cfg); - cfg_unlock(cfg); - return (1); -} - -void -convert_to_blockdevice() { - int len = strlen(real_bitmap); - int i = 0, j = 0; - char *temp_string = malloc(len-1); - while (i < len + 1) { - if (real_bitmap[i] != 'r') { - temp_string[j] = real_bitmap[i]; - j++; - } - i++; - } - (void) strcpy(real_bitmap, temp_string); - free(temp_string); -} diff --git a/usr/src/cmd/avs/errgen/Makefile b/usr/src/cmd/avs/errgen/Makefile deleted file mode 100644 index afd5db1b7b..0000000000 --- a/usr/src/cmd/avs/errgen/Makefile +++ /dev/null @@ -1,55 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -DYNPROG= errgen - -include ../../Makefile.cmd -include ../Makefile.com - -PROG= $(DYNPROG) - -OBJS= errgen.o - -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-switch -LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY -CLOBBERFILES += $(DYNPROG) - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -install: all - -lint: lint_PROG - -clean: - $(RM) $(OBJS) - -$(PROG): $(OBJS) - $(NATIVECC) $(CFLAGS) $(OBJS) -o $@ - $(POST_PROCESS) - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/errgen/errgen.c b/usr/src/cmd/avs/errgen/errgen.c deleted file mode 100644 index ea7eb756b6..0000000000 --- a/usr/src/cmd/avs/errgen/errgen.c +++ /dev/null @@ -1,379 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Read an errgen status resource file (*.err) from standard input and - * write an SPCS error code C header file (-c), Java resource file (-j), - * libspcs Java exception class file(-e), error text file (-m) or JNI - * exception trinket table to standard output. Lines starting with "#" - * are ignored. - * - * Use "errgen -h" to get usage info including module codes and example - * input and output. - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <libgen.h> -#include <limits.h> -#include <sys/param.h> - -/* The public error info header file. */ - -#include <sys/unistat/spcs_s.h> - -/* The private error info header file */ - -#include <sys/unistat/spcs_s_impl.h> - - -/* locals */ - -static enum {C_MODE, J_MODE, M_MODE, E_MODE, T_MODE, X_MODE} mode = E_MODE; -static char key[SPCS_S_MAXKEY]; -static char text[SPCS_S_MAXTEXT]; -static int mod_number; - -static char help_path[PATH_MAX]; - -static int count = 1; - -static char key[SPCS_S_MAXKEY]; -static char text[SPCS_S_MAXTEXT]; -static char modname[SPCS_S_MAXMODNAME]; - -/* - * Display help info - */ - -static void -help() -{ - char line[SPCS_S_MAXLINE]; - FILE *h = fopen(help_path, "r"); - - if (h) { - while (! feof(h)) { - (void) fgets(line, SPCS_S_MAXLINE, h); - if (! feof(h)) - (void) fputs(line, stderr); - } - } else { - perror(strcat("could not open: ", help_path)); - exit(1); - } -} - -/* - * Put out a message with terse instructions and err out - */ - -static void -fatal(char *msg) -{ - (void) fprintf(stderr, "%s\n\n", msg); - (void) fprintf(stderr, "use errgen -h for help\n"); - exit(1); -} - -/* - * Put out the output file preamble - */ - -static void -do_preamble() -{ - switch (mode) { - case M_MODE: - (void) fprintf(stdout, - "static\nchar *SPCS_MSG_%s[] = {\n", modname); - (void) fprintf(stdout, "\t\"\",\n"); - break; - case T_MODE: - (void) fprintf(stdout, - "static\nchar *SPCS_TRNK_%s[] = {\n", modname); - (void) fprintf(stdout, "\t\"\",\n"); - break; - } -} - -/* - * Put out the output file trailer - */ - -static void -do_trailer() -{ - switch (mode) { - case M_MODE: - (void) fprintf(stdout, "};\n"); - (void) fprintf(stdout, - "#define\tSPCS_MSGLEN_%s %d\t/* total codes */\n", - modname, count-1); - break; - case T_MODE: - (void) fprintf(stdout, "};\n"); - (void) fprintf(stdout, - "#define\tSPCS_TRNKLEN_%s %d\t/* total codes */\n", - modname, count-1); - break; - } -} - -/* - * Process a single input line - */ - -static void -do_line() -{ - spcs_s_udata_t c; - int fc = 0; - int len = 0; - char ptext[SPCS_S_MAXTEXT]; - char keystring[SPCS_S_MAXKEY+SPCS_S_MAXPRE]; - char *p = text; - int tlen; - char *pt = ptext; - char havebytestream = 0; - - c.i = 0; - (void) sprintf(keystring, "%s_E%s", modname, key); - while (*p) { - if (*p == '%') { - if (*(p + 1) != 's') { - (void) fprintf(stderr, - "ERRGEN: Error in .err file\n"); - (void) fprintf(stderr, - "%c is an illegal format spec after %%", - *p); - (void) fprintf(stderr, - " at line: %d pos: %d\n", count, - /* LINTED possible ptrdiff_t overflow */ - (int)(p - text)); - fatal(""); - } - len = sprintf(pt, "{%d}", fc); - pt += len; - p++; - fc += 1; - if (fc > SPCS_S_MAXSUPP) { - (void) fprintf(stderr, - "ERRGEN: Error in .err file\n"); - (void) fprintf(stderr, - "SPCS_S_MAXSUPP exceeeded\n"); - fatal("Too many %%s specifiers"); - } - } else - *pt++ = *p; - p++; - } - - /* look for a bytestream indicator */ - - tlen = strlen(text); - - if ((tlen > 2) && (text[tlen - 1] == '@') && (text[tlen - 2] == '@')) { - if (fc) - fatal("ERRGEN: cannot have %%s and @@ ending too"); - - /* bump the item count and set the bytestream flag */ - fc += 1; - havebytestream = 1; - } - - *pt = 0; - - switch (mode) { - case C_MODE: - c.f.bytestream = havebytestream; - c.f.sup_count = fc; - c.f.module = mod_number; - c.f.code = count; - (void) fprintf(stdout, "#define\t%s 0x%x /* %s */\n", - keystring, c.i, text); - break; - case J_MODE: - (void) fprintf(stdout, "`%s` = %s\n", keystring, ptext); - break; - case X_MODE: - (void) fprintf(stdout, - "#define\tT_%s \"`%s`\"\n", keystring, keystring); - break; - case T_MODE: - (void) fprintf(stdout, "\t\"`%s`\",\n", keystring); - break; - case M_MODE: - (void) fprintf(stdout, "\t\"%s\",\n", text); - break; - case E_MODE: - (void) fprintf(stdout, " /**\n * %s\n **/\n", - text); - (void) fprintf(stdout, " public static final String %s", - keystring); - (void) fprintf(stdout, " = `%s`;\n\n", keystring); - break; - } -} - -int -main(int argc, char **argv) -{ - int i; - int searching = 1; - char searchname[SPCS_S_MAXMODNAME]; - char line[SPCS_S_MAXLINE]; - char tline[SPCS_S_MAXLINE]; - char *p, *p2; - - (void) strcpy(help_path, dirname(argv[0])); - (void) strcat(help_path, "/errgen.help"); - if ((argc == 1) || ((argc == 2) && (strcmp(argv[1], "-h") == 0))) { - help(); - exit(0); - } - - if (argc != 3) - fatal("Bad number of arguments"); - - p = argv[2]; - p2 = modname; - - while (*p) - *p2++ = toupper(*p++); - *p2 = 0; - - switch (argv[1][1]) { - case 'c': - mode = C_MODE; - break; - case 'j': - mode = J_MODE; - break; - case 'e': - mode = E_MODE; - break; - case 'm': - mode = M_MODE; - break; - case 't': - mode = T_MODE; - break; - case 'x': - mode = X_MODE; - break; - default: - fatal("Unknown option switch"); - } - - if (strcmp(modname, "DSW") == 0) { - (void) strcpy(searchname, "II"); - } else if (strcmp(modname, "RDC") == 0) { - (void) strcpy(searchname, "SNDR"); - } else if (strcmp(modname, "SDCTL") == 0) { - (void) strcpy(searchname, "NSCTL"); - } else { - (void) strcpy(searchname, modname); - } - - i = 0; - do { - if (strcmp(module_names[i++], searchname) == 0) { - searching = 0; - mod_number = i - 1; - break; - } - } while (module_names[i]); - - if (searching) { - if (i != SPCS_M_MAX) - (void) fprintf(stderr, - "NULL in module_names before SPCS_M_MAX\n"); - fatal("Undefined module name"); - } - - do_preamble(); - - while (!feof(stdin)) { - (void) fgets(line, SPCS_S_MAXLINE, stdin); - if (feof(stdin)) { - if (count == 0) - fatal("errgen file empty"); - - do_trailer(); - exit(0); - } - line[strlen(line)-1] = 0; - if ((strlen(line) != 0) && (line[0] != '#')) { - (void) strcpy(tline, line); - p = strchr(tline, ' '); - if (p == NULL) { - (void) fprintf(stderr, - "blank separator missing at line: %d\n", - count); - fatal(""); - } - *p = 0; - if (strlen(p) > SPCS_S_MAXKEY) { - (void) fprintf(stderr, - "message label too long at line: %d\n", count); - fatal(""); - } - (void) strcpy(key, tline); - if (strlen(key) == 0) { - (void) fprintf(stderr, - "leading blank at line: %d\n", count); - fatal(""); - } - p++; - if (*p != '=') { - (void) fprintf(stderr, - "= separator missing at line: %d\n", count); - fatal(""); - } - p++; - if (*p != ' ') { - (void) fprintf(stderr, - "blank separator missing at line: %d\n", count); - fatal(""); - } - p++; - if (! *p) { - (void) fprintf(stderr, - "msg text missing at line:%d\n", count); - fatal(""); - } - (void) strcpy(text, p); - - do_line(); - count++; - } - } - - return (0); -} diff --git a/usr/src/cmd/avs/errgen/errgen.help.txt b/usr/src/cmd/avs/errgen/errgen.help.txt deleted file mode 100644 index 33600d3bd1..0000000000 --- a/usr/src/cmd/avs/errgen/errgen.help.txt +++ /dev/null @@ -1,118 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -Usage: errgen [-c | -j | -e | -m | -t] <module_code> -Options: - -c Generate C header file - -j Generate Java resource file - -e Generate libspcs exception class body - -m Generate error message text header file - -t Genrate libspcs JNI exception trinket string table - -x Genrate libspcs JNI exception trinket defines -The module_code values are case insensitive: - - SPCS Storage Product Controller Software (general errors) - DSW DataShadow Module - SV Storage Volume Module - RDC Remote Dual Copy Module - SDBC Storage Device Block Cache Module - STE SCSI Target Emulation Module - SDCTL Storage Device Control Module - MC Memory Channel Module - SIMCKD CKD Simulation (SIMCKD) Module - -The format of the resource file is as follows: - -<message_key> = <message text> - -The message_key will become the #define or static final name of the message -definition with a module error prefix. The message_text will become a -inline comment depending on usage - -EXAMPLE resource input file. NOTE that only the %s format spec is supported -for supplying supplemental data for ioctl status. If a line ends with "@@" it -it indicates that a byte address and length will be supplied with the status -code to provide arbitrary data for shipment to userspace (a "bytestream"). -Bytestreams are intended for asynchronous status output from coresw and are -not supported for ioctl status. - -NOMINOR = No more minor numbers available -ARRBOUNDS = Array bounds check exceeded %s size limit -INTERNALDUMP = Internal state dump @@ - -EXAMPLE C header file generated with "errgen -c SV": - -#define SV_ENOMINOR 0x00030001 /* No more minor numbers available */ -#define SV_EARRBOUNDS 0x01030002 /*Array bounds over %s size limit */ -#define SV_EINTERNALDUMP 0x09030003 /* Internal state dump */ - -EXAMPLE Java resource file generated by "errgen -j SV": - -`SV_ENOMINOR` = No more minor numbers available -`SV_EARRBOUNDS` = Array bounds check exceeded {0} size limit -`SV_EINTERNALDUMP` = Internal state dump - -EXAMPLE libspcs exception class body generated by "errgen -e SV": - - /** - * No more minor numbers available - **/ - public static final String SV_ENOMINOR = `SV_ENOMINOR`; - - /** - * Array bounds check exceeded %s size limit - **/ - public static final String SV_EARRBOUND = `SV_EARRBOUND`; - - /** - * Internal state dump - **/ - public static final String SV_EINTERNALDUMP = `SV_EINTERNALDUMP`; - -EXAMPLE msg text data generated by "errgen -m SV": - - static char *SPCS_L_NTOM_SV[]={ - "", - "No more minor numbers available", - "Array bounds check exceeded %s size limit", - "Internal State dump", - }; - #define SPCS_M_CNT_SV 3 /* total codes */ - -EXAMPLE libspcs JNI exception "trinket" table generated by "errgen -t SV": - - static char *SPCS_TRINKET_SV[]={ - "", - "`SV_ENOMINOR`", - "`SV_EARRBOUNDS`", - "`SV_EINTERNALDUMP`", - } - -EXAMPLE libspcs JNI exception "trinket" defines generated by "errgen -x SV": - -#define T_SV_ENOMINOR "`SV_ENOMINOR`" -#define T_SV_EARRBOUNDS "`SV_EARRBOUNDS`" -#define T_SV_EARRBOUNDS "`SV_EINTERNALDUMP`" diff --git a/usr/src/cmd/avs/ncall/Makefile b/usr/src/cmd/avs/ncall/Makefile deleted file mode 100644 index 30bffc0513..0000000000 --- a/usr/src/cmd/avs/ncall/Makefile +++ /dev/null @@ -1,84 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# - -DYNPROG = \ - ncalladm - -include ../../Makefile.cmd - -SUBDIRS= -PROG= $(DYNPROG) - -ncalladm := POBJS = ncalladm.o - -OBJS= ncalladm.o -SRCS= $(OBJS:%.o=%.c) -POFILE= $(OBJS:%.o=%.po) - -LDLIBS += -ldscfg -LINTFLAGS += -D_SYSCALL32 -D__NCALL__ -LINTFLAGS += -erroff=E_NAME_DEF_NOT_USED2 -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -LINTFLAGS += -erroff=E_FUNC_RET_MAYBE_IGNORED2 -LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2 -LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2 -LINTFLAGS += -erroff=E_FUNC_RET_ALWAYS_IGNOR2 -LINTDIR = $(KBASE)/lintdir -CFLAGS += $(CCVERBOSE) -D_SYSCALL32 -D__NCALL__ -CERRWARN += -_gcc=-Wno-uninitialized -ROOTLINK = $(ROOTLIB)/$(PROG) - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SUBDIRS)$(PROG) $(POFILE) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK) - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o $(POFILE) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(ROOTLINK): $(ROOTLIB) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTPROG) $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/ncall/ncalladm.c b/usr/src/cmd/avs/ncall/ncalladm.c deleted file mode 100644 index 1214b39c1a..0000000000 --- a/usr/src/cmd/avs/ncall/ncalladm.c +++ /dev/null @@ -1,558 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> -#include <fcntl.h> -#include <libgen.h> - -#include <sys/nsctl/cfg.h> -#include <sys/ncall/ncall.h> - -static CFGFILE *cfg; -static int cfg_changed; -static char *progname; -static ncall_node_t *getnodelist(int, int *, int *); - - -static void -usage(int exitstat) -{ - (void) fprintf(stderr, gettext("usage:\n")); - (void) fprintf(stderr, gettext(" %s -d\n"), progname); - (void) fprintf(stderr, gettext(" %s -e\n"), progname); - (void) fprintf(stderr, gettext(" %s -h\n"), progname); -#ifdef DEBUG - (void) fprintf(stderr, gettext(" %s -c [nodeid <nodeid>]\n"), - progname); - (void) fprintf(stderr, gettext(" %s -i\n"), progname); - (void) fprintf(stderr, gettext(" %s -p <host>\n"), progname); -#endif - - (void) fprintf(stderr, gettext("where:\n")); - (void) fprintf(stderr, gettext(" -d disable ncall\n")); - (void) fprintf(stderr, gettext(" -e enable ncall core\n")); - (void) fprintf(stderr, gettext(" -h this help message\n")); -#ifdef DEBUG - (void) fprintf(stderr, - gettext(" -c set or print ncall configuration\n")); - (void) fprintf(stderr, gettext(" -i ncall information\n")); - (void) fprintf(stderr, gettext(" -p ncall ping <host>\n")); -#endif - - exit(exitstat); -} - - -static void -ncall_cfg_open(CFGLOCK lk) -{ - char hostid[32]; - - if (cfg != NULL) { - return; - } - - if (snprintf(hostid, sizeof (hostid), "%lx", gethostid()) >= - sizeof (hostid)) { - (void) fprintf(stderr, gettext("%s: hostid %lx too large\n"), - progname, gethostid()); - exit(1); - } - - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access the configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (!cfg_lock(cfg, lk)) { - (void) fprintf(stderr, - gettext("%s: unable to lock the configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - cfg_resource(cfg, hostid); -} - - -static void -ncall_cfg_close(void) -{ - if (cfg_changed && cfg_commit(cfg) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to update the configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - cfg_close(cfg); - cfg = NULL; -} - - -/* - * Get config from dscfg. - */ -static int -get_nodeid_from_cfg(int *nodeid) -{ - char buf[CFG_MAX_BUF]; - int ret = -1; - int rc; - - ncall_cfg_open(CFG_RDLOCK); - - if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) { - rc = sscanf(buf, "%d", nodeid); - if (rc == 1) { - ret = 0; - } - } - - ncall_cfg_close(); - - return (ret); -} - - -static void -ncall_print(void) -{ - int cfnodeid, clnodeid, rc; - - clnodeid = cfg_issuncluster(); - - rc = get_nodeid_from_cfg(&cfnodeid); - - if (rc < 0 && clnodeid > 0) { - (void) printf(gettext("%s: ncall is using the SunCluster " - "nodeid: %d\n"), progname, clnodeid); - } else if (rc < 0) { - (void) printf(gettext("%s: ncall is using the default " - "nodeid: %d\n"), progname, 0); - } else { - (void) printf(gettext("%s: current configuration:\n"), - progname); - /* deliberately not i18n'd - "nodeid" is a keyword */ - (void) printf("nodeid %d\n", cfnodeid); - } -} - - -static void -ncall_config(const int nodeid) -{ - char buf[CFG_MAX_BUF]; - - ncall_cfg_open(CFG_WRLOCK); - - if (cfg_get_cstring(cfg, "ncallcore.set1", buf, sizeof (buf)) >= 0) { - /* remove old config */ - if (cfg_put_cstring(cfg, "ncallcore.set1", NULL, 0) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to update the configuration: " - "%s\n"), cfg_error(NULL)); - exit(1); - } - } - - if (snprintf(buf, sizeof (buf), "%d", nodeid) >= sizeof (buf)) { - (void) fprintf(stderr, - gettext("%s: unable to update configuration: " - "data too long\n"), progname); - exit(1); - } - - if (cfg_put_cstring(cfg, "ncallcore", buf, sizeof (buf)) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to update the configuration: %s\n"), - cfg_error(NULL)); - exit(1); - } - - cfg_changed = 1; - ncall_cfg_close(); - - (void) printf(gettext("%s: configuration set to:\n"), progname); - /* deliberately not i18n'd - "nodeid" is a keyword */ - (void) printf("nodeid %d\n", nodeid); -} - -#ifdef lint -int -ncalladm_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - const char *dev = "/dev/ncall"; - extern int optind, opterr; - ncall_node_t nodeinfo, *nodes; - int nsize; - int i; - int cflag, dflag, eflag, iflag, pflag; - int rc, fd, opt; - int clnodeid, cfnodeid; - int up; - char *cp, *ping; - int mnode; /* mirror nodeid */ - - (void) setlocale(LC_ALL, ""); - (void) textdomain("ncalladm"); - - opterr = 0; - cflag = dflag = eflag = iflag = pflag = 0; - ping = NULL; - - progname = basename(argv[0]); - - while ((opt = getopt(argc, argv, -#ifdef DEBUG - "cip:" -#endif - "deh")) != -1) { - switch (opt) { - case 'c': - cflag = 1; - break; - - case 'd': - dflag = 1; - break; - - case 'e': - eflag = 1; - break; - - case 'h': - usage(0); - break; - - case 'i': - iflag = 1; - break; - - case 'p': - ping = optarg; - pflag = 1; - break; - - default: - (void) fprintf(stderr, gettext("%s: unknown option\n"), - progname); - usage(1); - break; - } - } - - if (!(cflag || dflag || eflag || iflag || pflag)) { - usage(1); - } - - if (argc != optind) { - if (!cflag || - (argc - optind) != 2 || - strcmp(argv[optind], "nodeid") != 0) { - usage(1); - } - } - - if ((cflag + dflag + eflag + iflag + pflag) > 1) { - (void) fprintf(stderr, - gettext("%s: multiple options are not supported\n"), - progname); - usage(1); - } - - if (!cflag) { - fd = open(dev, O_RDONLY); - if (fd < 0) { - (void) fprintf(stderr, - gettext("%s: unable to open %s: %s\n"), - progname, dev, strerror(errno)); - exit(1); - } - } - - if (dflag) { - /* ioctl stop into kernel */ - if (ioctl(fd, NC_IOC_STOP, 0) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to disable ncall: %s\n"), - progname, strerror(errno)); - exit(1); - } - } else if (eflag) { - bzero(&nodeinfo, sizeof (nodeinfo)); - - clnodeid = cfg_issuncluster(); - cfnodeid = 0; - - /* get node info */ - rc = gethostname(nodeinfo.nc_nodename, - sizeof (nodeinfo.nc_nodename)); - if (rc < 0) { - (void) fprintf(stderr, - gettext("%s: unable to determine hostname: %s\n"), - progname, strerror(errno)); - exit(1); - } - - rc = get_nodeid_from_cfg(&cfnodeid); - - if (clnodeid > 0 && rc == 0) { - /* - * check that the nodeids from the cf file and - * cluster match. - */ - if (clnodeid != cfnodeid) { - (void) fprintf(stderr, - gettext("%s: nodeid from configuration " - "(%d) != cluster nodeid (%d)\n"), - progname, cfnodeid, clnodeid); - exit(1); - } - } - - if (rc == 0) { - nodeinfo.nc_nodeid = cfnodeid; - } else if (clnodeid > 0) { - nodeinfo.nc_nodeid = clnodeid; - } else { - nodeinfo.nc_nodeid = 0; - } - - /* ioctl node info into kernel and start ncall */ - rc = ioctl(fd, NC_IOC_START, &nodeinfo); - if (rc < 0) { - (void) fprintf(stderr, - gettext("%s: unable to enable ncall: %s\n"), - progname, strerror(errno)); - exit(1); - } - } - - if (iflag || pflag) { - nodes = getnodelist(fd, &nsize, &mnode); - - if (nodes == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to get node info\n"), - progname); - exit(1); - } - } - - if (iflag) { - char *mname; - char *pnodestr; - - (void) printf(gettext("Self Node Name: %s\n"), - nodes[0].nc_nodename); - (void) printf(gettext("Self Node ID: %d\n"), - nodes[0].nc_nodeid); - /* - * determine which slot is the mirror node. - */ - if (mnode != -1) { - for (i = 1; i < nsize; i++) { - if (nodes[i].nc_nodeid == mnode) { - mname = nodes[i].nc_nodename; - break; - } - } - } - if ((mnode == -1) || (i >= nsize)) { - mname = gettext("unknown"); - mnode = -1; - } - - (void) printf(gettext("Mirror Node Name: %s\n"), mname); - (void) printf(gettext("Mirror Node ID: %d\n"), mnode); - /* - * See if we need to translate the node strings. - */ - if (nsize > 1) { - pnodestr = gettext("Node Name: %s\nNode ID: %d\n"); - for (i = 1; i < nsize; i++) { - /* - * Don't print the mirror twice. - */ - if (nodes[i].nc_nodeid != mnode) { - (void) printf(pnodestr, - nodes[i].nc_nodename, - nodes[i].nc_nodeid); - } - } - } - } - - if (pflag) { - if (strlen(ping) >= sizeof (nodeinfo.nc_nodename)) { - (void) fprintf(stderr, - gettext("%s: hostname '%s' is too long\n"), - progname, ping); - exit(1); - } - up = 0; - if (strcmp(nodes[0].nc_nodename, ping) == 0) { - up = 1; /* self */ - } else { - /* not self, so ask kernel */ - bzero(&nodeinfo, sizeof (nodeinfo)); - /* strlen(ping) checked above */ - (void) strcpy(nodeinfo.nc_nodename, ping); - up = ioctl(fd, NC_IOC_PING, nodeinfo); - } - - /* model the ping messages on ping(1m) */ - - if (up < 0) { - (void) fprintf(stderr, - gettext("%s: unable to ping host '%s': %s\n"), - progname, ping, strerror(errno)); - exit(1); - } else if (up > 0) { - (void) printf(gettext("%s is alive\n"), ping); - } else { - (void) printf(gettext("no answer from %s\n"), ping); - exit(1); - } - } - - if (iflag || pflag) { - free(nodes); - } - - if (cflag) { - if (argc == optind) { - ncall_print(); - return (0); - } - - cp = NULL; - cfnodeid = (int)strtol(argv[optind+1], &cp, 0); - if (cp != NULL && *cp != '\0') { - (void) fprintf(stderr, - gettext("%s: nodeid \"%s\" is not an " - "integer number\n"), progname, argv[optind+1]); - exit(1); - } - - clnodeid = cfg_issuncluster(); - if (clnodeid > 0 && cfnodeid != clnodeid) { - (void) fprintf(stderr, - gettext("%s: nodeid from command line " - "(%d) != cluster nodeid (%d)\n"), - progname, cfnodeid, clnodeid); - exit(1); - } - - ncall_config(cfnodeid); - } - - if (!cflag) { - (void) close(fd); - } - - return (0); -} - - -/* - * return a pointer to a list of currently configured - * nodes. - * Return the number of nodes via the nodesizep pointer. - * Return the mirror nodeid via the mirrorp pointer. - * Return NULL on errors. - */ -static ncall_node_t * -getnodelist(int ifd, int *nodesizep, int *mirrorp) -{ - int maxsize; - int cnt; - ncall_node_t *noderet = NULL; - ncall_node_t *nodelist; - ncall_node_t thisnode; - int mirror; - int nonet; - - /* - * Get this host info and mirror nodeid. - */ - mirror = ioctl(ifd, NC_IOC_GETNODE, &thisnode); - - if (mirror < 0) { - return (NULL); - } - - /* - * See if we need to allocate the buffer. - */ - nonet = 0; - maxsize = ioctl(ifd, NC_IOC_GETNETNODES, 0); - if (maxsize < 1) { - maxsize = 1; - nonet = 1; - } - nodelist = malloc(sizeof (*nodelist) * maxsize); - if (nodelist) { - if (nonet == 0) { - /* - * fetch the node data. - */ - cnt = ioctl(ifd, NC_IOC_GETNETNODES, nodelist); - if (cnt > 0) { - *nodesizep = cnt; - noderet = nodelist; - *mirrorp = mirror; - } else { - *nodesizep = 0; - free(nodelist); - } - } else { - (void) memcpy(nodelist, &thisnode, sizeof (*nodelist)); - *nodesizep = 1; - noderet = nodelist; - /* - * Although we know the mirror nodeid, there - * is no point in returning it as we have - * no information about any other hosts. - */ - *mirrorp = -1; - } - } - return (noderet); -} diff --git a/usr/src/cmd/avs/nsctl/Makefile b/usr/src/cmd/avs/nsctl/Makefile deleted file mode 100644 index f5b19dc7b2..0000000000 --- a/usr/src/cmd/avs/nsctl/Makefile +++ /dev/null @@ -1,87 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# must be before include of Makefile.cmd -DYNPROG = nscadm nskernd - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -OBJS= nscadm.o nskernd.o -SRCS= $(OBJS:%.o=%.c) -POFILES= $(OBJS:%.o=%.po) - -nscadm := POBJS = nscadm.o -nskernd := POBJS = nskernd.o - -CFLAGS += -v -CPPFLAGS += -DBUILD_REV_STR='"5.11"' -NSCADM_LDLIBS = -lnsctl -NSKERND_LDLIBS = -lnsctl -ldscfg -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -DDEBUG -LINTDIR = $(KBASE)/lintdir -POFILE = nsctl_all.po -LFILE = $(LINTDIR)/nsctl.ln -ROOTLIBLINK = $(ROOTLIB)/nskernd -ROOTSBINLINK = $(ROOTUSRSBIN)/nscadm - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -nscadm := LDLIBS += $(NSCADM_LDLIBS) -nskernd := LDLIBS += $(NSKERND_LDLIBS) - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) $(POFILES) - -install: all $(ROOTPROG) $(ROOTBIN)/nskernd $(ROOTLIBLINK) $(ROOTSBINLINK) - -lint: lint_SRCS - -clean: - $(RM) *.o $(POFILES) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(ROOTLIBLINK): $(ROOTLIB) $(ROOTBIN)/nskernd - -$(RM) $@; $(LN) $(ROOTBIN)/nskernd $@ - -$(ROOTSBINLINK): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTBIN)/nscadm $@ - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/nsctl/nscadm.c b/usr/src/cmd/avs/nsctl/nscadm.c deleted file mode 100644 index 5096dd5b73..0000000000 --- a/usr/src/cmd/avs/nsctl/nscadm.c +++ /dev/null @@ -1,275 +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/stat.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> - -#include <nsctl.h> -#define __NSC_GEN__ -#include <sys/nsctl/nsc_gen.h> -#include <sys/nsctl/nsc_mem.h> - - -/* - * Private functions from libsd. - */ -extern int nsc_nvclean(int); -extern int nsc_gmem_data(char *); -extern int nsc_gmem_sizes(int *); - -/* - * Local functions. - */ -static int _nsc_gmem(void); -static void show_maps(char *, int); - - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("usage: nscadm [-h] command\n")); - (void) fprintf(stderr, gettext("valid commands:\n")); - (void) fprintf(stderr, gettext(" freeze <device>\n")); - (void) fprintf(stderr, gettext(" unfreeze <device>\n")); - (void) fprintf(stderr, gettext(" isfrozen <device>\n")); -} - -static void -is_chr_dev(char *dev, char *op) -{ - struct stat sbuf; - if (stat(dev, &sbuf) < 0) { - (void) fprintf(stderr, gettext("nscadm: ")); - perror(op); - exit(255); - } - if (!S_ISCHR(sbuf.st_mode)) { - (void) fprintf(stderr, gettext("nscadm: %s: not a valid device " - "<%s>\n"), op, dev); - exit(255); - } -} - -int -main(int argc, char *argv[]) -{ - extern int optind, opterr; - int opt, rc; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("nscadm"); - - rc = 0; - opterr = 0; - - while ((opt = getopt(argc, argv, "h")) != -1) { - switch (opt) { - case 'h': - usage(); - exit(0); - break; - default: - usage(); - exit(255); - break; - } - } - - if (optind == argc) { - usage(); - exit(255); - } - - if (strcoll(argv[optind], gettext("freeze")) == 0 || - strcmp(argv[optind], "freeze") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "freeze"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: freeze")); - exit(255); - } else if (rc != 0) { - rc = nsc_freeze(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: freeze")); - exit(255); - } - } else { - (void) fprintf(stderr, gettext("nscadm: device <%s> is " - "already frozen\n"), argv[optind+1]); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> frozen\n"), - argv[optind+1]); - } else if (strcoll(argv[optind], gettext("unfreeze")) == 0 || - strcmp(argv[optind], "unfreeze") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "unfreeze"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: unfreeze")); - exit(255); - } else if (rc == 0) { - rc = nsc_unfreeze(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: unfreeze")); - exit(255); - } - } else { - (void) fprintf(stderr, - gettext("nscadm: device <%s> is not " - "frozen\n"), argv[optind+1]); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> unfrozen\n"), - argv[optind+1]); - } else if (strcoll(argv[optind], gettext("isfrozen")) == 0 || - strcmp(argv[optind], "isfrozen") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "isfrozen"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: isfrozen")); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> is %sfrozen\n"), - argv[optind+1], rc ? gettext("not ") : ""); -#ifdef DEBUG - } else if (strcoll(argv[optind], gettext("nvclean")) == 0 || - strcmp(argv[optind], "nvclean") == 0) { - rc = nsc_nvclean(0); - if (rc < 0) { - perror(gettext("nscadm: nvclean")); - exit(255); - } - } else if (strcoll(argv[optind], gettext("nvclean_force")) == 0 || - strcmp(argv[optind], "nvclean_force") == 0) { - rc = nsc_nvclean(1); - if (rc < 0) { - perror(gettext("nscadm: nvclean_force")); - exit(255); - } -#endif /* DEBUG */ - } else if (strcoll(argv[optind], gettext("gmem")) == 0 || - strcmp(argv[optind], "gmem") == 0) { - rc = _nsc_gmem(); - if (rc < 0) { - perror(gettext("nscadm: gmem")); - exit(255); - } - } else { - usage(); - exit(255); - } - - return (rc); -} - - -static int -_nsc_gmem(void) -{ - char *addr; - int size; - int rc = 0; - - rc = nsc_gmem_sizes(&size); - - if (rc < 0) - return (rc); - - (void) printf(gettext("size %d\n"), size); - - if ((addr = (char *)malloc(size * 2)) == NULL) { - errno = ENOMEM; - return (-1); - } - - rc = nsc_gmem_data(addr); - - if (rc < 0) { - free(addr); - return (rc); - } - - (void) printf(gettext("Global map entries:\n")); - show_maps(addr, size); - - (void) printf(gettext("\nGlobal NVMEM map entries:\n")); - show_maps(addr + size, size); - - free(addr); - return (0); -} - - -static void -show_maps(char *addr, int len) -{ - /* LINTED alignment of cast ok */ - nsc_rmhdr_t *rhp = (nsc_rmhdr_t *)addr; - nsc_rmmap_t *rmap; - char tname[_NSC_MAXNAME + 1]; - int i; - - (void) printf( - gettext("magic 0x%x ver %d size %d dirty (nvmem systems): %d\n"), - rhp->magic, rhp->ver, rhp->size, rhp->rh_dirty); - - for (i = 0, rmap = rhp->map; - /* LINTED alignment of cast ok */ - rmap < (nsc_rmmap_t *)(addr + len); ++i, ++rmap) { - if (!rmap->name[0]) - continue; - (void) strncpy(tname, rmap->name, _NSC_MAXNAME); - (void) strcpy(&tname[strlen(tname)], " "); - tname[_NSC_MAXNAME] = '\0'; - (void) printf(gettext( - "%d:\tname %s\toffset 0x%x size 0x%x inuse 0x%x\n"), - i, tname, rmap->offset, rmap->size, rmap->inuse); - } -} diff --git a/usr/src/cmd/avs/nsctl/nskernd.c b/usr/src/cmd/avs/nsctl/nskernd.c deleted file mode 100644 index 1a205979d5..0000000000 --- a/usr/src/cmd/avs/nsctl/nskernd.c +++ /dev/null @@ -1,1000 +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/resource.h> -#include <sys/priocntl.h> -#include <sys/rtpriocntl.h> -#include <sys/tspriocntl.h> -#include <sys/wait.h> -#include <sys/stat.h> - -#include <strings.h> -#include <thread.h> -#include <stdlib.h> -#include <signal.h> -#include <errno.h> -#include <stdio.h> -#include <fcntl.h> -#include <locale.h> -#include <unistd.h> -#include <syslog.h> - -#include <sys/nsctl/cfg.h> -#include <sys/nsctl/nsctl.h> -#include <sys/nsctl/nsc_ioctl.h> -#include <sys/nskernd.h> -#include <nsctl.h> - -#include <sys/mkdev.h> -#include <sys/nsctl/sv_efi.h> - -static const char *rdev = "/dev/nsctl"; - -/* - * Define a minimal user stack size in bytes over and above the - * libthread THR_STACK_MIN minimum value. - * - * This stack size needs to be sufficient to run _newlwp() and then - * ioctl() down into the kernel. - */ -#define NSK_STACK_SIZE 512 - -/* - * LWP scheduling control switches. - * - * allow_pri - set to non-zero to enable priocntl() manipulations of - * created LWPs. - * allow_rt - set to non-zero to use the RT rather than the TS - * scheduling class when manipulating the schduling - * parameters for an LWP. Only used if allow_pri is - * non-zero. - */ -static int allow_pri = 1; -static int allow_rt = 0; /* disallow - bad interactions with timeout() */ - -static int nsctl_fd = -1; -static int sigterm; - -static int nthreads; /* number of threads in the kernel */ -static int exiting; /* shutdown in progress flag */ -static mutex_t thr_mutex = DEFAULTMUTEX; -static mutex_t cfg_mutex = DEFAULTMUTEX; - -static int cl_nodeid = -1; - -static int display_msg = 0; -static int delay_time = 30; - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("usage: nskernd\n")); - exit(255); -} - - -static void -sighand(int sig) -{ - if (sig == SIGTERM) { - sigterm++; - } -} - - -/* - * Returns: 1 - can enter kernel; 0 - shutdown in progress, do not enter kernel - */ -int -nthread_inc(void) -{ - (void) mutex_lock(&thr_mutex); - if (exiting) { - /* cannot enter kernel as nskernd is being shutdown - exit */ - (void) mutex_unlock(&thr_mutex); - return (0); - } - nthreads++; - (void) mutex_unlock(&thr_mutex); - return (1); -} - - -void -nthread_dec(void) -{ - (void) mutex_lock(&thr_mutex); - nthreads--; - (void) mutex_unlock(&thr_mutex); -} - - -/* - * returns: 1 - can shutdown; 0 - unable to shutdown - */ -int -canshutdown(void) -{ - int rc = 1; - time_t start_delay; - - (void) mutex_lock(&thr_mutex); - if (nthreads > 0) { - if (display_msg) { - (void) fprintf(stderr, - gettext("nskernd: unable to shutdown: " - "%d kernel threads in use\n"), nthreads); - } - start_delay = time(0); - while (nthreads > 0 && (time(0) - start_delay) < delay_time) { - (void) mutex_unlock(&thr_mutex); - (void) sleep(1); - (void) mutex_lock(&thr_mutex); - (void) fprintf(stderr, - gettext("nskernd: delay shutdown: " - "%d kernel threads in use\n"), nthreads); - } - if (nthreads > 0) { - rc = 0; - } else { - exiting = 1; - } - } else { - /* flag shutdown in progress */ - exiting = 1; - } - (void) mutex_unlock(&thr_mutex); - - return (rc); -} - - -/* - * returns: 1 - shutdown successful; 0 - unable to shutdown - */ -int -shutdown(void) -{ - struct nskernd data; - int rc; - - if (nsctl_fd < 0) - return (1); - - bzero(&data, sizeof (data)); - data.command = NSKERND_STOP; - - if (!canshutdown()) { - return (0); - } - - rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data); - if (rc < 0) { - if (errno != EINTR || !sigterm) { - (void) fprintf(stderr, - gettext("nskernd: NSKERND_STOP failed\n")); - } - } - - return (1); -} - - -/* - * First function run by a NSKERND_NEWLWP thread. - * - * Determines if it needs to change the scheduling priority of the LWP, - * and then calls back into the kernel. - */ -static void * -_newlwp(void *arg) -{ - struct nskernd nsk; - pcparms_t pcparms; - pcinfo_t pcinfo; - - /* copy arguments onto stack and free heap memory */ - bcopy(arg, &nsk, sizeof (nsk)); - free(arg); - - if (nsk.data2 && allow_pri) { - /* increase the scheduling priority of this LWP */ - - bzero(&pcinfo, sizeof (pcinfo)); - (void) strcpy(pcinfo.pc_clname, allow_rt ? "RT" : "TS"); - - if (priocntl(0, 0, PC_GETCID, (char *)&pcinfo) < 0) { - (void) fprintf(stderr, - gettext( - "nskernd: priocntl(PC_GETCID) failed: %s\n"), - strerror(errno)); - goto pri_done; - } - - bzero(&pcparms, sizeof (pcparms)); - pcparms.pc_cid = pcinfo.pc_cid; - - if (allow_rt) { - ((rtparms_t *)pcparms.pc_clparms)->rt_pri = - (pri_t)0; /* minimum RT priority */ - ((rtparms_t *)pcparms.pc_clparms)->rt_tqsecs = - (uint_t)RT_TQDEF; - ((rtparms_t *)pcparms.pc_clparms)->rt_tqnsecs = - RT_TQDEF; - } else { - ((tsparms_t *)pcparms.pc_clparms)->ts_uprilim = - ((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri; - ((tsparms_t *)pcparms.pc_clparms)->ts_upri = - ((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri; - } - - if (priocntl(P_LWPID, P_MYID, - PC_SETPARMS, (char *)&pcparms) < 0) { - (void) fprintf(stderr, - gettext( - "nskernd: priocntl(PC_SETPARMS) failed: %s\n"), - strerror(errno)); - } - } - -pri_done: - if (nthread_inc()) { - (void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk); - nthread_dec(); - } - return (NULL); -} - - -/* - * Start a new thread bound to an LWP. - * - * This is the user level side of nsc_create_process(). - */ -static void -newlwp(struct nskernd *req) -{ - struct nskernd *nskp; - thread_t tid; - int rc; - - nskp = malloc(sizeof (*nskp)); - if (!nskp) { -#ifdef DEBUG - (void) fprintf(stderr, gettext("nskernd: malloc(%d) failed\n"), - sizeof (*nskp)); -#endif - req->data1 = (uint64_t)ENOMEM; - return; - } - - /* copy args for child */ - bcopy(req, nskp, sizeof (*nskp)); - - rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE), - _newlwp, nskp, THR_BOUND|THR_DETACHED, &tid); - - if (rc != 0) { - /* thr_create failed */ -#ifdef DEBUG - (void) fprintf(stderr, - gettext("nskernd: thr_create failed: %s\n"), - strerror(errno)); -#endif - req->data1 = (uint64_t)errno; - free(nskp); - } else { - /* success - _newlwp() will free nskp */ - req->data1 = (uint64_t)0; - } -} - -static int -log_iibmp_err(char *set, int flags) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - char newflags[CFG_MAX_BUF]; - char outbuf[CFG_MAX_BUF]; - char *mst, *shd, *bmp, *mode, *ovr, *cnode, *opt, *grp; - int setno, found = 0; - int setlen; - int rc = 0; - pid_t pid = -1; - - if (set && *set) { - setlen = strlen(set); - } else { - return (EINVAL); - } - - (void) mutex_lock(&cfg_mutex); - cfg = cfg_open(""); - if (!cfg) { - (void) mutex_unlock(&cfg_mutex); - return (ENXIO); - } - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - - (void) mutex_unlock(&cfg_mutex); - cfg_close(cfg); - - pid = fork(); - - if (pid == -1) { - (void) fprintf(stderr, gettext( - "nskernd: Error forking\n")); - return (errno); - } else if (pid > 0) { - (void) fprintf(stdout, gettext( - "nskernd: Attempting deferred bitmap error\n")); - return (0); - } - - (void) mutex_lock(&cfg_mutex); - cfg = cfg_open(""); - if (!cfg) { - (void) mutex_unlock(&cfg_mutex); - (void) fprintf(stderr, gettext( - "nskernd: Failed cfg_open, deferred bitmap\n")); - return (ENXIO); - } - - /* Sooner or later, this lock will be free */ - while (!cfg_lock(cfg, CFG_WRLOCK)) - (void) sleep(2); - } - - /* find the proper set number */ - for (setno = 1; !found; setno++) { - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - - mst = strtok(buf, " "); - shd = strtok(NULL, " "); - if (strncmp(shd, set, setlen) == 0) { - found = 1; - - bmp = strtok(NULL, " "); - mode = strtok(NULL, " "); - ovr = strtok(NULL, " "); - cnode = strtok(NULL, " "); - opt = strtok(NULL, " "); - grp = strtok(NULL, " "); - break; - } - } - - if (found) { - /* were there flags in the options field already? */ - (void) snprintf(newflags, CFG_MAX_BUF, "%s=0x%x", - NSKERN_II_BMP_OPTION, flags); - if (opt && strcmp(opt, "-") != 0) { - bzero(newflags, CFG_MAX_BUF); - opt = strtok(opt, ";"); - while (opt) { - if (strncmp(opt, NSKERN_II_BMP_OPTION, - strlen(NSKERN_II_BMP_OPTION)) != 0) { - (void) strcat(newflags, ";"); - (void) strcat(newflags, opt); - } - } - } - (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno); - (void) snprintf(outbuf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s", - mst, shd, bmp, mode, ovr, cnode, newflags, grp); - if (cfg_put_cstring(cfg, key, outbuf, CFG_MAX_BUF) < 0) { - (void) printf("Failed to put [%s]\n", outbuf); - rc = ENXIO; - } else { - (void) cfg_commit(cfg); - rc = 0; - } - } else { - (void) fprintf(stderr, gettext( - "nskernd: Failed deferred bitmap [%s]\n"), set); - rc = EINVAL; - } - cfg_unlock(cfg); - cfg_close(cfg); - (void) mutex_unlock(&cfg_mutex); - - /* - * if we are the fork'ed client, just exit, if parent just return - */ - if (pid == 0) { - exit(rc); - /*NOTREACHED*/ - } else { - return (rc); - } -} - -/* - * First function run by a NSKERND_LOCK thread. - * - * Opens dscfg and locks it, - * and then calls back into the kernel. - * - * Incoming: - * data1 is the kernel address of the sync structure. - * data2 is read(0)/write(1) lock mode. - * - * Returns: - * data1 as incoming. - * data2 errno. - */ -static void * -_dolock(void *arg) -{ - struct nskernd nsk; - CFGFILE *cfg; - int locked; - int mode; - int rc = 0; - - /* copy arguments onto stack and free heap memory */ - bcopy(arg, &nsk, sizeof (nsk)); - free(arg); - - (void) mutex_lock(&cfg_mutex); - cfg = cfg_open(""); - if (cfg == NULL) { -#ifdef DEBUG - (void) fprintf(stderr, - gettext("nskernd: cfg_open failed: %s\n"), - strerror(errno)); -#endif - rc = ENXIO; - } - - if (nsk.data2 == 0) { - mode = CFG_RDLOCK; - } else { - mode = CFG_WRLOCK; - } - - locked = 0; - if (rc == 0) { - if (cfg_lock(cfg, mode)) { - locked = 1; - } else { -#ifdef DEBUG - (void) fprintf(stderr, - gettext("nskernd: cfg_lock failed: %s\n"), - strerror(errno)); -#endif - rc = EINVAL; - } - } - - /* return to kernel */ - - nsk.data2 = (uint64_t)rc; - if (nthread_inc()) { - (void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk); - nthread_dec(); - } - - /* cleanup */ - - if (locked) { - cfg_unlock(cfg); - locked = 0; - } - - if (cfg != NULL) { - cfg_close(cfg); - cfg = NULL; - } - (void) mutex_unlock(&cfg_mutex); - - return (NULL); -} - - -/* - * Inter-node lock thread. - * - * This is the user level side of nsc_rmlock(). - */ -static void -dolock(struct nskernd *req) -{ - struct nskernd *nskp; - thread_t tid; - int rc; - - /* create a new thread to do the lock and return to kernel */ - - nskp = malloc(sizeof (*nskp)); - if (!nskp) { -#ifdef DEBUG - (void) fprintf(stderr, - gettext("nskernd:dolock: malloc(%d) failed\n"), - sizeof (*nskp)); -#endif - req->data1 = (uint64_t)ENOMEM; - return; - } - - /* copy args for child */ - bcopy(req, nskp, sizeof (*nskp)); - - rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE), - _dolock, nskp, THR_BOUND|THR_DETACHED, &tid); - - if (rc != 0) { - /* thr_create failed */ -#ifdef DEBUG - (void) fprintf(stderr, - gettext("nskernd: thr_create failed: %s\n"), - strerror(errno)); -#endif - req->data1 = (uint64_t)errno; - free(nskp); - } else { - /* success - _dolock() will free nskp */ - req->data1 = (uint64_t)0; - } -} - - -/* - * Convenience code for engineering test of multi-terabyte volumes. - * - * zvol (part of zfs) does not support DKIOCPARTITION but does use EFI - * labels. This code allocates a simple efi label structure and ioctls - * to extract the size of a zvol. It only handles the minimal EFI ioctl - * implementation in zvol. - */ - -static void -zvol_bsize(char *path, uint64_t *size, const int pnum) -{ - struct stat64 stb1, stb2; - struct dk_minfo dkm; - int fd = -1; - int rc; - - if (cl_nodeid || pnum != 0) - return; - - if ((fd = open(path, O_RDONLY)) < 0) { - return; - } - - if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 || - fstat64(fd, &stb2) != 0 || - !S_ISCHR(stb1.st_mode) || - !S_ISCHR(stb2.st_mode) || - major(stb1.st_rdev) != major(stb2.st_rdev)) { - (void) close(fd); - return; - } - - rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm); - if (rc >= 0) { - *size = LE_64(dkm.dki_capacity) * - (dkm.dki_lbsize) / 512; - } - - (void) close(fd); -} - -/* ARGSUSED */ -static void -get_bsize(uint64_t raw_fd, uint64_t *size, int *partitionp, char *path) -{ - struct nscioc_bsize bsize; -#ifdef DKIOCPARTITION - struct partition64 p64; -#endif - struct dk_cinfo dki_info; - struct vtoc vtoc; - int fd; - - *partitionp = -1; - *size = (uint64_t)0; - - dki_info.dki_partition = (ushort_t)-1; - bsize.dki_info = (uint64_t)(unsigned long)&dki_info; - bsize.vtoc = (uint64_t)(unsigned long)&vtoc; - bsize.raw_fd = raw_fd; - bsize.efi = 0; - - fd = open(rdev, O_RDONLY); - if (fd < 0) - return; - - if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) { - if (dki_info.dki_partition != (ushort_t)-1) { - /* assume part# is ok and just the size failed */ - *partitionp = (int)dki_info.dki_partition; - -#ifdef DKIOCPARTITION - /* see if this is an EFI label */ - bzero(&p64, sizeof (p64)); - p64.p_partno = (uint_t)*partitionp; - if ((ioctl(fd, DKIOCPARTITION, &p64)) > 0) { - *size = (uint64_t)p64.p_size; - } else { - bsize.p64 = (uint64_t)(unsigned long)&p64; - bsize.efi = 1; - - if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) { - /* see if this is a zvol */ - zvol_bsize(path, size, *partitionp); - } else { - *size = (uint64_t)p64.p_size; - } - } -#endif /* DKIOCPARTITION */ - } - - (void) close(fd); - return; - } - - (void) close(fd); - - *partitionp = (int)dki_info.dki_partition; - - if (vtoc.v_sanity != VTOC_SANE) - return; - - if (vtoc.v_version != V_VERSION && vtoc.v_version != 0) - return; - - if (dki_info.dki_partition > V_NUMPAR) - return; - - *size = (uint64_t)vtoc.v_part[(int)dki_info.dki_partition].p_size; -} - - -static int -iscluster(void) -{ - /* - * Find out if we are running in a cluster - */ - cl_nodeid = cfg_iscluster(); - if (cl_nodeid > 0) { - return (TRUE); - } else if (cl_nodeid == 0) { - return (FALSE); - } - - (void) fprintf(stderr, "%s\n", - gettext("nskernd: unable to ascertain environment")); - exit(1); - /* NOTREACHED */ -} - -/* - * Runtime Solaris release checking - build release == runtime release - * is always considered success, so only keep entries in the map for - * the special cases. - */ -static nsc_release_t nskernd_rel_map[] = { -/* { "5.10", "5.10" }, */ - { "5.11", "5.10" }, - { NULL, NULL } -}; - - -#ifdef lint -#define main nskernd_main -#endif -/* ARGSUSED1 */ -int -main(int argc, char *argv[]) -{ - const char *dir = "/"; - struct nskernd data; - struct rlimit rl; - int i, run, rc; - int partition; - char *reqd; - int syncpipe[2]; - int startup; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("nskernd"); - - rc = nsc_check_release(BUILD_REV_STR, nskernd_rel_map, &reqd); - if (rc < 0) { - (void) fprintf(stderr, - gettext("nskernd: unable to determine the current " - "Solaris release: %s\n"), strerror(errno)); - exit(1); - } else if (rc == FALSE) { - (void) fprintf(stderr, - gettext("nskernd: incorrect Solaris release " - "(requires %s)\n"), reqd); - exit(1); - } - - rc = 0; - - if (argc != 1) - usage(); - - /* - * Usage: <progname> [-g] [-d <seconds to delay>] - */ - while ((i = getopt(argc, argv, "gd:")) != EOF) { - switch (i) { - case 'g': - display_msg = 1; - break; - case 'd': - delay_time = atoi(optarg); - if (delay_time <= 0) { - delay_time = 30; - } - break; - default: - syslog(LOG_ERR, - "Usage: nskernd [-g] [-d <seconds to delay>]"); - exit(1); - break; - } - } - - if (chroot(dir) < 0) { - (void) fprintf(stderr, gettext("nskernd: chroot failed: %s\n"), - strerror(errno)); - exit(1); - } - - if (chdir(dir) < 0) { - (void) fprintf(stderr, gettext("nskernd: chdir failed: %s\n"), - strerror(errno)); - exit(1); - } - - /* - * Determine if we are in a Sun Cluster or not, before fork'ing - */ - (void) iscluster(); - - /* - * create a pipe to synchronise the parent with the - * child just before it enters its service loop. - */ - if (pipe(syncpipe) < 0) { - (void) fprintf(stderr, - gettext("nskernd: cannot create pipe: %s\n"), - strerror(errno)); - exit(1); - } - /* - * Fork off a child that becomes the daemon. - */ - - if ((rc = fork()) > 0) { - char c; - int n; - (void) close(syncpipe[1]); - /* - * wait for the close of the pipe. - * If we get a char back, indicates good - * status from child, so exit 0. - * If we get a zero length read, then the - * child has failed, so we do too. - */ - n = read(syncpipe[0], &c, 1); - exit((n <= 0) ? 1 : 0); - } else if (rc < 0) { - (void) fprintf(stderr, gettext("nskernd: cannot fork: %s\n"), - strerror(errno)); - exit(1); - } - - /* - * In child - become daemon. - */ - - /* use closefrom(3C) from PSARC/2000/193 when possible */ - for (i = 0; i < syncpipe[1]; i++) { - (void) close(i); - } - closefrom(syncpipe[1] + 1); - - (void) open("/dev/console", O_WRONLY|O_APPEND); - (void) dup(0); - (void) dup(0); - (void) close(0); - - (void) setpgrp(); - - /* - * Ignore all signals apart from SIGTERM. - */ - - for (i = 1; i < _sys_nsig; i++) - (void) sigset(i, SIG_IGN); - - (void) sigset(SIGTERM, sighand); - - /* - * Increase the number of fd's that can be open. - */ - - rl.rlim_cur = RLIM_INFINITY; - rl.rlim_max = RLIM_INFINITY; - if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { - (void) fprintf(stderr, - gettext("nskernd: could not increase RLIMIT_NOFILE: %s\n"), - strerror(errno)); - (void) fprintf(stderr, - gettext("nskernd: the maximum number of nsctl open " - "devices may be reduced\n")); - } - - /* - * Open /dev/nsctl and startup. - */ - - nsctl_fd = open(rdev, O_RDONLY); - if (nsctl_fd < 0) { - (void) fprintf(stderr, gettext("nskernd: unable to open %s\n"), - rdev); - exit(1); - } - - bzero(&data, sizeof (data)); - - data.command = NSKERND_START; - data.data1 = (uint64_t)cl_nodeid; - run = 1; - - startup = 1; - while (run) { - rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data); - if (rc < 0) { - /* try and do kernel cleanup and exit */ - if (shutdown()) { - run = 0; - } else { - sigterm = 0; - } - - (void) fprintf(stderr, - gettext("nskernd: NSCIOC_NSKERND failed: %s\n"), - strerror(errno)); - continue; - } else if (sigterm) { - /* SIGTERM received - terminate */ - if (data.command != NSKERND_START && - (data.command != NSKERND_STOP || - data.data1 != (uint64_t)1)) { - /* need to do kernel cleanup */ - if (shutdown()) { - run = 0; - } else { - sigterm = 0; - data.command = NSKERND_START; - data.data1 = (uint64_t)cl_nodeid; - } - } else { - /* just quit */ - if (canshutdown()) { - run = 0; - } else { - /* cannot shutdown - threads active */ - sigterm = 0; - data.command = NSKERND_START; - data.data1 = (uint64_t)cl_nodeid; - } - } - continue; - } - if (startup) { - char c = 0; - (void) write(syncpipe[1], &c, 1); - (void) close(syncpipe[1]); - startup = 0; - } - switch (data.command) { - case NSKERND_START: /* (re)start completion */ - if (rc == 1) { - (void) fprintf(stderr, - gettext("nskernd: already started\n")); - run = 0; - } else if (rc == 2) { - (void) fprintf(stderr, - gettext("nskernd: stopped by kernel\n")); - run = 0; - } - data.command = NSKERND_WAIT; - break; - - case NSKERND_STOP: /* kernel telling daemon to stop */ - if (data.data1 != (uint64_t)1) { - (void) shutdown(); - run = 0; - } - break; - - case NSKERND_BSIZE: - /* - * kernel requesting partsize - * data1 - size return - * data2 - raw_fd (entry) - * - partition number (return) - */ - partition = -1; - get_bsize(data.data2, &data.data1, - &partition, data.char1); - data.data2 = (uint64_t)partition; - data.command = NSKERND_WAIT; - break; - - case NSKERND_NEWLWP: /* kernel requesting a new LWP */ - newlwp(&data); - data.command = NSKERND_WAIT; - break; - - case NSKERND_LOCK: /* kernel requesting lock */ - dolock(&data); - data.command = NSKERND_WAIT; - break; - - case NSKERND_WAIT: /* kernel retrying wait */ - /* - * the kernel thread can be woken by the dr config - * utilities (ie cfgadm) therefore we just reissue - * the wait. - */ - break; - - case NSKERND_IIBITMAP: - rc = log_iibmp_err(data.char1, (int)data.data1); - data.data1 = (uint64_t)rc; - data.command = NSKERND_WAIT; - break; - - default: - (void) fprintf(stderr, - gettext("nskernd: unknown command %d"), - data.command); - data.command = NSKERND_WAIT; - break; - } - } - - (void) close(nsctl_fd); - - return (rc); -} diff --git a/usr/src/cmd/avs/rdc/Makefile b/usr/src/cmd/avs/rdc/Makefile deleted file mode 100644 index 1148884422..0000000000 --- a/usr/src/cmd/avs/rdc/Makefile +++ /dev/null @@ -1,118 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# - -DYNPROG = sndrd sndradm sndrboot sndrsyncd - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -SUBDIRS= etc - -sndradm := POBJS = sndradm.o rdc_ioctl.o sndrsubr.o -sndrboot := POBJS = sndrboot.o rdc_ioctl.o sndrsubr.o -sndrd := POBJS = sndrd.o -sndrsyncd := POBJS = sndrsyncd.o rdc_ioctl.o sndrsubr.o - -OBJS= \ - sndrboot.o \ - sndradm.o \ - sndrd.o \ - sndrsyncd.o \ - rdc_ioctl.o \ - sndrsubr.o - -XTRA_OBJS= \ - sdbc_ioctl.o - -SRCS= $(OBJS:%.o=%.c) ../sdbc/sdbc_ioctl.c - -sndradm := LDLIBS += -lrdc -lunistat -ldscfg -lnsctl -lnsl -sndrboot := LDLIBS += -lrdc -lunistat -ldscfg -sndrd := LDLIBS += -lrdc -lnsl -sndrsyncd := LDLIBS += -lrdc -ldscfg -lunistat - -CFLAGS += $(CCVERBOSE) -D_RDC_ -D_SYSCALL32 -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -D_RDC_ -D_SYSCALL32 -LINTFLAGS += -DDEBUG -LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -LINTFLAGS += -erroff=E_FUNC_SET_NOT_USED -CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-uninitialized -POFILE = rdc_all.po -POFILES = sndradm.po sndrboot.po -ROOTLIBLINKS = $(ROOTLIB)/sndrd $(ROOTLIB)/sndrsyncd -ROOTUSRSBINLINKS = $(ROOTUSRSBIN)/sndradm $(ROOTUSRSBIN)/sndrboot - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) $(XTRA_OBJS) - -all: $(SUBDIRS) $(PROG) $(POFILES) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLIBLINKS) $(ROOTUSRSBINLINKS) - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o $(POFILES) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -sdbc_ioctl.o: ../sdbc/sdbc_ioctl.c - $(COMPILE.c) ../sdbc/sdbc_ioctl.c - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(ROOTLIBLINKS): $(ROOTLIB) $(ROOTPROG) - -$(RM) $(ROOTLIBLINKS); - $(LN) $(ROOTBIN)/sndrd $(ROOTLIB)/sndrd; - $(LN) $(ROOTBIN)/sndrsyncd $(ROOTLIB)/sndrsyncd - -$(ROOTUSRSBINLINKS): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $(ROOTUSRSBINLINKS); - $(LN) $(ROOTBIN)/sndradm $(ROOTUSRSBIN)/sndradm; - $(LN) $(ROOTBIN)/sndrboot $(ROOTUSRSBIN)/sndrboot - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/rdc/etc/Makefile b/usr/src/cmd/avs/rdc/etc/Makefile deleted file mode 100644 index cbe78b12a2..0000000000 --- a/usr/src/cmd/avs/rdc/etc/Makefile +++ /dev/null @@ -1,71 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -include ../../../Makefile.cmd -include ../../Makefile.com - -PROG1 = rdc -PROG2 = rdcfinish -PROG3 = rdc.cluster -SHFILES = $(PROG1) $(PROG2) $(PROG3) -ROOTINIT_D = $(ROOTETC)/init.d - -FILEMODE = 0744 - -ROOTETCFILES= $(ETCFILES:%=$(ROOTETC)/%) - -ROOTINIT_DPROG1 = $(ROOTINIT_D)/$(PROG1) -ROOTINIT_DPROG2 = $(ROOTINIT_D)/$(PROG2) -ROOTINIT_DPROG3 = $(ROOTINIT_D)/$(PROG3) - -.KEEP_STATE: - -all: $(SHFILES) $(ETCFILES) $(INITFILES) - -install: $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2) $(ROOTINIT_DPROG3) $(ROOTLIBSVCMETHOD) $(CLUSTERSBINDIR) - -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/15rdc - -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/10rdc - -$(RM) $(ROOTLIBSVCMETHOD)/svc-rdc - -$(RM) $(ROOTLIBSVCMETHOD)/svc-rdcsyncd - -$(RM) $(CLUSTERSBINDIR)/rdc - -$(SYMLINK) ../../../sbin/rdc $(CLUSTERLIBDSCFGSTOPDIR)/15rdc - -$(SYMLINK) ../../../sbin/rdc $(CLUSTERLIBDSCFGSTARTDIR)/10rdc - $(LN) $(ROOTINIT_D)/rdc $(ROOTLIBSVCMETHOD)/svc-rdc - $(LN) $(ROOTINIT_D)/rdcfinish $(ROOTLIBSVCMETHOD)/svc-rdcsyncd - $(CP) $(ROOTINIT_D)/rdc.cluster $(CLUSTERSBINDIR)/rdc - -$(ROOTINIT_DPROG1): $(PROG1) - $(INS.file) $(PROG1) - -$(ROOTINIT_DPROG2): $(PROG2) - $(INS.file) $(PROG2) - -$(ROOTINIT_DPROG3): $(PROG3) - $(INS.file) $(PROG3) - -clean: - $(RM) $(SHFILES) - -clobber: clean - -lint: diff --git a/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh b/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh deleted file mode 100644 index 2d6d0621df..0000000000 --- a/usr/src/cmd/avs/rdc/etc/rdc.cluster.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/ksh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# SNDR start script -# -# Description: This is the SNDR switchover script. -# It is used to start or stop a specified cluster -# resource group when invoked from the data service cluster -# failover script. -# - -PATH=/etc:/bin -RDCBOOT="/usr/sbin/sndrboot" -RDCSYNCD="/usr/lib/sndrsyncd" -USAGE="Usage: $0 {start|stop} cluster_resource" - -SVCS=/usr/bin/svcs -SVCS_NAME=system/nws_rdc - -# Determine if SMF service is online -# -ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"` -if [ -z $ONLINE ] -then - echo "$SVCS_NAME not online" - exit 1 -fi - -if [[ -z "$2" ]] -then - echo "$USAGE" - exit 1 -fi - -case "$1" in -'start') - if [[ -x $RDCBOOT ]] - then - $RDCBOOT -r -C "$2" - fi - ;; - -'stop') - if [[ -x $RDCBOOT ]] - then - $RDCBOOT -s -C "$2" - fi - ;; - -*) - echo $USAGE - exit 1 - ;; -esac diff --git a/usr/src/cmd/avs/rdc/etc/rdc.sh b/usr/src/cmd/avs/rdc/etc/rdc.sh deleted file mode 100644 index 198d1186b2..0000000000 --- a/usr/src/cmd/avs/rdc/etc/rdc.sh +++ /dev/null @@ -1,186 +0,0 @@ -#!/bin/sh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# SNDR start script -# -# Description: This is the SNDR start script. It must be located -# in /etc/init.d with links to the appropriate rc2.d and -# rc0.d files. -# It can also be used to start or stop a specified cluster -# resource group when invoked from the data service cluster -# failover script. -# -# -# -PATH=/etc:/bin -RDCBOOT="/usr/sbin/sndrboot" -USAGE="Usage: $0 {start|stop} [cluster_resource]" -SVCS=/usr/bin/svcs -DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" -OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2` - -. /lib/svc/share/smf_include.sh - -# Make sure prior SMF dependents are not 'online' -# $1 = name of SMF service to validate dependents -# -do_smf_depends () -{ - times=0 - count=1 - - if [ $OS_MINOR -ge 11 ] - then - return 0 - elif [ -f $DSCFG_DEPEND_NOCHK ] - then - for pid in `pgrep dscfgadm` - do - if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ] - then - return 0 - fi - done - elif [ `ps -ef | grep preremove | grep -c SUNWrdcu` -gt 0 ] - then - return 0 - - fi - - while [ $count -ne 0 ] - do - count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l` - if [ $count -ne 0 ] - then - # Output banner after waiting first 5 seconds - # - if [ $times -eq 1 ] - then - echo "Waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - fi - - # Has it been longer then 5 minutes? (60 * 5 secs.) - # - if [ $times -eq 60 ] - then - echo "Error: Failed waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - exit $SMF_EXIT_ERR_FATAL - fi - - # Now sleep, giving other services time to stop - # - sleep 5 - times=`expr $times + 1` - fi - done - return 0 -} - -CLINFO=/usr/sbin/clinfo - -killproc() { # kill the named process(es) - pid=`/usr/bin/ps -e | - /usr/bin/grep -w $1 | - /usr/bin/sed -e 's/^ *//' -e 's/ .*//'` - [ "$pid" != "" ] && kill $pid -} - - -case "$1" in -'start') - COPT= - - if [ -x ${RDCBOOT} ] - then - if ${CLINFO} - then - if [ "$2" != "" ] - then - ${RDCBOOT} -r -C $2 - else - # SNDR 3.2 SetIDs fixup - ${RDCBOOT} -C post-patch-setids -r -s - - COPT="-C -" - ${RDCBOOT} ${COPT} -r - fi - else - # non-clustered start - ${RDCBOOT} -r - fi - fi - ;; - -'stop') - COPT= - - if [ ! -r /dev/rdc ] - then - RDCBOOT=/usr/bin/true - fi - - do_smf_depends "system/nws_rdc" - - if [ -x ${RDCBOOT} ] - then - if ${CLINFO} - then - if [ "$2" != "" ] - then - ${RDCBOOT} -s -C $2 - else - COPT="-C -" - ${RDCBOOT} ${COPT} -s - - echo "killing SNDR daemons" - killproc sndrd - killproc sndrsync - fi - else - # non-clustered stop - - ${RDCBOOT} -s - - echo "killing SNDR daemons" - killproc sndrd - killproc sndrsync - fi - else - # no sndr boot command, kill daemon anyway - - echo "killing SNDR daemons" - killproc sndrd - killproc sndrsync - fi - - ;; - -*) - echo $USAGE - exit 1 - ;; -esac -exit $SMF_EXIT_OK diff --git a/usr/src/cmd/avs/rdc/etc/rdcfinish.sh b/usr/src/cmd/avs/rdc/etc/rdcfinish.sh deleted file mode 100644 index f0cc2f1b8e..0000000000 --- a/usr/src/cmd/avs/rdc/etc/rdcfinish.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Second SNDR start script -# - called after the TCP/IP stack has been initialised, -# and networking enabled. -# -# - should be linked to /etc/rc2.d/S72rdcfinish as follows: -# -# ln /etc/init.d/rdc /etc/rc2.d/S72rdcfinish -# -PATH=/etc:/bin -RDCD="/usr/lib/sndrd" -RDCSYNCD="/usr/lib/sndrsyncd" -USAGE="Usage: $0 start" - -. /lib/svc/share/smf_include.sh - -case "$1" in -'start') - echo "Completing SNDR startup:\c" - - ## - ## Start sndrd - ## - - if [ ! -f ${RDCD} ] - then - echo "Cannot find ${RDCD}.\nSNDR services unavailable." > /dev/console - exit $SMF_EXIT_MON_OFFLINE - fi - - ps -e | grep sndrd > /dev/null 2>&1 - if [ $? -ne 0 ]; then - ${RDCD} - echo " sndrd\c" - else - echo " sndrd already enabled\c" - fi - - ## - ## Start sndrsyncd - ## - - if [ ! -f ${RDCSYNCD} ] - then - echo "\nCannot find ${RDCSYNCD}.\nSNDR start aborted." > /dev/console - exit $SMF_EXIT_MON_OFFLINE - fi - - ps -e | grep sndrsyn > /dev/null 2>&1 - if [ $? -ne 0 ]; then - ${RDCSYNCD} - echo " sndrsyncd\c" - else - echo " sndrsyncd already running\c" - fi - - echo " done" - ;; -'stop') - # Inserted for symmetry - ;; -*) - echo $USAGE - exit 1 - ;; -esac -exit $SMF_EXIT_OK diff --git a/usr/src/cmd/avs/rdc/rdc_ioctl.c b/usr/src/cmd/avs/rdc/rdc_ioctl.c deleted file mode 100644 index 1fcd85669d..0000000000 --- a/usr/src/cmd/avs/rdc/rdc_ioctl.c +++ /dev/null @@ -1,87 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * RDC user level ioctl interface - */ - -#include <stdio.h> -#include <unistd.h> -#include <sys/types.h> -#include <fcntl.h> - -#include <sys/nsctl/sd_cache.h> -#include <sys/nsctl/sd_conf.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> - -const char *__rdc_dev = "/dev/rdc"; -static int __rdc_fd; - - -static int -__rdc_open(void) -{ - int fd = open(__rdc_dev, O_RDONLY); - - if (fd < 0) - return (-1); - - return (__rdc_fd = fd); -} - - -int -rdc_ioctl(long cmd, long a0, long a1, long a2, long a3, long a4, - spcs_s_info_t ustatus) -{ - _rdc_ioctl_t args; - - if (!__rdc_fd && __rdc_open() < 0) - return (-1); - - args.arg0 = a0; - args.arg1 = a1; - args.arg2 = a2; - args.arg3 = a3; - args.arg4 = a4; - args.magic = RDC_MAGIC; /* for versioning */ - args.ustatus = ustatus; - - return (ioctl(__rdc_fd, cmd, &args)); -} - -/* - * Simple form of the ioctl, just pass the command and buffer address - * to the kernel. - */ -int -rdc_ioctl_simple(long cmd, void *addr) -{ - if (!__rdc_fd && __rdc_open() < 0) - return (-1); - return (ioctl(__rdc_fd, cmd, addr)); -} diff --git a/usr/src/cmd/avs/rdc/rdcadm.h b/usr/src/cmd/avs/rdc/rdcadm.h deleted file mode 100644 index 6ad0c05731..0000000000 --- a/usr/src/cmd/avs/rdc/rdcadm.h +++ /dev/null @@ -1,67 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _RDCADM_H -#define _RDCADM_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#define MAXQFBAS 0 -#define MAXQITEMS 0 -#define ASYNCTHR 0 -#define AUTOSYNC -1 -#define AUTOSYNC_OFF 0 -#define AUTOSYNC_ON 1 -#define QBLOCK 0 - -extern int maxqfbas; -extern int maxqitems; -extern int autosync; -extern int asyncthr; -extern int qblock; - -extern char *rdc_decode_flag(int, int); -extern void rdc_err(spcs_s_info_t *status, char *string, ...); -extern void rdc_warn(spcs_s_info_t *status, char *string, ...); -extern int rdc_get_maxsets(); -extern int mounted(char *device); -extern int get_cfg_setid(CFGFILE *cfg, char *ctag, char *tohost, char *tofile); -extern int get_new_cfg_setid(CFGFILE *cfg); -extern void get_group_diskq(CFGFILE *cfg, char *group, char *diskq); -extern int find_setnumber_in_libcfg(CFGFILE *, char *, char *, char *); -extern int sv_enable(char *, CFGFILE *, char *); -extern void block_sigs(void); -extern void unblock_sigs(void); - -extern char *program; - -#ifdef __cplusplus -} -#endif - -#endif /* _RDCADM_H */ diff --git a/usr/src/cmd/avs/rdc/sndradm.c b/usr/src/cmd/avs/rdc/sndradm.c deleted file mode 100644 index 4bcb3008dd..0000000000 --- a/usr/src/cmd/avs/rdc/sndradm.c +++ /dev/null @@ -1,5715 +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/utsname.h> -#include <sys/wait.h> -#include <stdio.h> -#include <errno.h> -#include <values.h> -#include <limits.h> -#include <fcntl.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/stat.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> -#include <netdb.h> -#include <ctype.h> - -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_prot.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/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netinet/tcp.h> -#include <rpc/rpc_com.h> -#include <rpc/rpc.h> - -#include <sys/nsctl/librdc.h> -#include <sys/nsctl/nsc_hash.h> - -#include "rdcadm.h" - -/* - * support for the special cluster tag "local" to be used with -C in a - * cluster for local volumes. - */ - -#define RDC_LOCAL_TAG "local" - -typedef struct volcount_s { - int count; -} volcount_t; -hash_node_t **volhash = NULL; - -/* - * rdc_islocal is only pertinent while creating the pairs array. - * after all the pairs are set, its value is useless, retaining - * the last value it was set to. - * its only reason in life is to suppress an error message in 2 - * places where the inappropriate becomes appropriate (a supplied - * ctag which does not match an implied one cfg_dgame()). This - * happens when C "local" is supplied. It is then used to make an - * error message clearer. A - * gettext("set %s does not match", rdc_islocal < 1?dga:dgb) situation - */ -static int rdc_islocal = 0; - -char *program; - -#define min(a, b) ((a) > (b) ? (b) : (a)) - -static char place_holder[] = "-"; /* cfg place holder value */ - -/* - * config file user level Dual copy pair structure - */ -typedef struct _sd_dual_pair { - char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */ - char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */ - char ffile[NSC_MAXPATH]; /* Primary device */ - char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */ - char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */ - char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */ - char tfile[NSC_MAXPATH]; /* Secondary device */ - char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */ - char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */ - char group[NSC_MAXPATH]; /* Group name */ - char ctag[MAX_RDC_HOST_SIZE]; /* Cluster resource name tag */ - char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */ - int doasync; /* Device is in sync/async mode */ -} _sd_dual_pair_t; - -#define EXTRA_ARGS 6 /* g grp C ctag q diskqueue */ - -static int rdc_operation( - CFGFILE *, char *, char *, char *, char *, char *, char *, - int, int, char *, char *, char *, char *, int *, int); -int read_config(int, char *, char *, char *); -static int read_libcfg(int, char *, char *); -int prompt_user(int, int); -static void rdc_check_dgislocal(char *); -void process_clocal(char *); -static void usage(void); -void q_usage(int); -static void load_rdc_vols(CFGFILE *); -static void unload_rdc_vols(); -static int perform_autosv(); -static void different_devs(char *, char *); -static void validate_name(CFGFILE *, char *); -static void set_autosync(int, char *, char *, char *); -static int autosync_is_on(char *tohost, char *tofile); -static void enable_autosync(char *fhost, char *ffile, char *thost, char *tfile); -static void checkgfields(CFGFILE *, int, char *, char *, char *, char *, - char *, char *, char *, char *, char *); -static void checkgfield(CFGFILE *, int, char *, char *, char *); -static int rdc_bitmapset(char *, char *, char *, int, nsc_off_t); -static int parse_cfg_buf(char *, _sd_dual_pair_t *, char *); -static void verify_groupname(char *grp); -extern char *basename(char *); - -int rdc_maxsets; -static _sd_dual_pair_t *pair_list; - -struct netbuf svaddr; -struct netbuf *svp; -struct netconfig nconf; -struct netconfig *conf; -struct knetconfig knconf; - -static char *reconfig_pbitmap = NULL; -static char *reconfig_sbitmap = NULL; -#ifdef _RDC_CAMPUS -static char *reconfig_direct = NULL; -#endif -static char *reconfig_group = NULL; -static char reconfig_ctag[MAX_RDC_HOST_SIZE]; -static int reconfig_doasync = -1; - -static int clustered = 0; -static int proto_test = 0; -int allow_role = 0; - - -static char * -rdc_print_state(rdc_set_t *urdc) -{ - if (!urdc) - return (""); - - if (urdc->sync_flags & RDC_VOL_FAILED) - return (gettext("volume failed")); - else if (urdc->sync_flags & RDC_FCAL_FAILED) - return (gettext("fcal failed")); - else if (urdc->bmap_flags & RDC_BMP_FAILED) - return (gettext("bitmap failed")); - else if (urdc->flags & RDC_DISKQ_FAILED) - return (gettext("disk queue failed")); - else if (urdc->flags & RDC_LOGGING) { - if (urdc->sync_flags & RDC_SYNC_NEEDED) - return (gettext("need sync")); - else if (urdc->sync_flags & RDC_RSYNC_NEEDED) - return (gettext("need reverse sync")); - else if (urdc->flags & RDC_QUEUING) - return (gettext("queuing")); - else - return (gettext("logging")); - } else if ((urdc->flags & RDC_SLAVE) && (urdc->flags & RDC_SYNCING)) { - if (urdc->flags & RDC_PRIMARY) - return (gettext("reverse syncing")); - else - return (gettext("syncing")); - } else if (urdc->flags & RDC_SYNCING) { - if (urdc->flags & RDC_PRIMARY) - return (gettext("syncing")); - else - return (gettext("reverse syncing")); - } - - return (gettext("replicating")); -} - - -static int -rdc_print(int file_format, int verbose, char *group_arg, char *ctag_arg, - char *user_shost, char *user_sdev, CFGFILE *cfgp) -{ - rdc_status_t *rdc_status; - spcs_s_info_t ustatus; - rdc_set_t *urdc; - size_t size; - int i, rc, max; - char *tohost, *tofile; - _sd_dual_pair_t pair; - char *tmptohost = pair.thost; - char *tmptofile = pair.tfile; - char *fromhost = pair.fhost; - char *fromfile = pair.ffile; - char *frombitmap = pair.fbitmap; - char *tobitmap = pair.tbitmap; - char *directfile = pair.directfile; - char *group = pair.group; - char *diskqueue = pair.diskqueue; - char *ctag = pair.ctag; - CFGFILE *cfg; - int j; - int setnumber; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - char sync[16]; - int match, found; - - size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1)); - match = (user_shost != NULL || user_sdev != NULL); - found = 0; - - if (user_shost == NULL && user_sdev != NULL) - user_shost = ""; - else if (user_shost != NULL && user_sdev == NULL) - user_sdev = ""; - - rdc_status = malloc(size); - if (!rdc_status) { - rdc_err(NULL, - gettext("unable to allocate %ld bytes"), size); - } - - rdc_status->nset = rdc_maxsets; - ustatus = spcs_s_ucreate(); - - rc = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustatus); - if (rc == SPCS_S_ERROR) { - rdc_err(&ustatus, gettext("statistics error")); - } - - spcs_s_ufree(&ustatus); - - max = min(rdc_status->nset, rdc_maxsets); - - if (cfgp != NULL) { - cfg = cfgp; - cfg_rewind(cfg, CFG_SEC_CONF); - } else { - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - } - - for (i = 0; i < max; i++) { - urdc = &rdc_status->rdc_set[i]; - - if (!(urdc->flags & RDC_ENABLED)) - continue; - - if (match && - (strcmp(user_shost, urdc->secondary.intf) != 0 || - strcmp(user_sdev, urdc->secondary.file) != 0)) - continue; - - tohost = urdc->secondary.intf; - tofile = urdc->secondary.file; - found = 1; - - /* get sndr entries until shost, sfile match */ - for (j = 0; j < rdc_maxsets; j++) { - setnumber = j + 1; - (void) snprintf(key, sizeof (key), - "sndr.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - - if (parse_cfg_buf(buf, &pair, NULL)) - rdc_err(NULL, gettext("cfg input error")); - - if (strcmp(tmptofile, tofile) != 0) - continue; - if (strcmp(tmptohost, tohost) != 0) - continue; - - if (pair.doasync == 0) - (void) strcpy(sync, "sync"); - else - (void) strcpy(sync, "async"); - - /* Got the matching entry */ - - break; - } - - if (j == rdc_maxsets) - continue; /* not found in config */ - - if (strcmp(group_arg, "") != 0 && - strncmp(group_arg, group, NSC_MAXPATH) != 0) - continue; - - if (strcmp(ctag_arg, "") != 0 && - strncmp(ctag_arg, ctag, MAX_RDC_HOST_SIZE) != 0) - continue; - - if (file_format) { - (void) printf("%s %s %s %s %s %s %s %s", - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - directfile, sync); - if (strlen(group) != 0) - (void) printf(" g %s", group); - if ((strlen(ctag) != 0) && (ctag[0] != '-')) - (void) printf(" C %s", ctag); - if (strlen(diskqueue) != 0) - (void) printf(" q %s", diskqueue); - (void) printf("\n"); - continue; - } - - if (strcmp(group_arg, "") != 0 && - strncmp(group_arg, urdc->group_name, NSC_MAXPATH) != 0) - continue; - - if (!(urdc->flags & RDC_PRIMARY)) { - (void) printf(gettext("%s\t<-\t%s:%s\n"), - urdc->secondary.file, urdc->primary.intf, - urdc->primary.file); - } else { - (void) printf(gettext("%s\t->\t%s:%s\n"), - urdc->primary.file, urdc->secondary.intf, - urdc->secondary.file); - } - if (!verbose) - continue; - - if (urdc->autosync) - (void) printf(gettext("autosync: on")); - else - (void) printf(gettext("autosync: off")); - - (void) printf(gettext(", max q writes: %lld"), urdc->maxqitems); - (void) printf(gettext(", max q fbas: %lld"), urdc->maxqfbas); - (void) printf(gettext(", async threads: %d"), - urdc->asyncthr); - (void) printf(gettext(", mode: %s"), - pair.doasync ? "async" : "sync"); - - if (strlen(urdc->group_name) != 0) - (void) printf(gettext(", group: %s"), urdc->group_name); - if ((strlen(ctag) != 0) && (ctag[0] != '-')) - (void) printf(gettext(", ctag: %s"), ctag); - if (strlen(urdc->disk_queue) != 0) { - (void) printf(gettext(", %s diskqueue: %s"), - (urdc->flags & RDC_QNOBLOCK) ? gettext("non blocking") : - gettext("blocking"), urdc->disk_queue); - } - - (void) printf(gettext(", state: %s"), rdc_print_state(urdc)); - (void) printf(gettext("\n")); - - } - - if (!cfgp) - cfg_close(cfg); - - free(rdc_status); - - if (match && !found) { - rdc_warn(NULL, gettext("unable to find set %s:%s"), - user_shost, user_sdev); - } - - return (0); -} - - -int -parse_extras(int argc, char *args[], int i) -{ - int gflag = 0; - int Cflag = 0; - int qflag = 0; - int j; - - (void) strcpy(pair_list[i].ctag, ""); - (void) strcpy(pair_list[i].group, ""); - (void) strcpy(pair_list[i].diskqueue, ""); - - if (argc == 0) - return (0); - - if (argc != 2 && argc != 4 && argc != 6) - return (-1); - - for (j = 0; j < argc; j += 2) { - if (strcmp(args[j], "g") == 0) { - if (gflag) - return (-1); - (void) strncpy(pair_list[i].group, args[j + 1], - NSC_MAXPATH); - gflag = 1; - } - if (strcmp(args[j], "C") == 0) { - if (!clustered) - return (-1); - if (Cflag) - return (-1); - (void) strncpy(pair_list[i].ctag, args[j + 1], - MAX_RDC_HOST_SIZE); - process_clocal(pair_list[i].ctag); - Cflag = 1; - } - if (strcmp(args[j], "q") == 0) { - if (qflag) - return (-1); - (void) strncpy(pair_list[i].diskqueue, args[j + 1], - NSC_MAXPATH); - qflag = 1; - } - } - - return (0); -} - -static int -parse_cfg_buf(char *buf, _sd_dual_pair_t *pair, char *lghn) -{ - int rc = 0; - char sync[16]; - char options[64], *p, *q; - int len; - - rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s", pair->fhost, - pair->ffile, pair->fbitmap, pair->thost, pair->tfile, - pair->tbitmap, pair->directfile, sync, pair->group, - pair->ctag, options, pair->diskqueue); - - if (rc != 12) - rdc_err(NULL, gettext("cfg input error")); - - if (strcmp(pair->diskqueue, place_holder) == 0) - (void) strcpy(pair->diskqueue, ""); - - if (strcmp(pair->group, place_holder) == 0) - (void) strcpy(pair->group, ""); - - if (strcmp(sync, "sync") == 0) - pair->doasync = 0; - else if (strcmp(sync, "async") == 0) - pair->doasync = 1; - else { - rdc_err(NULL, - gettext("set %s:%s neither sync nor async"), - pair->thost, pair->tfile); - } - - if (lghn && (p = strstr(options, "lghn="))) { - p += 5; - q = strchr(p, ';'); - if (q) { - /* LINTED p & q limited to options[64] */ - len = q - p; - } else { - len = strlen(p); - } - (void) strncpy(lghn, p, len); - lghn[len] = '\0'; - } else if (lghn) { - *lghn = '\0'; - } - - return (0); -} - -static int -ctag_check(char *fromhost, char *fromfile, char *frombitmap, char *tohost, - char *tofile, char *tobitmap, char *ctag, char *diskq) -{ - char *file_dgname; - char *bmp_dgname; - char *que_dgname; - char *localfile; - char file_buf[MAX_RDC_HOST_SIZE]; - char bmp_buf[MAX_RDC_HOST_SIZE]; - char que_buf[NSC_MAXPATH]; - int is_primary; - struct hostent *hp; - char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN]; - - if (!clustered) - return (0); - - hp = gethost_byname(fromhost); - (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN); - hp = gethost_byname(tohost); - (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN); - if (!self_check(fromname) && !self_check(toname)) { - /* - * If we could get a list of logical hosts on this cluster - * then we could print something intelligent about where - * the volume is mastered. For now, just print some babble - * about the fact that we have no idea. - */ - rdc_err(NULL, - gettext("either %s:%s or %s:%s is not local"), - fromhost, fromfile, tohost, tofile); - } - - is_primary = self_check(fromname); - - /* - * If implicit disk group name and no ctag specified by user, - * we set the ctag to it. - * If implicit disk group name, it must match any supplied ctag. - */ - localfile = is_primary ? fromfile : tofile; - file_dgname = cfg_dgname(localfile, file_buf, sizeof (file_buf)); - if (file_dgname && strlen(file_dgname)) - rdc_check_dgislocal(file_dgname); - - /* - * Autogenerate a ctag, if not "-C local" or no "-C " specified - */ - if (!rdc_islocal && !strlen(ctag) && file_dgname && strlen(file_dgname)) - (void) strncpy(ctag, file_dgname, MAX_RDC_HOST_SIZE); - - /* - * making an exception here for users giving the "local"tag - * this overrides this error message. (rdc_islocal ! = 1) - */ - if (!rdc_islocal && strlen(ctag) && - file_dgname && strlen(file_dgname) && - strncmp(ctag, file_dgname, MAX_RDC_HOST_SIZE)) { - rdc_warn(NULL, gettext("ctag \"%s\" does not " - "match disk group name \"%s\" of volume %s"), ctag, - file_dgname, localfile); - return (-1); - } - - /* - * Do we have a non-volume managed disk without -C local specified? - */ - if (!rdc_islocal && (!file_dgname || !strlen(file_dgname))) { - rdc_err(NULL, gettext("volume \"%s\" is not part" - " of a disk group,\nplease specify resource ctag\n"), - localfile); - } - - /* - * Do we have a volume managed disk with -C local? - */ - if (rdc_islocal && file_dgname && (strlen(file_dgname) > 0)) { - rdc_err(NULL, gettext( - "volume \"%s\" is part of a disk group\n"), localfile); - } - - /* - * Local bitmap must also have same ctag. - */ - localfile = is_primary ? frombitmap : tobitmap; - bmp_dgname = cfg_dgname(localfile, bmp_buf, sizeof (bmp_buf)); - if (bmp_dgname && strlen(bmp_dgname)) - rdc_check_dgislocal(bmp_dgname); - - /* - * Assure that if the primary has a device group, so must the bitmap - */ - if ((file_dgname && strlen(file_dgname)) && - (!bmp_dgname || !strlen(bmp_dgname))) { - rdc_warn(NULL, gettext("bitmap %s is not in disk group \"%s\""), - localfile, rdc_islocal < 1?file_dgname:ctag); - return (-1); - } - - /* - * Assure that if the if there is a ctag, it must match the bitmap - */ - if (!rdc_islocal && strlen(ctag) && - bmp_dgname && strlen(bmp_dgname) && - strncmp(ctag, bmp_dgname, MAX_RDC_HOST_SIZE)) { - rdc_warn(NULL, gettext("ctag \"%s\" does not " - "match disk group name \"%s\" of bitmap %s"), ctag, - bmp_dgname, localfile); - return (-1); - } - - /* - * If this is the SNDR primary and there is a local disk queue - */ - if (is_primary && diskq[0]) { - - /* - * Local disk queue must also have same ctag. - */ - que_dgname = cfg_dgname(diskq, que_buf, sizeof (que_buf)); - if (que_dgname && strlen(que_dgname)) - rdc_check_dgislocal(que_dgname); - - /* - * Assure that if the primary has a device group, so must - * the disk queue - */ - if ((file_dgname && strlen(file_dgname)) && - (!que_dgname || !strlen(que_dgname))) { - rdc_warn(NULL, gettext("disk queue %s is not in disk " - "group \"%s\""), diskq, - rdc_islocal < 1?file_dgname:ctag); - return (-1); - } - - /* - * Assure that if the if there is a ctag, it must match - * the disk queue - */ - if (!rdc_islocal && strlen(ctag) && - que_dgname && strlen(que_dgname) && - strncmp(ctag, que_dgname, MAX_RDC_HOST_SIZE)) { - rdc_warn(NULL, gettext("ctag \"%s\" does not " - "match disk group name \"%s\" of disk queue %s"), - ctag, que_dgname, diskq); - return (-1); - } - } - - return (0); -} - -#define DISKQ_OKAY 0 -#define DISKQ_FAIL 1 -#define DISKQ_REWRITEG 2 -/* - * check that newq is compatable with the groups current disk queue. - * Newq is incompatable if it is set and the groups queue is set and the queues - * are different. - * - * if newq is not set but should be, it will be set to the correct value. - * returns: - * DISK_REWRITEG entire group needs to take new value of disk_queue - * DISKQ_OKAY newq contains a value that matches the group. - * DISKQ_FAIL disk queues are incompatible. - */ -static int -check_diskqueue(CFGFILE *cfg, char *newq, char *newgroup) -{ - int i, setnumber; - _sd_dual_pair_t pair; - char *group = pair.group; - char *diskqueue = pair.diskqueue; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int open_cfg = cfg == NULL ? 1 : 0; - - - if (newgroup == NULL || *newgroup == '\0') { - if (*newq == '\0') - return (DISKQ_OKAY); /* okay, */ - newgroup = "--nomatch--"; - } - - if (open_cfg) { - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - } - - /*CSTYLED*/ - for (i = 0; ; i++) { - setnumber = i + 1; - (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - /* - * I think this is quicker than - * having to double dip into the config - */ - if (parse_cfg_buf(buf, &pair, NULL)) - rdc_err(NULL, gettext("cfg input error")); - - if (strncmp(group, newgroup, NSC_MAXPATH) != 0) { - if (((strncmp(diskqueue, newq, NSC_MAXPATH) == 0)) && - (diskqueue[0] != '\0')) { - if (open_cfg) - cfg_close(cfg); - return (DISKQ_FAIL); - } - continue; - } - if (*newq == '\0') { - if (diskqueue[0] != '\0') - (void) strncpy(newq, diskqueue, NSC_MAXPATH); - if (open_cfg) - cfg_close(cfg); - return (DISKQ_OKAY); /* okay, */ - } - - if (open_cfg) - cfg_close(cfg); - if (diskqueue[0] == '\0') /* no queue here */ - return (DISKQ_REWRITEG); - return (strncmp(diskqueue, newq, NSC_MAXPATH) - == 0 ? DISKQ_OKAY : DISKQ_FAIL); - } - if (open_cfg) - cfg_close(cfg); - return (DISKQ_OKAY); -} - - -int -pair_diskqueue_check(int newpair) -{ - int i, j; - int rc; - - for (i = 0; i < newpair; i++) { - if (strcmp(pair_list[i].group, pair_list[newpair].group) != 0) - continue; - if (strcmp(pair_list[i].diskqueue, pair_list[newpair].diskqueue) - == 0) - return (DISKQ_OKAY); /* matches existing group */ - if ((pair_list[newpair].group[0] != '\0') && - (pair_list[newpair].diskqueue[0] != '\0') && - (pair_list[i].diskqueue[0] != '\0')) { - rdc_warn(NULL, - gettext("disk queue %s does not match %s " - "skipping set"), pair_list[newpair].diskqueue, - pair_list[i].diskqueue); - return (DISKQ_FAIL); - } - - if ((strcmp(pair_list[newpair].diskqueue, "") == 0) && - pair_list[newpair].group[0] != '\0') { - (void) strncpy(pair_list[newpair].diskqueue, - pair_list[i].diskqueue, NSC_MAXPATH); - return (DISKQ_OKAY); /* changed to existing group que */ - } - if (strcmp(pair_list[i].diskqueue, "") == 0) { - for (j = 0; j < newpair; j++) { - if ((pair_list[j].group[0] != '\0') && - (strncmp(pair_list[j].group, - pair_list[newpair].group, - NSC_MAXPATH) == 0)) { - (void) strncpy(pair_list[j].diskqueue, - pair_list[newpair].diskqueue, - NSC_MAXPATH); - } - } - return (DISKQ_OKAY); - } - break; /* no problem with pair_list sets */ - - } - - /* now check with already configured sets */ - rc = check_diskqueue(NULL, pair_list[newpair].diskqueue, - pair_list[newpair].group); - if (rc == DISKQ_REWRITEG) { - for (i = 0; i < newpair; i++) { - if (strcmp(pair_list[i].group, - pair_list[newpair].group) != 0) - continue; - - (void) strncpy(pair_list[i].diskqueue, - pair_list[newpair].diskqueue, NSC_MAXPATH); - } - } - return (rc); -} - -int -ii_set_exists(CFGFILE *cfg, char *ma, char *sh, char *bm) -{ - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - char master[NSC_MAXPATH]; - char shadow[NSC_MAXPATH]; - char bitmap[NSC_MAXPATH]; - int i; - - for (i = 1; ; i++) { - (void) snprintf(key, sizeof (key), "ii.set%d", i); - bzero(&master, sizeof (master)); - bzero(&shadow, sizeof (shadow)); - bzero(&bitmap, sizeof (bitmap)); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) sscanf(buf, "%s %s %s", master, shadow, bitmap); - if (strcmp(master, ma) != 0) - continue; - if (strcmp(shadow, sh) != 0) - continue; - if (strcmp(bitmap, bm) != 0) - continue; - return (1); - } - return (0); -} - -void -rdc_ii_config(int argc, char **argv) -{ - char *master; - char *shadow; - char *bitmap; - char c; - CFGFILE *cfg; - int i; - int setnumber; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - int found; - int sev; - - /* Parse the rest of the arguments to see what to do */ - - if (argc - optind != 4) { - usage(); - exit(1); - } - - c = *argv[optind]; - switch (c) { - case 'd': - /* Delete an ndr_ii entry */ - - master = argv[++optind]; - shadow = argv[++optind]; - bitmap = argv[++optind]; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - if (!cfg_lock(cfg, CFG_WRLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - - found = 0; - /* get ndr_ii entries until a match is found */ - /*CSTYLED*/ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, master) != 0) - continue; - - /* Got a matching entry */ - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, shadow) != 0) - continue; - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.bitmap", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, bitmap) != 0) - continue; - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d", setnumber); - if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { - rdc_warn(NULL, - gettext("unable to remove \"%s\" " - "from configuration storage: %s"), - key, cfg_error(&sev)); - } else { - if (cfg_commit(cfg) < 0) - rdc_err(NULL, - gettext("ndr_ii set %s %s %s " - "not deconfigured."), - master, shadow, bitmap); - else - spcs_log("sndr", NULL, - gettext("ndr_ii set %s %s %s " - "has been deconfigured."), - master, shadow, bitmap); - } - found = 1; - break; - } - - if (!found) { - rdc_err(NULL, - gettext("did not find matching ndr_ii " - "entry for %s %s %s"), master, shadow, bitmap); - } - - cfg_close(cfg); - - break; - - case 'a': - /* Add an ndr_ii entry */ - - master = argv[++optind]; - shadow = argv[++optind]; - bitmap = argv[++optind]; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - if (!cfg_lock(cfg, CFG_WRLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - - found = 0; - /* get ndr_ii entries in case a match is found */ - /*CSTYLED*/ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, master) == 0) { - rdc_err(NULL, - gettext("found matching ndr_ii " - "entry for %s"), master); - } - } - /* - * check to see if this is using a sndr bitmap. - * kind of a courtesy check, as the ii copy would fail anyway - * excepting the case where they had actually configured - * ii/sndr that way, in which case they are broken - * before we get here - */ - /*CSTYLED*/ - for (i = 0; ; i++) { - setnumber = i + 1; - - /* - * Checking local bitmaps - */ - (void) snprintf(key, sizeof (key), "sndr.set%d.phost", - setnumber); - - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (self_check(buf)) { - (void) snprintf(key, sizeof (key), - "sndr.set%d.pbitmap", - setnumber); - } else { - (void) snprintf(key, sizeof (key), - "sndr.set%d.sbitmap", - setnumber); - } - - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - if ((strcmp(buf, bitmap) == 0) || - (strcmp(buf, master) == 0) || - (strcmp(buf, shadow) == 0)) { - rdc_err(NULL, - gettext("%s is already configured " - "as a Remote Mirror bitmap"), buf); - } - } - if (!ii_set_exists(cfg, master, shadow, bitmap)) { - rdc_warn(NULL, gettext("Point-in-Time Copy set " - "%s %s %s is not already configured. Remote " - "Mirror will attempt to configure this set when " - "a sync is issued to it. The results of that " - "operation will be in /var/adm/ds.log"), - master, shadow, bitmap); - spcs_log("sndr", NULL, gettext("Point-in-Time Copy set " - "%s %s %s is not already configured. Remote " - "Mirror will attempt to configure this set when " - "a sync is issued to it. The results of that " - "operation will be in /var/adm/ds.log"), - master, shadow, bitmap); - } else { - spcs_log("sndr", NULL, gettext("ndr_ii set " - "%s %s %s has been configured."), - master, shadow, bitmap); - } - - /* - * Prior to insertion in ndr_ii entry, if in a Sun Cluster - * assure device groups are the same and cluster tag is set - */ - if (clustered && !rdc_islocal) { - char mst_dg[NSC_MAXPATH] = {0}; - char shd_dg[NSC_MAXPATH] = {0}; - char bmp_dg[NSC_MAXPATH] = {0}; - - if (!(cfg_dgname(master, mst_dg, sizeof (mst_dg)) && - cfg_dgname(shadow, shd_dg, sizeof (shd_dg)) && - cfg_dgname(bitmap, bmp_dg, sizeof (bmp_dg)))) - rdc_warn(NULL, gettext("ndr_ii: %s %s %s are " - "not in a device group"), - master, shadow, bitmap); - else if (strcmp(mst_dg, bmp_dg) || - strcmp(mst_dg, shd_dg)) - rdc_warn(NULL, gettext("ndr_ii: %s %s %s are " - "not in different device groups"), - master, shadow, bitmap); - else { - cfg_resource(cfg, shd_dg); - (void) snprintf(buf, sizeof (buf), - "%s %s %s update %s", - master, shadow, bitmap, shd_dg); - } - } else { - (void) snprintf(buf, sizeof (buf), "%s %s %s update", - master, shadow, bitmap); - } - - if ((cfg_put_cstring(cfg, "ndr_ii", buf, strlen(buf)) < 0) || - (cfg_commit(cfg) < 0)) - rdc_warn(NULL, gettext("unable to add \"%s\" to " - "configuration storage: %s"), - buf, cfg_error(&sev)); - - cfg_close(cfg); - - break; - - default: - usage(); - exit(1); - } -} - -void -check_rdcbitmap(int cmd, char *hostp, char *bmp) -{ - int i; - CFGFILE *cfg; - int entries; - char **entry; - char *host, *pri, *sec, *sbm, *bit, *mas, *sha, *ovr; - char *shost, *buf, *que; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - - /* - * look into II config to see if this is being used elsewhere - */ - entry = NULL; - entries = cfg_get_section(cfg, &entry, "ii"); - for (i = 0; i < entries; i++) { - buf = entry[i]; - - mas = strtok(buf, " "); /* master */ - sha = strtok(NULL, " "); /* shadow */ - bit = strtok(NULL, " "); /* bitmap */ - (void) strtok(NULL, " "); /* mode */ - ovr = strtok(NULL, " "); /* overflow */ - - /* - * got master, shadow, overflow, and bitmap, now compare - */ - if ((strcmp(bmp, mas) == 0) || - (strcmp(bmp, sha) == 0) || - (strcmp(bmp, ovr) == 0) || - (strcmp(bmp, bit) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is in use by" - " Point-in-Time Copy"), bmp); - } - free(buf); - } - if (entries) - free(entry); - - - /* - * and last but not least, make sure sndr is not using vol for anything - */ - entry = NULL; - entries = cfg_get_section(cfg, &entry, "sndr"); - for (i = 0; i < entries; i++) { - buf = entry[i]; - - /* - * I think this is quicker than - * having to double dip into the config - */ - host = strtok(buf, " "); /* phost */ - pri = strtok(NULL, " "); /* primary */ - bit = strtok(NULL, " "); /* pbitmap */ - shost = strtok(NULL, " "); /* shost */ - sec = strtok(NULL, " "); /* secondary */ - sbm = strtok(NULL, " "); /* sbitmap */ - (void) strtok(NULL, " "); /* type */ - (void) strtok(NULL, " "); /* mode */ - (void) strtok(NULL, " "); /* group */ - (void) strtok(NULL, " "); /* cnode */ - (void) strtok(NULL, " "); /* options */ - que = strtok(NULL, " "); /* diskq */ - - if (cmd == RDC_CMD_ENABLE) { - if (self_check(host)) { - if ((strcmp(bmp, pri) == 0) || - (strcmp(bmp, que) == 0) || - (strcmp(bmp, bit) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network Data " - "Replicator"), bmp); - } - } else { - if ((strcmp(bmp, sec) == 0) || - (strcmp(bmp, sbm) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network Data " - "Replicator"), bmp); - } - } - } else if (cmd == RDC_CMD_RECONFIG) { - - /* - * read this logic 1000 times and consider - * multi homed, one to many, many to one (marketing) - * etc, etc, before changing - */ - if (self_check(hostp)) { - if (self_check(host)) { - if ((strcmp(bmp, pri) == 0) || - (strcmp(bmp, que) == 0) || - (strcmp(bmp, bit) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network " - "Data Replicator"), bmp); - } - } else { - if ((strcmp(hostp, shost) == 0) && - (strcmp(bmp, sec) == 0) || - (strcmp(bmp, sbm) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network " - "Data Replicator"), bmp); - - } - } - } else { /* self_check(hostp) failed */ - if (self_check(host)) { - if ((strcmp(shost, hostp) == 0) && - (strcmp(bmp, sec) == 0) || - (strcmp(bmp, sbm) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network " - "Data Replicator"), bmp); - } - } else { - if ((strcmp(host, hostp) == 0) && - (strcmp(bmp, pri) == 0) || - (strcmp(bmp, que) == 0) || - (strcmp(bmp, bit) == 0)) { - rdc_err(NULL, - gettext("bitmap %s is already " - "in use by StorEdge Network " - "Data Replicator"), bmp); - } - } - } - - } - - free(buf); - } - cfg_close(cfg); - - if (entries) - free(entry); -} -int -check_intrange(char *arg) { - int i; - - for (i = 0; i < strlen(arg); i++) { - if (arg[i] < '0' || arg[i] > '9') { - rdc_warn(NULL, "not a valid number, must be a " - "decimal between 1 and %d", MAXINT); - return (0); - } - } - errno = 0; - i = (int)strtol(arg, NULL, 10); - if ((errno) || (i < 1) || (i > MAXINT)) { - rdc_warn(NULL, "not a valid number, must be a decimal " - "between 1 and %d", MAXINT); - return (0); - } - return (1); -} - -void -rewrite_group_diskqueue(CFGFILE *cfg, _sd_dual_pair_t *pair, char *diskqueue) -{ - int set; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - _sd_dual_pair_t tmpair; - - for (set = 1; /*CSTYLED*/; set++) { - bzero(buf, CFG_MAX_BUF); - bzero(&tmpair, sizeof (tmpair)); - - (void) snprintf(key, sizeof (key), "sndr.set%d", set); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - if (parse_cfg_buf(buf, &tmpair, NULL)) - continue; - if (pair->group && pair->group[0]) { - if (strcmp(pair->group, tmpair.group) != 0) - continue; /* not the group we want */ - - } else { /* no group specified */ - if (strcmp(pair->thost, tmpair.thost) != 0) - continue; - if (strcmp(pair->tfile, tmpair.tfile) != 0) - continue; - } - - (void) sprintf(key, "sndr.set%d.diskq", set); - - if (cfg_put_cstring(cfg, key, diskqueue, - strlen(diskqueue)) < 0) { - perror(cfg_error(NULL)); - } - } -} - -void -diskq_subcmd(int subcmd, char *qvol, char *group_arg, char *ctag_arg, - char *tohost_arg, char *tofile_arg) -{ - int found = 0; - int setnumber = 0; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - int i; - int rc; - int option = 0; - _sd_dual_pair_t pair; - CFGFILE *cfg; - char *ctag = NULL; - int resourced = 0; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_WRLOCK)) - rdc_err(NULL, - gettext("unable to lock configuration")); - -redo: - if (cfg_load_svols(cfg) < 0 || - cfg_load_dsvols(cfg) < 0 || - cfg_load_shadows(cfg) < 0) - rdc_err(NULL, - gettext("Unable to parse config filer")); - load_rdc_vols(cfg); - - /*CSTYLED*/ - for (i = 0; i < rdc_maxsets;) { - setnumber++; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), - "sndr.set%d", setnumber); - rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); - if (rc < 0) - break; - if (parse_cfg_buf(buf, &pair, NULL)) - continue; - - if (strlen(group_arg) == 0) { - if (strcmp(tohost_arg, pair.thost) == 0 && - strcmp(tofile_arg, pair.tfile) == 0) { - (void) strcpy(group_arg, pair.group); - found = 1; - break; - } - - } else { - if (strcmp(group_arg, pair.group) == 0) { - found = 1; - break; - } - } - } - - if (!found) { - if (strlen(group_arg) == 0) { - rdc_err(NULL, - gettext("Unable to find %s:%s in " - "configuration storage"), - tohost_arg, tofile_arg); - } else { - rdc_err(NULL, - gettext("Unable to find group %s in " - "configuration storage"), group_arg); - } - } - if (!resourced && strlen(pair.ctag)) { /* uh-oh... */ - cfg_unload_svols(cfg); - cfg_unload_dsvols(cfg); - cfg_unload_shadows(cfg); - unload_rdc_vols(); - cfg_resource(cfg, pair.ctag); - ctag = strdup(pair.ctag); - resourced = 1; - setnumber = 0; - goto redo; - } - - if (clustered && !rdc_islocal) { - if (strcmp(ctag_arg, "") && - strncmp(ctag_arg, pair.ctag, MAX_RDC_HOST_SIZE)) - rdc_warn(NULL, gettext("ctags %s and %s " - "do not match, proceeding with operation based " - "on existing set information"), ctag_arg, ctag); - } - switch (subcmd) { - case RDC_CMD_ADDQ: - if (clustered && (ctag_check(pair.fhost, pair.ffile, - pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap, - pair.ctag, qvol) < 0)) - exit(1); - - if (strlen(pair.diskqueue) > 0) { - rdc_err(NULL, gettext("Remote Mirror set already " - "has a disk queue")); - } - if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) { - rdc_err(NULL, - gettext("diskqueue %s is incompatible"), qvol); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove disk " - "queue [%s] from configuration"), qvol); - rdc_err(NULL, gettext("Add disk queue operation " - "failed")); - } - if (nsc_lookup(volhash, qvol) == NULL) { - if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) { - rdc_err(NULL, gettext("Add disk queue " - "operation failed")); - } - } - rewrite_group_diskqueue(cfg, &pair, qvol); - - spcs_log("sndr", NULL, gettext("Remote Mirror: added " - "diskqueue %s to set %s:%s and its group"), qvol, - pair.thost, pair.tfile); - break; - case RDC_OPT_FORCE_QINIT: - if (strlen(pair.diskqueue) == 0) { - rdc_err(NULL, gettext("Remote Mirror set does not " - "have a disk queue")); - } - subcmd = RDC_CMD_INITQ; - option = RDC_OPT_FORCE_QINIT; - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, subcmd, option, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - exit(1); - } - break; - case RDC_CMD_INITQ: - if (strlen(pair.diskqueue) == 0) { - rdc_err(NULL, gettext("Remote Mirror set does not " - "have a disk queue")); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - exit(1); - } - break; - case RDC_CMD_REMQ: - if (strlen(pair.diskqueue) == 0) { - rdc_err(NULL, gettext("Remote Mirror set does not " - "have a disk queue")); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - exit(1); - } - if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove disk queue " - "[%s] from configuration"), pair.diskqueue); - rewrite_group_diskqueue(cfg, &pair, place_holder); - - spcs_log("sndr", NULL, gettext("Remote Mirror: removed " - "diskqueue from set %s:%s and its group"), pair.thost, - pair.tfile); - break; - case RDC_CMD_KILLQ: - if (strlen(pair.diskqueue) == 0) { - rdc_err(NULL, gettext("Remote Mirror set does not " - "have a disk queue")); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, subcmd, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - rdc_err(NULL, gettext("Failed to remove disk queue")); - } - if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove disk queue " - "[%s] from configuration"), pair.diskqueue); - - rewrite_group_diskqueue(cfg, &pair, place_holder); - - spcs_log("sndr", NULL, gettext("Remote Mirror: forcibly " - "removed diskqueue from set %s:%s and its group "), - pair.thost, pair.tfile); - break; - case RDC_CMD_REPQ: - if (clustered && (ctag_check(pair.fhost, pair.ffile, - pair.fbitmap, pair.thost, pair.tfile, pair.tbitmap, - pair.ctag, qvol) < 0)) - exit(1); - - if (strlen(pair.diskqueue) == 0) { - rdc_err(NULL, gettext("Remote Mirror set does not " - "have a disk queue")); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_REMQ, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - rdc_err(NULL, gettext("Failed to remove disk queue")); - } - if (cfg_vol_disable(cfg, pair.diskqueue, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove disk queue " - "[%s] from configuration"), pair.diskqueue); - - rewrite_group_diskqueue(cfg, &pair, place_holder); - - /* commit here, enable may fail */ - if (cfg_commit(cfg) < 0) { - rdc_err(NULL, gettext("commit replace disk queue %s " - "with %s failed"), pair.diskqueue, qvol); - } - - if (check_diskqueue(cfg, qvol, group_arg) == DISKQ_FAIL) { - rdc_err(NULL, - gettext("cannot replace disk queue %s with %s"), - pair.diskqueue, qvol); - } - if (rdc_operation(cfg, pair.fhost, pair.ffile, pair.fbitmap, - pair.thost, pair.tfile, pair.tbitmap, RDC_CMD_ADDQ, 0, - pair.directfile, pair.group, pair.ctag, qvol, &pair.doasync, - 0) < 0) { - if (cfg_vol_disable(cfg, qvol, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove disk " - "queue [%s] from configuration"), qvol); - rdc_err(NULL, gettext("Failed to add new disk queue")); - } - if (nsc_lookup(volhash, qvol) == NULL) - if (cfg_vol_enable(cfg, qvol, ctag, "sndr") < 0) { - rdc_err(NULL, gettext("Replace disk queue " - "operation failed")); - } - - rewrite_group_diskqueue(cfg, &pair, qvol); - - spcs_log("sndr", NULL, gettext("Remote Mirror: replaced " - "diskqueue for set %s:%s and its group with %s"), - pair.thost, pair.tfile, qvol); - break; - } - - cfg_unload_svols(cfg); - cfg_unload_dsvols(cfg); - cfg_unload_shadows(cfg); - unload_rdc_vols(); - - if (cfg_commit(cfg) < 0) - rdc_err(NULL, gettext("commit failed on disk queue operation")); - - cfg_close(cfg); - if (ctag) - free(ctag); -} -void -spcslog_sync(rdcconfig_t *sets, int start, int type) -{ - rdcconfig_t *setp = sets; - - while (setp) { - if (start) { - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\nSync Started"), - program, rdc_decode_flag(RDC_CMD_COPY, type), - setp->phost, setp->pfile, setp->pbmp, - setp->shost, setp->sfile, setp->sbmp); - } else { - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\nSync Ended"), - program, rdc_decode_flag(RDC_CMD_COPY, type), - setp->phost, setp->pfile, setp->pbmp, - setp->shost, setp->sfile, setp->sbmp); - } - setp = setp->next; - } -} - -void -spcslog_tunable(char *shost, char *svol) -{ - if (qblock == RDC_OPT_SET_QNOBLOCK) - spcs_log("sndr", NULL, gettext("diskqueue " - "set to non blocking for %s:%s and any members " - "of it's group"), shost, svol); - else if (qblock == RDC_OPT_CLR_QNOBLOCK) - spcs_log("sndr", NULL, gettext("diskqueue " - "set to blocking for %s:%s and any members " - "of it's group"), shost, svol); - - if (maxqfbas) - spcs_log("sndr", NULL, gettext("maxqfbas set to %d for %s:%s"), - maxqfbas, shost, svol); - if (maxqitems) - spcs_log("sndr", NULL, gettext("maxwrites set to %d for %s:%s"), - maxqitems, shost, svol); - if (asyncthr) - spcs_log("sndr", NULL, gettext("%d async threads configured " - "for %s:%s"), asyncthr, shost, svol); -} - -int -set_qblock(char *blockarg) -{ - if (strcmp(blockarg, "block") == 0) - qblock = RDC_OPT_CLR_QNOBLOCK; - else if (strcmp(blockarg, "noblock") == 0) - qblock = RDC_OPT_SET_QNOBLOCK; - else - return (1); - - return (0); -} - -static void -rdc_force_disable(CFGFILE *cfg, char *phost, char *pvol, char *pbmp, - char *shost, char *svol, char *sbmp, char *ctag, char *lhname) -{ - rdc_config_t parms; - spcs_s_info_t ustatus; - volcount_t *vc; - char *datavol = NULL; - char *bmpvol = NULL; - int on_pri = 0; - int on_sec = 0; - - /* are we on the primary or secondary host? */ - if (ctag && *ctag && *lhname) { - if (strcmp(phost, lhname) == 0) { - on_pri = 1; - } else if (strcmp(shost, lhname) == 0) { - on_sec = 1; - } - } else if (self_check(phost)) { - on_pri = 1; - } else if (self_check(shost)) { - on_sec = 1; - } - - if (on_pri) { - datavol = pvol; - bmpvol = pbmp; - } else if (on_sec) { - datavol = svol; - bmpvol = sbmp; - } else { - rdc_err(NULL, gettext("Unable to determine whether current " - "node is primary or secondary")); - } - - /* set up parms structure */ - parms.command = RDC_CMD_DISABLE; - (void) strncpy(parms.rdc_set->primary.intf, phost, MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->primary.file, pvol, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->secondary.intf, shost, MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->secondary.file, svol, NSC_MAXPATH); - ustatus = spcs_s_ucreate(); - parms.options = RDC_OPT_FORCE_DISABLE; - - /* - * We are now going to 'force' the kernel to disable the set. By - * setting the RDC_OPT_FORCE_DISABLE flag, the kernel will bypass some - * of the checks that are normally done when attempting to disable - * a set. We need to do this force option in a cluster environment - * when the logical hostname for the primary or secondary volume - * is no longer available. - */ - spcs_log("sndr", NULL, "%s sndradm -d %s %s %s %s %s %s", - gettext("FORCE DISABLE"), phost, pvol, pbmp, shost, svol, sbmp); - rdc_warn(NULL, gettext("Forcing set disable")); - if (RDC_IOCTL(RDC_CONFIG, &parms, 0, 0, 0, 0, ustatus) != SPCS_S_OK) - rdc_warn(&ustatus, gettext("set %s:%s not enabled in kernel"), - shost, svol); - - /* if we get to this point, then a set was disabled. try sv-disable */ - vc = nsc_lookup(volhash, datavol); - if (vc && (1 == vc->count)) - if (cfg_vol_disable(cfg, datavol, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove data volume " - "[%s] from configuration"), datavol); - vc = nsc_lookup(volhash, bmpvol); - if (vc && (1 == vc->count)) - if (cfg_vol_disable(cfg, bmpvol, ctag, "sndr") < 0) - rdc_warn(NULL, gettext("Failed to remove bitmap " - "[%s] from configuration"), bmpvol); -} - -void -check_rdcsecondary(char *secondary) -{ - int i; - CFGFILE *cfg; - int entries; - char **entry; - char *sha; - char *buf; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("error opening config")); - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("error locking config")); - - entry = NULL; - entries = cfg_get_section(cfg, &entry, "ii"); - for (i = 0; i < entries; i++) { - buf = entry[i]; - - (void) strtok(buf, " "); /* master */ - sha = strtok(NULL, " "); /* shadow */ - if (strcmp(secondary, sha) == 0) { - rdc_err(NULL, - gettext("secondary %s is in use by" - " Point-in-Time Copy"), secondary); - } - free(buf); - } - if (entries) - free(entry); - cfg_close(cfg); -} - -int -main(int argc, char *argv[]) -{ - char config_file[FILENAME_MAX]; - char fromhost[MAX_RDC_HOST_SIZE]; - char tohost[MAX_RDC_HOST_SIZE]; - char fromfile[NSC_MAXPATH]; - char tofile[NSC_MAXPATH]; - char frombitmap[NSC_MAXPATH]; - char tobitmap[NSC_MAXPATH]; - char directfile[NSC_MAXPATH]; - char group[NSC_MAXPATH]; - char ctag[MAX_RDC_HOST_SIZE]; - char options_cfg[CFG_MAX_BUF]; - char fromnetaddr[RDC_MAXADDR]; - char tonetaddr[RDC_MAXADDR]; - char tmphost[MAX_RDC_HOST_SIZE]; - char tmpfile[NSC_MAXPATH]; - char tmpbitmap[NSC_MAXPATH]; - char diskqueue[NSC_MAXPATH]; - char lhname[MAX_RDC_HOST_SIZE]; - char mode[16]; - rdc_version_t rdc_version; - int pairs; - int pid; - int flag = 0; - int fflag = 0; - int reverse = 0; - int nflag = 0; - int iflag = 0; - int doasync; - int pflag = 0; - int vflag = 0; - int verbose = 0; - int errflag = 0; - int cfgflag = 0; - int cfg_success; - int Iflag = 0; - char c; - char inval = 0; - int found; - int rc; - int geflag = 0; - int qflag = 0; - char *qarg; - int Bflag = 0; - char *bitfile; - CFGFILE *cfg = NULL; - int i; - int setnumber; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - char ctag_arg[MAX_RDC_HOST_SIZE]; - char group_arg[NSC_MAXPATH]; - int file_format = 0; - int sev; - int diskq_group = DISKQ_OKAY; - int extra_argc; - char *ctag_p, *group_p, *diskqueue_p; - char *required; - char *role_env; - int checksetfields = -1; - nsc_off_t boffset = 0; - int oflag = 0; - rdcconfig_t *sets = NULL; - rdcconfig_t *sets_p = NULL; - rdc_rc_t *rclist = NULL; - rdc_rc_t *rcp = NULL; - int host_not_found = 0; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("rdc"); - role_env = getenv("SNDR_ROLE_REVERSE"); - if (role_env && strcmp(role_env, "sndr_allow_reverse") == 0) - allow_role = 1; - - program = basename(argv[0]); - - rc = rdc_check_release(&required); - if (rc < 0) { - rdc_err(NULL, - gettext("unable to determine the current " - "Solaris release: %s\n"), strerror(errno)); - } else if (rc == FALSE) { - rdc_err(NULL, - gettext("incorrect Solaris release (requires %s)\n"), - required); - } - - if ((clustered = cfg_iscluster()) < 0) { - rdc_err(NULL, gettext("unable to ascertain environment")); - } - - (void) strcpy(ctag_arg, ""); - (void) strcpy(group_arg, ""); - bzero(ctag, MAX_RDC_HOST_SIZE); - bzero(reconfig_ctag, MAX_RDC_HOST_SIZE); - bzero(diskqueue, NSC_MAXPATH); - - rdc_maxsets = rdc_get_maxsets(); - if (rdc_maxsets == -1) { - rdc_err(NULL, - gettext("unable to get maxsets value from kernel")); - } - - pair_list = calloc(rdc_maxsets, sizeof (*pair_list)); - if (pair_list == NULL) { - rdc_err(NULL, - gettext("unable to allocate pair_list array for %d sets"), - rdc_maxsets); - } - - bzero(group, sizeof (group)); - bzero(diskqueue, sizeof (diskqueue)); - qblock = 0; - - while ((c = -#ifdef DEBUG - getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw")) -#else - getopt(argc, argv, "A:B:C:D:EF:HIO:PRUW:a:bdef:g:hilmno:pq:rsuvw")) -#endif - != -1) { - switch (c) { - case 'B': - if (!allow_role || flag) { - inval = 1; - break; - } - bitfile = optarg; - Bflag = 1; - flag = RDC_BITMAPOP; - break; - case 'H': - /* 'h' was already assigned */ - if (flag) - inval = 1; - flag = RDC_CMD_HEALTH; - break; - case 'I': - /* List or edit ndr_ii configuration entries */ - Iflag = 1; - break; - case 'R': - if (flag) - inval = 1; - flag = RDC_CMD_RECONFIG; - break; -#ifdef DEBUG - case 'U': /* UDP support */ - proto_test = 1; - break; -#endif - case 'F': - if (flag && flag != RDC_CMD_TUNABLE) - inval = 1; - flag = RDC_CMD_TUNABLE; - - if (check_intrange(optarg)) - maxqfbas = atoi(optarg); - else - exit(1); - - break; - case 'W': - if (flag && flag != RDC_CMD_TUNABLE) - inval = 1; - flag = RDC_CMD_TUNABLE; - - if (check_intrange(optarg)) - maxqitems = atoi(optarg); - else - exit(1); - - break; - case 'A': - if (flag && flag != RDC_CMD_TUNABLE) - inval = 1; - flag = RDC_CMD_TUNABLE; - - if (check_intrange(optarg)) - asyncthr = atoi(optarg); - else - exit(1); - - break; - case 'D': - if (flag && flag != RDC_CMD_TUNABLE) - inval = 1; - flag = RDC_CMD_TUNABLE; - - if (set_qblock(optarg)) { - usage(); - exit(1); - } - iflag |= qblock; - break; - case 'a': - if (flag && flag != RDC_CMD_TUNABLE) - inval = 1; - flag = RDC_CMD_TUNABLE; - if (strcmp(optarg, "off") == 0) - autosync = AUTOSYNC_OFF; - else if (strcmp(optarg, "on") == 0) - autosync = AUTOSYNC_ON; - else - inval = 1; - break; - case 'C': - if (clustered) { - (void) strncpy(ctag_arg, optarg, - MAX_RDC_HOST_SIZE); - process_clocal(ctag_arg); - } else - inval = 1; - break; - case 'g': - if (flag == RDC_CMD_ENABLE) - inval = 1; - geflag = 1; - (void) strncpy(group_arg, optarg, NSC_MAXPATH); - verify_groupname(group_arg); - break; - case 'b': - /* ignore */ - break; - case 'n': - nflag = 1; - break; - case 'd': - if (flag) - inval = 1; - flag = RDC_CMD_DISABLE; - break; - case 'e': - if (flag || geflag) - inval = 1; - flag = RDC_CMD_ENABLE; - iflag |= RDC_OPT_SETBMP; - break; - case 'E': - if (flag) - inval = 1; - flag = RDC_CMD_ENABLE; - iflag |= RDC_OPT_CLRBMP; - break; - case 'f': - fflag = 1; - (void) strcpy(config_file, optarg); - break; - case 'h': - usage(); - exit(0); - break; - case 'l': - if (flag) - inval = 1; - flag = RDC_CMD_LOG; - break; - case 'm': - if (flag) - inval = 1; - flag = RDC_CMD_COPY; - iflag |= RDC_OPT_FULL; - break; - case 'O': - case 'o': - - if (!allow_role || oflag) { - inval = 1; - break; - } - if (c == 'o') { - oflag = RDC_BITMAPOR; - } else { - oflag = RDC_BITMAPSET; - } - boffset = strtoull(optarg, NULL, 0); - break; - case 'P': - if (flag) - inval = 1; - pflag = 1; - verbose = 1; - break; - case 'p': - if (flag) - inval = 1; - pflag = 1; - break; - case 'q': - if (flag) - inval = 1; - flag = RDC_CMD_INITQ; - qflag = optind; - qarg = optarg; - break; - case 'i': - if (flag) - inval = 1; - pflag = 1; - file_format = 1; - break; - case 'r': - reverse = 1; - iflag |= RDC_OPT_REVERSE; - break; - case 's': - if (flag) - inval = 1; - flag = RDC_CMD_STATUS; - nflag = 1; /* No prompt for a status */ - break; - case 'u': - if (flag) - inval = 1; - flag = RDC_CMD_COPY; - iflag |= RDC_OPT_UPDATE; - break; - case 'v': - if (flag) - inval = 1; - pflag = 1; - vflag = 1; - break; - case 'w': - if (flag) - inval = 1; - flag = RDC_CMD_WAIT; - break; - case '?': - errflag++; - } - } - - if (inval || ((flag != RDC_BITMAPOP) && oflag)) { - rdc_warn(NULL, gettext("invalid argument combination")); - errflag = 1; - } - - if (flag && Iflag) { - /* Mutually incompatible */ - usage(); - exit(1); - } - - if (Iflag) { - rdc_ii_config(argc, argv); - exit(0); - } - - if (vflag) { - spcs_s_info_t ustatus; - - ustatus = spcs_s_ucreate(); - rc = RDC_IOCTL(RDC_VERSION, &rdc_version, 0, 0, 0, 0, ustatus); - if (rc == SPCS_S_ERROR) { - rdc_err(&ustatus, gettext("statistics error")); - } - spcs_s_ufree(&ustatus); -#ifdef DEBUG - (void) printf(gettext("Remote Mirror version %d.%d.%d.%d\n"), - rdc_version.major, rdc_version.minor, - rdc_version.micro, rdc_version.baseline); -#else - if (rdc_version.micro) { - (void) printf(gettext( - "Remote Mirror version %d.%d.%d\n"), - rdc_version.major, - rdc_version.minor, - rdc_version.micro); - } else { - (void) printf(gettext("Remote Mirror version %d.%d\n"), - rdc_version.major, rdc_version.minor); - } -#endif - exit(0); - } - - if (!(flag || pflag) || errflag) { - usage(); - exit(1); - } - - if (pflag && !fflag && (argc - optind) == 0) { - /* print with no set specified */ - exit(rdc_print(file_format, verbose, - group_arg, ctag_arg, NULL, NULL, NULL)); - } - - if (qflag) { /* change disk queue setting */ - int subcmd = 0; - int offset = 0; - char *ptr; - char *qvol; - char tohost_arg[MAX_RDC_HOST_SIZE]; - char tofile_arg[NSC_MAXPATH]; - - if (strcmp("a", qarg) == 0) { - subcmd = RDC_CMD_ADDQ; - offset = 1; - } else if (strcmp("d", qarg) == 0) { - subcmd = RDC_CMD_REMQ; - offset = 0; - } else if (strcmp("r", qarg) == 0) { - subcmd = RDC_CMD_REPQ; - offset = 1; - } else { - rdc_warn(NULL, " %s Invalid qopt", qarg); - q_usage(1); - exit(1); - } - if (strlen(group_arg) == 0) { - /* pick out single set as shost:svol */ - ptr = strtok(argv[qflag + offset], ":"); - if (ptr) - (void) strncpy(tohost_arg, ptr, - MAX_RDC_HOST_SIZE); - else { - rdc_warn(NULL, gettext("Bad host specified")); - q_usage(1); - exit(1); - } - ptr = strtok(NULL, ":"); - if (ptr) - (void) strncpy(tofile_arg, ptr, NSC_MAXPATH); - else { - rdc_warn(NULL, gettext("Bad set specified")); - q_usage(1); - exit(1); - } - } - - qvol = argv[qflag]; - if ((qvol == NULL) && (subcmd != RDC_CMD_REMQ)) { - rdc_warn(NULL, gettext("missing queue volume")); - q_usage(1); - exit(1); - } - diskq_subcmd(subcmd, qvol, group_arg, ctag_arg, - tohost_arg, tofile_arg); - exit(0); - } - - if (flag == RDC_CMD_RECONFIG && !fflag) { - /* See what is to be reconfigured */ - if (argc - optind == 0) - flag = RDC_CMD_RESET; - else { - if (argc - optind < 2) { - usage(); - exit(1); - } - c = *argv[optind++]; - if (argv[optind -1][1] != '\0') { - usage(); - exit(2); - } - switch (c) { - case 'b': - if (argc - optind < 2) { - usage(); - exit(1); - } - if (*argv[optind] == 'p') - reconfig_pbitmap = argv[++optind]; - else if (*argv[optind] == 's') - reconfig_sbitmap = argv[++optind]; - else { - usage(); - exit(1); - } - optind++; - break; -#ifdef _RDC_CAMPUS - case 'd': - reconfig_direct = argv[optind++]; - break; -#endif - case 'g': - reconfig_group = argv[optind++]; - verify_groupname(reconfig_group); - break; - case 'C': - if (clustered) { - (void) strncpy(reconfig_ctag, - argv[optind++], MAX_RDC_HOST_SIZE); - process_clocal(reconfig_ctag); - } else { - usage(); - exit(1); - } - break; - case 'm': - if (strcmp(argv[optind], "sync") == 0) - reconfig_doasync = 0; - else if (strcmp(argv[optind], "async") == 0) - reconfig_doasync = 1; - else { - usage(); - exit(1); - } - optind++; - break; - case 'r': - if (allow_role) { - iflag |= RDC_OPT_REVERSE_ROLE; - break; - } - /* FALLTHROUGH */ - default: - usage(); - exit(1); - } - } - } - if (fflag) { - checksetfields = 1; - if ((argc - optind) != 0) { - usage(); - exit(1); - } - } else { - if ((argc - optind) == 0) { - /* Use libcfg to figure out what to operate on */ - cfgflag = 1; -#ifdef DEBUG - rdc_warn(NULL, gettext("using current config")); -#endif - checksetfields = 0; - } else { - if ((argc - optind) < 8 && (argc - optind) != 1) { - usage(); - exit(1); - } - } - } - - if (cfgflag) { - if (flag == RDC_CMD_ADDQ || - flag == RDC_CMD_REMQ || - flag == RDC_CMD_KILLQ || - flag == RDC_CMD_INITQ) { - rdc_err(NULL, gettext("can not use current config " - "for disk queue operations")); - } - } else if (fflag) { - if (flag == RDC_CMD_ADDQ || - flag == RDC_CMD_REMQ || - flag == RDC_CMD_KILLQ || - flag == RDC_CMD_INITQ) { - rdc_err(NULL, gettext("can not use a config file " - "for disk queue operations")); - } - } - if (cfgflag) { - if (flag == RDC_CMD_ENABLE) { - rdc_err(NULL, gettext("can not use current config " - "for enable command")); - } - if ((flag == RDC_CMD_RECONFIG) && (reconfig_pbitmap || - reconfig_sbitmap)) { - rdc_err(NULL, gettext("can not use current config " - "for bitmap reconfiguration")); - } - if (flag == RDC_BITMAPOP) { - rdc_err(NULL, gettext("can not use current config " - "for bitmap set command")); - } - pairs = read_libcfg(flag, group_arg, ctag_arg); - if (pairs == 0) { - (void) fprintf(stderr, - gettext("no matching Remote Mirror sets found " - "in config\n")); - exit(1); - } - } else if (!fflag) { - /* - * Format is either: - * - * tohost:tofile - * - * or something like this for example: - * - * fromhost fromfile frombitmap tohost tofile tobitmap ip sync - * g group C ctag - */ - - if (argc - optind == 1) { - char tohost_arg[MAX_RDC_HOST_SIZE]; - char tofile_arg[NSC_MAXPATH]; - char *ptr; - - checksetfields = 0; - if (flag == RDC_CMD_ENABLE) { - rdc_err(NULL, - gettext("must specify full set details for " - "enable command")); - } - ptr = strtok(argv[optind], ":"); - if (ptr) - (void) strncpy(tohost_arg, ptr, - MAX_RDC_HOST_SIZE); - else { - rdc_err(NULL, gettext("Bad host specified")); - } - ptr = strtok(NULL, ":"); - if (ptr) - (void) strncpy(tofile_arg, ptr, NSC_MAXPATH); - else { - rdc_err(NULL, gettext("Bad set specified")); - } - - /* Now look up tohost:tofile via libcfg */ - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, - gettext("unable to lock configuration")); - - setnumber = 0; - found = 0; - /*CSTYLED*/ - for (i = 0; i < rdc_maxsets;) { - setnumber++; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), - "sndr.set%d", setnumber); - rc = cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF); - if (rc < 0) - break; - - (void) snprintf(key, sizeof (key), - "sndr.set%d.shost", setnumber); - (void) cfg_get_cstring(cfg, key, tohost, - sizeof (tohost)); - if (strncmp(tohost, tohost_arg, NSC_MAXPATH)) - continue; - - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - (void) cfg_get_cstring(cfg, key, tofile, - sizeof (tofile)); - if (strncmp(tofile, tofile_arg, NSC_MAXPATH)) - continue; - - found = 1; - - (void) snprintf(key, sizeof (key), - "sndr.set%d.phost", setnumber); - (void) cfg_get_cstring(cfg, key, fromhost, - sizeof (fromhost)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.primary", setnumber); - (void) cfg_get_cstring(cfg, key, fromfile, - sizeof (fromfile)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.pbitmap", setnumber); - (void) cfg_get_cstring(cfg, key, frombitmap, - sizeof (frombitmap)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.sbitmap", setnumber); - (void) cfg_get_cstring(cfg, key, tobitmap, - sizeof (tobitmap)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.type", setnumber); - (void) cfg_get_cstring(cfg, key, directfile, - sizeof (directfile)); - if (strcmp(directfile, "ip") == 0) - (void) strcpy(directfile, ""); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.mode", setnumber); - (void) cfg_get_cstring( - cfg, key, mode, sizeof (mode)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.group", setnumber); - (void) cfg_get_cstring(cfg, key, group, - sizeof (group)); - if (strcmp(group_arg, "") && - strncmp(group_arg, group, NSC_MAXPATH)) - continue; - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", setnumber); - (void) cfg_get_cstring( - cfg, key, ctag, sizeof (ctag)); - if ((strlen(ctag_arg) > 0) && - (strcmp(ctag_arg, ctag) != 0)) - rdc_err(NULL, - gettext("ctags %s and %s " - "do not match"), ctag_arg, ctag); - - if (strcmp(mode, "sync") == 0) - doasync = 0; - else if (strcmp(mode, "async") == 0) - doasync = 1; - else { - rdc_err(NULL, - gettext("set %s:%s neither sync " - "nor async"), tohost, tofile); - } - break; - } - cfg_close(cfg); - if (!found) { - rdc_err(NULL, - gettext("set %s:%s not found in config"), - tohost_arg, tofile_arg); - } - } else { - checksetfields = 1; - (void) strncpy(fromhost, argv[optind], - MAX_RDC_HOST_SIZE); - (void) strncpy(fromfile, argv[optind+1], NSC_MAXPATH); - (void) strncpy(frombitmap, argv[optind+2], NSC_MAXPATH); - (void) strncpy(tohost, argv[optind+3], - MAX_RDC_HOST_SIZE); - (void) strncpy(tofile, argv[optind+4], NSC_MAXPATH); - (void) strncpy(tobitmap, argv[optind+5], NSC_MAXPATH); - - /* Check the length of entries from the command line */ - if ((fromhost[MAX_RDC_HOST_SIZE - 1] != '\0') || - (tohost[MAX_RDC_HOST_SIZE - 1] != '\0')) { - rdc_err(NULL, - gettext("hostname is longer than %d " - "characters\n"), (MAX_RDC_HOST_SIZE - 1)); - } - - /* Check if it's ip address -- not allowed */ - if ((inet_addr(fromhost) != (in_addr_t)(-1)) || - (inet_addr(tohost) != (in_addr_t)(-1))) { - rdc_err(NULL, gettext( - "The hostname specified is invalid.\n" - "See 'man inet(3SOCKET)'")); - } - - if ((fromfile[NSC_MAXPATH - 1] != '\0') || - (tofile[NSC_MAXPATH - 1] != '\0') || - (frombitmap[NSC_MAXPATH - 1] != '\0') || - (tobitmap[NSC_MAXPATH - 1] != '\0')) { - rdc_err(NULL, gettext("device name is longer " - "than %d characters\n"), (NSC_MAXPATH - 1)); - } -#ifdef _RDC_CAMPUS - if (argv[optind+6][0] == '/') { - /* FCAL directio */ - (void) strncpy(directfile, argv[optind+6], - NSC_MAXPATH); - } else if (strcmp(argv[optind+6], "ip") != 0) { -#else - if (strcmp(argv[optind+6], "ip") != 0) { -#endif - usage(); - exit(1); - } else - (void) strcpy(directfile, "ip"); - - if (strcmp(argv[optind+7], "sync") == 0) - doasync = 0; - else if (strcmp(argv[optind+7], "async") == 0) - doasync = 1; - else { - usage(); - exit(1); - } - - /* - * At this point, we could have a set which is - * clustered, but neither a 'C ctag' or '-C ctag' has - * been specified. To avoid clobbering the ctag if a - * dscfg operation is done in the future, we should get - * the ctag out of the config at this point. To do this, - * set the cluster resource filter to NULL to look at - * all sets in the config, pulling out the ctag for the - * set matching shost:svol. If the set is not found, - * fail here. Note, we skip this set on an enable as the - * set is not yet in the config, so no need to waste - * time. - */ - if ((argc - optind == 8) && clustered && - (flag != RDC_CMD_ENABLE)) { - int setnumber; - char key[CFG_MAX_KEY]; - - if ((cfg = cfg_open(NULL)) == NULL) { - rdc_err(NULL, - gettext("unable to access configuration")); - } - if (!cfg_lock(cfg, CFG_RDLOCK)) { - rdc_err(NULL, - gettext("unable to lock configuration")); - } - - cfg_resource(cfg, NULL); - - if ((setnumber = - find_setnumber_in_libcfg(cfg, NULL, tohost, - tofile)) < 0) { - cfg_close(cfg); - rdc_err(NULL, - gettext("unable to find Remote " - "Mirror set " - "%s:%s in config"), - tohost, tofile); - } - - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", setnumber); - if (cfg_get_cstring(cfg, key, ctag_arg, - MAX_RDC_HOST_SIZE) < 0) { - cfg_close(cfg); - rdc_err(NULL, - gettext("unable to determine ctag " - "for Remote Mirror set %s:%s"), - tohost, tofile); - } - - rdc_islocal = strcmp(ctag_arg, "-") ? 0 : 1; - - cfg_close(cfg); - } - - extra_argc = argc - optind; - if (extra_argc < 8 || extra_argc > 14 || - extra_argc % 2 != 0) { - usage(); - exit(1); - } - - /* - * Loop through all of the extra arguments specified - * on the command line, setting the appropriate values - * for valid entries. If an unrecognized argument is - * detected, abort with error. Note: This hack should be - * removed and we should not accept these entries as - * arguments, they should be passed in as switches. - */ - for (i = (8 + optind); i < argc; i += 2) { - /* string case statement */ - if (strcmp(argv[i], "g") == 0) { - (void) strncpy(group, argv[i + 1], - NSC_MAXPATH); - if (group[NSC_MAXPATH - 1] != '\0') { - rdc_err(NULL, gettext("group name is " - "longer than %d characters\n"), - (NSC_MAXPATH - 1)); - } - } else if (strcmp(argv[i], "C") == 0) { - if (!clustered) { - usage(); - exit(1); - } - (void) strncpy(ctag, argv[i + 1], - MAX_RDC_HOST_SIZE); - - if (ctag[MAX_RDC_HOST_SIZE - 1] != '\0') { - rdc_err(NULL, gettext("cluster name " - "is longer than %d characters\n"), - (MAX_RDC_HOST_SIZE - 1)); - } - process_clocal(ctag); - - /* - * well here is something. - * what if they went sndradm -C local - * host a b host a b ip sync C foobar? - * they might be confused - * lets stop them if ctag_arg and ctag - * don't match and forgive if they are - * the same, below also. - */ - if ((strlen(ctag_arg) > 0) && - (strcmp(ctag_arg, ctag) != 0)) { - rdc_err(NULL, gettext("ctags " - "%s and %s do not match "), - ctag_arg, ctag); - - } - } else if (strcmp(argv[i], "q") == 0) { - (void) strncpy(diskqueue, argv[i + 1], - NSC_MAXPATH); - if (diskqueue[NSC_MAXPATH - 1] != '\0') { - rdc_err(NULL, gettext("diskq name is " - "longer than %d characters\n"), - (NSC_MAXPATH - 1)); - } - } else { - /* Unrecognized argument */ - usage(); - exit(1); - } - } - } - - /* - * Are we able to determine the existance of either - * of these host addresses? - */ - if (gethost_netaddrs(fromhost, tohost, - (char *)&fromnetaddr, (char *)&tonetaddr) < 0) { - (void) fprintf(stderr, "\n"); - rdc_warn(NULL, gettext("unable to determine IP " - "addresses for either host %s or host %s"), - fromhost, tohost); - - if (flag != RDC_CMD_DISABLE) - exit(1); - else - host_not_found = 1; - } - - /* - * Are we running on neither host? - */ - if (!self_check(fromhost) && !self_check(tohost)) { - if (flag == RDC_CMD_DISABLE) { - (void) fprintf(stderr, "\n"); - rdc_warn(NULL, gettext("Not running on either host " - "%s or host %s"), fromhost, tohost); - host_not_found = 1; - } - } - - /* - * at this point, hopfully it is safe to say that - * if a ctag was supplied via -C tag it is safe to - * move it from ctag_arg to ctag. If it was passed in - * at the end and the beginning of the cli, it must - * match, as per checks above. if it was not passed - * in at the end, but at the beginning, we can deal. - * this should handle the case of shost:svol. - * which is the main reason for this. - * - * there are 3 cases: passed in by cli, checked just above. - * using libdscfg, you must pass in -C tag to have - * ctag_check pass. - * finally a file. same rules as libdscfg. - */ - if ((strlen(ctag) == 0) && (strlen(ctag_arg) > 0)) - (void) strcpy(ctag, ctag_arg); - - if (flag == RDC_CMD_RECONFIG) { - if (reconfig_pbitmap) { - (void) strncpy(frombitmap, reconfig_pbitmap, - NSC_MAXPATH); - check_rdcbitmap(flag, fromhost, frombitmap); - } - if (reconfig_sbitmap) { - (void) strncpy(tobitmap, reconfig_sbitmap, - NSC_MAXPATH); - check_rdcbitmap(flag, tohost, tobitmap); - } -#ifdef _RDC_CAMPUS - if (reconfig_direct) - (void) strncpy(directfile, reconfig_direct, - NSC_MAXPATH); -#endif - if (reconfig_group) - (void) strncpy(group, reconfig_group, - NSC_MAXPATH); - - if (strlen(reconfig_ctag) > 0) - (void) strncpy(ctag, reconfig_ctag, - MAX_RDC_HOST_SIZE); - if (reconfig_doasync != -1) - doasync = reconfig_doasync; - } - - if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { - if (ctag_check(fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, ctag, diskqueue) < 0) - exit(1); - if ((diskq_group = check_diskqueue(NULL, diskqueue, - group)) == DISKQ_FAIL) { - rdc_err(NULL, gettext("disk queue %s is " - "incompatible with existing queue"), - diskqueue); - } - - } - pairs = 1; - } else { - pairs = read_config(flag, config_file, group_arg, ctag_arg); - if (pairs == 0) { - rdc_err(NULL, gettext("%s contains no " - "matching Remote Mirror sets"), config_file); - } - } - - if (!nflag && !pflag && prompt_user(flag, iflag) == -1) - exit(1); - - while (pairs--) { - - if (cfgflag || fflag) { - (void) strncpy(fromfile, pair_list[pairs].ffile, - NSC_MAXPATH); - (void) strncpy(tofile, pair_list[pairs].tfile, - NSC_MAXPATH); - (void) strncpy(frombitmap, pair_list[pairs].fbitmap, - NSC_MAXPATH); - (void) strncpy(fromhost, - pair_list[pairs].fhost, MAX_RDC_HOST_SIZE); - (void) strncpy(tohost, pair_list[pairs].thost, - MAX_RDC_HOST_SIZE); - (void) strncpy(tobitmap, pair_list[pairs].tbitmap, - NSC_MAXPATH); - (void) strncpy(directfile, pair_list[pairs].directfile, - NSC_MAXPATH); - (void) strncpy(group, pair_list[pairs].group, - NSC_MAXPATH); - (void) strncpy(ctag, pair_list[pairs].ctag, - MAX_RDC_HOST_SIZE); - (void) strncpy(diskqueue, pair_list[pairs].diskqueue, - NSC_MAXPATH); - - bcopy(pair_list[pairs].fnetaddr, fromnetaddr, - RDC_MAXADDR); - bcopy(pair_list[pairs].tnetaddr, tonetaddr, - RDC_MAXADDR); - - doasync = pair_list[pairs].doasync; - } - - if (pflag) { - static int first = 1; - - if (first) { - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, - gettext("unable to lock configuration")); - - first = 0; - } - - (void) rdc_print(file_format, verbose, - group_arg, ctag_arg, tohost, tofile, cfg); - - if (pairs == 0) { - cfg_close(cfg); - exit(0); - } - - /* short circuit the rest of the command loop */ - continue; - } - if (Bflag) { - int ret; - ret = rdc_bitmapset(tohost, tofile, bitfile, oflag, - boffset); - exit(ret); - } - if ((fflag || cfgflag) && flag == RDC_CMD_RECONFIG) { - char orig_fbmp[MAXHOSTNAMELEN]; - char orig_tbmp[MAXHOSTNAMELEN]; - int ret; - rdc_config_t parms; - spcs_s_info_t ustatus; - - parms.command = RDC_CMD_STATUS; - parms.rdc_set->netconfig = NULL; - (void) strncpy(parms.rdc_set->primary.intf, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->secondary.intf, tohost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->primary.file, fromfile, - NSC_MAXPATH); - (void) strncpy(parms.rdc_set->secondary.file, tofile, - NSC_MAXPATH); - ustatus = spcs_s_ucreate(); - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - rdc_err(NULL, gettext("unable to get set status" - " before reconfig operation")); - } - (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap, - NSC_MAXPATH); - (void) strncpy(orig_tbmp, - parms.rdc_set->secondary.bitmap, NSC_MAXPATH); - - if (strncmp(orig_fbmp, frombitmap, NSC_MAXPATH) != 0) - check_rdcbitmap(flag, fromhost, frombitmap); - if (strncmp(orig_tbmp, tobitmap, NSC_MAXPATH) != 0) - check_rdcbitmap(flag, tohost, tobitmap); - spcs_s_ufree(&ustatus); - - } - /* - * take a peek in the config to see if - * the bitmap is being used elsewhere - */ - if (flag == RDC_CMD_ENABLE) { - struct stat stb; - /* - * just for fun, lets see if some silly person - * specified the same vol and bitmap - */ - if ((strcmp(fromfile, frombitmap) == 0) || - (strcmp(tofile, tobitmap) == 0)) - rdc_err(NULL, gettext("volumes and bitmaps" - " must not match")); - if (self_check(fromhost)) { - check_rdcbitmap(flag, fromhost, frombitmap); - if (stat(fromfile, &stb) != 0) { - rdc_err(NULL, - gettext("unable to access %s: %s"), - fromfile, strerror(errno)); - } - if (!S_ISCHR(stb.st_mode)) { - rdc_err(NULL, - gettext("%s is not a character device"), - fromfile); - } - } else { /* on the secondary */ - check_rdcbitmap(flag, tohost, tobitmap); - /* extra check for secondary vol */ - check_rdcsecondary(tofile); - if (stat(tofile, &stb) != 0) { - rdc_err(NULL, - gettext("unable to access %s: %s"), - tofile, strerror(errno)); - } - if (!S_ISCHR(stb.st_mode)) { - rdc_err(NULL, - gettext("%s is not a character device"), - tofile); - } - } - - } - - if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE || - flag == RDC_CMD_RECONFIG) { - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, - gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_WRLOCK)) - rdc_err(NULL, - gettext("unable to lock configuration")); - - cfg_resource(cfg, clustered ? ctag : NULL); - } else - cfg = NULL; - - if (cfg && perform_autosv() && - (flag == RDC_CMD_ENABLE || flag == RDC_CMD_DISABLE || - flag == RDC_CMD_RECONFIG)) { - if (cfg_load_svols(cfg) < 0 || - cfg_load_dsvols(cfg) < 0 || - cfg_load_shadows(cfg) < 0) - rdc_err(NULL, - gettext("Unable to parse config filer")); - load_rdc_vols(cfg); - } - cfg_success = (cfg == NULL); - if (cfg && flag == RDC_CMD_ENABLE) { - /* Enabled, so add the set via libcfg */ - - /* Build a new sndr entry and put it */ - group_p = *group? group : place_holder; - diskqueue_p = *diskqueue? diskqueue : place_holder; - - if ((diskqueue_p == place_holder) && - (group_p != place_holder)) { - get_group_diskq(cfg, group_p, diskqueue); - if (*diskqueue) - diskqueue_p = diskqueue; - } - - /* - * format in pconfig is: - * phost.primary.pbitmap.shost.secondary. - * sbitmap.type.mode.group.cnode.options.diskq - */ - (void) snprintf(buf, sizeof (buf), - "%s %s %s %s %s %s %s %s %s %s - %s", - fromhost, fromfile, frombitmap, tohost, tofile, - tobitmap, directfile, - doasync? "async" : "sync", group_p, - clustered? ctag : "-", diskqueue_p); - - if (cfg_put_cstring(cfg, "sndr", buf, strlen(buf)) < 0) - rdc_warn(NULL, - gettext("unable to add \"%s\" to " - "configuration storage: %s"), - buf, cfg_error(&sev)); - setnumber = find_setnumber_in_libcfg(cfg, clustered? - ctag : NULL, tohost, tofile); - if (setnumber < 0) - rdc_warn(NULL, - gettext("unable to add \"%s\" to " - "configuration storage: %s"), - diskqueue_p, cfg_error(&sev)); - - else - cfg_success = 1; - - /* Add cluster aware info */ - if (clustered && !rdc_islocal) { - (void) snprintf(key, sizeof (key), - "sndr.set%d.options", setnumber); - if (self_check(fromhost)) { - if (cfg_put_options(cfg, CFG_SEC_CONF, - key, "lghn", fromhost) < 0) { - rdc_err(NULL, - gettext("unable to add " - "\"%s\" to configuration " - "storage: %s"), - fromhost, cfg_error(&sev)); - } - } else if (self_check(tohost)) { - if (cfg_put_options(cfg, CFG_SEC_CONF, - key, "lghn", tohost) < 0) { - rdc_err(NULL, - gettext("unable to add " - "\"%s\" to configuration " - "storage: %s"), - fromhost, cfg_error(&sev)); - } - } - } - } else if (cfg && flag == RDC_CMD_DISABLE) { - found = 0; - /* Disabled, so delete the set via libcfg */ - - /* get sndr entries until shost, sfile match */ - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - (void) snprintf(key, sizeof (key), "sndr.set%d", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) { - break; - } - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, tofile) != 0) - continue; - (void) snprintf(key, sizeof (key), - "sndr.set%d.shost", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, tohost) != 0) - continue; - found = 1; -#ifdef DEBUG - if (checksetfields == -1) { - rdc_err(NULL, - gettext("checksetfields not set")); - } -#endif - if (checksetfields) { - checkgfields(cfg, setnumber, fromhost, - fromfile, frombitmap, tobitmap, - directfile, (doasync == 1) - ? "async" : "sync", group, ctag, - diskqueue); - } - - /* perform cluster specific options */ - if (clustered) { - /* get the logical host, if set */ - (void) snprintf(key, sizeof (key), - "sndr.set%d.options", setnumber); - (void) cfg_get_single_option(cfg, - CFG_SEC_CONF, key, "lghn", - lhname, MAX_RDC_HOST_SIZE); - - /* figure out the cluster tag, if any */ - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, ctag)) - rdc_err(NULL, gettext("ctags %s" - " and %s do not match"), - buf, ctag); - } else { - *lhname = '\0'; - *ctag = '\0'; - } - - /* figure out the disk queue, if any */ - (void) snprintf(key, sizeof (key), - "sndr.set%d.diskq", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strlen(buf) > 0) { - (void) strncpy(diskqueue, buf, - NSC_MAXPATH); - } else { - *diskqueue = '\0'; - } - (void) snprintf(key, sizeof (key), "sndr.set%d", - setnumber); - if (cfg_put_cstring(cfg, key, NULL, 0) < 0) - rdc_warn(NULL, - gettext("unable to remove \"%s\" " - "from configuration storage: %s"), - buf, cfg_error(&sev)); - else - cfg_success = 1; - break; - } - if (found == 0) { - rdc_err(NULL, - gettext("Unable to find %s:%s in " - "configuration storage"), - tohost, tofile); - } - if (host_not_found) { - rdc_force_disable(cfg, fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap, ctag, - lhname); - if (cfg_commit(cfg) < 0) - rdc_err(NULL, gettext("commit on " - "force disable failed")); - cfg_close(cfg); - return (0); - } - } else if (cfg && flag == RDC_CMD_RECONFIG) { - /* Update relevant cfg record */ - - cfg_resource(cfg, NULL); - - /* get sndr entries until shost, sfile match */ - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - (void) snprintf(key, sizeof (key), "sndr.set%d", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) { - break; - } - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, tofile) != 0) - continue; - (void) snprintf(key, sizeof (key), - "sndr.set%d.shost", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, tohost) != 0) - continue; - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", - setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if (reconfig_ctag[0] == '\0') - (void) strncpy(ctag, buf, - sizeof (ctag)); - if (doasync) - (void) strcpy(mode, "async"); - else - (void) strcpy(mode, "sync"); - if (strcmp(directfile, "") == 0) - (void) strcpy(directfile, "ip"); - - group_p = strlen(group) > 0 ? group : - place_holder; - - /* - * if we are reconfigging out altogether, - * get rid of the diskqueue - */ - if (group_p == place_holder) - diskqueue_p = place_holder; - else - diskqueue_p = strlen(diskqueue) > 0 ? - diskqueue : place_holder; - - /* - * do a little diskq dance here for reconfigs - * that did not specify the diskqueue whilst - * reconfigging ... - */ - if ((diskqueue_p == place_holder) && - (group_p != place_holder)) { - get_group_diskq(cfg, group_p, - diskqueue); - diskqueue_p = strlen(diskqueue) > 0 ? - diskqueue : place_holder; - } - - (void) snprintf(key, sizeof (key), - "sndr.set%d.options", setnumber); - if (cfg_get_cstring(cfg, key, options_cfg, - CFG_MAX_BUF) < 0) { - break; - } - - ctag_p = strlen(ctag) > 0 ? - ctag : place_holder; - (void) snprintf(buf, sizeof (buf), - "%s %s %s %s %s %s %s %s %s %s %s %s", - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - directfile, mode, group_p, - ctag_p, options_cfg, diskqueue_p); - - (void) snprintf(key, sizeof (key), "sndr.set%d", - setnumber); - if (cfg_put_cstring(cfg, key, buf, - strlen(buf)) < 0) - rdc_warn(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - else - cfg_success = 1; - break; - } - } - - if (cfg_success) { - if (cfg && perform_autosv()) { - if (self_check(fromhost)) { - if (diskqueue[0] && - (strcmp(diskqueue, fromfile) == 0) || - (strcmp(diskqueue, frombitmap) == 0)) { - rdc_err(NULL, gettext("disk " - "queue volume %s must not " - "match any primary Remote " - "Mirror volume or bitmap"), - diskqueue); - } - - if (diskqueue[0]) { - different_devs(fromfile, diskqueue); - different_devs(frombitmap, diskqueue); - validate_name(cfg, diskqueue); - } - different_devs(fromfile, frombitmap); - validate_name(cfg, fromfile); - validate_name(cfg, frombitmap); - } else { - different_devs(tofile, tobitmap); - validate_name(cfg, tofile); - validate_name(cfg, tobitmap); - } - } - /* - * okay, if the command is sync, just build - * a list of rdcconfig_t's after the pairs-- - * loop is done, we will pass this list to - * librdc to multithread the syncs (after - * forking off a daemonish type process - * that waits for the libcall to complete - * ints of interest: - * flag ie RDC_CMD_COPY, iflag RDC_OPT_UPDATE, - * reverse RDC_OPT_REVERSE, RDC_OPT_FORWARD - * if necessary, turn autosync back on - */ - if (flag == RDC_CMD_COPY) { - if (autosync_is_on(tohost, tofile) == - AUTOSYNC_ON) - enable_autosync(fromhost, fromfile, - tohost, tofile); - - if (sets == NULL) { - sets_p = sets = - rdc_alloc_config(fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap, "mode", "group", "ctag", - "options", 0); - - if (sets_p == NULL) { - rdc_err(NULL, - gettext("rdc config alloc" - "failed %s"), rdc_error(NULL)); - } - continue; - } - - sets_p = sets_p->next = - rdc_alloc_config(fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap, - "mode", "group", "ctag", "options", 0); - - if (sets_p == NULL) { - rdc_err(NULL, gettext("rdc config alloc" - "failed %s"), rdc_error(NULL)); - } - continue; - } - - /* - * block incoming signals until after the possible - * cfg_commit is done - */ - block_sigs(); - if (rdc_operation(cfg, fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, flag, iflag, directfile, - group, ctag, diskqueue, &doasync, reverse) < 0) { - ; - /*EMPTY*/ - } else if (cfg) { - if (diskq_group == DISKQ_REWRITEG) { - rewrite_group_diskqueue(cfg, - &pair_list[pairs], diskqueue); - } - if (perform_autosv() && - (flag == RDC_CMD_ENABLE || - flag == RDC_CMD_DISABLE || - flag == RDC_CMD_RECONFIG)) { - unload_rdc_vols(); - cfg_unload_shadows(); - cfg_unload_dsvols(); - cfg_unload_svols(); - } - if ((iflag & RDC_OPT_REVERSE_ROLE) != 0 && - allow_role) { - bzero(tmphost, MAX_RDC_HOST_SIZE); - bzero(tmpfile, NSC_MAXPATH); - bzero(tmpbitmap, NSC_MAXPATH); - (void) strncpy(tmphost, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(tmpfile, fromfile, - NSC_MAXPATH); - (void) strncpy(tmpbitmap, frombitmap, - NSC_MAXPATH); - - (void) strncpy(fromhost, tohost, - MAX_RDC_HOST_SIZE); - (void) strncpy(fromfile, tofile, - NSC_MAXPATH); - (void) strncpy(frombitmap, tobitmap, - NSC_MAXPATH); - - (void) strncpy(tohost, tmphost, - MAX_RDC_HOST_SIZE); - (void) strncpy(tofile, tmpfile, - NSC_MAXPATH); - (void) strncpy(tobitmap, tmpbitmap, - NSC_MAXPATH); - group_p = strlen(group) > 0 ? group : - place_holder; - diskqueue_p = strlen(diskqueue) > 0 ? - diskqueue : place_holder; - ctag_p = strlen(ctag) > 0 ? - ctag : place_holder; - (void) snprintf(buf, sizeof (buf), "%s " - "%s %s %s %s %s %s %s %s %s %s %s", - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - directfile, mode, group_p, - ctag_p, options_cfg, diskqueue_p); - - (void) snprintf(key, sizeof (key), - "sndr.set%d", setnumber); - if (cfg_put_cstring(cfg, key, buf, - strlen(buf)) < 0) - rdc_err(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - } - if (cfg_commit(cfg) < 0) { - rdc_err(NULL, gettext("commit on role " - "reversal failed")); - } - } - unblock_sigs(); - } - - if (cfg) { - cfg_close(cfg); - } - - } - if (flag == RDC_CMD_COPY) { - pid = fork(); - if (pid == -1) { /* error forking */ - perror("fork"); - exit(1); - } - } else { - exit(0); - } - if (pid > 0) /* parent process */ - exit(0); - - spcslog_sync(sets, 1, iflag); - if (iflag & RDC_OPT_REVERSE) { - if (iflag & RDC_OPT_UPDATE) - rclist = rdc_ursync(sets); - else - rclist = rdc_rsync(sets); - } else if (iflag & RDC_OPT_UPDATE) { - rclist = rdc_usync(sets); - } else - rclist = rdc_fsync(sets); - - rcp = rclist; - while (rcp) { - if (rcp->rc < 0) { - /* rclist->msg has already been gettext'd */ - (void) fprintf(stderr, - gettext("Remote Mirror: %s %s %s %s %s %s\n"), - rcp->set.phost, rcp->set.pfile, rcp->set.pbmp, - rcp->set.shost, rcp->set.sfile, rcp->set.sbmp); - rdc_warn(NULL, "%s", rcp->msg); - spcs_log("sndr", NULL, "%s", rcp->msg); - } - rcp = rcp->next; - } - - spcslog_sync(sets, 0, iflag); - - if (sets) - rdc_free_config(sets, RDC_FREEALL); - if (rclist) - rdc_free_rclist(rclist); - - return (0); -} -/* - * process_clocal() - * pre: a non null string - * post: if the string is "local" - * then it is converted to "-" - * and rdc_islocal is set to 1 - * if not rdc_islocal set to 0 - */ -void -process_clocal(char *ctag) -{ - /* - * Check for the special cluster tag and convert into the - * internal representation. - */ - - if (ctag != NULL && strcmp(ctag, RDC_LOCAL_TAG) == 0) { - (void) strcpy(ctag, "-"); - rdc_islocal = 1; - } else { - rdc_islocal = 0; - } -} - -static void -rdc_check_dgislocal(char *dgname) -{ - char *othernode; - int rc; - - /* - * check where this disk service is mastered - */ - - rc = cfg_dgname_islocal(dgname, &othernode); - if (rc < 0) { - rdc_err(NULL, gettext("unable to find " - "disk service, %s: %s"), dgname, strerror(errno)); - } - - if (rc == 0) { - rdc_err(NULL, gettext("disk service, %s, is " - "active on node \"%s\"\nPlease re-issue " - "the command on that node"), dgname, othernode); - } -} - -static void -different_devs(char *dev1, char *dev2) -{ - struct stat buf1, buf2; - - if (stat(dev1, &buf1) < 0) { - spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"), - dev1); - rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev1); - } - if (stat(dev2, &buf2) < 0) { - spcs_log("sndr", NULL, gettext("Remote Mirror: can't stat %s"), - dev2); - rdc_err(NULL, gettext("Remote Mirror: can't stat %s"), dev2); - } - if (buf1.st_rdev == buf2.st_rdev) { - spcs_log("sndr", NULL, gettext("Remote Mirror: '%s' and '%s' " - "refer to the same device"), dev1, dev2); - rdc_err(NULL, gettext("Remote Mirror: '%s' and '%s' refer to " - "the same device"), dev1, dev2); - } -} - -static void -validate_name(CFGFILE *cfg, char *vol) -{ - char *altname; - int rc; - - if (!cfg) { - rdc_err(NULL, gettext("Remote Mirror: null cfg ptr in " - "validate_name")); - } - - rc = cfg_get_canonical_name(cfg, vol, &altname); - if (rc < 0) { - spcs_log("sndr", NULL, gettext("Remote Mirror: unable to parse " - "config file\n")); - rdc_err(NULL, gettext("Remote Mirror: unable to parse config " - "file\n")); - } - if (rc) { - spcs_log("sndr", NULL, gettext("Remote Mirror: '%s': already " - "configured as '%s'"), vol, altname); - rdc_err(NULL, gettext("Remote Mirror: The volume '%s' has been " - "configured previously as '%s'. Re-enter command with " - "the latter name."), vol, altname); - } -} - -/* - * Add the autosync value to the option field for the sndr set specified by - * tohost:tofile. - * - * ASSUMPTIONS: - * - cfg file is available to take a write lock. - * - set is already configured in dscfg - * - * INPUTS: - * autosync_val - value to set autosync to - * tohost - secondary host - * tofile - secondary volume - * - * OUTPUTS: - * none. - * - */ -static void -set_autosync(int autosync_val, char *tohost, char *tofile, char *ctag) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - char tag[CFG_MAX_BUF], val[CFG_MAX_BUF]; - char auto_tag[CFG_MAX_BUF]; - _sd_dual_pair_t pair; - _sd_dual_pair_t tmpair; - int setnumber, options = 0, already_set = 0, cfg_success = 0; - int set; - - /* verify valid autosync request */ - if ((autosync_val != AUTOSYNC_ON) && (autosync_val != AUTOSYNC_OFF)) { -#ifdef DEBUG - rdc_warn(NULL, - gettext("set_autosync called with improper value")); -#endif - return; - } - - if ((cfg = cfg_open(NULL)) == NULL) { - rdc_err(NULL, gettext("unable to access configuration")); - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - rdc_err(NULL, gettext("unable to lock configuration")); - } - - if (clustered) { - cfg_resource(cfg, ctag); - } else { - cfg_resource(cfg, NULL); - } - - /* find set number in config */ - if ((setnumber = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL, - tohost, tofile)) < 0) { - cfg_close(cfg); - rdc_err(NULL, gettext("unable to find Remote Mirror set %s:%s: " - "in config"), tohost, tofile); - } - (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnumber); - (void) snprintf(auto_tag, sizeof (auto_tag), "auto"); - - /* Check if there are any options already set, including ours */ - if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val, - CFG_MAX_BUF) >= 0) { - options = 1; - - do { - if (strcmp(tag, auto_tag) == 0) { - already_set = 1; - } - } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag, - CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0); - } - - /* options already exist, edit ours out */ - if (options && already_set) { - char *p, *q; - int need_to_clear_buf = 1; - - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - rdc_err(NULL, gettext("unable to get options field " - "for Remote Mirror set %s:%s"), tohost, tofile); - } - - /* parse out our options, all of the form "auto=" */ - p = strdup(buf); - bzero(buf, sizeof (buf)); - - q = strtok(p, ";"); - do { - /* if another tag/value exists, keep it */ - if (strncmp(auto_tag, q, 4) != 0) { - (void) strcat(buf, q); - (void) strcat(buf, ";"); - need_to_clear_buf = 0; - } - } while (q = strtok(NULL, ";")); - free(p); - - /* if we were the only option, clear the field */ - if (need_to_clear_buf) { - (void) strcat(buf, "-"); - } - - if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - rdc_err(NULL, gettext("unable to clear autosync value " - "in config for Remote Mirror set %s:%s"), tohost, - tofile); - } else { - cfg_success = 1; - } - } - - /* autosync is not present in options field, add if on is requested */ - if (autosync_val == AUTOSYNC_ON) { - if (cfg_put_options(cfg, CFG_SEC_CONF, key, auto_tag, "on") - < 0) { - rdc_err(NULL, gettext("unable to update autosync value " - "in config for Remote Mirror set %s:%s"), tohost, - tofile); - } else { - cfg_success = 1; - } - } - /* if we are in a group, update any other sets in the same group */ - do { - bzero(&pair, sizeof (pair)); - bzero(buf, CFG_MAX_BUF); - - (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - if (parse_cfg_buf(buf, &pair, NULL)) - break; - if (pair.group == NULL) /* not in a group */ - break; - if (!pair.group[0]) - break; /* not in a group */ - for (set = 1; /*CSTYLED*/; set++) { - if (set == setnumber) - continue; - bzero(buf, CFG_MAX_BUF); - options = 0; - already_set = 0; - - (void) snprintf(key, sizeof (key), "sndr.set%d", set); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; /* last set processed */ - } - bzero(&tmpair, sizeof (tmpair)); - if (parse_cfg_buf(buf, &tmpair, NULL)) - break; - if (strcmp(pair.group, tmpair.group) != 0) - continue; /* not the group we want */ - - (void) snprintf(key, sizeof (key), "sndr.set%d.options", - set); - /* - * Check if there are any options already set, - * including ours - */ - if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, - CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0) { - options = 1; - - do { - if (strcmp(tag, auto_tag) == 0) { - already_set = 1; - } - } while (cfg_get_options(cfg, CFG_SEC_CONF, - NULL, tag, CFG_MAX_BUF, val, - CFG_MAX_BUF) >= 0); - } - - /* options already exist, edit ours out */ - if (options && already_set) { - char *p, *q; - int need_to_clear_buf = 1; - - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) - < 0) { - rdc_err(NULL, gettext("unable to get " - "options field for Remote Mirror set " - "%s:%s"), tmpair.thost, tmpair.tfile); - } - - /* - * parse out our options, all of the - * form "auto=" - */ - p = strdup(buf); - bzero(buf, sizeof (buf)); - - q = strtok(p, ";"); - do { - /* - * if another tag/value exists, - * keep it - */ - if (strncmp(auto_tag, q, 4) != 0) { - (void) strcat(buf, q); - (void) strcat(buf, ";"); - need_to_clear_buf = 0; - } - } while (q = strtok(NULL, ";")); - free(p); - - /* - * if we were the only option, - * clear the field - */ - if (need_to_clear_buf) { - (void) strcat(buf, "-"); - } - - if (cfg_put_cstring(cfg, key, buf, CFG_MAX_BUF) - < 0) { - rdc_err(NULL, gettext("unable to clear " - "autosync value in config for " - "Remote Mirror set %s:%s"), - tmpair.thost, tmpair.tfile); - cfg_success = 0; - } - } - - /* - * autosync is not present in options field, - * add if on is requested - */ - if (autosync_val == AUTOSYNC_ON) { - if (cfg_put_options(cfg, CFG_SEC_CONF, key, - auto_tag, "on") < 0) { - rdc_err(NULL, gettext("unable to update" - " autosync value in config for " - "Remote Mirror set %s:%s"), - tmpair.thost, - tmpair.tfile); - cfg_success = 0; - } - } - } - - /* CONSTCOND */ - } while (0); - if (cfg_success) { - if (cfg_commit(cfg) < 0) { - rdc_err(NULL, gettext("commit on role reversal failed")); - } - } - - cfg_close(cfg); -} - -/* - * Check to see if autosync is on for set specified by tohost:tofile. - * - * ASSUMPTIONS: - * config is available to take a read lock against it. - * - * INPUTS: - * tohost - secondary host - * tofile - secondary volume - * - * OUTPUTS: - * -1 error - * AUTOSYNC_ON if autosync is on - * AUTOSYNC_OFF if autosync is off - */ -static int -autosync_is_on(char *tohost, char *tofile) -{ - CFGFILE *cfg; - int setnumber, autosync_val = AUTOSYNC_OFF; - char key[CFG_MAX_KEY]; - char tag[CFG_MAX_BUF], val[CFG_MAX_BUF]; - - if ((cfg = cfg_open(NULL)) == NULL) { - rdc_err(NULL, gettext("unable to access configuration")); - } - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - cfg_close(cfg); - rdc_err(NULL, gettext("unable to lock configuration")); - } - - if ((setnumber = find_setnumber_in_libcfg(cfg, NULL, tohost, tofile)) < - 0) { - cfg_close(cfg); - rdc_err(NULL, gettext("cannot find Remote Mirror set %s:%s in " - "config"), tohost, tofile); - } - - (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnumber); - if (cfg_get_options(cfg, CFG_SEC_CONF, key, tag, CFG_MAX_BUF, val, - CFG_MAX_BUF) >= 0) { - do { - if (strcmp(tag, "auto") == 0) { - if (strcmp(val, "on") == 0) { - autosync_val = AUTOSYNC_ON; - } - break; - } - } while (cfg_get_options(cfg, CFG_SEC_CONF, NULL, tag, - CFG_MAX_BUF, val, CFG_MAX_BUF) >= 0); - } - - cfg_close(cfg); - return (autosync_val); -} - -void -enable_autosync(char *fhost, char *ffile, char *thost, char *tfile) -{ - rdc_config_t parms; - spcs_s_info_t ustat; - rdc_addr_t *p; - - ustat = spcs_s_ucreate(); - parms.command = RDC_CMD_TUNABLE; - - p = &parms.rdc_set[0].primary; - (void) strncpy(p->intf, fhost, MAX_RDC_HOST_SIZE); - (void) strncpy(p->file, ffile, MAX_RDC_HOST_SIZE); - - p = &parms.rdc_set[0].secondary; - (void) strncpy(p->intf, thost, NSC_MAXPATH); - (void) strncpy(p->file, tfile, NSC_MAXPATH); - - parms.rdc_set[0].autosync = 1; - parms.rdc_set[0].maxqfbas = -1; - parms.rdc_set[0].maxqitems = -1; - parms.rdc_set[0].asyncthr = -1; - parms.rdc_set[0].netconfig = NULL; - - if ((RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustat)) != - SPCS_S_OK) { - rdc_warn(&ustat, gettext("failed to update autosync for" - " Remote Mirror set %s:%s"), thost, tfile); - spcs_log("sndr", &ustat, gettext("failed to update autosync for" - " Remote Mirror set %s:%s"), thost, tfile); - } - spcs_s_ufree(&ustat); -} - -static int -rdc_operation(CFGFILE *cfg, char *fromhost, char *fromfile, char *frombitmap, - char *tohost, char *tofile, char *tobitmap, - int flag, int iflag, - char *directfile, char *group, char *ctag, char *diskqueue, - int *doasync, int reverse) -{ - const int getaddr = (flag == RDC_CMD_ENABLE); - const int rpcbind = !getaddr; - rdc_config_t parms; - int ret; - spcs_s_info_t ustatus; - struct hostent *hp; - char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN]; - char orig_fbmp[MAXHOSTNAMELEN], orig_tbmp[MAXHOSTNAMELEN]; - char orig_diskq[NSC_MAXPATH]; - struct t_info tinfo; - int success = 1; - int autosync_toggle_needed = 0; - char *vol1, *vol2, *vol3; - - conf = &nconf; - - hp = gethost_byname(fromhost); - (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN); - hp = gethost_byname(tohost); - (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN); - - if (self_check(fromname) && self_check(toname)) { - rdc_err(NULL, gettext("both %s and %s are local"), - fromhost, tohost); - } - - /* we have to find out what to sv disable after reconfig */ - if (flag == RDC_CMD_RECONFIG) { - - parms.command = RDC_CMD_STATUS; - parms.rdc_set->netconfig = NULL; - (void) strncpy(parms.rdc_set->primary.intf, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->secondary.intf, tohost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->primary.file, fromfile, - NSC_MAXPATH); - (void) strncpy(parms.rdc_set->secondary.file, tofile, - NSC_MAXPATH); - ustatus = spcs_s_ucreate(); - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - rdc_err(NULL, gettext("unable to get set status" - " before reconfig operation")); - } - (void) strncpy(orig_fbmp, parms.rdc_set->primary.bitmap, - NSC_MAXPATH); - (void) strncpy(orig_tbmp, parms.rdc_set->secondary.bitmap, - NSC_MAXPATH); - (void) strncpy(orig_diskq, parms.rdc_set->disk_queue, - NSC_MAXPATH); - } - - /* - * another terrible addition, if we are reconfigging mode - * and not logging, just give up. - */ - if ((reconfig_doasync != -1) && - (!(parms.rdc_set->flags & RDC_LOGGING))) { - rdc_err(NULL, gettext("cannot reconfigure sync/async, " - "Remote Mirror set not logging")); - spcs_log("sndr", NULL, gettext("cannot reconfigure sync/async, " - "Remote Mirror set not logging")); - } - - /* - * Now build up the address for each host including port and transport - */ - if (getaddr) { - svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN, - &conf, proto_test ? NC_UDP:NULL, "rdc", &tinfo, - rpcbind); - - if (svp == NULL) { - rdc_warn(NULL, gettext("unable to determine network " - "information for %s"), toname); -#ifdef DEBUG - (void) printf("get_addr failed for Ver 4 %s\n", toname); -#endif - return (-1); - } - svaddr = *svp; - } else { - bzero(&svaddr, sizeof (svaddr)); - } - - parms.rdc_set->secondary.addr.len = svaddr.len; - parms.rdc_set->secondary.addr.maxlen = - svaddr.maxlen; - parms.rdc_set->secondary.addr.buf = - (void *)svaddr.buf; - -#ifdef DEBUG_ADDR - (void) fprintf(stderr, "secondary buf %x len %d\n", - svaddr.buf, svaddr.len); - - for (i = 0; i < svaddr.len; i++) - (void) printf("%u ", svaddr.buf[i]); - (void) printf("\n"); -#endif - - if (getaddr) { - svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN, - &conf, proto_test ? NC_UDP: NULL, "rdc", &tinfo, - rpcbind); - if (svp == NULL) { -#ifdef DEBUG - (void) printf("get_addr failed for Ver 4 %s\n", - fromname); -#endif - return (-1); - } - svaddr = *svp; - } - - parms.rdc_set->primary.addr.len = svaddr.len; - parms.rdc_set->primary.addr.maxlen = svaddr.maxlen; - parms.rdc_set->primary.addr.buf = (void *)svaddr.buf; - -#ifdef DEBUG_ADDR - (void) fprintf(stderr, "primary buf %x len %d\n", - svaddr.buf, svaddr.len); - for (i = 0; i < svaddr.len; i++) - (void) printf("%u ", svaddr.buf[i]); - (void) printf("\n"); -#endif - - if (getaddr) { - (void) convert_nconf_to_knconf(conf, &knconf); -#ifdef DEBUG_ADDR - (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics, - knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev); -#endif - parms.rdc_set->netconfig = &knconf; - } else { - parms.rdc_set->netconfig = NULL; - } - - if (!self_check(fromname) && !self_check(toname)) { - if (!clustered) - rdc_err(NULL, gettext("neither %s nor %s is local"), - fromhost, tohost); - else { - /* - * IF we could get a list of logical hosts on this cluster - * Then we could print something intelligent about where - * the volume is mastered. For now, just print some babble - * about the fact that we have no idea. - */ - rdc_err(NULL, - gettext("either %s:%s or %s:%s is not local"), - fromhost, fromfile, tohost, tofile); - } - } - - (void) strncpy(parms.rdc_set->primary.intf, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH); - - (void) strncpy(parms.rdc_set->secondary.intf, tohost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH); - - if ((group == NULL) || ((strcmp(group, "-")) == 0)) - parms.rdc_set->group_name[0] = 0; - else - (void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH); - - if (self_check(tohost) && - (strlen(diskqueue) > 0) && (diskqueue[0] != '-')) - if ((flag == RDC_CMD_ENABLE) || (flag == RDC_CMD_ADDQ)) - rdc_err(NULL, gettext("enabling disk queue on a Remote" - " Mirror secondary is not allowed (%s)"), - diskqueue); - - if ((diskqueue == NULL) || ((strcmp(diskqueue, "-")) == 0)) - parms.rdc_set->disk_queue[0] = 0; - else - (void) strncpy(parms.rdc_set->disk_queue, diskqueue, - NSC_MAXPATH); - - parms.rdc_set->maxqfbas = maxqfbas; - parms.rdc_set->maxqitems = maxqitems; - parms.rdc_set->asyncthr = asyncthr; - /* set up the permanent set id for this set */ - if (flag == RDC_CMD_ENABLE) { - char key[CFG_MAX_KEY]; - char setid[64]; - int set; - parms.rdc_set->setid = get_new_cfg_setid(cfg); - if (parms.rdc_set->setid <= 0) { - rdc_err(NULL, gettext("unable to obtain unique set id " - "for %s:%s"), tohost, tofile); - } - if ((set = find_setnumber_in_libcfg(cfg, clustered? ctag : NULL, - tohost, tofile)) < 0) { - rdc_err(NULL, gettext("unable to store unique set id" - " for %s:%s"), tohost, tofile); - } - (void) snprintf(key, sizeof (key), "sndr.set%d.options", set); - (void) snprintf(setid, sizeof (setid), "%d", - parms.rdc_set->setid); - - if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", - setid) < 0) { - rdc_err(NULL, gettext("unable to store unique set " - "id for %s:%s: %s"), tohost, tofile, - gettext(cfg_error(NULL))); - } - } else if (flag != RDC_CMD_DISABLE) { /* set already gone from cfg */ - parms.rdc_set->setid = get_cfg_setid(cfg, ctag, tohost, tofile); - if (parms.rdc_set->setid <= 0) { - rdc_err(NULL, gettext("unable to obtain unique set id " - "for %s:%s"), tohost, tofile); - } - } - - /* - * Always set autosync flag to default so nothing gets messed up. If - * we are doing an autosync operation, it'll all get taken care of - * then. - */ - parms.rdc_set->autosync = AUTOSYNC; - - - /* gethostid(3c) is defined to return a 32bit value */ - parms.rdc_set->syshostid = (int32_t)gethostid(); - - parms.command = 0; - parms.options = iflag; - parms.command = flag; - if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { - if (*doasync) - parms.options |= RDC_OPT_ASYNC; - else - parms.options |= RDC_OPT_SYNC; - } else if (flag == RDC_CMD_COPY) { - if (reverse) - parms.options |= RDC_OPT_REVERSE; - else - parms.options |= RDC_OPT_FORWARD; - } - - if (self_check(fromname)) { - if (flag == RDC_CMD_COPY && reverse && mounted(fromfile)) - rdc_err(NULL, gettext("can not start reverse sync" - " as a file system is mounted on %s"), - fromfile); - parms.options |= RDC_OPT_PRIMARY; - if (strcmp(directfile, "ip") == 0) - parms.rdc_set->direct_file[0] = 0; /* no directfile */ - else - (void) strncpy(parms.rdc_set->direct_file, directfile, - NSC_MAXPATH); - } else { - parms.options |= RDC_OPT_SECONDARY; - parms.rdc_set->direct_file[0] = 0; /* no fcal directio */ - } - - if ((asyncthr || maxqitems || maxqfbas || qblock) && - (parms.options & RDC_OPT_SECONDARY)) { - rdc_err(NULL, gettext("changing queue parameters may " - " only be done on a primary Remote Mirror host")); - spcs_log("sndr", NULL, gettext("changing queue parameters may " - " only be done on a primary Remote Mirror host")); - - } - - ustatus = spcs_s_ucreate(); - - if (flag == RDC_CMD_COPY) { - parms.command = RDC_CMD_STATUS; - ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); - if ((ret != SPCS_S_OK) || - !(parms.rdc_set->flags & RDC_LOGGING)) { - rdc_err(NULL, gettext("can not start sync" - " as Remote Mirror set %s:%s is not logging"), - tohost, tofile); - } - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\nStarting"), - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap); - parms.command = RDC_CMD_COPY; - } - - if ((flag == RDC_CMD_COPY) && - (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) { - /* check if autosync needs to be turned on when doing a copy/update */ - parms.rdc_set->autosync = AUTOSYNC_ON; - autosync_toggle_needed = 1; - } else if ((flag == RDC_CMD_LOG) && - (autosync_is_on(tohost, tofile) == AUTOSYNC_ON)) { - /* check if autosync needs to be turned off when going to logging */ - parms.rdc_set->autosync = AUTOSYNC_OFF; - autosync_toggle_needed = 1; - } else if (((autosync == AUTOSYNC_ON) || (autosync == AUTOSYNC_OFF)) && - (flag == RDC_CMD_TUNABLE)) { - /* - * Request to change the autosync value. cfg file will be - * available at this point. If autosync request is to turn off, - * mark off in both the config and the kernel regardless of - * the state of the set. If the request is to turn autosync on, - * set in the kernel if the set is not in logging mode. - * - * XXX - * If the set is in logging mode because of a network - * failure, we will not know. Therefore, a manual update - * will have to be issued to enable autosync in the - * kernel. - * XXX - */ - set_autosync(autosync, tohost, tofile, ctag); - - if (autosync == AUTOSYNC_OFF) { - parms.rdc_set->autosync = AUTOSYNC_OFF; - } else if (autosync == AUTOSYNC_ON) { - parms.command = RDC_CMD_STATUS; - ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, - ustatus); - if (ret != SPCS_S_OK) { - rdc_err(NULL, gettext("can not determine " - "status of Remote Mirror set %s:%s"), - tohost, tofile); - } - - /* need to reset the tunables after a status ioctl */ - parms.rdc_set->autosync = autosync; - parms.rdc_set->maxqfbas = maxqfbas; - parms.rdc_set->maxqitems = maxqitems; - parms.rdc_set->asyncthr = asyncthr; - - /* - * if in logging mode, just update config, kernel will - * be updated with the next copy/update request. - */ - if (parms.rdc_set->flags & RDC_LOGGING) { - parms.rdc_set->autosync = AUTOSYNC; - } else { - parms.rdc_set->autosync = AUTOSYNC_ON; - } - - parms.command = flag; - } - } - - if (autosync_toggle_needed) { - parms.command = RDC_CMD_TUNABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - spcs_log("sndr", NULL, gettext("failed to update " - "autosync for Remote Mirror set %s:%s"), tohost, - tofile); - rdc_err(NULL, gettext("failed to update autosync for " - "Remote Mirror set %s:%s"), tohost, tofile); - } - /* reset command and default autosync flags */ - parms.rdc_set->autosync = AUTOSYNC; - parms.command = flag; - } - - errno = 0; - ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); - if ((ret != SPCS_S_OK) && (flag != RDC_CMD_HEALTH)) { - (void) fprintf(stderr, - gettext("Remote Mirror: %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap); - - if (errno == RDC_EEINVAL) { - spcs_log("sndr", NULL, - "%s %s %s %s %s %s %s %s\n%s", - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - gettext("invalid command option")); - rdc_err(&ustatus, - gettext("Remote Mirror: invalid command option " - "'%s'"), rdc_decode_flag(flag, - parms.options)); - } else { - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap); - if ((flag == RDC_CMD_RECONFIG) && - (!(iflag & RDC_OPT_REVERSE_ROLE))) { - success = 0; - rdc_warn(&ustatus, 0); - } else - rdc_err(&ustatus, 0); - } - } - if ((flag == RDC_CMD_RECONFIG) && (iflag & RDC_OPT_REVERSE_ROLE) == 0) { - parms.command = RDC_CMD_STATUS; - if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) == - SPCS_S_OK) { - char shostbuf[CFG_MAX_BUF]; - char svolbuf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int i, numels; - int cfgsuccess = 1; - - /* - * okeydoke, at this point we could have a reconfig - * gone bad. libdscfg does not know about this. - * parms contains the kernel picture, and we know - * what we tried to reconfig. find out where it went - * wrong, find the set in libdscfg, update it. We'll - * issue a warning, then return 0 (eventually). - * this will allow libdscfg to be committed with the - * good info. got it? - * BTW: the only time we can run into this multiple - * reconfig attempt failure is IF we reconfig from file - * and some thing goes wrong with one of the reconfigs - */ - - /* find the set in libdscfg */ - - numels = cfg_get_num_entries(cfg, "sndr"); - /* yes, numels could be -1 */ - for (i = 1; i < numels; i++) { - bzero(shostbuf, sizeof (shostbuf)); - bzero(svolbuf, sizeof (svolbuf)); - bzero(key, sizeof (key)); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.shost", i); - - (void) cfg_get_cstring(cfg, key, &shostbuf, - sizeof (shostbuf)); - if (strncmp(shostbuf, tohost, sizeof (tohost))) - continue; - - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", i); - (void) cfg_get_cstring(cfg, key, &svolbuf, - sizeof (svolbuf)); - if (strncmp(svolbuf, tofile, NSC_MAXPATH)) - continue; - break; - - /* - * found it, now i contains the set offset. - * i, being the variable, not bad english. - */ - - } - /* shouldn't happen */ - if ((numels < 1) || (i > numels)) { - rdc_warn(NULL, gettext("unable to retrieve " - "set from configuration database")); - /* - * yuck. but indents are pushing the envelope - * we should not be updating config - * if we did not find the entry - * the error will have to do - */ - cfgsuccess = 0; - goto notfound; - } - - /* - * now, put all the correct names back for errors etc. - * also, sock them into dscfg, if the the config was a - * success for one, it will be a redundant but harmless - */ - - /* - * we could not have reconfigged mode if we - * are not logging, AND the kernel CAN return - * sync as the status of an async set if it is - * currently syncing.. Hence the flags & RDC_LOGGING - */ - if (parms.rdc_set->flags & RDC_LOGGING) { - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.mode", i); - if (parms.rdc_set->flags & RDC_ASYNC) { - *doasync = 1; - if (cfg_put_cstring(cfg, key, "async", - strlen("async")) < 0) { - cfgsuccess = 0; - } - - } else { - *doasync = 0; - if (cfg_put_cstring(cfg, key, "sync", - strlen("sync")) < 0) { - cfgsuccess = 0; - } - } - } -#ifdef _RDC_CAMPUS - if (*parms.rdc_set->direct_file) { - (void) strncpy(directfile, - parms.rdc_set->direct_file, NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.type", i); - if (cfg_put_cstring(cfg, key, directfile, - strlen(directfile)) < 0) - cfgsuccess = 0; - } else { - (void) strncpy(directfile, "-", NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.type", i); - if (cfg_put_cstring(cfg, key, directfile, - strlen(directfile)) < 0) - cfgsuccess = 0; - } -#endif - - if (*parms.rdc_set->group_name) { - (void) strncpy(group, parms.rdc_set->group_name, - NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.group", i); - if (cfg_put_cstring(cfg, key, group, - strlen(group)) < 0) - cfgsuccess = 0; - - } else { - (void) strncpy(group, "-", NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.group", i); - if (cfg_put_cstring(cfg, key, group, - strlen(group)) < 0) - cfgsuccess = 0; - } - - if (*parms.rdc_set->disk_queue) { - (void) strncpy(diskqueue, - parms.rdc_set->disk_queue, NSC_MAXPATH); - } else { - (void) strncpy(diskqueue, "-", NSC_MAXPATH); - } - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.diskq", i); - if (cfg_put_cstring(cfg, key, diskqueue, - strlen(diskqueue)) < 0) - cfgsuccess = 0; - - (void) strncpy(frombitmap, - parms.rdc_set->primary.bitmap, NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.pbitmap", i); - if (cfg_put_cstring(cfg, key, frombitmap, - strlen(frombitmap)) < 0) - cfgsuccess = 0; - - (void) strncpy(tobitmap, - parms.rdc_set->secondary.bitmap, NSC_MAXPATH); - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.sbitmap", i); - if (cfg_put_cstring(cfg, key, tobitmap, - strlen(tobitmap)) < 0) - cfgsuccess = 0; - - bzero(key, sizeof (key)); - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", i); - if (clustered) - if (cfg_put_cstring(cfg, key, ctag, - strlen(ctag)) < 0) - cfgsuccess = 0; -notfound: - if (cfgsuccess == 0) { - rdc_warn(NULL, gettext("unable to update " - "configuration storage")); - } - } else { - spcs_log("sndr", NULL, - "%s %s %s %s %s %s %s %s\n%s", - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - gettext("unable to update config file")); - rdc_err(&ustatus, - gettext("Remote Mirror: unable to update " - "config file")); - - } - } - - if (flag == RDC_CMD_HEALTH && errno == 0) { - (void) fprintf(stderr, - gettext("Remote Mirror: %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap); - - if (ret == RDC_ACTIVE) - (void) fprintf(stderr, "Active\n"); - else if (ret == RDC_INACTIVE) - (void) fprintf(stderr, "Inactive\n"); - else - (void) fprintf(stderr, "Unknown\n"); - } else if (ret != SPCS_S_OK) { - if (errno == RDC_EEINVAL) { - spcs_log("sndr", NULL, - "%s %s %s %s %s %s %s %s\n%s", - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - gettext("invalid command option")); - rdc_err(&ustatus, - gettext("Remote Mirror: invalid command option " - "'%s'"), - rdc_decode_flag(flag, parms.options)); - } - } - if (flag == RDC_CMD_STATUS) { - (void) fprintf(stderr, - gettext("Remote Mirror: %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap); - (void) fprintf(stderr, "flags 0x%x\n", parms.rdc_set->flags | - parms.rdc_set->sync_flags | parms.rdc_set->bmap_flags); - } else if (success) { - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\nSuccessful"), - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap); - if (flag == RDC_CMD_TUNABLE) - spcslog_tunable(tohost, tofile); - } - - if (cfg && perform_autosv()) { - spcs_s_ufree(&ustatus); - /* figure out which are the local volumes */ - if (parms.options & RDC_OPT_PRIMARY) { - vol1 = fromfile; - vol2 = frombitmap; - if ((diskqueue && diskqueue[0]) && - (strncmp(diskqueue, "-", 1) != 0)) - vol3 = diskqueue; - else - vol3 = NULL; - } else { - vol1 = tofile; - vol2 = tobitmap; - vol3 = NULL; - if ((flag == RDC_CMD_ENABLE) && - (strlen(diskqueue) > 0) && - (strncmp(diskqueue, "-", 1)) != 0) { - rdc_warn(NULL, - gettext("enabling a disk queue on a " - "Remote Mirror secondary is not allowed. " - "(%s) ignored"), diskqueue); - } - } - - if (flag == RDC_CMD_ENABLE) { - ustatus = spcs_s_ucreate(); - /* - * SV-enable all local volumes - * if the sv_enables fail, disable the sndr vols - * that we just enabled - * and return -1 so the cfg_commit() won't happen - */ - - if (nsc_lookup(volhash, vol1) == NULL) { - if (cfg_vol_enable(cfg, vol1, ctag, "sndr") - < 0) { - spcs_log("sndr", NULL, - "sv enable failed for %s, " - "disabling Remote Mirror set %s:%s", - vol1, tohost, tofile); - /* - * warn here, but we are going to exit - * we want to catch any errors on the - * way down, then exit - */ - - rdc_warn(NULL, - "unable to sv enable %s\n" - "disabling Remote Mirror set %s:%s", - vol1, tohost, tofile); - - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, - fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_err(&ustatus, 0); - } - /* - * ok, we should've reported any errs - * exit explictly - */ - exit(1); - - } - } - if (vol2 && nsc_lookup(volhash, vol2) == NULL) { - if (cfg_vol_enable(cfg, vol2, ctag, "sndr") - < 0) { - spcs_log("sndr", NULL, - "sv enable failed for %s, " - "disabling Remote Mirror set %s:%s", - vol1, tohost, tofile); - /* - * warn here, but we are going to exit - * we want to catch any errors on the - * way down, then exit - */ - - rdc_warn(NULL, - "unable to sv enable %s\n" - "disabling Remote Mirror set %s:%s", - vol2, tohost, tofile); - - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, - fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_err(&ustatus, 0); - } - /* - * ok, we should've reported any errs - * exit explictly - */ - exit(1); - - } - } - - if (vol3 && nsc_lookup(volhash, diskqueue) == NULL) { - if (cfg_vol_enable(cfg, diskqueue, ctag, "sndr") - < 0) { - spcs_log("sndr", NULL, - "sv enable failed for %s, " - "disabling Remote Mirror set %s:%s", - diskqueue, tohost, tofile); - if (cfg_vol_disable(cfg, vol1, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove volume [%s] from " - "configuration"), vol1); - if (cfg_vol_disable(cfg, vol2, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove volume [%s] from " - "configuration"), vol2); - - /* - * warn here, but we are going to exit - * we want to catch any errors on the - * way down, then exit - */ - - rdc_warn(NULL, - "unable to sv enable %s\n" - "disabling Remote Mirror set %s:%s", - diskqueue, tohost, tofile); - - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, - fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_err(&ustatus, 0); - } - /* - * ok, we should've reported any errs - * exit explictly - */ - exit(1); - - } - } - } else if (flag == RDC_CMD_DISABLE) { - /* - * If we're no longer using a volume, SV-disable it - */ - volcount_t *vc; - - vc = nsc_lookup(volhash, vol1); - if (vc && (1 == vc->count)) { - if (cfg_vol_disable(cfg, vol1, ctag, "sndr") - < 0) - rdc_warn(NULL, gettext("Failed to " - "remove volume [%s] from " - "configuration"), vol1); - - } else if (!vc) { - rdc_warn(NULL, - gettext("Unable to find %s in config"), - vol1); - } - - if (vol2) { - vc = nsc_lookup(volhash, vol2); - if (vc && (1 == vc->count)) { - if (cfg_vol_disable(cfg, vol2, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove volume [%s] from " - "configuration"), vol2); - } else if (!vc) { - rdc_warn(NULL, gettext("Unable to find" - " %s in config"), vol2); - } - } - - if (diskqueue != NULL && strlen(diskqueue) > 0) { - vc = nsc_lookup(volhash, diskqueue); - if (vc && (1 == vc->count)) { - if (cfg_vol_disable(cfg, diskqueue, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove disk queue [%s] from " - "configuration"), diskqueue); - } else if (!vc) { - rdc_warn(NULL, gettext("Unable to find" - " %s in config"), diskqueue); - } - } - /* WARNING about to go to 4 space indenting */ - } else if (flag == RDC_CMD_RECONFIG) { - volcount_t *vc; - /* disable ex-bitmaps, enable new bitmaps */ - if (parms.options & RDC_OPT_PRIMARY) { - if (strcmp(orig_fbmp, frombitmap) != 0) { - vc = nsc_lookup(volhash, orig_fbmp); - if (vc && (vc->count == 1)) { - if (cfg_vol_disable(cfg, orig_fbmp, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove bitmap [%s] from " - "configuration"), orig_fbmp); - } else if (!vc) { - rdc_warn(NULL, gettext("Unable to find " - "%s in config"), orig_fbmp); - } - if (nsc_lookup(volhash, frombitmap) == NULL) { - if (cfg_vol_enable(cfg, frombitmap, ctag, - "sndr") < 0) { - spcs_log("sndr", NULL, - "reconfig sv enable failed for %s, " - "disabling Remote Mirror set %s:%s", - frombitmap, tohost, tofile); - rdc_warn(NULL, - "unable to sv enable %s\n" - "disabling Remote Mirror set %s:%s", - frombitmap, tohost, tofile); - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, - fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_warn(&ustatus, 0); - } - exit(1); - } - } - } else if ((orig_diskq[0] != '\0') && - (strcmp(orig_diskq, diskqueue) != 0)) { - vc = nsc_lookup(volhash, orig_diskq); - if (vc && (vc->count == 1)) { - if (cfg_vol_disable(cfg, orig_diskq, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove disk queue [%s] from " - "configuration"), orig_diskq); - } else if (!vc) { - rdc_warn(NULL, gettext("Unable to find " - "%s in config"), orig_diskq); - } - if (vol3 && - (nsc_lookup(volhash, diskqueue) == NULL)) { - if (cfg_vol_enable(cfg, diskqueue, ctag, - "sndr") < 0) { - spcs_log("sndr", NULL, "reconfig sv " - "enable of diskqueue %s failed, " - "disabling Remote Mirror set %s:%s", - diskqueue, tohost, tofile); - rdc_warn(NULL, "reconfig sv " - "enable of diskqueue %s failed." - "disabling Remote Mirror set %s:%s", - diskqueue, tohost, tofile); - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, - fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_warn(&ustatus, 0); - } - exit(1); - } - } - } - } else if (flag != RDC_OPT_PRIMARY) { - if (strcmp(orig_tbmp, tobitmap) != 0) { - vc = nsc_lookup(volhash, orig_tbmp); - if (vc && (vc->count == 1)) { - if (cfg_vol_disable(cfg, orig_tbmp, ctag, - "sndr") < 0) - rdc_warn(NULL, gettext("Failed to " - "remove bitmap [%s] from " - "configuration"), orig_tbmp); - } else if (!vc) { - rdc_warn(NULL, - gettext("Unable to find %s in config"), - orig_tbmp); - } - if (nsc_lookup(volhash, tobitmap) == NULL) { - if (cfg_vol_enable(cfg, tobitmap, ctag, - "sndr") < 0) { - spcs_log("sndr", NULL, - "reconfig sv enable failed for %s, " - "disabling Remote Mirror set %s:%s", - tobitmap, tohost, tofile); - rdc_warn(NULL, - "unable to sv enable %s\n" - "disabling Remote Mirror set %s:%s", - tobitmap, tohost, tofile); - parms.command = RDC_CMD_DISABLE; - ret = RDC_IOCTL(RDC_CONFIG, &parms, - NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - (void) fprintf(stderr, - gettext("Remote Mirror:" - " %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, - tobitmap); - spcs_log("sndr", &ustatus, - "%s %s %s %s %s %s %s %s", - program, - rdc_decode_flag(parms.command, - parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_warn(&ustatus, 0); - } - exit(1); - } - } - } - } - /* END 4 space indenting */ - } - } - spcs_s_ufree(&ustatus); - - return (0); -} - - -/* - * read_config() - * - * DESCRIPTION: Read the lines in a configuration file and return the - * pairs of devices to be mirrored/enabled/disabled/updated. - * The format for the configuration file is as follows: - * - * fromhost fromfile frombitmap tohost tofile tobitmap - * - * where fromfile is the primary device which is local to the - * fromhost subsystem, tofile is the secondary device which is - * local to the tohost subsystem, and type is 1 if the device - * a simckd device or 0 otherwise. Any line preceeded by a '#' - * is considered to be a comment. - * - * Inputs: - * char *config_file Name of configuration file for rdcadm - * - * Outputs: - * int i Number of pairs of devices - * - * Side Effects: The 0 to i-1 entries in the pair_list are filled. - * - */ - -int -read_config(int flag, char *config_file, char *group_arg, char *ctag_arg) -{ - int ret; - char dsk_flagstr[NSC_MAXPATH]; - char line[1024], tmp_line[1024]; - char fromhost[MAX_RDC_HOST_SIZE]; - char fromfile[NSC_MAXPATH]; - char frombitmap[NSC_MAXPATH]; - char tohost[MAX_RDC_HOST_SIZE]; - char tofile[NSC_MAXPATH]; - char tobitmap[NSC_MAXPATH]; - char directfile[NSC_MAXPATH]; - char sync[16]; - int doasync; - FILE *fp; - int i, j; - char *extra_args[EXTRA_ARGS]; - char *tmp, *split_str = " \t\n"; - - for (j = 0; j < EXTRA_ARGS; j++) - extra_args[j] = malloc(NSC_MAXPATH); - - if (!(fp = fopen(config_file, "r"))) { - rdc_err(NULL, gettext("error opening %s"), config_file); - } - - i = 0; - while (fgets(line, sizeof (line), fp)) { - if (line[0] == '#') /* this is a comment */ - continue; - - ret = 0; - (void) strcpy(tmp_line, line); - - if ((tmp = strtok(tmp_line, split_str)) != NULL) { - if (strlen(tmp) >= MAX_RDC_HOST_SIZE) { - (void) printf(gettext("hostname is longer than %d " - "characters\n"), (MAX_RDC_HOST_SIZE - 1)); - continue; - } - (void) strncpy(fromhost, tmp, (MAX_RDC_HOST_SIZE - 1)); - fromhost[(MAX_RDC_HOST_SIZE - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - if (strlen(tmp) >= NSC_MAXPATH) { - (void) printf(gettext( - "device name is longer than %d " - "characters\n"), (NSC_MAXPATH - 1)); - continue; - } - (void) strncpy(fromfile, tmp, (NSC_MAXPATH - 1)); - fromfile[(NSC_MAXPATH - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - if (strlen(tmp) >= NSC_MAXPATH) { - (void) printf(gettext( - "device name is longer than %d " - "characters\n"), (NSC_MAXPATH - 1)); - continue; - } - (void) strncpy(frombitmap, tmp, (NSC_MAXPATH - 1)); - frombitmap[(NSC_MAXPATH - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - if (strlen(tmp) >= MAX_RDC_HOST_SIZE) { - (void) printf(gettext( - "hostname is longer than %d " - "characters\n"), (MAX_RDC_HOST_SIZE - 1)); - continue; - } - (void) strncpy(tohost, tmp, (MAX_RDC_HOST_SIZE - 1)); - tohost[(MAX_RDC_HOST_SIZE - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - if (strlen(tmp) >= NSC_MAXPATH) { - (void) printf(gettext( - "device name is longer than %d " - "characters\n"), (NSC_MAXPATH - 1)); - continue; - } - (void) strncpy(tofile, tmp, (NSC_MAXPATH - 1)); - tofile[(NSC_MAXPATH - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - if (strlen(tmp) >= NSC_MAXPATH) { - (void) printf(gettext( - "device name is longer than %d " - "characters\n"), (NSC_MAXPATH - 1)); - continue; - } - (void) strncpy(tobitmap, tmp, (NSC_MAXPATH - 1)); - tobitmap[(NSC_MAXPATH - 1)] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - (void) strncpy(dsk_flagstr, tmp, 15); - dsk_flagstr[15] = '\0'; - ret++; - } - if ((tmp = strtok(NULL, split_str)) != NULL) { - (void) strncpy(sync, tmp, 15); - sync[15] = '\0'; - ret++; - } - for (j = 0; j < EXTRA_ARGS; j++) { - if ((tmp = strtok(NULL, split_str)) != NULL) { - (void) strncpy(extra_args[j], tmp, - (NSC_MAXPATH - 1)); - extra_args[j][(NSC_MAXPATH - 1)] = '\0'; - ret++; - } - } - - if (ret == 0) /* this is a blank line */ - continue; - - if (ret < 8) { - (void) fclose(fp); - rdc_warn(NULL, - gettext("invalid format in %s"), config_file); - rdc_err(NULL, "%s", line); - } - - if (i >= rdc_maxsets) { - (void) fclose(fp); - rdc_err(NULL, - gettext("number of Remote Mirror sets exceeds %d"), - rdc_maxsets); - } - -#ifdef _RDC_CAMPUS - if (dsk_flagstr[0] == '/') { - /* fcal directio */ - (void) strncpy(directfile, dsk_flagstr, NSC_MAXPATH); - } else if (strcmp(dsk_flagstr, "ip") != 0) { -#else - if (strcmp(dsk_flagstr, "ip") != 0) { -#endif - (void) fclose(fp); - rdc_err(NULL, -#ifdef _RDC_CAMPUS - gettext("ip/fcal specification missing")); -#else - gettext("ip specification missing")); -#endif - } else - (void) strcpy(directfile, "ip"); - - if (strcmp(sync, "sync") == 0) - doasync = 0; - else if (strcmp(sync, "async") == 0) - doasync = 1; - else { - (void) fclose(fp); - rdc_err(NULL, - gettext("sync/async specification missing")); - } - (void) strncpy(pair_list[i].fhost, fromhost, MAX_RDC_HOST_SIZE); - (void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH); - (void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH); - (void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE); - (void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH); - (void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH); - (void) strncpy(pair_list[i].directfile, directfile, - NSC_MAXPATH); - pair_list[i].doasync = doasync; - - if (gethost_netaddrs(fromhost, tohost, - (char *)pair_list[i].fnetaddr, - (char *)pair_list[i].tnetaddr) < 0) { - (void) fclose(fp); - rdc_err(NULL, gettext("unable to determine IP " - "addresses for hosts %s, %s"), fromhost, tohost); - } - - if (parse_extras(ret - 8, extra_args, i) < 0) { - (void) fclose(fp); - rdc_err(NULL, gettext("illegal option in:\n%s"), - line); - } - - if (flag == RDC_CMD_ENABLE || flag == RDC_CMD_RECONFIG) { - if (ctag_check(fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, pair_list[i].ctag, - pair_list[i].diskqueue) < 0) - continue; /* Ignore illegal sets */ - if (pair_diskqueue_check(i)) - continue; /* ignore sets with incorrect diskq */ - } - - /* Filter according to ctag and group arguments */ - if (strcmp(ctag_arg, "") && - strncmp(ctag_arg, pair_list[i].ctag, - MAX_RDC_HOST_SIZE)) - continue; - if (strcmp(group_arg, "") && - strncmp(group_arg, pair_list[i].group, NSC_MAXPATH)) - continue; - - i++; - } - (void) fclose(fp); - for (j = 0; j < EXTRA_ARGS; j++) - free(extra_args[j]); - return (i); -} - - -/* - * read_libcfg() - * - * DESCRIPTION: Read the relevant config info via libcfg - * - * Outputs: - * int i Number of pairs of devices - * - * Side Effects: The 0 to i-1 entries in the pair_list are filled. - * - */ -static int -read_libcfg(int flag, char *group_arg, char *ctag_arg) -{ - int rc; - CFGFILE *cfg; - int i; - _sd_dual_pair_t *pairp; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int setnumber; - - if ((cfg = cfg_open(NULL)) == NULL) - rdc_err(NULL, gettext("unable to access configuration")); - - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("unable to lock configuration")); - - if (strcmp(ctag_arg, "")) - cfg_resource(cfg, ctag_arg); - else { - cfg_resource(cfg, NULL); - } - - setnumber = 0; - /*CSTYLED*/ - for (i = 0; i < rdc_maxsets;) { - setnumber++; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); - rc = cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF); - if (rc < 0) - break; - - pairp = &pair_list[i]; - if (parse_cfg_buf(buf, pairp, NULL)) - continue; - - if (strcmp(group_arg, "") && - strncmp(group_arg, pairp->group, NSC_MAXPATH)) - continue; - - if (flag == RDC_CMD_RECONFIG) { - if (reconfig_pbitmap) - (void) strncpy(pairp->fbitmap, reconfig_pbitmap, - NSC_MAXPATH); - if (reconfig_sbitmap) - (void) strncpy(pairp->tbitmap, reconfig_sbitmap, - NSC_MAXPATH); -#ifdef _RDC_CAMPUS - if (reconfig_direct) - (void) strncpy(directfile, reconfig_direct, - NSC_MAXPATH); -#endif - if (reconfig_group) - (void) strncpy(pairp->group, reconfig_group, - NSC_MAXPATH); - - if (strlen(reconfig_ctag) > 0) - (void) strncpy(pairp->ctag, reconfig_ctag, - MAX_RDC_HOST_SIZE); - - if (reconfig_doasync != -1) - pairp->doasync = reconfig_doasync; - } - - - if (ctag_check(pairp->fhost, pairp->ffile, - pairp->fbitmap, pairp->thost, pairp->tfile, - pairp->tbitmap, pairp->ctag, pairp->diskqueue) < 0) - continue; /* Ignore illegal sets */ - - if (gethost_netaddrs(pairp->fhost, pairp->thost, - (char *)pairp->fnetaddr, - (char *)pairp->tnetaddr) < 0) { - rdc_err(NULL, gettext("unable to determine IP " - "addresses for hosts %s, %s"), pairp->fhost, - pairp->thost); - } - - i++; - } - - cfg_close(cfg); - return (i); -} - -void -q_usage(int prhdr) -{ - if (prhdr) - (void) fprintf(stderr, gettext("disk queue usage:\n")); - - (void) fprintf(stderr, - gettext("\t%s -g <group> -q a <vol>\t\tadd disk queue to " - "group\n"), program); - (void) fprintf(stderr, - gettext("\t%s -g <group> -q d \t\tremove disk queue from" - " group\n"), program); - (void) fprintf(stderr, - gettext("\t%s -g <group> -q r <newvol>\treplace disk queue for a" - " group\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -q a <vol> <shost>:<sdev>\tadd disk queue to " - "a set\n"), program); - (void) fprintf(stderr, - gettext("\t%s -q d <shost>:<sdev>\t\tremove disk queue from " - "a set\n"), program); - (void) fprintf(stderr, - gettext("\t%s -q r <newvol> <shost>:<sdev>\treplace disk queue for " - "a set\n"), program); - -} - -static void -usage() -{ - (void) fprintf(stderr, gettext("usage:\n")); - - (void) fprintf(stderr, - gettext("\t%s [opts] -a {on | off} [set]\t" - "set autosync\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -A <asyncthr> [set]\t" - "set the number of asynchronous\n\t\t\t\t\t\tthreads\n"), - program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -d [set]\t\t\t" - "disable\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -e [set]\t\t\t" - "enable with bits in bitmap set\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -E [set]\t\t\t" - "enable with bits in bitmap clear\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -F <maxqfbas> [set]\t" - "set maximum fbas to queue\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -D {block | noblock} [set]\t" - "set disk queue blocking mode\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -H [set]\t\t\t" - "report link health\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -h\t\t\t\tusage message\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -I a <master> <shadow> <bitmap>\t" - "add ndr_ii config entry\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -I d <master> <shadow> <bitmap>\t" - "delete ndr_ii config entry\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -i [set]\t\t\t" - "print sets in config file format\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -l [set]\t\t\t" - "enter logging mode\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -m [set]\t\t\t" - "full sync\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -m -r [set]\t\t" - "full reverse sync\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -P [set]\t\t\t" - "print sets verbose\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -p [set]\t\t\t" - "print sets\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -R\t\t\t" - "reset error conditions\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -R b p <bitmap> [set]\t" - "reconfig primary bitmap\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -R b s <bitmap> [set]\t" - "reconfig secondary bitmap\n"), program); - - if (clustered) - (void) fprintf(stderr, - gettext("\t%s [opts] -R C <ctag> [set]\t" - "reconfig cluster tag\n"), program); - -#ifdef _RDC_CAMPUS - (void) fprintf(stderr, - gettext("\t%s [opts] -R d <pathname> [set]\t" - "reconfig campus direct file\n"), program); -#endif - - (void) fprintf(stderr, - gettext("\t%s [opts] -R -f <volset-file> \t" - "reconfig from file\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -R g <group> [set]\t" - "reconfig group\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -R m {sync|async} [set]\t" - "reconfig mode\n"), program); - - if (allow_role) - (void) fprintf(stderr, - gettext("\t%s [opts] -R r [set]\t\t" - "reverse roles\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -u [set]\t\t\t" - "update sync\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -u -r [set]\t\t" - "update reverse sync\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -v\t\t\t\tdisplay version\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -W <maxwrites> [set]\t" - "set maximum writes to queue\n"), program); - - (void) fprintf(stderr, - gettext("\t%s [opts] -w [set]\t\t\t" - "wait\n"), program); - q_usage(0); - - (void) fprintf(stderr, gettext("\nopts:\n")); - (void) fprintf(stderr, gettext("\t-n\t\tnon-interactive mode " - "(not valid for print operations)\n")); - (void) fprintf(stderr, gettext( - "\t-g <group>\toperate on sets in group only " - "(not valid for enable\n\t\t\toperations)\n")); - if (clustered) - (void) fprintf(stderr, - gettext("\t-C <ctag>\tignore sets not in cluster ctag " - "(not valid for enable\n\t\t\toperations)\n")); - - (void) fprintf(stderr, gettext("\nset:\n")); - if (clustered) - (void) fprintf(stderr, - gettext("\t<phost> <pdev> <pbmp> " -#ifdef _RDC_CAMPUS - "<shost> <sdev> <sbmp> {ip | <directfile>} " -#else - "<shost> <sdev> <sbmp> ip " -#endif - "\\\n\t\t{sync | async} [g <group>] [q <qdev>] " - "[C <ctag>]\n")); - else - (void) fprintf(stderr, - gettext("\t<phost> <pdev> <pbmp> " -#ifdef _RDC_CAMPUS - "<shost> <sdev> <sbmp> {ip | <directfile>} " -#else - "<shost> <sdev> <sbmp> ip " -#endif - "\\\n\t\t{sync | async} [g <group>] [q <qdev>]\n")); - (void) fprintf(stderr, - gettext("\t<shost>:<sdev>\t\t" - "operate on set matching shost and sdev\n")); - (void) fprintf(stderr, - gettext("\t-f volset-file\t\t" - "operate on all sets specified in config file\n" - "\t\t\t\tnote: not valid for single set operations. See\n" - "\t\t\t\t%s(1RDC).\n"), program); - (void) fprintf(stderr, - gettext("\t<no arg>\t\toperate on all configured sets\n")); -} - -int -prompt_user(int flag, int options) -{ - int c; - - switch (flag) { - case RDC_CMD_DISABLE: - (void) printf(gettext("Disable Remote Mirror? (Y/N) [N]: ")); - break; - case RDC_CMD_ENABLE: - (void) printf(gettext("Enable Remote Mirror? (Y/N) [N]: ")); - break; - case RDC_CMD_HEALTH: - (void) printf(gettext("Report Remote Mirror link health? (Y/N)" - "[N]: ")); - break; - case RDC_CMD_COPY: - if (options & RDC_OPT_FULL) { - if (options & RDC_OPT_REVERSE) - (void) printf(gettext("Overwrite primary with" - " secondary? (Y/N) [N]: ")); - else - (void) printf(gettext("Overwrite secondary with" - " primary? (Y/N) [N]: ")); - } else { - if (options & RDC_OPT_REVERSE) - (void) printf(gettext("Refresh primary with" - " secondary? (Y/N) [N]: ")); - else - (void) printf(gettext("Refresh secondary with" - " primary? (Y/N) [N]: ")); - } - break; - case RDC_CMD_RECONFIG: - (void) printf(gettext( - "Perform Remote Mirror reconfiguration? (Y/N) [N]: ")); - break; - case RDC_CMD_RESET: - (void) printf(gettext("Perform Remote Mirror reset? (Y/N) " - "[N]: ")); - break; - case RDC_CMD_TUNABLE: - (void) printf(gettext("Change Remote Mirror tunable? (Y/N) " - "[N]: ")); - break; - case RDC_CMD_LOG: - (void) printf(gettext( - "Put Remote Mirror into logging mode? (Y/N) [N]: ")); - break; - case RDC_CMD_WAIT: - (void) printf(gettext( - "Wait for Remote Mirror sync completion? (Y/N) [N]: ")); - break; - default: - (void) printf(gettext("Perform Remote Mirror operation? (Y/N) " - "[N]: ")); - } - - c = getchar(); - if ((c != 'y') && (c != 'Y')) { - (void) printf("\n"); - return (-1); - } - return (0); -} - -static void -load_rdc_vols(CFGFILE *cfg) -{ - int set; - char key[ CFG_MAX_KEY ]; - char buf[ CFG_MAX_BUF ]; - _sd_dual_pair_t pair; - char *vol, *bmp; - char *host1 = pair.fhost, *host2 = pair.thost; - char *diskqueue = pair.diskqueue; - volcount_t *volcount; - char lghn[ MAX_RDC_HOST_SIZE ]; - - if (volhash) { - return; - } - - cfg_rewind(cfg, CFG_SEC_CONF); - volhash = nsc_create_hash(); - for (set = 1; /*CSTYLED*/; set++) { - (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d", set); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF)) { - break; - } - - if (parse_cfg_buf(buf, &pair, lghn)) - continue; - vol = pair.ffile; - bmp = pair.fbitmap; - - /* use lghn if possible */ - if (*lghn) { - if (strcmp(host2, lghn) == 0) { - vol = pair.tfile; - bmp = pair.tbitmap; - } - } else if (!self_check(host1)) { - /* next one had better be ours */ - vol = pair.tfile; - bmp = pair.tbitmap; - - if (!self_check(host2)) { - rdc_warn(NULL, - gettext("config error: neither %s nor %s" - " is localhost"), host1, host2); - continue; - } - } - - /* primary vol may be used more than once */ - volcount = (volcount_t *)nsc_lookup(volhash, vol); - if (volcount) { - volcount->count++; - } else { - volcount = (volcount_t *)malloc(sizeof (volcount_t)); - volcount->count = 1; - (void) nsc_insert_node(volhash, volcount, vol); - } - - /* bitmap ought to be only used once */ - volcount = (volcount_t *)nsc_lookup(volhash, bmp); - if (volcount) { - /* argh */ - volcount->count++; - } else { - volcount = (volcount_t *)malloc(sizeof (volcount_t)); - volcount->count = 1; - (void) nsc_insert_node(volhash, volcount, bmp); - } - - if (strcmp(diskqueue, place_holder) == 0) - continue; - /* diskqueue vol may be used more than once */ - volcount = (volcount_t *)nsc_lookup(volhash, diskqueue); - if (volcount) { - volcount->count++; - } else { - volcount = (volcount_t *)malloc(sizeof (volcount_t)); - volcount->count = 1; - (void) nsc_insert_node(volhash, volcount, diskqueue); - } - } -} - -static void -unload_rdc_vols() -{ - nsc_remove_all(volhash, free); - volhash = 0; -} - -static int -perform_autosv() -{ - if (!clustered) { - return (1); - } else { - return (cfg_issuncluster()); - } -} - -/* - * Check the user supplied fields against those in the dscfg for - * this set. - * Never returns on an error. - */ -static void -checkgfields(CFGFILE *cfg, int setnumber, char *fromhost, char *fromfile, - char *frombitmap, char *tobitmap, char *type, char *mode, char *group, - char *ctag, char *diskq) -{ - if (fromhost[0]) - checkgfield(cfg, setnumber, "phost", - gettext("primary host"), fromhost); - if (fromfile[0]) - checkgfield(cfg, setnumber, "primary", - gettext("primary volume"), fromfile); - if (frombitmap[0]) - checkgfield(cfg, setnumber, "pbitmap", - gettext("primary bitmap"), frombitmap); - if (tobitmap[0]) - checkgfield(cfg, setnumber, "sbitmap", - gettext("secondary bitmap"), tobitmap); - if (type[0]) - checkgfield(cfg, setnumber, "type", - gettext("type of connection"), type); - if (mode[0]) - checkgfield(cfg, setnumber, "mode", - gettext("mode of connection"), mode); - if (group[0]) - checkgfield(cfg, setnumber, "group", - gettext("group"), group); - if (ctag[0]) - checkgfield(cfg, setnumber, "cnode", - gettext("cluster tag"), ctag); - if (diskq[0]) - checkgfield(cfg, setnumber, "diskq", - gettext("disk queue volume"), diskq); -} - -/* - * Check the 'fname' field in the dscfg file for set number 'setnumber' - * If it does not match the user's data, 'data', then print the error - * message using the friendly field name 'ufield'. - * Never returns on an error. - */ -static void -checkgfield(CFGFILE *cfg, int setnumber, char *fname, char *ufield, char *data) -{ - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - - (void) snprintf(key, sizeof (key), "sndr.set%d.%s", setnumber, fname); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - rdc_err(NULL, gettext("unable to fetch data for key %s"), - key); - } - if (strcmp(buf, data) != 0) { - rdc_err(NULL, - gettext("the value specified for the %s field is not\nthe " - "same as that contained within the configuration storage " - "file for this set.\nYou specified \"%s\" " - "expected \"%s\"."), - ufield, data, buf); - } -} - -/* - * load and send the contents of the bitmap file to the kernel. - */ -static int -rdc_bitmapset(char *tohost, char *tofile, char *bitmap, int op, - nsc_off_t offset) -{ - rdc_bitmap_op_t bmop; - int fd; - void *buffer; - int buffersz; - struct stat s; - int n; - int ret; - /* - * open bitmap file for reading. - */ - if ((fd = open(bitmap, O_RDONLY)) < 0) { - rdc_warn(NULL, gettext("Unable to open bitmap file %s"), - bitmap); - return (1); - } - (void) fstat(fd, &s); - - if (S_ISREG(s.st_mode) == 0) { - rdc_warn(NULL, gettext("Bitmap %s is not a regular file"), - bitmap); - (void) close(fd); - return (1); - } - - if (op == 0) { - op = RDC_BITMAPOR; - } - /* - * use the file size to allocate buffer. This - * size should be a multiple of FBA, but don't check - * it here. - */ - buffersz = s.st_size; - buffer = malloc(buffersz); - if (buffer == NULL) { - rdc_warn(NULL, gettext("Unable to allocate %d bytes " - "for bitmap file %s"), buffersz, bitmap); - (void) close(fd); - return (1); - } - n = read(fd, buffer, buffersz); - (void) close(fd); - if (n != buffersz) { - rdc_warn(NULL, gettext("Unable to read the bitmap file, " - "read returned %d instead of %d"), - n, buffersz); - free(buffer); - return (1); - } - bmop.offset = offset; - bmop.op = op; - (void) strncpy(bmop.sechost, tohost, MAX_RDC_HOST_SIZE); - (void) strncpy(bmop.secfile, tofile, NSC_MAXPATH); - bmop.len = buffersz; - bmop.addr = (unsigned long)buffer; - ret = rdc_ioctl_simple(RDC_BITMAPOP, &bmop); - free(buffer); - if (ret < 0) { - rdc_warn(NULL, gettext("Setting bitmap ioctl failed for set " - "%s:%s"), tohost, tofile); - - switch (errno) { - case EIO: - rdc_warn(NULL, gettext("One of the sets is not " - "enabled")); - break; - case ENXIO: - rdc_warn(NULL, gettext("One of the sets is not " - "logging")); - break; - default: - break; - } - } else { - ret = 0; - } - if (ret) - ret = 1; - return (ret); -} - -/* - * verify_groupname: Check the group name for the following rules: - * 1. The name does not start with a '-' - * 2. The name does not contain any space characters as defined by - * isspace(3C). - * - * If either of these rules are broken, error immediately. - */ -static void -verify_groupname(char *grp) -{ - int i; - - if (grp[0] == '-') { - rdc_err(NULL, gettext("group name cannot start with a '-'")); - } - - for (i = 0; grp[i] != '\0'; i++) { - if (isspace(grp[i])) { - rdc_err(NULL, gettext("group name cannot contain a " - "space")); - } - } -} diff --git a/usr/src/cmd/avs/rdc/sndrboot.c b/usr/src/cmd/avs/rdc/sndrboot.c deleted file mode 100644 index fcdb59899b..0000000000 --- a/usr/src/cmd/avs/rdc/sndrboot.c +++ /dev/null @@ -1,881 +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/mnttab.h> -#include <errno.h> -#include <limits.h> -#include <fcntl.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> -#include <netdb.h> -#include <ctype.h> -#include <sys/utsname.h> - -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_prot.h> - -#include <sys/nsctl/cfg.h> -#include <sys/nsctl/cfg_cluster.h> - -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> - -#include "rdcadm.h" - -/* - * Special re-use of sndrboot to fix SNDR set IDs during post-patch processing - */ -#define RDC_CMD_FIXSETIDS 0xFEEDFACE - -/* - * config file user level Dual copy pair structure - */ -typedef struct _sd_dual_pair { - char fhost[MAX_RDC_HOST_SIZE]; /* Hostname for primary device */ - char fnetaddr[RDC_MAXADDR]; /* Host netaddr for primary device */ - char ffile[NSC_MAXPATH]; /* Primary device */ - char fbitmap[NSC_MAXPATH]; /* Primary bitmap device */ - char thost[MAX_RDC_HOST_SIZE]; /* Hostname for secondary device */ - char tnetaddr[RDC_MAXADDR]; /* Host netaddr for secondary device */ - char tfile[NSC_MAXPATH]; /* Secondary device */ - char tbitmap[NSC_MAXPATH]; /* Secondary bitmap device */ - char directfile[NSC_MAXPATH]; /* Local FCAL direct IO volume */ - char diskqueue[NSC_MAXPATH]; /* Disk Queue volume */ - char group[NSC_MAXPATH]; /* Group name */ - char lhost[MAX_RDC_HOST_SIZE]; /* Logical hostname for cluster */ - int doasync; /* Device is in sync/async mode */ - int setid; /* unique setid of this set */ -} _sd_dual_pair_t; - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netinet/tcp.h> -#include <rpc/rpc_com.h> -#include <rpc/rpc.h> - -#include <sys/nsctl/librdc.h> - -char *ctag = NULL; - -int parseopts(int, char **, int *); -static int rdc_operation(char *, char *, char *, char *, char *, char *, int, - char *, char *, char *, int, char *, int setid); -static int read_libcfg(int); -static void usage(void); - -extern char *basename(char *); - -int rdc_maxsets; -static _sd_dual_pair_t *pair_list; -char *program; - -struct netbuf svaddr; -struct netbuf *svp; -struct netconfig nconf; -struct netconfig *conf; -struct knetconfig knconf; -static int clustered = 0; -static int proto_test = 0; - -#ifdef lint -int -sndrboot_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - char fromhost[MAX_RDC_HOST_SIZE]; - char tohost[MAX_RDC_HOST_SIZE]; - char fromfile[NSC_MAXPATH]; - char tofile[NSC_MAXPATH]; - char frombitmap[NSC_MAXPATH]; - char tobitmap[NSC_MAXPATH]; - char directfile[NSC_MAXPATH]; - char diskqueue[NSC_MAXPATH]; - char group[NSC_MAXPATH]; - char lhost[MAX_RDC_HOST_SIZE]; - int pairs; - int pid; - int flag = 0; - int doasync; - int rc; - char *required; - int setid; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("rdc"); - - program = basename(argv[0]); - - rc = rdc_check_release(&required); - if (rc < 0) { - rdc_err(NULL, - gettext("unable to determine the current " - "Solaris release: %s\n"), strerror(errno)); - } else if (rc == FALSE) { - rdc_err(NULL, - gettext("incorrect Solaris release (requires %s)\n"), - required); - } - - rdc_maxsets = rdc_get_maxsets(); - if (rdc_maxsets == -1) { - spcs_log("sndr", NULL, - gettext("%s unable to get maxsets value from kernel"), - program); - - rdc_err(NULL, - gettext("unable to get maxsets value from kernel")); - } - - pair_list = calloc(rdc_maxsets, sizeof (*pair_list)); - if (pair_list == NULL) { - rdc_err(NULL, - gettext( - "unable to allocate pair_list" - " array for %d sets"), - rdc_maxsets); - } - - if (parseopts(argc, argv, &flag)) - return (1); - pairs = read_libcfg(flag); - - if (flag == RDC_CMD_FIXSETIDS) { - if (pairs) { - spcs_log("sndr", NULL, gettext("Fixed %d Remote Mirror" - " set IDs"), pairs); -#ifdef DEBUG - rdc_warn(NULL, gettext("Fixed %d Remote Mirror set " - "IDs"), pairs); -#endif - } - return (0); - } - - if (pairs == 0) { -#ifdef DEBUG - rdc_err(NULL, - gettext("Config contains no dual copy sets")); -#else - return (0); -#endif - } - - while (pairs--) { - pid = fork(); - if (pid == -1) { /* error forking */ - perror("fork"); - continue; - } - - if (pid > 0) /* this is parent process */ - continue; - -/* - * At this point, this is the child process. Do the operation - */ - - (void) strncpy(fromfile, - pair_list[pairs].ffile, NSC_MAXPATH); - (void) strncpy(tofile, - pair_list[pairs].tfile, NSC_MAXPATH); - (void) strncpy(frombitmap, - pair_list[pairs].fbitmap, NSC_MAXPATH); - (void) strncpy(fromhost, - pair_list[pairs].fhost, MAX_RDC_HOST_SIZE); - (void) strncpy(tohost, - pair_list[pairs].thost, MAX_RDC_HOST_SIZE); - (void) strncpy(tobitmap, - pair_list[pairs].tbitmap, NSC_MAXPATH); - (void) strncpy(directfile, - pair_list[pairs].directfile, NSC_MAXPATH); - (void) strncpy(diskqueue, - pair_list[pairs].diskqueue, NSC_MAXPATH); - (void) strncpy(group, - pair_list[pairs].group, NSC_MAXPATH); - (void) strncpy(lhost, - pair_list[pairs].lhost, MAX_RDC_HOST_SIZE); - - doasync = pair_list[pairs].doasync; - setid = pair_list[pairs].setid; - if (rdc_operation(fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, flag, directfile, group, - diskqueue, doasync, lhost, setid) - < 0) { - exit(255); - } - - exit(0); - } - - while ((wait((int *)0) > 0)) - ; - return (0); -} - -static int -rdc_operation(fromhost, fromfile, frombitmap, tohost, tofile, - tobitmap, flag, directfile, group, diskqueue, doasync, - lhost, setid) -char *fromhost, *fromfile, *frombitmap; -char *tohost, *tofile, *tobitmap; -int flag, doasync; -char *directfile; -char *group, *diskqueue; -int setid; -char *lhost; -{ - const int getaddr = (flag == RDC_CMD_RESUME); - const int rpcbind = !getaddr; - rdc_config_t parms; - int ret; - spcs_s_info_t ustatus; - struct hostent *hp; - char fromname[MAXHOSTNAMELEN], toname[MAXHOSTNAMELEN]; - struct t_info tinfo; - int i; - - conf = &nconf; - bzero(&fromname, MAXHOSTNAMELEN); - bzero(&toname, MAXHOSTNAMELEN); - - hp = gethost_byname(fromhost); - if (hp == NULL) { - spcs_log("sndr", NULL, - gettext("%s gethost_byname failed for %s"), - program, fromhost); - } - if (strcmp(hp->h_name, fromhost) == 0) - (void) strncpy(fromname, hp->h_name, MAXHOSTNAMELEN); - else { - for (i = 0; hp->h_aliases[i] != NULL; i++) { - if (strcmp(hp->h_aliases[i], fromhost) == 0) - (void) strncpy(fromname, hp->h_aliases[i], - MAXHOSTNAMELEN); - } - } - if (fromname[0] == '\0') { - spcs_log("sndr", NULL, - gettext("%s host %s is not local"), - program, fromhost); - rdc_err(NULL, gettext("Host %s is not local"), - fromhost); - } - hp = gethost_byname(tohost); - if (hp == NULL) { - spcs_log("sndr", NULL, - gettext("%s gethost_byname failed for %s"), - program, tohost); - } - if (strcmp(hp->h_name, tohost) == 0) - (void) strncpy(toname, hp->h_name, MAXHOSTNAMELEN); - else { - for (i = 0; hp->h_aliases[i] != NULL; i++) { - if (strcmp(hp->h_aliases[i], tohost) == 0) - (void) strncpy(toname, hp->h_aliases[i], - MAXHOSTNAMELEN); - } - } - if (toname[0] == '\0') { - spcs_log("sndr", NULL, - gettext("%s host %s is not local"), - program, tohost); - rdc_err(NULL, gettext("Host %s is not local"), - tohost); - } - - if (self_check(fromname) && self_check(toname)) { - spcs_log("sndr", NULL, - gettext("%s Both %s and %s are local"), - program, fromhost, tohost); - rdc_err(NULL, gettext("Both %s and %s are local"), - fromhost, tohost); - } - - /* - * Now build up the address for each host including port and transport - */ - if (getaddr) { - svp = get_addr(toname, RDC_PROGRAM, RDC_VERS_MIN, - &conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind); - - if (svp == NULL) { -#ifdef DEBUG - (void) printf("get_addr failed for Ver 4 %s\n", toname); -#endif - spcs_log("sndr", NULL, - gettext("%s get_addr failed for Ver 4"), - program); - return (-1); - } - svaddr = *svp; - } else { - bzero(&svaddr, sizeof (svaddr)); - } - - parms.rdc_set->secondary.addr.len = svaddr.len; - parms.rdc_set->secondary.addr.maxlen = svaddr.maxlen; - parms.rdc_set->secondary.addr.buf = (void *)svaddr.buf; - -#ifdef DEBUG_ADDR - (void) fprintf(stderr, - "secondary buf %x len %d\n", svaddr.buf, svaddr.len); - - for (i = 0; i < svaddr.len; i++) - (void) printf("%u ", svaddr.buf[i]); - (void) printf("\n"); -#endif - - if (getaddr) { - svp = get_addr(fromname, RDC_PROGRAM, RDC_VERS_MIN, - &conf, proto_test?NC_UDP: NULL, "rdc", &tinfo, rpcbind); - if (svp == NULL) { -#ifdef DEBUG - (void) printf("get_addr failed for Ver 4 %s\n", - fromname); -#endif - return (-1); - } - svaddr = *svp; - } else { - ; - /*EMPTY*/ - } - parms.rdc_set->primary.addr.len = svaddr.len; - parms.rdc_set->primary.addr.maxlen = svaddr.maxlen; - parms.rdc_set->primary.addr.buf = - (void *)svaddr.buf; - -#ifdef DEBUG_ADDR - (void) fprintf(stderr, "primary buf %x len %d\n", - svaddr.buf, svaddr.len); - for (i = 0; i < svaddr.len; i++) - (void) printf("%u ", svaddr.buf[i]); - (void) printf("\n"); -#endif - - if (getaddr) { - (void) convert_nconf_to_knconf(conf, &knconf); -#ifdef DEBUG_ADDR - (void) printf("knconf %x %s %s %x\n", knconf.knc_semantics, - knconf.knc_protofmly, knconf.knc_proto, knconf.knc_rdev); -#endif - parms.rdc_set->netconfig = &knconf; - } else { - parms.rdc_set->netconfig = NULL; - } - if (!clustered && !self_check(fromname) && !self_check(toname)) { - spcs_log("sndr", NULL, - gettext("%s Neither %s nor %s is local"), - program, fromhost, tohost); - rdc_err(NULL, gettext("Neither %s nor %s is local"), - fromhost, tohost); - } - (void) strncpy(parms.rdc_set->primary.intf, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->primary.file, fromfile, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->primary.bitmap, frombitmap, NSC_MAXPATH); - - (void) strncpy(parms.rdc_set->secondary.intf, tohost, - MAX_RDC_HOST_SIZE); - (void) strncpy(parms.rdc_set->secondary.file, tofile, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->secondary.bitmap, tobitmap, NSC_MAXPATH); - - (void) strncpy(parms.rdc_set->group_name, group, NSC_MAXPATH); - (void) strncpy(parms.rdc_set->disk_queue, diskqueue, NSC_MAXPATH); - - parms.rdc_set->maxqfbas = maxqfbas; - parms.rdc_set->maxqitems = maxqitems; - parms.rdc_set->autosync = autosync; - parms.rdc_set->asyncthr = asyncthr; - parms.rdc_set->setid = setid; - - /* gethostid(3c) is defined to return a 32bit value */ - parms.rdc_set->syshostid = (int32_t)gethostid(); - - parms.command = 0; - parms.options = 0; - parms.command = flag; - - if (flag == RDC_CMD_RESUME) { - if (doasync) - parms.options |= RDC_OPT_ASYNC; - else - parms.options |= RDC_OPT_SYNC; - } - if (clustered) { - if (!ctag) - goto noconfig; - if (strcmp(ctag, "-") == 0) - goto noconfig; - -#ifdef DEBUG - (void) fprintf(stderr, "logical hostname: %s\n", lhost); -#endif - - if (strcmp(lhost, fromname) == 0) { - parms.options |= RDC_OPT_PRIMARY; - (void) strncpy(parms.rdc_set->direct_file, directfile, - NSC_MAXPATH); - - } else { - parms.options |= RDC_OPT_SECONDARY; - parms.rdc_set->direct_file[0] = 0; /* no fcal direct */ - } - } else { -noconfig: - /* - * If not clustered, don't resume sndr sets with lhost - */ - if ((flag == RDC_CMD_RESUME) && lhost && strlen(lhost)) - return (0); - - if (self_check(fromname)) { - parms.options |= RDC_OPT_PRIMARY; - (void) strncpy(parms.rdc_set->direct_file, directfile, - NSC_MAXPATH); - } else { - parms.options |= RDC_OPT_SECONDARY; - parms.rdc_set->direct_file[0] = 0; /* no fcal direct */ - } - } - - ustatus = spcs_s_ucreate(); - - errno = 0; - ret = RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus); - if (ret != SPCS_S_OK) { - - /* Surpress error messages for suspend on cluster elements */ - if ((flag == RDC_CMD_SUSPEND) && (errno == RDC_EALREADY) && - !clustered && lhost && strlen(lhost)) { - spcs_s_ufree(&ustatus); - return (0); - } - - (void) fprintf(stderr, - gettext("Remote Mirror: %s %s %s %s %s %s\n"), - fromhost, fromfile, - frombitmap, tohost, tofile, tobitmap); - - if (errno == RDC_EEINVAL) { - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\n%s"), - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap, - gettext("invalid command option")); - rdc_err(&ustatus, - gettext("Remote Mirror: invalid command option " - "'%s'"), rdc_decode_flag(flag, - parms.options)); - } else { - spcs_log("sndr", &ustatus, - gettext("%s %s %s %s %s %s %s %s"), - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, - tohost, tofile, tobitmap); - rdc_err(&ustatus, 0); - } - } - - spcs_log("sndr", NULL, - gettext("%s %s %s %s %s %s %s %s\nSuccessful"), - program, rdc_decode_flag(flag, parms.options), - fromhost, fromfile, frombitmap, tohost, tofile, tobitmap); - - spcs_s_ufree(&ustatus); - return (0); -} -/* - * assign setid's to any existing - * sets without setids, making sure of course NOT to re-use a setid - */ -int -update_setids(CFGFILE *cfg, int *no_id, int highest) -{ - int setid; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - char *ctag; - - /* If in a Sun Cluster, SetIDs need to have a ctag */ - if ((ctag = cfg_get_resource(cfg)) != NULL) { - ctag = strdup(ctag); - cfg_resource(cfg, "setid-ctag"); - } - - /* - * Paranoia. IF there are any sets with setids, we don't - * want to re-use their number. - */ - if (highest > get_new_cfg_setid(cfg)) { - bzero(&buf, sizeof (buf)); - (void) sprintf(buf, "%d", highest); - if (cfg_put_cstring(cfg, "setid.set1.value", buf, - sizeof (buf)) < 0) - rdc_warn(NULL, gettext("sndrboot: Unable to store " - "new setid")); - } - - for (setid = 0; no_id[setid]; setid++) { - bzero(&buf, sizeof (buf)); - bzero(&key, sizeof (key)); - (void) sprintf(buf, "%d", get_new_cfg_setid(cfg)); - (void) sprintf(key, "sndr.set%d.options", no_id[setid]); - if (cfg_put_options(cfg, CFG_SEC_CONF, key, "setid", buf) < 0) - rdc_warn(NULL, gettext("sndrboot: Unable to store " - "unique setid")); - - pair_list[no_id[setid] - 1].setid = atoi(buf); - } - - /* Restore old ctag if in a Sun Cluster */ - if (ctag) { - cfg_resource(cfg, ctag); - free(ctag); - } - - if (cfg_commit(cfg) < 0) - rdc_err(NULL, gettext("sndrboot: Failed to commit setids")); - - return (setid); -} - -/* - * this is called when the option lghn is no available in libdscfg - * that should only happen on an upgrade. - * cfg write lock must be held across this function - */ -char * -get_lghn(CFGFILE *cfg, char *ctag, int setnum, int flag) -{ - FILE *pipe; - char rsgrp[SCCONF_MAXSTRINGLEN]; - char cmd[SCCONF_MAXSTRINGLEN]; - static char lhostname[MAX_RDC_HOST_SIZE]; - char key[CFG_MAX_KEY]; - int rc; - - if (ctag == NULL) - goto fail; - - bzero(&lhostname, sizeof (lhostname)); - - (void) sprintf(rsgrp, "%s-stor-rg", ctag); -/* BEGIN CSTYLED */ - rc = snprintf(cmd, SCCONF_MAXSTRINGLEN, - "/usr/cluster/bin/scrgadm -pvv | fgrep HostnameList \ -| fgrep %s | fgrep value | awk -F: '{ print $4 }'", rsgrp); -/* END CSTYLED */ - - if (rc < 0) { - rdc_err(NULL, gettext("Error getting scrgadm output")); - } - - pipe = popen(cmd, "r"); - - if (pipe == NULL) { - rdc_err(NULL, gettext("Error opening pipe")); - } - rc = fscanf(pipe, "%s", lhostname); - (void) pclose(pipe); - - if (rc != 1) { - rdc_err(NULL, gettext("Unable to get logical host")); - } - - /* not really failing, but suspend does not have the config lock */ - if (flag == RDC_CMD_SUSPEND) - goto fail; - - bzero(&key, sizeof (key)); - (void) snprintf(key, sizeof (key), "sndr.set%d.options", setnum); - if (cfg_put_options(cfg, CFG_SEC_CONF, key, "lghn", lhostname) < 0) - rdc_warn(NULL, gettext("sndrboot: Unable to store logical " - "host name in configuration database")); - - if (cfg_commit(cfg) < 0) - rdc_err(NULL, - gettext("sndrboot: Failed to commit logical host name")); - -fail: - return (lhostname); - -} - -/* - * read_libcfg() - * - * DESCRIPTION: Read the relevant config info via libcfg - * - * Outputs: - * int i Number of pairs of devices - * - * Side Effects: The 0 to i-1 entries in the pair_list are filled. - * - */ -static int -read_libcfg(int flag) -{ - char fromhost[MAX_RDC_HOST_SIZE]; - char fromfile[NSC_MAXPATH]; - char frombitmap[NSC_MAXPATH]; - char tohost[MAX_RDC_HOST_SIZE]; - char tofile[NSC_MAXPATH]; - char tobitmap[NSC_MAXPATH]; - char directfile[NSC_MAXPATH]; - char diskqueue[NSC_MAXPATH]; - char group[NSC_MAXPATH]; - char lhost[MAX_RDC_HOST_SIZE]; - char sync[16]; - char setid[64]; - int doasync; - CFGFILE *cfg; - int i, j = 0; - int rc; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - char dummy[NSC_MAXPATH]; - int setnumber; - int numsets; - int highest = 0; - char lghn[5]; - int *no_id; - - - if ((cfg = cfg_open("")) == NULL) - rdc_err(NULL, gettext("Error opening config")); - - /* - * If RDC_CMD_FIXSETIDS, we were called during post-patch install - * Acquire a write-lock on the cfg_lock(), so the code can attempt - * to fix setIDs - */ - if (flag == RDC_CMD_FIXSETIDS) { - if (!cfg_lock(cfg, CFG_WRLOCK)) - rdc_err(NULL, gettext("Error write locking config")); - cfg_resource(cfg, NULL); - } else { - if (!cfg_lock(cfg, CFG_RDLOCK)) - rdc_err(NULL, gettext("Error locking config")); - cfg_resource(cfg, ctag); - } - - if ((numsets = cfg_get_num_entries(cfg, "sndr")) < 0) - rdc_err(NULL, gettext("Unable to get set info from config")); - - no_id = (int *)calloc(numsets + 1, sizeof (int)); - if (!no_id) - rdc_err(NULL, gettext("No memory")); - - - (void) snprintf(lghn, sizeof (lghn), "lghn"); - - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "sndr.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - rc = sscanf(buf, "%s %s %s %s %s %s %s %s %s %s %s %s", - fromhost, fromfile, frombitmap, tohost, tofile, tobitmap, - directfile, sync, group, dummy, dummy, diskqueue); - if (rc != 12) - rdc_err(NULL, gettext("cfg input error (%d)"), rc); - - if (strcmp(directfile, "ip") == 0) - (void) strcpy(directfile, ""); - - if (strcmp(group, "-") == 0) - (void) strcpy(group, ""); - - if (strcmp(diskqueue, "-") == 0) - (void) strcpy(diskqueue, ""); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.options", setnumber); - - if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, - lghn, lhost, MAX_RDC_HOST_SIZE) < 0) - (void) strcpy(lhost, - get_lghn(cfg, ctag, setnumber, flag)); - - if (strcmp(sync, "sync") == 0) - doasync = 0; - else if (strcmp(sync, "async") == 0) - doasync = 1; - else { - cfg_close(cfg); - rdc_err(NULL, - gettext("Set %s:%s neither sync nor async"), - tohost, tofile); - } - - (void) strncpy(pair_list[i].fhost, fromhost, - MAX_RDC_HOST_SIZE); - (void) strncpy(pair_list[i].ffile, fromfile, NSC_MAXPATH); - (void) strncpy(pair_list[i].fbitmap, frombitmap, NSC_MAXPATH); - (void) strncpy(pair_list[i].thost, tohost, MAX_RDC_HOST_SIZE); - (void) strncpy(pair_list[i].tfile, tofile, NSC_MAXPATH); - (void) strncpy(pair_list[i].tbitmap, tobitmap, NSC_MAXPATH); - (void) strncpy(pair_list[i].directfile, directfile, - NSC_MAXPATH); - (void) strncpy(pair_list[i].diskqueue, diskqueue, - NSC_MAXPATH); - (void) strncpy(pair_list[i].group, group, NSC_MAXPATH); - (void) strncpy(pair_list[i].lhost, lhost, MAX_RDC_HOST_SIZE); - pair_list[i].doasync = doasync; - - if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid", - setid, sizeof (setid)) < 0) { - no_id[j++] = setnumber; - } - pair_list[i].setid = atoi(setid); - - if (pair_list[i].setid > highest) - highest = pair_list[i].setid; - - if (gethost_netaddrs(fromhost, tohost, - (char *)pair_list[i].fnetaddr, - (char *)pair_list[i].tnetaddr) < 0) { - cfg_close(cfg); - spcs_log("sndr", NULL, - gettext("%s unable to determine IP addresses " - "for hosts %s %s"), program, fromhost, tohost); - rdc_err(NULL, gettext("unable to determine IP " - "addresses for hosts %s, %s"), fromhost, tohost); - } - } - /* - * fix any lost set ids if possible, also deal with upgrade - */ - if (j > 0 && flag == RDC_CMD_FIXSETIDS) { - (void) update_setids(cfg, no_id, highest); - i = j; /* Set number of fixups */ - } - free(no_id); - cfg_close(cfg); - return (i); -} - - -int -parseopts(argc, argv, flag) -int argc; -char **argv; -int *flag; -{ - int errflag = 0; - char c; - char inval = 0; -#ifdef DEBUG - while ((c = getopt(argc, argv, "C:Urs")) != -1) { -#else - while ((c = getopt(argc, argv, "C:rs")) != -1) { -#endif - switch (c) { - case 'C': - clustered = TRUE; - ctag = optarg; - break; -#ifdef DEBUG - case 'U': - proto_test = 1; - break; -#endif - case 'r': - if (*flag) - inval = 1; - *flag = RDC_CMD_RESUME; - break; - case 's': - if (*flag) - inval = 1; - *flag = RDC_CMD_SUSPEND; - break; - case '?': - errflag++; - } - } - - /* - * Special fix to address no SetIds in AVS 3.1 to 3.2 install + patch - * Adjust set IDs, if someone invokes the following invalid command - * - * /use/sbin/sndrboot -C post-patch-setids -r -s - * - * Command will be called in post-install of the patch containing fix - * - */ - if (clustered && (strcmp(ctag, "post-patch-setids") == 0) && - *flag && inval) { - *flag = RDC_CMD_FIXSETIDS; - return (0); - } - - if (inval) { - rdc_warn(NULL, gettext("Invalid argument combination")); - errflag = 1; - } - - if (!*flag || errflag) { - usage(); - return (-1); - } - - return (0); -} - -static void -usage() -{ - (void) fprintf(stderr, gettext("usage:\n")); - (void) fprintf(stderr, - gettext("\t%s -r [-C tag]\t\t" - "resume\n"), program); - - (void) fprintf(stderr, - gettext("\t%s -s [-C tag]\t\t" - "suspend\n"), program); -} diff --git a/usr/src/cmd/avs/rdc/sndrd.c b/usr/src/cmd/avs/rdc/sndrd.c deleted file mode 100644 index aa04f19127..0000000000 --- a/usr/src/cmd/avs/rdc/sndrd.c +++ /dev/null @@ -1,2013 +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. - */ -/* - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. - * Copyright 2014 Gary Mills - */ - -/* - * Network SNDR/ncall-ip server - based on nfsd - */ -#include <sys/types.h> -#include <rpc/types.h> -#include <errno.h> -#include <netdb.h> -#include <sys/socket.h> -#include <netconfig.h> -#include <stropts.h> -#include <fcntl.h> -#include <stdio.h> -#include <strings.h> -#include <signal.h> -#include <unistd.h> -#include <stdlib.h> -#include <netdir.h> -#include <rpc/rpc_com.h> -#include <rpc/rpc.h> -#include <tiuser.h> -#include <netinet/tcp.h> -#include <netinet/in.h> -#include <syslog.h> -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <libgen.h> -#include <deflt.h> -#include <sys/resource.h> - -#include <sys/nsctl/nsctl.h> - -#ifdef __NCALL__ - -#include <sys/ncall/ncall.h> -#include <sys/ncall/ncall_ip.h> -#include <sys/nsctl/libncall.h> - -#define RDC_POOL_CREATE NC_IOC_POOL_CREATE -#define RDC_POOL_RUN NC_IOC_POOL_RUN -#define RDC_POOL_WAIT NC_IOC_POOL_WAIT -#define RDC_PROGRAM NCALL_PROGRAM -#define RDC_SERVICE "ncall" -#undef RDC_SVCPOOL_ID /* We are overloading this value */ -#define RDC_SVCPOOL_ID NCALL_SVCPOOL_ID -#define RDC_SVC_NAME "NCALL" -#define RDC_VERS_MIN NCALL_VERS_MIN -#define RDC_VERS_MAX NCALL_VERS_MAX - -#else /* !__NCALL__ */ - -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/librdc.h> - -#define RDC_SERVICE "rdc" -#define RDC_SVC_NAME "RDC" - -#endif /* __NCALL__ */ - -#define RDCADMIN "/etc/default/sndr" - -#include <nsctl.h> - -struct conn_ind { - struct conn_ind *conn_next; - struct conn_ind *conn_prev; - struct t_call *conn_call; -}; - -struct conn_entry { - bool_t closing; - struct netconfig nc; -}; - -static char *progname; -static struct conn_entry *conn_polled; -static int num_conns; /* Current number of connections */ -static struct pollfd *poll_array; /* array of poll descriptors for poll */ -static size_t num_fds = 0; /* number of transport fds opened */ -static void poll_for_action(); -static void remove_from_poll_list(int); -static int do_poll_cots_action(int, int); -static int do_poll_clts_action(int, int); -static void add_to_poll_list(int, struct netconfig *); -static int bind_to_provider(char *, char *, struct netbuf **, - struct netconfig **); -static int set_addrmask(int, struct netconfig *, struct netbuf *); -static void conn_close_oldest(void); -static boolean_t conn_get(int, struct netconfig *, struct conn_ind **); -static void cots_listen_event(int, int); -static int discon_get(int, struct netconfig *, struct conn_ind **); -static int nofile_increase(int); -static int is_listen_fd_index(int); -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) -static int sndrsvcpool(int); -static int svcwait(int id); -#endif - - -/* - * RPC protocol block. Useful for passing registration information. - */ -struct protob { - char *serv; /* ASCII service name, e.g. "RDC" */ - int versmin; /* minimum version no. to be registered */ - int versmax; /* maximum version no. to be registered */ - int program; /* program no. to be registered */ - struct protob *next; /* next entry on list */ -}; - - - -static size_t end_listen_fds; -static int debugflg = 0; -static int max_conns_allowed = -1; -static int listen_backlog = 10; -static char *trans_provider = (char *)NULL; -static int rdcsvc(int, struct netbuf, struct netconfig *); - -/* used by cots_listen_event() */ -static int (*Mysvc)(int, struct netbuf, struct netconfig *) = rdcsvc; - -/* - * Determine valid semantics for rdc. - */ -#define OK_TPI_TYPE(_nconf) \ - (_nconf->nc_semantics == NC_TPI_CLTS || \ - _nconf->nc_semantics == NC_TPI_COTS || \ - _nconf->nc_semantics == NC_TPI_COTS_ORD) - -#define BE32_TO_U32(a) \ - ((((uint32_t)((uchar_t *)a)[0] & 0xFF) << (uint32_t)24) |\ - (((uint32_t)((uchar_t *)a)[1] & 0xFF) << (uint32_t)16) |\ - (((uint32_t)((uchar_t *)a)[2] & 0xFF) << (uint32_t)8) |\ - ((uint32_t)((uchar_t *)a)[3] & 0xFF)) - -#ifdef DEBUG -/* - * Only support UDP in DEBUG mode for now - */ -static char *defaultproviders[] = { "/dev/tcp", "/dev/tcp6", "/dev/udp", - "/dev/udp6", NULL }; -#else -static char *defaultproviders[] = { "/dev/tcp6", "/dev/tcp", NULL }; -#endif - -/* - * Number of elements to add to the poll array on each allocation. - */ -#define POLL_ARRAY_INC_SIZE 64 -#define NOFILE_INC_SIZE 64 - -#ifdef __NCALL__ -const char *rdc_devr = "/dev/ncallip"; -#else -const char *rdc_devr = "/dev/rdc"; -#endif - -static int rdc_fdr; -static int - -open_rdc(void) -{ - int fd = open(rdc_devr, O_RDONLY); - - if (fd < 0) - return (-1); - - return (rdc_fdr = fd); -} - -static int -sndrsys(int type, void *arg) -{ - int ret = -1; - if (!rdc_fdr && open_rdc() < 0) { /* open failed */ - syslog(LOG_ERR, "open_rdc() failed: %m\n"); - } else { - if ((ret = ioctl(rdc_fdr, type, arg)) < 0) { - syslog(LOG_ERR, "ioctl(rdc_ioctl) failed: %m\n"); - } - } - return (ret); -} - -int -rdc_transport_open(struct netconfig *nconf) -{ - int fd; - struct strioctl strioc; - - if ((nconf == (struct netconfig *)NULL) || - (nconf->nc_device == (char *)NULL)) { - syslog(LOG_ERR, "No netconfig device"); - return (-1); - } - - /* - * Open the transport device. - */ - fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL); - if (fd == -1) { - if (t_errno == TSYSERR && errno == EMFILE && - (nofile_increase(0) == 0)) { - /* Try again with a higher NOFILE limit. */ - fd = t_open(nconf->nc_device, O_RDWR, NULL); - } - if (fd == -1) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, "t_open failed: %m"); - } else { - syslog(LOG_ERR, "t_open failed: %s", - t_errlist[t_errno]); - } - return (-1); - } - } - - /* - * Pop timod because the RPC module must be as close as possible - * to the transport. - */ - if (ioctl(fd, I_POP, 0) < 0) { - syslog(LOG_ERR, "I_POP of timod failed: %m"); - if (t_close(fd) == -1) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, "t_close failed on %d: %m", fd); - } else { - syslog(LOG_ERR, "t_close failed on %d: %s", - fd, t_errlist[t_errno]); - } - } - return (-1); - } - - if (nconf->nc_semantics == NC_TPI_CLTS) { - /* - * Push rpcmod to filter data traffic to KRPC. - */ - if (ioctl(fd, I_PUSH, "rpcmod") < 0) { - syslog(LOG_ERR, "I_PUSH of rpcmod failed: %m"); - (void) t_close(fd); - return (-1); - } - } else { - if (ioctl(fd, I_PUSH, "rpcmod") < 0) { - syslog(LOG_ERR, "I_PUSH of CONS rpcmod failed: %m"); - if (t_close(fd) == -1) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, - "t_close failed on %d: %m", fd); - } else { - syslog(LOG_ERR, - "t_close failed on %d: %s", - fd, t_errlist[t_errno]); - } - } - return (-1); - } - - strioc.ic_cmd = RPC_SERVER; - strioc.ic_dp = (char *)0; - strioc.ic_len = 0; - strioc.ic_timout = -1; - /* Tell CONS rpcmod to act like a server stream. */ - if (ioctl(fd, I_STR, &strioc) < 0) { - syslog(LOG_ERR, "CONS rpcmod set-up ioctl failed: %m"); - if (t_close(fd) == -1) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, - "t_close failed on %d: %m", fd); - } else { - syslog(LOG_ERR, - "t_close failed on %d: %s", - fd, t_errlist[t_errno]); - } - } - return (-1); - } - } - - /* - * Re-push timod so that we will still be doing TLI - * operations on the descriptor. - */ - if (ioctl(fd, I_PUSH, "timod") < 0) { - syslog(LOG_ERR, "I_PUSH of timod failed: %m"); - if (t_close(fd) == -1) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, "t_close failed on %d: %m", fd); - } else { - syslog(LOG_ERR, "t_close failed on %d: %s", - fd, t_errlist[t_errno]); - } - } - return (-1); - } - - return (fd); -} - - -void -rdcd_log_tli_error(char *tli_name, int fd, struct netconfig *nconf) -{ - int error; - - /* - * Save the error code across syslog(), just in case syslog() - * gets its own error and, therefore, overwrites errno. - */ - error = errno; - if (t_errno == TSYSERR) { - syslog(LOG_ERR, "%s(file descriptor %d/transport %s) %m", - tli_name, fd, nconf->nc_proto); - } else { - syslog(LOG_ERR, - "%s(file descriptor %d/transport %s) TLI error %d", - tli_name, fd, nconf->nc_proto, t_errno); - } - errno = error; -} - -/* - * Called to set up service over a particular transport - */ -void -do_one(char *provider, char *proto, struct protob *protobp0, - int (*svc)(int, struct netbuf, struct netconfig *)) -{ - struct netbuf *retaddr; - struct netconfig *retnconf; - struct netbuf addrmask; - int vers; - int sock; - - if (provider) { - sock = bind_to_provider(provider, protobp0->serv, &retaddr, - &retnconf); - } else { - (void) syslog(LOG_ERR, - "Cannot establish %s service over %s: transport setup problem.", - protobp0->serv, provider ? provider : proto); - return; - } - - if (sock == -1) { - if ((Is_ipv6present() && - (strcmp(provider, "/dev/tcp6") == 0)) || - (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0))) - (void) syslog(LOG_ERR, - "Cannot establish %s service over %s: transport " - "setup problem.", - protobp0->serv, provider ? provider : proto); - return; - } - - if (set_addrmask(sock, retnconf, &addrmask) < 0) { - (void) syslog(LOG_ERR, - "Cannot set address mask for %s", retnconf->nc_netid); - return; - } - - - /* - * Register all versions of the programs in the protocol block list - */ - for (vers = protobp0->versmin; vers <= protobp0->versmax; vers++) { - (void) rpcb_unset(protobp0->program, vers, retnconf); - (void) rpcb_set(protobp0->program, vers, retnconf, retaddr); - } - - if (retnconf->nc_semantics == NC_TPI_CLTS) { - /* Don't drop core if supporting module(s) aren't loaded. */ - (void) signal(SIGSYS, SIG_IGN); - - /* - * svc() doesn't block, it returns success or failure. - */ - if ((*svc)(sock, addrmask, retnconf) < 0) { - (void) syslog(LOG_ERR, "Cannot establish %s service " - "over <file desc. %d, protocol %s> : %m. Exiting", - protobp0->serv, sock, retnconf->nc_proto); - exit(1); - } - } - /* - * We successfully set up the server over this transport. - * Add this descriptor to the one being polled on. - */ - add_to_poll_list(sock, retnconf); -} - -/* - * Set up the SNDR/ncall-ip service over all the available transports. - * Returns -1 for failure, 0 for success. - */ -int -do_all(struct protob *protobp, - int (*svc)(int, struct netbuf, struct netconfig *)) -{ - struct netconfig *nconf; - NCONF_HANDLE *nc; - - if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) { - syslog(LOG_ERR, "setnetconfig failed: %m"); - return (-1); - } - while (nconf = getnetconfig(nc)) { - if ((nconf->nc_flag & NC_VISIBLE) && - strcmp(nconf->nc_protofmly, "loopback") != 0 && - OK_TPI_TYPE(nconf)) - do_one(nconf->nc_device, nconf->nc_proto, protobp, svc); - } - (void) endnetconfig(nc); - return (0); -} - -/* - * Read the /etc/default/sndr configuration file to determine if the - * client has been configured for number of threads, backlog or transport - * provider. - */ - -static void -read_default(void) -{ - char *defval, *tmp_str; - int errno; - int tmp; - - /* Fail silently if error in opening the default rdc config file */ - if ((defopen(RDCADMIN)) == 0) { - if ((defval = defread("SNDR_THREADS=")) != NULL) { - errno = 0; - tmp = strtol(defval, (char **)NULL, 10); - if (errno == 0) { - max_conns_allowed = tmp; - } - } - if ((defval = defread("SNDR_LISTEN_BACKLOG=")) != NULL) { - errno = 0; - tmp = strtol(defval, (char **)NULL, 10); - if (errno == 0) { - listen_backlog = tmp; - } - } - if ((defval = defread("SNDR_TRANSPORT=")) != NULL) { - errno = 0; - tmp_str = strdup(defval); - if (errno == 0) { - trans_provider = tmp_str; - } - } - /* close defaults file */ - (void) defopen(NULL); - } -} -#ifdef lint -int -sndrd_lintmain(int ac, char **av) -#else -int -main(int ac, char **av) -#endif -{ - const char *dir = "/"; - int allflag = 0; - int pid; - int i, rc; - struct protob *protobp0, *protobp; - char **providerp; - char *required; -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) - int maxservers; -#endif - - (void) setlocale(LC_ALL, ""); -#ifdef __NCALL__ - (void) textdomain("ncall"); -#else - (void) textdomain("rdc"); -#endif - - progname = basename(av[0]); - -#ifdef __NCALL__ - rc = ncall_check_release(&required); -#else - rc = rdc_check_release(&required); -#endif - if (rc < 0) { - (void) fprintf(stderr, - gettext("%s: unable to determine the current " - "Solaris release: %s\n"), progname, strerror(errno)); - exit(1); - } else if (rc == FALSE) { - (void) fprintf(stderr, - gettext("%s: incorrect Solaris release (requires %s)\n"), - progname, required); - exit(1); - } - - openlog(progname, LOG_PID|LOG_CONS, LOG_DAEMON); - read_default(); - - /* - * Usage: <progname> [-c <number of threads>] [-t protocol] \ - * [-d] [-l <listen backlog>] - */ - while ((i = getopt(ac, av, "ac:t:dl:")) != EOF) { - switch (i) { - case 'a': - allflag = 1; - break; - case 'c': - max_conns_allowed = atoi(optarg); - if (max_conns_allowed <= 0) - max_conns_allowed = 16; - break; - - case 'd': - debugflg++; - break; - - case 't': - trans_provider = optarg; - break; - - case 'l': - listen_backlog = atoi(optarg); - if (listen_backlog < 0) - listen_backlog = 32; - break; - - default: - syslog(LOG_ERR, - "Usage: %s [-c <number of threads>] " - "[-d] [-t protocol] " - "[-l <listen backlog>]\n", progname); - exit(1); - break; - } - } - - if (chroot(dir) < 0) { - syslog(LOG_ERR, "chroot failed: %m"); - exit(1); - } - - if (chdir(dir) < 0) { - syslog(LOG_ERR, "chdir failed: %m"); - exit(1); - } - - if (!debugflg) { - pid = fork(); - if (pid < 0) { - syslog(LOG_ERR, "Fork failed\n"); - exit(1); - } - if (pid != 0) - exit(0); - - /* - * Close existing file descriptors, open "/dev/null" as - * standard input, output, and error, and detach from - * controlling terminal. - */ -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) - /* use closefrom(3C) from PSARC/2000/193 when possible */ - closefrom(0); -#else - for (i = 0; i < _NFILE; i++) - (void) close(i); -#endif - (void) open("/dev/null", O_RDONLY); - (void) open("/dev/null", O_WRONLY); - (void) dup(1); - (void) setsid(); - - /* - * ignore all signals apart from SIGTERM. - */ - for (i = 1; i < _sys_nsig; i++) - (void) sigset(i, SIG_IGN); - - (void) sigset(SIGTERM, SIG_DFL); - } - -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) - /* - * Set up kernel RPC thread pool for the SNDR/ncall-ip server. - */ - maxservers = (max_conns_allowed < 0 ? 16 : max_conns_allowed); - if (sndrsvcpool(maxservers)) { - (void) syslog(LOG_ERR, - "Can't set up kernel %s service: %m. Exiting", progname); - exit(1); - } - - /* - * Set up blocked thread to do LWP creation on behalf of the kernel. - */ - if (svcwait(RDC_SVCPOOL_ID)) { - (void) syslog(LOG_ERR, - "Can't set up %s pool creator: %m, Exiting", progname); - exit(1); - } -#endif - - /* - * Build a protocol block list for registration. - */ - protobp0 = protobp = (struct protob *)malloc(sizeof (struct protob)); - protobp->serv = RDC_SVC_NAME; - protobp->versmin = RDC_VERS_MIN; - protobp->versmax = RDC_VERS_MAX; - protobp->program = RDC_PROGRAM; - protobp->next = (struct protob *)NULL; - - if (allflag) { - if (do_all(protobp0, rdcsvc) == -1) - exit(1); - } else if (trans_provider) - do_one(trans_provider, NULL, protobp0, rdcsvc); - else { - for (providerp = defaultproviders; - *providerp != NULL; providerp++) { - trans_provider = *providerp; - do_one(trans_provider, NULL, protobp0, rdcsvc); - } - } - -done: - free(protobp); - - end_listen_fds = num_fds; - /* - * Poll for non-data control events on the transport descriptors. - */ - poll_for_action(); - - syslog(LOG_ERR, "%s fatal server error\n", progname); - - return (-1); -} - -static int -reuseaddr(int fd) -{ - struct t_optmgmt req, resp; - struct opthdr *opt; - char reqbuf[128]; - int *ip; - - /* LINTED pointer alignment */ - opt = (struct opthdr *)reqbuf; - opt->level = SOL_SOCKET; - opt->name = SO_REUSEADDR; - opt->len = sizeof (int); - - /* LINTED pointer alignment */ - ip = (int *)&reqbuf[sizeof (struct opthdr)]; - *ip = 1; - - req.flags = T_NEGOTIATE; - req.opt.len = sizeof (struct opthdr) + opt->len; - req.opt.buf = (char *)opt; - - resp.flags = 0; - resp.opt.buf = reqbuf; - resp.opt.maxlen = sizeof (reqbuf); - - if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { - if (t_errno == TSYSERR) { - syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %m\n"); - } else { - syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %s\n", - t_errlist[t_errno]); - } - return (-1); - } - return (0); -} - -/* - * poll on the open transport descriptors for events and errors. - */ -void -poll_for_action(void) -{ - int nfds; - int i; - - /* - * Keep polling until all transports have been closed. When this - * happens, we return. - */ - while ((int)num_fds > 0) { - nfds = poll(poll_array, num_fds, INFTIM); - switch (nfds) { - case 0: - continue; - - case -1: - /* - * Some errors from poll could be - * due to temporary conditions, and we try to - * be robust in the face of them. Other - * errors (should never happen in theory) - * are fatal (eg. EINVAL, EFAULT). - */ - switch (errno) { - case EINTR: - continue; - - case EAGAIN: - case ENOMEM: - (void) sleep(10); - continue; - - default: - (void) syslog(LOG_ERR, - "poll failed: %m. Exiting"); - exit(1); - } - default: - break; - } - - /* - * Go through the poll list looking for events. - */ - for (i = 0; i < num_fds && nfds > 0; i++) { - if (poll_array[i].revents) { - nfds--; - /* - * We have a message, so try to read it. - * Record the error return in errno, - * so that syslog(LOG_ERR, "...%m") - * dumps the corresponding error string. - */ - if (conn_polled[i].nc.nc_semantics == - NC_TPI_CLTS) { - errno = do_poll_clts_action( - poll_array[i].fd, i); - } else { - errno = do_poll_cots_action( - poll_array[i].fd, i); - } - - if (errno == 0) - continue; - /* - * Most returned error codes mean that there is - * fatal condition which we can only deal with - * by closing the transport. - */ - if (errno != EAGAIN && errno != ENOMEM) { - (void) syslog(LOG_ERR, - "Error (%m) reading descriptor %d" - "/transport %s. Closing it.", - poll_array[i].fd, - conn_polled[i].nc.nc_proto); - (void) t_close(poll_array[i].fd); - remove_from_poll_list(poll_array[i].fd); - } else if (errno == ENOMEM) - (void) sleep(5); - } - } - } - - (void) syslog(LOG_ERR, - "All transports have been closed with errors. Exiting."); -} - -/* - * Allocate poll/transport array entries for this descriptor. - */ -static void -add_to_poll_list(int fd, struct netconfig *nconf) -{ - static int poll_array_size = 0; - - /* - * If the arrays are full, allocate new ones. - */ - if (num_fds == poll_array_size) { - struct pollfd *tpa; - struct conn_entry *tnp; - - if (poll_array_size != 0) { - tpa = poll_array; - tnp = conn_polled; - } else - tpa = (struct pollfd *)0; - - poll_array_size += POLL_ARRAY_INC_SIZE; - - /* - * Allocate new arrays. - */ - poll_array = (struct pollfd *) - malloc(poll_array_size * sizeof (struct pollfd) + 256); - conn_polled = (struct conn_entry *) - malloc(poll_array_size * sizeof (struct conn_entry) + 256); - if (poll_array == (struct pollfd *)NULL || - conn_polled == (struct conn_entry *)NULL) { - syslog(LOG_ERR, "malloc failed for poll array"); - exit(1); - } - - /* - * Copy the data of the old ones into new arrays, and - * free the old ones. - * num_fds is guaranteed to be less than - * poll_array_size, so this memcpy is safe. - */ - if (tpa) { - (void) memcpy((void *)poll_array, (void *)tpa, - num_fds * sizeof (struct pollfd)); - (void) memcpy((void *)conn_polled, (void *)tnp, - num_fds * sizeof (struct conn_entry)); - free((void *)tpa); - free((void *)tnp); - } - } - - /* - * Set the descriptor and event list. All possible events are - * polled for. - */ - poll_array[num_fds].fd = fd; - poll_array[num_fds].events = POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI; - - /* - * Copy the transport data over too. - */ - conn_polled[num_fds].nc = *nconf; /* structure copy */ - conn_polled[num_fds].closing = 0; - - /* - * Set the descriptor to non-blocking. Avoids a race - * between data arriving on the stream and then having it - * flushed before we can read it. - */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { - (void) syslog(LOG_ERR, - "fcntl(file desc. %d/transport %s, F_SETFL, " - "O_NONBLOCK): %m. Exiting", - num_fds, nconf->nc_proto); - exit(1); - } - - /* - * Count this descriptor. - */ - ++num_fds; -} - -static void -remove_from_poll_list(int fd) -{ - int i; - int num_to_copy; - - for (i = 0; i < num_fds; i++) { - if (poll_array[i].fd == fd) { - --num_fds; - num_to_copy = num_fds - i; - (void) memcpy((void *)&poll_array[i], - (void *)&poll_array[i+1], - num_to_copy * sizeof (struct pollfd)); - (void) memset((void *)&poll_array[num_fds], 0, - sizeof (struct pollfd)); - (void) memcpy((void *)&conn_polled[i], - (void *)&conn_polled[i+1], - num_to_copy * sizeof (struct conn_entry)); - (void) memset((void *)&conn_polled[num_fds], 0, - sizeof (struct conn_entry)); - return; - } - } - syslog(LOG_ERR, "attempt to remove nonexistent fd from poll list"); - -} - -static void -conn_close_oldest(void) -{ - int fd; - int i1; - - /* - * Find the oldest connection that is not already in the - * process of shutting down. - */ - for (i1 = end_listen_fds; /* no conditional expression */; i1++) { - if (i1 >= num_fds) - return; - if (conn_polled[i1].closing == 0) - break; - } -#ifdef DEBUG - (void) printf("too many connections (%d), releasing oldest (%d)\n", - num_conns, poll_array[i1].fd); -#else - syslog(LOG_WARNING, "too many connections (%d), releasing oldest (%d)", - num_conns, poll_array[i1].fd); -#endif - fd = poll_array[i1].fd; - if (conn_polled[i1].nc.nc_semantics == NC_TPI_COTS) { - /* - * For politeness, send a T_DISCON_REQ to the transport - * provider. We close the stream anyway. - */ - (void) t_snddis(fd, (struct t_call *)0); - num_conns--; - remove_from_poll_list(fd); - (void) t_close(fd); - } else { - /* - * For orderly release, we do not close the stream - * until the T_ORDREL_IND arrives to complete - * the handshake. - */ - if (t_sndrel(fd) == 0) - conn_polled[i1].closing = 1; - } -} - -static boolean_t -conn_get(int fd, struct netconfig *nconf, struct conn_ind **connp) -{ - struct conn_ind *conn; - struct conn_ind *next_conn; - - conn = (struct conn_ind *)malloc(sizeof (*conn)); - if (conn == NULL) { - syslog(LOG_ERR, "malloc for listen indication failed"); - return (FALSE); - } - - /* LINTED pointer alignment */ - conn->conn_call = (struct t_call *)t_alloc(fd, T_CALL, T_ALL); - if (conn->conn_call == NULL) { - free((char *)conn); - rdcd_log_tli_error("t_alloc", fd, nconf); - return (FALSE); - } - - if (t_listen(fd, conn->conn_call) == -1) { - rdcd_log_tli_error("t_listen", fd, nconf); - (void) t_free((char *)conn->conn_call, T_CALL); - free((char *)conn); - return (FALSE); - } - - if (conn->conn_call->udata.len > 0) { - syslog(LOG_WARNING, - "rejecting inbound connection(%s) with %d bytes " - "of connect data", - nconf->nc_proto, conn->conn_call->udata.len); - - conn->conn_call->udata.len = 0; - (void) t_snddis(fd, conn->conn_call); - (void) t_free((char *)conn->conn_call, T_CALL); - free((char *)conn); - return (FALSE); - } - - if ((next_conn = *connp) != NULL) { - next_conn->conn_prev->conn_next = conn; - conn->conn_next = next_conn; - conn->conn_prev = next_conn->conn_prev; - next_conn->conn_prev = conn; - } else { - conn->conn_next = conn; - conn->conn_prev = conn; - *connp = conn; - } - return (TRUE); -} - -static int -discon_get(int fd, struct netconfig *nconf, struct conn_ind **connp) -{ - struct conn_ind *conn; - struct t_discon discon; - - discon.udata.buf = (char *)0; - discon.udata.maxlen = 0; - if (t_rcvdis(fd, &discon) == -1) { - rdcd_log_tli_error("t_rcvdis", fd, nconf); - return (-1); - } - - conn = *connp; - if (conn == NULL) - return (0); - - do { - if (conn->conn_call->sequence == discon.sequence) { - if (conn->conn_next == conn) - *connp = (struct conn_ind *)0; - else { - if (conn == *connp) { - *connp = conn->conn_next; - } - conn->conn_next->conn_prev = conn->conn_prev; - conn->conn_prev->conn_next = conn->conn_next; - } - free((char *)conn); - break; - } - conn = conn->conn_next; - } while (conn != *connp); - - return (0); -} - -static void -cots_listen_event(int fd, int conn_index) -{ - struct t_call *call; - struct conn_ind *conn; - struct conn_ind *conn_head; - int event; - struct netconfig *nconf = &conn_polled[conn_index].nc; - int new_fd; - struct netbuf addrmask; - int ret = 0; - - conn_head = NULL; - (void) conn_get(fd, nconf, &conn_head); - - while ((conn = conn_head) != NULL) { - conn_head = conn->conn_next; - if (conn_head == conn) - conn_head = NULL; - else { - conn_head->conn_prev = conn->conn_prev; - conn->conn_prev->conn_next = conn_head; - } - call = conn->conn_call; - free(conn); - - /* - * If we have already accepted the maximum number of - * connections allowed on the command line, then drop - * the oldest connection (for any protocol) before - * accepting the new connection. Unless explicitly - * set on the command line, max_conns_allowed is -1. - */ - if (max_conns_allowed != -1 && num_conns >= max_conns_allowed) - conn_close_oldest(); - - /* - * Create a new transport endpoint for the same proto as - * the listener. - */ - new_fd = rdc_transport_open(nconf); - if (new_fd == -1) { - call->udata.len = 0; - (void) t_snddis(fd, call); - (void) t_free((char *)call, T_CALL); - syslog(LOG_ERR, "Cannot establish transport over %s", - nconf->nc_device); - continue; - } - - /* Bind to a generic address/port for the accepting stream. */ - if (t_bind(new_fd, NULL, NULL) == -1) { - rdcd_log_tli_error("t_bind", new_fd, nconf); - call->udata.len = 0; - (void) t_snddis(fd, call); - (void) t_free((char *)call, T_CALL); - (void) t_close(new_fd); - continue; - } - - while (t_accept(fd, new_fd, call) == -1) { - if (t_errno != TLOOK) { - rdcd_log_tli_error("t_accept", fd, nconf); - call->udata.len = 0; - (void) t_snddis(fd, call); - (void) t_free((char *)call, T_CALL); - (void) t_close(new_fd); - goto do_next_conn; - } - while (event = t_look(fd)) { - switch (event) { - case T_LISTEN: - (void) conn_get(fd, nconf, &conn_head); - continue; - - case T_DISCONNECT: - (void) discon_get(fd, nconf, - &conn_head); - continue; - - default: - syslog(LOG_ERR, - "unexpected event 0x%x during " - "accept processing (%s)", - event, nconf->nc_proto); - call->udata.len = 0; - (void) t_snddis(fd, call); - (void) t_free((char *)call, T_CALL); - (void) t_close(new_fd); - goto do_next_conn; - } - } - } - - if (set_addrmask(new_fd, nconf, &addrmask) < 0) { - (void) syslog(LOG_ERR, "Cannot set address mask for %s", - nconf->nc_netid); - (void) t_snddis(new_fd, NULL); - (void) t_free((char *)call, T_CALL); - (void) t_close(new_fd); - continue; - } - - /* Tell kRPC about the new stream. */ - ret = (*Mysvc)(new_fd, addrmask, nconf); - if (ret < 0) { - syslog(LOG_ERR, - "unable to register with kernel rpc: %m"); - free(addrmask.buf); - (void) t_snddis(new_fd, NULL); - (void) t_free((char *)call, T_CALL); - (void) t_close(new_fd); - goto do_next_conn; - } - - free(addrmask.buf); - (void) t_free((char *)call, T_CALL); - - /* - * Poll on the new descriptor so that we get disconnect - * and orderly release indications. - */ - num_conns++; - add_to_poll_list(new_fd, nconf); - - /* Reset nconf in case it has been moved. */ - nconf = &conn_polled[conn_index].nc; -do_next_conn:; - } -} - -static int -do_poll_cots_action(int fd, int conn_index) -{ - char buf[256]; - int event; - int i1; - int flags; - struct conn_entry *connent = &conn_polled[conn_index]; - struct netconfig *nconf = &(connent->nc); - const char *errorstr; - - while (event = t_look(fd)) { - switch (event) { - case T_LISTEN: - cots_listen_event(fd, conn_index); - break; - - case T_DATA: - /* - * Receive a private notification from CONS rpcmod. - */ - i1 = t_rcv(fd, buf, sizeof (buf), &flags); - if (i1 == -1) { - syslog(LOG_ERR, "t_rcv failed"); - break; - } - if (i1 < sizeof (int)) - break; - i1 = BE32_TO_U32(buf); - if (i1 == 1 || i1 == 2) { - /* - * This connection has been idle for too long, - * so release it as politely as we can. If we - * have already initiated an orderly release - * and we get notified that the stream is - * still idle, pull the plug. This prevents - * hung connections from continuing to consume - * resources. - */ - if (nconf->nc_semantics == NC_TPI_COTS || - connent->closing != 0) { - (void) t_snddis(fd, (struct t_call *)0); - goto fdclose; - } - /* - * For NC_TPI_COTS_ORD, the stream is closed - * and removed from the poll list when the - * T_ORDREL is received from the provider. We - * don't wait for it here because it may take - * a while for the transport to shut down. - */ - if (t_sndrel(fd) == -1) { - syslog(LOG_ERR, - "unable to send orderly release %m"); - } - connent->closing = 1; - } else - syslog(LOG_ERR, - "unexpected event from CONS rpcmod %d", i1); - break; - - case T_ORDREL: - /* Perform an orderly release. */ - if (t_rcvrel(fd) == 0) { - /* T_ORDREL on listen fd's should be ignored */ - if (!is_listen_fd_index(fd)) { - (void) t_sndrel(fd); - goto fdclose; - } - break; - - } else if (t_errno == TLOOK) { - break; - } else { - rdcd_log_tli_error("t_rcvrel", fd, nconf); - /* - * check to make sure we do not close - * listen fd - */ - if (!is_listen_fd_index(fd)) - break; - else - goto fdclose; - } - - case T_DISCONNECT: - if (t_rcvdis(fd, (struct t_discon *)NULL) == -1) - rdcd_log_tli_error("t_rcvdis", fd, nconf); - - /* - * T_DISCONNECT on listen fd's should be ignored. - */ - if (!is_listen_fd_index(fd)) - break; - else - goto fdclose; - - default: - if (t_errno == TSYSERR) { - if ((errorstr = strerror(errno)) == NULL) { - (void) snprintf(buf, sizeof (buf), - "Unknown error num %d", errno); - errorstr = (const char *)buf; - } - } else if (event == -1) - errorstr = t_strerror(t_errno); - else - errorstr = ""; -#ifdef DEBUG - syslog(LOG_ERR, - "unexpected TLI event (0x%x) on " - "connection-oriented transport(%s, %d):%s", - event, nconf->nc_proto, fd, errorstr); -#endif - -fdclose: - num_conns--; - remove_from_poll_list(fd); - (void) t_close(fd); - return (0); - } - } - - return (0); -} - - -/* - * Called to read and interpret the event on a connectionless descriptor. - * Returns 0 if successful, or a UNIX error code if failure. - */ -static int -do_poll_clts_action(int fd, int conn_index) -{ - int error; - int ret; - int flags; - struct netconfig *nconf = &conn_polled[conn_index].nc; - static struct t_unitdata *unitdata = NULL; - static struct t_uderr *uderr = NULL; - static int oldfd = -1; - struct nd_hostservlist *host = NULL; - struct strbuf ctl[1], data[1]; - /* - * We just need to have some space to consume the - * message in the event we can't use the TLI interface to do the - * job. - * - * We flush the message using getmsg(). For the control part - * we allocate enough for any TPI header plus 32 bytes for address - * and options. For the data part, there is nothing magic about - * the size of the array, but 256 bytes is probably better than - * 1 byte, and we don't expect any data portion anyway. - * - * If the array sizes are too small, we handle this because getmsg() - * (called to consume the message) will return MOREDATA|MORECTL. - * Thus we just call getmsg() until it's read the message. - */ - char ctlbuf[sizeof (union T_primitives) + 32]; - char databuf[256]; - - /* - * If this is the same descriptor as the last time - * do_poll_clts_action was called, we can save some - * de-allocation and allocation. - */ - if (oldfd != fd) { - oldfd = fd; - - if (unitdata) { - (void) t_free((char *)unitdata, T_UNITDATA); - unitdata = NULL; - } - if (uderr) { - (void) t_free((char *)uderr, T_UDERROR); - uderr = NULL; - } - } - - /* - * Allocate a unitdata structure for receiving the event. - */ - if (unitdata == NULL) { - /* LINTED pointer alignment */ - unitdata = (struct t_unitdata *)t_alloc(fd, T_UNITDATA, T_ALL); - if (unitdata == NULL) { - if (t_errno == TSYSERR) { - /* - * Save the error code across - * syslog(), just in case - * syslog() gets its own error - * and therefore overwrites errno. - */ - error = errno; - (void) syslog(LOG_ERR, - "t_alloc(file descriptor %d/transport %s, " - "T_UNITDATA) failed: %m", - fd, nconf->nc_proto); - return (error); - } - (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/" - "transport %s, T_UNITDATA) failed TLI error %d", - fd, nconf->nc_proto, t_errno); - goto flush_it; - } - } - -try_again: - flags = 0; - - /* - * The idea is we wait for T_UNITDATA_IND's. Of course, - * we don't get any, because rpcmod filters them out. - * However, we need to call t_rcvudata() to let TLI - * tell us we have a T_UDERROR_IND. - * - * algorithm is: - * t_rcvudata(), expecting TLOOK. - * t_look(), expecting T_UDERR. - * t_rcvuderr(), expecting success (0). - * expand destination address into ASCII, - * and dump it. - */ - - ret = t_rcvudata(fd, unitdata, &flags); - if (ret == 0 || t_errno == TBUFOVFLW) { - (void) syslog(LOG_WARNING, "t_rcvudata(file descriptor %d/" - "transport %s) got unexpected data, %d bytes", - fd, nconf->nc_proto, unitdata->udata.len); - - /* - * Even though we don't expect any data, in case we do, - * keep reading until there is no more. - */ - if (flags & T_MORE) - goto try_again; - - return (0); - } - - switch (t_errno) { - case TNODATA: - return (0); - case TSYSERR: - /* - * System errors are returned to caller. - * Save the error code across - * syslog(), just in case - * syslog() gets its own error - * and therefore overwrites errno. - */ - error = errno; - (void) syslog(LOG_ERR, - "t_rcvudata(file descriptor %d/transport %s) %m", - fd, nconf->nc_proto); - return (error); - case TLOOK: - break; - default: - (void) syslog(LOG_ERR, - "t_rcvudata(file descriptor %d/transport %s) TLI error %d", - fd, nconf->nc_proto, t_errno); - goto flush_it; - } - - ret = t_look(fd); - switch (ret) { - case 0: - return (0); - case -1: - /* - * System errors are returned to caller. - */ - if (t_errno == TSYSERR) { - /* - * Save the error code across - * syslog(), just in case - * syslog() gets its own error - * and therefore overwrites errno. - */ - error = errno; - (void) syslog(LOG_ERR, - "t_look(file descriptor %d/transport %s) %m", - fd, nconf->nc_proto); - return (error); - } - (void) syslog(LOG_ERR, - "t_look(file descriptor %d/transport %s) TLI error %d", - fd, nconf->nc_proto, t_errno); - goto flush_it; - case T_UDERR: - break; - default: - (void) syslog(LOG_WARNING, "t_look(file descriptor %d/" - "transport %s) returned %d not T_UDERR (%d)", - fd, nconf->nc_proto, ret, T_UDERR); - } - - if (uderr == NULL) { - /* LINTED pointer alignment */ - uderr = (struct t_uderr *)t_alloc(fd, T_UDERROR, T_ALL); - if (uderr == NULL) { - if (t_errno == TSYSERR) { - /* - * Save the error code across - * syslog(), just in case - * syslog() gets its own error - * and therefore overwrites errno. - */ - error = errno; - (void) syslog(LOG_ERR, - "t_alloc(file descriptor %d/transport %s, " - "T_UDERROR) failed: %m", - fd, nconf->nc_proto); - return (error); - } - (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/" - "transport %s, T_UDERROR) failed TLI error: %d", - fd, nconf->nc_proto, t_errno); - goto flush_it; - } - } - - ret = t_rcvuderr(fd, uderr); - if (ret == 0) { - - /* - * Save the datagram error in errno, so that the - * %m argument to syslog picks up the error string. - */ - errno = uderr->error; - - /* - * Log the datagram error, then log the host that - * probably triggerred. Cannot log both in the - * same transaction because of packet size limitations - * in /dev/log. - */ - (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING, - "%s response over <file descriptor %d/transport %s> " - "generated error: %m", - progname, fd, nconf->nc_proto); - - /* - * Try to map the client's address back to a - * name. - */ - ret = netdir_getbyaddr(nconf, &host, &uderr->addr); - if (ret != -1 && host && host->h_cnt > 0 && - host->h_hostservs) { - (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING, - "Bad %s response was sent to client with " - "host name: %s; service port: %s", - progname, host->h_hostservs->h_host, - host->h_hostservs->h_serv); - } else { - int i, j; - char *buf; - char *hex = "0123456789abcdef"; - - /* - * Mapping failed, print the whole thing - * in ASCII hex. - */ - buf = (char *)malloc(uderr->addr.len * 2 + 1); - for (i = 0, j = 0; i < uderr->addr.len; i++, j += 2) { - buf[j] = hex[((uderr->addr.buf[i]) >> 4) & 0xf]; - buf[j+1] = hex[uderr->addr.buf[i] & 0xf]; - } - buf[j] = '\0'; - (void) syslog((errno == ECONNREFUSED) ? - LOG_DEBUG : LOG_WARNING, - "Bad %s response was sent to client with " - "transport address: 0x%s", - progname, buf); - free((void *)buf); - } - - if (ret == 0 && host != NULL) - netdir_free((void *)host, ND_HOSTSERVLIST); - return (0); - } - - switch (t_errno) { - case TNOUDERR: - goto flush_it; - case TSYSERR: - /* - * System errors are returned to caller. - * Save the error code across - * syslog(), just in case - * syslog() gets its own error - * and therefore overwrites errno. - */ - error = errno; - (void) syslog(LOG_ERR, - "t_rcvuderr(file descriptor %d/transport %s) %m", - fd, nconf->nc_proto); - return (error); - default: - (void) syslog(LOG_ERR, - "t_rcvuderr(file descriptor %d/transport %s) TLI error %d", - fd, nconf->nc_proto, t_errno); - goto flush_it; - } - -flush_it: - /* - * If we get here, then we could not cope with whatever message - * we attempted to read, so flush it. If we did read a message, - * and one isn't present, that is all right, because fd is in - * nonblocking mode. - */ - (void) syslog(LOG_ERR, - "Flushing one input message from <file descriptor %d/transport %s>", - fd, nconf->nc_proto); - - /* - * Read and discard the message. Do this this until there is - * no more control/data in the message or until we get an error. - */ - do { - ctl->maxlen = sizeof (ctlbuf); - ctl->buf = ctlbuf; - data->maxlen = sizeof (databuf); - data->buf = databuf; - flags = 0; - ret = getmsg(fd, ctl, data, &flags); - if (ret == -1) - return (errno); - } while (ret != 0); - - return (0); -} - -/* - * Establish service thread. - */ -static int -rdcsvc(int fd, struct netbuf addrmask, struct netconfig *nconf) -{ -#ifdef __NCALL__ - struct ncall_svc_args nsa; -#else /* !__NCALL__ */ - struct rdc_svc_args nsa; - _rdc_ioctl_t rdc_args = { 0, }; -#endif /* __NCALL__ */ - - nsa.fd = fd; - nsa.nthr = (max_conns_allowed < 0 ? 16 : max_conns_allowed); - (void) strncpy(nsa.netid, nconf->nc_netid, sizeof (nsa.netid)); - nsa.addrmask.len = addrmask.len; - nsa.addrmask.maxlen = addrmask.maxlen; - nsa.addrmask.buf = addrmask.buf; - -#ifdef __NCALL__ - return (sndrsys(NC_IOC_SERVER, &nsa)); -#else /* !__NCALL__ */ - rdc_args.arg0 = (long)&nsa; - return (sndrsys(RDC_ENABLE_SVR, &rdc_args)); -#endif /* __NCALL__ */ -} - - - -static int -nofile_increase(int limit) -{ - struct rlimit rl; - - if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { - syslog(LOG_ERR, - "nofile_increase() getrlimit of NOFILE failed: %m"); - return (-1); - } - - if (limit > 0) - rl.rlim_cur = limit; - else - rl.rlim_cur += NOFILE_INC_SIZE; - - if (rl.rlim_cur > rl.rlim_max && rl.rlim_max != RLIM_INFINITY) - rl.rlim_max = rl.rlim_cur; - - if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { - syslog(LOG_ERR, - "nofile_increase() setrlimit of NOFILE to %d failed: %m", - rl.rlim_cur); - return (-1); - } - - return (0); -} - -int -rdcd_bindit(struct netconfig *nconf, struct netbuf **addr, - struct nd_hostserv *hs, int backlog) -{ - int fd; - struct t_bind *ntb; - struct t_bind tb; - struct nd_addrlist *addrlist; - struct t_optmgmt req, resp; - struct opthdr *opt; - char reqbuf[128]; - - if ((fd = rdc_transport_open(nconf)) == -1) { - syslog(LOG_ERR, "cannot establish transport service over %s", - nconf->nc_device); - return (-1); - } - - addrlist = (struct nd_addrlist *)NULL; - if (netdir_getbyname(nconf, hs, &addrlist) != 0) { - if (strncmp(nconf->nc_netid, "udp", 3) != 0) { - syslog(LOG_ERR, "Cannot get address for transport " - "%s host %s service %s", - nconf->nc_netid, hs->h_host, hs->h_serv); - } - (void) t_close(fd); - return (-1); - } - - if (strcmp(nconf->nc_proto, "tcp") == 0) { - /* - * If we're running over TCP, then set the - * SO_REUSEADDR option so that we can bind - * to our preferred address even if previously - * left connections exist in FIN_WAIT states. - * This is somewhat bogus, but otherwise you have - * to wait 2 minutes to restart after killing it. - */ - if (reuseaddr(fd) == -1) { - syslog(LOG_WARNING, - "couldn't set SO_REUSEADDR option on transport"); - } - } - - if (nconf->nc_semantics == NC_TPI_CLTS) - tb.qlen = 0; - else - tb.qlen = backlog; - - /* LINTED pointer alignment */ - ntb = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL); - if (ntb == (struct t_bind *)NULL) { - syslog(LOG_ERR, "t_alloc failed: t_errno %d, %m", t_errno); - (void) t_close(fd); - netdir_free((void *)addrlist, ND_ADDRLIST); - return (-1); - } - - tb.addr = *(addrlist->n_addrs); /* structure copy */ - - if (t_bind(fd, &tb, ntb) == -1) { - syslog(LOG_ERR, "t_bind failed: t_errno %d, %m", t_errno); - (void) t_free((char *)ntb, T_BIND); - netdir_free((void *)addrlist, ND_ADDRLIST); - (void) t_close(fd); - return (-1); - } - - /* make sure we bound to the right address */ - if (tb.addr.len != ntb->addr.len || - memcmp(tb.addr.buf, ntb->addr.buf, tb.addr.len) != 0) { - syslog(LOG_ERR, "t_bind to wrong address"); - (void) t_free((char *)ntb, T_BIND); - netdir_free((void *)addrlist, ND_ADDRLIST); - (void) t_close(fd); - return (-1); - } - - *addr = &ntb->addr; - netdir_free((void *)addrlist, ND_ADDRLIST); - - if (strcmp(nconf->nc_proto, "tcp") == 0 || - strcmp(nconf->nc_proto, "tcp6") == 0) { - /* - * Disable the Nagle algorithm on TCP connections. - * Connections accepted from this listener will - * inherit the listener options. - */ - - /* LINTED pointer alignment */ - opt = (struct opthdr *)reqbuf; - opt->level = IPPROTO_TCP; - opt->name = TCP_NODELAY; - opt->len = sizeof (int); - - /* LINTED pointer alignment */ - *(int *)((char *)opt + sizeof (*opt)) = 1; - - req.flags = T_NEGOTIATE; - req.opt.len = sizeof (*opt) + opt->len; - req.opt.buf = (char *)opt; - resp.flags = 0; - resp.opt.buf = reqbuf; - resp.opt.maxlen = sizeof (reqbuf); - - if (t_optmgmt(fd, &req, &resp) < 0 || - resp.flags != T_SUCCESS) { - syslog(LOG_ERR, "couldn't set NODELAY option for " - "proto %s: t_errno = %d, %m", nconf->nc_proto, - t_errno); - } - } - - return (fd); -} - - -/* ARGSUSED */ -static int -bind_to_provider(char *provider, char *serv, struct netbuf **addr, - struct netconfig **retnconf) -{ - struct netconfig *nconf; - NCONF_HANDLE *nc; - struct nd_hostserv hs; - - hs.h_host = HOST_SELF; - hs.h_serv = RDC_SERVICE; /* serv_name_to_port_name(serv); */ - - if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) { - syslog(LOG_ERR, "setnetconfig failed: %m"); - return (-1); - } - while (nconf = getnetconfig(nc)) { - if (OK_TPI_TYPE(nconf) && - strcmp(nconf->nc_device, provider) == 0) { - *retnconf = nconf; - return (rdcd_bindit(nconf, addr, &hs, listen_backlog)); - } - } - (void) endnetconfig(nc); - if ((Is_ipv6present() && (strcmp(provider, "/dev/tcp6") == 0)) || - (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0))) - syslog(LOG_ERR, "couldn't find netconfig entry for provider %s", - provider); - return (-1); -} - - -/* - * For listen fd's index is always less than end_listen_fds. - * It's value is equal to the number of open file descriptors after the - * last listen end point was opened but before any connection was accepted. - */ -static int -is_listen_fd_index(int index) -{ - return (index < end_listen_fds); -} - - -/* - * Create an address mask appropriate for the transport. - * The mask is used to obtain the host-specific part of - * a network address when comparing addresses. - * For an internet address the host-specific part is just - * the 32 bit IP address and this part of the mask is set - * to all-ones. The port number part of the mask is zeroes. - */ -static int -set_addrmask(int fd, struct netconfig *nconf, struct netbuf *mask) -{ - struct t_info info; - - /* - * Find the size of the address we need to mask. - */ - if (t_getinfo(fd, &info) < 0) { - t_error("t_getinfo"); - return (-1); - } - mask->len = mask->maxlen = info.addr; - if (info.addr <= 0) { - syslog(LOG_ERR, "set_addrmask: address size: %ld", info.addr); - return (-1); - } - - mask->buf = (char *)malloc(mask->len); - if (mask->buf == NULL) { - syslog(LOG_ERR, "set_addrmask: no memory"); - return (-1); - } - (void) memset(mask->buf, 0, mask->len); /* reset all mask bits */ - - if (strcmp(nconf->nc_protofmly, NC_INET) == 0) { - /* - * Set the mask so that the port is ignored. - */ - /* LINTED pointer alignment */ - ((struct sockaddr_in *)mask->buf)->sin_addr.s_addr = - (in_addr_t)~0; - /* LINTED pointer alignment */ - ((struct sockaddr_in *)mask->buf)->sin_family = (sa_family_t)~0; - } -#ifdef NC_INET6 - else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) { - /* LINTED pointer alignment */ - (void) memset(&((struct sockaddr_in6 *)mask->buf)->sin6_addr, - (uchar_t)~0, sizeof (struct in6_addr)); - /* LINTED pointer alignment */ - ((struct sockaddr_in6 *)mask->buf)->sin6_family = - (sa_family_t)~0; - } -#endif - else { - /* - * Set all mask bits. - */ - (void) memset(mask->buf, (uchar_t)~0, mask->len); - } - return (0); -} - -#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8) - -static int -sndrsvcpool(int maxservers) -{ - struct svcpool_args npa; - - npa.id = RDC_SVCPOOL_ID; - npa.maxthreads = maxservers; - npa.redline = 0; - npa.qsize = 0; - npa.timeout = 0; - npa.stksize = 0; - npa.max_same_xprt = 0; - return (sndrsys(RDC_POOL_CREATE, &npa)); -} - - -/* - * The following stolen from cmd/fs.d/nfs/lib/thrpool.c - */ - -#include <thread.h> - -/* - * Thread to call into the kernel and do work on behalf of SNDR/ncall-ip. - */ -static void * -svcstart(void *arg) -{ - int id = (int)arg; - int err; - - while ((err = sndrsys(RDC_POOL_RUN, &id)) != 0) { - /* - * Interrupted by a signal while in the kernel. - * this process is still alive, try again. - */ - if (err == EINTR) - continue; - else - break; - } - - /* - * If we weren't interrupted by a signal, but did - * return from the kernel, this thread's work is done, - * and it should exit. - */ - thr_exit(NULL); - return (NULL); -} - -/* - * User-space "creator" thread. This thread blocks in the kernel - * until new worker threads need to be created for the service - * pool. On return to userspace, if there is no error, create a - * new thread for the service pool. - */ -static void * -svcblock(void *arg) -{ - int id = (int)arg; - - /* CONSTCOND */ - while (1) { - thread_t tid; - int err; - - /* - * Call into the kernel, and hang out there - * until a thread needs to be created. - */ - if (err = sndrsys(RDC_POOL_WAIT, &id)) { - if (err == ECANCELED || err == EBUSY) - /* - * If we get back ECANCELED, the service - * pool is exiting, and we may as well - * clean up this thread. If EBUSY is - * returned, there's already a thread - * looping on this pool, so we should - * give up. - */ - break; - else - continue; - } - - (void) thr_create(NULL, NULL, svcstart, (void *)id, - THR_BOUND | THR_DETACHED, &tid); - } - - thr_exit(NULL); - return (NULL); -} - -static int -svcwait(int id) -{ - thread_t tid; - - /* - * Create a bound thread to wait for kernel LWPs that - * need to be created. - */ - if (thr_create(NULL, NULL, svcblock, (void *)id, - THR_BOUND | THR_DETACHED, &tid)) - return (1); - - return (0); -} -#endif /* Solaris 9+ */ diff --git a/usr/src/cmd/avs/rdc/sndrsubr.c b/usr/src/cmd/avs/rdc/sndrsubr.c deleted file mode 100644 index 3f3e30b307..0000000000 --- a/usr/src/cmd/avs/rdc/sndrsubr.c +++ /dev/null @@ -1,463 +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 <stdio.h> -#include <sys/mnttab.h> -#include <errno.h> -#include <limits.h> -#include <fcntl.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/stat.h> -#include <signal.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_prot.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 "rdcadm.h" - - -int maxqfbas = MAXQFBAS; -int maxqitems = MAXQITEMS; -int autosync = AUTOSYNC; -int asyncthr = ASYNCTHR; -int qblock = QBLOCK; - -int -mounted(char *device) -{ - char target[NSC_MAXPATH]; - struct mnttab mntref; - struct mnttab mntent; - FILE *mntfp; - int rdsk; - char *s; - int i; - - rdsk = i = 0; - for (s = target; i < NSC_MAXPATH && (*s = *device++); i++) { - if (*s == 'r' && rdsk == 0 && strncmp(device, "dsk/", 4) == 0) - rdsk = 1; - else - s++; - } - *s = '\0'; - - mntref.mnt_special = target; - mntref.mnt_mountp = NULL; - mntref.mnt_fstype = NULL; - mntref.mnt_mntopts = NULL; - mntref.mnt_time = NULL; - - mntfp = fopen(MNTTAB, "r"); - - if (mntfp == NULL) { - rdc_warn(NULL, - gettext("can not check volume %s against mount table"), - mntref.mnt_special); - /* Assume the worst, that it is mounted */ - return (1); - } - - if (getmntany(mntfp, &mntent, &mntref) != -1) { - /* found something before EOF */ - (void) fclose(mntfp); - return (1); - } - - (void) fclose(mntfp); - return (0); -} - - -/* Needs to match parsing code in rdcboot.c and rdcadm.c */ -char * -rdc_decode_flag(int flag, int options) -{ - static char str[32]; - - switch (flag) { - case (RDC_CMD_COPY): - if (options & RDC_OPT_FULL) - (void) strcpy(str, "-m"); - else - (void) strcpy(str, "-u"); - if (options & RDC_OPT_REVERSE) - (void) strcat(str, " -r"); - break; - - case (RDC_CMD_DISABLE): - (void) strcpy(str, "-d"); - break; - - case (RDC_CMD_ENABLE): - if (options & RDC_OPT_SETBMP) - (void) strcpy(str, "-e"); - else - (void) strcpy(str, "-E"); - break; - - case (RDC_CMD_LOG): - (void) strcpy(str, "-l"); - break; - - case (RDC_CMD_HEALTH): - (void) strcpy(str, "-H"); - break; - - case (RDC_CMD_WAIT): - (void) strcpy(str, "-w"); - break; - - case (RDC_CMD_RECONFIG): - (void) strcpy(str, "-R ..."); - break; - - case (RDC_CMD_TUNABLE): - (void) strcpy(str, ""); - if (maxqfbas != MAXQFBAS) - (void) strcat(str, " -F"); - if (maxqitems != MAXQITEMS) - (void) strcat(str, " -W"); - if (autosync != AUTOSYNC) - (void) strcat(str, " -a"); - if (asyncthr != ASYNCTHR) - (void) strcat(str, " -A"); - if (qblock != QBLOCK) - (void) strcat(str, " -D"); - break; - - case (RDC_CMD_SUSPEND): - (void) strcpy(str, "-s"); - break; - - case (RDC_CMD_RESUME): - (void) strcpy(str, "-r"); - break; - - case (RDC_CMD_RESET): - (void) strcpy(str, "-R"); - break; - - case (RDC_CMD_ADDQ): - (void) strcpy(str, "-q a"); - break; - - case (RDC_CMD_REMQ): - (void) strcpy(str, "-q d"); - break; - - case (RDC_CMD_REPQ): - (void) strcpy(str, "-q r"); - break; - - default: - (void) strcpy(str, gettext("unknown")); - break; - } - - return (str); -} - - -static void -rdc_msg(char *prefix, spcs_s_info_t *status, char *string, va_list ap) -{ - if (status) { - (void) fprintf(stderr, "Remote Mirror: %s\n", prefix); - spcs_s_report(*status, stderr); - } else { - (void) fprintf(stderr, "%s: %s: ", program, prefix); - } - - if (string && *string != '\0') { - (void) vfprintf(stderr, string, ap); - } - - (void) fprintf(stderr, "\n"); -} - -void -rdc_err(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - rdc_msg(gettext("Error"), status, string, ap); - - va_end(ap); - exit(1); -} - -void -rdc_warn(spcs_s_info_t *status, char *string, ...) -{ - va_list ap; - va_start(ap, string); - - rdc_msg(gettext("warning"), status, string, ap); - - va_end(ap); -} - -int -rdc_get_maxsets(void) -{ - rdc_status_t rdc_status; - spcs_s_info_t ustatus; - int rc; - - rdc_status.nset = 0; - ustatus = spcs_s_ucreate(); - - rc = RDC_IOCTL(RDC_STATUS, &rdc_status, 0, 0, 0, 0, ustatus); - if (rc == SPCS_S_ERROR) { - rdc_err(&ustatus, gettext("statistics error")); - } - - spcs_s_ufree(&ustatus); - return (rdc_status.maxsets); -} - -/* - * Look up a set in libcfg to find the setnumber. - * - * ASSUMPTIONS: - * - a valid cfg handle - * - * INPUTS: - * cfg - cfg handle - * tohost - secondary hostname - * tofile - secondary volume - * - * OUTPUTS: - * set number if found, otherwise -1 for an error - */ -int -find_setnumber_in_libcfg(CFGFILE *cfg, char *ctag, char *tohost, char *tofile) -{ - int setnumber; - int entries, rc; - char *buf, *secondary, *shost; - char **entry; - char *cnode; - int offset = 0; - - if (cfg == NULL) { -#ifdef DEBUG - rdc_warn(NULL, "cfg is NULL while looking up set number"); -#endif - return (-1); - } - - entries = cfg_get_section(cfg, &entry, "sndr"); - - rc = -1; - for (setnumber = 1; setnumber <= entries; setnumber++) { - buf = entry[setnumber - 1]; - - (void) strtok(buf, " "); /* phost */ - (void) strtok(NULL, " "); /* primary */ - (void) strtok(NULL, " "); /* pbitmap */ - shost = strtok(NULL, " "); - secondary = strtok(NULL, " "); - - if (ctag && *ctag) { - (void) strtok(NULL, " "); /* sbitmap */ - (void) strtok(NULL, " "); /* type */ - (void) strtok(NULL, " "); /* mode */ - (void) strtok(NULL, " "); /* group */ - cnode = strtok(NULL, " "); - - if (ctag && strcmp(cnode, ctag) != 0) { - /* filter this out */ - ++offset; - continue; - } - } - - /* Check secondary volume name first, will get less hits */ - if (strcmp(secondary, tofile) != 0) { - free(buf); - continue; - } - - if (strcmp(shost, tohost) == 0) { - free(buf); - rc = setnumber - offset; - break; - } - - free(buf); - } - - while (setnumber < entries) - free(entry[setnumber++]); - if (entries) - free(entry); - - return (rc); -} - -void -get_group_diskq(CFGFILE *cfg, char *group, char *diskq) -{ - int i; - char key[CFG_MAX_KEY]; - char buf[CFG_MAX_BUF]; - - if (*group == '\0') - return; - for (i = 1; ; i++) { - bzero(&key, sizeof (key)); - bzero(&buf, sizeof (buf)); - (void) sprintf(key, "sndr.set%d.group", i); - if (cfg_get_cstring(cfg, key, &buf, sizeof (buf)) < 0) - break; - if (strncmp(group, buf, sizeof (buf)) == 0) { - (void) sprintf(key, "sndr.set%d.diskq", i); - if (cfg_get_cstring(cfg, key, diskq, CFG_MAX_BUF) < 0) { - rdc_warn(NULL, gettext("unable to retrieve " - "group %s's disk queue"), group); - } - } - } -} - -int -get_cfg_setid(CFGFILE *cfg, char *ctag, char *tohost, char *tofile) -{ - int setnum = 0; - int close_cfg = 0; - char key[CFG_MAX_KEY]; - char setid[64]; - - if (cfg == NULL) { - close_cfg = 1; - if ((cfg = cfg_open(NULL)) == NULL) { - return (-1); /* message printed by caller */ - } - if (!cfg_lock(cfg, CFG_RDLOCK)) { - cfg_close(cfg); - return (-1); - } - } - setnum = find_setnumber_in_libcfg(cfg, ctag, tohost, tofile); - if (setnum < 0) - return (setnum); - - (void) snprintf(key, CFG_MAX_KEY, "sndr.set%d.options", setnum); - if (cfg_get_single_option(cfg, CFG_SEC_CONF, key, "setid", - setid, sizeof (setid)) < 0) { - if (close_cfg) - cfg_close(cfg); - - spcs_log("sndr", NULL, - gettext("%s unable to get unique setid " - "for %s:%s"), program, tohost, tofile); - return (-1); - - } - if (close_cfg) - cfg_close(cfg); - - return (atoi(setid)); - -} - -int -get_new_cfg_setid(CFGFILE *cfg) -{ - int setid; - char buf[CFG_MAX_BUF]; - char *ctag; - - /* If in a Sun Cluster, SetIDs need to have a ctag */ - if ((ctag = cfg_get_resource(cfg)) != NULL) { - ctag = strdup(ctag); - cfg_resource(cfg, "setid-ctag"); - } - - if (cfg_get_cstring(cfg, "setid.set1.value", buf, CFG_MAX_BUF) < 0) { - setid = 1; - if (cfg_put_cstring(cfg, "setid", "1", CFG_MAX_BUF) < 0) { - rdc_err(NULL, "Unable to store new setid"); - } - } else { - setid = atoi(buf); - setid++; - if (setid <= 0) { - setid = 1; - } - } - - bzero(&buf, CFG_MAX_BUF); - (void) snprintf(buf, sizeof (buf), "%d", setid); - if (cfg_put_cstring(cfg, "setid.set1.value", buf, CFG_MAX_BUF) < 0) { - rdc_err(NULL, "Unable to store new setid"); - } - - /* Restore old ctag if in a Sun Cluster */ - if (ctag) { - cfg_resource(cfg, ctag); - free(ctag); - } - - return (setid); -} - -sigset_t origmask; - -void -block_sigs(void) -{ - sigset_t allsigs; - - (void) sigfillset(&allsigs); - if (sigprocmask(SIG_BLOCK, &allsigs, &origmask) < 0) - rdc_warn(NULL, gettext("Unable to block signals")); -} - -void -unblock_sigs(void) -{ - if (sigprocmask(SIG_SETMASK, &origmask, NULL) < 0) - rdc_warn(NULL, gettext("Unable to unblock signals")); - -} diff --git a/usr/src/cmd/avs/rdc/sndrsyncd.c b/usr/src/cmd/avs/rdc/sndrsyncd.c deleted file mode 100644 index 5f2c56d1b1..0000000000 --- a/usr/src/cmd/avs/rdc/sndrsyncd.c +++ /dev/null @@ -1,1695 +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 <errno.h> -#include <limits.h> -#include <fcntl.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <pthread.h> -#include <thread.h> - -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <stdarg.h> - -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_prot.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/librdc.h> - -#include "rdcadm.h" - - -#define RDCADM "/usr/sbin/sndradm" -#define IIADM "/usr/sbin/iiadm" - -#define UPDATE "update" -#define NOUPDATE "noupdate" - -#define RESYNC_SLEEP (3 * 60) /* Three minutes */ -#define MAIN_SLEEP (5 * 60) /* Five minutes */ -#define CFG_WAIT_SLEEP (5) /* 5 sec */ - -#define MAXHOSTS 1024 -mutex_t cfglock = DEFAULTMUTEX; -#define LOCKCFG() (void) mutex_lock(&cfglock); -#define UNLOCKCFG() (void) mutex_unlock(&cfglock); - -typedef struct host_list_s { - char *hosts[MAXHOSTS]; - int numhosts; - int configured[MAXHOSTS]; - mutex_t hosts_mutex; -} host_list_t; - -host_list_t *host_list; - -extern char *basename(char *); -int rdc_maxsets; -char *program; - -static int clustered = 0; - -int isnewhost(char *host); -void *wait_sync_event(); -void *wait_link_down(void *host); -void rdc_sync(char *tohost); -void remove_from_hostlist(char *host); -void sync_start(char *master); -void sync_complete(char *master); -void cleanup_hostlist(); -void group_start(char *group); -void group_complete(char *group); - - -void -init_host_list(void) -{ - host_list = calloc(1, sizeof (host_list_t)); - if (host_list == NULL) { - spcs_log("sndr", NULL, - gettext("host list not initialized, cannot run")); - rdc_err(NULL, gettext("host list not initialized, cannot run")); - } - (void) mutex_init(&host_list->hosts_mutex, USYNC_THREAD, NULL); -} - -/* ARGSUSED */ -#ifdef lint -void -sndrsyncd_lintmain(argc, argv) -#else -int -main(argc, argv) -#endif -int argc; -char **argv; -{ - rdc_status_t *rdc_info; - int size; - int i; - pid_t pid; - spcs_s_info_t ustatus; - int rc, trc; - int first = 0; - char *required; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("rdc"); - - ustatus = spcs_s_ucreate(); - - program = basename(argv[0]); - - init_host_list(); - - rc = rdc_check_release(&required); - if (rc < 0) { - rdc_err(NULL, - gettext("unable to determine the current " - "Solaris release: %s\n"), strerror(errno)); - /* NOTREACHED */ - } else if (rc == FALSE) { - rdc_err(NULL, - gettext("incorrect Solaris release (requires %s)\n"), - required); - /* NOTREACHED */ - } - - clustered = cfg_iscluster(); - if (clustered < 0) { - rdc_err(NULL, gettext("unable to ascertain environment")); - } - - rdc_maxsets = rdc_get_maxsets(); - if (rdc_maxsets == -1) { - spcs_log("sndr", NULL, - gettext("%s: unable to get maxsets value from kernel"), - program); - rdc_err(NULL, - gettext("unable to get maxsets value from kernel")); - } - size = sizeof (rdc_status_t) + (sizeof (rdc_set_t) * (rdc_maxsets - 1)); - rdc_info = malloc(size); - if (rdc_info == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_err(NULL, - gettext("unable to allocate %ld bytes"), size); - } - bzero(rdc_info, size); - - rdc_info->nset = rdc_maxsets; - - /* - * Fork off a child that becomes the daemon. - */ - if ((pid = fork()) > 0) - exit(0); - else if (pid < 0) { - spcs_log("sndr", NULL, - gettext("%s: cannot fork: %s"), - program, strerror(errno)); - rdc_err(NULL, gettext("cannot fork: %s\n"), - strerror(errno)); - } - - /* - * In child - become daemon. - */ - - for (i = 0; i < 3; i++) - (void) close(i); - - (void) open("/dev/console", O_WRONLY|O_APPEND); - (void) dup(0); - (void) dup(0); - (void) close(0); - - (void) setpgrp(); - - (void) setlocale(LC_ALL, ""); - (void) textdomain("rdc"); - - /* launch a thread to wait for sync start and sync stop events */ - - if ((trc = thr_create(NULL, 0, wait_sync_event, NULL, - THR_BOUND|THR_DETACHED, NULL)) != 0) { - spcs_log("sndr", NULL, - gettext("%s: unable to create thread wait_sync_event"), - program); - rdc_warn(NULL, - gettext("%s unable to create thread wait_sync_event"), - program); - } else { -#ifdef DEBUG - spcs_log("sndr", NULL, - gettext("%s: thread wait_sync_event started"), program); -#endif - ; - } - - for (;;) { - if (!first) { - first++; - (void) sleep(15); - } else - (void) sleep(MAIN_SLEEP); - - bzero(rdc_info, size); - rdc_info->nset = rdc_maxsets; - if (RDC_IOCTL(RDC_STATUS, rdc_info, 0, 0, 0, 0, ustatus) - != SPCS_S_OK) { - spcs_log("sndr", &ustatus, - gettext("%s: status ioctl"), - program); - rdc_warn(&ustatus, gettext("status ioctl")); - continue; - } - - cleanup_hostlist(rdc_info); /* remove non-existent hosts */ - - /* - * Check all enabled sets to see if a new remote host has - * appeared. - */ - for (i = 0; i < rdc_maxsets; i++) { - if (!(rdc_info->rdc_set[i].flags & RDC_ENABLED)) - continue; - /* spawn a new thread for each new host found */ - if (isnewhost(rdc_info->rdc_set[i].secondary.intf)) { - /* - * right now, we could be here before - * the database did the write for this set - * I could check the lock on the database - * but I am just going to give up some time here - * instead. Why do the allocations etc, etc - * if the set is enabled in the kernel and not - * in the config, we know that this set has the - * lock. Why bother adding more contention to - * the lock. - * this is a daemon, afterall. its got time - */ - (void) sleep(CFG_WAIT_SLEEP); - - spcs_log("sndr", NULL, - gettext("%s: new host found (%s) starting " - "its autosync thread"), program, - rdc_info->rdc_set[i].secondary.intf); - - trc = thr_create(NULL, 0, wait_link_down, - (void *) rdc_info->rdc_set[i].\ -secondary.intf, THR_BOUND|THR_DETACHED, NULL); - - if (trc != 0) { - spcs_log("sndr", NULL, - gettext( - "%s create new autosync " - "thread failed"), program); - rdc_warn(NULL, gettext( - "%s create new autosync " - "thread failed"), program); - } - } - } - } - /* NOTREACHED */ -} - - -/* - * The kernel wakes up this function every time it detects the link to the - * specified host has dropped. - */ -void * -wait_link_down(void *thehost) -{ - char *host = (char *)thehost; - char tmphost[MAX_RDC_HOST_SIZE] = { '\0' }; - spcs_s_info_t ustatus; - - if (host) - (void) strncpy(tmphost, host, MAX_RDC_HOST_SIZE); - - ustatus = spcs_s_ucreate(); - - /* Never give up */ - for (;;) { -#ifdef DEBUG - spcs_log("sndr", NULL, - gettext("%s: awaiting link down ioctl for %s"), - program, host[0] == '\0' ? tmphost : host); -#endif - if (RDC_IOCTL(RDC_LINK_DOWN, host, 0, 0, 0, 0, ustatus) - != SPCS_S_OK) { - spcs_log("sndr", &ustatus, - gettext("%s: link down ioctl"), - program); - rdc_warn(&ustatus, gettext("link down ioctl")); - continue; - } -#ifdef DEBUG - - spcs_log("sndr", NULL, - gettext("%s: received link down ioctl for %s"), - program, host[0] == '\0' ? tmphost : host); -#endif - rdc_sync(host[0] == '\0' ? tmphost : host); - } - /* LINTED */ -} - - -/* - * Called when the link to the specified host has dropped. - * For all Remote Mirror sets using the link that have autosync on, - * issue rdcadm -u commands until they complete successfully. - */ -void -rdc_sync(char *tohost) -{ - rdc_set_t *rdc_set = NULL; - int *sync_done = NULL; - int sets = 0; - int syncs_done = 0; - char cmd[256]; - rdc_config_t parms = { 0 }; - spcs_s_info_t ustatus; - int i; - int setnumber; - int numfound = 0; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - CFGFILE *cfg = NULL; - int size; - int first = 0; - int death = 0; - int cfglocked = 0; - - ustatus = spcs_s_ucreate(); - - size = sizeof (rdc_set_t) * rdc_maxsets; - rdc_set = malloc(size); - if (rdc_set == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(rdc_set, size); - size = sizeof (int) * rdc_maxsets; - sync_done = malloc(size); - if (sync_done == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(sync_done, size); - - /* - * Get all sndr entries with shost matching tohost, and save the - * details in an array. - */ - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - bzero(buf, sizeof (buf)); - bzero(key, sizeof (key)); - - (void) snprintf(key, sizeof (key), "sndr.set%d.shost", - setnumber); - - if (!cfglocked) { - LOCKCFG(); - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - - rdc_warn(NULL, - gettext("error opening config")); - UNLOCKCFG(); - goto done; - } - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - goto done; - } - } - - cfglocked = 1; - - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - if (numfound == 0) /* no matching hosts */ - death = 1; /* thread will exit */ - break; - } - if (strcmp(buf, tohost) != 0) - continue; - - numfound++; - (void) strncpy(rdc_set[sets].secondary.intf, buf, - MAX_RDC_HOST_SIZE); - - /* Got a matching entry */ - - (void) snprintf(key, sizeof (key), "sndr.set%d.phost", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) strncpy(rdc_set[sets].primary.intf, buf, - MAX_RDC_HOST_SIZE); - - (void) snprintf(key, sizeof (key), "sndr.set%d.primary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) strncpy(rdc_set[sets].primary.file, buf, NSC_MAXPATH); - - (void) snprintf(key, sizeof (key), "sndr.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) strncpy(rdc_set[sets].secondary.file, buf, NSC_MAXPATH); - - parms.command = RDC_CMD_STATUS; - bcopy((void *)(&rdc_set[sets]), (void *)(&parms.rdc_set[0]), - sizeof (rdc_set_t)); - - /* - * release cfg before diving into the kernel - * this prevents a possible deadlock when doing - * a reverse sync whick will wake up the sync_event - * thread which will try and iiadm -c and hang - * because we still have the cfg_lock. the timed - * wait cv in the kernel will fail the sync and things - * will undeadlock. - */ - - cfg_close(cfg); - cfg = NULL; - cfglocked = 0; - UNLOCKCFG(); - - if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) { - continue; - } - if ((parms.rdc_set[0].autosync == 0) || - (!(parms.rdc_set[0].flags & RDC_LOGGING))) { - continue; - } - - /* Found a suitable set with autosync on, in logging mode */ - sets++; - } - - if (cfg) { - cfg_close(cfg); - cfg = NULL; - UNLOCKCFG(); - } - - if (sets == 0) { -#ifdef DEBUG - spcs_log("sndr", NULL, - gettext("%s: no sets requiring autosync found for %s"), - program, tohost); -#endif - if (death) { - spcs_log("sndr", NULL, - gettext("%s: autosync thread stopping for %s " - "(host deconfigured)"), program, tohost); - } - goto done; - } - - /* Keep issuing rdcadm -u commands until they have all completed */ - for (;;) { - if (!first) - first++; - else - (void) sleep(RESYNC_SLEEP); - - /* Issue rdcadm -u commands for all remaining sets */ - for (i = 0; i < sets; i++) { - if (sync_done[i]) - continue; - - /* - * Need to check if autosync was turned off for a set - * while we were sleeping. We could have the case where - * an update sync failed and autosync was disabled - * while we were sleeping and didn't detect the disable. - * See BugID 4814213. - */ - parms.command = RDC_CMD_STATUS; - bcopy((void *)(&rdc_set[i]), - (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t)); - if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, - ustatus) < 0) { - spcs_log("sndr", &ustatus, gettext("%s: " - "status not available for %s:%s, stopping " - "this autosync attempt"), program, tohost, - rdc_set[i].secondary.file); - sync_done[i] = 1; - syncs_done++; - continue; - } - if (!(parms.rdc_set[0].autosync)) { -#ifdef DEBUG - spcs_log("sndr", NULL, gettext("%s: autosync disabled during sleep, " - "stopping attempt for set %s:%s"), program, tohost, - rdc_set[i].secondary.file); -#endif - sync_done[i] = 1; - syncs_done++; - continue; - } - - (void) sprintf(cmd, "%s -un %s:%s", RDCADM, tohost, - rdc_set[i].secondary.file); - spcs_log("sndr", NULL, - gettext("%s: issuing update sync for %s:%s"), - program, tohost, rdc_set[i].secondary.file); - (void) system(cmd); - } - - /* Issue rdcadm -w commands to wait for updates to finish */ - for (i = 0; i < sets; i++) { - if (sync_done[i]) - continue; - - (void) sprintf(cmd, "%s -wn %s:%s", RDCADM, tohost, - rdc_set[i].secondary.file); - spcs_log("sndr", NULL, - gettext("%s: issuing wait for %s:%s"), - program, tohost, rdc_set[i].secondary.file); - - (void) system(cmd); - - parms.command = RDC_CMD_STATUS; - bcopy((void *)(&rdc_set[i]), - (void *)(&parms.rdc_set[0]), sizeof (rdc_set_t)); - - if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, - ustatus) < 0) { - spcs_log("sndr", &ustatus, - gettext("%s: status not available for " - "%s:%s, stopping this autosync attempt"), - program, tohost, rdc_set[i].secondary.file); - sync_done[i] = 1; - syncs_done++; - continue; - } - /* Check if completed OK, failed or autosync off */ - if (!(parms.rdc_set[0].autosync) || - !(parms.rdc_set[0].flags & RDC_LOGGING) && - !(parms.rdc_set[0].flags & RDC_SYNCING)) { - sync_done[i] = 1; - syncs_done++; - } - } - - if (syncs_done == sets) - break; /* All completed OK */ - } - -done: - if (cfg) { - cfg_close(cfg); - UNLOCKCFG(); - } - spcs_s_ufree(&ustatus); - if (sync_done) - free(sync_done); - if (rdc_set) - free(rdc_set); - if (death) { /* bye bye */ - /* - * if perhaps we lost some race, lets remove this entry from - * the list. Then, if something did go wrong, and we did kill - * a valid thread, it will be detected on the next go around - * of the thread who is looking for new hosts to spawn threads - */ - - remove_from_hostlist(tohost); - thr_exit(0); - } - - (void) sleep(RESYNC_SLEEP); -} - -/* - * Wait for notification by the kernel of a sync start or a sync completed OK - */ -void * -wait_sync_event() -{ - spcs_s_info_t ustatus; - char master[NSC_MAXPATH]; - char group[NSC_MAXPATH]; - int state; - - ustatus = spcs_s_ucreate(); - - master[0] = '\0'; - group[0] = '\0'; - - /* Never give up */ - for (;;) { - /* Kernel tells us which volume and group the event is for */ - state = RDC_IOCTL(RDC_SYNC_EVENT, master, group, 0, 0, 0, - ustatus); - if (state < SPCS_S_OK) { - if (errno != EAGAIN) { - spcs_log("sndr", &ustatus, - gettext("%s: update ioctl"), - program); - rdc_warn(&ustatus, gettext("update ioctl")); - continue; - } - master[0] = '\0'; - continue; - } - - /* - * If target is mounted at the start of a sync or reverse sync, - * return a negative ack. - */ - if ((state == RDC_SYNC_START || state == RDC_RSYNC_START) && - mounted(master)) { - spcs_log("sndr", NULL, - gettext("%s: %s has a file system mounted"), - program, master); - rdc_warn(NULL, - gettext("%s has a file system mounted"), - master); - master[0] = '\0'; /* negative ack */ - continue; - } - - switch (state) { - case RDC_SYNC_START: - if (group[0]) - group_start(group); - else - sync_start(master); - break; - - case RDC_SYNC_DONE: - if (group[0]) - group_complete(group); - else - sync_complete(master); - break; - - default: - break; - } - } - /* LINTED */ -} - - -/* - * A sync has completed OK to a volume not belonging to a group. - * Set the state of the ndr_ii config entry to "update". - */ -void -sync_complete(char *master) -{ - CFGFILE *cfg = NULL; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int i; - int setnumber; - int sev; - - LOCKCFG(); - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - rdc_warn(NULL, gettext("error opening config")); - UNLOCKCFG(); - return; - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - cfg_close(cfg); - UNLOCKCFG(); - return; - } - - /* get ndr_ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, master) != 0) - continue; - - /* Found the matching entry */ - - /* - * Set state to "update" so that starting another sync will - * cause a new Point-in-Time Copy snapshot to be taken. - */ - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", - setnumber); - if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) || - (cfg_commit(cfg) < 0)) { - spcs_log("sndr", NULL, - gettext("%s: unable to update \"%s\" " - "in configuration storage: %s"), - program, buf, cfg_error(&sev)); - rdc_warn(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - } - break; - } - - cfg_close(cfg); - UNLOCKCFG(); -} - - -/* - * Starting a sync to the specified master volume. - * Check the ndr_ii config entries to see if a Point-in-Time Copy - * snapshot should be taken. - */ -void -sync_start(char *master) -{ - char cmd[256]; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - CFGFILE *cfg = NULL; - int i; - int setnumber; - int found; - int sev; - char shadow[NSC_MAXPATH]; - char bitmap[NSC_MAXPATH]; - char *ctag = NULL; - - LOCKCFG(); - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - rdc_warn(NULL, - gettext("error opening config")); - UNLOCKCFG(); - return; - } - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - cfg_close(cfg); - UNLOCKCFG(); - return; - } - - found = 0; - /* get ndr_ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, master) != 0) - continue; - - /* Got a matching entry */ - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) strncpy(shadow, buf, NSC_MAXPATH); - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - (void) strncpy(bitmap, buf, NSC_MAXPATH); - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - /* - * If an PIT snapshot has already been taken, and syncing did - * not complete, the state will be "noupdate", to indicate we - * should not take another one at this point. - */ - if (strcmp(buf, NOUPDATE) != 0) - found = 1; - - break; - } - - if (!found) { - cfg_close(cfg); - UNLOCKCFG(); - return; - } - - found = 0; - /* get ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, shadow) != 0) - continue; - - /* Matching shadow found, so ii already enabled */ - found = 1; - break; - } - - if (found) { - /* Already PIT enabled, so just take a snapshot */ - - /* Get cluster tag of matching entry */ - (void) snprintf(key, sizeof (key), "ii.set%d.cnode", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0) - if ((strlen(buf) == 0) || (buf[0] == '-')) - ctag = "-C local"; - else - ctag = ""; - (void) sprintf(cmd, "%s %s -u s %s", IIADM, ctag, shadow); - } else { - /* - * If clustered, need to enable PIT Copy sets in the same - * cluster as the Remote Mirror set - */ - - if (clustered) { - /* Find a RM set with master as the local volume */ - - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - (void) snprintf(key, sizeof (key), - "sndr.set%d.phost", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - - if (self_check(buf)) - (void) snprintf(key, sizeof (key), - "sndr.set%d.primary", setnumber); - else - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - - if (strcmp(buf, master) != 0) - continue; - - /* Get cluster tag of matching entry */ - - (void) snprintf(key, sizeof (key), - "sndr.set%d.cnode", setnumber); - if (cfg_get_cstring(cfg, key, buf, - CFG_MAX_BUF) < 0) - break; - if ((strlen(buf) == 0) || (buf[0] == '-')) - ctag = strdup("local"); - else - ctag = strdup(buf); - break; - } - } - - /* Not already enabled, so enable a dependent */ - if (ctag) { - (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", IIADM, - ctag, master, shadow, bitmap); - free(ctag); - } else - (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, master, - shadow, bitmap); - } - - cfg_close(cfg); - - if (system(cmd) != 0) { - spcs_log("sndr", NULL, - gettext("Point-in-Time Copy snapshot failed for %s %s %s." - " Please check validity of ndr_ii entry"), - master, shadow, bitmap); - cfg_close(cfg); - UNLOCKCFG(); - return; - } - - /* - * PIT Copy enable or update was fine, so update the ndr_ii entry - * to "noupdate", to prevent invalid point in time copies. - */ - - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - rdc_warn(NULL, - gettext("error opening config")); - UNLOCKCFG(); - return; - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - cfg_close(cfg); - UNLOCKCFG(); - return; - } - - /* get ndr_ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, shadow) != 0) - continue; - - /* Found the matching entry */ - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", - setnumber); - if ((cfg_put_cstring(cfg, key, NOUPDATE, - strlen(NOUPDATE)) < 0) || (cfg_commit(cfg) < 0)) { - spcs_log("sndr", NULL, - gettext("%s: unable to update \"%s\" " - "in configuration storage: %s"), - program, buf, cfg_error(&sev)); - rdc_warn(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - } - break; - } - cfg_close(cfg); - UNLOCKCFG(); -} - -void -cleanup_hostlist(rdc_status_t *rdc_info) -{ - int i, j, k; - char *host, *exhost; - - - (void) mutex_lock(&host_list->hosts_mutex); - for (i = 0; i < host_list->numhosts; i++) { - int found = 0; - for (j = 0; (j < rdc_maxsets) && !found; j++) { - if (!rdc_info->rdc_set[j].flags & RDC_ENABLED) - continue; - if ((!host_list->configured[i]) || - (host_list->hosts[i] == NULL)) { - (void) mutex_unlock(&host_list->hosts_mutex); - return; - } - - host = rdc_info->rdc_set[j].secondary.intf; - if (strcmp(host_list->hosts[i], host) == 0) - found++; - } - if (j == rdc_maxsets) { - /* - * this set is not in the kernel, so remove from list - */ - exhost = host_list->hosts[i]; - if (exhost) { - free(exhost); - exhost = NULL; - } - - k = i; - while (k < host_list->numhosts) { - host_list->hosts[k] = k < host_list->numhosts - 1 ? - host_list->hosts[k+1] : NULL; - k++; - } - host_list->numhosts--; - - bcopy(&host_list->configured[i+1], - &host_list->configured[i], - (MAXHOSTS - i + 1) * sizeof (int)); - host_list->configured[MAXHOSTS - 1] = 0; - } - } - (void) mutex_unlock(&host_list->hosts_mutex); -} - -/* - * explicity remove a host from the host list - * also update the configured array - * called in rdc_sync, just before exiting a thread. - */ -void -remove_from_hostlist(char *host) -{ - int i, k; - char *exhost; - - /* why bother? */ - if ((!host) || (host[0] == '\0')) - return; - - (void) mutex_lock(&host_list->hosts_mutex); - for (i = 0; i < host_list->numhosts; i++) { - if (strcmp(host, host_list->hosts[i]) == 0) { /* found it */ - exhost = host_list->hosts[i]; - if (exhost) { - free(exhost); - exhost = NULL; - } - k = i; - while (k < host_list->numhosts) { - host_list->hosts[k] = k < host_list->numhosts - 1 ? - host_list->hosts[k+1] : NULL; - k++; - } - host_list->numhosts--; - bcopy(&host_list->configured[i+1], - &host_list->configured[i], - (MAXHOSTS - i + 1) * sizeof (int)); - host_list->configured[MAXHOSTS - 1] = 0; - } - - } - (void) mutex_unlock(&host_list->hosts_mutex); -} -/* - * Check to see if this host isn't in our list, so needs a new rdcsyncd proc - */ -int -isnewhost(char *host) -{ - int i; - int new; - - if (self_check(host)) { - return (0); - } - - (void) mutex_lock(&host_list->hosts_mutex); - new = 1; - for (i = 0; i < MAXHOSTS; i++) { - if (host_list->configured[i] == 0) { - host_list->configured[i] = 1; - host_list->hosts[i] = strdup(host); - host_list->numhosts++; - break; - } - if (strcmp(host, host_list->hosts[i]) == 0) { - new = 0; - break; - } - } - (void) mutex_unlock(&host_list->hosts_mutex); - if (i == MAXHOSTS) - new = 0; - return (new); -} - - -/* - * Look for a matching volume name in our remembered list. - */ -int -volume_match(char *buf, char **volume_list, int volumes) -{ - int i; - char *vol; - - for (i = 0; i < volumes; i++) { - vol = volume_list[i]; - if (strcmp(buf, vol) == 0) { - return (1); - } - } - return (0); -} - - -/* - * A sync has completed to a group. We can only update the ndr_ii entries - * if all the members of the group have completed their syncs OK. - * It would be bad to allow some members of the group to have PIT Copy snapshots - * taken and others not, as they need to be consistent. - */ -void -group_complete(char *group) -{ - char **volumes = NULL; - spcs_s_info_t ustatus; - rdc_config_t parms = { 0 }; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - CFGFILE *cfg = NULL; - int i; - int setnumber; - int found; - int replicating = 0; - char primary[NSC_MAXPATH]; - char secondary[NSC_MAXPATH]; - char phost[MAX_RDC_HOST_SIZE]; - char shost[MAX_RDC_HOST_SIZE]; - rdc_set_t *rdc_set; - int sev; - char *local_file; - int size; - - ustatus = spcs_s_ucreate(); - - size = sizeof (char *) * rdc_maxsets; - volumes = malloc(size); - if (volumes == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(volumes, size); - - /* - * If all members of this group are replicating - * set ii_ndr state to "update". Otherwise leave them alone. - */ - LOCKCFG(); - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening lconfig"), - program); - rdc_warn(NULL, gettext("error opening config")); - UNLOCKCFG(); - goto done; - } - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - goto done; - } - - found = 0; - - /* get all RM entries, with a matching group, that are replicating */ - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), - "sndr.set%d.group", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - if (strcmp(buf, group) != 0) - continue; - - /* Found a matching entry */ - - (void) snprintf(key, sizeof (key), - "sndr.set%d.primary", setnumber); - if (cfg_get_cstring(cfg, key, primary, sizeof (primary)) < 0) - break; - (void) strcpy(parms.rdc_set->primary.file, primary); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.phost", setnumber); - if (cfg_get_cstring(cfg, key, phost, sizeof (phost)) < 0) - break; - (void) strcpy(parms.rdc_set->primary.intf, phost); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - if (cfg_get_cstring(cfg, key, secondary, - sizeof (secondary)) < 0) - break; - (void) strcpy(parms.rdc_set->secondary.file, secondary); - - (void) snprintf(key, sizeof (key), - "sndr.set%d.shost", setnumber); - if (cfg_get_cstring(cfg, key, shost, sizeof (shost)) < 0) - break; - (void) strcpy(parms.rdc_set->secondary.intf, shost); - - parms.command = RDC_CMD_STATUS; - if (RDC_IOCTL(RDC_CONFIG, &parms, NULL, 0, 0, 0, ustatus) < 0) { - continue; - } - - /* We found a matching set */ - found++; - - if (self_check(phost)) - local_file = primary; - else - local_file = secondary; - - rdc_set = &parms.rdc_set[0]; - if (!(rdc_set->flags & RDC_LOGGING) && - !(rdc_set->flags & RDC_SYNCING)) { - volumes[replicating] = strdup(local_file); - if (volumes[replicating] == NULL) { - size = strlen(local_file); - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), - size); - goto done; - } - /* We remember all replicating sets */ - replicating++; - } else - break; /* Not all replicating, so done */ - } - - if (found != replicating) - goto done; - - /* All replicating, so update ndr_ii state fields */ - - cfg_unlock(cfg); - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking lconfig"), - program); - rdc_warn(NULL, gettext("error locking config")); - goto done; - } - - /* - * Search through the ndr_ii entries for entries - * that match the saved secondary volume names. - * Set state to "update". - */ - - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - if (!volume_match(buf, volumes, found)) { - continue; - } - - /* Got a matching entry */ - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.state", setnumber); - if ((cfg_put_cstring(cfg, key, UPDATE, strlen(UPDATE)) < 0) || - (cfg_commit(cfg) < 0)) { - spcs_log("sndr", NULL, - gettext("%s: unable to update \"%s\" " - "in configuration storage: %s"), - program, buf, cfg_error(&sev)); - rdc_warn(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - } - } - - -done: - if (cfg) { - cfg_close(cfg); - UNLOCKCFG(); - } - spcs_s_ufree(&ustatus); - if (volumes) { - for (i = 0; i < replicating; i++) - free(volumes[i]); - free(volumes); - } -} - - -/* - * Sync started to a member of a group. - * If all members of the group are in ndr_ii state "update" then take an PIT - * snapshot on all of them. This will provide a consistent point-in-time - * copy until whatever syncs take place are all completed. - */ -void -group_start(char *group) -{ - char **masters = NULL; - char **shadows = NULL; - char **bitmaps = NULL; - char cmd[256]; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - CFGFILE *cfg = NULL; - int i; - int j; - int setnumber; - int found; - int sndr_sets = 0; - int update_needed = 0; - int sev; - char *ctag = NULL; - int commit = 0; - int size; - - size = sizeof (char *) * rdc_maxsets; - masters = malloc(size); - if (masters == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(masters, size); - shadows = malloc(size); - if (shadows == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(shadows, size); - bitmaps = malloc(size); - if (bitmaps == NULL) { - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - bzero(bitmaps, size); - - LOCKCFG(); - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - rdc_warn(NULL, - gettext("error opening config")); - UNLOCKCFG(); - goto done; - } - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - goto done; - } - - /* Now get all Remote Mirror entries with a matching group */ - for (i = 0; i < rdc_maxsets; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), - "sndr.set%d.group", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - if (strcmp(buf, group) != 0) - continue; - - /* Found a matching entry */ - - (void) snprintf(key, sizeof (key), - "sndr.set%d.phost", setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - if (self_check(buf)) { - (void) snprintf(key, sizeof (key), "sndr.set%d.primary", - setnumber); - } else { - (void) snprintf(key, sizeof (key), - "sndr.set%d.secondary", setnumber); - } - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - masters[sndr_sets] = strdup(buf); - if (masters[sndr_sets] == NULL) { - size = strlen(buf); - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - sndr_sets++; - - if (ctag == NULL && clustered) { - /* Get cluster tag of matching entry */ - - (void) snprintf(key, sizeof (key), "sndr.set%d.cnode", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) >= 0) - ctag = strdup(buf); - } - } - - /* - * Search through the ndr_ii entries for entries - * that match the saved local volume names and are in "update" state. - */ - - update_needed = 0; - - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.secondary", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - - if (!volume_match(buf, masters, sndr_sets)) - continue; - - /* Got a matching entry */ - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - shadows[update_needed] = strdup(buf); - if (shadows[update_needed] == NULL) { - size = strlen(buf); - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.bitmap", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - bitmaps[update_needed] = strdup(buf); - if (bitmaps[update_needed] == NULL) { - size = strlen(buf); - spcs_log("sndr", NULL, - gettext("%s: unable to allocate %ld bytes"), - program, size); - rdc_warn(NULL, - gettext("unable to allocate %ld bytes"), size); - goto done; - } - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) { - break; - } - if (strcmp(buf, UPDATE) != 0) { - break; - } - - update_needed++; - } - - if (update_needed != sndr_sets) { -#ifdef DEBUG - spcs_log("sndr", NULL, - gettext("%s: group sync: no Point-in-Time Copy snapshot " - "for %s"), program, group); -#endif - goto done; - } - - /* All RM sets in the group have an ndr_ii entry in "update" state */ - - /* Issue PIT Copy snapshot commands for all sets in the group */ - for (j = 0; j < sndr_sets; j++) { - found = 0; - - /* get ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), "ii.set%d.shadow", - setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, shadows[j]) != 0) - continue; - - /* Matching shadow found, so ii already enabled */ - found = 1; - break; - } - - if (commit) - if (cfg_commit(cfg) < 0) - rdc_warn(NULL, gettext("commit config error")); - cfg_close(cfg); - - if (found) { - (void) sprintf(cmd, "%s -u s %s", IIADM, shadows[j]); - } else { - if (ctag) { - (void) sprintf(cmd, "%s -C %s -e dep %s %s %s", - IIADM, ctag, masters[j], shadows[j], - bitmaps[j]); - free(ctag); - ctag = NULL; - } else - (void) sprintf(cmd, "%s -e dep %s %s %s", IIADM, - masters[j], shadows[j], bitmaps[j]); - } - - if (system(cmd) != 0) { - spcs_log("sndr", NULL, - gettext("%s: group sync: Point-in-Time Copy" - " snapshot failed for %s"), - program, masters[j]); - - goto done; - } - - if ((cfg = cfg_open(NULL)) == NULL) { - spcs_log("sndr", NULL, - gettext("%s: error opening config"), - program); - rdc_warn(NULL, - gettext("error opening config")); - goto done; - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - spcs_log("sndr", NULL, - gettext("%s: error locking config"), - program); - rdc_warn(NULL, gettext("error locking config")); - goto done; - } - commit = 0; - - /* PIT enable or update was fine, so update the ndr_ii entry */ - - /* get ndr_ii entries until a match is found */ - for (i = 0; ; i++) { - setnumber = i + 1; - - (void) snprintf(key, sizeof (key), - "ndr_ii.set%d.shadow", setnumber); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) - break; - if (strcmp(buf, shadows[j]) != 0) - continue; - - /* Found the matching entry */ - - (void) snprintf(key, sizeof (key), "ndr_ii.set%d.state", - setnumber); - if (cfg_put_cstring(cfg, key, NOUPDATE, - strlen(NOUPDATE)) < 0) { - spcs_log("sndr", NULL, - gettext("%s: unable to update \"%s\" " - "in configuration storage: %s"), - program, buf, cfg_error(&sev)); - rdc_warn(NULL, - gettext("unable to update \"%s\" " - "in configuration storage: %s"), - buf, cfg_error(&sev)); - } else - commit = 1; - break; - } - } - - if (commit) - if (cfg_commit(cfg) < 0) - rdc_warn(NULL, gettext("commit config error")); - - spcs_log("sndr", NULL, - gettext("%s: group sync: Point-in-Time Copy snapshots completed " - "for %s"), program, group); - -done: - if (ctag) - free(ctag); - - if (cfg) { - cfg_close(cfg); - UNLOCKCFG(); - } - - if (masters) { - for (i = 0; i < sndr_sets; i++) { - if (masters[i]) - free(masters[i]); - } - free(masters); - } - - if (shadows) { - for (i = 0; i < update_needed; i++) { - if (shadows[i]) - free(shadows[i]); - } - free(shadows); - } - - if (bitmaps) { - for (i = 0; i < update_needed; i++) { - if (bitmaps[i]) - free(bitmaps[i]); - } - free(bitmaps); - } -} diff --git a/usr/src/cmd/avs/sdbc/Makefile b/usr/src/cmd/avs/sdbc/Makefile deleted file mode 100644 index 97cc48f5a1..0000000000 --- a/usr/src/cmd/avs/sdbc/Makefile +++ /dev/null @@ -1,108 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# - -# must be before include of Makefile.cmd -DYNPROG = scmadm \ - sd_stats \ - sd_diag - -include ../../Makefile.cmd -include ../Makefile.com - -SUBDIRS= etc - -PROG = $(DYNPROG) - -scmadm := POBJS = scmadm.o sdbc_ioctl.o -sd_stats := POBJS = sd_stats.o sd_trace.o sdbc_ioctl.o rdc_ioctl.o -sd_diag := POBJS = sd_diag.o -sdbc_dynmem := POBJS = sdbc_dynmem.o - -OBJS= scmadm.o\ - sdbc_ioctl.o\ - sd_diag.o\ - sd_stats.o\ - sd_trace.o\ - sdbc_dynmem.o - -XTRA_OBJS= \ - rdc_ioctl.o - -SRCS= $(OBJS:%.o=%.c) - -POFILE = scmadm.po - -scmadm := LDLIBS += -lnsctl -lunistat -ldscfg -sd_stats := LDLIBS += -lunistat -lcurses -sd_diag := LDLIBS += -lnsctl -sdbc_dynmem := LDLIBS += -lkstat - -CFLAGS += $(CCVERBOSE) -D_SCM_ -D_SD_8K_BLKSIZE -D_SYSCALL32 -CPPFLAGS += -DNSC_MULTI_TERABYTE -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -LINTFLAGS += -D_SCM_ -D_SD_8K_BLKSIZE -D_SYSCALL32 -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -LINTFLAGS += -erroff=E_SEC_SPRINTF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_FORBIDDEN_WARN_ASCFTIME -LINTFLAGS += -DDEBUG -CERRWARN += -_gcc=-Wno-uninitialized -ROOTLINK = $(ROOTUSRSBIN)/scmadm - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) $(XTRA_OBJS) - -all: $(SUBDIRS) $(PROG) $(POFILE) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK) - -lint: $(SUBDIRS) lint_SRCS - -clean: $(SUBDIRS) - $(RM) *.o - -rdc_ioctl.o: ../rdc/rdc_ioctl.c - $(COMPILE.c) ../rdc/rdc_ioctl.c - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(ROOTLINK): $(ROOTUSRSBIN) $(ROOTBIN)/scmadm - -$(RM) $@; $(LN) $(ROOTBIN)/scmadm $@ - -include ../../Makefile.targ - -FRC: diff --git a/usr/src/cmd/avs/sdbc/etc/Makefile b/usr/src/cmd/avs/sdbc/etc/Makefile deleted file mode 100644 index 0abbf70293..0000000000 --- a/usr/src/cmd/avs/sdbc/etc/Makefile +++ /dev/null @@ -1,62 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/ns/sdbc/etc/Makefile - -include ../../../Makefile.cmd -include ../../Makefile.com - -INITPROGS = scm -BINPROGS = dscfg_reconfigure.cluster -SHFILES = $(INITPROGS) $(BINPROGS) -ROOTINIT_D = $(ROOTETC)/init.d - -ROOTBINPROGS= $(BINPROGS:%=$(ROOTBIN)/%) -ROOTINITPROGS= $(INITPROGS:%=$(ROOTINIT_D)/%) - -# scm is mode 744, dscfg_reconfigure.cluster is mode 555 -$(ROOTINITPROGS) := FILEMODE= 744 -$(ROOTBINPROGS) := FILEMODE= 555 - -.KEEP_STATE: - -all: $(SHFILES) $(INITPROGS) $(BINPROGS) - -install: $(ROOTBINPROGS) $(ROOTINITPROGS) $(ROOTLIBSVCMETHOD) $(CLUSTERSBINDIR) - -$(RM) $(ROOTLIBSVCMETHOD)/svc-scm - -$(RM) $(CLUSTERSBINDIR)/dscfg_reconfigure - $(LN) $(ROOTINIT_D)/scm $(ROOTLIBSVCMETHOD)/svc-scm - $(LN) $(ROOTBIN)/$(BINPROGS) $(CLUSTERSBINDIR)/dscfg_reconfigure - -$(ROOTINIT_D)/%: % - $(INS.file) - -clean: - $(RM) $(SHFILES) - -clobber: clean - $(RM) $(ROOTBINPROGS) $(ROOTINITPROGS) - -lint: - -FRC: diff --git a/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh b/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh deleted file mode 100644 index 5dfb40768b..0000000000 --- a/usr/src/cmd/avs/sdbc/etc/dscfg_reconfigure.cluster.sh +++ /dev/null @@ -1,425 +0,0 @@ -#!/usr/bin/ksh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# NWS DataServices within SunCluster reconfiguration script. -# -# Description: -# -# This script is called from /usr/cluster/lib/sc/run_reserve at -# appropriate times to start and stop the NWS DataServices as SunCluster -# disk device groups are brought online or taken offline. -# -# SNDR configuration requires that a resource group to be configured. -# 1. The resource group name should be same as device group name with -stor-rg -# added. e.g. if device group name is abc-dg then resource group name -# would be abc-dg-stor-rg. -# 2. It should have 2 resources in it, unless one of the resource types is the -# SUNW.GeoCtlAVS. One of type SUNW.LogicalHostname and either SUNW.HAStorage -# or SUNW.HAStoragePlus types. Resource type versioning is ignored. -# HAStorage type resource, should have ServicePaths property set to -# device group name. HAStoragePlus type resource, should have either the -# FilesystemMountPoints pointing to a files system associated with the -# device group name, or GlobalDevicePaths property set to device group name. -# LogicalHostname type resource should have a failoverIP address in it and -# it will be used by SNDR to communicate with the secondary side. -# -# As SNDR requires that the LogicalHost (failover) IP address which is a -# part of resource group for SNDR, to be hosted on the same node where the -# device group is, it tries to move the resource group also alongwith the -# device group, in become_primary case of run_reserve script. While -# in primary_to_secondary case, it will try to kill the switchover function -# if it is still running in background, after stopping NWS data services. -# -# Usage: -# -# /usr/cluster/sbin/dscfg_reconfigure { start | stop } diskgroup -# -# Configuration: -# -# Scripts to be run should have been symlinked into $NWS_START_DIR and -# $NWS_STOP_DIR. Note that the scripts are processed in lexical order, -# and that unlike /etc/rc?.d/ there is no leading S or K character. -# -# Exit status: -# -# 0 - success -# 1 - error -# - -# -# Global variables -# - -# this program -typeset -r ARGV0=$(basename $0) - -# directory full of start scripts -typeset -r NWS_START_DIR=/usr/cluster/lib/dscfg/start - -# directory full of stop scripts -typeset -r NWS_STOP_DIR=/usr/cluster/lib/dscfg/stop - -# the syslog facility to use. -# - conceptually this should be based on the output of -# "scha_cluster_get -O SYSLOG_FACILITY", but that won't work early -# during boot. -typeset -r SYSLOG_FACILITY=daemon - -PATH=$PATH:/usr/cluster/bin:/etc - -# Variables for retrying scswitch of Resource group for SNDR -retry_num=12 -retry_interval=10 -rgname= -rgstat= -skip_resource=0 -count_LogicalHostname=0 -count_HAStoragePlus=0 - -# Since the switchover of the resource group is called in background, -# the stop action of the reconfig script will kill the background switchover -# if it is running. Since we are stopping the NWS services on the node, there -# is no need to switch the resource group, so it is killed. -# The pid of the process is kept in file /var/run/scnws/$dg.pid. -# Input: dg - device group -# Output: Nothing, kills the process - -function kill_scswitch -{ - dg=$1 - if [ -f /var/run/scnws/$dg.pid ] - then - for i in `cat /var/run/scnws/$dg.pid` - do - pid=$i - kill -9 $pid - done - rm -f /var/run/scnws/$dg.pid - fi -} - -# Get the status of the resource group on this node, using scha commands. -# Input: resource group - $1 -# Output: Status - -function get_rgstat -{ - rg=$1 - rgstat=`scha_resourcegroup_get -O RG_STATE -G $rg` -} - -# This function is called in background from do_scswitch function, to -# switch the resource group to this node, which is becoming primary for -# the diskgroup. If the status of resource group is Offline, it will use -# scswitch command to switch the resource group to this node. If it has -# become Online, cleanup pid file. If it is Pending, the resource group -# is in the state of becoming online, so wait for sometime to become Online.. -# scswitch may fail, so the function retries $retry_num times, waiting for -# $retry_interval seconds. -# Input: resource group - $1, Diskgroup/Diskset - $2 -# Output: 0 - success, 1 - failure - -function switchfunc -{ - rg=$1 - dg=$2 - how_many=0 - sleep 2 - while [ $how_many != $retry_num ] - do - get_rgstat $rg - case "$rgstat" in - "ONLINE") - rm -f /var/run/scnws/$dg.pid - return 0 - ;; - - "OFFLINE") - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "scswitch of resource group"` "$rg" - - scswitch -z -g $rg -h $(hostname) - retval=$? - if [ $retval != 0 ] - then - sleep $retry_interval - how_many=$(($how_many + 1)) - fi - ;; - - "PENDING_ONLINE") - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "pending online of resource group"` "$rg" - sleep $retry_interval - how_many=$(($how_many + 1)) - ;; - - *) - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "Improper resource group status for Remote Mirror"` "$rgstat" - rm -f /var/run/scnws/$dg.pid - return 1 - ;; - esac - done - logger -p ${SYSLOG_FACILITY}.err \ - -t "NWS.[$ARGV0]" "Did not switch resource group for Remote Mirror. System Administrator intervention required" - rm -f /var/run/scnws/$dg.pid - return 1 -} - - -# This function calls switchfunc function in background, to switch the -# resource group for SNDR. It validates the diskgroup/diskset is configured -# for SNDR, checks if the resource group is in Managed state etc. -# If it detects a mis-configuration, it will disable SNDR for the -# device group being processed. This is to prevent cluster hangs and panics. -# -# The ServicePaths extension property of HAStorage type resource or the -# GlobalDevicePaths extension property of HAStoragePlus, both of which -# specify the device group, serve as a link or mapping to retrieve the -# resource group associated with the SNDR configured device group. -# Switchfunc is called in the background to avoid the deadlock situation arising -# out of switchover of resource group from within device group switchover. -# -# In run_reserve context, we are doing the device group switchover, trying to -# bring it online on the node. Device group is not completely switched online, -# until the calling script run_reserve returns. In the process, we are calling -# the associated SNDR resource group switchover using scswitch command. -# Resource group switchover will trigger the switchover of device group also. -# -# If resource group switchover is called in foreground, before the device -# group has become online, then it will result in switching the device group -# again, resulting in deadlock. Resource group can not become online until -# the device group is online and the device group can not become online until the -# script returns, causing this circular dependency resulting in deadlock. -# -# Calling the resource group switch in background allows current run_reserve -# script to return immediately, allowing device group to become online. -# If the device group is already online on the node, then the resource group -# does not cause the device group switchover again. -# -# Input: Device group dg - $1 -# Output: 0 - success -# 1 - either dg not applicable for SNDR or error -# 2 - SNDR mis-configuration - -function do_scswitch -{ - dg=$1 - - if [ ! -x /usr/cluster/bin/scha_resource_get \ - -o ! -x /usr/cluster/bin/scha_resourcegroup_get ] - then - return 1 - fi - -# hard coded rg name from dg - rgname="$dg-stor-rg" - scha_resourcegroup_get -O rg_description -G $rgname > /dev/null - if [ $? != 0 ] - then -# There is no device group configured in cluster for SNDR with this cluster tag - return 1 - fi - -# Check the state of resource group - - get_rgstat $rgname - if [ -z "$rgstat" \ - -o "$rgstat" = "UNMANAGED" -o "$rgstat" = "ERROR_STOP_FAILED" ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" \ - `gettext "Improper Remote Mirror resource group state"` "$rgstat" - return 2 - fi - -# Check whether resources are of proper type and they are enabled - - rs_list=`scha_resourcegroup_get -O resource_list -G $rgname` - if [ -z "$rs_list" ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" \ - `gettext "No resources in Remote Mirror resource group <$rgname>"` - return 2 - fi - for rs in $rs_list - do - rs_type=`scha_resource_get -O type -R $rs -G $rgname | cut -d':' -f1` - case "$rs_type" in - SUNW.LogicalHostname) - rs_enb=`scha_resource_get -O ON_OFF_SWITCH -R $rs -G $rgname` - if [ "$rs_enb" = "ENABLED" ] - then - count_LogicalHostname=$(($count_LogicalHostname + 1)) - fi - ;; - SUNW.HAStoragePlus) - rs_enb=`scha_resource_get -O ON_OFF_SWITCH -R $rs -G $rgname` - if [ "$rs_enb" = "ENABLED" ] - then - count_HAStoragePlus=$(($count_HAStoragePlus + 1)) - fi - ;; - esac - done - if [ $count_LogicalHostname -lt 1 ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "Missing Enabled Logical Host in resource group <$rgname> for Remote Mirror"` - return 2 - elif [ $count_LogicalHostname -gt 1 ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "Too Many Enabled Logical Host in resource group <$rgname> for Remote Mirror"` - return 2 - fi - - if [ $count_HAStoragePlus -lt 1 ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "Missing Enabled HAStoragePlus in resource group <$rgname> for Remote Mirror"` - return 2 - elif [ $count_HAStoragePlus -gt 1 ] - then - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[$ARGV0]" `gettext "Too Many Enabled HAStoragePlus in resource group <$rgname> for Remote Mirror"` - return 2 - fi - -# Invoke switchfunc to switch the resource group. - - switchfunc $rgname $dg & - pid=$! - mkdir -p /var/run/scnws/ - rm -f /var/run/scnws/$dg.pid - echo $pid > /var/run/scnws/$dg.pid - - return 0 -} - - -# -# Functions -# - -usage() -{ - logger -p ${SYSLOG_FACILITY}.err \ - -t "NWS.[$ARGV0]" "usage: $ARGV0 { start | stop } diskgroup" - exit 1 -} - - -# Input: arg1) $NWS_START_DIR - location of NWS scripts -# arg2) start / stop -# arg3 ) device group - $2 -# arg4) sndr_ena / sndr_dis -# Output: Nothing. Log error if seen - -process_dir() -{ - typeset dir=$1 - typeset arg1=$2 - typeset dg=$3 - typeset arg2=$4 - typeset RDC=$dir/10rdc - - if [[ -d $dir ]] - then - for f in $dir/* - do - # process scripts in the directories in lexical order - # note - no leading S or K unlike /etc/rc?.d/ - - if [ -s $f ] && [ $arg2 != "sndr_dis" ] - then - # run script and pipe output through - # logger into syslog - - /usr/bin/ksh $f $arg1 $dg 2>&1 | - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[${ARGV0}:$(basename $f)]" - else - # SNDR misconfigured - prevent start - if [ -s $f ] && [ $f != $RDC ] - then - # run script and pipe output through - # logger into syslog - /usr/bin/ksh $f $arg1 $dg 2>&1 | - logger -p ${SYSLOG_FACILITY}.notice \ - -t "NWS.[${ARGV0}:$(basename $f)]" - fi - fi - done - else - logger -p ${SYSLOG_FACILITY}.err \ - -t "NWS.[$ARGV0]" "no directory: $dir" - fi -} - - -# -# main -# - -if [ $# -ne 2 ] -then - usage - # not reached -fi - - -case "$1" in -start) - logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "starting: $ARGV0 $*" - do_scswitch $2 - retval=$? - if [ $retval == 2 ] - then - logger -p ${SYSLOG_FACILITY}.err \ - -t "NWS.[$ARGV0]" "**FATAL ERROR** Remote Mirror is mis-configured and DISABLED for devicegroup <"$2"> " - # Disable SNDR - process_dir $NWS_START_DIR start "$2" sndr_dis - else - process_dir $NWS_START_DIR start "$2" sndr_ena - fi - ;; -stop) - logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "stopping: $ARGV0 $*" - process_dir $NWS_STOP_DIR stop "$2" sndr_ena - kill_scswitch $2 - ;; - -*) - usage - # not reached - ;; -esac - -logger -p ${SYSLOG_FACILITY}.notice -t "NWS.[$ARGV0]" "completed: $ARGV0 $*" - -exit 0 diff --git a/usr/src/cmd/avs/sdbc/etc/scm.sh b/usr/src/cmd/avs/sdbc/etc/scm.sh deleted file mode 100644 index f5ce4b1a78..0000000000 --- a/usr/src/cmd/avs/sdbc/etc/scm.sh +++ /dev/null @@ -1,348 +0,0 @@ -#!/bin/ksh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -####################################################################### -# -# This file contains system setup requirements for scm. -# -# For systems before Solaris 10 it should be located in /etc/init.d -# directory with the following links: -# -# ln /etc/init.d/scm /etc/rc0.d/K84scm -# ln /etc/init.d/scm /etc/rc2.d/S002scm -# -# For Solaris 10 or later systems this script is run as part of SVC by -# svc.startd and should be located in /lib/svc/method -# -#USAGE="Usage: $0 { start | stop } -# -####################################################################### - -SVCS=/usr/bin/svcs -DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" -OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2` - -. /lib/svc/share/smf_include.sh - -# Make sure prior SMF dependents are not 'online' -# $1 = name of SMF service to validate dependents -# -do_smf_depends () -{ - times=0 - count=1 - - if [ $OS_MINOR -ge 11 ] - then - return 0 - elif [ -f $DSCFG_DEPEND_NOCHK ] - then - for pid in `pgrep dscfgadm` - do - if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ] - then - return 0 - fi - done - elif [ `ps -ef | grep preremove | grep -c SUNWscmu` -gt 0 ] - then - return 0 - - fi - - while [ $count -ne 0 ] - do - count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l` - if [ $count -ne 0 ] - then - # Output banner after waiting first 5 seconds - # - if [ $times -eq 1 ] - then - echo "Waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - fi - - # Has it been longer then 5 minutes? (60 * 5 secs.) - # - if [ $times -eq 60 ] - then - echo "Error: Failed waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - exit $SMF_EXIT_ERR_FATAL - fi - - # Now sleep, giving other services time to stop - # - sleep 5 - times=`expr $times + 1` - fi - done - return 0 -} - -set_system_type() -{ - CLINFO=/usr/sbin/clinfo - ESMSBIN=/usr/sbin - SCMBIN=/usr/sbin - ESMSCMLIB=/usr/lib - SCMLIB=/usr/lib - DSCFG_LOCKDB=/etc/dscfg_lockdb -} - -do_stopsdbc () -{ - if [ ! -r /dev/sdbc ] - then - return - fi - - ${SCMBIN}/scmadm -d - if [ $? -ne 0 ] ; then - # If the disable failed that means we have pinned data. - echo "Cache Not Deconfigured" - fi -} - -do_stopnskernd () -{ - ps -e | grep -w nskernd > /dev/null 2>&1 - if [ $? -eq 0 ] ; then - # make sure that all data services are unloaded before stopping - # nskernd - cannot stop nskernd when its threads could be in use - # Note: sv is unloadable, but its threadset is shutdown in the - # final close(9e) call. - stop=1 - for m in ste rdc rdcsrv ii sdbc ; do - mid=`/usr/sbin/modinfo | grep -w $m | awk '{print $1}' -` - if [ -z "$mid" ] ; then - continue # not loaded - fi - /usr/sbin/modunload -i $mid > /dev/null 2>&1 - if [ $? -ne 0 ] ; then - stop=0 - break - fi - done - - # kill nskernd if we can - pid=`ps -e | grep -w nskernd | sed -e 's/^ *//' -e 's/ .*//'` - if [ $stop -eq 1 ] ; then - if [ -n "$pid" ] ; then - kill -15 $pid - fi - fi - fi - - if [ -r /dev/ncall -a -x $ESMSCMLIB/ncalladm ] - then - $ESMSCMLIB/ncalladm -d - fi -} - -do_stopdscfglockd () -{ - pid=`ps -e | grep -w dscfgloc | sed -e 's/^ *//' -e 's/ .*//'` - if [ -n "$pid" ] ; then - kill -15 $pid - fi -} - -do_stop () -{ - do_smf_depends "system/nws_scm" - do_stopsdbc - do_stopnskernd - do_stopdscfglockd -} - -do_nskernd () -{ - if [ -x $ESMSCMLIB/ncalladm ] - then - $ESMSCMLIB/ncalladm -e - fi - - ps -e | grep -w nskernd > /dev/null 2>&1 - if [ $? -ne 0 ] ; then - ${SCMLIB}/nskernd - if [ $? -ne 0 ] ; then - echo "Error: Unable to start nskernd" - exit $SMF_EXIT_ERR_FATAL - fi - fi -} - -do_dscfglockd () -{ - ps -e | grep -w dscfgloc > /dev/null 2>&1 - if [ $? -ne 0 ] - then - rm -f /var/tmp/.cfglockd.pid - else - # dscfglockd already running - return - fi - - if ${CLINFO} - then - # - # create or update the dscfg_lockdb file - # - - # create clean tmpnodelist - NODELIST=/tmp/$$.dscfg_nodelist - rm -f $NODELIST >/dev/null 2>&1 - touch $NODELIST - - if [ -x /usr/cluster/bin/scstat ] - then - # get valid names in cluster - /usr/cluster/bin/scstat -n | grep node: | \ - awk '{print $3}' >> $NODELIST - if [ ! -f $DSCFG_LOCKDB ] - then - printf "In clustered environment.\n" - printf "creating per node dscfg_lockdb database" - printf " with following nodenames:\n" - cat $NODELIST - cp $NODELIST $DSCFG_LOCKDB - else - # check if there are any changes - diff $NODELIST $DSCFG_LOCKDB > /dev/null - if [ $? != 0 ] - then - printf "The cluster node names have " - printf "changed. Updating dscfg_lockdb " - printf "database.\n" - printf "Previous node names:\n" - cat $DSCFG_LOCKDB - printf "New node names:\n" - cat $NODELIST - rm -f $DSCFG_LOCKDB - cp $NODELIST $DSCFG_LOCKDB - fi - fi - else - # we're in a cluster, but scstat is not available - printf "In clustered environment.\n" - printf "Required configuration file, $DSCFG_LOCKDB\n" - printf "was not properly populated with the cluster " - printf "nodenames.\nThis file needs to be manually" - printf "updated with the cluster\nnodenames before " - printf "reboot. Refer to Sun Storage Availability\n" - printf "Suite Installation Guide for details.\n" - fi - - # clustered start of dscfglockd - if [ -f $DSCFG_LOCKDB ] - then - printf "Starting dscfglockd\n" - ${SCMLIB}/dscfglockd -f $DSCFG_LOCKDB - else - printf "WARNING: Mis-Configuration of Availability " - printf "Suite for Sun Cluster\n" - printf "WARNING: Can't find configuration file for " - printf "dscfglockd\n" - fi - - rm -f $NODELIST - fi - -} - -do_sdbc () -{ - ${SCMBIN}/scmadm -e -} - - -do_start () -{ - # do nothing if we do not have a dscfg - if [ ! -f /etc/dscfg_local ] - then - echo "Cannot find Availability Suite configuration location" - exit $SMF_EXIT_ERR_NOSMF - fi - - # - # Ordering: - # dscfglockd -- locking must be present before any dscfg access - # nskernd -- starts infrastructure (nskernd, ncall). - # sdbc -- start the cache itself - # - do_dscfglockd - do_nskernd - do_sdbc -} - - -do_usage () -{ - echo "Usage: $0" - echo " start" - echo " stop" - exit 1 -} - -set_system_type - -USED=0 -ACTION= -CLUSTERTAG= - -case $# in -'0') - do_usage - ;; -'1') - ACTION=$1 - USED=1 - ;; -'2') - ACTION=$1 - CLUSTERTAG="$2" - USED=1 - exit 0 - ;; -'*') - do_usage - ;; -esac - -if [ $USED = 0 ] ; then - do_usage -fi - -if [ $ACTION = "start" ] ; then - do_start -elif [ $ACTION = "stop" ] ; then - do_stop -else - do_usage -fi - -exit $SMF_EXIT_OK diff --git a/usr/src/cmd/avs/sdbc/scmadm.c b/usr/src/cmd/avs/sdbc/scmadm.c deleted file mode 100644 index f0a28bbf81..0000000000 --- a/usr/src/cmd/avs/sdbc/scmadm.c +++ /dev/null @@ -1,2156 +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. - */ - -/* - * Utility for cache configuration - */ -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <strings.h> -#include <locale.h> -#include <langinfo.h> -#include <libintl.h> -#include <time.h> -#include <sys/nsctl/sd_bcache.h> -#include <sys/wait.h> -#include <errno.h> -#include <signal.h> -#include <sys/types.h> -#include <fcntl.h> -#include <stropts.h> -#include <ctype.h> -#include <libgen.h> - -#include <sys/nsctl/sdbc_ioctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> -#include <nsctl.h> - -#include <sys/nsctl/cfg.h> -#define STATS_PATH "/usr/bin/sd_stats" - -#define _SD_FNAME /* bring in function names from sd_trace.h */ -#include <sys/nsctl/sd_trace.h> -#include <sys/syslog.h> - -/* - * Since we no longer support nvram cards, the hints wrthru and nowrthru no - * longer serve any purpose, and the system will always be in wrthru mode. - * WRTHRU_HINTS, if defined still allows the setting and reporting of write - * hints. This is defined by default on DEBUG builds. - */ -#ifdef DEBUG -#define WRTHRU_HINTS -#endif - -static int sdbc_max_devices = 0; - -static char alert_file[200] = "/dev/console"; - -/* Variables used to set up paramater block passed to kernel */ -static _sd_cache_param_t user_level_conf; -static int myid; - -static int nodes_configured = 0; -static int minidsp = 0; /* Is it a sp10 */ -static int forced_wrthru = -1; /* 0 clear, 1 set,-1 as is */ -static int no_forced_wrthru = -1; -static short node_defined[MAX_SD_NODES]; -static short nodes_conf[MAX_SD_NODES]; - -#define USAGELEN 1024 -char stats_usage[USAGELEN+128]; -char scmadmUsage[USAGELEN]; - -static caddr_t progname; - - -/* - * Functions exported for fwcadm. - */ -void enable_sdbc(void); -void disable_sdbc(void); -void sdbc_set_maxdev(); - -static void buildusage(char *); - -void print_all_options(void); -void get_cd_all(void); -int toggle_flush(void); -static void sd_gather_alert_dumps(); -static int get_cd(char *); -static int get_hint(char *, int *, int *); -static void check_and_set_mirrors(int, int); -static void print_hint(const uint_t, const int); -static char *get_device_name(char *arg); -static void get_version(); - -extern struct tm *localtime_r(const time_t *, struct tm *); - -#define PRINT_CACHE_SZ_ERR(sz) {\ - (void) fprintf(stderr, gettext("\n%s: desired cache size (%d) "\ - "set to system max (%d)\n"), \ - progname, (sz), MAX_CACHE_SIZE); \ - spcs_log("sdbc", NULL, \ - gettext("desired cache size (%d) "\ - "set to system max (%d)\n"), \ - (sz), MAX_CACHE_SIZE); \ -} - -void -sdbc_report_error(spcs_s_info_t *ustatus) -{ - if (*ustatus != NULL) { - spcs_s_report(*ustatus, stderr); - spcs_s_ufree(ustatus); - } else - (void) fprintf(stderr, "%s\n", strerror(errno)); -} - - -/* - * Return the per-cd hints for a cd. - * - * Since the global (no)wrthru and NSC_NOCACHE hints take precedence - * over the per-cd hints, get them as well and OR the whole lot - * together. - */ -static int -get_cd_hint(const int cd) -{ - spcs_s_info_t ustats; - int nodehint, cdhint; - - nodehint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0, &ustats); - if (nodehint == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get system options failed\n"), progname); - sdbc_report_error(&ustats); - exit(1); - } - - cdhint = SDBC_IOCTL(SDBC_GET_CD_HINT, cd, 0, 0, 0, 0, &ustats); - if (cdhint == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get cd(%d) hint failed\n"), progname, cd); - sdbc_report_error(&ustats); - exit(1); - } - -#ifdef WRTHRU_HINTS - nodehint &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU | NSC_NOCACHE); -#else - nodehint &= (NSC_NOCACHE); -#endif - if (nodehint) { - /* set the top bit to mark it as a system override */ - nodehint |= 0x80000000; - } - - return (cdhint | nodehint); -} - - - -/* - * Check for a config. - * - * If no suitable config can be found, install the default config. - * - * Calling state: - * libcfg locked (mode describes type of lock) - */ -static void -convert_config(CFGFILE *cfg, CFGLOCK mode) -{ - char buf[CFG_MAX_BUF]; - char *default_cfg = "128 64"; - -retry: - if (cfg_get_cstring(cfg, "scm.set1", buf, sizeof (buf)) >= 0) { - /* config exists, return */ - return; - } - - cfg_rewind(cfg, CFG_SEC_CONF); - -#ifdef DEBUG - (void) printf(gettext("%s: installing default config entry '%s'\n"), - progname, default_cfg); -#endif - if (mode != CFG_WRLOCK) { - cfg_unlock(cfg); - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - mode = CFG_WRLOCK; -#ifdef DEBUG - (void) printf(gettext("%s: upgraded lock, retrying\n"), - progname); -#endif - goto retry; - } - - if (cfg_put_cstring(cfg, "scm", default_cfg, strlen(default_cfg)) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to write configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (!cfg_commit(cfg)) { - (void) fprintf(stderr, - gettext("%s: unable to write to configuration: %s\n"), - progname, cfg_error(NULL)); - } - - if (mode != CFG_WRLOCK) { - if (!cfg_lock(cfg, mode)) { - (void) fprintf(stderr, - gettext("%s: unable to relock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - } - - cfg_rewind(cfg, CFG_SEC_CONF); -} - - -static int -iscluster(void) -{ - int rc; - - rc = cfg_iscluster(); - if (rc == 0) { - return (FALSE); - } else if (rc > 0) { - return (TRUE); - } else { - (void) fprintf(stderr, - gettext("%s: unable to ascertain environment\n"), progname); - exit(1); - } - - /* NOTREACHED */ -} - - -static void -restore_hints() -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - int setnumber; - spcs_s_info_t ustatus; - int cd; - - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - if (!cfg_lock(cfg, CFG_RDLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) { - (void) snprintf(key, sizeof (key), "cache_hint.set%d.device", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - /* error or not found */ - break; - } - - if (strcmp(buf, "system") == 0) { - cd = -1; - } else { - cd = get_cd(buf); - if (cd < 0) - continue; - } - - (void) snprintf(key, sizeof (key), "cache_hint.set%d.wrthru", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - continue; - - if (atoi(buf) == 1) { - if (cd == -1) { - /* Node hint */ - if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_WRTHRU, - 1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set system " - "option failed\n"), - progname); - sdbc_report_error(&ustatus); - exit(1); - } - } else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, - NSC_WRTHRU, 1, 0, 0, &ustatus) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set option failed\n"), - progname); - sdbc_report_error(&ustatus); - exit(1); - } - } - - (void) snprintf(key, sizeof (key), "cache_hint.set%d.nordcache", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - continue; - - if (atoi(buf) == 1) { - if (cd == -1) { - /* Node hint */ - if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NOCACHE, - 1, 0, 0, 0, &ustatus) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set system " - "option failed\n"), - progname); - sdbc_report_error(&ustatus); - exit(1); - } - } else if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, NSC_NOCACHE, - 1, 0, 0, &ustatus) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set option failed\n"), - progname); - sdbc_report_error(&ustatus); - exit(1); - } - } - } - - cfg_close(cfg); -} - -void -sdbc_set_maxdev() -{ - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices, - 0, 0, 0, 0, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, gettext("%s: get maxfiles failed\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } -} - -static void -bitmapfs_print(void) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - int setnumber; - - cfg = cfg_open(NULL); - if (cfg == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - for (setnumber = 1; /*CSTYLED*/; setnumber++) { - (void) snprintf(key, sizeof (key), - "bitmaps.set%d.bitmap", setnumber); - buf[0] = 0; - - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - if (errno == ESRCH) { - /* end of list */ - break; - } - - (void) fprintf(stderr, - gettext("%s: error reading configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - (void) printf("%s\n", buf); - } - - cfg_close(cfg); -} - - -static void -bitmapfs_delete(char *bitmapfs) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - int setnumber; - int commit = 0; - - cfg = cfg_open(NULL); - if (cfg == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - for (setnumber = 1; /*CSTYLED*/; setnumber++) { - (void) snprintf(key, sizeof (key), - "bitmaps.set%d.bitmap", setnumber); - buf[0] = 0; - - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - if (errno == ESRCH) { - /* end of list */ - (void) fprintf(stderr, - gettext("%s: %s not found " - "in configuration\n"), - progname, bitmapfs); - break; - } - - (void) fprintf(stderr, - gettext("%s: error reading configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (strcmp(bitmapfs, buf) == 0) { - (void) snprintf(key, sizeof (key), - "bitmaps.set%d", setnumber); - - if (cfg_put_cstring(cfg, key, (char *)NULL, 0) < 0) { - (void) fprintf(stderr, - gettext("%s: unable to delete %s " - "from configuration: %s\n"), - progname, bitmapfs, cfg_error(NULL)); - } else - commit++; - - break; - } - } - - if (commit) { - if (!cfg_commit(cfg)) { - (void) fprintf(stderr, - gettext("%s: unable to write " - "to configuration: %s\n"), - progname, cfg_error(NULL)); - } - commit = 0; - } - - cfg_close(cfg); -} - - -/* - * User visible configuration. - */ - -static const struct { - const char *tag; /* libcfg tag */ - const char *name; /* user presented name */ - const char *help; /* explanation string */ -} sdbc_cfg_options[] = { - { "thread", "nthreads", "number of threads" }, - { "size", "cache_size", "total cache size" }, -#ifdef DEBUG - { "write_cache", "write_cache_size", "write cache size" }, - { "fill_pattern", "fill_pattern", "debug fill pattern" }, - { "reserved1", "reserved1", "unavailable, do not use" }, - { "iobuf", "niobuf", "number of io buffers" }, - { "tdemons", "ntdeamons", "number of sd_test daemons" }, - { "forced_wrthru", "forced_wrthru", "override wrthru detection" }, - { "no_forced_wrthru", "no_forced_wrthru", "override wrthru"}, -#endif - { NULL } -}; - - -static int -configure_sdbc(int argc, char *argv[], int optind) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - char *cp, option[CFG_MAX_BUF], value[CFG_MAX_BUF]; - const int opt_width = 20; - int error, found, commit; - int i; - - error = commit = 0; - - cfg = cfg_open(NULL); - if (cfg == NULL) { - (void) fprintf(stderr, "%s: unable to open configuration: %s", - progname, cfg_error(NULL)); - return (1); - } - - if (argc == optind) { - /* display current user visible config */ - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - error = 1; - goto out; - } - - convert_config(cfg, CFG_RDLOCK); - - for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) { - (void) snprintf(key, sizeof (key), - "scm.set1.%s", sdbc_cfg_options[i].tag); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - if (errno == ESRCH) { - /* not found */ - (void) strcpy(buf, ""); - } else { - (void) fprintf(stderr, - gettext("%s: error reading " - "configuration: %s\n"), - progname, cfg_error(NULL)); - error = 1; - goto out; - } - } - - (void) printf("%-*s: %-*s /* %s */\n", - opt_width, sdbc_cfg_options[i].name, - opt_width, buf, sdbc_cfg_options[i].help); - } - } else { - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - error = 1; - goto out; - } - - convert_config(cfg, CFG_WRLOCK); - - for (/*CSTYLED*/; optind < argc; optind++) { - (void) strncpy(option, argv[optind], sizeof (option)); - option[sizeof (option) - 1] = '\0'; /* terminate */ - - cp = strchr(option, '='); - if (cp != NULL) { - *cp = '\0'; /* terminate option */ - cp++; - (void) strncpy(value, cp, sizeof (value)); - value[sizeof (value) - 1] = '\0'; - - if (*value == '\0') - (void) strncpy(value, "-", - sizeof (value)); - } - - found = 0; - for (i = 0; sdbc_cfg_options[i].tag != NULL; i++) { - if (strcmp(option, - sdbc_cfg_options[i].name) == 0) { - found = 1; - break; - } - } - - if (!found) { - (void) fprintf(stderr, - gettext("%s: unknown configuration " - "parameter: %s\n"), progname, option); - continue; - } - - (void) snprintf(key, sizeof (key), - "scm.set1.%s", sdbc_cfg_options[i].tag); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - (void) fprintf(stderr, - gettext("%s: error reading " - "configuration: %s\n"), - progname, cfg_error(NULL)); - error = 1; - goto out; - } - - if (*buf == '\0') - (void) strncpy(buf, "<default>", sizeof (buf)); - - if (cp != NULL) { - char *tmp; - long val; - /* set to new value */ - - if (strcmp(value, "-")) { /* default ? */ - - val = strtol(value, &tmp, 0); - if (strcmp(value, tmp) == 0) { - (void) fprintf(stderr, - gettext( - "%s: bad value (%s) " - "for option %s\n"), - progname, value, option); - error = 1; - goto out; - } - - /* make sure cache size is valid */ - if (strcmp(key, "scm.set1.size") == 0) { - if (val > MAX_CACHE_SIZE) { - PRINT_CACHE_SZ_ERR(val); - - /* - * Overwrite the - * cache size with - * the maximum cache - * size. - */ - (void) snprintf(value, - sizeof (value), - "%ld", - (long) - MAX_CACHE_SIZE); - } - } - } - - if (cfg_put_cstring(cfg, key, value, - strlen(value)) < 0) { - (void) fprintf(stderr, - gettext("\n%s: error writing " - "configuration: %s\n"), - progname, cfg_error(NULL)); - error = 1; - goto out; - } - - (void) snprintf(buf, sizeof (buf), - "%s = %s", buf, - (strcmp(value, "-") == 0) ? - "<default>" : value); - - commit = 1; - } - - (void) printf("%-*s: %-*s /* %s */\n", - opt_width, sdbc_cfg_options[i].name, - opt_width, buf, sdbc_cfg_options[i].help); - } /* end command line args */ - } - -out: - if (commit) { - if (!cfg_commit(cfg)) { - (void) fprintf(stderr, - gettext("%s: unable to write " - "to configuration: %s\n"), - progname, cfg_error(NULL)); - } - commit = 0; - - (void) printf("\n%s\n", - gettext("Changed configuration parameters " - "will take effect when the cache is restarted")); - } - - cfg_close(cfg); - return (error); -} - - -static char * -cd_to_device(int cd) -{ - static _sd_stats_t *cs_cur = NULL; - spcs_s_info_t ustatus; - - if (cs_cur == NULL) { - cs_cur = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - - if (cs_cur == NULL) { - (void) fprintf(stderr, gettext("%s malloc: %s\n"), - progname, strerror(errno)); - exit(1); - } - } - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, - &ustatus) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: stats ioctl failed\n"), progname); - sdbc_report_error(&ustatus); - exit(1); - } - if (cs_cur->st_cachesize == 0 || cd >= cs_cur->st_count) - return (""); - - return (cs_cur->st_shared[cd].sh_filename); -} - -/* - * takes either either a string containing the cd or the device name, and - * returns the device name. - */ -static char * -get_device_name(char *arg) -{ - long cd = 0; - char *device; - - /* if the arg has a leading '/', assume it's a valid device name */ - if (!arg || *arg == '/') { - return (arg); - } - - /* treat the "all" keyword as a valid device name */ - if (strcmp(arg, "all") == 0) { - return (arg); - } - - /* - * Next, assume it's a cd, and try to convert it to an integer, and - * subsequently convert that cd to its corresponding device name. - * - * Since strtol returns 0 on failure, we need to make a special case - * for a cd of "0", which is valid. - */ - if (((cd = strtol(arg, (char **)NULL, 10)) > 0) || - strcmp(arg, "0") == 0) { - device = cd_to_device((int)cd); - - /* cd_to_device returns NULL or "" on failure--check both */ - if (device && (strcmp(device, ""))) { - /* it seems to be a valid device name */ - return (device); - } - } - - return (NULL); -} - -static void -remove_hint(char *device) -{ - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - int setnumber; - int rc; - - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) { - (void) snprintf(key, sizeof (key), "cache_hint.set%d.device", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - /* error or not found */ - break; - } - - if (strcmp(device, buf) != 0) - continue; - - /* remove config file entry */ - (void) snprintf(key, sizeof (key), - "cache_hint.set%d", setnumber); - rc = cfg_put_cstring(cfg, key, NULL, 0); - if (rc < 0) - (void) fprintf(stderr, - gettext("%s: unable to update configuration " - "storage: %s"), - progname, cfg_error(NULL)); - else if (!cfg_commit(cfg)) - (void) fprintf(stderr, - gettext("%s: unable to update configuration " - "storage: %s"), - progname, cfg_error(NULL)); - else - (void) fprintf(stderr, - gettext("%s: persistent hint for %s" - " removed from configuration\n"), - progname, device); - break; - } - cfg_close(cfg); -} - - -static void -save_hint(int cd, int hint, int flag) -{ - char device[NSC_MAXPATH]; - CFGFILE *cfg; - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - int setnumber; - int found; - int rc; - - if (hint != NSC_WRTHRU && hint != NSC_NOCACHE) - return; - - if (flag != 0 && flag != 1) - return; - - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("%s: unable to access configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - if (!cfg_lock(cfg, CFG_WRLOCK)) { - (void) fprintf(stderr, - gettext("%s: unable to lock configuration: %s\n"), - progname, cfg_error(NULL)); - exit(1); - } - - if (cd == -1) - (void) strcpy(device, "system"); - else - (void) strncpy(device, cd_to_device(cd), NSC_MAXPATH); - - found = 0; - for (setnumber = 1; /*CONSTCOND*/ TRUE; setnumber++) { - (void) snprintf(key, sizeof (key), "cache_hint.set%d.device", - setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - /* error or not found */ - break; - } - - if (strcmp(device, buf) == 0) { - found = 1; - break; - } - } - - if (found) { - if (hint == NSC_WRTHRU) - (void) snprintf(key, sizeof (key), - "cache_hint.set%d.wrthru", setnumber); - else /* NSC_NOCACHE */ - (void) snprintf(key, sizeof (key), - "cache_hint.set%d.nordcache", setnumber); - if (flag == 0) - rc = cfg_put_cstring(cfg, key, "0", 1); - else - rc = cfg_put_cstring(cfg, key, "1", 1); - } else { - (void) strncpy(buf, device, CFG_MAX_BUF); - if (flag == 0) - (void) strncat(buf, " 0 0", CFG_MAX_BUF); - else if (hint == NSC_WRTHRU) - (void) strncat(buf, " 1 0", CFG_MAX_BUF); - else /* NSC_NOCACHE */ - (void) strncat(buf, " 0 1", CFG_MAX_BUF); - rc = cfg_put_cstring(cfg, "cache_hint", buf, sizeof (buf)); - } - - if (rc < 0) - (void) fprintf(stderr, - gettext("%s: unable to update configuration storage: %s"), - progname, cfg_error(NULL)); - else if (!cfg_commit(cfg)) - (void) fprintf(stderr, - gettext("%s: unable to update configuration storage: %s"), - progname, cfg_error(NULL)); - cfg_close(cfg); -} - -#ifdef lint -int -scmadm_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - int o = 0; - int c; - int errflg = 0; - int hflag = 0; - int qflag = 1; - extern int optind; - extern char *optarg; - int cd; - int hint; - int flag; - int optflag = 0; - spcs_s_info_t ustats; - int Dopt, Lopt; - int Oopt = 0; - char *bitmapfs = NULL; - const char *exclusive = gettext( - "-d, -e, -m, -o, -C, -D, -L, and -v " - "are mutually exclusive\n"); - - (void) setlocale(LC_ALL, ""); - (void) textdomain("scm"); - - progname = strdup(basename(argv[0])); - - sdbc_set_maxdev(); - - buildusage(progname); - - Dopt = Lopt = 0; - - while ((c = getopt(argc, argv, -#ifdef DEBUG - "gi:t:S" -#endif - "CD:LOa:devqhm:o:")) != EOF) { - - switch (c) { - - case 'D': - if (optflag) { - (void) fprintf(stderr, exclusive); - goto usage; - } - - Dopt++; - optflag++; - bitmapfs = optarg; - break; - - case 'L': - if (optflag) { - (void) fprintf(stderr, exclusive); - goto usage; - } - - Lopt++; - optflag++; - break; - -#ifdef DEBUG - case 'S': - if (optflag) { - (void) fprintf(stderr, exclusive); - goto usage; - } - - if (putenv(stats_usage) != 0) { - (void) fprintf(stderr, - gettext("%s: unable to putenv()\n"), - progname); - exit(1); - } - - argv[1] = "scmadm"; - if (execv(STATS_PATH, &argv[1]) == -1) { - (void) fprintf(stderr, - gettext("%s: failed to execute " STATS_PATH - "\n"), progname); - (void) fprintf(stderr, - gettext("Please be sure to copy sd_stats" - " from src/cmd/ns/sdbc in a development" - " workspace\n")); - } - exit(0); - break; -#endif - case 'a': - (void) strcpy(alert_file, optarg); - break; - case 'q': - qflag++; - break; - case 'O': /* restore hints */ - Oopt++; - break; - case 'C': /* configure */ - case 'e': /* enable */ - case 'd': /* disable */ - case 'v': /* get version */ - case 'o': /* get/set options */ - case 'm': /* get cd map */ -#ifdef DEBUG - case 't': /* trace */ - case 'i': /* inject_ioerr */ - case 'c': /* clear_ioerr */ - case 'g': /* toggle_flush */ -#endif - if (optflag) { - (void) fprintf(stderr, -#ifdef DEBUG - "%s%s", gettext("-t, -i, -c, -g, "), -#endif - exclusive); - - errflg++; - } - optflag++; - o = c; - break; - case 'h': - hflag = 1; - break; - case '?': - default: - errflg++; - break; - } - if (errflg || hflag) - goto usage; - } - - if (Oopt) { - /* Set hints saved in persistent configuration */ - restore_hints(); - exit(0); - } - if (Dopt || Lopt) { - /* bitmapfs control */ - - if (iscluster()) { - (void) fprintf(stderr, - gettext("%s: bitmap filesystems are not " - "allowed in a cluster\n"), progname); - goto usage; - } - - if ((Dopt + Lopt) > 1) { - (void) fprintf(stderr, gettext("-D and -L are" - "mutually exclusive\n")); - goto usage; - } - - if (Lopt) - bitmapfs_print(); - else /* if (Dopt) */ - bitmapfs_delete(bitmapfs); - - exit(0); - } - - if (!o) { - if (argc > 1) - goto usage; - (void) printf(gettext("%s: Printing all cd's and options:\n"), - progname); - print_all_options(); - } - - /* Configure */ - if (o == 'C') { - exit(configure_sdbc(argc, argv, optind)); - } - /* enable */ - if (o == 'e') { - enable_sdbc(); - if (qflag == 0) - sd_gather_alert_dumps(); - exit(0); - } - /* disable */ - if (o == 'd') { - disable_sdbc(); - exit(0); - } - /* get version */ - if (o == 'v') { - get_version(); - exit(0); - } - /* node_hint or cd_hint */ - if (o == 'o') { - if (!(strcoll(optarg, "system"))) { /* node_hint */ - if ((optind - 1) == (argc - 1)) { /* get */ - if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, - 0, 0, 0, &ustats)) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get system " - "options failed\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } -#ifdef WRTHRU_HINTS - (void) printf(gettext("System Status: ")); - print_hint(hint, 1); -#endif - (void) printf(gettext("System Options: ")); - print_hint(hint, 0); - exit(0); - } else { /* set, clear */ - if (get_hint(argv[optind], &hint, &flag) == -1) - goto usage; - if (hint == -1) { - /* remove hint from config */ - remove_hint("system"); - exit(0); - } - - if (SDBC_IOCTL(SDBC_SET_NODE_HINT, hint, flag, - 0, 0, 0, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set system " - "option failed\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } - save_hint(-1, hint, flag); - (void) printf(gettext("%s: System option %s" - " now set.\n"), progname, argv[optind]); - exit(0); - } - } else { /* cd_hint */ - cd = get_cd(optarg); - if ((optind - 1) == (argc - 1)) { /* get */ - if (cd < 0) { - (void) fprintf(stderr, - gettext("%s: device %s not " - "found\n"), - progname, optarg); - exit(1); - } - hint = get_cd_hint(cd); - (void) printf(gettext("%s: cd(%d) Current " - "options are: "), progname, cd); - print_hint(hint, 0); - exit(0); - } else { /* set, clear */ - if (get_hint(argv[optind], &hint, &flag) == -1) - goto usage; - if (hint == -1) { - /* remove hint from config */ - if (cd < 0) - remove_hint(optarg); - else - remove_hint(cd_to_device(cd)); - exit(0); - } - if (cd < 0) { - (void) fprintf(stderr, - gettext("%s: device %s not " - "found\n"), - progname, optarg); - exit(1); - } - - if (SDBC_IOCTL(SDBC_SET_CD_HINT, cd, hint, - flag, 0, 0, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set option " - "failed\n"), progname); - sdbc_report_error(&ustats); - exit(1); - } - save_hint(cd, hint, flag); - (void) printf(gettext("%s: cd %d option %s now" - " set.\n"), progname, cd, argv[optind]); - exit(0); - } - } - } - - if (o == 'm') { /* "get_cd" = map */ - char *dev_name; - - if (!(strcoll(optarg, "all"))) /* all */ - (void) get_cd_all(); - else { - cd = get_cd(optarg); - if (cd < 0) { - (void) fprintf(stderr, - gettext("%s: device or cd %s not found\n"), - progname, optarg); - exit(1); - } - - if ((dev_name = get_device_name(optarg)) == NULL) { - (void) fprintf(stderr, gettext( - "%s: device for cd %d not found\n"), - progname, cd); - exit(1); - } - - (void) printf(gettext("%s: diskname %s; cd %d\n"), - progname, dev_name, cd); - exit(0); - } - } - -#ifdef DEBUG - if (o == 't') { /* "trace" */ - int flag, value; - _sdtr_table_t tt; - if ((optind+1) != (argc-1)) - goto usage; - cd = get_cd(argv[optind]); - if (cd < 0) { - (void) fprintf(stderr, - gettext("%s: device or cd %s not found\n"), - progname, argv[optind]); - exit(1); - } - - value = strtol(argv[optind+1], 0, 0); - if (!(strcoll(optarg, gettext("size")))) { - flag = SD_SET_SIZE; - tt.tt_max = value; - } else if (!(strcoll(optarg, gettext("mask")))) { - flag = SD_SET_MASK; - tt.tt_mask = value; - } else if (!(strcoll(optarg, gettext("lbolt")))) { - flag = SD_SET_LBOLT; - tt.tt_lbolt = value; - } else if (!(strcoll(optarg, gettext("good")))) { - flag = SD_SET_GOOD; - tt.tt_good = value; - } else goto usage; - - if (SDBC_IOCTL(SDBC_ADUMP, (long)cd, &tt, NULL, 0L, - (long)flag, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: trace %s failed\n"), - progname, optarg); - sdbc_report_error(&ustats); - exit(1); - } - (void) printf(gettext("%s: trace %s processed\n"), - progname, optarg); - if (cd != -1) - (void) printf(gettext(" cd %d; size %d; mask 0x%04x; " - "lbolt %d; good %d;\n"), - cd, tt.tt_max, tt.tt_mask, - tt.tt_lbolt, tt.tt_good); - exit(0); - } - - if (o == 'i') { /* "inject_ioerr" */ - int ioj_err = EIO; - int cd; - int ioj_cnt = 0; - - /* a cd of "-1" represents all devices */ - if (strcmp(optarg, "-1") == 0) { - cd = -1; - } else if ((cd = get_cd(optarg)) < 0) { - (void) fprintf(stderr, - gettext("%s: device or cd %s not found\n"), - progname, optarg); - exit(1); - } - if (argc == 4) - ioj_err = strtol(argv[optind], 0, 0); - if (argc == 5) - ioj_cnt = strtol(argv[optind+1], 0, 0); - - if (SDBC_IOCTL(SDBC_INJ_IOERR, cd, ioj_err, ioj_cnt, 0, 0, - &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: i/o error injection for cd %s " - "failed\n"), progname, optarg); - sdbc_report_error(&ustats); - exit(1); - } - (void) printf(gettext("%s: i/o error injection cd %d errno %d " - "processed\n"), progname, cd, ioj_err); - exit(0); - } - - if (o == 'c') { /* "clear_ioerr" */ - int cd; - - /* a cd of "-1" represents all devices */ - if (strcmp(optarg, "-1") == 0) { - cd = -1; - } else if ((cd = get_cd(optarg)) < 0) { - (void) fprintf(stderr, - gettext("%s: device or cd %s not found\n"), - progname, optarg); - exit(1); - } - - if (SDBC_IOCTL(SDBC_CLR_IOERR, cd, 0, 0, 0, 0, &ustats) - == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: i/o error clear %s failed\n"), - progname, optarg); - sdbc_report_error(&ustats); - exit(1); - } - (void) printf(gettext("%s: i/o error clear for cd %d " - "processed\n"), progname, cd); - exit(0); - } - - if (o == 'g') { /* "toggle_flush" */ - flag = toggle_flush(); - (void) printf(gettext("%s: sdbc cache flush now %s\n"), - progname, flag ? "on" : "off"); - exit(0); - } -#endif /* DEBUG */ - - return (0); -usage: - (void) fprintf(stderr, "%s\n", scmadmUsage); - if (hflag) { - return (0); - } - return (1); -} - - -#define addusage(f__) \ - (void) strncat(scmadmUsage, f__, sizeof (scmadmUsage)); - -#define addusage1(f__, a__) \ - (void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__); \ - (void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__); - -#define addusage2(f__, a__, b__) \ - (void) snprintf(fmt, sizeof (fmt), "%s%s", scmadmUsage, f__); \ - (void) snprintf(scmadmUsage, sizeof (scmadmUsage), fmt, a__, b__); - -static void -buildusage(char *p) -{ - char fmt[USAGELEN]; -#ifdef WRTHRU_HINTS - char *hints_str = "[nordcache|rdcache|wrthru|nowrthru|forget]\n"; -#else - char *hints_str = "[nordcache|rdcache|forget]\n"; -#endif - - bzero(scmadmUsage, sizeof (scmadmUsage)); - bzero(fmt, sizeof (fmt)); - - addusage(gettext("Usage :\n")); - addusage1(gettext("\t%s\n"), p); - addusage1(gettext("\t%s -h\n"), p); - addusage1(gettext("\t%s -e\n"), p); - addusage1(gettext("\t%s -d\n"), p); - addusage1(gettext("\t%s -v\n"), p); - addusage1(gettext("\t%s {-L | -D bitmapfs}\n"), p); - addusage1(gettext("\t%s -C [parameter[=[value]] ...]\n"), p); - addusage2(gettext("\t%s -o system %s"), p, hints_str); - addusage2(gettext("\t%s -o <cd> %s"), p, hints_str); - addusage2(gettext("\t%s -o <diskname> %s"), p, hints_str); - addusage1(gettext("\t%s -m {<cd>|<diskname>|all}\n"), p); -#ifdef DEBUG - addusage1(gettext( - "\t%s -S [-Mz] [-d delay_time] [-l logfile] [-r range]\n"), p); - addusage1(gettext( - "\t%s -t {size|mask|lbolt|good} <cd|diskname> <value>\n"), p); - addusage1(gettext("\t%s -g\n"), p); - addusage1(gettext( - "\t%s -i {cd|diskname|-1 for all} [errno [countdown]]\n"), p); - addusage1(gettext("\t%s -c {cd|diskname|-1 for all}\n"), p); - addusage(gettext("\nt = trace\tg = toggle_flush\ti = inject ioerr\n" - "c = clear ioerr\tS = stats\n")); -#endif /* DEBUG */ - addusage(gettext( - "e = enable\td = disable\tv=version\to = get/ set options\n")); - addusage(gettext( - "m = get cd map\n")); - addusage1(gettext( - "note: cd is a cache descriptor integer in the range [0-%d]\n"), - sdbc_max_devices - 1); - addusage(gettext( - " bitmapfs is a block device or filesystem mount point\n")); - -#ifdef DEBUG - (void) snprintf(stats_usage, sizeof (stats_usage), - "SD_STATS_USAGE=%s", scmadmUsage); -#endif -} - -static int -get_hint(char *str, int *hint, int *flag) -{ -#ifdef WRTHRU_HINTS - if (!(strcoll(str, gettext("wrthru")))) { - *hint = NSC_WRTHRU; - *flag = 1; - return (0); - } else if (!(strcoll(str, gettext("nowrthru")))) { - *hint = NSC_WRTHRU; - *flag = 0; - return (0); - } else -#endif - if (!(strcoll(str, gettext("nordcache")))) { - *hint = NSC_NOCACHE; - *flag = 1; - return (0); - } else if (!(strcoll(str, gettext("rdcache")))) { - *hint = NSC_NOCACHE; - *flag = 0; - return (0); - } else if (!(strcoll(str, gettext("forget")))) { - *hint = -1; - *flag = 0; - return (0); - } - return (-1); -} - -/*ARGSUSED*/ -void -print_hint(const uint_t type, const int status) -{ -#ifdef WRTHRU_HINTS - if (status) { - if (type & NSC_FORCED_WRTHRU) { - (void) printf(gettext("Fast Writes Overridden\n")); - } else { - /* if (type & NSC_NO_FORCED_WRTHRU) */ - (void) printf(gettext("default\n")); - } - } else { - (void) printf("%swrthru, %srdcache", - (type & (NSC_FORCED_WRTHRU|NSC_WRTHRU)) ? "" : "no", - (type & NSC_NOCACHE) ? "no" : ""); -#else - { - (void) printf("%srdcache", (type & NSC_NOCACHE) ? "no" : ""); -#endif - - if (type & 0x80000000) - (void) printf(" (overridden by system)"); - - (void) printf("\n"); - } -} - -/* - * Read the configuration via libcfg - */ - -int -get_cache_config() -{ - int i; - int sysid; - CFGFILE *cfg; - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - - - if ((cfg = cfg_open(NULL)) == NULL) { - (void) fprintf(stderr, - gettext("Cannot open configuration file\n")); - exit(1); - } - - if (!cfg_lock(cfg, CFG_RDLOCK)) { - (void) fprintf(stderr, - gettext("Cannot lock configuration file\n")); - exit(1); - } - - convert_config(cfg, CFG_RDLOCK); - (void) memset((char *)&user_level_conf, 0, sizeof (_sd_cache_param_t)); - - /* Get the system ID */ - if (nsc_getsystemid(&sysid) < 0) { - (void) fprintf(stderr, - gettext("%s Unable to obtain subsystem ID: %s\n"), - progname, strerror(errno)); - exit(1); - } - myid = sysid; - - user_level_conf.blk_size = 8192; /* DEFAULT */ - user_level_conf.procs = 16; /* DEFAULT */ - user_level_conf.reserved1 = RESERVED1_DEFAULTS; - - bzero(buf, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "scm.set1.thread"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.threads = atoi(buf); - } else - user_level_conf.threads = 128; /* DEFAULT */ - - (void) snprintf(key, sizeof (key), "scm.set1.tdemons"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.test_demons = atoi(buf); - } - - (void) snprintf(key, sizeof (key), "scm.set1.write_cache"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.write_cache = atoi(buf); - } - - (void) snprintf(key, sizeof (key), "scm.set1.size"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - /* - * We need to run strtol for backwards compatibility in 3.2. - * A workaround for this bug was put in 3.2 which allowed - * customers to set the cache size up to 1024 if it was - * specified in hexadecimal. Decimal still had the limit - * of 128. This change treats them both identically. - */ - user_level_conf.cache_mem[0] = (int)strtol(buf, NULL, 0); - if (user_level_conf.cache_mem[0] > MAX_CACHE_SIZE) { - (void) fprintf(stderr, gettext( - "The cache size of %ld is larger than " - "the system maximum of %ld.\nUse \"scmadm -C " - "cache_size=<size>\" to set the size to a proper " - "value.\n"), - user_level_conf.cache_mem[0], MAX_CACHE_SIZE); - user_level_conf.cache_mem[0] = MAX_CACHE_SIZE; - } - } - - (void) snprintf(key, sizeof (key), "scm.set1.iobuf"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.iobuf = atoi(buf); - } - - (void) snprintf(key, sizeof (key), "scm.set1.fill_pattern"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.fill_pattern = atoi(buf); - user_level_conf.gen_pattern = 1; - } - - (void) snprintf(key, sizeof (key), "scm.set1.no_forced_wrthru"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - no_forced_wrthru = atoi(buf); - } - - (void) snprintf(key, sizeof (key), "scm.set1.forced_wrthru"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - forced_wrthru = atoi(buf); - } - - (void) snprintf(key, sizeof (key), "scm.set1.reserved1"); - if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) > 0) { - user_level_conf.reserved1 = atoi(buf); - } - - cfg_close(cfg); - - /* - * use the default minidsp configuration if no - * node/mirror/remote-mirror/cluster line is in the sd.cf file - */ - if (nodes_configured == 0) - check_and_set_mirrors(myid, _SD_NO_HOST); - - - /* Check if our sysid was defined */ - if (!node_defined[myid]) { - (void) fprintf(stderr, - gettext("This node(%d) is not defined in config.\n"), myid); - exit(1); - } - - /* - * Save off number of nodes so we can calculate the point-to-point - * segements. Code in kernel currently supports MAX_SD_NODES - */ - if ((user_level_conf.num_nodes = nodes_configured) > - MAX_SD_NODES) { - (void) fprintf(stderr, - gettext("Cache can support only %d nodes(%d).\n"), - MAX_SD_NODES, nodes_configured); - exit(1); - } - - if ((nodes_configured % 2) && !minidsp) { - if (nodes_configured == 1) - (void) fprintf(stderr, - gettext("Only one node configured, " - "mirror node must be %d\n"), _SD_NO_HOST); - else - (void) fprintf(stderr, - gettext("Cannot configure odd number of nodes.\n")); - exit(1); - } - - - /* Pass List of Nodes Configured to Cache */ - for (i = 0; i < nodes_configured; i++) - user_level_conf.nodes_conf[i] = nodes_conf[i]; - - /* Place magic number in user_level_conf. Kernel will test for it */ - user_level_conf.magic = _SD_MAGIC; - (void) sleep(1); - return (0); -} - -_sdtr_t hdr; - -/* function name string */ -char * -_sd_fname(int f) -{ - int fn = f & ST_FUNC; - static char c[8]; - char *s; - - if (f & ST_BCACHE) - s = _bcache_fname[fn]; - else if (f & ST_BSUB) - s = _bsub_fname[fn]; - else if (f & ST_IO) - s = _io_fname[fn]; - else if (f & ST_STATS) - s = _stats_fname[fn]; - else if (f & ST_CCIO) - s = _ccio_fname[fn]; - else if (f & ST_FT) - s = _ft_fname[fn]; - else if (f & ST_INFO) - s = _info_fname[fn]; - if (!s) - (void) sprintf(s = c, "0x%04x", f & 0xffff); - return (s); -} - -int alerts = 0; - -/* - * Background daemon to wait for alert (on any device) - * Writes the traces to "sd_alert.CD.NUM", - * and writes an information message to the alert_file. - */ - -void -sd_gather_alert_dumps() -{ - _sdtr_table_t tt; - _sdtr_t *buf; - int cd, count, size, flag; - char filename[64]; - int fd; - time_t tloc; - struct tm tm_storage; - struct tm *tm_ptr; - char timebuf[80]; - spcs_s_info_t ustats; - - /* fork and detach daemon */ - if (fork()) - exit(0); - (void) close(0); - fd = open(alert_file, O_WRONLY|O_APPEND|O_CREAT, 0644); - if (fd == -1) - fd = open("/dev/console", O_WRONLY); - if (fd != -1) { - (void) dup2(fd, 1); - (void) dup2(fd, 2); - (void) close(fd); - } - (void) setsid(); - - size = 10000; - if (size < user_level_conf.trace_size) - size = user_level_conf.trace_size; - - buf = (_sdtr_t *)malloc(size * sizeof (_sdtr_t)); - if (!buf) { - (void) fprintf(stderr, gettext("%s malloc: %s\n"), - progname, strerror(errno)); - exit(1); - } - tloc = time(NULL); - tm_ptr = (struct tm *)localtime_r(&tloc, &tm_storage); - -loop: - cd = SDT_ANY_CD; /* any device */ - flag = SD_ALERT_WAIT; /* block for alert */ - if ((count = SDBC_IOCTL(SDBC_ADUMP, cd, &tt, buf, size, - flag, &ustats)) == SPCS_S_ERROR) { - (void) fprintf(stderr, gettext("%s: sd_adump\n"), progname); - sdbc_report_error(&ustats); - if (errno == EIDRM) { - (void) strftime(timebuf, 80, "%x %X", tm_ptr); - (void) fprintf(stderr, - gettext("%s: cache deconfigured at %s\n"), - progname, timebuf); - exit(0); - } - if (errno == ENOSYS) - exit(0); - exit(errno); - } - if (count == 0) - goto loop; - cd = tt.tt_cd; - (void) sprintf(filename, "%s.%d.%d", "sd_alert", cd, alerts++); - if ((fd = open(filename, O_CREAT | O_RDWR, 0444)) == -1) { - (void) fprintf(stderr, gettext("%s: open: %s\n"), - progname, strerror(errno)); - exit(errno); - } - /* - * write header to identify device, write entries - */ - hdr.t_func = SDF_CD; - hdr.t_len = count; - hdr.t_ret = tt.tt_cd; - if (write(fd, &hdr, sizeof (_sdtr_t)) == -1) { - (void) fprintf(stderr, gettext("%s: write: %s\n"), - progname, strerror(errno)); - exit(errno); - } - - if (write(fd, buf, sizeof (_sdtr_t)*count) == -1) { - (void) fprintf(stderr, gettext("%s: write: %s\n"), - progname, strerror(errno)); - exit(errno); - } - (void) close(fd); - - (void) strftime(timebuf, 80, "%x %X", tm_ptr); - (void) printf("sd alert trace dump %s at %s\n", filename, timebuf); - goto loop; -} - - - -/* - * print list of configured cd's, diskname, options and global options - */ -void -print_all_options() -{ - static _sd_stats_t *cs_cur; - spcs_s_info_t ustats; - int cd; - int hint; - char *s1 = "device name"; - char *s2 = "option"; - char fn[19]; - int len; - - /* No corresponding free because this function exits */ - cs_cur = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - if (cs_cur == NULL) { - (void) fprintf(stderr, gettext("%s malloc: %s\n"), - progname, strerror(errno)); - exit(1); - } - - /* node hints */ - if ((hint = SDBC_IOCTL(SDBC_GET_NODE_HINT, 0, 0, 0, 0, 0, - &ustats)) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get system option failed\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } -#ifdef WRTHRU_HINTS - (void) printf(gettext("System Status: ")); - print_hint(hint, 1); -#endif - (void) printf(gettext("System Options: ")); - print_hint(hint, 0); - - /* get cds */ - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) - == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get_cd failed in print_all options\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } - if (cs_cur->st_cachesize == 0) - (void) printf(gettext("Cache is disabled\n")); - else if (cs_cur->st_count == 0) - (void) printf(gettext("No devices are configured\n")); - else { - (void) printf( - gettext("\nConfigured cd's, disknames and options: \n")); - (void) printf(gettext("cd\t%-28s\t%-20s\n"), s1, s2); - for (cd = 0; cd < cs_cur->st_count; cd++) { - if (cs_cur->st_shared[cd].sh_alloc) { - hint = get_cd_hint(cd); - if ((len = - strlen(cs_cur->st_shared[cd].sh_filename)) - > 23) { - (void) strcpy(fn, "..."); - (void) strcat(fn, - cs_cur->st_shared[cd].sh_filename + - len - 20); - } else { - (void) strcpy(fn, - cs_cur->st_shared[cd].sh_filename); - } - - (void) printf(gettext("%d\t%-28.*s\t"), cd, - NSC_MAXPATH, fn); - - print_hint(hint, 0); - } - } - } - exit(0); -} - - -/* - * cache device -- lookup names and cache descriptors of all configured devices - */ -void -get_cd_all() -{ - static _sd_stats_t *cs_cur; - spcs_s_info_t ustats; - int cd; - char fn[19]; - int len; - - /* No corresponding free because this function exits */ - cs_cur = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - if (cs_cur == NULL) { - (void) fprintf(stderr, gettext("%s malloc: %s\n"), - progname, strerror(errno)); - exit(1); - } - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) - == SPCS_S_ERROR) { - (void) fprintf(stderr, gettext("%s: get_cd_all"), - progname); - sdbc_report_error(&ustats); - exit(1); - } - if (cs_cur->st_cachesize == 0) - (void) printf(gettext("Cache is disabled\n")); - else if (cs_cur->st_count == 0) - (void) printf(gettext("No devices are configured\n")); - else { - (void) printf(gettext("\tcd\tdevice name\n")); - for (cd = 0; cd < cs_cur->st_count; cd++) { - if (cs_cur->st_shared[cd].sh_alloc) { - if ((len = strlen( - cs_cur->st_shared[cd].sh_filename)) > 15) { - (void) strcpy(fn, "..."); - (void) strcat(fn, - cs_cur->st_shared[cd].sh_filename + - len - 12); - } else { - (void) strcpy(fn, - cs_cur->st_shared[cd].sh_filename); - } - (void) printf(gettext("\t%d\t%s\n"), - cd, fn); - } - } - } - exit(0); -} - -/* - * cache device -- specified by number or lookup name - */ -static int -get_cd(char *s) -{ - static _sd_stats_t *cs_cur = NULL; - spcs_s_info_t ustats; - int cd, arg_cd = -1; - - if (cs_cur == NULL) { - /* - * No corresponding free because the memory is reused - * every time the function is called. - */ - cs_cur = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - if (cs_cur == NULL) { - (void) fprintf(stderr, gettext("%s malloc: %s\n"), - progname, strerror(errno)); - exit(1); - } - } - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) - == SPCS_S_ERROR) { - (void) fprintf(stderr, gettext("%s: get_cd\n"), progname); - sdbc_report_error(&ustats); - exit(1); - } - if (cs_cur->st_cachesize == 0) { - (void) printf(gettext("Cache is disabled\n")); - exit(0); - } - - if (*s != '/') { - /* - * Since strtol returns 0 on failure, we need to make a - * special case for a cd of "0", which is valid. - * - * This case also deals with the difference between - * scmadm -o system and scmadm -o 0 - */ - if (((int)strtol(s, (char **)NULL, 10) == 0) && - strcmp(s, "0")) - return (-1); - - /* - * Only return failure at this point, in order to allow - * checking arg_cd against st_count later on. - */ - if ((arg_cd = strtol(s, 0, 0)) < 0) { - return (arg_cd); - } - } - - /* make sure the cd passed as an argument is alloc'd and < st_count */ - if (arg_cd >= 0) { - return (((arg_cd < cs_cur->st_count) && - (cs_cur->st_shared[arg_cd].sh_alloc)) ? arg_cd : -1); - } - - for (cd = 0; cd < cs_cur->st_count; cd++) { - if (cs_cur->st_shared[cd].sh_alloc && - strcmp(s, cs_cur->st_shared[cd].sh_filename) == 0) - return (cd); - } - return (-1); -} - -void -check_and_set_mirrors(int node, int mirror) -{ - - if (minidsp) { - (void) fprintf(stderr, - gettext("%s: minidsp defined. " - "Cannot define other nodes.\n"), - progname); - exit(1); - } - - if (mirror == _SD_NO_HOST) { - minidsp++; - } else if ((!(node % 2) && !(node == mirror - 1)) || - (((node % 2) && !(node == mirror + 1)))) { - (void) fprintf(stderr, - gettext("%s: Node and Mirror identification values " - "must be consecutive\n" - "starting at an even number (Node = %d Mirror = %d)\n"), - progname, node, mirror); - exit(1); - } - - node_defined[node]++; - - nodes_conf[nodes_configured] = node; - nodes_configured++; - - if (node == myid) { - user_level_conf.mirror_host = mirror; - } -} - -char *mem_string = - "%-8s Structures use approx. %8d bytes (%5d pages) of memory\n"; - -void -enable_sdbc() -{ - spcs_s_info_t ustats; - - if (get_cache_config()) { - (void) fprintf(stderr, - gettext("%s: unable to read configuration file\n"), - progname); - exit(1); - } - - if (SDBC_IOCTL(SDBC_ENABLE, &user_level_conf, 0, 0, 0, 0, - &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, gettext("%s: cache enable failed\n"), - progname); - spcs_log("scm", &ustats, gettext("%s cache enable failed"), - progname); - sdbc_report_error(&ustats); - exit(1); - } - spcs_log("scm", NULL, gettext("%s cache enable succeeded"), - progname); -#ifdef DEBUG - (void) printf(gettext("%s: cache has been configured\n"), progname); -#endif -#ifdef WRTHRU_HINTS - if (iscluster()) { - /* Must writethru on a cluster, even if nvram configured */ - forced_wrthru = 1; - } - - if (minidsp && forced_wrthru != -1) { - /* Have minidsp with forced_wrthru hint. Set / Clear hint */ - if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_FORCED_WRTHRU, - forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set/clear forced_wrthru failed\n"), - progname); - sdbc_report_error(&ustats); - } else if (forced_wrthru) { - (void) printf(gettext("%s: Node option forced_wrthru " - "now set.\n"), progname); - } else { - (void) printf(gettext("%s: Node option forced_wrthru " - "now cleared.\n"), progname); - } - } - if (no_forced_wrthru != -1) { - if (SDBC_IOCTL(SDBC_SET_NODE_HINT, NSC_NO_FORCED_WRTHRU, - no_forced_wrthru, 0, 0, 0, &ustats) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: set/clear no_forced_wrthru " - "failed\n"), progname); - sdbc_report_error(&ustats); - } else if (no_forced_wrthru) { - (void) printf(gettext("%s: Node option no_forced_wrthru" - " now set.\n"), progname); - } else { - (void) printf(gettext("%s: Node option no_forced_wrthru" - " now cleared.\n"), progname); - } - } -#endif - - /* do scmadm -O to cater for manual cache disable then enable */ - restore_hints(); -} - -void -disable_sdbc() -{ - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_DISABLE, 0, 0, 0, 0, 0, &ustats) != SPCS_S_OK) { - /* - * If it wasn't already enabled, don't appear to fail - * or users of this program might think the cache is - * configured, when it actually isn't. - */ - if (errno != SDBC_EDISABLE) { - spcs_log("scm", &ustats, - gettext("%s cache disable failed"), progname); - sdbc_report_error(&ustats); - exit(1); - } - } -#ifdef DEBUG - (void) printf(gettext("%s: cache has been deconfigured\n"), progname); -#endif - spcs_log("scm", NULL, gettext("%s cache disable succeeded"), - progname); -} - -static void -get_version() -{ - cache_version_t version; - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_VERSION, &version, 0, 0, 0, 0, &ustats) == - SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: get cache version failed\n"), progname); - sdbc_report_error(&ustats); - exit(1); - } -#ifdef DEBUG - (void) printf(gettext("Cache version %d.%d.%d.%d\n"), - version.major, version.minor, version.micro, version.baseline); -#else - if (version.micro) { - (void) printf(gettext("Cache version %d.%d.%d\n"), - version.major, version.minor, version.micro); - } else { - (void) printf(gettext("Cache version %d.%d\n"), - version.major, version.minor); - } -#endif -} - -#ifdef DEBUG -int -toggle_flush(void) -{ - int rc; - spcs_s_info_t ustats; - - if ((rc = SDBC_IOCTL(SDBC_TOGGLE_FLUSH, 0, 0, 0, - 0, 0, &ustats)) == SPCS_S_ERROR) { - (void) fprintf(stderr, - gettext("%s: toggle sdbc cache flush failed\n"), - progname); - sdbc_report_error(&ustats); - exit(1); - } - return (rc); -} -#endif diff --git a/usr/src/cmd/avs/sdbc/sd_diag.c b/usr/src/cmd/avs/sdbc/sd_diag.c deleted file mode 100644 index 706f547226..0000000000 --- a/usr/src/cmd/avs/sdbc/sd_diag.c +++ /dev/null @@ -1,1169 +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 <version.h> SKK */ -#include <errno.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/param.h> -#include <sys/inttypes.h> -#include <stdio.h> -#include <strings.h> -#include <fcntl.h> -#include <sys/shm.h> -#include <sys/wait.h> -#include <unistd.h> -#include <nsctl.h> - -#include <sys/nsctl/sd_cache.h> -#include <sys/nsctl/sd_conf.h> - -#include <stdlib.h> -#include <thread.h> -#include <synch.h> - -#define MAXPARTS 100 /* Max disks */ -#define MAXBUF 65536 /* Max buffer size in long words */ -#define DISKLIST "disk_config" /* Default config file */ -#define DEF_SIZE 8192 /* Default buffer size */ -#define DEF_LOOP 1000 /* Loops for test */ -#define RAND_LOOPS DEF_LOOP /* # of random ios to do */ - -/* - * >>>>>>>>> USER LEVEL SD CACHE DIAGNOSTICS <<<<<<<<<< - * - * Write and read data blocks w/multiple processes - * Starts one process for each partition specified in - * the config file - */ - -int buf1[MAXBUF]; -int buf2[MAXBUF]; -char name[MAXPARTS][80]; -int pattern[MAXPARTS]; -int bufsize = DEF_SIZE; -int fba_num_bufsize; -nsc_size_t loops = DEF_LOOP; -nsc_size_t r_loops = RAND_LOOPS; -int fsize = -1; -int readercount = 3; -int Rflag = O_EXCL; -char config_file[32]; - -int -read_parts() -{ - FILE *dfile; - int partitions = 0; - int i; - - dfile = fopen(config_file, "r"); - if (dfile == NULL) { - (void) printf("cannot open file: %s\n", config_file); - perror("fopen"); - exit(errno); - } - for (i = 0; i < MAXPARTS; i++) { - if (fscanf(dfile, "%s %x", name[i], (uint_t *)&pattern[i]) == - EOF) { - break; - } else - if (name[i][0] == '#' || strchr(name[i], '/') == NULL) { - i--; - continue; - } - partitions++; - } - (void) fclose(dfile); - (void) printf("No. of partitions listed in file '%s' = %d\n\n", - config_file, partitions); - return (partitions); -} - -void -print_usage() -{ - (void) printf("Usage:\n"); - (void) printf( -"sd_diag [-R] [-b <bufsize>] [-d <datasize>] [-l <loops>] [-r <readers>]\n"); - (void) printf( -" [-f <disk_config_file>] <test#>\n"); - (void) printf(" test 1 = random read/write\n"); - (void) printf(" 2 = random read/write/verify, read after write\n"); - (void) printf(" 3 = random read/write/verify,"); - (void) printf(" all reads after all writes\n"); - (void) printf(" 4 = sequential read/write\n"); - (void) printf(" 5 = sequential write/read/verify,"); - (void) printf(" all reads after all writes\n"); - (void) printf( - " 6 = altenating top/bottom sequential read/write/verify\n"); - (void) printf(" 7 = multiple readers/1 random writer\n"); - (void) printf(" 8 = random writes\n"); - (void) printf(" 9 = sequential write of known data\n"); - (void) printf(" 10 = sequential copy of datasize disk/verify\n"); - (void) printf(" 11 = sequential read/verify test 9 data -"); - (void) printf(" then clear data with timestamp\n"); - (void) printf(" 12 = sequential read/verify test 9 data -"); - (void) printf(" no clear data\n"); - (void) printf("\n"); - (void) printf(" <bufsize> in bytes (minimum is 512 bytes)\n"); - (void) printf(" <datasize> in Mbytes per disk\n"); - (void) printf(" <loops> is count of reads/writes,\n"); - (void) printf(" loops = 0 tests entire datasize disk"); - (void) printf(" for sequential tests.\n"); - (void) printf(" loops = 0 performs %d I/Os for the random " - "tests\n", RAND_LOOPS); - (void) printf(" <readers> is count of readers for test #7 (default " - "is 3).\n"); - (void) printf(" [ defaults: bufsize = %d bytes, loops = %d,", - DEF_SIZE, DEF_LOOP); - (void) printf(" datasize = disksize ]\n"); - (void) printf("\n"); - (void) printf(" -R : do nsc_reserve(), nsc_release(0 around each " - "I/O\n"); -} - -void -parse_opts(int argc, char *argv[]) -{ - extern char *optarg; - int c; - - while ((c = getopt(argc, argv, "b:d:l:r:Rf:")) != -1) { - switch (c) { - case 'f': - /* printf("\n%s", optarg); */ - (void) strcpy(config_file, optarg); - break; - case 'b': - /* bufsize between 1*512 and 512*512 */ - bufsize = strtol(optarg, 0, 0); - if (bufsize > (MAXBUF*4)) - bufsize = MAXBUF*4; - else if (bufsize < FBA_SIZE(1)) - bufsize = FBA_SIZE(1); - break; - case 'd': - /* convert datasize from Mb's to fba */ - fsize = strtol(optarg, 0, 0) * FBA_NUM(1 << 20); - break; - case 'l': - loops = (nsc_size_t)strtoll(optarg, 0, 0); - break; - case 'r': - /* count of readers for test 7 */ - readercount = strtol(optarg, 0, 0); - break; - case 'R': - /* do reserve, release on a per io basis */ - Rflag = 0; - break; - case '?': - print_usage(); - exit(0); - } - } - bufsize &= ~FBA_MASK; /* multiple of 512 bytes for SECTMODE I/O */ - fba_num_bufsize = FBA_NUM(bufsize); - - /* set #ios for random io tests */ - if (loops != 0) - r_loops = loops; - -} - -nsc_size_t -set_part_size(char *path, nsc_fd_t *sdfd) -{ - nsc_size_t filesize; - int rc; - - rc = nsc_partsize(sdfd, &filesize); /* partsize in FBAs (512 bytes) */ - if (rc < 0 || filesize == 0) { - (void) fprintf(stderr, - "set_part_size: cannot access partition size"); - (void) fprintf(stderr, " for %s\n", path); - (void) nsc_close(sdfd); - exit(1); - } - - (void) printf("Partition %s, size:%" NSC_SZFMT " blocks\n", path, - filesize); - - if (fsize != -1 && fsize < filesize) - filesize = fsize; - filesize -= fba_num_bufsize; - if (filesize < fba_num_bufsize) { - (void) printf("ERROR: Max block size %" NSC_SZFMT "\n", - filesize); - (void) nsc_close(sdfd); - exit(0); - } - - return (filesize); -} - -int -do_sdtest1(int fd, nsc_size_t loops, nsc_size_t filesize) -{ - nsc_off_t seekpos; - nsc_size_t i; - ssize_t r; - - for (i = 0; i < loops; i++) { - seekpos = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT)); - if (r <= 0) { - perror("Test1: write"); - return (1); - } - seekpos = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT)); - if (r <= 0) { - perror("Test1: read"); - return (1); - } - } - return (0); -} - -void -gen_data(int *buffer, int size) -{ - int i; - - size /= 4; - for (i = 0; i < size; i++) - buffer[i] = rand() << 16 | rand(); -} - -int -do_sdtest2(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - nsc_off_t seekpos; - int err = 0; - ssize_t r; - nsc_size_t i; - - for (i = 0; i < loops; i++) { - seekpos = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - gen_data(buf1, bufsize); - r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT)); - if (r <= 0) { - perror("Test2: write"); - err++; - return (err); - } - r = pread(fd, buf2, bufsize, (off_t)(seekpos << SCTRSHFT)); - if (r <= 0) { - perror("Test2: read"); - err++; - return (err); - } - if (memcmp(buf1, buf2, bufsize)) { - (void) printf("Test2: Data corruption," - " fd:%s, fpos:%" PRId64 ", len:%d\n", - name[h], (int64_t)(seekpos << SCTRSHFT), - bufsize); - err++; - } - } - return (err); -} - -int -do_sdtest3(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd) -{ - nsc_off_t *seekpos; - int err = 0; - nsc_size_t i; - ssize_t r; - - seekpos = malloc(loops*sizeof (nsc_off_t)); - if (seekpos == NULL) { - perror("Test3: malloc"); - (void) nsc_close(sdfd); - exit(errno); - } - gen_data(buf1, bufsize); - - for (i = 0; i < loops; i++) { - seekpos[i] = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - seekpos[i] -= seekpos[i] % fba_num_bufsize; - r = pwrite(fd, buf1, bufsize, (off_t)(seekpos[i] << SCTRSHFT)); - if (r <= 0) { - perror("Test3: write"); - err++; - goto cleanup; - } - } - for (i = 0; i < loops; i++) { - buf2[0] = '\0'; /* clear buf to make sure something is read */ - r = pread(fd, buf2, bufsize, (off_t)(seekpos[i] << SCTRSHFT)); - if (r <= 0) { - perror("Test3: read"); - err++; - goto cleanup; - } - if (memcmp(buf1, buf2, bufsize)) { - (void) printf("Data corruption, fd:%s, fpos:%" PRId64 - ", len:%d\n", name[h], - (int64_t)(seekpos[i] << SCTRSHFT), bufsize); - err++; - } - } - -cleanup: - free(seekpos); - return (err); -} - -int -do_sdtest4(int fd, nsc_size_t loops, nsc_size_t filesize) -{ - ssize_t r; - nsc_size_t i; - - /* - * Do sequential reads/writes for loops number - * of bufsize chunks, unless loops == 0, then do - * entire disk. - * 1. sequential reads from the top down, - * 2. sequential writes from the top down, - * 3. sequential reads from the bottom up, - * 4. sequential writes from the bottom up. - */ - if ((loops > (filesize / fba_num_bufsize)) || (!loops)) - loops = filesize / fba_num_bufsize; /* entire disk */ - - for (i = 0; i < loops; i++) { - r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test4: read"); - return (1); - } - } - for (i = 0; i < loops; i++) { - r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test4: write"); - return (1); - } - } - for (i = loops - 1; i + 1 > 0; i--) { - r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test4: read"); - return (1); - } - } - for (i = loops - 1; i + 1 > 0; i--) { - r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test4: write"); - return (1); - } - } - return (0); -} - -int -do_sdtest5(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - int err = 0; - ssize_t r; - nsc_size_t i; - - /* - * Do sequential writes with verify reads for loops number - * of bufsize chunks, unless loops == 0, then do - * entire disk. - * 1. sequential writes from the top down, - * 2. sequential reads from the top down with verify, - * 3. sequential writes from the bottom up, - * 4. sequential reads from the bottom up with verify. - */ - if ((loops > (filesize / fba_num_bufsize)) || (!loops)) - loops = filesize / fba_num_bufsize; /* entire disk */ - - gen_data(buf1, bufsize); - - for (i = 0; i < loops; i++) { - r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test5: write"); - err++; - return (err); - } - } - for (i = 0; i < loops; i++) { - buf2[0] = '\0'; /* clear buf to make sure something is read */ - r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test5: read"); - err++; - return (err); - } - if (memcmp(buf1, buf2, bufsize)) { - (void) printf("Test5: Data corruption," - " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n", - name[h], i, bufsize); - err++; - } - } - - gen_data(buf1, bufsize); - - for (i = loops - 1; i + 1 > 0; i--) { - r = pwrite(fd, buf1, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test5: write"); - err++; - return (err); - } - } - for (i = loops - 1; i + 1 > 0; i--) { - buf2[0] = '\0'; /* clear buf to make sure something is read */ - r = pread(fd, buf2, bufsize, (i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test5: read"); - err++; - return (err); - } - if (memcmp(buf1, buf2, bufsize)) { - (void) printf("Test5: Data corruption," - " fd:%s, fpos:%" NSC_SZFMT ", len:%d\n", - name[h], i, bufsize); - err++; - } - } - return (err); -} - - -int -do_sdtest6(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - int err = 0; - nsc_size_t i; - ssize_t r; - nsc_size_t endloop = filesize / fba_num_bufsize; - int buf3[MAXBUF]; - int buf4[MAXBUF]; - nsc_off_t top_pos, bottom_pos; - - /* - * Do alternating top down and bottom up sequential writes - * (working towards middle) and verify with reads - * for loops number of bufsize chunks, unless loops == 0, then do - * entire disk. - */ - if ((loops > (filesize / fba_num_bufsize)) || (!loops)) - loops = filesize / fba_num_bufsize; /* entire disk */ - - for (i = 0; i < loops; i++) { - gen_data(buf1, bufsize); - bottom_pos = i*fba_num_bufsize; - r = pwrite(fd, buf1, bufsize, (off_t)(bottom_pos << SCTRSHFT)); - if (r <= 0) { - perror("Test6: write"); - err++; - return (err); - } - gen_data(buf2, bufsize); - top_pos = (endloop - i - 1)*fba_num_bufsize; - - /* Make sure we don't collide in the middle */ - - if (abs(top_pos - bottom_pos) < fba_num_bufsize) - top_pos = bottom_pos + fba_num_bufsize; - - r = pwrite(fd, buf2, bufsize, (off_t)(top_pos << SCTRSHFT)); - if (r <= 0) { - perror("Test6: write"); - err++; - return (err); - } - r = pread(fd, buf3, bufsize, (off_t)(bottom_pos << SCTRSHFT)); - if (r <= 0) { - perror("Test6: read"); - err++; - return (err); - } - if (memcmp(buf1, buf3, bufsize)) { - (void) printf("Data corruption(1), fd:%s, fpos:%" - PRId64 ", len:%d\n", name[h], - (int64_t)(bottom_pos << SCTRSHFT), bufsize); - err++; - } - r = pread(fd, buf4, bufsize, (off_t)(top_pos << SCTRSHFT)); - if (r <= 0) { - perror("Test6: read"); - return (1); - } - if (memcmp(buf2, buf4, bufsize)) { - (void) printf("Test6: Data corruption(2)," - " fd:%s, fpos:%" PRId64 ", len:%d\n", - name[h], (int64_t)(top_pos << SCTRSHFT), bufsize); - err++; - } - } - return (err); -} - -int shmid; - -#define MAXREADERS 32 - -struct shm_struct { - int writebuf[MAXBUF]; - volatile nsc_off_t writepos; - int quit; - int err; - mutex_t err_mutex; - int rd_done[MAXREADERS]; - int rd_done_mask[MAXREADERS]; -} *shm; - -#define WRITEBUF (shm->writebuf) -#define WRITEPOS (shm->writepos) - -#define QUIT (shm->quit) -#define ERR (shm->err) -#define ERRMUTEX (shm->err_mutex) -#define RD_DONE (shm->rd_done) -#define RD_DONE_MASK (shm->rd_done_mask) - -#define LOCKWRITE -#define LOCKREAD(i) - -/* Clear RD_DONE and Set WRITEPOS */ -#define FREEWRITE { \ - bzero(RD_DONE, sizeof (RD_DONE)); \ - WRITEPOS = wr_pos; } - -/* Reader i+1 marks himself as finished */ -#define FREEREAD(i) (RD_DONE[(i)] = 1) - - -int -do_sdtest7read(int fd, int h, int which) -{ - int err; - ssize_t r_rd; - nsc_off_t curr_pos; - nsc_size_t loop_cnt; - err = 0; curr_pos = 0; loop_cnt = 0; - for (;;) { - /* Already read this? */ - if (curr_pos == WRITEPOS) { - if (!QUIT) { - continue; - } else { - /* Time to go! */ - /* printf("Quitting [%d]\n", which+1); */ - break; - } - } - - /* get location to read from */ - curr_pos = WRITEPOS; - - r_rd = pread(fd, buf1, bufsize, (curr_pos << SCTRSHFT)); - loop_cnt += 1; - if (r_rd <= 0) { - FREEREAD(which); - perror("Test7: read"); - err += 1; - continue; - } - - if (memcmp(buf1, WRITEBUF, bufsize)) { - FREEREAD(which); - (void) printf("\nTest7: Data corruption, reader #%d, " - "fd:%s, \ - fpos:%" PRId64 ", len:%d\n", which + 1, name[h], - (int64_t)(curr_pos << SCTRSHFT), bufsize); - err += 1; - continue; - } - - FREEREAD(which); - } - - (void) printf( - "Partition %s, Test 7, reader #%d: %d errors %lld loops\n", - name[h], which+1, err, loop_cnt); - - if (err > 0) { - (void) mutex_lock(&ERRMUTEX); - ERR += err; - (void) mutex_unlock(&ERRMUTEX); - } - - if (err) - return (1); - else - return (0); -} - - -int -do_sdtest7write(int fd, nsc_size_t filesize, int h) -{ - int err = 0; - ssize_t r; - nsc_off_t wr_pos; - - /* Wait for readers to finish */ - while (memcmp(RD_DONE, RD_DONE_MASK, readercount*sizeof (int))) - ; - - gen_data(WRITEBUF, bufsize); - wr_pos = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - r = pwrite(fd, WRITEBUF, bufsize, (off_t)(wr_pos << SCTRSHFT)); - if (r <= 0) { - FREEWRITE; - perror("Test7: write"); - return (1); - } - FREEWRITE; - - /* verify write */ - r = pread(fd, buf1, bufsize, (off_t)(wr_pos << SCTRSHFT)); - if (r <= 0) { - perror("Test7: writer: read"); - return (1); - } - - - if (memcmp(buf1, WRITEBUF, bufsize)) { - (void) printf("\nTest7: Data corruption in writer," - " fd:%s, fpos:%" PRId64 ", len:%d\n", - name[h], (int64_t)(wr_pos << SCTRSHFT), bufsize); - err++; - } - - - return (err); -} - -void -init_shm() -{ - int i; - - /* Clear out everything */ - bzero(shm, sizeof (struct shm_struct)); - - (void) mutex_init(&ERRMUTEX, USYNC_PROCESS, NULL); - - /* Set up mask (constant) to test reader doneness */ - for (i = 0; i < readercount; i++) - RD_DONE_MASK[i] = 1; - - /* Mark all readers done - so writer can start */ - for (i = 0; i < readercount; i++) - RD_DONE[i] = 1; -} - -int -do_sdtest7(int fd, nsc_size_t loops, nsc_size_t filesize, int h, nsc_fd_t *sdfd) -{ - int r, i, err; - nsc_size_t j; - - if ((shmid = shmget(IPC_PRIVATE, sizeof (struct shm_struct), - IPC_CREAT | 0666)) < 0) { - perror("shmget error: "); - (void) nsc_close(sdfd); - exit(1); - } - - shm = (struct shm_struct *)shmat(shmid, NULL, 0); - if (shm == (struct shm_struct *)-1) { - perror("shmat error: "); - (void) nsc_close(sdfd); - exit(1); /* cleanup exits */ - } - - init_shm(); - - /* Start Readers */ - for (i = 0; i < readercount; i++) { - r = fork(); - if (r == 0) { /* child */ - (void) do_sdtest7read(fd, h, i); - (void) nsc_close(sdfd); - exit(0); - } else - continue; - } - - /* Start Writer */ - srand(getpid()); err = 0; - for (j = 0; j < loops; j++) { - err += do_sdtest7write(fd, filesize, h); - } - QUIT = 1; - - (void) printf("\n\nPartition %s, Test 7, writer: %d errors\n", - name[h], err); - - for (i = 0; i < readercount; i++) - (void) wait(0); - - /* No lock needed here - everybody's finished */ - err += ERR; - - (void) mutex_destroy(&ERRMUTEX); - (void) shmctl(shmid, IPC_RMID, 0); - return (err); -} - -int -do_sdtest8(int fd, nsc_size_t loops, nsc_size_t filesize) -{ - nsc_off_t seekpos; - int err = 0; - ssize_t r; - nsc_size_t i; - - for (i = 0; i < loops; i++) { - seekpos = ( -#ifdef NSC_MULTI_TERABYTE - ((nsc_off_t)rand() << 48) | ((nsc_off_t)rand() << 32) | -#endif - (rand() << 16) | rand()) % filesize; - gen_data(buf1, bufsize); - r = pwrite(fd, buf1, bufsize, (off_t)(seekpos << SCTRSHFT)); - if (r <= 0) { - perror("Test8: write"); - err++; - return (err); - } - } - return (err); -} - -void -gen_data_known(int *buffer, int size, int data) -{ - int i; - - size /= 4; - for (i = 0; i < size; i++) - buffer[i] = data; -} - -int -do_sdtest9(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - int err = 0; - ssize_t r; - nsc_off_t fba_offset; - nsc_size_t i, wrapval; - - /* - * Test 9 will write a given pattern over and over Test 11 or - * Test 12 will read same pattern. - */ - /* Large loop value that would cause write overflow will wrap */ - - gen_data_known(buf1, bufsize, pattern[h]); - - wrapval = filesize / fba_num_bufsize; - - if (loops == 0) - loops = wrapval; /* entire disk */ - - for (i = 0; i < loops; i++) { - fba_offset = i % wrapval; - r = pwrite(fd, buf1, bufsize, - (off_t)(fba_offset * fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test9: write"); - err++; - return (err); - } - } - return (err); -} - -int -do_sdtest10(int fd1, int fd2, nsc_size_t loops, nsc_size_t filesize1, - nsc_size_t filesize2, int h) -{ - nsc_size_t filesize; - int err = 0; - nsc_size_t i; - ssize_t r; - - /* - * Do sequential copy of disk1 to disk2 for loops number - * of bufsize chunks, unless loops == 0, then copy size of - * the smaller disk. - * Go back and verify that the two disks are identical. - */ - - filesize = (filesize1 < filesize2) ? filesize1 : filesize2; - if ((loops > (filesize / fba_num_bufsize)) || (!loops)) - loops = filesize / fba_num_bufsize; - - /* copy disk1 to to disk2 */ - for (i = 0; i < loops; i++) { - r = pread(fd1, buf1, bufsize, - (off_t)(i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test10: read"); - return (1); - } - r = pwrite(fd2, buf1, bufsize, - (off_t)(i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test10: write"); - return (1); - } - } - - /* verify disks are identical */ - for (i = 0; i < loops; i++) { - buf1[0] = '\0'; /* clear buf to make sure something is read */ - r = pread(fd1, buf1, bufsize, - (off_t)(i * fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test10: read"); - return (1); - } - buf2[0] = 'x'; /* make sure something is read */ - r = pread(fd2, buf2, bufsize, - (off_t)(i * fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test10: read"); - return (1); - } - if (memcmp(buf1, buf2, bufsize)) { - (void) printf("Test10: Data corruption," - " fd1:%s, fd2:%s fpos:%" NSC_SZFMT ", len:%d\n", - name[2*h], name[2*h+1], i, bufsize); - err++; - } - } - return (err); -} - -int -buffcmp(int *b1, int *b2, int size) -{ - int i; - - for (i = 0; i < size/4; i++) { - if (b1[i] != b2[i]) { - (void) printf("Word %d does not match b1=0x%x, " - "b2=0x%x\n", i, b1[i], b2[i]); - return (1); - } - } - return (0); - -} - -int -do_sdtest11(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - int err = 0; - nsc_size_t i; - ssize_t r; - int buf3[MAXBUF]; - int buf4[MAXBUF]; - int timestamp; - time_t clock; - struct tm *tm; - - - /* - * Test 9 will write a given pattern over and over Test 11 will read - * same pattern and clear with timestamp data (MM:SS). - */ - - clock = time(NULL); - tm = localtime(&clock); - (void) ascftime((char *)×tamp, "%M""%S", tm); - - gen_data_known(buf1, bufsize, pattern[h]); - gen_data_known(buf4, bufsize, timestamp); - if ((loops > filesize / fba_num_bufsize) || (!loops)) - loops = filesize / fba_num_bufsize; /* entire disk */ - - for (i = 0; i < loops; i++) { - r = pread(fd, buf3, bufsize, - (off_t)(i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test11: read"); - err++; - return (err); - } - if (buffcmp(buf1, buf3, bufsize)) { - (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT - ", len:%d\n", name[h], i, bufsize); - err++; - return (err); - } - r = pwrite(fd, buf4, bufsize, - (off_t)(i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test11: write"); - err++; - return (err); - } - } - return (err); -} - -int -do_sdtest12(int fd, nsc_size_t loops, nsc_size_t filesize, int h) -{ - int err = 0; - nsc_size_t i; - ssize_t r; - int buf3[MAXBUF]; - - /* - * Test 9 will write a given pattern over and over Test 12 will read - * same pattern - */ - - gen_data_known(buf1, bufsize, pattern[h]); - if ((loops > filesize / fba_num_bufsize) || (!loops)) - loops = filesize / fba_num_bufsize; /* entire disk */ - - for (i = 0; i < loops; i++) { - r = pread(fd, buf3, bufsize, - (off_t)(i*fba_num_bufsize) << SCTRSHFT); - if (r <= 0) { - perror("Test12: read"); - err++; - return (err); - } - if (buffcmp(buf1, buf3, bufsize)) { - (void) printf("Data corr, fd:%s, fpos:%" NSC_SZFMT - ", len:%d\n", name[h], i, bufsize); - err++; - return (err); - } - } - return (err); -} - -#ifdef lint -int -sd_diag_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - int procs; - nsc_size_t filesize, filesize2; - int fd, fd2, r, id, h, i; - nsc_fd_t *sdfd, *sdfd2; - - if (argc < 2) { - print_usage(); - exit(0); - } - (void) strcpy(config_file, DISKLIST); - parse_opts(argc, argv); - - _nsc_nocheck(); - if ((procs = read_parts()) == 0) - exit(0); - - id = strtol(argv[optind], 0, 0); - if (id == 10) { - /* - * each process gets 2 disks and copies disk1 to disk2, - * then goes back and verifies that the two disks are - * identical. - */ - if (procs < 2) { - (void) printf("%s requires having at least 2 disks for test " - "#10.\n", config_file); - exit(0); - } - - for (h = 0; h < procs/2; h++) { - r = fork(); - if (r == 0) { - srand(getpid()); - - - if (!(sdfd = nsc_open(name[2*h], NSC_CACHE, - O_RDWR | Rflag))) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[2*h]); - exit(1); - } - fd = nsc_fileno(sdfd); - if (fd == -1) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[2*h]); - (void) nsc_close(sdfd); - exit(1); - } - filesize = set_part_size(name[2*h], sdfd); - if (!(sdfd2 = nsc_open(name[2*h+1], NSC_CACHE, - O_RDWR | Rflag))) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[2*h+1]); - exit(1); - } - fd2 = nsc_fileno(sdfd2); - if (fd2 == -1) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[2*h+1]); - (void) nsc_close(sdfd2); - exit(1); - } - filesize2 = set_part_size(name[2*h+1], sdfd2); - (void) sleep(2); - r = do_sdtest10(fd, fd2, loops, filesize, filesize2, h); - - (void) printf("Partitions %s and %s, Test %d," - " Completed %d errors\n", - name[2*h], name[2*h+1], id, r); - (void) nsc_close(sdfd); - (void) nsc_close(sdfd2); - exit(0); - } else if (r == -1) { - perror("fork"); - break; - } else - continue; - } /* for */ - for (i = 0; i < h; i++) - (void) wait(0); - } else { - - for (h = 0; h < procs; h++) { - r = fork(); - if (r == 0) { - srand(getpid()); - - id = strtol(argv[optind], 0, 0); - if (!(sdfd = nsc_open(name[h], NSC_CACHE, - O_RDWR | Rflag))) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[h]); - exit(1); - } - fd = nsc_fileno(sdfd); - - if (fd == -1) { - (void) fprintf(stderr, - "sd_diag: Error opening %s\n", name[h]); - (void) nsc_close(sdfd); - exit(1); - } - filesize = set_part_size(name[h], sdfd); - - (void) sleep(2); - - - switch (id) { - case 1: - r = do_sdtest1(fd, r_loops, filesize); - break; - case 2: - r = do_sdtest2(fd, r_loops, filesize, h); - break; - case 3: - r = do_sdtest3(fd, r_loops, filesize, h, sdfd); - break; - case 4: - r = do_sdtest4(fd, loops, filesize); - break; - case 5: - r = do_sdtest5(fd, loops, filesize, h); - break; - case 6: - r = do_sdtest6(fd, loops, filesize, h); - break; - case 7: - r = do_sdtest7(fd, r_loops, filesize, h, sdfd); - break; - case 8: - r = do_sdtest8(fd, r_loops, filesize); - break; - case 9: - r = do_sdtest9(fd, loops, filesize, h); - break; - case 11: - r = do_sdtest11(fd, loops, filesize, h); - break; - case 12: - r = do_sdtest12(fd, loops, filesize, h); - break; - default: - break; - } - - (void) printf("Partition %s, Test %d, Completed %d " - "errors\n", name[h], id, r); - (void) nsc_close(sdfd); - exit(r ? 1 : 0); - } else if (r == -1) { - perror("fork"); - break; - } else - continue; - } - for (i = 0; i < h; i++) - (void) wait(0); - } - - return (0); -} diff --git a/usr/src/cmd/avs/sdbc/sd_stats.c b/usr/src/cmd/avs/sdbc/sd_stats.c deleted file mode 100644 index 211ce6c1d6..0000000000 --- a/usr/src/cmd/avs/sdbc/sd_stats.c +++ /dev/null @@ -1,594 +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 <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <strings.h> -#include <curses.h> -#include <signal.h> -#include <fcntl.h> -#include <locale.h> - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/nsctl/sdbc_ioctl.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/nsctl/sd_bcache.h> -#include <sys/nsctl/sd_conf.h> - -extern void total_display(void); -extern void display_cache(void); -extern void wrefresh_file(WINDOW *, int); -extern int is_dirty(void); -extern int dual_stats(void); -void checkbuf(int); -void setup_ranges(char *); -void prheading(int); -extern int zero_nic(void); - -#ifdef m88k -#define USEC_INIT() usec_ptr = (unsigned int *)timer_init() -#define USEC_READ() (*usec_ptr) -#else /* !m88k */ -#define USEC_INIT() USEC_START() -#include <sys/time.h> -static struct timeval Usec_time; -static int Usec_started = 0; - -extern int higher(int); -extern int is_dirty(); -extern int dual_stats(); -extern void total_display(); -extern void display_cache(); -extern void wrefresh_file(WINDOW *, int); -void setup_ranges(char *); - -void prheading(int); -void checkbuf(int); -void quit(int); -void leave(int); -#pragma does_not_return(quit, leave) - -int sdbc_max_devices = 0; - -static void -USEC_START() -{ - if (!Usec_started) { - (void) gettimeofday(&Usec_time, NULL); - Usec_started = 1; - } -} - -static unsigned int -USEC_READ() -{ - struct timeval tv; - if (!Usec_started) - USEC_START(); - - (void) gettimeofday(&tv, NULL); - return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000 - + (tv.tv_usec - Usec_time.tv_usec)); -} -#endif /* m88k */ - -int rev_flag = 0; /* Reverse video flag */ -int bold_flg = 0; /* Bold flag */ -int under_flg = 0; /* Underline flag */ -int errflg = 0; /* Error flag */ -int node_sw = 0; /* Per node switch */ -int toggle_total_sw = 0; -int mirror_sw = 0; /* Dual copy switch */ - -int kmemfd; -int delay = 1; /* Display delay (seconds) */ - -time_t *usec_ptr; -time_t currtime = 0; -int lasttime = 0; -int Elapsed_Time = 0; - -static char *range; -static int had_r_option = 0; -int logfd = -1; /* screen output logging */ -extern int range_num; -extern int screen; -extern int dual_screen; -int *on_off; -int *dual_on_off; -int *updates_prev; -double *rate_prev; -int *samples; -_sd_stats_t *cs_cur; -_sd_stats_t *cs_prev; -_sd_stats_t *cs_persec; - -typedef struct { - int lb, ub; -} range_t; - -extern range_t ranges[]; - -#ifdef lint -int -sd_stats_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - spcs_s_info_t ustats; - struct timeval tout; - fd_set readfds; - char *errmessage, *ch; - int c, period, prev; - int count = 0, dflag = 0; - int fd = fileno(stdin); - - errmessage = NULL; - - if (strcmp(argv[0], "sd_stats") != 0) - errmessage = getenv("SD_STATS_USAGE"); - - if (errmessage == NULL) - errmessage = gettext("Usage: sd_stats [-Mz] " - "[-d delay_time] [-l logfile] [-r range]"); - - if (SDBC_IOCTL(SDBC_MAXFILES, &sdbc_max_devices, - 0, 0, 0, 0, &ustats) == SPCS_S_ERROR) { - if (ustats) { /* if SPCS_S_ERROR */ - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - (void) fprintf(stderr, gettext("cannot get maxfiles\n")); - exit(1); - } - on_off = calloc(sdbc_max_devices, sizeof (int)); - dual_on_off = calloc(sdbc_max_devices, sizeof (int)); - updates_prev = calloc(sdbc_max_devices, sizeof (int)); - samples = calloc(sdbc_max_devices, sizeof (int)); - rate_prev = calloc(sdbc_max_devices, sizeof (double)); - cs_cur = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - cs_prev = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - cs_persec = malloc(sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - range = malloc(100); - - if (!on_off || !dual_on_off || !updates_prev || !samples || - !rate_prev || !cs_cur || !cs_prev || !cs_persec || !range) { - (void) fprintf(stderr, gettext("no free memory\n")); - exit(1); - } - - *range = '\0'; - - while ((c = getopt(argc, argv, "DMzd:l:r:h")) != EOF) { - - prev = c; - switch (c) { - - case 'd': - delay = atoi(optarg); - ch = optarg; - while (*ch != '\0') { - if (!isdigit(*ch)) - errflg++; - ch++; - } - break; - - case 'l': - logfd = open(optarg, O_CREAT|O_WRONLY|O_TRUNC, 0644); - break; - - case 'r': - ch = optarg; - while (*ch != '\0') { - if ((!isdigit(*ch)) && (*ch != ',') && - (*ch != ':')) - errflg++; - ch++; - } - if (errflg) - break; - - range = realloc((char *)range, - (strlen(range) + strlen(optarg) + 1) - * sizeof (char)); - - if (had_r_option) - (void) strcat(range, ","); - (void) strcat(range, optarg); - had_r_option = 1; - break; - - case 'z': - if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0, - &ustats) == SPCS_S_ERROR) { - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - } - - break; - - case 'D': - dflag = 1; - break; - - case 'M': - mirror_sw = 1; - break; - - case 'h': - case '?': - default : - errflg++; - break; - } - } - - if (errflg) { - (void) fprintf(stderr, "%s\n", errmessage); - exit(1); - } else if (!prev) { - if (argc > 1) { - (void) fprintf(stderr, "%s\n", errmessage); - exit(1); - } - } - - if (dflag) { - exit(is_dirty()); - } - - - /* - * A few curses routines to setup screen and tty interface - */ - (void) initscr(); - (void) cbreak(); - (void) noecho(); - (void) nonl(); - (void) erase(); - (void) clear(); - (void) refresh(); - - setup_ranges(range); - - /* - * Set signal handle - */ - (void) sigset(SIGPIPE, leave); - (void) sigset(SIGINT, leave); - (void) sigset(SIGQUIT, leave); - (void) signal(SIGFPE, leave); - (void) signal(SIGSEGV, leave); - - USEC_INIT(); - currtime = USEC_READ(); - - /* - * Wait one second before reading the new values - */ - (void) sleep(1); - - /*CONSTCOND*/ - while (1) { - - lasttime = currtime; - currtime = USEC_READ(); - - /* - * If less that 1 second, force it to one second - */ - if ((period = (currtime - lasttime) / 1000000) <= 0) - period = 1; - - /* - * Calculate new per/period values for statistics - */ - Elapsed_Time += period; - - /* - * Display new statistics - */ - prheading(++count); - - if (mirror_sw) { - if (dual_stats() < 0) - mirror_sw = 0; - } else if (toggle_total_sw) - total_display(); - else - display_cache(); - - (void) move(0, 0); - (void) refresh(); - if (logfd > -1) wrefresh_file(stdscr, logfd); - - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - tout.tv_sec = delay; - for (;;) { - tout.tv_usec = 0; - if (select(fd + 1, &readfds, (fd_set *)0, (fd_set *)0, - &tout) <= 0) - break; - if ((c = getch()) == EOF) { - (void) sleep(delay); - break; - } - checkbuf(c); - tout.tv_sec = 0; - } - (void) erase(); - } -#pragma error_messages(off, E_STATEMENT_NOT_REACHED) - return (0); -#pragma error_messages(default, E_STATEMENT_NOT_REACHED) -} - -void -checkbuf(int c) -{ - spcs_s_info_t ustats; - - switch (c) { - case 'b' : /* ctrl b or b -- scroll backward */ - case 2 : - { - if (mirror_sw == 1) { - if (dual_screen > 0) - dual_screen--; - break; - } - if (screen > 0) - screen--; - break; - } - - case 'f' : /* ctrl f or f -- scroll forward */ - case 6 : - { - if (mirror_sw == 1) { - dual_screen++; - break; - } - screen++; - break; - } - - case 't': - case 'T': - if (mirror_sw == 1) - mirror_sw = 0; - - toggle_total_sw ^= 1; - break; - - case '-': - case KEY_DOWN: - if (delay > 1) { - --delay; - } else { - (void) beep(); - } - break; - - case '+': - case KEY_UP: - delay++; - break; - - case 'C': - case 0xc: - (void) clearok(stdscr, TRUE); - break; - - case 'B': - if (bold_flg) { - bold_flg = 0; - (void) attroff(A_BOLD); - } else { - bold_flg = 1; - (void) attron(A_BOLD); - } - break; - - case 'R': - if (rev_flag) { - rev_flag = 0; - (void) attroff(A_REVERSE); - } else { - rev_flag = 1; - (void) attron(A_REVERSE); - } - break; - - case 'z': - if (SDBC_IOCTL(SDBC_ZAP_STATS, 0, 0, 0, 0, 0, - &ustats) == SPCS_S_ERROR) { - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - } - break; - - case 'm': - case 'M': - mirror_sw = mirror_sw ? 0 : 1; - (void) clear(); - break; - } -} - -void -prheading(int count) -{ - time_t tim; - - /* - * Print sample count in upper left corner - */ - (void) mvprintw(0, 0, "SAMPLE %-8d", count); - - /* - * Get time and print it in upper right corner - */ - tim = time((time_t *)0); - (void) mvprintw(0, 79 - 10, "%-8.8s\n", &(ctime(&tim)[11])); -} - -/*ARGSUSED*/ -void -leave(int status) -{ - (void) sigignore(SIGPIPE); - (void) sigignore(SIGALRM); - /* clear(); */ - (void) move(LINES, 0); - (void) refresh(); - if (logfd > -1) wrefresh_file(stdscr, logfd); - quit(0); -} - -void -quit(int status) -{ - (void) resetterm(); - (void) endwin(); - exit(status); -} - -void -setup_ranges(char *range) -{ - int ndx; - char chr1; - char prev_chr = '\0'; - int got_colon = 0; - int after_got_colon = 0; - int got_comma = 0; - int after_got_comma = 0; - int number = 0; - int prev_num = 0; - - if (range == NULL || (strlen(range) == 0)) { - ranges[range_num].lb = 0; - ranges[range_num].ub = sdbc_max_devices - 1; - return; - } else { - ndx = 0; - got_comma = 0; - got_colon = 0; - while ((chr1 = (range[ndx++])) != '\0') { - switch (chr1) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - number = number*10 + (chr1 - '0'); - break; - case ':': - got_colon = 1; - break; - case ',': - got_comma = 1; - break; - default: /* ignore any unknown characters */ - break; - } /* switch */ - if (got_comma && after_got_colon) { - after_got_colon = 0; - got_comma = 0; - if (number >= sdbc_max_devices) - number = sdbc_max_devices - 1; - ranges[range_num].lb = prev_num; - ranges[range_num].ub = number; - if (range_num == 99) break; - range_num++; - number = 0; - } else if (got_colon && after_got_comma) { - got_colon = 0; - after_got_colon = 1; - after_got_comma = 0; - if (number >= sdbc_max_devices) - number = sdbc_max_devices - 1; - prev_num = number; - number = 0; - } else if (got_colon) { - got_colon = 0; - after_got_colon = 1; - if ((prev_chr != '\0') && (prev_chr != ':')) { - if (number >= sdbc_max_devices) - number = sdbc_max_devices - 1; - prev_num = number; - number = 0; - } - } else if (got_comma) { - got_comma = 0; - after_got_comma = 1; - after_got_colon = 0; - if (number >= sdbc_max_devices) - number = sdbc_max_devices -1; - if ((prev_chr != '\0') && (prev_chr != ',')) { - ranges[range_num].lb = number; - ranges[range_num].ub = number; - if (range_num == 99) break; - range_num++; - } - number = 0; - } /* if */ - prev_chr = chr1; - } /* while */ - if (number >= sdbc_max_devices) - number = sdbc_max_devices - 1; - if (after_got_colon) { - ranges[range_num].lb = prev_num; - ranges[range_num].ub = number; - } else { - if ((after_got_comma) && (prev_chr == ',')) - range_num--; - else { - ranges[range_num].lb = number; - ranges[range_num].ub = number; - } - } - } -} diff --git a/usr/src/cmd/avs/sdbc/sd_trace.c b/usr/src/cmd/avs/sdbc/sd_trace.c deleted file mode 100644 index 9b237ea057..0000000000 --- a/usr/src/cmd/avs/sdbc/sd_trace.c +++ /dev/null @@ -1,961 +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 <errno.h> -#include <stdio.h> -#include <unistd.h> -#include <strings.h> -#include <stdlib.h> - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/nsctl/sdbc_ioctl.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/sd_bcache.h> -#include <sys/nsctl/sd_conf.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_bitmap.h> -#include <sys/unistat/spcs_s_u.h> -#include <curses.h> - -static rdc_status_t *rdc_status; -static rdc_u_info_t *rdc_info; -static int rdc_maxsets; -static int rdc_enabled_sets; - -static unsigned prev_time, delta_time; -#ifdef m88k -extern unsigned *usec_ptr; -#endif -static int bright = 0; - -extern int sdbc_max_devices; - -extern _sd_stats_t *cs_cur; -extern _sd_stats_t *cs_prev; -extern _sd_stats_t *cs_persec; - -extern int *on_off; -extern int *dual_on_off; -extern int *updates_prev; -extern double *rate_prev; -extern int *samples; - -int range_num = 0; -int screen = 0; -int dual_screen = 0; -static int rnum = 0; - -typedef struct { - int lb, ub; -} range_t; -range_t ranges[100]; - -extern int range_first(); -extern int range_next(int); -extern int range_last(); - -static int dual_initted = 0; -static char status[11][30]; - -unsigned dc_delta_time, dc_prev_time; - -#ifdef m88k -#define USEC_INIT() usec_ptr = (unsigned int *)timer_init() -#define USEC_READ() (*usec_ptr) -#else /* !m88k */ -#define USEC_INIT() USEC_START() -#include <sys/time.h> -static struct timeval Usec_time; -static int Usec_started = 0; - -void total_display(void); -void disp_stats(void); -void do_calc(void); -void init_dual(void); -void calc_time(void); -void calc_completion(int, int, int); -void disp_total_stats(void); -void display_cache(void); - -#define DISPLEN 16 - -static void -USEC_START(void) -{ - if (!Usec_started) { - (void) gettimeofday(&Usec_time, NULL); - Usec_started = 1; - } -} - -static unsigned int -USEC_READ() -{ - struct timeval tv; - if (!Usec_started) - USEC_START(); - - (void) gettimeofday(&tv, NULL); - return (unsigned)((tv.tv_sec - Usec_time.tv_sec) * 1000000 + - (tv.tv_usec - Usec_time.tv_usec)); -} -#endif /* m88k */ - -#define SAMPLE_RATE 5 - -/* - * refresh curses window to file - */ -void -wrefresh_file(WINDOW *win, int fd) -{ - char buf[8192], c, *cp = buf, *line, *blank, *empty; - int x, y; - - empty = NULL; /* cull trailing empty lines */ - for (y = 0; y < win->_maxy; y++) { - line = cp; - blank = NULL; /* cull trailing blanks */ - for (x = 0; x < win->_maxx; x++) { - c = (win->_y[y][x]) & A_CHARTEXT; - if (c != ' ') - blank = NULL; - else if (blank == NULL) - blank = cp; - *cp++ = c; - } - if (blank) - cp = blank; - if (line != cp) - empty = NULL; - else if (empty == NULL) - empty = cp + 1; - *cp++ = '\n'; - } - if (empty) - cp = empty; - *cp++ = '\f'; *cp++ = '\n'; *cp = '\0'; - /* cp is eliminated by short _maxy and _maxx, it won't overflow */ - /* LINTED, cp - buf won't be > INT32_MAX */ - (void) write(fd, buf, cp - buf); -} - - -int -higher(int high) -{ - int i; - - for (i = high + 1; i <= sdbc_max_devices; i++) { - if (cs_cur->st_shared[i].sh_alloc) - return (i); - } - return (0); -} - -int -is_dirty() -{ - int i, dirty = 0; - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, - &ustats) == SPCS_S_ERROR) { - perror("Could not get stats from kernel"); - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - return (-errno); - } - if (cs_cur->st_cachesize == 0) - return (0); - - for (i = 0; i < cs_cur->st_count; i++) { - if (cs_cur->st_shared[i].sh_alloc) - dirty += cs_cur->st_shared[i].sh_numdirty; - } - - return (dirty != 0); -} - -void -display_cache(void) -{ - static int first = 1; - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) == - SPCS_S_ERROR) { - perror("sd_stats"); - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - } - - do_calc(); - if (first) { - prev_time = USEC_READ(); - first = 0; - } else - disp_stats(); -} - -void -total_display(void) -{ - spcs_s_info_t ustats; - - if (SDBC_IOCTL(SDBC_STATS, cs_cur, 0, 0, 0, 0, &ustats) == - SPCS_S_ERROR) { - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - perror("sd_stats"); - } - disp_total_stats(); -} - - -int -range_first() -{ - rnum = 0; - return (ranges[rnum].lb); -} - -int -range_next(int cd) -{ - if (ranges[rnum].ub > cd) - return (cd + 1); - if (range_num > rnum) - rnum++; - else - return (cd + 1); - return (ranges[rnum].lb); -} - -int -range_last() { - return (ranges[range_num].ub); -} - - -void -set_dual_on_off() -{ - int i, j, ct = 0, newct = 0; - - for (i = range_first(); i < rdc_enabled_sets && i <= range_last(); - i = range_next(i)) { - if (rdc_info[i].flags & RDC_ENABLED) { - ct++; - if (ct > dual_screen * ((LINES - 9) / 2)) - break; - } - } - if (((i >= rdc_enabled_sets) || - (i > range_last())) && (dual_screen > 0)) { - dual_screen--; - set_dual_on_off(); - } else { - bzero(dual_on_off, sdbc_max_devices * sizeof (int)); - for (j = i; j < rdc_enabled_sets && j <= range_last(); - j = range_next(j)) { - if (rdc_info[j].flags & RDC_ENABLED) { - newct++; - if (newct <= (LINES - 9) / 2) { - dual_on_off[j] = 1; - } else - break; - } - } - } -} - - -void -set_on_off() -{ - int i, j, ct = 0, newct = 0; - - for (i = range_first(); i <= range_last(); i = range_next(i)) { - if (cs_cur->st_shared[i].sh_alloc) { - ct++; - if (ct > screen*((LINES - 9) / 2)) - break; - } - } - if ((i > range_last()) && (screen > 0)) { - screen--; - set_on_off(); - } else { - bzero(on_off, sdbc_max_devices * sizeof (int)); - for (j = i; j <= range_last(); j = range_next(j)) { - if (cs_cur->st_shared[j].sh_alloc) { - newct++; - if (newct <= (LINES - 9) / 2) - on_off[j] = 1; - else - break; - } - } - } -} - -void -disp_stats(void) -{ - double read_s, write_s, access_s, readp, writep; - double rmiss_s, wmiss_s; - double elapsed = delta_time / 1000000.0; - double kbps = elapsed * 1024.0; /* for Kbytes per second */ - int rtotal, wtotal, i, j; - double throughput = 0.0, rthroughput = 0.0; - double creads = 0.0, cwrites = 0.0; - char status_bit, down = 0; - int len; - char fn[19]; - - if (delta_time != 0) { - read_s = cs_persec->st_rdhits / elapsed; - write_s = cs_persec->st_wrhits / elapsed; - rmiss_s = cs_persec->st_rdmiss / elapsed; - wmiss_s = cs_persec->st_wrmiss / elapsed; - access_s = (cs_persec->st_wrhits + cs_persec->st_rdhits + - cs_persec->st_rdmiss + cs_persec->st_wrmiss) / elapsed; - } else - read_s = write_s = access_s = 0.0; - - rtotal = cs_persec->st_rdhits + cs_persec->st_rdmiss; - wtotal = cs_persec->st_wrhits + cs_persec->st_wrmiss; - if (rtotal != 0) - readp = cs_persec->st_rdhits / (double)rtotal; - else - readp = 0.0; - - if (wtotal != 0) { - writep = cs_persec->st_wrhits / (double)wtotal; - } else - writep = 0.0; - - set_on_off(); - if (cs_cur->st_cachesize == 0) - (void) mvprintw(0, 20, "****** Storage Cache Disabled ******"); - else - (void) mvprintw(0, 20, "****** Storage Cache ******"); - (void) mvprintw(2, 26, "disk_io cache write_blocks"); - (void) attron(A_UNDERLINE); - (void) mvprintw(3, 1, " cd cached_partition reads writes reads writes" - " dirty todisk failed"); - (void) attroff(A_UNDERLINE); - for (i = 0, j = 0; j < cs_cur->st_count; i++) { - if (i >= sdbc_max_devices) - break; - if (cs_cur->st_shared[i].sh_alloc) { - cs_persec->st_shared[i].sh_disk_write /= kbps; - cs_persec->st_shared[i].sh_disk_read /= kbps; - cs_persec->st_shared[i].sh_cache_write /= kbps; - cs_persec->st_shared[i].sh_cache_read /= kbps; - rthroughput += cs_persec->st_shared[i].sh_disk_read; - throughput += cs_persec->st_shared[i].sh_disk_write; - creads += cs_persec->st_shared[i].sh_cache_read; - cwrites += cs_persec->st_shared[i].sh_cache_write; - if (!down) - down = cs_cur->st_shared[i].sh_failed; - if (cs_cur->st_shared[i].sh_failed && bright) { - status_bit = '*'; - } else - status_bit = ' '; - if ((len = strlen(cs_cur->st_shared[i].sh_filename)) - > 15) { - (void) strcpy(fn, "..."); - (void) strcat(fn, - cs_cur->st_shared[i].sh_filename + - len - 12); - } else - (void) strcpy(fn, - cs_cur->st_shared[i].sh_filename); - if (on_off[i]) { - (void) mvprintw(4 + j, 1, - "%3d %-15s%c %6d %6d %6d %6d %6d %6d %6d", - cs_cur->st_shared[i].sh_cd, - fn, - status_bit, - cs_persec->st_shared[i].sh_disk_read, - cs_persec->st_shared[i].sh_disk_write, - cs_persec->st_shared[i].sh_cache_read, - cs_persec->st_shared[i].sh_cache_write, - cs_cur->st_shared[i].sh_numdirty, - cs_cur->st_shared[i].sh_numio, - cs_cur->st_shared[i].sh_numfail); - j++; - } - } - } - bright = !bright; - - (void) mvprintw(4 + j, 22, "------ ------ ------ ------"); - (void) mvprintw(5 + j, 6, " Kbytes/s total:%6d %6d %6d %6d", - (int)rthroughput, (int)throughput, - (int)creads, (int)cwrites); - (void) mvprintw(7 + j, 1, "accesses/s"); - (void) mvprintw(7 + j, 15, "read/s write/s %%readh %%writeh"); - - (void) attron(A_UNDERLINE); - (void) mvprintw(8 + j, 1, " "); - (void) mvprintw(8 + j, 13, - " "); - (void) mvprintw(8 + j, 13, "(misses/s) (misses/s)"); - (void) attroff(A_UNDERLINE); - - (void) mvprintw(9 + j, 0, "%10.2lf %7.2f %7.2f %6.1f %6.1f", - access_s, read_s, write_s, readp * 100.0, writep * 100.0); - (void) mvprintw(10 + j, 0, " (%7.2f ) (%7.2f )\n\n", - rmiss_s, wmiss_s); - - if (down) - (void) mvprintw(20 + j, 1, "* -- disk off-line"); -} - -void -do_calc(void) -{ - int i, j; - - delta_time = USEC_READ() - prev_time; - - cs_persec->st_rdhits = cs_cur->st_rdhits - cs_prev->st_rdhits; - cs_persec->st_rdmiss = cs_cur->st_rdmiss - cs_prev->st_rdmiss; - cs_persec->st_wrhits = cs_cur->st_wrhits - cs_prev->st_wrhits; - cs_persec->st_wrmiss = cs_cur->st_wrmiss - cs_prev->st_wrmiss; - - for (i = 0, j = 0; j < cs_cur->st_count; i++) { - if (i >= sdbc_max_devices) - break; - if (cs_cur->st_shared[i].sh_alloc) { - cs_persec->st_shared[i].sh_disk_write = - FBA_SIZE(cs_cur->st_shared[i].sh_disk_write - - cs_prev->st_shared[i].sh_disk_write); - cs_persec->st_shared[i].sh_disk_read = - FBA_SIZE(cs_cur->st_shared[i].sh_disk_read - - cs_prev->st_shared[i].sh_disk_read); - cs_persec->st_shared[i].sh_cache_read = - FBA_SIZE(cs_cur->st_shared[i].sh_cache_read - - cs_prev->st_shared[i].sh_cache_read); - cs_persec->st_shared[i].sh_cache_write = - FBA_SIZE(cs_cur->st_shared[i].sh_cache_write - - cs_prev->st_shared[i].sh_cache_write); - j++; - } - } - (void) memcpy((char *) cs_prev, (char *) cs_cur, sizeof (_sd_stats_t) + - (sdbc_max_devices - 1) * sizeof (_sd_shared_t)); - prev_time = USEC_READ(); -} - - -void -init_dual(void) -{ -#define IND_ENABLED 0 -#define IND_RESYNC 1 -#define IND_RESYNC_REVERSE 2 -#define IND_VOLUME_DOWN 3 -#define IND_MIRROR_DOWN 4 -#define IND_LOGGING 5 -#define IND_RESYNC_NEEDED 6 -#define IND_REV_RESYNC_NEEDED 7 -#define IND_BITMAP_FAILED 8 -#define IND_FULL_SYNC_NEEDED 9 -#define IND_FCAL_FAILED 10 - (void) strcpy(status[IND_ENABLED], "replicating"); - (void) strcpy(status[IND_RESYNC], "sync"); - (void) strcpy(status[IND_RESYNC_REVERSE], "rev sync"); - (void) strcpy(status[IND_VOLUME_DOWN], "volume down"); - (void) strcpy(status[IND_MIRROR_DOWN], "mirror down"); - (void) strcpy(status[IND_LOGGING], "logging"); - (void) strcpy(status[IND_RESYNC_NEEDED], "need sync"); - (void) strcpy(status[IND_REV_RESYNC_NEEDED], "need rev sync"); - (void) strcpy(status[IND_BITMAP_FAILED], "bitmap failed"); - (void) strcpy(status[IND_FULL_SYNC_NEEDED], "full sync needed"); - (void) strcpy(status[IND_FCAL_FAILED], "fcal failed"); - dual_initted = 1; -} - - -int -rdc_get_maxsets(void) -{ - rdc_status_t rdc_status; - spcs_s_info_t ustatus; - int rc; - - rdc_status.nset = 0; - ustatus = spcs_s_ucreate(); - - rc = RDC_IOCTL(RDC_STATUS, &rdc_status, 0, 0, 0, 0, ustatus); - spcs_s_ufree(&ustatus); - - if (rc == SPCS_S_ERROR) - return (-1); - - return (rdc_status.maxsets); -} - -int -dual_stats() -{ - int ind, i, k, len; - int stars, size, segs; - int rdcindex; - float pct; - char fn[19]; - char *phost; - char *shost; - char *pfile; - char *sfile; - char lhost[16]; - spcs_s_info_t ustats = NULL; - - (void) gethostname(lhost, 16); - - if (rdc_maxsets <= 0) - rdc_maxsets = rdc_get_maxsets(); - - if (rdc_maxsets < 0) - goto no_stats; - - if (!rdc_status) { - rdc_status = malloc(sizeof (rdc_status_t) + - (sizeof (rdc_set_t) * (rdc_maxsets - 1))); - if (!rdc_status) { -no_stats: - (void) mvprintw(0, 20, - "****** Dual Copy Not Available ******"); - return (-1); - } - - rdc_info = rdc_status->rdc_set; - } - - rdc_status->nset = rdc_maxsets; - ustats = spcs_s_ucreate(); - - size = RDC_IOCTL(RDC_STATUS, rdc_status, 0, 0, 0, 0, ustats); - if (size == SPCS_S_ERROR) { - if (ustats) { - spcs_s_report(ustats, stderr); - spcs_s_ufree(&ustats); - } - (void) mvprintw(0, 20, "****** Dual Copy Not Available ******"); - return (-1); - } - spcs_s_ufree(&ustats); - rdc_enabled_sets = rdc_status->nset; - - if (!dual_initted) - init_dual(); - - set_dual_on_off(); - - calc_time(); - - (void) mvprintw(0, 20, "****** Dual Copy Statistics ******"); - (void) attron(A_UNDERLINE); - (void) mvprintw(2, 0, "primary"); - (void) mvprintw(2, 22, "link status"); - (void) mvprintw(2, 36, "secondary"); - (void) mvprintw(2, 54, "dual copy status"); - (void) attroff(A_UNDERLINE); - - for (rdcindex = 0, k = 0; rdcindex < rdc_enabled_sets; rdcindex++) { - if (!(rdc_info[rdcindex].flags & RDC_ENABLED) || - !dual_on_off[rdcindex]) - continue; - - if (rdc_info[rdcindex].sync_flags & RDC_VOL_FAILED) - ind = IND_VOLUME_DOWN; - else if (rdc_info[rdcindex].flags & RDC_FCAL_FAILED) - ind = IND_FCAL_FAILED; - else if (rdc_info[rdcindex].bmap_flags & RDC_BMP_FAILED) - ind = IND_BITMAP_FAILED; - else if (rdc_info[rdcindex].flags & RDC_LOGGING) { - if (rdc_info[rdcindex].sync_flags & - RDC_SYNC_NEEDED) - ind = IND_RESYNC_NEEDED; - else if (rdc_info[rdcindex].sync_flags & - RDC_RSYNC_NEEDED) - ind = IND_REV_RESYNC_NEEDED; - else - ind = IND_LOGGING; - } else if ((rdc_info[rdcindex].flags & RDC_SLAVE) && - (rdc_info[rdcindex].flags & RDC_SYNCING)) { - if (rdc_info[rdcindex].flags & RDC_PRIMARY) - ind = IND_RESYNC_REVERSE; - else - ind = IND_RESYNC; - } else if (rdc_info[rdcindex].flags & RDC_SYNCING) { - if (rdc_info[rdcindex].flags & RDC_PRIMARY) - ind = IND_RESYNC; - else - ind = IND_RESYNC_REVERSE; - } else - ind = IND_ENABLED; - - phost = rdc_info[rdcindex].primary.intf; - pfile = rdc_info[rdcindex].primary.file; - shost = rdc_info[rdcindex].secondary.intf; - sfile = rdc_info[rdcindex].secondary.file; - - if ((len = strlen(phost)) > 8) { - (void) mvprintw(4 + k, 0, ".%+7s:", - phost + len - 7); - } else - (void) mvprintw(4 + k, 0, "%+8s:", phost); - - if ((len = strlen(pfile)) > DISPLEN) { - (void) mvprintw(4 + k, 9, "...%-13s", - pfile + len - DISPLEN + 3); - } else - (void) mvprintw(4 + k, 9, "%-16s", pfile); - - (void) attron(A_BOLD); - (void) mvprintw(4 + k, 26, "*"); - (void) mvprintw(4 + k, 28, "*"); - - (void) mvprintw(4 + k, 56, "%-8s", status[ind]); - (void) attroff(A_BOLD); - - if (ind == IND_RESYNC_REVERSE) { - if (bright && !(rdc_info[rdcindex].flags & RDC_LOGGING)) - (void) mvprintw(4 + k, 27, "<"); - if (rdc_info[rdcindex].flags & RDC_PRIMARY && - !(rdc_info[rdcindex].flags & RDC_LOGGING)) - calc_completion(rdcindex, - rdc_info[rdcindex].bits_set, 4 + k); - } else if (ind == IND_RESYNC) { - if (bright && !(rdc_info[rdcindex].flags & RDC_LOGGING)) - (void) mvprintw(4 + k, 27, ">"); - if (rdc_info[rdcindex].flags & RDC_PRIMARY && - !(rdc_info[rdcindex].flags & RDC_LOGGING)) - calc_completion(rdcindex, - rdc_info[rdcindex].bits_set, 4 + k); - } else if (ind == IND_LOGGING) - (void) mvprintw(4 + k, 27, "."); - else if (ind == IND_ENABLED) - (void) mvprintw(4 + k, 27, "="); - - if ((len = strlen(shost)) > 8) { - (void) mvprintw(4 + k, 30, ".%+7s:", - shost + len - 7); - } else - (void) mvprintw(4 + k, 30, "%+8s:", shost); - - if ((len = strlen(sfile)) > DISPLEN) { - (void) mvprintw(4 + k, 39, "...%-13s", - sfile + len - DISPLEN + 3); - } else - (void) mvprintw(4 + k, 39, "%-16s", sfile); - - k++; - } - - k += 5; - (void) attron(A_UNDERLINE); - for (i = 0; i < 80; i++) - (void) mvprintw(k, i, " "); - k += 2; - (void) mvprintw(k, 0, "partition"); - (void) mvprintw(k, 16, "recovery needed"); - (void) mvprintw(k, 48, "recovery completed"); - (void) attroff(A_UNDERLINE); - k += 2; - - for (rdcindex = 0; rdcindex < rdc_enabled_sets; rdcindex++) { - if (!(rdc_info[rdcindex].flags & RDC_ENABLED) || - !dual_on_off[rdcindex]) - continue; - - if (!(rdc_info[rdcindex].flags & RDC_PRIMARY)) { - continue; - } - if (!(rdc_info[rdcindex].flags & RDC_SLAVE) && - !(rdc_info[rdcindex].flags & RDC_SYNCING) && - !(rdc_info[rdcindex].flags & RDC_LOGGING)) { - continue; - } - - len = strlen(rdc_info[rdcindex].secondary.file); - if (len > 15) { - (void) strcpy(fn, "..."); - (void) strcat(fn, - rdc_info[rdcindex].secondary.file + len - 12); - } else - (void) strcpy(fn, rdc_info[rdcindex].secondary.file); - (void) mvprintw(k, 0, "%-15s", fn); - - segs = FBA_TO_LOG_LEN(rdc_info[rdcindex].volume_size); - pct = segs ? - ((float)rdc_info[rdcindex].bits_set / (float)segs) : 0.0; - stars = (int)(pct * 20.0); - while (stars > 0) { - (void) mvprintw(k, 16 + stars, "*"); - stars--; - } - (void) attron(A_BOLD); - (void) mvprintw(k, 16, "["); - (void) mvprintw(k, 37, "]"); - (void) attroff(A_BOLD); - (void) mvprintw(k, 39, "%6.2f%%", pct * 100.0); - - if (rdc_info[rdcindex].flags & RDC_SYNCING) - pct = ((float)rdc_info[rdcindex].sync_pos / - (float)rdc_info[rdcindex].volume_size); - else - pct = 0.0; - stars = (int)(pct * 20.0); - while (stars > 0) { - (void) mvprintw(k, 48 + stars, "*"); - stars--; - } - (void) attron(A_BOLD); - (void) mvprintw(k, 48, "["); - (void) mvprintw(k, 69, "]"); - (void) attroff(A_BOLD); - (void) mvprintw(k, 70, "%6.2f%%", pct * 100.0); - k++; - } - bright = !bright; - return (0); -} - -/* - * Calculate a time interval in milliseconds using the - * micosecond counter - */ -void -calc_time(void) -{ - unsigned int cur; - - cur = USEC_READ(); - dc_delta_time = cur > dc_prev_time ? cur - dc_prev_time : - cur + 0xFFFFFFFF - dc_prev_time; - dc_delta_time /= 1000; - dc_prev_time = cur; -} - -/* - * Calculate estimated time of completion of resync - */ -void -calc_completion(int cd, int updates_left, int l) -{ - int delta_done; - double rate; - long time_left; - long hours; - long minutes; - static int initted = 0; - - if (!initted) { - updates_prev[cd] = updates_left; - initted = 1; - return; - } - - /* - * Caclulate updates since last check - */ - delta_done = updates_prev[cd] - updates_left; - updates_prev[cd] = updates_left; - - /* - * If no updates, don't bother estimating completion time - */ - if (delta_done <= 0) { - samples[cd] = 0; - return; - } - - rate = delta_done * 1000.0 / dc_delta_time; - - /* - * Calculate rate of updates as a weighted average - * of previous and current rate - */ - if (rate_prev[cd] && samples[cd] > SAMPLE_RATE) - rate = (rate_prev[cd] * 4.0 + rate) / 5.0; - rate_prev[cd] = rate; - samples[cd]++; - - /* - * Get enough samples before making estimate - */ - if (samples[cd]++ < SAMPLE_RATE) - return; - - time_left = (long)(updates_left/rate); /* time left in seconds */ - - if (time_left < 0) - return; - - hours = time_left / (60 * 60); - time_left -= hours * (60 * 60); - minutes = time_left / 60; - time_left -= minutes * 60; - (void) mvprintw(l, 67, - "time %02d:%02d:%02d \n", hours, minutes, time_left); -} - -void -disp_total_stats(void) -{ - unsigned int read_s, write_s, access_s; - double readp, writep; - unsigned int rmiss_s, wmiss_s; - double kbps = 2.0; - int rtotal, wtotal, i, j; - unsigned int throughput = 0, rthroughput = 0, creads = 0, cwrites = 0; - char status_bit, down = 0; - int len; - char fn[19]; - - read_s = cs_cur->st_rdhits; - write_s = cs_cur->st_wrhits; - rmiss_s = cs_cur->st_rdmiss; - wmiss_s = cs_cur->st_wrmiss; - access_s = (read_s + write_s + rmiss_s + wmiss_s); - - rtotal = cs_cur->st_rdhits + cs_cur->st_rdmiss; - wtotal = cs_cur->st_wrhits + cs_cur->st_wrmiss; - if (rtotal != 0) - readp = cs_cur->st_rdhits / (double)rtotal; - else - readp = 0.0; - - if (wtotal != 0) - writep = cs_cur->st_wrhits / (double)wtotal; - else - writep = 0.0; - - set_on_off(); - (void) mvprintw(0, 14, - "****** Storage Cache (Cumulative) ******"); - (void) mvprintw(2, 30, "disk_io cache"); - (void) attron(A_UNDERLINE); - (void) mvprintw(3, 1, - " cd cached_partition reads writes reads writes"); - (void) attroff(A_UNDERLINE); - for (i = 0, j = 0; j < cs_cur->st_count; i++) { - if (i >= sdbc_max_devices) - break; - if (cs_cur->st_shared[i].sh_alloc) { - cs_cur->st_shared[i].sh_disk_write /= kbps; - cs_cur->st_shared[i].sh_disk_read /= kbps; - cs_cur->st_shared[i].sh_cache_write /= kbps; - cs_cur->st_shared[i].sh_cache_read /= kbps; - rthroughput += cs_cur->st_shared[i].sh_disk_read; - throughput += cs_cur->st_shared[i].sh_disk_write; - creads += cs_cur->st_shared[i].sh_cache_read; - cwrites += cs_cur->st_shared[i].sh_cache_write; - if (!down) - down = cs_cur->st_shared[i].sh_failed; - if (cs_cur->st_shared[i].sh_failed && bright) - status_bit = '*'; - else - status_bit = ' '; - if ((len = - strlen(cs_cur->st_shared[i].sh_filename)) > 15) { - (void) strcpy(fn, "..."); - (void) strcat(fn, - cs_cur->st_shared[i].sh_filename + - len - 12); - } else - (void) strcpy(fn, - cs_cur->st_shared[i].sh_filename); - - if (on_off[i]) { - (void) mvprintw(4 + j, 1, - "%3d %-15s%c %10u %10u %10u %10u", - cs_cur->st_shared[i].sh_cd, - fn, - status_bit, - cs_cur->st_shared[i].sh_disk_read, - cs_cur->st_shared[i].sh_disk_write, - cs_cur->st_shared[i].sh_cache_read, - cs_cur->st_shared[i].sh_cache_write); - j++; - } - } - } - bright = !bright; - - (void) mvprintw(4 + j, 22, - "---------- ---------- ---------- ----------"); - (void) mvprintw(5 + j, 8, " Kbytes total:%10u %10u %10u %10u", - (int)rthroughput, (int)throughput, - (int)creads, (int)cwrites); - (void) mvprintw(7 + j, 1, " accesses"); - (void) mvprintw(7 + j, 18, "read write %%readh %%writeh"); - - (void) attron(A_UNDERLINE); - (void) mvprintw(8 + j, 1, " "); - (void) mvprintw(8 + j, 13, - " "); - (void) mvprintw(8 + j, 11, "( misses) ( misses)"); - (void) attroff(A_UNDERLINE); - - (void) mvprintw(9 + j, 0, "%10u %10u %10u %6.1f %6.1f", - access_s, read_s, write_s, readp*100.0, writep*100.0); - (void) mvprintw(10 + j, 0, - " (%10u) (%10u)\n\n", rmiss_s, wmiss_s); - - (void) attron(A_UNDERLINE); - (void) mvprintw(13 + j, 1, "cachesize blocksize"); - (void) attroff(A_UNDERLINE); - (void) mvprintw(14 + j, 1, "%8dK %10d", cs_cur->st_cachesize / 1024, - cs_cur->st_blksize); - - (void) attron(A_UNDERLINE); - (void) mvprintw(16 + j, 1, "Write blocks available:"); - (void) attroff(A_UNDERLINE); - (void) mvprintw(17 + j, 1, "Net 0: %6d", cs_cur->st_wlru_inq); - - (void) attron(A_UNDERLINE); - (void) mvprintw(19 + j, 1, "LRU stats: Blocks Requeued Optimized"); - (void) attroff(A_UNDERLINE); - (void) mvprintw(20 + j, 7, "%12d %12u %12u", cs_cur->st_lru_blocks, - cs_cur->st_lru_req, cs_cur->st_lru_noreq); - - if (down) - (void) mvprintw(25 + j, 1, "* -- disk off-line"); -} diff --git a/usr/src/cmd/avs/sdbc/sdbc_dynmem.c b/usr/src/cmd/avs/sdbc/sdbc_dynmem.c deleted file mode 100644 index f6d25a11f4..0000000000 --- a/usr/src/cmd/avs/sdbc/sdbc_dynmem.c +++ /dev/null @@ -1,388 +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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* - * This program is strictly for demonstration purposes and not for - * production use. It demonstrates how to access the dynamic memory - * caching statistics and turning variables via the kstat library. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stropts.h> -#include <ctype.h> -#include <unistd.h> -#include <memory.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <signal.h> -#include <locale.h> -#include <kstat.h> - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/sysinfo.h> -#include <sys/buf.h> -#include <sys/vfs.h> -#include <sys/dnlc.h> - -#define TRUE 1 -#define FALSE 0 -#define SDBC_KSTAT_MODULE "sdbc" -#define SDBC_KSTAT_DYNMEM "dynmem" - -typedef struct { - int instance; - kstat_t *ksp; - } KSTAT_INFO_DEF; - -typedef struct { - kstat_named_t *knp; - char *named; - int newval; - } DYNMEM_KNP_DEFN; - -typedef enum { -MONITOR = 0, -MAXLIST, -AGECT1, -AGECT2, -AGECT3, -SEC1, -SEC2, -SEC3, -PCNT1, -PCNT2, -HDPCNT, -ALLOC, -DEALLOC, -HISTORY, -NODATA, -CAND, -DEALLOCS, -HOSTS, -PESTS, -METAS, -HOLDS, -OTHERS, -NOTAVAIL, -DIRECTIVE, -SIMPLECT -} arglist_id; - -#define NO_VALUE -1 - -DYNMEM_KNP_DEFN dynmem_knp[] = { - NULL, "sdbc_monitor_dynmem", NO_VALUE, - NULL, "sdbc_max_dyn_list", NO_VALUE, - NULL, "sdbc_cache_aging_ct1", NO_VALUE, - NULL, "sdbc_cache_aging_ct2", NO_VALUE, - NULL, "sdbc_cache_aging_ct3", NO_VALUE, - NULL, "sdbc_cache_aging_sec1", NO_VALUE, - NULL, "sdbc_cache_aging_sec2", NO_VALUE, - NULL, "sdbc_cache_aging_sec3", NO_VALUE, - NULL, "sdbc_cache_aging_pcnt1", NO_VALUE, - NULL, "sdbc_cache_aging_pcnt2", NO_VALUE, - NULL, "sdbc_max_holds_pcnt", NO_VALUE, - NULL, "sdbc_alloc_cnt", NO_VALUE, - NULL, "sdbc_dealloc_cnt", NO_VALUE, - NULL, "sdbc_history", NO_VALUE, - NULL, "sdbc_nodatas", NO_VALUE, - NULL, "sdbc_candidates", NO_VALUE, - NULL, "sdbc_deallocs", NO_VALUE, - NULL, "sdbc_hosts", NO_VALUE, - NULL, "sdbc_pests", NO_VALUE, - NULL, "sdbc_metas", NO_VALUE, - NULL, "sdbc_holds", NO_VALUE, - NULL, "sdbc_others", NO_VALUE, - NULL, "sdbc_notavail", NO_VALUE, - NULL, "sdbc_process_directive", NO_VALUE, - NULL, "sdbc_simplect", NO_VALUE, - NULL, NULL, NO_VALUE - }; - -/* - * Print Usage - */ -static void -print_usage() -{ - (void) printf("USAGE: wake - wakeup thread, hys - max hysteresis\n"); - (void) printf(" mon 1 - monitor shutdown\n"); - (void) printf(" 2 - monitor thread stats1\n"); - (void) printf(" 4 - monitor thread stats2\n"); - (void) printf(" age1 n - num cyc to full host aging and " - "dealloc\n"); - (void) printf(" age2 n - num cyc to full meta aging and " - "dealloc\n"); - (void) printf(" age3 n - num cyc to full one pg aging and " - "dealloc\n"); - (void) printf(" sec1 n - sec1 aging time\n"); - (void) printf(" sec2 n - sec2 aging time\n"); - (void) printf(" sec3 n - sec3 aging time\n"); - (void) printf(" pcnt1 n - percent to sec1/sec2 trans\n"); - (void) printf(" pcnt2 n - percent to sec2/sec3 trans\n"); - (void) printf(" hdpcnt n - max percent of cents for holds\n"); - (void) printf(" list n - host+pest max len\n"); - (void) printf("No Args - print current settings only\n"); -} - -/* - * Main - */ -/* ARGSUSED */ -#ifdef lint -int -sd_dynmem_lintmain(int argc, char *argv[]) -#else -int -main(int argc, char *argv[]) -#endif -{ - DYNMEM_KNP_DEFN *p_dynmem_knp; - kstat_ctl_t *kctl; - KSTAT_INFO_DEF info_ksp; - int val; - char **pargs, **cur_pargs; - - /* - * grab and parse argument list - */ - p_dynmem_knp = dynmem_knp; - pargs = argv; - while (*pargs) { - (void) printf("pargs=%x - %s\n", (uint_t)pargs, *pargs); - - cur_pargs = pargs; - pargs++; - - if (strcmp(*cur_pargs, "h") == 0) { - print_usage(); - return (0); - } - - if (strcmp(*cur_pargs, "wake") == 0) { - if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE) - (p_dynmem_knp+DIRECTIVE)->newval = 0; - (p_dynmem_knp+DIRECTIVE)->newval |= 0x01; - continue; - } - - if (strcmp(*cur_pargs, "hys") == 0) { - if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE) - (p_dynmem_knp+DIRECTIVE)->newval = 0; - (p_dynmem_knp+DIRECTIVE)->newval |= 0x02; - continue; - } - - if (strcmp (*cur_pargs, "mon") == 0) { - val = atoi(*pargs); - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - pargs++; - (p_dynmem_knp+MONITOR)->newval = val; - } - - if (strcmp (*cur_pargs, "age1") == 0) { - val = atoi(*pargs); - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - pargs++; - (p_dynmem_knp+AGECT1)->newval = val; - } - - if (strcmp(*cur_pargs, "age2") == 0) { - val = atoi(*pargs); - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - pargs++; - (p_dynmem_knp+AGECT2)->newval = val; - } - - if (strcmp(*cur_pargs, "age3") == 0) { - val = atoi(*pargs); - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - pargs++; - (p_dynmem_knp+AGECT3)->newval = val; - } - - if (strcmp (*cur_pargs, "sec1") == 0) { - val = atoi(*pargs); - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - pargs++; - if (val == 0) - break; - else { - (p_dynmem_knp+SEC1)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "sec2") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val == 0) - break; - else { - (p_dynmem_knp+SEC2)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "sec3") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val == 0) - break; - else { - (p_dynmem_knp+SEC3)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "pcnt1") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val == 0) - break; - else { - (p_dynmem_knp+PCNT1)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "pcnt2") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val == 0) - break; - else { - (p_dynmem_knp+PCNT2)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "hdpcnt") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val < 0) - break; - else { - (p_dynmem_knp+HDPCNT)->newval = val; - continue; - } - } - - if (strcmp(*cur_pargs, "list") == 0) { - val = atoi(*pargs); - pargs++; - (void) printf("errno=%x, %s=%x\n", errno, *cur_pargs, - val); - if (val == 0) - break; - else { - (p_dynmem_knp+MAXLIST)->newval = val; - continue; - } - } - } /* while(*pargs && cl) */ - - /* - * open the kstat library - */ - kctl = kstat_open(); - if (kctl == NULL) { - (void) printf("kstat_open() failed\n"); - return (1); - } - - /* - * is the name module about - */ - info_ksp.instance = 0; - info_ksp.ksp = kstat_lookup(kctl, SDBC_KSTAT_MODULE, 0, - SDBC_KSTAT_DYNMEM); - if (info_ksp.ksp == NULL) { - (void) printf("No module to report\n"); - return (1); - } - - /* - * using the info get a copy of the data - */ - if (kstat_read(kctl, info_ksp.ksp, NULL) == -1) { - (void) printf("Can't read kstat\n"); - return (1); - } - - /* - * print the current data - */ - p_dynmem_knp = dynmem_knp; - while (p_dynmem_knp->named) { - p_dynmem_knp->knp = - kstat_data_lookup(info_ksp.ksp, p_dynmem_knp->named); - if (p_dynmem_knp->knp == NULL) { - (void) printf("kstat_data_lookup(%s) failed\n", - p_dynmem_knp->named); - return (1); - } else { - (void) printf("%s: %x\n", p_dynmem_knp->named, - (uint_t)p_dynmem_knp->knp->value.ul); - p_dynmem_knp++; - } - } - - /* - * modify the data and write it back - */ - p_dynmem_knp = dynmem_knp; - while (p_dynmem_knp->named) { - if (p_dynmem_knp->newval != NO_VALUE) - p_dynmem_knp->knp->value.ul = p_dynmem_knp->newval; - p_dynmem_knp++; - } - - if (kstat_write(kctl, info_ksp.ksp, NULL) == -1) { - (void) printf("kstat_write() failed\n"); - return (1); - } - - (void) printf("Finished (h for help)\n"); - return (0); -} diff --git a/usr/src/cmd/avs/sdbc/sdbc_ioctl.c b/usr/src/cmd/avs/sdbc/sdbc_ioctl.c deleted file mode 100644 index baa0858236..0000000000 --- a/usr/src/cmd/avs/sdbc/sdbc_ioctl.c +++ /dev/null @@ -1,156 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * SDBC user level ioctl interface - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/types.h> -#include <fcntl.h> -#include <strings.h> - -#include <sys/nsctl/sd_cache.h> -#include <sys/nsctl/sd_conf.h> -#include <sys/nsctl/sdbc_ioctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> - -#include <sys/nsctl/sv.h> -#include <sys/nsctl/sv_impl.h> - - -const char *__sdbc_dev = "/dev/sdbc"; -static int __sdbc_fd; - - -static int -__sdbc_open(void) -{ - int fd; - - fd = open("/dev/nsctl", O_RDONLY); - if (fd >= 0) - (void) close(fd); - - fd = open(__sdbc_dev, O_RDONLY); - if (fd < 0) - return (-1); - - return (__sdbc_fd = fd); -} - - -static void -sv_list() -{ - sv_name_t svn[1]; - sv_name_t *svn_system; - sv_list_t svl; - static int fd = -1; - - if (fd < 0) - fd = open(SV_DEVICE, O_RDONLY); - if (fd < 0) - return; - - bzero(&svl, sizeof (svl)); - bzero(&svn[0], sizeof (svn)); - - svl.svl_names = &svn[0]; - svl.svl_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_LIST, &svl) < 0) - return; - - svn_system = calloc(svl.svl_maxdevs, sizeof (*svn)); - if (svn_system == NULL) - return; - - /* Grab the system list from the driver */ - svl.svl_count = svl.svl_maxdevs; - svl.svl_names = svn_system; - - (void) ioctl(fd, SVIOC_LIST, &svl); - - free(svn_system); - spcs_s_ufree(&svl.svl_error); -} - - -int -sdbc_ioctl(long cmd, long a0, long a1, long a2, long a3, long a4, - spcs_s_info_t *ustatus) -{ - _sdbc_ioctl_t args; - int rc; - - *ustatus = NULL; - - if (!__sdbc_fd && __sdbc_open() < 0) - return (-1); - - switch (cmd) { - /* - * These ioctls work on open cache descriptors. The sv_list() function - * has the side-effect of re-opening all configured descriptors. - * Without this call, devices seem to "disappear" from the system when - * certain reconfiguration operations, for example II or SNDR disable, - * are done. - * It does rely on SV being configured, so in an STE-only environment - * the disappearing will still seem to happen. - */ - case SDBC_SET_CD_HINT: - case SDBC_GET_CD_HINT: - case SDBC_STATS: - case SDBC_GET_CD_BLK: - case SDBC_INJ_IOERR: - case SDBC_CLR_IOERR: - sv_list(); - break; - - default: - break; - } - - args.arg0 = a0; - args.arg1 = a1; - args.arg2 = a2; - args.arg3 = a3; - args.arg4 = a4; - args.magic = _SD_MAGIC; /* for versioning */ - args.sdbc_ustatus = spcs_s_ucreate(); - - if ((rc = ioctl(__sdbc_fd, cmd, &args)) < 0) { - *ustatus = args.sdbc_ustatus; - } else { - spcs_s_ufree(&args.sdbc_ustatus); - *ustatus = NULL; - } - - return (rc); -} diff --git a/usr/src/cmd/avs/sv/Makefile b/usr/src/cmd/avs/sv/Makefile deleted file mode 100644 index 150d63e925..0000000000 --- a/usr/src/cmd/avs/sv/Makefile +++ /dev/null @@ -1,94 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -DYNPROG= svadm svboot - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) -LPROG = $(PROG:%=%.li) - -SUBDIRS= etc - -svadm := POBJS = svadm.o -svboot := POBJS = svboot.o - -OBJS= svadm.o svboot.o -SRCS= $(OBJS:%.o=%.c) -POFILE = sv_all.po -POFILES = $(OBJS:%.o=%.po) - -svadm := LDLIBS += -lunistat -ldscfg -svboot := LDLIBS += -lunistat -ldscfg - -CFLAGS += -v -LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2 -LINTFLAGS += -erroff=E_SEC_SCANF_UNBOUNDED_COPY -LINTFLAGS += -erroff=E_SEC_PRINTF_VAR_FMT -ROOTLINK1 = $(ROOTUSRSBIN)/svadm -ROOTLINK2 = $(ROOTUSRSBIN)/svboot - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SUBDIRS) $(PROG) $(POFILES) - -install: $(SUBDIRS) all $(ROOTPROG) $(ROOTLINK1) $(ROOTLINK2) - -lint: $(SUBDIRS) $(LPROG) - -clean: $(SUBDIRS) - $(RM) *.o $(POFILE) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -$(LPROG): - $(LINT.c) $(@:%.li=%.c) $(LDLIBS) - -$(ROOTLINK1): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTBIN)/svadm $@ - -$(ROOTLINK2): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTBIN)/svboot $@ - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/sv/etc/Makefile b/usr/src/cmd/avs/sv/etc/Makefile deleted file mode 100644 index d027aedca9..0000000000 --- a/usr/src/cmd/avs/sv/etc/Makefile +++ /dev/null @@ -1,69 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -include ../../../Makefile.cmd -include ../../Makefile.com - -SHFILES = sv sv.cluster -ROOTINIT_D = $(ROOTETC)/init.d - -FILEMODE = 0744 - -ROOTINIT_DPROG1 = $(ROOTINIT_D)/sv -ROOTINIT_DPROG2 = $(ROOTINIT_D)/sv.cluster - -.KEEP_STATE: - -all: $(SHFILES) - -install: all $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2) $(CLUSTERSBINDIR) \ - $(CLUSTERLIBSTOPDIR) $(CLUSTERLIBSTARTDIR) $(ROOTLIBSVCMETHOD) - -$(RM) $(CLUSTERLIBDSCFGSTOPDIR)/10sv - -$(RM) $(CLUSTERLIBDSCFGSTARTDIR)/15sv - -$(RM) $(CLUSTERSBINDIR)/sv - -$(RM) $(ROOTLIBSVCMETHOD)/svc-sv - -$(SYMLINK) ../../../sbin/sv $(CLUSTERLIBDSCFGSTOPDIR)/10sv - -$(SYMLINK) ../../../sbin/sv $(CLUSTERLIBDSCFGSTARTDIR)/15sv - $(LN) $(ROOTINIT_D)/sv $(ROOTLIBSVCMETHOD)/svc-sv - $(CP) $(ROOTINIT_D)/sv.cluster $(CLUSTERSBINDIR)/sv - -$(ROOTINIT_DPROG1): sv - $(INS.file) sv - -$(ROOTINIT_DPROG2): sv.cluster - $(INS.file) sv.cluster - -$(CLUSTERLIBSTOPDIR): - $(INS.dir) - -$(CLUSTERLIBSTARTDIR): - $(INS.dir) - -lint: - -clean: - $(RM) $(SHFILES) - -clobber: clean - $(RM) $(ROOTINIT_DPROG1) $(ROOTINIT_DPROG2) diff --git a/usr/src/cmd/avs/sv/etc/sv.cluster.sh b/usr/src/cmd/avs/sv/etc/sv.cluster.sh deleted file mode 100644 index 272ae7f7ba..0000000000 --- a/usr/src/cmd/avs/sv/etc/sv.cluster.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/ksh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -if [ ! -d /usr/sbin -o ! -d /usr/bin ] -then - exit 1 -fi - -# Constants - -SVBOOT=/usr/sbin/svboot -SVCS=/usr/bin/svcs -SVCS_NAME=system/nws_sv - -# Functions - -# main program - -# Determine if SMF service is online -# -ONLINE=`$SVCS -D $SVCS_NAME 2>>/dev/null | grep "^online"` -if [ -z $ONLINE ] -then - echo "$SVCS_NAME not online" - exit 1 -fi - -if [[ ! -x $SVBOOT ]] -then - echo "$0: cannot find $SVBOOT" - exit 1 -fi - -if [[ -z "$2" ]] -then - opt=usage -else - opt=$1 -fi - -case "$opt" in -'start') - $SVBOOT -C "$2" -r - ;; - -'stop') - - $SVBOOT -C "$2" -s - ;; - -*) - echo "Usage: $0 { start | stop } cluster_resource" - exit 1 - ;; -esac diff --git a/usr/src/cmd/avs/sv/etc/sv.sh b/usr/src/cmd/avs/sv/etc/sv.sh deleted file mode 100644 index d9c952577c..0000000000 --- a/usr/src/cmd/avs/sv/etc/sv.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/sbin/sh -# 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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -[ ! -d /usr/sbin -o ! -d /usr/bin ] && exit - -# Constants - -SVBOOT=/usr/sbin/svboot -SVCS=/usr/bin/svcs -DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" -OS_MINOR=`/usr/bin/uname -r | /usr/bin/cut -d '.' -f2` - -. /lib/svc/share/smf_include.sh - -# Make sure prior SMF dependents are not 'online' -# $1 = name of SMF service to validate dependents -# -do_smf_depends () -{ - times=0 - count=1 - - if [ $OS_MINOR -ge 11 ] - then - return 0 - elif [ -f $DSCFG_DEPEND_NOCHK ] - then - for pid in `pgrep dscfgadm` - do - if [ `grep -c $pid $DSCFG_DEPEND_NOCHK` -gt 0 ] - then - return 0 - fi - done - elif [ `ps -ef | grep preremove | grep -c SUNWspsvu` -gt 0 ] - then - return 0 - - fi - - - while [ $count -ne 0 ] - do - count=`$SVCS -o STATE -D $1 2>>/dev/null | grep "^online" | wc -l` - if [ $count -ne 0 ] - then - # Output banner after waiting first 5 seconds - # - if [ $times -eq 1 ] - then - echo "Waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - fi - - # Has it been longer then 5 minutes? (60 * 5 secs.) - # - if [ $times -eq 60 ] - then - echo "Error: Failed waiting for $1 dependents to be 'offline'" - $SVCS -D $1 2>>/dev/null | grep "^online" - exit $SMF_EXIT_ERR_FATAL - fi - - # Now sleep, giving other services time to stop - # - sleep 5 - times=`expr $times + 1` - fi - done - return 0 -} - -# main program - -if [ ! -x $SVBOOT ] -then - echo "$0: cannot find $SVBOOT" - exit $SMF_EXIT_MON_OFFLINE -fi - -case "$1" in -'start') - - $SVBOOT -r - ;; - -'stop') - - do_smf_depends "system/nws_sv" - - $SVBOOT -s - ;; - -*) - echo "Usage: $0 { start | stop }" - exit $SMF_EXIT_MON_OFFLINE - ;; -esac - -exit $SMF_EXIT_OK diff --git a/usr/src/cmd/avs/sv/svadm.c b/usr/src/cmd/avs/sv/svadm.c deleted file mode 100644 index 4fee03b277..0000000000 --- a/usr/src/cmd/avs/sv/svadm.c +++ /dev/null @@ -1,1515 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mkdev.h> -#include <sys/param.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdlib.h> -#include <strings.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> -#include <unistd.h> -#include <search.h> -#include <libgen.h> -#include <nsctl.h> - -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> - -#include <sys/nsctl/sv.h> -#include <sys/nsctl/sv_impl.h> - -#include <sys/nsctl/cfg.h> -#include <sys/nsctl/nsc_hash.h> - -#include "../sv/svadm.h" - - -static int sv_max_devices; - - -/* - * support for the special cluster tag "local" to be used with -C in a - * cluster for local volumes. - */ - -#define SV_LOCAL_TAG "local" - -static int sv_islocal; - -/* - * libcfg access. - */ - -static CFGFILE *cfg; /* libcfg file pointer */ -static int cfg_changed; /* set to 1 if we need to commit changes */ - -static char *cfg_cluster_tag; /* local cluster tag */ - -static char *implicit_tag; /* implicit cluster tag */ - - -/* - * Print width for print_sv() output. - */ - -#define STATWIDTH (SV_MAXPATH / 2) - -/* - * Pathnames. - */ - -static const caddr_t sv_rpath = SV_DEVICE; - -/* - * Functions. - */ - -static int read_config_file(const caddr_t, sv_name_t []); -static int enable_dev(sv_name_t *); -static int disable_dev(const caddr_t); -static void error(spcs_s_info_t *, caddr_t, ...); -static void create_cfg_hash(); -static int find_in_hash(char *path); -static void destroy_hashtable(); -static void remove_from_cfgfile(char *path, int setnumber); - -static caddr_t program; - -static void -sv_cfg_open(CFGLOCK mode) -{ - if (cfg != NULL) - return; - - cfg = cfg_open(NULL); - if (cfg == NULL) { - error(NULL, gettext("unable to access the configuration")); - /* NOTREACHED */ - } - - if (cfg_cluster_tag && *cfg_cluster_tag) { - cfg_resource(cfg, cfg_cluster_tag); - } else { - cfg_resource(cfg, NULL); - } - if (!cfg_lock(cfg, mode)) { - error(NULL, gettext("unable to lock the configuration")); - /* NOTREACHED */ - } -} - - -static void -sv_cfg_close(void) -{ - if (cfg == NULL) - return; - - if (cfg_changed) { - (void) cfg_commit(cfg); - cfg_changed = 0; - } - - cfg_close(cfg); - cfg = NULL; -} - - - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("usage:\n")); - - (void) fprintf(stderr, gettext( - "\t%s -h help\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] display status\n"), - program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -i display " - "extended status\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -v display " - "version number\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -e { -f file | volume } enable\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -d { -f file | volume } disable\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -r { -f file | volume } reconfigure\n"), program); - - sv_cfg_close(); -} - -static void -message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap) -{ - (void) fprintf(stderr, "%s: %s: ", program, prefix); - (void) vfprintf(stderr, string, ap); - (void) fprintf(stderr, "\n"); - - if (status) { - spcs_s_report(*status, stderr); - spcs_s_ufree(status); - } -} - - -static void -error(spcs_s_info_t *status, caddr_t string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("error"), status, string, ap); - - va_end(ap); - - sv_cfg_close(); - exit(1); -} - - -static void -warn(spcs_s_info_t *status, caddr_t string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("warning"), status, string, ap); - - va_end(ap); -} - - -static void -sv_get_maxdevs(void) -{ - sv_name_t svn[1]; - sv_list_t svl; - int fd; - - if (sv_max_devices > 0) - return; - - fd = open(sv_rpath, O_RDONLY); - if (fd < 0) - error(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - - bzero(&svl, sizeof (svl)); - bzero(&svn[0], sizeof (svn)); - - svl.svl_names = &svn[0]; - svl.svl_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_LIST, &svl) < 0) { - (void) close(fd); - error(&svl.svl_error, gettext("unable to get max devs")); - } - - spcs_s_ufree(&svl.svl_error); - sv_max_devices = svl.svl_maxdevs; - - (void) close(fd); -} - - -static sv_name_t * -sv_alloc_svnames(void) -{ - sv_name_t *svn = NULL; - - sv_get_maxdevs(); - - svn = calloc(sv_max_devices, sizeof (*svn)); - if (svn == NULL) { - error(NULL, "unable to allocate %ld bytes of memory", - sv_max_devices * sizeof (*svn)); - } - - return (svn); -} - - -static void -sv_check_dgislocal(char *dgname) -{ - char *othernode; - int rc; - - /* - * check where this disk service is mastered - */ - - rc = cfg_dgname_islocal(dgname, &othernode); - if (rc < 0) { - error(NULL, gettext("unable to find " - "disk service, %s: %s"), dgname, strerror(errno)); - } - - if (rc == 0) { - error(NULL, gettext("disk service, %s, is " - "active on node \"%s\"\nPlease re-issue " - "the command on that node"), dgname, othernode); - } -} - - -/* - * Carry out cluster based checks for a specified volume, or just - * global options. - */ -static void -sv_check_cluster(char *path) -{ - char dgname[CFG_MAX_BUF]; - static int sv_iscluster = -1; /* set to 1 if running in a cluster */ - - /* - * Find out if we are running in a cluster - */ - if (sv_iscluster == -1) { - if ((sv_iscluster = cfg_iscluster()) < 0) { - error(NULL, gettext("unable to ascertain environment")); - } - } - - if (!sv_iscluster && cfg_cluster_tag != NULL) { - error(NULL, gettext("-C is not valid when not in a cluster")); - } - - if (!sv_iscluster || sv_islocal || path == NULL) { - return; - } - - - /* - * Cluster-only checks on pathname - */ - if (cfg_dgname(path, dgname, sizeof (dgname)) == NULL) { - error(NULL, gettext("unable to determine " - "disk group name for %s"), path); - return; - } - - if (cfg_cluster_tag != NULL) { - /* - * Do dgislocal check now in case path did not contain - * a dgname. - * - * E.g. adding a /dev/did/ device to a disk service. - */ - - sv_check_dgislocal(cfg_cluster_tag); - } - - if (strcmp(dgname, "") == 0) - return; /* NULL dgname is valid */ - - if (cfg_cluster_tag == NULL) { - /* - * Implicitly set the cluster tag to dgname - */ - - sv_check_dgislocal(dgname); - - if (implicit_tag) { - free(implicit_tag); - implicit_tag = NULL; - } - - implicit_tag = strdup(dgname); - if (implicit_tag == NULL) { - error(NULL, - gettext("unable to allocate memory " - "for cluster tag")); - } - } else { - /* - * Check dgname and cluster tag from -C are the same. - */ - - if (strcmp(dgname, cfg_cluster_tag) != 0) { - error(NULL, - gettext("-C (%s) does not match disk group " - "name (%s) for %s"), cfg_cluster_tag, - dgname, path); - } - - /* - * sv_check_dgislocal(cfg_cluster_tag) was called above. - */ - } -} - - -static void -print_version(void) -{ - sv_version_t svv; - int fd; - - bzero(&svv, sizeof (svv)); - svv.svv_error = spcs_s_ucreate(); - - fd = open(sv_rpath, O_RDONLY); - if (fd < 0) { - warn(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return; - } - - if (ioctl(fd, SVIOC_VERSION, &svv) != 0) { - error(&svv.svv_error, - gettext("unable to read the version number")); - /* NOTREACHED */ - } - - spcs_s_ufree(&svv.svv_error); -#ifdef DEBUG - (void) printf(gettext("Storage Volume version %d.%d.%d.%d\n"), - svv.svv_major_rev, svv.svv_minor_rev, - svv.svv_micro_rev, svv.svv_baseline_rev); -#else - if (svv.svv_micro_rev) { - (void) printf(gettext("Storage Volume version %d.%d.%d\n"), - svv.svv_major_rev, svv.svv_minor_rev, svv.svv_micro_rev); - } else { - (void) printf(gettext("Storage Volume version %d.%d\n"), - svv.svv_major_rev, svv.svv_minor_rev); - } -#endif - - (void) close(fd); -} - -int -main(int argc, char *argv[]) -{ - extern int optind; - extern char *optarg; - char *conf_file = NULL; - int enable, disable, compare, print, version; - int opt, Cflag, fflag, iflag; - int rc; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("svadm"); - - program = strdup(basename(argv[0])); - - Cflag = fflag = iflag = 0; - compare = enable = disable = version = 0; - - print = 1; - - while ((opt = getopt(argc, argv, "C:def:hirv")) != EOF) { - switch (opt) { - - case 'C': - if (Cflag) { - warn(NULL, - gettext("-C specified multiple times")); - usage(); - exit(2); - /* NOTREACHED */ - } - - Cflag++; - cfg_cluster_tag = optarg; - break; - - case 'e': - print = 0; - enable++; - break; - - case 'd': - print = 0; - disable++; - break; - - case 'f': - fflag++; - conf_file = optarg; - break; - - case 'i': - iflag++; - break; - - case 'r': - /* Compare running system with sv.cf */ - print = 0; - compare++; - break; - - case 'v': - print = 0; - version++; - break; - - case 'h': - usage(); - exit(0); - - default: - usage(); - exit(2); - /* NOTREACHED */ - } - } - - - /* - * Usage checks - */ - - if ((enable + disable + compare) > 1) { - warn(NULL, gettext("-d, -e and -r are mutually exclusive")); - usage(); - exit(2); - } - - if (fflag && (print || version)) { - warn(NULL, gettext("-f is only valid with -d, -e or -r")); - usage(); - exit(2); - } - - if (fflag && optind != argc) { - usage(); - exit(2); - } - - if (print || version) { - /* check for no more args */ - - if (optind != argc) { - usage(); - exit(2); - } - } else { - /* check for inline args */ - - if (!fflag && (argc - optind) != 1) { - usage(); - exit(2); - } - } - - if (!print && iflag) { - usage(); - exit(2); - } - - - /* - * Check for the special cluster tag and convert into the - * internal representation. - */ - - if (cfg_cluster_tag != NULL && - strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0) { - cfg_cluster_tag = "-"; - sv_islocal = 1; - } - - - /* - * Process commands - */ - - if (optind != argc) { - /* deal with inline volume argument */ - - rc = 0; - if (enable) - rc = enable_one_sv(argv[optind]); - else if (disable) - rc = disable_one_sv(argv[optind]); - else /* if (compare) */ - compare_one_sv(argv[optind]); - - if (rc != 0) - return (1); - - return (0); - } - - rc = 0; - if (enable) - rc = enable_sv(conf_file); - else if (disable) - rc = disable_sv(conf_file); - else if (compare) - compare_sv(conf_file); - else if (print) - print_sv(iflag); - else /* if (version) */ - print_version(); - - if (rc != 0) - return (1); - - return (0); -} - - - -/* LINT - not static as fwcadm uses it */ -static int -enable_sv(char *conf_file) -{ - int index; - sv_name_t *svn; - int cnt; - int rc, ret; - - svn = sv_alloc_svnames(); - - index = read_config_file(conf_file, svn); - - rc = ret = 0; - - for (cnt = 0; cnt < index; cnt++) { - - /* - * Check for more data. - */ - if (svn[cnt].svn_path[0] == '\0') { - /* - * This was set when reading sv.conf. After the last - * line svn_path was set to \0, so we are finished. - * We shouldn't get here, but put this in just in - * case. - */ - break; - } - rc = enable_dev(&svn[cnt]); - if (rc && !ret) - ret = rc; - } - - sv_cfg_close(); - - return (ret); -} - - -/* LINT - not static as fwcadm uses it */ -static int -enable_one_sv(caddr_t path) -{ - sv_name_t svn; - int rc; - - sv_get_maxdevs(); - - bzero(&svn, sizeof (svn)); - (void) strncpy(svn.svn_path, path, sizeof (svn.svn_path)); - svn.svn_mode = (NSC_DEVICE | NSC_CACHE); - - /* force NULL termination */ - svn.svn_path[sizeof (svn.svn_path) - 1] = '\0'; - - rc = enable_dev(&svn); - sv_cfg_close(); - - return (rc); -} - - -static int -enable_dev(sv_name_t *svn) -{ - char buf[CFG_MAX_BUF]; - struct stat stb; - sv_conf_t svc; - int fd; - int sev; - int rc; - char *lcltag; - char *altname; - - sv_check_cluster(svn->svn_path); - sv_cfg_open(CFG_WRLOCK); - - bzero(&svc, sizeof (svc)); - - if (stat(svn->svn_path, &stb) != 0) { - warn(NULL, gettext("unable to access %s: %s"), - svn->svn_path, strerror(errno)); - return (1); - } - - if (!S_ISCHR(stb.st_mode)) { - warn(NULL, gettext("%s is not a character device - ignored"), - svn->svn_path); - return (1); - } - - svc.svc_major = major(stb.st_rdev); - svc.svc_minor = minor(stb.st_rdev); - (void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path)); - - fd = open(sv_rpath, O_RDONLY); - if (fd < 0) { - warn(NULL, gettext("unable to open %s: %s"), - svn->svn_path, strerror(errno)); - return (1); - } - - svc.svc_flag = svn->svn_mode; - svc.svc_error = spcs_s_ucreate(); - - /* first, check for duplicates */ - rc = cfg_get_canonical_name(cfg, svn->svn_path, &altname); - if (rc < 0) { - spcs_log("sv", NULL, gettext("Unable to parse config file")); - warn(NULL, gettext("Unable to parse config file")); - (void) close(fd); - return (1); - } - if (rc) { - error(NULL, gettext("'%s' has already been configured as " - "'%s'. Re-enter command with the latter name."), - svn->svn_path, altname); - } - - /* secondly, try to insert it into the dsvol config */ - if (implicit_tag && *implicit_tag) { - lcltag = implicit_tag; - } else if (cfg_cluster_tag && *cfg_cluster_tag) { - lcltag = cfg_cluster_tag; - } else { - lcltag = "-"; - } - rc = cfg_add_user(cfg, svn->svn_path, lcltag, "sv"); - if (CFG_USER_ERR == rc) { - spcs_log("sv", NULL, - gettext("%s: unable to put %s into dsvol cfg"), - program, svn->svn_path); - warn(NULL, gettext("unable to put %s into dsvol cfg"), - svn->svn_path); - (void) close(fd); - return (1); - } - cfg_changed = 1; - - if (CFG_USER_OK == rc) { - /* success */ - (void) close(fd); - return (0); - } - - if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) { - if ((CFG_USER_REPEAT == rc) && (SV_EENABLED == errno)) { - /* it's ok -- we were just double-checking */ - (void) close(fd); - return (0); - } - - spcs_log("sv", &svc.svc_error, - gettext("%s: unable to enable %s"), - program, svn->svn_path); - - warn(&svc.svc_error, gettext("unable to enable %s"), - svn->svn_path); - - /* remove it from dsvol, if we're the ones who put it in */ - if (CFG_USER_FIRST == rc) { - (void) cfg_rem_user(cfg, svn->svn_path, lcltag, "sv"); - } - (void) close(fd); - return (1); - } - - spcs_log("sv", NULL, gettext("%s: enabled %s"), - program, svn->svn_path); - - if (implicit_tag != NULL) { -#ifdef DEBUG - if (cfg_cluster_tag != NULL) { - error(NULL, - gettext("enable_dev: -C %s AND implicit_tag %s!"), - cfg_cluster_tag, implicit_tag); - } -#endif - - (void) snprintf(buf, sizeof (buf), "%s - %s", - svc.svc_path, implicit_tag); - } else { - (void) strcpy(buf, svc.svc_path); - } - - rc = 0; - if (cfg_put_cstring(cfg, "sv", buf, sizeof (buf)) < 0) { - warn(NULL, - gettext("unable to add %s to configuration storage: %s"), - svc.svc_path, cfg_error(&sev)); - rc = 1; - } - - cfg_changed = 1; - spcs_s_ufree(&svc.svc_error); - (void) close(fd); - - return (rc); -} - - -/* - * This routine parses the config file passed in via conf_file and - * stores the data in the svn array. The return value is the number - * of entries read from conf_file. If an error occurs the error() - * routine is called (which exits the program). - */ -static int -read_config_file(const caddr_t conf_file, sv_name_t svn[]) -{ - char line[1024], rdev[1024], junk[1024]; - struct stat stb; - int lineno; - int cnt, i; - int index = 0; /* Current location in svn array */ - sv_name_t *cur_svn; /* Pointer to svn[index] */ - FILE *fp; - - if (access(conf_file, R_OK) != 0 || - stat(conf_file, &stb) != 0 || - !S_ISREG(stb.st_mode)) { - error(NULL, gettext("cannot read config file %s"), conf_file); - } - - if ((fp = fopen(conf_file, "r")) == NULL) { - error(NULL, gettext("unable to open config file %s: %s"), - conf_file, strerror(errno)); - } - - lineno = 0; - - while (fgets(line, sizeof (line), fp) != NULL) { - lineno++; - - i = strlen(line); - - if (i < 1) - continue; - - if (line[i-1] == '\n') - line[i-1] = '\0'; - else if (i == (sizeof (line) - 1)) { - warn(NULL, gettext( - "line %d: line too long -- should be less than %d characters"), - lineno, (sizeof (line) - 1)); - warn(NULL, gettext("line %d: ignored"), lineno); - } - - /* - * check for comment line. - */ - if (line[0] == '#') - continue; - - cnt = sscanf(line, "%s %s", rdev, junk); - - if (cnt != 1 && cnt != 2) { - if (cnt > 0) { - warn(NULL, gettext("line %d: invalid format"), - lineno); - warn(NULL, gettext("line %d: ignored"), lineno); - } - continue; - } - - rdev[sizeof (rdev) - 1] = '\0'; - - cur_svn = &svn[index]; /* For easier reading below */ - - if (strlen(rdev) >= sizeof (cur_svn->svn_path)) { - warn(NULL, gettext( - "line %d: raw device name (%s) longer than %d characters"), - lineno, rdev, - (sizeof (cur_svn->svn_path) - 1)); - warn(NULL, gettext("line %d: ignored"), lineno); - continue; - } - - (void) strcpy(cur_svn->svn_path, rdev); - cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE); - - index++; - } - - /* Set the last path to NULL */ - svn[index].svn_path[0] = '\0'; - - (void) fclose(fp); - - return (index); -} - - -/* - * Disable the device from the kernel configuration. - * - * RETURN: - * 0 on success - * non-zero on failure. - * - * Failures are reported to the user. - */ -static int -disable_dev(const caddr_t path) -{ - struct stat stb; - sv_conf_t svc; - int fd; - - sv_check_cluster(path); - - if (stat(path, &stb) < 0) { - svc.svc_major = (major_t)-1; - svc.svc_minor = (minor_t)-1; - } else { - svc.svc_major = major(stb.st_rdev); - svc.svc_minor = minor(stb.st_rdev); - } - - if ((fd = open(sv_rpath, O_RDONLY)) < 0) { - warn(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return (-1); - } - - (void) strcpy(svc.svc_path, path); - svc.svc_error = spcs_s_ucreate(); - - /* - * Issue the ioctl to attempt to disable this device. Note that all - * the libdscfg details are handled elsewhere. - */ - if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) { - if (errno != SV_EDISABLED) { - spcs_log("sv", &svc.svc_error, - gettext("%s: unable to disable %s"), - program, path); - - warn(&svc.svc_error, - gettext("unable to disable %s"), path); - (void) close(fd); - return (-1); - } - } - - spcs_log("sv", NULL, gettext("%s: disabled %s"), program, path); - - spcs_s_ufree(&svc.svc_error); - (void) close(fd); - - return (0); -} - - -static void -print_cluster_tag(const int setnumber) -{ - char buf[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - - bzero(buf, sizeof (buf)); - (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber); - - (void) cfg_get_cstring(cfg, key, buf, sizeof (buf)); - - if (*buf != '\0') { - if (strcmp(buf, "-") == 0) { - (void) printf(" [%s]", gettext("local to node")); - } else { - (void) printf(" [%s: %s]", gettext("cluster"), buf); - } - } -} - - -/* LINT - not static as fwcadm uses it */ -static void -print_sv(int verbose) -{ - sv_name_t *svn, *svn_system; /* Devices in system */ - sv_list_t svl_system; - int fd, i; - int setnumber; - - sv_check_cluster(NULL); - sv_cfg_open(CFG_RDLOCK); - - svn_system = sv_alloc_svnames(); - - if ((fd = open(sv_rpath, O_RDONLY)) < 0) { - (void) printf(gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return; - } - - /* Grab the system list from the driver */ - svl_system.svl_count = sv_max_devices; - svl_system.svl_names = &svn_system[0]; - svl_system.svl_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) { - error(&svl_system.svl_error, gettext("unable to get list")); - } - - spcs_s_ufree(&svl_system.svl_error); - (void) close(fd); - - /* - * We build a hashmap out of the entries from the config file to make - * searching faster. We end up taking a performance hit when the # of - * volumes is small, but for larger configurations it's a - * HUGE improvement. - */ - - /* build the hashtable */ - cfg_rewind(cfg, CFG_SEC_CONF); - create_cfg_hash(); - - /* - * For each volume found from the kernel, print out - * info about it from the kernel. - */ - for (i = 0; i < svl_system.svl_count; i++) { - if (*svn_system[i].svn_path == '\0') { - break; - } - - svn = &svn_system[i]; - if (svn->svn_mode == 0) { -#ifdef DEBUG - (void) printf(gettext("%s [kernel guard]\n"), - svn->svn_path); -#endif - continue; - } - /* get sv entry from the hashtable */ - if ((setnumber = find_in_hash(svn->svn_path)) != -1) { - (void) printf("%-*s", STATWIDTH, svn->svn_path); - - if (verbose) { - print_cluster_tag(setnumber); - } - - (void) printf("\n"); - - } else { - /* - * We didn't find the entry in the hashtable. Let - * the user know that the persistent storage is - * inconsistent with the kernel configuration. - */ - if (cfg_cluster_tag == NULL) - warn(NULL, gettext( - "%s is configured, but not in the " - "config storage"), svn->svn_path); - } - } - - /* free up the hashtable */ - destroy_hashtable(); - - sv_cfg_close(); -} - - -/* LINT - not static as fwcadm uses it */ -static int -disable_sv(char *conf_file) -{ - sv_name_t *svn, *svn_system; /* Devices in system */ - sv_list_t svl_system; - int fd, i, setnumber; - int rc, ret; - - svn_system = sv_alloc_svnames(); - - rc = ret = 0; - - if (conf_file == NULL) { - if ((fd = open(sv_rpath, O_RDONLY)) < 0) { - (void) printf(gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return (1); - } - - /* Grab the system list from the driver */ - svl_system.svl_count = sv_max_devices; - svl_system.svl_names = &svn_system[0]; - svl_system.svl_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_LIST, &svl_system) < 0) { - error(&(svl_system.svl_error), - gettext("unable to get list")); - } - - spcs_s_ufree(&(svl_system.svl_error)); - (void) close(fd); - } else { - svl_system.svl_count = read_config_file(conf_file, svn_system); - } - - - for (i = 0; i < svl_system.svl_count; i++) { - if (*svn_system[i].svn_path == '\0') - break; - - svn = &svn_system[i]; - - sv_check_cluster(svn->svn_path); - sv_cfg_open(CFG_WRLOCK); - create_cfg_hash(); - rc = 0; - if ((setnumber = find_in_hash(svn->svn_path)) != -1) { - if ((rc = disable_dev(svn->svn_path)) != -1) { - remove_from_cfgfile(svn->svn_path, setnumber); - } else if (errno == SV_ENODEV) { - remove_from_cfgfile(svn->svn_path, setnumber); - } - } else { - /* warn the user that we didn't find it in cfg file */ - warn(NULL, gettext( - "%s was not found in the config storage"), - svn->svn_path); - /* try to disable anyway */ - (void) disable_dev(svn->svn_path); - rc = 1; - } - - sv_cfg_close(); - destroy_hashtable(); - - if (rc && !ret) - ret = rc; - } - - return (ret); -} - - -/* LINT - not static as fwcadm uses it */ -static int -disable_one_sv(char *path) -{ - int setnumber; - int rc; - - sv_get_maxdevs(); - sv_check_cluster(path); - sv_cfg_open(CFG_WRLOCK); - - create_cfg_hash(); - if ((setnumber = find_in_hash(path)) != -1) { - /* remove from kernel */ - if ((rc = disable_dev(path)) == 0) { - /* remove the cfgline */ - remove_from_cfgfile(path, setnumber); - } else if (errno == SV_ENODEV) { - remove_from_cfgfile(path, setnumber); - } - } else { - /* warn the user that we didn't find it in cfg file */ - warn(NULL, - gettext("%s was not found in the config storage"), path); - /* still attempt to remove */ - (void) disable_dev(path); - rc = 1; - } - destroy_hashtable(); - - sv_cfg_close(); - return (rc); -} - - -static void -compare_tag(char *path) -{ - char buf[CFG_MAX_BUF], vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - int found, setnumber, i; - char *tag; - - sv_check_cluster(path); - cfg_resource(cfg, (char *)NULL); /* reset */ - cfg_rewind(cfg, CFG_SEC_CONF); - -#ifdef DEBUG - if (cfg_cluster_tag != NULL && implicit_tag != NULL) { - error(NULL, gettext("compare_tag: -C %s AND implicit_tag %s!"), - cfg_cluster_tag, implicit_tag); - } -#endif - - if (cfg_cluster_tag != NULL) - tag = cfg_cluster_tag; - else if (implicit_tag != NULL) - tag = implicit_tag; - else - tag = "-"; - - found = 0; - for (i = 0; i < sv_max_devices; i++) { - setnumber = i + 1; - (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) { - break; - } - - if (sscanf(buf, "%s - %s", vol, cnode) != 2) { - continue; - } - - if (strcmp(path, vol) == 0) { - found = 1; - break; - } - } - - if (!found) { - warn(NULL, gettext("unable to find %s in the configuration"), - path); - return; - } - - /* have name match, compare cnode to new tag */ - - if (strcmp(tag, cnode) == 0) { - /* cluster tags match */ - return; - } - - /* need to change the cluster tag */ - - (void) snprintf(key, sizeof (key), "sv.set%d.cnode", setnumber); - if (cfg_put_cstring(cfg, key, tag, strlen(tag)) < 0) { - warn(NULL, - gettext("unable to change cluster tag for %s"), path); - return; - } - - cfg_changed = 1; - - /* change "-" tags to "" for display purposes */ - - if (strcmp(tag, "-") == 0) - tag = ""; - - if (strcmp(cnode, "-") == 0) - (void) strcpy(cnode, ""); - - (void) printf( - gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\"\n"), - program, path, cnode, tag); - - spcs_log("sv", NULL, - gettext("%s: changed cluster tag for %s from \"%s\" to \"%s\""), - program, path, cnode, tag); -} - - -/* LINT - not static as fwcadm uses it */ -static void -compare_sv(char *conf_file) -{ - sv_name_t *svn_config; /* Devices in config file */ - sv_name_t *svn_system; /* Devices in system */ - sv_name_t *enable; /* Devices that need enabled */ - sv_list_t svl_system; - int config_cnt; - int sys_cnt = 0; - int setnumber, i, j; - int index = 0; /* Index in enable[] */ - int found; - int fd0; - - svn_config = sv_alloc_svnames(); - svn_system = sv_alloc_svnames(); - enable = sv_alloc_svnames(); - - bzero(svn_system, sizeof (svn_system)); - bzero(&svl_system, sizeof (svl_system)); - bzero(enable, sizeof (enable)); - - /* - * Read the configuration file - * The return value is the number of entries - */ - config_cnt = read_config_file(conf_file, svn_config); - - if ((fd0 = open(sv_rpath, O_RDONLY)) < 0) - error(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - - /* Grab the system list from the driver */ - svl_system.svl_count = sv_max_devices; - svl_system.svl_names = &svn_system[0]; - svl_system.svl_error = spcs_s_ucreate(); - - if (ioctl(fd0, SVIOC_LIST, &svl_system) < 0) { - error(&svl_system.svl_error, gettext("unable to get list")); - } - - spcs_s_ufree(&svl_system.svl_error); - (void) close(fd0); - - /* - * Count the number of devices in the system. - * The last entry in the array has '\0' for a path name. - */ - for (j = 0; j < sv_max_devices; j++) { - if (svn_system[j].svn_path[0] != '\0') { - sys_cnt++; - } else { - break; - } - } - /* - * Compare the configuration array with the system array. - * Mark any differences and disable conflicting devices. - */ - for (i = 0; i < config_cnt; i++) { - found = 0; - for (j = 0; j < sys_cnt; j++) { - if (svn_system[j].svn_path[0] == '\0' || - svn_system[j].svn_mode == 0) - continue; - - /* Check to see if path matches */ - if (strcmp(svn_system[j].svn_path, - svn_config[i].svn_path) == 0) { - /* Found a match */ - svn_system[j].svn_path[0] = '\0'; - found++; - break; - } - } - - if (!found) { - /* Minor number not in system = > enable device */ - enable[index].svn_mode = svn_config[i].svn_mode; - (void) strcpy(enable[index].svn_path, - svn_config[i].svn_path); - index++; - } - } - - /* Disable any devices that weren't in the config file */ - for (j = 0; j < sys_cnt; j++) { - sv_check_cluster(NULL); - sv_cfg_open(CFG_WRLOCK); - create_cfg_hash(); - if (svn_system[j].svn_path[0] != '\0' && - svn_system[j].svn_mode != 0) { - (void) printf(gettext("%s: disabling sv: %s\n"), - program, svn_system[j].svn_path); - if (disable_dev(svn_system[j].svn_path) == 0) { - setnumber = - find_in_hash(svn_system[j].svn_path); - if (setnumber != -1) { - /* the volume was found in cfg store */ - remove_from_cfgfile( - svn_system[j].svn_path, setnumber); - } - } - } - sv_cfg_close(); - destroy_hashtable(); - } - - while (index) { - /* - * Config file doesn't match system => enable the devices - * in enable[] - */ - index--; - (void) printf(gettext("%s: enabling new sv: %s\n"), - program, enable[index].svn_path); - (void) enable_dev(&enable[index]); - } - - /* - * Search for entries where the cluster tag has changed. - */ - sv_check_cluster(NULL); - sv_cfg_open(CFG_WRLOCK); - - for (i = 0; i < sv_max_devices; i++) { - if (svn_config[i].svn_path[0] == '\0') - break; - - compare_tag(svn_config[i].svn_path); - } - - sv_cfg_close(); -} - - -/* - * We assume that the volume is already enabled and we can only - * be changing the cluster tag. Anything else is an error. - */ -/* LINT - not static as fwcadm uses it */ -static void -compare_one_sv(char *path) -{ - sv_get_maxdevs(); - sv_check_cluster(NULL); - sv_cfg_open(CFG_WRLOCK); - - compare_tag(path); - - sv_cfg_close(); -} - -/* - * Read all sets from the libdscfg configuration file, and store everything in - * the hashfile. - * - * We assume that the config file has been opened & rewound for us. We store - * the volume name as the key, and the setnumber where we found it as the data. - * - * The caller can pass in a pointer to the maximum number of volumes, or - * a pointer to NULL, specifying we want 'all' the volumes. The table is - * searched using find_in_hash. - */ -static void -create_cfg_hash() -{ - char key[CFG_MAX_KEY], buf[CFG_MAX_BUF]; - char vol[CFG_MAX_BUF], cnode[CFG_MAX_BUF]; - int setnumber; - ENTRY item; - - if (hcreate((size_t)sv_max_devices) == 0) - error(NULL, gettext("unable to create hash table")); - - for (setnumber = 1; /* CSTYLED */; setnumber++) { - (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); - if (cfg_get_cstring(cfg, key, buf, sizeof (buf)) < 0) - break; - - if (sscanf(buf, "%s - %s", vol, cnode) != 2) { - continue; - } - - item.key = strdup(vol); - item.data = (void *)setnumber; - if (hsearch(item, ENTER) == NULL) { - error(NULL, - gettext("unable to add entry to hash table")); - } - } -} - -/* - * Function to search the hash for a specific volume. If it is found, - * we return the set number. If it isn't found, we return -1 - */ -static int -find_in_hash(char *path) -{ - ENTRY *found_entry, item; - int retval = -1; - - item.key = path; - - if ((found_entry = hsearch(item, FIND)) != NULL) { - retval = (int)found_entry->data; - } - - return (retval); -} - -/* - * Just a wrapper to destory the hashtable. At some point in the future we - * might want to do something more.... For instance, verify that the cfg - * database and the kernel configuration match (?) Just an idea. - */ -static void -destroy_hashtable() -{ - hdestroy(); -} - -/* - * This function will remove a particular set from the config file. - * - * We make a whole host of assumptions: - * o the hashfile is up to date; - * o The config file has been opened with a WRLOCK for us. - */ -static void -remove_from_cfgfile(char *path, int setnumber) -{ - char key[CFG_MAX_KEY]; - int sev; - char *lcltag; - - /* attempt to remove the volume from config storage */ - (void) snprintf(key, sizeof (key), "sv.set%d", setnumber); - if (cfg_put_cstring(cfg, key, NULL, 0) < 0) { - warn(NULL, gettext("unable to remove %s from " - "config storage: %s"), path, cfg_error(&sev)); - } else { - if (implicit_tag && *implicit_tag) { - lcltag = implicit_tag; - } else if (cfg_cluster_tag && *cfg_cluster_tag) { - lcltag = cfg_cluster_tag; - } else { - lcltag = "-"; - } - if (cfg_rem_user(cfg, path, lcltag, "sv") != CFG_USER_LAST) { - warn(NULL, gettext("unable to remove %s from dsvol"), - path); - } - cfg_changed = 1; - } -} diff --git a/usr/src/cmd/avs/sv/svadm.h b/usr/src/cmd/avs/sv/svadm.h deleted file mode 100644 index f1dfa35c1e..0000000000 --- a/usr/src/cmd/avs/sv/svadm.h +++ /dev/null @@ -1,50 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SVADM_H -#define _SVADM_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Functions exported from svadm.o for the use of fwcadm.o - */ - -static void compare_one_sv(char *); -static void compare_sv(char *); -static int disable_one_sv(char *); -static int disable_sv(char *); -static int enable_one_sv(char *); -static int enable_sv(char *); -static void print_sv(int); - -#ifdef __cplusplus -} -#endif - -#endif /* _SVADM_H */ diff --git a/usr/src/cmd/avs/sv/svboot.c b/usr/src/cmd/avs/sv/svboot.c deleted file mode 100644 index ccee741c1f..0000000000 --- a/usr/src/cmd/avs/sv/svboot.c +++ /dev/null @@ -1,533 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mkdev.h> -#include <sys/param.h> -#include <fcntl.h> -#include <stdarg.h> -#include <stdlib.h> -#include <strings.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> -#include <unistd.h> -#include <libgen.h> -#include <nsctl.h> - -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_u.h> -#include <sys/unistat/spcs_errors.h> - -#include <sys/nsctl/sv.h> -#include <sys/nsctl/sv_impl.h> - -#include <sys/nsctl/cfg.h> - - -static int sv_max_devices; - - -/* - * Pathnames. - */ - -static const caddr_t sv_rpath = SV_DEVICE; - -/* - * Functions. - */ - -static void resume_dev(int, sv_name_t *); -static void suspend_dev(int, const caddr_t); -static int read_libcfg(sv_name_t svn[]); -static void resume_sv(); -static void suspend_sv(); -static void prepare_unload_sv(); - - -/* - * support for the special cluster tag "local" to be used with -C in a - * cluster for local volumes. - */ - -#define SV_LOCAL_TAG "local" - -static caddr_t program; -static caddr_t cfg_cluster_tag; - - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("usage:\n")); - - (void) fprintf(stderr, gettext( - "\t%s -h help\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -r resume all sv devices\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s [-C tag] -s suspend all sv devices\n"), program); - - (void) fprintf(stderr, gettext( - "\t%s -u prepare for sv unload\n"), program); -} - - -static void -message(caddr_t prefix, spcs_s_info_t *status, caddr_t string, va_list ap) -{ - (void) fprintf(stderr, "%s: %s: ", program, prefix); - (void) vfprintf(stderr, string, ap); - (void) fprintf(stderr, "\n"); - - if (status) { - spcs_s_report(*status, stderr); - spcs_s_ufree(status); - } -} - - -static void -error(spcs_s_info_t *status, caddr_t string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("error"), status, string, ap); - - va_end(ap); - exit(1); -} - - -static void -warn(spcs_s_info_t *status, caddr_t string, ...) -{ - va_list ap; - va_start(ap, string); - - message(gettext("warning"), status, string, ap); - - va_end(ap); -} - - -static void -sv_get_maxdevs(void) -{ - sv_name_t svn[1]; - sv_list_t svl; - int fd; - - if (sv_max_devices > 0) - return; - - fd = open(sv_rpath, O_RDONLY); - if (fd < 0) - error(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - - bzero(&svl, sizeof (svl)); - bzero(&svn[0], sizeof (svn)); - - svl.svl_names = &svn[0]; - svl.svl_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_LIST, &svl) < 0) - error(&svl.svl_error, gettext("unable to get max devs")); - - spcs_s_ufree(&svl.svl_error); - sv_max_devices = svl.svl_maxdevs; - - (void) close(fd); -} - - -static sv_name_t * -sv_alloc_svnames(void) -{ - sv_name_t *svn = NULL; - - sv_get_maxdevs(); - - svn = calloc(sv_max_devices, sizeof (*svn)); - if (svn == NULL) { - error(NULL, "unable to allocate %ld bytes of memory", - sv_max_devices * sizeof (*svn)); - } - - return (svn); -} - -int -main(int argc, char *argv[]) -{ - extern int optind; - extern char *optarg; - int Cflag, resume, suspend, unload; - int opt; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("svboot"); - - program = strdup(basename(argv[0])); - - Cflag = unload = resume = suspend = 0; - - while ((opt = getopt(argc, argv, "C:hrsu")) != EOF) { - switch (opt) { - - case 'C': - if (Cflag) { - warn(NULL, - gettext("-C specified multiple times")); - usage(); - exit(2); - /* NOTREACHED */ - } - - Cflag++; - cfg_cluster_tag = optarg; - break; - - case 'r': - resume++; - break; - - case 's': - suspend++; - break; - - case 'u': - unload++; - break; - - case 'h': - usage(); - exit(0); - - case '?': /* FALLTHRU */ - - default: - usage(); - exit(2); - /* NOTREACHED */ - } - } - - - /* - * Usage checks - */ - - if ((resume + suspend + unload) > 1) { - warn(NULL, gettext("-r , -s and -u are mutually exclusive")); - usage(); - exit(2); - } - - if (!resume && !suspend && !unload) { - warn(NULL, gettext("option required")); - usage(); - exit(2); - } - - if (optind != argc) { - usage(); - exit(2); - } - - - /* - * Check for the special (local) cluster tag - */ - - if (cfg_cluster_tag != NULL && - strcmp(cfg_cluster_tag, SV_LOCAL_TAG) == 0) - cfg_cluster_tag = "-"; - - /* - * Process commands - */ - - if (resume) - resume_sv(); - else if (suspend) - suspend_sv(); - else if (unload) - prepare_unload_sv(); - - return (0); -} - - -static void -resume_sv() -{ - int index; - sv_name_t *svn; - int cnt; - int fd; - - svn = sv_alloc_svnames(); - - index = read_libcfg(svn); - - fd = open(sv_rpath, O_RDONLY); - if (fd < 0) { - warn(NULL, gettext("unable to open %s: %s"), - svn->svn_path, strerror(errno)); - return; - } - - for (cnt = 0; cnt < index; cnt++) { - - /* - * Check for more data. - */ - if (svn[cnt].svn_path[0] == '\0') { - /* - * This was set when reading sv.conf. After the last - * line svn_path was set to \0, so we are finished. - * We shouldn't get here, but put this in just in - * case. - */ - break; - } - resume_dev(fd, &svn[cnt]); - } - (void) close(fd); -} - - -static void -resume_dev(int fd, sv_name_t *svn) -{ - struct stat stb; - sv_conf_t svc; - - bzero(&svc, sizeof (svc)); - - if (stat(svn->svn_path, &stb) != 0) { - warn(NULL, gettext("unable to access %s: %s"), - svn->svn_path, strerror(errno)); - return; - } - - svc.svc_major = major(stb.st_rdev); - svc.svc_minor = minor(stb.st_rdev); - (void) strncpy(svc.svc_path, svn->svn_path, sizeof (svc.svc_path)); - - svc.svc_flag = svn->svn_mode; - svc.svc_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_ENABLE, &svc) < 0) { - spcs_log("sv", &svc.svc_error, - gettext("%s: unable to resume %s"), - program, svn->svn_path); - - warn(&svc.svc_error, gettext("unable to resume %s"), - svn->svn_path); - return; - } - - spcs_log("sv", NULL, gettext("%s: resume %s"), - program, svn->svn_path); - - spcs_s_ufree(&svc.svc_error); -} - - -/* - * This routine parses the config file and - * stores the data in the svn array. The return value is the number - * of entries read from conf_file. If an error occurs the error() - * routine is called (which exits the program). - */ -static int -read_libcfg(sv_name_t svn[]) -{ - char rdev[CFG_MAX_BUF]; - char key[CFG_MAX_KEY]; - struct stat stb; - int i; - int setnumber; - int index = 0; /* Current location in svn array */ - sv_name_t *cur_svn; /* Pointer to svn[index] */ - CFGFILE *cfg; - - if ((cfg = cfg_open("")) == NULL) { - error(NULL, gettext("Error opening config: %s"), - strerror(errno)); - } - - cfg_resource(cfg, cfg_cluster_tag); - if (!cfg_lock(cfg, CFG_RDLOCK)) { - error(NULL, gettext("Error locking config: %s"), - strerror(errno)); - } - - for (i = 0; /*CSTYLED*/; i++) { - setnumber = i + 1; - - bzero(rdev, CFG_MAX_BUF); - (void) snprintf(key, sizeof (key), "sv.set%d.vol", setnumber); - if (cfg_get_cstring(cfg, key, rdev, sizeof (rdev)) < 0) - break; - - /* Check to see if the raw device is present */ - if (stat(rdev, &stb) != 0) { - warn(NULL, gettext("unable to access %s: %s"), - rdev, strerror(errno)); - continue; - } - - if (!S_ISCHR(stb.st_mode)) { - warn(NULL, gettext("%s is not a character device"), - rdev); - continue; - } - - cur_svn = &svn[index]; /* For easier reading below */ - - if (strlen(rdev) >= sizeof (cur_svn->svn_path)) { - warn(NULL, gettext( - "raw device name (%s) longer than %d characters"), - rdev, - (sizeof (cur_svn->svn_path) - 1)); - continue; - } - - (void) strcpy(cur_svn->svn_path, rdev); - cur_svn->svn_mode = (NSC_DEVICE | NSC_CACHE); - - index++; - } - - cfg_close(cfg); - - /* Set the last path to NULL */ - svn[index].svn_path[0] = '\0'; - - return (index); -} - - -static void -suspend_dev(int fd, const caddr_t path) -{ - struct stat stb; - sv_conf_t svc; - - if (stat(path, &stb) < 0) { - svc.svc_major = (major_t)-1; - svc.svc_minor = (minor_t)-1; - } else { - svc.svc_major = major(stb.st_rdev); - svc.svc_minor = minor(stb.st_rdev); - } - - (void) strcpy(svc.svc_path, path); - svc.svc_error = spcs_s_ucreate(); - - if (ioctl(fd, SVIOC_DISABLE, &svc) < 0) { - if (errno != SV_EDISABLED) { - spcs_log("sv", &svc.svc_error, - gettext("%s: unable to suspend %s"), - program, path); - - warn(&svc.svc_error, - gettext("unable to suspend %s"), path); - return; - } - } - - spcs_log("sv", NULL, gettext("%s: suspend %s"), program, path); - - spcs_s_ufree(&svc.svc_error); -} - - -static void -suspend_sv(void) -{ - sv_name_t *svn, *svn_system; /* Devices in system */ - sv_list_t svl_system; - int i; - int fd; - - svn_system = sv_alloc_svnames(); - - svl_system.svl_count = read_libcfg(svn_system); - - if ((fd = open(sv_rpath, O_RDONLY)) < 0) { - warn(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return; - } - - for (i = 0; i < svl_system.svl_count; i++) { - if (*svn_system[i].svn_path == '\0') - break; - - svn = &svn_system[i]; - suspend_dev(fd, svn->svn_path); - } - - (void) close(fd); -} - - -/* - * Check kernel's sv_ndevices and thread sets, - * if empty then change kernel state to allow unload, - * and sleep SV_WAIT_UNLAOD (10 seconds). - * - * Only called in pkgrm time. - */ -static void -prepare_unload_sv(void) -{ - int fd; - int rc = 0; - - if ((fd = open(sv_rpath, O_RDONLY)) < 0) { - warn(NULL, gettext("unable to open %s: %s"), - sv_rpath, strerror(errno)); - return; - } - - if (ioctl(fd, SVIOC_UNLOAD, &rc) < 0) - error(NULL, gettext("unable to unload")); - - if (rc != 0) - error(NULL, gettext("still has active devices or threads")); - - (void) close(fd); -} diff --git a/usr/src/cmd/avs/svc/Makefile b/usr/src/cmd/avs/svc/Makefile deleted file mode 100644 index 751aa9e5cc..0000000000 --- a/usr/src/cmd/avs/svc/Makefile +++ /dev/null @@ -1,54 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -include ../../Makefile.cmd - -XML = nws_scm.xml nws_sv.xml nws_ii.xml nws_rdc.xml nws_rdcsyncd.xml -SHFILES = $(XML) - -ROOTSVCSYSFILES = $(XML:%=$(ROOTSVCSYSTEM)/%) - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(SHFILES) - -lint: - -install: all $(ROOTSVCSYSFILES) - -clean: - $(RM) *.xml - -$(SHFILES): $(XML:%=manifest/%) - $(RM) $(@F) - $(CP) $(@F:%=manifest/%) . - -FILEMODE = 0444 - -$(ROOTSVCSYSFILES): $(SHFILES) - - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/svc/manifest/nws_ii.xml b/usr/src/cmd/avs/svc/manifest/nws_ii.xml deleted file mode 100644 index 6a1c330db5..0000000000 --- a/usr/src/cmd/avs/svc/manifest/nws_ii.xml +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- -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 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Service manifest for Availability Suite init. ---> - -<service_bundle type='manifest' name='SUNWscmr:nws_ii'> - -<service - name='system/nws_ii' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency - name='nws_ii_sv' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/nws_sv' /> - </dependency> - - <!-- - We need to make sure that no user filesystems can mount until - AVS has configured, since user filesystems may be mounted on - volumes under AVS control - --> - <dependent - name='nws_ii-local-fs' - grouping='optional_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/local' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-ii %m' - timeout_seconds='300' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-ii %m' - timeout_seconds='600' /> - - <property_group - name='startd' - type='framework'> - <propval - name='duration' - type='astring' - value='transient' /> - </property_group> - - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Network Storage Instant Image Init service. - </loctext> - </common_name> - - <documentation> - <manpage - title='iiadm' - section='1M' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/avs/svc/manifest/nws_rdc.xml b/usr/src/cmd/avs/svc/manifest/nws_rdc.xml deleted file mode 100644 index c2a231bf64..0000000000 --- a/usr/src/cmd/avs/svc/manifest/nws_rdc.xml +++ /dev/null @@ -1,108 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- -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 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Service manifest for Availability Suite init. ---> - -<service_bundle type='manifest' name='SUNWscmr:nws_rdc'> - -<service - name='system/nws_rdc' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency - name='nws_rdc_sv' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/nws_sv' /> - </dependency> - - <dependency - name='nws_rdc_ii' - type='service' - grouping='optional_all' - restart_on='none'> - <service_fmri value='svc:/system/nws_ii' /> - </dependency> - - <!-- - We need to make sure that no user filesystems can mount until - AVS has configured, since user filesystems may be mounted on - volumes under AVS control - --> - <dependent - name='nws_rdc-local-fs' - grouping='optional_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/local' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-rdc %m' - timeout_seconds='300' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-rdc %m' - timeout_seconds='600' /> - - <property_group - name='startd' - type='framework'> - <propval - name='duration' - type='astring' - value='transient' /> - </property_group> - - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Network Storage Remote Data Replication Init service. - </loctext> - </common_name> - - <documentation> - <manpage - title='sndrd' - section='1rdc' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml b/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml deleted file mode 100644 index b6b416beb4..0000000000 --- a/usr/src/cmd/avs/svc/manifest/nws_rdcsyncd.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- -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 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Service manifest for Availability Suite init. ---> - -<service_bundle type='manifest' name='SUNWscmr:nws_rdcsyncd'> - -<service - name='system/nws_rdcsyncd' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency - name='nws_rdcsyncd_rdc' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/nws_rdc' /> - </dependency> - - <!-- - This dependency is necessary to make sure that - network/rpc/bind:default has started. Since rpc/bind is Unstable, - the dependency on it cannot be explicitly specified. - --> - <dependency - name='nws_rdc_multi-user' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/milestone/multi-user' /> - </dependency> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-rdcsyncd %m' - timeout_seconds='60' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-rdcsyncd %m' - timeout_seconds='20' /> - - <property_group - name='startd' - type='framework'> - <propval - name='duration' - type='astring' - value='transient' /> - </property_group> - - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Network Storage Remote Data Replication Syncd service. - </loctext> - </common_name> - - <documentation> - <manpage - title='sndrsyncd' - section='1rdc' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/avs/svc/manifest/nws_scm.xml b/usr/src/cmd/avs/svc/manifest/nws_scm.xml deleted file mode 100644 index 7714afbeb9..0000000000 --- a/usr/src/cmd/avs/svc/manifest/nws_scm.xml +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- -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 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Service manifest for Availability Suite init. ---> - -<service_bundle type='manifest' name='SUNWscmr:nws_scm'> - -<service - name='system/nws_scm' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <!-- - We want our services to start up after single-user mode. - This also satisfies our dependency on system/filesystem/minimal. - We need to make sure we have /usr and /var mounted. /usr, because - that's where our software is installed. /var, since that's where - ds.log is stored. Single-user also satisfies the nws_rdc dependency - on system/identity:node. - --> - <dependency - name='nws_scm-single-user' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/milestone/single-user' /> - </dependency> - - <!-- - We need to make sure that all device links have been created in - the /dev tree, and that all local and fabric devices are - available. We also need to make sure that vxvm and svm devices - have been configured at this point. Right now, the - 'milestone/devices' takes care of all of these. - --> - <dependency - name='nws_scm-dev-milestone' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/milestone/devices' /> - </dependency> - - <!-- - We need to make sure that no user filesystems can mount until - AVS has configured, since user filesystems may be mounted on - volumes under AVS control - --> - <dependent - name='nws_scm-local-fs' - grouping='optional_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/local' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-scm %m' - timeout_seconds='180' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-scm %m' - timeout_seconds='180' /> - - <property_group - name='startd' - type='framework'> - <propval - name='duration' - type='astring' - value='transient' /> - </property_group> - - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Network Storage Core Init service. - </loctext> - </common_name> - - <documentation> - <manpage - title='scmadm' - section='1scm' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/avs/svc/manifest/nws_sv.xml b/usr/src/cmd/avs/svc/manifest/nws_sv.xml deleted file mode 100644 index cb62572431..0000000000 --- a/usr/src/cmd/avs/svc/manifest/nws_sv.xml +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- -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 2008 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Service manifest for Availability Suite init. ---> - -<service_bundle type='manifest' name='SUNWscmr:nws_sv'> - -<service - name='system/nws_sv' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency - name='nws_sv_scm' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/nws_scm' /> - </dependency> - - <!-- - We need to make sure that no user filesystems can mount until - AVS has configured, since user filesystems may be mounted on - volumes under AVS control - --> - <dependent - name='nws_sv-local-fs' - grouping='optional_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/local' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-sv %m' - timeout_seconds='300' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-sv %m' - timeout_seconds='600' /> - - <property_group - name='startd' - type='framework'> - <propval - name='duration' - type='astring' - value='transient' /> - </property_group> - - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Network Storage Storage Volume Init service. - </loctext> - </common_name> - - <documentation> - <manpage - title='svadm' - section='1sv' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common index dcff6b3898..41de4dfdc2 100644 --- a/usr/src/cmd/mdb/Makefile.common +++ b/usr/src/cmd/mdb/Makefile.common @@ -70,7 +70,6 @@ COMMON_MODULES_KVM = \ hook \ neti \ idm \ - ii \ ip \ ipc \ ipp \ @@ -82,18 +81,15 @@ COMMON_MODULES_KVM = \ mpt_sas \ mr_sas \ nca \ - nsctl \ nsmb \ pmcs \ ptm \ qlc \ random \ - rdc \ s1394 \ scsi_vhci \ sctp \ sd \ - sdbc \ smbfs \ smbsrv \ sockfs \ @@ -102,7 +98,6 @@ COMMON_MODULES_KVM = \ srpt \ stmf \ stmf_sbd \ - sv \ ufs \ usba \ zfs diff --git a/usr/src/cmd/mdb/common/modules/ii/Makefile.com b/usr/src/cmd/mdb/common/modules/ii/Makefile.com deleted file mode 100644 index 40975cea69..0000000000 --- a/usr/src/cmd/mdb/common/modules/ii/Makefile.com +++ /dev/null @@ -1,24 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CPPFLAGS += -DNSC_MULTI_TERABYTE diff --git a/usr/src/cmd/mdb/common/modules/ii/ii.c b/usr/src/cmd/mdb/common/modules/ii/ii.c deleted file mode 100644 index 48bc03502b..0000000000 --- a/usr/src/cmd/mdb/common/modules/ii/ii.c +++ /dev/null @@ -1,427 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <stddef.h> - -#include <sys/types.h> -#include <sys/mdb_modapi.h> - -#include <sys/nsctl/nsctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_k.h> - - -#include <sys/nsctl/dsw.h> -#include <sys/nsctl/dsw_dev.h> - -#include <sys/nsctl/nsvers.h> - - -const mdb_bitmask_t bi_flags_bits[] = { - { "DSW_GOLDEN", DSW_GOLDEN, DSW_GOLDEN }, - { "DSW_COPYINGP", DSW_COPYINGP, DSW_COPYINGP }, - { "DSW_COPYINGM", DSW_COPYINGM, DSW_COPYINGM }, - { "DSW_COPYINGS", DSW_COPYINGS, DSW_COPYINGS }, - { "DSW_COPYINGX", DSW_COPYINGX, DSW_COPYINGX }, - { "DSW_BMPOFFLINE", DSW_BMPOFFLINE, DSW_BMPOFFLINE }, - { "DSW_SHDOFFLINE", DSW_SHDOFFLINE, DSW_SHDOFFLINE }, - { "DSW_MSTOFFLINE", DSW_MSTOFFLINE, DSW_MSTOFFLINE }, - { "DSW_OVROFFLINE", DSW_OVROFFLINE, DSW_OVROFFLINE }, - { "DSW_TREEMAP", DSW_TREEMAP, DSW_TREEMAP }, - { "DSW_OVERFLOW", DSW_OVERFLOW, DSW_OVERFLOW }, - { "DSW_SHDEXPORT", DSW_SHDEXPORT, DSW_SHDEXPORT }, - { "DSW_SHDIMPORT", DSW_SHDIMPORT, DSW_SHDIMPORT }, - { "DSW_VOVERFLOW", DSW_VOVERFLOW, DSW_VOVERFLOW }, - { "DSW_HANGING", DSW_HANGING, DSW_HANGING }, - { "DSW_CFGOFFLINE", DSW_CFGOFFLINE, DSW_CFGOFFLINE }, - { "DSW_OVRHDRDRTY", DSW_OVRHDRDRTY, DSW_OVRHDRDRTY }, - { "DSW_RESIZED", DSW_RESIZED, DSW_RESIZED }, - { "DSW_FRECLAIM", DSW_FRECLAIM, DSW_FRECLAIM }, - { NULL, 0, 0 } -}; - -const mdb_bitmask_t bi_state_bits[] = { - { "DSW_IOCTL", DSW_IOCTL, DSW_IOCTL }, - { "DSW_CLOSING", DSW_CLOSING, DSW_CLOSING }, - { "DSW_MSTTARGET", DSW_MSTTARGET, DSW_MSTTARGET }, - { "DSW_MULTIMST", DSW_MULTIMST, DSW_MULTIMST }, - { NULL, 0, 0 } -}; -static uintptr_t nextaddr; -/* - * Display a ii_fd_t - * Requires an address. - */ -/*ARGSUSED*/ -static int -ii_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - ii_fd_t fd; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_vread(&fd, sizeof (fd), addr) != sizeof (fd)) { - mdb_warn("failed to read ii_fd_t at 0x%p", addr); - return (DCMD_ERR); - } - - mdb_inc_indent(4); - mdb_printf("ii_info: 0x%p ii_bmp: %d ii_shd: %d ii_ovr: %d ii_optr: " - "0x%p\nii_oflags: 0x%x\n", fd.ii_info, fd.ii_bmp, fd.ii_shd, - fd.ii_ovr, fd.ii_optr, fd.ii_oflags); - mdb_dec_indent(4); - - return (DCMD_OK); -} - -/* - * displays a ii_info_dev structure. - */ -/*ARGSUSED*/ -static int -ii_info_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _ii_info_dev_t ipdev; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_vread(&ipdev, sizeof (ipdev), addr) != sizeof (ipdev)) { - mdb_warn("failed to read ii_info_dev_t at 0x%p", addr); - return (DCMD_ERR); - } - - mdb_inc_indent(4); - mdb_printf("bi_fd: 0x%p bi_iodev: 0x%p bi_tok: 0x%p\n", - ipdev.bi_fd, ipdev.bi_iodev, ipdev.bi_tok); - mdb_printf("bi_ref: %d bi_rsrv: %d bi_orsrv: %d\n", - ipdev.bi_ref, ipdev.bi_rsrv, ipdev.bi_orsrv); - - /* - * use nsc_fd to dump the fd details.... if present. - */ - if (ipdev.bi_fd) { - mdb_printf("nsc_fd structure:\n"); - mdb_inc_indent(4); - mdb_call_dcmd("nsc_fd", (uintptr_t)(ipdev.bi_fd), - flags, 0, NULL); - mdb_dec_indent(4); - } - mdb_dec_indent(4); - return (DCMD_OK); -} - -/* - * Displays an _ii_overflow structure - */ -/*ARGSUSED*/ -static int -ii_overflow(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _ii_overflow_t ii_overflow; - - nextaddr = 0; - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_vread(&ii_overflow, sizeof (ii_overflow), addr) - != sizeof (ii_overflow)) { - mdb_warn("failed to read ii_overflow_t at 0x%p", addr); - return (DCMD_ERR); - } - - mdb_inc_indent(4); - mdb_printf("_ii_overflow at 0x%p\n", addr); - mdb_printf("_ii_doverflow_t\n"); - mdb_inc_indent(4); - mdb_printf("ii_dvolname: %s\n", ii_overflow.ii_volname); - mdb_printf("ii_dhmagic: %x\n", ii_overflow.ii_hmagic); - mdb_printf("ii_dhversion: %x\n", ii_overflow.ii_hversion); - mdb_printf("ii_ddrefcnt: %x\n", ii_overflow.ii_drefcnt); - mdb_printf("ii_dflags: %x\n", ii_overflow.ii_flags); - mdb_printf("ii_dfreehead: %x\n", ii_overflow.ii_freehead); - mdb_printf("ii_dnchunks: %x\n", ii_overflow.ii_nchunks); - mdb_printf("ii_dunused: %x\n", ii_overflow.ii_unused); - mdb_printf("ii_dused: %x\n", ii_overflow.ii_used); - mdb_printf("ii_urefcnt: %x\n", ii_overflow.ii_urefcnt); - mdb_dec_indent(4); - - mdb_printf("ii_mutex: %x\n", ii_overflow.ii_mutex); - mdb_printf("ii_kstat_mutex: %x\n", ii_overflow.ii_kstat_mutex); - mdb_printf("ii_crefcnt: %d\n", ii_overflow.ii_crefcnt); - mdb_printf("ii_detachcnt: %d\n", ii_overflow.ii_detachcnt); - mdb_printf("ii_next: %x\n", ii_overflow.ii_next); - - mdb_printf("Overflow volume:\n"); - if (ii_overflow.ii_dev) - ii_info_dev((uintptr_t)ii_overflow.ii_dev, flags, 0, NULL); - - mdb_printf(" ii_ioname: %s\n", &ii_overflow.ii_ioname); - mdb_dec_indent(4); - - nextaddr = (uintptr_t)ii_overflow.ii_next; - return (DCMD_OK); -} -/*ARGSUSED*/ -static int -ii_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _ii_info_t ii_info = {0}; - char string[DSW_NAMELEN]; - - nextaddr = 0; - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_vread(&ii_info, sizeof (ii_info), addr) != sizeof (ii_info)) { - mdb_warn("failed to read ii_info_t at 0x%p", addr); - return (DCMD_ERR); - } - - mdb_printf( - "bi_next: 0x%p\n" - "bi_head: 0x%p\t" - "bi_sibling: 0x%p\n" - "bi_master: 0x%p\t" - "bi_nextmst: 0x%p\n", - ii_info.bi_next, ii_info.bi_head, ii_info.bi_sibling, - ii_info.bi_master, ii_info.bi_nextmst); - - mdb_printf("bi_mutex: 0x%p\n", ii_info.bi_mutex); - - /* - * Print out all the fds by using ii_info_dev - */ - mdb_printf("Cache master:\n"); - if (ii_info.bi_mstdev) - ii_info_dev((uintptr_t)ii_info.bi_mstdev, flags, 0, NULL); - - mdb_printf("Raw master:\n"); - if (ii_info.bi_mstrdev) - ii_info_dev((uintptr_t)ii_info.bi_mstrdev, flags, 0, NULL); - - mdb_printf("Cache shadow:\n"); - ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shddev)), - flags, 0, NULL); - - mdb_printf("Raw shadow:\n"); - ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_shdrdev)), - flags, 0, NULL); - - mdb_printf("Bitmap:\n"); - ii_info_dev((uintptr_t)(addr + offsetof(_ii_info_t, bi_bmpdev)), - flags, 0, NULL); - - mdb_printf("bi_keyname: %-*s\n", DSW_NAMELEN, ii_info.bi_keyname); - mdb_printf("bi_bitmap: 0x%p\n", ii_info.bi_bitmap); - - if ((ii_info.bi_cluster == NULL) || - (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_cluster) - != sizeof (string))) - string[0] = 0; - mdb_printf("bi_cluster: %s\n", string); - - if ((ii_info.bi_group == NULL) || - (mdb_vread(&string, sizeof (string), (uintptr_t)ii_info.bi_group) - != sizeof (string))) - string[0] = 0; - mdb_printf("bi_group: %s\n", string); - - mdb_printf("bi_busy: 0x%p\n", ii_info.bi_busy); - - mdb_printf("bi_shdfba: %0x\t", ii_info.bi_shdfba); - mdb_printf("bi_shdbits: %0x\n", ii_info.bi_shdbits); - mdb_printf("bi_copyfba: %0x\t", ii_info.bi_copyfba); - mdb_printf("bi_copybits: %0x\n", ii_info.bi_copybits); - - mdb_printf("bi_size: %0x\n", ii_info.bi_size); - - mdb_printf("bi_flags: 0x%x <%b>\n", - ii_info.bi_flags, ii_info.bi_flags, bi_flags_bits); - - mdb_printf("bi_state: 0x%x <%b>\n", - ii_info.bi_state, ii_info.bi_state, bi_state_bits); - - mdb_printf("bi_disabled: %d\n", ii_info.bi_disabled); - mdb_printf("bi_ioctl: %d\n", ii_info.bi_ioctl); - mdb_printf("bi_release: %d\t", ii_info.bi_release); - mdb_printf("bi_rsrvcnt: %d\n", ii_info.bi_rsrvcnt); - - mdb_printf("bi_copydonecv: %x\t", ii_info.bi_copydonecv); - mdb_printf("bi_reservecv: %x\n", ii_info.bi_reservecv); - mdb_printf("bi_releasecv: %x\t", ii_info.bi_releasecv); - mdb_printf("bi_closingcv: %x\n", ii_info.bi_closingcv); - mdb_printf("bi_ioctlcv: %x\t", ii_info.bi_ioctlcv); - mdb_printf("bi_busycv: %x\n", ii_info.bi_busycv); - mdb_call_dcmd("rwlock", (uintptr_t)(addr + - offsetof(_ii_info_t, bi_busyrw)), flags, 0, NULL); - mdb_printf("bi_bitmap_ops: 0x%p\n", ii_info.bi_bitmap_ops); - - mdb_printf("bi_rsrvmutex: %x\t", ii_info.bi_rsrvmutex); - mdb_printf("bi_rlsemutex: %x\n", ii_info.bi_rlsemutex); - mdb_printf("bi_bmpmutex: %x\n", ii_info.bi_bmpmutex); - - mdb_printf("bi_mstchks: %d\t", ii_info.bi_mstchks); - mdb_printf("bi_shdchks: %d\n", ii_info.bi_shdchks); - mdb_printf("bi_shdchkused: %d\t", ii_info.bi_shdchkused); - mdb_printf("bi_shdfchk: %d\n", ii_info.bi_shdfchk); - - mdb_printf("bi_overflow\n"); - if (ii_info.bi_overflow) - ii_overflow((uintptr_t)ii_info.bi_overflow, flags, 0, NULL); - - mdb_printf("bi_iifd:\n"); - if (ii_info.bi_iifd) - (void) ii_fd((uintptr_t)ii_info.bi_iifd, flags, 0, NULL); - - mdb_printf("bi_throttle_unit: %d\t", ii_info.bi_throttle_unit); - mdb_printf("bi_throttle_delay: %d\n", ii_info.bi_throttle_delay); - - mdb_printf("bi_linkrw:\n"); - mdb_call_dcmd("rwlock", (uintptr_t)(addr + - offsetof(_ii_info_t, bi_linkrw)), flags, 0, NULL); - - mdb_printf("bi_chksmutex: %x\n", ii_info.bi_chksmutex); - mdb_printf("bi_locked_pid: %x\n", ii_info.bi_locked_pid); - mdb_printf("bi_kstat: 0x%p\n", ii_info.bi_kstat); - /* ii_kstat_info_t bi_kstat_io; */ - - nextaddr = (uintptr_t)ii_info.bi_next; - return (DCMD_OK); -} - -/* - * This should be a walker surely. - */ -/*ARGSUSED*/ -static int -ii_info_all(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - uintptr_t myaddr; - /* - * we use the global address. - */ - if (flags & DCMD_ADDRSPEC) - return (DCMD_USAGE); - - if (mdb_readsym(&myaddr, sizeof (myaddr), "_ii_info_top") != - sizeof (myaddr)) { - return (DCMD_ERR); - } - - mdb_printf("_ii_info_top contains 0x%lx\n", myaddr); - - while (myaddr) { - ii_info(myaddr, DCMD_ADDRSPEC, 0, NULL); - myaddr = nextaddr; - } - return (DCMD_OK); -} - -/* - * Display general ii module information. - */ - -#define ii_get_print(kvar, str, fmt, val) \ - if (mdb_readvar(&(val), #kvar) == -1) { \ - mdb_dec_indent(4); \ - mdb_warn("unable to read '" #kvar "'"); \ - return (DCMD_ERR); \ - } \ - mdb_printf("%-20s" fmt "\n", str ":", val) - -/* ARGSUSED */ -static int -ii(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int maj, min, mic, baseline, i; - - if (argc != 0) - return (DCMD_USAGE); - - if (mdb_readvar(&maj, "dsw_major_rev") == -1) { - mdb_warn("unable to read 'dsw_major_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&min, "dsw_minor_rev") == -1) { - mdb_warn("unable to read 'dsw_minor_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&mic, "dsw_micro_rev") == -1) { - mdb_warn("unable to read 'dsw_micro_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&baseline, "dsw_baseline_rev") == -1) { - mdb_warn("unable to read 'dsw_baseline_rev'"); - return (DCMD_ERR); - } - - mdb_printf("Point-in-Time Copy module version: kernel %d.%d.%d.%d; " - "mdb %d.%d.%d.%d\n", maj, min, mic, baseline, - ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); - - mdb_inc_indent(4); - ii_get_print(ii_debug, "debug", "%d", i); - ii_get_print(ii_bitmap, "bitmaps", "%d", i); - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* - * MDB module linkage information: - */ - -static const mdb_dcmd_t dcmds[] = { -{ "ii", NULL, "display ii module info", ii }, -{ "ii_fd", NULL, "display ii_fd structure", ii_fd }, -{ "ii_info", NULL, "display ii_info structure", ii_info }, -{ "ii_info_all", NULL, "display all ii_info structures", ii_info_all }, -{ "ii_info_dev", NULL, "display ii_info_dev structure", ii_info_dev}, -{ "ii_overflow", NULL, "display ii_overflow structure", ii_overflow}, -{ NULL } -}; - - -static const mdb_walker_t walkers[] = { - { NULL } -}; - - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com b/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com deleted file mode 100644 index 40975cea69..0000000000 --- a/usr/src/cmd/mdb/common/modules/nsctl/Makefile.com +++ /dev/null @@ -1,24 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CPPFLAGS += -DNSC_MULTI_TERABYTE diff --git a/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c b/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c deleted file mode 100644 index e9a360deb6..0000000000 --- a/usr/src/cmd/mdb/common/modules/nsctl/nsctl.c +++ /dev/null @@ -1,2159 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/ksynch.h> -#include <sys/kmem.h> -#include <sys/errno.h> -#include <sys/ddi.h> - -#include <sys/mdb_modapi.h> - -#define __NSC_GEN__ -#include <sys/nsc_thread.h> -#include <sys/nsctl/nsc_dev.h> -#include <sys/nsctl/nsc_gen.h> -#include <sys/nsctl/nsc_mem.h> -#include <sys/nsctl/nsctl.h> -#include <sys/nsctl/nsc_disk.h> - - -/* - * Data struct for the complex walks. - */ - -struct complex_args { - int argc; - mdb_arg_t *argv; -}; - - -/* - * Bit definitions - */ - -#define NSC_RW_BITS \ - { "NSC_READ", NSC_READ, NSC_READ }, \ - { "NSC_WRITE", NSC_WRITE, NSC_WRITE } - - -static const mdb_bitmask_t nsc_bhflag_bits[] = { - NSC_RW_BITS, - { "NSC_PINNABLE", NSC_PINNABLE, NSC_PINNABLE }, - { "NSC_NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK }, - { "NSC_HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED }, - { "NSC_HACTIVE", NSC_HACTIVE, NSC_HACTIVE }, - { "NSC_BCOPY", NSC_BCOPY, NSC_BCOPY }, - { "NSC_PAGEIO", NSC_PAGEIO, NSC_PAGEIO }, - { "NSC_ABUF", NSC_ABUF, NSC_ABUF }, - { "NSC_MIXED", NSC_MIXED, NSC_MIXED }, - { "NSC_WRTHRU", NSC_WRTHRU, NSC_WRTHRU }, - { "NSC_FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU }, - { "NSC_NOCACHE", NSC_NOCACHE, NSC_NOCACHE }, - { "NSC_QUEUE", NSC_QUEUE, NSC_QUEUE }, - { "NSC_RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD }, - { "NSC_NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU }, - { "NSC_METADATA", NSC_METADATA, NSC_METADATA }, - { "NSC_SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nsc_fdflag_bits[] = { - NSC_RW_BITS, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nsc_fdmode_bits[] = { - { "NSC_MULTI", NSC_MULTI, NSC_MULTI }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nsc_type_bits[] = { - /* types */ - { "NSC_NULL", NSC_NULL, NSC_NULL }, - { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, - { "NSC_FILE", NSC_FILE, NSC_FILE }, - { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, - { "NSC_VCHR", NSC_VCHR, NSC_VCHR }, - { "NSC_NCALL", NSC_NCALL, NSC_NCALL }, - - /* type flags */ - { "NSC_ANON", NSC_ANON, NSC_ANON }, - - /* ids */ - { "NSC_RAW_ID", NSC_RAW_ID, NSC_RAW_ID }, - { "NSC_FILE_ID", NSC_FILE_ID, NSC_FILE_ID }, - { "NSC_FREEZE_ID", NSC_FREEZE_ID, NSC_FREEZE_ID }, - { "NSC_VCHR_ID", NSC_VCHR_ID, NSC_VCHR_ID }, - { "NSC_NCALL_ID", NSC_NCALL_ID, NSC_NCALL_ID }, - { "NSC_SDBC_ID", NSC_SDBC_ID, NSC_SDBC_ID }, - { "NSC_RDCLR_ID", NSC_RDCLR_ID, NSC_RDCLR_ID }, - { "NSC_RDCL_ID", NSC_RDCL_ID, NSC_RDCL_ID }, - { "NSC_IIR_ID", NSC_IIR_ID, NSC_IIR_ID }, - { "NSC_II_ID", NSC_II_ID, NSC_II_ID }, - { "NSC_RDCHR_ID", NSC_RDCHR_ID, NSC_RDCHR_ID }, - { "NSC_RDCH_ID", NSC_RDCH_ID, NSC_RDCH_ID }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nsc_availpend_bits[] = { - NSC_RW_BITS, - { "_NSC_OPEN", _NSC_OPEN, _NSC_OPEN }, - { "_NSC_CLOSE", _NSC_CLOSE, _NSC_CLOSE }, - { "_NSC_PINNED", _NSC_PINNED, _NSC_PINNED }, - { "_NSC_ATTACH", _NSC_ATTACH, _NSC_ATTACH }, - { "_NSC_DETACH", _NSC_DETACH, _NSC_DETACH }, - { "_NSC_OWNER", _NSC_OWNER, _NSC_OWNER }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nsc_ioflag_bits[] = { - { "NSC_REFCNT", NSC_REFCNT, NSC_REFCNT }, - { "NSC_FILTER", NSC_FILTER, NSC_FILTER }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nstset_flag_bits[] = { - { "NST_SF_KILL", NST_SF_KILL, NST_SF_KILL }, - { NULL, 0, 0 } -}; - - -static const mdb_bitmask_t nst_flag_bits[] = { - { "NST_TF_INUSE", NST_TF_INUSE, NST_TF_INUSE }, - { "NST_TF_ACTIVE", NST_TF_ACTIVE, NST_TF_ACTIVE }, - { "NST_TF_PENDING", NST_TF_PENDING, NST_TF_PENDING }, - { "NST_TF_DESTROY", NST_TF_DESTROY, NST_TF_DESTROY }, - { "NST_TF_KILL", NST_TF_KILL, NST_TF_KILL }, - { NULL, 0, 0 } -}; - - -/* - * Global data. - */ - -static nsc_mem_t type_mem[20]; -static int complex_walk; -static int complex_hdr; - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for an nsc_io chain. - * A global walk is assumed to start at _nsc_io_top. - */ - -static int -nsc_io_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "_nsc_io_top") == -1) { - mdb_warn("unable to read '_nsc_io_top'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_io_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t next; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - next = wsp->walk_addr + OFFSETOF(nsc_io_t, next); - - if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) { - mdb_warn("failed to read nsc_io_t.next at %p", next); - return (WALK_DONE); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for an nsc_dev chain. - * A global walk is assumed to start at _nsc_dev_top. - */ - -static int -nsc_dev_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "_nsc_dev_top") == -1) { - mdb_warn("unable to read '_nsc_dev_top'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_dev_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t next; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - next = wsp->walk_addr + OFFSETOF(nsc_dev_t, nsc_next); - - if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) { - mdb_warn("failed to read nsc_dev_t.nsc_next at %p", next); - return (WALK_DONE); - } - - return (status); -} - - -/* ARGSUSED */ - -static void -nsc_dev_wfini(mdb_walk_state_t *wsp) -{ - complex_walk = 0; -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_devval_t structures. - * Global walks start from _nsc_devval_top; - */ - -static int -nsc_devval_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "_nsc_devval_top") == -1) { - mdb_warn("unable to read '_nsc_devval_top'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_devval_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t devval = wsp->walk_addr; - int status; - - if (!devval) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next devval */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - devval + OFFSETOF(nsc_devval_t, dv_next)) == -1) { - mdb_warn("failed to read nsc_devval_t.dv_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_fd_t structures. - * No global walks. - */ - -static int -nsc_fd_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nsc_fd doesn't support global walks"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_fd_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t fd = wsp->walk_addr; - int status; - - if (!fd) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next fd */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - fd + OFFSETOF(nsc_fd_t, sf_next)) == -1) { - mdb_warn("failed to read nsc_fd_t.sf_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_iodev_t structures. - * No global walks. - */ - -static int -nsc_iodev_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nsc_iodev doesn't support global walks"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_iodev_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t iodev = wsp->walk_addr; - int status; - - if (!iodev) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - iodev + OFFSETOF(nsc_iodev_t, si_next)) == -1) { - mdb_warn("failed to read nsc_iodev_t.si_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_service_t structures. - * Global walks start at _nsc_services. - */ - -static int -nsc_service_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "_nsc_services") == -1) { - mdb_warn("unable to read '_nsc_services'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_service_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t service = wsp->walk_addr; - int status; - - if (!service) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next service */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - service + OFFSETOF(nsc_service_t, s_next)) == -1) { - mdb_warn("failed to read nsc_service_t.s_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_svc_t structures. - * No global walks. - */ - -static int -nsc_svc_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nsc_svc does not support global walks"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_svc_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t svc = wsp->walk_addr; - int status; - - if (!svc) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next svc */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - svc + OFFSETOF(nsc_svc_t, svc_next)) == -1) { - mdb_warn("failed to read nsc_svc_t.svc_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_val_t structures. - * No global walks. - */ - -static int -nsc_val_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nsc_val doesn't support global walks"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_val_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t val = wsp->walk_addr; - int status; - - if (!val) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next val */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - val + OFFSETOF(nsc_val_t, sv_next)) == -1) { - mdb_warn("failed to read nsc_val_t.sv_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nstset_t structures. - * Global walks start at _nst_sets. - */ - -static int -nstset_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "nst_sets") == -1) { - mdb_warn("unable to read 'nst_sets'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nstset_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t set = wsp->walk_addr; - int status; - - if (!set) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next set */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - set + OFFSETOF(nstset_t, set_next)) == -1) { - mdb_warn("failed to read nstset_t.set_next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsthread_t structures. - * No global walks. - */ - -static int -nsthread_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nsthread does not support global walks"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsthread_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t thread = wsp->walk_addr; - int status; - - if (!thread) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next iodev */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - thread + OFFSETOF(nsthread_t, tp_chain)) == -1) { - mdb_warn("failed to read nsthread_t.tp_chain"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for nsthread_t free/reuse chain. - * No global walks. - */ - -static int -nst_free_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - mdb_warn("nst_free does not support global walks"); - return (WALK_ERR); - } - - /* store starting address */ - - wsp->walk_data = (void *)wsp->walk_addr; - - /* move on to next thread */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - wsp->walk_addr + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) { - mdb_warn("failed to read nsthread_t.tp_link.q_forw"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nst_free_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t thread = wsp->walk_addr; - int status; - - if (!thread) - return (WALK_DONE); - - if (thread == (uintptr_t)wsp->walk_data) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next thread */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - thread + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) { - mdb_warn("failed to read nsthread_t.tp_link.q_forw"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Walker for a chain of nsc_mem_t structures. - * Global walks start at _nsc_mem_top. - */ - -static int -nsc_mem_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "_nsc_mem_top") == -1) { - mdb_warn("unable to read '_nsc_mem_top'"); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -static int -nsc_mem_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t mem = wsp->walk_addr; - int status; - - if (!mem) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - /* move on to next mem */ - - if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr), - mem + OFFSETOF(nsc_mem_t, next)) == -1) { - mdb_warn("failed to read nsc_mem_t.next"); - return (WALK_ERR); - } - - return (status); -} - - -/* ---------------------------------------------------------------------- */ - -struct { - char *name; - int id; -} io_ids[] = { - { "NSC_RAW_ID", NSC_RAW_ID }, - { "NSC_FILE_ID", NSC_FILE_ID }, - { "NSC_FREEZE_ID", NSC_FREEZE_ID }, - { "NSC_SDBC_ID", NSC_SDBC_ID }, - { "NSC_RDCLR_ID", NSC_RDCLR_ID }, - { "NSC_RDCL_ID", NSC_RDCL_ID }, - { "NSC_IIR_ID", NSC_IIR_ID }, - { "NSC_II_ID", NSC_II_ID }, - { "NSC_RDCHR_ID", NSC_RDCHR_ID }, - { "NSC_RDCH_ID", NSC_RDCH_ID }, - { NULL, 0 } -}; - - -static char * -nsc_io_id(const int id) -{ - int i; - - for (i = 0; io_ids[i].name != NULL; i++) { - if (io_ids[i].id == id) { - return (io_ids[i].name); - } - } - - return ("unknown"); -} - - -/* - * Display a single nsc_io_t structure. - * If called with no address, performs a global walk of all nsc_ios. - */ -static int -nsc_io(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - char io_name[128]; - nsc_io_t *io; - int v_opt; - - v_opt = 0; - - if (mdb_getopts(argc, argv, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("nsctl`nsc_io", - "nsctl`nsc_io", argc, argv) == -1) { - mdb_warn("failed to walk 'nsc_io'"); - return (DCMD_ERR); - } - - return (DCMD_OK); - } - - io = mdb_zalloc(sizeof (*io), UM_SLEEP | UM_GC); - memset(io_name, 0, sizeof (io_name)); - - if (mdb_vread(io, sizeof (*io), addr) != sizeof (*io)) { - mdb_warn("failed to read nsc_io at %p", addr); - return (DCMD_ERR); - } - - if (io->name) { - if (mdb_readstr(io_name, sizeof (io_name), - (uintptr_t)io->name) == -1) { - mdb_warn("failed to read nsc_io_t.name"); - return (DCMD_ERR); - } - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8Tid fl ref abuf name\n", "io"); - } - - mdb_printf("%0?p %8T%08x %2x %4d %4d %s\n", - addr, io->id, io->flag, io->refcnt, io->abufcnt, io_name); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("id: %08x <%s>\n", io->id, nsc_io_id(io->id)); - - mdb_printf("provide: %08x <%b>\n", io->provide, - io->provide, nsc_type_bits); - - mdb_printf("flag: %08x <%b>\n", io->flag, io->flag, nsc_ioflag_bits); - - mdb_printf("pend: %d\n", io->pend); - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display a single nsc_dev_t structure. - * If called with no address, performs a global walk of all nsc_devs. - */ -static int -nsc_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - char path[NSC_MAXPATH+1]; - nsc_devval_t *dv; - nsc_dev_t *dev; - uintptr_t dev_pend; - int a_opt, v_opt; - - a_opt = v_opt = 0; - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - mdb_printf("Active device structures:\n"); - - if (mdb_walk_dcmd("nsctl`nsc_dev", - "nsctl`nsc_dev", argc, argv) == -1) { - mdb_warn("failed to walk 'nsc_dev'"); - return (DCMD_ERR); - } - - if (a_opt) { - if (mdb_readvar(&dev_pend, "_nsc_dev_pend") == -1) { - mdb_warn("failed to read _nsc_dev_pend"); - return (DCMD_ERR); - } - - mdb_printf("\nPending device structures:"); - - if (dev_pend) { - mdb_printf("\n"); - - if (mdb_pwalk_dcmd("nsctl`nsc_dev", - "nsctl`nsc_dev", argc, argv, - dev_pend) == -1) { - mdb_warn("failed to walk " - "pending dev structs"); - return (DCMD_ERR); - } - } else { - mdb_printf(" none\n"); - } - } - - return (DCMD_OK); - } - - memset(path, 0, sizeof (path)); - dev = mdb_zalloc(sizeof (*dev), UM_SLEEP | UM_GC); - - if (mdb_vread(dev, sizeof (*dev), addr) != sizeof (*dev)) { - mdb_warn("failed to read nsc_dev at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readstr(path, sizeof (path), (uintptr_t)dev->nsc_path) == -1) { - mdb_warn("failed to read nsc_path at %p", dev->nsc_path); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8Tref pend rpnd wait path\n", "dev"); - } - - mdb_printf("%0?p %8T%3d %4d %4d %4d %s\n", - addr, dev->nsc_refcnt, dev->nsc_pend, dev->nsc_rpend, - dev->nsc_wait, path); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("next: %0?p %8Tclose: %0?p\n", - dev->nsc_next, dev->nsc_close); - - mdb_printf("list: %0?p %8Tlock: %0?p\n", - dev->nsc_list, addr + OFFSETOF(nsc_dev_t, nsc_lock)); - - mdb_printf("cv: %0?p %8Tpath: %0?p %8Tphash: %016llx\n", - addr + OFFSETOF(nsc_dev_t, nsc_cv), - dev->nsc_path, dev->nsc_phash); - - mdb_printf("drop: %d %8Treopen: %d\n", - dev->nsc_drop, dev->nsc_reopen); - - if (dev->nsc_values) { - dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC); - if (mdb_vread(dv, sizeof (*dv), (uintptr_t)dev->nsc_values) != - sizeof (*dv)) { - mdb_warn("unable to read nsc_dev_t.nsc_values"); - mdb_dec_indent(4); - return (DCMD_ERR); - } - - if (dv->dv_values) { - mdb_printf("device/values: (nsc_devval: %0?p)\n", - dev->nsc_values); - - mdb_inc_indent(4); - - if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val", - 0, NULL, (uintptr_t)dv->dv_values) == -1) { - mdb_dec_indent(8); - return (DCMD_ERR); - } - - mdb_dec_indent(4); - } - } - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display a single nsc_devval_t structure. - * If called with no address, performs a global walk of all nsc_devs. - */ -static int -nsc_devval(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_devval_t *dv; - int a_opt; - - a_opt = 0; - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("nsctl`nsc_devval", - "nsctl`nsc_devval", argc, argv) == -1) { - mdb_warn("failed to walk 'nsc_devval'"); - return (DCMD_ERR); - } - - return (DCMD_OK); - } - - dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC); - - if (mdb_vread(dv, sizeof (*dv), addr) != sizeof (*dv)) { - mdb_warn("failed to read nsc_devval at %p", addr); - return (DCMD_ERR); - } - - if (!a_opt && !dv->dv_values) { - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%?-s %8Tpath\n", "devval", "phash"); - } - - mdb_printf("%0?p %8T%016llx %8T%s\n", addr, - dv->dv_phash, dv->dv_path); - - mdb_inc_indent(4); - - if (dv->dv_values) { - if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val", - 0, NULL, (uintptr_t)dv->dv_values) == -1) { - return (DCMD_ERR); - } - } else { - mdb_printf("No values\n"); - } - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Part 2 callback for the all devices and fds walk. Called per iodev. - */ -/* ARGSUSED */ -static int -nsc_fd_iodev(uintptr_t addr, const void *data, void *cbdata) -{ - struct complex_args *fdall = cbdata; - struct nsc_fd_t *fd; - - if (mdb_vread(&fd, sizeof (fd), - addr + OFFSETOF(nsc_iodev_t, si_open)) == -1) { - mdb_warn("unable to read nsc_iodev_t.si_open"); - return (WALK_ERR); - } - - if (fd != NULL) { - if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd", - fdall->argc, fdall->argv, (uintptr_t)fd) == -1) - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -/* - * Part 1 callback for the all devices and fds walk. Called per device. - */ -/* ARGSUSED */ -static int -nsc_fd_dev(uintptr_t addr, const void *data, void *cbdata) -{ - struct complex_args *fdall = cbdata; - nsc_iodev_t *iodev; - nsc_fd_t *fd; - - if (mdb_vread(&iodev, sizeof (iodev), - addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) { - mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr); - return (WALK_ERR); - } - - /* walk iodev chains */ - - if (iodev != NULL) { - if (mdb_pwalk("nsctl`nsc_iodev", - nsc_fd_iodev, fdall, (uintptr_t)iodev) == -1) - return (WALK_ERR); - } - - /* walk nsc_close (closing fds) chains */ - - if (mdb_vread(&fd, sizeof (fd), - addr + OFFSETOF(nsc_dev_t, nsc_close)) == -1) { - mdb_warn("unable to read nsc_dev_t.nsc_close at %p", addr); - return (WALK_ERR); - } - - if (fd != NULL) { - if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd", - fdall->argc, fdall->argv, (uintptr_t)fd) == -1) - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -/* - * Walk all devices and fds in the system. - */ -static int -nsc_fd_all(int argc, const mdb_arg_t *argv) -{ - struct complex_args fdall; - - fdall.argc = argc; - fdall.argv = (mdb_arg_t *)argv; - - complex_walk = 1; - complex_hdr = 0; - - if (mdb_walk("nsctl`nsc_dev", nsc_fd_dev, &fdall) == -1) { - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - - -/* - * Display an nsd_fd_t structure, or walk all devices and fds in the system. - */ -static int -nsc_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - char io_name[128], *io_namep; - char path[NSC_MAXPATH+1]; - uintptr_t pathp; - nsc_fd_t *fd; - nsc_io_t *io; - int v_opt; - int hdr; - - v_opt = 0; - - if (mdb_getopts(argc, argv, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - return (nsc_fd_all(argc, argv)); - } - - memset(path, 0, sizeof (path)); - fd = mdb_zalloc(sizeof (*fd), UM_SLEEP | UM_GC); - memset(io_name, 0, sizeof (io_name)); - - if (mdb_vread(fd, sizeof (*fd), addr) != sizeof (*fd)) { - mdb_warn("failed to read nsc_fd at %p", addr); - return (DCMD_ERR); - } - - if (mdb_vread(&pathp, sizeof (pathp), - (uintptr_t)fd->sf_dev + OFFSETOF(nsc_dev_t, nsc_path)) != - sizeof (pathp)) { - mdb_warn("failed to read nsc_dev.nsc_path"); - return (DCMD_ERR); - } - - if (mdb_readstr(path, sizeof (path), pathp) == -1) { - mdb_warn("failed to read nsc_path"); - return (DCMD_ERR); - } - - if (fd->sf_iodev) { - if (mdb_vread(&io, sizeof (io), - (uintptr_t)fd->sf_iodev + OFFSETOF(nsc_iodev_t, si_io)) != - sizeof (io)) { - mdb_warn("failed to read nsc_iodev.si_io"); - return (DCMD_ERR); - } - - if (mdb_vread(&io_namep, sizeof (io_namep), - (uintptr_t)io + OFFSETOF(nsc_io_t, name)) != - sizeof (io_namep)) { - mdb_warn("failed to read nsc_io_t.name"); - return (DCMD_ERR); - } - - if (mdb_readstr(io_name, sizeof (io_name), - (uintptr_t)io_namep) == -1) { - mdb_warn("failed to read nsc_io_t.name string"); - return (DCMD_ERR); - } - } - - hdr = 0; - if (complex_walk) { - if (!complex_hdr) { - complex_hdr = 1; - hdr = 1; - } - } else if (DCMD_HDRSPEC(flags)) { - hdr = 1; - } - - if (hdr) { - mdb_printf("%-?s %8T%-?s %8T%-8s %-?s\n", - "fd", "dev", "io", "cd"); - mdb_printf(" %-?s %8Trv pend av path\n", "arg"); - } - - mdb_printf("%0?p %8T%0?p %8T%-8s %p\n", - addr, fd->sf_dev, io_name, fd->sf_cd); - mdb_printf(" %0?p %8T%2d %4x %2x %s\n", - fd->sf_arg, fd->sf_reserve, fd->sf_pend, - fd->sf_avail, path); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("open type: %08x <%b>\n", fd->sf_type, - fd->sf_type, nsc_type_bits); - - mdb_printf("avail: %08x <%b>\n", fd->sf_avail, - fd->sf_avail, nsc_availpend_bits); - - mdb_printf("flag: %08x <%b>\n", fd->sf_flag, - fd->sf_flag, nsc_fdflag_bits); - - mdb_printf("rsrv mode: %08x <%b>\n", fd->sf_mode, - fd->sf_mode, nsc_fdmode_bits); - - mdb_printf("open lbolt: %?x %8Treopen: %d\n", fd->sf_lbolt, - fd->sf_reopen); - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Callback for the all devices and iodevs walk. Called per device. - */ -/* ARGSUSED */ -static int -nsc_iodev_dev(uintptr_t addr, const void *data, void *cbdata) -{ - struct complex_args *iodevall = cbdata; - uintptr_t iodev; - - if (mdb_vread(&iodev, sizeof (iodev), - addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) { - mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr); - return (WALK_ERR); - } - - /* walk iodev chains */ - - if (iodev != NULL) { - if (mdb_pwalk_dcmd("nsctl`nsc_iodev", "nsctl`nsc_iodev", - iodevall->argc, iodevall->argv, iodev) == -1) - return (WALK_ERR); - } - - return (WALK_NEXT); -} - - -/* - * Walk all devices and iodevs in the system. - */ -static int -nsc_iodev_all(int argc, const mdb_arg_t *argv) -{ - struct complex_args iodevall; - - iodevall.argc = argc; - iodevall.argv = (mdb_arg_t *)argv; - - complex_walk = 1; - complex_hdr = 0; - - if (mdb_walk("nsctl`nsc_dev", nsc_iodev_dev, &iodevall) == -1) { - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - -/* - * Display an nsc_iodev_t structure, or walk all devices and - * iodevs in the system. - */ -static int -nsc_iodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - char io_name[128], *io_namep; - char path[NSC_MAXPATH+1]; - nsc_iodev_t *iodev; - uintptr_t pathp; - int v_opt; - int hdr; - - v_opt = 0; - - if (mdb_getopts(argc, argv, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - return (nsc_iodev_all(argc, argv)); - } - - memset(path, 0, sizeof (path)); - iodev = mdb_zalloc(sizeof (*iodev), UM_SLEEP | UM_GC); - memset(io_name, 0, sizeof (io_name)); - - if (mdb_vread(iodev, sizeof (*iodev), addr) != sizeof (*iodev)) { - mdb_warn("failed to read nsc_iodev at %p", addr); - return (DCMD_ERR); - } - - if (mdb_vread(&pathp, sizeof (pathp), - (uintptr_t)iodev->si_dev + OFFSETOF(nsc_dev_t, nsc_path)) != - sizeof (pathp)) { - mdb_warn("failed to read nsc_dev.nsc_path"); - return (DCMD_ERR); - } - - if (mdb_readstr(path, sizeof (path), pathp) == -1) { - mdb_warn("failed to read nsc_path"); - return (DCMD_ERR); - } - - if (mdb_vread(&io_namep, sizeof (io_namep), - (uintptr_t)iodev->si_io + OFFSETOF(nsc_io_t, name)) != - sizeof (io_namep)) { - mdb_warn("failed to read nsc_io_t.name"); - return (DCMD_ERR); - } - - if (mdb_readstr(io_name, sizeof (io_name), - (uintptr_t)io_namep) == -1) { - mdb_warn("failed to read nsc_io_t.name string"); - return (DCMD_ERR); - } - - hdr = 0; - if (complex_walk) { - if (!complex_hdr) { - complex_hdr = 1; - hdr = 1; - } - } else if (DCMD_HDRSPEC(flags)) { - hdr = 1; - } - - if (hdr) { - mdb_printf("%-?s %8T%-?s ref %-8s path\n", - "iodev", "dev", "io"); - } - - mdb_printf("%0?p %8T%0?p %3d %-8s %s\n", - addr, iodev->si_dev, iodev->si_refcnt, io_name, path); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("open fds: %?p %8Tactive ios: %?p\n", - iodev->si_open, iodev->si_active); - - mdb_printf("busy: %d %8Trsrv pend: %d\n", - iodev->si_busy, iodev->si_rpend); - - mdb_printf("pend: %08x <%b>\n", iodev->si_pend, - iodev->si_pend, nsc_availpend_bits); - - mdb_printf("avail: %08x <%b>\n", iodev->si_avail, - iodev->si_avail, nsc_availpend_bits); - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display an nsc_service_t structure, or walk all services. - */ -static int -nsc_service(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_service_t *service; - char s_name[32]; - int v_opt; - - v_opt = 0; - - if (mdb_getopts(argc, argv, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("nsctl`nsc_service", - "nsctl`nsc_service", argc, argv) == -1) { - mdb_warn("failed to walk 'nsc_service'"); - return (DCMD_ERR); - } - - return (DCMD_OK); - } - - service = mdb_zalloc(sizeof (*service), UM_SLEEP | UM_GC); - - if (mdb_vread(service, sizeof (*service), addr) != sizeof (*service)) { - mdb_warn("failed to read nsc_service at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8Tname\n", "service"); - } - - memset(s_name, 0, sizeof (s_name)); - if (service->s_name) { - if (mdb_readstr(s_name, sizeof (s_name), - (uintptr_t)service->s_name) == -1) { - mdb_warn("failed to read nsc_io_t.name"); - return (DCMD_ERR); - } - } - - mdb_printf("%0?p %8T%s\n", addr, s_name); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("servers:\n"); - if (service->s_servers == NULL) { - mdb_printf("<none>\n"); - } else { - mdb_inc_indent(4); - if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc", - argc, argv, (uintptr_t)service->s_servers) == -1) { - mdb_dec_indent(8); - return (DCMD_ERR); - } - mdb_dec_indent(4); - } - - mdb_printf("clients:\n"); - if (service->s_clients == NULL) { - mdb_printf("<none>\n"); - } else { - mdb_inc_indent(4); - if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc", - argc, argv, (uintptr_t)service->s_clients) == -1) { - mdb_dec_indent(8); - return (DCMD_ERR); - } - mdb_dec_indent(4); - } - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display an nsc_svc_t structure. - */ -/*ARGSUSED*/ -static int -nsc_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_svc_t *svc; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - svc = mdb_zalloc(sizeof (*svc), UM_SLEEP | UM_GC); - - if (mdb_vread(svc, sizeof (*svc), addr) != sizeof (*svc)) { - mdb_warn("failed to read nsc_svc at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-?s %8Tfunc\n", "svc", "service"); - } - - mdb_printf("%0?p %8T%0?p %8T%a\n", addr, svc->svc_svc, svc->svc_fn); - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display a single nsc_val_t structure. - * If called with no address, performs a global walk of all nsc_devs. - */ -/* ARGSUSED3 */ -static int -nsc_val(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_val_t *vp; - - if (argc != 0) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - mdb_warn("nsc_val requires an address"); - return (DCMD_ERR); - } - - vp = mdb_zalloc(sizeof (*vp), UM_SLEEP | UM_GC); - - if (mdb_vread(vp, sizeof (*vp), addr) != sizeof (*vp)) { - mdb_warn("failed to read nsc_val at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%8-s %8Tname\n", "val", "value"); - } - - mdb_printf("%0?p %8T%08x %8T%s\n", addr, vp->sv_value, vp->sv_name); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Display an nstset_t structure, or walk all sets. - */ - -static int -nstset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nstset_t *set; - int f_opt, r_opt, t_opt, v_opt; - - f_opt = r_opt = t_opt = v_opt = 0; - - if (mdb_getopts(argc, argv, - 'f', MDB_OPT_SETBITS, TRUE, &f_opt, /* free list */ - 'r', MDB_OPT_SETBITS, TRUE, &r_opt, /* reuse list */ - 't', MDB_OPT_SETBITS, TRUE, &t_opt, /* all threads */ - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - /* displaying threads implies verbose */ - if (f_opt || r_opt || t_opt) - v_opt = 1; - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("nsctl`nstset", - "nsctl`nstset", argc, argv) == -1) { - mdb_warn("failed to walk 'nstset'"); - return (DCMD_ERR); - } - - return (DCMD_OK); - } - - set = mdb_zalloc(sizeof (*set), UM_SLEEP | UM_GC); - - if (mdb_vread(set, sizeof (*set), addr) != sizeof (*set)) { - mdb_warn("failed to read nstset at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T live nthr flag name\n", "set"); - } - - mdb_printf("%0?p %8T%6d %6d %4x %s\n", addr, - set->set_nlive, set->set_nthread, set->set_flag, set->set_name); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("chain: %0?p %8Tpending: %4d res_cnt: %4d\n", - set->set_chain, set->set_pending, set->set_res_cnt); - - if (set->set_reuse.q_forw == set->set_reuse.q_back && - (uintptr_t)set->set_reuse.q_forw == - (addr + OFFSETOF(nstset_t, set_reuse))) { - mdb_printf("reuse.forw: %-?s %8Treuse.back: %s\n", - "empty", "empty"); - } else { - mdb_printf("reuse.forw: %0?p %8Treuse.back: %0?p\n", - set->set_reuse.q_forw, set->set_reuse.q_back); - - /* display all threads in reuse list */ - if (r_opt && - mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread", - 0, (const mdb_arg_t *)NULL, - (addr + OFFSETOF(nstset_t, set_reuse))) == -1) { - mdb_dec_indent(4); - return (DCMD_ERR); - } - } - - if (set->set_free.q_forw == set->set_free.q_back && - (uintptr_t)set->set_free.q_forw == - (addr + OFFSETOF(nstset_t, set_free))) { - mdb_printf("free.forw: %-?s %8Tfree.back: %s\n", - "empty", "empty"); - } else { - mdb_printf("free.forw: %0?p %8Tfree.back: %0?p\n", - set->set_free.q_forw, set->set_free.q_back); - - /* display all threads in free list */ - if (f_opt && - mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread", - 0, (const mdb_arg_t *)NULL, - (addr + OFFSETOF(nstset_t, set_free))) == -1) { - mdb_dec_indent(4); - return (DCMD_ERR); - } - } - - mdb_printf("flag: %08x <%b>\n", - set->set_flag, set->set_flag, nstset_flag_bits); - - /* display all threads in set */ - if (t_opt) { - mdb_printf("all threads in set:\n"); - if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread", - 0, (const mdb_arg_t *)NULL, - (uintptr_t)set->set_chain) == -1) { - mdb_dec_indent(4); - return (DCMD_ERR); - } - } - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -/* - * Callback for the all nstsets and threads walk. Called per set. - */ -/* ARGSUSED */ -static int -nst_thr_set(uintptr_t addr, const void *data, void *cbdata) -{ - struct complex_args *thrall = cbdata; - char set_name[48]; - uintptr_t tp; - - if (mdb_vread(&tp, sizeof (tp), - addr + OFFSETOF(nstset_t, set_chain)) == -1) { - mdb_warn("unable to read nstset_t.set_chain at %p", addr); - return (WALK_ERR); - } - - memset(set_name, 0, sizeof (set_name)); - - if (mdb_readstr(set_name, sizeof (set_name), - addr + OFFSETOF(nstset_t, set_name)) == -1) { - mdb_warn("unable to read nstset_t.set_name at %p", addr); - } - - mdb_printf("nstset: %0?p (%s)\n", addr, set_name); - - /* walk thread chains */ - - if (tp != NULL) { - if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread", - thrall->argc, thrall->argv, tp) == -1) - return (WALK_ERR); - } else - mdb_printf(" no threads\n"); - - mdb_printf("\n"); - - return (WALK_NEXT); -} - - -/* - * Walk all nstsets and threads in the system. - */ -static int -nst_thr_all(int argc, const mdb_arg_t *argv) -{ - struct complex_args thrall; - - thrall.argc = argc; - thrall.argv = (mdb_arg_t *)argv; - - if (mdb_walk("nsctl`nstset", nst_thr_set, &thrall) == -1) - return (DCMD_ERR); - - return (DCMD_OK); -} - - -/* - * Display an nsthread_t structure, or walk all threads. - */ - -static int -nsthread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - uintptr_t thrpend; - nsthread_t *tp; - int a_opt, v_opt; - int rc; - - a_opt = v_opt = 0; - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if ((rc = nst_thr_all(argc, argv)) != DCMD_OK) - return (rc); - - if (a_opt) { - if (mdb_readvar(&thrpend, "nst_pending") == -1) { - mdb_warn("unable to read 'nst_pending'"); - return (DCMD_ERR); - } - - if (thrpend) { - mdb_printf("\nPending threads:\n"); - - if (mdb_pwalk_dcmd("nsctl`nsthread", - "nsctl`nsthread", argc, argv, - thrpend) == -1) { - mdb_warn("failed to walk 'nsthread'"); - return (DCMD_ERR); - } - } - } - - return (DCMD_OK); - } - - tp = mdb_zalloc(sizeof (*tp), UM_SLEEP | UM_GC); - - if (mdb_vread(tp, sizeof (*tp), addr) != sizeof (*tp)) { - mdb_warn("failed to read nsthread at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8Tflag %-?s %8Tfunc\n", "thread", "arg"); - } - - mdb_printf("%0?p %8T%4x %0?p %8T%a\n", - addr, tp->tp_flag, tp->tp_arg, tp->tp_func); - - if (!v_opt) - return (DCMD_OK); - - mdb_inc_indent(4); - - mdb_printf("set: %0?p %8Tchain: %0?p\n", - tp->tp_set, tp->tp_chain); - - mdb_printf("link.forw: %0?p %8Tlink.back: %0?p\n", - tp->tp_link.q_forw, tp->tp_link.q_back); - - mdb_printf("flag: %08x <%b>\n", - tp->tp_flag, tp->tp_flag, nst_flag_bits); - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* ---------------------------------------------------------------------- */ - -static void -nsc_rmap(char *name) -{ - nsc_rmmap_t slot; - uintptr_t addr; - int nslot; - char *cp; - - if (mdb_readvar(&addr, name) == -1) { - mdb_warn("unable to read rmap '%s'", name); - return; - } - - if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) { - mdb_warn("unable to read rmap '%s' slot 0", name); - return; - } - - mdb_printf("\nmap name offset size nslot\n"); - mdb_printf("%16s %9d %9d %5d\n", - slot.name, slot.offset, slot.size, slot.inuse); - - nslot = slot.inuse; - mdb_printf("\nslot name offset size inuse\n"); - - while (--nslot) { - addr += sizeof (slot); - - if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) { - mdb_warn("unable to read rmap '%s' slot @ %p", - name, addr); - return; - } - - if (!slot.inuse || !slot.size) - continue; - - for (cp = slot.name; *cp; cp++) - if (*cp == ':') - *cp = ' '; - - mdb_printf("%16s %9d %9d %08x\n", - slot.name, slot.offset, slot.size, slot.inuse); - } -} - - -static void -nsc_rmhdr(void) -{ - nsc_rmhdr_t *rmhdr = mdb_zalloc(sizeof (*rmhdr), UM_SLEEP | UM_GC); - uintptr_t addr; - - if (mdb_readvar(&addr, "_nsc_rmhdr_ptr") == -1) { - mdb_warn("unable to read _nsc_rmhdr_ptr"); - return; - } - - if (!addr) { - mdb_printf("\n\nGlobal header not initialised\n"); - return; - } - - if (mdb_vread(rmhdr, sizeof (*rmhdr), addr) != sizeof (*rmhdr)) { - mdb_warn("unable to read global header at %p", addr); - return; - } - - mdb_printf("\n\nglobal header (magic %08x, version %d, size %d)\n", - rmhdr->magic, rmhdr->ver, rmhdr->size); - - nsc_rmap("_nsc_global_map"); -} - - -static nsc_mem_t * -memptr(int type, int flag) -{ - int i; - - type &= NSC_MEM_GLOBAL; - - if (type) - flag = 0; - - if (!type && !flag) - return (&type_mem[0]); - - for (i = 1; i < (sizeof (type_mem) / sizeof (nsc_mem_t)); i++) { - if (!type_mem[i].flag && !type_mem[i].type) { - type_mem[i].flag = flag; - type_mem[i].type = type; - return (&type_mem[i]); - } - - if (type_mem[i].flag == flag && type_mem[i].type == type) - return (&type_mem[i]); - } - - return (&type_mem[i]); -} - - -#define typename(t) \ - (((t) & NSC_MEM_GLOBAL) ? "gbl" : " - ") - -#define memname(t) \ - (((t) & NSC_MEM_GLOBAL) ? "nsc_global" : "system kmem") - -static void -nsc_mem_type(const int first, nsc_mem_t *mp) -{ - char *type, *name; - - if (first) { - mdb_printf("\nregion typ f "); - mdb_printf("used hwm pgs alloc free\n"); - } - - type = typename(mp->type); - name = memname(mp->type); - - mdb_printf("%16s %s %2x %9d %9d %6d %5d %5d\n", - name, type, mp->flag, mp->used, mp->hwm, mp->pagehwm, - mp->nalloc, mp->nfree); -} - - -static int -nsc_mem_all(int argc, const mdb_arg_t *argv, int v_opt) -{ - int first; - int i; - - memset(type_mem, 0, sizeof (type_mem)); - - if (mdb_walk_dcmd("nsctl`nsc_mem", - "nsctl`nsc_mem", argc, argv) == -1) { - mdb_warn("unable to walk 'nsc_mem'"); - return (DCMD_ERR); - } - - for (first = 1, i = 0; - i < (sizeof (type_mem) / sizeof (nsc_mem_t)); first = 0, i++) { - if (type_mem[i].nalloc || type_mem[i].hwm) { - nsc_mem_type(first, &type_mem[i]); - } - } - - if (v_opt) - nsc_rmhdr(); - - return (DCMD_OK); -} - - -static int -nsc_mem(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - char name[16], *type, *cp; - nsc_mem_t mem, *mp; - int v_opt; - - v_opt = 0; - - if (mdb_getopts(argc, argv, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - return (nsc_mem_all(argc, argv, v_opt)); - } - - if (mdb_vread(&mem, sizeof (mem), addr) != sizeof (mem)) { - mdb_warn("failed to read nsc_mem_t at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readstr(name, sizeof (name), (uintptr_t)mem.name) == -1) { - mdb_warn("failed to read nsc_mem_t.name at %p", addr); - return (DCMD_ERR); - } - - if (!mem.nalloc && !mem.hwm && !v_opt) - return (DCMD_OK); - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("name typ f "); - mdb_printf("used hwm pgs alloc free base\n"); - } - - type = typename(mem.type); - mp = memptr(mem.type, mem.flag); - - for (cp = name; *cp; cp++) - if (*cp == ':') - *cp = ' '; - - mdb_printf("%-16s %s %2x %9d %9d %5d %5d %5d %0?p\n", - name, type, mem.flag, mem.used, mem.hwm, mem.pagehwm, - mem.nalloc, mem.nfree, mem.base); - - mp->used += mem.used; - mp->hwm += mem.hwm; - mp->pagehwm += mem.pagehwm; - mp->nalloc += mem.nalloc; - mp->nfree += mem.nfree; - - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -nsc_vec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_vec_t *vec; - - vec = mdb_zalloc(sizeof (*vec), UM_SLEEP | UM_GC); - if (mdb_vread(vec, sizeof (*vec), addr) != sizeof (*vec)) { - mdb_warn("failed to read nsc_vec at %p", addr); - return (DCMD_ERR); - } - mdb_printf("nsc_vec_t @ 0x%p = {\n", addr); - mdb_inc_indent(4); - mdb_printf("sv_addr: %p\n", vec->sv_addr); - mdb_printf("sv_vme: %lu\n", vec->sv_vme); - mdb_printf("sv_len: %d\n", vec->sv_len); - mdb_dec_indent(4); - mdb_printf("};\n"); - if (vec->sv_addr) - return (DCMD_OK); - else - return (DCMD_ERR); -} - -/* ---------------------------------------------------------------------- */ -/* - * Display an nsc_buf_t structure. - */ - -#ifdef NSC_MULTI_TERABYTE -#define STRCONV "ll" -#else -#define STRCONV "" -#endif - -/* ARGSUSED */ -static int -nsc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_buf_t *bh; - nsc_vec_t *v; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC); - - if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) { - mdb_warn("failed to read nsc_buf at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("nsc_buf_t @ 0x%p = {\n", addr); - mdb_inc_indent(4); - mdb_printf("sb_fd: 0x%p\n", bh->sb_fd); - mdb_printf("sb_pos: 0x%" STRCONV "x\n", bh->sb_pos); - mdb_printf("sb_len: 0x%" STRCONV "x\n", bh->sb_len); - mdb_printf("sb_flag: 0x%08x <%b>\n", bh->sb_flag, - bh->sb_flag, nsc_bhflag_bits); - mdb_printf("sb_error: %d\n", bh->sb_error); -#ifdef NSC_MULTI_TERABYTE - mdb_printf("sb_user: 0x%p\n", bh->sb_user); -#else - mdb_printf("sb_user: 0x%x\n", bh->sb_user); -#endif - mdb_printf("sb_vec: 0x%p\n", bh->sb_vec); - v = bh->sb_vec++; - while (nsc_vec((uintptr_t)v, flags, argc, argv) == DCMD_OK) - v++; - - mdb_dec_indent(4); - mdb_printf("};\n"); - - return (DCMD_OK); -} - -/* ---------------------------------------------------------------------- */ - -/* ARGSUSED */ -static int -nsc_dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - nsc_dbuf_t *bh; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC); - - if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) { - mdb_warn("failed to read nsc_dbuf at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("nsc_dbuf_t @ 0x%p = {\n", addr); - mdb_inc_indent(4); - mdb_printf("db_disc: 0x%p\n", bh->db_disc); - mdb_printf("db_addr: 0x%p\n", bh->db_addr); - mdb_printf("db_next: 0x%p\n", bh->db_next); - mdb_printf("db_maxfbas: 0x%d\n", bh->db_maxfbas); - - - mdb_dec_indent(4); - mdb_printf("};\n"); - - return (DCMD_OK); -} -/* ---------------------------------------------------------------------- */ - -/* - * MDB module linkage information: - */ - -static const mdb_dcmd_t dcmds[] = { -#if 0 - { "nsctl", NULL, "display nsctl module info", nsctl }, -#endif - { "nsc_buf", ":", "list nsc_buf structure", nsc_buf }, - { "nsc_dbuf", ":", "list nsc_dbuf structure", nsc_dbuf }, - { "nsc_dev", "?[-av]", "list nsc_dev structure", nsc_dev }, - { "nsc_devval", "?[-a]", "list nsc_devval structure", nsc_devval }, - { "nsc_fd", "?[-v]", "list nsc_fd structure", nsc_fd }, - { "nsc_iodev", "?[-v]", "list nsc_iodev structure", nsc_iodev }, - { "nsc_io", "?[-v]", "list nsc_io structure", nsc_io }, - { "nsc_mem", "?[-v]", "list nsc_mem structure", nsc_mem }, - { "nsc_svc", ":", "list nsc_svc structure", nsc_svc }, - { "nsc_service", "?[-v]", "list nsc_service structure", nsc_service }, - { "nsc_val", ":", "list nsc_val structure", nsc_val }, - { "nstset", "?[-frtv]", "list nstset structure", nstset }, - { "nsthread", "?[-av]", "list nsthread structure", nsthread }, - { NULL } -}; - - -static const mdb_walker_t walkers[] = { - { "nsc_dev", "walk nsc_dev chain", - nsc_dev_winit, nsc_dev_wstep, nsc_dev_wfini, NULL }, - { "nsc_devval", "walk nsc_devval chain", - nsc_devval_winit, nsc_devval_wstep, NULL, NULL }, - { "nsc_fd", "walk nsc_fd chain", - nsc_fd_winit, nsc_fd_wstep, NULL, NULL }, - { "nsc_io", "walk nsc_io chain", - nsc_io_winit, nsc_io_wstep, NULL, NULL }, - { "nsc_iodev", "walk nsc_iodev chain", - nsc_iodev_winit, nsc_iodev_wstep, NULL, NULL }, - { "nsc_mem", "walk nsc_mem chain", - nsc_mem_winit, nsc_mem_wstep, NULL, NULL }, - { "nsc_service", "walk nsc_service chain", - nsc_service_winit, nsc_service_wstep, NULL, NULL }, - { "nsc_svc", "walk nsc_svc chain", - nsc_svc_winit, nsc_svc_wstep, NULL, NULL }, - { "nsc_val", "walk nsc_val chain", - nsc_val_winit, nsc_val_wstep, NULL, NULL }, - { "nstset", "walk nstset chain", - nstset_winit, nstset_wstep, NULL, NULL }, - { "nsthread", "walk nsthread chain", - nsthread_winit, nsthread_wstep, NULL, NULL }, - { "nst_free", "walk nsthread free/reuse list", - nst_free_winit, nst_free_wstep, NULL, NULL }, - { NULL } -}; - - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/common/modules/rdc/Makefile.com b/usr/src/cmd/mdb/common/modules/rdc/Makefile.com deleted file mode 100644 index 40975cea69..0000000000 --- a/usr/src/cmd/mdb/common/modules/rdc/Makefile.com +++ /dev/null @@ -1,24 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CPPFLAGS += -DNSC_MULTI_TERABYTE diff --git a/usr/src/cmd/mdb/common/modules/rdc/rdc.c b/usr/src/cmd/mdb/common/modules/rdc/rdc.c deleted file mode 100644 index 48d8b28969..0000000000 --- a/usr/src/cmd/mdb/common/modules/rdc/rdc.c +++ /dev/null @@ -1,1563 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/mdb_modapi.h> - -#include <sys/nsctl/nsctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_k.h> - -#include <rpc/auth.h> -#include <rpc/auth_unix.h> -#include <rpc/auth_des.h> -#include <rpc/svc.h> -#include <rpc/xdr.h> -#include <rpc/svc_soc.h> - -/* HACK HACK so we can bring in rdc_io.h and friends */ -#define nstset_t char - -#include <sys/nsctl/rdc.h> -#include <sys/nsctl/rdc_prot.h> -#include <sys/nsctl/rdc_ioctl.h> -#include <sys/nsctl/rdc_io.h> -#include <sys/nsctl/rdc_bitmap.h> - -#include <sys/nsctl/nsvers.h> - - -/* - * Walker for an array of rdc_k_info_t structures. - * A global walk is assumed to start at rdc_k_info. - */ - -struct rdc_kinfo_winfo { - uintptr_t start; - uintptr_t end; -}; - -char bitstr[33] = { '0' }; - -static int -rdc_k_info_winit(mdb_walk_state_t *wsp) -{ - struct rdc_kinfo_winfo *winfo; - rdc_k_info_t *rdc_k_info; - int rdc_max_sets; - - winfo = mdb_zalloc(sizeof (struct rdc_kinfo_winfo), UM_SLEEP); - - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - mdb_free(winfo, sizeof (struct rdc_kinfo_winfo)); - return (WALK_ERR); - } - - if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) { - mdb_warn("failed to read 'rdc_max_sets'"); - mdb_free(winfo, sizeof (struct rdc_kinfo_winfo)); - return (WALK_ERR); - } - - winfo->start = (uintptr_t)rdc_k_info; - winfo->end = (uintptr_t)(rdc_k_info + rdc_max_sets); - - if (wsp->walk_addr == NULL) - wsp->walk_addr = winfo->start; - - wsp->walk_data = winfo; - return (WALK_NEXT); -} - - -static int -rdc_k_info_wstep(mdb_walk_state_t *wsp) -{ - struct rdc_kinfo_winfo *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (rdc_k_info_t); - return (status); -} - - -static void -rdc_k_info_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct rdc_kinfo_winfo)); -} - -/* - * Walker for an array of rdc_u_info_t structures. - * A global walk is assumed to start at rdc_u_info. - */ - -struct rdc_uinfo_winfo { - uintptr_t start; - uintptr_t end; -}; - - -static int -rdc_u_info_winit(mdb_walk_state_t *wsp) -{ - struct rdc_uinfo_winfo *winfo; - rdc_u_info_t *rdc_u_info; - int rdc_max_sets; - - winfo = mdb_zalloc(sizeof (struct rdc_uinfo_winfo), UM_SLEEP); - - if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { - mdb_warn("failed to read 'rdc_u_info'"); - mdb_free(winfo, sizeof (struct rdc_uinfo_winfo)); - return (WALK_ERR); - } - - if (mdb_readvar(&rdc_max_sets, "rdc_max_sets") == -1) { - mdb_warn("failed to read 'rdc_max_sets'"); - mdb_free(winfo, sizeof (struct rdc_uinfo_winfo)); - return (WALK_ERR); - } - - winfo->start = (uintptr_t)rdc_u_info; - winfo->end = (uintptr_t)(rdc_u_info + rdc_max_sets); - - if (wsp->walk_addr == NULL) - wsp->walk_addr = winfo->start; - - wsp->walk_data = winfo; - return (WALK_NEXT); -} - - -static int -rdc_u_info_wstep(mdb_walk_state_t *wsp) -{ - struct rdc_uinfo_winfo *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (rdc_u_info_t); - return (status); -} - - -static void -rdc_u_info_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct rdc_uinfo_winfo)); -} - -/* - * Walker for the rdc_if chain. - * A global walk is assumed to start at rdc_if_top. - */ - -static int -rdc_if_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "rdc_if_top") == -1) { - mdb_warn("unable to read 'rdc_if_top'"); - return (WALK_ERR); - } - - wsp->walk_data = mdb_zalloc(sizeof (rdc_if_t), UM_SLEEP); - - return (WALK_NEXT); -} - - -static int -rdc_if_wstep(mdb_walk_state_t *wsp) -{ - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(wsp->walk_data, - sizeof (rdc_if_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read rdc_if at %p", wsp->walk_addr); - return (WALK_DONE); - } - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)(((rdc_if_t *)wsp->walk_data)->next); - return (status); -} - - -static void -rdc_if_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (rdc_if_t)); -} - -/* - * Displays the asynchronous sleep q on the server. - */ -/*ARGSUSED*/ -static int -rdc_sleepq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_sleepq_t sq; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - while (addr) { - if (mdb_vread(&sq, sizeof (sq), addr) != sizeof (sq)) { - mdb_warn("failed to read rdc_sleepq at %p", addr); - return (DCMD_ERR); - } - mdb_printf("sequence number %u qpos %d \n", sq.seq, sq.qpos); - addr = (uintptr_t)sq.next; - } - return (DCMD_OK); -} - -/* - * display the header info for the pending diskq requests - */ -/*ARGSUSED*/ -static int -rdc_iohdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - io_hdr hdr; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - while (addr) { - if (mdb_vread(&hdr, sizeof (io_hdr), addr) != sizeof (io_hdr)) { - mdb_warn("failed to read io_hdr at %p", addr); - return (DCMD_ERR); - } - mdb_printf("iohdr: type %d pos %d qpos %d len %d flag 0x%x" - " iostatus %x setid %d next %p\n", hdr.dat.type, hdr.dat.pos, - hdr.dat.qpos, hdr.dat.len, hdr.dat.flag, hdr.dat.iostatus, - hdr.dat.setid, hdr.dat.next); - - addr = (uintptr_t)hdr.dat.next; - } - return (DCMD_OK); -} - -/* - * Display a krdc->group. - * Requires an address. - */ -/*ARGSUSED*/ -static int -rdc_group(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - struct rdc_group *group; - disk_queue *dq; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - - group = mdb_zalloc(sizeof (*group), UM_GC); - - if (mdb_vread(group, sizeof (*group), addr) != sizeof (*group)) { - mdb_warn("failed to read rdc_group at %p", addr); - return (DCMD_ERR); - } -#ifdef XXXJET - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-8s %8T%s\n", "ADDR", "MAJOR", "INUSE"); - } -#endif - mdb_printf("count: %d %8Twriter: %d %8T flags: %d\n", - group->count, group->rdc_writer, group->flags); - mdb_printf("thread num %d\n", group->rdc_thrnum); - - dq = &group->diskq; - if (RDC_IS_MEMQ(group)) { - mdb_printf("queue type: Memory based\n"); - } else if (RDC_IS_DISKQ(group)) { - mdb_printf("queue type: Disk based %8Tqstate 0x%x\n", - QSTATE(dq)); - } - mdb_printf("ra_queue head: 0x%p %8Ttail 0x%p\n", - group->ra_queue.net_qhead, group->ra_queue.net_qtail); - mdb_printf("ra_queue blocks: %d %8Titems %d\n", - group->ra_queue.blocks, group->ra_queue.nitems); - mdb_printf("ra_queue blockhwm: %d itemhwm: %d\n", - group->ra_queue.blocks_hwm, group->ra_queue.nitems_hwm); - mdb_printf("ra_queue hwmhit: %d qfillsleep: %d\n", - group->ra_queue.hwmhit, group->ra_queue.qfill_sleeping); - mdb_printf("ra_queue throttle: %ld\n", - group->ra_queue.throttle_delay); - - if (RDC_IS_DISKQ(group)) { - mdb_printf("head: %d %8Tnxtio: %d %8Ttail %d %8Tlastail: %d\n", - QHEAD(dq), QNXTIO(dq), QTAIL(dq), LASTQTAIL(dq)); - mdb_printf("coalbounds: %d %8Tqwrap: %d\n", QCOALBOUNDS(dq), - QWRAP(dq)); - mdb_printf("blocks: %d %8Titems %d qfflags 0x%x \n", - QBLOCKS(dq), QNITEMS(dq), group->ra_queue.qfflags); - mdb_printf("diskq throttle: %ld %8Tflags: %x\n", - dq->throttle_delay, group->flags); - mdb_printf("disk queue nitems_hwm: %d %8Tblocks_hwm: %d\n", - dq->nitems_hwm, dq->blocks_hwm); - mdb_printf("diskqfd: 0x%p %8Tdisqrsrv: %d lastio: 0x%p\n", - group->diskqfd, group->diskqrsrv, dq->lastio); - mdb_printf("outstanding req %d iohdrs 0x%p iohdrs_last 0x%p\n", - dq->hdrcnt, dq->iohdrs, dq->hdr_last); - } - mdb_printf("seq: %u\n", group->seq); - mdb_printf("seqack: %u\n", group->seqack); - mdb_printf("sleepq: 0x%p\n", group->sleepq); - mdb_printf("asyncstall %d\n", group->asyncstall); - mdb_printf("asyncdis %d\n", group->asyncdis); - - mdb_inc_indent(4); - if (group->sleepq) { - rdc_sleepq((uintptr_t)group->sleepq, DCMD_ADDRSPEC, - 0, 0); - } - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* - * Display a krdc->lsrv. - * Requires an address. - */ -/*ARGSUSED*/ -static int -rdc_srv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_srv_t *lsrv; - char name[MAX_RDC_HOST_SIZE]; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - - lsrv = mdb_zalloc(sizeof (*lsrv), UM_GC); - - if (mdb_vread(lsrv, sizeof (*lsrv), addr) != sizeof (*lsrv)) { - mdb_warn("failed to read rdc_srv at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readstr(name, sizeof (name), - (uintptr_t)lsrv->ri_hostname) == -1) { - mdb_warn("failed to read ri_hostname name at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("host: %s %16Tri_knconf 0x%p\n", name, lsrv->ri_knconf); - - mdb_printf("ri_addr: 0x%p %8Tsecdata 0x%p\n", - addr + OFFSETOF(rdc_srv_t, ri_addr), lsrv->ri_secdata); - - return (DCMD_OK); -} - -/* - * Display a rdc_if_t. - * Requires an address. - */ -static int -rdc_if(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_if_t *ifp; - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("rdc`rdc_if", - "rdc`rdc_if", argc, argv) == -1) { - mdb_warn("failed to walk 'rdc_if'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - ifp = mdb_zalloc(sizeof (*ifp), UM_GC); - - if (mdb_vread(ifp, sizeof (*ifp), addr) != sizeof (*ifp)) { - mdb_warn("failed to read rdc_srv at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("next: 0x%p %8Tsrv 0x%p\n", ifp->next, ifp->srv); - mdb_printf("if_addr: 0x%p %8Tr_ifaddr 0x%p\n", - addr + OFFSETOF(rdc_if_t, ifaddr), - addr + OFFSETOF(rdc_if_t, r_ifaddr)); - mdb_printf("if_down: %d %8Tprimary %d %8Tsecondary %d\n", - ifp->if_down, ifp->isprimary, ifp->issecondary); - mdb_printf("version %d %8Tnoping %d\n", ifp->rpc_version, - ifp->no_ping); - mdb_printf("\n"); - - return (DCMD_OK); -} - - -/* - * Display a rdc_buf_t - * Requires an address. - */ -/*ARGSUSED*/ -static int -rdc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_buf_t *buf; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - - buf = mdb_zalloc(sizeof (*buf), UM_GC); - - if (mdb_vread(buf, sizeof (*buf), addr) != sizeof (*buf)) { - mdb_warn("failed to read rdc_buf at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("nsc_buf fd: 0x%p %8Tvec 0x%p\n", - buf->rdc_bufh.sb_fd, buf->rdc_bufh.sb_vec); - - mdb_printf("nsc_buf pos: %d %8Tlen %d\n", - buf->rdc_bufh.sb_pos, buf->rdc_bufh.sb_len); - - mdb_printf("nsc_buf flag: 0x%x %8Terror %d\n", - buf->rdc_bufh.sb_flag, buf->rdc_bufh.sb_error); - - mdb_printf("anon_buf : 0x%p %8Tfd 0x%p %8Tbufp 0x%p\n", - buf->rdc_anon, buf->rdc_fd, buf->rdc_bufp); - - mdb_printf("vsize: %d %8Tflags 0x%x\n", - buf->rdc_vsize, buf->rdc_flags); - - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -rdc_aio(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_aio_t *aio; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - aio = mdb_zalloc(sizeof (*aio), UM_GC); - - if (mdb_vread(aio, sizeof (*aio), addr) != sizeof (*aio)) { - mdb_warn("failed to read rdc_aio at %p", addr); - return (DCMD_ERR); - } - mdb_printf("rdc_aio next: %p %8T nsc_buf: %p %8T nsc_qbuf %p\n", - aio->next, aio->handle, aio->qhandle); - mdb_printf("pos: %d len: %d qpos: %d flag: %x iostatus: %d index: %d" - " seq: %d\n", aio->pos, aio->len, aio->qpos, aio->flag, - aio->iostatus, aio->index, aio->seq); - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -rdc_dset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_net_dataset_t *dset; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - dset = mdb_zalloc(sizeof (*dset), UM_GC); - - if (mdb_vread(dset, sizeof (*dset), addr) != sizeof (*dset)) { - mdb_warn("failed to read dset at %p", addr); - return (DCMD_ERR); - } - mdb_printf("dset id: %d %8T dset inuse: %d %8T dset delpend: %d\n", - dset->id, dset->inuse, dset->delpend); - mdb_printf("dset items: %d %8T dset head %p %8T dset tail %p \n", - dset->nitems, dset->head, dset->tail); - mdb_printf("dset pos %d %8T dset len %d\n", dset->pos, dset->fbalen); - - return (DCMD_OK); -} -/* - * Display a single rdc_k_info structure. - * If called with no address, performs a global walk of all rdc_k_info. - * -a : all (i.e. display all devices, even if disabled - * -v : verbose - */ - -const mdb_bitmask_t sv_flag_bits[] = { - { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, - { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, - { NULL, 0, 0 } -}; - -static int -rdc_kinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *krdc; - rdc_u_info_t *rdc_u_info, *urdc; - int a_opt, v_opt; - int dev_t_chars; - - a_opt = v_opt = FALSE; - dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - urdc = mdb_zalloc(sizeof (*urdc), UM_GC); - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("rdc`rdc_kinfo", - "rdc`rdc_kinfo", argc, argv) == -1) { - mdb_warn("failed to walk 'rdc_kinfo'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", - dev_t_chars, "TFLAG", "STATE"); - } - - if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { - mdb_warn("failed to read rdc_k_info at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { - mdb_warn("failed to read 'rdc_u_info'"); - return (DCMD_ERR); - } - - urdc = &rdc_u_info[krdc->index]; - - if (!a_opt && ((krdc->type_flag & RDC_CONFIGURED) == 0)) - return (DCMD_OK); - - mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, krdc->type_flag); - - - if (krdc->type_flag & RDC_DISABLEPEND) - mdb_printf(" disable pending"); - if (krdc->type_flag & RDC_ASYNCMODE) - mdb_printf(" async"); - if (krdc->type_flag & RDC_RESUMEPEND) - mdb_printf(" resume pending"); - if (krdc->type_flag & RDC_BUSYWAIT) - mdb_printf(" busywait"); -#ifdef RDC_SMALLIO - if (krdc->type_flag & RDC_SMALLIO) - mdb_printf(" smallio"); -#endif - - mdb_printf("\n"); - - if (!v_opt) - return (DCMD_OK); - - /* - * verbose - print the rest of the structure as well. - */ - - mdb_inc_indent(4); - - mdb_printf("index: %d %8Trindex: %d %8Tbusyc: %d %8Tmaxfbas: %d\n", - krdc->index, krdc->remote_index, krdc->busy_count, krdc->maxfbas); - - mdb_printf("info_dev: 0x%p %8Tiodev: 0x%p %8T %8T vers %d\n", - krdc->devices, krdc->iodev, krdc->rpc_version); - - mdb_printf("iokstats: 0x%p\n", krdc->io_kstats); - mdb_printf("group: 0x%p %8Tgroup_next: 0x%p\n", - krdc->group, krdc->group_next); - mdb_printf("group lock: 0x%p aux_state: %d\n", - &krdc->group->lock, krdc->aux_state); - - mdb_inc_indent(4); - if (krdc->type_flag & RDC_ASYNCMODE) { - rdc_group((uintptr_t)krdc->group, DCMD_ADDRSPEC, 0, 0); - } - mdb_dec_indent(4); - - mdb_printf("servinfo: 0x%p %8Tintf: 0x%p\nbitmap: 0x%p %8T" - "bitmap_ref: 0x%p\n", - krdc->lsrv, krdc->intf, krdc->dcio_bitmap, krdc->bitmap_ref); - - mdb_printf("bmap_size: %d %8Tbmaprsrv: %d%8T bmap_write: %d\n", - krdc->bitmap_size, krdc->bmaprsrv, krdc->bitmap_write); - - mdb_printf("bitmapfd: 0x%p %8Tremote_fd: 0x%p %8T\n", krdc->bitmapfd, - krdc->remote_fd); - - mdb_printf("net_dataset: 0x%p %8Tdisk_status: %d %8T\n", - krdc->net_dataset, krdc->disk_status); - - mdb_printf("many: 0x%p %8Tmulti: 0x%p %8T\n", krdc->many_next, - krdc->multi_next); - - mdb_printf("rdc_uinfo: 0x%p\n\n", urdc); - mdb_dec_indent(4); - return (DCMD_OK); -} - - -static int -rdc_uinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_u_info_t *urdc; - rdc_k_info_t *rdc_k_info, *krdc, krdc1; - rdc_group_t grp; - disk_queue *dqp = NULL; - int a_opt, v_opt; - int dev_t_chars; - int rdcflags; - - a_opt = v_opt = FALSE; - dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - urdc = mdb_zalloc(sizeof (*urdc), UM_GC); - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("rdc`rdc_uinfo", - "rdc`rdc_uinfo", argc, argv) == -1) { - mdb_warn("failed to walk 'rdc_uinfo'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", - dev_t_chars, "FLAG", "STATE"); - } - - if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) { - mdb_warn("failed to read rdc_u_info at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - - krdc = &rdc_k_info[urdc->index]; - - if (!a_opt && ((urdc->flags & RDC_ENABLED) == 0)) - return (DCMD_OK); - - - if (mdb_vread(&krdc1, sizeof (krdc1), - (uintptr_t)krdc) != sizeof (krdc1)) { - mdb_warn("failed to read 'rdc_k_info1'"); - return (DCMD_ERR); - } - - if (krdc1.group) { - if (mdb_vread(&grp, sizeof (grp), - (uintptr_t)krdc1.group) != sizeof (grp)) { - mdb_warn("failed to read group info "); - return (DCMD_ERR); - } - dqp = &grp.diskq; - } - - rdcflags = (urdc->flags | urdc->sync_flags | urdc->bmap_flags); - mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, rdcflags); - - - if (rdcflags & RDC_PRIMARY) - mdb_printf(" primary"); - if (rdcflags & RDC_SLAVE) - mdb_printf(" slave"); - if (rdcflags & RDC_SYNCING) - mdb_printf(" syncing"); - if (rdcflags & RDC_SYNC_NEEDED) - mdb_printf(" sync_need"); - if (rdcflags & RDC_RSYNC_NEEDED) - mdb_printf(" rsync_need"); - if (rdcflags & RDC_LOGGING) - mdb_printf(" logging"); - if (rdcflags & RDC_QUEUING) - mdb_printf(" queuing"); - if (rdcflags & RDC_DISKQ_FAILED) - mdb_printf(" diskq failed"); - if (rdcflags & RDC_VOL_FAILED) - mdb_printf(" vol failed"); - if (rdcflags & RDC_BMP_FAILED) - mdb_printf(" bmp failed"); - if (rdcflags & RDC_ASYNC) - mdb_printf(" async"); - if (rdcflags & RDC_CLR_AFTERSYNC) - mdb_printf(" clr_bitmap_aftersync"); - if (dqp) { - if (IS_QSTATE(dqp, RDC_QNOBLOCK)) - mdb_printf(" noblock"); - } -#ifdef RDC_SMALLIO - if (rdcflags & RDC_SMALLIO) - mdb_printf(" smallio"); -#endif - - mdb_printf("\n"); - - if (!v_opt) - return (DCMD_OK); - - /* - * verbose - print the rest of the structure as well. - */ - - mdb_inc_indent(4); - mdb_printf("\n"); - - mdb_printf("primary: %s %8Tfile: %s \nbitmap: %s ", - urdc->primary.intf, urdc->primary.file, urdc->primary.bitmap); - mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, primary)); - mdb_printf("secondary: %s %8Tfile: %s \nbitmap: %s ", - urdc->secondary.intf, urdc->secondary.file, urdc->secondary.bitmap); - mdb_printf("netbuf: 0x%p\n", addr + OFFSETOF(rdc_set_t, secondary)); - - mdb_printf("sflags: %d %8Tbflags: %d%8T mflags: %d\n", - urdc->sync_flags, urdc->bmap_flags, urdc->mflags); - mdb_printf("index: %d %8Tsync_pos: %d%8T vsize: %d\n", - urdc->index, urdc->sync_pos, urdc->volume_size); - mdb_printf("setid: %d %8Tbits set: %d %8Tautosync: %d\n", - urdc->setid, urdc->bits_set, urdc->autosync); - mdb_printf("maxqfbas: %d %8Tmaxqitems: %d\n", - urdc->maxqfbas, urdc->maxqitems); - mdb_printf("netconfig: %p\n", urdc->netconfig); - mdb_printf("group: %s %8TdirectIO: %s\n", - urdc->group_name, urdc->direct_file); - mdb_printf("diskqueue: %s ", urdc->disk_queue); - if (dqp) { - mdb_printf("diskqsize: %d\n", QSIZE(dqp)); - } else { - mdb_printf("\n"); - } - mdb_printf("rdc_k_info: 0x%p\n", krdc); - mdb_printf("\n"); - mdb_dec_indent(4); - - mdb_printf("\n"); - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -rdc_infodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_info_dev_t *infodev; - _rdc_info_dev_t *infp; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - infodev = mdb_zalloc(sizeof (*infodev), UM_GC); - infp = mdb_zalloc(sizeof (*infp), UM_GC); - - if (mdb_vread(infodev, sizeof (*infodev), addr) != sizeof (*infodev)) { - mdb_warn("failed to read rdc_infodev at 0x%p\n", addr); - return (DCMD_ERR); - } - - infp = &infodev->id_cache_dev; - mdb_inc_indent(4); - - mdb_printf("id_next: 0x%p\n", infodev->id_next); - mdb_printf("id_cache_dev:\n"); - - mdb_inc_indent(4); - mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n", - infp->bi_fd, infp->bi_iodev, infp->bi_krdc); - mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n" - "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv, - infp->bi_failed, infp->bi_ofailed, infp->bi_flag); - - infp = &infodev->id_raw_dev; - - mdb_dec_indent(4); - mdb_printf("id_cache_dev:\n"); - mdb_inc_indent(4); - - mdb_printf("bi_fd: 0x%p %8Tbi_iodev: 0x%p %8Tbi_krdc 0x%p\n", - infp->bi_fd, infp->bi_iodev, infp->bi_krdc); - mdb_printf("bi_rsrv: %d %8Tbi_orsrv: %d %8Tbi_failed: %d %8T\n" - "bi_ofailed: %d %8Tbi_flag: %d\n", infp->bi_rsrv, infp->bi_orsrv, - infp->bi_failed, infp->bi_ofailed, infp->bi_flag); - - mdb_dec_indent(4); - - mdb_printf("id_sets: %d %8Tid_release: %d %8Tid_flag %d", - infodev->id_sets, infodev->id_release, infodev->id_flag); - - if (infodev->id_flag & RDC_ID_CLOSING) { - mdb_printf("closing"); - } - mdb_printf("\n"); - - mdb_dec_indent(4); - return (DCMD_OK); -} - -/* - * Display general sv module information. - */ - -#define rdc_get_print(kvar, str, fmt, val) \ - if (mdb_readvar(&(val), #kvar) == -1) { \ - mdb_dec_indent(4); \ - mdb_warn("unable to read '" #kvar "'"); \ - return (DCMD_ERR); \ - } \ - mdb_printf("%-20s" fmt "\n", str ":", val) - -/*ARGSUSED*/ -static int -rdc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int maj, min, mic, baseline, i; - - if (argc != 0) - return (DCMD_USAGE); - - if (mdb_readvar(&maj, "sndr_major_rev") == -1) { - mdb_warn("unable to read 'sndr_major_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&min, "sndr_minor_rev") == -1) { - mdb_warn("unable to read 'sndr_minor_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&mic, "sndr_micro_rev") == -1) { - mdb_warn("unable to read 'sndr_micro_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&baseline, "sndr_baseline_rev") == -1) { - mdb_warn("unable to read 'sndr_baseline_rev'"); - return (DCMD_ERR); - } - - mdb_printf("Remote Mirror module version: kernel %d.%d.%d.%d; " - "mdb %d.%d.%d.%d\n", maj, min, mic, baseline, - ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); - mdb_inc_indent(4); - - rdc_get_print(rdc_debug, "debug", "%d", i); - rdc_get_print(rdc_bitmap_mode, "bitmap mode", "%d", i); - rdc_get_print(rdc_max_sets, "max sndr devices", "%d", i); - rdc_get_print(rdc_rpc_tmout, "client RPC timeout", "%d", i); - rdc_get_print(rdc_health_thres, "health threshold", "%d", i); - rdc_get_print(MAX_RDC_FBAS, "max trans fba", "%d", i); - - mdb_dec_indent(4); - return (DCMD_OK); -} - -static int -rdc_k2u(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *krdc; - rdc_u_info_t *rdc_u_info, *urdc; - int rc; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - urdc = mdb_zalloc(sizeof (*urdc), UM_GC); - - if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { - mdb_warn("failed to read krdc at %p", addr); - return (DCMD_ERR); - } - - if (mdb_readvar(&rdc_u_info, "rdc_u_info") == -1) { - mdb_warn("failed to read 'rdc_u_info'"); - return (DCMD_ERR); - } - - urdc = &rdc_u_info[krdc->index]; - - rc = rdc_uinfo((uintptr_t)urdc, DCMD_ADDRSPEC, argc, argv); - return (rc); -} - -static int -rdc_u2k(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_u_info_t *urdc; - rdc_k_info_t *rdc_k_info, *krdc; - int rc; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - urdc = mdb_zalloc(sizeof (*urdc), UM_GC); - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - - if (mdb_vread(urdc, sizeof (*urdc), addr) != sizeof (*urdc)) { - mdb_warn("failed to read urdc at %p\n", addr); - return (DCMD_ERR); - } - - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - - krdc = &rdc_k_info[urdc->index]; - - rc = rdc_kinfo((uintptr_t)krdc, DCMD_ADDRSPEC, argc, argv); - return (rc); -} - -#ifdef DEBUG -/* - * This routine is used to set the seq field in the rdc_kinfo->group - * structure. Used to test that the queue code handles the integer - * overflow correctly. - * Takes two arguments index and value. - * The index is the index into the kinfo structure array and - * the value is the new value to set into the seq field. - */ -/*ARGSUSED*/ -static int -rdc_setseq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *rdc_k_info; - rdc_group_t *group; - int index; - uint_t val; - uintptr_t pokeaddr; - - if (argc != 2) { - mdb_warn("must have two arguments, index and value\n"); - return (DCMD_ERR); - } - - index = (int)mdb_strtoull(argv[0].a_un.a_str); - val = (uint_t)mdb_strtoull(argv[1].a_un.a_str); - - /* - * Find out where in memory the seq field. - * The structure offset first. - */ - - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - pokeaddr = (uintptr_t)&rdc_k_info[index].group; - if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) != - sizeof (rdc_group_t *)) { - mdb_warn("failed to fetch the group structure for set %d\n", - index); - return (DCMD_ERR); - } - pokeaddr = (uintptr_t)(&group->seq); - if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) { - mdb_warn("failed to write seq at %p\n", pokeaddr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - -/* - * This routine is used to set the seqack field in the rdc_kinfo->group - * structure. Used to test that the queue code handles the integer - * overflow correctly. - * Takes two arguments index and value. - * The index is the index into the kinfo structure array and - * the value is the new value to set into the seqack field. - */ -/*ARGSUSED*/ -static int -rdc_setseqack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *rdc_k_info; - rdc_group_t *group; - int index; - uint_t val; - uintptr_t pokeaddr; - - if (argc != 2) { - mdb_warn("must have two arguments, index and value\n"); - return (DCMD_ERR); - } - - index = (int)mdb_strtoull(argv[0].a_un.a_str); - val = (uint_t)mdb_strtoull(argv[1].a_un.a_str); - - /* - * Find out where in memory the seqack field. - * The structure offset first. - */ - - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - pokeaddr = (uintptr_t)&rdc_k_info[index].group; - if (mdb_vread(&group, sizeof (rdc_group_t *), pokeaddr) != - sizeof (rdc_group_t *)) { - mdb_warn("failed to fetch the group structure for set %d\n", - index); - return (DCMD_ERR); - } - pokeaddr = (uintptr_t)(&group->seqack); - if (mdb_vwrite(&val, sizeof (val), pokeaddr) != sizeof (val)) { - mdb_warn("failed to write seqack at %p\n", pokeaddr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - -/* - * random define printing stuff, just does the define, and print the result - */ -/*ARGSUSED*/ -static int -fba_to_log_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int num; - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - num = (int)mdb_strtoull(argv[0].a_un.a_str); - num = FBA_TO_LOG_NUM(num); - mdb_printf("LOG NUM: %d (0x%x)", num, num); - - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -log_to_fba_num(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int num; - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - num = (int)mdb_strtoull(argv[0].a_un.a_str); - num = LOG_TO_FBA_NUM(num); - mdb_printf("LOG NUM: %d (0x%x)", num, num); - - return (DCMD_OK); -} - -static int -bmap_bit_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int st; - int i, num; - rdc_k_info_t *krdc; - unsigned char *bmap; - unsigned char *bmaddr; - int bmsize; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - - if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { - mdb_warn("failed to read rdc_k_info at %p", addr); - return (DCMD_ERR); - } - - bmaddr = krdc->dcio_bitmap; - bmsize = krdc->bitmap_size; - bmap = mdb_zalloc(bmsize, UM_GC); - if (mdb_vread(bmap, bmsize, (uintptr_t)bmaddr) != bmsize) { - mdb_warn("failed to read bitmap"); - return (DCMD_ERR); - } - - num = (int)mdb_strtoull(argv[0].a_un.a_str); - st = FBA_TO_LOG_NUM(num); - i = BMAP_BIT_ISSET(bmap, st); - mdb_printf(" BIT (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT", - bmap[IND_BYTE(st)] & 0xff); - - return (DCMD_OK); -} - -static int -bmap_bitref_isset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int num, st, i; - rdc_k_info_t *krdc; - unsigned char *brefbyte; - unsigned int *brefint; - void *bradder; - int brsize; - size_t refcntsize = sizeof (unsigned char); - struct bm_ref_ops *refops; - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - - krdc = mdb_zalloc(sizeof (*krdc), UM_GC); - - if (mdb_vread(krdc, sizeof (*krdc), addr) != sizeof (*krdc)) { - mdb_warn("failed to read rdc_k_info at %p", addr); - return (DCMD_ERR); - } - - bradder = krdc->bitmap_ref; - refops = mdb_zalloc(sizeof (*refops), UM_GC); - if (mdb_vread(refops, sizeof (*refops), (uintptr_t)krdc->bm_refs) != - sizeof (*refops)) { - mdb_warn("failed to read bm_refops at %p", krdc->bm_refs); - return (DCMD_ERR); - } - refcntsize = refops->bmap_ref_size; - brsize = krdc->bitmap_size * BITS_IN_BYTE * refcntsize; - if (refcntsize == sizeof (unsigned char)) { - brefbyte = mdb_zalloc(brsize, UM_GC); - if (mdb_vread(brefbyte, brsize, (uintptr_t)bradder) != brsize) { - mdb_warn("failed to read bitmap"); - return (DCMD_ERR); - } - } else { - brefint = mdb_zalloc(brsize, UM_GC); - if (mdb_vread(brefint, brsize, (uintptr_t)bradder) != brsize) { - mdb_warn("failed to read bitmap"); - return (DCMD_ERR); - } - } - - num = (int)mdb_strtoull(argv[0].a_un.a_str); - st = FBA_TO_LOG_NUM(num); - if (refcntsize == sizeof (unsigned char)) - i = brefbyte[st]; - else - i = brefint[st]; - - mdb_printf("BITREF (%d) for %x %s set (%02x)", st, num, i?"IS":"IS NOT", - i); - - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -ind_byte(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int num; - - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str)); - mdb_printf("IND_BYTE: %d", IND_BYTE(num)); - - return (DCMD_OK); -} - -/*ARGSUSED*/ -static int -ind_bit(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int num; - - if (argc < 1) { - mdb_warn("must have an argument\n"); - return (DCMD_ERR); - } - num = FBA_TO_LOG_NUM((int)mdb_strtoull(argv[0].a_un.a_str)); - mdb_printf("IND_BIT: %d 0x%x", IND_BIT(num), IND_BIT(num)); - - return (DCMD_OK); -} - -static char * -print_bit(uint_t bitmask) -{ - int bitval = 1; - int i; - - bitstr[32] = '\0'; - - for (i = 31; i >= 0; i--) { - if (bitmask & bitval) { - bitstr[i] = '1'; - } else { - bitstr[i] = '0'; - } - bitval *= 2; - } - return (bitstr); -} - -/*ARGSUSED*/ -static int -rdc_bitmask(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - uint_t bitmask = 0; - int first, st, en, pos, len; - - if (argc < 2) { - mdb_warn("must have 2 args (pos, len)\n"); - return (DCMD_ERR); - } - pos = (int)mdb_strtoull(argv[0].a_un.a_str); - len = (int)mdb_strtoull(argv[1].a_un.a_str); - - if (len <= 0) { - mdb_printf("non positive len specified"); - return (DCMD_ERR); - } - - if ((len - pos) > 2048) { - mdb_printf("len out of range, 32 bit bitmask"); - return (DCMD_ERR); - } - - first = st = FBA_TO_LOG_NUM(pos); - en = FBA_TO_LOG_NUM(pos + len - 1); - while (st <= en) { - BMAP_BIT_SET((uchar_t *)&bitmask, st - first); - st++; - } - - mdb_printf("bitmask for POS: %d LEN: %d : 0x%08x (%s)", pos, len, - bitmask & 0xffffffff, print_bit(bitmask)); - return (DCMD_OK); - -} - -/* - * Dump the bitmap of the krdc structure indicated by the index - * argument. Used by the ZatoIchi tests. - */ -/*ARGSUSED*/ -static int -rdc_bmapdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *rdc_k_info; - int index; - uintptr_t bmapaddr; - uintptr_t bmapdata; - unsigned char *data; - int bmapsize; - int i; - int st = 0; - int en = 0; - - if (argc < 1) { - mdb_warn("must have index argument\n"); - return (DCMD_ERR); - } - - i = argc; - if (i == 3) { - en = (int)mdb_strtoull(argv[2].a_un.a_str); - en = FBA_TO_LOG_NUM(en); - i--; - } - if (i == 2) { - st = (int)mdb_strtoull(argv[1].a_un.a_str); - st = FBA_TO_LOG_NUM(st); - } - - index = (int)mdb_strtoull(argv[0].a_un.a_str); - /* - * Find out where in memory the rdc_k_kinfo array starts - */ - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size); - if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr) - != sizeof (bmapsize)) { - mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); - return (DCMD_ERR); - } - - bmapaddr = (uintptr_t)(&rdc_k_info[index].dcio_bitmap); - if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr) - != sizeof (bmapdata)) { - mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); - return (DCMD_ERR); - } - data = mdb_zalloc(bmapsize, UM_SLEEP); - - if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) { - mdb_warn("failed to read the bitmap data\n"); - mdb_free(data, bmapsize); - return (DCMD_ERR); - } - mdb_printf("bitmap data address 0x%p bitmap size %d\n" - "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]); - - if ((st < 0) || ((st/8) > bmapsize) || (en < 0)) { - mdb_warn("offset is out of range st %d bms %d en %d", - st, bmapsize, en); - return (DCMD_ERR); - } - if (((en/8) > bmapsize) || (en == 0)) - en = bmapsize * 8; - - mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en); - st /= 8; - en /= 8; - for (i = st; i < en; i++) { - mdb_printf("%02x ", data[i] & 0xff); - if ((i % 16) == 15) { - int s = LOG_TO_FBA_NUM((i-15)*8); - int e = LOG_TO_FBA_NUM(((i+1)*8)) - 1; - mdb_printf(" fbas: %x - %x\n", s, e); - } - } - mdb_printf("\n"); - mdb_free(data, bmapsize); - return (DCMD_OK); -} - -/* - * dump the bitmap reference count - */ -/*ARGSUSED*/ -static int -rdc_brefdump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - rdc_k_info_t *rdc_k_info; - int index; - uintptr_t bmapaddr; - uintptr_t bmapdata; - unsigned char *data; - int bmapsize; - int i; - int st = 0; - int en = 0; - - if (argc < 1) { - mdb_warn("must have index argument\n"); - return (DCMD_ERR); - } - index = (int)mdb_strtoull(argv[0].a_un.a_str); - - i = argc; - if (i == 3) { - en = (int)mdb_strtoull(argv[2].a_un.a_str); - en = FBA_TO_LOG_NUM(en); - i--; - - } - if (i == 2) { - st = (int)mdb_strtoull(argv[1].a_un.a_str); - st = FBA_TO_LOG_NUM(st); - } - - /* - * Find out where in memory the rdc_k_kinfo array starts - */ - if (mdb_readvar(&rdc_k_info, "rdc_k_info") == -1) { - mdb_warn("failed to read 'rdc_k_info'"); - return (DCMD_ERR); - } - bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_size); - - if (mdb_vread(&bmapsize, sizeof (bmapsize), bmapaddr) - != sizeof (bmapsize)) { - mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); - return (DCMD_ERR); - } - - bmapsize *= 8; - bmapaddr = (uintptr_t)(&rdc_k_info[index].bitmap_ref); - - if (mdb_vread(&bmapdata, sizeof (bmapdata), bmapaddr) - != sizeof (bmapdata)) { - mdb_warn("failed to read dcio_bitmap at %p\n", bmapaddr); - return (DCMD_ERR); - } - data = mdb_zalloc(bmapsize, UM_SLEEP); - - if (mdb_vread(data, bmapsize, bmapdata) != bmapsize) { - mdb_warn("failed to read the bitmap data\n"); - mdb_free(data, bmapsize); - return (DCMD_ERR); - } - mdb_printf("bitmap data address 0x%p bitmap size %d\n" - "kinfo 0x%p\n", bmapdata, bmapsize, &rdc_k_info[index]); - - if ((st < 0) || (st > bmapsize) || (en < 0)) { - mdb_warn("offset is out of range"); - } - if ((en > bmapsize) || (en == 0)) - en = bmapsize; - - mdb_printf("bit start pos: %d bit end pos: %d\n\n", st, en); - - for (i = st; i < en; i++) { - mdb_printf("%02x ", data[i] & 0xff); - if ((i % 16) == 15) { - int s = LOG_TO_FBA_NUM(i-15); - int e = LOG_TO_FBA_NUM(i+1) - 1; - mdb_printf(" fbas: 0x%x - 0x%x \n", s, e); - } - } - mdb_printf("\n"); - mdb_free(data, bmapsize); - return (DCMD_OK); -} - -static int -rdc_bmapnref(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - mdb_printf("\nRDC bitmap info\n"); - rdc_bmapdump(addr, flags, argc, argv); - mdb_printf("RDC bitmap reference count info\n"); - rdc_brefdump(addr, flags, argc, argv); - return (DCMD_OK); -} - -#endif -/* - * MDB module linkage information: - */ - -static const mdb_dcmd_t dcmds[] = { - { "rdc", NULL, "display sndr module info", rdc }, - { "rdc_buf", "?[-v]", "rdc_buf structure", rdc_buf }, - { "rdc_kinfo", "?[-av]", "rdc_k_info structure", rdc_kinfo }, - { "rdc_uinfo", "?[-av]", "rdc_u_info structure", rdc_uinfo }, - { "rdc_group", "?", "rdc group structure", rdc_group }, - { "rdc_srv", "?", "rdc_srv structure", rdc_srv }, - { "rdc_if", "?", "rdc_if structure", rdc_if }, - { "rdc_infodev", "?", "rdc_info_dev structure", rdc_infodev }, - { "rdc_k2u", "?", "rdc_kinfo to rdc_uinfo", rdc_k2u }, - { "rdc_u2k", "?", "rdc_uinfo to rdc_kinfo", rdc_u2k }, - { "rdc_aio", "?", "rdc_aio structure", rdc_aio}, - { "rdc_iohdr", "?", "rdc_iohdr structure", rdc_iohdr}, -#ifdef DEBUG - { "rdc_setseq", "?", "Write seq field in group", rdc_setseq }, - { "rdc_setseqack", "?", "Write seqack field in group", rdc_setseqack }, - { "rdc_dset", "?", "Dump dset info", rdc_dset }, - { "rdc_bmapdump", "?", "Dump bitmap", rdc_bmapdump }, - { "rdc_brefdump", "?", "Dump bitmap reference count", rdc_brefdump }, - { "rdc_bmapnref", "?", "Dump bitmap and ref count", rdc_bmapnref }, - { "rdc_fba2log", "?", "fba to log num", fba_to_log_num }, - { "rdc_log2fba", "?", "log to fba num", log_to_fba_num }, - { "rdc_bitisset", "?", "check bit set", bmap_bit_isset }, - { "rdc_brefisset", "?", "check bit ref set", bmap_bitref_isset }, - { "rdc_indbyte", "?", "print indbyte", ind_byte }, - { "rdc_indbit", "?", "print indbit", ind_bit }, - { "rdc_bitmask", "?", "print bitmask for pos->len", rdc_bitmask }, -#endif - { NULL } -}; - - -static const mdb_walker_t walkers[] = { - { "rdc_kinfo", "walk the rdc_k_info array", - rdc_k_info_winit, rdc_k_info_wstep, rdc_k_info_wfini }, - { "rdc_uinfo", "walk the rdc_u_info array", - rdc_u_info_winit, rdc_u_info_wstep, rdc_u_info_wfini }, - { "rdc_if", "walk rdc_if chain", - rdc_if_winit, rdc_if_wstep, rdc_if_wfini }, - { NULL } -}; - - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com b/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com deleted file mode 100644 index 40975cea69..0000000000 --- a/usr/src/cmd/mdb/common/modules/sdbc/Makefile.com +++ /dev/null @@ -1,24 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CPPFLAGS += -DNSC_MULTI_TERABYTE diff --git a/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c b/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c deleted file mode 100644 index 14c99abecf..0000000000 --- a/usr/src/cmd/mdb/common/modules/sdbc/sdbc.c +++ /dev/null @@ -1,3158 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/mdb_modapi.h> -#include <sys/nsc_thread.h> - -/* needed to maintain identical _sd_bitmap_t sizes */ -#define _SD_8K_BLKSIZE -#include <sys/nsctl/sd_bcache.h> - -#include <ns/sdbc/sd_io.h> -#include <ns/sdbc/sd_ft.h> -#include <ns/sdbc/safestore.h> - -/* - * initialize cd filter options to this - * to differentiate with kernel values in range [-1, sdbc_max_devs] - */ -#define MDB_CD ((uintptr_t)~1) -#define OPT_C_SELECTED (opt_c != MDB_CD) - -/* initialize block filters to this */ -#define MDB_BLKNUM ((uintptr_t)~1) -#define OPT_B_SELECTED (opt_b != MDB_BLKNUM) - -enum vartype { UINTTYPE = 0, ADDRTYPE, LOCKTYPE, CVTYPE }; - -static void display_var(char *, enum vartype); -#ifdef SAFESTORE -static void print_wrq(_sd_writeq_t *, uint_t); -#endif - -struct walk_info { - uintptr_t w_start; - uintptr_t w_end; -}; - - -mdb_bitmask_t host_states[] = { - { "HOST_NONE", 0xff, _SD_HOST_NONE }, - { "HOST_CONFIGURED", 0xff, _SD_HOST_CONFIGURED }, - { "HOST_DECONFIGURED", 0xff, _SD_HOST_DECONFIGURED }, - { "HOST_NOCACHE", 0xff, _SD_HOST_NOCACHE }, - { NULL, 0, 0 } - -}; - -mdb_bitmask_t cache_hints[] = { - { "WRTHRU", NSC_WRTHRU, NSC_WRTHRU }, - { "FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU }, - { "NOCACHE", NSC_NOCACHE, NSC_NOCACHE }, - { "QUEUE", NSC_QUEUE, NSC_QUEUE }, - { "RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD }, - { "NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU }, - { "METADATA", NSC_METADATA, NSC_METADATA }, - { "SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO }, - { NULL, 0, 0 } - -}; - - -/* - * some cache general dcmds that do not use walkers - */ -/*ARGSUSED*/ -static int -sdbc_config(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _sd_cache_param_t _sd_cache_config; - _sd_net_t _sd_net_config; - _sd_ft_info_t _sd_ft_data; - uint_t _sd_node_hint; - char sdbc_version[17]; - - if (mdb_readvar(sdbc_version, "sdbc_version") == -1) { - mdb_warn("failed to read sdbc_version symbol"); - } else { - sdbc_version[16] = '\0'; /* make sure string is terminated */ - mdb_printf("sdbc_version %s\n", sdbc_version); - } - - if (mdb_readvar(&_sd_cache_config, "_sd_cache_config") == -1) { - mdb_warn("failed to read _sd_cache_config symbol"); - } else { - - mdb_printf("SDBC Configuration:\n"); - mdb_inc_indent(4); - mdb_printf("user magic: %X kernel magic: %X (should match)\n", - _SD_MAGIC, _sd_cache_config.magic); - mdb_printf( - "mirror host: %2d Block size: %4d threads %4d " - "write cache: %4dM\n", - _sd_cache_config.mirror_host, - _sd_cache_config.blk_size, - _sd_cache_config.threads, - _sd_cache_config.write_cache); - mdb_printf("num_handles %4-d cache_mem %4dM prot_lru %d\n", - _sd_cache_config.num_handles, - _sd_cache_config.cache_mem[0], - _sd_cache_config.prot_lru); - mdb_printf("gen_pattern %d fill_pattern %?-p num_nodes %d\n", - _sd_cache_config.gen_pattern, - _sd_cache_config.fill_pattern, - _sd_cache_config.num_nodes); - mdb_dec_indent(4); - } - - if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) { - mdb_warn("failed to read _sd_net_config symbol"); - } else { - mdb_inc_indent(4); - mdb_printf( - "psize %4-d configured %d csize %10-d wsize %10-d cpages %6d\n", - _sd_net_config.sn_psize, - _sd_net_config.sn_configured, - _sd_net_config.sn_csize, - _sd_net_config.sn_wsize, - _sd_net_config.sn_cpages); - - mdb_dec_indent(4); -#ifdef SAFESTORE - print_wrq(&(_sd_net_config.sn_wr_queue), FALSE); -#endif - } - - - if (mdb_readvar(&_sd_ft_data, "_sd_ft_data") == -1) { - mdb_warn("failed to read _sd_ft_data symbol"); - - } else { - mdb_printf("FT data:\n"); - mdb_inc_indent(4); - mdb_printf("crashed %d host_state <%b> numio %d\n", - _sd_ft_data.fi_crashed, - _sd_ft_data.fi_host_state, host_states, - _sd_ft_data.fi_numio); - mdb_printf("lock %?-p (owner) rem_sv %h-x sleep %?-p (owner)\n", - _sd_ft_data.fi_lock._opaque[0], - _sd_ft_data.fi_rem_sv._opaque, - _sd_ft_data.fi_sleep._opaque[0]); - mdb_dec_indent(4); - } - - if (mdb_readvar(&_sd_node_hint, "_sd_node_hint") == -1) { - mdb_warn("failed to read _sd_node_hint symbol"); - - } else - mdb_printf("Node Hints: %08x <%b>\n", - _sd_node_hint, cache_hints); - - display_var("sdbc_wrthru_len", UINTTYPE); - display_var("_sd_debug_level", UINTTYPE); - display_var("_sdbc_attached", UINTTYPE); - - return (DCMD_OK); -} - -static void -sdbc_hit_percent(uint_t hits, uint_t misses, char *type) -{ - uint64_t dhits, dmisses; - uint64_t hit_rate = 0; - - mdb_printf("%s hits: %u\t %s misses: %u\n", type, hits, type, misses); - - /* a little crude. anything less than 1 percent will show as 0 */ - if (hits > 0 || misses > 0) { - dhits = (uint64_t)hits; - dmisses = (uint64_t)misses; - hit_rate = (dhits * 100)/ (dhits + dmisses); - mdb_printf("%s hit rate: %lld %%\n", type, hit_rate); - } - mdb_printf("\n"); -} - -/*ARGSUSED*/ -static int -sdbc_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int i; - char *fn; - _sd_stats_t *_sd_cache_stats; /* local memory */ - uintptr_t _sd_cache_statsp; /* kernel pointer */ - _sd_shared_t *sh; - int statssize; - GElf_Sym sym; - int maxdevs; - - if (argc != 0) - return (DCMD_USAGE); - - /* get the number of volumes */ - if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) { - mdb_warn("failed to read sdbc_max_devs"); - return (DCMD_ERR); - } - - statssize = sizeof (_sd_stats_t) + (maxdevs - 1) * - sizeof (_sd_shared_t); - - _sd_cache_stats = mdb_zalloc(statssize, UM_SLEEP); - - if (mdb_lookup_by_obj("sdbc", "_sd_cache_stats", &sym) == -1) { - mdb_warn("failed to lookup _sd_cache_stats symbol"); - return (DCMD_ERR); - } - - if (mdb_vread(&_sd_cache_statsp, sizeof (uintptr_t), - sym.st_value) == -1) { - mdb_warn("failed to read _sd_stats_t pointer"); - return (DCMD_ERR); - } - - if (mdb_vread(_sd_cache_stats, statssize, _sd_cache_statsp) == -1) { - mdb_warn("failed to read _sd_stats_t structure"); - return (DCMD_ERR); - } - - mdb_printf("Storage Device Block Cache Statistics\n"); - mdb_printf("-------------------------------------\n"); - - i = _sd_cache_stats->st_blksize; - mdb_printf("Blocksize: 0x%x (%d)\n", i, i); - - mdb_printf("\n"); - sdbc_hit_percent(_sd_cache_stats->st_rdhits, _sd_cache_stats->st_rdmiss, - "Read"); - sdbc_hit_percent(_sd_cache_stats->st_wrhits, _sd_cache_stats->st_wrmiss, - "Write"); - - mdb_printf("%3s %10s %8s %8s %8s %8s %8s %7s %4s %4s %s\n", - "Cd", "Dev", "Size", - "CacheRd", "CacheWr", "DiskRd", "DiskWr", - "DirtyBl", "#IO", "Fail", "F"); - for (i = 0; i < maxdevs; i++) { - sh = &_sd_cache_stats->st_shared[i]; - if (!sh->sh_alloc) - continue; - fn = strrchr(sh->sh_filename, '/'); - fn = fn ? fn+1 : sh->sh_filename; - mdb_printf("%3d %10s %7d %8d %8d %8d %8d %7d %4d %4d %d\n", - sh->sh_cd, fn, sh->sh_filesize, - sh->sh_cache_read, sh->sh_cache_write, - sh->sh_disk_read, sh->sh_disk_write, - sh->sh_numdirty, sh->sh_numio, sh->sh_numfail, - sh->sh_failed); - } - - mdb_free(_sd_cache_stats, statssize); - return (DCMD_OK); -} - -/* - * display some variables and counters - */ -static void -display_var(char *name, enum vartype type) -{ - uint_t uintval; - uintptr_t addrval; - kmutex_t lockval; - kcondvar_t cvval; - - switch (type) { - case UINTTYPE: - if (mdb_readvar(&uintval, name) == -1) { - mdb_warn("failed to read %s variable", name); - } else - mdb_printf("%s =\t%8x %12u\n", - name, uintval, uintval); - break; - case ADDRTYPE: - if (mdb_readvar(&addrval, name) == -1) { - mdb_warn("failed to read %s variable", name); - } else - mdb_printf("%s =\t%?-p\n", - name, addrval); - break; - case LOCKTYPE: - if (mdb_readvar(&lockval, name) == -1) { - mdb_warn("failed to read %s lock variable", - name); - } else - mdb_printf("%s =\t%-p (owner)\n", - name, lockval._opaque[0]); - break; - case CVTYPE: - if (mdb_readvar(&cvval, name) == -1) { - mdb_warn("failed to read %s condvar variable", - name); - } else - mdb_printf("%s = \t%h-x\n", - name, cvval._opaque); - break; - default: - mdb_warn("display_var: unknown type"); - } -} - -mdb_bitmask_t dealloc_flag_vals[] = { - { "PROCESS_CACHE_DM", (u_longlong_t)~0, PROCESS_CACHE_DM }, - { "CACHE_SHUTDOWN_DM", (u_longlong_t)~0, CACHE_SHUTDOWN_DM }, - { "CACHE_THREAD_TERMINATED_DM", - (u_longlong_t)~0, CACHE_THREAD_TERMINATED_DM }, - { "TIME_DELAY_LVL0", (u_longlong_t)~0, TIME_DELAY_LVL0 }, - { "TIME_DELAY_LVL1", (u_longlong_t)~0, TIME_DELAY_LVL1 }, - { "TIME_DELAY_LVL2", (u_longlong_t)~0, TIME_DELAY_LVL2 }, - { NULL, 0, 0 } -}; - -mdb_bitmask_t mdp_bits[] = { - { "MONITOR_DYNMEM_PROCESS_DEFAULT", - (u_longlong_t)~0, MONITOR_DYNMEM_PROCESS_DEFAULT}, - { "RPT_SHUTDOWN_PROCESS_DM", - RPT_SHUTDOWN_PROCESS_DM, RPT_SHUTDOWN_PROCESS_DM }, - { "RPT_DEALLOC_STATS1_DM", - RPT_DEALLOC_STATS1_DM, RPT_DEALLOC_STATS1_DM }, - { "RPT_DEALLOC_STATS2_DM", - RPT_DEALLOC_STATS2_DM, RPT_DEALLOC_STATS2_DM }, - { NULL, 0, 0 } -}; - -mdb_bitmask_t process_directive_bits[] = { - { "PROCESS_DIRECTIVE_DEFAULT", - (u_longlong_t)~0, PROCESS_DIRECTIVE_DEFAULT }, - { "WAKE_DEALLOC_THREAD_DM", - WAKE_DEALLOC_THREAD_DM, WAKE_DEALLOC_THREAD_DM }, - { "MAX_OUT_ACCEL_HIST_FLAG_DM", - MAX_OUT_ACCEL_HIST_FLAG_DM, MAX_OUT_ACCEL_HIST_FLAG_DM}, - { NULL, 0, 0 } -}; - -/*ARGSUSED*/ -static int -sdbc_vars(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - int sd_dealloc_flag_dm; - _dm_process_vars_t dynmem_processing_dm; - - if (argc != 0) - return (DCMD_USAGE); - - mdb_printf("counters and other variables:\n"); - mdb_inc_indent(4); - - display_var("xmem_inval_hit", UINTTYPE); - display_var("xmem_inval_miss", UINTTYPE); - display_var("xmem_inval_inuse", UINTTYPE); - - display_var("sdbc_allocb_pageio1", UINTTYPE); - display_var("sdbc_allocb_pageio2", UINTTYPE); - display_var("sdbc_allocb_inuse", UINTTYPE); - display_var("sdbc_allocb_hit", UINTTYPE); - display_var("sdbc_allocb_lost", UINTTYPE); - display_var("sdbc_pageio_always", UINTTYPE); - display_var("sdbc_do_page", UINTTYPE); - display_var("sdbc_flush_pageio", UINTTYPE); - - display_var("sdbc_centry_hit", UINTTYPE); - display_var("sdbc_centry_inuse", UINTTYPE); - display_var("sdbc_centry_lost", UINTTYPE); - display_var("sdbc_centry_deallocd", UINTTYPE); - - display_var("_sd_prefetch_opt", UINTTYPE); - - display_var("sdbc_ra_hash", UINTTYPE); - display_var("sdbc_ra_none", UINTTYPE); - - display_var("sdbc_static_cache", UINTTYPE); - display_var("sdbc_use_dmchain", UINTTYPE); - - /* in no particular order ... */ - display_var("sdbc_check_cot", UINTTYPE); - display_var("_sd_cctl_groupsz", UINTTYPE); - display_var("CBLOCKS", UINTTYPE); - display_var("_SD_SELF_HOST", UINTTYPE); - display_var("_SD_MIRROR_HOST", UINTTYPE); - display_var("sdbc_bio_count", UINTTYPE); - display_var("_sd_cblock_shift", UINTTYPE); - display_var("_sd_nodes_configured", UINTTYPE); - display_var("nv_alloc_factor", UINTTYPE); - display_var("_sd_ft_exit", UINTTYPE); - display_var("_sd_flush_exit", UINTTYPE); - display_var("_sd_node_recovery", UINTTYPE); - display_var("_sd_async_recovery", UINTTYPE); - display_var("_sdbc_ft_hold_io", UINTTYPE); - display_var("mirror_clean_shutdown", UINTTYPE); - display_var("_sd_ft_warm_start", UINTTYPE); - mdb_dec_indent(4); - mdb_printf("\n"); - - /* some addresses of various lists and tables */ - mdb_printf("Addresses:\n"); - mdb_inc_indent(4); - display_var("_sd_htable", ADDRTYPE); - display_var("_sdbc_gl_centry_info", ADDRTYPE); - display_var("_sdbc_gl_centry_info_nvmem", ADDRTYPE); - display_var("_sdbc_gl_centry_info_size", ADDRTYPE); /* size_t */ - display_var("_sdbc_gl_file_info", ADDRTYPE); - display_var("_sdbc_gl_file_info_size", ADDRTYPE); /* size_t */ - mdb_dec_indent(4); - mdb_printf("\n"); - - /* dynamic memory variables */ - mdb_printf("Dynamic Memory variables and stats:\n"); - mdb_inc_indent(4); - display_var("_sdbc_memtype_deconfigure_delayed", UINTTYPE); - - if (mdb_readvar(&sd_dealloc_flag_dm, "sd_dealloc_flag_dm") == -1) { - mdb_warn("failed to read sd_dealloc_flag_dm symbol"); - } else - mdb_printf("sd_dealloc_flag_dm %08x <%b>\n", - sd_dealloc_flag_dm, - sd_dealloc_flag_dm, dealloc_flag_vals); - - if (mdb_readvar(&dynmem_processing_dm, "dynmem_processing_dm") == -1) { - mdb_warn("failed to read dynmem_processing_dm structure"); - } else { - _dm_process_vars_t *dp; - - dp = &dynmem_processing_dm; - - mdb_printf( - "thread_dm_cv %h-x thread_dm_lock %?-p (owner)\n", - dp->thread_dm_cv._opaque, - dp->thread_dm_lock._opaque[0]); - - mdb_printf("sd_dealloc_flagx %x %8Tmax_dyn_list %3-d\n", - dp->sd_dealloc_flagx, - dp->max_dyn_list); - - mdb_printf("monitor_dynmem_process <%b>\n", - dp->monitor_dynmem_process, mdp_bits); - - mdb_printf( - "cache_aging_ct1 %3-d %8Tcache_aging_ct2 %3-d cache_aging_ct3 %3-d\n", - dp->cache_aging_ct1, - dp->cache_aging_ct2, - dp->cache_aging_ct3); - - mdb_printf( - "cache_aging_sec1 %3-d %8Tcache_aging_sec2 %3-d" - " cache_aging_sec3 %3-d\n", - dp->cache_aging_sec1, - dp->cache_aging_sec2, - dp->cache_aging_sec3); - - mdb_printf("cache_aging_pcnt1 %3-d %8Tcache_aging_pcnt2 %3-d\n", - dp->cache_aging_pcnt1, - dp->cache_aging_pcnt2); - - mdb_printf( - "max_holds_pcnt %3-d %8Talloc_ct %8-d dealloc_ct %8-d\n", - dp->max_holds_pcnt, - dp->alloc_ct, - dp->dealloc_ct); - - mdb_printf( - "history %4x %8Tnodatas %8-d notavail %8-d candidates %8-d\n", - dp->history, - dp->nodatas, - dp->notavail, - dp->candidates); - - mdb_printf( - "deallocs %8-d %8Thosts %8-d pests %8-d metas %8-d\n", - dp->deallocs, - dp->hosts, - dp->pests, - dp->metas); - - mdb_printf("holds %8-d %8Tothers %8-d\n", - dp->holds, - dp->others); - - mdb_printf("process_directive <%b>\n", - dp->process_directive, process_directive_bits); - - mdb_printf("read_hits %8-d %8Tread_misses %8-d\n", - dp->read_hits, - dp->read_misses); - - mdb_printf( - "write_thru %8-d %8Twrite_hits %8-d write_misses %8-d\n", - dp->write_hits, - dp->write_misses, - dp->write_thru); - - mdb_printf("prefetch_hits %8-d prefetch_misses %8-d\n", - dp->prefetch_hits, - dp->prefetch_misses); - } - mdb_dec_indent(4); - mdb_printf("\n"); - - /* some locks and condition variables */ - mdb_printf("Locks:\n"); - mdb_inc_indent(4); - display_var("mutex_and_condvar_flag", UINTTYPE); - display_var("_sd_cache_lock", LOCKTYPE); - display_var("_sd_block_lk", LOCKTYPE); - display_var("_sdbc_config_lock", LOCKTYPE); - display_var("_sdbc_ft_hold_io_lk", LOCKTYPE); - display_var("_sd_flush_cv", CVTYPE); - display_var("_sdbc_ft_hold_io_cv", CVTYPE); - mdb_dec_indent(4); - mdb_printf("\n"); - - return (DCMD_OK); -} - -const mdb_bitmask_t nsc_buf_bits[] = { - {"HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED}, - {"HACTIVE", NSC_HACTIVE, NSC_HACTIVE}, - {"RDBUF", NSC_RDBUF, NSC_RDBUF}, - {"WRBUF", NSC_WRBUF, NSC_WRBUF}, - {"NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK}, - {"WRTHRU", NSC_WRTHRU, NSC_WRTHRU}, - {"NOCACHE", NSC_NOCACHE, NSC_NOCACHE}, - {"BCOPY", NSC_BCOPY, NSC_BCOPY}, - {"PAGEIO", NSC_PAGEIO, NSC_PAGEIO}, - {"PINNABLE", NSC_PINNABLE, NSC_PINNABLE}, - {"FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU}, - {"METADATA", NSC_METADATA, NSC_METADATA}, - {"MIXED", NSC_MIXED, NSC_MIXED}, - {NULL, 0, 0} -}; - - -/* - * HELP functions for cache ctl type dcmds - */ - -static void -cctl_help_common(char *name) -{ - mdb_inc_indent(4); - mdb_printf("-c cd displays cctls for cache descriptor 'cd'\n"); - mdb_dec_indent(4); - mdb_printf("inclusive filters:\n"); - mdb_inc_indent(4); - mdb_printf("-b blk displays cctls for cache block number 'blk'\n"); - mdb_printf("-d displays cctls with dirty bits\n"); - mdb_printf("-h displays cctls that are hashed\n"); - mdb_printf("-i displays cctls that are inuse\n"); - mdb_printf("-o displays cctls that have I/O in progress\n"); - mdb_printf("-p displays cctls that have pagio set\n"); - mdb_printf("-B displays cctls that are marked BAD\n"); - mdb_printf("-H displays cctls that are HOSTS\n"); - mdb_printf("-P displays cctls that are PARASITES\n"); - mdb_printf("-R displays cctls that are explicit (NSC_RDAHEAD) " - "Prefetch bufs\n"); - mdb_printf("-r displays cctls that are implicit Prefetch bufs\n"); - mdb_printf("-V displays cctls that have valid bits set\n"); - mdb_printf("-v verbose\n"); - mdb_dec_indent(4); - - mdb_printf("Default: %s displays all cctls in the list\n", name); - mdb_printf("\n"); - - mdb_printf("Example:\n"); - mdb_inc_indent(4); - - mdb_printf("%s -io -c 5 displays all cctls for cd 5 that are\n" - "in use or have I/O in progress\n", name); - mdb_dec_indent(4); -} - -#define CCTL_OPTIONSTRING "[-vdhiopBHPV][-c cd][-b blknum]" -void -cctl_help() -{ - mdb_printf("sdbc_cctl displays cache ctl structures\n"); - mdb_printf("Usage: [address]::sdbc_cctl " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_cctl"); -} - -void -cchain_help() -{ - mdb_printf("sdbc_cchain displays cache ctl structures in a" - " (alloc) cc_chain\n"); - mdb_printf("Usage: address::sdbc_cchain " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_cchain"); -} - -void -dchain_help() -{ - mdb_printf("sdbc_dchain displays cache ctl structures in a" - " dirty chain\n"); - mdb_printf("Usage: address::sdbc_dchain " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_dchain"); -} - -void -dmchain_help() -{ - mdb_printf("sdbc_dmchain displays cache ctl structures in a" - " dynamic memory allocation chain\n"); - mdb_printf("order of display is:\n" - "the cctl represented by the given address,\n" - "the cc_head_dm cctl,\n" - "the chain starting at cc_next_dm of the head cctl\n"); - mdb_printf("Usage: address::sdbc_dmchain " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_dmchain"); -} - -void -hashchain_help() -{ - mdb_printf("sdbc_hashchain displays cache ctl structures in a" - " hash chain\n"); - mdb_printf("Usage: address::sdbc_hashchain " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_hashchain"); -} - -void -hashtable_help() -{ - mdb_printf("sdbc_hashtable displays the hash table and its chains\n"); - mdb_printf("Usage: address::sdbc_hashtable " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_hashtable"); -} - - -void -lru_help() -{ - mdb_printf("sdbc_lru displays cache ctl structures in the LRU queue\n"); - mdb_printf("Usage: [address]::sdbc_lru " CCTL_OPTIONSTRING "\n"); - cctl_help_common("sdbc_lru"); -} - -/* - * help functions for write ctl dcmds - */ -void -wctl_help_common(char *name) -{ - mdb_inc_indent(4); - mdb_printf("-v verbose\n"); - mdb_printf("-c cd show ctl structs for cache descriptor 'cd'\n"); - mdb_printf("-d show ctl structs that have dirty bits set\n"); - mdb_dec_indent(4); - mdb_printf("Default: %s displays all write ctl in the list\n", name); -} - -void -wctl_help() -{ - mdb_printf( - "sdbc_wctl displays the allocated array of write ctl structures\n"); - mdb_printf("Usage: [address]::sdbc_wctl [-vd][-c cd]\n"); - wctl_help_common("sdbc_wctl"); -} - -void -wrq_help() -{ - mdb_printf("sdbc_wrq displays the write ctl queue (wctl free list)\n"); - mdb_printf("Usage: [address]::sdbc_wrq [-vd][-c cd]\n"); - wctl_help_common("sdbc_wrq"); -} - -/* help function for the sdbc_cdinfo dcmd */ -void -cdinfo_help() -{ - mdb_printf( - "sdbc_cdinfo displays cd information from the _sd_cache_files table\n"); - mdb_printf("Usage: [address]::sdbc_cdfinfo [-av][-c cd]\n"); - mdb_inc_indent(4); - mdb_printf("-a displays info for all cd_info structures\n"); - mdb_printf("-c cd displays info for cache descriptor 'cd'\n"); - mdb_printf("-v verbose\n"); - mdb_dec_indent(4); - mdb_printf("Default: display info for cd's that are allocated\n"); -} - -void -ftctl_help() -{ - mdb_printf( - "sdbc_ftctl displays the array of fault tolerant structures \n"); - mdb_printf("Usage: [address]::sdbc_ftctl [-vd][-c cd]\n"); - wctl_help_common("sdbc_ftctl"); -} - -/* - * help function for the sdbc_handles dcmd - */ -void -handle_help() -{ - mdb_printf("sdbc_handles displays active or allocated" - " cache buffer handles\n"); - mdb_printf("Usage: [address]::sdbc_handles [-avC][-c cd]\n"); - mdb_inc_indent(4); - mdb_printf("-a displays all handles\n"); - mdb_printf("-c n displays handle for cd n\n"); - mdb_printf("-v displays detailed handle data\n"); - mdb_printf("-C displays the handle cc_chain\n"); - mdb_dec_indent(4); - mdb_printf("Default: display only allocated or active handles\n"); -} - -/* - * help functions for the "global" memory dcmds - */ -void -glcinfo_help() -{ - mdb_printf("sdbc_glcinfo displays the global cache entry info\n"); - mdb_printf("Usage: [address]::sdbc_glcinfo [-adC][-c cd][-b fbapos]\n"); - mdb_inc_indent(4); - mdb_printf("-a displays all global info structs\n"); - mdb_printf("-b fbapos displays structs that match FBA block" - "(not cache block) 'fbapos'\n"); - mdb_printf("-c cd displays structs that match cache descriptor 'cd'\n"); - mdb_printf("-d displays structs with dirty bits set\n"); - mdb_printf("-C does consistency check against nvram copy\n"); - mdb_dec_indent(4); - mdb_printf("Default: display entries with a valid cd\n"); -} - -void -glfinfo_help() -{ - mdb_printf("sdbc_glfinfo displays the global file info\n"); - mdb_printf("Usage: [address]::sdbc_glfinfo [-aptC]\n"); - mdb_inc_indent(4); - mdb_printf("-a displays all global info structs\n"); - mdb_printf("-p displays structs for pinned volumes\n"); - mdb_printf("-t displays structs for attached volumes\n"); - mdb_printf("-C does consistency check against nvram copy\n"); - mdb_dec_indent(4); - mdb_printf("Default: display entries with non-null filename\n"); -} - - -/* - * WALKERS - */ - -/* - * walker for the cctl list using the cc_link_list_dm pointers - */ -static int -sdbc_cctl_winit(mdb_walk_state_t *wsp) -{ - _sd_cctl_t *_sd_cctl[_SD_CCTL_GROUPS]; /* for getting first entry */ - struct walk_info *winfo; - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - if (wsp->walk_addr == NULL) { - /* - * we get the "first" cctl from memory and then traverse - * the cc_link_list_dm pointers. - * this traversal could start from any cctl. here we start with - * the first cctl in the _sd_cctl[] array. - */ - if (mdb_readvar(_sd_cctl, "_sd_cctl") == -1) { - mdb_warn("failed to read _sd_cctl array"); - return (DCMD_ERR); - } - - wsp->walk_addr = (uintptr_t)_sd_cctl[0]; - } - - winfo->w_start = 0; - winfo->w_end = wsp->walk_addr; - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_cctl_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - _sd_cctl_t centry; - int status; - - if (wsp->walk_addr == NULL) /* should not happen */ - return (WALK_DONE); - - /* - * w_start is 0 on the first iteration so the test - * will fail, allowing the first centry to be processed - */ - if (wsp->walk_addr == winfo->w_start) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(¢ry, sizeof (_sd_cctl_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read centry at %p", wsp->walk_addr); - return (WALK_ERR); - } - wsp->walk_addr = (uintptr_t)(centry.cc_link_list_dm); - /* set termination condition. only needs to be done once */ - winfo->w_start = winfo->w_end; - - return (status); -} - -static void -sdbc_cctl_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -/* - * walk the cc_chain list of a _sd_cctl_t - * no global walks -- must be called with an address - */ -static int -sdbc_cchain_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) - return (WALK_ERR); - - wsp->walk_data = mdb_zalloc(sizeof (_sd_cctl_t), UM_SLEEP); - - return (WALK_NEXT); -} - -static int -sdbc_cchain_wstep(mdb_walk_state_t *wsp) -{ - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t), wsp->walk_addr) - == -1) { - mdb_warn("sdbc_cchain_wstep failed to read centry at %p", - wsp->walk_addr); - return (WALK_ERR); - } - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)(((_sd_cctl_t *) - (wsp->walk_data))->cc_chain); - return (status); -} - -static void -sdbc_cchain_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (_sd_cctl_t)); -} - - -/* - * walk the dirty chain list of a _sd_cctl_t - * no global walks -- must be called with an address - */ -static int -sdbc_dchain_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) - return (WALK_ERR); - - wsp->walk_data = mdb_zalloc(sizeof (_sd_cctl_t), UM_SLEEP); - - /* walk data stores the first and subsequent cc_dirty_link */ - if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t), wsp->walk_addr) - == -1) { - mdb_warn("sdbc_dchain_winit failed to read centry at %p", - wsp->walk_addr); - return (WALK_ERR); - } - - return (WALK_NEXT); -} - -static int -sdbc_dchain_wstep(mdb_walk_state_t *wsp) -{ - _sd_cctl_t centry; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - - if (mdb_vread(¢ry, sizeof (_sd_cctl_t), wsp->walk_addr) - == -1) { - mdb_warn("sdbc_dchain_wstep failed to read centry at %p", - wsp->walk_addr); - return (WALK_ERR); - } - - wsp->walk_addr = - (uintptr_t)(centry.cc_dirty_next); - - /* end of dirty_next chain? start on subsequent dirty_link */ - if (wsp->walk_addr == NULL) { - wsp->walk_addr = - (uintptr_t)(((_sd_cctl_t *)(wsp->walk_data))->cc_dirty_link); - - /* update dirty link */ - /* walk data stores the first and subsequent cc_dirty_link */ - if (wsp->walk_addr) { - if (mdb_vread(wsp->walk_data, sizeof (_sd_cctl_t), - wsp->walk_addr) == -1) { - - mdb_warn( - "sdbc_dchain_wstep failed to read centry at %p", - wsp->walk_addr); - - return (WALK_ERR); - } - } - } - - return (status); -} - -static void -sdbc_dchain_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (_sd_cctl_t)); -} - -/* for stepping thru the dynmem chain */ -#define GET_HEAD_DM 0x1 -#define GET_NEXT_DM 0x2 - -/* - * walk the dm chain of a cctl - * start with current address, then cc_head_dm, then the cc_next_dm chain - */ -static int -sdbc_dmchain_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) - return (WALK_ERR); - - wsp->walk_data = (void *)GET_HEAD_DM; - - return (WALK_NEXT); -} - -static int -sdbc_dmchain_wstep(mdb_walk_state_t *wsp) -{ - _sd_cctl_t centry; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(¢ry, sizeof (_sd_cctl_t), wsp->walk_addr) - == -1) { - mdb_warn("sdbc_dmchain_wstep failed to read centry at %p", - wsp->walk_addr); - return (WALK_ERR); - } - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (wsp->walk_data == (void *)GET_HEAD_DM) { - wsp->walk_addr = (uintptr_t)centry.cc_head_dm; - wsp->walk_data = (void *)GET_NEXT_DM; - } else - wsp->walk_addr = (uintptr_t)centry.cc_next_dm; - - return (status); -} - -/*ARGSUSED*/ -static void -sdbc_dmchain_wfini(mdb_walk_state_t *wsp) -{ -} - -/* - * walk a hash chain - * requires an address - */ -/*ARGSUSED*/ -static int -sdbc_hashchain_winit(mdb_walk_state_t *wsp) -{ - - if (wsp->walk_addr == NULL) - return (WALK_ERR); - - - return (WALK_NEXT); -} - -static int -sdbc_hashchain_wstep(mdb_walk_state_t *wsp) -{ - int status; - _sd_hash_hd_t hash_entry; - - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(&hash_entry, sizeof (_sd_hash_hd_t), - wsp->walk_addr) == -1) { - mdb_warn( - "sdbc_hashchain_wstep failed to read hash_entry at %p", - wsp->walk_addr); - return (WALK_ERR); /* will upper layer continue ? */ - } - - wsp->walk_addr = (uintptr_t)hash_entry.hh_next; - - return (status); -} - -/*ARGSUSED*/ -static void -sdbc_hashchain_wfini(mdb_walk_state_t *wsp) -{ -} - -/* - * walk the sdbc lru list - */ -static int -sdbc_lru_winit(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo; - GElf_Sym sym; - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - /* if called without an address, start at the head of the queue */ - if (wsp->walk_addr == NULL) { - - if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym) == -1) { - mdb_warn("failed to lookup _sd_lru_q symbol"); - return (WALK_ERR); - } - - /* &(_sd_lru_q.sq_qhead) */ - wsp->walk_addr = (uintptr_t)(sym.st_value); - } - - winfo->w_start = 0; - winfo->w_end = wsp->walk_addr; - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_lru_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - _sd_cctl_t centry; - int status; - - if (wsp->walk_addr == NULL) /* should not happen */ - return (WALK_DONE); - - /* - * w_start is 0 on the first iteration so the test - * will fail, allowing the first centry to be processed - */ - if (wsp->walk_addr == winfo->w_start) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(¢ry, sizeof (_sd_cctl_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read centry at %p", wsp->walk_addr); - return (WALK_ERR); - } - wsp->walk_addr = (uintptr_t)(centry.cc_next); - - /* set termination condition. only needs to be done once */ - winfo->w_start = winfo->w_end; - - return (status); -} - -static void -sdbc_lru_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - - -#ifdef SAFESTORE -/* - * walk the array of allocated write control structures - */ - -static int -sdbc_wctl_winit(mdb_walk_state_t *wsp) -{ - _sd_net_t _sd_net_config; - _sd_writeq_t wrq; - struct walk_info *winfo; - int blk_shft; - int count; - - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - /* need to calculate the end of the array */ - if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) { - mdb_warn("failed to read _sd_net_config structure"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - wsp->walk_addr = (uintptr_t)(_sd_net_config.sn_wr_cctl); - - /* - * this module assumes 8k block size so this code can - * be commented out if necessary. - */ - if (mdb_readvar(&blk_shft, "_sd_cblock_shift") == -1) { - mdb_warn("failed to read _sd_cblock_shift." - "assuming 8k cache block size"); - blk_shft = 13; - } - - count = (_sd_net_config.sn_wpages * _sd_net_config.sn_psize) / - (1 << blk_shft); - - winfo->w_end = (uintptr_t)(_sd_net_config.sn_wr_cctl + count); - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_wctl_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->w_end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (_sd_wr_cctl_t); - - return (status); - -} - -static void -sdbc_wctl_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -/* - * walk the queue (free list) of write control structures - */ - -static int -sdbc_wrq_winit(mdb_walk_state_t *wsp) -{ - _sd_net_t _sd_net_config; - _sd_writeq_t wrq; - - /* if called without an address, start at the head of the queue */ - if (wsp->walk_addr == NULL) { - - if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) { - mdb_warn("failed to read _sd_net_config structure"); - return (WALK_ERR); - } - - wsp->walk_addr = (uintptr_t) - (_sd_net_config.sn_wr_queue.wq_qtop); - } - - return (WALK_NEXT); -} - -static int -sdbc_wrq_wstep(mdb_walk_state_t *wsp) -{ - _sd_wr_cctl_t wctl; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(&wctl, sizeof (_sd_wr_cctl_t), wsp->walk_addr) - == -1) { - mdb_warn("sdbc_cchain_wstep failed to read wctl at %p", - wsp->walk_addr); - return (WALK_ERR); - } - - /* special case -- mini-DSP fake wr_cctl */ - if (wsp->walk_addr == (uintptr_t)wctl.wc_next) - return (WALK_DONE); - - wsp->walk_addr = (uintptr_t)(wctl.wc_next); - - return (WALK_NEXT); -} - -static void -sdbc_wrq_wfini(mdb_walk_state_t *wsp) -{ -} -#endif /* SAFESTORE */ -/* - * walk the _sd_cache_files array of cd_info structures - */ -static int -sdbc_cdinfo_winit(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo; - _sd_cd_info_t *_sd_cache_files_addr; - int maxdevs; - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - - /* get the address of the cdinfo table */ - if (mdb_readvar(&_sd_cache_files_addr, "_sd_cache_files") == -1) { - mdb_warn("failed to read _sd_cache_files address\n"); - return (WALK_ERR); - } - - /* if called without an address, start at the head of the queue */ - if (wsp->walk_addr == NULL) { - /* address of first _sd_cd_info_t */ - wsp->walk_addr = (uintptr_t)(_sd_cache_files_addr); - } - - /* get the number of volumes */ - if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) { - mdb_warn("failed to read sdbc_max_devs"); - return (WALK_ERR); - } - - winfo->w_end = (uintptr_t)(_sd_cache_files_addr + maxdevs); - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_cdinfo_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr >= winfo->w_end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (_sd_cd_info_t); - - return (status); -} - -static void -sdbc_cdinfo_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -#ifdef SAFESTORE -/* - * walk the array of allocated fault tolerant control structures - */ -static int -sdbc_ftctl_winit(mdb_walk_state_t *wsp) -{ - _sd_net_t _sd_net_config; - struct walk_info *winfo; - int blk_shft = 13; /* 8k default */ - int count; - - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - /* need to calculate the end of the array */ - if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) { - mdb_warn("failed to read _sd_net_config structure"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - wsp->walk_addr = (uintptr_t)(_sd_net_config.sn_ft_cctl); - - /* - * this module assumes 8k block size so this code can - * be commented out if necessary. - */ - if (mdb_readvar(&blk_shft, "_sd_cblock_shift") == -1) { - mdb_warn("failed to read _sd_cblock_shift." - "assuming 8k cache block size"); - blk_shft = 13; - } - - count = (_sd_net_config.sn_wpages * _sd_net_config.sn_psize) / - (1 << blk_shft); - - winfo->w_end = (uintptr_t)(_sd_net_config.sn_ft_cctl + count); - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_ftctl_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->w_end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (_sd_ft_cctl_t); - - return (status); -} - -static void -sdbc_ftctl_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} -#endif /* SAFESTORE */ - -/* - * walk the handle list - */ -static int -sdbc_handle_winit(mdb_walk_state_t *wsp) -{ - _sd_buf_hlist_t hl; - struct walk_info *winfo; - GElf_Sym sym; - - if (mdb_readvar(&hl, "_sd_handle_list") == -1) { - mdb_warn("failed to read _sd_handle_list structure"); - return (WALK_ERR); - } - - if (mdb_lookup_by_obj("sdbc", "_sd_handle_list", &sym) == -1) { - mdb_warn("failed to lookup _sd_handle_list symbol"); - return (WALK_ERR); - } - - /* if called without an address, start at first element in list */ - if (wsp->walk_addr == NULL) - wsp->walk_addr = (uintptr_t)(hl.hl_top.bh_next); - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - winfo->w_end = (uintptr_t)(sym.st_value); /* &_sd_handle_list.hl_top */ - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_handle_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - _sd_buf_handle_t handle; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr == winfo->w_end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - if (mdb_vread(&handle, sizeof (_sd_buf_handle_t), wsp->walk_addr) - == -1) { - mdb_warn("failed to read handle at %p", wsp->walk_addr); - return (WALK_ERR); - } - - wsp->walk_addr = (uintptr_t)(handle.bh_next); - - return (status); -} - -static void -sdbc_handle_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -/* - * walk the global info array (dirty bits) - */ - -static int -sdbc_glcinfo_winit(mdb_walk_state_t *wsp) -{ - ss_centry_info_t *gl_centry_info; - size_t gl_centry_info_size; - struct walk_info *winfo; - - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - /* get start of the cache entry metadata */ - if (mdb_readvar(&gl_centry_info, "_sdbc_gl_centry_info") == -1) { - mdb_warn("failed to read _sdbc_gl_centry_info"); - return (WALK_ERR); - } - - /* need to calculate the end of the array */ - if (mdb_readvar(&gl_centry_info_size, - "_sdbc_gl_centry_info_size") == -1) { - mdb_warn("failed to read _sdbc_gl_centry_info_size"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - wsp->walk_addr = (uintptr_t)(gl_centry_info); - - - - winfo->w_end = ((uintptr_t)(gl_centry_info)) + gl_centry_info_size; - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_glcinfo_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->w_end) - return (WALK_DONE); - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (ss_centry_info_t); - - return (status); -} - -static void -sdbc_glcinfo_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -/* - * walk the global file info array - */ -static int -sdbc_glfinfo_winit(mdb_walk_state_t *wsp) -{ - ss_voldata_t *gl_file_info; - struct walk_info *winfo; - int maxdevs; - - - winfo = mdb_zalloc(sizeof (struct walk_info), UM_SLEEP); - - /* get start of the cache entry metadata */ - if (mdb_readvar(&gl_file_info, "_sdbc_gl_file_info") == -1) { - mdb_warn("failed to read _sdbc_gl_file_info"); - return (WALK_ERR); - } - - - if (wsp->walk_addr == NULL) - wsp->walk_addr = (uintptr_t)(gl_file_info); - - /* get the number of volumes */ - if (mdb_readvar(&maxdevs, "sdbc_max_devs") == -1) { - mdb_warn("failed to read sdbc_max_devs"); - return (WALK_ERR); - } - - /* end of the array */ - winfo->w_end = (uintptr_t)((gl_file_info) + maxdevs); - - wsp->walk_data = winfo; - - return (WALK_NEXT); -} - -static int -sdbc_glfinfo_wstep(mdb_walk_state_t *wsp) -{ - struct walk_info *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->w_end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (ss_voldata_t); - - return (status); - -} - -static void -sdbc_glfinfo_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct walk_info)); -} - -/* end of WALKERS section */ - - -const mdb_bitmask_t cc_flag_bits[] = { - {"PEND_DIRTY", CC_PEND_DIRTY, CC_PEND_DIRTY}, - {"PINNED", CC_PINNED, CC_PINNED}, - {"PINNABLE", CC_PINNABLE, CC_PINNABLE}, - {"QHEAD", CC_QHEAD, CC_QHEAD}, - {NULL, 0, 0} -}; - -const mdb_bitmask_t io_status_bits[] = { - {"IO_NONE", 0xff, _SD_IO_NONE}, - {"IO_INITIATE", 0xff, _SD_IO_INITIATE}, - {"IO_DONE", 0xff, _SD_IO_DONE}, - {"IO_FAILED", 0xff, _SD_IO_FAILED}, - {"IO_DISCARDED", 0xff, _SD_IO_DISCARDED}, - {NULL, 0, 0} -}; - -const mdb_bitmask_t cc_aging_bits[] = { - {"FOUND_IN_HASH", FOUND_IN_HASH_DM, FOUND_IN_HASH_DM}, - {"FOUND_HOLD_OVER", FOUND_HOLD_OVER_DM, FOUND_HOLD_OVER_DM}, - {"HOST_ENTRY", HOST_ENTRY_DM, HOST_ENTRY_DM}, - {"PARASITIC_ENTRY", PARASITIC_ENTRY_DM, PARASITIC_ENTRY_DM}, - {"STICKY_METADATA", STICKY_METADATA_DM, STICKY_METADATA_DM}, - {"ELIGIBLE_ENTRY", ELIGIBLE_ENTRY_DM, ELIGIBLE_ENTRY_DM}, - {"HASH_ENTRY", HASH_ENTRY_DM, HASH_ENTRY_DM}, - {"HOLD_ENTRY", HOLD_ENTRY_DM, HOLD_ENTRY_DM}, - {"AVAIL_ENTRY", AVAIL_ENTRY_DM, AVAIL_ENTRY_DM}, - {"BAD_CHAIN", BAD_CHAIN_DM, BAD_CHAIN_DM}, - {"BAD_ENTRY", BAD_ENTRY_DM, BAD_ENTRY_DM}, - {"PREFETCH_I", PREFETCH_BUF_I, PREFETCH_BUF_I}, - {"PREFETCH_E", PREFETCH_BUF_E, PREFETCH_BUF_E}, - {NULL, 0, 0} -}; - - -/* DCMDS that use walkers */ - -/* - * dcmd to display cache entry control structures - */ -static int -sdbc_cctl(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - uint_t opt_a = FALSE; - uintptr_t opt_c = MDB_CD; /* cd */ - uintptr_t opt_b = MDB_BLKNUM; /* block num */ - uint_t opt_B = FALSE; /* BAD CHAIN or ENTRY */ - uint_t opt_d = FALSE; /* dirty */ - uint_t opt_H = FALSE; /* HOST */ - uint_t opt_h = FALSE; /* hashed */ - uint_t opt_i = FALSE; /* inuse */ - uint_t opt_p = FALSE; /* pageio */ - uint_t opt_P = FALSE; /* PARASITE */ - uint_t opt_R = FALSE; /* explicit read-ahead (prefetch) */ - uint_t opt_r = FALSE; /* implicit read-ahead (prefetch) */ - uint_t opt_o = FALSE; /* io in progress */ - uint_t opt_m = FALSE; /* has memory allocated */ - uint_t opt_V = FALSE; /* valid bits */ - uint_t opt_v = FALSE; /* verbose */ - uint_t nofilter = FALSE; /* true if b, d, h, i, o, p, V are all false */ - _sd_cctl_t centry; - _sd_cctl_sync_t cc_sync; - - /* - * possible enhancements -- option to filter on flag bits - * option that toggles other options. - */ - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &opt_a, - 'B', MDB_OPT_SETBITS, TRUE, &opt_B, - 'b', MDB_OPT_UINTPTR, &opt_b, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'd', MDB_OPT_SETBITS, TRUE, &opt_d, - 'H', MDB_OPT_SETBITS, TRUE, &opt_H, - 'h', MDB_OPT_SETBITS, TRUE, &opt_h, - 'i', MDB_OPT_SETBITS, TRUE, &opt_i, - 'o', MDB_OPT_SETBITS, TRUE, &opt_o, - 'm', MDB_OPT_SETBITS, TRUE, &opt_m, - 'P', MDB_OPT_SETBITS, TRUE, &opt_P, - 'p', MDB_OPT_SETBITS, TRUE, &opt_p, - 'R', MDB_OPT_SETBITS, TRUE, &opt_R, - 'r', MDB_OPT_SETBITS, TRUE, &opt_r, - 'V', MDB_OPT_SETBITS, TRUE, &opt_V, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - - nofilter = (!OPT_B_SELECTED && !opt_d && !opt_h && !opt_i && - !opt_o && !opt_m && !opt_p && !opt_V && !opt_B && - !opt_P && !opt_H && !opt_R && !opt_r); /* no options */ - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_cctl", "sdbc`sdbc_cctl", - argc, argv) == -1) { - mdb_warn("failed to walk 'cctl' list"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("sdbc cache ctl structures:\n"); - } - - - if (mdb_vread(¢ry, sizeof (_sd_cctl_t), addr) == -1) { - mdb_warn("dcmd failed to read centry at %p", addr); - return (DCMD_ERR); - } - - /* filter exclusively on a cd number if specified */ - if (OPT_C_SELECTED && (centry.cc_head.hh_cd != opt_c)) - return (DCMD_OK); - - /* all other filters are inclusive */ - if ((nofilter) || - (OPT_B_SELECTED && (centry.cc_head.hh_blk_num == opt_b)) || - (opt_B && (centry.cc_aging_dm & - (BAD_ENTRY_DM | BAD_CHAIN_DM))) || - (opt_d && (centry.cc_dirty)) || - (opt_H && (centry.cc_aging_dm & HOST_ENTRY_DM)) || - (opt_h && (centry.cc_head.hh_hashed)) || - (opt_i && (centry.cc_inuse)) || - (opt_p && (centry.cc_pageio)) || - (opt_P && (centry.cc_aging_dm & PARASITIC_ENTRY_DM)) || - (opt_R && (centry.cc_aging_dm & PREFETCH_BUF_E)) || - (opt_r && (centry.cc_aging_dm & PREFETCH_BUF_I)) || - (opt_V && (centry.cc_valid)) || - (opt_m && (centry.cc_alloc_size_dm)) || - (opt_o && (centry.cc_iostatus != _SD_IO_NONE))) - /*EMPTY*/; - else - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf( - "%-?p cd %3-d blk_num %10-d valid %04hx dirty %04hx flag %02x\n", - addr, centry.cc_head.hh_cd, - centry.cc_head.hh_blk_num, centry.cc_valid, - centry.cc_dirty, centry.cc_flag); - mdb_dec_indent(4); - - if (!opt_v) - return (DCMD_OK); - - /* verbose */ - mdb_inc_indent(4); - mdb_printf( - "hashed %d seq %4-d toflush %04hx %8Tawait_use %4-d await_page %4-d\n", - centry.cc_head.hh_hashed, centry.cc_seq, - centry.cc_toflush, centry.cc_await_use, - centry.cc_await_page); - - mdb_printf("inuse %d pageio %d cc_flag <%b>\n", - centry.cc_inuse, centry.cc_pageio, - centry.cc_flag, cc_flag_bits); - - mdb_printf("iocount %2d iostatus <%b>\n", - centry.cc_iocount, centry.cc_iostatus, io_status_bits); - - if (mdb_vread(&cc_sync, sizeof (struct _sd_cctl_sync), - (uintptr_t)centry.cc_sync) - == -1) - mdb_warn("failed to read cc_sync"); /* not catastophic */ - - else - mdb_printf("cc_sync blkcv: %h-x %8Tlock: 0x%p (owner)\n", - cc_sync._cc_blkcv._opaque, - cc_sync._cc_lock._opaque[0]); - - mdb_printf("dynamic memory allocation:\n"); - mdb_inc_indent(4); - mdb_printf("aging_dm age %3d %4Tage flags: <%b> 0x%x\n", - centry.cc_aging_dm & 0xff, - centry.cc_aging_dm, cc_aging_bits, centry.cc_aging_dm); - - mdb_printf("alloc_size_dm %10-d head_dm %?-p\n", - centry.cc_alloc_size_dm, centry.cc_head_dm); - mdb_printf("next_dm %?-p link_list_dm %?-p\n", - centry.cc_next_dm, centry.cc_link_list_dm); - - mdb_printf("alloc_ct_dm %10-d dealloc_ct_dm %10-d\n", - centry.cc_alloc_ct_dm, centry.cc_dealloc_ct_dm); - - mdb_dec_indent(4); - /* pointers */ - mdb_printf("cctl pointers:\n"); - mdb_inc_indent(4); - - mdb_printf("next %?-p prev %?-p chain %?-p\n", - centry.cc_next, centry.cc_prev, centry.cc_chain); - mdb_printf("dirty_next %?-p dirty_link %?-p\n", - centry.cc_dirty_next, centry.cc_dirty_link); - mdb_printf("data %?-p write ctl %?-p\n", - centry.cc_data, centry.cc_write); - - mdb_dec_indent(4); - - /* dynmem chain */ - mdb_printf("cctl dmqueue index cc_blocks %4-d\n", centry.cc_cblocks); - - mdb_printf("anon_addr %?-p anon_len %8-d\n", - centry.cc_anon_addr.sa_virt, centry.cc_anon_len); - - /* stats */ - mdb_printf("cctl stats: "); - mdb_inc_indent(4); - mdb_printf("hits %8-d creat time %?-p\n", centry.cc_hits, - centry.cc_creat); - mdb_dec_indent(4); - - mdb_printf("\n"); - - mdb_dec_indent(4); - - return (DCMD_OK); -} - - -/* - * convenience dcmd to display the _sd_cctl cc_chain list (alloc list) - * Must be called with an address of a cache entry (_sd_cctl_t) - * same options as sdbc_cctl(). - * alternatively the user can call the sdbc_cchain walker - * and pipe the addresses to sdbc_cctl dcmd. - */ -static int -sdbc_cchain(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_pwalk_dcmd("sdbc`sdbc_cchain", "sdbc`sdbc_cctl", - argc, argv, addr) - == -1) { - mdb_warn("failed to walk cc_chain at addr %p", addr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - -/* - * convenience dcmd to cdisplay the _sd_cctl dirty chain - * (which is really a 2d chain). - * Must be called with an address of a cache entry (_sd_cctl_t) - * same options as sdbc_cctl(). - * alternatively the user can call the sdbc_dchain walker - * and pipe the addresses to sdbc_cctl dcmd. - */ -static int -sdbc_dchain(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_pwalk_dcmd("sdbc`sdbc_dchain", "sdbc`sdbc_cctl", - argc, argv, addr) - == -1) { - mdb_warn("failed to walk dirty chain at addr %p", addr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - -/* - * convenience dcmd to display the _sd_cctl dm chain list - * Must be called with an address of a cache entry (_sd_cctl_t) - * same options as sdbc_cctl(). - * alternatively the user can call the sdbc_dmchain walker - * and pipe the addresses to sdbc_cctl dcmd. - */ -static int -sdbc_dmchain(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_pwalk_dcmd("sdbc`sdbc_dmchain", "sdbc`sdbc_cctl", - argc, argv, addr) - == -1) { - mdb_warn("failed to walk dm chain at addr %p", addr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - -/* - * dcmd to walk a hash chain - * requires an address. same options as sdbc_cctl dcmd - */ -static int -sdbc_hashchain(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - if (mdb_pwalk_dcmd("sdbc`sdbc_hashchain", "sdbc`sdbc_cctl", - argc, argv, addr) == -1) { - mdb_warn("failed to walk hashchain at %p", addr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - -static void -display_hash_table(_sd_hash_table_t *addr, _sd_hash_table_t *ht) -{ - mdb_printf("hash table (%p):\n", addr); - mdb_inc_indent(4); - mdb_printf("size %7-d bits %2-d mask %8-x nmask %8-x buckets %p\n", - ht->ht_size, ht->ht_bits, ht->ht_mask, - ht->ht_nmask, ht->ht_buckets); - mdb_dec_indent(4); -} - -static void -display_hash_bucket(_sd_hash_bucket_t *addr, _sd_hash_bucket_t *hb) -{ - kmutex_t lock; - int rc; - - if ((rc = mdb_vread(&lock, sizeof (kmutex_t), - (uintptr_t)hb->hb_lock)) == -1) - mdb_warn("failed to read bucket lock at %p", hb->hb_lock); - - mdb_printf("hash bucket (%p):\n", addr); - mdb_inc_indent(4); - mdb_printf("head %?-p tail %?-p lock %?-p %s\n", - hb->hb_head, hb->hb_tail, - (rc == -1) ? hb->hb_lock : lock._opaque[0], - (rc == -1) ? "" : "(owner)"); - mdb_printf("inlist %d seq %d\n", hb->hb_inlist, hb->hb_seq); - mdb_dec_indent(4); -} - -/* - * dcmd to walk the hash table - * defaults to _sd_htable the cache hash table, - * but wil accept an address which is probably only useful - * in the event that other hash tables are implemented in - * the cache. - * - * calls sdbc_hashchain dcmd. same options as sdbc_cctl dcmd. - */ -static int -sdbc_hashtable(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _sd_hash_table_t *sd_htable_addr; - _sd_hash_table_t _sd_htable; - _sd_hash_bucket_t hash_bucket; - int i; - - - - if (!(flags & DCMD_ADDRSPEC)) { - /* get the address of the standard cache hash table */ - if (mdb_readvar(&sd_htable_addr, "_sd_htable") == -1) { - mdb_warn("failed to read _sd_htable address\n"); - return (DCMD_ERR); - } - } else - sd_htable_addr = (_sd_hash_table_t *)addr; - - /* read in the hash table structure */ - if (mdb_vread(&_sd_htable, sizeof (_sd_hash_table_t), - (uintptr_t)sd_htable_addr) == -1) { - mdb_warn("failed to read _sd_htable structure at %p\n", - sd_htable_addr); - return (DCMD_ERR); - } - - display_hash_table(sd_htable_addr, &_sd_htable); - - /* - * read in the hash buckets - * and display chains if there are any - */ - for (i = 0; i < _sd_htable.ht_size; ++i) { - if (mdb_vread(&hash_bucket, sizeof (_sd_hash_bucket_t), - (uintptr_t)(_sd_htable.ht_buckets + i)) == -1) { - mdb_warn("failed to read ht_buckets at %p\n", - _sd_htable.ht_buckets + i); - return (DCMD_ERR); - } - - if (hash_bucket.hb_head != NULL) { - display_hash_bucket(_sd_htable.ht_buckets + i, - &hash_bucket); - /* - * if this walk fails, continue trying - * to read hash buckets - */ - if (mdb_call_dcmd("sdbc`sdbc_hashchain", - (uintptr_t)hash_bucket.hb_head, - flags|DCMD_ADDRSPEC, argc, argv) - == -1) - mdb_warn( - "failed to walk hash chain at %p", - hash_bucket.hb_head); - mdb_printf("\n"); - } - } - - return (DCMD_OK); -} -/* - * dcmd to display the sdbc lru queue - * same options as sdbc_cctl(). - * alternatively the user can call the sdbc_lru walker - * and pipe the addresses to sdbc_cctl dcmd. - */ -static int -sdbc_lru(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - _sd_queue_t _sd_lru_q; - GElf_Sym sym; - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_lookup_by_obj("sdbc", "_sd_lru_q", &sym) == -1) { - mdb_warn("failed to lookup _sd_lru_q symbol"); - return (DCMD_ERR); - } - - if (mdb_vread(&_sd_lru_q, sizeof (_sd_queue_t), - sym.st_value) == -1) { - mdb_warn("failed to read _sd_lru_q structure"); - return (DCMD_ERR); - } - - mdb_printf("Cache LRU Queue\n"); - mdb_inc_indent(4); - mdb_printf( - "qlock: 0x%-p (owner) await %d seq %d inq %d req %d noreq %d\n", - _sd_lru_q.sq_qlock._opaque[0], - _sd_lru_q.sq_await, - _sd_lru_q.sq_seq, - _sd_lru_q.sq_inq, - _sd_lru_q.sq_req_stat, - _sd_lru_q.sq_noreq_stat); - - addr = (uintptr_t)(sym.st_value); - } - - if (mdb_pwalk_dcmd("sdbc`sdbc_lru", "sdbc`sdbc_cctl", - argc, argv, addr) == -1) { - mdb_warn("failed to walk lru at addr %p", addr); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - -#ifdef SAFESTORE -static void -print_wrq(_sd_writeq_t *wrq, uint_t verbose) -{ - int i; - - mdb_printf("Cache Write Ctl Queue:\n"); - mdb_inc_indent(4); - mdb_printf("qtop %-p qlock: %-p (owner) inq %d\n", - wrq->wq_qtop, - wrq->wq_qlock._opaque[0], - wrq->wq_inq); - - mdb_printf("slp_top %3-d slp_index %3-d slp_inq %3-d\n", - wrq->wq_slp_top, - wrq->wq_slp_index, - wrq->wq_slp_inq); - - for (i = 0; verbose && i < SD_WR_SLP_Q_MAX; i += 2) { - mdb_printf("%3d: cv %h-x wq_need %3-d wq_held %3-d%4T", - i, - wrq->wq_slp[i].slp_wqcv._opaque, - wrq->wq_slp[i].slp_wqneed, - wrq->wq_slp[i].slp_wqheld); - if (SD_WR_SLP_Q_MAX > (i + 1)) { - mdb_printf( - "%3d: cv %h-x wq_need %3-d wq_held %3-d%\n", - i+1, - wrq->wq_slp[i+1].slp_wqcv._opaque, - wrq->wq_slp[i+1].slp_wqneed, - wrq->wq_slp[i+1].slp_wqheld); - } - } - mdb_dec_indent(4); -} - -/* - * dcmd to display write control structures - */ - -static int -sdbc_wctl(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - _sd_wr_cctl_t wctl; - ss_centry_info_t gl_info; - ss_centry_info_t nv_gl_info; - uintptr_t opt_c = MDB_CD; - uint_t opt_d = FALSE; - uint_t opt_v = FALSE; - - - /* TODO option for fba pos */ - if (mdb_getopts(argc, argv, - 'd', MDB_OPT_SETBITS, TRUE, &opt_d, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_wctl", "sdbc`sdbc_wctl", - argc, argv) == -1) { - mdb_warn("failed to walk write ctl array"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("write control block structures:\n"); - } - - if (mdb_vread(&wctl, sizeof (_sd_wr_cctl_t), addr) == -1) { - mdb_warn("failed to read wctl at 0x%p", addr); - return (DCMD_ERR); - } - - - /* - * print "all" is the default. - * filter conditions can only be checked by reading in wc_gl_info - */ - if (opt_c || opt_d || opt_v) - if (mdb_vread(&gl_info, sizeof (ss_centry_info_t), - (uintptr_t)wctl.wc_gl_info) == -1) { - mdb_warn("failed to read at wc_gl_info 0x%p", addr); - return (DCMD_ERR); - } - - - if (OPT_C_SELECTED && (gl_info.gl_cd != opt_c)) - return (DCMD_OK); - - if (opt_d && !(gl_info.gl_dirty)) - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%-p data %-p gl_info %-p Ngl_info %-p flg %02x\n", - addr, - wctl.wc_data, - wctl.wc_gl_info, - wctl.wc_nvmem_gl_info, - wctl.wc_flag); - mdb_dec_indent(4); - - /* verbose */ - if (!opt_v) - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("next %?-p prev %?-p\n", wctl.wc_next, wctl.wc_prev); - mdb_printf(" gl_info: "); - mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n", - gl_info.gl_cd, gl_info.gl_fpos, gl_info.gl_dirty & 0xffff, - gl_info.gl_flag, cc_flag_bits); - - if (wctl.wc_nvmem_gl_info) { - if (mdb_vread(&nv_gl_info, sizeof (ss_centry_info_t), - (uintptr_t)wctl.wc_nvmem_gl_info) == -1) { - mdb_warn("failed to read at wc_nvmem_gl_info 0x%p", - wctl.wc_nvmem_gl_info); /* not catastophic, continue */ - } else { - - /* consistency check */ - if (memcmp(&gl_info, &nv_gl_info, - sizeof (ss_centry_info_t) != 0)) { - mdb_warn("nvram and host memory are NOT identical!"); - mdb_printf("nvmem_gl_info: "); - mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n", - nv_gl_info.gl_cd, nv_gl_info.gl_fpos, - nv_gl_info.gl_dirty & 0xffff, - nv_gl_info.gl_flag, cc_flag_bits); - } - - } - } - - mdb_dec_indent(4); - mdb_printf("\n"); - return (DCMD_OK); -} - -/* - * dcmd to display write control structures in the free list - * same options as sdbc_wctl - */ - -static int -sdbc_wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _sd_net_t _sd_net_config; - uintptr_t opt_c = MDB_CD; - uint_t opt_d = FALSE; - uint_t opt_v = FALSE; - - - /* look for verbose option */ - if (mdb_getopts(argc, argv, - 'd', MDB_OPT_SETBITS, TRUE, &opt_d, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_readvar(&_sd_net_config, "_sd_net_config") == -1) { - mdb_warn("failed to read _sd_net_config structure"); - return (DCMD_ERR); - } - - print_wrq(&(_sd_net_config.sn_wr_queue), opt_v); - - addr = (uintptr_t)(_sd_net_config.sn_wr_queue.wq_qtop); - } - - if (mdb_pwalk_dcmd("sdbc`sdbc_wrq", "sdbc`sdbc_wctl", - argc, argv, addr) == -1) { - mdb_warn("failed to walk write ctl queue at addr %p", addr); - return (DCMD_ERR); - } - return (DCMD_OK); -} -#endif - -/* - * dcmd to display the dm queues - * use sdbc_lru walker to walk each queue. - */ -/*ARGSUSED*/ -static int -sdbc_dmqueues(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _sd_queue_t *sdbc_dm_queues; /* kernel address of dm queues */ - int max_dm_queues; - _sd_queue_t *queues = NULL; /* local copy */ - int i; - - - if (argc != 0) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_readvar(&sdbc_dm_queues, "sdbc_dm_queues") == -1) { - mdb_warn("failed to read sdbc_dm_queues address\n"); - return (DCMD_ERR); - } - - if (mdb_readvar(&max_dm_queues, "max_dm_queues") == -1) { - mdb_warn("failed to read max_dm_queues variable\n"); - return (DCMD_ERR); - } - - queues = mdb_zalloc(max_dm_queues * sizeof (_sd_queue_t), - UM_SLEEP); -mdb_printf("max_dm_queues %d sdbc_dm_queues %p queues %p\n", - max_dm_queues, sdbc_dm_queues, queues); - - if (mdb_vread(queues, max_dm_queues * sizeof (_sd_queue_t), - (uintptr_t)sdbc_dm_queues) == -1) { - mdb_warn("failed to read sdbc_dm_queues"); - return (DCMD_ERR); - } - - for (i = 0; i < max_dm_queues; ++i) { - mdb_printf("Cache DM Queue %d %p\n", - queues[i].sq_dmchain_cblocks, - sdbc_dm_queues +i); - mdb_inc_indent(4); - mdb_printf("qlock: 0x%-p (owner) await %d " - "seq %d inq %d req %d noreq %d\n", - queues[i].sq_qlock._opaque[0], - queues[i].sq_await, - queues[i].sq_seq, - queues[i].sq_inq, - queues[i].sq_req_stat, - queues[i].sq_noreq_stat); - - mdb_dec_indent(4); - } - } - - return (DCMD_OK); -} - - -mdb_bitmask_t cd_writer_bits[] = { - { "NONE ", (u_longlong_t)~0, _SD_WRITER_NONE }, - { "CREATE ", (u_longlong_t)~0, _SD_WRITER_CREATE }, - { "RUNNING", (u_longlong_t)~0, _SD_WRITER_RUNNING }, - { NULL, 0, 0 } -}; - -mdb_bitmask_t sh_failed_status[] = { - { "STATUS OK", (u_longlong_t)~0, 0 }, - { "I/O ERROR", (u_longlong_t)~0, 1 }, - { "OPEN FAIL", (u_longlong_t)~0, 2 }, - { NULL, 0, 0 } -}; - -mdb_bitmask_t sh_flag_bits[] = { - { "ATTACHED", CD_ATTACHED, CD_ATTACHED }, - { NULL, 0, 0 } -}; - -mdb_bitmask_t sh_alloc_bits[] = { - { "ALLOC_IN_PROGRESS", CD_ALLOC_IN_PROGRESS, CD_ALLOC_IN_PROGRESS }, - { "ALLOCATED", CD_ALLOCATED, CD_ALLOCATED }, - { "CLOSE_IN_PROGRESS", CD_CLOSE_IN_PROGRESS, CD_CLOSE_IN_PROGRESS }, - { NULL, 0, 0 } -}; - -/* - * dcmd to display cd information - */ -static int -sdbc_cdinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - _sd_shared_t sd_shared; - _sd_cd_info_t cdi; - ss_voldata_t gl_file; - char *fn = "nopath"; /* filename if sd_shared info cannot be read */ - uchar_t sh_alloc = 0; /* assume not alloc'd if sd_shared info unavail */ - uintptr_t opt_c = MDB_CD; - uint_t opt_a = FALSE; - uint_t opt_v = FALSE; - int dev_t_chars; - - dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ - - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &opt_a, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_cdinfo", "sdbc`sdbc_cdinfo", - argc, argv) == -1) { - mdb_warn("failed to walk cd info array"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("cd info structures:\n"); - } - - if (mdb_vread(&cdi, sizeof (_sd_cd_info_t), addr) == -1) { - mdb_warn("failed to read cd info at 0x%p", addr); - return (DCMD_ERR); - } - - /* - * need to do this read even for non-verbose option to - * get the filename and the sh_alloc field - */ - if (cdi.cd_info) { - if (mdb_vread(&sd_shared, sizeof (_sd_shared_t), - (uintptr_t)cdi.cd_info) == -1) { - mdb_warn("failed to read shared cd info at 0x%p", - cdi.cd_info); - /* not catastrophic, keep truckin' */ - } else { - fn = sd_shared.sh_filename; - sh_alloc = sd_shared.sh_alloc; - } - } - - if (!opt_a && (sh_alloc == 0)) - return (DCMD_OK); - - if (OPT_C_SELECTED && (opt_c != cdi.cd_desc)) - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%p cd %3-d filename %s\n", - addr, cdi.cd_desc, fn); - mdb_printf("alloc <%b> hint <%b>\n", - sh_alloc, sh_alloc_bits, - cdi.cd_hint, cache_hints); - mdb_dec_indent(4); - - if (!opt_v) - return (DCMD_OK); - - /* verbose */ - mdb_inc_indent(4); - mdb_printf("rawfd %?-p crdev %0*lx iodev %?-p\n", - cdi.cd_rawfd, - dev_t_chars, - cdi.cd_crdev, - cdi.cd_iodev); - mdb_printf("flag %x %8Tlock %?-p writer <%b>\n", - cdi.cd_flag, - cdi.cd_lock._opaque[0], - cdi.cd_writer, cd_writer_bits); - mdb_printf("global %?-p dirty_head %?-p\n", - cdi.cd_global, cdi.cd_dirty_head); - mdb_printf("last_ent %?-p lastchain_ptr %?-p lastchain %d\n", - cdi.cd_last_ent, cdi.cd_lastchain_ptr, - cdi.cd_lastchain); - mdb_printf("io_head %?-p io_tail %?-p fail_head %?-p\n", - cdi.cd_io_head, cdi.cd_io_tail, cdi.cd_fail_head); - mdb_printf( - "cd_info %?-p failover %d recovering %d write_inprogress %d\n", - cdi.cd_info, cdi.cd_failover, - cdi.cd_recovering, - cdi.cd_write_inprogress); - - if (cdi.cd_global != NULL) { - if (mdb_vread(&gl_file, sizeof (ss_voldata_t), - (uintptr_t)cdi.cd_global) == -1) - mdb_warn("failed to read cd_global at %p", - cdi.cd_global); - else { - mdb_printf("cd_global: %s\n", gl_file.sv_volname); - mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n", - gl_file.sv_pinned, gl_file.sv_attached, - gl_file.sv_devidsz); - mdb_printf("devid %s\n", gl_file.sv_devid); - mdb_printf("vol %?p\n", gl_file.sv_vol); - } - /* TODO do a consistency check here against the nvram copy */ - } - - if (cdi.cd_info == NULL) { - mdb_printf("no shared info\n"); - } else { - mdb_printf("shared:\n"); - mdb_printf("failed <%b> cd %3-d", - sd_shared.sh_failed, sh_failed_status, - sd_shared.sh_cd); - mdb_printf("cache_read %10-d cache_write %10-d\n", - sd_shared.sh_cache_read, sd_shared.sh_cache_write); - mdb_printf("disk_read %10-d disk_write %10-d filesize %10-d\n", - sd_shared.sh_disk_read, sd_shared.sh_disk_write, - sd_shared.sh_filesize); - mdb_printf("numdirty %8-d numio %8-d numfail %8-d\n", - sd_shared.sh_numdirty, - sd_shared.sh_numio, - sd_shared.sh_numfail); - mdb_printf("flushloop %2-d sh_flag <%b>\n", - sd_shared.sh_flushloop, sd_shared.sh_flag, sh_flag_bits); - - /* this can be really verbose */ - if (cdi.cd_dirty_head) { - mdb_printf("Dirty Chain (cd_dirty_head):"); - /* TODO reconstruct argv without opt_a */ - if (!opt_a) - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_dirty_head, - flags, argc, argv); - else /* print with no options */ - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_dirty_head, - flags, 0, NULL); - } - - if (cdi.cd_io_head) { - mdb_printf("I/O Pending Chain (cd_io_head):"); - /* TODO reconstruct argv without opt_a */ - if (!opt_a) - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_io_head, - flags, argc, argv); - else /* print with no options */ - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_dirty_head, - flags, 0, NULL); - } - - if (cdi.cd_fail_head) { - mdb_printf("Failed Chain (cd_fail_head):"); - /* TODO reconstruct argv without opt_a */ - if (!opt_a) - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_fail_head, - flags, argc, argv); - else /* print with no options */ - mdb_call_dcmd("sdbc_dchain", - (uintptr_t)cdi.cd_dirty_head, - flags, 0, NULL); - } - } - - mdb_dec_indent(4); - - mdb_printf("\n"); - - return (DCMD_OK); -} - -#ifdef SAFESTORE -/* - * dcmd to display fault tolerant control structures - */ -static int -sdbc_ftctl(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - _sd_ft_cctl_t ft_cent; - ss_centry_info_t gl_info; - ss_centry_info_t nv_gl_info; - uintptr_t opt_c = MDB_CD; - uint_t opt_d = FALSE; - uint_t opt_v = FALSE; - - - /* TODO option to select on fpos */ - if (mdb_getopts(argc, argv, - 'd', MDB_OPT_SETBITS, TRUE, &opt_d, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_ftctl", "sdbc`sdbc_ftctl", - argc, argv) == -1) { - mdb_warn("failed to walk write ctl array"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("Ft control block structures:\n"); - } - - if (mdb_vread(&ft_cent, sizeof (_sd_ft_cctl_t), addr) == -1) { - mdb_warn("failed to read ft_cent at 0x%p", addr); - return (DCMD_ERR); - } - - - /* - * print "all" is the default. - * filter conditions can only be checked by reading in wc_gl_info - */ - if (opt_c || opt_d || opt_v) - if (mdb_vread(&gl_info, sizeof (ss_centry_info_t), - (uintptr_t)ft_cent.ft_gl_info) == -1) { - mdb_warn("failed to read at wc_gl_info 0x%p", addr); - return (DCMD_ERR); - } - - - if (OPT_C_SELECTED && (gl_info.gl_cd != opt_c)) - return (DCMD_OK); - - if (opt_d && !(gl_info.gl_dirty)) - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%-p data %?-p qnext %?-p\n", - addr, - ft_cent.ft_qnext, - ft_cent.ft_data); - mdb_printf("gl_info %?-p nvmem_gl_info %?-p\n", - ft_cent.ft_gl_info, - ft_cent.ft_nvmem_gl_info); - mdb_dec_indent(4); - - /* verbose */ - if (!opt_v) { - mdb_printf("\n"); - return (DCMD_OK); - } - - mdb_inc_indent(4); - mdb_printf(" gl_info: "); - mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n", - gl_info.gl_cd, gl_info.gl_fpos, gl_info.gl_dirty & 0xffff, - gl_info.gl_flag, cc_flag_bits); - - if (ft_cent.ft_nvmem_gl_info) { - if (mdb_vread(&nv_gl_info, sizeof (ss_centry_info_t), - (uintptr_t)ft_cent.ft_nvmem_gl_info) == -1) { - mdb_warn("failed to read at ft_nvmem_gl_info 0x%p", - ft_cent.ft_nvmem_gl_info); /* not catastophic, continue */ - } else { - mdb_printf("nvmem_gl_info: "); - mdb_printf("cd %3-d fpos %10-d dirty %04x flag <%b>\n", - nv_gl_info.gl_cd, nv_gl_info.gl_fpos, - nv_gl_info.gl_dirty & 0xffff, - nv_gl_info.gl_flag, cc_flag_bits); - - /* consistency check */ - if (memcmp(&gl_info, &nv_gl_info, sizeof (ss_centry_info_t)) - != 0) { - mdb_warn("nvram and host memory are NOT identical!"); - } - - } - } - - mdb_dec_indent(4); - mdb_printf("\n"); - return (DCMD_OK); -} -#endif /* SAFESTORE */ - - -/* dcmd to display buffer handles */ -static int -sdbc_handles(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - uint_t opt_a = FALSE; - uintptr_t opt_c = MDB_CD; - uint_t opt_v = FALSE; - uint_t opt_C = FALSE; - _sd_buf_hlist_t hl; - _sd_buf_handle_t bh; - - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &opt_a, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'C', MDB_OPT_SETBITS, TRUE, &opt_C, - 'v', MDB_OPT_SETBITS, TRUE, &opt_v) != argc) - return (DCMD_USAGE); - - - if (mdb_readvar(&hl, "_sd_handle_list") == -1) { - mdb_warn("failed to read _sd_handle_list structure"); - return (DCMD_ERR); - } - - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_handles", "sdbc`sdbc_handles", - argc, argv) == -1) { - mdb_warn("failed to walk 'sdbc_handle_list'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("Handle List Info:\n"); - - mdb_inc_indent(4); - mdb_printf("hl_top.bh_next: 0x%p\n", hl.hl_top.bh_next); - mdb_printf("hl_lock: 0x%p (owner)\n", hl.hl_lock._opaque[0]); - mdb_printf("hl_count: %hd\n", hl.hl_count); - mdb_dec_indent(4); - mdb_printf("buf handles:\n"); - } - - if (mdb_vread(&bh, sizeof (bh), addr) == -1) { - mdb_warn("failed to read buf handle at 0x%p", addr); - return (DCMD_ERR); - } - - if (!opt_a && !(bh.bh_flag & (NSC_HALLOCATED | NSC_HACTIVE))) - return (DCMD_OK); - - /* - * may get false matches on cd option -- - * a cleared bh_cd field will match if user specified cd 0 - */ - if (OPT_C_SELECTED && (bh.bh_cd != opt_c)) - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%p %8T cd %3-d %4T<%b> %x\n", addr, bh.bh_cd, - bh.bh_flag, nsc_buf_bits, bh.bh_flag); - - /* check for verbose, avoid printing twice */ - if (!opt_v && opt_C) { - mdb_printf("cc_chain: "); - if (bh.bh_centry) - mdb_call_dcmd("sdbc`sdbc_cchain", - (uintptr_t)bh.bh_centry, DCMD_ADDRSPEC, 0, NULL); - } - - mdb_dec_indent(4); - - if (!opt_v) - return (DCMD_OK); - - /* verbose */ - mdb_inc_indent(4); - - mdb_printf("callbacks: %-20a%-20a%-20a\n", - bh.bh_disconnect_cb, bh.bh_read_cb, bh.bh_write_cb); - - mdb_printf("centry %?p %8T next %?p\n", - bh.bh_centry, bh.bh_next); - mdb_printf("buffer:\n"); - - mdb_inc_indent(4); - mdb_printf("fd 0x%p pos %10d len %6d flag 0x%x\n", - bh.bh_buf.sb_fd, bh.bh_fba_pos, bh.bh_fba_len, bh.bh_flag); - - mdb_printf("alloc_thread %p busy_thread %p\n", bh.bh_alloc_thread, - bh.bh_busy_thread); - - mdb_printf("err %4d %8T bh_vec 0x%p\n", bh.bh_error, bh.bh_vec); - mdb_dec_indent(4); - - mdb_printf("bufvec (scatter gather list): %-?s %8T%-s\n", - "ADDR", "LEN"); - { - _sd_bufvec_t *bv, *endvec; - - - /* todo check for (bh_vec != bh_bufvec) => readahead? */ - - bv = bh.bh_bufvec; - endvec = bv + _SD_MAX_BLKS; - mdb_inc_indent(30); - while (bv->bufaddr) { - mdb_printf("%p %8T%d\n", bv->bufaddr, bv->buflen); - ++bv; - if (bv > endvec) { - mdb_warn("END of bh_bufvec ARRAY"); - break; - } - } - mdb_dec_indent(30); - } - - if (opt_C) { - mdb_printf("cc_chain: "); - if (bh.bh_centry) - mdb_call_dcmd("sdbc`sdbc_cchain", - (uintptr_t)bh.bh_centry, DCMD_ADDRSPEC, 0, NULL); - } - - mdb_dec_indent(4); - mdb_printf("\n"); - - return (DCMD_OK); -} -/* - * dcmd to display ss_centry_info_t structures and - * do optional consistency check with the nvram copy - * if configured for nvram safe storage. - */ - -static int -sdbc_glcinfo(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - ss_centry_info_t gl_centry_info; - /* for doing consistency check */ - - ss_centry_info_t *gl_centry_info_start; - ss_centry_info_t *nv_gl_centry_info_start; - uintptr_t nv_addr; - ss_centry_info_t nv_gl_centry_info; - - /* options */ - uint_t opt_a = FALSE; - uintptr_t opt_b = MDB_BLKNUM; /* fba pos match */ - uintptr_t opt_c = MDB_CD; - uintptr_t opt_C = FALSE; /* consistency check */ - uint_t opt_d = FALSE; - - - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &opt_a, - 'b', MDB_OPT_UINTPTR, &opt_b, - 'c', MDB_OPT_UINTPTR, &opt_c, - 'C', MDB_OPT_SETBITS, TRUE, &opt_C, - 'd', MDB_OPT_SETBITS, TRUE, &opt_d) != argc) - return (DCMD_USAGE); - - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_glcinfo", "sdbc`sdbc_glcinfo", - argc, argv) == -1) { - mdb_warn("failed to walk global centry info array"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("global cache entry info:\n"); - } - - if (mdb_vread(&gl_centry_info, sizeof (ss_centry_info_t), addr) == -1) { - mdb_warn("failed to read gl_centry_info at 0x%p", addr); - return (DCMD_ERR); - } - - - /* - * default is to print entries initialized with a cd. return if - * no options are selected and cd is invalid. - */ - if (!opt_a && (!OPT_B_SELECTED) && (!OPT_C_SELECTED) && !opt_d && - (gl_centry_info.sc_cd == -1)) - return (DCMD_OK); - - - /* - * opt_c is exclusive filter. if opt_c is selected and there - * is no match on the cd then return - */ - if (!opt_a && - (OPT_C_SELECTED && (gl_centry_info.sc_cd != opt_c))) - return (DCMD_OK); - - /* - * opt_d and opt_b are inclusive. print if either one is chosen - * and the selection condition is true. - */ - if (opt_a || - (!opt_d && (!OPT_B_SELECTED)) || /* no options chosen */ - (opt_d && gl_centry_info.sc_dirty) || - (OPT_B_SELECTED && (gl_centry_info.sc_fpos == opt_b))) - /*EMPTY*/; - else - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n", - addr, - gl_centry_info.sc_cd, - gl_centry_info.sc_fpos, - gl_centry_info.sc_dirty & 0xffff, - gl_centry_info.sc_flag, cc_flag_bits); - - if (opt_C) { - /* get start of the cache entry metadata */ - if (mdb_readvar(&gl_centry_info_start, - "_sdbc_gl_centry_info") == -1) { - mdb_warn("failed to read _sdbc_gl_centry_info"); - /* not catastrophic */ - goto end; - } - - /* get start of the nvram copy cache entry metadata */ - if (mdb_readvar(&nv_gl_centry_info_start, - "_sdbc_gl_centry_info_nvmem") == -1) { - mdb_warn("failed to read _sdbc_gl_centry_info_nvmem"); - /* not catastrophic */ - goto end; - } - - nv_addr = (addr - (uintptr_t)gl_centry_info_start) + - (uintptr_t)nv_gl_centry_info_start; - - if (mdb_vread(&nv_gl_centry_info, sizeof (ss_centry_info_t), - nv_addr) == -1) { - mdb_warn("failed to read at nvmem_gl_info 0x%p", - nv_addr); - /* not catastophic, continue */ - } else { - - /* consistency check */ - mdb_inc_indent(4); - if (memcmp(&gl_centry_info, &nv_gl_centry_info, - sizeof (ss_centry_info_t) != 0)) { - mdb_warn( - "nvram and host memory are NOT identical!"); - mdb_printf("nvmem_gl_centry_info: "); - mdb_printf( - "%?-p cd %3-d fpos %10-d dirty %04x flag <%b>\n", - nv_addr, - nv_gl_centry_info.sc_cd, - nv_gl_centry_info.sc_fpos, - nv_gl_centry_info.sc_dirty & 0xffff, - nv_gl_centry_info.sc_flag, cc_flag_bits); - mdb_printf("\n"); - } else - mdb_printf("NVRAM ok\n"); - - mdb_dec_indent(4); - - } - } - - end: - mdb_dec_indent(4); - return (DCMD_OK); -} - -/* - * dcmd to display ss_voldata_t structures and - * do optional consistency check with the nvram copy - * if configured for nvram safe storage. - */ - -static int -sdbc_glfinfo(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv) -{ - ss_voldata_t gl_file_info; - /* for doing consistency check */ - - ss_voldata_t *gl_file_info_start; - ss_voldata_t *nv_gl_file_info_start; - uintptr_t nv_addr; - ss_voldata_t nv_gl_file_info; - - /* options default: valid filename */ - uint_t opt_a = FALSE; /* all */ - uint_t opt_p = FALSE; /* PINNED */ - uint_t opt_t = FALSE; /* attached */ - uint_t opt_C = FALSE; /* consistency check */ - - - - /* - * possible enhancement -- match on filename, - * or filename part (e.g. controller number) - */ - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &opt_a, - 'C', MDB_OPT_SETBITS, TRUE, &opt_C, - 'p', MDB_OPT_SETBITS, TRUE, &opt_p, - 't', MDB_OPT_SETBITS, TRUE, &opt_t) != argc) - return (DCMD_USAGE); - - - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("sdbc`sdbc_glfinfo", "sdbc`sdbc_glfinfo", - argc, argv) == -1) { - mdb_warn("failed to walk global file info array"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("global file entry info:\n"); - } - - if (mdb_vread(&gl_file_info, sizeof (ss_voldata_t), addr) == -1) { - mdb_warn("failed to read gl_file_info at 0x%p", addr); - return (DCMD_ERR); - } - - - /* - * default is to print entries initialized with non-null filename. - * return if no options are selected and filename is invalid. - */ - if (!opt_a && !opt_p && !opt_t && - (strlen(gl_file_info.sv_volname) == 0)) - return (DCMD_OK); - - - if (opt_a || - (!opt_p && !opt_t) || /* no options chosen */ - (opt_p && (gl_file_info.sv_pinned != _SD_NO_HOST)) || - (opt_t && (gl_file_info.sv_attached != _SD_NO_HOST))) - /*EMPTY*/; - else - return (DCMD_OK); - - mdb_inc_indent(4); - mdb_printf("%?-p %s\n", addr, gl_file_info.sv_volname); - mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n", - gl_file_info.sv_pinned, - gl_file_info.sv_attached, - gl_file_info.sv_devidsz); - mdb_printf("devid %s\n", gl_file_info.sv_devid); - - if (opt_C) { - /* get start of the cache entry metadata */ - if (mdb_readvar(&gl_file_info_start, - "_sdbc_gl_file_info") == -1) { - mdb_warn("failed to read _sdbc_gl_file_info"); - /* not catastrophic */ - goto end; - } - - /* get start of the nvram copy cache entry metadata */ - if (mdb_readvar(&nv_gl_file_info_start, - "_sdbc_gl_file_info_nvmem") == -1) { - mdb_warn("failed to read _sdbc_gl_file_info_nvmem"); - /* not catastrophic */ - goto end; - } - - nv_addr = (addr - (uintptr_t)gl_file_info_start) + - (uintptr_t)nv_gl_file_info_start; - - if (mdb_vread(&nv_gl_file_info, sizeof (ss_voldata_t), - nv_addr) == -1) { - mdb_warn("failed to read nvmem_gl_info at 0x%p", - nv_addr); - /* not catastophic, continue */ - } else { - - /* consistency check */ - mdb_inc_indent(4); - if (memcmp(&gl_file_info, &nv_gl_file_info, - sizeof (ss_centry_info_t) != 0)) { - mdb_warn("nvram and host memory are NOT identical!"); - mdb_printf("nvmem_gl_file_info: "); - mdb_printf("%?-p %s\n", nv_addr, - nv_gl_file_info.sv_volname); - mdb_printf("pinned %2-d attached %2-d devidsz %3-d\n", - nv_gl_file_info.sv_pinned, - nv_gl_file_info.sv_attached, - nv_gl_file_info.sv_devidsz); - mdb_printf("devid %s\n", nv_gl_file_info.sv_devid); - } else - mdb_printf("NVRAM ok\n"); - - mdb_dec_indent(4); - - } - } - - end: - mdb_dec_indent(4); - mdb_printf("\n"); - return (DCMD_OK); -} - - -/* - * MDB module linkage information: - * - * We declare a list of structures describing our dcmds, and a function - * named _mdb_init to return a pointer to our module information. - */ - -static const mdb_dcmd_t dcmds[] = { - /* general dcmds */ - { "sdbc_config", NULL, - "display sdbc configuration information", - sdbc_config }, - { "sdbc_stats", NULL, - "display sdbc stats information", - sdbc_stats }, - { "sdbc_vars", NULL, - "display some sdbc variables, counters and addresses", - sdbc_vars }, - - /* cctl dcmds */ - {"sdbc_cctl", "?[-vdhioV][-c cd][-b blknum]", - "display sdbc cache ctl structures", - sdbc_cctl, cctl_help }, - {"sdbc_cchain", ":[-vdhioV][-c cd][-b blknum]", - "display cache ctl structure cc_chain", - sdbc_cchain, cchain_help }, - {"sdbc_dchain", ":[-vdhioV][-c cd][-b blknum]", - "display cache ctl structure dirty chain", - sdbc_dchain, dchain_help }, - {"sdbc_dmchain", ":[-vdhioV][-c cd][-b blknum]", - "display dynamic memory cache ctl chain", - sdbc_dmchain, dmchain_help }, - {"sdbc_hashchain", ":[-vdhioV][-c cd][-b blknum]", - "display a hash chain", sdbc_hashchain, hashchain_help }, - {"sdbc_hashtable", "?[-vdhioV][-c cd][-b blknum]", - "display hash table", sdbc_hashtable, hashtable_help }, - {"sdbc_lru", "?[-vdhioV][-c cd][-b blknum]", - "display the cache lru queue", - sdbc_lru, lru_help }, -#ifdef SAFESTORE - /* wctl dcmds */ - {"sdbc_wctl", "?[-vd][-c cd]", - "display the write control structures", - sdbc_wctl, wctl_help }, - {"sdbc_wrq", "?[-vd][-c cd]", - "display the write control queue", - sdbc_wrq, wrq_help }, -#endif /* SAFESTORE */ - - /* others */ - {"sdbc_cdinfo", "?[-av][-c cd]", - "display cache descriptor information", - sdbc_cdinfo, cdinfo_help }, -#ifdef SAFESTORE - {"sdbc_ftctl", "?[-vd][-c cd]", - "display the fault tolerant control structures", - sdbc_ftctl, ftctl_help }, -#endif /* SAFESTORE */ - {"sdbc_handles", "?[-avC][-c cd]", - "display sdbc buffer handle information", - sdbc_handles, handle_help }, - - { "sdbc_dmqueues", NULL, - "display sdbc dynamic memory buffer queues information", - sdbc_dmqueues }, - - /* "global" metadata dcmds */ - {"sdbc_glcinfo", "?[-adC][-c cd][-b fbapos]", - "display the global cache entry info structures", - sdbc_glcinfo, glcinfo_help }, - {"sdbc_glfinfo", "?[-aptC]", - "display the global file info structures", - sdbc_glfinfo, glfinfo_help }, - { NULL } -}; - -static const mdb_walker_t walkers[] = { - /* walkers of cctl list and arrays */ - { "sdbc_cchain", "walk the cc_chain (alloc chain) of a cache ctl", - sdbc_cchain_winit, sdbc_cchain_wstep, sdbc_cchain_wfini }, - { "sdbc_cctl", "walk the cache ctl structure list", - sdbc_cctl_winit, sdbc_cctl_wstep, sdbc_cctl_wfini }, - { "sdbc_dchain", "walk the dirty chain of a cache ctl", - sdbc_dchain_winit, sdbc_dchain_wstep, sdbc_dchain_wfini }, - { "sdbc_dmchain", "walk the dynamic memory chain of a cache cctl", - sdbc_dmchain_winit, sdbc_dmchain_wstep, sdbc_dmchain_wfini }, - { "sdbc_hashchain", "walk a hash chain", - sdbc_hashchain_winit, sdbc_hashchain_wstep, - sdbc_hashchain_wfini }, - { "sdbc_lru", "walk the cache lru queue", - sdbc_lru_winit, sdbc_lru_wstep, sdbc_lru_wfini }, - -#ifdef SAFESTORE - /* walkers of wctl lists and arrays */ - { "sdbc_wctl", "walk the allocated write ctl array", - sdbc_wctl_winit, sdbc_wctl_wstep, sdbc_wctl_wfini }, - { "sdbc_wrq", "walk the write ctl queue (free list)", - sdbc_wrq_winit, sdbc_wrq_wstep, sdbc_wrq_wfini }, -#endif /* SAFESTORE */ - /* others */ - { "sdbc_cdinfo", - "walk the _sd_cache_files array of cache descriptor information", - sdbc_cdinfo_winit, sdbc_cdinfo_wstep, sdbc_cdinfo_wfini }, -#ifdef SAFESTORE - { "sdbc_ftctl", - "walk the allocated array of fault tolerant structures", - sdbc_ftctl_winit, sdbc_ftctl_wstep, sdbc_ftctl_wfini }, -#endif /* SAFESTORE */ - { "sdbc_handles", "walk array of _sd_buf_handle_t structures", - sdbc_handle_winit, sdbc_handle_wstep, sdbc_handle_wfini }, - - /* walkers for metadata arrays */ - { "sdbc_glcinfo", "walk the allocated global cache entry info array", - sdbc_glcinfo_winit, sdbc_glcinfo_wstep, sdbc_glcinfo_wfini }, - { "sdbc_glfinfo", "walk the allocated global file info array", - sdbc_glfinfo_winit, sdbc_glfinfo_wstep, sdbc_glfinfo_wfini }, - { NULL } -}; - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/common/modules/sv/Makefile.com b/usr/src/cmd/mdb/common/modules/sv/Makefile.com deleted file mode 100644 index 40975cea69..0000000000 --- a/usr/src/cmd/mdb/common/modules/sv/Makefile.com +++ /dev/null @@ -1,24 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -CPPFLAGS += -DNSC_MULTI_TERABYTE diff --git a/usr/src/cmd/mdb/common/modules/sv/sv.c b/usr/src/cmd/mdb/common/modules/sv/sv.c deleted file mode 100644 index 5c6ab5924f..0000000000 --- a/usr/src/cmd/mdb/common/modules/sv/sv.c +++ /dev/null @@ -1,624 +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 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/types.h> -#include <sys/mdb_modapi.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/sunldi.h> - -#include <sys/nsctl/nsctl.h> -#include <sys/unistat/spcs_s.h> -#include <sys/unistat/spcs_s_k.h> - -#include <sys/nsctl/sv.h> -#include <sys/nsctl/sv_impl.h> - -#include <sys/nsctl/nsvers.h> - -/* - * Walker for an array of sv_dev_t structures. - * A global walk is assumed to start at sv_devs. - */ - -struct sv_dev_winfo { - uintptr_t start; - uintptr_t end; -}; - - -static int -sv_dev_winit(mdb_walk_state_t *wsp) -{ - struct sv_dev_winfo *winfo; - sv_dev_t *sv_devs; - int sv_max_devices; - - winfo = mdb_zalloc(sizeof (struct sv_dev_winfo), UM_SLEEP); - - if (mdb_readvar(&sv_devs, "sv_devs") == -1) { - mdb_warn("failed to read 'sv_devs'"); - mdb_free(winfo, sizeof (struct sv_dev_winfo)); - return (WALK_ERR); - } - - if (mdb_readvar(&sv_max_devices, "sv_max_devices") == -1) { - mdb_warn("failed to read 'sv_max_devices'"); - mdb_free(winfo, sizeof (struct sv_dev_winfo)); - return (WALK_ERR); - } - - winfo->start = (uintptr_t)sv_devs; - winfo->end = (uintptr_t)(sv_devs + sv_max_devices); - - if (wsp->walk_addr == NULL) - wsp->walk_addr = winfo->start; - - wsp->walk_data = winfo; - return (WALK_NEXT); -} - - -static int -sv_dev_wstep(mdb_walk_state_t *wsp) -{ - struct sv_dev_winfo *winfo = wsp->walk_data; - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= winfo->end) - return (WALK_DONE); - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr += sizeof (sv_dev_t); - return (status); -} - - -static void -sv_dev_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (struct sv_dev_winfo)); -} - - -/* - * Walker for an sv hash chain. - * Global walks are disallowed. - */ - -static int -sv_hash_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) - return (WALK_ERR); - - wsp->walk_data = mdb_zalloc(sizeof (sv_dev_t), UM_SLEEP); - - return (WALK_NEXT); -} - - -static int -sv_hash_wstep(mdb_walk_state_t *wsp) -{ - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(wsp->walk_data, - sizeof (sv_dev_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read sv_dev at %p", wsp->walk_addr); - return (WALK_DONE); - } - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)(((sv_dev_t *)wsp->walk_data)->sv_hash); - return (status); -} - - -static void -sv_hash_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (sv_dev_t)); -} - - -/* - * Walker for an array of sv_maj_t structures. - * A global walk is assumed to start at sv_majors. - */ - -sv_maj_t *sv_majors[SV_MAJOR_HASH_CNT + 1] = {0}; - -static int -sv_maj_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL) { - if (mdb_readvar(&sv_majors, "sv_majors") == -1) { - mdb_warn("failed to read 'sv_majors'"); - return (WALK_ERR); - } - } else { - sv_majors[0] = (sv_maj_t *)wsp->walk_addr; - } - - wsp->walk_addr = (uintptr_t)&sv_majors[0]; - wsp->walk_data = mdb_zalloc(sizeof (sv_maj_t), UM_SLEEP); - - return (WALK_NEXT); -} - - -static int -sv_maj_wstep(mdb_walk_state_t *wsp) -{ - uintptr_t addr; - int status = DCMD_OK; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (wsp->walk_addr >= (uintptr_t)&sv_majors[SV_MAJOR_HASH_CNT]) - return (WALK_DONE); - - for (addr = *(uintptr_t *)wsp->walk_addr; addr; - addr = (uintptr_t)(((sv_maj_t *)wsp->walk_data)->sm_next)) { - - if (mdb_vread(wsp->walk_data, sizeof (sv_maj_t), addr) - != sizeof (sv_maj_t)) { - mdb_warn("failed to read sv_maj at %p", addr); - status = DCMD_ERR; - break; - } - - status = wsp->walk_callback(addr, wsp->walk_data, - wsp->walk_cbdata); - if (status != DCMD_OK) - break; - } - - wsp->walk_addr += sizeof (sv_maj_t *); - return (status); -} - - -static void -sv_maj_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (sv_maj_t)); -} - - -/* - * Walker for an sv gclient chain. - * A global walk is assumed to start at sv_gclients. - */ - -static int -sv_gclient_winit(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "sv_gclients") == -1) { - mdb_warn("unable to read 'sv_gclients'"); - return (WALK_ERR); - } - - wsp->walk_data = mdb_zalloc(sizeof (sv_gclient_t), UM_SLEEP); - - return (WALK_NEXT); -} - - -static int -sv_gclient_wstep(mdb_walk_state_t *wsp) -{ - int status; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(wsp->walk_data, - sizeof (sv_gclient_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read sv_gclient at %p", wsp->walk_addr); - return (WALK_DONE); - } - - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)(((sv_gclient_t *)wsp->walk_data)->sg_next); - return (status); -} - - -static void -sv_gclient_wfini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (sv_gclient_t)); -} - - -/* - * Display a single sv_glcient_t structure. - * If called with no address, performs a global walk of all sv_gclients. - */ -static int -sv_gclient(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - sv_gclient_t sg; - char name[64]; - - if (argc != 0) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("sv`sv_gclient", - "sv`sv_gclient", argc, argv) == -1) { - mdb_warn("failed to walk 'sv_gclient'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) { - mdb_warn("failed to read sv_gclient at %p", addr); - return (DCMD_ERR); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-?s %8T%-16s %8T%s\n", - "ADDR", "NEXT", "ID", "NAME"); - } - - if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) == -1) { - mdb_warn("failed to read sv_gclient name at %p", addr); - return (DCMD_ERR); - } - - mdb_printf("%p %8T%p %8T%llx %8T%s", - addr, sg.sg_next, sg.sg_id, name); - - return (DCMD_OK); -} - - -/* - * Display a single sv_maj_t structure. - * If called with no address, performs a global walk of all sv_majs. - * -a : all (i.e. display all devices, even if disabled - * -v : verbose - */ -static int -sv_maj(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - sv_maj_t *maj; - int a_opt, v_opt; - int i; - - a_opt = v_opt = FALSE; - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("sv`sv_maj", "sv`sv_maj", argc, argv) == -1) { - mdb_warn("failed to walk 'sv_maj'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%s\n", "ADDR", "INUSE"); - } - - maj = mdb_zalloc(sizeof (*maj), UM_GC); - if (mdb_vread(maj, sizeof (*maj), addr) != sizeof (*maj)) { - mdb_warn("failed to read sv_maj at %p", addr); - return (DCMD_ERR); - } - - if (!a_opt && maj->sm_inuse == 0) - return (DCMD_OK); - - mdb_printf("%?p %8T%d\n", addr, maj->sm_inuse); - - if (!v_opt) - return (DCMD_OK); - - /* - * verbose - print the rest of the structure as well. - */ - - mdb_inc_indent(4); - mdb_printf("\n"); - - mdb_printf("dev_ops: %a (%p)\n", maj->sm_dev_ops, maj->sm_dev_ops); - mdb_printf("flag: %08x %8Tsequence: %d %8Tmajor: %d\n", - maj->sm_flag, maj->sm_seq, maj->sm_major); - - mdb_printf("function pointers:\n"); - mdb_inc_indent(4); - mdb_printf("%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n", - maj->sm_open, maj->sm_close, - maj->sm_read, maj->sm_write, - maj->sm_aread, maj->sm_awrite, - maj->sm_strategy, maj->sm_ioctl); - mdb_dec_indent(4); - - - mdb_printf("hash chain:\n"); - mdb_inc_indent(4); - for (i = 0; i < SV_MINOR_HASH_CNT; i++) { - mdb_printf("%?p", maj->sm_hash[i]); - mdb_printf(((i % 4) == 3) ? "\n" : " %8T"); - } - mdb_printf("\n\n"); - mdb_dec_indent(4); - mdb_dec_indent(4); - return (DCMD_OK); -} - - -/* - * Display a sv_dev_t hash chain. - * Requires an address. - * Same options as sv_dev(). - */ -static int -sv_hash(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - if (!(flags & DCMD_ADDRSPEC)) - return (DCMD_USAGE); - - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_pwalk_dcmd("sv`sv_hash", "sv`sv_dev", argc, argv, addr) == -1) { - mdb_warn("failed to walk sv_dev hash chain"); - return (DCMD_ERR); - } - - return (DCMD_OK); -} - - -/* - * Display a single sv_dev_t structure. - * If called with no address, performs a global walk of all sv_devs. - * -a : all (i.e. display all devices, even if disabled - * -v : verbose - */ - -const mdb_bitmask_t sv_flag_bits[] = { - { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, - { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, - { NULL, 0, 0 } -}; - -static int -sv_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - sv_dev_t *svp; - int a_opt, v_opt; - int dev_t_chars; - - a_opt = v_opt = FALSE; - dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ - - if (mdb_getopts(argc, argv, - 'a', MDB_OPT_SETBITS, TRUE, &a_opt, - 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) - return (DCMD_USAGE); - - svp = mdb_zalloc(sizeof (*svp), UM_GC); - - if (!(flags & DCMD_ADDRSPEC)) { - /* - * paranoid mode on: qualify walker name with module name - * using '`' syntax. - */ - if (mdb_walk_dcmd("sv`sv_dev", "sv`sv_dev", argc, argv) == -1) { - mdb_warn("failed to walk 'sv_dev'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", - dev_t_chars, "DEV", "STATE"); - } - - if (mdb_vread(svp, sizeof (*svp), addr) != sizeof (*svp)) { - mdb_warn("failed to read sv_dev at %p", addr); - return (DCMD_ERR); - } - - if (!a_opt && svp->sv_state == SV_DISABLE) - return (DCMD_OK); - - mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, svp->sv_dev); - - if (svp->sv_state == SV_DISABLE) - mdb_printf("disabled"); - else if (svp->sv_state == SV_PENDING) - mdb_printf("pending"); - else if (svp->sv_state == SV_ENABLE) - mdb_printf("enabled"); - - mdb_printf("\n"); - - if (!v_opt) - return (DCMD_OK); - - /* - * verbose - print the rest of the structure as well. - */ - - mdb_inc_indent(4); - mdb_printf("\n"); - - mdb_printf("hash chain: 0x%p %8Tlock: 0x%p %8Tolock: 0x%p\n", - svp->sv_hash, - addr + OFFSETOF(sv_dev_t, sv_lock), - addr + OFFSETOF(sv_dev_t, sv_olock)); - - mdb_printf("fd: 0x%p %8T\n", svp->sv_fd); - - mdb_printf("maxfbas: %d %8Tnblocks: %d %8Tstate: %d\n", - svp->sv_maxfbas, svp->sv_nblocks, svp->sv_state); - - mdb_printf("gclients: 0x%llx %8Tgkernel: 0x%llx\n", - svp->sv_gclients, svp->sv_gkernel); - - mdb_printf("openlcnt: %d %8Ttimestamp: 0x%lx\n", - svp->sv_openlcnt, svp->sv_timestamp); - - mdb_printf("flags: 0x%08x <%b>\n", - svp->sv_flag, svp->sv_flag, sv_flag_bits); - - mdb_printf("lh: 0x%p %8Tpending: 0x%p\n", - svp->sv_lh, svp->sv_pending); - - mdb_dec_indent(4); - return (DCMD_OK); -} - - -/* - * Display general sv module information. - */ - -#define sv_get_print(kvar, str, fmt, val) \ - if (mdb_readvar(&(val), #kvar) == -1) { \ - mdb_dec_indent(4); \ - mdb_warn("unable to read '" #kvar "'"); \ - return (DCMD_ERR); \ - } \ - mdb_printf("%-20s" fmt "\n", str ":", val) - -/* ARGSUSED */ -static int -sv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - clock_t clock; - int maj, min, mic, baseline, i; - - if (argc != 0) - return (DCMD_USAGE); - - if (mdb_readvar(&maj, "sv_major_rev") == -1) { - mdb_warn("unable to read 'sv_major_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&min, "sv_minor_rev") == -1) { - mdb_warn("unable to read 'sv_minor_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&mic, "sv_micro_rev") == -1) { - mdb_warn("unable to read 'sv_micro_rev'"); - return (DCMD_ERR); - } - - if (mdb_readvar(&baseline, "sv_baseline_rev") == -1) { - mdb_warn("unable to read 'sv_baseline_rev'"); - return (DCMD_ERR); - } - - mdb_printf("SV module version: kernel %d.%d.%d.%d; mdb %d.%d.%d.%d\n", - maj, min, mic, baseline, - ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); - mdb_inc_indent(4); - - sv_get_print(sv_config_time, "last config time", "0x%lx", clock); - sv_get_print(sv_stats_on, "stats on", "%d", i); - sv_get_print(sv_debug, "debug", "%d", i); - sv_get_print(sv_max_devices, "max sv devices", "%d", i); - - mdb_dec_indent(4); - return (DCMD_OK); -} - - -/* - * MDB module linkage information: - */ - -static const mdb_dcmd_t dcmds[] = { - { "sv", NULL, "display sv module info", sv }, - { "sv_dev", "?[-av]", "list sv_dev structure", sv_dev }, - { "sv_gclient", "?", "list sv_gclient structure", sv_gclient }, - { "sv_hash", ":[-av]", "display sv_dev hash chain", sv_hash }, - { "sv_maj", "?[-av]", "list sv_maj structure", sv_maj }, - { NULL } -}; - - -static const mdb_walker_t walkers[] = { - { "sv_dev", "walk array of sv_dev structures", - sv_dev_winit, sv_dev_wstep, sv_dev_wfini }, - { "sv_gclient", "walk sb_gclient chain", - sv_gclient_winit, sv_gclient_wstep, sv_gclient_wfini }, - { "sv_hash", "walk sv_dev hash chain", - sv_hash_winit, sv_hash_wstep, sv_hash_wfini }, - { "sv_maj", "walk array of sv_maj structures", - sv_maj_winit, sv_maj_wstep, sv_maj_wfini }, - { NULL } -}; - - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/intel/amd64/ii/Makefile b/usr/src/cmd/mdb/intel/amd64/ii/Makefile deleted file mode 100644 index 5aa8957b11..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/ii/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = ii.so -MDBTGT = kvm - -MODSRCS = ii.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module -include ../../../common/modules/ii/Makefile.com diff --git a/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile b/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile deleted file mode 100644 index 40a0400919..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/nsctl/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = nsctl.so -MDBTGT = kvm - -MODSRCS = nsctl.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module -include ../../../common/modules/nsctl/Makefile.com diff --git a/usr/src/cmd/mdb/intel/amd64/rdc/Makefile b/usr/src/cmd/mdb/intel/amd64/rdc/Makefile deleted file mode 100644 index e9dd4a514c..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/rdc/Makefile +++ /dev/null @@ -1,38 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = rdc.so -MDBTGT = kvm - -MODSRCS = rdc.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module -include ../../../common/modules/rdc/Makefile.com -CPPFLAGS += -erroff=E_STATIC_UNUSED - -CERRWARN += -_gcc=-Wno-unused-function diff --git a/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile b/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile deleted file mode 100644 index a6a4f78b49..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/sdbc/Makefile +++ /dev/null @@ -1,38 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sdbc.so -MDBTGT = kvm - -AVSBASE = ../../../../../uts/common/avs - -MODSRCS = sdbc.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module -include ../../../common/modules/sdbc/Makefile.com -CPPFLAGS += -I$(AVSBASE) diff --git a/usr/src/cmd/mdb/intel/amd64/sv/Makefile b/usr/src/cmd/mdb/intel/amd64/sv/Makefile deleted file mode 100644 index 626e54c59d..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/sv/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sv.so -MDBTGT = kvm - -MODSRCS = sv.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module -include ../../../common/modules/sv/Makefile.com diff --git a/usr/src/cmd/mdb/intel/ia32/ii/Makefile b/usr/src/cmd/mdb/intel/ia32/ii/Makefile deleted file mode 100644 index 6e8855c023..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/ii/Makefile +++ /dev/null @@ -1,34 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = ii.so -MDBTGT = kvm - -MODSRCS = ii.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module -include ../../../common/modules/ii/Makefile.com diff --git a/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile b/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile deleted file mode 100644 index a361fbe67e..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/nsctl/Makefile +++ /dev/null @@ -1,34 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = nsctl.so -MDBTGT = kvm - -MODSRCS = nsctl.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module -include ../../../common/modules/nsctl/Makefile.com diff --git a/usr/src/cmd/mdb/intel/ia32/rdc/Makefile b/usr/src/cmd/mdb/intel/ia32/rdc/Makefile deleted file mode 100644 index 63d95aefb3..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/rdc/Makefile +++ /dev/null @@ -1,37 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = rdc.so -MDBTGT = kvm - -MODSRCS = rdc.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module -include ../../../common/modules/rdc/Makefile.com -CPPFLAGS += -erroff=E_STATIC_UNUSED - -CERRWARN += -_gcc=-Wno-unused-function diff --git a/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile b/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile deleted file mode 100644 index 359088f689..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/sdbc/Makefile +++ /dev/null @@ -1,37 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sdbc.so -MDBTGT = kvm - -AVSBASE = ../../../../../uts/common/avs - -MODSRCS = sdbc.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module -include ../../../common/modules/sdbc/Makefile.com -CPPFLAGS += -I$(AVSBASE) diff --git a/usr/src/cmd/mdb/intel/ia32/sv/Makefile b/usr/src/cmd/mdb/intel/ia32/sv/Makefile deleted file mode 100644 index 0636b1f0bb..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/sv/Makefile +++ /dev/null @@ -1,34 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sv.so -MDBTGT = kvm - -MODSRCS = sv.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module -include ../../../common/modules/sv/Makefile.com diff --git a/usr/src/cmd/mdb/sparc/v9/ii/Makefile b/usr/src/cmd/mdb/sparc/v9/ii/Makefile deleted file mode 100644 index dffc51365c..0000000000 --- a/usr/src/cmd/mdb/sparc/v9/ii/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = ii.so -MDBTGT = kvm - -MODSRCS = ii.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.sparcv9 -include ../../../Makefile.module -include ../../../common/modules/ii/Makefile.com diff --git a/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile b/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile deleted file mode 100644 index a7209d9313..0000000000 --- a/usr/src/cmd/mdb/sparc/v9/nsctl/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = nsctl.so -MDBTGT = kvm - -MODSRCS = nsctl.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.sparcv9 -include ../../../Makefile.module -include ../../../common/modules/nsctl/Makefile.com diff --git a/usr/src/cmd/mdb/sparc/v9/rdc/Makefile b/usr/src/cmd/mdb/sparc/v9/rdc/Makefile deleted file mode 100644 index 5810ed3fb0..0000000000 --- a/usr/src/cmd/mdb/sparc/v9/rdc/Makefile +++ /dev/null @@ -1,38 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = rdc.so -MDBTGT = kvm - -MODSRCS = rdc.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.sparcv9 -include ../../../Makefile.module -include ../../../common/modules/rdc/Makefile.com -CPPFLAGS += -erroff=E_STATIC_UNUSED - -CERRWARN += -_gcc=-Wno-unused-function diff --git a/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile b/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile deleted file mode 100644 index c7d6108028..0000000000 --- a/usr/src/cmd/mdb/sparc/v9/sdbc/Makefile +++ /dev/null @@ -1,38 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sdbc.so -MDBTGT = kvm - -AVSBASE = ../../../../../uts/common/avs - -MODSRCS = sdbc.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.sparcv9 -include ../../../Makefile.module -include ../../../common/modules/sdbc/Makefile.com -CPPFLAGS += -I$(AVSBASE) diff --git a/usr/src/cmd/mdb/sparc/v9/sv/Makefile b/usr/src/cmd/mdb/sparc/v9/sv/Makefile deleted file mode 100644 index 431b217cee..0000000000 --- a/usr/src/cmd/mdb/sparc/v9/sv/Makefile +++ /dev/null @@ -1,35 +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 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -MODULE = sv.so -MDBTGT = kvm - -MODSRCS = sv.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.sparcv9 -include ../../../Makefile.module -include ../../../common/modules/sv/Makefile.com |